Fix missing dependency on sparse binds
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / descriptor_indexing / vktDescriptorSetsIndexingTests.cpp
1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2019 The Khronos Group Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Vulkan Decriptor Indexing Tests
22 *//*--------------------------------------------------------------------*/
23
24 #include <algorithm>
25 #include <iostream>
26 #include <iterator>
27 #include <functional>
28 #include <sstream>
29 #include <utility>
30 #include <vector>
31
32 #include "vktDescriptorSetsIndexingTests.hpp"
33
34 #include "vkBuilderUtil.hpp"
35 #include "vkCmdUtil.hpp"
36 #include "vkDefs.hpp"
37 #include "vkObjUtil.hpp"
38 #include "vkPlatform.hpp"
39 #include "vkPrograms.hpp"
40 #include "vkQueryUtil.hpp"
41 #include "vkTypeUtil.hpp"
42
43 #include "tcuTestLog.hpp"
44 #include "tcuResource.hpp"
45 #include "tcuImageCompare.hpp"
46 #include "tcuCommandLine.hpp"
47 #include "tcuStringTemplate.hpp"
48 #include "tcuSurface.hpp"
49 #include "tcuVectorUtil.hpp"
50
51 #include "deRandom.hpp"
52 #include "deMath.h"
53 #include "deStringUtil.hpp"
54
55 namespace vkt
56 {
57 namespace DescriptorIndexing
58 {
59 namespace
60 {
61 using namespace vk;
62 using tcu::UVec2;
63 using tcu::Vec4;
64 using tcu::TestStatus;
65 using tcu::PixelBufferAccess;
66 using tcu::Texture2D;
67
68 #define RESOLUTION_width        64
69 #define RESOLUTION_height       64
70 static const VkExtent3D RESOLUTION = { RESOLUTION_width, RESOLUTION_height, 1 };
71
72 #define MAX_DESCRIPTORS         4200
73 #define FUZZY_COMPARE           DE_FALSE
74 #define CMP_THRESHOLD           0.02f
75
76 #define BINDING_Undefined                               0
77 #define BINDING_UniformBuffer                   1
78 #define BINDING_StorageBuffer                   2
79 #define BINDING_UniformTexelBuffer              3
80 #define BINDING_StorageTexelBuffer              4
81 #define BINDING_Sampler                                 5
82 #define BINDING_SampledImage                    6
83 #define BINDING_CombinedImageSampler    7
84 #define BINDING_UniformBufferDynamic    8
85 #define BINDING_StorageBufferDynamic    9
86 #define BINDING_InputAttachment                 10
87 #define BINDING_StorageImage                    11
88 #define BINDING_DescriptorEnumerator    12
89
90 static const VkExtent3D                 smallImageExtent                                = { 4, 4, 1 };
91 static const VkExtent3D                 bigImageExtent                                  = { 32, 32, 1 };
92
93 #ifndef CTS_USES_VULKANSC
94 static const VkDescriptorType   VK_DESCRIPTOR_TYPE_UNDEFINED    = VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT;
95 #else
96 static const VkDescriptorType   VK_DESCRIPTOR_TYPE_UNDEFINED    = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
97 #endif
98
99 template<deUint32 BindingNumber>
100 struct Binding
101 {
102         static const deUint32   binding = BindingNumber;
103 };
104
105 struct BindingUniformBuffer : Binding<BINDING_UniformBuffer>
106 {
107         typedef struct
108         {
109                 tcu::Vec4 c;
110         } Data;
111 };
112
113 struct BindingStorageBuffer : Binding<BINDING_StorageBuffer>
114 {
115         typedef struct
116         {
117                 tcu::Vec4 cnew;
118                 tcu::Vec4 cold;
119         } Data;
120 };
121
122 struct TestCaseParams
123 {
124         VkDescriptorType        descriptorType;         // used only to distinguish test class instance
125         VkShaderStageFlags      stageFlags;                     // used only to build a proper program
126         VkExtent3D                      frameResolution;        // target frame buffer resolution
127         bool                            updateAfterBind;        // whether a test will use update after bind feature
128         bool                            calculateInLoop;        // perform calculation in a loop
129         bool                            usesMipMaps;            // this makes a sense and affects in image test cases only
130         bool                            minNonUniform;          // whether a test will use the minimum nonUniform decorations
131         deBool                          fuzzyComparison;        // if true then a test will use fuzzy comparison, otherwise float threshold
132         float                           thresholdValue;         // a threshold that will be used for both, float and fuzzy comparisons
133 };
134
135 struct TestParams
136 {
137         VkShaderStageFlags      stageFlags;
138         VkDescriptorType        descriptorType;
139         deUint32                        descriptorBinding;
140         VkDescriptorType        additionalDescriptorType;
141         deUint32                        additionalDescriptorBinding;
142         bool                            copyBuffersToImages;
143         bool                            allowVertexStoring;
144         VkExtent3D                      frameResolution;
145         bool                            updateAfterBind;
146         bool                            calculateInLoop;
147         bool                            usesMipMaps;
148         bool                            minNonUniform;
149         deBool                          fuzzyComparison;
150         float                           thresholdValue;
151
152         TestParams                      (VkShaderStageFlags             stageFlags_,
153                                                 VkDescriptorType                descriptorType_,
154                                                 deUint32                                descriptorBinding_,
155                                                 VkDescriptorType                additionalDescriptorType_,
156                                                 deUint32                                additionalDescriptorBinding_,
157                                                 bool                                    copyBuffersToImages_,
158                                                 bool                                    allowVertexStoring_,
159                                                 const TestCaseParams&   caseParams)
160                 : stageFlags                                                    (stageFlags_)
161                 , descriptorType                                                (descriptorType_)
162                 , descriptorBinding                                             (descriptorBinding_)
163                 , additionalDescriptorType                              (additionalDescriptorType_)
164                 , additionalDescriptorBinding                   (additionalDescriptorBinding_)
165                 , copyBuffersToImages                                   (copyBuffersToImages_)
166                 , allowVertexStoring                                    (allowVertexStoring_)
167                 , frameResolution                                               (caseParams.frameResolution)
168                 , updateAfterBind                                               (caseParams.updateAfterBind)
169                 , calculateInLoop                                               (caseParams.calculateInLoop)
170                 , usesMipMaps                                                   (caseParams.usesMipMaps)
171                 , minNonUniform                                                 (caseParams.minNonUniform)
172                 , fuzzyComparison                                               (caseParams.fuzzyComparison ? true : false)
173                 , thresholdValue                                                (caseParams.thresholdValue)
174         {
175         }
176 };
177
178 struct DescriptorEnumerator
179 {
180         ut::BufferHandleAllocSp                                                 buffer;
181         ut::BufferViewSp                                                                bufferView;
182         VkDeviceSize                                                                    bufferSize;
183
184         Move<VkDescriptorSetLayout>                                             descriptorSetLayout;
185         Move<VkDescriptorPool>                                                  descriptorPool;
186         Move<VkDescriptorSet>                                                   descriptorSet;
187
188         void init(const vkt::Context& context, deUint32 vertexCount, deUint32 availableDescriptorCount);
189         void update(const vkt::Context& context);
190 };
191
192 struct IterateCommonVariables
193 {
194         // An amount of descriptors of a given type available on the platform
195         deUint32                                                                                availableDescriptorCount;
196         // An amount of valid descriptors that have connected a buffers to them
197         deUint32                                                                                validDescriptorCount;
198         // As the name suggests, sometimes it is used as invocationCount
199         deUint32                                                                                vertexCount;
200         VkRect2D                                                                                renderArea;
201         VkDeviceSize                                                                    dataAlignment;
202         deUint32                                                                                lowerBound;
203         deUint32                                                                                upperBound;
204
205         DescriptorEnumerator                                                    descriptorEnumerator;
206
207         ut::BufferHandleAllocSp                                                 vertexAttributesBuffer;
208         ut::BufferHandleAllocSp                                                 descriptorsBuffer;
209         std::vector<VkDescriptorBufferInfo>                             descriptorsBufferInfos;
210         std::vector<ut::BufferViewSp>                                   descriptorsBufferViews;
211         std::vector<ut::ImageViewSp>                                    descriptorImageViews;
212         std::vector<ut::SamplerSp>                                              descriptorSamplers;
213         std::vector<ut::ImageHandleAllocSp>                             descriptorsImages;
214         ut::FrameBufferSp                                                               frameBuffer;
215
216         Move<VkDescriptorSetLayout>                                             descriptorSetLayout;
217         Move<VkDescriptorPool>                                                  descriptorPool;
218         Move<VkDescriptorSet>                                                   descriptorSet;
219         Move<VkPipelineLayout>                                                  pipelineLayout;
220         Move<VkRenderPass>                                                              renderPass;
221         Move<VkPipeline>                                                                pipeline;
222         Move<VkCommandBuffer>                                                   commandBuffer;
223 };
224
225 class CommonDescriptorInstance : public TestInstance
226 {
227 public:
228                                                                 CommonDescriptorInstance                (Context&                                                                       context,
229                                                                                                                                 const TestParams&                                                       testParams);
230
231         deUint32                                        computeAvailableDescriptorCount (VkDescriptorType                                                       descriptorType,
232                                                                                                                                  bool                                                                           reserveUniformTexelBuffer) const;
233
234         Move<VkDescriptorSetLayout>     createDescriptorSetLayout               (bool                                                                           reserveUniformTexelBuffer,
235                                                                                                                                  deUint32&                                                                      descriptorCount) const;
236
237         Move<VkDescriptorPool>          createDescriptorPool                    (deUint32                                                                       descriptorCount) const;
238
239         Move<VkDescriptorSet>           createDescriptorSet                             (VkDescriptorPool                                                       dsPool,
240                                                                                                                                  VkDescriptorSetLayout                                          dsLayout) const;
241
242         struct attributes
243         {
244                 typedef tcu::Vec4       vec4;
245                 typedef tcu::Vec2       vec2;
246                 typedef tcu::IVec4      ivec4;
247                 vec4                    position;
248                 vec2                    normalpos;
249                 ivec4                   index;
250                 attributes& operator()(const vec4& pos)
251                 {
252                         position = pos;
253
254                         normalpos.x() = (pos.x() + 1.0f) / 2.0f;
255                         normalpos.y() = (pos.y() + 1.0f) / 2.0f;
256
257                         return *this;
258                 }
259         };
260         void                                            createVertexAttributeBuffer             (ut::BufferHandleAllocSp&                                       buffer,
261                                                                                                                                  deUint32                                                                       availableDescriptorCount) const;
262
263         static std::string                      substBinding                                    (deUint32                                                                       binding,
264                                                                                                                                  const char*                                                            str,
265                                                                                                                                  deUint32                                                                       count = 0,
266                                                                                                                                  const char*                                                            name = DE_NULL);
267
268         static const char*                      getVertexShaderProlog                   (void);
269
270         static const char*                      getFragmentShaderProlog                 (void);
271
272         static const char*                      getShaderEpilog                                 (void);
273
274         static bool                                     performWritesInVertex                   (VkDescriptorType                                                       descriptorType);
275
276         static bool                                     performWritesInVertex                   (VkDescriptorType                                                       descriptorType,
277                                                                                                                                  const Context&                                                 context);
278
279         static std::string                      getShaderAsm                                    (VkShaderStageFlagBits                                          shaderType,
280                                                                                                                                  const TestCaseParams&                                          testCaseParams,
281                                                                                                                                  bool                                                                           allowVertexStoring);
282
283         static std::string                      getShaderSource                 (VkShaderStageFlagBits                                          shaderType,
284                                                                          const TestCaseParams&                                          testCaseParams,
285                                                                          bool                                                                           allowVertexStoring);
286
287         static std::string                      getColorAccess                                  (VkDescriptorType                                                       descriptorType,
288                                                                                                                                  const char*                                                            indexVariableName,
289                                                                                                                                  bool                                                                           usesMipMaps);
290
291         static std::string                      getFragmentReturnSource                 (const std::string&                                                     colorAccess);
292
293         static std::string                      getFragmentLoopSource                   (const std::string&                                                     colorAccess1,
294                                                                                                                                  const std::string&                                                     colorAccess2);
295
296         virtual Move<VkRenderPass>      createRenderPass                                (const IterateCommonVariables&                          variables);
297
298         struct push_constant
299         {
300                 deInt32 lowerBound;
301                 deInt32 upperBound;
302         };
303         VkPushConstantRange                     makePushConstantRange                   (void) const;
304
305         Move<VkPipelineLayout>          createPipelineLayout                    (const std::vector<VkDescriptorSetLayout>&      descriptorSetLayouts) const;
306
307         // Creates graphics or compute pipeline and appropriate shaders' modules according the testCaseParams.stageFlags
308         // In the case of compute pipeline renderPass parameter is ignored.
309         // Viewport will be created with a width and a height taken from testCaseParam.fragResolution.
310         Move<VkPipeline>                        createPipeline                                  (VkPipelineLayout                                                       pipelineLayout,
311                                                                                                                                  VkRenderPass                                                           renderPass);
312
313         virtual void                            createFramebuffer                               (ut::FrameBufferSp&                                                     frameBuffer,
314                                                                                                                                  VkRenderPass                                                           renderPass,
315                                                                                                                                  const IterateCommonVariables&                          variables);
316
317         // Creates one big stagging buffer cutted out on chunks that can accomodate an element of elementSize size
318         VkDeviceSize                            createBuffers                                   (std::vector<VkDescriptorBufferInfo>&           bufferInfos,
319                                                                                                                                  ut::BufferHandleAllocSp&                                       buffer,
320                                                                                                                                  deUint32                                                                       elementCount,
321                                                                                                                                  deUint32                                                                       elementSize,
322                                                                                                                                  VkDeviceSize                                                           alignment,
323                                                                                                                                  VkBufferUsageFlags                                                     bufferUsage);
324
325         // Creates and binds an imagesCount of images with given parameters.
326         // Additionally creates stagging buffer for their data and PixelBufferAccess for particular images.
327         VkDeviceSize                            createImages                                    (std::vector<ut::ImageHandleAllocSp>&           images,
328                                                                                                                                  std::vector<VkDescriptorBufferInfo>&           bufferInfos,
329                                                                                                                                  ut::BufferHandleAllocSp&                                       buffer,
330                                                                                                                                  VkBufferUsageFlags                                                     bufferUsage,
331                                                                                                                                  const VkExtent3D&                                                      imageExtent,
332                                                                                                                                  VkFormat                                                                       imageFormat,
333                                                                                                                                  VkImageLayout                                                          imageLayout,
334                                                                                                                                  deUint32                                                                       imageCount,
335                                                                                                                                  bool                                                                           withMipMaps = false);
336
337         void                                            createBuffersViews                              (std::vector<ut::BufferViewSp>&                         views,
338                                                                                                                                  const std::vector<VkDescriptorBufferInfo>&     bufferInfos,
339                                                                                                                                  VkFormat                                                                       format);
340
341         void                                            createImagesViews                               (std::vector<ut::ImageViewSp>&                          views,
342                                                                                                                                  const std::vector<ut::ImageHandleAllocSp>&     images,
343                                                                                                                                  VkFormat                                                                       format);
344
345         virtual void                            copyBuffersToImages                             (IterateCommonVariables&                                        variables);
346
347         virtual void                            copyImagesToBuffers                             (IterateCommonVariables&                                        variables);
348
349         PixelBufferAccess                       getPixelAccess                                  (deUint32                                                                       imageIndex,
350                                                                                                                                  const VkExtent3D&                                                      imageExtent,
351                                                                                                                                  VkFormat                                                                       imageFormat,
352                                                                                                                                  const std::vector<VkDescriptorBufferInfo>&     bufferInfos,
353                                                                                                                                  const ut::BufferHandleAllocSp&                         buffer,
354                                                                                                                                  deUint32                                                                       mipLevel = 0u) const;
355
356         virtual void                            createAndPopulateDescriptors    (IterateCommonVariables&                                        variables) = 0;
357
358         virtual void                            updateDescriptors                               (IterateCommonVariables&                                        variables);
359
360         virtual void                            iterateCollectResults                   (ut::UpdatablePixelBufferAccessPtr&                     result,
361                                                                                                                                  const IterateCommonVariables&                          variables,
362                                                                                                                                  bool                                                                           fromTest);
363
364         void                                            iterateCommandSetup                             (IterateCommonVariables&                                        variables);
365
366         void                                            iterateCommandBegin                             (IterateCommonVariables&                                        variables,
367                                                                                                                                 bool                                                                            firstPass = true);
368
369         void                                            iterateCommandEnd                               (IterateCommonVariables&                                        variables,
370                                                                                                                                 ut::UpdatablePixelBufferAccessPtr&      programResult,
371                                                                                                                                 ut::UpdatablePixelBufferAccessPtr&      referenceResult,
372                                                                                                                                  bool                                                                           collectBeforeSubmit = true);
373
374         bool                                            iterateVerifyResults                    (IterateCommonVariables&                                        variables,
375                                                                                                                                          ut::UpdatablePixelBufferAccessPtr      programResult,
376                                                                                                                                          ut::UpdatablePixelBufferAccessPtr      referenceResult);
377
378         Move<VkCommandBuffer>           createCmdBuffer                                 (void);
379
380         void                                            commandBindPipeline                             (VkCommandBuffer                                                        commandBuffer,
381                                                                                                                                  VkPipeline                                                                     pipeline);
382
383         void                                            commandBindVertexAttributes             (VkCommandBuffer                                                        commandBuffer,
384                                                                                                                                  const ut::BufferHandleAllocSp&                         vertexAttributesBuffer);
385
386         void                                            commandBindDescriptorSets               (VkCommandBuffer                                                        commandBuffer,
387                                                                                                                                  VkPipelineLayout                                                       pipelineLayout,
388                                                                                                                                  VkDescriptorSet                                                        descriptorSet,
389                                                                                                                                  deUint32                                                                       descriptorSetIndex);
390
391         void                                            commandReadFrameBuffer                  (ut::BufferHandleAllocSp&                                       content,
392                                                                                                                                  VkCommandBuffer                                                        commandBuffer,
393                                                                                                                                  const ut::FrameBufferSp&                                       frameBuffer);
394         ut::UpdatablePixelBufferAccessPtr
395                                                                 commandReadFrameBuffer                  (VkCommandBuffer                                                        commandBuffer,
396                                                                                                                                  const ut::FrameBufferSp&                                       frameBuffer);
397
398         Move<VkFence>                           commandSubmit                                   (VkCommandBuffer                                                        commandBuffer);
399
400         virtual bool                            verifyVertexWriteResults                (IterateCommonVariables&                                        variables);
401
402 protected:
403         virtual tcu::TestStatus         iterate                                                 (void);
404
405 protected:
406         const VkDevice                          m_vkd;
407         const DeviceInterface&          m_vki;
408         Allocator&                                      m_allocator;
409         const VkQueue                           m_queue;
410         const deUint32                          m_queueFamilyIndex;
411         const Move<VkCommandPool>       m_commandPool;
412         const VkFormat                          m_colorFormat;
413         const TestParams                        m_testParams;
414         static const tcu::Vec4          m_clearColor;
415         const std::vector<float>        m_colorScheme;
416         const deUint32                          m_schemeSize;
417
418 private:
419
420         Move<VkPipeline>                        createGraphicsPipeline                  (VkPipelineLayout                                                       pipelineLayout,
421                                                                                                                                  VkRenderPass                                                           renderPass);
422
423         Move<VkPipeline>                        createComputePipeline                   (VkPipelineLayout                                                       pipelineLayout);
424
425         int                                                     constructShaderModules                  (void);
426
427         static std::vector<float>       createColorScheme();
428
429         Move<VkShaderModule>            m_vertexModule;
430         Move<VkShaderModule>            m_fragmentModule;
431         Move<VkShaderModule>            m_computeModule;
432 };
433 const tcu::Vec4 CommonDescriptorInstance::m_clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
434
435 void DescriptorEnumerator::init (const vkt::Context& context, deUint32 vertexCount, deUint32 availableDescriptorCount)
436 {
437         const VkDevice                                  device = context.getDevice();
438         const DeviceInterface&                  deviceInterface = context.getDeviceInterface();
439
440         const VkFormat                                  imageFormat = VK_FORMAT_R32G32B32A32_SINT;
441         typedef ut::mapVkFormat2Type<imageFormat>::type pixelType;
442         const VkDeviceSize                              dataSize = vertexCount * sizeof(pixelType);
443         const std::vector<deUint32>             primes = ut::generatePrimes(availableDescriptorCount);
444         const deUint32                                  primeCount = static_cast<deUint32>(primes.size());
445
446         std::vector<pixelType>  data(vertexCount);
447         // e.g. 2,3,5,7,11,13,2,3,5,7,...
448         for (deUint32 idx = 0; idx < vertexCount; ++idx)
449         {
450                 data[idx].x() = static_cast<pixelType::Element>(primes[idx % primeCount]);
451                 data[idx].y() = static_cast<pixelType::Element>(idx);
452         }
453
454         bufferSize = ut::createBufferAndBind(buffer, context, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, dataSize);
455         deMemcpy(buffer->alloc->getHostPtr(), data.data(), static_cast<size_t>(dataSize));
456
457         const VkBufferViewCreateInfo bufferViewCreateInfo =
458         {
459                 VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,              // sType
460                 DE_NULL,                                                                                // pNext
461                 0u,                                                                                             // flags
462                 *(buffer.get()->buffer),                                                // buffer
463                 imageFormat,                                                                    // format
464                 0u,                                                                                             // offset
465                 bufferSize,                                                                             // range
466         };
467
468         bufferView = ut::BufferViewSp(new Move<VkBufferView>(vk::createBufferView(deviceInterface, device, &bufferViewCreateInfo)));
469
470         const VkDescriptorSetLayoutBinding      binding =
471         {
472                 BINDING_DescriptorEnumerator,                                   // binding
473                 VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,                // descriptorType
474                 1u,                                                                                             // descriptorCount
475                 VK_SHADER_STAGE_ALL,                                                    // stageFlags
476                 DE_NULL,                                                                                // pImmutableSamplers
477         };
478
479         const VkDescriptorSetLayoutCreateInfo   layoutCreateInfo =
480         {
481                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
482                 DE_NULL,                                                                                // pNext
483                 0u,                                                                                             // flags
484                 1u,                                                                                             // bindingCount
485                 &binding,                                                                               // pBindings
486         };
487
488         descriptorSetLayout = vk::createDescriptorSetLayout(deviceInterface, device, &layoutCreateInfo);
489         descriptorPool = DescriptorPoolBuilder().addType(binding.descriptorType)
490                 .build(deviceInterface, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
491
492         const VkDescriptorSetAllocateInfo       dsAllocInfo =
493         {
494                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // sType
495                 DE_NULL,                                                                                // pNext
496                 *descriptorPool,                                                                // descriptorPool
497                 1u,                                                                                             // descriptorSetCount
498                 &(*descriptorSetLayout)                                                 // pSetLayouts
499         };
500
501         descriptorSet = vk::allocateDescriptorSet(deviceInterface, device, &dsAllocInfo);
502 }
503
504 void DescriptorEnumerator::update (const vkt::Context& context)
505 {
506         const VkDescriptorBufferInfo bufferInfo =
507         {
508                 *(buffer.get()->buffer),                                        // buffer
509                 0u,                                                                                     // offset
510                 bufferSize,                                                                     // range
511         };
512
513         const VkWriteDescriptorSet writeInfo =
514         {
515                 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
516                 DE_NULL,                                                                        // pNext
517                 *descriptorSet,                                                         // dstSet
518                 BINDING_DescriptorEnumerator,                           // dstBinding
519                 0u,                                                                                     // dstArrayElement
520                 1u,                                                                                     // descriptorCount
521                 VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,        // descriptorType
522                 DE_NULL,                                                                        // pImageInfo
523                 &bufferInfo,                                                            // pBufferInfo
524                 &(**bufferView),                                                        // pTexelBufferView
525         };
526
527         context.getDeviceInterface().updateDescriptorSets(context.getDevice(), 1u, &writeInfo, 0u, DE_NULL);
528 }
529
530 CommonDescriptorInstance::CommonDescriptorInstance                                      (Context&                                                               context,
531                                                                                                                                         const TestParams&                                               testParams)
532         : TestInstance          (context)
533         , m_vkd                         (context.getDevice())
534         , m_vki                         (context.getDeviceInterface())
535         , m_allocator           (context.getDefaultAllocator())
536         , m_queue                       (context.getUniversalQueue())
537         , m_queueFamilyIndex(context.getUniversalQueueFamilyIndex())
538         , m_commandPool         (vk::createCommandPool(m_vki, m_vkd, (VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT), m_queueFamilyIndex))
539         , m_colorFormat         (VK_FORMAT_R32G32B32A32_SFLOAT)
540         , m_testParams          (testParams)
541         , m_colorScheme         (createColorScheme())
542         , m_schemeSize          (static_cast<deUint32>(m_colorScheme.size()))
543 {
544 }
545
546 deUint32 CommonDescriptorInstance::computeAvailableDescriptorCount      (VkDescriptorType                                               descriptorType,
547                                                                                                                                          bool                                                                   reserveUniformTexelBuffer) const
548 {
549         DE_UNREF(descriptorType);
550         const deUint32 vertexCount = m_testParams.frameResolution.width * m_testParams.frameResolution.height;
551         const deUint32 availableDescriptorsOnDevice = ut::DeviceProperties(m_context).computeMaxPerStageDescriptorCount(m_testParams.descriptorType, m_testParams.updateAfterBind, reserveUniformTexelBuffer);
552         return deMinu32(deMinu32(vertexCount, availableDescriptorsOnDevice), MAX_DESCRIPTORS);
553 }
554
555 Move<VkDescriptorSetLayout>     CommonDescriptorInstance::createDescriptorSetLayout (bool                                               reserveUniformTexelBuffer,
556                                                                                                                                                                  deUint32&                                      descriptorCount) const
557 {
558         descriptorCount = computeAvailableDescriptorCount(m_testParams.descriptorType, reserveUniformTexelBuffer);
559
560         bool optional = (m_testParams.additionalDescriptorBinding != BINDING_Undefined) && (m_testParams.additionalDescriptorType != VK_DESCRIPTOR_TYPE_UNDEFINED);
561
562         const VkShaderStageFlags bindingStageFlags = (m_testParams.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) ?
563                                                                                                         VkShaderStageFlags{VK_SHADER_STAGE_FRAGMENT_BIT} : m_testParams.stageFlags;
564
565         const VkDescriptorSetLayoutBinding      bindings[] =
566         {
567                 {
568                         m_testParams.descriptorBinding,                         // binding
569                         m_testParams.descriptorType,                            // descriptorType
570                         descriptorCount,                                                        // descriptorCount
571                         bindingStageFlags,                                                      // stageFlags
572                         DE_NULL,                                                                        // pImmutableSamplers
573                 },
574                 {
575                         m_testParams.additionalDescriptorBinding,       // binding
576                         m_testParams.additionalDescriptorType,          // descriptorType
577                         1,                                                                                      // descriptorCount
578                         bindingStageFlags,                                                      // stageFlags
579                         DE_NULL,                                                                        // pImmutableSamplers
580                 }
581         };
582
583         const VkDescriptorBindingFlags  bindingFlagUpdateAfterBind =
584                 m_testParams.updateAfterBind ? VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT : 0;
585
586         const VkDescriptorBindingFlags bindingFlags[] =
587         {
588                 VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | bindingFlagUpdateAfterBind,
589                 VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | bindingFlagUpdateAfterBind
590         };
591
592         const VkDescriptorSetLayoutBindingFlagsCreateInfo       bindingCreateInfo =
593         {
594                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
595                 DE_NULL,
596                 optional ? 2u : 1u,     // bindingCount
597                 bindingFlags,           // pBindingFlags
598         };
599
600         const VkDescriptorSetLayoutCreateFlags  layoutCreateFlags =
601                 m_testParams.updateAfterBind ? VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT : 0;
602
603         const VkDescriptorSetLayoutCreateInfo   layoutCreateInfo =
604         {
605                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
606                 &bindingCreateInfo,             // pNext
607                 layoutCreateFlags,              // flags
608                 optional ? 2u : 1u,             // bindingCount
609                 bindings,                               // pBindings
610         };
611
612         return vk::createDescriptorSetLayout(m_vki, m_vkd, &layoutCreateInfo);
613 }
614
615 Move<VkDescriptorPool>  CommonDescriptorInstance::createDescriptorPool (deUint32                                                        descriptorCount) const
616 {
617         const VkDescriptorPoolCreateFlags pcf = m_testParams.updateAfterBind ? VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT : 0;
618
619         DescriptorPoolBuilder builder;
620
621         builder.addType(m_testParams.descriptorType, descriptorCount);
622
623         if (m_testParams.additionalDescriptorType != VK_DESCRIPTOR_TYPE_UNDEFINED && m_testParams.additionalDescriptorBinding != BINDING_Undefined)
624         {
625                 builder.addType(m_testParams.additionalDescriptorType, 1);
626         }
627
628         return builder.build(m_vki, m_vkd, (VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT | pcf), 1u);
629 }
630
631 Move<VkDescriptorSet> CommonDescriptorInstance::createDescriptorSet     (VkDescriptorPool                                               dsPool,
632                                                                                                                                          VkDescriptorSetLayout                                  dsLayout) const
633 {
634         const VkDescriptorSetAllocateInfo       dsAllocInfo =
635         {
636                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,         // sType;
637                 DE_NULL,                                                                                        // pNext;
638                 dsPool,                                                                                         // descriptorPool;
639                 1u,                                                                                                     // descriptorSetCount
640                 &dsLayout                                                                                       // pSetLayouts
641         };
642
643         return vk::allocateDescriptorSet(m_vki, m_vkd, &dsAllocInfo);
644 }
645
646 void CommonDescriptorInstance::createVertexAttributeBuffer                      (ut::BufferHandleAllocSp&                               buffer,
647                                                                                                                                          deUint32                                                               availableDescriptorCount) const
648 {
649         float                                           xSize                   = 0.0f;
650         float                                           ySize                   = 0.0f;
651
652         const deUint32                          invocationCount = m_testParams.frameResolution.width * m_testParams.frameResolution.height;
653         const std::vector<Vec4>         vertices                = ut::createVertices(m_testParams.frameResolution.width, m_testParams.frameResolution.height, xSize, ySize);
654         const std::vector<deUint32>     primes                  = ut::generatePrimes(availableDescriptorCount);
655         const deUint32                          primeCount              = static_cast<deUint32>(primes.size());
656
657         std::vector<attributes> data(vertices.size());
658         std::transform(vertices.begin(), vertices.end(), data.begin(), attributes());
659
660         for (deUint32 invIdx = 0; invIdx < invocationCount; ++invIdx)
661         {
662                 // r: 2,3,5,7,11,13,2,3,5,7,...
663                 data[invIdx].index.x() = primes[invIdx % primeCount];
664
665                 // b: x index in texel coordinate
666                 data[invIdx].index.z() = invIdx % m_testParams.frameResolution.width;
667
668                 //a: y index in texel coordinate
669                 data[invIdx].index.w() = invIdx / m_testParams.frameResolution.width;
670         }
671
672         // g: 0,0,2,3,0,5,0,7,0,0,0,11,0,13,...
673         for (deUint32 primeIdx = 0; primeIdx < primeCount; ++primeIdx)
674         {
675                 const deUint32 prime = primes[primeIdx];
676                 DE_ASSERT(prime < invocationCount);
677                 data[prime].index.y() = prime;
678         }
679
680         const VkDeviceSize              dataSize = data.size() * sizeof(attributes);
681
682         VkDeviceSize                    deviceSize = ut::createBufferAndBind(buffer, m_context, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, dataSize);
683
684         deMemcpy(buffer->alloc->getHostPtr(), data.data(), static_cast<size_t>(deviceSize));
685
686         vk::flushAlloc(m_vki, m_vkd, *buffer->alloc);
687 }
688
689 std::string CommonDescriptorInstance::substBinding                                      (deUint32                                                               binding,
690                                                                                                                                          const char*                                                    str,
691                                                                                                                                          deUint32                                                               count,
692                                                                                                                                          const char*                                                    name)
693 {
694         std::map<std::string, std::string> vars;
695         vars["?"]       = de::toString(binding);
696         vars["*"]       = (0 == count)          ? ""            : de::toString(count);
697         vars["VAR"]     = (DE_NULL == name)     ? "data"        : name;
698         return tcu::StringTemplate(str).specialize(vars);
699 }
700
701 const char* CommonDescriptorInstance::getVertexShaderProlog                     (void)
702 {
703         return
704                 "layout(location = 0) in  vec4  in_position;    \n"
705                 "layout(location = 1) in  vec2  in_normalpos;   \n"
706                 "layout(location = 2) in  ivec4 index;                  \n"
707                 "layout(location = 0) out vec4  position;       \n"
708                 "layout(location = 1) out vec2  normalpos;      \n"
709                 "layout(location = 2) out int   vIndex;         \n"
710                 "layout(location = 3) out int   rIndex;         \n"
711                 "layout(location = 4) out int   gIndex;         \n"
712                 "layout(location = 5) out int   bIndex;         \n"
713                 "layout(location = 6) out int   aIndex;         \n"
714                 "void main()                                                    \n"
715                 "{                                                                              \n"
716                 "    gl_PointSize = 0.2f;                               \n"
717                 "    position = in_position;                    \n"
718                 "    normalpos = in_normalpos;                  \n"
719                 "    gl_Position = position;                    \n"
720                 "    vIndex = gl_VertexIndex;                   \n"
721                 "    rIndex = index.x;                                  \n"
722                 "    gIndex = index.y;                                  \n"
723                 "    bIndex = index.z;                                  \n"
724                 "    aIndex = index.w;                                  \n";
725 }
726
727 const char* CommonDescriptorInstance::getFragmentShaderProlog           (void)
728 {
729         return
730                 "layout(location = 0) out vec4     FragColor;   \n"
731                 "layout(location = 0) in flat vec4 position;    \n"
732                 "layout(location = 1) in flat vec2 normalpos;   \n"
733                 "layout(location = 2) in flat int  vIndex;              \n"
734                 "layout(location = 3) in flat int  rIndex;              \n"
735                 "layout(location = 4) in flat int  gIndex;              \n"
736                 "layout(location = 5) in flat int  bIndex;              \n"
737                 "layout(location = 6) in flat int  aIndex;              \n"
738                 "void main()                                                                    \n"
739                 "{                                                                                              \n";
740 }
741
742 const char* CommonDescriptorInstance::getShaderEpilog                           (void)
743 {
744         return "}                                                                                       \n";
745 }
746
747 int     CommonDescriptorInstance::constructShaderModules                                (void)
748 {
749         int                                                             result  = 0;
750         tcu::TestLog&                                   log             = m_context.getTestContext().getLog();
751
752         if (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT)
753         {
754                 ++result;
755                 const std::string name = ut::buildShaderName(VK_SHADER_STAGE_COMPUTE_BIT, m_testParams.descriptorType, m_testParams.updateAfterBind, m_testParams.calculateInLoop, m_testParams.minNonUniform, false);
756                 m_computeModule = vk::createShaderModule(m_vki, m_vkd, m_context.getBinaryCollection().get(name), (VkShaderModuleCreateFlags)0);
757         }
758         if (m_testParams.stageFlags & VK_SHADER_STAGE_FRAGMENT_BIT)
759         {
760                 ++result;
761                 const std::string name = ut::buildShaderName(VK_SHADER_STAGE_FRAGMENT_BIT, m_testParams.descriptorType, m_testParams.updateAfterBind, m_testParams.calculateInLoop, m_testParams.minNonUniform, m_testParams.allowVertexStoring);
762                 m_fragmentModule = vk::createShaderModule(m_vki, m_vkd, m_context.getBinaryCollection().get(name), (VkShaderModuleCreateFlags)0);
763                 log << tcu::TestLog::Message << "Finally used fragment shader: " << name << '\n' << tcu::TestLog::EndMessage;
764         }
765         if (m_testParams.stageFlags & VK_SHADER_STAGE_VERTEX_BIT)
766         {
767                 ++result;
768                 const std::string name = ut::buildShaderName(VK_SHADER_STAGE_VERTEX_BIT, m_testParams.descriptorType, m_testParams.updateAfterBind, m_testParams.calculateInLoop, m_testParams.minNonUniform, m_testParams.allowVertexStoring);
769                 m_vertexModule = vk::createShaderModule(m_vki, m_vkd, m_context.getBinaryCollection().get(name), (VkShaderModuleCreateFlags)0);
770                 log << tcu::TestLog::Message << "Finally used vertex shader: " << name << '\n' << tcu::TestLog::EndMessage;
771         }
772
773         DE_ASSERT(result > 0);
774
775         return result;
776 }
777
778 Move<VkRenderPass> CommonDescriptorInstance::createRenderPass           (const IterateCommonVariables&                  variables)
779 {
780         DE_UNREF(variables);
781         if ((m_testParams.stageFlags & VK_SHADER_STAGE_VERTEX_BIT) || (m_testParams.stageFlags & VK_SHADER_STAGE_FRAGMENT_BIT))
782         {
783                 // Use VK_ATTACHMENT_LOAD_OP_LOAD to make the utility function select initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
784                 return vk::makeRenderPass(m_vki, m_vkd, m_colorFormat, VK_FORMAT_UNDEFINED, VK_ATTACHMENT_LOAD_OP_LOAD);
785         }
786         return Move<VkRenderPass>();
787 }
788
789 VkPushConstantRange CommonDescriptorInstance::makePushConstantRange     (void) const
790 {
791         const VkPushConstantRange pcr =
792         {
793                 m_testParams.stageFlags,                                                        // stageFlags
794                 0u,                                                                                                     // offset
795                 static_cast<deUint32>(sizeof(push_constant))            // size
796         };
797         return pcr;
798 }
799
800 Move<VkPipelineLayout> CommonDescriptorInstance::createPipelineLayout (const std::vector<VkDescriptorSetLayout>&        descriptorSetLayouts) const
801 {
802         const VkPushConstantRange pcr = makePushConstantRange();
803
804         const VkPipelineLayoutCreateInfo createInfo =
805         {
806                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // sType
807                 DE_NULL,                                                                                        // pNext
808                 (VkPipelineLayoutCreateFlags)0,                                         // flags
809                 static_cast<deUint32>(descriptorSetLayouts.size()),     // setLayoutCount
810                 descriptorSetLayouts.data(),                                            // pSetLayouts;
811                 m_testParams.calculateInLoop ? 1u : 0u,                         // pushConstantRangeCount
812                 m_testParams.calculateInLoop ? &pcr : DE_NULL,          // pPushConstantRanges
813         };
814
815         return vk::createPipelineLayout(m_vki, m_vkd, &createInfo);
816 }
817
818 void CommonDescriptorInstance::createFramebuffer                                        (ut::FrameBufferSp&                                                     frameBuffer,
819                                                                                                                                          VkRenderPass                                                           renderPass,
820                                                                                                                                          const IterateCommonVariables&                          variables)
821 {
822         DE_UNREF(variables);
823         ut::createFrameBuffer(frameBuffer, m_context, m_testParams.frameResolution, m_colorFormat, renderPass);
824 }
825
826 Move<VkPipeline> CommonDescriptorInstance::createPipeline                       (VkPipelineLayout                                                       pipelineLayout,
827                                                                                                                                          VkRenderPass                                                           renderPass)
828 {       DE_ASSERT(VK_SHADER_STAGE_ALL != m_testParams.stageFlags);
829
830         constructShaderModules();
831
832         return (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT)
833                 ? createComputePipeline(pipelineLayout)
834                 : createGraphicsPipeline(pipelineLayout, renderPass);
835 }
836
837 Move<VkPipeline> CommonDescriptorInstance::createComputePipeline        (VkPipelineLayout                                                       pipelineLayout)
838 {
839         const VkPipelineShaderStageCreateInfo   shaderStaegCreateInfo =
840         {
841                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
842                 DE_NULL,                                                                // pNext
843                 (VkPipelineShaderStageCreateFlags)0,    // flags
844                 VK_SHADER_STAGE_COMPUTE_BIT,                    // stage
845                 *m_computeModule,                                               // module
846                 "main",                                                                 // pName
847                 (VkSpecializationInfo*)DE_NULL                  // pSpecializationInfo
848         };
849
850         const VkComputePipelineCreateInfo               pipelineCreateInfo =
851         {
852                 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
853                 DE_NULL,                                                                // pNext
854                 0u,                                                                             // flags
855                 shaderStaegCreateInfo,                                  // stage
856                 pipelineLayout,                                                 // layout
857                 (VkPipeline)0,                                                  // basePipelineHandle
858                 0u,                                                                             // basePipelineIndex
859         };
860         return vk::createComputePipeline(m_vki, m_vkd, (VkPipelineCache)0u, &pipelineCreateInfo);
861 }
862
863 Move<VkPipeline> CommonDescriptorInstance::createGraphicsPipeline       (VkPipelineLayout                                                       pipelineLayout,
864                                                                                                                                          VkRenderPass                                                           renderPass)
865 {
866         const VkVertexInputBindingDescription                   bindingDescriptions[] =
867         {
868                 {
869                         0u,                                                                                                     // binding
870                         sizeof(attributes),                                                                     // stride
871                         VK_VERTEX_INPUT_RATE_VERTEX,                                            // inputRate
872                 },
873         };
874
875         const VkVertexInputAttributeDescription                 attributeDescriptions[] =
876         {
877                 {
878                         0u,                                                                                                     // location
879                         0u,                                                                                                     // binding
880                         ut::mapType2vkFormat<attributes::vec4>::value,          // format
881                         0u                                                                                                      // offset
882                 },                                                                                                              // @in_position
883                 {
884                         1u,                                                                                                     // location
885                         0u,                                                                                                     // binding
886                         ut::mapType2vkFormat<attributes::vec2>::value,          // format
887                         static_cast<deUint32>(sizeof(attributes::vec4))         // offset
888                 },                                                                                                              // @normalpos
889                 {
890                         2u,                                                                                                     // location
891                         0u,                                                                                                     // binding
892                         ut::mapType2vkFormat<attributes::ivec4>::value,         // format
893                         static_cast<deUint32>(sizeof(attributes::vec2)
894                                                                 + sizeof(attributes::vec4))             // offset
895                 },                                                                                                              // @index
896         };
897
898         const VkPipelineVertexInputStateCreateInfo              vertexInputStateCreateInfo      =
899         {
900                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
901                 DE_NULL,
902                 (VkPipelineVertexInputStateCreateFlags)0,       // flags
903                 DE_LENGTH_OF_ARRAY(bindingDescriptions),        // vertexBindingDescriptionCount
904                 bindingDescriptions,                                            // pVertexBindingDescriptions
905                 DE_LENGTH_OF_ARRAY(attributeDescriptions),      // vertexAttributeDescriptionCount
906                 attributeDescriptions                                           // pVertexAttributeDescriptions
907         };
908
909         const   VkDynamicState                                                  dynamicStates[]                         =
910         {
911                 VK_DYNAMIC_STATE_SCISSOR
912         };
913
914         const VkPipelineDynamicStateCreateInfo                  dynamicStateCreateInfo =
915         {
916                 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,  // sType
917                 DE_NULL,                                                                                           // pNext
918                 0u,                                                                                                        // flags
919                 DE_LENGTH_OF_ARRAY(dynamicStates),                                         // dynamicStateCount
920                 dynamicStates                                                                              // pDynamicStates
921         };
922
923         const std::vector<VkViewport>   viewports       (1, makeViewport(m_testParams.frameResolution.width, m_testParams.frameResolution.height));
924         const std::vector<VkRect2D>             scissors        (1, makeRect2D(0u, 0u));
925
926         DE_ASSERT(m_vertexModule && m_fragmentModule);
927
928         return vk::makeGraphicsPipeline(
929                 m_vki,                                                                                  // vk
930                 m_vkd,                                                                                  // device
931                 pipelineLayout,                                                                 // pipelineLayout
932                 *m_vertexModule,                                                                // vertexShaderModule
933                 DE_NULL,                                                                                // tessellationControlModule
934                 DE_NULL,                                                                                // tessellationEvalModule
935                 DE_NULL,                                                                                // geometryShaderModule
936                 *m_fragmentModule,                                                              // fragmentShaderModule
937                 renderPass,                                                                             // renderPass
938                 viewports,                                                                              // viewports
939                 scissors,                                                                               // scissors
940                 VK_PRIMITIVE_TOPOLOGY_POINT_LIST,                               // topology
941                 0U,                                                                                             // subpass
942                 0U,                                                                                             // patchControlPoints
943                 &vertexInputStateCreateInfo,                                    // vertexInputStateCreateInfo
944                 nullptr,                                                                                // rasterizationStateCreateInfo
945                 nullptr,                                                                                // multisampleStateCreateInfo
946                 nullptr,                                                                                // depthStencilStateCreateInfo
947                 nullptr,                                                                                // colorBlendStateCreateInfo
948                 &dynamicStateCreateInfo);                                               // dynamicStateCreateInfo
949 }
950
951 VkDeviceSize CommonDescriptorInstance::createBuffers                            (std::vector<VkDescriptorBufferInfo>&           bufferInfos,
952                                                                                                                                          ut::BufferHandleAllocSp&                                       buffer,
953                                                                                                                                          deUint32                                                                       elementCount,
954                                                                                                                                          deUint32                                                                       elementSize,
955                                                                                                                                          VkDeviceSize                                                           alignment,
956                                                                                                                                          VkBufferUsageFlags                                                     bufferUsage)
957 {
958         const VkDeviceSize      roundedSize = deAlign64(elementSize, alignment);
959         VkDeviceSize            bufferSize      = ut::createBufferAndBind(buffer, m_context, bufferUsage, (roundedSize * elementCount));
960
961         for (deUint32 elementIdx = 0; elementIdx < elementCount; ++elementIdx)
962         {
963                 const VkDescriptorBufferInfo bufferInfo =
964                 {
965                         *buffer.get()->buffer,          //buffer;
966                         elementIdx * roundedSize,       //offset;
967                         elementSize,                            // range;
968
969                 };
970                 bufferInfos.push_back(bufferInfo);
971         }
972
973         return bufferSize;
974 }
975
976 VkDeviceSize CommonDescriptorInstance::createImages                                     (std::vector<ut::ImageHandleAllocSp>&           images,
977                                                                                                                                          std::vector<VkDescriptorBufferInfo>&           bufferInfos,
978                                                                                                                                          ut::BufferHandleAllocSp&                                       buffer,
979                                                                                                                                          VkBufferUsageFlags                                                     bufferUsage,
980                                                                                                                                          const VkExtent3D&                                                      imageExtent,
981                                                                                                                                          VkFormat                                                                       imageFormat,
982                                                                                                                                          VkImageLayout                                                          imageLayout,
983                                                                                                                                          deUint32                                                                       imageCount,
984                                                                                                                                          bool                                                                           withMipMaps)
985
986 {
987         const deUint32          imageSize       = ut::computeImageSize(imageExtent, imageFormat, withMipMaps);
988
989         const VkDeviceSize      bufferSize      = createBuffers(bufferInfos, buffer, imageCount, imageSize, sizeof(tcu::Vec4), bufferUsage);
990
991         for (deUint32 imageIdx = 0; imageIdx < imageCount; ++imageIdx)
992         {
993                 ut::ImageHandleAllocSp image;
994                 ut::createImageAndBind(image, m_context, imageFormat, imageExtent, imageLayout, withMipMaps);
995                 images.push_back(image);
996         }
997
998         return bufferSize;
999 }
1000
1001 void CommonDescriptorInstance::createBuffersViews                                       (std::vector<ut::BufferViewSp>&                         views,
1002                                                                                                                                          const std::vector<VkDescriptorBufferInfo>&     bufferInfos,
1003                                                                                                                                          VkFormat                                                                       format)
1004 {
1005         const deUint32 infoCount = static_cast<deUint32>(bufferInfos.size());
1006         for (deUint32 infoIdx = 0; infoIdx < infoCount; ++infoIdx)
1007         {
1008                 const VkDescriptorBufferInfo&   bufferInfo = bufferInfos[infoIdx];
1009                 const VkBufferViewCreateInfo    bufferViewInfo =
1010                 {
1011                         VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,      // sType
1012                         DE_NULL,                                                                        // pNext
1013                         (VkBufferViewCreateFlags)0,                                     // flags
1014                         bufferInfo.buffer,                                                      // buffer
1015                         format,                                                                         // format
1016                         bufferInfo.offset,                                                      // offset
1017                         bufferInfo.range                                                        // range;
1018                 };
1019                 views.push_back(ut::BufferViewSp(new Move<VkBufferView>(vk::createBufferView(m_vki, m_vkd, &bufferViewInfo))));
1020         }
1021 }
1022
1023 void CommonDescriptorInstance::createImagesViews                                        (std::vector<ut::ImageViewSp>&                          views,
1024                                                                                                                                          const std::vector<ut::ImageHandleAllocSp>&     images,
1025                                                                                                                                          VkFormat                                                                       format)
1026 {
1027         const deUint32 imageCount = static_cast<deUint32>(images.size());
1028         for (deUint32 imageIdx = 0; imageIdx < imageCount; ++imageIdx)
1029         {
1030                 const VkImageViewCreateInfo createInfo =
1031                 {
1032                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,       // sType
1033                         DE_NULL,                                                                        // pNext
1034                         (VkImageViewCreateFlags)0,                                      // flags
1035                         *images[imageIdx]->image,                                       // image
1036                         VK_IMAGE_VIEW_TYPE_2D,                                          // viewType
1037                         format,                                                                         // format
1038                         vk::makeComponentMappingRGBA(),                         // components
1039                         {
1040                                 VK_IMAGE_ASPECT_COLOR_BIT,                              // aspectMask
1041                                 (deUint32)0,                                                    // baseMipLevel
1042                                 images[imageIdx]->levels,                               // mipLevels
1043                                 (deUint32)0,                                                    // baseArrayLayer
1044                                 (deUint32)1u,                                                   // arraySize
1045                         },
1046                 };
1047                 views.push_back(ut::ImageViewSp(new Move<VkImageView>(vk::createImageView(m_vki, m_vkd, &createInfo))));
1048         }
1049 }
1050
1051 void CommonDescriptorInstance::copyBuffersToImages                                      (IterateCommonVariables&                                        variables)
1052 {
1053         const deUint32 infoCount = static_cast<deUint32>(variables.descriptorsBufferInfos.size());
1054         DE_ASSERT(variables.descriptorsImages.size() == infoCount);
1055         const VkPipelineStageFlagBits dstStageMask = (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT)
1056                 ? VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
1057                 : VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
1058         for (deUint32 infoIdx = 0; infoIdx < infoCount; ++infoIdx)
1059         {
1060                 ut::recordCopyBufferToImage(
1061                         *variables.commandBuffer,                                               // commandBuffer
1062                         m_vki,                                                                                  // interface
1063                         VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,                              // srcStageMask
1064                         dstStageMask,                                                                   // dstStageMask
1065                         variables.descriptorsBufferInfos[infoIdx],              // bufferInfo
1066                         *(variables.descriptorsImages[infoIdx]->image), // image
1067                         variables.descriptorsImages[infoIdx]->extent,   // imageExtent
1068                         variables.descriptorsImages[infoIdx]->format,   // imageFormat
1069                         VK_IMAGE_LAYOUT_UNDEFINED,                                              // oldImageLayout
1070                         VK_IMAGE_LAYOUT_GENERAL,                                                // newImageLayout
1071                         variables.descriptorsImages[infoIdx]->levels);  // mipLevelCount
1072         }
1073 }
1074
1075 void CommonDescriptorInstance::copyImagesToBuffers                                      (IterateCommonVariables&                                        variables)
1076 {
1077         const deUint32 infoCount = static_cast<deUint32>(variables.descriptorsBufferInfos.size());
1078         DE_ASSERT(variables.descriptorsImages.size() == infoCount);
1079         const VkPipelineStageFlagBits srcStageMask = (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT)
1080                 ? VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
1081                 : VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
1082
1083         for (deUint32 infoIdx = 0; infoIdx < infoCount; ++infoIdx)
1084         {
1085                 ut::recordCopyImageToBuffer(
1086                         *variables.commandBuffer,                                               // commandBuffer
1087                         m_vki,                                                                                  // interface
1088                         srcStageMask,                                                                   // srcStageMask
1089                         VK_PIPELINE_STAGE_HOST_BIT,                                             // dstStageMask
1090                         *(variables.descriptorsImages[infoIdx]->image), // image
1091                         variables.descriptorsImages[infoIdx]->extent,   // imageExtent
1092                         variables.descriptorsImages[infoIdx]->format,   // imageFormat
1093                         VK_IMAGE_LAYOUT_GENERAL,                                                // oldImageLayout
1094                         VK_IMAGE_LAYOUT_GENERAL,                                                // newImageLayout
1095                         variables.descriptorsBufferInfos[infoIdx]);             // bufferInfo
1096         }
1097 }
1098
1099 PixelBufferAccess CommonDescriptorInstance::getPixelAccess                      (deUint32                                                                       imageIndex,
1100                                                                                                                                          const VkExtent3D&                                                      imageExtent,
1101                                                                                                                                          VkFormat                                                                       imageFormat,
1102                                                                                                                                          const std::vector<VkDescriptorBufferInfo>&     bufferInfos,
1103                                                                                                                                          const ut::BufferHandleAllocSp&                         buffer,
1104                                                                                                                                          deUint32                                                                       mipLevel) const
1105 {
1106         DE_ASSERT(bufferInfos[imageIndex].buffer == *buffer.get()->buffer);
1107         DE_ASSERT(ut::computeImageSize(imageExtent, imageFormat, true, (mipLevel ? ut::maxDeUint32 : 0)) <= bufferInfos[imageIndex].range);
1108         DE_ASSERT(imageExtent.width             >> mipLevel);
1109         DE_ASSERT(imageExtent.height    >> mipLevel);
1110
1111         deUint32 mipOffset = 0;
1112
1113         for (deUint32 level = 0; mipLevel && level < mipLevel; ++level)
1114         {
1115                 mipOffset += ut::computeImageSize(imageExtent, imageFormat, true, level);
1116         }
1117
1118         unsigned char* hostPtr  = static_cast<unsigned char*>(buffer->alloc->getHostPtr());
1119         unsigned char* data = hostPtr + bufferInfos[imageIndex].offset + mipOffset;
1120         return tcu::PixelBufferAccess(vk::mapVkFormat(imageFormat), (imageExtent.width >> mipLevel), (imageExtent.height >> mipLevel), imageExtent.depth, data);
1121 }
1122
1123 void CommonDescriptorInstance::updateDescriptors                                        (IterateCommonVariables&                                        variables)
1124 {
1125         const std::vector<deUint32>     primes = ut::generatePrimes(variables.availableDescriptorCount);
1126         const deUint32                          primeCount = static_cast<deUint32>(primes.size());
1127
1128         for (deUint32 primeIdx = 0; primeIdx < primeCount; ++primeIdx)
1129         {
1130                 const VkDescriptorBufferInfo*   pBufferInfo                     = DE_NULL;
1131                 const VkDescriptorImageInfo*    pImageInfo                      = DE_NULL;
1132                 const VkBufferView*                             pTexelBufferView        = DE_NULL;
1133
1134                 VkDescriptorImageInfo           imageInfo =
1135                 {
1136                         static_cast<VkSampler>(0),
1137                         static_cast<VkImageView>(0),
1138                         VK_IMAGE_LAYOUT_GENERAL
1139                 };
1140
1141                 switch (m_testParams.descriptorType)
1142                 {
1143                 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1144                 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1145                 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1146                 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1147                 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1148                 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1149                         {
1150                                 pBufferInfo = &variables.descriptorsBufferInfos[primeIdx];
1151                                 switch (m_testParams.descriptorType)
1152                                 {
1153                                 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1154                                 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1155                                         pTexelBufferView = &(**variables.descriptorsBufferViews[primeIdx]);
1156                                         break;
1157                                 default:
1158                                         break;
1159                                 }
1160                         }
1161                         break;
1162
1163                 case VK_DESCRIPTOR_TYPE_SAMPLER:
1164                         imageInfo.sampler = **variables.descriptorSamplers[primeIdx];
1165                         pImageInfo = &imageInfo;
1166                         break;
1167
1168                 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1169                 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1170                 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1171                         imageInfo.imageView = **variables.descriptorImageViews[primeIdx];
1172                         pImageInfo = &imageInfo;
1173                         break;
1174
1175                 default:        break;
1176                 }
1177
1178                 const VkWriteDescriptorSet writeInfo =
1179                 {
1180                         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,                 // sType
1181                         DE_NULL,                                                                                // pNext
1182                         *variables.descriptorSet,                                               // descriptorSet
1183                         m_testParams.descriptorBinding,                                 // descriptorBinding;
1184                         primes[primeIdx],                                                               // elementIndex
1185                         1u,                                                                                             // descriptorCount
1186                         m_testParams.descriptorType,                                    // descriptorType
1187                         pImageInfo,                                                                             // pImageInfo
1188                         pBufferInfo,                                                                    // pBufferInfo
1189                         pTexelBufferView                                                                // pTexelBufferView
1190                 };
1191
1192                 m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, DE_NULL);
1193         }
1194 }
1195
1196 void CommonDescriptorInstance::iterateCommandSetup                                      (IterateCommonVariables&                                        variables)
1197 {
1198         variables.dataAlignment                         = 0;
1199
1200         variables.renderArea.offset.x           = 0;
1201         variables.renderArea.offset.y           = 0;
1202         variables.renderArea.extent.width       = m_testParams.frameResolution.width;
1203         variables.renderArea.extent.height      = m_testParams.frameResolution.height;
1204
1205         variables.vertexCount                           = m_testParams.frameResolution.width * m_testParams.frameResolution.height;
1206
1207         variables.lowerBound                            = 0;
1208         variables.upperBound                            = variables.vertexCount;
1209
1210         variables.descriptorSetLayout           = createDescriptorSetLayout(m_testParams.calculateInLoop, variables.availableDescriptorCount);
1211         variables.validDescriptorCount          = ut::computePrimeCount(variables.availableDescriptorCount);
1212         variables.descriptorPool                        = createDescriptorPool(variables.availableDescriptorCount);
1213         variables.descriptorSet                         = createDescriptorSet(*variables.descriptorPool, *variables.descriptorSetLayout);
1214
1215         std::vector<VkDescriptorSetLayout>      descriptorSetLayouts;
1216         descriptorSetLayouts.push_back(*variables.descriptorSetLayout);
1217         if (m_testParams.calculateInLoop)
1218         {
1219                 variables.descriptorEnumerator.init(m_context, variables.vertexCount, variables.availableDescriptorCount);
1220                 descriptorSetLayouts.push_back(*variables.descriptorEnumerator.descriptorSetLayout);
1221         }
1222
1223         variables.pipelineLayout                        = createPipelineLayout(descriptorSetLayouts);
1224
1225         createAndPopulateDescriptors            (variables);
1226
1227         variables.renderPass                            = createRenderPass(variables);
1228         variables.pipeline                                      = createPipeline(*variables.pipelineLayout, *variables.renderPass);
1229
1230         variables.commandBuffer                         = createCmdBuffer();
1231
1232         if ((m_testParams.stageFlags & VK_SHADER_STAGE_VERTEX_BIT) || (m_testParams.stageFlags & VK_SHADER_STAGE_FRAGMENT_BIT))
1233         {
1234                 createVertexAttributeBuffer             (variables.vertexAttributesBuffer, variables.availableDescriptorCount);
1235                 createFramebuffer                               (variables.frameBuffer, *variables.renderPass, variables);
1236         }
1237
1238         if (m_testParams.calculateInLoop)
1239         {
1240                 variables.descriptorEnumerator.update(m_context);
1241         }
1242
1243         if (!m_testParams.updateAfterBind)
1244         {
1245                 updateDescriptors                               (variables);
1246         }
1247
1248 }
1249
1250 void CommonDescriptorInstance::iterateCommandBegin                                      (IterateCommonVariables&                                        variables,      bool firstPass)
1251 {
1252         vk::beginCommandBuffer                          (m_vki, *variables.commandBuffer);
1253
1254         // Clear color attachment, and transition it to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
1255         if ((m_testParams.stageFlags & VK_SHADER_STAGE_VERTEX_BIT) || (m_testParams.stageFlags & VK_SHADER_STAGE_FRAGMENT_BIT))
1256         {
1257                 if (firstPass)
1258                 {
1259                         const VkImageMemoryBarrier preImageBarrier =
1260                         {
1261                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                         // VkStructureType              sType
1262                                 DE_NULL,                                                                                        // const void*                  pNext
1263                                 0u,                                                                                                     // VkAccessFlags                srcAccessMask
1264                                 VK_ACCESS_TRANSFER_WRITE_BIT,                                           // VkAccessFlags                dstAccessMask
1265                                 VK_IMAGE_LAYOUT_UNDEFINED,                                                      // VkImageLayout                oldLayout
1266                                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                           // VkImageLayout                newLayout
1267                                 VK_QUEUE_FAMILY_IGNORED,                                                        // uint32_t                             srcQueueFamilyIndex
1268                                 VK_QUEUE_FAMILY_IGNORED,                                                        // uint32_t                             dstQueueFamilyIndex
1269                                 *variables.frameBuffer->image->image,                           // VkImage                              image
1270                                 {
1271                                         VK_IMAGE_ASPECT_COLOR_BIT,                              // VkImageAspectFlags   aspectMask
1272                                         0u,                                                                             // uint32_t                             baseMipLevel
1273                                         VK_REMAINING_MIP_LEVELS,                                // uint32_t                             mipLevels,
1274                                         0u,                                                                             // uint32_t                             baseArray
1275                                         VK_REMAINING_ARRAY_LAYERS,                              // uint32_t                             arraySize
1276                                 }
1277                         };
1278
1279                         m_vki.cmdPipelineBarrier(*variables.commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1280                                                                         (VkDependencyFlags)0,
1281                                                                         0, (const VkMemoryBarrier*)DE_NULL,
1282                                                                         0, (const VkBufferMemoryBarrier*)DE_NULL,
1283                                                                         1, &preImageBarrier);
1284
1285                         const VkClearColorValue clearColorValue         = makeClearValueColor(m_clearColor).color;
1286
1287                         m_vki.cmdClearColorImage(*variables.commandBuffer, *variables.frameBuffer->image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColorValue, 1, &preImageBarrier.subresourceRange);
1288
1289                         const VkImageMemoryBarrier postImageBarrier =
1290                         {
1291                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                         // VkStructureType              sType
1292                                 DE_NULL,                                                                                        // const void*                  pNext
1293                                 VK_ACCESS_TRANSFER_WRITE_BIT,                                           // VkAccessFlags                srcAccessMask
1294                                 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags            dstAccessMask
1295                                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                           // VkImageLayout                oldLayout
1296                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                newLayout
1297                                 VK_QUEUE_FAMILY_IGNORED,                                                        // uint32_t                             srcQueueFamilyIndex
1298                                 VK_QUEUE_FAMILY_IGNORED,                                                        // uint32_t                             dstQueueFamilyIndex
1299                                 *variables.frameBuffer->image->image,                           // VkImage                              image
1300                                 {
1301                                         VK_IMAGE_ASPECT_COLOR_BIT,                              // VkImageAspectFlags   aspectMask
1302                                         0u,                                                                             // uint32_t                             baseMipLevel
1303                                         VK_REMAINING_MIP_LEVELS,                                // uint32_t                             mipLevels,
1304                                         0u,                                                                             // uint32_t                             baseArray
1305                                         VK_REMAINING_ARRAY_LAYERS,                              // uint32_t                             arraySize
1306                                 }
1307                         };
1308
1309                         m_vki.cmdPipelineBarrier(*variables.commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1310                                                                         (VkDependencyFlags)0,
1311                                                                         0, (const VkMemoryBarrier*)DE_NULL,
1312                                                                         0, (const VkBufferMemoryBarrier*)DE_NULL,
1313                                                                         1, &postImageBarrier);
1314
1315                 }
1316         }
1317
1318         if (m_testParams.calculateInLoop)
1319         {
1320                 deRandom rnd;
1321                 deRandom_init(&rnd, static_cast<deUint32>(m_testParams.descriptorType));
1322                 const deUint32 quarter = variables.vertexCount / 4;
1323
1324                 variables.lowerBound                    = deRandom_getUint32(&rnd) % quarter;
1325                 variables.upperBound                    = (deRandom_getUint32(&rnd) % quarter) + (3 * quarter);
1326
1327                 const push_constant pc =
1328                 {
1329                         static_cast<deInt32>(variables.lowerBound),
1330                         static_cast<deInt32>(variables.upperBound)
1331                 };
1332
1333                 m_vki.cmdPushConstants(*variables.commandBuffer, *variables.pipelineLayout, m_testParams.stageFlags, 0u, static_cast<deUint32>(sizeof(pc)), &pc);
1334         }
1335
1336         if ((m_testParams.stageFlags & VK_SHADER_STAGE_VERTEX_BIT) || (m_testParams.stageFlags & VK_SHADER_STAGE_FRAGMENT_BIT))
1337         {
1338                 commandBindVertexAttributes             (*variables.commandBuffer, variables.vertexAttributesBuffer);
1339         }
1340
1341         if (m_testParams.calculateInLoop)
1342         {
1343                 commandBindDescriptorSets(*variables.commandBuffer, *variables.pipelineLayout, *variables.descriptorEnumerator.descriptorSet, 1);
1344         }
1345
1346         if (!ut::isDynamicDescriptor(m_testParams.descriptorType))
1347         {
1348                 commandBindDescriptorSets               (*variables.commandBuffer, *variables.pipelineLayout, *variables.descriptorSet, 0);
1349         }
1350
1351         commandBindPipeline                                     (*variables.commandBuffer, *variables.pipeline);
1352 }
1353
1354 tcu::TestStatus CommonDescriptorInstance::iterate                                       (void)
1355 {
1356         IterateCommonVariables  v;
1357         ut::UpdatablePixelBufferAccessPtr       programResult;
1358         ut::UpdatablePixelBufferAccessPtr       referenceResult;
1359
1360         bool firstPass = true;
1361
1362         iterateCommandSetup             (v);
1363
1364         v.renderArea.extent.width       = m_testParams.frameResolution.width/4;
1365         v.renderArea.extent.height      = m_testParams.frameResolution.height/4;
1366
1367         for (int x = 0; x < 4; x++)
1368                 for (int y= 0; y < 4; y++)
1369                 {
1370                         iterateCommandBegin             (v, firstPass);
1371
1372                         if (true == firstPass && true == m_testParams.copyBuffersToImages)
1373                         {
1374                                 copyBuffersToImages     (v);
1375                         }
1376
1377                         firstPass = false;
1378
1379                         if (true == m_testParams.updateAfterBind)
1380                         {
1381                                 updateDescriptors       (v);
1382                         }
1383
1384                         v.renderArea.offset.x           = x * m_testParams.frameResolution.width/4;
1385                         v.renderArea.offset.y           = y * m_testParams.frameResolution.height/4;
1386
1387                         vk::VkRect2D scissor = makeRect2D(v.renderArea.offset.x, v.renderArea.offset.y, v.renderArea.extent.width, v.renderArea.extent.height);
1388                         m_vki.cmdSetScissor(*v.commandBuffer, 0u, 1u, &scissor);
1389
1390                         vk::beginRenderPass             (m_vki, *v.commandBuffer, *v.renderPass, *v.frameBuffer->buffer, v.renderArea, m_clearColor);
1391                         m_vki.cmdDraw                   (*v.commandBuffer, v.vertexCount, 1u, 0u, 0u);
1392                         vk::endRenderPass               (m_vki, *v.commandBuffer);
1393
1394                         iterateCommandEnd(v, programResult, referenceResult);
1395                         programResult->invalidate();
1396                 }
1397
1398         return ( iterateVerifyResults(v, programResult, referenceResult) ? tcu::TestStatus::pass : tcu::TestStatus::fail)("");
1399 }
1400
1401 std::vector<float> CommonDescriptorInstance::createColorScheme          (void)
1402 {
1403         std::vector<float> cs;
1404         int divider = 2;
1405         for (int i = 0; i < 10; ++i)
1406         {
1407                 cs.push_back(1.0f / float(divider));
1408                 divider *= 2;
1409         }
1410         return cs;
1411 }
1412
1413 void CommonDescriptorInstance::iterateCommandEnd                                        (IterateCommonVariables&                                        variables,
1414                                                                                                                                          ut::UpdatablePixelBufferAccessPtr&     programResult,
1415                                                                                                                                          ut::UpdatablePixelBufferAccessPtr&     referenceResult,
1416                                                                                                                                          bool                                                                           collectBeforeSubmit)
1417 {
1418         if (collectBeforeSubmit)
1419         {
1420                 iterateCollectResults(programResult, variables, true);
1421                 iterateCollectResults(referenceResult, variables, false);
1422         }
1423
1424         VK_CHECK(m_vki.endCommandBuffer(*variables.commandBuffer));
1425         Move<VkFence> fence = commandSubmit(*variables.commandBuffer);
1426         m_vki.waitForFences(m_vkd, 1, &(*fence), DE_TRUE, ~0ull);
1427
1428         if (false == collectBeforeSubmit)
1429         {
1430                 iterateCollectResults(programResult, variables, true);
1431                 iterateCollectResults(referenceResult, variables, false);
1432         }
1433         m_context.resetCommandPoolForVKSC(m_vkd, *m_commandPool);
1434 }
1435
1436 bool CommonDescriptorInstance::iterateVerifyResults                     (IterateCommonVariables&                                        variables,
1437                                                                                                                                          ut::UpdatablePixelBufferAccessPtr      programResult,
1438                                                                                                                                          ut::UpdatablePixelBufferAccessPtr      referenceResult)
1439 {
1440         bool result = false;
1441         if (m_testParams.fuzzyComparison)
1442         {
1443                 result = tcu::fuzzyCompare(m_context.getTestContext().getLog(),
1444                         "Fuzzy Compare", "Comparison result", *referenceResult.get(), *programResult.get(), 0.02f, tcu::COMPARE_LOG_EVERYTHING);
1445         }
1446         else
1447         {
1448                 result = tcu::floatThresholdCompare(m_context.getTestContext().getLog(),
1449                         "Float Threshold Compare", "Comparison result", *referenceResult.get(), *programResult.get(), tcu::Vec4(0.02f, 0.02f, 0.02f, 0.02f), tcu::COMPARE_LOG_EVERYTHING);
1450         }
1451
1452         if (m_testParams.allowVertexStoring)
1453         {
1454                 result = verifyVertexWriteResults(variables);
1455         }
1456
1457         return result;
1458 }
1459
1460 void CommonDescriptorInstance::iterateCollectResults                            (ut::UpdatablePixelBufferAccessPtr&                     result,
1461                                                                                                                                          const IterateCommonVariables&                          variables,
1462                                                                                                                                          bool                                                                           fromTest)
1463 {
1464         if (fromTest)
1465         {
1466                 result = commandReadFrameBuffer(*variables.commandBuffer, variables.frameBuffer);
1467         }
1468         else
1469         {
1470                 result = ut::UpdatablePixelBufferAccessPtr(new ut::PixelBufferAccessAllocation(vk::mapVkFormat(m_colorFormat), m_testParams.frameResolution));
1471
1472                 for (deUint32 y = 0, pixelNum = 0; y < m_testParams.frameResolution.height; ++y)
1473                 {
1474                         for (deUint32 x = 0; x < m_testParams.frameResolution.width; ++x, ++pixelNum)
1475                         {
1476                                 const float component = m_colorScheme[(pixelNum % variables.validDescriptorCount) % m_schemeSize];
1477                                 result->setPixel(tcu::Vec4(component, component, component, 1.0f), x, y);
1478                         }
1479                 }
1480         }
1481 }
1482
1483 Move<VkCommandBuffer> CommonDescriptorInstance::createCmdBuffer         (void)
1484 {
1485         return vk::allocateCommandBuffer(m_vki, m_vkd, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1486 }
1487
1488 Move<VkFence> CommonDescriptorInstance::commandSubmit                           (VkCommandBuffer                                                        cmd)
1489 {
1490         Move<VkFence>   fence(vk::createFence(m_vki, m_vkd));
1491
1492         const VkSubmitInfo      submitInfo =
1493         {
1494                 VK_STRUCTURE_TYPE_SUBMIT_INFO,                                          // sType
1495                 DE_NULL,                                                                                        // pNext
1496                 0u,                                                                                                     // waitSemaphoreCount
1497                 static_cast<VkSemaphore*>(DE_NULL),                                     // pWaitSemaphores
1498                 static_cast<const VkPipelineStageFlags*>(DE_NULL),      // pWaitDstStageMask
1499                 1u,                                                                                                     // commandBufferCount
1500                 &cmd,                                                                                           // pCommandBuffers
1501                 0u,                                                                                                     // signalSemaphoreCount
1502                 static_cast<VkSemaphore*>(DE_NULL)                                      // pSignalSemaphores
1503         };
1504
1505         VK_CHECK(m_vki.queueSubmit(m_queue, 1u, &submitInfo, *fence));
1506
1507         return fence;
1508 }
1509
1510 bool CommonDescriptorInstance::verifyVertexWriteResults(IterateCommonVariables&                                 variables)
1511 {
1512         DE_UNREF(variables);
1513         return true;
1514 }
1515
1516 void CommonDescriptorInstance::commandBindPipeline                                      (VkCommandBuffer                                                        commandBuffer,
1517                                                                                                                                          VkPipeline                                                                     pipeline)
1518 {
1519         const VkPipelineBindPoint pipelineBindingPoint = (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT) ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS;
1520         m_vki.cmdBindPipeline(commandBuffer, pipelineBindingPoint, pipeline);
1521 }
1522
1523 void CommonDescriptorInstance::commandBindVertexAttributes                      (VkCommandBuffer                                                        commandBuffer,
1524                                                                                                                                          const ut::BufferHandleAllocSp&                         vertexAttributesBuffer)
1525 {
1526         const VkDeviceSize      offsets[] = { 0u };
1527         const VkBuffer          buffers[] = { *vertexAttributesBuffer->buffer };
1528         m_vki.cmdBindVertexBuffers(commandBuffer, 0u, 1u, buffers, offsets);
1529 }
1530
1531 void CommonDescriptorInstance::commandBindDescriptorSets                        (VkCommandBuffer                                                        commandBuffer,
1532                                                                                                                                          VkPipelineLayout                                                       pipelineLayout,
1533                                                                                                                                          VkDescriptorSet                                                        descriptorSet,
1534                                                                                                                                          deUint32                                                                       descriptorSetIndex)
1535 {
1536         const VkPipelineBindPoint pipelineBindingPoint = (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT) ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS;
1537         m_vki.cmdBindDescriptorSets(commandBuffer, pipelineBindingPoint, pipelineLayout, descriptorSetIndex, 1u, &descriptorSet, 0u, static_cast<deUint32*>(DE_NULL));
1538 }
1539
1540 ut::UpdatablePixelBufferAccessPtr
1541 CommonDescriptorInstance::commandReadFrameBuffer                                        (VkCommandBuffer                                                        commandBuffer,
1542                                                                                                                                          const ut::FrameBufferSp&                                       frameBuffer)
1543 {
1544         ut::BufferHandleAllocSp frameBufferContent;
1545         commandReadFrameBuffer(frameBufferContent, commandBuffer, frameBuffer);
1546         return ut::UpdatablePixelBufferAccessPtr(new ut::PixelBufferAccessBuffer(
1547                 m_vkd, m_vki, vk::mapVkFormat(m_colorFormat), m_testParams.frameResolution,
1548                 de::SharedPtr< Move<VkBuffer> >(new Move<VkBuffer>(frameBufferContent->buffer)),
1549                 de::SharedPtr< de::MovePtr<Allocation> >(new de::MovePtr<Allocation>(frameBufferContent->alloc))));
1550 }
1551
1552 void CommonDescriptorInstance::commandReadFrameBuffer                           (ut::BufferHandleAllocSp&                                       content,
1553                                                                                                                                          VkCommandBuffer                                                        commandBuffer,
1554                                                                                                                                          const ut::FrameBufferSp&                                       frameBuffer)
1555 {
1556         Move<VkBuffer>                  buffer;
1557         de::MovePtr<Allocation> allocation;
1558
1559         const VkDeviceSize bufferSize = ut::computeImageSize(frameBuffer->image);
1560
1561         // create a buffer and an host allocation for it
1562         {
1563                 const VkBufferCreateInfo bufferCreateInfo =
1564                 {
1565                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // sType
1566                         DE_NULL,                                                                        // pNext
1567                         0u,                                                                                     // flags
1568                         bufferSize,                                                                     // size
1569                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       // usage
1570                         VK_SHARING_MODE_EXCLUSIVE,                                      // sharingMode
1571                         1u,                                                                                     // queueFamilyIndexCoun
1572                         &m_queueFamilyIndex                                                     // pQueueFamilyIndices
1573                 };
1574
1575                 buffer = vk::createBuffer(m_vki, m_vkd, &bufferCreateInfo);
1576                 const VkMemoryRequirements      memRequirements(vk::getBufferMemoryRequirements(m_vki, m_vkd, *buffer));
1577                 allocation = m_allocator.allocate(memRequirements, MemoryRequirement::HostVisible);
1578
1579                 VK_CHECK(m_vki.bindBufferMemory(m_vkd, *buffer, allocation->getMemory(), allocation->getOffset()));
1580         }
1581
1582         const VkImage& image = *frameBuffer->image->image;
1583
1584         VkImageSubresourceRange         subresourceRange =
1585         {
1586                 VK_IMAGE_ASPECT_COLOR_BIT,                                      // aspectMask
1587                 0u,                                                                                     // baseMipLevel
1588                 1u,                                                                                     // levelCount
1589                 0u,                                                                                     // baseArrayLayer
1590                 1u                                                                                      // layerCount
1591         };
1592
1593         const VkImageMemoryBarrier      barrierBefore =
1594         {
1595                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // sType;
1596                 DE_NULL,                                                                        // pNext;
1597                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // srcAccessMask;
1598                 VK_ACCESS_TRANSFER_READ_BIT,                            // dstAccessMask;
1599                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // oldLayout
1600                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // newLayout;
1601                 VK_QUEUE_FAMILY_IGNORED,                                        // srcQueueFamilyIndex;
1602                 VK_QUEUE_FAMILY_IGNORED,                                        // dstQueueFamilyIndex;
1603                 image,                                                                          // image;
1604                 subresourceRange                                                        // subresourceRange;
1605         };
1606
1607         const VkBufferImageCopy         copyRegion =
1608         {
1609                 0u,                                                                                     // bufferOffset
1610                 frameBuffer->image->extent.width,                               // bufferRowLength
1611                 frameBuffer->image->extent.height,                      // bufferImageHeight
1612                 {                                                                                       // VkImageSubresourceLayers
1613                         VK_IMAGE_ASPECT_COLOR_BIT,                              // aspect
1614                         0u,                                                                             // mipLevel
1615                         0u,                                                                             // baseArrayLayer
1616                         1u,                                                                             // layerCount
1617                 },
1618                 { 0, 0, 0 },                                                            // imageOffset
1619                 frameBuffer->image->extent                                      // imageExtent
1620         };
1621
1622         const VkBufferMemoryBarrier     bufferBarrier =
1623         {
1624                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // sType;
1625                 DE_NULL,                                                                        // pNext;
1626                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // srcAccessMask;
1627                 VK_ACCESS_HOST_READ_BIT,                                        // dstAccessMask;
1628                 VK_QUEUE_FAMILY_IGNORED,                                        // srcQueueFamilyIndex;
1629                 VK_QUEUE_FAMILY_IGNORED,                                        // dstQueueFamilyIndex;
1630                 *buffer,                                                                        // buffer;
1631                 0u,                                                                                     // offset;
1632                 bufferSize                                                                      // size;
1633         };
1634
1635         const VkImageMemoryBarrier      barrierAfter =
1636         {
1637                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // sType;
1638                 DE_NULL,                                                                                // pNext;
1639                 VK_ACCESS_TRANSFER_READ_BIT,                                    // srcAccessMask;
1640                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                   // dstAccessMask;
1641                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,                   // oldLayout;
1642                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,               // newLayout;
1643                 VK_QUEUE_FAMILY_IGNORED,                                                // srcQueueFamilyIndex;
1644                 VK_QUEUE_FAMILY_IGNORED,                                                // dstQueueFamilyIndex;
1645                 image,                                                                                  // image
1646                 subresourceRange                                                                // subresourceRange
1647         };
1648
1649
1650         m_vki.cmdPipelineBarrier(commandBuffer,                                                                                         // commandBuffer
1651                 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,  // srcStageMask, dstStageMask
1652                 (VkDependencyFlags)0,                                                                                                                   // dependencyFlags
1653                 0u, DE_NULL,                                                                                                                                    // memoryBarrierCount, pMemoryBarriers
1654                 0u, DE_NULL,                                                                                                                                    // bufferBarrierCount, pBufferBarriers
1655                 1u, &barrierBefore);                                                                                                                            // imageBarrierCount, pImageBarriers
1656
1657         m_vki.cmdCopyImageToBuffer(commandBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, &copyRegion);
1658
1659         m_vki.cmdPipelineBarrier(commandBuffer,
1660                 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT | VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
1661                 (VkDependencyFlags)0,
1662                 0u, DE_NULL,
1663                 1u, &bufferBarrier,
1664                 1u, &barrierAfter);
1665
1666         content = ut::BufferHandleAllocSp(new ut::BufferHandleAlloc(buffer, allocation));
1667 }
1668
1669 std::string CommonDescriptorInstance::getColorAccess                            (VkDescriptorType                                                       descriptorType,
1670                                                                                                                                          const char*                                                            indexVariableName,
1671                                                                                                                                          bool                                                                           usesMipMaps)
1672 {
1673         std::string text;
1674         std::map<std::string, std::string> vars;
1675         vars["INDEX"] = indexVariableName;
1676
1677         switch (descriptorType)
1678         {
1679         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1680         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1681                 text = "data[nonuniformEXT(${INDEX})].c";
1682                 break;
1683         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1684         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1685                 text = "data[nonuniformEXT(${INDEX})].cold";
1686                 break;
1687         case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1688                 text = "subpassLoad(data[nonuniformEXT(${INDEX})]).rgba";
1689                 break;
1690         case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1691                 text = "texelFetch(data[nonuniformEXT(${INDEX})], 0)";
1692                 break;
1693         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1694                 text = "imageLoad(data[nonuniformEXT(${INDEX})], 0)";
1695                 break;
1696         case VK_DESCRIPTOR_TYPE_SAMPLER:
1697                 text = usesMipMaps
1698                         ? "textureLod(nonuniformEXT(sampler2D(tex[0], data[${INDEX}])), normalpos, 1)"
1699                         : "texture(   nonuniformEXT(sampler2D(tex[0], data[${INDEX}])), normalpos   )";
1700                 break;
1701         case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1702                 text = usesMipMaps
1703                         ? "textureLod( nonuniformEXT(sampler2D(data[${INDEX}], samp[0])), vec2(0,0), textureQueryLevels(nonuniformEXT(sampler2D(data[${INDEX}], samp[0])))-1)"
1704                         : "texture(    nonuniformEXT(sampler2D(data[${INDEX}], samp[0])), vec2(0,0)   )";
1705                 break;
1706         case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1707                 text = usesMipMaps
1708                         ? "textureLod( data[nonuniformEXT(${INDEX})], uvec2(0,0), textureQueryLevels(data[nonuniformEXT(${INDEX})])-1)"
1709                         : "texture(    data[nonuniformEXT(${INDEX})], uvec2(0,0)   )";
1710                 break;
1711         default:
1712                 TCU_THROW(InternalError, "Not implemented descriptor type");
1713         }
1714
1715         return tcu::StringTemplate(text).specialize(vars);
1716 }
1717
1718 std::string CommonDescriptorInstance::getFragmentReturnSource           (const std::string&                                                     colorAccess)
1719 {
1720         return "  FragColor = " + colorAccess + ";\n";
1721 }
1722
1723 std::string CommonDescriptorInstance::getFragmentLoopSource                     (const std::string&                                                     colorAccess1,
1724                                                                                                                                          const std::string&                                                     colorAccess2)
1725 {
1726         std::map < std::string, std::string > vars;
1727         vars["COLOR_ACCESS_1"] = colorAccess1;
1728         vars["COLOR_ACCESS_2"] = colorAccess2;
1729
1730         const char* s =
1731                 "  vec4 sumClr1 = vec4(0,0,0,0);                \n"
1732                 "  vec4 sumClr2 = vec4(0,0,0,0);                \n"
1733                 "  for (int i = pc.lowerBound; i < pc.upperBound; ++i)  \n"
1734                 "  {\n"
1735                 "    int loopIdx = texelFetch(iter, i).x;                               \n"
1736                 "    sumClr1 += ${COLOR_ACCESS_2} + ${COLOR_ACCESS_1};  \n"
1737                 "    sumClr2 += ${COLOR_ACCESS_2};                                              \n"
1738                 "  }\n"
1739                 "  FragColor = vec4(((sumClr1 - sumClr2) / float(pc.upperBound - pc.lowerBound)).rgb, 1);       \n";
1740
1741         return tcu::StringTemplate(s).specialize(vars);
1742 }
1743
1744 bool CommonDescriptorInstance::performWritesInVertex                            (VkDescriptorType                                                       descriptorType)
1745 {
1746         bool result = false;
1747
1748         switch (descriptorType)
1749         {
1750         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1751         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1752         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1753                 result = true;
1754                 break;
1755         default:
1756                 result = false;
1757                 break;
1758         }
1759
1760         return result;
1761 }
1762
1763 bool CommonDescriptorInstance::performWritesInVertex                            (VkDescriptorType                                                       descriptorType,
1764                                                                                                                                         const Context&                                                          context)
1765 {
1766         bool result = false;
1767
1768         ut::DeviceProperties                    dp              (context);
1769         const VkPhysicalDeviceFeatures& feats   = dp.physicalDeviceFeatures();
1770
1771         if (feats.vertexPipelineStoresAndAtomics != DE_FALSE)
1772         {
1773                 result = CommonDescriptorInstance::performWritesInVertex(descriptorType);
1774         }
1775
1776         return result;
1777 }
1778
1779 std::string CommonDescriptorInstance::getShaderAsm                                      (VkShaderStageFlagBits                                          shaderType,
1780                                                                                                                                          const TestCaseParams&                                          testCaseParams,
1781                                                                                                                                          bool                                                                           allowVertexStoring)
1782 {
1783         std::stringstream       s;
1784         switch (shaderType)
1785         {
1786                 case VK_SHADER_STAGE_VERTEX_BIT:
1787                         switch (testCaseParams.descriptorType)
1788                         {
1789                                 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1790                                 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1791                                 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1792                                         s << "               OpCapability Shader\n";
1793                                         s << "               OpCapability SampledBuffer\n";
1794                                         s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
1795                                         s << "               OpMemoryModel Logical GLSL450\n";
1796                                         s << "               OpEntryPoint Vertex %main \"main\" %_ %position %in_position %normalpos %in_normalpos %vIndex %gl_VertexIndex %rIndex %index %gIndex %bIndex %aIndex\n";
1797                                         s << "               OpSource GLSL 450\n";
1798                                         s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
1799                                         s << "               OpSourceExtension \"GL_EXT_texture_buffer\"\n";
1800                                         s << "               OpName %main \"main\"\n";
1801                                         s << "               OpName %gl_PerVertex \"gl_PerVertex\"\n";
1802                                         s << "               OpMemberName %gl_PerVertex 0 \"gl_Position\"\n";
1803                                         s << "               OpMemberName %gl_PerVertex 1 \"gl_PointSize\"\n";
1804                                         s << "               OpMemberName %gl_PerVertex 2 \"gl_ClipDistance\"\n";
1805                                         s << "               OpMemberName %gl_PerVertex 3 \"gl_CullDistance\"\n";
1806                                         s << "               OpName %_ \"\"\n";
1807                                         s << "               OpName %position \"position\"\n";
1808                                         s << "               OpName %in_position \"in_position\"\n";
1809                                         s << "               OpName %normalpos \"normalpos\"\n";
1810                                         s << "               OpName %in_normalpos \"in_normalpos\"\n";
1811                                         s << "               OpName %vIndex \"vIndex\"\n";
1812                                         s << "               OpName %gl_VertexIndex \"gl_VertexIndex\"\n";
1813                                         s << "               OpName %rIndex \"rIndex\"\n";
1814                                         s << "               OpName %index \"index\"\n";
1815                                         s << "               OpName %gIndex \"gIndex\"\n";
1816                                         s << "               OpName %bIndex \"bIndex\"\n";
1817                                         s << "               OpName %aIndex \"aIndex\"\n";
1818                                         s << "               OpMemberDecorate %gl_PerVertex 0 BuiltIn Position\n";
1819                                         s << "               OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize\n";
1820                                         s << "               OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance\n";
1821                                         s << "               OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance\n";
1822                                         s << "               OpDecorate %gl_PerVertex Block\n";
1823                                         s << "               OpDecorate %position Location 0\n";
1824                                         s << "               OpDecorate %in_position Location 0\n";
1825                                         s << "               OpDecorate %normalpos Location 1\n";
1826                                         s << "               OpDecorate %in_normalpos Location 1\n";
1827                                         s << "               OpDecorate %vIndex Location 2\n";
1828                                         s << "               OpDecorate %gl_VertexIndex BuiltIn VertexIndex\n";
1829                                         s << "               OpDecorate %rIndex Location 3\n";
1830                                         s << "               OpDecorate %index Location 2\n";
1831                                         s << "               OpDecorate %gIndex Location 4\n";
1832                                         s << "               OpDecorate %bIndex Location 5\n";
1833                                         s << "               OpDecorate %aIndex Location 6\n";
1834                                         s << "       %void = OpTypeVoid\n";
1835                                         s << "          %3 = OpTypeFunction %void\n";
1836                                         s << "      %float = OpTypeFloat 32\n";
1837                                         s << "    %v4float = OpTypeVector %float 4\n";
1838                                         s << "       %uint = OpTypeInt 32 0\n";
1839                                         s << "     %uint_1 = OpConstant %uint 1\n";
1840                                         s << "%_arr_float_uint_1 = OpTypeArray %float %uint_1\n";
1841                                         s << "%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1\n";
1842                                         s << "%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex\n";
1843                                         s << "          %_ = OpVariable %_ptr_Output_gl_PerVertex Output\n";
1844                                         s << "        %int = OpTypeInt 32 1\n";
1845                                         s << "      %int_1 = OpConstant %int 1\n";
1846                                         s << "%float_0_200000003 = OpConstant %float 0.200000003\n";
1847                                         s << "%_ptr_Output_float = OpTypePointer Output %float\n";
1848                                         s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
1849                                         s << "   %position = OpVariable %_ptr_Output_v4float Output\n";
1850                                         s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
1851                                         s << "%in_position = OpVariable %_ptr_Input_v4float Input\n";
1852                                         s << "    %v2float = OpTypeVector %float 2\n";
1853                                         s << "%_ptr_Output_v2float = OpTypePointer Output %v2float\n";
1854                                         s << "  %normalpos = OpVariable %_ptr_Output_v2float Output\n";
1855                                         s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
1856                                         s << "%in_normalpos = OpVariable %_ptr_Input_v2float Input\n";
1857                                         s << "      %int_0 = OpConstant %int 0\n";
1858                                         s << "%_ptr_Output_int = OpTypePointer Output %int\n";
1859                                         s << "     %vIndex = OpVariable %_ptr_Output_int Output\n";
1860                                         s << "%_ptr_Input_int = OpTypePointer Input %int\n";
1861                                         s << "%gl_VertexIndex = OpVariable %_ptr_Input_int Input\n";
1862                                         s << "     %rIndex = OpVariable %_ptr_Output_int Output\n";
1863                                         s << "      %v4int = OpTypeVector %int 4\n";
1864                                         s << "%_ptr_Input_v4int = OpTypePointer Input %v4int\n";
1865                                         s << "      %index = OpVariable %_ptr_Input_v4int Input\n";
1866                                         s << "     %uint_0 = OpConstant %uint 0\n";
1867                                         s << "     %gIndex = OpVariable %_ptr_Output_int Output\n";
1868                                         s << "     %bIndex = OpVariable %_ptr_Output_int Output\n";
1869                                         s << "     %uint_2 = OpConstant %uint 2\n";
1870                                         s << "     %aIndex = OpVariable %_ptr_Output_int Output\n";
1871                                         s << "     %uint_3 = OpConstant %uint 3\n";
1872                                         s << "       %main = OpFunction %void None %3\n";
1873                                         s << "          %5 = OpLabel\n";
1874                                         s << "         %18 = OpAccessChain %_ptr_Output_float %_ %int_1\n";
1875                                         s << "               OpStore %18 %float_0_200000003\n";
1876                                         s << "         %23 = OpLoad %v4float %in_position\n";
1877                                         s << "               OpStore %position %23\n";
1878                                         s << "         %29 = OpLoad %v2float %in_normalpos\n";
1879                                         s << "               OpStore %normalpos %29\n";
1880                                         s << "         %31 = OpLoad %v4float %position\n";
1881                                         s << "         %32 = OpAccessChain %_ptr_Output_v4float %_ %int_0\n";
1882                                         s << "               OpStore %32 %31\n";
1883                                         s << "         %37 = OpLoad %int %gl_VertexIndex\n";
1884                                         s << "               OpStore %vIndex %37\n";
1885                                         s << "         %43 = OpAccessChain %_ptr_Input_int %index %uint_0\n";
1886                                         s << "         %44 = OpLoad %int %43\n";
1887                                         s << "               OpStore %rIndex %44\n";
1888                                         s << "         %46 = OpAccessChain %_ptr_Input_int %index %uint_1\n";
1889                                         s << "         %47 = OpLoad %int %46\n";
1890                                         s << "               OpStore %gIndex %47\n";
1891                                         s << "         %50 = OpAccessChain %_ptr_Input_int %index %uint_2\n";
1892                                         s << "         %51 = OpLoad %int %50\n";
1893                                         s << "               OpStore %bIndex %51\n";
1894                                         s << "         %54 = OpAccessChain %_ptr_Input_int %index %uint_3\n";
1895                                         s << "         %55 = OpLoad %int %54\n";
1896                                         s << "               OpStore %aIndex %55\n";
1897                                         s << "               OpReturn\n";
1898                                         s << "               OpFunctionEnd\n";
1899                                         break;
1900                                 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1901                                         s << "               OpCapability Shader\n";
1902                                         s << "               OpCapability ImageBuffer\n";
1903                                         if (allowVertexStoring)
1904                                         {
1905                                                 s << "               OpCapability ShaderNonUniform\n";
1906                                                 s << "               OpCapability RuntimeDescriptorArray\n";
1907                                                 s << "               OpCapability StorageTexelBufferArrayNonUniformIndexing\n";
1908                                                 s << "               OpExtension \"SPV_EXT_descriptor_indexing\"\n";
1909                                         }
1910                                         s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
1911                                         s << "               OpMemoryModel Logical GLSL450\n";
1912                                         s << "               OpEntryPoint Vertex %main \"main\" %_ %position %in_position %normalpos %in_normalpos %vIndex %gl_VertexIndex %rIndex %index %gIndex %bIndex %aIndex %data\n";
1913                                         s << "               OpSource GLSL 450\n";
1914                                         s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
1915                                         s << "               OpName %main \"main\"\n";
1916                                         s << "               OpName %gl_PerVertex \"gl_PerVertex\"\n";
1917                                         s << "               OpMemberName %gl_PerVertex 0 \"gl_Position\"\n";
1918                                         s << "               OpMemberName %gl_PerVertex 1 \"gl_PointSize\"\n";
1919                                         s << "               OpMemberName %gl_PerVertex 2 \"gl_ClipDistance\"\n";
1920                                         s << "               OpMemberName %gl_PerVertex 3 \"gl_CullDistance\"\n";
1921                                         s << "               OpName %_ \"\"\n";
1922                                         s << "               OpName %position \"position\"\n";
1923                                         s << "               OpName %in_position \"in_position\"\n";
1924                                         s << "               OpName %normalpos \"normalpos\"\n";
1925                                         s << "               OpName %in_normalpos \"in_normalpos\"\n";
1926                                         s << "               OpName %vIndex \"vIndex\"\n";
1927                                         s << "               OpName %gl_VertexIndex \"gl_VertexIndex\"\n";
1928                                         s << "               OpName %rIndex \"rIndex\"\n";
1929                                         s << "               OpName %index \"index\"\n";
1930                                         s << "               OpName %gIndex \"gIndex\"\n";
1931                                         s << "               OpName %bIndex \"bIndex\"\n";
1932                                         s << "               OpName %aIndex \"aIndex\"\n";
1933                                         s << "               OpName %data \"data\"\n";
1934                                         s << "               OpMemberDecorate %gl_PerVertex 0 BuiltIn Position\n";
1935                                         s << "               OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize\n";
1936                                         s << "               OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance\n";
1937                                         s << "               OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance\n";
1938                                         s << "               OpDecorate %gl_PerVertex Block\n";
1939                                         s << "               OpDecorate %position Location 0\n";
1940                                         s << "               OpDecorate %in_position Location 0\n";
1941                                         s << "               OpDecorate %normalpos Location 1\n";
1942                                         s << "               OpDecorate %in_normalpos Location 1\n";
1943                                         s << "               OpDecorate %vIndex Location 2\n";
1944                                         s << "               OpDecorate %gl_VertexIndex BuiltIn VertexIndex\n";
1945                                         s << "               OpDecorate %rIndex Location 3\n";
1946                                         s << "               OpDecorate %index Location 2\n";
1947                                         s << "               OpDecorate %gIndex Location 4\n";
1948                                         s << "               OpDecorate %bIndex Location 5\n";
1949                                         s << "               OpDecorate %aIndex Location 6\n";
1950                                         s << "               OpDecorate %data DescriptorSet 0\n";
1951                                         s << "               OpDecorate %data Binding 4\n";
1952                                         if (allowVertexStoring)
1953                                         {
1954                                                 // s << "               OpDecorate %66 NonUniform\n";
1955                                                 // s << "               OpDecorate %68 NonUniform\n";
1956                                                 s << "               OpDecorate %69 NonUniform\n";
1957                                                 // s << "               OpDecorate %71 NonUniform\n";
1958                                                 // s << "               OpDecorate %72 NonUniform\n";
1959                                                 s << "               OpDecorate %73 NonUniform\n";
1960                                         }
1961                                         s << "       %void = OpTypeVoid\n";
1962                                         s << "          %3 = OpTypeFunction %void\n";
1963                                         s << "      %float = OpTypeFloat 32\n";
1964                                         s << "    %v4float = OpTypeVector %float 4\n";
1965                                         s << "       %uint = OpTypeInt 32 0\n";
1966                                         s << "     %uint_1 = OpConstant %uint 1\n";
1967                                         s << "%_arr_float_uint_1 = OpTypeArray %float %uint_1\n";
1968                                         s << "%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1\n";
1969                                         s << "%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex\n";
1970                                         s << "          %_ = OpVariable %_ptr_Output_gl_PerVertex Output\n";
1971                                         s << "        %int = OpTypeInt 32 1\n";
1972                                         s << "      %int_1 = OpConstant %int 1\n";
1973                                         s << "%float_0_200000003 = OpConstant %float 0.200000003\n";
1974                                         s << "%_ptr_Output_float = OpTypePointer Output %float\n";
1975                                         s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
1976                                         s << "   %position = OpVariable %_ptr_Output_v4float Output\n";
1977                                         s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
1978                                         s << "%in_position = OpVariable %_ptr_Input_v4float Input\n";
1979                                         s << "    %v2float = OpTypeVector %float 2\n";
1980                                         s << "%_ptr_Output_v2float = OpTypePointer Output %v2float\n";
1981                                         s << "  %normalpos = OpVariable %_ptr_Output_v2float Output\n";
1982                                         s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
1983                                         s << "%in_normalpos = OpVariable %_ptr_Input_v2float Input\n";
1984                                         s << "      %int_0 = OpConstant %int 0\n";
1985                                         s << "%_ptr_Output_int = OpTypePointer Output %int\n";
1986                                         s << "     %vIndex = OpVariable %_ptr_Output_int Output\n";
1987                                         s << "%_ptr_Input_int = OpTypePointer Input %int\n";
1988                                         s << "%gl_VertexIndex = OpVariable %_ptr_Input_int Input\n";
1989                                         s << "     %rIndex = OpVariable %_ptr_Output_int Output\n";
1990                                         s << "      %v4int = OpTypeVector %int 4\n";
1991                                         s << "%_ptr_Input_v4int = OpTypePointer Input %v4int\n";
1992                                         s << "      %index = OpVariable %_ptr_Input_v4int Input\n";
1993                                         s << "     %uint_0 = OpConstant %uint 0\n";
1994                                         s << "     %gIndex = OpVariable %_ptr_Output_int Output\n";
1995                                         s << "     %bIndex = OpVariable %_ptr_Output_int Output\n";
1996                                         s << "     %uint_2 = OpConstant %uint 2\n";
1997                                         s << "     %aIndex = OpVariable %_ptr_Output_int Output\n";
1998                                         s << "     %uint_3 = OpConstant %uint 3\n";
1999                                         if (allowVertexStoring)
2000                                         {
2001                                                 s << "        %bool = OpTypeBool\n";
2002                                                 s << "          %61 = OpTypeImage %float Buffer 0 0 0 2 Rgba32f\n";
2003                                                 s << " %_runtimearr_61 = OpTypeRuntimeArray %61\n";
2004                                                 s << " %_ptr_UniformConstant__runtimearr_61 = OpTypePointer UniformConstant %_runtimearr_61\n";
2005                                                 s << "        %data = OpVariable %_ptr_UniformConstant__runtimearr_61 UniformConstant\n";
2006                                                 s << " %_ptr_UniformConstant_61 = OpTypePointer UniformConstant %61\n";
2007                                         }
2008                                         else
2009                                         {
2010                                                 s << "         %56 = OpTypeImage %float Buffer 0 0 0 2 Rgba32f\n";
2011                                                 s << "%_arr_56_uint_1 = OpTypeArray %56 %uint_1\n";
2012                                                 s << "%_ptr_UniformConstant__arr_56_uint_1 = OpTypePointer UniformConstant %_arr_56_uint_1\n";
2013                                                 s << "       %data = OpVariable %_ptr_UniformConstant__arr_56_uint_1 UniformConstant\n";
2014                                         }
2015                                         s << "       %main = OpFunction %void None %3\n";
2016                                         s << "          %5 = OpLabel\n";
2017                                         s << "         %18 = OpAccessChain %_ptr_Output_float %_ %int_1\n";
2018                                         s << "               OpStore %18 %float_0_200000003\n";
2019                                         s << "         %23 = OpLoad %v4float %in_position\n";
2020                                         s << "               OpStore %position %23\n";
2021                                         s << "         %29 = OpLoad %v2float %in_normalpos\n";
2022                                         s << "               OpStore %normalpos %29\n";
2023                                         s << "         %31 = OpLoad %v4float %position\n";
2024                                         s << "         %32 = OpAccessChain %_ptr_Output_v4float %_ %int_0\n";
2025                                         s << "               OpStore %32 %31\n";
2026                                         s << "         %37 = OpLoad %int %gl_VertexIndex\n";
2027                                         s << "               OpStore %vIndex %37\n";
2028                                         s << "         %43 = OpAccessChain %_ptr_Input_int %index %uint_0\n";
2029                                         s << "         %44 = OpLoad %int %43\n";
2030                                         s << "               OpStore %rIndex %44\n";
2031                                         s << "         %46 = OpAccessChain %_ptr_Input_int %index %uint_1\n";
2032                                         s << "         %47 = OpLoad %int %46\n";
2033                                         s << "               OpStore %gIndex %47\n";
2034                                         s << "         %50 = OpAccessChain %_ptr_Input_int %index %uint_2\n";
2035                                         s << "         %51 = OpLoad %int %50\n";
2036                                         s << "               OpStore %bIndex %51\n";
2037                                         s << "         %54 = OpAccessChain %_ptr_Input_int %index %uint_3\n";
2038                                         s << "         %55 = OpLoad %int %54\n";
2039                                         s << "               OpStore %aIndex %55\n";
2040                                         if (allowVertexStoring)
2041                                         {
2042                                                 s << "          %56 = OpLoad %int %gIndex\n";
2043                                                 s << "          %58 = OpINotEqual %bool %56 %int_0\n";
2044                                                 s << "                OpSelectionMerge %60 None\n";
2045                                                 s << "                OpBranchConditional %58 %59 %60\n";
2046                                                 s << "          %59 = OpLabel\n";
2047                                                 s << "          %65 = OpLoad %int %gIndex\n";
2048                                                 s << "          %66 = OpCopyObject %int %65\n";
2049                                                 s << "          %68 = OpAccessChain %_ptr_UniformConstant_61 %data %66\n";
2050                                                 s << "          %69 = OpLoad %61 %68\n";
2051                                                 s << "          %70 = OpLoad %int %rIndex\n";
2052                                                 s << "          %71 = OpCopyObject %int %70\n";
2053                                                 s << "          %72 = OpAccessChain %_ptr_UniformConstant_61 %data %71\n";
2054                                                 s << "          %73 = OpLoad %61 %72\n";
2055                                                 s << "          %74 = OpImageRead %v4float %73 %int_0\n";
2056                                                 s << "                OpImageWrite %69 %int_1 %74\n";
2057                                                 s << "                OpBranch %60\n";
2058                                                 s << "          %60 = OpLabel\n";
2059                                         }
2060                                         s << "               OpReturn\n";
2061                                         s << "               OpFunctionEnd\n";
2062                                         break;
2063                                 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2064                                         s << "               OpCapability Shader\n";
2065                                         if (allowVertexStoring)
2066                                         {
2067                                                 s << "               OpCapability ShaderNonUniform\n";
2068                                                 s << "               OpCapability RuntimeDescriptorArray\n";
2069                                                 s << "               OpCapability StorageBufferArrayNonUniformIndexing\n";
2070                                                 s << "               OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2071                                         }
2072                                         s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
2073                                         s << "               OpMemoryModel Logical GLSL450\n";
2074                                         s << "               OpEntryPoint Vertex %main \"main\" %_ %position %in_position %normalpos %in_normalpos %vIndex %gl_VertexIndex %rIndex %index %gIndex %bIndex %aIndex %data\n";
2075                                         s << "               OpSource GLSL 450\n";
2076                                         s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2077                                         s << "               OpName %main \"main\"\n";
2078                                         s << "               OpName %gl_PerVertex \"gl_PerVertex\"\n";
2079                                         s << "               OpMemberName %gl_PerVertex 0 \"gl_Position\"\n";
2080                                         s << "               OpMemberName %gl_PerVertex 1 \"gl_PointSize\"\n";
2081                                         s << "               OpMemberName %gl_PerVertex 2 \"gl_ClipDistance\"\n";
2082                                         s << "               OpMemberName %gl_PerVertex 3 \"gl_CullDistance\"\n";
2083                                         s << "               OpName %_ \"\"\n";
2084                                         s << "               OpName %position \"position\"\n";
2085                                         s << "               OpName %in_position \"in_position\"\n";
2086                                         s << "               OpName %normalpos \"normalpos\"\n";
2087                                         s << "               OpName %in_normalpos \"in_normalpos\"\n";
2088                                         s << "               OpName %vIndex \"vIndex\"\n";
2089                                         s << "               OpName %gl_VertexIndex \"gl_VertexIndex\"\n";
2090                                         s << "               OpName %rIndex \"rIndex\"\n";
2091                                         s << "               OpName %index \"index\"\n";
2092                                         s << "               OpName %gIndex \"gIndex\"\n";
2093                                         s << "               OpName %bIndex \"bIndex\"\n";
2094                                         s << "               OpName %aIndex \"aIndex\"\n";
2095                                         s << "               OpName %Data \"Data\"\n";
2096                                         s << "               OpMemberName %Data 0 \"cnew\"\n";
2097                                         s << "               OpMemberName %Data 1 \"cold\"\n";
2098                                         s << "               OpName %data \"data\"\n";
2099                                         s << "               OpMemberDecorate %gl_PerVertex 0 BuiltIn Position\n";
2100                                         s << "               OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize\n";
2101                                         s << "               OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance\n";
2102                                         s << "               OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance\n";
2103                                         s << "               OpDecorate %gl_PerVertex Block\n";
2104                                         s << "               OpDecorate %position Location 0\n";
2105                                         s << "               OpDecorate %in_position Location 0\n";
2106                                         s << "               OpDecorate %normalpos Location 1\n";
2107                                         s << "               OpDecorate %in_normalpos Location 1\n";
2108                                         s << "               OpDecorate %vIndex Location 2\n";
2109                                         s << "               OpDecorate %gl_VertexIndex BuiltIn VertexIndex\n";
2110                                         s << "               OpDecorate %rIndex Location 3\n";
2111                                         s << "               OpDecorate %index Location 2\n";
2112                                         s << "               OpDecorate %gIndex Location 4\n";
2113                                         s << "               OpDecorate %bIndex Location 5\n";
2114                                         s << "               OpDecorate %aIndex Location 6\n";
2115                                         s << "               OpMemberDecorate %Data 0 Offset 0\n";
2116                                         s << "               OpMemberDecorate %Data 1 Offset 16\n";
2117                                         s << "               OpDecorate %Data Block\n";
2118                                         s << "               OpDecorate %data DescriptorSet 0\n";
2119                                         s << "               OpDecorate %data Binding 2\n";
2120                                         if (allowVertexStoring)
2121                                         {
2122                                                 // s << "               OpDecorate %66 NonUniform\n";
2123                                                 // s << "               OpDecorate %68 NonUniform\n";
2124                                                 s << "               OpDecorate %70 NonUniform\n";
2125                                                 // s << "               OpDecorate %71 NonUniform\n";
2126                                                 s << "               OpDecorate %72 NonUniform\n";
2127                                         }
2128                                         s << "       %void = OpTypeVoid\n";
2129                                         s << "          %3 = OpTypeFunction %void\n";
2130                                         s << "      %float = OpTypeFloat 32\n";
2131                                         s << "    %v4float = OpTypeVector %float 4\n";
2132                                         s << "       %uint = OpTypeInt 32 0\n";
2133                                         s << "     %uint_1 = OpConstant %uint 1\n";
2134                                         s << "%_arr_float_uint_1 = OpTypeArray %float %uint_1\n";
2135                                         s << "%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1\n";
2136                                         s << "%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex\n";
2137                                         s << "          %_ = OpVariable %_ptr_Output_gl_PerVertex Output\n";
2138                                         s << "        %int = OpTypeInt 32 1\n";
2139                                         s << "      %int_1 = OpConstant %int 1\n";
2140                                         s << "%float_0_200000003 = OpConstant %float 0.200000003\n";
2141                                         s << "%_ptr_Output_float = OpTypePointer Output %float\n";
2142                                         s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
2143                                         s << "   %position = OpVariable %_ptr_Output_v4float Output\n";
2144                                         s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
2145                                         s << "%in_position = OpVariable %_ptr_Input_v4float Input\n";
2146                                         s << "    %v2float = OpTypeVector %float 2\n";
2147                                         s << "%_ptr_Output_v2float = OpTypePointer Output %v2float\n";
2148                                         s << "  %normalpos = OpVariable %_ptr_Output_v2float Output\n";
2149                                         s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
2150                                         s << "%in_normalpos = OpVariable %_ptr_Input_v2float Input\n";
2151                                         s << "      %int_0 = OpConstant %int 0\n";
2152                                         s << "%_ptr_Output_int = OpTypePointer Output %int\n";
2153                                         s << "     %vIndex = OpVariable %_ptr_Output_int Output\n";
2154                                         s << "%_ptr_Input_int = OpTypePointer Input %int\n";
2155                                         s << "%gl_VertexIndex = OpVariable %_ptr_Input_int Input\n";
2156                                         s << "     %rIndex = OpVariable %_ptr_Output_int Output\n";
2157                                         s << "      %v4int = OpTypeVector %int 4\n";
2158                                         s << "%_ptr_Input_v4int = OpTypePointer Input %v4int\n";
2159                                         s << "      %index = OpVariable %_ptr_Input_v4int Input\n";
2160                                         s << "     %uint_0 = OpConstant %uint 0\n";
2161                                         s << "     %gIndex = OpVariable %_ptr_Output_int Output\n";
2162                                         s << "     %bIndex = OpVariable %_ptr_Output_int Output\n";
2163                                         s << "     %uint_2 = OpConstant %uint 2\n";
2164                                         s << "     %aIndex = OpVariable %_ptr_Output_int Output\n";
2165                                         s << "     %uint_3 = OpConstant %uint 3\n";
2166                                         s << "       %Data = OpTypeStruct %v4float %v4float\n";
2167                                         if (allowVertexStoring)
2168                                         {
2169                                                 s << "       %bool = OpTypeBool\n";
2170                                                 s << "%_runtimearr_Data = OpTypeRuntimeArray %Data\n";
2171                                                 s << "%_ptr_StorageBuffer__runtimearr_Data = OpTypePointer StorageBuffer %_runtimearr_Data\n";
2172                                                 s << "       %data = OpVariable  %_ptr_StorageBuffer__runtimearr_Data StorageBuffer\n";
2173                                                 s << "%_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float\n";
2174                                         }
2175                                         else
2176                                         {
2177                                                 s << "%_arr_Data_uint_1 = OpTypeArray %Data %uint_1\n";
2178                                                 s << "%_ptr_StorageBuffer__arr_Data_uint_1 = OpTypePointer StorageBuffer %_arr_Data_uint_1\n";
2179                                                 s << "       %data = OpVariable %_ptr_StorageBuffer__arr_Data_uint_1 StorageBuffer\n";
2180                                         }
2181                                         s << "       %main = OpFunction %void None %3\n";
2182                                         s << "          %5 = OpLabel\n";
2183                                         s << "         %18 = OpAccessChain %_ptr_Output_float %_ %int_1\n";
2184                                         s << "               OpStore %18 %float_0_200000003\n";
2185                                         s << "         %23 = OpLoad %v4float %in_position\n";
2186                                         s << "               OpStore %position %23\n";
2187                                         s << "         %29 = OpLoad %v2float %in_normalpos\n";
2188                                         s << "               OpStore %normalpos %29\n";
2189                                         s << "         %31 = OpLoad %v4float %position\n";
2190                                         s << "         %32 = OpAccessChain %_ptr_Output_v4float %_ %int_0\n";
2191                                         s << "               OpStore %32 %31\n";
2192                                         s << "         %37 = OpLoad %int %gl_VertexIndex\n";
2193                                         s << "               OpStore %vIndex %37\n";
2194                                         s << "         %43 = OpAccessChain %_ptr_Input_int %index %uint_0\n";
2195                                         s << "         %44 = OpLoad %int %43\n";
2196                                         s << "               OpStore %rIndex %44\n";
2197                                         s << "         %46 = OpAccessChain %_ptr_Input_int %index %uint_1\n";
2198                                         s << "         %47 = OpLoad %int %46\n";
2199                                         s << "               OpStore %gIndex %47\n";
2200                                         s << "         %50 = OpAccessChain %_ptr_Input_int %index %uint_2\n";
2201                                         s << "         %51 = OpLoad %int %50\n";
2202                                         s << "               OpStore %bIndex %51\n";
2203                                         s << "         %54 = OpAccessChain %_ptr_Input_int %index %uint_3\n";
2204                                         s << "         %55 = OpLoad %int %54\n";
2205                                         s << "               OpStore %aIndex %55\n";
2206                                         if (allowVertexStoring)
2207                                         {
2208                                                 s << "          %56 = OpLoad %int %gIndex\n";
2209                                                 s << "          %58 = OpINotEqual %bool %56 %int_0\n";
2210                                                 s << "                OpSelectionMerge %60 None\n";
2211                                                 s << "                OpBranchConditional %58 %59 %60\n";
2212                                                 s << "          %59 = OpLabel\n";
2213                                                 s << "          %65 = OpLoad %int %gIndex\n";
2214                                                 s << "          %66 = OpCopyObject %int %65\n";
2215                                                 s << "          %67 = OpLoad %int %rIndex\n";
2216                                                 s << "          %68 = OpCopyObject %int %67\n";
2217                                                 s << "          %70 = OpAccessChain %_ptr_StorageBuffer_v4float %data %68 %int_1\n";
2218                                                 s << "          %71 = OpLoad %v4float %70\n";
2219                                                 s << "          %72 = OpAccessChain %_ptr_StorageBuffer_v4float %data %66 %int_0\n";
2220                                                 s << "                OpStore %72 %71\n";
2221                                                 s << "                OpBranch %60\n";
2222                                                 s << "          %60 = OpLabel\n";
2223                                         }
2224                                         s << "               OpReturn\n";
2225                                         s << "               OpFunctionEnd\n";
2226                                         break;
2227                                 default:
2228                                         TCU_THROW(InternalError, "Unexpected descriptor type");
2229                         }
2230                         break;
2231                 case VK_SHADER_STAGE_FRAGMENT_BIT:
2232                         switch (testCaseParams.descriptorType)
2233                         {
2234                                 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
2235                                         s << "               OpCapability Shader\n";
2236                                         if (testCaseParams.usesMipMaps)
2237                                         {
2238                                                 s << "               OpCapability ImageQuery\n";
2239                                         }
2240                                         s << "               OpCapability ShaderNonUniform\n";
2241                                         s << "               OpCapability RuntimeDescriptorArray\n";
2242                                         s << "               OpCapability SampledImageArrayNonUniformIndexing\n";
2243                                         s << "               OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2244                                         s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
2245                                         s << "               OpMemoryModel Logical GLSL450\n";
2246                                         s << "               OpEntryPoint Fragment %main \"main\" %FragColor %data %rIndex %position %normalpos %vIndex %gIndex %bIndex %aIndex\n";
2247                                         s << "               OpExecutionMode %main OriginUpperLeft\n";
2248                                         s << "               OpSource GLSL 450\n";
2249                                         s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2250                                         s << "               OpSourceExtension \"GL_EXT_texture_buffer\"\n";
2251                                         s << "               OpName %main \"main\"\n";
2252                                         s << "               OpName %FragColor \"FragColor\"\n";
2253                                         s << "               OpName %data \"data\"\n";
2254                                         s << "               OpName %rIndex \"rIndex\"\n";
2255                                         s << "               OpName %position \"position\"\n";
2256                                         s << "               OpName %normalpos \"normalpos\"\n";
2257                                         s << "               OpName %vIndex \"vIndex\"\n";
2258                                         s << "               OpName %gIndex \"gIndex\"\n";
2259                                         s << "               OpName %bIndex \"bIndex\"\n";
2260                                         s << "               OpName %aIndex \"aIndex\"\n";
2261                                         s << "               OpDecorate %FragColor Location 0\n";
2262                                         s << "               OpDecorate %data DescriptorSet 0\n";
2263                                         s << "               OpDecorate %data Binding 7\n";
2264                                         s << "               OpDecorate %rIndex Flat\n";
2265                                         s << "               OpDecorate %rIndex Location 3\n";
2266                                         // s << "               OpDecorate %19 NonUniform\n";
2267                                         // s << "               OpDecorate %21 NonUniform\n";
2268                                         s << "               OpDecorate %22 NonUniform\n";
2269                                         if (testCaseParams.usesMipMaps)
2270                                         {
2271                                                 // s << "               OpDecorate %27 NonUniform\n";
2272                                                 // s << "               OpDecorate %28 NonUniform\n";
2273                                                 // s << "               OpDecorate %29 NonUniform\n";
2274                                                 s << "               OpDecorate %30 NonUniform\n";
2275                                         }
2276                                         s << "               OpDecorate %position Flat\n";
2277                                         s << "               OpDecorate %position Location 0\n";
2278                                         s << "               OpDecorate %normalpos Flat\n";
2279                                         s << "               OpDecorate %normalpos Location 1\n";
2280                                         s << "               OpDecorate %vIndex Flat\n";
2281                                         s << "               OpDecorate %vIndex Location 2\n";
2282                                         s << "               OpDecorate %gIndex Flat\n";
2283                                         s << "               OpDecorate %gIndex Location 4\n";
2284                                         s << "               OpDecorate %bIndex Flat\n";
2285                                         s << "               OpDecorate %bIndex Location 5\n";
2286                                         s << "               OpDecorate %aIndex Flat\n";
2287                                         s << "               OpDecorate %aIndex Location 6\n";
2288                                         s << "       %void = OpTypeVoid\n";
2289                                         s << "          %3 = OpTypeFunction %void\n";
2290                                         s << "      %float = OpTypeFloat 32\n";
2291                                         s << "    %v4float = OpTypeVector %float 4\n";
2292                                         s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
2293                                         s << "  %FragColor = OpVariable %_ptr_Output_v4float Output\n";
2294                                         s << "         %10 = OpTypeImage %float 2D 0 0 0 1 Unknown\n";
2295                                         s << "         %11 = OpTypeSampledImage %10\n";
2296                                         s << "%_runtimearr_11 = OpTypeRuntimeArray %11\n";
2297                                         s << "%_ptr_UniformConstant__runtimearr_11 = OpTypePointer UniformConstant %_runtimearr_11\n";
2298                                         s << "       %data = OpVariable %_ptr_UniformConstant__runtimearr_11 UniformConstant\n";
2299                                         s << "        %int = OpTypeInt 32 1\n";
2300                                         s << "%_ptr_Input_int = OpTypePointer Input %int\n";
2301                                         s << "     %rIndex = OpVariable %_ptr_Input_int Input\n";
2302                                         s << "%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11\n";
2303                                         s << "    %v2float = OpTypeVector %float 2\n";
2304                                         s << "    %float_0 = OpConstant %float 0\n";
2305                                         s << "      %int_1 = OpConstant %int 1\n";
2306                                         s << "         %25 = OpConstantComposite %v2float %float_0 %float_0\n";
2307                                         s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
2308                                         s << "   %position = OpVariable %_ptr_Input_v4float Input\n";
2309                                         s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
2310                                         s << "  %normalpos = OpVariable %_ptr_Input_v2float Input\n";
2311                                         s << "     %vIndex = OpVariable %_ptr_Input_int Input\n";
2312                                         s << "     %gIndex = OpVariable %_ptr_Input_int Input\n";
2313                                         s << "     %bIndex = OpVariable %_ptr_Input_int Input\n";
2314                                         s << "     %aIndex = OpVariable %_ptr_Input_int Input\n";
2315                                         s << "       %main = OpFunction %void None %3\n";
2316                                         s << "          %5 = OpLabel\n";
2317                                         s << "         %18 = OpLoad %int %rIndex\n";
2318                                         s << "         %19 = OpCopyObject %int %18\n";
2319                                         s << "         %21 = OpAccessChain %_ptr_UniformConstant_11 %data %19\n";
2320                                         s << "         %22 = OpLoad %11 %21\n";
2321                                         if (testCaseParams.usesMipMaps)
2322                                         {
2323                                                 s << "          %26 = OpLoad %int %rIndex\n";
2324                                                 s << "          %27 = OpCopyObject %int %26\n";
2325                                                 s << "          %28 = OpAccessChain %_ptr_UniformConstant_11 %data %27\n";
2326                                                 s << "          %29 = OpLoad %11 %28\n";
2327                                                 s << "          %30 = OpImage %10 %29\n";
2328                                                 s << "          %31 = OpImageQueryLevels %int %30\n";
2329                                                 s << "          %33 = OpISub %int %31 %int_1\n";
2330                                                 s << "          %34 = OpConvertSToF %float %33\n";
2331                                                 s << "          %35 = OpImageSampleExplicitLod %v4float %22 %25 Lod %34\n";
2332                                                 s << "                OpStore %FragColor %35\n";
2333                                         }
2334                                         else
2335                                         {
2336                                                 s << "         %26 = OpImageSampleImplicitLod %v4float %22 %25\n";
2337                                                 s << "               OpStore %FragColor %26\n";
2338                                         }
2339                                         s << "               OpReturn\n";
2340                                         s << "               OpFunctionEnd\n";
2341                                         break;
2342                                 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
2343                                         s << "               OpCapability Shader\n";
2344                                         s << "               OpCapability SampledBuffer\n";
2345                                         s << "               OpCapability ShaderNonUniform\n";
2346                                         s << "               OpCapability RuntimeDescriptorArray\n";
2347                                         s << "               OpCapability UniformTexelBufferArrayNonUniformIndexing\n";
2348                                         s << "               OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2349                                         s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
2350                                         s << "               OpMemoryModel Logical GLSL450\n";
2351                                         s << "               OpEntryPoint Fragment %main \"main\" %FragColor %data %rIndex %position %normalpos %vIndex %gIndex %bIndex %aIndex\n";
2352                                         s << "               OpExecutionMode %main OriginUpperLeft\n";
2353                                         s << "               OpSource GLSL 450\n";
2354                                         s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2355                                         s << "               OpSourceExtension \"GL_EXT_texture_buffer\"\n";
2356                                         s << "               OpName %main \"main\"\n";
2357                                         s << "               OpName %FragColor \"FragColor\"\n";
2358                                         s << "               OpName %data \"data\"\n";
2359                                         s << "               OpName %rIndex \"rIndex\"\n";
2360                                         s << "               OpName %position \"position\"\n";
2361                                         s << "               OpName %normalpos \"normalpos\"\n";
2362                                         s << "               OpName %vIndex \"vIndex\"\n";
2363                                         s << "               OpName %gIndex \"gIndex\"\n";
2364                                         s << "               OpName %bIndex \"bIndex\"\n";
2365                                         s << "               OpName %aIndex \"aIndex\"\n";
2366                                         s << "               OpDecorate %FragColor Location 0\n";
2367                                         s << "               OpDecorate %data DescriptorSet 0\n";
2368                                         s << "               OpDecorate %data Binding 3\n";
2369                                         s << "               OpDecorate %rIndex Flat\n";
2370                                         s << "               OpDecorate %rIndex Location 3\n";
2371                                         // s << "               OpDecorate %19 NonUniform\n";
2372                                         // s << "               OpDecorate %21 NonUniform\n";
2373                                         // s << "               OpDecorate %22 NonUniform\n";
2374                                         s << "               OpDecorate %24 NonUniform\n";
2375                                         s << "               OpDecorate %position Flat\n";
2376                                         s << "               OpDecorate %position Location 0\n";
2377                                         s << "               OpDecorate %normalpos Flat\n";
2378                                         s << "               OpDecorate %normalpos Location 1\n";
2379                                         s << "               OpDecorate %vIndex Flat\n";
2380                                         s << "               OpDecorate %vIndex Location 2\n";
2381                                         s << "               OpDecorate %gIndex Flat\n";
2382                                         s << "               OpDecorate %gIndex Location 4\n";
2383                                         s << "               OpDecorate %bIndex Flat\n";
2384                                         s << "               OpDecorate %bIndex Location 5\n";
2385                                         s << "               OpDecorate %aIndex Flat\n";
2386                                         s << "               OpDecorate %aIndex Location 6\n";
2387                                         s << "       %void = OpTypeVoid\n";
2388                                         s << "          %3 = OpTypeFunction %void\n";
2389                                         s << "      %float = OpTypeFloat 32\n";
2390                                         s << "    %v4float = OpTypeVector %float 4\n";
2391                                         s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
2392                                         s << "  %FragColor = OpVariable %_ptr_Output_v4float Output\n";
2393                                         s << "         %10 = OpTypeImage %float Buffer 0 0 0 1 Unknown\n";
2394                                         s << "         %11 = OpTypeSampledImage %10\n";
2395                                         s << "%_runtimearr_11 = OpTypeRuntimeArray %11\n";
2396                                         s << "%_ptr_UniformConstant__runtimearr_11 = OpTypePointer UniformConstant %_runtimearr_11\n";
2397                                         s << "       %data = OpVariable %_ptr_UniformConstant__runtimearr_11 UniformConstant\n";
2398                                         s << "        %int = OpTypeInt 32 1\n";
2399                                         s << "%_ptr_Input_int = OpTypePointer Input %int\n";
2400                                         s << "     %rIndex = OpVariable %_ptr_Input_int Input\n";
2401                                         s << "%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11\n";
2402                                         s << "      %int_0 = OpConstant %int 0\n";
2403                                         s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
2404                                         s << "   %position = OpVariable %_ptr_Input_v4float Input\n";
2405                                         s << "    %v2float = OpTypeVector %float 2\n";
2406                                         s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
2407                                         s << "  %normalpos = OpVariable %_ptr_Input_v2float Input\n";
2408                                         s << "     %vIndex = OpVariable %_ptr_Input_int Input\n";
2409                                         s << "     %gIndex = OpVariable %_ptr_Input_int Input\n";
2410                                         s << "     %bIndex = OpVariable %_ptr_Input_int Input\n";
2411                                         s << "     %aIndex = OpVariable %_ptr_Input_int Input\n";
2412                                         s << "       %main = OpFunction %void None %3\n";
2413                                         s << "          %5 = OpLabel\n";
2414                                         s << "         %18 = OpLoad %int %rIndex\n";
2415                                         s << "         %19 = OpCopyObject %int %18\n";
2416                                         s << "         %21 = OpAccessChain %_ptr_UniformConstant_11 %data %19\n";
2417                                         s << "         %22 = OpLoad %11 %21\n";
2418                                         s << "         %24 = OpImage %10 %22\n";
2419                                         s << "         %25 = OpImageFetch %v4float %24 %int_0\n";
2420                                         s << "               OpStore %FragColor %25\n";
2421                                         s << "               OpReturn\n";
2422                                         s << "               OpFunctionEnd\n";
2423                                         break;
2424                                 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
2425                                         s << "               OpCapability Shader\n";
2426                                         s << "               OpCapability ImageBuffer\n";
2427                                         s << "               OpCapability ShaderNonUniform\n";
2428                                         s << "               OpCapability RuntimeDescriptorArray\n";
2429                                         s << "               OpCapability StorageTexelBufferArrayNonUniformIndexing\n";
2430                                         s << "               OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2431                                         s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
2432                                         s << "               OpMemoryModel Logical GLSL450\n";
2433                                         s << "               OpEntryPoint Fragment %main \"main\" %FragColor %data %rIndex %position %normalpos %vIndex %gIndex %bIndex %aIndex\n";
2434                                         s << "               OpExecutionMode %main OriginUpperLeft\n";
2435                                         s << "               OpSource GLSL 450\n";
2436                                         s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2437                                         s << "               OpName %main \"main\"\n";
2438                                         s << "               OpName %FragColor \"FragColor\"\n";
2439                                         s << "               OpName %data \"data\"\n";
2440                                         s << "               OpName %rIndex \"rIndex\"\n";
2441                                         s << "               OpName %position \"position\"\n";
2442                                         s << "               OpName %normalpos \"normalpos\"\n";
2443                                         s << "               OpName %vIndex \"vIndex\"\n";
2444                                         s << "               OpName %gIndex \"gIndex\"\n";
2445                                         s << "               OpName %bIndex \"bIndex\"\n";
2446                                         s << "               OpName %aIndex \"aIndex\"\n";
2447                                         s << "               OpDecorate %FragColor Location 0\n";
2448                                         s << "               OpDecorate %data DescriptorSet 0\n";
2449                                         s << "               OpDecorate %data Binding 4\n";
2450                                         s << "               OpDecorate %rIndex Flat\n";
2451                                         s << "               OpDecorate %rIndex Location 3\n";
2452                                         // s << "               OpDecorate %18 NonUniform\n";
2453                                         // s << "               OpDecorate %20 NonUniform\n";
2454                                         s << "               OpDecorate %21 NonUniform\n";
2455                                         s << "               OpDecorate %position Flat\n";
2456                                         s << "               OpDecorate %position Location 0\n";
2457                                         s << "               OpDecorate %normalpos Flat\n";
2458                                         s << "               OpDecorate %normalpos Location 1\n";
2459                                         s << "               OpDecorate %vIndex Flat\n";
2460                                         s << "               OpDecorate %vIndex Location 2\n";
2461                                         s << "               OpDecorate %gIndex Flat\n";
2462                                         s << "               OpDecorate %gIndex Location 4\n";
2463                                         s << "               OpDecorate %bIndex Flat\n";
2464                                         s << "               OpDecorate %bIndex Location 5\n";
2465                                         s << "               OpDecorate %aIndex Flat\n";
2466                                         s << "               OpDecorate %aIndex Location 6\n";
2467                                         s << "       %void = OpTypeVoid\n";
2468                                         s << "          %3 = OpTypeFunction %void\n";
2469                                         s << "      %float = OpTypeFloat 32\n";
2470                                         s << "    %v4float = OpTypeVector %float 4\n";
2471                                         s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
2472                                         s << "  %FragColor = OpVariable %_ptr_Output_v4float Output\n";
2473                                         s << "         %10 = OpTypeImage %float Buffer 0 0 0 2 Rgba32f\n";
2474                                         s << "%_runtimearr_10 = OpTypeRuntimeArray %10\n";
2475                                         s << "%_ptr_UniformConstant__runtimearr_10 = OpTypePointer UniformConstant %_runtimearr_10\n";
2476                                         s << "       %data = OpVariable %_ptr_UniformConstant__runtimearr_10 UniformConstant\n";
2477                                         s << "        %int = OpTypeInt 32 1\n";
2478                                         s << "%_ptr_Input_int = OpTypePointer Input %int\n";
2479                                         s << "     %rIndex = OpVariable %_ptr_Input_int Input\n";
2480                                         s << "%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10\n";
2481                                         s << "      %int_0 = OpConstant %int 0\n";
2482                                         s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
2483                                         s << "   %position = OpVariable %_ptr_Input_v4float Input\n";
2484                                         s << "    %v2float = OpTypeVector %float 2\n";
2485                                         s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
2486                                         s << "  %normalpos = OpVariable %_ptr_Input_v2float Input\n";
2487                                         s << "     %vIndex = OpVariable %_ptr_Input_int Input\n";
2488                                         s << "     %gIndex = OpVariable %_ptr_Input_int Input\n";
2489                                         s << "     %bIndex = OpVariable %_ptr_Input_int Input\n";
2490                                         s << "     %aIndex = OpVariable %_ptr_Input_int Input\n";
2491                                         s << "       %main = OpFunction %void None %3\n";
2492                                         s << "          %5 = OpLabel\n";
2493                                         s << "         %17 = OpLoad %int %rIndex\n";
2494                                         s << "         %18 = OpCopyObject %int %17\n";
2495                                         s << "         %20 = OpAccessChain %_ptr_UniformConstant_10 %data %18\n";
2496                                         s << "         %21 = OpLoad %10 %20\n";
2497                                         s << "         %23 = OpImageRead %v4float %21 %int_0\n";
2498                                         s << "               OpStore %FragColor %23\n";
2499                                         s << "               OpReturn\n";
2500                                         s << "               OpFunctionEnd\n";
2501                                         break;
2502                                 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2503                                         s << "               OpCapability Shader\n";
2504                                         s << "               OpCapability ShaderNonUniform\n";
2505                                         s << "               OpCapability RuntimeDescriptorArray\n";
2506                                         s << "               OpCapability StorageBufferArrayNonUniformIndexing\n";
2507                                         s << "               OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2508                                         s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
2509                                         s << "               OpMemoryModel Logical GLSL450\n";
2510                                         s << "               OpEntryPoint Fragment %main \"main\" %FragColor %data %rIndex %position %normalpos %vIndex %gIndex %bIndex %aIndex\n";
2511                                         s << "               OpExecutionMode %main OriginUpperLeft\n";
2512                                         s << "               OpSource GLSL 450\n";
2513                                         s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2514                                         s << "               OpName %main \"main\"\n";
2515                                         s << "               OpName %FragColor \"FragColor\"\n";
2516                                         s << "               OpName %Data \"Data\"\n";
2517                                         s << "               OpMemberName %Data 0 \"cnew\"\n";
2518                                         s << "               OpMemberName %Data 1 \"cold\"\n";
2519                                         s << "               OpName %data \"data\"\n";
2520                                         s << "               OpName %rIndex \"rIndex\"\n";
2521                                         s << "               OpName %position \"position\"\n";
2522                                         s << "               OpName %normalpos \"normalpos\"\n";
2523                                         s << "               OpName %vIndex \"vIndex\"\n";
2524                                         s << "               OpName %gIndex \"gIndex\"\n";
2525                                         s << "               OpName %bIndex \"bIndex\"\n";
2526                                         s << "               OpName %aIndex \"aIndex\"\n";
2527                                         s << "               OpDecorate %FragColor Location 0\n";
2528                                         s << "               OpMemberDecorate %Data 0 Offset 0\n";
2529                                         s << "               OpMemberDecorate %Data 1 Offset 16\n";
2530                                         s << "               OpDecorate %Data Block\n";
2531                                         s << "               OpDecorate %data DescriptorSet 0\n";
2532                                         s << "               OpDecorate %data Binding 2\n";
2533                                         s << "               OpDecorate %rIndex Flat\n";
2534                                         s << "               OpDecorate %rIndex Location 3\n";
2535                                         // s << "               OpDecorate %18 NonUniform\n";
2536                                         s << "               OpDecorate %21 NonUniform\n";
2537                                         // s << "               OpDecorate %22 NonUniform\n";
2538                                         s << "               OpDecorate %position Flat\n";
2539                                         s << "               OpDecorate %position Location 0\n";
2540                                         s << "               OpDecorate %normalpos Flat               OpDecorate %normalpos Location 1\n";
2541                                         s << "               OpDecorate %vIndex Flat\n";
2542                                         s << "               OpDecorate %vIndex Location 2\n";
2543                                         s << "               OpDecorate %gIndex Flat\n";
2544                                         s << "               OpDecorate %gIndex Location 4\n";
2545                                         s << "               OpDecorate %bIndex Flat\n";
2546                                         s << "               OpDecorate %bIndex Location 5\n";
2547                                         s << "               OpDecorate %aIndex Flat\n";
2548                                         s << "               OpDecorate %aIndex Location 6\n";
2549                                         s << "       %void = OpTypeVoid\n";
2550                                         s << "          %3 = OpTypeFunction %void\n";
2551                                         s << "      %float = OpTypeFloat 32\n";
2552                                         s << "    %v4float = OpTypeVector %float 4\n";
2553                                         s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
2554                                         s << "  %FragColor = OpVariable %_ptr_Output_v4float Output\n";
2555                                         s << "       %Data = OpTypeStruct %v4float %v4float\n";
2556                                         s << "%_runtimearr_Data = OpTypeRuntimeArray %Data\n";
2557                                         s << "%_ptr_StorageBuffer__runtimearr_Data = OpTypePointer StorageBuffer %_runtimearr_Data\n";
2558                                         s << "       %data = OpVariable %_ptr_StorageBuffer__runtimearr_Data StorageBuffer\n";
2559                                         s << "        %int = OpTypeInt 32 1\n";
2560                                         s << "%_ptr_Input_int = OpTypePointer Input %int\n";
2561                                         s << "     %rIndex = OpVariable %_ptr_Input_int Input\n";
2562                                         s << "      %int_1 = OpConstant %int 1\n";
2563                                         s << "%_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float\n";
2564                                         s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
2565                                         s << "   %position = OpVariable %_ptr_Input_v4float Input\n";
2566                                         s << "    %v2float = OpTypeVector %float 2\n";
2567                                         s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
2568                                         s << "  %normalpos = OpVariable %_ptr_Input_v2float Input\n";
2569                                         s << "     %vIndex = OpVariable %_ptr_Input_int Input\n";
2570                                         s << "     %gIndex = OpVariable %_ptr_Input_int Input\n";
2571                                         s << "     %bIndex = OpVariable %_ptr_Input_int Input\n";
2572                                         s << "     %aIndex = OpVariable %_ptr_Input_int Input\n";
2573                                         s << "       %main = OpFunction %void None %3\n";
2574                                         s << "          %5 = OpLabel\n";
2575                                         s << "         %17 = OpLoad %int %rIndex\n";
2576                                         s << "         %18 = OpCopyObject %int %17\n";
2577                                         s << "         %21 = OpAccessChain %_ptr_StorageBuffer_v4float %data %18 %int_1\n";
2578                                         s << "         %22 = OpLoad %v4float %21\n";
2579                                         s << "               OpStore %FragColor %22\n";
2580                                         s << "               OpReturn\n";
2581                                         s << "               OpFunctionEnd\n";
2582                                         break;
2583                                 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
2584                                         s << "               OpCapability Shader\n";
2585                                         s << "               OpCapability ShaderNonUniform\n";
2586                                         s << "               OpCapability RuntimeDescriptorArray\n";
2587                                         s << "               OpCapability UniformBufferArrayNonUniformIndexing\n";
2588                                         s << "               OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2589                                         s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
2590                                         s << "               OpMemoryModel Logical GLSL450\n";
2591                                         s << "               OpEntryPoint Fragment %main \"main\" %FragColor %data %rIndex %position %normalpos %vIndex %gIndex %bIndex %aIndex\n";
2592                                         s << "               OpExecutionMode %main OriginUpperLeft\n";
2593                                         s << "               OpSource GLSL 450\n";
2594                                         s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2595                                         s << "               OpName %main \"main\"\n";
2596                                         s << "               OpName %FragColor \"FragColor\"\n";
2597                                         s << "               OpName %Data \"Data\"\n";
2598                                         s << "               OpMemberName %Data 0 \"c\"\n";
2599                                         s << "               OpName %data \"data\"\n";
2600                                         s << "               OpName %rIndex \"rIndex\"\n";
2601                                         s << "               OpName %position \"position\"\n";
2602                                         s << "               OpName %normalpos \"normalpos\"\n";
2603                                         s << "               OpName %vIndex \"vIndex\"\n";
2604                                         s << "               OpName %gIndex \"gIndex\"\n";
2605                                         s << "               OpName %bIndex \"bIndex\"\n";
2606                                         s << "               OpName %aIndex \"aIndex\"\n";
2607                                         s << "               OpDecorate %FragColor Location 0\n";
2608                                         s << "               OpMemberDecorate %Data 0 Offset 0\n";
2609                                         s << "               OpDecorate %Data Block\n";
2610                                         s << "               OpDecorate %data DescriptorSet 0\n";
2611                                         s << "               OpDecorate %data Binding 1\n";
2612                                         s << "               OpDecorate %rIndex Flat\n";
2613                                         s << "               OpDecorate %rIndex Location 3\n";
2614                                         // s << "               OpDecorate %18 NonUniform\n";
2615                                         s << "               OpDecorate %21 NonUniform\n";
2616                                         // s << "               OpDecorate %22 NonUniform\n";
2617                                         s << "               OpDecorate %position Flat\n";
2618                                         s << "               OpDecorate %position Location 0\n";
2619                                         s << "               OpDecorate %normalpos Flat\n";
2620                                         s << "               OpDecorate %normalpos Location 1\n";
2621                                         s << "               OpDecorate %vIndex Flat\n";
2622                                         s << "               OpDecorate %vIndex Location 2\n";
2623                                         s << "               OpDecorate %gIndex Flat\n";
2624                                         s << "               OpDecorate %gIndex Location 4\n";
2625                                         s << "               OpDecorate %bIndex Flat\n";
2626                                         s << "               OpDecorate %bIndex Location 5\n";
2627                                         s << "               OpDecorate %aIndex Flat\n";
2628                                         s << "               OpDecorate %aIndex Location 6\n";
2629                                         s << "       %void = OpTypeVoid\n";
2630                                         s << "          %3 = OpTypeFunction %void\n";
2631                                         s << "      %float = OpTypeFloat 32\n";
2632                                         s << "    %v4float = OpTypeVector %float 4\n";
2633                                         s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
2634                                         s << "  %FragColor = OpVariable %_ptr_Output_v4float Output\n";
2635                                         s << "       %Data = OpTypeStruct %v4float\n";
2636                                         s << "%_runtimearr_Data = OpTypeRuntimeArray %Data\n";
2637                                         s << "%_ptr_Uniform__runtimearr_Data = OpTypePointer Uniform %_runtimearr_Data\n";
2638                                         s << "       %data = OpVariable %_ptr_Uniform__runtimearr_Data Uniform\n";
2639                                         s << "        %int = OpTypeInt 32 1\n";
2640                                         s << "%_ptr_Input_int = OpTypePointer Input %int\n";
2641                                         s << "     %rIndex = OpVariable %_ptr_Input_int Input\n";
2642                                         s << "      %int_0 = OpConstant %int 0\n";
2643                                         s << "%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float\n";
2644                                         s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
2645                                         s << "   %position = OpVariable %_ptr_Input_v4float Input\n";
2646                                         s << "    %v2float = OpTypeVector %float 2\n";
2647                                         s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
2648                                         s << "  %normalpos = OpVariable %_ptr_Input_v2float Input\n";
2649                                         s << "     %vIndex = OpVariable %_ptr_Input_int Input\n";
2650                                         s << "     %gIndex = OpVariable %_ptr_Input_int Input\n";
2651                                         s << "     %bIndex = OpVariable %_ptr_Input_int Input\n";
2652                                         s << "     %aIndex = OpVariable %_ptr_Input_int Input\n";
2653                                         s << "       %main = OpFunction %void None %3\n";
2654                                         s << "          %5 = OpLabel\n";
2655                                         s << "         %17 = OpLoad %int %rIndex\n";
2656                                         s << "         %18 = OpCopyObject %int %17\n";
2657                                         s << "         %21 = OpAccessChain %_ptr_Uniform_v4float %data %18 %int_0\n";
2658                                         s << "         %22 = OpLoad %v4float %21\n";
2659                                         s << "               OpStore %FragColor %22\n";
2660                                         s << "               OpReturn\n";
2661                                         s << "               OpFunctionEnd\n";
2662                                         break;
2663                                 default:
2664                                         TCU_THROW(InternalError, "Unexpected descriptor type");
2665                         }
2666                     break;
2667                 case VK_SHADER_STAGE_COMPUTE_BIT:
2668                         switch (testCaseParams.descriptorType)
2669                         {
2670                                 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
2671                                         s << "               OpCapability Shader\n";
2672                                         s << "               OpCapability ShaderNonUniform\n";
2673                                         s << "               OpCapability RuntimeDescriptorArray\n";
2674                                         s << "               OpCapability StorageImageArrayNonUniformIndexing\n";
2675                                         s << "               OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2676                                         s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
2677                                         s << "               OpMemoryModel Logical GLSL450\n";
2678                                         s << "               OpEntryPoint GLCompute %main \"main\" %idxs %gl_WorkGroupID %data\n";
2679                                         s << "               OpExecutionMode %main LocalSize 1 1 1\n";
2680                                         s << "               OpSource GLSL 450\n";
2681                                         s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2682                                         s << "               OpName %main \"main\"\n";
2683                                         s << "               OpName %c \"c\"\n";
2684                                         s << "               OpName %idxs \"idxs\"\n";
2685                                         s << "               OpName %gl_WorkGroupID \"gl_WorkGroupID\"\n";
2686                                         s << "               OpName %data \"data\"\n";
2687                                         s << "               OpDecorate %idxs DescriptorSet 0\n";
2688                                         s << "               OpDecorate %idxs Binding 12\n";
2689                                         s << "               OpDecorate %gl_WorkGroupID BuiltIn WorkgroupId\n";
2690                                         s << "               OpDecorate %data DescriptorSet 0\n";
2691                                         s << "               OpDecorate %data Binding 11\n";
2692                                         // s << "               OpDecorate %36 NonUniform\n";
2693                                         // s << "               OpDecorate %37 NonUniform\n";
2694                                         s << "               OpDecorate %41 NonUniform\n";
2695                                         s << "               OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize\n";
2696                                         s << "       %void = OpTypeVoid\n";
2697                                         s << "          %3 = OpTypeFunction %void\n";
2698                                         s << "       %uint = OpTypeInt 32 0\n";
2699                                         s << "     %v4uint = OpTypeVector %uint 4\n";
2700                                         s << "%_ptr_Function_v4uint = OpTypePointer Function %v4uint\n";
2701                                         s << "         %10 = OpTypeImage %uint 2D 0 0 0 2 R32ui\n";
2702                                         s << "%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10\n";
2703                                         s << "       %idxs = OpVariable %_ptr_UniformConstant_10 UniformConstant\n";
2704                                         s << "     %v3uint = OpTypeVector %uint 3\n";
2705                                         s << "%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n";
2706                                         s << "%gl_WorkGroupID = OpVariable %_ptr_Input_v3uint Input\n";
2707                                         s << "     %uint_0 = OpConstant %uint 0\n";
2708                                         s << "%_ptr_Input_uint = OpTypePointer Input %uint\n";
2709                                         s << "        %int = OpTypeInt 32 1\n";
2710                                         s << "     %uint_1 = OpConstant %uint 1\n";
2711                                         s << "      %v2int = OpTypeVector %int 2\n";
2712                                         s << "%_runtimearr_10 = OpTypeRuntimeArray %10\n";
2713                                         s << "%_ptr_UniformConstant__runtimearr_10 = OpTypePointer UniformConstant %_runtimearr_10\n";
2714                                         s << "       %data = OpVariable %_ptr_UniformConstant__runtimearr_10 UniformConstant\n";
2715                                         s << "%_ptr_Function_uint = OpTypePointer Function %uint\n";
2716                                         s << "      %int_0 = OpConstant %int 0\n";
2717                                         s << "         %39 = OpConstantComposite %v2int %int_0 %int_0\n";
2718                                         s << "%_ptr_Image_uint = OpTypePointer Image %uint\n";
2719                                         s << "%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1\n";
2720                                         s << "       %main = OpFunction %void None %3\n";
2721                                         s << "          %5 = OpLabel\n";
2722                                         s << "          %c = OpVariable %_ptr_Function_v4uint Function\n";
2723                                         s << "         %13 = OpLoad %10 %idxs\n";
2724                                         s << "         %19 = OpAccessChain %_ptr_Input_uint %gl_WorkGroupID %uint_0\n";
2725                                         s << "         %20 = OpLoad %uint %19\n";
2726                                         s << "         %22 = OpBitcast %int %20\n";
2727                                         s << "         %24 = OpAccessChain %_ptr_Input_uint %gl_WorkGroupID %uint_1\n";
2728                                         s << "         %25 = OpLoad %uint %24\n";
2729                                         s << "         %26 = OpBitcast %int %25\n";
2730                                         s << "         %28 = OpCompositeConstruct %v2int %22 %26\n";
2731                                         s << "         %29 = OpImageRead %v4uint %13 %28 ZeroExtend\n";
2732                                         s << "               OpStore %c %29\n";
2733                                         s << "         %34 = OpAccessChain %_ptr_Function_uint %c %uint_0\n";
2734                                         s << "         %35 = OpLoad %uint %34\n";
2735                                         s << "         %36 = OpCopyObject %uint %35\n";
2736                                         s << "         %37 = OpAccessChain %_ptr_UniformConstant_10 %data %36\n";
2737                                         s << "         %41 = OpImageTexelPointer %_ptr_Image_uint %37 %39 %uint_0\n";
2738                                         s << "         %42 = OpAtomicIAdd %uint %41 %uint_1 %uint_0 %uint_1\n";
2739                                         s << "               OpReturn\n";
2740                                         s << "               OpFunctionEnd\n";
2741                                         break;
2742                                 default:
2743                                         TCU_THROW(InternalError, "Unexpected descriptor type");
2744                         }
2745                         break;
2746                 default:
2747                         TCU_THROW(InternalError, "Unexpected stage");
2748         }
2749
2750         return s.str();
2751 }
2752
2753 std::string CommonDescriptorInstance::getShaderSource                           (VkShaderStageFlagBits                                          shaderType,
2754                                                                                                                                          const TestCaseParams&                                          testCaseParams,
2755                                                                                                                                          bool                                                                           allowVertexStoring)
2756 {
2757         std::stringstream       s;
2758
2759         s << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << '\n';
2760         s << "#extension GL_EXT_nonuniform_qualifier : require  \n";
2761
2762         if (testCaseParams.calculateInLoop)
2763         {
2764                 s << "layout(push_constant)     uniform Block { int lowerBound, upperBound; } pc;\n";
2765                 s << substBinding(BINDING_DescriptorEnumerator,
2766                         "layout(set=1,binding=${?}) uniform isamplerBuffer iter;        \n");
2767         }
2768
2769         switch (testCaseParams.descriptorType)
2770         {
2771                 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2772                         s << substBinding(BINDING_StorageBuffer,
2773                                 "layout(set=0,binding=${?}) buffer Data { vec4 cnew, cold; } data[]; \n");
2774                         break;
2775                 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
2776                         s << substBinding(BINDING_StorageBufferDynamic,
2777                                 "layout(set=0,binding=${?}) buffer Data { vec4 cnew, cold; } data[]; \n");
2778                         break;
2779                 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
2780                         s << substBinding(BINDING_UniformBuffer,
2781                                 "layout(set=0,binding=${?}) uniform Data { vec4 c; } data[]; \n");
2782                         break;
2783                 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
2784                         s << substBinding(BINDING_UniformBufferDynamic,
2785                                 "layout(set=0,binding=${?}) uniform Data { vec4 c; } data[]; \n");
2786                         break;
2787                 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
2788                         s << substBinding(BINDING_StorageTexelBuffer,
2789                                 "layout(set=0,binding=${?},rgba32f) uniform imageBuffer data[];\n");
2790                         break;
2791                 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
2792                         s << "#extension GL_EXT_texture_buffer : require        \n";
2793                         s << substBinding(BINDING_UniformTexelBuffer,
2794                                 "layout(set=0,binding=${?}) uniform samplerBuffer data[];\n");
2795                         break;
2796                 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
2797                         // Left for the consistent of code.
2798                         // Header is set one swicth below
2799                         break;
2800                 case VK_DESCRIPTOR_TYPE_SAMPLER:
2801                         s << "#extension GL_EXT_texture_buffer : require        \n";
2802                         s << substBinding(BINDING_SampledImage,
2803                                 "layout(set=0,binding=${?}) uniform texture2D ${VAR}[${*}];\n", 1, "tex");
2804                         s << substBinding(BINDING_Sampler,
2805                                 "layout(set=0,binding=${?}) uniform sampler ${VAR}[${*}];\n");
2806                         break;
2807                 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
2808                         s << "#extension GL_EXT_texture_buffer : require        \n";
2809                         s << substBinding(BINDING_Sampler,
2810                                 "layout(set=0,binding=${?}) uniform sampler ${VAR}[${*}];\n", 1, "samp");
2811                         s << substBinding(BINDING_SampledImage,
2812                                 "layout(set=0,binding=${?}) uniform texture2D ${VAR}[${*}];\n");
2813                         break;
2814                 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
2815                         s << "#extension GL_EXT_texture_buffer : require        \n";
2816                         s << substBinding(BINDING_CombinedImageSampler,
2817                                 "layout(set=0,binding=${?}) uniform sampler2D data[];\n");
2818                         break;
2819                 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
2820                         s << "layout(local_size_x=1,local_size_y=1,local_size_z=1) in;  \n";
2821                         s << substBinding(BINDING_StorageImage + 1,
2822                                 "layout(r32ui,set=0,binding=${?}) uniform uimage2D idxs;        \n");
2823                         s << substBinding(BINDING_StorageImage,
2824                                 "layout(r32ui,set=0,binding=${?}) uniform uimage2D data[];      \n");
2825                         break;
2826                 default:
2827                         TCU_THROW(InternalError, "Not implemented descriptor type");
2828         }
2829
2830         switch (shaderType)
2831         {
2832                 case VK_SHADER_STAGE_VERTEX_BIT:        s << getVertexShaderProlog();   break;
2833                 case VK_SHADER_STAGE_FRAGMENT_BIT:
2834                         {
2835                                 if (testCaseParams.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)
2836                                 {
2837                                         s << substBinding(BINDING_InputAttachment,
2838                                                 "layout(input_attachment_index=1,set=0,binding=${?}) uniform subpassInput data[];       \n");
2839                                 }
2840                                 s << getFragmentShaderProlog();
2841                         }
2842                         break;
2843                 case VK_SHADER_STAGE_COMPUTE_BIT:
2844                         break;
2845                 default:
2846                         TCU_THROW(InternalError, "Not implemented shader stage");
2847         }
2848
2849         switch (shaderType)
2850         {
2851                 case VK_SHADER_STAGE_VERTEX_BIT:
2852                 {
2853                         switch (testCaseParams.descriptorType)
2854                         {
2855                         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2856                         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
2857                                 if (allowVertexStoring)
2858                                         s << "  if (gIndex != 0) data[nonuniformEXT(gIndex)].cnew = data[nonuniformEXT(rIndex)].cold;   \n";
2859                                 break;
2860                         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
2861                                 if (allowVertexStoring)
2862                                         s << "  if (gIndex != 0) imageStore(data[nonuniformEXT(gIndex)], 1, imageLoad(data[nonuniformEXT(rIndex)], 0)); \n";
2863                                 break;
2864                         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
2865                         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
2866                         case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
2867                         case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
2868                         case VK_DESCRIPTOR_TYPE_SAMPLER:
2869                         case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
2870                         case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
2871                                 break;
2872
2873                         default:
2874                                 TCU_THROW(InternalError, "Not implemented descriptor type");
2875                         }
2876                 }
2877                 break;
2878
2879                 case VK_SHADER_STAGE_FRAGMENT_BIT:
2880                 {
2881                         switch (testCaseParams.descriptorType)
2882                         {
2883                         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2884                         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
2885                         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
2886                                 {
2887                                         if (testCaseParams.calculateInLoop)
2888                                                 s << getFragmentLoopSource(
2889                                                         getColorAccess(testCaseParams.descriptorType, "rIndex", false),
2890                                                         getColorAccess(testCaseParams.descriptorType, "loopIdx", false));
2891                                         else
2892                                                 s << getFragmentReturnSource(getColorAccess(testCaseParams.descriptorType, "rIndex", false));
2893                                 }
2894                                 break;
2895                         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
2896                         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
2897                         case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
2898                         case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
2899                         case VK_DESCRIPTOR_TYPE_SAMPLER:
2900                         case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
2901                         case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
2902                                 if (testCaseParams.calculateInLoop)
2903                                         s << getFragmentLoopSource(
2904                                                 getColorAccess(testCaseParams.descriptorType, "rIndex", testCaseParams.usesMipMaps),
2905                                                 getColorAccess(testCaseParams.descriptorType, "loopIdx", testCaseParams.usesMipMaps));
2906                                 else
2907                                         s << getFragmentReturnSource(getColorAccess(testCaseParams.descriptorType, "rIndex", testCaseParams.usesMipMaps));
2908                                 break;
2909                         default:        TCU_THROW(InternalError, "Not implemented descriptor type");
2910                         }
2911                 }
2912                 break;
2913
2914                 case VK_SHADER_STAGE_COMPUTE_BIT: // VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
2915                         s << "void main(void)\n{\n";
2916                         if (testCaseParams.calculateInLoop)
2917                                 s << "  for (int i = pc.lowerBound; i < pc.upperBound; ++i)     \n"
2918                                         "    imageAtomicAdd(data[nonuniformEXT(texelFetch(iter, i).x)], ivec2(0, 0), 1);                        \n";
2919                         else
2920                                 s << "  uvec4 c = imageLoad(idxs, ivec2(gl_WorkGroupID.x, gl_WorkGroupID.y));   \n"
2921                                         "  imageAtomicAdd( data[nonuniformEXT(c.r)], ivec2(0, 0), 1);                                                           \n";
2922                         break;
2923
2924                 default:        TCU_THROW(InternalError, "Not implemented shader stage");
2925         }
2926
2927         s << getShaderEpilog();
2928
2929         return s.str();
2930 }
2931
2932 class StorageBufferInstance : virtual public CommonDescriptorInstance
2933 {
2934 public:
2935                                                                 StorageBufferInstance                           (Context&                                                                       context,
2936                                                                                                                                          const TestCaseParams&                                          testCaseParams);
2937 protected:
2938         virtual void                            createAndPopulateDescriptors            (IterateCommonVariables&                                        variables);
2939
2940         virtual bool                            verifyVertexWriteResults                        (IterateCommonVariables&                                        variables);
2941 };
2942
2943 StorageBufferInstance::StorageBufferInstance                                            (Context&                                                                       context,
2944                                                                                                                                          const TestCaseParams&                                          testCaseParams)
2945         : CommonDescriptorInstance(context,
2946                 TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
2947                         VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
2948                         BINDING_StorageBuffer,
2949                         VK_DESCRIPTOR_TYPE_UNDEFINED,
2950                         BINDING_Undefined,
2951                         false,
2952                         performWritesInVertex(testCaseParams.descriptorType, context),
2953                         testCaseParams))
2954 {
2955 }
2956
2957 void StorageBufferInstance::createAndPopulateDescriptors                        (IterateCommonVariables&                                        variables)
2958 {
2959         BindingStorageBuffer::Data      data;
2960
2961         bool                                            vertexStores = false;
2962         {
2963                 ut::DeviceProperties dp(m_context);
2964                 vertexStores = dp.physicalDeviceFeatures().vertexPipelineStoresAndAtomics != DE_FALSE;
2965         }
2966         const deUint32                          alignment       = static_cast<deUint32>(ut::DeviceProperties(m_context).physicalDeviceProperties().limits.minStorageBufferOffsetAlignment);
2967         createBuffers(variables.descriptorsBufferInfos, variables.descriptorsBuffer, variables.validDescriptorCount, sizeof(data), alignment, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
2968
2969         unsigned char*                          buffer          = static_cast<unsigned char*>(variables.descriptorsBuffer->alloc->getHostPtr());
2970         for (deUint32 infoIdx = 0; infoIdx < variables.validDescriptorCount; ++infoIdx)
2971         {
2972                 const float                             component       = m_colorScheme[infoIdx % m_schemeSize];
2973                 const tcu::Vec4                 color           (component, component, component, 1.0f);
2974                 VkDescriptorBufferInfo& info            = variables.descriptorsBufferInfos[infoIdx];
2975                 data.cnew                                                       = vertexStores ? m_clearColor : color;
2976                 data.cold                                                       = color;
2977
2978                 deMemcpy(buffer + info.offset, &data, sizeof(data));
2979         }
2980         vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
2981
2982         variables.dataAlignment = deAlign64(sizeof(data), alignment);
2983 }
2984
2985 bool StorageBufferInstance::verifyVertexWriteResults                            (IterateCommonVariables&                                        variables)
2986 {
2987         const tcu::Vec4                         threshold               (0.002f, 0.002f, 0.002f, 0.002f);
2988         const std::vector<deUint32>     primes                  = ut::generatePrimes(variables.availableDescriptorCount);
2989
2990         unsigned char*                          buffer = static_cast<unsigned char*>(variables.descriptorsBuffer->alloc->getHostPtr());
2991         BindingStorageBuffer::Data      data;
2992         for (deUint32 primeIdx = 0; primeIdx < variables.validDescriptorCount; ++primeIdx)
2993         {
2994                 const deUint32                  prime           = primes[primeIdx];
2995                 const float                             component       = m_colorScheme[(prime % variables.validDescriptorCount) % m_schemeSize];
2996                 const tcu::Vec4                 referenceValue(component, component, component, 1.0f);
2997
2998                 VkDescriptorBufferInfo& info = variables.descriptorsBufferInfos[primeIdx];
2999                 deMemcpy(&data, buffer + info.offset, sizeof(data));
3000                 const tcu::Vec4                 realValue = data.cnew;
3001
3002                 const tcu::Vec4                 diff = tcu::absDiff(referenceValue, realValue);
3003                 if (!tcu::boolAll(tcu::lessThanEqual(diff, threshold)))
3004                         return false;
3005         }
3006         return true;
3007 }
3008
3009 class UniformBufferInstance : virtual public CommonDescriptorInstance
3010 {
3011 public:
3012                                                                 UniformBufferInstance                           (Context&                                                                       context,
3013                                                                                                                                          const TestCaseParams&                                          testCaseParams);
3014 protected:
3015         virtual void                            createAndPopulateDescriptors            (IterateCommonVariables&                                        variables);
3016 };
3017
3018 UniformBufferInstance::UniformBufferInstance                                            (Context&                                                                       context,
3019                                                                                                                                          const TestCaseParams&                                          testCaseParams)
3020         : CommonDescriptorInstance(context,
3021                 TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
3022                         VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
3023                         BINDING_UniformBuffer,
3024                         VK_DESCRIPTOR_TYPE_UNDEFINED,
3025                         BINDING_Undefined,
3026                         false,
3027                         performWritesInVertex(testCaseParams.descriptorType, context),
3028                         testCaseParams))
3029 {
3030 }
3031
3032 void UniformBufferInstance::createAndPopulateDescriptors                        (IterateCommonVariables&                                        variables)
3033 {
3034         BindingUniformBuffer::Data data;
3035
3036         const deUint32                          alignment       = static_cast<deUint32>(ut::DeviceProperties(m_context).physicalDeviceProperties().limits.minUniformBufferOffsetAlignment);
3037         createBuffers(variables.descriptorsBufferInfos, variables.descriptorsBuffer, variables.validDescriptorCount, sizeof(data), alignment, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
3038
3039         unsigned char*                          buffer          = static_cast<unsigned char*>(variables.descriptorsBuffer->alloc->getHostPtr());
3040         for (deUint32 infoIdx = 0; infoIdx < variables.validDescriptorCount; ++infoIdx)
3041         {
3042                 const float                             component       = m_colorScheme[infoIdx % m_schemeSize];
3043                 VkDescriptorBufferInfo& info            = variables.descriptorsBufferInfos[infoIdx];
3044                 data.c                                                          = tcu::Vec4(component, component, component, 1.0f);
3045                 deMemcpy(buffer + info.offset, &data, sizeof(data));
3046         }
3047         vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3048
3049         variables.dataAlignment = deAlign64(sizeof(data), alignment);
3050 }
3051
3052 class StorageTexelInstance : public CommonDescriptorInstance
3053 {
3054 public:
3055                                                                 StorageTexelInstance                            (Context&                                                                       context,
3056                                                                                                                                          const TestCaseParams&                                          testCaseParams);
3057 private:
3058         virtual void                            createAndPopulateDescriptors            (IterateCommonVariables&                                        variables);
3059
3060         virtual bool                            verifyVertexWriteResults                        (IterateCommonVariables&                                        variables);
3061 };
3062
3063 StorageTexelInstance::StorageTexelInstance                                                      (Context&                                                                       context,
3064                                                                                                                                          const TestCaseParams&                                          testCaseParams)
3065         : CommonDescriptorInstance(context,
3066                 TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
3067                         VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
3068                         BINDING_StorageTexelBuffer,
3069                         VK_DESCRIPTOR_TYPE_UNDEFINED,
3070                         BINDING_Undefined,
3071                         false,
3072                         performWritesInVertex(testCaseParams.descriptorType, context),
3073                         testCaseParams))
3074 {
3075 }
3076
3077 void StorageTexelInstance::createAndPopulateDescriptors                 (IterateCommonVariables&                                        variables)
3078 {
3079         const VkExtent3D                        imageExtent                     = { 4, 4, 1 };
3080         const deUint32                          imageSize                       = ut::computeImageSize(imageExtent, m_colorFormat);
3081
3082         createBuffers(variables.descriptorsBufferInfos, variables.descriptorsBuffer, variables.validDescriptorCount, imageSize, sizeof(tcu::Vec4), VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT);
3083         createBuffersViews(variables.descriptorsBufferViews, variables.descriptorsBufferInfos, m_colorFormat);
3084
3085         for (deUint32 imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
3086         {
3087                 const float                             component                       = m_colorScheme[imageIdx % m_schemeSize];
3088                 const PixelBufferAccess pa                                      = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer);
3089
3090                 tcu::clear(pa, m_clearColor);
3091                 pa.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
3092         }
3093         vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3094 }
3095
3096 bool StorageTexelInstance::verifyVertexWriteResults(IterateCommonVariables&                                     variables)
3097 {
3098         const VkExtent3D                        imageExtent             = { 4, 4, 1 };
3099         const tcu::Vec4                         threshold               (0.002f, 0.002f, 0.002f, 0.002f);
3100         const std::vector<deUint32>     primes                  = ut::generatePrimes(variables.availableDescriptorCount);
3101
3102         for (deUint32 primeIdx = 0; primeIdx < variables.validDescriptorCount; ++primeIdx)
3103         {
3104                 const deUint32                  prime           = primes[primeIdx];
3105                 const float                             component       = m_colorScheme[( prime % variables.validDescriptorCount ) % m_schemeSize];
3106                 const tcu::Vec4                 referenceValue(component, component, component, 1.0f);
3107
3108                 const PixelBufferAccess pa                      = getPixelAccess(primeIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer);
3109                 const tcu::Vec4                 realValue       = pa.getPixel(1, 0);
3110
3111                 const tcu::Vec4                 diff            = tcu::absDiff(referenceValue, realValue);
3112                 if (!tcu::boolAll(tcu::lessThanEqual(diff, threshold)))
3113                         return false;
3114         }
3115         return true;
3116 }
3117
3118 class UniformTexelInstance : public CommonDescriptorInstance
3119 {
3120 public:
3121                                                                 UniformTexelInstance                            (Context&                                                                       context,
3122                                                                                                                                          const TestCaseParams&                                          testCaseParams);
3123 private:
3124         virtual void                            createAndPopulateDescriptors            (IterateCommonVariables&                                        variables);
3125 };
3126
3127 UniformTexelInstance::UniformTexelInstance                                                      (Context&                                                                       context,
3128                                                                                                                                          const TestCaseParams&                                          testCaseParams)
3129         : CommonDescriptorInstance(context,
3130                 TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
3131                         VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
3132                         BINDING_UniformTexelBuffer,
3133                         VK_DESCRIPTOR_TYPE_UNDEFINED,
3134                         BINDING_Undefined,
3135                         false,
3136                         performWritesInVertex(testCaseParams.descriptorType, context),
3137                         testCaseParams))
3138 {
3139 }
3140
3141 void UniformTexelInstance::createAndPopulateDescriptors                         (IterateCommonVariables&                                        variables)
3142 {
3143         const VkExtent3D                        imageExtent     = { 4, 4, 1 };
3144         const deUint32                          imageSize       = ut::computeImageSize(imageExtent, m_colorFormat);
3145
3146         createBuffers(variables.descriptorsBufferInfos, variables.descriptorsBuffer, variables.validDescriptorCount, imageSize, sizeof(tcu::Vec4), VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT);
3147         createBuffersViews(variables.descriptorsBufferViews, variables.descriptorsBufferInfos, m_colorFormat);
3148
3149         for (deUint32 imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
3150         {
3151                 const float                             component       = m_colorScheme[imageIdx % m_schemeSize];
3152                 const PixelBufferAccess pa                      = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer);
3153
3154                 tcu::clear(pa, tcu::Vec4(component, component, component, 1.0f));
3155         }
3156         vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3157 }
3158
3159 class DynamicBuffersInstance : virtual public CommonDescriptorInstance
3160 {
3161 public:
3162         DynamicBuffersInstance                                                                                  (Context&                                                                       context,
3163                                                                                                                                          const TestParams&                                                      testParams)
3164                 : CommonDescriptorInstance(context, testParams) {}
3165
3166 protected:
3167         virtual tcu::TestStatus         iterate                                                         (void);
3168         virtual void                            updateDescriptors                                       (IterateCommonVariables&                                        variables);
3169 };
3170
3171 void DynamicBuffersInstance::updateDescriptors                                          (IterateCommonVariables&                                        variables)
3172 {
3173         DE_ASSERT(variables.dataAlignment);
3174
3175         VkDescriptorBufferInfo  bufferInfo =
3176         {
3177                 *variables.descriptorsBuffer.get()->buffer,
3178                 0,      // always 0, it will be taken from pDynamicOffsets
3179                 variables.dataAlignment
3180         };
3181
3182         VkWriteDescriptorSet updateInfo =
3183         {
3184                 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,                 // sType
3185                 DE_NULL,                                                                                // pNext
3186                 *variables.descriptorSet,                                               // descriptorSet
3187                 m_testParams.descriptorBinding,                                 // descriptorBinding;
3188                 0,      // to be set in below loop                                      // dstArrayElement
3189                 1u,                                                                                             // descriptorCount
3190                 m_testParams.descriptorType,                                    // descriptorType
3191                 DE_NULL,                                                                                // pImageInfo
3192                 &bufferInfo,                                                                    // pBufferInfo
3193                 DE_NULL                                                                                 // pTexelBufferView
3194         };
3195
3196         deUint32 descIdx = 0;
3197         const std::vector<deUint32> primes = ut::generatePrimes(variables.availableDescriptorCount);
3198         for (deUint32 validIdx = 0; validIdx < variables.validDescriptorCount; ++validIdx)
3199         {
3200                 for (; descIdx < primes[validIdx]; ++descIdx)
3201                 {
3202                         updateInfo.dstArrayElement                      = descIdx;
3203                         m_vki.updateDescriptorSets      (m_vkd, 1u, &updateInfo, 0u, DE_NULL);
3204                 }
3205
3206                 updateInfo.dstArrayElement                              = primes[validIdx];
3207                 m_vki.updateDescriptorSets              (m_vkd, 1u, &updateInfo, 0u, DE_NULL);
3208
3209                 ++descIdx;
3210         }
3211         for (; descIdx < variables.availableDescriptorCount; ++descIdx)
3212         {
3213                 updateInfo.dstArrayElement = descIdx;
3214                 m_vki.updateDescriptorSets(m_vkd, 1u, &updateInfo, 0u, DE_NULL);
3215         }
3216 }
3217
3218 tcu::TestStatus DynamicBuffersInstance::iterate                                         (void)
3219 {
3220         IterateCommonVariables  v;
3221         iterateCommandSetup             (v);
3222
3223         ut::UpdatablePixelBufferAccessPtr       programResult;
3224         ut::UpdatablePixelBufferAccessPtr       referenceResult;
3225         bool firstPass = true;
3226
3227         DE_ASSERT(v.dataAlignment);
3228
3229         std::vector<deUint32> dynamicOffsets;
3230
3231         deUint32 descIdx = 0;
3232         const std::vector<deUint32> primes = ut::generatePrimes(v.availableDescriptorCount);
3233         for (deUint32 validIdx = 0; validIdx < v.validDescriptorCount; ++validIdx)
3234         {
3235                 for (; descIdx < primes[validIdx]; ++descIdx)
3236                 {
3237                         dynamicOffsets.push_back(0);
3238                 }
3239
3240                 dynamicOffsets.push_back(static_cast<deUint32>(validIdx * v.dataAlignment));
3241
3242                 ++descIdx;
3243         }
3244         for (; descIdx < v.availableDescriptorCount; ++descIdx)
3245         {
3246                 dynamicOffsets.push_back(0);
3247         }
3248
3249         // Unfortunatelly not lees and not more, only exactly
3250         DE_ASSERT(dynamicOffsets.size() == v.availableDescriptorCount);
3251
3252         const VkDescriptorSet   descriptorSets[] = { *v.descriptorSet };
3253
3254         v.renderArea.extent.width       = m_testParams.frameResolution.width/4;
3255         v.renderArea.extent.height      = m_testParams.frameResolution.height/4;
3256
3257         for (int x = 0; x < 4; x++)
3258                 for (int y= 0; y < 4; y++)
3259                 {
3260
3261                         v.renderArea.offset.x           = x * m_testParams.frameResolution.width/4;
3262                         v.renderArea.offset.y           = y * m_testParams.frameResolution.height/4;
3263
3264                         iterateCommandBegin             (v, firstPass);
3265                         firstPass = false;
3266
3267         m_vki.cmdBindDescriptorSets(
3268                 *v.commandBuffer,                                               // commandBuffer
3269                 VK_PIPELINE_BIND_POINT_GRAPHICS,                // pipelineBindPoint
3270                 *v.pipelineLayout,                                              // layout
3271                 0u,                                                                             // firstSet
3272                 DE_LENGTH_OF_ARRAY(descriptorSets),             // descriptorSetCount
3273                 descriptorSets,                                                 // pDescriptorSets
3274                 v.availableDescriptorCount,                             // dynamicOffsetCount
3275                 dynamicOffsets.data());                                 // pDynamicOffsets
3276
3277                         vk::VkRect2D scissor = makeRect2D(v.renderArea.offset.x, v.renderArea.offset.y, v.renderArea.extent.width, v.renderArea.extent.height);
3278         m_vki.cmdSetScissor(*v.commandBuffer, 0u, 1u, &scissor);
3279
3280         vk::beginRenderPass     (m_vki, *v.commandBuffer, *v.renderPass, *v.frameBuffer->buffer, v.renderArea, m_clearColor);
3281                         m_vki.cmdDraw                   (*v.commandBuffer, v.vertexCount, 1u, 0u, 0u);
3282         vk::endRenderPass       (m_vki, *v.commandBuffer);
3283
3284                         iterateCommandEnd(v, programResult, referenceResult);
3285                         programResult->invalidate();
3286                 }
3287
3288         return (iterateVerifyResults(v, programResult, referenceResult) ? tcu::TestStatus::pass : tcu::TestStatus::fail)("");
3289 }
3290
3291 class DynamicStorageBufferInstance : public DynamicBuffersInstance, public StorageBufferInstance
3292 {
3293 public:
3294         DynamicStorageBufferInstance                                                                    (Context&                                       context,
3295                                                                                                                                          const TestCaseParams&          testCaseParams);
3296         tcu::TestStatus         iterate                                                                         (void);
3297         void                            createAndPopulateDescriptors                            (IterateCommonVariables&        variables);
3298         void                            updateDescriptors                                                       (IterateCommonVariables&        variables);
3299         bool                            verifyVertexWriteResults                                        (IterateCommonVariables&        variables);
3300 };
3301
3302 DynamicStorageBufferInstance::DynamicStorageBufferInstance                      (Context&                                       context,
3303                                                                                                                                          const TestCaseParams&          testCaseParams)
3304         : CommonDescriptorInstance(context,
3305                 TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
3306                         VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC,
3307                         BINDING_StorageBufferDynamic,
3308                         VK_DESCRIPTOR_TYPE_UNDEFINED,
3309                         BINDING_Undefined,
3310                         false,
3311                         performWritesInVertex(testCaseParams.descriptorType, context),
3312                         testCaseParams)),
3313                         DynamicBuffersInstance(context, m_testParams), StorageBufferInstance(context, testCaseParams)
3314 {
3315 }
3316
3317 tcu::TestStatus DynamicStorageBufferInstance::iterate(void)
3318 {
3319         return DynamicBuffersInstance::iterate();
3320 }
3321
3322 void DynamicStorageBufferInstance::createAndPopulateDescriptors(IterateCommonVariables&                 variables)
3323 {
3324         StorageBufferInstance::createAndPopulateDescriptors(variables);
3325 }
3326
3327 void DynamicStorageBufferInstance::updateDescriptors(IterateCommonVariables&                                    variables)
3328 {
3329         DynamicBuffersInstance::updateDescriptors(variables);
3330 }
3331
3332 bool DynamicStorageBufferInstance::verifyVertexWriteResults(IterateCommonVariables&                             variables)
3333 {
3334         return StorageBufferInstance::verifyVertexWriteResults(variables);
3335 }
3336
3337 class DynamicUniformBufferInstance : public DynamicBuffersInstance, public UniformBufferInstance
3338 {
3339 public:
3340         DynamicUniformBufferInstance                                                                    (Context&                                       context,
3341                                                                                                                                          const TestCaseParams&          testCaseParams);
3342         tcu::TestStatus         iterate(void);
3343         void                            createAndPopulateDescriptors(IterateCommonVariables&                                    variables);
3344         void                            updateDescriptors(IterateCommonVariables&                                                               variables);
3345 };
3346
3347 DynamicUniformBufferInstance::DynamicUniformBufferInstance                      (Context&                                       context,
3348                                                                                                                                          const TestCaseParams&          testCaseParams)
3349         : CommonDescriptorInstance(context,
3350                 TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
3351                         VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
3352                         BINDING_UniformBufferDynamic,
3353                         VK_DESCRIPTOR_TYPE_UNDEFINED,
3354                         BINDING_Undefined,
3355                         false,
3356                         performWritesInVertex(testCaseParams.descriptorType, context),
3357                         testCaseParams)),
3358                         DynamicBuffersInstance(context, m_testParams), UniformBufferInstance(context, testCaseParams)
3359 {
3360 }
3361
3362 tcu::TestStatus DynamicUniformBufferInstance::iterate(void)
3363 {
3364         return DynamicBuffersInstance::iterate();
3365 }
3366
3367 void DynamicUniformBufferInstance::createAndPopulateDescriptors(IterateCommonVariables&                 variables)
3368 {
3369         UniformBufferInstance::createAndPopulateDescriptors(variables);
3370 }
3371
3372 void DynamicUniformBufferInstance::updateDescriptors(IterateCommonVariables&                                    variables)
3373 {
3374         DynamicBuffersInstance::updateDescriptors(variables);
3375 }
3376
3377 class InputAttachmentInstance : public CommonDescriptorInstance
3378 {
3379 public:
3380                                                                 InputAttachmentInstance                         (Context&                                                                       context,
3381                                                                                                                                         const TestCaseParams&                                           testCaseParams);
3382 private:
3383         virtual Move<VkRenderPass>      createRenderPass                                        (const IterateCommonVariables&                          variables);
3384         virtual void                            createFramebuffer                                       (ut::FrameBufferSp&                                                     frameBuffer,
3385                                                                                                                                          VkRenderPass                                                           renderPass,
3386                                                                                                                                          const IterateCommonVariables&                          variables);
3387         virtual void                            createAndPopulateDescriptors            (IterateCommonVariables&                                        variables);
3388 };
3389
3390 InputAttachmentInstance::InputAttachmentInstance                                        (Context&                                                                       context,
3391                                                                                                                                          const TestCaseParams&                                          testCaseParams)
3392         : CommonDescriptorInstance(context,
3393                 TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
3394                         VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
3395                         BINDING_InputAttachment,
3396                         VK_DESCRIPTOR_TYPE_UNDEFINED,
3397                         BINDING_Undefined,
3398                         true,
3399                         performWritesInVertex(testCaseParams.descriptorType, context),
3400                         testCaseParams))
3401 {
3402 }
3403
3404 void InputAttachmentInstance::createAndPopulateDescriptors                      (IterateCommonVariables&                                        variables)
3405 {
3406         createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer,
3407                 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, m_testParams.frameResolution, m_colorFormat, VK_IMAGE_LAYOUT_UNDEFINED, variables.validDescriptorCount);
3408         createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, m_colorFormat);
3409
3410         for (deUint32 descriptorIdx = 0; descriptorIdx < variables.validDescriptorCount; ++descriptorIdx)
3411         {
3412                 const float                                             component       = m_colorScheme[descriptorIdx % m_schemeSize];
3413                 const tcu::PixelBufferAccess    pa                      = getPixelAccess(descriptorIdx, m_testParams.frameResolution, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer);
3414                 tcu::clear(pa, tcu::Vec4(component, component, component, 1.0f));
3415         }
3416         vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3417 }
3418
3419 Move<VkRenderPass> InputAttachmentInstance::createRenderPass            (const IterateCommonVariables&                          variables)
3420 {
3421         std::vector<VkAttachmentDescription>    attachmentDescriptions;
3422         std::vector<VkAttachmentReference>              inputAttachmentRefs;
3423
3424         const VkAttachmentDescription   colorAttachmentDescription =
3425         {
3426                 (VkAttachmentDescriptionFlags)0,                        // VkAttachmentDescriptionFlags         flags;
3427                 m_colorFormat,                                                          // VkFormat                                                     format;
3428                 VK_SAMPLE_COUNT_1_BIT,                                          // VkSampleCountFlagBits                        samples;
3429                 VK_ATTACHMENT_LOAD_OP_CLEAR,                            // VkAttachmentLoadOp                           loadOp;
3430                 VK_ATTACHMENT_STORE_OP_STORE,                           // VkAttachmentStoreOp                          storeOp;
3431                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                        // VkAttachmentLoadOp                           stencilLoadOp;
3432                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                       // VkAttachmentStoreOp                          stencilStoreOp;
3433                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                                        initialLayout;
3434                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                                        finalLayout;
3435         };
3436         const VkAttachmentReference             colorAttachmentRef =
3437         {
3438                 0u,                                                                                             // deUint32                                                     attachment;
3439                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                // VkImageLayout                                        layout;
3440         };
3441         attachmentDescriptions.push_back(colorAttachmentDescription);
3442
3443         // build input atachments
3444         {
3445                 const std::vector<deUint32>     primes = ut::generatePrimes(variables.availableDescriptorCount);
3446                 const deUint32 inputCount = static_cast<deUint32>(variables.descriptorImageViews.size());
3447                 for (deUint32 inputIdx = 0; inputIdx < inputCount; ++inputIdx)
3448                 {
3449                         // primes holds the indices of input attachments for shader binding 10 which has input_attachment_index=1
3450                         deUint32 nextInputAttachmentIndex = primes[inputIdx] + 1;
3451
3452                         // Fill up the subpass description's input attachments with unused attachments forming gaps to the next referenced attachment
3453                         for (deUint32 unusedIdx = static_cast<deUint32>(inputAttachmentRefs.size()); unusedIdx < nextInputAttachmentIndex; ++unusedIdx)
3454                         {
3455                                 const VkAttachmentReference             inputAttachmentRef =
3456                                 {
3457                                         VK_ATTACHMENT_UNUSED,                                           // deUint32                                                     attachment;
3458                                         VK_IMAGE_LAYOUT_GENERAL                                         // VkImageLayout                                        layout;
3459                                 };
3460
3461                                 inputAttachmentRefs.push_back(inputAttachmentRef);
3462                         }
3463
3464                         const VkAttachmentDescription   inputAttachmentDescription =
3465                         {
3466                                 VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT,                // VkAttachmentDescriptionFlags         flags;
3467                                 variables.descriptorsImages[inputIdx]->format,  // VkFormat                                                     format;
3468                                 VK_SAMPLE_COUNT_1_BIT,                                                  // VkSampleCountFlagBits                        samples;
3469                                 VK_ATTACHMENT_LOAD_OP_LOAD,                                             // VkAttachmentLoadOp                           loadOp;
3470                                 VK_ATTACHMENT_STORE_OP_STORE,                                   // VkAttachmentStoreOp                          storeOp;
3471                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                // VkAttachmentLoadOp                           stencilLoadOp;
3472                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                               // VkAttachmentStoreOp                          stencilStoreOp;
3473                                 VK_IMAGE_LAYOUT_GENERAL,                                                // VkImageLayout                                        initialLayout;
3474                                 VK_IMAGE_LAYOUT_GENERAL                                                 // VkImageLayout                                        finalLayout;
3475                         };
3476
3477                         const VkAttachmentReference             inputAttachmentRef =
3478                         {
3479                                 inputIdx + 1,                                                           // deUint32                                                     attachment;
3480                                 VK_IMAGE_LAYOUT_GENERAL                                         // VkImageLayout                                        layout;
3481                         };
3482
3483                         inputAttachmentRefs.push_back(inputAttachmentRef);
3484                         attachmentDescriptions.push_back(inputAttachmentDescription);
3485                 }
3486         }
3487
3488         const VkSubpassDescription              subpassDescription =
3489         {
3490                 (VkSubpassDescriptionFlags)0,                                           // VkSubpassDescriptionFlags            flags;
3491                 VK_PIPELINE_BIND_POINT_GRAPHICS,                                        // VkPipelineBindPoint                          pipelineBindPoint;
3492                 static_cast<deUint32>(inputAttachmentRefs.size()),      // deUint32                                                     inputAttachmentCount;
3493                 inputAttachmentRefs.data(),                                                     // const VkAttachmentReference*         pInputAttachments;
3494                 1u,                                                                                                     // deUint32                                                     colorAttachmentCount;
3495                 &colorAttachmentRef,                                                            // const VkAttachmentReference*         pColorAttachments;
3496                 DE_NULL,                                                                                        // const VkAttachmentReference*         pResolveAttachments;
3497                 DE_NULL,                                                                                        // const VkAttachmentReference*         pDepthStencilAttachment;
3498                 0u,                                                                                                     // deUint32                                                     preserveAttachmentCount;
3499                 DE_NULL                                                                                         // const deUint32*                                      pPreserveAttachments;
3500         };
3501
3502         const VkRenderPassCreateInfo    renderPassInfo =
3503         {
3504                 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                              // VkStructureType                                      sType;
3505                 DE_NULL,                                                                                                // const void*                                          pNext;
3506                 (VkRenderPassCreateFlags)0,                                                             // VkRenderPassCreateFlags                      flags;
3507                 static_cast<deUint32>(attachmentDescriptions.size()),   // deUint32                                                     attachmentCount;
3508                 attachmentDescriptions.data(),                                                  // const VkAttachmentDescription*       pAttachments;
3509                 1u,                                                                                                             // deUint32                                                     subpassCount;
3510                 &subpassDescription,                                                                    // const VkSubpassDescription*          pSubpasses;
3511                 0u,                                                                                                             // deUint32                                                     dependencyCount;
3512                 DE_NULL                                                                                                 // const VkSubpassDependency*           pDependencies;
3513         };
3514
3515         return vk::createRenderPass(m_vki, m_vkd, &renderPassInfo);
3516 }
3517
3518 void InputAttachmentInstance::createFramebuffer                                         (ut::FrameBufferSp&                                                     frameBuffer,
3519                                                                                                                                          VkRenderPass                                                           renderPass,
3520                                                                                                                                          const IterateCommonVariables&                          variables)
3521 {
3522         std::vector<VkImageView>                        inputAttachments;
3523         const deUint32 viewCount = static_cast<deUint32>(variables.descriptorImageViews.size());
3524         inputAttachments.resize(viewCount);
3525         for (deUint32 viewIdx = 0; viewIdx < viewCount; ++viewIdx)
3526         {
3527                 inputAttachments[viewIdx] = **variables.descriptorImageViews[viewIdx];
3528         }
3529         ut::createFrameBuffer(frameBuffer, m_context, m_testParams.frameResolution, m_colorFormat, renderPass, viewCount, inputAttachments.data());
3530 }
3531
3532 class SamplerInstance : public CommonDescriptorInstance
3533 {
3534 public:
3535                                                                 SamplerInstance                                         (Context&                                                                       context,
3536                                                                                                                                          const TestCaseParams&                                          testCaseParams);
3537 private:
3538         virtual void                            createAndPopulateDescriptors            (IterateCommonVariables&                                        variables);
3539         virtual void                            updateDescriptors                                       (IterateCommonVariables&                                        variables);
3540 };
3541
3542 SamplerInstance::SamplerInstance                                                                        (Context&                                                                       context,
3543                                                                                                                                          const TestCaseParams&                                          testCaseParams)
3544         : CommonDescriptorInstance(context,
3545                 TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
3546                         VK_DESCRIPTOR_TYPE_SAMPLER,
3547                         BINDING_Sampler,
3548                         VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
3549                         BINDING_SampledImage,
3550                         true,
3551                         performWritesInVertex(testCaseParams.descriptorType, context),
3552                         testCaseParams))
3553 {
3554 }
3555
3556 void SamplerInstance::updateDescriptors                                                         (IterateCommonVariables&                                        variables)
3557 {
3558         DE_ASSERT(variables.descriptorsImages.size()            == 1);
3559         DE_ASSERT(variables.descriptorImageViews.size()         == 1);
3560         DE_ASSERT(variables.descriptorsBufferInfos.size()       == 1);
3561         DE_ASSERT(m_testParams.additionalDescriptorType         == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
3562         DE_ASSERT(variables.descriptorSamplers.size()           == variables.validDescriptorCount);
3563
3564         // update an image
3565         {
3566                 const VkDescriptorImageInfo imageInfo =
3567                 {
3568                         static_cast<VkSampler>(0),
3569                         **variables.descriptorImageViews[0],
3570                         VK_IMAGE_LAYOUT_GENERAL
3571                 };
3572
3573                 const VkWriteDescriptorSet writeInfo =
3574                 {
3575                         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,                 // sType
3576                         DE_NULL,                                                                                // pNext
3577                         *variables.descriptorSet,                                               // descriptorSet
3578                         BINDING_SampledImage,                                                   // descriptorBinding;
3579                         0,                                                                                              // elementIndex
3580                         1u,                                                                                             // descriptorCount
3581                         VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,                               // descriptorType
3582                         &imageInfo,                                                                             // pImageInfo
3583                         DE_NULL,                                                                                // pBufferInfo
3584                         DE_NULL                                                                                 // pTexelBufferView
3585                 };
3586
3587                 m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, DE_NULL);
3588         }
3589
3590         // update samplers
3591         CommonDescriptorInstance::updateDescriptors(variables);
3592 }
3593
3594 void SamplerInstance::createAndPopulateDescriptors                                      (IterateCommonVariables&                                        variables)
3595 {
3596         DE_ASSERT(variables.descriptorsImages.size()            == 0);
3597         DE_ASSERT(variables.descriptorImageViews.size()         == 0);
3598         DE_ASSERT(variables.descriptorsBufferInfos.size()       == 0);
3599         DE_ASSERT(variables.descriptorSamplers.size()           == 0);
3600
3601         // create and populate an image
3602         {
3603                 VkExtent3D imageExtent = m_testParams.frameResolution;
3604                 if (m_testParams.usesMipMaps)
3605                 {
3606                         imageExtent.width *= 2;
3607                         imageExtent.height *= 2;
3608                 }
3609
3610                 createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer,
3611                         VK_BUFFER_USAGE_TRANSFER_SRC_BIT, imageExtent, m_colorFormat, VK_IMAGE_LAYOUT_UNDEFINED, 1, m_testParams.usesMipMaps);
3612                 createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, m_colorFormat);
3613
3614                 PixelBufferAccess pa = getPixelAccess(0, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, m_testParams.usesMipMaps ? 1 : 0);
3615
3616                 for (deUint32 y = 0, pixelNum = 0; y < m_testParams.frameResolution.height; ++y)
3617                 {
3618                         for (deUint32 x = 0; x < m_testParams.frameResolution.width; ++x, ++pixelNum)
3619                         {
3620                                 const float             component       = m_colorScheme[(pixelNum % variables.validDescriptorCount) % m_schemeSize];
3621                                 pa.setPixel(tcu::Vec4(component, component, component, 1.0f), x, y);
3622                         }
3623                 }
3624
3625                 vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3626         }
3627
3628         const tcu::Sampler sampler(
3629                 tcu::Sampler::CLAMP_TO_BORDER,                                                                                                                  // wrapS
3630                 tcu::Sampler::CLAMP_TO_BORDER,                                                                                                                  // wrapT
3631                 tcu::Sampler::CLAMP_TO_BORDER,                                                                                                                  // wrapR
3632                 m_testParams.usesMipMaps ? tcu::Sampler::LINEAR_MIPMAP_NEAREST : tcu::Sampler::NEAREST, // minFilter
3633                 m_testParams.usesMipMaps ? tcu::Sampler::LINEAR_MIPMAP_NEAREST : tcu::Sampler::NEAREST, // magFilter
3634                 0.0f,                                                                                                                                                                   // lodTreshold
3635                 true,                                                                                                                                                                   // normalizeCoords
3636                 tcu::Sampler::COMPAREMODE_NONE,                                                                                                                 // compare
3637                 0,                                                                                                                                                                              // compareChannel
3638                 tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),                                                                                                              // borderColor
3639                 true);                                                                                                                                                                  // seamlessCubeMap
3640         const VkSamplerCreateInfo createInfo = vk::mapSampler(sampler, vk::mapVkFormat(m_colorFormat));
3641         variables.descriptorSamplers.resize(variables.validDescriptorCount);
3642
3643         for (deUint32 samplerIdx = 0; samplerIdx < variables.validDescriptorCount; ++samplerIdx)
3644         {
3645                 variables.descriptorSamplers[samplerIdx] = ut::SamplerSp(new Move<VkSampler>(vk::createSampler(m_vki, m_vkd, &createInfo)));
3646         }
3647 }
3648
3649 class SampledImageInstance : public CommonDescriptorInstance
3650 {
3651 public:
3652                                                                 SampledImageInstance                            (Context&                                                                       context,
3653                                                                                                                                          const TestCaseParams&                                          testCaseParams);
3654 private:
3655         virtual void                            createAndPopulateDescriptors            (IterateCommonVariables&                                        variables);
3656         virtual void                            updateDescriptors                                       (IterateCommonVariables&                                        variables);
3657 };
3658
3659 SampledImageInstance::SampledImageInstance                                                      (Context&                                                                       context,
3660                                                                                                                                          const TestCaseParams&                                          testCaseParams)
3661         : CommonDescriptorInstance(context,
3662                 TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
3663                         VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
3664                         BINDING_SampledImage,
3665                         VK_DESCRIPTOR_TYPE_SAMPLER,
3666                         BINDING_Sampler,
3667                         true,
3668                         performWritesInVertex(testCaseParams.descriptorType, context),
3669                         testCaseParams))
3670 {
3671 }
3672
3673 void SampledImageInstance::updateDescriptors                                            (IterateCommonVariables&                                        variables)
3674 {
3675         DE_ASSERT(variables.descriptorSamplers.size()           == 1);
3676         DE_ASSERT(variables.descriptorsImages.size()            == variables.validDescriptorCount);
3677         DE_ASSERT(variables.descriptorImageViews.size()         == variables.validDescriptorCount);
3678         DE_ASSERT(variables.descriptorsBufferInfos.size()       == variables.validDescriptorCount);
3679
3680         // update a sampler
3681         {
3682                 const VkDescriptorImageInfo samplerInfo =
3683                 {
3684                         **variables.descriptorSamplers[0],
3685                         static_cast<VkImageView>(0),
3686                         static_cast<VkImageLayout>(0)
3687                 };
3688
3689                 const VkWriteDescriptorSet writeInfo =
3690                 {
3691                         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,                 // sType
3692                         DE_NULL,                                                                                // pNext
3693                         *variables.descriptorSet,                                               // descriptorSet
3694                         BINDING_Sampler,                                                                // descriptorBinding;
3695                         0,                                                                                              // elementIndex
3696                         1u,                                                                                             // descriptorCount
3697                         VK_DESCRIPTOR_TYPE_SAMPLER,                                             // descriptorType
3698                         &samplerInfo,                                                                   // pImageInfo
3699                         DE_NULL,                                                                                // pBufferInfo
3700                         DE_NULL                                                                                 // pTexelBufferView
3701                 };
3702
3703                 m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, DE_NULL);
3704         }
3705
3706         // update images
3707         CommonDescriptorInstance::updateDescriptors(variables);
3708 }
3709
3710 void SampledImageInstance::createAndPopulateDescriptors                         (IterateCommonVariables&                                        variables)
3711 {
3712         DE_ASSERT(variables.descriptorSamplers.size()           == 0);
3713         DE_ASSERT(variables.descriptorsImages.size()            == 0);
3714         DE_ASSERT(variables.descriptorImageViews.size()         == 0);
3715         DE_ASSERT(variables.descriptorsBufferInfos.size()       == 0);
3716
3717         // create an only one sampler for all images
3718         {
3719                 const tcu::Sampler sampler(
3720                         tcu::Sampler::CLAMP_TO_BORDER,                                                                                                                          // wrapS
3721                         tcu::Sampler::CLAMP_TO_BORDER,                                                                                                                          // wrapT
3722                         tcu::Sampler::CLAMP_TO_BORDER,                                                                                                                          // wrapR
3723                         m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST,        // minFilter
3724                         m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST,        // magFilter
3725                         0.0f,                                                                                                                                                                           // lodTreshold
3726                         true,                                                                                                                                                                           // normalizeCoords
3727                         tcu::Sampler::COMPAREMODE_NONE,                                                                                                                         // compare
3728                         0,                                                                                                                                                                                      // compareChannel
3729                         tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),                                                                                                                      // borderColor
3730                         true);                                                                                                                                                                          // seamlessCubeMap
3731                 const VkSamplerCreateInfo createInfo = vk::mapSampler(sampler, vk::mapVkFormat(m_colorFormat));
3732                 variables.descriptorSamplers.push_back(ut::SamplerSp(new Move<VkSampler>(vk::createSampler(m_vki, m_vkd, &createInfo))));
3733         }
3734
3735         const VkExtent3D&                       imageExtent = m_testParams.usesMipMaps ? bigImageExtent : smallImageExtent;
3736
3737         createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer,
3738                 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, imageExtent, m_colorFormat, VK_IMAGE_LAYOUT_UNDEFINED, variables.validDescriptorCount, m_testParams.usesMipMaps);
3739         createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, m_colorFormat);
3740
3741         PixelBufferAccess                       pixelAccess;
3742         for (deUint32 imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
3743         {
3744                 const float                             component       = m_colorScheme[imageIdx % m_schemeSize];
3745
3746                 if (m_testParams.usesMipMaps)
3747                 {
3748                         const deUint32 mipCount = ut::computeMipMapCount(imageExtent);
3749                         DE_ASSERT(mipCount >= 2);
3750                         for (deUint32 mipIdx = 0; mipIdx < mipCount; ++mipIdx)
3751                         {
3752                                 pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, mipIdx);
3753                                 tcu::clear(pixelAccess, m_clearColor);
3754                         }
3755
3756                         pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, mipCount-1);
3757                         pixelAccess.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
3758                 }
3759                 else
3760                 {
3761                         pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, 0);
3762                         pixelAccess.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
3763                 }
3764         }
3765         vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3766 }
3767
3768 class CombinedImageInstance : public CommonDescriptorInstance
3769 {
3770 public:
3771                                                                 CombinedImageInstance                           (Context&                                                                       context,
3772                                                                                                                                          const TestCaseParams&                                          testCaseParams);
3773 private:
3774         virtual void                            createAndPopulateDescriptors            (IterateCommonVariables&                                        variables);
3775         virtual void                            updateDescriptors                                       (IterateCommonVariables&                                        variables);
3776 };
3777
3778 CombinedImageInstance::CombinedImageInstance                                            (Context&                                                                       context,
3779                                                                                                                                          const TestCaseParams&                                          testCaseParams)
3780         : CommonDescriptorInstance(context,
3781                 TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
3782                         testCaseParams.descriptorType,
3783                         BINDING_CombinedImageSampler,
3784                         VK_DESCRIPTOR_TYPE_UNDEFINED,
3785                         BINDING_Undefined,
3786                         true,
3787                         performWritesInVertex(testCaseParams.descriptorType),
3788                         testCaseParams))
3789 {
3790 }
3791
3792 void CombinedImageInstance::updateDescriptors                                           (IterateCommonVariables&                                        variables)
3793 {
3794         const std::vector<deUint32>     primes = ut::generatePrimes(variables.availableDescriptorCount);
3795         const deUint32                          primeCount = static_cast<deUint32>(primes.size());
3796
3797         DE_ASSERT(variables.descriptorSamplers.size()           == 1);
3798         DE_ASSERT(variables.descriptorsImages.size()            == primeCount);
3799         DE_ASSERT(variables.descriptorImageViews.size()         == primeCount);
3800         DE_ASSERT(variables.descriptorsBufferInfos.size()       == primeCount);
3801
3802         for (deUint32 primeIdx = 0; primeIdx < primeCount; ++primeIdx)
3803         {
3804                 const VkDescriptorImageInfo imageInfo =
3805                 {
3806                         **variables.descriptorSamplers[0],
3807                         **variables.descriptorImageViews[primeIdx],
3808                         VK_IMAGE_LAYOUT_GENERAL
3809                 };
3810
3811                 const VkWriteDescriptorSet writeInfo =
3812                 {
3813                         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,                 // sType
3814                         DE_NULL,                                                                                // pNext
3815                         *variables.descriptorSet,                                               // descriptorSet
3816                         BINDING_CombinedImageSampler,                                   // descriptorBinding;
3817                         primes[primeIdx],                                                               // elementIndex
3818                         1u,                                                                                             // descriptorCount
3819                         m_testParams.descriptorType,                                    // descriptorType
3820                         &imageInfo,                                                                             // pImageInfo
3821                         DE_NULL,                                                                                // pBufferInfo
3822                         DE_NULL                                                                                 // pTexelBufferView
3823                 };
3824
3825                 m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, DE_NULL);
3826         }
3827 }
3828
3829 void CombinedImageInstance::createAndPopulateDescriptors                        (IterateCommonVariables&                                        variables)
3830 {
3831         DE_ASSERT(variables.descriptorSamplers.size()           == 0);
3832         DE_ASSERT(variables.descriptorsImages.size()            == 0);
3833         DE_ASSERT(variables.descriptorImageViews.size()         == 0);
3834         DE_ASSERT(variables.descriptorsBufferInfos.size()       == 0);
3835         DE_ASSERT(variables.descriptorSamplers.size()           == 0);
3836
3837         const tcu::Sampler sampler(
3838                 tcu::Sampler::CLAMP_TO_BORDER,                                                                                                                          // wrapS
3839                 tcu::Sampler::CLAMP_TO_BORDER,                                                                                                                          // wrapT
3840                 tcu::Sampler::CLAMP_TO_BORDER,                                                                                                                          // wrapR
3841                 m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST,        // minFilter
3842                 m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST,        // magFilter
3843                 0.0f,                                                                                                                                                                           // lodTreshold
3844                 true,                                                                                                                                                                           // normalizeCoords
3845                 tcu::Sampler::COMPAREMODE_NONE,                                                                                                                         // compare
3846                 0,                                                                                                                                                                                      // compareChannel
3847                 tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),                                                                                                                      // borderColor
3848                 true);                                                                                                                                                                          // seamlessCubeMap
3849         const VkSamplerCreateInfo       createInfo = vk::mapSampler(sampler, vk::mapVkFormat(m_colorFormat));
3850         variables.descriptorSamplers.push_back(ut::SamplerSp(new Move<VkSampler>(vk::createSampler(m_vki, m_vkd, &createInfo))));
3851
3852         const VkExtent3D&                       imageExtent = m_testParams.usesMipMaps ? bigImageExtent : smallImageExtent;
3853         createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
3854                 imageExtent, m_colorFormat, VK_IMAGE_LAYOUT_UNDEFINED, variables.validDescriptorCount, m_testParams.usesMipMaps);
3855         createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, m_colorFormat);
3856
3857         PixelBufferAccess                       pixelAccess;
3858         for (deUint32 imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
3859         {
3860                 const float                             component = m_colorScheme[imageIdx % m_schemeSize];
3861
3862                 if (m_testParams.usesMipMaps)
3863                 {
3864                         const deUint32  mipCount = ut::computeMipMapCount(imageExtent);
3865                         DE_ASSERT(mipCount >= 2);
3866                         for (deUint32 mipIdx = 0; mipIdx < mipCount; ++mipIdx)
3867                         {
3868                                 pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, mipIdx);
3869                                 tcu::clear(pixelAccess, m_clearColor);
3870                         }
3871
3872                         pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, mipCount-1);
3873                         pixelAccess.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
3874                 }
3875                 else
3876                 {
3877                         pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, 0);
3878                         pixelAccess.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
3879                 }
3880         }
3881
3882         vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3883 }
3884
3885 class StorageImageInstance : public CommonDescriptorInstance
3886 {
3887 public:
3888                                                                 StorageImageInstance                            (Context&                                                                       context,
3889                                                                                                                                          const TestCaseParams&                                          testCaseParams);
3890 private:
3891         virtual tcu::TestStatus         iterate                                                         (void);
3892         virtual void                            createAndPopulateDescriptors            (IterateCommonVariables&                                        variables);
3893         virtual void                            updateDescriptors                                       (IterateCommonVariables&                                        variables);
3894         virtual void                            iterateCollectResults                           (ut::UpdatablePixelBufferAccessPtr&                     result,
3895                                                                                                                                          const IterateCommonVariables&                          variables,
3896                                                                                                                                          bool                                                                           fromTest);
3897         ut::BufferHandleAllocSp         m_buffer;
3898         const deUint32                          m_fillColor;
3899         typedef deUint32                        m_imageFormat_t;
3900 };
3901
3902 StorageImageInstance::StorageImageInstance                                                      (Context&                                                                       context,
3903                                                                                                                                          const TestCaseParams&                                          testCaseParams)
3904         : CommonDescriptorInstance(context,
3905                 TestParams      (VK_SHADER_STAGE_COMPUTE_BIT,
3906                                         VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
3907                                         BINDING_StorageImage,
3908                                         VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
3909                                         (BINDING_StorageImage + 1),
3910                                         true,
3911                                         performWritesInVertex(testCaseParams.descriptorType, context),
3912                                         testCaseParams))
3913         , m_buffer              ()
3914         , m_fillColor   (10)
3915 {
3916 }
3917
3918 void StorageImageInstance::updateDescriptors                                            (IterateCommonVariables&                                        variables)
3919 {
3920         // update image at last index
3921         {
3922                 VkDescriptorImageInfo           imageInfo =
3923                 {
3924                         static_cast<VkSampler>(0),
3925                         **variables.descriptorImageViews[variables.validDescriptorCount],
3926                         VK_IMAGE_LAYOUT_GENERAL
3927                 };
3928
3929                 const VkWriteDescriptorSet writeInfo =
3930                 {
3931                         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,         // sType
3932                         DE_NULL,                                                                        // pNext
3933                         *variables.descriptorSet,                                       // descriptorSet
3934                         m_testParams.additionalDescriptorBinding,       // descriptorBinding;
3935                         0,                                                                                      // elementIndex
3936                         1u,                                                                                     // descriptorCount
3937                         m_testParams.additionalDescriptorType,          // descriptorType
3938                         &imageInfo,                                                                     // pImageInfo
3939                         DE_NULL,                                                                        // pBufferInfo
3940                         DE_NULL                                                                         // pTexelBufferView
3941                 };
3942
3943                 m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, DE_NULL);
3944         }
3945
3946         // update rest images
3947         CommonDescriptorInstance::updateDescriptors(variables);
3948 }
3949
3950 void StorageImageInstance::createAndPopulateDescriptors                         (IterateCommonVariables&                                        variables)
3951 {
3952         const VkFormat                          imageFormat = ut::mapType2vkFormat<m_imageFormat_t>::value;
3953         const VkBufferUsageFlags        bufferUsage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
3954
3955         // create descriptor buffer, images and views
3956         {
3957                 const VkExtent3D                        imageExtent = { 4, 4, 1 };
3958
3959                 createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer,
3960                         bufferUsage, imageExtent, imageFormat, VK_IMAGE_LAYOUT_UNDEFINED, variables.validDescriptorCount);
3961
3962                 for (deUint32 imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
3963                 {
3964                         const PixelBufferAccess pa = getPixelAccess(imageIdx, imageExtent, imageFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer);
3965                         tcu::clear(pa, tcu::UVec4(m_fillColor));
3966                 }
3967                 vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3968         }
3969
3970         // create additional image that will be used as index container
3971         {
3972                 createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, m_buffer,
3973                         bufferUsage, m_testParams.frameResolution, imageFormat, VK_IMAGE_LAYOUT_UNDEFINED, 1);
3974
3975                 // populate buffer
3976                 const std::vector<deUint32>     primes = ut::generatePrimes(variables.availableDescriptorCount);
3977                 const PixelBufferAccess pa = getPixelAccess(variables.validDescriptorCount, m_testParams.frameResolution, imageFormat, variables.descriptorsBufferInfos, m_buffer);
3978                 for (deUint32 y = 0, pixel = 0; y < m_testParams.frameResolution.height; ++y)
3979                 {
3980                         for (deUint32 x = 0; x < m_testParams.frameResolution.width; ++x, ++pixel)
3981                         {
3982                                 const deUint32 component = primes[pixel % variables.validDescriptorCount];
3983                                 pa.setPixel(tcu::UVec4(component), x, y);
3984                         }
3985                 }
3986
3987                 // save changes
3988                 vk::flushAlloc(m_vki, m_vkd, *m_buffer->alloc);
3989         }
3990
3991         // create views for all previously created images
3992         createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, imageFormat);
3993 }
3994
3995 tcu::TestStatus StorageImageInstance::iterate                                           (void)
3996 {
3997         IterateCommonVariables  v;
3998         iterateCommandSetup             (v);
3999         iterateCommandBegin             (v);
4000
4001         ut::UpdatablePixelBufferAccessPtr       programResult;
4002         ut::UpdatablePixelBufferAccessPtr       referenceResult;
4003
4004         if (m_testParams.updateAfterBind)
4005         {
4006                 updateDescriptors       (v);
4007         }
4008
4009         copyBuffersToImages             (v);
4010
4011         m_vki.cmdDispatch               (*v.commandBuffer,
4012                                                         m_testParams.calculateInLoop ? 1 : v.renderArea.extent.width,
4013                                                         m_testParams.calculateInLoop ? 1 : v.renderArea.extent.height,
4014                                                         1);
4015
4016         copyImagesToBuffers             (v);
4017
4018         iterateCommandEnd(v, programResult, referenceResult, false);
4019
4020         return ( iterateVerifyResults(v, programResult, referenceResult) ? tcu::TestStatus::pass : tcu::TestStatus::fail)("");
4021 }
4022
4023 void StorageImageInstance::iterateCollectResults                                        (ut::UpdatablePixelBufferAccessPtr&                     result,
4024                                                                                                                                          const IterateCommonVariables&                          variables,
4025                                                                                                                                          bool                                                                           fromTest)
4026 {
4027         result = ut::UpdatablePixelBufferAccessPtr(new ut::PixelBufferAccessAllocation(
4028                 vk::mapVkFormat(ut::mapType2vkFormat<m_imageFormat_t>::value), m_testParams.frameResolution));
4029         const PixelBufferAccess& dst = *result.get();
4030
4031         if (fromTest)
4032         {
4033                 vk::invalidateAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
4034                 for (deUint32 y = 0, pixelNum = 0; y < m_testParams.frameResolution.height; ++y)
4035                 {
4036                         for (deUint32 x = 0; x < m_testParams.frameResolution.width; ++x, ++pixelNum)
4037                         {
4038                                 const deUint32 imageIdx = pixelNum % variables.validDescriptorCount;
4039                                 const PixelBufferAccess src = getPixelAccess(imageIdx,
4040                                         variables.descriptorsImages[imageIdx]->extent, variables.descriptorsImages[imageIdx]->format,
4041                                         variables.descriptorsBufferInfos, variables.descriptorsBuffer);
4042                                 dst.setPixel(tcu::Vector<m_imageFormat_t, 4>(src.getPixelT<m_imageFormat_t>(0, 0).x()), x, y);
4043                         }
4044                 }
4045         }
4046         else
4047         {
4048                 std::vector<m_imageFormat_t> inc(variables.validDescriptorCount, m_fillColor);
4049
4050                 for (deUint32 invIdx = variables.lowerBound; invIdx < variables.upperBound; ++invIdx)
4051                 {
4052                         ++inc[invIdx % variables.validDescriptorCount];
4053                 }
4054
4055                 for (deUint32 invIdx = 0; invIdx < variables.vertexCount; ++invIdx)
4056                 {
4057                         const deUint32 row = invIdx / m_testParams.frameResolution.width;
4058                         const deUint32 col = invIdx % m_testParams.frameResolution.width;
4059                         const m_imageFormat_t color = inc[invIdx % variables.validDescriptorCount];
4060                         dst.setPixel(tcu::Vector<m_imageFormat_t, 4>(color), col, row);
4061                 }
4062         }
4063 }
4064
4065 class DescriptorIndexingTestCase : public TestCase
4066 {
4067         const TestCaseParams m_testCaseParams;
4068 public:
4069         DescriptorIndexingTestCase (tcu::TestContext &context, const char *name, const char *description, const TestCaseParams& testCaseParams)
4070                 : TestCase(context, name, description)
4071                 , m_testCaseParams(testCaseParams)
4072         {
4073         }
4074
4075         vkt::TestInstance* createInstance (vkt::Context& context) const // override
4076         {
4077                 switch (m_testCaseParams.descriptorType)
4078                 {
4079                 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
4080                         return new StorageBufferInstance                (context, m_testCaseParams);
4081                 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
4082                         return new UniformBufferInstance                (context, m_testCaseParams);
4083                 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
4084                         return new StorageTexelInstance                 (context, m_testCaseParams);
4085                 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
4086                         return new UniformTexelInstance                 (context, m_testCaseParams);
4087                 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
4088                         return new DynamicStorageBufferInstance (context, m_testCaseParams);
4089                 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
4090                         return new DynamicUniformBufferInstance (context, m_testCaseParams);
4091                 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
4092                         return new InputAttachmentInstance              (context, m_testCaseParams);
4093                 case VK_DESCRIPTOR_TYPE_SAMPLER:
4094                         return new SamplerInstance                              (context, m_testCaseParams);
4095                 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
4096                         return new SampledImageInstance                 (context, m_testCaseParams);
4097                 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
4098                         return new CombinedImageInstance                (context, m_testCaseParams);
4099                 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
4100                         return new StorageImageInstance                 (context, m_testCaseParams);
4101                 default:
4102                         TCU_THROW(InternalError, "Unknown Descriptor Type");
4103                 }
4104                 return DE_NULL;
4105         }
4106
4107         virtual void checkSupport (vkt::Context& context) const
4108         {
4109                 context.requireDeviceFunctionality("VK_EXT_descriptor_indexing");
4110
4111                 const vk::VkPhysicalDeviceDescriptorIndexingFeatures& feats = context.getDescriptorIndexingFeatures();
4112
4113                 switch (m_testCaseParams.descriptorType)
4114                 {
4115                 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
4116                         if (!(feats.shaderStorageBufferArrayNonUniformIndexing))
4117                                 TCU_THROW(NotSupportedError, "Non-uniform indexing over storage buffer descriptor arrays is not supported.");
4118
4119                         if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingStorageBufferUpdateAfterBind)
4120                                 TCU_THROW(NotSupportedError, "Update after bind for storage buffer descriptors is not supported.");
4121                         break;
4122                 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
4123                         if (!(feats.shaderUniformBufferArrayNonUniformIndexing))
4124                                 TCU_THROW(NotSupportedError, "Non-uniform indexing for uniform buffer descriptor arrays is not supported.");
4125
4126                         if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingUniformBufferUpdateAfterBind)
4127                                 TCU_THROW(NotSupportedError, "Update after bind for uniform buffer descriptors is not supported.");
4128                         break;
4129                 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
4130                         if (!(feats.shaderStorageTexelBufferArrayNonUniformIndexing))
4131                                 TCU_THROW(NotSupportedError, "Non-uniform indexing for storage texel buffer descriptor arrays is not supported.");
4132
4133                         if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingStorageTexelBufferUpdateAfterBind)
4134                                 TCU_THROW(NotSupportedError, "Update after bind for storage texel buffer descriptors is not supported.");
4135                         break;
4136                 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
4137                         if (!(feats.shaderUniformTexelBufferArrayNonUniformIndexing))
4138                                 TCU_THROW(NotSupportedError, "Non-uniform indexing for uniform texel buffer descriptor arrays is not supported.");
4139
4140                         if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingUniformTexelBufferUpdateAfterBind)
4141                                 TCU_THROW(NotSupportedError, "Update after bind for uniform texel buffer descriptors is not supported.");
4142                         break;
4143                 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
4144                         if (!(feats.shaderStorageBufferArrayNonUniformIndexing))
4145                                 TCU_THROW(NotSupportedError, "Non-uniform indexing over storage buffer dynamic descriptor arrays is not supported.");
4146
4147                         if (m_testCaseParams.updateAfterBind)
4148                                 TCU_THROW(NotSupportedError, "Update after bind for storage buffer dynamic descriptors is not supported.");
4149                         break;
4150                 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
4151                         if (!(feats.shaderUniformBufferArrayNonUniformIndexing))
4152                                 TCU_THROW(NotSupportedError, "Non-uniform indexing over uniform buffer dynamic descriptor arrays is not supported.");
4153
4154                         if (m_testCaseParams.updateAfterBind)
4155                                 TCU_THROW(NotSupportedError, "Update after bind for uniform buffer dynamic descriptors is not supported.");
4156                         break;
4157                 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
4158                         if (!(feats.shaderInputAttachmentArrayNonUniformIndexing))
4159                                 TCU_THROW(NotSupportedError, "Non-uniform indexing over input attachment descriptor arrays is not supported.");
4160
4161                         if (m_testCaseParams.updateAfterBind)
4162                                 TCU_THROW(NotSupportedError, "Update after bind for input attachment descriptors is not supported.");
4163                         break;
4164                 case VK_DESCRIPTOR_TYPE_SAMPLER:
4165                         if (!(feats.shaderSampledImageArrayNonUniformIndexing))
4166                                 TCU_THROW(NotSupportedError, "Non-uniform indexing over sampler descriptor arrays is not supported.");
4167
4168                         if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingSampledImageUpdateAfterBind)
4169                                 TCU_THROW(NotSupportedError, "Update after bind for sampler descriptors is not supported.");
4170                         break;
4171                 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
4172                         if (!(feats.shaderSampledImageArrayNonUniformIndexing))
4173                                 TCU_THROW(NotSupportedError, "Non-uniform indexing over sampled image descriptor arrays is not supported.");
4174
4175                         if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingSampledImageUpdateAfterBind)
4176                                 TCU_THROW(NotSupportedError, "Update after bind for sampled image descriptors is not supported.");
4177                         break;
4178                 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
4179                         if (!(feats.shaderSampledImageArrayNonUniformIndexing))
4180                                 TCU_THROW(NotSupportedError, "Non-uniform indexing over combined image sampler descriptor arrays is not supported.");
4181
4182                         if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingSampledImageUpdateAfterBind)
4183                                 TCU_THROW(NotSupportedError, "Update after bind for combined image sampler descriptors is not supported.");
4184                         break;
4185                 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
4186                         if (!(feats.shaderStorageImageArrayNonUniformIndexing))
4187                                 TCU_THROW(NotSupportedError, "Non-uniform indexing over storage image descriptor arrays is not supported.");
4188
4189                         if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingStorageImageUpdateAfterBind)
4190                                 TCU_THROW(NotSupportedError, "Update after bind for storage image descriptors is not supported.");
4191                         break;
4192                 default:
4193                         DE_FATAL("Unknown Descriptor Type");
4194                         break;
4195                 }
4196         }
4197
4198         void initAsmPrograms(SourceCollections& programCollection) const
4199         {
4200
4201                 std::string(*genShaderSource)(VkShaderStageFlagBits, const TestCaseParams&, bool) = &CommonDescriptorInstance::getShaderAsm;
4202
4203                 deUint32 vulkan_version = VK_MAKE_API_VERSION(0, 1, 2, 0);
4204                 vk::SpirvVersion spirv_version = vk::SPIRV_VERSION_1_4;
4205                 vk::SpirVAsmBuildOptions asm_options(vulkan_version, spirv_version);
4206
4207                 if (VK_SHADER_STAGE_VERTEX_BIT & m_testCaseParams.stageFlags)
4208                 {
4209                         programCollection.spirvAsmSources.add(
4210                                 ut::buildShaderName(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, false), &asm_options)
4211                                 << (*genShaderSource)(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams, false);
4212
4213                         if (CommonDescriptorInstance::performWritesInVertex(m_testCaseParams.descriptorType))
4214                         {
4215                                 programCollection.spirvAsmSources.add(
4216                                         ut::buildShaderName(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, true), &asm_options)
4217                                         << (*genShaderSource)(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams, true);
4218                         }
4219                 }
4220                 if (VK_SHADER_STAGE_FRAGMENT_BIT & m_testCaseParams.stageFlags)
4221                 {
4222                         programCollection.spirvAsmSources.add(
4223                                 ut::buildShaderName(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, false), &asm_options)
4224                                 << (*genShaderSource)(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams, false);
4225
4226                         if (CommonDescriptorInstance::performWritesInVertex(m_testCaseParams.descriptorType))
4227                         {
4228                                 programCollection.spirvAsmSources.add(
4229                                         ut::buildShaderName(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, true), &asm_options)
4230                                         << (*genShaderSource)(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams, true);
4231                         }
4232                 }
4233                 if (VK_SHADER_STAGE_COMPUTE_BIT & m_testCaseParams.stageFlags)
4234                 {
4235                         programCollection.spirvAsmSources.add(
4236                                 ut::buildShaderName(VK_SHADER_STAGE_COMPUTE_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, false), &asm_options)
4237                                 << (*genShaderSource)(VK_SHADER_STAGE_COMPUTE_BIT, m_testCaseParams, false);
4238                 }
4239         }
4240
4241         virtual void initPrograms (SourceCollections& programCollection) const
4242         {
4243                 if (m_testCaseParams.minNonUniform) {
4244                         initAsmPrograms(programCollection);
4245                         return;
4246                 }
4247
4248                 std::string(*genShaderSource)(VkShaderStageFlagBits, const TestCaseParams&, bool) = &CommonDescriptorInstance::getShaderSource;
4249
4250                 if (VK_SHADER_STAGE_VERTEX_BIT & m_testCaseParams.stageFlags)
4251                 {
4252                         programCollection.glslSources.add(
4253                                 ut::buildShaderName(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, false))
4254                                 << glu::VertexSource((*genShaderSource)(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams, false));
4255
4256                         if (CommonDescriptorInstance::performWritesInVertex(m_testCaseParams.descriptorType))
4257                         {
4258                                 programCollection.glslSources.add(
4259                                         ut::buildShaderName(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, true))
4260                                         << glu::VertexSource((*genShaderSource)(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams, true));
4261                         }
4262                 }
4263                 if (VK_SHADER_STAGE_FRAGMENT_BIT & m_testCaseParams.stageFlags)
4264                 {
4265                         programCollection.glslSources.add(
4266                                 ut::buildShaderName(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, false))
4267                                 << glu::FragmentSource((*genShaderSource)(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams, false));
4268
4269                         if (CommonDescriptorInstance::performWritesInVertex(m_testCaseParams.descriptorType))
4270                         {
4271                                 programCollection.glslSources.add(
4272                                         ut::buildShaderName(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, true))
4273                                         << glu::FragmentSource((*genShaderSource)(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams, true));
4274                         }
4275                 }
4276                 if (VK_SHADER_STAGE_COMPUTE_BIT & m_testCaseParams.stageFlags)
4277                 {
4278                         programCollection.glslSources.add(
4279                                 ut::buildShaderName(VK_SHADER_STAGE_COMPUTE_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, false))
4280                                 << glu::ComputeSource((*genShaderSource)(VK_SHADER_STAGE_COMPUTE_BIT, m_testCaseParams, false));
4281                 }
4282         }
4283 };
4284
4285 } // - unnamed namespace
4286
4287 void descriptorIndexingDescriptorSetsCreateTests (tcu::TestCaseGroup* group)
4288 {
4289         struct TestCaseInfo
4290         {
4291                 const char*             name;
4292                 const char*             description;
4293                 TestCaseParams  params;
4294         };
4295
4296         tcu::TestContext&                               context(group->getTestContext());
4297
4298         TestCaseInfo casesAfterBindAndLoop[] =
4299         {
4300                 {
4301                         "storage_buffer", "Regular Storage Buffer Descriptors",
4302                         {
4303                                 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
4304                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4305                                 RESOLUTION,
4306                                 false,  // updateAfterBind
4307                                 false,  // calculateInLoop
4308                                 false,  // useMipMaps
4309                                 false,  // minNonUniform
4310                                 FUZZY_COMPARE, CMP_THRESHOLD
4311                         }
4312                 },
4313                 {
4314                         "storage_texel_buffer", "Storage Texel Buffer Descriptors",
4315                         {
4316                                 VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
4317                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4318                                 RESOLUTION,
4319                                 false,  // updateAfterBind
4320                                 false,  // calculateInLoop
4321                                 false,  // useMipMaps
4322                                 false,  // minNonUniform
4323                                 FUZZY_COMPARE, CMP_THRESHOLD
4324                         }
4325                 },
4326                 {
4327                         "uniform_texel_buffer", "Uniform Texel Buffer Descriptors",
4328                         {
4329                                 VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
4330                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4331                                 RESOLUTION,
4332                                 false,  // updateAfterBind,
4333                                 false,  // calculateInLoop
4334                                 false,  // usesMipMaps
4335                                 false,  // minNonUniform
4336                                 FUZZY_COMPARE, CMP_THRESHOLD
4337                         }
4338                 },
4339                 {
4340                         "storage_image", "Storage Image Descriptors",
4341                         {
4342                                 VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
4343                                 VK_SHADER_STAGE_COMPUTE_BIT,
4344                                 RESOLUTION,
4345                                 false,  // updateAfterBind
4346                                 false,  // calculateInLoop
4347                                 false,  // useMipMaps
4348                                 false,  // minNonUniform
4349                                 FUZZY_COMPARE, CMP_THRESHOLD
4350                         }
4351                 },
4352         };
4353
4354         for (int updateAfterBind = 0; updateAfterBind < 2; ++updateAfterBind)
4355         {
4356                 for (int calculateInLoop = 0; calculateInLoop < 2; ++calculateInLoop)
4357                 {
4358                         for (deUint32 caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(casesAfterBindAndLoop); ++caseIdx)
4359                         {
4360                                 TestCaseInfo&   info                    (casesAfterBindAndLoop[caseIdx]);
4361                                 std::string             caseName                (info.name);
4362                                 std::string             caseDescription (info.description);
4363                                 TestCaseParams  params                  (info.params);
4364
4365                                 caseName                                += (updateAfterBind     ? "_after_bind" : "");
4366                                 caseName                                += (calculateInLoop     ? "_in_loop"    : "");
4367
4368                                 caseDescription                 += (updateAfterBind     ? " After Bind" : "");
4369                                 caseDescription                 += (calculateInLoop ? " In Loop"        : "");
4370
4371                                 params.updateAfterBind  = updateAfterBind       ? true                  : false;
4372                                 params.calculateInLoop  = calculateInLoop       ? true                  : false;
4373
4374                                 group->addChild(new DescriptorIndexingTestCase(context, caseName.c_str(), caseDescription.c_str(), params));
4375                         }
4376                 }
4377         }
4378
4379         TestCaseInfo casesAfterBindAndLoopAndLOD[] =
4380         {
4381                 {
4382                         "sampler", "Sampler Descriptors",
4383                         {
4384                                 VK_DESCRIPTOR_TYPE_SAMPLER,
4385                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4386                                 RESOLUTION,
4387                                 false,  // updateAfterBind
4388                                 false,  // calculateInLoop
4389                                 false,  // usesMipMaps
4390                                 false,  // minNonUniform
4391                                 FUZZY_COMPARE, CMP_THRESHOLD
4392                         }
4393                 },
4394                 {
4395                         "sampled_image", "Sampled Image Descriptors",
4396                         {
4397                                 VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
4398                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4399                                 RESOLUTION,
4400                                 false,  // updateAfterBind
4401                                 false,  // calculateInLoop
4402                                 false,  // usesMipMaps
4403                                 false,  // minNonUniform
4404                                 FUZZY_COMPARE, CMP_THRESHOLD
4405                         }
4406                 },
4407                 {
4408                         "combined_image_sampler", "Combined Image Sampler Descriptors",
4409                         {
4410                                 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
4411                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4412                                 RESOLUTION,
4413                                 false,  // updateAfterBind
4414                                 false,  // calculateInLoop
4415                                 false,  // usesMipMaps
4416                                 false,  // minNonUniform
4417                                 FUZZY_COMPARE, CMP_THRESHOLD
4418                         }
4419                 },
4420         };
4421
4422         for (int updateAfterBind = 0; updateAfterBind < 2; ++updateAfterBind)
4423         {
4424                 for (int calculateInLoop = 0; calculateInLoop < 2; ++calculateInLoop)
4425                 {
4426                         for (int usesMipMaps = 0; usesMipMaps < 2; ++usesMipMaps)
4427                         {
4428                                 for (deUint32 caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(casesAfterBindAndLoopAndLOD); ++caseIdx)
4429                                 {
4430                                         TestCaseInfo&   info                    (casesAfterBindAndLoopAndLOD[caseIdx]);
4431                                         std::string             caseName                (info.name);
4432                                         std::string             caseDescription (info.description);
4433                                         TestCaseParams  params                  (info.params);
4434
4435                                         caseName                                += (updateAfterBind     ? "_after_bind" : "");
4436                                         caseName                                += (calculateInLoop ? "_in_loop"        : "");
4437                                         caseName                                += (usesMipMaps         ? "_with_lod"   : "");
4438
4439                                         caseDescription                 += (updateAfterBind     ? " After Bind" : "");
4440                                         caseDescription                 += (calculateInLoop     ? " In Loop"    : "");
4441                                         caseDescription                 += (usesMipMaps         ? " Use LOD"    : "");
4442
4443                                         params.updateAfterBind  = updateAfterBind       ? true                  : false;
4444                                         params.calculateInLoop  = calculateInLoop       ? true                  : false;
4445                                         params.usesMipMaps              = usesMipMaps           ? true                  : false;
4446
4447                                         group->addChild(new DescriptorIndexingTestCase(context, caseName.c_str(), caseDescription.c_str(), params));
4448                                 }
4449                         }
4450                 }
4451         }
4452
4453         TestCaseInfo casesNonAfterBindAndLoop[] =
4454         {
4455                 {
4456                         "uniform_buffer", "Regular Uniform Buffer Descriptors",
4457                         {
4458                                 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
4459                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4460                                 RESOLUTION,
4461                                 false,  // updateAfterBind
4462                                 false,  // calculateInLoop
4463                                 false,  // usesMipMaps
4464                                 false,  // minNonUniform
4465                                 FUZZY_COMPARE, CMP_THRESHOLD
4466                         }
4467                 },
4468                 {
4469                         "storage_buffer_dynamic", "Dynamic Storage Buffer Descriptors",
4470                         {
4471                                 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC,
4472                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4473                                 RESOLUTION,
4474                                 false,  // updateAfterBind
4475                                 false,  // calculateInLoop
4476                                 false,  // useMipMaps
4477                                 false,  // minNonUniform
4478                                 FUZZY_COMPARE, CMP_THRESHOLD
4479                         }
4480                 },
4481                 {
4482                         "uniform_buffer_dynamic", "Dynamic Uniform Buffer Descriptors",
4483                         {
4484                                 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
4485                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4486                                 RESOLUTION,
4487                                 false,  // updateAfterBind
4488                                 false,  // calculateInLoop
4489                                 false,  // useMipMaps
4490                                 false,  // minNonUniform
4491                                 FUZZY_COMPARE, CMP_THRESHOLD
4492                         }
4493                 },
4494                 {
4495                         "input_attachment", "Input Attachment Descriptors",
4496                         {
4497                                 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
4498                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4499                                 RESOLUTION,
4500                                 false,  // updateAfterBind
4501                                 false,  // calculateInLoop
4502                                 false,  // useMipMaps
4503                                 false,  // minNonUniform
4504                                 FUZZY_COMPARE, CMP_THRESHOLD
4505                         }
4506                 },
4507         };
4508
4509         for (int calculateInLoop = 0; calculateInLoop < 2; ++calculateInLoop)
4510         {
4511                 for (deUint32 caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(casesNonAfterBindAndLoop); ++caseIdx)
4512                 {
4513                         TestCaseInfo&   info(casesNonAfterBindAndLoop[caseIdx]);
4514                         std::string             caseName(info.name);
4515                         std::string             caseDescription(info.description);
4516                         TestCaseParams  params(info.params);
4517
4518                         caseName                                += (calculateInLoop     ? "_in_loop"    : "");
4519
4520                         caseDescription                 += (calculateInLoop ? " In Loop"        : "");
4521
4522                         params.calculateInLoop  = calculateInLoop       ? true                  : false;
4523
4524                         group->addChild(new DescriptorIndexingTestCase(context, caseName.c_str(), caseDescription.c_str(), params));
4525                 }
4526         }
4527
4528         // SPIR-V Asm Tests
4529         // Tests that have the minimum necessary NonUniform decorations.
4530         // sampler and sampled_image GLSL already have minimum NonUniform decorations.
4531
4532         TestCaseInfo casesMinNonUniform[] =
4533         {
4534                 {
4535                         "storage_buffer", "Regular Storage Buffer Descriptors",
4536                         {
4537                                 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
4538                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4539                                 RESOLUTION,
4540                                 false,  // updateAfterBind
4541                                 false,  // calculateInLoop
4542                                 false,  // useMipMaps
4543                                 true,   // minNonUniform
4544                                 FUZZY_COMPARE, CMP_THRESHOLD
4545                         }
4546                 },
4547                 {
4548                         "storage_texel_buffer", "Storage Texel Buffer Descriptors",
4549                         {
4550                                 VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
4551                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4552                                 RESOLUTION,
4553                                 false,  // updateAfterBind
4554                                 false,  // calculateInLoop
4555                                 false,  // useMipMaps
4556                                 true,   // minNonUniform
4557                                 FUZZY_COMPARE, CMP_THRESHOLD
4558                         }
4559                 },
4560                 {
4561                         "uniform_texel_buffer", "Uniform Texel Buffer Descriptors",
4562                         {
4563                                 VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
4564                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4565                                 RESOLUTION,
4566                                 false,  // updateAfterBind,
4567                                 false,  // calculateInLoop
4568                                 false,  // usesMipMaps
4569                                 true,   // minNonUniform
4570                                 FUZZY_COMPARE, CMP_THRESHOLD
4571                         }
4572                 },
4573                 {
4574                         "uniform_buffer", "Regular Uniform Buffer Descriptors",
4575                         {
4576                                 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
4577                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4578                                 RESOLUTION,
4579                                 false,  // updateAfterBind
4580                                 false,  // calculateInLoop
4581                                 false,  // usesMipMaps
4582                                 true,   // minNonUniform
4583                                 FUZZY_COMPARE, CMP_THRESHOLD
4584                         }
4585                 },
4586                 {
4587                         "combined_image_sampler", "Combined Image Sampler Descriptors",
4588                         {
4589                                 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
4590                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4591                                 RESOLUTION,
4592                                 false,  // updateAfterBind
4593                                 false,  // calculateInLoop
4594                                 false,  // usesMipMaps
4595                                 true,   // minNonUniform
4596                                 FUZZY_COMPARE, CMP_THRESHOLD
4597                         }
4598                 },
4599                 {
4600                         "combined_image_sampler", "Combined Image Sampler Descriptors",
4601                         {
4602                                 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
4603                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4604                                 RESOLUTION,
4605                                 false,  // updateAfterBind
4606                                 false,  // calculateInLoop
4607                                 true,   // usesMipMaps
4608                                 true,   // minNonUniform
4609                                 FUZZY_COMPARE, CMP_THRESHOLD
4610                         }
4611                 },
4612                 {
4613                         "storage_image", "Storage Image Descriptors",
4614                         {
4615                                 VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
4616                                 VK_SHADER_STAGE_COMPUTE_BIT,
4617                                 RESOLUTION,
4618                                 false,  // updateAfterBind
4619                                 false,  // calculateInLoop
4620                                 false,  // useMipMaps
4621                                 true,   // minNonUniform
4622                                 FUZZY_COMPARE, CMP_THRESHOLD
4623                         }
4624                 },
4625         };
4626
4627         for (deUint32 caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(casesMinNonUniform); ++caseIdx)
4628         {
4629                 TestCaseInfo&   info(casesMinNonUniform[caseIdx]);
4630                 std::string             caseName(info.name);
4631                 std::string             caseDescription(info.description);
4632                 TestCaseParams  params(info.params);
4633
4634                 if (params.usesMipMaps) {
4635                         caseName += "_with_lod";
4636                 }
4637                 caseName += "_minNonUniform";
4638
4639                 caseDescription += " With Minimum NonUniform Decorations";
4640
4641                 TestCase* tc = new DescriptorIndexingTestCase(context, caseName.c_str(), caseDescription.c_str(), params);
4642                 group->addChild(tc);
4643                 // group->addChild(new DescriptorIndexingTestCase(context, caseName.c_str(), caseDescription.c_str(), params));
4644         }
4645 }
4646
4647 } // - DescriptorIndexing
4648 } // - vkt