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