Merge vk-gl-cts/vulkan-cts-1.3.4 into vk-gl-cts/main
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / fragment_shading_rate / vktFragmentShadingRateBasic.cpp
index 702ebd0..4e21315 100644 (file)
@@ -42,6 +42,7 @@
 #include "vkTypeUtil.hpp"
 #include "vkObjUtil.hpp"
 #include "vkImageUtil.hpp"
+#include "vkStrUtil.hpp"
 
 #include "vktTestGroupUtil.hpp"
 #include "vktTestCase.hpp"
@@ -58,6 +59,9 @@
 #include <set>
 #include <string>
 #include <sstream>
+#include <vector>
+#include <algorithm>
+#include <iterator>
 
 namespace vkt
 {
@@ -75,6 +79,7 @@ enum class AttachmentUsage
        NO_ATTACHMENT = 0,
        NO_ATTACHMENT_PTR,
        WITH_ATTACHMENT,
+       WITH_ATTACHMENT_WITHOUT_IMAGEVIEW, // No imageview at VkRenderingFragmentShadingRateAttachmentInfoKHR.
 };
 
 struct CaseDef
@@ -87,6 +92,7 @@ struct CaseDef
        AttachmentUsage attachmentUsage;
        bool shaderWritesRate;
        bool geometryShader;
+       bool meshShader;
        bool useDynamicState;
        bool useApiSampleMask;
        bool useSampleMaskIn;
@@ -106,11 +112,18 @@ struct CaseDef
        bool sampleShadingEnable;
        bool sampleShadingInput;
        bool sampleMaskTest;
+       bool earlyAndLateTest;
+       bool garbageAttachment;
 
        bool useAttachment () const
        {
                return (attachmentUsage == AttachmentUsage::WITH_ATTACHMENT);
        }
+
+       bool useAttachmentWithoutImageView () const
+       {
+               return (attachmentUsage == AttachmentUsage::WITH_ATTACHMENT_WITHOUT_IMAGEVIEW);
+       }
 };
 
 class FSRTestInstance : public TestInstance
@@ -172,9 +185,11 @@ protected:
                                                                                                                 PipelineRenderingCreateInfoWrapper                                     dynamicRenderingState,
                                                                                                                 const VkShaderModule                                                           vertShader,
                                                                                                                 const VkShaderModule                                                           geomShader,
+                                                                                                                const VkShaderModule                                                           meshShader,
                                                                                                                 const VkShaderModule                                                           fragShader,
-                                                                                                                VkDescriptorSet                                                                        descriptorSet,
-                                                                                                                VkBuffer                                                                                       vertexBuffer);
+                                                                                                                const std::vector<VkDescriptorSet>&                            descriptorSet,
+                                                                                                                VkBuffer                                                                                       vertexBuffer,
+                                                                                                                const uint32_t                                                                         pushConstantSize);
 #ifndef CTS_USES_VULKANSC
        void                            beginSecondaryCmdBuffer                 (VkCommandBuffer                                                                        cmdBuffer,
                                                                                                                 VkFormat                                                                                       cbFormat,
@@ -286,6 +301,12 @@ static VkImageUsageFlags cbUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
                                                                   VK_IMAGE_USAGE_TRANSFER_DST_BIT |
                                                                   VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
 
+static VkImageUsageFlags dsUsage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
+                                                                  VK_IMAGE_USAGE_SAMPLED_BIT |
+                                                                  VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
+                                                                  VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+
+
 void FSRTestCase::checkSupport(Context& context) const
 {
        context.requireDeviceFunctionality("VK_KHR_fragment_shading_rate");
@@ -308,16 +329,18 @@ void FSRTestCase::checkSupport(Context& context) const
                m_data.combinerOp[1] != VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR)
                TCU_THROW(NotSupportedError, "attachmentFragmentShadingRate not supported");
 
-       const auto&     vki                             = context.getInstanceInterface();
-       const auto      physicalDevice  = context.getPhysicalDevice();
+       const auto&             vki                     = context.getInstanceInterface();
+       const auto              physDev         = context.getPhysicalDevice();
 
-       VkImageFormatProperties imageProperties;
-       VkResult result = vki.getPhysicalDeviceImageFormatProperties(physicalDevice, VK_FORMAT_R32G32B32A32_UINT, VK_IMAGE_TYPE_2D,
-                                                                                                                                VK_IMAGE_TILING_OPTIMAL, cbUsage, 0, &imageProperties);
+       VkImageFormatProperties imageProperties;
+       VkResult                                result                  = vki.getPhysicalDeviceImageFormatProperties(physDev, VK_FORMAT_R32G32B32A32_UINT, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, cbUsage, 0, &imageProperties);
 
        if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
                TCU_THROW(NotSupportedError, "VK_FORMAT_R32G32B32A32_UINT not supported");
 
+       if (m_data.geometryShader)
+               context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
+
        if (!(imageProperties.sampleCounts & m_data.samples))
                TCU_THROW(NotSupportedError, "color buffer sample count not supported");
 
@@ -373,7 +396,28 @@ void FSRTestCase::checkSupport(Context& context) const
        if (m_data.sampleMaskTest && !context.getFragmentShadingRateProperties().fragmentShadingRateWithSampleMask)
                TCU_THROW(NotSupportedError, "fragmentShadingRateWithSampleMask not supported");
 
-       checkPipelineLibraryRequirements(vki, physicalDevice, m_data.groupParams->pipelineConstructionType);
+#ifndef CTS_USES_VULKANSC
+       if (m_data.meshShader)
+       {
+               context.requireDeviceFunctionality("VK_EXT_mesh_shader");
+               const auto& meshFeatures = context.getMeshShaderFeaturesEXT();
+
+               if (m_data.shaderWritesRate && !meshFeatures.primitiveFragmentShadingRateMeshShader)
+                       TCU_THROW(NotSupportedError, "primitiveFragmentShadingRateMeshShader not supported");
+
+               if (m_data.multiView && !meshFeatures.multiviewMeshShader)
+                       TCU_THROW(NotSupportedError, "multiviewMeshShader not supported");
+       }
+
+       checkPipelineLibraryRequirements(vki, physDev, m_data.groupParams->pipelineConstructionType);
+
+       if (m_data.earlyAndLateTest)
+       {
+               context.requireDeviceFunctionality("VK_AMD_shader_early_and_late_fragment_tests");
+               if (context.getShaderEarlyAndLateFragmentTestsFeaturesAMD().shaderEarlyAndLateFragmentTests == VK_FALSE)
+                       TCU_THROW(NotSupportedError, "shaderEarlyAndLateFragmentTests is not supported");
+       }
+#endif
 }
 
 // Error codes writted by the fragment shader
