From 72bfe32c818ea129f1046e8271dc25550c20cc32 Mon Sep 17 00:00:00 2001 From: Tobin Ehlis Date: Fri, 22 May 2015 12:38:16 -0600 Subject: layers: Fix some DrawState checks --- layers/draw_state.cpp | 66 +++++++++++++++++++++++++++++---------------------- layers/draw_state.h | 26 ++++++++++---------- 2 files changed, 52 insertions(+), 40 deletions(-) diff --git a/layers/draw_state.cpp b/layers/draw_state.cpp index 5f279fcd..21345600 100755 --- a/layers/draw_state.cpp +++ b/layers/draw_state.cpp @@ -966,7 +966,7 @@ static void clearDescriptorPool(VkDescriptorPool pool) POOL_NODE* pPool = getPoolNode(pool); if (!pPool) { char str[1024]; - sprintf(str, "Unable to find pool node for pool %p specified in vkClearDescriptorPool() call", (void*)pool); + sprintf(str, "Unable to find pool node for pool %p specified in vkResetDescriptorPool() call", (void*)pool); layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pool, 0, DRAWSTATE_INVALID_POOL, "DS", str); } else @@ -1564,8 +1564,25 @@ VK_LAYER_EXPORT VkResult VKAPI vkEnumerateLayers(VkPhysicalDevice gpu, size_t ma VK_LAYER_EXPORT VkResult VKAPI vkQueueSubmit(VkQueue queue, uint32_t cmdBufferCount, const VkCmdBuffer* pCmdBuffers, VkFence fence) { + GLOBAL_CB_NODE* pCB = NULL; for (uint32_t i=0; i < cmdBufferCount; i++) { // Validate that cmd buffers have been updated + pCB = getCBNode(pCmdBuffers[i]); + loader_platform_thread_lock_mutex(&globalLock); + if (CB_UPDATE_COMPLETE != pCB->state) { + // Flag error for using CB w/o vkEndCommandBuffer() called + char str[1024]; + sprintf(str, "You must call vkEndCommandBuffer() on CB %p before this call to vkQueueSubmit()!", pCB->cmdBuffer); + layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pCB->cmdBuffer, 0, DRAWSTATE_NO_END_CMD_BUFFER, "DS", str); + } + for (auto ii=pCB->boundDescriptorSets.begin(); ii != pCB->boundDescriptorSets.end(); ++ii) { + if (dsUpdateActive(*ii)) { + char str[1024]; + sprintf(str, "You must call vkEndDescriptorPoolUpdate() before this call to vkQueueSubmit()!"); + layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, *ii, 0, DRAWSTATE_BINDING_DS_NO_END_UPDATE, "DS", str); + } + } + loader_platform_thread_unlock_mutex(&globalLock); } VkResult result = nextTable.QueueSubmit(queue, cmdBufferCount, pCmdBuffers, fence); return result; @@ -1739,27 +1756,27 @@ VK_LAYER_EXPORT VkResult VKAPI vkBeginDescriptorPoolUpdate(VkDevice device, VkDe VK_LAYER_EXPORT VkResult VKAPI vkEndDescriptorPoolUpdate(VkDevice device, VkCmdBuffer cmd) { - VkResult result = nextTable.EndDescriptorPoolUpdate(device, cmd); - if (VK_SUCCESS == result) { - loader_platform_thread_lock_mutex(&globalLock); - POOL_NODE* pPoolNode = poolMap.begin()->second; - if (!pPoolNode) { + // Perform some initial validation checks + POOL_NODE* pPoolNode = NULL; + loader_platform_thread_lock_mutex(&globalLock); + auto poolEntry = poolMap.begin(); + if (poolEntry == poolMap.end()) { + char str[1024]; + sprintf(str, "Unable to find pool node"); + layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_INTERNAL_ERROR, "DS", str); + } + else { + pPoolNode = poolEntry->second; + if (!pPoolNode->updateActive) { char str[1024]; - sprintf(str, "Unable to find pool node"); - layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_INTERNAL_ERROR, "DS", str); - } - else { - if (!pPoolNode->updateActive) { - char str[1024]; - sprintf(str, "You must call vkBeginDescriptorPoolUpdate() before this call to vkEndDescriptorPoolUpdate()!"); - layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_DS_END_WITHOUT_BEGIN, "DS", str); - } - else { - pPoolNode->updateActive = 0; - } - pPoolNode->updateActive = 0; + sprintf(str, "You must call vkBeginDescriptorPoolUpdate() before this call to vkEndDescriptorPoolUpdate()!"); + layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_DS_END_WITHOUT_BEGIN, "DS", str); } - loader_platform_thread_unlock_mutex(&globalLock); + } + loader_platform_thread_unlock_mutex(&globalLock); + VkResult result = nextTable.EndDescriptorPoolUpdate(device, cmd); + if (VK_SUCCESS == result) { + pPoolNode->updateActive = 0; } return result; } @@ -2030,16 +2047,9 @@ VK_LAYER_EXPORT void VKAPI vkCmdBindDescriptorSets(VkCmdBuffer cmdBuffer, VkPipe addCmd(pCB, CMD_BINDDESCRIPTORSETS); for (uint32_t i=0; ilastBoundDescriptorSet = pDescriptorSets[i]; + pCB->boundDescriptorSets.push_back(pDescriptorSets[i]); g_lastBoundDescriptorSet = pDescriptorSets[i]; loader_platform_thread_unlock_mutex(&globalLock); char str[1024]; diff --git a/layers/draw_state.h b/layers/draw_state.h index f1404724..185e5a64 100644 --- a/layers/draw_state.h +++ b/layers/draw_state.h @@ -49,7 +49,8 @@ typedef enum _DRAW_STATE_ERROR DRAWSTATE_DESCRIPTOR_UPDATE_OUT_OF_BOUNDS, // Descriptors set for update out of bounds for corresponding layout section DRAWSTATE_INVALID_UPDATE_INDEX, // Index of requested update is invalid for specified descriptors set DRAWSTATE_INVALID_UPDATE_STRUCT, // Struct in DS Update tree is of invalid type - DRAWSTATE_NUM_SAMPLES_MISMATCH // Number of samples in bound PSO does not match number in FB of current RenderPass + DRAWSTATE_NUM_SAMPLES_MISMATCH, // Number of samples in bound PSO does not match number in FB of current RenderPass + DRAWSTATE_NO_END_CMD_BUFFER, // Must call vkEndCommandBuffer() before QueueSubmit on that cmdBuffer } DRAW_STATE_ERROR; typedef enum _DRAW_TYPE @@ -219,22 +220,23 @@ typedef enum _CB_STATE // Cmd Buffer Wrapper Struct typedef struct _GLOBAL_CB_NODE { VkCmdBuffer cmdBuffer; - uint32_t queueNodeIndex; - VkFlags flags; - VkFence fence; // fence tracking this cmd buffer - uint64_t numCmds; // number of cmds in this CB - uint64_t drawCount[NUM_DRAW_TYPES]; // Count of each type of draw in this CB - CB_STATE state; // Track if cmd buffer update status - vector pCmds; + uint32_t queueNodeIndex; + VkFlags flags; + VkFence fence; // fence tracking this cmd buffer + uint64_t numCmds; // number of cmds in this CB + uint64_t drawCount[NUM_DRAW_TYPES]; // Count of each type of draw in this CB + CB_STATE state; // Track if cmd buffer update status + vector pCmds; // Currently storing "lastBound" objects on per-CB basis // long-term may want to create caches of "lastBound" states and could have // each individual CMD_NODE referencing its own "lastBound" state - VkPipeline lastBoundPipeline; - uint32_t lastVtxBinding; - DYNAMIC_STATE_NODE* lastBoundDynamicState[VK_NUM_STATE_BIND_POINT]; + VkPipeline lastBoundPipeline; + uint32_t lastVtxBinding; + DYNAMIC_STATE_NODE* lastBoundDynamicState[VK_NUM_STATE_BIND_POINT]; VkDescriptorSet lastBoundDescriptorSet; VkRenderPass activeRenderPass; - VkFramebuffer framebuffer; + VkFramebuffer framebuffer; + vector boundDescriptorSets; } GLOBAL_CB_NODE; //prototypes for extension functions -- cgit v1.2.3