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