From b8ba12167798f6c07e9208a0b09cb563e673977e Mon Sep 17 00:00:00 2001 From: Mike Schuchardt Date: Thu, 23 Feb 2017 15:57:37 -0700 Subject: [PATCH] layers: Add VU enums to VkQueueFlag checks Split validation of command pool queue flag checks into a dedicated function and add valid usage error enums. Change-Id: I4fc4e71d96b818c281ad310dd0d15bca508efb94 --- layers/buffer_validation.cpp | 14 ++ layers/core_validation.cpp | 182 +++++++++++------------- layers/core_validation_types.h | 2 + layers/vk_validation_error_database.txt | 84 +++++------ 4 files changed, 144 insertions(+), 138 deletions(-) diff --git a/layers/buffer_validation.cpp b/layers/buffer_validation.cpp index a3aee898..2dca9ed0 100644 --- a/layers/buffer_validation.cpp +++ b/layers/buffer_validation.cpp @@ -945,6 +945,8 @@ bool PreCallValidateCmdClearColorImage(layer_data *dev_data, VkCommandBuffer com auto image_state = GetImageState(dev_data, image); if (cb_node && image_state) { skip |= ValidateMemoryIsBoundToImage(dev_data, image_state, "vkCmdClearColorImage()", VALIDATION_ERROR_02527); + skip |= ValidateCmdQueueFlags(dev_data, cb_node, "vkCmdClearColorImage()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, + VALIDATION_ERROR_01095); skip |= ValidateCmd(dev_data, cb_node, CMD_CLEARCOLORIMAGE, "vkCmdClearColorImage()"); skip |= insideRenderPass(dev_data, cb_node, "vkCmdClearColorImage()", VALIDATION_ERROR_01096); for (uint32_t i = 0; i < rangeCount; ++i) { @@ -985,6 +987,8 @@ bool PreCallValidateCmdClearDepthStencilImage(layer_data *device_data, VkCommand auto image_state = GetImageState(device_data, image); if (cb_node && image_state) { skip |= ValidateMemoryIsBoundToImage(device_data, image_state, "vkCmdClearDepthStencilImage()", VALIDATION_ERROR_02528); + skip |= ValidateCmdQueueFlags(device_data, cb_node, "vkCmdClearDepthStencilImage()", VK_QUEUE_GRAPHICS_BIT, + VALIDATION_ERROR_01110); skip |= ValidateCmd(device_data, cb_node, CMD_CLEARDEPTHSTENCILIMAGE, "vkCmdClearDepthStencilImage()"); skip |= insideRenderPass(device_data, cb_node, "vkCmdClearDepthStencilImage()", VALIDATION_ERROR_01111); for (uint32_t i = 0; i < rangeCount; ++i) { @@ -1481,6 +1485,8 @@ bool PreCallValidateCmdCopyImage(layer_data *device_data, GLOBAL_CB_NODE *cb_nod "vkCmdCopyImage()", "VK_IMAGE_USAGE_TRANSFER_SRC_BIT"); skip |= ValidateImageUsageFlags(device_data, dst_image_state, VK_IMAGE_USAGE_TRANSFER_DST_BIT, true, VALIDATION_ERROR_01181, "vkCmdCopyImage()", "VK_IMAGE_USAGE_TRANSFER_DST_BIT"); + skip |= ValidateCmdQueueFlags(device_data, cb_node, "vkCmdCopyImage()", + VK_QUEUE_TRANSFER_BIT | VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, VALIDATION_ERROR_01193); skip |= ValidateCmd(device_data, cb_node, CMD_COPYIMAGE, "vkCmdCopyImage()"); skip |= insideRenderPass(device_data, cb_node, "vkCmdCopyImage()", VALIDATION_ERROR_01194); for (uint32_t i = 0; i < region_count; ++i) { @@ -1542,6 +1548,8 @@ bool PreCallValidateCmdClearAttachments(layer_data *device_data, VkCommandBuffer bool skip = false; if (cb_node) { + skip |= + ValidateCmdQueueFlags(device_data, cb_node, "vkCmdClearAttachments()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_01121); skip |= ValidateCmd(device_data, cb_node, CMD_CLEARATTACHMENTS, "vkCmdClearAttachments()"); core_validation::UpdateCmdBufferLastCmd(cb_node, CMD_CLEARATTACHMENTS); // Warn if this is issued prior to Draw Cmd and clearing the entire attachment @@ -1661,6 +1669,7 @@ bool PreCallValidateCmdResolveImage(layer_data *device_data, GLOBAL_CB_NODE *cb_ if (cb_node && src_image_state && dst_image_state) { skip |= ValidateMemoryIsBoundToImage(device_data, src_image_state, "vkCmdResolveImage()", VALIDATION_ERROR_02541); skip |= ValidateMemoryIsBoundToImage(device_data, dst_image_state, "vkCmdResolveImage()", VALIDATION_ERROR_02542); + skip |= ValidateCmdQueueFlags(device_data, cb_node, "vkCmdResolveImage()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_01334); skip |= ValidateCmd(device_data, cb_node, CMD_RESOLVEIMAGE, "vkCmdResolveImage()"); skip |= insideRenderPass(device_data, cb_node, "vkCmdResolveImage()", VALIDATION_ERROR_01335); @@ -1760,6 +1769,7 @@ bool PreCallValidateCmdBlitImage(layer_data *device_data, GLOBAL_CB_NODE *cb_nod "vkCmdBlitImage()", "VK_IMAGE_USAGE_TRANSFER_SRC_BIT"); skip |= ValidateImageUsageFlags(device_data, dst_image_state, VK_IMAGE_USAGE_TRANSFER_DST_BIT, true, VALIDATION_ERROR_02186, "vkCmdBlitImage()", "VK_IMAGE_USAGE_TRANSFER_DST_BIT"); + skip |= ValidateCmdQueueFlags(device_data, cb_node, "vkCmdBlitImage()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_01299); skip |= ValidateCmd(device_data, cb_node, CMD_BLITIMAGE, "vkCmdBlitImage()"); skip |= insideRenderPass(device_data, cb_node, "vkCmdBlitImage()", VALIDATION_ERROR_01300); @@ -2516,6 +2526,8 @@ bool PreCallValidateCmdCopyBuffer(layer_data *device_data, GLOBAL_CB_NODE *cb_no "vkCmdCopyBuffer()", "VK_BUFFER_USAGE_TRANSFER_SRC_BIT"); skip |= ValidateBufferUsageFlags(device_data, dst_buffer_state, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true, VALIDATION_ERROR_01165, "vkCmdCopyBuffer()", "VK_BUFFER_USAGE_TRANSFER_DST_BIT"); + skip |= ValidateCmdQueueFlags(device_data, cb_node, "vkCmdCopyBuffer()", + VK_QUEUE_TRANSFER_BIT | VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, VALIDATION_ERROR_01171); skip |= ValidateCmd(device_data, cb_node, CMD_COPYBUFFER, "vkCmdCopyBuffer()"); skip |= insideRenderPass(device_data, cb_node, "vkCmdCopyBuffer()", VALIDATION_ERROR_01172); return skip; @@ -2622,6 +2634,8 @@ void PostCallRecordDestroyBufferView(layer_data *device_data, VkBufferView buffe bool PreCallValidateCmdFillBuffer(layer_data *device_data, GLOBAL_CB_NODE *cb_node, BUFFER_STATE *buffer_state) { bool skip = false; skip |= ValidateMemoryIsBoundToBuffer(device_data, buffer_state, "vkCmdFillBuffer()", VALIDATION_ERROR_02529); + skip |= ValidateCmdQueueFlags(device_data, cb_node, "vkCmdFillBuffer()", + VK_QUEUE_TRANSFER_BIT | VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, VALIDATION_ERROR_01141); skip |= ValidateCmd(device_data, cb_node, CMD_FILLBUFFER, "vkCmdFillBuffer()"); // Validate that DST buffer has correct usage flags set skip |= ValidateBufferUsageFlags(device_data, buffer_state, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true, VALIDATION_ERROR_01137, diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp index ffe8e7ad..0ac46a00 100644 --- a/layers/core_validation.cpp +++ b/layers/core_validation.cpp @@ -3452,28 +3452,27 @@ bool ValidateCmdSubpassState(const layer_data *dev_data, const GLOBAL_CB_NODE *p return skip_call; } -static bool checkGraphicsBit(const layer_data *dev_data, VkCommandBuffer command_buffer, VkQueueFlags flags, const char *name) { - if (!(flags & VK_QUEUE_GRAPHICS_BIT)) - return log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, - reinterpret_cast(command_buffer), __LINE__, DRAWSTATE_INVALID_COMMAND_BUFFER, "DS", - "Cannot call %s on a command buffer allocated from a pool without graphics capabilities.", name); - return false; -} - -static bool checkComputeBit(const layer_data *dev_data, VkCommandBuffer command_buffer, VkQueueFlags flags, const char *name) { - if (!(flags & VK_QUEUE_COMPUTE_BIT)) - return log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, - reinterpret_cast(command_buffer), __LINE__, DRAWSTATE_INVALID_COMMAND_BUFFER, "DS", - "Cannot call %s on a command buffer allocated from a pool without compute capabilities.", name); - return false; -} - -static bool checkGraphicsOrComputeBit(const layer_data *dev_data, VkCommandBuffer command_buffer, VkQueueFlags flags, - const char *name) { - if (!((flags & VK_QUEUE_GRAPHICS_BIT) || (flags & VK_QUEUE_COMPUTE_BIT))) - return log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, - reinterpret_cast(command_buffer), __LINE__, DRAWSTATE_INVALID_COMMAND_BUFFER, "DS", - "Cannot call %s on a command buffer allocated from a pool without graphics or compute capabilities.", name); +bool ValidateCmdQueueFlags(layer_data *dev_data, GLOBAL_CB_NODE *cb_node, const char *caller_name, VkQueueFlags required_flags, + UNIQUE_VALIDATION_ERROR_CODE error_code) { + auto pool = GetCommandPoolNode(dev_data, cb_node->createInfo.commandPool); + if (pool) { + VkQueueFlags queue_flags = dev_data->phys_dev_properties.queue_family_properties[pool->queueFamilyIndex].queueFlags; + if (!(required_flags & queue_flags)) { + string required_flags_string; + for (auto flag : {VK_QUEUE_TRANSFER_BIT, VK_QUEUE_GRAPHICS_BIT, VK_QUEUE_COMPUTE_BIT}) { + if (flag & required_flags) { + if (required_flags_string.size()) { + required_flags_string += " or "; + } + required_flags_string += string_VkQueueFlagBits(flag); + } + } + return log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, + reinterpret_cast(cb_node->commandBuffer), __LINE__, error_code, "DS", + "Cannot call %s on a command buffer allocated from a pool without %s capabilities. %s.", caller_name, + required_flags_string.c_str(), validation_error_map[error_code]); + } + } return false; } @@ -3495,67 +3494,6 @@ static bool ReportInvalidCommandBuffer(layer_data *dev_data, GLOBAL_CB_NODE *cb_ // there's an issue with the Cmd ordering bool ValidateCmd(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, const CMD_TYPE cmd, const char *caller_name) { bool skip = false; - auto command_pool = GetCommandPoolNode(dev_data, cb_state->createInfo.commandPool); - if (command_pool) { - VkQueueFlags flags = dev_data->phys_dev_properties.queue_family_properties[command_pool->queueFamilyIndex].queueFlags; - switch (cmd) { - case CMD_BINDPIPELINE: - case CMD_BINDPIPELINEDELTA: - case CMD_BINDDESCRIPTORSETS: - case CMD_FILLBUFFER: - case CMD_CLEARCOLORIMAGE: - case CMD_SETEVENT: - case CMD_RESETEVENT: - case CMD_WAITEVENTS: - case CMD_BEGINQUERY: - case CMD_ENDQUERY: - case CMD_RESETQUERYPOOL: - case CMD_COPYQUERYPOOLRESULTS: - case CMD_WRITETIMESTAMP: - skip |= checkGraphicsOrComputeBit(dev_data, cb_state->commandBuffer, flags, cmdTypeToString(cmd).c_str()); - break; - case CMD_SETVIEWPORTSTATE: - case CMD_SETSCISSORSTATE: - case CMD_SETLINEWIDTHSTATE: - case CMD_SETDEPTHBIASSTATE: - case CMD_SETBLENDSTATE: - case CMD_SETDEPTHBOUNDSSTATE: - case CMD_SETSTENCILREADMASKSTATE: - case CMD_SETSTENCILWRITEMASKSTATE: - case CMD_SETSTENCILREFERENCESTATE: - case CMD_BINDINDEXBUFFER: - case CMD_BINDVERTEXBUFFER: - case CMD_DRAW: - case CMD_DRAWINDEXED: - case CMD_DRAWINDIRECT: - case CMD_DRAWINDEXEDINDIRECT: - case CMD_BLITIMAGE: - case CMD_CLEARATTACHMENTS: - case CMD_CLEARDEPTHSTENCILIMAGE: - case CMD_RESOLVEIMAGE: - case CMD_BEGINRENDERPASS: - case CMD_NEXTSUBPASS: - case CMD_ENDRENDERPASS: - skip |= checkGraphicsBit(dev_data, cb_state->commandBuffer, flags, cmdTypeToString(cmd).c_str()); - break; - case CMD_DISPATCH: - case CMD_DISPATCHINDIRECT: - skip |= checkComputeBit(dev_data, cb_state->commandBuffer, flags, cmdTypeToString(cmd).c_str()); - break; - case CMD_COPYBUFFER: - case CMD_COPYIMAGE: - case CMD_COPYBUFFERTOIMAGE: - case CMD_COPYIMAGETOBUFFER: - case CMD_CLONEIMAGEDATA: - case CMD_UPDATEBUFFER: - case CMD_PIPELINEBARRIER: - case CMD_EXECUTECOMMANDS: - case CMD_END: - break; - default: - break; - } - } if (cb_state->state != CB_RECORDING) { if (cb_state->state == CB_INVALID) { skip |= ReportInvalidCommandBuffer(dev_data, cb_state, caller_name); @@ -7117,6 +7055,8 @@ VKAPI_ATTR void VKAPI_CALL CmdBindPipeline(VkCommandBuffer commandBuffer, VkPipe std::unique_lock lock(global_lock); GLOBAL_CB_NODE *cb_state = GetCBNode(dev_data, commandBuffer); if (cb_state) { + skip |= ValidateCmdQueueFlags(dev_data, cb_state, "vkCmdBindPipeline()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, + VALIDATION_ERROR_00603); skip |= ValidateCmd(dev_data, cb_state, CMD_BINDPIPELINE, "vkCmdBindPipeline()"); UpdateCmdBufferLastCmd(cb_state, CMD_BINDPIPELINE); if ((VK_PIPELINE_BIND_POINT_COMPUTE == pipelineBindPoint) && (cb_state->activeRenderPass)) { @@ -7163,6 +7103,7 @@ VKAPI_ATTR void VKAPI_CALL CmdSetViewport(VkCommandBuffer commandBuffer, uint32_ std::unique_lock lock(global_lock); GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); if (pCB) { + skip_call |= ValidateCmdQueueFlags(dev_data, pCB, "vkCmdSetViewport()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_01446); skip_call |= ValidateCmd(dev_data, pCB, CMD_SETVIEWPORTSTATE, "vkCmdSetViewport()"); UpdateCmdBufferLastCmd(pCB, CMD_SETVIEWPORTSTATE); pCB->viewportMask |= ((1u << viewportCount) - 1u) << firstViewport; @@ -7178,6 +7119,7 @@ VKAPI_ATTR void VKAPI_CALL CmdSetScissor(VkCommandBuffer commandBuffer, uint32_t std::unique_lock lock(global_lock); GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); if (pCB) { + skip_call |= ValidateCmdQueueFlags(dev_data, pCB, "vkCmdSetScissor()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_01495); skip_call |= ValidateCmd(dev_data, pCB, CMD_SETSCISSORSTATE, "vkCmdSetScissor()"); UpdateCmdBufferLastCmd(pCB, CMD_SETSCISSORSTATE); pCB->scissorMask |= ((1u << scissorCount) - 1u) << firstScissor; @@ -7192,6 +7134,7 @@ VKAPI_ATTR void VKAPI_CALL CmdSetLineWidth(VkCommandBuffer commandBuffer, float std::unique_lock lock(global_lock); GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); if (pCB) { + skip_call |= ValidateCmdQueueFlags(dev_data, pCB, "vkCmdSetLineWidth()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_01480); skip_call |= ValidateCmd(dev_data, pCB, CMD_SETLINEWIDTHSTATE, "vkCmdSetLineWidth()"); UpdateCmdBufferLastCmd(pCB, CMD_SETLINEWIDTHSTATE); pCB->status |= CBSTATUS_LINE_WIDTH_SET; @@ -7220,6 +7163,7 @@ VKAPI_ATTR void VKAPI_CALL CmdSetDepthBias(VkCommandBuffer commandBuffer, float std::unique_lock lock(global_lock); GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); if (pCB) { + skip_call |= ValidateCmdQueueFlags(dev_data, pCB, "vkCmdSetDepthBias()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_01485); skip_call |= ValidateCmd(dev_data, pCB, CMD_SETDEPTHBIASSTATE, "vkCmdSetDepthBias()"); if ((depthBiasClamp != 0.0) && (!dev_data->enabled_features.depthBiasClamp)) { skip_call |= @@ -7245,6 +7189,8 @@ VKAPI_ATTR void VKAPI_CALL CmdSetBlendConstants(VkCommandBuffer commandBuffer, c std::unique_lock lock(global_lock); GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); if (pCB) { + skip_call |= + ValidateCmdQueueFlags(dev_data, pCB, "vkCmdSetBlendConstants()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_01553); skip_call |= ValidateCmd(dev_data, pCB, CMD_SETBLENDSTATE, "vkCmdSetBlendConstants()"); UpdateCmdBufferLastCmd(pCB, CMD_SETBLENDSTATE); pCB->status |= CBSTATUS_BLEND_CONSTANTS_SET; @@ -7259,6 +7205,7 @@ VKAPI_ATTR void VKAPI_CALL CmdSetDepthBounds(VkCommandBuffer commandBuffer, floa std::unique_lock lock(global_lock); GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); if (pCB) { + skip_call |= ValidateCmdQueueFlags(dev_data, pCB, "vkCmdSetDepthBounds()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_01509); skip_call |= ValidateCmd(dev_data, pCB, CMD_SETDEPTHBOUNDSSTATE, "vkCmdSetDepthBounds()"); UpdateCmdBufferLastCmd(pCB, CMD_SETDEPTHBOUNDSSTATE); pCB->status |= CBSTATUS_DEPTH_BOUNDS_SET; @@ -7274,6 +7221,8 @@ VKAPI_ATTR void VKAPI_CALL CmdSetStencilCompareMask(VkCommandBuffer commandBuffe std::unique_lock lock(global_lock); GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); if (pCB) { + skip_call |= + ValidateCmdQueueFlags(dev_data, pCB, "vkCmdSetStencilCompareMask()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_01519); skip_call |= ValidateCmd(dev_data, pCB, CMD_SETSTENCILREADMASKSTATE, "vkCmdSetStencilCompareMask()"); UpdateCmdBufferLastCmd(pCB, CMD_SETSTENCILREADMASKSTATE); pCB->status |= CBSTATUS_STENCIL_READ_MASK_SET; @@ -7288,6 +7237,8 @@ VKAPI_ATTR void VKAPI_CALL CmdSetStencilWriteMask(VkCommandBuffer commandBuffer, std::unique_lock lock(global_lock); GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); if (pCB) { + skip_call |= + ValidateCmdQueueFlags(dev_data, pCB, "vkCmdSetStencilWriteMask()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_01525); skip_call |= ValidateCmd(dev_data, pCB, CMD_SETSTENCILWRITEMASKSTATE, "vkCmdSetStencilWriteMask()"); UpdateCmdBufferLastCmd(pCB, CMD_SETSTENCILWRITEMASKSTATE); pCB->status |= CBSTATUS_STENCIL_WRITE_MASK_SET; @@ -7302,6 +7253,8 @@ VKAPI_ATTR void VKAPI_CALL CmdSetStencilReference(VkCommandBuffer commandBuffer, std::unique_lock lock(global_lock); GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); if (pCB) { + skip_call |= + ValidateCmdQueueFlags(dev_data, pCB, "vkCmdSetStencilReference()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_01531); skip_call |= ValidateCmd(dev_data, pCB, CMD_SETSTENCILREFERENCESTATE, "vkCmdSetStencilReference()"); UpdateCmdBufferLastCmd(pCB, CMD_SETSTENCILREFERENCESTATE); pCB->status |= CBSTATUS_STENCIL_REFERENCE_SET; @@ -7319,6 +7272,8 @@ VKAPI_ATTR void VKAPI_CALL CmdBindDescriptorSets(VkCommandBuffer commandBuffer, std::unique_lock lock(global_lock); GLOBAL_CB_NODE *cb_state = GetCBNode(dev_data, commandBuffer); if (cb_state) { + skip |= ValidateCmdQueueFlags(dev_data, cb_state, "vkCmdBindDescriptorSets()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, + VALIDATION_ERROR_00985); skip |= ValidateCmd(dev_data, cb_state, CMD_BINDDESCRIPTORSETS, "vkCmdBindDescriptorSets()"); // Track total count of dynamic descriptor types to make sure we have an offset for each one uint32_t total_dynamic_descriptors = 0; @@ -7483,6 +7438,7 @@ VKAPI_ATTR void VKAPI_CALL CmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkB auto buffer_state = GetBufferState(dev_data, buffer); auto cb_node = GetCBNode(dev_data, commandBuffer); if (cb_node && buffer_state) { + skip |= ValidateCmdQueueFlags(dev_data, cb_node, "vkCmdBindIndexBuffer()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_01357); skip |= ValidateCmd(dev_data, cb_node, CMD_BINDINDEXBUFFER, "vkCmdBindIndexBuffer()"); skip |= ValidateMemoryIsBoundToBuffer(dev_data, buffer_state, "vkCmdBindIndexBuffer()", VALIDATION_ERROR_02543); std::function function = [=]() { @@ -7537,7 +7493,8 @@ VKAPI_ATTR void VKAPI_CALL CmdBindVertexBuffers(VkCommandBuffer commandBuffer, u auto cb_node = GetCBNode(dev_data, commandBuffer); if (cb_node) { - skip |= ValidateCmd(dev_data, cb_node, CMD_BINDVERTEXBUFFER, "vkCmdBindVertexBuffer()"); + skip |= ValidateCmdQueueFlags(dev_data, cb_node, "vkCmdBindVertexBuffers()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_01423); + skip |= ValidateCmd(dev_data, cb_node, CMD_BINDVERTEXBUFFER, "vkCmdBindVertexBuffers()"); for (uint32_t i = 0; i < bindingCount; ++i) { auto buffer_state = GetBufferState(dev_data, pBuffers[i]); assert(buffer_state); @@ -7583,11 +7540,13 @@ static void MarkStoreImagesAndBuffersAsWritten(layer_data *dev_data, GLOBAL_CB_N // Generic function to handle validation for all CmdDraw* type functions static bool ValidateCmdDrawType(layer_data *dev_data, VkCommandBuffer cmd_buffer, bool indexed, VkPipelineBindPoint bind_point, - CMD_TYPE cmd_type, GLOBAL_CB_NODE **cb_state, const char *caller, - UNIQUE_VALIDATION_ERROR_CODE msg_code, UNIQUE_VALIDATION_ERROR_CODE const dynamic_state_msg_code) { + CMD_TYPE cmd_type, GLOBAL_CB_NODE **cb_state, const char *caller, VkQueueFlags queue_flags, + UNIQUE_VALIDATION_ERROR_CODE queue_flag_code, UNIQUE_VALIDATION_ERROR_CODE msg_code, + UNIQUE_VALIDATION_ERROR_CODE const dynamic_state_msg_code) { bool skip = false; *cb_state = GetCBNode(dev_data, cmd_buffer); if (*cb_state) { + skip |= ValidateCmdQueueFlags(dev_data, *cb_state, caller, queue_flags, queue_flag_code); skip |= ValidateCmd(dev_data, *cb_state, cmd_type, caller); skip |= ValidateDrawState(dev_data, *cb_state, indexed, bind_point, caller, dynamic_state_msg_code); skip |= (VK_PIPELINE_BIND_POINT_GRAPHICS == bind_point) ? outsideRenderPass(dev_data, *cb_state, caller, msg_code) @@ -7614,8 +7573,8 @@ static void UpdateStateCmdDrawType(layer_data *dev_data, GLOBAL_CB_NODE *cb_stat static bool PreCallValidateCmdDraw(layer_data *dev_data, VkCommandBuffer cmd_buffer, bool indexed, VkPipelineBindPoint bind_point, GLOBAL_CB_NODE **cb_state, const char *caller) { - return ValidateCmdDrawType(dev_data, cmd_buffer, indexed, bind_point, CMD_DRAW, cb_state, caller, VALIDATION_ERROR_01365, - VALIDATION_ERROR_02203); + return ValidateCmdDrawType(dev_data, cmd_buffer, indexed, bind_point, CMD_DRAW, cb_state, caller, VK_QUEUE_GRAPHICS_BIT, + VALIDATION_ERROR_01364, VALIDATION_ERROR_01365, VALIDATION_ERROR_02203); } static void PostCallRecordCmdDraw(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, VkPipelineBindPoint bind_point) { @@ -7639,8 +7598,8 @@ VKAPI_ATTR void VKAPI_CALL CmdDraw(VkCommandBuffer commandBuffer, uint32_t verte static bool PreCallValidateCmdDrawIndexed(layer_data *dev_data, VkCommandBuffer cmd_buffer, bool indexed, VkPipelineBindPoint bind_point, GLOBAL_CB_NODE **cb_state, const char *caller) { - return ValidateCmdDrawType(dev_data, cmd_buffer, indexed, bind_point, CMD_DRAWINDEXED, cb_state, caller, VALIDATION_ERROR_01372, - VALIDATION_ERROR_02216); + return ValidateCmdDrawType(dev_data, cmd_buffer, indexed, bind_point, CMD_DRAWINDEXED, cb_state, caller, VK_QUEUE_GRAPHICS_BIT, + VALIDATION_ERROR_01371, VALIDATION_ERROR_01372, VALIDATION_ERROR_02216); } static void PostCallRecordCmdDrawIndexed(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, VkPipelineBindPoint bind_point) { @@ -7667,7 +7626,7 @@ static bool PreCallValidateCmdDrawIndirect(layer_data *dev_data, VkCommandBuffer VkPipelineBindPoint bind_point, GLOBAL_CB_NODE **cb_state, BUFFER_STATE **buffer_state, const char *caller) { bool skip = ValidateCmdDrawType(dev_data, cmd_buffer, indexed, bind_point, CMD_DRAWINDIRECT, cb_state, caller, - VALIDATION_ERROR_01381, VALIDATION_ERROR_02234); + VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_01380, VALIDATION_ERROR_01381, VALIDATION_ERROR_02234); *buffer_state = GetBufferState(dev_data, buffer); skip |= ValidateMemoryIsBoundToBuffer(dev_data, *buffer_state, caller, VALIDATION_ERROR_02544); // TODO: If the drawIndirectFirstInstance feature is not enabled, all the firstInstance members of the @@ -7702,7 +7661,7 @@ static bool PreCallValidateCmdDrawIndexedIndirect(layer_data *dev_data, VkComman VkPipelineBindPoint bind_point, GLOBAL_CB_NODE **cb_state, BUFFER_STATE **buffer_state, const char *caller) { bool skip = ValidateCmdDrawType(dev_data, cmd_buffer, indexed, bind_point, CMD_DRAWINDEXEDINDIRECT, cb_state, caller, - VALIDATION_ERROR_01393, VALIDATION_ERROR_02272); + VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_01392, VALIDATION_ERROR_01393, VALIDATION_ERROR_02272); *buffer_state = GetBufferState(dev_data, buffer); skip |= ValidateMemoryIsBoundToBuffer(dev_data, *buffer_state, caller, VALIDATION_ERROR_02545); // TODO: If the drawIndirectFirstInstance feature is not enabled, all the firstInstance members of the @@ -7736,8 +7695,8 @@ VKAPI_ATTR void VKAPI_CALL CmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, static bool PreCallValidateCmdDispatch(layer_data *dev_data, VkCommandBuffer cmd_buffer, bool indexed, VkPipelineBindPoint bind_point, GLOBAL_CB_NODE **cb_state, const char *caller) { - return ValidateCmdDrawType(dev_data, cmd_buffer, indexed, bind_point, CMD_DISPATCH, cb_state, caller, VALIDATION_ERROR_01562, - VALIDATION_ERROR_UNDEFINED); + return ValidateCmdDrawType(dev_data, cmd_buffer, indexed, bind_point, CMD_DISPATCH, cb_state, caller, VK_QUEUE_COMPUTE_BIT, + VALIDATION_ERROR_01561, VALIDATION_ERROR_01562, VALIDATION_ERROR_UNDEFINED); } static void PostCallRecordCmdDispatch(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, VkPipelineBindPoint bind_point) { @@ -7762,8 +7721,9 @@ VKAPI_ATTR void VKAPI_CALL CmdDispatch(VkCommandBuffer commandBuffer, uint32_t x static bool PreCallValidateCmdDispatchIndirect(layer_data *dev_data, VkCommandBuffer cmd_buffer, VkBuffer buffer, bool indexed, VkPipelineBindPoint bind_point, GLOBAL_CB_NODE **cb_state, BUFFER_STATE **buffer_state, const char *caller) { - bool skip = ValidateCmdDrawType(dev_data, cmd_buffer, indexed, bind_point, CMD_DISPATCHINDIRECT, cb_state, caller, - VALIDATION_ERROR_01569, VALIDATION_ERROR_UNDEFINED); + bool skip = + ValidateCmdDrawType(dev_data, cmd_buffer, indexed, bind_point, CMD_DISPATCHINDIRECT, cb_state, caller, VK_QUEUE_COMPUTE_BIT, + VALIDATION_ERROR_01568, VALIDATION_ERROR_01569, VALIDATION_ERROR_UNDEFINED); *buffer_state = GetBufferState(dev_data, buffer); skip |= ValidateMemoryIsBoundToBuffer(dev_data, *buffer_state, caller, VALIDATION_ERROR_02547); return skip; @@ -7945,6 +7905,9 @@ VKAPI_ATTR void VKAPI_CALL CmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuff }; cb_node->validate_functions.push_back(function); + skip_call |= + ValidateCmdQueueFlags(dev_data, cb_node, "vkCmdUpdateBuffer()", + VK_QUEUE_TRANSFER_BIT | VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, VALIDATION_ERROR_01154); skip_call |= ValidateCmd(dev_data, cb_node, CMD_UPDATEBUFFER, "vkCmdUpdateBuffer()"); UpdateCmdBufferLastCmd(cb_node, CMD_UPDATEBUFFER); skip_call |= insideRenderPass(dev_data, cb_node, "vkCmdUpdateBuffer()", VALIDATION_ERROR_01155); @@ -8064,6 +8027,8 @@ VKAPI_ATTR void VKAPI_CALL CmdSetEvent(VkCommandBuffer commandBuffer, VkEvent ev std::unique_lock lock(global_lock); GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); if (pCB) { + skip_call |= ValidateCmdQueueFlags(dev_data, pCB, "vkCmdSetEvent()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, + VALIDATION_ERROR_00237); skip_call |= ValidateCmd(dev_data, pCB, CMD_SETEVENT, "vkCmdSetEvent()"); UpdateCmdBufferLastCmd(pCB, CMD_SETEVENT); skip_call |= insideRenderPass(dev_data, pCB, "vkCmdSetEvent()", VALIDATION_ERROR_00238); @@ -8093,6 +8058,8 @@ VKAPI_ATTR void VKAPI_CALL CmdResetEvent(VkCommandBuffer commandBuffer, VkEvent std::unique_lock lock(global_lock); GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); if (pCB) { + skip_call |= ValidateCmdQueueFlags(dev_data, pCB, "vkCmdResetEvent()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, + VALIDATION_ERROR_00248); skip_call |= ValidateCmd(dev_data, pCB, CMD_RESETEVENT, "vkCmdResetEvent()"); UpdateCmdBufferLastCmd(pCB, CMD_RESETEVENT); skip_call |= insideRenderPass(dev_data, pCB, "vkCmdResetEvent()", VALIDATION_ERROR_00249); @@ -8449,6 +8416,8 @@ VKAPI_ATTR void VKAPI_CALL CmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t std::function event_update = std::bind(validateEventStageMask, std::placeholders::_1, cb_state, eventCount, first_event_index, sourceStageMask); cb_state->eventUpdates.push_back(event_update); + skip |= ValidateCmdQueueFlags(dev_data, cb_state, "vkCmdWaitEvents()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, + VALIDATION_ERROR_00262); skip |= ValidateCmd(dev_data, cb_state, CMD_WAITEVENTS, "vkCmdWaitEvents()"); UpdateCmdBufferLastCmd(cb_state, CMD_WAITEVENTS); skip |= @@ -8475,6 +8444,8 @@ static bool PreCallValidateCmdPipelineBarrier(layer_data *device_data, GLOBAL_CB bool skip = false; skip |= ValidateStageMasksAgainstQueueCapabilities(device_data, cb_state, srcStageMask, dstStageMask, "vkCmdPipelineBarrier", VALIDATION_ERROR_02513); + skip |= ValidateCmdQueueFlags(device_data, cb_state, "vkCmdPipelineBarrier()", + VK_QUEUE_TRANSFER_BIT | VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, VALIDATION_ERROR_00280); skip |= ValidateCmd(device_data, cb_state, CMD_PIPELINEBARRIER, "vkCmdPipelineBarrier()"); skip |= ValidateStageMaskGsTsEnables(device_data, srcStageMask, "vkCmdPipelineBarrier()", VALIDATION_ERROR_00265, VALIDATION_ERROR_00267); @@ -8544,6 +8515,8 @@ VKAPI_ATTR void VKAPI_CALL CmdBeginQuery(VkCommandBuffer commandBuffer, VkQueryP if (!pCB->startedQueries.count(query)) { pCB->startedQueries.insert(query); } + skip_call |= ValidateCmdQueueFlags(dev_data, pCB, "vkCmdBeginQuery()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, + VALIDATION_ERROR_01039); skip_call |= ValidateCmd(dev_data, pCB, CMD_BEGINQUERY, "vkCmdBeginQuery()"); UpdateCmdBufferLastCmd(pCB, CMD_BEGINQUERY); addCommandBufferBinding(&GetQueryPoolNode(dev_data, queryPool)->cb_bindings, @@ -8570,6 +8543,8 @@ VKAPI_ATTR void VKAPI_CALL CmdEndQuery(VkCommandBuffer commandBuffer, VkQueryPoo } std::function query_update = std::bind(setQueryState, std::placeholders::_1, commandBuffer, query, true); cb_state->queryUpdates.push_back(query_update); + skip |= ValidateCmdQueueFlags(dev_data, cb_state, "VkCmdEndQuery()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, + VALIDATION_ERROR_01046); skip |= ValidateCmd(dev_data, cb_state, CMD_ENDQUERY, "VkCmdEndQuery()"); UpdateCmdBufferLastCmd(cb_state, CMD_ENDQUERY); addCommandBufferBinding(&GetQueryPoolNode(dev_data, queryPool)->cb_bindings, @@ -8593,6 +8568,8 @@ VKAPI_ATTR void VKAPI_CALL CmdResetQueryPool(VkCommandBuffer commandBuffer, VkQu std::bind(setQueryState, std::placeholders::_1, commandBuffer, query, false); cb_state->queryUpdates.push_back(query_update); } + skip |= ValidateCmdQueueFlags(dev_data, cb_state, "VkCmdResetQueryPool()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, + VALIDATION_ERROR_01024); skip |= ValidateCmd(dev_data, cb_state, CMD_RESETQUERYPOOL, "VkCmdResetQueryPool()"); UpdateCmdBufferLastCmd(cb_state, CMD_RESETQUERYPOOL); skip |= insideRenderPass(dev_data, cb_state, "vkCmdResetQueryPool()", VALIDATION_ERROR_01025); @@ -8661,6 +8638,8 @@ VKAPI_ATTR void VKAPI_CALL CmdCopyQueryPoolResults(VkCommandBuffer commandBuffer std::function query_update = std::bind(validateQuery, std::placeholders::_1, cb_node, queryPool, queryCount, firstQuery); cb_node->queryUpdates.push_back(query_update); + skip |= ValidateCmdQueueFlags(dev_data, cb_node, "vkCmdCopyQueryPoolResults()", + VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, VALIDATION_ERROR_01073); skip |= ValidateCmd(dev_data, cb_node, CMD_COPYQUERYPOOLRESULTS, "vkCmdCopyQueryPoolResults()"); UpdateCmdBufferLastCmd(cb_node, CMD_COPYQUERYPOOLRESULTS); skip |= insideRenderPass(dev_data, cb_node, "vkCmdCopyQueryPoolResults()", VALIDATION_ERROR_01074); @@ -8682,6 +8661,8 @@ VKAPI_ATTR void VKAPI_CALL CmdPushConstants(VkCommandBuffer commandBuffer, VkPip std::unique_lock lock(global_lock); GLOBAL_CB_NODE *cb_state = GetCBNode(dev_data, commandBuffer); if (cb_state) { + skip |= ValidateCmdQueueFlags(dev_data, cb_state, "vkCmdPushConstants()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, + VALIDATION_ERROR_00999); skip |= ValidateCmd(dev_data, cb_state, CMD_PUSHCONSTANTS, "vkCmdPushConstants()"); UpdateCmdBufferLastCmd(cb_state, CMD_PUSHCONSTANTS); } @@ -8728,6 +8709,8 @@ VKAPI_ATTR void VKAPI_CALL CmdWriteTimestamp(VkCommandBuffer commandBuffer, VkPi QueryObject query = {queryPool, slot}; std::function query_update = std::bind(setQueryState, std::placeholders::_1, commandBuffer, query, true); cb_state->queryUpdates.push_back(query_update); + skip |= ValidateCmdQueueFlags(dev_data, cb_state, "vkCmdWriteTimestamp()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, + VALIDATION_ERROR_01082); skip |= ValidateCmd(dev_data, cb_state, CMD_WRITETIMESTAMP, "vkCmdWriteTimestamp()"); UpdateCmdBufferLastCmd(cb_state, CMD_WRITETIMESTAMP); } @@ -9548,6 +9531,8 @@ VKAPI_ATTR void VKAPI_CALL CmdBeginRenderPass(VkCommandBuffer commandBuffer, con skip_call |= insideRenderPass(dev_data, cb_node, "vkCmdBeginRenderPass()", VALIDATION_ERROR_00440); skip_call |= ValidateDependencies(dev_data, framebuffer, render_pass_state); skip_call |= validatePrimaryCommandBuffer(dev_data, cb_node, "vkCmdBeginRenderPass", VALIDATION_ERROR_00441); + skip_call |= + ValidateCmdQueueFlags(dev_data, cb_node, "vkCmdBeginRenderPass()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_00439); skip_call |= ValidateCmd(dev_data, cb_node, CMD_BEGINRENDERPASS, "vkCmdBeginRenderPass()"); UpdateCmdBufferLastCmd(cb_node, CMD_BEGINRENDERPASS); cb_node->activeRenderPass = render_pass_state; @@ -9575,6 +9560,7 @@ VKAPI_ATTR void VKAPI_CALL CmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpa GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); if (pCB) { skip_call |= validatePrimaryCommandBuffer(dev_data, pCB, "vkCmdNextSubpass", VALIDATION_ERROR_00459); + skip_call |= ValidateCmdQueueFlags(dev_data, pCB, "vkCmdNextSubpass()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_00457); skip_call |= ValidateCmd(dev_data, pCB, CMD_NEXTSUBPASS, "vkCmdNextSubpass()"); UpdateCmdBufferLastCmd(pCB, CMD_NEXTSUBPASS); skip_call |= outsideRenderPass(dev_data, pCB, "vkCmdNextSubpass()", VALIDATION_ERROR_00458); @@ -9641,6 +9627,7 @@ VKAPI_ATTR void VKAPI_CALL CmdEndRenderPass(VkCommandBuffer commandBuffer) { } skip_call |= outsideRenderPass(dev_data, pCB, "vkCmdEndRenderpass()", VALIDATION_ERROR_00464); skip_call |= validatePrimaryCommandBuffer(dev_data, pCB, "vkCmdEndRenderPass", VALIDATION_ERROR_00465); + skip_call |= ValidateCmdQueueFlags(dev_data, pCB, "vkCmdEndRenderPass()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_00463); skip_call |= ValidateCmd(dev_data, pCB, CMD_ENDRENDERPASS, "vkCmdEndRenderPass()"); UpdateCmdBufferLastCmd(pCB, CMD_ENDRENDERPASS); } @@ -9977,6 +9964,9 @@ VKAPI_ATTR void VKAPI_CALL CmdExecuteCommands(VkCommandBuffer commandBuffer, uin } } skip_call |= validatePrimaryCommandBuffer(dev_data, pCB, "vkCmdExecuteComands", VALIDATION_ERROR_00163); + skip_call |= + ValidateCmdQueueFlags(dev_data, pCB, "vkCmdExecuteComands()", + VK_QUEUE_TRANSFER_BIT | VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, VALIDATION_ERROR_00162); skip_call |= ValidateCmd(dev_data, pCB, CMD_EXECUTECOMMANDS, "vkCmdExecuteComands()"); UpdateCmdBufferLastCmd(pCB, CMD_EXECUTECOMMANDS); } diff --git a/layers/core_validation_types.h b/layers/core_validation_types.h index f2659aed..f80a5853 100644 --- a/layers/core_validation_types.h +++ b/layers/core_validation_types.h @@ -814,6 +814,8 @@ void invalidateCommandBuffers(const layer_data *dev_data, std::unordered_set