diff options
| author | Mark Lobodzinski <mark@lunarg.com> | 2015-10-14 13:16:33 -0600 |
|---|---|---|
| committer | Mark Lobodzinski <mark@lunarg.com> | 2015-10-15 10:22:00 -0600 |
| commit | 84c38b4ab6624883d1d410937bb4d4d0dbf09cbf (patch) | |
| tree | a29bf894c3e56606c545dc57629febe8861266d3 | |
| parent | 95398a0365055f41928aad19ba5e53ec6e9dfeab (diff) | |
| download | usermoji-84c38b4ab6624883d1d410937bb4d4d0dbf09cbf.tar.xz | |
layers: LX159, properly validate swapchain images
Swapchain images are implicitly created and deleted, but must
be considered valid VkImage objects.
| -rw-r--r-- | layers/object_track.h | 79 | ||||
| -rwxr-xr-x | vk-layer-generate.py | 10 |
2 files changed, 78 insertions, 11 deletions
diff --git a/layers/object_track.h b/layers/object_track.h index e7d58201..dea26642 100644 --- a/layers/object_track.h +++ b/layers/object_track.h @@ -52,9 +52,10 @@ typedef enum _ObjectStatusFlagBits } ObjectStatusFlagBits; typedef struct _OBJTRACK_NODE { - uint64_t vkObj; - VkDbgObjectType objType; - ObjectStatusFlags status; + uint64_t vkObj; // Object handle + VkDbgObjectType objType; // Object type identifier + ObjectStatusFlags status; // Object state + uint64_t parentObj; // Parent object } OBJTRACK_NODE; // prototype for extension functions @@ -89,6 +90,10 @@ static std::unordered_map<void*, layer_data *> layer_data_map; static device_table_map ObjectTracker_device_table_map; static instance_table_map ObjectTracker_instance_table_map; +// We need additionally validate image usage using a separate map +// of swapchain-created images +static unordered_map<const void*, OBJTRACK_NODE*> swapchainImageMap; + static long long unsigned int object_track_index = 0; static int objLockInitialized = 0; static loader_platform_thread_mutex objLock; @@ -446,7 +451,8 @@ extern unordered_map<const void*, OBJTRACK_NODE*> VkSwapchainKHRMap; static VkBool32 validate_object(VkQueue dispatchable_object, VkImage object) { - if (VkImageMap.find((void*)object.handle) == VkImageMap.end()) { + if ((VkImageMap.find((void*)object.handle) == VkImageMap.end()) && + (swapchainImageMap.find((void*)object.handle) == swapchainImageMap.end())) { return log_msg(mdd(dispatchable_object), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, object.handle, 0, OBJTRACK_INVALID_OBJECT, "OBJTRACK", "Invalid VkImage Object %p", object.handle); } @@ -455,7 +461,8 @@ static VkBool32 validate_object(VkQueue dispatchable_object, VkImage object) static VkBool32 validate_object(VkCmdBuffer dispatchable_object, VkImage object) { - if (VkImageMap.find((void*)object.handle) == VkImageMap.end()) { + if ((VkImageMap.find((void*)object.handle) == VkImageMap.end()) && + (swapchainImageMap.find((void*)object.handle) == swapchainImageMap.end())) { return log_msg(mdd(dispatchable_object), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, object.handle, 0, OBJTRACK_INVALID_OBJECT, "OBJTRACK", "Invalid VkImage Object %p", object.handle); } @@ -586,6 +593,20 @@ static void create_obj(VkDevice dispatchable_object, VkQueue vkObj, VkDbgObjectT numObjs[objIndex]++; numTotalObjs++; } +static void create_swapchain_image_obj(VkDevice dispatchable_object, VkImage vkObj, VkSwapchainKHR swapchain) +{ + log_msg(mdd(dispatchable_object), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_IMAGE, vkObj.handle, 0, OBJTRACK_NONE, "OBJTRACK", + "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, "SwapchainImage", + vkObj.handle); + + OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE; + pNewObjNode->objType = VK_OBJECT_TYPE_IMAGE; + pNewObjNode->status = OBJSTATUS_NONE; + pNewObjNode->vkObj = vkObj.handle; + pNewObjNode->parentObj = swapchain.handle; + swapchainImageMap[(void*)vkObj.handle] = pNewObjNode; +} + static void destroy_obj(VkDevice dispatchable_object, VkSwapchainKHR object) { if (VkSwapchainKHRMap.find((void*) object.handle) != VkSwapchainKHRMap.end()) { @@ -834,16 +855,25 @@ explicit_AllocDescriptorSets( VkResult explicit_DestroySwapchainKHR( - VkDevice device, + VkDevice device, VkSwapchainKHR swapchain) { - loader_platform_thread_lock_mutex(&objLock); + // A swapchain's images are implicitly deleted when the swapchain is deleted. + // Remove this swapchain's images from our map of such images. + unordered_map<const void*, OBJTRACK_NODE*>::iterator itr = swapchainImageMap.begin(); + while (itr != swapchainImageMap.end()) { + OBJTRACK_NODE* pNode = (*itr).second; + if (pNode->parentObj == swapchain.handle) { + swapchainImageMap.erase(itr++); + } else { + ++itr; + } + } destroy_obj(device, swapchain); loader_platform_thread_unlock_mutex(&objLock); VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->DestroySwapchainKHR(device, swapchain); - return result; } @@ -864,7 +894,11 @@ explicit_FreeMemory( } VkResult -explicit_FreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t count, const VkDescriptorSet* pDescriptorSets) +explicit_FreeDescriptorSets( + VkDevice device, + VkDescriptorPool descriptorPool, + uint32_t count, + const VkDescriptorSet *pDescriptorSets) { loader_platform_thread_lock_mutex(&objLock); validate_object(device, descriptorPool); @@ -880,3 +914,30 @@ explicit_FreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, ui loader_platform_thread_unlock_mutex(&objLock); return result; } + +VkResult +explicit_GetSwapchainImagesKHR( + VkDevice device, + VkSwapchainKHR swapchain, + uint32_t *pCount, + VkImage *pSwapchainImages) +{ + VkBool32 skipCall = VK_FALSE; + loader_platform_thread_lock_mutex(&objLock); + skipCall |= validate_object(device, device); + loader_platform_thread_unlock_mutex(&objLock); + if (skipCall) + return VK_ERROR_VALIDATION_FAILED; + + VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->GetSwapchainImagesKHR(device, swapchain, pCount, pSwapchainImages); + + if (pSwapchainImages != NULL) { + loader_platform_thread_lock_mutex(&objLock); + for (uint32_t i = 0; i < *pCount; i++) { + create_swapchain_image_obj(device, pSwapchainImages[i], swapchain); + } + loader_platform_thread_unlock_mutex(&objLock); + } + return result; +} + diff --git a/vk-layer-generate.py b/vk-layer-generate.py index f918f35f..a846892e 100755 --- a/vk-layer-generate.py +++ b/vk-layer-generate.py @@ -1261,7 +1261,12 @@ class ObjectTrackerSubcommand(Subcommand): procs_txt.append(' // VkPipelineCache object can be NULL if not caching') procs_txt.append(' if (object == VK_NULL_HANDLE) return VK_TRUE;') procs_txt.append('') - procs_txt.append(' if (%sMap.find((void*)object.handle) == %sMap.end()) {' % (o, o)) + if o == "VkImage": + procs_txt.append(' // We need to validate normal image objects and those from the swapchain') + procs_txt.append(' if ((%sMap.find((void*)object.handle) == %sMap.end()) &&' % (o, o)) + procs_txt.append(' (swapchainImageMap.find((void*)object.handle) == swapchainImageMap.end())) {') + else: + procs_txt.append(' if (%sMap.find((void*)object.handle) == %sMap.end()) {' % (o, o)) procs_txt.append(' return log_msg(mdd(dispatchable_object), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, object.handle, 0, OBJTRACK_INVALID_OBJECT, "OBJTRACK",') procs_txt.append(' "Invalid %s Object %%p", object.handle);' % o) procs_txt.append(' }') @@ -1548,7 +1553,8 @@ class ObjectTrackerSubcommand(Subcommand): "MapMemory", "UnmapMemory", "FreeMemory", - "DestroySwapchainKHR" + "DestroySwapchainKHR", + "GetSwapchainImagesKHR" ] decl = proto.c_func(prefix="vk", attr="VKAPI") param0_name = proto.params[0].name |
