1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2017-2019 The Khronos Group Inc.
6 * Copyright (c) 2018-2020 NVIDIA Corporation
7 *
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
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
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.
19 *
20 *//*!
21 * \file
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 *//*--------------------------------------------------------------------*/
34
35 #include "vktFragmentShadingRateBasic.hpp"
36
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"
45
46 #include "vktTestGroupUtil.hpp"
47 #include "vktTestCase.hpp"
48
49 #include "deDefs.h"
50 #include "deMath.h"
51 #include "deRandom.h"
52 #include "deSharedPtr.hpp"
53 #include "deString.h"
54
55 #include "tcuTestCase.hpp"
56 #include "tcuTestLog.hpp"
57
58 #include <string>
59 #include <sstream>
60
61 namespace vkt
62 {
63 namespace FragmentShadingRate
64 {
65 namespace
66 {
67 using namespace vk;
68 using namespace std;
69
70 #define NUM_TRIANGLES (9*9)
71
72 enum class AttachmentUsage
73 {
74 NO_ATTACHMENT = 0,
75 NO_ATTACHMENT_PTR,
76 WITH_ATTACHMENT,
77 };
78
79 struct CaseDef
80 {
81 deInt32 seed;
82 VkExtent2D framebufferDim;
83 VkSampleCountFlagBits samples;
84 VkFragmentShadingRateCombinerOpKHR combinerOp[2];
85 AttachmentUsage attachmentUsage;
86 bool shaderWritesRate;
87 bool geometryShader;
88 bool useDynamicState;
89 bool useDynamicRendering;
90 bool useApiSampleMask;
91 bool useSampleMaskIn;
92 bool conservativeEnable;
93 VkConservativeRasterizationModeEXT conservativeMode;
94 bool useDepthStencil; // == fragDepth || fragStencil
95 bool fragDepth;
96 bool fragStencil;
97 bool multiViewport;
98 bool colorLayered;
99 bool srLayered; // colorLayered must also be true
100 deUint32 numColorLayers;
101 bool multiView;
102 bool interlock;
103 bool sampleLocations;
104 bool sampleShadingEnable;
105 bool sampleShadingInput;
106 bool sampleMaskTest;
107
useAttachmentvkt::FragmentShadingRate::__anon238d709f0111::CaseDef108 bool useAttachment () const
109 {
110 return (attachmentUsage == AttachmentUsage::WITH_ATTACHMENT);
111 }
112 };
113
114 class FSRTestInstance : public TestInstance
115 {
116 public:
117 FSRTestInstance (Context& context, const CaseDef& data);
118 ~FSRTestInstance (void);
119 tcu::TestStatus iterate (void);
120
121 private:
122 // Test parameters
123 CaseDef m_data;
124
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;
134
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;
145 };
146
FSRTestInstance(Context & context,const CaseDef & data)147 FSRTestInstance::FSRTestInstance (Context& context, const CaseDef& data)
148 : vkt::TestInstance (context)
149 , m_data (data)
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)
154 {
155 m_supportedFragmentShadingRateCount = 0;
156 m_context.getInstanceInterface().getPhysicalDeviceFragmentShadingRatesKHR(m_context.getPhysicalDevice(), &m_supportedFragmentShadingRateCount, DE_NULL);
157
158 if (m_supportedFragmentShadingRateCount < 3)
159 TCU_THROW(TestError, "*pFragmentShadingRateCount too small");
160
161 m_supportedFragmentShadingRates.resize(m_supportedFragmentShadingRateCount);
162 for (deUint32 i = 0; i < m_supportedFragmentShadingRateCount; ++i)
163 {
164 m_supportedFragmentShadingRates[i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_KHR;
165 m_supportedFragmentShadingRates[i].pNext = nullptr;
166 }
167 m_context.getInstanceInterface().getPhysicalDeviceFragmentShadingRatesKHR(m_context.getPhysicalDevice(), &m_supportedFragmentShadingRateCount, &m_supportedFragmentShadingRates[0]);
168
169 m_shadingRateProperties = m_context.getFragmentShadingRateProperties();
170 }
171
~FSRTestInstance(void)172 FSRTestInstance::~FSRTestInstance (void)
173 {
174 }
175
176 class FSRTestCase : public TestCase
177 {
178 public:
179 FSRTestCase (tcu::TestContext& context, const char* name, const char* desc, const CaseDef data);
180 ~FSRTestCase (void);
181 virtual void initPrograms (SourceCollections& programCollection) const;
182 virtual TestInstance* createInstance (Context& context) const;
183 virtual void checkSupport (Context& context) const;
184
185 private:
186 CaseDef m_data;
187 };
188
FSRTestCase(tcu::TestContext & context,const char * name,const char * desc,const CaseDef data)189 FSRTestCase::FSRTestCase (tcu::TestContext& context, const char* name, const char* desc, const CaseDef data)
190 : vkt::TestCase (context, name, desc)
191 , m_data (data)
192 {
193 }
194
~FSRTestCase(void)195 FSRTestCase::~FSRTestCase (void)
196 {
197 }
198
Force1x1() const199 bool FSRTestInstance::Force1x1() const
200 {
201 if (m_data.useApiSampleMask && !m_context.getFragmentShadingRateProperties().fragmentShadingRateWithSampleMask)
202 return true;
203
204 if (m_data.useSampleMaskIn && !m_context.getFragmentShadingRateProperties().fragmentShadingRateWithShaderSampleMask)
205 return true;
206
207 if (m_data.conservativeEnable && !m_context.getFragmentShadingRateProperties().fragmentShadingRateWithConservativeRasterization)
208 return true;
209
210 if (m_data.useDepthStencil && !m_context.getFragmentShadingRateProperties().fragmentShadingRateWithShaderDepthStencilWrites)
211 return true;
212
213 if (m_data.interlock && !m_context.getFragmentShadingRateProperties().fragmentShadingRateWithFragmentShaderInterlock)
214 return true;
215
216 if (m_data.sampleLocations && !m_context.getFragmentShadingRateProperties().fragmentShadingRateWithCustomSampleLocations)
217 return true;
218
219 if (m_data.sampleShadingEnable || m_data.sampleShadingInput)
220 return true;
221
222 return false;
223 }
224
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;
229
checkSupport(Context & context) const230 void FSRTestCase::checkSupport(Context& context) const
231 {
232 context.requireDeviceFunctionality("VK_KHR_fragment_shading_rate");
233
234 if (m_data.useDynamicRendering)
235 context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
236
237 if (!context.getFragmentShadingRateFeatures().pipelineFragmentShadingRate)
238 TCU_THROW(NotSupportedError, "pipelineFragmentShadingRate not supported");
239
240 if (m_data.shaderWritesRate &&
241 !context.getFragmentShadingRateFeatures().primitiveFragmentShadingRate)
242 TCU_THROW(NotSupportedError, "primitiveFragmentShadingRate not supported");
243
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");
247
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");
251
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);
255
256 if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
257 TCU_THROW(NotSupportedError, "VK_FORMAT_R32G32B32A32_UINT not supported");
258
259 if (!(imageProperties.sampleCounts & m_data.samples))
260 TCU_THROW(NotSupportedError, "color buffer sample count not supported");
261
262 if (m_data.numColorLayers > imageProperties.maxArrayLayers)
263 TCU_THROW(NotSupportedError, "color buffer layers not supported");
264
265 if (m_data.useAttachment() && !context.getFragmentShadingRateFeatures().attachmentFragmentShadingRate)
266 TCU_THROW(NotSupportedError, "attachmentFragmentShadingRate not supported");
267
268 if (!context.getFragmentShadingRateProperties().fragmentShadingRateNonTrivialCombinerOps &&
269 ((m_data.combinerOp[0] != VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR && m_data.combinerOp[0] != VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR) ||
270 (m_data.combinerOp[1] != VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR && m_data.combinerOp[1] != VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR)))
271 TCU_THROW(NotSupportedError, "fragmentShadingRateNonTrivialCombinerOps not supported");
272
273 if (m_data.conservativeEnable)
274 {
275 context.requireDeviceFunctionality("VK_EXT_conservative_rasterization");
276 if (m_data.conservativeMode == VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT &&
277 !context.getConservativeRasterizationPropertiesEXT().primitiveUnderestimation)
278 TCU_THROW(NotSupportedError, "primitiveUnderestimation not supported");
279 }
280
281 if (m_data.fragStencil)
282 context.requireDeviceFunctionality("VK_EXT_shader_stencil_export");
283
284 if (m_data.multiViewport &&
285 !context.getFragmentShadingRateProperties().primitiveFragmentShadingRateWithMultipleViewports)
286 TCU_THROW(NotSupportedError, "primitiveFragmentShadingRateWithMultipleViewports not supported");
287
288 if (m_data.srLayered &&
289 !context.getFragmentShadingRateProperties().layeredShadingRateAttachments)
290 TCU_THROW(NotSupportedError, "layeredShadingRateAttachments not supported");
291
292 if ((m_data.multiViewport || m_data.colorLayered) &&
293 !m_data.geometryShader)
294 context.requireDeviceFunctionality("VK_EXT_shader_viewport_index_layer");
295
296 if (m_data.multiView && m_data.geometryShader &&
297 !context.getMultiviewFeatures().multiviewGeometryShader)
298 TCU_THROW(NotSupportedError, "multiviewGeometryShader not supported");
299
300 if (m_data.interlock &&
301 !context.getFragmentShaderInterlockFeaturesEXT().fragmentShaderPixelInterlock)
302 TCU_THROW(NotSupportedError, "fragmentShaderPixelInterlock not supported");
303
304 if (m_data.sampleLocations)
305 {
306 context.requireDeviceFunctionality("VK_EXT_sample_locations");
307 if (!(m_data.samples & context.getSampleLocationsPropertiesEXT().sampleLocationSampleCounts))
308 TCU_THROW(NotSupportedError, "samples not supported in sampleLocationSampleCounts");
309 }
310
311 if (m_data.sampleMaskTest && !context.getFragmentShadingRateProperties().fragmentShadingRateWithSampleMask)
312 TCU_THROW(NotSupportedError, "fragmentShadingRateWithSampleMask not supported");
313 }
314
315 // Error codes writted by the fragment shader
316 enum
317 {
318 ERROR_NONE = 0,
319 ERROR_FRAGCOORD_CENTER = 1,
320 ERROR_VTG_READBACK = 2,
321 ERROR_FRAGCOORD_DERIV = 3,
322 ERROR_FRAGCOORD_IMPLICIT_DERIV = 4,
323 };
324
initPrograms(SourceCollections & programCollection) const325 void FSRTestCase::initPrograms (SourceCollections& programCollection) const
326 {
327 std::stringstream vss;
328
329 vss <<
330 "#version 450 core\n"
331 "#extension GL_EXT_fragment_shading_rate : enable\n"
332 "#extension GL_ARB_shader_viewport_layer_array : enable\n"
333 "layout(push_constant) uniform PC {\n"
334 " int shadingRate;\n"
335 "} pc;\n"
336 "layout(location = 0) in vec2 pos;\n"
337 "layout(location = 0) out int instanceIndex;\n"
338 "layout(location = 1) out int readbackok;\n"
339 "layout(location = 2) out float zero;\n"
340 "out gl_PerVertex\n"
341 "{\n"
342 " vec4 gl_Position;\n"
343 "};\n"
344 "void main()\n"
345 "{\n"
346 " gl_Position = vec4(pos, 0, 1);\n"
347 " instanceIndex = gl_InstanceIndex;\n"
348 " readbackok = 1;\n"
349 " zero = 0;\n";
350
351 if (m_data.shaderWritesRate)
352 {
353 vss << " gl_PrimitiveShadingRateEXT = pc.shadingRate;\n";
354
355 // Verify that we can read from the output variable
356 vss << " if (gl_PrimitiveShadingRateEXT != pc.shadingRate) readbackok = 0;\n";
357
358 if (!m_data.geometryShader)
359 {
360 if (m_data.multiViewport)
361 vss << " gl_ViewportIndex = instanceIndex & 1;\n";
362 if (m_data.colorLayered)
363 vss << " gl_Layer = (instanceIndex & 2) >> 1;\n";
364 }
365 }
366
367 vss << "}\n";
368
369 programCollection.glslSources.add("vert") << glu::VertexSource(vss.str());
370
371 if (m_data.geometryShader)
372 {
373 std::string writeShadingRate = "";
374 if (m_data.shaderWritesRate)
375 {
376 writeShadingRate =
377 " gl_PrimitiveShadingRateEXT = pc.shadingRate;\n"
378 " if (gl_PrimitiveShadingRateEXT != pc.shadingRate) readbackok = 0;\n";
379
380 if (m_data.multiViewport)
381 writeShadingRate += " gl_ViewportIndex = inInstanceIndex[0] & 1;\n";
382
383 if (m_data.colorLayered)
384 writeShadingRate += " gl_Layer = (inInstanceIndex[0] & 2) >> 1;\n";
385 }
386
387 std::stringstream gss;
388 gss <<
389 "#version 450 core\n"
390 "#extension GL_EXT_fragment_shading_rate : enable\n"
391 "\n"
392 "layout(push_constant) uniform PC {\n"
393 " int shadingRate;\n"
394 "} pc;\n"
395 "\n"
396 "in gl_PerVertex\n"
397 "{\n"
398 " vec4 gl_Position;\n"
399 "} gl_in[3];\n"
400 "\n"
401 "layout(location = 0) in int inInstanceIndex[];\n"
402 "layout(location = 0) out int outInstanceIndex;\n"
403 "layout(location = 1) out int readbackok;\n"
404 "layout(location = 2) out float zero;\n"
405 "layout(triangles) in;\n"
406 "layout(triangle_strip, max_vertices=3) out;\n"
407 "\n"
408 "out gl_PerVertex {\n"
409 " vec4 gl_Position;\n"
410 "};\n"
411 "\n"
412 "void main(void)\n"
413 "{\n"
414 " gl_Position = gl_in[0].gl_Position;\n"
415 " outInstanceIndex = inInstanceIndex[0];\n"
416 " readbackok = 1;\n"
417 " zero = 0;\n"
418 << writeShadingRate <<
419 " EmitVertex();"
420 "\n"
421 " gl_Position = gl_in[1].gl_Position;\n"
422 " outInstanceIndex = inInstanceIndex[1];\n"
423 " readbackok = 1;\n"
424 " zero = 0;\n"
425 << writeShadingRate <<
426 " EmitVertex();"
427 "\n"
428 " gl_Position = gl_in[2].gl_Position;\n"
429 " outInstanceIndex = inInstanceIndex[2];\n"
430 " readbackok = 1;\n"
431 " zero = 0;\n"
432 << writeShadingRate <<
433 " EmitVertex();"
434 "}\n";
435
436 programCollection.glslSources.add("geom") << glu::GeometrySource(gss.str());
437 }
438
439 std::stringstream fss;
440
441 fss <<
442 "#version 450 core\n"
443 "#extension GL_EXT_fragment_shading_rate : enable\n"
444 "#extension GL_ARB_shader_stencil_export : enable\n"
445 "#extension GL_ARB_fragment_shader_interlock : enable\n"
446 "layout(location = 0) out uvec4 col0;\n"
447 "layout(set = 0, binding = 0) buffer Block { uint counter; } buf;\n"
448 "layout(set = 0, binding = 3) uniform usampler2D tex;\n"
449 "layout(location = 0) flat in int instanceIndex;\n"
450 "layout(location = 1) flat in int readbackok;\n"
451 "layout(location = 2) " << (m_data.sampleShadingInput ? "sample " : "") << "in float zero;\n";
452
453 if (m_data.interlock)
454 fss << "layout(pixel_interlock_ordered) in;\n";
455
456 fss <<
457 "void main()\n"
458 "{\n";
459
460 if (m_data.interlock)
461 fss << " beginInvocationInterlockARB();\n";
462
463 fss <<
464 // X component gets shading rate enum
465 " col0.x = gl_ShadingRateEXT;\n"
466 " col0.y = 0;\n"
467 // Z component gets packed primitiveID | atomic value
468 " col0.z = (instanceIndex << 24) | ((atomicAdd(buf.counter, 1) + 1) & 0x00FFFFFFu);\n"
469 " ivec2 fragCoordXY = ivec2(gl_FragCoord.xy);\n"
470 " ivec2 fragSize = ivec2(1<<((gl_ShadingRateEXT/4)&3), 1<<(gl_ShadingRateEXT&3));\n"
471 // W component gets error code
472 " col0.w = uint(zero)" << (m_data.sampleShadingInput ? " * gl_SampleID" : "") << ";\n"
473 " if (((fragCoordXY - fragSize / 2) % fragSize) != ivec2(0,0))\n"
474 " col0.w = " << ERROR_FRAGCOORD_CENTER << ";\n";
475
476 if (m_data.shaderWritesRate)
477 {
478 fss <<
479 " if (readbackok != 1)\n"
480 " col0.w = " << ERROR_VTG_READBACK << ";\n";
481 }
482
483 // When sample shading, gl_FragCoord is more likely to give bad derivatives,
484 // e.g. due to a partially covered quad having some pixels center sample and
485 // some sample at a sample location.
486 if (!m_data.sampleShadingEnable && !m_data.sampleShadingInput)
487 {
488 fss << " if (dFdx(gl_FragCoord.xy) != ivec2(fragSize.x, 0) || dFdy(gl_FragCoord.xy) != ivec2(0, fragSize.y))\n"
489 " col0.w = (fragSize.y << 26) | (fragSize.x << 20) | (int(dFdx(gl_FragCoord.xy)) << 14) | (int(dFdx(gl_FragCoord.xy)) << 8) | " << ERROR_FRAGCOORD_DERIV << ";\n";
490
491 fss << " uint implicitDerivX = texture(tex, vec2(gl_FragCoord.x / textureSize(tex, 0).x, 0)).x;\n"
492 " uint implicitDerivY = texture(tex, vec2(0, gl_FragCoord.y / textureSize(tex, 0).y)).x;\n"
493 " if (implicitDerivX != fragSize.x || implicitDerivY != fragSize.y)\n"
494 " col0.w = (fragSize.y << 26) | (fragSize.x << 20) | (implicitDerivY << 14) | (implicitDerivX << 8) | " << ERROR_FRAGCOORD_IMPLICIT_DERIV << ";\n";
495 }
496 // Y component gets sample mask value
497 if (m_data.useSampleMaskIn)
498 fss << " col0.y = gl_SampleMaskIn[0];\n";
499
500 if (m_data.fragDepth)
501 fss << " gl_FragDepth = float(instanceIndex) / float(" << NUM_TRIANGLES << ");\n";
502
503 if (m_data.fragStencil)
504 fss << " gl_FragStencilRefARB = instanceIndex;\n";
505
506 if (m_data.interlock)
507 fss << " endInvocationInterlockARB();\n";
508
509 fss <<
510 "}\n";
511
512 programCollection.glslSources.add("frag") << glu::FragmentSource(fss.str());
513
514 std::stringstream css;
515
516 std::string fsampType = m_data.samples > 1 ? "texture2DMSArray" : "texture2DArray";
517 std::string usampType = m_data.samples > 1 ? "utexture2DMSArray" : "utexture2DArray";
518
519 // Compute shader copies color/depth/stencil to linear layout in buffer memory
520 css <<
521 "#version 450 core\n"
522 "#extension GL_EXT_samplerless_texture_functions : enable\n"
523 "layout(set = 0, binding = 1) uniform " << usampType << " colorTex;\n"
524 "layout(set = 0, binding = 2, std430) buffer Block0 { uvec4 b[]; } colorbuf;\n"
525 "layout(set = 0, binding = 4, std430) buffer Block1 { float b[]; } depthbuf;\n"
526 "layout(set = 0, binding = 5, std430) buffer Block2 { uint b[]; } stencilbuf;\n"
527 "layout(set = 0, binding = 6) uniform " << fsampType << " depthTex;\n"
528 "layout(set = 0, binding = 7) uniform " << usampType << " stencilTex;\n"
529 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
530 "void main()\n"
531 "{\n"
532 " for (int i = 0; i < " << m_data.samples << "; ++i) {\n"
533 " uint idx = ((gl_GlobalInvocationID.z * " << m_data.framebufferDim.height << " + gl_GlobalInvocationID.y) * " << m_data.framebufferDim.width << " + gl_GlobalInvocationID.x) * " << m_data.samples << " + i;\n"
534 " colorbuf.b[idx] = texelFetch(colorTex, ivec3(gl_GlobalInvocationID.xyz), i);\n";
535
536 if (m_data.fragDepth)
537 css << " depthbuf.b[idx] = texelFetch(depthTex, ivec3(gl_GlobalInvocationID.xyz), i).x;\n";
538
539 if (m_data.fragStencil)
540 css << " stencilbuf.b[idx] = texelFetch(stencilTex, ivec3(gl_GlobalInvocationID.xyz), i).x;\n";
541
542 css <<
543 " }\n"
544 "}\n";
545
546 programCollection.glslSources.add("comp") << glu::ComputeSource(css.str());
547 }
548
createInstance(Context & context) const549 TestInstance* FSRTestCase::createInstance (Context& context) const
550 {
551 return new FSRTestInstance(context, m_data);
552 }
553
ShadingRateExtentToEnum(VkExtent2D ext) const554 deInt32 FSRTestInstance::ShadingRateExtentToEnum(VkExtent2D ext) const
555 {
556 ext.width = deCtz32(ext.width);
557 ext.height = deCtz32(ext.height);
558
559 return (ext.width << 2) | ext.height;
560 }
561
ShadingRateEnumToExtent(deInt32 rate) const562 VkExtent2D FSRTestInstance::ShadingRateEnumToExtent(deInt32 rate) const
563 {
564 VkExtent2D ret;
565 ret.width = 1 << ((rate/4) & 3);
566 ret.height = 1 << (rate & 3);
567
568 return ret;
569 }
570
Combine(VkExtent2D ext0,VkExtent2D ext1,VkFragmentShadingRateCombinerOpKHR comb) const571 VkExtent2D FSRTestInstance::Combine(VkExtent2D ext0, VkExtent2D ext1, VkFragmentShadingRateCombinerOpKHR comb) const
572 {
573 VkExtent2D ret;
574 switch (comb)
575 {
576 default:
577 DE_ASSERT(0);
578 // fallthrough
579 case VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR:
580 return ext0;
581 case VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR:
582 return ext1;
583 case VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MIN_KHR:
584 ret = { de::min(ext0.width, ext1.width), de::min(ext0.height, ext1.height) };
585 return ret;
586 case VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_KHR:
587 ret = { de::max(ext0.width, ext1.width), de::max(ext0.height, ext1.height) };
588 return ret;
589 case VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_KHR:
590 ret = { ext0.width * ext1.width, ext0.height * ext1.height };
591 if (!m_shadingRateProperties.fragmentShadingRateStrictMultiplyCombiner)
592 {
593 if (ext0.width == 1 && ext1.width == 1)
594 ret.width = 2;
595 if (ext0.height == 1 && ext1.height == 1)
596 ret.height = 2;
597 }
598 return ret;
599 }
600 }
601
Simulate(deInt32 rate0,deInt32 rate1,deInt32 rate2)602 deInt32 FSRTestInstance::Simulate(deInt32 rate0, deInt32 rate1, deInt32 rate2)
603 {
604 deInt32 &cachedRate = m_simulateCache[(rate2*m_simulateValueCount + rate1)*m_simulateValueCount + rate0];
605 if (cachedRate != ~0)
606 return cachedRate;
607
608 VkExtent2D extent0 = ShadingRateEnumToExtent(rate0);
609 VkExtent2D extent1 = ShadingRateEnumToExtent(rate1);
610 VkExtent2D extent2 = ShadingRateEnumToExtent(rate2);
611
612 deInt32 finalMask = 0;
613 // Simulate once for implementations that don't allow swapping rate xy,
614 // and once for those that do. Any of those results is allowed.
615 for (deUint32 allowSwap = 0; allowSwap <= 1; ++allowSwap)
616 {
617 // Combine rate 0 and 1, get a mask of possible clamped rates
618 VkExtent2D intermed = Combine(extent0, extent1, m_data.combinerOp[0]);
619 deInt32 intermedMask = ShadingRateExtentToClampedMask(intermed, allowSwap == 1);
620
621 // For each clamped rate, combine that with rate 2 and accumulate the possible clamped rates
622 for (int i = 0; i < 16; ++i)
623 {
624 if (intermedMask & (1<<i))
625 {
626 VkExtent2D final = Combine(ShadingRateEnumToExtent(i), extent2, m_data.combinerOp[1]);
627 finalMask |= ShadingRateExtentToClampedMask(final, allowSwap == 1);
628 }
629 }
630 {
631 // unclamped intermediate value is also permitted
632 VkExtent2D final = Combine(intermed, extent2, m_data.combinerOp[1]);
633 finalMask |= ShadingRateExtentToClampedMask(final, allowSwap == 1);
634 }
635 }
636
637 if (Force1x1())
638 finalMask = 0x1;
639
640 cachedRate = finalMask;
641 return finalMask;
642 }
643
644 // If a rate is not valid (<=4x4), clamp it to something valid.
645 // This is only used for "inputs" to the system, not to mimic
646 // how the implementation internally clamps intermediate values.
SanitizeExtent(VkExtent2D ext) const647 VkExtent2D FSRTestInstance::SanitizeExtent(VkExtent2D ext) const
648 {
649 DE_ASSERT(ext.width > 0 && ext.height > 0);
650
651 ext.width = de::min(ext.width, 4u);
652 ext.height = de::min(ext.height, 4u);
653
654 return ext;
655 }
656
657 // Map an extent to a mask of all modes smaller than or equal to it in either dimension
ShadingRateExtentToClampedMask(VkExtent2D ext,bool allowSwap) const658 deInt32 FSRTestInstance::ShadingRateExtentToClampedMask(VkExtent2D ext, bool allowSwap) const
659 {
660 deUint32 desiredSize = ext.width * ext.height;
661
662 deInt32 mask = 0;
663
664 while (desiredSize > 0)
665 {
666 // First, find modes that maximize the area
667 for (deUint32 i = 0; i < m_supportedFragmentShadingRateCount; ++i)
668 {
669 const VkPhysicalDeviceFragmentShadingRateKHR &supportedRate = m_supportedFragmentShadingRates[i];
670 if ((supportedRate.sampleCounts & m_data.samples) &&
671 supportedRate.fragmentSize.width * supportedRate.fragmentSize.height == desiredSize &&
672 ((supportedRate.fragmentSize.width <= ext.width && supportedRate.fragmentSize.height <= ext.height) ||
673 (supportedRate.fragmentSize.height <= ext.width && supportedRate.fragmentSize.width <= ext.height && allowSwap)))
674 {
675 mask |= 1 << ShadingRateExtentToEnum(supportedRate.fragmentSize);
676 }
677 }
678 if (mask)
679 {
680 // Amongst the modes that maximize the area, pick the ones that
681 // minimize the aspect ratio. Prefer ratio of 1, then 2, then 4.
682 // 1x1 = 0, 2x2 = 5, 4x4 = 10
683 static const deUint32 aspectMaskRatio1 = 0x421;
684 // 2x1 = 4, 1x2 = 1, 4x2 = 9, 2x4 = 6
685 static const deUint32 aspectMaskRatio2 = 0x252;
686 // 4x1 = 8, 1x4 = 2,
687 static const deUint32 aspectMaskRatio4 = 0x104;
688
689 if (mask & aspectMaskRatio1)
690 {
691 mask &= aspectMaskRatio1;
692 break;
693 }
694 if (mask & aspectMaskRatio2)
695 {
696 mask &= aspectMaskRatio2;
697 break;
698 }
699 if (mask & aspectMaskRatio4)
700 {
701 mask &= aspectMaskRatio4;
702 break;
703 }
704 DE_ASSERT(0);
705 }
706 desiredSize /= 2;
707 }
708
709 return mask;
710 }
711
712
SanitizeRate(deInt32 rate) const713 deInt32 FSRTestInstance::SanitizeRate(deInt32 rate) const
714 {
715 VkExtent2D extent = ShadingRateEnumToExtent(rate);
716
717 extent = SanitizeExtent(extent);
718
719 return ShadingRateExtentToEnum(extent);
720 }
721
722 // Map primID % 9 to primitive shading rate
PrimIDToPrimitiveShadingRate(deInt32 primID)723 deInt32 FSRTestInstance::PrimIDToPrimitiveShadingRate(deInt32 primID)
724 {
725 deInt32 &cachedRate = m_primIDToPrimitiveShadingRate[primID];
726 if (cachedRate != ~0)
727 return cachedRate;
728
729 VkExtent2D extent;
730 extent.width = 1 << (primID % 3);
731 extent.height = 1 << ((primID/3) % 3);
732
733 cachedRate = ShadingRateExtentToEnum(extent);
734 return cachedRate;
735 }
736
737 // Map primID / 9 to pipeline shading rate
PrimIDToPipelineShadingRate(deInt32 primID)738 deInt32 FSRTestInstance::PrimIDToPipelineShadingRate(deInt32 primID)
739 {
740 deInt32 &cachedRate = m_primIDToPipelineShadingRate[primID];
741 if (cachedRate != ~0)
742 return cachedRate;
743
744 primID /= 9;
745 VkExtent2D extent;
746 extent.width = 1 << (primID % 3);
747 extent.height = 1 << ((primID/3) % 3);
748
749 cachedRate = ShadingRateExtentToEnum(extent);
750 return cachedRate;
751 }
752
CreateCachedBuffer(const vk::DeviceInterface & vk,const vk::VkDevice device,vk::Allocator & allocator,const vk::VkBufferCreateInfo & bufferCreateInfo)753 static de::MovePtr<BufferWithMemory> CreateCachedBuffer(const vk::DeviceInterface& vk,
754 const vk::VkDevice device,
755 vk::Allocator& allocator,
756 const vk::VkBufferCreateInfo& bufferCreateInfo)
757 {
758 try
759 {
760 return de::MovePtr<BufferWithMemory>(new BufferWithMemory(
761 vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Cached));
762 }
763 catch (const tcu::NotSupportedError&)
764 {
765 return de::MovePtr<BufferWithMemory>(new BufferWithMemory(
766 vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible));
767 }
768 }
769
iterate(void)770 tcu::TestStatus FSRTestInstance::iterate (void)
771 {
772 const DeviceInterface& vk = m_context.getDeviceInterface();
773 const VkDevice device = m_context.getDevice();
774 tcu::TestLog& log = m_context.getTestContext().getLog();
775 Allocator& allocator = m_context.getDefaultAllocator();
776 VkFlags allShaderStages = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT;
777 VkFlags allPipelineStages = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
778 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
779 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
780 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
781 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
782 VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT |
783 VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV;
784 const VkFormat cbFormat = VK_FORMAT_R32G32B32A32_UINT;
785 const VkFormat dsFormat = VK_FORMAT_D32_SFLOAT_S8_UINT;
786
787 if (m_data.geometryShader)
788 {
789 allShaderStages |= VK_SHADER_STAGE_GEOMETRY_BIT;
790 allPipelineStages |= VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
791 }
792
793 deRandom rnd;
794 deRandom_init(&rnd, m_data.seed);
795
796 qpTestResult res = QP_TEST_RESULT_PASS;
797 deUint32 numUnexpected1x1Samples = 0;
798 deUint32 numTotalSamples = 0;
799
800 enum AttachmentModes
801 {
802 ATTACHMENT_MODE_DEFAULT = 0,
803 ATTACHMENT_MODE_LAYOUT_OPTIMAL,
804 ATTACHMENT_MODE_IMAGELESS,
805 ATTACHMENT_MODE_2DARRAY,
806 ATTACHMENT_MODE_TILING_LINEAR,
807
808 ATTACHMENT_MODE_COUNT,
809 };
810
811 deUint32 numSRLayers = m_data.srLayered ? 2u : 1u;
812
813 VkExtent2D minFragmentShadingRateAttachmentTexelSize = {1, 1};
814 VkExtent2D maxFragmentShadingRateAttachmentTexelSize = {1, 1};
815 deUint32 maxFragmentShadingRateAttachmentTexelSizeAspectRatio = 1;
816 if (m_context.getFragmentShadingRateFeatures().attachmentFragmentShadingRate)
817 {
818 minFragmentShadingRateAttachmentTexelSize = m_context.getFragmentShadingRateProperties().minFragmentShadingRateAttachmentTexelSize;
819 maxFragmentShadingRateAttachmentTexelSize = m_context.getFragmentShadingRateProperties().maxFragmentShadingRateAttachmentTexelSize;
820 maxFragmentShadingRateAttachmentTexelSizeAspectRatio = m_context.getFragmentShadingRateProperties().maxFragmentShadingRateAttachmentTexelSizeAspectRatio;
821 }
822
823 VkDeviceSize atomicBufferSize = sizeof(deUint32);
824
825 de::MovePtr<BufferWithMemory> atomicBuffer;
826 atomicBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
827 vk, device, allocator, makeBufferCreateInfo(atomicBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible | MemoryRequirement::Coherent));
828
829 deUint32 *abuf = (deUint32 *)atomicBuffer->getAllocation().getHostPtr();
830
831 // NUM_TRIANGLES triangles, 3 vertices, 2 components of float position
832 VkDeviceSize vertexBufferSize = NUM_TRIANGLES * 3 * 2 * sizeof(float);
833
834 de::MovePtr<BufferWithMemory> vertexBuffer;
835 vertexBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
836 vk, device, allocator, makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible | MemoryRequirement::Coherent));
837
838 float *vbuf = (float *)vertexBuffer->getAllocation().getHostPtr();
839 for (deInt32 i = 0; i < (deInt32)(vertexBufferSize / sizeof(float)); ++i)
840 {
841 vbuf[i] = deRandom_getFloat(&rnd)*2.0f - 1.0f;
842 }
843 flushAlloc(vk, device, vertexBuffer->getAllocation());
844
845 VkDeviceSize colorOutputBufferSize = m_data.framebufferDim.width * m_data.framebufferDim.height * m_data.samples * 4 * sizeof(deUint32) * m_data.numColorLayers;
846 de::MovePtr<BufferWithMemory> colorOutputBuffer = CreateCachedBuffer(vk, device, allocator, makeBufferCreateInfo(colorOutputBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT));
847
848 VkDeviceSize depthOutputBufferSize = 0, stencilOutputBufferSize = 0;
849 de::MovePtr<BufferWithMemory> depthOutputBuffer, stencilOutputBuffer;
850 if (m_data.useDepthStencil)
851 {
852 depthOutputBufferSize = m_data.framebufferDim.width * m_data.framebufferDim.height * m_data.samples * sizeof(float) * m_data.numColorLayers;
853 depthOutputBuffer = CreateCachedBuffer(vk, device, allocator, makeBufferCreateInfo(depthOutputBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT));
854
855 stencilOutputBufferSize = m_data.framebufferDim.width * m_data.framebufferDim.height * m_data.samples * sizeof(deUint32) * m_data.numColorLayers;
856 stencilOutputBuffer = CreateCachedBuffer(vk, device, allocator, makeBufferCreateInfo(stencilOutputBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT));
857 }
858
859 deUint32 minSRTexelWidth = minFragmentShadingRateAttachmentTexelSize.width;
860 deUint32 minSRTexelHeight = minFragmentShadingRateAttachmentTexelSize.height;
861 deUint32 maxSRWidth = (m_data.framebufferDim.width + minSRTexelWidth - 1) / minSRTexelWidth;
862 deUint32 maxSRHeight = (m_data.framebufferDim.height + minSRTexelHeight - 1) / minSRTexelHeight;
863
864 // max size over all formats
865 VkDeviceSize srFillBufferSize = numSRLayers * maxSRWidth * maxSRHeight * 32/*4 component 64-bit*/;
866 de::MovePtr<BufferWithMemory> srFillBuffer;
867 deUint8 *fillPtr = DE_NULL;
868 if (m_data.useAttachment())
869 {
870 srFillBuffer = CreateCachedBuffer(vk, device, allocator, makeBufferCreateInfo(srFillBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT));
871 fillPtr = (deUint8 *)srFillBuffer->getAllocation().getHostPtr();
872 }
873
874 de::MovePtr<ImageWithMemory> cbImage;
875 Move<VkImageView> cbImageView;
876 {
877 const VkImageCreateInfo imageCreateInfo =
878 {
879 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
880 DE_NULL, // const void* pNext;
881 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
882 VK_IMAGE_TYPE_2D, // VkImageType imageType;
883 cbFormat, // VkFormat format;
884 {
885 m_data.framebufferDim.width, // deUint32 width;
886 m_data.framebufferDim.height, // deUint32 height;
887 1u // deUint32 depth;
888 }, // VkExtent3D extent;
889 1u, // deUint32 mipLevels;
890 m_data.numColorLayers, // deUint32 arrayLayers;
891 m_data.samples, // VkSampleCountFlagBits samples;
892 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
893 cbUsage, // VkImageUsageFlags usage;
894 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
895 0u, // deUint32 queueFamilyIndexCount;
896 DE_NULL, // const deUint32* pQueueFamilyIndices;
897 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
898 };
899 cbImage = de::MovePtr<ImageWithMemory>(new ImageWithMemory(
900 vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
901
902 VkImageViewCreateInfo imageViewCreateInfo =
903 {
904 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
905 DE_NULL, // const void* pNext;
906 (VkImageViewCreateFlags)0u, // VkImageViewCreateFlags flags;
907 **cbImage, // VkImage image;
908 VK_IMAGE_VIEW_TYPE_2D_ARRAY, // VkImageViewType viewType;
909 cbFormat, // VkFormat format;
910 {
911 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
912 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
913 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
914 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
915 }, // VkComponentMapping components;
916 {
917 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
918 0u, // deUint32 baseMipLevel;
919 1u, // deUint32 levelCount;
920 0u, // deUint32 baseArrayLayer;
921 m_data.numColorLayers // deUint32 layerCount;
922 } // VkImageSubresourceRange subresourceRange;
923 };
924 cbImageView = createImageView(vk, device, &imageViewCreateInfo, NULL);
925 }
926
927 de::MovePtr<ImageWithMemory> dsImage;
928 Move<VkImageView> dsImageView, dImageView, sImageView;
929 VkImageUsageFlags dsUsage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
930 VK_IMAGE_USAGE_SAMPLED_BIT |
931 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
932 VK_IMAGE_USAGE_TRANSFER_DST_BIT;
933 if (m_data.useDepthStencil)
934 {
935 const VkImageCreateInfo imageCreateInfo =
936 {
937 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
938 DE_NULL, // const void* pNext;
939 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
940 VK_IMAGE_TYPE_2D, // VkImageType imageType;
941 dsFormat, // VkFormat format;
942 {
943 m_data.framebufferDim.width, // deUint32 width;
944 m_data.framebufferDim.height, // deUint32 height;
945 1u // deUint32 depth;
946 }, // VkExtent3D extent;
947 1u, // deUint32 mipLevels;
948 m_data.numColorLayers, // deUint32 arrayLayers;
949 m_data.samples, // VkSampleCountFlagBits samples;
950 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
951 dsUsage, // VkImageUsageFlags usage;
952 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
953 0u, // deUint32 queueFamilyIndexCount;
954 DE_NULL, // const deUint32* pQueueFamilyIndices;
955 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
956 };
957 dsImage = de::MovePtr<ImageWithMemory>(new ImageWithMemory(
958 vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
959
960 VkImageViewCreateInfo imageViewCreateInfo =
961 {
962 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
963 DE_NULL, // const void* pNext;
964 (VkImageViewCreateFlags)0u, // VkImageViewCreateFlags flags;
965 **dsImage, // VkImage image;
966 VK_IMAGE_VIEW_TYPE_2D_ARRAY, // VkImageViewType viewType;
967 dsFormat, // VkFormat format;
968 {
969 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
970 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
971 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
972 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
973 }, // VkComponentMapping components;
974 {
975 VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags aspectMask;
976 0u, // deUint32 baseMipLevel;
977 1u, // deUint32 levelCount;
978 0u, // deUint32 baseArrayLayer;
979 m_data.numColorLayers // deUint32 layerCount;
980 } // VkImageSubresourceRange subresourceRange;
981 };
982 dsImageView = createImageView(vk, device, &imageViewCreateInfo, NULL);
983 imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
984 dImageView = createImageView(vk, device, &imageViewCreateInfo, NULL);
985 imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
986 sImageView = createImageView(vk, device, &imageViewCreateInfo, NULL);
987 }
988
989 // Image used to test implicit derivative calculations.
990 // Filled with a value of 1<<lod.
991 de::MovePtr<ImageWithMemory> derivImage;
992 Move<VkImageView> derivImageView;
993 VkImageUsageFlags derivUsage = VK_IMAGE_USAGE_SAMPLED_BIT |
994 VK_IMAGE_USAGE_TRANSFER_DST_BIT;
995 deUint32 derivNumLevels;
996 {
997 deUint32 maxDim = de::max(m_context.getFragmentShadingRateProperties().maxFragmentSize.width, m_context.getFragmentShadingRateProperties().maxFragmentSize.height);
998 derivNumLevels = 1 + deCtz32(maxDim);
999 const VkImageCreateInfo imageCreateInfo =
1000 {
1001 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1002 DE_NULL, // const void* pNext;
1003 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
1004 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1005 VK_FORMAT_R32_UINT, // VkFormat format;
1006 {
1007 m_context.getFragmentShadingRateProperties().maxFragmentSize.width, // deUint32 width;
1008 m_context.getFragmentShadingRateProperties().maxFragmentSize.height, // deUint32 height;
1009 1u // deUint32 depth;
1010 }, // VkExtent3D extent;
1011 derivNumLevels, // deUint32 mipLevels;
1012 1u, // deUint32 arrayLayers;
1013 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
1014 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1015 derivUsage, // VkImageUsageFlags usage;
1016 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1017 0u, // deUint32 queueFamilyIndexCount;
1018 DE_NULL, // const deUint32* pQueueFamilyIndices;
1019 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
1020 };
1021 derivImage = de::MovePtr<ImageWithMemory>(new ImageWithMemory(
1022 vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
1023
1024 VkImageViewCreateInfo imageViewCreateInfo =
1025 {
1026 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1027 DE_NULL, // const void* pNext;
1028 (VkImageViewCreateFlags)0u, // VkImageViewCreateFlags flags;
1029 **derivImage, // VkImage image;
1030 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
1031 VK_FORMAT_R32_UINT, // VkFormat format;
1032 {
1033 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
1034 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
1035 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
1036 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
1037 }, // VkComponentMapping components;
1038 {
1039 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1040 0u, // deUint32 baseMipLevel;
1041 derivNumLevels, // deUint32 levelCount;
1042 0u, // deUint32 baseArrayLayer;
1043 1u // deUint32 layerCount;
1044 } // VkImageSubresourceRange subresourceRange;
1045 };
1046 derivImageView = createImageView(vk, device, &imageViewCreateInfo, NULL);
1047 }
1048
1049 // sampler used with derivImage
1050 const struct VkSamplerCreateInfo samplerInfo =
1051 {
1052 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // sType
1053 DE_NULL, // pNext
1054 0u, // flags
1055 VK_FILTER_NEAREST, // magFilter
1056 VK_FILTER_NEAREST, // minFilter
1057 VK_SAMPLER_MIPMAP_MODE_NEAREST, // mipmapMode
1058 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeU
1059 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeV
1060 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeW
1061 0.0f, // mipLodBias
1062 VK_FALSE, // anisotropyEnable
1063 1.0f, // maxAnisotropy
1064 DE_FALSE, // compareEnable
1065 VK_COMPARE_OP_ALWAYS, // compareOp
1066 0.0f, // minLod
1067 (float)derivNumLevels, // maxLod
1068 VK_BORDER_COLOR_INT_TRANSPARENT_BLACK, // borderColor
1069 VK_FALSE, // unnormalizedCoords
1070 };
1071
1072 Move<VkSampler> sampler = createSampler(vk, device, &samplerInfo);
1073
1074 Move<vk::VkDescriptorSetLayout> descriptorSetLayout;
1075 VkDescriptorSetLayoutCreateFlags layoutCreateFlags = 0;
1076
1077 const VkDescriptorSetLayoutBinding bindings[] =
1078 {
1079 {
1080 0u, // binding
1081 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // descriptorType
1082 1u, // descriptorCount
1083 allShaderStages, // stageFlags
1084 DE_NULL, // pImmutableSamplers
1085 },
1086 {
1087 1u, // binding
1088 VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, // descriptorType
1089 1u, // descriptorCount
1090 allShaderStages, // stageFlags
1091 DE_NULL, // pImmutableSamplers
1092 },
1093 {
1094 2u, // binding
1095 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // descriptorType
1096 1u, // descriptorCount
1097 allShaderStages, // stageFlags
1098 DE_NULL, // pImmutableSamplers
1099 },
1100 {
1101 3u, // binding
1102 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, // descriptorType
1103 1u, // descriptorCount
1104 allShaderStages, // stageFlags
1105 DE_NULL, // pImmutableSamplers
1106 },
1107 {
1108 4u, // binding
1109 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // descriptorType
1110 1u, // descriptorCount
1111 allShaderStages, // stageFlags
1112 DE_NULL, // pImmutableSamplers
1113 },
1114 {
1115 5u, // binding
1116 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // descriptorType
1117 1u, // descriptorCount
1118 allShaderStages, // stageFlags
1119 DE_NULL, // pImmutableSamplers
1120 },
1121 {
1122 6u, // binding
1123 VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, // descriptorType
1124 1u, // descriptorCount
1125 allShaderStages, // stageFlags
1126 DE_NULL, // pImmutableSamplers
1127 },
1128 {
1129 7u, // binding
1130 VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, // descriptorType
1131 1u, // descriptorCount
1132 allShaderStages, // stageFlags
1133 DE_NULL, // pImmutableSamplers
1134 },
1135 };
1136
1137 // Create a layout and allocate a descriptor set for it.
1138 const VkDescriptorSetLayoutCreateInfo setLayoutCreateInfo =
1139 {
1140 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // sType
1141 DE_NULL, // pNext
1142 layoutCreateFlags, // flags
1143 sizeof(bindings)/sizeof(bindings[0]), // bindingCount
1144 &bindings[0] // pBindings
1145 };
1146
1147 descriptorSetLayout = vk::createDescriptorSetLayout(vk, device, &setLayoutCreateInfo);
1148
1149 const VkPushConstantRange pushConstantRange =
1150 {
1151 allShaderStages, // VkShaderStageFlags stageFlags;
1152 0u, // deUint32 offset;
1153 sizeof(deInt32) // deUint32 size;
1154 };
1155
1156 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
1157 {
1158 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType
1159 DE_NULL, // pNext
1160 (VkPipelineLayoutCreateFlags)0,
1161 1, // setLayoutCount
1162 &descriptorSetLayout.get(), // pSetLayouts
1163 1u, // pushConstantRangeCount
1164 &pushConstantRange, // pPushConstantRanges
1165 };
1166
1167 Move<VkPipelineLayout> pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo, NULL);
1168
1169 const Unique<VkShaderModule> cs (createShaderModule(vk, device, m_context.getBinaryCollection().get("comp"), 0));
1170
1171 const VkPipelineShaderStageCreateInfo csShaderCreateInfo =
1172 {
1173 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1174 DE_NULL,
1175 (VkPipelineShaderStageCreateFlags)0,
1176 VK_SHADER_STAGE_COMPUTE_BIT, // stage
1177 *cs, // shader
1178 "main",
1179 DE_NULL, // pSpecializationInfo
1180 };
1181
1182 const VkComputePipelineCreateInfo pipelineCreateInfo =
1183 {
1184 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
1185 DE_NULL,
1186 0u, // flags
1187 csShaderCreateInfo, // cs
1188 *pipelineLayout, // layout
1189 (vk::VkPipeline)0, // basePipelineHandle
1190 0u, // basePipelineIndex
1191 };
1192 Move<VkPipeline> computePipeline = createComputePipeline(vk, device, DE_NULL, &pipelineCreateInfo, NULL);
1193
1194 for (deUint32 modeIdx = 0; modeIdx < ATTACHMENT_MODE_COUNT; ++modeIdx)
1195 {
1196 // If we're not using an attachment, don't test all the different attachment modes
1197 if (modeIdx != ATTACHMENT_MODE_DEFAULT && !m_data.useAttachment())
1198 continue;
1199
1200 // Consider all uint formats possible
1201 static const VkFormat srFillFormats[] =
1202 {
1203 VK_FORMAT_R8_UINT,
1204 VK_FORMAT_R8G8_UINT,
1205 VK_FORMAT_R8G8B8_UINT,
1206 VK_FORMAT_R8G8B8A8_UINT,
1207 VK_FORMAT_R16_UINT,
1208 VK_FORMAT_R16G16_UINT,
1209 VK_FORMAT_R16G16B16_UINT,
1210 VK_FORMAT_R16G16B16A16_UINT,
1211 VK_FORMAT_R32_UINT,
1212 VK_FORMAT_R32G32_UINT,
1213 VK_FORMAT_R32G32B32_UINT,
1214 VK_FORMAT_R32G32B32A32_UINT,
1215 VK_FORMAT_R64_UINT,
1216 VK_FORMAT_R64G64_UINT,
1217 VK_FORMAT_R64G64B64_UINT,
1218 VK_FORMAT_R64G64B64A64_UINT,
1219 };
1220 // Only test all formats in the default mode
1221 deUint32 numFillFormats = modeIdx == ATTACHMENT_MODE_DEFAULT ? (deUint32)(sizeof(srFillFormats)/sizeof(srFillFormats[0])) : 1u;
1222
1223 // Iterate over all supported tile sizes and formats
1224 for (deUint32 srTexelWidth = minFragmentShadingRateAttachmentTexelSize.width;
1225 srTexelWidth <= maxFragmentShadingRateAttachmentTexelSize.width;
1226 srTexelWidth *= 2)
1227 for (deUint32 srTexelHeight = minFragmentShadingRateAttachmentTexelSize.height;
1228 srTexelHeight <= maxFragmentShadingRateAttachmentTexelSize.height;
1229 srTexelHeight *= 2)
1230 for (deUint32 formatIdx = 0; formatIdx < numFillFormats; ++formatIdx)
1231 {
1232
1233 deUint32 aspectRatio = (srTexelHeight > srTexelWidth) ? (srTexelHeight / srTexelWidth) : (srTexelWidth / srTexelHeight);
1234 if (aspectRatio > maxFragmentShadingRateAttachmentTexelSizeAspectRatio)
1235 continue;
1236
1237 // Go through the loop only once when not using an attachment
1238 if (!m_data.useAttachment() &&
1239 (srTexelWidth != minFragmentShadingRateAttachmentTexelSize.width ||
1240 srTexelHeight != minFragmentShadingRateAttachmentTexelSize.height ||
1241 formatIdx != 0))
1242 continue;
1243
1244 bool imagelessFB = modeIdx == ATTACHMENT_MODE_IMAGELESS;
1245
1246 deUint32 srWidth = (m_data.framebufferDim.width + srTexelWidth - 1) / srTexelWidth;
1247 deUint32 srHeight = (m_data.framebufferDim.height + srTexelHeight - 1) / srTexelHeight;
1248
1249 VkFormat srFormat = srFillFormats[formatIdx];
1250 deUint32 srFillBpp = tcu::getPixelSize(mapVkFormat(srFormat));
1251
1252 VkImageLayout srLayout = modeIdx == ATTACHMENT_MODE_LAYOUT_OPTIMAL ? VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR : VK_IMAGE_LAYOUT_GENERAL;
1253 VkImageViewType srViewType = modeIdx == ATTACHMENT_MODE_2DARRAY ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D;
1254 VkImageTiling srTiling = (modeIdx == ATTACHMENT_MODE_TILING_LINEAR) ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL;
1255
1256 VkFormatProperties srFormatProperties;
1257 m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), srFormat, &srFormatProperties);
1258 VkFormatFeatureFlags srFormatFeatures = srTiling == VK_IMAGE_TILING_LINEAR ? srFormatProperties.linearTilingFeatures : srFormatProperties.optimalTilingFeatures;
1259
1260 if (m_context.getFragmentShadingRateFeatures().attachmentFragmentShadingRate &&
1261 !(srFormatFeatures & VK_FORMAT_FEATURE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR))
1262 {
1263 if (srFormat == VK_FORMAT_R8_UINT && srTiling == VK_IMAGE_TILING_OPTIMAL)
1264 {
1265 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;
1266 res = QP_TEST_RESULT_FAIL;
1267 }
1268 continue;
1269 }
1270
1271 Move<vk::VkDescriptorPool> descriptorPool;
1272 Move<vk::VkDescriptorSet> descriptorSet;
1273 VkDescriptorPoolCreateFlags poolCreateFlags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
1274
1275 vk::DescriptorPoolBuilder poolBuilder;
1276 for (deInt32 i = 0; i < (deInt32)(sizeof(bindings)/sizeof(bindings[0])); ++i)
1277 poolBuilder.addType(bindings[i].descriptorType, bindings[i].descriptorCount);
1278
1279 descriptorPool = poolBuilder.build(vk, device, poolCreateFlags, 1u);
1280 descriptorSet = makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout);
1281
1282 de::MovePtr<ImageWithMemory> srImage;
1283 Move<VkImageView> srImageView;
1284 VkImageUsageFlags srUsage = VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR |
1285 VK_IMAGE_USAGE_TRANSFER_DST_BIT |
1286 VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1287
1288 if (m_data.useAttachment())
1289 {
1290 const VkImageCreateInfo imageCreateInfo =
1291 {
1292 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1293 DE_NULL, // const void* pNext;
1294 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
1295 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1296 srFormat, // VkFormat format;
1297 {
1298 srWidth, // deUint32 width;
1299 srHeight, // deUint32 height;
1300 1u // deUint32 depth;
1301 }, // VkExtent3D extent;
1302 1u, // deUint32 mipLevels;
1303 numSRLayers, // deUint32 arrayLayers;
1304 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
1305 srTiling, // VkImageTiling tiling;
1306 srUsage, // VkImageUsageFlags usage;
1307 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1308 0u, // deUint32 queueFamilyIndexCount;
1309 DE_NULL, // const deUint32* pQueueFamilyIndices;
1310 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
1311 };
1312 srImage = de::MovePtr<ImageWithMemory>(new ImageWithMemory(
1313 vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
1314
1315 VkImageViewCreateInfo imageViewCreateInfo =
1316 {
1317 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1318 DE_NULL, // const void* pNext;
1319 (VkImageViewCreateFlags)0u, // VkImageViewCreateFlags flags;
1320 **srImage, // VkImage image;
1321 srViewType, // VkImageViewType viewType;
1322 srFormat, // VkFormat format;
1323 {
1324 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
1325 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
1326 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
1327 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
1328 }, // VkComponentMapping components;
1329 {
1330 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1331 0u, // deUint32 baseMipLevel;
1332 1u, // deUint32 levelCount;
1333 0u, // deUint32 baseArrayLayer;
1334 srViewType == VK_IMAGE_VIEW_TYPE_2D ?
1335 1 : numSRLayers, // deUint32 layerCount;
1336 } // VkImageSubresourceRange subresourceRange;
1337 };
1338 srImageView = createImageView(vk, device, &imageViewCreateInfo, NULL);
1339 }
1340
1341 VkDescriptorImageInfo imageInfo;
1342 VkDescriptorBufferInfo bufferInfo;
1343
1344 VkWriteDescriptorSet w =
1345 {
1346 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
1347 DE_NULL, // pNext
1348 *descriptorSet, // dstSet
1349 (deUint32)0, // dstBinding
1350 0, // dstArrayElement
1351 1u, // descriptorCount
1352 bindings[0].descriptorType, // descriptorType
1353 &imageInfo, // pImageInfo
1354 &bufferInfo, // pBufferInfo
1355 DE_NULL, // pTexelBufferView
1356 };
1357
1358 abuf[0] = 0;
1359 flushAlloc(vk, device, atomicBuffer->getAllocation());
1360
1361 bufferInfo = makeDescriptorBufferInfo(**atomicBuffer, 0, atomicBufferSize);
1362 w.dstBinding = 0;
1363 w.descriptorType = bindings[0].descriptorType;
1364 vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1365
1366 imageInfo = makeDescriptorImageInfo(DE_NULL, *cbImageView, VK_IMAGE_LAYOUT_GENERAL);
1367 w.dstBinding = 1;
1368 w.descriptorType = bindings[1].descriptorType;
1369 vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1370
1371 bufferInfo = makeDescriptorBufferInfo(**colorOutputBuffer, 0, colorOutputBufferSize);
1372 w.dstBinding = 2;
1373 w.descriptorType = bindings[2].descriptorType;
1374 vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1375
1376 imageInfo = makeDescriptorImageInfo(*sampler, *derivImageView, VK_IMAGE_LAYOUT_GENERAL);
1377 w.dstBinding = 3;
1378 w.descriptorType = bindings[3].descriptorType;
1379 vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1380
1381 if (m_data.useDepthStencil)
1382 {
1383 bufferInfo = makeDescriptorBufferInfo(**depthOutputBuffer, 0, depthOutputBufferSize);
1384 w.dstBinding = 4;
1385 w.descriptorType = bindings[4].descriptorType;
1386 vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1387
1388 bufferInfo = makeDescriptorBufferInfo(**stencilOutputBuffer, 0, stencilOutputBufferSize);
1389 w.dstBinding = 5;
1390 w.descriptorType = bindings[5].descriptorType;
1391 vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1392
1393 imageInfo = makeDescriptorImageInfo(DE_NULL, *dImageView, VK_IMAGE_LAYOUT_GENERAL);
1394 w.dstBinding = 6;
1395 w.descriptorType = bindings[6].descriptorType;
1396 vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1397
1398 imageInfo = makeDescriptorImageInfo(DE_NULL, *sImageView, VK_IMAGE_LAYOUT_GENERAL);
1399 w.dstBinding = 7;
1400 w.descriptorType = bindings[7].descriptorType;
1401 vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1402 }
1403
1404 Move<VkRenderPass> renderPass;
1405 Move<VkFramebuffer> framebuffer;
1406
1407 std::vector<VkImageView> attachments;
1408 attachments.push_back(*cbImageView);
1409 deUint32 dsAttachmentIdx = 0, srAttachmentIdx = 0;
1410 if (m_data.useAttachment())
1411 {
1412 srAttachmentIdx = (deUint32)attachments.size();
1413 attachments.push_back(*srImageView);
1414 }
1415 if (m_data.useDepthStencil)
1416 {
1417 dsAttachmentIdx = (deUint32)attachments.size();
1418 attachments.push_back(*dsImageView);
1419 }
1420
1421 if (!m_data.useDynamicRendering)
1422 {
1423 const vk::VkAttachmentReference2 colorAttachmentReference
1424 {
1425 VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, // sType
1426 DE_NULL, // pNext
1427 0, // attachment
1428 vk::VK_IMAGE_LAYOUT_GENERAL, // layout
1429 0, // aspectMask
1430 };
1431
1432 const vk::VkAttachmentReference2 fragmentShadingRateAttachment =
1433 {
1434 VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, // sType
1435 DE_NULL, // pNext
1436 srAttachmentIdx, // attachment
1437 srLayout, // layout
1438 0, // aspectMask
1439 };
1440
1441 const vk::VkAttachmentReference2 depthAttachmentReference =
1442 {
1443 VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, // sType
1444 DE_NULL, // pNext
1445 dsAttachmentIdx, // attachment
1446 vk::VK_IMAGE_LAYOUT_GENERAL, // layout
1447 0, // aspectMask
1448 };
1449
1450 const bool noAttachmentPtr = (m_data.attachmentUsage == AttachmentUsage::NO_ATTACHMENT_PTR);
1451 const VkFragmentShadingRateAttachmentInfoKHR shadingRateAttachmentInfo =
1452 {
1453 VK_STRUCTURE_TYPE_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR, // VkStructureType sType;
1454 DE_NULL, // const void* pNext;
1455 (noAttachmentPtr ? nullptr : &fragmentShadingRateAttachment), // const VkAttachmentReference2* pFragmentShadingRateAttachment;
1456 { srTexelWidth, srTexelHeight }, // VkExtent2D shadingRateAttachmentTexelSize;
1457 };
1458
1459 const bool useAttachmentInfo = (m_data.attachmentUsage != AttachmentUsage::NO_ATTACHMENT);
1460 const VkSubpassDescription2 subpassDesc =
1461 {
1462 VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2, // sType
1463 (useAttachmentInfo ? &shadingRateAttachmentInfo : nullptr), // pNext;
1464 (vk::VkSubpassDescriptionFlags)0, // flags
1465 vk::VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
1466 m_data.multiView ? 0x3 : 0u, // viewMask
1467 0u, // inputCount
1468 DE_NULL, // pInputAttachments
1469 1, // colorCount
1470 &colorAttachmentReference, // pColorAttachments
1471 DE_NULL, // pResolveAttachments
1472 m_data.useDepthStencil ? &depthAttachmentReference : DE_NULL, // depthStencilAttachment
1473 0u, // preserveCount
1474 DE_NULL, // pPreserveAttachments
1475 };
1476
1477 std::vector<VkAttachmentDescription2> attachmentDescriptions
1478 {
1479 {
1480 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, // VkStructureType sType;
1481 DE_NULL, // const void* pNext;
1482 (VkAttachmentDescriptionFlags)0u, // VkAttachmentDescriptionFlags flags;
1483 VK_FORMAT_R32G32B32A32_UINT, // VkFormat format;
1484 m_data.samples, // VkSampleCountFlagBits samples;
1485 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
1486 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
1487 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
1488 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
1489 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout initialLayout;
1490 VK_IMAGE_LAYOUT_GENERAL // VkImageLayout finalLayout;
1491 }
1492 };
1493 if (m_data.useAttachment())
1494 attachmentDescriptions.push_back(
1495 {
1496 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, // VkStructureType sType;
1497 DE_NULL, // const void* pNext;
1498 (VkAttachmentDescriptionFlags)0u, // VkAttachmentDescriptionFlags flags;
1499 srFormat, // VkFormat format;
1500 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
1501 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
1502 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
1503 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
1504 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
1505 srLayout, // VkImageLayout initialLayout;
1506 srLayout // VkImageLayout finalLayout;
1507 }
1508 );
1509
1510 if (m_data.useDepthStencil)
1511 attachmentDescriptions.push_back(
1512 {
1513 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, // VkStructureType sType;
1514 DE_NULL, // const void* pNext;
1515 (VkAttachmentDescriptionFlags)0u, // VkAttachmentDescriptionFlags flags;
1516 VK_FORMAT_D32_SFLOAT_S8_UINT, // VkFormat format;
1517 m_data.samples, // VkSampleCountFlagBits samples;
1518 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
1519 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
1520 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp stencilLoadOp;
1521 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp;
1522 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout initialLayout;
1523 VK_IMAGE_LAYOUT_GENERAL // VkImageLayout finalLayout;
1524 }
1525 );
1526
1527 const VkRenderPassCreateInfo2 renderPassParams =
1528 {
1529 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2, // sType
1530 DE_NULL, // pNext
1531 (vk::VkRenderPassCreateFlags)0,
1532 (deUint32)attachmentDescriptions.size(), // attachmentCount
1533 &attachmentDescriptions[0], // pAttachments
1534 1u, // subpassCount
1535 &subpassDesc, // pSubpasses
1536 0u, // dependencyCount
1537 DE_NULL, // pDependencies
1538 0u, // correlatedViewMaskCount
1539 DE_NULL, // pCorrelatedViewMasks
1540 };
1541
1542 renderPass = createRenderPass2(vk, device, &renderPassParams);
1543
1544 std::vector<VkFramebufferAttachmentImageInfo> framebufferAttachmentImageInfo;
1545 framebufferAttachmentImageInfo.push_back(
1546 {
1547 VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO, // VkStructureType sType;
1548 DE_NULL, // const void* pNext;
1549 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
1550 cbUsage, // VkImageUsageFlags usage;
1551 m_data.framebufferDim.width, // deUint32 width;
1552 m_data.framebufferDim.height, // deUint32 height;
1553 m_data.numColorLayers, // deUint32 layerCount;
1554 0u, // deUint32 viewFormatCount;
1555 DE_NULL // const VkFormat* pViewFormats;
1556 }
1557 );
1558 if (m_data.useAttachment())
1559 framebufferAttachmentImageInfo.push_back(
1560 {
1561 VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO, // VkStructureType sType;
1562 DE_NULL, // const void* pNext;
1563 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
1564 srUsage, // VkImageUsageFlags usage;
1565 srWidth, // deUint32 width;
1566 srHeight, // deUint32 height;
1567 numSRLayers, // deUint32 layerCount;
1568 0u, // deUint32 viewFormatCount;
1569 DE_NULL // const VkFormat* pViewFormats;
1570 }
1571 );
1572
1573 if (m_data.useDepthStencil)
1574 framebufferAttachmentImageInfo.push_back(
1575 {
1576 VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO, // VkStructureType sType;
1577 DE_NULL, // const void* pNext;
1578 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
1579 dsUsage, // VkImageUsageFlags usage;
1580 m_data.framebufferDim.width, // deUint32 width;
1581 m_data.framebufferDim.height, // deUint32 height;
1582 m_data.numColorLayers, // deUint32 layerCount;
1583 0u, // deUint32 viewFormatCount;
1584 DE_NULL // const VkFormat* pViewFormats;
1585 }
1586 );
1587
1588 const VkFramebufferAttachmentsCreateInfo framebufferAttachmentsCreateInfo =
1589 {
1590 VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO, // VkStructureType sType;
1591 DE_NULL, // const void* pNext;
1592 (deUint32)framebufferAttachmentImageInfo.size(), // deUint32 attachmentImageInfoCount;
1593 &framebufferAttachmentImageInfo[0] // const VkFramebufferAttachmentImageInfo* pAttachmentImageInfos;
1594 };
1595
1596 const vk::VkFramebufferCreateInfo framebufferParams =
1597 {
1598 vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // sType
1599 imagelessFB ? &framebufferAttachmentsCreateInfo : DE_NULL, // pNext
1600 (vk::VkFramebufferCreateFlags)(imagelessFB ? VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT : 0),
1601 *renderPass, // renderPass
1602 (deUint32)attachments.size(), // attachmentCount
1603 imagelessFB ? DE_NULL : &attachments[0], // pAttachments
1604 m_data.framebufferDim.width, // width
1605 m_data.framebufferDim.height, // height
1606 m_data.multiView ? 1 : m_data.numColorLayers, // layers
1607 };
1608
1609 framebuffer = createFramebuffer(vk, device, &framebufferParams);
1610 }
1611
1612 const VkVertexInputBindingDescription vertexBinding =
1613 {
1614 0u, // deUint32 binding;
1615 sizeof(float) * 2, // deUint32 stride;
1616 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate;
1617 };
1618 const VkVertexInputAttributeDescription vertexInputAttributeDescription =
1619 {
1620 0u, // deUint32 location;
1621 0u, // deUint32 binding;
1622 VK_FORMAT_R32G32_SFLOAT, // VkFormat format;
1623 0u // deUint32 offset;
1624 };
1625
1626 const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo =
1627 {
1628 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1629 DE_NULL, // const void* pNext;
1630 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
1631 1u, // deUint32 vertexBindingDescriptionCount;
1632 &vertexBinding, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1633 1u, // deUint32 vertexAttributeDescriptionCount;
1634 &vertexInputAttributeDescription // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
1635 };
1636
1637 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo =
1638 {
1639 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
1640 DE_NULL, // const void* pNext;
1641 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
1642 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology;
1643 VK_FALSE // VkBool32 primitiveRestartEnable;
1644 };
1645
1646 const VkPipelineRasterizationConservativeStateCreateInfoEXT consRastState =
1647 {
1648 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT, // VkStructureType sType;
1649 DE_NULL, // const void* pNext;
1650 (VkPipelineRasterizationConservativeStateCreateFlagsEXT)0, // VkPipelineRasterizationConservativeStateCreateFlagsEXT flags;
1651 m_data.conservativeMode, // VkConservativeRasterizationModeEXT conservativeRasterizationMode;
1652 0.0f, // float extraPrimitiveOverestimationSize;
1653 };
1654
1655 const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
1656 {
1657 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
1658 m_data.conservativeEnable ? &consRastState : DE_NULL, // const void* pNext;
1659 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
1660 VK_FALSE, // VkBool32 depthClampEnable;
1661 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
1662 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
1663 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
1664 VK_FRONT_FACE_CLOCKWISE, // VkFrontFace frontFace;
1665 VK_FALSE, // VkBool32 depthBiasEnable;
1666 0.0f, // float depthBiasConstantFactor;
1667 0.0f, // float depthBiasClamp;
1668 0.0f, // float depthBiasSlopeFactor;
1669 1.0f // float lineWidth;
1670 };
1671
1672 // Kill some bits from each AA mode
1673 const VkSampleMask sampleMask = m_data.sampleMaskTest ? 0x9 : 0x7D56;
1674 const VkSampleMask* pSampleMask = m_data.useApiSampleMask ? &sampleMask : DE_NULL;
1675
1676 // All samples at pixel center. We'll validate that pixels are fully covered or uncovered.
1677 std::vector<VkSampleLocationEXT> sampleLocations(m_data.samples, { 0.5f, 0.5f });
1678 const VkSampleLocationsInfoEXT sampleLocationsInfo =
1679 {
1680 VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT, // VkStructureType sType;
1681 DE_NULL, // const void* pNext;
1682 (VkSampleCountFlagBits)m_data.samples, // VkSampleCountFlagBits sampleLocationsPerPixel;
1683 { 1, 1 }, // VkExtent2D sampleLocationGridSize;
1684 (deUint32)m_data.samples, // uint32_t sampleLocationsCount;
1685 &sampleLocations[0], // const VkSampleLocationEXT* pSampleLocations;
1686 };
1687
1688 const VkPipelineSampleLocationsStateCreateInfoEXT pipelineSampleLocationsCreateInfo =
1689 {
1690 VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT, // VkStructureType sType;
1691 DE_NULL, // const void* pNext;
1692 VK_TRUE, // VkBool32 sampleLocationsEnable;
1693 sampleLocationsInfo, // VkSampleLocationsInfoEXT sampleLocationsInfo;
1694 };
1695
1696 const VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfo =
1697 {
1698 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType
1699 m_data.sampleLocations ? &pipelineSampleLocationsCreateInfo : DE_NULL, // const void* pNext
1700 0u, // VkPipelineMultisampleStateCreateFlags flags
1701 (VkSampleCountFlagBits)m_data.samples, // VkSampleCountFlagBits rasterizationSamples
1702 (VkBool32)m_data.sampleShadingEnable, // VkBool32 sampleShadingEnable
1703 1.0f, // float minSampleShading
1704 pSampleMask, // const VkSampleMask* pSampleMask
1705 VK_FALSE, // VkBool32 alphaToCoverageEnable
1706 VK_FALSE // VkBool32 alphaToOneEnable
1707 };
1708
1709 std::vector<VkViewport> viewports;
1710 std::vector<VkRect2D> scissors;
1711 if (m_data.multiViewport)
1712 {
1713 // Split the viewport into left and right halves
1714 int x0 = 0, x1 = m_data.framebufferDim.width/2, x2 = m_data.framebufferDim.width;
1715
1716 viewports.push_back(makeViewport((float)x0, 0, (float)(x1-x0), (float)m_data.framebufferDim.height, 0.0f, 1.0f));
1717 scissors.push_back(makeRect2D(x0, 0, x1-x0, m_data.framebufferDim.height));
1718
1719 viewports.push_back(makeViewport((float)x1, 0, (float)(x2-x1), (float)m_data.framebufferDim.height, 0.0f, 1.0f));
1720 scissors.push_back(makeRect2D(x1, 0, x2-x1, m_data.framebufferDim.height));
1721 }
1722 else
1723 {
1724 viewports.push_back(makeViewport(m_data.framebufferDim.width, m_data.framebufferDim.height));
1725 scissors.push_back(makeRect2D(m_data.framebufferDim.width, m_data.framebufferDim.height));
1726 }
1727
1728 const VkPipelineViewportStateCreateInfo viewportStateCreateInfo =
1729 {
1730 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType
1731 DE_NULL, // const void* pNext
1732 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags
1733 (deUint32)viewports.size(), // deUint32 viewportCount
1734 &viewports[0], // const VkViewport* pViewports
1735 (deUint32)scissors.size(), // deUint32 scissorCount
1736 &scissors[0] // const VkRect2D* pScissors
1737 };
1738
1739 Move<VkShaderModule> fragShader = createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0);
1740 Move<VkShaderModule> vertShader = createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0);
1741 Move<VkShaderModule> geomShader;
1742 if (m_data.geometryShader)
1743 geomShader = createShaderModule(vk, device, m_context.getBinaryCollection().get("geom"), 0);
1744
1745 deUint32 numStages = m_data.geometryShader ? 3 : 2u;
1746
1747 const VkPipelineShaderStageCreateInfo shaderCreateInfo[3] =
1748 {
1749 {
1750 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1751 DE_NULL,
1752 (VkPipelineShaderStageCreateFlags)0,
1753 VK_SHADER_STAGE_VERTEX_BIT, // stage
1754 *vertShader, // shader
1755 "main",
1756 DE_NULL, // pSpecializationInfo
1757 },
1758 {
1759 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1760 DE_NULL,
1761 (VkPipelineShaderStageCreateFlags)0,
1762 VK_SHADER_STAGE_FRAGMENT_BIT, // stage
1763 *fragShader, // shader
1764 "main",
1765 DE_NULL, // pSpecializationInfo
1766 },
1767 {
1768 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1769 DE_NULL,
1770 (VkPipelineShaderStageCreateFlags)0,
1771 VK_SHADER_STAGE_GEOMETRY_BIT, // stage
1772 *geomShader, // shader
1773 "main",
1774 DE_NULL, // pSpecializationInfo
1775 }
1776 };
1777
1778 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
1779 {
1780 VK_FALSE, // VkBool32 blendEnable;
1781 VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcColorBlendFactor;
1782 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
1783 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
1784 VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcAlphaBlendFactor;
1785 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor;
1786 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
1787 0xf // VkColorComponentFlags colorWriteMask;
1788 };
1789
1790 const VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfo =
1791 {
1792 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
1793 DE_NULL, // const void* pNext;
1794 0u, // VkPipelineColorBlendStateCreateFlags flags;
1795 VK_FALSE, // VkBool32 logicOpEnable;
1796 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
1797 1u, // deUint32 attachmentCount;
1798 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
1799 { 1.0f, 1.0f, 1.0f, 1.0f } // float blendConstants[4];
1800 };
1801
1802 const deUint32 fragSizeWH = m_data.sampleMaskTest ? 2 : 0;
1803
1804 VkPipelineRenderingCreateInfoKHR renderingCreateInfo
1805 {
1806 VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
1807 DE_NULL,
1808 m_data.multiView ? 0x3 : 0u,
1809 1u,
1810 &cbFormat,
1811 m_data.useDepthStencil ? dsFormat : VK_FORMAT_UNDEFINED,
1812 m_data.useDepthStencil ? dsFormat : VK_FORMAT_UNDEFINED
1813 };
1814
1815 VkPipelineFragmentShadingRateStateCreateInfoKHR shadingRateStateCreateInfo =
1816 {
1817 VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR, // VkStructureType sType;
1818 m_data.useDynamicRendering ? &renderingCreateInfo : DE_NULL, // const void* pNext;
1819 { fragSizeWH, fragSizeWH }, // VkExtent2D fragmentSize;
1820 { m_data.combinerOp[0], m_data.combinerOp[1] }, // VkFragmentShadingRateCombinerOpKHR combinerOps[2];
1821 };
1822
1823 VkDynamicState dynamicState = VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR;
1824 const VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo =
1825 {
1826 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType;
1827 DE_NULL, // const void* pNext;
1828 (VkPipelineDynamicStateCreateFlags)0, // VkPipelineDynamicStateCreateFlags flags;
1829 m_data.useDynamicState ? 1u : 0u, // uint32_t dynamicStateCount;
1830 &dynamicState, // const VkDynamicState* pDynamicStates;
1831 };
1832
1833 // Enable depth/stencil writes, always passing
1834 VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
1835 {
1836 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
1837 DE_NULL, // const void* pNext;
1838 0u, // VkPipelineDepthStencilStateCreateFlags flags;
1839 VK_TRUE, // VkBool32 depthTestEnable;
1840 VK_TRUE, // VkBool32 depthWriteEnable;
1841 VK_COMPARE_OP_ALWAYS, // VkCompareOp depthCompareOp;
1842 VK_FALSE, // VkBool32 depthBoundsTestEnable;
1843 VK_TRUE, // VkBool32 stencilTestEnable;
1844 // VkStencilOpState front;
1845 {
1846 VK_STENCIL_OP_REPLACE, // VkStencilOp failOp;
1847 VK_STENCIL_OP_REPLACE, // VkStencilOp passOp;
1848 VK_STENCIL_OP_REPLACE, // VkStencilOp depthFailOp;
1849 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp;
1850 0u, // deUint32 compareMask;
1851 0xFFu, // deUint32 writeMask;
1852 0xFFu, // deUint32 reference;
1853 },
1854 // VkStencilOpState back;
1855 {
1856 VK_STENCIL_OP_REPLACE, // VkStencilOp failOp;
1857 VK_STENCIL_OP_REPLACE, // VkStencilOp passOp;
1858 VK_STENCIL_OP_REPLACE, // VkStencilOp depthFailOp;
1859 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp;
1860 0u, // deUint32 compareMask;
1861 0xFFu, // deUint32 writeMask;
1862 0xFFu, // deUint32 reference;
1863 },
1864 0.0f, // float minDepthBounds;
1865 0.0f, // float maxDepthBounds;
1866 };
1867
1868 const VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo =
1869 {
1870 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
1871 &shadingRateStateCreateInfo, // const void* pNext;
1872 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
1873 numStages, // deUint32 stageCount;
1874 &shaderCreateInfo[0], // const VkPipelineShaderStageCreateInfo* pStages;
1875 &vertexInputStateCreateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
1876 &inputAssemblyStateCreateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
1877 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
1878 &viewportStateCreateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState;
1879 &rasterizationStateCreateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
1880 &multisampleStateCreateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
1881 &depthStencilStateParams, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
1882 &colorBlendStateCreateInfo, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
1883 &dynamicStateCreateInfo, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
1884 pipelineLayout.get(), // VkPipelineLayout layout;
1885 renderPass.get(), // VkRenderPass renderPass;
1886 0u, // deUint32 subpass;
1887 DE_NULL, // VkPipeline basePipelineHandle;
1888 0 // int basePipelineIndex;
1889 };
1890
1891 VkImageMemoryBarrier imageBarrier =
1892 {
1893 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
1894 DE_NULL, // const void* pNext
1895 0u, // VkAccessFlags srcAccessMask
1896 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
1897 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
1898 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout
1899 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
1900 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
1901 **cbImage, // VkImage image
1902 {
1903 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
1904 0u, // uint32_t baseMipLevel
1905 VK_REMAINING_MIP_LEVELS, // uint32_t mipLevels,
1906 0u, // uint32_t baseArray
1907 VK_REMAINING_ARRAY_LAYERS, // uint32_t arraySize
1908 }
1909 };
1910
1911 const VkQueue queue = m_context.getUniversalQueue();
1912 Move<VkCommandPool> cmdPool = createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, m_context.getUniversalQueueFamilyIndex());
1913 Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1914 VkClearValue clearColor = makeClearValueColorU32(0, 0, 0, 0);
1915 VkClearValue clearDepthStencil = makeClearValueDepthStencil(0.0, 0);
1916
1917 beginCommandBuffer(vk, *cmdBuffer, 0u);
1918
1919 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1920 (VkDependencyFlags)0,
1921 0, (const VkMemoryBarrier*)DE_NULL,
1922 0, (const VkBufferMemoryBarrier*)DE_NULL,
1923 1, &imageBarrier);
1924
1925 imageBarrier.image = **derivImage;
1926 imageBarrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
1927
1928 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1929 (VkDependencyFlags)0,
1930 0, (const VkMemoryBarrier*)DE_NULL,
1931 0, (const VkBufferMemoryBarrier*)DE_NULL,
1932 1, &imageBarrier);
1933
1934 // Clear level to 1<<level
1935 for (deUint32 i = 0; i < derivNumLevels; ++i)
1936 {
1937 VkImageSubresourceRange range = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, i, 1u, 0u, 1u);
1938 VkClearValue clearLevelColor = makeClearValueColorU32(1<<i,0,0,0);
1939 vk.cmdClearColorImage(*cmdBuffer, **derivImage, VK_IMAGE_LAYOUT_GENERAL, &clearLevelColor.color, 1, &range);
1940 }
1941
1942 // Clear color buffer to transparent black
1943 {
1944 VkImageSubresourceRange range = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, VK_REMAINING_ARRAY_LAYERS);
1945 vk.cmdClearColorImage(*cmdBuffer, **cbImage, VK_IMAGE_LAYOUT_GENERAL, &clearColor.color, 1, &range);
1946 }
1947
1948 // Clear depth and stencil
1949 if (m_data.useDepthStencil)
1950 {
1951 VkImageSubresourceRange range = makeImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 1u, 0u, VK_REMAINING_ARRAY_LAYERS);
1952 VkImageMemoryBarrier dsBarrier = imageBarrier;
1953 dsBarrier.image = **dsImage;
1954 dsBarrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
1955 dsBarrier.subresourceRange = range;
1956 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1957 0u, // dependencyFlags
1958 0u, nullptr,
1959 0u, nullptr,
1960 1u, &dsBarrier);
1961 vk.cmdClearDepthStencilImage(*cmdBuffer, **dsImage, VK_IMAGE_LAYOUT_GENERAL, &clearDepthStencil.depthStencil, 1, &range);
1962 }
1963
1964 // Initialize shading rate image with varying values
1965 if (m_data.useAttachment())
1966 {
1967 imageBarrier.image = **srImage;
1968 imageBarrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
1969
1970 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1971 (VkDependencyFlags)0,
1972 0, (const VkMemoryBarrier*)DE_NULL,
1973 0, (const VkBufferMemoryBarrier*)DE_NULL,
1974 1, &imageBarrier);
1975
1976 deMemset(fillPtr, 0, (size_t)srFillBufferSize);
1977 for (deUint32 layer = 0; layer < numSRLayers; ++layer)
1978 {
1979 for (deUint32 x = 0; x < srWidth; ++x)
1980 {
1981 for (deUint32 y = 0; y < srHeight; ++y)
1982 {
1983 deUint32 idx = (layer*srHeight + y)*srWidth + x;
1984 deUint8 val = (deUint8)SanitizeRate(idx & 0xF);
1985 // actual shading rate is always in the LSBs of the first byte of a texel
1986 fillPtr[srFillBpp*idx] = val;
1987 }
1988 }
1989 }
1990 flushAlloc(vk, device, srFillBuffer->getAllocation());
1991
1992 const VkBufferImageCopy copyRegion =
1993 {
1994 0u, // VkDeviceSize bufferOffset;
1995 0u, // deUint32 bufferRowLength;
1996 0u, // deUint32 bufferImageHeight;
1997 {
1998 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect;
1999 0u, // deUint32 mipLevel;
2000 0u, // deUint32 baseArrayLayer;
2001 numSRLayers, // deUint32 layerCount;
2002 }, // VkImageSubresourceLayers imageSubresource;
2003 { 0, 0, 0 }, // VkOffset3D imageOffset;
2004 { srWidth, srHeight, 1 }, // VkExtent3D imageExtent;
2005 };
2006
2007 vk.cmdCopyBufferToImage(*cmdBuffer, **srFillBuffer, **srImage, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region);
2008
2009 imageBarrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
2010 imageBarrier.newLayout = srLayout;
2011
2012 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
2013 (VkDependencyFlags)0,
2014 0, (const VkMemoryBarrier*)DE_NULL,
2015 0, (const VkBufferMemoryBarrier*)DE_NULL,
2016 1, &imageBarrier);
2017 }
2018
2019 VkMemoryBarrier memBarrier =
2020 {
2021 VK_STRUCTURE_TYPE_MEMORY_BARRIER, // sType
2022 DE_NULL, // pNext
2023 0u, // srcAccessMask
2024 0u, // dstAccessMask
2025 };
2026
2027 memBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
2028 memBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR;
2029 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, allPipelineStages,
2030 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
2031
2032 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0, 1, &descriptorSet.get(), 0, DE_NULL);
2033
2034 vector<Move<VkPipeline>> pipelines;
2035
2036 // If using dynamic state, create a single graphics pipeline and bind it
2037 if (m_data.useDynamicState)
2038 {
2039 pipelines.push_back(createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineCreateInfo));
2040 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelines[0]);
2041 }
2042
2043 VkRect2D renderArea = makeRect2D(m_data.framebufferDim.width, m_data.framebufferDim.height);
2044 if (m_data.useDynamicRendering)
2045 {
2046 VkRenderingFragmentShadingRateAttachmentInfoKHR shadingRateAttachmentInfo
2047 {
2048 VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR, // VkStructureType sType;
2049 DE_NULL, // const void* pNext;
2050 *srImageView, // VkImageView imageView;
2051 srLayout, // VkImageLayout imageLayout;
2052 { srTexelWidth, srTexelHeight } // VkExtent2D shadingRateAttachmentTexelSize;
2053 };
2054
2055 VkRenderingAttachmentInfoKHR colorAttachment
2056 {
2057 vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
2058 DE_NULL, // const void* pNext;
2059 *cbImageView, // VkImageView imageView;
2060 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
2061 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
2062 DE_NULL, // VkImageView resolveImageView;
2063 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout;
2064 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
2065 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
2066 clearColor // VkClearValue clearValue;
2067 };
2068
2069 std::vector<VkRenderingAttachmentInfoKHR> depthStencilAttachments(2,
2070 {
2071 VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
2072 DE_NULL, // const void* pNext;
2073 *dsImageView, // VkImageView imageView;
2074 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
2075 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
2076 DE_NULL, // VkImageView resolveImageView;
2077 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout;
2078 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
2079 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
2080 clearDepthStencil // VkClearValue clearValue;
2081 });
2082
2083 vk::VkRenderingInfoKHR renderingInfo
2084 {
2085 vk::VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
2086 m_data.useAttachment() ? &shadingRateAttachmentInfo : DE_NULL,
2087 0, // VkRenderingFlagsKHR flags;
2088 renderArea, // VkRect2D renderArea;
2089 m_data.multiView ? 1 : m_data.numColorLayers, // deUint32 layerCount;
2090 m_data.multiView ? 0x3 : 0u, // deUint32 viewMask;
2091 1u, // deUint32 colorAttachmentCount;
2092 &colorAttachment, // const VkRenderingAttachmentInfoKHR* pColorAttachments;
2093 m_data.useDepthStencil ? &depthStencilAttachments[0] : DE_NULL, // const VkRenderingAttachmentInfoKHR* pDepthAttachment;
2094 m_data.useDepthStencil ? &depthStencilAttachments[1] : DE_NULL, // const VkRenderingAttachmentInfoKHR* pStencilAttachment;
2095 };
2096
2097 vk.cmdBeginRenderingKHR(*cmdBuffer, &renderingInfo);
2098 }
2099 else
2100 {
2101 const VkRenderPassAttachmentBeginInfo renderPassAttachmentBeginInfo
2102 {
2103 VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO, // VkStructureType sType;
2104 DE_NULL, // const void* pNext;
2105 (deUint32)attachments.size(), // deUint32 attachmentCount;
2106 &attachments[0] // const VkImageView* pAttachments;
2107 };
2108
2109 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderArea,
2110 0, DE_NULL, VK_SUBPASS_CONTENTS_INLINE, imagelessFB ? &renderPassAttachmentBeginInfo : DE_NULL);
2111 }
2112
2113 for (deInt32 i = 0; i < NUM_TRIANGLES; ++i)
2114 {
2115 // Bind vertex attributes pointing to the next triangle
2116 VkDeviceSize vertexBufferOffset = i*3*2*sizeof(float);
2117 VkBuffer vb = **vertexBuffer;
2118 vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vb, &vertexBufferOffset);
2119
2120 // Put primitive shading rate in a push constant
2121 deInt32 shadingRatePC = PrimIDToPrimitiveShadingRate(i);
2122 vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, allShaderStages, 0, sizeof(shadingRatePC), &shadingRatePC);
2123
2124 if (m_data.useDynamicState)
2125 {
2126 VkExtent2D fragmentSize = ShadingRateEnumToExtent(PrimIDToPipelineShadingRate(i));
2127 vk.cmdSetFragmentShadingRateKHR(*cmdBuffer, &fragmentSize, m_data.combinerOp);
2128 }
2129 else
2130 {
2131 // Create a new pipeline with the desired pipeline shading rate
2132 shadingRateStateCreateInfo.fragmentSize = ShadingRateEnumToExtent(PrimIDToPipelineShadingRate(i));
2133 pipelines.push_back(createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineCreateInfo));
2134 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelines.back());
2135 }
2136
2137 // Draw one triangle, with "primitive ID" in gl_InstanceIndex
2138 vk.cmdDraw(*cmdBuffer, 3u, 1, 0u, i);
2139 }
2140
2141 if (m_data.useDynamicRendering)
2142 endRendering(vk, *cmdBuffer);
2143 else
2144 endRenderPass(vk, *cmdBuffer);
2145
2146 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;
2147 memBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
2148 vk.cmdPipelineBarrier(*cmdBuffer, allPipelineStages, allPipelineStages,
2149 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
2150
2151 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1, &*descriptorSet, 0u, DE_NULL);
2152 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
2153
2154 // Copy color/depth/stencil buffers to buffer memory
2155 vk.cmdDispatch(*cmdBuffer, m_data.framebufferDim.width, m_data.framebufferDim.height, m_data.numColorLayers);
2156
2157 memBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
2158 memBarrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT;
2159 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
2160 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
2161
2162 endCommandBuffer(vk, *cmdBuffer);
2163
2164 submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
2165
2166 deUint32 *colorptr = (deUint32 *)colorOutputBuffer->getAllocation().getHostPtr();
2167 invalidateAlloc(vk, device, colorOutputBuffer->getAllocation());
2168
2169 invalidateAlloc(vk, device, atomicBuffer->getAllocation());
2170
2171 float *depthptr = DE_NULL;
2172 deUint32 *stencilptr = DE_NULL;
2173
2174 if (m_data.useDepthStencil)
2175 {
2176 depthptr = (float *)depthOutputBuffer->getAllocation().getHostPtr();
2177 invalidateAlloc(vk, device, depthOutputBuffer->getAllocation());
2178
2179 stencilptr = (deUint32 *)stencilOutputBuffer->getAllocation().getHostPtr();
2180 invalidateAlloc(vk, device, stencilOutputBuffer->getAllocation());
2181 }
2182
2183 // Loop over all samples and validate the output
2184 for (deUint32 layer = 0; layer < m_data.numColorLayers && res == QP_TEST_RESULT_PASS; ++layer)
2185 {
2186 for (deUint32 y = 0; y < m_data.framebufferDim.height && res == QP_TEST_RESULT_PASS; ++y)
2187 {
2188 for (deUint32 x = 0; x < m_data.framebufferDim.width && res == QP_TEST_RESULT_PASS; ++x)
2189 {
2190 for (deInt32 s = 0; s < m_data.samples && res == QP_TEST_RESULT_PASS; ++s)
2191 {
2192 deUint32 *sample = &colorptr[4*(((layer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + s)];
2193
2194 // If testing the rasterizer sample mask, if this sample is not set in the
2195 // mask then it shouldn't have written anything.
2196 if (m_data.useApiSampleMask && !(sampleMask & (1 << s)) && sample[2] != 0)
2197 {
2198 log << tcu::TestLog::Message << std::hex << "sample written despite pSampleMask (" << x << "," << y << ",sample " << s << ")" << tcu::TestLog::EndMessage;
2199 res = QP_TEST_RESULT_FAIL;
2200 continue;
2201 }
2202
2203 // The same isn't covered by any primitives, skip it
2204 if (sample[2] == 0)
2205 continue;
2206
2207 // skip samples that have the same value as sample zero - it would be redundant to check them.
2208 if (s > 0)
2209 {
2210 deUint32 *sample0 = &colorptr[4*(((layer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + 0)];
2211 bool same = deMemCmp(sample, sample0, 16) == 0;
2212
2213 if (m_data.fragDepth)
2214 {
2215 float *dsample = &depthptr[((layer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + s];
2216 float *dsample0 = &depthptr[((layer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + 0];
2217 same = same && (*dsample == *dsample0);
2218 }
2219
2220 if (m_data.fragStencil)
2221 {
2222 deUint32 *ssample = &stencilptr[((layer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + s];
2223 deUint32 *ssample0 = &stencilptr[((layer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + 0];
2224 same = same && (*ssample == *ssample0);
2225 }
2226
2227 if (same)
2228 continue;
2229 }
2230
2231 // Fragment shader writes error codes to .w component.
2232 // All nonzero values are unconditionally failures
2233 if (sample[3] != 0)
2234 {
2235 if (sample[3] == ERROR_FRAGCOORD_CENTER)
2236 log << tcu::TestLog::Message << std::hex << "fragcoord test failed pixel (0x" << x << ",0x" << y << ",sample 0x" << s << ")" << tcu::TestLog::EndMessage;
2237 else if (sample[3] == ERROR_VTG_READBACK)
2238 log << tcu::TestLog::Message << std::hex << "vs/gs output readback test failed pixel (0x" << x << ",0x" << y << ",sample 0x" << s << ")" << tcu::TestLog::EndMessage;
2239 else if ((sample[3] & 0xFF) == ERROR_FRAGCOORD_DERIV)
2240 log << tcu::TestLog::Message << std::hex << "fragcoord derivative test failed pixel (0x" << x << ",0x" << y << ",sample 0x" << s << ")="
2241 "(0x" << ((sample[3] >> 8) & 0x3F) << ",0x" << ((sample[3] >> 14) & 0x3F) << "), expected="
2242 "(0x" << ((sample[3] >> 20) & 0x3F) << ",0x" << ((sample[3] >> 26) & 0x3F) << ")" << tcu::TestLog::EndMessage;
2243 else if ((sample[3] & 0xFF) == ERROR_FRAGCOORD_IMPLICIT_DERIV)
2244 log << tcu::TestLog::Message << std::hex << "implicit derivative test failed pixel (0x" << x << ",0x" << y << ",sample 0x" << s << ")="
2245 "(0x" << ((sample[3] >> 8) & 0x3F) << ",0x" << ((sample[3] >> 14) & 0x3F) << "), expected="
2246 "(0x" << ((sample[3] >> 20) & 0x3F) << ",0x" << ((sample[3] >> 26) & 0x3F) << ")" << tcu::TestLog::EndMessage;
2247 else
2248 log << tcu::TestLog::Message << std::hex << "w coord unknown test failed pixel (0x" << x << ",0x" << y << ",sample 0x" << s << ")" << tcu::TestLog::EndMessage;
2249 res = QP_TEST_RESULT_FAIL;
2250 continue;
2251 }
2252
2253 // x component of sample
2254 deUint32 rate = sample[0];
2255 // fragment size
2256 deUint32 pixelsX = 1 << ((rate/4)&3);
2257 deUint32 pixelsY = 1 << (rate&3);
2258
2259 // Fragment region
2260 deUint32 fragMinX = x & ~(pixelsX-1);
2261 deUint32 fragMinY = y & ~(pixelsY-1);
2262 deUint32 fragMaxX = fragMinX + pixelsX;
2263 deUint32 fragMaxY = fragMinY + pixelsY;
2264
2265 // Clamp to FB dimension for odd sizes
2266 if (fragMaxX > m_data.framebufferDim.width)
2267 fragMaxX = m_data.framebufferDim.width;
2268 if (fragMaxY > m_data.framebufferDim.height)
2269 fragMaxY = m_data.framebufferDim.height;
2270
2271 // z component of sample
2272 deUint32 primID = sample[2] >> 24;
2273 deUint32 atomVal = sample[2] & 0xFFFFFF;
2274
2275 // Compute pipeline and primitive rate from primitive ID, and attachment
2276 // rate from the x/y coordinate
2277 deInt32 pipelineRate = PrimIDToPipelineShadingRate(primID);
2278 deInt32 primitiveRate = m_data.shaderWritesRate ? PrimIDToPrimitiveShadingRate(primID) : 0;
2279
2280 deInt32 attachmentLayer = (m_data.srLayered && modeIdx == ATTACHMENT_MODE_2DARRAY) ? layer : 0;
2281 deInt32 attachmentRate = m_data.useAttachment() ? fillPtr[srFillBpp*((attachmentLayer * srHeight + (y / srTexelHeight)) * srWidth + (x / srTexelWidth))] : 0;
2282
2283 // Get mask of allowed shading rates
2284 deInt32 expectedMasks = Simulate(pipelineRate, primitiveRate, attachmentRate);
2285
2286 if (!(expectedMasks & (1 << rate)))
2287 {
2288 log << tcu::TestLog::Message << std::hex << "unexpected shading rate. failed pixel (0x" << x << ",0x" << y << ",sample 0x" << s << ") "
2289 "result rate 0x" << rate << " mask of expected rates 0x" << expectedMasks <<
2290 " pipelineRate=0x" << pipelineRate << " primitiveRate=0x" << primitiveRate << " attachmentRate =0x" << attachmentRate << tcu::TestLog::EndMessage;
2291 res = QP_TEST_RESULT_FAIL;
2292 continue;
2293 }
2294 // Check that not all fragments are downgraded to 1x1
2295 if (rate == 0 && expectedMasks != 1)
2296 numUnexpected1x1Samples++;
2297 numTotalSamples++;
2298
2299 // Check that gl_FragDepth = primID / NUM_TRIANGLES
2300 if (m_data.fragDepth)
2301 {
2302 float *dsample = &depthptr[((layer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + s];
2303 float expected = (float)primID / NUM_TRIANGLES;
2304 if (fabs(*dsample - expected) > 0.01)
2305 {
2306 log << tcu::TestLog::Message << std::hex << "depth write failed pixel (0x" << x << ",0x" << y << ",sample 0x" << s << ")=" << *dsample << " expected " << expected << tcu::TestLog::EndMessage;
2307 res = QP_TEST_RESULT_FAIL;
2308 continue;
2309 }
2310 }
2311
2312 // Check that stencil value = primID
2313 if (m_data.fragStencil)
2314 {
2315 deUint32 *ssample = &stencilptr[((layer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + s];
2316 if (*ssample != primID)
2317 {
2318 log << tcu::TestLog::Message << std::hex << "stencil write failed pixel (0x" << x << ",0x" << y << ",sample 0x" << s << ")=" << *ssample << " expected " << primID << tcu::TestLog::EndMessage;
2319 res = QP_TEST_RESULT_FAIL;
2320 continue;
2321 }
2322 }
2323
2324 // Check that primitives are in the right viewport/scissor
2325 if (m_data.multiViewport)
2326 {
2327 VkRect2D *scissor = &scissors[primID & 1];
2328 if ((int)x < scissor->offset.x || (int)x >= (int)(scissor->offset.x + scissor->extent.width) ||
2329 (int)y < scissor->offset.y || (int)y >= (int)(scissor->offset.y + scissor->extent.height))
2330 {
2331 log << tcu::TestLog::Message << std::hex << "primitive found outside of expected viewport (0x" << x << ",0x" << y << ",sample 0x" << s << ") primID=" << primID << tcu::TestLog::EndMessage;
2332 res = QP_TEST_RESULT_FAIL;
2333 continue;
2334 }
2335 }
2336
2337 // Check that primitives are in the right layer
2338 if (m_data.colorLayered)
2339 {
2340 if (layer != ((primID & 2)>>1))
2341 {
2342 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;
2343 res = QP_TEST_RESULT_FAIL;
2344 continue;
2345 }
2346 }
2347
2348 // Check that multiview broadcasts the same primitive to both layers
2349 if (m_data.multiView)
2350 {
2351 deUint32 otherLayer = layer^1;
2352 deUint32 *othersample = &colorptr[4*(((otherLayer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + s)];
2353 deUint32 otherPrimID = othersample[2] >> 24;
2354 if (primID != otherPrimID)
2355 {
2356 log << tcu::TestLog::Message << std::hex << "multiview primitive mismatch (0x" << x << ",0x" << y << ",sample 0x" << s << ") primID=" << primID << " otherPrimID=" << otherPrimID << tcu::TestLog::EndMessage;
2357 res = QP_TEST_RESULT_FAIL;
2358 continue;
2359 }
2360 }
2361
2362 // Loop over all samples in the same fragment
2363 for (deUint32 fx = fragMinX; fx < fragMaxX; ++fx)
2364 {
2365 for (deUint32 fy = fragMinY; fy < fragMaxY; ++fy)
2366 {
2367 for (deInt32 fs = 0; fs < m_data.samples; ++fs)
2368 {
2369 deUint32 *fsample = &colorptr[4*(((layer * m_data.framebufferDim.height + fy) * m_data.framebufferDim.width + fx)*m_data.samples + fs)];
2370 deUint32 frate = fsample[0];
2371 deUint32 fprimID = fsample[2] >> 24;
2372 deUint32 fatomVal = fsample[2] & 0xFFFFFF;
2373
2374 // If we write out the sample mask value, check that the samples in the
2375 // mask must not be uncovered, and that samples not in the mask must not
2376 // be covered by this primitive
2377 if (m_data.useSampleMaskIn)
2378 {
2379 int p = pixelsX * pixelsY - ((fx - fragMinX) + pixelsX * (fy - fragMinY)) - 1;
2380 int sampleIdx = fs + m_data.samples * p;
2381
2382 if ((sample[1] & (1 << sampleIdx)) && fsample[2] == 0)
2383 {
2384 log << tcu::TestLog::Message << std::hex << "sample set in sampleMask but not written (0x" << fx << ",0x" << fy << ",sample 0x" << fs << ")" << tcu::TestLog::EndMessage;
2385 res = QP_TEST_RESULT_FAIL;
2386 continue;
2387 }
2388 if (!(sample[1] & (1 << sampleIdx)) && fsample[2] != 0 && fprimID == primID)
2389 {
2390 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;
2391 res = QP_TEST_RESULT_FAIL;
2392 continue;
2393 }
2394 }
2395
2396 // If conservative raster is enabled, or custom sample locations all at the center, check that
2397 // samples in the same pixel must be covered.
2398 if (m_data.conservativeEnable ||
2399 (m_data.sampleLocations && m_context.getFragmentShadingRateProperties().fragmentShadingRateWithCustomSampleLocations))
2400 {
2401 // If it's in the same pixel, expect it to be fully covered.
2402 if (fx == x && fy == y && fsample[2] == 0)
2403 {
2404 log << tcu::TestLog::Message << std::hex << "pixel not fully covered (0x" << fx << ",0x" << fy << ",sample 0x" << fs << ")" << tcu::TestLog::EndMessage;
2405 res = QP_TEST_RESULT_FAIL;
2406 continue;
2407 }
2408 }
2409
2410 if (fsample[2] == 0)
2411 continue;
2412
2413 // If the primitive matches this sample, then it must have the same rate and
2414 // atomic value
2415 if (fprimID == primID)
2416 {
2417 if (rate != frate || (atomVal != fatomVal && !(m_data.sampleShadingEnable || m_data.sampleShadingInput)))
2418 {
2419 log << tcu::TestLog::Message << std::hex << "failed pixel (0x" << x << ",0x" << y << ",sample " << s << ")=0x" << ((primID<<24)|atomVal) <<
2420 " compared to (0x" << fx << ",0x" << fy << ",sample " << fs << ")=0x" << ((fprimID<<24)|fatomVal) <<
2421 " pipelineRate=0x" << pipelineRate << " primitiveRate=0x" << primitiveRate << " attachmentRate =0x" << attachmentRate <<
2422 tcu::TestLog::EndMessage;
2423 res = QP_TEST_RESULT_FAIL;
2424 }
2425 }
2426 }
2427 }
2428 }
2429 }
2430 }
2431 }
2432 }
2433 if (res == QP_TEST_RESULT_FAIL)
2434 break;
2435 }
2436 }
2437 // All samples were coerced to 1x1, unexpected
2438 if (res == QP_TEST_RESULT_PASS &&
2439 numTotalSamples != 0 &&
2440 numUnexpected1x1Samples == numTotalSamples &&
2441 numTotalSamples > 16)
2442 {
2443 log << tcu::TestLog::Message << std::hex << "Quality warning - all fragments used 1x1" << tcu::TestLog::EndMessage;
2444 res = QP_TEST_RESULT_QUALITY_WARNING;
2445 }
2446
2447 return tcu::TestStatus(res, qpGetTestResultName(res));
2448 }
2449
2450 } // anonymous
2451
createBasicTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * parentGroup,bool useDynamicRendering)2452 void createBasicTests (tcu::TestContext& testCtx, tcu::TestCaseGroup* parentGroup, bool useDynamicRendering)
2453 {
2454 typedef struct
2455 {
2456 deUint32 count;
2457 const char* name;
2458 const char* description;
2459 } TestGroupCase;
2460
2461 typedef struct
2462 {
2463 VkExtent2D count;
2464 const char* name;
2465 const char* description;
2466 } TestGroupCase2D;
2467
2468 typedef struct
2469 {
2470 AttachmentUsage usage;
2471 const char* name;
2472 const char* description;
2473 } TestGroupUsageCase;
2474
2475 TestGroupCase groupCases[] =
2476 {
2477 { 0, "basic", "basic tests" },
2478 { 1, "apisamplemask", "use pSampleMask" },
2479 { 2, "samplemaskin", "use gl_SampleMaskIn" },
2480 { 3, "conservativeunder", "conservative underestimation" },
2481 { 4, "conservativeover", "conservative overestimation" },
2482 { 5, "fragdepth", "depth shader output" },
2483 { 6, "fragstencil", "stencil shader output" },
2484 { 7, "multiviewport", "multiple viewports and gl_ViewportIndex" },
2485 { 8, "colorlayered", "multiple layer color, single layer shading rate" },
2486 { 9, "srlayered", "multiple layer color, multiple layers shading rate" },
2487 { 10, "multiview", "multiview" },
2488 { 11, "multiviewsrlayered", "multiview and multilayer shading rate" },
2489 { 12, "interlock", "fragment shader interlock" },
2490 { 13, "samplelocations", "custom sample locations" },
2491 { 14, "sampleshadingenable", "enable sample shading in createinfo" },
2492 { 15, "sampleshadinginput", "enable sample shading by using gl_SampleID" },
2493 };
2494
2495 TestGroupCase dynCases[] =
2496 {
2497 { 1, "dynamic", "uses dynamic shading rate state" },
2498 { 0, "static", "uses static shading rate state" },
2499 };
2500
2501 TestGroupUsageCase attCases[] =
2502 {
2503 { AttachmentUsage::NO_ATTACHMENT, "noattachment", "no shading rate attachment" },
2504 { AttachmentUsage::WITH_ATTACHMENT, "attachment", "has shading rate attachment" },
2505 { AttachmentUsage::NO_ATTACHMENT_PTR, "noattachmentptr", "no shading rate attachment pointer" },
2506 };
2507
2508 TestGroupCase shdCases[] =
2509 {
2510 { 0, "noshaderrate", "shader doesn't write rate" },
2511 { 1, "shaderrate", "shader writes rate" },
2512 };
2513
2514 TestGroupCase combCases[] =
2515 {
2516 { VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR, "keep", "keep" },
2517 { VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR, "replace", "replace" },
2518 { VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MIN_KHR, "min", "min" },
2519 { VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_KHR, "max", "max" },
2520 { VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_KHR, "mul", "mul" },
2521 };
2522
2523 TestGroupCase2D extentCases[] =
2524 {
2525 { {1, 1}, "1x1", "1x1" },
2526 { {4, 4}, "4x4", "4x4" },
2527 { {33, 35}, "33x35", "33x35" },
2528 { {151, 431}, "151x431", "151x431" },
2529 { {256, 256}, "256x256", "256x256" },
2530 };
2531
2532 TestGroupCase sampCases[] =
2533 {
2534 { VK_SAMPLE_COUNT_1_BIT, "samples1", "1 raster sample" },
2535 { VK_SAMPLE_COUNT_2_BIT, "samples2", "2 raster samples" },
2536 { VK_SAMPLE_COUNT_4_BIT, "samples4", "4 raster samples" },
2537 { VK_SAMPLE_COUNT_8_BIT, "samples8", "8 raster samples" },
2538 { VK_SAMPLE_COUNT_16_BIT, "samples16", "16 raster samples" },
2539 };
2540
2541 TestGroupCase geomCases[] =
2542 {
2543 { 0, "vs", "vertex shader only" },
2544 { 1, "gs", "vertex and geometry shader" },
2545 };
2546
2547 deInt32 seed = 0;
2548
2549 for (int groupNdx = 0; groupNdx < DE_LENGTH_OF_ARRAY(groupCases); groupNdx++)
2550 {
2551 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, groupCases[groupNdx].name, groupCases[groupNdx].description));
2552 for (int dynNdx = 0; dynNdx < DE_LENGTH_OF_ARRAY(dynCases); dynNdx++)
2553 {
2554 de::MovePtr<tcu::TestCaseGroup> dynGroup(new tcu::TestCaseGroup(testCtx, dynCases[dynNdx].name, dynCases[dynNdx].description));
2555 for (int attNdx = 0; attNdx < DE_LENGTH_OF_ARRAY(attCases); attNdx++)
2556 {
2557 if (useDynamicRendering && attCases[attNdx].usage == AttachmentUsage::NO_ATTACHMENT_PTR)
2558 continue;
2559
2560 de::MovePtr<tcu::TestCaseGroup> attGroup(new tcu::TestCaseGroup(testCtx, attCases[attNdx].name, attCases[attNdx].description));
2561 for (int shdNdx = 0; shdNdx < DE_LENGTH_OF_ARRAY(shdCases); shdNdx++)
2562 {
2563 de::MovePtr<tcu::TestCaseGroup> shdGroup(new tcu::TestCaseGroup(testCtx, shdCases[shdNdx].name, shdCases[shdNdx].description));
2564 for (int cmb0Ndx = 0; cmb0Ndx < DE_LENGTH_OF_ARRAY(combCases); cmb0Ndx++)
2565 {
2566 de::MovePtr<tcu::TestCaseGroup> cmb0Group(new tcu::TestCaseGroup(testCtx, combCases[cmb0Ndx].name, combCases[cmb0Ndx].description));
2567 for (int cmb1Ndx = 0; cmb1Ndx < DE_LENGTH_OF_ARRAY(combCases); cmb1Ndx++)
2568 {
2569 de::MovePtr<tcu::TestCaseGroup> cmb1Group(new tcu::TestCaseGroup(testCtx, combCases[cmb1Ndx].name, combCases[cmb1Ndx].description));
2570 for (int extNdx = 0; extNdx < DE_LENGTH_OF_ARRAY(extentCases); extNdx++)
2571 {
2572 de::MovePtr<tcu::TestCaseGroup> extGroup(new tcu::TestCaseGroup(testCtx, extentCases[extNdx].name, extentCases[extNdx].description));
2573 for (int sampNdx = 0; sampNdx < DE_LENGTH_OF_ARRAY(sampCases); sampNdx++)
2574 {
2575 de::MovePtr<tcu::TestCaseGroup> sampGroup(new tcu::TestCaseGroup(testCtx, sampCases[sampNdx].name, sampCases[sampNdx].description));
2576 for (int geomNdx = 0; geomNdx < DE_LENGTH_OF_ARRAY(geomCases); geomNdx++)
2577 {
2578 bool useApiSampleMask = groupNdx == 1;
2579 bool useSampleMaskIn = groupNdx == 2;
2580 bool consRast = groupNdx == 3 || groupNdx == 4;
2581 bool fragDepth = groupNdx == 5;
2582 bool fragStencil = groupNdx == 6;
2583 bool multiViewport = groupNdx == 7;
2584 bool colorLayered = groupNdx == 8 || groupNdx == 9;
2585 bool srLayered = groupNdx == 9 || groupNdx == 11;
2586 bool multiView = groupNdx == 10 || groupNdx == 11;
2587 bool interlock = groupNdx == 12;
2588 bool sampleLocations = groupNdx == 13;
2589 bool sampleShadingEnable = groupNdx == 14;
2590 bool sampleShadingInput = groupNdx == 15;
2591 VkConservativeRasterizationModeEXT conservativeMode = (groupNdx == 3) ? VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT : VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT;
2592 deUint32 numColorLayers = (colorLayered || multiView) ? 2u : 1u;
2593
2594 // Don't bother with geometry shader if we're not testing shader writes
2595 if (geomCases[geomNdx].count && !shdCases[shdNdx].count)
2596 continue;
2597
2598 // reduce number of tests
2599 if ((groupNdx != 0) &&
2600 (!dynCases[dynNdx].count ||
2601 !(combCases[cmb0Ndx].count == VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR || combCases[cmb0Ndx].count == VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR) ||
2602 !(combCases[cmb1Ndx].count == VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR || combCases[cmb1Ndx].count == VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR)))
2603 continue;
2604
2605 // Don't bother with geometry shader if we're testing conservative raster, sample mask, depth/stencil
2606 if (geomCases[geomNdx].count && (useApiSampleMask || useSampleMaskIn || consRast || fragDepth || fragStencil))
2607 continue;
2608
2609 // Don't bother with geometry shader if we're testing non-dynamic state
2610 if (geomCases[geomNdx].count && !dynCases[dynNdx].count)
2611 continue;
2612
2613 // Only test multiViewport/layered with shaderWritesRate
2614 if ((multiViewport || colorLayered) && !shdCases[shdNdx].count)
2615 continue;
2616
2617 // Can't test layered shading rate attachment without an attachment
2618 if (srLayered && attCases[attNdx].usage != AttachmentUsage::WITH_ATTACHMENT)
2619 continue;
2620
2621 CaseDef c =
2622 {
2623 seed++, // deInt32 seed;
2624 extentCases[extNdx].count, // VkExtent2D framebufferDim;
2625 (VkSampleCountFlagBits)sampCases[sampNdx].count, // VkSampleCountFlagBits samples;
2626 {
2627 (VkFragmentShadingRateCombinerOpKHR)combCases[cmb0Ndx].count,
2628 (VkFragmentShadingRateCombinerOpKHR)combCases[cmb1Ndx].count
2629 }, // VkFragmentShadingRateCombinerOpKHR combinerOp[2];
2630 attCases[attNdx].usage, // AttachmentUsage attachmentUsage;
2631 (bool)shdCases[shdNdx].count, // bool shaderWritesRate;
2632 (bool)geomCases[geomNdx].count, // bool geometryShader;
2633 (bool)dynCases[dynNdx].count, // bool useDynamicState;
2634 useDynamicRendering, // bool useDynamicRendering;
2635 useApiSampleMask, // bool useApiSampleMask;
2636 useSampleMaskIn, // bool useSampleMaskIn;
2637 consRast, // bool conservativeEnable;
2638 conservativeMode, // VkConservativeRasterizationModeEXT conservativeMode;
2639 fragDepth || fragStencil, // bool useDepthStencil;
2640 fragDepth, // bool fragDepth;
2641 fragStencil, // bool fragStencil;
2642 multiViewport, // bool multiViewport;
2643 colorLayered, // bool colorLayered;
2644 srLayered, // bool srLayered;
2645 numColorLayers, // deUint32 numColorLayers;
2646 multiView, // bool multiView;
2647 interlock, // bool interlock;
2648 sampleLocations, // bool sampleLocations;
2649 sampleShadingEnable, // bool sampleShadingEnable;
2650 sampleShadingInput, // bool sampleShadingInput;
2651 false, // bool sampleMaskTest;
2652 };
2653
2654 sampGroup->addChild(new FSRTestCase(testCtx, geomCases[geomNdx].name, geomCases[geomNdx].description, c));
2655 }
2656 extGroup->addChild(sampGroup.release());
2657 }
2658 cmb1Group->addChild(extGroup.release());
2659 }
2660 cmb0Group->addChild(cmb1Group.release());
2661 }
2662 shdGroup->addChild(cmb0Group.release());
2663 }
2664 attGroup->addChild(shdGroup.release());
2665 }
2666 dynGroup->addChild(attGroup.release());
2667 }
2668 group->addChild(dynGroup.release());
2669 }
2670 parentGroup->addChild(group.release());
2671 }
2672
2673 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "misc_tests", "Single tests that don't need to be part of above test matrix"));
2674 group->addChild(new FSRTestCase(testCtx, "sample_mask_test", "", {
2675 123, // deInt32 seed;
2676 {32, 33}, // VkExtent2D framebufferDim;
2677 VK_SAMPLE_COUNT_4_BIT, // VkSampleCountFlagBits samples;
2678 {
2679 VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR,
2680 VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR
2681 }, // VkFragmentShadingRateCombinerOpKHR combinerOp[2];
2682 AttachmentUsage::NO_ATTACHMENT, // AttachmentUsage attachmentUsage;
2683 true, // bool shaderWritesRate;
2684 false, // bool geometryShader;
2685 false, // bool useDynamicState;
2686 false, // bool useDynamicRendering;
2687 true, // bool useApiSampleMask;
2688 false, // bool useSampleMaskIn;
2689 false, // bool conservativeEnable;
2690 VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT, // VkConservativeRasterizationModeEXT conservativeMode;
2691 false, // bool useDepthStencil;
2692 false, // bool fragDepth;
2693 false, // bool fragStencil;
2694 false, // bool multiViewport;
2695 false, // bool colorLayered;
2696 false, // bool srLayered;
2697 1u, // deUint32 numColorLayers;
2698 false, // bool multiView;
2699 false, // bool interlock;
2700 false, // bool sampleLocations;
2701 false, // bool sampleShadingEnable;
2702 false, // bool sampleShadingInput;
2703 true, // bool sampleMaskTest;
2704 }));
2705
2706 parentGroup->addChild(group.release());
2707 }
2708
2709 } // FragmentShadingRage
2710 } // vkt
2711