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