diff options
Diffstat (limited to 'layers')
| -rw-r--r-- | layers/draw_state.cpp | 92 | ||||
| -rw-r--r-- | layers/draw_state.h | 17 | ||||
| -rw-r--r-- | layers/vk_validation_layer_details.md | 3 |
3 files changed, 81 insertions, 31 deletions
diff --git a/layers/draw_state.cpp b/layers/draw_state.cpp index 5a6d1211..239a9b0e 100644 --- a/layers/draw_state.cpp +++ b/layers/draw_state.cpp @@ -359,16 +359,17 @@ static PIPELINE_NODE* getPipeline(VkPipeline pipeline) // Validate state stored as flags at time of draw call static VkBool32 validate_draw_state_flags(GLOBAL_CB_NODE* pCB, VkBool32 indexedDraw) { VkBool32 result; - result = validate_status(pCB, CBSTATUS_NONE, CBSTATUS_VIEWPORT_SET, CBSTATUS_VIEWPORT_SET, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_VIEWPORT_NOT_BOUND, "Viewport object not bound to this command buffer"); - result |= validate_status(pCB, CBSTATUS_NONE, CBSTATUS_LINE_WIDTH_SET, CBSTATUS_LINE_WIDTH_SET, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_LINE_WIDTH_NOT_BOUND, "Line width object not bound to this command buffer"); - result |= validate_status(pCB, CBSTATUS_NONE, CBSTATUS_DEPTH_BIAS_SET, CBSTATUS_DEPTH_BIAS_SET, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_DEPTH_BIAS_NOT_BOUND, "Depth bias object not bound to this command buffer"); - result |= validate_status(pCB, CBSTATUS_COLOR_BLEND_WRITE_ENABLE, CBSTATUS_BLEND_SET, CBSTATUS_BLEND_SET, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_BLEND_NOT_BOUND, "Blend object not bound to this command buffer"); - result |= validate_status(pCB, CBSTATUS_DEPTH_WRITE_ENABLE, CBSTATUS_DEPTH_BOUNDS_SET, CBSTATUS_DEPTH_BOUNDS_SET, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_DEPTH_BOUNDS_NOT_BOUND, "Depth bounds object not bound to this command buffer"); - result |= validate_status(pCB, CBSTATUS_STENCIL_TEST_ENABLE, CBSTATUS_STENCIL_READ_MASK_SET, CBSTATUS_STENCIL_READ_MASK_SET, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_STENCIL_NOT_BOUND, "Stencil read mask not set on this command buffer"); - result |= validate_status(pCB, CBSTATUS_STENCIL_TEST_ENABLE, CBSTATUS_STENCIL_WRITE_MASK_SET, CBSTATUS_STENCIL_WRITE_MASK_SET, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_STENCIL_NOT_BOUND, "Stencil write mask not set on this command buffer"); - result |= validate_status(pCB, CBSTATUS_STENCIL_TEST_ENABLE, CBSTATUS_STENCIL_REFERENCE_SET, CBSTATUS_STENCIL_REFERENCE_SET, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_STENCIL_NOT_BOUND, "Stencil reference not set on this command buffer"); + result = validate_status(pCB, CBSTATUS_NONE, CBSTATUS_VIEWPORT_SET, CBSTATUS_VIEWPORT_SET, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_VIEWPORT_NOT_BOUND, "Dynamic viewport state not set for this command buffer"); + result |= validate_status(pCB, CBSTATUS_NONE, CBSTATUS_SCISSOR_SET, CBSTATUS_SCISSOR_SET, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_STENCIL_NOT_BOUND, "Dynamic scissor state not set for this command buffer"); + result |= validate_status(pCB, CBSTATUS_NONE, CBSTATUS_LINE_WIDTH_SET, CBSTATUS_LINE_WIDTH_SET, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_LINE_WIDTH_NOT_BOUND, "Dynamic line width state not set for this command buffer"); + result |= validate_status(pCB, CBSTATUS_NONE, CBSTATUS_DEPTH_BIAS_SET, CBSTATUS_DEPTH_BIAS_SET, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_DEPTH_BIAS_NOT_BOUND, "Dynamic depth bias state not set for this command buffer"); + result |= validate_status(pCB, CBSTATUS_COLOR_BLEND_WRITE_ENABLE, CBSTATUS_BLEND_SET, CBSTATUS_BLEND_SET, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_BLEND_NOT_BOUND, "Dynamic blend object state not set for this command buffer"); + result |= validate_status(pCB, CBSTATUS_DEPTH_WRITE_ENABLE, CBSTATUS_DEPTH_BOUNDS_SET, CBSTATUS_DEPTH_BOUNDS_SET, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_DEPTH_BOUNDS_NOT_BOUND, "Dynamic depth bounds state not set for this command buffer"); + result |= validate_status(pCB, CBSTATUS_STENCIL_TEST_ENABLE, CBSTATUS_STENCIL_READ_MASK_SET, CBSTATUS_STENCIL_READ_MASK_SET, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_STENCIL_NOT_BOUND, "Dynamic stencil read mask state not set for this command buffer"); + result |= validate_status(pCB, CBSTATUS_STENCIL_TEST_ENABLE, CBSTATUS_STENCIL_WRITE_MASK_SET, CBSTATUS_STENCIL_WRITE_MASK_SET, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_STENCIL_NOT_BOUND, "Dynamic stencil write mask state not set for this command buffer"); + result |= validate_status(pCB, CBSTATUS_STENCIL_TEST_ENABLE, CBSTATUS_STENCIL_REFERENCE_SET, CBSTATUS_STENCIL_REFERENCE_SET, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_STENCIL_NOT_BOUND, "Dynamic stencil reference state not set for this command buffer"); if (indexedDraw) - result |= validate_status(pCB, CBSTATUS_NONE, CBSTATUS_INDEX_BUFFER_BOUND, CBSTATUS_INDEX_BUFFER_BOUND, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_INDEX_BUFFER_NOT_BOUND, "Index buffer object not bound to this command buffer when Index Draw attempted"); + result |= validate_status(pCB, CBSTATUS_NONE, CBSTATUS_INDEX_BUFFER_BOUND, CBSTATUS_INDEX_BUFFER_BOUND, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_INDEX_BUFFER_NOT_BOUND, "Index buffer object not bound to this command buffer when Indexed Draw attempted"); return result; } // Validate overall state at the time of a draw call @@ -469,7 +470,6 @@ static PIPELINE_NODE* initPipeline(const VkGraphicsPipelineCreateInfo* pCreateIn memset((void*)pPipeline, 0, sizeof(PIPELINE_NODE)); } // First init create info - // TODO : Validate that no create info is incorrectly replicated memcpy(&pPipeline->graphicsPipelineCI, pCreateInfo, sizeof(VkGraphicsPipelineCreateInfo)); size_t bufferSize = 0; @@ -509,7 +509,12 @@ static PIPELINE_NODE* initPipeline(const VkGraphicsPipelineCreateInfo* pCreateIn break; } } - + // Copy over GraphicsPipelineCreateInfo structure embedded pointers + if (pCreateInfo->stageCount != 0) { + pPipeline->graphicsPipelineCI.pStages = new VkPipelineShaderStageCreateInfo[pCreateInfo->stageCount]; + bufferSize = pCreateInfo->stageCount * sizeof(VkPipelineShaderStageCreateInfo); + memcpy((void*)pPipeline->graphicsPipelineCI.pStages, pCreateInfo->pStages, bufferSize); + } if (pCreateInfo->pVertexInputState != NULL) { memcpy((void*)&pPipeline->vertexInputCI, pCreateInfo->pVertexInputState , sizeof(VkPipelineVertexInputStateCreateInfo)); // Copy embedded ptrs @@ -548,6 +553,10 @@ static PIPELINE_NODE* initPipeline(const VkGraphicsPipelineCreateInfo* pCreateIn memcpy((void*)&pPipeline->msStateCI, pCreateInfo->pMultisampleState, sizeof(VkPipelineMultisampleStateCreateInfo)); pPipeline->graphicsPipelineCI.pMultisampleState = &pPipeline->msStateCI; } + if (pCreateInfo->pDepthStencilState != NULL) { + memcpy((void*)&pPipeline->dsStateCI, pCreateInfo->pDepthStencilState, sizeof(VkPipelineDepthStencilStateCreateInfo)); + pPipeline->graphicsPipelineCI.pDepthStencilState = &pPipeline->dsStateCI; + } if (pCreateInfo->pColorBlendState != NULL) { memcpy((void*)&pPipeline->cbStateCI, pCreateInfo->pColorBlendState, sizeof(VkPipelineColorBlendStateCreateInfo)); // Copy embedded ptrs @@ -560,16 +569,14 @@ static PIPELINE_NODE* initPipeline(const VkGraphicsPipelineCreateInfo* pCreateIn } pPipeline->graphicsPipelineCI.pColorBlendState = &pPipeline->cbStateCI; } - if (pCreateInfo->pDepthStencilState != NULL) { - memcpy((void*)&pPipeline->dsStateCI, pCreateInfo->pDepthStencilState, sizeof(VkPipelineDepthStencilStateCreateInfo)); - pPipeline->graphicsPipelineCI.pDepthStencilState = &pPipeline->dsStateCI; - } - - // Copy over GraphicsPipelineCreateInfo structure embedded pointers - if (pCreateInfo->stageCount != 0) { - pPipeline->graphicsPipelineCI.pStages = new VkPipelineShaderStageCreateInfo[pCreateInfo->stageCount]; - bufferSize = pCreateInfo->stageCount * sizeof(VkPipelineShaderStageCreateInfo); - memcpy((void*)pPipeline->graphicsPipelineCI.pStages, pCreateInfo->pStages, bufferSize); + if (pCreateInfo->pDynamicState != NULL) { + memcpy((void*)&pPipeline->dynStateCI, pCreateInfo->pDynamicState, sizeof(VkPipelineDynamicStateCreateInfo)); + if (pPipeline->dynStateCI.dynamicStateCount) { + pPipeline->dynStateCI.pDynamicStates = new VkDynamicState[pPipeline->dynStateCI.dynamicStateCount]; + bufferSize = pPipeline->dynStateCI.dynamicStateCount * sizeof(VkDynamicState); + memcpy((void*)pPipeline->dynStateCI.pDynamicStates, pCreateInfo->pDynamicState->pDynamicStates, bufferSize); + } + pPipeline->graphicsPipelineCI.pDynamicState = &pPipeline->dynStateCI; } return pPipeline; @@ -593,6 +600,9 @@ static void deletePipelines() if ((*ii).second->pAttachments) { delete[] (*ii).second->pAttachments; } + if ((*ii).second->dynStateCI.dynamicStateCount != 0) { + delete[] (*ii).second->dynStateCI.pDynamicStates; + } delete (*ii).second; } pipelineMap.clear(); @@ -1126,7 +1136,7 @@ static void resetCB(const VkCmdBuffer cb) pCB->lastVtxBinding = MAX_BINDING; } } -// Set PSO-related status bits for CB +// Set PSO-related status bits for CB, including dynamic state set via PSO static void set_cb_pso_status(GLOBAL_CB_NODE* pCB, const PIPELINE_NODE* pPipe) { for (uint32_t i = 0; i < pPipe->cbStateCI.attachmentCount; i++) { @@ -1137,10 +1147,46 @@ static void set_cb_pso_status(GLOBAL_CB_NODE* pCB, const PIPELINE_NODE* pPipe) if (pPipe->dsStateCI.depthWriteEnable) { pCB->status |= CBSTATUS_DEPTH_WRITE_ENABLE; } - if (pPipe->dsStateCI.stencilTestEnable) { pCB->status |= CBSTATUS_STENCIL_TEST_ENABLE; } + if (pPipe->dynStateCI.dynamicStateCount) { + // Account for any dynamic state set via this PSO + for (uint32_t i=0; i < pPipe->dynStateCI.dynamicStateCount; i++) { + switch (pPipe->dynStateCI.pDynamicStates[i]) { + case VK_DYNAMIC_STATE_VIEWPORT: + pCB->status |= CBSTATUS_VIEWPORT_SET; + break; + case VK_DYNAMIC_STATE_SCISSOR: + pCB->status |= CBSTATUS_SCISSOR_SET; + break; + case VK_DYNAMIC_STATE_LINE_WIDTH: + pCB->status |= CBSTATUS_LINE_WIDTH_SET; + break; + case VK_DYNAMIC_STATE_DEPTH_BIAS: + pCB->status |= CBSTATUS_DEPTH_BIAS_SET; + break; + case VK_DYNAMIC_STATE_BLEND_CONSTANTS: + pCB->status |= CBSTATUS_BLEND_SET; + break; + case VK_DYNAMIC_STATE_DEPTH_BOUNDS: + pCB->status |= CBSTATUS_DEPTH_BOUNDS_SET; + break; + case VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK: + pCB->status |= CBSTATUS_STENCIL_READ_MASK_SET; + break; + case VK_DYNAMIC_STATE_STENCIL_WRITE_MASK: + pCB->status |= CBSTATUS_STENCIL_WRITE_MASK_SET; + break; + case VK_DYNAMIC_STATE_STENCIL_REFERENCE: + pCB->status |= CBSTATUS_STENCIL_REFERENCE_SET; + break; + default: + // TODO : Flag error here + break; + } + } + } } // Print the last bound Gfx Pipeline static VkBool32 printPipeline(const VkCmdBuffer cb) diff --git a/layers/draw_state.h b/layers/draw_state.h index 1641f8a6..c84eb2e7 100644 --- a/layers/draw_state.h +++ b/layers/draw_state.h @@ -52,13 +52,14 @@ typedef enum _DRAW_STATE_ERROR DRAWSTATE_NO_BEGIN_CMD_BUFFER, // Binding cmds or calling End on CB that never had vkBeginCommandBuffer() called on it DRAWSTATE_CMD_BUFFER_SINGLE_SUBMIT_VIOLATION, // Cmd Buffer created with VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT flag is submitted multiple times DRAWSTATE_INVALID_SECONDARY_CMD_BUFFER, // vkCmdExecuteCommands() called with a primary cmdBuffer in pCmdBuffers array - DRAWSTATE_VIEWPORT_NOT_BOUND, // Draw submitted with no viewport state object bound - DRAWSTATE_LINE_WIDTH_NOT_BOUND, // Draw submitted with no line width state object bound - DRAWSTATE_DEPTH_BIAS_NOT_BOUND, // Draw submitted with no depth bias state object bound - DRAWSTATE_BLEND_NOT_BOUND, // Draw submitted with no blend state object bound when color write enabled - DRAWSTATE_DEPTH_BOUNDS_NOT_BOUND, // Draw submitted with no depth bounds state object bound when depth enabled - DRAWSTATE_STENCIL_NOT_BOUND, // Draw submitted with no stencil state object bound when stencil enabled - DRAWSTATE_INDEX_BUFFER_NOT_BOUND, // Draw submitted with no depth-stencil state object bound when depth write enabled + DRAWSTATE_VIEWPORT_NOT_BOUND, // Draw submitted with no viewport state bound + DRAWSTATE_SCISSOR_NOT_BOUND, // Draw submitted with no scissor state bound + DRAWSTATE_LINE_WIDTH_NOT_BOUND, // Draw submitted with no line width state bound + DRAWSTATE_DEPTH_BIAS_NOT_BOUND, // Draw submitted with no depth bias state bound + DRAWSTATE_BLEND_NOT_BOUND, // Draw submitted with no blend state bound when color write enabled + DRAWSTATE_DEPTH_BOUNDS_NOT_BOUND, // Draw submitted with no depth bounds state bound when depth enabled + DRAWSTATE_STENCIL_NOT_BOUND, // Draw submitted with no stencil state bound when stencil enabled + DRAWSTATE_INDEX_BUFFER_NOT_BOUND, // Draw submitted with no depth-stencil state bound when depth write enabled DRAWSTATE_PIPELINE_LAYOUT_MISMATCH, // Draw submitted PSO Pipeline layout that doesn't match layout from BindDescriptorSets DRAWSTATE_INVALID_RENDERPASS, // Use of a NULL or otherwise invalid RenderPass object DRAWSTATE_INVALID_RENDERPASS_CMD, // Invalid cmd submitted while a RenderPass is active @@ -101,6 +102,7 @@ typedef struct _PIPELINE_NODE { VkPipelineMultisampleStateCreateInfo msStateCI; VkPipelineColorBlendStateCreateInfo cbStateCI; VkPipelineDepthStencilStateCreateInfo dsStateCI; + VkPipelineDynamicStateCreateInfo dynStateCI; VkPipelineShaderStageCreateInfo vsCI; VkPipelineShaderStageCreateInfo tcsCI; VkPipelineShaderStageCreateInfo tesCI; @@ -110,7 +112,6 @@ typedef struct _PIPELINE_NODE { VkComputePipelineCreateInfo computePipelineCI; // Flag of which shader stages are active for this pipeline uint32_t active_shaders; - VkGraphicsPipelineCreateInfo* pCreateTree; // Ptr to shadow of data in create tree // Vtx input info (if any) uint32_t vtxBindingCount; // number of bindings VkVertexInputBindingDescription* pVertexBindingDescriptions; diff --git a/layers/vk_validation_layer_details.md b/layers/vk_validation_layer_details.md index c6e7a679..80081328 100644 --- a/layers/vk_validation_layer_details.md +++ b/layers/vk_validation_layer_details.md @@ -34,6 +34,7 @@ The DrawState layer tracks state leading into Draw cmds. This includes the Pipel | DS Update Type | Verifies that structs in DS Update tree are properly created, currenly valid, and of the right type | INVALID_UPDATE_STRUCT | vkUpdateDescriptorSets | InvalidDSUpdateStruct | NA | | MSAA Sample Count | Verifies that Pipeline, RenderPass, and Subpass sample counts are consistent | NUM_SAMPLES_MISMATCH | vkCmdBindPipeline vkCmdBeginRenderPass vkCmdNextSubpass | NumSamplesMismatch | NA | | Dynamic Viewport State Binding | Verify that viewport dynamic state bound to Cmd Buffer at Draw time | VIEWPORT_NOT_BOUND |vkCmdDraw vkCmdDrawIndexed vkCmdDrawIndirect vkCmdDrawIndexedIndirect | ViewportStateNotBound | NA | +| Dynamic Scissor State Binding | Verify that scissor dynamic state bound to Cmd Buffer at Draw time | SCISSOR_NOT_BOUND |vkCmdDraw vkCmdDrawIndexed vkCmdDrawIndirect vkCmdDrawIndexedIndirect | ScissorStateNotBound | NA | | Dynamic Line Width State Binding | Verify that line width dynamic state bound to Cmd Buffer at when required (TODO : Verify when this is) | LINE_WIDTH_NOT_BOUND |vkCmdDraw vkCmdDrawIndexed vkCmdDrawIndirect vkCmdDrawIndexedIndirect | TODO | Verify this check and Write targeted test | | Dynamic Depth Bias State Binding | Verify that depth bias dynamic state bound when depth enabled | DEPTH_BIAS_NOT_BOUND |vkCmdDraw vkCmdDrawIndexed vkCmdDrawIndirect vkCmdDrawIndexedIndirect | TODO | Verify this check and Write targeted test | | Dynamic Blend State Binding | Verify that blend dynamic state bound when color blend enabled | BLEND_NOT_BOUND |vkCmdDraw vkCmdDrawIndexed vkCmdDrawIndirect vkCmdDrawIndexedIndirect | TODO | Verify this check and Write targeted test | @@ -75,6 +76,7 @@ Additional checks to be added to DrawState 29. Flag an error if CmdBuffer has Begin called while it's being constructed - this is not a reset, this is a violation 30. At PSO creation time, there is no case when NOT including a FS should flag an error since there exist dynamic state configurations that can be set to cause a FS to not be required. Instead, in the case when no FS is in the PSO, validation should detect at runtime if dynamic state will require a FS, and in those case issue a runtime warning about undefined behavior. (see bug https://cvs.khronos.org/bugzilla/show_bug.cgi?id=14429) 31. Error if a cmdbuffer is submitted on a queue whose family doesn't match the family of the pool from which it was created. + 32. Update Gfx Pipe Create Info shadowing to remove new/delete and instead use unique_ptrs for auto clean-up ## ParamChecker @@ -222,6 +224,7 @@ The ObjectTracker layer maintains a record of all Vulkan objects. It flags error 7. Verify cube array VkImageView objects use subresourceRange.arraySize (or effective arraySize when VK_REMAINING_ARRAY_SLICES is specified) that is a multiple of 6. 8. Make object maps specific to instance and device. Objects may only be used with matching instance or device. 9. Use reference counting for non-dispatchable objects. Multiple object creation calls may return identical handles. + 10. Update codegen for destroy_obj & validate_obj to generate all of the correct signatures and use the generated code ## Threading |