@@ -388,116 +432,181 @@ enum
 
 void FSRTestCase::initPrograms (SourceCollections& programCollection) const
 {
-       std::stringstream vss;
+       if (!m_data.meshShader)
+       {
+               std::stringstream vss;
 
-       vss <<
-               "#version 450 core\n"
-               "#extension GL_EXT_fragment_shading_rate : enable\n"
-               "#extension GL_ARB_shader_viewport_layer_array : enable\n"
-               "layout(push_constant) uniform PC {\n"
-               "       int shadingRate;\n"
-               "} pc;\n"
-               "layout(location = 0) in vec2 pos;\n"
-               "layout(location = 0) out int instanceIndex;\n"
-               "layout(location = 1) out int readbackok;\n"
-               "layout(location = 2) out float zero;\n"
-               "out gl_PerVertex\n"
-               "{\n"
-               "   vec4 gl_Position;\n"
-               "};\n"
-               "void main()\n"
-               "{\n"
-               "  gl_Position = vec4(pos, 0, 1);\n"
-               "  instanceIndex = gl_InstanceIndex;\n"
-               "  readbackok = 1;\n"
-               "  zero = 0;\n";
+               vss <<
+                       "#version 450 core\n"
+                       "#extension GL_EXT_fragment_shading_rate : enable\n"
+                       "#extension GL_ARB_shader_viewport_layer_array : enable\n"
+                       "layout(push_constant) uniform PC {\n"
+                       "       int shadingRate;\n"
+                       "} pc;\n"
+                       "layout(location = 0) in vec2 pos;\n"
+                       "layout(location = 0) out int instanceIndex;\n"
+                       "layout(location = 1) out int readbackok;\n"
+                       "layout(location = 2) out float zero;\n"
+                       "out gl_PerVertex\n"
+                       "{\n"
+                       "   vec4 gl_Position;\n"
+                       "};\n"
+                       "void main()\n"
+                       "{\n"
+                       "  gl_Position = vec4(pos, 0, 1);\n"
+                       "  instanceIndex = gl_InstanceIndex;\n"
+                       "  readbackok = 1;\n"
+                       "  zero = 0;\n";
 
-       if (m_data.shaderWritesRate)
-       {
-               vss << "  gl_PrimitiveShadingRateEXT = pc.shadingRate;\n";
+               if (m_data.shaderWritesRate)
+               {
+                       vss << "  gl_PrimitiveShadingRateEXT = pc.shadingRate;\n";
 
-               // Verify that we can read from the output variable
-               vss << "  if (gl_PrimitiveShadingRateEXT != pc.shadingRate) readbackok = 0;\n";
+                       // Verify that we can read from the output variable
+                       vss << "  if (gl_PrimitiveShadingRateEXT != pc.shadingRate) readbackok = 0;\n";
 
-               if (!m_data.geometryShader)
+                       if (!m_data.geometryShader)
+                       {
+                               if (m_data.multiViewport)
+                                       vss << "  gl_ViewportIndex = instanceIndex & 1;\n";
+                               if (m_data.colorLayered)
+                                       vss << "  gl_Layer = ((instanceIndex & 2) >> 1);\n";
+                       }
+               }
+
+               vss << "}\n";
+
+               programCollection.glslSources.add("vert") << glu::VertexSource(vss.str());
+
+               if (m_data.geometryShader)
                {
-                       if (m_data.multiViewport)
-                               vss << "  gl_ViewportIndex = instanceIndex & 1;\n";
-                       if (m_data.colorLayered)
-                               vss << "  gl_Layer = (instanceIndex & 2) >> 1;\n";
+                       std::string writeShadingRate = "";
+                       if (m_data.shaderWritesRate)
+                       {
+                               writeShadingRate =
+                                       "  gl_PrimitiveShadingRateEXT = pc.shadingRate;\n"
+                                       "  if (gl_PrimitiveShadingRateEXT != pc.shadingRate) readbackok = 0;\n";
+
+                               if (m_data.multiViewport)
+                                       writeShadingRate += "  gl_ViewportIndex = inInstanceIndex[0] & 1;\n";
+
+                               if (m_data.colorLayered)
+                                       writeShadingRate += "  gl_Layer = (inInstanceIndex[0] & 2) >> 1;\n";
+                       }
+
+                       std::stringstream gss;
+                       gss <<
+                               "#version 450 core\n"
+                               "#extension GL_EXT_fragment_shading_rate : enable\n"
+                               "\n"
+                               "layout(push_constant) uniform PC {\n"
+                               "       int shadingRate;\n"
+                               "} pc;\n"
+                               "\n"
+                               "in gl_PerVertex\n"
+                               "{\n"
+                               "   vec4 gl_Position;\n"
+                               "} gl_in[3];\n"
+                               "\n"
+                               "layout(location = 0) in int inInstanceIndex[];\n"
+                               "layout(location = 0) out int outInstanceIndex;\n"
+                               "layout(location = 1) out int readbackok;\n"
+                               "layout(location = 2) out float zero;\n"
+                               "layout(triangles) in;\n"
+                               "layout(triangle_strip, max_vertices=3) out;\n"
+                               "\n"
+                               "out gl_PerVertex {\n"
+                               "   vec4 gl_Position;\n"
+                               "};\n"
+                               "\n"
+                               "void main(void)\n"
+                               "{\n"
+                               "   gl_Position = gl_in[0].gl_Position;\n"
+                               "   outInstanceIndex = inInstanceIndex[0];\n"
+                               "   readbackok  = 1;\n"
+                               "   zero = 0;\n"
+                               << writeShadingRate <<
+                               "   EmitVertex();"
+                               "\n"
+                               "   gl_Position = gl_in[1].gl_Position;\n"
+                               "   outInstanceIndex = inInstanceIndex[1];\n"
+                               "   readbackok = 1;\n"
+                               "   zero = 0;\n"
+                               << writeShadingRate <<
+                               "   EmitVertex();"
+                               "\n"
+                               "   gl_Position = gl_in[2].gl_Position;\n"
+                               "   outInstanceIndex = inInstanceIndex[2];\n"
+                               "   readbackok = 1;\n"
+                               "   zero = 0;\n"
+                               << writeShadingRate <<
+                               "   EmitVertex();"
+                               "}\n";
+
+                       programCollection.glslSources.add("geom") << glu::GeometrySource(gss.str());
                }
        }
+       else
+       {
+               std::stringstream mss;
 
-       vss << "}\n";
+               mss <<
+                       "#version 450 core\n"
+                       "#extension GL_EXT_mesh_shader : enable\n"
+                       "layout(local_size_x=3) in;\n"
+                       "layout(triangles) out;\n"
+                       "layout(max_vertices=3, max_primitives=1) out;\n"
+                       "layout(push_constant, std430) uniform PC {\n"
+                       "  int shadingRate;\n"
+                       "  uint instanceIndex;\n"
+                       "} pc;\n"
+                       "layout(set=1, binding=0, std430) readonly buffer PosBuffer {\n"
+                       "  vec2 vertexPositions[];\n"
+                       "} pb;\n"
+                       "layout(location = 0) flat out int instanceIndex[];\n"
+                       "layout(location = 1) flat out int readbackok[];\n"
+                       "layout(location = 2) out float zero[];\n";
 
-       programCollection.glslSources.add("vert") << glu::VertexSource(vss.str());
+               if (m_data.shaderWritesRate)
+               {
+                       mss <<
+                               "perprimitiveEXT out gl_MeshPerPrimitiveEXT {\n"
+                               << (m_data.colorLayered ? "  int gl_Layer;\n" : "")
+                               << (m_data.multiViewport ? "  int gl_ViewportIndex;\n" : "") <<
+                               "  int gl_PrimitiveShadingRateEXT;\n"
+                               "} gl_MeshPrimitivesEXT[];\n";
+               }
+
+               mss <<
+                       "void main()\n"
+                       "{\n"
+                       "  SetMeshOutputsEXT(3u, 1u);\n"
+                       "  const uint vertexIdx = (pc.instanceIndex * 3u + gl_LocalInvocationIndex);\n"
+                       "  gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position = vec4(pb.vertexPositions[vertexIdx], 0, 1);\n"
+                       "  if (gl_LocalInvocationIndex == 0) {\n"
+                       "    gl_PrimitiveTriangleIndicesEXT[0] = uvec3(0, 1, 2);\n"
+                       "  }\n"
+                       "  instanceIndex[gl_LocalInvocationIndex] = int(pc.instanceIndex);\n"
+                       "  readbackok[gl_LocalInvocationIndex] = 1;\n"
+                       "  zero[gl_LocalInvocationIndex] = 0;\n";
 
-       if (m_data.geometryShader)
-       {
-               std::string writeShadingRate = "";
                if (m_data.shaderWritesRate)
                {
-                       writeShadingRate =
-                               "  gl_PrimitiveShadingRateEXT = pc.shadingRate;\n"
-                               "  if (gl_PrimitiveShadingRateEXT != pc.shadingRate) readbackok = 0;\n";
+                       mss << "  gl_MeshPrimitivesEXT[0].gl_PrimitiveShadingRateEXT = pc.shadingRate;\n";
 
-                       if (m_data.multiViewport)
-                               writeShadingRate += "  gl_ViewportIndex = inInstanceIndex[0] & 1;\n";
+                       // gl_MeshPerPrimitiveEXT is write-only in mesh shaders, so we cannot verify the readback operation.
+                       //mss << "  if (gl_PrimitiveShadingRateEXT != pc.shadingRate) readbackok = 0;\n";
 
+                       if (m_data.multiViewport)
+                               mss << "  gl_MeshPrimitivesEXT[0].gl_ViewportIndex = int(pc.instanceIndex & 1);\n";
                        if (m_data.colorLayered)
-                               writeShadingRate += "  gl_Layer = (inInstanceIndex[0] & 2) >> 1;\n";
+                               mss << "  gl_MeshPrimitivesEXT[0].gl_Layer = int((pc.instanceIndex & 2) >> 1);\n";
                }
 
-               std::stringstream gss;
-               gss <<
-                       "#version 450 core\n"
-                       "#extension GL_EXT_fragment_shading_rate : enable\n"
-                       "\n"
-                       "layout(push_constant) uniform PC {\n"
-                       "       int shadingRate;\n"
-                       "} pc;\n"
-                       "\n"
-                       "in gl_PerVertex\n"
-                       "{\n"
-                       "   vec4 gl_Position;\n"
-                       "} gl_in[3];\n"
-                       "\n"
-                       "layout(location = 0) in int inInstanceIndex[];\n"
-                       "layout(location = 0) out int outInstanceIndex;\n"
-                       "layout(location = 1) out int readbackok;\n"
-                       "layout(location = 2) out float zero;\n"
-                       "layout(triangles) in;\n"
-                       "layout(triangle_strip, max_vertices=3) out;\n"
-                       "\n"
-                       "out gl_PerVertex {\n"
-                       "   vec4 gl_Position;\n"
-                       "};\n"
-                       "\n"
-                       "void main(void)\n"
-                       "{\n"
-                       "   gl_Position = gl_in[0].gl_Position;\n"
-                       "   outInstanceIndex = inInstanceIndex[0];\n"
-                       "   readbackok  = 1;\n"
-                       "   zero = 0;\n"
-                       << writeShadingRate <<
-                       "   EmitVertex();"
-                       "\n"
-                       "   gl_Position = gl_in[1].gl_Position;\n"
-                       "   outInstanceIndex = inInstanceIndex[1];\n"
-                       "   readbackok = 1;\n"
-                       "   zero = 0;\n"
-                       << writeShadingRate <<
-                       "   EmitVertex();"
-                       "\n"
-                       "   gl_Position = gl_in[2].gl_Position;\n"
-                       "   outInstanceIndex = inInstanceIndex[2];\n"
-                       "   readbackok = 1;\n"
-                       "   zero = 0;\n"
-                       << writeShadingRate <<
-                       "   EmitVertex();"
-                       "}\n";
-
-               programCollection.glslSources.add("geom") << glu::GeometrySource(gss.str());
+               mss << "}\n";
+
+               const ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
+               programCollection.glslSources.add("mesh") << glu::MeshSource(mss.str()) << buildOptions;
        }
 
        std::stringstream fss;
@@ -506,14 +615,27 @@ void FSRTestCase::initPrograms (SourceCollections& programCollection) const
                "#version 450 core\n"
                "#extension GL_EXT_fragment_shading_rate : enable\n"
                "#extension GL_ARB_shader_stencil_export : enable\n"
-               "#extension GL_ARB_fragment_shader_interlock : enable\n"
-               "layout(location = 0) out uvec4 col0;\n"
+               "#extension GL_ARB_fragment_shader_interlock : enable\n";
+
+       if (m_data.earlyAndLateTest)
+               fss << "#extension GL_AMD_shader_early_and_late_fragment_tests : enable\n";
+
+       fss << "layout(location = 0) out uvec4 col0;\n"
                "layout(set = 0, binding = 0) buffer Block { uint counter; } buf;\n"
                "layout(set = 0, binding = 3) uniform usampler2D tex;\n"
                "layout(location = 0) flat in int instanceIndex;\n"
                "layout(location = 1) flat in int readbackok;\n"
                "layout(location = 2) " << (m_data.sampleShadingInput ? "sample " : "") << "in float zero;\n";
 
+       if (m_data.earlyAndLateTest)
+               fss << "layout(early_and_late_fragment_tests_amd) in;\n";
+
+       if (m_data.fragDepth && m_data.earlyAndLateTest)
+               fss << "layout(depth_less) out float gl_FragDepth;\n";
+
+       if (m_data.fragStencil && m_data.earlyAndLateTest)
+               fss << "layout(stencil_ref_less_front_amd) out int gl_FragStencilRefARB;\n";
+
        if (m_data.interlock)
                fss << "layout(pixel_interlock_ordered) in;\n";
 
@@ -837,9 +959,8 @@ tcu::TestStatus FSRTestInstance::iterate (void)
        const VkDevice                  device                                  = m_context.getDevice();
        tcu::TestLog&                   log                                             = m_context.getTestContext().getLog();
        Allocator&                              allocator                               = m_context.getDefaultAllocator();
-       VkFlags                                 allShaderStages                 = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT;
-       VkFlags                                 allPipelineStages               = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
-                                                                                                         VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
+       VkFlags                                 allShaderStages                 = VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT;
+       VkFlags                                 allPipelineStages               = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
                                                                                                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
                                                                                                          VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
                                                                                                          VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
@@ -847,11 +968,27 @@ tcu::TestStatus FSRTestInstance::iterate (void)
                                                                                                          VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR;
        const VkFormat                  cbFormat                                = VK_FORMAT_R32G32B32A32_UINT;
        VkFormat                                dsFormat                                = VK_FORMAT_UNDEFINED;
+       const auto                              vertBufferUsage                 = (m_data.meshShader ? VK_BUFFER_USAGE_STORAGE_BUFFER_BIT : VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
 
-       if (m_data.geometryShader)
+       if (m_data.meshShader)
        {
-               allShaderStages |= VK_SHADER_STAGE_GEOMETRY_BIT;
-               allPipelineStages |= VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
+#ifndef CTS_USES_VULKANSC
+               allShaderStages |= VK_SHADER_STAGE_MESH_BIT_EXT;
+               allPipelineStages |= VK_PIPELINE_STAGE_MESH_SHADER_BIT_EXT;
+#else
+               DE_ASSERT(false);
+#endif // CTS_USES_VULKANSC
+       }
+       else
+       {
+               allShaderStages |= VK_SHADER_STAGE_VERTEX_BIT;
+               allPipelineStages |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT;
+
+               if (m_data.geometryShader)
+               {
+                       allShaderStages |= VK_SHADER_STAGE_GEOMETRY_BIT;
+                       allPipelineStages |= VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
+               }
        }
 
        if (m_data.useDepthStencil)
@@ -911,7 +1048,7 @@ tcu::TestStatus FSRTestInstance::iterate (void)
 
        de::MovePtr<BufferWithMemory> vertexBuffer;
        vertexBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
-               vk, device, allocator, makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible | MemoryRequirement::Coherent));
+               vk, device, allocator, makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | vertBufferUsage), MemoryRequirement::HostVisible | MemoryRequirement::Coherent));
 
        float *vbuf = (float *)vertexBuffer->getAllocation().getHostPtr();
        for (deInt32 i = 0; i < (deInt32)(vertexBufferSize / sizeof(float)); ++i)
