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         vk::beginRenderPass             (m_vki, *v.commandBuffer, *v.renderPass, *v.frameBuffer->buffer, v.renderArea, m_clearColor);
1256         m_vki.cmdDraw                   (*v.commandBuffer, v.vertexCount, 1u, 0u, 0u);
1257         vk::endRenderPass               (m_vki, *v.commandBuffer);
1258
1259         return (iterateCommandEnd(v) ? tcu::TestStatus::pass : tcu::TestStatus::fail)("");
1260 }
1261
1262 std::vector<float> CommonDescriptorInstance::createColorScheme          (void)
1263 {
1264         std::vector<float> cs;
1265         int divider = 2;
1266         for (int i = 0; i < 10; ++i)
1267         {
1268                 cs.push_back(1.0f / float(divider));
1269                 divider *= 2;
1270         }
1271         return cs;
1272 }
1273
1274 bool CommonDescriptorInstance::iterateCommandEnd                                        (IterateCommonVariables&                                        variables,
1275                                                                                                                                          bool                                                                           collectBeforeSubmit)
1276 {
1277         ut::UpdatablePixelBufferAccessPtr       programResult;
1278         ut::UpdatablePixelBufferAccessPtr       referenceResult;
1279
1280         if (collectBeforeSubmit)
1281         {
1282                 iterateCollectResults(programResult, variables, true);
1283                 iterateCollectResults(referenceResult, variables, false);
1284         }
1285
1286         VK_CHECK(m_vki.endCommandBuffer(*variables.commandBuffer));
1287         Move<VkFence> fence = commandSubmit(*variables.commandBuffer);
1288         m_vki.waitForFences(m_vkd, 1, &(*fence), DE_TRUE, ~0ull);
1289
1290         if (false == collectBeforeSubmit)
1291         {
1292                 iterateCollectResults(programResult, variables, true);
1293                 iterateCollectResults(referenceResult, variables, false);
1294         }
1295
1296         bool result = false;
1297         if (m_testParams.fuzzyComparison)
1298         {
1299                 result = tcu::fuzzyCompare(m_context.getTestContext().getLog(),
1300                         "Fuzzy Compare", "Comparison result", *referenceResult.get(), *programResult.get(), 0.02f, tcu::COMPARE_LOG_EVERYTHING);
1301         }
1302         else
1303         {
1304                 result = tcu::floatThresholdCompare(m_context.getTestContext().getLog(),
1305                         "Float Threshold Compare", "Comparison result", *referenceResult.get(), *programResult.get(), tcu::Vec4(0.02f, 0.02f, 0.02f, 0.02f), tcu::COMPARE_LOG_EVERYTHING);
1306         }
1307
1308         if (m_testParams.allowVertexStoring)
1309         {
1310                 result = verifyVertexWriteResults(variables);
1311         }
1312
1313         return result;
1314 }
1315
1316 void CommonDescriptorInstance::iterateCollectResults                            (ut::UpdatablePixelBufferAccessPtr&                     result,
1317                                                                                                                                          const IterateCommonVariables&                          variables,
1318                                                                                                                                          bool                                                                           fromTest)
1319 {
1320         if (fromTest)
1321         {
1322                 result = commandReadFrameBuffer(*variables.commandBuffer, variables.frameBuffer);
1323         }
1324         else
1325         {
1326                 result = ut::UpdatablePixelBufferAccessPtr(new ut::PixelBufferAccessAllocation(vk::mapVkFormat(m_colorFormat), m_testParams.frameResolution));
1327
1328                 for (deUint32 y = 0, pixelNum = 0; y < m_testParams.frameResolution.height; ++y)
1329                 {
1330                         for (deUint32 x = 0; x < m_testParams.frameResolution.width; ++x, ++pixelNum)
1331                         {
1332                                 const float component = m_colorScheme[(pixelNum % variables.validDescriptorCount) % m_schemeSize];
1333                                 result->setPixel(tcu::Vec4(component, component, component, 1.0f), x, y);
1334                         }
1335                 }
1336         }
1337 }
1338
1339 Move<VkCommandBuffer> CommonDescriptorInstance::createCmdBuffer         (void)
1340 {
1341         return vk::allocateCommandBuffer(m_vki, m_vkd, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1342 }
1343
1344 Move<VkFence> CommonDescriptorInstance::commandSubmit                           (VkCommandBuffer                                                        cmd)
1345 {
1346         Move<VkFence>   fence(vk::createFence(m_vki, m_vkd));
1347
1348         const VkSubmitInfo      submitInfo =
1349         {
1350                 VK_STRUCTURE_TYPE_SUBMIT_INFO,                                          // sType
1351                 DE_NULL,                                                                                        // pNext
1352                 0u,                                                                                                     // waitSemaphoreCount
1353                 static_cast<VkSemaphore*>(DE_NULL),                                     // pWaitSemaphores
1354                 static_cast<const VkPipelineStageFlags*>(DE_NULL),      // pWaitDstStageMask
1355                 1u,                                                                                                     // commandBufferCount
1356                 &cmd,                                                                                           // pCommandBuffers
1357                 0u,                                                                                                     // signalSemaphoreCount
1358                 static_cast<VkSemaphore*>(DE_NULL)                                      // pSignalSemaphores
1359         };
1360
1361         VK_CHECK(m_vki.queueSubmit(m_queue, 1u, &submitInfo, *fence));
1362
1363         return fence;
1364 }
1365
1366 bool CommonDescriptorInstance::verifyVertexWriteResults(IterateCommonVariables&                                 variables)
1367 {
1368         DE_UNREF(variables);
1369         return true;
1370 }
1371
1372 void CommonDescriptorInstance::commandBindPipeline                                      (VkCommandBuffer                                                        commandBuffer,
1373                                                                                                                                          VkPipeline                                                                     pipeline)
1374 {
1375         const VkPipelineBindPoint pipelineBindingPoint = (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT) ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS;
1376         m_vki.cmdBindPipeline(commandBuffer, pipelineBindingPoint, pipeline);
1377 }
1378
1379 void CommonDescriptorInstance::commandBindVertexAttributes                      (VkCommandBuffer                                                        commandBuffer,
1380                                                                                                                                          const ut::BufferHandleAllocSp&                         vertexAttributesBuffer)
1381 {
1382         const VkDeviceSize      offsets[] = { 0u };
1383         const VkBuffer          buffers[] = { *vertexAttributesBuffer->buffer };
1384         m_vki.cmdBindVertexBuffers(commandBuffer, 0u, 1u, buffers, offsets);
1385 }
1386
1387 void CommonDescriptorInstance::commandBindDescriptorSets                        (VkCommandBuffer                                                        commandBuffer,
1388                                                                                                                                          VkPipelineLayout                                                       pipelineLayout,
1389                                                                                                                                          VkDescriptorSet                                                        descriptorSet,
1390                                                                                                                                          deUint32                                                                       descriptorSetIndex)
1391 {
1392         const VkPipelineBindPoint pipelineBindingPoint = (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT) ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS;
1393         m_vki.cmdBindDescriptorSets(commandBuffer, pipelineBindingPoint, pipelineLayout, descriptorSetIndex, 1u, &descriptorSet, 0u, static_cast<deUint32*>(DE_NULL));
1394 }
1395
1396 ut::UpdatablePixelBufferAccessPtr
1397 CommonDescriptorInstance::commandReadFrameBuffer                                        (VkCommandBuffer                                                        commandBuffer,
1398                                                                                                                                          const ut::FrameBufferSp&                                       frameBuffer)
1399 {
1400         ut::BufferHandleAllocSp frameBufferContent;
1401         commandReadFrameBuffer(frameBufferContent, commandBuffer, frameBuffer);
1402         return ut::UpdatablePixelBufferAccessPtr(new ut::PixelBufferAccessBuffer(
1403                 m_vkd, m_vki, vk::mapVkFormat(m_colorFormat), m_testParams.frameResolution,
1404                 de::SharedPtr< Move<VkBuffer> >(new Move<VkBuffer>(frameBufferContent->buffer)),
1405                 de::SharedPtr< de::MovePtr<Allocation> >(new de::MovePtr<Allocation>(frameBufferContent->alloc))));
1406 }
1407
1408 void CommonDescriptorInstance::commandReadFrameBuffer                           (ut::BufferHandleAllocSp&                                       content,
1409                                                                                                                                          VkCommandBuffer                                                        commandBuffer,
1410                                                                                                                                          const ut::FrameBufferSp&                                       frameBuffer)
1411 {
1412         Move<VkBuffer>                  buffer;
1413         de::MovePtr<Allocation> allocation;
1414
1415         const VkDeviceSize bufferSize = ut::computeImageSize(frameBuffer->image);
1416
1417         // create a buffer and an host allocation for it
1418         {
1419                 const VkBufferCreateInfo bufferCreateInfo =
1420                 {
1421                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // sType
1422                         DE_NULL,                                                                        // pNext
1423                         0u,                                                                                     // flags
1424                         bufferSize,                                                                     // size
1425                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       // usage
1426                         VK_SHARING_MODE_EXCLUSIVE,                                      // sharingMode
1427                         1u,                                                                                     // queueFamilyIndexCoun
1428                         &m_queueFamilyIndex                                                     // pQueueFamilyIndices
1429                 };
1430
1431                 buffer = vk::createBuffer(m_vki, m_vkd, &bufferCreateInfo);
1432                 const VkMemoryRequirements      memRequirements(vk::getBufferMemoryRequirements(m_vki, m_vkd, *buffer));
1433                 allocation = m_allocator.allocate(memRequirements, MemoryRequirement::HostVisible);
1434
1435                 VK_CHECK(m_vki.bindBufferMemory(m_vkd, *buffer, allocation->getMemory(), allocation->getOffset()));
1436         }
1437
1438         const VkImage& image = *frameBuffer->image->image;
1439
1440         VkImageSubresourceRange         subresourceRange =
1441         {
1442                 VK_IMAGE_ASPECT_COLOR_BIT,                                      // aspectMask
1443                 0u,                                                                                     // baseMipLevel
1444                 1u,                                                                                     // levelCount
1445                 0u,                                                                                     // baseArrayLayer
1446                 1u                                                                                      // layerCount
1447         };
1448
1449         const VkImageMemoryBarrier      barrierBefore =
1450         {
1451                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // sType;
1452                 DE_NULL,                                                                        // pNext;
1453                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // srcAccessMask;
1454                 VK_ACCESS_TRANSFER_READ_BIT,                            // dstAccessMask;
1455                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // oldLayout
1456                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // newLayout;
1457                 VK_QUEUE_FAMILY_IGNORED,                                        // srcQueueFamilyIndex;
1458                 VK_QUEUE_FAMILY_IGNORED,                                        // dstQueueFamilyIndex;
1459                 image,                                                                          // image;
1460                 subresourceRange                                                        // subresourceRange;
1461         };
1462
1463         const VkBufferImageCopy         copyRegion =
1464         {
1465                 0u,                                                                                     // bufferOffset
1466                 frameBuffer->image->extent.width,                               // bufferRowLength
1467                 frameBuffer->image->extent.height,                      // bufferImageHeight
1468                 {                                                                                       // VkImageSubresourceLayers
1469                         VK_IMAGE_ASPECT_COLOR_BIT,                              // aspect
1470                         0u,                                                                             // mipLevel
1471                         0u,                                                                             // baseArrayLayer
1472                         1u,                                                                             // layerCount
1473                 },
1474                 { 0, 0, 0 },                                                            // imageOffset
1475                 frameBuffer->image->extent                                      // imageExtent
1476         };
1477
1478         const VkBufferMemoryBarrier     bufferBarrier =
1479         {
1480                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // sType;
1481                 DE_NULL,                                                                        // pNext;
1482                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // srcAccessMask;
1483                 VK_ACCESS_HOST_READ_BIT,                                        // dstAccessMask;
1484                 VK_QUEUE_FAMILY_IGNORED,                                        // srcQueueFamilyIndex;
1485                 VK_QUEUE_FAMILY_IGNORED,                                        // dstQueueFamilyIndex;
1486                 *buffer,                                                                        // buffer;
1487                 0u,                                                                                     // offset;
1488                 bufferSize                                                                      // size;
1489         };
1490
1491         const VkImageMemoryBarrier      barrierAfter =
1492         {
1493                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // sType;
1494                 DE_NULL,                                                                                // pNext;
1495                 VK_ACCESS_TRANSFER_READ_BIT,                                    // srcAccessMask;
1496                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                   // dstAccessMask;
1497                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,                   // oldLayout;
1498                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,               // newLayout;
1499                 VK_QUEUE_FAMILY_IGNORED,                                                // srcQueueFamilyIndex;
1500                 VK_QUEUE_FAMILY_IGNORED,                                                // dstQueueFamilyIndex;
1501                 image,                                                                                  // image
1502                 subresourceRange                                                                // subresourceRange
1503         };
1504
1505
1506         m_vki.cmdPipelineBarrier(commandBuffer,                                                                                         // commandBuffer
1507                 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,  // srcStageMask, dstStageMask
1508                 (VkDependencyFlags)0,                                                                                                                   // dependencyFlags
1509                 0u, DE_NULL,                                                                                                                                    // memoryBarrierCount, pMemoryBarriers
1510                 0u, DE_NULL,                                                                                                                                    // bufferBarrierCount, pBufferBarriers
1511                 1u, &barrierBefore);                                                                                                                            // imageBarrierCount, pImageBarriers
1512
1513         m_vki.cmdCopyImageToBuffer(commandBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, &copyRegion);
1514
1515         m_vki.cmdPipelineBarrier(commandBuffer,
1516                 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT | VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
1517                 (VkDependencyFlags)0,
1518                 0u, DE_NULL,
1519                 1u, &bufferBarrier,
1520                 1u, &barrierAfter);
1521
1522         content = ut::BufferHandleAllocSp(new ut::BufferHandleAlloc(buffer, allocation));
1523 }
1524
1525 std::string CommonDescriptorInstance::getColorAccess                            (VkDescriptorType                                                       descriptorType,
1526                                                                                                                                          const char*                                                            indexVariableName,
1527                                                                                                                                          bool                                                                           usesMipMaps)
1528 {
1529         std::string text;
1530         std::map<std::string, std::string> vars;
1531         vars["INDEX"] = indexVariableName;
1532
1533         switch (descriptorType)
1534         {
1535         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1536         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1537                 text = "data[nonuniformEXT(${INDEX})].c";
1538                 break;
1539         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1540         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1541                 text = "data[nonuniformEXT(${INDEX})].cold";
1542                 break;
1543         case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1544                 text = "subpassLoad(data[nonuniformEXT(${INDEX})]).rgba";
1545                 break;
1546         case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1547                 text = "texelFetch(data[nonuniformEXT(${INDEX})], 0)";
1548                 break;
1549         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1550                 text = "imageLoad(data[nonuniformEXT(${INDEX})], 0)";
1551                 break;
1552         case VK_DESCRIPTOR_TYPE_SAMPLER:
1553                 text = usesMipMaps
1554                         ? "textureLod(sampler2D(tex[0], data[nonuniformEXT(${INDEX})]), normalpos, 1)"
1555                         : "texture(   sampler2D(tex[0], data[nonuniformEXT(${INDEX})]), normalpos   )";
1556                 break;
1557         case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1558                 text = usesMipMaps
1559                         ? "textureLod( sampler2D(data[nonuniformEXT(${INDEX})], samp[0]), vec2(0,0), textureQueryLevels(sampler2D(data[nonuniformEXT(${INDEX})], samp[0]))-1)"
1560                         : "texture(    sampler2D(data[nonuniformEXT(${INDEX})], samp[0]), vec2(0,0)   )";
1561                 break;
1562         case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1563                 text = usesMipMaps
1564                         ? "textureLod( data[nonuniformEXT(${INDEX})], uvec2(0,0), textureQueryLevels(data[nonuniformEXT(${INDEX})])-1)"
1565                         : "texture(    data[nonuniformEXT(${INDEX})], uvec2(0,0)   )";
1566                 break;
1567         default:
1568                 TCU_THROW(InternalError, "Not implemented descriptor type");
1569         }
1570
1571         return tcu::StringTemplate(text).specialize(vars);
1572 }
1573
1574 std::string CommonDescriptorInstance::getFragmentReturnSource           (const std::string&                                                     colorAccess)
1575 {
1576         return "  FragColor = " + colorAccess + ";\n";
1577 }
1578
1579 std::string CommonDescriptorInstance::getFragmentLoopSource                     (const std::string&                                                     colorAccess1,
1580                                                                                                                                          const std::string&                                                     colorAccess2)
1581 {
1582         std::map < std::string, std::string > vars;
1583         vars["COLOR_ACCESS_1"] = colorAccess1;
1584         vars["COLOR_ACCESS_2"] = colorAccess2;
1585
1586         const char* s =
1587                 "  vec4 sumClr1 = vec4(0,0,0,0);                \n"
1588                 "  vec4 sumClr2 = vec4(0,0,0,0);                \n"
1589                 "  for (int i = pc.lowerBound; i < pc.upperBound; ++i)  \n"
1590                 "  {\n"
1591                 "    int loopIdx = texelFetch(iter, i).x;                               \n"
1592                 "    sumClr1 += ${COLOR_ACCESS_2} + ${COLOR_ACCESS_1};  \n"
1593                 "    sumClr2 += ${COLOR_ACCESS_2};                                              \n"
1594                 "  }\n"
1595                 "  FragColor = vec4(((sumClr1 - sumClr2) / float(pc.upperBound - pc.lowerBound)).rgb, 1);       \n";
1596
1597         return tcu::StringTemplate(s).specialize(vars);
1598 }
1599
1600 bool CommonDescriptorInstance::performWritesInVertex                            (VkDescriptorType                                                       descriptorType)
1601 {
1602         bool result = false;
1603
1604         switch (descriptorType)
1605         {
1606         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1607         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1608         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1609                 result = true;
1610                 break;
1611         default:
1612                 result = false;
1613                 break;
1614         }
1615
1616         return result;
1617 }
1618
1619 bool CommonDescriptorInstance::performWritesInVertex                            (VkDescriptorType                                                       descriptorType,
1620                                                                                                                                         const Context&                                                          context)
1621 {
1622         bool result = false;
1623
1624         ut::DeviceProperties                    dp              (context);
1625         const VkPhysicalDeviceFeatures& feats   = dp.physicalDeviceFeatures();
1626
1627         if (feats.vertexPipelineStoresAndAtomics != DE_FALSE)
1628         {
1629                 result = CommonDescriptorInstance::performWritesInVertex(descriptorType);
1630         }
1631
1632         return result;
1633 }
1634
1635 std::string CommonDescriptorInstance::getShaderSource                           (VkShaderStageFlagBits                                          shaderType,
1636                                                                                                                                          const TestCaseParams&                                          testCaseParams,
1637                                                                                                                                          bool                                                                           allowVertexStoring)
1638 {
1639         std::stringstream       s;
1640
1641         s << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << '\n';
1642         s << "#extension GL_EXT_nonuniform_qualifier : require  \n";
1643
1644         if (testCaseParams.calculateInLoop)
1645         {
1646                 s << "layout(push_constant)     uniform Block { int lowerBound, upperBound; } pc;\n";
1647                 s << substBinding(BINDING_DescriptorEnumerator,
1648                         "layout(set=1,binding=${?}) uniform isamplerBuffer iter;        \n");
1649         }
1650
1651         switch (testCaseParams.descriptorType)
1652         {
1653                 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1654                         s << substBinding(BINDING_StorageBuffer,
1655                                 "layout(set=0,binding=${?}) buffer Data { vec4 cnew, cold; } data[]; \n");
1656                         break;
1657                 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1658                         s << substBinding(BINDING_StorageBufferDynamic,
1659                                 "layout(set=0,binding=${?}) buffer Data { vec4 cnew, cold; } data[]; \n");
1660                         break;
1661                 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1662                         s << substBinding(BINDING_UniformBuffer,
1663                                 "layout(set=0,binding=${?}) uniform Data { vec4 c; } data[]; \n");
1664                         break;
1665                 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1666                         s << substBinding(BINDING_UniformBufferDynamic,
1667                                 "layout(set=0,binding=${?}) uniform Data { vec4 c; } data[]; \n");
1668                         break;
1669                 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1670                         s << substBinding(BINDING_StorageTexelBuffer,
1671                                 "layout(set=0,binding=${?},rgba32f) uniform imageBuffer data[];\n");
1672                         break;
1673                 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1674                         s << "#extension GL_EXT_texture_buffer : require        \n";
1675                         s << substBinding(BINDING_UniformTexelBuffer,
1676                                 "layout(set=0,binding=${?}) uniform samplerBuffer data[];\n");
1677                         break;
1678                 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1679                         // Left for the consistent of code.
1680                         // Header is set one swicth below
1681                         break;
1682                 case VK_DESCRIPTOR_TYPE_SAMPLER:
1683                         s << "#extension GL_EXT_texture_buffer : require        \n";
1684                         s << substBinding(BINDING_SampledImage,
1685                                 "layout(set=0,binding=${?}) uniform texture2D ${VAR}[${*}];\n", 1, "tex");
1686                         s << substBinding(BINDING_Sampler,
1687                                 "layout(set=0,binding=${?}) uniform sampler ${VAR}[${*}];\n");
1688                         break;
1689                 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1690                         s << "#extension GL_EXT_texture_buffer : require        \n";
1691                         s << substBinding(BINDING_Sampler,
1692                                 "layout(set=0,binding=${?}) uniform sampler ${VAR}[${*}];\n", 1, "samp");
1693                         s << substBinding(BINDING_SampledImage,
1694                                 "layout(set=0,binding=${?}) uniform texture2D ${VAR}[${*}];\n");
1695                         break;
1696                 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1697                         s << "#extension GL_EXT_texture_buffer : require        \n";
1698                         s << substBinding(BINDING_CombinedImageSampler,
1699                                 "layout(set=0,binding=${?}) uniform sampler2D data[];\n");
1700                         break;
1701                 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1702                         s << "layout(local_size_x=1,local_size_y=1,local_size_z=1) in;  \n";
1703                         s << substBinding(BINDING_StorageImage + 1,
1704                                 "layout(r32ui,set=0,binding=${?}) uniform uimage2D idxs;        \n");
1705                         s << substBinding(BINDING_StorageImage,
1706                                 "layout(r32ui,set=0,binding=${?}) uniform uimage2D data[];      \n");
1707                         break;
1708                 default:
1709                         TCU_THROW(InternalError, "Not implemented descriptor type");
1710         }
1711
1712         switch (shaderType)
1713         {
1714                 case VK_SHADER_STAGE_VERTEX_BIT:        s << getVertexShaderProlog();   break;
1715                 case VK_SHADER_STAGE_FRAGMENT_BIT:
1716                         {
1717                                 if (testCaseParams.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)
1718                                 {
1719                                         s << substBinding(BINDING_InputAttachment,
1720                                                 "layout(input_attachment_index=1,set=0,binding=${?}) uniform subpassInput data[];       \n");
1721                                 }
1722                                 s << getFragmentShaderProlog();
1723                         }
1724                         break;
1725                 case VK_SHADER_STAGE_COMPUTE_BIT:
1726                         break;
1727                 default:
1728                         TCU_THROW(InternalError, "Not implemented shader stage");
1729         }
1730
1731         switch (shaderType)
1732         {
1733                 case VK_SHADER_STAGE_VERTEX_BIT:
1734                 {
1735                         switch (testCaseParams.descriptorType)
1736                         {
1737                         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1738                         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1739                                 if (allowVertexStoring)
1740                                         s << "  if (gIndex != 0) data[nonuniformEXT(gIndex)].cnew = data[nonuniformEXT(rIndex)].cold;   \n";
1741                                 break;
1742                         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1743                                 if (allowVertexStoring)
1744                                         s << "  if (gIndex != 0) imageStore(data[nonuniformEXT(gIndex)], 1, imageLoad(data[nonuniformEXT(rIndex)], 0)); \n";
1745                                 break;
1746                         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1747                         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1748                         case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1749                         case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1750                         case VK_DESCRIPTOR_TYPE_SAMPLER:
1751                         case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1752                         case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1753                                 break;
1754
1755                         default:
1756                                 TCU_THROW(InternalError, "Not implemented descriptor type");
1757                         }
1758                 }
1759                 break;
1760
1761                 case VK_SHADER_STAGE_FRAGMENT_BIT:
1762                 {
1763                         switch (testCaseParams.descriptorType)
1764                         {
1765                         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1766                         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1767                         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1768                                 {
1769                                         if (testCaseParams.calculateInLoop)
1770                                                 s << getFragmentLoopSource(
1771                                                         getColorAccess(testCaseParams.descriptorType, "rIndex", false),
1772                                                         getColorAccess(testCaseParams.descriptorType, "loopIdx", false));
1773                                         else
1774                                                 s << getFragmentReturnSource(getColorAccess(testCaseParams.descriptorType, "rIndex", false));
1775                                 }
1776                                 break;
1777                         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1778                         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1779                         case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1780                         case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1781                         case VK_DESCRIPTOR_TYPE_SAMPLER:
1782                         case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1783                         case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1784                                 if (testCaseParams.calculateInLoop)
1785                                         s << getFragmentLoopSource(
1786                                                 getColorAccess(testCaseParams.descriptorType, "rIndex", testCaseParams.usesMipMaps),
1787                                                 getColorAccess(testCaseParams.descriptorType, "loopIdx", testCaseParams.usesMipMaps));
1788                                 else
1789                                         s << getFragmentReturnSource(getColorAccess(testCaseParams.descriptorType, "rIndex", testCaseParams.usesMipMaps));
1790                                 break;
1791                         default:        TCU_THROW(InternalError, "Not implemented descriptor type");
1792                         }
1793                 }
1794                 break;
1795
1796                 case VK_SHADER_STAGE_COMPUTE_BIT: // VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
1797                         s << "void main(void)\n{\n";
1798                         if (testCaseParams.calculateInLoop)
1799                                 s << "  for (int i = pc.lowerBound; i < pc.upperBound; ++i)     \n"
1800                                         "    imageAtomicAdd(data[nonuniformEXT(texelFetch(iter, i).x)], ivec2(0, 0), 1);                        \n";
1801                         else
1802                                 s << "  uvec4 c = imageLoad(idxs, ivec2(gl_WorkGroupID.x, gl_WorkGroupID.y));   \n"
1803                                         "  imageAtomicAdd( data[nonuniformEXT(c.r)], ivec2(0, 0), 1);                                                           \n";
1804                         break;
1805
1806                 default:        TCU_THROW(InternalError, "Not implemented shader stage");
1807         }
1808
1809         s << getShaderEpilog();
1810
1811         return s.str();
1812 }
1813
1814 class StorageBufferInstance : virtual public CommonDescriptorInstance
1815 {
1816 public:
1817                                                                 StorageBufferInstance                           (Context&                                                                       context,
1818                                                                                                                                          const TestCaseParams&                                          testCaseParams);
1819 protected:
1820         virtual void                            createAndPopulateDescriptors            (IterateCommonVariables&                                        variables);
1821
1822         virtual bool                            verifyVertexWriteResults                        (IterateCommonVariables&                                        variables);
1823 };
1824
1825 StorageBufferInstance::StorageBufferInstance                                            (Context&                                                                       context,
1826                                                                                                                                          const TestCaseParams&                                          testCaseParams)
1827         : CommonDescriptorInstance(context,
1828                 TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
1829                         VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1830                         BINDING_StorageBuffer,
1831                         VK_DESCRIPTOR_TYPE_UNDEFINED,
1832                         BINDING_Undefined,
1833                         false,
1834                         performWritesInVertex(testCaseParams.descriptorType, context),
1835                         testCaseParams))
1836 {
1837 }
1838
1839 void StorageBufferInstance::createAndPopulateDescriptors                        (IterateCommonVariables&                                        variables)
1840 {
1841         BindingStorageBuffer::Data      data;
1842
1843         bool                                            vertexStores = false;
1844         {
1845                 ut::DeviceProperties dp(m_context);
1846                 vertexStores = dp.physicalDeviceFeatures().vertexPipelineStoresAndAtomics != DE_FALSE;
1847         }
1848         const deUint32                          alignment       = static_cast<deUint32>(ut::DeviceProperties(m_context).physicalDeviceProperties().limits.minStorageBufferOffsetAlignment);
1849         createBuffers(variables.descriptorsBufferInfos, variables.descriptorsBuffer, variables.validDescriptorCount, sizeof(data), alignment, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1850
1851         unsigned char*                          buffer          = static_cast<unsigned char*>(variables.descriptorsBuffer->alloc->getHostPtr());
1852         for (deUint32 infoIdx = 0; infoIdx < variables.validDescriptorCount; ++infoIdx)
1853         {
1854                 const float                             component       = m_colorScheme[infoIdx % m_schemeSize];
1855                 const tcu::Vec4                 color           (component, component, component, 1.0f);
1856                 VkDescriptorBufferInfo& info            = variables.descriptorsBufferInfos[infoIdx];
1857                 data.cnew                                                       = vertexStores ? m_clearColor : color;
1858                 data.cold                                                       = color;
1859
1860                 deMemcpy(buffer + info.offset, &data, sizeof(data));
1861         }
1862         vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
1863
1864         variables.dataAlignment = deAlign64(sizeof(data), alignment);
1865 }
1866
1867 bool StorageBufferInstance::verifyVertexWriteResults                            (IterateCommonVariables&                                        variables)
1868 {
1869         const tcu::Vec4                         threshold               (0.002f, 0.002f, 0.002f, 0.002f);
1870         const std::vector<deUint32>     primes                  = ut::generatePrimes(variables.availableDescriptorCount);
1871
1872         unsigned char*                          buffer = static_cast<unsigned char*>(variables.descriptorsBuffer->alloc->getHostPtr());
1873         BindingStorageBuffer::Data      data;
1874         for (deUint32 primeIdx = 0; primeIdx < variables.validDescriptorCount; ++primeIdx)
1875         {
1876                 const deUint32                  prime           = primes[primeIdx];
1877                 const float                             component       = m_colorScheme[(prime % variables.validDescriptorCount) % m_schemeSize];
1878                 const tcu::Vec4                 referenceValue(component, component, component, 1.0f);
1879
1880                 VkDescriptorBufferInfo& info = variables.descriptorsBufferInfos[primeIdx];
1881                 deMemcpy(&data, buffer + info.offset, sizeof(data));
1882                 const tcu::Vec4                 realValue = data.cnew;
1883
1884                 const tcu::Vec4                 diff = tcu::absDiff(referenceValue, realValue);
1885                 if (!tcu::boolAll(tcu::lessThanEqual(diff, threshold)))
1886                         return false;
1887         }
1888         return true;
1889 }
1890
1891 class UniformBufferInstance : virtual public CommonDescriptorInstance
1892 {
1893 public:
1894                                                                 UniformBufferInstance                           (Context&                                                                       context,
1895                                                                                                                                          const TestCaseParams&                                          testCaseParams);
1896 protected:
1897         virtual void                            createAndPopulateDescriptors            (IterateCommonVariables&                                        variables);
1898 };
1899
1900 UniformBufferInstance::UniformBufferInstance                                            (Context&                                                                       context,
1901                                                                                                                                          const TestCaseParams&                                          testCaseParams)
1902         : CommonDescriptorInstance(context,
1903                 TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
1904                         VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1905                         BINDING_UniformBuffer,
1906                         VK_DESCRIPTOR_TYPE_UNDEFINED,
1907                         BINDING_Undefined,
1908                         false,
1909                         performWritesInVertex(testCaseParams.descriptorType, context),
1910                         testCaseParams))
1911 {
1912 }
1913
1914 void UniformBufferInstance::createAndPopulateDescriptors                        (IterateCommonVariables&                                        variables)
1915 {
1916         BindingUniformBuffer::Data data;
1917
1918         const deUint32                          alignment       = static_cast<deUint32>(ut::DeviceProperties(m_context).physicalDeviceProperties().limits.minUniformBufferOffsetAlignment);
1919         createBuffers(variables.descriptorsBufferInfos, variables.descriptorsBuffer, variables.validDescriptorCount, sizeof(data), alignment, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
1920
1921         unsigned char*                          buffer          = static_cast<unsigned char*>(variables.descriptorsBuffer->alloc->getHostPtr());
1922         for (deUint32 infoIdx = 0; infoIdx < variables.validDescriptorCount; ++infoIdx)
1923         {
1924                 const float                             component       = m_colorScheme[infoIdx % m_schemeSize];
1925                 VkDescriptorBufferInfo& info            = variables.descriptorsBufferInfos[infoIdx];
1926                 data.c                                                          = tcu::Vec4(component, component, component, 1.0f);
1927                 deMemcpy(buffer + info.offset, &data, sizeof(data));
1928         }
1929         vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
1930
1931         variables.dataAlignment = deAlign64(sizeof(data), alignment);
1932 }
1933
1934 class StorageTexelInstance : public CommonDescriptorInstance
1935 {
1936 public:
1937                                                                 StorageTexelInstance                            (Context&                                                                       context,
1938                                                                                                                                          const TestCaseParams&                                          testCaseParams);
1939 private:
1940         virtual void                            createAndPopulateDescriptors            (IterateCommonVariables&                                        variables);
1941
1942         virtual bool                            verifyVertexWriteResults                        (IterateCommonVariables&                                        variables);
1943 };
1944
1945 StorageTexelInstance::StorageTexelInstance                                                      (Context&                                                                       context,
1946                                                                                                                                          const TestCaseParams&                                          testCaseParams)
1947         : CommonDescriptorInstance(context,
1948                 TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
1949                         VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
1950                         BINDING_StorageTexelBuffer,
1951                         VK_DESCRIPTOR_TYPE_UNDEFINED,
1952                         BINDING_Undefined,
1953                         false,
1954                         performWritesInVertex(testCaseParams.descriptorType, context),
1955                         testCaseParams))
1956 {
1957 }
1958
1959 void StorageTexelInstance::createAndPopulateDescriptors                 (IterateCommonVariables&                                        variables)
1960 {
1961         const VkExtent3D                        imageExtent                     = { 4, 4, 1 };
1962         const deUint32                          imageSize                       = ut::computeImageSize(imageExtent, m_colorFormat);
1963
1964         createBuffers(variables.descriptorsBufferInfos, variables.descriptorsBuffer, variables.validDescriptorCount, imageSize, sizeof(tcu::Vec4), VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT);
1965         createBuffersViews(variables.descriptorsBufferViews, variables.descriptorsBufferInfos, m_colorFormat);
1966
1967         for (deUint32 imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
1968         {
1969                 const float                             component                       = m_colorScheme[imageIdx % m_schemeSize];
1970                 const PixelBufferAccess pa                                      = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer);
1971
1972                 tcu::clear(pa, m_clearColor);
1973                 pa.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
1974         }
1975         vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
1976 }
1977
1978 bool StorageTexelInstance::verifyVertexWriteResults(IterateCommonVariables&                                     variables)
1979 {
1980         const VkExtent3D                        imageExtent             = { 4, 4, 1 };
1981         const tcu::Vec4                         threshold               (0.002f, 0.002f, 0.002f, 0.002f);
1982         const std::vector<deUint32>     primes                  = ut::generatePrimes(variables.availableDescriptorCount);
1983
1984         for (deUint32 primeIdx = 0; primeIdx < variables.validDescriptorCount; ++primeIdx)
1985         {
1986                 const deUint32                  prime           = primes[primeIdx];
1987                 const float                             component       = m_colorScheme[( prime % variables.validDescriptorCount ) % m_schemeSize];
1988                 const tcu::Vec4                 referenceValue(component, component, component, 1.0f);
1989
1990                 const PixelBufferAccess pa                      = getPixelAccess(primeIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer);
1991                 const tcu::Vec4                 realValue       = pa.getPixel(1, 0);
1992
1993                 const tcu::Vec4                 diff            = tcu::absDiff(referenceValue, realValue);
1994                 if (!tcu::boolAll(tcu::lessThanEqual(diff, threshold)))
1995                         return false;
1996         }
1997         return true;
1998 }
1999
2000 class UniformTexelInstance : public CommonDescriptorInstance
2001 {
2002 public:
2003                                                                 UniformTexelInstance                            (Context&                                                                       context,
2004                                                                                                                                          const TestCaseParams&                                          testCaseParams);
2005 private:
2006         virtual void                            createAndPopulateDescriptors            (IterateCommonVariables&                                        variables);
2007 };
2008
2009 UniformTexelInstance::UniformTexelInstance                                                      (Context&                                                                       context,
2010                                                                                                                                          const TestCaseParams&                                          testCaseParams)
2011         : CommonDescriptorInstance(context,
2012                 TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
2013                         VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
2014                         BINDING_UniformTexelBuffer,
2015                         VK_DESCRIPTOR_TYPE_UNDEFINED,
2016                         BINDING_Undefined,
2017                         false,
2018                         performWritesInVertex(testCaseParams.descriptorType, context),
2019                         testCaseParams))
2020 {
2021 }
2022
2023 void UniformTexelInstance::createAndPopulateDescriptors                         (IterateCommonVariables&                                        variables)
2024 {
2025         const VkExtent3D                        imageExtent     = { 4, 4, 1 };
2026         const deUint32                          imageSize       = ut::computeImageSize(imageExtent, m_colorFormat);
2027
2028         createBuffers(variables.descriptorsBufferInfos, variables.descriptorsBuffer, variables.validDescriptorCount, imageSize, sizeof(tcu::Vec4), VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT);
2029         createBuffersViews(variables.descriptorsBufferViews, variables.descriptorsBufferInfos, m_colorFormat);
2030
2031         for (deUint32 imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
2032         {
2033                 const float                             component       = m_colorScheme[imageIdx % m_schemeSize];
2034                 const PixelBufferAccess pa                      = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer);
2035
2036                 tcu::clear(pa, tcu::Vec4(component, component, component, 1.0f));
2037         }
2038         vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
2039 }
2040
2041 class DynamicBuffersInstance : virtual public CommonDescriptorInstance
2042 {
2043 public:
2044         DynamicBuffersInstance                                                                                  (Context&                                                                       context,
2045                                                                                                                                          const TestParams&                                                      testParams)
2046                 : CommonDescriptorInstance(context, testParams) {}
2047
2048 protected:
2049         virtual tcu::TestStatus         iterate                                                         (void);
2050         virtual void                            updateDescriptors                                       (IterateCommonVariables&                                        variables);
2051 };
2052
2053 void DynamicBuffersInstance::updateDescriptors                                          (IterateCommonVariables&                                        variables)
2054 {
2055         DE_ASSERT(variables.dataAlignment);
2056
2057         VkDescriptorBufferInfo  bufferInfo =
2058         {
2059                 *variables.descriptorsBuffer.get()->buffer,
2060                 0,      // always 0, it will be taken from pDynamicOffsets
2061                 variables.dataAlignment
2062         };
2063
2064         VkWriteDescriptorSet updateInfo =
2065         {
2066                 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,                 // sType
2067                 DE_NULL,                                                                                // pNext
2068                 *variables.descriptorSet,                                               // descriptorSet
2069                 m_testParams.descriptorBinding,                                 // descriptorBinding;
2070                 0,      // to be set in below loop                                      // dstArrayElement
2071                 1u,                                                                                             // descriptorCount
2072                 m_testParams.descriptorType,                                    // descriptorType
2073                 DE_NULL,                                                                                // pImageInfo
2074                 &bufferInfo,                                                                    // pBufferInfo
2075                 DE_NULL                                                                                 // pTexelBufferView
2076         };
2077
2078         deUint32 descIdx = 0;
2079         const std::vector<deUint32> primes = ut::generatePrimes(variables.availableDescriptorCount);
2080         for (deUint32 validIdx = 0; validIdx < variables.validDescriptorCount; ++validIdx)
2081         {
2082                 for (; descIdx < primes[validIdx]; ++descIdx)
2083                 {
2084                         updateInfo.dstArrayElement                      = descIdx;
2085                         m_vki.updateDescriptorSets      (m_vkd, 1u, &updateInfo, 0u, DE_NULL);
2086                 }
2087
2088                 updateInfo.dstArrayElement                              = primes[validIdx];
2089                 m_vki.updateDescriptorSets              (m_vkd, 1u, &updateInfo, 0u, DE_NULL);
2090
2091                 ++descIdx;
2092         }
2093         for (; descIdx < variables.availableDescriptorCount; ++descIdx)
2094         {
2095                 updateInfo.dstArrayElement = descIdx;
2096                 m_vki.updateDescriptorSets(m_vkd, 1u, &updateInfo, 0u, DE_NULL);
2097         }
2098 }
2099
2100 tcu::TestStatus DynamicBuffersInstance::iterate                                         (void)
2101 {
2102         IterateCommonVariables  v;
2103         iterateCommandBegin             (v);
2104
2105         DE_ASSERT(v.dataAlignment);
2106
2107         std::vector<deUint32> dynamicOffsets;
2108
2109         deUint32 descIdx = 0;
2110         const std::vector<deUint32> primes = ut::generatePrimes(v.availableDescriptorCount);
2111         for (deUint32 validIdx = 0; validIdx < v.validDescriptorCount; ++validIdx)
2112         {
2113                 for (; descIdx < primes[validIdx]; ++descIdx)
2114                 {
2115                         dynamicOffsets.push_back(0);
2116                 }
2117
2118                 dynamicOffsets.push_back(static_cast<deUint32>(validIdx * v.dataAlignment));
2119
2120                 ++descIdx;
2121         }
2122         for (; descIdx < v.availableDescriptorCount; ++descIdx)
2123         {
2124                 dynamicOffsets.push_back(0);
2125         }
2126
2127         // Unfortunatelly not lees and not more, only exactly
2128         DE_ASSERT(dynamicOffsets.size() == v.availableDescriptorCount);
2129
2130         const VkDescriptorSet   descriptorSets[] = { *v.descriptorSet };
2131
2132         m_vki.cmdBindDescriptorSets(
2133                 *v.commandBuffer,                                               // commandBuffer
2134                 VK_PIPELINE_BIND_POINT_GRAPHICS,                // pipelineBindPoint
2135                 *v.pipelineLayout,                                              // layout
2136                 0u,                                                                             // firstSet
2137                 DE_LENGTH_OF_ARRAY(descriptorSets),             // descriptorSetCount
2138                 descriptorSets,                                                 // pDescriptorSets
2139                 v.availableDescriptorCount,                             // dynamicOffsetCount
2140                 dynamicOffsets.data());                                 // pDynamicOffsets
2141
2142         vk::beginRenderPass     (m_vki, *v.commandBuffer, *v.renderPass, *v.frameBuffer->buffer, v.renderArea, m_clearColor);
2143         m_vki.cmdDraw           (*v.commandBuffer, v.vertexCount, 1, 0, 0);
2144         vk::endRenderPass       (m_vki, *v.commandBuffer);
2145
2146         return (iterateCommandEnd(v) ? tcu::TestStatus::pass : tcu::TestStatus::fail)("");
2147 }
2148
2149 class DynamicStorageBufferInstance : public DynamicBuffersInstance, public StorageBufferInstance
2150 {
2151 public:
2152         DynamicStorageBufferInstance                                                                    (Context&                                       context,
2153                                                                                                                                          const TestCaseParams&          testCaseParams);
2154         tcu::TestStatus         iterate                                                                         (void);
2155         void                            createAndPopulateDescriptors                            (IterateCommonVariables&        variables);
2156         void                            updateDescriptors                                                       (IterateCommonVariables&        variables);
2157         bool                            verifyVertexWriteResults                                        (IterateCommonVariables&        variables);
2158 };
2159
2160 DynamicStorageBufferInstance::DynamicStorageBufferInstance                      (Context&                                       context,
2161                                                                                                                                          const TestCaseParams&          testCaseParams)
2162         : CommonDescriptorInstance(context,
2163                 TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
2164                         VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC,
2165                         BINDING_StorageBufferDynamic,
2166                         VK_DESCRIPTOR_TYPE_UNDEFINED,
2167                         BINDING_Undefined,
2168                         false,
2169                         performWritesInVertex(testCaseParams.descriptorType, context),
2170                         testCaseParams)),
2171                         DynamicBuffersInstance(context, m_testParams), StorageBufferInstance(context, testCaseParams)
2172 {
2173 }
2174
2175 tcu::TestStatus DynamicStorageBufferInstance::iterate(void)
2176 {
2177         return DynamicBuffersInstance::iterate();
2178 }
2179
2180 void DynamicStorageBufferInstance::createAndPopulateDescriptors(IterateCommonVariables&                 variables)
2181 {
2182         StorageBufferInstance::createAndPopulateDescriptors(variables);
2183 }
2184
2185 void DynamicStorageBufferInstance::updateDescriptors(IterateCommonVariables&                                    variables)
2186 {
2187         DynamicBuffersInstance::updateDescriptors(variables);
2188 }
2189
2190 bool DynamicStorageBufferInstance::verifyVertexWriteResults(IterateCommonVariables&                             variables)
2191 {
2192         return StorageBufferInstance::verifyVertexWriteResults(variables);
2193 }
2194
2195 class DynamicUniformBufferInstance : public DynamicBuffersInstance, public UniformBufferInstance
2196 {
2197 public:
2198         DynamicUniformBufferInstance                                                                    (Context&                                       context,
2199                                                                                                                                          const TestCaseParams&          testCaseParams);
2200         tcu::TestStatus         iterate(void);
2201         void                            createAndPopulateDescriptors(IterateCommonVariables&                                    variables);
2202         void                            updateDescriptors(IterateCommonVariables&                                                               variables);
2203 };
2204
2205 DynamicUniformBufferInstance::DynamicUniformBufferInstance                      (Context&                                       context,
2206                                                                                                                                          const TestCaseParams&          testCaseParams)
2207         : CommonDescriptorInstance(context,
2208                 TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
2209                         VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
2210                         BINDING_UniformBufferDynamic,
2211                         VK_DESCRIPTOR_TYPE_UNDEFINED,
2212                         BINDING_Undefined,
2213                         false,
2214                         performWritesInVertex(testCaseParams.descriptorType, context),
2215                         testCaseParams)),
2216                         DynamicBuffersInstance(context, m_testParams), UniformBufferInstance(context, testCaseParams)
2217 {
2218 }
2219
2220 tcu::TestStatus DynamicUniformBufferInstance::iterate(void)
2221 {
2222         return DynamicBuffersInstance::iterate();
2223 }
2224
2225 void DynamicUniformBufferInstance::createAndPopulateDescriptors(IterateCommonVariables&                 variables)
2226 {
2227         UniformBufferInstance::createAndPopulateDescriptors(variables);
2228 }
2229
2230 void DynamicUniformBufferInstance::updateDescriptors(IterateCommonVariables&                                    variables)
2231 {
2232         DynamicBuffersInstance::updateDescriptors(variables);
2233 }
2234
2235 class InputAttachmentInstance : public CommonDescriptorInstance
2236 {
2237 public:
2238                                                                 InputAttachmentInstance                         (Context&                                                                       context,
2239                                                                                                                                         const TestCaseParams&                                           testCaseParams);
2240 private:
2241         virtual Move<VkRenderPass>      createRenderPass                                        (const IterateCommonVariables&                          variables);
2242         virtual void                            createFramebuffer                                       (ut::FrameBufferSp&                                                     frameBuffer,
2243                                                                                                                                          VkRenderPass                                                           renderPass,
2244                                                                                                                                          const IterateCommonVariables&                          variables);
2245         virtual void                            createAndPopulateDescriptors            (IterateCommonVariables&                                        variables);
2246 };
2247
2248 InputAttachmentInstance::InputAttachmentInstance                                        (Context&                                                                       context,
2249                                                                                                                                          const TestCaseParams&                                          testCaseParams)
2250         : CommonDescriptorInstance(context,
2251                 TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
2252                         VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2253                         BINDING_InputAttachment,
2254                         VK_DESCRIPTOR_TYPE_UNDEFINED,
2255                         BINDING_Undefined,
2256                         true,
2257                         performWritesInVertex(testCaseParams.descriptorType, context),
2258                         testCaseParams))
2259 {
2260 }
2261
2262 void InputAttachmentInstance::createAndPopulateDescriptors                      (IterateCommonVariables&                                        variables)
2263 {
2264         createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer,
2265                 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, m_testParams.frameResolution, m_colorFormat, VK_IMAGE_LAYOUT_UNDEFINED, variables.validDescriptorCount);
2266         createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, m_colorFormat);
2267
2268         for (deUint32 descriptorIdx = 0; descriptorIdx < variables.validDescriptorCount; ++descriptorIdx)
2269         {
2270                 const float                                             component       = m_colorScheme[descriptorIdx % m_schemeSize];
2271                 const tcu::PixelBufferAccess    pa                      = getPixelAccess(descriptorIdx, m_testParams.frameResolution, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer);
2272                 tcu::clear(pa, tcu::Vec4(component, component, component, 1.0f));
2273         }
2274         vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
2275 }
2276
2277 Move<VkRenderPass> InputAttachmentInstance::createRenderPass            (const IterateCommonVariables&                          variables)
2278 {
2279         std::vector<VkAttachmentDescription>    attachmentDescriptions;
2280         std::vector<VkAttachmentReference>              inputAttachmentRefs;
2281
2282         const VkAttachmentDescription   colorAttachmentDescription =
2283         {
2284                 (VkAttachmentDescriptionFlags)0,                        // VkAttachmentDescriptionFlags         flags;
2285                 m_colorFormat,                                                          // VkFormat                                                     format;
2286                 VK_SAMPLE_COUNT_1_BIT,                                          // VkSampleCountFlagBits                        samples;
2287                 VK_ATTACHMENT_LOAD_OP_CLEAR,                            // VkAttachmentLoadOp                           loadOp;
2288                 VK_ATTACHMENT_STORE_OP_STORE,                           // VkAttachmentStoreOp                          storeOp;
2289                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                        // VkAttachmentLoadOp                           stencilLoadOp;
2290                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                       // VkAttachmentStoreOp                          stencilStoreOp;
2291                 VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout                                        initialLayout;
2292                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                                        finalLayout;
2293         };
2294         const VkAttachmentReference             colorAttachmentRef =
2295         {
2296                 0u,                                                                                             // deUint32                                                     attachment;
2297                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                // VkImageLayout                                        layout;
2298         };
2299         attachmentDescriptions.push_back(colorAttachmentDescription);
2300
2301         // build input atachments
2302         {
2303                 const deUint32 inputCount = static_cast<deUint32>(variables.descriptorImageViews.size());
2304                 for (deUint32 inputIdx = 0; inputIdx < inputCount; ++inputIdx)
2305                 {
2306                         const VkAttachmentDescription   inputAttachmentDescription =
2307                         {
2308                                 VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT,                // VkAttachmentDescriptionFlags         flags;
2309                                 variables.descriptorsImages[inputIdx]->format,  // VkFormat                                                     format;
2310                                 VK_SAMPLE_COUNT_1_BIT,                                                  // VkSampleCountFlagBits                        samples;
2311                                 VK_ATTACHMENT_LOAD_OP_LOAD,                                             // VkAttachmentLoadOp                           loadOp;
2312                                 VK_ATTACHMENT_STORE_OP_STORE,                                   // VkAttachmentStoreOp                          storeOp;
2313                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                // VkAttachmentLoadOp                           stencilLoadOp;
2314                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                               // VkAttachmentStoreOp                          stencilStoreOp;
2315                                 VK_IMAGE_LAYOUT_GENERAL,                                                // VkImageLayout                                        initialLayout;
2316                                 VK_IMAGE_LAYOUT_GENERAL                                                 // VkImageLayout                                        finalLayout;
2317                         };
2318
2319                         const VkAttachmentReference             inputAttachmentRef =
2320                         {
2321                                 inputIdx + 1,                                                           // deUint32                                                     attachment;
2322                                 VK_IMAGE_LAYOUT_GENERAL                                         // VkImageLayout                                        layout;
2323                         };
2324
2325                         inputAttachmentRefs.push_back(inputAttachmentRef);
2326                         attachmentDescriptions.push_back(inputAttachmentDescription);
2327                 }
2328         }
2329
2330         const VkSubpassDescription              subpassDescription =
2331         {
2332                 (VkSubpassDescriptionFlags)0,                                           // VkSubpassDescriptionFlags            flags;
2333                 VK_PIPELINE_BIND_POINT_GRAPHICS,                                        // VkPipelineBindPoint                          pipelineBindPoint;
2334                 static_cast<deUint32>(inputAttachmentRefs.size()),      // deUint32                                                     inputAttachmentCount;
2335                 inputAttachmentRefs.data(),                                                     // const VkAttachmentReference*         pInputAttachments;
2336                 1u,                                                                                                     // deUint32                                                     colorAttachmentCount;
2337                 &colorAttachmentRef,                                                            // const VkAttachmentReference*         pColorAttachments;
2338                 DE_NULL,                                                                                        // const VkAttachmentReference*         pResolveAttachments;
2339                 DE_NULL,                                                                                        // const VkAttachmentReference*         pDepthStencilAttachment;
2340                 0u,                                                                                                     // deUint32                                                     preserveAttachmentCount;
2341                 DE_NULL                                                                                         // const deUint32*                                      pPreserveAttachments;
2342         };
2343
2344         const VkRenderPassCreateInfo    renderPassInfo =
2345         {
2346                 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                              // VkStructureType                                      sType;
2347                 DE_NULL,                                                                                                // const void*                                          pNext;
2348                 (VkRenderPassCreateFlags)0,                                                             // VkRenderPassCreateFlags                      flags;
2349                 static_cast<deUint32>(attachmentDescriptions.size()),   // deUint32                                                     attachmentCount;
2350                 attachmentDescriptions.data(),                                                  // const VkAttachmentDescription*       pAttachments;
2351                 1u,                                                                                                             // deUint32                                                     subpassCount;
2352                 &subpassDescription,                                                                    // const VkSubpassDescription*          pSubpasses;
2353                 0u,                                                                                                             // deUint32                                                     dependencyCount;
2354                 DE_NULL                                                                                                 // const VkSubpassDependency*           pDependencies;
2355         };
2356
2357         return vk::createRenderPass(m_vki, m_vkd, &renderPassInfo);
2358 }
2359
2360 void InputAttachmentInstance::createFramebuffer                                         (ut::FrameBufferSp&                                                     frameBuffer,
2361                                                                                                                                          VkRenderPass                                                           renderPass,
2362                                                                                                                                          const IterateCommonVariables&                          variables)
2363 {
2364         std::vector<VkImageView>                        inputAttachments;
2365         const deUint32 viewCount = static_cast<deUint32>(variables.descriptorImageViews.size());
2366         inputAttachments.resize(viewCount);
2367         for (deUint32 viewIdx = 0; viewIdx < viewCount; ++viewIdx)
2368         {
2369                 inputAttachments[viewIdx] = **variables.descriptorImageViews[viewIdx];
2370         }
2371         ut::createFrameBuffer(frameBuffer, m_context, m_testParams.frameResolution, m_colorFormat, renderPass, viewCount, inputAttachments.data());
2372 }
2373
2374 class SamplerInstance : public CommonDescriptorInstance
2375 {
2376 public:
2377                                                                 SamplerInstance                                         (Context&                                                                       context,
2378                                                                                                                                          const TestCaseParams&                                          testCaseParams);
2379 private:
2380         virtual void                            createAndPopulateDescriptors            (IterateCommonVariables&                                        variables);
2381         virtual void                            updateDescriptors                                       (IterateCommonVariables&                                        variables);
2382 };
2383
2384 SamplerInstance::SamplerInstance                                                                        (Context&                                                                       context,
2385                                                                                                                                          const TestCaseParams&                                          testCaseParams)
2386         : CommonDescriptorInstance(context,
2387                 TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
2388                         VK_DESCRIPTOR_TYPE_SAMPLER,
2389                         BINDING_Sampler,
2390                         VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
2391                         BINDING_SampledImage,
2392                         true,
2393                         performWritesInVertex(testCaseParams.descriptorType, context),
2394                         testCaseParams))
2395 {
2396 }
2397
2398 void SamplerInstance::updateDescriptors                                                         (IterateCommonVariables&                                        variables)
2399 {
2400         DE_ASSERT(variables.descriptorsImages.size()            == 1);
2401         DE_ASSERT(variables.descriptorImageViews.size()         == 1);
2402         DE_ASSERT(variables.descriptorsBufferInfos.size()       == 1);
2403         DE_ASSERT(m_testParams.additionalDescriptorType         == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
2404         DE_ASSERT(variables.descriptorSamplers.size()           == variables.validDescriptorCount);
2405
2406         // update an image
2407         {
2408                 const VkDescriptorImageInfo imageInfo =
2409                 {
2410                         static_cast<VkSampler>(0),
2411                         **variables.descriptorImageViews[0],
2412                         VK_IMAGE_LAYOUT_GENERAL
2413                 };
2414
2415                 const VkWriteDescriptorSet writeInfo =
2416                 {
2417                         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,                 // sType
2418                         DE_NULL,                                                                                // pNext
2419                         *variables.descriptorSet,                                               // descriptorSet
2420                         BINDING_SampledImage,                                                   // descriptorBinding;
2421                         0,                                                                                              // elementIndex
2422                         1u,                                                                                             // descriptorCount
2423                         VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,                               // descriptorType
2424                         &imageInfo,                                                                             // pImageInfo
2425                         DE_NULL,                                                                                // pBufferInfo
2426                         DE_NULL                                                                                 // pTexelBufferView
2427                 };
2428
2429                 m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, DE_NULL);
2430         }
2431
2432         // update samplers
2433         CommonDescriptorInstance::updateDescriptors(variables);
2434 }
2435
2436 void SamplerInstance::createAndPopulateDescriptors                                      (IterateCommonVariables&                                        variables)
2437 {
2438         DE_ASSERT(variables.descriptorsImages.size()            == 0);
2439         DE_ASSERT(variables.descriptorImageViews.size()         == 0);
2440         DE_ASSERT(variables.descriptorsBufferInfos.size()       == 0);
2441         DE_ASSERT(variables.descriptorSamplers.size()           == 0);
2442
2443         // create and populate an image
2444         {
2445                 VkExtent3D imageExtent = m_testParams.frameResolution;
2446                 if (m_testParams.usesMipMaps)
2447                 {
2448                         imageExtent.width *= 2;
2449                         imageExtent.height *= 2;
2450                 };
2451
2452                 createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer,
2453                         VK_BUFFER_USAGE_TRANSFER_SRC_BIT, imageExtent, m_colorFormat, VK_IMAGE_LAYOUT_UNDEFINED, 1, m_testParams.usesMipMaps);
2454                 createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, m_colorFormat);
2455
2456                 PixelBufferAccess pa = getPixelAccess(0, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, m_testParams.usesMipMaps ? 1 : 0);
2457
2458                 for (deUint32 y = 0, pixelNum = 0; y < m_testParams.frameResolution.height; ++y)
2459                 {
2460                         for (deUint32 x = 0; x < m_testParams.frameResolution.width; ++x, ++pixelNum)
2461                         {
2462                                 const float             component       = m_colorScheme[(pixelNum % variables.validDescriptorCount) % m_schemeSize];
2463                                 pa.setPixel(tcu::Vec4(component, component, component, 1.0f), x, y);
2464                         }
2465                 }
2466
2467                 vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
2468         }
2469
2470         const tcu::Sampler sampler(
2471                 tcu::Sampler::CLAMP_TO_BORDER,                                                                                                                  // wrapS
2472                 tcu::Sampler::CLAMP_TO_BORDER,                                                                                                                  // wrapT
2473                 tcu::Sampler::CLAMP_TO_BORDER,                                                                                                                  // wrapR
2474                 m_testParams.usesMipMaps ? tcu::Sampler::LINEAR_MIPMAP_NEAREST : tcu::Sampler::NEAREST, // minFilter
2475                 m_testParams.usesMipMaps ? tcu::Sampler::LINEAR_MIPMAP_NEAREST : tcu::Sampler::NEAREST, // magFilter
2476                 0.0f,                                                                                                                                                                   // lodTreshold
2477                 true);                                                                                                                                                                  // normalizeCoords
2478         const VkSamplerCreateInfo createInfo = vk::mapSampler(sampler, vk::mapVkFormat(m_colorFormat));
2479         variables.descriptorSamplers.resize(variables.validDescriptorCount);
2480
2481         for (deUint32 samplerIdx = 0; samplerIdx < variables.validDescriptorCount; ++samplerIdx)
2482         {
2483                 variables.descriptorSamplers[samplerIdx] = ut::SamplerSp(new Move<VkSampler>(vk::createSampler(m_vki, m_vkd, &createInfo)));
2484         }
2485 }
2486
2487 class SampledImageInstance : public CommonDescriptorInstance
2488 {
2489 public:
2490                                                                 SampledImageInstance                            (Context&                                                                       context,
2491                                                                                                                                          const TestCaseParams&                                          testCaseParams);
2492 private:
2493         virtual void                            createAndPopulateDescriptors            (IterateCommonVariables&                                        variables);
2494         virtual void                            updateDescriptors                                       (IterateCommonVariables&                                        variables);
2495 };
2496
2497 SampledImageInstance::SampledImageInstance                                                      (Context&                                                                       context,
2498                                                                                                                                          const TestCaseParams&                                          testCaseParams)
2499         : CommonDescriptorInstance(context,
2500                 TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
2501                         VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
2502                         BINDING_SampledImage,
2503                         VK_DESCRIPTOR_TYPE_SAMPLER,
2504                         BINDING_Sampler,
2505                         true,
2506                         performWritesInVertex(testCaseParams.descriptorType, context),
2507                         testCaseParams))
2508 {
2509 }
2510
2511 void SampledImageInstance::updateDescriptors                                            (IterateCommonVariables&                                        variables)
2512 {
2513         DE_ASSERT(variables.descriptorSamplers.size()           == 1);
2514         DE_ASSERT(variables.descriptorsImages.size()            == variables.validDescriptorCount);
2515         DE_ASSERT(variables.descriptorImageViews.size()         == variables.validDescriptorCount);
2516         DE_ASSERT(variables.descriptorsBufferInfos.size()       == variables.validDescriptorCount);
2517
2518         // update a sampler
2519         {
2520                 const VkDescriptorImageInfo samplerInfo =
2521                 {
2522                         **variables.descriptorSamplers[0],
2523                         static_cast<VkImageView>(0),
2524                         static_cast<VkImageLayout>(0)
2525                 };
2526
2527                 const VkWriteDescriptorSet writeInfo =
2528                 {
2529                         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,                 // sType
2530                         DE_NULL,                                                                                // pNext
2531                         *variables.descriptorSet,                                               // descriptorSet
2532                         BINDING_Sampler,                                                                // descriptorBinding;
2533                         0,                                                                                              // elementIndex
2534                         1u,                                                                                             // descriptorCount
2535                         VK_DESCRIPTOR_TYPE_SAMPLER,                                             // descriptorType
2536                         &samplerInfo,                                                                   // pImageInfo
2537                         DE_NULL,                                                                                // pBufferInfo
2538                         DE_NULL                                                                                 // pTexelBufferView
2539                 };
2540
2541                 m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, DE_NULL);
2542         }
2543
2544         // update images
2545         CommonDescriptorInstance::updateDescriptors(variables);
2546 }
2547
2548 void SampledImageInstance::createAndPopulateDescriptors                         (IterateCommonVariables&                                        variables)
2549 {
2550         DE_ASSERT(variables.descriptorSamplers.size()           == 0);
2551         DE_ASSERT(variables.descriptorsImages.size()            == 0);
2552         DE_ASSERT(variables.descriptorImageViews.size()         == 0);
2553         DE_ASSERT(variables.descriptorsBufferInfos.size()       == 0);
2554
2555         // create an only one sampler for all images
2556         {
2557                 const tcu::Sampler sampler(
2558                         tcu::Sampler::CLAMP_TO_BORDER,                                                                                                                          // wrapS
2559                         tcu::Sampler::CLAMP_TO_BORDER,                                                                                                                          // wrapT
2560                         tcu::Sampler::CLAMP_TO_BORDER,                                                                                                                          // wrapR
2561                         m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST,        // minFilter
2562                         m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST,        // magFilter
2563                         0.0f,                                                                                                                                                                           // lodTreshold
2564                         true);                                                                                                                                                                          // normalizeCoords
2565                 const VkSamplerCreateInfo createInfo = vk::mapSampler(sampler, vk::mapVkFormat(m_colorFormat));
2566                 variables.descriptorSamplers.push_back(ut::SamplerSp(new Move<VkSampler>(vk::createSampler(m_vki, m_vkd, &createInfo))));
2567         }
2568
2569         const VkExtent3D&                       imageExtent = m_testParams.usesMipMaps ? bigImageExtent : smallImageExtent;
2570
2571         createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer,
2572                 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, imageExtent, m_colorFormat, VK_IMAGE_LAYOUT_UNDEFINED, variables.validDescriptorCount, m_testParams.usesMipMaps);
2573         createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, m_colorFormat);
2574
2575         PixelBufferAccess                       pixelAccess;
2576         for (deUint32 imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
2577         {
2578                 const float                             component       = m_colorScheme[imageIdx % m_schemeSize];
2579
2580                 if (m_testParams.usesMipMaps)
2581                 {
2582                         const deUint32 mipCount = ut::computeMipMapCount(imageExtent);
2583                         DE_ASSERT(mipCount >= 2);
2584                         for (deUint32 mipIdx = 0; mipIdx < mipCount; ++mipIdx)
2585                         {
2586                                 pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, mipIdx);
2587                                 tcu::clear(pixelAccess, m_clearColor);
2588                         }
2589
2590                         pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, mipCount-1);
2591                         pixelAccess.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
2592                 }
2593                 else
2594                 {
2595                         pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, 0);
2596                         pixelAccess.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
2597                 }
2598         }
2599         vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
2600 }
2601
2602 class CombinedImageInstance : public CommonDescriptorInstance
2603 {
2604 public:
2605                                                                 CombinedImageInstance                           (Context&                                                                       context,
2606                                                                                                                                          const TestCaseParams&                                          testCaseParams);
2607 private:
2608         virtual void                            createAndPopulateDescriptors            (IterateCommonVariables&                                        variables);
2609         virtual void                            updateDescriptors                                       (IterateCommonVariables&                                        variables);
2610 };
2611
2612 CombinedImageInstance::CombinedImageInstance                                            (Context&                                                                       context,
2613                                                                                                                                          const TestCaseParams&                                          testCaseParams)
2614         : CommonDescriptorInstance(context,
2615                 TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
2616                         testCaseParams.descriptorType,
2617                         BINDING_CombinedImageSampler,
2618                         VK_DESCRIPTOR_TYPE_UNDEFINED,
2619                         BINDING_Undefined,
2620                         true,
2621                         performWritesInVertex(testCaseParams.descriptorType),
2622                         testCaseParams))
2623 {
2624 }
2625
2626 void CombinedImageInstance::updateDescriptors                                           (IterateCommonVariables&                                        variables)
2627 {
2628         const std::vector<deUint32>     primes = ut::generatePrimes(variables.availableDescriptorCount);
2629         const deUint32                          primeCount = static_cast<deUint32>(primes.size());
2630
2631         DE_ASSERT(variables.descriptorSamplers.size()           == 1);
2632         DE_ASSERT(variables.descriptorsImages.size()            == primeCount);
2633         DE_ASSERT(variables.descriptorImageViews.size()         == primeCount);
2634         DE_ASSERT(variables.descriptorsBufferInfos.size()       == primeCount);
2635
2636         for (deUint32 primeIdx = 0; primeIdx < primeCount; ++primeIdx)
2637         {
2638                 const VkDescriptorImageInfo imageInfo =
2639                 {
2640                         **variables.descriptorSamplers[0],
2641                         **variables.descriptorImageViews[primeIdx],
2642                         VK_IMAGE_LAYOUT_GENERAL
2643                 };
2644
2645                 const VkWriteDescriptorSet writeInfo =
2646                 {
2647                         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,                 // sType
2648                         DE_NULL,                                                                                // pNext
2649                         *variables.descriptorSet,                                               // descriptorSet
2650                         BINDING_CombinedImageSampler,                                   // descriptorBinding;
2651                         primes[primeIdx],                                                               // elementIndex
2652                         1u,                                                                                             // descriptorCount
2653                         m_testParams.descriptorType,                                    // descriptorType
2654                         &imageInfo,                                                                             // pImageInfo
2655                         DE_NULL,                                                                                // pBufferInfo
2656                         DE_NULL                                                                                 // pTexelBufferView
2657                 };
2658
2659                 m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, DE_NULL);
2660         }
2661 }
2662
2663 void CombinedImageInstance::createAndPopulateDescriptors                        (IterateCommonVariables&                                        variables)
2664 {
2665         DE_ASSERT(variables.descriptorSamplers.size()           == 0);
2666         DE_ASSERT(variables.descriptorsImages.size()            == 0);
2667         DE_ASSERT(variables.descriptorImageViews.size()         == 0);
2668         DE_ASSERT(variables.descriptorsBufferInfos.size()       == 0);
2669         DE_ASSERT(variables.descriptorSamplers.size()           == 0);
2670
2671         const tcu::Sampler sampler(
2672                 tcu::Sampler::CLAMP_TO_BORDER,                                                                                                                          // wrapS
2673                 tcu::Sampler::CLAMP_TO_BORDER,                                                                                                                          // wrapT
2674                 tcu::Sampler::CLAMP_TO_BORDER,                                                                                                                          // wrapR
2675                 m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST,        // minFilter
2676                 m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST,        // magFilter
2677                 0.0f,                                                                                                                                                                           // lodTreshold
2678                 true);                                                                                                                                                                          // normalizeCoords
2679         const VkSamplerCreateInfo       createInfo = vk::mapSampler(sampler, vk::mapVkFormat(m_colorFormat));
2680         variables.descriptorSamplers.push_back(ut::SamplerSp(new Move<VkSampler>(vk::createSampler(m_vki, m_vkd, &createInfo))));
2681
2682         const VkExtent3D&                       imageExtent = m_testParams.usesMipMaps ? bigImageExtent : smallImageExtent;
2683         createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
2684                 imageExtent, m_colorFormat, VK_IMAGE_LAYOUT_UNDEFINED, variables.validDescriptorCount, m_testParams.usesMipMaps);
2685         createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, m_colorFormat);
2686
2687         PixelBufferAccess                       pixelAccess;
2688         for (deUint32 imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
2689         {
2690                 const float                             component = m_colorScheme[imageIdx % m_schemeSize];
2691
2692                 if (m_testParams.usesMipMaps)
2693                 {
2694                         const deUint32  mipCount = ut::computeMipMapCount(imageExtent);
2695                         DE_ASSERT(mipCount >= 2);
2696                         for (deUint32 mipIdx = 0; mipIdx < mipCount; ++mipIdx)
2697                         {
2698                                 pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, mipIdx);
2699                                 tcu::clear(pixelAccess, m_clearColor);
2700                         }
2701
2702                         pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, mipCount-1);
2703                         pixelAccess.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
2704                 }
2705                 else
2706                 {
2707                         pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, 0);
2708                         pixelAccess.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
2709                 }
2710         }
2711
2712         vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
2713 }
2714
2715 class StorageImageInstance : public CommonDescriptorInstance
2716 {
2717 public:
2718                                                                 StorageImageInstance                            (Context&                                                                       context,
2719                                                                                                                                          const TestCaseParams&                                          testCaseParams);
2720 private:
2721         virtual tcu::TestStatus         iterate                                                         (void);
2722         virtual void                            createAndPopulateDescriptors            (IterateCommonVariables&                                        variables);
2723         virtual void                            updateDescriptors                                       (IterateCommonVariables&                                        variables);
2724         virtual void                            iterateCollectResults                           (ut::UpdatablePixelBufferAccessPtr&                     result,
2725                                                                                                                                          const IterateCommonVariables&                          variables,
2726                                                                                                                                          bool                                                                           fromTest);
2727         ut::BufferHandleAllocSp         m_buffer;
2728         const deUint32                          m_fillColor;
2729         typedef deUint32                        m_imageFormat_t;
2730 };
2731
2732 StorageImageInstance::StorageImageInstance                                                      (Context&                                                                       context,
2733                                                                                                                                          const TestCaseParams&                                          testCaseParams)
2734         : CommonDescriptorInstance(context,
2735                 TestParams      (VK_SHADER_STAGE_COMPUTE_BIT,
2736                                         VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
2737                                         BINDING_StorageImage,
2738                                         VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
2739                                         (BINDING_StorageImage + 1),
2740                                         true,
2741                                         performWritesInVertex(testCaseParams.descriptorType, context),
2742                                         testCaseParams))
2743         , m_buffer              ()
2744         , m_fillColor   (10)
2745 {
2746 }
2747
2748 void StorageImageInstance::updateDescriptors                                            (IterateCommonVariables&                                        variables)
2749 {
2750         // update image at last index
2751         {
2752                 VkDescriptorImageInfo           imageInfo =
2753                 {
2754                         static_cast<VkSampler>(0),
2755                         **variables.descriptorImageViews[variables.validDescriptorCount],
2756                         VK_IMAGE_LAYOUT_GENERAL
2757                 };
2758
2759                 const VkWriteDescriptorSet writeInfo =
2760                 {
2761                         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,         // sType
2762                         DE_NULL,                                                                        // pNext
2763                         *variables.descriptorSet,                                       // descriptorSet
2764                         m_testParams.additionalDescriptorBinding,       // descriptorBinding;
2765                         0,                                                                                      // elementIndex
2766                         1u,                                                                                     // descriptorCount
2767                         m_testParams.additionalDescriptorType,          // descriptorType
2768                         &imageInfo,                                                                     // pImageInfo
2769                         DE_NULL,                                                                        // pBufferInfo
2770                         DE_NULL                                                                         // pTexelBufferView
2771                 };
2772
2773                 m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, DE_NULL);
2774         }
2775
2776         // update rest images
2777         CommonDescriptorInstance::updateDescriptors(variables);
2778 }
2779
2780 void StorageImageInstance::createAndPopulateDescriptors                         (IterateCommonVariables&                                        variables)
2781 {
2782         const VkFormat                          imageFormat = ut::mapType2vkFormat<m_imageFormat_t>::value;
2783         const VkBufferUsageFlags        bufferUsage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
2784
2785         // create descriptor buffer, images and views
2786         {
2787                 const VkExtent3D                        imageExtent = { 4, 4, 1 };
2788
2789                 createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer,
2790                         bufferUsage, imageExtent, imageFormat, VK_IMAGE_LAYOUT_UNDEFINED, variables.validDescriptorCount);
2791
2792                 for (deUint32 imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
2793                 {
2794                         const PixelBufferAccess pa = getPixelAccess(imageIdx, imageExtent, imageFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer);
2795                         tcu::clear(pa, tcu::UVec4(m_fillColor));
2796                 }
2797                 vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
2798         }
2799
2800         // create additional image that will be used as index container
2801         {
2802                 createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, m_buffer,
2803                         bufferUsage, m_testParams.frameResolution, imageFormat, VK_IMAGE_LAYOUT_UNDEFINED, 1);
2804
2805                 // populate buffer
2806                 const std::vector<deUint32>     primes = ut::generatePrimes(variables.availableDescriptorCount);
2807                 const PixelBufferAccess pa = getPixelAccess(variables.validDescriptorCount, m_testParams.frameResolution, imageFormat, variables.descriptorsBufferInfos, m_buffer);
2808                 for (deUint32 y = 0, pixel = 0; y < m_testParams.frameResolution.height; ++y)
2809                 {
2810                         for (deUint32 x = 0; x < m_testParams.frameResolution.width; ++x, ++pixel)
2811                         {
2812                                 const deUint32 component = primes[pixel % variables.validDescriptorCount];
2813                                 pa.setPixel(tcu::UVec4(component), x, y);
2814                         }
2815                 }
2816
2817                 // save changes
2818                 vk::flushAlloc(m_vki, m_vkd, *m_buffer->alloc);
2819         }
2820
2821         // create views for all previously created images
2822         createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, imageFormat);
2823 }
2824
2825 tcu::TestStatus StorageImageInstance::iterate                                           (void)
2826 {
2827         IterateCommonVariables  v;
2828         iterateCommandBegin             (v);
2829
2830         if (m_testParams.updateAfterBind)
2831         {
2832                 updateDescriptors       (v);
2833         }
2834
2835         copyBuffersToImages             (v);
2836
2837         m_vki.cmdDispatch               (*v.commandBuffer,
2838                                                         m_testParams.calculateInLoop ? 1 : v.renderArea.extent.width,
2839                                                         m_testParams.calculateInLoop ? 1 : v.renderArea.extent.height,
2840                                                         1);
2841
2842         copyImagesToBuffers             (v);
2843
2844         return (iterateCommandEnd(v, false) ? tcu::TestStatus::pass : tcu::TestStatus::fail)("");
2845 }
2846
2847 void StorageImageInstance::iterateCollectResults                                        (ut::UpdatablePixelBufferAccessPtr&                     result,
2848                                                                                                                                          const IterateCommonVariables&                          variables,
2849                                                                                                                                          bool                                                                           fromTest)
2850 {
2851         result = ut::UpdatablePixelBufferAccessPtr(new ut::PixelBufferAccessAllocation(
2852                 vk::mapVkFormat(ut::mapType2vkFormat<m_imageFormat_t>::value), m_testParams.frameResolution));
2853         const PixelBufferAccess& dst = *result.get();
2854
2855         if (fromTest)
2856         {
2857                 vk::invalidateAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
2858                 for (deUint32 y = 0, pixelNum = 0; y < m_testParams.frameResolution.height; ++y)
2859                 {
2860                         for (deUint32 x = 0; x < m_testParams.frameResolution.width; ++x, ++pixelNum)
2861                         {
2862                                 const deUint32 imageIdx = pixelNum % variables.validDescriptorCount;
2863                                 const PixelBufferAccess src = getPixelAccess(imageIdx,
2864                                         variables.descriptorsImages[imageIdx]->extent, variables.descriptorsImages[imageIdx]->format,
2865                                         variables.descriptorsBufferInfos, variables.descriptorsBuffer);
2866                                 dst.setPixel(tcu::Vector<m_imageFormat_t, 4>(src.getPixelT<m_imageFormat_t>(0, 0).x()), x, y);
2867                         }
2868                 }
2869         }
2870         else
2871         {
2872                 std::vector<m_imageFormat_t> inc(variables.validDescriptorCount, m_fillColor);
2873
2874                 for (deUint32 invIdx = variables.lowerBound; invIdx < variables.upperBound; ++invIdx)
2875                 {
2876                         ++inc[invIdx % variables.validDescriptorCount];
2877                 }
2878
2879                 for (deUint32 invIdx = 0; invIdx < variables.vertexCount; ++invIdx)
2880                 {
2881                         const deUint32 row = invIdx / m_testParams.frameResolution.width;
2882                         const deUint32 col = invIdx % m_testParams.frameResolution.width;
2883                         const m_imageFormat_t color = inc[invIdx % variables.validDescriptorCount];
2884                         dst.setPixel(tcu::Vector<m_imageFormat_t, 4>(color), col, row);
2885                 }
2886         }
2887 }
2888
2889 class DescriptorIndexingTestCase : public TestCase
2890 {
2891         const TestCaseParams m_testCaseParams;
2892 public:
2893         DescriptorIndexingTestCase (tcu::TestContext &context, const char *name, const char *description, const TestCaseParams& testCaseParams)
2894                 : TestCase(context, name, description)
2895                 , m_testCaseParams(testCaseParams)
2896         {
2897         }
2898
2899         vkt::TestInstance* createInstance (vkt::Context& context) const // override
2900         {
2901                 switch (m_testCaseParams.descriptorType)
2902                 {
2903                 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2904                         return new StorageBufferInstance                (context, m_testCaseParams);
2905                 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
2906                         return new UniformBufferInstance                (context, m_testCaseParams);
2907                 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
2908                         return new StorageTexelInstance                 (context, m_testCaseParams);
2909                 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
2910                         return new UniformTexelInstance                 (context, m_testCaseParams);
2911                 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
2912                         return new DynamicStorageBufferInstance (context, m_testCaseParams);
2913                 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
2914                         return new DynamicUniformBufferInstance (context, m_testCaseParams);
2915                 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
2916                         return new InputAttachmentInstance              (context, m_testCaseParams);
2917                 case VK_DESCRIPTOR_TYPE_SAMPLER:
2918                         return new SamplerInstance                              (context, m_testCaseParams);
2919                 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
2920                         return new SampledImageInstance                 (context, m_testCaseParams);
2921                 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
2922                         return new CombinedImageInstance                (context, m_testCaseParams);
2923                 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
2924                         return new StorageImageInstance                 (context, m_testCaseParams);
2925                 default:
2926                         TCU_THROW(InternalError, "Unknown Descriptor Type");
2927                 }
2928                 return DE_NULL;
2929         }
2930
2931         virtual void checkSupport (vkt::Context& context) const
2932         {
2933                 context.requireDeviceExtension("VK_EXT_descriptor_indexing");
2934
2935                 const vk::VkPhysicalDeviceDescriptorIndexingFeaturesEXT& feats = context.getDescriptorIndexingFeatures();
2936
2937                 switch (m_testCaseParams.descriptorType)
2938                 {
2939                 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2940                         if (!(feats.shaderStorageBufferArrayNonUniformIndexing))
2941                                 TCU_THROW(NotSupportedError, "Non-uniform indexing over storage buffer descriptor arrays is not supported.");
2942
2943                         if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingStorageBufferUpdateAfterBind)
2944                                 TCU_THROW(NotSupportedError, "Update after bind for storage buffer descriptors is not supported.");
2945                         break;
2946                 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
2947                         if (!(feats.shaderUniformBufferArrayNonUniformIndexing))
2948                                 TCU_THROW(NotSupportedError, "Non-uniform indexing for uniform buffer descriptor arrays is not supported.");
2949
2950                         if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingUniformBufferUpdateAfterBind)
2951                                 TCU_THROW(NotSupportedError, "Update after bind for uniform buffer descriptors is not supported.");
2952                         break;
2953                 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
2954                         if (!(feats.shaderStorageTexelBufferArrayNonUniformIndexing))
2955                                 TCU_THROW(NotSupportedError, "Non-uniform indexing for storage texel buffer descriptor arrays is not supported.");
2956
2957                         if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingStorageTexelBufferUpdateAfterBind)
2958                                 TCU_THROW(NotSupportedError, "Update after bind for storage texel buffer descriptors is not supported.");
2959                         break;
2960                 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
2961                         if (!(feats.shaderUniformTexelBufferArrayNonUniformIndexing))
2962                                 TCU_THROW(NotSupportedError, "Non-uniform indexing for uniform texel buffer descriptor arrays is not supported.");
2963
2964                         if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingUniformTexelBufferUpdateAfterBind)
2965                                 TCU_THROW(NotSupportedError, "Update after bind for uniform texel buffer descriptors is not supported.");
2966                         break;
2967                 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
2968                         if (!(feats.shaderStorageBufferArrayNonUniformIndexing))
2969                                 TCU_THROW(NotSupportedError, "Non-uniform indexing over storage buffer dynamic descriptor arrays is not supported.");
2970
2971                         if (m_testCaseParams.updateAfterBind)
2972                                 TCU_THROW(NotSupportedError, "Update after bind for storage buffer dynamic descriptors is not supported.");
2973                         break;
2974                 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
2975                         if (!(feats.shaderUniformBufferArrayNonUniformIndexing))
2976                                 TCU_THROW(NotSupportedError, "Non-uniform indexing over uniform buffer dynamic descriptor arrays is not supported.");
2977
2978                         if (m_testCaseParams.updateAfterBind)
2979                                 TCU_THROW(NotSupportedError, "Update after bind for uniform buffer dynamic descriptors is not supported.");
2980                         break;
2981                 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
2982                         if (!(feats.shaderInputAttachmentArrayNonUniformIndexing))
2983                                 TCU_THROW(NotSupportedError, "Non-uniform indexing over input attachment descriptor arrays is not supported.");
2984
2985                         if (m_testCaseParams.updateAfterBind)
2986                                 TCU_THROW(NotSupportedError, "Update after bind for input attachment descriptors is not supported.");
2987                         break;
2988                 case VK_DESCRIPTOR_TYPE_SAMPLER:
2989                         if (!(feats.shaderSampledImageArrayNonUniformIndexing))
2990                                 TCU_THROW(NotSupportedError, "Non-uniform indexing over sampler descriptor arrays is not supported.");
2991
2992                         if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingSampledImageUpdateAfterBind)
2993                                 TCU_THROW(NotSupportedError, "Update after bind for sampler descriptors is not supported.");
2994                         break;
2995                 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
2996                         if (!(feats.shaderSampledImageArrayNonUniformIndexing))
2997                                 TCU_THROW(NotSupportedError, "Non-uniform indexing over sampled image descriptor arrays is not supported.");
2998
2999                         if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingSampledImageUpdateAfterBind)
3000                                 TCU_THROW(NotSupportedError, "Update after bind for sampled image descriptors is not supported.");
3001                         break;
3002                 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
3003                         if (!(feats.shaderSampledImageArrayNonUniformIndexing))
3004                                 TCU_THROW(NotSupportedError, "Non-uniform indexing over combined image sampler descriptor arrays is not supported.");
3005
3006                         if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingSampledImageUpdateAfterBind)
3007                                 TCU_THROW(NotSupportedError, "Update after bind for combined image sampler descriptors is not supported.");
3008                         break;
3009                 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
3010                         if (!(feats.shaderStorageImageArrayNonUniformIndexing))
3011                                 TCU_THROW(NotSupportedError, "Non-uniform indexing over storage image descriptor arrays is not supported.");
3012
3013                         if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingStorageImageUpdateAfterBind)
3014                                 TCU_THROW(NotSupportedError, "Update after bind for storage image descriptors is not supported.");
3015                         break;
3016                 default:
3017                         DE_FATAL("Unknown Descriptor Type");
3018                         break;
3019                 }
3020         }
3021
3022         virtual void initPrograms (SourceCollections& programCollection) const
3023         {
3024                 std::string(*genShaderSource)(VkShaderStageFlagBits, const TestCaseParams&, bool) = &CommonDescriptorInstance::getShaderSource;
3025
3026                 if (VK_SHADER_STAGE_VERTEX_BIT & m_testCaseParams.stageFlags)
3027                 {
3028                         programCollection.glslSources.add(
3029                                 ut::buildShaderName(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, false))
3030                                 << glu::VertexSource((*genShaderSource)(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams, false));
3031
3032                         if (CommonDescriptorInstance::performWritesInVertex(m_testCaseParams.descriptorType))
3033                         {
3034                                 programCollection.glslSources.add(
3035                                         ut::buildShaderName(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, true))
3036                                         << glu::VertexSource((*genShaderSource)(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams, true));
3037                         }
3038                 }
3039                 if (VK_SHADER_STAGE_FRAGMENT_BIT & m_testCaseParams.stageFlags)
3040                 {
3041                         programCollection.glslSources.add(
3042                                 ut::buildShaderName(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, false))
3043                                 << glu::FragmentSource((*genShaderSource)(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams, false));
3044
3045                         if (CommonDescriptorInstance::performWritesInVertex(m_testCaseParams.descriptorType))
3046                         {
3047                                 programCollection.glslSources.add(
3048                                         ut::buildShaderName(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, true))
3049                                         << glu::FragmentSource((*genShaderSource)(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams, true));
3050                         }
3051                 }
3052                 if (VK_SHADER_STAGE_COMPUTE_BIT & m_testCaseParams.stageFlags)
3053                 {
3054                         programCollection.glslSources.add(
3055                                 ut::buildShaderName(VK_SHADER_STAGE_COMPUTE_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, false))
3056                                 << glu::ComputeSource((*genShaderSource)(VK_SHADER_STAGE_COMPUTE_BIT, m_testCaseParams, false));
3057                 }
3058         }
3059 };
3060
3061 } // - unnamed namespace
3062
3063 void descriptorIndexingDescriptorSetsCreateTests (tcu::TestCaseGroup* group)
3064 {
3065         struct TestCaseInfo
3066         {
3067                 const char*             name;
3068                 const char*             description;
3069                 TestCaseParams  params;
3070         };
3071
3072         tcu::TestContext&                               context(group->getTestContext());
3073
3074         TestCaseInfo casesAfterBindAndLoop[] =
3075         {
3076                 {
3077                         "storage_buffer", "Regular Storage Buffer Descriptors",
3078                         {
3079                                 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
3080                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
3081                                 RESOLUTION,
3082                                 false,  // updateAfterBind
3083                                 false,  // calculateInLoop
3084                                 false,  // useMipMaps
3085                                 FUZZY_COMPARE, CMP_THRESHOLD
3086                         }
3087                 },
3088                 {
3089                         "storage_texel_buffer", "Storage Texel Buffer Descriptors",
3090                         {
3091                                 VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
3092                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
3093                                 RESOLUTION,
3094                                 false,  // updateAfterBind
3095                                 false,  // calculateInLoop
3096                                 false,  // useMipMaps
3097                                 FUZZY_COMPARE, CMP_THRESHOLD
3098                         }
3099                 },
3100                 {
3101                         "uniform_texel_buffer", "Uniform Texel Buffer Descriptors",
3102                         {
3103                                 VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
3104                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
3105                                 RESOLUTION,
3106                                 false,  // updateAfterBind,
3107                                 false,  // calculateInLoop
3108                                 false,  // usesMipMaps
3109                                 FUZZY_COMPARE, CMP_THRESHOLD
3110                         }
3111                 },
3112                 {
3113                         "storage_image", "Storage Image Descriptors",
3114                         {
3115                                 VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
3116                                 VK_SHADER_STAGE_COMPUTE_BIT,
3117                                 RESOLUTION,
3118                                 false,  // updateAfterBind
3119                                 false,  // calculateInLoop
3120                                 false,  // useMipMaps
3121                                 FUZZY_COMPARE, CMP_THRESHOLD
3122                         }
3123                 },
3124         };
3125
3126         for (int updateAfterBind = 0; updateAfterBind < 2; ++updateAfterBind)
3127         {
3128                 for (int calculateInLoop = 0; calculateInLoop < 2; ++calculateInLoop)
3129                 {
3130                         for (deUint32 caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(casesAfterBindAndLoop); ++caseIdx)
3131                         {
3132                                 TestCaseInfo&   info                    (casesAfterBindAndLoop[caseIdx]);
3133                                 std::string             caseName                (info.name);
3134                                 std::string             caseDescription (info.description);
3135                                 TestCaseParams  params                  (info.params);
3136
3137                                 caseName                                += (updateAfterBind     ? "_after_bind" : "");
3138                                 caseName                                += (calculateInLoop     ? "_in_loop"    : "");
3139
3140                                 caseDescription                 += (updateAfterBind     ? " After Bind" : "");
3141                                 caseDescription                 += (calculateInLoop ? " In Loop"        : "");
3142
3143                                 params.updateAfterBind  = updateAfterBind       ? true                  : false;
3144                                 params.calculateInLoop  = calculateInLoop       ? true                  : false;
3145
3146                                 group->addChild(new DescriptorIndexingTestCase(context, caseName.c_str(), caseDescription.c_str(), params));
3147                         }
3148                 }
3149         }
3150
3151         TestCaseInfo casesAfterBindAndLoopAndLOD[] =
3152         {
3153                 {
3154                         "sampler", "Sampler Descriptors",
3155                         {
3156                                 VK_DESCRIPTOR_TYPE_SAMPLER,
3157                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
3158                                 RESOLUTION,
3159                                 false,  // updateAfterBind
3160                                 false,  // calculateInLoop
3161                                 false,  // usesMipMaps
3162                                 FUZZY_COMPARE, CMP_THRESHOLD
3163                         }
3164                 },
3165                 {
3166                         "sampled_image", "Sampled Image Descriptors",
3167                         {
3168                                 VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
3169                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
3170                                 RESOLUTION,
3171                                 false,  // updateAfterBind
3172                                 false,  // calculateInLoop
3173                                 false,  // usesMipMaps
3174                                 FUZZY_COMPARE, CMP_THRESHOLD
3175                         }
3176                 },
3177                 {
3178                         "combined_image_sampler", "Combined Image Sampler Descriptors",
3179                         {
3180                                 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
3181                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
3182                                 RESOLUTION,
3183                                 false,  // updateAfterBind
3184                                 false,  // calculateInLoop
3185                                 false,  // usesMipMaps
3186                                 FUZZY_COMPARE, CMP_THRESHOLD
3187                         }
3188                 },
3189         };
3190
3191         for (int updateAfterBind = 0; updateAfterBind < 2; ++updateAfterBind)
3192         {
3193                 for (int calculateInLoop = 0; calculateInLoop < 2; ++calculateInLoop)
3194                 {
3195                         for (int usesMipMaps = 0; usesMipMaps < 2; ++usesMipMaps)
3196                         {
3197                                 for (deUint32 caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(casesAfterBindAndLoopAndLOD); ++caseIdx)
3198                                 {
3199                                         TestCaseInfo&   info                    (casesAfterBindAndLoopAndLOD[caseIdx]);
3200                                         std::string             caseName                (info.name);
3201                                         std::string             caseDescription (info.description);
3202                                         TestCaseParams  params                  (info.params);
3203
3204                                         caseName                                += (updateAfterBind     ? "_after_bind" : "");
3205                                         caseName                                += (calculateInLoop ? "_in_loop"        : "");
3206                                         caseName                                += (usesMipMaps         ? "_with_lod"   : "");
3207
3208                                         caseDescription                 += (updateAfterBind     ? " After Bind" : "");
3209                                         caseDescription                 += (calculateInLoop     ? " In Loop"    : "");
3210                                         caseDescription                 += (usesMipMaps         ? " Use LOD"    : "");
3211
3212                                         params.updateAfterBind  = updateAfterBind       ? true                  : false;
3213                                         params.calculateInLoop  = calculateInLoop       ? true                  : false;
3214                                         params.usesMipMaps              = usesMipMaps           ? true                  : false;
3215
3216                                         group->addChild(new DescriptorIndexingTestCase(context, caseName.c_str(), caseDescription.c_str(), params));
3217                                 }
3218                         }
3219                 }
3220         }
3221
3222         TestCaseInfo casesNonAfterBindAndLoop[] =
3223         {
3224                 {
3225                         "uniform_buffer", "Regular Uniform Buffer Descriptors",
3226                         {
3227                                 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
3228                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
3229                                 RESOLUTION,
3230                                 false,  // updateAfterBind
3231                                 false,  // calculateInLoop
3232                                 false,  // usesMipMaps
3233                                 FUZZY_COMPARE, CMP_THRESHOLD
3234                         }
3235                 },
3236                 {
3237                         "storage_buffer_dynamic", "Dynamic Storage Buffer Descriptors",
3238                         {
3239                                 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC,
3240                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
3241                                 RESOLUTION,
3242                                 false,  // updateAfterBind
3243                                 false,  // calculateInLoop
3244                                 false,  // useMipMaps
3245                                 FUZZY_COMPARE, CMP_THRESHOLD
3246                         }
3247                 },
3248                 {
3249                         "uniform_buffer_dynamic", "Dynamic Uniform Buffer Descriptors",
3250                         {
3251                                 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
3252                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
3253                                 RESOLUTION,
3254                                 false,  // updateAfterBind
3255                                 false,  // calculateInLoop
3256                                 false,  // useMipMaps
3257                                 FUZZY_COMPARE, CMP_THRESHOLD
3258                         }
3259                 },
3260                 {
3261                         "input_attachment", "Input Attachment Descriptors",
3262                         {
3263                                 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
3264                                 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
3265                                 RESOLUTION,
3266                                 false,  // updateAfterBind
3267                                 false,  // calculateInLoop
3268                                 false,  // useMipMaps
3269                                 FUZZY_COMPARE, CMP_THRESHOLD
3270                         }
3271                 },
3272         };
3273
3274         for (int calculateInLoop = 0; calculateInLoop < 2; ++calculateInLoop)
3275         {
3276                 for (deUint32 caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(casesNonAfterBindAndLoop); ++caseIdx)
3277                 {
3278                         TestCaseInfo&   info(casesNonAfterBindAndLoop[caseIdx]);
3279                         std::string             caseName(info.name);
3280                         std::string             caseDescription(info.description);
3281                         TestCaseParams  params(info.params);
3282
3283                         caseName                                += (calculateInLoop     ? "_in_loop"    : "");
3284
3285                         caseDescription                 += (calculateInLoop ? " In Loop"        : "");
3286
3287                         params.calculateInLoop  = calculateInLoop       ? true                  : false;
3288
3289                         group->addChild(new DescriptorIndexingTestCase(context, caseName.c_str(), caseDescription.c_str(), params));
3290                 }
3291         }
3292 }
3293
3294 } // - DescriptorIndexing
3295 } // - vkt