Add tests for VK_EXT_descriptor_indexing
[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 static const VkDescriptorType   VK_DESCRIPTOR_TYPE_UNDEFINED = VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT;
93
94 template<deUint32 BindingNumber>
95 struct Binding
96 {
97         static const deUint32   binding = BindingNumber;
98 };
99
100 struct BindingUniformBuffer : Binding<BINDING_UniformBuffer>
101 {
102         typedef struct
103         {
104                 tcu::Vec4 c;
105         } Data;
106 };
107
108 struct BindingStorageBuffer : Binding<BINDING_StorageBuffer>
109 {
110         typedef struct
111         {
112                 tcu::Vec4 cnew;
113                 tcu::Vec4 cold;
114         } Data;
115 };
116
117 struct TestCaseParams
118 {
119         VkDescriptorType        descriptorType;         // used only to distinguish test class instance
120         VkShaderStageFlags      stageFlags;                     // used only to build a proper program
121         VkExtent3D                      frameResolution;        // target frame buffer resolution
122         bool                            updateAfterBind;        // whether a test will use update after bind feature
123         bool                            calculateInLoop;        // perform calculation in a loop
124         bool                            usesMipMaps;            // this makes a sense and affects in image test cases only
125         deBool                          fuzzyComparison;        // if true then a test will use fuzzy comparison, otherwise float threshold
126         float                           thresholdValue;         // a threshold that will be used for both, float and fuzzy comparisons
127 };
128
129 struct TestParams
130 {
131         VkShaderStageFlags      stageFlags;
132         VkDescriptorType        descriptorType;
133         deUint32                        descriptorBinding;
134         VkDescriptorType        additionalDescriptorType;
135         deUint32                        additionalDescriptorBinding;
136         bool                            copyBuffersToImages;
137         bool                            allowVertexStoring;
138         VkExtent3D                      frameResolution;
139         bool                            updateAfterBind;
140         bool                            calculateInLoop;
141         bool                            usesMipMaps;
142         deBool                          fuzzyComparison;
143         float                           thresholdValue;
144
145         TestParams                      (VkShaderStageFlags             stageFlags_,
146                                                 VkDescriptorType                descriptorType_,
147                                                 deUint32                                descriptorBinding_,
148                                                 VkDescriptorType                additionalDescriptorType_,
149                                                 deUint32                                additionalDescriptorBinding_,
150                                                 bool                                    copyBuffersToImages_,
151                                                 bool                                    allowVertexStoring_,
152                                                 const TestCaseParams&   caseParams)
153                 : stageFlags                                                    (stageFlags_)
154                 , descriptorType                                                (descriptorType_)
155                 , descriptorBinding                                             (descriptorBinding_)
156                 , additionalDescriptorType                              (additionalDescriptorType_)
157                 , additionalDescriptorBinding                   (additionalDescriptorBinding_)
158                 , copyBuffersToImages                                   (copyBuffersToImages_)
159                 , allowVertexStoring                                    (allowVertexStoring_)
160                 , frameResolution                                               (caseParams.frameResolution)
161                 , updateAfterBind                                               (caseParams.updateAfterBind)
162                 , calculateInLoop                                               (caseParams.calculateInLoop)
163                 , usesMipMaps                                                   (caseParams.usesMipMaps)
164                 , fuzzyComparison                                               (caseParams.fuzzyComparison ? true : false)
165                 , thresholdValue                                                (caseParams.thresholdValue)
166         {
167         }
168 };
169
170 struct DescriptorEnumerator
171 {
172         ut::BufferHandleAllocSp                                                 buffer;
173         ut::BufferViewSp                                                                bufferView;
174         VkDeviceSize                                                                    bufferSize;
175
176         Move<VkDescriptorSetLayout>                                             descriptorSetLayout;
177         Move<VkDescriptorPool>                                                  descriptorPool;
178         Move<VkDescriptorSet>                                                   descriptorSet;
179
180         void init(const vkt::Context& context, deUint32 vertexCount, deUint32 availableDescriptorCount);
181         void update(const vkt::Context& context);
182 };
183
184 struct IterateCommonVariables
185 {
186         // An amount of descriptors of a given type available on the platform
187         deUint32                                                                                availableDescriptorCount;
188         // An amount of valid descriptors that have connected a buffers to them
189         deUint32                                                                                validDescriptorCount;
190         // As the name suggests, sometimes it is used as invocationCount
191         deUint32                                                                                vertexCount;
192         VkRect2D                                                                                renderArea;
193         VkDeviceSize                                                                    dataAlignment;
194         deUint32                                                                                lowerBound;
195         deUint32                                                                                upperBound;
196
197         DescriptorEnumerator                                                    descriptorEnumerator;
198
199         ut::BufferHandleAllocSp                                                 vertexAttributesBuffer;
200         ut::BufferHandleAllocSp                                                 descriptorsBuffer;
201         std::vector<VkDescriptorBufferInfo>                             descriptorsBufferInfos;
202         std::vector<ut::BufferViewSp>                                   descriptorsBufferViews;
203         std::vector<ut::ImageViewSp>                                    descriptorImageViews;
204         std::vector<ut::SamplerSp>                                              descriptorSamplers;
205         std::vector<ut::ImageHandleAllocSp>                             descriptorsImages;
206         ut::FrameBufferSp                                                               frameBuffer;
207
208         Move<VkDescriptorSetLayout>                                             descriptorSetLayout;
209         Move<VkDescriptorPool>                                                  descriptorPool;
210         Move<VkDescriptorSet>                                                   descriptorSet;
211         Move<VkPipelineLayout>                                                  pipelineLayout;
212         Move<VkRenderPass>                                                              renderPass;
213         Move<VkPipeline>                                                                pipeline;
214         Move<VkCommandBuffer>                                                   commandBuffer;
215 };
216
217 class CommonDescriptorInstance : public TestInstance
218 {
219 public:
220                                                                 CommonDescriptorInstance                (Context&                                                                       context,
221                                                                                                                                 const TestParams&                                                       testParams);
222
223         void                                            checkIndexingAvailable                  (const ut::DeviceProperties&                            devProps) const;
224
225         deUint32                                        computeAvailableDescriptorCount (VkDescriptorType                                                       descriptorType) const;
226
227         Move<VkDescriptorSetLayout>     createDescriptorSetLayout               (deUint32&                                                                      descriptorCount) const;
228
229         Move<VkDescriptorPool>          createDescriptorPool                    (deUint32                                                                       descriptorCount) const;
230
231         Move<VkDescriptorSet>           createDescriptorSet                             (VkDescriptorPool                                                       dsPool,
232                                                                                                                                  VkDescriptorSetLayout                                          dsLayout) const;
233
234         struct attributes
235         {
236                 typedef tcu::Vec4       vec4;
237                 typedef tcu::Vec2       vec2;
238                 typedef tcu::IVec4      ivec4;
239                 vec4                    position;
240                 vec2                    normalpos;
241                 ivec4                   index;
242                 attributes& operator()(const vec4& pos)
243                 {
244                         position = pos;
245
246                         normalpos.x() = (pos.x() + 1.0f) / 2.0f;
247                         normalpos.y() = (pos.y() + 1.0f) / 2.0f;
248
249                         return *this;
250                 }
251         };
252         void                                            createVertexAttributeBuffer             (ut::BufferHandleAllocSp&                                       buffer,
253                                                                                                                                  deUint32                                                                       availableDescriptorCount) const;
254
255         static std::string                      substBinding                                    (deUint32                                                                       binding,
256                                                                                                                                  const char*                                                            str,
257                                                                                                                                  deUint32                                                                       count = 0,
258                                                                                                                                  const char*                                                            name = DE_NULL);
259
260         static const char*                      getVertexShaderProlog                   (void);
261
262         static const char*                      getFragmentShaderProlog                 (void);
263
264         static const char*                      getShaderEpilog                                 (void);
265
266         static bool                                     performWritesInVertex                   (VkDescriptorType                                                       descriptorType);
267
268         static std::string                      getShaderSource                                 (VkShaderStageFlagBits                                          shaderType,
269                                                                                                                                  const TestCaseParams&                                          testCaseParams,
270                                                                                                                                  bool                                                                           allowVertexStoring);
271
272         static std::string                      getColorAccess                                  (VkDescriptorType                                                       descriptorType,
273                                                                                                                                  const char*                                                            indexVariableName,
274                                                                                                                                  bool                                                                           usesMipMaps);
275
276         static std::string                      getFragmentReturnSource                 (const std::string&                                                     colorAccess);
277
278         static std::string                      getFragmentLoopSource                   (const std::string&                                                     colorAccess1,
279                                                                                                                                  const std::string&                                                     colorAccess2);
280
281         virtual Move<VkRenderPass>      createRenderPass                                (const IterateCommonVariables&                          variables);
282
283         struct push_constant
284         {
285                 deInt32 lowerBound;
286                 deInt32 upperBound;
287         };
288         VkPushConstantRange                     makePushConstantRange                   (void) const;
289
290         Move<VkPipelineLayout>          createPipelineLayout                    (const std::vector<VkDescriptorSetLayout>&      descriptorSetLayouts) const;
291
292         // Creates graphics or compute pipeline and appropriate shaders' modules according the testCaseParams.stageFlags
293         // In the case of compute pipeline renderPass parameter is ignored.
294         // Viewport will be created with a width and a height taken from testCaseParam.fragResolution.
295         Move<VkPipeline>                        createPipeline                                  (VkPipelineLayout                                                       pipelineLayout,
296                                                                                                                                  VkRenderPass                                                           renderPass);
297
298         virtual void                            createFramebuffer                               (ut::FrameBufferSp&                                                     frameBuffer,
299                                                                                                                                  VkRenderPass                                                           renderPass,
300                                                                                                                                  const IterateCommonVariables&                          variables);
301
302         // Creates one big stagging buffer cutted out on chunks that can accomodate an element of elementSize size
303         VkDeviceSize                            createBuffers                                   (std::vector<VkDescriptorBufferInfo>&           bufferInfos,
304                                                                                                                                  ut::BufferHandleAllocSp&                                       buffer,
305                                                                                                                                  deUint32                                                                       elementCount,
306                                                                                                                                  deUint32                                                                       elementSize,
307                                                                                                                                  VkDeviceSize                                                           alignment,
308                                                                                                                                  VkBufferUsageFlags                                                     bufferUsage);
309
310         // Creates and binds an imagesCount of images with given parameters.
311         // Additionally creates stagging buffer for their data and PixelBufferAccess for particular images.
312         VkDeviceSize                            createImages                                    (std::vector<ut::ImageHandleAllocSp>&           images,
313                                                                                                                                  std::vector<VkDescriptorBufferInfo>&           bufferInfos,
314                                                                                                                                  ut::BufferHandleAllocSp&                                       buffer,
315                                                                                                                                  VkBufferUsageFlags                                                     bufferUsage,
316                                                                                                                                  const VkExtent3D&                                                      imageExtent,
317                                                                                                                                  VkFormat                                                                       imageFormat,
318                                                                                                                                  VkImageLayout                                                          imageLayout,
319                                                                                                                                  deUint32                                                                       imageCount,
320                                                                                                                                  bool                                                                           withMipMaps = false);
321
322         void                                            createBuffersViews                              (std::vector<ut::BufferViewSp>&                         views,
323                                                                                                                                  const std::vector<VkDescriptorBufferInfo>&     bufferInfos,
324                                                                                                                                  VkFormat                                                                       format);
325
326         void                                            createImagesViews                               (std::vector<ut::ImageViewSp>&                          views,
327                                                                                                                                  const std::vector<ut::ImageHandleAllocSp>&     images,
328                                                                                                                                  VkFormat                                                                       format);
329
330         virtual void                            copyBuffersToImages                             (IterateCommonVariables&                                        variables);
331
332         virtual void                            copyImagesToBuffers                             (IterateCommonVariables&                                        variables);
333
334         PixelBufferAccess                       getPixelAccess                                  (deUint32                                                                       imageIndex,
335                                                                                                                                  const VkExtent3D&                                                      imageExtent,
336                                                                                                                                  VkFormat                                                                       imageFormat,
337                                                                                                                                  const std::vector<VkDescriptorBufferInfo>&     bufferInfos,
338                                                                                                                                  const ut::BufferHandleAllocSp&                         buffer,
339                                                                                                                                  deUint32                                                                       mipLevel = 0u) const;
340
341         virtual void                            createAndPopulateDescriptors    (IterateCommonVariables&                                        variables) = 0;
342
343         virtual void                            updateDescriptors                               (IterateCommonVariables&                                        variables);
344
345         virtual void                            iterateCollectResults                   (ut::UpdatablePixelBufferAccessPtr&                     result,
346                                                                                                                                  const IterateCommonVariables&                          variables,
347                                                                                                                                  bool                                                                           fromTest);
348
349
350         void                                            iterateCommandBegin                             (IterateCommonVariables&                                        variables);
351
352         bool                                            iterateCommandEnd                               (IterateCommonVariables&                                        variables,
353                                                                                                                                  bool                                                                           collectBeforeSubmit = true);
354
355         Move<VkCommandBuffer>           createCmdBuffer                                 (void);
356
357         void                                            commandBindPipeline                             (VkCommandBuffer                                                        commandBuffer,
358                                                                                                                                  VkPipeline                                                                     pipeline);
359
360         void                                            commandBindVertexAttributes             (VkCommandBuffer                                                        commandBuffer,
361                                                                                                                                  const ut::BufferHandleAllocSp&                         vertexAttributesBuffer);
362
363         void                                            commandBindDescriptorSets               (VkCommandBuffer                                                        commandBuffer,
364                                                                                                                                  VkPipelineLayout                                                       pipelineLayout,
365                                                                                                                                  VkDescriptorSet                                                        descriptorSet,
366                                                                                                                                  deUint32                                                                       descriptorSetIndex);
367
368         void                                            commandReadFrameBuffer                  (ut::BufferHandleAllocSp&                                       content,
369                                                                                                                                  VkCommandBuffer                                                        commandBuffer,
370                                                                                                                                  const ut::FrameBufferSp&                                       frameBuffer);
371         ut::UpdatablePixelBufferAccessPtr
372                                                                 commandReadFrameBuffer                  (VkCommandBuffer                                                        commandBuffer,
373                                                                                                                                  const ut::FrameBufferSp&                                       frameBuffer);
374
375         Move<VkFence>                           commandSubmit                                   (VkCommandBuffer                                                        commandBuffer);
376
377         virtual bool                            verifyVertexWriteResults                (IterateCommonVariables&                                        variables);
378
379 protected:
380         virtual tcu::TestStatus         iterate                                                 (void);
381
382 protected:
383         const VkDevice                          m_vkd;
384         const DeviceInterface&          m_vki;
385         Allocator&                                      m_allocator;
386         const VkQueue                           m_queue;
387         const deUint32                          m_queueFamilyIndex;
388         const Move<VkCommandPool>       m_commandPool;
389         const VkFormat                          m_colorFormat;
390         const TestParams                        m_testParams;
391         static const tcu::Vec4          m_clearColor;
392         const std::vector<float>        m_colorScheme;
393         const deUint32                          m_schemeSize;
394
395 private:
396
397         Move<VkPipeline>                        createGraphicsPipeline                  (VkPipelineLayout                                                       pipelineLayout,
398                                                                                                                                  VkRenderPass                                                           renderPass);
399
400         Move<VkPipeline>                        createComputePipeline                   (VkPipelineLayout                                                       pipelineLayout);
401
402         int                                                     constructShaderModules                  (void);
403
404         static std::vector<float>       createColorScheme();
405
406         Move<VkShaderModule>            m_vertexModule;
407         Move<VkShaderModule>            m_fragmentModule;
408         Move<VkShaderModule>            m_computeModule;
409 };
410 const tcu::Vec4 CommonDescriptorInstance::m_clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
411
412 void DescriptorEnumerator::init (const vkt::Context& context, deUint32 vertexCount, deUint32 availableDescriptorCount)
413 {
414         const VkDevice                                  device = context.getDevice();
415         const DeviceInterface&                  deviceInterface = context.getDeviceInterface();
416
417         const VkFormat                                  imageFormat = VK_FORMAT_R32G32B32A32_SINT;
418         typedef ut::mapVkFormat2Type<imageFormat>::type pixelType;
419         const VkDeviceSize                              dataSize = vertexCount * sizeof(pixelType);
420         const std::vector<deUint32>             primes = ut::generatePrimes(availableDescriptorCount);
421         const deUint32                                  primeCount = static_cast<deUint32>(primes.size());
422
423         std::vector<pixelType>  data(vertexCount);
424         // e.g. 2,3,5,7,11,13,2,3,5,7,...
425         for (deUint32 idx = 0; idx < vertexCount; ++idx)
426         {
427                 data[idx].x() = static_cast<pixelType::Element>(primes[idx % primeCount]);
428                 data[idx].y() = static_cast<pixelType::Element>(idx);
429         }
430
431         bufferSize = ut::createBufferAndBind(buffer, context, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, dataSize);
432         deMemcpy(buffer->alloc->getHostPtr(), data.data(), static_cast<size_t>(dataSize));
433
434         const VkBufferViewCreateInfo bufferViewCreateInfo =
435         {
436                 VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,              // sType
437                 DE_NULL,                                                                                // pNext
438                 0u,                                                                                             // flags
439                 *(buffer.get()->buffer),                                                // buffer
440                 imageFormat,                                                                    // format
441                 0u,                                                                                             // offset
442                 bufferSize,                                                                             // range
443         };
444
445         bufferView = ut::BufferViewSp(new Move<VkBufferView>(vk::createBufferView(deviceInterface, device, &bufferViewCreateInfo)));
446
447         const VkDescriptorSetLayoutBinding      binding =
448         {
449                 BINDING_DescriptorEnumerator,                                   // binding
450                 VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,                // descriptorType
451                 1u,                                                                                             // descriptorCount
452                 VK_SHADER_STAGE_ALL,                                                    // stageFlags
453                 DE_NULL,                                                                                // pImmutableSamplers
454         };
455
456         const VkDescriptorSetLayoutCreateInfo   layoutCreateInfo =
457         {
458                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
459                 DE_NULL,                                                                                // pNext
460                 0u,                                                                                             // flags
461                 1u,                                                                                             // bindingCount
462                 &binding,                                                                               // pBindings
463         };
464
465         descriptorSetLayout = vk::createDescriptorSetLayout(deviceInterface, device, &layoutCreateInfo);
466         descriptorPool = DescriptorPoolBuilder().addType(binding.descriptorType)
467                 .build(deviceInterface, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
468
469         const VkDescriptorSetAllocateInfo       dsAllocInfo =
470         {
471                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // sType
472                 DE_NULL,                                                                                // pNext
473                 *descriptorPool,                                                                // descriptorPool
474                 1u,                                                                                             // descriptorSetCount
475                 &(*descriptorSetLayout)                                                 // pSetLayouts
476         };
477
478         descriptorSet = vk::allocateDescriptorSet(deviceInterface, device, &dsAllocInfo);
479 }
480
481 void DescriptorEnumerator::update (const vkt::Context& context)
482 {
483         const VkDescriptorBufferInfo bufferInfo =
484         {
485                 *(buffer.get()->buffer),                                        // buffer
486                 0u,                                                                                     // offset
487                 bufferSize,                                                                     // range
488         };
489
490         const VkWriteDescriptorSet writeInfo =
491         {
492                 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
493                 DE_NULL,                                                                        // pNext
494                 *descriptorSet,                                                         // dstSet
495                 BINDING_DescriptorEnumerator,                           // dstBinding
496                 0u,                                                                                     // dstArrayElement
497                 1u,                                                                                     // descriptorCount
498                 VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,        // descriptorType
499                 DE_NULL,                                                                        // pImageInfo
500                 &bufferInfo,                                                            // pBufferInfo
501                 &(**bufferView),                                                        // pTexelBufferView
502         };
503
504         context.getDeviceInterface().updateDescriptorSets(context.getDevice(), 1u, &writeInfo, 0u, DE_NULL);
505 }
506
507 CommonDescriptorInstance::CommonDescriptorInstance                                      (Context&                                                               context,
508                                                                                                                                         const TestParams&                                               testParams)
509         : TestInstance          (context)
510         , m_vkd                         (context.getDevice())
511         , m_vki                         (context.getDeviceInterface())
512         , m_allocator           (context.getDefaultAllocator())
513         , m_queue                       (context.getUniversalQueue())
514         , m_queueFamilyIndex(context.getUniversalQueueFamilyIndex())
515         , m_commandPool         (vk::createCommandPool(m_vki, m_vkd, (VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT), m_queueFamilyIndex))
516         , m_colorFormat         (VK_FORMAT_R32G32B32A32_SFLOAT)
517         , m_testParams          (testParams)
518         , m_colorScheme         (createColorScheme())
519         , m_schemeSize          (static_cast<deUint32>(m_colorScheme.size()))
520 {
521 }
522
523 void CommonDescriptorInstance::checkIndexingAvailable                           (const ut::DeviceProperties&                    devProps) const
524 {
525         DE_UNREF(devProps);
526         m_context.requireDeviceExtension("VK_EXT_descriptor_indexing");
527 }
528
529 deUint32 CommonDescriptorInstance::computeAvailableDescriptorCount      (VkDescriptorType                                               descriptorType) const
530 {
531         DE_UNREF(descriptorType);
532         const deUint32 vertexCount = m_testParams.frameResolution.width * m_testParams.frameResolution.height;
533         const deUint32 availableDescriptorsOnDevice = ut::DeviceProperties(m_context).computeMaxPerStageDescriptorCount(m_testParams.descriptorType, m_testParams.updateAfterBind);
534         return deMinu32(deMinu32(vertexCount, availableDescriptorsOnDevice), MAX_DESCRIPTORS);
535 }
536
537 Move<VkDescriptorSetLayout>     CommonDescriptorInstance::createDescriptorSetLayout (deUint32&                                  descriptorCount) const
538 {
539         descriptorCount = computeAvailableDescriptorCount(m_testParams.descriptorType);
540
541         bool optional = (m_testParams.additionalDescriptorBinding != BINDING_Undefined) && (m_testParams.additionalDescriptorType != VK_DESCRIPTOR_TYPE_UNDEFINED);
542
543         const VkDescriptorSetLayoutBinding      bindings[] =
544         {
545                 {
546                         m_testParams.descriptorBinding,                         // binding
547                         m_testParams.descriptorType,                            // descriptorType
548                         descriptorCount,                                                        // descriptorCount
549                         m_testParams.stageFlags,                                        // stageFlags
550                         DE_NULL,                                                                        // pImmutableSamplers
551                 },
552                 {
553                         m_testParams.additionalDescriptorBinding,       // binding
554                         m_testParams.additionalDescriptorType,          // descriptorType
555                         1,                                                                                      // descriptorCount
556                         m_testParams.stageFlags,                                        // stageFlags
557                         DE_NULL,                                                                        // pImmutableSamplers
558                 }
559         };
560
561         const VkDescriptorBindingFlagsEXT       bindingFlagUpdateAfterBind =
562                 m_testParams.updateAfterBind ? VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT : 0;
563
564         const VkDescriptorBindingFlagsEXT bindingFlagsExt[] =
565         {
566                 VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT | bindingFlagUpdateAfterBind,
567                 VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT | bindingFlagUpdateAfterBind
568         };
569
570         const VkDescriptorSetLayoutBindingFlagsCreateInfoEXT    bindingCreateInfoExt =
571         {
572                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT,
573                 DE_NULL,
574                 optional ? 2u : 1u,     // bindingCount
575                 bindingFlagsExt,        // pBindingFlags
576         };
577
578         const VkDescriptorSetLayoutCreateFlags  layoutCreateFlags =
579                 m_testParams.updateAfterBind ? VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT : 0;
580
581         const VkDescriptorSetLayoutCreateInfo   layoutCreateInfo =
582         {
583                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
584                 &bindingCreateInfoExt,  // pNext
585                 layoutCreateFlags,              // flags
586                 optional ? 2u : 1u,             // bindingCount
587                 bindings,                               // pBindings
588         };
589
590         return vk::createDescriptorSetLayout(m_vki, m_vkd, &layoutCreateInfo);
591 }
592
593 Move<VkDescriptorPool>  CommonDescriptorInstance::createDescriptorPool (deUint32                                                        descriptorCount) const
594 {
595         const VkDescriptorPoolCreateFlags pcf = m_testParams.updateAfterBind ? VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT : 0;
596
597         DescriptorPoolBuilder builder;
598
599         builder.addType(m_testParams.descriptorType, descriptorCount);
600
601         if (m_testParams.additionalDescriptorType != VK_DESCRIPTOR_TYPE_UNDEFINED && m_testParams.additionalDescriptorBinding != BINDING_Undefined)
602         {
603                 builder.addType(m_testParams.additionalDescriptorType, 1);
604         }
605
606         return builder.build(m_vki, m_vkd, (VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT | pcf), 1u);
607 }
608
609 Move<VkDescriptorSet> CommonDescriptorInstance::createDescriptorSet     (VkDescriptorPool                                               dsPool,
610                                                                                                                                          VkDescriptorSetLayout                                  dsLayout) const
611 {
612         const VkDescriptorSetAllocateInfo       dsAllocInfo =
613         {
614                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,         // sType;
615                 DE_NULL,                                                                                        // pNext;
616                 dsPool,                                                                                         // descriptorPool;
617                 1u,                                                                                                     // descriptorSetCount
618                 &dsLayout                                                                                       // pSetLayouts
619         };
620
621         return vk::allocateDescriptorSet(m_vki, m_vkd, &dsAllocInfo);
622 }
623
624 void CommonDescriptorInstance::createVertexAttributeBuffer                      (ut::BufferHandleAllocSp&                               buffer,
625                                                                                                                                          deUint32                                                               availableDescriptorCount) const
626 {
627         float                                           xSize                   = 0.0f;
628         float                                           ySize                   = 0.0f;
629
630         const deUint32                          invocationCount = m_testParams.frameResolution.width * m_testParams.frameResolution.height;
631         const std::vector<Vec4>         vertices                = ut::createVertices(m_testParams.frameResolution.width, m_testParams.frameResolution.height, xSize, ySize);
632         const std::vector<deUint32>     primes                  = ut::generatePrimes(availableDescriptorCount);
633         const deUint32                          primeCount              = static_cast<deUint32>(primes.size());
634
635         std::vector<attributes> data(vertices.size());
636         std::transform(vertices.begin(), vertices.end(), data.begin(), attributes());
637
638         for (deUint32 invIdx = 0; invIdx < invocationCount; ++invIdx)
639         {
640                 // r: 2,3,5,7,11,13,2,3,5,7,...
641                 data[invIdx].index.x() = primes[invIdx % primeCount];
642
643                 // b: x index in texel coordinate
644                 data[invIdx].index.z() = invIdx % m_testParams.frameResolution.width;
645
646                 //a: y index in texel coordinate
647                 data[invIdx].index.w() = invIdx / m_testParams.frameResolution.width;
648         }
649
650         // g: 0,0,2,3,0,5,0,7,0,0,0,11,0,13,...
651         for (deUint32 primeIdx = 0; primeIdx < primeCount; ++primeIdx)
652         {
653                 const deUint32 prime = primes[primeIdx];
654                 DE_ASSERT(prime < invocationCount);
655                 data[prime].index.y() = prime;
656         }
657
658         const VkDeviceSize              dataSize = data.size() * sizeof(attributes);
659
660         VkDeviceSize                    deviceSize = ut::createBufferAndBind(buffer, m_context, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, dataSize);
661
662         deMemcpy(buffer->alloc->getHostPtr(), data.data(), static_cast<size_t>(deviceSize));
663
664         vk::flushAlloc(m_vki, m_vkd, *buffer->alloc);
665 }
666
667 std::string CommonDescriptorInstance::substBinding                                      (deUint32                                                               binding,
668                                                                                                                                          const char*                                                    str,
669                                                                                                                                          deUint32                                                               count,
670                                                                                                                                          const char*                                                    name)
671 {
672         std::map<std::string, std::string> vars;
673         vars["?"]       = de::toString(binding);
674         vars["*"]       = (0 == count)          ? ""            : de::toString(count);
675         vars["VAR"]     = (DE_NULL == name)     ? "data"        : name;
676         return tcu::StringTemplate(str).specialize(vars);
677 }
678
679 const char* CommonDescriptorInstance::getVertexShaderProlog                     (void)
680 {
681         return
682                 "layout(location = 0) in  vec4  in_position;    \n"
683                 "layout(location = 1) in  vec2  in_normalpos;   \n"
684                 "layout(location = 2) in  ivec4 index;                  \n"
685                 "layout(location = 0) out vec4  position;       \n"
686                 "layout(location = 1) out vec2  normalpos;      \n"
687                 "layout(location = 2) out int   vIndex;         \n"
688                 "layout(location = 3) out int   rIndex;         \n"
689                 "layout(location = 4) out int   gIndex;         \n"
690                 "layout(location = 5) out int   bIndex;         \n"
691                 "layout(location = 6) out int   aIndex;         \n"
692                 "void main()                                                    \n"
693                 "{                                                                              \n"
694                 "    gl_PointSize = 0.2f;                               \n"
695                 "    position = in_position;                    \n"
696                 "    normalpos = in_normalpos;                  \n"
697                 "    gl_Position = position;                    \n"
698                 "    vIndex = gl_VertexIndex;                   \n"
699                 "    rIndex = index.x;                                  \n"
700                 "    gIndex = index.y;                                  \n"
701                 "    bIndex = index.z;                                  \n"
702                 "    aIndex = index.w;                                  \n";
703 }
704
705 const char* CommonDescriptorInstance::getFragmentShaderProlog           (void)
706 {
707         return
708                 "layout(location = 0) out vec4     FragColor;   \n"
709                 "layout(location = 0) in flat vec4 position;    \n"
710                 "layout(location = 1) in flat vec2 normalpos;   \n"
711                 "layout(location = 2) in flat int  vIndex;              \n"
712                 "layout(location = 3) in flat int  rIndex;              \n"
713                 "layout(location = 4) in flat int  gIndex;              \n"
714                 "layout(location = 5) in flat int  bIndex;              \n"
715                 "layout(location = 6) in flat int  aIndex;              \n"
716                 "void main()                                                                    \n"
717                 "{                                                                                              \n";
718 }
719
720 const char* CommonDescriptorInstance::getShaderEpilog                           (void)
721 {
722         return "}                                                                                       \n";
723 }
724
725 int     CommonDescriptorInstance::constructShaderModules                                (void)
726 {
727         int                                                             result  = 0;
728         ut::DeviceProperties                    dp              (m_context);
729         const VkPhysicalDeviceFeatures& feats   = dp.physicalDeviceFeatures();
730         tcu::TestLog&                                   log             = m_context.getTestContext().getLog();
731
732         if (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT)
733         {
734                 ++result;
735                 const std::string name = ut::buildShaderName(VK_SHADER_STAGE_COMPUTE_BIT, m_testParams.descriptorType, m_testParams.updateAfterBind, m_testParams.calculateInLoop, false);
736                 m_computeModule = vk::createShaderModule(m_vki, m_vkd, m_context.getBinaryCollection().get(name), (VkShaderModuleCreateFlags)0);
737         }
738         if (m_testParams.stageFlags & VK_SHADER_STAGE_FRAGMENT_BIT)
739         {
740                 ++result;
741                 const std::string name = ut::buildShaderName(VK_SHADER_STAGE_FRAGMENT_BIT, m_testParams.descriptorType, m_testParams.updateAfterBind, m_testParams.calculateInLoop, (feats.vertexPipelineStoresAndAtomics != DE_FALSE && m_testParams.allowVertexStoring));
742                 m_fragmentModule = vk::createShaderModule(m_vki, m_vkd, m_context.getBinaryCollection().get(name), (VkShaderModuleCreateFlags)0);
743                 log << tcu::TestLog::Message << "Finally used fragment shader: " << name << '\n' << tcu::TestLog::EndMessage;
744         }
745         if (m_testParams.stageFlags & VK_SHADER_STAGE_VERTEX_BIT)
746         {
747                 ++result;
748                 const std::string name = ut::buildShaderName(VK_SHADER_STAGE_VERTEX_BIT, m_testParams.descriptorType, m_testParams.updateAfterBind, m_testParams.calculateInLoop, (feats.vertexPipelineStoresAndAtomics != DE_FALSE && m_testParams.allowVertexStoring));
749                 m_vertexModule = vk::createShaderModule(m_vki, m_vkd, m_context.getBinaryCollection().get(name), (VkShaderModuleCreateFlags)0);
750                 log << tcu::TestLog::Message << "Finally used vertex shader: " << name << '\n' << tcu::TestLog::EndMessage;
751         }
752
753         DE_ASSERT(result > 0);
754
755         return result;
756 }
757
758 Move<VkRenderPass> CommonDescriptorInstance::createRenderPass           (const IterateCommonVariables&                  variables)
759 {
760         DE_UNREF(variables);
761         if ((m_testParams.stageFlags & VK_SHADER_STAGE_VERTEX_BIT) || (m_testParams.stageFlags & VK_SHADER_STAGE_FRAGMENT_BIT))
762         {
763                 return vk::makeRenderPass(m_vki, m_vkd, m_colorFormat);
764         }
765         return Move<VkRenderPass>();
766 }
767
768 VkPushConstantRange CommonDescriptorInstance::makePushConstantRange     (void) const
769 {
770         const VkPushConstantRange pcr =
771         {
772                 m_testParams.stageFlags,                                                        // stageFlags
773                 0u,                                                                                                     // offset
774                 static_cast<deUint32>(sizeof(push_constant))            // size
775         };
776         return pcr;
777 }
778
779 Move<VkPipelineLayout> CommonDescriptorInstance::createPipelineLayout (const std::vector<VkDescriptorSetLayout>&        descriptorSetLayouts) const
780 {
781         const VkPushConstantRange pcr = makePushConstantRange();
782
783         const VkPipelineLayoutCreateInfo createInfo =
784         {
785                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // sType
786                 DE_NULL,                                                                                        // pNext
787                 (VkPipelineLayoutCreateFlags)0,                                         // flags
788                 static_cast<deUint32>(descriptorSetLayouts.size()),     // setLayoutCount
789                 descriptorSetLayouts.data(),                                            // pSetLayouts;
790                 m_testParams.calculateInLoop ? 1u : 0u,                         // pushConstantRangeCount
791                 m_testParams.calculateInLoop ? &pcr : DE_NULL,          // pPushConstantRanges
792         };
793
794         return vk::createPipelineLayout(m_vki, m_vkd, &createInfo);
795 }
796
797 void CommonDescriptorInstance::createFramebuffer                                        (ut::FrameBufferSp&                                                     frameBuffer,
798                                                                                                                                          VkRenderPass                                                           renderPass,
799                                                                                                                                          const IterateCommonVariables&                          variables)
800 {
801         DE_UNREF(variables);
802         ut::createFrameBuffer(frameBuffer, m_context, m_testParams.frameResolution, m_colorFormat, renderPass);
803 }
804
805 Move<VkPipeline> CommonDescriptorInstance::createPipeline                       (VkPipelineLayout                                                       pipelineLayout,
806                                                                                                                                          VkRenderPass                                                           renderPass)
807 {       DE_ASSERT(VK_SHADER_STAGE_ALL != m_testParams.stageFlags);
808
809         constructShaderModules();
810
811         return (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT)
812                 ? createComputePipeline(pipelineLayout)
813                 : createGraphicsPipeline(pipelineLayout, renderPass);
814 }
815
816 Move<VkPipeline> CommonDescriptorInstance::createComputePipeline        (VkPipelineLayout                                                       pipelineLayout)
817 {
818         const VkPipelineShaderStageCreateInfo   shaderStaegCreateInfo =
819         {
820                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
821                 DE_NULL,                                                                // pNext
822                 (VkPipelineShaderStageCreateFlags)0,    // flags
823                 VK_SHADER_STAGE_COMPUTE_BIT,                    // stage
824                 *m_computeModule,                                               // module
825                 "main",                                                                 // pName
826                 (VkSpecializationInfo*)DE_NULL                  // pSpecializationInfo
827         };
828
829         const VkComputePipelineCreateInfo               pipelineCreateInfo =
830         {
831                 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
832                 DE_NULL,                                                                // pNext
833                 0u,                                                                             // flags
834                 shaderStaegCreateInfo,                                  // stage
835                 pipelineLayout,                                                 // layout
836                 (VkPipeline)0,                                                  // basePipelineHandle
837                 0u,                                                                             // basePipelineIndex
838         };
839         return vk::createComputePipeline(m_vki, m_vkd, (VkPipelineCache)0u, &pipelineCreateInfo);
840 }
841
842 Move<VkPipeline> CommonDescriptorInstance::createGraphicsPipeline       (VkPipelineLayout                                                       pipelineLayout,
843                                                                                                                                          VkRenderPass                                                           renderPass)
844 {
845         const VkVertexInputBindingDescription                   bindingDescriptions[] =
846         {
847                 {
848                         0u,                                                                                                     // binding
849                         sizeof(attributes),                                                                     // stride
850                         VK_VERTEX_INPUT_RATE_VERTEX,                                            // inputRate
851                 },
852         };
853
854         const VkVertexInputAttributeDescription                 attributeDescriptions[] =
855         {
856                 {
857                         0u,                                                                                                     // location
858                         0u,                                                                                                     // binding
859                         ut::mapType2vkFormat<attributes::vec4>::value,          // format
860                         0u                                                                                                      // offset
861                 },                                                                                                              // @in_position
862                 {
863                         1u,                                                                                                     // location
864                         0u,                                                                                                     // binding
865                         ut::mapType2vkFormat<attributes::vec2>::value,          // format
866                         static_cast<deUint32>(sizeof(attributes::vec4))         // offset
867                 },                                                                                                              // @normalpos
868                 {
869                         2u,                                                                                                     // location
870                         0u,                                                                                                     // binding
871                         ut::mapType2vkFormat<attributes::ivec4>::value,         // format
872                         static_cast<deUint32>(sizeof(attributes::vec2)
873                                                                 + sizeof(attributes::vec4))             // offset
874                 },                                                                                                              // @index
875         };
876
877         const VkPipelineVertexInputStateCreateInfo              vertexInputStateCreateInfo      =
878         {
879                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
880                 DE_NULL,
881                 (VkPipelineVertexInputStateCreateFlags)0,       // flags
882                 DE_LENGTH_OF_ARRAY(bindingDescriptions),        // vertexBindingDescriptionCount
883                 bindingDescriptions,                                            // pVertexBindingDescriptions
884                 DE_LENGTH_OF_ARRAY(attributeDescriptions),      // vertexAttributeDescriptionCount
885                 attributeDescriptions                                           // pVertexAttributeDescriptions
886         };
887
888         const std::vector<VkViewport>   viewports       (1, makeViewport(m_testParams.frameResolution.width, m_testParams.frameResolution.height));
889         const std::vector<VkRect2D>             scissors        (1, makeRect2D(m_testParams.frameResolution.width, m_testParams.frameResolution.height));
890
891         DE_ASSERT(m_vertexModule && m_fragmentModule);
892
893         return vk::makeGraphicsPipeline(
894                 m_vki,                                                                                  // vk
895                 m_vkd,                                                                                  // device
896                 pipelineLayout,                                                                 // pipelineLayout
897                 *m_vertexModule,                                                                // vertexShaderModule
898                 DE_NULL,                                                                                // tessellationControlModule
899                 DE_NULL,                                                                                // tessellationEvalModule
900                 DE_NULL,                                                                                // geometryShaderModule
901                 *m_fragmentModule,                                                              // fragmentShaderModule
902                 renderPass,                                                                             // renderPass
903                 viewports,                                                                              // viewports
904                 scissors,                                                                               // scissors
905                 VK_PRIMITIVE_TOPOLOGY_POINT_LIST,                               // topology
906                 0U,                                                                                             // subpass
907                 0U,                                                                                             // patchControlPoints
908                 &vertexInputStateCreateInfo);                                   // vertexInputStateCreateInfo
909 }
910
911 VkDeviceSize CommonDescriptorInstance::createBuffers                            (std::vector<VkDescriptorBufferInfo>&           bufferInfos,
912                                                                                                                                          ut::BufferHandleAllocSp&                                       buffer,
913                                                                                                                                          deUint32                                                                       elementCount,
914                                                                                                                                          deUint32                                                                       elementSize,
915                                                                                                                                          VkDeviceSize                                                           alignment,
916                                                                                                                                          VkBufferUsageFlags                                                     bufferUsage)
917 {
918         const VkDeviceSize      roundedSize = deAlign64(elementSize, alignment);
919         VkDeviceSize            bufferSize      = ut::createBufferAndBind(buffer, m_context, bufferUsage, (roundedSize * elementCount));
920
921         for (deUint32 elementIdx = 0; elementIdx < elementCount; ++elementIdx)
922         {
923                 const VkDescriptorBufferInfo bufferInfo =
924                 {
925                         *buffer.get()->buffer,          //buffer;
926                         elementIdx * roundedSize,       //offset;
927                         elementSize,                            // range;
928
929                 };
930                 bufferInfos.push_back(bufferInfo);
931         }
932
933         return bufferSize;
934 }
935
936 VkDeviceSize CommonDescriptorInstance::createImages                                     (std::vector<ut::ImageHandleAllocSp>&           images,
937                                                                                                                                          std::vector<VkDescriptorBufferInfo>&           bufferInfos,
938                                                                                                                                          ut::BufferHandleAllocSp&                                       buffer,
939                                                                                                                                          VkBufferUsageFlags                                                     bufferUsage,
940                                                                                                                                          const VkExtent3D&                                                      imageExtent,
941                                                                                                                                          VkFormat                                                                       imageFormat,
942                                                                                                                                          VkImageLayout                                                          imageLayout,
943                                                                                                                                          deUint32                                                                       imageCount,
944                                                                                                                                          bool                                                                           withMipMaps)
945
946 {
947         const deUint32          imageSize       = ut::computeImageSize(imageExtent, imageFormat, withMipMaps);
948
949         const VkDeviceSize      bufferSize      = createBuffers(bufferInfos, buffer, imageCount, imageSize, sizeof(tcu::Vec4), bufferUsage);
950
951         for (deUint32 imageIdx = 0; imageIdx < imageCount; ++imageIdx)
952         {
953                 ut::ImageHandleAllocSp image;
954                 ut::createImageAndBind(image, m_context, imageFormat, imageExtent, imageLayout, withMipMaps);
955                 images.push_back(image);
956         }
957
958         return bufferSize;
959 }
960
961 void CommonDescriptorInstance::createBuffersViews                                       (std::vector<ut::BufferViewSp>&                         views,
962                                                                                                                                          const std::vector<VkDescriptorBufferInfo>&     bufferInfos,
963                                                                                                                                          VkFormat                                                                       format)
964 {
965         const deUint32 infoCount = static_cast<deUint32>(bufferInfos.size());
966         for (deUint32 infoIdx = 0; infoIdx < infoCount; ++infoIdx)
967         {
968                 const VkDescriptorBufferInfo&   bufferInfo = bufferInfos[infoIdx];
969                 const VkBufferViewCreateInfo    bufferViewInfo =
970                 {
971                         VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,      // sType
972                         DE_NULL,                                                                        // pNext
973                         (VkBufferViewCreateFlags)0,                                     // flags
974                         bufferInfo.buffer,                                                      // buffer
975                         format,                                                                         // format
976                         bufferInfo.offset,                                                      // offset
977                         bufferInfo.range                                                        // range;
978                 };
979                 views.push_back(ut::BufferViewSp(new Move<VkBufferView>(vk::createBufferView(m_vki, m_vkd, &bufferViewInfo))));
980         }
981 }
982
983 void CommonDescriptorInstance::createImagesViews                                        (std::vector<ut::ImageViewSp>&                          views,
984                                                                                                                                          const std::vector<ut::ImageHandleAllocSp>&     images,
985                                                                                                                                          VkFormat                                                                       format)
986 {
987         const deUint32 imageCount = static_cast<deUint32>(images.size());
988         for (deUint32 imageIdx = 0; imageIdx < imageCount; ++imageIdx)
989         {
990                 const VkImageViewCreateInfo createInfo =
991                 {
992                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,       // sType
993                         DE_NULL,                                                                        // pNext
994                         (VkImageViewCreateFlags)0,                                      // flags
995                         *images[imageIdx]->image,                                       // image
996                         VK_IMAGE_VIEW_TYPE_2D,                                          // viewType
997                         format,                                                                         // format
998                         vk::makeComponentMappingRGBA(),                         // components
999                         {
1000                                 VK_IMAGE_ASPECT_COLOR_BIT,                              // aspectMask
1001                                 (deUint32)0,                                                    // baseMipLevel
1002                                 images[imageIdx]->levels,                               // mipLevels
1003                                 (deUint32)0,                                                    // baseArrayLayer
1004                                 (deUint32)1u,                                                   // arraySize
1005                         },
1006                 };
1007                 views.push_back(ut::ImageViewSp(new Move<VkImageView>(vk::createImageView(m_vki, m_vkd, &createInfo))));
1008         }
1009 }
1010
1011 void CommonDescriptorInstance::copyBuffersToImages                                      (IterateCommonVariables&                                        variables)
1012 {
1013         const deUint32 infoCount = static_cast<deUint32>(variables.descriptorsBufferInfos.size());
1014         DE_ASSERT(variables.descriptorsImages.size() == infoCount);
1015         const VkPipelineStageFlagBits dstStageMask = (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT)
1016                 ? VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
1017                 : VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
1018         for (deUint32 infoIdx = 0; infoIdx < infoCount; ++infoIdx)
1019         {
1020                 ut::recordCopyBufferToImage(
1021                         *variables.commandBuffer,                                               // commandBuffer
1022                         m_vki,                                                                                  // interface
1023                         VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,                              // srcStageMask
1024                         dstStageMask,                                                                   // dstStageMask
1025                         variables.descriptorsBufferInfos[infoIdx],              // bufferInfo
1026                         *(variables.descriptorsImages[infoIdx]->image), // image
1027                         variables.descriptorsImages[infoIdx]->extent,   // imageExtent
1028                         variables.descriptorsImages[infoIdx]->format,   // imageFormat
1029                         variables.descriptorsImages[infoIdx]->layout,   // oldImageLayout
1030                         VK_IMAGE_LAYOUT_GENERAL,                                                // newImageLayout
1031                         variables.descriptorsImages[infoIdx]->levels);  // mipLevelCount
1032
1033                 variables.descriptorsImages[infoIdx]->layout = VK_IMAGE_LAYOUT_GENERAL;
1034         }
1035 }
1036
1037 void CommonDescriptorInstance::copyImagesToBuffers                                      (IterateCommonVariables&                                        variables)
1038 {
1039         const deUint32 infoCount = static_cast<deUint32>(variables.descriptorsBufferInfos.size());
1040         DE_ASSERT(variables.descriptorsImages.size() == infoCount);
1041         const VkPipelineStageFlagBits srcStageMask = (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT)
1042                 ? VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
1043                 : VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
1044
1045         for (deUint32 infoIdx = 0; infoIdx < infoCount; ++infoIdx)
1046         {
1047                 ut::recordCopyImageToBuffer(
1048                         *variables.commandBuffer,                                               // commandBuffer
1049                         m_vki,                                                                                  // interface
1050                         srcStageMask,                                                                   // srcStageMask
1051                         VK_PIPELINE_STAGE_HOST_BIT,                                             // dstStageMask
1052                         *(variables.descriptorsImages[infoIdx]->image), // image
1053                         variables.descriptorsImages[infoIdx]->extent,   // imageExtent
1054                         variables.descriptorsImages[infoIdx]->format,   // imageFormat
1055                         variables.descriptorsImages[infoIdx]->layout,   // oldImageLayout
1056                         VK_IMAGE_LAYOUT_GENERAL,                                                // newImageLayout
1057                         variables.descriptorsBufferInfos[infoIdx]);             // bufferInfo
1058         }
1059 }
1060
1061 PixelBufferAccess CommonDescriptorInstance::getPixelAccess                      (deUint32                                                                       imageIndex,
1062                                                                                                                                          const VkExtent3D&                                                      imageExtent,
1063                                                                                                                                          VkFormat                                                                       imageFormat,
1064                                                                                                                                          const std::vector<VkDescriptorBufferInfo>&     bufferInfos,
1065                                                                                                                                          const ut::BufferHandleAllocSp&                         buffer,
1066                                                                                                                                          deUint32                                                                       mipLevel) const
1067 {
1068         DE_ASSERT(bufferInfos[imageIndex].buffer == *buffer.get()->buffer);
1069         DE_ASSERT(ut::computeImageSize(imageExtent, imageFormat, true, (mipLevel ? ut::maxDeUint32 : 0)) <= bufferInfos[imageIndex].range);
1070         DE_ASSERT(imageExtent.width             >> mipLevel);
1071         DE_ASSERT(imageExtent.height    >> mipLevel);
1072
1073         deUint32 mipOffset = 0;
1074
1075         for (deUint32 level = 0; mipLevel && level < mipLevel; ++level)
1076         {
1077                 mipOffset += ut::computeImageSize(imageExtent, imageFormat, true, level);
1078         }
1079
1080         unsigned char* hostPtr  = static_cast<unsigned char*>(buffer->alloc->getHostPtr());
1081         unsigned char* data = hostPtr + bufferInfos[imageIndex].offset + mipOffset;
1082         return tcu::PixelBufferAccess(vk::mapVkFormat(imageFormat), (imageExtent.width >> mipLevel), (imageExtent.height >> mipLevel), imageExtent.depth, data);
1083 }
1084
1085
1086 void CommonDescriptorInstance::updateDescriptors                                        (IterateCommonVariables&                                        variables)
1087 {
1088         const std::vector<deUint32>     primes = ut::generatePrimes(variables.availableDescriptorCount);
1089         const deUint32                          primeCount = static_cast<deUint32>(primes.size());
1090
1091         for (deUint32 primeIdx = 0; primeIdx < primeCount; ++primeIdx)
1092         {
1093                 const VkDescriptorBufferInfo*   pBufferInfo                     = DE_NULL;
1094                 const VkDescriptorImageInfo*    pImageInfo                      = DE_NULL;
1095                 const VkBufferView*                             pTexelBufferView        = DE_NULL;
1096
1097
1098                 VkDescriptorImageInfo           imageInfo =
1099                 {
1100                         static_cast<VkSampler>(0),
1101                         static_cast<VkImageView>(0),
1102                         VK_IMAGE_LAYOUT_GENERAL
1103                 };
1104
1105                 switch (m_testParams.descriptorType)
1106                 {
1107                 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1108                 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1109                 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1110                 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1111                 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1112                 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1113                         {
1114                                 pBufferInfo = &variables.descriptorsBufferInfos[primeIdx];
1115                                 switch (m_testParams.descriptorType)
1116                                 {
1117                                 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1118                                 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1119                                         pTexelBufferView = &(**variables.descriptorsBufferViews[primeIdx]);
1120                                         break;
1121                                 default:
1122                                         break;
1123                                 }
1124                         }
1125                         break;
1126
1127                 case VK_DESCRIPTOR_TYPE_SAMPLER:
1128                         imageInfo.sampler = **variables.descriptorSamplers[primeIdx];
1129                         pImageInfo = &imageInfo;
1130                         break;
1131
1132                 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1133                 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1134                 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1135                         imageInfo.imageView = **variables.descriptorImageViews[primeIdx];
1136                         pImageInfo = &imageInfo;
1137                         break;
1138
1139                 default:        break;
1140                 }
1141
1142                 const VkWriteDescriptorSet writeInfo =
1143                 {
1144                         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,                 // sType
1145                         DE_NULL,                                                                                // pNext
1146                         *variables.descriptorSet,                                               // descriptorSet
1147                         m_testParams.descriptorBinding,                                 // descriptorBinding;
1148                         primes[primeIdx],                                                               // elementIndex
1149                         1u,                                                                                             // descriptorCount
1150                         m_testParams.descriptorType,                                    // descriptorType
1151                         pImageInfo,                                                                             // pImageInfo
1152                         pBufferInfo,                                                                    // pBufferInfo
1153                         pTexelBufferView                                                                // pTexelBufferView
1154                 };
1155
1156                 m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, DE_NULL);
1157         }
1158 }
1159
1160 void CommonDescriptorInstance::iterateCommandBegin                                      (IterateCommonVariables&                                        variables)
1161 {
1162         variables.dataAlignment                         = 0;
1163
1164         variables.renderArea.offset.x           = 0;
1165         variables.renderArea.offset.y           = 0;
1166         variables.renderArea.extent.width       = m_testParams.frameResolution.width;
1167         variables.renderArea.extent.height      = m_testParams.frameResolution.height;
1168
1169         variables.vertexCount                           = m_testParams.frameResolution.width * m_testParams.frameResolution.height;
1170
1171         variables.lowerBound                            = 0;
1172         variables.upperBound                            = variables.vertexCount;
1173
1174         variables.descriptorSetLayout           = createDescriptorSetLayout(variables.availableDescriptorCount);
1175         variables.validDescriptorCount          = ut::computePrimeCount(variables.availableDescriptorCount);
1176         variables.descriptorPool                        = createDescriptorPool(variables.availableDescriptorCount);
1177         variables.descriptorSet                         = createDescriptorSet(*variables.descriptorPool, *variables.descriptorSetLayout);
1178
1179         std::vector<VkDescriptorSetLayout>      descriptorSetLayouts;
1180         descriptorSetLayouts.push_back(*variables.descriptorSetLayout);
1181         if (m_testParams.calculateInLoop)
1182         {
1183                 variables.descriptorEnumerator.init(m_context, variables.vertexCount, variables.availableDescriptorCount);
1184                 descriptorSetLayouts.push_back(*variables.descriptorEnumerator.descriptorSetLayout);
1185         }
1186
1187         variables.pipelineLayout                        = createPipelineLayout(descriptorSetLayouts);
1188
1189         createAndPopulateDescriptors            (variables);
1190
1191         variables.renderPass                            = createRenderPass(variables);
1192         variables.pipeline                                      = createPipeline(*variables.pipelineLayout, *variables.renderPass);
1193
1194         variables.commandBuffer                         = createCmdBuffer();
1195
1196         if ((m_testParams.stageFlags & VK_SHADER_STAGE_VERTEX_BIT) || (m_testParams.stageFlags & VK_SHADER_STAGE_FRAGMENT_BIT))
1197         {
1198                 createVertexAttributeBuffer             (variables.vertexAttributesBuffer, variables.availableDescriptorCount);
1199                 createFramebuffer                               (variables.frameBuffer, *variables.renderPass, variables);
1200         }
1201
1202         if (m_testParams.calculateInLoop)
1203         {
1204                 variables.descriptorEnumerator.update(m_context);
1205         }
1206
1207         if (!m_testParams.updateAfterBind)
1208         {
1209                 updateDescriptors                               (variables);
1210         }
1211
1212         vk::beginCommandBuffer                          (m_vki, *variables.commandBuffer);
1213
1214         if (m_testParams.calculateInLoop)
1215         {
1216                 deRandom rnd;
1217                 deRandom_init(&rnd, static_cast<deUint32>(m_testParams.descriptorType));
1218                 const deUint32 quarter = variables.vertexCount / 4;
1219
1220                 variables.lowerBound                    = deRandom_getUint32(&rnd) % quarter;
1221                 variables.upperBound                    = (deRandom_getUint32(&rnd) % quarter) + (3 * quarter);
1222
1223                 const push_constant pc =
1224                 {
1225                         static_cast<deInt32>(variables.lowerBound),
1226                         static_cast<deInt32>(variables.upperBound)
1227                 };
1228
1229                 m_vki.cmdPushConstants(*variables.commandBuffer, *variables.pipelineLayout, m_testParams.stageFlags, 0u, static_cast<deUint32>(sizeof(pc)), &pc);
1230         }
1231
1232         if ((m_testParams.stageFlags & VK_SHADER_STAGE_VERTEX_BIT) || (m_testParams.stageFlags & VK_SHADER_STAGE_FRAGMENT_BIT))
1233         {
1234                 commandBindVertexAttributes             (*variables.commandBuffer, variables.vertexAttributesBuffer);
1235         }
1236
1237         if (m_testParams.calculateInLoop)
1238         {
1239                 commandBindDescriptorSets(*variables.commandBuffer, *variables.pipelineLayout, *variables.descriptorEnumerator.descriptorSet, 1);
1240         }
1241
1242         if (!ut::isDynamicDescriptor(m_testParams.descriptorType))
1243         {
1244                 commandBindDescriptorSets               (*variables.commandBuffer, *variables.pipelineLayout, *variables.descriptorSet, 0);
1245         }
1246
1247         commandBindPipeline                                     (*variables.commandBuffer, *variables.pipeline);
1248 }
1249
1250 tcu::TestStatus CommonDescriptorInstance::iterate                                       (void)
1251 {
1252         IterateCommonVariables  v;
1253         iterateCommandBegin             (v);
1254
1255         if (true == m_testParams.copyBuffersToImages)
1256         {
1257                 copyBuffersToImages     (v);
1258         }
1259
1260         if (true == m_testParams.updateAfterBind)
1261         {
1262                 updateDescriptors       (v);
1263         }
1264
1265         vk::beginRenderPass             (m_vki, *v.commandBuffer, *v.renderPass, *v.frameBuffer->buffer, v.renderArea, m_clearColor);
1266         m_vki.cmdDraw                   (*v.commandBuffer, v.vertexCount, 1u, 0u, 0u);
1267         vk::endRenderPass               (m_vki, *v.commandBuffer);
1268
1269         return (iterateCommandEnd(v) ? tcu::TestStatus::pass : tcu::TestStatus::fail)("");
1270 }
1271
1272 std::vector<float> CommonDescriptorInstance::createColorScheme          (void)
1273 {
1274         std::vector<float> cs;
1275         int divider = 2;
1276         for (int i = 0; i < 10; ++i)
1277         {
1278                 cs.push_back(1.0f / float(divider));
1279                 divider *= 2;
1280         }
1281         return cs;
1282 }
1283
1284 bool CommonDescriptorInstance::iterateCommandEnd                                        (IterateCommonVariables&                                        variables,
1285                                                                                                                                          bool                                                                           collectBeforeSubmit)
1286 {
1287         ut::UpdatablePixelBufferAccessPtr       programResult;
1288         ut::UpdatablePixelBufferAccessPtr       referenceResult;
1289
1290         if (collectBeforeSubmit)
1291         {
1292                 iterateCollectResults(programResult, variables, true);
1293                 iterateCollectResults(referenceResult, variables, false);
1294         }
1295
1296         VK_CHECK(m_vki.endCommandBuffer(*variables.commandBuffer));
1297         Move<VkFence> fence = commandSubmit(*variables.commandBuffer);
1298         m_vki.waitForFences(m_vkd, 1, &(*fence), DE_TRUE, ~0ull);
1299
1300         if (false == collectBeforeSubmit)
1301         {
1302                 iterateCollectResults(programResult, variables, true);
1303                 iterateCollectResults(referenceResult, variables, false);
1304         }
1305
1306         bool result = false;
1307         if (m_testParams.fuzzyComparison)
1308         {
1309                 result = tcu::fuzzyCompare(m_context.getTestContext().getLog(),
1310                         "Fuzzy Compare", "Comparison result", *referenceResult.get(), *programResult.get(), 0.02f, tcu::COMPARE_LOG_EVERYTHING);
1311         }
1312         else
1313         {
1314                 result = tcu::floatThresholdCompare(m_context.getTestContext().getLog(),
1315                         "Float Threshold Compare", "Comparison result", *referenceResult.get(), *programResult.get(), tcu::Vec4(0.02f, 0.02f, 0.02f, 0.02f), tcu::COMPARE_LOG_EVERYTHING);
1316         }
1317
1318         if (m_testParams.allowVertexStoring)
1319         {
1320                 result = verifyVertexWriteResults(variables);
1321         }
1322
1323         return result;
1324 }
1325
1326 void CommonDescriptorInstance::iterateCollectResults                            (ut::UpdatablePixelBufferAccessPtr&                     result,
1327                                                                                                                                          const IterateCommonVariables&                          variables,
1328                                                                                                                                          bool                                                                           fromTest)
1329 {
1330         if (fromTest)
1331         {
1332                 result = commandReadFrameBuffer(*variables.commandBuffer, variables.frameBuffer);
1333         }
1334         else
1335         {
1336                 result = ut::UpdatablePixelBufferAccessPtr(new ut::PixelBufferAccessAllocation(vk::mapVkFormat(m_colorFormat), m_testParams.frameResolution));
1337
1338                 for (deUint32 y = 0, pixelNum = 0; y < m_testParams.frameResolution.height; ++y)
1339                 {
1340                         for (deUint32 x = 0; x < m_testParams.frameResolution.width; ++x, ++pixelNum)
1341                         {
1342                                 const float component = m_colorScheme[(pixelNum % variables.validDescriptorCount) % m_schemeSize];
1343                                 result->setPixel(tcu::Vec4(component, component, component, 1.0f), x, y);
1344                         }
1345                 }
1346         }
1347 }
1348
1349 Move<VkCommandBuffer> CommonDescriptorInstance::createCmdBuffer         (void)
1350 {
1351         return vk::allocateCommandBuffer(m_vki, m_vkd, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1352 }
1353
1354 Move<VkFence> CommonDescriptorInstance::commandSubmit                           (VkCommandBuffer                                                        cmd)
1355 {
1356         Move<VkFence>   fence(vk::createFence(m_vki, m_vkd));
1357
1358         const VkSubmitInfo      submitInfo =
1359         {
1360                 VK_STRUCTURE_TYPE_SUBMIT_INFO,                                          // sType
1361                 DE_NULL,                                                                                        // pNext
1362                 0u,                                                                                                     // waitSemaphoreCount
1363                 static_cast<VkSemaphore*>(DE_NULL),                                     // pWaitSemaphores
1364                 static_cast<const VkPipelineStageFlags*>(DE_NULL),      // pWaitDstStageMask
1365                 1u,                                                                                                     // commandBufferCount
1366                 &cmd,                                                                                           // pCommandBuffers
1367                 0u,                                                                                                     // signalSemaphoreCount
1368                 static_cast<VkSemaphore*>(DE_NULL)                                      // pSignalSemaphores
1369         };
1370
1371         VK_CHECK(m_vki.queueSubmit(m_queue, 1u, &submitInfo, *fence));
1372
1373         return fence;
1374 }
1375
1376 bool CommonDescriptorInstance::verifyVertexWriteResults(IterateCommonVariables&                                 variables)
1377 {
1378         DE_UNREF(variables);
1379         return true;
1380 }
1381
1382 void CommonDescriptorInstance::commandBindPipeline                                      (VkCommandBuffer                                                        commandBuffer,
1383                                                                                                                                          VkPipeline                                                                     pipeline)
1384 {
1385         const VkPipelineBindPoint pipelineBindingPoint = (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT) ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS;
1386         m_vki.cmdBindPipeline(commandBuffer, pipelineBindingPoint, pipeline);
1387 }
1388
1389 void CommonDescriptorInstance::commandBindVertexAttributes                      (VkCommandBuffer                                                        commandBuffer,
1390                                                                                                                                          const ut::BufferHandleAllocSp&                         vertexAttributesBuffer)
1391 {
1392         const VkDeviceSize      offsets[] = { 0u };
1393         const VkBuffer          buffers[] = { *vertexAttributesBuffer->buffer };
1394         m_vki.cmdBindVertexBuffers(commandBuffer, 0u, 1u, buffers, offsets);
1395 }
1396
1397 void CommonDescriptorInstance::commandBindDescriptorSets                        (VkCommandBuffer                                                        commandBuffer,
1398                                                                                                                                          VkPipelineLayout                                                       pipelineLayout,
1399                                                                                                                                          VkDescriptorSet                                                        descriptorSet,
1400                                                                                                                                          deUint32                                                                       descriptorSetIndex)
1401 {
1402         const VkPipelineBindPoint pipelineBindingPoint = (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT) ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS;
1403         m_vki.cmdBindDescriptorSets(commandBuffer, pipelineBindingPoint, pipelineLayout, descriptorSetIndex, 1u, &descriptorSet, 0u, static_cast<deUint32*>(DE_NULL));
1404 }
1405
1406 ut::UpdatablePixelBufferAccessPtr
1407 CommonDescriptorInstance::commandReadFrameBuffer                                        (VkCommandBuffer                                                        commandBuffer,
1408                                                                                                                                          const ut::FrameBufferSp&                                       frameBuffer)
1409 {
1410         ut::BufferHandleAllocSp frameBufferContent;
1411         commandReadFrameBuffer(frameBufferContent, commandBuffer, frameBuffer);
1412         return ut::UpdatablePixelBufferAccessPtr(new ut::PixelBufferAccessBuffer(
1413                 m_vkd, m_vki, vk::mapVkFormat(m_colorFormat), m_testParams.frameResolution,
1414                 de::SharedPtr< Move<VkBuffer> >(new Move<VkBuffer>(frameBufferContent->buffer)),
1415                 de::SharedPtr< de::MovePtr<Allocation> >(new de::MovePtr<Allocation>(frameBufferContent->alloc))));
1416 }
1417
1418 void CommonDescriptorInstance::commandReadFrameBuffer                           (ut::BufferHandleAllocSp&                                       content,
1419                                                                                                                                          VkCommandBuffer                                                        commandBuffer,
1420                                                                                                                                          const ut::FrameBufferSp&                                       frameBuffer)
1421 {
1422         Move<VkBuffer>                  buffer;
1423         de::MovePtr<Allocation> allocation;
1424
1425         const VkDeviceSize bufferSize = ut::computeImageSize(frameBuffer->image);
1426
1427         // create a buffer and an host allocation for it
1428         {
1429                 const VkBufferCreateInfo bufferCreateInfo =
1430                 {
1431                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // sType
1432                         DE_NULL,                                                                        // pNext
1433                         0u,                                                                                     // flags
1434                         bufferSize,                                                                     // size
1435                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       // usage
1436                         VK_SHARING_MODE_EXCLUSIVE,                                      // sharingMode
1437                         1u,                                                                                     // queueFamilyIndexCoun
1438                         &m_queueFamilyIndex                                                     // pQueueFamilyIndices
1439                 };
1440
1441                 buffer = vk::createBuffer(m_vki, m_vkd, &bufferCreateInfo);
1442                 const VkMemoryRequirements      memRequirements(vk::getBufferMemoryRequirements(m_vki, m_vkd, *buffer));
1443                 allocation = m_allocator.allocate(memRequirements, MemoryRequirement::HostVisible);
1444
1445                 VK_CHECK(m_vki.bindBufferMemory(m_vkd, *buffer, allocation->getMemory(), allocation->getOffset()));
1446         }
1447
1448         const VkImage& image = *frameBuffer->image->image;
1449
1450         VkImageSubresourceRange         subresourceRange =
1451         {
1452                 VK_IMAGE_ASPECT_COLOR_BIT,                                      // aspectMask
1453                 0u,                                                                                     // baseMipLevel
1454                 1u,                                                                                     // levelCount
1455                 0u,                                                                                     // baseArrayLayer
1456                 1u,                                                                                     // layerCount
1457         };
1458
1459         const VkImageMemoryBarrier      imageBarrier =
1460         {
1461                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // sType;
1462                 DE_NULL,                                                                        // pNext;
1463                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // srcAccessMask;
1464                 VK_ACCESS_TRANSFER_READ_BIT,                            // dstAccessMask;
1465                 VK_IMAGE_LAYOUT_UNDEFINED,                                      // oldLayout
1466                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // newLayout;
1467                 VK_QUEUE_FAMILY_IGNORED,                                        // srcQueueFamilyIndex;
1468                 VK_QUEUE_FAMILY_IGNORED,                                        // dstQueueFamilyIndex;
1469                 image,                                                                          // image;
1470                 subresourceRange,                                                       // subresourceRange;
1471         };
1472
1473         const VkBufferImageCopy         copyRegion =
1474         {
1475                 0u,                                                                                     // bufferOffset
1476                 frameBuffer->image->extent.width,                               // bufferRowLength
1477                 frameBuffer->image->extent.height,                      // bufferImageHeight
1478                 {                                                                                       // VkImageSubresourceLayers
1479                         VK_IMAGE_ASPECT_COLOR_BIT,                              // aspect
1480                         0u,                                                                             // mipLevel
1481                         0u,                                                                             // baseArrayLayer
1482                         1u,                                                                             // layerCount
1483                 },
1484                 { 0, 0, 0 },                                                            // imageOffset
1485                 frameBuffer->image->extent                                      // imageExtent
1486         };
1487
1488         const VkBufferMemoryBarrier     bufferBarrier =
1489         {
1490                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // sType;
1491                 DE_NULL,                                                                        // pNext;
1492                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // srcAccessMask;
1493                 VK_ACCESS_HOST_READ_BIT,                                        // dstAccessMask;
1494                 VK_QUEUE_FAMILY_IGNORED,                                        // srcQueueFamilyIndex;
1495                 VK_QUEUE_FAMILY_IGNORED,                                        // dstQueueFamilyIndex;
1496                 *buffer,                                                                        // buffer;
1497                 0u,                                                                                     // offset;
1498                 bufferSize                                                                      // size;
1499         };
1500
1501         m_vki.cmdPipelineBarrier(commandBuffer,                                                                                         // commandBuffer
1502                 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,  // srcStageMask, dstStageMask
1503                 (VkDependencyFlags)0,                                                                                                                   // dependencyFlags
1504                 0u, (const VkMemoryBarrier*)DE_NULL,                                                                                    // memoryBarrierCount, pMemoryBarriers
1505                 0u, (const VkBufferMemoryBarrier*)DE_NULL,                                                                              // bufferBarrierCount, pBufferBarriers
1506                 1u, &imageBarrier);                                                                                                                             // imageBarrierCount, pImageBarriers
1507
1508         m_vki.cmdCopyImageToBuffer(commandBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, &copyRegion);
1509
1510         m_vki.cmdPipelineBarrier(commandBuffer,
1511                 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
1512                 (VkDependencyFlags)0,
1513                 0, DE_NULL,
1514                 1, &bufferBarrier,
1515                 0u, DE_NULL);
1516
1517         content = ut::BufferHandleAllocSp(new ut::BufferHandleAlloc(buffer, allocation));
1518 }
1519
1520 std::string CommonDescriptorInstance::getColorAccess                            (VkDescriptorType                                                       descriptorType,
1521                                                                                                                                          const char*                                                            indexVariableName,
1522                                                                                                                                          bool                                                                           usesMipMaps)
1523 {
1524         std::string text;
1525         std::map<std::string, std::string> vars;
1526         vars["INDEX"] = indexVariableName;
1527
1528         switch (descriptorType)
1529         {
1530         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1531         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1532                 text = "data[nonuniformEXT(${INDEX})].c";
1533                 break;
1534         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1535         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1536                 text = "data[nonuniformEXT(${INDEX})].cold";
1537                 break;
1538         case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1539                 text = "subpassLoad(data[nonuniformEXT(${INDEX})]).rgba";
1540                 break;
1541         case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1542                 text = "texelFetch(data[nonuniformEXT(${INDEX})], 0)";
1543                 break;
1544         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1545                 text = "imageLoad(data[nonuniformEXT(${INDEX})], 0)";
1546                 break;
1547         case VK_DESCRIPTOR_TYPE_SAMPLER:
1548                 text = usesMipMaps
1549                         ? "textureLod(sampler2D(tex[0], data[nonuniformEXT(${INDEX})]), normalpos, 1)"
1550                         : "texture(   sampler2D(tex[0], data[nonuniformEXT(${INDEX})]), normalpos   )";
1551                 break;
1552         case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1553                 text = usesMipMaps
1554                         ? "textureLod( sampler2D(data[nonuniformEXT(${INDEX})], samp[0]), vec2(0,0), textureQueryLevels(sampler2D(data[nonuniformEXT(${INDEX})], samp[0]))-1)"
1555                         : "texture(    sampler2D(data[nonuniformEXT(${INDEX})], samp[0]), vec2(0,0)   )";
1556                 break;
1557         case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1558                 text = usesMipMaps
1559                         ? "textureLod( data[nonuniformEXT(${INDEX})], uvec2(0,0), textureQueryLevels(data[nonuniformEXT(${INDEX})])-1)"
1560                         : "texture(    data[nonuniformEXT(${INDEX})], uvec2(0,0)   )";
1561                 break;
1562         default:
1563                 TCU_THROW(InternalError, "Not implemented descriptor type");
1564         }
1565
1566         return tcu::StringTemplate(text).specialize(vars);
1567 }
1568
1569 std::string CommonDescriptorInstance::getFragmentReturnSource           (const std::string&                                                     colorAccess)
1570 {
1571         return "  FragColor = " + colorAccess + ";\n";
1572 }
1573
1574 std::string CommonDescriptorInstance::getFragmentLoopSource                     (const std::string&                                                     colorAccess1,
1575                                                                                                                                          const std::string&                                                     colorAccess2)
1576 {
1577         std::map < std::string, std::string > vars;
1578         vars["COLOR_ACCESS_1"] = colorAccess1;
1579         vars["COLOR_ACCESS_2"] = colorAccess2;
1580
1581         const char* s =
1582                 "  vec4 sumClr1 = vec4(0,0,0,0);                \n"
1583                 "  vec4 sumClr2 = vec4(0,0,0,0);                \n"
1584                 "  for (int i = pc.lowerBound; i < pc.upperBound; ++i)  \n"
1585                 "  {\n"
1586                 "    int loopIdx = texelFetch(iter, i).x;                               \n"
1587                 "    sumClr1 += ${COLOR_ACCESS_2} + ${COLOR_ACCESS_1};  \n"
1588                 "    sumClr2 += ${COLOR_ACCESS_2};                                              \n"
1589                 "  }\n"
1590                 "  FragColor = vec4(((sumClr1 - sumClr2) / float(pc.upperBound - pc.lowerBound)).rgb, 1);       \n";
1591
1592         return tcu::StringTemplate(s).specialize(vars);
1593 }
1594
1595 bool CommonDescriptorInstance::performWritesInVertex                            (VkDescriptorType                                                       descriptorType)
1596 {
1597         bool result = false;
1598
1599         switch (descriptorType)
1600         {
1601         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1602         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1603         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1604                 result = true;
1605                 break;
1606         default:
1607                 result = false;
1608                 break;
1609         }
1610
1611         return result;
1612 }
1613
1614 std::string CommonDescriptorInstance::getShaderSource                           (VkShaderStageFlagBits                                          shaderType,
1615                                                                                                                                          const TestCaseParams&                                          testCaseParams,
1616                                                                                                                                          bool                                                                           allowVertexStoring)
1617 {
1618         std::stringstream       s;
1619
1620         s << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << '\n';
1621         s << "#extension GL_EXT_nonuniform_qualifier : require  \n";
1622
1623         if (testCaseParams.calculateInLoop)
1624         {
1625                 s << "layout(push_constant)     uniform Block { int lowerBound, upperBound; } pc;\n";
1626                 s << substBinding(BINDING_DescriptorEnumerator,
1627                         "layout(set=1,binding=${?}) uniform isamplerBuffer iter;        \n");
1628         }
1629
1630         switch (testCaseParams.descriptorType)
1631         {
1632                 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1633                         s << substBinding(BINDING_StorageBuffer,
1634                                 "layout(set=0,binding=${?}) buffer Data { vec4 cnew, cold; } data[]; \n");
1635                         break;
1636                 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1637                         s << substBinding(BINDING_StorageBufferDynamic,
1638                                 "layout(set=0,binding=${?}) buffer Data { vec4 cnew, cold; } data[]; \n");
1639                         break;
1640                 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1641                         s << substBinding(BINDING_UniformBuffer,
1642                                 "layout(set=0,binding=${?}) uniform Data { vec4 c; } data[]; \n");
1643                         break;
1644                 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1645                         s << substBinding(BINDING_UniformBufferDynamic,
1646                                 "layout(set=0,binding=${?}) uniform Data { vec4 c; } data[]; \n");
1647                         break;
1648                 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1649                         s << substBinding(BINDING_StorageTexelBuffer,
1650                                 "layout(set=0,binding=${?},rgba32f) uniform imageBuffer data[];\n");
1651                         break;
1652                 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1653                         s << "#extension GL_EXT_texture_buffer : require        \n";
1654                         s << substBinding(BINDING_UniformTexelBuffer,
1655                                 "layout(set=0,binding=${?}) uniform samplerBuffer data[];\n");
1656                         break;
1657                 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1658                         // Left for the consistent of code.
1659                         // Header is set one swicth below
1660                         break;
1661                 case VK_DESCRIPTOR_TYPE_SAMPLER:
1662                         s << "#extension GL_EXT_texture_buffer : require        \n";
1663                         s << substBinding(BINDING_SampledImage,
1664                                 "layout(set=0,binding=${?}) uniform texture2D ${VAR}[${*}];\n", 1, "tex");
1665                         s << substBinding(BINDING_Sampler,
1666                                 "layout(set=0,binding=${?}) uniform sampler ${VAR}[${*}];\n");
1667                         break;
1668                 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1669                         s << "#extension GL_EXT_texture_buffer : require        \n";
1670                         s << substBinding(BINDING_Sampler,
1671                                 "layout(set=0,binding=${?}) uniform sampler ${VAR}[${*}];\n", 1, "samp");
1672                         s << substBinding(BINDING_SampledImage,
1673                                 "layout(set=0,binding=${?}) uniform texture2D ${VAR}[${*}];\n");
1674                         break;
1675                 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1676                         s << "#extension GL_EXT_texture_buffer : require        \n";
1677                         s << substBinding(BINDING_CombinedImageSampler,
1678                                 "layout(set=0,binding=${?}) uniform sampler2D data[];\n");
1679                         break;
1680                 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1681                         s << "layout(local_size_x=1,local_size_y=1,local_size_z=1) in;  \n";
1682                         s << substBinding(BINDING_StorageImage + 1,
1683                                 "layout(r32ui,set=0,binding=${?}) uniform uimage2D idxs;        \n");
1684                         s << substBinding(BINDING_StorageImage,
1685                                 "layout(r32ui,set=0,binding=${?}) uniform uimage2D data[];      \n");
1686                         break;
1687                 default:
1688                         TCU_THROW(InternalError, "Not implemented descriptor type");
1689         }
1690
1691         switch (shaderType)
1692         {
1693                 case VK_SHADER_STAGE_VERTEX_BIT:        s << getVertexShaderProlog();   break;
1694                 case VK_SHADER_STAGE_FRAGMENT_BIT:
1695                         {
1696                                 if (testCaseParams.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)
1697                                 {
1698                                         s << substBinding(BINDING_InputAttachment,
1699                                                 "layout(input_attachment_index=1,set=0,binding=${?}) uniform subpassInput data[];       \n");
1700                                 }
1701                                 s << getFragmentShaderProlog();
1702                         }
1703                         break;
1704                 case VK_SHADER_STAGE_COMPUTE_BIT:
1705                         break;
1706                 default:
1707                         TCU_THROW(InternalError, "Not implemented shader stage");
1708         }
1709
1710         switch (shaderType)
1711         {
1712                 case VK_SHADER_STAGE_VERTEX_BIT:
1713                 {
1714                         switch (testCaseParams.descriptorType)
1715                         {
1716                         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1717                         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1718                                 if (allowVertexStoring)
1719                                         s << "  if (gIndex != 0) data[nonuniformEXT(gIndex)].cnew = data[nonuniformEXT(rIndex)].cold;   \n";
1720                                 break;
1721                         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1722                                 if (allowVertexStoring)
1723                                         s << "  if (gIndex != 0) imageStore(data[nonuniformEXT(gIndex)], 1, imageLoad(data[nonuniformEXT(rIndex)], 0)); \n";
1724                                 break;
1725                         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1726                         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1727                         case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1728                         case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1729                         case VK_DESCRIPTOR_TYPE_SAMPLER:
1730                         case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1731                         case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1732                                 break;
1733
1734                         default:
1735                                 TCU_THROW(InternalError, "Not implemented descriptor type");
1736                         }
1737                 }
1738                 break;
1739
1740                 case VK_SHADER_STAGE_FRAGMENT_BIT:
1741                 {
1742                         switch (testCaseParams.descriptorType)
1743                         {
1744                         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1745                         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1746                         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1747                                 {
1748                                         if (testCaseParams.calculateInLoop)
1749                                                 s << getFragmentLoopSource(
1750                                                         getColorAccess(testCaseParams.descriptorType, "rIndex", false),
1751                                                         getColorAccess(testCaseParams.descriptorType, "loopIdx", false));
1752                                         else
1753                                                 s << getFragmentReturnSource(getColorAccess(testCaseParams.descriptorType, "rIndex", false));
1754                                 }
1755                                 break;
1756                         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1757                         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1758                         case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1759                         case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1760                         case VK_DESCRIPTOR_TYPE_SAMPLER:
1761                         case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1762                         case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1763                                 if (testCaseParams.calculateInLoop)
1764                                         s << getFragmentLoopSource(
1765                                                 getColorAccess(testCaseParams.descriptorType, "rIndex", testCaseParams.usesMipMaps),
1766                                                 getColorAccess(testCaseParams.descriptorType, "loopIdx", testCaseParams.usesMipMaps));
1767                                 else
1768                                         s << getFragmentReturnSource(getColorAccess(testCaseParams.descriptorType, "rIndex", testCaseParams.usesMipMaps));
1769                                 break;
1770                         default:        TCU_THROW(InternalError, "Not implemented descriptor type");
1771                         }
1772                 }
1773                 break;
1774
1775                 case VK_SHADER_STAGE_COMPUTE_BIT: // VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
1776                         s << "void main(void)\n{\n";
1777                         if (testCaseParams.calculateInLoop)
1778                                 s << "  for (int i = pc.lowerBound; i < pc.upperBound; ++i)     \n"
1779                                         "    imageAtomicAdd(data[nonuniformEXT(texelFetch(iter, i).x)], ivec2(0, 0), 1);                        \n";
1780                         else
1781                                 s << "  uvec4 c = imageLoad(idxs, ivec2(gl_WorkGroupID.x, gl_WorkGroupID.y));   \n"
1782                                         "  imageAtomicAdd( data[nonuniformEXT(c.r)], ivec2(0, 0), 1);                                                           \n";
1783                         break;
1784
1785                 default:        TCU_THROW(InternalError, "Not implemented shader stage");
1786         }
1787
1788         s << getShaderEpilog();
1789
1790         return s.str();
1791 }
1792
1793 class StorageBufferInstance : virtual public CommonDescriptorInstance
1794 {
1795 public:
1796                                                                 StorageBufferInstance                           (Context&                                                                       context,
1797                                                                                                                                          const TestCaseParams&                                          testCaseParams);
1798 protected:
1799         virtual void                            createAndPopulateDescriptors            (IterateCommonVariables&                                        variables);
1800
1801         virtual bool                            verifyVertexWriteResults                        (IterateCommonVariables&                                        variables);
1802 };
1803
1804 StorageBufferInstance::StorageBufferInstance                                            (Context&                                                                       context,
1805                                                                                                                                          const TestCaseParams&                                          testCaseParams)
1806         : CommonDescriptorInstance(context,
1807                 TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
1808                         VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1809                         BINDING_StorageBuffer,
1810                         VK_DESCRIPTOR_TYPE_UNDEFINED,
1811                         BINDING_Undefined,
1812                         false,
1813                         performWritesInVertex(testCaseParams.descriptorType),
1814                         testCaseParams))
1815 {
1816         ut::DeviceProperties dp(context);
1817
1818         checkIndexingAvailable(dp);
1819
1820         const vk::VkPhysicalDeviceDescriptorIndexingFeaturesEXT&        feats = dp.descriptorIndexingFeatures();
1821
1822         if (!(feats.shaderStorageBufferArrayNonUniformIndexing))
1823                 TCU_THROW(NotSupportedError, "Non-uniform indexing over storage buffer descriptor arrays is not supported.");
1824
1825         if (m_testParams.updateAfterBind)
1826         {
1827                 if (!(feats.descriptorBindingStorageBufferUpdateAfterBind))
1828                         TCU_THROW(NotSupportedError, "Update after bind for storage buffer descriptors is not supported.");
1829         }
1830 }
1831
1832 void StorageBufferInstance::createAndPopulateDescriptors                        (IterateCommonVariables&                                        variables)
1833 {
1834         BindingStorageBuffer::Data      data;
1835
1836         bool                                            vertexStores = false;
1837         {
1838                 ut::DeviceProperties dp(m_context);
1839                 vertexStores = dp.physicalDeviceFeatures().vertexPipelineStoresAndAtomics != DE_FALSE;
1840         }
1841         const deUint32                          alignment       = static_cast<deUint32>(ut::DeviceProperties(m_context).physicalDeviceProperties().limits.minStorageBufferOffsetAlignment);
1842         createBuffers(variables.descriptorsBufferInfos, variables.descriptorsBuffer, variables.validDescriptorCount, sizeof(data), alignment, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1843
1844         unsigned char*                          buffer          = static_cast<unsigned char*>(variables.descriptorsBuffer->alloc->getHostPtr());
1845         for (deUint32 infoIdx = 0; infoIdx < variables.validDescriptorCount; ++infoIdx)
1846         {
1847                 const float                             component       = m_colorScheme[infoIdx % m_schemeSize];
1848                 const tcu::Vec4                 color           (component, component, component, 1.0f);
1849                 VkDescriptorBufferInfo& info            = variables.descriptorsBufferInfos[infoIdx];
1850                 data.cnew                                                       = vertexStores ? m_clearColor : color;
1851                 data.cold                                                       = color;
1852
1853                 deMemcpy(buffer + info.offset, &data, sizeof(data));
1854         }
1855         vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
1856
1857         variables.dataAlignment = deAlign64(sizeof(data), alignment);
1858 }
1859
1860 bool StorageBufferInstance::verifyVertexWriteResults                            (IterateCommonVariables&                                        variables)
1861 {
1862         const tcu::Vec4                         threshold               (0.002f, 0.002f, 0.002f, 0.002f);
1863         const std::vector<deUint32>     primes                  = ut::generatePrimes(variables.availableDescriptorCount);
1864
1865         unsigned char*                          buffer = static_cast<unsigned char*>(variables.descriptorsBuffer->alloc->getHostPtr());
1866         BindingStorageBuffer::Data      data;
1867         for (deUint32 primeIdx = 0; primeIdx < variables.validDescriptorCount; ++primeIdx)
1868         {
1869                 const deUint32                  prime           = primes[primeIdx];
1870                 const float                             component       = m_colorScheme[(prime % variables.validDescriptorCount) % m_schemeSize];
1871                 const tcu::Vec4                 referenceValue(component, component, component, 1.0f);
1872
1873                 VkDescriptorBufferInfo& info = variables.descriptorsBufferInfos[primeIdx];
1874                 deMemcpy(&data, buffer + info.offset, sizeof(data));
1875                 const tcu::Vec4                 realValue = data.cnew;
1876
1877                 const tcu::Vec4                 diff = tcu::absDiff(referenceValue, realValue);
1878                 if (!tcu::boolAll(tcu::lessThanEqual(diff, threshold)))
1879                         return false;
1880         }
1881         return true;
1882 }
1883
1884 class UniformBufferInstance : virtual public CommonDescriptorInstance
1885 {
1886 public:
1887                                                                 UniformBufferInstance                           (Context&                                                                       context,
1888                                                                                                                                          const TestCaseParams&                                          testCaseParams);
1889 protected:
1890         virtual void                            createAndPopulateDescriptors            (IterateCommonVariables&                                        variables);
1891 };
1892
1893 UniformBufferInstance::UniformBufferInstance                                            (Context&                                                                       context,
1894                                                                                                                                          const TestCaseParams&                                          testCaseParams)
1895         : CommonDescriptorInstance(context,
1896                 TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
1897                         VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1898                         BINDING_UniformBuffer,
1899                         VK_DESCRIPTOR_TYPE_UNDEFINED,
1900                         BINDING_Undefined,
1901                         false,
1902                         performWritesInVertex(testCaseParams.descriptorType),
1903                         testCaseParams))
1904 {
1905         ut::DeviceProperties dp(context);
1906
1907         checkIndexingAvailable(dp);
1908
1909         const VkPhysicalDeviceDescriptorIndexingFeaturesEXT&    feats = dp.descriptorIndexingFeatures();
1910
1911         if (!(feats.shaderUniformBufferArrayNonUniformIndexing))
1912                 TCU_THROW(NotSupportedError, "Non-uniform indexing for uniform buffer descriptor arrays is not supported.");
1913
1914         if (m_testParams.updateAfterBind)
1915         {
1916                 if (!(feats.descriptorBindingUniformBufferUpdateAfterBind))
1917                         TCU_THROW(NotSupportedError, "Update after bind for uniform buffer descriptors is not supported.");
1918         }
1919 }
1920
1921 void UniformBufferInstance::createAndPopulateDescriptors                        (IterateCommonVariables&                                        variables)
1922 {
1923         BindingUniformBuffer::Data data;
1924
1925         const deUint32                          alignment       = static_cast<deUint32>(ut::DeviceProperties(m_context).physicalDeviceProperties().limits.minUniformBufferOffsetAlignment);
1926         createBuffers(variables.descriptorsBufferInfos, variables.descriptorsBuffer, variables.validDescriptorCount, sizeof(data), alignment, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
1927
1928         unsigned char*                          buffer          = static_cast<unsigned char*>(variables.descriptorsBuffer->alloc->getHostPtr());
1929         for (deUint32 infoIdx = 0; infoIdx < variables.validDescriptorCount; ++infoIdx)
1930         {
1931                 const float                             component       = m_colorScheme[infoIdx % m_schemeSize];
1932                 VkDescriptorBufferInfo& info            = variables.descriptorsBufferInfos[infoIdx];
1933                 data.c                                                          = tcu::Vec4(component, component, component, 1.0f);
1934                 deMemcpy(buffer + info.offset, &data, sizeof(data));
1935         }
1936         vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
1937
1938         variables.dataAlignment = deAlign64(sizeof(data), alignment);
1939 }
1940
1941 class StorageTexelInstance : public CommonDescriptorInstance
1942 {
1943 public:
1944                                                                 StorageTexelInstance                            (Context&                                                                       context,
1945                                                                                                                                          const TestCaseParams&                                          testCaseParams);
1946 private:
1947         virtual void                            createAndPopulateDescriptors            (IterateCommonVariables&                                        variables);
1948
1949         virtual bool                            verifyVertexWriteResults                        (IterateCommonVariables&                                        variables);
1950 };
1951
1952 StorageTexelInstance::StorageTexelInstance                                                      (Context&                                                                       context,
1953                                                                                                                                          const TestCaseParams&                                          testCaseParams)
1954         : CommonDescriptorInstance(context,
1955                 TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
1956                         VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
1957                         BINDING_StorageTexelBuffer,
1958                         VK_DESCRIPTOR_TYPE_UNDEFINED,
1959                         BINDING_Undefined,
1960                         false,
1961                         performWritesInVertex(testCaseParams.descriptorType),
1962                         testCaseParams))
1963 {
1964         ut::DeviceProperties dp(context);
1965
1966         checkIndexingAvailable(dp);
1967
1968         const VkPhysicalDeviceDescriptorIndexingFeaturesEXT&    feats = dp.descriptorIndexingFeatures();
1969
1970         if (!(feats.shaderStorageTexelBufferArrayNonUniformIndexing))
1971                 TCU_THROW(NotSupportedError, "Non-uniform indexing for storage texel buffer descriptor arrays is not supported.");
1972
1973         if (m_testParams.updateAfterBind)
1974         {
1975                 if (!(feats.descriptorBindingStorageTexelBufferUpdateAfterBind))
1976                         TCU_THROW(NotSupportedError, "Update after bind for storage texel buffer descriptors is not supported.");
1977         }
1978 }
1979
1980 void StorageTexelInstance::createAndPopulateDescriptors                 (IterateCommonVariables&                                        variables)
1981 {
1982         const VkExtent3D                        imageExtent                     = { 4, 4, 1 };
1983         const deUint32                          imageSize                       = ut::computeImageSize(imageExtent, m_colorFormat);
1984
1985         createBuffers(variables.descriptorsBufferInfos, variables.descriptorsBuffer, variables.validDescriptorCount, imageSize, sizeof(tcu::Vec4), VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT);
1986         createBuffersViews(variables.descriptorsBufferViews, variables.descriptorsBufferInfos, m_colorFormat);
1987
1988         for (deUint32 imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
1989         {
1990                 const float                             component                       = m_colorScheme[imageIdx % m_schemeSize];
1991                 const PixelBufferAccess pa                                      = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer);
1992
1993                 tcu::clear(pa, m_clearColor);
1994                 pa.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
1995         }
1996         vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
1997 }
1998
1999 bool StorageTexelInstance::verifyVertexWriteResults(IterateCommonVariables&                                     variables)
2000 {
2001         const VkExtent3D                        imageExtent             = { 4, 4, 1 };
2002         const tcu::Vec4                         threshold               (0.002f, 0.002f, 0.002f, 0.002f);
2003         const std::vector<deUint32>     primes                  = ut::generatePrimes(variables.availableDescriptorCount);
2004
2005         for (deUint32 primeIdx = 0; primeIdx < variables.validDescriptorCount; ++primeIdx)
2006         {
2007                 const deUint32                  prime           = primes[primeIdx];
2008                 const float                             component       = m_colorScheme[( prime % variables.validDescriptorCount ) % m_schemeSize];
2009                 const tcu::Vec4                 referenceValue(component, component, component, 1.0f);
2010
2011                 const PixelBufferAccess pa                      = getPixelAccess(primeIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer);
2012                 const tcu::Vec4                 realValue       = pa.getPixel(1, 0);
2013
2014                 const tcu::Vec4                 diff            = tcu::absDiff(referenceValue, realValue);
2015                 if (!tcu::boolAll(tcu::lessThanEqual(diff, threshold)))
2016                         return false;
2017         }
2018         return true;
2019 }
2020
2021 class UniformTexelInstance : public CommonDescriptorInstance
2022 {
2023 public:
2024                                                                 UniformTexelInstance                            (Context&                                                                       context,
2025                                                                                                                                          const TestCaseParams&                                          testCaseParams);
2026 private:
2027         virtual void                            createAndPopulateDescriptors            (IterateCommonVariables&                                        variables);
2028 };
2029
2030 UniformTexelInstance::UniformTexelInstance                                                      (Context&                                                                       context,
2031                                                                                                                                          const TestCaseParams&                                          testCaseParams)
2032         : CommonDescriptorInstance(context,
2033                 TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
2034                         VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
2035                         BINDING_UniformTexelBuffer,
2036                         VK_DESCRIPTOR_TYPE_UNDEFINED,
2037                         BINDING_Undefined,
2038                         false,
2039                         performWritesInVertex(testCaseParams.descriptorType),
2040                         testCaseParams))
2041 {
2042         ut::DeviceProperties dp(context);
2043
2044         checkIndexingAvailable(dp);
2045
2046         const VkPhysicalDeviceDescriptorIndexingFeaturesEXT&    feats = dp.descriptorIndexingFeatures();
2047
2048         if (!(feats.shaderUniformTexelBufferArrayNonUniformIndexing))
2049                 TCU_THROW(NotSupportedError, "Non-uniform indexing for uniform texel buffer descriptor arrays is not supported.");
2050
2051         if (m_testParams.updateAfterBind)
2052         {
2053                 if (!(feats.descriptorBindingUniformTexelBufferUpdateAfterBind))
2054                         TCU_THROW(NotSupportedError, "Update after bind for uniform texel buffer descriptors is not supported.");
2055         }
2056 }
2057
2058 void UniformTexelInstance::createAndPopulateDescriptors                         (IterateCommonVariables&                                        variables)
2059 {
2060         const VkExtent3D                        imageExtent     = { 4, 4, 1 };
2061         const deUint32                          imageSize       = ut::computeImageSize(imageExtent, m_colorFormat);
2062
2063         createBuffers(variables.descriptorsBufferInfos, variables.descriptorsBuffer, variables.validDescriptorCount, imageSize, sizeof(tcu::Vec4), VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT);
2064         createBuffersViews(variables.descriptorsBufferViews, variables.descriptorsBufferInfos, m_colorFormat);
2065
2066         for (deUint32 imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
2067         {
2068                 const float                             component       = m_colorScheme[imageIdx % m_schemeSize];
2069                 const PixelBufferAccess pa                      = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer);
2070
2071                 tcu::clear(pa, tcu::Vec4(component, component, component, 1.0f));
2072         }
2073         vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
2074 }
2075
2076 class DynamicBuffersInstance : virtual public CommonDescriptorInstance
2077 {
2078 public:
2079         DynamicBuffersInstance                                                                                  (Context&                                                                       context,
2080                                                                                                                                          const TestParams&                                                      testParams)
2081                 : CommonDescriptorInstance(context, testParams) {}
2082
2083 protected:
2084         virtual tcu::TestStatus         iterate                                                         (void);
2085         virtual void                            updateDescriptors                                       (IterateCommonVariables&                                        variables);
2086 };
2087
2088 void DynamicBuffersInstance::updateDescriptors                                          (IterateCommonVariables&                                        variables)
2089 {
2090         DE_ASSERT(variables.dataAlignment);
2091
2092         VkDescriptorBufferInfo  bufferInfo =
2093         {
2094                 *variables.descriptorsBuffer.get()->buffer,
2095                 0,      // always 0, it will be taken from pDynamicOffsets
2096                 variables.dataAlignment
2097         };
2098
2099         VkWriteDescriptorSet updateInfo =
2100         {
2101                 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,                 // sType
2102                 DE_NULL,                                                                                // pNext
2103                 *variables.descriptorSet,                                               // descriptorSet
2104                 m_testParams.descriptorBinding,                                 // descriptorBinding;
2105                 0,      // to be set in below loop                                      // dstArrayElement
2106                 1u,                                                                                             // descriptorCount
2107                 m_testParams.descriptorType,                                    // descriptorType
2108                 DE_NULL,                                                                                // pImageInfo
2109                 &bufferInfo,                                                                    // pBufferInfo
2110                 DE_NULL                                                                                 // pTexelBufferView
2111         };
2112
2113         deUint32 descIdx = 0;
2114         const std::vector<deUint32> primes = ut::generatePrimes(variables.availableDescriptorCount);
2115         for (deUint32 validIdx = 0; validIdx < variables.validDescriptorCount; ++validIdx)
2116         {
2117                 for (; descIdx < primes[validIdx]; ++descIdx)
2118                 {
2119                         updateInfo.dstArrayElement                      = descIdx;
2120                         m_vki.updateDescriptorSets      (m_vkd, 1u, &updateInfo, 0u, DE_NULL);
2121                 }
2122
2123                 updateInfo.dstArrayElement                              = primes[validIdx];
2124                 m_vki.updateDescriptorSets              (m_vkd, 1u, &updateInfo, 0u, DE_NULL);
2125
2126                 ++descIdx;
2127         }
2128         for (; descIdx < variables.availableDescriptorCount; ++descIdx)
2129         {
2130                 updateInfo.dstArrayElement = descIdx;
2131                 m_vki.updateDescriptorSets(m_vkd, 1u, &updateInfo, 0u, DE_NULL);
2132         }
2133 }
2134
2135 tcu::TestStatus DynamicBuffersInstance::iterate                                         (void)
2136 {
2137         IterateCommonVariables  v;
2138         iterateCommandBegin             (v);
2139
2140         DE_ASSERT(v.dataAlignment);
2141
2142         std::vector<deUint32> dynamicOffsets;
2143
2144         deUint32 descIdx = 0;
2145         const std::vector<deUint32> primes = ut::generatePrimes(v.availableDescriptorCount);
2146         for (deUint32 validIdx = 0; validIdx < v.validDescriptorCount; ++validIdx)
2147         {
2148                 for (; descIdx < primes[validIdx]; ++descIdx)
2149                 {
2150                         dynamicOffsets.push_back(0);
2151                 }
2152
2153                 dynamicOffsets.push_back(static_cast<deUint32>(validIdx * v.dataAlignment));
2154
2155                 ++descIdx;
2156         }
2157         for (; descIdx < v.availableDescriptorCount; ++descIdx)
2158         {
2159                 dynamicOffsets.push_back(0);
2160         }
2161
2162         // Unfortunatelly not lees and not more, only exactly
2163         DE_ASSERT(dynamicOffsets.size() == v.availableDescriptorCount);
2164
2165         const VkDescriptorSet   descriptorSets[] = { *v.descriptorSet };
2166
2167         m_vki.cmdBindDescriptorSets(
2168                 *v.commandBuffer,                                               // commandBuffer
2169                 VK_PIPELINE_BIND_POINT_GRAPHICS,                // pipelineBindPoint
2170                 *v.pipelineLayout,                                              // layout
2171                 0u,                                                                             // firstSet
2172                 DE_LENGTH_OF_ARRAY(descriptorSets),             // descriptorSetCount
2173                 descriptorSets,                                                 // pDescriptorSets
2174                 v.availableDescriptorCount,                             // dynamicOffsetCount
2175                 dynamicOffsets.data());                                 // pDynamicOffsets
2176
2177         vk::beginRenderPass     (m_vki, *v.commandBuffer, *v.renderPass, *v.frameBuffer->buffer, v.renderArea, m_clearColor);
2178         m_vki.cmdDraw           (*v.commandBuffer, v.vertexCount, 1, 0, 0);
2179         vk::endRenderPass       (m_vki, *v.commandBuffer);
2180
2181         return (iterateCommandEnd(v) ? tcu::TestStatus::pass : tcu::TestStatus::fail)("");
2182 }
2183
2184 class DynamicStorageBufferInstance : public DynamicBuffersInstance, public StorageBufferInstance
2185 {
2186 public:
2187         DynamicStorageBufferInstance                                                                    (Context&                                       context,
2188                                                                                                                                          const TestCaseParams&          testCaseParams);
2189         tcu::TestStatus         iterate                                                                         (void);
2190         void                            createAndPopulateDescriptors                            (IterateCommonVariables&        variables);
2191         void                            updateDescriptors                                                       (IterateCommonVariables&        variables);
2192         bool                            verifyVertexWriteResults                                        (IterateCommonVariables&        variables);
2193 };
2194
2195 DynamicStorageBufferInstance::DynamicStorageBufferInstance                      (Context&                                       context,
2196                                                                                                                                          const TestCaseParams&          testCaseParams)
2197         : CommonDescriptorInstance(context,
2198                 TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
2199                         VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC,
2200                         BINDING_StorageBufferDynamic,
2201                         VK_DESCRIPTOR_TYPE_UNDEFINED,
2202                         BINDING_Undefined,
2203                         false,
2204                         performWritesInVertex(testCaseParams.descriptorType),
2205                         testCaseParams)),
2206                         DynamicBuffersInstance(context, m_testParams), StorageBufferInstance(context, testCaseParams)
2207 {
2208         ut::DeviceProperties dp(context);
2209
2210         checkIndexingAvailable(dp);
2211
2212         const VkPhysicalDeviceDescriptorIndexingFeaturesEXT&    feats = dp.descriptorIndexingFeatures();
2213
2214         if (!(feats.shaderStorageBufferArrayNonUniformIndexing))
2215                 TCU_THROW(NotSupportedError, "Non-uniform indexing over storage buffer dynamic descriptor arrays is not supported.");
2216
2217         if (testCaseParams.updateAfterBind)
2218         {
2219                 TCU_THROW(NotSupportedError, "Update after bind for storage buffer dynamic descriptors is not supported.");
2220         }
2221 }
2222
2223 tcu::TestStatus DynamicStorageBufferInstance::iterate(void)
2224 {
2225         return DynamicBuffersInstance::iterate();
2226 }
2227
2228 void DynamicStorageBufferInstance::createAndPopulateDescriptors(IterateCommonVariables&                 variables)
2229 {
2230         StorageBufferInstance::createAndPopulateDescriptors(variables);
2231 }
2232
2233 void DynamicStorageBufferInstance::updateDescriptors(IterateCommonVariables&                                    variables)
2234 {
2235         DynamicBuffersInstance::updateDescriptors(variables);
2236 }
2237
2238 bool DynamicStorageBufferInstance::verifyVertexWriteResults(IterateCommonVariables&                             variables)
2239 {
2240         return StorageBufferInstance::verifyVertexWriteResults(variables);
2241 }
2242
2243 class DynamicUniformBufferInstance : public DynamicBuffersInstance, public UniformBufferInstance
2244 {
2245 public:
2246         DynamicUniformBufferInstance                                                                    (Context&                                       context,
2247                                                                                                                                          const TestCaseParams&          testCaseParams);
2248         tcu::TestStatus         iterate(void);
2249         void                            createAndPopulateDescriptors(IterateCommonVariables&                                    variables);
2250         void                            updateDescriptors(IterateCommonVariables&                                                               variables);
2251 };
2252
2253 DynamicUniformBufferInstance::DynamicUniformBufferInstance                      (Context&                                       context,
2254                                                                                                                                          const TestCaseParams&          testCaseParams)
2255         : CommonDescriptorInstance(context,
2256                 TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
2257                         VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
2258                         BINDING_UniformBufferDynamic,
2259                         VK_DESCRIPTOR_TYPE_UNDEFINED,
2260                         BINDING_Undefined,
2261                         false,
2262                         performWritesInVertex(testCaseParams.descriptorType),
2263                         testCaseParams)),
2264                         DynamicBuffersInstance(context, m_testParams), UniformBufferInstance(context, testCaseParams)
2265 {
2266         ut::DeviceProperties dp(context);
2267
2268         checkIndexingAvailable(dp);
2269
2270         const VkPhysicalDeviceDescriptorIndexingFeaturesEXT&    feats = dp.descriptorIndexingFeatures();
2271
2272         if (!(feats.shaderUniformBufferArrayNonUniformIndexing))
2273                 TCU_THROW(NotSupportedError, "Non-uniform indexing over uniform buffer dynamic descriptor arrays is not supported.");
2274
2275         if (testCaseParams.updateAfterBind)
2276         {
2277                 TCU_THROW(NotSupportedError, "Update after bind for uniform buffer dynamic descriptors is not supported.");
2278         }
2279 }
2280
2281 tcu::TestStatus DynamicUniformBufferInstance::iterate(void)
2282 {
2283         return DynamicBuffersInstance::iterate();
2284 }
2285
2286 void DynamicUniformBufferInstance::createAndPopulateDescriptors(IterateCommonVariables&                 variables)
2287 {
2288         UniformBufferInstance::createAndPopulateDescriptors(variables);
2289 }
2290
2291 void DynamicUniformBufferInstance::updateDescriptors(IterateCommonVariables&                                    variables)
2292 {
2293         DynamicBuffersInstance::updateDescriptors(variables);
2294 }
2295
2296 class InputAttachmentInstance : public CommonDescriptorInstance
2297 {
2298 public:
2299                                                                 InputAttachmentInstance                         (Context&                                                                       context,
2300                                                                                                                                         const TestCaseParams&                                           testCaseParams);
2301 private:
2302         virtual Move<VkRenderPass>      createRenderPass                                        (const IterateCommonVariables&                          variables);
2303         virtual void                            createFramebuffer                                       (ut::FrameBufferSp&                                                     frameBuffer,
2304                                                                                                                                          VkRenderPass                                                           renderPass,
2305                                                                                                                                          const IterateCommonVariables&                          variables);
2306         virtual void                            createAndPopulateDescriptors            (IterateCommonVariables&                                        variables);
2307 };
2308
2309 InputAttachmentInstance::InputAttachmentInstance                                        (Context&                                                                       context,
2310                                                                                                                                          const TestCaseParams&                                          testCaseParams)
2311         : CommonDescriptorInstance(context,
2312                 TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
2313                         VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2314                         BINDING_InputAttachment,
2315                         VK_DESCRIPTOR_TYPE_UNDEFINED,
2316                         BINDING_Undefined,
2317                         true,
2318                         performWritesInVertex(testCaseParams.descriptorType),
2319                         testCaseParams))
2320 {
2321         ut::DeviceProperties dp(context);
2322
2323         checkIndexingAvailable(dp);
2324
2325         const VkPhysicalDeviceDescriptorIndexingFeaturesEXT&    feats = dp.descriptorIndexingFeatures();
2326
2327         if (!(feats.shaderInputAttachmentArrayNonUniformIndexing))
2328                 TCU_THROW(NotSupportedError, "Non-uniform indexing over input attachment descriptor arrays is not supported.");
2329
2330         if (testCaseParams.updateAfterBind)
2331         {
2332                 TCU_THROW(NotSupportedError, "Update after bind for input attachment descriptors is not supported.");
2333         }
2334 }
2335
2336 void InputAttachmentInstance::createAndPopulateDescriptors                      (IterateCommonVariables&                                        variables)
2337 {
2338         createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer,
2339                 (VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT), m_testParams.frameResolution, m_colorFormat, VK_IMAGE_LAYOUT_UNDEFINED, variables.validDescriptorCount);
2340         createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, m_colorFormat);
2341
2342         for (deUint32 descriptorIdx = 0; descriptorIdx < variables.validDescriptorCount; ++descriptorIdx)
2343         {
2344                 const float                                             component       = m_colorScheme[descriptorIdx % m_schemeSize];
2345                 const tcu::PixelBufferAccess    pa                      = getPixelAccess(descriptorIdx, m_testParams.frameResolution, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer);
2346                 tcu::clear(pa, tcu::Vec4(component, component, component, 1.0f));
2347         }
2348 }
2349
2350 Move<VkRenderPass> InputAttachmentInstance::createRenderPass            (const IterateCommonVariables&                          variables)
2351 {
2352         std::vector<VkAttachmentDescription>    attachmentDescriptions;
2353         std::vector<VkAttachmentReference>              inputAttachmentRefs;
2354
2355         const VkAttachmentDescription   colorAttachmentDescription =
2356         {
2357                 (VkAttachmentDescriptionFlags)0,                        // VkAttachmentDescriptionFlags         flags;
2358                 m_colorFormat,                                                          // VkFormat                                                     format;
2359                 VK_SAMPLE_COUNT_1_BIT,                                          // VkSampleCountFlagBits                        samples;
2360                 VK_ATTACHMENT_LOAD_OP_CLEAR,                            // VkAttachmentLoadOp                           loadOp;
2361                 VK_ATTACHMENT_STORE_OP_STORE,                           // VkAttachmentStoreOp                          storeOp;
2362                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                        // VkAttachmentLoadOp                           stencilLoadOp;
2363                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                       // VkAttachmentStoreOp                          stencilStoreOp;
2364                 VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout                                        initialLayout;
2365                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                                        finalLayout;
2366         };
2367         const VkAttachmentReference             colorAttachmentRef =
2368         {
2369                 0u,                                                                                             // deUint32                                                     attachment;
2370                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                // VkImageLayout                                        layout;
2371         };
2372         attachmentDescriptions.push_back(colorAttachmentDescription);
2373
2374         // build input atachments
2375         {
2376                 const deUint32 inputCount = static_cast<deUint32>(variables.descriptorImageViews.size());
2377                 for (deUint32 inputIdx = 0; inputIdx < inputCount; ++inputIdx)
2378                 {
2379                         const VkAttachmentDescription   inputAttachmentDescription =
2380                         {
2381                                 VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT,                // VkAttachmentDescriptionFlags         flags;
2382                                 variables.descriptorsImages[inputIdx]->format,  // VkFormat                                                     format;
2383                                 VK_SAMPLE_COUNT_1_BIT,                                                  // VkSampleCountFlagBits                        samples;
2384                                 VK_ATTACHMENT_LOAD_OP_LOAD,                                             // VkAttachmentLoadOp                           loadOp;
2385                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                               // VkAttachmentStoreOp                          storeOp;
2386                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                // VkAttachmentLoadOp                           stencilLoadOp;
2387                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                               // VkAttachmentStoreOp                          stencilStoreOp;
2388                                 variables.descriptorsImages[inputIdx]->layout,  // VkImageLayout                                        initialLayout;
2389                                 VK_IMAGE_LAYOUT_GENERAL,                                                // VkImageLayout                                        finalLayout;
2390                         };
2391
2392                         const VkAttachmentReference             inputAttachmentRef =
2393                         {
2394                                 inputIdx + 1,                                                           // deUint32                                                     attachment;
2395                                 VK_IMAGE_LAYOUT_GENERAL                                         // VkImageLayout                                        layout;
2396                         };
2397
2398                         inputAttachmentRefs.push_back(inputAttachmentRef);
2399                         attachmentDescriptions.push_back(inputAttachmentDescription);
2400                 }
2401         }
2402
2403         const VkSubpassDescription              subpassDescription =
2404         {
2405                 (VkSubpassDescriptionFlags)0,                                           // VkSubpassDescriptionFlags            flags;
2406                 VK_PIPELINE_BIND_POINT_GRAPHICS,                                        // VkPipelineBindPoint                          pipelineBindPoint;
2407                 static_cast<deUint32>(inputAttachmentRefs.size()),      // deUint32                                                     inputAttachmentCount;
2408                 inputAttachmentRefs.data(),                                                     // const VkAttachmentReference*         pInputAttachments;
2409                 1u,                                                                                                     // deUint32                                                     colorAttachmentCount;
2410                 &colorAttachmentRef,                                                            // const VkAttachmentReference*         pColorAttachments;
2411                 DE_NULL,                                                                                        // const VkAttachmentReference*         pResolveAttachments;
2412                 DE_NULL,                                                                                        // const VkAttachmentReference*         pDepthStencilAttachment;
2413                 0u,                                                                                                     // deUint32                                                     preserveAttachmentCount;
2414                 DE_NULL                                                                                         // const deUint32*                                      pPreserveAttachments;
2415         };
2416
2417         const VkRenderPassCreateInfo    renderPassInfo =
2418         {
2419                 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                              // VkStructureType                                      sType;
2420                 DE_NULL,                                                                                                // const void*                                          pNext;
2421                 (VkRenderPassCreateFlags)0,                                                             // VkRenderPassCreateFlags                      flags;
2422                 static_cast<deUint32>(attachmentDescriptions.size()),   // deUint32                                                     attachmentCount;
2423                 attachmentDescriptions.data(),                                                  // const VkAttachmentDescription*       pAttachments;
2424                 1u,                                                                                                             // deUint32                                                     subpassCount;
2425                 &subpassDescription,                                                                    // const VkSubpassDescription*          pSubpasses;
2426                 0u,                                                                                                             // deUint32                                                     dependencyCount;
2427                 DE_NULL                                                                                                 // const VkSubpassDependency*           pDependencies;
2428         };
2429
2430         return vk::createRenderPass(m_vki, m_vkd, &renderPassInfo);
2431 }
2432
2433 void InputAttachmentInstance::createFramebuffer                                         (ut::FrameBufferSp&                                                     frameBuffer,
2434                                                                                                                                          VkRenderPass                                                           renderPass,
2435                                                                                                                                          const IterateCommonVariables&                          variables)
2436 {
2437         std::vector<VkImageView>                        inputAttachments;
2438         const deUint32 viewCount = static_cast<deUint32>(variables.descriptorImageViews.size());
2439         inputAttachments.resize(viewCount);
2440         for (deUint32 viewIdx = 0; viewIdx < viewCount; ++viewIdx)
2441         {
2442                 inputAttachments[viewIdx] = **variables.descriptorImageViews[viewIdx];
2443         }
2444         ut::createFrameBuffer(frameBuffer, m_context, m_testParams.frameResolution, m_colorFormat, renderPass, viewCount, inputAttachments.data());
2445 }
2446
2447 class SamplerInstance : public CommonDescriptorInstance
2448 {
2449 public:
2450                                                                 SamplerInstance                                         (Context&                                                                       context,
2451                                                                                                                                          const TestCaseParams&                                          testCaseParams);
2452 private:
2453         virtual void                            createAndPopulateDescriptors            (IterateCommonVariables&                                        variables);
2454         virtual void                            updateDescriptors                                       (IterateCommonVariables&                                        variables);
2455 };
2456
2457 SamplerInstance::SamplerInstance                                                                        (Context&                                                                       context,
2458                                                                                                                                          const TestCaseParams&                                          testCaseParams)
2459         : CommonDescriptorInstance(context,
2460                 TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
2461                         VK_DESCRIPTOR_TYPE_SAMPLER,
2462                         BINDING_Sampler,
2463                         VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
2464                         BINDING_SampledImage,
2465                         true,
2466                         performWritesInVertex(testCaseParams.descriptorType),
2467                         testCaseParams))
2468 {
2469         ut::DeviceProperties dp(context);
2470
2471         checkIndexingAvailable(dp);
2472
2473         const VkPhysicalDeviceDescriptorIndexingFeaturesEXT&    feats = dp.descriptorIndexingFeatures();
2474         // Note: common flags for SAMPLER, SAMPLED_IMAGE, COMBINED_IMAGE_SAMPLER
2475
2476         if (!(feats.shaderSampledImageArrayNonUniformIndexing))
2477                 TCU_THROW(NotSupportedError, "Non-uniform indexing over sampler descriptor arrays is not supported.");
2478
2479         if (testCaseParams.updateAfterBind)
2480         {
2481                 if (!(feats.descriptorBindingSampledImageUpdateAfterBind))
2482                         TCU_THROW(NotSupportedError, "Update after bind for sampler descriptors is not supported.");
2483         }
2484 }
2485
2486 void SamplerInstance::updateDescriptors                                                         (IterateCommonVariables&                                        variables)
2487 {
2488         DE_ASSERT(variables.descriptorsImages.size()            == 1);
2489         DE_ASSERT(variables.descriptorImageViews.size()         == 1);
2490         DE_ASSERT(variables.descriptorsBufferInfos.size()       == 1);
2491         DE_ASSERT(m_testParams.additionalDescriptorType         == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
2492         DE_ASSERT(variables.descriptorSamplers.size()           == variables.validDescriptorCount);
2493
2494         // update an image
2495         {
2496                 const VkDescriptorImageInfo imageInfo =
2497                 {
2498                         static_cast<VkSampler>(0),
2499                         **variables.descriptorImageViews[0],
2500                         VK_IMAGE_LAYOUT_GENERAL
2501                 };
2502
2503                 const VkWriteDescriptorSet writeInfo =
2504                 {
2505                         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,                 // sType
2506                         DE_NULL,                                                                                // pNext
2507                         *variables.descriptorSet,                                               // descriptorSet
2508                         BINDING_SampledImage,                                                   // descriptorBinding;
2509                         0,                                                                                              // elementIndex
2510                         1u,                                                                                             // descriptorCount
2511                         VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,                               // descriptorType
2512                         &imageInfo,                                                                             // pImageInfo
2513                         DE_NULL,                                                                                // pBufferInfo
2514                         DE_NULL                                                                                 // pTexelBufferView
2515                 };
2516
2517                 m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, DE_NULL);
2518         }
2519
2520         // update samplers
2521         CommonDescriptorInstance::updateDescriptors(variables);
2522 }
2523
2524 void SamplerInstance::createAndPopulateDescriptors                                      (IterateCommonVariables&                                        variables)
2525 {
2526         DE_ASSERT(variables.descriptorsImages.size()            == 0);
2527         DE_ASSERT(variables.descriptorImageViews.size()         == 0);
2528         DE_ASSERT(variables.descriptorsBufferInfos.size()       == 0);
2529         DE_ASSERT(variables.descriptorSamplers.size()           == 0);
2530
2531         // create and populate an image
2532         {
2533                 VkExtent3D imageExtent = m_testParams.frameResolution;
2534                 if (m_testParams.usesMipMaps)
2535                 {
2536                         imageExtent.width *= 2;
2537                         imageExtent.height *= 2;
2538                 };
2539
2540                 createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer,
2541                         (VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT), imageExtent, m_colorFormat, VK_IMAGE_LAYOUT_UNDEFINED, 1, m_testParams.usesMipMaps);
2542                 createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, m_colorFormat);
2543
2544                 PixelBufferAccess pa = getPixelAccess(0, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, m_testParams.usesMipMaps ? 1 : 0);
2545
2546                 for (deUint32 y = 0, pixelNum = 0; y < m_testParams.frameResolution.height; ++y)
2547                 {
2548                         for (deUint32 x = 0; x < m_testParams.frameResolution.width; ++x, ++pixelNum)
2549                         {
2550                                 const float             component       = m_colorScheme[(pixelNum % variables.validDescriptorCount) % m_schemeSize];
2551                                 pa.setPixel(tcu::Vec4(component, component, component, 1.0f), x, y);
2552                         }
2553                 }
2554
2555                 vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
2556         }
2557
2558         const tcu::Sampler sampler(
2559                 tcu::Sampler::CLAMP_TO_BORDER,                                                                                                                  // wrapS
2560                 tcu::Sampler::CLAMP_TO_BORDER,                                                                                                                  // wrapT
2561                 tcu::Sampler::CLAMP_TO_BORDER,                                                                                                                  // wrapR
2562                 m_testParams.usesMipMaps ? tcu::Sampler::LINEAR_MIPMAP_NEAREST : tcu::Sampler::NEAREST, // minFilter
2563                 m_testParams.usesMipMaps ? tcu::Sampler::LINEAR_MIPMAP_NEAREST : tcu::Sampler::NEAREST, // magFilter
2564                 0.0f,                                                                                                                                                                   // lodTreshold
2565                 true);                                                                                                                                                                  // normalizeCoords
2566         const VkSamplerCreateInfo createInfo = vk::mapSampler(sampler, vk::mapVkFormat(m_colorFormat));
2567         variables.descriptorSamplers.resize(variables.validDescriptorCount);
2568
2569         for (deUint32 samplerIdx = 0; samplerIdx < variables.validDescriptorCount; ++samplerIdx)
2570         {
2571                 variables.descriptorSamplers[samplerIdx] = ut::SamplerSp(new Move<VkSampler>(vk::createSampler(m_vki, m_vkd, &createInfo)));
2572         }
2573 }
2574
2575 class SampledImageInstance : public CommonDescriptorInstance
2576 {
2577 public:
2578                                                                 SampledImageInstance                            (Context&                                                                       context,
2579                                                                                                                                          const TestCaseParams&                                          testCaseParams);
2580 private:
2581         virtual void                            createAndPopulateDescriptors            (IterateCommonVariables&                                        variables);
2582         virtual void                            updateDescriptors                                       (IterateCommonVariables&                                        variables);
2583 };
2584
2585 SampledImageInstance::SampledImageInstance                                                      (Context&                                                                       context,
2586                                                                                                                                          const TestCaseParams&                                          testCaseParams)
2587         : CommonDescriptorInstance(context,
2588                 TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
2589                         VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
2590                         BINDING_SampledImage,
2591                         VK_DESCRIPTOR_TYPE_SAMPLER,
2592                         BINDING_Sampler,
2593                         true,
2594                         performWritesInVertex(testCaseParams.descriptorType),
2595                         testCaseParams))
2596 {
2597         ut::DeviceProperties dp(context);
2598
2599         checkIndexingAvailable(dp);
2600
2601         const VkPhysicalDeviceDescriptorIndexingFeaturesEXT&    feats = dp.descriptorIndexingFeatures();
2602         // Note: common flags for SAMPLER, SAMPLED_IMAGE, COMBINED_IMAGE_SAMPLER
2603
2604         if (!(feats.shaderSampledImageArrayNonUniformIndexing))
2605                 TCU_THROW(NotSupportedError, "Non-uniform indexing over sampled image descriptor arrays is not supported.");
2606
2607         if (testCaseParams.updateAfterBind)
2608         {
2609                 if (!(feats.descriptorBindingSampledImageUpdateAfterBind))
2610                         TCU_THROW(NotSupportedError, "Update after bind for sampled image descriptors is not supported.");
2611         }
2612 }
2613
2614 void SampledImageInstance::updateDescriptors                                            (IterateCommonVariables&                                        variables)
2615 {
2616         DE_ASSERT(variables.descriptorSamplers.size()           == 1);
2617         DE_ASSERT(variables.descriptorsImages.size()            == variables.validDescriptorCount);
2618         DE_ASSERT(variables.descriptorImageViews.size()         == variables.validDescriptorCount);
2619         DE_ASSERT(variables.descriptorsBufferInfos.size()       == variables.validDescriptorCount);
2620
2621         // update a sampler
2622         {
2623                 const VkDescriptorImageInfo samplerInfo =
2624                 {
2625                         **variables.descriptorSamplers[0],
2626                         static_cast<VkImageView>(0),
2627                         static_cast<VkImageLayout>(0)
2628                 };
2629
2630                 const VkWriteDescriptorSet writeInfo =
2631                 {
2632                         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,                 // sType
2633                         DE_NULL,                                                                                // pNext
2634                         *variables.descriptorSet,                                               // descriptorSet
2635                         BINDING_Sampler,                                                                // descriptorBinding;
2636                         0,                                                                                              // elementIndex
2637                         1u,                                                                                             // descriptorCount
2638                         VK_DESCRIPTOR_TYPE_SAMPLER,                                             // descriptorType
2639                         &samplerInfo,                                                                   // pImageInfo
2640                         DE_NULL,                                                                                // pBufferInfo
2641                         DE_NULL                                                                                 // pTexelBufferView
2642                 };
2643
2644                 m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, DE_NULL);
2645         }
2646
2647         // update images
2648         CommonDescriptorInstance::updateDescriptors(variables);
2649 }
2650
2651 void SampledImageInstance::createAndPopulateDescriptors                         (IterateCommonVariables&                                        variables)
2652 {
2653         DE_ASSERT(variables.descriptorSamplers.size()           == 0);
2654         DE_ASSERT(variables.descriptorsImages.size()            == 0);
2655         DE_ASSERT(variables.descriptorImageViews.size()         == 0);
2656         DE_ASSERT(variables.descriptorsBufferInfos.size()       == 0);
2657
2658         // create an only one sampler for all images
2659         {
2660                 const tcu::Sampler sampler(
2661                         tcu::Sampler::CLAMP_TO_BORDER,                                                                                                                          // wrapS
2662                         tcu::Sampler::CLAMP_TO_BORDER,                                                                                                                          // wrapT
2663                         tcu::Sampler::CLAMP_TO_BORDER,                                                                                                                          // wrapR
2664                         m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST,        // minFilter
2665                         m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST,        // magFilter
2666                         0.0f,                                                                                                                                                                           // lodTreshold
2667                         true);                                                                                                                                                                          // normalizeCoords
2668                 const VkSamplerCreateInfo createInfo = vk::mapSampler(sampler, vk::mapVkFormat(m_colorFormat));
2669                 variables.descriptorSamplers.push_back(ut::SamplerSp(new Move<VkSampler>(vk::createSampler(m_vki, m_vkd, &createInfo))));
2670         }
2671
2672         const VkExtent3D&                       imageExtent = m_testParams.usesMipMaps ? bigImageExtent : smallImageExtent;
2673
2674         createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer,
2675                 (VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT), imageExtent, m_colorFormat, VK_IMAGE_LAYOUT_UNDEFINED, variables.validDescriptorCount, m_testParams.usesMipMaps);
2676         createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, m_colorFormat);
2677
2678         PixelBufferAccess                       pixelAccess;
2679         for (deUint32 imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
2680         {
2681                 const float                             component       = m_colorScheme[imageIdx % m_schemeSize];
2682
2683                 if (m_testParams.usesMipMaps)
2684                 {
2685                         const deUint32 mipCount = ut::computeMipMapCount(imageExtent);
2686                         DE_ASSERT(mipCount >= 2);
2687                         for (deUint32 mipIdx = 0; mipIdx < mipCount; ++mipIdx)
2688                         {
2689                                 pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, mipIdx);
2690                                 tcu::clear(pixelAccess, m_clearColor);
2691                         }
2692
2693                         pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, mipCount-1);
2694                         pixelAccess.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
2695                 }
2696                 else
2697                 {
2698                         pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, 0);
2699                         pixelAccess.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
2700                 }
2701         }
2702         vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
2703 }
2704
2705 class CombinedImageInstance : public CommonDescriptorInstance
2706 {
2707 public:
2708                                                                 CombinedImageInstance                           (Context&                                                                       context,
2709                                                                                                                                          const TestCaseParams&                                          testCaseParams);
2710 private:
2711         virtual void                            createAndPopulateDescriptors            (IterateCommonVariables&                                        variables);
2712         virtual void                            updateDescriptors                                       (IterateCommonVariables&                                        variables);
2713 };
2714
2715 CombinedImageInstance::CombinedImageInstance                                            (Context&                                                                       context,
2716                                                                                                                                          const TestCaseParams&                                          testCaseParams)
2717         : CommonDescriptorInstance(context,
2718                 TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
2719                         testCaseParams.descriptorType,
2720                         BINDING_CombinedImageSampler,
2721                         VK_DESCRIPTOR_TYPE_UNDEFINED,
2722                         BINDING_Undefined,
2723                         true,
2724                         performWritesInVertex(testCaseParams.descriptorType),
2725                         testCaseParams))
2726 {
2727         ut::DeviceProperties dp(context);
2728
2729         checkIndexingAvailable(dp);
2730
2731         const VkPhysicalDeviceDescriptorIndexingFeaturesEXT&    feats = dp.descriptorIndexingFeatures();
2732         // Note: common flags for SAMPLER, SAMPLED_IMAGE, COMBINED_IMAGE_SAMPLER
2733
2734         if (!(feats.shaderSampledImageArrayNonUniformIndexing))
2735                 TCU_THROW(NotSupportedError, "Non-uniform indexing over combined image sampler descriptor arrays is not supported.");
2736
2737         if (testCaseParams.updateAfterBind)
2738         {
2739                 if (!(feats.descriptorBindingSampledImageUpdateAfterBind))
2740                         TCU_THROW(NotSupportedError, "Update after bind for combined image sampler descriptors is not supported.");
2741         }
2742 }
2743
2744 void CombinedImageInstance::updateDescriptors                                           (IterateCommonVariables&                                        variables)
2745 {
2746         const std::vector<deUint32>     primes = ut::generatePrimes(variables.availableDescriptorCount);
2747         const deUint32                          primeCount = static_cast<deUint32>(primes.size());
2748
2749         DE_ASSERT(variables.descriptorSamplers.size()           == 1);
2750         DE_ASSERT(variables.descriptorsImages.size()            == primeCount);
2751         DE_ASSERT(variables.descriptorImageViews.size()         == primeCount);
2752         DE_ASSERT(variables.descriptorsBufferInfos.size()       == primeCount);
2753
2754         for (deUint32 primeIdx = 0; primeIdx < primeCount; ++primeIdx)
2755         {
2756                 const VkDescriptorImageInfo imageInfo =
2757                 {
2758                         **variables.descriptorSamplers[0],
2759                         **variables.descriptorImageViews[primeIdx],
2760                         VK_IMAGE_LAYOUT_GENERAL
2761                 };
2762
2763                 const VkWriteDescriptorSet writeInfo =
2764                 {
2765                         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,                 // sType
2766                         DE_NULL,                                                                                // pNext
2767                         *variables.descriptorSet,                                               // descriptorSet
2768                         BINDING_CombinedImageSampler,                                   // descriptorBinding;
2769                         primes[primeIdx],                                                               // elementIndex
2770                         1u,                                                                                             // descriptorCount
2771                         m_testParams.descriptorType,                                    // descriptorType
2772                         &imageInfo,                                                                             // pImageInfo
2773                         DE_NULL,                                                                                // pBufferInfo
2774                         DE_NULL                                                                                 // pTexelBufferView
2775                 };
2776
2777                 m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, DE_NULL);
2778         }
2779 }
2780
2781 void CombinedImageInstance::createAndPopulateDescriptors                        (IterateCommonVariables&                                        variables)
2782 {
2783         DE_ASSERT(variables.descriptorSamplers.size()           == 0);
2784         DE_ASSERT(variables.descriptorsImages.size()            == 0);
2785         DE_ASSERT(variables.descriptorImageViews.size()         == 0);
2786         DE_ASSERT(variables.descriptorsBufferInfos.size()       == 0);
2787         DE_ASSERT(variables.descriptorSamplers.size()           == 0);
2788
2789         const tcu::Sampler sampler(
2790                 tcu::Sampler::CLAMP_TO_BORDER,                                                                                                                          // wrapS
2791                 tcu::Sampler::CLAMP_TO_BORDER,                                                                                                                          // wrapT
2792                 tcu::Sampler::CLAMP_TO_BORDER,                                                                                                                          // wrapR
2793                 m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST,        // minFilter
2794                 m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST,        // magFilter
2795                 0.0f,                                                                                                                                                                           // lodTreshold
2796                 true);                                                                                                                                                                          // normalizeCoords
2797         const VkSamplerCreateInfo       createInfo = vk::mapSampler(sampler, vk::mapVkFormat(m_colorFormat));
2798         variables.descriptorSamplers.push_back(ut::SamplerSp(new Move<VkSampler>(vk::createSampler(m_vki, m_vkd, &createInfo))));
2799
2800         const VkExtent3D&                       imageExtent = m_testParams.usesMipMaps ? bigImageExtent : smallImageExtent;
2801         createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer, (VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT),
2802                 imageExtent, m_colorFormat, VK_IMAGE_LAYOUT_UNDEFINED, variables.validDescriptorCount, m_testParams.usesMipMaps);
2803         createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, m_colorFormat);
2804
2805         PixelBufferAccess                       pixelAccess;
2806         for (deUint32 imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
2807         {
2808                 const float                             component = m_colorScheme[imageIdx % m_schemeSize];
2809
2810                 if (m_testParams.usesMipMaps)
2811                 {
2812                         const deUint32  mipCount = ut::computeMipMapCount(imageExtent);
2813                         DE_ASSERT(mipCount >= 2);
2814                         for (deUint32 mipIdx = 0; mipIdx < mipCount; ++mipIdx)
2815                         {
2816                                 pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, mipIdx);
2817                                 tcu::clear(pixelAccess, m_clearColor);
2818                         }
2819
2820                         pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, mipCount-1);
2821                         pixelAccess.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
2822                 }
2823                 else
2824                 {
2825                         pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, 0);
2826                         pixelAccess.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
2827                 }
2828         }
2829
2830         vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
2831 }
2832
2833 class StorageImageInstance : public CommonDescriptorInstance
2834 {
2835 public:
2836                                                                 StorageImageInstance                            (Context&                                                                       context,
2837                                                                                                                                          const TestCaseParams&                                          testCaseParams);
2838 private:
2839         virtual tcu::TestStatus         iterate                                                         (void);
2840         virtual void                            createAndPopulateDescriptors            (IterateCommonVariables&                                        variables);
2841         virtual void                            updateDescriptors                                       (IterateCommonVariables&                                        variables);
2842         virtual void                            iterateCollectResults                           (ut::UpdatablePixelBufferAccessPtr&                     result,
2843                                                                                                                                          const IterateCommonVariables&                          variables,
2844                                                                                                                                          bool                                                                           fromTest);
2845         ut::BufferHandleAllocSp         m_buffer;
2846         const deUint32                          m_fillColor;
2847         typedef deUint32                        m_imageFormat_t;
2848 };
2849
2850 StorageImageInstance::StorageImageInstance                                                      (Context&                                                                       context,
2851                                                                                                                                          const TestCaseParams&                                          testCaseParams)
2852         : CommonDescriptorInstance(context,
2853                 TestParams      (VK_SHADER_STAGE_COMPUTE_BIT,
2854                                         VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
2855                                         BINDING_StorageImage,
2856                                         VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
2857                                         (BINDING_StorageImage + 1),
2858                                         true,
2859                                         performWritesInVertex(testCaseParams.descriptorType),
2860                                         testCaseParams))
2861         , m_buffer              ()
2862         , m_fillColor   (10)
2863 {
2864         ut::DeviceProperties dp(context);
2865
2866         checkIndexingAvailable(dp);
2867
2868         const VkPhysicalDeviceDescriptorIndexingFeaturesEXT& features = dp.descriptorIndexingFeatures();
2869
2870         if (!(features.shaderStorageImageArrayNonUniformIndexing))
2871                 TCU_THROW(NotSupportedError, "Non-uniform indexing over storage image descriptor arrays is not supported.");
2872
2873         if (testCaseParams.updateAfterBind)
2874         {
2875                 if (!(features.descriptorBindingStorageImageUpdateAfterBind))
2876                         TCU_THROW(NotSupportedError, "Update after bind for storage image descriptors is not supported.");
2877         }
2878 }
2879
2880 void StorageImageInstance::updateDescriptors                                            (IterateCommonVariables&                                        variables)
2881 {
2882         // update image at last index
2883         {
2884                 VkDescriptorImageInfo           imageInfo =
2885                 {
2886                         static_cast<VkSampler>(0),
2887                         **variables.descriptorImageViews[variables.validDescriptorCount],
2888                         VK_IMAGE_LAYOUT_GENERAL
2889                 };
2890
2891                 const VkWriteDescriptorSet writeInfo =
2892                 {
2893                         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,         // sType
2894                         DE_NULL,                                                                        // pNext
2895                         *variables.descriptorSet,                                       // descriptorSet
2896                         m_testParams.additionalDescriptorBinding,       // descriptorBinding;
2897                         0,                                                                                      // elementIndex
2898                         1u,                                                                                     // descriptorCount
2899                         m_testParams.additionalDescriptorType,          // descriptorType
2900                         &imageInfo,                                                                     // pImageInfo
2901                         DE_NULL,                                                                        // pBufferInfo
2902                         DE_NULL                                                                         // pTexelBufferView
2903                 };
2904
2905                 m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, DE_NULL);
2906         }
2907
2908         // update rest images
2909         CommonDescriptorInstance::updateDescriptors(variables);
2910 }
2911
2912 void StorageImageInstance::createAndPopulateDescriptors                         (IterateCommonVariables&                                        variables)
2913 {
2914         const VkFormat                          imageFormat = ut::mapType2vkFormat<m_imageFormat_t>::value;
2915         const VkBufferUsageFlags        bufferUsage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
2916
2917         // create descriptor buffer, images and views
2918         {
2919                 const VkExtent3D                        imageExtent = { 4, 4, 1 };
2920
2921                 createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer,
2922                         bufferUsage, imageExtent, imageFormat, VK_IMAGE_LAYOUT_UNDEFINED, variables.validDescriptorCount);
2923
2924                 for (deUint32 imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
2925                 {
2926                         const PixelBufferAccess pa = getPixelAccess(imageIdx, imageExtent, imageFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer);
2927                         tcu::clear(pa, tcu::UVec4(m_fillColor));
2928                 }
2929                 vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
2930         }
2931
2932         // create additional image that will be used as index container
2933         {
2934                 createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, m_buffer,
2935                         bufferUsage, m_testParams.frameResolution, imageFormat, VK_IMAGE_LAYOUT_UNDEFINED, 1);
2936
2937                 // populate buffer
2938                 const std::vector<deUint32>     primes = ut::generatePrimes(variables.availableDescriptorCount);
2939                 const PixelBufferAccess pa = getPixelAccess(variables.validDescriptorCount, m_testParams.frameResolution, imageFormat, variables.descriptorsBufferInfos, m_buffer);
2940                 for (deUint32 y = 0, pixel = 0; y < m_testParams.frameResolution.height; ++y)
2941                 {
2942                         for (deUint32 x = 0; x < m_testParams.frameResolution.width; ++x, ++pixel)
2943                         {
2944                                 const deUint32 component = primes[pixel % variables.validDescriptorCount];
2945                                 pa.setPixel(tcu::UVec4(component), x, y);
2946                         }
2947                 }
2948
2949                 // save changes
2950                 vk::flushAlloc(m_vki, m_vkd, *m_buffer->alloc);
2951         }
2952
2953         // create views for all previously created images
2954         createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, imageFormat);
2955 }
2956
2957 tcu::TestStatus StorageImageInstance::iterate                                           (void)
2958 {
2959         IterateCommonVariables  v;
2960         iterateCommandBegin             (v);
2961
2962         if (m_testParams.updateAfterBind)
2963         {
2964                 updateDescriptors       (v);
2965         }
2966
2967         copyBuffersToImages             (v);
2968
2969         m_vki.cmdDispatch               (*v.commandBuffer,
2970                                                         m_testParams.calculateInLoop ? 1 : v.renderArea.extent.width,
2971                                                         m_testParams.calculateInLoop ? 1 : v.renderArea.extent.height,
2972                                                         1);
2973
2974         copyImagesToBuffers             (v);
2975
2976         return (iterateCommandEnd(v, false) ? tcu::TestStatus::pass : tcu::TestStatus::fail)("");
2977 }
2978
2979 void StorageImageInstance::iterateCollectResults                                        (ut::UpdatablePixelBufferAccessPtr&                     result,
2980                                                                                                                                          const IterateCommonVariables&                          variables,
2981                                                                                                                                          bool                                                                           fromTest)
2982 {
2983         result = ut::UpdatablePixelBufferAccessPtr(new ut::PixelBufferAccessAllocation(
2984                 vk::mapVkFormat(ut::mapType2vkFormat<m_imageFormat_t>::value), m_testParams.frameResolution));
2985         const PixelBufferAccess& dst = *result.get();
2986
2987         if (fromTest)
2988         {
2989                 vk::invalidateAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
2990                 for (deUint32 y = 0, pixelNum = 0; y < m_testParams.frameResolution.height; ++y)
2991                 {
2992                         for (deUint32 x = 0; x < m_testParams.frameResolution.width; ++x, ++pixelNum)
2993                         {
2994                                 const deUint32 imageIdx = pixelNum % variables.validDescriptorCount;
2995                                 const PixelBufferAccess src = getPixelAccess(imageIdx,
2996                                         variables.descriptorsImages[imageIdx]->extent, variables.descriptorsImages[imageIdx]->format,
2997                                         variables.descriptorsBufferInfos, variables.descriptorsBuffer);
2998                                 dst.setPixel(tcu::Vector<m_imageFormat_t, 4>(src.getPixelT<m_imageFormat_t>(0, 0).x()), x, y);
2999                         }
3000                 }
3001         }
3002         else
3003         {
3004                 std::vector<m_imageFormat_t> inc(variables.validDescriptorCount, m_fillColor);
3005
3006                 for (deUint32 invIdx = variables.lowerBound; invIdx < variables.upperBound; ++invIdx)
3007                 {
3008                         ++inc[invIdx % variables.validDescriptorCount];
3009                 }
3010
3011                 for (deUint32 invIdx = 0; invIdx < variables.vertexCount; ++invIdx)
3012                 {
3013                         const deUint32 row = invIdx / m_testParams.frameResolution.width;
3014                         const deUint32 col = invIdx % m_testParams.frameResolution.width;
3015                         const m_imageFormat_t color = inc[invIdx % variables.validDescriptorCount];
3016                         dst.setPixel(tcu::Vector<m_imageFormat_t, 4>(color), col, row);
3017                 }
3018         }
3019 }
3020
3021 class DescriptorIndexingTestCase : public TestCase
3022 {
3023         const TestCaseParams m_testCaseParams;
3024 public:
3025         DescriptorIndexingTestCase(tcu::TestContext &context, const char *name, const char *description, const TestCaseParams& testCaseParams)
3026                 : TestCase(context, name, description)
3027                 , m_testCaseParams(testCaseParams)
3028         {
3029         }
3030
3031         vkt::TestInstance* createInstance(vkt::Context& context) const // override
3032         {
3033                 switch (m_testCaseParams.descriptorType)
3034                 {
3035                 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
3036                         return new StorageBufferInstance                (context, m_testCaseParams);
3037                 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
3038                         return new UniformBufferInstance                (context, m_testCaseParams);
3039                 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
3040                         return new StorageTexelInstance                 (context, m_testCaseParams);
3041                 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
3042                         return new UniformTexelInstance                 (context, m_testCaseParams);
3043                 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
3044                         return new DynamicStorageBufferInstance (context, m_testCaseParams);
3045                 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
3046                         return new DynamicUniformBufferInstance (context, m_testCaseParams);
3047                 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
3048                         return new InputAttachmentInstance              (context, m_testCaseParams);
3049                 case VK_DESCRIPTOR_TYPE_SAMPLER:
3050                         return new SamplerInstance                              (context, m_testCaseParams);
3051                 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
3052                         return new SampledImageInstance                 (context, m_testCaseParams);
3053                 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
3054                         return new CombinedImageInstance                (context, m_testCaseParams);
3055                 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
3056                         return new StorageImageInstance                 (context, m_testCaseParams);
3057                 default:
3058                         TCU_THROW(InternalError, "Unknown Descriptor Type");
3059                 }
3060                 return DE_NULL;
3061         }
3062
3063         virtual void initPrograms(SourceCollections& programCollection) const
3064         {
3065                 std::string(*genShaderSource)(VkShaderStageFlagBits, const TestCaseParams&, bool) = &CommonDescriptorInstance::getShaderSource;
3066
3067                 if (VK_SHADER_STAGE_VERTEX_BIT & m_testCaseParams.stageFlags)
3068                 {
3069                         programCollection.glslSources.add(
3070                                 ut::buildShaderName(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, false))
3071                                 << glu::VertexSource((*genShaderSource)(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams, false));
3072
3073                         if (CommonDescriptorInstance::performWritesInVertex(m_testCaseParams.descriptorType))
3074                         {
3075                                 programCollection.glslSources.add(
3076                                         ut::buildShaderName(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, true))
3077                                         << glu::VertexSource((*genShaderSource)(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams, true));
3078                         }
3079                 }
3080                 if (VK_SHADER_STAGE_FRAGMENT_BIT & m_testCaseParams.stageFlags)
3081                 {
3082                         programCollection.glslSources.add(
3083                                 ut::buildShaderName(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, false))
3084                                 << glu::FragmentSource((*genShaderSource)(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams, false));
3085
3086                         if (CommonDescriptorInstance::performWritesInVertex(m_testCaseParams.descriptorType))
3087                         {
3088                                 programCollection.glslSources.add(
3089                                         ut::buildShaderName(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, true))
3090                                         << glu::FragmentSource((*genShaderSource)(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams, true));
3091                         }
3092                 }
3093                 if (VK_SHADER_STAGE_COMPUTE_BIT & m_testCaseParams.stageFlags)
3094                 {
3095                         programCollection.glslSources.add(
3096                                 ut::buildShaderName(VK_SHADER_STAGE_COMPUTE_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, false))
3097                                 << glu::ComputeSource((*genShaderSource)(VK_SHADER_STAGE_COMPUTE_BIT, m_testCaseParams, false));
3098                 }
3099         }
3100 };
3101
3102 } // - unnamed namespace
3103
3104 void descriptorIndexingDescriptorSetsCreateTests (tcu::TestCaseGroup* group)
3105 {
3106         struct TestCaseInfo
3107         {
3108                 const char*             name;
3109                 const char*             description;
3110                 TestCaseParams  params;
3111         };
3112
3113         tcu::TestContext&                               context(group->getTestContext());
3114
3115         TestCaseInfo casesAfterBindAndLoop[] =
3116         {
3117                 {
3118                         "storage_buffer", "Regular Storage Buffer Descriptors",
3119                         {
3120                                 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
3121                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
3122                                 RESOLUTION,
3123                                 false,  // updateAfterBind
3124                                 false,  // calculateInLoop
3125                                 false,  // useMipMaps
3126                                 FUZZY_COMPARE, CMP_THRESHOLD
3127                         }
3128                 },
3129                 {
3130                         "storage_texel_buffer", "Storage Texel Buffer Descriptors",
3131                         {
3132                                 VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
3133                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
3134                                 RESOLUTION,
3135                                 false,  // updateAfterBind
3136                                 false,  // calculateInLoop
3137                                 false,  // useMipMaps
3138                                 FUZZY_COMPARE, CMP_THRESHOLD
3139                         }
3140                 },
3141                 {
3142                         "uniform_texel_buffer", "Uniform Texel Buffer Descriptors",
3143                         {
3144                                 VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
3145                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
3146                                 RESOLUTION,
3147                                 false,  // updateAfterBind,
3148                                 false,  // calculateInLoop
3149                                 false,  // usesMipMaps
3150                                 FUZZY_COMPARE, CMP_THRESHOLD
3151                         }
3152                 },
3153                 {
3154                         "storage_image", "Storage Image Descriptors",
3155                         {
3156                                 VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
3157                                 VK_SHADER_STAGE_COMPUTE_BIT,
3158                                 RESOLUTION,
3159                                 false,  // updateAfterBind
3160                                 false,  // calculateInLoop
3161                                 false,  // useMipMaps
3162                                 FUZZY_COMPARE, CMP_THRESHOLD
3163                         }
3164                 },
3165         };
3166
3167         for (int updateAfterBind = 0; updateAfterBind < 2; ++updateAfterBind)
3168         {
3169                 for (int calculateInLoop = 0; calculateInLoop < 2; ++calculateInLoop)
3170                 {
3171                         for (deUint32 caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(casesAfterBindAndLoop); ++caseIdx)
3172                         {
3173                                 TestCaseInfo&   info                    (casesAfterBindAndLoop[caseIdx]);
3174                                 std::string             caseName                (info.name);
3175                                 std::string             caseDescription (info.description);
3176                                 TestCaseParams  params                  (info.params);
3177
3178                                 caseName                                += (updateAfterBind     ? "_after_bind" : "");
3179                                 caseName                                += (calculateInLoop     ? "_in_loop"    : "");
3180
3181                                 caseDescription                 += (updateAfterBind     ? " After Bind" : "");
3182                                 caseDescription                 += (calculateInLoop ? " In Loop"        : "");
3183
3184                                 params.updateAfterBind  = updateAfterBind       ? true                  : false;
3185                                 params.calculateInLoop  = calculateInLoop       ? true                  : false;
3186
3187                                 group->addChild(new DescriptorIndexingTestCase(context, caseName.c_str(), caseDescription.c_str(), params));
3188                         }
3189                 }
3190         }
3191
3192         TestCaseInfo casesAfterBindAndLoopAndLOD[] =
3193         {
3194                 {
3195                         "sampler", "Sampler Descriptors",
3196                         {
3197                                 VK_DESCRIPTOR_TYPE_SAMPLER,
3198                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
3199                                 RESOLUTION,
3200                                 false,  // updateAfterBind
3201                                 false,  // calculateInLoop
3202                                 false,  // usesMipMaps
3203                                 FUZZY_COMPARE, CMP_THRESHOLD
3204                         }
3205                 },
3206                 {
3207                         "sampled_image", "Sampled Image Descriptors",
3208                         {
3209                                 VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
3210                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
3211                                 RESOLUTION,
3212                                 false,  // updateAfterBind
3213                                 false,  // calculateInLoop
3214                                 false,  // usesMipMaps
3215                                 FUZZY_COMPARE, CMP_THRESHOLD
3216                         }
3217                 },
3218                 {
3219                         "combined_image_sampler", "Combined Image Sampler Descriptors",
3220                         {
3221                                 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
3222                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
3223                                 RESOLUTION,
3224                                 false,  // updateAfterBind
3225                                 false,  // calculateInLoop
3226                                 false,  // usesMipMaps
3227                                 FUZZY_COMPARE, CMP_THRESHOLD
3228                         }
3229                 },
3230         };
3231
3232         for (int updateAfterBind = 0; updateAfterBind < 2; ++updateAfterBind)
3233         {
3234                 for (int calculateInLoop = 0; calculateInLoop < 2; ++calculateInLoop)
3235                 {
3236                         for (int usesMipMaps = 0; usesMipMaps < 2; ++usesMipMaps)
3237                         {
3238                                 for (deUint32 caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(casesAfterBindAndLoopAndLOD); ++caseIdx)
3239                                 {
3240                                         TestCaseInfo&   info                    (casesAfterBindAndLoopAndLOD[caseIdx]);
3241                                         std::string             caseName                (info.name);
3242                                         std::string             caseDescription (info.description);
3243                                         TestCaseParams  params                  (info.params);
3244
3245                                         caseName                                += (updateAfterBind     ? "_after_bind" : "");
3246                                         caseName                                += (calculateInLoop ? "_in_loop"        : "");
3247                                         caseName                                += (usesMipMaps         ? "_with_lod"   : "");
3248
3249                                         caseDescription                 += (updateAfterBind     ? " After Bind" : "");
3250                                         caseDescription                 += (calculateInLoop     ? " In Loop"    : "");
3251                                         caseDescription                 += (usesMipMaps         ? " Use LOD"    : "");
3252
3253                                         params.updateAfterBind  = updateAfterBind       ? true                  : false;
3254                                         params.calculateInLoop  = calculateInLoop       ? true                  : false;
3255                                         params.usesMipMaps              = usesMipMaps           ? true                  : false;
3256
3257                                         group->addChild(new DescriptorIndexingTestCase(context, caseName.c_str(), caseDescription.c_str(), params));
3258                                 }
3259                         }
3260                 }
3261         }
3262
3263         TestCaseInfo casesNonAfterBindAndLoop[] =
3264         {
3265                 {
3266                         "uniform_buffer", "Regular Uniform Buffer Descriptors",
3267                         {
3268                                 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
3269                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
3270                                 RESOLUTION,
3271                                 false,  // updateAfterBind
3272                                 false,  // calculateInLoop
3273                                 false,  // usesMipMaps
3274                                 FUZZY_COMPARE, CMP_THRESHOLD
3275                         }
3276                 },
3277                 {
3278                         "storage_buffer_dynamic", "Dynamic Storage Buffer Descriptors",
3279                         {
3280                                 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC,
3281                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
3282                                 RESOLUTION,
3283                                 false,  // updateAfterBind
3284                                 false,  // calculateInLoop
3285                                 false,  // useMipMaps
3286                                 FUZZY_COMPARE, CMP_THRESHOLD
3287                         }
3288                 },
3289                 {
3290                         "uniform_buffer_dynamic", "Dynamic Uniform Buffer Descriptors",
3291                         {
3292                                 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
3293                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
3294                                 RESOLUTION,
3295                                 false,  // updateAfterBind
3296                                 false,  // calculateInLoop
3297                                 false,  // useMipMaps
3298                                 FUZZY_COMPARE, CMP_THRESHOLD
3299                         }
3300                 },
3301                 {
3302                         "input_attachment", "Input Attachment Descriptors",
3303                         {
3304                                 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
3305                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
3306                                 RESOLUTION,
3307                                 false,  // updateAfterBind
3308                                 false,  // calculateInLoop
3309                                 false,  // useMipMaps
3310                                 FUZZY_COMPARE, CMP_THRESHOLD
3311                         }
3312                 },
3313         };
3314
3315         for (int calculateInLoop = 0; calculateInLoop < 2; ++calculateInLoop)
3316         {
3317                 for (deUint32 caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(casesNonAfterBindAndLoop); ++caseIdx)
3318                 {
3319                         TestCaseInfo&   info(casesNonAfterBindAndLoop[caseIdx]);
3320                         std::string             caseName(info.name);
3321                         std::string             caseDescription(info.description);
3322                         TestCaseParams  params(info.params);
3323
3324                         caseName                                += (calculateInLoop     ? "_in_loop"    : "");
3325
3326                         caseDescription                 += (calculateInLoop ? " In Loop"        : "");
3327
3328                         params.calculateInLoop  = calculateInLoop       ? true                  : false;
3329
3330                         group->addChild(new DescriptorIndexingTestCase(context, caseName.c_str(), caseDescription.c_str(), params));
3331                 }
3332         }
3333 }
3334
3335 } // - DescriptorIndexing
3336 } // - vkt