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