| /* |
| * Copyright (c) 2015-2026 The Khronos Group Inc. |
| * Copyright (c) 2015-2026 Valve Corporation |
| * Copyright (c) 2015-2026 LunarG, Inc. |
| * Copyright (c) 2015-2025 Google, Inc. |
| * Modifications Copyright (C) 2022 Advanced Micro Devices, Inc. All rights reserved. |
| * |
| * 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 |
| */ |
| |
| #include <vulkan/vulkan_core.h> |
| #include "../framework/layer_validation_tests.h" |
| #include "../framework/pipeline_helper.h" |
| #include "../framework/render_pass_helper.h" |
| |
| class NegativeFragmentShadingRate : public VkLayerTest { |
| public: |
| VkImageCreateInfo BasicFragmentDensityMapImage() { |
| VkImageCreateInfo image_create_info = vku::InitStructHelper(); |
| image_create_info.flags = VK_IMAGE_CREATE_FRAGMENT_DENSITY_MAP_OFFSET_BIT_EXT; |
| image_create_info.imageType = VK_IMAGE_TYPE_2D; |
| image_create_info.format = VK_FORMAT_R8G8_UNORM; |
| image_create_info.extent = {32u, 32u, 1u}; |
| image_create_info.mipLevels = 1u; |
| image_create_info.arrayLayers = 1u; |
| image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; |
| image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT; |
| image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| return image_create_info; |
| } |
| }; |
| |
| TEST_F(NegativeFragmentShadingRate, Values) { |
| TEST_DESCRIPTION("Specify invalid fragment shading rate values"); |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_1_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::pipelineFragmentShadingRate); |
| RETURN_IF_SKIP(Init()); |
| |
| VkExtent2D fragmentSize = {1, 1}; |
| VkFragmentShadingRateCombinerOpKHR combinerOps[2] = {VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR, |
| VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR}; |
| |
| m_command_buffer.Begin(); |
| fragmentSize.width = 0; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetFragmentShadingRateKHR-pFragmentSize-04513"); |
| vk::CmdSetFragmentShadingRateKHR(m_command_buffer, &fragmentSize, combinerOps); |
| m_errorMonitor->VerifyFound(); |
| fragmentSize.width = 1; |
| |
| fragmentSize.height = 0; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetFragmentShadingRateKHR-pFragmentSize-04514"); |
| vk::CmdSetFragmentShadingRateKHR(m_command_buffer, &fragmentSize, combinerOps); |
| m_errorMonitor->VerifyFound(); |
| fragmentSize.height = 1; |
| |
| fragmentSize.width = 3; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetFragmentShadingRateKHR-pFragmentSize-04515"); |
| vk::CmdSetFragmentShadingRateKHR(m_command_buffer, &fragmentSize, combinerOps); |
| m_errorMonitor->VerifyFound(); |
| fragmentSize.width = 1; |
| |
| fragmentSize.height = 3; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetFragmentShadingRateKHR-pFragmentSize-04516"); |
| vk::CmdSetFragmentShadingRateKHR(m_command_buffer, &fragmentSize, combinerOps); |
| m_errorMonitor->VerifyFound(); |
| fragmentSize.height = 1; |
| |
| fragmentSize.width = 8; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetFragmentShadingRateKHR-pFragmentSize-04517"); |
| vk::CmdSetFragmentShadingRateKHR(m_command_buffer, &fragmentSize, combinerOps); |
| m_errorMonitor->VerifyFound(); |
| fragmentSize.width = 1; |
| |
| fragmentSize.height = 8; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetFragmentShadingRateKHR-pFragmentSize-04518"); |
| vk::CmdSetFragmentShadingRateKHR(m_command_buffer, &fragmentSize, combinerOps); |
| m_errorMonitor->VerifyFound(); |
| fragmentSize.height = 1; |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, ValuesNoFeatures) { |
| TEST_DESCRIPTION("Specify invalid fsr pipeline settings for the enabled features"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_1_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| VkExtent2D fragmentSize = {1, 1}; |
| VkFragmentShadingRateCombinerOpKHR combinerOps[2] = {VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR, |
| VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR}; |
| |
| m_command_buffer.Begin(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetFragmentShadingRateKHR-pipelineFragmentShadingRate-04509"); |
| vk::CmdSetFragmentShadingRateKHR(m_command_buffer, &fragmentSize, combinerOps); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, CombinerOpsNoFeatures) { |
| TEST_DESCRIPTION("Specify combiner operations when only pipeline rate is supported"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_1_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::pipelineFragmentShadingRate); |
| |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| VkExtent2D fragmentSize = {1, 1}; |
| VkFragmentShadingRateCombinerOpKHR combinerOps[2] = {VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR, |
| VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR}; |
| |
| m_command_buffer.Begin(); |
| |
| combinerOps[0] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetFragmentShadingRateKHR-primitiveFragmentShadingRate-04510"); |
| vk::CmdSetFragmentShadingRateKHR(m_command_buffer, &fragmentSize, combinerOps); |
| m_errorMonitor->VerifyFound(); |
| combinerOps[0] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR; |
| |
| combinerOps[1] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetFragmentShadingRateKHR-attachmentFragmentShadingRate-04511"); |
| vk::CmdSetFragmentShadingRateKHR(m_command_buffer, &fragmentSize, combinerOps); |
| m_errorMonitor->VerifyFound(); |
| combinerOps[1] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR; |
| |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, CombinerOpsNoPipelineRate) { |
| TEST_DESCRIPTION("Specify pipeline rate when only attachment or primitive rate are supported"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_1_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::attachmentFragmentShadingRate); |
| AddRequiredFeature(vkt::Feature::primitiveFragmentShadingRate); |
| |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| VkExtent2D fragmentSize = {1, 1}; |
| VkFragmentShadingRateCombinerOpKHR combinerOps[2] = {VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR, |
| VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR}; |
| |
| m_command_buffer.Begin(); |
| fragmentSize.width = 2; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetFragmentShadingRateKHR-pipelineFragmentShadingRate-04507"); |
| vk::CmdSetFragmentShadingRateKHR(m_command_buffer, &fragmentSize, combinerOps); |
| m_errorMonitor->VerifyFound(); |
| fragmentSize.width = 1; |
| |
| fragmentSize.height = 2; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetFragmentShadingRateKHR-pipelineFragmentShadingRate-04508"); |
| vk::CmdSetFragmentShadingRateKHR(m_command_buffer, &fragmentSize, combinerOps); |
| m_errorMonitor->VerifyFound(); |
| fragmentSize.height = 1; |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, CombinerOpsLimit) { |
| TEST_DESCRIPTION("Specify invalid fsr pipeline settings for the enabled features"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_1_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::attachmentFragmentShadingRate); |
| AddRequiredFeature(vkt::Feature::primitiveFragmentShadingRate); |
| RETURN_IF_SKIP(Init()); |
| VkPhysicalDeviceFragmentShadingRatePropertiesKHR fsr_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fsr_properties); |
| |
| if (fsr_properties.fragmentShadingRateNonTrivialCombinerOps) { |
| GTEST_SKIP() << "requires fragmentShadingRateNonTrivialCombinerOps to be unsupported."; |
| } |
| InitRenderTarget(); |
| |
| VkExtent2D fragmentSize = {1, 1}; |
| VkFragmentShadingRateCombinerOpKHR combinerOps[2] = {VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR, |
| VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR}; |
| |
| m_command_buffer.Begin(); |
| { |
| // primitiveFragmentShadingRate |
| combinerOps[0] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_KHR; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetFragmentShadingRateKHR-fragmentSizeNonTrivialCombinerOps-04512"); |
| vk::CmdSetFragmentShadingRateKHR(m_command_buffer, &fragmentSize, combinerOps); |
| m_errorMonitor->VerifyFound(); |
| combinerOps[0] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR; |
| } |
| |
| { |
| // attachmentFragmentShadingRate |
| combinerOps[1] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_KHR; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetFragmentShadingRateKHR-fragmentSizeNonTrivialCombinerOps-04512"); |
| vk::CmdSetFragmentShadingRateKHR(m_command_buffer, &fragmentSize, combinerOps); |
| m_errorMonitor->VerifyFound(); |
| combinerOps[1] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR; |
| } |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, PrimitiveFragmentShadingRateWriteMultiViewportLimitDynamic) { |
| TEST_DESCRIPTION("Test dynamic validation of the primitiveFragmentShadingRateWithMultipleViewports limit"); |
| |
| // Enable KHR_fragment_shading_rate and all of its required extensions |
| AddRequiredExtensions(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME); |
| AddRequiredExtensions(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::multiViewport); |
| AddRequiredFeature(vkt::Feature::extendedDynamicState); |
| AddRequiredFeature(vkt::Feature::primitiveFragmentShadingRate); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDeviceFragmentShadingRatePropertiesKHR fsr_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fsr_properties); |
| |
| if (fsr_properties.primitiveFragmentShadingRateWithMultipleViewports) { |
| GTEST_SKIP() << "Test requires primitiveFragmentShadingRateWithMultipleViewports to be unsupported."; |
| } |
| InitRenderTarget(); |
| |
| const char* vsSource = R"glsl( |
| #version 450 |
| #extension GL_EXT_fragment_shading_rate : enable |
| void main() { |
| gl_PrimitiveShadingRateEXT = gl_ShadingRateFlag4VerticalPixelsEXT | gl_ShadingRateFlag4HorizontalPixelsEXT; |
| } |
| )glsl"; |
| VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT); |
| |
| CreatePipelineHelper pipe(*this); |
| pipe.shader_stages_[0] = vs.GetStageCreateInfo(); |
| pipe.vp_state_ci_.viewportCount = 0; |
| pipe.AddDynamicState(VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT); |
| pipe.CreateGraphicsPipeline(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| |
| VkViewport viewports[] = {{0, 0, 16, 16, 0, 1}, {1, 1, 16, 16, 0, 1}}; |
| vk::CmdSetViewportWithCountEXT(m_command_buffer, 2, viewports); |
| |
| // error produced here. |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-primitiveFragmentShadingRateWithMultipleViewports-04552"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, FragmentDensityMapReferences) { |
| TEST_DESCRIPTION("Create a subpass with the wrong attachment information for a fragment density map "); |
| |
| AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| AddOptionalExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME); |
| AddOptionalExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_2_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| |
| if (!IsExtensionsEnabled(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME) && |
| !IsExtensionsEnabled(VK_EXT_FRAGMENT_DENSITY_MAP_2_EXTENSION_NAME)) { |
| GTEST_SKIP() << "Extensions not supported"; |
| } |
| |
| VkAttachmentDescription attach = {0, |
| VK_FORMAT_R8G8_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_PREINITIALIZED, |
| VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT}; |
| // Set 1 instead of 0 |
| VkAttachmentReference ref = {1, VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT}; |
| VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr}; |
| auto rpfdmi = vku::InitStruct<VkRenderPassFragmentDensityMapCreateInfoEXT>(nullptr, ref); |
| |
| auto rpci = vku::InitStruct<VkRenderPassCreateInfo>(&rpfdmi, 0u, 1u, &attach, 1u, &subpass, 0u, nullptr); |
| |
| CreateRenderPassTest(rpci, false, "VUID-VkRenderPassCreateInfo-fragmentDensityMapAttachment-06471", nullptr); |
| |
| // Set wrong VkImageLayout |
| ref = {0, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL}; |
| subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr}; |
| rpfdmi = vku::InitStruct<VkRenderPassFragmentDensityMapCreateInfoEXT>(nullptr, ref); |
| rpci = vku::InitStruct<VkRenderPassCreateInfo>(&rpfdmi, 0u, 1u, &attach, 1u, &subpass, 0u, nullptr); |
| |
| CreateRenderPassTest(rpci, false, "VUID-VkRenderPassFragmentDensityMapCreateInfoEXT-fragmentDensityMapAttachment-02549", |
| nullptr); |
| |
| // Set wrong load operation |
| attach = {0, |
| VK_FORMAT_R8G8_UNORM, |
| VK_SAMPLE_COUNT_1_BIT, |
| VK_ATTACHMENT_LOAD_OP_CLEAR, |
| VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, |
| VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_IMAGE_LAYOUT_PREINITIALIZED, |
| VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT}; |
| |
| ref = {0, VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT}; |
| subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr}; |
| rpfdmi = vku::InitStruct<VkRenderPassFragmentDensityMapCreateInfoEXT>(nullptr, ref); |
| rpci = vku::InitStruct<VkRenderPassCreateInfo>(&rpfdmi, 0u, 1u, &attach, 1u, &subpass, 0u, nullptr); |
| |
| CreateRenderPassTest(rpci, false, "VUID-VkRenderPassFragmentDensityMapCreateInfoEXT-fragmentDensityMapAttachment-02550", |
| nullptr); |
| |
| // Set wrong store operation |
| attach = {0, |
| VK_FORMAT_R8G8_UNORM, |
| VK_SAMPLE_COUNT_1_BIT, |
| VK_ATTACHMENT_LOAD_OP_LOAD, |
| VK_ATTACHMENT_STORE_OP_STORE, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, |
| VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_IMAGE_LAYOUT_PREINITIALIZED, |
| VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT}; |
| |
| ref = {0, VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT}; |
| subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr}; |
| rpfdmi = vku::InitStruct<VkRenderPassFragmentDensityMapCreateInfoEXT>(nullptr, ref); |
| rpci = vku::InitStruct<VkRenderPassCreateInfo>(&rpfdmi, 0u, 1u, &attach, 1u, &subpass, 0u, nullptr); |
| |
| CreateRenderPassTest(rpci, false, "VUID-VkRenderPassFragmentDensityMapCreateInfoEXT-fragmentDensityMapAttachment-02551", |
| nullptr); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, FragmentDensityMapDuplicateReferences) { |
| /* Note: This test omits testing of depth attachments. The wording of |
| VUID-VkRenderPassFragmentDensityMapCreateInfoEXT-fragmentDensityMapAttachment-02548 states that they should be |
| covered but currently no depth formats are valid for use as fragment density map attachments. |
| */ |
| TEST_DESCRIPTION("Create a subpass with the attachment used as both fragment density map and another attachment"); |
| |
| AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| AddOptionalExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME); |
| AddOptionalExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_2_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| |
| if (!IsExtensionsEnabled(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME) && |
| !IsExtensionsEnabled(VK_EXT_FRAGMENT_DENSITY_MAP_2_EXTENSION_NAME)) { |
| GTEST_SKIP() << "Extensions not supported"; |
| } |
| |
| // Fragment density map attachment idx referenced in multiple places |
| VkFormat depth_stencil_format = FindSupportedDepthStencilFormat(Gpu()); |
| VkAttachmentDescription attachments[6] = { |
| // 0th: color attachment |
| {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_PREINITIALIZED, |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, |
| // 1st: depth-stencil attachment |
| {0, depth_stencil_format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_PREINITIALIZED, |
| VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}, |
| // 2nd: fdm |
| {0, VK_FORMAT_R8G8_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_PREINITIALIZED, |
| VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT}, |
| // 3rd: color preserve attachment |
| {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_PREINITIALIZED, |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, |
| // 4th: input attachment |
| {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_PREINITIALIZED, |
| VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL}, |
| }; |
| |
| VkAttachmentReference ref_input = {4, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL}; |
| VkAttachmentReference ref_color = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; |
| VkAttachmentReference ref_depth = {1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; |
| VkAttachmentReference ref_preserve = {3, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; |
| VkAttachmentReference ref_fdm = {2, VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT}; |
| |
| { |
| // FDM in input attachments |
| VkAttachmentReference ref_fail[2] = {ref_input, ref_fdm}; |
| VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 2, ref_fail, 1, &ref_color, nullptr, &ref_depth, |
| 1, &ref_preserve.attachment}; |
| auto rpfdmi = vku::InitStruct<VkRenderPassFragmentDensityMapCreateInfoEXT>(nullptr, ref_fdm); |
| auto rpci = vku::InitStruct<VkRenderPassCreateInfo>(&rpfdmi, 0u, 5u, attachments, 1u, &subpass, 0u, nullptr); |
| |
| CreateRenderPassTest(rpci, false, "VUID-VkRenderPassFragmentDensityMapCreateInfoEXT-fragmentDensityMapAttachment-02548", |
| nullptr); |
| } |
| |
| { |
| // FDM in color attachments |
| VkAttachmentReference ref_fail[2] = {ref_color, ref_fdm}; |
| VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &ref_input, 2, ref_fail, nullptr, &ref_depth, |
| 1, &ref_preserve.attachment}; |
| auto rpfdmi = vku::InitStruct<VkRenderPassFragmentDensityMapCreateInfoEXT>(nullptr, ref_fdm); |
| auto rpci = vku::InitStruct<VkRenderPassCreateInfo>(&rpfdmi, 0u, 5u, attachments, 1u, &subpass, 0u, nullptr); |
| |
| CreateRenderPassTest(rpci, false, "VUID-VkRenderPassFragmentDensityMapCreateInfoEXT-fragmentDensityMapAttachment-02548", |
| nullptr); |
| } |
| |
| { |
| // FDM as preserve attachment |
| uint32_t ref_fail[2] = {ref_preserve.attachment, ref_fdm.attachment}; |
| VkSubpassDescription subpass = { |
| 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &ref_input, 1, &ref_color, nullptr, &ref_depth, 2, ref_fail}; |
| auto rpfdmi = vku::InitStruct<VkRenderPassFragmentDensityMapCreateInfoEXT>(nullptr, ref_fdm); |
| auto rpci = vku::InitStruct<VkRenderPassCreateInfo>(&rpfdmi, 0u, 5u, attachments, 1u, &subpass, 0u, nullptr); |
| |
| CreateRenderPassTest(rpci, false, "VUID-VkRenderPassFragmentDensityMapCreateInfoEXT-fragmentDensityMapAttachment-02548", |
| nullptr); |
| } |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, FragmentDensityMapLayerCount) { |
| TEST_DESCRIPTION("Specify a fragment density map attachment with incorrect layerCount"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_MULTIVIEW_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::multiview); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMap); |
| RETURN_IF_SKIP(Init()); |
| |
| VkAttachmentDescription2 attach_desc = vku::InitStructHelper(); |
| attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM; |
| attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_GENERAL; |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| |
| VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT}; |
| auto rpfdmi = vku::InitStruct<VkRenderPassFragmentDensityMapCreateInfoEXT>(nullptr, ref); |
| |
| // Create a renderPass with viewMask 0 |
| VkSubpassDescription2 subpass = vku::InitStructHelper(); |
| subpass.viewMask = 0; |
| |
| VkRenderPassCreateInfo2 rpci = vku::InitStructHelper(&rpfdmi); |
| rpci.subpassCount = 1; |
| rpci.pSubpasses = &subpass; |
| rpci.attachmentCount = 1; |
| rpci.pAttachments = &attach_desc; |
| |
| vkt::RenderPass rp(*m_device, rpci); |
| |
| auto image_ci = vkt::Image::ImageCreateInfo2D(32, 32, 1, 2, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); |
| vkt::Image image(*m_device, image_ci); |
| vkt::ImageView imageView = image.CreateView(VK_IMAGE_VIEW_TYPE_2D_ARRAY, 0, VK_REMAINING_MIP_LEVELS, 0, 2); |
| |
| VkFramebufferCreateInfo fb_info = vku::InitStructHelper(); |
| fb_info.renderPass = rp; |
| fb_info.attachmentCount = 1; |
| fb_info.pAttachments = &imageView.handle(); |
| fb_info.width = 32; |
| fb_info.height = 32; |
| fb_info.layers = 1; |
| |
| VkFramebuffer fb; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkFramebufferCreateInfo-renderPass-02746"); |
| vk::CreateFramebuffer(device(), &fb_info, NULL, &fb); |
| m_errorMonitor->VerifyFound(); |
| |
| // Set viewMask to non-zero - requires multiview |
| subpass.viewMask = 0x10; |
| vkt::RenderPass rp_mv(*m_device, rpci); |
| |
| fb_info.renderPass = rp_mv; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkFramebufferCreateInfo-renderPass-02746"); |
| vk::CreateFramebuffer(device(), &fb_info, NULL, &fb); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, FragmentDensityMapEnabled) { |
| TEST_DESCRIPTION("Validation must check several conditions that apply only when Fragment Density Maps are used."); |
| |
| // VK_EXT_fragment_density_map2 requires VK_EXT_fragment_density_map |
| AddRequiredExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME); |
| AddOptionalExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_2_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitFramework()); |
| const bool fdm2Supported = IsExtensionsEnabled(VK_EXT_FRAGMENT_DENSITY_MAP_2_EXTENSION_NAME); |
| |
| VkPhysicalDeviceFragmentDensityMapFeaturesEXT density_map_features = vku::InitStructHelper(); |
| VkPhysicalDeviceFragmentDensityMap2FeaturesEXT density_map2_features = vku::InitStructHelper(&density_map_features); |
| VkPhysicalDeviceFeatures2KHR features2 = GetPhysicalDeviceFeatures2(density_map2_features); |
| |
| if (density_map_features.fragmentDensityMapDynamic == VK_FALSE) { |
| GTEST_SKIP() << "fragmentDensityMapDynamic not supported"; |
| } |
| |
| features2 = vku::InitStructHelper(&density_map2_features); |
| RETURN_IF_SKIP(InitState(nullptr, &features2)); |
| |
| VkPhysicalDeviceFragmentDensityMap2PropertiesEXT density_map2_properties = vku::InitStructHelper(); |
| auto properties2 = GetPhysicalDeviceProperties2(density_map2_properties); |
| |
| // Test sampler parameters |
| |
| VkSamplerCreateInfo sampler_info_ref = SafeSaneSamplerCreateInfo(); |
| sampler_info_ref.maxLod = 0.0; |
| sampler_info_ref.flags |= VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT; |
| VkSamplerCreateInfo sampler_info = sampler_info_ref; |
| |
| // min max filters must match |
| sampler_info.minFilter = VK_FILTER_LINEAR; |
| sampler_info.magFilter = VK_FILTER_NEAREST; |
| CreateSamplerTest(sampler_info, "VUID-VkSamplerCreateInfo-flags-02574"); |
| sampler_info.minFilter = sampler_info_ref.minFilter; |
| sampler_info.magFilter = sampler_info_ref.magFilter; |
| |
| // mipmapMode must be SAMPLER_MIPMAP_MODE_NEAREST |
| sampler_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; |
| CreateSamplerTest(sampler_info, "VUID-VkSamplerCreateInfo-flags-02575"); |
| sampler_info.mipmapMode = sampler_info_ref.mipmapMode; |
| |
| // minLod and maxLod must be 0.0 |
| sampler_info.minLod = 1.0; |
| sampler_info.maxLod = 1.0; |
| CreateSamplerTest(sampler_info, "VUID-VkSamplerCreateInfo-flags-02576"); |
| sampler_info.minLod = sampler_info_ref.minLod; |
| sampler_info.maxLod = sampler_info_ref.maxLod; |
| |
| // addressMode must be CLAMP_TO_EDGE or CLAMP_TO_BORDER |
| sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; |
| CreateSamplerTest(sampler_info, "VUID-VkSamplerCreateInfo-flags-02577"); |
| sampler_info.addressModeU = sampler_info_ref.addressModeU; |
| |
| sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; |
| CreateSamplerTest(sampler_info, "VUID-VkSamplerCreateInfo-flags-02577"); |
| sampler_info.addressModeV = sampler_info_ref.addressModeV; |
| |
| // some features cannot be enabled for subsampled samplers |
| if (features2.features.samplerAnisotropy == VK_TRUE) { |
| sampler_info.anisotropyEnable = VK_TRUE; |
| CreateSamplerTest(sampler_info, "VUID-VkSamplerCreateInfo-flags-02578"); |
| sampler_info.anisotropyEnable = sampler_info_ref.anisotropyEnable; |
| sampler_info.anisotropyEnable = VK_FALSE; |
| } |
| |
| sampler_info.compareEnable = VK_TRUE; |
| CreateSamplerTest(sampler_info, "VUID-VkSamplerCreateInfo-flags-02579"); |
| sampler_info.compareEnable = sampler_info_ref.compareEnable; |
| |
| sampler_info.unnormalizedCoordinates = VK_TRUE; |
| CreateSamplerTest(sampler_info, "VUID-VkSamplerCreateInfo-flags-02580"); |
| sampler_info.unnormalizedCoordinates = sampler_info_ref.unnormalizedCoordinates; |
| |
| // Test image parameters |
| |
| VkImageCreateInfo image_create_info = vku::InitStructHelper(); |
| image_create_info.imageType = VK_IMAGE_TYPE_2D; |
| image_create_info.format = VK_FORMAT_R8G8_UNORM; |
| image_create_info.extent = {64, 64, 1}; |
| image_create_info.mipLevels = 1; |
| image_create_info.arrayLayers = 1; |
| image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; |
| image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_create_info.usage = VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT; |
| image_create_info.flags = 0; |
| |
| // only VK_IMAGE_TYPE_2D is supported |
| image_create_info.imageType = VK_IMAGE_TYPE_1D; |
| image_create_info.extent.height = 1; |
| CreateImageTest(image_create_info, "VUID-VkImageCreateInfo-flags-02557"); |
| |
| // only VK_SAMPLE_COUNT_1_BIT is supported |
| image_create_info.imageType = VK_IMAGE_TYPE_2D; |
| image_create_info.samples = VK_SAMPLE_COUNT_4_BIT; |
| CreateImageTest(image_create_info, "VUID-VkImageCreateInfo-samples-02558"); |
| |
| // tiling must be VK_IMAGE_TILING_OPTIMAL |
| image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; |
| image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; |
| image_create_info.flags = VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT; |
| image_create_info.tiling = VK_IMAGE_TILING_LINEAR; |
| CreateImageTest(image_create_info, "VUID-VkImageCreateInfo-flags-02565"); |
| |
| // only 2D |
| image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_create_info.imageType = VK_IMAGE_TYPE_1D; |
| CreateImageTest(image_create_info, "VUID-VkImageCreateInfo-flags-02566"); |
| |
| // no cube maps |
| image_create_info.imageType = VK_IMAGE_TYPE_2D; |
| image_create_info.extent.height = 64; |
| image_create_info.arrayLayers = 6; |
| image_create_info.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; |
| CreateImageTest(image_create_info, "VUID-VkImageCreateInfo-flags-02567"); |
| |
| // mipLevels must be 1 |
| image_create_info.flags = VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT; |
| image_create_info.arrayLayers = 1; |
| image_create_info.mipLevels = 2; |
| CreateImageTest(image_create_info, "VUID-VkImageCreateInfo-flags-02568"); |
| |
| // Test image view parameters |
| |
| // create a valid density map image |
| image_create_info.flags = 0; |
| image_create_info.mipLevels = 1; |
| image_create_info.usage = VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT; |
| vkt::Image densityImage(*m_device, image_create_info, vkt::set_layout); |
| |
| VkImageViewCreateInfo ivci = vku::InitStructHelper(); |
| ivci.image = densityImage; |
| ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; |
| ivci.format = VK_FORMAT_R8G8_UNORM; |
| ivci.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; |
| |
| // density maps can't be sparse (or protected) |
| if (features2.features.sparseResidencyImage2D) { |
| image_create_info.flags = VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_BINDING_BIT; |
| image_create_info.usage = VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT; |
| vkt::Image image(*m_device, image_create_info, vkt::no_mem); |
| |
| ivci.image = image; |
| CreateImageViewTest(ivci, "VUID-VkImageViewCreateInfo-flags-04116"); |
| } |
| |
| if (fdm2Supported) { |
| if (!density_map2_features.fragmentDensityMapDeferred) { |
| ivci.flags = VK_IMAGE_VIEW_CREATE_FRAGMENT_DENSITY_MAP_DEFERRED_BIT_EXT; |
| ivci.image = densityImage; |
| CreateImageViewTest(ivci, "VUID-VkImageViewCreateInfo-flags-03567"); |
| } else { |
| ivci.flags = VK_IMAGE_VIEW_CREATE_FRAGMENT_DENSITY_MAP_DEFERRED_BIT_EXT; |
| ivci.flags |= VK_IMAGE_VIEW_CREATE_FRAGMENT_DENSITY_MAP_DYNAMIC_BIT_EXT; |
| ivci.image = densityImage; |
| CreateImageViewTest(ivci, "VUID-VkImageViewCreateInfo-flags-03568"); |
| } |
| if (density_map2_properties.maxSubsampledArrayLayers < properties2.properties.limits.maxImageArrayLayers) { |
| image_create_info.flags = VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT; |
| image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; |
| image_create_info.arrayLayers = density_map2_properties.maxSubsampledArrayLayers + 1; |
| vkt::Image image(*m_device, image_create_info, vkt::set_layout); |
| ivci.image = image; |
| ivci.flags = 0; |
| ivci.subresourceRange.layerCount = density_map2_properties.maxSubsampledArrayLayers + 1; |
| m_errorMonitor->SetUnexpectedError("VUID-VkImageViewCreateInfo-imageViewType-04973"); |
| CreateImageViewTest(ivci, "VUID-VkImageViewCreateInfo-image-03569"); |
| } |
| } |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, FragmentDensityMapDisabled) { |
| TEST_DESCRIPTION("Checks for when the fragment density map features are not enabled."); |
| |
| // VK_EXT_fragment_density_map2 requires VK_EXT_fragment_density_map |
| AddRequiredExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| |
| VkImageCreateInfo image_create_info = vku::InitStructHelper(); |
| image_create_info.imageType = VK_IMAGE_TYPE_2D; |
| image_create_info.format = VK_FORMAT_R8G8_UNORM; |
| image_create_info.extent = {64, 64, 1}; |
| image_create_info.mipLevels = 1; |
| image_create_info.arrayLayers = 1; |
| image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; |
| image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; |
| image_create_info.flags = 0; |
| vkt::Image image2D(*m_device, image_create_info, vkt::set_layout); |
| |
| VkImageViewCreateInfo ivci = vku::InitStructHelper(); |
| ivci.image = image2D; |
| ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; |
| ivci.format = VK_FORMAT_R8G8_UNORM; |
| ivci.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; |
| |
| // Flags must not be set if the feature is not enabled |
| ivci.flags = VK_IMAGE_VIEW_CREATE_FRAGMENT_DENSITY_MAP_DYNAMIC_BIT_EXT; |
| CreateImageViewTest(ivci, "VUID-VkImageViewCreateInfo-flags-02572"); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, FragmentDensityMapReferenceAttachment) { |
| TEST_DESCRIPTION( |
| "Test creating a framebuffer with fragment density map reference to an attachment with layer count different from 1"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_0); |
| |
| AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMap); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| if (DeviceValidationVersion() >= VK_API_VERSION_1_1) { |
| GTEST_SKIP() << "Test requires Vulkan version 1.0"; |
| } |
| |
| VkAttachmentReference ref; |
| ref.attachment = 0; |
| ref.layout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| VkRenderPassFragmentDensityMapCreateInfoEXT rpfdmi = vku::InitStructHelper(); |
| rpfdmi.fragmentDensityMapAttachment = ref; |
| |
| VkAttachmentDescription attach = {}; |
| attach.format = VK_FORMAT_R8G8_UNORM; |
| attach.samples = VK_SAMPLE_COUNT_1_BIT; |
| attach.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attach.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attach.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attach.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attach.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attach.finalLayout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkSubpassDescription subpass = {}; |
| subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
| subpass.inputAttachmentCount = 0; |
| subpass.pInputAttachments = nullptr; |
| |
| VkRenderPassCreateInfo rpci = vku::InitStructHelper(&rpfdmi); |
| rpci.attachmentCount = 1; |
| rpci.pAttachments = &attach; |
| rpci.subpassCount = 1; |
| rpci.pSubpasses = &subpass; |
| vkt::RenderPass render_pass(*m_device, rpci); |
| |
| VkImageCreateInfo image_create_info = vku::InitStructHelper(); |
| image_create_info.imageType = VK_IMAGE_TYPE_2D; |
| image_create_info.format = VK_FORMAT_R8G8_UNORM; |
| image_create_info.extent = {32, 32, 1}; |
| image_create_info.mipLevels = 1; |
| image_create_info.arrayLayers = 4; |
| image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; |
| image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_create_info.usage = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT; |
| image_create_info.flags = 0; |
| vkt::Image image(*m_device, image_create_info, vkt::set_layout); |
| vkt::ImageView imageView = image.CreateView(VK_IMAGE_VIEW_TYPE_2D_ARRAY, 0, 1, 0, 4); |
| |
| VkFramebufferCreateInfo fb_info = vku::InitStructHelper(); |
| fb_info.renderPass = render_pass; |
| fb_info.attachmentCount = 1; |
| fb_info.pAttachments = &imageView.handle(); |
| fb_info.width = 32; |
| fb_info.height = 32; |
| fb_info.layers = 1; |
| |
| VkFramebuffer framebuffer; |
| m_errorMonitor->SetDesiredError("VUID-VkFramebufferCreateInfo-renderPass-02746"); |
| vk::CreateFramebuffer(device(), &fb_info, nullptr, &framebuffer); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, FramebufferUsage) { |
| TEST_DESCRIPTION("Specify a fragment shading rate attachment without the correct usage"); |
| |
| AddRequiredExtensions(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::attachmentFragmentShadingRate); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDeviceFragmentShadingRatePropertiesKHR fsr_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fsr_properties); |
| |
| RenderPass2SingleSubpass rp(*this); |
| rp.AddAttachmentDescription(VK_FORMAT_R8_UINT); |
| rp.AddFragmentShadingRateAttachment(0, VK_IMAGE_LAYOUT_GENERAL, fsr_properties.minFragmentShadingRateAttachmentTexelSize); |
| rp.CreateRenderPass(); |
| |
| vkt::Image image(*m_device, 1, 1, VK_FORMAT_R8_UINT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); |
| vkt::ImageView imageView = image.CreateView(); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkFramebufferCreateInfo-flags-04548"); |
| vkt::Framebuffer framebuffer(*m_device, rp, 1, &imageView.handle(), |
| fsr_properties.minFragmentShadingRateAttachmentTexelSize.width, |
| fsr_properties.minFragmentShadingRateAttachmentTexelSize.height); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, FramebufferDimensions) { |
| TEST_DESCRIPTION("Specify a fragment shading rate attachment with too small dimensions"); |
| |
| AddRequiredExtensions(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::attachmentFragmentShadingRate); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDeviceFragmentShadingRatePropertiesKHR fsr_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fsr_properties); |
| if (fsr_properties.layeredShadingRateAttachments != VK_TRUE) { |
| GTEST_SKIP() << "VkPhysicalDeviceFragmentShadingRatePropertiesKHR::layeredShadingRateAttachments not supported."; |
| } |
| |
| RenderPass2SingleSubpass rp(*this); |
| rp.AddAttachmentDescription(VK_FORMAT_R8_UINT); |
| rp.AddFragmentShadingRateAttachment(0, VK_IMAGE_LAYOUT_GENERAL, fsr_properties.minFragmentShadingRateAttachmentTexelSize); |
| rp.CreateRenderPass(); |
| |
| VkImageCreateInfo ici = |
| vkt::Image::ImageCreateInfo2D(1, 1, 1, 2, VK_FORMAT_R8_UINT, VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR); |
| vkt::Image image(*m_device, ici); |
| auto image_view_ci = image.BasicViewCreatInfo(); |
| image_view_ci.subresourceRange.layerCount = 2; |
| image_view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; |
| vkt::ImageView image_view(*m_device, image_view_ci); |
| |
| VkFramebufferCreateInfo fb_info = vku::InitStructHelper(); |
| fb_info.renderPass = rp; |
| fb_info.attachmentCount = 1; |
| fb_info.pAttachments = &image_view.handle(); |
| fb_info.width = fsr_properties.minFragmentShadingRateAttachmentTexelSize.width * 2; |
| fb_info.height = fsr_properties.minFragmentShadingRateAttachmentTexelSize.height; |
| fb_info.layers = 1; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkFramebufferCreateInfo-flags-04539"); |
| vkt::Framebuffer fb(*m_device, fb_info); |
| m_errorMonitor->VerifyFound(); |
| |
| fb_info.width = fsr_properties.minFragmentShadingRateAttachmentTexelSize.width; |
| |
| fb_info.height = fsr_properties.minFragmentShadingRateAttachmentTexelSize.height * 2; |
| m_errorMonitor->SetDesiredError("VUID-VkFramebufferCreateInfo-flags-04540"); |
| fb.Init(*m_device, fb_info); |
| m_errorMonitor->VerifyFound(); |
| fb_info.height = fsr_properties.minFragmentShadingRateAttachmentTexelSize.height; |
| |
| fb_info.layers = 3; |
| m_errorMonitor->SetDesiredError("VUID-VkFramebufferCreateInfo-flags-04538"); |
| fb.Init(*m_device, fb_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, FramebufferDimensionsMultiview) { |
| TEST_DESCRIPTION("Specify a fragment shading rate attachment with too small dimensions"); |
| |
| AddRequiredExtensions(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_MULTIVIEW_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::attachmentFragmentShadingRate); |
| AddRequiredFeature(vkt::Feature::multiview); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDeviceFragmentShadingRatePropertiesKHR fsr_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fsr_properties); |
| if (fsr_properties.layeredShadingRateAttachments != VK_TRUE) { |
| GTEST_SKIP() << "VkPhysicalDeviceFragmentShadingRatePropertiesKHR::layeredShadingRateAttachments not supported."; |
| } |
| |
| RenderPass2SingleSubpass rp(*this); |
| rp.AddAttachmentDescription(VK_FORMAT_R8_UINT); |
| rp.AddFragmentShadingRateAttachment(0, VK_IMAGE_LAYOUT_GENERAL, fsr_properties.minFragmentShadingRateAttachmentTexelSize); |
| rp.SetViewMask(0x4); |
| rp.CreateRenderPass(); |
| |
| VkImageCreateInfo ici = |
| vkt::Image::ImageCreateInfo2D(1, 1, 1, 2, VK_FORMAT_R8_UINT, VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR); |
| vkt::Image image(*m_device, ici); |
| auto image_view_ci = image.BasicViewCreatInfo(); |
| image_view_ci.subresourceRange.layerCount = 2; |
| image_view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; |
| vkt::ImageView image_view(*m_device, image_view_ci); |
| |
| VkFramebufferCreateInfo fb_info = vku::InitStructHelper(); |
| fb_info.renderPass = rp; |
| fb_info.attachmentCount = 1; |
| fb_info.pAttachments = &image_view.handle(); |
| fb_info.width = fsr_properties.minFragmentShadingRateAttachmentTexelSize.width; |
| fb_info.height = fsr_properties.minFragmentShadingRateAttachmentTexelSize.height; |
| fb_info.layers = 1; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkFramebufferCreateInfo-flags-04537"); |
| vkt::Framebuffer fb(*m_device, fb_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, Attachments) { |
| TEST_DESCRIPTION("Specify a fragment shading rate attachment with too small dimensions"); |
| |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_1_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::attachmentFragmentShadingRate); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDeviceFragmentShadingRatePropertiesKHR fsr_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fsr_properties); |
| |
| VkAttachmentReference2 attach = vku::InitStructHelper(); |
| attach.layout = VK_IMAGE_LAYOUT_GENERAL; |
| attach.attachment = 0; |
| |
| VkFragmentShadingRateAttachmentInfoKHR fsr_attachment = vku::InitStructHelper(); |
| fsr_attachment.shadingRateAttachmentTexelSize = fsr_properties.minFragmentShadingRateAttachmentTexelSize; |
| fsr_attachment.pFragmentShadingRateAttachment = &attach; |
| |
| // Create a renderPass with a single fsr attachment |
| VkSubpassDescription2 subpass = vku::InitStructHelper(&fsr_attachment); |
| |
| VkAttachmentDescription2 attach_desc = vku::InitStructHelper(); |
| attach_desc.format = VK_FORMAT_R8_UINT; |
| attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_GENERAL; |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| VkRenderPassCreateInfo2 rpci = vku::InitStructHelper(); |
| rpci.subpassCount = 1; |
| rpci.pSubpasses = &subpass; |
| rpci.attachmentCount = 1; |
| rpci.pAttachments = &attach_desc; |
| |
| VkRenderPass rp; |
| |
| rpci.flags = VK_RENDER_PASS_CREATE_TRANSFORM_BIT_QCOM; |
| // skip stateless so we can test core checks |
| m_errorMonitor->SetAllowedFailureMsg("VUID-VkRenderPassCreateInfo2-flags-parameter"); |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassCreateInfo2-flags-04521"); |
| vk::CreateRenderPass2KHR(device(), &rpci, NULL, &rp); |
| m_errorMonitor->VerifyFound(); |
| rpci.flags = 0; |
| attach_desc.format = |
| FindFormatWithoutFeatures(Gpu(), VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR); |
| if (attach_desc.format != VK_FORMAT_UNDEFINED) { |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassCreateInfo2-pAttachments-04586"); |
| vk::CreateRenderPass2KHR(device(), &rpci, NULL, &rp); |
| m_errorMonitor->VerifyFound(); |
| } |
| attach_desc.format = VK_FORMAT_R8_UINT; |
| |
| attach.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| m_errorMonitor->SetDesiredError("VUID-VkFragmentShadingRateAttachmentInfoKHR-pFragmentShadingRateAttachment-04524"); |
| vk::CreateRenderPass2KHR(device(), &rpci, NULL, &rp); |
| m_errorMonitor->VerifyFound(); |
| attach.layout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| fsr_attachment.shadingRateAttachmentTexelSize.width = fsr_properties.minFragmentShadingRateAttachmentTexelSize.width + 1; |
| fsr_attachment.shadingRateAttachmentTexelSize.height = fsr_properties.minFragmentShadingRateAttachmentTexelSize.height + 1; |
| m_errorMonitor->SetDesiredError("VUID-VkFragmentShadingRateAttachmentInfoKHR-pFragmentShadingRateAttachment-04525"); |
| m_errorMonitor->SetDesiredError("VUID-VkFragmentShadingRateAttachmentInfoKHR-pFragmentShadingRateAttachment-04528"); |
| if (fsr_properties.maxFragmentShadingRateAttachmentTexelSize.width == |
| fsr_properties.minFragmentShadingRateAttachmentTexelSize.width) { |
| m_errorMonitor->SetDesiredError("VUID-VkFragmentShadingRateAttachmentInfoKHR-pFragmentShadingRateAttachment-04526"); |
| } |
| if (fsr_properties.maxFragmentShadingRateAttachmentTexelSize.height == |
| fsr_properties.minFragmentShadingRateAttachmentTexelSize.height) { |
| m_errorMonitor->SetDesiredError("VUID-VkFragmentShadingRateAttachmentInfoKHR-pFragmentShadingRateAttachment-04529"); |
| } |
| vk::CreateRenderPass2KHR(device(), &rpci, NULL, &rp); |
| m_errorMonitor->VerifyFound(); |
| fsr_attachment.shadingRateAttachmentTexelSize = fsr_properties.minFragmentShadingRateAttachmentTexelSize; |
| |
| fsr_attachment.shadingRateAttachmentTexelSize.width = fsr_properties.minFragmentShadingRateAttachmentTexelSize.width / 2; |
| fsr_attachment.shadingRateAttachmentTexelSize.height = fsr_properties.minFragmentShadingRateAttachmentTexelSize.height / 2; |
| m_errorMonitor->SetDesiredError("VUID-VkFragmentShadingRateAttachmentInfoKHR-pFragmentShadingRateAttachment-04527"); |
| m_errorMonitor->SetDesiredError("VUID-VkFragmentShadingRateAttachmentInfoKHR-pFragmentShadingRateAttachment-04530"); |
| vk::CreateRenderPass2KHR(device(), &rpci, NULL, &rp); |
| m_errorMonitor->VerifyFound(); |
| fsr_attachment.shadingRateAttachmentTexelSize = fsr_properties.minFragmentShadingRateAttachmentTexelSize; |
| |
| fsr_attachment.shadingRateAttachmentTexelSize.width = fsr_properties.maxFragmentShadingRateAttachmentTexelSize.width * 2; |
| fsr_attachment.shadingRateAttachmentTexelSize.height = fsr_properties.maxFragmentShadingRateAttachmentTexelSize.height * 2; |
| m_errorMonitor->SetDesiredError("VUID-VkFragmentShadingRateAttachmentInfoKHR-pFragmentShadingRateAttachment-04526"); |
| m_errorMonitor->SetDesiredError("VUID-VkFragmentShadingRateAttachmentInfoKHR-pFragmentShadingRateAttachment-04529"); |
| vk::CreateRenderPass2KHR(device(), &rpci, NULL, &rp); |
| m_errorMonitor->VerifyFound(); |
| fsr_attachment.shadingRateAttachmentTexelSize = fsr_properties.minFragmentShadingRateAttachmentTexelSize; |
| |
| if (fsr_properties.maxFragmentShadingRateAttachmentTexelSize.width / |
| fsr_properties.minFragmentShadingRateAttachmentTexelSize.height > |
| fsr_properties.maxFragmentShadingRateAttachmentTexelSizeAspectRatio) { |
| fsr_attachment.shadingRateAttachmentTexelSize.width = fsr_properties.maxFragmentShadingRateAttachmentTexelSize.width; |
| m_errorMonitor->SetDesiredError("VUID-VkFragmentShadingRateAttachmentInfoKHR-pFragmentShadingRateAttachment-04531"); |
| vk::CreateRenderPass2KHR(device(), &rpci, NULL, &rp); |
| m_errorMonitor->VerifyFound(); |
| fsr_attachment.shadingRateAttachmentTexelSize = fsr_properties.minFragmentShadingRateAttachmentTexelSize; |
| } |
| |
| if (fsr_properties.maxFragmentShadingRateAttachmentTexelSize.height / |
| fsr_properties.minFragmentShadingRateAttachmentTexelSize.width > |
| fsr_properties.maxFragmentShadingRateAttachmentTexelSizeAspectRatio) { |
| fsr_attachment.shadingRateAttachmentTexelSize.height = fsr_properties.maxFragmentShadingRateAttachmentTexelSize.height; |
| m_errorMonitor->SetDesiredError("VUID-VkFragmentShadingRateAttachmentInfoKHR-pFragmentShadingRateAttachment-04532"); |
| vk::CreateRenderPass2KHR(device(), &rpci, NULL, &rp); |
| m_errorMonitor->VerifyFound(); |
| fsr_attachment.shadingRateAttachmentTexelSize = fsr_properties.minFragmentShadingRateAttachmentTexelSize; |
| } |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, LoadOpClear) { |
| AddRequiredExtensions(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::attachmentFragmentShadingRate); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDeviceFragmentShadingRatePropertiesKHR fsr_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fsr_properties); |
| |
| VkAttachmentReference2 attach = vku::InitStructHelper(); |
| attach.layout = VK_IMAGE_LAYOUT_GENERAL; |
| attach.attachment = 0; |
| |
| VkFragmentShadingRateAttachmentInfoKHR fsr_attachment = vku::InitStructHelper(); |
| fsr_attachment.shadingRateAttachmentTexelSize = fsr_properties.minFragmentShadingRateAttachmentTexelSize; |
| fsr_attachment.pFragmentShadingRateAttachment = &attach; |
| VkSubpassDescription2 subpass = vku::InitStructHelper(&fsr_attachment); |
| |
| VkAttachmentDescription2 attach_desc = vku::InitStructHelper(); |
| attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| attach_desc.format = VK_FORMAT_R8_UINT; |
| attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_GENERAL; |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| VkRenderPassCreateInfo2 rpci = vku::InitStructHelper(); |
| rpci.subpassCount = 1; |
| rpci.pSubpasses = &subpass; |
| rpci.attachmentCount = 1; |
| rpci.pAttachments = &attach_desc; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassCreateInfo2-pAttachments-09387"); |
| VkRenderPass rp; |
| vk::CreateRenderPass2KHR(device(), &rpci, NULL, &rp); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, IncompatibleFragmentRateShadingAttachmentInExecuteCommands) { |
| TEST_DESCRIPTION( |
| "Test incompatible fragment shading rate attachments " |
| "calling CmdExecuteCommands"); |
| AddRequiredExtensions(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::attachmentFragmentShadingRate); |
| RETURN_IF_SKIP(Init()); |
| |
| if (!FormatFeaturesAreSupported(Gpu(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TILING_OPTIMAL, |
| VK_FORMAT_FEATURE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR)) { |
| GTEST_SKIP() << "VK_FORMAT_FEATURE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR not supported"; |
| } |
| |
| VkPhysicalDeviceFragmentShadingRatePropertiesKHR fsr_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fsr_properties); |
| |
| // Create a render pass without a Fragment Shading Rate attachment |
| RenderPass2SingleSubpass rp_no_fsr(*this); |
| rp_no_fsr.AddAttachmentDescription(VK_FORMAT_R8G8B8A8_UNORM); |
| rp_no_fsr.CreateRenderPass(); |
| |
| // Create 2 render passes with fragment shading rate attachments with |
| // differing shadingRateAttachmentTexelSize values |
| VkExtent2D texel_size_1 = fsr_properties.minFragmentShadingRateAttachmentTexelSize; |
| VkExtent2D texel_size_2 = fsr_properties.maxFragmentShadingRateAttachmentTexelSize; |
| |
| RenderPass2SingleSubpass rp_fsr_1(*this); |
| rp_fsr_1.AddAttachmentDescription(VK_FORMAT_R8G8B8A8_UNORM); |
| rp_fsr_1.AddFragmentShadingRateAttachment(0, VK_IMAGE_LAYOUT_GENERAL, texel_size_1); |
| rp_fsr_1.CreateRenderPass(); |
| |
| RenderPass2SingleSubpass rp_fsr_2(*this); |
| rp_fsr_2.AddAttachmentDescription(VK_FORMAT_R8G8B8A8_UNORM); |
| rp_fsr_2.AddFragmentShadingRateAttachment(0, VK_IMAGE_LAYOUT_GENERAL, texel_size_2); |
| rp_fsr_2.CreateRenderPass(); |
| |
| vkt::Image image(*m_device, 32, 32, VK_FORMAT_R8G8B8A8_UNORM, |
| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR); |
| vkt::ImageView imageView = image.CreateView(); |
| |
| // Create a frame buffer with a render pass with FSR attachment |
| vkt::Framebuffer framebuffer_fsr(*m_device, rp_fsr_1, 1, &imageView.handle()); |
| |
| // Create a frame buffer with a render pass without FSR attachment |
| vkt::Framebuffer framebuffer_no_fsr(*m_device, rp_no_fsr, 1, &imageView.handle()); |
| |
| vkt::CommandPool pool(*m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT); |
| vkt::CommandBuffer secondary(*m_device, pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| |
| // Inheritance info without FSR attachment |
| const VkCommandBufferInheritanceInfo cmdbuff_ii_no_fsr = { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, |
| nullptr, // pNext |
| rp_no_fsr.Handle(), |
| 0, // subpass |
| VK_NULL_HANDLE, |
| }; |
| |
| VkCommandBufferBeginInfo cmdbuff__bi_no_fsr = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, |
| nullptr, // pNext |
| VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, &cmdbuff_ii_no_fsr}; |
| cmdbuff__bi_no_fsr.flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; |
| |
| // Render pass begin info for no FSR attachment |
| const auto rp_bi_no_fsr = vku::InitStruct<VkRenderPassBeginInfo>(nullptr, rp_no_fsr.Handle(), framebuffer_no_fsr.handle(), |
| VkRect2D{{0, 0}, {32u, 32u}}, 0u, nullptr); |
| |
| // Inheritance info with FSR attachment |
| const VkCommandBufferInheritanceInfo cmdbuff_ii_fsr = { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, |
| nullptr, // pNext |
| rp_fsr_2.Handle(), |
| 0, // subpass |
| VK_NULL_HANDLE, |
| }; |
| |
| VkCommandBufferBeginInfo cmdbuff__bi_fsr = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, |
| nullptr, // pNext |
| VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, &cmdbuff_ii_fsr}; |
| cmdbuff__bi_fsr.flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; |
| |
| // Render pass begin info with FSR attachment |
| const auto rp_bi_fsr = vku::InitStruct<VkRenderPassBeginInfo>(nullptr, rp_fsr_1.Handle(), framebuffer_fsr.handle(), |
| VkRect2D{{0, 0}, {32u, 32u}}, 0u, nullptr); |
| |
| // Test case where primary command buffer does not have an FSR attachment but |
| // secondary command buffer does. |
| { |
| secondary.Begin(&cmdbuff__bi_fsr); |
| secondary.End(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-pBeginInfo-06020"); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(rp_bi_no_fsr, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); |
| vk::CmdExecuteCommands(m_command_buffer, 1, &secondary.handle()); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| m_command_buffer.Reset(); |
| secondary.Reset(); |
| |
| // Test case where primary command buffer has FSR attachment but secondary |
| // command buffer does not. |
| { |
| secondary.Begin(&cmdbuff__bi_no_fsr); |
| secondary.End(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-pBeginInfo-06020"); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(rp_bi_fsr, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); |
| |
| vk::CmdExecuteCommands(m_command_buffer, 1, &secondary.handle()); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| m_command_buffer.Reset(); |
| secondary.Reset(); |
| |
| // Test case where both command buffers have FSR attachments but they are |
| // incompatible. |
| if (texel_size_1.width != texel_size_2.width || texel_size_1.height != texel_size_2.height) { |
| secondary.Begin(&cmdbuff__bi_fsr); |
| secondary.End(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-pBeginInfo-06020"); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(rp_bi_fsr, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); |
| |
| vk::CmdExecuteCommands(m_command_buffer, 1, &secondary.handle()); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| m_command_buffer.Reset(); |
| secondary.Reset(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, ShadingRateUsage) { |
| TEST_DESCRIPTION("Specify invalid usage of the fragment shading rate image view usage."); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_1_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_MULTIVIEW_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::attachmentFragmentShadingRate); |
| RETURN_IF_SKIP(Init()); |
| |
| const VkFormat format = |
| FindFormatWithoutFeatures(Gpu(), VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR); |
| if (format == VK_FORMAT_UNDEFINED) { |
| GTEST_SKIP() << "No format found without shading rate attachment support"; |
| } |
| |
| VkImageFormatProperties format_props; |
| if (vk::GetPhysicalDeviceImageFormatProperties(Gpu(), format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, |
| VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR, 0, |
| &format_props) == VK_ERROR_FORMAT_NOT_SUPPORTED) { |
| GTEST_SKIP() << "Format not supported"; |
| } |
| // Initialize image with transfer source usage |
| vkt::Image image(*m_device, 128, 128, format, VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR); |
| |
| VkImageViewCreateInfo createinfo = vku::InitStructHelper(); |
| createinfo.image = image; |
| createinfo.viewType = VK_IMAGE_VIEW_TYPE_2D; |
| createinfo.format = format; |
| createinfo.subresourceRange.layerCount = 1; |
| createinfo.subresourceRange.baseMipLevel = 0; |
| createinfo.subresourceRange.levelCount = 1; |
| if (vkuFormatIsColor(format)) { |
| createinfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
| } else if (vkuFormatHasDepth(format)) { |
| createinfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; |
| } else if (vkuFormatHasStencil(format)) { |
| createinfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; |
| } |
| |
| // Create a view with the fragment shading rate attachment usage, but that doesn't support it |
| CreateImageViewTest(createinfo, "VUID-VkImageViewCreateInfo-usage-04550"); |
| |
| VkPhysicalDeviceFragmentShadingRatePropertiesKHR fsr_props = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fsr_props); |
| |
| if (!fsr_props.layeredShadingRateAttachments) { |
| if (IsPlatformMockICD()) { |
| GTEST_SKIP() << "Test not supported by MockICD, doesn't correctly advertise format support for fragment shading " |
| "rate attachments"; |
| } else { |
| auto image_ci = vkt::Image::ImageCreateInfo2D(128, 128, 1, 2, VK_FORMAT_R8_UINT, |
| VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR); |
| vkt::Image image2(*m_device, image_ci); |
| |
| createinfo.image = image2; |
| createinfo.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; |
| createinfo.format = VK_FORMAT_R8_UINT; |
| createinfo.subresourceRange.layerCount = 2; |
| createinfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
| CreateImageViewTest(createinfo, "VUID-VkImageViewCreateInfo-usage-04551"); |
| } |
| } |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, Pipeline) { |
| TEST_DESCRIPTION("Specify invalid fragment shading rate values"); |
| |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_1_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::pipelineFragmentShadingRate); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| VkPipelineFragmentShadingRateStateCreateInfoKHR fsr_ci = vku::InitStructHelper(); |
| fsr_ci.fragmentSize.width = 1; |
| fsr_ci.fragmentSize.height = 1; |
| |
| auto set_fsr_ci = [&](CreatePipelineHelper& helper) { helper.gp_ci_.pNext = &fsr_ci; }; |
| |
| fsr_ci.fragmentSize.width = 0; |
| CreatePipelineHelper::OneshotTest(*this, set_fsr_ci, kErrorBit, "VUID-VkGraphicsPipelineCreateInfo-pDynamicState-04494"); |
| fsr_ci.fragmentSize.width = 1; |
| |
| fsr_ci.fragmentSize.height = 0; |
| CreatePipelineHelper::OneshotTest(*this, set_fsr_ci, kErrorBit, "VUID-VkGraphicsPipelineCreateInfo-pDynamicState-04495"); |
| fsr_ci.fragmentSize.height = 1; |
| |
| fsr_ci.fragmentSize.width = 3; |
| CreatePipelineHelper::OneshotTest(*this, set_fsr_ci, kErrorBit, "VUID-VkGraphicsPipelineCreateInfo-pDynamicState-04496"); |
| fsr_ci.fragmentSize.width = 1; |
| |
| fsr_ci.fragmentSize.height = 3; |
| CreatePipelineHelper::OneshotTest(*this, set_fsr_ci, kErrorBit, "VUID-VkGraphicsPipelineCreateInfo-pDynamicState-04497"); |
| fsr_ci.fragmentSize.height = 1; |
| |
| fsr_ci.fragmentSize.width = 8; |
| CreatePipelineHelper::OneshotTest(*this, set_fsr_ci, kErrorBit, "VUID-VkGraphicsPipelineCreateInfo-pDynamicState-04498"); |
| fsr_ci.fragmentSize.width = 1; |
| |
| fsr_ci.fragmentSize.height = 8; |
| CreatePipelineHelper::OneshotTest(*this, set_fsr_ci, kErrorBit, "VUID-VkGraphicsPipelineCreateInfo-pDynamicState-04499"); |
| fsr_ci.fragmentSize.height = 1; |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, PipelineFeatureUsage) { |
| TEST_DESCRIPTION("Specify invalid fsr pipeline settings for the enabled features"); |
| |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_1_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| VkPipelineFragmentShadingRateStateCreateInfoKHR fsr_ci = vku::InitStructHelper(); |
| fsr_ci.fragmentSize.width = 1; |
| fsr_ci.fragmentSize.height = 1; |
| |
| auto set_fsr_ci = [&](CreatePipelineHelper& helper) { helper.gp_ci_.pNext = &fsr_ci; }; |
| |
| fsr_ci.fragmentSize.width = 2; |
| CreatePipelineHelper::OneshotTest(*this, set_fsr_ci, kErrorBit, "VUID-VkGraphicsPipelineCreateInfo-pDynamicState-04500"); |
| fsr_ci.fragmentSize.width = 1; |
| |
| fsr_ci.fragmentSize.height = 2; |
| CreatePipelineHelper::OneshotTest(*this, set_fsr_ci, kErrorBit, "VUID-VkGraphicsPipelineCreateInfo-pDynamicState-04500"); |
| fsr_ci.fragmentSize.height = 1; |
| |
| fsr_ci.combinerOps[0] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR; |
| CreatePipelineHelper::OneshotTest(*this, set_fsr_ci, kErrorBit, "VUID-VkGraphicsPipelineCreateInfo-pDynamicState-04501"); |
| fsr_ci.combinerOps[0] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR; |
| |
| fsr_ci.combinerOps[1] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR; |
| CreatePipelineHelper::OneshotTest(*this, set_fsr_ci, kErrorBit, "VUID-VkGraphicsPipelineCreateInfo-pDynamicState-04502"); |
| fsr_ci.combinerOps[1] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR; |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, PipelineCombinerOpsLimit) { |
| TEST_DESCRIPTION("Specify invalid use of combiner ops when non trivial ops aren't supported"); |
| |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_1_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::attachmentFragmentShadingRate); |
| AddRequiredFeature(vkt::Feature::pipelineFragmentShadingRate); |
| AddRequiredFeature(vkt::Feature::primitiveFragmentShadingRate); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDeviceFragmentShadingRatePropertiesKHR fsr_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fsr_properties); |
| |
| if (fsr_properties.fragmentShadingRateNonTrivialCombinerOps) { |
| GTEST_SKIP() << "requires fragmentShadingRateNonTrivialCombinerOps to be unsupported"; |
| } |
| |
| InitRenderTarget(); |
| |
| VkPipelineFragmentShadingRateStateCreateInfoKHR fsr_ci = vku::InitStructHelper(); |
| fsr_ci.fragmentSize.width = 1; |
| fsr_ci.fragmentSize.height = 1; |
| |
| auto set_fsr_ci = [&](CreatePipelineHelper& helper) { helper.gp_ci_.pNext = &fsr_ci; }; |
| |
| // primitiveFragmentShadingRate |
| { |
| fsr_ci.combinerOps[0] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_KHR; |
| CreatePipelineHelper::OneshotTest(*this, set_fsr_ci, kErrorBit, |
| "VUID-VkGraphicsPipelineCreateInfo-fragmentShadingRateNonTrivialCombinerOps-04506"); |
| fsr_ci.combinerOps[0] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR; |
| } |
| |
| // attachmentFragmentShadingRate |
| { |
| fsr_ci.combinerOps[1] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_KHR; |
| CreatePipelineHelper::OneshotTest(*this, set_fsr_ci, kErrorBit, |
| "VUID-VkGraphicsPipelineCreateInfo-fragmentShadingRateNonTrivialCombinerOps-04506"); |
| fsr_ci.combinerOps[1] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR; |
| } |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, PrimitiveWriteMultiViewportLimit) { |
| TEST_DESCRIPTION("Test static validation of the primitiveFragmentShadingRateWithMultipleViewports limit"); |
| |
| // Enable KHR_fragment_shading_rate and all of its required extensions |
| AddRequiredExtensions(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME); |
| AddOptionalExtensions(VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME); |
| AddOptionalExtensions(VK_NV_VIEWPORT_ARRAY_2_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::geometryShader); |
| AddRequiredFeature(vkt::Feature::primitiveFragmentShadingRate); |
| AddRequiredFeature(vkt::Feature::multiViewport); |
| AddRequiredFeature(vkt::Feature::shaderTessellationAndGeometryPointSize); |
| RETURN_IF_SKIP(InitFramework()); |
| |
| const bool vil_extension = IsExtensionsEnabled(VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME); |
| const bool va2_extension = IsExtensionsEnabled(VK_NV_VIEWPORT_ARRAY_2_EXTENSION_NAME); |
| |
| VkPhysicalDeviceFragmentShadingRatePropertiesKHR fsr_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fsr_properties); |
| |
| if (fsr_properties.primitiveFragmentShadingRateWithMultipleViewports) { |
| GTEST_SKIP() << "requires primitiveFragmentShadingRateWithMultipleViewports to be unsupported."; |
| } |
| |
| RETURN_IF_SKIP(InitState()); |
| InitRenderTarget(); |
| |
| // Test PrimitiveShadingRate writes with multiple viewports |
| { |
| const char* vsSource = R"glsl( |
| #version 450 |
| #extension GL_EXT_fragment_shading_rate : enable |
| void main() { |
| gl_PrimitiveShadingRateEXT = gl_ShadingRateFlag4VerticalPixelsEXT | gl_ShadingRateFlag4HorizontalPixelsEXT; |
| } |
| )glsl"; |
| |
| VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT); |
| |
| VkViewport viewports[2] = {{0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f}}; |
| VkRect2D scissors[2] = {}; |
| |
| auto info_override = [&](CreatePipelineHelper& info) { |
| info.shader_stages_ = {vs.GetStageCreateInfo(), info.fs_->GetStageCreateInfo()}; |
| info.vp_state_ci_.viewportCount = 2; |
| info.vp_state_ci_.pViewports = viewports; |
| info.vp_state_ci_.scissorCount = 2; |
| info.vp_state_ci_.pScissors = scissors; |
| }; |
| |
| CreatePipelineHelper::OneshotTest( |
| *this, info_override, kErrorBit, |
| "VUID-VkGraphicsPipelineCreateInfo-primitiveFragmentShadingRateWithMultipleViewports-04503"); |
| } |
| VkPhysicalDeviceFeatures2 features2 = vku::InitStructHelper(); |
| GetPhysicalDeviceFeatures2(features2); |
| |
| // Test PrimitiveShadingRate writes with ViewportIndex writes in a geometry shader |
| if (features2.features.geometryShader) { |
| const char* vsSource = R"glsl( |
| #version 450 |
| void main() {} |
| )glsl"; |
| |
| const char* gsSource = R"glsl( |
| #version 450 |
| #extension GL_EXT_fragment_shading_rate : enable |
| layout (points) in; |
| layout (points) out; |
| layout (max_vertices = 1) out; |
| void main() { |
| gl_PrimitiveShadingRateEXT = gl_ShadingRateFlag4VerticalPixelsEXT | gl_ShadingRateFlag4HorizontalPixelsEXT; |
| gl_Position = vec4(1.0, 0.5, 0.5, 0.0); |
| gl_ViewportIndex = 0; |
| gl_PointSize = 1.0f; |
| EmitVertex(); |
| } |
| )glsl"; |
| |
| VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT); |
| VkShaderObj gs(*m_device, gsSource, VK_SHADER_STAGE_GEOMETRY_BIT); |
| |
| auto info_override = [&](CreatePipelineHelper& info) { |
| info.ia_ci_.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; |
| info.shader_stages_ = {vs.GetStageCreateInfo(), gs.GetStageCreateInfo(), info.fs_->GetStageCreateInfo()}; |
| }; |
| |
| CreatePipelineHelper::OneshotTest( |
| *this, info_override, kErrorBit, |
| "VUID-VkGraphicsPipelineCreateInfo-primitiveFragmentShadingRateWithMultipleViewports-04504"); |
| } |
| |
| // Test PrimitiveShadingRate writes with ViewportIndex writes in a vertex shader |
| if (vil_extension) { |
| const char* vsSource = R"glsl( |
| #version 450 |
| #extension GL_EXT_fragment_shading_rate : enable |
| #extension GL_ARB_shader_viewport_layer_array : enable |
| void main() { |
| gl_PrimitiveShadingRateEXT = gl_ShadingRateFlag4VerticalPixelsEXT | gl_ShadingRateFlag4HorizontalPixelsEXT; |
| gl_ViewportIndex = 0; |
| } |
| )glsl"; |
| |
| VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT); |
| |
| auto info_override = [&](CreatePipelineHelper& info) { |
| info.shader_stages_ = {vs.GetStageCreateInfo(), info.fs_->GetStageCreateInfo()}; |
| }; |
| |
| CreatePipelineHelper::OneshotTest( |
| *this, info_override, kErrorBit, |
| "VUID-VkGraphicsPipelineCreateInfo-primitiveFragmentShadingRateWithMultipleViewports-04504"); |
| } |
| |
| if (va2_extension) { |
| // Test PrimitiveShadingRate writes with ViewportIndex writes in a geometry shader |
| if (features2.features.geometryShader) { |
| const char* vsSource = R"glsl( |
| #version 450 |
| void main() {} |
| )glsl"; |
| |
| const char* gsSource = R"glsl( |
| #version 450 |
| #extension GL_EXT_fragment_shading_rate : enable |
| #extension GL_NV_viewport_array2 : enable |
| layout (points) in; |
| layout (points) out; |
| layout (max_vertices = 1) out; |
| void main() { |
| gl_PrimitiveShadingRateEXT = gl_ShadingRateFlag4VerticalPixelsEXT | gl_ShadingRateFlag4HorizontalPixelsEXT; |
| gl_ViewportMask[0] = 0; |
| gl_Position = vec4(1.0, 0.5, 0.5, 0.0); |
| gl_PointSize = 1.0f; |
| EmitVertex(); |
| } |
| )glsl"; |
| |
| VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT); |
| VkShaderObj gs(*m_device, gsSource, VK_SHADER_STAGE_GEOMETRY_BIT); |
| |
| auto info_override = [&](CreatePipelineHelper& info) { |
| info.ia_ci_.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; |
| info.shader_stages_ = {vs.GetStageCreateInfo(), gs.GetStageCreateInfo(), info.fs_->GetStageCreateInfo()}; |
| }; |
| |
| CreatePipelineHelper::OneshotTest( |
| *this, info_override, kErrorBit, |
| "VUID-VkGraphicsPipelineCreateInfo-primitiveFragmentShadingRateWithMultipleViewports-04505"); |
| } |
| |
| // Test PrimitiveShadingRate writes with ViewportIndex writes in a vertex shader |
| if (vil_extension) { |
| const char* vsSource = R"glsl( |
| #version 450 |
| #extension GL_EXT_fragment_shading_rate : enable |
| #extension GL_NV_viewport_array2 : enable |
| void main() { |
| gl_PrimitiveShadingRateEXT = gl_ShadingRateFlag4VerticalPixelsEXT | gl_ShadingRateFlag4HorizontalPixelsEXT; |
| gl_ViewportMask[0] = 0; |
| } |
| )glsl"; |
| |
| VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT); |
| |
| auto info_override = [&](CreatePipelineHelper& info) { |
| info.shader_stages_ = {vs.GetStageCreateInfo(), info.fs_->GetStageCreateInfo()}; |
| }; |
| |
| CreatePipelineHelper::OneshotTest( |
| *this, info_override, kErrorBit, |
| "VUID-VkGraphicsPipelineCreateInfo-primitiveFragmentShadingRateWithMultipleViewports-04505"); |
| } |
| } |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, Ops) { |
| TEST_DESCRIPTION("Specify invalid fsr pipeline settings for the enabled features"); |
| |
| // Enable KHR_fragment_shading_rate and all of its required extensions |
| AddRequiredExtensions(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::primitiveFragmentShadingRate); |
| AddRequiredFeature(vkt::Feature::attachmentFragmentShadingRate); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| VkPipelineFragmentShadingRateStateCreateInfoKHR fsr_ci = vku::InitStructHelper(); |
| fsr_ci.fragmentSize.width = 1; |
| fsr_ci.fragmentSize.height = 1; |
| fsr_ci.combinerOps[0] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR; |
| fsr_ci.combinerOps[1] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR; |
| |
| auto set_fsr_ci = [&](CreatePipelineHelper& helper) { helper.gp_ci_.pNext = &fsr_ci; }; |
| |
| // Pass an invalid value for op 0 |
| fsr_ci.combinerOps[0] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_ENUM_KHR; |
| // if fragmentShadingRateNonTrivialCombinerOps is not supported |
| m_errorMonitor->SetUnexpectedError("VUID-VkGraphicsPipelineCreateInfo-fragmentShadingRateNonTrivialCombinerOps-04506"); |
| CreatePipelineHelper::OneshotTest(*this, set_fsr_ci, kErrorBit, "VUID-VkGraphicsPipelineCreateInfo-pDynamicState-06567"); |
| fsr_ci.combinerOps[0] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR; |
| |
| // Pass an invalid value for op 1 |
| fsr_ci.combinerOps[1] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_ENUM_KHR; |
| // if fragmentShadingRateNonTrivialCombinerOps is not supported |
| m_errorMonitor->SetUnexpectedError("VUID-VkGraphicsPipelineCreateInfo-fragmentShadingRateNonTrivialCombinerOps-04506"); |
| CreatePipelineHelper::OneshotTest(*this, set_fsr_ci, kErrorBit, "VUID-VkGraphicsPipelineCreateInfo-pDynamicState-06568"); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, FragmentDensityMapAttachmentCount) { |
| TEST_DESCRIPTION("Test attachmentCount of VkRenderPassFragmentDensityMapCreateInfoEXT."); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMap); |
| RETURN_IF_SKIP(Init()); |
| |
| VkAttachmentDescription2 attach_desc = vku::InitStructHelper(); |
| attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM; |
| attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; |
| attach_desc.initialLayout = VK_IMAGE_LAYOUT_GENERAL; |
| attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| VkAttachmentReference ref = {}; |
| ref.attachment = 1; |
| ref.layout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| VkRenderPassFragmentDensityMapCreateInfoEXT rpfdmi = vku::InitStructHelper(); |
| rpfdmi.fragmentDensityMapAttachment = ref; |
| |
| // Create a renderPass with viewMask 0 |
| VkSubpassDescription2 subpass = vku::InitStructHelper(); |
| subpass.viewMask = 0; |
| |
| VkRenderPassCreateInfo2 render_pass_ci = vku::InitStructHelper(&rpfdmi); |
| render_pass_ci.subpassCount = 1; |
| render_pass_ci.pSubpasses = &subpass; |
| render_pass_ci.attachmentCount = 1; |
| render_pass_ci.pAttachments = &attach_desc; |
| |
| VkRenderPass render_pass; |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassCreateInfo2-fragmentDensityMapAttachment-06472"); |
| vk::CreateRenderPass2KHR(device(), &render_pass_ci, nullptr, &render_pass); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, FragmentDensityMapOffsetMissingFeature) { |
| AddRequiredExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::Image image(*m_device, 32u, 32u, VK_FORMAT_R8G8_UNORM, VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT); |
| vkt::ImageView image_view = image.CreateView(); |
| |
| VkRenderPassFragmentDensityMapCreateInfoEXT fragment_density_map_ci = vku::InitStructHelper(); |
| fragment_density_map_ci.fragmentDensityMapAttachment.attachment = VK_ATTACHMENT_UNUSED; |
| fragment_density_map_ci.fragmentDensityMapAttachment.layout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkAttachmentDescription attachment_description = {}; |
| attachment_description.format = VK_FORMAT_R8G8_UNORM; |
| attachment_description.samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_description.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_description.finalLayout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkSubpassDescription subpass_description = {}; |
| |
| VkRenderPassCreateInfo render_pass_ci = vku::InitStructHelper(&fragment_density_map_ci); |
| render_pass_ci.attachmentCount = 1u; |
| render_pass_ci.pAttachments = &attachment_description; |
| render_pass_ci.subpassCount = 1u; |
| render_pass_ci.pSubpasses = &subpass_description; |
| vkt::RenderPass render_pass(*m_device, render_pass_ci); |
| |
| vkt::Framebuffer framebuffer(*m_device, render_pass, 1u, &image_view.handle()); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(render_pass, framebuffer); |
| |
| VkPhysicalDeviceFragmentDensityMapOffsetPropertiesEXT fdm_offset_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fdm_offset_properties); |
| |
| int32_t width = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.width); |
| int32_t height = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.height); |
| VkOffset2D offset = {width, height}; |
| VkRenderPassFragmentDensityMapOffsetEndInfoEXT fdm_offset_end_info = vku::InitStructHelper(); |
| fdm_offset_end_info.fragmentDensityOffsetCount = 1u; |
| fdm_offset_end_info.pFragmentDensityOffsets = &offset; |
| VkSubpassEndInfo subpass_end_info = vku::InitStructHelper(&fdm_offset_end_info); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassFragmentDensityMapOffsetEndInfoEXT-fragmentDensityMapOffsets-06503"); |
| vk::CmdEndRenderPass2KHR(m_command_buffer, &subpass_end_info); |
| m_errorMonitor->VerifyFound(); |
| |
| // Same error even if offsets are zero |
| offset = {0, 0}; |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassFragmentDensityMapOffsetEndInfoEXT-fragmentDensityMapOffsets-06503"); |
| vk::CmdEndRenderPass2KHR(m_command_buffer, &subpass_end_info); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, FragmentDensityMapOffsetMissingFeatureDynamicRendering) { |
| AddRequiredExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| RETURN_IF_SKIP(Init()); |
| |
| VkImageCreateInfo image_create_info = vku::InitStructHelper(); |
| image_create_info.flags = VK_IMAGE_CREATE_FRAGMENT_DENSITY_MAP_OFFSET_BIT_EXT; |
| image_create_info.imageType = VK_IMAGE_TYPE_2D; |
| image_create_info.format = VK_FORMAT_R8G8_UNORM; |
| image_create_info.extent = {32u, 32u, 1u}; |
| image_create_info.mipLevels = 1u; |
| image_create_info.arrayLayers = 1u; |
| image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; |
| image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT; |
| image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| vkt::Image image(*m_device, image_create_info); |
| vkt::ImageView image_view = image.CreateView(); |
| |
| VkRenderingFragmentDensityMapAttachmentInfoEXT fdm_attachment_info = vku::InitStructHelper(); |
| fdm_attachment_info.imageView = image_view; |
| fdm_attachment_info.imageLayout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkRenderingInfo rendering_info = vku::InitStructHelper(&fdm_attachment_info); |
| rendering_info.renderArea = {{0, 0}, {1u, 1u}}; |
| rendering_info.layerCount = 1u; |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRendering(rendering_info); |
| |
| VkPhysicalDeviceFragmentDensityMapOffsetPropertiesEXT fdm_offset_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fdm_offset_properties); |
| |
| int32_t width = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.width); |
| int32_t height = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.height); |
| VkOffset2D offset = {width, height}; |
| VkRenderPassFragmentDensityMapOffsetEndInfoEXT fdm_offset_end_info = vku::InitStructHelper(); |
| fdm_offset_end_info.fragmentDensityOffsetCount = 1u; |
| fdm_offset_end_info.pFragmentDensityOffsets = &offset; |
| VkRenderingEndInfoEXT rendering_end_info = vku::InitStructHelper(&fdm_offset_end_info); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassFragmentDensityMapOffsetEndInfoEXT-fragmentDensityMapOffsets-06503"); |
| vk::CmdEndRendering2EXT(m_command_buffer, &rendering_end_info); |
| m_errorMonitor->VerifyFound(); |
| |
| // Same error even if offsets are zero |
| offset = {0, 0}; |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassFragmentDensityMapOffsetEndInfoEXT-fragmentDensityMapOffsets-06503"); |
| vk::CmdEndRendering2EXT(m_command_buffer, &rendering_end_info); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, FragmentDensityMapOffsetAttachmentDynamicRendering) { |
| AddRequiredExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMap); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMapOffset); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::Image image(*m_device, 32u, 32u, VK_FORMAT_R8G8_UNORM, VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT); |
| vkt::ImageView image_view = image.CreateView(); |
| |
| VkRenderingFragmentDensityMapAttachmentInfoEXT fdm_attachment_info = vku::InitStructHelper(); |
| fdm_attachment_info.imageView = image_view; |
| fdm_attachment_info.imageLayout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkRenderingInfo rendering_info = vku::InitStructHelper(&fdm_attachment_info); |
| rendering_info.renderArea = {{0, 0}, {1u, 1u}}; |
| rendering_info.layerCount = 1u; |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRendering(rendering_info); |
| |
| VkPhysicalDeviceFragmentDensityMapOffsetPropertiesEXT fdm_offset_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fdm_offset_properties); |
| |
| int32_t width = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.width); |
| int32_t height = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.height); |
| VkOffset2D offset = {width, height}; |
| VkRenderPassFragmentDensityMapOffsetEndInfoEXT fdm_offset_end_info = vku::InitStructHelper(); |
| fdm_offset_end_info.fragmentDensityOffsetCount = 1u; |
| fdm_offset_end_info.pFragmentDensityOffsets = &offset; |
| VkRenderingEndInfoEXT rendering_end_info = vku::InitStructHelper(&fdm_offset_end_info); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassFragmentDensityMapOffsetEndInfoEXT-fragmentDensityMapAttachment-06504"); |
| vk::CmdEndRendering2EXT(m_command_buffer, &rendering_end_info); |
| m_errorMonitor->VerifyFound(); |
| |
| // Same error even if offsets are zero |
| offset = {0, 0}; |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassFragmentDensityMapOffsetEndInfoEXT-fragmentDensityMapAttachment-06504"); |
| vk::CmdEndRendering2EXT(m_command_buffer, &rendering_end_info); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, FragmentDensityMapOffsetDepthAttachmentDynamicRendering) { |
| AddRequiredExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMap); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMapOffset); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMapNonSubsampledImages); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| RETURN_IF_SKIP(Init()); |
| |
| VkImageCreateInfo image_create_info = BasicFragmentDensityMapImage(); |
| vkt::Image image(*m_device, image_create_info); |
| vkt::ImageView image_view = image.CreateView(); |
| |
| vkt::Image ds_image(*m_device, 32u, 32u, VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT); |
| vkt::ImageView ds_image_view = ds_image.CreateView(VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); |
| |
| VkClearValue clear_value; |
| clear_value.depthStencil = {1.0f, 0u}; |
| |
| VkRenderingFragmentDensityMapAttachmentInfoEXT fdm_attachment_info = vku::InitStructHelper(); |
| fdm_attachment_info.imageView = image_view; |
| fdm_attachment_info.imageLayout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkRenderingAttachmentInfo ds_attachment = vku::InitStructHelper(); |
| ds_attachment.imageView = ds_image_view; |
| ds_attachment.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; |
| ds_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| ds_attachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| ds_attachment.clearValue = clear_value; |
| |
| VkRenderingInfo rendering_info = vku::InitStructHelper(&fdm_attachment_info); |
| rendering_info.renderArea = {{0, 0}, {1u, 1u}}; |
| rendering_info.layerCount = 1u; |
| rendering_info.pDepthAttachment = &ds_attachment; |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRendering(rendering_info); |
| |
| VkPhysicalDeviceFragmentDensityMapOffsetPropertiesEXT fdm_offset_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fdm_offset_properties); |
| |
| int32_t width = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.width); |
| int32_t height = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.height); |
| VkOffset2D offset = {width, height}; |
| VkRenderPassFragmentDensityMapOffsetEndInfoEXT fdm_offset_end_info = vku::InitStructHelper(); |
| fdm_offset_end_info.fragmentDensityOffsetCount = 1u; |
| fdm_offset_end_info.pFragmentDensityOffsets = &offset; |
| VkRenderingEndInfoEXT rendering_end_info = vku::InitStructHelper(&fdm_offset_end_info); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassFragmentDensityMapOffsetEndInfoEXT-pDepthStencilAttachment-06505"); |
| vk::CmdEndRendering2EXT(m_command_buffer, &rendering_end_info); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, FragmentDensityMapOffsetColorAttachmentDynamicRendering) { |
| AddRequiredExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMap); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMapOffset); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMapNonSubsampledImages); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| RETURN_IF_SKIP(Init()); |
| |
| VkImageCreateInfo image_create_info = BasicFragmentDensityMapImage(); |
| vkt::Image image(*m_device, image_create_info); |
| vkt::ImageView image_view = image.CreateView(); |
| |
| vkt::Image color_image(*m_device, 32u, 32u, VK_FORMAT_R8G8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); |
| vkt::ImageView color_image_view = color_image.CreateView(); |
| |
| VkClearValue clear_value; |
| clear_value.color = m_clear_color; |
| |
| VkRenderingFragmentDensityMapAttachmentInfoEXT fdm_attachment_info = vku::InitStructHelper(); |
| fdm_attachment_info.imageView = image_view; |
| fdm_attachment_info.imageLayout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkRenderingAttachmentInfo color_attachment = vku::InitStructHelper(); |
| color_attachment.imageView = color_image_view; |
| color_attachment.imageLayout = VK_IMAGE_LAYOUT_GENERAL; |
| color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| color_attachment.clearValue = clear_value; |
| |
| VkRenderingInfo rendering_info = vku::InitStructHelper(&fdm_attachment_info); |
| rendering_info.renderArea = {{0, 0}, {1u, 1u}}; |
| rendering_info.layerCount = 1u; |
| rendering_info.colorAttachmentCount = 1u; |
| rendering_info.pColorAttachments = &color_attachment; |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRendering(rendering_info); |
| |
| VkPhysicalDeviceFragmentDensityMapOffsetPropertiesEXT fdm_offset_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fdm_offset_properties); |
| |
| int32_t width = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.width); |
| int32_t height = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.height); |
| VkOffset2D offset = {width, height}; |
| VkRenderPassFragmentDensityMapOffsetEndInfoEXT fdm_offset_end_info = vku::InitStructHelper(); |
| fdm_offset_end_info.fragmentDensityOffsetCount = 1u; |
| fdm_offset_end_info.pFragmentDensityOffsets = &offset; |
| VkRenderingEndInfoEXT rendering_end_info = vku::InitStructHelper(&fdm_offset_end_info); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassFragmentDensityMapOffsetEndInfoEXT-pColorAttachments-06507"); |
| vk::CmdEndRendering2EXT(m_command_buffer, &rendering_end_info); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, FragmentDensityMapOffsetWidthGranularityDynamicRendering) { |
| AddRequiredExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMap); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMapOffset); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDeviceFragmentDensityMapOffsetPropertiesEXT fdm_offset_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fdm_offset_properties); |
| |
| if (fdm_offset_properties.fragmentDensityOffsetGranularity.width == 1u) { |
| GTEST_SKIP() << "fragmentDensityOffsetGranularity width is 1"; |
| } |
| |
| VkImageCreateInfo image_create_info = BasicFragmentDensityMapImage(); |
| vkt::Image image(*m_device, image_create_info); |
| vkt::ImageView image_view = image.CreateView(); |
| |
| VkRenderingFragmentDensityMapAttachmentInfoEXT fdm_attachment_info = vku::InitStructHelper(); |
| fdm_attachment_info.imageView = image_view; |
| fdm_attachment_info.imageLayout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkRenderingInfo rendering_info = vku::InitStructHelper(&fdm_attachment_info); |
| rendering_info.renderArea = {{0, 0}, {1u, 1u}}; |
| rendering_info.layerCount = 1u; |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRendering(rendering_info); |
| |
| int32_t width = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.width); |
| VkOffset2D offset = {width + 1, 0}; |
| VkRenderPassFragmentDensityMapOffsetEndInfoEXT fdm_offset_end_info = vku::InitStructHelper(); |
| fdm_offset_end_info.fragmentDensityOffsetCount = 1u; |
| fdm_offset_end_info.pFragmentDensityOffsets = &offset; |
| VkRenderingEndInfoEXT rendering_end_info = vku::InitStructHelper(&fdm_offset_end_info); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassFragmentDensityMapOffsetEndInfoEXT-x-06512"); |
| vk::CmdEndRendering2EXT(m_command_buffer, &rendering_end_info); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, FragmentDensityMapOffsetEndRenderingMismatch) { |
| AddRequiredExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMap); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMapOffset); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::Image image(*m_device, 32u, 32u, VK_FORMAT_R8G8_UNORM, VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT); |
| vkt::ImageView image_view = image.CreateView(); |
| |
| VkRenderPassFragmentDensityMapCreateInfoEXT fragment_density_map_ci = vku::InitStructHelper(); |
| fragment_density_map_ci.fragmentDensityMapAttachment.attachment = VK_ATTACHMENT_UNUSED; |
| fragment_density_map_ci.fragmentDensityMapAttachment.layout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkAttachmentDescription attachment_description = {}; |
| attachment_description.format = VK_FORMAT_R8G8_UNORM; |
| attachment_description.samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_description.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_description.finalLayout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkSubpassDescription subpass_description = {}; |
| |
| VkRenderPassCreateInfo render_pass_ci = vku::InitStructHelper(&fragment_density_map_ci); |
| render_pass_ci.attachmentCount = 1u; |
| render_pass_ci.pAttachments = &attachment_description; |
| render_pass_ci.subpassCount = 1u; |
| render_pass_ci.pSubpasses = &subpass_description; |
| vkt::RenderPass render_pass(*m_device, render_pass_ci); |
| vkt::Framebuffer framebuffer(*m_device, render_pass, 1u, &image_view.handle()); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(render_pass, framebuffer); |
| |
| VkOffset2D offset = {0, 0}; |
| VkRenderPassFragmentDensityMapOffsetEndInfoEXT fdm_offset_end_info = vku::InitStructHelper(); |
| fdm_offset_end_info.fragmentDensityOffsetCount = 1u; |
| fdm_offset_end_info.pFragmentDensityOffsets = &offset; |
| VkRenderingEndInfoEXT rendering_end_info = vku::InitStructHelper(&fdm_offset_end_info); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdEndRendering2KHR-None-10610"); |
| vk::CmdEndRendering2EXT(m_command_buffer, &rendering_end_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, FragmentDensityMapOffsetAttachment) { |
| AddRequiredExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMap); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMapOffset); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::Image image(*m_device, 32u, 32u, VK_FORMAT_R8G8_UNORM, VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT); |
| vkt::ImageView image_view = image.CreateView(); |
| |
| VkRenderPassFragmentDensityMapCreateInfoEXT fragment_density_map_ci = vku::InitStructHelper(); |
| fragment_density_map_ci.fragmentDensityMapAttachment.layout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkAttachmentDescription attachment_description = {}; |
| attachment_description.format = VK_FORMAT_R8G8_UNORM; |
| attachment_description.samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_description.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_description.finalLayout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkSubpassDescription subpass_description = {}; |
| |
| VkRenderPassCreateInfo render_pass_ci = vku::InitStructHelper(&fragment_density_map_ci); |
| render_pass_ci.attachmentCount = 1u; |
| render_pass_ci.pAttachments = &attachment_description; |
| render_pass_ci.subpassCount = 1u; |
| render_pass_ci.pSubpasses = &subpass_description; |
| vkt::RenderPass render_pass(*m_device, render_pass_ci); |
| vkt::Framebuffer framebuffer(*m_device, render_pass, 1u, &image_view.handle()); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(render_pass, framebuffer); |
| |
| VkPhysicalDeviceFragmentDensityMapOffsetPropertiesEXT fdm_offset_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fdm_offset_properties); |
| |
| int32_t width = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.width); |
| int32_t height = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.height); |
| VkOffset2D offset = {width, height}; |
| VkRenderPassFragmentDensityMapOffsetEndInfoEXT fdm_offset_end_info = vku::InitStructHelper(); |
| fdm_offset_end_info.fragmentDensityOffsetCount = 1u; |
| fdm_offset_end_info.pFragmentDensityOffsets = &offset; |
| VkSubpassEndInfo subpass_end_info = vku::InitStructHelper(&fdm_offset_end_info); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassFragmentDensityMapOffsetEndInfoEXT-fragmentDensityMapAttachment-06504"); |
| vk::CmdEndRenderPass2KHR(m_command_buffer, &subpass_end_info); |
| m_errorMonitor->VerifyFound(); |
| |
| // Same error even if offsets are zero |
| offset = {0, 0}; |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassFragmentDensityMapOffsetEndInfoEXT-fragmentDensityMapAttachment-06504"); |
| vk::CmdEndRenderPass2KHR(m_command_buffer, &subpass_end_info); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, FragmentDensityMapOffsetAttachmentQCOM) { |
| AddRequiredExtensions(VK_QCOM_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMap); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMapOffset); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::Image image(*m_device, 32u, 32u, VK_FORMAT_R8G8_UNORM, VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT); |
| vkt::ImageView image_view = image.CreateView(); |
| |
| VkRenderPassFragmentDensityMapCreateInfoEXT fragment_density_map_ci = vku::InitStructHelper(); |
| fragment_density_map_ci.fragmentDensityMapAttachment.layout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkAttachmentDescription attachment_description = {}; |
| attachment_description.format = VK_FORMAT_R8G8_UNORM; |
| attachment_description.samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_description.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_description.finalLayout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkSubpassDescription subpass_description = {}; |
| |
| VkRenderPassCreateInfo render_pass_ci = vku::InitStructHelper(&fragment_density_map_ci); |
| render_pass_ci.attachmentCount = 1u; |
| render_pass_ci.pAttachments = &attachment_description; |
| render_pass_ci.subpassCount = 1u; |
| render_pass_ci.pSubpasses = &subpass_description; |
| vkt::RenderPass render_pass(*m_device, render_pass_ci); |
| vkt::Framebuffer framebuffer(*m_device, render_pass, 1u, &image_view.handle()); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(render_pass, framebuffer); |
| |
| VkPhysicalDeviceFragmentDensityMapOffsetPropertiesQCOM fdm_offset_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fdm_offset_properties); |
| |
| int32_t width = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.width); |
| int32_t height = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.height); |
| VkOffset2D offset = {width, height}; |
| VkSubpassFragmentDensityMapOffsetEndInfoQCOM fdm_offset_end_info = vku::InitStructHelper(); |
| fdm_offset_end_info.fragmentDensityOffsetCount = 1u; |
| fdm_offset_end_info.pFragmentDensityOffsets = &offset; |
| VkSubpassEndInfo subpass_end_info = vku::InitStructHelper(&fdm_offset_end_info); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassFragmentDensityMapOffsetEndInfoEXT-fragmentDensityMapAttachment-06504"); |
| vk::CmdEndRenderPass2KHR(m_command_buffer, &subpass_end_info); |
| m_errorMonitor->VerifyFound(); |
| |
| // Same error even if offsets are zero |
| offset = {0, 0}; |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassFragmentDensityMapOffsetEndInfoEXT-fragmentDensityMapAttachment-06504"); |
| vk::CmdEndRenderPass2KHR(m_command_buffer, &subpass_end_info); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, FragmentDensityMapOffsetDepthAttachment) { |
| AddRequiredExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMap); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMapOffset); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::Image image(*m_device, 32u, 32u, VK_FORMAT_R8G8_UNORM, VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT); |
| vkt::ImageView image_view = image.CreateView(); |
| vkt::Image ds_image(*m_device, 32u, 32u, VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT); |
| vkt::ImageView ds_image_view = ds_image.CreateView(VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); |
| |
| VkRenderPassFragmentDensityMapCreateInfoEXT fragment_density_map_ci = vku::InitStructHelper(); |
| fragment_density_map_ci.fragmentDensityMapAttachment.attachment = VK_ATTACHMENT_UNUSED; |
| fragment_density_map_ci.fragmentDensityMapAttachment.layout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkAttachmentDescription attachment_descriptions[2]; |
| attachment_descriptions[0].flags = 0u; |
| attachment_descriptions[0].format = VK_FORMAT_R8G8_UNORM; |
| attachment_descriptions[0].samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_descriptions[0].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descriptions[0].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descriptions[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descriptions[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descriptions[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_descriptions[0].finalLayout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| attachment_descriptions[1].flags = 0u; |
| attachment_descriptions[1].format = VK_FORMAT_D24_UNORM_S8_UINT; |
| attachment_descriptions[1].samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_descriptions[1].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descriptions[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descriptions[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descriptions[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descriptions[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_descriptions[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; |
| |
| VkAttachmentReference ds_attachment_reference; |
| ds_attachment_reference.attachment = 1u; |
| ds_attachment_reference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; |
| |
| VkSubpassDescription subpass_description = {}; |
| subpass_description.pDepthStencilAttachment = &ds_attachment_reference; |
| |
| VkRenderPassCreateInfo render_pass_ci = vku::InitStructHelper(&fragment_density_map_ci); |
| render_pass_ci.attachmentCount = 2u; |
| render_pass_ci.pAttachments = attachment_descriptions; |
| render_pass_ci.subpassCount = 1u; |
| render_pass_ci.pSubpasses = &subpass_description; |
| vkt::RenderPass render_pass(*m_device, render_pass_ci); |
| |
| VkImageView image_views[2] = {image_view, ds_image_view}; |
| vkt::Framebuffer framebuffer(*m_device, render_pass, 2u, image_views); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(render_pass, framebuffer); |
| |
| VkPhysicalDeviceFragmentDensityMapOffsetPropertiesEXT fdm_offset_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fdm_offset_properties); |
| |
| int32_t width = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.width); |
| int32_t height = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.height); |
| VkOffset2D offset = {width, height}; |
| VkRenderPassFragmentDensityMapOffsetEndInfoEXT fdm_offset_end_info = vku::InitStructHelper(); |
| fdm_offset_end_info.fragmentDensityOffsetCount = 1u; |
| fdm_offset_end_info.pFragmentDensityOffsets = &offset; |
| VkSubpassEndInfo subpass_end_info = vku::InitStructHelper(&fdm_offset_end_info); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassFragmentDensityMapOffsetEndInfoEXT-pDepthStencilAttachment-06505"); |
| vk::CmdEndRenderPass2KHR(m_command_buffer, &subpass_end_info); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, FragmentDensityMapOffsetInputAttachment) { |
| AddRequiredExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMap); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMapOffset); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::Image image(*m_device, 32u, 32u, VK_FORMAT_R8G8_UNORM, VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT); |
| vkt::ImageView image_view = image.CreateView(); |
| vkt::Image input_image(*m_device, 32u, 32u, VK_FORMAT_R8G8_UNORM, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT); |
| vkt::ImageView input_image_view = input_image.CreateView(); |
| |
| VkRenderPassFragmentDensityMapCreateInfoEXT fragment_density_map_ci = vku::InitStructHelper(); |
| fragment_density_map_ci.fragmentDensityMapAttachment.attachment = VK_ATTACHMENT_UNUSED; |
| fragment_density_map_ci.fragmentDensityMapAttachment.layout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkAttachmentDescription attachment_descriptions[2]; |
| attachment_descriptions[0].flags = 0u; |
| attachment_descriptions[0].format = VK_FORMAT_R8G8_UNORM; |
| attachment_descriptions[0].samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_descriptions[0].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descriptions[0].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descriptions[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descriptions[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descriptions[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_descriptions[0].finalLayout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| attachment_descriptions[1].flags = 0u; |
| attachment_descriptions[1].format = VK_FORMAT_R8G8_UNORM; |
| attachment_descriptions[1].samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_descriptions[1].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descriptions[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descriptions[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descriptions[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descriptions[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_descriptions[1].finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| VkAttachmentReference input_attachment_reference; |
| input_attachment_reference.attachment = 1u; |
| input_attachment_reference.layout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| VkSubpassDescription subpass_description = {}; |
| subpass_description.inputAttachmentCount = 1u; |
| subpass_description.pInputAttachments = &input_attachment_reference; |
| |
| VkRenderPassCreateInfo render_pass_ci = vku::InitStructHelper(&fragment_density_map_ci); |
| render_pass_ci.attachmentCount = 2u; |
| render_pass_ci.pAttachments = attachment_descriptions; |
| render_pass_ci.subpassCount = 1u; |
| render_pass_ci.pSubpasses = &subpass_description; |
| vkt::RenderPass render_pass(*m_device, render_pass_ci); |
| |
| VkImageView image_views[2] = {image_view, input_image_view}; |
| vkt::Framebuffer framebuffer(*m_device, render_pass, 2u, image_views); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(render_pass, framebuffer); |
| |
| VkPhysicalDeviceFragmentDensityMapOffsetPropertiesEXT fdm_offset_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fdm_offset_properties); |
| |
| int32_t width = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.width); |
| int32_t height = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.height); |
| VkOffset2D offset = {width, height}; |
| VkRenderPassFragmentDensityMapOffsetEndInfoEXT fdm_offset_end_info = vku::InitStructHelper(); |
| fdm_offset_end_info.fragmentDensityOffsetCount = 1u; |
| fdm_offset_end_info.pFragmentDensityOffsets = &offset; |
| VkSubpassEndInfo subpass_end_info = vku::InitStructHelper(&fdm_offset_end_info); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassFragmentDensityMapOffsetEndInfoEXT-pInputAttachments-06506"); |
| vk::CmdEndRenderPass2KHR(m_command_buffer, &subpass_end_info); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, FragmentDensityMapOffsetColorAttachment) { |
| AddRequiredExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMap); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMapOffset); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::Image image(*m_device, 32u, 32u, VK_FORMAT_R8G8_UNORM, VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT); |
| vkt::ImageView image_view = image.CreateView(); |
| vkt::Image color_image(*m_device, 32u, 32u, VK_FORMAT_R8G8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); |
| vkt::ImageView color_image_view = color_image.CreateView(); |
| |
| VkRenderPassFragmentDensityMapCreateInfoEXT fragment_density_map_ci = vku::InitStructHelper(); |
| fragment_density_map_ci.fragmentDensityMapAttachment.attachment = VK_ATTACHMENT_UNUSED; |
| fragment_density_map_ci.fragmentDensityMapAttachment.layout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkAttachmentDescription attachment_descriptions[2]; |
| attachment_descriptions[0].flags = 0u; |
| attachment_descriptions[0].format = VK_FORMAT_R8G8_UNORM; |
| attachment_descriptions[0].samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_descriptions[0].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descriptions[0].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descriptions[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descriptions[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descriptions[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_descriptions[0].finalLayout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| attachment_descriptions[1].flags = 0u; |
| attachment_descriptions[1].format = VK_FORMAT_R8G8_UNORM; |
| attachment_descriptions[1].samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_descriptions[1].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descriptions[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descriptions[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descriptions[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descriptions[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_descriptions[1].finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| VkAttachmentReference color_attachment_reference; |
| color_attachment_reference.attachment = 1u; |
| color_attachment_reference.layout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| VkSubpassDescription subpass_description = {}; |
| subpass_description.colorAttachmentCount = 1u; |
| subpass_description.pColorAttachments = &color_attachment_reference; |
| |
| VkRenderPassCreateInfo render_pass_ci = vku::InitStructHelper(&fragment_density_map_ci); |
| render_pass_ci.attachmentCount = 2u; |
| render_pass_ci.pAttachments = attachment_descriptions; |
| render_pass_ci.subpassCount = 1u; |
| render_pass_ci.pSubpasses = &subpass_description; |
| vkt::RenderPass render_pass(*m_device, render_pass_ci); |
| |
| VkImageView image_views[2] = {image_view, color_image_view}; |
| vkt::Framebuffer framebuffer(*m_device, render_pass, 2u, image_views); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(render_pass, framebuffer); |
| |
| VkPhysicalDeviceFragmentDensityMapOffsetPropertiesEXT fdm_offset_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fdm_offset_properties); |
| |
| int32_t width = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.width); |
| int32_t height = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.height); |
| VkOffset2D offset = {width, height}; |
| VkRenderPassFragmentDensityMapOffsetEndInfoEXT fdm_offset_end_info = vku::InitStructHelper(); |
| fdm_offset_end_info.fragmentDensityOffsetCount = 1u; |
| fdm_offset_end_info.pFragmentDensityOffsets = &offset; |
| VkSubpassEndInfo subpass_end_info = vku::InitStructHelper(&fdm_offset_end_info); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassFragmentDensityMapOffsetEndInfoEXT-pColorAttachments-06507"); |
| vk::CmdEndRenderPass2KHR(m_command_buffer, &subpass_end_info); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, FragmentDensityMapOffsetResolveAttachment) { |
| AddRequiredExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMap); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMapOffset); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::Image image(*m_device, 32u, 32u, VK_FORMAT_R8G8_UNORM, VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT); |
| vkt::ImageView image_view = image.CreateView(); |
| |
| VkImageCreateInfo image_create_info = vku::InitStructHelper(); |
| image_create_info.flags = VK_IMAGE_CREATE_FRAGMENT_DENSITY_MAP_OFFSET_BIT_EXT; |
| image_create_info.imageType = VK_IMAGE_TYPE_2D; |
| image_create_info.format = VK_FORMAT_R8G8_UNORM; |
| image_create_info.extent = {32u, 32u, 1u}; |
| image_create_info.mipLevels = 1u; |
| image_create_info.arrayLayers = 1u; |
| image_create_info.samples = VK_SAMPLE_COUNT_4_BIT; |
| image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| vkt::Image color_image(*m_device, image_create_info); |
| vkt::ImageView color_image_view = color_image.CreateView(); |
| vkt::Image resolve_image(*m_device, 32u, 32u, VK_FORMAT_R8G8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); |
| vkt::ImageView resolve_image_view = resolve_image.CreateView(); |
| |
| VkRenderPassFragmentDensityMapCreateInfoEXT fragment_density_map_ci = vku::InitStructHelper(); |
| fragment_density_map_ci.fragmentDensityMapAttachment.attachment = VK_ATTACHMENT_UNUSED; |
| fragment_density_map_ci.fragmentDensityMapAttachment.layout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkAttachmentDescription attachment_descriptions[3]; |
| attachment_descriptions[0].flags = 0u; |
| attachment_descriptions[0].format = VK_FORMAT_R8G8_UNORM; |
| attachment_descriptions[0].samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_descriptions[0].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descriptions[0].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descriptions[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descriptions[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descriptions[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_descriptions[0].finalLayout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| attachment_descriptions[1].flags = 0u; |
| attachment_descriptions[1].format = VK_FORMAT_R8G8_UNORM; |
| attachment_descriptions[1].samples = VK_SAMPLE_COUNT_4_BIT; |
| attachment_descriptions[1].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descriptions[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descriptions[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descriptions[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descriptions[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_descriptions[1].finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| attachment_descriptions[2].flags = 0u; |
| attachment_descriptions[2].format = VK_FORMAT_R8G8_UNORM; |
| attachment_descriptions[2].samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_descriptions[2].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descriptions[2].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descriptions[2].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descriptions[2].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descriptions[2].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_descriptions[2].finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| VkAttachmentReference color_attachment_reference; |
| color_attachment_reference.attachment = 1u; |
| color_attachment_reference.layout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| VkAttachmentReference resolve_attachment_reference; |
| resolve_attachment_reference.attachment = 2u; |
| resolve_attachment_reference.layout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| VkSubpassDescription subpass_description = {}; |
| subpass_description.colorAttachmentCount = 1u; |
| subpass_description.pColorAttachments = &color_attachment_reference; |
| subpass_description.pResolveAttachments = &resolve_attachment_reference; |
| |
| VkRenderPassCreateInfo render_pass_ci = vku::InitStructHelper(&fragment_density_map_ci); |
| render_pass_ci.attachmentCount = 3u; |
| render_pass_ci.pAttachments = attachment_descriptions; |
| render_pass_ci.subpassCount = 1u; |
| render_pass_ci.pSubpasses = &subpass_description; |
| vkt::RenderPass render_pass(*m_device, render_pass_ci); |
| |
| VkImageView image_views[3] = {image_view, color_image_view, resolve_image_view}; |
| vkt::Framebuffer framebuffer(*m_device, render_pass, 3u, image_views); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(render_pass, framebuffer); |
| |
| VkPhysicalDeviceFragmentDensityMapOffsetPropertiesEXT fdm_offset_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fdm_offset_properties); |
| |
| int32_t width = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.width); |
| int32_t height = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.height); |
| VkOffset2D offset = {width, height}; |
| VkRenderPassFragmentDensityMapOffsetEndInfoEXT fdm_offset_end_info = vku::InitStructHelper(); |
| fdm_offset_end_info.fragmentDensityOffsetCount = 1u; |
| fdm_offset_end_info.pFragmentDensityOffsets = &offset; |
| VkSubpassEndInfo subpass_end_info = vku::InitStructHelper(&fdm_offset_end_info); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassFragmentDensityMapOffsetEndInfoEXT-pResolveAttachments-06508"); |
| vk::CmdEndRenderPass2KHR(m_command_buffer, &subpass_end_info); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, FragmentDensityMapOffsetPreserveAttachment) { |
| AddRequiredExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMap); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMapOffset); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::Image image(*m_device, 32u, 32u, VK_FORMAT_R8G8_UNORM, VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT); |
| vkt::ImageView image_view = image.CreateView(); |
| vkt::Image color_image(*m_device, 32u, 32u, VK_FORMAT_R8G8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); |
| vkt::ImageView color_image_view = color_image.CreateView(); |
| |
| VkRenderPassFragmentDensityMapCreateInfoEXT fragment_density_map_ci = vku::InitStructHelper(); |
| fragment_density_map_ci.fragmentDensityMapAttachment.attachment = VK_ATTACHMENT_UNUSED; |
| fragment_density_map_ci.fragmentDensityMapAttachment.layout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkAttachmentDescription attachment_descriptions[2]; |
| attachment_descriptions[0].flags = 0u; |
| attachment_descriptions[0].format = VK_FORMAT_R8G8_UNORM; |
| attachment_descriptions[0].samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_descriptions[0].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descriptions[0].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descriptions[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descriptions[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descriptions[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_descriptions[0].finalLayout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| attachment_descriptions[1].flags = 0u; |
| attachment_descriptions[1].format = VK_FORMAT_R8G8_UNORM; |
| attachment_descriptions[1].samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_descriptions[1].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descriptions[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descriptions[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descriptions[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descriptions[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_descriptions[1].finalLayout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| uint32_t preserve_attachment = 1u; |
| VkSubpassDescription subpass_description = {}; |
| subpass_description.preserveAttachmentCount = 1u; |
| subpass_description.pPreserveAttachments = &preserve_attachment; |
| |
| VkRenderPassCreateInfo render_pass_ci = vku::InitStructHelper(&fragment_density_map_ci); |
| render_pass_ci.attachmentCount = 2u; |
| render_pass_ci.pAttachments = attachment_descriptions; |
| render_pass_ci.subpassCount = 1u; |
| render_pass_ci.pSubpasses = &subpass_description; |
| vkt::RenderPass render_pass(*m_device, render_pass_ci); |
| |
| VkImageView image_views[2] = {image_view, color_image_view}; |
| vkt::Framebuffer framebuffer(*m_device, render_pass, 2u, image_views); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(render_pass, framebuffer); |
| |
| VkPhysicalDeviceFragmentDensityMapOffsetPropertiesEXT fdm_offset_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fdm_offset_properties); |
| |
| int32_t width = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.width); |
| int32_t height = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.height); |
| VkOffset2D offset = {width, height}; |
| VkRenderPassFragmentDensityMapOffsetEndInfoEXT fdm_offset_end_info = vku::InitStructHelper(); |
| fdm_offset_end_info.fragmentDensityOffsetCount = 1u; |
| fdm_offset_end_info.pFragmentDensityOffsets = &offset; |
| VkSubpassEndInfo subpass_end_info = vku::InitStructHelper(&fdm_offset_end_info); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassFragmentDensityMapOffsetEndInfoEXT-pPreserveAttachments-06509"); |
| vk::CmdEndRenderPass2KHR(m_command_buffer, &subpass_end_info); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, FragmentDensityMapOffsetMultiview) { |
| AddRequiredExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_MULTIVIEW_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMap); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMapOffset); |
| AddRequiredFeature(vkt::Feature::multiview); |
| RETURN_IF_SKIP(Init()); |
| |
| VkImageCreateInfo image_create_info = vku::InitStructHelper(); |
| image_create_info.flags = VK_IMAGE_CREATE_FRAGMENT_DENSITY_MAP_OFFSET_BIT_EXT; |
| image_create_info.imageType = VK_IMAGE_TYPE_2D; |
| image_create_info.format = VK_FORMAT_R8G8_UNORM; |
| image_create_info.extent = {32u, 32u, 1u}; |
| image_create_info.mipLevels = 1u; |
| image_create_info.arrayLayers = 2u; |
| image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; |
| image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| vkt::Image image(*m_device, image_create_info); |
| vkt::ImageView image_view = image.CreateView(VK_IMAGE_VIEW_TYPE_2D_ARRAY); |
| |
| VkRenderPassFragmentDensityMapCreateInfoEXT fragment_density_map_ci = vku::InitStructHelper(); |
| fragment_density_map_ci.fragmentDensityMapAttachment.layout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkAttachmentDescription2 attachment_description = vku::InitStructHelper(); |
| attachment_description.format = VK_FORMAT_R8G8_UNORM; |
| attachment_description.samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_description.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_description.finalLayout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkSubpassDescription2 subpass_description = vku::InitStructHelper(); |
| subpass_description.viewMask = 0x3u; |
| |
| VkRenderPassCreateInfo2 render_pass_ci = vku::InitStructHelper(&fragment_density_map_ci); |
| render_pass_ci.attachmentCount = 1u; |
| render_pass_ci.pAttachments = &attachment_description; |
| render_pass_ci.subpassCount = 1u; |
| render_pass_ci.pSubpasses = &subpass_description; |
| vkt::RenderPass render_pass(*m_device, render_pass_ci); |
| vkt::Framebuffer framebuffer(*m_device, render_pass, 1u, &image_view.handle()); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(render_pass, framebuffer); |
| |
| VkPhysicalDeviceFragmentDensityMapOffsetPropertiesEXT fdm_offset_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fdm_offset_properties); |
| |
| int32_t width = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.width); |
| int32_t height = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.height); |
| VkOffset2D offset = {width, height}; |
| VkRenderPassFragmentDensityMapOffsetEndInfoEXT fdm_offset_end_info = vku::InitStructHelper(); |
| fdm_offset_end_info.fragmentDensityOffsetCount = 1u; |
| fdm_offset_end_info.pFragmentDensityOffsets = &offset; |
| VkSubpassEndInfo subpass_end_info = vku::InitStructHelper(&fdm_offset_end_info); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassFragmentDensityMapOffsetEndInfoEXT-fragmentDensityOffsetCount-06510"); |
| vk::CmdEndRenderPass2KHR(m_command_buffer, &subpass_end_info); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, FragmentDensityMapOffsetInvalidCount) { |
| AddRequiredExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMap); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMapOffset); |
| RETURN_IF_SKIP(Init()); |
| |
| VkImageCreateInfo image_create_info = BasicFragmentDensityMapImage(); |
| vkt::Image image(*m_device, image_create_info); |
| vkt::ImageView image_view = image.CreateView(); |
| |
| VkRenderPassFragmentDensityMapCreateInfoEXT fragment_density_map_ci = vku::InitStructHelper(); |
| fragment_density_map_ci.fragmentDensityMapAttachment.layout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkAttachmentDescription attachment_description = {}; |
| attachment_description.format = VK_FORMAT_R8G8_UNORM; |
| attachment_description.samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_description.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_description.finalLayout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkSubpassDescription subpass_description = {}; |
| |
| VkRenderPassCreateInfo render_pass_ci = vku::InitStructHelper(&fragment_density_map_ci); |
| render_pass_ci.attachmentCount = 1u; |
| render_pass_ci.pAttachments = &attachment_description; |
| render_pass_ci.subpassCount = 1u; |
| render_pass_ci.pSubpasses = &subpass_description; |
| vkt::RenderPass render_pass(*m_device, render_pass_ci); |
| vkt::Framebuffer framebuffer(*m_device, render_pass, 1u, &image_view.handle()); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(render_pass, framebuffer); |
| |
| VkOffset2D offsets[2] = {{0, 0}, {0, 0}}; |
| VkRenderPassFragmentDensityMapOffsetEndInfoEXT fdm_offset_end_info = vku::InitStructHelper(); |
| fdm_offset_end_info.fragmentDensityOffsetCount = 2u; |
| fdm_offset_end_info.pFragmentDensityOffsets = offsets; |
| VkSubpassEndInfo subpass_end_info = vku::InitStructHelper(&fdm_offset_end_info); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassFragmentDensityMapOffsetEndInfoEXT-fragmentDensityOffsetCount-06511"); |
| vk::CmdEndRenderPass2KHR(m_command_buffer, &subpass_end_info); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, FragmentDensityMapOffsetWidthGranularity) { |
| AddRequiredExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMap); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMapOffset); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDeviceFragmentDensityMapOffsetPropertiesEXT fdm_offset_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fdm_offset_properties); |
| |
| if (fdm_offset_properties.fragmentDensityOffsetGranularity.width == 1u) { |
| GTEST_SKIP() << "fragmentDensityOffsetGranularity width is 1"; |
| } |
| |
| VkImageCreateInfo image_create_info = BasicFragmentDensityMapImage(); |
| vkt::Image image(*m_device, image_create_info); |
| vkt::ImageView image_view = image.CreateView(); |
| |
| VkRenderPassFragmentDensityMapCreateInfoEXT fragment_density_map_ci = vku::InitStructHelper(); |
| fragment_density_map_ci.fragmentDensityMapAttachment.layout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkAttachmentDescription attachment_description = {}; |
| attachment_description.format = VK_FORMAT_R8G8_UNORM; |
| attachment_description.samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_description.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_description.finalLayout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkSubpassDescription subpass_description = {}; |
| |
| VkRenderPassCreateInfo render_pass_ci = vku::InitStructHelper(&fragment_density_map_ci); |
| render_pass_ci.attachmentCount = 1u; |
| render_pass_ci.pAttachments = &attachment_description; |
| render_pass_ci.subpassCount = 1u; |
| render_pass_ci.pSubpasses = &subpass_description; |
| vkt::RenderPass render_pass(*m_device, render_pass_ci); |
| vkt::Framebuffer framebuffer(*m_device, render_pass, 1u, &image_view.handle()); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(render_pass, framebuffer); |
| |
| int32_t width = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.width); |
| VkOffset2D offset = {width + 1, 0}; |
| VkRenderPassFragmentDensityMapOffsetEndInfoEXT fdm_offset_end_info = vku::InitStructHelper(); |
| fdm_offset_end_info.fragmentDensityOffsetCount = 1u; |
| fdm_offset_end_info.pFragmentDensityOffsets = &offset; |
| VkSubpassEndInfo subpass_end_info = vku::InitStructHelper(&fdm_offset_end_info); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassFragmentDensityMapOffsetEndInfoEXT-x-06512"); |
| vk::CmdEndRenderPass2KHR(m_command_buffer, &subpass_end_info); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, FragmentDensityMapOffsetHeightGranularity) { |
| AddRequiredExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMap); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMapOffset); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDeviceFragmentDensityMapOffsetPropertiesEXT fdm_offset_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fdm_offset_properties); |
| |
| if (fdm_offset_properties.fragmentDensityOffsetGranularity.height == 1u) { |
| GTEST_SKIP() << "fragmentDensityOffsetGranularity height is 1"; |
| } |
| |
| VkImageCreateInfo image_create_info = BasicFragmentDensityMapImage(); |
| vkt::Image image(*m_device, image_create_info); |
| vkt::ImageView image_view = image.CreateView(); |
| |
| VkRenderPassFragmentDensityMapCreateInfoEXT fragment_density_map_ci = vku::InitStructHelper(); |
| fragment_density_map_ci.fragmentDensityMapAttachment.layout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkAttachmentDescription attachment_description = {}; |
| attachment_description.format = VK_FORMAT_R8G8_UNORM; |
| attachment_description.samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_description.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_description.finalLayout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkSubpassDescription subpass_description = {}; |
| |
| VkRenderPassCreateInfo render_pass_ci = vku::InitStructHelper(&fragment_density_map_ci); |
| render_pass_ci.attachmentCount = 1u; |
| render_pass_ci.pAttachments = &attachment_description; |
| render_pass_ci.subpassCount = 1u; |
| render_pass_ci.pSubpasses = &subpass_description; |
| vkt::RenderPass render_pass(*m_device, render_pass_ci); |
| vkt::Framebuffer framebuffer(*m_device, render_pass, 1u, &image_view.handle()); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(render_pass, framebuffer); |
| |
| int32_t height = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.height); |
| VkOffset2D offset = {0, height + 1}; |
| VkRenderPassFragmentDensityMapOffsetEndInfoEXT fdm_offset_end_info = vku::InitStructHelper(); |
| fdm_offset_end_info.fragmentDensityOffsetCount = 1u; |
| fdm_offset_end_info.pFragmentDensityOffsets = &offset; |
| VkSubpassEndInfo subpass_end_info = vku::InitStructHelper(&fdm_offset_end_info); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassFragmentDensityMapOffsetEndInfoEXT-y-06513"); |
| vk::CmdEndRenderPass2KHR(m_command_buffer, &subpass_end_info); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, ShadingRateImageNV) { |
| TEST_DESCRIPTION("Test VK_NV_shading_rate_image."); |
| AddRequiredExtensions(VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::shadingRateImage); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| // R8_UINT doesn't seem to be supported |
| if (!IsPlatformMockICD()) { |
| GTEST_SKIP() << "Need someone to figure out which format NVIDIA supports"; |
| } |
| |
| VkImageCreateInfo image_create_info = vku::InitStructHelper(); |
| image_create_info.imageType = VK_IMAGE_TYPE_2D; |
| image_create_info.format = VK_FORMAT_R8_UINT; |
| image_create_info.extent = {4, 4, 1}; |
| image_create_info.mipLevels = 1; |
| image_create_info.arrayLayers = 1; |
| image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; |
| image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV; |
| image_create_info.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; |
| |
| image_create_info.imageType = VK_IMAGE_TYPE_3D; |
| CreateImageTest(image_create_info, "VUID-VkImageCreateInfo-imageType-02082"); |
| |
| image_create_info.imageType = VK_IMAGE_TYPE_2D; |
| image_create_info.arrayLayers = 6; |
| |
| image_create_info.samples = VK_SAMPLE_COUNT_2_BIT; |
| CreateImageTest(image_create_info, "VUID-VkImageCreateInfo-samples-02083"); |
| |
| image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; |
| |
| image_create_info.tiling = VK_IMAGE_TILING_LINEAR; |
| CreateImageTest(image_create_info, "VUID-VkImageCreateInfo-shadingRateImage-07727"); |
| |
| image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; |
| vkt::Image image(*m_device, image_create_info, vkt::set_layout); |
| |
| VkImageViewCreateInfo ivci = vku::InitStructHelper(); |
| ivci.image = image; |
| ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; |
| ivci.format = VK_FORMAT_R8_UINT; |
| ivci.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; |
| |
| { |
| ivci.viewType = VK_IMAGE_VIEW_TYPE_CUBE; |
| ivci.subresourceRange.layerCount = 6; |
| m_errorMonitor->SetDesiredError("VUID-VkImageViewCreateInfo-image-02086"); |
| m_errorMonitor->SetDesiredError("VUID-VkImageViewCreateInfo-image-01003"); |
| m_errorMonitor->SetDesiredError("VUID-VkImageViewCreateInfo-usage-04551"); |
| vkt::ImageView view(*m_device, ivci); |
| m_errorMonitor->VerifyFound(); |
| ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; |
| ivci.subresourceRange.layerCount = 1; |
| } |
| |
| { |
| ivci.format = VK_FORMAT_R8_UNORM; |
| m_errorMonitor->SetDesiredError("VUID-VkImageViewCreateInfo-image-02087"); |
| vkt::ImageView view(*m_device, ivci); |
| m_errorMonitor->VerifyFound(); |
| ivci.format = VK_FORMAT_R8_UINT; |
| } |
| |
| vkt::ImageView view(*m_device, ivci); |
| |
| VkPipelineViewportShadingRateImageStateCreateInfoNV vsrisci = vku::InitStructHelper(); |
| |
| VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f}; |
| VkViewport viewports[20] = {viewport, viewport}; |
| VkRect2D scissor = {{0, 0}, {64, 64}}; |
| VkRect2D scissors[20] = {scissor, scissor}; |
| VkDynamicState dyn_palette = VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV; |
| VkPipelineDynamicStateCreateInfo dyn = {VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, nullptr, 0, 1, &dyn_palette}; |
| |
| // viewportCount must be 0 or 1 when multiViewport is disabled |
| { |
| const auto break_vp = [&](CreatePipelineHelper& helper) { |
| helper.vp_state_ci_.viewportCount = 2; |
| helper.vp_state_ci_.pViewports = viewports; |
| helper.vp_state_ci_.scissorCount = 2; |
| helper.vp_state_ci_.pScissors = scissors; |
| helper.vp_state_ci_.pNext = &vsrisci; |
| helper.dyn_state_ci_ = dyn; |
| |
| vsrisci.shadingRateImageEnable = VK_TRUE; |
| vsrisci.viewportCount = 2; |
| }; |
| constexpr std::array vuids = {"VUID-VkPipelineViewportShadingRateImageStateCreateInfoNV-viewportCount-02054", |
| "VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216", |
| "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217"}; |
| CreatePipelineHelper::OneshotTest(*this, break_vp, kErrorBit, vuids); |
| } |
| { |
| const auto break_vp = [&](CreatePipelineHelper& helper) { |
| helper.vp_state_ci_.viewportCount = 1; |
| helper.vp_state_ci_.pViewports = viewports; |
| helper.vp_state_ci_.scissorCount = 1; |
| helper.vp_state_ci_.pScissors = scissors; |
| helper.vp_state_ci_.pNext = &vsrisci; |
| |
| vsrisci.shadingRateImageEnable = VK_TRUE; |
| vsrisci.viewportCount = 1; |
| }; |
| CreatePipelineHelper::OneshotTest(*this, break_vp, kErrorBit, |
| std::vector<std::string>({"VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-04057"})); |
| } |
| |
| vkt::Image non_sri_image(*m_device, 256, 256, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); |
| vkt::ImageView non_sri_view = non_sri_image.CreateView(); |
| |
| VkImageMemoryBarrier img_barrier = vku::InitStructHelper(); |
| img_barrier.srcAccessMask = 0; |
| img_barrier.dstAccessMask = 0; |
| img_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL; |
| img_barrier.newLayout = VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV; |
| img_barrier.image = non_sri_image; |
| img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; |
| img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; |
| img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
| img_barrier.subresourceRange.baseArrayLayer = 0; |
| img_barrier.subresourceRange.baseMipLevel = 0; |
| img_barrier.subresourceRange.layerCount = 1; |
| img_barrier.subresourceRange.levelCount = 1; |
| |
| m_command_buffer.Begin(); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkImageMemoryBarrier-oldLayout-02088"); |
| vk::CmdPipelineBarrier(m_command_buffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, |
| 0, nullptr, 1, &img_barrier); |
| m_errorMonitor->VerifyFound(); |
| |
| // succeed converting it to GENERAL |
| img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; |
| vk::CmdPipelineBarrier(m_command_buffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, |
| 0, nullptr, 1, &img_barrier); |
| |
| // if the view is non-NULL, it must be R8_UINT, USAGE_SRI, image layout must match, layout must be valid |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBindShadingRateImageNV-imageView-02060"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBindShadingRateImageNV-imageView-02061"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBindShadingRateImageNV-imageView-02062"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBindShadingRateImageNV-imageLayout-02063"); |
| vk::CmdBindShadingRateImageNV(m_command_buffer, non_sri_view, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); |
| m_errorMonitor->VerifyFound(); |
| |
| VkShadingRatePaletteEntryNV palette_entries[100] = {}; |
| VkShadingRatePaletteNV palette = {100, palette_entries}; |
| VkShadingRatePaletteNV palettes[] = {palette, palette}; |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetViewportShadingRatePaletteNV-firstViewport-02067"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetViewportShadingRatePaletteNV-firstViewport-02068"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetViewportShadingRatePaletteNV-viewportCount-02069"); |
| vk::CmdSetViewportShadingRatePaletteNV(m_command_buffer, 20, 2, palettes); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkShadingRatePaletteNV-shadingRatePaletteEntryCount-02071"); |
| vk::CmdSetViewportShadingRatePaletteNV(m_command_buffer, 0, 1, palettes); |
| m_errorMonitor->VerifyFound(); |
| |
| VkCoarseSampleLocationNV locations[100] = { |
| {0, 0, 0}, {0, 0, 1}, {0, 1, 0}, {0, 1, 1}, {0, 1, 1}, // duplicate |
| {1000, 0, 0}, // pixelX too large |
| {0, 1000, 0}, // pixelY too large |
| {0, 0, 1000}, // sample too large |
| }; |
| |
| // Test custom sample orders, both via pipeline state and via dynamic state |
| { |
| VkCoarseSampleOrderCustomNV samp_ord_bad_shading_rate = {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_PIXEL_NV, 1, 1, |
| locations}; |
| VkCoarseSampleOrderCustomNV samp_ord_bad_sample_count = {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV, 3, 1, |
| locations}; |
| VkCoarseSampleOrderCustomNV samp_ord_bad_sample_location_count = { |
| VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV, 2, 2, locations}; |
| VkCoarseSampleOrderCustomNV samp_ord_dup_locations = {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV, 2, |
| 1 * 2 * 2, &locations[1]}; |
| VkCoarseSampleOrderCustomNV samp_ord_out_of_range = {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV, 2, |
| 1 * 2 * 2, &locations[4]}; |
| VkCoarseSampleOrderCustomNV samp_ord_too_large = {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X4_PIXELS_NV, 4, 64, |
| &locations[8]}; |
| VkCoarseSampleOrderCustomNV samp_ord_good = {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV, 2, 1 * 2 * 2, |
| &locations[0]}; |
| |
| VkPipelineViewportCoarseSampleOrderStateCreateInfoNV csosci = vku::InitStructHelper(); |
| csosci.sampleOrderType = VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV; |
| csosci.customSampleOrderCount = 1; |
| |
| struct TestCase { |
| const VkCoarseSampleOrderCustomNV* order; |
| std::vector<std::string> vuids; |
| }; |
| |
| std::vector<TestCase> test_cases = { |
| {&samp_ord_bad_shading_rate, {"VUID-VkCoarseSampleOrderCustomNV-shadingRate-02073"}}, |
| {&samp_ord_bad_sample_count, |
| {"VUID-VkCoarseSampleOrderCustomNV-sampleCount-02074", "VUID-VkCoarseSampleOrderCustomNV-sampleLocationCount-02075"}}, |
| {&samp_ord_bad_sample_location_count, {"VUID-VkCoarseSampleOrderCustomNV-sampleLocationCount-02075"}}, |
| {&samp_ord_dup_locations, {"VUID-VkCoarseSampleOrderCustomNV-pSampleLocations-02077"}}, |
| {&samp_ord_out_of_range, |
| {"VUID-VkCoarseSampleOrderCustomNV-pSampleLocations-02077", "VUID-VkCoarseSampleLocationNV-pixelX-02078", |
| "VUID-VkCoarseSampleLocationNV-pixelY-02079", "VUID-VkCoarseSampleLocationNV-sample-02080"}}, |
| {&samp_ord_too_large, |
| {"VUID-VkCoarseSampleOrderCustomNV-sampleLocationCount-02076", |
| "VUID-VkCoarseSampleOrderCustomNV-pSampleLocations-02077"}}, |
| {&samp_ord_good, {}}, |
| }; |
| |
| for (const auto& test_case : test_cases) { |
| const auto break_vp = [&](CreatePipelineHelper& helper) { |
| helper.vp_state_ci_.pNext = &csosci; |
| csosci.pCustomSampleOrders = test_case.order; |
| }; |
| CreatePipelineHelper::OneshotTest(*this, break_vp, kErrorBit, test_case.vuids); |
| } |
| |
| for (const auto& test_case : test_cases) { |
| for (uint32_t i = 0; i < test_case.vuids.size(); ++i) { |
| m_errorMonitor->SetDesiredError(test_case.vuids[i].c_str()); |
| } |
| vk::CmdSetCoarseSampleOrderNV(m_command_buffer, VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV, 1, test_case.order); |
| if (test_case.vuids.size()) { |
| m_errorMonitor->VerifyFound(); |
| } else { |
| } |
| } |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetCoarseSampleOrderNV-sampleOrderType-02081"); |
| vk::CmdSetCoarseSampleOrderNV(m_command_buffer, VK_COARSE_SAMPLE_ORDER_TYPE_PIXEL_MAJOR_NV, 1, &samp_ord_good); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, ShadingRateImageNVViewportCount) { |
| TEST_DESCRIPTION("Test VK_NV_shading_rate_image viewportCount."); |
| AddRequiredExtensions(VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::shadingRateImage); |
| AddRequiredFeature(vkt::Feature::multiViewport); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| // Test shading rate image creation |
| VkImageCreateInfo image_create_info = vku::InitStructHelper(); |
| image_create_info.imageType = VK_IMAGE_TYPE_2D; |
| image_create_info.format = VK_FORMAT_R8_UINT; |
| image_create_info.extent = {4, 4, 1}; |
| image_create_info.mipLevels = 1; |
| image_create_info.arrayLayers = 1; |
| image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; |
| image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV; |
| image_create_info.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; |
| vkt::Image image(*m_device, image_create_info, vkt::set_layout); |
| vkt::ImageView view = image.CreateView(); |
| |
| VkPipelineViewportShadingRateImageStateCreateInfoNV vsrisci = vku::InitStructHelper(); |
| |
| VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f}; |
| VkViewport viewports[20] = {viewport, viewport}; |
| VkRect2D scissor = {{0, 0}, {64, 64}}; |
| VkRect2D scissors[20] = {scissor, scissor}; |
| VkDynamicState dynPalette = VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV; |
| VkPipelineDynamicStateCreateInfo dyn = {VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, nullptr, 0, 1, &dynPalette}; |
| |
| const auto break_vp = [&](CreatePipelineHelper& helper) { |
| helper.vp_state_ci_.viewportCount = 1; |
| helper.vp_state_ci_.pViewports = viewports; |
| helper.vp_state_ci_.scissorCount = 1; |
| helper.vp_state_ci_.pScissors = scissors; |
| helper.vp_state_ci_.pNext = &vsrisci; |
| helper.dyn_state_ci_ = dyn; |
| |
| vsrisci.shadingRateImageEnable = VK_TRUE; |
| vsrisci.viewportCount = 2; |
| }; |
| CreatePipelineHelper::OneshotTest(*this, break_vp, kErrorBit, |
| "VUID-VkPipelineViewportShadingRateImageStateCreateInfoNV-shadingRateImageEnable-02056"); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, StageUsage) { |
| TEST_DESCRIPTION("Specify shading rate pipeline stage with attachmentFragmentShadingRate feature disabled"); |
| AddRequiredExtensions(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::synchronization2); |
| RETURN_IF_SKIP(Init()); |
| |
| const vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_TIMESTAMP, 1); |
| const vkt::Event event(*m_device); |
| const vkt::Event event2(*m_device); |
| |
| m_command_buffer.Begin(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResetEvent2-stageMask-07316"); |
| vk::CmdResetEvent2KHR(m_command_buffer, event, VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetEvent-stageMask-07318"); |
| vk::CmdSetEvent(m_command_buffer, event2, VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdWriteTimestamp-shadingRateImage-07314"); |
| vk::CmdWriteTimestamp(m_command_buffer, VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR, query_pool, 0); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, StageUsageNV) { |
| TEST_DESCRIPTION( |
| "Specify shading rate pipeline stage with shading rate features disabled and NV shading rate extension enabled"); |
| AddRequiredExtensions(VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::synchronization2); |
| RETURN_IF_SKIP(Init()); |
| |
| const vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_TIMESTAMP, 1); |
| const vkt::Event event(*m_device); |
| const vkt::Event event2(*m_device); |
| |
| m_command_buffer.Begin(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResetEvent2-stageMask-07316"); |
| vk::CmdResetEvent2KHR(m_command_buffer, event, VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetEvent-stageMask-07318"); |
| vk::CmdSetEvent(m_command_buffer, event2, VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdWriteTimestamp-shadingRateImage-07314"); |
| vk::CmdWriteTimestamp(m_command_buffer, VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR, query_pool, 0); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| TEST_F(NegativeFragmentShadingRate, ImageMaxLimitsEXT) { |
| TEST_DESCRIPTION("Tests physical device limits for VK_EXT_fragment_density_map_offset."); |
| AddRequiredExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| |
| const VkPhysicalDeviceLimits& dev_limits = m_device->Physical().limits_; |
| VkImageCreateInfo image_ci = vku::InitStructHelper(); |
| image_ci.flags = 0; |
| image_ci.imageType = VK_IMAGE_TYPE_2D; |
| image_ci.format = VK_FORMAT_R8G8_UNORM; |
| image_ci.extent = {1, 1, 1}; |
| image_ci.mipLevels = 1; |
| image_ci.arrayLayers = 1; |
| image_ci.samples = VK_SAMPLE_COUNT_1_BIT; |
| image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_ci.usage = VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT; |
| image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| |
| VkImageFormatProperties img_limits; |
| ASSERT_EQ(VK_SUCCESS, GetImageFormatProps(Gpu(), image_ci, img_limits)); |
| |
| image_ci.extent = {dev_limits.maxFramebufferWidth + 1, 64, 1}; |
| if (dev_limits.maxFramebufferWidth + 1 > img_limits.maxExtent.width) { |
| m_errorMonitor->SetDesiredError("VUID-VkImageCreateInfo-extent-02252"); |
| } |
| CreateImageTest(image_ci, "VUID-VkImageCreateInfo-fragmentDensityMapOffset-06514"); |
| |
| image_ci.extent = {64, dev_limits.maxFramebufferHeight + 1, 1}; |
| if (dev_limits.maxFramebufferHeight + 1 > img_limits.maxExtent.height) { |
| m_errorMonitor->SetDesiredError("VUID-VkImageCreateInfo-extent-02253"); |
| } |
| CreateImageTest(image_ci, "VUID-VkImageCreateInfo-fragmentDensityMapOffset-06515"); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, Framebuffer) { |
| TEST_DESCRIPTION("VUIDs related to framebuffer creation"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMap); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| VkPhysicalDeviceFragmentDensityMapPropertiesEXT fdm_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fdm_properties); |
| |
| VkFormat format = VK_FORMAT_R8G8_UNORM; |
| |
| VkRenderPassFragmentDensityMapCreateInfoEXT fragment_density_map_ci = vku::InitStructHelper(); |
| fragment_density_map_ci.fragmentDensityMapAttachment.layout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| VkAttachmentDescription attachment_description = {}; |
| attachment_description.format = format; |
| attachment_description.samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_description.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_description.initialLayout = VK_IMAGE_LAYOUT_GENERAL; |
| attachment_description.finalLayout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkSubpassDescription subpass_description = {}; |
| |
| VkRenderPassCreateInfo render_pass_ci = vku::InitStructHelper(&fragment_density_map_ci); |
| render_pass_ci.attachmentCount = 1u; |
| render_pass_ci.pAttachments = &attachment_description; |
| render_pass_ci.subpassCount = 1u; |
| render_pass_ci.pSubpasses = &subpass_description; |
| vkt::RenderPass render_pass(*m_device, render_pass_ci); |
| |
| vkt::Image image2(*m_device, 32u, 32u, format, VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT); |
| |
| VkImageViewCreateInfo image_view_ci = vku::InitStructHelper(); |
| image_view_ci.image = image2; |
| image_view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D; |
| image_view_ci.format = format; |
| image_view_ci.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; |
| vkt::ImageView view(*m_device, image_view_ci); |
| |
| VkFramebufferCreateInfo framebuffer_ci = vku::InitStructHelper(); |
| framebuffer_ci.renderPass = render_pass; |
| framebuffer_ci.attachmentCount = 1u; |
| framebuffer_ci.pAttachments = &view.handle(); |
| framebuffer_ci.width = 33u * fdm_properties.maxFragmentDensityTexelSize.width; |
| framebuffer_ci.height = 32u; |
| framebuffer_ci.layers = 1u; |
| |
| VkFramebuffer framebuffer; |
| m_errorMonitor->SetDesiredError("VUID-VkFramebufferCreateInfo-pAttachments-02555"); |
| vk::CreateFramebuffer(device(), &framebuffer_ci, nullptr, &framebuffer); |
| m_errorMonitor->VerifyFound(); |
| |
| framebuffer_ci.width = 32u; |
| framebuffer_ci.height = 33u * fdm_properties.maxFragmentDensityTexelSize.height; |
| m_errorMonitor->SetDesiredError("VUID-VkFramebufferCreateInfo-pAttachments-02556"); |
| vk::CreateFramebuffer(device(), &framebuffer_ci, nullptr, &framebuffer); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, FragmentDensityMapNonSubsampledImages) { |
| TEST_DESCRIPTION("Test creating framebuffer with non subsampled images"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMap); |
| |
| RETURN_IF_SKIP(Init()); |
| |
| VkFramebuffer fb; |
| |
| VkFormat attachment_format = VK_FORMAT_R8G8_UNORM; |
| // Just use the same values for both height and width |
| uint32_t frame_size = 512; |
| |
| // Create a render pass with a color attachment and fragment density map attachment |
| VkAttachmentDescription attach[2] = {}; |
| attach[0].format = attachment_format; |
| attach[0].samples = VK_SAMPLE_COUNT_1_BIT; |
| attach[0].initialLayout = VK_IMAGE_LAYOUT_GENERAL; |
| attach[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| attach[1].format = attachment_format; |
| attach[1].samples = VK_SAMPLE_COUNT_1_BIT; |
| attach[1].initialLayout = VK_IMAGE_LAYOUT_GENERAL; |
| attach[1].finalLayout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| attach[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| |
| VkRenderPassFragmentDensityMapCreateInfoEXT fragment_density_map_create_info = vku::InitStructHelper(); |
| fragment_density_map_create_info.fragmentDensityMapAttachment.layout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| fragment_density_map_create_info.fragmentDensityMapAttachment.attachment = 1; |
| |
| VkSubpassDescription subpass = {}; |
| |
| VkRenderPassCreateInfo rpci = vku::InitStructHelper(&fragment_density_map_create_info); |
| rpci.subpassCount = 1; |
| rpci.pSubpasses = &subpass; |
| rpci.attachmentCount = 2; |
| rpci.pAttachments = attach; |
| |
| vkt::RenderPass rp(*m_device, rpci); |
| |
| // Don't use the VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT flag at the color attachment image creation |
| vkt::Image image(*m_device, frame_size, frame_size, attachment_format, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); |
| vkt::Image image_fdm(*m_device, frame_size, frame_size, attachment_format, VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT); |
| |
| VkImageViewCreateInfo ivci = vku::InitStructHelper(); |
| ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; |
| ivci.format = attachment_format; |
| ivci.flags = 0; |
| ivci.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; |
| ivci.image = image; |
| |
| VkImageViewCreateInfo ivci_fdm = ivci; |
| ivci.image = image_fdm; |
| |
| vkt::ImageView image_view(*m_device, ivci); |
| vkt::ImageView image_view_fdm(*m_device, ivci_fdm); |
| |
| VkImageView views[2] = {image_view, image_view_fdm}; |
| |
| VkFramebufferCreateInfo fbci = vku::InitStructHelper(); |
| fbci.flags = 0; |
| fbci.width = frame_size; |
| fbci.height = frame_size; |
| fbci.layers = 1; |
| fbci.renderPass = rp; |
| fbci.attachmentCount = 2; |
| fbci.pAttachments = views; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkFramebufferCreateInfo-renderPass-02553"); |
| vk::CreateFramebuffer(device(), &fbci, NULL, &fb); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, AttachmentFragmentDensityFlags) { |
| AddRequiredExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMap); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDeviceFragmentDensityMapPropertiesEXT fdm_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fdm_properties); |
| |
| VkImageCreateInfo fdm_ici = vku::InitStructHelper(); |
| fdm_ici.imageType = VK_IMAGE_TYPE_2D; |
| fdm_ici.format = VK_FORMAT_R8G8_UNORM; |
| fdm_ici.extent = {16, 16, 1}; |
| fdm_ici.mipLevels = 1; |
| fdm_ici.arrayLayers = 1; |
| fdm_ici.samples = VK_SAMPLE_COUNT_1_BIT; |
| fdm_ici.tiling = VK_IMAGE_TILING_OPTIMAL; |
| fdm_ici.usage = VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT; |
| // VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT should not be allowed for density map |
| fdm_ici.flags = VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT; |
| |
| vkt::Image fdm_image(*m_device, fdm_ici, vkt::set_layout); |
| vkt::ImageView fdm_image_view = fdm_image.CreateView(VK_IMAGE_VIEW_TYPE_2D, 0, 1, 0, 1); |
| |
| VkImageCreateInfo base_ici = vku::InitStructHelper(); |
| base_ici.imageType = VK_IMAGE_TYPE_2D; |
| base_ici.format = VK_FORMAT_R8G8B8A8_UNORM; |
| base_ici.extent = {16, 16, 1}; |
| base_ici.mipLevels = 1; |
| base_ici.arrayLayers = 1; |
| base_ici.samples = VK_SAMPLE_COUNT_1_BIT; |
| base_ici.tiling = VK_IMAGE_TILING_OPTIMAL; |
| base_ici.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| // for non fragment density map images this is required |
| base_ici.flags = VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT; |
| |
| vkt::Image image(*m_device, base_ici, vkt::set_layout); |
| vkt::ImageView image_view = image.CreateView(); |
| |
| VkAttachmentReference fdm_ref; |
| fdm_ref.attachment = 0; |
| fdm_ref.layout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkAttachmentReference color_ref; |
| color_ref.attachment = 1; |
| color_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| |
| VkSubpassDescription subpass = {}; |
| subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
| subpass.inputAttachmentCount = 0; |
| subpass.pInputAttachments = nullptr; |
| subpass.colorAttachmentCount = 1; |
| subpass.pColorAttachments = &color_ref; |
| |
| VkRenderPassFragmentDensityMapCreateInfoEXT rpfdmi = vku::InitStructHelper(); |
| rpfdmi.fragmentDensityMapAttachment = fdm_ref; |
| |
| VkAttachmentDescription fdm_attach = {}; |
| fdm_attach.format = VK_FORMAT_R8G8_UNORM; |
| fdm_attach.samples = VK_SAMPLE_COUNT_1_BIT; |
| fdm_attach.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| fdm_attach.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| fdm_attach.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| fdm_attach.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| fdm_attach.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| fdm_attach.finalLayout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkAttachmentDescription color_attach = {}; |
| color_attach.format = VK_FORMAT_R8G8B8A8_UNORM; |
| color_attach.samples = VK_SAMPLE_COUNT_1_BIT; |
| color_attach.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| color_attach.storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
| color_attach.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| color_attach.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| color_attach.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| color_attach.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| |
| VkAttachmentDescription attach[2] = {fdm_attach, color_attach}; |
| |
| VkRenderPassCreateInfo rpci = vku::InitStructHelper(&rpfdmi); |
| rpci.attachmentCount = 2; |
| rpci.pAttachments = attach; |
| rpci.subpassCount = 1; |
| rpci.pSubpasses = &subpass; |
| vkt::RenderPass render_pass(*m_device, rpci); |
| |
| VkImageView attachments[2] = {fdm_image_view, image_view}; |
| |
| VkFramebufferCreateInfo fb_info = vku::InitStructHelper(); |
| fb_info.flags = 0; |
| fb_info.renderPass = render_pass; |
| fb_info.attachmentCount = 2; |
| fb_info.pAttachments = attachments; |
| fb_info.width = 1; |
| fb_info.height = 1; |
| fb_info.layers = 1; |
| |
| VkFramebuffer framebuffer; |
| m_errorMonitor->SetDesiredError("VUID-VkFramebufferCreateInfo-pAttachments-02552"); |
| vk::CreateFramebuffer(device(), &fb_info, nullptr, &framebuffer); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, ImagelessAttachmentFragmentDensity) { |
| AddRequiredExtensions(VK_KHR_IMAGELESS_FRAMEBUFFER_EXTENSION_NAME); |
| AddRequiredExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::imagelessFramebuffer); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMap); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDeviceFragmentDensityMapPropertiesEXT fdm_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fdm_properties); |
| const auto& maxFragmentDensityTexelSize = fdm_properties.maxFragmentDensityTexelSize; |
| |
| VkFormat image_format = VK_FORMAT_R8G8_UNORM; |
| |
| VkAttachmentReference ref; |
| ref.attachment = 0; |
| ref.layout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkRenderPassFragmentDensityMapCreateInfoEXT rpfdmi = vku::InitStructHelper(); |
| rpfdmi.fragmentDensityMapAttachment = ref; |
| |
| VkAttachmentDescription attach = {}; |
| attach.format = VK_FORMAT_R8G8_UNORM; |
| attach.samples = VK_SAMPLE_COUNT_1_BIT; |
| attach.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attach.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attach.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attach.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attach.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attach.finalLayout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkSubpassDescription subpass = {}; |
| subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
| |
| VkRenderPassCreateInfo rpci = vku::InitStructHelper(&rpfdmi); |
| rpci.attachmentCount = 1; |
| rpci.pAttachments = &attach; |
| rpci.subpassCount = 1; |
| rpci.pSubpasses = &subpass; |
| vkt::RenderPass render_pass(*m_device, rpci); |
| |
| VkFramebufferAttachmentImageInfo fb_fdm = vku::InitStructHelper(); |
| fb_fdm.usage = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT; |
| // FDM width and height must be greater than framebuffer.{width, height} / maxFragmentDensityTexelSize.{width, height} |
| fb_fdm.width = 1; |
| fb_fdm.height = 1; |
| fb_fdm.layerCount = 1; |
| fb_fdm.viewFormatCount = 1; |
| fb_fdm.pViewFormats = &image_format; |
| |
| VkFramebufferAttachmentsCreateInfo fb_aci_fdm = vku::InitStructHelper(); |
| fb_aci_fdm.attachmentImageInfoCount = 1; |
| fb_aci_fdm.pAttachmentImageInfos = &fb_fdm; |
| |
| VkFramebufferCreateInfo fb_info = vku::InitStructHelper(&fb_aci_fdm); |
| fb_info.flags = VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT; |
| fb_info.renderPass = render_pass; |
| fb_info.attachmentCount = 1; |
| fb_info.pAttachments = nullptr; |
| fb_info.width = 64; |
| fb_info.height = 64; |
| fb_info.layers = 1; |
| |
| VkFramebuffer framebuffer; |
| { |
| // fb.width / maxFragmentDensityTexelSize.width > attachment.width |
| fb_fdm.width = 1; |
| fb_fdm.height = 2048; |
| |
| fb_info.width = maxFragmentDensityTexelSize.width * 5; |
| fb_info.height = 2; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkFramebufferCreateInfo-flags-03196"); |
| vk::CreateFramebuffer(device(), &fb_info, nullptr, &framebuffer); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| { |
| // fb.height / maxFragmentDensityTexelSize.height > attachment.height |
| fb_fdm.width = 2048; |
| fb_fdm.height = 1; |
| |
| fb_info.width = 2; |
| fb_info.height = maxFragmentDensityTexelSize.width * 5; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkFramebufferCreateInfo-flags-03197"); |
| vk::CreateFramebuffer(device(), &fb_info, nullptr, &framebuffer); |
| m_errorMonitor->VerifyFound(); |
| } |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, FragmentDensityMapOffsetDifferentOffsetCount) { |
| AddRequiredExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMap); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMapOffset); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDeviceFragmentDensityMapOffsetPropertiesEXT fdm_offset_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fdm_offset_properties); |
| |
| VkImageCreateInfo image_create_info = BasicFragmentDensityMapImage(); |
| vkt::Image image(*m_device, image_create_info); |
| vkt::ImageView image_view = image.CreateView(); |
| |
| VkRenderingFragmentDensityMapAttachmentInfoEXT fdm_attachment_info = vku::InitStructHelper(); |
| fdm_attachment_info.imageView = image_view; |
| fdm_attachment_info.imageLayout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkRenderingInfo rendering_info = vku::InitStructHelper(&fdm_attachment_info); |
| rendering_info.flags = VK_RENDERING_SUSPENDING_BIT; |
| rendering_info.renderArea = {{0, 0}, {1u, 1u}}; |
| rendering_info.layerCount = 1u; |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRendering(rendering_info); |
| |
| int32_t width = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.width); |
| int32_t height = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.height); |
| VkOffset2D offset = {width, height}; |
| VkRenderPassFragmentDensityMapOffsetEndInfoEXT fdm_offset_end_info = vku::InitStructHelper(); |
| fdm_offset_end_info.fragmentDensityOffsetCount = 1u; |
| fdm_offset_end_info.pFragmentDensityOffsets = &offset; |
| VkRenderingEndInfoEXT rendering_end_info = vku::InitStructHelper(&fdm_offset_end_info); |
| vk::CmdEndRendering2EXT(m_command_buffer, &rendering_end_info); |
| |
| rendering_info.flags = VK_RENDERING_RESUMING_BIT; |
| m_command_buffer.BeginRendering(rendering_info); |
| fdm_offset_end_info.fragmentDensityOffsetCount = 0u; |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassFragmentDensityMapOffsetEndInfoEXT-pFragmentDensityOffsets-10730"); |
| vk::CmdEndRendering2EXT(m_command_buffer, &rendering_end_info); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, FragmentDensityMapOffsetDifferentOffsets) { |
| AddRequiredExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMap); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMapOffset); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDeviceFragmentDensityMapOffsetPropertiesEXT fdm_offset_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fdm_offset_properties); |
| |
| VkImageCreateInfo image_create_info = BasicFragmentDensityMapImage(); |
| vkt::Image image(*m_device, image_create_info); |
| vkt::ImageView image_view = image.CreateView(); |
| |
| VkRenderingFragmentDensityMapAttachmentInfoEXT fdm_attachment_info = vku::InitStructHelper(); |
| fdm_attachment_info.imageView = image_view; |
| fdm_attachment_info.imageLayout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkRenderingInfo rendering_info = vku::InitStructHelper(&fdm_attachment_info); |
| rendering_info.flags = VK_RENDERING_SUSPENDING_BIT; |
| rendering_info.renderArea = {{0, 0}, {1u, 1u}}; |
| rendering_info.layerCount = 1u; |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRendering(rendering_info); |
| |
| int32_t width = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.width); |
| int32_t height = static_cast<int32_t>(fdm_offset_properties.fragmentDensityOffsetGranularity.height); |
| VkOffset2D offset = {width, height}; |
| VkRenderPassFragmentDensityMapOffsetEndInfoEXT fdm_offset_end_info = vku::InitStructHelper(); |
| fdm_offset_end_info.fragmentDensityOffsetCount = 1u; |
| fdm_offset_end_info.pFragmentDensityOffsets = &offset; |
| VkRenderingEndInfoEXT rendering_end_info = vku::InitStructHelper(&fdm_offset_end_info); |
| vk::CmdEndRendering2EXT(m_command_buffer, &rendering_end_info); |
| |
| rendering_info.flags = VK_RENDERING_RESUMING_BIT; |
| m_command_buffer.BeginRendering(rendering_info); |
| VkOffset2D offset2 = {width * 2, height * 2}; |
| fdm_offset_end_info.pFragmentDensityOffsets = &offset2; |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassFragmentDensityMapOffsetEndInfoEXT-pFragmentDensityOffsets-10730"); |
| vk::CmdEndRendering2EXT(m_command_buffer, &rendering_end_info); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, FragmentDensityMapLayeredFeatures) { |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| AddRequiredExtensions(VK_VALVE_FRAGMENT_DENSITY_MAP_LAYERED_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| RETURN_IF_SKIP(Init()); |
| |
| VkSubpassDescription subpass = {}; |
| subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
| VkRenderPassCreateInfo render_pass_ci = vku::InitStructHelper(); |
| render_pass_ci.flags = VK_RENDER_PASS_CREATE_PER_LAYER_FRAGMENT_DENSITY_BIT_VALVE; |
| render_pass_ci.subpassCount = 1u; |
| render_pass_ci.pSubpasses = &subpass; |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassCreateInfo-fragmentDensityMapLayered-10828"); |
| vkt::RenderPass render_pass(*m_device, render_pass_ci); |
| m_errorMonitor->VerifyFound(); |
| |
| VkRenderingInfo rendering_info = vku::InitStructHelper(); |
| rendering_info.flags = VK_RENDERING_PER_LAYER_FRAGMENT_DENSITY_BIT_VALVE; |
| rendering_info.renderArea = {{0, 0}, {32, 32}}; |
| rendering_info.layerCount = 1; |
| rendering_info.colorAttachmentCount = 0; |
| |
| m_command_buffer.Begin(); |
| m_errorMonitor->SetDesiredError("VUID-VkRenderingInfo-fragmentDensityMapLayered-10827"); |
| m_command_buffer.BeginRendering(rendering_info); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, MaxFragmentDensityMapLayers) { |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| AddRequiredExtensions(VK_VALVE_FRAGMENT_DENSITY_MAP_LAYERED_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMapLayered); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| VkPhysicalDeviceFragmentDensityMapLayeredPropertiesVALVE fdm_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fdm_properties); |
| |
| { |
| const VkFormat format = VK_FORMAT_R8G8B8A8_UNORM; |
| RenderPassSingleSubpass rp(*this); |
| rp.AddAttachmentDescription(format, VK_IMAGE_LAYOUT_UNDEFINED); |
| rp.AddColorAttachment(0, VK_IMAGE_LAYOUT_GENERAL); |
| rp.CreateRenderPass(nullptr, VK_RENDER_PASS_CREATE_PER_LAYER_FRAGMENT_DENSITY_BIT_VALVE); |
| |
| auto image_ci = vkt::Image::ImageCreateInfo2D(32, 32, 1, fdm_properties.maxFragmentDensityMapLayers + 1, |
| VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); |
| vkt::Image image(*m_device, image_ci); |
| vkt::ImageView image_view = image.CreateView(VK_IMAGE_VIEW_TYPE_2D_ARRAY, 0, 1, 0, VK_REMAINING_ARRAY_LAYERS); |
| |
| VkFramebufferCreateInfo fb_info = vku::InitStructHelper(); |
| fb_info.renderPass = rp; |
| fb_info.attachmentCount = 1; |
| fb_info.pAttachments = &image_view.handle(); |
| fb_info.width = 32; |
| fb_info.height = 32; |
| fb_info.layers = fdm_properties.maxFragmentDensityMapLayers + 1; |
| m_errorMonitor->SetDesiredError("VUID-VkFramebufferCreateInfo-renderPass-10830"); |
| vkt::Framebuffer fb(*m_device, fb_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| { |
| VkRenderingInfo rendering_info = vku::InitStructHelper(); |
| rendering_info.flags = VK_RENDERING_PER_LAYER_FRAGMENT_DENSITY_BIT_VALVE; |
| rendering_info.renderArea = {{0, 0}, {32, 32}}; |
| rendering_info.layerCount = fdm_properties.maxFragmentDensityMapLayers + 1; |
| rendering_info.colorAttachmentCount = 0; |
| |
| m_command_buffer.Begin(); |
| m_errorMonitor->SetDesiredError("VUID-VkRenderingInfo-flags-10826"); |
| m_command_buffer.BeginRendering(rendering_info); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| { |
| VkPipelineFragmentDensityMapLayeredCreateInfoVALVE fdm_layered_ci = vku::InitStructHelper(); |
| fdm_layered_ci.maxFragmentDensityMapLayers = fdm_properties.maxFragmentDensityMapLayers + 1; |
| CreatePipelineHelper pipe(*this, &fdm_layered_ci); |
| m_errorMonitor->SetDesiredError( |
| "VUID-VkPipelineFragmentDensityMapLayeredCreateInfoVALVE-maxFragmentDensityMapLayers-10825"); |
| pipe.CreateGraphicsPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, MaxFragmentDensityMapLayersDraw) { |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| AddRequiredExtensions(VK_VALVE_FRAGMENT_DENSITY_MAP_LAYERED_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMapLayered); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDeviceFragmentDensityMapLayeredPropertiesVALVE fdm_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fdm_properties); |
| if (fdm_properties.maxFragmentDensityMapLayers <= 2) { |
| GTEST_SKIP() << "Need maxFragmentDensityMapLayers above 2"; |
| } |
| |
| VkPipelineCreateFlags2CreateInfo pipe_flags2 = vku::InitStructHelper(); |
| pipe_flags2.flags = VK_PIPELINE_CREATE_2_PER_LAYER_FRAGMENT_DENSITY_BIT_VALVE; |
| |
| VkFormat color_format = VK_FORMAT_B8G8R8A8_UNORM; |
| VkPipelineRenderingCreateInfo pipeline_rendering_info = vku::InitStructHelper(&pipe_flags2); |
| pipeline_rendering_info.colorAttachmentCount = 1; |
| pipeline_rendering_info.pColorAttachmentFormats = &color_format; |
| |
| VkPipelineFragmentDensityMapLayeredCreateInfoVALVE fdm_layered_ci = vku::InitStructHelper(&pipeline_rendering_info); |
| fdm_layered_ci.maxFragmentDensityMapLayers = 1; |
| CreatePipelineHelper pipe(*this, &fdm_layered_ci); |
| pipe.gp_ci_.renderPass = VK_NULL_HANDLE; |
| pipe.CreateGraphicsPipeline(); |
| |
| auto image_ci = vkt::Image::ImageCreateInfo2D(32, 32, 1, 2, color_format, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); |
| vkt::Image color_image(*m_device, image_ci, vkt::set_layout); |
| vkt::ImageView color_image_view = color_image.CreateView(VK_IMAGE_VIEW_TYPE_2D_ARRAY, 0, 1, 0, VK_REMAINING_ARRAY_LAYERS); |
| |
| VkRenderingAttachmentInfo color_attachment = vku::InitStructHelper(); |
| color_attachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| color_attachment.imageView = color_image_view; |
| |
| VkRenderingInfo rendering_info = vku::InitStructHelper(); |
| rendering_info.flags = VK_RENDERING_PER_LAYER_FRAGMENT_DENSITY_BIT_VALVE; |
| rendering_info.renderArea = {{0, 0}, {32, 32}}; |
| rendering_info.layerCount = 2; |
| rendering_info.colorAttachmentCount = 1; |
| rendering_info.pColorAttachments = &color_attachment; |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRendering(rendering_info); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-layers-10831"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, PrimitiveFragmentShadingRateMeshShader) { |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| AddRequiredExtensions(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::pipelineFragmentShadingRate); |
| AddRequiredExtensions(VK_EXT_MESH_SHADER_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::meshShader); |
| RETURN_IF_SKIP(Init()); |
| |
| const char* mesh_source = R"glsl( |
| #version 450 |
| #extension GL_EXT_mesh_shader : require |
| #extension GL_EXT_fragment_shading_rate : enable |
| layout(triangles, max_vertices = 3, max_primitives = 1) out; |
| void main() { |
| SetMeshOutputsEXT(3, 1); |
| gl_MeshPrimitivesEXT[0].gl_PrimitiveShadingRateEXT = 0; |
| } |
| )glsl"; |
| |
| m_errorMonitor->SetDesiredError("VUID-PrimitiveShadingRateKHR-PrimitiveShadingRateKHR-12275"); |
| VkShaderObj ms(*m_device, mesh_source, VK_SHADER_STAGE_MESH_BIT_EXT, SPV_ENV_VULKAN_1_2); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeFragmentShadingRate, AttachmentFragmentShadingRate) { |
| AddRequiredExtensions(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| |
| if (!FormatFeaturesAreSupported(Gpu(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TILING_OPTIMAL, |
| VK_FORMAT_FEATURE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR)) { |
| GTEST_SKIP() << "format doesn't support FRAGMENT_SHADING_RATE_ATTACHMENT_BIT"; |
| } |
| |
| vkt::Image image(*m_device, 128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR); |
| m_errorMonitor->SetDesiredError("VUID-VkImageViewCreateInfo-attachmentFragmentShadingRate-12386"); |
| image.CreateView(); |
| m_errorMonitor->VerifyFound(); |
| } |