@@ -1004,10 +1141,7 @@ tcu::TestStatus FSRTestInstance::iterate (void)
 
        de::MovePtr<ImageWithMemory> dsImage;
        Move<VkImageView> dsImageView, dImageView, sImageView;
-       VkImageUsageFlags dsUsage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
-                                                               VK_IMAGE_USAGE_SAMPLED_BIT |
-                                                               VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
-                                                               VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+
        if (m_data.useDepthStencil)
        {
                const VkImageCreateInfo                 imageCreateInfo                 =
@@ -1149,8 +1283,8 @@ tcu::TestStatus FSRTestInstance::iterate (void)
 
        Move<VkSampler>                 sampler = createSampler(vk, device, &samplerInfo);
 
-       Move<vk::VkDescriptorSetLayout> descriptorSetLayout;
-       VkDescriptorSetLayoutCreateFlags layoutCreateFlags = 0;
+       std::vector<Move<vk::VkDescriptorSetLayout>> descriptorSetLayouts;
+       const VkDescriptorSetLayoutCreateFlags layoutCreateFlags = 0;
 
        const VkDescriptorSetLayoutBinding bindings[] =
        {
@@ -1218,26 +1352,62 @@ tcu::TestStatus FSRTestInstance::iterate (void)
                vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,        // sType
                DE_NULL,                                                                                                        // pNext
                layoutCreateFlags,                                                                                      // flags
-               sizeof(bindings)/sizeof(bindings[0]),                                           // bindingCount
+               static_cast<uint32_t>(de::arrayLength(bindings)),                       // bindingCount
                &bindings[0]                                                                                            // pBindings
        };
 
-       descriptorSetLayout = vk::createDescriptorSetLayout(vk, device, &setLayoutCreateInfo);
+       descriptorSetLayouts.push_back(vk::createDescriptorSetLayout(vk, device, &setLayoutCreateInfo));
 
+       // Mesh shaders use set 1 binding 0 as the vertex buffer.
+       if (m_data.meshShader)
+       {
+#ifndef CTS_USES_VULKANSC
+               const VkDescriptorSetLayoutBinding extraBinding =
+               {
+                       0u,                                                                             // binding
+                       VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,              // descriptorType
+                       1u,                                                                             // descriptorCount
+                       VK_SHADER_STAGE_MESH_BIT_EXT,                   // stageFlags
+                       DE_NULL,                                                                // pImmutableSamplers
+               };
+
+               const VkDescriptorSetLayoutCreateInfo extraSetLayoutCreateInfo =
+               {
+                       vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,        // sType
+                       DE_NULL,                                                                                                        // pNext
+                       layoutCreateFlags,                                                                                      // flags
+                       1u,                                                                                                                     // bindingCount
+                       &extraBinding,                                                                                          // pBindings
+               };
+
+               descriptorSetLayouts.push_back(vk::createDescriptorSetLayout(vk, device, &extraSetLayoutCreateInfo));
+#else
+               DE_ASSERT(false);
+#endif // CTS_USES_VULKANSC
+       }
+
+       const uint32_t                                                  numConstants                                    = (m_data.meshShader ? 2u : 1u);
+       const uint32_t                                                  pushConstantSize                                = (static_cast<uint32_t>(sizeof(deInt32)) * numConstants);
        const VkPushConstantRange                               pushConstantRange                               =
        {
-               allShaderStages,                                                                                        // VkShaderStageFlags                                   stageFlags;
-               0u,                                                                                                                     // deUint32                                                             offset;
-               sizeof(deInt32)                                                                                         // deUint32                                                             size;
+               allShaderStages,        // VkShaderStageFlags                                   stageFlags;
+               0u,                                     // deUint32                                                             offset;
+               pushConstantSize,       // deUint32                                                             size;
        };
 
+       std::vector<VkDescriptorSetLayout> descriptorSetLayoutsRaw;
+       descriptorSetLayoutsRaw.reserve(descriptorSetLayouts.size());
+
+       std::transform(begin(descriptorSetLayouts), end(descriptorSetLayouts), std::back_inserter(descriptorSetLayoutsRaw),
+               [](const Move<VkDescriptorSetLayout>& elem) { return elem.get(); });
+
        const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
        {
                VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,                          // sType
                DE_NULL,                                                                                                        // pNext
                (VkPipelineLayoutCreateFlags)0,
-               1,                                                                                                                      // setLayoutCount
-               &descriptorSetLayout.get(),                                                                     // pSetLayouts
+               static_cast<uint32_t>(descriptorSetLayoutsRaw.size()),          // setLayoutCount
+               de::dataOrNull(descriptorSetLayoutsRaw),                                        // pSetLayouts
                1u,                                                                                                                     // pushConstantRangeCount
                &pushConstantRange,                                                                                     // pPushConstantRanges
        };
@@ -1326,9 +1496,9 @@ tcu::TestStatus FSRTestInstance::iterate (void)
                        VkFormat srFormat = srFillFormats[formatIdx];
                        deUint32 srFillBpp = tcu::getPixelSize(mapVkFormat(srFormat));
 
-                       VkImageLayout srLayout = modeIdx == ATTACHMENT_MODE_LAYOUT_OPTIMAL ? VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR : VK_IMAGE_LAYOUT_GENERAL;
-                       VkImageViewType srViewType = modeIdx == ATTACHMENT_MODE_2DARRAY ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D;
-                       VkImageTiling srTiling = (modeIdx == ATTACHMENT_MODE_TILING_LINEAR) ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL;
+                       VkImageLayout   srLayout        = modeIdx == ATTACHMENT_MODE_LAYOUT_OPTIMAL ? VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR : VK_IMAGE_LAYOUT_GENERAL;
+                       VkImageViewType srViewType      = (modeIdx == ATTACHMENT_MODE_2DARRAY || numSRLayers > 1u) ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D;
+                       VkImageTiling   srTiling        = (modeIdx == ATTACHMENT_MODE_TILING_LINEAR) ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL;
 
                        VkFormatProperties srFormatProperties;
                        m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), srFormat, &srFormatProperties);
