From 3bee7ccd1a8aa216c77e4bb2406740cda998a44e Mon Sep 17 00:00:00 2001 From: John Zulauf <32470354+jzulauf-lunarg@users.noreply.github.com> Date: Fri, 26 Oct 2018 16:10:00 -0600 Subject: [PATCH 1/3] Revert "tests: Added tests for all the new VUID checks" This reverts commit 154c770c22c3e9bef7367adec176321da9388d89. --- build-android/jni/Android.mk | 4 - tests/CMakeLists.txt | 1 - tests/layer_validation_tests.cpp | 3652 ++++++++++-------------------- 3 files changed, 1217 insertions(+), 2440 deletions(-) diff --git a/build-android/jni/Android.mk b/build-android/jni/Android.mk index e0824ae1050..39f04642a1e 100644 --- a/build-android/jni/Android.mk +++ b/build-android/jni/Android.mk @@ -116,8 +116,6 @@ LOCAL_SRC_FILES += $(SRC_DIR)/tests/layer_validation_tests.cpp \ $(SRC_DIR)/tests/vktestbinding.cpp \ $(SRC_DIR)/tests/vktestframeworkandroid.cpp \ $(SRC_DIR)/tests/vkrenderframework.cpp \ - $(SRC_DIR)/layers/convert_to_renderpass2.cpp \ - $(LAYER_DIR)/include/vk_safe_struct.cpp \ $(THIRD_PARTY)/Vulkan-Tools/common/vulkan_wrapper.cpp LOCAL_C_INCLUDES += $(VULKAN_INCLUDE) \ $(LOCAL_PATH)/$(LAYER_DIR)/include \ @@ -140,8 +138,6 @@ LOCAL_SRC_FILES += $(SRC_DIR)/tests/layer_validation_tests.cpp \ $(SRC_DIR)/tests/vktestbinding.cpp \ $(SRC_DIR)/tests/vktestframeworkandroid.cpp \ $(SRC_DIR)/tests/vkrenderframework.cpp \ - $(SRC_DIR)/layers/convert_to_renderpass2.cpp \ - $(LAYER_DIR)/include/vk_safe_struct.cpp \ $(THIRD_PARTY)/Vulkan-Tools/common/vulkan_wrapper.cpp LOCAL_C_INCLUDES += $(VULKAN_INCLUDE) \ $(LOCAL_PATH)/$(LAYER_DIR)/include \ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f13d2b5097b..022c85fa2c0 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -103,7 +103,6 @@ set_source_files_properties(${PROJECT_BINARY_DIR}/vk_safe_struct.cpp PROPERTIES add_executable(vk_layer_validation_tests layer_validation_tests.cpp ../layers/vk_format_utils.cpp - ../layers/convert_to_renderpass2.cpp ${PROJECT_BINARY_DIR}/vk_safe_struct.cpp ${COMMON_CPP}) set_target_properties(vk_layer_validation_tests PROPERTIES COMPILE_DEFINITIONS "GTEST_LINKED_AS_SHARED_LIBRARY=1") diff --git a/tests/layer_validation_tests.cpp b/tests/layer_validation_tests.cpp index 5ed62d96d50..a790f5c167c 100644 --- a/tests/layer_validation_tests.cpp +++ b/tests/layer_validation_tests.cpp @@ -43,7 +43,6 @@ #include "vk_format_utils.h" #include "vkrenderframework.h" #include "vk_typemap_helper.h" -#include "convert_to_renderpass2.h" #include #include @@ -4449,9 +4448,121 @@ TEST_F(VkLayerTest, MismatchedQueueFamiliesOnSubmit) { m_errorMonitor->VerifyFound(); } -TEST_F(VkLayerTest, DrawWithPipelineIncompatibleWithSubpass) { - TEST_DESCRIPTION("Use a pipeline for the wrong subpass in a render pass instance"); +TEST_F(VkLayerTest, RenderPassAttachmentIndexOutOfRange) { + ASSERT_NO_FATAL_FAILURE(Init()); + + // There are no attachments, but refer to attachment 0. + VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; + VkSubpassDescription subpasses[] = { + {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr}, + }; + + VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 1, subpasses, 0, nullptr}; + VkRenderPass rp; + + // "... must be less than the total number of attachments ..." + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkRenderPassCreateInfo-attachment-00834"); + vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); + m_errorMonitor->VerifyFound(); +} + +TEST_F(VkLayerTest, RenderPassAttachmentUsedTwiceColor) { + ASSERT_NO_FATAL_FAILURE(Init()); + TEST_DESCRIPTION("Attachment is used simultaneously as two color attachments. This is not acceptable."); + + VkAttachmentDescription attach[] = { + {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, + VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, + }; + VkAttachmentReference refs[] = { + {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, + {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, + }; + VkSubpassDescription subpasses[] = { + {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 2, refs, nullptr, nullptr, 0, nullptr}, + }; + + VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 1, subpasses, 0, nullptr}; + VkRenderPass rp; + + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, + "subpass 0 already uses attachment 0 as a color attachment"); + vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); + m_errorMonitor->VerifyFound(); +} + +TEST_F(VkLayerTest, RenderPassAttachmentUsedTwiceMismatchingLayout) { + ASSERT_NO_FATAL_FAILURE(Init()); + + TEST_DESCRIPTION("Attachment is used simultaneously as color and input. The layouts differ, which is not acceptable."); + + VkAttachmentDescription attach[] = { + {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_DONT_CARE, + VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL}, + }; + VkAttachmentReference color_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; + VkAttachmentReference input_ref = {0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL}; + VkSubpassDescription subpasses[] = { + {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &input_ref, 1, &color_ref, nullptr, nullptr, 0, nullptr}, + }; + + VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 1, subpasses, 0, nullptr}; + VkRenderPass rp; + + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSubpassDescription-layout-00855"); + vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); + m_errorMonitor->VerifyFound(); +} + +TEST_F(VkPositiveLayerTest, RenderPassAttachmentUsedTwiceOK) { + ASSERT_NO_FATAL_FAILURE(Init()); + + TEST_DESCRIPTION("Attachment is used simultaneously as color and input, with the same layout. This is OK."); + + VkAttachmentDescription attach[] = { + {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_DONT_CARE, + VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL}, + }; + VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_GENERAL}; + VkSubpassDescription subpasses[] = { + {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &ref, 1, &ref, nullptr, nullptr, 0, nullptr}, + }; + + VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 1, subpasses, 0, nullptr}; + VkRenderPass rp; + + m_errorMonitor->ExpectSuccess(); + vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); + m_errorMonitor->VerifyNotFound(); + vkDestroyRenderPass(m_device->device(), rp, nullptr); +} + +TEST_F(VkLayerTest, RenderPassAttachmentUsedTwicePreserveAndColor) { + ASSERT_NO_FATAL_FAILURE(Init()); + + TEST_DESCRIPTION("Attachment is used simultaneously as color and preserve. This is not acceptable."); + + VkAttachmentDescription attach[] = { + {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_DONT_CARE, + VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL}, + }; + VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_GENERAL}; + uint32_t preserve_attachment = 0; + VkSubpassDescription subpasses[] = { + {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 1, &preserve_attachment}, + }; + + VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 1, subpasses, 0, nullptr}; + VkRenderPass rp; + + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSubpassDescription-pPreserveAttachments-00854"); + vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); + m_errorMonitor->VerifyFound(); +} +TEST_F(VkLayerTest, RenderPassPipelineSubpassMismatch) { + TEST_DESCRIPTION("Use a pipeline for the wrong subpass in a render pass instance"); ASSERT_NO_FATAL_FAILURE(Init()); // A renderpass with two subpasses, both writing the same attachment. @@ -4550,7 +4661,7 @@ TEST_F(VkLayerTest, DrawWithPipelineIncompatibleWithSubpass) { vkDestroyRenderPass(m_device->device(), rp, nullptr); } -TEST_F(VkLayerTest, ImageBarrierSubpassConflicts) { +TEST_F(VkLayerTest, RenderPassBarrierConflicts) { TEST_DESCRIPTION("Add a pipeline barrier within a subpass that has conflicting state"); ASSERT_NO_FATAL_FAILURE(Init()); @@ -5282,2453 +5393,301 @@ TEST_F(VkPositiveLayerTest, SecondaryCommandBufferBarrier) { vkDestroyRenderPass(m_device->device(), rp, nullptr); } -static void TestRenderPassCreate(ErrorMonitor *error_monitor, const VkDevice device, const VkRenderPassCreateInfo *create_info, - PFN_vkCreateRenderPass2KHR vkCreateRenderPass2KHR, const char *rp1_vuid, const char *rp2_vuid) { - // "... must be less than the total number of attachments ..." - VkRenderPass render_pass = VK_NULL_HANDLE; - VkResult err; - - if (rp1_vuid) { - error_monitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, rp1_vuid); - err = vkCreateRenderPass(device, create_info, nullptr, &render_pass); - if (err == VK_SUCCESS) vkDestroyRenderPass(device, render_pass, nullptr); - error_monitor->VerifyFound(); - } +TEST_F(VkLayerTest, RenderPassInvalidRenderArea) { + TEST_DESCRIPTION("Generate INVALID_RENDER_AREA error by beginning renderpass with extent outside of framebuffer"); + ASSERT_NO_FATAL_FAILURE(Init()); + ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); - if (vkCreateRenderPass2KHR && rp2_vuid) { - safe_VkRenderPassCreateInfo2KHR create_info2; - ConvertVkRenderPassCreateInfoToV2KHR(create_info, &create_info2); + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, + "Cannot execute a render pass with renderArea not within the bound of the framebuffer."); - error_monitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, rp2_vuid); - err = vkCreateRenderPass2KHR(device, create_info2.ptr(), nullptr, &render_pass); - if (err == VK_SUCCESS) vkDestroyRenderPass(device, render_pass, nullptr); - error_monitor->VerifyFound(); - } + // Framebuffer for render target is 256x256, exceed that for INVALID_RENDER_AREA + m_renderPassBeginInfo.renderArea.extent.width = 257; + m_renderPassBeginInfo.renderArea.extent.height = 257; + m_commandBuffer->begin(); + m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); + m_errorMonitor->VerifyFound(); } -TEST_F(VkLayerTest, RenderPassCreateAttachmentIndexOutOfRange) { - // Check for VK_KHR_get_physical_device_properties2 - if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { - m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - } - - ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); - PFN_vkCreateRenderPass2KHR vkCreateRenderPass2KHR = nullptr; - bool rp2Supported = false; - - // Check for VK_KHR_create_renderpass2 - if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME)) { - m_device_extension_names.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); - rp2Supported = true; - } - ASSERT_NO_FATAL_FAILURE(InitState()); - - if (rp2Supported) { - vkCreateRenderPass2KHR = (PFN_vkCreateRenderPass2KHR)vkGetDeviceProcAddr(m_device->device(), "vkCreateRenderPass2KHR"); - } +TEST_F(VkLayerTest, DisabledIndependentBlend) { + TEST_DESCRIPTION( + "Generate INDEPENDENT_BLEND by disabling independent blend and then specifying different blend states for two " + "attachments"); + VkPhysicalDeviceFeatures features = {}; + features.independentBlend = VK_FALSE; + ASSERT_NO_FATAL_FAILURE(Init(&features)); - // There are no attachments, but refer to attachment 0. - VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; - VkSubpassDescription subpasses[] = { - {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr}, - }; + m_errorMonitor->SetDesiredFailureMsg( + VK_DEBUG_REPORT_ERROR_BIT_EXT, + "Invalid Pipeline CreateInfo: If independent blend feature not enabled, all elements of pAttachments must be identical"); - VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 1, subpasses, 0, nullptr}; + VkDescriptorSetObj descriptorSet(m_device); + descriptorSet.AppendDummy(); + descriptorSet.CreateVKDescriptorSet(m_commandBuffer); - // "... must be less than the total number of attachments ..." - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkRenderPassCreateInfo-attachment-00834", "VUID-VkRenderPassCreateInfo2KHR-attachment-03051"); -} + VkPipelineObj pipeline(m_device); + // Create a renderPass with two color attachments + VkAttachmentReference attachments[2] = {}; + attachments[0].layout = VK_IMAGE_LAYOUT_GENERAL; + attachments[1].attachment = 1; + attachments[1].layout = VK_IMAGE_LAYOUT_GENERAL; -TEST_F(VkLayerTest, RenderPassCreateAttachmentReadOnlyButCleared) { - // Check for VK_KHR_get_physical_device_properties2 - if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { - m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - } + VkSubpassDescription subpass = {}; + subpass.pColorAttachments = attachments; + subpass.colorAttachmentCount = 2; - ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); - PFN_vkCreateRenderPass2KHR vkCreateRenderPass2KHR = nullptr; - bool rp2Supported = false; - bool maintenance2Supported = false; + VkRenderPassCreateInfo rpci = {}; + rpci.subpassCount = 1; + rpci.pSubpasses = &subpass; + rpci.attachmentCount = 2; - // Check for VK_KHR_maintenance2 - if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE2_EXTENSION_NAME)) { - m_device_extension_names.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME); - maintenance2Supported = true; - } - // Check for VK_KHR_create_renderpass2 - if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME)) { - m_device_extension_names.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); - rp2Supported = true; - } - ASSERT_NO_FATAL_FAILURE(InitState()); + VkAttachmentDescription attach_desc[2] = {}; + attach_desc[0].format = VK_FORMAT_B8G8R8A8_UNORM; + attach_desc[0].samples = VK_SAMPLE_COUNT_1_BIT; + attach_desc[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + attach_desc[0].finalLayout = VK_IMAGE_LAYOUT_GENERAL; + attach_desc[1].format = VK_FORMAT_B8G8R8A8_UNORM; + attach_desc[1].samples = VK_SAMPLE_COUNT_1_BIT; + attach_desc[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + attach_desc[1].finalLayout = VK_IMAGE_LAYOUT_GENERAL; - if (m_device->props.apiVersion < VK_API_VERSION_1_1) { - maintenance2Supported = true; - } + rpci.pAttachments = attach_desc; + rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - if (rp2Supported) { - vkCreateRenderPass2KHR = (PFN_vkCreateRenderPass2KHR)vkGetDeviceProcAddr(m_device->device(), "vkCreateRenderPass2KHR"); - } + VkRenderPass renderpass; + vkCreateRenderPass(m_device->device(), &rpci, NULL, &renderpass); + VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); + pipeline.AddShader(&vs); - VkAttachmentDescription description = {0, - VK_FORMAT_D32_SFLOAT_S8_UINT, - VK_SAMPLE_COUNT_1_BIT, - VK_ATTACHMENT_LOAD_OP_CLEAR, - VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_ATTACHMENT_LOAD_OP_CLEAR, - VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_IMAGE_LAYOUT_GENERAL, - VK_IMAGE_LAYOUT_GENERAL}; + VkPipelineColorBlendAttachmentState att_state1 = {}, att_state2 = {}; + att_state1.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR; + att_state1.blendEnable = VK_TRUE; + att_state2.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR; + att_state2.blendEnable = VK_FALSE; + pipeline.AddColorAttachment(0, att_state1); + pipeline.AddColorAttachment(1, att_state2); + pipeline.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderpass); + m_errorMonitor->VerifyFound(); + vkDestroyRenderPass(m_device->device(), renderpass, NULL); +} - VkAttachmentReference depth_stencil_ref = {0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL}; +// Is the Pipeline compatible with the expectations of the Renderpass/subpasses? +TEST_F(VkLayerTest, PipelineRenderpassCompatibility) { + TEST_DESCRIPTION( + "Create a graphics pipeline that is incompatible with the requirements of its contained Renderpass/subpasses."); + ASSERT_NO_FATAL_FAILURE(Init()); - VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, &depth_stencil_ref, 0, - nullptr}; + VkDescriptorSetObj ds_obj(m_device); + ds_obj.AppendDummy(); + ds_obj.CreateVKDescriptorSet(m_commandBuffer); - VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &description, 1, &subpass, 0, nullptr}; + VkShaderObj vs_obj(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); - // VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL but depth cleared - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkRenderPassCreateInfo-pAttachments-00836", "VUID-VkRenderPassCreateInfo2KHR-pAttachments-03053"); + VkPipelineColorBlendAttachmentState att_state1 = {}; + att_state1.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR; + att_state1.blendEnable = VK_TRUE; - if (maintenance2Supported) { - // VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL but depth cleared - depth_stencil_ref.layout = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL; + VkRenderpassObj rp_obj(m_device); - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkRenderPassCreateInfo-pAttachments-01566", nullptr); + { + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, + "VUID-VkGraphicsPipelineCreateInfo-rasterizerDiscardEnable-00753"); + VkPipelineObj pipeline(m_device); + pipeline.AddShader(&vs_obj); + pipeline.AddColorAttachment(0, att_state1); - // VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL but depth cleared - depth_stencil_ref.layout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL; + VkGraphicsPipelineCreateInfo info = {}; + pipeline.InitGraphicsPipelineCreateInfo(&info); + info.pColorBlendState = nullptr; - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkRenderPassCreateInfo-pAttachments-01567", nullptr); + pipeline.CreateVKPipeline(ds_obj.GetPipelineLayout(), rp_obj.handle(), &info); + m_errorMonitor->VerifyFound(); } } -TEST_F(VkLayerTest, RenderPassCreateAttachmentUsedTwiceColor) { - TEST_DESCRIPTION("Attachment is used simultaneously as two color attachments. This is usually unintended."); - - // Check for VK_KHR_get_physical_device_properties2 - if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { - m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - } - - ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); - PFN_vkCreateRenderPass2KHR vkCreateRenderPass2KHR = nullptr; - bool rp2Supported = false; - - // Check for VK_KHR_create_renderpass2 - if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME)) { - m_device_extension_names.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); - rp2Supported = true; - } - ASSERT_NO_FATAL_FAILURE(InitState()); +TEST_F(VkLayerTest, CreateRenderPassAttachments) { + TEST_DESCRIPTION( + "Ensure that CreateRenderPass produces the expected validation errors when a subpass's attachments violate the valid usage " + "conditions."); - if (rp2Supported) { - vkCreateRenderPass2KHR = (PFN_vkCreateRenderPass2KHR)vkGetDeviceProcAddr(m_device->device(), "vkCreateRenderPass2KHR"); - } + ASSERT_NO_FATAL_FAILURE(Init()); - VkAttachmentDescription attach[] = { + std::vector attachments = { + // input attachments + {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, + VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL}, + // color attachments + {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, + VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, + {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, + VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, + // depth attachment + {0, VK_FORMAT_D24_UNORM_S8_UINT, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, + VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}, + // resolve attachment {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED, + VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, + // preserve attachments + {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, + VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, }; - VkAttachmentReference refs[] = { - {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, - {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, - }; - VkSubpassDescription subpasses[] = { - {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 2, refs, nullptr, nullptr, 0, nullptr}, - }; - - VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 1, subpasses, 0, nullptr}; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "subpass 0 already uses attachment 0 as a color attachment", - "subpass 0 already uses attachment 0 as a color attachment"); -} - -TEST_F(VkLayerTest, RenderPassCreateAttachmentDescriptionInvalidFinalLayout) { - TEST_DESCRIPTION("VkAttachmentDescription's finalLayout must not be UNDEFINED or PREINITIALIZED"); - - // Check for VK_KHR_get_physical_device_properties2 - if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { - m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - } - - ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); - PFN_vkCreateRenderPass2KHR vkCreateRenderPass2KHR = nullptr; - bool rp2Supported = false; - - // Check for VK_KHR_create_renderpass2 - if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME)) { - m_device_extension_names.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); - rp2Supported = true; - } - ASSERT_NO_FATAL_FAILURE(InitState()); - - if (rp2Supported) { - vkCreateRenderPass2KHR = (PFN_vkCreateRenderPass2KHR)vkGetDeviceProcAddr(m_device->device(), "vkCreateRenderPass2KHR"); - } - - VkAttachmentDescription attach_desc = {}; - attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM; - attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; - attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attach_desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - attach_desc.finalLayout = VK_IMAGE_LAYOUT_UNDEFINED; - VkAttachmentReference attach_ref = {}; - attach_ref.attachment = 0; - attach_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - VkSubpassDescription subpass = {}; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.colorAttachmentCount = 1; - subpass.pColorAttachments = &attach_ref; - VkRenderPassCreateInfo rpci = {}; - rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - rpci.attachmentCount = 1; - rpci.pAttachments = &attach_desc; - rpci.subpassCount = 1; - rpci.pSubpasses = &subpass; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkAttachmentDescription-finalLayout-00843", "VUID-VkAttachmentDescription2KHR-finalLayout-03061"); - - attach_desc.finalLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkAttachmentDescription-finalLayout-00843", "VUID-VkAttachmentDescription2KHR-finalLayout-03061"); -} - -TEST_F(VkLayerTest, RenderPassCreateAttachmentsMisc) { - TEST_DESCRIPTION( - "Ensure that CreateRenderPass produces the expected validation errors when a subpass's attachments violate the valid usage " - "conditions."); - - // Check for VK_KHR_get_physical_device_properties2 - if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { - m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - } - - ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); - PFN_vkCreateRenderPass2KHR vkCreateRenderPass2KHR = nullptr; - bool rp2Supported = false; - - // Check for VK_KHR_create_renderpass2 - if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME)) { - m_device_extension_names.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); - rp2Supported = true; - } - ASSERT_NO_FATAL_FAILURE(InitState()); - - if (rp2Supported) { - vkCreateRenderPass2KHR = (PFN_vkCreateRenderPass2KHR)vkGetDeviceProcAddr(m_device->device(), "vkCreateRenderPass2KHR"); - } - - std::vector attachments = { - // input attachments - {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL}, - // color attachments - {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, - {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, - // depth attachment - {0, VK_FORMAT_D24_UNORM_S8_UINT, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}, - // resolve attachment - {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, - // preserve attachments - {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, - }; - - std::vector input = { - {0, VK_IMAGE_LAYOUT_GENERAL}, - }; - std::vector color = { - {1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, - {2, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, - }; - VkAttachmentReference depth = {3, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; - std::vector resolve = { - {4, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, - {VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, - }; - std::vector preserve = {5}; - - VkSubpassDescription subpass = {0, - VK_PIPELINE_BIND_POINT_GRAPHICS, - (uint32_t)input.size(), - input.data(), - (uint32_t)color.size(), - color.data(), - resolve.data(), - &depth, - (uint32_t)preserve.size(), - preserve.data()}; - - VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, - nullptr, - 0, - (uint32_t)attachments.size(), - attachments.data(), - 1, - &subpass, - 0, - nullptr}; - - // Test too many color attachments - { - std::vector too_many_colors(m_device->props.limits.maxColorAttachments + 1, color[0]); - subpass.colorAttachmentCount = (uint32_t)too_many_colors.size(); - subpass.pColorAttachments = too_many_colors.data(); - subpass.pResolveAttachments = NULL; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkSubpassDescription-colorAttachmentCount-00845", - "VUID-VkSubpassDescription2KHR-colorAttachmentCount-03063"); - - subpass.colorAttachmentCount = (uint32_t)color.size(); - subpass.pColorAttachments = color.data(); - subpass.pResolveAttachments = resolve.data(); - } - - // Test sample count mismatch between color buffers - attachments[subpass.pColorAttachments[1].attachment].samples = VK_SAMPLE_COUNT_8_BIT; - depth.attachment = VK_ATTACHMENT_UNUSED; // Avoids triggering 01418 - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkSubpassDescription-pColorAttachments-01417", - "VUID-VkSubpassDescription2KHR-pColorAttachments-03069"); - - depth.attachment = 3; - attachments[subpass.pColorAttachments[1].attachment].samples = attachments[subpass.pColorAttachments[0].attachment].samples; - - // Test sample count mismatch between color buffers and depth buffer - attachments[subpass.pDepthStencilAttachment->attachment].samples = VK_SAMPLE_COUNT_8_BIT; - subpass.colorAttachmentCount = 1; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkSubpassDescription-pDepthStencilAttachment-01418", - "VUID-VkSubpassDescription2KHR-pDepthStencilAttachment-03071"); - - attachments[subpass.pDepthStencilAttachment->attachment].samples = attachments[subpass.pColorAttachments[0].attachment].samples; - subpass.colorAttachmentCount = (uint32_t)color.size(); - - // Test resolve attachment with UNUSED color attachment - color[0].attachment = VK_ATTACHMENT_UNUSED; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkSubpassDescription-pResolveAttachments-00847", - "VUID-VkSubpassDescription2KHR-pResolveAttachments-03065"); - - color[0].attachment = 1; - - // Test resolve from a single-sampled color attachment - attachments[subpass.pColorAttachments[0].attachment].samples = VK_SAMPLE_COUNT_1_BIT; - subpass.colorAttachmentCount = 1; // avoid mismatch (00337), and avoid double report - subpass.pDepthStencilAttachment = nullptr; // avoid mismatch (01418) - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkSubpassDescription-pResolveAttachments-00848", - "VUID-VkSubpassDescription2KHR-pResolveAttachments-03066"); - - attachments[subpass.pColorAttachments[0].attachment].samples = VK_SAMPLE_COUNT_4_BIT; - subpass.colorAttachmentCount = (uint32_t)color.size(); - subpass.pDepthStencilAttachment = &depth; - - // Test resolve to a multi-sampled resolve attachment - attachments[subpass.pResolveAttachments[0].attachment].samples = VK_SAMPLE_COUNT_4_BIT; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkSubpassDescription-pResolveAttachments-00849", - "VUID-VkSubpassDescription2KHR-pResolveAttachments-03067"); - - attachments[subpass.pResolveAttachments[0].attachment].samples = VK_SAMPLE_COUNT_1_BIT; - - // Test with color/resolve format mismatch - attachments[subpass.pColorAttachments[0].attachment].format = VK_FORMAT_R8G8B8A8_SRGB; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkSubpassDescription-pResolveAttachments-00850", - "VUID-VkSubpassDescription2KHR-pResolveAttachments-03068"); - - attachments[subpass.pColorAttachments[0].attachment].format = attachments[subpass.pResolveAttachments[0].attachment].format; - - // Test for UNUSED preserve attachments - preserve[0] = VK_ATTACHMENT_UNUSED; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkSubpassDescription-attachment-00853", "VUID-VkSubpassDescription2KHR-attachment-03073"); - - preserve[0] = 5; - // Test for preserve attachments used elsewhere in the subpass - color[0].attachment = preserve[0]; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkSubpassDescription-pPreserveAttachments-00854", - "VUID-VkSubpassDescription2KHR-pPreserveAttachments-03074"); - - color[0].attachment = 1; - - // Test for layout mismatch between input attachment and color attachment - input[0].attachment = color[0].attachment; - input[0].layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkSubpassDescription-layout-00855", "VUID-VkSubpassDescription2KHR-layout-03075"); - - input[0].attachment = 0; - input[0].layout = VK_IMAGE_LAYOUT_GENERAL; - - // Test for layout mismatch between input attachment and depth attachment - input[0].attachment = depth.attachment; - input[0].layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkSubpassDescription-layout-00855", "VUID-VkSubpassDescription2KHR-layout-03075"); - - input[0].attachment = 0; - input[0].layout = VK_IMAGE_LAYOUT_GENERAL; - - // Test for attachment used first as input with loadOp=CLEAR - { - std::vector subpasses = {subpass, subpass, subpass}; - subpasses[0].inputAttachmentCount = 0; - subpasses[1].inputAttachmentCount = 0; - attachments[input[0].attachment].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - VkRenderPassCreateInfo rpci_multipass = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, - nullptr, - 0, - (uint32_t)attachments.size(), - attachments.data(), - (uint32_t)subpasses.size(), - subpasses.data(), - 0, - nullptr}; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci_multipass, vkCreateRenderPass2KHR, - "VUID-VkSubpassDescription-loadOp-00846", "VUID-VkSubpassDescription2KHR-loadOp-03064"); - - attachments[input[0].attachment].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - } -} - -TEST_F(VkLayerTest, RenderPassCreateAttachmentReferenceInvalidLayout) { - TEST_DESCRIPTION("Attachment reference uses PREINITIALIZED or UNDEFINED layouts"); - - // Check for VK_KHR_get_physical_device_properties2 - if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { - m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - } - - ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); - PFN_vkCreateRenderPass2KHR vkCreateRenderPass2KHR = nullptr; - bool rp2Supported = false; - - // Check for VK_KHR_create_renderpass2 - if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME)) { - m_device_extension_names.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); - rp2Supported = true; - } - ASSERT_NO_FATAL_FAILURE(InitState()); - - if (rp2Supported) { - vkCreateRenderPass2KHR = (PFN_vkCreateRenderPass2KHR)vkGetDeviceProcAddr(m_device->device(), "vkCreateRenderPass2KHR"); - } - - VkAttachmentDescription attach[] = { - {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, - }; - VkAttachmentReference refs[] = { - {0, VK_IMAGE_LAYOUT_UNDEFINED}, - }; - VkSubpassDescription subpasses[] = { - {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, refs, nullptr, nullptr, 0, nullptr}, - }; - - VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 1, subpasses, 0, nullptr}; - - // Use UNDEFINED layout - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkAttachmentReference-layout-00857", "VUID-VkAttachmentReference2KHR-layout-03077"); - - // Use PREINITIALIZED layout - refs[0].layout = VK_IMAGE_LAYOUT_PREINITIALIZED; - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkAttachmentReference-layout-00857", "VUID-VkAttachmentReference2KHR-layout-03077"); -} - -TEST_F(VkLayerTest, RenderPassCreateOverlappingCorrelationMasks) { - TEST_DESCRIPTION("Create a subpass with overlapping correlation masks"); - - // Check for VK_KHR_get_physical_device_properties2 - if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { - m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - } - - ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); - PFN_vkCreateRenderPass2KHR vkCreateRenderPass2KHR = nullptr; - bool rp2Supported = false; - - if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MULTIVIEW_EXTENSION_NAME)) { - m_device_extension_names.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME); - } else { - printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_MULTIVIEW_EXTENSION_NAME); - return; - } - - // Check for VK_KHR_create_renderpass2 - if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME)) { - m_device_extension_names.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); - rp2Supported = true; - } - ASSERT_NO_FATAL_FAILURE(InitState()); - - if (rp2Supported) { - vkCreateRenderPass2KHR = (PFN_vkCreateRenderPass2KHR)vkGetDeviceProcAddr(m_device->device(), "vkCreateRenderPass2KHR"); - } - - VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr}; - uint32_t viewMasks[] = {0x3u}; - uint32_t correlationMasks[] = {0x1u, 0x3u}; - VkRenderPassMultiviewCreateInfo rpmvci = { - VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO, nullptr, 1, viewMasks, 0, nullptr, 2, correlationMasks}; - - VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, &rpmvci, 0, 0, nullptr, 1, &subpass, 0, nullptr}; - - // Correlation masks must not overlap - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkRenderPassMultiviewCreateInfo-pCorrelationMasks-00841", - "VUID-VkRenderPassCreateInfo2KHR-pCorrelatedViewMasks-03056"); - - // Check for more specific "don't set any correlation masks when multiview is not enabled" - if (rp2Supported) { - viewMasks[0] = 0; - correlationMasks[0] = 0; - correlationMasks[1] = 0; - safe_VkRenderPassCreateInfo2KHR safe_rpci2; - ConvertVkRenderPassCreateInfoToV2KHR(&rpci, &safe_rpci2); - - m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkRenderPassCreateInfo2KHR-viewMask-03057"); - VkRenderPass rp; - VkResult err = vkCreateRenderPass2KHR(m_device->device(), safe_rpci2.ptr(), nullptr, &rp); - if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr); - m_errorMonitor->VerifyFound(); - } -} - -TEST_F(VkLayerTest, RenderPassCreateInvalidViewMasks) { - TEST_DESCRIPTION("Create a subpass with the wrong number of view masks, or inconsistent setting of view masks"); - - // Check for VK_KHR_get_physical_device_properties2 - if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { - m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - } - - ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); - PFN_vkCreateRenderPass2KHR vkCreateRenderPass2KHR = nullptr; - bool rp2Supported = false; - - if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MULTIVIEW_EXTENSION_NAME)) { - m_device_extension_names.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME); - } else { - printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_MULTIVIEW_EXTENSION_NAME); - return; - } - - // Check for VK_KHR_create_renderpass2 - if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME)) { - m_device_extension_names.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); - rp2Supported = true; - } - ASSERT_NO_FATAL_FAILURE(InitState()); - - if (rp2Supported) { - vkCreateRenderPass2KHR = (PFN_vkCreateRenderPass2KHR)vkGetDeviceProcAddr(m_device->device(), "vkCreateRenderPass2KHR"); - } - - VkSubpassDescription subpasses[] = { - {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr}, - {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr}, - }; - uint32_t viewMasks[] = {0x3u, 0u}; - VkRenderPassMultiviewCreateInfo rpmvci = { - VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO, nullptr, 1, viewMasks, 0, nullptr, 0, nullptr}; - - VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, &rpmvci, 0, 0, nullptr, 2, subpasses, 0, nullptr}; - - // Not enough view masks - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkRenderPassCreateInfo-pNext-01928", "VUID-VkRenderPassCreateInfo2KHR-viewMask-03058"); -} - -TEST_F(VkLayerTest, RenderPassCreateInvalidInputAttachmentReferences) { - TEST_DESCRIPTION("Create a subpass with the meta data aspect mask set for an input attachment"); - - ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); - - if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE2_EXTENSION_NAME)) { - m_device_extension_names.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME); - } else { - printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_MAINTENANCE2_EXTENSION_NAME); - return; - } - - ASSERT_NO_FATAL_FAILURE(InitState()); - - VkAttachmentDescription attach = {0, - VK_FORMAT_R8G8B8A8_UNORM, - VK_SAMPLE_COUNT_1_BIT, - VK_ATTACHMENT_LOAD_OP_DONT_CARE, - VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_ATTACHMENT_LOAD_OP_DONT_CARE, - VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_IMAGE_LAYOUT_UNDEFINED, - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL}; - VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL}; - - VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &ref, 0, nullptr, nullptr, nullptr, 0, nullptr}; - VkInputAttachmentAspectReference iaar = {0, 0, VK_IMAGE_ASPECT_METADATA_BIT}; - VkRenderPassInputAttachmentAspectCreateInfo rpiaaci = {VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO, - nullptr, 1, &iaar}; - - VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, &rpiaaci, 0, 1, &attach, 1, &subpass, 0, nullptr}; - - // Invalid meta data aspect - m_errorMonitor->SetDesiredFailureMsg( - VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkRenderPassCreateInfo-pNext-01963"); // Cannot/should not avoid getting this one too - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, nullptr, - "VUID-VkInputAttachmentAspectReference-aspectMask-01964", nullptr); - - // Aspect not present - iaar.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, nullptr, "VUID-VkRenderPassCreateInfo-pNext-01963", nullptr); - - // Invalid subpass index - iaar.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - iaar.subpass = 1; - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, nullptr, "VUID-VkRenderPassCreateInfo-pNext-01926", nullptr); - iaar.subpass = 0; - - // Invalid input attachment index - iaar.inputAttachmentIndex = 1; - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, nullptr, "VUID-VkRenderPassCreateInfo-pNext-01927", nullptr); -} - -TEST_F(VkLayerTest, RenderPassCreateSubpassNonGraphicsPipeline) { - TEST_DESCRIPTION("Create a subpass with the compute pipeline bind point"); - // Check for VK_KHR_get_physical_device_properties2 - if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { - m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - } - - ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); - PFN_vkCreateRenderPass2KHR vkCreateRenderPass2KHR = nullptr; - bool rp2Supported = false; - - // Check for VK_KHR_create_renderpass2 - if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME)) { - m_device_extension_names.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); - rp2Supported = true; - } - ASSERT_NO_FATAL_FAILURE(InitState()); - - if (rp2Supported) { - vkCreateRenderPass2KHR = (PFN_vkCreateRenderPass2KHR)vkGetDeviceProcAddr(m_device->device(), "vkCreateRenderPass2KHR"); - } - - VkSubpassDescription subpasses[] = { - {0, VK_PIPELINE_BIND_POINT_COMPUTE, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr}, - }; - - VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 1, subpasses, 0, nullptr}; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkSubpassDescription-pipelineBindPoint-00844", - "VUID-VkSubpassDescription2KHR-pipelineBindPoint-03062"); -} - -TEST_F(VkLayerTest, RenderPassCreateSubpassMissingAttributesBitMultiviewNVX) { - TEST_DESCRIPTION("Create a subpass with the VK_SUBPASS_DESCRIPTION_PER_VIEW_ATTRIBUTES_BIT_NVX flag missing"); - - // Check for VK_KHR_get_physical_device_properties2 - if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { - m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - } else { - printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_EXTENSION_NAME); - return; - } - - ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); - PFN_vkCreateRenderPass2KHR vkCreateRenderPass2KHR = nullptr; - bool rp2Supported = false; - - if (DeviceExtensionSupported(gpu(), nullptr, VK_NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_EXTENSION_NAME)) { - m_device_extension_names.push_back(VK_NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME); - } else { - printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_EXTENSION_NAME); - return; - } - - // Check for VK_KHR_create_renderpass2 - if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME)) { - m_device_extension_names.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME); - rp2Supported = true; - } - ASSERT_NO_FATAL_FAILURE(InitState()); - - if (rp2Supported) { - vkCreateRenderPass2KHR = (PFN_vkCreateRenderPass2KHR)vkGetDeviceProcAddr(m_device->device(), "vkCreateRenderPass2KHR"); - } - - VkSubpassDescription subpasses[] = { - {VK_SUBPASS_DESCRIPTION_PER_VIEW_POSITION_X_ONLY_BIT_NVX, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, - nullptr, 0, nullptr}, - }; - - VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 1, subpasses, 0, nullptr}; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, "VUID-VkSubpassDescription-flags-00856", - "VUID-VkSubpassDescription2KHR-flags-03076"); -} - -TEST_F(VkLayerTest, RenderPassCreate2SubpassInvalidInputAttachmentParameters) { - TEST_DESCRIPTION("Create a subpass with parameters in the input attachment ref which are invalid"); - - // Check for VK_KHR_get_physical_device_properties2 - if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { - m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - } else { - printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); - return; - } - - ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); - - if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME)) { - m_device_extension_names.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME); - } else { - printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); - return; - } - - ASSERT_NO_FATAL_FAILURE(InitState()); - - PFN_vkCreateRenderPass2KHR vkCreateRenderPass2KHR = - (PFN_vkCreateRenderPass2KHR)vkGetDeviceProcAddr(m_device->device(), "vkCreateRenderPass2KHR"); - - VkResult err; - - VkAttachmentReference2KHR reference = {VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR, nullptr, VK_ATTACHMENT_UNUSED, - VK_IMAGE_LAYOUT_UNDEFINED, 0}; - VkSubpassDescription2KHR subpass = {VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR, - nullptr, - 0, - VK_PIPELINE_BIND_POINT_GRAPHICS, - 0, - 1, - &reference, - 0, - nullptr, - nullptr, - nullptr, - 0, - nullptr}; - - VkRenderPassCreateInfo2KHR rpci2 = { - VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR, nullptr, 0, 0, nullptr, 1, &subpass, 0, nullptr, 0, nullptr}; - VkRenderPass rp; - - // Test for aspect mask of 0 - m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSubpassDescription2KHR-aspectMask-03176"); - err = vkCreateRenderPass2KHR(m_device->device(), &rpci2, nullptr, &rp); - if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr); - m_errorMonitor->VerifyFound(); - - // Test for invalid aspect mask bits - reference.aspectMask |= VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM; - m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSubpassDescription2KHR-aspectMask-03175"); - err = vkCreateRenderPass2KHR(m_device->device(), &rpci2, nullptr, &rp); - if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr); - m_errorMonitor->VerifyFound(); -} - -TEST_F(VkLayerTest, RenderPassCreateInvalidSubpassDependencies) { - // Check for VK_KHR_get_physical_device_properties2 - if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { - m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - } - - ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); - PFN_vkCreateRenderPass2KHR vkCreateRenderPass2KHR = nullptr; - bool rp2Supported = false; - bool multiviewSupported = false; - - if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MULTIVIEW_EXTENSION_NAME)) { - m_device_extension_names.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME); - multiviewSupported = true; - } - - // Check for VK_KHR_create_renderpass2 - if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME)) { - m_device_extension_names.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME); - rp2Supported = true; - } - - // Add a device features struct enabling NO features - VkPhysicalDeviceFeatures features = {0}; - ASSERT_NO_FATAL_FAILURE(InitState(&features)); - - if (m_device->props.apiVersion >= VK_API_VERSION_1_1) { - multiviewSupported = true; - } - - if (rp2Supported) { - vkCreateRenderPass2KHR = (PFN_vkCreateRenderPass2KHR)vkGetDeviceProcAddr(m_device->device(), "vkCreateRenderPass2KHR"); - } - - // Create two dummy subpasses - VkSubpassDescription subpasses[] = { - {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr}, - {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr}, - }; - - VkSubpassDependency dependency; - VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 2, subpasses, 1, &dependency}; - // dependency = { 0, 1, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, 0 }; - - // Source subpass is not EXTERNAL, so source stage mask must not include HOST - dependency = {0, 1, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, 0}; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkSubpassDependency-srcSubpass-00858", "VUID-VkSubpassDependency2KHR-srcSubpass-03078"); - - // Destination subpass is not EXTERNAL, so destination stage mask must not include HOST - dependency = {0, 1, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0, 0, 0}; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkSubpassDependency-dstSubpass-00859", "VUID-VkSubpassDependency2KHR-dstSubpass-03079"); - - // Geometry shaders not enabled source - dependency = {0, 1, VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, 0}; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkSubpassDependency-srcStageMask-00860", "VUID-VkSubpassDependency2KHR-srcStageMask-03080"); - - // Geometry shaders not enabled destination - dependency = {0, 1, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT, 0, 0, 0}; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkSubpassDependency-dstStageMask-00861", "VUID-VkSubpassDependency2KHR-dstStageMask-03081"); - - // Tessellation not enabled source - dependency = {0, 1, VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, 0}; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkSubpassDependency-srcStageMask-00862", "VUID-VkSubpassDependency2KHR-srcStageMask-03082"); - - // Tessellation not enabled destination - dependency = {0, 1, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT, 0, 0, 0}; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkSubpassDependency-dstStageMask-00863", "VUID-VkSubpassDependency2KHR-dstStageMask-03083"); - - // Potential cyclical dependency - dependency = {1, 0, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, 0}; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkSubpassDependency-srcSubpass-00864", "VUID-VkSubpassDependency2KHR-srcSubpass-03084"); - - // EXTERNAL to EXTERNAL dependency - dependency = { - VK_SUBPASS_EXTERNAL, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, 0}; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkSubpassDependency-srcSubpass-00865", "VUID-VkSubpassDependency2KHR-srcSubpass-03085"); - - // Source compute stage not part of subpass 0's GRAPHICS pipeline - dependency = {0, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, 0}; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkRenderPassCreateInfo-pDependencies-00837", "VUID-VkRenderPassCreateInfo2KHR-pDependencies-03054"); - - // Destination compute stage not part of subpass 0's GRAPHICS pipeline - dependency = {VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, 0}; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkRenderPassCreateInfo-pDependencies-00838", "VUID-VkRenderPassCreateInfo2KHR-pDependencies-03055"); - - // Non graphics stage in self dependency - dependency = {0, 0, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, 0}; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkSubpassDependency-srcSubpass-01989", "VUID-VkSubpassDependency2KHR-srcSubpass-02244"); - - // Logically later source stages in self dependency - dependency = {0, 0, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0, 0, 0}; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkSubpassDependency-srcSubpass-00867", "VUID-VkSubpassDependency2KHR-srcSubpass-03087"); - - // Source access mask mismatch with source stage mask - dependency = {0, 1, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_ACCESS_UNIFORM_READ_BIT, 0, 0}; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkSubpassDependency-srcAccessMask-00868", "VUID-VkSubpassDependency2KHR-srcAccessMask-03088"); - - // Destination access mask mismatch with destination stage mask - dependency = { - 0, 1, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 0}; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkSubpassDependency-dstAccessMask-00869", "VUID-VkSubpassDependency2KHR-dstAccessMask-03089"); - - if (multiviewSupported) { - // VIEW_LOCAL_BIT but multiview is not enabled - dependency = {0, 1, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, - 0, 0, VK_DEPENDENCY_VIEW_LOCAL_BIT}; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkSubpassDependency-dependencyFlags-00871", "VUID-VkRenderPassCreateInfo2KHR-viewMask-03059"); - - // Enable multiview - uint32_t pViewMasks[2] = {0x3u, 0x3u}; - int32_t pViewOffsets[2] = {0, 0}; - VkRenderPassMultiviewCreateInfo rpmvci = { - VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO, nullptr, 2, pViewMasks, 0, nullptr, 0, nullptr}; - rpci.pNext = &rpmvci; - - // Excessive view offsets - dependency = {0, 1, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, - 0, 0, VK_DEPENDENCY_VIEW_LOCAL_BIT}; - rpmvci.pViewOffsets = pViewOffsets; - rpmvci.dependencyCount = 2; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, nullptr, "VUID-VkRenderPassCreateInfo-pNext-01929", - nullptr); - - rpmvci.dependencyCount = 0; - - // View offset with subpass self dependency - dependency = {0, 0, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, - 0, 0, VK_DEPENDENCY_VIEW_LOCAL_BIT}; - rpmvci.pViewOffsets = pViewOffsets; - pViewOffsets[0] = 1; - rpmvci.dependencyCount = 1; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, nullptr, "VUID-VkRenderPassCreateInfo-pNext-01930", - nullptr); - - rpmvci.dependencyCount = 0; - - // View offset with no view local bit - if (rp2Supported) { - dependency = {0, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, 0}; - rpmvci.pViewOffsets = pViewOffsets; - pViewOffsets[0] = 1; - rpmvci.dependencyCount = 1; - - safe_VkRenderPassCreateInfo2KHR safe_rpci2; - ConvertVkRenderPassCreateInfoToV2KHR(&rpci, &safe_rpci2); - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, nullptr, - "VUID-VkSubpassDependency2KHR-dependencyFlags-03092"); - - rpmvci.dependencyCount = 0; - } - - // EXTERNAL subpass with VIEW_LOCAL_BIT - source subpass - dependency = {VK_SUBPASS_EXTERNAL, 1, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, - VK_DEPENDENCY_VIEW_LOCAL_BIT}; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkSubpassDependency-dependencyFlags-00870", - "VUID-VkSubpassDependency2KHR-dependencyFlags-03090"); - - // EXTERNAL subpass with VIEW_LOCAL_BIT - destination subpass - dependency = {0, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, - 0, VK_DEPENDENCY_VIEW_LOCAL_BIT}; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkSubpassDependency-dependencyFlags-00870", - "VUID-VkSubpassDependency2KHR-dependencyFlags-03091"); - - // Multiple views but no view local bit in self-dependency - dependency = {0, 0, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, 0}; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkSubpassDependency-srcSubpass-00872", "VUID-VkRenderPassCreateInfo2KHR-pDependencies-03060"); - } -} - -TEST_F(VkLayerTest, RenderPassCreateInvalidMixedAttachmentSamplesAMD) { - TEST_DESCRIPTION("Verify error messages for supported and unsupported sample counts in render pass attachments."); - - // Check for VK_KHR_get_physical_device_properties2 - if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { - m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - } - - ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); - PFN_vkCreateRenderPass2KHR vkCreateRenderPass2KHR = nullptr; - bool rp2Supported = false; - - if (DeviceExtensionSupported(gpu(), nullptr, VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME)) { - m_device_extension_names.push_back(VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME); - } else { - printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME); - return; - } - - // Check for VK_KHR_create_renderpass2 - if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME)) { - m_device_extension_names.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); - rp2Supported = true; - } - ASSERT_NO_FATAL_FAILURE(InitState()); - - if (rp2Supported) { - vkCreateRenderPass2KHR = (PFN_vkCreateRenderPass2KHR)vkGetDeviceProcAddr(m_device->device(), "vkCreateRenderPass2KHR"); - } - - std::vector attachments; - - { - VkAttachmentDescription att = {}; - att.format = VK_FORMAT_R8G8B8A8_UNORM; - att.samples = VK_SAMPLE_COUNT_1_BIT; - att.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - att.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - att.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - att.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - attachments.push_back(att); - - att.format = VK_FORMAT_D16_UNORM; - att.samples = VK_SAMPLE_COUNT_4_BIT; - att.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - att.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; - att.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - att.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - - attachments.push_back(att); - } - - VkAttachmentReference color_ref = {}; - color_ref.attachment = 0; - color_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - VkAttachmentReference depth_ref = {}; - depth_ref.attachment = 1; - depth_ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - - VkSubpassDescription subpass = {}; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.colorAttachmentCount = 1; - subpass.pColorAttachments = &color_ref; - subpass.pDepthStencilAttachment = &depth_ref; - - VkRenderPassCreateInfo rpci = {}; - rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - rpci.attachmentCount = attachments.size(); - rpci.pAttachments = attachments.data(); - rpci.subpassCount = 1; - rpci.pSubpasses = &subpass; - - m_errorMonitor->ExpectSuccess(); - - VkRenderPass rp; - VkResult err; - - err = vkCreateRenderPass(device(), &rpci, NULL, &rp); - m_errorMonitor->VerifyNotFound(); - if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr); - - // Expect an error message for invalid sample counts - attachments[0].samples = VK_SAMPLE_COUNT_4_BIT; - attachments[1].samples = VK_SAMPLE_COUNT_1_BIT; - - TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, vkCreateRenderPass2KHR, - "VUID-VkSubpassDescription-pColorAttachments-01506", - "VUID-VkSubpassDescription2KHR-pColorAttachments-03070"); -} - -static void TestRenderPassBegin(ErrorMonitor *error_monitor, const VkCommandBuffer command_buffer, - const VkRenderPassBeginInfo *begin_info, PFN_vkCmdBeginRenderPass2KHR vkCmdBeginRenderPass2KHR, - const char *rp1_vuid, const char *rp2_vuid) { - // "... must be less than the total number of attachments ..." - - VkCommandBufferBeginInfo cmd_begin_info = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, - VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, nullptr}; - - if (rp1_vuid) { - vkBeginCommandBuffer(command_buffer, &cmd_begin_info); - error_monitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, rp1_vuid); - vkCmdBeginRenderPass(command_buffer, begin_info, VK_SUBPASS_CONTENTS_INLINE); - error_monitor->VerifyFound(); - vkResetCommandBuffer(command_buffer, 0); - } - if (vkCmdBeginRenderPass2KHR && rp2_vuid) { - VkSubpassBeginInfoKHR subpass_begin_info = {VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR, nullptr, VK_SUBPASS_CONTENTS_INLINE}; - vkBeginCommandBuffer(command_buffer, &cmd_begin_info); - error_monitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, rp2_vuid); - vkCmdBeginRenderPass2KHR(command_buffer, begin_info, &subpass_begin_info); - error_monitor->VerifyFound(); - vkResetCommandBuffer(command_buffer, 0); - } -} - -TEST_F(VkLayerTest, RenderPassBeginInvalidRenderArea) { - TEST_DESCRIPTION("Generate INVALID_RENDER_AREA error by beginning renderpass with extent outside of framebuffer"); - // Check for VK_KHR_get_physical_device_properties2 - if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { - m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - } - - ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); - PFN_vkCmdBeginRenderPass2KHR vkCmdBeginRenderPass2KHR = nullptr; - bool rp2Supported = false; - - // Check for VK_KHR_create_renderpass2 - if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME)) { - m_device_extension_names.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); - rp2Supported = true; - } - ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT)); - - if (rp2Supported) { - vkCmdBeginRenderPass2KHR = - (PFN_vkCmdBeginRenderPass2KHR)vkGetDeviceProcAddr(m_device->device(), "vkCmdBeginRenderPass2KHR"); - } - - ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); - - // Framebuffer for render target is 256x256, exceed that for INVALID_RENDER_AREA - m_renderPassBeginInfo.renderArea.extent.width = 257; - m_renderPassBeginInfo.renderArea.extent.height = 257; - - TestRenderPassBegin(m_errorMonitor, m_commandBuffer->handle(), &m_renderPassBeginInfo, vkCmdBeginRenderPass2KHR, - "Cannot execute a render pass with renderArea not within the bound of the framebuffer.", - "Cannot execute a render pass with renderArea not within the bound of the framebuffer."); -} - -TEST_F(VkLayerTest, RenderPassBeginWithinRenderPass) { - // Check for VK_KHR_get_physical_device_properties2 - if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { - m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - } - - ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); - PFN_vkCmdBeginRenderPass2KHR vkCmdBeginRenderPass2KHR = nullptr; - bool rp2Supported = false; - - // Check for VK_KHR_create_renderpass2 - if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME)) { - m_device_extension_names.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); - rp2Supported = true; - } - ASSERT_NO_FATAL_FAILURE(InitState()); - - if (rp2Supported) { - vkCmdBeginRenderPass2KHR = - (PFN_vkCmdBeginRenderPass2KHR)vkGetDeviceProcAddr(m_device->device(), "vkCmdBeginRenderPass2KHR"); - } - - ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); - - // Bind a BeginRenderPass within an active RenderPass - m_commandBuffer->begin(); - m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); - - // Just use a dummy Renderpass - m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBeginRenderPass-renderpass"); - vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); - - m_errorMonitor->VerifyFound(); - - if (rp2Supported) { - VkSubpassBeginInfoKHR subpassBeginInfo = {VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR, nullptr, VK_SUBPASS_CONTENTS_INLINE}; - - m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBeginRenderPass2KHR-renderpass"); - vkCmdBeginRenderPass2KHR(m_commandBuffer->handle(), &m_renderPassBeginInfo, &subpassBeginInfo); - m_errorMonitor->VerifyFound(); - } -} - -TEST_F(VkLayerTest, RenderPassBeginIncompatibleFramebufferRenderPass) { - TEST_DESCRIPTION("Test that renderpass begin is compatible with the framebuffer renderpass "); - - ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT)); - - // Create a depth stencil image view - VkImageObj image(m_device); - - image.Init(128, 128, 1, VK_FORMAT_D16_UNORM, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL); - ASSERT_TRUE(image.initialized()); - - VkImageView dsv; - VkImageViewCreateInfo dsvci = {}; - dsvci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - dsvci.pNext = nullptr; - dsvci.image = image.handle(); - dsvci.viewType = VK_IMAGE_VIEW_TYPE_2D; - dsvci.format = VK_FORMAT_D16_UNORM; - dsvci.subresourceRange.layerCount = 1; - dsvci.subresourceRange.baseMipLevel = 0; - dsvci.subresourceRange.levelCount = 1; - dsvci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; - vkCreateImageView(m_device->device(), &dsvci, NULL, &dsv); - - // Create a renderPass with a single attachment that uses loadOp CLEAR - VkAttachmentDescription description = {0, - VK_FORMAT_D16_UNORM, - VK_SAMPLE_COUNT_1_BIT, - VK_ATTACHMENT_LOAD_OP_LOAD, - VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_ATTACHMENT_LOAD_OP_CLEAR, - VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_IMAGE_LAYOUT_GENERAL, - VK_IMAGE_LAYOUT_GENERAL}; - - VkAttachmentReference depth_stencil_ref = {0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; - - VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, &depth_stencil_ref, 0, - nullptr}; - - VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &description, 1, &subpass, 0, nullptr}; - VkRenderPass rp1, rp2; - - vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp1); - subpass.pDepthStencilAttachment = nullptr; - vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp2); - - // Create a framebuffer - - VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp1, 1, &dsv, 128, 128, 1}; - VkFramebuffer fb; - - vkCreateFramebuffer(m_device->handle(), &fbci, nullptr, &fb); - - VkRenderPassBeginInfo rp_begin = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp2, fb, {{0, 0}, {128, 128}}, 0, nullptr}; - - TestRenderPassBegin(m_errorMonitor, m_commandBuffer->handle(), &rp_begin, nullptr, - "VUID-VkRenderPassBeginInfo-renderPass-00904", nullptr); - - vkDestroyRenderPass(m_device->device(), rp1, nullptr); - vkDestroyRenderPass(m_device->device(), rp2, nullptr); - vkDestroyFramebuffer(m_device->device(), fb, nullptr); - vkDestroyImageView(m_device->device(), dsv, nullptr); -} - -TEST_F(VkLayerTest, RenderPassBeginLayoutsFramebufferImageUsageMismatches) { - TEST_DESCRIPTION( - "Test that renderpass initial/final layouts match up with the usage bits set for each attachment of the framebuffer"); - - // Check for VK_KHR_get_physical_device_properties2 - if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { - m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - } - - ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); - PFN_vkCmdBeginRenderPass2KHR vkCmdBeginRenderPass2KHR = nullptr; - bool rp2Supported = false; - bool maintenance2Supported = false; - - // Check for VK_KHR_maintenance2 - if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE2_EXTENSION_NAME)) { - m_device_extension_names.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME); - maintenance2Supported = true; - } - - // Check for VK_KHR_create_renderpass2 - if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME)) { - m_device_extension_names.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); - rp2Supported = true; - } - ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT)); - - if (m_device->props.apiVersion >= VK_API_VERSION_1_1) { - maintenance2Supported = true; - } - - if (rp2Supported) { - vkCmdBeginRenderPass2KHR = - (PFN_vkCmdBeginRenderPass2KHR)vkGetDeviceProcAddr(m_device->device(), "vkCmdBeginRenderPass2KHR"); - } - - // Create an input attachment view - VkImageObj iai(m_device); - - iai.InitNoLayout(128, 128, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL); - ASSERT_TRUE(iai.initialized()); - - VkImageView iav; - VkImageViewCreateInfo iavci = {}; - iavci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - iavci.pNext = nullptr; - iavci.image = iai.handle(); - iavci.viewType = VK_IMAGE_VIEW_TYPE_2D; - iavci.format = VK_FORMAT_R8G8B8A8_UNORM; - iavci.subresourceRange.layerCount = 1; - iavci.subresourceRange.baseMipLevel = 0; - iavci.subresourceRange.levelCount = 1; - iavci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - vkCreateImageView(m_device->device(), &iavci, NULL, &iav); - - // Create a color attachment view - VkImageObj cai(m_device); - - cai.InitNoLayout(128, 128, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL); - ASSERT_TRUE(cai.initialized()); - - VkImageView cav; - VkImageViewCreateInfo cavci = {}; - cavci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - cavci.pNext = nullptr; - cavci.image = cai.handle(); - cavci.viewType = VK_IMAGE_VIEW_TYPE_2D; - cavci.format = VK_FORMAT_R8G8B8A8_UNORM; - cavci.subresourceRange.layerCount = 1; - cavci.subresourceRange.baseMipLevel = 0; - cavci.subresourceRange.levelCount = 1; - cavci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - vkCreateImageView(m_device->device(), &cavci, NULL, &cav); - - // Create a renderPass with those attachments - VkAttachmentDescription descriptions[] = { - {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL}, - {1, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL}}; - - VkAttachmentReference input_ref = {0, VK_IMAGE_LAYOUT_GENERAL}; - VkAttachmentReference color_ref = {1, VK_IMAGE_LAYOUT_GENERAL}; - - VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &input_ref, 1, &color_ref, nullptr, nullptr, 0, nullptr}; - - VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, descriptions, 1, &subpass, 0, nullptr}; - - VkRenderPass rp; - - vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); - - // Create a framebuffer - - VkImageView views[] = {iav, cav}; - - VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 2, views, 128, 128, 1}; - VkFramebuffer fb; - - vkCreateFramebuffer(m_device->handle(), &fbci, nullptr, &fb); - - VkRenderPassBeginInfo rp_begin = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {128, 128}}, 0, nullptr}; - - VkRenderPass rp_invalid; - - // Initial layout is VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL but attachment doesn't support IMAGE_USAGE_COLOR_ATTACHMENT_BIT - descriptions[0].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp_invalid); - rp_begin.renderPass = rp_invalid; - TestRenderPassBegin(m_errorMonitor, m_commandBuffer->handle(), &rp_begin, vkCmdBeginRenderPass2KHR, - "VUID-vkCmdBeginRenderPass-initialLayout-00895", "VUID-vkCmdBeginRenderPass2KHR-initialLayout-03094"); - - vkDestroyRenderPass(m_device->handle(), rp_invalid, nullptr); - - // Initial layout is VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL but attachment doesn't support VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT - // / VK_IMAGE_USAGE_SAMPLED_BIT - descriptions[0].initialLayout = VK_IMAGE_LAYOUT_GENERAL; - descriptions[1].initialLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp_invalid); - rp_begin.renderPass = rp_invalid; - - TestRenderPassBegin(m_errorMonitor, m_commandBuffer->handle(), &rp_begin, vkCmdBeginRenderPass2KHR, - "VUID-vkCmdBeginRenderPass-initialLayout-00897", "VUID-vkCmdBeginRenderPass2KHR-initialLayout-03097"); - - vkDestroyRenderPass(m_device->handle(), rp_invalid, nullptr); - descriptions[1].initialLayout = VK_IMAGE_LAYOUT_GENERAL; - - // Initial layout is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL but attachment doesn't support VK_IMAGE_USAGE_TRANSFER_SRC_BIT - descriptions[0].initialLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; - vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp_invalid); - rp_begin.renderPass = rp_invalid; - - TestRenderPassBegin(m_errorMonitor, m_commandBuffer->handle(), &rp_begin, vkCmdBeginRenderPass2KHR, - "VUID-vkCmdBeginRenderPass-initialLayout-00898", "VUID-vkCmdBeginRenderPass2KHR-initialLayout-03098"); - - vkDestroyRenderPass(m_device->handle(), rp_invalid, nullptr); - - // Initial layout is VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL but attachment doesn't support VK_IMAGE_USAGE_TRANSFER_DST_BIT - descriptions[0].initialLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp_invalid); - rp_begin.renderPass = rp_invalid; - - TestRenderPassBegin(m_errorMonitor, m_commandBuffer->handle(), &rp_begin, vkCmdBeginRenderPass2KHR, - "VUID-vkCmdBeginRenderPass-initialLayout-00899", "VUID-vkCmdBeginRenderPass2KHR-initialLayout-03099"); - - vkDestroyRenderPass(m_device->handle(), rp_invalid, nullptr); - - // Initial layout is VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL but attachment doesn't support - // VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT - descriptions[0].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp_invalid); - rp_begin.renderPass = rp_invalid; - const char *initial_layout_vuid_rp1 = - maintenance2Supported ? "VUID-vkCmdBeginRenderPass-initialLayout-01758" : "VUID-vkCmdBeginRenderPass-initialLayout-00896"; - - TestRenderPassBegin(m_errorMonitor, m_commandBuffer->handle(), &rp_begin, vkCmdBeginRenderPass2KHR, initial_layout_vuid_rp1, - "VUID-vkCmdBeginRenderPass2KHR-initialLayout-03096"); - - vkDestroyRenderPass(m_device->handle(), rp_invalid, nullptr); - - // Initial layout is VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL but attachment doesn't support - // VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT - descriptions[0].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; - vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp_invalid); - rp_begin.renderPass = rp_invalid; - - TestRenderPassBegin(m_errorMonitor, m_commandBuffer->handle(), &rp_begin, vkCmdBeginRenderPass2KHR, initial_layout_vuid_rp1, - "VUID-vkCmdBeginRenderPass2KHR-initialLayout-03096"); - - vkDestroyRenderPass(m_device->handle(), rp_invalid, nullptr); - - if (maintenance2Supported || rp2Supported) { - // Initial layout is VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL but attachment doesn't support - // VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT - descriptions[0].initialLayout = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL; - vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp_invalid); - rp_begin.renderPass = rp_invalid; - - TestRenderPassBegin(m_errorMonitor, m_commandBuffer->handle(), &rp_begin, vkCmdBeginRenderPass2KHR, - "VUID-vkCmdBeginRenderPass-initialLayout-01758", "VUID-vkCmdBeginRenderPass2KHR-initialLayout-03096"); - - vkDestroyRenderPass(m_device->handle(), rp_invalid, nullptr); - - // Initial layout is VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL but attachment doesn't support - // VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT - descriptions[0].initialLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL; - vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp_invalid); - rp_begin.renderPass = rp_invalid; - - TestRenderPassBegin(m_errorMonitor, m_commandBuffer->handle(), &rp_begin, vkCmdBeginRenderPass2KHR, - "VUID-vkCmdBeginRenderPass-initialLayout-01758", "VUID-vkCmdBeginRenderPass2KHR-initialLayout-03096"); - - vkDestroyRenderPass(m_device->handle(), rp_invalid, nullptr); - } - - vkDestroyRenderPass(m_device->device(), rp, nullptr); - vkDestroyFramebuffer(m_device->device(), fb, nullptr); - vkDestroyImageView(m_device->device(), iav, nullptr); - vkDestroyImageView(m_device->device(), cav, nullptr); -} - -TEST_F(VkLayerTest, RenderPassBeginClearOpMismatch) { - TEST_DESCRIPTION( - "Begin a renderPass where clearValueCount is less than the number of renderPass attachments that use " - "loadOp VK_ATTACHMENT_LOAD_OP_CLEAR."); - - // Check for VK_KHR_get_physical_device_properties2 - if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { - m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - } - - ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); - PFN_vkCmdBeginRenderPass2KHR vkCmdBeginRenderPass2KHR = nullptr; - bool rp2Supported = false; - - // Check for VK_KHR_create_renderpass2 - if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME)) { - m_device_extension_names.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); - rp2Supported = true; - } - ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT)); - - if (rp2Supported) { - vkCmdBeginRenderPass2KHR = - (PFN_vkCmdBeginRenderPass2KHR)vkGetDeviceProcAddr(m_device->device(), "vkCmdBeginRenderPass2KHR"); - } - - ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); - - // Create a renderPass with a single attachment that uses loadOp CLEAR - VkAttachmentReference attach = {}; - attach.layout = VK_IMAGE_LAYOUT_GENERAL; - VkSubpassDescription subpass = {}; - subpass.colorAttachmentCount = 1; - subpass.pColorAttachments = &attach; - VkRenderPassCreateInfo rpci = {}; - rpci.subpassCount = 1; - rpci.pSubpasses = &subpass; - rpci.attachmentCount = 1; - VkAttachmentDescription attach_desc = {}; - attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM; - // Set loadOp to CLEAR - attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; - attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; - rpci.pAttachments = &attach_desc; - rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - VkRenderPass rp; - vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); - - VkCommandBufferInheritanceInfo hinfo = {}; - hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; - hinfo.renderPass = VK_NULL_HANDLE; - hinfo.subpass = 0; - hinfo.framebuffer = VK_NULL_HANDLE; - hinfo.occlusionQueryEnable = VK_FALSE; - hinfo.queryFlags = 0; - hinfo.pipelineStatistics = 0; - VkCommandBufferBeginInfo info = {}; - info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - info.pInheritanceInfo = &hinfo; - - VkRenderPassBeginInfo rp_begin = {}; - rp_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - rp_begin.pNext = NULL; - rp_begin.renderPass = renderPass(); - rp_begin.framebuffer = framebuffer(); - rp_begin.clearValueCount = 0; // Should be 1 - - TestRenderPassBegin(m_errorMonitor, m_commandBuffer->handle(), &rp_begin, vkCmdBeginRenderPass2KHR, - "VUID-VkRenderPassBeginInfo-clearValueCount-00902", "VUID-VkRenderPassBeginInfo-clearValueCount-00902"); - - vkDestroyRenderPass(m_device->device(), rp, NULL); -} - -TEST_F(VkLayerTest, RenderPassBeginSampleLocationsInvalidIndicesEXT) { - TEST_DESCRIPTION("Test that attachment indices and subpass indices specifed by sample locations structures are valid"); - - ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); - if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME)) { - m_device_extension_names.push_back(VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME); - } else { - printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME); - return; - } - - ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT)); - - // Create a depth stencil image view - VkImageObj image(m_device); - - image.Init(128, 128, 1, VK_FORMAT_D16_UNORM, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL); - ASSERT_TRUE(image.initialized()); - - VkImageView dsv; - VkImageViewCreateInfo dsvci = {}; - dsvci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - dsvci.pNext = nullptr; - dsvci.image = image.handle(); - dsvci.viewType = VK_IMAGE_VIEW_TYPE_2D; - dsvci.format = VK_FORMAT_D16_UNORM; - dsvci.subresourceRange.layerCount = 1; - dsvci.subresourceRange.baseMipLevel = 0; - dsvci.subresourceRange.levelCount = 1; - dsvci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; - vkCreateImageView(m_device->device(), &dsvci, NULL, &dsv); - - // Create a renderPass with a single attachment that uses loadOp CLEAR - VkAttachmentDescription description = {0, - VK_FORMAT_D16_UNORM, - VK_SAMPLE_COUNT_1_BIT, - VK_ATTACHMENT_LOAD_OP_LOAD, - VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_ATTACHMENT_LOAD_OP_CLEAR, - VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_IMAGE_LAYOUT_GENERAL, - VK_IMAGE_LAYOUT_GENERAL}; - - VkAttachmentReference depth_stencil_ref = {0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; - - VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, &depth_stencil_ref, 0, - nullptr}; - - VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &description, 1, &subpass, 0, nullptr}; - VkRenderPass rp; - - vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); - - // Create a framebuffer - - VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &dsv, 128, 128, 1}; - VkFramebuffer fb; - - vkCreateFramebuffer(m_device->handle(), &fbci, nullptr, &fb); - - VkSampleLocationEXT sample_location = {0.5, 0.5}; - - VkSampleLocationsInfoEXT sample_locations_info = { - VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT, nullptr, VK_SAMPLE_COUNT_1_BIT, {1, 1}, 1, &sample_location}; - - VkAttachmentSampleLocationsEXT attachment_sample_locations = {0, sample_locations_info}; - VkSubpassSampleLocationsEXT subpass_sample_locations = {0, sample_locations_info}; - - VkRenderPassSampleLocationsBeginInfoEXT rp_sl_begin = {VK_STRUCTURE_TYPE_RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT, - nullptr, - 1, - &attachment_sample_locations, - 1, - &subpass_sample_locations}; - - VkRenderPassBeginInfo rp_begin = { - VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, &rp_sl_begin, rp, fb, {{0, 0}, {128, 128}}, 0, nullptr}; - - attachment_sample_locations.attachmentIndex = 1; - TestRenderPassBegin(m_errorMonitor, m_commandBuffer->handle(), &rp_begin, nullptr, - "VUID-VkAttachmentSampleLocationsEXT-attachmentIndex-01531", nullptr); - attachment_sample_locations.attachmentIndex = 0; - - subpass_sample_locations.subpassIndex = 1; - TestRenderPassBegin(m_errorMonitor, m_commandBuffer->handle(), &rp_begin, nullptr, - "VUID-VkSubpassSampleLocationsEXT-subpassIndex-01532", nullptr); - subpass_sample_locations.subpassIndex = 0; - - vkDestroyRenderPass(m_device->device(), rp, nullptr); - vkDestroyFramebuffer(m_device->device(), fb, nullptr); - vkDestroyImageView(m_device->device(), dsv, nullptr); -} - -TEST_F(VkLayerTest, RenderPassNextSubpassExcessive) { - TEST_DESCRIPTION("Test that an error is produced when CmdNextSubpass is called too many times in a renderpass instance"); - - // Check for VK_KHR_get_physical_device_properties2 - if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { - m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - } - - ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); - PFN_vkCmdNextSubpass2KHR vkCmdNextSubpass2KHR = nullptr; - bool rp2Supported = false; - - // Check for VK_KHR_create_renderpass2 - if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME)) { - m_device_extension_names.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); - rp2Supported = true; - } - ASSERT_NO_FATAL_FAILURE(InitState()); - - if (rp2Supported) { - vkCmdNextSubpass2KHR = (PFN_vkCmdNextSubpass2KHR)vkGetDeviceProcAddr(m_device->device(), "vkCmdNextSubpass2KHR"); - } - - ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); - - m_commandBuffer->begin(); - m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); - - m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdNextSubpass-None-00909"); - vkCmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE); - m_errorMonitor->VerifyFound(); - - if (rp2Supported) { - VkSubpassBeginInfoKHR subpassBeginInfo = {VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR, nullptr, VK_SUBPASS_CONTENTS_INLINE}; - VkSubpassEndInfoKHR subpassEndInfo = {VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR, nullptr}; - - m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdNextSubpass2KHR-None-03102"); - - vkCmdNextSubpass2KHR(m_commandBuffer->handle(), &subpassBeginInfo, &subpassEndInfo); - m_errorMonitor->VerifyFound(); - } - - m_commandBuffer->EndRenderPass(); - m_commandBuffer->end(); -} - -TEST_F(VkLayerTest, RenderPassEndBeforeFinalSubpass) { - TEST_DESCRIPTION("Test that an error is produced when CmdEndRenderPass is called before the final subpass has been reached"); - - // Check for VK_KHR_get_physical_device_properties2 - if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { - m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - } - - ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); - PFN_vkCmdEndRenderPass2KHR vkCmdEndRenderPass2KHR = nullptr; - bool rp2Supported = false; - - // Check for VK_KHR_create_renderpass2 - if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME)) { - m_device_extension_names.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME); - m_device_extension_names.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); - rp2Supported = true; - } - ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT)); - - if (rp2Supported) { - vkCmdEndRenderPass2KHR = (PFN_vkCmdEndRenderPass2KHR)vkGetDeviceProcAddr(m_device->device(), "vkCmdEndRenderPass2KHR"); - } - - VkSubpassDescription sd[2] = {{0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr}, - {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr}}; - - VkRenderPassCreateInfo rcpi = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 2, sd, 0, nullptr}; - - VkRenderPass rp; - VkResult err = vkCreateRenderPass(m_device->device(), &rcpi, nullptr, &rp); - ASSERT_VK_SUCCESS(err); - - VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 0, nullptr, 16, 16, 1}; - - VkFramebuffer fb; - err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb); - ASSERT_VK_SUCCESS(err); - - m_commandBuffer->begin(); - - VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {16, 16}}, 0, nullptr}; - - vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); - - m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdEndRenderPass-None-00910"); - vkCmdEndRenderPass(m_commandBuffer->handle()); - m_errorMonitor->VerifyFound(); - - if (rp2Supported) { - VkSubpassEndInfoKHR subpassEndInfo = {VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR, nullptr}; - - m_commandBuffer->reset(); - m_commandBuffer->begin(); - vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); - - m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdEndRenderPass2KHR-None-03103"); - vkCmdEndRenderPass2KHR(m_commandBuffer->handle(), &subpassEndInfo); - m_errorMonitor->VerifyFound(); - } - - // Clean up. - vkDestroyFramebuffer(m_device->device(), fb, nullptr); - vkDestroyRenderPass(m_device->device(), rp, nullptr); -} - -TEST_F(VkLayerTest, RenderPassDestroyWhileInUse) { - TEST_DESCRIPTION("Delete in-use renderPass."); - - ASSERT_NO_FATAL_FAILURE(Init()); - ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); - - // Create simple renderpass - VkAttachmentReference attach = {}; - attach.layout = VK_IMAGE_LAYOUT_GENERAL; - VkSubpassDescription subpass = {}; - subpass.colorAttachmentCount = 1; - subpass.pColorAttachments = &attach; - VkRenderPassCreateInfo rpci = {}; - rpci.subpassCount = 1; - rpci.pSubpasses = &subpass; - rpci.attachmentCount = 1; - VkAttachmentDescription attach_desc = {}; - attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM; - attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; - attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; - rpci.pAttachments = &attach_desc; - rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - VkRenderPass rp; - VkResult err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); - ASSERT_VK_SUCCESS(err); - - m_errorMonitor->ExpectSuccess(); - - m_commandBuffer->begin(); - VkRenderPassBeginInfo rpbi = {}; - rpbi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - rpbi.framebuffer = m_framebuffer; - rpbi.renderPass = rp; - m_commandBuffer->BeginRenderPass(rpbi); - m_commandBuffer->EndRenderPass(); - m_commandBuffer->end(); - - VkSubmitInfo submit_info = {}; - submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submit_info.commandBufferCount = 1; - submit_info.pCommandBuffers = &m_commandBuffer->handle(); - vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); - m_errorMonitor->VerifyNotFound(); - - m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkDestroyRenderPass-renderPass-00873"); - vkDestroyRenderPass(m_device->device(), rp, nullptr); - m_errorMonitor->VerifyFound(); - - // Wait for queue to complete so we can safely destroy rp - vkQueueWaitIdle(m_device->m_queue); - m_errorMonitor->SetUnexpectedError("If renderPass is not VK_NULL_HANDLE, renderPass must be a valid VkRenderPass handle"); - m_errorMonitor->SetUnexpectedError("Was it created? Has it already been destroyed?"); - vkDestroyRenderPass(m_device->device(), rp, nullptr); -} - -TEST_F(VkPositiveLayerTest, RenderPassCreateAttachmentUsedTwiceOK) { - TEST_DESCRIPTION("Attachment is used simultaneously as color and input, with the same layout. This is OK."); - - ASSERT_NO_FATAL_FAILURE(Init()); - - VkAttachmentDescription attach[] = { - {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL}, - }; - VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_GENERAL}; - VkSubpassDescription subpasses[] = { - {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &ref, 1, &ref, nullptr, nullptr, 0, nullptr}, - }; - - VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 1, subpasses, 0, nullptr}; - VkRenderPass rp; - - m_errorMonitor->ExpectSuccess(); - vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); - m_errorMonitor->VerifyNotFound(); - vkDestroyRenderPass(m_device->device(), rp, nullptr); -} - -TEST_F(VkPositiveLayerTest, RenderPassCreateInitialLayoutUndefined) { - TEST_DESCRIPTION( - "Ensure that CmdBeginRenderPass with an attachment's initialLayout of VK_IMAGE_LAYOUT_UNDEFINED works when the command " - "buffer has prior knowledge of that attachment's layout."); - - m_errorMonitor->ExpectSuccess(); - - ASSERT_NO_FATAL_FAILURE(Init()); - - // A renderpass with one color attachment. - VkAttachmentDescription attachment = {0, - VK_FORMAT_R8G8B8A8_UNORM, - VK_SAMPLE_COUNT_1_BIT, - VK_ATTACHMENT_LOAD_OP_DONT_CARE, - VK_ATTACHMENT_STORE_OP_STORE, - VK_ATTACHMENT_LOAD_OP_DONT_CARE, - VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_IMAGE_LAYOUT_UNDEFINED, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; - - VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; - - VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr}; - - VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr}; - - VkRenderPass rp; - VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); - ASSERT_VK_SUCCESS(err); - - // A compatible framebuffer. - VkImageObj image(m_device); - image.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); - ASSERT_TRUE(image.initialized()); - - VkImageViewCreateInfo ivci = { - VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, - nullptr, - 0, - image.handle(), - VK_IMAGE_VIEW_TYPE_2D, - VK_FORMAT_R8G8B8A8_UNORM, - {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, - VK_COMPONENT_SWIZZLE_IDENTITY}, - {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}, - }; - VkImageView view; - err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view); - ASSERT_VK_SUCCESS(err); - - VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1}; - VkFramebuffer fb; - err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb); - ASSERT_VK_SUCCESS(err); - - // Record a single command buffer which uses this renderpass twice. The - // bug is triggered at the beginning of the second renderpass, when the - // command buffer already has a layout recorded for the attachment. - VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr}; - m_commandBuffer->begin(); - vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); - vkCmdEndRenderPass(m_commandBuffer->handle()); - vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); - - m_errorMonitor->VerifyNotFound(); - - vkCmdEndRenderPass(m_commandBuffer->handle()); - m_commandBuffer->end(); - - vkDestroyFramebuffer(m_device->device(), fb, nullptr); - vkDestroyRenderPass(m_device->device(), rp, nullptr); - vkDestroyImageView(m_device->device(), view, nullptr); -} - -TEST_F(VkPositiveLayerTest, RenderPassCreateAttachmentLayoutWithLoadOpThenReadOnly) { - TEST_DESCRIPTION( - "Positive test where we create a renderpass with an attachment that uses LOAD_OP_CLEAR, the first subpass has a valid " - "layout, and a second subpass then uses a valid *READ_ONLY* layout."); - m_errorMonitor->ExpectSuccess(); - ASSERT_NO_FATAL_FAILURE(Init()); - auto depth_format = FindSupportedDepthStencilFormat(gpu()); - if (!depth_format) { - printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix); - return; - } - - VkAttachmentReference attach[2] = {}; - attach[0].attachment = 0; - attach[0].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - attach[1].attachment = 0; - attach[1].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; - VkSubpassDescription subpasses[2] = {}; - // First subpass clears DS attach on load - subpasses[0].pDepthStencilAttachment = &attach[0]; - // 2nd subpass reads in DS as input attachment - subpasses[1].inputAttachmentCount = 1; - subpasses[1].pInputAttachments = &attach[1]; - VkAttachmentDescription attach_desc = {}; - attach_desc.format = depth_format; - attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; - attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - attach_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - attach_desc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; - VkRenderPassCreateInfo rpci = {}; - rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - rpci.attachmentCount = 1; - rpci.pAttachments = &attach_desc; - rpci.subpassCount = 2; - rpci.pSubpasses = subpasses; - - // Now create RenderPass and verify no errors - VkRenderPass rp; - vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); - m_errorMonitor->VerifyNotFound(); - - vkDestroyRenderPass(m_device->device(), rp, NULL); -} - -TEST_F(VkPositiveLayerTest, RenderPassBeginSubpassZeroTransitionsApplied) { - TEST_DESCRIPTION("Ensure that CmdBeginRenderPass applies the layout transitions for the first subpass"); - - m_errorMonitor->ExpectSuccess(); - - ASSERT_NO_FATAL_FAILURE(Init()); - - // A renderpass with one color attachment. - VkAttachmentDescription attachment = {0, - VK_FORMAT_R8G8B8A8_UNORM, - VK_SAMPLE_COUNT_1_BIT, - VK_ATTACHMENT_LOAD_OP_DONT_CARE, - VK_ATTACHMENT_STORE_OP_STORE, - VK_ATTACHMENT_LOAD_OP_DONT_CARE, - VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_IMAGE_LAYOUT_UNDEFINED, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; - - VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; - - VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr}; - - VkSubpassDependency dep = {0, - 0, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - VK_DEPENDENCY_BY_REGION_BIT}; - - VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 1, &dep}; - - VkResult err; - VkRenderPass rp; - err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); - ASSERT_VK_SUCCESS(err); - - // A compatible framebuffer. - VkImageObj image(m_device); - image.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); - ASSERT_TRUE(image.initialized()); - - VkImageView view = image.targetView(VK_FORMAT_R8G8B8A8_UNORM); - - VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1}; - VkFramebuffer fb; - err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb); - ASSERT_VK_SUCCESS(err); - - // Record a single command buffer which issues a pipeline barrier w/ - // image memory barrier for the attachment. This detects the previously - // missing tracking of the subpass layout by throwing a validation error - // if it doesn't occur. - VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr}; - m_commandBuffer->begin(); - vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); - - VkImageMemoryBarrier imb = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - nullptr, - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - VK_QUEUE_FAMILY_IGNORED, - VK_QUEUE_FAMILY_IGNORED, - image.handle(), - {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; - vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, - &imb); - - vkCmdEndRenderPass(m_commandBuffer->handle()); - m_errorMonitor->VerifyNotFound(); - m_commandBuffer->end(); - - vkDestroyFramebuffer(m_device->device(), fb, nullptr); - vkDestroyRenderPass(m_device->device(), rp, nullptr); -} - -TEST_F(VkPositiveLayerTest, RenderPassBeginTransitionsAttachmentUnused) { - TEST_DESCRIPTION( - "Ensure that layout transitions work correctly without errors, when an attachment reference is VK_ATTACHMENT_UNUSED"); - - m_errorMonitor->ExpectSuccess(); - - ASSERT_NO_FATAL_FAILURE(Init()); - - // A renderpass with no attachments - VkAttachmentReference att_ref = {VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; - - VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr}; - - VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 1, &subpass, 0, nullptr}; - - VkRenderPass rp; - VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); - ASSERT_VK_SUCCESS(err); - - // A compatible framebuffer. - VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 0, nullptr, 32, 32, 1}; - VkFramebuffer fb; - err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb); - ASSERT_VK_SUCCESS(err); - - // Record a command buffer which just begins and ends the renderpass. The - // bug manifests in BeginRenderPass. - VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr}; - m_commandBuffer->begin(); - vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); - vkCmdEndRenderPass(m_commandBuffer->handle()); - m_errorMonitor->VerifyNotFound(); - m_commandBuffer->end(); - - vkDestroyFramebuffer(m_device->device(), fb, nullptr); - vkDestroyRenderPass(m_device->device(), rp, nullptr); -} - -TEST_F(VkPositiveLayerTest, RenderPassBeginStencilLoadOp) { - TEST_DESCRIPTION("Create a stencil-only attachment with a LOAD_OP set to CLEAR. stencil[Load|Store]Op used to be ignored."); - VkResult result = VK_SUCCESS; - ASSERT_NO_FATAL_FAILURE(Init()); - auto depth_format = FindSupportedDepthStencilFormat(gpu()); - if (!depth_format) { - printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix); - return; - } - VkImageFormatProperties formatProps; - vkGetPhysicalDeviceImageFormatProperties(gpu(), depth_format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, - VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0, - &formatProps); - if (formatProps.maxExtent.width < 100 || formatProps.maxExtent.height < 100) { - printf("%s Image format max extent is too small.\n", kSkipPrefix); - return; - } - - VkFormat depth_stencil_fmt = depth_format; - m_depthStencil->Init(m_device, 100, 100, depth_stencil_fmt, - VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT); - VkAttachmentDescription att = {}; - VkAttachmentReference ref = {}; - att.format = depth_stencil_fmt; - att.samples = VK_SAMPLE_COUNT_1_BIT; - att.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - att.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; - att.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - att.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - - VkClearValue clear; - clear.depthStencil.depth = 1.0; - clear.depthStencil.stencil = 0; - ref.attachment = 0; - ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - - VkSubpassDescription subpass = {}; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.flags = 0; - subpass.inputAttachmentCount = 0; - subpass.pInputAttachments = NULL; - subpass.colorAttachmentCount = 0; - subpass.pColorAttachments = NULL; - subpass.pResolveAttachments = NULL; - subpass.pDepthStencilAttachment = &ref; - subpass.preserveAttachmentCount = 0; - subpass.pPreserveAttachments = NULL; - - VkRenderPass rp; - VkRenderPassCreateInfo rp_info = {}; - rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - rp_info.attachmentCount = 1; - rp_info.pAttachments = &att; - rp_info.subpassCount = 1; - rp_info.pSubpasses = &subpass; - result = vkCreateRenderPass(device(), &rp_info, NULL, &rp); - ASSERT_VK_SUCCESS(result); - - VkImageView *depthView = m_depthStencil->BindInfo(); - VkFramebufferCreateInfo fb_info = {}; - fb_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - fb_info.pNext = NULL; - fb_info.renderPass = rp; - fb_info.attachmentCount = 1; - fb_info.pAttachments = depthView; - fb_info.width = 100; - fb_info.height = 100; - fb_info.layers = 1; - VkFramebuffer fb; - result = vkCreateFramebuffer(device(), &fb_info, NULL, &fb); - ASSERT_VK_SUCCESS(result); - - VkRenderPassBeginInfo rpbinfo = {}; - rpbinfo.clearValueCount = 1; - rpbinfo.pClearValues = &clear; - rpbinfo.pNext = NULL; - rpbinfo.renderPass = rp; - rpbinfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - rpbinfo.renderArea.extent.width = 100; - rpbinfo.renderArea.extent.height = 100; - rpbinfo.renderArea.offset.x = 0; - rpbinfo.renderArea.offset.y = 0; - rpbinfo.framebuffer = fb; - - VkFenceObj fence; - fence.init(*m_device, VkFenceObj::create_info()); - ASSERT_TRUE(fence.initialized()); - - m_commandBuffer->begin(); - m_commandBuffer->BeginRenderPass(rpbinfo); - m_commandBuffer->EndRenderPass(); - m_commandBuffer->end(); - m_commandBuffer->QueueCommandBuffer(fence); - - VkImageObj destImage(m_device); - destImage.Init(100, 100, 1, depth_stencil_fmt, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, - VK_IMAGE_TILING_OPTIMAL, 0); - VkImageMemoryBarrier barrier = {}; - VkImageSubresourceRange range; - barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; - barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; - barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; - barrier.image = m_depthStencil->handle(); - range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; - range.baseMipLevel = 0; - range.levelCount = 1; - range.baseArrayLayer = 0; - range.layerCount = 1; - barrier.subresourceRange = range; - fence.wait(VK_TRUE, UINT64_MAX); - VkCommandBufferObj cmdbuf(m_device, m_commandPool); - cmdbuf.begin(); - cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1, - &barrier); - barrier.srcAccessMask = 0; - barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; - barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - barrier.image = destImage.handle(); - barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; - cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1, - &barrier); - VkImageCopy cregion; - cregion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; - cregion.srcSubresource.mipLevel = 0; - cregion.srcSubresource.baseArrayLayer = 0; - cregion.srcSubresource.layerCount = 1; - cregion.srcOffset.x = 0; - cregion.srcOffset.y = 0; - cregion.srcOffset.z = 0; - cregion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; - cregion.dstSubresource.mipLevel = 0; - cregion.dstSubresource.baseArrayLayer = 0; - cregion.dstSubresource.layerCount = 1; - cregion.dstOffset.x = 0; - cregion.dstOffset.y = 0; - cregion.dstOffset.z = 0; - cregion.extent.width = 100; - cregion.extent.height = 100; - cregion.extent.depth = 1; - cmdbuf.CopyImage(m_depthStencil->handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, destImage.handle(), - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &cregion); - cmdbuf.end(); - - VkSubmitInfo submit_info; - submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submit_info.pNext = NULL; - submit_info.waitSemaphoreCount = 0; - submit_info.pWaitSemaphores = NULL; - submit_info.pWaitDstStageMask = NULL; - submit_info.commandBufferCount = 1; - submit_info.pCommandBuffers = &cmdbuf.handle(); - submit_info.signalSemaphoreCount = 0; - submit_info.pSignalSemaphores = NULL; - - m_errorMonitor->ExpectSuccess(); - vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); - m_errorMonitor->VerifyNotFound(); - - vkQueueWaitIdle(m_device->m_queue); - vkDestroyRenderPass(m_device->device(), rp, nullptr); - vkDestroyFramebuffer(m_device->device(), fb, nullptr); -} - -TEST_F(VkPositiveLayerTest, RenderPassBeginInlineAndSecondaryCommandBuffers) { - m_errorMonitor->ExpectSuccess(); - - ASSERT_NO_FATAL_FAILURE(Init()); - ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); - - m_commandBuffer->begin(); - - vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); - vkCmdEndRenderPass(m_commandBuffer->handle()); - m_errorMonitor->VerifyNotFound(); - vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); - m_errorMonitor->VerifyNotFound(); - vkCmdEndRenderPass(m_commandBuffer->handle()); - m_errorMonitor->VerifyNotFound(); - - m_commandBuffer->end(); - m_errorMonitor->VerifyNotFound(); -} - -TEST_F(VkPositiveLayerTest, RenderPassBeginDepthStencilLayoutTransitionFromUndefined) { - TEST_DESCRIPTION( - "Create a render pass with depth-stencil attachment where layout transition from UNDEFINED TO DS_READ_ONLY_OPTIMAL is set " - "by render pass and verify that transition has correctly occurred at queue submit time with no validation errors."); - - ASSERT_NO_FATAL_FAILURE(Init()); - auto depth_format = FindSupportedDepthStencilFormat(gpu()); - if (!depth_format) { - printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix); - return; - } - VkImageFormatProperties format_props; - vkGetPhysicalDeviceImageFormatProperties(gpu(), depth_format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, - VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, 0, &format_props); - if (format_props.maxExtent.width < 32 || format_props.maxExtent.height < 32) { - printf("%s Depth extent too small, RenderPassDepthStencilLayoutTransition skipped.\n", kSkipPrefix); - return; - } - - m_errorMonitor->ExpectSuccess(); - ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); - - // A renderpass with one depth/stencil attachment. - VkAttachmentDescription attachment = {0, - depth_format, - VK_SAMPLE_COUNT_1_BIT, - VK_ATTACHMENT_LOAD_OP_DONT_CARE, - VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_ATTACHMENT_LOAD_OP_DONT_CARE, - VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_IMAGE_LAYOUT_UNDEFINED, - VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; - - VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; - - VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, &att_ref, 0, nullptr}; - - VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr}; - - VkRenderPass rp; - VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); - ASSERT_VK_SUCCESS(err); - // A compatible ds image. - VkImageObj image(m_device); - image.Init(32, 32, 1, depth_format, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); - ASSERT_TRUE(image.initialized()); - - VkImageViewCreateInfo ivci = { - VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, - nullptr, - 0, - image.handle(), - VK_IMAGE_VIEW_TYPE_2D, - depth_format, - {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, - VK_COMPONENT_SWIZZLE_IDENTITY}, - {VK_IMAGE_ASPECT_DEPTH_BIT, 0, 1, 0, 1}, - }; - VkImageView view; - err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view); - ASSERT_VK_SUCCESS(err); - - VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1}; - VkFramebuffer fb; - err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb); - ASSERT_VK_SUCCESS(err); - - VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr}; - m_commandBuffer->begin(); - vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); - vkCmdEndRenderPass(m_commandBuffer->handle()); - m_commandBuffer->end(); - m_commandBuffer->QueueCommandBuffer(false); - m_errorMonitor->VerifyNotFound(); - - // Cleanup - vkDestroyImageView(m_device->device(), view, NULL); - vkDestroyRenderPass(m_device->device(), rp, NULL); - vkDestroyFramebuffer(m_device->device(), fb, NULL); -} - -TEST_F(VkLayerTest, DisabledIndependentBlend) { - TEST_DESCRIPTION( - "Generate INDEPENDENT_BLEND by disabling independent blend and then specifying different blend states for two " - "attachments"); - VkPhysicalDeviceFeatures features = {}; - features.independentBlend = VK_FALSE; - ASSERT_NO_FATAL_FAILURE(Init(&features)); - - m_errorMonitor->SetDesiredFailureMsg( - VK_DEBUG_REPORT_ERROR_BIT_EXT, - "Invalid Pipeline CreateInfo: If independent blend feature not enabled, all elements of pAttachments must be identical"); - - VkDescriptorSetObj descriptorSet(m_device); - descriptorSet.AppendDummy(); - descriptorSet.CreateVKDescriptorSet(m_commandBuffer); - - VkPipelineObj pipeline(m_device); - // Create a renderPass with two color attachments - VkAttachmentReference attachments[2] = {}; - attachments[0].layout = VK_IMAGE_LAYOUT_GENERAL; - attachments[1].attachment = 1; - attachments[1].layout = VK_IMAGE_LAYOUT_GENERAL; - - VkSubpassDescription subpass = {}; - subpass.pColorAttachments = attachments; - subpass.colorAttachmentCount = 2; - - VkRenderPassCreateInfo rpci = {}; - rpci.subpassCount = 1; - rpci.pSubpasses = &subpass; - rpci.attachmentCount = 2; - VkAttachmentDescription attach_desc[2] = {}; - attach_desc[0].format = VK_FORMAT_B8G8R8A8_UNORM; - attach_desc[0].samples = VK_SAMPLE_COUNT_1_BIT; - attach_desc[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - attach_desc[0].finalLayout = VK_IMAGE_LAYOUT_GENERAL; - attach_desc[1].format = VK_FORMAT_B8G8R8A8_UNORM; - attach_desc[1].samples = VK_SAMPLE_COUNT_1_BIT; - attach_desc[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - attach_desc[1].finalLayout = VK_IMAGE_LAYOUT_GENERAL; + std::vector input = { + {0, VK_IMAGE_LAYOUT_GENERAL}, + }; + std::vector color = { + {1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, + {2, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, + }; + VkAttachmentReference depth = {3, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; + std::vector resolve = { + {4, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, + {VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, + }; + std::vector preserve = {5}; - rpci.pAttachments = attach_desc; - rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + VkSubpassDescription subpass = {0, + VK_PIPELINE_BIND_POINT_GRAPHICS, + (uint32_t)input.size(), + input.data(), + (uint32_t)color.size(), + color.data(), + resolve.data(), + &depth, + (uint32_t)preserve.size(), + preserve.data()}; - VkRenderPass renderpass; - vkCreateRenderPass(m_device->device(), &rpci, NULL, &renderpass); - VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); - pipeline.AddShader(&vs); + VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, + nullptr, + 0, + (uint32_t)attachments.size(), + attachments.data(), + 1, + &subpass, + 0, + nullptr}; - VkPipelineColorBlendAttachmentState att_state1 = {}, att_state2 = {}; - att_state1.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR; - att_state1.blendEnable = VK_TRUE; - att_state2.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR; - att_state2.blendEnable = VK_FALSE; - pipeline.AddColorAttachment(0, att_state1); - pipeline.AddColorAttachment(1, att_state2); - pipeline.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderpass); + VkRenderPass rp; + VkResult err; + // Test too many color attachments + { + std::vector too_many_colors(m_device->props.limits.maxColorAttachments + 1, color[0]); + subpass.colorAttachmentCount = (uint32_t)too_many_colors.size(); + subpass.pColorAttachments = too_many_colors.data(); + subpass.pResolveAttachments = NULL; + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSubpassDescription-colorAttachmentCount-00845"); + err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); + m_errorMonitor->VerifyFound(); + if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr); + subpass.colorAttachmentCount = (uint32_t)color.size(); + subpass.pColorAttachments = color.data(); + subpass.pResolveAttachments = resolve.data(); + } + // Test sample count mismatch between color buffers + attachments[subpass.pColorAttachments[1].attachment].samples = VK_SAMPLE_COUNT_8_BIT; + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSubpassDescription-pColorAttachments-01417"); + err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); m_errorMonitor->VerifyFound(); - vkDestroyRenderPass(m_device->device(), renderpass, NULL); -} - -// Is the Pipeline compatible with the expectations of the Renderpass/subpasses? -TEST_F(VkLayerTest, PipelineRenderpassCompatibility) { - TEST_DESCRIPTION( - "Create a graphics pipeline that is incompatible with the requirements of its contained Renderpass/subpasses."); - ASSERT_NO_FATAL_FAILURE(Init()); - - VkDescriptorSetObj ds_obj(m_device); - ds_obj.AppendDummy(); - ds_obj.CreateVKDescriptorSet(m_commandBuffer); - - VkShaderObj vs_obj(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); - - VkPipelineColorBlendAttachmentState att_state1 = {}; - att_state1.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR; - att_state1.blendEnable = VK_TRUE; - - VkRenderpassObj rp_obj(m_device); - + if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr); + attachments[subpass.pColorAttachments[1].attachment].samples = attachments[subpass.pColorAttachments[0].attachment].samples; + // Test sample count mismatch between color buffers and depth buffer + attachments[subpass.pDepthStencilAttachment->attachment].samples = VK_SAMPLE_COUNT_8_BIT; + subpass.colorAttachmentCount = 1; + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSubpassDescription-pDepthStencilAttachment-01418"); + err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); + m_errorMonitor->VerifyFound(); + if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr); + attachments[subpass.pDepthStencilAttachment->attachment].samples = attachments[subpass.pColorAttachments[0].attachment].samples; + subpass.colorAttachmentCount = (uint32_t)color.size(); + // Test resolve attachment with UNUSED color attachment + color[0].attachment = VK_ATTACHMENT_UNUSED; + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSubpassDescription-pResolveAttachments-00847"); + err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); + m_errorMonitor->VerifyFound(); + if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr); + color[0].attachment = 1; + // Test resolve from a single-sampled color attachment + attachments[subpass.pColorAttachments[0].attachment].samples = VK_SAMPLE_COUNT_1_BIT; + subpass.colorAttachmentCount = 1; // avoid mismatch (00337), and avoid double report + subpass.pDepthStencilAttachment = nullptr; // avoid mismatch (01418) + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSubpassDescription-pResolveAttachments-00848"); + err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); + m_errorMonitor->VerifyFound(); + if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr); + attachments[subpass.pColorAttachments[0].attachment].samples = VK_SAMPLE_COUNT_4_BIT; + subpass.colorAttachmentCount = (uint32_t)color.size(); // avoid mismatch (00337), and avoid double report + subpass.pDepthStencilAttachment = &depth; + // Test resolve to a multi-sampled resolve attachment + attachments[subpass.pResolveAttachments[0].attachment].samples = VK_SAMPLE_COUNT_4_BIT; + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSubpassDescription-pResolveAttachments-00849"); + err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); + m_errorMonitor->VerifyFound(); + if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr); + attachments[subpass.pResolveAttachments[0].attachment].samples = VK_SAMPLE_COUNT_1_BIT; + // Test with color/resolve format mismatch + attachments[subpass.pColorAttachments[0].attachment].format = VK_FORMAT_R8G8B8A8_SRGB; + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSubpassDescription-pResolveAttachments-00850"); + err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); + m_errorMonitor->VerifyFound(); + if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr); + attachments[subpass.pColorAttachments[0].attachment].format = attachments[subpass.pResolveAttachments[0].attachment].format; + // Test for UNUSED preserve attachments + preserve[0] = VK_ATTACHMENT_UNUSED; + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSubpassDescription-attachment-00853"); + err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); + m_errorMonitor->VerifyFound(); + if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr); + preserve[0] = 5; + // Test for preserve attachments used elsewhere in the subpass + color[0].attachment = preserve[0]; + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSubpassDescription-pPreserveAttachments-00854"); + err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); + m_errorMonitor->VerifyFound(); + if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr); + color[0].attachment = 1; + // test for layout mismatch between input attachment and color attachment + input[0].attachment = color[0].attachment; + input[0].layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSubpassDescription-layout-00855"); + err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); + m_errorMonitor->VerifyFound(); + if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr); + input[0].attachment = 0; + input[0].layout = VK_IMAGE_LAYOUT_GENERAL; + // test for layout mismatch between input attachment and depth attachment + input[0].attachment = depth.attachment; + input[0].layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSubpassDescription-layout-00855"); + err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); + m_errorMonitor->VerifyFound(); + if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr); + input[0].attachment = 0; + input[0].layout = VK_IMAGE_LAYOUT_GENERAL; + // Test for attachment used first as input with loadOp=CLEAR { - m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, - "VUID-VkGraphicsPipelineCreateInfo-rasterizerDiscardEnable-00753"); - VkPipelineObj pipeline(m_device); - pipeline.AddShader(&vs_obj); - pipeline.AddColorAttachment(0, att_state1); - - VkGraphicsPipelineCreateInfo info = {}; - pipeline.InitGraphicsPipelineCreateInfo(&info); - info.pColorBlendState = nullptr; - - pipeline.CreateVKPipeline(ds_obj.GetPipelineLayout(), rp_obj.handle(), &info); + std::vector subpasses = {subpass, subpass, subpass}; + subpasses[0].inputAttachmentCount = 0; + subpasses[1].inputAttachmentCount = 0; + attachments[input[0].attachment].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + VkRenderPassCreateInfo rpci_multipass = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, + nullptr, + 0, + (uint32_t)attachments.size(), + attachments.data(), + (uint32_t)subpasses.size(), + subpasses.data(), + 0, + nullptr}; + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSubpassDescription-loadOp-00846"); + err = vkCreateRenderPass(m_device->device(), &rpci_multipass, nullptr, &rp); m_errorMonitor->VerifyFound(); + if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr); + attachments[input[0].attachment].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; } } @@ -9761,25 +7720,80 @@ TEST_F(VkLayerTest, FramebufferImageInUseDestroyedSignaled) { m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); m_commandBuffer->EndRenderPass(); m_commandBuffer->end(); - // Submit cmd buffer to put it (and attached imageView) in-flight + // Submit cmd buffer to put it (and attached imageView) in-flight + VkSubmitInfo submit_info = {}; + submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submit_info.commandBufferCount = 1; + submit_info.pCommandBuffers = &m_commandBuffer->handle(); + // Submit cmd buffer to put framebuffer and children in-flight + vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); + // Destroy image attached to framebuffer while in-flight + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkDestroyImage-image-01000"); + vkDestroyImage(m_device->device(), image, NULL); + m_errorMonitor->VerifyFound(); + // Wait for queue to complete so we can safely destroy image and other objects + vkQueueWaitIdle(m_device->m_queue); + m_errorMonitor->SetUnexpectedError("If image is not VK_NULL_HANDLE, image must be a valid VkImage handle"); + m_errorMonitor->SetUnexpectedError("Unable to remove Image obj"); + vkDestroyImage(m_device->device(), image, NULL); + vkDestroyFramebuffer(m_device->device(), fb, nullptr); + vkDestroyImageView(m_device->device(), view, nullptr); + vkFreeMemory(m_device->device(), image_memory, nullptr); +} + +TEST_F(VkLayerTest, RenderPassInUseDestroyedSignaled) { + TEST_DESCRIPTION("Delete in-use renderPass."); + + ASSERT_NO_FATAL_FAILURE(Init()); + ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); + + // Create simple renderpass + VkAttachmentReference attach = {}; + attach.layout = VK_IMAGE_LAYOUT_GENERAL; + VkSubpassDescription subpass = {}; + subpass.colorAttachmentCount = 1; + subpass.pColorAttachments = &attach; + VkRenderPassCreateInfo rpci = {}; + rpci.subpassCount = 1; + rpci.pSubpasses = &subpass; + rpci.attachmentCount = 1; + VkAttachmentDescription attach_desc = {}; + attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM; + attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; + attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; + rpci.pAttachments = &attach_desc; + rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + VkRenderPass rp; + VkResult err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); + ASSERT_VK_SUCCESS(err); + + m_errorMonitor->ExpectSuccess(); + + m_commandBuffer->begin(); + VkRenderPassBeginInfo rpbi = {}; + rpbi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + rpbi.framebuffer = m_framebuffer; + rpbi.renderPass = rp; + m_commandBuffer->BeginRenderPass(rpbi); + m_commandBuffer->EndRenderPass(); + m_commandBuffer->end(); + VkSubmitInfo submit_info = {}; submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submit_info.commandBufferCount = 1; submit_info.pCommandBuffers = &m_commandBuffer->handle(); - // Submit cmd buffer to put framebuffer and children in-flight vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); - // Destroy image attached to framebuffer while in-flight - m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkDestroyImage-image-01000"); - vkDestroyImage(m_device->device(), image, NULL); + m_errorMonitor->VerifyNotFound(); + + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkDestroyRenderPass-renderPass-00873"); + vkDestroyRenderPass(m_device->device(), rp, nullptr); m_errorMonitor->VerifyFound(); - // Wait for queue to complete so we can safely destroy image and other objects + + // Wait for queue to complete so we can safely destroy rp vkQueueWaitIdle(m_device->m_queue); - m_errorMonitor->SetUnexpectedError("If image is not VK_NULL_HANDLE, image must be a valid VkImage handle"); - m_errorMonitor->SetUnexpectedError("Unable to remove Image obj"); - vkDestroyImage(m_device->device(), image, NULL); - vkDestroyFramebuffer(m_device->device(), fb, nullptr); - vkDestroyImageView(m_device->device(), view, nullptr); - vkFreeMemory(m_device->device(), image_memory, nullptr); + m_errorMonitor->SetUnexpectedError("If renderPass is not VK_NULL_HANDLE, renderPass must be a valid VkRenderPass handle"); + m_errorMonitor->SetUnexpectedError("Was it created? Has it already been destroyed?"); + vkDestroyRenderPass(m_device->device(), rp, nullptr); } TEST_F(VkLayerTest, ImageMemoryNotBound) { @@ -14028,6 +12042,85 @@ TEST_F(VkLayerTest, NullRenderPass) { m_commandBuffer->end(); } +TEST_F(VkLayerTest, RenderPassWithinRenderPass) { + // Bind a BeginRenderPass within an active RenderPass + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, + "It is invalid to issue this call inside an active render pass"); + + ASSERT_NO_FATAL_FAILURE(Init()); + ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); + + m_commandBuffer->begin(); + m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); + // Just create a dummy Renderpass that's non-NULL so we can get to the + // proper error + vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); + + m_errorMonitor->VerifyFound(); + + m_commandBuffer->EndRenderPass(); + m_commandBuffer->end(); +} + +TEST_F(VkLayerTest, RenderPassClearOpMismatch) { + TEST_DESCRIPTION( + "Begin a renderPass where clearValueCount is less than the number of renderPass attachments that use " + "loadOpVK_ATTACHMENT_LOAD_OP_CLEAR."); + + ASSERT_NO_FATAL_FAILURE(Init()); + ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); + + // Create a renderPass with a single attachment that uses loadOp CLEAR + VkAttachmentReference attach = {}; + attach.layout = VK_IMAGE_LAYOUT_GENERAL; + VkSubpassDescription subpass = {}; + subpass.colorAttachmentCount = 1; + subpass.pColorAttachments = &attach; + VkRenderPassCreateInfo rpci = {}; + rpci.subpassCount = 1; + rpci.pSubpasses = &subpass; + rpci.attachmentCount = 1; + VkAttachmentDescription attach_desc = {}; + attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM; + // Set loadOp to CLEAR + attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; + attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; + rpci.pAttachments = &attach_desc; + rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + VkRenderPass rp; + vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); + + VkCommandBufferInheritanceInfo hinfo = {}; + hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; + hinfo.renderPass = VK_NULL_HANDLE; + hinfo.subpass = 0; + hinfo.framebuffer = VK_NULL_HANDLE; + hinfo.occlusionQueryEnable = VK_FALSE; + hinfo.queryFlags = 0; + hinfo.pipelineStatistics = 0; + VkCommandBufferBeginInfo info = {}; + info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + info.pInheritanceInfo = &hinfo; + + vkBeginCommandBuffer(m_commandBuffer->handle(), &info); + VkRenderPassBeginInfo rp_begin = {}; + rp_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + rp_begin.pNext = NULL; + rp_begin.renderPass = renderPass(); + rp_begin.framebuffer = framebuffer(); + rp_begin.clearValueCount = 0; // Should be 1 + + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkRenderPassBeginInfo-clearValueCount-00902"); + + vkCmdBeginRenderPass(m_commandBuffer->handle(), &rp_begin, VK_SUBPASS_CONTENTS_INLINE); + + m_errorMonitor->VerifyFound(); + + vkDestroyRenderPass(m_device->device(), rp, NULL); +} + TEST_F(VkLayerTest, EndCommandBufferWithinRenderPass) { TEST_DESCRIPTION("End a command buffer with an active render pass"); @@ -14397,6 +12490,63 @@ TEST_F(VkLayerTest, ClearColorAttachmentsOutsideRenderPass) { m_errorMonitor->VerifyFound(); } +TEST_F(VkLayerTest, RenderPassExcessiveNextSubpass) { + TEST_DESCRIPTION("Test that an error is produced when CmdNextSubpass is called too many times in a renderpass instance"); + + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, + "vkCmdNextSubpass(): Attempted to advance beyond final subpass"); + + ASSERT_NO_FATAL_FAILURE(Init()); + ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); + + m_commandBuffer->begin(); + m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); + + // error here. + vkCmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE); + m_errorMonitor->VerifyFound(); + + m_commandBuffer->EndRenderPass(); + m_commandBuffer->end(); +} + +TEST_F(VkLayerTest, RenderPassEndedBeforeFinalSubpass) { + TEST_DESCRIPTION("Test that an error is produced when CmdEndRenderPass is called before the final subpass has been reached"); + + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, + "vkCmdEndRenderPass(): Called before reaching final subpass"); + + ASSERT_NO_FATAL_FAILURE(Init()); + VkSubpassDescription sd[2] = {{0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr}, + {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr}}; + + VkRenderPassCreateInfo rcpi = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 2, sd, 0, nullptr}; + + VkRenderPass rp; + VkResult err = vkCreateRenderPass(m_device->device(), &rcpi, nullptr, &rp); + ASSERT_VK_SUCCESS(err); + + VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 0, nullptr, 16, 16, 1}; + + VkFramebuffer fb; + err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb); + ASSERT_VK_SUCCESS(err); + + m_commandBuffer->begin(); // no implicit RP begin + + VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {16, 16}}, 0, nullptr}; + + vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); + + // Error here. + vkCmdEndRenderPass(m_commandBuffer->handle()); + m_errorMonitor->VerifyFound(); + + // Clean up. + vkDestroyFramebuffer(m_device->device(), fb, nullptr); + vkDestroyRenderPass(m_device->device(), rp, nullptr); +} + TEST_F(VkLayerTest, BufferMemoryBarrierNoBuffer) { // Try to add a buffer memory barrier with no buffer. m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, @@ -16463,7 +14613,7 @@ TEST_F(VkLayerTest, NumSamplesMismatch) { m_errorMonitor->VerifyFound(); } -TEST_F(VkLayerTest, DrawWithPipelineIncompatibleWithRenderPass) { +TEST_F(VkLayerTest, RenderPassIncompatible) { TEST_DESCRIPTION( "Hit RenderPass incompatible cases. Initial case is drawing with an active renderpass that's not compatible with the bound " "pipeline state object's creation renderpass"); @@ -21607,6 +19757,51 @@ TEST_F(VkLayerTest, AttachmentDescriptionUndefinedFormat) { } } +TEST_F(VkLayerTest, AttachmentDescriptionInvalidFinalLayout) { + TEST_DESCRIPTION("VkAttachmentDescription's finalLayout must not be UNDEFINED or PREINITIALIZED"); + + ASSERT_NO_FATAL_FAILURE(Init()); + + VkAttachmentDescription attach_desc = {}; + attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM; + attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; + attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + attach_desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + attach_desc.finalLayout = VK_IMAGE_LAYOUT_UNDEFINED; + VkAttachmentReference attach_ref = {}; + attach_ref.attachment = 0; + attach_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + VkSubpassDescription subpass = {}; + subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + subpass.colorAttachmentCount = 1; + subpass.pColorAttachments = &attach_ref; + VkRenderPassCreateInfo rpci = {}; + rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + rpci.attachmentCount = 1; + rpci.pAttachments = &attach_desc; + rpci.subpassCount = 1; + rpci.pSubpasses = &subpass; + VkRenderPass rp = VK_NULL_HANDLE; + + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkAttachmentDescription-finalLayout-00843"); + vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); + m_errorMonitor->VerifyFound(); + if (rp != VK_NULL_HANDLE) { + vkDestroyRenderPass(m_device->device(), rp, NULL); + } + + attach_desc.finalLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkAttachmentDescription-finalLayout-00843"); + vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); + m_errorMonitor->VerifyFound(); + if (rp != VK_NULL_HANDLE) { + vkDestroyRenderPass(m_device->device(), rp, NULL); + } +} + TEST_F(VkLayerTest, CreateImageViewNoMemoryBoundToImage) { VkResult err; m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, @@ -28706,6 +26901,80 @@ TEST_F(VkPositiveLayerTest, BindSparse) { m_errorMonitor->VerifyNotFound(); } +TEST_F(VkPositiveLayerTest, RenderPassInitialLayoutUndefined) { + TEST_DESCRIPTION( + "Ensure that CmdBeginRenderPass with an attachment's initialLayout of VK_IMAGE_LAYOUT_UNDEFINED works when the command " + "buffer has prior knowledge of that attachment's layout."); + + m_errorMonitor->ExpectSuccess(); + + ASSERT_NO_FATAL_FAILURE(Init()); + + // A renderpass with one color attachment. + VkAttachmentDescription attachment = {0, + VK_FORMAT_R8G8B8A8_UNORM, + VK_SAMPLE_COUNT_1_BIT, + VK_ATTACHMENT_LOAD_OP_DONT_CARE, + VK_ATTACHMENT_STORE_OP_STORE, + VK_ATTACHMENT_LOAD_OP_DONT_CARE, + VK_ATTACHMENT_STORE_OP_DONT_CARE, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; + + VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; + + VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr}; + + VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr}; + + VkRenderPass rp; + VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); + ASSERT_VK_SUCCESS(err); + + // A compatible framebuffer. + VkImageObj image(m_device); + image.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); + ASSERT_TRUE(image.initialized()); + + VkImageViewCreateInfo ivci = { + VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + nullptr, + 0, + image.handle(), + VK_IMAGE_VIEW_TYPE_2D, + VK_FORMAT_R8G8B8A8_UNORM, + {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, + VK_COMPONENT_SWIZZLE_IDENTITY}, + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}, + }; + VkImageView view; + err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view); + ASSERT_VK_SUCCESS(err); + + VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1}; + VkFramebuffer fb; + err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb); + ASSERT_VK_SUCCESS(err); + + // Record a single command buffer which uses this renderpass twice. The + // bug is triggered at the beginning of the second renderpass, when the + // command buffer already has a layout recorded for the attachment. + VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr}; + m_commandBuffer->begin(); + vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); + vkCmdEndRenderPass(m_commandBuffer->handle()); + vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); + + m_errorMonitor->VerifyNotFound(); + + vkCmdEndRenderPass(m_commandBuffer->handle()); + m_commandBuffer->end(); + + vkDestroyFramebuffer(m_device->device(), fb, nullptr); + vkDestroyRenderPass(m_device->device(), rp, nullptr); + vkDestroyImageView(m_device->device(), view, nullptr); +} + TEST_F(VkPositiveLayerTest, FramebufferBindingDestroyCommandPool) { TEST_DESCRIPTION( "This test should pass. Create a Framebuffer and command buffer, bind them together, then destroy command pool and " @@ -28781,7 +27050,86 @@ TEST_F(VkPositiveLayerTest, FramebufferBindingDestroyCommandPool) { m_errorMonitor->VerifyNotFound(); } -TEST_F(VkPositiveLayerTest, FramebufferCreateDepthStencilLayoutTransitionForDepthOnlyImageView) { +TEST_F(VkPositiveLayerTest, RenderPassSubpassZeroTransitionsApplied) { + TEST_DESCRIPTION("Ensure that CmdBeginRenderPass applies the layout transitions for the first subpass"); + + m_errorMonitor->ExpectSuccess(); + + ASSERT_NO_FATAL_FAILURE(Init()); + + // A renderpass with one color attachment. + VkAttachmentDescription attachment = {0, + VK_FORMAT_R8G8B8A8_UNORM, + VK_SAMPLE_COUNT_1_BIT, + VK_ATTACHMENT_LOAD_OP_DONT_CARE, + VK_ATTACHMENT_STORE_OP_STORE, + VK_ATTACHMENT_LOAD_OP_DONT_CARE, + VK_ATTACHMENT_STORE_OP_DONT_CARE, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; + + VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; + + VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr}; + + VkSubpassDependency dep = {0, + 0, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_DEPENDENCY_BY_REGION_BIT}; + + VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 1, &dep}; + + VkResult err; + VkRenderPass rp; + err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); + ASSERT_VK_SUCCESS(err); + + // A compatible framebuffer. + VkImageObj image(m_device); + image.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); + ASSERT_TRUE(image.initialized()); + + VkImageView view = image.targetView(VK_FORMAT_R8G8B8A8_UNORM); + + VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1}; + VkFramebuffer fb; + err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb); + ASSERT_VK_SUCCESS(err); + + // Record a single command buffer which issues a pipeline barrier w/ + // image memory barrier for the attachment. This detects the previously + // missing tracking of the subpass layout by throwing a validation error + // if it doesn't occur. + VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr}; + m_commandBuffer->begin(); + vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); + + VkImageMemoryBarrier imb = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + nullptr, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_QUEUE_FAMILY_IGNORED, + VK_QUEUE_FAMILY_IGNORED, + image.handle(), + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; + vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, + &imb); + + vkCmdEndRenderPass(m_commandBuffer->handle()); + m_errorMonitor->VerifyNotFound(); + m_commandBuffer->end(); + + vkDestroyFramebuffer(m_device->device(), fb, nullptr); + vkDestroyRenderPass(m_device->device(), rp, nullptr); +} + +TEST_F(VkPositiveLayerTest, DepthStencilLayoutTransitionForDepthOnlyImageview) { TEST_DESCRIPTION( "Validate that when an imageView of a depth/stencil image is used as a depth/stencil framebuffer attachment, the " "aspectMask is ignored and both depth and stencil image subresources are used."); @@ -28869,16 +27217,222 @@ TEST_F(VkPositiveLayerTest, FramebufferCreateDepthStencilLayoutTransitionForDept imb.subresourceRange.baseArrayLayer = 0; imb.subresourceRange.layerCount = 0x1; - vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, &imb); + vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, &imb); + + m_commandBuffer->end(); + m_commandBuffer->QueueCommandBuffer(false); + m_errorMonitor->VerifyNotFound(); + + vkDestroyFramebuffer(m_device->device(), fb, nullptr); + vkDestroyRenderPass(m_device->device(), rp, nullptr); + vkDestroyImageView(m_device->device(), view, nullptr); +} + +TEST_F(VkPositiveLayerTest, RenderPassTransitionsAttachmentUnused) { + TEST_DESCRIPTION( + "Ensure that layout transitions work correctly without errors, when an attachment reference is VK_ATTACHMENT_UNUSED"); + + m_errorMonitor->ExpectSuccess(); + + ASSERT_NO_FATAL_FAILURE(Init()); + + // A renderpass with no attachments + VkAttachmentReference att_ref = {VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; + + VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr}; + + VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 1, &subpass, 0, nullptr}; + + VkRenderPass rp; + VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); + ASSERT_VK_SUCCESS(err); + + // A compatible framebuffer. + VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 0, nullptr, 32, 32, 1}; + VkFramebuffer fb; + err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb); + ASSERT_VK_SUCCESS(err); + + // Record a command buffer which just begins and ends the renderpass. The + // bug manifests in BeginRenderPass. + VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr}; + m_commandBuffer->begin(); + vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); + vkCmdEndRenderPass(m_commandBuffer->handle()); + m_errorMonitor->VerifyNotFound(); + m_commandBuffer->end(); + + vkDestroyFramebuffer(m_device->device(), fb, nullptr); + vkDestroyRenderPass(m_device->device(), rp, nullptr); +} + +// This is a positive test. No errors are expected. +TEST_F(VkPositiveLayerTest, StencilLoadOp) { + TEST_DESCRIPTION("Create a stencil-only attachment with a LOAD_OP set to CLEAR. stencil[Load|Store]Op used to be ignored."); + VkResult result = VK_SUCCESS; + ASSERT_NO_FATAL_FAILURE(Init()); + auto depth_format = FindSupportedDepthStencilFormat(gpu()); + if (!depth_format) { + printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix); + return; + } + VkImageFormatProperties formatProps; + vkGetPhysicalDeviceImageFormatProperties(gpu(), depth_format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, + VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0, + &formatProps); + if (formatProps.maxExtent.width < 100 || formatProps.maxExtent.height < 100) { + printf("%s Image format max extent is too small.\n", kSkipPrefix); + return; + } + + VkFormat depth_stencil_fmt = depth_format; + m_depthStencil->Init(m_device, 100, 100, depth_stencil_fmt, + VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT); + VkAttachmentDescription att = {}; + VkAttachmentReference ref = {}; + att.format = depth_stencil_fmt; + att.samples = VK_SAMPLE_COUNT_1_BIT; + att.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + att.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; + att.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + att.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + + VkClearValue clear; + clear.depthStencil.depth = 1.0; + clear.depthStencil.stencil = 0; + ref.attachment = 0; + ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + + VkSubpassDescription subpass = {}; + subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + subpass.flags = 0; + subpass.inputAttachmentCount = 0; + subpass.pInputAttachments = NULL; + subpass.colorAttachmentCount = 0; + subpass.pColorAttachments = NULL; + subpass.pResolveAttachments = NULL; + subpass.pDepthStencilAttachment = &ref; + subpass.preserveAttachmentCount = 0; + subpass.pPreserveAttachments = NULL; + + VkRenderPass rp; + VkRenderPassCreateInfo rp_info = {}; + rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + rp_info.attachmentCount = 1; + rp_info.pAttachments = &att; + rp_info.subpassCount = 1; + rp_info.pSubpasses = &subpass; + result = vkCreateRenderPass(device(), &rp_info, NULL, &rp); + ASSERT_VK_SUCCESS(result); + + VkImageView *depthView = m_depthStencil->BindInfo(); + VkFramebufferCreateInfo fb_info = {}; + fb_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; + fb_info.pNext = NULL; + fb_info.renderPass = rp; + fb_info.attachmentCount = 1; + fb_info.pAttachments = depthView; + fb_info.width = 100; + fb_info.height = 100; + fb_info.layers = 1; + VkFramebuffer fb; + result = vkCreateFramebuffer(device(), &fb_info, NULL, &fb); + ASSERT_VK_SUCCESS(result); + + VkRenderPassBeginInfo rpbinfo = {}; + rpbinfo.clearValueCount = 1; + rpbinfo.pClearValues = &clear; + rpbinfo.pNext = NULL; + rpbinfo.renderPass = rp; + rpbinfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + rpbinfo.renderArea.extent.width = 100; + rpbinfo.renderArea.extent.height = 100; + rpbinfo.renderArea.offset.x = 0; + rpbinfo.renderArea.offset.y = 0; + rpbinfo.framebuffer = fb; + + VkFenceObj fence; + fence.init(*m_device, VkFenceObj::create_info()); + ASSERT_TRUE(fence.initialized()); + + m_commandBuffer->begin(); + m_commandBuffer->BeginRenderPass(rpbinfo); + m_commandBuffer->EndRenderPass(); + m_commandBuffer->end(); + m_commandBuffer->QueueCommandBuffer(fence); + + VkImageObj destImage(m_device); + destImage.Init(100, 100, 1, depth_stencil_fmt, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, + VK_IMAGE_TILING_OPTIMAL, 0); + VkImageMemoryBarrier barrier = {}; + VkImageSubresourceRange range; + barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; + barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + barrier.image = m_depthStencil->handle(); + range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; + range.baseMipLevel = 0; + range.levelCount = 1; + range.baseArrayLayer = 0; + range.layerCount = 1; + barrier.subresourceRange = range; + fence.wait(VK_TRUE, UINT64_MAX); + VkCommandBufferObj cmdbuf(m_device, m_commandPool); + cmdbuf.begin(); + cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1, + &barrier); + barrier.srcAccessMask = 0; + barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; + barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + barrier.image = destImage.handle(); + barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1, + &barrier); + VkImageCopy cregion; + cregion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; + cregion.srcSubresource.mipLevel = 0; + cregion.srcSubresource.baseArrayLayer = 0; + cregion.srcSubresource.layerCount = 1; + cregion.srcOffset.x = 0; + cregion.srcOffset.y = 0; + cregion.srcOffset.z = 0; + cregion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; + cregion.dstSubresource.mipLevel = 0; + cregion.dstSubresource.baseArrayLayer = 0; + cregion.dstSubresource.layerCount = 1; + cregion.dstOffset.x = 0; + cregion.dstOffset.y = 0; + cregion.dstOffset.z = 0; + cregion.extent.width = 100; + cregion.extent.height = 100; + cregion.extent.depth = 1; + cmdbuf.CopyImage(m_depthStencil->handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, destImage.handle(), + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &cregion); + cmdbuf.end(); + + VkSubmitInfo submit_info; + submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submit_info.pNext = NULL; + submit_info.waitSemaphoreCount = 0; + submit_info.pWaitSemaphores = NULL; + submit_info.pWaitDstStageMask = NULL; + submit_info.commandBufferCount = 1; + submit_info.pCommandBuffers = &cmdbuf.handle(); + submit_info.signalSemaphoreCount = 0; + submit_info.pSignalSemaphores = NULL; - m_commandBuffer->end(); - m_commandBuffer->QueueCommandBuffer(false); + m_errorMonitor->ExpectSuccess(); + vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); m_errorMonitor->VerifyNotFound(); - vkDestroyFramebuffer(m_device->device(), fb, nullptr); + vkQueueWaitIdle(m_device->m_queue); vkDestroyRenderPass(m_device->device(), rp, nullptr); - vkDestroyImageView(m_device->device(), view, nullptr); + vkDestroyFramebuffer(m_device->device(), fb, nullptr); } // This is a positive test. No errors should be generated. @@ -30241,6 +28795,154 @@ TEST_F(VkPositiveLayerTest, TwoSubmitInfosWithSemaphoreOneQueueSubmitsOneFence) m_errorMonitor->VerifyNotFound(); } +TEST_F(VkPositiveLayerTest, RenderPassSecondaryCommandBuffersMultipleTimes) { + m_errorMonitor->ExpectSuccess(); + + ASSERT_NO_FATAL_FAILURE(Init()); + ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); + + m_commandBuffer->begin(); + + vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); + vkCmdEndRenderPass(m_commandBuffer->handle()); + m_errorMonitor->VerifyNotFound(); + vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); + m_errorMonitor->VerifyNotFound(); + vkCmdEndRenderPass(m_commandBuffer->handle()); + m_errorMonitor->VerifyNotFound(); + + m_commandBuffer->end(); + m_errorMonitor->VerifyNotFound(); +} + +TEST_F(VkPositiveLayerTest, ValidRenderPassAttachmentLayoutWithLoadOp) { + TEST_DESCRIPTION( + "Positive test where we create a renderpass with an attachment that uses LOAD_OP_CLEAR, the first subpass has a valid " + "layout, and a second subpass then uses a valid *READ_ONLY* layout."); + m_errorMonitor->ExpectSuccess(); + ASSERT_NO_FATAL_FAILURE(Init()); + auto depth_format = FindSupportedDepthStencilFormat(gpu()); + if (!depth_format) { + printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix); + return; + } + + VkAttachmentReference attach[2] = {}; + attach[0].attachment = 0; + attach[0].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + attach[1].attachment = 0; + attach[1].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; + VkSubpassDescription subpasses[2] = {}; + // First subpass clears DS attach on load + subpasses[0].pDepthStencilAttachment = &attach[0]; + // 2nd subpass reads in DS as input attachment + subpasses[1].inputAttachmentCount = 1; + subpasses[1].pInputAttachments = &attach[1]; + VkAttachmentDescription attach_desc = {}; + attach_desc.format = depth_format; + attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; + attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + attach_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + attach_desc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; + VkRenderPassCreateInfo rpci = {}; + rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + rpci.attachmentCount = 1; + rpci.pAttachments = &attach_desc; + rpci.subpassCount = 2; + rpci.pSubpasses = subpasses; + + // Now create RenderPass and verify no errors + VkRenderPass rp; + vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); + m_errorMonitor->VerifyNotFound(); + + vkDestroyRenderPass(m_device->device(), rp, NULL); +} + +TEST_F(VkPositiveLayerTest, RenderPassDepthStencilLayoutTransition) { + TEST_DESCRIPTION( + "Create a render pass with depth-stencil attachment where layout transition from UNDEFINED TO DS_READ_ONLY_OPTIMAL is set " + "by render pass and verify that transition has correctly occurred at queue submit time with no validation errors."); + + ASSERT_NO_FATAL_FAILURE(Init()); + auto depth_format = FindSupportedDepthStencilFormat(gpu()); + if (!depth_format) { + printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix); + return; + } + VkImageFormatProperties format_props; + vkGetPhysicalDeviceImageFormatProperties(gpu(), depth_format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, + VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, 0, &format_props); + if (format_props.maxExtent.width < 32 || format_props.maxExtent.height < 32) { + printf("%s Depth extent too small, RenderPassDepthStencilLayoutTransition skipped.\n", kSkipPrefix); + return; + } + + m_errorMonitor->ExpectSuccess(); + ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); + + // A renderpass with one depth/stencil attachment. + VkAttachmentDescription attachment = {0, + depth_format, + VK_SAMPLE_COUNT_1_BIT, + VK_ATTACHMENT_LOAD_OP_DONT_CARE, + VK_ATTACHMENT_STORE_OP_DONT_CARE, + VK_ATTACHMENT_LOAD_OP_DONT_CARE, + VK_ATTACHMENT_STORE_OP_DONT_CARE, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; + + VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; + + VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, &att_ref, 0, nullptr}; + + VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr}; + + VkRenderPass rp; + VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); + ASSERT_VK_SUCCESS(err); + // A compatible ds image. + VkImageObj image(m_device); + image.Init(32, 32, 1, depth_format, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); + ASSERT_TRUE(image.initialized()); + + VkImageViewCreateInfo ivci = { + VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + nullptr, + 0, + image.handle(), + VK_IMAGE_VIEW_TYPE_2D, + depth_format, + {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, + VK_COMPONENT_SWIZZLE_IDENTITY}, + {VK_IMAGE_ASPECT_DEPTH_BIT, 0, 1, 0, 1}, + }; + VkImageView view; + err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view); + ASSERT_VK_SUCCESS(err); + + VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1}; + VkFramebuffer fb; + err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb); + ASSERT_VK_SUCCESS(err); + + VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr}; + m_commandBuffer->begin(); + vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); + vkCmdEndRenderPass(m_commandBuffer->handle()); + m_commandBuffer->end(); + m_commandBuffer->QueueCommandBuffer(false); + m_errorMonitor->VerifyNotFound(); + + // Cleanup + vkDestroyImageView(m_device->device(), view, NULL); + vkDestroyRenderPass(m_device->device(), rp, NULL); + vkDestroyFramebuffer(m_device->device(), fb, NULL); +} + TEST_F(VkPositiveLayerTest, CreatePipelineAttribMatrixType) { TEST_DESCRIPTION("Test that pipeline validation accepts matrices passed as vertex attributes"); m_errorMonitor->ExpectSuccess(); @@ -32149,6 +30851,86 @@ TEST_F(VkPositiveLayerTest, ExternalMemory) { m_errorMonitor->VerifyNotFound(); } +TEST_F(VkLayerTest, AMDMixedAttachmentSamplesValidateRenderPass) { + TEST_DESCRIPTION("Verify error messages for supported and unsupported sample counts in render pass attachments."); + + ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); + if (DeviceExtensionSupported(gpu(), nullptr, VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME)) { + m_device_extension_names.push_back(VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME); + } else { + printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME); + return; + } + ASSERT_NO_FATAL_FAILURE(InitState()); + + m_errorMonitor->ExpectSuccess(); + + std::vector attachments; + + { + VkAttachmentDescription att = {}; + att.format = VK_FORMAT_R8G8B8A8_UNORM; + att.samples = VK_SAMPLE_COUNT_1_BIT; + att.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + att.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + att.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + att.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + attachments.push_back(att); + + att.format = VK_FORMAT_D16_UNORM; + att.samples = VK_SAMPLE_COUNT_4_BIT; + att.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + att.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; + att.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + att.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + + attachments.push_back(att); + } + + VkAttachmentReference color_ref = {}; + color_ref.attachment = 0; + color_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + VkAttachmentReference depth_ref = {}; + depth_ref.attachment = 1; + depth_ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + + VkSubpassDescription subpass = {}; + subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + subpass.colorAttachmentCount = 1; + subpass.pColorAttachments = &color_ref; + subpass.pDepthStencilAttachment = &depth_ref; + + VkRenderPassCreateInfo rp_info = {}; + rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + rp_info.attachmentCount = attachments.size(); + rp_info.pAttachments = attachments.data(); + rp_info.subpassCount = 1; + rp_info.pSubpasses = &subpass; + + vkCreateRenderPass(device(), &rp_info, NULL, &m_renderPass); + m_errorMonitor->VerifyNotFound(); + + // Expect an error message for invalid sample counts + + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSubpassDescription-pColorAttachments-01506"); + + attachments[0].samples = VK_SAMPLE_COUNT_4_BIT; + attachments[1].samples = VK_SAMPLE_COUNT_1_BIT; + + { + VkRenderPass render_pass; + VkResult err = vkCreateRenderPass(device(), &rp_info, NULL, &render_pass); + m_errorMonitor->VerifyFound(); + ASSERT_NE(err, VK_SUCCESS); + } +} + TEST_F(VkLayerTest, AMDMixedAttachmentSamplesValidateGraphicsPipeline) { TEST_DESCRIPTION("Verify an error message for an incorrect graphics pipeline rasterization sample count."); From 27695322d61603c30da8f4d5c00bef8ab21201d0 Mon Sep 17 00:00:00 2001 From: John Zulauf <32470354+jzulauf-lunarg@users.noreply.github.com> Date: Fri, 26 Oct 2018 16:10:00 -0600 Subject: [PATCH 2/3] Revert "layers: Added parameter validation for CRP2" This reverts commit d942eb9df5a22b9482c91f42041773f0b370e258. --- layers/parameter_validation_utils.cpp | 107 +++++----------------- scripts/parameter_validation_generator.py | 1 - 2 files changed, 24 insertions(+), 84 deletions(-) diff --git a/layers/parameter_validation_utils.cpp b/layers/parameter_validation_utils.cpp index 2bb54006567..29cc315739d 100644 --- a/layers/parameter_validation_utils.cpp +++ b/layers/parameter_validation_utils.cpp @@ -88,8 +88,6 @@ extern bool parameter_validation_vkCreateCommandPool(VkDevice device, const VkCo const VkAllocationCallbacks *pAllocator, VkCommandPool *pCommandPool); extern bool parameter_validation_vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass); -extern bool parameter_validation_vkCreateRenderPass2KHR(VkDevice device, const VkRenderPassCreateInfo2KHR *pCreateInfo, - const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass); extern bool parameter_validation_vkDestroyRenderPass(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks *pAllocator); @@ -119,8 +117,6 @@ static const VkLayerProperties global_layer = { "LunarG Validation Layer", }; -enum RenderPassCreateVersion { RENDER_PASS_VERSION_1 = 0, RENDER_PASS_VERSION_2 = 1 }; - static const int MaxParamCheckerStringLength = 256; template @@ -761,25 +757,6 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateQueryPool(VkDevice device, const VkQueryP return result; } -template -static void RecordRenderPass(layer_data *device_data, VkRenderPass renderPass, const T *pCreateInfo) { - auto &renderpass_state = device_data->renderpasses_states[renderPass]; - - for (uint32_t subpass = 0; subpass < pCreateInfo->subpassCount; ++subpass) { - bool uses_color = false; - for (uint32_t i = 0; i < pCreateInfo->pSubpasses[subpass].colorAttachmentCount && !uses_color; ++i) - if (pCreateInfo->pSubpasses[subpass].pColorAttachments[i].attachment != VK_ATTACHMENT_UNUSED) uses_color = true; - - bool uses_depthstencil = false; - if (pCreateInfo->pSubpasses[subpass].pDepthStencilAttachment) - if (pCreateInfo->pSubpasses[subpass].pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) - uses_depthstencil = true; - - if (uses_color) renderpass_state.subpasses_using_color_attachment.insert(subpass); - if (uses_depthstencil) renderpass_state.subpasses_using_depthstencil_attachment.insert(subpass); - } -} - VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) { layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); @@ -804,38 +781,22 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass(VkDevice device, const VkRende // track the state necessary for checking vkCreateGraphicsPipeline (subpass usage of depth and color attachments) if (result == VK_SUCCESS) { std::unique_lock lock(global_lock); - RecordRenderPass(device_data, *pRenderPass, pCreateInfo); - } - } - return result; -} - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass2KHR(VkDevice device, const VkRenderPassCreateInfo2KHR *pCreateInfo, - const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) { - layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); - bool skip = false; - VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; - - { - std::unique_lock lock(global_lock); - skip |= parameter_validation_vkCreateRenderPass2KHR(device, pCreateInfo, pAllocator, pRenderPass); + const auto renderPass = *pRenderPass; + auto &renderpass_state = device_data->renderpasses_states[renderPass]; - typedef bool (*PFN_manual_vkCreateRenderPass2KHR)(VkDevice device, const VkRenderPassCreateInfo2KHR *pCreateInfo, - const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass); - PFN_manual_vkCreateRenderPass2KHR custom_func = - (PFN_manual_vkCreateRenderPass2KHR)custom_functions["vkCreateRenderPass2KHR"]; - if (custom_func != nullptr) { - skip |= custom_func(device, pCreateInfo, pAllocator, pRenderPass); - } - } + for (uint32_t subpass = 0; subpass < pCreateInfo->subpassCount; ++subpass) { + bool uses_color = false; + for (uint32_t i = 0; i < pCreateInfo->pSubpasses[subpass].colorAttachmentCount && !uses_color; ++i) + if (pCreateInfo->pSubpasses[subpass].pColorAttachments[i].attachment != VK_ATTACHMENT_UNUSED) uses_color = true; - if (!skip) { - result = device_data->dispatch_table.CreateRenderPass2KHR(device, pCreateInfo, pAllocator, pRenderPass); + bool uses_depthstencil = false; + if (pCreateInfo->pSubpasses[subpass].pDepthStencilAttachment) + if (pCreateInfo->pSubpasses[subpass].pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) + uses_depthstencil = true; - // track the state necessary for checking vkCreateGraphicsPipeline (subpass usage of depth and color attachments) - if (result == VK_SUCCESS) { - std::unique_lock lock(global_lock); - RecordRenderPass(device_data, *pRenderPass, pCreateInfo); + if (uses_color) renderpass_state.subpasses_using_color_attachment.insert(subpass); + if (uses_depthstencil) renderpass_state.subpasses_using_depthstencil_attachment.insert(subpass); + } } } return result; @@ -2672,59 +2633,40 @@ bool pv_vkUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount, c return skip; } -template -bool pv_CreateRenderPassGeneric(VkDevice device, const RenderPassCreateInfoGeneric *pCreateInfo, - const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass, - RenderPassCreateVersion rp_version) { +bool pv_vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, + VkRenderPass *pRenderPass) { bool skip = false; layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); uint32_t max_color_attachments = device_data->device_limits.maxColorAttachments; - bool use_rp2 = (rp_version == RENDER_PASS_VERSION_2); - const char *vuid; for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) { if (pCreateInfo->pAttachments[i].format == VK_FORMAT_UNDEFINED) { std::stringstream ss; - ss << (use_rp2 ? "vkCreateRenderPass2KHR" : "vkCreateRenderPass") << ": pCreateInfo->pAttachments[" << i - << "].format is VK_FORMAT_UNDEFINED. "; - vuid = use_rp2 ? "VUID-VkAttachmentDescription2KHR-format-parameter" : "VUID-VkAttachmentDescription-format-parameter"; + ss << "vkCreateRenderPass: pCreateInfo->pAttachments[" << i << "].format is VK_FORMAT_UNDEFINED. "; skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, - vuid, "%s", ss.str().c_str()); + "VUID-VkAttachmentDescription-format-parameter", "%s", ss.str().c_str()); } if (pCreateInfo->pAttachments[i].finalLayout == VK_IMAGE_LAYOUT_UNDEFINED || pCreateInfo->pAttachments[i].finalLayout == VK_IMAGE_LAYOUT_PREINITIALIZED) { - vuid = - use_rp2 ? "VUID-VkAttachmentDescription2KHR-finalLayout-03061" : "VUID-VkAttachmentDescription-finalLayout-00843"; - skip |= - log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, - "pCreateInfo->pAttachments[%d].finalLayout must not be VK_IMAGE_LAYOUT_UNDEFINED or " - "VK_IMAGE_LAYOUT_PREINITIALIZED.", - i); + skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, + "VUID-VkAttachmentDescription-finalLayout-00843", + "pCreateInfo->pAttachments[%d].finalLayout must not be VK_IMAGE_LAYOUT_UNDEFINED or " + "VK_IMAGE_LAYOUT_PREINITIALIZED.", + i); } } for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { if (pCreateInfo->pSubpasses[i].colorAttachmentCount > max_color_attachments) { - vuid = use_rp2 ? "VUID-VkSubpassDescription2KHR-colorAttachmentCount-03063" - : "VUID-VkSubpassDescription-colorAttachmentCount-00845"; skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, - vuid, "Cannot create a render pass with %d color attachments. Max is %d.", + "VUID-VkSubpassDescription-colorAttachmentCount-00845", + "Cannot create a render pass with %d color attachments. Max is %d.", pCreateInfo->pSubpasses[i].colorAttachmentCount, max_color_attachments); } } return skip; } -bool pv_vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, - VkRenderPass *pRenderPass) { - return pv_CreateRenderPassGeneric(device, pCreateInfo, pAllocator, pRenderPass, RENDER_PASS_VERSION_1); -} - -bool pv_vkCreateRenderPass2KHR(VkDevice device, const VkRenderPassCreateInfo2KHR *pCreateInfo, - const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) { - return pv_CreateRenderPassGeneric(device, pCreateInfo, pAllocator, pRenderPass, RENDER_PASS_VERSION_2); -} - bool pv_vkFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers) { bool skip = false; @@ -3655,7 +3597,6 @@ void InitializeManualParameterValidationFunctionPointers() { custom_functions["vkFreeDescriptorSets"] = (void *)pv_vkFreeDescriptorSets; custom_functions["vkUpdateDescriptorSets"] = (void *)pv_vkUpdateDescriptorSets; custom_functions["vkCreateRenderPass"] = (void *)pv_vkCreateRenderPass; - custom_functions["vkCreateRenderPass2KHR"] = (void *)pv_vkCreateRenderPass2KHR; custom_functions["vkBeginCommandBuffer"] = (void *)pv_vkBeginCommandBuffer; custom_functions["vkCmdSetViewport"] = (void *)pv_vkCmdSetViewport; custom_functions["vkCmdSetScissor"] = (void *)pv_vkCmdSetScissor; diff --git a/scripts/parameter_validation_generator.py b/scripts/parameter_validation_generator.py index ad3b36fd3ab..3262050067a 100644 --- a/scripts/parameter_validation_generator.py +++ b/scripts/parameter_validation_generator.py @@ -146,7 +146,6 @@ def __init__(self, 'vkDestroyDebugReportCallbackEXT', 'vkCreateCommandPool', 'vkCreateRenderPass', - 'vkCreateRenderPass2KHR', 'vkDestroyRenderPass', 'vkCreateDebugUtilsMessengerEXT', 'vkDestroyDebugUtilsMessengerEXT', From df5318d44802e4c0ab2ed65b753b1aa59b08d1f7 Mon Sep 17 00:00:00 2001 From: John Zulauf <32470354+jzulauf-lunarg@users.noreply.github.com> Date: Fri, 26 Oct 2018 16:10:00 -0600 Subject: [PATCH 3/3] Revert "layers: Audited renderpass validation, added CRP2" This reverts commit bbb122821b14d61c416b70c2d5fc6b50b8c782d9. --- build-android/cmake/layerlib/CMakeLists.txt | 1 - build-android/jni/Android.mk | 1 - layers/CMakeLists.txt | 2 +- layers/buffer_validation.cpp | 300 +------ layers/buffer_validation.h | 17 +- layers/convert_to_renderpass2.cpp | 202 ----- layers/convert_to_renderpass2.h | 24 - layers/core_validation.cpp | 906 ++++---------------- layers/core_validation_types.h | 11 +- tests/layer_validation_tests.cpp | 32 +- 10 files changed, 245 insertions(+), 1251 deletions(-) delete mode 100644 layers/convert_to_renderpass2.cpp delete mode 100644 layers/convert_to_renderpass2.h diff --git a/build-android/cmake/layerlib/CMakeLists.txt b/build-android/cmake/layerlib/CMakeLists.txt index 69754b8ed41..e9abd5c8aa1 100644 --- a/build-android/cmake/layerlib/CMakeLists.txt +++ b/build-android/cmake/layerlib/CMakeLists.txt @@ -62,7 +62,6 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVK_USE_PLATFORM_ANDROID_KHR \ -fvisibility=hidden") add_library(VkLayer_core_validation SHARED ${SRC_DIR}/layers/core_validation.cpp - ${SRC_DIR}/layers/convert_to_renderpass2.cpp ${SRC_DIR}/layers/descriptor_sets.cpp ${SRC_DIR}/layers/buffer_validation.cpp ${SRC_DIR}/layers/shader_validation.cpp diff --git a/build-android/jni/Android.mk b/build-android/jni/Android.mk index 39f04642a1e..ebec08bd44a 100644 --- a/build-android/jni/Android.mk +++ b/build-android/jni/Android.mk @@ -39,7 +39,6 @@ LOCAL_SRC_FILES += $(SRC_DIR)/layers/core_validation.cpp LOCAL_SRC_FILES += $(SRC_DIR)/layers/descriptor_sets.cpp LOCAL_SRC_FILES += $(SRC_DIR)/layers/buffer_validation.cpp LOCAL_SRC_FILES += $(SRC_DIR)/layers/shader_validation.cpp -LOCAL_SRC_FILES += $(SRC_DIR)/layers/convert_to_renderpass2.cpp LOCAL_SRC_FILES += $(SRC_DIR)/layers/xxhash.c LOCAL_C_INCLUDES += $(VULKAN_INCLUDE) \ $(LOCAL_PATH)/$(SRC_DIR)/layers \ diff --git a/layers/CMakeLists.txt b/layers/CMakeLists.txt index 5fd5b44bdaf..ebba94f443f 100644 --- a/layers/CMakeLists.txt +++ b/layers/CMakeLists.txt @@ -178,7 +178,7 @@ GenerateFromVkXml(dispatch_table_helper_generator.py vk_dispatch_table_helper.h) GenerateFromVkXml(object_tracker_generator.py object_tracker.cpp) if(BUILD_LAYERS) - AddVkLayer(core_validation core_validation.cpp convert_to_renderpass2.cpp descriptor_sets.cpp buffer_validation.cpp shader_validation.cpp xxhash.c) + AddVkLayer(core_validation core_validation.cpp descriptor_sets.cpp buffer_validation.cpp shader_validation.cpp xxhash.c) AddVkLayer(object_tracker object_tracker.cpp object_tracker_utils.cpp) AddVkLayer(threading threading.cpp thread_check.h) AddVkLayer(unique_objects unique_objects.cpp unique_objects_wrappers.h) diff --git a/layers/buffer_validation.cpp b/layers/buffer_validation.cpp index bb7edf796e5..d48a0db632e 100644 --- a/layers/buffer_validation.cpp +++ b/layers/buffer_validation.cpp @@ -319,116 +319,13 @@ void SetImageViewLayout(layer_data *device_data, GLOBAL_CB_NODE *cb_node, VkImag SetImageViewLayout(device_data, cb_node, view_state, layout); } -bool ValidateRenderPassLayoutAgainstFramebufferImageUsage(layer_data *device_data, RenderPassCreateVersion rp_version, - VkImageLayout layout, VkImage image, VkImageView image_view, - VkFramebuffer framebuffer, VkRenderPass renderpass, - uint32_t attachment_index, const char *variable_name) { - bool skip = false; - const auto report_data = core_validation::GetReportData(device_data); - auto image_state = GetImageState(device_data, image); - const char *vuid; - const bool use_rp2 = (rp_version == RENDER_PASS_VERSION_2); - - if (!image_state) { - skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, HandleToUint64(image), - "VUID-VkRenderPassBeginInfo-framebuffer-parameter", - "Render Pass begin with renderpass 0x%" PRIx64 " uses framebuffer 0x%" PRIx64 " where pAttachments[%" PRIu32 - "] = image view 0x%" PRIx64 ", which refers to an invalid image", - HandleToUint64(renderpass), HandleToUint64(framebuffer), attachment_index, HandleToUint64(image_view)); - return skip; - } - - auto image_usage = image_state->createInfo.usage; - - // Check for layouts that mismatch image usages in the framebuffer - if (layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL && !(image_usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)) { - vuid = use_rp2 ? "VUID-vkCmdBeginRenderPass2KHR-initialLayout-03094" : "VUID-vkCmdBeginRenderPass-initialLayout-00895"; - skip |= - log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, HandleToUint64(image), vuid, - "Layout/usage mismatch for attachment %u in render pass 0x%" PRIx64 - " - the %s is %s but the image attached to framebuffer 0x%" PRIx64 " via image view 0x%" PRIx64 - " was not created with VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT", - attachment_index, HandleToUint64(framebuffer), variable_name, string_VkImageLayout(layout), - HandleToUint64(renderpass), HandleToUint64(image_view)); - } - - if (layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL && - !(image_usage & (VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT))) { - vuid = use_rp2 ? "VUID-vkCmdBeginRenderPass2KHR-initialLayout-03097" : "VUID-vkCmdBeginRenderPass-initialLayout-00897"; - skip |= - log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, HandleToUint64(image), vuid, - "Layout/usage mismatch for attachment %u in render pass 0x%" PRIx64 - " - the %s is %s but the image attached to framebuffer 0x%" PRIx64 " via image view 0x%" PRIx64 - " was not created with VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT or VK_IMAGE_USAGE_SAMPLED_BIT", - attachment_index, HandleToUint64(framebuffer), variable_name, string_VkImageLayout(layout), - HandleToUint64(renderpass), HandleToUint64(image_view)); - } - - if (layout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL && !(image_usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT)) { - vuid = use_rp2 ? "VUID-vkCmdBeginRenderPass2KHR-initialLayout-03098" : "VUID-vkCmdBeginRenderPass-initialLayout-00898"; - skip |= - log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, HandleToUint64(image), vuid, - "Layout/usage mismatch for attachment %u in render pass 0x%" PRIx64 - " - the %s is %s but the image attached to framebuffer 0x%" PRIx64 " via image view 0x%" PRIx64 - " was not created with VK_IMAGE_USAGE_TRANSFER_SRC_BIT", - attachment_index, HandleToUint64(framebuffer), variable_name, string_VkImageLayout(layout), - HandleToUint64(renderpass), HandleToUint64(image_view)); - } - - if (layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && !(image_usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT)) { - vuid = use_rp2 ? "VUID-vkCmdBeginRenderPass2KHR-initialLayout-03099" : "VUID-vkCmdBeginRenderPass-initialLayout-00899"; - skip |= - log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, HandleToUint64(image), vuid, - "Layout/usage mismatch for attachment %u in render pass 0x%" PRIx64 - " - the %s is %s but the image attached to framebuffer 0x%" PRIx64 " via image view 0x%" PRIx64 - " was not created with VK_IMAGE_USAGE_TRANSFER_DST_BIT", - attachment_index, HandleToUint64(framebuffer), variable_name, string_VkImageLayout(layout), - HandleToUint64(renderpass), HandleToUint64(image_view)); - } - - if (GetDeviceExtensions(device_data)->vk_khr_maintenance2) { - if ((layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL || - layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL || - layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL || - layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL) && - !(image_usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) { - vuid = use_rp2 ? "VUID-vkCmdBeginRenderPass2KHR-initialLayout-03096" : "VUID-vkCmdBeginRenderPass-initialLayout-01758"; - skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, - HandleToUint64(image), vuid, - "Layout/usage mismatch for attachment %u in render pass 0x%" PRIx64 - " - the %s is %s but the image attached to framebuffer 0x%" PRIx64 " via image view 0x%" PRIx64 - " was not created with VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT", - attachment_index, HandleToUint64(framebuffer), variable_name, string_VkImageLayout(layout), - HandleToUint64(renderpass), HandleToUint64(image_view)); - } - } else { - // The create render pass 2 extension requires maintenance 2 (the previous branch), so no vuid switch needed here. - if ((layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL || - layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL) && - !(image_usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) { - skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, - HandleToUint64(image), "VUID-vkCmdBeginRenderPass-initialLayout-00896", - "Layout/usage mismatch for attachment %u in render pass 0x%" PRIx64 - " - the %s is %s but the image attached to framebuffer 0x%" PRIx64 " via image view 0x%" PRIx64 - " was not created with VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT", - attachment_index, HandleToUint64(framebuffer), variable_name, string_VkImageLayout(layout), - HandleToUint64(renderpass), HandleToUint64(image_view)); - } - } - return skip; -} - -bool VerifyFramebufferAndRenderPassLayouts(layer_data *device_data, RenderPassCreateVersion rp_version, GLOBAL_CB_NODE *pCB, +bool VerifyFramebufferAndRenderPassLayouts(layer_data *device_data, GLOBAL_CB_NODE *pCB, const VkRenderPassBeginInfo *pRenderPassBegin, const FRAMEBUFFER_STATE *framebuffer_state) { bool skip = false; auto const pRenderPassInfo = GetRenderPassState(device_data, pRenderPassBegin->renderPass)->createInfo.ptr(); auto const &framebufferInfo = framebuffer_state->createInfo; const auto report_data = core_validation::GetReportData(device_data); - - auto render_pass = GetRenderPassState(device_data, pRenderPassBegin->renderPass)->renderPass; - auto framebuffer = framebuffer_state->framebuffer; - if (pRenderPassInfo->attachmentCount != framebufferInfo.attachmentCount) { skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, HandleToUint64(pCB->commandBuffer), kVUID_Core_DrawState_InvalidRenderpass, @@ -450,8 +347,6 @@ bool VerifyFramebufferAndRenderPassLayouts(layer_data *device_data, RenderPassCr const VkImage &image = view_state->create_info.image; const VkImageSubresourceRange &subRange = view_state->create_info.subresourceRange; auto initial_layout = pRenderPassInfo->pAttachments[i].initialLayout; - auto final_layout = pRenderPassInfo->pAttachments[i].finalLayout; - // TODO: Do not iterate over every possibility - consolidate where possible for (uint32_t j = 0; j < subRange.levelCount; j++) { uint32_t level = subRange.baseMipLevel + j; @@ -473,71 +368,12 @@ bool VerifyFramebufferAndRenderPassLayouts(layer_data *device_data, RenderPassCr } } } - - ValidateRenderPassLayoutAgainstFramebufferImageUsage(device_data, rp_version, initial_layout, image, image_view, - framebuffer, render_pass, i, "initial layout"); - - ValidateRenderPassLayoutAgainstFramebufferImageUsage(device_data, rp_version, final_layout, image, image_view, framebuffer, - render_pass, i, "final layout"); - } - - for (uint32_t j = 0; j < pRenderPassInfo->subpassCount; ++j) { - auto &subpass = pRenderPassInfo->pSubpasses[j]; - for (uint32_t k = 0; k < pRenderPassInfo->pSubpasses[j].inputAttachmentCount; ++k) { - auto &attachment_ref = subpass.pInputAttachments[k]; - if (attachment_ref.attachment != VK_ATTACHMENT_UNUSED) { - auto image_view = framebufferInfo.pAttachments[attachment_ref.attachment]; - auto view_state = GetImageViewState(device_data, image_view); - - if (view_state) { - auto image = view_state->create_info.image; - ValidateRenderPassLayoutAgainstFramebufferImageUsage(device_data, rp_version, attachment_ref.layout, image, - image_view, framebuffer, render_pass, - attachment_ref.attachment, "input attachment layout"); - } - } - } - - for (uint32_t k = 0; k < pRenderPassInfo->pSubpasses[j].colorAttachmentCount; ++k) { - auto &attachment_ref = subpass.pColorAttachments[k]; - if (attachment_ref.attachment != VK_ATTACHMENT_UNUSED) { - auto image_view = framebufferInfo.pAttachments[attachment_ref.attachment]; - auto view_state = GetImageViewState(device_data, image_view); - - if (view_state) { - auto image = view_state->create_info.image; - ValidateRenderPassLayoutAgainstFramebufferImageUsage(device_data, rp_version, attachment_ref.layout, image, - image_view, framebuffer, render_pass, - attachment_ref.attachment, "color attachment layout"); - if (subpass.pResolveAttachments) { - ValidateRenderPassLayoutAgainstFramebufferImageUsage( - device_data, rp_version, attachment_ref.layout, image, image_view, framebuffer, render_pass, - attachment_ref.attachment, "resolve attachment layout"); - } - } - } - } - - if (pRenderPassInfo->pSubpasses[j].pDepthStencilAttachment) { - auto &attachment_ref = *subpass.pDepthStencilAttachment; - if (attachment_ref.attachment != VK_ATTACHMENT_UNUSED) { - auto image_view = framebufferInfo.pAttachments[attachment_ref.attachment]; - auto view_state = GetImageViewState(device_data, image_view); - - if (view_state) { - auto image = view_state->create_info.image; - ValidateRenderPassLayoutAgainstFramebufferImageUsage(device_data, rp_version, attachment_ref.layout, image, - image_view, framebuffer, render_pass, - attachment_ref.attachment, "input attachment layout"); - } - } - } } return skip; } void TransitionAttachmentRefLayout(layer_data *device_data, GLOBAL_CB_NODE *pCB, FRAMEBUFFER_STATE *pFramebuffer, - const safe_VkAttachmentReference2KHR &ref) { + VkAttachmentReference ref) { if (ref.attachment != VK_ATTACHMENT_UNUSED) { auto image_view = GetAttachmentImageViewState(device_data, pFramebuffer, ref.attachment); if (image_view) { @@ -1155,7 +991,7 @@ void TransitionFinalSubpassLayouts(layer_data *device_data, GLOBAL_CB_NODE *pCB, auto renderPass = GetRenderPassState(device_data, pRenderPassBegin->renderPass); if (!renderPass) return; - const VkRenderPassCreateInfo2KHR *pRenderPassInfo = renderPass->createInfo.ptr(); + const VkRenderPassCreateInfo *pRenderPassInfo = renderPass->createInfo.ptr(); if (framebuffer_state) { for (uint32_t i = 0; i < pRenderPassInfo->attachmentCount; ++i) { auto view_state = GetAttachmentImageViewState(device_data, framebuffer_state, i); @@ -2525,8 +2361,8 @@ bool PreCallValidateCmdClearAttachments(layer_data *device_data, VkCommandBuffer // Validate that attachment is in reference list of active subpass if (cb_node->activeRenderPass) { - const VkRenderPassCreateInfo2KHR *renderpass_create_info = cb_node->activeRenderPass->createInfo.ptr(); - const VkSubpassDescription2KHR *subpass_desc = &renderpass_create_info->pSubpasses[cb_node->activeSubpass]; + const VkRenderPassCreateInfo *renderpass_create_info = cb_node->activeRenderPass->createInfo.ptr(); + const VkSubpassDescription *subpass_desc = &renderpass_create_info->pSubpasses[cb_node->activeSubpass]; auto framebuffer = GetFramebufferState(device_data, cb_node->activeFramebuffer); for (uint32_t i = 0; i < attachmentCount; i++) { @@ -3176,51 +3012,42 @@ static bool ValidateMaskBits(core_validation::layer_data *device_data, VkCommand // 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, RenderPassCreateVersion rp_version, - const VkImageLayout first_layout, const uint32_t attachment, - const VkAttachmentDescription2KHR &attachment_description) { +bool ValidateLayoutVsAttachmentDescription(const debug_report_data *report_data, const VkImageLayout first_layout, + const uint32_t attachment, const VkAttachmentDescription &attachment_description) { bool skip = false; - const char *vuid; - const bool use_rp2 = (rp_version == RENDER_PASS_VERSION_2); - // 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)) { - vuid = - use_rp2 ? "VUID-VkRenderPassCreateInfo2KHR-pAttachments-03053" : "VUID-VkRenderPassCreateInfo-pAttachments-00836"; skip |= - log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, + log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, + "VUID-VkRenderPassCreateInfo-pAttachments-00836", "Cannot clear attachment %d with invalid first layout %s.", attachment, string_VkImageLayout(first_layout)); } } if (attachment_description.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) { if (first_layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL) { - vuid = use_rp2 ? kVUID_Core_DrawState_InvalidRenderpass : "VUID-VkRenderPassCreateInfo-pAttachments-01566"; skip |= - log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, + log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, + "VUID-VkRenderPassCreateInfo-pAttachments-01566", "Cannot clear attachment %d with invalid first layout %s.", attachment, string_VkImageLayout(first_layout)); } } if (attachment_description.stencilLoadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) { if (first_layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL) { - vuid = use_rp2 ? kVUID_Core_DrawState_InvalidRenderpass : "VUID-VkRenderPassCreateInfo-pAttachments-01567"; skip |= - log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, + log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, + "VUID-VkRenderPassCreateInfo-pAttachments-01567", "Cannot clear attachment %d with invalid first layout %s.", attachment, string_VkImageLayout(first_layout)); } } return skip; } -bool ValidateLayouts(const core_validation::layer_data *device_data, RenderPassCreateVersion rp_version, VkDevice device, - const VkRenderPassCreateInfo2KHR *pCreateInfo) { +bool ValidateLayouts(const core_validation::layer_data *device_data, VkDevice device, const VkRenderPassCreateInfo *pCreateInfo) { const debug_report_data *report_data = core_validation::GetReportData(device_data); bool skip = false; - const char *vuid; - const bool use_rp2 = (rp_version == RENDER_PASS_VERSION_2); - const char *const function_name = use_rp2 ? "vkCreateRenderPass2KHR()" : "vkCreateRenderPass()"; for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) { VkFormat format = pCreateInfo->pAttachments[i].format; @@ -3248,12 +3075,13 @@ bool ValidateLayouts(const core_validation::layer_data *device_data, RenderPassC // Track when we're observing the first use of an attachment std::vector attach_first_use(pCreateInfo->attachmentCount, true); for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { - const VkSubpassDescription2KHR &subpass = pCreateInfo->pSubpasses[i]; + const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[i]; // Check input attachments first, so we can detect first-use-as-input for VU #00349 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: @@ -3267,15 +3095,6 @@ bool ValidateLayouts(const core_validation::layer_data *device_data, RenderPassC "Layout for input attachment is GENERAL but should be READ_ONLY_OPTIMAL."); break; - case VK_IMAGE_LAYOUT_UNDEFINED: - case VK_IMAGE_LAYOUT_PREINITIALIZED: - vuid = use_rp2 ? "VUID-VkAttachmentReference2KHR-layout-03077" : "VUID-VkAttachmentReference-layout-00857"; - skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, - "Layout for input attachment reference %u in subpass %u is %s but must be " - "DEPTH_STENCIL_READ_ONLY, SHADER_READ_ONLY_OPTIMAL, or GENERAL.", - j, i, string_VkImageLayout(subpass.pDepthStencilAttachment->layout)); - break; - case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR: case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR: if (GetDeviceExtensions(device_data)->vk_khr_maintenance2) { @@ -3284,7 +3103,6 @@ bool ValidateLayouts(const core_validation::layer_data *device_data, RenderPassC // Intentionally fall through to generic error message } // fall through - 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, @@ -3294,8 +3112,8 @@ bool ValidateLayouts(const core_validation::layer_data *device_data, RenderPassC } if (attach_first_use[attach_index]) { - skip |= ValidateLayoutVsAttachmentDescription(report_data, rp_version, subpass.pInputAttachments[j].layout, - attach_index, pCreateInfo->pAttachments[attach_index]); + skip |= ValidateLayoutVsAttachmentDescription(report_data, subpass.pInputAttachments[j].layout, attach_index, + pCreateInfo->pAttachments[attach_index]); bool used_as_depth = (subpass.pDepthStencilAttachment != NULL && subpass.pDepthStencilAttachment->attachment == attach_index); @@ -3305,15 +3123,15 @@ bool ValidateLayouts(const core_validation::layer_data *device_data, RenderPassC } if (!used_as_depth && !used_as_color && pCreateInfo->pAttachments[attach_index].loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) { - vuid = use_rp2 ? "VUID-VkSubpassDescription2KHR-loadOp-03064" : "VUID-VkSubpassDescription-loadOp-00846"; - skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, - "%s: attachment %u is first used as an input attachment in subpass %u with loadOp=CLEAR.", - function_name, attach_index, attach_index); + skip |= log_msg( + report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, + "VUID-VkSubpassDescription-loadOp-00846", + "CreateRenderPass: attachment %u is first used as an input attachment in subpass %u with loadOp=CLEAR.", + attach_index, attach_index); } } attach_first_use[attach_index] = false; } - for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) { auto attach_index = subpass.pColorAttachments[j].attachment; if (attach_index == VK_ATTACHMENT_UNUSED) continue; @@ -3335,15 +3153,6 @@ bool ValidateLayouts(const core_validation::layer_data *device_data, RenderPassC "Layout for color attachment is GENERAL but should be COLOR_ATTACHMENT_OPTIMAL."); break; - case VK_IMAGE_LAYOUT_UNDEFINED: - case VK_IMAGE_LAYOUT_PREINITIALIZED: - vuid = use_rp2 ? "VUID-VkAttachmentReference2KHR-layout-03077" : "VUID-VkAttachmentReference-layout-00857"; - skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, - "Layout for color attachment reference %u in subpass %u is %s but should be " - "COLOR_ATTACHMENT_OPTIMAL or GENERAL.", - j, i, string_VkImageLayout(subpass.pColorAttachments[j].layout)); - break; - default: skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, kVUID_Core_DrawState_InvalidImageLayout, @@ -3351,18 +3160,9 @@ bool ValidateLayouts(const core_validation::layer_data *device_data, RenderPassC string_VkImageLayout(subpass.pColorAttachments[j].layout)); } - if (subpass.pResolveAttachments && (subpass.pResolveAttachments[j].layout == VK_IMAGE_LAYOUT_UNDEFINED || - subpass.pResolveAttachments[j].layout == VK_IMAGE_LAYOUT_PREINITIALIZED)) { - vuid = use_rp2 ? "VUID-VkAttachmentReference2KHR-layout-03077" : "VUID-VkAttachmentReference-layout-00857"; - skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, - "Layout for color attachment reference %u in subpass %u is %s but should be " - "COLOR_ATTACHMENT_OPTIMAL or GENERAL.", - j, i, string_VkImageLayout(subpass.pColorAttachments[j].layout)); - } - if (attach_first_use[attach_index]) { - skip |= ValidateLayoutVsAttachmentDescription(report_data, rp_version, subpass.pColorAttachments[j].layout, - attach_index, pCreateInfo->pAttachments[attach_index]); + skip |= ValidateLayoutVsAttachmentDescription(report_data, subpass.pColorAttachments[j].layout, attach_index, + pCreateInfo->pAttachments[attach_index]); } attach_first_use[attach_index] = false; } @@ -3382,15 +3182,6 @@ bool ValidateLayouts(const core_validation::layer_data *device_data, RenderPassC "GENERAL layout for depth attachment may not give optimal performance."); break; - case VK_IMAGE_LAYOUT_UNDEFINED: - case VK_IMAGE_LAYOUT_PREINITIALIZED: - vuid = use_rp2 ? "VUID-VkAttachmentReference2KHR-layout-03077" : "VUID-VkAttachmentReference-layout-00857"; - skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, - "Layout for depth attachment reference in subpass %u is %s but must be a valid depth/stencil " - "layout or GENERAL.", - i, string_VkImageLayout(subpass.pDepthStencilAttachment->layout)); - break; - case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR: case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR: if (GetDeviceExtensions(device_data)->vk_khr_maintenance2) { @@ -3399,7 +3190,6 @@ bool ValidateLayouts(const core_validation::layer_data *device_data, RenderPassC // Intentionally fall through to generic error message } // fall through - 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, @@ -3411,8 +3201,8 @@ bool ValidateLayouts(const core_validation::layer_data *device_data, RenderPassC auto attach_index = subpass.pDepthStencilAttachment->attachment; if (attach_first_use[attach_index]) { - skip |= ValidateLayoutVsAttachmentDescription(report_data, rp_version, subpass.pDepthStencilAttachment->layout, - attach_index, pCreateInfo->pAttachments[attach_index]); + skip |= ValidateLayoutVsAttachmentDescription(report_data, subpass.pDepthStencilAttachment->layout, attach_index, + pCreateInfo->pAttachments[attach_index]); } attach_first_use[attach_index] = false; } @@ -3706,49 +3496,52 @@ void PostCallRecordCreateBufferView(layer_data *device_data, const VkBufferViewC } // For the given format verify that the aspect masks make sense -bool ValidateImageAspectMask(const layer_data *device_data, VkImage image, VkFormat format, VkImageAspectFlags aspect_mask, - const char *func_name, const char *vuid) { +bool ValidateImageAspectMask(layer_data *device_data, VkImage image, VkFormat format, VkImageAspectFlags aspect_mask, + const char *func_name) { const debug_report_data *report_data = core_validation::GetReportData(device_data); bool skip = false; - VkDebugReportObjectTypeEXT objectType = VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT; - if (image != VK_NULL_HANDLE) { - objectType = VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT; - } - if (FormatIsColor(format)) { if ((aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT) != VK_IMAGE_ASPECT_COLOR_BIT) { - skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, objectType, HandleToUint64(image), vuid, + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, + HandleToUint64(image), "VUID-VkImageSubresource-aspectMask-parameter", "%s: Color image formats must have the VK_IMAGE_ASPECT_COLOR_BIT set.", func_name); } else if ((aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT) != aspect_mask) { - skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, objectType, HandleToUint64(image), vuid, + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, + HandleToUint64(image), "VUID-VkImageSubresource-aspectMask-parameter", "%s: Color image formats must have ONLY the VK_IMAGE_ASPECT_COLOR_BIT set.", func_name); } } else if (FormatIsDepthAndStencil(format)) { if ((aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) == 0) { - skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, objectType, HandleToUint64(image), vuid, + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, + HandleToUint64(image), "VUID-VkImageSubresource-aspectMask-parameter", "%s: Depth/stencil image formats must have at least one of VK_IMAGE_ASPECT_DEPTH_BIT and " "VK_IMAGE_ASPECT_STENCIL_BIT set.", func_name); } else if ((aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != aspect_mask) { - skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, objectType, HandleToUint64(image), vuid, + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, + HandleToUint64(image), "VUID-VkImageSubresource-aspectMask-parameter", "%s: Combination depth/stencil image formats can have only the VK_IMAGE_ASPECT_DEPTH_BIT and " "VK_IMAGE_ASPECT_STENCIL_BIT set.", func_name); } } else if (FormatIsDepthOnly(format)) { if ((aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) != VK_IMAGE_ASPECT_DEPTH_BIT) { - skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, objectType, HandleToUint64(image), vuid, + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, + HandleToUint64(image), "VUID-VkImageSubresource-aspectMask-parameter", "%s: Depth-only image formats must have the VK_IMAGE_ASPECT_DEPTH_BIT set.", func_name); } else if ((aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) != aspect_mask) { - skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, objectType, HandleToUint64(image), vuid, + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, + HandleToUint64(image), "VUID-VkImageSubresource-aspectMask-parameter", "%s: Depth-only image formats can have only the VK_IMAGE_ASPECT_DEPTH_BIT set.", func_name); } } else if (FormatIsStencilOnly(format)) { if ((aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) != VK_IMAGE_ASPECT_STENCIL_BIT) { - skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, objectType, HandleToUint64(image), vuid, + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, + HandleToUint64(image), "VUID-VkImageSubresource-aspectMask-parameter", "%s: Stencil-only image formats must have the VK_IMAGE_ASPECT_STENCIL_BIT set.", func_name); } else if ((aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) != aspect_mask) { - skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, objectType, HandleToUint64(image), vuid, + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, + HandleToUint64(image), "VUID-VkImageSubresource-aspectMask-parameter", "%s: Stencil-only image formats can have only the VK_IMAGE_ASPECT_STENCIL_BIT set.", func_name); } } else if (FormatIsMultiplane(format)) { @@ -3757,7 +3550,8 @@ bool ValidateImageAspectMask(const layer_data *device_data, VkImage image, VkFor valid_flags = valid_flags | VK_IMAGE_ASPECT_PLANE_2_BIT; } if ((aspect_mask & valid_flags) != aspect_mask) { - skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, objectType, HandleToUint64(image), vuid, + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, + HandleToUint64(image), "VUID-VkImageSubresource-aspectMask-parameter", "%s: Multi-plane image formats may have only VK_IMAGE_ASPECT_COLOR_BIT or VK_IMAGE_ASPECT_PLANE_n_BITs " "set, where n = [0, 1, 2].", func_name); diff --git a/layers/buffer_validation.h b/layers/buffer_validation.h index 98789789de2..7c46f78a7d9 100644 --- a/layers/buffer_validation.h +++ b/layers/buffer_validation.h @@ -102,12 +102,11 @@ void SetImageViewLayout(layer_data *device_data, GLOBAL_CB_NODE *pCB, VkImageVie void SetImageViewLayout(layer_data *device_data, GLOBAL_CB_NODE *cb_node, IMAGE_VIEW_STATE *view_state, const VkImageLayout &layout); -bool VerifyFramebufferAndRenderPassLayouts(layer_data *dev_data, RenderPassCreateVersion rp_version, GLOBAL_CB_NODE *pCB, - const VkRenderPassBeginInfo *pRenderPassBegin, +bool VerifyFramebufferAndRenderPassLayouts(layer_data *dev_data, GLOBAL_CB_NODE *pCB, const VkRenderPassBeginInfo *pRenderPassBegin, const FRAMEBUFFER_STATE *framebuffer_state); void TransitionAttachmentRefLayout(layer_data *dev_data, GLOBAL_CB_NODE *pCB, FRAMEBUFFER_STATE *pFramebuffer, - const safe_VkAttachmentReference2KHR &ref); + VkAttachmentReference ref); void TransitionSubpassLayouts(layer_data *, GLOBAL_CB_NODE *, const RENDER_PASS_STATE *, const int, FRAMEBUFFER_STATE *); @@ -183,12 +182,10 @@ void UpdateCmdBufImageLayouts(layer_data *device_data, GLOBAL_CB_NODE *pCB); 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, RenderPassCreateVersion rp_version, - const VkImageLayout first_layout, const uint32_t attachment, - const VkAttachmentDescription2KHR &attachment_description); +bool ValidateLayoutVsAttachmentDescription(const debug_report_data *report_data, const VkImageLayout first_layout, + const uint32_t attachment, const VkAttachmentDescription &attachment_description); -bool ValidateLayouts(const core_validation::layer_data *dev_data, RenderPassCreateVersion rp_version, VkDevice device, - const VkRenderPassCreateInfo2KHR *pCreateInfo); +bool ValidateLayouts(const core_validation::layer_data *dev_data, VkDevice device, const VkRenderPassCreateInfo *pCreateInfo); bool ValidateMapImageLayouts(core_validation::layer_data *dev_data, VkDevice device, DEVICE_MEM_INFO const *mem_info, VkDeviceSize offset, VkDeviceSize end_offset); @@ -214,8 +211,8 @@ bool PreCallValidateCreateBufferView(const layer_data *dev_data, const VkBufferV void PostCallRecordCreateBufferView(layer_data *device_data, const VkBufferViewCreateInfo *pCreateInfo, VkBufferView *pView); -bool ValidateImageAspectMask(const layer_data *device_data, VkImage image, VkFormat format, VkImageAspectFlags aspect_mask, - const char *func_name, const char *vuid = "VUID-VkImageSubresource-aspectMask-parameter"); +bool ValidateImageAspectMask(layer_data *device_data, VkImage image, VkFormat format, VkImageAspectFlags aspect_mask, + const char *func_name); bool ValidateCreateImageViewSubresourceRange(const layer_data *device_data, const IMAGE_STATE *image_state, bool is_imageview_2d_type, const VkImageSubresourceRange &subresourceRange); diff --git a/layers/convert_to_renderpass2.cpp b/layers/convert_to_renderpass2.cpp deleted file mode 100644 index ca3bbcde84a..00000000000 --- a/layers/convert_to_renderpass2.cpp +++ /dev/null @@ -1,202 +0,0 @@ -/* Copyright (c) 2015-2018 The Khronos Group Inc. - * Copyright (c) 2015-2018 Valve Corporation - * Copyright (c) 2015-2018 LunarG, Inc. - * Copyright (C) 2015-2018 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Author: Tobias Hector <@tobski> - */ - -#include - -#include "convert_to_renderpass2.h" -#include "vk_typemap_helper.h" -#include "vk_format_utils.h" - -static void ConvertVkAttachmentReferenceToV2KHR(const VkAttachmentReference* in_struct, - safe_VkAttachmentReference2KHR* out_struct) { - out_struct->sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR; - out_struct->pNext = nullptr; - out_struct->attachment = in_struct->attachment; - out_struct->layout = in_struct->layout; - out_struct->aspectMask = - VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM; // Uninitialized - must be filled in by top level struct for input attachments -} - -static void ConvertVkSubpassDependencyToV2KHR(const VkSubpassDependency* in_struct, safe_VkSubpassDependency2KHR* out_struct) { - out_struct->sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR; - out_struct->pNext = nullptr; - out_struct->srcSubpass = in_struct->srcSubpass; - out_struct->dstSubpass = in_struct->dstSubpass; - out_struct->srcStageMask = in_struct->srcStageMask; - out_struct->dstStageMask = in_struct->dstStageMask; - out_struct->srcAccessMask = in_struct->srcAccessMask; - out_struct->dstAccessMask = in_struct->dstAccessMask; - out_struct->dependencyFlags = in_struct->dependencyFlags; - out_struct->viewOffset = 0; -} - -static void ConvertVkSubpassDescriptionToV2KHR(const VkSubpassDescription* in_struct, safe_VkSubpassDescription2KHR* out_struct) { - out_struct->sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR; - out_struct->pNext = nullptr; - out_struct->flags = in_struct->flags; - out_struct->pipelineBindPoint = in_struct->pipelineBindPoint; - out_struct->viewMask = 0; - out_struct->inputAttachmentCount = in_struct->inputAttachmentCount; - out_struct->pInputAttachments = nullptr; - out_struct->colorAttachmentCount = in_struct->colorAttachmentCount; - out_struct->pColorAttachments = nullptr; - out_struct->pResolveAttachments = nullptr; - out_struct->preserveAttachmentCount = in_struct->preserveAttachmentCount; - out_struct->pPreserveAttachments = nullptr; - - if (out_struct->inputAttachmentCount && in_struct->pInputAttachments) { - out_struct->pInputAttachments = new safe_VkAttachmentReference2KHR[out_struct->inputAttachmentCount]; - for (uint32_t i = 0; i < out_struct->inputAttachmentCount; ++i) { - ConvertVkAttachmentReferenceToV2KHR(&in_struct->pInputAttachments[i], &out_struct->pInputAttachments[i]); - } - } - if (out_struct->colorAttachmentCount && in_struct->pColorAttachments) { - out_struct->pColorAttachments = new safe_VkAttachmentReference2KHR[out_struct->colorAttachmentCount]; - for (uint32_t i = 0; i < out_struct->colorAttachmentCount; ++i) { - ConvertVkAttachmentReferenceToV2KHR(&in_struct->pColorAttachments[i], &out_struct->pColorAttachments[i]); - } - } - if (out_struct->colorAttachmentCount && in_struct->pResolveAttachments) { - out_struct->pResolveAttachments = new safe_VkAttachmentReference2KHR[out_struct->colorAttachmentCount]; - for (uint32_t i = 0; i < out_struct->colorAttachmentCount; ++i) { - ConvertVkAttachmentReferenceToV2KHR(&in_struct->pResolveAttachments[i], &out_struct->pResolveAttachments[i]); - } - } - if (in_struct->pDepthStencilAttachment) { - out_struct->pDepthStencilAttachment = new safe_VkAttachmentReference2KHR(); - ConvertVkAttachmentReferenceToV2KHR(in_struct->pDepthStencilAttachment, out_struct->pDepthStencilAttachment); - } else { - out_struct->pDepthStencilAttachment = NULL; - } - if (in_struct->pPreserveAttachments) { - out_struct->pPreserveAttachments = new uint32_t[in_struct->preserveAttachmentCount]; - memcpy((void*)out_struct->pPreserveAttachments, (void*)in_struct->pPreserveAttachments, - sizeof(uint32_t) * in_struct->preserveAttachmentCount); - } -} - -static void ConvertVkAttachmentDescriptionToV2KHR(const VkAttachmentDescription* in_struct, - safe_VkAttachmentDescription2KHR* out_struct) { - out_struct->sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR; - out_struct->pNext = nullptr; - out_struct->flags = in_struct->flags; - out_struct->format = in_struct->format; - out_struct->samples = in_struct->samples; - out_struct->loadOp = in_struct->loadOp; - out_struct->storeOp = in_struct->storeOp; - out_struct->stencilLoadOp = in_struct->stencilLoadOp; - out_struct->stencilStoreOp = in_struct->stencilStoreOp; - out_struct->initialLayout = in_struct->initialLayout; - out_struct->finalLayout = in_struct->finalLayout; -} - -void ConvertVkRenderPassCreateInfoToV2KHR(const VkRenderPassCreateInfo* in_struct, safe_VkRenderPassCreateInfo2KHR* out_struct) { - out_struct->sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR; - out_struct->pNext = nullptr; - out_struct->flags = in_struct->flags; - out_struct->attachmentCount = in_struct->attachmentCount; - out_struct->pAttachments = nullptr; - out_struct->subpassCount = in_struct->subpassCount; - out_struct->pSubpasses = nullptr; - out_struct->dependencyCount = in_struct->dependencyCount; - out_struct->pDependencies = nullptr; - out_struct->correlatedViewMaskCount = 0; - out_struct->pCorrelatedViewMasks = nullptr; - if (out_struct->attachmentCount && in_struct->pAttachments) { - out_struct->pAttachments = new safe_VkAttachmentDescription2KHR[out_struct->attachmentCount]; - for (uint32_t i = 0; i < out_struct->attachmentCount; ++i) { - ConvertVkAttachmentDescriptionToV2KHR(&in_struct->pAttachments[i], &out_struct->pAttachments[i]); - } - } - if (out_struct->subpassCount && in_struct->pSubpasses) { - out_struct->pSubpasses = new safe_VkSubpassDescription2KHR[out_struct->subpassCount]; - for (uint32_t i = 0; i < out_struct->subpassCount; ++i) { - ConvertVkSubpassDescriptionToV2KHR(&in_struct->pSubpasses[i], &out_struct->pSubpasses[i]); - } - } - if (out_struct->dependencyCount && in_struct->pDependencies) { - out_struct->pDependencies = new safe_VkSubpassDependency2KHR[out_struct->dependencyCount]; - for (uint32_t i = 0; i < out_struct->dependencyCount; ++i) { - ConvertVkSubpassDependencyToV2KHR(&in_struct->pDependencies[i], &out_struct->pDependencies[i]); - } - } - - // Handle extension structs from KHR_multiview and KHR_maintenance2 to fill out the "filled in" bits. - if (in_struct->pNext) { - const VkRenderPassMultiviewCreateInfo* pMultiviewInfo = - lvl_find_in_chain(in_struct->pNext); - if (pMultiviewInfo) { - for (uint32_t subpass = 0; subpass < pMultiviewInfo->subpassCount; ++subpass) { - if (subpass < in_struct->subpassCount) { - out_struct->pSubpasses[subpass].viewMask = pMultiviewInfo->pViewMasks[subpass]; - } - } - for (uint32_t dependency = 0; dependency < pMultiviewInfo->dependencyCount; ++dependency) { - if (dependency < in_struct->dependencyCount) { - out_struct->pDependencies[dependency].viewOffset = pMultiviewInfo->pViewOffsets[dependency]; - } - } - if (pMultiviewInfo->correlationMaskCount) { - out_struct->correlatedViewMaskCount = pMultiviewInfo->correlationMaskCount; - uint32_t* pCorrelatedViewMasks = new uint32_t[out_struct->correlatedViewMaskCount]; - for (uint32_t correlationMask = 0; correlationMask < pMultiviewInfo->correlationMaskCount; ++correlationMask) { - pCorrelatedViewMasks[correlationMask] = pMultiviewInfo->pCorrelationMasks[correlationMask]; - } - out_struct->pCorrelatedViewMasks = pCorrelatedViewMasks; - } - } - const VkRenderPassInputAttachmentAspectCreateInfo* pInputAttachmentAspectInfo = - lvl_find_in_chain(in_struct->pNext); - if (pInputAttachmentAspectInfo) { - for (uint32_t i = 0; i < pInputAttachmentAspectInfo->aspectReferenceCount; ++i) { - uint32_t subpass = pInputAttachmentAspectInfo->pAspectReferences[i].subpass; - uint32_t attachment = pInputAttachmentAspectInfo->pAspectReferences[i].inputAttachmentIndex; - VkImageAspectFlags aspectMask = pInputAttachmentAspectInfo->pAspectReferences[i].aspectMask; - if (subpass < in_struct->subpassCount && attachment < in_struct->pSubpasses[subpass].inputAttachmentCount) { - out_struct->pSubpasses[subpass].pInputAttachments[attachment].aspectMask = aspectMask; - } - } - } - } - - if (out_struct->subpassCount && out_struct->pSubpasses) { - for (uint32_t i = 0; i < out_struct->subpassCount; ++i) { - if (out_struct->pSubpasses[i].inputAttachmentCount && out_struct->pSubpasses[i].pInputAttachments) { - for (uint32_t j = 0; j < out_struct->pSubpasses[i].inputAttachmentCount; ++j) { - safe_VkAttachmentReference2KHR& attachment_ref = out_struct->pSubpasses[i].pInputAttachments[j]; - if (attachment_ref.aspectMask == VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM && - attachment_ref.attachment < out_struct->attachmentCount && out_struct->pAttachments) { - attachment_ref.aspectMask = 0; - VkFormat attachmentFormat = out_struct->pAttachments[attachment_ref.attachment].format; - if (FormatIsColor(attachmentFormat)) { - attachment_ref.aspectMask |= VK_IMAGE_ASPECT_COLOR_BIT; - } - if (FormatHasDepth(attachmentFormat)) { - attachment_ref.aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT; - } - if (FormatHasStencil(attachmentFormat)) { - attachment_ref.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT; - } - } - } - } - } - } -} diff --git a/layers/convert_to_renderpass2.h b/layers/convert_to_renderpass2.h deleted file mode 100644 index 8e7f0f95a91..00000000000 --- a/layers/convert_to_renderpass2.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Copyright (c) 2015-2018 The Khronos Group Inc. - * Copyright (c) 2015-2018 Valve Corporation - * Copyright (c) 2015-2018 LunarG, Inc. - * Copyright (C) 2015-2018 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Author: Tobias Hector <@tobski> - */ - -#pragma once -#include "vk_safe_struct.h" - -void ConvertVkRenderPassCreateInfoToV2KHR(const VkRenderPassCreateInfo* in_struct, safe_VkRenderPassCreateInfo2KHR* out_struct); diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp index 4c56089dfa0..b98c66e5311 100644 --- a/layers/core_validation.cpp +++ b/layers/core_validation.cpp @@ -61,7 +61,6 @@ #if defined(__GNUC__) #pragma GCC diagnostic warning "-Wwrite-strings" #endif -#include "convert_to_renderpass2.h" #include "core_validation.h" #include "buffer_validation.h" #include "shader_validation.h" @@ -1071,7 +1070,7 @@ static bool ValidatePipelineDrawtimeState(layer_data const *dev_data, LAST_BOUND VkSampleCountFlagBits pso_num_samples = GetNumSamples(pPipeline); if (pCB->activeRenderPass) { const auto render_pass_info = pCB->activeRenderPass->createInfo.ptr(); - const VkSubpassDescription2KHR *subpass_desc = &render_pass_info->pSubpasses[pCB->activeSubpass]; + const VkSubpassDescription *subpass_desc = &render_pass_info->pSubpasses[pCB->activeSubpass]; uint32_t i; unsigned subpass_num_samples = 0; @@ -1736,8 +1735,7 @@ bool ValidateCmdSubpassState(const layer_data *dev_data, const GLOBAL_CB_NODE *p if (!pCB->activeRenderPass) return false; bool skip = false; if (pCB->activeSubpassContents == VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS && - (cmd_type != CMD_EXECUTECOMMANDS && cmd_type != CMD_NEXTSUBPASS && cmd_type != CMD_ENDRENDERPASS && - cmd_type != CMD_NEXTSUBPASS2KHR && cmd_type != CMD_ENDRENDERPASS2KHR)) { + (cmd_type != CMD_EXECUTECOMMANDS && cmd_type != CMD_NEXTSUBPASS && cmd_type != CMD_ENDRENDERPASS)) { skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, HandleToUint64(pCB->commandBuffer), kVUID_Core_DrawState_InvalidCommandBuffer, "Commands cannot be called in a subpass using secondary command buffers."); @@ -1800,7 +1798,6 @@ static const std::unordered_map must_be_recording_ {CMD_NONE, kVUIDUndefined}, // UNMATCHED {CMD_BEGINQUERY, "VUID-vkCmdBeginQuery-commandBuffer-recording"}, {CMD_BEGINRENDERPASS, "VUID-vkCmdBeginRenderPass-commandBuffer-recording"}, - {CMD_BEGINRENDERPASS2KHR, "VUID-vkCmdBeginRenderPass2KHR-commandBuffer-recording"}, {CMD_BINDDESCRIPTORSETS, "VUID-vkCmdBindDescriptorSets-commandBuffer-recording"}, {CMD_BINDINDEXBUFFER, "VUID-vkCmdBindIndexBuffer-commandBuffer-recording"}, {CMD_BINDPIPELINE, "VUID-vkCmdBindPipeline-commandBuffer-recording"}, @@ -1837,11 +1834,9 @@ static const std::unordered_map must_be_recording_ {CMD_ENDCOMMANDBUFFER, "VUID-vkEndCommandBuffer-commandBuffer-00059"}, {CMD_ENDQUERY, "VUID-vkCmdEndQuery-commandBuffer-recording"}, {CMD_ENDRENDERPASS, "VUID-vkCmdEndRenderPass-commandBuffer-recording"}, - {CMD_ENDRENDERPASS2KHR, "VUID-vkCmdEndRenderPass2KHR-commandBuffer-recording"}, {CMD_EXECUTECOMMANDS, "VUID-vkCmdExecuteCommands-commandBuffer-recording"}, {CMD_FILLBUFFER, "VUID-vkCmdFillBuffer-commandBuffer-recording"}, {CMD_NEXTSUBPASS, "VUID-vkCmdNextSubpass-commandBuffer-recording"}, - {CMD_NEXTSUBPASS2KHR, "VUID-vkCmdNextSubpass2KHR-commandBuffer-recording"}, {CMD_PIPELINEBARRIER, "VUID-vkCmdPipelineBarrier-commandBuffer-recording"}, // Exclude vendor ext (if not already present) { CMD_PROCESSCOMMANDSNVX, "VUID-vkCmdProcessCommandsNVX-commandBuffer-recording" // }, @@ -8101,80 +8096,10 @@ static VkPipelineStageFlags ExpandPipelineStageFlags(VkPipelineStageFlags inflag VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV | VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV); } -static bool HasNonFramebufferStagePipelineStageFlags(VkPipelineStageFlags inflags) { - return (inflags & ~(VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | - VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT)) != 0; -} - -static int GetGraphicsPipelineStageLogicalOrdinal(VkPipelineStageFlagBits flag) { - const VkPipelineStageFlagBits ordered_array[] = { - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, - VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT, - VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT, VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT, - // Including the task/mesh shaders here is not technically correct, as they are in a - // separate logical pipeline - but it works for the case this is currently used, and - // fixing it would require significant rework and end up with the code being far more - // verbose for no practical gain. - // However, worth paying attention to this if using this function in a new way. - VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV, VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT}; - - const int ordered_array_length = sizeof(ordered_array) / sizeof(VkPipelineStageFlagBits); - - for (int i = 0; i < ordered_array_length; ++i) { - if (ordered_array[i] == flag) { - return i; - } - } - - return -1; -} - -// The following two functions technically have O(N^2) complexity, but it's for a value of O that's largely -// stable and also rather tiny - this could definitely be rejigged to work more efficiently, but the impact -// on runtime is currently negligible, so it wouldn't gain very much. -// If we add a lot more graphics pipeline stages, this set of functions should be rewritten to accomodate. -static VkPipelineStageFlagBits GetLogicallyEarliestGraphicsPipelineStage(VkPipelineStageFlags inflags) { - VkPipelineStageFlagBits earliest_bit = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; - int earliest_bit_order = GetGraphicsPipelineStageLogicalOrdinal(earliest_bit); - - for (int i = 0; i < sizeof(VkPipelineStageFlagBits); ++i) { - VkPipelineStageFlagBits current_flag = (VkPipelineStageFlagBits)((inflags & 0x1u) << i); - if (current_flag) { - int new_order = GetGraphicsPipelineStageLogicalOrdinal(current_flag); - if (new_order != -1 && new_order < earliest_bit_order) { - earliest_bit_order = new_order; - earliest_bit = current_flag; - } - } - inflags = inflags >> 1; - } - return earliest_bit; -} - -static VkPipelineStageFlagBits GetLogicallyLatestGraphicsPipelineStage(VkPipelineStageFlags inflags) { - VkPipelineStageFlagBits latest_bit = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; - int latest_bit_order = GetGraphicsPipelineStageLogicalOrdinal(latest_bit); - - for (int i = 0; i < sizeof(VkPipelineStageFlagBits); ++i) { - if (inflags & 0x1u) { - int new_order = GetGraphicsPipelineStageLogicalOrdinal((VkPipelineStageFlagBits)((inflags & 0x1u) << i)); - if (new_order != -1 && new_order > latest_bit_order) { - latest_bit_order = new_order; - latest_bit = (VkPipelineStageFlagBits)((inflags & 0x1u) << i); - } - } - inflags = inflags >> 1; - } - return latest_bit; -} - // Verify image barrier image state and that the image is consistent with FB image static bool ValidateImageBarrierImage(layer_data *device_data, const char *funcName, GLOBAL_CB_NODE const *cb_state, - VkFramebuffer framebuffer, uint32_t active_subpass, - const safe_VkSubpassDescription2KHR &sub_desc, uint64_t rp_handle, uint32_t img_index, - const VkImageMemoryBarrier &img_barrier) { + VkFramebuffer framebuffer, uint32_t active_subpass, const safe_VkSubpassDescription &sub_desc, + uint64_t rp_handle, uint32_t img_index, const VkImageMemoryBarrier &img_barrier) { bool skip = false; const auto &fb_state = GetFramebufferState(device_data, framebuffer); assert(fb_state); @@ -8249,10 +8174,9 @@ static bool ValidateImageBarrierImage(layer_data *device_data, const char *funcN // Validate image barriers within a renderPass static bool ValidateRenderPassImageBarriers(layer_data *device_data, const char *funcName, GLOBAL_CB_NODE *cb_state, - uint32_t active_subpass, const safe_VkSubpassDescription2KHR &sub_desc, - uint64_t rp_handle, const safe_VkSubpassDependency2KHR *dependencies, - const std::vector &self_dependencies, uint32_t image_mem_barrier_count, - const VkImageMemoryBarrier *image_barriers) { + uint32_t active_subpass, const safe_VkSubpassDescription &sub_desc, uint64_t rp_handle, + const VkSubpassDependency *dependencies, const std::vector &self_dependencies, + uint32_t image_mem_barrier_count, const VkImageMemoryBarrier *image_barriers) { bool skip = false; for (uint32_t i = 0; i < image_mem_barrier_count; ++i) { const auto &img_barrier = image_barriers[i]; @@ -9468,7 +9392,7 @@ VKAPI_ATTR void VKAPI_CALL CmdWriteTimestamp(VkCommandBuffer commandBuffer, VkPi if (cb_state) PostCallRecordCmdWriteTimestamp(cb_state, commandBuffer, queryPool, slot); } -static bool MatchUsage(layer_data *dev_data, uint32_t count, const VkAttachmentReference2KHR *attachments, +static bool MatchUsage(layer_data *dev_data, uint32_t count, const VkAttachmentReference *attachments, const VkFramebufferCreateInfo *fbci, VkImageUsageFlagBits usage_flag, std::string error_code) { bool skip = false; @@ -9510,7 +9434,7 @@ static bool ValidateFramebufferCreateInfo(layer_data *dev_data, const VkFramebuf auto rp_state = GetRenderPassState(dev_data, pCreateInfo->renderPass); if (rp_state) { - const VkRenderPassCreateInfo2KHR *rpci = rp_state->createInfo.ptr(); + const VkRenderPassCreateInfo *rpci = rp_state->createInfo.ptr(); if (rpci->attachmentCount != pCreateInfo->attachmentCount) { skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, HandleToUint64(pCreateInfo->renderPass), "VUID-VkFramebufferCreateInfo-attachmentCount-00876", @@ -9737,11 +9661,11 @@ static bool CheckDependencyExists(const layer_data *dev_data, const uint32_t sub return result; } -static bool CheckPreserved(const layer_data *dev_data, const VkRenderPassCreateInfo2KHR *pCreateInfo, const int index, +static bool CheckPreserved(const layer_data *dev_data, const VkRenderPassCreateInfo *pCreateInfo, const int index, const uint32_t attachment, const std::vector &subpass_to_node, int depth, bool &skip) { const DAGNode &node = subpass_to_node[index]; // If this node writes to the attachment return true as next nodes need to preserve the attachment. - const VkSubpassDescription2KHR &subpass = pCreateInfo->pSubpasses[index]; + const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[index]; for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) { if (attachment == subpass.pColorAttachments[j].attachment) return true; } @@ -9849,7 +9773,7 @@ static bool ValidateDependencies(const layer_data *dev_data, FRAMEBUFFER_STATE c // Find for each attachment the subpasses that use them. unordered_set attachmentIndices; for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { - const VkSubpassDescription2KHR &subpass = pCreateInfo->pSubpasses[i]; + const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[i]; attachmentIndices.clear(); for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) { uint32_t attachment = subpass.pInputAttachments[j].attachment; @@ -9885,7 +9809,7 @@ static bool ValidateDependencies(const layer_data *dev_data, FRAMEBUFFER_STATE c } // If there is a dependency needed make sure one exists for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { - const VkSubpassDescription2KHR &subpass = pCreateInfo->pSubpasses[i]; + const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[i]; // If the attachment is an input then all subpasses that output must have a dependency relationship for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) { uint32_t attachment = subpass.pInputAttachments[j].attachment; @@ -9908,7 +9832,7 @@ static bool ValidateDependencies(const layer_data *dev_data, FRAMEBUFFER_STATE c // Loop through implicit dependencies, if this pass reads make sure the attachment is preserved for all passes after it was // written. for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { - const VkSubpassDescription2KHR &subpass = pCreateInfo->pSubpasses[i]; + const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[i]; for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) { CheckPreserved(dev_data, pCreateInfo, i, subpass.pInputAttachments[j].attachment, subpass_to_node, 0, skip); } @@ -9916,8 +9840,7 @@ static bool ValidateDependencies(const layer_data *dev_data, FRAMEBUFFER_STATE c return skip; } -static bool CreatePassDAG(const layer_data *dev_data, RenderPassCreateVersion rp_version, - const VkRenderPassCreateInfo2KHR *pCreateInfo, RENDER_PASS_STATE *render_pass) { +static bool CreatePassDAG(const layer_data *dev_data, const VkRenderPassCreateInfo *pCreateInfo, RENDER_PASS_STATE *render_pass) { // Shorthand... auto &subpass_to_node = render_pass->subpassToNode; subpass_to_node.resize(pCreateInfo->subpassCount); @@ -9925,128 +9848,23 @@ static bool CreatePassDAG(const layer_data *dev_data, RenderPassCreateVersion rp self_dependencies.resize(pCreateInfo->subpassCount); bool skip = false; - const char *vuid; - const bool use_rp2 = (rp_version == RENDER_PASS_VERSION_2); - for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { subpass_to_node[i].pass = i; self_dependencies[i].clear(); } for (uint32_t i = 0; i < pCreateInfo->dependencyCount; ++i) { - const VkSubpassDependency2KHR &dependency = pCreateInfo->pDependencies[i]; - VkPipelineStageFlags exclude_graphics_pipeline_stages = - ~(VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT | ExpandPipelineStageFlags(VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT)); - VkPipelineStageFlagBits latest_src_stage = GetLogicallyLatestGraphicsPipelineStage(dependency.srcStageMask); - VkPipelineStageFlagBits earliest_dst_stage = GetLogicallyEarliestGraphicsPipelineStage(dependency.dstStageMask); - - // This VU is actually generalised to *any* pipeline - not just graphics - but only graphics render passes are - // currently supported by the spec - so only that pipeline is checked here. - // If that is ever relaxed, this check should be extended to cover those pipelines. - if (dependency.srcSubpass == dependency.dstSubpass && (dependency.srcStageMask & exclude_graphics_pipeline_stages) != 0u && - (dependency.dstStageMask & exclude_graphics_pipeline_stages) != 0u) { - vuid = use_rp2 ? "VUID-VkSubpassDependency2KHR-srcSubpass-02244" : "VUID-VkSubpassDependency-srcSubpass-01989"; - skip |= log_msg( - dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, - "Dependency %u is a self-dependency, but specifies stage masks that contain stages not in the GRAPHICS pipeline.", - i); - } else if (dependency.srcSubpass != VK_SUBPASS_EXTERNAL && (dependency.srcStageMask & VK_PIPELINE_STAGE_HOST_BIT)) { - vuid = use_rp2 ? "VUID-VkSubpassDependency2KHR-srcSubpass-03078" : "VUID-VkSubpassDependency-srcSubpass-00858"; - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, - "Dependency %u specifies a dependency from subpass %u, but includes HOST_BIT in the source stage mask.", - i, dependency.srcSubpass); - } else if (dependency.dstSubpass != VK_SUBPASS_EXTERNAL && (dependency.dstStageMask & VK_PIPELINE_STAGE_HOST_BIT)) { - vuid = use_rp2 ? "VUID-VkSubpassDependency2KHR-dstSubpass-03079" : "VUID-VkSubpassDependency-dstSubpass-00859"; - skip |= - log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, - "Dependency %u specifies a dependency to subpass %u, but includes HOST_BIT in the destination stage mask.", - i, dependency.dstSubpass); - } - // These next two VUs are actually generalised to *any* pipeline - not just graphics - but only graphics render passes are - // currently supported by the spec - so only that pipeline is checked here. - // If that is ever relaxed, these next two checks should be extended to cover those pipelines. - else if (dependency.srcSubpass != VK_SUBPASS_EXTERNAL && - pCreateInfo->pSubpasses[dependency.srcSubpass].pipelineBindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS && - (dependency.srcStageMask & exclude_graphics_pipeline_stages) != 0u) { - vuid = - use_rp2 ? "VUID-VkRenderPassCreateInfo2KHR-pDependencies-03054" : "VUID-VkRenderPassCreateInfo-pDependencies-00837"; - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, - "Dependency %u specifies a source stage mask that contains stages not in the GRAPHICS pipeline as used " - "by the source subpass %u.", - i, dependency.srcSubpass); - } else if (dependency.dstSubpass != VK_SUBPASS_EXTERNAL && - pCreateInfo->pSubpasses[dependency.dstSubpass].pipelineBindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS && - (dependency.dstStageMask & exclude_graphics_pipeline_stages) != 0u) { - vuid = - use_rp2 ? "VUID-VkRenderPassCreateInfo2KHR-pDependencies-03055" : "VUID-VkRenderPassCreateInfo-pDependencies-00838"; - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, - "Dependency %u specifies a destination stage mask that contains stages not in the GRAPHICS pipeline as " - "used by the destination subpass %u.", - i, dependency.dstSubpass); - } - // The first subpass here serves as a good proxy for "is multiview enabled" - since all view masks need to be non-zero if - // any are, which enables multiview. - else if (dependency.dependencyFlags & VK_DEPENDENCY_VIEW_LOCAL_BIT && pCreateInfo->pSubpasses[0].viewMask == 0) { - vuid = use_rp2 ? "VUID-VkRenderPassCreateInfo2KHR-viewMask-03059" : "VUID-VkSubpassDependency-dependencyFlags-00871"; - skip |= log_msg( - dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, - "Dependency %u specifies the VK_DEPENDENCY_VIEW_LOCAL_BIT, but multiview is not enabled for this render pass.", i); - } else if (use_rp2 && !(dependency.dependencyFlags & VK_DEPENDENCY_VIEW_LOCAL_BIT) && dependency.viewOffset != 0) { - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, - "VUID-VkSubpassDependency2KHR-dependencyFlags-03092", - "Dependency %u specifies the VK_DEPENDENCY_VIEW_LOCAL_BIT, but also specifies a view offset of %u.", i, - dependency.viewOffset); - } else if (dependency.srcSubpass == VK_SUBPASS_EXTERNAL || dependency.dstSubpass == VK_SUBPASS_EXTERNAL) { + const VkSubpassDependency &dependency = pCreateInfo->pDependencies[i]; + if (dependency.srcSubpass == VK_SUBPASS_EXTERNAL || dependency.dstSubpass == VK_SUBPASS_EXTERNAL) { if (dependency.srcSubpass == dependency.dstSubpass) { - vuid = use_rp2 ? "VUID-VkSubpassDependency2KHR-srcSubpass-03085" : "VUID-VkSubpassDependency-srcSubpass-00865"; skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, - vuid, "The src and dst subpasses in dependency %u are both external.", i); - } else if (dependency.dependencyFlags & VK_DEPENDENCY_VIEW_LOCAL_BIT) { - vuid = "VUID-VkSubpassDependency-dependencyFlags-00870"; - if (use_rp2) { - // Create render pass 2 distinguishes between source and destination external dependencies. - if (dependency.srcSubpass == VK_SUBPASS_EXTERNAL) { - vuid = "VUID-VkSubpassDependency2KHR-dependencyFlags-03090"; - } else { - vuid = "VUID-VkSubpassDependency2KHR-dependencyFlags-03091"; - } - } - skip |= - log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, - "Dependency %u specifies an external dependency but also specifies VK_DEPENDENCY_VIEW_LOCAL_BIT.", i); + kVUID_Core_DrawState_InvalidRenderpass, "The src and dest subpasses cannot both be external."); } } else if (dependency.srcSubpass > dependency.dstSubpass) { - vuid = use_rp2 ? "VUID-VkSubpassDependency2KHR-srcSubpass-03084" : "VUID-VkSubpassDependency-srcSubpass-00864"; - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, - "Dependency %u specifies a dependency from a later subpass (%u) to an earlier subpass (%u), which is " - "disallowed to prevent cyclic dependencies.", - i, dependency.srcSubpass, dependency.dstSubpass); + skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, + kVUID_Core_DrawState_InvalidRenderpass, + "Dependency graph must be specified such that an earlier pass cannot depend on a later pass."); } else if (dependency.srcSubpass == dependency.dstSubpass) { - if (dependency.viewOffset != 0) { - vuid = use_rp2 ? kVUID_Core_DrawState_InvalidRenderpass : "VUID-VkRenderPassCreateInfo-pNext-01930"; - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, - vuid, "Dependency %u specifies a self-dependency but has a non-zero view offset of %u", i, - dependency.viewOffset); - } else if ((dependency.dependencyFlags | VK_DEPENDENCY_VIEW_LOCAL_BIT) != dependency.dependencyFlags && - pCreateInfo->pSubpasses[dependency.srcSubpass].viewMask > 1) { - vuid = - use_rp2 ? "VUID-VkRenderPassCreateInfo2KHR-pDependencies-03060" : "VUID-VkSubpassDependency-srcSubpass-00872"; - skip |= - log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, - "Dependency %u specifies a self-dependency for subpass %u with a non-zero view mask, but does not " - "specify VK_DEPENDENCY_VIEW_LOCAL_BIT.", - i, dependency.srcSubpass); - } else if ((HasNonFramebufferStagePipelineStageFlags(dependency.srcStageMask) || - HasNonFramebufferStagePipelineStageFlags(dependency.dstStageMask)) && - (GetGraphicsPipelineStageLogicalOrdinal(latest_src_stage) > - GetGraphicsPipelineStageLogicalOrdinal(earliest_dst_stage))) { - vuid = use_rp2 ? "VUID-VkSubpassDependency2KHR-srcSubpass-03087" : "VUID-VkSubpassDependency-srcSubpass-00867"; - skip |= log_msg( - dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, - "Dependency %u specifies a self-dependency from logically-later stage (%s) to a logically-earlier stage (%s).", - i, string_VkPipelineStageFlagBits(latest_src_stage), string_VkPipelineStageFlagBits(earliest_dst_stage)); - } else { - self_dependencies[dependency.srcSubpass].push_back(i); - } + self_dependencies[dependency.srcSubpass].push_back(i); } else { subpass_to_node[dependency.dstSubpass].prev.push_back(dependency.srcSubpass); subpass_to_node[dependency.srcSubpass].next.push_back(dependency.dstSubpass); @@ -10077,17 +9895,12 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateShaderModule(VkDevice device, const VkShade return res; } -static bool ValidateAttachmentIndex(const layer_data *dev_data, RenderPassCreateVersion rp_version, uint32_t attachment, - uint32_t attachment_count, const char *type) { +static bool ValidateAttachmentIndex(const layer_data *dev_data, uint32_t attachment, uint32_t attachment_count, const char *type) { bool skip = false; - const bool use_rp2 = (rp_version == RENDER_PASS_VERSION_2); - const char *const function_name = use_rp2 ? "vkCreateRenderPass2KHR()" : "vkCreateRenderPass()"; - if (attachment >= attachment_count && attachment != VK_ATTACHMENT_UNUSED) { - const char *vuid = - use_rp2 ? "VUID-VkRenderPassCreateInfo2KHR-attachment-03051" : "VUID-VkRenderPassCreateInfo-attachment-00834"; - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, - "%s: %s attachment %d must be less than the total number of attachments %d.", type, function_name, + skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, + "VUID-VkRenderPassCreateInfo-attachment-00834", + "CreateRenderPass: %s attachment %d must be less than the total number of attachments %d.", type, attachment, attachment_count); } return skip; @@ -10120,35 +9933,31 @@ char const *StringAttachmentType(uint8_t type) { } } -static bool AddAttachmentUse(const layer_data *dev_data, RenderPassCreateVersion rp_version, uint32_t subpass, - std::vector &attachment_uses, std::vector &attachment_layouts, - uint32_t attachment, uint8_t new_use, VkImageLayout new_layout) { +static bool AddAttachmentUse(const layer_data *dev_data, uint32_t subpass, std::vector &attachment_uses, + std::vector &attachment_layouts, uint32_t attachment, uint8_t new_use, + VkImageLayout new_layout) { if (attachment >= attachment_uses.size()) return false; /* out of range, but already reported */ bool skip = false; auto &uses = attachment_uses[attachment]; - const bool use_rp2 = (rp_version == RENDER_PASS_VERSION_2); - const char *vuid; - const char *const function_name = use_rp2 ? "vkCreateRenderPass2KHR()" : "vkCreateRenderPass()"; - if (uses & new_use) { - log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, - kVUID_Core_DrawState_InvalidRenderpass, "%s: subpass %u already uses attachment %u as a %s attachment.", - function_name, subpass, attachment, StringAttachmentType(new_use)); + skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, + kVUID_Core_DrawState_InvalidRenderpass, + "vkCreateRenderPass(): subpass %u already uses attachment %u as a %s attachment.", subpass, attachment, + StringAttachmentType(new_use)); } else if (uses & ~ATTACHMENT_INPUT || (uses && (new_use == ATTACHMENT_RESOLVE || new_use == ATTACHMENT_PRESERVE))) { /* Note: input attachments are assumed to be done first. */ - vuid = use_rp2 ? "VUID-VkSubpassDescription2KHR-pPreserveAttachments-03074" - : "VUID-VkSubpassDescription-pPreserveAttachments-00854"; - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, - "%s: subpass %u uses attachment %u as both %s and %s attachment.", function_name, subpass, attachment, + skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, + "VUID-VkSubpassDescription-pPreserveAttachments-00854", + "vkCreateRenderPass(): subpass %u uses attachment %u as both %s and %s attachment.", subpass, attachment, StringAttachmentType(uses), StringAttachmentType(new_use)); } else if (uses && attachment_layouts[attachment] != new_layout) { - vuid = use_rp2 ? "VUID-VkSubpassDescription2KHR-layout-03075" : "VUID-VkSubpassDescription-layout-00855"; - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, - "%s: subpass %u uses attachment %u with conflicting layouts: input uses %s, but %s " + skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, + "VUID-VkSubpassDescription-layout-00855", + "vkCreateRenderPass(): subpass %u uses attachment %u with conflicting layouts: input uses %s, but %s " "attachment uses %s.", - function_name, subpass, attachment, string_VkImageLayout(attachment_layouts[attachment]), - StringAttachmentType(new_use), string_VkImageLayout(new_layout)); + subpass, attachment, string_VkImageLayout(attachment_layouts[attachment]), StringAttachmentType(new_use), + string_VkImageLayout(new_layout)); } else { attachment_layouts[attachment] = new_layout; uses |= new_use; @@ -10157,235 +9966,139 @@ static bool AddAttachmentUse(const layer_data *dev_data, RenderPassCreateVersion return skip; } -static bool ValidateRenderpassAttachmentUsage(const layer_data *dev_data, RenderPassCreateVersion rp_version, - const VkRenderPassCreateInfo2KHR *pCreateInfo) { +static bool ValidateRenderpassAttachmentUsage(const layer_data *dev_data, const VkRenderPassCreateInfo *pCreateInfo) { bool skip = false; - const bool use_rp2 = (rp_version == RENDER_PASS_VERSION_2); - const char *vuid; - const char *const function_name = use_rp2 ? "vkCreateRenderPass2KHR()" : "vkCreateRenderPass()"; - for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { - const VkSubpassDescription2KHR &subpass = pCreateInfo->pSubpasses[i]; + const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[i]; std::vector attachment_uses(pCreateInfo->attachmentCount); std::vector attachment_layouts(pCreateInfo->attachmentCount); if (subpass.pipelineBindPoint != VK_PIPELINE_BIND_POINT_GRAPHICS) { - vuid = use_rp2 ? "VUID-VkSubpassDescription2KHR-pipelineBindPoint-03062" - : "VUID-VkSubpassDescription-pipelineBindPoint-00844"; - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, - "%s: Pipeline bind point for subpass %d must be VK_PIPELINE_BIND_POINT_GRAPHICS.", function_name, i); + skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, + "VUID-VkSubpassDescription-pipelineBindPoint-00844", + "vkCreateRenderPass(): Pipeline bind point for subpass %d must be VK_PIPELINE_BIND_POINT_GRAPHICS.", i); } for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) { auto const &attachment_ref = subpass.pInputAttachments[j]; if (attachment_ref.attachment != VK_ATTACHMENT_UNUSED) { - skip |= - ValidateAttachmentIndex(dev_data, rp_version, attachment_ref.attachment, pCreateInfo->attachmentCount, "Input"); - - if (attachment_ref.aspectMask & VK_IMAGE_ASPECT_METADATA_BIT) { - vuid = - use_rp2 ? kVUID_Core_DrawState_InvalidRenderpass : "VUID-VkInputAttachmentAspectReference-aspectMask-01964"; - skip |= log_msg( - dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, - "%s: Aspect mask for input attachment reference %d in subpass %d includes VK_IMAGE_ASPECT_METADATA_BIT.", - function_name, i, j); - } - - if (attachment_ref.attachment < pCreateInfo->attachmentCount) { - skip |= AddAttachmentUse(dev_data, rp_version, i, attachment_uses, attachment_layouts, - attachment_ref.attachment, ATTACHMENT_INPUT, attachment_ref.layout); - - vuid = use_rp2 ? kVUID_Core_DrawState_InvalidRenderpass : "VUID-VkRenderPassCreateInfo-pNext-01963"; - skip |= ValidateImageAspectMask(dev_data, VK_NULL_HANDLE, - pCreateInfo->pAttachments[attachment_ref.attachment].format, - attachment_ref.aspectMask, function_name, vuid); - } - } - - if (rp_version == RENDER_PASS_VERSION_2) { - // These are validated automatically as part of parameter validation for create renderpass 1 - // as they are in a struct that only applies to input attachments - not so for v2. - - // Check for 0 - if (attachment_ref.aspectMask == 0) { - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, - 0, "VUID-VkSubpassDescription2KHR-aspectMask-03176", - "%s: Input attachment (%d) aspect mask must not be 0.", function_name, j); - } else { - const VkImageAspectFlags valid_bits = - (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT | - VK_IMAGE_ASPECT_METADATA_BIT | VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT | - VK_IMAGE_ASPECT_PLANE_2_BIT); - - // Check for valid aspect mask bits - if (attachment_ref.aspectMask & ~valid_bits) { - skip |= - log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, - 0, "VUID-VkSubpassDescription2KHR-aspectMask-03175", - "%s: Input attachment (%d) aspect mask (0x%" PRIx32 ")is invalid.", function_name, j, - attachment_ref.aspectMask); - } - } + skip |= ValidateAttachmentIndex(dev_data, attachment_ref.attachment, pCreateInfo->attachmentCount, "Input"); + skip |= AddAttachmentUse(dev_data, i, attachment_uses, attachment_layouts, attachment_ref.attachment, + ATTACHMENT_INPUT, attachment_ref.layout); } } for (uint32_t j = 0; j < subpass.preserveAttachmentCount; ++j) { uint32_t attachment = subpass.pPreserveAttachments[j]; if (attachment == VK_ATTACHMENT_UNUSED) { - vuid = use_rp2 ? "VUID-VkSubpassDescription2KHR-attachment-03073" : "VUID-VkSubpassDescription-attachment-00853"; skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, - vuid, "%s: Preserve attachment (%d) must not be VK_ATTACHMENT_UNUSED.", function_name, j); + "VUID-VkSubpassDescription-attachment-00853", + "vkCreateRenderPass(): Preserve attachment (%d) must not be VK_ATTACHMENT_UNUSED.", j); } else { - skip |= ValidateAttachmentIndex(dev_data, rp_version, attachment, pCreateInfo->attachmentCount, "Preserve"); - if (attachment < pCreateInfo->attachmentCount) { - skip |= AddAttachmentUse(dev_data, rp_version, i, attachment_uses, attachment_layouts, attachment, - ATTACHMENT_PRESERVE, VkImageLayout(0) /* preserve doesn't have any layout */); - } + skip |= ValidateAttachmentIndex(dev_data, attachment, pCreateInfo->attachmentCount, "Preserve"); + skip |= AddAttachmentUse(dev_data, i, attachment_uses, attachment_layouts, attachment, ATTACHMENT_PRESERVE, + VkImageLayout(0) /* preserve doesn't have any layout */); } } + unsigned sample_count = 0; bool subpass_performs_resolve = false; for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) { if (subpass.pResolveAttachments) { auto const &attachment_ref = subpass.pResolveAttachments[j]; if (attachment_ref.attachment != VK_ATTACHMENT_UNUSED) { - skip |= ValidateAttachmentIndex(dev_data, rp_version, attachment_ref.attachment, pCreateInfo->attachmentCount, - "Resolve"); - - if (attachment_ref.attachment < pCreateInfo->attachmentCount) { - skip |= AddAttachmentUse(dev_data, rp_version, i, attachment_uses, attachment_layouts, - attachment_ref.attachment, ATTACHMENT_RESOLVE, attachment_ref.layout); + skip |= ValidateAttachmentIndex(dev_data, attachment_ref.attachment, pCreateInfo->attachmentCount, "Resolve"); + skip |= AddAttachmentUse(dev_data, i, attachment_uses, attachment_layouts, attachment_ref.attachment, + ATTACHMENT_RESOLVE, attachment_ref.layout); - subpass_performs_resolve = true; + subpass_performs_resolve = true; - if (pCreateInfo->pAttachments[attachment_ref.attachment].samples != VK_SAMPLE_COUNT_1_BIT) { - vuid = use_rp2 ? "VUID-VkSubpassDescription2KHR-pResolveAttachments-03067" - : "VUID-VkSubpassDescription-pResolveAttachments-00849"; - skip |= - log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, - VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, - "%s: Subpass %u requests multisample resolve into attachment %u, which must " - "have VK_SAMPLE_COUNT_1_BIT but has %s.", - function_name, i, attachment_ref.attachment, - string_VkSampleCountFlagBits(pCreateInfo->pAttachments[attachment_ref.attachment].samples)); - } + if (!skip && pCreateInfo->pAttachments[attachment_ref.attachment].samples != VK_SAMPLE_COUNT_1_BIT) { + skip |= + log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, + 0, "VUID-VkSubpassDescription-pResolveAttachments-00849", + "vkCreateRenderPass(): Subpass %u requests multisample resolve into attachment %u, which must " + "have VK_SAMPLE_COUNT_1_BIT but has %s.", + i, attachment_ref.attachment, + string_VkSampleCountFlagBits(pCreateInfo->pAttachments[attachment_ref.attachment].samples)); } } } } - if (subpass.pDepthStencilAttachment) { - if (subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) { - skip |= ValidateAttachmentIndex(dev_data, rp_version, subpass.pDepthStencilAttachment->attachment, - pCreateInfo->attachmentCount, "Depth"); - if (subpass.pDepthStencilAttachment->attachment < pCreateInfo->attachmentCount) { - skip |= AddAttachmentUse(dev_data, rp_version, i, attachment_uses, attachment_layouts, - subpass.pDepthStencilAttachment->attachment, ATTACHMENT_DEPTH, - subpass.pDepthStencilAttachment->layout); - } - } - } - - uint32_t last_sample_count_attachment = VK_ATTACHMENT_UNUSED; for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) { auto const &attachment_ref = subpass.pColorAttachments[j]; - skip |= ValidateAttachmentIndex(dev_data, rp_version, attachment_ref.attachment, pCreateInfo->attachmentCount, "Color"); - if (attachment_ref.attachment != VK_ATTACHMENT_UNUSED && attachment_ref.attachment < pCreateInfo->attachmentCount) { - skip |= AddAttachmentUse(dev_data, rp_version, i, attachment_uses, attachment_layouts, attachment_ref.attachment, + skip |= ValidateAttachmentIndex(dev_data, attachment_ref.attachment, pCreateInfo->attachmentCount, "Color"); + if (!skip && attachment_ref.attachment != VK_ATTACHMENT_UNUSED) { + skip |= AddAttachmentUse(dev_data, i, attachment_uses, attachment_layouts, attachment_ref.attachment, ATTACHMENT_COLOR, attachment_ref.layout); + sample_count |= (unsigned)pCreateInfo->pAttachments[attachment_ref.attachment].samples; - VkSampleCountFlagBits current_sample_count = pCreateInfo->pAttachments[attachment_ref.attachment].samples; - if (last_sample_count_attachment != VK_ATTACHMENT_UNUSED) { - VkSampleCountFlagBits last_sample_count = - pCreateInfo->pAttachments[subpass.pColorAttachments[last_sample_count_attachment].attachment].samples; - if (current_sample_count != last_sample_count) { - vuid = use_rp2 ? "VUID-VkSubpassDescription2KHR-pColorAttachments-03069" - : "VUID-VkSubpassDescription-pColorAttachments-01417"; - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, - VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, - "%s: Subpass %u attempts to render to color attachments with inconsistent sample counts." - "Color attachment ref %u has sample count %s, whereas previous color attachment ref %u has " - "sample count %s.", - function_name, i, j, string_VkSampleCountFlagBits(current_sample_count), - last_sample_count_attachment, string_VkSampleCountFlagBits(last_sample_count)); - } - } - last_sample_count_attachment = j; - - if (subpass_performs_resolve && current_sample_count == VK_SAMPLE_COUNT_1_BIT) { - vuid = use_rp2 ? "VUID-VkSubpassDescription2KHR-pResolveAttachments-03066" - : "VUID-VkSubpassDescription-pResolveAttachments-00848"; + if (subpass_performs_resolve && + pCreateInfo->pAttachments[attachment_ref.attachment].samples == VK_SAMPLE_COUNT_1_BIT) { skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, - 0, vuid, - "%s: Subpass %u requests multisample resolve from attachment %u which has " + 0, "VUID-VkSubpassDescription-pResolveAttachments-00848", + "vkCreateRenderPass(): Subpass %u requests multisample resolve from attachment %u which has " "VK_SAMPLE_COUNT_1_BIT.", - function_name, i, attachment_ref.attachment); + i, attachment_ref.attachment); } - if (subpass.pDepthStencilAttachment && subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED && - subpass.pDepthStencilAttachment->attachment < pCreateInfo->attachmentCount) { + if (dev_data->extensions.vk_amd_mixed_attachment_samples && subpass.pDepthStencilAttachment && + subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) { const auto depth_stencil_sample_count = pCreateInfo->pAttachments[subpass.pDepthStencilAttachment->attachment].samples; - - if (dev_data->extensions.vk_amd_mixed_attachment_samples) { - if (pCreateInfo->pAttachments[attachment_ref.attachment].samples > depth_stencil_sample_count) { - vuid = use_rp2 ? "VUID-VkSubpassDescription2KHR-pColorAttachments-03070" - : "VUID-VkSubpassDescription-pColorAttachments-01506"; - skip |= - log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, - VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, - "%s: Subpass %u pColorAttachments[%u] has %s which is larger than " - "depth/stencil attachment %s.", - function_name, i, j, - string_VkSampleCountFlagBits(pCreateInfo->pAttachments[attachment_ref.attachment].samples), - string_VkSampleCountFlagBits(depth_stencil_sample_count)); - break; - } - } - - if (!dev_data->extensions.vk_amd_mixed_attachment_samples && - !dev_data->extensions.vk_nv_framebuffer_mixed_samples && - current_sample_count != depth_stencil_sample_count) { - vuid = use_rp2 ? "VUID-VkSubpassDescription2KHR-pDepthStencilAttachment-03071" - : "VUID-VkSubpassDescription-pDepthStencilAttachment-01418"; + if (pCreateInfo->pAttachments[attachment_ref.attachment].samples > depth_stencil_sample_count) { skip |= log_msg( - dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, - "%s: Subpass %u attempts to render to use a depth/stencil attachment with sample count that differs " - "from color attachment %u." - "The depth attachment ref has sample count %s, whereas color attachment ref %u has sample count %s.", - function_name, i, j, string_VkSampleCountFlagBits(depth_stencil_sample_count), j, - string_VkSampleCountFlagBits(current_sample_count)); - break; + dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, + "VUID-VkSubpassDescription-pColorAttachments-01506", + "vkCreateRenderPass(): Subpass %u pColorAttachments[%u] has %s which is larger than " + "depth/stencil attachment %s.", + i, j, string_VkSampleCountFlagBits(pCreateInfo->pAttachments[attachment_ref.attachment].samples), + string_VkSampleCountFlagBits(depth_stencil_sample_count)); } } } - if (subpass_performs_resolve && subpass.pResolveAttachments[j].attachment != VK_ATTACHMENT_UNUSED && - subpass.pResolveAttachments[j].attachment < pCreateInfo->attachmentCount) { + if (!skip && subpass_performs_resolve && subpass.pResolveAttachments[j].attachment != VK_ATTACHMENT_UNUSED) { if (attachment_ref.attachment == VK_ATTACHMENT_UNUSED) { - vuid = use_rp2 ? "VUID-VkSubpassDescription2KHR-pResolveAttachments-03065" - : "VUID-VkSubpassDescription-pResolveAttachments-00847"; skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, - 0, vuid, - "%s: Subpass %u requests multisample resolve from attachment %u which has " + 0, "VUID-VkSubpassDescription-pResolveAttachments-00847", + "vkCreateRenderPass(): Subpass %u requests multisample resolve from attachment %u which has " "attachment=VK_ATTACHMENT_UNUSED.", - function_name, i, attachment_ref.attachment); + i, attachment_ref.attachment); } else { const auto &color_desc = pCreateInfo->pAttachments[attachment_ref.attachment]; const auto &resolve_desc = pCreateInfo->pAttachments[subpass.pResolveAttachments[j].attachment]; if (color_desc.format != resolve_desc.format) { - vuid = use_rp2 ? "VUID-VkSubpassDescription2KHR-pResolveAttachments-03068" - : "VUID-VkSubpassDescription-pResolveAttachments-00850"; - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, - VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, - "%s: Subpass %u pColorAttachments[%u] resolves to an attachment with a " - "different format. color format: %u, resolve format: %u.", - function_name, i, j, color_desc.format, resolve_desc.format); + skip |= + log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, + 0, "VUID-VkSubpassDescription-pResolveAttachments-00850", + "vkCreateRenderPass(): Subpass %u pColorAttachments[%u] resolves to an attachment with a " + "different format. color format: %u, resolve format: %u.", + i, j, color_desc.format, resolve_desc.format); } } } } + + if (subpass.pDepthStencilAttachment && subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) { + auto const &attachment_ref = *subpass.pDepthStencilAttachment; + skip |= ValidateAttachmentIndex(dev_data, attachment_ref.attachment, pCreateInfo->attachmentCount, "Depth stencil"); + + if (!skip && attachment_ref.attachment != VK_ATTACHMENT_UNUSED) { + skip |= AddAttachmentUse(dev_data, i, attachment_uses, attachment_layouts, attachment_ref.attachment, + ATTACHMENT_DEPTH, attachment_ref.layout); + sample_count |= (unsigned)pCreateInfo->pAttachments[attachment_ref.attachment].samples; + } + } + + if (!dev_data->extensions.vk_amd_mixed_attachment_samples && sample_count && !IsPowerOfTwo(sample_count)) { + skip |= + log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, + "VUID-VkAttachmentDescription-samples-parameter", + "vkCreateRenderPass(): Subpass %u attempts to render to attachments with inconsistent sample counts.", i); + } } return skip; } @@ -10396,151 +10109,44 @@ static void MarkAttachmentFirstUse(RENDER_PASS_STATE *render_pass, uint32_t inde if (!render_pass->attachment_first_read.count(index)) render_pass->attachment_first_read[index] = is_read; } -static bool ValidateCreateRenderPass(const layer_data *dev_data, VkDevice device, RenderPassCreateVersion rp_version, - const VkRenderPassCreateInfo2KHR *pCreateInfo, RENDER_PASS_STATE *render_pass) { +static bool PreCallValidateCreateRenderPass(const layer_data *dev_data, VkDevice device, const VkRenderPassCreateInfo *pCreateInfo, + RENDER_PASS_STATE *render_pass) { bool skip = false; - const bool use_rp2 = (rp_version == RENDER_PASS_VERSION_2); - const char *vuid; - const char *const function_name = use_rp2 ? "vkCreateRenderPass2KHR()" : "vkCreateRenderPass()"; // TODO: As part of wrapping up the mem_tracker/core_validation merge the following routine should be consolidated with // ValidateLayouts. - skip |= ValidateRenderpassAttachmentUsage(dev_data, rp_version, pCreateInfo); + skip |= ValidateRenderpassAttachmentUsage(dev_data, pCreateInfo); render_pass->renderPass = VK_NULL_HANDLE; - skip |= CreatePassDAG(dev_data, rp_version, pCreateInfo, render_pass); - - // Validate multiview correlation and view masks - bool viewMaskZero = false; - bool viewMaskNonZero = false; - - for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { - const VkSubpassDescription2KHR &subpass = pCreateInfo->pSubpasses[i]; - if (subpass.viewMask != 0) { - viewMaskNonZero = true; - } else { - viewMaskZero = true; - } - - if ((subpass.flags & VK_SUBPASS_DESCRIPTION_PER_VIEW_POSITION_X_ONLY_BIT_NVX) != 0 && - (subpass.flags & VK_SUBPASS_DESCRIPTION_PER_VIEW_ATTRIBUTES_BIT_NVX) == 0) { - vuid = use_rp2 ? "VUID-VkSubpassDescription2KHR-flags-03076" : "VUID-VkSubpassDescription-flags-00856"; - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, - "%s: The flags parameter of subpass description %u includes " - "VK_SUBPASS_DESCRIPTION_PER_VIEW_POSITION_X_ONLY_BIT_NVX but does not also include " - "VK_SUBPASS_DESCRIPTION_PER_VIEW_ATTRIBUTES_BIT_NVX.", - function_name, i); - } - } - - if (rp_version == RENDER_PASS_VERSION_2) { - if (viewMaskNonZero && viewMaskZero) { - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, - "VUID-VkRenderPassCreateInfo2KHR-viewMask-03058", - "%s: Some view masks are non-zero whilst others are zero.", function_name); - } - - if (viewMaskZero && pCreateInfo->correlatedViewMaskCount != 0) { - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, - "VUID-VkRenderPassCreateInfo2KHR-viewMask-03057", - "%s: Multiview is not enabled but correlation masks are still provided", function_name); - } - } - uint32_t aggregated_cvms = 0; - for (uint32_t i = 0; i < pCreateInfo->correlatedViewMaskCount; ++i) { - if (aggregated_cvms & pCreateInfo->pCorrelatedViewMasks[i]) { - vuid = use_rp2 ? "VUID-VkRenderPassCreateInfo2KHR-pCorrelatedViewMasks-03056" - : "VUID-VkRenderPassMultiviewCreateInfo-pCorrelationMasks-00841"; - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, - "%s: pCorrelatedViewMasks[%u] contains a previously appearing view bit.", function_name, i); - } - aggregated_cvms |= pCreateInfo->pCorrelatedViewMasks[i]; - } + skip |= CreatePassDAG(dev_data, pCreateInfo, render_pass); for (uint32_t i = 0; i < pCreateInfo->dependencyCount; ++i) { auto const &dependency = pCreateInfo->pDependencies[i]; - if (rp_version == RENDER_PASS_VERSION_2) { - skip |= ValidateStageMaskGsTsEnables( - dev_data, dependency.srcStageMask, function_name, "VUID-VkSubpassDependency2KHR-srcStageMask-03080", - "VUID-VkSubpassDependency2KHR-srcStageMask-03082", "VUID-VkSubpassDependency-srcStageMask-02103", - "VUID-VkSubpassDependency-srcStageMask-02104"); - skip |= ValidateStageMaskGsTsEnables( - dev_data, dependency.dstStageMask, function_name, "VUID-VkSubpassDependency2KHR-dstStageMask-03081", - "VUID-VkSubpassDependency2KHR-dstStageMask-03083", "VUID-VkSubpassDependency-srcStageMask-02105", - "VUID-VkSubpassDependency-srcStageMask-02106"); - } else { - skip |= ValidateStageMaskGsTsEnables( - dev_data, dependency.srcStageMask, function_name, "VUID-VkSubpassDependency-srcStageMask-00860", - "VUID-VkSubpassDependency-srcStageMask-00862", "VUID-VkSubpassDependency-srcStageMask-02099", - "VUID-VkSubpassDependency-srcStageMask-02100"); - skip |= ValidateStageMaskGsTsEnables( - dev_data, dependency.dstStageMask, function_name, "VUID-VkSubpassDependency-dstStageMask-00861", - "VUID-VkSubpassDependency-dstStageMask-00863", "VUID-VkSubpassDependency-dstStageMask-02101", - "VUID-VkSubpassDependency-dstStageMask-02102"); - } + skip |= ValidateStageMaskGsTsEnables( + dev_data, dependency.srcStageMask, "vkCreateRenderPass()", "VUID-VkSubpassDependency-srcStageMask-00860", + "VUID-VkSubpassDependency-srcStageMask-00862", "VUID-VkSubpassDependency-srcStageMask-02099", + "VUID-VkSubpassDependency-srcStageMask-02100"); + skip |= ValidateStageMaskGsTsEnables( + dev_data, dependency.dstStageMask, "vkCreateRenderPass()", "VUID-VkSubpassDependency-dstStageMask-00861", + "VUID-VkSubpassDependency-dstStageMask-00863", "VUID-VkSubpassDependency-dstStageMask-02101", + "VUID-VkSubpassDependency-dstStageMask-02102"); if (!ValidateAccessMaskPipelineStage(dependency.srcAccessMask, dependency.srcStageMask)) { - vuid = use_rp2 ? "VUID-VkSubpassDependency2KHR-srcAccessMask-03088" : "VUID-VkSubpassDependency-srcAccessMask-00868"; - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, - "%s: pDependencies[%u].srcAccessMask (0x%" PRIx32 ") is not supported by srcStageMask (0x%" PRIx32 ").", - function_name, i, dependency.srcAccessMask, dependency.srcStageMask); + skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, + "VUID-VkSubpassDependency-srcAccessMask-00868", + "CreateRenderPass: pDependencies[%u].srcAccessMask (0x%X) is not supported by srcStageMask (0x%X).", i, + dependency.srcAccessMask, dependency.srcStageMask); } if (!ValidateAccessMaskPipelineStage(dependency.dstAccessMask, dependency.dstStageMask)) { - vuid = use_rp2 ? "VUID-VkSubpassDependency2KHR-dstAccessMask-03089" : "VUID-VkSubpassDependency-dstAccessMask-00869"; - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, - "%s: pDependencies[%u].dstAccessMask (0x%" PRIx32 ") is not supported by dstStageMask (0x%" PRIx32 ").", - function_name, i, dependency.dstAccessMask, dependency.dstStageMask); - } - } - if (!skip) { - skip |= ValidateLayouts(dev_data, rp_version, device, pCreateInfo); - } - return skip; -} - -static bool PreCallValidateCreateRenderPass(const layer_data *dev_data, VkDevice device, const VkRenderPassCreateInfo *pCreateInfo, - RENDER_PASS_STATE *render_pass) { - bool skip = false; - // Handle extension structs from KHR_multiview and KHR_maintenance2 that can only be validated for RP1 (indices out of bounds) - const VkRenderPassMultiviewCreateInfo *pMultiviewInfo = lvl_find_in_chain(pCreateInfo->pNext); - if (pMultiviewInfo) { - if (pMultiviewInfo->subpassCount && pMultiviewInfo->subpassCount != pCreateInfo->subpassCount) { skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, - "VUID-VkRenderPassCreateInfo-pNext-01928", - "Subpass count is %u but multiview info has a subpass count of %u.", pCreateInfo->subpassCount, - pMultiviewInfo->subpassCount); - } else if (pMultiviewInfo->dependencyCount && pMultiviewInfo->dependencyCount != pCreateInfo->dependencyCount) { - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, - "VUID-VkRenderPassCreateInfo-pNext-01929", - "Dependency count is %u but multiview info has a dependency count of %u.", pCreateInfo->dependencyCount, - pMultiviewInfo->dependencyCount); - } - } - const VkRenderPassInputAttachmentAspectCreateInfo *pInputAttachmentAspectInfo = - lvl_find_in_chain(pCreateInfo->pNext); - if (pInputAttachmentAspectInfo) { - for (uint32_t i = 0; i < pInputAttachmentAspectInfo->aspectReferenceCount; ++i) { - uint32_t subpass = pInputAttachmentAspectInfo->pAspectReferences[i].subpass; - uint32_t attachment = pInputAttachmentAspectInfo->pAspectReferences[i].inputAttachmentIndex; - if (subpass >= pCreateInfo->subpassCount) { - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, - "VUID-VkRenderPassCreateInfo-pNext-01926", - "Subpass index %u specified by input attachment aspect info %u is greater than the subpass " - "count of %u for this render pass.", - subpass, i, pCreateInfo->subpassCount); - } else if (pCreateInfo->pSubpasses && attachment >= pCreateInfo->pSubpasses[subpass].inputAttachmentCount) { - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, - "VUID-VkRenderPassCreateInfo-pNext-01927", - "Input attachment index %u specified by input attachment aspect info %u is greater than the " - "input attachment count of %u for this subpass.", - attachment, i, pCreateInfo->pSubpasses[subpass].inputAttachmentCount); - } + "VUID-VkSubpassDependency-dstAccessMask-00869", + "CreateRenderPass: pDependencies[%u].dstAccessMask (0x%X) is not supported by dstStageMask (0x%X).", i, + dependency.dstAccessMask, dependency.dstStageMask); } } - if (!skip) { - skip |= ValidateCreateRenderPass(dev_data, device, RENDER_PASS_VERSION_1, render_pass->createInfo.ptr(), render_pass); + skip |= ValidateLayouts(dev_data, device, pCreateInfo); } return skip; } @@ -10549,12 +10155,12 @@ static bool PreCallValidateCreateRenderPass(const layer_data *dev_data, VkDevice // Use of rvalue reference exceeds reccommended usage of rvalue refs in google style guide, but intentionally forces caller to move // or copy. This is clearer than passing a pointer to shared_ptr and avoids the atomic increment/decrement of shared_ptr copy // construction or assignment. -static void PostCallRecordCreateRenderPass(layer_data *dev_data, const VkRenderPass render_pass_handle, +static void PostCallRecordCreateRenderPass(layer_data *dev_data, const VkRenderPassCreateInfo *pCreateInfo, + const VkRenderPass render_pass_handle, std::shared_ptr &&render_pass) { render_pass->renderPass = render_pass_handle; - auto pCreateInfo = render_pass->createInfo.ptr(); for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { - const VkSubpassDescription2KHR &subpass = pCreateInfo->pSubpasses[i]; + const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[i]; for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) { MarkAttachmentFirstUse(render_pass.get(), subpass.pColorAttachments[j].attachment, false); @@ -10578,13 +10184,11 @@ static void PostCallRecordCreateRenderPass(layer_data *dev_data, const VkRenderP VKAPI_ATTR VkResult VKAPI_CALL CreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) { bool skip = false; - layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); // If we fail, this will act like a unique_ptr and auto-cleanup, as we aren't saving it anywhere auto render_pass = std::make_shared(pCreateInfo); unique_lock_t lock(global_lock); - skip = PreCallValidateCreateRenderPass(dev_data, device, pCreateInfo, render_pass.get()); lock.unlock(); @@ -10596,38 +10200,7 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateRenderPass(VkDevice device, const VkRenderP if (VK_SUCCESS == result) { lock.lock(); - PostCallRecordCreateRenderPass(dev_data, *pRenderPass, std::move(render_pass)); - } - return result; -} - -static bool PreCallValidateCreateRenderPass2KHR(const layer_data *dev_data, VkDevice device, - const VkRenderPassCreateInfo2KHR *pCreateInfo, RENDER_PASS_STATE *render_pass) { - return ValidateCreateRenderPass(dev_data, device, RENDER_PASS_VERSION_2, pCreateInfo, render_pass); -} - -VKAPI_ATTR VkResult VKAPI_CALL CreateRenderPass2KHR(VkDevice device, const VkRenderPassCreateInfo2KHR *pCreateInfo, - const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) { - bool skip = false; - - layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); - // If we fail, this will act like a unique_ptr and auto-cleanup, as we aren't saving it anywhere - auto render_pass = std::make_shared(pCreateInfo); - - unique_lock_t lock(global_lock); - - skip = PreCallValidateCreateRenderPass2KHR(dev_data, device, pCreateInfo, render_pass.get()); - lock.unlock(); - - if (skip) { - return VK_ERROR_VALIDATION_FAILED_EXT; - } - - VkResult result = dev_data->dispatch_table.CreateRenderPass2KHR(device, pCreateInfo, pAllocator, pRenderPass); - - if (VK_SUCCESS == result) { - lock.lock(); - PostCallRecordCreateRenderPass(dev_data, *pRenderPass, std::move(render_pass)); + PostCallRecordCreateRenderPass(dev_data, pCreateInfo, *pRenderPass, std::move(render_pass)); } return result; } @@ -10676,49 +10249,14 @@ static bool FormatSpecificLoadAndStoreOpSettings(VkFormat format, T color_depth_ return ((check_color_depth_load_op && (color_depth_op == op)) || (check_stencil_load_op && (stencil_op == op))); } -static bool PreCallValidateCmdBeginRenderPass(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, RenderPassCreateVersion rp_version, +static bool PreCallValidateCmdBeginRenderPass(layer_data *dev_data, const RENDER_PASS_STATE *render_pass_state, + GLOBAL_CB_NODE *cb_state, const FRAMEBUFFER_STATE *framebuffer, const VkRenderPassBeginInfo *pRenderPassBegin) { - auto render_pass_state = pRenderPassBegin ? GetRenderPassState(dev_data, pRenderPassBegin->renderPass) : nullptr; - auto framebuffer = pRenderPassBegin ? GetFramebufferState(dev_data, pRenderPassBegin->framebuffer) : nullptr; - assert(cb_state); bool skip = false; - const bool use_rp2 = (rp_version == RENDER_PASS_VERSION_2); - const char *vuid; - const char *const function_name = use_rp2 ? "vkCmdBeginRenderPass2KHR()" : "vkCmdBeginRenderPass()"; - if (render_pass_state) { uint32_t clear_op_size = 0; // Make sure pClearValues is at least as large as last LOAD_OP_CLEAR - // Handle extension struct from EXT_sample_locations - const VkRenderPassSampleLocationsBeginInfoEXT *pSampleLocationsBeginInfo = - lvl_find_in_chain(pRenderPassBegin->pNext); - if (pSampleLocationsBeginInfo) { - for (uint32_t i = 0; i < pSampleLocationsBeginInfo->attachmentInitialSampleLocationsCount; ++i) { - if (pSampleLocationsBeginInfo->pAttachmentInitialSampleLocations[i].attachmentIndex >= - render_pass_state->createInfo.attachmentCount) { - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, - 0, "VUID-VkAttachmentSampleLocationsEXT-attachmentIndex-01531", - "Attachment index %u specified by attachment sample locations %u is greater than the " - "attachment count of %u for the render pass being begun.", - pSampleLocationsBeginInfo->pAttachmentInitialSampleLocations[i].attachmentIndex, i, - render_pass_state->createInfo.attachmentCount); - } - } - - for (uint32_t i = 0; i < pSampleLocationsBeginInfo->postSubpassSampleLocationsCount; ++i) { - if (pSampleLocationsBeginInfo->pPostSubpassSampleLocations[i].subpassIndex >= - render_pass_state->createInfo.subpassCount) { - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, - 0, "VUID-VkSubpassSampleLocationsEXT-subpassIndex-01532", - "Subpass index %u specified by subpass sample locations %u is greater than the subpass count " - "of %u for the render pass being begun.", - pSampleLocationsBeginInfo->pPostSubpassSampleLocations[i].subpassIndex, i, - render_pass_state->createInfo.subpassCount); - } - } - } - for (uint32_t i = 0; i < render_pass_state->createInfo.attachmentCount; ++i) { auto pAttachment = &render_pass_state->createInfo.pAttachments[i]; if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->loadOp, pAttachment->stencilLoadOp, @@ -10730,45 +10268,36 @@ static bool PreCallValidateCmdBeginRenderPass(layer_data *dev_data, GLOBAL_CB_NO if (clear_op_size > pRenderPassBegin->clearValueCount) { skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, HandleToUint64(render_pass_state->renderPass), "VUID-VkRenderPassBeginInfo-clearValueCount-00902", - "In %s the VkRenderPassBeginInfo struct has a clearValueCount of %u but there " + "In vkCmdBeginRenderPass() the VkRenderPassBeginInfo struct has a clearValueCount of %u but there " "must be at least %u entries in pClearValues array to account for the highest index attachment in " "renderPass 0x%" PRIx64 " that uses VK_ATTACHMENT_LOAD_OP_CLEAR is %u. Note that the pClearValues array is indexed by " "attachment number so even if some pClearValues entries between 0 and %u correspond to attachments " "that aren't cleared they will be ignored.", - function_name, pRenderPassBegin->clearValueCount, clear_op_size, - HandleToUint64(render_pass_state->renderPass), clear_op_size, clear_op_size - 1); + pRenderPassBegin->clearValueCount, clear_op_size, HandleToUint64(render_pass_state->renderPass), + clear_op_size, clear_op_size - 1); } skip |= VerifyRenderAreaBounds(dev_data, pRenderPassBegin); - skip |= VerifyFramebufferAndRenderPassLayouts(dev_data, rp_version, cb_state, pRenderPassBegin, + skip |= VerifyFramebufferAndRenderPassLayouts(dev_data, cb_state, pRenderPassBegin, GetFramebufferState(dev_data, pRenderPassBegin->framebuffer)); if (framebuffer->rp_state->renderPass != render_pass_state->renderPass) { skip |= ValidateRenderPassCompatibility(dev_data, "render pass", render_pass_state, "framebuffer", - framebuffer->rp_state.get(), function_name, + framebuffer->rp_state.get(), "vkCmdBeginRenderPass()", "VUID-VkRenderPassBeginInfo-renderPass-00904"); } - - vuid = use_rp2 ? "VUID-vkCmdBeginRenderPass2KHR-renderpass" : "VUID-vkCmdBeginRenderPass-renderpass"; - skip |= InsideRenderPass(dev_data, cb_state, function_name, vuid); + skip |= InsideRenderPass(dev_data, cb_state, "vkCmdBeginRenderPass()", "VUID-vkCmdBeginRenderPass-renderpass"); skip |= ValidateDependencies(dev_data, framebuffer, render_pass_state); - - vuid = use_rp2 ? "VUID-vkCmdBeginRenderPass2KHR-bufferlevel" : "VUID-vkCmdBeginRenderPass-bufferlevel"; - skip |= ValidatePrimaryCommandBuffer(dev_data, cb_state, function_name, vuid); - - vuid = use_rp2 ? "VUID-vkCmdBeginRenderPass2KHR-commandBuffer-cmdpool" : "VUID-vkCmdBeginRenderPass-commandBuffer-cmdpool"; - skip |= ValidateCmdQueueFlags(dev_data, cb_state, function_name, VK_QUEUE_GRAPHICS_BIT, vuid); - - const CMD_TYPE cmd_type = use_rp2 ? CMD_BEGINRENDERPASS2KHR : CMD_BEGINRENDERPASS; - skip |= ValidateCmd(dev_data, cb_state, cmd_type, function_name); + skip |= ValidatePrimaryCommandBuffer(dev_data, cb_state, "vkCmdBeginRenderPass()", "VUID-vkCmdBeginRenderPass-bufferlevel"); + skip |= ValidateCmdQueueFlags(dev_data, cb_state, "vkCmdBeginRenderPass()", VK_QUEUE_GRAPHICS_BIT, + "VUID-vkCmdBeginRenderPass-commandBuffer-cmdpool"); + skip |= ValidateCmd(dev_data, cb_state, CMD_BEGINRENDERPASS, "vkCmdBeginRenderPass()"); } return skip; } -static void PreCallRecordCmdBeginRenderPass(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, - const VkRenderPassBeginInfo *pRenderPassBegin, const VkSubpassContents contents) { - auto render_pass_state = pRenderPassBegin ? GetRenderPassState(dev_data, pRenderPassBegin->renderPass) : nullptr; - auto framebuffer = pRenderPassBegin ? GetFramebufferState(dev_data, pRenderPassBegin->framebuffer) : nullptr; - +static void PreCallRecordCmdBeginRenderPass(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, FRAMEBUFFER_STATE *framebuffer, + RENDER_PASS_STATE *render_pass_state, const VkRenderPassBeginInfo *pRenderPassBegin, + const VkSubpassContents contents) { assert(cb_state); if (render_pass_state) { cb_state->activeFramebuffer = pRenderPassBegin->framebuffer; @@ -10794,63 +10323,33 @@ VKAPI_ATTR void VKAPI_CALL CmdBeginRenderPass(VkCommandBuffer commandBuffer, con layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); unique_lock_t lock(global_lock); GLOBAL_CB_NODE *cb_state = GetCBNode(dev_data, commandBuffer); + auto render_pass_state = pRenderPassBegin ? GetRenderPassState(dev_data, pRenderPassBegin->renderPass) : nullptr; + auto framebuffer = pRenderPassBegin ? GetFramebufferState(dev_data, pRenderPassBegin->framebuffer) : nullptr; if (cb_state) { - skip |= PreCallValidateCmdBeginRenderPass(dev_data, cb_state, RENDER_PASS_VERSION_1, pRenderPassBegin); + skip |= PreCallValidateCmdBeginRenderPass(dev_data, render_pass_state, cb_state, framebuffer, pRenderPassBegin); if (!skip) { - PreCallRecordCmdBeginRenderPass(dev_data, cb_state, pRenderPassBegin, contents); + PreCallRecordCmdBeginRenderPass(dev_data, cb_state, framebuffer, render_pass_state, pRenderPassBegin, contents); } } - lock.unlock(); if (!skip) { dev_data->dispatch_table.CmdBeginRenderPass(commandBuffer, pRenderPassBegin, contents); } } -VKAPI_ATTR void VKAPI_CALL CmdBeginRenderPass2KHR(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo *pRenderPassBegin, - const VkSubpassBeginInfoKHR *pSubpassBeginInfo) { - bool skip = false; - layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); - unique_lock_t lock(global_lock); - GLOBAL_CB_NODE *cb_state = GetCBNode(dev_data, commandBuffer); - if (cb_state) { - skip |= PreCallValidateCmdBeginRenderPass(dev_data, cb_state, RENDER_PASS_VERSION_2, pRenderPassBegin); - if (!skip) { - PreCallRecordCmdBeginRenderPass(dev_data, cb_state, pRenderPassBegin, pSubpassBeginInfo->contents); - } - } - - lock.unlock(); - if (!skip) { - dev_data->dispatch_table.CmdBeginRenderPass(commandBuffer, pRenderPassBegin, pSubpassBeginInfo->contents); - } -} - -static bool PreCallValidateCmdNextSubpass(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, RenderPassCreateVersion rp_version, - VkCommandBuffer commandBuffer) { - bool skip = false; - const bool use_rp2 = (rp_version == RENDER_PASS_VERSION_2); - const char *vuid; - const char *const function_name = use_rp2 ? "vkCmdNextSubpass2KHR()" : "vkCmdNextSubpass()"; - - vuid = use_rp2 ? "VUID-vkCmdNextSubpass2KHR-bufferlevel" : "VUID-vkCmdNextSubpass-bufferlevel"; - skip |= ValidatePrimaryCommandBuffer(dev_data, cb_state, function_name, vuid); - - vuid = use_rp2 ? "VUID-vkCmdNextSubpass2KHR-commandBuffer-cmdpool" : "VUID-vkCmdNextSubpass-commandBuffer-cmdpool"; - skip |= ValidateCmdQueueFlags(dev_data, cb_state, function_name, VK_QUEUE_GRAPHICS_BIT, vuid); - const CMD_TYPE cmd_type = use_rp2 ? CMD_NEXTSUBPASS2KHR : CMD_NEXTSUBPASS; - skip |= ValidateCmd(dev_data, cb_state, cmd_type, function_name); - - vuid = use_rp2 ? "VUID-vkCmdNextSubpass2KHR-renderpass" : "VUID-vkCmdNextSubpass-renderpass"; - skip |= OutsideRenderPass(dev_data, cb_state, function_name, vuid); +static bool PreCallValidateCmdNextSubpass(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, VkCommandBuffer commandBuffer) { + bool skip = ValidatePrimaryCommandBuffer(dev_data, cb_state, "vkCmdNextSubpass()", "VUID-vkCmdNextSubpass-bufferlevel"); + skip |= ValidateCmdQueueFlags(dev_data, cb_state, "vkCmdNextSubpass()", VK_QUEUE_GRAPHICS_BIT, + "VUID-vkCmdNextSubpass-commandBuffer-cmdpool"); + skip |= ValidateCmd(dev_data, cb_state, CMD_NEXTSUBPASS, "vkCmdNextSubpass()"); + skip |= OutsideRenderPass(dev_data, cb_state, "vkCmdNextSubpass()", "VUID-vkCmdNextSubpass-renderpass"); auto subpassCount = cb_state->activeRenderPass->createInfo.subpassCount; if (cb_state->activeSubpass == subpassCount - 1) { - vuid = use_rp2 ? "VUID-vkCmdNextSubpass2KHR-None-03102" : "VUID-vkCmdNextSubpass-None-00909"; skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, - HandleToUint64(commandBuffer), vuid, "%s: Attempted to advance beyond final subpass.", function_name); + HandleToUint64(commandBuffer), "VUID-vkCmdNextSubpass-None-00909", + "vkCmdNextSubpass(): Attempted to advance beyond final subpass."); } - return skip; } @@ -10867,7 +10366,7 @@ VKAPI_ATTR void VKAPI_CALL CmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpa unique_lock_t lock(global_lock); GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); if (pCB) { - skip |= PreCallValidateCmdNextSubpass(dev_data, pCB, RENDER_PASS_VERSION_1, commandBuffer); + skip |= PreCallValidateCmdNextSubpass(dev_data, pCB, commandBuffer); } lock.unlock(); @@ -10881,54 +10380,21 @@ VKAPI_ATTR void VKAPI_CALL CmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpa } } -VKAPI_ATTR void VKAPI_CALL CmdNextSubpass2KHR(VkCommandBuffer commandBuffer, const VkSubpassBeginInfoKHR *pSubpassBeginInfo, - const VkSubpassEndInfoKHR *pSubpassEndInfo) { - bool skip = false; - layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); - unique_lock_t lock(global_lock); - GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); - if (pCB) { - skip |= PreCallValidateCmdNextSubpass(dev_data, pCB, RENDER_PASS_VERSION_2, commandBuffer); - } - lock.unlock(); - - if (skip) return; - - dev_data->dispatch_table.CmdNextSubpass(commandBuffer, pSubpassBeginInfo->contents); - - if (pCB) { - lock.lock(); - PostCallRecordCmdNextSubpass(dev_data, pCB, pSubpassBeginInfo->contents); - } -} -static bool PreCallValidateCmdEndRenderPass(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, RenderPassCreateVersion rp_version, - VkCommandBuffer commandBuffer) { +static bool PreCallValidateCmdEndRenderPass(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, VkCommandBuffer commandBuffer) { bool skip = false; - - const bool use_rp2 = (rp_version == RENDER_PASS_VERSION_2); - const char *vuid; - const char *const function_name = use_rp2 ? "vkCmdEndRenderPass2KHR()" : "vkCmdEndRenderPass()"; - RENDER_PASS_STATE *rp_state = cb_state->activeRenderPass; if (rp_state) { if (cb_state->activeSubpass != rp_state->createInfo.subpassCount - 1) { - vuid = use_rp2 ? "VUID-vkCmdEndRenderPass2KHR-None-03103" : "VUID-vkCmdEndRenderPass-None-00910"; skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, - HandleToUint64(commandBuffer), vuid, "%s: Called before reaching final subpass.", function_name); + HandleToUint64(commandBuffer), "VUID-vkCmdEndRenderPass-None-00910", + "vkCmdEndRenderPass(): Called before reaching final subpass."); } } - - vuid = use_rp2 ? "VUID-vkCmdEndRenderPass2KHR-renderpass" : "VUID-vkCmdEndRenderPass-renderpass"; - skip |= OutsideRenderPass(dev_data, cb_state, function_name, vuid); - - vuid = use_rp2 ? "VUID-vkCmdEndRenderPass2KHR-bufferlevel" : "VUID-vkCmdEndRenderPass-bufferlevel"; - skip |= ValidatePrimaryCommandBuffer(dev_data, cb_state, function_name, vuid); - - vuid = use_rp2 ? "VUID-vkCmdEndRenderPass2KHR-commandBuffer-cmdpool" : "VUID-vkCmdEndRenderPass-commandBuffer-cmdpool"; - skip |= ValidateCmdQueueFlags(dev_data, cb_state, function_name, VK_QUEUE_GRAPHICS_BIT, vuid); - - const CMD_TYPE cmd_type = use_rp2 ? CMD_ENDRENDERPASS2KHR : CMD_ENDRENDERPASS; - skip |= ValidateCmd(dev_data, cb_state, cmd_type, function_name); + skip |= OutsideRenderPass(dev_data, cb_state, "vkCmdEndRenderpass()", "VUID-vkCmdEndRenderPass-renderpass"); + skip |= ValidatePrimaryCommandBuffer(dev_data, cb_state, "vkCmdEndRenderPass()", "VUID-vkCmdEndRenderPass-bufferlevel"); + skip |= ValidateCmdQueueFlags(dev_data, cb_state, "vkCmdEndRenderPass()", VK_QUEUE_GRAPHICS_BIT, + "VUID-vkCmdEndRenderPass-commandBuffer-cmdpool"); + skip |= ValidateCmd(dev_data, cb_state, CMD_ENDRENDERPASS, "vkCmdEndRenderPass()"); return skip; } @@ -10946,27 +10412,7 @@ VKAPI_ATTR void VKAPI_CALL CmdEndRenderPass(VkCommandBuffer commandBuffer) { unique_lock_t lock(global_lock); auto pCB = GetCBNode(dev_data, commandBuffer); if (pCB) { - skip |= PreCallValidateCmdEndRenderPass(dev_data, pCB, RENDER_PASS_VERSION_1, commandBuffer); - } - lock.unlock(); - - if (skip) return; - - dev_data->dispatch_table.CmdEndRenderPass(commandBuffer); - - if (pCB) { - lock.lock(); - PostCallRecordCmdEndRenderPass(dev_data, pCB); - } -} - -VKAPI_ATTR void VKAPI_CALL CmdEndRenderPass2KHR(VkCommandBuffer commandBuffer, const VkSubpassEndInfoKHR *pSubpassEndInfo) { - bool skip = false; - layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); - unique_lock_t lock(global_lock); - auto pCB = GetCBNode(dev_data, commandBuffer); - if (pCB) { - skip |= PreCallValidateCmdEndRenderPass(dev_data, pCB, RENDER_PASS_VERSION_2, commandBuffer); + skip |= PreCallValidateCmdEndRenderPass(dev_data, pCB, commandBuffer); } lock.unlock(); @@ -14920,10 +14366,6 @@ static const std::unordered_map name_to_funcptr_map = { {"vkCmdDrawMeshTasksIndirectNV", (void *)CmdDrawMeshTasksIndirectNV}, {"vkCmdDrawMeshTasksIndirectCountNV", (void *)CmdDrawMeshTasksIndirectCountNV}, {"vkCreateRaytracingPipelinesNVX", (void *)CreateRaytracingPipelinesNVX}, - {"vkCreateRenderPass2KHR", (void *)CreateRenderPass2KHR}, - {"vkCmdBeginRenderPass2KHR", (void *)CmdBeginRenderPass2KHR}, - {"vkCmdNextSubpass2KHR", (void *)CmdNextSubpass2KHR}, - {"vkCmdEndRenderPass2KHR", (void *)CmdEndRenderPass2KHR}, }; VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char *funcName) { diff --git a/layers/core_validation_types.h b/layers/core_validation_types.h index d90f503630e..f471d24077f 100644 --- a/layers/core_validation_types.h +++ b/layers/core_validation_types.h @@ -29,7 +29,6 @@ #include "vk_layer_logging.h" #include "vk_object_types.h" #include "vk_extension_helper.h" -#include "convert_to_renderpass2.h" #include #include #include @@ -414,13 +413,12 @@ struct DAGNode { struct RENDER_PASS_STATE : public BASE_NODE { VkRenderPass renderPass; - safe_VkRenderPassCreateInfo2KHR createInfo; + safe_VkRenderPassCreateInfo createInfo; std::vector> self_dependencies; std::vector subpassToNode; std::unordered_map attachment_first_read; - RENDER_PASS_STATE(VkRenderPassCreateInfo2KHR const *pCreateInfo) : createInfo(pCreateInfo) {} - RENDER_PASS_STATE(VkRenderPassCreateInfo const *pCreateInfo) { ConvertVkRenderPassCreateInfoToV2KHR(pCreateInfo, &createInfo); } + RENDER_PASS_STATE(VkRenderPassCreateInfo const *pCreateInfo) : createInfo(pCreateInfo) {} }; // vkCmd tracking -- complete as of header 1.0.68 @@ -431,7 +429,6 @@ enum CMD_TYPE { CMD_NONE, CMD_BEGINQUERY, CMD_BEGINRENDERPASS, - CMD_BEGINRENDERPASS2KHR, CMD_BINDDESCRIPTORSETS, CMD_BINDINDEXBUFFER, CMD_BINDPIPELINE, @@ -466,11 +463,9 @@ enum CMD_TYPE { CMD_ENDCOMMANDBUFFER, // Should be the last command in any RECORDED cmd buffer CMD_ENDQUERY, CMD_ENDRENDERPASS, - CMD_ENDRENDERPASS2KHR, CMD_EXECUTECOMMANDS, CMD_FILLBUFFER, CMD_NEXTSUBPASS, - CMD_NEXTSUBPASS2KHR, CMD_PIPELINEBARRIER, CMD_PROCESSCOMMANDSNVX, CMD_PUSHCONSTANTS, @@ -1106,8 +1101,6 @@ struct DeviceFeatures { VkPhysicalDeviceInlineUniformBlockFeaturesEXT inline_uniform_block; }; -enum RenderPassCreateVersion { RENDER_PASS_VERSION_1 = 0, RENDER_PASS_VERSION_2 = 1 }; - // Fwd declarations of layer_data and helpers to look-up/validate state from layer_data maps namespace core_validation { struct layer_data; diff --git a/tests/layer_validation_tests.cpp b/tests/layer_validation_tests.cpp index a790f5c167c..511a95058ff 100644 --- a/tests/layer_validation_tests.cpp +++ b/tests/layer_validation_tests.cpp @@ -4874,9 +4874,9 @@ TEST_F(VkLayerTest, InvalidSecondaryCommandBufferBarrier) { }; VkSubpassDependency dep = {0, 0, + VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - VK_ACCESS_SHADER_WRITE_BIT, + VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_SHADER_WRITE_BIT, VK_DEPENDENCY_BY_REGION_BIT}; VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 1, subpasses, 1, &dep}; @@ -4930,7 +4930,7 @@ TEST_F(VkLayerTest, InvalidSecondaryCommandBufferBarrier) { vkBeginCommandBuffer(secondary.handle(), &cbbi); VkImageMemoryBarrier img_barrier = {}; img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - img_barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; + img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; img_barrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT; img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; @@ -4942,7 +4942,7 @@ TEST_F(VkLayerTest, InvalidSecondaryCommandBufferBarrier) { img_barrier.subresourceRange.baseMipLevel = 0; img_barrier.subresourceRange.layerCount = 1; img_barrier.subresourceRange.levelCount = 1; - vkCmdPipelineBarrier(secondary.handle(), VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + vkCmdPipelineBarrier(secondary.handle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier); secondary.end(); @@ -5302,9 +5302,9 @@ TEST_F(VkPositiveLayerTest, SecondaryCommandBufferBarrier) { }; VkSubpassDependency dep = {0, 0, + VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - VK_ACCESS_SHADER_WRITE_BIT, + VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_SHADER_WRITE_BIT, VK_DEPENDENCY_BY_REGION_BIT}; VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 1, subpasses, 1, &dep}; @@ -5356,13 +5356,13 @@ TEST_F(VkPositiveLayerTest, SecondaryCommandBufferBarrier) { VkMemoryBarrier mem_barrier = {}; mem_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; mem_barrier.pNext = NULL; - mem_barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; + mem_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; mem_barrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT; - vkCmdPipelineBarrier(secondary.handle(), VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + vkCmdPipelineBarrier(secondary.handle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 1, &mem_barrier, 0, nullptr, 0, nullptr); VkImageMemoryBarrier img_barrier = {}; img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - img_barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; + img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; img_barrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT; img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; @@ -5374,7 +5374,7 @@ TEST_F(VkPositiveLayerTest, SecondaryCommandBufferBarrier) { img_barrier.subresourceRange.baseMipLevel = 0; img_barrier.subresourceRange.layerCount = 1; img_barrier.subresourceRange.levelCount = 1; - vkCmdPipelineBarrier(secondary.handle(), VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + vkCmdPipelineBarrier(secondary.handle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier); secondary.end(); @@ -5590,20 +5590,18 @@ TEST_F(VkLayerTest, CreateRenderPassAttachments) { } // Test sample count mismatch between color buffers attachments[subpass.pColorAttachments[1].attachment].samples = VK_SAMPLE_COUNT_8_BIT; - m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSubpassDescription-pColorAttachments-01417"); + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkAttachmentDescription-samples-parameter"); err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); m_errorMonitor->VerifyFound(); if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr); attachments[subpass.pColorAttachments[1].attachment].samples = attachments[subpass.pColorAttachments[0].attachment].samples; // Test sample count mismatch between color buffers and depth buffer attachments[subpass.pDepthStencilAttachment->attachment].samples = VK_SAMPLE_COUNT_8_BIT; - subpass.colorAttachmentCount = 1; - m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSubpassDescription-pDepthStencilAttachment-01418"); + m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkAttachmentDescription-samples-parameter"); err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); m_errorMonitor->VerifyFound(); if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr); attachments[subpass.pDepthStencilAttachment->attachment].samples = attachments[subpass.pColorAttachments[0].attachment].samples; - subpass.colorAttachmentCount = (uint32_t)color.size(); // Test resolve attachment with UNUSED color attachment color[0].attachment = VK_ATTACHMENT_UNUSED; m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSubpassDescription-pResolveAttachments-00847"); @@ -5613,15 +5611,13 @@ TEST_F(VkLayerTest, CreateRenderPassAttachments) { color[0].attachment = 1; // Test resolve from a single-sampled color attachment attachments[subpass.pColorAttachments[0].attachment].samples = VK_SAMPLE_COUNT_1_BIT; - subpass.colorAttachmentCount = 1; // avoid mismatch (00337), and avoid double report - subpass.pDepthStencilAttachment = nullptr; // avoid mismatch (01418) + attachments[subpass.pColorAttachments[1].attachment].samples = VK_SAMPLE_COUNT_1_BIT; // avoid mismatch (00337) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSubpassDescription-pResolveAttachments-00848"); err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); m_errorMonitor->VerifyFound(); if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr); attachments[subpass.pColorAttachments[0].attachment].samples = VK_SAMPLE_COUNT_4_BIT; - subpass.colorAttachmentCount = (uint32_t)color.size(); // avoid mismatch (00337), and avoid double report - subpass.pDepthStencilAttachment = &depth; + attachments[subpass.pColorAttachments[1].attachment].samples = VK_SAMPLE_COUNT_4_BIT; // Test resolve to a multi-sampled resolve attachment attachments[subpass.pResolveAttachments[0].attachment].samples = VK_SAMPLE_COUNT_4_BIT; m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSubpassDescription-pResolveAttachments-00849");