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