@@ -1345,16 +1515,21 @@ tcu::TestStatus FSRTestInstance::iterate (void)
                                continue;
                        }
 
-                       Move<vk::VkDescriptorPool>              descriptorPool;
-                       Move<vk::VkDescriptorSet>               descriptorSet;
-                       VkDescriptorPoolCreateFlags poolCreateFlags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
+                       Move<vk::VkDescriptorPool>                                      descriptorPool;
+                       std::vector<Move<vk::VkDescriptorSet>>          descriptorSets;
+                       VkDescriptorPoolCreateFlags                                     poolCreateFlags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
 
                        vk::DescriptorPoolBuilder poolBuilder;
                        for (deInt32 i = 0; i < (deInt32)(sizeof(bindings)/sizeof(bindings[0])); ++i)
                                poolBuilder.addType(bindings[i].descriptorType, bindings[i].descriptorCount);
+                       if (m_data.meshShader)
+                               poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
 
-                       descriptorPool = poolBuilder.build(vk, device, poolCreateFlags, 1u);
-                       descriptorSet = makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout);
+                       descriptorPool = poolBuilder.build(vk, device, poolCreateFlags, static_cast<uint32_t>(descriptorSetLayouts.size()));
+                       for (const auto& setLayout : descriptorSetLayouts)
+                               descriptorSets.push_back(makeDescriptorSet(vk, device, *descriptorPool, *setLayout));
+
+                       const auto mainDescriptorSet = descriptorSets.front().get();
 
                        de::MovePtr<ImageWithMemory> srImage;
                        Move<VkImageView> srImageView;
@@ -1422,7 +1597,7 @@ tcu::TestStatus FSRTestInstance::iterate (void)
                        {
                                VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,                                                 // sType
                                DE_NULL,                                                                                                                // pNext
-                               *descriptorSet,                                                                                                 // dstSet
+                               descriptorSets.front().get(),                                                                   // dstSet
                                (deUint32)0,                                                                                                    // dstBinding
                                0,                                                                                                                              // dstArrayElement
                                1u,                                                                                                                             // descriptorCount
@@ -1478,6 +1653,27 @@ tcu::TestStatus FSRTestInstance::iterate (void)
                                vk.updateDescriptorSets(device, 1, &w, 0, NULL);
                        }
 
+                       // Update vertex buffer descriptor.
+                       if (m_data.meshShader)
+                       {
+                               const auto                                      extraBufferInfo = makeDescriptorBufferInfo(vertexBuffer->get(), 0ull, vertexBufferSize);
+                               const VkWriteDescriptorSet      extraWrite              =
+                               {
+                                       VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,                                                 // sType
+                                       DE_NULL,                                                                                                                // pNext
+                                       descriptorSets.back().get(),                                                                    // dstSet
+                                       (deUint32)0,                                                                                                    // dstBinding
+                                       0,                                                                                                                              // dstArrayElement
+                                       1u,                                                                                                                             // descriptorCount
+                                       VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,                                                              // descriptorType
+                                       nullptr,                                                                                                                // pImageInfo
+                                       &extraBufferInfo,                                                                                               // pBufferInfo
+                                       DE_NULL,                                                                                                                // pTexelBufferView
+                               };
+
+                               vk.updateDescriptorSets(device, 1u, &extraWrite, 0u, nullptr);
+                       }
+
                        Move<VkRenderPass> renderPass;
                        Move<VkFramebuffer> framebuffer;
 
@@ -1590,7 +1786,7 @@ tcu::TestStatus FSRTestInstance::iterate (void)
                                                VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,     // VkStructureType sType;
                                                DE_NULL,                                                                        // const void* pNext;
                                                (VkAttachmentDescriptionFlags)0u,                       // VkAttachmentDescriptionFlags         flags;
-                                               dsFormat,                                       // VkFormat                                                     format;
+                                               dsFormat,                                                                       // VkFormat                                                     format;
                                                m_data.samples,                                                         // VkSampleCountFlagBits                        samples;
                                                VK_ATTACHMENT_LOAD_OP_LOAD,                                     // VkAttachmentLoadOp                           loadOp;
                                                VK_ATTACHMENT_STORE_OP_STORE,                           // VkAttachmentStoreOp                          storeOp;
@@ -1629,8 +1825,8 @@ tcu::TestStatus FSRTestInstance::iterate (void)
                                                m_data.framebufferDim.width,                                                            //  deUint32                    width;
                                                m_data.framebufferDim.height,                                                           //  deUint32                    height;
                                                m_data.numColorLayers,                                                                          //  deUint32                    layerCount;
-                                               0u,                                                                                                                     //  deUint32                    viewFormatCount;
-                                               DE_NULL                                                                                                         //  const VkFormat*             pViewFormats;
+                                               1u,                                                                                                                     //  deUint32                    viewFormatCount;
+                                               &cbFormat                                                                                                       //  const VkFormat*             pViewFormats;
                                        }
                                );
                                if (m_data.useAttachment())
@@ -1643,8 +1839,8 @@ tcu::TestStatus FSRTestInstance::iterate (void)
                                                srWidth,                                                                                                        //  deUint32                    width;
                                                srHeight,                                                                                                       //  deUint32                    height;
                                                numSRLayers,                                                                                            //  deUint32                    layerCount;
-                                               0u,                                                                                                                     //  deUint32                    viewFormatCount;
-                                               DE_NULL                                                                                                         //  const VkFormat*             pViewFormats;
+                                               srViewType == VK_IMAGE_VIEW_TYPE_2D ? 1 : numSRLayers,          //  deUint32                    viewFormatCount;
+                                               &srFormat                                                                                                       //  const VkFormat*             pViewFormats;
                                        }
                                        );
 
@@ -1658,8 +1854,8 @@ tcu::TestStatus FSRTestInstance::iterate (void)
                                                m_data.framebufferDim.width,                                                            //  deUint32                    width;
                                                m_data.framebufferDim.height,                                                           //  deUint32                    height;
                                                m_data.numColorLayers,                                                                          //  deUint32                    layerCount;
-                                               0u,                                                                                                                     //  deUint32                    viewFormatCount;
-                                               DE_NULL                                                                                                         //  const VkFormat*             pViewFormats;
+                                               1u,                                                                                                                     //  deUint32                    viewFormatCount;
+                                               &dsFormat                                                                                                       //  const VkFormat*             pViewFormats;
                                        }
                                        );
 
@@ -1782,11 +1978,11 @@ tcu::TestStatus FSRTestInstance::iterate (void)
                                // Split the viewport into left and right halves
                                int x0 = 0, x1 = m_data.framebufferDim.width/2, x2 = m_data.framebufferDim.width;
 
-                               viewports.push_back(makeViewport((float)x0, 0, (float)(x1-x0), (float)m_data.framebufferDim.height, 0.0f, 1.0f));
-                               scissors.push_back(makeRect2D(x0, 0, x1-x0, m_data.framebufferDim.height));
+                               viewports.push_back(makeViewport((float)x0, 0, std::max((float)(x1 - x0), 1.0f), (float)m_data.framebufferDim.height, 0.0f, 1.0f));
+                               scissors.push_back(makeRect2D(x0, 0, x1 - x0, m_data.framebufferDim.height));
 
