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