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