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