diff options
| author | Mark Lobodzinski <mark@lunarg.com> | 2017-05-16 09:14:35 -0600 |
|---|---|---|
| committer | Mark Lobodzinski <mark@lunarg.com> | 2017-05-18 09:31:58 -0600 |
| commit | e847c032bb7083ab18c2185f02a16737e0f42c74 (patch) | |
| tree | deb9a3216dbac344cfb03c1a451ba52989f50559 | |
| parent | 93e402828567b4312dbbbd15bcdba4c6a7df18d5 (diff) | |
| download | usermoji-e847c032bb7083ab18c2185f02a16737e0f42c74.tar.xz | |
layers: GH1756, Fix null pInteritanceInfo deref
Trying to execute an unrecorded secondary command buffer in an
active renderpass resulted in a nullptr dereference. Added null check
along with a warning for unrecorded command buffers.
Change-Id: I67f34da57a9eda422f2321ddc6f28b863c999f5b
| -rw-r--r-- | layers/core_validation.cpp | 71 | ||||
| -rw-r--r-- | layers/vk_validation_error_database.txt | 4 |
2 files changed, 42 insertions, 33 deletions
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp index c7c125ea..471a0b01 100644 --- a/layers/core_validation.cpp +++ b/layers/core_validation.cpp @@ -3904,7 +3904,7 @@ static bool validateCommandBufferSimultaneousUse(layer_data *dev_data, GLOBAL_CB } static bool validateCommandBufferState(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, const char *call_source, - int current_submit_count) { + int current_submit_count, UNIQUE_VALIDATION_ERROR_CODE vu_id) { bool skip = false; if (dev_data->instance_data->disabled.command_buffer_state) return skip; // Validate ONE_TIME_SUBMIT_BIT CB is not being submitted more than once @@ -3920,6 +3920,11 @@ static bool validateCommandBufferState(layer_data *dev_data, GLOBAL_CB_NODE *cb_ if (CB_RECORDED != cb_state->state) { if (CB_INVALID == cb_state->state) { skip |= ReportInvalidCommandBuffer(dev_data, cb_state, call_source); + } else if (CB_NEW == cb_state->state) { + skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, + (uint64_t)(cb_state->commandBuffer), __LINE__, vu_id, "DS", + "Command buffer 0x%p used in the call to %s is unrecorded and contains no commands. %s", + cb_state->commandBuffer, call_source, validation_error_map[vu_id]); } else { // Flag error for using CB w/o vkEndCommandBuffer() called skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, HandleToUint64(cb_state->commandBuffer), __LINE__, DRAWSTATE_NO_END_COMMAND_BUFFER, "DS", @@ -4039,7 +4044,7 @@ static bool validatePrimaryCommandBufferState(layer_data *dev_data, GLOBAL_CB_NO } } - skip |= validateCommandBufferState(dev_data, pCB, "vkQueueSubmit()", current_submit_count); + skip |= validateCommandBufferState(dev_data, pCB, "vkQueueSubmit()", current_submit_count, VALIDATION_ERROR_00134); return skip; } @@ -9515,41 +9520,45 @@ VKAPI_ATTR void VKAPI_CALL CmdExecuteCommands(VkCommandBuffer commandBuffer, uin "array. All cmd buffers in pCommandBuffers array must be secondary. %s", pCommandBuffers[i], i, validation_error_map[VALIDATION_ERROR_00156]); } else if (pCB->activeRenderPass) { // Secondary CB w/i RenderPass must have *CONTINUE_BIT set - auto secondary_rp_state = GetRenderPassState(dev_data, pSubCB->beginInfo.pInheritanceInfo->renderPass); - if (!(pSubCB->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) { - skip |= log_msg( - dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, - HandleToUint64(pCommandBuffers[i]), __LINE__, VALIDATION_ERROR_02057, "DS", - "vkCmdExecuteCommands(): Secondary Command Buffer (0x%p) executed within render pass (0x%" PRIxLEAST64 - ") must have had vkBeginCommandBuffer() called w/ VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT set. %s", - pCommandBuffers[i], HandleToUint64(pCB->activeRenderPass->renderPass), - validation_error_map[VALIDATION_ERROR_02057]); - } else { - // Make sure render pass is compatible with parent command buffer pass if has continue - if (pCB->activeRenderPass->renderPass != secondary_rp_state->renderPass) { - skip |= validateRenderPassCompatibility(dev_data, commandBuffer, pCB->activeRenderPass->createInfo.ptr(), + if (pSubCB->beginInfo.pInheritanceInfo != nullptr) { + auto secondary_rp_state = GetRenderPassState(dev_data, pSubCB->beginInfo.pInheritanceInfo->renderPass); + if (!(pSubCB->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) { + skip |= log_msg( + dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, + HandleToUint64(pCommandBuffers[i]), __LINE__, VALIDATION_ERROR_02057, "DS", + "vkCmdExecuteCommands(): Secondary Command Buffer (0x%p) executed within render pass (0x%" PRIxLEAST64 + ") must have had vkBeginCommandBuffer() called w/ VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT " + "set. %s", + pCommandBuffers[i], HandleToUint64(pCB->activeRenderPass->renderPass), + validation_error_map[VALIDATION_ERROR_02057]); + } else { + // Make sure render pass is compatible with parent command buffer pass if has continue + if (pCB->activeRenderPass->renderPass != secondary_rp_state->renderPass) { + skip |= + validateRenderPassCompatibility(dev_data, commandBuffer, pCB->activeRenderPass->createInfo.ptr(), pCommandBuffers[i], secondary_rp_state->createInfo.ptr()); + } + // If framebuffer for secondary CB is not NULL, then it must match active FB from primaryCB + skip |= validateFramebuffer(dev_data, commandBuffer, pCB, pCommandBuffers[i], pSubCB); + } + string errorString = ""; + // secondaryCB must have been created w/ RP compatible w/ primaryCB active renderpass + if ((pCB->activeRenderPass->renderPass != secondary_rp_state->renderPass) && + !verify_renderpass_compatibility(dev_data, pCB->activeRenderPass->createInfo.ptr(), + secondary_rp_state->createInfo.ptr(), errorString)) { + skip |= log_msg( + dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, + HandleToUint64(pCommandBuffers[i]), __LINE__, DRAWSTATE_RENDERPASS_INCOMPATIBLE, "DS", + "vkCmdExecuteCommands(): Secondary Command Buffer (0x%p) w/ render pass (0x%" PRIxLEAST64 + ") is incompatible w/ primary command buffer (0x%p) w/ render pass (0x%" PRIxLEAST64 ") due to: %s", + pCommandBuffers[i], HandleToUint64(pSubCB->beginInfo.pInheritanceInfo->renderPass), commandBuffer, + HandleToUint64(pCB->activeRenderPass->renderPass), errorString.c_str()); } - // If framebuffer for secondary CB is not NULL, then it must match active FB from primaryCB - skip |= validateFramebuffer(dev_data, commandBuffer, pCB, pCommandBuffers[i], pSubCB); - } - string errorString = ""; - // secondaryCB must have been created w/ RP compatible w/ primaryCB active renderpass - if ((pCB->activeRenderPass->renderPass != secondary_rp_state->renderPass) && - !verify_renderpass_compatibility(dev_data, pCB->activeRenderPass->createInfo.ptr(), - secondary_rp_state->createInfo.ptr(), errorString)) { - skip |= log_msg( - dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, - HandleToUint64(pCommandBuffers[i]), __LINE__, DRAWSTATE_RENDERPASS_INCOMPATIBLE, "DS", - "vkCmdExecuteCommands(): Secondary Command Buffer (0x%p) w/ render pass (0x%" PRIxLEAST64 - ") is incompatible w/ primary command buffer (0x%p) w/ render pass (0x%" PRIxLEAST64 ") due to: %s", - pCommandBuffers[i], HandleToUint64(pSubCB->beginInfo.pInheritanceInfo->renderPass), commandBuffer, - HandleToUint64(pCB->activeRenderPass->renderPass), errorString.c_str()); } } // TODO(mlentine): Move more logic into this method skip |= validateSecondaryCommandBufferState(dev_data, pCB, pSubCB); - skip |= validateCommandBufferState(dev_data, pSubCB, "vkCmdExecuteCommands()", 0); + skip |= validateCommandBufferState(dev_data, pSubCB, "vkCmdExecuteCommands()", 0, VALIDATION_ERROR_00155); // Secondary cmdBuffers are considered pending execution starting w/ // being recorded if (!(pSubCB->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT)) { diff --git a/layers/vk_validation_error_database.txt b/layers/vk_validation_error_database.txt index c42d9581..7554f238 100644 --- a/layers/vk_validation_error_database.txt +++ b/layers/vk_validation_error_database.txt @@ -129,7 +129,7 @@ VALIDATION_ERROR_00130~^~Y~^~None~^~vkQueueSubmit~^~For more information refer t VALIDATION_ERROR_00131~^~Y~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.5. Command Buffer Submission' which states 'Both of fence, and queue that are valid handles must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VUID-vkQueueSubmit-pCommandBuffers-00074)~^~implicit VALIDATION_ERROR_00132~^~N~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.5. Command Buffer Submission' which states 'Any given element of the pSignalSemaphores member of any element of pSubmits must be unsignaled when the semaphore signal operation it defines is executed on the device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkQueueSubmit)~^~ VALIDATION_ERROR_00133~^~Y~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.5. Command Buffer Submission' which states 'If any given element of the pCommandBuffers member of any element of pSubmits was not recorded with the VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, it must not be in the pending state.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkQueueSubmit)~^~ -VALIDATION_ERROR_00134~^~N~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.5. Command Buffer Submission' which states 'Any secondary command buffers recorded into any given element of the pCommandBuffers member of any element of pSubmits must be in the pending or executable state.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkQueueSubmit)~^~ +VALIDATION_ERROR_00134~^~Y~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.5. Command Buffer Submission' which states 'Any secondary command buffers recorded into any given element of the pCommandBuffers member of any element of pSubmits must be in the pending or executable state.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkQueueSubmit)~^~ VALIDATION_ERROR_00135~^~Y~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.5. Command Buffer Submission' which states 'If any secondary command buffers recorded into any given element of the pCommandBuffers member of any element of pSubmits was not recorded with the VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, it must not be in the pending state.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkQueueSubmit)~^~ VALIDATION_ERROR_00139~^~Y~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.5. Command Buffer Submission' which states 'Any given element of the pCommandBuffers member of any element of pSubmits must have been allocated from a VkCommandPool that was created for the same queue family queue belongs to.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkQueueSubmit)~^~ VALIDATION_ERROR_00140~^~N~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.5. Command Buffer Submission' which states 'Any given element of pCommandBuffers must not have been allocated with VK_COMMAND_BUFFER_LEVEL_SECONDARY' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkSubmitInfo)~^~ @@ -145,7 +145,7 @@ VALIDATION_ERROR_00150~^~Y~^~None~^~vkQueueSubmit~^~For more information refer t VALIDATION_ERROR_00151~^~Y~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.5. Command Buffer Submission' which states 'Each of the elements of pCommandBuffers, the elements of pSignalSemaphores, and the elements of pWaitSemaphores that are valid handles must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VUID-VkSubmitInfo-pWaitDstStageMask-00078)~^~implicit VALIDATION_ERROR_00152~^~N~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.7. Secondary Command Buffer Execution' which states 'commandBuffer must have been allocated with a level of VK_COMMAND_BUFFER_LEVEL_PRIMARY' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkCmdExecuteCommands)~^~ VALIDATION_ERROR_00154~^~Y~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.7. Secondary Command Buffer Execution' which states 'If any element of pCommandBuffers was not recorded with the VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT flag, and it was recorded into any other primary command buffer, that primary command buffer must not be in the pending state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkCmdExecuteCommands)~^~ -VALIDATION_ERROR_00155~^~N~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.7. Secondary Command Buffer Execution' which states 'Any given element of pCommandBuffers must be in the pending or executable state.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkCmdExecuteCommands)~^~ +VALIDATION_ERROR_00155~^~Y~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.7. Secondary Command Buffer Execution' which states 'Any given element of pCommandBuffers must be in the pending or executable state.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkCmdExecuteCommands)~^~ VALIDATION_ERROR_00156~^~Y~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.7. Secondary Command Buffer Execution' which states 'Any given element of pCommandBuffers must have been allocated with a level of VK_COMMAND_BUFFER_LEVEL_SECONDARY' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkCmdExecuteCommands)~^~ VALIDATION_ERROR_00157~^~N~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.7. Secondary Command Buffer Execution' which states 'Any given element of pCommandBuffers must have been allocated from a VkCommandPool that was created for the same queue family as the VkCommandPool from which commandBuffer was allocated' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkCmdExecuteCommands)~^~ VALIDATION_ERROR_00158~^~N~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.7. Secondary Command Buffer Execution' which states 'If vkCmdExecuteCommands is being called within a render pass instance, that render pass instance must have been begun with the contents parameter of vkCmdBeginRenderPass set to VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkCmdExecuteCommands)~^~ |
