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