-                               viewports.push_back(makeViewport((float)x1, 0, (float)(x2-x1), (float)m_data.framebufferDim.height, 0.0f, 1.0f));
-                               scissors.push_back(makeRect2D(x1, 0, x2-x1, m_data.framebufferDim.height));
+                               viewports.push_back(makeViewport((float)x1, 0, std::max((float)(x2 - x1), 1.0f), (float)m_data.framebufferDim.height, 0.0f, 1.0f));
+                               scissors.push_back(makeRect2D(x1, 0, x2 - x1, m_data.framebufferDim.height));
                        }
                        else
                        {
@@ -1794,11 +1990,22 @@ tcu::TestStatus FSRTestInstance::iterate (void)
                                scissors.push_back(makeRect2D(m_data.framebufferDim.width, m_data.framebufferDim.height));
                        }
 
-                       Move<VkShaderModule> fragShader = createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0);
-                       Move<VkShaderModule> vertShader = createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0);
+                       const auto& binaries = m_context.getBinaryCollection();
+                       Move<VkShaderModule> fragShader = createShaderModule(vk, device, binaries.get("frag"), 0);
+                       Move<VkShaderModule> vertShader;
                        Move<VkShaderModule> geomShader;
-                       if (m_data.geometryShader)
-                               geomShader = createShaderModule(vk, device, m_context.getBinaryCollection().get("geom"), 0);
+                       Move<VkShaderModule> meshShader;
+
+                       if (m_data.meshShader)
+                       {
+                               meshShader = createShaderModule(vk, device, binaries.get("mesh"), 0);
+                       }
+                       else
+                       {
+                               vertShader = createShaderModule(vk, device, binaries.get("vert"), 0);
+                               if (m_data.geometryShader)
+                                       geomShader = createShaderModule(vk, device, binaries.get("geom"), 0);
+                       }
 
                        const deUint32 fragSizeWH = m_data.sampleMaskTest ? 2 : 0;
 
@@ -1880,6 +2087,13 @@ tcu::TestStatus FSRTestInstance::iterate (void)
                        std::vector<GraphicsPipelineWrapper> pipelines;
                        pipelines.reserve(m_data.useDynamicState ? 1u : NUM_TRIANGLES);
 
+                       std::vector<VkDescriptorSet> descriptorSetsRaw;
+
+                       descriptorSetsRaw.reserve(descriptorSets.size());
+
+                       std::transform(begin(descriptorSets), end(descriptorSets), std::back_inserter(descriptorSetsRaw),
+                               [](const Move<VkDescriptorSet>& elem) { return elem.get(); });
+
 #ifndef CTS_USES_VULKANSC
                        const VkExtent2D srTexelSize { srTexelWidth, srTexelHeight };
                        if (m_data.groupParams->useSecondaryCmdBuffer)
@@ -1899,7 +2113,7 @@ tcu::TestStatus FSRTestInstance::iterate (void)
                                drawCommands(*secCmdBuffer, pipelines, viewports, scissors, *pipelineLayout, *renderPass,
                                                         &vertexInputStateCreateInfo, &dynamicStateCreateInfo, &rasterizationStateCreateInfo,
                                                         &depthStencilStateParams, &multisampleStateCreateInfo, &shadingRateStateCreateInfo,
-                                                        renderingCreateInfoWrapper, *vertShader, *geomShader, *fragShader, *descriptorSet, **vertexBuffer);
+                                                        renderingCreateInfoWrapper, *vertShader, *geomShader, *meshShader, *fragShader, descriptorSetsRaw, **vertexBuffer, pushConstantSize);
 
                                if (m_data.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
                                        endRendering(vk, *secCmdBuffer);
@@ -1929,7 +2143,7 @@ tcu::TestStatus FSRTestInstance::iterate (void)
                                drawCommands(*cmdBuffer, pipelines, viewports, scissors, *pipelineLayout, *renderPass,
                                                         &vertexInputStateCreateInfo, &dynamicStateCreateInfo, &rasterizationStateCreateInfo,
                                                         &depthStencilStateParams, &multisampleStateCreateInfo, &shadingRateStateCreateInfo,
-                                                        renderingCreateInfoWrapper, *vertShader, *geomShader, *fragShader, *descriptorSet, **vertexBuffer);
+                                                        renderingCreateInfoWrapper, *vertShader, *geomShader, *meshShader, *fragShader, descriptorSetsRaw, **vertexBuffer, pushConstantSize);
                                endRendering(vk, *cmdBuffer);
                        }
 #endif // CTS_USES_VULKANSC
@@ -1943,7 +2157,7 @@ tcu::TestStatus FSRTestInstance::iterate (void)
                                drawCommands(*cmdBuffer, pipelines, viewports, scissors, *pipelineLayout, *renderPass,
                                                         &vertexInputStateCreateInfo, &dynamicStateCreateInfo, &rasterizationStateCreateInfo,
                                                         &depthStencilStateParams, &multisampleStateCreateInfo, &shadingRateStateCreateInfo,
-                                                        renderingCreateInfoWrapper, *vertShader, *geomShader, *fragShader, *descriptorSet, **vertexBuffer);
+                                                        renderingCreateInfoWrapper, *vertShader, *geomShader, *meshShader, *fragShader, descriptorSetsRaw, **vertexBuffer, pushConstantSize);
                                endRenderPass(vk, *cmdBuffer);
                        }
 
@@ -1956,7 +2170,7 @@ tcu::TestStatus FSRTestInstance::iterate (void)
                        };
                        vk.cmdPipelineBarrier(*cmdBuffer, allPipelineStages, allPipelineStages, 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
 
-                       vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1, &*descriptorSet, 0u, DE_NULL);
+                       vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1, &mainDescriptorSet, 0u, DE_NULL);
                        vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
 
                        // Copy color/depth/stencil buffers to buffer memory
