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