• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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::PixelBufferAccess;
63 using tcu::UVec2;
64 using tcu::Vec4;
65 
66 static const VkExtent3D RESOLUTION = {64, 64, 1};
67 
68 constexpr uint32_t kMinWorkGroupSize = 2u;
69 constexpr uint32_t kMaxWorkGroupSize = 128u;
70 
71 #define MAX_DESCRIPTORS 4200
72 #define FUZZY_COMPARE false
73 
74 #define BINDING_TestObject 0
75 #define BINDING_Additional 1
76 #define BINDING_DescriptorEnumerator 2
77 
78 static const VkExtent3D smallImageExtent = {4, 4, 1};
79 static const VkExtent3D bigImageExtent   = {32, 32, 1};
80 
81 #ifndef CTS_USES_VULKANSC
82 static const VkDescriptorType VK_DESCRIPTOR_TYPE_UNDEFINED = VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT;
83 #else
84 static const VkDescriptorType VK_DESCRIPTOR_TYPE_UNDEFINED = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
85 #endif
86 
87 struct BindingUniformBufferData
88 {
89     tcu::Vec4 c;
90 };
91 
92 struct BindingStorageBufferData
93 {
94     tcu::Vec4 cnew;
95     tcu::Vec4 cold;
96 };
97 
98 struct TestCaseParams
99 {
100     VkDescriptorType descriptorType; // used only to distinguish test class instance
101     VkShaderStageFlags stageFlags;   // used only to build a proper program
102     VkExtent3D frameResolution;      // target frame buffer resolution
103     bool updateAfterBind;            // whether a test will use update after bind feature
104     bool calculateInLoop;            // perform calculation in a loop
105     bool usesMipMaps;                // this makes a sense and affects in image test cases only
106     bool minNonUniform;              // whether a test will use the minimum nonUniform decorations
107     bool lifetimeCheck;              // fill unused descriptors with resource that will be deleted before draw
108 };
109 
110 struct TestParams
111 {
112     VkShaderStageFlags stageFlags;
113     VkDescriptorType descriptorType;
114     VkDescriptorType additionalDescriptorType;
115     bool copyBuffersToImages;
116     bool allowVertexStoring;
117     VkExtent3D frameResolution;
118     bool updateAfterBind;
119     bool calculateInLoop;
120     bool usesMipMaps;
121     bool minNonUniform;
122     bool lifetimeCheck;
123 
TestParamsvkt::DescriptorIndexing::__anon4905adf40111::TestParams124     TestParams(VkShaderStageFlags stageFlags_, VkDescriptorType descriptorType_,
125                VkDescriptorType additionalDescriptorType_, bool copyBuffersToImages_, bool allowVertexStoring_,
126                const TestCaseParams &caseParams)
127         : stageFlags(stageFlags_)
128         , descriptorType(descriptorType_)
129         , additionalDescriptorType(additionalDescriptorType_)
130         , copyBuffersToImages(copyBuffersToImages_)
131         , allowVertexStoring(allowVertexStoring_)
132         , frameResolution(caseParams.frameResolution)
133         , updateAfterBind(caseParams.updateAfterBind)
134         , calculateInLoop(caseParams.calculateInLoop)
135         , usesMipMaps(caseParams.usesMipMaps)
136         , minNonUniform(caseParams.minNonUniform)
137         , lifetimeCheck(caseParams.lifetimeCheck)
138     {
139     }
140 };
141 
142 struct DescriptorEnumerator
143 {
144     ut::BufferHandleAllocSp buffer;
145     ut::BufferViewSp bufferView;
146     VkDeviceSize bufferSize;
147 
148     Move<VkDescriptorSetLayout> descriptorSetLayout;
149     Move<VkDescriptorPool> descriptorPool;
150     Move<VkDescriptorSet> descriptorSet;
151 
152     void init(const vkt::Context &context, uint32_t vertexCount, uint32_t availableDescriptorCount);
153     void update(const vkt::Context &context);
154 };
155 
156 struct IterateCommonVariables
157 {
158     // An amount of descriptors of a given type available on the platform
159     uint32_t availableDescriptorCount;
160     // An amount of valid descriptors that have connected a buffers to them
161     uint32_t validDescriptorCount;
162     // As the name suggests, sometimes it is used as invocationCount
163     uint32_t vertexCount;
164     VkRect2D renderArea;
165     VkDeviceSize dataAlignment;
166     uint32_t lowerBound;
167     uint32_t upperBound;
168 
169     DescriptorEnumerator descriptorEnumerator;
170 
171     ut::BufferHandleAllocSp vertexAttributesBuffer;
172     ut::BufferHandleAllocSp descriptorsBuffer;
173     ut::BufferHandleAllocSp unusedDescriptorsBuffer;
174     std::vector<VkDescriptorBufferInfo> descriptorsBufferInfos;
175     std::vector<ut::BufferViewSp> descriptorsBufferViews;
176     std::vector<ut::ImageViewSp> descriptorImageViews;
177     std::vector<ut::SamplerSp> descriptorSamplers;
178     std::vector<ut::ImageHandleAllocSp> descriptorsImages;
179     // Only need a single resource to fill all unused descriptors. Using vector for compatibility with utility
180     std::vector<VkDescriptorBufferInfo> unusedDescriptorsBufferInfos;
181     std::vector<ut::BufferViewSp> unusedDescriptorsBufferViews;
182     std::vector<ut::ImageViewSp> unusedDescriptorImageViews;
183     std::vector<ut::SamplerSp> unusedDescriptorSamplers;
184     std::vector<ut::ImageHandleAllocSp> unusedDescriptorsImages;
185     ut::FrameBufferSp frameBuffer;
186 
187     Move<VkDescriptorSetLayout> descriptorSetLayout;
188     Move<VkDescriptorPool> descriptorPool;
189     Move<VkDescriptorSet> descriptorSet;
190     Move<VkPipelineLayout> pipelineLayout;
191     Move<VkRenderPass> renderPass;
192     Move<VkPipeline> pipeline;
193     Move<VkCommandBuffer> commandBuffer;
194 };
195 
196 class CommonDescriptorInstance : public TestInstance
197 {
198 public:
199     CommonDescriptorInstance(Context &context, const TestParams &testParams);
200 
201     uint32_t computeAvailableDescriptorCount(VkDescriptorType descriptorType, bool reserveUniformTexelBuffer) const;
202 
203     Move<VkDescriptorSetLayout> createDescriptorSetLayout(bool reserveUniformTexelBuffer,
204                                                           uint32_t &descriptorCount) const;
205 
206     Move<VkDescriptorPool> createDescriptorPool(uint32_t descriptorCount) const;
207 
208     Move<VkDescriptorSet> createDescriptorSet(VkDescriptorPool dsPool, VkDescriptorSetLayout dsLayout) const;
209 
210     struct attributes
211     {
212         typedef tcu::Vec4 vec4;
213         typedef tcu::Vec2 vec2;
214         typedef tcu::IVec4 ivec4;
215         vec4 position;
216         vec2 normalpos;
217         ivec4 index;
operator ()vkt::DescriptorIndexing::__anon4905adf40111::CommonDescriptorInstance::attributes218         attributes &operator()(const vec4 &pos)
219         {
220             position = pos;
221 
222             normalpos.x() = (pos.x() + 1.0f) / 2.0f;
223             normalpos.y() = (pos.y() + 1.0f) / 2.0f;
224 
225             return *this;
226         }
227     };
228     void createVertexAttributeBuffer(ut::BufferHandleAllocSp &buffer, uint32_t availableDescriptorCount) const;
229 
230     static std::string substBinding(uint32_t binding, const char *str);
231 
232     static const char *getVertexShaderProlog(void);
233     static const char *getFragmentShaderProlog(void);
234     static const char *getComputeShaderProlog(void);
235 
236     static const char *getShaderEpilog(void);
237 
238     static bool performWritesInVertex(VkDescriptorType descriptorType);
239 
240     static bool performWritesInVertex(VkDescriptorType descriptorType, const Context &context);
241 
242     static std::string getShaderAsm(VkShaderStageFlagBits shaderType, const TestCaseParams &testCaseParams,
243                                     bool allowVertexStoring);
244 
245     static std::string getShaderSource(VkShaderStageFlagBits shaderType, const TestCaseParams &testCaseParams,
246                                        bool allowVertexStoring);
247 
248     static std::string getColorAccess(VkDescriptorType descriptorType, const char *indexVariableName, bool usesMipMaps);
249 
250     static std::string getFragmentReturnSource(const std::string &colorAccess);
251 
252     static std::string getFragmentLoopSource(const std::string &colorAccess1, const std::string &colorAccess2);
253 
254     virtual Move<VkRenderPass> createRenderPass(const IterateCommonVariables &variables);
255 
256     struct push_constant
257     {
258         int32_t lowerBound;
259         int32_t upperBound;
260     };
261     VkPushConstantRange makePushConstantRange(void) const;
262 
263     Move<VkPipelineLayout> createPipelineLayout(const std::vector<VkDescriptorSetLayout> &descriptorSetLayouts) const;
264 
265     // Creates graphics or compute pipeline and appropriate shaders' modules according the testCaseParams.stageFlags
266     // In the case of compute pipeline renderPass parameter is ignored.
267     // Viewport will be created with a width and a height taken from testCaseParam.fragResolution.
268     Move<VkPipeline> createPipeline(VkPipelineLayout pipelineLayout, VkRenderPass renderPass);
269 
270     virtual void createFramebuffer(ut::FrameBufferSp &frameBuffer, VkRenderPass renderPass,
271                                    const IterateCommonVariables &variables);
272 
273     // Creates one big stagging buffer cutted out on chunks that can accomodate an element of elementSize size
274     VkDeviceSize createBuffers(std::vector<VkDescriptorBufferInfo> &bufferInfos, ut::BufferHandleAllocSp &buffer,
275                                uint32_t elementCount, uint32_t elementSize, VkDeviceSize alignment,
276                                VkBufferUsageFlags bufferUsage);
277 
278     // Creates and binds an imagesCount of images with given parameters.
279     // Additionally creates stagging buffer for their data and PixelBufferAccess for particular images.
280     VkDeviceSize createImages(std::vector<ut::ImageHandleAllocSp> &images,
281                               std::vector<VkDescriptorBufferInfo> &bufferInfos, ut::BufferHandleAllocSp &buffer,
282                               VkBufferUsageFlags bufferUsage, const VkExtent3D &imageExtent, VkFormat imageFormat,
283                               VkImageLayout imageLayout, uint32_t imageCount, bool withMipMaps = false);
284 
285     void createBuffersViews(std::vector<ut::BufferViewSp> &views,
286                             const std::vector<VkDescriptorBufferInfo> &bufferInfos, VkFormat format);
287 
288     void createImagesViews(std::vector<ut::ImageViewSp> &views, const std::vector<ut::ImageHandleAllocSp> &images,
289                            VkFormat format);
290 
291     virtual void copyBuffersToImages(IterateCommonVariables &variables);
292 
293     virtual void copyImagesToBuffers(IterateCommonVariables &variables);
294 
295     PixelBufferAccess getPixelAccess(uint32_t imageIndex, const VkExtent3D &imageExtent, VkFormat imageFormat,
296                                      const std::vector<VkDescriptorBufferInfo> &bufferInfos,
297                                      const ut::BufferHandleAllocSp &buffer, uint32_t mipLevel = 0u) const;
298 
299     virtual void createAndPopulateDescriptors(IterateCommonVariables &variables)       = 0;
300     virtual void createAndPopulateUnusedDescriptors(IterateCommonVariables &variables) = 0;
301 
302     virtual void updateDescriptors(IterateCommonVariables &variables);
303     void updateUnusedDescriptors(IterateCommonVariables &variables);
304 
305     void destroyUnusedResources(IterateCommonVariables &variables);
306 
307     virtual void iterateCollectResults(ut::UpdatablePixelBufferAccessPtr &result,
308                                        const IterateCommonVariables &variables, bool fromTest);
309 
310     void iterateCommandSetup(IterateCommonVariables &variables);
311 
312     void iterateCommandBegin(IterateCommonVariables &variables, bool firstPass = true);
313 
314     void iterateCommandEnd(IterateCommonVariables &variables, ut::UpdatablePixelBufferAccessPtr &programResult,
315                            ut::UpdatablePixelBufferAccessPtr &referenceResult, bool collectBeforeSubmit = true);
316 
317     bool iterateVerifyResults(IterateCommonVariables &variables, ut::UpdatablePixelBufferAccessPtr programResult,
318                               ut::UpdatablePixelBufferAccessPtr referenceResult);
319 
320     Move<VkCommandBuffer> createCmdBuffer(void);
321 
322     void commandBindPipeline(VkCommandBuffer commandBuffer, VkPipeline pipeline);
323 
324     void commandBindVertexAttributes(VkCommandBuffer commandBuffer,
325                                      const ut::BufferHandleAllocSp &vertexAttributesBuffer);
326 
327     void commandBindDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineLayout pipelineLayout,
328                                    VkDescriptorSet descriptorSet, uint32_t descriptorSetIndex);
329 
330     void commandReadFrameBuffer(ut::BufferHandleAllocSp &content, VkCommandBuffer commandBuffer,
331                                 const ut::FrameBufferSp &frameBuffer);
332     ut::UpdatablePixelBufferAccessPtr commandReadFrameBuffer(VkCommandBuffer commandBuffer,
333                                                              const ut::FrameBufferSp &frameBuffer);
334 
335     Move<VkFence> commandSubmit(VkCommandBuffer commandBuffer);
336 
337     virtual bool verifyVertexWriteResults(IterateCommonVariables &variables);
338 
339 protected:
340     virtual tcu::TestStatus iterate(void);
341 
342 protected:
343     const VkDevice m_vkd;
344     const DeviceInterface &m_vki;
345     Allocator &m_allocator;
346     const VkQueue m_queue;
347     const uint32_t m_queueFamilyIndex;
348     const Move<VkCommandPool> m_commandPool;
349     const VkFormat m_colorFormat;
350     const TestParams m_testParams;
351     static const tcu::Vec4 m_clearColor;
352     const std::vector<float> m_colorScheme;
353     const uint32_t m_schemeSize;
354 
355 private:
356     Move<VkPipeline> createGraphicsPipeline(VkPipelineLayout pipelineLayout, VkRenderPass renderPass);
357 
358     Move<VkPipeline> createComputePipeline(VkPipelineLayout pipelineLayout);
359 
360     void constructShaderModules(void);
361 
362     static std::vector<float> createColorScheme();
363 
364     Move<VkShaderModule> m_vertexModule;
365     Move<VkShaderModule> m_fragmentModule;
366     Move<VkShaderModule> m_computeModule;
367 };
368 const tcu::Vec4 CommonDescriptorInstance::m_clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
369 
init(const vkt::Context & context,uint32_t vertexCount,uint32_t availableDescriptorCount)370 void DescriptorEnumerator::init(const vkt::Context &context, uint32_t vertexCount, uint32_t availableDescriptorCount)
371 {
372     const VkDevice device                  = context.getDevice();
373     const DeviceInterface &deviceInterface = context.getDeviceInterface();
374 
375     const VkFormat imageFormat = VK_FORMAT_R32G32B32A32_SINT;
376     typedef ut::mapVkFormat2Type<imageFormat>::type pixelType;
377     const VkDeviceSize dataSize        = vertexCount * sizeof(pixelType);
378     const std::vector<uint32_t> primes = ut::generatePrimes(availableDescriptorCount);
379     const uint32_t primeCount          = static_cast<uint32_t>(primes.size());
380 
381     std::vector<pixelType> data(vertexCount);
382     // e.g. 2,3,5,7,11,13,2,3,5,7,...
383     for (uint32_t idx = 0; idx < vertexCount; ++idx)
384     {
385         data[idx].x() = static_cast<pixelType::Element>(primes[idx % primeCount]);
386         data[idx].y() = static_cast<pixelType::Element>(idx);
387     }
388 
389     bufferSize = ut::createBufferAndBind(buffer, context, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, dataSize);
390     deMemcpy(buffer->alloc->getHostPtr(), data.data(), static_cast<size_t>(dataSize));
391 
392     const VkBufferViewCreateInfo bufferViewCreateInfo = {
393         VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO, // sType
394         nullptr,                                   // pNext
395         0u,                                        // flags
396         *(buffer.get()->buffer),                   // buffer
397         imageFormat,                               // format
398         0u,                                        // offset
399         bufferSize,                                // range
400     };
401 
402     bufferView =
403         ut::BufferViewSp(new Move<VkBufferView>(vk::createBufferView(deviceInterface, device, &bufferViewCreateInfo)));
404 
405     const VkDescriptorSetLayoutBinding binding = {
406         BINDING_DescriptorEnumerator,            // binding
407         VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, // descriptorType
408         1u,                                      // descriptorCount
409         VK_SHADER_STAGE_ALL,                     // stageFlags
410         nullptr,                                 // pImmutableSamplers
411     };
412 
413     const VkDescriptorSetLayoutCreateInfo layoutCreateInfo = {
414         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
415         nullptr,  // pNext
416         0u,       // flags
417         1u,       // bindingCount
418         &binding, // pBindings
419     };
420 
421     descriptorSetLayout = vk::createDescriptorSetLayout(deviceInterface, device, &layoutCreateInfo);
422     descriptorPool      = DescriptorPoolBuilder()
423                          .addType(binding.descriptorType)
424                          .build(deviceInterface, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
425 
426     const VkDescriptorSetAllocateInfo dsAllocInfo = {
427         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // sType
428         nullptr,                                        // pNext
429         *descriptorPool,                                // descriptorPool
430         1u,                                             // descriptorSetCount
431         &(*descriptorSetLayout)                         // pSetLayouts
432     };
433 
434     descriptorSet = vk::allocateDescriptorSet(deviceInterface, device, &dsAllocInfo);
435 }
436 
update(const vkt::Context & context)437 void DescriptorEnumerator::update(const vkt::Context &context)
438 {
439     const VkDescriptorBufferInfo bufferInfo = {
440         *(buffer.get()->buffer), // buffer
441         0u,                      // offset
442         bufferSize,              // range
443     };
444 
445     const VkWriteDescriptorSet writeInfo = {
446         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
447         nullptr,                                 // pNext
448         *descriptorSet,                          // dstSet
449         BINDING_DescriptorEnumerator,            // dstBinding
450         0u,                                      // dstArrayElement
451         1u,                                      // descriptorCount
452         VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, // descriptorType
453         nullptr,                                 // pImageInfo
454         &bufferInfo,                             // pBufferInfo
455         &(**bufferView),                         // pTexelBufferView
456     };
457 
458     context.getDeviceInterface().updateDescriptorSets(context.getDevice(), 1u, &writeInfo, 0u, nullptr);
459 }
460 
CommonDescriptorInstance(Context & context,const TestParams & testParams)461 CommonDescriptorInstance::CommonDescriptorInstance(Context &context, const TestParams &testParams)
462     : TestInstance(context)
463     , m_vkd(context.getDevice())
464     , m_vki(context.getDeviceInterface())
465     , m_allocator(context.getDefaultAllocator())
466     , m_queue(context.getUniversalQueue())
467     , m_queueFamilyIndex(context.getUniversalQueueFamilyIndex())
468     , m_commandPool(vk::createCommandPool(
469           m_vki, m_vkd, (VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT),
470           m_queueFamilyIndex))
471     , m_colorFormat(VK_FORMAT_R32G32B32A32_SFLOAT)
472     , m_testParams(testParams)
473     , m_colorScheme(createColorScheme())
474     , m_schemeSize(static_cast<uint32_t>(m_colorScheme.size()))
475 {
476 }
477 
computeAvailableDescriptorCount(VkDescriptorType descriptorType,bool reserveUniformTexelBuffer) const478 uint32_t CommonDescriptorInstance::computeAvailableDescriptorCount(VkDescriptorType descriptorType,
479                                                                    bool reserveUniformTexelBuffer) const
480 {
481     DE_UNREF(descriptorType);
482     const uint32_t vertexCount = m_testParams.frameResolution.width * m_testParams.frameResolution.height;
483     const uint32_t availableDescriptorsOnDevice = ut::DeviceProperties(m_context).computeMaxPerStageDescriptorCount(
484         m_testParams.descriptorType, m_testParams.updateAfterBind, reserveUniformTexelBuffer);
485     return deMinu32(deMinu32(vertexCount, availableDescriptorsOnDevice), MAX_DESCRIPTORS);
486 }
487 
createDescriptorSetLayout(bool reserveUniformTexelBuffer,uint32_t & descriptorCount) const488 Move<VkDescriptorSetLayout> CommonDescriptorInstance::createDescriptorSetLayout(bool reserveUniformTexelBuffer,
489                                                                                 uint32_t &descriptorCount) const
490 {
491     descriptorCount = computeAvailableDescriptorCount(m_testParams.descriptorType, reserveUniformTexelBuffer);
492 
493     bool optional = (m_testParams.additionalDescriptorType != VK_DESCRIPTOR_TYPE_UNDEFINED);
494 
495     const VkShaderStageFlags bindingStageFlags = (m_testParams.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) ?
496                                                      VkShaderStageFlags{VK_SHADER_STAGE_FRAGMENT_BIT} :
497                                                      m_testParams.stageFlags;
498 
499     const VkDescriptorSetLayoutBinding bindings[] = {{
500                                                          BINDING_TestObject,          // binding
501                                                          m_testParams.descriptorType, // descriptorType
502                                                          descriptorCount,             // descriptorCount
503                                                          bindingStageFlags,           // stageFlags
504                                                          nullptr,                     // pImmutableSamplers
505                                                      },
506                                                      {
507                                                          BINDING_Additional,                    // binding
508                                                          m_testParams.additionalDescriptorType, // descriptorType
509                                                          1,                                     // descriptorCount
510                                                          bindingStageFlags,                     // stageFlags
511                                                          nullptr,                               // pImmutableSamplers
512                                                      }};
513 
514     const VkDescriptorBindingFlags bindingFlagUpdateAfterBind =
515         m_testParams.updateAfterBind ? VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT : 0;
516 
517     const VkDescriptorBindingFlags bindingFlags[] = {
518         VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | bindingFlagUpdateAfterBind,
519         VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | bindingFlagUpdateAfterBind};
520 
521     const VkDescriptorSetLayoutBindingFlagsCreateInfo bindingCreateInfo = {
522         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO, nullptr,
523         optional ? 2u : 1u, // bindingCount
524         bindingFlags,       // pBindingFlags
525     };
526 
527     const VkDescriptorSetLayoutCreateFlags layoutCreateFlags =
528         m_testParams.updateAfterBind ? VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT : 0;
529 
530     const VkDescriptorSetLayoutCreateInfo layoutCreateInfo = {
531         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
532         &bindingCreateInfo, // pNext
533         layoutCreateFlags,  // flags
534         optional ? 2u : 1u, // bindingCount
535         bindings,           // pBindings
536     };
537 
538     return vk::createDescriptorSetLayout(m_vki, m_vkd, &layoutCreateInfo);
539 }
540 
createDescriptorPool(uint32_t descriptorCount) const541 Move<VkDescriptorPool> CommonDescriptorInstance::createDescriptorPool(uint32_t descriptorCount) const
542 {
543     const VkDescriptorPoolCreateFlags pcf =
544         m_testParams.updateAfterBind ? VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT : 0;
545 
546     DescriptorPoolBuilder builder;
547 
548     builder.addType(m_testParams.descriptorType, descriptorCount);
549 
550     if (m_testParams.additionalDescriptorType != VK_DESCRIPTOR_TYPE_UNDEFINED)
551         builder.addType(m_testParams.additionalDescriptorType, 1);
552 
553     return builder.build(m_vki, m_vkd, (VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT | pcf), 1u);
554 }
555 
createDescriptorSet(VkDescriptorPool dsPool,VkDescriptorSetLayout dsLayout) const556 Move<VkDescriptorSet> CommonDescriptorInstance::createDescriptorSet(VkDescriptorPool dsPool,
557                                                                     VkDescriptorSetLayout dsLayout) const
558 {
559     const VkDescriptorSetAllocateInfo dsAllocInfo = {
560         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // sType;
561         nullptr,                                        // pNext;
562         dsPool,                                         // descriptorPool;
563         1u,                                             // descriptorSetCount
564         &dsLayout                                       // pSetLayouts
565     };
566 
567     return vk::allocateDescriptorSet(m_vki, m_vkd, &dsAllocInfo);
568 }
569 
createVertexAttributeBuffer(ut::BufferHandleAllocSp & buffer,uint32_t availableDescriptorCount) const570 void CommonDescriptorInstance::createVertexAttributeBuffer(ut::BufferHandleAllocSp &buffer,
571                                                            uint32_t availableDescriptorCount) const
572 {
573     float xSize = 0.0f;
574     float ySize = 0.0f;
575 
576     const uint32_t invocationCount = m_testParams.frameResolution.width * m_testParams.frameResolution.height;
577     const std::vector<Vec4> vertices =
578         ut::createVertices(m_testParams.frameResolution.width, m_testParams.frameResolution.height, xSize, ySize);
579     const std::vector<uint32_t> primes = ut::generatePrimes(availableDescriptorCount);
580     const uint32_t primeCount          = static_cast<uint32_t>(primes.size());
581 
582     std::vector<attributes> data(vertices.size());
583     std::transform(vertices.begin(), vertices.end(), data.begin(), attributes());
584 
585     for (uint32_t invIdx = 0; invIdx < invocationCount; ++invIdx)
586     {
587         // r: 2,3,5,7,11,13,2,3,5,7,...
588         data[invIdx].index.x() = primes[invIdx % primeCount];
589 
590         // b, a: not used
591         data[invIdx].index.z() = 0;
592         data[invIdx].index.w() = 0;
593     }
594 
595     // g: 0,0,2,3,0,5,0,7,0,0,0,11,0,13,...
596     for (uint32_t primeIdx = 0; primeIdx < primeCount; ++primeIdx)
597     {
598         const uint32_t prime = primes[primeIdx];
599         DE_ASSERT(prime < invocationCount);
600         data[prime].index.y() = prime;
601     }
602 
603     const VkDeviceSize dataSize = data.size() * sizeof(attributes);
604 
605     VkDeviceSize deviceSize = ut::createBufferAndBind(buffer, m_context, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, dataSize);
606 
607     deMemcpy(buffer->alloc->getHostPtr(), data.data(), static_cast<size_t>(deviceSize));
608 
609     vk::flushAlloc(m_vki, m_vkd, *buffer->alloc);
610 }
611 
substBinding(uint32_t binding,const char * str)612 std::string CommonDescriptorInstance::substBinding(uint32_t binding, const char *str)
613 {
614     std::map<std::string, std::string> vars;
615     vars["?"] = de::toString(binding);
616     return tcu::StringTemplate(str).specialize(vars);
617 }
618 
getVertexShaderProlog(void)619 const char *CommonDescriptorInstance::getVertexShaderProlog(void)
620 {
621     return "layout(location = 0) in  vec4  in_position;    \n"
622            "layout(location = 1) in  vec2  in_normalpos;    \n"
623            "layout(location = 2) in  ivec4 index;            \n"
624            "layout(location = 0) out vec2  normalpos;        \n"
625            "layout(location = 1) out int   rIndex;            \n"
626            "layout(location = 2) out int   gIndex;            \n"
627            "void main(void)                                \n"
628            "{                                                \n"
629            "    gl_PointSize = 0.2f;                        \n"
630            "    normalpos = in_normalpos;                    \n"
631            "    gl_Position = in_position;                    \n"
632            "    rIndex = index.x;                            \n"
633            "    gIndex = index.y;                            \n";
634 }
635 
getFragmentShaderProlog(void)636 const char *CommonDescriptorInstance::getFragmentShaderProlog(void)
637 {
638     return "layout(location = 0) out vec4     FragColor;    \n"
639            "layout(location = 0) in flat vec2 normalpos;    \n"
640            "layout(location = 1) in flat int  rIndex;        \n"
641            "layout(location = 2) in flat int  gIndex;        \n"
642            "void main(void)                                \n"
643            "{                                                \n";
644 }
645 
getComputeShaderProlog(void)646 const char *CommonDescriptorInstance::getComputeShaderProlog(void)
647 {
648     return "layout(constant_id=0) const int local_size_x_val = 1;                \n"
649            "layout(constant_id=1) const int local_size_y_val = 1;                \n"
650            "layout(constant_id=2) const int local_size_z_val = 1;                \n"
651            "layout(local_size_x_id=0,local_size_y_id=1,local_size_z_id=2) in;    \n"
652            "void main(void)                                                    \n"
653            "{                                                                    \n";
654 }
655 
getShaderEpilog(void)656 const char *CommonDescriptorInstance::getShaderEpilog(void)
657 {
658     return "}                                            \n";
659 }
660 
constructShaderModules(void)661 void CommonDescriptorInstance::constructShaderModules(void)
662 {
663     tcu::TestLog &log = m_context.getTestContext().getLog();
664 
665     // Must construct at least one stage.
666     DE_ASSERT(m_testParams.stageFlags &
667               (VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_VERTEX_BIT));
668 
669     if (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT)
670     {
671         const std::string name =
672             ut::buildShaderName(VK_SHADER_STAGE_COMPUTE_BIT, m_testParams.descriptorType, m_testParams.updateAfterBind,
673                                 m_testParams.calculateInLoop, m_testParams.minNonUniform, false);
674         m_computeModule = vk::createShaderModule(m_vki, m_vkd, m_context.getBinaryCollection().get(name),
675                                                  (VkShaderModuleCreateFlags)0);
676     }
677     if (m_testParams.stageFlags & VK_SHADER_STAGE_FRAGMENT_BIT)
678     {
679         const std::string name = ut::buildShaderName(VK_SHADER_STAGE_FRAGMENT_BIT, m_testParams.descriptorType,
680                                                      m_testParams.updateAfterBind, m_testParams.calculateInLoop,
681                                                      m_testParams.minNonUniform, m_testParams.allowVertexStoring);
682         m_fragmentModule       = vk::createShaderModule(m_vki, m_vkd, m_context.getBinaryCollection().get(name),
683                                                         (VkShaderModuleCreateFlags)0);
684         log << tcu::TestLog::Message << "Finally used fragment shader: " << name << '\n' << tcu::TestLog::EndMessage;
685     }
686     if (m_testParams.stageFlags & VK_SHADER_STAGE_VERTEX_BIT)
687     {
688         const std::string name = ut::buildShaderName(VK_SHADER_STAGE_VERTEX_BIT, m_testParams.descriptorType,
689                                                      m_testParams.updateAfterBind, m_testParams.calculateInLoop,
690                                                      m_testParams.minNonUniform, m_testParams.allowVertexStoring);
691         m_vertexModule         = vk::createShaderModule(m_vki, m_vkd, m_context.getBinaryCollection().get(name),
692                                                         (VkShaderModuleCreateFlags)0);
693         log << tcu::TestLog::Message << "Finally used vertex shader: " << name << '\n' << tcu::TestLog::EndMessage;
694     }
695 }
696 
createRenderPass(const IterateCommonVariables & variables)697 Move<VkRenderPass> CommonDescriptorInstance::createRenderPass(const IterateCommonVariables &variables)
698 {
699     DE_UNREF(variables);
700     if ((m_testParams.stageFlags & VK_SHADER_STAGE_VERTEX_BIT) ||
701         (m_testParams.stageFlags & VK_SHADER_STAGE_FRAGMENT_BIT))
702     {
703         // Use VK_ATTACHMENT_LOAD_OP_LOAD to make the utility function select initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
704         return vk::makeRenderPass(m_vki, m_vkd, m_colorFormat, VK_FORMAT_UNDEFINED, VK_ATTACHMENT_LOAD_OP_LOAD);
705     }
706     return Move<VkRenderPass>();
707 }
708 
makePushConstantRange(void) const709 VkPushConstantRange CommonDescriptorInstance::makePushConstantRange(void) const
710 {
711     const VkPushConstantRange pcr = {
712         m_testParams.stageFlags,                     // stageFlags
713         0u,                                          // offset
714         static_cast<uint32_t>(sizeof(push_constant)) // size
715     };
716     return pcr;
717 }
718 
createPipelineLayout(const std::vector<VkDescriptorSetLayout> & descriptorSetLayouts) const719 Move<VkPipelineLayout> CommonDescriptorInstance::createPipelineLayout(
720     const std::vector<VkDescriptorSetLayout> &descriptorSetLayouts) const
721 {
722     const VkPushConstantRange pcr = makePushConstantRange();
723 
724     const VkPipelineLayoutCreateInfo createInfo = {
725         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,      // sType
726         nullptr,                                            // pNext
727         (VkPipelineLayoutCreateFlags)0,                     // flags
728         static_cast<uint32_t>(descriptorSetLayouts.size()), // setLayoutCount
729         descriptorSetLayouts.data(),                        // pSetLayouts;
730         m_testParams.calculateInLoop ? 1u : 0u,             // pushConstantRangeCount
731         m_testParams.calculateInLoop ? &pcr : nullptr,      // pPushConstantRanges
732     };
733 
734     return vk::createPipelineLayout(m_vki, m_vkd, &createInfo);
735 }
736 
createFramebuffer(ut::FrameBufferSp & frameBuffer,VkRenderPass renderPass,const IterateCommonVariables & variables)737 void CommonDescriptorInstance::createFramebuffer(ut::FrameBufferSp &frameBuffer, VkRenderPass renderPass,
738                                                  const IterateCommonVariables &variables)
739 {
740     DE_UNREF(variables);
741     ut::createFrameBuffer(frameBuffer, m_context, m_testParams.frameResolution, m_colorFormat, renderPass);
742 }
743 
createPipeline(VkPipelineLayout pipelineLayout,VkRenderPass renderPass)744 Move<VkPipeline> CommonDescriptorInstance::createPipeline(VkPipelineLayout pipelineLayout, VkRenderPass renderPass)
745 {
746     DE_ASSERT(VK_SHADER_STAGE_ALL != m_testParams.stageFlags);
747 
748     constructShaderModules();
749 
750     return (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT) ? createComputePipeline(pipelineLayout) :
751                                                                      createGraphicsPipeline(pipelineLayout, renderPass);
752 }
753 
createComputePipeline(VkPipelineLayout pipelineLayout)754 Move<VkPipeline> CommonDescriptorInstance::createComputePipeline(VkPipelineLayout pipelineLayout)
755 {
756     const tcu::IVec3 workGroupSize((m_testParams.calculateInLoop ? kMaxWorkGroupSize : kMinWorkGroupSize), 1, 1);
757     const auto intSize    = sizeof(int);
758     const auto intSizeU32 = static_cast<uint32_t>(intSize);
759 
760     const std::vector<VkSpecializationMapEntry> mapEntries{
761         makeSpecializationMapEntry(0u, intSizeU32 * 0u, intSize),
762         makeSpecializationMapEntry(1u, intSizeU32 * 1u, intSize),
763         makeSpecializationMapEntry(2u, intSizeU32 * 2u, intSize),
764     };
765 
766     const VkSpecializationInfo workGroupSizeInfo = {
767         static_cast<uint32_t>(mapEntries.size()), // uint32_t mapEntryCount;
768         mapEntries.data(),                        // const VkSpecializationMapEntry* pMapEntries;
769         sizeof(workGroupSize),                    // size_t dataSize;
770         &workGroupSize,                           // const void* pData;
771     };
772 
773     const VkPipelineShaderStageCreateInfo shaderStageCreateInfo = {
774         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
775         nullptr,                             // pNext
776         (VkPipelineShaderStageCreateFlags)0, // flags
777         VK_SHADER_STAGE_COMPUTE_BIT,         // stage
778         *m_computeModule,                    // module
779         "main",                              // pName
780         &workGroupSizeInfo,                  // pSpecializationInfo
781     };
782 
783     const VkComputePipelineCreateInfo pipelineCreateInfo = {
784         VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
785         nullptr,               // pNext
786         0u,                    // flags
787         shaderStageCreateInfo, // stage
788         pipelineLayout,        // layout
789         VK_NULL_HANDLE,        // basePipelineHandle
790         0u,                    // basePipelineIndex
791     };
792     return vk::createComputePipeline(m_vki, m_vkd, VK_NULL_HANDLE, &pipelineCreateInfo);
793 }
794 
createGraphicsPipeline(VkPipelineLayout pipelineLayout,VkRenderPass renderPass)795 Move<VkPipeline> CommonDescriptorInstance::createGraphicsPipeline(VkPipelineLayout pipelineLayout,
796                                                                   VkRenderPass renderPass)
797 {
798     const VkVertexInputBindingDescription bindingDescriptions[] = {
799         {
800             0u,                          // binding
801             sizeof(attributes),          // stride
802             VK_VERTEX_INPUT_RATE_VERTEX, // inputRate
803         },
804     };
805 
806     const VkVertexInputAttributeDescription attributeDescriptions[] = {
807         {
808             0u,                                            // location
809             0u,                                            // binding
810             ut::mapType2vkFormat<attributes::vec4>::value, // format
811             0u                                             // offset
812         },                                                 // @in_position
813         {
814             1u,                                             // location
815             0u,                                             // binding
816             ut::mapType2vkFormat<attributes::vec2>::value,  // format
817             static_cast<uint32_t>(sizeof(attributes::vec4)) // offset
818         },                                                  // @normalpos
819         {
820             2u,                                                                        // location
821             0u,                                                                        // binding
822             ut::mapType2vkFormat<attributes::ivec4>::value,                            // format
823             static_cast<uint32_t>(sizeof(attributes::vec2) + sizeof(attributes::vec4)) // offset
824         },                                                                             // @index
825     };
826 
827     const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = {
828         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
829         nullptr,
830         (VkPipelineVertexInputStateCreateFlags)0,  // flags
831         DE_LENGTH_OF_ARRAY(bindingDescriptions),   // vertexBindingDescriptionCount
832         bindingDescriptions,                       // pVertexBindingDescriptions
833         DE_LENGTH_OF_ARRAY(attributeDescriptions), // vertexAttributeDescriptionCount
834         attributeDescriptions                      // pVertexAttributeDescriptions
835     };
836 
837     const VkDynamicState dynamicStates[] = {VK_DYNAMIC_STATE_SCISSOR};
838 
839     const VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo = {
840         VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // sType
841         nullptr,                                              // pNext
842         0u,                                                   // flags
843         DE_LENGTH_OF_ARRAY(dynamicStates),                    // dynamicStateCount
844         dynamicStates                                         // pDynamicStates
845     };
846 
847     const std::vector<VkViewport> viewports(
848         1, makeViewport(m_testParams.frameResolution.width, m_testParams.frameResolution.height));
849     const std::vector<VkRect2D> scissors(1, makeRect2D(0u, 0u));
850 
851     DE_ASSERT(m_vertexModule && m_fragmentModule);
852 
853     return vk::makeGraphicsPipeline(m_vki,                            // vk
854                                     m_vkd,                            // device
855                                     pipelineLayout,                   // pipelineLayout
856                                     *m_vertexModule,                  // vertexShaderModule
857                                     VK_NULL_HANDLE,                   // tessellationControlModule
858                                     VK_NULL_HANDLE,                   // tessellationEvalModule
859                                     VK_NULL_HANDLE,                   // geometryShaderModule
860                                     *m_fragmentModule,                // fragmentShaderModule
861                                     renderPass,                       // renderPass
862                                     viewports,                        // viewports
863                                     scissors,                         // scissors
864                                     VK_PRIMITIVE_TOPOLOGY_POINT_LIST, // topology
865                                     0U,                               // subpass
866                                     0U,                               // patchControlPoints
867                                     &vertexInputStateCreateInfo,      // vertexInputStateCreateInfo
868                                     nullptr,                          // rasterizationStateCreateInfo
869                                     nullptr,                          // multisampleStateCreateInfo
870                                     nullptr,                          // depthStencilStateCreateInfo
871                                     nullptr,                          // colorBlendStateCreateInfo
872                                     &dynamicStateCreateInfo);         // dynamicStateCreateInfo
873 }
874 
createBuffers(std::vector<VkDescriptorBufferInfo> & bufferInfos,ut::BufferHandleAllocSp & buffer,uint32_t elementCount,uint32_t elementSize,VkDeviceSize alignment,VkBufferUsageFlags bufferUsage)875 VkDeviceSize CommonDescriptorInstance::createBuffers(std::vector<VkDescriptorBufferInfo> &bufferInfos,
876                                                      ut::BufferHandleAllocSp &buffer, uint32_t elementCount,
877                                                      uint32_t elementSize, VkDeviceSize alignment,
878                                                      VkBufferUsageFlags bufferUsage)
879 {
880     const VkDeviceSize roundedSize = deAlign64(elementSize, alignment);
881     VkDeviceSize bufferSize = ut::createBufferAndBind(buffer, m_context, bufferUsage, (roundedSize * elementCount));
882 
883     for (uint32_t elementIdx = 0; elementIdx < elementCount; ++elementIdx)
884     {
885         const VkDescriptorBufferInfo bufferInfo = {
886             *buffer.get()->buffer,    //buffer;
887             elementIdx * roundedSize, //offset;
888             elementSize,              // range;
889 
890         };
891         bufferInfos.push_back(bufferInfo);
892     }
893 
894     return bufferSize;
895 }
896 
createImages(std::vector<ut::ImageHandleAllocSp> & images,std::vector<VkDescriptorBufferInfo> & bufferInfos,ut::BufferHandleAllocSp & buffer,VkBufferUsageFlags bufferUsage,const VkExtent3D & imageExtent,VkFormat imageFormat,VkImageLayout imageLayout,uint32_t imageCount,bool withMipMaps)897 VkDeviceSize CommonDescriptorInstance::createImages(std::vector<ut::ImageHandleAllocSp> &images,
898                                                     std::vector<VkDescriptorBufferInfo> &bufferInfos,
899                                                     ut::BufferHandleAllocSp &buffer, VkBufferUsageFlags bufferUsage,
900                                                     const VkExtent3D &imageExtent, VkFormat imageFormat,
901                                                     VkImageLayout imageLayout, uint32_t imageCount, bool withMipMaps)
902 
903 {
904     const uint32_t imageSize = ut::computeImageSize(imageExtent, imageFormat, withMipMaps);
905 
906     const VkDeviceSize bufferSize =
907         createBuffers(bufferInfos, buffer, imageCount, imageSize, sizeof(tcu::Vec4), bufferUsage);
908 
909     for (uint32_t imageIdx = 0; imageIdx < imageCount; ++imageIdx)
910     {
911         ut::ImageHandleAllocSp image;
912         ut::createImageAndBind(image, m_context, imageFormat, imageExtent, imageLayout, withMipMaps);
913         images.push_back(image);
914     }
915 
916     return bufferSize;
917 }
918 
createBuffersViews(std::vector<ut::BufferViewSp> & views,const std::vector<VkDescriptorBufferInfo> & bufferInfos,VkFormat format)919 void CommonDescriptorInstance::createBuffersViews(std::vector<ut::BufferViewSp> &views,
920                                                   const std::vector<VkDescriptorBufferInfo> &bufferInfos,
921                                                   VkFormat format)
922 {
923     const uint32_t infoCount = static_cast<uint32_t>(bufferInfos.size());
924     for (uint32_t infoIdx = 0; infoIdx < infoCount; ++infoIdx)
925     {
926         const VkDescriptorBufferInfo &bufferInfo    = bufferInfos[infoIdx];
927         const VkBufferViewCreateInfo bufferViewInfo = {
928             VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO, // sType
929             nullptr,                                   // pNext
930             (VkBufferViewCreateFlags)0,                // flags
931             bufferInfo.buffer,                         // buffer
932             format,                                    // format
933             bufferInfo.offset,                         // offset
934             bufferInfo.range                           // range;
935         };
936         views.push_back(ut::BufferViewSp(new Move<VkBufferView>(vk::createBufferView(m_vki, m_vkd, &bufferViewInfo))));
937     }
938 }
939 
createImagesViews(std::vector<ut::ImageViewSp> & views,const std::vector<ut::ImageHandleAllocSp> & images,VkFormat format)940 void CommonDescriptorInstance::createImagesViews(std::vector<ut::ImageViewSp> &views,
941                                                  const std::vector<ut::ImageHandleAllocSp> &images, VkFormat format)
942 {
943     const uint32_t imageCount = static_cast<uint32_t>(images.size());
944     for (uint32_t imageIdx = 0; imageIdx < imageCount; ++imageIdx)
945     {
946         const VkImageViewCreateInfo createInfo = {
947             VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // sType
948             nullptr,                                  // pNext
949             (VkImageViewCreateFlags)0,                // flags
950             *images[imageIdx]->image,                 // image
951             VK_IMAGE_VIEW_TYPE_2D,                    // viewType
952             format,                                   // format
953             vk::makeComponentMappingRGBA(),           // components
954             {
955                 VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
956                 (uint32_t)0,               // baseMipLevel
957                 images[imageIdx]->levels,  // mipLevels
958                 (uint32_t)0,               // baseArrayLayer
959                 (uint32_t)1u,              // arraySize
960             },
961         };
962         views.push_back(ut::ImageViewSp(new Move<VkImageView>(vk::createImageView(m_vki, m_vkd, &createInfo))));
963     }
964 }
965 
copyBuffersToImages(IterateCommonVariables & variables)966 void CommonDescriptorInstance::copyBuffersToImages(IterateCommonVariables &variables)
967 {
968     const uint32_t infoCount = static_cast<uint32_t>(variables.descriptorsBufferInfos.size());
969     DE_ASSERT(variables.descriptorsImages.size() == infoCount);
970     const VkPipelineStageFlagBits dstStageMask = (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT) ?
971                                                      VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT :
972                                                      VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
973     for (uint32_t infoIdx = 0; infoIdx < infoCount; ++infoIdx)
974     {
975         ut::recordCopyBufferToImage(*variables.commandBuffer,                       // commandBuffer
976                                     m_vki,                                          // interface
977                                     VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,              // srcStageMask
978                                     dstStageMask,                                   // dstStageMask
979                                     variables.descriptorsBufferInfos[infoIdx],      // bufferInfo
980                                     *(variables.descriptorsImages[infoIdx]->image), // image
981                                     variables.descriptorsImages[infoIdx]->extent,   // imageExtent
982                                     variables.descriptorsImages[infoIdx]->format,   // imageFormat
983                                     VK_IMAGE_LAYOUT_UNDEFINED,                      // oldImageLayout
984                                     VK_IMAGE_LAYOUT_GENERAL,                        // newImageLayout
985                                     variables.descriptorsImages[infoIdx]->levels);  // mipLevelCount
986     }
987 }
988 
copyImagesToBuffers(IterateCommonVariables & variables)989 void CommonDescriptorInstance::copyImagesToBuffers(IterateCommonVariables &variables)
990 {
991     const uint32_t infoCount = static_cast<uint32_t>(variables.descriptorsBufferInfos.size());
992     DE_ASSERT(variables.descriptorsImages.size() == infoCount);
993     const VkPipelineStageFlagBits srcStageMask = (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT) ?
994                                                      VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT :
995                                                      VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
996 
997     for (uint32_t infoIdx = 0; infoIdx < infoCount; ++infoIdx)
998     {
999         ut::recordCopyImageToBuffer(*variables.commandBuffer,                       // commandBuffer
1000                                     m_vki,                                          // interface
1001                                     srcStageMask,                                   // srcStageMask
1002                                     VK_PIPELINE_STAGE_HOST_BIT,                     // dstStageMask
1003                                     *(variables.descriptorsImages[infoIdx]->image), // image
1004                                     variables.descriptorsImages[infoIdx]->extent,   // imageExtent
1005                                     variables.descriptorsImages[infoIdx]->format,   // imageFormat
1006                                     VK_IMAGE_LAYOUT_GENERAL,                        // oldImageLayout
1007                                     VK_IMAGE_LAYOUT_GENERAL,                        // newImageLayout
1008                                     variables.descriptorsBufferInfos[infoIdx]);     // bufferInfo
1009     }
1010 }
1011 
getPixelAccess(uint32_t imageIndex,const VkExtent3D & imageExtent,VkFormat imageFormat,const std::vector<VkDescriptorBufferInfo> & bufferInfos,const ut::BufferHandleAllocSp & buffer,uint32_t mipLevel) const1012 PixelBufferAccess CommonDescriptorInstance::getPixelAccess(uint32_t imageIndex, const VkExtent3D &imageExtent,
1013                                                            VkFormat imageFormat,
1014                                                            const std::vector<VkDescriptorBufferInfo> &bufferInfos,
1015                                                            const ut::BufferHandleAllocSp &buffer,
1016                                                            uint32_t mipLevel) const
1017 {
1018     DE_ASSERT(bufferInfos[imageIndex].buffer == *buffer.get()->buffer);
1019     DE_ASSERT(ut::computeImageSize(imageExtent, imageFormat, true, (mipLevel ? ut::maxDeUint32 : 0)) <=
1020               bufferInfos[imageIndex].range);
1021     DE_ASSERT(imageExtent.width >> mipLevel);
1022     DE_ASSERT(imageExtent.height >> mipLevel);
1023 
1024     uint32_t mipOffset = 0;
1025 
1026     for (uint32_t level = 0; mipLevel && level < mipLevel; ++level)
1027     {
1028         mipOffset += ut::computeImageSize(imageExtent, imageFormat, true, level);
1029     }
1030 
1031     unsigned char *hostPtr = static_cast<unsigned char *>(buffer->alloc->getHostPtr());
1032     unsigned char *data    = hostPtr + bufferInfos[imageIndex].offset + mipOffset;
1033     return tcu::PixelBufferAccess(vk::mapVkFormat(imageFormat), (imageExtent.width >> mipLevel),
1034                                   (imageExtent.height >> mipLevel), imageExtent.depth, data);
1035 }
1036 
updateDescriptors(IterateCommonVariables & variables)1037 void CommonDescriptorInstance::updateDescriptors(IterateCommonVariables &variables)
1038 {
1039     const std::vector<uint32_t> primes = ut::generatePrimes(variables.availableDescriptorCount);
1040     const uint32_t primeCount          = static_cast<uint32_t>(primes.size());
1041 
1042     for (uint32_t primeIdx = 0; primeIdx < primeCount; ++primeIdx)
1043     {
1044         const VkDescriptorBufferInfo *pBufferInfo = nullptr;
1045         const VkDescriptorImageInfo *pImageInfo   = nullptr;
1046         const VkBufferView *pTexelBufferView      = nullptr;
1047 
1048         VkDescriptorImageInfo imageInfo = {VK_NULL_HANDLE, VK_NULL_HANDLE, VK_IMAGE_LAYOUT_GENERAL};
1049 
1050         switch (m_testParams.descriptorType)
1051         {
1052         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1053         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1054         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1055         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1056         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1057         case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1058         {
1059             pBufferInfo = &variables.descriptorsBufferInfos[primeIdx];
1060             switch (m_testParams.descriptorType)
1061             {
1062             case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1063             case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1064                 pTexelBufferView = &(**variables.descriptorsBufferViews[primeIdx]);
1065                 break;
1066             default:
1067                 break;
1068             }
1069         }
1070         break;
1071 
1072         case VK_DESCRIPTOR_TYPE_SAMPLER:
1073             imageInfo.sampler = **variables.descriptorSamplers[primeIdx];
1074             pImageInfo        = &imageInfo;
1075             break;
1076 
1077         case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1078         case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1079         case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1080             imageInfo.imageView = **variables.descriptorImageViews[primeIdx];
1081             pImageInfo          = &imageInfo;
1082             break;
1083 
1084         default:
1085             break;
1086         }
1087 
1088         const VkWriteDescriptorSet writeInfo = {
1089             VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
1090             nullptr,                                // pNext
1091             *variables.descriptorSet,               // descriptorSet
1092             BINDING_TestObject,                     // descriptorBinding;
1093             primes[primeIdx],                       // elementIndex
1094             1u,                                     // descriptorCount
1095             m_testParams.descriptorType,            // descriptorType
1096             pImageInfo,                             // pImageInfo
1097             pBufferInfo,                            // pBufferInfo
1098             pTexelBufferView                        // pTexelBufferView
1099         };
1100 
1101         m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, nullptr);
1102     }
1103 }
1104 
updateUnusedDescriptors(IterateCommonVariables & variables)1105 void CommonDescriptorInstance::updateUnusedDescriptors(IterateCommonVariables &variables)
1106 {
1107     const std::vector<uint32_t> primes = ut::generatePrimes(variables.availableDescriptorCount);
1108     const uint32_t primeCount          = static_cast<uint32_t>(primes.size());
1109     uint32_t primeIndex                = 0u;
1110 
1111     for (uint32_t i = 0u; i < variables.availableDescriptorCount; ++i)
1112     {
1113         if (primeIndex < primeCount && i == primes[primeIndex])
1114         {
1115             ++primeIndex;
1116             continue;
1117         }
1118 
1119         const VkDescriptorBufferInfo *pBufferInfo = nullptr;
1120         const VkDescriptorImageInfo *pImageInfo   = nullptr;
1121         const VkBufferView *pTexelBufferView      = nullptr;
1122 
1123         VkDescriptorImageInfo imageInfo = {VK_NULL_HANDLE, VK_NULL_HANDLE, VK_IMAGE_LAYOUT_GENERAL};
1124 
1125         switch (m_testParams.descriptorType)
1126         {
1127         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1128         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1129         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1130         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1131         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1132         case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1133         {
1134             pBufferInfo = &variables.unusedDescriptorsBufferInfos[0];
1135             switch (m_testParams.descriptorType)
1136             {
1137             case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1138             case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1139                 pTexelBufferView = &(**variables.unusedDescriptorsBufferViews[0]);
1140                 break;
1141             default:
1142                 break;
1143             }
1144         }
1145         break;
1146 
1147         case VK_DESCRIPTOR_TYPE_SAMPLER:
1148             imageInfo.sampler = **variables.unusedDescriptorSamplers[0];
1149             pImageInfo        = &imageInfo;
1150             break;
1151 
1152         case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1153         case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1154         case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1155             imageInfo.imageView = **variables.unusedDescriptorImageViews[0];
1156             pImageInfo          = &imageInfo;
1157             break;
1158 
1159         case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1160             imageInfo.sampler   = **variables.unusedDescriptorSamplers[0];
1161             imageInfo.imageView = **variables.unusedDescriptorImageViews[0];
1162             pImageInfo          = &imageInfo;
1163             break;
1164 
1165         default:
1166             break;
1167         }
1168 
1169         const VkWriteDescriptorSet writeInfo = {
1170             VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
1171             nullptr,                                // pNext
1172             *variables.descriptorSet,               // descriptorSet
1173             BINDING_TestObject,                     // descriptorBinding;
1174             i,                                      // elementIndex
1175             1u,                                     // descriptorCount
1176             m_testParams.descriptorType,            // descriptorType
1177             pImageInfo,                             // pImageInfo
1178             pBufferInfo,                            // pBufferInfo
1179             pTexelBufferView                        // pTexelBufferView
1180         };
1181 
1182         m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, nullptr);
1183     }
1184 }
1185 
destroyUnusedResources(IterateCommonVariables & variables)1186 void CommonDescriptorInstance::destroyUnusedResources(IterateCommonVariables &variables)
1187 {
1188     variables.unusedDescriptorsBufferInfos.clear();
1189     variables.unusedDescriptorsBufferViews.clear();
1190     variables.unusedDescriptorImageViews.clear();
1191     variables.unusedDescriptorSamplers.clear();
1192     variables.unusedDescriptorsImages.clear();
1193 }
1194 
iterateCommandSetup(IterateCommonVariables & variables)1195 void CommonDescriptorInstance::iterateCommandSetup(IterateCommonVariables &variables)
1196 {
1197     variables.dataAlignment = 0;
1198 
1199     variables.renderArea.offset.x      = 0;
1200     variables.renderArea.offset.y      = 0;
1201     variables.renderArea.extent.width  = m_testParams.frameResolution.width;
1202     variables.renderArea.extent.height = m_testParams.frameResolution.height;
1203 
1204     variables.vertexCount = m_testParams.frameResolution.width * m_testParams.frameResolution.height;
1205 
1206     variables.lowerBound = 0;
1207     variables.upperBound = variables.vertexCount;
1208 
1209     variables.descriptorSetLayout =
1210         createDescriptorSetLayout(m_testParams.calculateInLoop, variables.availableDescriptorCount);
1211     variables.validDescriptorCount = ut::computePrimeCount(variables.availableDescriptorCount);
1212     variables.descriptorPool       = createDescriptorPool(variables.availableDescriptorCount);
1213     variables.descriptorSet        = createDescriptorSet(*variables.descriptorPool, *variables.descriptorSetLayout);
1214 
1215     std::vector<VkDescriptorSetLayout> descriptorSetLayouts;
1216     descriptorSetLayouts.push_back(*variables.descriptorSetLayout);
1217     if (m_testParams.calculateInLoop)
1218     {
1219         variables.descriptorEnumerator.init(m_context, variables.vertexCount, variables.availableDescriptorCount);
1220         descriptorSetLayouts.push_back(*variables.descriptorEnumerator.descriptorSetLayout);
1221     }
1222 
1223     variables.pipelineLayout = createPipelineLayout(descriptorSetLayouts);
1224 
1225     createAndPopulateDescriptors(variables);
1226 
1227     variables.renderPass = createRenderPass(variables);
1228     variables.pipeline   = createPipeline(*variables.pipelineLayout, *variables.renderPass);
1229 
1230     variables.commandBuffer = createCmdBuffer();
1231 
1232     if ((m_testParams.stageFlags & VK_SHADER_STAGE_VERTEX_BIT) ||
1233         (m_testParams.stageFlags & VK_SHADER_STAGE_FRAGMENT_BIT))
1234     {
1235         createVertexAttributeBuffer(variables.vertexAttributesBuffer, variables.availableDescriptorCount);
1236         createFramebuffer(variables.frameBuffer, *variables.renderPass, variables);
1237     }
1238 
1239     if (m_testParams.calculateInLoop)
1240     {
1241         variables.descriptorEnumerator.update(m_context);
1242     }
1243 
1244     if (!m_testParams.updateAfterBind)
1245     {
1246         updateDescriptors(variables);
1247     }
1248 }
1249 
iterateCommandBegin(IterateCommonVariables & variables,bool firstPass)1250 void CommonDescriptorInstance::iterateCommandBegin(IterateCommonVariables &variables, bool firstPass)
1251 {
1252     if (m_testParams.lifetimeCheck)
1253     {
1254         createAndPopulateUnusedDescriptors(variables);
1255 
1256         if (!m_testParams.updateAfterBind)
1257             updateUnusedDescriptors(variables);
1258     }
1259 
1260     vk::beginCommandBuffer(m_vki, *variables.commandBuffer);
1261 
1262     // Clear color attachment, and transition it to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
1263     if ((m_testParams.stageFlags & VK_SHADER_STAGE_VERTEX_BIT) ||
1264         (m_testParams.stageFlags & VK_SHADER_STAGE_FRAGMENT_BIT))
1265     {
1266         if (firstPass)
1267         {
1268             const VkImageMemoryBarrier preImageBarrier = {
1269                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType        sType
1270                 nullptr,                                // const void*            pNext
1271                 0u,                                     // VkAccessFlags        srcAccessMask
1272                 VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags        dstAccessMask
1273                 VK_IMAGE_LAYOUT_UNDEFINED,              // VkImageLayout        oldLayout
1274                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout        newLayout
1275                 VK_QUEUE_FAMILY_IGNORED,                // uint32_t                srcQueueFamilyIndex
1276                 VK_QUEUE_FAMILY_IGNORED,                // uint32_t                dstQueueFamilyIndex
1277                 *variables.frameBuffer->image->image,   // VkImage                image
1278                 {
1279                     VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags    aspectMask
1280                     0u,                        // uint32_t                baseMipLevel
1281                     VK_REMAINING_MIP_LEVELS,   // uint32_t                mipLevels,
1282                     0u,                        // uint32_t                baseArray
1283                     VK_REMAINING_ARRAY_LAYERS, // uint32_t                arraySize
1284                 }};
1285 
1286             m_vki.cmdPipelineBarrier(*variables.commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
1287                                      VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, nullptr, 0, nullptr, 1,
1288                                      &preImageBarrier);
1289 
1290             const VkClearColorValue clearColorValue = makeClearValueColor(m_clearColor).color;
1291 
1292             m_vki.cmdClearColorImage(*variables.commandBuffer, *variables.frameBuffer->image->image,
1293                                      VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColorValue, 1,
1294                                      &preImageBarrier.subresourceRange);
1295 
1296             const VkImageMemoryBarrier postImageBarrier = {
1297                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType        sType
1298                 nullptr,                                // const void*            pNext
1299                 VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags        srcAccessMask
1300                 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
1301                     VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags        dstAccessMask
1302                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,     // VkImageLayout        oldLayout
1303                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout        newLayout
1304                 VK_QUEUE_FAMILY_IGNORED,                  // uint32_t                srcQueueFamilyIndex
1305                 VK_QUEUE_FAMILY_IGNORED,                  // uint32_t                dstQueueFamilyIndex
1306                 *variables.frameBuffer->image->image,     // VkImage                image
1307                 {
1308                     VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags    aspectMask
1309                     0u,                        // uint32_t                baseMipLevel
1310                     VK_REMAINING_MIP_LEVELS,   // uint32_t                mipLevels,
1311                     0u,                        // uint32_t                baseArray
1312                     VK_REMAINING_ARRAY_LAYERS, // uint32_t                arraySize
1313                 }};
1314 
1315             m_vki.cmdPipelineBarrier(*variables.commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
1316                                      VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0, 0, nullptr, 0,
1317                                      nullptr, 1, &postImageBarrier);
1318         }
1319     }
1320 
1321     if (m_testParams.calculateInLoop)
1322     {
1323         deRandom rnd;
1324         deRandom_init(&rnd, static_cast<uint32_t>(m_testParams.descriptorType));
1325         const uint32_t quarter = variables.vertexCount / 4;
1326 
1327         variables.lowerBound = deRandom_getUint32(&rnd) % quarter;
1328         variables.upperBound = (deRandom_getUint32(&rnd) % quarter) + (3 * quarter);
1329 
1330         const push_constant pc = {static_cast<int32_t>(variables.lowerBound),
1331                                   static_cast<int32_t>(variables.upperBound)};
1332 
1333         m_vki.cmdPushConstants(*variables.commandBuffer, *variables.pipelineLayout, m_testParams.stageFlags, 0u,
1334                                static_cast<uint32_t>(sizeof(pc)), &pc);
1335     }
1336 
1337     if ((m_testParams.stageFlags & VK_SHADER_STAGE_VERTEX_BIT) ||
1338         (m_testParams.stageFlags & VK_SHADER_STAGE_FRAGMENT_BIT))
1339     {
1340         commandBindVertexAttributes(*variables.commandBuffer, variables.vertexAttributesBuffer);
1341     }
1342 
1343     if (m_testParams.calculateInLoop)
1344     {
1345         commandBindDescriptorSets(*variables.commandBuffer, *variables.pipelineLayout,
1346                                   *variables.descriptorEnumerator.descriptorSet, 1);
1347     }
1348 
1349     if (!ut::isDynamicDescriptor(m_testParams.descriptorType))
1350     {
1351         commandBindDescriptorSets(*variables.commandBuffer, *variables.pipelineLayout, *variables.descriptorSet, 0);
1352     }
1353 
1354     commandBindPipeline(*variables.commandBuffer, *variables.pipeline);
1355 }
1356 
iterate(void)1357 tcu::TestStatus CommonDescriptorInstance::iterate(void)
1358 {
1359     IterateCommonVariables v;
1360     ut::UpdatablePixelBufferAccessPtr programResult;
1361     ut::UpdatablePixelBufferAccessPtr referenceResult;
1362 
1363     bool firstPass = true;
1364 
1365     iterateCommandSetup(v);
1366 
1367     v.renderArea.extent.width  = m_testParams.frameResolution.width / 4;
1368     v.renderArea.extent.height = m_testParams.frameResolution.height / 4;
1369 
1370     for (int x = 0; x < 4; x++)
1371         for (int y = 0; y < 4; y++)
1372         {
1373             iterateCommandBegin(v, firstPass);
1374 
1375             if (true == firstPass && true == m_testParams.copyBuffersToImages)
1376             {
1377                 copyBuffersToImages(v);
1378             }
1379 
1380             firstPass = false;
1381 
1382             if (true == m_testParams.updateAfterBind)
1383             {
1384                 updateDescriptors(v);
1385             }
1386 
1387             v.renderArea.offset.x = x * m_testParams.frameResolution.width / 4;
1388             v.renderArea.offset.y = y * m_testParams.frameResolution.height / 4;
1389 
1390             vk::VkRect2D scissor = makeRect2D(v.renderArea.offset.x, v.renderArea.offset.y, v.renderArea.extent.width,
1391                                               v.renderArea.extent.height);
1392             m_vki.cmdSetScissor(*v.commandBuffer, 0u, 1u, &scissor);
1393 
1394             vk::beginRenderPass(m_vki, *v.commandBuffer, *v.renderPass, *v.frameBuffer->buffer, v.renderArea,
1395                                 m_clearColor);
1396             m_vki.cmdDraw(*v.commandBuffer, v.vertexCount, 1u, 0u, 0u);
1397             vk::endRenderPass(m_vki, *v.commandBuffer);
1398 
1399             iterateCommandEnd(v, programResult, referenceResult);
1400             programResult->invalidate();
1401         }
1402 
1403     if (iterateVerifyResults(v, programResult, referenceResult))
1404         return tcu::TestStatus::pass("Pass");
1405     return tcu::TestStatus::fail("Failed -- check log for details");
1406 }
1407 
createColorScheme(void)1408 std::vector<float> CommonDescriptorInstance::createColorScheme(void)
1409 {
1410     std::vector<float> cs;
1411     int divider = 2;
1412     for (int i = 0; i < 10; ++i)
1413     {
1414         cs.push_back(1.0f / float(divider));
1415         divider *= 2;
1416     }
1417     return cs;
1418 }
1419 
iterateCommandEnd(IterateCommonVariables & variables,ut::UpdatablePixelBufferAccessPtr & programResult,ut::UpdatablePixelBufferAccessPtr & referenceResult,bool collectBeforeSubmit)1420 void CommonDescriptorInstance::iterateCommandEnd(IterateCommonVariables &variables,
1421                                                  ut::UpdatablePixelBufferAccessPtr &programResult,
1422                                                  ut::UpdatablePixelBufferAccessPtr &referenceResult,
1423                                                  bool collectBeforeSubmit)
1424 {
1425     // Destroy unused descriptor resources to test there's no issues as allowed by the spec
1426     if (m_testParams.lifetimeCheck)
1427         destroyUnusedResources(variables);
1428 
1429     if (collectBeforeSubmit)
1430     {
1431         iterateCollectResults(programResult, variables, true);
1432         iterateCollectResults(referenceResult, variables, false);
1433     }
1434 
1435     VK_CHECK(m_vki.endCommandBuffer(*variables.commandBuffer));
1436     Move<VkFence> fence = commandSubmit(*variables.commandBuffer);
1437     m_vki.waitForFences(m_vkd, 1, &(*fence), true, ~0ull);
1438 
1439     if (false == collectBeforeSubmit)
1440     {
1441         iterateCollectResults(programResult, variables, true);
1442         iterateCollectResults(referenceResult, variables, false);
1443     }
1444     m_context.resetCommandPoolForVKSC(m_vkd, *m_commandPool);
1445 }
1446 
iterateVerifyResults(IterateCommonVariables & variables,ut::UpdatablePixelBufferAccessPtr programResult,ut::UpdatablePixelBufferAccessPtr referenceResult)1447 bool CommonDescriptorInstance::iterateVerifyResults(IterateCommonVariables &variables,
1448                                                     ut::UpdatablePixelBufferAccessPtr programResult,
1449                                                     ut::UpdatablePixelBufferAccessPtr referenceResult)
1450 {
1451     bool result = false;
1452     if (FUZZY_COMPARE)
1453     {
1454         result = tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Fuzzy Compare", "Comparison result",
1455                                    *referenceResult.get(), *programResult.get(), 0.02f, tcu::COMPARE_LOG_EVERYTHING);
1456     }
1457     else
1458     {
1459         result = tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Float Threshold Compare",
1460                                             "Comparison result", *referenceResult.get(), *programResult.get(),
1461                                             tcu::Vec4(0.02f, 0.02f, 0.02f, 0.02f), tcu::COMPARE_LOG_EVERYTHING);
1462     }
1463 
1464     if (m_testParams.allowVertexStoring)
1465     {
1466         result = (verifyVertexWriteResults(variables) && result);
1467     }
1468 
1469     return result;
1470 }
1471 
iterateCollectResults(ut::UpdatablePixelBufferAccessPtr & result,const IterateCommonVariables & variables,bool fromTest)1472 void CommonDescriptorInstance::iterateCollectResults(ut::UpdatablePixelBufferAccessPtr &result,
1473                                                      const IterateCommonVariables &variables, bool fromTest)
1474 {
1475     if (fromTest)
1476     {
1477         result = commandReadFrameBuffer(*variables.commandBuffer, variables.frameBuffer);
1478     }
1479     else
1480     {
1481         result = ut::UpdatablePixelBufferAccessPtr(
1482             new ut::PixelBufferAccessAllocation(vk::mapVkFormat(m_colorFormat), m_testParams.frameResolution));
1483 
1484         for (uint32_t y = 0, pixelNum = 0; y < m_testParams.frameResolution.height; ++y)
1485         {
1486             for (uint32_t x = 0; x < m_testParams.frameResolution.width; ++x, ++pixelNum)
1487             {
1488                 const float component = m_colorScheme[(pixelNum % variables.validDescriptorCount) % m_schemeSize];
1489                 result->setPixel(tcu::Vec4(component, component, component, 1.0f), x, y);
1490             }
1491         }
1492     }
1493 }
1494 
createCmdBuffer(void)1495 Move<VkCommandBuffer> CommonDescriptorInstance::createCmdBuffer(void)
1496 {
1497     return vk::allocateCommandBuffer(m_vki, m_vkd, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1498 }
1499 
commandSubmit(VkCommandBuffer cmd)1500 Move<VkFence> CommonDescriptorInstance::commandSubmit(VkCommandBuffer cmd)
1501 {
1502     Move<VkFence> fence(vk::createFence(m_vki, m_vkd));
1503 
1504     const VkSubmitInfo submitInfo = {
1505         VK_STRUCTURE_TYPE_SUBMIT_INFO,                      // sType
1506         nullptr,                                            // pNext
1507         0u,                                                 // waitSemaphoreCount
1508         static_cast<VkSemaphore *>(nullptr),                // pWaitSemaphores
1509         static_cast<const VkPipelineStageFlags *>(nullptr), // pWaitDstStageMask
1510         1u,                                                 // commandBufferCount
1511         &cmd,                                               // pCommandBuffers
1512         0u,                                                 // signalSemaphoreCount
1513         static_cast<VkSemaphore *>(nullptr)                 // pSignalSemaphores
1514     };
1515 
1516     VK_CHECK(m_vki.queueSubmit(m_queue, 1u, &submitInfo, *fence));
1517 
1518     return fence;
1519 }
1520 
verifyVertexWriteResults(IterateCommonVariables & variables)1521 bool CommonDescriptorInstance::verifyVertexWriteResults(IterateCommonVariables &variables)
1522 {
1523     DE_UNREF(variables);
1524     return true;
1525 }
1526 
commandBindPipeline(VkCommandBuffer commandBuffer,VkPipeline pipeline)1527 void CommonDescriptorInstance::commandBindPipeline(VkCommandBuffer commandBuffer, VkPipeline pipeline)
1528 {
1529     const VkPipelineBindPoint pipelineBindingPoint = (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT) ?
1530                                                          VK_PIPELINE_BIND_POINT_COMPUTE :
1531                                                          VK_PIPELINE_BIND_POINT_GRAPHICS;
1532     m_vki.cmdBindPipeline(commandBuffer, pipelineBindingPoint, pipeline);
1533 }
1534 
commandBindVertexAttributes(VkCommandBuffer commandBuffer,const ut::BufferHandleAllocSp & vertexAttributesBuffer)1535 void CommonDescriptorInstance::commandBindVertexAttributes(VkCommandBuffer commandBuffer,
1536                                                            const ut::BufferHandleAllocSp &vertexAttributesBuffer)
1537 {
1538     const VkDeviceSize offsets[] = {0u};
1539     const VkBuffer buffers[]     = {*vertexAttributesBuffer->buffer};
1540     m_vki.cmdBindVertexBuffers(commandBuffer, 0u, 1u, buffers, offsets);
1541 }
1542 
commandBindDescriptorSets(VkCommandBuffer commandBuffer,VkPipelineLayout pipelineLayout,VkDescriptorSet descriptorSet,uint32_t descriptorSetIndex)1543 void CommonDescriptorInstance::commandBindDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineLayout pipelineLayout,
1544                                                          VkDescriptorSet descriptorSet, uint32_t descriptorSetIndex)
1545 {
1546     const VkPipelineBindPoint pipelineBindingPoint = (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT) ?
1547                                                          VK_PIPELINE_BIND_POINT_COMPUTE :
1548                                                          VK_PIPELINE_BIND_POINT_GRAPHICS;
1549     m_vki.cmdBindDescriptorSets(commandBuffer, pipelineBindingPoint, pipelineLayout, descriptorSetIndex, 1u,
1550                                 &descriptorSet, 0u, static_cast<uint32_t *>(nullptr));
1551 }
1552 
commandReadFrameBuffer(VkCommandBuffer commandBuffer,const ut::FrameBufferSp & frameBuffer)1553 ut::UpdatablePixelBufferAccessPtr CommonDescriptorInstance::commandReadFrameBuffer(VkCommandBuffer commandBuffer,
1554                                                                                    const ut::FrameBufferSp &frameBuffer)
1555 {
1556     ut::BufferHandleAllocSp frameBufferContent;
1557     commandReadFrameBuffer(frameBufferContent, commandBuffer, frameBuffer);
1558     return ut::UpdatablePixelBufferAccessPtr(new ut::PixelBufferAccessBuffer(
1559         m_vkd, m_vki, vk::mapVkFormat(m_colorFormat), m_testParams.frameResolution,
1560         de::SharedPtr<Move<VkBuffer>>(new Move<VkBuffer>(frameBufferContent->buffer)),
1561         de::SharedPtr<de::MovePtr<Allocation>>(new de::MovePtr<Allocation>(frameBufferContent->alloc))));
1562 }
1563 
commandReadFrameBuffer(ut::BufferHandleAllocSp & content,VkCommandBuffer commandBuffer,const ut::FrameBufferSp & frameBuffer)1564 void CommonDescriptorInstance::commandReadFrameBuffer(ut::BufferHandleAllocSp &content, VkCommandBuffer commandBuffer,
1565                                                       const ut::FrameBufferSp &frameBuffer)
1566 {
1567     Move<VkBuffer> buffer;
1568     de::MovePtr<Allocation> allocation;
1569 
1570     const VkDeviceSize bufferSize = ut::computeImageSize(frameBuffer->image);
1571 
1572     // create a buffer and an host allocation for it
1573     {
1574         const VkBufferCreateInfo bufferCreateInfo = {
1575             VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType
1576             nullptr,                              // pNext
1577             0u,                                   // flags
1578             bufferSize,                           // size
1579             VK_BUFFER_USAGE_TRANSFER_DST_BIT,     // usage
1580             VK_SHARING_MODE_EXCLUSIVE,            // sharingMode
1581             1u,                                   // queueFamilyIndexCoun
1582             &m_queueFamilyIndex                   // pQueueFamilyIndices
1583         };
1584 
1585         buffer = vk::createBuffer(m_vki, m_vkd, &bufferCreateInfo);
1586         const VkMemoryRequirements memRequirements(vk::getBufferMemoryRequirements(m_vki, m_vkd, *buffer));
1587         allocation = m_allocator.allocate(memRequirements, MemoryRequirement::HostVisible);
1588 
1589         VK_CHECK(m_vki.bindBufferMemory(m_vkd, *buffer, allocation->getMemory(), allocation->getOffset()));
1590     }
1591 
1592     const VkImage &image = *frameBuffer->image->image;
1593 
1594     VkImageSubresourceRange subresourceRange = {
1595         VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
1596         0u,                        // baseMipLevel
1597         1u,                        // levelCount
1598         0u,                        // baseArrayLayer
1599         1u                         // layerCount
1600     };
1601 
1602     const VkImageMemoryBarrier barrierBefore = {
1603         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,   // sType;
1604         nullptr,                                  // pNext;
1605         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,     // srcAccessMask;
1606         VK_ACCESS_TRANSFER_READ_BIT,              // dstAccessMask;
1607         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // oldLayout
1608         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,     // newLayout;
1609         VK_QUEUE_FAMILY_IGNORED,                  // srcQueueFamilyIndex;
1610         VK_QUEUE_FAMILY_IGNORED,                  // dstQueueFamilyIndex;
1611         image,                                    // image;
1612         subresourceRange                          // subresourceRange;
1613     };
1614 
1615     const VkBufferImageCopy copyRegion = {
1616         0u,                                // bufferOffset
1617         frameBuffer->image->extent.width,  // bufferRowLength
1618         frameBuffer->image->extent.height, // bufferImageHeight
1619         {
1620             // VkImageSubresourceLayers
1621             VK_IMAGE_ASPECT_COLOR_BIT, // aspect
1622             0u,                        // mipLevel
1623             0u,                        // baseArrayLayer
1624             1u,                        // layerCount
1625         },
1626         {0, 0, 0},                 // imageOffset
1627         frameBuffer->image->extent // imageExtent
1628     };
1629 
1630     const VkBufferMemoryBarrier bufferBarrier = {
1631         VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // sType;
1632         nullptr,                                 // pNext;
1633         VK_ACCESS_TRANSFER_WRITE_BIT,            // srcAccessMask;
1634         VK_ACCESS_HOST_READ_BIT,                 // dstAccessMask;
1635         VK_QUEUE_FAMILY_IGNORED,                 // srcQueueFamilyIndex;
1636         VK_QUEUE_FAMILY_IGNORED,                 // dstQueueFamilyIndex;
1637         *buffer,                                 // buffer;
1638         0u,                                      // offset;
1639         bufferSize                               // size;
1640     };
1641 
1642     const VkImageMemoryBarrier barrierAfter = {
1643         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,   // sType;
1644         nullptr,                                  // pNext;
1645         VK_ACCESS_TRANSFER_READ_BIT,              // srcAccessMask;
1646         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,     // dstAccessMask;
1647         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,     // oldLayout;
1648         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // newLayout;
1649         VK_QUEUE_FAMILY_IGNORED,                  // srcQueueFamilyIndex;
1650         VK_QUEUE_FAMILY_IGNORED,                  // dstQueueFamilyIndex;
1651         image,                                    // image
1652         subresourceRange                          // subresourceRange
1653     };
1654 
1655     m_vki.cmdPipelineBarrier(commandBuffer, // commandBuffer
1656                              VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1657                              VK_PIPELINE_STAGE_TRANSFER_BIT, // srcStageMask, dstStageMask
1658                              (VkDependencyFlags)0,           // dependencyFlags
1659                              0u, nullptr,                    // memoryBarrierCount, pMemoryBarriers
1660                              0u, nullptr,                    // bufferBarrierCount, pBufferBarriers
1661                              1u, &barrierBefore);            // imageBarrierCount, pImageBarriers
1662 
1663     m_vki.cmdCopyImageToBuffer(commandBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, &copyRegion);
1664 
1665     m_vki.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
1666                              VK_PIPELINE_STAGE_HOST_BIT | VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (VkDependencyFlags)0, 0u,
1667                              nullptr, 1u, &bufferBarrier, 1u, &barrierAfter);
1668 
1669     content = ut::BufferHandleAllocSp(new ut::BufferHandleAlloc(buffer, allocation));
1670 }
1671 
getColorAccess(VkDescriptorType descriptorType,const char * indexVariableName,bool usesMipMaps)1672 std::string CommonDescriptorInstance::getColorAccess(VkDescriptorType descriptorType, const char *indexVariableName,
1673                                                      bool usesMipMaps)
1674 {
1675     std::string text;
1676     std::map<std::string, std::string> vars;
1677     vars["INDEX"] = indexVariableName;
1678 
1679     switch (descriptorType)
1680     {
1681     case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1682     case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1683         text = "data[nonuniformEXT(${INDEX})].c";
1684         break;
1685     case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1686     case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1687         text = "data[nonuniformEXT(${INDEX})].cold";
1688         break;
1689     case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1690         text = "subpassLoad(data[nonuniformEXT(${INDEX})]).rgba";
1691         break;
1692     case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1693         text = "texelFetch(data[nonuniformEXT(${INDEX})], 0)";
1694         break;
1695     case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1696         text = "imageLoad(data[nonuniformEXT(${INDEX})], 0)";
1697         break;
1698     case VK_DESCRIPTOR_TYPE_SAMPLER:
1699         text = usesMipMaps ? "textureLod(nonuniformEXT(sampler2D(tex, data[${INDEX}])), normalpos, 1)" :
1700                              "texture(   nonuniformEXT(sampler2D(tex, data[${INDEX}])), normalpos   )";
1701         break;
1702     case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1703         text = usesMipMaps ? "textureLod( nonuniformEXT(sampler2D(data[${INDEX}], samp)), vec2(0,0), "
1704                              "textureQueryLevels(nonuniformEXT(sampler2D(data[${INDEX}], samp)))-1)" :
1705                              "texture(    nonuniformEXT(sampler2D(data[${INDEX}], samp)), vec2(0,0)   )";
1706         break;
1707     case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1708         text = usesMipMaps ? "textureLod( data[nonuniformEXT(${INDEX})], uvec2(0,0), "
1709                              "textureQueryLevels(data[nonuniformEXT(${INDEX})])-1)" :
1710                              "texture(    data[nonuniformEXT(${INDEX})], uvec2(0,0)   )";
1711         break;
1712     default:
1713         TCU_THROW(InternalError, "Not implemented descriptor type");
1714     }
1715 
1716     return tcu::StringTemplate(text).specialize(vars);
1717 }
1718 
getFragmentReturnSource(const std::string & colorAccess)1719 std::string CommonDescriptorInstance::getFragmentReturnSource(const std::string &colorAccess)
1720 {
1721     return "  FragColor = " + colorAccess + ";\n";
1722 }
1723 
getFragmentLoopSource(const std::string & colorAccess1,const std::string & colorAccess2)1724 std::string CommonDescriptorInstance::getFragmentLoopSource(const std::string &colorAccess1,
1725                                                             const std::string &colorAccess2)
1726 {
1727     std::map<std::string, std::string> vars;
1728     vars["COLOR_ACCESS_1"] = colorAccess1;
1729     vars["COLOR_ACCESS_2"] = colorAccess2;
1730 
1731     const char *s = "  vec4 sumClr1 = vec4(0,0,0,0);        \n"
1732                     "  vec4 sumClr2 = vec4(0,0,0,0);        \n"
1733                     "  for (int i = pc.lowerBound; i < pc.upperBound; ++i)    \n"
1734                     "  {\n"
1735                     "    int loopIdx = texelFetch(iter, i).x;                \n"
1736                     "    sumClr1 += ${COLOR_ACCESS_2} + ${COLOR_ACCESS_1};    \n"
1737                     "    sumClr2 += ${COLOR_ACCESS_2};                        \n"
1738                     "  }\n"
1739                     "  FragColor = vec4(((sumClr1 - sumClr2) / float(pc.upperBound - pc.lowerBound)).rgb, 1);    \n";
1740 
1741     return tcu::StringTemplate(s).specialize(vars);
1742 }
1743 
performWritesInVertex(VkDescriptorType descriptorType)1744 bool CommonDescriptorInstance::performWritesInVertex(VkDescriptorType descriptorType)
1745 {
1746     switch (descriptorType)
1747     {
1748     case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1749     case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1750     case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1751         return true;
1752     default:
1753         return false;
1754     }
1755 }
1756 
performWritesInVertex(VkDescriptorType descriptorType,const Context & context)1757 bool CommonDescriptorInstance::performWritesInVertex(VkDescriptorType descriptorType, const Context &context)
1758 {
1759     ut::DeviceProperties dp(context);
1760     const VkPhysicalDeviceFeatures &feats = dp.physicalDeviceFeatures();
1761     return feats.vertexPipelineStoresAndAtomics && CommonDescriptorInstance::performWritesInVertex(descriptorType);
1762 }
1763 
getShaderAsm(VkShaderStageFlagBits shaderType,const TestCaseParams & testCaseParams,bool allowVertexStoring)1764 std::string CommonDescriptorInstance::getShaderAsm(VkShaderStageFlagBits shaderType,
1765                                                    const TestCaseParams &testCaseParams, bool allowVertexStoring)
1766 {
1767     std::stringstream s;
1768     switch (shaderType)
1769     {
1770     case VK_SHADER_STAGE_VERTEX_BIT:
1771         switch (testCaseParams.descriptorType)
1772         {
1773         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1774         case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1775         case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1776             s << "               OpCapability Shader\n";
1777             s << "               OpCapability SampledBuffer\n";
1778             s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
1779             s << "               OpMemoryModel Logical GLSL450\n";
1780             s << "               OpEntryPoint Vertex %main \"main\" %_ %position %in_position %normalpos %in_normalpos "
1781                  "%vIndex %gl_VertexIndex %rIndex %index %gIndex %bIndex %aIndex\n";
1782             s << "               OpSource GLSL 450\n";
1783             s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
1784             s << "               OpSourceExtension \"GL_EXT_texture_buffer\"\n";
1785             s << "               OpName %main \"main\"\n";
1786             s << "               OpName %gl_PerVertex \"gl_PerVertex\"\n";
1787             s << "               OpMemberName %gl_PerVertex 0 \"gl_Position\"\n";
1788             s << "               OpMemberName %gl_PerVertex 1 \"gl_PointSize\"\n";
1789             s << "               OpMemberName %gl_PerVertex 2 \"gl_ClipDistance\"\n";
1790             s << "               OpMemberName %gl_PerVertex 3 \"gl_CullDistance\"\n";
1791             s << "               OpName %_ \"\"\n";
1792             s << "               OpName %position \"position\"\n";
1793             s << "               OpName %in_position \"in_position\"\n";
1794             s << "               OpName %normalpos \"normalpos\"\n";
1795             s << "               OpName %in_normalpos \"in_normalpos\"\n";
1796             s << "               OpName %vIndex \"vIndex\"\n";
1797             s << "               OpName %gl_VertexIndex \"gl_VertexIndex\"\n";
1798             s << "               OpName %rIndex \"rIndex\"\n";
1799             s << "               OpName %index \"index\"\n";
1800             s << "               OpName %gIndex \"gIndex\"\n";
1801             s << "               OpName %bIndex \"bIndex\"\n";
1802             s << "               OpName %aIndex \"aIndex\"\n";
1803             s << "               OpMemberDecorate %gl_PerVertex 0 BuiltIn Position\n";
1804             s << "               OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize\n";
1805             s << "               OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance\n";
1806             s << "               OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance\n";
1807             s << "               OpDecorate %gl_PerVertex Block\n";
1808             s << "               OpDecorate %position Location 0\n";
1809             s << "               OpDecorate %in_position Location 0\n";
1810             s << "               OpDecorate %normalpos Location 1\n";
1811             s << "               OpDecorate %in_normalpos Location 1\n";
1812             s << "               OpDecorate %vIndex Location 2\n";
1813             s << "               OpDecorate %gl_VertexIndex BuiltIn VertexIndex\n";
1814             s << "               OpDecorate %rIndex Location 3\n";
1815             s << "               OpDecorate %index Location 2\n";
1816             s << "               OpDecorate %gIndex Location 4\n";
1817             s << "               OpDecorate %bIndex Location 5\n";
1818             s << "               OpDecorate %aIndex Location 6\n";
1819             s << "       %void = OpTypeVoid\n";
1820             s << "          %3 = OpTypeFunction %void\n";
1821             s << "      %float = OpTypeFloat 32\n";
1822             s << "    %v4float = OpTypeVector %float 4\n";
1823             s << "       %uint = OpTypeInt 32 0\n";
1824             s << "     %uint_1 = OpConstant %uint 1\n";
1825             s << "%_arr_float_uint_1 = OpTypeArray %float %uint_1\n";
1826             s << "%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1\n";
1827             s << "%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex\n";
1828             s << "          %_ = OpVariable %_ptr_Output_gl_PerVertex Output\n";
1829             s << "        %int = OpTypeInt 32 1\n";
1830             s << "      %int_1 = OpConstant %int 1\n";
1831             s << "%float_0_200000003 = OpConstant %float 0.200000003\n";
1832             s << "%_ptr_Output_float = OpTypePointer Output %float\n";
1833             s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
1834             s << "   %position = OpVariable %_ptr_Output_v4float Output\n";
1835             s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
1836             s << "%in_position = OpVariable %_ptr_Input_v4float Input\n";
1837             s << "    %v2float = OpTypeVector %float 2\n";
1838             s << "%_ptr_Output_v2float = OpTypePointer Output %v2float\n";
1839             s << "  %normalpos = OpVariable %_ptr_Output_v2float Output\n";
1840             s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
1841             s << "%in_normalpos = OpVariable %_ptr_Input_v2float Input\n";
1842             s << "      %int_0 = OpConstant %int 0\n";
1843             s << "%_ptr_Output_int = OpTypePointer Output %int\n";
1844             s << "     %vIndex = OpVariable %_ptr_Output_int Output\n";
1845             s << "%_ptr_Input_int = OpTypePointer Input %int\n";
1846             s << "%gl_VertexIndex = OpVariable %_ptr_Input_int Input\n";
1847             s << "     %rIndex = OpVariable %_ptr_Output_int Output\n";
1848             s << "      %v4int = OpTypeVector %int 4\n";
1849             s << "%_ptr_Input_v4int = OpTypePointer Input %v4int\n";
1850             s << "      %index = OpVariable %_ptr_Input_v4int Input\n";
1851             s << "     %uint_0 = OpConstant %uint 0\n";
1852             s << "     %gIndex = OpVariable %_ptr_Output_int Output\n";
1853             s << "     %bIndex = OpVariable %_ptr_Output_int Output\n";
1854             s << "     %uint_2 = OpConstant %uint 2\n";
1855             s << "     %aIndex = OpVariable %_ptr_Output_int Output\n";
1856             s << "     %uint_3 = OpConstant %uint 3\n";
1857             s << "       %main = OpFunction %void None %3\n";
1858             s << "          %5 = OpLabel\n";
1859             s << "         %18 = OpAccessChain %_ptr_Output_float %_ %int_1\n";
1860             s << "               OpStore %18 %float_0_200000003\n";
1861             s << "         %23 = OpLoad %v4float %in_position\n";
1862             s << "               OpStore %position %23\n";
1863             s << "         %29 = OpLoad %v2float %in_normalpos\n";
1864             s << "               OpStore %normalpos %29\n";
1865             s << "         %31 = OpLoad %v4float %position\n";
1866             s << "         %32 = OpAccessChain %_ptr_Output_v4float %_ %int_0\n";
1867             s << "               OpStore %32 %31\n";
1868             s << "         %37 = OpLoad %int %gl_VertexIndex\n";
1869             s << "               OpStore %vIndex %37\n";
1870             s << "         %43 = OpAccessChain %_ptr_Input_int %index %uint_0\n";
1871             s << "         %44 = OpLoad %int %43\n";
1872             s << "               OpStore %rIndex %44\n";
1873             s << "         %46 = OpAccessChain %_ptr_Input_int %index %uint_1\n";
1874             s << "         %47 = OpLoad %int %46\n";
1875             s << "               OpStore %gIndex %47\n";
1876             s << "         %50 = OpAccessChain %_ptr_Input_int %index %uint_2\n";
1877             s << "         %51 = OpLoad %int %50\n";
1878             s << "               OpStore %bIndex %51\n";
1879             s << "         %54 = OpAccessChain %_ptr_Input_int %index %uint_3\n";
1880             s << "         %55 = OpLoad %int %54\n";
1881             s << "               OpStore %aIndex %55\n";
1882             s << "               OpReturn\n";
1883             s << "               OpFunctionEnd\n";
1884             break;
1885         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1886             s << "               OpCapability Shader\n";
1887             s << "               OpCapability ImageBuffer\n";
1888             if (allowVertexStoring)
1889             {
1890                 s << "               OpCapability ShaderNonUniform\n";
1891                 s << "               OpCapability RuntimeDescriptorArray\n";
1892                 s << "               OpCapability StorageTexelBufferArrayNonUniformIndexing\n";
1893                 s << "               OpExtension \"SPV_EXT_descriptor_indexing\"\n";
1894             }
1895             s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
1896             s << "               OpMemoryModel Logical GLSL450\n";
1897             s << "               OpEntryPoint Vertex %main \"main\" %_ %position %in_position %normalpos %in_normalpos "
1898                  "%vIndex %gl_VertexIndex %rIndex %index %gIndex %bIndex %aIndex %data\n";
1899             s << "               OpSource GLSL 450\n";
1900             s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
1901             s << "               OpName %main \"main\"\n";
1902             s << "               OpName %gl_PerVertex \"gl_PerVertex\"\n";
1903             s << "               OpMemberName %gl_PerVertex 0 \"gl_Position\"\n";
1904             s << "               OpMemberName %gl_PerVertex 1 \"gl_PointSize\"\n";
1905             s << "               OpMemberName %gl_PerVertex 2 \"gl_ClipDistance\"\n";
1906             s << "               OpMemberName %gl_PerVertex 3 \"gl_CullDistance\"\n";
1907             s << "               OpName %_ \"\"\n";
1908             s << "               OpName %position \"position\"\n";
1909             s << "               OpName %in_position \"in_position\"\n";
1910             s << "               OpName %normalpos \"normalpos\"\n";
1911             s << "               OpName %in_normalpos \"in_normalpos\"\n";
1912             s << "               OpName %vIndex \"vIndex\"\n";
1913             s << "               OpName %gl_VertexIndex \"gl_VertexIndex\"\n";
1914             s << "               OpName %rIndex \"rIndex\"\n";
1915             s << "               OpName %index \"index\"\n";
1916             s << "               OpName %gIndex \"gIndex\"\n";
1917             s << "               OpName %bIndex \"bIndex\"\n";
1918             s << "               OpName %aIndex \"aIndex\"\n";
1919             s << "               OpName %data \"data\"\n";
1920             s << "               OpMemberDecorate %gl_PerVertex 0 BuiltIn Position\n";
1921             s << "               OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize\n";
1922             s << "               OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance\n";
1923             s << "               OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance\n";
1924             s << "               OpDecorate %gl_PerVertex Block\n";
1925             s << "               OpDecorate %position Location 0\n";
1926             s << "               OpDecorate %in_position Location 0\n";
1927             s << "               OpDecorate %normalpos Location 1\n";
1928             s << "               OpDecorate %in_normalpos Location 1\n";
1929             s << "               OpDecorate %vIndex Location 2\n";
1930             s << "               OpDecorate %gl_VertexIndex BuiltIn VertexIndex\n";
1931             s << "               OpDecorate %rIndex Location 3\n";
1932             s << "               OpDecorate %index Location 2\n";
1933             s << "               OpDecorate %gIndex Location 4\n";
1934             s << "               OpDecorate %bIndex Location 5\n";
1935             s << "               OpDecorate %aIndex Location 6\n";
1936             s << "               OpDecorate %data DescriptorSet 0\n";
1937             s << "               OpDecorate %data Binding " << BINDING_TestObject << "\n";
1938             if (allowVertexStoring)
1939             {
1940                 // s << "               OpDecorate %66 NonUniform\n";
1941                 // s << "               OpDecorate %68 NonUniform\n";
1942                 s << "               OpDecorate %69 NonUniform\n";
1943                 // s << "               OpDecorate %71 NonUniform\n";
1944                 // s << "               OpDecorate %72 NonUniform\n";
1945                 s << "               OpDecorate %73 NonUniform\n";
1946             }
1947             s << "       %void = OpTypeVoid\n";
1948             s << "          %3 = OpTypeFunction %void\n";
1949             s << "      %float = OpTypeFloat 32\n";
1950             s << "    %v4float = OpTypeVector %float 4\n";
1951             s << "       %uint = OpTypeInt 32 0\n";
1952             s << "     %uint_1 = OpConstant %uint 1\n";
1953             s << "%_arr_float_uint_1 = OpTypeArray %float %uint_1\n";
1954             s << "%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1\n";
1955             s << "%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex\n";
1956             s << "          %_ = OpVariable %_ptr_Output_gl_PerVertex Output\n";
1957             s << "        %int = OpTypeInt 32 1\n";
1958             s << "      %int_1 = OpConstant %int 1\n";
1959             s << "%float_0_200000003 = OpConstant %float 0.200000003\n";
1960             s << "%_ptr_Output_float = OpTypePointer Output %float\n";
1961             s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
1962             s << "   %position = OpVariable %_ptr_Output_v4float Output\n";
1963             s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
1964             s << "%in_position = OpVariable %_ptr_Input_v4float Input\n";
1965             s << "    %v2float = OpTypeVector %float 2\n";
1966             s << "%_ptr_Output_v2float = OpTypePointer Output %v2float\n";
1967             s << "  %normalpos = OpVariable %_ptr_Output_v2float Output\n";
1968             s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
1969             s << "%in_normalpos = OpVariable %_ptr_Input_v2float Input\n";
1970             s << "      %int_0 = OpConstant %int 0\n";
1971             s << "%_ptr_Output_int = OpTypePointer Output %int\n";
1972             s << "     %vIndex = OpVariable %_ptr_Output_int Output\n";
1973             s << "%_ptr_Input_int = OpTypePointer Input %int\n";
1974             s << "%gl_VertexIndex = OpVariable %_ptr_Input_int Input\n";
1975             s << "     %rIndex = OpVariable %_ptr_Output_int Output\n";
1976             s << "      %v4int = OpTypeVector %int 4\n";
1977             s << "%_ptr_Input_v4int = OpTypePointer Input %v4int\n";
1978             s << "      %index = OpVariable %_ptr_Input_v4int Input\n";
1979             s << "     %uint_0 = OpConstant %uint 0\n";
1980             s << "     %gIndex = OpVariable %_ptr_Output_int Output\n";
1981             s << "     %bIndex = OpVariable %_ptr_Output_int Output\n";
1982             s << "     %uint_2 = OpConstant %uint 2\n";
1983             s << "     %aIndex = OpVariable %_ptr_Output_int Output\n";
1984             s << "     %uint_3 = OpConstant %uint 3\n";
1985             if (allowVertexStoring)
1986             {
1987                 s << "        %bool = OpTypeBool\n";
1988                 s << "          %61 = OpTypeImage %float Buffer 0 0 0 2 Rgba32f\n";
1989                 s << " %_runtimearr_61 = OpTypeRuntimeArray %61\n";
1990                 s << " %_ptr_UniformConstant__runtimearr_61 = OpTypePointer UniformConstant %_runtimearr_61\n";
1991                 s << "        %data = OpVariable %_ptr_UniformConstant__runtimearr_61 UniformConstant\n";
1992                 s << " %_ptr_UniformConstant_61 = OpTypePointer UniformConstant %61\n";
1993             }
1994             else
1995             {
1996                 s << "         %56 = OpTypeImage %float Buffer 0 0 0 2 Rgba32f\n";
1997                 s << "%_arr_56_uint_1 = OpTypeArray %56 %uint_1\n";
1998                 s << "%_ptr_UniformConstant__arr_56_uint_1 = OpTypePointer UniformConstant %_arr_56_uint_1\n";
1999                 s << "       %data = OpVariable %_ptr_UniformConstant__arr_56_uint_1 UniformConstant\n";
2000             }
2001             s << "       %main = OpFunction %void None %3\n";
2002             s << "          %5 = OpLabel\n";
2003             s << "         %18 = OpAccessChain %_ptr_Output_float %_ %int_1\n";
2004             s << "               OpStore %18 %float_0_200000003\n";
2005             s << "         %23 = OpLoad %v4float %in_position\n";
2006             s << "               OpStore %position %23\n";
2007             s << "         %29 = OpLoad %v2float %in_normalpos\n";
2008             s << "               OpStore %normalpos %29\n";
2009             s << "         %31 = OpLoad %v4float %position\n";
2010             s << "         %32 = OpAccessChain %_ptr_Output_v4float %_ %int_0\n";
2011             s << "               OpStore %32 %31\n";
2012             s << "         %37 = OpLoad %int %gl_VertexIndex\n";
2013             s << "               OpStore %vIndex %37\n";
2014             s << "         %43 = OpAccessChain %_ptr_Input_int %index %uint_0\n";
2015             s << "         %44 = OpLoad %int %43\n";
2016             s << "               OpStore %rIndex %44\n";
2017             s << "         %46 = OpAccessChain %_ptr_Input_int %index %uint_1\n";
2018             s << "         %47 = OpLoad %int %46\n";
2019             s << "               OpStore %gIndex %47\n";
2020             s << "         %50 = OpAccessChain %_ptr_Input_int %index %uint_2\n";
2021             s << "         %51 = OpLoad %int %50\n";
2022             s << "               OpStore %bIndex %51\n";
2023             s << "         %54 = OpAccessChain %_ptr_Input_int %index %uint_3\n";
2024             s << "         %55 = OpLoad %int %54\n";
2025             s << "               OpStore %aIndex %55\n";
2026             if (allowVertexStoring)
2027             {
2028                 s << "          %56 = OpLoad %int %gIndex\n";
2029                 s << "          %58 = OpINotEqual %bool %56 %int_0\n";
2030                 s << "                OpSelectionMerge %60 None\n";
2031                 s << "                OpBranchConditional %58 %59 %60\n";
2032                 s << "          %59 = OpLabel\n";
2033                 s << "          %65 = OpLoad %int %gIndex\n";
2034                 s << "          %66 = OpCopyObject %int %65\n";
2035                 s << "          %68 = OpAccessChain %_ptr_UniformConstant_61 %data %66\n";
2036                 s << "          %69 = OpLoad %61 %68\n";
2037                 s << "          %70 = OpLoad %int %rIndex\n";
2038                 s << "          %71 = OpCopyObject %int %70\n";
2039                 s << "          %72 = OpAccessChain %_ptr_UniformConstant_61 %data %71\n";
2040                 s << "          %73 = OpLoad %61 %72\n";
2041                 s << "          %74 = OpImageRead %v4float %73 %int_0\n";
2042                 s << "                OpImageWrite %69 %int_1 %74\n";
2043                 s << "                OpBranch %60\n";
2044                 s << "          %60 = OpLabel\n";
2045             }
2046             s << "               OpReturn\n";
2047             s << "               OpFunctionEnd\n";
2048             break;
2049         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2050             s << "               OpCapability Shader\n";
2051             if (allowVertexStoring)
2052             {
2053                 s << "               OpCapability ShaderNonUniform\n";
2054                 s << "               OpCapability RuntimeDescriptorArray\n";
2055                 s << "               OpCapability StorageBufferArrayNonUniformIndexing\n";
2056                 s << "               OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2057             }
2058             s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
2059             s << "               OpMemoryModel Logical GLSL450\n";
2060             s << "               OpEntryPoint Vertex %main \"main\" %_ %position %in_position %normalpos %in_normalpos "
2061                  "%vIndex %gl_VertexIndex %rIndex %index %gIndex %bIndex %aIndex %data\n";
2062             s << "               OpSource GLSL 450\n";
2063             s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2064             s << "               OpName %main \"main\"\n";
2065             s << "               OpName %gl_PerVertex \"gl_PerVertex\"\n";
2066             s << "               OpMemberName %gl_PerVertex 0 \"gl_Position\"\n";
2067             s << "               OpMemberName %gl_PerVertex 1 \"gl_PointSize\"\n";
2068             s << "               OpMemberName %gl_PerVertex 2 \"gl_ClipDistance\"\n";
2069             s << "               OpMemberName %gl_PerVertex 3 \"gl_CullDistance\"\n";
2070             s << "               OpName %_ \"\"\n";
2071             s << "               OpName %position \"position\"\n";
2072             s << "               OpName %in_position \"in_position\"\n";
2073             s << "               OpName %normalpos \"normalpos\"\n";
2074             s << "               OpName %in_normalpos \"in_normalpos\"\n";
2075             s << "               OpName %vIndex \"vIndex\"\n";
2076             s << "               OpName %gl_VertexIndex \"gl_VertexIndex\"\n";
2077             s << "               OpName %rIndex \"rIndex\"\n";
2078             s << "               OpName %index \"index\"\n";
2079             s << "               OpName %gIndex \"gIndex\"\n";
2080             s << "               OpName %bIndex \"bIndex\"\n";
2081             s << "               OpName %aIndex \"aIndex\"\n";
2082             s << "               OpName %Data \"Data\"\n";
2083             s << "               OpMemberName %Data 0 \"cnew\"\n";
2084             s << "               OpMemberName %Data 1 \"cold\"\n";
2085             s << "               OpName %data \"data\"\n";
2086             s << "               OpMemberDecorate %gl_PerVertex 0 BuiltIn Position\n";
2087             s << "               OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize\n";
2088             s << "               OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance\n";
2089             s << "               OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance\n";
2090             s << "               OpDecorate %gl_PerVertex Block\n";
2091             s << "               OpDecorate %position Location 0\n";
2092             s << "               OpDecorate %in_position Location 0\n";
2093             s << "               OpDecorate %normalpos Location 1\n";
2094             s << "               OpDecorate %in_normalpos Location 1\n";
2095             s << "               OpDecorate %vIndex Location 2\n";
2096             s << "               OpDecorate %gl_VertexIndex BuiltIn VertexIndex\n";
2097             s << "               OpDecorate %rIndex Location 3\n";
2098             s << "               OpDecorate %index Location 2\n";
2099             s << "               OpDecorate %gIndex Location 4\n";
2100             s << "               OpDecorate %bIndex Location 5\n";
2101             s << "               OpDecorate %aIndex Location 6\n";
2102             s << "               OpMemberDecorate %Data 0 Offset 0\n";
2103             s << "               OpMemberDecorate %Data 1 Offset 16\n";
2104             s << "               OpDecorate %Data Block\n";
2105             s << "               OpDecorate %data DescriptorSet 0\n";
2106             s << "               OpDecorate %data Binding " << BINDING_TestObject << "\n";
2107             if (allowVertexStoring)
2108             {
2109                 // s << "               OpDecorate %66 NonUniform\n";
2110                 // s << "               OpDecorate %68 NonUniform\n";
2111                 s << "               OpDecorate %70 NonUniform\n";
2112                 // s << "               OpDecorate %71 NonUniform\n";
2113                 s << "               OpDecorate %72 NonUniform\n";
2114             }
2115             s << "       %void = OpTypeVoid\n";
2116             s << "          %3 = OpTypeFunction %void\n";
2117             s << "      %float = OpTypeFloat 32\n";
2118             s << "    %v4float = OpTypeVector %float 4\n";
2119             s << "       %uint = OpTypeInt 32 0\n";
2120             s << "     %uint_1 = OpConstant %uint 1\n";
2121             s << "%_arr_float_uint_1 = OpTypeArray %float %uint_1\n";
2122             s << "%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1\n";
2123             s << "%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex\n";
2124             s << "          %_ = OpVariable %_ptr_Output_gl_PerVertex Output\n";
2125             s << "        %int = OpTypeInt 32 1\n";
2126             s << "      %int_1 = OpConstant %int 1\n";
2127             s << "%float_0_200000003 = OpConstant %float 0.200000003\n";
2128             s << "%_ptr_Output_float = OpTypePointer Output %float\n";
2129             s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
2130             s << "   %position = OpVariable %_ptr_Output_v4float Output\n";
2131             s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
2132             s << "%in_position = OpVariable %_ptr_Input_v4float Input\n";
2133             s << "    %v2float = OpTypeVector %float 2\n";
2134             s << "%_ptr_Output_v2float = OpTypePointer Output %v2float\n";
2135             s << "  %normalpos = OpVariable %_ptr_Output_v2float Output\n";
2136             s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
2137             s << "%in_normalpos = OpVariable %_ptr_Input_v2float Input\n";
2138             s << "      %int_0 = OpConstant %int 0\n";
2139             s << "%_ptr_Output_int = OpTypePointer Output %int\n";
2140             s << "     %vIndex = OpVariable %_ptr_Output_int Output\n";
2141             s << "%_ptr_Input_int = OpTypePointer Input %int\n";
2142             s << "%gl_VertexIndex = OpVariable %_ptr_Input_int Input\n";
2143             s << "     %rIndex = OpVariable %_ptr_Output_int Output\n";
2144             s << "      %v4int = OpTypeVector %int 4\n";
2145             s << "%_ptr_Input_v4int = OpTypePointer Input %v4int\n";
2146             s << "      %index = OpVariable %_ptr_Input_v4int Input\n";
2147             s << "     %uint_0 = OpConstant %uint 0\n";
2148             s << "     %gIndex = OpVariable %_ptr_Output_int Output\n";
2149             s << "     %bIndex = OpVariable %_ptr_Output_int Output\n";
2150             s << "     %uint_2 = OpConstant %uint 2\n";
2151             s << "     %aIndex = OpVariable %_ptr_Output_int Output\n";
2152             s << "     %uint_3 = OpConstant %uint 3\n";
2153             s << "       %Data = OpTypeStruct %v4float %v4float\n";
2154             if (allowVertexStoring)
2155             {
2156                 s << "       %bool = OpTypeBool\n";
2157                 s << "%_runtimearr_Data = OpTypeRuntimeArray %Data\n";
2158                 s << "%_ptr_StorageBuffer__runtimearr_Data = OpTypePointer StorageBuffer %_runtimearr_Data\n";
2159                 s << "       %data = OpVariable  %_ptr_StorageBuffer__runtimearr_Data StorageBuffer\n";
2160                 s << "%_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float\n";
2161             }
2162             else
2163             {
2164                 s << "%_arr_Data_uint_1 = OpTypeArray %Data %uint_1\n";
2165                 s << "%_ptr_StorageBuffer__arr_Data_uint_1 = OpTypePointer StorageBuffer %_arr_Data_uint_1\n";
2166                 s << "       %data = OpVariable %_ptr_StorageBuffer__arr_Data_uint_1 StorageBuffer\n";
2167             }
2168             s << "       %main = OpFunction %void None %3\n";
2169             s << "          %5 = OpLabel\n";
2170             s << "         %18 = OpAccessChain %_ptr_Output_float %_ %int_1\n";
2171             s << "               OpStore %18 %float_0_200000003\n";
2172             s << "         %23 = OpLoad %v4float %in_position\n";
2173             s << "               OpStore %position %23\n";
2174             s << "         %29 = OpLoad %v2float %in_normalpos\n";
2175             s << "               OpStore %normalpos %29\n";
2176             s << "         %31 = OpLoad %v4float %position\n";
2177             s << "         %32 = OpAccessChain %_ptr_Output_v4float %_ %int_0\n";
2178             s << "               OpStore %32 %31\n";
2179             s << "         %37 = OpLoad %int %gl_VertexIndex\n";
2180             s << "               OpStore %vIndex %37\n";
2181             s << "         %43 = OpAccessChain %_ptr_Input_int %index %uint_0\n";
2182             s << "         %44 = OpLoad %int %43\n";
2183             s << "               OpStore %rIndex %44\n";
2184             s << "         %46 = OpAccessChain %_ptr_Input_int %index %uint_1\n";
2185             s << "         %47 = OpLoad %int %46\n";
2186             s << "               OpStore %gIndex %47\n";
2187             s << "         %50 = OpAccessChain %_ptr_Input_int %index %uint_2\n";
2188             s << "         %51 = OpLoad %int %50\n";
2189             s << "               OpStore %bIndex %51\n";
2190             s << "         %54 = OpAccessChain %_ptr_Input_int %index %uint_3\n";
2191             s << "         %55 = OpLoad %int %54\n";
2192             s << "               OpStore %aIndex %55\n";
2193             if (allowVertexStoring)
2194             {
2195                 s << "          %56 = OpLoad %int %gIndex\n";
2196                 s << "          %58 = OpINotEqual %bool %56 %int_0\n";
2197                 s << "                OpSelectionMerge %60 None\n";
2198                 s << "                OpBranchConditional %58 %59 %60\n";
2199                 s << "          %59 = OpLabel\n";
2200                 s << "          %65 = OpLoad %int %gIndex\n";
2201                 s << "          %66 = OpCopyObject %int %65\n";
2202                 s << "          %67 = OpLoad %int %rIndex\n";
2203                 s << "          %68 = OpCopyObject %int %67\n";
2204                 s << "          %70 = OpAccessChain %_ptr_StorageBuffer_v4float %data %68 %int_1\n";
2205                 s << "          %71 = OpLoad %v4float %70\n";
2206                 s << "          %72 = OpAccessChain %_ptr_StorageBuffer_v4float %data %66 %int_0\n";
2207                 s << "                OpStore %72 %71\n";
2208                 s << "                OpBranch %60\n";
2209                 s << "          %60 = OpLabel\n";
2210             }
2211             s << "               OpReturn\n";
2212             s << "               OpFunctionEnd\n";
2213             break;
2214         default:
2215             TCU_THROW(InternalError, "Unexpected descriptor type");
2216         }
2217         break;
2218     case VK_SHADER_STAGE_FRAGMENT_BIT:
2219         switch (testCaseParams.descriptorType)
2220         {
2221         case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
2222             s << "               OpCapability Shader\n";
2223             if (testCaseParams.usesMipMaps)
2224             {
2225                 s << "               OpCapability ImageQuery\n";
2226             }
2227             s << "               OpCapability ShaderNonUniform\n";
2228             s << "               OpCapability RuntimeDescriptorArray\n";
2229             s << "               OpCapability SampledImageArrayNonUniformIndexing\n";
2230             s << "               OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2231             s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
2232             s << "               OpMemoryModel Logical GLSL450\n";
2233             s << "               OpEntryPoint Fragment %main \"main\" %FragColor %data %rIndex %position %normalpos "
2234                  "%vIndex %gIndex %bIndex %aIndex\n";
2235             s << "               OpExecutionMode %main OriginUpperLeft\n";
2236             s << "               OpSource GLSL 450\n";
2237             s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2238             s << "               OpSourceExtension \"GL_EXT_texture_buffer\"\n";
2239             s << "               OpName %main \"main\"\n";
2240             s << "               OpName %FragColor \"FragColor\"\n";
2241             s << "               OpName %data \"data\"\n";
2242             s << "               OpName %rIndex \"rIndex\"\n";
2243             s << "               OpName %position \"position\"\n";
2244             s << "               OpName %normalpos \"normalpos\"\n";
2245             s << "               OpName %vIndex \"vIndex\"\n";
2246             s << "               OpName %gIndex \"gIndex\"\n";
2247             s << "               OpName %bIndex \"bIndex\"\n";
2248             s << "               OpName %aIndex \"aIndex\"\n";
2249             s << "               OpDecorate %FragColor Location 0\n";
2250             s << "               OpDecorate %data DescriptorSet 0\n";
2251             s << "               OpDecorate %data Binding " << BINDING_TestObject << "\n";
2252             s << "               OpDecorate %rIndex Flat\n";
2253             s << "               OpDecorate %rIndex Location 3\n";
2254             // s << "               OpDecorate %19 NonUniform\n";
2255             // s << "               OpDecorate %21 NonUniform\n";
2256             s << "               OpDecorate %22 NonUniform\n";
2257             if (testCaseParams.usesMipMaps)
2258             {
2259                 // s << "               OpDecorate %27 NonUniform\n";
2260                 // s << "               OpDecorate %28 NonUniform\n";
2261                 // s << "               OpDecorate %29 NonUniform\n";
2262                 s << "               OpDecorate %30 NonUniform\n";
2263             }
2264             s << "               OpDecorate %position Flat\n";
2265             s << "               OpDecorate %position Location 0\n";
2266             s << "               OpDecorate %normalpos Flat\n";
2267             s << "               OpDecorate %normalpos Location 1\n";
2268             s << "               OpDecorate %vIndex Flat\n";
2269             s << "               OpDecorate %vIndex Location 2\n";
2270             s << "               OpDecorate %gIndex Flat\n";
2271             s << "               OpDecorate %gIndex Location 4\n";
2272             s << "               OpDecorate %bIndex Flat\n";
2273             s << "               OpDecorate %bIndex Location 5\n";
2274             s << "               OpDecorate %aIndex Flat\n";
2275             s << "               OpDecorate %aIndex Location 6\n";
2276             s << "       %void = OpTypeVoid\n";
2277             s << "          %3 = OpTypeFunction %void\n";
2278             s << "      %float = OpTypeFloat 32\n";
2279             s << "    %v4float = OpTypeVector %float 4\n";
2280             s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
2281             s << "  %FragColor = OpVariable %_ptr_Output_v4float Output\n";
2282             s << "         %10 = OpTypeImage %float 2D 0 0 0 1 Unknown\n";
2283             s << "         %11 = OpTypeSampledImage %10\n";
2284             s << "%_runtimearr_11 = OpTypeRuntimeArray %11\n";
2285             s << "%_ptr_UniformConstant__runtimearr_11 = OpTypePointer UniformConstant %_runtimearr_11\n";
2286             s << "       %data = OpVariable %_ptr_UniformConstant__runtimearr_11 UniformConstant\n";
2287             s << "        %int = OpTypeInt 32 1\n";
2288             s << "%_ptr_Input_int = OpTypePointer Input %int\n";
2289             s << "     %rIndex = OpVariable %_ptr_Input_int Input\n";
2290             s << "%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11\n";
2291             s << "    %v2float = OpTypeVector %float 2\n";
2292             s << "    %float_0 = OpConstant %float 0\n";
2293             s << "      %int_1 = OpConstant %int 1\n";
2294             s << "         %25 = OpConstantComposite %v2float %float_0 %float_0\n";
2295             s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
2296             s << "   %position = OpVariable %_ptr_Input_v4float Input\n";
2297             s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
2298             s << "  %normalpos = OpVariable %_ptr_Input_v2float Input\n";
2299             s << "     %vIndex = OpVariable %_ptr_Input_int Input\n";
2300             s << "     %gIndex = OpVariable %_ptr_Input_int Input\n";
2301             s << "     %bIndex = OpVariable %_ptr_Input_int Input\n";
2302             s << "     %aIndex = OpVariable %_ptr_Input_int Input\n";
2303             s << "       %main = OpFunction %void None %3\n";
2304             s << "          %5 = OpLabel\n";
2305             s << "         %18 = OpLoad %int %rIndex\n";
2306             s << "         %19 = OpCopyObject %int %18\n";
2307             s << "         %21 = OpAccessChain %_ptr_UniformConstant_11 %data %19\n";
2308             s << "         %22 = OpLoad %11 %21\n";
2309             if (testCaseParams.usesMipMaps)
2310             {
2311                 s << "          %26 = OpLoad %int %rIndex\n";
2312                 s << "          %27 = OpCopyObject %int %26\n";
2313                 s << "          %28 = OpAccessChain %_ptr_UniformConstant_11 %data %27\n";
2314                 s << "          %29 = OpLoad %11 %28\n";
2315                 s << "          %30 = OpImage %10 %29\n";
2316                 s << "          %31 = OpImageQueryLevels %int %30\n";
2317                 s << "          %33 = OpISub %int %31 %int_1\n";
2318                 s << "          %34 = OpConvertSToF %float %33\n";
2319                 s << "          %35 = OpImageSampleExplicitLod %v4float %22 %25 Lod %34\n";
2320                 s << "                OpStore %FragColor %35\n";
2321             }
2322             else
2323             {
2324                 s << "         %26 = OpImageSampleImplicitLod %v4float %22 %25\n";
2325                 s << "               OpStore %FragColor %26\n";
2326             }
2327             s << "               OpReturn\n";
2328             s << "               OpFunctionEnd\n";
2329             break;
2330         case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
2331             s << "               OpCapability Shader\n";
2332             s << "               OpCapability SampledBuffer\n";
2333             s << "               OpCapability ShaderNonUniform\n";
2334             s << "               OpCapability RuntimeDescriptorArray\n";
2335             s << "               OpCapability UniformTexelBufferArrayNonUniformIndexing\n";
2336             s << "               OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2337             s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
2338             s << "               OpMemoryModel Logical GLSL450\n";
2339             s << "               OpEntryPoint Fragment %main \"main\" %FragColor %data %rIndex %position %normalpos "
2340                  "%vIndex %gIndex %bIndex %aIndex\n";
2341             s << "               OpExecutionMode %main OriginUpperLeft\n";
2342             s << "               OpSource GLSL 450\n";
2343             s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2344             s << "               OpSourceExtension \"GL_EXT_texture_buffer\"\n";
2345             s << "               OpName %main \"main\"\n";
2346             s << "               OpName %FragColor \"FragColor\"\n";
2347             s << "               OpName %data \"data\"\n";
2348             s << "               OpName %rIndex \"rIndex\"\n";
2349             s << "               OpName %position \"position\"\n";
2350             s << "               OpName %normalpos \"normalpos\"\n";
2351             s << "               OpName %vIndex \"vIndex\"\n";
2352             s << "               OpName %gIndex \"gIndex\"\n";
2353             s << "               OpName %bIndex \"bIndex\"\n";
2354             s << "               OpName %aIndex \"aIndex\"\n";
2355             s << "               OpDecorate %FragColor Location 0\n";
2356             s << "               OpDecorate %data DescriptorSet 0\n";
2357             s << "               OpDecorate %data Binding " << BINDING_TestObject << "\n";
2358             s << "               OpDecorate %rIndex Flat\n";
2359             s << "               OpDecorate %rIndex Location 3\n";
2360             // s << "               OpDecorate %19 NonUniform\n";
2361             // s << "               OpDecorate %21 NonUniform\n";
2362             // s << "               OpDecorate %22 NonUniform\n";
2363             s << "               OpDecorate %24 NonUniform\n";
2364             s << "               OpDecorate %position Flat\n";
2365             s << "               OpDecorate %position Location 0\n";
2366             s << "               OpDecorate %normalpos Flat\n";
2367             s << "               OpDecorate %normalpos Location 1\n";
2368             s << "               OpDecorate %vIndex Flat\n";
2369             s << "               OpDecorate %vIndex Location 2\n";
2370             s << "               OpDecorate %gIndex Flat\n";
2371             s << "               OpDecorate %gIndex Location 4\n";
2372             s << "               OpDecorate %bIndex Flat\n";
2373             s << "               OpDecorate %bIndex Location 5\n";
2374             s << "               OpDecorate %aIndex Flat\n";
2375             s << "               OpDecorate %aIndex Location 6\n";
2376             s << "       %void = OpTypeVoid\n";
2377             s << "          %3 = OpTypeFunction %void\n";
2378             s << "      %float = OpTypeFloat 32\n";
2379             s << "    %v4float = OpTypeVector %float 4\n";
2380             s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
2381             s << "  %FragColor = OpVariable %_ptr_Output_v4float Output\n";
2382             s << "         %10 = OpTypeImage %float Buffer 0 0 0 1 Unknown\n";
2383             s << "         %11 = OpTypeSampledImage %10\n";
2384             s << "%_runtimearr_11 = OpTypeRuntimeArray %11\n";
2385             s << "%_ptr_UniformConstant__runtimearr_11 = OpTypePointer UniformConstant %_runtimearr_11\n";
2386             s << "       %data = OpVariable %_ptr_UniformConstant__runtimearr_11 UniformConstant\n";
2387             s << "        %int = OpTypeInt 32 1\n";
2388             s << "%_ptr_Input_int = OpTypePointer Input %int\n";
2389             s << "     %rIndex = OpVariable %_ptr_Input_int Input\n";
2390             s << "%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11\n";
2391             s << "      %int_0 = OpConstant %int 0\n";
2392             s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
2393             s << "   %position = OpVariable %_ptr_Input_v4float Input\n";
2394             s << "    %v2float = OpTypeVector %float 2\n";
2395             s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
2396             s << "  %normalpos = OpVariable %_ptr_Input_v2float Input\n";
2397             s << "     %vIndex = OpVariable %_ptr_Input_int Input\n";
2398             s << "     %gIndex = OpVariable %_ptr_Input_int Input\n";
2399             s << "     %bIndex = OpVariable %_ptr_Input_int Input\n";
2400             s << "     %aIndex = OpVariable %_ptr_Input_int Input\n";
2401             s << "       %main = OpFunction %void None %3\n";
2402             s << "          %5 = OpLabel\n";
2403             s << "         %18 = OpLoad %int %rIndex\n";
2404             s << "         %19 = OpCopyObject %int %18\n";
2405             s << "         %21 = OpAccessChain %_ptr_UniformConstant_11 %data %19\n";
2406             s << "         %22 = OpLoad %11 %21\n";
2407             s << "         %24 = OpImage %10 %22\n";
2408             s << "         %25 = OpImageFetch %v4float %24 %int_0\n";
2409             s << "               OpStore %FragColor %25\n";
2410             s << "               OpReturn\n";
2411             s << "               OpFunctionEnd\n";
2412             break;
2413         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
2414             s << "               OpCapability Shader\n";
2415             s << "               OpCapability ImageBuffer\n";
2416             s << "               OpCapability ShaderNonUniform\n";
2417             s << "               OpCapability RuntimeDescriptorArray\n";
2418             s << "               OpCapability StorageTexelBufferArrayNonUniformIndexing\n";
2419             s << "               OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2420             s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
2421             s << "               OpMemoryModel Logical GLSL450\n";
2422             s << "               OpEntryPoint Fragment %main \"main\" %FragColor %data %rIndex %position %normalpos "
2423                  "%vIndex %gIndex %bIndex %aIndex\n";
2424             s << "               OpExecutionMode %main OriginUpperLeft\n";
2425             s << "               OpSource GLSL 450\n";
2426             s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2427             s << "               OpName %main \"main\"\n";
2428             s << "               OpName %FragColor \"FragColor\"\n";
2429             s << "               OpName %data \"data\"\n";
2430             s << "               OpName %rIndex \"rIndex\"\n";
2431             s << "               OpName %position \"position\"\n";
2432             s << "               OpName %normalpos \"normalpos\"\n";
2433             s << "               OpName %vIndex \"vIndex\"\n";
2434             s << "               OpName %gIndex \"gIndex\"\n";
2435             s << "               OpName %bIndex \"bIndex\"\n";
2436             s << "               OpName %aIndex \"aIndex\"\n";
2437             s << "               OpDecorate %FragColor Location 0\n";
2438             s << "               OpDecorate %data DescriptorSet 0\n";
2439             s << "               OpDecorate %data Binding " << BINDING_TestObject << "\n";
2440             s << "               OpDecorate %rIndex Flat\n";
2441             s << "               OpDecorate %rIndex Location 3\n";
2442             // s << "               OpDecorate %18 NonUniform\n";
2443             // s << "               OpDecorate %20 NonUniform\n";
2444             s << "               OpDecorate %21 NonUniform\n";
2445             s << "               OpDecorate %position Flat\n";
2446             s << "               OpDecorate %position Location 0\n";
2447             s << "               OpDecorate %normalpos Flat\n";
2448             s << "               OpDecorate %normalpos Location 1\n";
2449             s << "               OpDecorate %vIndex Flat\n";
2450             s << "               OpDecorate %vIndex Location 2\n";
2451             s << "               OpDecorate %gIndex Flat\n";
2452             s << "               OpDecorate %gIndex Location 4\n";
2453             s << "               OpDecorate %bIndex Flat\n";
2454             s << "               OpDecorate %bIndex Location 5\n";
2455             s << "               OpDecorate %aIndex Flat\n";
2456             s << "               OpDecorate %aIndex Location 6\n";
2457             s << "       %void = OpTypeVoid\n";
2458             s << "          %3 = OpTypeFunction %void\n";
2459             s << "      %float = OpTypeFloat 32\n";
2460             s << "    %v4float = OpTypeVector %float 4\n";
2461             s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
2462             s << "  %FragColor = OpVariable %_ptr_Output_v4float Output\n";
2463             s << "         %10 = OpTypeImage %float Buffer 0 0 0 2 Rgba32f\n";
2464             s << "%_runtimearr_10 = OpTypeRuntimeArray %10\n";
2465             s << "%_ptr_UniformConstant__runtimearr_10 = OpTypePointer UniformConstant %_runtimearr_10\n";
2466             s << "       %data = OpVariable %_ptr_UniformConstant__runtimearr_10 UniformConstant\n";
2467             s << "        %int = OpTypeInt 32 1\n";
2468             s << "%_ptr_Input_int = OpTypePointer Input %int\n";
2469             s << "     %rIndex = OpVariable %_ptr_Input_int Input\n";
2470             s << "%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10\n";
2471             s << "      %int_0 = OpConstant %int 0\n";
2472             s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
2473             s << "   %position = OpVariable %_ptr_Input_v4float Input\n";
2474             s << "    %v2float = OpTypeVector %float 2\n";
2475             s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
2476             s << "  %normalpos = OpVariable %_ptr_Input_v2float Input\n";
2477             s << "     %vIndex = OpVariable %_ptr_Input_int Input\n";
2478             s << "     %gIndex = OpVariable %_ptr_Input_int Input\n";
2479             s << "     %bIndex = OpVariable %_ptr_Input_int Input\n";
2480             s << "     %aIndex = OpVariable %_ptr_Input_int Input\n";
2481             s << "       %main = OpFunction %void None %3\n";
2482             s << "          %5 = OpLabel\n";
2483             s << "         %17 = OpLoad %int %rIndex\n";
2484             s << "         %18 = OpCopyObject %int %17\n";
2485             s << "         %20 = OpAccessChain %_ptr_UniformConstant_10 %data %18\n";
2486             s << "         %21 = OpLoad %10 %20\n";
2487             s << "         %23 = OpImageRead %v4float %21 %int_0\n";
2488             s << "               OpStore %FragColor %23\n";
2489             s << "               OpReturn\n";
2490             s << "               OpFunctionEnd\n";
2491             break;
2492         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2493             s << "               OpCapability Shader\n";
2494             s << "               OpCapability ShaderNonUniform\n";
2495             s << "               OpCapability RuntimeDescriptorArray\n";
2496             s << "               OpCapability StorageBufferArrayNonUniformIndexing\n";
2497             s << "               OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2498             s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
2499             s << "               OpMemoryModel Logical GLSL450\n";
2500             s << "               OpEntryPoint Fragment %main \"main\" %FragColor %data %rIndex %position %normalpos "
2501                  "%vIndex %gIndex %bIndex %aIndex\n";
2502             s << "               OpExecutionMode %main OriginUpperLeft\n";
2503             s << "               OpSource GLSL 450\n";
2504             s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2505             s << "               OpName %main \"main\"\n";
2506             s << "               OpName %FragColor \"FragColor\"\n";
2507             s << "               OpName %Data \"Data\"\n";
2508             s << "               OpMemberName %Data 0 \"cnew\"\n";
2509             s << "               OpMemberName %Data 1 \"cold\"\n";
2510             s << "               OpName %data \"data\"\n";
2511             s << "               OpName %rIndex \"rIndex\"\n";
2512             s << "               OpName %position \"position\"\n";
2513             s << "               OpName %normalpos \"normalpos\"\n";
2514             s << "               OpName %vIndex \"vIndex\"\n";
2515             s << "               OpName %gIndex \"gIndex\"\n";
2516             s << "               OpName %bIndex \"bIndex\"\n";
2517             s << "               OpName %aIndex \"aIndex\"\n";
2518             s << "               OpDecorate %FragColor Location 0\n";
2519             s << "               OpMemberDecorate %Data 0 Offset 0\n";
2520             s << "               OpMemberDecorate %Data 1 Offset 16\n";
2521             s << "               OpDecorate %Data Block\n";
2522             s << "               OpDecorate %data DescriptorSet 0\n";
2523             s << "               OpDecorate %data Binding " << BINDING_TestObject << "\n";
2524             s << "               OpDecorate %rIndex Flat\n";
2525             s << "               OpDecorate %rIndex Location 3\n";
2526             // s << "               OpDecorate %18 NonUniform\n";
2527             s << "               OpDecorate %21 NonUniform\n";
2528             // s << "               OpDecorate %22 NonUniform\n";
2529             s << "               OpDecorate %position Flat\n";
2530             s << "               OpDecorate %position Location 0\n";
2531             s << "               OpDecorate %normalpos Flat               OpDecorate %normalpos Location 1\n";
2532             s << "               OpDecorate %vIndex Flat\n";
2533             s << "               OpDecorate %vIndex Location 2\n";
2534             s << "               OpDecorate %gIndex Flat\n";
2535             s << "               OpDecorate %gIndex Location 4\n";
2536             s << "               OpDecorate %bIndex Flat\n";
2537             s << "               OpDecorate %bIndex Location 5\n";
2538             s << "               OpDecorate %aIndex Flat\n";
2539             s << "               OpDecorate %aIndex Location 6\n";
2540             s << "       %void = OpTypeVoid\n";
2541             s << "          %3 = OpTypeFunction %void\n";
2542             s << "      %float = OpTypeFloat 32\n";
2543             s << "    %v4float = OpTypeVector %float 4\n";
2544             s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
2545             s << "  %FragColor = OpVariable %_ptr_Output_v4float Output\n";
2546             s << "       %Data = OpTypeStruct %v4float %v4float\n";
2547             s << "%_runtimearr_Data = OpTypeRuntimeArray %Data\n";
2548             s << "%_ptr_StorageBuffer__runtimearr_Data = OpTypePointer StorageBuffer %_runtimearr_Data\n";
2549             s << "       %data = OpVariable %_ptr_StorageBuffer__runtimearr_Data StorageBuffer\n";
2550             s << "        %int = OpTypeInt 32 1\n";
2551             s << "%_ptr_Input_int = OpTypePointer Input %int\n";
2552             s << "     %rIndex = OpVariable %_ptr_Input_int Input\n";
2553             s << "      %int_1 = OpConstant %int 1\n";
2554             s << "%_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float\n";
2555             s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
2556             s << "   %position = OpVariable %_ptr_Input_v4float Input\n";
2557             s << "    %v2float = OpTypeVector %float 2\n";
2558             s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
2559             s << "  %normalpos = OpVariable %_ptr_Input_v2float Input\n";
2560             s << "     %vIndex = OpVariable %_ptr_Input_int Input\n";
2561             s << "     %gIndex = OpVariable %_ptr_Input_int Input\n";
2562             s << "     %bIndex = OpVariable %_ptr_Input_int Input\n";
2563             s << "     %aIndex = OpVariable %_ptr_Input_int Input\n";
2564             s << "       %main = OpFunction %void None %3\n";
2565             s << "          %5 = OpLabel\n";
2566             s << "         %17 = OpLoad %int %rIndex\n";
2567             s << "         %18 = OpCopyObject %int %17\n";
2568             s << "         %21 = OpAccessChain %_ptr_StorageBuffer_v4float %data %18 %int_1\n";
2569             s << "         %22 = OpLoad %v4float %21\n";
2570             s << "               OpStore %FragColor %22\n";
2571             s << "               OpReturn\n";
2572             s << "               OpFunctionEnd\n";
2573             break;
2574         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
2575             s << "               OpCapability Shader\n";
2576             s << "               OpCapability ShaderNonUniform\n";
2577             s << "               OpCapability RuntimeDescriptorArray\n";
2578             s << "               OpCapability UniformBufferArrayNonUniformIndexing\n";
2579             s << "               OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2580             s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
2581             s << "               OpMemoryModel Logical GLSL450\n";
2582             s << "               OpEntryPoint Fragment %main \"main\" %FragColor %data %rIndex %position %normalpos "
2583                  "%vIndex %gIndex %bIndex %aIndex\n";
2584             s << "               OpExecutionMode %main OriginUpperLeft\n";
2585             s << "               OpSource GLSL 450\n";
2586             s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2587             s << "               OpName %main \"main\"\n";
2588             s << "               OpName %FragColor \"FragColor\"\n";
2589             s << "               OpName %Data \"Data\"\n";
2590             s << "               OpMemberName %Data 0 \"c\"\n";
2591             s << "               OpName %data \"data\"\n";
2592             s << "               OpName %rIndex \"rIndex\"\n";
2593             s << "               OpName %position \"position\"\n";
2594             s << "               OpName %normalpos \"normalpos\"\n";
2595             s << "               OpName %vIndex \"vIndex\"\n";
2596             s << "               OpName %gIndex \"gIndex\"\n";
2597             s << "               OpName %bIndex \"bIndex\"\n";
2598             s << "               OpName %aIndex \"aIndex\"\n";
2599             s << "               OpDecorate %FragColor Location 0\n";
2600             s << "               OpMemberDecorate %Data 0 Offset 0\n";
2601             s << "               OpDecorate %Data Block\n";
2602             s << "               OpDecorate %data DescriptorSet 0\n";
2603             s << "               OpDecorate %data Binding " << BINDING_TestObject << "\n";
2604             s << "               OpDecorate %rIndex Flat\n";
2605             s << "               OpDecorate %rIndex Location 3\n";
2606             // s << "               OpDecorate %18 NonUniform\n";
2607             s << "               OpDecorate %21 NonUniform\n";
2608             // s << "               OpDecorate %22 NonUniform\n";
2609             s << "               OpDecorate %position Flat\n";
2610             s << "               OpDecorate %position Location 0\n";
2611             s << "               OpDecorate %normalpos Flat\n";
2612             s << "               OpDecorate %normalpos Location 1\n";
2613             s << "               OpDecorate %vIndex Flat\n";
2614             s << "               OpDecorate %vIndex Location 2\n";
2615             s << "               OpDecorate %gIndex Flat\n";
2616             s << "               OpDecorate %gIndex Location 4\n";
2617             s << "               OpDecorate %bIndex Flat\n";
2618             s << "               OpDecorate %bIndex Location 5\n";
2619             s << "               OpDecorate %aIndex Flat\n";
2620             s << "               OpDecorate %aIndex Location 6\n";
2621             s << "       %void = OpTypeVoid\n";
2622             s << "          %3 = OpTypeFunction %void\n";
2623             s << "      %float = OpTypeFloat 32\n";
2624             s << "    %v4float = OpTypeVector %float 4\n";
2625             s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
2626             s << "  %FragColor = OpVariable %_ptr_Output_v4float Output\n";
2627             s << "       %Data = OpTypeStruct %v4float\n";
2628             s << "%_runtimearr_Data = OpTypeRuntimeArray %Data\n";
2629             s << "%_ptr_Uniform__runtimearr_Data = OpTypePointer Uniform %_runtimearr_Data\n";
2630             s << "       %data = OpVariable %_ptr_Uniform__runtimearr_Data Uniform\n";
2631             s << "        %int = OpTypeInt 32 1\n";
2632             s << "%_ptr_Input_int = OpTypePointer Input %int\n";
2633             s << "     %rIndex = OpVariable %_ptr_Input_int Input\n";
2634             s << "      %int_0 = OpConstant %int 0\n";
2635             s << "%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float\n";
2636             s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
2637             s << "   %position = OpVariable %_ptr_Input_v4float Input\n";
2638             s << "    %v2float = OpTypeVector %float 2\n";
2639             s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
2640             s << "  %normalpos = OpVariable %_ptr_Input_v2float Input\n";
2641             s << "     %vIndex = OpVariable %_ptr_Input_int Input\n";
2642             s << "     %gIndex = OpVariable %_ptr_Input_int Input\n";
2643             s << "     %bIndex = OpVariable %_ptr_Input_int Input\n";
2644             s << "     %aIndex = OpVariable %_ptr_Input_int Input\n";
2645             s << "       %main = OpFunction %void None %3\n";
2646             s << "          %5 = OpLabel\n";
2647             s << "         %17 = OpLoad %int %rIndex\n";
2648             s << "         %18 = OpCopyObject %int %17\n";
2649             s << "         %21 = OpAccessChain %_ptr_Uniform_v4float %data %18 %int_0\n";
2650             s << "         %22 = OpLoad %v4float %21\n";
2651             s << "               OpStore %FragColor %22\n";
2652             s << "               OpReturn\n";
2653             s << "               OpFunctionEnd\n";
2654             break;
2655         default:
2656             TCU_THROW(InternalError, "Unexpected descriptor type");
2657         }
2658         break;
2659     case VK_SHADER_STAGE_COMPUTE_BIT:
2660         switch (testCaseParams.descriptorType)
2661         {
2662         case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
2663             s << "               OpCapability Shader\n";
2664             s << "               OpCapability ShaderNonUniform\n";
2665             s << "               OpCapability RuntimeDescriptorArray\n";
2666             s << "               OpCapability StorageImageArrayNonUniformIndexing\n";
2667             s << "               OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2668             s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
2669             s << "               OpMemoryModel Logical GLSL450\n";
2670             s << "               OpEntryPoint GLCompute %main \"main\" %idxs %gl_WorkGroupID %data\n";
2671             s << "               OpExecutionMode %main LocalSize 1 1 1\n";
2672             s << "               OpSource GLSL 450\n";
2673             s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2674             s << "               OpName %main \"main\"\n";
2675             s << "               OpName %c \"c\"\n";
2676             s << "               OpName %idxs \"idxs\"\n";
2677             s << "               OpName %gl_WorkGroupID \"gl_WorkGroupID\"\n";
2678             s << "               OpName %data \"data\"\n";
2679             s << "               OpDecorate %idxs DescriptorSet 0\n";
2680             s << "               OpDecorate %idxs Binding " << BINDING_Additional << "\n";
2681             s << "               OpDecorate %gl_WorkGroupID BuiltIn WorkgroupId\n";
2682             s << "               OpDecorate %data DescriptorSet 0\n";
2683             s << "               OpDecorate %data Binding " << BINDING_TestObject << "\n";
2684             // s << "               OpDecorate %36 NonUniform\n";
2685             // s << "               OpDecorate %37 NonUniform\n";
2686             s << "               OpDecorate %41 NonUniform\n";
2687             s << "               OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize\n";
2688             s << "       %void = OpTypeVoid\n";
2689             s << "          %3 = OpTypeFunction %void\n";
2690             s << "       %uint = OpTypeInt 32 0\n";
2691             s << "     %v4uint = OpTypeVector %uint 4\n";
2692             s << "%_ptr_Function_v4uint = OpTypePointer Function %v4uint\n";
2693             s << "         %10 = OpTypeImage %uint 2D 0 0 0 2 R32ui\n";
2694             s << "%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10\n";
2695             s << "       %idxs = OpVariable %_ptr_UniformConstant_10 UniformConstant\n";
2696             s << "     %v3uint = OpTypeVector %uint 3\n";
2697             s << "%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n";
2698             s << "%gl_WorkGroupID = OpVariable %_ptr_Input_v3uint Input\n";
2699             s << "     %uint_0 = OpConstant %uint 0\n";
2700             s << "%_ptr_Input_uint = OpTypePointer Input %uint\n";
2701             s << "        %int = OpTypeInt 32 1\n";
2702             s << "     %uint_1 = OpConstant %uint 1\n";
2703             s << "      %v2int = OpTypeVector %int 2\n";
2704             s << "%_runtimearr_10 = OpTypeRuntimeArray %10\n";
2705             s << "%_ptr_UniformConstant__runtimearr_10 = OpTypePointer UniformConstant %_runtimearr_10\n";
2706             s << "       %data = OpVariable %_ptr_UniformConstant__runtimearr_10 UniformConstant\n";
2707             s << "%_ptr_Function_uint = OpTypePointer Function %uint\n";
2708             s << "      %int_0 = OpConstant %int 0\n";
2709             s << "         %39 = OpConstantComposite %v2int %int_0 %int_0\n";
2710             s << "%_ptr_Image_uint = OpTypePointer Image %uint\n";
2711             s << "%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1\n";
2712             s << "       %main = OpFunction %void None %3\n";
2713             s << "          %5 = OpLabel\n";
2714             s << "          %c = OpVariable %_ptr_Function_v4uint Function\n";
2715             s << "         %13 = OpLoad %10 %idxs\n";
2716             s << "         %19 = OpAccessChain %_ptr_Input_uint %gl_WorkGroupID %uint_0\n";
2717             s << "         %20 = OpLoad %uint %19\n";
2718             s << "         %22 = OpBitcast %int %20\n";
2719             s << "         %24 = OpAccessChain %_ptr_Input_uint %gl_WorkGroupID %uint_1\n";
2720             s << "         %25 = OpLoad %uint %24\n";
2721             s << "         %26 = OpBitcast %int %25\n";
2722             s << "         %28 = OpCompositeConstruct %v2int %22 %26\n";
2723             s << "         %29 = OpImageRead %v4uint %13 %28 ZeroExtend\n";
2724             s << "               OpStore %c %29\n";
2725             s << "         %34 = OpAccessChain %_ptr_Function_uint %c %uint_0\n";
2726             s << "         %35 = OpLoad %uint %34\n";
2727             s << "         %36 = OpCopyObject %uint %35\n";
2728             s << "         %37 = OpAccessChain %_ptr_UniformConstant_10 %data %36\n";
2729             s << "         %41 = OpImageTexelPointer %_ptr_Image_uint %37 %39 %uint_0\n";
2730             s << "         %42 = OpAtomicIAdd %uint %41 %uint_1 %uint_0 %uint_1\n";
2731             s << "               OpReturn\n";
2732             s << "               OpFunctionEnd\n";
2733             break;
2734         default:
2735             TCU_THROW(InternalError, "Unexpected descriptor type");
2736         }
2737         break;
2738     default:
2739         TCU_THROW(InternalError, "Unexpected stage");
2740     }
2741 
2742     return s.str();
2743 }
2744 
getShaderSource(VkShaderStageFlagBits shaderType,const TestCaseParams & testCaseParams,bool allowVertexStoring)2745 std::string CommonDescriptorInstance::getShaderSource(VkShaderStageFlagBits shaderType,
2746                                                       const TestCaseParams &testCaseParams, bool allowVertexStoring)
2747 {
2748     std::stringstream s;
2749 
2750     s << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << '\n';
2751     s << "#extension GL_EXT_nonuniform_qualifier : require    \n";
2752 
2753     if (testCaseParams.calculateInLoop)
2754     {
2755         s << "layout(push_constant)     uniform Block { int lowerBound, upperBound; } pc;\n";
2756         s << substBinding(BINDING_DescriptorEnumerator,
2757                           "layout(set=1,binding=${?}) uniform isamplerBuffer iter;    \n");
2758     }
2759 
2760     std::string declType;
2761     switch (testCaseParams.descriptorType)
2762     {
2763     case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2764     case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
2765         declType = "buffer Data { vec4 cnew, cold; }";
2766         break;
2767     case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
2768     case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
2769         declType = "uniform Data { vec4 c; }";
2770         break;
2771     case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
2772         declType = "uniform imageBuffer";
2773         break;
2774     case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
2775         declType = "uniform samplerBuffer";
2776         break;
2777     case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
2778         declType = "uniform subpassInput";
2779         break;
2780     case VK_DESCRIPTOR_TYPE_SAMPLER:
2781         declType = "uniform sampler";
2782         break;
2783     case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
2784         declType = "uniform texture2D";
2785         break;
2786     case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
2787         declType = "uniform sampler2D";
2788         break;
2789     case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
2790         declType = "uniform uimage2D";
2791         break;
2792     default:
2793         TCU_THROW(InternalError, "Not implemented descriptor type");
2794     }
2795 
2796     std::string extraLayout = "";
2797     switch (testCaseParams.descriptorType)
2798     {
2799     // Note trailing commas to fit in with layout declaration, below.
2800     case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
2801         extraLayout = "rgba32f,";
2802         break;
2803     case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
2804         extraLayout = "input_attachment_index=1,";
2805         break;
2806     case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
2807         extraLayout = "r32ui,";
2808         break;
2809     default:
2810         break;
2811     }
2812 
2813     // Input attachments may only be declared in fragment shaders. The tests should only be constructed to use fragment
2814     // shaders, but the matching vertex shader will still pass here and must not pick up the invalid declaration.
2815     if (testCaseParams.descriptorType != VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT ||
2816         shaderType == VK_SHADER_STAGE_FRAGMENT_BIT)
2817         s << "layout(" << extraLayout << "set=0, binding = " << BINDING_TestObject << ") " << declType << " data[];\n";
2818 
2819     // Now make any additional declarations needed for specific descriptor types
2820     switch (testCaseParams.descriptorType)
2821     {
2822     case VK_DESCRIPTOR_TYPE_SAMPLER:
2823         s << "layout(set=0,binding=" << BINDING_Additional << ") uniform texture2D tex;\n";
2824         break;
2825     case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
2826         s << "layout(set=0,binding=" << BINDING_Additional << ") uniform sampler samp;\n";
2827         break;
2828     case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
2829         s << "layout(r32ui,set=0,binding=" << BINDING_Additional << ") uniform uimage2D idxs;\n";
2830         break;
2831     default:
2832         break;
2833     }
2834 
2835     switch (shaderType)
2836     {
2837     case VK_SHADER_STAGE_VERTEX_BIT:
2838         s << getVertexShaderProlog();
2839         break;
2840     case VK_SHADER_STAGE_FRAGMENT_BIT:
2841         s << getFragmentShaderProlog();
2842         break;
2843     case VK_SHADER_STAGE_COMPUTE_BIT:
2844         s << getComputeShaderProlog();
2845         break;
2846     default:
2847         TCU_THROW(InternalError, "Not implemented shader stage");
2848     }
2849 
2850     switch (shaderType)
2851     {
2852     case VK_SHADER_STAGE_VERTEX_BIT:
2853     {
2854         switch (testCaseParams.descriptorType)
2855         {
2856         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2857         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
2858             if (allowVertexStoring)
2859                 s << "  if (gIndex != 0) data[nonuniformEXT(gIndex)].cnew = data[nonuniformEXT(rIndex)].cold;    \n";
2860             break;
2861         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
2862             if (allowVertexStoring)
2863                 s << "  if (gIndex != 0) imageStore(data[nonuniformEXT(gIndex)], 1, "
2864                      "imageLoad(data[nonuniformEXT(rIndex)], 0));    \n";
2865             break;
2866         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
2867         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
2868         case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
2869         case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
2870         case VK_DESCRIPTOR_TYPE_SAMPLER:
2871         case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
2872         case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
2873             break;
2874 
2875         default:
2876             TCU_THROW(InternalError, "Not implemented descriptor type");
2877         }
2878     }
2879     break;
2880 
2881     case VK_SHADER_STAGE_FRAGMENT_BIT:
2882     {
2883         if (testCaseParams.calculateInLoop)
2884             s << getFragmentLoopSource(
2885                 getColorAccess(testCaseParams.descriptorType, "rIndex", testCaseParams.usesMipMaps),
2886                 getColorAccess(testCaseParams.descriptorType, "loopIdx", testCaseParams.usesMipMaps));
2887         else
2888             s << getFragmentReturnSource(
2889                 getColorAccess(testCaseParams.descriptorType, "rIndex", testCaseParams.usesMipMaps));
2890         break;
2891     }
2892     break;
2893 
2894     case VK_SHADER_STAGE_COMPUTE_BIT: // VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
2895         if (testCaseParams.calculateInLoop)
2896             s << "  const int totalAdds = pc.upperBound - pc.lowerBound;\n"
2897               << "  const int totalInvs = int(gl_WorkGroupSize.x);\n"
2898               << "  // Round number up so we never fall short in the number of additions\n"
2899               << "  const int addsPerInv = (totalAdds + totalInvs - 1) / totalInvs;\n"
2900               << "  const int baseAdd = int(gl_LocalInvocationID.x) * addsPerInv;\n"
2901               << "  for (int i = 0; i < addsPerInv; ++i) {\n"
2902               << "    const int addIdx = i + baseAdd + pc.lowerBound;\n"
2903               << "    if (addIdx < pc.upperBound) {\n"
2904               << "      imageAtomicAdd(data[nonuniformEXT(texelFetch(iter, addIdx).x)], ivec2(0, 0), 1);\n"
2905               << "    }\n"
2906               << "  }\n";
2907         else
2908         {
2909             s << "  const int xCoord = int(gl_WorkGroupID.x * gl_WorkGroupSize.x + gl_LocalInvocationID.x);\n"
2910               << "  const int yCoord = int(gl_WorkGroupID.y);\n"
2911               << "  uvec4 c = imageLoad(idxs, ivec2(xCoord, yCoord));\n"
2912               << "  imageAtomicAdd( data[nonuniformEXT(c.r)], ivec2(0, 0), 1);\n";
2913         }
2914         break;
2915 
2916     default:
2917         TCU_THROW(InternalError, "Not implemented shader stage");
2918     }
2919 
2920     s << getShaderEpilog();
2921 
2922     return s.str();
2923 }
2924 
2925 class StorageBufferInstance : virtual public CommonDescriptorInstance
2926 {
2927 public:
2928     StorageBufferInstance(Context &context, const TestCaseParams &testCaseParams);
2929 
2930 protected:
2931     void createAndPopulateDescriptors(IterateCommonVariables &variables) override;
2932     void createAndPopulateUnusedDescriptors(IterateCommonVariables &variables) override;
2933 
2934     bool verifyVertexWriteResults(IterateCommonVariables &variables) override;
2935 };
2936 
StorageBufferInstance(Context & context,const TestCaseParams & testCaseParams)2937 StorageBufferInstance::StorageBufferInstance(Context &context, const TestCaseParams &testCaseParams)
2938     : CommonDescriptorInstance(context, TestParams(VK_SHADER_STAGE_ALL_GRAPHICS, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
2939                                                    VK_DESCRIPTOR_TYPE_UNDEFINED, false,
2940                                                    performWritesInVertex(testCaseParams.descriptorType, context),
2941                                                    testCaseParams))
2942 {
2943 }
2944 
createAndPopulateDescriptors(IterateCommonVariables & variables)2945 void StorageBufferInstance::createAndPopulateDescriptors(IterateCommonVariables &variables)
2946 {
2947     BindingStorageBufferData data;
2948 
2949     bool vertexStores = false;
2950     {
2951         ut::DeviceProperties dp(m_context);
2952         vertexStores = dp.physicalDeviceFeatures().vertexPipelineStoresAndAtomics != false;
2953     }
2954     const uint32_t alignment = static_cast<uint32_t>(
2955         ut::DeviceProperties(m_context).physicalDeviceProperties().limits.minStorageBufferOffsetAlignment);
2956     createBuffers(variables.descriptorsBufferInfos, variables.descriptorsBuffer, variables.validDescriptorCount,
2957                   sizeof(data), alignment, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
2958 
2959     unsigned char *buffer = static_cast<unsigned char *>(variables.descriptorsBuffer->alloc->getHostPtr());
2960     for (uint32_t infoIdx = 0; infoIdx < variables.validDescriptorCount; ++infoIdx)
2961     {
2962         const float component = m_colorScheme[infoIdx % m_schemeSize];
2963         const tcu::Vec4 color(component, component, component, 1.0f);
2964         VkDescriptorBufferInfo &info = variables.descriptorsBufferInfos[infoIdx];
2965         data.cnew                    = vertexStores ? m_clearColor : color;
2966         data.cold                    = color;
2967 
2968         deMemcpy(buffer + info.offset, &data, sizeof(data));
2969     }
2970     vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
2971 
2972     variables.dataAlignment = deAlign64(sizeof(data), alignment);
2973 }
2974 
createAndPopulateUnusedDescriptors(IterateCommonVariables & variables)2975 void StorageBufferInstance::createAndPopulateUnusedDescriptors(IterateCommonVariables &variables)
2976 {
2977     const uint32_t alignment = static_cast<uint32_t>(
2978         ut::DeviceProperties(m_context).physicalDeviceProperties().limits.minStorageBufferOffsetAlignment);
2979     createBuffers(variables.unusedDescriptorsBufferInfos, variables.unusedDescriptorsBuffer, 1,
2980                   sizeof(BindingStorageBufferData), alignment, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
2981 }
2982 
verifyVertexWriteResults(IterateCommonVariables & variables)2983 bool StorageBufferInstance::verifyVertexWriteResults(IterateCommonVariables &variables)
2984 {
2985     auto &log = m_context.getTestContext().getLog();
2986     const tcu::Vec4 threshold(0.002f, 0.002f, 0.002f, 0.002f);
2987     const std::vector<uint32_t> primes = ut::generatePrimes(variables.availableDescriptorCount);
2988     unsigned char *buffer              = static_cast<unsigned char *>(variables.descriptorsBuffer->alloc->getHostPtr());
2989     BindingStorageBufferData data;
2990 
2991     log << tcu::TestLog::Message << "Available descriptor count: " << variables.availableDescriptorCount
2992         << tcu::TestLog::EndMessage;
2993     log << tcu::TestLog::Message << "Valid descriptor count:     " << variables.validDescriptorCount
2994         << tcu::TestLog::EndMessage;
2995 
2996     for (uint32_t primeIdx = 0; primeIdx < variables.validDescriptorCount; ++primeIdx)
2997     {
2998         const uint32_t prime  = primes[primeIdx];
2999         const float component = m_colorScheme[(prime % variables.validDescriptorCount) % m_schemeSize];
3000         const tcu::Vec4 referenceValue(component, component, component, 1.0f);
3001 
3002         VkDescriptorBufferInfo &info = variables.descriptorsBufferInfos[primeIdx];
3003         deMemcpy(&data, buffer + info.offset, sizeof(data));
3004         const tcu::Vec4 realValue = data.cnew;
3005 
3006         const tcu::Vec4 diff = tcu::absDiff(referenceValue, realValue);
3007         if (!tcu::boolAll(tcu::lessThanEqual(diff, threshold)))
3008         {
3009             log << tcu::TestLog::Message << "Error in valid descriptor " << primeIdx << " (descriptor " << prime
3010                 << "): expected " << referenceValue << " but found " << realValue << " (threshold " << threshold << ")"
3011                 << tcu::TestLog::EndMessage;
3012 
3013             return false;
3014         }
3015     }
3016     return true;
3017 }
3018 
3019 class UniformBufferInstance : virtual public CommonDescriptorInstance
3020 {
3021 public:
3022     UniformBufferInstance(Context &context, const TestCaseParams &testCaseParams);
3023 
3024 protected:
3025     void createAndPopulateDescriptors(IterateCommonVariables &variables) override;
3026     void createAndPopulateUnusedDescriptors(IterateCommonVariables &variables) override;
3027 };
3028 
UniformBufferInstance(Context & context,const TestCaseParams & testCaseParams)3029 UniformBufferInstance::UniformBufferInstance(Context &context, const TestCaseParams &testCaseParams)
3030     : CommonDescriptorInstance(context, TestParams(VK_SHADER_STAGE_ALL_GRAPHICS, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
3031                                                    VK_DESCRIPTOR_TYPE_UNDEFINED, false,
3032                                                    performWritesInVertex(testCaseParams.descriptorType, context),
3033                                                    testCaseParams))
3034 {
3035 }
3036 
createAndPopulateDescriptors(IterateCommonVariables & variables)3037 void UniformBufferInstance::createAndPopulateDescriptors(IterateCommonVariables &variables)
3038 {
3039     BindingUniformBufferData data;
3040 
3041     const uint32_t alignment = static_cast<uint32_t>(
3042         ut::DeviceProperties(m_context).physicalDeviceProperties().limits.minUniformBufferOffsetAlignment);
3043     createBuffers(variables.descriptorsBufferInfos, variables.descriptorsBuffer, variables.validDescriptorCount,
3044                   sizeof(data), alignment, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
3045 
3046     unsigned char *buffer = static_cast<unsigned char *>(variables.descriptorsBuffer->alloc->getHostPtr());
3047     for (uint32_t infoIdx = 0; infoIdx < variables.validDescriptorCount; ++infoIdx)
3048     {
3049         const float component        = m_colorScheme[infoIdx % m_schemeSize];
3050         VkDescriptorBufferInfo &info = variables.descriptorsBufferInfos[infoIdx];
3051         data.c                       = tcu::Vec4(component, component, component, 1.0f);
3052         deMemcpy(buffer + info.offset, &data, sizeof(data));
3053     }
3054     vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3055 
3056     variables.dataAlignment = deAlign64(sizeof(data), alignment);
3057 }
3058 
createAndPopulateUnusedDescriptors(IterateCommonVariables & variables)3059 void UniformBufferInstance::createAndPopulateUnusedDescriptors(IterateCommonVariables &variables)
3060 {
3061     // Just create buffer for unused descriptors, no data needed
3062     const uint32_t alignment = static_cast<uint32_t>(
3063         ut::DeviceProperties(m_context).physicalDeviceProperties().limits.minUniformBufferOffsetAlignment);
3064     createBuffers(variables.unusedDescriptorsBufferInfos, variables.unusedDescriptorsBuffer, 1,
3065                   sizeof(BindingUniformBufferData), alignment, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
3066 }
3067 
3068 class StorageTexelInstance : public CommonDescriptorInstance
3069 {
3070 public:
3071     StorageTexelInstance(Context &context, const TestCaseParams &testCaseParams);
3072 
3073 private:
3074     void createAndPopulateDescriptors(IterateCommonVariables &variables) override;
3075     void createAndPopulateUnusedDescriptors(IterateCommonVariables &variables) override;
3076 
3077     bool verifyVertexWriteResults(IterateCommonVariables &variables) override;
3078 };
3079 
StorageTexelInstance(Context & context,const TestCaseParams & testCaseParams)3080 StorageTexelInstance::StorageTexelInstance(Context &context, const TestCaseParams &testCaseParams)
3081     : CommonDescriptorInstance(
3082           context, TestParams(VK_SHADER_STAGE_ALL_GRAPHICS, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
3083                               VK_DESCRIPTOR_TYPE_UNDEFINED, false,
3084                               performWritesInVertex(testCaseParams.descriptorType, context), testCaseParams))
3085 {
3086 }
3087 
createAndPopulateDescriptors(IterateCommonVariables & variables)3088 void StorageTexelInstance::createAndPopulateDescriptors(IterateCommonVariables &variables)
3089 {
3090     const VkExtent3D imageExtent = {4, 4, 1};
3091     const uint32_t imageSize     = ut::computeImageSize(imageExtent, m_colorFormat);
3092 
3093     createBuffers(variables.descriptorsBufferInfos, variables.descriptorsBuffer, variables.validDescriptorCount,
3094                   imageSize, sizeof(tcu::Vec4), VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT);
3095     createBuffersViews(variables.descriptorsBufferViews, variables.descriptorsBufferInfos, m_colorFormat);
3096 
3097     for (uint32_t imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
3098     {
3099         const float component      = m_colorScheme[imageIdx % m_schemeSize];
3100         const PixelBufferAccess pa = getPixelAccess(imageIdx, imageExtent, m_colorFormat,
3101                                                     variables.descriptorsBufferInfos, variables.descriptorsBuffer);
3102 
3103         tcu::clear(pa, m_clearColor);
3104         pa.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
3105     }
3106     vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3107 }
3108 
createAndPopulateUnusedDescriptors(IterateCommonVariables & variables)3109 void StorageTexelInstance::createAndPopulateUnusedDescriptors(IterateCommonVariables &variables)
3110 {
3111     const VkExtent3D imageExtent = {4, 4, 1};
3112     const uint32_t imageSize     = ut::computeImageSize(imageExtent, m_colorFormat);
3113 
3114     createBuffers(variables.unusedDescriptorsBufferInfos, variables.unusedDescriptorsBuffer, 1, imageSize,
3115                   sizeof(tcu::Vec4), VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT);
3116     createBuffersViews(variables.unusedDescriptorsBufferViews, variables.unusedDescriptorsBufferInfos, m_colorFormat);
3117 }
3118 
verifyVertexWriteResults(IterateCommonVariables & variables)3119 bool StorageTexelInstance::verifyVertexWriteResults(IterateCommonVariables &variables)
3120 {
3121     auto &log                    = m_context.getTestContext().getLog();
3122     const VkExtent3D imageExtent = {4, 4, 1};
3123     const tcu::Vec4 threshold(0.002f, 0.002f, 0.002f, 0.002f);
3124     const std::vector<uint32_t> primes = ut::generatePrimes(variables.availableDescriptorCount);
3125 
3126     log << tcu::TestLog::Message << "Available descriptor count: " << variables.availableDescriptorCount
3127         << tcu::TestLog::EndMessage;
3128     log << tcu::TestLog::Message << "Valid descriptor count:     " << variables.validDescriptorCount
3129         << tcu::TestLog::EndMessage;
3130 
3131     for (uint32_t primeIdx = 0; primeIdx < variables.validDescriptorCount; ++primeIdx)
3132     {
3133         const uint32_t prime  = primes[primeIdx];
3134         const float component = m_colorScheme[(prime % variables.validDescriptorCount) % m_schemeSize];
3135         const tcu::Vec4 referenceValue(component, component, component, 1.0f);
3136 
3137         const PixelBufferAccess pa = getPixelAccess(primeIdx, imageExtent, m_colorFormat,
3138                                                     variables.descriptorsBufferInfos, variables.descriptorsBuffer);
3139         const tcu::Vec4 realValue  = pa.getPixel(1, 0);
3140 
3141         const tcu::Vec4 diff = tcu::absDiff(referenceValue, realValue);
3142         if (!tcu::boolAll(tcu::lessThanEqual(diff, threshold)))
3143         {
3144             log << tcu::TestLog::Message << "Error in valid descriptor " << primeIdx << " (descriptor " << prime
3145                 << "): expected " << referenceValue << " but found " << realValue << " (threshold " << threshold << ")"
3146                 << tcu::TestLog::EndMessage;
3147 
3148             return false;
3149         }
3150     }
3151     return true;
3152 }
3153 
3154 class UniformTexelInstance : public CommonDescriptorInstance
3155 {
3156 public:
3157     UniformTexelInstance(Context &context, const TestCaseParams &testCaseParams);
3158 
3159 private:
3160     void createAndPopulateDescriptors(IterateCommonVariables &variables) override;
3161     void createAndPopulateUnusedDescriptors(IterateCommonVariables &variables) override;
3162 };
3163 
UniformTexelInstance(Context & context,const TestCaseParams & testCaseParams)3164 UniformTexelInstance::UniformTexelInstance(Context &context, const TestCaseParams &testCaseParams)
3165     : CommonDescriptorInstance(
3166           context, TestParams(VK_SHADER_STAGE_ALL_GRAPHICS, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
3167                               VK_DESCRIPTOR_TYPE_UNDEFINED, false,
3168                               performWritesInVertex(testCaseParams.descriptorType, context), testCaseParams))
3169 {
3170 }
3171 
createAndPopulateDescriptors(IterateCommonVariables & variables)3172 void UniformTexelInstance::createAndPopulateDescriptors(IterateCommonVariables &variables)
3173 {
3174     const VkExtent3D imageExtent = {4, 4, 1};
3175     const uint32_t imageSize     = ut::computeImageSize(imageExtent, m_colorFormat);
3176 
3177     createBuffers(variables.descriptorsBufferInfos, variables.descriptorsBuffer, variables.validDescriptorCount,
3178                   imageSize, sizeof(tcu::Vec4), VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT);
3179     createBuffersViews(variables.descriptorsBufferViews, variables.descriptorsBufferInfos, m_colorFormat);
3180 
3181     for (uint32_t imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
3182     {
3183         const float component      = m_colorScheme[imageIdx % m_schemeSize];
3184         const PixelBufferAccess pa = getPixelAccess(imageIdx, imageExtent, m_colorFormat,
3185                                                     variables.descriptorsBufferInfos, variables.descriptorsBuffer);
3186 
3187         tcu::clear(pa, tcu::Vec4(component, component, component, 1.0f));
3188     }
3189     vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3190 }
3191 
createAndPopulateUnusedDescriptors(IterateCommonVariables & variables)3192 void UniformTexelInstance::createAndPopulateUnusedDescriptors(IterateCommonVariables &variables)
3193 {
3194     const VkExtent3D imageExtent = {4, 4, 1};
3195     const uint32_t imageSize     = ut::computeImageSize(imageExtent, m_colorFormat);
3196 
3197     createBuffers(variables.unusedDescriptorsBufferInfos, variables.unusedDescriptorsBuffer, 1, imageSize,
3198                   sizeof(tcu::Vec4), VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT);
3199     createBuffersViews(variables.unusedDescriptorsBufferViews, variables.unusedDescriptorsBufferInfos, m_colorFormat);
3200 }
3201 
3202 class DynamicBuffersInstance : virtual public CommonDescriptorInstance
3203 {
3204 public:
DynamicBuffersInstance(Context & context,const TestParams & testParams)3205     DynamicBuffersInstance(Context &context, const TestParams &testParams)
3206         : CommonDescriptorInstance(context, testParams)
3207     {
3208     }
3209 
3210 protected:
3211     virtual tcu::TestStatus iterate(void);
3212     virtual void updateDescriptors(IterateCommonVariables &variables);
3213 };
3214 
updateDescriptors(IterateCommonVariables & variables)3215 void DynamicBuffersInstance::updateDescriptors(IterateCommonVariables &variables)
3216 {
3217     DE_ASSERT(variables.dataAlignment);
3218 
3219     VkDescriptorBufferInfo bufferInfo = {*variables.descriptorsBuffer.get()->buffer,
3220                                          0, // always 0, it will be taken from pDynamicOffsets
3221                                          variables.dataAlignment};
3222 
3223     VkWriteDescriptorSet updateInfo = {
3224         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
3225         nullptr,                                // pNext
3226         *variables.descriptorSet,               // descriptorSet
3227         BINDING_TestObject,                     // descriptorBinding;
3228         0,                                      // to be set in below loop                    // dstArrayElement
3229         1u,                                     // descriptorCount
3230         m_testParams.descriptorType,            // descriptorType
3231         nullptr,                                // pImageInfo
3232         &bufferInfo,                            // pBufferInfo
3233         nullptr                                 // pTexelBufferView
3234     };
3235 
3236     uint32_t descIdx                   = 0;
3237     const std::vector<uint32_t> primes = ut::generatePrimes(variables.availableDescriptorCount);
3238     for (uint32_t validIdx = 0; validIdx < variables.validDescriptorCount; ++validIdx)
3239     {
3240         for (; descIdx < primes[validIdx]; ++descIdx)
3241         {
3242             updateInfo.dstArrayElement = descIdx;
3243             m_vki.updateDescriptorSets(m_vkd, 1u, &updateInfo, 0u, nullptr);
3244         }
3245 
3246         updateInfo.dstArrayElement = primes[validIdx];
3247         m_vki.updateDescriptorSets(m_vkd, 1u, &updateInfo, 0u, nullptr);
3248 
3249         ++descIdx;
3250     }
3251     for (; descIdx < variables.availableDescriptorCount; ++descIdx)
3252     {
3253         updateInfo.dstArrayElement = descIdx;
3254         m_vki.updateDescriptorSets(m_vkd, 1u, &updateInfo, 0u, nullptr);
3255     }
3256 }
3257 
iterate(void)3258 tcu::TestStatus DynamicBuffersInstance::iterate(void)
3259 {
3260     IterateCommonVariables v;
3261     iterateCommandSetup(v);
3262 
3263     ut::UpdatablePixelBufferAccessPtr programResult;
3264     ut::UpdatablePixelBufferAccessPtr referenceResult;
3265     bool firstPass = true;
3266 
3267     DE_ASSERT(v.dataAlignment);
3268 
3269     std::vector<uint32_t> dynamicOffsets;
3270 
3271     uint32_t descIdx                   = 0;
3272     const std::vector<uint32_t> primes = ut::generatePrimes(v.availableDescriptorCount);
3273     for (uint32_t validIdx = 0; validIdx < v.validDescriptorCount; ++validIdx)
3274     {
3275         for (; descIdx < primes[validIdx]; ++descIdx)
3276         {
3277             dynamicOffsets.push_back(0);
3278         }
3279 
3280         dynamicOffsets.push_back(static_cast<uint32_t>(validIdx * v.dataAlignment));
3281 
3282         ++descIdx;
3283     }
3284     for (; descIdx < v.availableDescriptorCount; ++descIdx)
3285     {
3286         dynamicOffsets.push_back(0);
3287     }
3288 
3289     // Unfortunatelly not lees and not more, only exactly
3290     DE_ASSERT(dynamicOffsets.size() == v.availableDescriptorCount);
3291 
3292     const VkDescriptorSet descriptorSets[] = {*v.descriptorSet};
3293 
3294     v.renderArea.extent.width  = m_testParams.frameResolution.width / 4;
3295     v.renderArea.extent.height = m_testParams.frameResolution.height / 4;
3296 
3297     for (int x = 0; x < 4; x++)
3298         for (int y = 0; y < 4; y++)
3299         {
3300             v.renderArea.offset.x = x * m_testParams.frameResolution.width / 4;
3301             v.renderArea.offset.y = y * m_testParams.frameResolution.height / 4;
3302 
3303             iterateCommandBegin(v, firstPass);
3304             firstPass = false;
3305 
3306             m_vki.cmdBindDescriptorSets(*v.commandBuffer,                   // commandBuffer
3307                                         VK_PIPELINE_BIND_POINT_GRAPHICS,    // pipelineBindPoint
3308                                         *v.pipelineLayout,                  // layout
3309                                         0u,                                 // firstSet
3310                                         DE_LENGTH_OF_ARRAY(descriptorSets), // descriptorSetCount
3311                                         descriptorSets,                     // pDescriptorSets
3312                                         v.availableDescriptorCount,         // dynamicOffsetCount
3313                                         dynamicOffsets.data());             // pDynamicOffsets
3314 
3315             vk::VkRect2D scissor = makeRect2D(v.renderArea.offset.x, v.renderArea.offset.y, v.renderArea.extent.width,
3316                                               v.renderArea.extent.height);
3317             m_vki.cmdSetScissor(*v.commandBuffer, 0u, 1u, &scissor);
3318 
3319             vk::beginRenderPass(m_vki, *v.commandBuffer, *v.renderPass, *v.frameBuffer->buffer, v.renderArea,
3320                                 m_clearColor);
3321             m_vki.cmdDraw(*v.commandBuffer, v.vertexCount, 1u, 0u, 0u);
3322             vk::endRenderPass(m_vki, *v.commandBuffer);
3323 
3324             iterateCommandEnd(v, programResult, referenceResult);
3325             programResult->invalidate();
3326         }
3327 
3328     if (iterateVerifyResults(v, programResult, referenceResult))
3329         return tcu::TestStatus::pass("Pass");
3330     return tcu::TestStatus::fail("Failed -- check log for details");
3331 }
3332 
3333 class DynamicStorageBufferInstance : public DynamicBuffersInstance, public StorageBufferInstance
3334 {
3335 public:
3336     DynamicStorageBufferInstance(Context &context, const TestCaseParams &testCaseParams);
3337     tcu::TestStatus iterate(void) override;
3338     void createAndPopulateDescriptors(IterateCommonVariables &variables) override;
3339     void createAndPopulateUnusedDescriptors(IterateCommonVariables &variables) override;
3340     void updateDescriptors(IterateCommonVariables &variables) override;
3341     bool verifyVertexWriteResults(IterateCommonVariables &variables) override;
3342 };
3343 
DynamicStorageBufferInstance(Context & context,const TestCaseParams & testCaseParams)3344 DynamicStorageBufferInstance::DynamicStorageBufferInstance(Context &context, const TestCaseParams &testCaseParams)
3345     : CommonDescriptorInstance(
3346           context, TestParams(VK_SHADER_STAGE_ALL_GRAPHICS, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC,
3347                               VK_DESCRIPTOR_TYPE_UNDEFINED, false,
3348                               performWritesInVertex(testCaseParams.descriptorType, context), testCaseParams))
3349     , DynamicBuffersInstance(context, m_testParams)
3350     , StorageBufferInstance(context, testCaseParams)
3351 {
3352 }
3353 
iterate(void)3354 tcu::TestStatus DynamicStorageBufferInstance::iterate(void)
3355 {
3356     return DynamicBuffersInstance::iterate();
3357 }
3358 
createAndPopulateDescriptors(IterateCommonVariables & variables)3359 void DynamicStorageBufferInstance::createAndPopulateDescriptors(IterateCommonVariables &variables)
3360 {
3361     StorageBufferInstance::createAndPopulateDescriptors(variables);
3362 }
3363 
createAndPopulateUnusedDescriptors(IterateCommonVariables & variables)3364 void DynamicStorageBufferInstance::createAndPopulateUnusedDescriptors(IterateCommonVariables &variables)
3365 {
3366     StorageBufferInstance::createAndPopulateUnusedDescriptors(variables);
3367 }
3368 
updateDescriptors(IterateCommonVariables & variables)3369 void DynamicStorageBufferInstance::updateDescriptors(IterateCommonVariables &variables)
3370 {
3371     DynamicBuffersInstance::updateDescriptors(variables);
3372 }
3373 
verifyVertexWriteResults(IterateCommonVariables & variables)3374 bool DynamicStorageBufferInstance::verifyVertexWriteResults(IterateCommonVariables &variables)
3375 {
3376     return StorageBufferInstance::verifyVertexWriteResults(variables);
3377 }
3378 
3379 class DynamicUniformBufferInstance : public DynamicBuffersInstance, public UniformBufferInstance
3380 {
3381 public:
3382     DynamicUniformBufferInstance(Context &context, const TestCaseParams &testCaseParams);
3383     tcu::TestStatus iterate(void) override;
3384     void createAndPopulateDescriptors(IterateCommonVariables &variables) override;
3385     void createAndPopulateUnusedDescriptors(IterateCommonVariables &variables) override;
3386     void updateDescriptors(IterateCommonVariables &variables) override;
3387 };
3388 
DynamicUniformBufferInstance(Context & context,const TestCaseParams & testCaseParams)3389 DynamicUniformBufferInstance::DynamicUniformBufferInstance(Context &context, const TestCaseParams &testCaseParams)
3390     : CommonDescriptorInstance(
3391           context, TestParams(VK_SHADER_STAGE_ALL_GRAPHICS, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
3392                               VK_DESCRIPTOR_TYPE_UNDEFINED, false,
3393                               performWritesInVertex(testCaseParams.descriptorType, context), testCaseParams))
3394     , DynamicBuffersInstance(context, m_testParams)
3395     , UniformBufferInstance(context, testCaseParams)
3396 {
3397 }
3398 
iterate(void)3399 tcu::TestStatus DynamicUniformBufferInstance::iterate(void)
3400 {
3401     return DynamicBuffersInstance::iterate();
3402 }
3403 
createAndPopulateDescriptors(IterateCommonVariables & variables)3404 void DynamicUniformBufferInstance::createAndPopulateDescriptors(IterateCommonVariables &variables)
3405 {
3406     UniformBufferInstance::createAndPopulateDescriptors(variables);
3407 }
3408 
createAndPopulateUnusedDescriptors(IterateCommonVariables & variables)3409 void DynamicUniformBufferInstance::createAndPopulateUnusedDescriptors(IterateCommonVariables &variables)
3410 {
3411     UniformBufferInstance::createAndPopulateUnusedDescriptors(variables);
3412 }
3413 
updateDescriptors(IterateCommonVariables & variables)3414 void DynamicUniformBufferInstance::updateDescriptors(IterateCommonVariables &variables)
3415 {
3416     DynamicBuffersInstance::updateDescriptors(variables);
3417 }
3418 
3419 class InputAttachmentInstance : public CommonDescriptorInstance
3420 {
3421 public:
3422     InputAttachmentInstance(Context &context, const TestCaseParams &testCaseParams);
3423 
3424 private:
3425     Move<VkRenderPass> createRenderPass(const IterateCommonVariables &variables) override;
3426     void createFramebuffer(ut::FrameBufferSp &frameBuffer, VkRenderPass renderPass,
3427                            const IterateCommonVariables &variables) override;
3428     void createAndPopulateDescriptors(IterateCommonVariables &variables) override;
3429     void createAndPopulateUnusedDescriptors(IterateCommonVariables &variables) override;
3430 };
3431 
InputAttachmentInstance(Context & context,const TestCaseParams & testCaseParams)3432 InputAttachmentInstance::InputAttachmentInstance(Context &context, const TestCaseParams &testCaseParams)
3433     : CommonDescriptorInstance(context, TestParams(VK_SHADER_STAGE_ALL_GRAPHICS, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
3434                                                    VK_DESCRIPTOR_TYPE_UNDEFINED, true,
3435                                                    performWritesInVertex(testCaseParams.descriptorType, context),
3436                                                    testCaseParams))
3437 {
3438 }
3439 
createAndPopulateDescriptors(IterateCommonVariables & variables)3440 void InputAttachmentInstance::createAndPopulateDescriptors(IterateCommonVariables &variables)
3441 {
3442     createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer,
3443                  VK_BUFFER_USAGE_TRANSFER_SRC_BIT, m_testParams.frameResolution, m_colorFormat,
3444                  VK_IMAGE_LAYOUT_UNDEFINED, variables.validDescriptorCount);
3445     createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, m_colorFormat);
3446 
3447     for (uint32_t descriptorIdx = 0; descriptorIdx < variables.validDescriptorCount; ++descriptorIdx)
3448     {
3449         const float component           = m_colorScheme[descriptorIdx % m_schemeSize];
3450         const tcu::PixelBufferAccess pa = getPixelAccess(descriptorIdx, m_testParams.frameResolution, m_colorFormat,
3451                                                          variables.descriptorsBufferInfos, variables.descriptorsBuffer);
3452         tcu::clear(pa, tcu::Vec4(component, component, component, 1.0f));
3453     }
3454     vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3455 }
3456 
createAndPopulateUnusedDescriptors(IterateCommonVariables & variables)3457 void InputAttachmentInstance::createAndPopulateUnusedDescriptors(IterateCommonVariables &variables)
3458 {
3459     createImages(variables.unusedDescriptorsImages, variables.unusedDescriptorsBufferInfos,
3460                  variables.unusedDescriptorsBuffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, m_testParams.frameResolution,
3461                  m_colorFormat, VK_IMAGE_LAYOUT_UNDEFINED, 1);
3462     createImagesViews(variables.unusedDescriptorImageViews, variables.unusedDescriptorsImages, m_colorFormat);
3463 }
3464 
createRenderPass(const IterateCommonVariables & variables)3465 Move<VkRenderPass> InputAttachmentInstance::createRenderPass(const IterateCommonVariables &variables)
3466 {
3467     std::vector<VkAttachmentDescription> attachmentDescriptions;
3468     std::vector<VkAttachmentReference> inputAttachmentRefs;
3469 
3470     const VkAttachmentDescription colorAttachmentDescription = {
3471         (VkAttachmentDescriptionFlags)0,          // VkAttachmentDescriptionFlags flags;
3472         m_colorFormat,                            // VkFormat format;
3473         VK_SAMPLE_COUNT_1_BIT,                    // VkSampleCountFlagBits samples;
3474         VK_ATTACHMENT_LOAD_OP_CLEAR,              // VkAttachmentLoadOp loadOp;
3475         VK_ATTACHMENT_STORE_OP_STORE,             // VkAttachmentStoreOp storeOp;
3476         VK_ATTACHMENT_LOAD_OP_DONT_CARE,          // VkAttachmentLoadOp stencilLoadOp;
3477         VK_ATTACHMENT_STORE_OP_DONT_CARE,         // VkAttachmentStoreOp stencilStoreOp;
3478         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
3479         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
3480     };
3481     const VkAttachmentReference colorAttachmentRef = {
3482         0u,                                      // uint32_t attachment;
3483         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
3484     };
3485     attachmentDescriptions.push_back(colorAttachmentDescription);
3486 
3487     // build input atachments
3488     {
3489         const std::vector<uint32_t> primes = ut::generatePrimes(variables.availableDescriptorCount);
3490         const uint32_t inputCount          = static_cast<uint32_t>(variables.descriptorImageViews.size());
3491         for (uint32_t inputIdx = 0; inputIdx < inputCount; ++inputIdx)
3492         {
3493             // primes holds the indices of input attachments for shader binding 10 which has input_attachment_index=1
3494             uint32_t nextInputAttachmentIndex = primes[inputIdx] + 1;
3495 
3496             // Fill up the subpass description's input attachments with unused attachments forming gaps to the next referenced attachment
3497             for (uint32_t unusedIdx = static_cast<uint32_t>(inputAttachmentRefs.size());
3498                  unusedIdx < nextInputAttachmentIndex; ++unusedIdx)
3499             {
3500                 const VkAttachmentReference inputAttachmentRef = {
3501                     VK_ATTACHMENT_UNUSED,   // uint32_t attachment;
3502                     VK_IMAGE_LAYOUT_GENERAL // VkImageLayout layout;
3503                 };
3504 
3505                 inputAttachmentRefs.push_back(inputAttachmentRef);
3506             }
3507 
3508             const VkAttachmentDescription inputAttachmentDescription = {
3509                 VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT,       // VkAttachmentDescriptionFlags flags;
3510                 variables.descriptorsImages[inputIdx]->format, // VkFormat format;
3511                 VK_SAMPLE_COUNT_1_BIT,                         // VkSampleCountFlagBits samples;
3512                 VK_ATTACHMENT_LOAD_OP_LOAD,                    // VkAttachmentLoadOp loadOp;
3513                 VK_ATTACHMENT_STORE_OP_STORE,                  // VkAttachmentStoreOp storeOp;
3514                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,               // VkAttachmentLoadOp stencilLoadOp;
3515                 VK_ATTACHMENT_STORE_OP_DONT_CARE,              // VkAttachmentStoreOp stencilStoreOp;
3516                 VK_IMAGE_LAYOUT_GENERAL,                       // VkImageLayout initialLayout;
3517                 VK_IMAGE_LAYOUT_GENERAL                        // VkImageLayout finalLayout;
3518             };
3519 
3520             const VkAttachmentReference inputAttachmentRef = {
3521                 inputIdx + 1,           // uint32_t attachment;
3522                 VK_IMAGE_LAYOUT_GENERAL // VkImageLayout layout;
3523             };
3524 
3525             inputAttachmentRefs.push_back(inputAttachmentRef);
3526             attachmentDescriptions.push_back(inputAttachmentDescription);
3527         }
3528     }
3529 
3530     const VkSubpassDescription subpassDescription = {
3531         (VkSubpassDescriptionFlags)0,                      // VkSubpassDescriptionFlags flags;
3532         VK_PIPELINE_BIND_POINT_GRAPHICS,                   // VkPipelineBindPoint pipelineBindPoint;
3533         static_cast<uint32_t>(inputAttachmentRefs.size()), // uint32_t inputAttachmentCount;
3534         inputAttachmentRefs.data(),                        // const VkAttachmentReference* pInputAttachments;
3535         1u,                                                // uint32_t colorAttachmentCount;
3536         &colorAttachmentRef,                               // const VkAttachmentReference* pColorAttachments;
3537         nullptr,                                           // const VkAttachmentReference* pResolveAttachments;
3538         nullptr,                                           // const VkAttachmentReference* pDepthStencilAttachment;
3539         0u,                                                // uint32_t preserveAttachmentCount;
3540         nullptr                                            // const uint32_t* pPreserveAttachments;
3541     };
3542 
3543     const VkRenderPassCreateInfo renderPassInfo = {
3544         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,            // VkStructureType sType;
3545         nullptr,                                              // const void* pNext;
3546         (VkRenderPassCreateFlags)0,                           // VkRenderPassCreateFlags flags;
3547         static_cast<uint32_t>(attachmentDescriptions.size()), // uint32_t attachmentCount;
3548         attachmentDescriptions.data(),                        // const VkAttachmentDescription* pAttachments;
3549         1u,                                                   // uint32_t subpassCount;
3550         &subpassDescription,                                  // const VkSubpassDescription* pSubpasses;
3551         0u,                                                   // uint32_t dependencyCount;
3552         nullptr                                               // const VkSubpassDependency* pDependencies;
3553     };
3554 
3555     return vk::createRenderPass(m_vki, m_vkd, &renderPassInfo);
3556 }
3557 
createFramebuffer(ut::FrameBufferSp & frameBuffer,VkRenderPass renderPass,const IterateCommonVariables & variables)3558 void InputAttachmentInstance::createFramebuffer(ut::FrameBufferSp &frameBuffer, VkRenderPass renderPass,
3559                                                 const IterateCommonVariables &variables)
3560 {
3561     std::vector<VkImageView> inputAttachments;
3562     const uint32_t viewCount = static_cast<uint32_t>(variables.descriptorImageViews.size());
3563     inputAttachments.resize(viewCount);
3564     for (uint32_t viewIdx = 0; viewIdx < viewCount; ++viewIdx)
3565     {
3566         inputAttachments[viewIdx] = **variables.descriptorImageViews[viewIdx];
3567     }
3568     ut::createFrameBuffer(frameBuffer, m_context, m_testParams.frameResolution, m_colorFormat, renderPass, viewCount,
3569                           inputAttachments.data());
3570 }
3571 
3572 class SamplerInstance : public CommonDescriptorInstance
3573 {
3574 public:
3575     SamplerInstance(Context &context, const TestCaseParams &testCaseParams);
3576 
3577 private:
3578     void createAndPopulateDescriptors(IterateCommonVariables &variables) override;
3579     void createAndPopulateUnusedDescriptors(IterateCommonVariables &variables) override;
3580     void updateDescriptors(IterateCommonVariables &variables) override;
3581 };
3582 
SamplerInstance(Context & context,const TestCaseParams & testCaseParams)3583 SamplerInstance::SamplerInstance(Context &context, const TestCaseParams &testCaseParams)
3584     : CommonDescriptorInstance(context, TestParams(VK_SHADER_STAGE_ALL_GRAPHICS, VK_DESCRIPTOR_TYPE_SAMPLER,
3585                                                    VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, true,
3586                                                    performWritesInVertex(testCaseParams.descriptorType, context),
3587                                                    testCaseParams))
3588 {
3589 }
3590 
updateDescriptors(IterateCommonVariables & variables)3591 void SamplerInstance::updateDescriptors(IterateCommonVariables &variables)
3592 {
3593     DE_ASSERT(variables.descriptorsImages.size() == 1);
3594     DE_ASSERT(variables.descriptorImageViews.size() == 1);
3595     DE_ASSERT(variables.descriptorsBufferInfos.size() == 1);
3596     DE_ASSERT(m_testParams.additionalDescriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
3597     DE_ASSERT(variables.descriptorSamplers.size() == variables.validDescriptorCount);
3598 
3599     // update an image
3600     {
3601         const VkDescriptorImageInfo imageInfo = {VK_NULL_HANDLE, **variables.descriptorImageViews[0],
3602                                                  VK_IMAGE_LAYOUT_GENERAL};
3603 
3604         const VkWriteDescriptorSet writeInfo = {
3605             VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
3606             nullptr,                                // pNext
3607             *variables.descriptorSet,               // descriptorSet
3608             BINDING_Additional,                     // descriptorBinding;
3609             0,                                      // elementIndex
3610             1u,                                     // descriptorCount
3611             VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,       // descriptorType
3612             &imageInfo,                             // pImageInfo
3613             nullptr,                                // pBufferInfo
3614             nullptr                                 // pTexelBufferView
3615         };
3616 
3617         m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, nullptr);
3618     }
3619 
3620     // update samplers
3621     CommonDescriptorInstance::updateDescriptors(variables);
3622 }
3623 
createAndPopulateDescriptors(IterateCommonVariables & variables)3624 void SamplerInstance::createAndPopulateDescriptors(IterateCommonVariables &variables)
3625 {
3626     DE_ASSERT(variables.descriptorsImages.size() == 0);
3627     DE_ASSERT(variables.descriptorImageViews.size() == 0);
3628     DE_ASSERT(variables.descriptorsBufferInfos.size() == 0);
3629     DE_ASSERT(variables.descriptorSamplers.size() == 0);
3630 
3631     // create and populate an image
3632     {
3633         VkExtent3D imageExtent = m_testParams.frameResolution;
3634         if (m_testParams.usesMipMaps)
3635         {
3636             imageExtent.width *= 2;
3637             imageExtent.height *= 2;
3638         }
3639 
3640         createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer,
3641                      VK_BUFFER_USAGE_TRANSFER_SRC_BIT, imageExtent, m_colorFormat, VK_IMAGE_LAYOUT_UNDEFINED, 1,
3642                      m_testParams.usesMipMaps);
3643         createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, m_colorFormat);
3644 
3645         PixelBufferAccess pa = getPixelAccess(0, imageExtent, m_colorFormat, variables.descriptorsBufferInfos,
3646                                               variables.descriptorsBuffer, m_testParams.usesMipMaps ? 1 : 0);
3647 
3648         for (uint32_t y = 0, pixelNum = 0; y < m_testParams.frameResolution.height; ++y)
3649         {
3650             for (uint32_t x = 0; x < m_testParams.frameResolution.width; ++x, ++pixelNum)
3651             {
3652                 const float component = m_colorScheme[(pixelNum % variables.validDescriptorCount) % m_schemeSize];
3653                 pa.setPixel(tcu::Vec4(component, component, component, 1.0f), x, y);
3654             }
3655         }
3656 
3657         vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3658     }
3659 
3660     const tcu::Sampler sampler(
3661         tcu::Sampler::CLAMP_TO_BORDER,                                                           // wrapS
3662         tcu::Sampler::CLAMP_TO_BORDER,                                                           // wrapT
3663         tcu::Sampler::CLAMP_TO_BORDER,                                                           // wrapR
3664         m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST, // minFilter
3665         m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST, // magFilter
3666         0.0f,                                                                                    // lodTreshold
3667         true,                                                                                    // normalizeCoords
3668         tcu::Sampler::COMPAREMODE_NONE,                                                          // compare
3669         0,                                                                                       // compareChannel
3670         tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),                                                       // borderColor
3671         true);                                                                                   // seamlessCubeMap
3672     const VkSamplerCreateInfo createInfo = vk::mapSampler(sampler, vk::mapVkFormat(m_colorFormat));
3673     variables.descriptorSamplers.resize(variables.validDescriptorCount);
3674 
3675     for (uint32_t samplerIdx = 0; samplerIdx < variables.validDescriptorCount; ++samplerIdx)
3676     {
3677         variables.descriptorSamplers[samplerIdx] =
3678             ut::SamplerSp(new Move<VkSampler>(vk::createSampler(m_vki, m_vkd, &createInfo)));
3679     }
3680 }
3681 
createAndPopulateUnusedDescriptors(IterateCommonVariables & variables)3682 void SamplerInstance::createAndPopulateUnusedDescriptors(IterateCommonVariables &variables)
3683 {
3684     DE_ASSERT(variables.unusedDescriptorsImages.size() == 0);
3685     DE_ASSERT(variables.unusedDescriptorImageViews.size() == 0);
3686     DE_ASSERT(variables.unusedDescriptorsBufferInfos.size() == 0);
3687     DE_ASSERT(variables.unusedDescriptorSamplers.size() == 0);
3688 
3689     // create and populate an image
3690     {
3691         VkExtent3D imageExtent = m_testParams.frameResolution;
3692         if (m_testParams.usesMipMaps)
3693         {
3694             imageExtent.width *= 2;
3695             imageExtent.height *= 2;
3696         }
3697 
3698         createImages(variables.unusedDescriptorsImages, variables.unusedDescriptorsBufferInfos,
3699                      variables.unusedDescriptorsBuffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, imageExtent, m_colorFormat,
3700                      VK_IMAGE_LAYOUT_UNDEFINED, 1, m_testParams.usesMipMaps);
3701         createImagesViews(variables.unusedDescriptorImageViews, variables.unusedDescriptorsImages, m_colorFormat);
3702     }
3703 
3704     const tcu::Sampler sampler(
3705         tcu::Sampler::CLAMP_TO_BORDER,                                                          // wrapS
3706         tcu::Sampler::CLAMP_TO_BORDER,                                                          // wrapT
3707         tcu::Sampler::CLAMP_TO_BORDER,                                                          // wrapR
3708         m_testParams.usesMipMaps ? tcu::Sampler::LINEAR_MIPMAP_NEAREST : tcu::Sampler::NEAREST, // minFilter
3709         m_testParams.usesMipMaps ? tcu::Sampler::LINEAR_MIPMAP_NEAREST : tcu::Sampler::NEAREST, // magFilter
3710         0.0f,                                                                                   // lodTreshold
3711         true,                                                                                   // normalizeCoords
3712         tcu::Sampler::COMPAREMODE_NONE,                                                         // compare
3713         0,                                                                                      // compareChannel
3714         tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),                                                      // borderColor
3715         true);                                                                                  // seamlessCubeMap
3716     const VkSamplerCreateInfo createInfo = vk::mapSampler(sampler, vk::mapVkFormat(m_colorFormat));
3717     variables.unusedDescriptorSamplers.resize(1);
3718     variables.unusedDescriptorSamplers[0] =
3719         ut::SamplerSp(new Move<VkSampler>(vk::createSampler(m_vki, m_vkd, &createInfo)));
3720 }
3721 
3722 class SampledImageInstance : public CommonDescriptorInstance
3723 {
3724 public:
3725     SampledImageInstance(Context &context, const TestCaseParams &testCaseParams);
3726 
3727 private:
3728     void createAndPopulateDescriptors(IterateCommonVariables &variables) override;
3729     void createAndPopulateUnusedDescriptors(IterateCommonVariables &variables) override;
3730     void updateDescriptors(IterateCommonVariables &variables) override;
3731 };
3732 
SampledImageInstance(Context & context,const TestCaseParams & testCaseParams)3733 SampledImageInstance::SampledImageInstance(Context &context, const TestCaseParams &testCaseParams)
3734     : CommonDescriptorInstance(context, TestParams(VK_SHADER_STAGE_ALL_GRAPHICS, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
3735                                                    VK_DESCRIPTOR_TYPE_SAMPLER, true,
3736                                                    performWritesInVertex(testCaseParams.descriptorType, context),
3737                                                    testCaseParams))
3738 {
3739 }
3740 
updateDescriptors(IterateCommonVariables & variables)3741 void SampledImageInstance::updateDescriptors(IterateCommonVariables &variables)
3742 {
3743     DE_ASSERT(variables.descriptorSamplers.size() == 1);
3744     DE_ASSERT(variables.descriptorsImages.size() == variables.validDescriptorCount);
3745     DE_ASSERT(variables.descriptorImageViews.size() == variables.validDescriptorCount);
3746     DE_ASSERT(variables.descriptorsBufferInfos.size() == variables.validDescriptorCount);
3747 
3748     // update a sampler
3749     {
3750         const VkDescriptorImageInfo samplerInfo = {**variables.descriptorSamplers[0], VK_NULL_HANDLE,
3751                                                    static_cast<VkImageLayout>(0)};
3752 
3753         const VkWriteDescriptorSet writeInfo = {
3754             VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
3755             nullptr,                                // pNext
3756             *variables.descriptorSet,               // descriptorSet
3757             BINDING_Additional,                     // descriptorBinding;
3758             0,                                      // elementIndex
3759             1u,                                     // descriptorCount
3760             VK_DESCRIPTOR_TYPE_SAMPLER,             // descriptorType
3761             &samplerInfo,                           // pImageInfo
3762             nullptr,                                // pBufferInfo
3763             nullptr                                 // pTexelBufferView
3764         };
3765 
3766         m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, nullptr);
3767     }
3768 
3769     // update images
3770     CommonDescriptorInstance::updateDescriptors(variables);
3771 }
3772 
createAndPopulateDescriptors(IterateCommonVariables & variables)3773 void SampledImageInstance::createAndPopulateDescriptors(IterateCommonVariables &variables)
3774 {
3775     DE_ASSERT(variables.descriptorSamplers.size() == 0);
3776     DE_ASSERT(variables.descriptorsImages.size() == 0);
3777     DE_ASSERT(variables.descriptorImageViews.size() == 0);
3778     DE_ASSERT(variables.descriptorsBufferInfos.size() == 0);
3779 
3780     // create an only one sampler for all images
3781     {
3782         const tcu::Sampler sampler(
3783             tcu::Sampler::CLAMP_TO_BORDER,                                                           // wrapS
3784             tcu::Sampler::CLAMP_TO_BORDER,                                                           // wrapT
3785             tcu::Sampler::CLAMP_TO_BORDER,                                                           // wrapR
3786             m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST, // minFilter
3787             m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST, // magFilter
3788             0.0f,                                                                                    // lodTreshold
3789             true,                                                                                    // normalizeCoords
3790             tcu::Sampler::COMPAREMODE_NONE,                                                          // compare
3791             0,                                                                                       // compareChannel
3792             tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),                                                       // borderColor
3793             true);                                                                                   // seamlessCubeMap
3794         const VkSamplerCreateInfo createInfo = vk::mapSampler(sampler, vk::mapVkFormat(m_colorFormat));
3795         variables.descriptorSamplers.push_back(
3796             ut::SamplerSp(new Move<VkSampler>(vk::createSampler(m_vki, m_vkd, &createInfo))));
3797     }
3798 
3799     const VkExtent3D &imageExtent = m_testParams.usesMipMaps ? bigImageExtent : smallImageExtent;
3800 
3801     createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer,
3802                  VK_BUFFER_USAGE_TRANSFER_SRC_BIT, imageExtent, m_colorFormat, VK_IMAGE_LAYOUT_UNDEFINED,
3803                  variables.validDescriptorCount, m_testParams.usesMipMaps);
3804     createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, m_colorFormat);
3805 
3806     PixelBufferAccess pixelAccess;
3807     for (uint32_t imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
3808     {
3809         const float component = m_colorScheme[imageIdx % m_schemeSize];
3810 
3811         if (m_testParams.usesMipMaps)
3812         {
3813             const uint32_t mipCount = ut::computeMipMapCount(imageExtent);
3814             DE_ASSERT(mipCount >= 2);
3815             for (uint32_t mipIdx = 0; mipIdx < mipCount; ++mipIdx)
3816             {
3817                 pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos,
3818                                              variables.descriptorsBuffer, mipIdx);
3819                 tcu::clear(pixelAccess, m_clearColor);
3820             }
3821 
3822             pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos,
3823                                          variables.descriptorsBuffer, mipCount - 1);
3824             pixelAccess.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
3825         }
3826         else
3827         {
3828             pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos,
3829                                          variables.descriptorsBuffer, 0);
3830             pixelAccess.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
3831         }
3832     }
3833     vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3834 }
3835 
createAndPopulateUnusedDescriptors(IterateCommonVariables & variables)3836 void SampledImageInstance::createAndPopulateUnusedDescriptors(IterateCommonVariables &variables)
3837 {
3838     DE_ASSERT(variables.unusedDescriptorSamplers.size() == 0);
3839     DE_ASSERT(variables.unusedDescriptorsImages.size() == 0);
3840     DE_ASSERT(variables.unusedDescriptorImageViews.size() == 0);
3841     DE_ASSERT(variables.unusedDescriptorsBufferInfos.size() == 0);
3842 
3843     // create an only one sampler for all images
3844     {
3845         const tcu::Sampler sampler(
3846             tcu::Sampler::CLAMP_TO_BORDER,                                                           // wrapS
3847             tcu::Sampler::CLAMP_TO_BORDER,                                                           // wrapT
3848             tcu::Sampler::CLAMP_TO_BORDER,                                                           // wrapR
3849             m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST, // minFilter
3850             m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST, // magFilter
3851             0.0f,                                                                                    // lodTreshold
3852             true,                                                                                    // normalizeCoords
3853             tcu::Sampler::COMPAREMODE_NONE,                                                          // compare
3854             0,                                                                                       // compareChannel
3855             tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),                                                       // borderColor
3856             true);                                                                                   // seamlessCubeMap
3857         const VkSamplerCreateInfo createInfo = vk::mapSampler(sampler, vk::mapVkFormat(m_colorFormat));
3858         variables.unusedDescriptorSamplers.push_back(
3859             ut::SamplerSp(new Move<VkSampler>(vk::createSampler(m_vki, m_vkd, &createInfo))));
3860     }
3861 
3862     const VkExtent3D &imageExtent = m_testParams.usesMipMaps ? bigImageExtent : smallImageExtent;
3863 
3864     createImages(variables.unusedDescriptorsImages, variables.unusedDescriptorsBufferInfos,
3865                  variables.unusedDescriptorsBuffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, imageExtent, m_colorFormat,
3866                  VK_IMAGE_LAYOUT_UNDEFINED, 1, m_testParams.usesMipMaps);
3867     createImagesViews(variables.unusedDescriptorImageViews, variables.unusedDescriptorsImages, m_colorFormat);
3868 }
3869 
3870 class CombinedImageInstance : public CommonDescriptorInstance
3871 {
3872 public:
3873     CombinedImageInstance(Context &context, const TestCaseParams &testCaseParams);
3874 
3875 private:
3876     void createAndPopulateDescriptors(IterateCommonVariables &variables) override;
3877     void createAndPopulateUnusedDescriptors(IterateCommonVariables &variables) override;
3878     void updateDescriptors(IterateCommonVariables &variables) override;
3879 };
3880 
CombinedImageInstance(Context & context,const TestCaseParams & testCaseParams)3881 CombinedImageInstance::CombinedImageInstance(Context &context, const TestCaseParams &testCaseParams)
3882     : CommonDescriptorInstance(
3883           context, TestParams(VK_SHADER_STAGE_ALL_GRAPHICS, testCaseParams.descriptorType, VK_DESCRIPTOR_TYPE_UNDEFINED,
3884                               true, performWritesInVertex(testCaseParams.descriptorType), testCaseParams))
3885 {
3886 }
3887 
updateDescriptors(IterateCommonVariables & variables)3888 void CombinedImageInstance::updateDescriptors(IterateCommonVariables &variables)
3889 {
3890     const std::vector<uint32_t> primes = ut::generatePrimes(variables.availableDescriptorCount);
3891     const uint32_t primeCount          = static_cast<uint32_t>(primes.size());
3892 
3893     DE_ASSERT(variables.descriptorSamplers.size() == 1);
3894     DE_ASSERT(variables.descriptorsImages.size() == primeCount);
3895     DE_ASSERT(variables.descriptorImageViews.size() == primeCount);
3896     DE_ASSERT(variables.descriptorsBufferInfos.size() == primeCount);
3897 
3898     for (uint32_t primeIdx = 0; primeIdx < primeCount; ++primeIdx)
3899     {
3900         const VkDescriptorImageInfo imageInfo = {**variables.descriptorSamplers[0],
3901                                                  **variables.descriptorImageViews[primeIdx], VK_IMAGE_LAYOUT_GENERAL};
3902 
3903         const VkWriteDescriptorSet writeInfo = {
3904             VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
3905             nullptr,                                // pNext
3906             *variables.descriptorSet,               // descriptorSet
3907             BINDING_TestObject,                     // descriptorBinding;
3908             primes[primeIdx],                       // elementIndex
3909             1u,                                     // descriptorCount
3910             m_testParams.descriptorType,            // descriptorType
3911             &imageInfo,                             // pImageInfo
3912             nullptr,                                // pBufferInfo
3913             nullptr                                 // pTexelBufferView
3914         };
3915 
3916         m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, nullptr);
3917     }
3918 }
3919 
createAndPopulateDescriptors(IterateCommonVariables & variables)3920 void CombinedImageInstance::createAndPopulateDescriptors(IterateCommonVariables &variables)
3921 {
3922     DE_ASSERT(variables.descriptorSamplers.size() == 0);
3923     DE_ASSERT(variables.descriptorsImages.size() == 0);
3924     DE_ASSERT(variables.descriptorImageViews.size() == 0);
3925     DE_ASSERT(variables.descriptorsBufferInfos.size() == 0);
3926     DE_ASSERT(variables.descriptorSamplers.size() == 0);
3927 
3928     const tcu::Sampler sampler(
3929         tcu::Sampler::CLAMP_TO_BORDER,                                                           // wrapS
3930         tcu::Sampler::CLAMP_TO_BORDER,                                                           // wrapT
3931         tcu::Sampler::CLAMP_TO_BORDER,                                                           // wrapR
3932         m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST, // minFilter
3933         m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST, // magFilter
3934         0.0f,                                                                                    // lodTreshold
3935         true,                                                                                    // normalizeCoords
3936         tcu::Sampler::COMPAREMODE_NONE,                                                          // compare
3937         0,                                                                                       // compareChannel
3938         tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),                                                       // borderColor
3939         true);                                                                                   // seamlessCubeMap
3940     const VkSamplerCreateInfo createInfo = vk::mapSampler(sampler, vk::mapVkFormat(m_colorFormat));
3941     variables.descriptorSamplers.push_back(
3942         ut::SamplerSp(new Move<VkSampler>(vk::createSampler(m_vki, m_vkd, &createInfo))));
3943 
3944     const VkExtent3D &imageExtent = m_testParams.usesMipMaps ? bigImageExtent : smallImageExtent;
3945     createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer,
3946                  VK_BUFFER_USAGE_TRANSFER_SRC_BIT, imageExtent, m_colorFormat, VK_IMAGE_LAYOUT_UNDEFINED,
3947                  variables.validDescriptorCount, m_testParams.usesMipMaps);
3948     createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, m_colorFormat);
3949 
3950     PixelBufferAccess pixelAccess;
3951     for (uint32_t imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
3952     {
3953         const float component = m_colorScheme[imageIdx % m_schemeSize];
3954 
3955         if (m_testParams.usesMipMaps)
3956         {
3957             const uint32_t mipCount = ut::computeMipMapCount(imageExtent);
3958             DE_ASSERT(mipCount >= 2);
3959             for (uint32_t mipIdx = 0; mipIdx < mipCount; ++mipIdx)
3960             {
3961                 pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos,
3962                                              variables.descriptorsBuffer, mipIdx);
3963                 tcu::clear(pixelAccess, m_clearColor);
3964             }
3965 
3966             pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos,
3967                                          variables.descriptorsBuffer, mipCount - 1);
3968             pixelAccess.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
3969         }
3970         else
3971         {
3972             pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos,
3973                                          variables.descriptorsBuffer, 0);
3974             pixelAccess.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
3975         }
3976     }
3977 
3978     vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3979 }
3980 
createAndPopulateUnusedDescriptors(IterateCommonVariables & variables)3981 void CombinedImageInstance::createAndPopulateUnusedDescriptors(IterateCommonVariables &variables)
3982 {
3983     DE_ASSERT(variables.unusedDescriptorSamplers.size() == 0);
3984     DE_ASSERT(variables.unusedDescriptorsImages.size() == 0);
3985     DE_ASSERT(variables.unusedDescriptorImageViews.size() == 0);
3986     DE_ASSERT(variables.unusedDescriptorsBufferInfos.size() == 0);
3987     DE_ASSERT(variables.unusedDescriptorSamplers.size() == 0);
3988 
3989     const tcu::Sampler sampler(
3990         tcu::Sampler::CLAMP_TO_BORDER,                                                           // wrapS
3991         tcu::Sampler::CLAMP_TO_BORDER,                                                           // wrapT
3992         tcu::Sampler::CLAMP_TO_BORDER,                                                           // wrapR
3993         m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST, // minFilter
3994         m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST, // magFilter
3995         0.0f,                                                                                    // lodTreshold
3996         true,                                                                                    // normalizeCoords
3997         tcu::Sampler::COMPAREMODE_NONE,                                                          // compare
3998         0,                                                                                       // compareChannel
3999         tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),                                                       // borderColor
4000         true);                                                                                   // seamlessCubeMap
4001     const VkSamplerCreateInfo createInfo = vk::mapSampler(sampler, vk::mapVkFormat(m_colorFormat));
4002     variables.unusedDescriptorSamplers.push_back(
4003         ut::SamplerSp(new Move<VkSampler>(vk::createSampler(m_vki, m_vkd, &createInfo))));
4004 
4005     const VkExtent3D &imageExtent = m_testParams.usesMipMaps ? bigImageExtent : smallImageExtent;
4006     createImages(variables.unusedDescriptorsImages, variables.unusedDescriptorsBufferInfos,
4007                  variables.unusedDescriptorsBuffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, imageExtent, m_colorFormat,
4008                  VK_IMAGE_LAYOUT_UNDEFINED, 1, m_testParams.usesMipMaps);
4009     createImagesViews(variables.unusedDescriptorImageViews, variables.unusedDescriptorsImages, m_colorFormat);
4010 }
4011 
4012 class StorageImageInstance : public CommonDescriptorInstance
4013 {
4014 public:
4015     StorageImageInstance(Context &context, const TestCaseParams &testCaseParams);
4016 
4017 private:
4018     tcu::TestStatus iterate(void) override;
4019     void createAndPopulateDescriptors(IterateCommonVariables &variables) override;
4020     void createAndPopulateUnusedDescriptors(IterateCommonVariables &variables) override;
4021     void updateDescriptors(IterateCommonVariables &variables) override;
4022     void iterateCollectResults(ut::UpdatablePixelBufferAccessPtr &result, const IterateCommonVariables &variables,
4023                                bool fromTest) override;
4024     ut::BufferHandleAllocSp m_buffer;
4025     const uint32_t m_fillColor;
4026     typedef uint32_t m_imageFormat_t;
4027 };
4028 
StorageImageInstance(Context & context,const TestCaseParams & testCaseParams)4029 StorageImageInstance::StorageImageInstance(Context &context, const TestCaseParams &testCaseParams)
4030     : CommonDescriptorInstance(context, TestParams(VK_SHADER_STAGE_COMPUTE_BIT, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
4031                                                    VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, true,
4032                                                    performWritesInVertex(testCaseParams.descriptorType, context),
4033                                                    testCaseParams))
4034     , m_buffer()
4035     , m_fillColor(10)
4036 {
4037 }
4038 
updateDescriptors(IterateCommonVariables & variables)4039 void StorageImageInstance::updateDescriptors(IterateCommonVariables &variables)
4040 {
4041     // update image at last index
4042     {
4043         VkDescriptorImageInfo imageInfo = {
4044             VK_NULL_HANDLE, **variables.descriptorImageViews[variables.validDescriptorCount], VK_IMAGE_LAYOUT_GENERAL};
4045 
4046         const VkWriteDescriptorSet writeInfo = {
4047             VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
4048             nullptr,                                // pNext
4049             *variables.descriptorSet,               // descriptorSet
4050             BINDING_Additional,                     // descriptorBinding;
4051             0,                                      // elementIndex
4052             1u,                                     // descriptorCount
4053             m_testParams.additionalDescriptorType,  // descriptorType
4054             &imageInfo,                             // pImageInfo
4055             nullptr,                                // pBufferInfo
4056             nullptr                                 // pTexelBufferView
4057         };
4058 
4059         m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, nullptr);
4060     }
4061 
4062     // update rest images
4063     CommonDescriptorInstance::updateDescriptors(variables);
4064 }
4065 
createAndPopulateDescriptors(IterateCommonVariables & variables)4066 void StorageImageInstance::createAndPopulateDescriptors(IterateCommonVariables &variables)
4067 {
4068     const VkFormat imageFormat = ut::mapType2vkFormat<m_imageFormat_t>::value;
4069     const VkBufferUsageFlags bufferUsage =
4070         VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
4071 
4072     // create descriptor buffer, images and views
4073     {
4074         const VkExtent3D imageExtent = {4, 4, 1};
4075 
4076         createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer,
4077                      bufferUsage, imageExtent, imageFormat, VK_IMAGE_LAYOUT_UNDEFINED, variables.validDescriptorCount);
4078 
4079         for (uint32_t imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
4080         {
4081             const PixelBufferAccess pa = getPixelAccess(imageIdx, imageExtent, imageFormat,
4082                                                         variables.descriptorsBufferInfos, variables.descriptorsBuffer);
4083             tcu::clear(pa, tcu::UVec4(m_fillColor));
4084         }
4085         vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
4086     }
4087 
4088     // create additional image that will be used as index container
4089     {
4090         createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, m_buffer, bufferUsage,
4091                      m_testParams.frameResolution, imageFormat, VK_IMAGE_LAYOUT_UNDEFINED, 1);
4092 
4093         // populate buffer
4094         const std::vector<uint32_t> primes = ut::generatePrimes(variables.availableDescriptorCount);
4095         const PixelBufferAccess pa = getPixelAccess(variables.validDescriptorCount, m_testParams.frameResolution,
4096                                                     imageFormat, variables.descriptorsBufferInfos, m_buffer);
4097         for (uint32_t y = 0, pixel = 0; y < m_testParams.frameResolution.height; ++y)
4098         {
4099             for (uint32_t x = 0; x < m_testParams.frameResolution.width; ++x, ++pixel)
4100             {
4101                 const uint32_t component = primes[pixel % variables.validDescriptorCount];
4102                 pa.setPixel(tcu::UVec4(component), x, y);
4103             }
4104         }
4105 
4106         // save changes
4107         vk::flushAlloc(m_vki, m_vkd, *m_buffer->alloc);
4108     }
4109 
4110     // create views for all previously created images
4111     createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, imageFormat);
4112 }
4113 
createAndPopulateUnusedDescriptors(IterateCommonVariables & variables)4114 void StorageImageInstance::createAndPopulateUnusedDescriptors(IterateCommonVariables &variables)
4115 {
4116     const VkFormat imageFormat = ut::mapType2vkFormat<m_imageFormat_t>::value;
4117     const VkBufferUsageFlags bufferUsage =
4118         VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
4119     const VkExtent3D imageExtent = {4, 4, 1};
4120 
4121     createImages(variables.unusedDescriptorsImages, variables.unusedDescriptorsBufferInfos,
4122                  variables.unusedDescriptorsBuffer, bufferUsage, imageExtent, imageFormat, VK_IMAGE_LAYOUT_UNDEFINED,
4123                  1);
4124     createImagesViews(variables.unusedDescriptorImageViews, variables.unusedDescriptorsImages, imageFormat);
4125 }
4126 
iterate(void)4127 tcu::TestStatus StorageImageInstance::iterate(void)
4128 {
4129     IterateCommonVariables v;
4130     iterateCommandSetup(v);
4131     iterateCommandBegin(v);
4132 
4133     ut::UpdatablePixelBufferAccessPtr programResult;
4134     ut::UpdatablePixelBufferAccessPtr referenceResult;
4135 
4136     if (m_testParams.updateAfterBind)
4137     {
4138         updateDescriptors(v);
4139     }
4140 
4141     copyBuffersToImages(v);
4142 
4143     m_vki.cmdDispatch(*v.commandBuffer,
4144                       m_testParams.calculateInLoop ?
4145                           1 :
4146                           (v.renderArea.extent.width / (m_testParams.minNonUniform ? 1u : kMinWorkGroupSize)),
4147                       m_testParams.calculateInLoop ? 1 : v.renderArea.extent.height, 1);
4148 
4149     copyImagesToBuffers(v);
4150 
4151     iterateCommandEnd(v, programResult, referenceResult, false);
4152 
4153     if (iterateVerifyResults(v, programResult, referenceResult))
4154         return tcu::TestStatus::pass("Pass");
4155     return tcu::TestStatus::fail("Failed -- check log for details");
4156 }
4157 
iterateCollectResults(ut::UpdatablePixelBufferAccessPtr & result,const IterateCommonVariables & variables,bool fromTest)4158 void StorageImageInstance::iterateCollectResults(ut::UpdatablePixelBufferAccessPtr &result,
4159                                                  const IterateCommonVariables &variables, bool fromTest)
4160 {
4161     result                       = ut::UpdatablePixelBufferAccessPtr(new ut::PixelBufferAccessAllocation(
4162         vk::mapVkFormat(ut::mapType2vkFormat<m_imageFormat_t>::value), m_testParams.frameResolution));
4163     const PixelBufferAccess &dst = *result.get();
4164 
4165     if (fromTest)
4166     {
4167         vk::invalidateAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
4168         for (uint32_t y = 0, pixelNum = 0; y < m_testParams.frameResolution.height; ++y)
4169         {
4170             for (uint32_t x = 0; x < m_testParams.frameResolution.width; ++x, ++pixelNum)
4171             {
4172                 const uint32_t imageIdx = pixelNum % variables.validDescriptorCount;
4173                 const PixelBufferAccess src =
4174                     getPixelAccess(imageIdx, variables.descriptorsImages[imageIdx]->extent,
4175                                    variables.descriptorsImages[imageIdx]->format, variables.descriptorsBufferInfos,
4176                                    variables.descriptorsBuffer);
4177                 dst.setPixel(tcu::Vector<m_imageFormat_t, 4>(src.getPixelT<m_imageFormat_t>(0, 0).x()), x, y);
4178             }
4179         }
4180     }
4181     else
4182     {
4183         std::vector<m_imageFormat_t> inc(variables.validDescriptorCount, m_fillColor);
4184 
4185         for (uint32_t invIdx = variables.lowerBound; invIdx < variables.upperBound; ++invIdx)
4186         {
4187             ++inc[invIdx % variables.validDescriptorCount];
4188         }
4189 
4190         for (uint32_t invIdx = 0; invIdx < variables.vertexCount; ++invIdx)
4191         {
4192             const uint32_t row          = invIdx / m_testParams.frameResolution.width;
4193             const uint32_t col          = invIdx % m_testParams.frameResolution.width;
4194             const m_imageFormat_t color = inc[invIdx % variables.validDescriptorCount];
4195             dst.setPixel(tcu::Vector<m_imageFormat_t, 4>(color), col, row);
4196         }
4197     }
4198 }
4199 
4200 class DescriptorIndexingTestCase : public TestCase
4201 {
4202     const TestCaseParams m_testCaseParams;
4203 
4204 public:
DescriptorIndexingTestCase(tcu::TestContext & context,const char * name,const TestCaseParams & testCaseParams)4205     DescriptorIndexingTestCase(tcu::TestContext &context, const char *name, const TestCaseParams &testCaseParams)
4206         : TestCase(context, name)
4207         , m_testCaseParams(testCaseParams)
4208     {
4209     }
4210 
createInstance(vkt::Context & context) const4211     vkt::TestInstance *createInstance(vkt::Context &context) const // override
4212     {
4213         switch (m_testCaseParams.descriptorType)
4214         {
4215         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
4216             return new StorageBufferInstance(context, m_testCaseParams);
4217         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
4218             return new UniformBufferInstance(context, m_testCaseParams);
4219         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
4220             return new StorageTexelInstance(context, m_testCaseParams);
4221         case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
4222             return new UniformTexelInstance(context, m_testCaseParams);
4223         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
4224             return new DynamicStorageBufferInstance(context, m_testCaseParams);
4225         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
4226             return new DynamicUniformBufferInstance(context, m_testCaseParams);
4227         case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
4228             return new InputAttachmentInstance(context, m_testCaseParams);
4229         case VK_DESCRIPTOR_TYPE_SAMPLER:
4230             return new SamplerInstance(context, m_testCaseParams);
4231         case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
4232             return new SampledImageInstance(context, m_testCaseParams);
4233         case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
4234             return new CombinedImageInstance(context, m_testCaseParams);
4235         case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
4236             return new StorageImageInstance(context, m_testCaseParams);
4237         default:
4238             TCU_THROW(InternalError, "Unknown Descriptor Type");
4239         }
4240         return nullptr;
4241     }
4242 
checkSupport(vkt::Context & context) const4243     virtual void checkSupport(vkt::Context &context) const
4244     {
4245         const vk::VkPhysicalDeviceDescriptorIndexingFeatures &feats = context.getDescriptorIndexingFeatures();
4246 
4247         if (!feats.runtimeDescriptorArray)
4248             TCU_THROW(NotSupportedError, "runtimeDescriptorArray not supported");
4249 
4250         switch (m_testCaseParams.descriptorType)
4251         {
4252         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
4253             if (!(feats.shaderStorageBufferArrayNonUniformIndexing))
4254                 TCU_THROW(NotSupportedError,
4255                           "Non-uniform indexing over storage buffer descriptor arrays is not supported.");
4256 
4257             if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingStorageBufferUpdateAfterBind)
4258                 TCU_THROW(NotSupportedError, "Update after bind for storage buffer descriptors is not supported.");
4259             break;
4260         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
4261             if (!(feats.shaderUniformBufferArrayNonUniformIndexing))
4262                 TCU_THROW(NotSupportedError,
4263                           "Non-uniform indexing for uniform buffer descriptor arrays is not supported.");
4264 
4265             if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingUniformBufferUpdateAfterBind)
4266                 TCU_THROW(NotSupportedError, "Update after bind for uniform buffer descriptors is not supported.");
4267             break;
4268         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
4269             if (!(feats.shaderStorageTexelBufferArrayNonUniformIndexing))
4270                 TCU_THROW(NotSupportedError,
4271                           "Non-uniform indexing for storage texel buffer descriptor arrays is not supported.");
4272 
4273             if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingStorageTexelBufferUpdateAfterBind)
4274                 TCU_THROW(NotSupportedError,
4275                           "Update after bind for storage texel buffer descriptors is not supported.");
4276             break;
4277         case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
4278             if (!(feats.shaderUniformTexelBufferArrayNonUniformIndexing))
4279                 TCU_THROW(NotSupportedError,
4280                           "Non-uniform indexing for uniform texel buffer descriptor arrays is not supported.");
4281 
4282             if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingUniformTexelBufferUpdateAfterBind)
4283                 TCU_THROW(NotSupportedError,
4284                           "Update after bind for uniform texel buffer descriptors is not supported.");
4285             break;
4286         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
4287             if (!(feats.shaderStorageBufferArrayNonUniformIndexing))
4288                 TCU_THROW(NotSupportedError,
4289                           "Non-uniform indexing over storage buffer dynamic descriptor arrays is not supported.");
4290 
4291             if (m_testCaseParams.updateAfterBind)
4292                 TCU_THROW(NotSupportedError,
4293                           "Update after bind for storage buffer dynamic descriptors is not supported.");
4294             break;
4295         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
4296             if (!(feats.shaderUniformBufferArrayNonUniformIndexing))
4297                 TCU_THROW(NotSupportedError,
4298                           "Non-uniform indexing over uniform buffer dynamic descriptor arrays is not supported.");
4299 
4300             if (m_testCaseParams.updateAfterBind)
4301                 TCU_THROW(NotSupportedError,
4302                           "Update after bind for uniform buffer dynamic descriptors is not supported.");
4303             break;
4304         case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
4305             if (!(feats.shaderInputAttachmentArrayNonUniformIndexing))
4306                 TCU_THROW(NotSupportedError,
4307                           "Non-uniform indexing over input attachment descriptor arrays is not supported.");
4308 
4309             if (m_testCaseParams.updateAfterBind)
4310                 TCU_THROW(NotSupportedError, "Update after bind for input attachment descriptors is not supported.");
4311             break;
4312         case VK_DESCRIPTOR_TYPE_SAMPLER:
4313             if (!(feats.shaderSampledImageArrayNonUniformIndexing))
4314                 TCU_THROW(NotSupportedError, "Non-uniform indexing over sampler descriptor arrays is not supported.");
4315 
4316             if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingSampledImageUpdateAfterBind)
4317                 TCU_THROW(NotSupportedError, "Update after bind for sampler descriptors is not supported.");
4318             break;
4319         case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
4320             if (!(feats.shaderSampledImageArrayNonUniformIndexing))
4321                 TCU_THROW(NotSupportedError,
4322                           "Non-uniform indexing over sampled image descriptor arrays is not supported.");
4323 
4324             if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingSampledImageUpdateAfterBind)
4325                 TCU_THROW(NotSupportedError, "Update after bind for sampled image descriptors is not supported.");
4326             break;
4327         case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
4328             if (!(feats.shaderSampledImageArrayNonUniformIndexing))
4329                 TCU_THROW(NotSupportedError,
4330                           "Non-uniform indexing over combined image sampler descriptor arrays is not supported.");
4331 
4332             if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingSampledImageUpdateAfterBind)
4333                 TCU_THROW(NotSupportedError,
4334                           "Update after bind for combined image sampler descriptors is not supported.");
4335             break;
4336         case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
4337             if (!(feats.shaderStorageImageArrayNonUniformIndexing))
4338                 TCU_THROW(NotSupportedError,
4339                           "Non-uniform indexing over storage image descriptor arrays is not supported.");
4340 
4341             if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingStorageImageUpdateAfterBind)
4342                 TCU_THROW(NotSupportedError, "Update after bind for storage image descriptors is not supported.");
4343             break;
4344         default:
4345             DE_FATAL("Unknown Descriptor Type");
4346             break;
4347         }
4348     }
4349 
initAsmPrograms(SourceCollections & programCollection) const4350     void initAsmPrograms(SourceCollections &programCollection) const
4351     {
4352 
4353         std::string (*genShaderSource)(VkShaderStageFlagBits, const TestCaseParams &, bool) =
4354             &CommonDescriptorInstance::getShaderAsm;
4355 
4356         uint32_t vulkan_version        = VK_MAKE_API_VERSION(0, 1, 2, 0);
4357         vk::SpirvVersion spirv_version = vk::SPIRV_VERSION_1_4;
4358         vk::SpirVAsmBuildOptions asm_options(vulkan_version, spirv_version);
4359 
4360         if (VK_SHADER_STAGE_VERTEX_BIT & m_testCaseParams.stageFlags)
4361         {
4362             programCollection.spirvAsmSources.add(
4363                 ut::buildShaderName(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams.descriptorType,
4364                                     m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop,
4365                                     m_testCaseParams.minNonUniform, false),
4366                 &asm_options)
4367                 << (*genShaderSource)(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams, false);
4368 
4369             if (CommonDescriptorInstance::performWritesInVertex(m_testCaseParams.descriptorType))
4370             {
4371                 programCollection.spirvAsmSources.add(
4372                     ut::buildShaderName(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams.descriptorType,
4373                                         m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop,
4374                                         m_testCaseParams.minNonUniform, true),
4375                     &asm_options)
4376                     << (*genShaderSource)(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams, true);
4377             }
4378         }
4379         if (VK_SHADER_STAGE_FRAGMENT_BIT & m_testCaseParams.stageFlags)
4380         {
4381             programCollection.spirvAsmSources.add(
4382                 ut::buildShaderName(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams.descriptorType,
4383                                     m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop,
4384                                     m_testCaseParams.minNonUniform, false),
4385                 &asm_options)
4386                 << (*genShaderSource)(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams, false);
4387 
4388             if (CommonDescriptorInstance::performWritesInVertex(m_testCaseParams.descriptorType))
4389             {
4390                 programCollection.spirvAsmSources.add(
4391                     ut::buildShaderName(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams.descriptorType,
4392                                         m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop,
4393                                         m_testCaseParams.minNonUniform, true),
4394                     &asm_options)
4395                     << (*genShaderSource)(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams, true);
4396             }
4397         }
4398         if (VK_SHADER_STAGE_COMPUTE_BIT & m_testCaseParams.stageFlags)
4399         {
4400             programCollection.spirvAsmSources.add(
4401                 ut::buildShaderName(VK_SHADER_STAGE_COMPUTE_BIT, m_testCaseParams.descriptorType,
4402                                     m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop,
4403                                     m_testCaseParams.minNonUniform, false),
4404                 &asm_options)
4405                 << (*genShaderSource)(VK_SHADER_STAGE_COMPUTE_BIT, m_testCaseParams, false);
4406         }
4407     }
4408 
initPrograms(SourceCollections & programCollection) const4409     virtual void initPrograms(SourceCollections &programCollection) const
4410     {
4411         if (m_testCaseParams.minNonUniform)
4412         {
4413             initAsmPrograms(programCollection);
4414             return;
4415         }
4416 
4417         std::string (*genShaderSource)(VkShaderStageFlagBits, const TestCaseParams &, bool) =
4418             &CommonDescriptorInstance::getShaderSource;
4419 
4420         if (VK_SHADER_STAGE_VERTEX_BIT & m_testCaseParams.stageFlags)
4421         {
4422             programCollection.glslSources.add(ut::buildShaderName(
4423                 VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind,
4424                 m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, false))
4425                 << glu::VertexSource((*genShaderSource)(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams, false));
4426 
4427             if (CommonDescriptorInstance::performWritesInVertex(m_testCaseParams.descriptorType))
4428             {
4429                 programCollection.glslSources.add(ut::buildShaderName(
4430                     VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind,
4431                     m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, true))
4432                     << glu::VertexSource((*genShaderSource)(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams, true));
4433             }
4434         }
4435         if (VK_SHADER_STAGE_FRAGMENT_BIT & m_testCaseParams.stageFlags)
4436         {
4437             programCollection.glslSources.add(ut::buildShaderName(
4438                 VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind,
4439                 m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, false))
4440                 << glu::FragmentSource((*genShaderSource)(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams, false));
4441 
4442             if (CommonDescriptorInstance::performWritesInVertex(m_testCaseParams.descriptorType))
4443             {
4444                 programCollection.glslSources.add(ut::buildShaderName(
4445                     VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind,
4446                     m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, true))
4447                     << glu::FragmentSource((*genShaderSource)(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams, true));
4448             }
4449         }
4450         if (VK_SHADER_STAGE_COMPUTE_BIT & m_testCaseParams.stageFlags)
4451         {
4452             programCollection.glslSources.add(ut::buildShaderName(
4453                 VK_SHADER_STAGE_COMPUTE_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind,
4454                 m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, false))
4455                 << glu::ComputeSource((*genShaderSource)(VK_SHADER_STAGE_COMPUTE_BIT, m_testCaseParams, false));
4456         }
4457     }
4458 };
4459 
4460 } // namespace
4461 
descriptorTypeUsesMipmaps(VkDescriptorType t)4462 static bool descriptorTypeUsesMipmaps(VkDescriptorType t)
4463 {
4464     return t == VK_DESCRIPTOR_TYPE_SAMPLER || t == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ||
4465            t == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
4466 }
4467 
descriptorTypeSupportsUpdateAfterBind(VkDescriptorType t)4468 static bool descriptorTypeSupportsUpdateAfterBind(VkDescriptorType t)
4469 {
4470     switch (t)
4471     {
4472     case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
4473     case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
4474     case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
4475     case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
4476     case VK_DESCRIPTOR_TYPE_SAMPLER:
4477     case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
4478     case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
4479         return true;
4480     default:
4481         return false;
4482     }
4483 }
4484 
descriptorIndexingDescriptorSetsCreateTests(tcu::TestCaseGroup * group)4485 void descriptorIndexingDescriptorSetsCreateTests(tcu::TestCaseGroup *group)
4486 {
4487     struct TestCaseInfo
4488     {
4489         const char *name;
4490         VkDescriptorType descriptorType;
4491     };
4492 
4493     tcu::TestContext &context(group->getTestContext());
4494 
4495     TestCaseInfo casesAfterBindAndLoop[] = {
4496         {
4497             "storage_buffer",
4498             VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
4499         },
4500         {
4501             "storage_texel_buffer",
4502             VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
4503         },
4504         {
4505             "uniform_texel_buffer",
4506             VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
4507         },
4508         {
4509             "storage_image",
4510             VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
4511         },
4512         {
4513             "sampler",
4514             VK_DESCRIPTOR_TYPE_SAMPLER,
4515         },
4516         {
4517             "sampled_image",
4518             VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
4519         },
4520         {
4521             "combined_image_sampler",
4522             VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
4523         },
4524         {
4525             "uniform_buffer",
4526             VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
4527         },
4528         {
4529             "storage_buffer_dynamic",
4530             VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC,
4531         },
4532         {
4533             "uniform_buffer_dynamic",
4534             VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
4535         },
4536         {
4537             "input_attachment",
4538             VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
4539         },
4540     };
4541 
4542     for (int updateAfterBind = 0; updateAfterBind < 2; ++updateAfterBind)
4543     {
4544         for (int calculateInLoop = 0; calculateInLoop < 2; ++calculateInLoop)
4545         {
4546             for (int usesMipMaps = 0; usesMipMaps < 2; ++usesMipMaps)
4547             {
4548                 for (int lifetimeCheck = 0; lifetimeCheck < 2; ++lifetimeCheck)
4549                 {
4550                     for (uint32_t caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(casesAfterBindAndLoop); ++caseIdx)
4551                     {
4552                         TestCaseInfo &info(casesAfterBindAndLoop[caseIdx]);
4553 
4554                         if (updateAfterBind && !descriptorTypeSupportsUpdateAfterBind(info.descriptorType))
4555                             continue;
4556 
4557                         if (usesMipMaps && !descriptorTypeUsesMipmaps(info.descriptorType))
4558                             continue;
4559 
4560                         std::string caseName(info.name);
4561                         TestCaseParams params;
4562 
4563                         caseName += (updateAfterBind ? "_after_bind" : "");
4564                         caseName += (calculateInLoop ? "_in_loop" : "");
4565                         caseName += (usesMipMaps ? "_with_lod" : "");
4566                         caseName += (lifetimeCheck ? "_lifetime" : "");
4567 
4568                         params.descriptorType  = info.descriptorType;
4569                         params.stageFlags      = (info.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ?
4570                                                      VK_SHADER_STAGE_COMPUTE_BIT :
4571                                                      (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
4572                         params.frameResolution = RESOLUTION;
4573                         params.updateAfterBind = updateAfterBind ? true : false;
4574                         params.calculateInLoop = calculateInLoop ? true : false;
4575                         params.usesMipMaps     = usesMipMaps ? true : false;
4576                         params.lifetimeCheck   = lifetimeCheck ? true : false;
4577                         params.minNonUniform   = false;
4578 
4579                         group->addChild(new DescriptorIndexingTestCase(context, caseName.c_str(), params));
4580                     }
4581                 }
4582             }
4583         }
4584     }
4585 
4586     // SPIR-V Asm Tests
4587     // Tests that have the minimum necessary NonUniform decorations.
4588     // sampler and sampled_image GLSL already have minimum NonUniform decorations.
4589 
4590     TestCaseInfo casesMinNonUniform[] = {
4591         {
4592             "storage_buffer",
4593             VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
4594         },
4595         {
4596             "storage_texel_buffer",
4597             VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
4598         },
4599         {
4600             "uniform_texel_buffer",
4601             VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
4602         },
4603         {
4604             "uniform_buffer",
4605             VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
4606         },
4607         {
4608             "combined_image_sampler",
4609             VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
4610         },
4611         {
4612             "storage_image",
4613             VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
4614         },
4615     };
4616 
4617     for (int usesMipMaps = 0; usesMipMaps < 2; ++usesMipMaps)
4618     {
4619         for (uint32_t caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(casesMinNonUniform); ++caseIdx)
4620         {
4621             TestCaseInfo &info(casesMinNonUniform[caseIdx]);
4622 
4623             if (usesMipMaps && !descriptorTypeUsesMipmaps(info.descriptorType))
4624                 continue;
4625 
4626             std::string caseName(info.name);
4627             TestCaseParams params;
4628 
4629             caseName += (usesMipMaps ? "_with_lod" : "");
4630             caseName += "_minNonUniform";
4631 
4632             params.descriptorType  = info.descriptorType;
4633             params.stageFlags      = (info.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ?
4634                                          VK_SHADER_STAGE_COMPUTE_BIT :
4635                                          (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
4636             params.frameResolution = RESOLUTION;
4637             params.updateAfterBind = false;
4638             params.calculateInLoop = false;
4639             params.usesMipMaps     = usesMipMaps ? true : false;
4640             params.minNonUniform   = true;
4641 
4642             TestCase *tc = new DescriptorIndexingTestCase(context, caseName.c_str(), params);
4643             group->addChild(tc);
4644         }
4645     }
4646 }
4647 
4648 } // namespace DescriptorIndexing
4649 } // namespace vkt
4650