aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Lobodzinski <mark@lunarg.com>2015-10-14 13:16:33 -0600
committerMark Lobodzinski <mark@lunarg.com>2015-10-15 10:22:00 -0600
commit84c38b4ab6624883d1d410937bb4d4d0dbf09cbf (patch)
treea29bf894c3e56606c545dc57629febe8861266d3
parent95398a0365055f41928aad19ba5e53ec6e9dfeab (diff)
downloadusermoji-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.h79
-rwxr-xr-xvk-layer-generate.py10
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