Merge vk-gl-cts/vulkan-cts-1.3.2 into vk-gl-cts/main
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / robustness / vktRobustnessExtsTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2017-2019 The Khronos Group Inc.
6  * Copyright (c) 2018-2020 NVIDIA Corporation
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *        http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Vulkan robustness2 tests
23  *//*--------------------------------------------------------------------*/
24
25 #include "vktRobustnessExtsTests.hpp"
26
27 #include "vkBufferWithMemory.hpp"
28 #include "vkImageWithMemory.hpp"
29 #include "vkImageUtil.hpp"
30 #include "vkQueryUtil.hpp"
31 #include "vkDeviceUtil.hpp"
32 #include "vkBuilderUtil.hpp"
33 #include "vkCmdUtil.hpp"
34 #include "vkTypeUtil.hpp"
35 #include "vkObjUtil.hpp"
36 #include "vkBarrierUtil.hpp"
37 #include "vktRobustnessUtil.hpp"
38
39 #include "vktTestGroupUtil.hpp"
40 #include "vktTestCase.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 "tcuVectorType.hpp"
49 #include "tcuTestCase.hpp"
50 #include "tcuTestLog.hpp"
51
52 #include <string>
53 #include <sstream>
54 #include <algorithm>
55 #include <limits>
56
57 namespace vkt
58 {
59 namespace robustness
60 {
61 namespace
62 {
63 using namespace vk;
64 using namespace std;
65 using de::SharedPtr;
66
67 enum RobustnessFeatureBits
68 {
69         RF_IMG_ROBUSTNESS       = (1            ),
70         RF_ROBUSTNESS2          = (1 << 1       ),
71         SIF_INT64ATOMICS        = (1 << 2       ),
72 };
73
74 using RobustnessFeatures = deUint32;
75
76 // Class to wrap a singleton device with the indicated robustness features.
77 template <RobustnessFeatures FEATURES>
78 class SingletonDevice
79 {
80         SingletonDevice (Context& context)
81                 : m_context(context), m_instanceWrapper(new CustomInstanceWrapper(context)),  m_logicalDevice ()
82         {
83                 // Note we are already checking the needed features are available in checkSupport().
84                 VkPhysicalDeviceRobustness2FeaturesEXT                          robustness2Features                             = initVulkanStructure();
85                 VkPhysicalDeviceImageRobustnessFeaturesEXT                      imageRobustnessFeatures                 = initVulkanStructure();
86                 VkPhysicalDeviceScalarBlockLayoutFeatures                       scalarBlockLayoutFeatures               = initVulkanStructure();
87                 VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT       shaderImageAtomicInt64Features  = initVulkanStructure();
88                 VkPhysicalDeviceFeatures2                                                       features2                                               = initVulkanStructure();
89
90                 features2.pNext = &scalarBlockLayoutFeatures;
91
92                 if (FEATURES & RF_IMG_ROBUSTNESS)
93                 {
94                         DE_ASSERT(context.isDeviceFunctionalitySupported("VK_EXT_image_robustness"));
95                         imageRobustnessFeatures.pNext = features2.pNext;
96                         features2.pNext = &imageRobustnessFeatures;
97                 }
98
99                 if (FEATURES & RF_ROBUSTNESS2)
100                 {
101                         DE_ASSERT(context.isDeviceFunctionalitySupported("VK_EXT_robustness2"));
102                         robustness2Features.pNext = features2.pNext;
103                         features2.pNext = &robustness2Features;
104                 }
105
106                 if (FEATURES & SIF_INT64ATOMICS)
107                 {
108                         DE_ASSERT(context.isDeviceFunctionalitySupported("VK_EXT_shader_image_atomic_int64"));
109                         shaderImageAtomicInt64Features.pNext = features2.pNext;
110                         features2.pNext = &shaderImageAtomicInt64Features;
111                 }
112
113                 const VkPhysicalDevice physicalDevice = chooseDevice(m_instanceWrapper->instance.getDriver(), m_instanceWrapper->instance, context.getTestContext().getCommandLine());
114                 m_instanceWrapper->instance.getDriver().getPhysicalDeviceFeatures2(physicalDevice, &features2);
115                 m_logicalDevice = createRobustBufferAccessDevice(context, m_instanceWrapper->instance, m_instanceWrapper->instance.getDriver(), &features2);
116
117 #ifndef CTS_USES_VULKANSC
118                 m_deviceDriver = de::MovePtr<DeviceDriver>(new DeviceDriver(context.getPlatformInterface(), m_instanceWrapper->instance, *m_logicalDevice));
119 #else
120                 m_deviceDriver = de::MovePtr<DeviceDriverSC, DeinitDeviceDeleter>(new DeviceDriverSC(context.getPlatformInterface(), m_instanceWrapper->instance, *m_logicalDevice, context.getTestContext().getCommandLine(), context.getResourceInterface(), m_context.getDeviceVulkanSC10Properties()), vk::DeinitDeviceDeleter(context.getResourceInterface().get(), *m_logicalDevice));
121 #endif // CTS_USES_VULKANSC
122         }
123
124 public:
125         ~SingletonDevice()
126         {
127         }
128         static VkInstance getInstance(Context& context)
129         {
130                 if (!m_singletonDevice)
131                         m_singletonDevice = SharedPtr<SingletonDevice>(new SingletonDevice(context));
132                 DE_ASSERT(m_singletonDevice);
133                 return m_singletonDevice->m_instanceWrapper->instance;
134         }
135         static const InstanceInterface& getInstanceInterface(Context& context)
136         {
137                 if (!m_singletonDevice)
138                         m_singletonDevice = SharedPtr<SingletonDevice>(new SingletonDevice(context));
139                 DE_ASSERT(m_singletonDevice);
140                 return m_singletonDevice->m_instanceWrapper->instance.getDriver();
141         }
142
143         static VkDevice getDevice(Context& context)
144         {
145                 if (!m_singletonDevice)
146                         m_singletonDevice = SharedPtr<SingletonDevice>(new SingletonDevice(context));
147                 DE_ASSERT(m_singletonDevice);
148                 return m_singletonDevice->m_logicalDevice.get();
149         }
150         static const DeviceInterface& getDeviceInterface(Context& context)
151         {
152                 if (!m_singletonDevice)
153                         m_singletonDevice = SharedPtr<SingletonDevice>(new SingletonDevice(context));
154                 DE_ASSERT(m_singletonDevice);
155                 return *(m_singletonDevice->m_deviceDriver.get());
156         }
157
158         static void destroy()
159         {
160                 m_singletonDevice.clear();
161         }
162
163 private:
164         const Context&                                                          m_context;
165         std::shared_ptr<CustomInstanceWrapper>          m_instanceWrapper;
166         Move<vk::VkDevice>                                                      m_logicalDevice;
167 #ifndef CTS_USES_VULKANSC
168         de::MovePtr<vk::DeviceDriver>                           m_deviceDriver;
169 #else
170         de::MovePtr<vk::DeviceDriverSC, vk::DeinitDeviceDeleter>        m_deviceDriver;
171 #endif // CTS_USES_VULKANSC
172
173         static SharedPtr<SingletonDevice<FEATURES>>     m_singletonDevice;
174 };
175
176 template <RobustnessFeatures FEATURES>
177 SharedPtr<SingletonDevice<FEATURES>> SingletonDevice<FEATURES>::m_singletonDevice;
178
179 constexpr RobustnessFeatures kImageRobustness                   = RF_IMG_ROBUSTNESS;
180 constexpr RobustnessFeatures kRobustness2                               = RF_ROBUSTNESS2;
181 constexpr RobustnessFeatures kShaderImageInt64Atomics   = SIF_INT64ATOMICS;
182
183 using ImageRobustnessSingleton  = SingletonDevice<kImageRobustness>;
184 using Robustness2Singleton              = SingletonDevice<kRobustness2>;
185
186 using ImageRobustnessInt64AtomicsSingleton      = SingletonDevice<kImageRobustness | kShaderImageInt64Atomics>;
187 using Robustness2Int64AtomicsSingleton          = SingletonDevice<kRobustness2 | kShaderImageInt64Atomics>;
188
189 // Render target / compute grid dimensions
190 static const deUint32 DIM = 8;
191
192 // treated as a phony VkDescriptorType value
193 #define VERTEX_ATTRIBUTE_FETCH 999
194
195 typedef enum
196 {
197         STAGE_COMPUTE = 0,
198         STAGE_VERTEX,
199         STAGE_FRAGMENT,
200         STAGE_RAYGEN
201 } Stage;
202
203 struct CaseDef
204 {
205         VkFormat format;
206         Stage stage;
207         VkFlags allShaderStages;
208         VkFlags allPipelineStages;
209         int/*VkDescriptorType*/ descriptorType;
210         VkImageViewType viewType;
211         VkSampleCountFlagBits samples;
212         int bufferLen;
213         bool unroll;
214         bool vol;
215         bool nullDescriptor;
216         bool useTemplate;
217         bool formatQualifier;
218         bool pushDescriptor;
219         bool testRobustness2;
220         deUint32 imageDim[3]; // width, height, depth or layers
221         bool readOnly;
222 };
223
224 static bool formatIsR64(const VkFormat& f)
225 {
226         switch (f)
227         {
228         case VK_FORMAT_R64_SINT:
229         case VK_FORMAT_R64_UINT:
230                 return true;
231         default:
232                 return false;
233         }
234 }
235
236 // Returns the appropriate singleton device for the given case.
237 VkInstance getInstance(Context& ctx, const CaseDef& caseDef)
238 {
239         if (formatIsR64(caseDef.format))
240         {
241                 if (caseDef.testRobustness2)
242                         return Robustness2Int64AtomicsSingleton::getInstance(ctx);
243                 return ImageRobustnessInt64AtomicsSingleton::getInstance(ctx);
244         }
245
246         if (caseDef.testRobustness2)
247                 return Robustness2Singleton::getInstance(ctx);
248         return ImageRobustnessSingleton::getInstance(ctx);
249 }
250
251 // Returns the appropriate singleton device driver for the given case.
252 const InstanceInterface& getInstanceInterface(Context& ctx, const CaseDef& caseDef)
253 {
254         if (formatIsR64(caseDef.format))
255         {
256                 if (caseDef.testRobustness2)
257                         return Robustness2Int64AtomicsSingleton::getInstanceInterface(ctx);
258                 return ImageRobustnessInt64AtomicsSingleton::getInstanceInterface(ctx);
259         }
260
261         if (caseDef.testRobustness2)
262                 return Robustness2Singleton::getInstanceInterface(ctx);
263         return ImageRobustnessSingleton::getInstanceInterface(ctx);
264 }
265
266 // Returns the appropriate singleton device for the given case.
267 VkDevice getLogicalDevice (Context& ctx, const CaseDef& caseDef)
268 {
269         if (formatIsR64(caseDef.format))
270         {
271                 if (caseDef.testRobustness2)
272                         return Robustness2Int64AtomicsSingleton::getDevice(ctx);
273                 return ImageRobustnessInt64AtomicsSingleton::getDevice(ctx);
274         }
275
276         if (caseDef.testRobustness2)
277                 return Robustness2Singleton::getDevice(ctx);
278         return ImageRobustnessSingleton::getDevice(ctx);
279 }
280
281 // Returns the appropriate singleton device driver for the given case.
282 const DeviceInterface& getDeviceInterface(Context& ctx, const CaseDef& caseDef)
283 {
284         if (formatIsR64(caseDef.format))
285         {
286                 if (caseDef.testRobustness2)
287                         return Robustness2Int64AtomicsSingleton::getDeviceInterface(ctx);
288                 return ImageRobustnessInt64AtomicsSingleton::getDeviceInterface(ctx);
289         }
290
291         if (caseDef.testRobustness2)
292                 return Robustness2Singleton::getDeviceInterface(ctx);
293         return ImageRobustnessSingleton::getDeviceInterface(ctx);
294 }
295
296
297 class Layout
298 {
299 public:
300         vector<VkDescriptorSetLayoutBinding> layoutBindings;
301         vector<deUint8> refData;
302 };
303
304
305 class RobustnessExtsTestInstance : public TestInstance
306 {
307 public:
308                                                 RobustnessExtsTestInstance              (Context& context, const CaseDef& data);
309                                                 ~RobustnessExtsTestInstance     (void);
310         tcu::TestStatus         iterate                                                         (void);
311 private:
312         CaseDef                         m_data;
313 };
314
315 RobustnessExtsTestInstance::RobustnessExtsTestInstance (Context& context, const CaseDef& data)
316         : vkt::TestInstance             (context)
317         , m_data                                (data)
318 {
319 }
320
321 RobustnessExtsTestInstance::~RobustnessExtsTestInstance (void)
322 {
323 }
324
325 class RobustnessExtsTestCase : public TestCase
326 {
327         public:
328                                                                 RobustnessExtsTestCase          (tcu::TestContext& context, const char* name, const char* desc, const CaseDef data);
329                                                                 ~RobustnessExtsTestCase (void);
330         virtual void                            initPrograms                                    (SourceCollections& programCollection) const;
331         virtual TestInstance*           createInstance                                  (Context& context) const;
332         virtual void                            checkSupport                                    (Context& context) const;
333
334 private:
335         CaseDef                                 m_data;
336 };
337
338 RobustnessExtsTestCase::RobustnessExtsTestCase (tcu::TestContext& context, const char* name, const char* desc, const CaseDef data)
339         : vkt::TestCase (context, name, desc)
340         , m_data                (data)
341 {
342 }
343
344 RobustnessExtsTestCase::~RobustnessExtsTestCase (void)
345 {
346 }
347
348 static bool formatIsFloat(const VkFormat& f)
349 {
350         switch (f)
351         {
352         case VK_FORMAT_R32_SFLOAT:
353         case VK_FORMAT_R32G32_SFLOAT:
354         case VK_FORMAT_R32G32B32A32_SFLOAT:
355                 return true;
356         default:
357                 return false;
358         }
359 }
360
361 static bool formatIsSignedInt(const VkFormat& f)
362 {
363         switch (f)
364         {
365         case VK_FORMAT_R32_SINT:
366         case VK_FORMAT_R64_SINT:
367         case VK_FORMAT_R32G32_SINT:
368         case VK_FORMAT_R32G32B32A32_SINT:
369                 return true;
370         default:
371                 return false;
372         }
373 }
374
375 static bool supportsStores(int descriptorType)
376 {
377         switch (descriptorType)
378         {
379         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
380         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
381         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
382         case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
383                 return true;
384         default:
385                 return false;
386         }
387 }
388
389 void RobustnessExtsTestCase::checkSupport(Context& context) const
390 {
391         const auto&     vki                             = context.getInstanceInterface();
392         const auto      physicalDevice  = context.getPhysicalDevice();
393
394         // We need to query feature support using the physical device instead of using the reported context features because robustness2
395         // and image robustness are always disabled in the default device but they may be available.
396         VkPhysicalDeviceRobustness2FeaturesEXT                          robustness2Features                             = initVulkanStructure();
397         VkPhysicalDeviceImageRobustnessFeaturesEXT                      imageRobustnessFeatures                 = initVulkanStructure();
398         VkPhysicalDeviceScalarBlockLayoutFeatures                       scalarLayoutFeatures                    = initVulkanStructure();
399         VkPhysicalDeviceFeatures2                                                       features2                                               = initVulkanStructure();
400
401         context.requireInstanceFunctionality("VK_KHR_get_physical_device_properties2");
402
403         context.requireDeviceFunctionality("VK_EXT_scalar_block_layout");
404         features2.pNext = &scalarLayoutFeatures;
405
406         if (context.isDeviceFunctionalitySupported("VK_EXT_image_robustness"))
407         {
408                 imageRobustnessFeatures.pNext = features2.pNext;
409                 features2.pNext = &imageRobustnessFeatures;
410         }
411
412         if (context.isDeviceFunctionalitySupported("VK_EXT_robustness2"))
413         {
414                 robustness2Features.pNext = features2.pNext;
415                 features2.pNext = &robustness2Features;
416         }
417
418         vki.getPhysicalDeviceFeatures2(physicalDevice, &features2);
419
420         if (formatIsR64(m_data.format))
421         {
422                 context.requireDeviceFunctionality("VK_EXT_shader_image_atomic_int64");
423
424                 VkFormatProperties formatProperties;
425                 vki.getPhysicalDeviceFormatProperties(physicalDevice, m_data.format, &formatProperties);
426
427                 switch (m_data.descriptorType)
428                 {
429                 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
430                         if ((formatProperties.bufferFeatures & VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT) != VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT)
431                                 TCU_THROW(NotSupportedError, "VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT is not supported");
432                         break;
433                 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
434                         if ((formatProperties.bufferFeatures & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT) != VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT)
435                                 TCU_THROW(NotSupportedError, "VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT is not supported");
436                         break;
437                 case VERTEX_ATTRIBUTE_FETCH:
438                         if ((formatProperties.bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) != VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)
439                                 TCU_THROW(NotSupportedError, "VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT is not supported");
440                         break;
441                 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
442                         if ((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)
443                                 TCU_THROW(NotSupportedError, "VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT is not supported");
444                         break;
445                 default: DE_ASSERT(true);
446                 }
447
448                 if (m_data.samples > VK_SAMPLE_COUNT_1_BIT)
449                 {
450                         if ((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)
451                                 TCU_THROW(NotSupportedError, "VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT is not supported");
452                 }
453         }
454
455         // Check needed properties and features
456         if (!scalarLayoutFeatures.scalarBlockLayout)
457                 TCU_THROW(NotSupportedError, "Scalar block layout not supported");
458
459         if (m_data.stage == STAGE_VERTEX && !features2.features.vertexPipelineStoresAndAtomics)
460                 TCU_THROW(NotSupportedError, "Vertex pipeline stores and atomics not supported");
461
462         if (m_data.stage == STAGE_FRAGMENT && !features2.features.fragmentStoresAndAtomics)
463                 TCU_THROW(NotSupportedError, "Fragment shader stores not supported");
464
465         if (m_data.stage == STAGE_RAYGEN)
466                 context.requireDeviceFunctionality("VK_NV_ray_tracing");
467
468         switch (m_data.descriptorType)
469         {
470         default: DE_ASSERT(0); // Fallthrough
471         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
472         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
473         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
474         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
475         case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
476         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
477         case VERTEX_ATTRIBUTE_FETCH:
478                 if (m_data.testRobustness2)
479                 {
480                         if (!robustness2Features.robustBufferAccess2)
481                                 TCU_THROW(NotSupportedError, "robustBufferAccess2 not supported");
482                 }
483                 else
484                 {
485                         // This case is not tested here.
486                         DE_ASSERT(false);
487                 }
488                 break;
489         case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
490         case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
491                 if (m_data.testRobustness2)
492                 {
493                         if (!robustness2Features.robustImageAccess2)
494                                 TCU_THROW(NotSupportedError, "robustImageAccess2 not supported");
495                 }
496                 else
497                 {
498                         if (!imageRobustnessFeatures.robustImageAccess)
499                                 TCU_THROW(NotSupportedError, "robustImageAccess not supported");
500                 }
501                 break;
502         }
503
504         if (m_data.nullDescriptor && !robustness2Features.nullDescriptor)
505                 TCU_THROW(NotSupportedError, "nullDescriptor not supported");
506
507         // The fill shader for 64-bit multisample image tests uses a storage image.
508         if (m_data.samples > VK_SAMPLE_COUNT_1_BIT && formatIsR64(m_data.format) &&
509                 !features2.features.shaderStorageImageMultisample)
510                 TCU_THROW(NotSupportedError, "shaderStorageImageMultisample not supported");
511
512         if ((m_data.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) &&
513                 m_data.samples != VK_SAMPLE_COUNT_1_BIT &&
514                 !features2.features.shaderStorageImageMultisample)
515                 TCU_THROW(NotSupportedError, "shaderStorageImageMultisample not supported");
516
517         if ((m_data.useTemplate || formatIsR64(m_data.format)) && !context.contextSupports(vk::ApiVersion(0, 1, 1, 0)))
518                 TCU_THROW(NotSupportedError, "Vulkan 1.1 not supported");
519
520 #ifndef CTS_USES_VULKANSC
521         if ((m_data.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER || m_data.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) &&
522                 !m_data.formatQualifier)
523         {
524                 const VkFormatProperties3 formatProperties = context.getFormatProperties(m_data.format);
525                 if (!(formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR))
526                         TCU_THROW(NotSupportedError, "Format does not support reading without format");
527                 if (!(formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR))
528                         TCU_THROW(NotSupportedError, "Format does not support writing without format");
529         }
530 #else
531         if ((m_data.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER || m_data.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) &&
532                 !m_data.formatQualifier &&
533                 (!features2.features.shaderStorageImageReadWithoutFormat || !features2.features.shaderStorageImageWriteWithoutFormat))
534                 TCU_THROW(NotSupportedError, "shaderStorageImageReadWithoutFormat or shaderStorageImageWriteWithoutFormat not supported");
535 #endif // CTS_USES_VULKANSC
536
537         if (m_data.pushDescriptor)
538                 context.requireDeviceFunctionality("VK_KHR_push_descriptor");
539
540         if (m_data.viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY && !features2.features.imageCubeArray)
541                 TCU_THROW(NotSupportedError, "Cube array image view type not supported");
542
543         if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") && !context.getDeviceFeatures().robustBufferAccess)
544                 TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: robustBufferAccess not supported by this implementation");
545 }
546
547 void generateLayout(Layout &layout, const CaseDef &caseDef)
548 {
549         vector<VkDescriptorSetLayoutBinding> &bindings = layout.layoutBindings;
550         int numBindings = caseDef.descriptorType != VERTEX_ATTRIBUTE_FETCH ? 2 : 1;
551         bindings = vector<VkDescriptorSetLayoutBinding>(numBindings);
552
553         for (deUint32 b = 0; b < layout.layoutBindings.size(); ++b)
554         {
555                 VkDescriptorSetLayoutBinding &binding = bindings[b];
556                 binding.binding = b;
557                 binding.pImmutableSamplers = NULL;
558                 binding.stageFlags = caseDef.allShaderStages;
559                 binding.descriptorCount = 1;
560
561                 // Output image
562                 if (b == 0)
563                         binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
564                 else if (caseDef.descriptorType != VERTEX_ATTRIBUTE_FETCH)
565                         binding.descriptorType = (VkDescriptorType)caseDef.descriptorType;
566         }
567
568         if (caseDef.nullDescriptor)
569                 return;
570
571         if (caseDef.bufferLen == 0)
572         {
573                 // Clear color values for image tests
574                 static deUint32 urefData[4]             = { 0x12345678, 0x23456789, 0x34567890, 0x45678901 };
575                 static deUint64 urefData64[4]   = { 0x1234567887654321, 0x234567899, 0x345678909, 0x456789019 };
576                 static float frefData[4]                = { 123.f, 234.f, 345.f, 456.f };
577
578                 if (formatIsR64(caseDef.format))
579                 {
580                         layout.refData.resize(32);
581                         deUint64 *ptr = (deUint64 *)layout.refData.data();
582
583                         for (unsigned int i = 0; i < 4; ++i)
584                         {
585                                 ptr[i] = urefData64[i];
586                         }
587                 }
588                 else
589                 {
590                         layout.refData.resize(16);
591                         deMemcpy(layout.refData.data(), formatIsFloat(caseDef.format) ? (const void *)frefData : (const void *)urefData, sizeof(frefData));
592                 }
593         }
594         else
595         {
596                 layout.refData.resize(caseDef.bufferLen & (formatIsR64(caseDef.format) ? ~7: ~3));
597                 for (unsigned int i = 0; i < caseDef.bufferLen / (formatIsR64(caseDef.format) ? sizeof(deUint64) : sizeof(deUint32)); ++i)
598                 {
599                         if (formatIsFloat(caseDef.format))
600                         {
601                                 float *f = (float *)layout.refData.data() + i;
602                                 *f = 2.0f*(float)i + 3.0f;
603                         }
604                         if (formatIsR64(caseDef.format))
605                         {
606                                 deUint64 *u = (deUint64 *)layout.refData.data() + i;
607                                 *u = 2 * i + 3;
608                         }
609                         else
610                         {
611                                 int *u = (int *)layout.refData.data() + i;
612                                 *u = 2*i + 3;
613                         }
614                 }
615         }
616 }
617
618 static string genFetch(const CaseDef &caseDef, int numComponents, const string& vecType, const string& coord, const string& lod)
619 {
620         std::stringstream s;
621         // Fetch from the descriptor.
622         switch (caseDef.descriptorType)
623         {
624         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
625         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
626                 s << vecType << "(ubo0_1.val[" << coord << "]";
627                 for (int i = numComponents; i < 4; ++i) s << ", 0";
628                 s << ")";
629                 break;
630         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
631         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
632                 s << vecType << "(ssbo0_1.val[" << coord << "]";
633                 for (int i = numComponents; i < 4; ++i) s << ", 0";
634                 s << ")";
635                 break;
636         case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
637                 s << "texelFetch(texbo0_1, " << coord << ")";
638                 break;
639         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
640                 s << "imageLoad(image0_1, " << coord << ")";
641                 break;
642         case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
643                 if (caseDef.samples > VK_SAMPLE_COUNT_1_BIT)
644                         s << "texelFetch(texture0_1, " << coord << ")";
645                 else
646                         s << "texelFetch(texture0_1, " << coord << ", " << lod << ")";
647                 break;
648         case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
649                 s << "imageLoad(image0_1, " << coord << ")";
650                 break;
651         case VERTEX_ATTRIBUTE_FETCH:
652                 s << "attr";
653                 break;
654         default: DE_ASSERT(0);
655         }
656         return s.str();
657 }
658
659 static const int storeValue = 123;
660
661 // Get the value stored by genStore.
662 static string getStoreValue(int descriptorType, int numComponents, const string& vecType, const string& bufType)
663 {
664         std::stringstream s;
665         switch (descriptorType)
666         {
667         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
668         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
669                 s << vecType  << "(" << bufType << "(" << storeValue << ")";
670                 for (int i = numComponents; i < 4; ++i) s << ", 0";
671                 s << ")";
672                 break;
673         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
674                 s << vecType << "(" << storeValue << ")";
675                 break;
676         case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
677                 s << vecType << "(" << storeValue << ")";
678                 break;
679         default: DE_ASSERT(0);
680         }
681         return s.str();
682 }
683
684 static string genStore(int descriptorType, const string& vecType, const string& bufType, const string& coord)
685 {
686         std::stringstream s;
687         // Store to the descriptor.
688         switch (descriptorType)
689         {
690         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
691         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
692                 s << "ssbo0_1.val[" << coord << "] = " << bufType << "(" << storeValue << ")";
693                 break;
694         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
695                 s << "imageStore(image0_1, " << coord << ", " << vecType << "(" << storeValue << "))";
696                 break;
697         case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
698                 s << "imageStore(image0_1, " << coord << ", " << vecType << "(" << storeValue << "))";
699                 break;
700         default: DE_ASSERT(0);
701         }
702         return s.str();
703 }
704
705 static string genAtomic(int descriptorType, const string& bufType, const string& coord)
706 {
707         std::stringstream s;
708         // Store to the descriptor. The value doesn't matter, since we only test out of bounds coordinates.
709         switch (descriptorType)
710         {
711         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
712         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
713                 s << "atomicAdd(ssbo0_1.val[" << coord << "], " << bufType << "(10))";
714                 break;
715         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
716                 s << "imageAtomicAdd(image0_1, " << coord << ", " << bufType << "(10))";
717                 break;
718         case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
719                 s << "imageAtomicAdd(image0_1, " << coord << ", " << bufType << "(10))";
720                 break;
721         default: DE_ASSERT(0);
722         }
723         return s.str();
724 }
725
726 static std::string getShaderImageFormatQualifier (const tcu::TextureFormat& format)
727 {
728         const char* orderPart;
729         const char* typePart;
730
731         switch (format.order)
732         {
733                 case tcu::TextureFormat::R:             orderPart = "r";        break;
734                 case tcu::TextureFormat::RG:    orderPart = "rg";       break;
735                 case tcu::TextureFormat::RGB:   orderPart = "rgb";      break;
736                 case tcu::TextureFormat::RGBA:  orderPart = "rgba";     break;
737
738                 default:
739                         DE_FATAL("Impossible");
740                         orderPart = DE_NULL;
741         }
742
743         switch (format.type)
744         {
745                 case tcu::TextureFormat::FLOAT:                         typePart = "32f";               break;
746                 case tcu::TextureFormat::HALF_FLOAT:            typePart = "16f";               break;
747
748                 case tcu::TextureFormat::UNSIGNED_INT64:        typePart = "64ui";              break;
749                 case tcu::TextureFormat::UNSIGNED_INT32:        typePart = "32ui";              break;
750                 case tcu::TextureFormat::UNSIGNED_INT16:        typePart = "16ui";              break;
751                 case tcu::TextureFormat::UNSIGNED_INT8:         typePart = "8ui";               break;
752
753                 case tcu::TextureFormat::SIGNED_INT64:          typePart = "64i";               break;
754                 case tcu::TextureFormat::SIGNED_INT32:          typePart = "32i";               break;
755                 case tcu::TextureFormat::SIGNED_INT16:          typePart = "16i";               break;
756                 case tcu::TextureFormat::SIGNED_INT8:           typePart = "8i";                break;
757
758                 case tcu::TextureFormat::UNORM_INT16:           typePart = "16";                break;
759                 case tcu::TextureFormat::UNORM_INT8:            typePart = "8";                 break;
760
761                 case tcu::TextureFormat::SNORM_INT16:           typePart = "16_snorm";  break;
762                 case tcu::TextureFormat::SNORM_INT8:            typePart = "8_snorm";   break;
763
764                 default:
765                         DE_FATAL("Impossible");
766                         typePart = DE_NULL;
767         }
768
769         return std::string() + orderPart + typePart;
770 }
771
772 string genCoord(string c, int numCoords, VkSampleCountFlagBits samples, int dim)
773 {
774         if (numCoords == 1)
775                 return c;
776
777         if (samples != VK_SAMPLE_COUNT_1_BIT)
778                 numCoords--;
779
780         string coord = "ivec" + to_string(numCoords) + "(";
781
782         for (int i = 0; i < numCoords; ++i)
783         {
784                 if (i == dim)
785                         coord += c;
786                 else
787                         coord += "0";
788                 if (i < numCoords - 1)
789                         coord += ", ";
790         }
791         coord += ")";
792
793         // Append sample coordinate
794         if (samples != VK_SAMPLE_COUNT_1_BIT)
795         {
796                 coord += ", ";
797                 if (dim == numCoords)
798                         coord += c;
799                 else
800                         coord += "0";
801         }
802         return coord;
803 }
804
805 // Normalized coordinates. Divide by "imageDim" and add 0.25 so we're not on a pixel boundary.
806 string genCoordNorm(const CaseDef &caseDef, string c, int numCoords, int numNormalizedCoords, int dim)
807 {
808         // dim can be 3 for cube_array. Reuse the number of layers in that case.
809         dim = std::min(dim, 2);
810
811         if (numCoords == 1)
812                 return c + " / float(" + to_string(caseDef.imageDim[dim]) + ")";
813
814         string coord = "vec" + to_string(numCoords) + "(";
815
816         for (int i = 0; i < numCoords; ++i)
817         {
818                 if (i == dim)
819                         coord += c;
820                 else
821                         coord += "0.25";
822                 if (i < numNormalizedCoords)
823                         coord += " / float(" + to_string(caseDef.imageDim[dim]) + ")";
824                 if (i < numCoords - 1)
825                         coord += ", ";
826         }
827         coord += ")";
828         return coord;
829 }
830
831 void RobustnessExtsTestCase::initPrograms (SourceCollections& programCollection) const
832 {
833         VkFormat format = m_data.format;
834
835         Layout layout;
836         generateLayout(layout, m_data);
837
838         if (layout.layoutBindings.size() > 1 &&
839                 layout.layoutBindings[1].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
840         {
841                 if (format == VK_FORMAT_R64_SINT)
842                         format = VK_FORMAT_R32G32_SINT;
843
844                 if (format == VK_FORMAT_R64_UINT)
845                         format = VK_FORMAT_R32G32_UINT;
846         }
847
848         std::stringstream decls, checks;
849
850         const string    r64                     = formatIsR64(format) ? "64" : "";
851         const string    i64Type         = formatIsR64(format) ? "64_t" : "";
852         const string    vecType         = formatIsFloat(format) ? "vec4" : (formatIsSignedInt(format) ? ("i" + r64 + "vec4") : ("u" + r64 + "vec4"));
853         const string    qLevelType      = vecType == "vec4" ? "float" : ((vecType == "ivec4") || (vecType == "i64vec4")) ? ("int" + i64Type) : ("uint" + i64Type);
854
855         decls << "uvec4 abs(uvec4 x) { return x; }\n";
856         if (formatIsR64(format))
857                 decls << "u64vec4 abs(u64vec4 x) { return x; }\n";
858         decls << "int smod(int a, int b) { if (a < 0) a += b*(abs(a)/b+1); return a%b; }\n";
859
860
861         const int       componetsSize = (formatIsR64(format) ? 8 : 4);
862         int                     refDataNumElements = deIntRoundToPow2(((int)layout.refData.size() / componetsSize), 4);
863         // Pad reference data to include zeros, up to max value of robustUniformBufferAccessSizeAlignment (256).
864         // robustStorageBufferAccessSizeAlignment is 4, so no extra padding needed.
865         if (m_data.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
866                 m_data.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC)
867         {
868                 refDataNumElements = deIntRoundToPow2(refDataNumElements, 256 / (formatIsR64(format) ? 8 : 4));
869         }
870         if (m_data.nullDescriptor)
871                 refDataNumElements = 4;
872
873         if (formatIsFloat(format))
874         {
875                 decls << "float refData[" << refDataNumElements << "] = {";
876                 int i;
877                 for (i = 0; i < (int)layout.refData.size() / 4; ++i)
878                 {
879                         if (i != 0)
880                                 decls << ", ";
881                         decls << ((const float *)layout.refData.data())[i];
882                 }
883                 while (i < refDataNumElements)
884                 {
885                         if (i != 0)
886                                 decls << ", ";
887                         decls << "0";
888                         i++;
889                 }
890         }
891         else if (formatIsR64(format))
892         {
893                 decls << "int" << i64Type << " refData[" << refDataNumElements << "] = {";
894                 int i;
895                 for (i = 0; i < (int)layout.refData.size() / 8; ++i)
896                 {
897                         if (i != 0)
898                                 decls << ", ";
899                         decls << ((const deUint64 *)layout.refData.data())[i] << "l";
900                 }
901                 while (i < refDataNumElements)
902                 {
903                         if (i != 0)
904                                 decls << ", ";
905                         decls << "0l";
906                         i++;
907                 }
908         }
909         else
910         {
911                 decls << "int" << " refData[" << refDataNumElements << "] = {";
912                 int i;
913                 for (i = 0; i < (int)layout.refData.size() / 4; ++i)
914                 {
915                         if (i != 0)
916                                 decls << ", ";
917                         decls << ((const int *)layout.refData.data())[i];
918                 }
919                 while (i < refDataNumElements)
920                 {
921                         if (i != 0)
922                                 decls << ", ";
923                         decls << "0";
924                         i++;
925                 }
926         }
927
928         decls << "};\n";
929         decls << vecType << " zzzz = " << vecType << "(0);\n";
930         decls << vecType << " zzzo = " << vecType << "(0, 0, 0, 1);\n";
931         decls << vecType << " expectedIB;\n";
932
933         string imgprefix = (formatIsFloat(format) ? "" : formatIsSignedInt(format) ? "i" : "u") + r64;
934         string imgqualif = (m_data.formatQualifier) ? getShaderImageFormatQualifier(mapVkFormat(format)) + ", " : "";
935         string outputimgqualif = getShaderImageFormatQualifier(mapVkFormat(format));
936
937         string imageDim = "";
938         int numCoords, numNormalizedCoords;
939         bool layered = false;
940         switch (m_data.viewType)
941         {
942                 default: DE_ASSERT(0); // Fallthrough
943                 case VK_IMAGE_VIEW_TYPE_1D:                     imageDim = "1D";                numCoords = 1;  numNormalizedCoords = 1;        break;
944                 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:       imageDim = "1DArray";   numCoords = 2;  numNormalizedCoords = 1;        layered = true; break;
945                 case VK_IMAGE_VIEW_TYPE_2D:                     imageDim = "2D";                numCoords = 2;  numNormalizedCoords = 2;        break;
946                 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:       imageDim = "2DArray";   numCoords = 3;  numNormalizedCoords = 2;        layered = true; break;
947                 case VK_IMAGE_VIEW_TYPE_3D:                     imageDim = "3D";                numCoords = 3;  numNormalizedCoords = 3;        break;
948                 case VK_IMAGE_VIEW_TYPE_CUBE:           imageDim = "Cube";              numCoords = 3;  numNormalizedCoords = 3;        break;
949                 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:     imageDim = "CubeArray"; numCoords = 4;  numNormalizedCoords = 3;        layered = true; break;
950         }
951         if (m_data.samples > VK_SAMPLE_COUNT_1_BIT)
952         {
953                 switch (m_data.viewType)
954                 {
955                         default: DE_ASSERT(0); // Fallthrough
956                         case VK_IMAGE_VIEW_TYPE_2D:                     imageDim = "2DMS";              break;
957                         case VK_IMAGE_VIEW_TYPE_2D_ARRAY:       imageDim = "2DMSArray"; break;
958                 }
959                 numCoords++;
960         }
961         bool dataDependsOnLayer = (m_data.viewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY || m_data.viewType == VK_IMAGE_VIEW_TYPE_2D_ARRAY) && !m_data.nullDescriptor;
962
963         // Special case imageLoad(imageCubeArray, ...) which uses ivec3
964         if (m_data.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE &&
965                 m_data.viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
966         {
967                 numCoords = 3;
968         }
969
970         int numComponents = tcu::getPixelSize(mapVkFormat(format)) / tcu::getChannelSize(mapVkFormat(format).type);
971         string bufType;
972         if (numComponents == 1)
973                 bufType = string(formatIsFloat(format) ? "float" : formatIsSignedInt(format) ? "int" : "uint") + i64Type;
974         else
975                 bufType = imgprefix + "vec" + std::to_string(numComponents);
976
977         // For UBO's, which have a declared size in the shader, don't access outside that size.
978         bool declaredSize = false;
979         switch (m_data.descriptorType) {
980         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
981         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
982                 declaredSize = true;
983                 break;
984         default:
985                 break;
986         }
987
988         checks << "  int inboundcoords, clampedLayer;\n";
989         checks << "  " << vecType << " expectedIB2;\n";
990         if (m_data.unroll)
991         {
992                 if (declaredSize)
993                         checks << "  [[unroll]] for (int c = 0; c <= 10; ++c) {\n";
994                 else
995                         checks << "  [[unroll]] for (int c = -10; c <= 10; ++c) {\n";
996         }
997         else
998         {
999                 if (declaredSize)
1000                         checks << "  [[dont_unroll]] for (int c = 1023; c >= 0; --c) {\n";
1001                 else
1002                         checks << "  [[dont_unroll]] for (int c = 1050; c >= -1050; --c) {\n";
1003         }
1004
1005         if (m_data.descriptorType == VERTEX_ATTRIBUTE_FETCH)
1006                 checks << "    int idx = smod(gl_VertexIndex * " << numComponents << ", " << refDataNumElements << ");\n";
1007         else
1008                 checks << "    int idx = smod(c * " << numComponents << ", " << refDataNumElements << ");\n";
1009
1010         decls << "layout(" << outputimgqualif << ", set = 0, binding = 0) uniform " << imgprefix << "image2D image0_0;\n";
1011
1012         const char *vol = m_data.vol ? "volatile " : "";
1013         const char *ro = m_data.readOnly ? "readonly " : "";
1014
1015         // Construct the declaration for the binding
1016         switch (m_data.descriptorType)
1017         {
1018         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1019         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1020                 decls << "layout(scalar, set = 0, binding = 1) uniform ubodef0_1 { " << bufType << " val[1024]; } ubo0_1;\n";
1021                 break;
1022         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1023         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1024                 decls << "layout(scalar, set = 0, binding = 1) " << vol << ro << "buffer sbodef0_1 { " << bufType << " val[]; } ssbo0_1;\n";
1025                 decls << "layout(scalar, set = 0, binding = 1) " << vol << ro << "buffer sbodef0_1_pad { vec4 pad; " << bufType << " val[]; } ssbo0_1_pad;\n";
1026                 break;
1027         case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1028                 switch(format)
1029                 {
1030                 case VK_FORMAT_R64_SINT:
1031                         decls << "layout(set = 0, binding = 1) uniform itextureBuffer texbo0_1;\n";
1032                         break;
1033                 case VK_FORMAT_R64_UINT:
1034                         decls << "layout(set = 0, binding = 1) uniform utextureBuffer texbo0_1;\n";
1035                         break;
1036                 default:
1037                         decls << "layout(set = 0, binding = 1) uniform " << imgprefix << "textureBuffer texbo0_1;\n";
1038                 }
1039                 break;
1040         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1041                 decls << "layout(" << imgqualif << "set = 0, binding = 1) " << vol << "uniform " << imgprefix << "imageBuffer image0_1;\n";
1042                 break;
1043         case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1044                 decls << "layout(" << imgqualif << "set = 0, binding = 1) " << vol << "uniform " << imgprefix << "image" << imageDim << " image0_1;\n";
1045                 break;
1046         case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1047                 switch (format)
1048                 {
1049                 case VK_FORMAT_R64_SINT:
1050                         decls << "layout(set = 0, binding = 1) uniform isampler" << imageDim << " texture0_1; \n";
1051                         break;
1052                 case VK_FORMAT_R64_UINT:
1053                         decls << "layout(set = 0, binding = 1) uniform usampler" << imageDim << " texture0_1; \n";
1054                         break;
1055                 default:
1056                         decls << "layout(set = 0, binding = 1) uniform " << imgprefix << "sampler" << imageDim << " texture0_1;\n";
1057                         break;
1058                 }
1059                 break;
1060         case VERTEX_ATTRIBUTE_FETCH:
1061                 if (formatIsR64(format))
1062                 {
1063                         decls << "layout(location = 0) in " << (formatIsSignedInt(format) ? ("int64_t") : ("uint64_t")) << " attr;\n";
1064                 }
1065                 else
1066                 {
1067                         decls << "layout(location = 0) in " << vecType << " attr;\n";
1068                 }
1069                 break;
1070         default: DE_ASSERT(0);
1071         }
1072
1073         string expectedOOB;
1074         string defaultw;
1075
1076         switch (m_data.descriptorType)
1077         {
1078         default: DE_ASSERT(0); // Fallthrough
1079         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1080         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1081         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1082         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1083                 expectedOOB = "zzzz";
1084                 defaultw = "0";
1085                 break;
1086         case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1087         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1088         case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1089         case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1090         case VERTEX_ATTRIBUTE_FETCH:
1091                 if (numComponents == 1)
1092                 {
1093                         expectedOOB = "zzzo";
1094                 }
1095                 else if (numComponents == 2)
1096                 {
1097                         expectedOOB = "zzzo";
1098                 }
1099                 else
1100                 {
1101                         expectedOOB = "zzzz";
1102                 }
1103                 defaultw = "1";
1104                 break;
1105         }
1106
1107         string idx;
1108         switch (m_data.descriptorType)
1109         {
1110         default: DE_ASSERT(0); // Fallthrough
1111         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1112         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1113         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1114         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1115         case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1116         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1117         case VERTEX_ATTRIBUTE_FETCH:
1118                 idx = "idx";
1119                 break;
1120         case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1121         case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1122                 idx = "0";
1123                 break;
1124         }
1125
1126         if (m_data.nullDescriptor)
1127         {
1128                 checks << "    expectedIB = zzzz;\n";
1129                 checks << "    inboundcoords = 0;\n";
1130                 checks << "    int paddedinboundcoords = 0;\n";
1131                 // Vertex attribute fetch still gets format conversion applied
1132                 if (m_data.descriptorType != VERTEX_ATTRIBUTE_FETCH)
1133                         expectedOOB = "zzzz";
1134         }
1135         else
1136         {
1137                 checks << "    expectedIB.x = refData[" << idx << "];\n";
1138                 if (numComponents > 1)
1139                 {
1140                         checks << "    expectedIB.y = refData[" << idx << "+1];\n";
1141                 }
1142                 else
1143                 {
1144                         checks << "    expectedIB.y = 0;\n";
1145                 }
1146                 if (numComponents > 2)
1147                 {
1148                         checks << "    expectedIB.z = refData[" << idx << "+2];\n";
1149                         checks << "    expectedIB.w = refData[" << idx << "+3];\n";
1150                 }
1151                 else
1152                 {
1153                         checks << "    expectedIB.z = 0;\n";
1154                         checks << "    expectedIB.w = " << defaultw << ";\n";
1155                 }
1156
1157                 switch (m_data.descriptorType)
1158                 {
1159                 default: DE_ASSERT(0); // Fallthrough
1160                 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1161                 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1162                         // UBOs can either strictly bounds check against inboundcoords, or can
1163                         // return the contents from memory for the range padded up to paddedinboundcoords.
1164                         checks << "    int paddedinboundcoords = " << refDataNumElements / numComponents << ";\n";
1165                         // fallthrough
1166                 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1167                 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1168                 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1169                 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1170                 case VERTEX_ATTRIBUTE_FETCH:
1171                         checks << "    inboundcoords = " << layout.refData.size() / (formatIsR64(format) ? sizeof(deUint64) : sizeof(deUint32)) / numComponents << ";\n";
1172                         break;
1173                 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1174                 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1175                         // set per-component below
1176                         break;
1177                 }
1178         }
1179
1180         if ((m_data.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ||
1181                  m_data.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER ||
1182                  m_data.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
1183                  m_data.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) &&
1184                  !m_data.readOnly)
1185         {
1186                 for (int i = 0; i < numCoords; ++i)
1187                 {
1188                         // Treat i==3 coord (cube array layer) like i == 2
1189                         deUint32 coordDim = m_data.imageDim[i == 3 ? 2 : i];
1190                         if (!m_data.nullDescriptor && m_data.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1191                                 checks << "    inboundcoords = " << coordDim << ";\n";
1192
1193                         string coord = genCoord("c", numCoords, m_data.samples, i);
1194                         string inboundcoords =
1195                                 m_data.nullDescriptor ? "0" :
1196                                 (m_data.samples > VK_SAMPLE_COUNT_1_BIT && i == numCoords - 1) ? to_string(m_data.samples) : "inboundcoords";
1197
1198                         checks << "    if (c < 0 || c >= " << inboundcoords << ") " << genStore(m_data.descriptorType, vecType, bufType, coord) << ";\n";
1199                         if (m_data.formatQualifier &&
1200                                 (format == VK_FORMAT_R32_SINT || format == VK_FORMAT_R32_UINT))
1201                         {
1202                                 checks << "    if (c < 0 || c >= " << inboundcoords << ") " << genAtomic(m_data.descriptorType, bufType, coord) << ";\n";
1203                         }
1204                 }
1205         }
1206
1207         for (int i = 0; i < numCoords; ++i)
1208         {
1209                 // Treat i==3 coord (cube array layer) like i == 2
1210                 deUint32 coordDim = m_data.imageDim[i == 3 ? 2 : i];
1211                 if (!m_data.nullDescriptor)
1212                 {
1213                         switch (m_data.descriptorType)
1214                         {
1215                         default:
1216                                 break;
1217                         case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1218                         case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1219                                 checks << "    inboundcoords = " << coordDim << ";\n";
1220                                 break;
1221                         }
1222                 }
1223
1224                 string coord = genCoord("c", numCoords, m_data.samples, i);
1225
1226                 if (m_data.descriptorType == VERTEX_ATTRIBUTE_FETCH)
1227                 {
1228                         if (formatIsR64(format))
1229                         {
1230                                 checks << "    temp.x = attr;\n";
1231                                 checks << "    temp.y = 0l;\n";
1232                                 checks << "    temp.z = 0l;\n";
1233                                 checks << "    temp.w = 0l;\n";
1234                                 checks << "    if (gl_VertexIndex >= 0 && gl_VertexIndex < inboundcoords) temp.x -= expectedIB.x; else temp -= zzzz;\n";
1235                         }
1236                         else
1237                         {
1238                                 checks << "    temp = " << genFetch(m_data, numComponents, vecType, coord, "0") << ";\n";
1239                                 checks << "    if (gl_VertexIndex >= 0 && gl_VertexIndex < inboundcoords) temp -= expectedIB; else temp -= " << expectedOOB << ";\n";
1240                         }
1241                         // Accumulate any incorrect values.
1242                         checks << "    accum += abs(temp);\n";
1243                 }
1244                 // Skip texelFetch testing for cube(array) - texelFetch doesn't support it
1245                 if (m_data.descriptorType != VERTEX_ATTRIBUTE_FETCH &&
1246                         !(m_data.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER &&
1247                           (m_data.viewType == VK_IMAGE_VIEW_TYPE_CUBE || m_data.viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)))
1248                 {
1249                         checks << "    temp = " << genFetch(m_data, numComponents, vecType, coord, "0") << ";\n";
1250
1251                         checks << "    expectedIB2 = expectedIB;\n";
1252
1253                         // Expected data is a function of layer, for array images. Subtract out the layer value for in-bounds coordinates.
1254                         if (dataDependsOnLayer && i == numNormalizedCoords)
1255                                 checks << "    if (c >= 0 && c < inboundcoords) expectedIB2 += " << vecType << "(c, 0, 0, 0);\n";
1256
1257                         if (m_data.samples > VK_SAMPLE_COUNT_1_BIT && i == numCoords - 1)
1258                         {
1259                                 if (m_data.nullDescriptor && m_data.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1260                                 {
1261                                         checks << "    if (temp == zzzz) temp = " << vecType << "(0);\n";
1262                                         if (m_data.formatQualifier && numComponents < 4)
1263                                                 checks << "    else if (temp == zzzo) temp = " << vecType << "(0);\n";
1264                                         checks << "    else temp = " << vecType << "(1);\n";
1265                                 }
1266                                 else
1267                                         // multisample coord doesn't have defined behavior for OOB, so just set temp to 0.
1268                                         checks << "    if (c >= 0 && c < " << m_data.samples << ") temp -= expectedIB2; else temp = " << vecType << "(0);\n";
1269                         }
1270                         else
1271                         {
1272                                 // Storage buffers may be split into per-component loads. Generate a second
1273                                 // expected out of bounds value where some subset of the components are
1274                                 // actually in-bounds. If both loads and stores are split into per-component
1275                                 // accesses, then the result value can be a mix of storeValue and zero.
1276                                 string expectedOOB2 = expectedOOB;
1277                                 string expectedOOB3 = expectedOOB;
1278                                 if ((m_data.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
1279                                          m_data.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) &&
1280                                          !m_data.nullDescriptor)
1281                                 {
1282                                         int len = m_data.bufferLen & (formatIsR64(format) ? ~7 : ~3);
1283                                         int mod = (int)((len / (formatIsR64(format) ? sizeof(deUint64) : sizeof(deUint32))) % numComponents);
1284                                         string sstoreValue = de::toString(storeValue);
1285                                         switch (mod)
1286                                         {
1287                                         case 0:
1288                                                 break;
1289                                         case 1:
1290                                                 expectedOOB2 = vecType + "(expectedIB2.x, 0, 0, 0)";
1291                                                 expectedOOB3 = vecType + "(" + sstoreValue + ", 0, 0, 0)";
1292                                                 break;
1293                                         case 2:
1294                                                 expectedOOB2 = vecType + "(expectedIB2.xy, 0, 0)";
1295                                                 expectedOOB3 = vecType + "(" + sstoreValue + ", " + sstoreValue + ", 0, 0)";
1296                                                 break;
1297                                         case 3:
1298                                                 expectedOOB2 = vecType + "(expectedIB2.xyz, 0)";
1299                                                 expectedOOB3 = vecType + "(" + sstoreValue + ", " + sstoreValue + ", " + sstoreValue + ", 0)";
1300                                                 break;
1301                                         }
1302                                 }
1303
1304                                 // Entirely in-bounds.
1305                                 checks << "    if (c >= 0 && c < inboundcoords) {\n"
1306                                                   "       if (temp == expectedIB2) temp = " << vecType << "(0); else temp = " << vecType << "(1);\n"
1307                                                   "    }\n";
1308
1309                                 // normal out-of-bounds value
1310                                 if (m_data.testRobustness2)
1311                                         checks << "    else if (temp == " << expectedOOB << ") temp = " << vecType << "(0);\n";
1312                                 else
1313                                         // image_robustness relaxes alpha which is allowed to be zero or one
1314                                         checks << "    else if (temp == zzzz || temp == zzzo) temp = " << vecType << "(0);\n";
1315
1316                                 if (m_data.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
1317                                         m_data.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC)
1318                                 {
1319                                         checks << "    else if (c >= 0 && c < paddedinboundcoords && temp == expectedIB2) temp = " << vecType << "(0);\n";
1320                                 }
1321
1322                                 // null descriptor loads with image format layout qualifier that doesn't include alpha may return alpha=1
1323                                 if (m_data.nullDescriptor && m_data.formatQualifier &&
1324                                         (m_data.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE || m_data.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) &&
1325                                         numComponents < 4)
1326                                         checks << "    else if (temp == zzzo) temp = " << vecType << "(0);\n";
1327
1328                                 // non-volatile value replaced with stored value
1329                                 if (supportsStores(m_data.descriptorType) && !m_data.vol)
1330                                         checks << "    else if (temp == " << getStoreValue(m_data.descriptorType, numComponents, vecType, bufType) << ") temp = " << vecType << "(0);\n";
1331
1332                                 // value straddling the boundary, returning a partial vector
1333                                 if (expectedOOB2 != expectedOOB)
1334                                         checks << "    else if (c == inboundcoords && temp == " << expectedOOB2 << ") temp = " << vecType << "(0);\n";
1335                                 if (expectedOOB3 != expectedOOB)
1336                                         checks << "    else if (c == inboundcoords && temp == " << expectedOOB3 << ") temp = " << vecType << "(0);\n";
1337
1338                                 // failure
1339                                 checks << "    else temp = " << vecType << "(1);\n";
1340                         }
1341                         // Accumulate any incorrect values.
1342                         checks << "    accum += abs(temp);\n";
1343
1344                         // Only the full robustness2 extension provides guarantees about out-of-bounds mip levels.
1345                         if (m_data.testRobustness2 && m_data.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER && m_data.samples == VK_SAMPLE_COUNT_1_BIT)
1346                         {
1347                                 // Fetch from an out of bounds mip level. Expect this to always return the OOB value.
1348                                 string coord0 = genCoord("0", numCoords, m_data.samples, i);
1349                                 checks << "    if (c != 0) temp = " << genFetch(m_data, numComponents, vecType, coord0, "c") << "; else temp = " << vecType << "(0);\n";
1350                                 checks << "    if (c != 0) temp -= " << expectedOOB << ";\n";
1351                                 checks << "    accum += abs(temp);\n";
1352                         }
1353                 }
1354                 if (m_data.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER &&
1355                         m_data.samples == VK_SAMPLE_COUNT_1_BIT)
1356                 {
1357                         string coordNorm = genCoordNorm(m_data, "(c+0.25)", numCoords, numNormalizedCoords, i);
1358
1359                         checks << "    expectedIB2 = expectedIB;\n";
1360
1361                         // Data is a function of layer, for array images. Subtract out the layer value for in-bounds coordinates.
1362                         if (dataDependsOnLayer && i == numNormalizedCoords)
1363                         {
1364                                 checks << "    clampedLayer = clamp(c, 0, " << coordDim-1 << ");\n";
1365                                 checks << "    expectedIB2 += " << vecType << "(clampedLayer, 0, 0, 0);\n";
1366                         }
1367
1368                         stringstream normexpected;
1369                         // Cubemap fetches are always in-bounds. Layer coordinate is clamped, so is always in-bounds.
1370                         if (m_data.viewType == VK_IMAGE_VIEW_TYPE_CUBE ||
1371                                 m_data.viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY ||
1372                                 (layered && i == numCoords-1))
1373                                 normexpected << "    temp -= expectedIB2;\n";
1374                         else
1375                         {
1376                                 normexpected << "    if (c >= 0 && c < inboundcoords)\n";
1377                                 normexpected << "        temp -= expectedIB2;\n";
1378                                 normexpected << "    else\n";
1379                                 if (m_data.testRobustness2)
1380                                         normexpected << "        temp -= " << expectedOOB << ";\n";
1381                                 else
1382                                         // image_robustness relaxes alpha which is allowed to be zero or one
1383                                         normexpected << "        temp = " << vecType << "((temp == zzzz || temp == zzzo) ? 0 : 1);\n";
1384                         }
1385
1386                         checks << "    temp = texture(texture0_1, " << coordNorm << ");\n";
1387                         checks << normexpected.str();
1388                         checks << "    accum += abs(temp);\n";
1389                         checks << "    temp = textureLod(texture0_1, " << coordNorm << ", 0.0f);\n";
1390                         checks << normexpected.str();
1391                         checks << "    accum += abs(temp);\n";
1392                         checks << "    temp = textureGrad(texture0_1, " << coordNorm << ", " << genCoord("1.0", numNormalizedCoords, m_data.samples, i) << ", " << genCoord("1.0", numNormalizedCoords, m_data.samples, i) << ");\n";
1393                         checks << normexpected.str();
1394                         checks << "    accum += abs(temp);\n";
1395                 }
1396                 if (m_data.nullDescriptor)
1397                 {
1398                         const char *sizeswiz;
1399                         switch (m_data.viewType)
1400                         {
1401                                 default: DE_ASSERT(0); // Fallthrough
1402                                 case VK_IMAGE_VIEW_TYPE_1D:                     sizeswiz = ".xxxx";     break;
1403                                 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:       sizeswiz = ".xyxx";     break;
1404                                 case VK_IMAGE_VIEW_TYPE_2D:                     sizeswiz = ".xyxx";     break;
1405                                 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:       sizeswiz = ".xyzx";     break;
1406                                 case VK_IMAGE_VIEW_TYPE_3D:                     sizeswiz = ".xyzx";     break;
1407                                 case VK_IMAGE_VIEW_TYPE_CUBE:           sizeswiz = ".xyxx";     break;
1408                                 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:     sizeswiz = ".xyzx";     break;
1409                         }
1410                         if (m_data.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
1411                         {
1412                                 if (m_data.samples == VK_SAMPLE_COUNT_1_BIT)
1413                                 {
1414                                         checks << "    temp = textureSize(texture0_1, 0)" << sizeswiz <<";\n";
1415                                         checks << "    accum += abs(temp);\n";
1416
1417                                         // checking textureSize with clearly out of range LOD values
1418                                         checks << "    temp = textureSize(texture0_1, " << -i << ")" << sizeswiz <<";\n";
1419                                         checks << "    accum += abs(temp);\n";
1420                                         checks << "    temp = textureSize(texture0_1, " << (std::numeric_limits<deInt32>::max() - i) << ")" << sizeswiz <<";\n";
1421                                         checks << "    accum += abs(temp);\n";
1422                                 }
1423                                 else
1424                                 {
1425                                         checks << "    temp = textureSize(texture0_1)" << sizeswiz <<";\n";
1426                                         checks << "    accum += abs(temp);\n";
1427                                         checks << "    temp = textureSamples(texture0_1).xxxx;\n";
1428                                         checks << "    accum += abs(temp);\n";
1429                                 }
1430                         }
1431                         if (m_data.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1432                         {
1433                                 if (m_data.samples == VK_SAMPLE_COUNT_1_BIT)
1434                                 {
1435                                         checks << "    temp = imageSize(image0_1)" << sizeswiz <<";\n";
1436                                         checks << "    accum += abs(temp);\n";
1437                                 }
1438                                 else
1439                                 {
1440                                         checks << "    temp = imageSize(image0_1)" << sizeswiz <<";\n";
1441                                         checks << "    accum += abs(temp);\n";
1442                                         checks << "    temp = imageSamples(image0_1).xxxx;\n";
1443                                         checks << "    accum += abs(temp);\n";
1444                                 }
1445                         }
1446                         if (m_data.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
1447                                 m_data.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)
1448                         {
1449                                 // expect zero for runtime-sized array .length()
1450                                 checks << "    temp = " << vecType << "(ssbo0_1.val.length());\n";
1451                                 checks << "    accum += abs(temp);\n";
1452                                 checks << "    temp = " << vecType << "(ssbo0_1_pad.val.length());\n";
1453                                 checks << "    accum += abs(temp);\n";
1454                         }
1455                 }
1456         }
1457         checks << "  }\n";
1458
1459         // outside the coordinates loop because we only need to call it once
1460         if (m_data.nullDescriptor &&
1461                 m_data.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER &&
1462                 m_data.samples == VK_SAMPLE_COUNT_1_BIT)
1463         {
1464                 checks << "  temp_ql = " << qLevelType << "(textureQueryLevels(texture0_1));\n";
1465                 checks << "  temp = " << vecType << "(temp_ql);\n";
1466                 checks << "  accum += abs(temp);\n";
1467
1468                 if (m_data.stage == STAGE_FRAGMENT)
1469                 {
1470                         // as here we only want to check that textureQueryLod returns 0 when
1471                         // texture0_1 is null, we don't need to use the actual texture coordinates
1472                         // (and modify the vertex shader below to do so). Any coordinates are fine.
1473                         // gl_FragCoord has been selected "randomly", instead of selecting 0 for example.
1474                         std::string lod_str = (numNormalizedCoords == 1) ? ");" : (numNormalizedCoords == 2) ? "y);" : "yz);";
1475                         checks << "  vec2 lod = textureQueryLod(texture0_1, gl_FragCoord.x" << lod_str << "\n";
1476                         checks << "  temp_ql = " << qLevelType << "(ceil(abs(lod.x) + abs(lod.y)));\n";
1477                         checks << "  temp = " << vecType << "(temp_ql);\n";
1478                         checks << "  accum += abs(temp);\n";
1479                 }
1480         }
1481
1482
1483         const bool is64BitFormat = formatIsR64(m_data.format);
1484         std::string support =   "#version 460 core\n"
1485                                                         "#extension GL_EXT_nonuniform_qualifier : enable\n"
1486                                                         "#extension GL_EXT_scalar_block_layout : enable\n"
1487                                                         "#extension GL_EXT_samplerless_texture_functions : enable\n"
1488                                                         "#extension GL_EXT_control_flow_attributes : enable\n"
1489                                                         "#extension GL_EXT_shader_image_load_formatted : enable\n";
1490         std::string SupportR64 =        "#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require\n"
1491                                                                 "#extension GL_EXT_shader_image_int64 : require\n";
1492         if (is64BitFormat)
1493                 support += SupportR64;
1494         if (m_data.stage == STAGE_RAYGEN)
1495                 support += "#extension GL_NV_ray_tracing : require\n";
1496
1497         std::string code =      "  " + vecType + " accum = " + vecType + "(0);\n"
1498                                                 "  " + vecType + " temp;\n"
1499                                                 "  " + qLevelType + " temp_ql;\n" +
1500                                                 checks.str() +
1501                                                 "  " + vecType + " color = (accum != " + vecType + "(0)) ? " + vecType + "(0,0,0,0) : " + vecType + "(1,0,0,1);\n";
1502
1503         switch (m_data.stage)
1504         {
1505         default: DE_ASSERT(0); // Fallthrough
1506         case STAGE_COMPUTE:
1507                 {
1508                         std::stringstream css;
1509                         css << support
1510                                 << decls.str() <<
1511                                 "layout(local_size_x = 1, local_size_y = 1) in;\n"
1512                                 "void main()\n"
1513                                 "{\n"
1514                                 << code <<
1515                                 "  imageStore(image0_0, ivec2(gl_GlobalInvocationID.xy), color);\n"
1516                                 "}\n";
1517
1518                         programCollection.glslSources.add("test") << glu::ComputeSource(css.str())
1519                                 << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, is64BitFormat ? vk::SPIRV_VERSION_1_3 : vk::SPIRV_VERSION_1_0, vk::ShaderBuildOptions::FLAG_ALLOW_SCALAR_OFFSETS);
1520                         break;
1521                 }
1522         case STAGE_RAYGEN:
1523                 {
1524                         std::stringstream css;
1525                         css << support
1526                                 << decls.str() <<
1527                                 "void main()\n"
1528                                 "{\n"
1529                                 << code <<
1530                                 "  imageStore(image0_0, ivec2(gl_LaunchIDNV.xy), color);\n"
1531                                 "}\n";
1532
1533                         programCollection.glslSources.add("test") << glu::RaygenSource(css.str())
1534                                 << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_0, vk::ShaderBuildOptions::FLAG_ALLOW_SCALAR_OFFSETS);
1535                         break;
1536                 }
1537         case STAGE_VERTEX:
1538                 {
1539                         std::stringstream vss;
1540                         vss << support
1541                                 << decls.str() <<
1542                                 "void main()\n"
1543                                 "{\n"
1544                                 << code <<
1545                                 "  imageStore(image0_0, ivec2(gl_VertexIndex % " << DIM << ", gl_VertexIndex / " << DIM << "), color);\n"
1546                                 "  gl_PointSize = 1.0f;\n"
1547                                 "  gl_Position = vec4(0.0f, 0.0f, 0.0f, 1.0f);\n"
1548                                 "}\n";
1549
1550                         programCollection.glslSources.add("test") << glu::VertexSource(vss.str())
1551                                 << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_0, vk::ShaderBuildOptions::FLAG_ALLOW_SCALAR_OFFSETS);
1552                         break;
1553                 }
1554         case STAGE_FRAGMENT:
1555                 {
1556                         std::stringstream vss;
1557                         vss <<
1558                                 "#version 450 core\n"
1559                                 "void main()\n"
1560                                 "{\n"
1561                                 // full-viewport quad
1562                                 "  gl_Position = vec4( 2.0*float(gl_VertexIndex&2) - 1.0, 4.0*(gl_VertexIndex&1)-1.0, 1.0 - 2.0 * float(gl_VertexIndex&1), 1);\n"
1563                                 "}\n";
1564
1565                         programCollection.glslSources.add("vert") << glu::VertexSource(vss.str())
1566                                 << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_0, vk::ShaderBuildOptions::FLAG_ALLOW_SCALAR_OFFSETS);
1567
1568                         std::stringstream fss;
1569                         fss << support
1570                                 << decls.str() <<
1571                                 "void main()\n"
1572                                 "{\n"
1573                                 << code <<
1574                                 "  imageStore(image0_0, ivec2(gl_FragCoord.x, gl_FragCoord.y), color);\n"
1575                                 "}\n";
1576
1577                         programCollection.glslSources.add("test") << glu::FragmentSource(fss.str())
1578                                 << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_0, vk::ShaderBuildOptions::FLAG_ALLOW_SCALAR_OFFSETS);
1579                         break;
1580                 }
1581         }
1582
1583         // The 64-bit conditions below are redundant. Can we support the below shader for other than 64-bit formats?
1584         if ((m_data.samples > VK_SAMPLE_COUNT_1_BIT) && is64BitFormat)
1585         {
1586                 const std::string       ivecCords = (m_data.viewType == VK_IMAGE_VIEW_TYPE_2D ? "ivec2(gx, gy)" : "ivec3(gx, gy, gz)");
1587                 std::stringstream       fillShader;
1588
1589                 fillShader <<
1590                         "#version 450\n"
1591                         << SupportR64
1592                         << "\n"
1593                         "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1594                         "layout (" + getShaderImageFormatQualifier(mapVkFormat(m_data.format)) + ", binding=0) volatile uniform "
1595                         << string(formatIsSignedInt(m_data.format) ? "i" : "u") + string(is64BitFormat ? "64" : "") << "image" << imageDim << +" u_resultImage;\n"
1596                         "\n"
1597                         "layout(std430, binding = 1) buffer inputBuffer\n"
1598                         "{\n"
1599                         "  int" << (is64BitFormat ? "64_t" : "") << " data[];\n"
1600                         "} inBuffer;\n"
1601                         "\n"
1602                         "void main(void)\n"
1603                         "{\n"
1604                         "  int gx = int(gl_GlobalInvocationID.x);\n"
1605                         "  int gy = int(gl_GlobalInvocationID.y);\n"
1606                         "  int gz = int(gl_GlobalInvocationID.z);\n"
1607                         "  uint index = gx + (gy * gl_NumWorkGroups.x) + (gz *gl_NumWorkGroups.x * gl_NumWorkGroups.y);\n";
1608
1609                         for(int ndx = 0; ndx < static_cast<int>(m_data.samples); ++ndx)
1610                         {
1611                                 fillShader << "  imageStore(u_resultImage, " << ivecCords << ", " << ndx << ", i64vec4(inBuffer.data[index]));\n";
1612                         }
1613
1614                         fillShader << "}\n";
1615
1616                 programCollection.glslSources.add("fillShader") << glu::ComputeSource(fillShader.str())
1617                         << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, is64BitFormat ? vk::SPIRV_VERSION_1_3 : vk::SPIRV_VERSION_1_0, vk::ShaderBuildOptions::FLAG_ALLOW_SCALAR_OFFSETS);
1618         }
1619
1620 }
1621
1622 VkImageType imageViewTypeToImageType (VkImageViewType type)
1623 {
1624         switch (type)
1625         {
1626                 case VK_IMAGE_VIEW_TYPE_1D:
1627                 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:               return VK_IMAGE_TYPE_1D;
1628                 case VK_IMAGE_VIEW_TYPE_2D:
1629                 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
1630                 case VK_IMAGE_VIEW_TYPE_CUBE:
1631                 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:             return VK_IMAGE_TYPE_2D;
1632                 case VK_IMAGE_VIEW_TYPE_3D:                             return VK_IMAGE_TYPE_3D;
1633                 default:
1634                         DE_ASSERT(false);
1635         }
1636
1637         return VK_IMAGE_TYPE_2D;
1638 }
1639
1640 TestInstance* RobustnessExtsTestCase::createInstance (Context& context) const
1641 {
1642         return new RobustnessExtsTestInstance(context, m_data);
1643 }
1644
1645 tcu::TestStatus RobustnessExtsTestInstance::iterate (void)
1646 {
1647         const VkInstance                        instance                        = getInstance(m_context, m_data);
1648         const InstanceInterface&        vki                                     = getInstanceInterface(m_context, m_data);
1649         const VkDevice                          device                          = getLogicalDevice(m_context, m_data);
1650         const vk::DeviceInterface&      vk                                      = getDeviceInterface(m_context, m_data);
1651         const VkPhysicalDevice          physicalDevice          = chooseDevice(vki, instance, m_context.getTestContext().getCommandLine());
1652         SimpleAllocator                         allocator                       (vk, device, getPhysicalDeviceMemoryProperties(vki, physicalDevice));
1653
1654         Layout layout;
1655         generateLayout(layout, m_data);
1656
1657         // Get needed properties.
1658         VkPhysicalDeviceProperties2 properties;
1659         deMemset(&properties, 0, sizeof(properties));
1660         properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1661         void** pNextTail = &properties.pNext;
1662
1663 #ifndef CTS_USES_VULKANSC
1664         VkPhysicalDeviceRayTracingPropertiesNV rayTracingProperties;
1665         deMemset(&rayTracingProperties, 0, sizeof(rayTracingProperties));
1666         rayTracingProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PROPERTIES_NV;
1667 #endif
1668
1669         VkPhysicalDeviceRobustness2PropertiesEXT robustness2Properties;
1670         deMemset(&robustness2Properties, 0, sizeof(robustness2Properties));
1671         robustness2Properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_PROPERTIES_EXT;
1672
1673 #ifndef CTS_USES_VULKANSC
1674         if (m_context.isDeviceFunctionalitySupported("VK_NV_ray_tracing"))
1675         {
1676                 *pNextTail = &rayTracingProperties;
1677                 pNextTail = &rayTracingProperties.pNext;
1678         }
1679 #endif
1680
1681         if (m_context.isDeviceFunctionalitySupported("VK_EXT_robustness2"))
1682         {
1683                 *pNextTail = &robustness2Properties;
1684                 pNextTail = &robustness2Properties.pNext;
1685         }
1686
1687         vki.getPhysicalDeviceProperties2(physicalDevice, &properties);
1688
1689         if (m_data.testRobustness2)
1690         {
1691                 if (robustness2Properties.robustStorageBufferAccessSizeAlignment != 1 &&
1692                         robustness2Properties.robustStorageBufferAccessSizeAlignment != 4)
1693                         return tcu::TestStatus(QP_TEST_RESULT_FAIL, "robustStorageBufferAccessSizeAlignment must be 1 or 4");
1694
1695                 if (robustness2Properties.robustUniformBufferAccessSizeAlignment < 1 ||
1696                         robustness2Properties.robustUniformBufferAccessSizeAlignment > 256 ||
1697                         !deIntIsPow2((int)robustness2Properties.robustUniformBufferAccessSizeAlignment))
1698                         return tcu::TestStatus(QP_TEST_RESULT_FAIL, "robustUniformBufferAccessSizeAlignment must be a power of two in [1,256]");
1699         }
1700
1701         VkPipelineBindPoint bindPoint;
1702
1703         switch (m_data.stage)
1704         {
1705         case STAGE_COMPUTE:
1706                 bindPoint = VK_PIPELINE_BIND_POINT_COMPUTE;
1707                 break;
1708 #ifndef CTS_USES_VULKANSC
1709         case STAGE_RAYGEN:
1710                 bindPoint = VK_PIPELINE_BIND_POINT_RAY_TRACING_NV;
1711                 break;
1712 #endif
1713         default:
1714                 bindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
1715                 break;
1716         }
1717
1718         Move<vk::VkDescriptorSetLayout> descriptorSetLayout;
1719         Move<vk::VkDescriptorPool>              descriptorPool;
1720         Move<vk::VkDescriptorSet>               descriptorSet;
1721
1722         int formatBytes = tcu::getPixelSize(mapVkFormat(m_data.format));
1723         int numComponents = formatBytes / tcu::getChannelSize(mapVkFormat(m_data.format).type);
1724
1725         vector<VkDescriptorSetLayoutBinding> &bindings = layout.layoutBindings;
1726
1727         VkDescriptorPoolCreateFlags poolCreateFlags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
1728
1729 #ifndef CTS_USES_VULKANSC
1730         VkDescriptorSetLayoutCreateFlags layoutCreateFlags = m_data.pushDescriptor ? VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR : 0;
1731 #else
1732         VkDescriptorSetLayoutCreateFlags layoutCreateFlags = 0;
1733 #endif
1734
1735         // Create a layout and allocate a descriptor set for it.
1736
1737         const VkDescriptorSetLayoutCreateInfo setLayoutCreateInfo =
1738         {
1739                 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1740                 DE_NULL,
1741
1742                 layoutCreateFlags,
1743                 (deUint32)bindings.size(),
1744                 bindings.empty() ? DE_NULL : bindings.data()
1745         };
1746
1747         descriptorSetLayout = vk::createDescriptorSetLayout(vk, device, &setLayoutCreateInfo);
1748
1749         vk::DescriptorPoolBuilder poolBuilder;
1750         poolBuilder.addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1);
1751         poolBuilder.addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1);
1752         poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1);
1753         poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1);
1754         poolBuilder.addType(VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1);
1755         poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1);
1756         poolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1);
1757         poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 2);
1758
1759         descriptorPool = poolBuilder.build(vk, device, poolCreateFlags, 1u, DE_NULL);
1760
1761         const void *pNext = DE_NULL;
1762
1763         if (!m_data.pushDescriptor)
1764                 descriptorSet = makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout, pNext);
1765
1766         de::MovePtr<BufferWithMemory> buffer;
1767
1768         deUint8 *bufferPtr = DE_NULL;
1769         if (!m_data.nullDescriptor)
1770         {
1771                 // Create a buffer to hold data for all descriptors.
1772                 VkDeviceSize    size = de::max(
1773                         (VkDeviceSize)(m_data.bufferLen ? m_data.bufferLen : 1),
1774                         (VkDeviceSize)256);
1775
1776                 if (m_data.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
1777                         m_data.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC)
1778                 {
1779                         size = deIntRoundToPow2((int)size, (int)robustness2Properties.robustUniformBufferAccessSizeAlignment);
1780                 }
1781                 else if (m_data.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
1782                                  m_data.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)
1783                 {
1784                         size = deIntRoundToPow2((int)size, (int)robustness2Properties.robustStorageBufferAccessSizeAlignment);
1785                 }
1786                 else if (m_data.descriptorType == VERTEX_ATTRIBUTE_FETCH)
1787                 {
1788                         size = m_data.bufferLen;
1789                 }
1790
1791                 buffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
1792                         vk, device, allocator, makeBufferCreateInfo(size,
1793                                                                                                                 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
1794                                                                                                                 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT |
1795                                                                                                                 VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT |
1796                                                                                                                 VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT |
1797                                                                                                                 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
1798                                                                                                                 MemoryRequirement::HostVisible));
1799                 bufferPtr = (deUint8 *)buffer->getAllocation().getHostPtr();
1800
1801                 deMemset(bufferPtr, 0x3f, (size_t)size);
1802
1803                 deMemset(bufferPtr, 0, m_data.bufferLen);
1804                 if (m_data.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
1805                         m_data.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC)
1806                 {
1807                         deMemset(bufferPtr, 0, deIntRoundToPow2(m_data.bufferLen, (int)robustness2Properties.robustUniformBufferAccessSizeAlignment));
1808                 }
1809                 else if (m_data.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
1810                                  m_data.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)
1811                 {
1812                         deMemset(bufferPtr, 0, deIntRoundToPow2(m_data.bufferLen, (int)robustness2Properties.robustStorageBufferAccessSizeAlignment));
1813                 }
1814         }
1815
1816         const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1817
1818         Move<VkDescriptorSetLayout>             descriptorSetLayoutR64;
1819         Move<VkDescriptorPool>                  descriptorPoolR64;
1820         Move<VkDescriptorSet>                   descriptorSetFillImage;
1821         Move<VkShaderModule>                    shaderModuleFillImage;
1822         Move<VkPipelineLayout>                  pipelineLayoutFillImage;
1823         Move<VkPipeline>                                pipelineFillImage;
1824
1825         Move<VkCommandPool>                             cmdPool         = createCommandPool(vk, device, 0, queueFamilyIndex);
1826         Move<VkCommandBuffer>                   cmdBuffer       = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1827         VkQueue                                                 queue;
1828
1829         vk.getDeviceQueue(device, queueFamilyIndex, 0, &queue);
1830
1831         const VkImageSubresourceRange   barrierRange                            =
1832         {
1833                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
1834                 0u,                                                     // deUint32                             baseMipLevel;
1835                 VK_REMAINING_MIP_LEVELS,        // deUint32                             levelCount;
1836                 0u,                                                     // deUint32                             baseArrayLayer;
1837                 VK_REMAINING_ARRAY_LAYERS       // deUint32                             layerCount;
1838         };
1839
1840         VkImageMemoryBarrier                    preImageBarrier                         =
1841         {
1842                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                         // VkStructureType              sType
1843                 DE_NULL,                                                                                        // const void*                  pNext
1844                 0u,                                                                                                     // VkAccessFlags                srcAccessMask
1845                 VK_ACCESS_TRANSFER_WRITE_BIT,                                           // VkAccessFlags                dstAccessMask
1846                 VK_IMAGE_LAYOUT_UNDEFINED,                                                      // VkImageLayout                oldLayout
1847                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                           // VkImageLayout                newLayout
1848                 VK_QUEUE_FAMILY_IGNORED,                                                        // uint32_t                             srcQueueFamilyIndex
1849                 VK_QUEUE_FAMILY_IGNORED,                                                        // uint32_t                             dstQueueFamilyIndex
1850                 DE_NULL,                                                                                        // VkImage                              image
1851                 barrierRange,                                                                           // VkImageSubresourceRange      subresourceRange;
1852         };
1853
1854         VkImageMemoryBarrier                    postImageBarrier                        =
1855         {
1856                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
1857                 DE_NULL,                                                                        // const void*                          pNext;
1858                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
1859                 VK_ACCESS_SHADER_READ_BIT,                                      // VkAccessFlags                        dstAccessMask;
1860                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
1861                 VK_IMAGE_LAYOUT_GENERAL,                                        // VkImageLayout                        newLayout;
1862                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
1863                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
1864                 DE_NULL,                                                                        // VkImage                                      image;
1865                 barrierRange,                                                           // VkImageSubresourceRange      subresourceRange;
1866         };
1867
1868         vk::VkClearColorValue                   clearValue;
1869         clearValue.uint32[0] = 0u;
1870         clearValue.uint32[1] = 0u;
1871         clearValue.uint32[2] = 0u;
1872         clearValue.uint32[3] = 0u;
1873
1874         beginCommandBuffer(vk, *cmdBuffer, 0u);
1875
1876         typedef vk::Unique<vk::VkBufferView>            BufferViewHandleUp;
1877         typedef de::SharedPtr<BufferViewHandleUp>       BufferViewHandleSp;
1878         typedef de::SharedPtr<ImageWithMemory>          ImageWithMemorySp;
1879         typedef de::SharedPtr<Unique<VkImageView> >     VkImageViewSp;
1880         typedef de::MovePtr<BufferWithMemory>           BufferWithMemoryMp;
1881
1882         vector<BufferViewHandleSp>                                      bufferViews(1);
1883
1884         VkImageCreateFlags mutableFormatFlag = 0;
1885         // The 64-bit image tests use a view format which differs from the image.
1886         if (formatIsR64(m_data.format))
1887                 mutableFormatFlag = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
1888         VkImageCreateFlags imageCreateFlags = mutableFormatFlag;
1889         if (m_data.viewType == VK_IMAGE_VIEW_TYPE_CUBE || m_data.viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
1890                 imageCreateFlags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
1891
1892         const bool featureSampledImage = ((getPhysicalDeviceFormatProperties(vki,
1893                                                                                 physicalDevice,
1894                                                                                 m_data.format).optimalTilingFeatures &
1895                                                                                 VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) == VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT);
1896
1897         const VkImageUsageFlags usageSampledImage = (featureSampledImage ? VK_IMAGE_USAGE_SAMPLED_BIT : (VkImageUsageFlagBits)0);
1898
1899         const VkImageCreateInfo                 outputImageCreateInfo                   =
1900         {
1901                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType                      sType;
1902                 DE_NULL,                                                                // const void*                          pNext;
1903                 mutableFormatFlag,                                              // VkImageCreateFlags           flags;
1904                 VK_IMAGE_TYPE_2D,                                               // VkImageType                          imageType;
1905                 m_data.format,                                                  // VkFormat                                     format;
1906                 {
1907                         DIM,                                                            // deUint32     width;
1908                         DIM,                                                            // deUint32     height;
1909                         1u                                                                      // deUint32     depth;
1910                 },                                                                              // VkExtent3D                           extent;
1911                 1u,                                                                             // deUint32                                     mipLevels;
1912                 1u,                                                                             // deUint32                                     arrayLayers;
1913                 VK_SAMPLE_COUNT_1_BIT,                                  // VkSampleCountFlagBits        samples;
1914                 VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                        tiling;
1915                 VK_IMAGE_USAGE_STORAGE_BIT
1916                 | usageSampledImage
1917                 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
1918                 | VK_IMAGE_USAGE_TRANSFER_DST_BIT,              // VkImageUsageFlags            usage;
1919                 VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                        sharingMode;
1920                 0u,                                                                             // deUint32                                     queueFamilyIndexCount;
1921                 DE_NULL,                                                                // const deUint32*                      pQueueFamilyIndices;
1922                 VK_IMAGE_LAYOUT_UNDEFINED                               // VkImageLayout                        initialLayout;
1923         };
1924
1925         deUint32 width = m_data.imageDim[0];
1926         deUint32 height = m_data.viewType != VK_IMAGE_VIEW_TYPE_1D && m_data.viewType != VK_IMAGE_VIEW_TYPE_1D_ARRAY ? m_data.imageDim[1] : 1;
1927         deUint32 depth = m_data.viewType == VK_IMAGE_VIEW_TYPE_3D ? m_data.imageDim[2] : 1;
1928         deUint32 layers = m_data.viewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY ? m_data.imageDim[1] :
1929                                                 m_data.viewType != VK_IMAGE_VIEW_TYPE_1D &&
1930                                                 m_data.viewType != VK_IMAGE_VIEW_TYPE_2D &&
1931                                                 m_data.viewType != VK_IMAGE_VIEW_TYPE_3D ? m_data.imageDim[2] : 1;
1932
1933         const VkImageUsageFlags usageImage = (m_data.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ? VK_IMAGE_USAGE_STORAGE_BIT : (VkImageUsageFlagBits)0);
1934
1935         const VkImageCreateInfo                 imageCreateInfo                 =
1936         {
1937                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType                      sType;
1938                 DE_NULL,                                                                // const void*                          pNext;
1939                 imageCreateFlags,                                               // VkImageCreateFlags           flags;
1940                 imageViewTypeToImageType(m_data.viewType),      // VkImageType                          imageType;
1941                 m_data.format,                                                  // VkFormat                                     format;
1942                 {
1943                         width,                                                          // deUint32     width;
1944                         height,                                                         // deUint32     height;
1945                         depth                                                           // deUint32     depth;
1946                 },                                                                              // VkExtent3D                           extent;
1947                 1u,                                                                             // deUint32                                     mipLevels;
1948                 layers,                                                                 // deUint32                                     arrayLayers;
1949                 m_data.samples,                                                 // VkSampleCountFlagBits        samples;
1950                 VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                        tiling;
1951                 usageImage
1952                 | usageSampledImage
1953                 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
1954                 | VK_IMAGE_USAGE_TRANSFER_DST_BIT,              // VkImageUsageFlags            usage;
1955                 VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                        sharingMode;
1956                 0u,                                                                             // deUint32                                     queueFamilyIndexCount;
1957                 DE_NULL,                                                                // const deUint32*                      pQueueFamilyIndices;
1958                 VK_IMAGE_LAYOUT_UNDEFINED                               // VkImageLayout                        initialLayout;
1959         };
1960
1961         VkImageViewCreateInfo           imageViewCreateInfo             =
1962         {
1963                 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,       // VkStructureType                      sType;
1964                 DE_NULL,                                                                        // const void*                          pNext;
1965                 (VkImageViewCreateFlags)0u,                                     // VkImageViewCreateFlags       flags;
1966                 DE_NULL,                                                                        // VkImage                                      image;
1967                 VK_IMAGE_VIEW_TYPE_2D,                                          // VkImageViewType                      viewType;
1968                 m_data.format,                                                          // VkFormat                                     format;
1969                 {
1970                         VK_COMPONENT_SWIZZLE_IDENTITY,
1971                         VK_COMPONENT_SWIZZLE_IDENTITY,
1972                         VK_COMPONENT_SWIZZLE_IDENTITY,
1973                         VK_COMPONENT_SWIZZLE_IDENTITY
1974                 },                                                                                      // VkComponentMapping            components;
1975                 {
1976                         VK_IMAGE_ASPECT_COLOR_BIT,                              // VkImageAspectFlags   aspectMask;
1977                         0u,                                                                             // deUint32                             baseMipLevel;
1978                         VK_REMAINING_MIP_LEVELS,                                // deUint32                             levelCount;
1979                         0u,                                                                             // deUint32                             baseArrayLayer;
1980                         VK_REMAINING_ARRAY_LAYERS                               // deUint32                             layerCount;
1981                 }                                                                                       // VkImageSubresourceRange      subresourceRange;
1982         };
1983
1984         vector<ImageWithMemorySp> images(2);
1985         vector<VkImageViewSp> imageViews(2);
1986
1987         if (m_data.descriptorType == VERTEX_ATTRIBUTE_FETCH)
1988         {
1989                 deUint32 *ptr = (deUint32 *)bufferPtr;
1990                 deMemcpy(ptr, layout.refData.data(), layout.refData.size());
1991         }
1992
1993         BufferWithMemoryMp                              bufferImageR64;
1994         BufferWithMemoryMp                              bufferOutputImageR64;
1995         const VkDeviceSize                              sizeOutputR64   = 8 * outputImageCreateInfo.extent.width * outputImageCreateInfo.extent.height * outputImageCreateInfo.extent.depth;
1996         const VkDeviceSize                              sizeOneLayers   = 8 * imageCreateInfo.extent.width * imageCreateInfo.extent.height * imageCreateInfo.extent.depth;
1997         const VkDeviceSize                              sizeImageR64    = sizeOneLayers * layers;
1998
1999         if (formatIsR64(m_data.format))
2000         {
2001                 bufferOutputImageR64 = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
2002                         vk, device, allocator,
2003                         makeBufferCreateInfo(sizeOutputR64, VK_BUFFER_USAGE_TRANSFER_SRC_BIT),
2004                         MemoryRequirement::HostVisible));
2005
2006                 deUint64* bufferUint64Ptr = (deUint64 *)bufferOutputImageR64->getAllocation().getHostPtr();
2007
2008                 for (int ndx = 0; ndx < static_cast<int>(sizeOutputR64 / 8); ++ndx)
2009                 {
2010                         bufferUint64Ptr[ndx] = 0;
2011                 }
2012                 flushAlloc(vk, device, bufferOutputImageR64->getAllocation());
2013
2014                 bufferImageR64 = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
2015                         vk, device, allocator,
2016                         makeBufferCreateInfo(sizeImageR64, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
2017                         MemoryRequirement::HostVisible));
2018
2019                 for (deUint32 layerNdx = 0; layerNdx < layers; ++layerNdx)
2020                 {
2021                         bufferUint64Ptr = (deUint64 *)bufferImageR64->getAllocation().getHostPtr();
2022                         bufferUint64Ptr = bufferUint64Ptr + ((sizeOneLayers * layerNdx) / 8);
2023
2024                         for (int ndx = 0; ndx < static_cast<int>(sizeOneLayers / 8); ++ndx)
2025                         {
2026                                 bufferUint64Ptr[ndx] = 0x1234567887654321 + ((m_data.viewType != VK_IMAGE_VIEW_TYPE_CUBE && m_data.viewType != VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? layerNdx : 0);
2027                         }
2028                 }
2029                 flushAlloc(vk, device, bufferImageR64->getAllocation());
2030         }
2031
2032         for (size_t b = 0; b < bindings.size(); ++b)
2033         {
2034                 VkDescriptorSetLayoutBinding &binding = bindings[b];
2035
2036                 if (binding.descriptorCount == 0)
2037                         continue;
2038                 if (b == 1 && m_data.nullDescriptor)
2039                         continue;
2040
2041                 DE_ASSERT(binding.descriptorCount == 1);
2042                 switch (binding.descriptorType)
2043                 {
2044                 default: DE_ASSERT(0); // Fallthrough
2045                 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
2046                 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
2047                 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2048                 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
2049                         {
2050                                 deUint32 *ptr = (deUint32 *)bufferPtr;
2051                                 deMemcpy(ptr, layout.refData.data(), layout.refData.size());
2052                         }
2053                         break;
2054                 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
2055                 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
2056                         {
2057                                 deUint32 *ptr = (deUint32 *)bufferPtr;
2058                                 deMemcpy(ptr, layout.refData.data(), layout.refData.size());
2059
2060                                 const vk::VkBufferViewCreateInfo viewCreateInfo =
2061                                 {
2062                                         vk::VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
2063                                         DE_NULL,
2064                                         (vk::VkBufferViewCreateFlags)0,
2065                                         **buffer,                                                               // buffer
2066                                         m_data.format,                                                  // format
2067                                         (vk::VkDeviceSize)0,                                    // offset
2068                                         (vk::VkDeviceSize)m_data.bufferLen              // range
2069                                 };
2070                                 vk::Move<vk::VkBufferView> bufferView = vk::createBufferView(vk, device, &viewCreateInfo);
2071                                 bufferViews[0] = BufferViewHandleSp(new BufferViewHandleUp(bufferView));
2072                         }
2073                         break;
2074                 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
2075                 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
2076                         {
2077                                 if (bindings.size() > 1 &&
2078                                         bindings[1].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
2079                                 {
2080                                         if (m_data.format == VK_FORMAT_R64_SINT)
2081                                                 imageViewCreateInfo.format = VK_FORMAT_R32G32_SINT;
2082
2083                                         if (m_data.format == VK_FORMAT_R64_UINT)
2084                                                 imageViewCreateInfo.format = VK_FORMAT_R32G32_UINT;
2085                                 }
2086
2087                                 if (b == 0)
2088                                 {
2089                                         images[b] = ImageWithMemorySp(new ImageWithMemory(vk, device, allocator, outputImageCreateInfo, MemoryRequirement::Any));
2090                                         imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
2091                                 }
2092                                 else
2093                                 {
2094                                         images[b] = ImageWithMemorySp(new ImageWithMemory(vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
2095                                         imageViewCreateInfo.viewType = m_data.viewType;
2096                                 }
2097                                 imageViewCreateInfo.image = **images[b];
2098                                 imageViews[b] = VkImageViewSp(new Unique<VkImageView>(createImageView(vk, device, &imageViewCreateInfo, NULL)));
2099
2100                                 VkImage                                         img                     = **images[b];
2101                                 const VkBuffer&                         bufferR64= ((b == 0) ? *(*bufferOutputImageR64) : *(*(bufferImageR64)));
2102                                 const VkImageCreateInfo&        imageInfo       = ((b == 0) ? outputImageCreateInfo : imageCreateInfo);
2103                                 const deUint32                          clearLayers     = b == 0 ? 1 : layers;
2104
2105                                 if (!formatIsR64(m_data.format))
2106                                 {
2107                                         preImageBarrier.image   = img;
2108                                         if (b == 1)
2109                                         {
2110                                                 if (formatIsFloat(m_data.format))
2111                                                 {
2112                                                         deMemcpy(&clearValue.float32[0], layout.refData.data(), layout.refData.size());
2113                                                 }
2114                                                 else if (formatIsSignedInt(m_data.format))
2115                                                 {
2116                                                         deMemcpy(&clearValue.int32[0], layout.refData.data(), layout.refData.size());
2117                                                 }
2118                                                 else
2119                                                 {
2120                                                         deMemcpy(&clearValue.uint32[0], layout.refData.data(), layout.refData.size());
2121                                                 }
2122                                         }
2123                                         postImageBarrier.image  = img;
2124
2125                                         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &preImageBarrier);
2126
2127                                         for (unsigned int i = 0; i < clearLayers; ++i)
2128                                         {
2129                                                 const VkImageSubresourceRange   clearRange                              =
2130                                                 {
2131                                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
2132                                                         0u,                                                     // deUint32                             baseMipLevel;
2133                                                         VK_REMAINING_MIP_LEVELS,        // deUint32                             levelCount;
2134                                                         i,                                                      // deUint32                             baseArrayLayer;
2135                                                         1                                                       // deUint32                             layerCount;
2136                                                 };
2137
2138                                                 vk.cmdClearColorImage(*cmdBuffer, img, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue, 1, &clearRange);
2139
2140                                                 // Use same data for all faces for cube(array), otherwise make value a function of the layer
2141                                                 if (m_data.viewType != VK_IMAGE_VIEW_TYPE_CUBE && m_data.viewType != VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
2142                                                 {
2143                                                         if (formatIsFloat(m_data.format))
2144                                                                 clearValue.float32[0] += 1;
2145                                                         else if (formatIsSignedInt(m_data.format))
2146                                                                 clearValue.int32[0] += 1;
2147                                                         else
2148                                                                 clearValue.uint32[0] += 1;
2149                                                 }
2150                                         }
2151                                         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
2152                                 }
2153                                 else
2154                                 {
2155                                         if ((m_data.samples > VK_SAMPLE_COUNT_1_BIT) && (b == 1))
2156                                         {
2157                                                 const VkImageSubresourceRange   subresourceRange        = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, clearLayers);
2158                                                 const VkImageMemoryBarrier              imageBarrierPre         = makeImageMemoryBarrier(0,
2159                                                                                                                                                                 VK_ACCESS_SHADER_WRITE_BIT,
2160                                                                                                                                                                 VK_IMAGE_LAYOUT_UNDEFINED,
2161                                                                                                                                                                 VK_IMAGE_LAYOUT_GENERAL,
2162                                                                                                                                                                 img,
2163                                                                                                                                                                 subresourceRange);
2164                                                 const VkImageMemoryBarrier              imageBarrierPost        = makeImageMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT,
2165                                                                                                                                                                 VK_ACCESS_SHADER_READ_BIT,
2166                                                                                                                                                                 VK_IMAGE_LAYOUT_GENERAL,
2167                                                                                                                                                                 VK_IMAGE_LAYOUT_GENERAL,
2168                                                                                                                                                                 img,
2169                                                                                                                                                                 subresourceRange);
2170
2171                                                 descriptorSetLayoutR64 =
2172                                                         DescriptorSetLayoutBuilder()
2173                                                         .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
2174                                                         .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
2175                                                         .build(vk, device);
2176
2177                                                 descriptorPoolR64 =
2178                                                         DescriptorPoolBuilder()
2179                                                         .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1)
2180                                                         .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,1)
2181                                                         .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 2u);
2182
2183                                                 descriptorSetFillImage = makeDescriptorSet(vk,
2184                                                         device,
2185                                                         *descriptorPoolR64,
2186                                                         *descriptorSetLayoutR64);
2187
2188                                                 shaderModuleFillImage   = createShaderModule(vk, device, m_context.getBinaryCollection().get("fillShader"), 0);
2189                                                 pipelineLayoutFillImage = makePipelineLayout(vk, device, *descriptorSetLayoutR64);
2190                                                 pipelineFillImage               = makeComputePipeline(vk, device, *pipelineLayoutFillImage, *shaderModuleFillImage);
2191
2192                                                 const VkDescriptorImageInfo             descResultImageInfo             = makeDescriptorImageInfo(DE_NULL, **imageViews[b], VK_IMAGE_LAYOUT_GENERAL);
2193                                                 const VkDescriptorBufferInfo    descResultBufferInfo    = makeDescriptorBufferInfo(bufferR64, 0, sizeImageR64);
2194
2195                                                 DescriptorSetUpdateBuilder()
2196                                                         .writeSingle(*descriptorSetFillImage, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descResultImageInfo)
2197                                                         .writeSingle(*descriptorSetFillImage, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descResultBufferInfo)
2198                                                         .update(vk, device);
2199
2200                                                 vk.cmdPipelineBarrier(*cmdBuffer,
2201                                                         VK_PIPELINE_STAGE_HOST_BIT,
2202                                                         VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
2203                                                         (VkDependencyFlags)0,
2204                                                         0, (const VkMemoryBarrier*)DE_NULL,
2205                                                         0, (const VkBufferMemoryBarrier*)DE_NULL,
2206                                                         1, &imageBarrierPre);
2207
2208                                                 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineFillImage);
2209                                                 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayoutFillImage, 0u, 1u, &(*descriptorSetFillImage), 0u, DE_NULL);
2210
2211                                                 vk.cmdDispatch(*cmdBuffer, imageInfo.extent.width, imageInfo.extent.height, clearLayers);
2212
2213                                                 vk.cmdPipelineBarrier(*cmdBuffer,
2214                                                                         VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
2215                                                                         VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
2216                                                                         (VkDependencyFlags)0,
2217                                                                         0, (const VkMemoryBarrier*)DE_NULL,
2218                                                                         0, (const VkBufferMemoryBarrier*)DE_NULL,
2219                                                                         1, &imageBarrierPost);
2220                                         }
2221                                         else
2222                                         {
2223                                                 VkDeviceSize                                    size                    = ((b == 0) ? sizeOutputR64 : sizeImageR64);
2224                                                 const vector<VkBufferImageCopy> bufferImageCopy (1, makeBufferImageCopy(imageInfo.extent, makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, clearLayers)));
2225
2226                                                 copyBufferToImage(vk,
2227                                                         *cmdBuffer,
2228                                                         bufferR64,
2229                                                         size,
2230                                                         bufferImageCopy,
2231                                                         VK_IMAGE_ASPECT_COLOR_BIT,
2232                                                         1,
2233                                                         clearLayers, img, VK_IMAGE_LAYOUT_GENERAL, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT);
2234                                         }
2235                                 }
2236                         }
2237                         break;
2238                 }
2239         }
2240
2241         const VkSamplerCreateInfo       samplerParams   =
2242         {
2243                 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,          // VkStructureType                      sType;
2244                 DE_NULL,                                                                        // const void*                          pNext;
2245                 0,                                                                                      // VkSamplerCreateFlags         flags;
2246                 VK_FILTER_NEAREST,                                                      // VkFilter                                     magFilter:
2247                 VK_FILTER_NEAREST,                                                      // VkFilter                                     minFilter;
2248                 VK_SAMPLER_MIPMAP_MODE_NEAREST,                         // VkSamplerMipmapMode          mipmapMode;
2249                 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,        // VkSamplerAddressMode         addressModeU;
2250                 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,        // VkSamplerAddressMode         addressModeV;
2251                 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,        // VkSamplerAddressMode         addressModeW;
2252                 0.0f,                                                                           // float                                        mipLodBias;
2253                 VK_FALSE,                                                                       // VkBool32                                     anistoropyEnable;
2254                 1.0f,                                                                           // float                                        maxAnisotropy;
2255                 VK_FALSE,                                                                       // VkBool32                                     compareEnable;
2256                 VK_COMPARE_OP_ALWAYS,                                           // VkCompareOp                          compareOp;
2257                 0.0f,                                                                           // float                                        minLod;
2258                 0.0f,                                                                           // float                                        maxLod;
2259                 formatIsFloat(m_data.format) ?
2260                         VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK :
2261                         VK_BORDER_COLOR_INT_TRANSPARENT_BLACK,  // VkBorderColor                        borderColor;
2262                 VK_FALSE                                                                        // VkBool32                                     unnormalizedCoordinates;
2263         };
2264
2265         Move<VkSampler>                         sampler                 (createSampler(vk, device, &samplerParams));
2266
2267         // Flush modified memory.
2268         if (!m_data.nullDescriptor)
2269                 flushAlloc(vk, device, buffer->getAllocation());
2270
2271         const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
2272         {
2273                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,                          // sType
2274                 DE_NULL,                                                                                                        // pNext
2275                 (VkPipelineLayoutCreateFlags)0,
2276                 1u,                                                                                                                     // setLayoutCount
2277                 &descriptorSetLayout.get(),                                                                     // pSetLayouts
2278                 0u,                                                                                                                     // pushConstantRangeCount
2279                 DE_NULL,                                                                                                        // pPushConstantRanges
2280         };
2281
2282         Move<VkPipelineLayout> pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo, NULL);
2283
2284         de::MovePtr<BufferWithMemory> copyBuffer;
2285         copyBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
2286                 vk, device, allocator, makeBufferCreateInfo(DIM*DIM*16, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible));
2287
2288         {
2289                 vector<VkDescriptorBufferInfo> bufferInfoVec(2);
2290                 vector<VkDescriptorImageInfo> imageInfoVec(2);
2291                 vector<VkBufferView> bufferViewVec(2);
2292                 vector<VkWriteDescriptorSet> writesBeforeBindVec(0);
2293                 int vecIndex = 0;
2294                 int numDynamic = 0;
2295
2296 #ifndef CTS_USES_VULKANSC
2297                 vector<VkDescriptorUpdateTemplateEntry> imgTemplateEntriesBefore,
2298                                                                                                 bufTemplateEntriesBefore,
2299                                                                                                 texelBufTemplateEntriesBefore;
2300 #endif
2301
2302                 for (size_t b = 0; b < bindings.size(); ++b)
2303                 {
2304                         VkDescriptorSetLayoutBinding &binding = bindings[b];
2305                         // Construct the declaration for the binding
2306                         if (binding.descriptorCount > 0)
2307                         {
2308                                 // output image
2309                                 switch (binding.descriptorType)
2310                                 {
2311                                 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
2312                                 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
2313                                         // Output image.
2314                                         if (b == 1 && m_data.nullDescriptor)
2315                                                 imageInfoVec[vecIndex] = makeDescriptorImageInfo(*sampler, DE_NULL, VK_IMAGE_LAYOUT_GENERAL);
2316                                         else
2317                                                 imageInfoVec[vecIndex] = makeDescriptorImageInfo(*sampler, **imageViews[b], VK_IMAGE_LAYOUT_GENERAL);
2318                                         break;
2319                                 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
2320                                 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
2321                                         if (b == 1 && m_data.nullDescriptor)
2322                                                 bufferViewVec[vecIndex] = DE_NULL;
2323                                         else
2324                                                 bufferViewVec[vecIndex] = **bufferViews[0];
2325                                         break;
2326                                 default:
2327                                         // Other descriptor types.
2328                                         if (b == 1 && m_data.nullDescriptor)
2329                                                 bufferInfoVec[vecIndex] = makeDescriptorBufferInfo(DE_NULL, 0, VK_WHOLE_SIZE);
2330                                         else
2331                                                 bufferInfoVec[vecIndex] = makeDescriptorBufferInfo(**buffer, 0, layout.refData.size());
2332                                         break;
2333                                 }
2334
2335                                 VkWriteDescriptorSet w =
2336                                 {
2337                                         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,                         // sType
2338                                         DE_NULL,                                                                                        // pNext
2339                                         m_data.pushDescriptor ? DE_NULL : *descriptorSet,       // dstSet
2340                                         (deUint32)b,                                                                            // binding
2341                                         0,                                                                                                      // dstArrayElement
2342                                         1u,                                                                                                     // descriptorCount
2343                                         binding.descriptorType,                                                         // descriptorType
2344                                         &imageInfoVec[vecIndex],                                                        // pImageInfo
2345                                         &bufferInfoVec[vecIndex],                                                       // pBufferInfo
2346                                         &bufferViewVec[vecIndex],                                                       // pTexelBufferView
2347                                 };
2348
2349 #ifndef CTS_USES_VULKANSC
2350                                 VkDescriptorUpdateTemplateEntry templateEntry =
2351                                 {
2352                                         (deUint32)b,                            // uint32_t                             dstBinding;
2353                                         0,                                                      // uint32_t                             dstArrayElement;
2354                                         1u,                                                     // uint32_t                             descriptorCount;
2355                                         binding.descriptorType,         // VkDescriptorType             descriptorType;
2356                                         0,                                                      // size_t                               offset;
2357                                         0,                                                      // size_t                               stride;
2358                                 };
2359
2360                                 switch (binding.descriptorType)
2361                                 {
2362                                 default: DE_ASSERT(0); // Fallthrough
2363                                 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
2364                                 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
2365                                         templateEntry.offset = vecIndex * sizeof(VkDescriptorImageInfo);
2366                                         imgTemplateEntriesBefore.push_back(templateEntry);
2367                                         break;
2368                                 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
2369                                 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
2370                                         templateEntry.offset = vecIndex * sizeof(VkBufferView);
2371                                         texelBufTemplateEntriesBefore.push_back(templateEntry);
2372                                         break;
2373                                 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
2374                                 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
2375                                 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2376                                 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
2377                                         templateEntry.offset = vecIndex * sizeof(VkDescriptorBufferInfo);
2378                                         bufTemplateEntriesBefore.push_back(templateEntry);
2379                                         break;
2380                                 }
2381 #endif
2382
2383                                 vecIndex++;
2384
2385                                 writesBeforeBindVec.push_back(w);
2386
2387                                 // Count the number of dynamic descriptors in this set.
2388                                 if (binding.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
2389                                         binding.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)
2390                                 {
2391                                         numDynamic++;
2392                                 }
2393                         }
2394                 }
2395
2396                 // Make zeros have at least one element so &zeros[0] works
2397                 vector<deUint32> zeros(de::max(1,numDynamic));
2398                 deMemset(&zeros[0], 0, numDynamic * sizeof(deUint32));
2399
2400                 // Randomly select between vkUpdateDescriptorSets and vkUpdateDescriptorSetWithTemplate
2401                 if (m_data.useTemplate)
2402                 {
2403 #ifndef CTS_USES_VULKANSC
2404                         VkDescriptorUpdateTemplateCreateInfo templateCreateInfo =
2405                         {
2406                                 VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO,       // VkStructureType                                                      sType;
2407                                 NULL,                                                                                                           // void*                                                                        pNext;
2408                                 0,                                                                                                                      // VkDescriptorUpdateTemplateCreateFlags        flags;
2409                                 0,                                                                                                                      // uint32_t                                                                     descriptorUpdateEntryCount;
2410                                 DE_NULL,                                                                                                        // uint32_t                                                                     descriptorUpdateEntryCount;
2411                                 m_data.pushDescriptor ?
2412                                         VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR :
2413                                         VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET,              // VkDescriptorUpdateTemplateType                       templateType;
2414                                 descriptorSetLayout.get(),                                                                      // VkDescriptorSetLayout                                        descriptorSetLayout;
2415                                 bindPoint,                                                                                                      // VkPipelineBindPoint                                          pipelineBindPoint;
2416                                 *pipelineLayout,                                                                                        // VkPipelineLayout                                                     pipelineLayout;
2417                                 0,                                                                                                                      // uint32_t                                                                     set;
2418                         };
2419
2420                         void *templateVectorData[] =
2421                         {
2422                                 imageInfoVec.data(),
2423                                 bufferInfoVec.data(),
2424                                 bufferViewVec.data(),
2425                         };
2426
2427                         vector<VkDescriptorUpdateTemplateEntry> *templateVectorsBefore[] =
2428                         {
2429                                 &imgTemplateEntriesBefore,
2430                                 &bufTemplateEntriesBefore,
2431                                 &texelBufTemplateEntriesBefore,
2432                         };
2433
2434                         if (m_data.pushDescriptor)
2435                         {
2436                                 for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(templateVectorsBefore); ++i)
2437                                 {
2438                                         if (templateVectorsBefore[i]->size())
2439                                         {
2440                                                 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)templateVectorsBefore[i]->size();
2441                                                 templateCreateInfo.pDescriptorUpdateEntries = templateVectorsBefore[i]->data();
2442                                                 Move<VkDescriptorUpdateTemplate> descriptorUpdateTemplate = createDescriptorUpdateTemplate(vk, device, &templateCreateInfo, NULL);
2443                                                 vk.cmdPushDescriptorSetWithTemplateKHR(*cmdBuffer, *descriptorUpdateTemplate, *pipelineLayout, 0, templateVectorData[i]);
2444                                         }
2445                                 }
2446                         }
2447                         else
2448                         {
2449                                 for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(templateVectorsBefore); ++i)
2450                                 {
2451                                         if (templateVectorsBefore[i]->size())
2452                                         {
2453                                                 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)templateVectorsBefore[i]->size();
2454                                                 templateCreateInfo.pDescriptorUpdateEntries = templateVectorsBefore[i]->data();
2455                                                 Move<VkDescriptorUpdateTemplate> descriptorUpdateTemplate = createDescriptorUpdateTemplate(vk, device, &templateCreateInfo, NULL);
2456                                                 vk.updateDescriptorSetWithTemplate(device, descriptorSet.get(), *descriptorUpdateTemplate, templateVectorData[i]);
2457                                         }
2458                                 }
2459
2460                                 vk.cmdBindDescriptorSets(*cmdBuffer, bindPoint, *pipelineLayout, 0, 1, &descriptorSet.get(), numDynamic, &zeros[0]);
2461                         }
2462 #endif
2463                 }
2464                 else
2465                 {
2466                         if (m_data.pushDescriptor)
2467                         {
2468 #ifndef CTS_USES_VULKANSC
2469                                 if (writesBeforeBindVec.size())
2470                                 {
2471                                         vk.cmdPushDescriptorSetKHR(*cmdBuffer, bindPoint, *pipelineLayout, 0, (deUint32)writesBeforeBindVec.size(), &writesBeforeBindVec[0]);
2472                                 }
2473 #endif
2474                         }
2475                         else
2476                         {
2477                                 if (writesBeforeBindVec.size())
2478                                 {
2479                                         vk.updateDescriptorSets(device, (deUint32)writesBeforeBindVec.size(), &writesBeforeBindVec[0], 0, NULL);
2480                                 }
2481
2482                                 vk.cmdBindDescriptorSets(*cmdBuffer, bindPoint, *pipelineLayout, 0, 1, &descriptorSet.get(), numDynamic, &zeros[0]);
2483                         }
2484                 }
2485         }
2486
2487         Move<VkPipeline> pipeline;
2488         Move<VkRenderPass> renderPass;
2489         Move<VkFramebuffer> framebuffer;
2490
2491         de::MovePtr<BufferWithMemory> sbtBuffer;
2492
2493         if (m_data.stage == STAGE_COMPUTE)
2494         {
2495                 const Unique<VkShaderModule>    shader(createShaderModule(vk, device, m_context.getBinaryCollection().get("test"), 0));
2496
2497                 pipeline = makeComputePipeline(vk, device, *pipelineLayout, *shader);
2498
2499         }
2500 #ifndef CTS_USES_VULKANSC
2501         else if (m_data.stage == STAGE_RAYGEN)
2502         {
2503                 const Unique<VkShaderModule>    shader(createShaderModule(vk, device, m_context.getBinaryCollection().get("test"), 0));
2504
2505                 const VkPipelineShaderStageCreateInfo   shaderCreateInfo =
2506                 {
2507                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
2508                         DE_NULL,
2509                         (VkPipelineShaderStageCreateFlags)0,
2510                         VK_SHADER_STAGE_RAYGEN_BIT_NV,                                                          // stage
2511                         *shader,                                                                                                        // shader
2512                         "main",
2513                         DE_NULL,                                                                                                        // pSpecializationInfo
2514                 };
2515
2516                 VkRayTracingShaderGroupCreateInfoNV group =
2517                 {
2518                         VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV,
2519                         DE_NULL,
2520                         VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV,                    // type
2521                         0,                                                                                                              // generalShader
2522                         VK_SHADER_UNUSED_NV,                                                                    // closestHitShader
2523                         VK_SHADER_UNUSED_NV,                                                                    // anyHitShader
2524                         VK_SHADER_UNUSED_NV,                                                                    // intersectionShader
2525                 };
2526
2527                 VkRayTracingPipelineCreateInfoNV pipelineCreateInfo = {
2528                         VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_NV,  // sType
2529                         DE_NULL,                                                                                                // pNext
2530                         0,                                                                                                              // flags
2531                         1,                                                                                                              // stageCount
2532                         &shaderCreateInfo,                                                                              // pStages
2533                         1,                                                                                                              // groupCount
2534                         &group,                                                                                                 // pGroups
2535                         0,                                                                                                              // maxRecursionDepth
2536                         *pipelineLayout,                                                                                // layout
2537                         (vk::VkPipeline)0,                                                                              // basePipelineHandle
2538                         0u,                                                                                                             // basePipelineIndex
2539                 };
2540
2541                 pipeline = createRayTracingPipelineNV(vk, device, DE_NULL, &pipelineCreateInfo, NULL);
2542
2543                 sbtBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
2544                         vk, device, allocator, makeBufferCreateInfo(rayTracingProperties.shaderGroupHandleSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_RAY_TRACING_BIT_NV), MemoryRequirement::HostVisible));
2545
2546                 deUint32 *ptr = (deUint32 *)sbtBuffer->getAllocation().getHostPtr();
2547                 invalidateAlloc(vk, device, sbtBuffer->getAllocation());
2548
2549                 vk.getRayTracingShaderGroupHandlesNV(device, *pipeline, 0, 1, rayTracingProperties.shaderGroupHandleSize, ptr);
2550         }
2551 #endif
2552         else
2553         {
2554                 const VkSubpassDescription              subpassDesc                             =
2555                 {
2556                         (VkSubpassDescriptionFlags)0,                                                                                   // VkSubpassDescriptionFlags    flags
2557                         VK_PIPELINE_BIND_POINT_GRAPHICS,                                                                                // VkPipelineBindPoint                  pipelineBindPoint
2558                         0u,                                                                                                                                             // deUint32                                             inputAttachmentCount
2559                         DE_NULL,                                                                                                                                // const VkAttachmentReference* pInputAttachments
2560                         0u,                                                                                                                                             // deUint32                                             colorAttachmentCount
2561                         DE_NULL,                                                                                                                                // const VkAttachmentReference* pColorAttachments
2562                         DE_NULL,                                                                                                                                // const VkAttachmentReference* pResolveAttachments
2563                         DE_NULL,                                                                                                                                // const VkAttachmentReference* pDepthStencilAttachment
2564                         0u,                                                                                                                                             // deUint32                                             preserveAttachmentCount
2565                         DE_NULL                                                                                                                                 // const deUint32*                              pPreserveAttachments
2566                 };
2567
2568                 const VkSubpassDependency               subpassDependency               =
2569                 {
2570                         VK_SUBPASS_EXTERNAL,                                                    // deUint32                             srcSubpass
2571                         0,                                                                                              // deUint32                             dstSubpass
2572                         VK_PIPELINE_STAGE_TRANSFER_BIT,                                 // VkPipelineStageFlags srcStageMask
2573                         VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,                  // VkPipelineStageFlags dstStageMask
2574                         VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                srcAccessMask
2575                         VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT,        //      dstAccessMask
2576                         VK_DEPENDENCY_BY_REGION_BIT                                             // VkDependencyFlags    dependencyFlags
2577                 };
2578
2579                 const VkRenderPassCreateInfo    renderPassParams                =
2580                 {
2581                         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                              // VkStructureTypei                                     sType
2582                         DE_NULL,                                                                                                // const void*                                          pNext
2583                         (VkRenderPassCreateFlags)0,                                                             // VkRenderPassCreateFlags                      flags
2584                         0u,                                                                                                             // deUint32                                                     attachmentCount
2585                         DE_NULL,                                                                                                // const VkAttachmentDescription*       pAttachments
2586                         1u,                                                                                                             // deUint32                                                     subpassCount
2587                         &subpassDesc,                                                                                   // const VkSubpassDescription*          pSubpasses
2588                         1u,                                                                                                             // deUint32                                                     dependencyCount
2589                         &subpassDependency                                                                              // const VkSubpassDependency*           pDependencies
2590                 };
2591
2592                 renderPass = createRenderPass(vk, device, &renderPassParams);
2593
2594                 const vk::VkFramebufferCreateInfo       framebufferParams       =
2595                 {
2596                         vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,                  // sType
2597                         DE_NULL,                                                                                                // pNext
2598                         (vk::VkFramebufferCreateFlags)0,
2599                         *renderPass,                                                                                    // renderPass
2600                         0u,                                                                                                             // attachmentCount
2601                         DE_NULL,                                                                                                // pAttachments
2602                         DIM,                                                                                                    // width
2603                         DIM,                                                                                                    // height
2604                         1u,                                                                                                             // layers
2605                 };
2606
2607                 framebuffer = createFramebuffer(vk, device, &framebufferParams);
2608
2609                 const VkVertexInputBindingDescription                   vertexInputBindingDescription           =
2610                 {
2611                         0u,                                                             // deUint32                      binding
2612                         (deUint32)formatBytes,                  // deUint32                      stride
2613                         VK_VERTEX_INPUT_RATE_VERTEX,    // VkVertexInputRate    inputRate
2614                 };
2615
2616                 const VkVertexInputAttributeDescription                 vertexInputAttributeDescription         =
2617                 {
2618                         0u,                                                             // deUint32     location
2619                         0u,                                                             // deUint32     binding
2620                         m_data.format,                                  // VkFormat     format
2621                         0u                                                              // deUint32     offset
2622                 };
2623
2624                 deUint32 numAttribs = m_data.descriptorType == VERTEX_ATTRIBUTE_FETCH ? 1u : 0u;
2625
2626                 const VkPipelineVertexInputStateCreateInfo              vertexInputStateCreateInfo              =
2627                 {
2628                         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,      // VkStructureType                                                      sType;
2629                         DE_NULL,                                                                                                        // const void*                                                          pNext;
2630                         (VkPipelineVertexInputStateCreateFlags)0,                                       // VkPipelineVertexInputStateCreateFlags        flags;
2631                         numAttribs,                                                                                                     // deUint32                                                                     vertexBindingDescriptionCount;
2632                         &vertexInputBindingDescription,                                                         // const VkVertexInputBindingDescription*       pVertexBindingDescriptions;
2633                         numAttribs,                                                                                                     // deUint32                                                                     vertexAttributeDescriptionCount;
2634                         &vertexInputAttributeDescription                                                        // const VkVertexInputAttributeDescription*     pVertexAttributeDescriptions;
2635                 };
2636
2637                 const VkPipelineInputAssemblyStateCreateInfo    inputAssemblyStateCreateInfo    =
2638                 {
2639                         VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                                                      sType;
2640                         DE_NULL,                                                                                                                // const void*                                                          pNext;
2641                         (VkPipelineInputAssemblyStateCreateFlags)0,                                             // VkPipelineInputAssemblyStateCreateFlags      flags;
2642                         (m_data.stage == STAGE_VERTEX) ? VK_PRIMITIVE_TOPOLOGY_POINT_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // VkPrimitiveTopology                                                topology;
2643                         VK_FALSE                                                                                                                // VkBool32                                                                     primitiveRestartEnable;
2644                 };
2645
2646                 const VkPipelineRasterizationStateCreateInfo    rasterizationStateCreateInfo    =
2647                 {
2648                         VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                                                      sType;
2649                         DE_NULL,                                                                                                                // const void*                                                          pNext;
2650                         (VkPipelineRasterizationStateCreateFlags)0,                                             // VkPipelineRasterizationStateCreateFlags      flags;
2651                         VK_FALSE,                                                                                                               // VkBool32                                                                     depthClampEnable;
2652                         (m_data.stage == STAGE_VERTEX) ? VK_TRUE : VK_FALSE,                    // VkBool32                                                                     rasterizerDiscardEnable;
2653                         VK_POLYGON_MODE_FILL,                                                                                   // VkPolygonMode                                                        polygonMode;
2654                         VK_CULL_MODE_NONE,                                                                                              // VkCullModeFlags                                                      cullMode;
2655                         VK_FRONT_FACE_CLOCKWISE,                                                                                // VkFrontFace                                                          frontFace;
2656                         VK_FALSE,                                                                                                               // VkBool32                                                                     depthBiasEnable;
2657                         0.0f,                                                                                                                   // float                                                                        depthBiasConstantFactor;
2658                         0.0f,                                                                                                                   // float                                                                        depthBiasClamp;
2659                         0.0f,                                                                                                                   // float                                                                        depthBiasSlopeFactor;
2660                         1.0f                                                                                                                    // float                                                                        lineWidth;
2661                 };
2662
2663                 const VkPipelineMultisampleStateCreateInfo              multisampleStateCreateInfo =
2664                 {
2665                         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType
2666                         DE_NULL,                                                                                                        // const void*                                                          pNext
2667                         0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags
2668                         VK_SAMPLE_COUNT_1_BIT,                                                                          // VkSampleCountFlagBits                                        rasterizationSamples
2669                         VK_FALSE,                                                                                                       // VkBool32                                                                     sampleShadingEnable
2670                         1.0f,                                                                                                           // float                                                                        minSampleShading
2671                         DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask
2672                         VK_FALSE,                                                                                                       // VkBool32                                                                     alphaToCoverageEnable
2673                         VK_FALSE                                                                                                        // VkBool32                                                                     alphaToOneEnable
2674                 };
2675
2676                 VkViewport viewport = makeViewport(DIM, DIM);
2677                 VkRect2D scissor = makeRect2D(DIM, DIM);
2678
2679                 const VkPipelineViewportStateCreateInfo                 viewportStateCreateInfo                         =
2680                 {
2681                         VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,  // VkStructureType                                                      sType
2682                         DE_NULL,                                                                                                // const void*                                                          pNext
2683                         (VkPipelineViewportStateCreateFlags)0,                                  // VkPipelineViewportStateCreateFlags           flags
2684                         1u,                                                                                                             // deUint32                                                                     viewportCount
2685                         &viewport,                                                                                              // const VkViewport*                                            pViewports
2686                         1u,                                                                                                             // deUint32                                                                     scissorCount
2687                         &scissor                                                                                                // const VkRect2D*                                                      pScissors
2688                 };
2689
2690                 Move<VkShaderModule> fs;
2691                 Move<VkShaderModule> vs;
2692
2693                 deUint32 numStages;
2694                 if (m_data.stage == STAGE_VERTEX)
2695                 {
2696                         vs = createShaderModule(vk, device, m_context.getBinaryCollection().get("test"), 0);
2697                         fs = createShaderModule(vk, device, m_context.getBinaryCollection().get("test"), 0); // bogus
2698                         numStages = 1u;
2699                 }
2700                 else
2701                 {
2702                         vs = createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0);
2703                         fs = createShaderModule(vk, device, m_context.getBinaryCollection().get("test"), 0);
2704                         numStages = 2u;
2705                 }
2706
2707                 const VkPipelineShaderStageCreateInfo   shaderCreateInfo[2] =
2708                 {
2709                         {
2710                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
2711                                 DE_NULL,
2712                                 (VkPipelineShaderStageCreateFlags)0,
2713                                 VK_SHADER_STAGE_VERTEX_BIT,                                                                     // stage
2714                                 *vs,                                                                                                            // shader
2715                                 "main",
2716                                 DE_NULL,                                                                                                        // pSpecializationInfo
2717                         },
2718                         {
2719                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
2720                                 DE_NULL,
2721                                 (VkPipelineShaderStageCreateFlags)0,
2722                                 VK_SHADER_STAGE_FRAGMENT_BIT,                                                           // stage
2723                                 *fs,                                                                                                            // shader
2724                                 "main",
2725                                 DE_NULL,                                                                                                        // pSpecializationInfo
2726                         }
2727                 };
2728
2729                 const VkGraphicsPipelineCreateInfo                              graphicsPipelineCreateInfo              =
2730                 {
2731                         VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,        // VkStructureType                                                                      sType;
2732                         DE_NULL,                                                                                        // const void*                                                                          pNext;
2733                         (VkPipelineCreateFlags)0,                                                       // VkPipelineCreateFlags                                                        flags;
2734                         numStages,                                                                                      // deUint32                                                                                     stageCount;
2735                         &shaderCreateInfo[0],                                                           // const VkPipelineShaderStageCreateInfo*                       pStages;
2736                         &vertexInputStateCreateInfo,                                            // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
2737                         &inputAssemblyStateCreateInfo,                                          // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
2738                         DE_NULL,                                                                                        // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
2739                         &viewportStateCreateInfo,                                                       // const VkPipelineViewportStateCreateInfo*                     pViewportState;
2740                         &rasterizationStateCreateInfo,                                          // const VkPipelineRasterizationStateCreateInfo*        pRasterizationState;
2741                         &multisampleStateCreateInfo,                                            // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
2742                         DE_NULL,                                                                                        // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
2743                         DE_NULL,                                                                                        // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
2744                         DE_NULL,                                                                                        // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
2745                         pipelineLayout.get(),                                                           // VkPipelineLayout                                                                     layout;
2746                         renderPass.get(),                                                                       // VkRenderPass                                                                         renderPass;
2747                         0u,                                                                                                     // deUint32                                                                                     subpass;
2748                         DE_NULL,                                                                                        // VkPipeline                                                                           basePipelineHandle;
2749                         0                                                                                                       // int                                                                                          basePipelineIndex;
2750                 };
2751
2752                 pipeline = createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineCreateInfo);
2753         }
2754
2755         const VkImageMemoryBarrier imageBarrier =
2756         {
2757                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                         // VkStructureType              sType
2758                 DE_NULL,                                                                                        // const void*                  pNext
2759                 0u,                                                                                                     // VkAccessFlags                srcAccessMask
2760                 VK_ACCESS_TRANSFER_WRITE_BIT,                                           // VkAccessFlags                dstAccessMask
2761                 VK_IMAGE_LAYOUT_UNDEFINED,                                                      // VkImageLayout                oldLayout
2762                 VK_IMAGE_LAYOUT_GENERAL,                                                        // VkImageLayout                newLayout
2763                 VK_QUEUE_FAMILY_IGNORED,                                                        // uint32_t                             srcQueueFamilyIndex
2764                 VK_QUEUE_FAMILY_IGNORED,                                                        // uint32_t                             dstQueueFamilyIndex
2765                 **images[0],                                                                            // VkImage                              image
2766                 {
2767                         VK_IMAGE_ASPECT_COLOR_BIT,                              // VkImageAspectFlags   aspectMask
2768                         0u,                                                                             // uint32_t                             baseMipLevel
2769                         1u,                                                                             // uint32_t                             mipLevels,
2770                         0u,                                                                             // uint32_t                             baseArray
2771                         1u,                                                                             // uint32_t                             arraySize
2772                 }
2773         };
2774
2775         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
2776                                                         (VkDependencyFlags)0,
2777                                                         0, (const VkMemoryBarrier*)DE_NULL,
2778                                                         0, (const VkBufferMemoryBarrier*)DE_NULL,
2779                                                         1, &imageBarrier);
2780
2781         vk.cmdBindPipeline(*cmdBuffer, bindPoint, *pipeline);
2782
2783         if (!formatIsR64(m_data.format))
2784         {
2785                 VkImageSubresourceRange range = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
2786                 VkClearValue clearColor = makeClearValueColorU32(0,0,0,0);
2787
2788                 vk.cmdClearColorImage(*cmdBuffer, **images[0], VK_IMAGE_LAYOUT_GENERAL, &clearColor.color, 1, &range);
2789         }
2790         else
2791         {
2792                 const vector<VkBufferImageCopy> bufferImageCopy(1, makeBufferImageCopy(outputImageCreateInfo.extent, makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1)));
2793                 copyBufferToImage(vk,
2794                         *cmdBuffer,
2795                         *(*bufferOutputImageR64),
2796                         sizeOutputR64,
2797                         bufferImageCopy,
2798                         VK_IMAGE_ASPECT_COLOR_BIT,
2799                         1,
2800                         1, **images[0], VK_IMAGE_LAYOUT_GENERAL, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT);
2801         }
2802
2803         VkMemoryBarrier                                 memBarrier =
2804         {
2805                 VK_STRUCTURE_TYPE_MEMORY_BARRIER,       // sType
2806                 DE_NULL,                                                        // pNext
2807                 0u,                                                                     // srcAccessMask
2808                 0u,                                                                     // dstAccessMask
2809         };
2810
2811         memBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
2812         memBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
2813         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, m_data.allPipelineStages,
2814                 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
2815
2816         if (m_data.stage == STAGE_COMPUTE)
2817         {
2818                 vk.cmdDispatch(*cmdBuffer, DIM, DIM, 1);
2819         }
2820 #ifndef CTS_USES_VULKANSC
2821         else if (m_data.stage == STAGE_RAYGEN)
2822         {
2823                 vk.cmdTraceRaysNV(*cmdBuffer,
2824                         **sbtBuffer, 0,
2825                         DE_NULL, 0, 0,
2826                         DE_NULL, 0, 0,
2827                         DE_NULL, 0, 0,
2828                         DIM, DIM, 1);
2829         }
2830 #endif
2831         else
2832         {
2833                 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer,
2834                                                 makeRect2D(DIM, DIM),
2835                                                 0, DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
2836                 // Draw a point cloud for vertex shader testing, and a single quad for fragment shader testing
2837                 if (m_data.descriptorType == VERTEX_ATTRIBUTE_FETCH)
2838                 {
2839                         VkDeviceSize zeroOffset = 0;
2840                         VkBuffer b = m_data.nullDescriptor ? DE_NULL : **buffer;
2841                         vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &b, &zeroOffset);
2842                         vk.cmdDraw(*cmdBuffer, 1000u, 1u, 0u, 0u);
2843                 }
2844                 if (m_data.stage == STAGE_VERTEX)
2845                 {
2846                         vk.cmdDraw(*cmdBuffer, DIM*DIM, 1u, 0u, 0u);
2847                 }
2848                 else
2849                 {
2850                         vk.cmdDraw(*cmdBuffer, 4u, 1u, 0u, 0u);
2851                 }
2852                 endRenderPass(vk, *cmdBuffer);
2853         }
2854
2855         memBarrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
2856         memBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
2857         vk.cmdPipelineBarrier(*cmdBuffer, m_data.allPipelineStages, VK_PIPELINE_STAGE_TRANSFER_BIT,
2858                 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
2859
2860         const VkBufferImageCopy copyRegion = makeBufferImageCopy(makeExtent3D(DIM, DIM, 1u),
2861                                                                                                                          makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
2862         vk.cmdCopyImageToBuffer(*cmdBuffer, **images[0], VK_IMAGE_LAYOUT_GENERAL, **copyBuffer, 1u, &copyRegion);
2863
2864         endCommandBuffer(vk, *cmdBuffer);
2865
2866         submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
2867
2868         void *ptr = copyBuffer->getAllocation().getHostPtr();
2869
2870         invalidateAlloc(vk, device, copyBuffer->getAllocation());
2871
2872         qpTestResult res = QP_TEST_RESULT_PASS;
2873
2874         for (deUint32 i = 0; i < DIM*DIM; ++i)
2875         {
2876                 if (formatIsFloat(m_data.format))
2877                 {
2878                         if (((float *)ptr)[i * numComponents] != 1.0f)
2879                         {
2880                                 res = QP_TEST_RESULT_FAIL;
2881                         }
2882                 }
2883                 else if (formatIsR64(m_data.format))
2884                 {
2885                         if (((deUint64 *)ptr)[i * numComponents] != 1)
2886                         {
2887                                 res = QP_TEST_RESULT_FAIL;
2888                         }
2889                 }
2890                 else
2891                 {
2892                         if (((deUint32 *)ptr)[i * numComponents] != 1)
2893                         {
2894                                 res = QP_TEST_RESULT_FAIL;
2895                         }
2896                 }
2897         }
2898
2899         return tcu::TestStatus(res, qpGetTestResultName(res));
2900 }
2901
2902 }       // anonymous
2903
2904 static void createTests (tcu::TestCaseGroup* group, bool robustness2)
2905 {
2906         tcu::TestContext& testCtx = group->getTestContext();
2907
2908         typedef struct
2909         {
2910                 deUint32                                count;
2911                 const char*                             name;
2912                 const char*                             description;
2913         } TestGroupCase;
2914
2915         TestGroupCase fmtCases[] =
2916         {
2917                 { VK_FORMAT_R32_SINT,                           "r32i",         ""              },
2918                 { VK_FORMAT_R32_UINT,                           "r32ui",        ""              },
2919                 { VK_FORMAT_R32_SFLOAT,                         "r32f",         ""              },
2920                 { VK_FORMAT_R32G32_SINT,                        "rg32i",        ""              },
2921                 { VK_FORMAT_R32G32_UINT,                        "rg32ui",       ""              },
2922                 { VK_FORMAT_R32G32_SFLOAT,                      "rg32f",        ""              },
2923                 { VK_FORMAT_R32G32B32A32_SINT,          "rgba32i",      ""              },
2924                 { VK_FORMAT_R32G32B32A32_UINT,          "rgba32ui",     ""              },
2925                 { VK_FORMAT_R32G32B32A32_SFLOAT,        "rgba32f",      ""              },
2926                 { VK_FORMAT_R64_SINT,                           "r64i",         ""              },
2927                 { VK_FORMAT_R64_UINT,                           "r64ui",        ""              },
2928         };
2929
2930         TestGroupCase fullDescCases[] =
2931         {
2932                 { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,                            "uniform_buffer",                       ""              },
2933                 { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,                            "storage_buffer",                       ""              },
2934                 { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,            "uniform_buffer_dynamic",       ""              },
2935                 { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC,            "storage_buffer_dynamic",       ""              },
2936                 { VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,                      "uniform_texel_buffer",         ""              },
2937                 { VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,                      "storage_texel_buffer",         ""              },
2938                 { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,                                     "storage_image",                        ""              },
2939                 { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,            "sampled_image",                        ""              },
2940                 { VERTEX_ATTRIBUTE_FETCH,                                                       "vertex_attribute_fetch",       ""              },
2941         };
2942
2943         TestGroupCase imgDescCases[] =
2944         {
2945                 { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,                                     "storage_image",                        ""              },
2946                 { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,            "sampled_image",                        ""              },
2947         };
2948
2949         TestGroupCase fullLenCases32Bit[] =
2950         {
2951                 { ~0U,                  "null_descriptor",      ""              },
2952                 { 0,                    "img",                          ""              },
2953                 { 4,                    "len_4",                        ""              },
2954                 { 8,                    "len_8",                        ""              },
2955                 { 12,                   "len_12",                       ""              },
2956                 { 16,                   "len_16",                       ""              },
2957                 { 20,                   "len_20",                       ""              },
2958                 { 31,                   "len_31",                       ""              },
2959                 { 32,                   "len_32",                       ""              },
2960                 { 33,                   "len_33",                       ""              },
2961                 { 35,                   "len_35",                       ""              },
2962                 { 36,                   "len_36",                       ""              },
2963                 { 39,                   "len_39",                       ""              },
2964                 { 40,                   "len_41",                       ""              },
2965                 { 252,                  "len_252",                      ""              },
2966                 { 256,                  "len_256",                      ""              },
2967                 { 260,                  "len_260",                      ""              },
2968         };
2969
2970         TestGroupCase fullLenCases64Bit[] =
2971         {
2972                 { ~0U,                  "null_descriptor",      ""              },
2973                 { 0,                    "img",                          ""              },
2974                 { 8,                    "len_8",                        ""              },
2975                 { 16,                   "len_16",                       ""              },
2976                 { 24,                   "len_24",                       ""              },
2977                 { 32,                   "len_32",                       ""              },
2978                 { 40,                   "len_40",                       ""              },
2979                 { 62,                   "len_62",                       ""              },
2980                 { 64,                   "len_64",                       ""              },
2981                 { 66,                   "len_66",                       ""              },
2982                 { 70,                   "len_70",                       ""              },
2983                 { 72,                   "len_72",                       ""              },
2984                 { 78,                   "len_78",                       ""              },
2985                 { 80,                   "len_80",                       ""              },
2986                 { 504,                  "len_504",                      ""              },
2987                 { 512,                  "len_512",                      ""              },
2988                 { 520,                  "len_520",                      ""              },
2989         };
2990
2991         TestGroupCase imgLenCases[] =
2992         {
2993                 { 0,    "img",  ""              },
2994         };
2995
2996         TestGroupCase viewCases[] =
2997         {
2998                 { VK_IMAGE_VIEW_TYPE_1D,                        "1d",                   ""              },
2999                 { VK_IMAGE_VIEW_TYPE_2D,                        "2d",                   ""              },
3000                 { VK_IMAGE_VIEW_TYPE_3D,                        "3d",                   ""              },
3001                 { VK_IMAGE_VIEW_TYPE_CUBE,                      "cube",                 ""              },
3002                 { VK_IMAGE_VIEW_TYPE_1D_ARRAY,          "1d_array",             ""              },
3003                 { VK_IMAGE_VIEW_TYPE_2D_ARRAY,          "2d_array",             ""              },
3004                 { VK_IMAGE_VIEW_TYPE_CUBE_ARRAY,        "cube_array",   ""              },
3005         };
3006
3007         TestGroupCase sampCases[] =
3008         {
3009                 { VK_SAMPLE_COUNT_1_BIT,                        "samples_1",    ""              },
3010                 { VK_SAMPLE_COUNT_4_BIT,                        "samples_4",    ""              },
3011         };
3012
3013         TestGroupCase stageCases[] =
3014         {
3015                 { STAGE_COMPUTE,        "comp",         "compute"       },
3016                 { STAGE_FRAGMENT,       "frag",         "fragment"      },
3017                 { STAGE_VERTEX,         "vert",         "vertex"        },
3018 #ifndef CTS_USES_VULKANSC
3019                 { STAGE_RAYGEN,         "rgen",         "raygen"        },
3020 #endif
3021         };
3022
3023         TestGroupCase volCases[] =
3024         {
3025                 { 0,                    "nonvolatile",  ""              },
3026                 { 1,                    "volatile",             ""              },
3027         };
3028
3029         TestGroupCase unrollCases[] =
3030         {
3031                 { 0,                    "dontunroll",   ""              },
3032                 { 1,                    "unroll",               ""              },
3033         };
3034
3035         TestGroupCase tempCases[] =
3036         {
3037                 { 0,                    "notemplate",   ""              },
3038 #ifndef CTS_USES_VULKANSC
3039                 { 1,                    "template",             ""              },
3040 #endif
3041         };
3042
3043         TestGroupCase pushCases[] =
3044         {
3045                 { 0,                    "bind",                 ""              },
3046 #ifndef CTS_USES_VULKANSC
3047                 { 1,                    "push",                 ""              },
3048 #endif
3049         };
3050
3051         TestGroupCase fmtQualCases[] =
3052         {
3053                 { 0,                    "no_fmt_qual",  ""              },
3054                 { 1,                    "fmt_qual",             ""              },
3055         };
3056
3057         TestGroupCase readOnlyCases[] =
3058         {
3059                 { 0,                    "readwrite",    ""              },
3060                 { 1,                    "readonly",             ""              },
3061         };
3062
3063         for (int pushNdx = 0; pushNdx < DE_LENGTH_OF_ARRAY(pushCases); pushNdx++)
3064         {
3065                 de::MovePtr<tcu::TestCaseGroup> pushGroup(new tcu::TestCaseGroup(testCtx, pushCases[pushNdx].name, pushCases[pushNdx].name));
3066                 for (int tempNdx = 0; tempNdx < DE_LENGTH_OF_ARRAY(tempCases); tempNdx++)
3067                 {
3068                         de::MovePtr<tcu::TestCaseGroup> tempGroup(new tcu::TestCaseGroup(testCtx, tempCases[tempNdx].name, tempCases[tempNdx].name));
3069                         for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(fmtCases); fmtNdx++)
3070                         {
3071                                 de::MovePtr<tcu::TestCaseGroup> fmtGroup(new tcu::TestCaseGroup(testCtx, fmtCases[fmtNdx].name, fmtCases[fmtNdx].name));
3072
3073                                 int fmtSize = tcu::getPixelSize(mapVkFormat((VkFormat)fmtCases[fmtNdx].count));
3074
3075                                 for (int unrollNdx = 0; unrollNdx < DE_LENGTH_OF_ARRAY(unrollCases); unrollNdx++)
3076                                 {
3077                                         de::MovePtr<tcu::TestCaseGroup> unrollGroup(new tcu::TestCaseGroup(testCtx, unrollCases[unrollNdx].name, unrollCases[unrollNdx].name));
3078                                         for (int volNdx = 0; volNdx < DE_LENGTH_OF_ARRAY(volCases); volNdx++)
3079                                         {
3080                                                 de::MovePtr<tcu::TestCaseGroup> volGroup(new tcu::TestCaseGroup(testCtx, volCases[volNdx].name, volCases[volNdx].name));
3081
3082                                                 int numDescCases = robustness2 ? DE_LENGTH_OF_ARRAY(fullDescCases) : DE_LENGTH_OF_ARRAY(imgDescCases);
3083                                                 TestGroupCase *descCases = robustness2 ? fullDescCases : imgDescCases;
3084
3085                                                 for (int descNdx = 0; descNdx < numDescCases; descNdx++)
3086                                                 {
3087                                                         de::MovePtr<tcu::TestCaseGroup> descGroup(new tcu::TestCaseGroup(testCtx, descCases[descNdx].name, descCases[descNdx].name));
3088
3089                                                         for (int roNdx = 0; roNdx < DE_LENGTH_OF_ARRAY(readOnlyCases); roNdx++)
3090                                                         {
3091                                                                 de::MovePtr<tcu::TestCaseGroup> rwGroup(new tcu::TestCaseGroup(testCtx, readOnlyCases[roNdx].name, readOnlyCases[roNdx].name));
3092
3093                                                                 // readonly cases are just for storage_buffer
3094                                                                 if (readOnlyCases[roNdx].count != 0 &&
3095                                                                         descCases[descNdx].count != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER &&
3096                                                                         descCases[descNdx].count != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)
3097                                                                         continue;
3098
3099                                                                 for (int fmtQualNdx = 0; fmtQualNdx < DE_LENGTH_OF_ARRAY(fmtQualCases); fmtQualNdx++)
3100                                                                 {
3101                                                                         de::MovePtr<tcu::TestCaseGroup> fmtQualGroup(new tcu::TestCaseGroup(testCtx, fmtQualCases[fmtQualNdx].name, fmtQualCases[fmtQualNdx].name));
3102
3103                                                                         // format qualifier is only used for storage image and storage texel buffers
3104                                                                         if (fmtQualCases[fmtQualNdx].count &&
3105                                                                                 !(descCases[descNdx].count == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER || descCases[descNdx].count == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE))
3106                                                                                 continue;
3107
3108                                                                         if (pushCases[pushNdx].count &&
3109                                                                                 (descCases[descNdx].count == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || descCases[descNdx].count == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC || descCases[descNdx].count == VERTEX_ATTRIBUTE_FETCH))
3110                                                                                 continue;
3111
3112                                                                         const bool isR64 = formatIsR64((VkFormat)fmtCases[fmtNdx].count);
3113                                                                         int numLenCases = robustness2 ? DE_LENGTH_OF_ARRAY((isR64 ? fullLenCases64Bit : fullLenCases32Bit)) : DE_LENGTH_OF_ARRAY(imgLenCases);
3114                                                                         TestGroupCase *lenCases = robustness2 ? (isR64 ? fullLenCases64Bit : fullLenCases32Bit) : imgLenCases;
3115
3116                                                                         for (int lenNdx = 0; lenNdx < numLenCases; lenNdx++)
3117                                                                         {
3118                                                                                 if (lenCases[lenNdx].count != ~0U)
3119                                                                                 {
3120                                                                                         bool bufferLen = lenCases[lenNdx].count != 0;
3121                                                                                         bool bufferDesc = descCases[descNdx].count != VK_DESCRIPTOR_TYPE_STORAGE_IMAGE && descCases[descNdx].count != VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
3122                                                                                         if (bufferLen != bufferDesc)
3123                                                                                                 continue;
3124
3125                                                                                         // Add template tests cases only for null_descriptor cases
3126                                                                                         if (tempCases[tempNdx].count)
3127                                                                                                 continue;
3128                                                                                 }
3129
3130                                                                                 if ((descCases[descNdx].count == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER || descCases[descNdx].count == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) &&
3131                                                                                         ((lenCases[lenNdx].count % fmtSize) != 0) &&
3132                                                                                         lenCases[lenNdx].count != ~0U)
3133                                                                                 {
3134                                                                                         continue;
3135                                                                                 }
3136
3137                                                                                 // "volatile" only applies to storage images/buffers
3138                                                                                 if (volCases[volNdx].count && !supportsStores(descCases[descNdx].count))
3139                                                                                         continue;
3140
3141                                                                                 de::MovePtr<tcu::TestCaseGroup> lenGroup(new tcu::TestCaseGroup(testCtx, lenCases[lenNdx].name, lenCases[lenNdx].name));
3142                                                                                 for (int sampNdx = 0; sampNdx < DE_LENGTH_OF_ARRAY(sampCases); sampNdx++)
3143                                                                                 {
3144                                                                                         de::MovePtr<tcu::TestCaseGroup> sampGroup(new tcu::TestCaseGroup(testCtx, sampCases[sampNdx].name, sampCases[sampNdx].name));
3145                                                                                         for (int viewNdx = 0; viewNdx < DE_LENGTH_OF_ARRAY(viewCases); viewNdx++)
3146                                                                                         {
3147                                                                                                 if (viewCases[viewNdx].count != VK_IMAGE_VIEW_TYPE_1D &&
3148                                                                                                         descCases[descNdx].count != VK_DESCRIPTOR_TYPE_STORAGE_IMAGE &&
3149                                                                                                         descCases[descNdx].count != VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
3150                                                                                                 {
3151                                                                                                         // buffer descriptors don't have different dimensionalities. Only test "1D"
3152                                                                                                         continue;
3153                                                                                                 }
3154
3155                                                                                                 if (viewCases[viewNdx].count != VK_IMAGE_VIEW_TYPE_2D && viewCases[viewNdx].count != VK_IMAGE_VIEW_TYPE_2D_ARRAY &&
3156                                                                                                         sampCases[sampNdx].count != VK_SAMPLE_COUNT_1_BIT)
3157                                                                                                 {
3158                                                                                                         continue;
3159                                                                                                 }
3160
3161                                                                                                 de::MovePtr<tcu::TestCaseGroup> viewGroup(new tcu::TestCaseGroup(testCtx, viewCases[viewNdx].name, viewCases[viewNdx].name));
3162                                                                                                 for (int stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(stageCases); stageNdx++)
3163                                                                                                 {
3164                                                                                                         Stage currentStage = static_cast<Stage>(stageCases[stageNdx].count);
3165                                                                                                         VkFlags allShaderStages = VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
3166                                                                                                         VkFlags allPipelineStages = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
3167 #ifndef CTS_USES_VULKANSC
3168                                                                                                         if ((Stage)stageCases[stageNdx].count == STAGE_RAYGEN)
3169                                                                                                         {
3170                                                                                                                 allShaderStages |= VK_SHADER_STAGE_RAYGEN_BIT_NV;
3171                                                                                                                 allPipelineStages |= VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_NV;
3172                                                                                                         }
3173 #endif // CTS_USES_VULKANSC
3174
3175                                                                                                         if (descCases[descNdx].count == VERTEX_ATTRIBUTE_FETCH &&
3176                                                                                                                 currentStage != STAGE_VERTEX)
3177                                                                                                                 continue;
3178
3179                                                                                                         deUint32 imageDim[3] = {5, 11, 6};
3180                                                                                                         if (viewCases[viewNdx].count == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY ||
3181                                                                                                                 viewCases[viewNdx].count == VK_IMAGE_VIEW_TYPE_CUBE)
3182                                                                                                                 imageDim[1] = imageDim[0];
3183
3184                                                                                                         CaseDef c =
3185                                                                                                         {
3186                                                                                                                 (VkFormat)fmtCases[fmtNdx].count,                                                               // VkFormat format;
3187                                                                                                                 currentStage,                                                                                                   // Stage stage;
3188                                                                                                                 allShaderStages,                                                                                                // VkFlags allShaderStages;
3189                                                                                                                 allPipelineStages,                                                                                              // VkFlags allPipelineStages;
3190                                                                                                                 (int)descCases[descNdx].count,                                                                  // VkDescriptorType descriptorType;
3191                                                                                                                 (VkImageViewType)viewCases[viewNdx].count,                                              // VkImageViewType viewType;
3192                                                                                                                 (VkSampleCountFlagBits)sampCases[sampNdx].count,                                // VkSampleCountFlagBits samples;
3193                                                                                                                 (int)lenCases[lenNdx].count,                                                                    // int bufferLen;
3194                                                                                                                 (bool)unrollCases[unrollNdx].count,                                                             // bool unroll;
3195                                                                                                                 (bool)volCases[volNdx].count,                                                                   // bool vol;
3196                                                                                                                 (bool)(lenCases[lenNdx].count == ~0U),                                                  // bool nullDescriptor
3197                                                                                                                 (bool)tempCases[tempNdx].count,                                                                 // bool useTemplate
3198                                                                                                                 (bool)fmtQualCases[fmtQualNdx].count,                                                   // bool formatQualifier
3199                                                                                                                 (bool)pushCases[pushNdx].count,                                                                 // bool pushDescriptor;
3200                                                                                                                 (bool)robustness2,                                                                                              // bool testRobustness2;
3201                                                                                                                 { imageDim[0], imageDim[1], imageDim[2] },                                              // deUint32 imageDim[3];
3202                                                                                                                 (bool)(readOnlyCases[roNdx].count == 1),                                                // bool readOnly;
3203                                                                                                         };
3204
3205                                                                                                         viewGroup->addChild(new RobustnessExtsTestCase(testCtx, stageCases[stageNdx].name, stageCases[stageNdx].name, c));
3206                                                                                                 }
3207                                                                                                 sampGroup->addChild(viewGroup.release());
3208                                                                                         }
3209                                                                                         lenGroup->addChild(sampGroup.release());
3210                                                                                 }
3211                                                                                 fmtQualGroup->addChild(lenGroup.release());
3212                                                                         }
3213                                                                         // Put storage_buffer tests in separate readonly vs readwrite groups. Other types
3214                                                                         // go directly into descGroup
3215                                                                         if (descCases[descNdx].count == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
3216                                                                                 descCases[descNdx].count == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) {
3217                                                                                 rwGroup->addChild(fmtQualGroup.release());
3218                                                                         } else {
3219                                                                                 descGroup->addChild(fmtQualGroup.release());
3220                                                                         }
3221                                                                 }
3222                                                                 if (descCases[descNdx].count == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
3223                                                                         descCases[descNdx].count == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) {
3224                                                                         descGroup->addChild(rwGroup.release());
3225                                                                 }
3226                                                         }
3227                                                         volGroup->addChild(descGroup.release());
3228                                                 }
3229                                                 unrollGroup->addChild(volGroup.release());
3230                                         }
3231                                         fmtGroup->addChild(unrollGroup.release());
3232                                 }
3233                                 tempGroup->addChild(fmtGroup.release());
3234                         }
3235                         pushGroup->addChild(tempGroup.release());
3236                 }
3237                 group->addChild(pushGroup.release());
3238         }
3239 }
3240
3241 static void createRobustness2Tests (tcu::TestCaseGroup* group)
3242 {
3243         createTests(group, /*robustness2=*/true);
3244 }
3245
3246 static void createImageRobustnessTests (tcu::TestCaseGroup* group)
3247 {
3248         createTests(group, /*robustness2=*/false);
3249 }
3250
3251 static void cleanupGroup (tcu::TestCaseGroup* group)
3252 {
3253         DE_UNREF(group);
3254         // Destroy singleton objects.
3255         Robustness2Int64AtomicsSingleton::destroy();
3256         ImageRobustnessInt64AtomicsSingleton::destroy();
3257         ImageRobustnessSingleton::destroy();
3258         Robustness2Singleton::destroy();
3259 }
3260
3261 tcu::TestCaseGroup* createRobustness2Tests (tcu::TestContext& testCtx)
3262 {
3263         return createTestGroup(testCtx, "robustness2", "VK_EXT_robustness2 tests",
3264                                                         createRobustness2Tests, cleanupGroup);
3265 }
3266
3267 tcu::TestCaseGroup* createImageRobustnessTests (tcu::TestContext& testCtx)
3268 {
3269         return createTestGroup(testCtx, "image_robustness", "VK_EXT_image_robustness tests",
3270                                                         createImageRobustnessTests, cleanupGroup);
3271 }
3272
3273 }       // robustness
3274 }       // vkt