1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2017-2019 The Khronos Group Inc.
6 * Copyright (c) 2018-2020 NVIDIA Corporation
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
22 * \brief Tests for VK_KHR_fragment_shading_rate
23 * The test renders 9*9 triangles, where each triangle has one of the valid
24 * fragment sizes ({1,2,4},{1,2,4}) (clamped to implementation limits) for
25 * each of the pipeline shading rate and the primitive shading rate. The
26 * fragment shader does an atomic add to a memory location to get a unique
27 * identifier for the fragment, and outputs the primitive ID, atomic counter,
28 * fragment size, and some other info the the color output. Then a compute
29 * shader copies this to buffer memory, and the host verifies several
30 * properties of the output. For example, if a sample has a particular
31 * primitive ID and atomic value, then all other samples in the tile with
32 * the same primitive ID should have the same atomic value.
33 *//*--------------------------------------------------------------------*/
35 #include "vktFragmentShadingRateBasic.hpp"
37 #include "vkBufferWithMemory.hpp"
38 #include "vkImageWithMemory.hpp"
39 #include "vkQueryUtil.hpp"
40 #include "vkBuilderUtil.hpp"
41 #include "vkCmdUtil.hpp"
42 #include "vkTypeUtil.hpp"
43 #include "vkObjUtil.hpp"
44 #include "vkImageUtil.hpp"
46 #include "vktTestGroupUtil.hpp"
47 #include "vktTestCase.hpp"
52 #include "deSharedPtr.hpp"
55 #include "tcuTestCase.hpp"
56 #include "tcuTestLog.hpp"
64 namespace FragmentShadingRate
71 #define NUM_TRIANGLES (9*9)
73 enum class AttachmentUsage
82 PipelineConstructionType pipelineConstructionType;
84 VkExtent2D framebufferDim;
85 VkSampleCountFlagBits samples;
86 VkFragmentShadingRateCombinerOpKHR combinerOp[2];
87 AttachmentUsage attachmentUsage;
88 bool shaderWritesRate;
91 bool useDynamicRendering;
92 bool useApiSampleMask;
94 bool conservativeEnable;
95 VkConservativeRasterizationModeEXT conservativeMode;
96 bool useDepthStencil; // == fragDepth || fragStencil
101 bool srLayered; // colorLayered must also be true
102 deUint32 numColorLayers;
104 bool correlationMask;
106 bool sampleLocations;
107 bool sampleShadingEnable;
108 bool sampleShadingInput;
111 bool useAttachment () const
113 return (attachmentUsage == AttachmentUsage::WITH_ATTACHMENT);
117 class FSRTestInstance : public TestInstance
120 FSRTestInstance (Context& context, const CaseDef& data);
121 ~FSRTestInstance (void);
122 tcu::TestStatus iterate (void);
128 // Cache simulated combiner operations, to avoid recomputing per-sample
129 deInt32 m_simulateValueCount;
130 vector<deInt32> m_simulateCache;
131 // Cache mapping of primitive ID to pipeline/primitive shading rate
132 vector<deInt32> m_primIDToPrimitiveShadingRate;
133 vector<deInt32> m_primIDToPipelineShadingRate;
134 deUint32 m_supportedFragmentShadingRateCount;
135 vector<VkPhysicalDeviceFragmentShadingRateKHR> m_supportedFragmentShadingRates;
136 VkPhysicalDeviceFragmentShadingRatePropertiesKHR m_shadingRateProperties;
138 deInt32 PrimIDToPrimitiveShadingRate (deInt32 primID);
139 deInt32 PrimIDToPipelineShadingRate (deInt32 primID);
140 VkExtent2D SanitizeExtent (VkExtent2D ext) const;
141 deInt32 SanitizeRate (deInt32 rate) const;
142 deInt32 ShadingRateExtentToClampedMask (VkExtent2D ext, bool allowSwap) const;
143 deInt32 ShadingRateExtentToEnum (VkExtent2D ext) const;
144 VkExtent2D ShadingRateEnumToExtent (deInt32 rate) const;
145 deInt32 Simulate (deInt32 rate0, deInt32 rate1, deInt32 rate2);
146 VkExtent2D Combine (VkExtent2D ext0, VkExtent2D ext1, VkFragmentShadingRateCombinerOpKHR comb) const;
147 bool Force1x1 () const;
150 FSRTestInstance::FSRTestInstance (Context& context, const CaseDef& data)
151 : vkt::TestInstance (context)
153 , m_simulateValueCount (((4 * 4) | 4) + 1)
154 , m_simulateCache (m_simulateValueCount*m_simulateValueCount*m_simulateValueCount, ~0)
155 , m_primIDToPrimitiveShadingRate(NUM_TRIANGLES, ~0)
156 , m_primIDToPipelineShadingRate(NUM_TRIANGLES, ~0)
158 m_supportedFragmentShadingRateCount = 0;
159 m_context.getInstanceInterface().getPhysicalDeviceFragmentShadingRatesKHR(m_context.getPhysicalDevice(), &m_supportedFragmentShadingRateCount, DE_NULL);
161 if (m_supportedFragmentShadingRateCount < 3)
162 TCU_THROW(TestError, "*pFragmentShadingRateCount too small");
164 m_supportedFragmentShadingRates.resize(m_supportedFragmentShadingRateCount);
165 for (deUint32 i = 0; i < m_supportedFragmentShadingRateCount; ++i)
167 m_supportedFragmentShadingRates[i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_KHR;
168 m_supportedFragmentShadingRates[i].pNext = nullptr;
170 m_context.getInstanceInterface().getPhysicalDeviceFragmentShadingRatesKHR(m_context.getPhysicalDevice(), &m_supportedFragmentShadingRateCount, &m_supportedFragmentShadingRates[0]);
172 m_shadingRateProperties = m_context.getFragmentShadingRateProperties();
175 FSRTestInstance::~FSRTestInstance (void)
179 class FSRTestCase : public TestCase
182 FSRTestCase (tcu::TestContext& context, const char* name, const char* desc, const CaseDef data);
184 virtual void initPrograms (SourceCollections& programCollection) const;
185 virtual TestInstance* createInstance (Context& context) const;
186 virtual void checkSupport (Context& context) const;
192 FSRTestCase::FSRTestCase (tcu::TestContext& context, const char* name, const char* desc, const CaseDef data)
193 : vkt::TestCase (context, name, desc)
198 FSRTestCase::~FSRTestCase (void)
202 bool FSRTestInstance::Force1x1() const
204 if (m_data.useApiSampleMask && !m_context.getFragmentShadingRateProperties().fragmentShadingRateWithSampleMask)
207 if (m_data.useSampleMaskIn && !m_context.getFragmentShadingRateProperties().fragmentShadingRateWithShaderSampleMask)
210 if (m_data.conservativeEnable && !m_context.getFragmentShadingRateProperties().fragmentShadingRateWithConservativeRasterization)
213 if (m_data.useDepthStencil && !m_context.getFragmentShadingRateProperties().fragmentShadingRateWithShaderDepthStencilWrites)
216 if (m_data.interlock && !m_context.getFragmentShadingRateProperties().fragmentShadingRateWithFragmentShaderInterlock)
219 if (m_data.sampleLocations && !m_context.getFragmentShadingRateProperties().fragmentShadingRateWithCustomSampleLocations)
222 if (m_data.sampleShadingEnable || m_data.sampleShadingInput)
228 static VkImageUsageFlags cbUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
229 VK_IMAGE_USAGE_SAMPLED_BIT |
230 VK_IMAGE_USAGE_TRANSFER_DST_BIT |
231 VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
233 void FSRTestCase::checkSupport(Context& context) const
235 context.requireDeviceFunctionality("VK_KHR_fragment_shading_rate");
237 checkPipelineLibraryRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_data.pipelineConstructionType);
239 if (m_data.useDynamicRendering)
240 context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
242 if (!context.getFragmentShadingRateFeatures().pipelineFragmentShadingRate)
243 TCU_THROW(NotSupportedError, "pipelineFragmentShadingRate not supported");
245 if (m_data.shaderWritesRate &&
246 !context.getFragmentShadingRateFeatures().primitiveFragmentShadingRate)
247 TCU_THROW(NotSupportedError, "primitiveFragmentShadingRate not supported");
249 if (!context.getFragmentShadingRateFeatures().primitiveFragmentShadingRate &&
250 m_data.combinerOp[0] != VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR)
251 TCU_THROW(NotSupportedError, "primitiveFragmentShadingRate not supported");
253 if (!context.getFragmentShadingRateFeatures().attachmentFragmentShadingRate &&
254 m_data.combinerOp[1] != VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR)
255 TCU_THROW(NotSupportedError, "attachmentFragmentShadingRate not supported");
257 const auto& vki = context.getInstanceInterface();
258 const auto physicalDevice = context.getPhysicalDevice();
260 VkImageFormatProperties imageProperties;
261 VkResult result = vki.getPhysicalDeviceImageFormatProperties(physicalDevice, VK_FORMAT_R32G32B32A32_UINT, VK_IMAGE_TYPE_2D,
262 VK_IMAGE_TILING_OPTIMAL, cbUsage, 0, &imageProperties);
264 if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
265 TCU_THROW(NotSupportedError, "VK_FORMAT_R32G32B32A32_UINT not supported");
267 if (!(imageProperties.sampleCounts & m_data.samples))
268 TCU_THROW(NotSupportedError, "color buffer sample count not supported");
270 if (m_data.numColorLayers > imageProperties.maxArrayLayers)
271 TCU_THROW(NotSupportedError, "color buffer layers not supported");
273 if (m_data.useAttachment() && !context.getFragmentShadingRateFeatures().attachmentFragmentShadingRate)
274 TCU_THROW(NotSupportedError, "attachmentFragmentShadingRate not supported");
276 if (!context.getFragmentShadingRateProperties().fragmentShadingRateNonTrivialCombinerOps &&
277 ((m_data.combinerOp[0] != VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR && m_data.combinerOp[0] != VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR) ||
278 (m_data.combinerOp[1] != VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR && m_data.combinerOp[1] != VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR)))
279 TCU_THROW(NotSupportedError, "fragmentShadingRateNonTrivialCombinerOps not supported");
281 if (m_data.conservativeEnable)
283 context.requireDeviceFunctionality("VK_EXT_conservative_rasterization");
284 if (m_data.conservativeMode == VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT &&
285 !context.getConservativeRasterizationPropertiesEXT().primitiveUnderestimation)
286 TCU_THROW(NotSupportedError, "primitiveUnderestimation not supported");
289 if (m_data.fragStencil)
290 context.requireDeviceFunctionality("VK_EXT_shader_stencil_export");
292 if (m_data.multiViewport &&
293 !context.getFragmentShadingRateProperties().primitiveFragmentShadingRateWithMultipleViewports)
294 TCU_THROW(NotSupportedError, "primitiveFragmentShadingRateWithMultipleViewports not supported");
296 if (m_data.srLayered &&
297 !context.getFragmentShadingRateProperties().layeredShadingRateAttachments)
298 TCU_THROW(NotSupportedError, "layeredShadingRateAttachments not supported");
300 if ((m_data.multiViewport || m_data.colorLayered) &&
301 !m_data.geometryShader)
302 context.requireDeviceFunctionality("VK_EXT_shader_viewport_index_layer");
304 if (m_data.multiView && m_data.geometryShader &&
305 !context.getMultiviewFeatures().multiviewGeometryShader)
306 TCU_THROW(NotSupportedError, "multiviewGeometryShader not supported");
308 if (m_data.interlock &&
309 !context.getFragmentShaderInterlockFeaturesEXT().fragmentShaderPixelInterlock)
310 TCU_THROW(NotSupportedError, "fragmentShaderPixelInterlock not supported");
312 if (m_data.sampleLocations)
314 context.requireDeviceFunctionality("VK_EXT_sample_locations");
315 if (!(m_data.samples & context.getSampleLocationsPropertiesEXT().sampleLocationSampleCounts))
316 TCU_THROW(NotSupportedError, "samples not supported in sampleLocationSampleCounts");
319 if (m_data.sampleMaskTest && !context.getFragmentShadingRateProperties().fragmentShadingRateWithSampleMask)
320 TCU_THROW(NotSupportedError, "fragmentShadingRateWithSampleMask not supported");
322 checkPipelineLibraryRequirements(vki, physicalDevice, m_data.pipelineConstructionType);
325 // Error codes writted by the fragment shader
329 ERROR_FRAGCOORD_CENTER = 1,
330 ERROR_VTG_READBACK = 2,
331 ERROR_FRAGCOORD_DERIV = 3,
332 ERROR_FRAGCOORD_IMPLICIT_DERIV = 4,
335 void FSRTestCase::initPrograms (SourceCollections& programCollection) const
337 std::stringstream vss;
340 "#version 450 core\n"
341 "#extension GL_EXT_fragment_shading_rate : enable\n"
342 "#extension GL_ARB_shader_viewport_layer_array : enable\n"
343 "layout(push_constant) uniform PC {\n"
344 " int shadingRate;\n"
346 "layout(location = 0) in vec2 pos;\n"
347 "layout(location = 0) out int instanceIndex;\n"
348 "layout(location = 1) out int readbackok;\n"
349 "layout(location = 2) out float zero;\n"
352 " vec4 gl_Position;\n"
356 " gl_Position = vec4(pos, 0, 1);\n"
357 " instanceIndex = gl_InstanceIndex;\n"
361 if (m_data.shaderWritesRate)
363 vss << " gl_PrimitiveShadingRateEXT = pc.shadingRate;\n";
365 // Verify that we can read from the output variable
366 vss << " if (gl_PrimitiveShadingRateEXT != pc.shadingRate) readbackok = 0;\n";
368 if (!m_data.geometryShader)
370 if (m_data.multiViewport)
371 vss << " gl_ViewportIndex = instanceIndex & 1;\n";
372 if (m_data.colorLayered)
373 vss << " gl_Layer = (instanceIndex & 2) >> 1;\n";
379 programCollection.glslSources.add("vert") << glu::VertexSource(vss.str());
381 if (m_data.geometryShader)
383 std::string writeShadingRate = "";
384 if (m_data.shaderWritesRate)
387 " gl_PrimitiveShadingRateEXT = pc.shadingRate;\n"
388 " if (gl_PrimitiveShadingRateEXT != pc.shadingRate) readbackok = 0;\n";
390 if (m_data.multiViewport)
391 writeShadingRate += " gl_ViewportIndex = inInstanceIndex[0] & 1;\n";
393 if (m_data.colorLayered)
394 writeShadingRate += " gl_Layer = (inInstanceIndex[0] & 2) >> 1;\n";
397 std::stringstream gss;
399 "#version 450 core\n"
400 "#extension GL_EXT_fragment_shading_rate : enable\n"
402 "layout(push_constant) uniform PC {\n"
403 " int shadingRate;\n"
408 " vec4 gl_Position;\n"
411 "layout(location = 0) in int inInstanceIndex[];\n"
412 "layout(location = 0) out int outInstanceIndex;\n"
413 "layout(location = 1) out int readbackok;\n"
414 "layout(location = 2) out float zero;\n"
415 "layout(triangles) in;\n"
416 "layout(triangle_strip, max_vertices=3) out;\n"
418 "out gl_PerVertex {\n"
419 " vec4 gl_Position;\n"
424 " gl_Position = gl_in[0].gl_Position;\n"
425 " outInstanceIndex = inInstanceIndex[0];\n"
428 << writeShadingRate <<
431 " gl_Position = gl_in[1].gl_Position;\n"
432 " outInstanceIndex = inInstanceIndex[1];\n"
435 << writeShadingRate <<
438 " gl_Position = gl_in[2].gl_Position;\n"
439 " outInstanceIndex = inInstanceIndex[2];\n"
442 << writeShadingRate <<
446 programCollection.glslSources.add("geom") << glu::GeometrySource(gss.str());
449 std::stringstream fss;
452 "#version 450 core\n"
453 "#extension GL_EXT_fragment_shading_rate : enable\n"
454 "#extension GL_ARB_shader_stencil_export : enable\n"
455 "#extension GL_ARB_fragment_shader_interlock : enable\n"
456 "layout(location = 0) out uvec4 col0;\n"
457 "layout(set = 0, binding = 0) buffer Block { uint counter; } buf;\n"
458 "layout(set = 0, binding = 3) uniform usampler2D tex;\n"
459 "layout(location = 0) flat in int instanceIndex;\n"
460 "layout(location = 1) flat in int readbackok;\n"
461 "layout(location = 2) " << (m_data.sampleShadingInput ? "sample " : "") << "in float zero;\n";
463 if (m_data.interlock)
464 fss << "layout(pixel_interlock_ordered) in;\n";
470 if (m_data.interlock)
471 fss << " beginInvocationInterlockARB();\n";
474 // X component gets shading rate enum
475 " col0.x = gl_ShadingRateEXT;\n"
477 // Z component gets packed primitiveID | atomic value
478 " col0.z = (instanceIndex << 24) | ((atomicAdd(buf.counter, 1) + 1) & 0x00FFFFFFu);\n"
479 " ivec2 fragCoordXY = ivec2(gl_FragCoord.xy);\n"
480 " ivec2 fragSize = ivec2(1<<((gl_ShadingRateEXT/4)&3), 1<<(gl_ShadingRateEXT&3));\n"
481 // W component gets error code
482 " col0.w = uint(zero)" << (m_data.sampleShadingInput ? " * gl_SampleID" : "") << ";\n"
483 " if (((fragCoordXY - fragSize / 2) % fragSize) != ivec2(0,0))\n"
484 " col0.w = " << ERROR_FRAGCOORD_CENTER << ";\n";
486 if (m_data.shaderWritesRate)
489 " if (readbackok != 1)\n"
490 " col0.w = " << ERROR_VTG_READBACK << ";\n";
493 // When sample shading, gl_FragCoord is more likely to give bad derivatives,
494 // e.g. due to a partially covered quad having some pixels center sample and
495 // some sample at a sample location.
496 if (!m_data.sampleShadingEnable && !m_data.sampleShadingInput)
498 fss << " if (dFdx(gl_FragCoord.xy) != ivec2(fragSize.x, 0) || dFdy(gl_FragCoord.xy) != ivec2(0, fragSize.y))\n"
499 " col0.w = (fragSize.y << 26) | (fragSize.x << 20) | (int(dFdx(gl_FragCoord.xy)) << 14) | (int(dFdx(gl_FragCoord.xy)) << 8) | " << ERROR_FRAGCOORD_DERIV << ";\n";
501 fss << " uint implicitDerivX = texture(tex, vec2(gl_FragCoord.x / textureSize(tex, 0).x, 0)).x;\n"
502 " uint implicitDerivY = texture(tex, vec2(0, gl_FragCoord.y / textureSize(tex, 0).y)).x;\n"
503 " if (implicitDerivX != fragSize.x || implicitDerivY != fragSize.y)\n"
504 " col0.w = (fragSize.y << 26) | (fragSize.x << 20) | (implicitDerivY << 14) | (implicitDerivX << 8) | " << ERROR_FRAGCOORD_IMPLICIT_DERIV << ";\n";
506 // Y component gets sample mask value
507 if (m_data.useSampleMaskIn)
508 fss << " col0.y = gl_SampleMaskIn[0];\n";
510 if (m_data.fragDepth)
511 fss << " gl_FragDepth = float(instanceIndex) / float(" << NUM_TRIANGLES << ");\n";
513 if (m_data.fragStencil)
514 fss << " gl_FragStencilRefARB = instanceIndex;\n";
516 if (m_data.interlock)
517 fss << " endInvocationInterlockARB();\n";
522 programCollection.glslSources.add("frag") << glu::FragmentSource(fss.str());
524 std::stringstream css;
526 std::string fsampType = m_data.samples > 1 ? "texture2DMSArray" : "texture2DArray";
527 std::string usampType = m_data.samples > 1 ? "utexture2DMSArray" : "utexture2DArray";
529 // Compute shader copies color/depth/stencil to linear layout in buffer memory
531 "#version 450 core\n"
532 "#extension GL_EXT_samplerless_texture_functions : enable\n"
533 "layout(set = 0, binding = 1) uniform " << usampType << " colorTex;\n"
534 "layout(set = 0, binding = 2, std430) buffer Block0 { uvec4 b[]; } colorbuf;\n"
535 "layout(set = 0, binding = 4, std430) buffer Block1 { float b[]; } depthbuf;\n"
536 "layout(set = 0, binding = 5, std430) buffer Block2 { uint b[]; } stencilbuf;\n"
537 "layout(set = 0, binding = 6) uniform " << fsampType << " depthTex;\n"
538 "layout(set = 0, binding = 7) uniform " << usampType << " stencilTex;\n"
539 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
542 " for (int i = 0; i < " << m_data.samples << "; ++i) {\n"
543 " uint idx = ((gl_GlobalInvocationID.z * " << m_data.framebufferDim.height << " + gl_GlobalInvocationID.y) * " << m_data.framebufferDim.width << " + gl_GlobalInvocationID.x) * " << m_data.samples << " + i;\n"
544 " colorbuf.b[idx] = texelFetch(colorTex, ivec3(gl_GlobalInvocationID.xyz), i);\n";
546 if (m_data.fragDepth)
547 css << " depthbuf.b[idx] = texelFetch(depthTex, ivec3(gl_GlobalInvocationID.xyz), i).x;\n";
549 if (m_data.fragStencil)
550 css << " stencilbuf.b[idx] = texelFetch(stencilTex, ivec3(gl_GlobalInvocationID.xyz), i).x;\n";
556 programCollection.glslSources.add("comp") << glu::ComputeSource(css.str());
559 TestInstance* FSRTestCase::createInstance (Context& context) const
561 return new FSRTestInstance(context, m_data);
564 deInt32 FSRTestInstance::ShadingRateExtentToEnum(VkExtent2D ext) const
566 ext.width = deCtz32(ext.width);
567 ext.height = deCtz32(ext.height);
569 return (ext.width << 2) | ext.height;
572 VkExtent2D FSRTestInstance::ShadingRateEnumToExtent(deInt32 rate) const
575 ret.width = 1 << ((rate/4) & 3);
576 ret.height = 1 << (rate & 3);
581 VkExtent2D FSRTestInstance::Combine(VkExtent2D ext0, VkExtent2D ext1, VkFragmentShadingRateCombinerOpKHR comb) const
589 case VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR:
591 case VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR:
593 case VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MIN_KHR:
594 ret = { de::min(ext0.width, ext1.width), de::min(ext0.height, ext1.height) };
596 case VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_KHR:
597 ret = { de::max(ext0.width, ext1.width), de::max(ext0.height, ext1.height) };
599 case VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_KHR:
600 ret = { ext0.width * ext1.width, ext0.height * ext1.height };
601 if (!m_shadingRateProperties.fragmentShadingRateStrictMultiplyCombiner)
603 if (ext0.width == 1 && ext1.width == 1)
605 if (ext0.height == 1 && ext1.height == 1)
612 deInt32 FSRTestInstance::Simulate(deInt32 rate0, deInt32 rate1, deInt32 rate2)
614 deInt32 &cachedRate = m_simulateCache[(rate2*m_simulateValueCount + rate1)*m_simulateValueCount + rate0];
615 if (cachedRate != ~0)
618 VkExtent2D extent0 = ShadingRateEnumToExtent(rate0);
619 VkExtent2D extent1 = ShadingRateEnumToExtent(rate1);
620 VkExtent2D extent2 = ShadingRateEnumToExtent(rate2);
622 deInt32 finalMask = 0;
623 // Simulate once for implementations that don't allow swapping rate xy,
624 // and once for those that do. Any of those results is allowed.
625 for (deUint32 allowSwap = 0; allowSwap <= 1; ++allowSwap)
627 // Combine rate 0 and 1, get a mask of possible clamped rates
628 VkExtent2D intermed = Combine(extent0, extent1, m_data.combinerOp[0]);
629 deInt32 intermedMask = ShadingRateExtentToClampedMask(intermed, allowSwap == 1);
631 // For each clamped rate, combine that with rate 2 and accumulate the possible clamped rates
632 for (int i = 0; i < 16; ++i)
634 if (intermedMask & (1<<i))
636 VkExtent2D final = Combine(ShadingRateEnumToExtent(i), extent2, m_data.combinerOp[1]);
637 finalMask |= ShadingRateExtentToClampedMask(final, allowSwap == 1);
641 // unclamped intermediate value is also permitted
642 VkExtent2D final = Combine(intermed, extent2, m_data.combinerOp[1]);
643 finalMask |= ShadingRateExtentToClampedMask(final, allowSwap == 1);
650 cachedRate = finalMask;
654 // If a rate is not valid (<=4x4), clamp it to something valid.
655 // This is only used for "inputs" to the system, not to mimic
656 // how the implementation internally clamps intermediate values.
657 VkExtent2D FSRTestInstance::SanitizeExtent(VkExtent2D ext) const
659 DE_ASSERT(ext.width > 0 && ext.height > 0);
661 ext.width = de::min(ext.width, 4u);
662 ext.height = de::min(ext.height, 4u);
667 // Map an extent to a mask of all modes smaller than or equal to it in either dimension
668 deInt32 FSRTestInstance::ShadingRateExtentToClampedMask(VkExtent2D ext, bool allowSwap) const
670 deUint32 desiredSize = ext.width * ext.height;
674 while (desiredSize > 0)
676 // First, find modes that maximize the area
677 for (deUint32 i = 0; i < m_supportedFragmentShadingRateCount; ++i)
679 const VkPhysicalDeviceFragmentShadingRateKHR &supportedRate = m_supportedFragmentShadingRates[i];
680 if ((supportedRate.sampleCounts & m_data.samples) &&
681 supportedRate.fragmentSize.width * supportedRate.fragmentSize.height == desiredSize &&
682 ((supportedRate.fragmentSize.width <= ext.width && supportedRate.fragmentSize.height <= ext.height) ||
683 (supportedRate.fragmentSize.height <= ext.width && supportedRate.fragmentSize.width <= ext.height && allowSwap)))
685 mask |= 1 << ShadingRateExtentToEnum(supportedRate.fragmentSize);
690 // Amongst the modes that maximize the area, pick the ones that
691 // minimize the aspect ratio. Prefer ratio of 1, then 2, then 4.
692 // 1x1 = 0, 2x2 = 5, 4x4 = 10
693 static const deUint32 aspectMaskRatio1 = 0x421;
694 // 2x1 = 4, 1x2 = 1, 4x2 = 9, 2x4 = 6
695 static const deUint32 aspectMaskRatio2 = 0x252;
697 static const deUint32 aspectMaskRatio4 = 0x104;
699 if (mask & aspectMaskRatio1)
701 mask &= aspectMaskRatio1;
704 if (mask & aspectMaskRatio2)
706 mask &= aspectMaskRatio2;
709 if (mask & aspectMaskRatio4)
711 mask &= aspectMaskRatio4;
723 deInt32 FSRTestInstance::SanitizeRate(deInt32 rate) const
725 VkExtent2D extent = ShadingRateEnumToExtent(rate);
727 extent = SanitizeExtent(extent);
729 return ShadingRateExtentToEnum(extent);
732 // Map primID % 9 to primitive shading rate
733 deInt32 FSRTestInstance::PrimIDToPrimitiveShadingRate(deInt32 primID)
735 deInt32 &cachedRate = m_primIDToPrimitiveShadingRate[primID];
736 if (cachedRate != ~0)
740 extent.width = 1 << (primID % 3);
741 extent.height = 1 << ((primID/3) % 3);
743 cachedRate = ShadingRateExtentToEnum(extent);
747 // Map primID / 9 to pipeline shading rate
748 deInt32 FSRTestInstance::PrimIDToPipelineShadingRate(deInt32 primID)
750 deInt32 &cachedRate = m_primIDToPipelineShadingRate[primID];
751 if (cachedRate != ~0)
756 extent.width = 1 << (primID % 3);
757 extent.height = 1 << ((primID/3) % 3);
759 cachedRate = ShadingRateExtentToEnum(extent);
763 static de::MovePtr<BufferWithMemory> CreateCachedBuffer(const vk::DeviceInterface& vk,
764 const vk::VkDevice device,
765 vk::Allocator& allocator,
766 const vk::VkBufferCreateInfo& bufferCreateInfo)
770 return de::MovePtr<BufferWithMemory>(new BufferWithMemory(
771 vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Cached));
773 catch (const tcu::NotSupportedError&)
775 return de::MovePtr<BufferWithMemory>(new BufferWithMemory(
776 vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible));
780 tcu::TestStatus FSRTestInstance::iterate (void)
782 const DeviceInterface& vk = m_context.getDeviceInterface();
783 const VkDevice device = m_context.getDevice();
784 tcu::TestLog& log = m_context.getTestContext().getLog();
785 Allocator& allocator = m_context.getDefaultAllocator();
786 VkFlags allShaderStages = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT;
787 VkFlags allPipelineStages = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
788 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
789 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
790 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
791 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
792 VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT |
793 VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV;
794 const VkFormat cbFormat = VK_FORMAT_R32G32B32A32_UINT;
795 const VkFormat dsFormat = VK_FORMAT_D32_SFLOAT_S8_UINT;
797 if (m_data.geometryShader)
799 allShaderStages |= VK_SHADER_STAGE_GEOMETRY_BIT;
800 allPipelineStages |= VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
804 deRandom_init(&rnd, m_data.seed);
806 qpTestResult res = QP_TEST_RESULT_PASS;
807 deUint32 numUnexpected1x1Samples = 0;
808 deUint32 numTotalSamples = 0;
812 ATTACHMENT_MODE_DEFAULT = 0,
813 ATTACHMENT_MODE_LAYOUT_OPTIMAL,
814 ATTACHMENT_MODE_IMAGELESS,
815 ATTACHMENT_MODE_2DARRAY,
816 ATTACHMENT_MODE_TILING_LINEAR,
818 ATTACHMENT_MODE_COUNT,
821 deUint32 numSRLayers = m_data.srLayered ? 2u : 1u;
823 VkExtent2D minFragmentShadingRateAttachmentTexelSize = {1, 1};
824 VkExtent2D maxFragmentShadingRateAttachmentTexelSize = {1, 1};
825 deUint32 maxFragmentShadingRateAttachmentTexelSizeAspectRatio = 1;
826 if (m_context.getFragmentShadingRateFeatures().attachmentFragmentShadingRate)
828 minFragmentShadingRateAttachmentTexelSize = m_context.getFragmentShadingRateProperties().minFragmentShadingRateAttachmentTexelSize;
829 maxFragmentShadingRateAttachmentTexelSize = m_context.getFragmentShadingRateProperties().maxFragmentShadingRateAttachmentTexelSize;
830 maxFragmentShadingRateAttachmentTexelSizeAspectRatio = m_context.getFragmentShadingRateProperties().maxFragmentShadingRateAttachmentTexelSizeAspectRatio;
833 VkDeviceSize atomicBufferSize = sizeof(deUint32);
835 de::MovePtr<BufferWithMemory> atomicBuffer;
836 atomicBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
837 vk, device, allocator, makeBufferCreateInfo(atomicBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible | MemoryRequirement::Coherent));
839 deUint32 *abuf = (deUint32 *)atomicBuffer->getAllocation().getHostPtr();
841 // NUM_TRIANGLES triangles, 3 vertices, 2 components of float position
842 VkDeviceSize vertexBufferSize = NUM_TRIANGLES * 3 * 2 * sizeof(float);
844 de::MovePtr<BufferWithMemory> vertexBuffer;
845 vertexBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
846 vk, device, allocator, makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible | MemoryRequirement::Coherent));
848 float *vbuf = (float *)vertexBuffer->getAllocation().getHostPtr();
849 for (deInt32 i = 0; i < (deInt32)(vertexBufferSize / sizeof(float)); ++i)
851 vbuf[i] = deRandom_getFloat(&rnd)*2.0f - 1.0f;
853 flushAlloc(vk, device, vertexBuffer->getAllocation());
855 VkDeviceSize colorOutputBufferSize = m_data.framebufferDim.width * m_data.framebufferDim.height * m_data.samples * 4 * sizeof(deUint32) * m_data.numColorLayers;
856 de::MovePtr<BufferWithMemory> colorOutputBuffer = CreateCachedBuffer(vk, device, allocator, makeBufferCreateInfo(colorOutputBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT));
858 VkDeviceSize depthOutputBufferSize = 0, stencilOutputBufferSize = 0;
859 de::MovePtr<BufferWithMemory> depthOutputBuffer, stencilOutputBuffer;
860 if (m_data.useDepthStencil)
862 depthOutputBufferSize = m_data.framebufferDim.width * m_data.framebufferDim.height * m_data.samples * sizeof(float) * m_data.numColorLayers;
863 depthOutputBuffer = CreateCachedBuffer(vk, device, allocator, makeBufferCreateInfo(depthOutputBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT));
865 stencilOutputBufferSize = m_data.framebufferDim.width * m_data.framebufferDim.height * m_data.samples * sizeof(deUint32) * m_data.numColorLayers;
866 stencilOutputBuffer = CreateCachedBuffer(vk, device, allocator, makeBufferCreateInfo(stencilOutputBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT));
869 deUint32 minSRTexelWidth = minFragmentShadingRateAttachmentTexelSize.width;
870 deUint32 minSRTexelHeight = minFragmentShadingRateAttachmentTexelSize.height;
871 deUint32 maxSRWidth = (m_data.framebufferDim.width + minSRTexelWidth - 1) / minSRTexelWidth;
872 deUint32 maxSRHeight = (m_data.framebufferDim.height + minSRTexelHeight - 1) / minSRTexelHeight;
874 // max size over all formats
875 VkDeviceSize srFillBufferSize = numSRLayers * maxSRWidth * maxSRHeight * 32/*4 component 64-bit*/;
876 de::MovePtr<BufferWithMemory> srFillBuffer;
877 deUint8 *fillPtr = DE_NULL;
878 if (m_data.useAttachment())
880 srFillBuffer = CreateCachedBuffer(vk, device, allocator, makeBufferCreateInfo(srFillBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT));
881 fillPtr = (deUint8 *)srFillBuffer->getAllocation().getHostPtr();
884 de::MovePtr<ImageWithMemory> cbImage;
885 Move<VkImageView> cbImageView;
887 const VkImageCreateInfo imageCreateInfo =
889 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
890 DE_NULL, // const void* pNext;
891 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
892 VK_IMAGE_TYPE_2D, // VkImageType imageType;
893 cbFormat, // VkFormat format;
895 m_data.framebufferDim.width, // deUint32 width;
896 m_data.framebufferDim.height, // deUint32 height;
897 1u // deUint32 depth;
898 }, // VkExtent3D extent;
899 1u, // deUint32 mipLevels;
900 m_data.numColorLayers, // deUint32 arrayLayers;
901 m_data.samples, // VkSampleCountFlagBits samples;
902 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
903 cbUsage, // VkImageUsageFlags usage;
904 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
905 0u, // deUint32 queueFamilyIndexCount;
906 DE_NULL, // const deUint32* pQueueFamilyIndices;
907 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
909 cbImage = de::MovePtr<ImageWithMemory>(new ImageWithMemory(
910 vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
912 VkImageViewCreateInfo imageViewCreateInfo =
914 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
915 DE_NULL, // const void* pNext;
916 (VkImageViewCreateFlags)0u, // VkImageViewCreateFlags flags;
917 **cbImage, // VkImage image;
918 VK_IMAGE_VIEW_TYPE_2D_ARRAY, // VkImageViewType viewType;
919 cbFormat, // VkFormat format;
921 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
922 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
923 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
924 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
925 }, // VkComponentMapping components;
927 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
928 0u, // deUint32 baseMipLevel;
929 1u, // deUint32 levelCount;
930 0u, // deUint32 baseArrayLayer;
931 m_data.numColorLayers // deUint32 layerCount;
932 } // VkImageSubresourceRange subresourceRange;
934 cbImageView = createImageView(vk, device, &imageViewCreateInfo, NULL);
937 de::MovePtr<ImageWithMemory> dsImage;
938 Move<VkImageView> dsImageView, dImageView, sImageView;
939 VkImageUsageFlags dsUsage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
940 VK_IMAGE_USAGE_SAMPLED_BIT |
941 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
942 VK_IMAGE_USAGE_TRANSFER_DST_BIT;
943 if (m_data.useDepthStencil)
945 const VkImageCreateInfo imageCreateInfo =
947 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
948 DE_NULL, // const void* pNext;
949 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
950 VK_IMAGE_TYPE_2D, // VkImageType imageType;
951 dsFormat, // VkFormat format;
953 m_data.framebufferDim.width, // deUint32 width;
954 m_data.framebufferDim.height, // deUint32 height;
955 1u // deUint32 depth;
956 }, // VkExtent3D extent;
957 1u, // deUint32 mipLevels;
958 m_data.numColorLayers, // deUint32 arrayLayers;
959 m_data.samples, // VkSampleCountFlagBits samples;
960 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
961 dsUsage, // VkImageUsageFlags usage;
962 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
963 0u, // deUint32 queueFamilyIndexCount;
964 DE_NULL, // const deUint32* pQueueFamilyIndices;
965 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
967 dsImage = de::MovePtr<ImageWithMemory>(new ImageWithMemory(
968 vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
970 VkImageViewCreateInfo imageViewCreateInfo =
972 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
973 DE_NULL, // const void* pNext;
974 (VkImageViewCreateFlags)0u, // VkImageViewCreateFlags flags;
975 **dsImage, // VkImage image;
976 VK_IMAGE_VIEW_TYPE_2D_ARRAY, // VkImageViewType viewType;
977 dsFormat, // VkFormat format;
979 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
980 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
981 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
982 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
983 }, // VkComponentMapping components;
985 VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags aspectMask;
986 0u, // deUint32 baseMipLevel;
987 1u, // deUint32 levelCount;
988 0u, // deUint32 baseArrayLayer;
989 m_data.numColorLayers // deUint32 layerCount;
990 } // VkImageSubresourceRange subresourceRange;
992 dsImageView = createImageView(vk, device, &imageViewCreateInfo, NULL);
993 imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
994 dImageView = createImageView(vk, device, &imageViewCreateInfo, NULL);
995 imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
996 sImageView = createImageView(vk, device, &imageViewCreateInfo, NULL);
999 // Image used to test implicit derivative calculations.
1000 // Filled with a value of 1<<lod.
1001 de::MovePtr<ImageWithMemory> derivImage;
1002 Move<VkImageView> derivImageView;
1003 VkImageUsageFlags derivUsage = VK_IMAGE_USAGE_SAMPLED_BIT |
1004 VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1005 deUint32 derivNumLevels;
1007 deUint32 maxDim = de::max(m_context.getFragmentShadingRateProperties().maxFragmentSize.width, m_context.getFragmentShadingRateProperties().maxFragmentSize.height);
1008 derivNumLevels = 1 + deCtz32(maxDim);
1009 const VkImageCreateInfo imageCreateInfo =
1011 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1012 DE_NULL, // const void* pNext;
1013 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
1014 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1015 VK_FORMAT_R32_UINT, // VkFormat format;
1017 m_context.getFragmentShadingRateProperties().maxFragmentSize.width, // deUint32 width;
1018 m_context.getFragmentShadingRateProperties().maxFragmentSize.height, // deUint32 height;
1019 1u // deUint32 depth;
1020 }, // VkExtent3D extent;
1021 derivNumLevels, // deUint32 mipLevels;
1022 1u, // deUint32 arrayLayers;
1023 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
1024 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1025 derivUsage, // VkImageUsageFlags usage;
1026 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1027 0u, // deUint32 queueFamilyIndexCount;
1028 DE_NULL, // const deUint32* pQueueFamilyIndices;
1029 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
1031 derivImage = de::MovePtr<ImageWithMemory>(new ImageWithMemory(
1032 vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
1034 VkImageViewCreateInfo imageViewCreateInfo =
1036 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1037 DE_NULL, // const void* pNext;
1038 (VkImageViewCreateFlags)0u, // VkImageViewCreateFlags flags;
1039 **derivImage, // VkImage image;
1040 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
1041 VK_FORMAT_R32_UINT, // VkFormat format;
1043 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
1044 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
1045 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
1046 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
1047 }, // VkComponentMapping components;
1049 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1050 0u, // deUint32 baseMipLevel;
1051 derivNumLevels, // deUint32 levelCount;
1052 0u, // deUint32 baseArrayLayer;
1053 1u // deUint32 layerCount;
1054 } // VkImageSubresourceRange subresourceRange;
1056 derivImageView = createImageView(vk, device, &imageViewCreateInfo, NULL);
1059 // sampler used with derivImage
1060 const struct VkSamplerCreateInfo samplerInfo =
1062 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // sType
1065 VK_FILTER_NEAREST, // magFilter
1066 VK_FILTER_NEAREST, // minFilter
1067 VK_SAMPLER_MIPMAP_MODE_NEAREST, // mipmapMode
1068 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeU
1069 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeV
1070 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeW
1072 VK_FALSE, // anisotropyEnable
1073 1.0f, // maxAnisotropy
1074 DE_FALSE, // compareEnable
1075 VK_COMPARE_OP_ALWAYS, // compareOp
1077 (float)derivNumLevels, // maxLod
1078 VK_BORDER_COLOR_INT_TRANSPARENT_BLACK, // borderColor
1079 VK_FALSE, // unnormalizedCoords
1082 Move<VkSampler> sampler = createSampler(vk, device, &samplerInfo);
1084 Move<vk::VkDescriptorSetLayout> descriptorSetLayout;
1085 VkDescriptorSetLayoutCreateFlags layoutCreateFlags = 0;
1087 const VkDescriptorSetLayoutBinding bindings[] =
1091 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // descriptorType
1092 1u, // descriptorCount
1093 allShaderStages, // stageFlags
1094 DE_NULL, // pImmutableSamplers
1098 VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, // descriptorType
1099 1u, // descriptorCount
1100 allShaderStages, // stageFlags
1101 DE_NULL, // pImmutableSamplers
1105 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // descriptorType
1106 1u, // descriptorCount
1107 allShaderStages, // stageFlags
1108 DE_NULL, // pImmutableSamplers
1112 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, // descriptorType
1113 1u, // descriptorCount
1114 allShaderStages, // stageFlags
1115 DE_NULL, // pImmutableSamplers
1119 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // descriptorType
1120 1u, // descriptorCount
1121 allShaderStages, // stageFlags
1122 DE_NULL, // pImmutableSamplers
1126 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // descriptorType
1127 1u, // descriptorCount
1128 allShaderStages, // stageFlags
1129 DE_NULL, // pImmutableSamplers
1133 VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, // descriptorType
1134 1u, // descriptorCount
1135 allShaderStages, // stageFlags
1136 DE_NULL, // pImmutableSamplers
1140 VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, // descriptorType
1141 1u, // descriptorCount
1142 allShaderStages, // stageFlags
1143 DE_NULL, // pImmutableSamplers
1147 // Create a layout and allocate a descriptor set for it.
1148 const VkDescriptorSetLayoutCreateInfo setLayoutCreateInfo =
1150 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // sType
1152 layoutCreateFlags, // flags
1153 sizeof(bindings)/sizeof(bindings[0]), // bindingCount
1154 &bindings[0] // pBindings
1157 descriptorSetLayout = vk::createDescriptorSetLayout(vk, device, &setLayoutCreateInfo);
1159 const VkPushConstantRange pushConstantRange =
1161 allShaderStages, // VkShaderStageFlags stageFlags;
1162 0u, // deUint32 offset;
1163 sizeof(deInt32) // deUint32 size;
1166 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
1168 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType
1170 (VkPipelineLayoutCreateFlags)0,
1171 1, // setLayoutCount
1172 &descriptorSetLayout.get(), // pSetLayouts
1173 1u, // pushConstantRangeCount
1174 &pushConstantRange, // pPushConstantRanges
1177 Move<VkPipelineLayout> pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo, NULL);
1179 const Unique<VkShaderModule> cs (createShaderModule(vk, device, m_context.getBinaryCollection().get("comp"), 0));
1181 const VkPipelineShaderStageCreateInfo csShaderCreateInfo =
1183 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1185 (VkPipelineShaderStageCreateFlags)0,
1186 VK_SHADER_STAGE_COMPUTE_BIT, // stage
1189 DE_NULL, // pSpecializationInfo
1192 const VkComputePipelineCreateInfo pipelineCreateInfo =
1194 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
1197 csShaderCreateInfo, // cs
1198 *pipelineLayout, // layout
1199 (vk::VkPipeline)0, // basePipelineHandle
1200 0u, // basePipelineIndex
1202 Move<VkPipeline> computePipeline = createComputePipeline(vk, device, DE_NULL, &pipelineCreateInfo, NULL);
1204 for (deUint32 modeIdx = 0; modeIdx < ATTACHMENT_MODE_COUNT; ++modeIdx)
1206 // If we're not using an attachment, don't test all the different attachment modes
1207 if (modeIdx != ATTACHMENT_MODE_DEFAULT && !m_data.useAttachment())
1210 // Consider all uint formats possible
1211 static const VkFormat srFillFormats[] =
1214 VK_FORMAT_R8G8_UINT,
1215 VK_FORMAT_R8G8B8_UINT,
1216 VK_FORMAT_R8G8B8A8_UINT,
1218 VK_FORMAT_R16G16_UINT,
1219 VK_FORMAT_R16G16B16_UINT,
1220 VK_FORMAT_R16G16B16A16_UINT,
1222 VK_FORMAT_R32G32_UINT,
1223 VK_FORMAT_R32G32B32_UINT,
1224 VK_FORMAT_R32G32B32A32_UINT,
1226 VK_FORMAT_R64G64_UINT,
1227 VK_FORMAT_R64G64B64_UINT,
1228 VK_FORMAT_R64G64B64A64_UINT,
1230 // Only test all formats in the default mode
1231 deUint32 numFillFormats = modeIdx == ATTACHMENT_MODE_DEFAULT ? (deUint32)(sizeof(srFillFormats)/sizeof(srFillFormats[0])) : 1u;
1233 // Iterate over all supported tile sizes and formats
1234 for (deUint32 srTexelWidth = minFragmentShadingRateAttachmentTexelSize.width;
1235 srTexelWidth <= maxFragmentShadingRateAttachmentTexelSize.width;
1237 for (deUint32 srTexelHeight = minFragmentShadingRateAttachmentTexelSize.height;
1238 srTexelHeight <= maxFragmentShadingRateAttachmentTexelSize.height;
1240 for (deUint32 formatIdx = 0; formatIdx < numFillFormats; ++formatIdx)
1243 deUint32 aspectRatio = (srTexelHeight > srTexelWidth) ? (srTexelHeight / srTexelWidth) : (srTexelWidth / srTexelHeight);
1244 if (aspectRatio > maxFragmentShadingRateAttachmentTexelSizeAspectRatio)
1247 // Go through the loop only once when not using an attachment
1248 if (!m_data.useAttachment() &&
1249 (srTexelWidth != minFragmentShadingRateAttachmentTexelSize.width ||
1250 srTexelHeight != minFragmentShadingRateAttachmentTexelSize.height ||
1254 bool imagelessFB = modeIdx == ATTACHMENT_MODE_IMAGELESS;
1256 deUint32 srWidth = (m_data.framebufferDim.width + srTexelWidth - 1) / srTexelWidth;
1257 deUint32 srHeight = (m_data.framebufferDim.height + srTexelHeight - 1) / srTexelHeight;
1259 VkFormat srFormat = srFillFormats[formatIdx];
1260 deUint32 srFillBpp = tcu::getPixelSize(mapVkFormat(srFormat));
1262 VkImageLayout srLayout = modeIdx == ATTACHMENT_MODE_LAYOUT_OPTIMAL ? VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR : VK_IMAGE_LAYOUT_GENERAL;
1263 VkImageViewType srViewType = modeIdx == ATTACHMENT_MODE_2DARRAY ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D;
1264 VkImageTiling srTiling = (modeIdx == ATTACHMENT_MODE_TILING_LINEAR) ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL;
1266 VkFormatProperties srFormatProperties;
1267 m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), srFormat, &srFormatProperties);
1268 VkFormatFeatureFlags srFormatFeatures = srTiling == VK_IMAGE_TILING_LINEAR ? srFormatProperties.linearTilingFeatures : srFormatProperties.optimalTilingFeatures;
1270 if (m_context.getFragmentShadingRateFeatures().attachmentFragmentShadingRate &&
1271 !(srFormatFeatures & VK_FORMAT_FEATURE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR))
1273 if (srFormat == VK_FORMAT_R8_UINT && srTiling == VK_IMAGE_TILING_OPTIMAL)
1275 log << tcu::TestLog::Message << "VK_FORMAT_R8_UINT/VK_IMAGE_TILING_OPTIMAL don't support VK_FORMAT_FEATURE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR" << tcu::TestLog::EndMessage;
1276 res = QP_TEST_RESULT_FAIL;
1281 Move<vk::VkDescriptorPool> descriptorPool;
1282 Move<vk::VkDescriptorSet> descriptorSet;
1283 VkDescriptorPoolCreateFlags poolCreateFlags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
1285 vk::DescriptorPoolBuilder poolBuilder;
1286 for (deInt32 i = 0; i < (deInt32)(sizeof(bindings)/sizeof(bindings[0])); ++i)
1287 poolBuilder.addType(bindings[i].descriptorType, bindings[i].descriptorCount);
1289 descriptorPool = poolBuilder.build(vk, device, poolCreateFlags, 1u);
1290 descriptorSet = makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout);
1292 de::MovePtr<ImageWithMemory> srImage;
1293 Move<VkImageView> srImageView;
1294 VkImageUsageFlags srUsage = VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR |
1295 VK_IMAGE_USAGE_TRANSFER_DST_BIT |
1296 VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1298 if (m_data.useAttachment())
1300 const VkImageCreateInfo imageCreateInfo =
1302 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1303 DE_NULL, // const void* pNext;
1304 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
1305 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1306 srFormat, // VkFormat format;
1308 srWidth, // deUint32 width;
1309 srHeight, // deUint32 height;
1310 1u // deUint32 depth;
1311 }, // VkExtent3D extent;
1312 1u, // deUint32 mipLevels;
1313 numSRLayers, // deUint32 arrayLayers;
1314 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
1315 srTiling, // VkImageTiling tiling;
1316 srUsage, // VkImageUsageFlags usage;
1317 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1318 0u, // deUint32 queueFamilyIndexCount;
1319 DE_NULL, // const deUint32* pQueueFamilyIndices;
1320 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
1322 srImage = de::MovePtr<ImageWithMemory>(new ImageWithMemory(
1323 vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
1325 VkImageViewCreateInfo imageViewCreateInfo =
1327 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1328 DE_NULL, // const void* pNext;
1329 (VkImageViewCreateFlags)0u, // VkImageViewCreateFlags flags;
1330 **srImage, // VkImage image;
1331 srViewType, // VkImageViewType viewType;
1332 srFormat, // VkFormat format;
1334 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
1335 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
1336 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
1337 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
1338 }, // VkComponentMapping components;
1340 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1341 0u, // deUint32 baseMipLevel;
1342 1u, // deUint32 levelCount;
1343 0u, // deUint32 baseArrayLayer;
1344 srViewType == VK_IMAGE_VIEW_TYPE_2D ?
1345 1 : numSRLayers, // deUint32 layerCount;
1346 } // VkImageSubresourceRange subresourceRange;
1348 srImageView = createImageView(vk, device, &imageViewCreateInfo, NULL);
1351 VkDescriptorImageInfo imageInfo;
1352 VkDescriptorBufferInfo bufferInfo;
1354 VkWriteDescriptorSet w =
1356 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
1358 *descriptorSet, // dstSet
1359 (deUint32)0, // dstBinding
1360 0, // dstArrayElement
1361 1u, // descriptorCount
1362 bindings[0].descriptorType, // descriptorType
1363 &imageInfo, // pImageInfo
1364 &bufferInfo, // pBufferInfo
1365 DE_NULL, // pTexelBufferView
1369 flushAlloc(vk, device, atomicBuffer->getAllocation());
1371 bufferInfo = makeDescriptorBufferInfo(**atomicBuffer, 0, atomicBufferSize);
1373 w.descriptorType = bindings[0].descriptorType;
1374 vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1376 imageInfo = makeDescriptorImageInfo(DE_NULL, *cbImageView, VK_IMAGE_LAYOUT_GENERAL);
1378 w.descriptorType = bindings[1].descriptorType;
1379 vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1381 bufferInfo = makeDescriptorBufferInfo(**colorOutputBuffer, 0, colorOutputBufferSize);
1383 w.descriptorType = bindings[2].descriptorType;
1384 vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1386 imageInfo = makeDescriptorImageInfo(*sampler, *derivImageView, VK_IMAGE_LAYOUT_GENERAL);
1388 w.descriptorType = bindings[3].descriptorType;
1389 vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1391 if (m_data.useDepthStencil)
1393 bufferInfo = makeDescriptorBufferInfo(**depthOutputBuffer, 0, depthOutputBufferSize);
1395 w.descriptorType = bindings[4].descriptorType;
1396 vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1398 bufferInfo = makeDescriptorBufferInfo(**stencilOutputBuffer, 0, stencilOutputBufferSize);
1400 w.descriptorType = bindings[5].descriptorType;
1401 vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1403 imageInfo = makeDescriptorImageInfo(DE_NULL, *dImageView, VK_IMAGE_LAYOUT_GENERAL);
1405 w.descriptorType = bindings[6].descriptorType;
1406 vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1408 imageInfo = makeDescriptorImageInfo(DE_NULL, *sImageView, VK_IMAGE_LAYOUT_GENERAL);
1410 w.descriptorType = bindings[7].descriptorType;
1411 vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1414 Move<VkRenderPass> renderPass;
1415 Move<VkFramebuffer> framebuffer;
1417 std::vector<VkImageView> attachments;
1418 attachments.push_back(*cbImageView);
1419 deUint32 dsAttachmentIdx = 0, srAttachmentIdx = 0;
1420 if (m_data.useAttachment())
1422 srAttachmentIdx = (deUint32)attachments.size();
1423 attachments.push_back(*srImageView);
1425 if (m_data.useDepthStencil)
1427 dsAttachmentIdx = (deUint32)attachments.size();
1428 attachments.push_back(*dsImageView);
1431 if (!m_data.useDynamicRendering)
1433 const vk::VkAttachmentReference2 colorAttachmentReference
1435 VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, // sType
1438 vk::VK_IMAGE_LAYOUT_GENERAL, // layout
1442 const vk::VkAttachmentReference2 fragmentShadingRateAttachment =
1444 VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, // sType
1446 srAttachmentIdx, // attachment
1451 const vk::VkAttachmentReference2 depthAttachmentReference =
1453 VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, // sType
1455 dsAttachmentIdx, // attachment
1456 vk::VK_IMAGE_LAYOUT_GENERAL, // layout
1460 const bool noAttachmentPtr = (m_data.attachmentUsage == AttachmentUsage::NO_ATTACHMENT_PTR);
1461 const VkFragmentShadingRateAttachmentInfoKHR shadingRateAttachmentInfo =
1463 VK_STRUCTURE_TYPE_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR, // VkStructureType sType;
1464 DE_NULL, // const void* pNext;
1465 (noAttachmentPtr ? nullptr : &fragmentShadingRateAttachment), // const VkAttachmentReference2* pFragmentShadingRateAttachment;
1466 { srTexelWidth, srTexelHeight }, // VkExtent2D shadingRateAttachmentTexelSize;
1469 const bool useAttachmentInfo = (m_data.attachmentUsage != AttachmentUsage::NO_ATTACHMENT);
1470 const VkSubpassDescription2 subpassDesc =
1472 VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2, // sType
1473 (useAttachmentInfo ? &shadingRateAttachmentInfo : nullptr), // pNext;
1474 (vk::VkSubpassDescriptionFlags)0, // flags
1475 vk::VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
1476 m_data.multiView ? 0x3 : 0u, // viewMask
1478 DE_NULL, // pInputAttachments
1480 &colorAttachmentReference, // pColorAttachments
1481 DE_NULL, // pResolveAttachments
1482 m_data.useDepthStencil ? &depthAttachmentReference : DE_NULL, // depthStencilAttachment
1483 0u, // preserveCount
1484 DE_NULL, // pPreserveAttachments
1487 std::vector<VkAttachmentDescription2> attachmentDescriptions
1490 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, // VkStructureType sType;
1491 DE_NULL, // const void* pNext;
1492 (VkAttachmentDescriptionFlags)0u, // VkAttachmentDescriptionFlags flags;
1493 cbFormat, // VkFormat format;
1494 m_data.samples, // VkSampleCountFlagBits samples;
1495 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
1496 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
1497 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
1498 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
1499 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout initialLayout;
1500 VK_IMAGE_LAYOUT_GENERAL // VkImageLayout finalLayout;
1503 if (m_data.useAttachment())
1504 attachmentDescriptions.push_back(
1506 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, // VkStructureType sType;
1507 DE_NULL, // const void* pNext;
1508 (VkAttachmentDescriptionFlags)0u, // VkAttachmentDescriptionFlags flags;
1509 srFormat, // VkFormat format;
1510 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
1511 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
1512 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
1513 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
1514 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
1515 srLayout, // VkImageLayout initialLayout;
1516 srLayout // VkImageLayout finalLayout;
1520 if (m_data.useDepthStencil)
1521 attachmentDescriptions.push_back(
1523 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, // VkStructureType sType;
1524 DE_NULL, // const void* pNext;
1525 (VkAttachmentDescriptionFlags)0u, // VkAttachmentDescriptionFlags flags;
1526 dsFormat, // VkFormat format;
1527 m_data.samples, // VkSampleCountFlagBits samples;
1528 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
1529 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
1530 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp stencilLoadOp;
1531 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp;
1532 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout initialLayout;
1533 VK_IMAGE_LAYOUT_GENERAL // VkImageLayout finalLayout;
1537 const deUint32 correlatedViewMask = 0x3;
1538 const VkRenderPassCreateInfo2 renderPassParams =
1540 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2, // sType
1542 (vk::VkRenderPassCreateFlags)0,
1543 (deUint32)attachmentDescriptions.size(), // attachmentCount
1544 &attachmentDescriptions[0], // pAttachments
1546 &subpassDesc, // pSubpasses
1547 0u, // dependencyCount
1548 DE_NULL, // pDependencies
1549 m_data.correlationMask, // correlatedViewMaskCount
1550 m_data.correlationMask ? &correlatedViewMask : DE_NULL // pCorrelatedViewMasks
1553 renderPass = createRenderPass2(vk, device, &renderPassParams);
1555 std::vector<VkFramebufferAttachmentImageInfo> framebufferAttachmentImageInfo;
1556 framebufferAttachmentImageInfo.push_back(
1558 VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO, // VkStructureType sType;
1559 DE_NULL, // const void* pNext;
1560 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
1561 cbUsage, // VkImageUsageFlags usage;
1562 m_data.framebufferDim.width, // deUint32 width;
1563 m_data.framebufferDim.height, // deUint32 height;
1564 m_data.numColorLayers, // deUint32 layerCount;
1565 1u, // deUint32 viewFormatCount;
1566 &cbFormat // const VkFormat* pViewFormats;
1569 if (m_data.useAttachment())
1570 framebufferAttachmentImageInfo.push_back(
1572 VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO, // VkStructureType sType;
1573 DE_NULL, // const void* pNext;
1574 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
1575 srUsage, // VkImageUsageFlags usage;
1576 srWidth, // deUint32 width;
1577 srHeight, // deUint32 height;
1578 numSRLayers, // deUint32 layerCount;
1579 1u, // deUint32 viewFormatCount;
1580 &srFormat // const VkFormat* pViewFormats;
1584 if (m_data.useDepthStencil)
1585 framebufferAttachmentImageInfo.push_back(
1587 VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO, // VkStructureType sType;
1588 DE_NULL, // const void* pNext;
1589 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
1590 dsUsage, // VkImageUsageFlags usage;
1591 m_data.framebufferDim.width, // deUint32 width;
1592 m_data.framebufferDim.height, // deUint32 height;
1593 m_data.numColorLayers, // deUint32 layerCount;
1594 1u, // deUint32 viewFormatCount;
1595 &dsFormat // const VkFormat* pViewFormats;
1599 const VkFramebufferAttachmentsCreateInfo framebufferAttachmentsCreateInfo =
1601 VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO, // VkStructureType sType;
1602 DE_NULL, // const void* pNext;
1603 (deUint32)framebufferAttachmentImageInfo.size(), // deUint32 attachmentImageInfoCount;
1604 &framebufferAttachmentImageInfo[0] // const VkFramebufferAttachmentImageInfo* pAttachmentImageInfos;
1607 const vk::VkFramebufferCreateInfo framebufferParams =
1609 vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // sType
1610 imagelessFB ? &framebufferAttachmentsCreateInfo : DE_NULL, // pNext
1611 (vk::VkFramebufferCreateFlags)(imagelessFB ? VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT : 0),
1612 *renderPass, // renderPass
1613 (deUint32)attachments.size(), // attachmentCount
1614 imagelessFB ? DE_NULL : &attachments[0], // pAttachments
1615 m_data.framebufferDim.width, // width
1616 m_data.framebufferDim.height, // height
1617 m_data.multiView ? 1 : m_data.numColorLayers, // layers
1620 framebuffer = createFramebuffer(vk, device, &framebufferParams);
1623 const VkVertexInputBindingDescription vertexBinding =
1625 0u, // deUint32 binding;
1626 sizeof(float) * 2, // deUint32 stride;
1627 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate;
1629 const VkVertexInputAttributeDescription vertexInputAttributeDescription =
1631 0u, // deUint32 location;
1632 0u, // deUint32 binding;
1633 VK_FORMAT_R32G32_SFLOAT, // VkFormat format;
1634 0u // deUint32 offset;
1637 const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo =
1639 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1640 DE_NULL, // const void* pNext;
1641 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
1642 1u, // deUint32 vertexBindingDescriptionCount;
1643 &vertexBinding, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1644 1u, // deUint32 vertexAttributeDescriptionCount;
1645 &vertexInputAttributeDescription // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
1648 const VkPipelineRasterizationConservativeStateCreateInfoEXT consRastState =
1650 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT, // VkStructureType sType;
1651 DE_NULL, // const void* pNext;
1652 (VkPipelineRasterizationConservativeStateCreateFlagsEXT)0, // VkPipelineRasterizationConservativeStateCreateFlagsEXT flags;
1653 m_data.conservativeMode, // VkConservativeRasterizationModeEXT conservativeRasterizationMode;
1654 0.0f, // float extraPrimitiveOverestimationSize;
1657 const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
1659 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
1660 m_data.conservativeEnable ? &consRastState : DE_NULL, // const void* pNext;
1661 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
1662 VK_FALSE, // VkBool32 depthClampEnable;
1663 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
1664 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
1665 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
1666 VK_FRONT_FACE_CLOCKWISE, // VkFrontFace frontFace;
1667 VK_FALSE, // VkBool32 depthBiasEnable;
1668 0.0f, // float depthBiasConstantFactor;
1669 0.0f, // float depthBiasClamp;
1670 0.0f, // float depthBiasSlopeFactor;
1671 1.0f // float lineWidth;
1674 // Kill some bits from each AA mode
1675 const VkSampleMask sampleMask = m_data.sampleMaskTest ? 0x9 : 0x7D56;
1676 const VkSampleMask* pSampleMask = m_data.useApiSampleMask ? &sampleMask : DE_NULL;
1678 // All samples at pixel center. We'll validate that pixels are fully covered or uncovered.
1679 std::vector<VkSampleLocationEXT> sampleLocations(m_data.samples, { 0.5f, 0.5f });
1680 const VkSampleLocationsInfoEXT sampleLocationsInfo =
1682 VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT, // VkStructureType sType;
1683 DE_NULL, // const void* pNext;
1684 (VkSampleCountFlagBits)m_data.samples, // VkSampleCountFlagBits sampleLocationsPerPixel;
1685 { 1, 1 }, // VkExtent2D sampleLocationGridSize;
1686 (deUint32)m_data.samples, // uint32_t sampleLocationsCount;
1687 &sampleLocations[0], // const VkSampleLocationEXT* pSampleLocations;
1690 const VkPipelineSampleLocationsStateCreateInfoEXT pipelineSampleLocationsCreateInfo =
1692 VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT, // VkStructureType sType;
1693 DE_NULL, // const void* pNext;
1694 VK_TRUE, // VkBool32 sampleLocationsEnable;
1695 sampleLocationsInfo, // VkSampleLocationsInfoEXT sampleLocationsInfo;
1698 const VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfo =
1700 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType
1701 m_data.sampleLocations ? &pipelineSampleLocationsCreateInfo : DE_NULL, // const void* pNext
1702 0u, // VkPipelineMultisampleStateCreateFlags flags
1703 (VkSampleCountFlagBits)m_data.samples, // VkSampleCountFlagBits rasterizationSamples
1704 (VkBool32)m_data.sampleShadingEnable, // VkBool32 sampleShadingEnable
1705 1.0f, // float minSampleShading
1706 pSampleMask, // const VkSampleMask* pSampleMask
1707 VK_FALSE, // VkBool32 alphaToCoverageEnable
1708 VK_FALSE // VkBool32 alphaToOneEnable
1711 std::vector<VkViewport> viewports;
1712 std::vector<VkRect2D> scissors;
1713 if (m_data.multiViewport)
1715 // Split the viewport into left and right halves
1716 int x0 = 0, x1 = m_data.framebufferDim.width/2, x2 = m_data.framebufferDim.width;
1718 viewports.push_back(makeViewport((float)x0, 0, (float)(x1-x0), (float)m_data.framebufferDim.height, 0.0f, 1.0f));
1719 scissors.push_back(makeRect2D(x0, 0, x1-x0, m_data.framebufferDim.height));
1721 viewports.push_back(makeViewport((float)x1, 0, (float)(x2-x1), (float)m_data.framebufferDim.height, 0.0f, 1.0f));
1722 scissors.push_back(makeRect2D(x1, 0, x2-x1, m_data.framebufferDim.height));
1726 viewports.push_back(makeViewport(m_data.framebufferDim.width, m_data.framebufferDim.height));
1727 scissors.push_back(makeRect2D(m_data.framebufferDim.width, m_data.framebufferDim.height));
1730 Move<VkShaderModule> fragShader = createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0);
1731 Move<VkShaderModule> vertShader = createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0);
1732 Move<VkShaderModule> geomShader;
1733 if (m_data.geometryShader)
1734 geomShader = createShaderModule(vk, device, m_context.getBinaryCollection().get("geom"), 0);
1736 const deUint32 fragSizeWH = m_data.sampleMaskTest ? 2 : 0;
1738 VkPipelineRenderingCreateInfoKHR renderingCreateInfo
1740 VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
1742 m_data.multiView ? 0x3 : 0u,
1745 m_data.useDepthStencil ? dsFormat : VK_FORMAT_UNDEFINED,
1746 m_data.useDepthStencil ? dsFormat : VK_FORMAT_UNDEFINED
1749 VkPipelineFragmentShadingRateStateCreateInfoKHR shadingRateStateCreateInfo
1751 VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR, // VkStructureType sType;
1752 m_data.useDynamicRendering ? &renderingCreateInfo : DE_NULL, // const void* pNext;
1753 { fragSizeWH, fragSizeWH }, // VkExtent2D fragmentSize;
1754 { m_data.combinerOp[0], m_data.combinerOp[1] }, // VkFragmentShadingRateCombinerOpKHR combinerOps[2];
1757 VkDynamicState dynamicState = VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR;
1758 const VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo =
1760 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType;
1761 DE_NULL, // const void* pNext;
1762 (VkPipelineDynamicStateCreateFlags)0, // VkPipelineDynamicStateCreateFlags flags;
1763 m_data.useDynamicState ? 1u : 0u, // uint32_t dynamicStateCount;
1764 &dynamicState, // const VkDynamicState* pDynamicStates;
1767 // Enable depth/stencil writes, always passing
1768 VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
1770 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
1771 DE_NULL, // const void* pNext;
1772 0u, // VkPipelineDepthStencilStateCreateFlags flags;
1773 VK_TRUE, // VkBool32 depthTestEnable;
1774 VK_TRUE, // VkBool32 depthWriteEnable;
1775 VK_COMPARE_OP_ALWAYS, // VkCompareOp depthCompareOp;
1776 VK_FALSE, // VkBool32 depthBoundsTestEnable;
1777 VK_TRUE, // VkBool32 stencilTestEnable;
1778 // VkStencilOpState front;
1780 VK_STENCIL_OP_REPLACE, // VkStencilOp failOp;
1781 VK_STENCIL_OP_REPLACE, // VkStencilOp passOp;
1782 VK_STENCIL_OP_REPLACE, // VkStencilOp depthFailOp;
1783 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp;
1784 0u, // deUint32 compareMask;
1785 0xFFu, // deUint32 writeMask;
1786 0xFFu, // deUint32 reference;
1788 // VkStencilOpState back;
1790 VK_STENCIL_OP_REPLACE, // VkStencilOp failOp;
1791 VK_STENCIL_OP_REPLACE, // VkStencilOp passOp;
1792 VK_STENCIL_OP_REPLACE, // VkStencilOp depthFailOp;
1793 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp;
1794 0u, // deUint32 compareMask;
1795 0xFFu, // deUint32 writeMask;
1796 0xFFu, // deUint32 reference;
1798 0.0f, // float minDepthBounds;
1799 0.0f, // float maxDepthBounds;
1802 VkPipelineCreateFlags pipelineCreateFlags = (VkPipelineCreateFlags)0;
1803 if (m_data.useDynamicRendering)
1804 pipelineCreateFlags |= VK_PIPELINE_CREATE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR;
1806 VkImageMemoryBarrier imageBarrier =
1808 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
1809 DE_NULL, // const void* pNext
1810 0u, // VkAccessFlags srcAccessMask
1811 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
1812 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
1813 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout
1814 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
1815 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
1816 **cbImage, // VkImage image
1818 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
1819 0u, // uint32_t baseMipLevel
1820 VK_REMAINING_MIP_LEVELS, // uint32_t mipLevels,
1821 0u, // uint32_t baseArray
1822 VK_REMAINING_ARRAY_LAYERS, // uint32_t arraySize
1826 const VkQueue queue = m_context.getUniversalQueue();
1827 Move<VkCommandPool> cmdPool = createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, m_context.getUniversalQueueFamilyIndex());
1828 Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1829 VkClearValue clearColor = makeClearValueColorU32(0, 0, 0, 0);
1830 VkClearValue clearDepthStencil = makeClearValueDepthStencil(0.0, 0);
1832 beginCommandBuffer(vk, *cmdBuffer, 0u);
1834 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1835 (VkDependencyFlags)0,
1836 0, (const VkMemoryBarrier*)DE_NULL,
1837 0, (const VkBufferMemoryBarrier*)DE_NULL,
1840 imageBarrier.image = **derivImage;
1841 imageBarrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
1843 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1844 (VkDependencyFlags)0,
1845 0, (const VkMemoryBarrier*)DE_NULL,
1846 0, (const VkBufferMemoryBarrier*)DE_NULL,
1849 // Clear level to 1<<level
1850 for (deUint32 i = 0; i < derivNumLevels; ++i)
1852 VkImageSubresourceRange range = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, i, 1u, 0u, 1u);
1853 VkClearValue clearLevelColor = makeClearValueColorU32(1<<i,0,0,0);
1854 vk.cmdClearColorImage(*cmdBuffer, **derivImage, VK_IMAGE_LAYOUT_GENERAL, &clearLevelColor.color, 1, &range);
1857 // Clear color buffer to transparent black
1859 VkImageSubresourceRange range = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, VK_REMAINING_ARRAY_LAYERS);
1860 vk.cmdClearColorImage(*cmdBuffer, **cbImage, VK_IMAGE_LAYOUT_GENERAL, &clearColor.color, 1, &range);
1863 // Clear depth and stencil
1864 if (m_data.useDepthStencil)
1866 VkImageSubresourceRange range = makeImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 1u, 0u, VK_REMAINING_ARRAY_LAYERS);
1867 VkImageMemoryBarrier dsBarrier = imageBarrier;
1868 dsBarrier.image = **dsImage;
1869 dsBarrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
1870 dsBarrier.subresourceRange = range;
1871 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1872 0u, // dependencyFlags
1876 vk.cmdClearDepthStencilImage(*cmdBuffer, **dsImage, VK_IMAGE_LAYOUT_GENERAL, &clearDepthStencil.depthStencil, 1, &range);
1879 // Initialize shading rate image with varying values
1880 if (m_data.useAttachment())
1882 imageBarrier.image = **srImage;
1883 imageBarrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
1885 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1886 (VkDependencyFlags)0,
1887 0, (const VkMemoryBarrier*)DE_NULL,
1888 0, (const VkBufferMemoryBarrier*)DE_NULL,
1891 deMemset(fillPtr, 0, (size_t)srFillBufferSize);
1892 for (deUint32 layer = 0; layer < numSRLayers; ++layer)
1894 for (deUint32 x = 0; x < srWidth; ++x)
1896 for (deUint32 y = 0; y < srHeight; ++y)
1898 deUint32 idx = (layer*srHeight + y)*srWidth + x;
1899 deUint8 val = (deUint8)SanitizeRate(idx & 0xF);
1900 // actual shading rate is always in the LSBs of the first byte of a texel
1901 fillPtr[srFillBpp*idx] = val;
1905 flushAlloc(vk, device, srFillBuffer->getAllocation());
1907 const VkBufferImageCopy copyRegion =
1909 0u, // VkDeviceSize bufferOffset;
1910 0u, // deUint32 bufferRowLength;
1911 0u, // deUint32 bufferImageHeight;
1913 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect;
1914 0u, // deUint32 mipLevel;
1915 0u, // deUint32 baseArrayLayer;
1916 numSRLayers, // deUint32 layerCount;
1917 }, // VkImageSubresourceLayers imageSubresource;
1918 { 0, 0, 0 }, // VkOffset3D imageOffset;
1919 { srWidth, srHeight, 1 }, // VkExtent3D imageExtent;
1922 vk.cmdCopyBufferToImage(*cmdBuffer, **srFillBuffer, **srImage, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region);
1924 imageBarrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
1925 imageBarrier.newLayout = srLayout;
1927 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1928 (VkDependencyFlags)0,
1929 0, (const VkMemoryBarrier*)DE_NULL,
1930 0, (const VkBufferMemoryBarrier*)DE_NULL,
1934 VkMemoryBarrier memBarrier =
1936 VK_STRUCTURE_TYPE_MEMORY_BARRIER, // sType
1938 0u, // srcAccessMask
1939 0u, // dstAccessMask
1942 memBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1943 memBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR;
1944 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, allPipelineStages,
1945 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
1947 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0, 1, &descriptorSet.get(), 0, DE_NULL);
1949 vector<GraphicsPipelineWrapper> pipelines;
1950 pipelines.reserve(m_data.useDynamicState ? 1u : NUM_TRIANGLES);
1952 // If using dynamic state, create a single graphics pipeline and bind it
1953 vk::VkPipelineRenderingCreateInfoKHR* pDynamicRendering = (m_data.useDynamicRendering ? &renderingCreateInfo : DE_NULL);
1954 if (m_data.useDynamicState)
1956 pipelines.emplace_back(vk, device, m_data.pipelineConstructionType, pipelineCreateFlags);
1958 .setDefaultColorBlendState()
1959 .setDynamicState(&dynamicStateCreateInfo)
1960 .setupVertexInputStete(&vertexInputStateCreateInfo)
1961 .setupPreRasterizationShaderState(viewports,
1967 &rasterizationStateCreateInfo,
1973 .setupFragmentShaderState(
1978 &depthStencilStateParams,
1979 &multisampleStateCreateInfo,
1980 &shadingRateStateCreateInfo)
1981 .setupFragmentOutputState(*renderPass, 0u, DE_NULL, &multisampleStateCreateInfo)
1982 .setMonolithicPipelineLayout(*pipelineLayout)
1984 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.back().getPipeline());
1987 VkRect2D renderArea = makeRect2D(m_data.framebufferDim.width, m_data.framebufferDim.height);
1988 if (m_data.useDynamicRendering)
1990 VkRenderingFragmentShadingRateAttachmentInfoKHR shadingRateAttachmentInfo
1992 VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR, // VkStructureType sType;
1993 DE_NULL, // const void* pNext;
1994 *srImageView, // VkImageView imageView;
1995 srLayout, // VkImageLayout imageLayout;
1996 { srTexelWidth, srTexelHeight } // VkExtent2D shadingRateAttachmentTexelSize;
1999 VkRenderingAttachmentInfoKHR colorAttachment
2001 vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
2002 DE_NULL, // const void* pNext;
2003 *cbImageView, // VkImageView imageView;
2004 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
2005 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
2006 DE_NULL, // VkImageView resolveImageView;
2007 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout;
2008 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
2009 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
2010 clearColor // VkClearValue clearValue;
2013 std::vector<VkRenderingAttachmentInfoKHR> depthStencilAttachments(2,
2015 VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
2016 DE_NULL, // const void* pNext;
2017 *dsImageView, // VkImageView imageView;
2018 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
2019 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
2020 DE_NULL, // VkImageView resolveImageView;
2021 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout;
2022 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
2023 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
2024 clearDepthStencil // VkClearValue clearValue;
2027 vk::VkRenderingInfoKHR renderingInfo
2029 vk::VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
2030 m_data.useAttachment() ? &shadingRateAttachmentInfo : DE_NULL,
2031 0, // VkRenderingFlagsKHR flags;
2032 renderArea, // VkRect2D renderArea;
2033 m_data.multiView ? 1 : m_data.numColorLayers, // deUint32 layerCount;
2034 m_data.multiView ? 0x3 : 0u, // deUint32 viewMask;
2035 1u, // deUint32 colorAttachmentCount;
2036 &colorAttachment, // const VkRenderingAttachmentInfoKHR* pColorAttachments;
2037 m_data.useDepthStencil ? &depthStencilAttachments[0] : DE_NULL, // const VkRenderingAttachmentInfoKHR* pDepthAttachment;
2038 m_data.useDepthStencil ? &depthStencilAttachments[1] : DE_NULL, // const VkRenderingAttachmentInfoKHR* pStencilAttachment;
2041 vk.cmdBeginRendering(*cmdBuffer, &renderingInfo);
2045 const VkRenderPassAttachmentBeginInfo renderPassAttachmentBeginInfo
2047 VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO, // VkStructureType sType;
2048 DE_NULL, // const void* pNext;
2049 (deUint32)attachments.size(), // deUint32 attachmentCount;
2050 &attachments[0] // const VkImageView* pAttachments;
2053 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderArea,
2054 0, DE_NULL, VK_SUBPASS_CONTENTS_INLINE, imagelessFB ? &renderPassAttachmentBeginInfo : DE_NULL);
2057 for (deInt32 i = 0; i < NUM_TRIANGLES; ++i)
2059 // Bind vertex attributes pointing to the next triangle
2060 VkDeviceSize vertexBufferOffset = i*3*2*sizeof(float);
2061 VkBuffer vb = **vertexBuffer;
2062 vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vb, &vertexBufferOffset);
2064 // Put primitive shading rate in a push constant
2065 deInt32 shadingRatePC = PrimIDToPrimitiveShadingRate(i);
2066 vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, allShaderStages, 0, sizeof(shadingRatePC), &shadingRatePC);
2068 if (m_data.useDynamicState)
2070 VkExtent2D fragmentSize = ShadingRateEnumToExtent(PrimIDToPipelineShadingRate(i));
2071 vk.cmdSetFragmentShadingRateKHR(*cmdBuffer, &fragmentSize, m_data.combinerOp);
2075 // Create a new pipeline with the desired pipeline shading rate
2076 shadingRateStateCreateInfo.fragmentSize = ShadingRateEnumToExtent(PrimIDToPipelineShadingRate(i));
2077 pipelines.emplace_back(vk, device, m_data.pipelineConstructionType, pipelineCreateFlags);
2079 .setDefaultColorBlendState()
2080 .setDynamicState(&dynamicStateCreateInfo)
2081 .setupVertexInputStete(&vertexInputStateCreateInfo)
2082 .setupPreRasterizationShaderState(viewports,
2088 &rasterizationStateCreateInfo,
2094 .setupFragmentShaderState(
2099 &depthStencilStateParams,
2100 &multisampleStateCreateInfo,
2101 &shadingRateStateCreateInfo)
2102 .setupFragmentOutputState(*renderPass, 0u, DE_NULL, &multisampleStateCreateInfo)
2103 .setMonolithicPipelineLayout(*pipelineLayout)
2105 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.back().getPipeline());
2108 // Draw one triangle, with "primitive ID" in gl_InstanceIndex
2109 vk.cmdDraw(*cmdBuffer, 3u, 1, 0u, i);
2112 if (m_data.useDynamicRendering)
2113 endRendering(vk, *cmdBuffer);
2115 endRenderPass(vk, *cmdBuffer);
2117 memBarrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
2118 memBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
2119 vk.cmdPipelineBarrier(*cmdBuffer, allPipelineStages, allPipelineStages,
2120 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
2122 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1, &*descriptorSet, 0u, DE_NULL);
2123 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
2125 // Copy color/depth/stencil buffers to buffer memory
2126 vk.cmdDispatch(*cmdBuffer, m_data.framebufferDim.width, m_data.framebufferDim.height, m_data.numColorLayers);
2128 memBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
2129 memBarrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT;
2130 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
2131 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
2133 endCommandBuffer(vk, *cmdBuffer);
2135 submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
2137 deUint32 *colorptr = (deUint32 *)colorOutputBuffer->getAllocation().getHostPtr();
2138 invalidateAlloc(vk, device, colorOutputBuffer->getAllocation());
2140 invalidateAlloc(vk, device, atomicBuffer->getAllocation());
2142 float *depthptr = DE_NULL;
2143 deUint32 *stencilptr = DE_NULL;
2145 if (m_data.useDepthStencil)
2147 depthptr = (float *)depthOutputBuffer->getAllocation().getHostPtr();
2148 invalidateAlloc(vk, device, depthOutputBuffer->getAllocation());
2150 stencilptr = (deUint32 *)stencilOutputBuffer->getAllocation().getHostPtr();
2151 invalidateAlloc(vk, device, stencilOutputBuffer->getAllocation());
2154 // Loop over all samples and validate the output
2155 for (deUint32 layer = 0; layer < m_data.numColorLayers && res == QP_TEST_RESULT_PASS; ++layer)
2157 for (deUint32 y = 0; y < m_data.framebufferDim.height && res == QP_TEST_RESULT_PASS; ++y)
2159 for (deUint32 x = 0; x < m_data.framebufferDim.width && res == QP_TEST_RESULT_PASS; ++x)
2161 for (deInt32 s = 0; s < m_data.samples && res == QP_TEST_RESULT_PASS; ++s)
2163 deUint32 *sample = &colorptr[4*(((layer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + s)];
2165 // If testing the rasterizer sample mask, if this sample is not set in the
2166 // mask then it shouldn't have written anything.
2167 if (m_data.useApiSampleMask && !(sampleMask & (1 << s)) && sample[2] != 0)
2169 log << tcu::TestLog::Message << std::hex << "sample written despite pSampleMask (" << x << "," << y << ",sample " << s << ")" << tcu::TestLog::EndMessage;
2170 res = QP_TEST_RESULT_FAIL;
2174 // The same isn't covered by any primitives, skip it
2178 // skip samples that have the same value as sample zero - it would be redundant to check them.
2181 deUint32 *sample0 = &colorptr[4*(((layer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + 0)];
2182 bool same = deMemCmp(sample, sample0, 16) == 0;
2184 if (m_data.fragDepth)
2186 float *dsample = &depthptr[((layer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + s];
2187 float *dsample0 = &depthptr[((layer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + 0];
2188 same = same && (*dsample == *dsample0);
2191 if (m_data.fragStencil)
2193 deUint32 *ssample = &stencilptr[((layer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + s];
2194 deUint32 *ssample0 = &stencilptr[((layer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + 0];
2195 same = same && (*ssample == *ssample0);
2202 // Fragment shader writes error codes to .w component.
2203 // All nonzero values are unconditionally failures
2206 if (sample[3] == ERROR_FRAGCOORD_CENTER)
2207 log << tcu::TestLog::Message << std::hex << "fragcoord test failed pixel (0x" << x << ",0x" << y << ",sample 0x" << s << ")" << tcu::TestLog::EndMessage;
2208 else if (sample[3] == ERROR_VTG_READBACK)
2209 log << tcu::TestLog::Message << std::hex << "vs/gs output readback test failed pixel (0x" << x << ",0x" << y << ",sample 0x" << s << ")" << tcu::TestLog::EndMessage;
2210 else if ((sample[3] & 0xFF) == ERROR_FRAGCOORD_DERIV)
2211 log << tcu::TestLog::Message << std::hex << "fragcoord derivative test failed pixel (0x" << x << ",0x" << y << ",sample 0x" << s << ")="
2212 "(0x" << ((sample[3] >> 8) & 0x3F) << ",0x" << ((sample[3] >> 14) & 0x3F) << "), expected="
2213 "(0x" << ((sample[3] >> 20) & 0x3F) << ",0x" << ((sample[3] >> 26) & 0x3F) << ")" << tcu::TestLog::EndMessage;
2214 else if ((sample[3] & 0xFF) == ERROR_FRAGCOORD_IMPLICIT_DERIV)
2215 log << tcu::TestLog::Message << std::hex << "implicit derivative test failed pixel (0x" << x << ",0x" << y << ",sample 0x" << s << ")="
2216 "(0x" << ((sample[3] >> 8) & 0x3F) << ",0x" << ((sample[3] >> 14) & 0x3F) << "), expected="
2217 "(0x" << ((sample[3] >> 20) & 0x3F) << ",0x" << ((sample[3] >> 26) & 0x3F) << ")" << tcu::TestLog::EndMessage;
2219 log << tcu::TestLog::Message << std::hex << "w coord unknown test failed pixel (0x" << x << ",0x" << y << ",sample 0x" << s << ")" << tcu::TestLog::EndMessage;
2220 res = QP_TEST_RESULT_FAIL;
2224 // x component of sample
2225 deUint32 rate = sample[0];
2227 deUint32 pixelsX = 1 << ((rate/4)&3);
2228 deUint32 pixelsY = 1 << (rate&3);
2231 deUint32 fragMinX = x & ~(pixelsX-1);
2232 deUint32 fragMinY = y & ~(pixelsY-1);
2233 deUint32 fragMaxX = fragMinX + pixelsX;
2234 deUint32 fragMaxY = fragMinY + pixelsY;
2236 // Clamp to FB dimension for odd sizes
2237 if (fragMaxX > m_data.framebufferDim.width)
2238 fragMaxX = m_data.framebufferDim.width;
2239 if (fragMaxY > m_data.framebufferDim.height)
2240 fragMaxY = m_data.framebufferDim.height;
2242 // z component of sample
2243 deUint32 primID = sample[2] >> 24;
2244 deUint32 atomVal = sample[2] & 0xFFFFFF;
2246 // Compute pipeline and primitive rate from primitive ID, and attachment
2247 // rate from the x/y coordinate
2248 deInt32 pipelineRate = PrimIDToPipelineShadingRate(primID);
2249 deInt32 primitiveRate = m_data.shaderWritesRate ? PrimIDToPrimitiveShadingRate(primID) : 0;
2251 deInt32 attachmentLayer = (m_data.srLayered && modeIdx == ATTACHMENT_MODE_2DARRAY) ? layer : 0;
2252 deInt32 attachmentRate = m_data.useAttachment() ? fillPtr[srFillBpp*((attachmentLayer * srHeight + (y / srTexelHeight)) * srWidth + (x / srTexelWidth))] : 0;
2254 // Get mask of allowed shading rates
2255 deInt32 expectedMasks = Simulate(pipelineRate, primitiveRate, attachmentRate);
2257 if (!(expectedMasks & (1 << rate)))
2259 log << tcu::TestLog::Message << std::hex << "unexpected shading rate. failed pixel (0x" << x << ",0x" << y << ",sample 0x" << s << ") "
2260 "result rate 0x" << rate << " mask of expected rates 0x" << expectedMasks <<
2261 " pipelineRate=0x" << pipelineRate << " primitiveRate=0x" << primitiveRate << " attachmentRate =0x" << attachmentRate << tcu::TestLog::EndMessage;
2262 res = QP_TEST_RESULT_FAIL;
2265 // Check that not all fragments are downgraded to 1x1
2266 if (rate == 0 && expectedMasks != 1)
2267 numUnexpected1x1Samples++;
2270 // Check that gl_FragDepth = primID / NUM_TRIANGLES
2271 if (m_data.fragDepth)
2273 float *dsample = &depthptr[((layer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + s];
2274 float expected = (float)primID / NUM_TRIANGLES;
2275 if (fabs(*dsample - expected) > 0.01)
2277 log << tcu::TestLog::Message << std::hex << "depth write failed pixel (0x" << x << ",0x" << y << ",sample 0x" << s << ")=" << *dsample << " expected " << expected << tcu::TestLog::EndMessage;
2278 res = QP_TEST_RESULT_FAIL;
2283 // Check that stencil value = primID
2284 if (m_data.fragStencil)
2286 deUint32 *ssample = &stencilptr[((layer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + s];
2287 if (*ssample != primID)
2289 log << tcu::TestLog::Message << std::hex << "stencil write failed pixel (0x" << x << ",0x" << y << ",sample 0x" << s << ")=" << *ssample << " expected " << primID << tcu::TestLog::EndMessage;
2290 res = QP_TEST_RESULT_FAIL;
2295 // Check that primitives are in the right viewport/scissor
2296 if (m_data.multiViewport)
2298 VkRect2D *scissor = &scissors[primID & 1];
2299 if ((int)x < scissor->offset.x || (int)x >= (int)(scissor->offset.x + scissor->extent.width) ||
2300 (int)y < scissor->offset.y || (int)y >= (int)(scissor->offset.y + scissor->extent.height))
2302 log << tcu::TestLog::Message << std::hex << "primitive found outside of expected viewport (0x" << x << ",0x" << y << ",sample 0x" << s << ") primID=" << primID << tcu::TestLog::EndMessage;
2303 res = QP_TEST_RESULT_FAIL;
2308 // Check that primitives are in the right layer
2309 if (m_data.colorLayered)
2311 if (layer != ((primID & 2)>>1))
2313 log << tcu::TestLog::Message << std::hex << "primitive found in wrong layer (0x" << x << ",0x" << y << ",sample 0x" << s << ") primID=" << primID << " layer=" << layer << tcu::TestLog::EndMessage;
2314 res = QP_TEST_RESULT_FAIL;
2319 // Check that multiview broadcasts the same primitive to both layers
2320 if (m_data.multiView)
2322 deUint32 otherLayer = layer^1;
2323 deUint32 *othersample = &colorptr[4*(((otherLayer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + s)];
2324 deUint32 otherPrimID = othersample[2] >> 24;
2325 if (primID != otherPrimID)
2327 log << tcu::TestLog::Message << std::hex << "multiview primitive mismatch (0x" << x << ",0x" << y << ",sample 0x" << s << ") primID=" << primID << " otherPrimID=" << otherPrimID << tcu::TestLog::EndMessage;
2328 res = QP_TEST_RESULT_FAIL;
2333 // Loop over all samples in the same fragment
2334 for (deUint32 fx = fragMinX; fx < fragMaxX; ++fx)
2336 for (deUint32 fy = fragMinY; fy < fragMaxY; ++fy)
2338 for (deInt32 fs = 0; fs < m_data.samples; ++fs)
2340 deUint32 *fsample = &colorptr[4*(((layer * m_data.framebufferDim.height + fy) * m_data.framebufferDim.width + fx)*m_data.samples + fs)];
2341 deUint32 frate = fsample[0];
2342 deUint32 fprimID = fsample[2] >> 24;
2343 deUint32 fatomVal = fsample[2] & 0xFFFFFF;
2345 // If we write out the sample mask value, check that the samples in the
2346 // mask must not be uncovered, and that samples not in the mask must not
2347 // be covered by this primitive
2348 if (m_data.useSampleMaskIn)
2350 int p = pixelsX * pixelsY - ((fx - fragMinX) + pixelsX * (fy - fragMinY)) - 1;
2351 int sampleIdx = fs + m_data.samples * p;
2353 if ((sample[1] & (1 << sampleIdx)) && fsample[2] == 0)
2355 log << tcu::TestLog::Message << std::hex << "sample set in sampleMask but not written (0x" << fx << ",0x" << fy << ",sample 0x" << fs << ")" << tcu::TestLog::EndMessage;
2356 res = QP_TEST_RESULT_FAIL;
2359 if (!(sample[1] & (1 << sampleIdx)) && fsample[2] != 0 && fprimID == primID)
2361 log << tcu::TestLog::Message << std::hex << "sample not set in sampleMask but written with same primID (0x" << fx << ",0x" << fy << ",sample 0x" << fs << ")" << tcu::TestLog::EndMessage;
2362 res = QP_TEST_RESULT_FAIL;
2367 // If conservative raster is enabled, or custom sample locations all at the center, check that
2368 // samples in the same pixel must be covered.
2369 if (m_data.conservativeEnable ||
2370 (m_data.sampleLocations && m_context.getFragmentShadingRateProperties().fragmentShadingRateWithCustomSampleLocations))
2372 // If it's in the same pixel, expect it to be fully covered.
2373 if (fx == x && fy == y && fsample[2] == 0)
2375 log << tcu::TestLog::Message << std::hex << "pixel not fully covered (0x" << fx << ",0x" << fy << ",sample 0x" << fs << ")" << tcu::TestLog::EndMessage;
2376 res = QP_TEST_RESULT_FAIL;
2381 if (fsample[2] == 0)
2384 // If the primitive matches this sample, then it must have the same rate and
2386 if (fprimID == primID)
2388 if (rate != frate || (atomVal != fatomVal && !(m_data.sampleShadingEnable || m_data.sampleShadingInput)))
2390 log << tcu::TestLog::Message << std::hex << "failed pixel (0x" << x << ",0x" << y << ",sample " << s << ")=0x" << ((primID<<24)|atomVal) <<
2391 " compared to (0x" << fx << ",0x" << fy << ",sample " << fs << ")=0x" << ((fprimID<<24)|fatomVal) <<
2392 " pipelineRate=0x" << pipelineRate << " primitiveRate=0x" << primitiveRate << " attachmentRate =0x" << attachmentRate <<
2393 tcu::TestLog::EndMessage;
2394 res = QP_TEST_RESULT_FAIL;
2404 if (res == QP_TEST_RESULT_FAIL)
2408 // All samples were coerced to 1x1, unexpected
2409 if (res == QP_TEST_RESULT_PASS &&
2410 numTotalSamples != 0 &&
2411 numUnexpected1x1Samples == numTotalSamples &&
2412 numTotalSamples > 16)
2414 log << tcu::TestLog::Message << std::hex << "Quality warning - all fragments used 1x1" << tcu::TestLog::EndMessage;
2415 res = QP_TEST_RESULT_QUALITY_WARNING;
2418 return tcu::TestStatus(res, qpGetTestResultName(res));
2423 void createBasicTests (tcu::TestContext& testCtx, tcu::TestCaseGroup* parentGroup, vk::PipelineConstructionType pipelineConstructionType, bool useDynamicRendering)
2429 const char* description;
2436 const char* description;
2441 AttachmentUsage usage;
2443 const char* description;
2444 } TestGroupUsageCase;
2446 TestGroupCase groupCases[] =
2448 { 0, "basic", "basic tests" },
2449 { 1, "apisamplemask", "use pSampleMask" },
2450 { 2, "samplemaskin", "use gl_SampleMaskIn" },
2451 { 3, "conservativeunder", "conservative underestimation" },
2452 { 4, "conservativeover", "conservative overestimation" },
2453 { 5, "fragdepth", "depth shader output" },
2454 { 6, "fragstencil", "stencil shader output" },
2455 { 7, "multiviewport", "multiple viewports and gl_ViewportIndex" },
2456 { 8, "colorlayered", "multiple layer color, single layer shading rate" },
2457 { 9, "srlayered", "multiple layer color, multiple layers shading rate" },
2458 { 10, "multiview", "multiview" },
2459 { 11, "multiviewsrlayered", "multiview and multilayer shading rate" },
2460 { 12, "multiviewcorrelation", "multiview with correlation mask" },
2461 { 13, "interlock", "fragment shader interlock" },
2462 { 14, "samplelocations", "custom sample locations" },
2463 { 15, "sampleshadingenable", "enable sample shading in createinfo" },
2464 { 16, "sampleshadinginput", "enable sample shading by using gl_SampleID" },
2467 TestGroupCase dynCases[] =
2469 { 1, "dynamic", "uses dynamic shading rate state" },
2470 { 0, "static", "uses static shading rate state" },
2473 TestGroupUsageCase attCases[] =
2475 { AttachmentUsage::NO_ATTACHMENT, "noattachment", "no shading rate attachment" },
2476 { AttachmentUsage::WITH_ATTACHMENT, "attachment", "has shading rate attachment" },
2477 { AttachmentUsage::NO_ATTACHMENT_PTR, "noattachmentptr", "no shading rate attachment pointer" },
2480 TestGroupCase shdCases[] =
2482 { 0, "noshaderrate", "shader doesn't write rate" },
2483 { 1, "shaderrate", "shader writes rate" },
2486 TestGroupCase combCases[] =
2488 { VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR, "keep", "keep" },
2489 { VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR, "replace", "replace" },
2490 { VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MIN_KHR, "min", "min" },
2491 { VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_KHR, "max", "max" },
2492 { VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_KHR, "mul", "mul" },
2495 TestGroupCase2D extentCases[] =
2497 { {1, 1}, "1x1", "1x1" },
2498 { {4, 4}, "4x4", "4x4" },
2499 { {33, 35}, "33x35", "33x35" },
2500 { {151, 431}, "151x431", "151x431" },
2501 { {256, 256}, "256x256", "256x256" },
2504 TestGroupCase sampCases[] =
2506 { VK_SAMPLE_COUNT_1_BIT, "samples1", "1 raster sample" },
2507 { VK_SAMPLE_COUNT_2_BIT, "samples2", "2 raster samples" },
2508 { VK_SAMPLE_COUNT_4_BIT, "samples4", "4 raster samples" },
2509 { VK_SAMPLE_COUNT_8_BIT, "samples8", "8 raster samples" },
2510 { VK_SAMPLE_COUNT_16_BIT, "samples16", "16 raster samples" },
2513 TestGroupCase geomCases[] =
2515 { 0, "vs", "vertex shader only" },
2516 { 1, "gs", "vertex and geometry shader" },
2521 for (int groupNdx = 0; groupNdx < DE_LENGTH_OF_ARRAY(groupCases); groupNdx++)
2523 if (useDynamicRendering && groupNdx == 12)
2526 if (pipelineConstructionType != PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
2528 // for graphics pipeline library we need to repeat only selected groups
2529 if (std::set<int> { 2, 3, 4, 10, 11, 12, 13, 14, 15 }.count(groupNdx) == 0)
2533 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, groupCases[groupNdx].name, groupCases[groupNdx].description));
2534 for (int dynNdx = 0; dynNdx < DE_LENGTH_OF_ARRAY(dynCases); dynNdx++)
2536 de::MovePtr<tcu::TestCaseGroup> dynGroup(new tcu::TestCaseGroup(testCtx, dynCases[dynNdx].name, dynCases[dynNdx].description));
2537 for (int attNdx = 0; attNdx < DE_LENGTH_OF_ARRAY(attCases); attNdx++)
2539 if (useDynamicRendering && attCases[attNdx].usage == AttachmentUsage::NO_ATTACHMENT_PTR)
2542 de::MovePtr<tcu::TestCaseGroup> attGroup(new tcu::TestCaseGroup(testCtx, attCases[attNdx].name, attCases[attNdx].description));
2543 for (int shdNdx = 0; shdNdx < DE_LENGTH_OF_ARRAY(shdCases); shdNdx++)
2545 de::MovePtr<tcu::TestCaseGroup> shdGroup(new tcu::TestCaseGroup(testCtx, shdCases[shdNdx].name, shdCases[shdNdx].description));
2546 for (int cmb0Ndx = 0; cmb0Ndx < DE_LENGTH_OF_ARRAY(combCases); cmb0Ndx++)
2548 de::MovePtr<tcu::TestCaseGroup> cmb0Group(new tcu::TestCaseGroup(testCtx, combCases[cmb0Ndx].name, combCases[cmb0Ndx].description));
2549 for (int cmb1Ndx = 0; cmb1Ndx < DE_LENGTH_OF_ARRAY(combCases); cmb1Ndx++)
2551 de::MovePtr<tcu::TestCaseGroup> cmb1Group(new tcu::TestCaseGroup(testCtx, combCases[cmb1Ndx].name, combCases[cmb1Ndx].description));
2552 for (int extNdx = 0; extNdx < DE_LENGTH_OF_ARRAY(extentCases); extNdx++)
2554 // to reduce number of cases repeat every other extent case for graphics pipeline library
2555 if ((pipelineConstructionType != PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC) && ((extNdx % 2) == 1))
2558 de::MovePtr<tcu::TestCaseGroup> extGroup(new tcu::TestCaseGroup(testCtx, extentCases[extNdx].name, extentCases[extNdx].description));
2559 for (int sampNdx = 0; sampNdx < DE_LENGTH_OF_ARRAY(sampCases); sampNdx++)
2561 de::MovePtr<tcu::TestCaseGroup> sampGroup(new tcu::TestCaseGroup(testCtx, sampCases[sampNdx].name, sampCases[sampNdx].description));
2562 for (int geomNdx = 0; geomNdx < DE_LENGTH_OF_ARRAY(geomCases); geomNdx++)
2564 bool useApiSampleMask = groupNdx == 1;
2565 bool useSampleMaskIn = groupNdx == 2;
2566 bool consRast = groupNdx == 3 || groupNdx == 4;
2567 bool fragDepth = groupNdx == 5;
2568 bool fragStencil = groupNdx == 6;
2569 bool multiViewport = groupNdx == 7;
2570 bool colorLayered = groupNdx == 8 || groupNdx == 9;
2571 bool srLayered = groupNdx == 9 || groupNdx == 11;
2572 bool multiView = groupNdx == 10 || groupNdx == 11 || groupNdx == 12;
2573 bool correlationMask = groupNdx == 12;
2574 bool interlock = groupNdx == 13;
2575 bool sampleLocations = groupNdx == 14;
2576 bool sampleShadingEnable = groupNdx == 15;
2577 bool sampleShadingInput = groupNdx == 16;
2578 VkConservativeRasterizationModeEXT conservativeMode = (groupNdx == 3) ? VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT : VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT;
2579 deUint32 numColorLayers = (colorLayered || multiView) ? 2u : 1u;
2581 // Don't bother with geometry shader if we're not testing shader writes
2582 if (geomCases[geomNdx].count && !shdCases[shdNdx].count)
2585 // reduce number of tests
2586 if ((groupNdx != 0) &&
2587 (!dynCases[dynNdx].count ||
2588 !(combCases[cmb0Ndx].count == VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR || combCases[cmb0Ndx].count == VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR) ||
2589 !(combCases[cmb1Ndx].count == VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR || combCases[cmb1Ndx].count == VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR)))
2592 // Don't bother with geometry shader if we're testing conservative raster, sample mask, depth/stencil
2593 if (geomCases[geomNdx].count && (useApiSampleMask || useSampleMaskIn || consRast || fragDepth || fragStencil))
2596 // Don't bother with geometry shader if we're testing non-dynamic state
2597 if (geomCases[geomNdx].count && !dynCases[dynNdx].count)
2600 // Only test multiViewport/layered with shaderWritesRate
2601 if ((multiViewport || colorLayered) && !shdCases[shdNdx].count)
2604 // Can't test layered shading rate attachment without an attachment
2605 if (srLayered && attCases[attNdx].usage != AttachmentUsage::WITH_ATTACHMENT)
2610 pipelineConstructionType, // PipelineConstructionType pipelineConstructionType;
2611 seed++, // deInt32 seed;
2612 extentCases[extNdx].count, // VkExtent2D framebufferDim;
2613 (VkSampleCountFlagBits)sampCases[sampNdx].count, // VkSampleCountFlagBits samples;
2615 (VkFragmentShadingRateCombinerOpKHR)combCases[cmb0Ndx].count,
2616 (VkFragmentShadingRateCombinerOpKHR)combCases[cmb1Ndx].count
2617 }, // VkFragmentShadingRateCombinerOpKHR combinerOp[2];
2618 attCases[attNdx].usage, // AttachmentUsage attachmentUsage;
2619 (bool)shdCases[shdNdx].count, // bool shaderWritesRate;
2620 (bool)geomCases[geomNdx].count, // bool geometryShader;
2621 (bool)dynCases[dynNdx].count, // bool useDynamicState;
2622 useDynamicRendering, // bool useDynamicRendering;
2623 useApiSampleMask, // bool useApiSampleMask;
2624 useSampleMaskIn, // bool useSampleMaskIn;
2625 consRast, // bool conservativeEnable;
2626 conservativeMode, // VkConservativeRasterizationModeEXT conservativeMode;
2627 fragDepth || fragStencil, // bool useDepthStencil;
2628 fragDepth, // bool fragDepth;
2629 fragStencil, // bool fragStencil;
2630 multiViewport, // bool multiViewport;
2631 colorLayered, // bool colorLayered;
2632 srLayered, // bool srLayered;
2633 numColorLayers, // deUint32 numColorLayers;
2634 multiView, // bool multiView;
2635 correlationMask, // bool correlationMask;
2636 interlock, // bool interlock;
2637 sampleLocations, // bool sampleLocations;
2638 sampleShadingEnable, // bool sampleShadingEnable;
2639 sampleShadingInput, // bool sampleShadingInput;
2640 false, // bool sampleMaskTest;
2643 sampGroup->addChild(new FSRTestCase(testCtx, geomCases[geomNdx].name, geomCases[geomNdx].description, c));
2645 extGroup->addChild(sampGroup.release());
2647 cmb1Group->addChild(extGroup.release());
2649 cmb0Group->addChild(cmb1Group.release());
2651 shdGroup->addChild(cmb0Group.release());
2653 attGroup->addChild(shdGroup.release());
2655 dynGroup->addChild(attGroup.release());
2657 group->addChild(dynGroup.release());
2659 parentGroup->addChild(group.release());
2662 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "misc_tests", "Single tests that don't need to be part of above test matrix"));
2663 group->addChild(new FSRTestCase(testCtx, "sample_mask_test", "", {
2664 pipelineConstructionType, // PipelineConstructionType pipelineConstructionType;
2665 123, // deInt32 seed;
2666 {32, 33}, // VkExtent2D framebufferDim;
2667 VK_SAMPLE_COUNT_4_BIT, // VkSampleCountFlagBits samples;
2669 VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR,
2670 VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR
2671 }, // VkFragmentShadingRateCombinerOpKHR combinerOp[2];
2672 AttachmentUsage::NO_ATTACHMENT, // AttachmentUsage attachmentUsage;
2673 true, // bool shaderWritesRate;
2674 false, // bool geometryShader;
2675 false, // bool useDynamicState;
2676 false, // bool useDynamicRendering;
2677 true, // bool useApiSampleMask;
2678 false, // bool useSampleMaskIn;
2679 false, // bool conservativeEnable;
2680 VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT, // VkConservativeRasterizationModeEXT conservativeMode;
2681 false, // bool useDepthStencil;
2682 false, // bool fragDepth;
2683 false, // bool fragStencil;
2684 false, // bool multiViewport;
2685 false, // bool colorLayered;
2686 false, // bool srLayered;
2687 1u, // deUint32 numColorLayers;
2688 false, // bool multiView;
2689 false, // bool correlationMask;
2690 false, // bool interlock;
2691 false, // bool sampleLocations;
2692 false, // bool sampleShadingEnable;
2693 false, // bool sampleShadingInput;
2694 true, // bool sampleMaskTest;
2697 parentGroup->addChild(group.release());
2700 } // FragmentShadingRage