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::__anon7412b3740111::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::__anon7412b3740111::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 = {static_cast<VkSampler>(0), static_cast<VkImageView>(0),
1049 VK_IMAGE_LAYOUT_GENERAL};
1050
1051 switch (m_testParams.descriptorType)
1052 {
1053 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1054 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1055 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1056 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1057 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1058 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1059 {
1060 pBufferInfo = &variables.descriptorsBufferInfos[primeIdx];
1061 switch (m_testParams.descriptorType)
1062 {
1063 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1064 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1065 pTexelBufferView = &(**variables.descriptorsBufferViews[primeIdx]);
1066 break;
1067 default:
1068 break;
1069 }
1070 }
1071 break;
1072
1073 case VK_DESCRIPTOR_TYPE_SAMPLER:
1074 imageInfo.sampler = **variables.descriptorSamplers[primeIdx];
1075 pImageInfo = &imageInfo;
1076 break;
1077
1078 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1079 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1080 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1081 imageInfo.imageView = **variables.descriptorImageViews[primeIdx];
1082 pImageInfo = &imageInfo;
1083 break;
1084
1085 default:
1086 break;
1087 }
1088
1089 const VkWriteDescriptorSet writeInfo = {
1090 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
1091 nullptr, // pNext
1092 *variables.descriptorSet, // descriptorSet
1093 BINDING_TestObject, // descriptorBinding;
1094 primes[primeIdx], // elementIndex
1095 1u, // descriptorCount
1096 m_testParams.descriptorType, // descriptorType
1097 pImageInfo, // pImageInfo
1098 pBufferInfo, // pBufferInfo
1099 pTexelBufferView // pTexelBufferView
1100 };
1101
1102 m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, nullptr);
1103 }
1104 }
1105
updateUnusedDescriptors(IterateCommonVariables & variables)1106 void CommonDescriptorInstance::updateUnusedDescriptors(IterateCommonVariables &variables)
1107 {
1108 const std::vector<uint32_t> primes = ut::generatePrimes(variables.availableDescriptorCount);
1109 const uint32_t primeCount = static_cast<uint32_t>(primes.size());
1110 uint32_t primeIndex = 0u;
1111
1112 for (uint32_t i = 0u; i < variables.availableDescriptorCount; ++i)
1113 {
1114 if (primeIndex < primeCount && i == primes[primeIndex])
1115 {
1116 ++primeIndex;
1117 continue;
1118 }
1119
1120 const VkDescriptorBufferInfo *pBufferInfo = DE_NULL;
1121 const VkDescriptorImageInfo *pImageInfo = DE_NULL;
1122 const VkBufferView *pTexelBufferView = DE_NULL;
1123
1124 VkDescriptorImageInfo imageInfo = {static_cast<VkSampler>(0), static_cast<VkImageView>(0),
1125 VK_IMAGE_LAYOUT_GENERAL};
1126
1127 switch (m_testParams.descriptorType)
1128 {
1129 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1130 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1131 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1132 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1133 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1134 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1135 {
1136 pBufferInfo = &variables.unusedDescriptorsBufferInfos[0];
1137 switch (m_testParams.descriptorType)
1138 {
1139 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1140 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1141 pTexelBufferView = &(**variables.unusedDescriptorsBufferViews[0]);
1142 break;
1143 default:
1144 break;
1145 }
1146 }
1147 break;
1148
1149 case VK_DESCRIPTOR_TYPE_SAMPLER:
1150 imageInfo.sampler = **variables.unusedDescriptorSamplers[0];
1151 pImageInfo = &imageInfo;
1152 break;
1153
1154 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1155 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1156 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1157 imageInfo.imageView = **variables.unusedDescriptorImageViews[0];
1158 pImageInfo = &imageInfo;
1159 break;
1160
1161 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1162 imageInfo.sampler = **variables.unusedDescriptorSamplers[0];
1163 imageInfo.imageView = **variables.unusedDescriptorImageViews[0];
1164 pImageInfo = &imageInfo;
1165 break;
1166
1167 default:
1168 break;
1169 }
1170
1171 const VkWriteDescriptorSet writeInfo = {
1172 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
1173 DE_NULL, // pNext
1174 *variables.descriptorSet, // descriptorSet
1175 BINDING_TestObject, // descriptorBinding;
1176 i, // elementIndex
1177 1u, // descriptorCount
1178 m_testParams.descriptorType, // descriptorType
1179 pImageInfo, // pImageInfo
1180 pBufferInfo, // pBufferInfo
1181 pTexelBufferView // pTexelBufferView
1182 };
1183
1184 m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, DE_NULL);
1185 }
1186 }
1187
destroyUnusedResources(IterateCommonVariables & variables)1188 void CommonDescriptorInstance::destroyUnusedResources(IterateCommonVariables &variables)
1189 {
1190 variables.unusedDescriptorsBufferInfos.clear();
1191 variables.unusedDescriptorsBufferViews.clear();
1192 variables.unusedDescriptorImageViews.clear();
1193 variables.unusedDescriptorSamplers.clear();
1194 variables.unusedDescriptorsImages.clear();
1195 }
1196
iterateCommandSetup(IterateCommonVariables & variables)1197 void CommonDescriptorInstance::iterateCommandSetup(IterateCommonVariables &variables)
1198 {
1199 variables.dataAlignment = 0;
1200
1201 variables.renderArea.offset.x = 0;
1202 variables.renderArea.offset.y = 0;
1203 variables.renderArea.extent.width = m_testParams.frameResolution.width;
1204 variables.renderArea.extent.height = m_testParams.frameResolution.height;
1205
1206 variables.vertexCount = m_testParams.frameResolution.width * m_testParams.frameResolution.height;
1207
1208 variables.lowerBound = 0;
1209 variables.upperBound = variables.vertexCount;
1210
1211 variables.descriptorSetLayout =
1212 createDescriptorSetLayout(m_testParams.calculateInLoop, variables.availableDescriptorCount);
1213 variables.validDescriptorCount = ut::computePrimeCount(variables.availableDescriptorCount);
1214 variables.descriptorPool = createDescriptorPool(variables.availableDescriptorCount);
1215 variables.descriptorSet = createDescriptorSet(*variables.descriptorPool, *variables.descriptorSetLayout);
1216
1217 std::vector<VkDescriptorSetLayout> descriptorSetLayouts;
1218 descriptorSetLayouts.push_back(*variables.descriptorSetLayout);
1219 if (m_testParams.calculateInLoop)
1220 {
1221 variables.descriptorEnumerator.init(m_context, variables.vertexCount, variables.availableDescriptorCount);
1222 descriptorSetLayouts.push_back(*variables.descriptorEnumerator.descriptorSetLayout);
1223 }
1224
1225 variables.pipelineLayout = createPipelineLayout(descriptorSetLayouts);
1226
1227 createAndPopulateDescriptors(variables);
1228
1229 variables.renderPass = createRenderPass(variables);
1230 variables.pipeline = createPipeline(*variables.pipelineLayout, *variables.renderPass);
1231
1232 variables.commandBuffer = createCmdBuffer();
1233
1234 if ((m_testParams.stageFlags & VK_SHADER_STAGE_VERTEX_BIT) ||
1235 (m_testParams.stageFlags & VK_SHADER_STAGE_FRAGMENT_BIT))
1236 {
1237 createVertexAttributeBuffer(variables.vertexAttributesBuffer, variables.availableDescriptorCount);
1238 createFramebuffer(variables.frameBuffer, *variables.renderPass, variables);
1239 }
1240
1241 if (m_testParams.calculateInLoop)
1242 {
1243 variables.descriptorEnumerator.update(m_context);
1244 }
1245
1246 if (!m_testParams.updateAfterBind)
1247 {
1248 updateDescriptors(variables);
1249 }
1250 }
1251
iterateCommandBegin(IterateCommonVariables & variables,bool firstPass)1252 void CommonDescriptorInstance::iterateCommandBegin(IterateCommonVariables &variables, bool firstPass)
1253 {
1254 if (m_testParams.lifetimeCheck)
1255 {
1256 createAndPopulateUnusedDescriptors(variables);
1257
1258 if (!m_testParams.updateAfterBind)
1259 updateUnusedDescriptors(variables);
1260 }
1261
1262 vk::beginCommandBuffer(m_vki, *variables.commandBuffer);
1263
1264 // Clear color attachment, and transition it to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
1265 if ((m_testParams.stageFlags & VK_SHADER_STAGE_VERTEX_BIT) ||
1266 (m_testParams.stageFlags & VK_SHADER_STAGE_FRAGMENT_BIT))
1267 {
1268 if (firstPass)
1269 {
1270 const VkImageMemoryBarrier preImageBarrier = {
1271 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
1272 nullptr, // const void* pNext
1273 0u, // VkAccessFlags srcAccessMask
1274 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
1275 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
1276 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout
1277 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
1278 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
1279 *variables.frameBuffer->image->image, // VkImage image
1280 {
1281 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
1282 0u, // uint32_t baseMipLevel
1283 VK_REMAINING_MIP_LEVELS, // uint32_t mipLevels,
1284 0u, // uint32_t baseArray
1285 VK_REMAINING_ARRAY_LAYERS, // uint32_t arraySize
1286 }};
1287
1288 m_vki.cmdPipelineBarrier(*variables.commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
1289 VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0,
1290 (const VkMemoryBarrier *)nullptr, 0, (const VkBufferMemoryBarrier *)nullptr, 1,
1291 &preImageBarrier);
1292
1293 const VkClearColorValue clearColorValue = makeClearValueColor(m_clearColor).color;
1294
1295 m_vki.cmdClearColorImage(*variables.commandBuffer, *variables.frameBuffer->image->image,
1296 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColorValue, 1,
1297 &preImageBarrier.subresourceRange);
1298
1299 const VkImageMemoryBarrier postImageBarrier = {
1300 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
1301 nullptr, // const void* pNext
1302 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
1303 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
1304 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
1305 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout
1306 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout
1307 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
1308 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
1309 *variables.frameBuffer->image->image, // VkImage image
1310 {
1311 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
1312 0u, // uint32_t baseMipLevel
1313 VK_REMAINING_MIP_LEVELS, // uint32_t mipLevels,
1314 0u, // uint32_t baseArray
1315 VK_REMAINING_ARRAY_LAYERS, // uint32_t arraySize
1316 }};
1317
1318 m_vki.cmdPipelineBarrier(*variables.commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
1319 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0, 0,
1320 (const VkMemoryBarrier *)nullptr, 0, (const VkBufferMemoryBarrier *)nullptr, 1,
1321 &postImageBarrier);
1322 }
1323 }
1324
1325 if (m_testParams.calculateInLoop)
1326 {
1327 deRandom rnd;
1328 deRandom_init(&rnd, static_cast<uint32_t>(m_testParams.descriptorType));
1329 const uint32_t quarter = variables.vertexCount / 4;
1330
1331 variables.lowerBound = deRandom_getUint32(&rnd) % quarter;
1332 variables.upperBound = (deRandom_getUint32(&rnd) % quarter) + (3 * quarter);
1333
1334 const push_constant pc = {static_cast<int32_t>(variables.lowerBound),
1335 static_cast<int32_t>(variables.upperBound)};
1336
1337 m_vki.cmdPushConstants(*variables.commandBuffer, *variables.pipelineLayout, m_testParams.stageFlags, 0u,
1338 static_cast<uint32_t>(sizeof(pc)), &pc);
1339 }
1340
1341 if ((m_testParams.stageFlags & VK_SHADER_STAGE_VERTEX_BIT) ||
1342 (m_testParams.stageFlags & VK_SHADER_STAGE_FRAGMENT_BIT))
1343 {
1344 commandBindVertexAttributes(*variables.commandBuffer, variables.vertexAttributesBuffer);
1345 }
1346
1347 if (m_testParams.calculateInLoop)
1348 {
1349 commandBindDescriptorSets(*variables.commandBuffer, *variables.pipelineLayout,
1350 *variables.descriptorEnumerator.descriptorSet, 1);
1351 }
1352
1353 if (!ut::isDynamicDescriptor(m_testParams.descriptorType))
1354 {
1355 commandBindDescriptorSets(*variables.commandBuffer, *variables.pipelineLayout, *variables.descriptorSet, 0);
1356 }
1357
1358 commandBindPipeline(*variables.commandBuffer, *variables.pipeline);
1359 }
1360
iterate(void)1361 tcu::TestStatus CommonDescriptorInstance::iterate(void)
1362 {
1363 IterateCommonVariables v;
1364 ut::UpdatablePixelBufferAccessPtr programResult;
1365 ut::UpdatablePixelBufferAccessPtr referenceResult;
1366
1367 bool firstPass = true;
1368
1369 iterateCommandSetup(v);
1370
1371 v.renderArea.extent.width = m_testParams.frameResolution.width / 4;
1372 v.renderArea.extent.height = m_testParams.frameResolution.height / 4;
1373
1374 for (int x = 0; x < 4; x++)
1375 for (int y = 0; y < 4; y++)
1376 {
1377 iterateCommandBegin(v, firstPass);
1378
1379 if (true == firstPass && true == m_testParams.copyBuffersToImages)
1380 {
1381 copyBuffersToImages(v);
1382 }
1383
1384 firstPass = false;
1385
1386 if (true == m_testParams.updateAfterBind)
1387 {
1388 updateDescriptors(v);
1389 }
1390
1391 v.renderArea.offset.x = x * m_testParams.frameResolution.width / 4;
1392 v.renderArea.offset.y = y * m_testParams.frameResolution.height / 4;
1393
1394 vk::VkRect2D scissor = makeRect2D(v.renderArea.offset.x, v.renderArea.offset.y, v.renderArea.extent.width,
1395 v.renderArea.extent.height);
1396 m_vki.cmdSetScissor(*v.commandBuffer, 0u, 1u, &scissor);
1397
1398 vk::beginRenderPass(m_vki, *v.commandBuffer, *v.renderPass, *v.frameBuffer->buffer, v.renderArea,
1399 m_clearColor);
1400 m_vki.cmdDraw(*v.commandBuffer, v.vertexCount, 1u, 0u, 0u);
1401 vk::endRenderPass(m_vki, *v.commandBuffer);
1402
1403 iterateCommandEnd(v, programResult, referenceResult);
1404 programResult->invalidate();
1405 }
1406
1407 if (iterateVerifyResults(v, programResult, referenceResult))
1408 return tcu::TestStatus::pass("Pass");
1409 return tcu::TestStatus::fail("Failed -- check log for details");
1410 }
1411
createColorScheme(void)1412 std::vector<float> CommonDescriptorInstance::createColorScheme(void)
1413 {
1414 std::vector<float> cs;
1415 int divider = 2;
1416 for (int i = 0; i < 10; ++i)
1417 {
1418 cs.push_back(1.0f / float(divider));
1419 divider *= 2;
1420 }
1421 return cs;
1422 }
1423
iterateCommandEnd(IterateCommonVariables & variables,ut::UpdatablePixelBufferAccessPtr & programResult,ut::UpdatablePixelBufferAccessPtr & referenceResult,bool collectBeforeSubmit)1424 void CommonDescriptorInstance::iterateCommandEnd(IterateCommonVariables &variables,
1425 ut::UpdatablePixelBufferAccessPtr &programResult,
1426 ut::UpdatablePixelBufferAccessPtr &referenceResult,
1427 bool collectBeforeSubmit)
1428 {
1429 // Destroy unused descriptor resources to test there's no issues as allowed by the spec
1430 if (m_testParams.lifetimeCheck)
1431 destroyUnusedResources(variables);
1432
1433 if (collectBeforeSubmit)
1434 {
1435 iterateCollectResults(programResult, variables, true);
1436 iterateCollectResults(referenceResult, variables, false);
1437 }
1438
1439 VK_CHECK(m_vki.endCommandBuffer(*variables.commandBuffer));
1440 Move<VkFence> fence = commandSubmit(*variables.commandBuffer);
1441 m_vki.waitForFences(m_vkd, 1, &(*fence), true, ~0ull);
1442
1443 if (false == collectBeforeSubmit)
1444 {
1445 iterateCollectResults(programResult, variables, true);
1446 iterateCollectResults(referenceResult, variables, false);
1447 }
1448 m_context.resetCommandPoolForVKSC(m_vkd, *m_commandPool);
1449 }
1450
iterateVerifyResults(IterateCommonVariables & variables,ut::UpdatablePixelBufferAccessPtr programResult,ut::UpdatablePixelBufferAccessPtr referenceResult)1451 bool CommonDescriptorInstance::iterateVerifyResults(IterateCommonVariables &variables,
1452 ut::UpdatablePixelBufferAccessPtr programResult,
1453 ut::UpdatablePixelBufferAccessPtr referenceResult)
1454 {
1455 bool result = false;
1456 if (FUZZY_COMPARE)
1457 {
1458 result = tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Fuzzy Compare", "Comparison result",
1459 *referenceResult.get(), *programResult.get(), 0.02f, tcu::COMPARE_LOG_EVERYTHING);
1460 }
1461 else
1462 {
1463 result = tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Float Threshold Compare",
1464 "Comparison result", *referenceResult.get(), *programResult.get(),
1465 tcu::Vec4(0.02f, 0.02f, 0.02f, 0.02f), tcu::COMPARE_LOG_EVERYTHING);
1466 }
1467
1468 if (m_testParams.allowVertexStoring)
1469 {
1470 result = (verifyVertexWriteResults(variables) && result);
1471 }
1472
1473 return result;
1474 }
1475
iterateCollectResults(ut::UpdatablePixelBufferAccessPtr & result,const IterateCommonVariables & variables,bool fromTest)1476 void CommonDescriptorInstance::iterateCollectResults(ut::UpdatablePixelBufferAccessPtr &result,
1477 const IterateCommonVariables &variables, bool fromTest)
1478 {
1479 if (fromTest)
1480 {
1481 result = commandReadFrameBuffer(*variables.commandBuffer, variables.frameBuffer);
1482 }
1483 else
1484 {
1485 result = ut::UpdatablePixelBufferAccessPtr(
1486 new ut::PixelBufferAccessAllocation(vk::mapVkFormat(m_colorFormat), m_testParams.frameResolution));
1487
1488 for (uint32_t y = 0, pixelNum = 0; y < m_testParams.frameResolution.height; ++y)
1489 {
1490 for (uint32_t x = 0; x < m_testParams.frameResolution.width; ++x, ++pixelNum)
1491 {
1492 const float component = m_colorScheme[(pixelNum % variables.validDescriptorCount) % m_schemeSize];
1493 result->setPixel(tcu::Vec4(component, component, component, 1.0f), x, y);
1494 }
1495 }
1496 }
1497 }
1498
createCmdBuffer(void)1499 Move<VkCommandBuffer> CommonDescriptorInstance::createCmdBuffer(void)
1500 {
1501 return vk::allocateCommandBuffer(m_vki, m_vkd, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1502 }
1503
commandSubmit(VkCommandBuffer cmd)1504 Move<VkFence> CommonDescriptorInstance::commandSubmit(VkCommandBuffer cmd)
1505 {
1506 Move<VkFence> fence(vk::createFence(m_vki, m_vkd));
1507
1508 const VkSubmitInfo submitInfo = {
1509 VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType
1510 nullptr, // pNext
1511 0u, // waitSemaphoreCount
1512 static_cast<VkSemaphore *>(nullptr), // pWaitSemaphores
1513 static_cast<const VkPipelineStageFlags *>(nullptr), // pWaitDstStageMask
1514 1u, // commandBufferCount
1515 &cmd, // pCommandBuffers
1516 0u, // signalSemaphoreCount
1517 static_cast<VkSemaphore *>(nullptr) // pSignalSemaphores
1518 };
1519
1520 VK_CHECK(m_vki.queueSubmit(m_queue, 1u, &submitInfo, *fence));
1521
1522 return fence;
1523 }
1524
verifyVertexWriteResults(IterateCommonVariables & variables)1525 bool CommonDescriptorInstance::verifyVertexWriteResults(IterateCommonVariables &variables)
1526 {
1527 DE_UNREF(variables);
1528 return true;
1529 }
1530
commandBindPipeline(VkCommandBuffer commandBuffer,VkPipeline pipeline)1531 void CommonDescriptorInstance::commandBindPipeline(VkCommandBuffer commandBuffer, VkPipeline pipeline)
1532 {
1533 const VkPipelineBindPoint pipelineBindingPoint = (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT) ?
1534 VK_PIPELINE_BIND_POINT_COMPUTE :
1535 VK_PIPELINE_BIND_POINT_GRAPHICS;
1536 m_vki.cmdBindPipeline(commandBuffer, pipelineBindingPoint, pipeline);
1537 }
1538
commandBindVertexAttributes(VkCommandBuffer commandBuffer,const ut::BufferHandleAllocSp & vertexAttributesBuffer)1539 void CommonDescriptorInstance::commandBindVertexAttributes(VkCommandBuffer commandBuffer,
1540 const ut::BufferHandleAllocSp &vertexAttributesBuffer)
1541 {
1542 const VkDeviceSize offsets[] = {0u};
1543 const VkBuffer buffers[] = {*vertexAttributesBuffer->buffer};
1544 m_vki.cmdBindVertexBuffers(commandBuffer, 0u, 1u, buffers, offsets);
1545 }
1546
commandBindDescriptorSets(VkCommandBuffer commandBuffer,VkPipelineLayout pipelineLayout,VkDescriptorSet descriptorSet,uint32_t descriptorSetIndex)1547 void CommonDescriptorInstance::commandBindDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineLayout pipelineLayout,
1548 VkDescriptorSet descriptorSet, uint32_t descriptorSetIndex)
1549 {
1550 const VkPipelineBindPoint pipelineBindingPoint = (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT) ?
1551 VK_PIPELINE_BIND_POINT_COMPUTE :
1552 VK_PIPELINE_BIND_POINT_GRAPHICS;
1553 m_vki.cmdBindDescriptorSets(commandBuffer, pipelineBindingPoint, pipelineLayout, descriptorSetIndex, 1u,
1554 &descriptorSet, 0u, static_cast<uint32_t *>(nullptr));
1555 }
1556
commandReadFrameBuffer(VkCommandBuffer commandBuffer,const ut::FrameBufferSp & frameBuffer)1557 ut::UpdatablePixelBufferAccessPtr CommonDescriptorInstance::commandReadFrameBuffer(VkCommandBuffer commandBuffer,
1558 const ut::FrameBufferSp &frameBuffer)
1559 {
1560 ut::BufferHandleAllocSp frameBufferContent;
1561 commandReadFrameBuffer(frameBufferContent, commandBuffer, frameBuffer);
1562 return ut::UpdatablePixelBufferAccessPtr(new ut::PixelBufferAccessBuffer(
1563 m_vkd, m_vki, vk::mapVkFormat(m_colorFormat), m_testParams.frameResolution,
1564 de::SharedPtr<Move<VkBuffer>>(new Move<VkBuffer>(frameBufferContent->buffer)),
1565 de::SharedPtr<de::MovePtr<Allocation>>(new de::MovePtr<Allocation>(frameBufferContent->alloc))));
1566 }
1567
commandReadFrameBuffer(ut::BufferHandleAllocSp & content,VkCommandBuffer commandBuffer,const ut::FrameBufferSp & frameBuffer)1568 void CommonDescriptorInstance::commandReadFrameBuffer(ut::BufferHandleAllocSp &content, VkCommandBuffer commandBuffer,
1569 const ut::FrameBufferSp &frameBuffer)
1570 {
1571 Move<VkBuffer> buffer;
1572 de::MovePtr<Allocation> allocation;
1573
1574 const VkDeviceSize bufferSize = ut::computeImageSize(frameBuffer->image);
1575
1576 // create a buffer and an host allocation for it
1577 {
1578 const VkBufferCreateInfo bufferCreateInfo = {
1579 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType
1580 nullptr, // pNext
1581 0u, // flags
1582 bufferSize, // size
1583 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // usage
1584 VK_SHARING_MODE_EXCLUSIVE, // sharingMode
1585 1u, // queueFamilyIndexCoun
1586 &m_queueFamilyIndex // pQueueFamilyIndices
1587 };
1588
1589 buffer = vk::createBuffer(m_vki, m_vkd, &bufferCreateInfo);
1590 const VkMemoryRequirements memRequirements(vk::getBufferMemoryRequirements(m_vki, m_vkd, *buffer));
1591 allocation = m_allocator.allocate(memRequirements, MemoryRequirement::HostVisible);
1592
1593 VK_CHECK(m_vki.bindBufferMemory(m_vkd, *buffer, allocation->getMemory(), allocation->getOffset()));
1594 }
1595
1596 const VkImage &image = *frameBuffer->image->image;
1597
1598 VkImageSubresourceRange subresourceRange = {
1599 VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
1600 0u, // baseMipLevel
1601 1u, // levelCount
1602 0u, // baseArrayLayer
1603 1u // layerCount
1604 };
1605
1606 const VkImageMemoryBarrier barrierBefore = {
1607 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
1608 nullptr, // pNext;
1609 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // srcAccessMask;
1610 VK_ACCESS_TRANSFER_READ_BIT, // dstAccessMask;
1611 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // oldLayout
1612 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // newLayout;
1613 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex;
1614 VK_QUEUE_FAMILY_IGNORED, // dstQueueFamilyIndex;
1615 image, // image;
1616 subresourceRange // subresourceRange;
1617 };
1618
1619 const VkBufferImageCopy copyRegion = {
1620 0u, // bufferOffset
1621 frameBuffer->image->extent.width, // bufferRowLength
1622 frameBuffer->image->extent.height, // bufferImageHeight
1623 {
1624 // VkImageSubresourceLayers
1625 VK_IMAGE_ASPECT_COLOR_BIT, // aspect
1626 0u, // mipLevel
1627 0u, // baseArrayLayer
1628 1u, // layerCount
1629 },
1630 {0, 0, 0}, // imageOffset
1631 frameBuffer->image->extent // imageExtent
1632 };
1633
1634 const VkBufferMemoryBarrier bufferBarrier = {
1635 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // sType;
1636 nullptr, // pNext;
1637 VK_ACCESS_TRANSFER_WRITE_BIT, // srcAccessMask;
1638 VK_ACCESS_HOST_READ_BIT, // dstAccessMask;
1639 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex;
1640 VK_QUEUE_FAMILY_IGNORED, // dstQueueFamilyIndex;
1641 *buffer, // buffer;
1642 0u, // offset;
1643 bufferSize // size;
1644 };
1645
1646 const VkImageMemoryBarrier barrierAfter = {
1647 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
1648 nullptr, // pNext;
1649 VK_ACCESS_TRANSFER_READ_BIT, // srcAccessMask;
1650 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // dstAccessMask;
1651 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // oldLayout;
1652 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // newLayout;
1653 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex;
1654 VK_QUEUE_FAMILY_IGNORED, // dstQueueFamilyIndex;
1655 image, // image
1656 subresourceRange // subresourceRange
1657 };
1658
1659 m_vki.cmdPipelineBarrier(commandBuffer, // commandBuffer
1660 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1661 VK_PIPELINE_STAGE_TRANSFER_BIT, // srcStageMask, dstStageMask
1662 (VkDependencyFlags)0, // dependencyFlags
1663 0u, nullptr, // memoryBarrierCount, pMemoryBarriers
1664 0u, nullptr, // bufferBarrierCount, pBufferBarriers
1665 1u, &barrierBefore); // imageBarrierCount, pImageBarriers
1666
1667 m_vki.cmdCopyImageToBuffer(commandBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, ©Region);
1668
1669 m_vki.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
1670 VK_PIPELINE_STAGE_HOST_BIT | VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (VkDependencyFlags)0, 0u,
1671 nullptr, 1u, &bufferBarrier, 1u, &barrierAfter);
1672
1673 content = ut::BufferHandleAllocSp(new ut::BufferHandleAlloc(buffer, allocation));
1674 }
1675
getColorAccess(VkDescriptorType descriptorType,const char * indexVariableName,bool usesMipMaps)1676 std::string CommonDescriptorInstance::getColorAccess(VkDescriptorType descriptorType, const char *indexVariableName,
1677 bool usesMipMaps)
1678 {
1679 std::string text;
1680 std::map<std::string, std::string> vars;
1681 vars["INDEX"] = indexVariableName;
1682
1683 switch (descriptorType)
1684 {
1685 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1686 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1687 text = "data[nonuniformEXT(${INDEX})].c";
1688 break;
1689 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1690 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1691 text = "data[nonuniformEXT(${INDEX})].cold";
1692 break;
1693 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1694 text = "subpassLoad(data[nonuniformEXT(${INDEX})]).rgba";
1695 break;
1696 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1697 text = "texelFetch(data[nonuniformEXT(${INDEX})], 0)";
1698 break;
1699 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1700 text = "imageLoad(data[nonuniformEXT(${INDEX})], 0)";
1701 break;
1702 case VK_DESCRIPTOR_TYPE_SAMPLER:
1703 text = usesMipMaps ? "textureLod(nonuniformEXT(sampler2D(tex, data[${INDEX}])), normalpos, 1)" :
1704 "texture( nonuniformEXT(sampler2D(tex, data[${INDEX}])), normalpos )";
1705 break;
1706 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1707 text = usesMipMaps ? "textureLod( nonuniformEXT(sampler2D(data[${INDEX}], samp)), vec2(0,0), "
1708 "textureQueryLevels(nonuniformEXT(sampler2D(data[${INDEX}], samp)))-1)" :
1709 "texture( nonuniformEXT(sampler2D(data[${INDEX}], samp)), vec2(0,0) )";
1710 break;
1711 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1712 text = usesMipMaps ? "textureLod( data[nonuniformEXT(${INDEX})], uvec2(0,0), "
1713 "textureQueryLevels(data[nonuniformEXT(${INDEX})])-1)" :
1714 "texture( data[nonuniformEXT(${INDEX})], uvec2(0,0) )";
1715 break;
1716 default:
1717 TCU_THROW(InternalError, "Not implemented descriptor type");
1718 }
1719
1720 return tcu::StringTemplate(text).specialize(vars);
1721 }
1722
getFragmentReturnSource(const std::string & colorAccess)1723 std::string CommonDescriptorInstance::getFragmentReturnSource(const std::string &colorAccess)
1724 {
1725 return " FragColor = " + colorAccess + ";\n";
1726 }
1727
getFragmentLoopSource(const std::string & colorAccess1,const std::string & colorAccess2)1728 std::string CommonDescriptorInstance::getFragmentLoopSource(const std::string &colorAccess1,
1729 const std::string &colorAccess2)
1730 {
1731 std::map<std::string, std::string> vars;
1732 vars["COLOR_ACCESS_1"] = colorAccess1;
1733 vars["COLOR_ACCESS_2"] = colorAccess2;
1734
1735 const char *s = " vec4 sumClr1 = vec4(0,0,0,0); \n"
1736 " vec4 sumClr2 = vec4(0,0,0,0); \n"
1737 " for (int i = pc.lowerBound; i < pc.upperBound; ++i) \n"
1738 " {\n"
1739 " int loopIdx = texelFetch(iter, i).x; \n"
1740 " sumClr1 += ${COLOR_ACCESS_2} + ${COLOR_ACCESS_1}; \n"
1741 " sumClr2 += ${COLOR_ACCESS_2}; \n"
1742 " }\n"
1743 " FragColor = vec4(((sumClr1 - sumClr2) / float(pc.upperBound - pc.lowerBound)).rgb, 1); \n";
1744
1745 return tcu::StringTemplate(s).specialize(vars);
1746 }
1747
performWritesInVertex(VkDescriptorType descriptorType)1748 bool CommonDescriptorInstance::performWritesInVertex(VkDescriptorType descriptorType)
1749 {
1750 switch (descriptorType)
1751 {
1752 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1753 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1754 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1755 return true;
1756 default:
1757 return false;
1758 }
1759 }
1760
performWritesInVertex(VkDescriptorType descriptorType,const Context & context)1761 bool CommonDescriptorInstance::performWritesInVertex(VkDescriptorType descriptorType, const Context &context)
1762 {
1763 ut::DeviceProperties dp(context);
1764 const VkPhysicalDeviceFeatures &feats = dp.physicalDeviceFeatures();
1765 return feats.vertexPipelineStoresAndAtomics && CommonDescriptorInstance::performWritesInVertex(descriptorType);
1766 }
1767
getShaderAsm(VkShaderStageFlagBits shaderType,const TestCaseParams & testCaseParams,bool allowVertexStoring)1768 std::string CommonDescriptorInstance::getShaderAsm(VkShaderStageFlagBits shaderType,
1769 const TestCaseParams &testCaseParams, bool allowVertexStoring)
1770 {
1771 std::stringstream s;
1772 switch (shaderType)
1773 {
1774 case VK_SHADER_STAGE_VERTEX_BIT:
1775 switch (testCaseParams.descriptorType)
1776 {
1777 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1778 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1779 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1780 s << " OpCapability Shader\n";
1781 s << " OpCapability SampledBuffer\n";
1782 s << " %1 = OpExtInstImport \"GLSL.std.450\"\n";
1783 s << " OpMemoryModel Logical GLSL450\n";
1784 s << " OpEntryPoint Vertex %main \"main\" %_ %position %in_position %normalpos %in_normalpos "
1785 "%vIndex %gl_VertexIndex %rIndex %index %gIndex %bIndex %aIndex\n";
1786 s << " OpSource GLSL 450\n";
1787 s << " OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
1788 s << " OpSourceExtension \"GL_EXT_texture_buffer\"\n";
1789 s << " OpName %main \"main\"\n";
1790 s << " OpName %gl_PerVertex \"gl_PerVertex\"\n";
1791 s << " OpMemberName %gl_PerVertex 0 \"gl_Position\"\n";
1792 s << " OpMemberName %gl_PerVertex 1 \"gl_PointSize\"\n";
1793 s << " OpMemberName %gl_PerVertex 2 \"gl_ClipDistance\"\n";
1794 s << " OpMemberName %gl_PerVertex 3 \"gl_CullDistance\"\n";
1795 s << " OpName %_ \"\"\n";
1796 s << " OpName %position \"position\"\n";
1797 s << " OpName %in_position \"in_position\"\n";
1798 s << " OpName %normalpos \"normalpos\"\n";
1799 s << " OpName %in_normalpos \"in_normalpos\"\n";
1800 s << " OpName %vIndex \"vIndex\"\n";
1801 s << " OpName %gl_VertexIndex \"gl_VertexIndex\"\n";
1802 s << " OpName %rIndex \"rIndex\"\n";
1803 s << " OpName %index \"index\"\n";
1804 s << " OpName %gIndex \"gIndex\"\n";
1805 s << " OpName %bIndex \"bIndex\"\n";
1806 s << " OpName %aIndex \"aIndex\"\n";
1807 s << " OpMemberDecorate %gl_PerVertex 0 BuiltIn Position\n";
1808 s << " OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize\n";
1809 s << " OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance\n";
1810 s << " OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance\n";
1811 s << " OpDecorate %gl_PerVertex Block\n";
1812 s << " OpDecorate %position Location 0\n";
1813 s << " OpDecorate %in_position Location 0\n";
1814 s << " OpDecorate %normalpos Location 1\n";
1815 s << " OpDecorate %in_normalpos Location 1\n";
1816 s << " OpDecorate %vIndex Location 2\n";
1817 s << " OpDecorate %gl_VertexIndex BuiltIn VertexIndex\n";
1818 s << " OpDecorate %rIndex Location 3\n";
1819 s << " OpDecorate %index Location 2\n";
1820 s << " OpDecorate %gIndex Location 4\n";
1821 s << " OpDecorate %bIndex Location 5\n";
1822 s << " OpDecorate %aIndex Location 6\n";
1823 s << " %void = OpTypeVoid\n";
1824 s << " %3 = OpTypeFunction %void\n";
1825 s << " %float = OpTypeFloat 32\n";
1826 s << " %v4float = OpTypeVector %float 4\n";
1827 s << " %uint = OpTypeInt 32 0\n";
1828 s << " %uint_1 = OpConstant %uint 1\n";
1829 s << "%_arr_float_uint_1 = OpTypeArray %float %uint_1\n";
1830 s << "%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1\n";
1831 s << "%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex\n";
1832 s << " %_ = OpVariable %_ptr_Output_gl_PerVertex Output\n";
1833 s << " %int = OpTypeInt 32 1\n";
1834 s << " %int_1 = OpConstant %int 1\n";
1835 s << "%float_0_200000003 = OpConstant %float 0.200000003\n";
1836 s << "%_ptr_Output_float = OpTypePointer Output %float\n";
1837 s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
1838 s << " %position = OpVariable %_ptr_Output_v4float Output\n";
1839 s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
1840 s << "%in_position = OpVariable %_ptr_Input_v4float Input\n";
1841 s << " %v2float = OpTypeVector %float 2\n";
1842 s << "%_ptr_Output_v2float = OpTypePointer Output %v2float\n";
1843 s << " %normalpos = OpVariable %_ptr_Output_v2float Output\n";
1844 s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
1845 s << "%in_normalpos = OpVariable %_ptr_Input_v2float Input\n";
1846 s << " %int_0 = OpConstant %int 0\n";
1847 s << "%_ptr_Output_int = OpTypePointer Output %int\n";
1848 s << " %vIndex = OpVariable %_ptr_Output_int Output\n";
1849 s << "%_ptr_Input_int = OpTypePointer Input %int\n";
1850 s << "%gl_VertexIndex = OpVariable %_ptr_Input_int Input\n";
1851 s << " %rIndex = OpVariable %_ptr_Output_int Output\n";
1852 s << " %v4int = OpTypeVector %int 4\n";
1853 s << "%_ptr_Input_v4int = OpTypePointer Input %v4int\n";
1854 s << " %index = OpVariable %_ptr_Input_v4int Input\n";
1855 s << " %uint_0 = OpConstant %uint 0\n";
1856 s << " %gIndex = OpVariable %_ptr_Output_int Output\n";
1857 s << " %bIndex = OpVariable %_ptr_Output_int Output\n";
1858 s << " %uint_2 = OpConstant %uint 2\n";
1859 s << " %aIndex = OpVariable %_ptr_Output_int Output\n";
1860 s << " %uint_3 = OpConstant %uint 3\n";
1861 s << " %main = OpFunction %void None %3\n";
1862 s << " %5 = OpLabel\n";
1863 s << " %18 = OpAccessChain %_ptr_Output_float %_ %int_1\n";
1864 s << " OpStore %18 %float_0_200000003\n";
1865 s << " %23 = OpLoad %v4float %in_position\n";
1866 s << " OpStore %position %23\n";
1867 s << " %29 = OpLoad %v2float %in_normalpos\n";
1868 s << " OpStore %normalpos %29\n";
1869 s << " %31 = OpLoad %v4float %position\n";
1870 s << " %32 = OpAccessChain %_ptr_Output_v4float %_ %int_0\n";
1871 s << " OpStore %32 %31\n";
1872 s << " %37 = OpLoad %int %gl_VertexIndex\n";
1873 s << " OpStore %vIndex %37\n";
1874 s << " %43 = OpAccessChain %_ptr_Input_int %index %uint_0\n";
1875 s << " %44 = OpLoad %int %43\n";
1876 s << " OpStore %rIndex %44\n";
1877 s << " %46 = OpAccessChain %_ptr_Input_int %index %uint_1\n";
1878 s << " %47 = OpLoad %int %46\n";
1879 s << " OpStore %gIndex %47\n";
1880 s << " %50 = OpAccessChain %_ptr_Input_int %index %uint_2\n";
1881 s << " %51 = OpLoad %int %50\n";
1882 s << " OpStore %bIndex %51\n";
1883 s << " %54 = OpAccessChain %_ptr_Input_int %index %uint_3\n";
1884 s << " %55 = OpLoad %int %54\n";
1885 s << " OpStore %aIndex %55\n";
1886 s << " OpReturn\n";
1887 s << " OpFunctionEnd\n";
1888 break;
1889 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1890 s << " OpCapability Shader\n";
1891 s << " OpCapability ImageBuffer\n";
1892 if (allowVertexStoring)
1893 {
1894 s << " OpCapability ShaderNonUniform\n";
1895 s << " OpCapability RuntimeDescriptorArray\n";
1896 s << " OpCapability StorageTexelBufferArrayNonUniformIndexing\n";
1897 s << " OpExtension \"SPV_EXT_descriptor_indexing\"\n";
1898 }
1899 s << " %1 = OpExtInstImport \"GLSL.std.450\"\n";
1900 s << " OpMemoryModel Logical GLSL450\n";
1901 s << " OpEntryPoint Vertex %main \"main\" %_ %position %in_position %normalpos %in_normalpos "
1902 "%vIndex %gl_VertexIndex %rIndex %index %gIndex %bIndex %aIndex %data\n";
1903 s << " OpSource GLSL 450\n";
1904 s << " OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
1905 s << " OpName %main \"main\"\n";
1906 s << " OpName %gl_PerVertex \"gl_PerVertex\"\n";
1907 s << " OpMemberName %gl_PerVertex 0 \"gl_Position\"\n";
1908 s << " OpMemberName %gl_PerVertex 1 \"gl_PointSize\"\n";
1909 s << " OpMemberName %gl_PerVertex 2 \"gl_ClipDistance\"\n";
1910 s << " OpMemberName %gl_PerVertex 3 \"gl_CullDistance\"\n";
1911 s << " OpName %_ \"\"\n";
1912 s << " OpName %position \"position\"\n";
1913 s << " OpName %in_position \"in_position\"\n";
1914 s << " OpName %normalpos \"normalpos\"\n";
1915 s << " OpName %in_normalpos \"in_normalpos\"\n";
1916 s << " OpName %vIndex \"vIndex\"\n";
1917 s << " OpName %gl_VertexIndex \"gl_VertexIndex\"\n";
1918 s << " OpName %rIndex \"rIndex\"\n";
1919 s << " OpName %index \"index\"\n";
1920 s << " OpName %gIndex \"gIndex\"\n";
1921 s << " OpName %bIndex \"bIndex\"\n";
1922 s << " OpName %aIndex \"aIndex\"\n";
1923 s << " OpName %data \"data\"\n";
1924 s << " OpMemberDecorate %gl_PerVertex 0 BuiltIn Position\n";
1925 s << " OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize\n";
1926 s << " OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance\n";
1927 s << " OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance\n";
1928 s << " OpDecorate %gl_PerVertex Block\n";
1929 s << " OpDecorate %position Location 0\n";
1930 s << " OpDecorate %in_position Location 0\n";
1931 s << " OpDecorate %normalpos Location 1\n";
1932 s << " OpDecorate %in_normalpos Location 1\n";
1933 s << " OpDecorate %vIndex Location 2\n";
1934 s << " OpDecorate %gl_VertexIndex BuiltIn VertexIndex\n";
1935 s << " OpDecorate %rIndex Location 3\n";
1936 s << " OpDecorate %index Location 2\n";
1937 s << " OpDecorate %gIndex Location 4\n";
1938 s << " OpDecorate %bIndex Location 5\n";
1939 s << " OpDecorate %aIndex Location 6\n";
1940 s << " OpDecorate %data DescriptorSet 0\n";
1941 s << " OpDecorate %data Binding " << BINDING_TestObject << "\n";
1942 if (allowVertexStoring)
1943 {
1944 // s << " OpDecorate %66 NonUniform\n";
1945 // s << " OpDecorate %68 NonUniform\n";
1946 s << " OpDecorate %69 NonUniform\n";
1947 // s << " OpDecorate %71 NonUniform\n";
1948 // s << " OpDecorate %72 NonUniform\n";
1949 s << " OpDecorate %73 NonUniform\n";
1950 }
1951 s << " %void = OpTypeVoid\n";
1952 s << " %3 = OpTypeFunction %void\n";
1953 s << " %float = OpTypeFloat 32\n";
1954 s << " %v4float = OpTypeVector %float 4\n";
1955 s << " %uint = OpTypeInt 32 0\n";
1956 s << " %uint_1 = OpConstant %uint 1\n";
1957 s << "%_arr_float_uint_1 = OpTypeArray %float %uint_1\n";
1958 s << "%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1\n";
1959 s << "%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex\n";
1960 s << " %_ = OpVariable %_ptr_Output_gl_PerVertex Output\n";
1961 s << " %int = OpTypeInt 32 1\n";
1962 s << " %int_1 = OpConstant %int 1\n";
1963 s << "%float_0_200000003 = OpConstant %float 0.200000003\n";
1964 s << "%_ptr_Output_float = OpTypePointer Output %float\n";
1965 s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
1966 s << " %position = OpVariable %_ptr_Output_v4float Output\n";
1967 s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
1968 s << "%in_position = OpVariable %_ptr_Input_v4float Input\n";
1969 s << " %v2float = OpTypeVector %float 2\n";
1970 s << "%_ptr_Output_v2float = OpTypePointer Output %v2float\n";
1971 s << " %normalpos = OpVariable %_ptr_Output_v2float Output\n";
1972 s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
1973 s << "%in_normalpos = OpVariable %_ptr_Input_v2float Input\n";
1974 s << " %int_0 = OpConstant %int 0\n";
1975 s << "%_ptr_Output_int = OpTypePointer Output %int\n";
1976 s << " %vIndex = OpVariable %_ptr_Output_int Output\n";
1977 s << "%_ptr_Input_int = OpTypePointer Input %int\n";
1978 s << "%gl_VertexIndex = OpVariable %_ptr_Input_int Input\n";
1979 s << " %rIndex = OpVariable %_ptr_Output_int Output\n";
1980 s << " %v4int = OpTypeVector %int 4\n";
1981 s << "%_ptr_Input_v4int = OpTypePointer Input %v4int\n";
1982 s << " %index = OpVariable %_ptr_Input_v4int Input\n";
1983 s << " %uint_0 = OpConstant %uint 0\n";
1984 s << " %gIndex = OpVariable %_ptr_Output_int Output\n";
1985 s << " %bIndex = OpVariable %_ptr_Output_int Output\n";
1986 s << " %uint_2 = OpConstant %uint 2\n";
1987 s << " %aIndex = OpVariable %_ptr_Output_int Output\n";
1988 s << " %uint_3 = OpConstant %uint 3\n";
1989 if (allowVertexStoring)
1990 {
1991 s << " %bool = OpTypeBool\n";
1992 s << " %61 = OpTypeImage %float Buffer 0 0 0 2 Rgba32f\n";
1993 s << " %_runtimearr_61 = OpTypeRuntimeArray %61\n";
1994 s << " %_ptr_UniformConstant__runtimearr_61 = OpTypePointer UniformConstant %_runtimearr_61\n";
1995 s << " %data = OpVariable %_ptr_UniformConstant__runtimearr_61 UniformConstant\n";
1996 s << " %_ptr_UniformConstant_61 = OpTypePointer UniformConstant %61\n";
1997 }
1998 else
1999 {
2000 s << " %56 = OpTypeImage %float Buffer 0 0 0 2 Rgba32f\n";
2001 s << "%_arr_56_uint_1 = OpTypeArray %56 %uint_1\n";
2002 s << "%_ptr_UniformConstant__arr_56_uint_1 = OpTypePointer UniformConstant %_arr_56_uint_1\n";
2003 s << " %data = OpVariable %_ptr_UniformConstant__arr_56_uint_1 UniformConstant\n";
2004 }
2005 s << " %main = OpFunction %void None %3\n";
2006 s << " %5 = OpLabel\n";
2007 s << " %18 = OpAccessChain %_ptr_Output_float %_ %int_1\n";
2008 s << " OpStore %18 %float_0_200000003\n";
2009 s << " %23 = OpLoad %v4float %in_position\n";
2010 s << " OpStore %position %23\n";
2011 s << " %29 = OpLoad %v2float %in_normalpos\n";
2012 s << " OpStore %normalpos %29\n";
2013 s << " %31 = OpLoad %v4float %position\n";
2014 s << " %32 = OpAccessChain %_ptr_Output_v4float %_ %int_0\n";
2015 s << " OpStore %32 %31\n";
2016 s << " %37 = OpLoad %int %gl_VertexIndex\n";
2017 s << " OpStore %vIndex %37\n";
2018 s << " %43 = OpAccessChain %_ptr_Input_int %index %uint_0\n";
2019 s << " %44 = OpLoad %int %43\n";
2020 s << " OpStore %rIndex %44\n";
2021 s << " %46 = OpAccessChain %_ptr_Input_int %index %uint_1\n";
2022 s << " %47 = OpLoad %int %46\n";
2023 s << " OpStore %gIndex %47\n";
2024 s << " %50 = OpAccessChain %_ptr_Input_int %index %uint_2\n";
2025 s << " %51 = OpLoad %int %50\n";
2026 s << " OpStore %bIndex %51\n";
2027 s << " %54 = OpAccessChain %_ptr_Input_int %index %uint_3\n";
2028 s << " %55 = OpLoad %int %54\n";
2029 s << " OpStore %aIndex %55\n";
2030 if (allowVertexStoring)
2031 {
2032 s << " %56 = OpLoad %int %gIndex\n";
2033 s << " %58 = OpINotEqual %bool %56 %int_0\n";
2034 s << " OpSelectionMerge %60 None\n";
2035 s << " OpBranchConditional %58 %59 %60\n";
2036 s << " %59 = OpLabel\n";
2037 s << " %65 = OpLoad %int %gIndex\n";
2038 s << " %66 = OpCopyObject %int %65\n";
2039 s << " %68 = OpAccessChain %_ptr_UniformConstant_61 %data %66\n";
2040 s << " %69 = OpLoad %61 %68\n";
2041 s << " %70 = OpLoad %int %rIndex\n";
2042 s << " %71 = OpCopyObject %int %70\n";
2043 s << " %72 = OpAccessChain %_ptr_UniformConstant_61 %data %71\n";
2044 s << " %73 = OpLoad %61 %72\n";
2045 s << " %74 = OpImageRead %v4float %73 %int_0\n";
2046 s << " OpImageWrite %69 %int_1 %74\n";
2047 s << " OpBranch %60\n";
2048 s << " %60 = OpLabel\n";
2049 }
2050 s << " OpReturn\n";
2051 s << " OpFunctionEnd\n";
2052 break;
2053 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2054 s << " OpCapability Shader\n";
2055 if (allowVertexStoring)
2056 {
2057 s << " OpCapability ShaderNonUniform\n";
2058 s << " OpCapability RuntimeDescriptorArray\n";
2059 s << " OpCapability StorageBufferArrayNonUniformIndexing\n";
2060 s << " OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2061 }
2062 s << " %1 = OpExtInstImport \"GLSL.std.450\"\n";
2063 s << " OpMemoryModel Logical GLSL450\n";
2064 s << " OpEntryPoint Vertex %main \"main\" %_ %position %in_position %normalpos %in_normalpos "
2065 "%vIndex %gl_VertexIndex %rIndex %index %gIndex %bIndex %aIndex %data\n";
2066 s << " OpSource GLSL 450\n";
2067 s << " OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2068 s << " OpName %main \"main\"\n";
2069 s << " OpName %gl_PerVertex \"gl_PerVertex\"\n";
2070 s << " OpMemberName %gl_PerVertex 0 \"gl_Position\"\n";
2071 s << " OpMemberName %gl_PerVertex 1 \"gl_PointSize\"\n";
2072 s << " OpMemberName %gl_PerVertex 2 \"gl_ClipDistance\"\n";
2073 s << " OpMemberName %gl_PerVertex 3 \"gl_CullDistance\"\n";
2074 s << " OpName %_ \"\"\n";
2075 s << " OpName %position \"position\"\n";
2076 s << " OpName %in_position \"in_position\"\n";
2077 s << " OpName %normalpos \"normalpos\"\n";
2078 s << " OpName %in_normalpos \"in_normalpos\"\n";
2079 s << " OpName %vIndex \"vIndex\"\n";
2080 s << " OpName %gl_VertexIndex \"gl_VertexIndex\"\n";
2081 s << " OpName %rIndex \"rIndex\"\n";
2082 s << " OpName %index \"index\"\n";
2083 s << " OpName %gIndex \"gIndex\"\n";
2084 s << " OpName %bIndex \"bIndex\"\n";
2085 s << " OpName %aIndex \"aIndex\"\n";
2086 s << " OpName %Data \"Data\"\n";
2087 s << " OpMemberName %Data 0 \"cnew\"\n";
2088 s << " OpMemberName %Data 1 \"cold\"\n";
2089 s << " OpName %data \"data\"\n";
2090 s << " OpMemberDecorate %gl_PerVertex 0 BuiltIn Position\n";
2091 s << " OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize\n";
2092 s << " OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance\n";
2093 s << " OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance\n";
2094 s << " OpDecorate %gl_PerVertex Block\n";
2095 s << " OpDecorate %position Location 0\n";
2096 s << " OpDecorate %in_position Location 0\n";
2097 s << " OpDecorate %normalpos Location 1\n";
2098 s << " OpDecorate %in_normalpos Location 1\n";
2099 s << " OpDecorate %vIndex Location 2\n";
2100 s << " OpDecorate %gl_VertexIndex BuiltIn VertexIndex\n";
2101 s << " OpDecorate %rIndex Location 3\n";
2102 s << " OpDecorate %index Location 2\n";
2103 s << " OpDecorate %gIndex Location 4\n";
2104 s << " OpDecorate %bIndex Location 5\n";
2105 s << " OpDecorate %aIndex Location 6\n";
2106 s << " OpMemberDecorate %Data 0 Offset 0\n";
2107 s << " OpMemberDecorate %Data 1 Offset 16\n";
2108 s << " OpDecorate %Data Block\n";
2109 s << " OpDecorate %data DescriptorSet 0\n";
2110 s << " OpDecorate %data Binding " << BINDING_TestObject << "\n";
2111 if (allowVertexStoring)
2112 {
2113 // s << " OpDecorate %66 NonUniform\n";
2114 // s << " OpDecorate %68 NonUniform\n";
2115 s << " OpDecorate %70 NonUniform\n";
2116 // s << " OpDecorate %71 NonUniform\n";
2117 s << " OpDecorate %72 NonUniform\n";
2118 }
2119 s << " %void = OpTypeVoid\n";
2120 s << " %3 = OpTypeFunction %void\n";
2121 s << " %float = OpTypeFloat 32\n";
2122 s << " %v4float = OpTypeVector %float 4\n";
2123 s << " %uint = OpTypeInt 32 0\n";
2124 s << " %uint_1 = OpConstant %uint 1\n";
2125 s << "%_arr_float_uint_1 = OpTypeArray %float %uint_1\n";
2126 s << "%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1\n";
2127 s << "%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex\n";
2128 s << " %_ = OpVariable %_ptr_Output_gl_PerVertex Output\n";
2129 s << " %int = OpTypeInt 32 1\n";
2130 s << " %int_1 = OpConstant %int 1\n";
2131 s << "%float_0_200000003 = OpConstant %float 0.200000003\n";
2132 s << "%_ptr_Output_float = OpTypePointer Output %float\n";
2133 s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
2134 s << " %position = OpVariable %_ptr_Output_v4float Output\n";
2135 s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
2136 s << "%in_position = OpVariable %_ptr_Input_v4float Input\n";
2137 s << " %v2float = OpTypeVector %float 2\n";
2138 s << "%_ptr_Output_v2float = OpTypePointer Output %v2float\n";
2139 s << " %normalpos = OpVariable %_ptr_Output_v2float Output\n";
2140 s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
2141 s << "%in_normalpos = OpVariable %_ptr_Input_v2float Input\n";
2142 s << " %int_0 = OpConstant %int 0\n";
2143 s << "%_ptr_Output_int = OpTypePointer Output %int\n";
2144 s << " %vIndex = OpVariable %_ptr_Output_int Output\n";
2145 s << "%_ptr_Input_int = OpTypePointer Input %int\n";
2146 s << "%gl_VertexIndex = OpVariable %_ptr_Input_int Input\n";
2147 s << " %rIndex = OpVariable %_ptr_Output_int Output\n";
2148 s << " %v4int = OpTypeVector %int 4\n";
2149 s << "%_ptr_Input_v4int = OpTypePointer Input %v4int\n";
2150 s << " %index = OpVariable %_ptr_Input_v4int Input\n";
2151 s << " %uint_0 = OpConstant %uint 0\n";
2152 s << " %gIndex = OpVariable %_ptr_Output_int Output\n";
2153 s << " %bIndex = OpVariable %_ptr_Output_int Output\n";
2154 s << " %uint_2 = OpConstant %uint 2\n";
2155 s << " %aIndex = OpVariable %_ptr_Output_int Output\n";
2156 s << " %uint_3 = OpConstant %uint 3\n";
2157 s << " %Data = OpTypeStruct %v4float %v4float\n";
2158 if (allowVertexStoring)
2159 {
2160 s << " %bool = OpTypeBool\n";
2161 s << "%_runtimearr_Data = OpTypeRuntimeArray %Data\n";
2162 s << "%_ptr_StorageBuffer__runtimearr_Data = OpTypePointer StorageBuffer %_runtimearr_Data\n";
2163 s << " %data = OpVariable %_ptr_StorageBuffer__runtimearr_Data StorageBuffer\n";
2164 s << "%_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float\n";
2165 }
2166 else
2167 {
2168 s << "%_arr_Data_uint_1 = OpTypeArray %Data %uint_1\n";
2169 s << "%_ptr_StorageBuffer__arr_Data_uint_1 = OpTypePointer StorageBuffer %_arr_Data_uint_1\n";
2170 s << " %data = OpVariable %_ptr_StorageBuffer__arr_Data_uint_1 StorageBuffer\n";
2171 }
2172 s << " %main = OpFunction %void None %3\n";
2173 s << " %5 = OpLabel\n";
2174 s << " %18 = OpAccessChain %_ptr_Output_float %_ %int_1\n";
2175 s << " OpStore %18 %float_0_200000003\n";
2176 s << " %23 = OpLoad %v4float %in_position\n";
2177 s << " OpStore %position %23\n";
2178 s << " %29 = OpLoad %v2float %in_normalpos\n";
2179 s << " OpStore %normalpos %29\n";
2180 s << " %31 = OpLoad %v4float %position\n";
2181 s << " %32 = OpAccessChain %_ptr_Output_v4float %_ %int_0\n";
2182 s << " OpStore %32 %31\n";
2183 s << " %37 = OpLoad %int %gl_VertexIndex\n";
2184 s << " OpStore %vIndex %37\n";
2185 s << " %43 = OpAccessChain %_ptr_Input_int %index %uint_0\n";
2186 s << " %44 = OpLoad %int %43\n";
2187 s << " OpStore %rIndex %44\n";
2188 s << " %46 = OpAccessChain %_ptr_Input_int %index %uint_1\n";
2189 s << " %47 = OpLoad %int %46\n";
2190 s << " OpStore %gIndex %47\n";
2191 s << " %50 = OpAccessChain %_ptr_Input_int %index %uint_2\n";
2192 s << " %51 = OpLoad %int %50\n";
2193 s << " OpStore %bIndex %51\n";
2194 s << " %54 = OpAccessChain %_ptr_Input_int %index %uint_3\n";
2195 s << " %55 = OpLoad %int %54\n";
2196 s << " OpStore %aIndex %55\n";
2197 if (allowVertexStoring)
2198 {
2199 s << " %56 = OpLoad %int %gIndex\n";
2200 s << " %58 = OpINotEqual %bool %56 %int_0\n";
2201 s << " OpSelectionMerge %60 None\n";
2202 s << " OpBranchConditional %58 %59 %60\n";
2203 s << " %59 = OpLabel\n";
2204 s << " %65 = OpLoad %int %gIndex\n";
2205 s << " %66 = OpCopyObject %int %65\n";
2206 s << " %67 = OpLoad %int %rIndex\n";
2207 s << " %68 = OpCopyObject %int %67\n";
2208 s << " %70 = OpAccessChain %_ptr_StorageBuffer_v4float %data %68 %int_1\n";
2209 s << " %71 = OpLoad %v4float %70\n";
2210 s << " %72 = OpAccessChain %_ptr_StorageBuffer_v4float %data %66 %int_0\n";
2211 s << " OpStore %72 %71\n";
2212 s << " OpBranch %60\n";
2213 s << " %60 = OpLabel\n";
2214 }
2215 s << " OpReturn\n";
2216 s << " OpFunctionEnd\n";
2217 break;
2218 default:
2219 TCU_THROW(InternalError, "Unexpected descriptor type");
2220 }
2221 break;
2222 case VK_SHADER_STAGE_FRAGMENT_BIT:
2223 switch (testCaseParams.descriptorType)
2224 {
2225 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
2226 s << " OpCapability Shader\n";
2227 if (testCaseParams.usesMipMaps)
2228 {
2229 s << " OpCapability ImageQuery\n";
2230 }
2231 s << " OpCapability ShaderNonUniform\n";
2232 s << " OpCapability RuntimeDescriptorArray\n";
2233 s << " OpCapability SampledImageArrayNonUniformIndexing\n";
2234 s << " OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2235 s << " %1 = OpExtInstImport \"GLSL.std.450\"\n";
2236 s << " OpMemoryModel Logical GLSL450\n";
2237 s << " OpEntryPoint Fragment %main \"main\" %FragColor %data %rIndex %position %normalpos "
2238 "%vIndex %gIndex %bIndex %aIndex\n";
2239 s << " OpExecutionMode %main OriginUpperLeft\n";
2240 s << " OpSource GLSL 450\n";
2241 s << " OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2242 s << " OpSourceExtension \"GL_EXT_texture_buffer\"\n";
2243 s << " OpName %main \"main\"\n";
2244 s << " OpName %FragColor \"FragColor\"\n";
2245 s << " OpName %data \"data\"\n";
2246 s << " OpName %rIndex \"rIndex\"\n";
2247 s << " OpName %position \"position\"\n";
2248 s << " OpName %normalpos \"normalpos\"\n";
2249 s << " OpName %vIndex \"vIndex\"\n";
2250 s << " OpName %gIndex \"gIndex\"\n";
2251 s << " OpName %bIndex \"bIndex\"\n";
2252 s << " OpName %aIndex \"aIndex\"\n";
2253 s << " OpDecorate %FragColor Location 0\n";
2254 s << " OpDecorate %data DescriptorSet 0\n";
2255 s << " OpDecorate %data Binding " << BINDING_TestObject << "\n";
2256 s << " OpDecorate %rIndex Flat\n";
2257 s << " OpDecorate %rIndex Location 3\n";
2258 // s << " OpDecorate %19 NonUniform\n";
2259 // s << " OpDecorate %21 NonUniform\n";
2260 s << " OpDecorate %22 NonUniform\n";
2261 if (testCaseParams.usesMipMaps)
2262 {
2263 // s << " OpDecorate %27 NonUniform\n";
2264 // s << " OpDecorate %28 NonUniform\n";
2265 // s << " OpDecorate %29 NonUniform\n";
2266 s << " OpDecorate %30 NonUniform\n";
2267 }
2268 s << " OpDecorate %position Flat\n";
2269 s << " OpDecorate %position Location 0\n";
2270 s << " OpDecorate %normalpos Flat\n";
2271 s << " OpDecorate %normalpos Location 1\n";
2272 s << " OpDecorate %vIndex Flat\n";
2273 s << " OpDecorate %vIndex Location 2\n";
2274 s << " OpDecorate %gIndex Flat\n";
2275 s << " OpDecorate %gIndex Location 4\n";
2276 s << " OpDecorate %bIndex Flat\n";
2277 s << " OpDecorate %bIndex Location 5\n";
2278 s << " OpDecorate %aIndex Flat\n";
2279 s << " OpDecorate %aIndex Location 6\n";
2280 s << " %void = OpTypeVoid\n";
2281 s << " %3 = OpTypeFunction %void\n";
2282 s << " %float = OpTypeFloat 32\n";
2283 s << " %v4float = OpTypeVector %float 4\n";
2284 s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
2285 s << " %FragColor = OpVariable %_ptr_Output_v4float Output\n";
2286 s << " %10 = OpTypeImage %float 2D 0 0 0 1 Unknown\n";
2287 s << " %11 = OpTypeSampledImage %10\n";
2288 s << "%_runtimearr_11 = OpTypeRuntimeArray %11\n";
2289 s << "%_ptr_UniformConstant__runtimearr_11 = OpTypePointer UniformConstant %_runtimearr_11\n";
2290 s << " %data = OpVariable %_ptr_UniformConstant__runtimearr_11 UniformConstant\n";
2291 s << " %int = OpTypeInt 32 1\n";
2292 s << "%_ptr_Input_int = OpTypePointer Input %int\n";
2293 s << " %rIndex = OpVariable %_ptr_Input_int Input\n";
2294 s << "%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11\n";
2295 s << " %v2float = OpTypeVector %float 2\n";
2296 s << " %float_0 = OpConstant %float 0\n";
2297 s << " %int_1 = OpConstant %int 1\n";
2298 s << " %25 = OpConstantComposite %v2float %float_0 %float_0\n";
2299 s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
2300 s << " %position = OpVariable %_ptr_Input_v4float Input\n";
2301 s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
2302 s << " %normalpos = OpVariable %_ptr_Input_v2float Input\n";
2303 s << " %vIndex = OpVariable %_ptr_Input_int Input\n";
2304 s << " %gIndex = OpVariable %_ptr_Input_int Input\n";
2305 s << " %bIndex = OpVariable %_ptr_Input_int Input\n";
2306 s << " %aIndex = OpVariable %_ptr_Input_int Input\n";
2307 s << " %main = OpFunction %void None %3\n";
2308 s << " %5 = OpLabel\n";
2309 s << " %18 = OpLoad %int %rIndex\n";
2310 s << " %19 = OpCopyObject %int %18\n";
2311 s << " %21 = OpAccessChain %_ptr_UniformConstant_11 %data %19\n";
2312 s << " %22 = OpLoad %11 %21\n";
2313 if (testCaseParams.usesMipMaps)
2314 {
2315 s << " %26 = OpLoad %int %rIndex\n";
2316 s << " %27 = OpCopyObject %int %26\n";
2317 s << " %28 = OpAccessChain %_ptr_UniformConstant_11 %data %27\n";
2318 s << " %29 = OpLoad %11 %28\n";
2319 s << " %30 = OpImage %10 %29\n";
2320 s << " %31 = OpImageQueryLevels %int %30\n";
2321 s << " %33 = OpISub %int %31 %int_1\n";
2322 s << " %34 = OpConvertSToF %float %33\n";
2323 s << " %35 = OpImageSampleExplicitLod %v4float %22 %25 Lod %34\n";
2324 s << " OpStore %FragColor %35\n";
2325 }
2326 else
2327 {
2328 s << " %26 = OpImageSampleImplicitLod %v4float %22 %25\n";
2329 s << " OpStore %FragColor %26\n";
2330 }
2331 s << " OpReturn\n";
2332 s << " OpFunctionEnd\n";
2333 break;
2334 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
2335 s << " OpCapability Shader\n";
2336 s << " OpCapability SampledBuffer\n";
2337 s << " OpCapability ShaderNonUniform\n";
2338 s << " OpCapability RuntimeDescriptorArray\n";
2339 s << " OpCapability UniformTexelBufferArrayNonUniformIndexing\n";
2340 s << " OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2341 s << " %1 = OpExtInstImport \"GLSL.std.450\"\n";
2342 s << " OpMemoryModel Logical GLSL450\n";
2343 s << " OpEntryPoint Fragment %main \"main\" %FragColor %data %rIndex %position %normalpos "
2344 "%vIndex %gIndex %bIndex %aIndex\n";
2345 s << " OpExecutionMode %main OriginUpperLeft\n";
2346 s << " OpSource GLSL 450\n";
2347 s << " OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2348 s << " OpSourceExtension \"GL_EXT_texture_buffer\"\n";
2349 s << " OpName %main \"main\"\n";
2350 s << " OpName %FragColor \"FragColor\"\n";
2351 s << " OpName %data \"data\"\n";
2352 s << " OpName %rIndex \"rIndex\"\n";
2353 s << " OpName %position \"position\"\n";
2354 s << " OpName %normalpos \"normalpos\"\n";
2355 s << " OpName %vIndex \"vIndex\"\n";
2356 s << " OpName %gIndex \"gIndex\"\n";
2357 s << " OpName %bIndex \"bIndex\"\n";
2358 s << " OpName %aIndex \"aIndex\"\n";
2359 s << " OpDecorate %FragColor Location 0\n";
2360 s << " OpDecorate %data DescriptorSet 0\n";
2361 s << " OpDecorate %data Binding " << BINDING_TestObject << "\n";
2362 s << " OpDecorate %rIndex Flat\n";
2363 s << " OpDecorate %rIndex Location 3\n";
2364 // s << " OpDecorate %19 NonUniform\n";
2365 // s << " OpDecorate %21 NonUniform\n";
2366 // s << " OpDecorate %22 NonUniform\n";
2367 s << " OpDecorate %24 NonUniform\n";
2368 s << " OpDecorate %position Flat\n";
2369 s << " OpDecorate %position Location 0\n";
2370 s << " OpDecorate %normalpos Flat\n";
2371 s << " OpDecorate %normalpos Location 1\n";
2372 s << " OpDecorate %vIndex Flat\n";
2373 s << " OpDecorate %vIndex Location 2\n";
2374 s << " OpDecorate %gIndex Flat\n";
2375 s << " OpDecorate %gIndex Location 4\n";
2376 s << " OpDecorate %bIndex Flat\n";
2377 s << " OpDecorate %bIndex Location 5\n";
2378 s << " OpDecorate %aIndex Flat\n";
2379 s << " OpDecorate %aIndex Location 6\n";
2380 s << " %void = OpTypeVoid\n";
2381 s << " %3 = OpTypeFunction %void\n";
2382 s << " %float = OpTypeFloat 32\n";
2383 s << " %v4float = OpTypeVector %float 4\n";
2384 s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
2385 s << " %FragColor = OpVariable %_ptr_Output_v4float Output\n";
2386 s << " %10 = OpTypeImage %float Buffer 0 0 0 1 Unknown\n";
2387 s << " %11 = OpTypeSampledImage %10\n";
2388 s << "%_runtimearr_11 = OpTypeRuntimeArray %11\n";
2389 s << "%_ptr_UniformConstant__runtimearr_11 = OpTypePointer UniformConstant %_runtimearr_11\n";
2390 s << " %data = OpVariable %_ptr_UniformConstant__runtimearr_11 UniformConstant\n";
2391 s << " %int = OpTypeInt 32 1\n";
2392 s << "%_ptr_Input_int = OpTypePointer Input %int\n";
2393 s << " %rIndex = OpVariable %_ptr_Input_int Input\n";
2394 s << "%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11\n";
2395 s << " %int_0 = OpConstant %int 0\n";
2396 s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
2397 s << " %position = OpVariable %_ptr_Input_v4float Input\n";
2398 s << " %v2float = OpTypeVector %float 2\n";
2399 s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
2400 s << " %normalpos = OpVariable %_ptr_Input_v2float Input\n";
2401 s << " %vIndex = OpVariable %_ptr_Input_int Input\n";
2402 s << " %gIndex = OpVariable %_ptr_Input_int Input\n";
2403 s << " %bIndex = OpVariable %_ptr_Input_int Input\n";
2404 s << " %aIndex = OpVariable %_ptr_Input_int Input\n";
2405 s << " %main = OpFunction %void None %3\n";
2406 s << " %5 = OpLabel\n";
2407 s << " %18 = OpLoad %int %rIndex\n";
2408 s << " %19 = OpCopyObject %int %18\n";
2409 s << " %21 = OpAccessChain %_ptr_UniformConstant_11 %data %19\n";
2410 s << " %22 = OpLoad %11 %21\n";
2411 s << " %24 = OpImage %10 %22\n";
2412 s << " %25 = OpImageFetch %v4float %24 %int_0\n";
2413 s << " OpStore %FragColor %25\n";
2414 s << " OpReturn\n";
2415 s << " OpFunctionEnd\n";
2416 break;
2417 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
2418 s << " OpCapability Shader\n";
2419 s << " OpCapability ImageBuffer\n";
2420 s << " OpCapability ShaderNonUniform\n";
2421 s << " OpCapability RuntimeDescriptorArray\n";
2422 s << " OpCapability StorageTexelBufferArrayNonUniformIndexing\n";
2423 s << " OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2424 s << " %1 = OpExtInstImport \"GLSL.std.450\"\n";
2425 s << " OpMemoryModel Logical GLSL450\n";
2426 s << " OpEntryPoint Fragment %main \"main\" %FragColor %data %rIndex %position %normalpos "
2427 "%vIndex %gIndex %bIndex %aIndex\n";
2428 s << " OpExecutionMode %main OriginUpperLeft\n";
2429 s << " OpSource GLSL 450\n";
2430 s << " OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2431 s << " OpName %main \"main\"\n";
2432 s << " OpName %FragColor \"FragColor\"\n";
2433 s << " OpName %data \"data\"\n";
2434 s << " OpName %rIndex \"rIndex\"\n";
2435 s << " OpName %position \"position\"\n";
2436 s << " OpName %normalpos \"normalpos\"\n";
2437 s << " OpName %vIndex \"vIndex\"\n";
2438 s << " OpName %gIndex \"gIndex\"\n";
2439 s << " OpName %bIndex \"bIndex\"\n";
2440 s << " OpName %aIndex \"aIndex\"\n";
2441 s << " OpDecorate %FragColor Location 0\n";
2442 s << " OpDecorate %data DescriptorSet 0\n";
2443 s << " OpDecorate %data Binding " << BINDING_TestObject << "\n";
2444 s << " OpDecorate %rIndex Flat\n";
2445 s << " OpDecorate %rIndex Location 3\n";
2446 // s << " OpDecorate %18 NonUniform\n";
2447 // s << " OpDecorate %20 NonUniform\n";
2448 s << " OpDecorate %21 NonUniform\n";
2449 s << " OpDecorate %position Flat\n";
2450 s << " OpDecorate %position Location 0\n";
2451 s << " OpDecorate %normalpos Flat\n";
2452 s << " OpDecorate %normalpos Location 1\n";
2453 s << " OpDecorate %vIndex Flat\n";
2454 s << " OpDecorate %vIndex Location 2\n";
2455 s << " OpDecorate %gIndex Flat\n";
2456 s << " OpDecorate %gIndex Location 4\n";
2457 s << " OpDecorate %bIndex Flat\n";
2458 s << " OpDecorate %bIndex Location 5\n";
2459 s << " OpDecorate %aIndex Flat\n";
2460 s << " OpDecorate %aIndex Location 6\n";
2461 s << " %void = OpTypeVoid\n";
2462 s << " %3 = OpTypeFunction %void\n";
2463 s << " %float = OpTypeFloat 32\n";
2464 s << " %v4float = OpTypeVector %float 4\n";
2465 s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
2466 s << " %FragColor = OpVariable %_ptr_Output_v4float Output\n";
2467 s << " %10 = OpTypeImage %float Buffer 0 0 0 2 Rgba32f\n";
2468 s << "%_runtimearr_10 = OpTypeRuntimeArray %10\n";
2469 s << "%_ptr_UniformConstant__runtimearr_10 = OpTypePointer UniformConstant %_runtimearr_10\n";
2470 s << " %data = OpVariable %_ptr_UniformConstant__runtimearr_10 UniformConstant\n";
2471 s << " %int = OpTypeInt 32 1\n";
2472 s << "%_ptr_Input_int = OpTypePointer Input %int\n";
2473 s << " %rIndex = OpVariable %_ptr_Input_int Input\n";
2474 s << "%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10\n";
2475 s << " %int_0 = OpConstant %int 0\n";
2476 s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
2477 s << " %position = OpVariable %_ptr_Input_v4float Input\n";
2478 s << " %v2float = OpTypeVector %float 2\n";
2479 s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
2480 s << " %normalpos = OpVariable %_ptr_Input_v2float Input\n";
2481 s << " %vIndex = OpVariable %_ptr_Input_int Input\n";
2482 s << " %gIndex = OpVariable %_ptr_Input_int Input\n";
2483 s << " %bIndex = OpVariable %_ptr_Input_int Input\n";
2484 s << " %aIndex = OpVariable %_ptr_Input_int Input\n";
2485 s << " %main = OpFunction %void None %3\n";
2486 s << " %5 = OpLabel\n";
2487 s << " %17 = OpLoad %int %rIndex\n";
2488 s << " %18 = OpCopyObject %int %17\n";
2489 s << " %20 = OpAccessChain %_ptr_UniformConstant_10 %data %18\n";
2490 s << " %21 = OpLoad %10 %20\n";
2491 s << " %23 = OpImageRead %v4float %21 %int_0\n";
2492 s << " OpStore %FragColor %23\n";
2493 s << " OpReturn\n";
2494 s << " OpFunctionEnd\n";
2495 break;
2496 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2497 s << " OpCapability Shader\n";
2498 s << " OpCapability ShaderNonUniform\n";
2499 s << " OpCapability RuntimeDescriptorArray\n";
2500 s << " OpCapability StorageBufferArrayNonUniformIndexing\n";
2501 s << " OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2502 s << " %1 = OpExtInstImport \"GLSL.std.450\"\n";
2503 s << " OpMemoryModel Logical GLSL450\n";
2504 s << " OpEntryPoint Fragment %main \"main\" %FragColor %data %rIndex %position %normalpos "
2505 "%vIndex %gIndex %bIndex %aIndex\n";
2506 s << " OpExecutionMode %main OriginUpperLeft\n";
2507 s << " OpSource GLSL 450\n";
2508 s << " OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2509 s << " OpName %main \"main\"\n";
2510 s << " OpName %FragColor \"FragColor\"\n";
2511 s << " OpName %Data \"Data\"\n";
2512 s << " OpMemberName %Data 0 \"cnew\"\n";
2513 s << " OpMemberName %Data 1 \"cold\"\n";
2514 s << " OpName %data \"data\"\n";
2515 s << " OpName %rIndex \"rIndex\"\n";
2516 s << " OpName %position \"position\"\n";
2517 s << " OpName %normalpos \"normalpos\"\n";
2518 s << " OpName %vIndex \"vIndex\"\n";
2519 s << " OpName %gIndex \"gIndex\"\n";
2520 s << " OpName %bIndex \"bIndex\"\n";
2521 s << " OpName %aIndex \"aIndex\"\n";
2522 s << " OpDecorate %FragColor Location 0\n";
2523 s << " OpMemberDecorate %Data 0 Offset 0\n";
2524 s << " OpMemberDecorate %Data 1 Offset 16\n";
2525 s << " OpDecorate %Data Block\n";
2526 s << " OpDecorate %data DescriptorSet 0\n";
2527 s << " OpDecorate %data Binding " << BINDING_TestObject << "\n";
2528 s << " OpDecorate %rIndex Flat\n";
2529 s << " OpDecorate %rIndex Location 3\n";
2530 // s << " OpDecorate %18 NonUniform\n";
2531 s << " OpDecorate %21 NonUniform\n";
2532 // s << " OpDecorate %22 NonUniform\n";
2533 s << " OpDecorate %position Flat\n";
2534 s << " OpDecorate %position Location 0\n";
2535 s << " OpDecorate %normalpos Flat OpDecorate %normalpos Location 1\n";
2536 s << " OpDecorate %vIndex Flat\n";
2537 s << " OpDecorate %vIndex Location 2\n";
2538 s << " OpDecorate %gIndex Flat\n";
2539 s << " OpDecorate %gIndex Location 4\n";
2540 s << " OpDecorate %bIndex Flat\n";
2541 s << " OpDecorate %bIndex Location 5\n";
2542 s << " OpDecorate %aIndex Flat\n";
2543 s << " OpDecorate %aIndex Location 6\n";
2544 s << " %void = OpTypeVoid\n";
2545 s << " %3 = OpTypeFunction %void\n";
2546 s << " %float = OpTypeFloat 32\n";
2547 s << " %v4float = OpTypeVector %float 4\n";
2548 s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
2549 s << " %FragColor = OpVariable %_ptr_Output_v4float Output\n";
2550 s << " %Data = OpTypeStruct %v4float %v4float\n";
2551 s << "%_runtimearr_Data = OpTypeRuntimeArray %Data\n";
2552 s << "%_ptr_StorageBuffer__runtimearr_Data = OpTypePointer StorageBuffer %_runtimearr_Data\n";
2553 s << " %data = OpVariable %_ptr_StorageBuffer__runtimearr_Data StorageBuffer\n";
2554 s << " %int = OpTypeInt 32 1\n";
2555 s << "%_ptr_Input_int = OpTypePointer Input %int\n";
2556 s << " %rIndex = OpVariable %_ptr_Input_int Input\n";
2557 s << " %int_1 = OpConstant %int 1\n";
2558 s << "%_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float\n";
2559 s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
2560 s << " %position = OpVariable %_ptr_Input_v4float Input\n";
2561 s << " %v2float = OpTypeVector %float 2\n";
2562 s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
2563 s << " %normalpos = OpVariable %_ptr_Input_v2float Input\n";
2564 s << " %vIndex = OpVariable %_ptr_Input_int Input\n";
2565 s << " %gIndex = OpVariable %_ptr_Input_int Input\n";
2566 s << " %bIndex = OpVariable %_ptr_Input_int Input\n";
2567 s << " %aIndex = OpVariable %_ptr_Input_int Input\n";
2568 s << " %main = OpFunction %void None %3\n";
2569 s << " %5 = OpLabel\n";
2570 s << " %17 = OpLoad %int %rIndex\n";
2571 s << " %18 = OpCopyObject %int %17\n";
2572 s << " %21 = OpAccessChain %_ptr_StorageBuffer_v4float %data %18 %int_1\n";
2573 s << " %22 = OpLoad %v4float %21\n";
2574 s << " OpStore %FragColor %22\n";
2575 s << " OpReturn\n";
2576 s << " OpFunctionEnd\n";
2577 break;
2578 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
2579 s << " OpCapability Shader\n";
2580 s << " OpCapability ShaderNonUniform\n";
2581 s << " OpCapability RuntimeDescriptorArray\n";
2582 s << " OpCapability UniformBufferArrayNonUniformIndexing\n";
2583 s << " OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2584 s << " %1 = OpExtInstImport \"GLSL.std.450\"\n";
2585 s << " OpMemoryModel Logical GLSL450\n";
2586 s << " OpEntryPoint Fragment %main \"main\" %FragColor %data %rIndex %position %normalpos "
2587 "%vIndex %gIndex %bIndex %aIndex\n";
2588 s << " OpExecutionMode %main OriginUpperLeft\n";
2589 s << " OpSource GLSL 450\n";
2590 s << " OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2591 s << " OpName %main \"main\"\n";
2592 s << " OpName %FragColor \"FragColor\"\n";
2593 s << " OpName %Data \"Data\"\n";
2594 s << " OpMemberName %Data 0 \"c\"\n";
2595 s << " OpName %data \"data\"\n";
2596 s << " OpName %rIndex \"rIndex\"\n";
2597 s << " OpName %position \"position\"\n";
2598 s << " OpName %normalpos \"normalpos\"\n";
2599 s << " OpName %vIndex \"vIndex\"\n";
2600 s << " OpName %gIndex \"gIndex\"\n";
2601 s << " OpName %bIndex \"bIndex\"\n";
2602 s << " OpName %aIndex \"aIndex\"\n";
2603 s << " OpDecorate %FragColor Location 0\n";
2604 s << " OpMemberDecorate %Data 0 Offset 0\n";
2605 s << " OpDecorate %Data Block\n";
2606 s << " OpDecorate %data DescriptorSet 0\n";
2607 s << " OpDecorate %data Binding " << BINDING_TestObject << "\n";
2608 s << " OpDecorate %rIndex Flat\n";
2609 s << " OpDecorate %rIndex Location 3\n";
2610 // s << " OpDecorate %18 NonUniform\n";
2611 s << " OpDecorate %21 NonUniform\n";
2612 // s << " OpDecorate %22 NonUniform\n";
2613 s << " OpDecorate %position Flat\n";
2614 s << " OpDecorate %position Location 0\n";
2615 s << " OpDecorate %normalpos Flat\n";
2616 s << " OpDecorate %normalpos Location 1\n";
2617 s << " OpDecorate %vIndex Flat\n";
2618 s << " OpDecorate %vIndex Location 2\n";
2619 s << " OpDecorate %gIndex Flat\n";
2620 s << " OpDecorate %gIndex Location 4\n";
2621 s << " OpDecorate %bIndex Flat\n";
2622 s << " OpDecorate %bIndex Location 5\n";
2623 s << " OpDecorate %aIndex Flat\n";
2624 s << " OpDecorate %aIndex Location 6\n";
2625 s << " %void = OpTypeVoid\n";
2626 s << " %3 = OpTypeFunction %void\n";
2627 s << " %float = OpTypeFloat 32\n";
2628 s << " %v4float = OpTypeVector %float 4\n";
2629 s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
2630 s << " %FragColor = OpVariable %_ptr_Output_v4float Output\n";
2631 s << " %Data = OpTypeStruct %v4float\n";
2632 s << "%_runtimearr_Data = OpTypeRuntimeArray %Data\n";
2633 s << "%_ptr_Uniform__runtimearr_Data = OpTypePointer Uniform %_runtimearr_Data\n";
2634 s << " %data = OpVariable %_ptr_Uniform__runtimearr_Data Uniform\n";
2635 s << " %int = OpTypeInt 32 1\n";
2636 s << "%_ptr_Input_int = OpTypePointer Input %int\n";
2637 s << " %rIndex = OpVariable %_ptr_Input_int Input\n";
2638 s << " %int_0 = OpConstant %int 0\n";
2639 s << "%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float\n";
2640 s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
2641 s << " %position = OpVariable %_ptr_Input_v4float Input\n";
2642 s << " %v2float = OpTypeVector %float 2\n";
2643 s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
2644 s << " %normalpos = OpVariable %_ptr_Input_v2float Input\n";
2645 s << " %vIndex = OpVariable %_ptr_Input_int Input\n";
2646 s << " %gIndex = OpVariable %_ptr_Input_int Input\n";
2647 s << " %bIndex = OpVariable %_ptr_Input_int Input\n";
2648 s << " %aIndex = OpVariable %_ptr_Input_int Input\n";
2649 s << " %main = OpFunction %void None %3\n";
2650 s << " %5 = OpLabel\n";
2651 s << " %17 = OpLoad %int %rIndex\n";
2652 s << " %18 = OpCopyObject %int %17\n";
2653 s << " %21 = OpAccessChain %_ptr_Uniform_v4float %data %18 %int_0\n";
2654 s << " %22 = OpLoad %v4float %21\n";
2655 s << " OpStore %FragColor %22\n";
2656 s << " OpReturn\n";
2657 s << " OpFunctionEnd\n";
2658 break;
2659 default:
2660 TCU_THROW(InternalError, "Unexpected descriptor type");
2661 }
2662 break;
2663 case VK_SHADER_STAGE_COMPUTE_BIT:
2664 switch (testCaseParams.descriptorType)
2665 {
2666 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
2667 s << " OpCapability Shader\n";
2668 s << " OpCapability ShaderNonUniform\n";
2669 s << " OpCapability RuntimeDescriptorArray\n";
2670 s << " OpCapability StorageImageArrayNonUniformIndexing\n";
2671 s << " OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2672 s << " %1 = OpExtInstImport \"GLSL.std.450\"\n";
2673 s << " OpMemoryModel Logical GLSL450\n";
2674 s << " OpEntryPoint GLCompute %main \"main\" %idxs %gl_WorkGroupID %data\n";
2675 s << " OpExecutionMode %main LocalSize 1 1 1\n";
2676 s << " OpSource GLSL 450\n";
2677 s << " OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2678 s << " OpName %main \"main\"\n";
2679 s << " OpName %c \"c\"\n";
2680 s << " OpName %idxs \"idxs\"\n";
2681 s << " OpName %gl_WorkGroupID \"gl_WorkGroupID\"\n";
2682 s << " OpName %data \"data\"\n";
2683 s << " OpDecorate %idxs DescriptorSet 0\n";
2684 s << " OpDecorate %idxs Binding " << BINDING_Additional << "\n";
2685 s << " OpDecorate %gl_WorkGroupID BuiltIn WorkgroupId\n";
2686 s << " OpDecorate %data DescriptorSet 0\n";
2687 s << " OpDecorate %data Binding " << BINDING_TestObject << "\n";
2688 // s << " OpDecorate %36 NonUniform\n";
2689 // s << " OpDecorate %37 NonUniform\n";
2690 s << " OpDecorate %41 NonUniform\n";
2691 s << " OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize\n";
2692 s << " %void = OpTypeVoid\n";
2693 s << " %3 = OpTypeFunction %void\n";
2694 s << " %uint = OpTypeInt 32 0\n";
2695 s << " %v4uint = OpTypeVector %uint 4\n";
2696 s << "%_ptr_Function_v4uint = OpTypePointer Function %v4uint\n";
2697 s << " %10 = OpTypeImage %uint 2D 0 0 0 2 R32ui\n";
2698 s << "%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10\n";
2699 s << " %idxs = OpVariable %_ptr_UniformConstant_10 UniformConstant\n";
2700 s << " %v3uint = OpTypeVector %uint 3\n";
2701 s << "%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n";
2702 s << "%gl_WorkGroupID = OpVariable %_ptr_Input_v3uint Input\n";
2703 s << " %uint_0 = OpConstant %uint 0\n";
2704 s << "%_ptr_Input_uint = OpTypePointer Input %uint\n";
2705 s << " %int = OpTypeInt 32 1\n";
2706 s << " %uint_1 = OpConstant %uint 1\n";
2707 s << " %v2int = OpTypeVector %int 2\n";
2708 s << "%_runtimearr_10 = OpTypeRuntimeArray %10\n";
2709 s << "%_ptr_UniformConstant__runtimearr_10 = OpTypePointer UniformConstant %_runtimearr_10\n";
2710 s << " %data = OpVariable %_ptr_UniformConstant__runtimearr_10 UniformConstant\n";
2711 s << "%_ptr_Function_uint = OpTypePointer Function %uint\n";
2712 s << " %int_0 = OpConstant %int 0\n";
2713 s << " %39 = OpConstantComposite %v2int %int_0 %int_0\n";
2714 s << "%_ptr_Image_uint = OpTypePointer Image %uint\n";
2715 s << "%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1\n";
2716 s << " %main = OpFunction %void None %3\n";
2717 s << " %5 = OpLabel\n";
2718 s << " %c = OpVariable %_ptr_Function_v4uint Function\n";
2719 s << " %13 = OpLoad %10 %idxs\n";
2720 s << " %19 = OpAccessChain %_ptr_Input_uint %gl_WorkGroupID %uint_0\n";
2721 s << " %20 = OpLoad %uint %19\n";
2722 s << " %22 = OpBitcast %int %20\n";
2723 s << " %24 = OpAccessChain %_ptr_Input_uint %gl_WorkGroupID %uint_1\n";
2724 s << " %25 = OpLoad %uint %24\n";
2725 s << " %26 = OpBitcast %int %25\n";
2726 s << " %28 = OpCompositeConstruct %v2int %22 %26\n";
2727 s << " %29 = OpImageRead %v4uint %13 %28 ZeroExtend\n";
2728 s << " OpStore %c %29\n";
2729 s << " %34 = OpAccessChain %_ptr_Function_uint %c %uint_0\n";
2730 s << " %35 = OpLoad %uint %34\n";
2731 s << " %36 = OpCopyObject %uint %35\n";
2732 s << " %37 = OpAccessChain %_ptr_UniformConstant_10 %data %36\n";
2733 s << " %41 = OpImageTexelPointer %_ptr_Image_uint %37 %39 %uint_0\n";
2734 s << " %42 = OpAtomicIAdd %uint %41 %uint_1 %uint_0 %uint_1\n";
2735 s << " OpReturn\n";
2736 s << " OpFunctionEnd\n";
2737 break;
2738 default:
2739 TCU_THROW(InternalError, "Unexpected descriptor type");
2740 }
2741 break;
2742 default:
2743 TCU_THROW(InternalError, "Unexpected stage");
2744 }
2745
2746 return s.str();
2747 }
2748
getShaderSource(VkShaderStageFlagBits shaderType,const TestCaseParams & testCaseParams,bool allowVertexStoring)2749 std::string CommonDescriptorInstance::getShaderSource(VkShaderStageFlagBits shaderType,
2750 const TestCaseParams &testCaseParams, bool allowVertexStoring)
2751 {
2752 std::stringstream s;
2753
2754 s << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << '\n';
2755 s << "#extension GL_EXT_nonuniform_qualifier : require \n";
2756
2757 if (testCaseParams.calculateInLoop)
2758 {
2759 s << "layout(push_constant) uniform Block { int lowerBound, upperBound; } pc;\n";
2760 s << substBinding(BINDING_DescriptorEnumerator,
2761 "layout(set=1,binding=${?}) uniform isamplerBuffer iter; \n");
2762 }
2763
2764 std::string declType;
2765 switch (testCaseParams.descriptorType)
2766 {
2767 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2768 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
2769 declType = "buffer Data { vec4 cnew, cold; }";
2770 break;
2771 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
2772 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
2773 declType = "uniform Data { vec4 c; }";
2774 break;
2775 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
2776 declType = "uniform imageBuffer";
2777 break;
2778 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
2779 declType = "uniform samplerBuffer";
2780 break;
2781 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
2782 declType = "uniform subpassInput";
2783 break;
2784 case VK_DESCRIPTOR_TYPE_SAMPLER:
2785 declType = "uniform sampler";
2786 break;
2787 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
2788 declType = "uniform texture2D";
2789 break;
2790 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
2791 declType = "uniform sampler2D";
2792 break;
2793 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
2794 declType = "uniform uimage2D";
2795 break;
2796 default:
2797 TCU_THROW(InternalError, "Not implemented descriptor type");
2798 }
2799
2800 std::string extraLayout = "";
2801 switch (testCaseParams.descriptorType)
2802 {
2803 // Note trailing commas to fit in with layout declaration, below.
2804 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
2805 extraLayout = "rgba32f,";
2806 break;
2807 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
2808 extraLayout = "input_attachment_index=1,";
2809 break;
2810 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
2811 extraLayout = "r32ui,";
2812 break;
2813 default:
2814 break;
2815 }
2816
2817 // Input attachments may only be declared in fragment shaders. The tests should only be constructed to use fragment
2818 // shaders, but the matching vertex shader will still pass here and must not pick up the invalid declaration.
2819 if (testCaseParams.descriptorType != VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT ||
2820 shaderType == VK_SHADER_STAGE_FRAGMENT_BIT)
2821 s << "layout(" << extraLayout << "set=0, binding = " << BINDING_TestObject << ") " << declType << " data[];\n";
2822
2823 // Now make any additional declarations needed for specific descriptor types
2824 switch (testCaseParams.descriptorType)
2825 {
2826 case VK_DESCRIPTOR_TYPE_SAMPLER:
2827 s << "layout(set=0,binding=" << BINDING_Additional << ") uniform texture2D tex;\n";
2828 break;
2829 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
2830 s << "layout(set=0,binding=" << BINDING_Additional << ") uniform sampler samp;\n";
2831 break;
2832 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
2833 s << "layout(r32ui,set=0,binding=" << BINDING_Additional << ") uniform uimage2D idxs;\n";
2834 break;
2835 default:
2836 break;
2837 }
2838
2839 switch (shaderType)
2840 {
2841 case VK_SHADER_STAGE_VERTEX_BIT:
2842 s << getVertexShaderProlog();
2843 break;
2844 case VK_SHADER_STAGE_FRAGMENT_BIT:
2845 s << getFragmentShaderProlog();
2846 break;
2847 case VK_SHADER_STAGE_COMPUTE_BIT:
2848 s << getComputeShaderProlog();
2849 break;
2850 default:
2851 TCU_THROW(InternalError, "Not implemented shader stage");
2852 }
2853
2854 switch (shaderType)
2855 {
2856 case VK_SHADER_STAGE_VERTEX_BIT:
2857 {
2858 switch (testCaseParams.descriptorType)
2859 {
2860 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2861 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
2862 if (allowVertexStoring)
2863 s << " if (gIndex != 0) data[nonuniformEXT(gIndex)].cnew = data[nonuniformEXT(rIndex)].cold; \n";
2864 break;
2865 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
2866 if (allowVertexStoring)
2867 s << " if (gIndex != 0) imageStore(data[nonuniformEXT(gIndex)], 1, "
2868 "imageLoad(data[nonuniformEXT(rIndex)], 0)); \n";
2869 break;
2870 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
2871 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
2872 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
2873 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
2874 case VK_DESCRIPTOR_TYPE_SAMPLER:
2875 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
2876 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
2877 break;
2878
2879 default:
2880 TCU_THROW(InternalError, "Not implemented descriptor type");
2881 }
2882 }
2883 break;
2884
2885 case VK_SHADER_STAGE_FRAGMENT_BIT:
2886 {
2887 if (testCaseParams.calculateInLoop)
2888 s << getFragmentLoopSource(
2889 getColorAccess(testCaseParams.descriptorType, "rIndex", testCaseParams.usesMipMaps),
2890 getColorAccess(testCaseParams.descriptorType, "loopIdx", testCaseParams.usesMipMaps));
2891 else
2892 s << getFragmentReturnSource(
2893 getColorAccess(testCaseParams.descriptorType, "rIndex", testCaseParams.usesMipMaps));
2894 break;
2895 }
2896 break;
2897
2898 case VK_SHADER_STAGE_COMPUTE_BIT: // VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
2899 if (testCaseParams.calculateInLoop)
2900 s << " const int totalAdds = pc.upperBound - pc.lowerBound;\n"
2901 << " const int totalInvs = int(gl_WorkGroupSize.x);\n"
2902 << " // Round number up so we never fall short in the number of additions\n"
2903 << " const int addsPerInv = (totalAdds + totalInvs - 1) / totalInvs;\n"
2904 << " const int baseAdd = int(gl_LocalInvocationID.x) * addsPerInv;\n"
2905 << " for (int i = 0; i < addsPerInv; ++i) {\n"
2906 << " const int addIdx = i + baseAdd + pc.lowerBound;\n"
2907 << " if (addIdx < pc.upperBound) {\n"
2908 << " imageAtomicAdd(data[nonuniformEXT(texelFetch(iter, addIdx).x)], ivec2(0, 0), 1);\n"
2909 << " }\n"
2910 << " }\n";
2911 else
2912 {
2913 s << " const int xCoord = int(gl_WorkGroupID.x * gl_WorkGroupSize.x + gl_LocalInvocationID.x);\n"
2914 << " const int yCoord = int(gl_WorkGroupID.y);\n"
2915 << " uvec4 c = imageLoad(idxs, ivec2(xCoord, yCoord));\n"
2916 << " imageAtomicAdd( data[nonuniformEXT(c.r)], ivec2(0, 0), 1);\n";
2917 }
2918 break;
2919
2920 default:
2921 TCU_THROW(InternalError, "Not implemented shader stage");
2922 }
2923
2924 s << getShaderEpilog();
2925
2926 return s.str();
2927 }
2928
2929 class StorageBufferInstance : virtual public CommonDescriptorInstance
2930 {
2931 public:
2932 StorageBufferInstance(Context &context, const TestCaseParams &testCaseParams);
2933
2934 protected:
2935 void createAndPopulateDescriptors(IterateCommonVariables &variables) override;
2936 void createAndPopulateUnusedDescriptors(IterateCommonVariables &variables) override;
2937
2938 bool verifyVertexWriteResults(IterateCommonVariables &variables) override;
2939 };
2940
StorageBufferInstance(Context & context,const TestCaseParams & testCaseParams)2941 StorageBufferInstance::StorageBufferInstance(Context &context, const TestCaseParams &testCaseParams)
2942 : CommonDescriptorInstance(context, TestParams(VK_SHADER_STAGE_ALL_GRAPHICS, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
2943 VK_DESCRIPTOR_TYPE_UNDEFINED, false,
2944 performWritesInVertex(testCaseParams.descriptorType, context),
2945 testCaseParams))
2946 {
2947 }
2948
createAndPopulateDescriptors(IterateCommonVariables & variables)2949 void StorageBufferInstance::createAndPopulateDescriptors(IterateCommonVariables &variables)
2950 {
2951 BindingStorageBufferData data;
2952
2953 bool vertexStores = false;
2954 {
2955 ut::DeviceProperties dp(m_context);
2956 vertexStores = dp.physicalDeviceFeatures().vertexPipelineStoresAndAtomics != false;
2957 }
2958 const uint32_t alignment = static_cast<uint32_t>(
2959 ut::DeviceProperties(m_context).physicalDeviceProperties().limits.minStorageBufferOffsetAlignment);
2960 createBuffers(variables.descriptorsBufferInfos, variables.descriptorsBuffer, variables.validDescriptorCount,
2961 sizeof(data), alignment, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
2962
2963 unsigned char *buffer = static_cast<unsigned char *>(variables.descriptorsBuffer->alloc->getHostPtr());
2964 for (uint32_t infoIdx = 0; infoIdx < variables.validDescriptorCount; ++infoIdx)
2965 {
2966 const float component = m_colorScheme[infoIdx % m_schemeSize];
2967 const tcu::Vec4 color(component, component, component, 1.0f);
2968 VkDescriptorBufferInfo &info = variables.descriptorsBufferInfos[infoIdx];
2969 data.cnew = vertexStores ? m_clearColor : color;
2970 data.cold = color;
2971
2972 deMemcpy(buffer + info.offset, &data, sizeof(data));
2973 }
2974 vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
2975
2976 variables.dataAlignment = deAlign64(sizeof(data), alignment);
2977 }
2978
createAndPopulateUnusedDescriptors(IterateCommonVariables & variables)2979 void StorageBufferInstance::createAndPopulateUnusedDescriptors(IterateCommonVariables &variables)
2980 {
2981 const uint32_t alignment = static_cast<uint32_t>(
2982 ut::DeviceProperties(m_context).physicalDeviceProperties().limits.minStorageBufferOffsetAlignment);
2983 createBuffers(variables.unusedDescriptorsBufferInfos, variables.unusedDescriptorsBuffer, 1,
2984 sizeof(BindingStorageBufferData), alignment, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
2985 }
2986
verifyVertexWriteResults(IterateCommonVariables & variables)2987 bool StorageBufferInstance::verifyVertexWriteResults(IterateCommonVariables &variables)
2988 {
2989 auto &log = m_context.getTestContext().getLog();
2990 const tcu::Vec4 threshold(0.002f, 0.002f, 0.002f, 0.002f);
2991 const std::vector<uint32_t> primes = ut::generatePrimes(variables.availableDescriptorCount);
2992 unsigned char *buffer = static_cast<unsigned char *>(variables.descriptorsBuffer->alloc->getHostPtr());
2993 BindingStorageBufferData data;
2994
2995 log << tcu::TestLog::Message << "Available descriptor count: " << variables.availableDescriptorCount
2996 << tcu::TestLog::EndMessage;
2997 log << tcu::TestLog::Message << "Valid descriptor count: " << variables.validDescriptorCount
2998 << tcu::TestLog::EndMessage;
2999
3000 for (uint32_t primeIdx = 0; primeIdx < variables.validDescriptorCount; ++primeIdx)
3001 {
3002 const uint32_t prime = primes[primeIdx];
3003 const float component = m_colorScheme[(prime % variables.validDescriptorCount) % m_schemeSize];
3004 const tcu::Vec4 referenceValue(component, component, component, 1.0f);
3005
3006 VkDescriptorBufferInfo &info = variables.descriptorsBufferInfos[primeIdx];
3007 deMemcpy(&data, buffer + info.offset, sizeof(data));
3008 const tcu::Vec4 realValue = data.cnew;
3009
3010 const tcu::Vec4 diff = tcu::absDiff(referenceValue, realValue);
3011 if (!tcu::boolAll(tcu::lessThanEqual(diff, threshold)))
3012 {
3013 log << tcu::TestLog::Message << "Error in valid descriptor " << primeIdx << " (descriptor " << prime
3014 << "): expected " << referenceValue << " but found " << realValue << " (threshold " << threshold << ")"
3015 << tcu::TestLog::EndMessage;
3016
3017 return false;
3018 }
3019 }
3020 return true;
3021 }
3022
3023 class UniformBufferInstance : virtual public CommonDescriptorInstance
3024 {
3025 public:
3026 UniformBufferInstance(Context &context, const TestCaseParams &testCaseParams);
3027
3028 protected:
3029 void createAndPopulateDescriptors(IterateCommonVariables &variables) override;
3030 void createAndPopulateUnusedDescriptors(IterateCommonVariables &variables) override;
3031 };
3032
UniformBufferInstance(Context & context,const TestCaseParams & testCaseParams)3033 UniformBufferInstance::UniformBufferInstance(Context &context, const TestCaseParams &testCaseParams)
3034 : CommonDescriptorInstance(context, TestParams(VK_SHADER_STAGE_ALL_GRAPHICS, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
3035 VK_DESCRIPTOR_TYPE_UNDEFINED, false,
3036 performWritesInVertex(testCaseParams.descriptorType, context),
3037 testCaseParams))
3038 {
3039 }
3040
createAndPopulateDescriptors(IterateCommonVariables & variables)3041 void UniformBufferInstance::createAndPopulateDescriptors(IterateCommonVariables &variables)
3042 {
3043 BindingUniformBufferData data;
3044
3045 const uint32_t alignment = static_cast<uint32_t>(
3046 ut::DeviceProperties(m_context).physicalDeviceProperties().limits.minUniformBufferOffsetAlignment);
3047 createBuffers(variables.descriptorsBufferInfos, variables.descriptorsBuffer, variables.validDescriptorCount,
3048 sizeof(data), alignment, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
3049
3050 unsigned char *buffer = static_cast<unsigned char *>(variables.descriptorsBuffer->alloc->getHostPtr());
3051 for (uint32_t infoIdx = 0; infoIdx < variables.validDescriptorCount; ++infoIdx)
3052 {
3053 const float component = m_colorScheme[infoIdx % m_schemeSize];
3054 VkDescriptorBufferInfo &info = variables.descriptorsBufferInfos[infoIdx];
3055 data.c = tcu::Vec4(component, component, component, 1.0f);
3056 deMemcpy(buffer + info.offset, &data, sizeof(data));
3057 }
3058 vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3059
3060 variables.dataAlignment = deAlign64(sizeof(data), alignment);
3061 }
3062
createAndPopulateUnusedDescriptors(IterateCommonVariables & variables)3063 void UniformBufferInstance::createAndPopulateUnusedDescriptors(IterateCommonVariables &variables)
3064 {
3065 // Just create buffer for unused descriptors, no data needed
3066 const uint32_t alignment = static_cast<uint32_t>(
3067 ut::DeviceProperties(m_context).physicalDeviceProperties().limits.minUniformBufferOffsetAlignment);
3068 createBuffers(variables.unusedDescriptorsBufferInfos, variables.unusedDescriptorsBuffer, 1,
3069 sizeof(BindingUniformBufferData), alignment, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
3070 }
3071
3072 class StorageTexelInstance : public CommonDescriptorInstance
3073 {
3074 public:
3075 StorageTexelInstance(Context &context, const TestCaseParams &testCaseParams);
3076
3077 private:
3078 void createAndPopulateDescriptors(IterateCommonVariables &variables) override;
3079 void createAndPopulateUnusedDescriptors(IterateCommonVariables &variables) override;
3080
3081 bool verifyVertexWriteResults(IterateCommonVariables &variables) override;
3082 };
3083
StorageTexelInstance(Context & context,const TestCaseParams & testCaseParams)3084 StorageTexelInstance::StorageTexelInstance(Context &context, const TestCaseParams &testCaseParams)
3085 : CommonDescriptorInstance(
3086 context, TestParams(VK_SHADER_STAGE_ALL_GRAPHICS, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
3087 VK_DESCRIPTOR_TYPE_UNDEFINED, false,
3088 performWritesInVertex(testCaseParams.descriptorType, context), testCaseParams))
3089 {
3090 }
3091
createAndPopulateDescriptors(IterateCommonVariables & variables)3092 void StorageTexelInstance::createAndPopulateDescriptors(IterateCommonVariables &variables)
3093 {
3094 const VkExtent3D imageExtent = {4, 4, 1};
3095 const uint32_t imageSize = ut::computeImageSize(imageExtent, m_colorFormat);
3096
3097 createBuffers(variables.descriptorsBufferInfos, variables.descriptorsBuffer, variables.validDescriptorCount,
3098 imageSize, sizeof(tcu::Vec4), VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT);
3099 createBuffersViews(variables.descriptorsBufferViews, variables.descriptorsBufferInfos, m_colorFormat);
3100
3101 for (uint32_t imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
3102 {
3103 const float component = m_colorScheme[imageIdx % m_schemeSize];
3104 const PixelBufferAccess pa = getPixelAccess(imageIdx, imageExtent, m_colorFormat,
3105 variables.descriptorsBufferInfos, variables.descriptorsBuffer);
3106
3107 tcu::clear(pa, m_clearColor);
3108 pa.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
3109 }
3110 vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3111 }
3112
createAndPopulateUnusedDescriptors(IterateCommonVariables & variables)3113 void StorageTexelInstance::createAndPopulateUnusedDescriptors(IterateCommonVariables &variables)
3114 {
3115 const VkExtent3D imageExtent = {4, 4, 1};
3116 const uint32_t imageSize = ut::computeImageSize(imageExtent, m_colorFormat);
3117
3118 createBuffers(variables.unusedDescriptorsBufferInfos, variables.unusedDescriptorsBuffer, 1, imageSize,
3119 sizeof(tcu::Vec4), VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT);
3120 createBuffersViews(variables.unusedDescriptorsBufferViews, variables.unusedDescriptorsBufferInfos, m_colorFormat);
3121 }
3122
verifyVertexWriteResults(IterateCommonVariables & variables)3123 bool StorageTexelInstance::verifyVertexWriteResults(IterateCommonVariables &variables)
3124 {
3125 auto &log = m_context.getTestContext().getLog();
3126 const VkExtent3D imageExtent = {4, 4, 1};
3127 const tcu::Vec4 threshold(0.002f, 0.002f, 0.002f, 0.002f);
3128 const std::vector<uint32_t> primes = ut::generatePrimes(variables.availableDescriptorCount);
3129
3130 log << tcu::TestLog::Message << "Available descriptor count: " << variables.availableDescriptorCount
3131 << tcu::TestLog::EndMessage;
3132 log << tcu::TestLog::Message << "Valid descriptor count: " << variables.validDescriptorCount
3133 << tcu::TestLog::EndMessage;
3134
3135 for (uint32_t primeIdx = 0; primeIdx < variables.validDescriptorCount; ++primeIdx)
3136 {
3137 const uint32_t prime = primes[primeIdx];
3138 const float component = m_colorScheme[(prime % variables.validDescriptorCount) % m_schemeSize];
3139 const tcu::Vec4 referenceValue(component, component, component, 1.0f);
3140
3141 const PixelBufferAccess pa = getPixelAccess(primeIdx, imageExtent, m_colorFormat,
3142 variables.descriptorsBufferInfos, variables.descriptorsBuffer);
3143 const tcu::Vec4 realValue = pa.getPixel(1, 0);
3144
3145 const tcu::Vec4 diff = tcu::absDiff(referenceValue, realValue);
3146 if (!tcu::boolAll(tcu::lessThanEqual(diff, threshold)))
3147 {
3148 log << tcu::TestLog::Message << "Error in valid descriptor " << primeIdx << " (descriptor " << prime
3149 << "): expected " << referenceValue << " but found " << realValue << " (threshold " << threshold << ")"
3150 << tcu::TestLog::EndMessage;
3151
3152 return false;
3153 }
3154 }
3155 return true;
3156 }
3157
3158 class UniformTexelInstance : public CommonDescriptorInstance
3159 {
3160 public:
3161 UniformTexelInstance(Context &context, const TestCaseParams &testCaseParams);
3162
3163 private:
3164 void createAndPopulateDescriptors(IterateCommonVariables &variables) override;
3165 void createAndPopulateUnusedDescriptors(IterateCommonVariables &variables) override;
3166 };
3167
UniformTexelInstance(Context & context,const TestCaseParams & testCaseParams)3168 UniformTexelInstance::UniformTexelInstance(Context &context, const TestCaseParams &testCaseParams)
3169 : CommonDescriptorInstance(
3170 context, TestParams(VK_SHADER_STAGE_ALL_GRAPHICS, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
3171 VK_DESCRIPTOR_TYPE_UNDEFINED, false,
3172 performWritesInVertex(testCaseParams.descriptorType, context), testCaseParams))
3173 {
3174 }
3175
createAndPopulateDescriptors(IterateCommonVariables & variables)3176 void UniformTexelInstance::createAndPopulateDescriptors(IterateCommonVariables &variables)
3177 {
3178 const VkExtent3D imageExtent = {4, 4, 1};
3179 const uint32_t imageSize = ut::computeImageSize(imageExtent, m_colorFormat);
3180
3181 createBuffers(variables.descriptorsBufferInfos, variables.descriptorsBuffer, variables.validDescriptorCount,
3182 imageSize, sizeof(tcu::Vec4), VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT);
3183 createBuffersViews(variables.descriptorsBufferViews, variables.descriptorsBufferInfos, m_colorFormat);
3184
3185 for (uint32_t imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
3186 {
3187 const float component = m_colorScheme[imageIdx % m_schemeSize];
3188 const PixelBufferAccess pa = getPixelAccess(imageIdx, imageExtent, m_colorFormat,
3189 variables.descriptorsBufferInfos, variables.descriptorsBuffer);
3190
3191 tcu::clear(pa, tcu::Vec4(component, component, component, 1.0f));
3192 }
3193 vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3194 }
3195
createAndPopulateUnusedDescriptors(IterateCommonVariables & variables)3196 void UniformTexelInstance::createAndPopulateUnusedDescriptors(IterateCommonVariables &variables)
3197 {
3198 const VkExtent3D imageExtent = {4, 4, 1};
3199 const uint32_t imageSize = ut::computeImageSize(imageExtent, m_colorFormat);
3200
3201 createBuffers(variables.unusedDescriptorsBufferInfos, variables.unusedDescriptorsBuffer, 1, imageSize,
3202 sizeof(tcu::Vec4), VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT);
3203 createBuffersViews(variables.unusedDescriptorsBufferViews, variables.unusedDescriptorsBufferInfos, m_colorFormat);
3204 }
3205
3206 class DynamicBuffersInstance : virtual public CommonDescriptorInstance
3207 {
3208 public:
DynamicBuffersInstance(Context & context,const TestParams & testParams)3209 DynamicBuffersInstance(Context &context, const TestParams &testParams)
3210 : CommonDescriptorInstance(context, testParams)
3211 {
3212 }
3213
3214 protected:
3215 virtual tcu::TestStatus iterate(void);
3216 virtual void updateDescriptors(IterateCommonVariables &variables);
3217 };
3218
updateDescriptors(IterateCommonVariables & variables)3219 void DynamicBuffersInstance::updateDescriptors(IterateCommonVariables &variables)
3220 {
3221 DE_ASSERT(variables.dataAlignment);
3222
3223 VkDescriptorBufferInfo bufferInfo = {*variables.descriptorsBuffer.get()->buffer,
3224 0, // always 0, it will be taken from pDynamicOffsets
3225 variables.dataAlignment};
3226
3227 VkWriteDescriptorSet updateInfo = {
3228 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
3229 nullptr, // pNext
3230 *variables.descriptorSet, // descriptorSet
3231 BINDING_TestObject, // descriptorBinding;
3232 0, // to be set in below loop // dstArrayElement
3233 1u, // descriptorCount
3234 m_testParams.descriptorType, // descriptorType
3235 nullptr, // pImageInfo
3236 &bufferInfo, // pBufferInfo
3237 nullptr // pTexelBufferView
3238 };
3239
3240 uint32_t descIdx = 0;
3241 const std::vector<uint32_t> primes = ut::generatePrimes(variables.availableDescriptorCount);
3242 for (uint32_t validIdx = 0; validIdx < variables.validDescriptorCount; ++validIdx)
3243 {
3244 for (; descIdx < primes[validIdx]; ++descIdx)
3245 {
3246 updateInfo.dstArrayElement = descIdx;
3247 m_vki.updateDescriptorSets(m_vkd, 1u, &updateInfo, 0u, nullptr);
3248 }
3249
3250 updateInfo.dstArrayElement = primes[validIdx];
3251 m_vki.updateDescriptorSets(m_vkd, 1u, &updateInfo, 0u, nullptr);
3252
3253 ++descIdx;
3254 }
3255 for (; descIdx < variables.availableDescriptorCount; ++descIdx)
3256 {
3257 updateInfo.dstArrayElement = descIdx;
3258 m_vki.updateDescriptorSets(m_vkd, 1u, &updateInfo, 0u, nullptr);
3259 }
3260 }
3261
iterate(void)3262 tcu::TestStatus DynamicBuffersInstance::iterate(void)
3263 {
3264 IterateCommonVariables v;
3265 iterateCommandSetup(v);
3266
3267 ut::UpdatablePixelBufferAccessPtr programResult;
3268 ut::UpdatablePixelBufferAccessPtr referenceResult;
3269 bool firstPass = true;
3270
3271 DE_ASSERT(v.dataAlignment);
3272
3273 std::vector<uint32_t> dynamicOffsets;
3274
3275 uint32_t descIdx = 0;
3276 const std::vector<uint32_t> primes = ut::generatePrimes(v.availableDescriptorCount);
3277 for (uint32_t validIdx = 0; validIdx < v.validDescriptorCount; ++validIdx)
3278 {
3279 for (; descIdx < primes[validIdx]; ++descIdx)
3280 {
3281 dynamicOffsets.push_back(0);
3282 }
3283
3284 dynamicOffsets.push_back(static_cast<uint32_t>(validIdx * v.dataAlignment));
3285
3286 ++descIdx;
3287 }
3288 for (; descIdx < v.availableDescriptorCount; ++descIdx)
3289 {
3290 dynamicOffsets.push_back(0);
3291 }
3292
3293 // Unfortunatelly not lees and not more, only exactly
3294 DE_ASSERT(dynamicOffsets.size() == v.availableDescriptorCount);
3295
3296 const VkDescriptorSet descriptorSets[] = {*v.descriptorSet};
3297
3298 v.renderArea.extent.width = m_testParams.frameResolution.width / 4;
3299 v.renderArea.extent.height = m_testParams.frameResolution.height / 4;
3300
3301 for (int x = 0; x < 4; x++)
3302 for (int y = 0; y < 4; y++)
3303 {
3304 v.renderArea.offset.x = x * m_testParams.frameResolution.width / 4;
3305 v.renderArea.offset.y = y * m_testParams.frameResolution.height / 4;
3306
3307 iterateCommandBegin(v, firstPass);
3308 firstPass = false;
3309
3310 m_vki.cmdBindDescriptorSets(*v.commandBuffer, // commandBuffer
3311 VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
3312 *v.pipelineLayout, // layout
3313 0u, // firstSet
3314 DE_LENGTH_OF_ARRAY(descriptorSets), // descriptorSetCount
3315 descriptorSets, // pDescriptorSets
3316 v.availableDescriptorCount, // dynamicOffsetCount
3317 dynamicOffsets.data()); // pDynamicOffsets
3318
3319 vk::VkRect2D scissor = makeRect2D(v.renderArea.offset.x, v.renderArea.offset.y, v.renderArea.extent.width,
3320 v.renderArea.extent.height);
3321 m_vki.cmdSetScissor(*v.commandBuffer, 0u, 1u, &scissor);
3322
3323 vk::beginRenderPass(m_vki, *v.commandBuffer, *v.renderPass, *v.frameBuffer->buffer, v.renderArea,
3324 m_clearColor);
3325 m_vki.cmdDraw(*v.commandBuffer, v.vertexCount, 1u, 0u, 0u);
3326 vk::endRenderPass(m_vki, *v.commandBuffer);
3327
3328 iterateCommandEnd(v, programResult, referenceResult);
3329 programResult->invalidate();
3330 }
3331
3332 if (iterateVerifyResults(v, programResult, referenceResult))
3333 return tcu::TestStatus::pass("Pass");
3334 return tcu::TestStatus::fail("Failed -- check log for details");
3335 }
3336
3337 class DynamicStorageBufferInstance : public DynamicBuffersInstance, public StorageBufferInstance
3338 {
3339 public:
3340 DynamicStorageBufferInstance(Context &context, const TestCaseParams &testCaseParams);
3341 tcu::TestStatus iterate(void) override;
3342 void createAndPopulateDescriptors(IterateCommonVariables &variables) override;
3343 void createAndPopulateUnusedDescriptors(IterateCommonVariables &variables) override;
3344 void updateDescriptors(IterateCommonVariables &variables) override;
3345 bool verifyVertexWriteResults(IterateCommonVariables &variables) override;
3346 };
3347
DynamicStorageBufferInstance(Context & context,const TestCaseParams & testCaseParams)3348 DynamicStorageBufferInstance::DynamicStorageBufferInstance(Context &context, const TestCaseParams &testCaseParams)
3349 : CommonDescriptorInstance(
3350 context, TestParams(VK_SHADER_STAGE_ALL_GRAPHICS, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC,
3351 VK_DESCRIPTOR_TYPE_UNDEFINED, false,
3352 performWritesInVertex(testCaseParams.descriptorType, context), testCaseParams))
3353 , DynamicBuffersInstance(context, m_testParams)
3354 , StorageBufferInstance(context, testCaseParams)
3355 {
3356 }
3357
iterate(void)3358 tcu::TestStatus DynamicStorageBufferInstance::iterate(void)
3359 {
3360 return DynamicBuffersInstance::iterate();
3361 }
3362
createAndPopulateDescriptors(IterateCommonVariables & variables)3363 void DynamicStorageBufferInstance::createAndPopulateDescriptors(IterateCommonVariables &variables)
3364 {
3365 StorageBufferInstance::createAndPopulateDescriptors(variables);
3366 }
3367
createAndPopulateUnusedDescriptors(IterateCommonVariables & variables)3368 void DynamicStorageBufferInstance::createAndPopulateUnusedDescriptors(IterateCommonVariables &variables)
3369 {
3370 StorageBufferInstance::createAndPopulateUnusedDescriptors(variables);
3371 }
3372
updateDescriptors(IterateCommonVariables & variables)3373 void DynamicStorageBufferInstance::updateDescriptors(IterateCommonVariables &variables)
3374 {
3375 DynamicBuffersInstance::updateDescriptors(variables);
3376 }
3377
verifyVertexWriteResults(IterateCommonVariables & variables)3378 bool DynamicStorageBufferInstance::verifyVertexWriteResults(IterateCommonVariables &variables)
3379 {
3380 return StorageBufferInstance::verifyVertexWriteResults(variables);
3381 }
3382
3383 class DynamicUniformBufferInstance : public DynamicBuffersInstance, public UniformBufferInstance
3384 {
3385 public:
3386 DynamicUniformBufferInstance(Context &context, const TestCaseParams &testCaseParams);
3387 tcu::TestStatus iterate(void) override;
3388 void createAndPopulateDescriptors(IterateCommonVariables &variables) override;
3389 void createAndPopulateUnusedDescriptors(IterateCommonVariables &variables) override;
3390 void updateDescriptors(IterateCommonVariables &variables) override;
3391 };
3392
DynamicUniformBufferInstance(Context & context,const TestCaseParams & testCaseParams)3393 DynamicUniformBufferInstance::DynamicUniformBufferInstance(Context &context, const TestCaseParams &testCaseParams)
3394 : CommonDescriptorInstance(
3395 context, TestParams(VK_SHADER_STAGE_ALL_GRAPHICS, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
3396 VK_DESCRIPTOR_TYPE_UNDEFINED, false,
3397 performWritesInVertex(testCaseParams.descriptorType, context), testCaseParams))
3398 , DynamicBuffersInstance(context, m_testParams)
3399 , UniformBufferInstance(context, testCaseParams)
3400 {
3401 }
3402
iterate(void)3403 tcu::TestStatus DynamicUniformBufferInstance::iterate(void)
3404 {
3405 return DynamicBuffersInstance::iterate();
3406 }
3407
createAndPopulateDescriptors(IterateCommonVariables & variables)3408 void DynamicUniformBufferInstance::createAndPopulateDescriptors(IterateCommonVariables &variables)
3409 {
3410 UniformBufferInstance::createAndPopulateDescriptors(variables);
3411 }
3412
createAndPopulateUnusedDescriptors(IterateCommonVariables & variables)3413 void DynamicUniformBufferInstance::createAndPopulateUnusedDescriptors(IterateCommonVariables &variables)
3414 {
3415 UniformBufferInstance::createAndPopulateUnusedDescriptors(variables);
3416 }
3417
updateDescriptors(IterateCommonVariables & variables)3418 void DynamicUniformBufferInstance::updateDescriptors(IterateCommonVariables &variables)
3419 {
3420 DynamicBuffersInstance::updateDescriptors(variables);
3421 }
3422
3423 class InputAttachmentInstance : public CommonDescriptorInstance
3424 {
3425 public:
3426 InputAttachmentInstance(Context &context, const TestCaseParams &testCaseParams);
3427
3428 private:
3429 Move<VkRenderPass> createRenderPass(const IterateCommonVariables &variables) override;
3430 void createFramebuffer(ut::FrameBufferSp &frameBuffer, VkRenderPass renderPass,
3431 const IterateCommonVariables &variables) override;
3432 void createAndPopulateDescriptors(IterateCommonVariables &variables) override;
3433 void createAndPopulateUnusedDescriptors(IterateCommonVariables &variables) override;
3434 };
3435
InputAttachmentInstance(Context & context,const TestCaseParams & testCaseParams)3436 InputAttachmentInstance::InputAttachmentInstance(Context &context, const TestCaseParams &testCaseParams)
3437 : CommonDescriptorInstance(context, TestParams(VK_SHADER_STAGE_ALL_GRAPHICS, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
3438 VK_DESCRIPTOR_TYPE_UNDEFINED, true,
3439 performWritesInVertex(testCaseParams.descriptorType, context),
3440 testCaseParams))
3441 {
3442 }
3443
createAndPopulateDescriptors(IterateCommonVariables & variables)3444 void InputAttachmentInstance::createAndPopulateDescriptors(IterateCommonVariables &variables)
3445 {
3446 createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer,
3447 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, m_testParams.frameResolution, m_colorFormat,
3448 VK_IMAGE_LAYOUT_UNDEFINED, variables.validDescriptorCount);
3449 createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, m_colorFormat);
3450
3451 for (uint32_t descriptorIdx = 0; descriptorIdx < variables.validDescriptorCount; ++descriptorIdx)
3452 {
3453 const float component = m_colorScheme[descriptorIdx % m_schemeSize];
3454 const tcu::PixelBufferAccess pa = getPixelAccess(descriptorIdx, m_testParams.frameResolution, m_colorFormat,
3455 variables.descriptorsBufferInfos, variables.descriptorsBuffer);
3456 tcu::clear(pa, tcu::Vec4(component, component, component, 1.0f));
3457 }
3458 vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3459 }
3460
createAndPopulateUnusedDescriptors(IterateCommonVariables & variables)3461 void InputAttachmentInstance::createAndPopulateUnusedDescriptors(IterateCommonVariables &variables)
3462 {
3463 createImages(variables.unusedDescriptorsImages, variables.unusedDescriptorsBufferInfos,
3464 variables.unusedDescriptorsBuffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, m_testParams.frameResolution,
3465 m_colorFormat, VK_IMAGE_LAYOUT_UNDEFINED, 1);
3466 createImagesViews(variables.unusedDescriptorImageViews, variables.unusedDescriptorsImages, m_colorFormat);
3467 }
3468
createRenderPass(const IterateCommonVariables & variables)3469 Move<VkRenderPass> InputAttachmentInstance::createRenderPass(const IterateCommonVariables &variables)
3470 {
3471 std::vector<VkAttachmentDescription> attachmentDescriptions;
3472 std::vector<VkAttachmentReference> inputAttachmentRefs;
3473
3474 const VkAttachmentDescription colorAttachmentDescription = {
3475 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
3476 m_colorFormat, // VkFormat format;
3477 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
3478 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
3479 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
3480 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
3481 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
3482 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
3483 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
3484 };
3485 const VkAttachmentReference colorAttachmentRef = {
3486 0u, // uint32_t attachment;
3487 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
3488 };
3489 attachmentDescriptions.push_back(colorAttachmentDescription);
3490
3491 // build input atachments
3492 {
3493 const std::vector<uint32_t> primes = ut::generatePrimes(variables.availableDescriptorCount);
3494 const uint32_t inputCount = static_cast<uint32_t>(variables.descriptorImageViews.size());
3495 for (uint32_t inputIdx = 0; inputIdx < inputCount; ++inputIdx)
3496 {
3497 // primes holds the indices of input attachments for shader binding 10 which has input_attachment_index=1
3498 uint32_t nextInputAttachmentIndex = primes[inputIdx] + 1;
3499
3500 // Fill up the subpass description's input attachments with unused attachments forming gaps to the next referenced attachment
3501 for (uint32_t unusedIdx = static_cast<uint32_t>(inputAttachmentRefs.size());
3502 unusedIdx < nextInputAttachmentIndex; ++unusedIdx)
3503 {
3504 const VkAttachmentReference inputAttachmentRef = {
3505 VK_ATTACHMENT_UNUSED, // uint32_t attachment;
3506 VK_IMAGE_LAYOUT_GENERAL // VkImageLayout layout;
3507 };
3508
3509 inputAttachmentRefs.push_back(inputAttachmentRef);
3510 }
3511
3512 const VkAttachmentDescription inputAttachmentDescription = {
3513 VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT, // VkAttachmentDescriptionFlags flags;
3514 variables.descriptorsImages[inputIdx]->format, // VkFormat format;
3515 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
3516 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
3517 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
3518 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
3519 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
3520 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout initialLayout;
3521 VK_IMAGE_LAYOUT_GENERAL // VkImageLayout finalLayout;
3522 };
3523
3524 const VkAttachmentReference inputAttachmentRef = {
3525 inputIdx + 1, // uint32_t attachment;
3526 VK_IMAGE_LAYOUT_GENERAL // VkImageLayout layout;
3527 };
3528
3529 inputAttachmentRefs.push_back(inputAttachmentRef);
3530 attachmentDescriptions.push_back(inputAttachmentDescription);
3531 }
3532 }
3533
3534 const VkSubpassDescription subpassDescription = {
3535 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
3536 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
3537 static_cast<uint32_t>(inputAttachmentRefs.size()), // uint32_t inputAttachmentCount;
3538 inputAttachmentRefs.data(), // const VkAttachmentReference* pInputAttachments;
3539 1u, // uint32_t colorAttachmentCount;
3540 &colorAttachmentRef, // const VkAttachmentReference* pColorAttachments;
3541 nullptr, // const VkAttachmentReference* pResolveAttachments;
3542 nullptr, // const VkAttachmentReference* pDepthStencilAttachment;
3543 0u, // uint32_t preserveAttachmentCount;
3544 nullptr // const uint32_t* pPreserveAttachments;
3545 };
3546
3547 const VkRenderPassCreateInfo renderPassInfo = {
3548 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
3549 nullptr, // const void* pNext;
3550 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
3551 static_cast<uint32_t>(attachmentDescriptions.size()), // uint32_t attachmentCount;
3552 attachmentDescriptions.data(), // const VkAttachmentDescription* pAttachments;
3553 1u, // uint32_t subpassCount;
3554 &subpassDescription, // const VkSubpassDescription* pSubpasses;
3555 0u, // uint32_t dependencyCount;
3556 nullptr // const VkSubpassDependency* pDependencies;
3557 };
3558
3559 return vk::createRenderPass(m_vki, m_vkd, &renderPassInfo);
3560 }
3561
createFramebuffer(ut::FrameBufferSp & frameBuffer,VkRenderPass renderPass,const IterateCommonVariables & variables)3562 void InputAttachmentInstance::createFramebuffer(ut::FrameBufferSp &frameBuffer, VkRenderPass renderPass,
3563 const IterateCommonVariables &variables)
3564 {
3565 std::vector<VkImageView> inputAttachments;
3566 const uint32_t viewCount = static_cast<uint32_t>(variables.descriptorImageViews.size());
3567 inputAttachments.resize(viewCount);
3568 for (uint32_t viewIdx = 0; viewIdx < viewCount; ++viewIdx)
3569 {
3570 inputAttachments[viewIdx] = **variables.descriptorImageViews[viewIdx];
3571 }
3572 ut::createFrameBuffer(frameBuffer, m_context, m_testParams.frameResolution, m_colorFormat, renderPass, viewCount,
3573 inputAttachments.data());
3574 }
3575
3576 class SamplerInstance : public CommonDescriptorInstance
3577 {
3578 public:
3579 SamplerInstance(Context &context, const TestCaseParams &testCaseParams);
3580
3581 private:
3582 void createAndPopulateDescriptors(IterateCommonVariables &variables) override;
3583 void createAndPopulateUnusedDescriptors(IterateCommonVariables &variables) override;
3584 void updateDescriptors(IterateCommonVariables &variables) override;
3585 };
3586
SamplerInstance(Context & context,const TestCaseParams & testCaseParams)3587 SamplerInstance::SamplerInstance(Context &context, const TestCaseParams &testCaseParams)
3588 : CommonDescriptorInstance(context, TestParams(VK_SHADER_STAGE_ALL_GRAPHICS, VK_DESCRIPTOR_TYPE_SAMPLER,
3589 VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, true,
3590 performWritesInVertex(testCaseParams.descriptorType, context),
3591 testCaseParams))
3592 {
3593 }
3594
updateDescriptors(IterateCommonVariables & variables)3595 void SamplerInstance::updateDescriptors(IterateCommonVariables &variables)
3596 {
3597 DE_ASSERT(variables.descriptorsImages.size() == 1);
3598 DE_ASSERT(variables.descriptorImageViews.size() == 1);
3599 DE_ASSERT(variables.descriptorsBufferInfos.size() == 1);
3600 DE_ASSERT(m_testParams.additionalDescriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
3601 DE_ASSERT(variables.descriptorSamplers.size() == variables.validDescriptorCount);
3602
3603 // update an image
3604 {
3605 const VkDescriptorImageInfo imageInfo = {static_cast<VkSampler>(0), **variables.descriptorImageViews[0],
3606 VK_IMAGE_LAYOUT_GENERAL};
3607
3608 const VkWriteDescriptorSet writeInfo = {
3609 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
3610 nullptr, // pNext
3611 *variables.descriptorSet, // descriptorSet
3612 BINDING_Additional, // descriptorBinding;
3613 0, // elementIndex
3614 1u, // descriptorCount
3615 VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, // descriptorType
3616 &imageInfo, // pImageInfo
3617 nullptr, // pBufferInfo
3618 nullptr // pTexelBufferView
3619 };
3620
3621 m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, nullptr);
3622 }
3623
3624 // update samplers
3625 CommonDescriptorInstance::updateDescriptors(variables);
3626 }
3627
createAndPopulateDescriptors(IterateCommonVariables & variables)3628 void SamplerInstance::createAndPopulateDescriptors(IterateCommonVariables &variables)
3629 {
3630 DE_ASSERT(variables.descriptorsImages.size() == 0);
3631 DE_ASSERT(variables.descriptorImageViews.size() == 0);
3632 DE_ASSERT(variables.descriptorsBufferInfos.size() == 0);
3633 DE_ASSERT(variables.descriptorSamplers.size() == 0);
3634
3635 // create and populate an image
3636 {
3637 VkExtent3D imageExtent = m_testParams.frameResolution;
3638 if (m_testParams.usesMipMaps)
3639 {
3640 imageExtent.width *= 2;
3641 imageExtent.height *= 2;
3642 }
3643
3644 createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer,
3645 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, imageExtent, m_colorFormat, VK_IMAGE_LAYOUT_UNDEFINED, 1,
3646 m_testParams.usesMipMaps);
3647 createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, m_colorFormat);
3648
3649 PixelBufferAccess pa = getPixelAccess(0, imageExtent, m_colorFormat, variables.descriptorsBufferInfos,
3650 variables.descriptorsBuffer, m_testParams.usesMipMaps ? 1 : 0);
3651
3652 for (uint32_t y = 0, pixelNum = 0; y < m_testParams.frameResolution.height; ++y)
3653 {
3654 for (uint32_t x = 0; x < m_testParams.frameResolution.width; ++x, ++pixelNum)
3655 {
3656 const float component = m_colorScheme[(pixelNum % variables.validDescriptorCount) % m_schemeSize];
3657 pa.setPixel(tcu::Vec4(component, component, component, 1.0f), x, y);
3658 }
3659 }
3660
3661 vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3662 }
3663
3664 const tcu::Sampler sampler(
3665 tcu::Sampler::CLAMP_TO_BORDER, // wrapS
3666 tcu::Sampler::CLAMP_TO_BORDER, // wrapT
3667 tcu::Sampler::CLAMP_TO_BORDER, // wrapR
3668 m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST, // minFilter
3669 m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST, // magFilter
3670 0.0f, // lodTreshold
3671 true, // normalizeCoords
3672 tcu::Sampler::COMPAREMODE_NONE, // compare
3673 0, // compareChannel
3674 tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), // borderColor
3675 true); // seamlessCubeMap
3676 const VkSamplerCreateInfo createInfo = vk::mapSampler(sampler, vk::mapVkFormat(m_colorFormat));
3677 variables.descriptorSamplers.resize(variables.validDescriptorCount);
3678
3679 for (uint32_t samplerIdx = 0; samplerIdx < variables.validDescriptorCount; ++samplerIdx)
3680 {
3681 variables.descriptorSamplers[samplerIdx] =
3682 ut::SamplerSp(new Move<VkSampler>(vk::createSampler(m_vki, m_vkd, &createInfo)));
3683 }
3684 }
3685
createAndPopulateUnusedDescriptors(IterateCommonVariables & variables)3686 void SamplerInstance::createAndPopulateUnusedDescriptors(IterateCommonVariables &variables)
3687 {
3688 DE_ASSERT(variables.unusedDescriptorsImages.size() == 0);
3689 DE_ASSERT(variables.unusedDescriptorImageViews.size() == 0);
3690 DE_ASSERT(variables.unusedDescriptorsBufferInfos.size() == 0);
3691 DE_ASSERT(variables.unusedDescriptorSamplers.size() == 0);
3692
3693 // create and populate an image
3694 {
3695 VkExtent3D imageExtent = m_testParams.frameResolution;
3696 if (m_testParams.usesMipMaps)
3697 {
3698 imageExtent.width *= 2;
3699 imageExtent.height *= 2;
3700 }
3701
3702 createImages(variables.unusedDescriptorsImages, variables.unusedDescriptorsBufferInfos,
3703 variables.unusedDescriptorsBuffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, imageExtent, m_colorFormat,
3704 VK_IMAGE_LAYOUT_UNDEFINED, 1, m_testParams.usesMipMaps);
3705 createImagesViews(variables.unusedDescriptorImageViews, variables.unusedDescriptorsImages, m_colorFormat);
3706 }
3707
3708 const tcu::Sampler sampler(
3709 tcu::Sampler::CLAMP_TO_BORDER, // wrapS
3710 tcu::Sampler::CLAMP_TO_BORDER, // wrapT
3711 tcu::Sampler::CLAMP_TO_BORDER, // wrapR
3712 m_testParams.usesMipMaps ? tcu::Sampler::LINEAR_MIPMAP_NEAREST : tcu::Sampler::NEAREST, // minFilter
3713 m_testParams.usesMipMaps ? tcu::Sampler::LINEAR_MIPMAP_NEAREST : tcu::Sampler::NEAREST, // magFilter
3714 0.0f, // lodTreshold
3715 true, // normalizeCoords
3716 tcu::Sampler::COMPAREMODE_NONE, // compare
3717 0, // compareChannel
3718 tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), // borderColor
3719 true); // seamlessCubeMap
3720 const VkSamplerCreateInfo createInfo = vk::mapSampler(sampler, vk::mapVkFormat(m_colorFormat));
3721 variables.unusedDescriptorSamplers.resize(1);
3722 variables.unusedDescriptorSamplers[0] =
3723 ut::SamplerSp(new Move<VkSampler>(vk::createSampler(m_vki, m_vkd, &createInfo)));
3724 }
3725
3726 class SampledImageInstance : public CommonDescriptorInstance
3727 {
3728 public:
3729 SampledImageInstance(Context &context, const TestCaseParams &testCaseParams);
3730
3731 private:
3732 void createAndPopulateDescriptors(IterateCommonVariables &variables) override;
3733 void createAndPopulateUnusedDescriptors(IterateCommonVariables &variables) override;
3734 void updateDescriptors(IterateCommonVariables &variables) override;
3735 };
3736
SampledImageInstance(Context & context,const TestCaseParams & testCaseParams)3737 SampledImageInstance::SampledImageInstance(Context &context, const TestCaseParams &testCaseParams)
3738 : CommonDescriptorInstance(context, TestParams(VK_SHADER_STAGE_ALL_GRAPHICS, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
3739 VK_DESCRIPTOR_TYPE_SAMPLER, true,
3740 performWritesInVertex(testCaseParams.descriptorType, context),
3741 testCaseParams))
3742 {
3743 }
3744
updateDescriptors(IterateCommonVariables & variables)3745 void SampledImageInstance::updateDescriptors(IterateCommonVariables &variables)
3746 {
3747 DE_ASSERT(variables.descriptorSamplers.size() == 1);
3748 DE_ASSERT(variables.descriptorsImages.size() == variables.validDescriptorCount);
3749 DE_ASSERT(variables.descriptorImageViews.size() == variables.validDescriptorCount);
3750 DE_ASSERT(variables.descriptorsBufferInfos.size() == variables.validDescriptorCount);
3751
3752 // update a sampler
3753 {
3754 const VkDescriptorImageInfo samplerInfo = {**variables.descriptorSamplers[0], static_cast<VkImageView>(0),
3755 static_cast<VkImageLayout>(0)};
3756
3757 const VkWriteDescriptorSet writeInfo = {
3758 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
3759 nullptr, // pNext
3760 *variables.descriptorSet, // descriptorSet
3761 BINDING_Additional, // descriptorBinding;
3762 0, // elementIndex
3763 1u, // descriptorCount
3764 VK_DESCRIPTOR_TYPE_SAMPLER, // descriptorType
3765 &samplerInfo, // pImageInfo
3766 nullptr, // pBufferInfo
3767 nullptr // pTexelBufferView
3768 };
3769
3770 m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, nullptr);
3771 }
3772
3773 // update images
3774 CommonDescriptorInstance::updateDescriptors(variables);
3775 }
3776
createAndPopulateDescriptors(IterateCommonVariables & variables)3777 void SampledImageInstance::createAndPopulateDescriptors(IterateCommonVariables &variables)
3778 {
3779 DE_ASSERT(variables.descriptorSamplers.size() == 0);
3780 DE_ASSERT(variables.descriptorsImages.size() == 0);
3781 DE_ASSERT(variables.descriptorImageViews.size() == 0);
3782 DE_ASSERT(variables.descriptorsBufferInfos.size() == 0);
3783
3784 // create an only one sampler for all images
3785 {
3786 const tcu::Sampler sampler(
3787 tcu::Sampler::CLAMP_TO_BORDER, // wrapS
3788 tcu::Sampler::CLAMP_TO_BORDER, // wrapT
3789 tcu::Sampler::CLAMP_TO_BORDER, // wrapR
3790 m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST, // minFilter
3791 m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST, // magFilter
3792 0.0f, // lodTreshold
3793 true, // normalizeCoords
3794 tcu::Sampler::COMPAREMODE_NONE, // compare
3795 0, // compareChannel
3796 tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), // borderColor
3797 true); // seamlessCubeMap
3798 const VkSamplerCreateInfo createInfo = vk::mapSampler(sampler, vk::mapVkFormat(m_colorFormat));
3799 variables.descriptorSamplers.push_back(
3800 ut::SamplerSp(new Move<VkSampler>(vk::createSampler(m_vki, m_vkd, &createInfo))));
3801 }
3802
3803 const VkExtent3D &imageExtent = m_testParams.usesMipMaps ? bigImageExtent : smallImageExtent;
3804
3805 createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer,
3806 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, imageExtent, m_colorFormat, VK_IMAGE_LAYOUT_UNDEFINED,
3807 variables.validDescriptorCount, m_testParams.usesMipMaps);
3808 createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, m_colorFormat);
3809
3810 PixelBufferAccess pixelAccess;
3811 for (uint32_t imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
3812 {
3813 const float component = m_colorScheme[imageIdx % m_schemeSize];
3814
3815 if (m_testParams.usesMipMaps)
3816 {
3817 const uint32_t mipCount = ut::computeMipMapCount(imageExtent);
3818 DE_ASSERT(mipCount >= 2);
3819 for (uint32_t mipIdx = 0; mipIdx < mipCount; ++mipIdx)
3820 {
3821 pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos,
3822 variables.descriptorsBuffer, mipIdx);
3823 tcu::clear(pixelAccess, m_clearColor);
3824 }
3825
3826 pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos,
3827 variables.descriptorsBuffer, mipCount - 1);
3828 pixelAccess.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
3829 }
3830 else
3831 {
3832 pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos,
3833 variables.descriptorsBuffer, 0);
3834 pixelAccess.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
3835 }
3836 }
3837 vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3838 }
3839
createAndPopulateUnusedDescriptors(IterateCommonVariables & variables)3840 void SampledImageInstance::createAndPopulateUnusedDescriptors(IterateCommonVariables &variables)
3841 {
3842 DE_ASSERT(variables.unusedDescriptorSamplers.size() == 0);
3843 DE_ASSERT(variables.unusedDescriptorsImages.size() == 0);
3844 DE_ASSERT(variables.unusedDescriptorImageViews.size() == 0);
3845 DE_ASSERT(variables.unusedDescriptorsBufferInfos.size() == 0);
3846
3847 // create an only one sampler for all images
3848 {
3849 const tcu::Sampler sampler(
3850 tcu::Sampler::CLAMP_TO_BORDER, // wrapS
3851 tcu::Sampler::CLAMP_TO_BORDER, // wrapT
3852 tcu::Sampler::CLAMP_TO_BORDER, // wrapR
3853 m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST, // minFilter
3854 m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST, // magFilter
3855 0.0f, // lodTreshold
3856 true, // normalizeCoords
3857 tcu::Sampler::COMPAREMODE_NONE, // compare
3858 0, // compareChannel
3859 tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), // borderColor
3860 true); // seamlessCubeMap
3861 const VkSamplerCreateInfo createInfo = vk::mapSampler(sampler, vk::mapVkFormat(m_colorFormat));
3862 variables.unusedDescriptorSamplers.push_back(
3863 ut::SamplerSp(new Move<VkSampler>(vk::createSampler(m_vki, m_vkd, &createInfo))));
3864 }
3865
3866 const VkExtent3D &imageExtent = m_testParams.usesMipMaps ? bigImageExtent : smallImageExtent;
3867
3868 createImages(variables.unusedDescriptorsImages, variables.unusedDescriptorsBufferInfos,
3869 variables.unusedDescriptorsBuffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, imageExtent, m_colorFormat,
3870 VK_IMAGE_LAYOUT_UNDEFINED, 1, m_testParams.usesMipMaps);
3871 createImagesViews(variables.unusedDescriptorImageViews, variables.unusedDescriptorsImages, m_colorFormat);
3872 }
3873
3874 class CombinedImageInstance : public CommonDescriptorInstance
3875 {
3876 public:
3877 CombinedImageInstance(Context &context, const TestCaseParams &testCaseParams);
3878
3879 private:
3880 void createAndPopulateDescriptors(IterateCommonVariables &variables) override;
3881 void createAndPopulateUnusedDescriptors(IterateCommonVariables &variables) override;
3882 void updateDescriptors(IterateCommonVariables &variables) override;
3883 };
3884
CombinedImageInstance(Context & context,const TestCaseParams & testCaseParams)3885 CombinedImageInstance::CombinedImageInstance(Context &context, const TestCaseParams &testCaseParams)
3886 : CommonDescriptorInstance(
3887 context, TestParams(VK_SHADER_STAGE_ALL_GRAPHICS, testCaseParams.descriptorType, VK_DESCRIPTOR_TYPE_UNDEFINED,
3888 true, performWritesInVertex(testCaseParams.descriptorType), testCaseParams))
3889 {
3890 }
3891
updateDescriptors(IterateCommonVariables & variables)3892 void CombinedImageInstance::updateDescriptors(IterateCommonVariables &variables)
3893 {
3894 const std::vector<uint32_t> primes = ut::generatePrimes(variables.availableDescriptorCount);
3895 const uint32_t primeCount = static_cast<uint32_t>(primes.size());
3896
3897 DE_ASSERT(variables.descriptorSamplers.size() == 1);
3898 DE_ASSERT(variables.descriptorsImages.size() == primeCount);
3899 DE_ASSERT(variables.descriptorImageViews.size() == primeCount);
3900 DE_ASSERT(variables.descriptorsBufferInfos.size() == primeCount);
3901
3902 for (uint32_t primeIdx = 0; primeIdx < primeCount; ++primeIdx)
3903 {
3904 const VkDescriptorImageInfo imageInfo = {**variables.descriptorSamplers[0],
3905 **variables.descriptorImageViews[primeIdx], VK_IMAGE_LAYOUT_GENERAL};
3906
3907 const VkWriteDescriptorSet writeInfo = {
3908 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
3909 nullptr, // pNext
3910 *variables.descriptorSet, // descriptorSet
3911 BINDING_TestObject, // descriptorBinding;
3912 primes[primeIdx], // elementIndex
3913 1u, // descriptorCount
3914 m_testParams.descriptorType, // descriptorType
3915 &imageInfo, // pImageInfo
3916 nullptr, // pBufferInfo
3917 nullptr // pTexelBufferView
3918 };
3919
3920 m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, nullptr);
3921 }
3922 }
3923
createAndPopulateDescriptors(IterateCommonVariables & variables)3924 void CombinedImageInstance::createAndPopulateDescriptors(IterateCommonVariables &variables)
3925 {
3926 DE_ASSERT(variables.descriptorSamplers.size() == 0);
3927 DE_ASSERT(variables.descriptorsImages.size() == 0);
3928 DE_ASSERT(variables.descriptorImageViews.size() == 0);
3929 DE_ASSERT(variables.descriptorsBufferInfos.size() == 0);
3930 DE_ASSERT(variables.descriptorSamplers.size() == 0);
3931
3932 const tcu::Sampler sampler(
3933 tcu::Sampler::CLAMP_TO_BORDER, // wrapS
3934 tcu::Sampler::CLAMP_TO_BORDER, // wrapT
3935 tcu::Sampler::CLAMP_TO_BORDER, // wrapR
3936 m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST, // minFilter
3937 m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST, // magFilter
3938 0.0f, // lodTreshold
3939 true, // normalizeCoords
3940 tcu::Sampler::COMPAREMODE_NONE, // compare
3941 0, // compareChannel
3942 tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), // borderColor
3943 true); // seamlessCubeMap
3944 const VkSamplerCreateInfo createInfo = vk::mapSampler(sampler, vk::mapVkFormat(m_colorFormat));
3945 variables.descriptorSamplers.push_back(
3946 ut::SamplerSp(new Move<VkSampler>(vk::createSampler(m_vki, m_vkd, &createInfo))));
3947
3948 const VkExtent3D &imageExtent = m_testParams.usesMipMaps ? bigImageExtent : smallImageExtent;
3949 createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer,
3950 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, imageExtent, m_colorFormat, VK_IMAGE_LAYOUT_UNDEFINED,
3951 variables.validDescriptorCount, m_testParams.usesMipMaps);
3952 createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, m_colorFormat);
3953
3954 PixelBufferAccess pixelAccess;
3955 for (uint32_t imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
3956 {
3957 const float component = m_colorScheme[imageIdx % m_schemeSize];
3958
3959 if (m_testParams.usesMipMaps)
3960 {
3961 const uint32_t mipCount = ut::computeMipMapCount(imageExtent);
3962 DE_ASSERT(mipCount >= 2);
3963 for (uint32_t mipIdx = 0; mipIdx < mipCount; ++mipIdx)
3964 {
3965 pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos,
3966 variables.descriptorsBuffer, mipIdx);
3967 tcu::clear(pixelAccess, m_clearColor);
3968 }
3969
3970 pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos,
3971 variables.descriptorsBuffer, mipCount - 1);
3972 pixelAccess.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
3973 }
3974 else
3975 {
3976 pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos,
3977 variables.descriptorsBuffer, 0);
3978 pixelAccess.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
3979 }
3980 }
3981
3982 vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3983 }
3984
createAndPopulateUnusedDescriptors(IterateCommonVariables & variables)3985 void CombinedImageInstance::createAndPopulateUnusedDescriptors(IterateCommonVariables &variables)
3986 {
3987 DE_ASSERT(variables.unusedDescriptorSamplers.size() == 0);
3988 DE_ASSERT(variables.unusedDescriptorsImages.size() == 0);
3989 DE_ASSERT(variables.unusedDescriptorImageViews.size() == 0);
3990 DE_ASSERT(variables.unusedDescriptorsBufferInfos.size() == 0);
3991 DE_ASSERT(variables.unusedDescriptorSamplers.size() == 0);
3992
3993 const tcu::Sampler sampler(
3994 tcu::Sampler::CLAMP_TO_BORDER, // wrapS
3995 tcu::Sampler::CLAMP_TO_BORDER, // wrapT
3996 tcu::Sampler::CLAMP_TO_BORDER, // wrapR
3997 m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST, // minFilter
3998 m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST, // magFilter
3999 0.0f, // lodTreshold
4000 true, // normalizeCoords
4001 tcu::Sampler::COMPAREMODE_NONE, // compare
4002 0, // compareChannel
4003 tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), // borderColor
4004 true); // seamlessCubeMap
4005 const VkSamplerCreateInfo createInfo = vk::mapSampler(sampler, vk::mapVkFormat(m_colorFormat));
4006 variables.unusedDescriptorSamplers.push_back(
4007 ut::SamplerSp(new Move<VkSampler>(vk::createSampler(m_vki, m_vkd, &createInfo))));
4008
4009 const VkExtent3D &imageExtent = m_testParams.usesMipMaps ? bigImageExtent : smallImageExtent;
4010 createImages(variables.unusedDescriptorsImages, variables.unusedDescriptorsBufferInfos,
4011 variables.unusedDescriptorsBuffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, imageExtent, m_colorFormat,
4012 VK_IMAGE_LAYOUT_UNDEFINED, 1, m_testParams.usesMipMaps);
4013 createImagesViews(variables.unusedDescriptorImageViews, variables.unusedDescriptorsImages, m_colorFormat);
4014 }
4015
4016 class StorageImageInstance : public CommonDescriptorInstance
4017 {
4018 public:
4019 StorageImageInstance(Context &context, const TestCaseParams &testCaseParams);
4020
4021 private:
4022 tcu::TestStatus iterate(void) override;
4023 void createAndPopulateDescriptors(IterateCommonVariables &variables) override;
4024 void createAndPopulateUnusedDescriptors(IterateCommonVariables &variables) override;
4025 void updateDescriptors(IterateCommonVariables &variables) override;
4026 void iterateCollectResults(ut::UpdatablePixelBufferAccessPtr &result, const IterateCommonVariables &variables,
4027 bool fromTest) override;
4028 ut::BufferHandleAllocSp m_buffer;
4029 const uint32_t m_fillColor;
4030 typedef uint32_t m_imageFormat_t;
4031 };
4032
StorageImageInstance(Context & context,const TestCaseParams & testCaseParams)4033 StorageImageInstance::StorageImageInstance(Context &context, const TestCaseParams &testCaseParams)
4034 : CommonDescriptorInstance(context, TestParams(VK_SHADER_STAGE_COMPUTE_BIT, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
4035 VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, true,
4036 performWritesInVertex(testCaseParams.descriptorType, context),
4037 testCaseParams))
4038 , m_buffer()
4039 , m_fillColor(10)
4040 {
4041 }
4042
updateDescriptors(IterateCommonVariables & variables)4043 void StorageImageInstance::updateDescriptors(IterateCommonVariables &variables)
4044 {
4045 // update image at last index
4046 {
4047 VkDescriptorImageInfo imageInfo = {static_cast<VkSampler>(0),
4048 **variables.descriptorImageViews[variables.validDescriptorCount],
4049 VK_IMAGE_LAYOUT_GENERAL};
4050
4051 const VkWriteDescriptorSet writeInfo = {
4052 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
4053 nullptr, // pNext
4054 *variables.descriptorSet, // descriptorSet
4055 BINDING_Additional, // descriptorBinding;
4056 0, // elementIndex
4057 1u, // descriptorCount
4058 m_testParams.additionalDescriptorType, // descriptorType
4059 &imageInfo, // pImageInfo
4060 nullptr, // pBufferInfo
4061 nullptr // pTexelBufferView
4062 };
4063
4064 m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, nullptr);
4065 }
4066
4067 // update rest images
4068 CommonDescriptorInstance::updateDescriptors(variables);
4069 }
4070
createAndPopulateDescriptors(IterateCommonVariables & variables)4071 void StorageImageInstance::createAndPopulateDescriptors(IterateCommonVariables &variables)
4072 {
4073 const VkFormat imageFormat = ut::mapType2vkFormat<m_imageFormat_t>::value;
4074 const VkBufferUsageFlags bufferUsage =
4075 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
4076
4077 // create descriptor buffer, images and views
4078 {
4079 const VkExtent3D imageExtent = {4, 4, 1};
4080
4081 createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer,
4082 bufferUsage, imageExtent, imageFormat, VK_IMAGE_LAYOUT_UNDEFINED, variables.validDescriptorCount);
4083
4084 for (uint32_t imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
4085 {
4086 const PixelBufferAccess pa = getPixelAccess(imageIdx, imageExtent, imageFormat,
4087 variables.descriptorsBufferInfos, variables.descriptorsBuffer);
4088 tcu::clear(pa, tcu::UVec4(m_fillColor));
4089 }
4090 vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
4091 }
4092
4093 // create additional image that will be used as index container
4094 {
4095 createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, m_buffer, bufferUsage,
4096 m_testParams.frameResolution, imageFormat, VK_IMAGE_LAYOUT_UNDEFINED, 1);
4097
4098 // populate buffer
4099 const std::vector<uint32_t> primes = ut::generatePrimes(variables.availableDescriptorCount);
4100 const PixelBufferAccess pa = getPixelAccess(variables.validDescriptorCount, m_testParams.frameResolution,
4101 imageFormat, variables.descriptorsBufferInfos, m_buffer);
4102 for (uint32_t y = 0, pixel = 0; y < m_testParams.frameResolution.height; ++y)
4103 {
4104 for (uint32_t x = 0; x < m_testParams.frameResolution.width; ++x, ++pixel)
4105 {
4106 const uint32_t component = primes[pixel % variables.validDescriptorCount];
4107 pa.setPixel(tcu::UVec4(component), x, y);
4108 }
4109 }
4110
4111 // save changes
4112 vk::flushAlloc(m_vki, m_vkd, *m_buffer->alloc);
4113 }
4114
4115 // create views for all previously created images
4116 createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, imageFormat);
4117 }
4118
createAndPopulateUnusedDescriptors(IterateCommonVariables & variables)4119 void StorageImageInstance::createAndPopulateUnusedDescriptors(IterateCommonVariables &variables)
4120 {
4121 const VkFormat imageFormat = ut::mapType2vkFormat<m_imageFormat_t>::value;
4122 const VkBufferUsageFlags bufferUsage =
4123 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
4124 const VkExtent3D imageExtent = {4, 4, 1};
4125
4126 createImages(variables.unusedDescriptorsImages, variables.unusedDescriptorsBufferInfos,
4127 variables.unusedDescriptorsBuffer, bufferUsage, imageExtent, imageFormat, VK_IMAGE_LAYOUT_UNDEFINED,
4128 1);
4129 createImagesViews(variables.unusedDescriptorImageViews, variables.unusedDescriptorsImages, imageFormat);
4130 }
4131
iterate(void)4132 tcu::TestStatus StorageImageInstance::iterate(void)
4133 {
4134 IterateCommonVariables v;
4135 iterateCommandSetup(v);
4136 iterateCommandBegin(v);
4137
4138 ut::UpdatablePixelBufferAccessPtr programResult;
4139 ut::UpdatablePixelBufferAccessPtr referenceResult;
4140
4141 if (m_testParams.updateAfterBind)
4142 {
4143 updateDescriptors(v);
4144 }
4145
4146 copyBuffersToImages(v);
4147
4148 m_vki.cmdDispatch(*v.commandBuffer,
4149 m_testParams.calculateInLoop ?
4150 1 :
4151 (v.renderArea.extent.width / (m_testParams.minNonUniform ? 1u : kMinWorkGroupSize)),
4152 m_testParams.calculateInLoop ? 1 : v.renderArea.extent.height, 1);
4153
4154 copyImagesToBuffers(v);
4155
4156 iterateCommandEnd(v, programResult, referenceResult, false);
4157
4158 if (iterateVerifyResults(v, programResult, referenceResult))
4159 return tcu::TestStatus::pass("Pass");
4160 return tcu::TestStatus::fail("Failed -- check log for details");
4161 }
4162
iterateCollectResults(ut::UpdatablePixelBufferAccessPtr & result,const IterateCommonVariables & variables,bool fromTest)4163 void StorageImageInstance::iterateCollectResults(ut::UpdatablePixelBufferAccessPtr &result,
4164 const IterateCommonVariables &variables, bool fromTest)
4165 {
4166 result = ut::UpdatablePixelBufferAccessPtr(new ut::PixelBufferAccessAllocation(
4167 vk::mapVkFormat(ut::mapType2vkFormat<m_imageFormat_t>::value), m_testParams.frameResolution));
4168 const PixelBufferAccess &dst = *result.get();
4169
4170 if (fromTest)
4171 {
4172 vk::invalidateAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
4173 for (uint32_t y = 0, pixelNum = 0; y < m_testParams.frameResolution.height; ++y)
4174 {
4175 for (uint32_t x = 0; x < m_testParams.frameResolution.width; ++x, ++pixelNum)
4176 {
4177 const uint32_t imageIdx = pixelNum % variables.validDescriptorCount;
4178 const PixelBufferAccess src =
4179 getPixelAccess(imageIdx, variables.descriptorsImages[imageIdx]->extent,
4180 variables.descriptorsImages[imageIdx]->format, variables.descriptorsBufferInfos,
4181 variables.descriptorsBuffer);
4182 dst.setPixel(tcu::Vector<m_imageFormat_t, 4>(src.getPixelT<m_imageFormat_t>(0, 0).x()), x, y);
4183 }
4184 }
4185 }
4186 else
4187 {
4188 std::vector<m_imageFormat_t> inc(variables.validDescriptorCount, m_fillColor);
4189
4190 for (uint32_t invIdx = variables.lowerBound; invIdx < variables.upperBound; ++invIdx)
4191 {
4192 ++inc[invIdx % variables.validDescriptorCount];
4193 }
4194
4195 for (uint32_t invIdx = 0; invIdx < variables.vertexCount; ++invIdx)
4196 {
4197 const uint32_t row = invIdx / m_testParams.frameResolution.width;
4198 const uint32_t col = invIdx % m_testParams.frameResolution.width;
4199 const m_imageFormat_t color = inc[invIdx % variables.validDescriptorCount];
4200 dst.setPixel(tcu::Vector<m_imageFormat_t, 4>(color), col, row);
4201 }
4202 }
4203 }
4204
4205 class DescriptorIndexingTestCase : public TestCase
4206 {
4207 const TestCaseParams m_testCaseParams;
4208
4209 public:
DescriptorIndexingTestCase(tcu::TestContext & context,const char * name,const TestCaseParams & testCaseParams)4210 DescriptorIndexingTestCase(tcu::TestContext &context, const char *name, const TestCaseParams &testCaseParams)
4211 : TestCase(context, name)
4212 , m_testCaseParams(testCaseParams)
4213 {
4214 }
4215
createInstance(vkt::Context & context) const4216 vkt::TestInstance *createInstance(vkt::Context &context) const // override
4217 {
4218 switch (m_testCaseParams.descriptorType)
4219 {
4220 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
4221 return new StorageBufferInstance(context, m_testCaseParams);
4222 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
4223 return new UniformBufferInstance(context, m_testCaseParams);
4224 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
4225 return new StorageTexelInstance(context, m_testCaseParams);
4226 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
4227 return new UniformTexelInstance(context, m_testCaseParams);
4228 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
4229 return new DynamicStorageBufferInstance(context, m_testCaseParams);
4230 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
4231 return new DynamicUniformBufferInstance(context, m_testCaseParams);
4232 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
4233 return new InputAttachmentInstance(context, m_testCaseParams);
4234 case VK_DESCRIPTOR_TYPE_SAMPLER:
4235 return new SamplerInstance(context, m_testCaseParams);
4236 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
4237 return new SampledImageInstance(context, m_testCaseParams);
4238 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
4239 return new CombinedImageInstance(context, m_testCaseParams);
4240 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
4241 return new StorageImageInstance(context, m_testCaseParams);
4242 default:
4243 TCU_THROW(InternalError, "Unknown Descriptor Type");
4244 }
4245 return nullptr;
4246 }
4247
checkSupport(vkt::Context & context) const4248 virtual void checkSupport(vkt::Context &context) const
4249 {
4250 const vk::VkPhysicalDeviceDescriptorIndexingFeatures &feats = context.getDescriptorIndexingFeatures();
4251
4252 if (!feats.runtimeDescriptorArray)
4253 TCU_THROW(NotSupportedError, "runtimeDescriptorArray not supported");
4254
4255 switch (m_testCaseParams.descriptorType)
4256 {
4257 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
4258 if (!(feats.shaderStorageBufferArrayNonUniformIndexing))
4259 TCU_THROW(NotSupportedError,
4260 "Non-uniform indexing over storage buffer descriptor arrays is not supported.");
4261
4262 if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingStorageBufferUpdateAfterBind)
4263 TCU_THROW(NotSupportedError, "Update after bind for storage buffer descriptors is not supported.");
4264 break;
4265 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
4266 if (!(feats.shaderUniformBufferArrayNonUniformIndexing))
4267 TCU_THROW(NotSupportedError,
4268 "Non-uniform indexing for uniform buffer descriptor arrays is not supported.");
4269
4270 if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingUniformBufferUpdateAfterBind)
4271 TCU_THROW(NotSupportedError, "Update after bind for uniform buffer descriptors is not supported.");
4272 break;
4273 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
4274 if (!(feats.shaderStorageTexelBufferArrayNonUniformIndexing))
4275 TCU_THROW(NotSupportedError,
4276 "Non-uniform indexing for storage texel buffer descriptor arrays is not supported.");
4277
4278 if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingStorageTexelBufferUpdateAfterBind)
4279 TCU_THROW(NotSupportedError,
4280 "Update after bind for storage texel buffer descriptors is not supported.");
4281 break;
4282 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
4283 if (!(feats.shaderUniformTexelBufferArrayNonUniformIndexing))
4284 TCU_THROW(NotSupportedError,
4285 "Non-uniform indexing for uniform texel buffer descriptor arrays is not supported.");
4286
4287 if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingUniformTexelBufferUpdateAfterBind)
4288 TCU_THROW(NotSupportedError,
4289 "Update after bind for uniform texel buffer descriptors is not supported.");
4290 break;
4291 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
4292 if (!(feats.shaderStorageBufferArrayNonUniformIndexing))
4293 TCU_THROW(NotSupportedError,
4294 "Non-uniform indexing over storage buffer dynamic descriptor arrays is not supported.");
4295
4296 if (m_testCaseParams.updateAfterBind)
4297 TCU_THROW(NotSupportedError,
4298 "Update after bind for storage buffer dynamic descriptors is not supported.");
4299 break;
4300 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
4301 if (!(feats.shaderUniformBufferArrayNonUniformIndexing))
4302 TCU_THROW(NotSupportedError,
4303 "Non-uniform indexing over uniform buffer dynamic descriptor arrays is not supported.");
4304
4305 if (m_testCaseParams.updateAfterBind)
4306 TCU_THROW(NotSupportedError,
4307 "Update after bind for uniform buffer dynamic descriptors is not supported.");
4308 break;
4309 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
4310 if (!(feats.shaderInputAttachmentArrayNonUniformIndexing))
4311 TCU_THROW(NotSupportedError,
4312 "Non-uniform indexing over input attachment descriptor arrays is not supported.");
4313
4314 if (m_testCaseParams.updateAfterBind)
4315 TCU_THROW(NotSupportedError, "Update after bind for input attachment descriptors is not supported.");
4316 break;
4317 case VK_DESCRIPTOR_TYPE_SAMPLER:
4318 if (!(feats.shaderSampledImageArrayNonUniformIndexing))
4319 TCU_THROW(NotSupportedError, "Non-uniform indexing over sampler descriptor arrays is not supported.");
4320
4321 if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingSampledImageUpdateAfterBind)
4322 TCU_THROW(NotSupportedError, "Update after bind for sampler descriptors is not supported.");
4323 break;
4324 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
4325 if (!(feats.shaderSampledImageArrayNonUniformIndexing))
4326 TCU_THROW(NotSupportedError,
4327 "Non-uniform indexing over sampled image descriptor arrays is not supported.");
4328
4329 if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingSampledImageUpdateAfterBind)
4330 TCU_THROW(NotSupportedError, "Update after bind for sampled image descriptors is not supported.");
4331 break;
4332 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
4333 if (!(feats.shaderSampledImageArrayNonUniformIndexing))
4334 TCU_THROW(NotSupportedError,
4335 "Non-uniform indexing over combined image sampler descriptor arrays is not supported.");
4336
4337 if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingSampledImageUpdateAfterBind)
4338 TCU_THROW(NotSupportedError,
4339 "Update after bind for combined image sampler descriptors is not supported.");
4340 break;
4341 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
4342 if (!(feats.shaderStorageImageArrayNonUniformIndexing))
4343 TCU_THROW(NotSupportedError,
4344 "Non-uniform indexing over storage image descriptor arrays is not supported.");
4345
4346 if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingStorageImageUpdateAfterBind)
4347 TCU_THROW(NotSupportedError, "Update after bind for storage image descriptors is not supported.");
4348 break;
4349 default:
4350 DE_FATAL("Unknown Descriptor Type");
4351 break;
4352 }
4353 }
4354
initAsmPrograms(SourceCollections & programCollection) const4355 void initAsmPrograms(SourceCollections &programCollection) const
4356 {
4357
4358 std::string (*genShaderSource)(VkShaderStageFlagBits, const TestCaseParams &, bool) =
4359 &CommonDescriptorInstance::getShaderAsm;
4360
4361 uint32_t vulkan_version = VK_MAKE_API_VERSION(0, 1, 2, 0);
4362 vk::SpirvVersion spirv_version = vk::SPIRV_VERSION_1_4;
4363 vk::SpirVAsmBuildOptions asm_options(vulkan_version, spirv_version);
4364
4365 if (VK_SHADER_STAGE_VERTEX_BIT & m_testCaseParams.stageFlags)
4366 {
4367 programCollection.spirvAsmSources.add(
4368 ut::buildShaderName(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams.descriptorType,
4369 m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop,
4370 m_testCaseParams.minNonUniform, false),
4371 &asm_options)
4372 << (*genShaderSource)(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams, false);
4373
4374 if (CommonDescriptorInstance::performWritesInVertex(m_testCaseParams.descriptorType))
4375 {
4376 programCollection.spirvAsmSources.add(
4377 ut::buildShaderName(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams.descriptorType,
4378 m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop,
4379 m_testCaseParams.minNonUniform, true),
4380 &asm_options)
4381 << (*genShaderSource)(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams, true);
4382 }
4383 }
4384 if (VK_SHADER_STAGE_FRAGMENT_BIT & m_testCaseParams.stageFlags)
4385 {
4386 programCollection.spirvAsmSources.add(
4387 ut::buildShaderName(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams.descriptorType,
4388 m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop,
4389 m_testCaseParams.minNonUniform, false),
4390 &asm_options)
4391 << (*genShaderSource)(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams, false);
4392
4393 if (CommonDescriptorInstance::performWritesInVertex(m_testCaseParams.descriptorType))
4394 {
4395 programCollection.spirvAsmSources.add(
4396 ut::buildShaderName(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams.descriptorType,
4397 m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop,
4398 m_testCaseParams.minNonUniform, true),
4399 &asm_options)
4400 << (*genShaderSource)(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams, true);
4401 }
4402 }
4403 if (VK_SHADER_STAGE_COMPUTE_BIT & m_testCaseParams.stageFlags)
4404 {
4405 programCollection.spirvAsmSources.add(
4406 ut::buildShaderName(VK_SHADER_STAGE_COMPUTE_BIT, m_testCaseParams.descriptorType,
4407 m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop,
4408 m_testCaseParams.minNonUniform, false),
4409 &asm_options)
4410 << (*genShaderSource)(VK_SHADER_STAGE_COMPUTE_BIT, m_testCaseParams, false);
4411 }
4412 }
4413
initPrograms(SourceCollections & programCollection) const4414 virtual void initPrograms(SourceCollections &programCollection) const
4415 {
4416 if (m_testCaseParams.minNonUniform)
4417 {
4418 initAsmPrograms(programCollection);
4419 return;
4420 }
4421
4422 std::string (*genShaderSource)(VkShaderStageFlagBits, const TestCaseParams &, bool) =
4423 &CommonDescriptorInstance::getShaderSource;
4424
4425 if (VK_SHADER_STAGE_VERTEX_BIT & m_testCaseParams.stageFlags)
4426 {
4427 programCollection.glslSources.add(ut::buildShaderName(
4428 VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind,
4429 m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, false))
4430 << glu::VertexSource((*genShaderSource)(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams, false));
4431
4432 if (CommonDescriptorInstance::performWritesInVertex(m_testCaseParams.descriptorType))
4433 {
4434 programCollection.glslSources.add(ut::buildShaderName(
4435 VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind,
4436 m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, true))
4437 << glu::VertexSource((*genShaderSource)(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams, true));
4438 }
4439 }
4440 if (VK_SHADER_STAGE_FRAGMENT_BIT & m_testCaseParams.stageFlags)
4441 {
4442 programCollection.glslSources.add(ut::buildShaderName(
4443 VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind,
4444 m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, false))
4445 << glu::FragmentSource((*genShaderSource)(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams, false));
4446
4447 if (CommonDescriptorInstance::performWritesInVertex(m_testCaseParams.descriptorType))
4448 {
4449 programCollection.glslSources.add(ut::buildShaderName(
4450 VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind,
4451 m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, true))
4452 << glu::FragmentSource((*genShaderSource)(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams, true));
4453 }
4454 }
4455 if (VK_SHADER_STAGE_COMPUTE_BIT & m_testCaseParams.stageFlags)
4456 {
4457 programCollection.glslSources.add(ut::buildShaderName(
4458 VK_SHADER_STAGE_COMPUTE_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind,
4459 m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, false))
4460 << glu::ComputeSource((*genShaderSource)(VK_SHADER_STAGE_COMPUTE_BIT, m_testCaseParams, false));
4461 }
4462 }
4463 };
4464
4465 } // namespace
4466
descriptorTypeUsesMipmaps(VkDescriptorType t)4467 static bool descriptorTypeUsesMipmaps(VkDescriptorType t)
4468 {
4469 return t == VK_DESCRIPTOR_TYPE_SAMPLER || t == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ||
4470 t == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
4471 }
4472
descriptorTypeSupportsUpdateAfterBind(VkDescriptorType t)4473 static bool descriptorTypeSupportsUpdateAfterBind(VkDescriptorType t)
4474 {
4475 switch (t)
4476 {
4477 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
4478 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
4479 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
4480 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
4481 case VK_DESCRIPTOR_TYPE_SAMPLER:
4482 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
4483 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
4484 return true;
4485 default:
4486 return false;
4487 }
4488 }
4489
descriptorIndexingDescriptorSetsCreateTests(tcu::TestCaseGroup * group)4490 void descriptorIndexingDescriptorSetsCreateTests(tcu::TestCaseGroup *group)
4491 {
4492 struct TestCaseInfo
4493 {
4494 const char *name;
4495 VkDescriptorType descriptorType;
4496 };
4497
4498 tcu::TestContext &context(group->getTestContext());
4499
4500 TestCaseInfo casesAfterBindAndLoop[] = {
4501 {
4502 "storage_buffer",
4503 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
4504 },
4505 {
4506 "storage_texel_buffer",
4507 VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
4508 },
4509 {
4510 "uniform_texel_buffer",
4511 VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
4512 },
4513 {
4514 "storage_image",
4515 VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
4516 },
4517 {
4518 "sampler",
4519 VK_DESCRIPTOR_TYPE_SAMPLER,
4520 },
4521 {
4522 "sampled_image",
4523 VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
4524 },
4525 {
4526 "combined_image_sampler",
4527 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
4528 },
4529 {
4530 "uniform_buffer",
4531 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
4532 },
4533 {
4534 "storage_buffer_dynamic",
4535 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC,
4536 },
4537 {
4538 "uniform_buffer_dynamic",
4539 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
4540 },
4541 {
4542 "input_attachment",
4543 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
4544 },
4545 };
4546
4547 for (int updateAfterBind = 0; updateAfterBind < 2; ++updateAfterBind)
4548 {
4549 for (int calculateInLoop = 0; calculateInLoop < 2; ++calculateInLoop)
4550 {
4551 for (int usesMipMaps = 0; usesMipMaps < 2; ++usesMipMaps)
4552 {
4553 for (int lifetimeCheck = 0; lifetimeCheck < 2; ++lifetimeCheck)
4554 {
4555 for (uint32_t caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(casesAfterBindAndLoop); ++caseIdx)
4556 {
4557 TestCaseInfo &info(casesAfterBindAndLoop[caseIdx]);
4558
4559 if (updateAfterBind && !descriptorTypeSupportsUpdateAfterBind(info.descriptorType))
4560 continue;
4561
4562 if (usesMipMaps && !descriptorTypeUsesMipmaps(info.descriptorType))
4563 continue;
4564
4565 std::string caseName(info.name);
4566 TestCaseParams params;
4567
4568 caseName += (updateAfterBind ? "_after_bind" : "");
4569 caseName += (calculateInLoop ? "_in_loop" : "");
4570 caseName += (usesMipMaps ? "_with_lod" : "");
4571 caseName += (lifetimeCheck ? "_lifetime" : "");
4572
4573 params.descriptorType = info.descriptorType;
4574 params.stageFlags = (info.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ?
4575 VK_SHADER_STAGE_COMPUTE_BIT :
4576 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
4577 params.frameResolution = RESOLUTION;
4578 params.updateAfterBind = updateAfterBind ? true : false;
4579 params.calculateInLoop = calculateInLoop ? true : false;
4580 params.usesMipMaps = usesMipMaps ? true : false;
4581 params.lifetimeCheck = lifetimeCheck ? true : false;
4582 params.minNonUniform = false;
4583
4584 group->addChild(new DescriptorIndexingTestCase(context, caseName.c_str(), params));
4585 }
4586 }
4587 }
4588 }
4589 }
4590
4591 // SPIR-V Asm Tests
4592 // Tests that have the minimum necessary NonUniform decorations.
4593 // sampler and sampled_image GLSL already have minimum NonUniform decorations.
4594
4595 TestCaseInfo casesMinNonUniform[] = {
4596 {
4597 "storage_buffer",
4598 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
4599 },
4600 {
4601 "storage_texel_buffer",
4602 VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
4603 },
4604 {
4605 "uniform_texel_buffer",
4606 VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
4607 },
4608 {
4609 "uniform_buffer",
4610 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
4611 },
4612 {
4613 "combined_image_sampler",
4614 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
4615 },
4616 {
4617 "storage_image",
4618 VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
4619 },
4620 };
4621
4622 for (int usesMipMaps = 0; usesMipMaps < 2; ++usesMipMaps)
4623 {
4624 for (uint32_t caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(casesMinNonUniform); ++caseIdx)
4625 {
4626 TestCaseInfo &info(casesMinNonUniform[caseIdx]);
4627
4628 if (usesMipMaps && !descriptorTypeUsesMipmaps(info.descriptorType))
4629 continue;
4630
4631 std::string caseName(info.name);
4632 TestCaseParams params;
4633
4634 caseName += (usesMipMaps ? "_with_lod" : "");
4635 caseName += "_minNonUniform";
4636
4637 params.descriptorType = info.descriptorType;
4638 params.stageFlags = (info.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ?
4639 VK_SHADER_STAGE_COMPUTE_BIT :
4640 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
4641 params.frameResolution = RESOLUTION;
4642 params.updateAfterBind = false;
4643 params.calculateInLoop = false;
4644 params.usesMipMaps = usesMipMaps ? true : false;
4645 params.minNonUniform = true;
4646
4647 TestCase *tc = new DescriptorIndexingTestCase(context, caseName.c_str(), params);
4648 group->addChild(tc);
4649 }
4650 }
4651 }
4652
4653 } // namespace DescriptorIndexing
4654 } // namespace vkt
4655