VK_KHR_fragment_shading_rate pixel consistency
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / fragment_shading_rate / vktFragmentShadingRatePixelConsistency.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2017-2020 The Khronos Group Inc.
6  * Copyright (c) 2020 AMD
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  *//*--------------------------------------------------------------------*/
24
25 #include "vktFragmentShadingRatePixelConsistency.hpp"
26
27 #include "vkBufferWithMemory.hpp"
28 #include "vkImageWithMemory.hpp"
29 #include "vkQueryUtil.hpp"
30 #include "vkBuilderUtil.hpp"
31 #include "vkCmdUtil.hpp"
32 #include "vkTypeUtil.hpp"
33 #include "vkObjUtil.hpp"
34 #include "vkImageUtil.hpp"
35 #include "vkQueryUtil.hpp"
36 #include "vkPlatform.hpp"
37
38 #include "vktTestGroupUtil.hpp"
39 #include "vktTestCase.hpp"
40 #include "vktCustomInstancesDevices.hpp"
41
42 #include "deDefs.h"
43 #include "deMath.h"
44 #include "deRandom.h"
45 #include "deSharedPtr.hpp"
46 #include "deString.h"
47
48 #include "tcuTestCase.hpp"
49 #include "tcuTestLog.hpp"
50 #include "tcuCommandLine.hpp"
51
52 #include <limits>
53 #include <string>
54 #include <sstream>
55
56 namespace vkt
57 {
58 namespace FragmentShadingRate
59 {
60 namespace
61 {
62 using namespace vk;
63 using namespace std;
64
65 struct CaseDef
66 {
67         VkExtent2D                              shadingRate;
68         VkSampleCountFlagBits   samples;
69         VkExtent2D                              framebufferExtent;
70 };
71
72 struct Vertex
73 {
74         float x;
75         float y;
76 };
77
78 Vertex basicTriangles[6] =
79 {
80         {-1.0f, -1.0f},
81         { 1.0f, -1.0f},
82         { 1.0f,  1.0f},
83
84         {-1.0f,  1.0f},
85         { 1.0f, -1.0f},
86         { 1.0f,  1.0f},
87 };
88
89 Move<VkDevice> createImageRobustnessDevice(Context& context)
90 {
91         const InstanceInterface&        instance                = context.getInstanceInterface();
92         const vk::VkPhysicalDevice      physicalDevice  = context.getPhysicalDevice();
93         const float                                     queuePriority   = 1.0f;
94
95         // Create a universal queue
96         const VkDeviceQueueCreateInfo queueParams =
97         {
98                 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,     // VkStructureType                              sType;
99                 DE_NULL,                                                                        // const void*                                  pNext;
100                 0u,                                                                                     // VkDeviceQueueCreateFlags             flags;
101                 context.getUniversalQueueFamilyIndex(),         // deUint32                                             queueFamilyIndex;
102                 1u,                                                                                     // deUint32                                             queueCount;
103                 &queuePriority                                                          // const float*                                 pQueuePriorities;
104         };
105
106         // Add image robustness extension if supported
107         std::vector<const char*> deviceExtensions;
108
109         if (context.isDeviceFunctionalitySupported("VK_EXT_image_robustness"))
110         {
111                 deviceExtensions.push_back("VK_EXT_image_robustness");
112         }
113
114         VkPhysicalDeviceFragmentShadingRateFeaturesKHR fsrFeatures =
115         {
116                 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR,   // VkStructureType      sType;
117                 DE_NULL,                                                                                                                                // void*                        pNext;
118                 DE_FALSE,                                                                                                                               // VkBool32                     pipelineFragmentShadingRate;
119                 DE_FALSE,                                                                                                                               // VkBool32                     primitiveFragmentShadingRate;
120                 DE_FALSE,                                                                                                                               // VkBool32                     attachmentFragmentShadingRate;
121         };
122
123         VkPhysicalDeviceFeatures2 enabledFeatures;
124         enabledFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
125         enabledFeatures.pNext = &fsrFeatures;
126
127         instance.getPhysicalDeviceFeatures2(physicalDevice, &enabledFeatures);
128
129         const VkDeviceCreateInfo deviceParams =
130         {
131                 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,                                           // VkStructureType                                      sType;
132                 &enabledFeatures,                                                                                       // const void*                                          pNext;
133                 0u,                                                                                                                     // VkDeviceCreateFlags                          flags;
134                 1u,                                                                                                                     // deUint32                                                     queueCreateInfoCount;
135                 &queueParams,                                                                                           // const VkDeviceQueueCreateInfo*       pQueueCreateInfos;
136                 0u,                                                                                                                     // deUint32                                                     enabledLayerCount;
137                 DE_NULL,                                                                                                        // const char* const*                           ppEnabledLayerNames;
138                 static_cast<deUint32>(deviceExtensions.size()),                         // deUint32                                                     enabledExtensionCount;
139                 deviceExtensions.empty() ? DE_NULL : &deviceExtensions[0],      // const char* const*                           ppEnabledExtensionNames;
140                 DE_NULL,                                                                                                        // const VkPhysicalDeviceFeatures*      pEnabledFeatures;
141         };
142
143         return createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(),
144                                                           context.getInstance(), context.getInstanceInterface(), context.getPhysicalDevice(), &deviceParams);
145 }
146
147 class FSRPixelConsistencyInstance : public TestInstance
148 {
149 public:
150                                                 FSRPixelConsistencyInstance     (Context& context, const CaseDef& data);
151                                                 ~FSRPixelConsistencyInstance(void);
152         tcu::TestStatus         iterate                                         (void);
153
154 private:
155         void                            clampShadingRate();
156         tcu::TestStatus         verifyResult(tcu::ConstPixelBufferAccess& resultBuffer, const deUint32 index);
157
158         CaseDef                                                                                 m_data;
159         vector<VkExtent2D>                                                              m_shadingRateClamped;
160
161         deUint32                                                                                m_supportedFragmentShadingRateCount;
162         vector<VkPhysicalDeviceFragmentShadingRateKHR>  m_supportedFragmentShadingRates;
163 };
164
165 FSRPixelConsistencyInstance::FSRPixelConsistencyInstance(Context& context, const CaseDef& data)
166         : vkt::TestInstance             (context)
167         , m_data(data)
168         , m_supportedFragmentShadingRateCount(0)
169 {
170         // Fetch information about supported fragment shading rates
171         context.getInstanceInterface().getPhysicalDeviceFragmentShadingRatesKHR(context.getPhysicalDevice(), &m_supportedFragmentShadingRateCount, DE_NULL);
172
173         m_supportedFragmentShadingRates.resize(m_supportedFragmentShadingRateCount);
174         context.getInstanceInterface().getPhysicalDeviceFragmentShadingRatesKHR(context.getPhysicalDevice(), &m_supportedFragmentShadingRateCount, &m_supportedFragmentShadingRates[0]);
175
176         clampShadingRate();
177 }
178
179 FSRPixelConsistencyInstance::~FSRPixelConsistencyInstance(void)
180 {
181 }
182
183 class FSRPixelConsistencyTestCase : public TestCase
184 {
185         public:
186                                                                 FSRPixelConsistencyTestCase             (tcu::TestContext& context, const char* name, const char* desc, const CaseDef data);
187                                                                 ~FSRPixelConsistencyTestCase    (void);
188         virtual void                            initPrograms                                    (SourceCollections& programCollection) const;
189         virtual TestInstance*           createInstance                                  (Context& context) const;
190         virtual void                            checkSupport                                    (Context& context) const;
191
192 private:
193
194         CaseDef                                                                                 m_data;
195 };
196
197 FSRPixelConsistencyTestCase::FSRPixelConsistencyTestCase(tcu::TestContext& context, const char* name, const char* desc, const CaseDef data)
198         : vkt::TestCase (context, name, desc)
199         , m_data                (data)
200 {
201 }
202
203 FSRPixelConsistencyTestCase::~FSRPixelConsistencyTestCase(void)
204 {
205 }
206
207 void FSRPixelConsistencyTestCase::checkSupport(Context& context) const
208 {
209         const VkImageUsageFlags cbUsage =       VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
210                                                                                 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
211                                                                                 VK_IMAGE_USAGE_TRANSFER_SRC_BIT         |
212                                                                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT;
213
214         context.requireDeviceFunctionality("VK_KHR_fragment_shading_rate");
215
216         if (!context.getFragmentShadingRateFeatures().pipelineFragmentShadingRate)
217                 TCU_THROW(NotSupportedError, "pipelineFragmentShadingRate not supported");
218
219         VkImageFormatProperties imageProperties;
220         VkResult result = context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(context.getPhysicalDevice(), VK_FORMAT_R32G32_UINT, VK_IMAGE_TYPE_2D,
221                                                                                                                                                                                         VK_IMAGE_TILING_OPTIMAL, cbUsage , 0, &imageProperties);
222
223         if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
224                 TCU_THROW(NotSupportedError, "VK_FORMAT_R32G32_UINT not supported");
225
226         if (!(imageProperties.sampleCounts & m_data.samples))
227                 TCU_THROW(NotSupportedError, "Image sample count not supported");
228
229         if ((imageProperties.maxExtent.width < m_data.framebufferExtent.width) || (imageProperties.maxExtent.height < m_data.framebufferExtent.height))
230                 TCU_THROW(NotSupportedError, "Image max extents are smaller than required");
231 }
232
233 void FSRPixelConsistencyTestCase::initPrograms (SourceCollections& programCollection) const
234 {
235         std::stringstream vss;
236
237         vss <<
238                 "#version 450 core\n"
239                 "layout(location = 0) in vec2 position;\n"
240                 "out gl_PerVertex\n"
241                 "{\n"
242                 "   vec4 gl_Position;\n"
243                 "};\n"
244                 "void main()\n"
245                 "{\n"
246                 "  gl_Position = vec4(position, 0, 1);\n"
247                 "}\n";
248
249         programCollection.glslSources.add("vert") << glu::VertexSource(vss.str());
250
251         std::stringstream fssPass0;
252
253         fssPass0 <<
254                 "#version 450 core\n"
255                 "layout(push_constant) uniform PC {\n"
256                 "       uvec2 shadingRate[2];\n"
257                 "} pc;\n"
258                 "layout(location = 0) out uvec2 col0;\n"
259                 "void main()\n"
260                 "{\n"
261                 "  col0.x = (uint(gl_FragCoord.x) % pc.shadingRate[0].x) + ((uint(gl_FragCoord.y) % pc.shadingRate[0].y) * pc.shadingRate[0].x);\n"
262                 "  col0.y = (uint(gl_FragCoord.x) % pc.shadingRate[1].x) + ((uint(gl_FragCoord.y) % pc.shadingRate[1].y) * pc.shadingRate[1].x);\n"
263                 "}\n";
264
265         programCollection.glslSources.add("frag_pass0") << glu::FragmentSource(fssPass0.str());
266
267         std::stringstream fssPass1;
268
269         fssPass1 <<
270                 "#version 450 core\n";
271
272         if (m_data.samples == VK_SAMPLE_COUNT_1_BIT)
273         {
274                 fssPass1 <<
275                         "layout(input_attachment_index=0, set=0, binding=0) uniform usubpassInput inputAttachment;\n";
276         }
277         else
278         {
279                 fssPass1 <<
280                         "layout(input_attachment_index=0, set=0, binding=0) uniform usubpassInputMS inputAttachment;\n";
281         }
282
283         fssPass1 <<
284                 "layout(location = 0) out uvec2 col0;\n"
285                 "void main()\n"
286                 "{\n";
287
288         if (m_data.samples == VK_SAMPLE_COUNT_1_BIT)
289         {
290                 fssPass1 <<
291                         "  col0 = subpassLoad(inputAttachment).xy;\n";
292         }
293         else
294         {
295                 fssPass1 <<
296                         "  col0 = subpassLoad(inputAttachment, 0).xy;\n";
297         }
298
299         fssPass1 <<
300                 "}\n";
301
302         programCollection.glslSources.add("frag_pass1") << glu::FragmentSource(fssPass1.str());
303 }
304
305 TestInstance* FSRPixelConsistencyTestCase::createInstance (Context& context) const
306 {
307         return new FSRPixelConsistencyInstance(context, m_data);
308 }
309
310 bool compareShadingRate(VkExtent2D ext1, VkExtent2D ext2)
311 {
312         deUint32 ratio1 = std::max(ext1.width, ext1.height) / std::min(ext1.width, ext1.height);
313         deUint32 ratio2 = std::max(ext2.width, ext2.height) / std::min(ext2.width, ext2.height);
314
315         return ratio1 < ratio2;
316 }
317
318 void FSRPixelConsistencyInstance::clampShadingRate()
319 {
320         deUint32 desiredSize = m_data.shadingRate.width * m_data.shadingRate.height;
321
322         while (desiredSize > 0)
323         {
324                 // Find modes that maximize the area
325                 for (deUint32 i = 0; i < m_supportedFragmentShadingRateCount; ++i)
326                 {
327                         const VkPhysicalDeviceFragmentShadingRateKHR& supportedRate = m_supportedFragmentShadingRates[i];
328
329                         if (supportedRate.sampleCounts & VK_SAMPLE_COUNT_1_BIT)
330                         {
331                                 // We found exact match
332                                 if (supportedRate.fragmentSize.width  == m_data.shadingRate.width       &&
333                                         supportedRate.fragmentSize.height == m_data.shadingRate.height)
334                                 {
335                                         m_shadingRateClamped.push_back(supportedRate.fragmentSize);
336
337                                         return;
338                                 }
339                                 else
340                                 {
341                                         if (supportedRate.fragmentSize.width  <= m_data.shadingRate.width  &&
342                                                 supportedRate.fragmentSize.height <= m_data.shadingRate.height &&
343                                                 supportedRate.fragmentSize.width  *  supportedRate.fragmentSize.height == desiredSize)
344                                         {
345                                                 m_shadingRateClamped.push_back(supportedRate.fragmentSize);
346                                         }
347                                 }
348                         }
349                 }
350                 if (!m_shadingRateClamped.empty())
351                 {
352                         // Sort the modes so that the ones with the smallest aspect ratio are in front
353                         std::sort(m_shadingRateClamped.begin(), m_shadingRateClamped.end(), compareShadingRate);
354
355                         deUint32 desiredRatio = std::max(m_shadingRateClamped[0].width, m_shadingRateClamped[0].height) /
356                                                                         std::min(m_shadingRateClamped[0].width, m_shadingRateClamped[0].height);
357
358                         // Leave only entries with the smallest aspect ratio
359                         auto it = m_shadingRateClamped.begin();
360                         while (it != m_shadingRateClamped.end())
361                         {
362                                 deUint32 ratio = std::max(it->width, it->height) / std::min(it->width, it->height);
363
364                                 if (ratio < desiredRatio)
365                                 {
366                                         it = m_shadingRateClamped.erase(it, m_shadingRateClamped.end());
367                                 }
368                                 else
369                                 {
370                                         ++it;
371                                 }
372                         }
373
374                         return;
375                 }
376                 else
377                 {
378                         desiredSize /= 2;
379                 }
380         }
381         DE_ASSERT(0);
382
383         return;
384 }
385
386 tcu::TestStatus FSRPixelConsistencyInstance::verifyResult(tcu::ConstPixelBufferAccess& resultBuffer, const deUint32 index)
387 {
388         deUint32 pixelIndex                     = std::numeric_limits<unsigned int>::max();
389         deUint32 pixelOutsideIndex      = std::numeric_limits<unsigned int>::max();
390
391         for (int y = 0; y < resultBuffer.getHeight(); y++)
392         {
393                 for (int x = 0; x < resultBuffer.getWidth(); x++)
394                 {
395                         deUint32 pixel = resultBuffer.getPixelUint(x, y)[index];
396
397                         // If pixel was not covered by any triangle, we skip it
398                         if (pixel == std::numeric_limits<unsigned int>::max())
399                         {
400                                 continue;
401                         }
402
403                         // We check if pixel is part of fragment area that is partially outside of framebuffer area
404                         deBool outsideW = (x / m_shadingRateClamped[index].width  + 1) * m_shadingRateClamped[index].width  > static_cast<deUint32>(resultBuffer.getWidth());
405                         deBool outsideH = (y / m_shadingRateClamped[index].height + 1) * m_shadingRateClamped[index].height > static_cast<deUint32>(resultBuffer.getHeight());
406
407                         if (outsideW || outsideH)
408                         {
409                                 // If image robustness is enabled such pixel can have either a value of 0 or one of the values from the area inside framebuffer
410                                 if (m_context.isDeviceFunctionalitySupported("VK_EXT_image_robustness"))
411                                 {
412                                         if (pixelOutsideIndex == std::numeric_limits<unsigned int>::max() || pixelOutsideIndex == 0)
413                                         {
414                                                 pixelOutsideIndex = pixel;
415                                         }
416                                         // If value is non-zero we make sure that all 'corner' pixels have the same value
417                                         else if ((pixel != 0) && (pixelOutsideIndex != pixel))
418                                         {
419                                                 return tcu::TestStatus(QP_TEST_RESULT_FAIL, qpGetTestResultName(QP_TEST_RESULT_FAIL));
420                                         }
421                                 }
422                                 // If image robustness is not enabled such pixel can have an undefined value, so we skip it
423                                 else
424                                 {
425                                         continue;
426                                 }
427                         }
428                         else
429                         {
430                                 if (pixelIndex == std::numeric_limits<unsigned int>::max())
431                                 {
432                                         if (pixel >= m_shadingRateClamped[index].width * m_shadingRateClamped[index].height)
433                                         {
434                                                 return tcu::TestStatus(QP_TEST_RESULT_FAIL, qpGetTestResultName(QP_TEST_RESULT_FAIL));
435                                         }
436
437                                         pixelIndex = pixel;
438                                 }
439                                 // If pixel is not part of 'corner' pixels we make sure that is has the same value as other non-'corner' pixels
440                                 else if (pixelIndex != pixel)
441                                 {
442                                         return tcu::TestStatus(QP_TEST_RESULT_FAIL, qpGetTestResultName(QP_TEST_RESULT_FAIL));
443                                 }
444                         }
445                 }
446         }
447
448         return tcu::TestStatus(QP_TEST_RESULT_PASS, qpGetTestResultName(QP_TEST_RESULT_PASS));
449 }
450
451 tcu::TestStatus FSRPixelConsistencyInstance::iterate (void)
452 {
453         const VkPhysicalDeviceMemoryProperties memoryProperties = vk::getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice());
454
455         Move<VkDevice>                          vkd                      = createImageRobustnessDevice(m_context);
456         const VkDevice                          device           = *vkd;
457         de::MovePtr<DeviceDriver>       deviceDriver = de::MovePtr<DeviceDriver>(new DeviceDriver(m_context.getPlatformInterface(), m_context.getInstance(), device));
458         const DeviceInterface&          vk                       = *deviceDriver.get();
459         const VkQueue                           queue            = getDeviceQueue(vk, device, m_context.getUniversalQueueFamilyIndex(), 0);
460         de::MovePtr<Allocator>          allocator        = de::MovePtr<Allocator>(new SimpleAllocator(vk, device, memoryProperties));
461
462         // Create vertex buffer
463         const VkDeviceSize vertexBufferSize = sizeof(basicTriangles);
464
465         const VkFormat imageFormat = VK_FORMAT_R32G32_UINT;
466
467         de::MovePtr<BufferWithMemory> vertexBuffer;
468         vertexBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
469                 vk, device, *allocator, makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
470
471         float* vbuf = (float*)vertexBuffer->getAllocation().getHostPtr();
472
473         deMemcpy(vbuf, basicTriangles, vertexBufferSize);
474
475         flushAlloc(vk, device, vertexBuffer->getAllocation());
476
477         // Create color output buffer
478         const VkDeviceSize colorOutputBufferSize = m_data.framebufferExtent.width * m_data.framebufferExtent.height * tcu::getPixelSize(mapVkFormat(imageFormat));
479
480         de::MovePtr<BufferWithMemory> colorOutputBuffer;
481         colorOutputBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
482                 vk, device, *allocator, makeBufferCreateInfo(colorOutputBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible));
483
484
485         // Create color attachment for subpass 0
486         de::MovePtr<ImageWithMemory> cbImagePass0;
487         Move<VkImageView>                        cbImagePass0View;
488         {
489                 const VkImageUsageFlags cbUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
490                                                                                   VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
491                                                                                   VK_IMAGE_USAGE_TRANSFER_DST_BIT;
492
493                 const VkImageCreateInfo                 imageCreateInfo =
494                 {
495                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType                      sType;
496                         DE_NULL,                                                                // const void*                          pNext;
497                         (VkImageCreateFlags)0u,                                 // VkImageCreateFlags           flags;
498                         VK_IMAGE_TYPE_2D,                                               // VkImageType                          imageType;
499                         imageFormat,                                                    // VkFormat                                     format;
500                         {
501                                 m_data.framebufferExtent.width,         // deUint32     width;
502                                 m_data.framebufferExtent.height,        // deUint32     height;
503                                 1u                                                                      // deUint32     depth;
504                         },                                                                              // VkExtent3D                           extent;
505                         1u,                                                                             // deUint32                                     mipLevels;
506                         1u,                                                                             // deUint32                                     arrayLayers;
507                         m_data.samples,                                                 // VkSampleCountFlagBits        samples;
508                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                        tiling;
509                         cbUsage,                                                                // VkImageUsageFlags            usage;
510                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                        sharingMode;
511                         0u,                                                                             // deUint32                                     queueFamilyIndexCount;
512                         DE_NULL,                                                                // const deUint32*                      pQueueFamilyIndices;
513                         VK_IMAGE_LAYOUT_UNDEFINED                               // VkImageLayout                        initialLayout;
514                 };
515                 cbImagePass0 = de::MovePtr<ImageWithMemory>(new ImageWithMemory(
516                         vk, device, *allocator, imageCreateInfo, MemoryRequirement::Any));
517
518                 VkImageViewCreateInfo           imageViewCreateInfo =
519                 {
520                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,       // VkStructureType                      sType;
521                         DE_NULL,                                                                        // const void*                          pNext;
522                         (VkImageViewCreateFlags)0u,                                     // VkImageViewCreateFlags       flags;
523                         **cbImagePass0,                                                         // VkImage                                      image;
524                         VK_IMAGE_VIEW_TYPE_2D,                                          // VkImageViewType                      viewType;
525                         imageFormat,                                                            // VkFormat                                     format;
526                         {
527                                 VK_COMPONENT_SWIZZLE_R,                                 // VkComponentSwizzle   r;
528                                 VK_COMPONENT_SWIZZLE_G,                                 // VkComponentSwizzle   g;
529                                 VK_COMPONENT_SWIZZLE_B,                                 // VkComponentSwizzle   b;
530                                 VK_COMPONENT_SWIZZLE_A                                  // VkComponentSwizzle   a;
531                         },                                                                                      // VkComponentMapping            components;
532                         {
533                                 VK_IMAGE_ASPECT_COLOR_BIT,                              // VkImageAspectFlags   aspectMask;
534                                 0u,                                                                             // deUint32                             baseMipLevel;
535                                 1u,                                                                             // deUint32                             levelCount;
536                                 0u,                                                                             // deUint32                             baseArrayLayer;
537                                 1u                                                                              // deUint32                             layerCount;
538                         }                                                                                       // VkImageSubresourceRange      subresourceRange;
539                 };
540                 cbImagePass0View = createImageView(vk, device, &imageViewCreateInfo, NULL);
541         }
542
543         // Create color attachment for subpass 1
544         de::MovePtr<ImageWithMemory> cbImagePass1;
545         Move<VkImageView>                        cbImagePass1View;
546         {
547                 const VkImageUsageFlags cbUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
548                                                                                   VK_IMAGE_USAGE_TRANSFER_SRC_BIT         |
549                                                                                   VK_IMAGE_USAGE_TRANSFER_DST_BIT;
550
551                 const VkImageCreateInfo                 imageCreateInfo =
552                 {
553                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType                      sType;
554                         DE_NULL,                                                                // const void*                          pNext;
555                         (VkImageCreateFlags)0u,                                 // VkImageCreateFlags           flags;
556                         VK_IMAGE_TYPE_2D,                                               // VkImageType                          imageType;
557                         imageFormat,                                                    // VkFormat                                     format;
558                         {
559                                 m_data.framebufferExtent.width,         // deUint32     width;
560                                 m_data.framebufferExtent.height,        // deUint32     height;
561                                 1u                                                                      // deUint32     depth;
562                         },                                                                              // VkExtent3D                           extent;
563                         1u,                                                                             // deUint32                                     mipLevels;
564                         1u,                                                                             // deUint32                                     arrayLayers;
565                         VK_SAMPLE_COUNT_1_BIT,                                  // VkSampleCountFlagBits        samples;
566                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                        tiling;
567                         cbUsage,                                                                // VkImageUsageFlags            usage;
568                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                        sharingMode;
569                         0u,                                                                             // deUint32                                     queueFamilyIndexCount;
570                         DE_NULL,                                                                // const deUint32*                      pQueueFamilyIndices;
571                         VK_IMAGE_LAYOUT_UNDEFINED                               // VkImageLayout                        initialLayout;
572                 };
573                 cbImagePass1 = de::MovePtr<ImageWithMemory>(new ImageWithMemory(
574                         vk, device, *allocator, imageCreateInfo, MemoryRequirement::Any));
575
576                 VkImageViewCreateInfo           imageViewCreateInfo =
577                 {
578                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,       // VkStructureType                      sType;
579                         DE_NULL,                                                                        // const void*                          pNext;
580                         (VkImageViewCreateFlags)0u,                                     // VkImageViewCreateFlags       flags;
581                         **cbImagePass1,                                                         // VkImage                                      image;
582                         VK_IMAGE_VIEW_TYPE_2D,                                          // VkImageViewType                      viewType;
583                         imageFormat,                                                            // VkFormat                                     format;
584                         {
585                                 VK_COMPONENT_SWIZZLE_R,                                 // VkComponentSwizzle   r;
586                                 VK_COMPONENT_SWIZZLE_G,                                 // VkComponentSwizzle   g;
587                                 VK_COMPONENT_SWIZZLE_B,                                 // VkComponentSwizzle   b;
588                                 VK_COMPONENT_SWIZZLE_A                                  // VkComponentSwizzle   a;
589                         },                                                                                      // VkComponentMapping            components;
590                         {
591                                 VK_IMAGE_ASPECT_COLOR_BIT,                              // VkImageAspectFlags   aspectMask;
592                                 0u,                                                                             // deUint32                             baseMipLevel;
593                                 1u,                                                                             // deUint32                             levelCount;
594                                 0u,                                                                             // deUint32                             baseArrayLayer;
595                                 1u                                                                              // deUint32                             layerCount;
596                         }                                                                                       // VkImageSubresourceRange      subresourceRange;
597                 };
598                 cbImagePass1View = createImageView(vk, device, &imageViewCreateInfo, NULL);
599         }
600
601         // Create render pass
602         Move<VkRenderPass>      renderPass;
603         {
604                 const vk::VkAttachmentReference colorAttachment0Reference =
605                 {
606                         0,                                                                                                                      // attachment
607                         vk::VK_IMAGE_LAYOUT_GENERAL,                                                            // layout
608                 };
609
610                 const vk::VkAttachmentReference colorAttachment1Reference =
611                 {
612                         1,                                                                                                                      // attachment
613                         vk::VK_IMAGE_LAYOUT_GENERAL,                                                            // layout
614                 };
615
616                 std::vector<VkAttachmentDescription> attachmentDescriptions;
617
618                 attachmentDescriptions.push_back(
619                         {
620                                 (VkAttachmentDescriptionFlags)0u,                       // VkAttachmentDescriptionFlags         flags;
621                                 imageFormat,                                                            // VkFormat                                                     format;
622                                 m_data.samples,                                                         // VkSampleCountFlagBits                        samples;
623                                 VK_ATTACHMENT_LOAD_OP_LOAD,                                     // VkAttachmentLoadOp                           loadOp;
624                                 VK_ATTACHMENT_STORE_OP_STORE,                           // VkAttachmentStoreOp                          storeOp;
625                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                        // VkAttachmentLoadOp                           stencilLoadOp;
626                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                       // VkAttachmentStoreOp                          stencilStoreOp;
627                                 VK_IMAGE_LAYOUT_GENERAL,                                        // VkImageLayout                                        initialLayout;
628                                 VK_IMAGE_LAYOUT_GENERAL                                         // VkImageLayout                                        finalLayout;
629                         }
630                 );
631
632                 attachmentDescriptions.push_back(
633                         {
634                                 (VkAttachmentDescriptionFlags)0u,                       // VkAttachmentDescriptionFlags         flags;
635                                 imageFormat,                                                            // VkFormat                                                     format;
636                                 VK_SAMPLE_COUNT_1_BIT,                                          // VkSampleCountFlagBits                        samples;
637                                 VK_ATTACHMENT_LOAD_OP_LOAD,                                     // VkAttachmentLoadOp                           loadOp;
638                                 VK_ATTACHMENT_STORE_OP_STORE,                           // VkAttachmentStoreOp                          storeOp;
639                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                        // VkAttachmentLoadOp                           stencilLoadOp;
640                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                       // VkAttachmentStoreOp                          stencilStoreOp;
641                                 VK_IMAGE_LAYOUT_GENERAL,                                        // VkImageLayout                                        initialLayout;
642                                 VK_IMAGE_LAYOUT_GENERAL                                         // VkImageLayout                                        finalLayout;
643                         }
644                 );
645
646                 const VkSubpassDescription subpassDescs[] =
647                 {
648                         {
649                                 (vk::VkSubpassDescriptionFlags)0,                                               // flags
650                                 vk::VK_PIPELINE_BIND_POINT_GRAPHICS,                                    // pipelineBindPoint
651                                 0u,                                                                                                             // inputCount
652                                 DE_NULL,                                                                                                // pInputAttachments
653                                 1u,                                                                                                             // colorCount
654                                 &colorAttachment0Reference,                                                             // pColorAttachments
655                                 DE_NULL,                                                                                                // pResolveAttachments
656                                 DE_NULL,                                                                                                // depthStencilAttachment
657                                 0u,                                                                                                             // preserveCount
658                                 DE_NULL,                                                                                                // pPreserveAttachments
659                         },
660                         {
661                                 (vk::VkSubpassDescriptionFlags)0,                                               // flags
662                                 vk::VK_PIPELINE_BIND_POINT_GRAPHICS,                                    // pipelineBindPoint
663                                 1u,                                                                                                             // inputCount
664                                 &colorAttachment0Reference,                                                             // pInputAttachments
665                                 1u,                                                                                                             // colorCount
666                                 &colorAttachment1Reference,                                                             // pColorAttachments
667                                 DE_NULL,                                                                                                // pResolveAttachments
668                                 DE_NULL,                                                                                                // depthStencilAttachment
669                                 0u,                                                                                                             // preserveCount
670                                 DE_NULL,                                                                                                // pPreserveAttachments
671                         },
672                 };
673
674                 const VkSubpassDependency subpassDependency =
675                 {
676                         0u,                                                                                             // srcSubpass;
677                         1u,                                                                                             // dstSubpass;
678                         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,  // srcStageMask;
679                         VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,                  // dstStageMask;
680                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                   // srcAccessMask;
681                         VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,                    // dstAccessMask;
682                         0                                                                                               // dependencyFlags;
683                 };
684
685                 const VkRenderPassCreateInfo renderPassParams =
686                 {
687                         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                              // sType
688                         DE_NULL,                                                                                                // pNext
689                         (vk::VkRenderPassCreateFlags)0,
690                         (deUint32)attachmentDescriptions.size(),                                // attachmentCount
691                         &attachmentDescriptions[0],                                                             // pAttachments
692                         sizeof(subpassDescs) / sizeof(subpassDescs[0]),                 // subpassCount
693                         subpassDescs,                                                                                   // pSubpasses
694                         1u,                                                                                                             // dependencyCount
695                         &subpassDependency,                                                                             // pDependencies
696                 };
697
698                 renderPass = createRenderPass(vk, device, &renderPassParams);
699         }
700
701         // Create framebuffer
702         Move<VkFramebuffer> framebuffer;
703         {
704                 std::vector<VkImageView> attachments;
705                 attachments.push_back(*cbImagePass0View);
706                 attachments.push_back(*cbImagePass1View);
707
708                 const vk::VkFramebufferCreateInfo framebufferParams =
709                 {
710                         vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,  // sType
711                         DE_NULL,                                                                                // pNext
712                         (vk::VkFramebufferCreateFlags)(0),                              // createFlags
713                         *renderPass,                                                                    // renderPass
714                         (deUint32)attachments.size(),                                   // attachmentCount
715                         &attachments[0],                                                                // pAttachments
716                         m_data.framebufferExtent.width,                                 // width
717                         m_data.framebufferExtent.height,                                // height
718                         1u,                                                                                             // layers
719                 };
720
721                 framebuffer = createFramebuffer(vk, device, &framebufferParams);
722         }
723
724
725         // Create vertex attribute
726         const VkVertexInputBindingDescription vertexBinding =
727         {
728                 0u,                                                     // deUint32                             binding;
729                 sizeof(Vertex),                         // deUint32                             stride;
730                 VK_VERTEX_INPUT_RATE_VERTEX     // VkVertexInputRate    inputRate;
731         };
732
733         const VkVertexInputAttributeDescription vertexInputAttributeDescription =
734         {
735                 0u,                                                     // deUint32     location;
736                 0u,                                                     // deUint32     binding;
737                 VK_FORMAT_R32G32_SFLOAT,        // VkFormat     format;
738                 0u                                                      // deUint32     offset;
739         };
740
741         const VkPipelineVertexInputStateCreateInfo      vertexInputStateCreateInfo =
742         {
743                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,      // VkStructureType                                                      sType;
744                 DE_NULL,                                                                                                        // const void*                                                          pNext;
745                 (VkPipelineVertexInputStateCreateFlags)0,                                       // VkPipelineVertexInputStateCreateFlags        flags;
746                 1u,                                                                                                                     // deUint32                                                                     vertexBindingDescriptionCount;
747                 &vertexBinding,                                                                                         // const VkVertexInputBindingDescription*       pVertexBindingDescriptions;
748                 1u,                                                                                                                     // deUint32                                                                     vertexAttributeDescriptionCount;
749                 &vertexInputAttributeDescription                                                        // const VkVertexInputAttributeDescription*     pVertexAttributeDescriptions;
750         };
751
752         const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo =
753         {
754                 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                                                      sType;
755                 DE_NULL,                                                                                                                // const void*                                                          pNext;
756                 (VkPipelineInputAssemblyStateCreateFlags)0,                                             // VkPipelineInputAssemblyStateCreateFlags      flags;
757                 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,                                                    // VkPrimitiveTopology                                          topology;
758                 VK_FALSE                                                                                                                // VkBool32                                                                     primitiveRestartEnable;
759         };
760
761         // Create rasterization state
762         const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
763         {
764                 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                                                      sType;
765                 DE_NULL,                                                                                                                // const void*                                                          pNext;
766                 (VkPipelineRasterizationStateCreateFlags)0,                                             // VkPipelineRasterizationStateCreateFlags      flags;
767                 VK_FALSE,                                                                                                               // VkBool32                                                                     depthClampEnable;
768                 VK_FALSE,                                                                                                               // VkBool32                                                                     rasterizerDiscardEnable;
769                 VK_POLYGON_MODE_FILL,                                                                                   // VkPolygonMode                                                        polygonMode;
770                 VK_CULL_MODE_NONE,                                                                                              // VkCullModeFlags                                                      cullMode;
771                 VK_FRONT_FACE_CLOCKWISE,                                                                                // VkFrontFace                                                          frontFace;
772                 VK_FALSE,                                                                                                               // VkBool32                                                                     depthBiasEnable;
773                 0.0f,                                                                                                                   // float                                                                        depthBiasConstantFactor;
774                 0.0f,                                                                                                                   // float                                                                        depthBiasClamp;
775                 0.0f,                                                                                                                   // float                                                                        depthBiasSlopeFactor;
776                 1.0f                                                                                                                    // float                                                                        lineWidth;
777         };
778
779         // Create scissor and viewport
780         VkViewport      viewport        = makeViewport(m_data.framebufferExtent.width, m_data.framebufferExtent.height);
781         VkRect2D        scissor         = makeRect2D(m_data.framebufferExtent.width, m_data.framebufferExtent.height);
782
783         const VkPipelineViewportStateCreateInfo viewportStateCreateInfo =
784         {
785                 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,          // VkStructureType                                                      sType
786                 DE_NULL,                                                                                                        // const void*                                                          pNext
787                 (VkPipelineViewportStateCreateFlags)0,                                          // VkPipelineViewportStateCreateFlags           flags
788                 1u,                                                                                                                     // deUint32                                                                     viewportCount
789                 &viewport,                                                                                                      // const VkViewport*                                            pViewports
790                 1u,                                                                                                                     // deUint32                                                                     scissorCount
791                 &scissor                                                                                                        // const VkRect2D*                                                      pScissors
792         };
793
794         const VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo =
795         {
796                 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,           // VkStructureType                                        sType;
797                 DE_NULL,                                                                                                        // const void*                                            pNext;
798                 (VkPipelineDynamicStateCreateFlags)0,                                           // VkPipelineDynamicStateCreateFlags    flags;
799                 0u,                                                                                                                     // uint32_t                                                      dynamicStateCount;
800                 DE_NULL,                                                                                                        // const VkDynamicState*                                pDynamicStates;
801         };
802
803         const VkPipelineColorBlendAttachmentState colorBlendAttachmentState[] =
804         {
805                 {
806                         VK_FALSE,                               // VkBool32                                     blendEnable;
807                         VK_BLEND_FACTOR_ZERO,   // VkBlendFactor                        srcColorBlendFactor;
808                         VK_BLEND_FACTOR_ZERO,   // VkBlendFactor                        dstColorBlendFactor;
809                         VK_BLEND_OP_ADD,                // VkBlendOp                            colorBlendOp;
810                         VK_BLEND_FACTOR_ZERO,   // VkBlendFactor                        srcAlphaBlendFactor;
811                         VK_BLEND_FACTOR_ZERO,   // VkBlendFactor                        dstAlphaBlendFactor;
812                         VK_BLEND_OP_ADD,                // VkBlendOp                            alphaBlendOp;
813                         0xf                                             // VkColorComponentFlags        colorWriteMask;
814                 }
815         };
816
817         const VkPipelineColorBlendStateCreateInfo               colorBlendStateCreateInfo =
818         {
819                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,                                       // VkStructureType                                                              sType;
820                 DE_NULL,                                                                                                                                        // const void*                                                                  pNext;
821                 0u,                                                                                                                                                     // VkPipelineColorBlendStateCreateFlags                 flags;
822                 VK_FALSE,                                                                                                                                       // VkBool32                                                                             logicOpEnable;
823                 VK_LOGIC_OP_COPY,                                                                                                                       // VkLogicOp                                                                    logicOp;
824                 sizeof(colorBlendAttachmentState) / sizeof(colorBlendAttachmentState[0]),       // deUint32                                                                             attachmentCount;
825                 colorBlendAttachmentState,                                                                                                      // const VkPipelineColorBlendAttachmentState*   pAttachments;
826                 { 1.0f, 1.0f, 1.0f, 1.0f }                                                                                                      // float                                                                                blendConstants[4];
827         };
828
829         VkPipelineDepthStencilStateCreateInfo   depthStencilStateParams =
830         {
831                 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,     // VkStructureType                                                      sType;
832                 DE_NULL,                                                                                                        // const void*                                                          pNext;
833                 0u,                                                                                                                     // VkPipelineDepthStencilStateCreateFlags       flags;
834                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthTestEnable;
835                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthWriteEnable;
836                 VK_COMPARE_OP_ALWAYS,                                                                           // VkCompareOp                                                          depthCompareOp;
837                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthBoundsTestEnable;
838                 VK_FALSE,                                                                                                       // VkBool32                                                                     stencilTestEnable;
839                 // VkStencilOpState     front;
840                 {
841                         VK_STENCIL_OP_REPLACE,  // VkStencilOp  failOp;
842                         VK_STENCIL_OP_REPLACE,  // VkStencilOp  passOp;
843                         VK_STENCIL_OP_REPLACE,  // VkStencilOp  depthFailOp;
844                         VK_COMPARE_OP_ALWAYS,   // VkCompareOp  compareOp;
845                         0u,                                             // deUint32             compareMask;
846                         0xFFu,                                  // deUint32             writeMask;
847                         0xFFu,                                  // deUint32             reference;
848                 },
849                 // VkStencilOpState     back;
850                 {
851                         VK_STENCIL_OP_REPLACE,  // VkStencilOp  failOp;
852                         VK_STENCIL_OP_REPLACE,  // VkStencilOp  passOp;
853                         VK_STENCIL_OP_REPLACE,  // VkStencilOp  depthFailOp;
854                         VK_COMPARE_OP_ALWAYS,   // VkCompareOp  compareOp;
855                         0u,                                             // deUint32             compareMask;
856                         0xFFu,                                  // deUint32             writeMask;
857                         0xFFu,                                  // deUint32             reference;
858                 },
859                 0.0f,                                           // float                        minDepthBounds;
860                 0.0f,                                           // float                        maxDepthBounds;
861         };
862
863         // Create pipeline for pass 0
864         Move<VkPipeline> pipelinePass0;
865         Move<VkPipelineLayout> pipelineLayoutPass0;
866         {
867                 const VkPushConstantRange               pushConstantRange =
868                 {
869                         VK_SHADER_STAGE_FRAGMENT_BIT,                                                           // VkShaderStageFlags                                   stageFlags;
870                         0u,                                                                                                                     // deUint32                                                             offset;
871                         2 * sizeof(VkExtent2D)                                                                          // deUint32                                                             size;
872                 };
873
874                 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
875                 {
876                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,                          // sType
877                         DE_NULL,                                                                                                        // pNext
878                         (VkPipelineLayoutCreateFlags)0,
879                         0u,                                                                                                                     // setLayoutCount
880                         DE_NULL,                                                                                                        // pSetLayouts
881                         1u,                                                                                                                     // pushConstantRangeCount
882                         &pushConstantRange,                                                                                     // pPushConstantRanges
883                 };
884
885                 pipelineLayoutPass0 = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo, NULL);
886
887                 const VkPipelineMultisampleStateCreateInfo      multisampleStateCreateInfo =
888                 {
889                         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType
890                         DE_NULL,                                                                                                        // const void*                                  pNext
891                         0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags
892                         (VkSampleCountFlagBits)m_data.samples,                                          // VkSampleCountFlagBits                                        rasterizationSamples
893                         VK_FALSE,                                                                                                       // VkBool32                                                                     sampleShadingEnable
894                         1.0f,                                                                                                           // float                                                                        minSampleShading
895                         DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask
896                         VK_FALSE,                                                                                                       // VkBool32                                                                     alphaToCoverageEnable
897                         VK_FALSE                                                                                                        // VkBool32                                                                     alphaToOneEnable
898                 };
899
900                 Move<VkShaderModule> vertShader = createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0);
901                 Move<VkShaderModule> fragShader = createShaderModule(vk, device, m_context.getBinaryCollection().get("frag_pass0"), 0);
902
903                 const VkPipelineShaderStageCreateInfo   shaderCreateInfo[] =
904                 {
905                         {
906                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
907                                 DE_NULL,
908                                 (VkPipelineShaderStageCreateFlags)0,
909                                 VK_SHADER_STAGE_VERTEX_BIT,                                                                     // stage
910                                 *vertShader,                                                                                            // shader
911                                 "main",
912                                 DE_NULL,                                                                                                        // pSpecializationInfo
913                         },
914                         {
915                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
916                                 DE_NULL,
917                                 (VkPipelineShaderStageCreateFlags)0,
918                                 VK_SHADER_STAGE_FRAGMENT_BIT,                                                           // stage
919                                 *fragShader,                                                                                            // shader
920                                 "main",
921                                 DE_NULL,                                                                                                        // pSpecializationInfo
922                         }
923                 };
924
925                 const VkGraphicsPipelineCreateInfo      graphicsPipelineCreateInfo =
926                 {
927                         VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,                // VkStructureType                                                                      sType;
928                         DE_NULL,                                                                                                // const void*                                                                          pNext;
929                         (VkPipelineCreateFlags)0,                                                               // VkPipelineCreateFlags                                                        flags;
930                         sizeof(shaderCreateInfo) / sizeof(shaderCreateInfo[0]), // deUint32                                                                                     stageCount;
931                         &shaderCreateInfo[0],                                                                   // const VkPipelineShaderStageCreateInfo*                       pStages;
932                         &vertexInputStateCreateInfo,                                                    // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
933                         &inputAssemblyStateCreateInfo,                                                  // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
934                         DE_NULL,                                                                                                // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
935                         &viewportStateCreateInfo,                                                               // const VkPipelineViewportStateCreateInfo*                     pViewportState;
936                         &rasterizationStateCreateInfo,                                                  // const VkPipelineRasterizationStateCreateInfo*        pRasterizationState;
937                         &multisampleStateCreateInfo,                                                    // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
938                         &depthStencilStateParams,                                                               // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
939                         &colorBlendStateCreateInfo,                                                             // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
940                         &dynamicStateCreateInfo,                                                                // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
941                         pipelineLayoutPass0.get(),                                                              // VkPipelineLayout                                                                     layout;
942                         renderPass.get(),                                                                               // VkRenderPass                                                                         renderPass;
943                         0u,                                                                                                             // deUint32                                                                                     subpass;
944                         DE_NULL,                                                                                                // VkPipeline                                                                           basePipelineHandle;
945                         0                                                                                                               // int                                                                                          basePipelineIndex;
946                 };
947
948                 pipelinePass0 = createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineCreateInfo);
949         }
950
951
952         // Create pipeline for pass 1
953         Move<VkPipeline>                                pipelinePass1;
954         Move<VkPipelineLayout>                  pipelineLayoutPass1;
955         Move<vk::VkDescriptorPool>              descriptorPool;
956         Move<vk::VkDescriptorSetLayout> descriptorSetLayout;
957         Move<vk::VkDescriptorSet>               descriptorSet;
958         {
959                 const VkDescriptorSetLayoutBinding bindings[] =
960                 {
961                         {
962                                 0u,                                                                             // binding
963                                 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,    // descriptorType
964                                 1u,                                                                             // descriptorCount
965                                 VK_SHADER_STAGE_FRAGMENT_BIT,                   // stageFlags
966                                 DE_NULL,                                                                // pImmutableSamplers
967                         }
968                 };
969
970                 // Create a layout and allocate a descriptor set for it.
971                 const VkDescriptorSetLayoutCreateInfo setLayoutCreateInfo =
972                 {
973                         vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,        // sType
974                         DE_NULL,                                                                                                        // pNext
975                         (VkDescriptorSetLayoutCreateFlags)(0),                                          // flags
976                         sizeof(bindings) / sizeof(bindings[0]),                                         // bindingCount
977                         &bindings[0]                                                                                            // pBindings
978                 };
979
980                 descriptorSetLayout = vk::createDescriptorSetLayout(vk, device, &setLayoutCreateInfo);
981
982                 vk::DescriptorPoolBuilder poolBuilder;
983
984                 for (deInt32 i = 0; i < (deInt32)(sizeof(bindings) / sizeof(bindings[0])); ++i)
985                 {
986                         poolBuilder.addType(bindings[i].descriptorType, bindings[i].descriptorCount);
987                 }
988
989                 descriptorPool = poolBuilder.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
990                 descriptorSet = makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout);
991
992                 VkDescriptorImageInfo imageInfo = makeDescriptorImageInfo(DE_NULL, *cbImagePass0View, VK_IMAGE_LAYOUT_GENERAL);
993
994                 VkWriteDescriptorSet writeDescriptorSet =
995                 {
996                         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,                                                 // sType
997                         DE_NULL,                                                                                                                // pNext
998                         *descriptorSet,                                                                                                 // dstSet
999                         0u,                                                                                                                             // dstBinding
1000                         0u,                                                                                                                             // dstArrayElement
1001                         1u,                                                                                                                             // descriptorCount
1002                         bindings[0].descriptorType,                                                                             // descriptorType
1003                         &imageInfo,                                                                                                             // pImageInfo
1004                         DE_NULL,                                                                                                                // pBufferInfo
1005                         DE_NULL,                                                                                                                // pTexelBufferView
1006                 };
1007
1008                 vk.updateDescriptorSets(device, 1, &writeDescriptorSet, 0, NULL);
1009
1010                 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
1011                 {
1012                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,                          // sType
1013                         DE_NULL,                                                                                                        // pNext
1014                         (VkPipelineLayoutCreateFlags)0,
1015                         1u,                                                                                                                     // setLayoutCount
1016                         &descriptorSetLayout.get(),                                                                     // pSetLayouts
1017                         0u,                                                                                                                     // pushConstantRangeCount
1018                         DE_NULL,                                                                                                        // pPushConstantRanges
1019                 };
1020
1021                 pipelineLayoutPass1 = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo, NULL);
1022
1023                 const VkPipelineMultisampleStateCreateInfo      multisampleStateCreateInfo =
1024                 {
1025                         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType
1026                         DE_NULL,                                                                                                        // const void*                                                          pNext
1027                         0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags
1028                         VK_SAMPLE_COUNT_1_BIT,                                                                          // VkSampleCountFlagBits                                        rasterizationSamples
1029                         VK_FALSE,                                                                                                       // VkBool32                                                                     sampleShadingEnable
1030                         1.0f,                                                                                                           // float                                                                        minSampleShading
1031                         DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask
1032                         VK_FALSE,                                                                                                       // VkBool32                                                                     alphaToCoverageEnable
1033                         VK_FALSE                                                                                                        // VkBool32                                                                     alphaToOneEnable
1034                 };
1035
1036                 VkPipelineFragmentShadingRateStateCreateInfoKHR shadingRateStateCreateInfo =
1037                 {
1038                         VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR,                                                         // VkStructureType                                              sType;
1039                         DE_NULL,                                                                                                                                                                                        // const void*                                                  pNext;
1040                         m_data.shadingRate,                                                                                                                                                                     // VkExtent2D                                                   fragmentSize;
1041                         { VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR, VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR },       // VkFragmentShadingRateCombinerOpKHR   combinerOps[2];
1042                 };
1043
1044                 Move<VkShaderModule> vertShader = createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0);
1045                 Move<VkShaderModule> fragShader = createShaderModule(vk, device, m_context.getBinaryCollection().get("frag_pass1"), 0);
1046
1047                 const VkPipelineShaderStageCreateInfo   shaderCreateInfo[] =
1048                 {
1049                         {
1050                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1051                                 DE_NULL,
1052                                 (VkPipelineShaderStageCreateFlags)0,
1053                                 VK_SHADER_STAGE_VERTEX_BIT,                                                                     // stage
1054                                 *vertShader,                                                                                            // shader
1055                                 "main",
1056                                 DE_NULL,                                                                                                        // pSpecializationInfo
1057                         },
1058                         {
1059                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1060                                 DE_NULL,
1061                                 (VkPipelineShaderStageCreateFlags)0,
1062                                 VK_SHADER_STAGE_FRAGMENT_BIT,                                                           // stage
1063                                 *fragShader,                                                                                            // shader
1064                                 "main",
1065                                 DE_NULL,                                                                                                        // pSpecializationInfo
1066                         }
1067                 };
1068
1069                 const VkGraphicsPipelineCreateInfo      graphicsPipelineCreateInfo =
1070                 {
1071                         VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,                // VkStructureType                                                                      sType;
1072                         &shadingRateStateCreateInfo,                                                    // const void*                                                                          pNext;
1073                         (VkPipelineCreateFlags)0,                                                               // VkPipelineCreateFlags                                                        flags;
1074                         sizeof(shaderCreateInfo) / sizeof(shaderCreateInfo[0]), // deUint32                                                                                     stageCount;
1075                         &shaderCreateInfo[0],                                                                   // const VkPipelineShaderStageCreateInfo*                       pStages;
1076                         &vertexInputStateCreateInfo,                                                    // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
1077                         &inputAssemblyStateCreateInfo,                                                  // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
1078                         DE_NULL,                                                                                                // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
1079                         &viewportStateCreateInfo,                                                               // const VkPipelineViewportStateCreateInfo*                     pViewportState;
1080                         &rasterizationStateCreateInfo,                                                  // const VkPipelineRasterizationStateCreateInfo*        pRasterizationState;
1081                         &multisampleStateCreateInfo,                                                    // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
1082                         &depthStencilStateParams,                                                               // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
1083                         &colorBlendStateCreateInfo,                                                             // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
1084                         &dynamicStateCreateInfo,                                                                // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
1085                         pipelineLayoutPass1.get(),                                                              // VkPipelineLayout                                                                     layout;
1086                         renderPass.get(),                                                                               // VkRenderPass                                                                         renderPass;
1087                         1u,                                                                                                             // deUint32                                                                                     subpass;
1088                         DE_NULL,                                                                                                // VkPipeline                                                                           basePipelineHandle;
1089                         0                                                                                                               // int                                                                                          basePipelineIndex;
1090                 };
1091
1092                 pipelinePass1 = createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineCreateInfo);
1093         }
1094
1095         // Create command buffer
1096         Move<VkCommandPool>             cmdPool         = createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, m_context.getUniversalQueueFamilyIndex());
1097         Move<VkCommandBuffer>   cmdBuffer       = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1098
1099         VkImageMemoryBarrier preImageBarrier =
1100         {
1101                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                         // VkStructureType              sType
1102                 DE_NULL,                                                                                        // const void*                  pNext
1103                 0u,                                                                                                     // VkAccessFlags                srcAccessMask
1104                 VK_ACCESS_TRANSFER_WRITE_BIT,                                           // VkAccessFlags                dstAccessMask
1105                 VK_IMAGE_LAYOUT_UNDEFINED,                                                      // VkImageLayout                oldLayout
1106                 VK_IMAGE_LAYOUT_GENERAL,                                                        // VkImageLayout                newLayout
1107                 VK_QUEUE_FAMILY_IGNORED,                                                        // uint32_t                             srcQueueFamilyIndex
1108                 VK_QUEUE_FAMILY_IGNORED,                                                        // uint32_t                             dstQueueFamilyIndex
1109                 **cbImagePass0,                                                                         // VkImage                              image
1110                 {
1111                         VK_IMAGE_ASPECT_COLOR_BIT,                              // VkImageAspectFlags   aspectMask
1112                         0u,                                                                             // uint32_t                             baseMipLevel
1113                         VK_REMAINING_MIP_LEVELS,                                // uint32_t                             mipLevels,
1114                         0u,                                                                             // uint32_t                             baseArray
1115                         VK_REMAINING_ARRAY_LAYERS,                              // uint32_t                             arraySize
1116                 }
1117         };
1118
1119         // Record commands
1120         beginCommandBuffer(vk, *cmdBuffer, 0u);
1121
1122         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1123                                                         (VkDependencyFlags)0,
1124                                                         0, (const VkMemoryBarrier*)DE_NULL,
1125                                                         0, (const VkBufferMemoryBarrier*)DE_NULL,
1126                                                         1, &preImageBarrier);
1127
1128         preImageBarrier.image = **cbImagePass1;
1129
1130         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1131                                                         (VkDependencyFlags)0,
1132                                                         0, (const VkMemoryBarrier*)DE_NULL,
1133                                                         0, (const VkBufferMemoryBarrier*)DE_NULL,
1134                                                         1, &preImageBarrier);
1135
1136         // Clear both images to UINT_MAX
1137         VkImageSubresourceRange range           = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1138         VkClearValue                    clearColor      = makeClearValueColorU32(std::numeric_limits<unsigned int>::max(),0,0,0);
1139
1140         vk.cmdClearColorImage(*cmdBuffer, **cbImagePass0, VK_IMAGE_LAYOUT_GENERAL, &clearColor.color, 1, &range);
1141         vk.cmdClearColorImage(*cmdBuffer, **cbImagePass1, VK_IMAGE_LAYOUT_GENERAL, &clearColor.color, 1, &range);
1142
1143         beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer,
1144                                         makeRect2D(m_data.framebufferExtent.width, m_data.framebufferExtent.height),
1145                                         0, DE_NULL, VK_SUBPASS_CONTENTS_INLINE, DE_NULL);
1146
1147         // Put primitive shading rate in a push constant
1148         if (m_shadingRateClamped.size() == 1)
1149         {
1150                 vk.cmdPushConstants(*cmdBuffer, *pipelineLayoutPass0, VK_SHADER_STAGE_FRAGMENT_BIT,     0, sizeof(m_shadingRateClamped[0]), &m_shadingRateClamped[0]);
1151                 vk.cmdPushConstants(*cmdBuffer, *pipelineLayoutPass0, VK_SHADER_STAGE_FRAGMENT_BIT, sizeof(m_shadingRateClamped[0]), sizeof(m_shadingRateClamped[0]), &m_shadingRateClamped[0]);
1152         }
1153         else
1154         {
1155                 vk.cmdPushConstants(*cmdBuffer, *pipelineLayoutPass0, VK_SHADER_STAGE_FRAGMENT_BIT, 0, static_cast<deUint32>(m_shadingRateClamped.size() * sizeof(m_shadingRateClamped[0])), &m_shadingRateClamped[0]);
1156         }
1157
1158         // Bind vertex buffer
1159         const VkDeviceSize vertexBufferOffset = 0;
1160         VkBuffer vb = **vertexBuffer;
1161         vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vb, &vertexBufferOffset);
1162
1163         // Bind pipeline
1164         vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelinePass0);
1165
1166         // Draw triangles
1167         vk.cmdDraw(*cmdBuffer, sizeof(basicTriangles) / sizeof(Vertex), 1u, 0u, 0u);
1168
1169         // Start next subpass
1170         vk.cmdNextSubpass(*cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
1171
1172         // Bind descriptors
1173         vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayoutPass1, 0, 1, &descriptorSet.get(), 0, DE_NULL);
1174
1175         // Bind vertex buffer
1176         vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vb, &vertexBufferOffset);
1177
1178         // Bind pipeline
1179         vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelinePass1);
1180
1181         // Draw triangles
1182         vk.cmdDraw(*cmdBuffer, sizeof(basicTriangles) / sizeof(Vertex), 1u, 0u, 0u);
1183
1184         endRenderPass(vk, *cmdBuffer);
1185
1186         VkImageMemoryBarrier postImageBarrier =
1187         {
1188                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                         // VkStructureType              sType
1189                 DE_NULL,                                                                                        // const void*                  pNext
1190                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                           // VkAccessFlags                srcAccessMask
1191                 VK_ACCESS_TRANSFER_READ_BIT,                                            // VkAccessFlags                dstAccessMask
1192                 VK_IMAGE_LAYOUT_GENERAL,                                                        // VkImageLayout                oldLayout
1193                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,                           // VkImageLayout                newLayout
1194                 VK_QUEUE_FAMILY_IGNORED,                                                        // uint32_t                             srcQueueFamilyIndex
1195                 VK_QUEUE_FAMILY_IGNORED,                                                        // uint32_t                             dstQueueFamilyIndex
1196                 **cbImagePass1,                                                                         // VkImage                              image
1197                 {
1198                         VK_IMAGE_ASPECT_COLOR_BIT,                              // VkImageAspectFlags   aspectMask
1199                         0u,                                                                             // uint32_t                             baseMipLevel
1200                         VK_REMAINING_MIP_LEVELS,                                // uint32_t                             mipLevels,
1201                         0u,                                                                             // uint32_t                             baseArray
1202                         VK_REMAINING_ARRAY_LAYERS,                              // uint32_t                             arraySize
1203                 }
1204         };
1205
1206         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
1207
1208         const VkBufferImageCopy copyRegion =
1209         {
1210                 0u,                                                                                                                                             // VkDeviceSize                         bufferOffset;
1211                 0u,                                                                                                                                             // deUint32                                     bufferRowLength;
1212                 0u,                                                                                                                                             // deUint32                                     bufferImageHeight;
1213                 {
1214                         VK_IMAGE_ASPECT_COLOR_BIT,                                                                                      // VkImageAspectFlags           aspect;
1215                         0u,                                                                                                                                     // deUint32                                     mipLevel;
1216                         0u,                                                                                                                                     // deUint32                                     baseArrayLayer;
1217                         1u,                                                                                                                                     // deUint32                                     layerCount;
1218                 },                                                                                                                                              // VkImageSubresourceLayers     imageSubresource;
1219                 { 0, 0, 0 },                                                                                                                    // VkOffset3D                           imageOffset;
1220                 {m_data.framebufferExtent.width, m_data.framebufferExtent.height, 1}    // VkExtent3D                           imageExtent;
1221         };
1222
1223
1224         vk.cmdCopyImageToBuffer(*cmdBuffer, **cbImagePass1, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **colorOutputBuffer, 1u, &copyRegion);
1225
1226         const VkBufferMemoryBarrier     bufferBarrier =
1227         {
1228                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
1229                 DE_NULL,                                                                        // const void*          pNext;
1230                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags        srcAccessMask;
1231                 VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags        dstAccessMask;
1232                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
1233                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
1234                 **colorOutputBuffer,                                            // VkBuffer                     buffer;
1235                 0ull,                                                                           // VkDeviceSize         offset;
1236                 VK_WHOLE_SIZE                                                           // VkDeviceSize         size;
1237         };
1238
1239         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
1240
1241         endCommandBuffer(vk, *cmdBuffer);
1242
1243         submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
1244
1245         // Read buffer data
1246         invalidateAlloc(vk, device, colorOutputBuffer->getAllocation());
1247
1248         tcu::ConstPixelBufferAccess resultBuffer = tcu::ConstPixelBufferAccess(
1249                 tcu::TextureFormat(tcu::TextureFormat::RG, tcu::TextureFormat::UNSIGNED_INT32),
1250                 m_data.framebufferExtent.width, m_data.framebufferExtent.height, 1, (const void *)colorOutputBuffer->getAllocation().getHostPtr());
1251
1252         for (deUint32 i = 0; i < m_shadingRateClamped.size(); i++)
1253         {
1254                 tcu::TestStatus result = verifyResult(resultBuffer, i);
1255                 if (result.getCode() == QP_TEST_RESULT_PASS)
1256                 {
1257                         return result;
1258                 }
1259         }
1260
1261         return tcu::TestStatus(QP_TEST_RESULT_FAIL, qpGetTestResultName(QP_TEST_RESULT_FAIL));
1262 }
1263
1264 }       // anonymous
1265
1266 void createPixelConsistencyTests(tcu::TestContext& testCtx, tcu::TestCaseGroup* parentGroup)
1267 {
1268         typedef struct
1269         {
1270                 deUint32                                count;
1271                 const char*                             name;
1272                 const char*                             description;
1273         } TestGroupCase;
1274
1275         typedef struct
1276         {
1277                 VkExtent2D                              count;
1278                 const char*                             name;
1279                 const char*                             description;
1280         } TestGroupCase2D;
1281
1282         TestGroupCase2D shadingRateCases[] =
1283         {
1284                 { {1, 1},       "rate_1x1",     "1x1 shading rate"      },
1285                 { {1, 2},       "rate_1x2",     "1x2 shading rate"      },
1286                 { {1, 4},       "rate_1x4",     "1x4 shading rate"      },
1287                 { {2, 1},       "rate_2x1",     "2x1 shading rate"      },
1288                 { {2, 2},       "rate_2x2",     "2x2 shading rate"      },
1289                 { {2, 4},       "rate_2x4",     "2x4 shading rate"      },
1290                 { {4, 1},       "rate_4x1",     "4x1 shading rate"      },
1291                 { {4, 2},       "rate_4x2",     "4x2 shading rate"      },
1292                 { {4, 4},       "rate_4x4",     "4x4 shading rate"      },
1293         };
1294
1295         TestGroupCase sampCases[] =
1296         {
1297                 { VK_SAMPLE_COUNT_1_BIT,        "samples_1",    "1 raster sample"       },
1298                 { VK_SAMPLE_COUNT_2_BIT,        "samples_2",    "2 raster samples"      },
1299                 { VK_SAMPLE_COUNT_4_BIT,        "samples_4",    "4 raster samples"      },
1300                 { VK_SAMPLE_COUNT_8_BIT,        "samples_8",    "8 raster samples"      },
1301                 { VK_SAMPLE_COUNT_16_BIT,       "samples_16",   "16 raster samples"     },
1302         };
1303
1304         TestGroupCase2D extentCases[] =
1305         {
1306                 { {1,   1},             "extent_1x1",           "framebuffer size 1x1"          },
1307                 { {4,   4},             "extent_4x4",           "framebuffer size 4x4"          },
1308                 { {33,  35},    "extent_33x35",         "framebuffer size 33x35"        },
1309                 { {151, 431},   "extent_151x431",       "framebuffer size 151x431"      },
1310                 { {256, 256},   "extent_256x256",       "framebuffer size 256x256"      },
1311         };
1312
1313         de::MovePtr<tcu::TestCaseGroup> pixelGroup(new tcu::TestCaseGroup(testCtx, "pixel_consistency", "Pixel selection consistency"));
1314
1315         for (int rateNdx = 0; rateNdx < DE_LENGTH_OF_ARRAY(shadingRateCases); rateNdx++)
1316         {
1317                 de::MovePtr<tcu::TestCaseGroup> rateGroup(new tcu::TestCaseGroup(testCtx, shadingRateCases[rateNdx].name, shadingRateCases[rateNdx].description));
1318
1319                 for (int sampNdx = 0; sampNdx < DE_LENGTH_OF_ARRAY(sampCases); sampNdx++)
1320                 {
1321                         de::MovePtr<tcu::TestCaseGroup> sampleGroup(new tcu::TestCaseGroup(testCtx, sampCases[sampNdx].name, sampCases[sampNdx].description));
1322
1323                         for (int extNdx = 0; extNdx < DE_LENGTH_OF_ARRAY(extentCases); extNdx++)
1324                         {
1325                                 CaseDef c =
1326                                 {
1327                                         shadingRateCases[rateNdx].count,
1328                                         (VkSampleCountFlagBits)sampCases[sampNdx].count,
1329                                         extentCases[extNdx].count
1330                                 };
1331
1332                                 sampleGroup->addChild(new FSRPixelConsistencyTestCase(testCtx, extentCases[extNdx].name, extentCases[extNdx].description, c));
1333                         }
1334
1335                         rateGroup->addChild(sampleGroup.release());
1336                 }
1337
1338                 pixelGroup->addChild(rateGroup.release());
1339         }
1340
1341         parentGroup->addChild(pixelGroup.release());
1342 }
1343
1344 }       // FragmentShadingRage
1345 }       // vkt