@@ -2300,7 +2514,7 @@ void FSRTestInstance::beginDynamicRender(VkCommandBuffer cmdBuffer, VkImageView
        {
                VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR,  // VkStructureType              sType;
                DE_NULL,                                                                                                                                // const void*                  pNext;
-               srImageView,                                                                                                                    // VkImageView                  imageView;
+               m_data.useAttachment() ? srImageView : DE_NULL,                                                 // VkImageView                  imageView;
                srImageLayout,                                                                                                                  // VkImageLayout                imageLayout;
                srTexelSize                                                                                                                             // VkExtent2D                   shadingRateAttachmentTexelSize;
        };
@@ -2336,7 +2550,7 @@ void FSRTestInstance::beginDynamicRender(VkCommandBuffer cmdBuffer, VkImageView
        vk::VkRenderingInfoKHR renderingInfo
        {
                vk::VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
-               m_data.useAttachment() ? &shadingRateAttachmentInfo : DE_NULL,
+               m_data.useAttachment() || m_data.useAttachmentWithoutImageView() ? &shadingRateAttachmentInfo : DE_NULL,
                renderingFlags,                                                                                                                 // VkRenderingFlagsKHR                                  flags;
                renderArea,                                                                                                                             // VkRect2D                                                             renderArea;
                m_data.multiView ? 1 : m_data.numColorLayers,                                                   // deUint32                                                             layerCount;
@@ -2544,16 +2758,35 @@ void FSRTestInstance::drawCommands(VkCommandBuffer                                                                      cmdBuffer,
                                                                   PipelineRenderingCreateInfoWrapper                           dynamicRenderingState,
                                                                   const VkShaderModule                                                         vertShader,
                                                                   const VkShaderModule                                                         geomShader,
+                                                                  const VkShaderModule                                                         meshShader,
                                                                   const VkShaderModule                                                         fragShader,
-                                                                  VkDescriptorSet                                                                      descriptorSet,
-                                                                  VkBuffer                                                                                     vertexBuffer)
+                                                                  const std::vector<VkDescriptorSet>&                          descriptorSets,
+                                                                  VkBuffer                                                                                     vertexBuffer,
+                                                                  const uint32_t                                                                       pushConstantSize)
 {
        const DeviceInterface&  vk              = m_context.getDeviceInterface();
        const VkDevice                  device  = m_context.getDevice();
+       const bool                              useMesh = (meshShader != DE_NULL);
 
-       VkFlags allShaderStages = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT;
-       if (m_data.geometryShader)
-               allShaderStages |= VK_SHADER_STAGE_GEOMETRY_BIT;
+#ifdef CTS_USES_VULKANSC
+       if (useMesh)
+               DE_ASSERT(false);
+#endif // CTS_USES_VULKANSC
+
+       VkFlags allShaderStages = VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT;
+
+       if (useMesh)
+       {
+#ifndef CTS_USES_VULKANSC
+               allShaderStages |= VK_SHADER_STAGE_MESH_BIT_EXT;
+#endif // CTS_USES_VULKANSC
+       }
+       else
+       {
+               allShaderStages |= VK_SHADER_STAGE_VERTEX_BIT;
+               if (m_data.geometryShader)
+                       allShaderStages |= VK_SHADER_STAGE_GEOMETRY_BIT;
+       }
 
        VkPipelineCreateFlags pipelineCreateFlags = (VkPipelineCreateFlags)0;
 
@@ -2562,51 +2795,102 @@ void FSRTestInstance::drawCommands(VkCommandBuffer                                                                     cmdBuffer,
                pipelineCreateFlags |= VK_PIPELINE_CREATE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR;
 #endif // CTS_USES_VULKANSC
 
-       vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, DE_NULL);
+       vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, static_cast<uint32_t>(descriptorSets.size()), de::dataOrNull(descriptorSets), 0, DE_NULL);
+
+       PipelineRenderingCreateInfoWrapper              pipelineRenderingCreateInfo = dynamicRenderingState;
+#ifndef CTS_USES_VULKANSC
+       vk::VkPipelineRenderingCreateInfo               pipelineRenderingCreateInfoWithGarbage;
+       if (m_data.garbageAttachment)
+       {
+               pipelineRenderingCreateInfoWithGarbage = *dynamicRenderingState.ptr;
+               pipelineRenderingCreateInfoWithGarbage.colorAttachmentCount             = 99999u;
+               pipelineRenderingCreateInfoWithGarbage.pColorAttachmentFormats  = reinterpret_cast<VkFormat *>(0x11);
+
+               pipelineRenderingCreateInfo = &pipelineRenderingCreateInfoWithGarbage;
+       }
+#endif
 
        // If using dynamic state, create a single graphics pipeline and bind it
        if (m_data.useDynamicState)
        {
                pipelines.emplace_back(vk, device, m_data.groupParams->pipelineConstructionType, pipelineCreateFlags);
-               pipelines.back()
+               auto& pipeline = pipelines.back();
+
+               pipeline
                        .setDefaultColorBlendState()
-                       .setDynamicState(dynamicState)
-                       .setupVertexInputStete(vertexInputState)
-                       .setupPreRasterizationShaderState(viewports,
-                                                                                         scissors,
-                                                                                         pipelineLayout,
-                                                                                         renderPass,
-                                                                                         0u,
-                                                                                         vertShader,
-                                                                                         rasterizationState,
-                                                                                         DE_NULL,
-                                                                                         DE_NULL,
-                                                                                         geomShader,
-                                                                                         DE_NULL,
-                                                                                         dynamicRenderingState)
+                       .setDynamicState(dynamicState);
+
+               if (useMesh)
+               {
+#ifndef CTS_USES_VULKANSC
+                       pipeline
+                               .setupPreRasterizationMeshShaderState(viewports,
+                                                                                                         scissors,
+                                                                                                         pipelineLayout,
+                                                                                                         renderPass,
+                                                                                                         0u,
+                                                                                                         DE_NULL,
+                                                                                                         meshShader,
+                                                                                                         rasterizationState,
+                                                                                                         nullptr,
+                                                                                                         nullptr,
+                                                                                                         shadingRateState,
+                                                                                                         pipelineRenderingCreateInfo);
+#endif // CTS_USES_VULKANSC
+               }
+               else
+               {
+                       pipeline
+                               .setupVertexInputState(vertexInputState)
+                               .setupPreRasterizationShaderState(viewports,
+                                                                                                 scissors,
+                                                                                                 pipelineLayout,
+                                                                                                 renderPass,
+                                                                                                 0u,
+                                                                                                 vertShader,
+                                                                                                 rasterizationState,
+                                                                                                 DE_NULL,
+                                                                                                 DE_NULL,
+                                                                                                 geomShader,
+                                                                                                 DE_NULL,
+                                                                                                 shadingRateState,
+                                                                                                 pipelineRenderingCreateInfo);
+               }
+
+               pipeline
                        .setupFragmentShaderState(pipelineLayout,
                                                                          renderPass,
                                                                          0u,
                                                                          fragShader,
                                                                          depthStencilState,
-                                                                         multisampleState,
-                                                                         shadingRateState)
+                                                                         multisampleState)
                        .setupFragmentOutputState(renderPass, 0u, DE_NULL, multisampleState)
                        .setMonolithicPipelineLayout(pipelineLayout)
                        .buildPipeline();
 
-               vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.back().getPipeline());
+               vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.getPipeline());
        }
 
+       // Push constant block (must match shaders).
+       struct
+       {
+               int32_t         shadingRate;
+               uint32_t        instanceIndex;
+       } pushConstantBlock;
+
        for (deInt32 i = 0; i < NUM_TRIANGLES; ++i)
        {
-               // Bind vertex attributes pointing to the next triangle
-               VkDeviceSize vertexBufferOffset = i * 3 * 2 * sizeof(float);
-               vk.cmdBindVertexBuffers(cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
+               if (!useMesh)
+               {
+                       // Bind vertex attributes pointing to the next triangle
+                       VkDeviceSize vertexBufferOffset = i * 3 * 2 * sizeof(float);
+                       vk.cmdBindVertexBuffers(cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
+               }
 
-               // Put primitive shading rate in a push constant
-               deInt32 shadingRatePC = PrimIDToPrimitiveShadingRate(i);
-               vk.cmdPushConstants(cmdBuffer, pipelineLayout, allShaderStages, 0, sizeof(shadingRatePC), &shadingRatePC);
+               // Put primitive shading rate and instance index (used in mesh shading cases) in push constants.
+               pushConstantBlock.shadingRate   = PrimIDToPrimitiveShadingRate(i);
+               pushConstantBlock.instanceIndex = static_cast<uint32_t>(i);
+               vk.cmdPushConstants(cmdBuffer, pipelineLayout, allShaderStages, 0, pushConstantSize, &pushConstantBlock);
 
                if (m_data.useDynamicState)
                {
@@ -2619,38 +2903,78 @@ void FSRTestInstance::drawCommands(VkCommandBuffer                                                                      cmdBuffer,
                        shadingRateState->fragmentSize = ShadingRateEnumToExtent(PrimIDToPipelineShadingRate(i));
 
                        pipelines.emplace_back(vk, device, m_data.groupParams->pipelineConstructionType, pipelineCreateFlags);
-                       pipelines.back()
+                       auto& pipeline = pipelines.back();
+
+                       pipeline
                                .setDefaultColorBlendState()
-                               .setDynamicState(dynamicState)
-                               .setupVertexInputStete(vertexInputState)
-                               .setupPreRasterizationShaderState(viewports,
-                                                                                                 scissors,
-                                                                                                 pipelineLayout,
-                                                                                                 renderPass,
-                                                                                                 0u,
-                                                                                                 vertShader,
-                                                                                                 rasterizationState,
-                                                                                                 DE_NULL,
-                                                                                                 DE_NULL,
-                                                                                                 geomShader,
-                                                                                                 DE_NULL,
-                                                                                                 dynamicRenderingState)
+                               .setDynamicState(dynamicState);
+
+                       if (useMesh)
+                       {
+#ifndef CTS_USES_VULKANSC
+                               pipeline
+                                       .setupPreRasterizationMeshShaderState(viewports,
+                                                                                                                 scissors,
+                                                                                                                 pipelineLayout,
+                                                                                                                 renderPass,
+                                                                                                                 0u,
+                                                                                                                 DE_NULL,
+                                                                                                                 meshShader,
+                                                                                                                 rasterizationState,
+                                                                                                                 nullptr,
+                                                                                                                 nullptr,
+                                                                                                                 shadingRateState,
+                                                                                                                 dynamicRenderingState);
+#endif // CTS_USES_VULKANSC
+                       }
+                       else
+                       {
+                               pipeline
+                                       .setupVertexInputState(vertexInputState)
+                                       .setupPreRasterizationShaderState(viewports,
+                                                                                                         scissors,
+                                                                                                         pipelineLayout,
+                                                                                                         renderPass,
+                                                                                                         0u,
+                                                                                                         vertShader,
+                                                                                                         rasterizationState,
+                                                                                                         DE_NULL,
+                                                                                                         DE_NULL,
+                                                                                                         geomShader,
+                                                                                                         DE_NULL,
+                                                                                                         shadingRateState,
+                                                                                                         dynamicRenderingState);
+                       }
+
+                       pipeline
                                .setupFragmentShaderState(pipelineLayout,
                                                                                  renderPass,
                                                                                  0u,
                                                                                  fragShader,
                                                                                  depthStencilState,
-                                                                                 multisampleState,
-                                                                                 shadingRateState)
+                                                                                 multisampleState)
+#ifndef CTS_USES_VULKANSC
+                               .setRenderingColorAttachmentsInfo(dynamicRenderingState)
+#endif
                                .setupFragmentOutputState(renderPass, 0u, DE_NULL, multisampleState)
                                .setMonolithicPipelineLayout(pipelineLayout)
                                .buildPipeline();
 
-                       vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.back().getPipeline());
+                       vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.getPipeline());
                }
 
-               // Draw one triangle, with "primitive ID" in gl_InstanceIndex
-               vk.cmdDraw(cmdBuffer, 3u, 1, 0u, i);
+               if (useMesh)
+               {
+#ifndef CTS_USES_VULKANSC
+                       // Create a single workgroup to draw one triangle. The "primitive id" will be in the push constants.
+                       vk.cmdDrawMeshTasksEXT(cmdBuffer, 1u, 1u, 1u);
+#endif // CTS_USES_VULKANSC
+               }
+               else
+               {
+                       // Draw one triangle, with "primitive ID" in gl_InstanceIndex
+                       vk.cmdDraw(cmdBuffer, 3u, 1, 0u, i);
+               }
        }
 }
 
