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"
63 namespace FragmentShadingRate
70 #define NUM_TRIANGLES (9*9)
72 enum class AttachmentUsage
82 VkExtent2D framebufferDim;
83 VkSampleCountFlagBits samples;
84 VkFragmentShadingRateCombinerOpKHR combinerOp[2];
85 AttachmentUsage attachmentUsage;
86 bool shaderWritesRate;
89 bool useDynamicRendering;
90 bool useApiSampleMask;
92 bool conservativeEnable;
93 VkConservativeRasterizationModeEXT conservativeMode;
94 bool useDepthStencil; // == fragDepth || fragStencil
99 bool srLayered; // colorLayered must also be true
100 deUint32 numColorLayers;
103 bool sampleLocations;
104 bool sampleShadingEnable;
105 bool sampleShadingInput;
108 bool useAttachment () const
110 return (attachmentUsage == AttachmentUsage::WITH_ATTACHMENT);
114 class FSRTestInstance : public TestInstance
117 FSRTestInstance (Context& context, const CaseDef& data);
118 ~FSRTestInstance (void);
119 tcu::TestStatus iterate (void);
125 // Cache simulated combiner operations, to avoid recomputing per-sample
126 deInt32 m_simulateValueCount;
127 vector<deInt32> m_simulateCache;
128 // Cache mapping of primitive ID to pipeline/primitive shading rate
129 vector<deInt32> m_primIDToPrimitiveShadingRate;
130 vector<deInt32> m_primIDToPipelineShadingRate;
131 deUint32 m_supportedFragmentShadingRateCount;
132 vector<VkPhysicalDeviceFragmentShadingRateKHR> m_supportedFragmentShadingRates;
133 VkPhysicalDeviceFragmentShadingRatePropertiesKHR m_shadingRateProperties;
135 deInt32 PrimIDToPrimitiveShadingRate (deInt32 primID);
136 deInt32 PrimIDToPipelineShadingRate (deInt32 primID);
137 VkExtent2D SanitizeExtent (VkExtent2D ext) const;
138 deInt32 SanitizeRate (deInt32 rate) const;
139 deInt32 ShadingRateExtentToClampedMask (VkExtent2D ext, bool allowSwap) const;
140 deInt32 ShadingRateExtentToEnum (VkExtent2D ext) const;
141 VkExtent2D ShadingRateEnumToExtent (deInt32 rate) const;
142 deInt32 Simulate (deInt32 rate0, deInt32 rate1, deInt32 rate2);
143 VkExtent2D Combine (VkExtent2D ext0, VkExtent2D ext1, VkFragmentShadingRateCombinerOpKHR comb) const;
144 bool Force1x1 () const;
147 FSRTestInstance::FSRTestInstance (Context& context, const CaseDef& data)
148 : vkt::TestInstance (context)
150 , m_simulateValueCount (((4 * 4) | 4) + 1)
151 , m_simulateCache (m_simulateValueCount*m_simulateValueCount*m_simulateValueCount, ~0)
152 , m_primIDToPrimitiveShadingRate(NUM_TRIANGLES, ~0)
153 , m_primIDToPipelineShadingRate(NUM_TRIANGLES, ~0)
155 m_supportedFragmentShadingRateCount = 0;
156 m_context.getInstanceInterface().getPhysicalDeviceFragmentShadingRatesKHR(m_context.getPhysicalDevice(), &m_supportedFragmentShadingRateCount, DE_NULL);
158 if (m_supportedFragmentShadingRateCount < 3)
159 TCU_THROW(TestError, "*pFragmentShadingRateCount too small");
161 m_supportedFragmentShadingRates.resize(m_supportedFragmentShadingRateCount);
162 for (deUint32 i = 0; i < m_supportedFragmentShadingRateCount; ++i)
164 m_supportedFragmentShadingRates[i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_KHR;
165 m_supportedFragmentShadingRates[i].pNext = nullptr;
167 m_context.getInstanceInterface().getPhysicalDeviceFragmentShadingRatesKHR(m_context.getPhysicalDevice(), &m_supportedFragmentShadingRateCount, &m_supportedFragmentShadingRates[0]);
169 m_shadingRateProperties = m_context.getFragmentShadingRateProperties();
172 FSRTestInstance::~FSRTestInstance (void)
176 class FSRTestCase : public TestCase
179 FSRTestCase (tcu::TestContext& context, const char* name, const char* desc, const CaseDef data);
181 virtual void initPrograms (SourceCollections& programCollection) const;
182 virtual TestInstance* createInstance (Context& context) const;
183 virtual void checkSupport (Context& context) const;
189 FSRTestCase::FSRTestCase (tcu::TestContext& context, const char* name, const char* desc, const CaseDef data)
190 : vkt::TestCase (context, name, desc)
195 FSRTestCase::~FSRTestCase (void)
199 bool FSRTestInstance::Force1x1() const
201 if (m_data.useApiSampleMask && !m_context.getFragmentShadingRateProperties().fragmentShadingRateWithSampleMask)
204 if (m_data.useSampleMaskIn && !m_context.getFragmentShadingRateProperties().fragmentShadingRateWithShaderSampleMask)
207 if (m_data.conservativeEnable && !m_context.getFragmentShadingRateProperties().fragmentShadingRateWithConservativeRasterization)
210 if (m_data.useDepthStencil && !m_context.getFragmentShadingRateProperties().fragmentShadingRateWithShaderDepthStencilWrites)
213 if (m_data.interlock && !m_context.getFragmentShadingRateProperties().fragmentShadingRateWithFragmentShaderInterlock)
216 if (m_data.sampleLocations && !m_context.getFragmentShadingRateProperties().fragmentShadingRateWithCustomSampleLocations)
219 if (m_data.sampleShadingEnable || m_data.sampleShadingInput)
225 static VkImageUsageFlags cbUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
226 VK_IMAGE_USAGE_SAMPLED_BIT |
227 VK_IMAGE_USAGE_TRANSFER_DST_BIT |
228 VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
230 void FSRTestCase::checkSupport(Context& context) const
232 context.requireDeviceFunctionality("VK_KHR_fragment_shading_rate");
234 if (m_data.useDynamicRendering)
235 context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
237 if (!context.getFragmentShadingRateFeatures().pipelineFragmentShadingRate)
238 TCU_THROW(NotSupportedError, "pipelineFragmentShadingRate not supported");
240 if (m_data.shaderWritesRate &&
241 !context.getFragmentShadingRateFeatures().primitiveFragmentShadingRate)
242 TCU_THROW(NotSupportedError, "primitiveFragmentShadingRate not supported");
244 if (!context.getFragmentShadingRateFeatures().primitiveFragmentShadingRate &&
245 m_data.combinerOp[0] != VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR)
246 TCU_THROW(NotSupportedError, "primitiveFragmentShadingRate not supported");
248 if (!context.getFragmentShadingRateFeatures().attachmentFragmentShadingRate &&
249 m_data.combinerOp[1] != VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR)
250 TCU_THROW(NotSupportedError, "attachmentFragmentShadingRate not supported");
252 VkImageFormatProperties imageProperties;
253 VkResult result = context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(context.getPhysicalDevice(), VK_FORMAT_R32G32B32A32_UINT, VK_IMAGE_TYPE_2D,
254 VK_IMAGE_TILING_OPTIMAL, cbUsage, 0, &imageProperties);
256 if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
257 TCU_THROW(NotSupportedError, "VK_FORMAT_R32G32B32A32_UINT not supported");
259 if (m_data.geometryShader)
260 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
262 if (!(imageProperties.sampleCounts & m_data.samples))
263 TCU_THROW(NotSupportedError, "color buffer sample count not supported");
265 if (m_data.numColorLayers > imageProperties.maxArrayLayers)
266 TCU_THROW(NotSupportedError, "color buffer layers not supported");
268 if (m_data.useAttachment() && !context.getFragmentShadingRateFeatures().attachmentFragmentShadingRate)
269 TCU_THROW(NotSupportedError, "attachmentFragmentShadingRate not supported");
271 if (!context.getFragmentShadingRateProperties().fragmentShadingRateNonTrivialCombinerOps &&
272 ((m_data.combinerOp[0] != VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR && m_data.combinerOp[0] != VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR) ||
273 (m_data.combinerOp[1] != VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR && m_data.combinerOp[1] != VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR)))
274 TCU_THROW(NotSupportedError, "fragmentShadingRateNonTrivialCombinerOps not supported");
276 if (m_data.conservativeEnable)
278 context.requireDeviceFunctionality("VK_EXT_conservative_rasterization");
279 if (m_data.conservativeMode == VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT &&
280 !context.getConservativeRasterizationPropertiesEXT().primitiveUnderestimation)
281 TCU_THROW(NotSupportedError, "primitiveUnderestimation not supported");
284 if (m_data.fragStencil)
285 context.requireDeviceFunctionality("VK_EXT_shader_stencil_export");
287 if (m_data.multiViewport &&
288 !context.getFragmentShadingRateProperties().primitiveFragmentShadingRateWithMultipleViewports)
289 TCU_THROW(NotSupportedError, "primitiveFragmentShadingRateWithMultipleViewports not supported");
291 if (m_data.srLayered &&
292 !context.getFragmentShadingRateProperties().layeredShadingRateAttachments)
293 TCU_THROW(NotSupportedError, "layeredShadingRateAttachments not supported");
295 if ((m_data.multiViewport || m_data.colorLayered) &&
296 !m_data.geometryShader)
297 context.requireDeviceFunctionality("VK_EXT_shader_viewport_index_layer");
299 if (m_data.multiView && m_data.geometryShader &&
300 !context.getMultiviewFeatures().multiviewGeometryShader)
301 TCU_THROW(NotSupportedError, "multiviewGeometryShader not supported");
303 if (m_data.interlock &&
304 !context.getFragmentShaderInterlockFeaturesEXT().fragmentShaderPixelInterlock)
305 TCU_THROW(NotSupportedError, "fragmentShaderPixelInterlock not supported");
307 if (m_data.sampleLocations)
309 context.requireDeviceFunctionality("VK_EXT_sample_locations");
310 if (!(m_data.samples & context.getSampleLocationsPropertiesEXT().sampleLocationSampleCounts))
311 TCU_THROW(NotSupportedError, "samples not supported in sampleLocationSampleCounts");
314 if (m_data.sampleMaskTest && !context.getFragmentShadingRateProperties().fragmentShadingRateWithSampleMask)
315 TCU_THROW(NotSupportedError, "fragmentShadingRateWithSampleMask not supported");
318 // Error codes writted by the fragment shader
322 ERROR_FRAGCOORD_CENTER = 1,
323 ERROR_VTG_READBACK = 2,
324 ERROR_FRAGCOORD_DERIV = 3,
325 ERROR_FRAGCOORD_IMPLICIT_DERIV = 4,
328 void FSRTestCase::initPrograms (SourceCollections& programCollection) const
330 std::stringstream vss;
333 "#version 450 core\n"
334 "#extension GL_EXT_fragment_shading_rate : enable\n"
335 "#extension GL_ARB_shader_viewport_layer_array : enable\n"
336 "layout(push_constant) uniform PC {\n"
337 " int shadingRate;\n"
339 "layout(location = 0) in vec2 pos;\n"
340 "layout(location = 0) out int instanceIndex;\n"
341 "layout(location = 1) out int readbackok;\n"
342 "layout(location = 2) out float zero;\n"
345 " vec4 gl_Position;\n"
349 " gl_Position = vec4(pos, 0, 1);\n"
350 " instanceIndex = gl_InstanceIndex;\n"
354 if (m_data.shaderWritesRate)
356 vss << " gl_PrimitiveShadingRateEXT = pc.shadingRate;\n";
358 // Verify that we can read from the output variable
359 vss << " if (gl_PrimitiveShadingRateEXT != pc.shadingRate) readbackok = 0;\n";
361 if (!m_data.geometryShader)
363 if (m_data.multiViewport)
364 vss << " gl_ViewportIndex = instanceIndex & 1;\n";
365 if (m_data.colorLayered)
366 vss << " gl_Layer = (instanceIndex & 2) >> 1;\n";
372 programCollection.glslSources.add("vert") << glu::VertexSource(vss.str());
374 if (m_data.geometryShader)
376 std::string writeShadingRate = "";
377 if (m_data.shaderWritesRate)
380 " gl_PrimitiveShadingRateEXT = pc.shadingRate;\n"
381 " if (gl_PrimitiveShadingRateEXT != pc.shadingRate) readbackok = 0;\n";
383 if (m_data.multiViewport)
384 writeShadingRate += " gl_ViewportIndex = inInstanceIndex[0] & 1;\n";
386 if (m_data.colorLayered)
387 writeShadingRate += " gl_Layer = (inInstanceIndex[0] & 2) >> 1;\n";
390 std::stringstream gss;
392 "#version 450 core\n"
393 "#extension GL_EXT_fragment_shading_rate : enable\n"
395 "layout(push_constant) uniform PC {\n"
396 " int shadingRate;\n"
401 " vec4 gl_Position;\n"
404 "layout(location = 0) in int inInstanceIndex[];\n"
405 "layout(location = 0) out int outInstanceIndex;\n"
406 "layout(location = 1) out int readbackok;\n"
407 "layout(location = 2) out float zero;\n"
408 "layout(triangles) in;\n"
409 "layout(triangle_strip, max_vertices=3) out;\n"
411 "out gl_PerVertex {\n"
412 " vec4 gl_Position;\n"
417 " gl_Position = gl_in[0].gl_Position;\n"
418 " outInstanceIndex = inInstanceIndex[0];\n"
421 << writeShadingRate <<
424 " gl_Position = gl_in[1].gl_Position;\n"
425 " outInstanceIndex = inInstanceIndex[1];\n"
428 << writeShadingRate <<
431 " gl_Position = gl_in[2].gl_Position;\n"
432 " outInstanceIndex = inInstanceIndex[2];\n"
435 << writeShadingRate <<
439 programCollection.glslSources.add("geom") << glu::GeometrySource(gss.str());
442 std::stringstream fss;
445 "#version 450 core\n"
446 "#extension GL_EXT_fragment_shading_rate : enable\n"
447 "#extension GL_ARB_shader_stencil_export : enable\n"
448 "#extension GL_ARB_fragment_shader_interlock : enable\n"
449 "layout(location = 0) out uvec4 col0;\n"
450 "layout(set = 0, binding = 0) buffer Block { uint counter; } buf;\n"
451 "layout(set = 0, binding = 3) uniform usampler2D tex;\n"
452 "layout(location = 0) flat in int instanceIndex;\n"
453 "layout(location = 1) flat in int readbackok;\n"
454 "layout(location = 2) " << (m_data.sampleShadingInput ? "sample " : "") << "in float zero;\n";
456 if (m_data.interlock)
457 fss << "layout(pixel_interlock_ordered) in;\n";
463 if (m_data.interlock)
464 fss << " beginInvocationInterlockARB();\n";
467 // X component gets shading rate enum
468 " col0.x = gl_ShadingRateEXT;\n"
470 // Z component gets packed primitiveID | atomic value
471 " col0.z = (instanceIndex << 24) | ((atomicAdd(buf.counter, 1) + 1) & 0x00FFFFFFu);\n"
472 " ivec2 fragCoordXY = ivec2(gl_FragCoord.xy);\n"
473 " ivec2 fragSize = ivec2(1<<((gl_ShadingRateEXT/4)&3), 1<<(gl_ShadingRateEXT&3));\n"
474 // W component gets error code
475 " col0.w = uint(zero)" << (m_data.sampleShadingInput ? " * gl_SampleID" : "") << ";\n"
476 " if (((fragCoordXY - fragSize / 2) % fragSize) != ivec2(0,0))\n"
477 " col0.w = " << ERROR_FRAGCOORD_CENTER << ";\n";
479 if (m_data.shaderWritesRate)
482 " if (readbackok != 1)\n"
483 " col0.w = " << ERROR_VTG_READBACK << ";\n";
486 // When sample shading, gl_FragCoord is more likely to give bad derivatives,
487 // e.g. due to a partially covered quad having some pixels center sample and
488 // some sample at a sample location.
489 if (!m_data.sampleShadingEnable && !m_data.sampleShadingInput)
491 fss << " if (dFdx(gl_FragCoord.xy) != ivec2(fragSize.x, 0) || dFdy(gl_FragCoord.xy) != ivec2(0, fragSize.y))\n"
492 " col0.w = (fragSize.y << 26) | (fragSize.x << 20) | (int(dFdx(gl_FragCoord.xy)) << 14) | (int(dFdx(gl_FragCoord.xy)) << 8) | " << ERROR_FRAGCOORD_DERIV << ";\n";
494 fss << " uint implicitDerivX = texture(tex, vec2(gl_FragCoord.x / textureSize(tex, 0).x, 0)).x;\n"
495 " uint implicitDerivY = texture(tex, vec2(0, gl_FragCoord.y / textureSize(tex, 0).y)).x;\n"
496 " if (implicitDerivX != fragSize.x || implicitDerivY != fragSize.y)\n"
497 " col0.w = (fragSize.y << 26) | (fragSize.x << 20) | (implicitDerivY << 14) | (implicitDerivX << 8) | " << ERROR_FRAGCOORD_IMPLICIT_DERIV << ";\n";
499 // Y component gets sample mask value
500 if (m_data.useSampleMaskIn)
501 fss << " col0.y = gl_SampleMaskIn[0];\n";
503 if (m_data.fragDepth)
504 fss << " gl_FragDepth = float(instanceIndex) / float(" << NUM_TRIANGLES << ");\n";
506 if (m_data.fragStencil)
507 fss << " gl_FragStencilRefARB = instanceIndex;\n";
509 if (m_data.interlock)
510 fss << " endInvocationInterlockARB();\n";
515 programCollection.glslSources.add("frag") << glu::FragmentSource(fss.str());
517 std::stringstream css;
519 std::string fsampType = m_data.samples > 1 ? "texture2DMSArray" : "texture2DArray";
520 std::string usampType = m_data.samples > 1 ? "utexture2DMSArray" : "utexture2DArray";
522 // Compute shader copies color/depth/stencil to linear layout in buffer memory
524 "#version 450 core\n"
525 "#extension GL_EXT_samplerless_texture_functions : enable\n"
526 "layout(set = 0, binding = 1) uniform " << usampType << " colorTex;\n"
527 "layout(set = 0, binding = 2, std430) buffer Block0 { uvec4 b[]; } colorbuf;\n"
528 "layout(set = 0, binding = 4, std430) buffer Block1 { float b[]; } depthbuf;\n"
529 "layout(set = 0, binding = 5, std430) buffer Block2 { uint b[]; } stencilbuf;\n"
530 "layout(set = 0, binding = 6) uniform " << fsampType << " depthTex;\n"
531 "layout(set = 0, binding = 7) uniform " << usampType << " stencilTex;\n"
532 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
535 " for (int i = 0; i < " << m_data.samples << "; ++i) {\n"
536 " uint idx = ((gl_GlobalInvocationID.z * " << m_data.framebufferDim.height << " + gl_GlobalInvocationID.y) * " << m_data.framebufferDim.width << " + gl_GlobalInvocationID.x) * " << m_data.samples << " + i;\n"
537 " colorbuf.b[idx] = texelFetch(colorTex, ivec3(gl_GlobalInvocationID.xyz), i);\n";
539 if (m_data.fragDepth)
540 css << " depthbuf.b[idx] = texelFetch(depthTex, ivec3(gl_GlobalInvocationID.xyz), i).x;\n";
542 if (m_data.fragStencil)
543 css << " stencilbuf.b[idx] = texelFetch(stencilTex, ivec3(gl_GlobalInvocationID.xyz), i).x;\n";
549 programCollection.glslSources.add("comp") << glu::ComputeSource(css.str());
552 TestInstance* FSRTestCase::createInstance (Context& context) const
554 return new FSRTestInstance(context, m_data);
557 deInt32 FSRTestInstance::ShadingRateExtentToEnum(VkExtent2D ext) const
559 ext.width = deCtz32(ext.width);
560 ext.height = deCtz32(ext.height);
562 return (ext.width << 2) | ext.height;
565 VkExtent2D FSRTestInstance::ShadingRateEnumToExtent(deInt32 rate) const
568 ret.width = 1 << ((rate/4) & 3);
569 ret.height = 1 << (rate & 3);
574 VkExtent2D FSRTestInstance::Combine(VkExtent2D ext0, VkExtent2D ext1, VkFragmentShadingRateCombinerOpKHR comb) const
582 case VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR:
584 case VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR:
586 case VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MIN_KHR:
587 ret = { de::min(ext0.width, ext1.width), de::min(ext0.height, ext1.height) };
589 case VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_KHR:
590 ret = { de::max(ext0.width, ext1.width), de::max(ext0.height, ext1.height) };
592 case VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_KHR:
593 ret = { ext0.width * ext1.width, ext0.height * ext1.height };
594 if (!m_shadingRateProperties.fragmentShadingRateStrictMultiplyCombiner)
596 if (ext0.width == 1 && ext1.width == 1)
598 if (ext0.height == 1 && ext1.height == 1)
605 deInt32 FSRTestInstance::Simulate(deInt32 rate0, deInt32 rate1, deInt32 rate2)
607 deInt32 &cachedRate = m_simulateCache[(rate2*m_simulateValueCount + rate1)*m_simulateValueCount + rate0];
608 if (cachedRate != ~0)
611 VkExtent2D extent0 = ShadingRateEnumToExtent(rate0);
612 VkExtent2D extent1 = ShadingRateEnumToExtent(rate1);
613 VkExtent2D extent2 = ShadingRateEnumToExtent(rate2);
615 deInt32 finalMask = 0;
616 // Simulate once for implementations that don't allow swapping rate xy,
617 // and once for those that do. Any of those results is allowed.
618 for (deUint32 allowSwap = 0; allowSwap <= 1; ++allowSwap)
620 // Combine rate 0 and 1, get a mask of possible clamped rates
621 VkExtent2D intermed = Combine(extent0, extent1, m_data.combinerOp[0]);
622 deInt32 intermedMask = ShadingRateExtentToClampedMask(intermed, allowSwap == 1);
624 // For each clamped rate, combine that with rate 2 and accumulate the possible clamped rates
625 for (int i = 0; i < 16; ++i)
627 if (intermedMask & (1<<i))
629 VkExtent2D final = Combine(ShadingRateEnumToExtent(i), extent2, m_data.combinerOp[1]);
630 finalMask |= ShadingRateExtentToClampedMask(final, allowSwap == 1);
634 // unclamped intermediate value is also permitted
635 VkExtent2D final = Combine(intermed, extent2, m_data.combinerOp[1]);
636 finalMask |= ShadingRateExtentToClampedMask(final, allowSwap == 1);
643 cachedRate = finalMask;
647 // If a rate is not valid (<=4x4), clamp it to something valid.
648 // This is only used for "inputs" to the system, not to mimic
649 // how the implementation internally clamps intermediate values.
650 VkExtent2D FSRTestInstance::SanitizeExtent(VkExtent2D ext) const
652 DE_ASSERT(ext.width > 0 && ext.height > 0);
654 ext.width = de::min(ext.width, 4u);
655 ext.height = de::min(ext.height, 4u);
660 // Map an extent to a mask of all modes smaller than or equal to it in either dimension
661 deInt32 FSRTestInstance::ShadingRateExtentToClampedMask(VkExtent2D ext, bool allowSwap) const
663 deUint32 desiredSize = ext.width * ext.height;
667 while (desiredSize > 0)
669 // First, find modes that maximize the area
670 for (deUint32 i = 0; i < m_supportedFragmentShadingRateCount; ++i)
672 const VkPhysicalDeviceFragmentShadingRateKHR &supportedRate = m_supportedFragmentShadingRates[i];
673 if ((supportedRate.sampleCounts & m_data.samples) &&
674 supportedRate.fragmentSize.width * supportedRate.fragmentSize.height == desiredSize &&
675 ((supportedRate.fragmentSize.width <= ext.width && supportedRate.fragmentSize.height <= ext.height) ||
676 (supportedRate.fragmentSize.height <= ext.width && supportedRate.fragmentSize.width <= ext.height && allowSwap)))
678 mask |= 1 << ShadingRateExtentToEnum(supportedRate.fragmentSize);
683 // Amongst the modes that maximize the area, pick the ones that
684 // minimize the aspect ratio. Prefer ratio of 1, then 2, then 4.
685 // 1x1 = 0, 2x2 = 5, 4x4 = 10
686 static const deUint32 aspectMaskRatio1 = 0x421;
687 // 2x1 = 4, 1x2 = 1, 4x2 = 9, 2x4 = 6
688 static const deUint32 aspectMaskRatio2 = 0x252;
690 static const deUint32 aspectMaskRatio4 = 0x104;
692 if (mask & aspectMaskRatio1)
694 mask &= aspectMaskRatio1;
697 if (mask & aspectMaskRatio2)
699 mask &= aspectMaskRatio2;
702 if (mask & aspectMaskRatio4)
704 mask &= aspectMaskRatio4;
716 deInt32 FSRTestInstance::SanitizeRate(deInt32 rate) const
718 VkExtent2D extent = ShadingRateEnumToExtent(rate);
720 extent = SanitizeExtent(extent);
722 return ShadingRateExtentToEnum(extent);
725 // Map primID % 9 to primitive shading rate
726 deInt32 FSRTestInstance::PrimIDToPrimitiveShadingRate(deInt32 primID)
728 deInt32 &cachedRate = m_primIDToPrimitiveShadingRate[primID];
729 if (cachedRate != ~0)
733 extent.width = 1 << (primID % 3);
734 extent.height = 1 << ((primID/3) % 3);
736 cachedRate = ShadingRateExtentToEnum(extent);
740 // Map primID / 9 to pipeline shading rate
741 deInt32 FSRTestInstance::PrimIDToPipelineShadingRate(deInt32 primID)
743 deInt32 &cachedRate = m_primIDToPipelineShadingRate[primID];
744 if (cachedRate != ~0)
749 extent.width = 1 << (primID % 3);
750 extent.height = 1 << ((primID/3) % 3);
752 cachedRate = ShadingRateExtentToEnum(extent);
756 static de::MovePtr<BufferWithMemory> CreateCachedBuffer(const vk::DeviceInterface& vk,
757 const vk::VkDevice device,
758 vk::Allocator& allocator,
759 const vk::VkBufferCreateInfo& bufferCreateInfo)
763 return de::MovePtr<BufferWithMemory>(new BufferWithMemory(
764 vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Cached));
766 catch (const tcu::NotSupportedError&)
768 return de::MovePtr<BufferWithMemory>(new BufferWithMemory(
769 vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible));
773 tcu::TestStatus FSRTestInstance::iterate (void)
775 const DeviceInterface& vk = m_context.getDeviceInterface();
776 const VkDevice device = m_context.getDevice();
777 tcu::TestLog& log = m_context.getTestContext().getLog();
778 Allocator& allocator = m_context.getDefaultAllocator();
779 VkFlags allShaderStages = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT;
780 VkFlags allPipelineStages = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
781 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
782 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
783 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
784 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
785 VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT |
786 VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV;
787 const VkFormat cbFormat = VK_FORMAT_R32G32B32A32_UINT;
788 const VkFormat dsFormat = VK_FORMAT_D32_SFLOAT_S8_UINT;
790 if (m_data.geometryShader)
792 allShaderStages |= VK_SHADER_STAGE_GEOMETRY_BIT;
793 allPipelineStages |= VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
797 deRandom_init(&rnd, m_data.seed);
799 qpTestResult res = QP_TEST_RESULT_PASS;
800 deUint32 numUnexpected1x1Samples = 0;
801 deUint32 numTotalSamples = 0;
805 ATTACHMENT_MODE_DEFAULT = 0,
806 ATTACHMENT_MODE_LAYOUT_OPTIMAL,
807 ATTACHMENT_MODE_IMAGELESS,
808 ATTACHMENT_MODE_2DARRAY,
809 ATTACHMENT_MODE_TILING_LINEAR,
811 ATTACHMENT_MODE_COUNT,
814 deUint32 numSRLayers = m_data.srLayered ? 2u : 1u;
816 VkExtent2D minFragmentShadingRateAttachmentTexelSize = {1, 1};
817 VkExtent2D maxFragmentShadingRateAttachmentTexelSize = {1, 1};
818 deUint32 maxFragmentShadingRateAttachmentTexelSizeAspectRatio = 1;
819 if (m_context.getFragmentShadingRateFeatures().attachmentFragmentShadingRate)
821 minFragmentShadingRateAttachmentTexelSize = m_context.getFragmentShadingRateProperties().minFragmentShadingRateAttachmentTexelSize;
822 maxFragmentShadingRateAttachmentTexelSize = m_context.getFragmentShadingRateProperties().maxFragmentShadingRateAttachmentTexelSize;
823 maxFragmentShadingRateAttachmentTexelSizeAspectRatio = m_context.getFragmentShadingRateProperties().maxFragmentShadingRateAttachmentTexelSizeAspectRatio;
826 VkDeviceSize atomicBufferSize = sizeof(deUint32);
828 de::MovePtr<BufferWithMemory> atomicBuffer;
829 atomicBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
830 vk, device, allocator, makeBufferCreateInfo(atomicBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible | MemoryRequirement::Coherent));
832 deUint32 *abuf = (deUint32 *)atomicBuffer->getAllocation().getHostPtr();
834 // NUM_TRIANGLES triangles, 3 vertices, 2 components of float position
835 VkDeviceSize vertexBufferSize = NUM_TRIANGLES * 3 * 2 * sizeof(float);
837 de::MovePtr<BufferWithMemory> vertexBuffer;
838 vertexBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
839 vk, device, allocator, makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible | MemoryRequirement::Coherent));
841 float *vbuf = (float *)vertexBuffer->getAllocation().getHostPtr();
842 for (deInt32 i = 0; i < (deInt32)(vertexBufferSize / sizeof(float)); ++i)
844 vbuf[i] = deRandom_getFloat(&rnd)*2.0f - 1.0f;
846 flushAlloc(vk, device, vertexBuffer->getAllocation());
848 VkDeviceSize colorOutputBufferSize = m_data.framebufferDim.width * m_data.framebufferDim.height * m_data.samples * 4 * sizeof(deUint32) * m_data.numColorLayers;
849 de::MovePtr<BufferWithMemory> colorOutputBuffer = CreateCachedBuffer(vk, device, allocator, makeBufferCreateInfo(colorOutputBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT));
851 VkDeviceSize depthOutputBufferSize = 0, stencilOutputBufferSize = 0;
852 de::MovePtr<BufferWithMemory> depthOutputBuffer, stencilOutputBuffer;
853 if (m_data.useDepthStencil)
855 depthOutputBufferSize = m_data.framebufferDim.width * m_data.framebufferDim.height * m_data.samples * sizeof(float) * m_data.numColorLayers;
856 depthOutputBuffer = CreateCachedBuffer(vk, device, allocator, makeBufferCreateInfo(depthOutputBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT));
858 stencilOutputBufferSize = m_data.framebufferDim.width * m_data.framebufferDim.height * m_data.samples * sizeof(deUint32) * m_data.numColorLayers;
859 stencilOutputBuffer = CreateCachedBuffer(vk, device, allocator, makeBufferCreateInfo(stencilOutputBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT));
862 deUint32 minSRTexelWidth = minFragmentShadingRateAttachmentTexelSize.width;
863 deUint32 minSRTexelHeight = minFragmentShadingRateAttachmentTexelSize.height;
864 deUint32 maxSRWidth = (m_data.framebufferDim.width + minSRTexelWidth - 1) / minSRTexelWidth;
865 deUint32 maxSRHeight = (m_data.framebufferDim.height + minSRTexelHeight - 1) / minSRTexelHeight;
867 // max size over all formats
868 VkDeviceSize srFillBufferSize = numSRLayers * maxSRWidth * maxSRHeight * 32/*4 component 64-bit*/;
869 de::MovePtr<BufferWithMemory> srFillBuffer;
870 deUint8 *fillPtr = DE_NULL;
871 if (m_data.useAttachment())
873 srFillBuffer = CreateCachedBuffer(vk, device, allocator, makeBufferCreateInfo(srFillBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT));
874 fillPtr = (deUint8 *)srFillBuffer->getAllocation().getHostPtr();
877 de::MovePtr<ImageWithMemory> cbImage;
878 Move<VkImageView> cbImageView;
880 const VkImageCreateInfo imageCreateInfo =
882 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
883 DE_NULL, // const void* pNext;
884 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
885 VK_IMAGE_TYPE_2D, // VkImageType imageType;
886 cbFormat, // VkFormat format;
888 m_data.framebufferDim.width, // deUint32 width;
889 m_data.framebufferDim.height, // deUint32 height;
890 1u // deUint32 depth;
891 }, // VkExtent3D extent;
892 1u, // deUint32 mipLevels;
893 m_data.numColorLayers, // deUint32 arrayLayers;
894 m_data.samples, // VkSampleCountFlagBits samples;
895 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
896 cbUsage, // VkImageUsageFlags usage;
897 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
898 0u, // deUint32 queueFamilyIndexCount;
899 DE_NULL, // const deUint32* pQueueFamilyIndices;
900 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
902 cbImage = de::MovePtr<ImageWithMemory>(new ImageWithMemory(
903 vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
905 VkImageViewCreateInfo imageViewCreateInfo =
907 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
908 DE_NULL, // const void* pNext;
909 (VkImageViewCreateFlags)0u, // VkImageViewCreateFlags flags;
910 **cbImage, // VkImage image;
911 VK_IMAGE_VIEW_TYPE_2D_ARRAY, // VkImageViewType viewType;
912 cbFormat, // VkFormat format;
914 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
915 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
916 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
917 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
918 }, // VkComponentMapping components;
920 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
921 0u, // deUint32 baseMipLevel;
922 1u, // deUint32 levelCount;
923 0u, // deUint32 baseArrayLayer;
924 m_data.numColorLayers // deUint32 layerCount;
925 } // VkImageSubresourceRange subresourceRange;
927 cbImageView = createImageView(vk, device, &imageViewCreateInfo, NULL);
930 de::MovePtr<ImageWithMemory> dsImage;
931 Move<VkImageView> dsImageView, dImageView, sImageView;
932 VkImageUsageFlags dsUsage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
933 VK_IMAGE_USAGE_SAMPLED_BIT |
934 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
935 VK_IMAGE_USAGE_TRANSFER_DST_BIT;
936 if (m_data.useDepthStencil)
938 const VkImageCreateInfo imageCreateInfo =
940 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
941 DE_NULL, // const void* pNext;
942 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
943 VK_IMAGE_TYPE_2D, // VkImageType imageType;
944 dsFormat, // VkFormat format;
946 m_data.framebufferDim.width, // deUint32 width;
947 m_data.framebufferDim.height, // deUint32 height;
948 1u // deUint32 depth;
949 }, // VkExtent3D extent;
950 1u, // deUint32 mipLevels;
951 m_data.numColorLayers, // deUint32 arrayLayers;
952 m_data.samples, // VkSampleCountFlagBits samples;
953 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
954 dsUsage, // VkImageUsageFlags usage;
955 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
956 0u, // deUint32 queueFamilyIndexCount;
957 DE_NULL, // const deUint32* pQueueFamilyIndices;
958 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
960 dsImage = de::MovePtr<ImageWithMemory>(new ImageWithMemory(
961 vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
963 VkImageViewCreateInfo imageViewCreateInfo =
965 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
966 DE_NULL, // const void* pNext;
967 (VkImageViewCreateFlags)0u, // VkImageViewCreateFlags flags;
968 **dsImage, // VkImage image;
969 VK_IMAGE_VIEW_TYPE_2D_ARRAY, // VkImageViewType viewType;
970 dsFormat, // VkFormat format;
972 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
973 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
974 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
975 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
976 }, // VkComponentMapping components;
978 VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags aspectMask;
979 0u, // deUint32 baseMipLevel;
980 1u, // deUint32 levelCount;
981 0u, // deUint32 baseArrayLayer;
982 m_data.numColorLayers // deUint32 layerCount;
983 } // VkImageSubresourceRange subresourceRange;
985 dsImageView = createImageView(vk, device, &imageViewCreateInfo, NULL);
986 imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
987 dImageView = createImageView(vk, device, &imageViewCreateInfo, NULL);
988 imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
989 sImageView = createImageView(vk, device, &imageViewCreateInfo, NULL);
992 // Image used to test implicit derivative calculations.
993 // Filled with a value of 1<<lod.
994 de::MovePtr<ImageWithMemory> derivImage;
995 Move<VkImageView> derivImageView;
996 VkImageUsageFlags derivUsage = VK_IMAGE_USAGE_SAMPLED_BIT |
997 VK_IMAGE_USAGE_TRANSFER_DST_BIT;
998 deUint32 derivNumLevels;
1000 deUint32 maxDim = de::max(m_context.getFragmentShadingRateProperties().maxFragmentSize.width, m_context.getFragmentShadingRateProperties().maxFragmentSize.height);
1001 derivNumLevels = 1 + deCtz32(maxDim);
1002 const VkImageCreateInfo imageCreateInfo =
1004 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1005 DE_NULL, // const void* pNext;
1006 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
1007 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1008 VK_FORMAT_R32_UINT, // VkFormat format;
1010 m_context.getFragmentShadingRateProperties().maxFragmentSize.width, // deUint32 width;
1011 m_context.getFragmentShadingRateProperties().maxFragmentSize.height, // deUint32 height;
1012 1u // deUint32 depth;
1013 }, // VkExtent3D extent;
1014 derivNumLevels, // deUint32 mipLevels;
1015 1u, // deUint32 arrayLayers;
1016 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
1017 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1018 derivUsage, // VkImageUsageFlags usage;
1019 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1020 0u, // deUint32 queueFamilyIndexCount;
1021 DE_NULL, // const deUint32* pQueueFamilyIndices;
1022 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
1024 derivImage = de::MovePtr<ImageWithMemory>(new ImageWithMemory(
1025 vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
1027 VkImageViewCreateInfo imageViewCreateInfo =
1029 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1030 DE_NULL, // const void* pNext;
1031 (VkImageViewCreateFlags)0u, // VkImageViewCreateFlags flags;
1032 **derivImage, // VkImage image;
1033 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
1034 VK_FORMAT_R32_UINT, // VkFormat format;
1036 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
1037 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
1038 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
1039 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
1040 }, // VkComponentMapping components;
1042 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1043 0u, // deUint32 baseMipLevel;
1044 derivNumLevels, // deUint32 levelCount;
1045 0u, // deUint32 baseArrayLayer;
1046 1u // deUint32 layerCount;
1047 } // VkImageSubresourceRange subresourceRange;
1049 derivImageView = createImageView(vk, device, &imageViewCreateInfo, NULL);
1052 // sampler used with derivImage
1053 const struct VkSamplerCreateInfo samplerInfo =
1055 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // sType
1058 VK_FILTER_NEAREST, // magFilter
1059 VK_FILTER_NEAREST, // minFilter
1060 VK_SAMPLER_MIPMAP_MODE_NEAREST, // mipmapMode
1061 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeU
1062 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeV
1063 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeW
1065 VK_FALSE, // anisotropyEnable
1066 1.0f, // maxAnisotropy
1067 DE_FALSE, // compareEnable
1068 VK_COMPARE_OP_ALWAYS, // compareOp
1070 (float)derivNumLevels, // maxLod
1071 VK_BORDER_COLOR_INT_TRANSPARENT_BLACK, // borderColor
1072 VK_FALSE, // unnormalizedCoords
1075 Move<VkSampler> sampler = createSampler(vk, device, &samplerInfo);
1077 Move<vk::VkDescriptorSetLayout> descriptorSetLayout;
1078 VkDescriptorSetLayoutCreateFlags layoutCreateFlags = 0;
1080 const VkDescriptorSetLayoutBinding bindings[] =
1084 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // descriptorType
1085 1u, // descriptorCount
1086 allShaderStages, // stageFlags
1087 DE_NULL, // pImmutableSamplers
1091 VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, // descriptorType
1092 1u, // descriptorCount
1093 allShaderStages, // stageFlags
1094 DE_NULL, // pImmutableSamplers
1098 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // descriptorType
1099 1u, // descriptorCount
1100 allShaderStages, // stageFlags
1101 DE_NULL, // pImmutableSamplers
1105 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, // descriptorType
1106 1u, // descriptorCount
1107 allShaderStages, // stageFlags
1108 DE_NULL, // pImmutableSamplers
1112 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // 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_SAMPLED_IMAGE, // 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 // Create a layout and allocate a descriptor set for it.
1141 const VkDescriptorSetLayoutCreateInfo setLayoutCreateInfo =
1143 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // sType
1145 layoutCreateFlags, // flags
1146 sizeof(bindings)/sizeof(bindings[0]), // bindingCount
1147 &bindings[0] // pBindings
1150 descriptorSetLayout = vk::createDescriptorSetLayout(vk, device, &setLayoutCreateInfo);
1152 const VkPushConstantRange pushConstantRange =
1154 allShaderStages, // VkShaderStageFlags stageFlags;
1155 0u, // deUint32 offset;
1156 sizeof(deInt32) // deUint32 size;
1159 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
1161 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType
1163 (VkPipelineLayoutCreateFlags)0,
1164 1, // setLayoutCount
1165 &descriptorSetLayout.get(), // pSetLayouts
1166 1u, // pushConstantRangeCount
1167 &pushConstantRange, // pPushConstantRanges
1170 Move<VkPipelineLayout> pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo, NULL);
1172 const Unique<VkShaderModule> cs (createShaderModule(vk, device, m_context.getBinaryCollection().get("comp"), 0));
1174 const VkPipelineShaderStageCreateInfo csShaderCreateInfo =
1176 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1178 (VkPipelineShaderStageCreateFlags)0,
1179 VK_SHADER_STAGE_COMPUTE_BIT, // stage
1182 DE_NULL, // pSpecializationInfo
1185 const VkComputePipelineCreateInfo pipelineCreateInfo =
1187 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
1190 csShaderCreateInfo, // cs
1191 *pipelineLayout, // layout
1192 (vk::VkPipeline)0, // basePipelineHandle
1193 0u, // basePipelineIndex
1195 Move<VkPipeline> computePipeline = createComputePipeline(vk, device, DE_NULL, &pipelineCreateInfo, NULL);
1197 for (deUint32 modeIdx = 0; modeIdx < ATTACHMENT_MODE_COUNT; ++modeIdx)
1199 // If we're not using an attachment, don't test all the different attachment modes
1200 if (modeIdx != ATTACHMENT_MODE_DEFAULT && !m_data.useAttachment())
1203 // Consider all uint formats possible
1204 static const VkFormat srFillFormats[] =
1207 VK_FORMAT_R8G8_UINT,
1208 VK_FORMAT_R8G8B8_UINT,
1209 VK_FORMAT_R8G8B8A8_UINT,
1211 VK_FORMAT_R16G16_UINT,
1212 VK_FORMAT_R16G16B16_UINT,
1213 VK_FORMAT_R16G16B16A16_UINT,
1215 VK_FORMAT_R32G32_UINT,
1216 VK_FORMAT_R32G32B32_UINT,
1217 VK_FORMAT_R32G32B32A32_UINT,
1219 VK_FORMAT_R64G64_UINT,
1220 VK_FORMAT_R64G64B64_UINT,
1221 VK_FORMAT_R64G64B64A64_UINT,
1223 // Only test all formats in the default mode
1224 deUint32 numFillFormats = modeIdx == ATTACHMENT_MODE_DEFAULT ? (deUint32)(sizeof(srFillFormats)/sizeof(srFillFormats[0])) : 1u;
1226 // Iterate over all supported tile sizes and formats
1227 for (deUint32 srTexelWidth = minFragmentShadingRateAttachmentTexelSize.width;
1228 srTexelWidth <= maxFragmentShadingRateAttachmentTexelSize.width;
1230 for (deUint32 srTexelHeight = minFragmentShadingRateAttachmentTexelSize.height;
1231 srTexelHeight <= maxFragmentShadingRateAttachmentTexelSize.height;
1233 for (deUint32 formatIdx = 0; formatIdx < numFillFormats; ++formatIdx)
1236 deUint32 aspectRatio = (srTexelHeight > srTexelWidth) ? (srTexelHeight / srTexelWidth) : (srTexelWidth / srTexelHeight);
1237 if (aspectRatio > maxFragmentShadingRateAttachmentTexelSizeAspectRatio)
1240 // Go through the loop only once when not using an attachment
1241 if (!m_data.useAttachment() &&
1242 (srTexelWidth != minFragmentShadingRateAttachmentTexelSize.width ||
1243 srTexelHeight != minFragmentShadingRateAttachmentTexelSize.height ||
1247 bool imagelessFB = modeIdx == ATTACHMENT_MODE_IMAGELESS;
1249 deUint32 srWidth = (m_data.framebufferDim.width + srTexelWidth - 1) / srTexelWidth;
1250 deUint32 srHeight = (m_data.framebufferDim.height + srTexelHeight - 1) / srTexelHeight;
1252 VkFormat srFormat = srFillFormats[formatIdx];
1253 deUint32 srFillBpp = tcu::getPixelSize(mapVkFormat(srFormat));
1255 VkImageLayout srLayout = modeIdx == ATTACHMENT_MODE_LAYOUT_OPTIMAL ? VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR : VK_IMAGE_LAYOUT_GENERAL;
1256 VkImageViewType srViewType = modeIdx == ATTACHMENT_MODE_2DARRAY ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D;
1257 VkImageTiling srTiling = (modeIdx == ATTACHMENT_MODE_TILING_LINEAR) ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL;
1259 VkFormatProperties srFormatProperties;
1260 m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), srFormat, &srFormatProperties);
1261 VkFormatFeatureFlags srFormatFeatures = srTiling == VK_IMAGE_TILING_LINEAR ? srFormatProperties.linearTilingFeatures : srFormatProperties.optimalTilingFeatures;
1263 if (m_context.getFragmentShadingRateFeatures().attachmentFragmentShadingRate &&
1264 !(srFormatFeatures & VK_FORMAT_FEATURE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR))
1266 if (srFormat == VK_FORMAT_R8_UINT && srTiling == VK_IMAGE_TILING_OPTIMAL)
1268 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;
1269 res = QP_TEST_RESULT_FAIL;
1274 Move<vk::VkDescriptorPool> descriptorPool;
1275 Move<vk::VkDescriptorSet> descriptorSet;
1276 VkDescriptorPoolCreateFlags poolCreateFlags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
1278 vk::DescriptorPoolBuilder poolBuilder;
1279 for (deInt32 i = 0; i < (deInt32)(sizeof(bindings)/sizeof(bindings[0])); ++i)
1280 poolBuilder.addType(bindings[i].descriptorType, bindings[i].descriptorCount);
1282 descriptorPool = poolBuilder.build(vk, device, poolCreateFlags, 1u);
1283 descriptorSet = makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout);
1285 de::MovePtr<ImageWithMemory> srImage;
1286 Move<VkImageView> srImageView;
1287 VkImageUsageFlags srUsage = VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR |
1288 VK_IMAGE_USAGE_TRANSFER_DST_BIT |
1289 VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1291 if (m_data.useAttachment())
1293 const VkImageCreateInfo imageCreateInfo =
1295 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1296 DE_NULL, // const void* pNext;
1297 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
1298 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1299 srFormat, // VkFormat format;
1301 srWidth, // deUint32 width;
1302 srHeight, // deUint32 height;
1303 1u // deUint32 depth;
1304 }, // VkExtent3D extent;
1305 1u, // deUint32 mipLevels;
1306 numSRLayers, // deUint32 arrayLayers;
1307 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
1308 srTiling, // VkImageTiling tiling;
1309 srUsage, // VkImageUsageFlags usage;
1310 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1311 0u, // deUint32 queueFamilyIndexCount;
1312 DE_NULL, // const deUint32* pQueueFamilyIndices;
1313 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
1315 srImage = de::MovePtr<ImageWithMemory>(new ImageWithMemory(
1316 vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
1318 VkImageViewCreateInfo imageViewCreateInfo =
1320 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1321 DE_NULL, // const void* pNext;
1322 (VkImageViewCreateFlags)0u, // VkImageViewCreateFlags flags;
1323 **srImage, // VkImage image;
1324 srViewType, // VkImageViewType viewType;
1325 srFormat, // VkFormat format;
1327 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
1328 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
1329 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
1330 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
1331 }, // VkComponentMapping components;
1333 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1334 0u, // deUint32 baseMipLevel;
1335 1u, // deUint32 levelCount;
1336 0u, // deUint32 baseArrayLayer;
1337 srViewType == VK_IMAGE_VIEW_TYPE_2D ?
1338 1 : numSRLayers, // deUint32 layerCount;
1339 } // VkImageSubresourceRange subresourceRange;
1341 srImageView = createImageView(vk, device, &imageViewCreateInfo, NULL);
1344 VkDescriptorImageInfo imageInfo;
1345 VkDescriptorBufferInfo bufferInfo;
1347 VkWriteDescriptorSet w =
1349 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
1351 *descriptorSet, // dstSet
1352 (deUint32)0, // dstBinding
1353 0, // dstArrayElement
1354 1u, // descriptorCount
1355 bindings[0].descriptorType, // descriptorType
1356 &imageInfo, // pImageInfo
1357 &bufferInfo, // pBufferInfo
1358 DE_NULL, // pTexelBufferView
1362 flushAlloc(vk, device, atomicBuffer->getAllocation());
1364 bufferInfo = makeDescriptorBufferInfo(**atomicBuffer, 0, atomicBufferSize);
1366 w.descriptorType = bindings[0].descriptorType;
1367 vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1369 imageInfo = makeDescriptorImageInfo(DE_NULL, *cbImageView, VK_IMAGE_LAYOUT_GENERAL);
1371 w.descriptorType = bindings[1].descriptorType;
1372 vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1374 bufferInfo = makeDescriptorBufferInfo(**colorOutputBuffer, 0, colorOutputBufferSize);
1376 w.descriptorType = bindings[2].descriptorType;
1377 vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1379 imageInfo = makeDescriptorImageInfo(*sampler, *derivImageView, VK_IMAGE_LAYOUT_GENERAL);
1381 w.descriptorType = bindings[3].descriptorType;
1382 vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1384 if (m_data.useDepthStencil)
1386 bufferInfo = makeDescriptorBufferInfo(**depthOutputBuffer, 0, depthOutputBufferSize);
1388 w.descriptorType = bindings[4].descriptorType;
1389 vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1391 bufferInfo = makeDescriptorBufferInfo(**stencilOutputBuffer, 0, stencilOutputBufferSize);
1393 w.descriptorType = bindings[5].descriptorType;
1394 vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1396 imageInfo = makeDescriptorImageInfo(DE_NULL, *dImageView, VK_IMAGE_LAYOUT_GENERAL);
1398 w.descriptorType = bindings[6].descriptorType;
1399 vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1401 imageInfo = makeDescriptorImageInfo(DE_NULL, *sImageView, VK_IMAGE_LAYOUT_GENERAL);
1403 w.descriptorType = bindings[7].descriptorType;
1404 vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1407 Move<VkRenderPass> renderPass;
1408 Move<VkFramebuffer> framebuffer;
1410 std::vector<VkImageView> attachments;
1411 attachments.push_back(*cbImageView);
1412 deUint32 dsAttachmentIdx = 0, srAttachmentIdx = 0;
1413 if (m_data.useAttachment())
1415 srAttachmentIdx = (deUint32)attachments.size();
1416 attachments.push_back(*srImageView);
1418 if (m_data.useDepthStencil)
1420 dsAttachmentIdx = (deUint32)attachments.size();
1421 attachments.push_back(*dsImageView);
1424 if (!m_data.useDynamicRendering)
1426 const vk::VkAttachmentReference2 colorAttachmentReference
1428 VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, // sType
1431 vk::VK_IMAGE_LAYOUT_GENERAL, // layout
1435 const vk::VkAttachmentReference2 fragmentShadingRateAttachment =
1437 VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, // sType
1439 srAttachmentIdx, // attachment
1444 const vk::VkAttachmentReference2 depthAttachmentReference =
1446 VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, // sType
1448 dsAttachmentIdx, // attachment
1449 vk::VK_IMAGE_LAYOUT_GENERAL, // layout
1453 const bool noAttachmentPtr = (m_data.attachmentUsage == AttachmentUsage::NO_ATTACHMENT_PTR);
1454 const VkFragmentShadingRateAttachmentInfoKHR shadingRateAttachmentInfo =
1456 VK_STRUCTURE_TYPE_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR, // VkStructureType sType;
1457 DE_NULL, // const void* pNext;
1458 (noAttachmentPtr ? nullptr : &fragmentShadingRateAttachment), // const VkAttachmentReference2* pFragmentShadingRateAttachment;
1459 { srTexelWidth, srTexelHeight }, // VkExtent2D shadingRateAttachmentTexelSize;
1462 const bool useAttachmentInfo = (m_data.attachmentUsage != AttachmentUsage::NO_ATTACHMENT);
1463 const VkSubpassDescription2 subpassDesc =
1465 VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2, // sType
1466 (useAttachmentInfo ? &shadingRateAttachmentInfo : nullptr), // pNext;
1467 (vk::VkSubpassDescriptionFlags)0, // flags
1468 vk::VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
1469 m_data.multiView ? 0x3 : 0u, // viewMask
1471 DE_NULL, // pInputAttachments
1473 &colorAttachmentReference, // pColorAttachments
1474 DE_NULL, // pResolveAttachments
1475 m_data.useDepthStencil ? &depthAttachmentReference : DE_NULL, // depthStencilAttachment
1476 0u, // preserveCount
1477 DE_NULL, // pPreserveAttachments
1480 std::vector<VkAttachmentDescription2> attachmentDescriptions
1483 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, // VkStructureType sType;
1484 DE_NULL, // const void* pNext;
1485 (VkAttachmentDescriptionFlags)0u, // VkAttachmentDescriptionFlags flags;
1486 cbFormat, // VkFormat format;
1487 m_data.samples, // VkSampleCountFlagBits samples;
1488 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
1489 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
1490 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
1491 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
1492 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout initialLayout;
1493 VK_IMAGE_LAYOUT_GENERAL // VkImageLayout finalLayout;
1496 if (m_data.useAttachment())
1497 attachmentDescriptions.push_back(
1499 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, // VkStructureType sType;
1500 DE_NULL, // const void* pNext;
1501 (VkAttachmentDescriptionFlags)0u, // VkAttachmentDescriptionFlags flags;
1502 srFormat, // VkFormat format;
1503 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
1504 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
1505 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
1506 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
1507 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
1508 srLayout, // VkImageLayout initialLayout;
1509 srLayout // VkImageLayout finalLayout;
1513 if (m_data.useDepthStencil)
1514 attachmentDescriptions.push_back(
1516 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, // VkStructureType sType;
1517 DE_NULL, // const void* pNext;
1518 (VkAttachmentDescriptionFlags)0u, // VkAttachmentDescriptionFlags flags;
1519 dsFormat, // VkFormat format;
1520 m_data.samples, // VkSampleCountFlagBits samples;
1521 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
1522 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
1523 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp stencilLoadOp;
1524 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp;
1525 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout initialLayout;
1526 VK_IMAGE_LAYOUT_GENERAL // VkImageLayout finalLayout;
1530 const VkRenderPassCreateInfo2 renderPassParams =
1532 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2, // sType
1534 (vk::VkRenderPassCreateFlags)0,
1535 (deUint32)attachmentDescriptions.size(), // attachmentCount
1536 &attachmentDescriptions[0], // pAttachments
1538 &subpassDesc, // pSubpasses
1539 0u, // dependencyCount
1540 DE_NULL, // pDependencies
1541 0u, // correlatedViewMaskCount
1542 DE_NULL, // pCorrelatedViewMasks
1545 renderPass = createRenderPass2(vk, device, &renderPassParams);
1547 std::vector<VkFramebufferAttachmentImageInfo> framebufferAttachmentImageInfo;
1548 framebufferAttachmentImageInfo.push_back(
1550 VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO, // VkStructureType sType;
1551 DE_NULL, // const void* pNext;
1552 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
1553 cbUsage, // VkImageUsageFlags usage;
1554 m_data.framebufferDim.width, // deUint32 width;
1555 m_data.framebufferDim.height, // deUint32 height;
1556 m_data.numColorLayers, // deUint32 layerCount;
1557 1u, // deUint32 viewFormatCount;
1558 &cbFormat // const VkFormat* pViewFormats;
1561 if (m_data.useAttachment())
1562 framebufferAttachmentImageInfo.push_back(
1564 VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO, // VkStructureType sType;
1565 DE_NULL, // const void* pNext;
1566 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
1567 srUsage, // VkImageUsageFlags usage;
1568 srWidth, // deUint32 width;
1569 srHeight, // deUint32 height;
1570 numSRLayers, // deUint32 layerCount;
1571 1u, // deUint32 viewFormatCount;
1572 &srFormat // const VkFormat* pViewFormats;
1576 if (m_data.useDepthStencil)
1577 framebufferAttachmentImageInfo.push_back(
1579 VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO, // VkStructureType sType;
1580 DE_NULL, // const void* pNext;
1581 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
1582 dsUsage, // VkImageUsageFlags usage;
1583 m_data.framebufferDim.width, // deUint32 width;
1584 m_data.framebufferDim.height, // deUint32 height;
1585 m_data.numColorLayers, // deUint32 layerCount;
1586 1u, // deUint32 viewFormatCount;
1587 &dsFormat // const VkFormat* pViewFormats;
1591 const VkFramebufferAttachmentsCreateInfo framebufferAttachmentsCreateInfo =
1593 VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO, // VkStructureType sType;
1594 DE_NULL, // const void* pNext;
1595 (deUint32)framebufferAttachmentImageInfo.size(), // deUint32 attachmentImageInfoCount;
1596 &framebufferAttachmentImageInfo[0] // const VkFramebufferAttachmentImageInfo* pAttachmentImageInfos;
1599 const vk::VkFramebufferCreateInfo framebufferParams =
1601 vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // sType
1602 imagelessFB ? &framebufferAttachmentsCreateInfo : DE_NULL, // pNext
1603 (vk::VkFramebufferCreateFlags)(imagelessFB ? VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT : 0),
1604 *renderPass, // renderPass
1605 (deUint32)attachments.size(), // attachmentCount
1606 imagelessFB ? DE_NULL : &attachments[0], // pAttachments
1607 m_data.framebufferDim.width, // width
1608 m_data.framebufferDim.height, // height
1609 m_data.multiView ? 1 : m_data.numColorLayers, // layers
1612 framebuffer = createFramebuffer(vk, device, &framebufferParams);
1615 const VkVertexInputBindingDescription vertexBinding =
1617 0u, // deUint32 binding;
1618 sizeof(float) * 2, // deUint32 stride;
1619 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate;
1621 const VkVertexInputAttributeDescription vertexInputAttributeDescription =
1623 0u, // deUint32 location;
1624 0u, // deUint32 binding;
1625 VK_FORMAT_R32G32_SFLOAT, // VkFormat format;
1626 0u // deUint32 offset;
1629 const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo =
1631 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1632 DE_NULL, // const void* pNext;
1633 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
1634 1u, // deUint32 vertexBindingDescriptionCount;
1635 &vertexBinding, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1636 1u, // deUint32 vertexAttributeDescriptionCount;
1637 &vertexInputAttributeDescription // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
1640 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo =
1642 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
1643 DE_NULL, // const void* pNext;
1644 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
1645 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology;
1646 VK_FALSE // VkBool32 primitiveRestartEnable;
1649 const VkPipelineRasterizationConservativeStateCreateInfoEXT consRastState =
1651 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT, // VkStructureType sType;
1652 DE_NULL, // const void* pNext;
1653 (VkPipelineRasterizationConservativeStateCreateFlagsEXT)0, // VkPipelineRasterizationConservativeStateCreateFlagsEXT flags;
1654 m_data.conservativeMode, // VkConservativeRasterizationModeEXT conservativeRasterizationMode;
1655 0.0f, // float extraPrimitiveOverestimationSize;
1658 const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
1660 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
1661 m_data.conservativeEnable ? &consRastState : DE_NULL, // const void* pNext;
1662 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
1663 VK_FALSE, // VkBool32 depthClampEnable;
1664 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
1665 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
1666 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
1667 VK_FRONT_FACE_CLOCKWISE, // VkFrontFace frontFace;
1668 VK_FALSE, // VkBool32 depthBiasEnable;
1669 0.0f, // float depthBiasConstantFactor;
1670 0.0f, // float depthBiasClamp;
1671 0.0f, // float depthBiasSlopeFactor;
1672 1.0f // float lineWidth;
1675 // Kill some bits from each AA mode
1676 const VkSampleMask sampleMask = m_data.sampleMaskTest ? 0x9 : 0x7D56;
1677 const VkSampleMask* pSampleMask = m_data.useApiSampleMask ? &sampleMask : DE_NULL;
1679 // All samples at pixel center. We'll validate that pixels are fully covered or uncovered.
1680 std::vector<VkSampleLocationEXT> sampleLocations(m_data.samples, { 0.5f, 0.5f });
1681 const VkSampleLocationsInfoEXT sampleLocationsInfo =
1683 VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT, // VkStructureType sType;
1684 DE_NULL, // const void* pNext;
1685 (VkSampleCountFlagBits)m_data.samples, // VkSampleCountFlagBits sampleLocationsPerPixel;
1686 { 1, 1 }, // VkExtent2D sampleLocationGridSize;
1687 (deUint32)m_data.samples, // uint32_t sampleLocationsCount;
1688 &sampleLocations[0], // const VkSampleLocationEXT* pSampleLocations;
1691 const VkPipelineSampleLocationsStateCreateInfoEXT pipelineSampleLocationsCreateInfo =
1693 VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT, // VkStructureType sType;
1694 DE_NULL, // const void* pNext;
1695 VK_TRUE, // VkBool32 sampleLocationsEnable;
1696 sampleLocationsInfo, // VkSampleLocationsInfoEXT sampleLocationsInfo;
1699 const VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfo =
1701 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType
1702 m_data.sampleLocations ? &pipelineSampleLocationsCreateInfo : DE_NULL, // const void* pNext
1703 0u, // VkPipelineMultisampleStateCreateFlags flags
1704 (VkSampleCountFlagBits)m_data.samples, // VkSampleCountFlagBits rasterizationSamples
1705 (VkBool32)m_data.sampleShadingEnable, // VkBool32 sampleShadingEnable
1706 1.0f, // float minSampleShading
1707 pSampleMask, // const VkSampleMask* pSampleMask
1708 VK_FALSE, // VkBool32 alphaToCoverageEnable
1709 VK_FALSE // VkBool32 alphaToOneEnable
1712 std::vector<VkViewport> viewports;
1713 std::vector<VkRect2D> scissors;
1714 if (m_data.multiViewport)
1716 // Split the viewport into left and right halves
1717 int x0 = 0, x1 = m_data.framebufferDim.width/2, x2 = m_data.framebufferDim.width;
1719 viewports.push_back(makeViewport((float)x0, 0, std::max((float)(x1 - x0), 1.0f), (float)m_data.framebufferDim.height, 0.0f, 1.0f));
1720 scissors.push_back(makeRect2D(x0, 0, x1 - x0, m_data.framebufferDim.height));
1722 viewports.push_back(makeViewport((float)x1, 0, std::max((float)(x2 - x1), 1.0f), (float)m_data.framebufferDim.height, 0.0f, 1.0f));
1723 scissors.push_back(makeRect2D(x1, 0, x2 - x1, m_data.framebufferDim.height));
1727 viewports.push_back(makeViewport(m_data.framebufferDim.width, m_data.framebufferDim.height));
1728 scissors.push_back(makeRect2D(m_data.framebufferDim.width, m_data.framebufferDim.height));
1731 const VkPipelineViewportStateCreateInfo viewportStateCreateInfo =
1733 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType
1734 DE_NULL, // const void* pNext
1735 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags
1736 (deUint32)viewports.size(), // deUint32 viewportCount
1737 &viewports[0], // const VkViewport* pViewports
1738 (deUint32)scissors.size(), // deUint32 scissorCount
1739 &scissors[0] // const VkRect2D* pScissors
1742 Move<VkShaderModule> fragShader = createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0);
1743 Move<VkShaderModule> vertShader = createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0);
1744 Move<VkShaderModule> geomShader;
1745 if (m_data.geometryShader)
1746 geomShader = createShaderModule(vk, device, m_context.getBinaryCollection().get("geom"), 0);
1748 deUint32 numStages = m_data.geometryShader ? 3 : 2u;
1750 const VkPipelineShaderStageCreateInfo shaderCreateInfo[3] =
1753 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1755 (VkPipelineShaderStageCreateFlags)0,
1756 VK_SHADER_STAGE_VERTEX_BIT, // stage
1757 *vertShader, // shader
1759 DE_NULL, // pSpecializationInfo
1762 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1764 (VkPipelineShaderStageCreateFlags)0,
1765 VK_SHADER_STAGE_FRAGMENT_BIT, // stage
1766 *fragShader, // shader
1768 DE_NULL, // pSpecializationInfo
1771 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1773 (VkPipelineShaderStageCreateFlags)0,
1774 VK_SHADER_STAGE_GEOMETRY_BIT, // stage
1775 *geomShader, // shader
1777 DE_NULL, // pSpecializationInfo
1781 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
1783 VK_FALSE, // VkBool32 blendEnable;
1784 VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcColorBlendFactor;
1785 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
1786 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
1787 VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcAlphaBlendFactor;
1788 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor;
1789 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
1790 0xf // VkColorComponentFlags colorWriteMask;
1793 const VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfo =
1795 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
1796 DE_NULL, // const void* pNext;
1797 0u, // VkPipelineColorBlendStateCreateFlags flags;
1798 VK_FALSE, // VkBool32 logicOpEnable;
1799 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
1800 1u, // deUint32 attachmentCount;
1801 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
1802 { 1.0f, 1.0f, 1.0f, 1.0f } // float blendConstants[4];
1805 const deUint32 fragSizeWH = m_data.sampleMaskTest ? 2 : 0;
1807 VkPipelineRenderingCreateInfoKHR renderingCreateInfo
1809 VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
1811 m_data.multiView ? 0x3 : 0u,
1814 m_data.useDepthStencil ? dsFormat : VK_FORMAT_UNDEFINED,
1815 m_data.useDepthStencil ? dsFormat : VK_FORMAT_UNDEFINED
1818 VkPipelineFragmentShadingRateStateCreateInfoKHR shadingRateStateCreateInfo =
1820 VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR, // VkStructureType sType;
1821 m_data.useDynamicRendering ? &renderingCreateInfo : DE_NULL, // const void* pNext;
1822 { fragSizeWH, fragSizeWH }, // VkExtent2D fragmentSize;
1823 { m_data.combinerOp[0], m_data.combinerOp[1] }, // VkFragmentShadingRateCombinerOpKHR combinerOps[2];
1826 VkDynamicState dynamicState = VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR;
1827 const VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo =
1829 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType;
1830 DE_NULL, // const void* pNext;
1831 (VkPipelineDynamicStateCreateFlags)0, // VkPipelineDynamicStateCreateFlags flags;
1832 m_data.useDynamicState ? 1u : 0u, // uint32_t dynamicStateCount;
1833 &dynamicState, // const VkDynamicState* pDynamicStates;
1836 // Enable depth/stencil writes, always passing
1837 VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
1839 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
1840 DE_NULL, // const void* pNext;
1841 0u, // VkPipelineDepthStencilStateCreateFlags flags;
1842 VK_TRUE, // VkBool32 depthTestEnable;
1843 VK_TRUE, // VkBool32 depthWriteEnable;
1844 VK_COMPARE_OP_ALWAYS, // VkCompareOp depthCompareOp;
1845 VK_FALSE, // VkBool32 depthBoundsTestEnable;
1846 VK_TRUE, // VkBool32 stencilTestEnable;
1847 // VkStencilOpState front;
1849 VK_STENCIL_OP_REPLACE, // VkStencilOp failOp;
1850 VK_STENCIL_OP_REPLACE, // VkStencilOp passOp;
1851 VK_STENCIL_OP_REPLACE, // VkStencilOp depthFailOp;
1852 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp;
1853 0u, // deUint32 compareMask;
1854 0xFFu, // deUint32 writeMask;
1855 0xFFu, // deUint32 reference;
1857 // VkStencilOpState back;
1859 VK_STENCIL_OP_REPLACE, // VkStencilOp failOp;
1860 VK_STENCIL_OP_REPLACE, // VkStencilOp passOp;
1861 VK_STENCIL_OP_REPLACE, // VkStencilOp depthFailOp;
1862 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp;
1863 0u, // deUint32 compareMask;
1864 0xFFu, // deUint32 writeMask;
1865 0xFFu, // deUint32 reference;
1867 0.0f, // float minDepthBounds;
1868 0.0f, // float maxDepthBounds;
1871 VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo =
1873 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
1874 &shadingRateStateCreateInfo, // const void* pNext;
1875 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
1876 numStages, // deUint32 stageCount;
1877 &shaderCreateInfo[0], // const VkPipelineShaderStageCreateInfo* pStages;
1878 &vertexInputStateCreateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
1879 &inputAssemblyStateCreateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
1880 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
1881 &viewportStateCreateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState;
1882 &rasterizationStateCreateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
1883 &multisampleStateCreateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
1884 &depthStencilStateParams, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
1885 &colorBlendStateCreateInfo, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
1886 &dynamicStateCreateInfo, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
1887 pipelineLayout.get(), // VkPipelineLayout layout;
1888 renderPass.get(), // VkRenderPass renderPass;
1889 0u, // deUint32 subpass;
1890 DE_NULL, // VkPipeline basePipelineHandle;
1891 0 // int basePipelineIndex;
1894 if (m_data.useDynamicRendering)
1895 graphicsPipelineCreateInfo.flags |= VK_PIPELINE_CREATE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR;
1897 VkImageMemoryBarrier imageBarrier =
1899 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
1900 DE_NULL, // const void* pNext
1901 0u, // VkAccessFlags srcAccessMask
1902 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
1903 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
1904 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout
1905 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
1906 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
1907 **cbImage, // VkImage image
1909 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
1910 0u, // uint32_t baseMipLevel
1911 VK_REMAINING_MIP_LEVELS, // uint32_t mipLevels,
1912 0u, // uint32_t baseArray
1913 VK_REMAINING_ARRAY_LAYERS, // uint32_t arraySize
1917 const VkQueue queue = m_context.getUniversalQueue();
1918 Move<VkCommandPool> cmdPool = createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, m_context.getUniversalQueueFamilyIndex());
1919 Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1920 VkClearValue clearColor = makeClearValueColorU32(0, 0, 0, 0);
1921 VkClearValue clearDepthStencil = makeClearValueDepthStencil(0.0, 0);
1923 beginCommandBuffer(vk, *cmdBuffer, 0u);
1925 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1926 (VkDependencyFlags)0,
1927 0, (const VkMemoryBarrier*)DE_NULL,
1928 0, (const VkBufferMemoryBarrier*)DE_NULL,
1931 imageBarrier.image = **derivImage;
1932 imageBarrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
1934 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1935 (VkDependencyFlags)0,
1936 0, (const VkMemoryBarrier*)DE_NULL,
1937 0, (const VkBufferMemoryBarrier*)DE_NULL,
1940 // Clear level to 1<<level
1941 for (deUint32 i = 0; i < derivNumLevels; ++i)
1943 VkImageSubresourceRange range = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, i, 1u, 0u, 1u);
1944 VkClearValue clearLevelColor = makeClearValueColorU32(1<<i,0,0,0);
1945 vk.cmdClearColorImage(*cmdBuffer, **derivImage, VK_IMAGE_LAYOUT_GENERAL, &clearLevelColor.color, 1, &range);
1948 // Clear color buffer to transparent black
1950 VkImageSubresourceRange range = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, VK_REMAINING_ARRAY_LAYERS);
1951 vk.cmdClearColorImage(*cmdBuffer, **cbImage, VK_IMAGE_LAYOUT_GENERAL, &clearColor.color, 1, &range);
1954 // Clear depth and stencil
1955 if (m_data.useDepthStencil)
1957 VkImageSubresourceRange range = makeImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 1u, 0u, VK_REMAINING_ARRAY_LAYERS);
1958 VkImageMemoryBarrier dsBarrier = imageBarrier;
1959 dsBarrier.image = **dsImage;
1960 dsBarrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
1961 dsBarrier.subresourceRange = range;
1962 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1963 0u, // dependencyFlags
1967 vk.cmdClearDepthStencilImage(*cmdBuffer, **dsImage, VK_IMAGE_LAYOUT_GENERAL, &clearDepthStencil.depthStencil, 1, &range);
1970 // Initialize shading rate image with varying values
1971 if (m_data.useAttachment())
1973 imageBarrier.image = **srImage;
1974 imageBarrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
1976 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1977 (VkDependencyFlags)0,
1978 0, (const VkMemoryBarrier*)DE_NULL,
1979 0, (const VkBufferMemoryBarrier*)DE_NULL,
1982 deMemset(fillPtr, 0, (size_t)srFillBufferSize);
1983 for (deUint32 layer = 0; layer < numSRLayers; ++layer)
1985 for (deUint32 x = 0; x < srWidth; ++x)
1987 for (deUint32 y = 0; y < srHeight; ++y)
1989 deUint32 idx = (layer*srHeight + y)*srWidth + x;
1990 deUint8 val = (deUint8)SanitizeRate(idx & 0xF);
1991 // actual shading rate is always in the LSBs of the first byte of a texel
1992 fillPtr[srFillBpp*idx] = val;
1996 flushAlloc(vk, device, srFillBuffer->getAllocation());
1998 const VkBufferImageCopy copyRegion =
2000 0u, // VkDeviceSize bufferOffset;
2001 0u, // deUint32 bufferRowLength;
2002 0u, // deUint32 bufferImageHeight;
2004 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect;
2005 0u, // deUint32 mipLevel;
2006 0u, // deUint32 baseArrayLayer;
2007 numSRLayers, // deUint32 layerCount;
2008 }, // VkImageSubresourceLayers imageSubresource;
2009 { 0, 0, 0 }, // VkOffset3D imageOffset;
2010 { srWidth, srHeight, 1 }, // VkExtent3D imageExtent;
2013 vk.cmdCopyBufferToImage(*cmdBuffer, **srFillBuffer, **srImage, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region);
2015 imageBarrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
2016 imageBarrier.newLayout = srLayout;
2018 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
2019 (VkDependencyFlags)0,
2020 0, (const VkMemoryBarrier*)DE_NULL,
2021 0, (const VkBufferMemoryBarrier*)DE_NULL,
2025 VkMemoryBarrier memBarrier =
2027 VK_STRUCTURE_TYPE_MEMORY_BARRIER, // sType
2029 0u, // srcAccessMask
2030 0u, // dstAccessMask
2033 memBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
2034 memBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR;
2035 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, allPipelineStages,
2036 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
2038 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0, 1, &descriptorSet.get(), 0, DE_NULL);
2040 vector<Move<VkPipeline>> pipelines;
2042 // If using dynamic state, create a single graphics pipeline and bind it
2043 if (m_data.useDynamicState)
2045 pipelines.push_back(createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineCreateInfo));
2046 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelines[0]);
2049 VkRect2D renderArea = makeRect2D(m_data.framebufferDim.width, m_data.framebufferDim.height);
2050 if (m_data.useDynamicRendering)
2052 VkRenderingFragmentShadingRateAttachmentInfoKHR shadingRateAttachmentInfo
2054 VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR, // VkStructureType sType;
2055 DE_NULL, // const void* pNext;
2056 *srImageView, // VkImageView imageView;
2057 srLayout, // VkImageLayout imageLayout;
2058 { srTexelWidth, srTexelHeight } // VkExtent2D shadingRateAttachmentTexelSize;
2061 VkRenderingAttachmentInfoKHR colorAttachment
2063 vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
2064 DE_NULL, // const void* pNext;
2065 *cbImageView, // VkImageView imageView;
2066 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
2067 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
2068 DE_NULL, // VkImageView resolveImageView;
2069 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout;
2070 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
2071 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
2072 clearColor // VkClearValue clearValue;
2075 std::vector<VkRenderingAttachmentInfoKHR> depthStencilAttachments(2,
2077 VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
2078 DE_NULL, // const void* pNext;
2079 *dsImageView, // VkImageView imageView;
2080 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
2081 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
2082 DE_NULL, // VkImageView resolveImageView;
2083 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout;
2084 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
2085 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
2086 clearDepthStencil // VkClearValue clearValue;
2089 vk::VkRenderingInfoKHR renderingInfo
2091 vk::VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
2092 m_data.useAttachment() ? &shadingRateAttachmentInfo : DE_NULL,
2093 0, // VkRenderingFlagsKHR flags;
2094 renderArea, // VkRect2D renderArea;
2095 m_data.multiView ? 1 : m_data.numColorLayers, // deUint32 layerCount;
2096 m_data.multiView ? 0x3 : 0u, // deUint32 viewMask;
2097 1u, // deUint32 colorAttachmentCount;
2098 &colorAttachment, // const VkRenderingAttachmentInfoKHR* pColorAttachments;
2099 m_data.useDepthStencil ? &depthStencilAttachments[0] : DE_NULL, // const VkRenderingAttachmentInfoKHR* pDepthAttachment;
2100 m_data.useDepthStencil ? &depthStencilAttachments[1] : DE_NULL, // const VkRenderingAttachmentInfoKHR* pStencilAttachment;
2103 vk.cmdBeginRendering(*cmdBuffer, &renderingInfo);
2107 const VkRenderPassAttachmentBeginInfo renderPassAttachmentBeginInfo
2109 VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO, // VkStructureType sType;
2110 DE_NULL, // const void* pNext;
2111 (deUint32)attachments.size(), // deUint32 attachmentCount;
2112 &attachments[0] // const VkImageView* pAttachments;
2115 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderArea,
2116 0, DE_NULL, VK_SUBPASS_CONTENTS_INLINE, imagelessFB ? &renderPassAttachmentBeginInfo : DE_NULL);
2119 for (deInt32 i = 0; i < NUM_TRIANGLES; ++i)
2121 // Bind vertex attributes pointing to the next triangle
2122 VkDeviceSize vertexBufferOffset = i*3*2*sizeof(float);
2123 VkBuffer vb = **vertexBuffer;
2124 vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vb, &vertexBufferOffset);
2126 // Put primitive shading rate in a push constant
2127 deInt32 shadingRatePC = PrimIDToPrimitiveShadingRate(i);
2128 vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, allShaderStages, 0, sizeof(shadingRatePC), &shadingRatePC);
2130 if (m_data.useDynamicState)
2132 VkExtent2D fragmentSize = ShadingRateEnumToExtent(PrimIDToPipelineShadingRate(i));
2133 vk.cmdSetFragmentShadingRateKHR(*cmdBuffer, &fragmentSize, m_data.combinerOp);
2137 // Create a new pipeline with the desired pipeline shading rate
2138 shadingRateStateCreateInfo.fragmentSize = ShadingRateEnumToExtent(PrimIDToPipelineShadingRate(i));
2139 pipelines.push_back(createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineCreateInfo));
2140 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelines.back());
2143 // Draw one triangle, with "primitive ID" in gl_InstanceIndex
2144 vk.cmdDraw(*cmdBuffer, 3u, 1, 0u, i);
2147 if (m_data.useDynamicRendering)
2148 endRendering(vk, *cmdBuffer);
2150 endRenderPass(vk, *cmdBuffer);
2152 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;
2153 memBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
2154 vk.cmdPipelineBarrier(*cmdBuffer, allPipelineStages, allPipelineStages,
2155 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
2157 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1, &*descriptorSet, 0u, DE_NULL);
2158 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
2160 // Copy color/depth/stencil buffers to buffer memory
2161 vk.cmdDispatch(*cmdBuffer, m_data.framebufferDim.width, m_data.framebufferDim.height, m_data.numColorLayers);
2163 memBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
2164 memBarrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT;
2165 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
2166 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
2168 endCommandBuffer(vk, *cmdBuffer);
2170 submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
2172 deUint32 *colorptr = (deUint32 *)colorOutputBuffer->getAllocation().getHostPtr();
2173 invalidateAlloc(vk, device, colorOutputBuffer->getAllocation());
2175 invalidateAlloc(vk, device, atomicBuffer->getAllocation());
2177 float *depthptr = DE_NULL;
2178 deUint32 *stencilptr = DE_NULL;
2180 if (m_data.useDepthStencil)
2182 depthptr = (float *)depthOutputBuffer->getAllocation().getHostPtr();
2183 invalidateAlloc(vk, device, depthOutputBuffer->getAllocation());
2185 stencilptr = (deUint32 *)stencilOutputBuffer->getAllocation().getHostPtr();
2186 invalidateAlloc(vk, device, stencilOutputBuffer->getAllocation());
2189 // Loop over all samples and validate the output
2190 for (deUint32 layer = 0; layer < m_data.numColorLayers && res == QP_TEST_RESULT_PASS; ++layer)
2192 for (deUint32 y = 0; y < m_data.framebufferDim.height && res == QP_TEST_RESULT_PASS; ++y)
2194 for (deUint32 x = 0; x < m_data.framebufferDim.width && res == QP_TEST_RESULT_PASS; ++x)
2196 for (deInt32 s = 0; s < m_data.samples && res == QP_TEST_RESULT_PASS; ++s)
2198 deUint32 *sample = &colorptr[4*(((layer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + s)];
2200 // If testing the rasterizer sample mask, if this sample is not set in the
2201 // mask then it shouldn't have written anything.
2202 if (m_data.useApiSampleMask && !(sampleMask & (1 << s)) && sample[2] != 0)
2204 log << tcu::TestLog::Message << std::hex << "sample written despite pSampleMask (" << x << "," << y << ",sample " << s << ")" << tcu::TestLog::EndMessage;
2205 res = QP_TEST_RESULT_FAIL;
2209 // The same isn't covered by any primitives, skip it
2213 // skip samples that have the same value as sample zero - it would be redundant to check them.
2216 deUint32 *sample0 = &colorptr[4*(((layer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + 0)];
2217 bool same = deMemCmp(sample, sample0, 16) == 0;
2219 if (m_data.fragDepth)
2221 float *dsample = &depthptr[((layer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + s];
2222 float *dsample0 = &depthptr[((layer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + 0];
2223 same = same && (*dsample == *dsample0);
2226 if (m_data.fragStencil)
2228 deUint32 *ssample = &stencilptr[((layer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + s];
2229 deUint32 *ssample0 = &stencilptr[((layer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + 0];
2230 same = same && (*ssample == *ssample0);
2237 // Fragment shader writes error codes to .w component.
2238 // All nonzero values are unconditionally failures
2241 if (sample[3] == ERROR_FRAGCOORD_CENTER)
2242 log << tcu::TestLog::Message << std::hex << "fragcoord test failed pixel (0x" << x << ",0x" << y << ",sample 0x" << s << ")" << tcu::TestLog::EndMessage;
2243 else if (sample[3] == ERROR_VTG_READBACK)
2244 log << tcu::TestLog::Message << std::hex << "vs/gs output readback test failed pixel (0x" << x << ",0x" << y << ",sample 0x" << s << ")" << tcu::TestLog::EndMessage;
2245 else if ((sample[3] & 0xFF) == ERROR_FRAGCOORD_DERIV)
2246 log << tcu::TestLog::Message << std::hex << "fragcoord derivative test failed pixel (0x" << x << ",0x" << y << ",sample 0x" << s << ")="
2247 "(0x" << ((sample[3] >> 8) & 0x3F) << ",0x" << ((sample[3] >> 14) & 0x3F) << "), expected="
2248 "(0x" << ((sample[3] >> 20) & 0x3F) << ",0x" << ((sample[3] >> 26) & 0x3F) << ")" << tcu::TestLog::EndMessage;
2249 else if ((sample[3] & 0xFF) == ERROR_FRAGCOORD_IMPLICIT_DERIV)
2250 log << tcu::TestLog::Message << std::hex << "implicit derivative test failed pixel (0x" << x << ",0x" << y << ",sample 0x" << s << ")="
2251 "(0x" << ((sample[3] >> 8) & 0x3F) << ",0x" << ((sample[3] >> 14) & 0x3F) << "), expected="
2252 "(0x" << ((sample[3] >> 20) & 0x3F) << ",0x" << ((sample[3] >> 26) & 0x3F) << ")" << tcu::TestLog::EndMessage;
2254 log << tcu::TestLog::Message << std::hex << "w coord unknown test failed pixel (0x" << x << ",0x" << y << ",sample 0x" << s << ")" << tcu::TestLog::EndMessage;
2255 res = QP_TEST_RESULT_FAIL;
2259 // x component of sample
2260 deUint32 rate = sample[0];
2262 deUint32 pixelsX = 1 << ((rate/4)&3);
2263 deUint32 pixelsY = 1 << (rate&3);
2266 deUint32 fragMinX = x & ~(pixelsX-1);
2267 deUint32 fragMinY = y & ~(pixelsY-1);
2268 deUint32 fragMaxX = fragMinX + pixelsX;
2269 deUint32 fragMaxY = fragMinY + pixelsY;
2271 // Clamp to FB dimension for odd sizes
2272 if (fragMaxX > m_data.framebufferDim.width)
2273 fragMaxX = m_data.framebufferDim.width;
2274 if (fragMaxY > m_data.framebufferDim.height)
2275 fragMaxY = m_data.framebufferDim.height;
2277 // z component of sample
2278 deUint32 primID = sample[2] >> 24;
2279 deUint32 atomVal = sample[2] & 0xFFFFFF;
2281 // Compute pipeline and primitive rate from primitive ID, and attachment
2282 // rate from the x/y coordinate
2283 deInt32 pipelineRate = PrimIDToPipelineShadingRate(primID);
2284 deInt32 primitiveRate = m_data.shaderWritesRate ? PrimIDToPrimitiveShadingRate(primID) : 0;
2286 deInt32 attachmentLayer = (m_data.srLayered && modeIdx == ATTACHMENT_MODE_2DARRAY) ? layer : 0;
2287 deInt32 attachmentRate = m_data.useAttachment() ? fillPtr[srFillBpp*((attachmentLayer * srHeight + (y / srTexelHeight)) * srWidth + (x / srTexelWidth))] : 0;
2289 // Get mask of allowed shading rates
2290 deInt32 expectedMasks = Simulate(pipelineRate, primitiveRate, attachmentRate);
2292 if (!(expectedMasks & (1 << rate)))
2294 log << tcu::TestLog::Message << std::hex << "unexpected shading rate. failed pixel (0x" << x << ",0x" << y << ",sample 0x" << s << ") "
2295 "result rate 0x" << rate << " mask of expected rates 0x" << expectedMasks <<
2296 " pipelineRate=0x" << pipelineRate << " primitiveRate=0x" << primitiveRate << " attachmentRate =0x" << attachmentRate << tcu::TestLog::EndMessage;
2297 res = QP_TEST_RESULT_FAIL;
2300 // Check that not all fragments are downgraded to 1x1
2301 if (rate == 0 && expectedMasks != 1)
2302 numUnexpected1x1Samples++;
2305 // Check that gl_FragDepth = primID / NUM_TRIANGLES
2306 if (m_data.fragDepth)
2308 float *dsample = &depthptr[((layer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + s];
2309 float expected = (float)primID / NUM_TRIANGLES;
2310 if (fabs(*dsample - expected) > 0.01)
2312 log << tcu::TestLog::Message << std::hex << "depth write failed pixel (0x" << x << ",0x" << y << ",sample 0x" << s << ")=" << *dsample << " expected " << expected << tcu::TestLog::EndMessage;
2313 res = QP_TEST_RESULT_FAIL;
2318 // Check that stencil value = primID
2319 if (m_data.fragStencil)
2321 deUint32 *ssample = &stencilptr[((layer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + s];
2322 if (*ssample != primID)
2324 log << tcu::TestLog::Message << std::hex << "stencil write failed pixel (0x" << x << ",0x" << y << ",sample 0x" << s << ")=" << *ssample << " expected " << primID << tcu::TestLog::EndMessage;
2325 res = QP_TEST_RESULT_FAIL;
2330 // Check that primitives are in the right viewport/scissor
2331 if (m_data.multiViewport)
2333 VkRect2D *scissor = &scissors[primID & 1];
2334 if ((int)x < scissor->offset.x || (int)x >= (int)(scissor->offset.x + scissor->extent.width) ||
2335 (int)y < scissor->offset.y || (int)y >= (int)(scissor->offset.y + scissor->extent.height))
2337 log << tcu::TestLog::Message << std::hex << "primitive found outside of expected viewport (0x" << x << ",0x" << y << ",sample 0x" << s << ") primID=" << primID << tcu::TestLog::EndMessage;
2338 res = QP_TEST_RESULT_FAIL;
2343 // Check that primitives are in the right layer
2344 if (m_data.colorLayered)
2346 if (layer != ((primID & 2)>>1))
2348 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;
2349 res = QP_TEST_RESULT_FAIL;
2354 // Check that multiview broadcasts the same primitive to both layers
2355 if (m_data.multiView)
2357 deUint32 otherLayer = layer^1;
2358 deUint32 *othersample = &colorptr[4*(((otherLayer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + s)];
2359 deUint32 otherPrimID = othersample[2] >> 24;
2360 if (primID != otherPrimID)
2362 log << tcu::TestLog::Message << std::hex << "multiview primitive mismatch (0x" << x << ",0x" << y << ",sample 0x" << s << ") primID=" << primID << " otherPrimID=" << otherPrimID << tcu::TestLog::EndMessage;
2363 res = QP_TEST_RESULT_FAIL;
2368 // Loop over all samples in the same fragment
2369 for (deUint32 fx = fragMinX; fx < fragMaxX; ++fx)
2371 for (deUint32 fy = fragMinY; fy < fragMaxY; ++fy)
2373 for (deInt32 fs = 0; fs < m_data.samples; ++fs)
2375 deUint32 *fsample = &colorptr[4*(((layer * m_data.framebufferDim.height + fy) * m_data.framebufferDim.width + fx)*m_data.samples + fs)];
2376 deUint32 frate = fsample[0];
2377 deUint32 fprimID = fsample[2] >> 24;
2378 deUint32 fatomVal = fsample[2] & 0xFFFFFF;
2380 // If we write out the sample mask value, check that the samples in the
2381 // mask must not be uncovered, and that samples not in the mask must not
2382 // be covered by this primitive
2383 if (m_data.useSampleMaskIn)
2385 int p = pixelsX * pixelsY - ((fx - fragMinX) + pixelsX * (fy - fragMinY)) - 1;
2386 int sampleIdx = fs + m_data.samples * p;
2388 if ((sample[1] & (1 << sampleIdx)) && fsample[2] == 0)
2390 log << tcu::TestLog::Message << std::hex << "sample set in sampleMask but not written (0x" << fx << ",0x" << fy << ",sample 0x" << fs << ")" << tcu::TestLog::EndMessage;
2391 res = QP_TEST_RESULT_FAIL;
2394 if (!(sample[1] & (1 << sampleIdx)) && fsample[2] != 0 && fprimID == primID)
2396 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;
2397 res = QP_TEST_RESULT_FAIL;
2402 // If conservative raster is enabled, or custom sample locations all at the center, check that
2403 // samples in the same pixel must be covered.
2404 if (m_data.conservativeEnable ||
2405 (m_data.sampleLocations && m_context.getFragmentShadingRateProperties().fragmentShadingRateWithCustomSampleLocations))
2407 // If it's in the same pixel, expect it to be fully covered.
2408 if (fx == x && fy == y && fsample[2] == 0)
2410 log << tcu::TestLog::Message << std::hex << "pixel not fully covered (0x" << fx << ",0x" << fy << ",sample 0x" << fs << ")" << tcu::TestLog::EndMessage;
2411 res = QP_TEST_RESULT_FAIL;
2416 if (fsample[2] == 0)
2419 // If the primitive matches this sample, then it must have the same rate and
2421 if (fprimID == primID)
2423 if (rate != frate || (atomVal != fatomVal && !(m_data.sampleShadingEnable || m_data.sampleShadingInput)))
2425 log << tcu::TestLog::Message << std::hex << "failed pixel (0x" << x << ",0x" << y << ",sample " << s << ")=0x" << ((primID<<24)|atomVal) <<
2426 " compared to (0x" << fx << ",0x" << fy << ",sample " << fs << ")=0x" << ((fprimID<<24)|fatomVal) <<
2427 " pipelineRate=0x" << pipelineRate << " primitiveRate=0x" << primitiveRate << " attachmentRate =0x" << attachmentRate <<
2428 tcu::TestLog::EndMessage;
2429 res = QP_TEST_RESULT_FAIL;
2439 if (res == QP_TEST_RESULT_FAIL)
2443 // All samples were coerced to 1x1, unexpected
2444 if (res == QP_TEST_RESULT_PASS &&
2445 numTotalSamples != 0 &&
2446 numUnexpected1x1Samples == numTotalSamples &&
2447 numTotalSamples > 16)
2449 log << tcu::TestLog::Message << std::hex << "Quality warning - all fragments used 1x1" << tcu::TestLog::EndMessage;
2450 res = QP_TEST_RESULT_QUALITY_WARNING;
2453 return tcu::TestStatus(res, qpGetTestResultName(res));
2458 void createBasicTests (tcu::TestContext& testCtx, tcu::TestCaseGroup* parentGroup, bool useDynamicRendering)
2464 const char* description;
2471 const char* description;
2476 AttachmentUsage usage;
2478 const char* description;
2479 } TestGroupUsageCase;
2481 TestGroupCase groupCases[] =
2483 { 0, "basic", "basic tests" },
2484 { 1, "apisamplemask", "use pSampleMask" },
2485 { 2, "samplemaskin", "use gl_SampleMaskIn" },
2486 { 3, "conservativeunder", "conservative underestimation" },
2487 { 4, "conservativeover", "conservative overestimation" },
2488 { 5, "fragdepth", "depth shader output" },
2489 { 6, "fragstencil", "stencil shader output" },
2490 { 7, "multiviewport", "multiple viewports and gl_ViewportIndex" },
2491 { 8, "colorlayered", "multiple layer color, single layer shading rate" },
2492 { 9, "srlayered", "multiple layer color, multiple layers shading rate" },
2493 { 10, "multiview", "multiview" },
2494 { 11, "multiviewsrlayered", "multiview and multilayer shading rate" },
2495 { 12, "interlock", "fragment shader interlock" },
2496 { 13, "samplelocations", "custom sample locations" },
2497 { 14, "sampleshadingenable", "enable sample shading in createinfo" },
2498 { 15, "sampleshadinginput", "enable sample shading by using gl_SampleID" },
2501 TestGroupCase dynCases[] =
2503 { 1, "dynamic", "uses dynamic shading rate state" },
2504 { 0, "static", "uses static shading rate state" },
2507 TestGroupUsageCase attCases[] =
2509 { AttachmentUsage::NO_ATTACHMENT, "noattachment", "no shading rate attachment" },
2510 { AttachmentUsage::WITH_ATTACHMENT, "attachment", "has shading rate attachment" },
2511 { AttachmentUsage::NO_ATTACHMENT_PTR, "noattachmentptr", "no shading rate attachment pointer" },
2514 TestGroupCase shdCases[] =
2516 { 0, "noshaderrate", "shader doesn't write rate" },
2517 { 1, "shaderrate", "shader writes rate" },
2520 TestGroupCase combCases[] =
2522 { VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR, "keep", "keep" },
2523 { VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR, "replace", "replace" },
2524 { VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MIN_KHR, "min", "min" },
2525 { VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_KHR, "max", "max" },
2526 { VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_KHR, "mul", "mul" },
2529 TestGroupCase2D extentCases[] =
2531 { {1, 1}, "1x1", "1x1" },
2532 { {4, 4}, "4x4", "4x4" },
2533 { {33, 35}, "33x35", "33x35" },
2534 { {151, 431}, "151x431", "151x431" },
2535 { {256, 256}, "256x256", "256x256" },
2538 TestGroupCase sampCases[] =
2540 { VK_SAMPLE_COUNT_1_BIT, "samples1", "1 raster sample" },
2541 { VK_SAMPLE_COUNT_2_BIT, "samples2", "2 raster samples" },
2542 { VK_SAMPLE_COUNT_4_BIT, "samples4", "4 raster samples" },
2543 { VK_SAMPLE_COUNT_8_BIT, "samples8", "8 raster samples" },
2544 { VK_SAMPLE_COUNT_16_BIT, "samples16", "16 raster samples" },
2547 TestGroupCase geomCases[] =
2549 { 0, "vs", "vertex shader only" },
2550 { 1, "gs", "vertex and geometry shader" },
2555 for (int groupNdx = 0; groupNdx < DE_LENGTH_OF_ARRAY(groupCases); groupNdx++)
2557 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, groupCases[groupNdx].name, groupCases[groupNdx].description));
2558 for (int dynNdx = 0; dynNdx < DE_LENGTH_OF_ARRAY(dynCases); dynNdx++)
2560 de::MovePtr<tcu::TestCaseGroup> dynGroup(new tcu::TestCaseGroup(testCtx, dynCases[dynNdx].name, dynCases[dynNdx].description));
2561 for (int attNdx = 0; attNdx < DE_LENGTH_OF_ARRAY(attCases); attNdx++)
2563 if (useDynamicRendering && attCases[attNdx].usage == AttachmentUsage::NO_ATTACHMENT_PTR)
2566 de::MovePtr<tcu::TestCaseGroup> attGroup(new tcu::TestCaseGroup(testCtx, attCases[attNdx].name, attCases[attNdx].description));
2567 for (int shdNdx = 0; shdNdx < DE_LENGTH_OF_ARRAY(shdCases); shdNdx++)
2569 de::MovePtr<tcu::TestCaseGroup> shdGroup(new tcu::TestCaseGroup(testCtx, shdCases[shdNdx].name, shdCases[shdNdx].description));
2570 for (int cmb0Ndx = 0; cmb0Ndx < DE_LENGTH_OF_ARRAY(combCases); cmb0Ndx++)
2572 de::MovePtr<tcu::TestCaseGroup> cmb0Group(new tcu::TestCaseGroup(testCtx, combCases[cmb0Ndx].name, combCases[cmb0Ndx].description));
2573 for (int cmb1Ndx = 0; cmb1Ndx < DE_LENGTH_OF_ARRAY(combCases); cmb1Ndx++)
2575 de::MovePtr<tcu::TestCaseGroup> cmb1Group(new tcu::TestCaseGroup(testCtx, combCases[cmb1Ndx].name, combCases[cmb1Ndx].description));
2576 for (int extNdx = 0; extNdx < DE_LENGTH_OF_ARRAY(extentCases); extNdx++)
2578 de::MovePtr<tcu::TestCaseGroup> extGroup(new tcu::TestCaseGroup(testCtx, extentCases[extNdx].name, extentCases[extNdx].description));
2579 for (int sampNdx = 0; sampNdx < DE_LENGTH_OF_ARRAY(sampCases); sampNdx++)
2581 de::MovePtr<tcu::TestCaseGroup> sampGroup(new tcu::TestCaseGroup(testCtx, sampCases[sampNdx].name, sampCases[sampNdx].description));
2582 for (int geomNdx = 0; geomNdx < DE_LENGTH_OF_ARRAY(geomCases); geomNdx++)
2584 bool useApiSampleMask = groupNdx == 1;
2585 bool useSampleMaskIn = groupNdx == 2;
2586 bool consRast = groupNdx == 3 || groupNdx == 4;
2587 bool fragDepth = groupNdx == 5;
2588 bool fragStencil = groupNdx == 6;
2589 bool multiViewport = groupNdx == 7;
2590 bool colorLayered = groupNdx == 8 || groupNdx == 9;
2591 bool srLayered = groupNdx == 9 || groupNdx == 11;
2592 bool multiView = groupNdx == 10 || groupNdx == 11;
2593 bool interlock = groupNdx == 12;
2594 bool sampleLocations = groupNdx == 13;
2595 bool sampleShadingEnable = groupNdx == 14;
2596 bool sampleShadingInput = groupNdx == 15;
2597 VkConservativeRasterizationModeEXT conservativeMode = (groupNdx == 3) ? VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT : VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT;
2598 deUint32 numColorLayers = (colorLayered || multiView) ? 2u : 1u;
2600 // Don't bother with geometry shader if we're not testing shader writes
2601 if (geomCases[geomNdx].count && !shdCases[shdNdx].count)
2604 // reduce number of tests
2605 if ((groupNdx != 0) &&
2606 (!dynCases[dynNdx].count ||
2607 !(combCases[cmb0Ndx].count == VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR || combCases[cmb0Ndx].count == VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR) ||
2608 !(combCases[cmb1Ndx].count == VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR || combCases[cmb1Ndx].count == VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR)))
2611 // Don't bother with geometry shader if we're testing conservative raster, sample mask, depth/stencil
2612 if (geomCases[geomNdx].count && (useApiSampleMask || useSampleMaskIn || consRast || fragDepth || fragStencil))
2615 // Don't bother with geometry shader if we're testing non-dynamic state
2616 if (geomCases[geomNdx].count && !dynCases[dynNdx].count)
2619 // Only test multiViewport/layered with shaderWritesRate
2620 if ((multiViewport || colorLayered) && !shdCases[shdNdx].count)
2623 // Can't test layered shading rate attachment without an attachment
2624 if (srLayered && attCases[attNdx].usage != AttachmentUsage::WITH_ATTACHMENT)
2629 seed++, // deInt32 seed;
2630 extentCases[extNdx].count, // VkExtent2D framebufferDim;
2631 (VkSampleCountFlagBits)sampCases[sampNdx].count, // VkSampleCountFlagBits samples;
2633 (VkFragmentShadingRateCombinerOpKHR)combCases[cmb0Ndx].count,
2634 (VkFragmentShadingRateCombinerOpKHR)combCases[cmb1Ndx].count
2635 }, // VkFragmentShadingRateCombinerOpKHR combinerOp[2];
2636 attCases[attNdx].usage, // AttachmentUsage attachmentUsage;
2637 (bool)shdCases[shdNdx].count, // bool shaderWritesRate;
2638 (bool)geomCases[geomNdx].count, // bool geometryShader;
2639 (bool)dynCases[dynNdx].count, // bool useDynamicState;
2640 useDynamicRendering, // bool useDynamicRendering;
2641 useApiSampleMask, // bool useApiSampleMask;
2642 useSampleMaskIn, // bool useSampleMaskIn;
2643 consRast, // bool conservativeEnable;
2644 conservativeMode, // VkConservativeRasterizationModeEXT conservativeMode;
2645 fragDepth || fragStencil, // bool useDepthStencil;
2646 fragDepth, // bool fragDepth;
2647 fragStencil, // bool fragStencil;
2648 multiViewport, // bool multiViewport;
2649 colorLayered, // bool colorLayered;
2650 srLayered, // bool srLayered;
2651 numColorLayers, // deUint32 numColorLayers;
2652 multiView, // bool multiView;
2653 interlock, // bool interlock;
2654 sampleLocations, // bool sampleLocations;
2655 sampleShadingEnable, // bool sampleShadingEnable;
2656 sampleShadingInput, // bool sampleShadingInput;
2657 false, // bool sampleMaskTest;
2660 sampGroup->addChild(new FSRTestCase(testCtx, geomCases[geomNdx].name, geomCases[geomNdx].description, c));
2662 extGroup->addChild(sampGroup.release());
2664 cmb1Group->addChild(extGroup.release());
2666 cmb0Group->addChild(cmb1Group.release());
2668 shdGroup->addChild(cmb0Group.release());
2670 attGroup->addChild(shdGroup.release());
2672 dynGroup->addChild(attGroup.release());
2674 group->addChild(dynGroup.release());
2676 parentGroup->addChild(group.release());
2679 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "misc_tests", "Single tests that don't need to be part of above test matrix"));
2680 group->addChild(new FSRTestCase(testCtx, "sample_mask_test", "", {
2681 123, // deInt32 seed;
2682 {32, 33}, // VkExtent2D framebufferDim;
2683 VK_SAMPLE_COUNT_4_BIT, // VkSampleCountFlagBits samples;
2685 VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR,
2686 VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR
2687 }, // VkFragmentShadingRateCombinerOpKHR combinerOp[2];
2688 AttachmentUsage::NO_ATTACHMENT, // AttachmentUsage attachmentUsage;
2689 true, // bool shaderWritesRate;
2690 false, // bool geometryShader;
2691 false, // bool useDynamicState;
2692 false, // bool useDynamicRendering;
2693 true, // bool useApiSampleMask;
2694 false, // bool useSampleMaskIn;
2695 false, // bool conservativeEnable;
2696 VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT, // VkConservativeRasterizationModeEXT conservativeMode;
2697 false, // bool useDepthStencil;
2698 false, // bool fragDepth;
2699 false, // bool fragStencil;
2700 false, // bool multiViewport;
2701 false, // bool colorLayered;
2702 false, // bool srLayered;
2703 1u, // deUint32 numColorLayers;
2704 false, // bool multiView;
2705 false, // bool interlock;
2706 false, // bool sampleLocations;
2707 false, // bool sampleShadingEnable;
2708 false, // bool sampleShadingInput;
2709 true, // bool sampleMaskTest;
2712 parentGroup->addChild(group.release());
2715 } // FragmentShadingRage