diff options
| author | Mark Lobodzinski <mark@lunarg.com> | 2017-02-07 17:11:55 -0700 |
|---|---|---|
| committer | Mark Lobodzinski <mark@lunarg.com> | 2017-02-08 10:25:28 -0700 |
| commit | 00c264502439315958b77b28d982adaedf3fd42a (patch) | |
| tree | ea5018a632f572b241a04d77b509559d45366281 | |
| parent | dbf79952ff762f42331f82ba8dadfc276cc5d16e (diff) | |
| download | usermoji-00c264502439315958b77b28d982adaedf3fd42a.tar.xz | |
layers: Move image layout validation helpers from CV
ValidateLayoutVsAttachmentDescription and ValidateLayouts now reside
in the buffer_validation module.
Change-Id: I66ce6ecba882b0e5acb70410ef2b99d32070feb0
| -rw-r--r-- | layers/buffer_validation.cpp | 124 | ||||
| -rw-r--r-- | layers/buffer_validation.h | 5 | ||||
| -rw-r--r-- | layers/core_validation.cpp | 122 |
3 files changed, 129 insertions, 122 deletions
diff --git a/layers/buffer_validation.cpp b/layers/buffer_validation.cpp index 8cb0eb5f..3823c21d 100644 --- a/layers/buffer_validation.cpp +++ b/layers/buffer_validation.cpp @@ -1661,3 +1661,127 @@ bool ValidateMaskBitsFromLayouts(core_validation::layer_data *device_data, VkCom } return skip; } + +// ValidateLayoutVsAttachmentDescription is a general function where we can validate various state associated with the +// VkAttachmentDescription structs that are used by the sub-passes of a renderpass. Initial check is to make sure that +// READ_ONLY layout attachments don't have CLEAR as their loadOp. +bool ValidateLayoutVsAttachmentDescription(const debug_report_data *report_data, const VkImageLayout first_layout, + const uint32_t attachment, + const VkAttachmentDescription &attachment_description) { + bool skip_call = false; + // Verify that initial loadOp on READ_ONLY attachments is not CLEAR + if (attachment_description.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) { + if ((first_layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL) || + (first_layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)) { + skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, + VkDebugReportObjectTypeEXT(0), __LINE__, VALIDATION_ERROR_02351, "DS", + "Cannot clear attachment %d with invalid first layout %s. %s", attachment, + string_VkImageLayout(first_layout), validation_error_map[VALIDATION_ERROR_02351]); + } + } + return skip_call; +} + +bool ValidateLayouts(core_validation::layer_data *dev_data, VkDevice device, const VkRenderPassCreateInfo *pCreateInfo) { + const debug_report_data *report_data = core_validation::GetReportData(dev_data); + bool skip = false; + + // Track when we're observing the first use of an attachment + std::vector<bool> attach_first_use(pCreateInfo->attachmentCount, true); + for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { + const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[i]; + for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) { + auto attach_index = subpass.pColorAttachments[j].attachment; + if (attach_index == VK_ATTACHMENT_UNUSED) continue; + + switch (subpass.pColorAttachments[j].layout) { + case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: + // This is ideal. + break; + + case VK_IMAGE_LAYOUT_GENERAL: + // May not be optimal; TODO: reconsider this warning based on other constraints? + skip |= log_msg(report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, + VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", + "Layout for color attachment is GENERAL but should be COLOR_ATTACHMENT_OPTIMAL."); + break; + + default: + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, + 0, __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", + "Layout for color attachment is %s but can only be COLOR_ATTACHMENT_OPTIMAL or GENERAL.", + string_VkImageLayout(subpass.pColorAttachments[j].layout)); + } + + if (attach_first_use[attach_index]) { + skip |= ValidateLayoutVsAttachmentDescription(report_data, subpass.pColorAttachments[j].layout, + attach_index, pCreateInfo->pAttachments[attach_index]); + } + attach_first_use[attach_index] = false; + } + if (subpass.pDepthStencilAttachment && subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) { + switch (subpass.pDepthStencilAttachment->layout) { + case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: + case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: + // These are ideal. + break; + + case VK_IMAGE_LAYOUT_GENERAL: + // May not be optimal; TODO: reconsider this warning based on other constraints? GENERAL can be better than + // doing + // a bunch of transitions. + skip |= log_msg(report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, + VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", + "GENERAL layout for depth attachment may not give optimal performance."); + break; + + default: + // No other layouts are acceptable + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, + 0, __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", + "Layout for depth attachment is %s but can only be DEPTH_STENCIL_ATTACHMENT_OPTIMAL, " + "DEPTH_STENCIL_READ_ONLY_OPTIMAL or GENERAL.", + string_VkImageLayout(subpass.pDepthStencilAttachment->layout)); + } + + auto attach_index = subpass.pDepthStencilAttachment->attachment; + if (attach_first_use[attach_index]) { + skip |= ValidateLayoutVsAttachmentDescription(report_data, subpass.pDepthStencilAttachment->layout, + attach_index, pCreateInfo->pAttachments[attach_index]); + } + attach_first_use[attach_index] = false; + } + for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) { + auto attach_index = subpass.pInputAttachments[j].attachment; + if (attach_index == VK_ATTACHMENT_UNUSED) continue; + + switch (subpass.pInputAttachments[j].layout) { + case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: + case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: + // These are ideal. + break; + + case VK_IMAGE_LAYOUT_GENERAL: + // May not be optimal. TODO: reconsider this warning based on other constraints. + skip |= log_msg(report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, + VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", + "Layout for input attachment is GENERAL but should be READ_ONLY_OPTIMAL."); + break; + + default: + // No other layouts are acceptable + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, + __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", + "Layout for input attachment is %s but can only be READ_ONLY_OPTIMAL or GENERAL.", + string_VkImageLayout(subpass.pInputAttachments[j].layout)); + } + + if (attach_first_use[attach_index]) { + skip |= ValidateLayoutVsAttachmentDescription(report_data, subpass.pInputAttachments[j].layout, + attach_index, pCreateInfo->pAttachments[attach_index]); + } + attach_first_use[attach_index] = false; + } + } + return skip; +} diff --git a/layers/buffer_validation.h b/layers/buffer_validation.h index e8a57547..5375722a 100644 --- a/layers/buffer_validation.h +++ b/layers/buffer_validation.h @@ -145,4 +145,9 @@ bool ValidateCmdBufImageLayouts(core_validation::layer_data *dev_data, GLOBAL_CB bool ValidateMaskBitsFromLayouts(core_validation::layer_data *device_data, VkCommandBuffer cmdBuffer, const VkAccessFlags &accessMask, const VkImageLayout &layout, const char *type); +bool ValidateLayoutVsAttachmentDescription(const debug_report_data *report_data, const VkImageLayout first_layout, + const uint32_t attachment, const VkAttachmentDescription &attachment_description); + +bool ValidateLayouts(core_validation::layer_data *dev_data, VkDevice device, const VkRenderPassCreateInfo *pCreateInfo); + #endif // CORE_VALIDATION_BUFFER_VALIDATION_H_ diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp index 854664f4..60431051 100644 --- a/layers/core_validation.cpp +++ b/layers/core_validation.cpp @@ -9590,128 +9590,6 @@ static bool ValidateDependencies(const layer_data *dev_data, FRAMEBUFFER_STATE c } return skip_call; } -// ValidateLayoutVsAttachmentDescription is a general function where we can validate various state associated with the -// VkAttachmentDescription structs that are used by the sub-passes of a renderpass. Initial check is to make sure that -// READ_ONLY layout attachments don't have CLEAR as their loadOp. -static bool ValidateLayoutVsAttachmentDescription(debug_report_data *report_data, const VkImageLayout first_layout, - const uint32_t attachment, - const VkAttachmentDescription &attachment_description) { - bool skip_call = false; - // Verify that initial loadOp on READ_ONLY attachments is not CLEAR - if (attachment_description.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) { - if ((first_layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL) || - (first_layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)) { - skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, - VkDebugReportObjectTypeEXT(0), __LINE__, VALIDATION_ERROR_02351, "DS", - "Cannot clear attachment %d with invalid first layout %s. %s", attachment, - string_VkImageLayout(first_layout), validation_error_map[VALIDATION_ERROR_02351]); - } - } - return skip_call; -} - -static bool ValidateLayouts(const layer_data *dev_data, VkDevice device, const VkRenderPassCreateInfo *pCreateInfo) { - bool skip = false; - - // Track when we're observing the first use of an attachment - std::vector<bool> attach_first_use(pCreateInfo->attachmentCount, true); - for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { - const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[i]; - for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) { - auto attach_index = subpass.pColorAttachments[j].attachment; - if (attach_index == VK_ATTACHMENT_UNUSED) continue; - - switch (subpass.pColorAttachments[j].layout) { - case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: - // This is ideal. - break; - - case VK_IMAGE_LAYOUT_GENERAL: - // May not be optimal; TODO: reconsider this warning based on other constraints? - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, - VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", - "Layout for color attachment is GENERAL but should be COLOR_ATTACHMENT_OPTIMAL."); - break; - - default: - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, - 0, __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", - "Layout for color attachment is %s but can only be COLOR_ATTACHMENT_OPTIMAL or GENERAL.", - string_VkImageLayout(subpass.pColorAttachments[j].layout)); - } - - if (attach_first_use[attach_index]) { - skip |= ValidateLayoutVsAttachmentDescription(dev_data->report_data, subpass.pColorAttachments[j].layout, - attach_index, pCreateInfo->pAttachments[attach_index]); - } - attach_first_use[attach_index] = false; - } - if (subpass.pDepthStencilAttachment && subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) { - switch (subpass.pDepthStencilAttachment->layout) { - case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: - case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: - // These are ideal. - break; - - case VK_IMAGE_LAYOUT_GENERAL: - // May not be optimal; TODO: reconsider this warning based on other constraints? GENERAL can be better than - // doing - // a bunch of transitions. - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, - VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", - "GENERAL layout for depth attachment may not give optimal performance."); - break; - - default: - // No other layouts are acceptable - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, - 0, __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", - "Layout for depth attachment is %s but can only be DEPTH_STENCIL_ATTACHMENT_OPTIMAL, " - "DEPTH_STENCIL_READ_ONLY_OPTIMAL or GENERAL.", - string_VkImageLayout(subpass.pDepthStencilAttachment->layout)); - } - - auto attach_index = subpass.pDepthStencilAttachment->attachment; - if (attach_first_use[attach_index]) { - skip |= ValidateLayoutVsAttachmentDescription(dev_data->report_data, subpass.pDepthStencilAttachment->layout, - attach_index, pCreateInfo->pAttachments[attach_index]); - } - attach_first_use[attach_index] = false; - } - for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) { - auto attach_index = subpass.pInputAttachments[j].attachment; - if (attach_index == VK_ATTACHMENT_UNUSED) continue; - - switch (subpass.pInputAttachments[j].layout) { - case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: - case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: - // These are ideal. - break; - - case VK_IMAGE_LAYOUT_GENERAL: - // May not be optimal. TODO: reconsider this warning based on other constraints. - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, - VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", - "Layout for input attachment is GENERAL but should be READ_ONLY_OPTIMAL."); - break; - - default: - // No other layouts are acceptable - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, - __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", - "Layout for input attachment is %s but can only be READ_ONLY_OPTIMAL or GENERAL.", - string_VkImageLayout(subpass.pInputAttachments[j].layout)); - } - - if (attach_first_use[attach_index]) { - skip |= ValidateLayoutVsAttachmentDescription(dev_data->report_data, subpass.pInputAttachments[j].layout, - attach_index, pCreateInfo->pAttachments[attach_index]); - } - attach_first_use[attach_index] = false; - } - } - return skip; -} static bool CreatePassDAG(const layer_data *dev_data, VkDevice device, const VkRenderPassCreateInfo *pCreateInfo, std::vector<DAGNode> &subpass_to_node, std::vector<bool> &has_self_dependency) { |