@@ -2681,23 +3005,27 @@ void createBasicTests (tcu::TestContext& testCtx, tcu::TestCaseGroup* parentGrou
 
        TestGroupCase groupCases[] =
        {
-               { 0,    "basic",                                "basic tests"                                   },
-               { 1,    "apisamplemask",                "use pSampleMask"                               },
-               { 2,    "samplemaskin",                 "use gl_SampleMaskIn"                   },
-               { 3,    "conservativeunder",    "conservative underestimation"  },
-               { 4,    "conservativeover",             "conservative overestimation"   },
-               { 5,    "fragdepth",                    "depth shader output"                   },
-               { 6,    "fragstencil",                  "stencil shader output"                 },
-               { 7,    "multiviewport",                "multiple viewports and gl_ViewportIndex"       },
-               { 8,    "colorlayered",                 "multiple layer color, single layer shading rate"       },
-               { 9,    "srlayered",                    "multiple layer color, multiple layers shading rate"    },
-               { 10,   "multiview",                    "multiview"     },
-               { 11,   "multiviewsrlayered",   "multiview and multilayer shading rate" },
-               { 12,   "multiviewcorrelation", "multiview with correlation mask"       },
-               { 13,   "interlock",                    "fragment shader interlock"     },
-               { 14,   "samplelocations",              "custom sample locations"       },
-               { 15,   "sampleshadingenable",  "enable sample shading in createinfo"   },
-               { 16,   "sampleshadinginput",   "enable sample shading by using gl_SampleID"    },
+               { 0,    "basic",                                        "basic tests"                                                                                   },
+               { 1,    "apisamplemask",                        "use pSampleMask"                                                                               },
+               { 2,    "samplemaskin",                         "use gl_SampleMaskIn"                                                                   },
+               { 3,    "conservativeunder",            "conservative underestimation"                                                  },
+               { 4,    "conservativeover",                     "conservative overestimation"                                                   },
+               { 5,    "fragdepth",                            "depth shader output"                                                                   },
+               { 6,    "fragstencil",                          "stencil shader output"                                                                 },
+               { 7,    "multiviewport",                        "multiple viewports and gl_ViewportIndex"                               },
+               { 8,    "colorlayered",                         "multiple layer color, single layer shading rate"               },
+               { 9,    "srlayered",                            "multiple layer color, multiple layers shading rate"    },
+               { 10,   "multiview",                            "multiview"                                                                                             },
+               { 11,   "multiviewsrlayered",           "multiview and multilayer shading rate"                                 },
+               { 12,   "multiviewcorrelation",         "multiview with correlation mask"                                               },
+               { 13,   "interlock",                            "fragment shader interlock"                                                             },
+               { 14,   "samplelocations",                      "custom sample locations"                                                               },
+               { 15,   "sampleshadingenable",          "enable sample shading in createinfo"                                   },
+               { 16,   "sampleshadinginput",           "enable sample shading by using gl_SampleID"                    },
+#ifndef CTS_USES_VULKANSC
+               { 17,   "fragdepth_early_late",         "depth shader output"                                                                   },
+               { 18,   "fragstencil_early_late",       "stencil shader output"                                                                 },
+#endif
        };
 
        TestGroupCase dynCases[] =
@@ -2708,9 +3036,10 @@ void createBasicTests (tcu::TestContext& testCtx, tcu::TestCaseGroup* parentGrou
 
        TestGroupUsageCase attCases[] =
        {
-               { AttachmentUsage::NO_ATTACHMENT,               "noattachment",         "no shading rate attachment"                    },
-               { AttachmentUsage::WITH_ATTACHMENT,             "attachment",           "has shading rate attachment"                   },
-               { AttachmentUsage::NO_ATTACHMENT_PTR,   "noattachmentptr",      "no shading rate attachment pointer"    },
+               { AttachmentUsage::NO_ATTACHMENT,                                               "noattachment",                         "no shading rate attachment"                                    },
+               { AttachmentUsage::WITH_ATTACHMENT,                                             "attachment",                           "has shading rate attachment"                                   },
+               { AttachmentUsage::NO_ATTACHMENT_PTR,                                   "noattachmentptr",                      "no shading rate attachment pointer"                    },
+               { AttachmentUsage::WITH_ATTACHMENT_WITHOUT_IMAGEVIEW,   "attachment_noimageview",       "has shading rate attachment without imageview" },
        };
 
        TestGroupCase shdCases[] =
@@ -2746,10 +3075,13 @@ void createBasicTests (tcu::TestContext& testCtx, tcu::TestCaseGroup* parentGrou
                { VK_SAMPLE_COUNT_16_BIT,       "samples16",    "16 raster samples"     },
        };
 
-       TestGroupCase geomCases[] =
+       TestGroupCase shaderCases[] =
        {
-               { 0,    "vs",   "vertex shader only"    },
+               { 0,    "vs",   "vertex shader only"                    },
                { 1,    "gs",   "vertex and geometry shader"    },
+#ifndef CTS_USES_VULKANSC
+               { 2,    "ms",   "mesh shader"                                   },
+#endif // CTS_USES_VULKANSC
        };
 
        deInt32 seed = 0;
@@ -2779,6 +3111,10 @@ void createBasicTests (tcu::TestContext& testCtx, tcu::TestCaseGroup* parentGrou
                                if (groupParams->useDynamicRendering && attCases[attNdx].usage == AttachmentUsage::NO_ATTACHMENT_PTR)
                                        continue;
 
+                               // WITH_ATTACHMENT_WITHOUT_IMAGEVIEW is only for VkRenderingFragmentShadingRateAttachmentInfoKHR.
+                               if (!groupParams->useDynamicRendering && attCases[attNdx].usage == AttachmentUsage::WITH_ATTACHMENT_WITHOUT_IMAGEVIEW)
+                                       continue;
+
                                de::MovePtr<tcu::TestCaseGroup> attGroup(new tcu::TestCaseGroup(testCtx, attCases[attNdx].name, attCases[attNdx].description));
                                for (int shdNdx = 0; shdNdx < DE_LENGTH_OF_ARRAY(shdCases); shdNdx++)
                                {
@@ -2807,17 +3143,17 @@ void createBasicTests (tcu::TestContext& testCtx, tcu::TestCaseGroup* parentGrou
                                                                                continue;
 
                                                                        de::MovePtr<tcu::TestCaseGroup> sampGroup(new tcu::TestCaseGroup(testCtx, sampCases[sampNdx].name, sampCases[sampNdx].description));
-                                                                       for (int geomNdx = 0; geomNdx < DE_LENGTH_OF_ARRAY(geomCases); geomNdx++)
+                                                                       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(shaderCases); shaderNdx++)
                                                                        {
                                                                                // reduce number of tests for dynamic rendering cases where secondary command buffer is used
-                                                                               if (groupParams->useSecondaryCmdBuffer && (geomNdx != 0))
+                                                                               if (groupParams->useSecondaryCmdBuffer && (shaderNdx != 0))
                                                                                        continue;
 
                                                                                bool useApiSampleMask = groupNdx == 1;
                                                                                bool useSampleMaskIn = groupNdx == 2;
                                                                                bool consRast = groupNdx == 3 || groupNdx == 4;
-                                                                               bool fragDepth = groupNdx == 5;
-                                                                               bool fragStencil = groupNdx == 6;
+                                                                               bool fragDepth = groupNdx == 5 || groupNdx == 17;
+                                                                               bool fragStencil = groupNdx == 6 || groupNdx == 18;
                                                                                bool multiViewport = groupNdx == 7;
                                                                                bool colorLayered = groupNdx == 8 || groupNdx == 9;
                                                                                bool srLayered = groupNdx == 9 || groupNdx == 11;
@@ -2827,11 +3163,15 @@ void createBasicTests (tcu::TestContext& testCtx, tcu::TestCaseGroup* parentGrou
                                                                                bool sampleLocations = groupNdx == 14;
                                                                                bool sampleShadingEnable = groupNdx == 15;
                                                                                bool sampleShadingInput = groupNdx == 16;
+                                                                               bool useGeometryShader = (shaderCases[shaderNdx].count == 1u);
+                                                                               bool useMeshShader = (shaderCases[shaderNdx].count == 2u);
+                                                                               bool earlyAndLateTest = groupNdx == 17 || groupNdx == 18;
+
                                                                                VkConservativeRasterizationModeEXT conservativeMode = (groupNdx == 3) ? VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT : VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT;
                                                                                deUint32 numColorLayers = (colorLayered || multiView) ? 2u : 1u;
 
                                                                                // Don't bother with geometry shader if we're not testing shader writes
-                                                                               if (geomCases[geomNdx].count && !shdCases[shdNdx].count)
+                                                                               if (useGeometryShader && !shdCases[shdNdx].count)
                                                                                        continue;
 
                                                                                // reduce number of tests
@@ -2842,11 +3182,11 @@ void createBasicTests (tcu::TestContext& testCtx, tcu::TestCaseGroup* parentGrou
                                                                                        continue;
 
                                                                                // Don't bother with geometry shader if we're testing conservative raster, sample mask, depth/stencil
-                                                                               if (geomCases[geomNdx].count && (useApiSampleMask || useSampleMaskIn || consRast || fragDepth || fragStencil))
+                                                                               if (useGeometryShader && (useApiSampleMask || useSampleMaskIn || consRast || fragDepth || fragStencil))
                                                                                        continue;
 
                                                                                // Don't bother with geometry shader if we're testing non-dynamic state
-                                                                               if (geomCases[geomNdx].count && !dynCases[dynNdx].count)
+                                                                               if (useGeometryShader && !dynCases[dynNdx].count)
                                                                                        continue;
 
                                                                                // Only test multiViewport/layered with shaderWritesRate
@@ -2869,7 +3209,8 @@ void createBasicTests (tcu::TestContext& testCtx, tcu::TestCaseGroup* parentGrou
                                                                                        },                                                                                                              // VkFragmentShadingRateCombinerOpKHR combinerOp[2];
                                                                                        attCases[attNdx].usage,                                                                 // AttachmentUsage attachmentUsage;
                                                                                        (bool)shdCases[shdNdx].count,                                                   // bool shaderWritesRate;
-                                                                                       (bool)geomCases[geomNdx].count,                                                 // bool geometryShader;
+                                                                                       useGeometryShader,                                                                              // bool geometryShader;
+                                                                                       useMeshShader,                                                                                  // bool meshShader;
                                                                                        (bool)dynCases[dynNdx].count,                                                   // bool useDynamicState;
                                                                                        useApiSampleMask,                                                                               // bool useApiSampleMask;
                                                                                        useSampleMaskIn,                                                                                // bool useSampleMaskIn;
@@ -2889,9 +3230,11 @@ void createBasicTests (tcu::TestContext& testCtx, tcu::TestCaseGroup* parentGrou
                                                                                        sampleShadingEnable,                                                                    // bool sampleShadingEnable;
                                                                                        sampleShadingInput,                                                                             // bool sampleShadingInput;
                                                                                        false,                                                                                                  // bool sampleMaskTest;
+                                                                                       earlyAndLateTest,                                                                               // bool earlyAndLateTest;
+                                                                                       false,                                                                                                  // bool garbageAttachment;
                                                                                };
 
-                                                                               sampGroup->addChild(new FSRTestCase(testCtx, geomCases[geomNdx].name, geomCases[geomNdx].description, c));
+                                                                               sampGroup->addChild(new FSRTestCase(testCtx, shaderCases[shaderNdx].name, shaderCases[shaderNdx].description, c));
                                                                        }
                                                                        extGroup->addChild(sampGroup.release());
                                                                }
@@ -2910,41 +3253,88 @@ void createBasicTests (tcu::TestContext& testCtx, tcu::TestCaseGroup* parentGrou
                parentGroup->addChild(group.release());
        }
 
-       if (!groupParams->useSecondaryCmdBuffer)
        {
                de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "misc_tests", "Single tests that don't need to be part of above test matrix"));
-               group->addChild(new FSRTestCase(testCtx, "sample_mask_test", "", {
-                       groupParams,                                                                                    // SharedGroupParams groupParams;
-                       123,                                                                                                    // deInt32 seed;
-                       {32,  33},                                                                                              // VkExtent2D framebufferDim;
-                       VK_SAMPLE_COUNT_4_BIT,                                                                  // VkSampleCountFlagBits samples;
-                       {
-                               VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR,
-                               VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR
-                       },                                                                                                              // VkFragmentShadingRateCombinerOpKHR combinerOp[2];
-                       AttachmentUsage::NO_ATTACHMENT,                                                 // AttachmentUsage attachmentUsage;
-                       true,                                                                                                   // bool shaderWritesRate;
-                       false,                                                                                                  // bool geometryShader;
-                       false,                                                                                                  // bool useDynamicState;
-                       true,                                                                                                   // bool useApiSampleMask;
-                       false,                                                                                                  // bool useSampleMaskIn;
-                       false,                                                                                                  // bool conservativeEnable;
-                       VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT,   // VkConservativeRasterizationModeEXT conservativeMode;
-                       false,                                                                                                  // bool useDepthStencil;
-                       false,                                                                                                  // bool fragDepth;
-                       false,                                                                                                  // bool fragStencil;
-                       false,                                                                                                  // bool multiViewport;
-                       false,                                                                                                  // bool colorLayered;
-                       false,                                                                                                  // bool srLayered;
-                       1u,                                                                                                             // deUint32 numColorLayers;
-                       false,                                                                                                  // bool multiView;
-                       false,                                                                                                  // bool correlationMask;
-                       false,                                                                                                  // bool interlock;
-                       false,                                                                                                  // bool sampleLocations;
-                       false,                                                                                                  // bool sampleShadingEnable;
-                       false,                                                                                                  // bool sampleShadingInput;
-                       true,                                                                                                   // bool sampleMaskTest;
-               }));
+
+               if (!groupParams->useSecondaryCmdBuffer)
+               {
+                       group->addChild(new FSRTestCase(testCtx, "sample_mask_test", "", {
+                               groupParams,                                                                                    // SharedGroupParams groupParams;
+                               123,                                                                                                    // deInt32 seed;
+                               {32,  33},                                                                                              // VkExtent2D framebufferDim;
+                               VK_SAMPLE_COUNT_4_BIT,                                                                  // VkSampleCountFlagBits samples;
+                               {
+                                       VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR,
+                                       VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR
+                               },                                                                                                              // VkFragmentShadingRateCombinerOpKHR combinerOp[2];
+                               AttachmentUsage::NO_ATTACHMENT,                                                 // AttachmentUsage attachmentUsage;
+                               true,                                                                                                   // bool shaderWritesRate;
+                               false,                                                                                                  // bool geometryShader;
+                               false,                                                                                                  // bool meshShader;
+                               false,                                                                                                  // bool useDynamicState;
+                               true,                                                                                                   // bool useApiSampleMask;
+                               false,                                                                                                  // bool useSampleMaskIn;
+                               false,                                                                                                  // bool conservativeEnable;
+                               VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT,   // VkConservativeRasterizationModeEXT conservativeMode;
+                               false,                                                                                                  // bool useDepthStencil;
+                               false,                                                                                                  // bool fragDepth;
+                               false,                                                                                                  // bool fragStencil;
+                               false,                                                                                                  // bool multiViewport;
+                               false,                                                                                                  // bool colorLayered;
+                               false,                                                                                                  // bool srLayered;
+                               1u,                                                                                                             // deUint32 numColorLayers;
+                               false,                                                                                                  // bool multiView;
+                               false,                                                                                                  // bool correlationMask;
+                               false,                                                                                                  // bool interlock;
+                               false,                                                                                                  // bool sampleLocations;
+                               false,                                                                                                  // bool sampleShadingEnable;
+                               false,                                                                                                  // bool sampleShadingInput;
+                               true,                                                                                                   // bool sampleMaskTest;
+                               false,                                                                                                  // bool earlyAndLateTest;
+                               false,                                                                                                  // bool garbageAttachment;
+                       }));
+               }
+
+#ifndef CTS_USES_VULKANSC
+               if (groupParams->useDynamicRendering && groupParams->pipelineConstructionType != vk::PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
+               {
+                       group->addChild(new FSRTestCase(testCtx, "garbage_color_attachment", "", {
+                               groupParams,                                                                                    // SharedGroupParams groupParams;
+                               123,                                                                                                    // deInt32 seed;
+                               {32,  33},                                                                                              // VkExtent2D framebufferDim;
+                               VK_SAMPLE_COUNT_1_BIT,                                                                  // VkSampleCountFlagBits samples;
+                               {
+                                       VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR,
+                                       VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR
+                               },                                                                                                              // VkFragmentShadingRateCombinerOpKHR combinerOp[2];
+                               AttachmentUsage::NO_ATTACHMENT,                                                 // AttachmentUsage attachmentUsage;
+                               false,                                                                                                  // bool shaderWritesRate;
+                               false,                                                                                                  // bool geometryShader;
+                               false,                                                                                                  // bool meshShader;
+                               false,                                                                                                  // bool useDynamicState;
+                               false,                                                                                                  // bool useApiSampleMask;
+                               false,                                                                                                  // bool useSampleMaskIn;
+                               false,                                                                                                  // bool conservativeEnable;
+                               VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT,   // VkConservativeRasterizationModeEXT conservativeMode;
+                               false,                                                                                                  // bool useDepthStencil;
+                               false,                                                                                                  // bool fragDepth;
+                               false,                                                                                                  // bool fragStencil;
+                               false,                                                                                                  // bool multiViewport;
+                               false,                                                                                                  // bool colorLayered;
+                               false,                                                                                                  // bool srLayered;
+                               1u,                                                                                                             // deUint32 numColorLayers;
+                               false,                                                                                                  // bool multiView;
+                               false,                                                                                                  // bool correlationMask;
+                               false,                                                                                                  // bool interlock;
+                               false,                                                                                                  // bool sampleLocations;
+                               false,                                                                                                  // bool sampleShadingEnable;
+                               false,                                                                                                  // bool sampleShadingInput;
+                               false,                                                                                                  // bool sampleMaskTest;
+                               false,                                                                                                  // bool earlyAndLateTest;
+                               true,                                                                                                   // bool garbageAttachment;
+                       }));
+               }
+#endif // CTS_USES_VULKANSC
 
                parentGroup->addChild(group.release());
        }