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