1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2019 Google Inc.
6 * Copyright (c) 2019 The Khronos Group Inc.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 *//*!
21 * \file
22 * \brief Tests for descriptor copying
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktBindingDescriptorCopyTests.hpp"
26
27 #include "vkBufferWithMemory.hpp"
28 #include "vkImageWithMemory.hpp"
29 #include "vkQueryUtil.hpp"
30 #include "vkBuilderUtil.hpp"
31 #include "vkCmdUtil.hpp"
32 #include "vkTypeUtil.hpp"
33 #include "vkImageUtil.hpp"
34 #include "vkObjUtil.hpp"
35 #include "vktTestGroupUtil.hpp"
36 #include "vktTestCase.hpp"
37
38 #include "deDefs.h"
39 #include "deMath.h"
40 #include "deRandom.h"
41 #include "deSharedPtr.hpp"
42 #include "deString.h"
43
44 #include "tcuTestCase.hpp"
45 #include "tcuTestLog.hpp"
46
47 #include <string>
48 #include <sstream>
49
50 namespace vkt
51 {
52 namespace BindingModel
53 {
54 namespace
55 {
56 using namespace vk;
57 using namespace std;
58 using tcu::Vec2;
59 using tcu::Vec4;
60
61 enum PipelineType
62 {
63 PIPELINE_TYPE_COMPUTE = 0,
64 PIPELINE_TYPE_GRAPHICS = 1
65 };
66
67 struct DescriptorCopy
68 {
69 uint32_t srcSet;
70 uint32_t srcBinding;
71 uint32_t srcArrayElement;
72 uint32_t dstSet;
73 uint32_t dstBinding;
74 uint32_t dstArrayElement;
75 uint32_t descriptorCount;
76 };
77
78 struct DescriptorData
79 {
80 vector<uint32_t> data; // The actual data. One element per dynamic offset.
81 bool written; // Is the data written in descriptor update
82 bool copiedInto; // Is the data being overwritten by a copy operation
83 };
84
85 typedef de::SharedPtr<ImageWithMemory> ImageWithMemorySp;
86 typedef de::SharedPtr<Unique<VkImageView>> VkImageViewSp;
87 typedef de::SharedPtr<Unique<VkBufferView>> VkBufferViewSp;
88 typedef de::SharedPtr<Unique<VkSampler>> VkSamplerSp;
89 typedef de::SharedPtr<Unique<VkDescriptorSetLayout>> VkDescriptorSetLayoutSp;
90
91 const tcu::IVec2 renderSize(64, 64);
92
93 // Base class for descriptors
94 class Descriptor
95 {
96 public:
97 Descriptor(VkDescriptorType descriptorType, uint32_t arraySize = 1u, uint32_t writeStart = 0u,
98 uint32_t elementsToWrite = 1u, uint32_t numDynamicAreas = 1u);
99 virtual ~Descriptor(void);
getType(void) const100 VkDescriptorType getType(void) const
101 {
102 return m_descriptorType;
103 }
getArraySize(void) const104 uint32_t getArraySize(void) const
105 {
106 return m_arraySize;
107 }
108 virtual VkWriteDescriptorSet getDescriptorWrite(void) = 0;
109 virtual string getShaderDeclaration(void) const = 0;
110 virtual void init(Context &context, PipelineType pipelineType) = 0;
111 virtual void copyValue(const Descriptor &src, uint32_t srcElement, uint32_t dstElement, uint32_t numElements);
invalidate(Context & context)112 virtual void invalidate(Context &context)
113 {
114 DE_UNREF(context);
115 }
getData(void)116 virtual vector<uint32_t> getData(void)
117 {
118 DE_FATAL("Unexpected");
119 return vector<uint32_t>();
120 }
getId(void) const121 uint32_t getId(void) const
122 {
123 return m_id;
124 }
125 virtual string getShaderVerifyCode(void) const = 0;
126 string getArrayString(uint32_t index) const;
127 uint32_t getFirstWrittenElement(void) const;
128 uint32_t getNumWrittenElements(void) const;
getReferenceData(uint32_t arrayIdx,uint32_t dynamicAreaIdx=0) const129 uint32_t getReferenceData(uint32_t arrayIdx, uint32_t dynamicAreaIdx = 0) const
130 {
131 return m_data[arrayIdx].data[dynamicAreaIdx];
132 }
isDynamic(void) const133 virtual bool isDynamic(void) const
134 {
135 return false;
136 }
setDynamicAreas(vector<uint32_t> dynamicAreas)137 virtual void setDynamicAreas(vector<uint32_t> dynamicAreas)
138 {
139 DE_UNREF(dynamicAreas);
140 }
getImageViews(void) const141 virtual vector<VkImageViewSp> getImageViews(void) const
142 {
143 return vector<VkImageViewSp>();
144 }
getAttachmentReferences(void) const145 virtual vector<VkAttachmentReference> getAttachmentReferences(void) const
146 {
147 return vector<VkAttachmentReference>();
148 }
149
150 static uint32_t s_nextId;
151
152 protected:
153 VkDescriptorType m_descriptorType;
154 uint32_t m_arraySize;
155 uint32_t m_id;
156 vector<DescriptorData> m_data;
157 uint32_t m_numDynamicAreas;
158 };
159
160 typedef de::SharedPtr<Descriptor> DescriptorSp;
161
162 // Base class for all buffer based descriptors
163 class BufferDescriptor : public Descriptor
164 {
165 public:
166 BufferDescriptor(VkDescriptorType type, uint32_t arraySize, uint32_t writeStart, uint32_t elementsToWrite,
167 uint32_t numDynamicAreas = 1u);
168 virtual ~BufferDescriptor(void);
169 void init(Context &context, PipelineType pipelineType);
170
171 VkWriteDescriptorSet getDescriptorWrite(void);
172 virtual string getShaderDeclaration(void) const = 0;
173 void invalidate(Context &context);
174 vector<uint32_t> getData(void);
175 virtual string getShaderVerifyCode(void) const = 0;
176 virtual VkBufferUsageFlags getBufferUsageFlags(void) const = 0;
usesBufferView(void)177 virtual bool usesBufferView(void)
178 {
179 return false;
180 }
181
182 private:
183 vector<VkDescriptorBufferInfo> m_descriptorBufferInfos;
184 de::MovePtr<BufferWithMemory> m_buffer;
185 uint32_t m_bufferSize;
186 vector<VkBufferViewSp> m_bufferViews;
187 vector<VkBufferView> m_bufferViewHandles;
188 };
189
190 #ifndef CTS_USES_VULKANSC
191 // Inline uniform block descriptor.
192 class InlineUniformBlockDescriptor : public Descriptor
193 {
194 public:
195 InlineUniformBlockDescriptor(uint32_t arraySize, uint32_t writeStart, uint32_t elementsToWrite,
196 uint32_t numDynamicAreas = 1u);
197 virtual ~InlineUniformBlockDescriptor(void);
198 void init(Context &context, PipelineType pipelineType);
199
200 VkWriteDescriptorSet getDescriptorWrite(void);
201 virtual string getShaderDeclaration(void) const;
202 virtual string getShaderVerifyCode(void) const;
usesBufferView(void)203 virtual bool usesBufferView(void)
204 {
205 return false;
206 }
getElementSizeInBytes(void) const207 uint32_t getElementSizeInBytes(void) const
208 {
209 return static_cast<uint32_t>(sizeof(decltype(m_blockData)::value_type));
210 }
getSizeInBytes(void) const211 uint32_t getSizeInBytes(void) const
212 {
213 return m_blockElements * getElementSizeInBytes();
214 }
215
216 private:
217 // Inline uniform blocks cannot form arrays, so we will reuse the array size to create a data array inside the uniform block as
218 // an array of integers. However, with std140, each of those ints will be padded to 16 bytes in the shader. The struct below
219 // allows memory to match between the host and the shader.
220 struct PaddedUint
221 {
PaddedUintvkt::BindingModel::__anon37b3beec0111::InlineUniformBlockDescriptor::PaddedUint222 PaddedUint() : value(0)
223 {
224 deMemset(padding, 0, sizeof(padding));
225 }
PaddedUintvkt::BindingModel::__anon37b3beec0111::InlineUniformBlockDescriptor::PaddedUint226 PaddedUint(uint32_t value_) : value(value_)
227 {
228 deMemset(padding, 0, sizeof(padding));
229 }
operator =vkt::BindingModel::__anon37b3beec0111::InlineUniformBlockDescriptor::PaddedUint230 PaddedUint &operator=(uint32_t value_)
231 {
232 value = value_;
233 return *this;
234 }
235
236 uint32_t value;
237 uint32_t padding[3];
238 };
239
240 vector<PaddedUint> m_blockData;
241 VkWriteDescriptorSetInlineUniformBlockEXT m_inlineWrite;
242 uint32_t m_blockElements;
243 uint32_t m_writeStart;
244 uint32_t m_elementsToWrite;
245 uint32_t m_writeStartByteOffset;
246 uint32_t m_bytesToWrite;
247 };
248 #endif
249
250 class UniformBufferDescriptor : public BufferDescriptor
251 {
252 public:
253 UniformBufferDescriptor(uint32_t arraySize = 1u, uint32_t writeStart = 0u, uint32_t elementsToWrite = 1u,
254 uint32_t numDynamicAreas = 1u);
255 virtual ~UniformBufferDescriptor(void);
256
257 string getShaderDeclaration(void) const;
258 string getShaderVerifyCode(void) const;
getBufferUsageFlags(void) const259 VkBufferUsageFlags getBufferUsageFlags(void) const
260 {
261 return VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
262 }
263
264 private:
265 };
266
267 class DynamicUniformBufferDescriptor : public BufferDescriptor
268 {
269 public:
270 DynamicUniformBufferDescriptor(uint32_t arraySize, uint32_t writeStart, uint32_t elementsToWrite,
271 uint32_t numDynamicAreas);
272 virtual ~DynamicUniformBufferDescriptor(void);
273
274 string getShaderDeclaration(void) const;
275 string getShaderVerifyCode(void) const;
getBufferUsageFlags(void) const276 VkBufferUsageFlags getBufferUsageFlags(void) const
277 {
278 return VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
279 }
setDynamicAreas(vector<uint32_t> dynamicAreas)280 virtual void setDynamicAreas(vector<uint32_t> dynamicAreas)
281 {
282 m_dynamicAreas = dynamicAreas;
283 }
isDynamic(void) const284 virtual bool isDynamic(void) const
285 {
286 return true;
287 }
288
289 private:
290 vector<uint32_t> m_dynamicAreas;
291 };
292
293 class StorageBufferDescriptor : public BufferDescriptor
294 {
295 public:
296 StorageBufferDescriptor(uint32_t arraySize = 1u, uint32_t writeStart = 0u, uint32_t elementsToWrite = 1u,
297 uint32_t numDynamicAreas = 1u);
298 virtual ~StorageBufferDescriptor(void);
299
300 string getShaderDeclaration(void) const;
301 string getShaderVerifyCode(void) const;
getBufferUsageFlags(void) const302 VkBufferUsageFlags getBufferUsageFlags(void) const
303 {
304 return VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
305 }
306
307 private:
308 };
309
310 class DynamicStorageBufferDescriptor : public BufferDescriptor
311 {
312 public:
313 DynamicStorageBufferDescriptor(uint32_t arraySize, uint32_t writeStart, uint32_t elementsToWrite,
314 uint32_t numDynamicAreas);
315 virtual ~DynamicStorageBufferDescriptor(void);
316
317 string getShaderDeclaration(void) const;
318 string getShaderVerifyCode(void) const;
getBufferUsageFlags(void) const319 VkBufferUsageFlags getBufferUsageFlags(void) const
320 {
321 return VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
322 }
setDynamicAreas(vector<uint32_t> dynamicAreas)323 virtual void setDynamicAreas(vector<uint32_t> dynamicAreas)
324 {
325 m_dynamicAreas = dynamicAreas;
326 }
isDynamic(void) const327 virtual bool isDynamic(void) const
328 {
329 return true;
330 }
331
332 private:
333 vector<uint32_t> m_dynamicAreas;
334 };
335
336 class UniformTexelBufferDescriptor : public BufferDescriptor
337 {
338 public:
339 UniformTexelBufferDescriptor(uint32_t arraySize = 1, uint32_t writeStart = 0, uint32_t elementsToWrite = 1,
340 uint32_t numDynamicAreas = 1);
341 virtual ~UniformTexelBufferDescriptor(void);
342
343 string getShaderDeclaration(void) const;
344 string getShaderVerifyCode(void) const;
getBufferUsageFlags(void) const345 VkBufferUsageFlags getBufferUsageFlags(void) const
346 {
347 return VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
348 }
usesBufferView(void)349 bool usesBufferView(void)
350 {
351 return true;
352 }
353
354 private:
355 };
356
357 class StorageTexelBufferDescriptor : public BufferDescriptor
358 {
359 public:
360 StorageTexelBufferDescriptor(uint32_t arraySize = 1u, uint32_t writeStart = 0u, uint32_t elementsToWrite = 1u,
361 uint32_t numDynamicAreas = 1u);
362 virtual ~StorageTexelBufferDescriptor(void);
363
364 string getShaderDeclaration(void) const;
365 string getShaderVerifyCode(void) const;
getBufferUsageFlags(void) const366 VkBufferUsageFlags getBufferUsageFlags(void) const
367 {
368 return VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
369 }
usesBufferView(void)370 bool usesBufferView(void)
371 {
372 return true;
373 }
374
375 private:
376 };
377
378 // Base class for all image based descriptors
379 class ImageDescriptor : public Descriptor
380 {
381 public:
382 ImageDescriptor(VkDescriptorType type, uint32_t arraySize, uint32_t writeStart, uint32_t elementsToWrite,
383 uint32_t numDynamicAreas);
384 virtual ~ImageDescriptor(void);
385 void init(Context &context, PipelineType pipelineType);
386
387 VkWriteDescriptorSet getDescriptorWrite(void);
388 virtual VkImageUsageFlags getImageUsageFlags(void) const = 0;
389 virtual string getShaderDeclaration(void) const = 0;
390 virtual string getShaderVerifyCode(void) const = 0;
getAccessFlags(void) const391 virtual VkAccessFlags getAccessFlags(void) const
392 {
393 return VK_ACCESS_SHADER_READ_BIT;
394 }
getImageLayout(void) const395 virtual VkImageLayout getImageLayout(void) const
396 {
397 return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
398 }
399
400 protected:
401 vector<VkImageViewSp> m_imageViews;
402
403 private:
404 vector<ImageWithMemorySp> m_images;
405 vector<VkDescriptorImageInfo> m_descriptorImageInfos;
406 Move<VkSampler> m_sampler;
407 };
408
409 class InputAttachmentDescriptor : public ImageDescriptor
410 {
411 public:
412 InputAttachmentDescriptor(uint32_t arraySize = 1u, uint32_t writeStart = 0u, uint32_t elementsToWrite = 1u,
413 uint32_t numDynamicAreas = 1u);
414 virtual ~InputAttachmentDescriptor(void);
415
getImageUsageFlags(void) const416 VkImageUsageFlags getImageUsageFlags(void) const
417 {
418 return VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
419 }
420 string getShaderDeclaration(void) const;
421 string getShaderVerifyCode(void) const;
getImageViews(void) const422 vector<VkImageViewSp> getImageViews(void) const
423 {
424 return m_imageViews;
425 }
426 void copyValue(const Descriptor &src, uint32_t srcElement, uint32_t dstElement, uint32_t numElements);
getAccessFlags(void) const427 VkAccessFlags getAccessFlags(void) const
428 {
429 return VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
430 }
431 vector<VkAttachmentReference> getAttachmentReferences(void) const;
432 static uint32_t s_nextAttachmentIndex;
433
434 private:
435 vector<uint32_t> m_attachmentIndices;
436 uint32_t m_originalAttachmentIndex;
437 };
438
439 class CombinedImageSamplerDescriptor : public ImageDescriptor
440 {
441 public:
442 CombinedImageSamplerDescriptor(uint32_t arraySize = 1u, uint32_t writeStart = 0u, uint32_t elementsToWrite = 1u,
443 uint32_t numDynamicAreas = 1u);
444 virtual ~CombinedImageSamplerDescriptor(void);
445
getImageUsageFlags(void) const446 VkImageUsageFlags getImageUsageFlags(void) const
447 {
448 return VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
449 }
450 string getShaderDeclaration(void) const;
451 string getShaderVerifyCode(void) const;
452
453 private:
454 };
455
456 class SamplerDescriptor;
457
458 class SampledImageDescriptor : public ImageDescriptor
459 {
460 public:
461 SampledImageDescriptor(uint32_t arraySize = 1u, uint32_t writeStart = 0u, uint32_t elementsToWrite = 1u,
462 uint32_t numDynamicAreas = 1u);
463 virtual ~SampledImageDescriptor(void);
464
getImageUsageFlags(void) const465 VkImageUsageFlags getImageUsageFlags(void) const
466 {
467 return VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
468 }
469 string getShaderDeclaration(void) const;
470 string getShaderVerifyCode(void) const;
addSampler(SamplerDescriptor * sampler,uint32_t count=1u)471 void addSampler(SamplerDescriptor *sampler, uint32_t count = 1u)
472 {
473 for (uint32_t i = 0; i < count; i++)
474 m_samplers.push_back(sampler);
475 }
476
477 private:
478 vector<SamplerDescriptor *> m_samplers;
479 };
480
481 class SamplerDescriptor : public Descriptor
482 {
483 public:
484 SamplerDescriptor(uint32_t arraySize = 1u, uint32_t writeStart = 0u, uint32_t elementsToWrite = 1u,
485 uint32_t numDynamicAreas = 1u);
486 virtual ~SamplerDescriptor(void);
487 void init(Context &context, PipelineType pipelineType);
488
addImage(SampledImageDescriptor * image,uint32_t count=1u)489 void addImage(SampledImageDescriptor *image, uint32_t count = 1u)
490 {
491 for (uint32_t i = 0; i < count; i++)
492 m_images.push_back(image);
493 }
494 VkWriteDescriptorSet getDescriptorWrite(void);
495 string getShaderDeclaration(void) const;
496 string getShaderVerifyCode(void) const;
497
498 private:
499 vector<VkSamplerSp> m_samplers;
500 vector<VkDescriptorImageInfo> m_descriptorImageInfos;
501 vector<SampledImageDescriptor *> m_images;
502 };
503
504 class StorageImageDescriptor : public ImageDescriptor
505 {
506 public:
507 StorageImageDescriptor(uint32_t arraySize = 1u, uint32_t writeStart = 0u, uint32_t elementsToWrite = 1u,
508 uint32_t numDynamicAreas = 1u);
509 virtual ~StorageImageDescriptor(void);
510
getImageUsageFlags(void) const511 VkImageUsageFlags getImageUsageFlags(void) const
512 {
513 return VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
514 }
515 string getShaderDeclaration(void) const;
516 string getShaderVerifyCode(void) const;
getImageLayout(void) const517 VkImageLayout getImageLayout(void) const
518 {
519 return VK_IMAGE_LAYOUT_GENERAL;
520 }
521
522 private:
523 };
524
525 class DescriptorSet
526 {
527 public:
528 DescriptorSet(void);
529 ~DescriptorSet(void);
530 void addBinding(DescriptorSp descriptor);
getBindings(void) const531 const vector<DescriptorSp> getBindings(void) const
532 {
533 return m_bindings;
534 }
535
536 private:
537 vector<DescriptorSp> m_bindings;
538 };
539
540 typedef de::SharedPtr<DescriptorSet> DescriptorSetSp;
541
542 // Class that handles descriptor sets and descriptors bound to those sets. Keeps track of copy operations.
543 class DescriptorCommands
544 {
545 public:
546 DescriptorCommands(PipelineType pipelineType, bool useUpdateAfterBind);
547 ~DescriptorCommands(void);
548 void addDescriptor(DescriptorSp descriptor, uint32_t descriptorSet);
549 void copyDescriptor(uint32_t srcSet, uint32_t srcBinding, uint32_t srcArrayElement, uint32_t dstSet,
550 uint32_t dstBinding, uint32_t dstArrayElement, uint32_t descriptorCount);
copyDescriptor(uint32_t srcSet,uint32_t srcBinding,uint32_t dstSet,uint32_t dstBinding)551 void copyDescriptor(uint32_t srcSet, uint32_t srcBinding, uint32_t dstSet, uint32_t dstBinding)
552 {
553 copyDescriptor(srcSet, srcBinding, 0u, dstSet, dstBinding, 0u, 1u);
554 }
555 string getShaderDeclarations(void) const;
556 string getDescriptorVerifications(void) const;
557 void addResultBuffer(void);
getResultBufferId(void) const558 uint32_t getResultBufferId(void) const
559 {
560 return m_resultBuffer->getId();
561 }
562 void setDynamicAreas(vector<uint32_t> areas);
563 bool hasDynamicAreas(void) const;
getPipelineType(void) const564 PipelineType getPipelineType(void) const
565 {
566 return m_pipelineType;
567 }
568
569 void checkSupport(Context &context) const;
570 tcu::TestStatus run(Context &context);
571
572 protected:
573 void updateDescriptorSets(Context &context, const vector<VkDescriptorSet> &descriptorSets);
574
575 private:
576 PipelineType m_pipelineType;
577 bool m_useUpdateAfterBind;
578 vector<DescriptorSetSp> m_descriptorSets;
579 vector<DescriptorCopy> m_descriptorCopies;
580 vector<DescriptorSp> m_descriptors;
581 map<VkDescriptorType, uint32_t> m_descriptorCounts;
582 DescriptorSp m_resultBuffer;
583 vector<uint32_t> m_dynamicAreas;
584 };
585
586 typedef de::SharedPtr<DescriptorCommands> DescriptorCommandsSp;
587
588 class DescriptorCopyTestInstance : public TestInstance
589 {
590 public:
591 DescriptorCopyTestInstance(Context &context, DescriptorCommandsSp commands);
592 ~DescriptorCopyTestInstance(void);
593 tcu::TestStatus iterate(void);
594
595 private:
596 DescriptorCommandsSp m_commands;
597 };
598
599 class DescriptorCopyTestCase : public TestCase
600 {
601 public:
602 DescriptorCopyTestCase(tcu::TestContext &context, const char *name, DescriptorCommandsSp commands);
603 virtual ~DescriptorCopyTestCase(void);
604 virtual void initPrograms(SourceCollections &programCollection) const;
605 virtual TestInstance *createInstance(Context &context) const;
606 void checkSupport(Context &context) const;
607
608 private:
609 mutable DescriptorCommandsSp m_commands;
610 };
611
612 uint32_t Descriptor::s_nextId = 0xabc; // Random starting point for ID counter
613 uint32_t InputAttachmentDescriptor::s_nextAttachmentIndex = 0;
614
Descriptor(VkDescriptorType descriptorType,uint32_t arraySize,uint32_t writeStart,uint32_t elementsToWrite,uint32_t numDynamicAreas)615 Descriptor::Descriptor(VkDescriptorType descriptorType, uint32_t arraySize, uint32_t writeStart,
616 uint32_t elementsToWrite, uint32_t numDynamicAreas)
617 : m_descriptorType(descriptorType)
618 , m_arraySize(arraySize)
619 , m_id(s_nextId++)
620 , m_numDynamicAreas(numDynamicAreas)
621 {
622 for (uint32_t arrayIdx = 0; arrayIdx < m_arraySize; arrayIdx++)
623 {
624 const bool written = arrayIdx >= writeStart && arrayIdx < writeStart + elementsToWrite;
625 vector<uint32_t> data;
626
627 for (uint32_t dynamicAreaIdx = 0; dynamicAreaIdx < m_numDynamicAreas; dynamicAreaIdx++)
628 data.push_back(m_id + arrayIdx * m_numDynamicAreas + dynamicAreaIdx);
629
630 const DescriptorData descriptorData = {
631 data, // vector<uint32_t> data
632 written, // bool written
633 false // bool copiedInto
634 };
635
636 m_data.push_back(descriptorData);
637 }
638 }
639
~Descriptor(void)640 Descriptor::~Descriptor(void)
641 {
642 }
643
644 // Copy refrence data from another descriptor
copyValue(const Descriptor & src,uint32_t srcElement,uint32_t dstElement,uint32_t numElements)645 void Descriptor::copyValue(const Descriptor &src, uint32_t srcElement, uint32_t dstElement, uint32_t numElements)
646 {
647 for (uint32_t elementIdx = 0; elementIdx < numElements; elementIdx++)
648 {
649 DE_ASSERT(src.m_data[elementIdx + srcElement].written);
650
651 for (uint32_t dynamicAreaIdx = 0; dynamicAreaIdx < de::min(m_numDynamicAreas, src.m_numDynamicAreas);
652 dynamicAreaIdx++)
653 m_data[elementIdx + dstElement].data[dynamicAreaIdx] =
654 src.m_data[elementIdx + srcElement].data[dynamicAreaIdx];
655
656 m_data[elementIdx + dstElement].copiedInto = true;
657 }
658 }
659
getArrayString(uint32_t index) const660 string Descriptor::getArrayString(uint32_t index) const
661 {
662 return m_arraySize > 1 ? (string("[") + de::toString(index) + "]") : "";
663 }
664
665 // Returns the first element to be written in descriptor update
getFirstWrittenElement(void) const666 uint32_t Descriptor::getFirstWrittenElement(void) const
667 {
668 for (uint32_t i = 0; i < (uint32_t)m_data.size(); i++)
669 if (m_data[i].written)
670 return i;
671
672 return 0;
673 }
674
675 // Returns the number of array elements to be written for a descriptor array
getNumWrittenElements(void) const676 uint32_t Descriptor::getNumWrittenElements(void) const
677 {
678 uint32_t numElements = 0;
679
680 for (uint32_t i = 0; i < (uint32_t)m_data.size(); i++)
681 if (m_data[i].written)
682 numElements++;
683
684 return numElements;
685 }
686
BufferDescriptor(VkDescriptorType type,uint32_t arraySize,uint32_t writeStart,uint32_t elementsToWrite,uint32_t numDynamicAreas)687 BufferDescriptor::BufferDescriptor(VkDescriptorType type, uint32_t arraySize, uint32_t writeStart,
688 uint32_t elementsToWrite, uint32_t numDynamicAreas)
689 : Descriptor(type, arraySize, writeStart, elementsToWrite, numDynamicAreas)
690 , m_bufferSize(256u * arraySize * numDynamicAreas)
691 {
692 }
693
~BufferDescriptor(void)694 BufferDescriptor::~BufferDescriptor(void)
695 {
696 }
697
init(Context & context,PipelineType pipelineType)698 void BufferDescriptor::init(Context &context, PipelineType pipelineType)
699 {
700 DE_UNREF(pipelineType);
701
702 const DeviceInterface &vk = context.getDeviceInterface();
703 const VkDevice device = context.getDevice();
704 Allocator &allocator = context.getDefaultAllocator();
705
706 // Create buffer
707 {
708 const VkBufferCreateInfo bufferCreateInfo = {
709 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType
710 DE_NULL, // const void* pNext
711 0u, // VkBufferCreateFlags flags
712 m_bufferSize, // VkDeviceSize size
713 getBufferUsageFlags(), // VkBufferUsageFlags usage
714 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
715 0u, // uint32_t queueFamilyIndexCount
716 DE_NULL // const uint32_t* pQueueFamilyIndices
717 };
718
719 m_buffer = de::MovePtr<BufferWithMemory>(
720 new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible));
721 }
722
723 // Create descriptor buffer infos
724 {
725 for (uint32_t arrayIdx = 0; arrayIdx < m_arraySize; arrayIdx++)
726 {
727 const VkDescriptorBufferInfo bufferInfo = {
728 m_buffer->get(), // VkBuffer buffer
729 256u * m_numDynamicAreas * arrayIdx, // VkDeviceSize offset
730 isDynamic() ? 256u : 4u // VkDeviceSize range
731 };
732
733 m_descriptorBufferInfos.push_back(bufferInfo);
734 }
735 }
736
737 // Create buffer views
738 if (usesBufferView())
739 {
740 for (uint32_t viewIdx = 0; viewIdx < m_arraySize; viewIdx++)
741 {
742 const VkBufferViewCreateInfo bufferViewCreateInfo = {
743 VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO, // VkStructureType sType
744 DE_NULL, // const void* pNext
745 0u, // VkBufferViewCreateFlags flags
746 m_buffer->get(), // VkBuffer buffer
747 VK_FORMAT_R32_SFLOAT, // VkFormat format
748 256u * viewIdx, // VkDeviceSize offset
749 4u // VkDeviceSize range
750 };
751
752 m_bufferViews.push_back(
753 VkBufferViewSp(new Unique<VkBufferView>(createBufferView(vk, device, &bufferViewCreateInfo))));
754 m_bufferViewHandles.push_back(**m_bufferViews[viewIdx]);
755 }
756 }
757
758 // Initialize buffer memory
759 {
760 uint32_t *hostPtr = (uint32_t *)m_buffer->getAllocation().getHostPtr();
761
762 for (uint32_t arrayIdx = 0; arrayIdx < m_arraySize; arrayIdx++)
763 {
764 for (uint32_t dynamicAreaIdx = 0; dynamicAreaIdx < m_numDynamicAreas; dynamicAreaIdx++)
765 {
766 union BufferValue
767 {
768 uint32_t uintValue;
769 float floatValue;
770 } bufferValue;
771
772 bufferValue.uintValue = m_id + (arrayIdx * m_numDynamicAreas) + dynamicAreaIdx;
773
774 if (usesBufferView())
775 bufferValue.floatValue = (float)bufferValue.uintValue;
776
777 hostPtr[(256 / 4) * (m_numDynamicAreas * arrayIdx + dynamicAreaIdx)] = bufferValue.uintValue;
778 }
779 }
780
781 flushAlloc(vk, device, m_buffer->getAllocation());
782 }
783 }
784
getDescriptorWrite(void)785 VkWriteDescriptorSet BufferDescriptor::getDescriptorWrite(void)
786 {
787 const uint32_t firstElement = getFirstWrittenElement();
788
789 // Set and binding will be overwritten later
790 const VkWriteDescriptorSet descriptorWrite = {
791 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType
792 DE_NULL, // const void* pNext
793 (VkDescriptorSet)0u, // VkDescriptorSet dstSet
794 0u, // uint32_t dstBinding
795 firstElement, // uint32_t dstArrayElement
796 getNumWrittenElements(), // uint32_t descriptorCount
797 getType(), // VkDescriptorType descriptorType
798 DE_NULL, // const VkDescriptorImageInfo pImageInfo
799 usesBufferView() ? DE_NULL :
800 &m_descriptorBufferInfos[firstElement], // const VkDescriptorBufferInfo* pBufferInfo
801 usesBufferView() ? &m_bufferViewHandles[firstElement] :
802 DE_NULL // const VkBufferView* pTexelBufferView
803 };
804
805 return descriptorWrite;
806 }
807
invalidate(Context & context)808 void BufferDescriptor::invalidate(Context &context)
809 {
810 const DeviceInterface &vk = context.getDeviceInterface();
811 const VkDevice device = context.getDevice();
812
813 invalidateAlloc(vk, device, m_buffer->getAllocation());
814 }
815
816 // Returns the buffer data as a vector
getData(void)817 vector<uint32_t> BufferDescriptor::getData(void)
818 {
819 vector<uint32_t> data;
820 int32_t *hostPtr = (int32_t *)m_buffer->getAllocation().getHostPtr();
821
822 for (uint32_t i = 0; i < m_arraySize; i++)
823 data.push_back(hostPtr[i]);
824
825 return data;
826 }
827
828 #ifndef CTS_USES_VULKANSC
829 // Inline Uniform Block descriptor. These are similar to uniform buffers, but they can't form arrays for spec reasons.
830 // The array size is reused, instead, as the size of a data array inside the uniform block.
InlineUniformBlockDescriptor(uint32_t arraySize,uint32_t writeStart,uint32_t elementsToWrite,uint32_t numDynamicAreas)831 InlineUniformBlockDescriptor::InlineUniformBlockDescriptor(uint32_t arraySize, uint32_t writeStart,
832 uint32_t elementsToWrite, uint32_t numDynamicAreas)
833 : Descriptor(VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT, arraySize, writeStart, elementsToWrite, 1u)
834 , m_blockElements(arraySize)
835 , m_writeStart(writeStart)
836 , m_elementsToWrite(elementsToWrite)
837 , m_writeStartByteOffset(m_writeStart * getElementSizeInBytes())
838 , m_bytesToWrite(m_elementsToWrite * getElementSizeInBytes())
839 {
840 DE_UNREF(numDynamicAreas);
841 }
842
~InlineUniformBlockDescriptor(void)843 InlineUniformBlockDescriptor::~InlineUniformBlockDescriptor(void)
844 {
845 }
846
init(Context & context,PipelineType pipelineType)847 void InlineUniformBlockDescriptor::init(Context &context, PipelineType pipelineType)
848 {
849 DE_UNREF(context);
850 DE_UNREF(pipelineType);
851
852 // Initialize host memory.
853 m_blockData.resize(m_blockElements);
854 for (uint32_t i = 0; i < m_blockElements; ++i)
855 m_blockData[i] = m_id + i;
856
857 // Initialize descriptor write extension structure.
858 m_inlineWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT;
859 m_inlineWrite.pNext = DE_NULL;
860 m_inlineWrite.dataSize = m_bytesToWrite;
861 m_inlineWrite.pData = &m_blockData[m_writeStart];
862 }
863
getDescriptorWrite(void)864 VkWriteDescriptorSet InlineUniformBlockDescriptor::getDescriptorWrite(void)
865 {
866 // Set and binding will be overwritten later
867 const VkWriteDescriptorSet descriptorWrite = {
868 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType
869 &m_inlineWrite, // const void* pNext
870 (VkDescriptorSet)0u, // VkDescriptorSet dstSet
871 0u, // uint32_t dstBinding
872 m_writeStartByteOffset, // uint32_t dstArrayElement
873 m_bytesToWrite, // uint32_t descriptorCount
874 getType(), // VkDescriptorType descriptorType
875 DE_NULL, // const VkDescriptorImageInfo pImageInfo
876 DE_NULL, // const VkDescriptorBufferInfo* pBufferInfo
877 DE_NULL // const VkBufferView* pTexelBufferView
878 };
879
880 return descriptorWrite;
881 }
882
getShaderDeclaration(void) const883 string InlineUniformBlockDescriptor::getShaderDeclaration(void) const
884 {
885 const string idStr = de::toString(m_id);
886 return string(") uniform InlineUniformBlock" + idStr +
887 "\n"
888 "{\n"
889 " int data" +
890 getArrayString(m_arraySize) +
891 ";\n"
892 "} inlineUniformBlock" +
893 idStr + ";\n");
894 }
895
getShaderVerifyCode(void) const896 string InlineUniformBlockDescriptor::getShaderVerifyCode(void) const
897 {
898 const string idStr = de::toString(m_id);
899 string ret;
900
901 for (uint32_t i = 0; i < m_arraySize; i++)
902 {
903 if (m_data[i].written || m_data[i].copiedInto)
904 {
905 ret += string("if (inlineUniformBlock") + idStr + ".data" + getArrayString(i) +
906 " != " + de::toString(m_data[i].data[0]) + ") result = 0;\n";
907 }
908 }
909
910 return ret;
911 }
912 #endif
913
UniformBufferDescriptor(uint32_t arraySize,uint32_t writeStart,uint32_t elementsToWrite,uint32_t numDynamicAreas)914 UniformBufferDescriptor::UniformBufferDescriptor(uint32_t arraySize, uint32_t writeStart, uint32_t elementsToWrite,
915 uint32_t numDynamicAreas)
916 : BufferDescriptor(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, arraySize, writeStart, elementsToWrite, 1u)
917 {
918 DE_UNREF(numDynamicAreas);
919 }
920
~UniformBufferDescriptor(void)921 UniformBufferDescriptor::~UniformBufferDescriptor(void)
922 {
923 }
924
getShaderDeclaration(void) const925 string UniformBufferDescriptor::getShaderDeclaration(void) const
926 {
927 return string(") uniform UniformBuffer" + de::toString(m_id) +
928 "\n"
929 "{\n"
930 " int data;\n"
931 "} uniformBuffer" +
932 de::toString(m_id) + getArrayString(m_arraySize) + ";\n");
933 }
934
getShaderVerifyCode(void) const935 string UniformBufferDescriptor::getShaderVerifyCode(void) const
936 {
937 string ret;
938
939 for (uint32_t i = 0; i < m_arraySize; i++)
940 {
941 if (m_data[i].written || m_data[i].copiedInto)
942 ret += string("if (uniformBuffer") + de::toString(m_id) + getArrayString(i) +
943 ".data != " + de::toString(m_data[i].data[0]) + ") result = 0;\n";
944 }
945
946 return ret;
947 }
948
DynamicUniformBufferDescriptor(uint32_t arraySize,uint32_t writeStart,uint32_t elementsToWrite,uint32_t numDynamicAreas)949 DynamicUniformBufferDescriptor::DynamicUniformBufferDescriptor(uint32_t arraySize, uint32_t writeStart,
950 uint32_t elementsToWrite, uint32_t numDynamicAreas)
951 : BufferDescriptor(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, arraySize, writeStart, elementsToWrite,
952 numDynamicAreas)
953 {
954 }
955
~DynamicUniformBufferDescriptor(void)956 DynamicUniformBufferDescriptor::~DynamicUniformBufferDescriptor(void)
957 {
958 }
959
getShaderDeclaration(void) const960 string DynamicUniformBufferDescriptor::getShaderDeclaration(void) const
961 {
962 return string(") uniform UniformBuffer" + de::toString(m_id) +
963 "\n"
964 "{\n"
965 " int data;\n"
966 "} dynamicUniformBuffer" +
967 de::toString(m_id) + getArrayString(m_arraySize) + ";\n");
968 }
969
getShaderVerifyCode(void) const970 string DynamicUniformBufferDescriptor::getShaderVerifyCode(void) const
971 {
972 string ret;
973
974 for (uint32_t arrayIdx = 0; arrayIdx < m_arraySize; arrayIdx++)
975 {
976 if (m_data[arrayIdx].written || m_data[arrayIdx].copiedInto)
977 ret += string("if (dynamicUniformBuffer") + de::toString(m_id) + getArrayString(arrayIdx) +
978 ".data != " + de::toString(m_data[arrayIdx].data[m_dynamicAreas[arrayIdx]]) + ") result = 0;\n";
979 }
980
981 return ret;
982 }
983
StorageBufferDescriptor(uint32_t arraySize,uint32_t writeStart,uint32_t elementsToWrite,uint32_t numDynamicAreas)984 StorageBufferDescriptor::StorageBufferDescriptor(uint32_t arraySize, uint32_t writeStart, uint32_t elementsToWrite,
985 uint32_t numDynamicAreas)
986 : BufferDescriptor(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, arraySize, writeStart, elementsToWrite, 1u)
987 {
988 DE_UNREF(numDynamicAreas);
989 }
990
~StorageBufferDescriptor(void)991 StorageBufferDescriptor::~StorageBufferDescriptor(void)
992 {
993 }
994
getShaderDeclaration(void) const995 string StorageBufferDescriptor::getShaderDeclaration(void) const
996 {
997 return string(") buffer StorageBuffer" + de::toString(m_id) +
998 "\n"
999 "{\n"
1000 " int data;\n"
1001 "} storageBuffer" +
1002 de::toString(m_id) + getArrayString(m_arraySize) + ";\n");
1003 }
1004
getShaderVerifyCode(void) const1005 string StorageBufferDescriptor::getShaderVerifyCode(void) const
1006 {
1007 string ret;
1008
1009 for (uint32_t i = 0; i < m_arraySize; i++)
1010 {
1011 if (m_data[i].written || m_data[i].copiedInto)
1012 ret += string("if (storageBuffer") + de::toString(m_id) + getArrayString(i) +
1013 ".data != " + de::toString(m_data[i].data[0]) + ") result = 0;\n";
1014 }
1015
1016 return ret;
1017 }
1018
DynamicStorageBufferDescriptor(uint32_t arraySize,uint32_t writeStart,uint32_t elementsToWrite,uint32_t numDynamicAreas)1019 DynamicStorageBufferDescriptor::DynamicStorageBufferDescriptor(uint32_t arraySize, uint32_t writeStart,
1020 uint32_t elementsToWrite, uint32_t numDynamicAreas)
1021 : BufferDescriptor(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, arraySize, writeStart, elementsToWrite,
1022 numDynamicAreas)
1023 {
1024 }
1025
~DynamicStorageBufferDescriptor(void)1026 DynamicStorageBufferDescriptor::~DynamicStorageBufferDescriptor(void)
1027 {
1028 }
1029
getShaderDeclaration(void) const1030 string DynamicStorageBufferDescriptor::getShaderDeclaration(void) const
1031 {
1032 return string(") buffer StorageBuffer" + de::toString(m_id) +
1033 "\n"
1034 "{\n"
1035 " int data;\n"
1036 "} dynamicStorageBuffer" +
1037 de::toString(m_id) + getArrayString(m_arraySize) + ";\n");
1038 }
1039
getShaderVerifyCode(void) const1040 string DynamicStorageBufferDescriptor::getShaderVerifyCode(void) const
1041 {
1042 string ret;
1043
1044 for (uint32_t arrayIdx = 0; arrayIdx < m_arraySize; arrayIdx++)
1045 {
1046 if (m_data[arrayIdx].written || m_data[arrayIdx].copiedInto)
1047 ret += string("if (dynamicStorageBuffer") + de::toString(m_id) + getArrayString(arrayIdx) +
1048 ".data != " + de::toString(m_data[arrayIdx].data[m_dynamicAreas[arrayIdx]]) + ") result = 0;\n";
1049 }
1050
1051 return ret;
1052 }
1053
UniformTexelBufferDescriptor(uint32_t arraySize,uint32_t writeStart,uint32_t elementsToWrite,uint32_t numDynamicAreas)1054 UniformTexelBufferDescriptor::UniformTexelBufferDescriptor(uint32_t arraySize, uint32_t writeStart,
1055 uint32_t elementsToWrite, uint32_t numDynamicAreas)
1056 : BufferDescriptor(VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, arraySize, writeStart, elementsToWrite, 1u)
1057 {
1058 DE_UNREF(numDynamicAreas);
1059 }
1060
~UniformTexelBufferDescriptor(void)1061 UniformTexelBufferDescriptor::~UniformTexelBufferDescriptor(void)
1062 {
1063 }
1064
getShaderDeclaration(void) const1065 string UniformTexelBufferDescriptor::getShaderDeclaration(void) const
1066 {
1067 return string(") uniform textureBuffer uniformTexelBuffer" + de::toString(m_id) + getArrayString(m_arraySize) +
1068 ";\n");
1069 }
1070
getShaderVerifyCode(void) const1071 string UniformTexelBufferDescriptor::getShaderVerifyCode(void) const
1072 {
1073 string ret;
1074
1075 for (uint32_t i = 0; i < m_arraySize; i++)
1076 {
1077 if (m_data[i].written || m_data[i].copiedInto)
1078 ret += string("if (texelFetch(uniformTexelBuffer") + de::toString(m_id) + getArrayString(i) +
1079 ", 0).x != " + de::toString(m_data[i].data[0]) + ") result = 0;\n";
1080 }
1081
1082 return ret;
1083 }
1084
StorageTexelBufferDescriptor(uint32_t arraySize,uint32_t writeStart,uint32_t elementsToWrite,uint32_t numDynamicAreas)1085 StorageTexelBufferDescriptor::StorageTexelBufferDescriptor(uint32_t arraySize, uint32_t writeStart,
1086 uint32_t elementsToWrite, uint32_t numDynamicAreas)
1087 : BufferDescriptor(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, arraySize, writeStart, elementsToWrite, 1u)
1088 {
1089 DE_UNREF(numDynamicAreas);
1090 }
1091
~StorageTexelBufferDescriptor(void)1092 StorageTexelBufferDescriptor::~StorageTexelBufferDescriptor(void)
1093 {
1094 }
1095
getShaderDeclaration(void) const1096 string StorageTexelBufferDescriptor::getShaderDeclaration(void) const
1097 {
1098 return string(", r32f) uniform imageBuffer storageTexelBuffer" + de::toString(m_id) + getArrayString(m_arraySize) +
1099 ";\n");
1100 }
1101
getShaderVerifyCode(void) const1102 string StorageTexelBufferDescriptor::getShaderVerifyCode(void) const
1103 {
1104 string ret;
1105
1106 for (uint32_t i = 0; i < m_arraySize; i++)
1107 {
1108 if (m_data[i].written || m_data[i].copiedInto)
1109 ret += string("if (imageLoad(storageTexelBuffer") + de::toString(m_id) + getArrayString(i) +
1110 ", 0).x != " + de::toString(m_data[i].data[0]) + ") result = 0;\n";
1111 }
1112
1113 return ret;
1114 }
1115
ImageDescriptor(VkDescriptorType type,uint32_t arraySize,uint32_t writeStart,uint32_t elementsToWrite,uint32_t numDynamicAreas)1116 ImageDescriptor::ImageDescriptor(VkDescriptorType type, uint32_t arraySize, uint32_t writeStart,
1117 uint32_t elementsToWrite, uint32_t numDynamicAreas)
1118 : Descriptor(type, arraySize, writeStart, elementsToWrite, 1u)
1119 {
1120 DE_UNREF(numDynamicAreas);
1121 }
1122
~ImageDescriptor(void)1123 ImageDescriptor::~ImageDescriptor(void)
1124 {
1125 }
1126
init(Context & context,PipelineType pipelineType)1127 void ImageDescriptor::init(Context &context, PipelineType pipelineType)
1128 {
1129 const DeviceInterface &vk = context.getDeviceInterface();
1130 const VkDevice device = context.getDevice();
1131 Allocator &allocator = context.getDefaultAllocator();
1132 const VkQueue queue = context.getUniversalQueue();
1133 uint32_t queueFamilyIndex = context.getUniversalQueueFamilyIndex();
1134 const VkFormat format = VK_FORMAT_R32_SFLOAT;
1135 const VkComponentMapping componentMapping = makeComponentMappingRGBA();
1136
1137 const VkImageSubresourceRange subresourceRange = {
1138 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
1139 0u, // uint32_t baseMipLevel
1140 1u, // uint32_t levelCount
1141 0u, // uint32_t baseArrayLayer
1142 1u, // uint32_t layerCount
1143 };
1144
1145 // Create sampler
1146 {
1147 const tcu::Sampler sampler =
1148 tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
1149 tcu::Sampler::NEAREST, tcu::Sampler::NEAREST, 0.0f, true, tcu::Sampler::COMPAREMODE_NONE, 0,
1150 tcu::Vec4(0.0f), true);
1151 const tcu::TextureFormat texFormat = mapVkFormat(format);
1152 const VkSamplerCreateInfo samplerParams = mapSampler(sampler, texFormat);
1153
1154 m_sampler = createSampler(vk, device, &samplerParams);
1155 }
1156
1157 // Create images
1158 for (uint32_t imageIdx = 0; imageIdx < m_arraySize; imageIdx++)
1159 {
1160 const VkImageCreateInfo imageCreateInfo = {
1161 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType stype
1162 DE_NULL, // const void* pNext
1163 0u, // VkImageCreateFlags flags
1164 VK_IMAGE_TYPE_2D, // VkImageType imageType
1165 format, // VkFormat format
1166 {(uint32_t)renderSize.x(), (uint32_t)renderSize.y(), 1}, // VkExtent3D extent
1167 1u, // uint32_t mipLevels
1168 1u, // uint32_t arrayLayers
1169 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
1170 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
1171 getImageUsageFlags(), // VkImageUsageFlags usage
1172 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
1173 1u, // uint32_t queueFamilyIndexCount
1174 &queueFamilyIndex, // const uint32_t* pQueueFamilyIndices
1175 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout
1176 };
1177
1178 m_images.push_back(
1179 ImageWithMemorySp(new ImageWithMemory(vk, device, allocator, imageCreateInfo, MemoryRequirement::Any)));
1180 }
1181
1182 // Create image views
1183 for (uint32_t imageIdx = 0; imageIdx < m_arraySize; imageIdx++)
1184 {
1185 const VkImageViewCreateInfo imageViewCreateInfo = {
1186 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType
1187 DE_NULL, // const void* pNext
1188 0u, // VkImageViewCreateFlags flags
1189 **m_images[imageIdx], // VkImage image
1190 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType
1191 format, // VkFormat format
1192 componentMapping, // VkComponentMapping components
1193 subresourceRange // VkImageSubresourceRange subresourceRange
1194 };
1195
1196 m_imageViews.push_back(
1197 VkImageViewSp(new Unique<VkImageView>(createImageView(vk, device, &imageViewCreateInfo))));
1198 }
1199
1200 // Create descriptor image infos
1201 {
1202 for (uint32_t i = 0; i < m_arraySize; i++)
1203 {
1204 const VkDescriptorImageInfo imageInfo = {
1205 *m_sampler, // VkSampler sampler
1206 **m_imageViews[i], // VkImageView imageView
1207 getImageLayout() // VkImageLayout imageLayout
1208 };
1209
1210 m_descriptorImageInfos.push_back(imageInfo);
1211 }
1212 }
1213
1214 // Clear images to reference value
1215 for (uint32_t imageIdx = 0; imageIdx < m_arraySize; imageIdx++)
1216 {
1217 const Unique<VkCommandPool> cmdPool(
1218 createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex));
1219 const Unique<VkCommandBuffer> cmdBuffer(
1220 allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1221
1222 const float clearValue = (float)(m_id + imageIdx);
1223 const VkClearValue clearColor = makeClearValueColorF32(clearValue, clearValue, clearValue, clearValue);
1224
1225 const VkImageMemoryBarrier preImageBarrier = {
1226 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
1227 DE_NULL, // const void* pNext
1228 0u, // VkAccessFlags srcAccessMask
1229 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
1230 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
1231 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout
1232 queueFamilyIndex, // uint32_t srcQueueFamilyIndex
1233 queueFamilyIndex, // uint32_t dstQueueFamilyIndex
1234 **m_images[imageIdx], // VkImage image
1235 subresourceRange // VkImageSubresourceRange subresourceRange
1236 };
1237
1238 const VkImageMemoryBarrier postImageBarrier = {
1239 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
1240 DE_NULL, // const void* pNext
1241 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
1242 getAccessFlags(), // VkAccessFlags dstAccessMask
1243 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout
1244 getImageLayout(), // VkImageLayout newLayout
1245 queueFamilyIndex, // uint32_t srcQueueFamilyIndex
1246 queueFamilyIndex, // uint32_t dstQueueFamilyIndex
1247 **m_images[imageIdx], // VkImage image
1248 subresourceRange // VkImageSubresourceRange subresourceRange
1249 };
1250
1251 beginCommandBuffer(vk, *cmdBuffer);
1252 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1253 (VkDependencyFlags)0u, 0u, (const VkMemoryBarrier *)DE_NULL, 0u,
1254 (const VkBufferMemoryBarrier *)DE_NULL, 1u, &preImageBarrier);
1255 vk.cmdClearColorImage(*cmdBuffer, **m_images[imageIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor.color,
1256 1, &subresourceRange);
1257 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
1258 pipelineType == PIPELINE_TYPE_COMPUTE ? VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT :
1259 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
1260 (VkDependencyFlags)0u, 0u, (const VkMemoryBarrier *)DE_NULL, 0u,
1261 (const VkBufferMemoryBarrier *)DE_NULL, 1u, &postImageBarrier);
1262 endCommandBuffer(vk, *cmdBuffer);
1263 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
1264 }
1265 }
1266
getDescriptorWrite(void)1267 VkWriteDescriptorSet ImageDescriptor::getDescriptorWrite(void)
1268 {
1269 const uint32_t firstElement = getFirstWrittenElement();
1270
1271 // Set and binding will be overwritten later
1272 const VkWriteDescriptorSet descriptorWrite = {
1273 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType
1274 DE_NULL, // const void* pNext
1275 (VkDescriptorSet)0u, // VkDescriptorSet dstSet
1276 0u, // uint32_t dstBinding
1277 firstElement, // uint32_t dstArrayElement
1278 getNumWrittenElements(), // uint32_t descriptorCount
1279 getType(), // VkDescriptorType descriptorType
1280 &m_descriptorImageInfos[firstElement], // const VkDescriptorImageInfo pImageInfo
1281 DE_NULL, // const VkDescriptorBufferInfo* pBufferInfo
1282 DE_NULL // const VkBufferView* pTexelBufferView
1283 };
1284
1285 return descriptorWrite;
1286 }
1287
InputAttachmentDescriptor(uint32_t arraySize,uint32_t writeStart,uint32_t elementsToWrite,uint32_t numDynamicAreas)1288 InputAttachmentDescriptor::InputAttachmentDescriptor(uint32_t arraySize, uint32_t writeStart, uint32_t elementsToWrite,
1289 uint32_t numDynamicAreas)
1290 : ImageDescriptor(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, arraySize, writeStart, elementsToWrite, 1u)
1291 , m_originalAttachmentIndex(s_nextAttachmentIndex)
1292 {
1293 DE_UNREF(numDynamicAreas);
1294
1295 for (uint32_t i = 0; i < m_arraySize; i++)
1296 m_attachmentIndices.push_back(s_nextAttachmentIndex++);
1297 }
1298
~InputAttachmentDescriptor(void)1299 InputAttachmentDescriptor::~InputAttachmentDescriptor(void)
1300 {
1301 }
1302
getShaderDeclaration(void) const1303 string InputAttachmentDescriptor::getShaderDeclaration(void) const
1304 {
1305 return string(", input_attachment_index=" + de::toString(m_originalAttachmentIndex) +
1306 ") uniform subpassInput inputAttachment" + de::toString(m_id) + getArrayString(m_arraySize) + ";\n");
1307 }
1308
getShaderVerifyCode(void) const1309 string InputAttachmentDescriptor::getShaderVerifyCode(void) const
1310 {
1311 string ret;
1312
1313 for (uint32_t i = 0; i < m_arraySize; i++)
1314 {
1315 if (m_data[i].written || m_data[i].copiedInto)
1316 ret += string("if (subpassLoad(inputAttachment") + de::toString(m_id) + getArrayString(i) +
1317 ").x != " + de::toString(m_data[i].data[0]) + ") result = 0;\n";
1318 }
1319
1320 return ret;
1321 }
1322
copyValue(const Descriptor & src,uint32_t srcElement,uint32_t dstElement,uint32_t numElements)1323 void InputAttachmentDescriptor::copyValue(const Descriptor &src, uint32_t srcElement, uint32_t dstElement,
1324 uint32_t numElements)
1325 {
1326 Descriptor::copyValue(src, srcElement, dstElement, numElements);
1327
1328 for (uint32_t elementIdx = 0; elementIdx < numElements; elementIdx++)
1329 {
1330 m_attachmentIndices[elementIdx + dstElement] =
1331 reinterpret_cast<const InputAttachmentDescriptor &>(src).m_attachmentIndices[elementIdx + srcElement];
1332 }
1333 }
1334
getAttachmentReferences(void) const1335 vector<VkAttachmentReference> InputAttachmentDescriptor::getAttachmentReferences(void) const
1336 {
1337 vector<VkAttachmentReference> references;
1338 for (uint32_t i = 0; i < m_arraySize; i++)
1339 {
1340 const VkAttachmentReference attachmentReference = {
1341 // The first attachment is the color buffer, thus +1
1342 m_attachmentIndices[i] + 1, // uint32_t attachment
1343 getImageLayout() // VkImageLayout layout
1344 };
1345
1346 references.push_back(attachmentReference);
1347 }
1348
1349 return references;
1350 }
1351
CombinedImageSamplerDescriptor(uint32_t arraySize,uint32_t writeStart,uint32_t elementsToWrite,uint32_t numDynamicAreas)1352 CombinedImageSamplerDescriptor::CombinedImageSamplerDescriptor(uint32_t arraySize, uint32_t writeStart,
1353 uint32_t elementsToWrite, uint32_t numDynamicAreas)
1354 : ImageDescriptor(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, arraySize, writeStart, elementsToWrite, 1u)
1355 {
1356 DE_UNREF(numDynamicAreas);
1357 }
1358
~CombinedImageSamplerDescriptor(void)1359 CombinedImageSamplerDescriptor::~CombinedImageSamplerDescriptor(void)
1360 {
1361 }
1362
getShaderDeclaration(void) const1363 string CombinedImageSamplerDescriptor::getShaderDeclaration(void) const
1364 {
1365 return string(") uniform sampler2D texSampler" + de::toString(m_id) + getArrayString(m_arraySize) + ";\n");
1366 }
1367
getShaderVerifyCode(void) const1368 string CombinedImageSamplerDescriptor::getShaderVerifyCode(void) const
1369 {
1370 string ret;
1371
1372 for (uint32_t i = 0; i < m_arraySize; i++)
1373 {
1374 if (m_data[i].written || m_data[i].copiedInto)
1375 ret += string("if (texture(texSampler") + de::toString(m_id) + getArrayString(i) +
1376 ", vec2(0)).x != " + de::toString(m_data[i].data[0]) + ") result = 0;\n";
1377 }
1378
1379 return ret;
1380 }
1381
SampledImageDescriptor(uint32_t arraySize,uint32_t writeStart,uint32_t elementsToWrite,uint32_t numDynamicAreas)1382 SampledImageDescriptor::SampledImageDescriptor(uint32_t arraySize, uint32_t writeStart, uint32_t elementsToWrite,
1383 uint32_t numDynamicAreas)
1384 : ImageDescriptor(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, arraySize, writeStart, elementsToWrite, 1u)
1385 {
1386 DE_UNREF(numDynamicAreas);
1387 }
1388
~SampledImageDescriptor(void)1389 SampledImageDescriptor::~SampledImageDescriptor(void)
1390 {
1391 }
1392
getShaderDeclaration(void) const1393 string SampledImageDescriptor::getShaderDeclaration(void) const
1394 {
1395 return string(") uniform texture2D sampledImage" + de::toString(m_id) + getArrayString(m_arraySize) + ";\n");
1396 }
1397
getShaderVerifyCode(void) const1398 string SampledImageDescriptor::getShaderVerifyCode(void) const
1399 {
1400 string ret;
1401
1402 for (uint32_t i = 0; i < m_arraySize; i++)
1403 {
1404 if ((m_data[i].written || m_data[i].copiedInto) && m_samplers.size() > i)
1405 {
1406 ret += string("if (texture(sampler2D(sampledImage") + de::toString(m_id) + getArrayString(i) + ", sampler" +
1407 de::toString(m_samplers[i]->getId()) + "), vec2(0)).x != " + de::toString(m_data[i].data[0]) +
1408 ") result = 0;\n";
1409 }
1410 }
1411
1412 return ret;
1413 }
1414
StorageImageDescriptor(uint32_t arraySize,uint32_t writeStart,uint32_t elementsToWrite,uint32_t numDynamicAreas)1415 StorageImageDescriptor::StorageImageDescriptor(uint32_t arraySize, uint32_t writeStart, uint32_t elementsToWrite,
1416 uint32_t numDynamicAreas)
1417 : ImageDescriptor(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, arraySize, writeStart, elementsToWrite, 1u)
1418 {
1419 DE_UNREF(numDynamicAreas);
1420 }
1421
~StorageImageDescriptor(void)1422 StorageImageDescriptor::~StorageImageDescriptor(void)
1423 {
1424 }
1425
getShaderDeclaration(void) const1426 string StorageImageDescriptor::getShaderDeclaration(void) const
1427 {
1428 return string(", r32f) readonly uniform image2D image" + de::toString(m_id) + getArrayString(m_arraySize) + ";\n");
1429 }
1430
getShaderVerifyCode(void) const1431 string StorageImageDescriptor::getShaderVerifyCode(void) const
1432 {
1433 string ret;
1434
1435 for (uint32_t i = 0; i < m_arraySize; i++)
1436 {
1437 if (m_data[i].written || m_data[i].copiedInto)
1438 ret += string("if (imageLoad(image") + de::toString(m_id) + getArrayString(i) +
1439 ", ivec2(0)).x != " + de::toString(m_data[i].data[0]) + ") result = 0;\n";
1440 }
1441
1442 return ret;
1443 }
1444
SamplerDescriptor(uint32_t arraySize,uint32_t writeStart,uint32_t elementsToWrite,uint32_t numDynamicAreas)1445 SamplerDescriptor::SamplerDescriptor(uint32_t arraySize, uint32_t writeStart, uint32_t elementsToWrite,
1446 uint32_t numDynamicAreas)
1447 : Descriptor(VK_DESCRIPTOR_TYPE_SAMPLER, arraySize, writeStart, elementsToWrite, 1u)
1448 {
1449 DE_UNREF(numDynamicAreas);
1450 }
1451
~SamplerDescriptor(void)1452 SamplerDescriptor::~SamplerDescriptor(void)
1453 {
1454 }
1455
init(Context & context,PipelineType pipelineType)1456 void SamplerDescriptor::init(Context &context, PipelineType pipelineType)
1457 {
1458 DE_UNREF(pipelineType);
1459
1460 const DeviceInterface &vk = context.getDeviceInterface();
1461 const VkDevice device = context.getDevice();
1462 const VkFormat format = VK_FORMAT_R32_SFLOAT;
1463
1464 // Create samplers
1465 for (uint32_t i = 0; i < m_arraySize; i++)
1466 {
1467 const float borderValue = (float)((m_id + i) % 2);
1468 const tcu::Sampler sampler =
1469 tcu::Sampler(tcu::Sampler::CLAMP_TO_BORDER, tcu::Sampler::CLAMP_TO_BORDER, tcu::Sampler::CLAMP_TO_BORDER,
1470 tcu::Sampler::NEAREST, tcu::Sampler::NEAREST, 0.0f, true, tcu::Sampler::COMPAREMODE_NONE, 0,
1471 Vec4(borderValue), true);
1472 const tcu::TextureFormat texFormat = mapVkFormat(format);
1473 const VkSamplerCreateInfo samplerParams = mapSampler(sampler, texFormat);
1474
1475 m_samplers.push_back(VkSamplerSp(new Unique<VkSampler>(createSampler(vk, device, &samplerParams))));
1476 }
1477
1478 // Create descriptor image infos
1479 for (uint32_t i = 0; i < m_arraySize; i++)
1480 {
1481 const VkDescriptorImageInfo imageInfo = {
1482 **m_samplers[i], // VkSampler sampler
1483 DE_NULL, // VkImageView imageView
1484 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout imageLayout
1485 };
1486
1487 m_descriptorImageInfos.push_back(imageInfo);
1488 }
1489 }
1490
getDescriptorWrite(void)1491 VkWriteDescriptorSet SamplerDescriptor::getDescriptorWrite(void)
1492 {
1493 const uint32_t firstElement = getFirstWrittenElement();
1494
1495 // Set and binding will be overwritten later
1496 const VkWriteDescriptorSet descriptorWrite = {
1497 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType
1498 DE_NULL, // const void* pNext
1499 (VkDescriptorSet)0u, // VkDescriptorSet dstSet
1500 0u, // uint32_t dstBinding
1501 firstElement, // uint32_t dstArrayElement
1502 getNumWrittenElements(), // uint32_t descriptorCount
1503 getType(), // VkDescriptorType descriptorType
1504 &m_descriptorImageInfos[firstElement], // const VkDescriptorImageInfo pImageInfo
1505 DE_NULL, // const VkDescriptorBufferInfo* pBufferInfo
1506 DE_NULL // const VkBufferView* pTexelBufferView
1507 };
1508
1509 return descriptorWrite;
1510 }
1511
getShaderDeclaration(void) const1512 string SamplerDescriptor::getShaderDeclaration(void) const
1513 {
1514 return string(") uniform sampler sampler" + de::toString(m_id) + getArrayString(m_arraySize) + ";\n");
1515 }
1516
getShaderVerifyCode(void) const1517 string SamplerDescriptor::getShaderVerifyCode(void) const
1518 {
1519 string ret;
1520
1521 for (uint32_t i = 0; i < m_arraySize; i++)
1522 {
1523 if ((m_data[i].written || m_data[i].copiedInto) && m_images.size() > i)
1524 {
1525 // Sample from (-1, -1) to get border color.
1526 ret += string("if (texture(sampler2D(sampledImage") + de::toString(m_images[i]->getId()) + ", sampler" +
1527 de::toString(m_id) + getArrayString(i) + "), vec2(-1)).x != " + de::toString(m_data[i].data[0] % 2) +
1528 ") result = 0;\n";
1529 }
1530 }
1531
1532 return ret;
1533 }
1534
DescriptorSet(void)1535 DescriptorSet::DescriptorSet(void)
1536 {
1537 }
1538
~DescriptorSet(void)1539 DescriptorSet::~DescriptorSet(void)
1540 {
1541 }
1542
addBinding(DescriptorSp descriptor)1543 void DescriptorSet::addBinding(DescriptorSp descriptor)
1544 {
1545 m_bindings.push_back(descriptor);
1546 }
1547
DescriptorCommands(PipelineType pipelineType,bool useUpdateAfterBind)1548 DescriptorCommands::DescriptorCommands(PipelineType pipelineType, bool useUpdateAfterBind)
1549 : m_pipelineType(pipelineType)
1550 , m_useUpdateAfterBind(useUpdateAfterBind)
1551 {
1552 // Reset counters
1553 Descriptor::s_nextId = 0xabc;
1554 InputAttachmentDescriptor::s_nextAttachmentIndex = 0;
1555 }
1556
~DescriptorCommands(void)1557 DescriptorCommands::~DescriptorCommands(void)
1558 {
1559 }
1560
addDescriptor(DescriptorSp descriptor,uint32_t descriptorSet)1561 void DescriptorCommands::addDescriptor(DescriptorSp descriptor, uint32_t descriptorSet)
1562 {
1563 const VkDescriptorType type = descriptor->getType();
1564
1565 // Create descriptor set objects until one with the given index exists
1566 while (m_descriptorSets.size() <= descriptorSet)
1567 m_descriptorSets.push_back(DescriptorSetSp(new DescriptorSet()));
1568
1569 m_descriptorSets[descriptorSet]->addBinding(descriptor);
1570
1571 // Keep track of how many descriptors of each type is needed. Inline uniform blocks cannot form arrays. We reuse the array size
1572 // as size of the data array for them, within a single descriptor.
1573
1574 #ifndef CTS_USES_VULKANSC
1575 const uint32_t count = ((type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) ? 1u : descriptor->getArraySize());
1576 #else
1577 const uint32_t count = descriptor->getArraySize();
1578 #endif
1579
1580 if (m_descriptorCounts.find(type) != m_descriptorCounts.end())
1581 m_descriptorCounts[type] += count;
1582 else
1583 m_descriptorCounts[type] = count;
1584
1585 // Keep descriptors also in a flat list for easier iteration
1586 m_descriptors.push_back(descriptor);
1587 }
1588
copyDescriptor(uint32_t srcSet,uint32_t srcBinding,uint32_t srcArrayElement,uint32_t dstSet,uint32_t dstBinding,uint32_t dstArrayElement,uint32_t descriptorCount)1589 void DescriptorCommands::copyDescriptor(uint32_t srcSet, uint32_t srcBinding, uint32_t srcArrayElement, uint32_t dstSet,
1590 uint32_t dstBinding, uint32_t dstArrayElement, uint32_t descriptorCount)
1591 {
1592 // For inline uniform blocks, (src|dst)ArrayElement are data array indices and descriptorCount is the number of integers to copy.
1593 DescriptorCopy descriptorCopy = {srcSet, srcBinding, srcArrayElement, dstSet,
1594 dstBinding, dstArrayElement, descriptorCount};
1595
1596 #ifndef CTS_USES_VULKANSC
1597 if (m_descriptorSets[srcSet]->getBindings()[srcBinding]->getType() == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
1598 {
1599 // For inline uniform blocks, these members of VkCopyDescriptorSet are offsets and sizes in bytes.
1600 const InlineUniformBlockDescriptor *iub =
1601 static_cast<InlineUniformBlockDescriptor *>(m_descriptorSets[srcSet]->getBindings()[srcBinding].get());
1602 const uint32_t elementSize = iub->getElementSizeInBytes();
1603
1604 descriptorCopy.srcArrayElement *= elementSize;
1605 descriptorCopy.dstArrayElement *= elementSize;
1606 descriptorCopy.descriptorCount *= elementSize;
1607 }
1608 #endif
1609
1610 m_descriptorCopies.push_back(descriptorCopy);
1611 m_descriptorSets[descriptorCopy.dstSet]->getBindings()[descriptorCopy.dstBinding]->copyValue(
1612 *m_descriptorSets[descriptorCopy.srcSet]->getBindings()[descriptorCopy.srcBinding], srcArrayElement,
1613 dstArrayElement, descriptorCount);
1614 }
1615
1616 // Generates shader source code for declarations of all descriptors
getShaderDeclarations(void) const1617 string DescriptorCommands::getShaderDeclarations(void) const
1618 {
1619 string ret;
1620
1621 for (size_t descriptorSetIdx = 0; descriptorSetIdx < m_descriptorSets.size(); descriptorSetIdx++)
1622 {
1623 const vector<DescriptorSp> bindings = m_descriptorSets[descriptorSetIdx]->getBindings();
1624
1625 for (size_t bindingIdx = 0; bindingIdx < bindings.size(); bindingIdx++)
1626 {
1627 ret += "layout (set=" + de::toString(descriptorSetIdx) + ", binding=" + de::toString(bindingIdx) +
1628 bindings[bindingIdx]->getShaderDeclaration();
1629 }
1630 }
1631
1632 return ret;
1633 }
1634
1635 // Generates shader source code for verification of all descriptor data
getDescriptorVerifications(void) const1636 string DescriptorCommands::getDescriptorVerifications(void) const
1637 {
1638 string ret;
1639
1640 for (size_t descriptorSetIdx = 0; descriptorSetIdx < m_descriptorSets.size(); descriptorSetIdx++)
1641 {
1642 const vector<DescriptorSp> bindings = m_descriptorSets[descriptorSetIdx]->getBindings();
1643
1644 for (size_t bindingIdx = 0; bindingIdx < bindings.size(); bindingIdx++)
1645 {
1646 if (m_pipelineType == PIPELINE_TYPE_COMPUTE && descriptorSetIdx == 0 && bindingIdx == bindings.size() - 1)
1647 continue; // Skip the result buffer which is always the last descriptor of set 0
1648 ret += bindings[bindingIdx]->getShaderVerifyCode();
1649 }
1650 }
1651
1652 return ret;
1653 }
1654
addResultBuffer(void)1655 void DescriptorCommands::addResultBuffer(void)
1656 {
1657 // Add result buffer if using compute pipeline
1658 if (m_pipelineType == PIPELINE_TYPE_COMPUTE)
1659 {
1660 m_resultBuffer = DescriptorSp(new StorageBufferDescriptor());
1661 addDescriptor(m_resultBuffer, 0u);
1662 }
1663 }
1664
1665 // Sets the list of dynamic areas selected for each dynamic descriptor when running the verification shader
setDynamicAreas(vector<uint32_t> areas)1666 void DescriptorCommands::setDynamicAreas(vector<uint32_t> areas)
1667 {
1668 m_dynamicAreas = areas;
1669 uint32_t areaIdx = 0;
1670
1671 for (vector<DescriptorSp>::iterator desc = m_descriptors.begin(); desc != m_descriptors.end(); desc++)
1672 {
1673 if ((*desc)->isDynamic())
1674 {
1675 vector<uint32_t> dynamicAreas;
1676
1677 for (uint32_t elementIdx = 0; elementIdx < (*desc)->getArraySize(); elementIdx++)
1678 dynamicAreas.push_back(areas[areaIdx++]);
1679
1680 (*desc)->setDynamicAreas(dynamicAreas);
1681 }
1682 }
1683 }
1684
hasDynamicAreas(void) const1685 bool DescriptorCommands::hasDynamicAreas(void) const
1686 {
1687 for (vector<DescriptorSp>::const_iterator desc = m_descriptors.begin(); desc != m_descriptors.end(); desc++)
1688 if ((*desc)->isDynamic())
1689 return true;
1690
1691 return false;
1692 }
1693
checkSupport(Context & context) const1694 void DescriptorCommands::checkSupport(Context &context) const
1695 {
1696 const InstanceInterface &vki = context.getInstanceInterface();
1697 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
1698 const VkPhysicalDeviceLimits limits = getPhysicalDeviceProperties(vki, physicalDevice).limits;
1699
1700 if (limits.maxBoundDescriptorSets <= m_descriptorSets.size())
1701 TCU_THROW(NotSupportedError, "Maximum bound descriptor sets limit exceeded.");
1702
1703 if (m_useUpdateAfterBind)
1704 context.requireDeviceFunctionality("VK_EXT_descriptor_indexing");
1705
1706 #ifndef CTS_USES_VULKANSC
1707 uint32_t numTotalIUBs = 0;
1708
1709 // Check if inline uniform blocks are supported.
1710 VkPhysicalDeviceInlineUniformBlockFeaturesEXT iubFeatures{
1711 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT, DE_NULL, VK_FALSE, VK_FALSE};
1712 VkPhysicalDeviceInlineUniformBlockPropertiesEXT iubProperties{
1713 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT, DE_NULL, 0u, 0u, 0u, 0u, 0u};
1714
1715 if (context.isDeviceFunctionalitySupported("VK_EXT_inline_uniform_block"))
1716 {
1717 VkPhysicalDeviceFeatures2 features2 = initVulkanStructure(&iubFeatures);
1718 vki.getPhysicalDeviceFeatures2(physicalDevice, &features2);
1719
1720 VkPhysicalDeviceProperties2 properties2 = initVulkanStructure(&iubProperties);
1721 vki.getPhysicalDeviceProperties2(physicalDevice, &properties2);
1722 }
1723 #endif
1724
1725 // Check physical device limits of per stage and per desriptor set descriptor count
1726 {
1727 uint32_t numPerStageSamplers = 0;
1728 uint32_t numPerStageUniformBuffers = 0;
1729 uint32_t numPerStageStorageBuffers = 0;
1730 uint32_t numPerStageSampledImages = 0;
1731 uint32_t numPerStageStorageImages = 0;
1732 uint32_t numPerStageInputAttachments = 0;
1733 uint32_t numPerStageTotalResources = 0;
1734
1735 bool usesUniformBuffer = false;
1736 bool usesSampledImage = false;
1737 bool usesStorageImage = false;
1738 bool usesStorageBuffer = false;
1739 bool usesUniformTexelBuffer = false;
1740 bool usesStorageTexelBuffer = false;
1741
1742 for (size_t descriptorSetIdx = 0; descriptorSetIdx < m_descriptorSets.size(); descriptorSetIdx++)
1743 {
1744 uint32_t numSamplers = 0;
1745 uint32_t numUniformBuffers = 0;
1746 uint32_t numUniformBuffersDynamic = 0;
1747 uint32_t numStorageBuffers = 0;
1748 uint32_t numStorageBuffersDynamic = 0;
1749 uint32_t numSampledImages = 0;
1750 uint32_t numStorageImages = 0;
1751 uint32_t numInputAttachments = 0;
1752 uint32_t numTotalResources =
1753 m_pipelineType == PIPELINE_TYPE_GRAPHICS ? 1u : 0u; // Color buffer counts as a resource.
1754
1755 const vector<DescriptorSp> &bindings = m_descriptorSets[descriptorSetIdx]->getBindings();
1756
1757 for (size_t bindingIdx = 0; bindingIdx < bindings.size(); bindingIdx++)
1758 {
1759 const uint32_t arraySize = bindings[bindingIdx]->getArraySize();
1760
1761 #ifndef CTS_USES_VULKANSC
1762 // Inline uniform blocks cannot form arrays. The array size is the size of the data array in the descriptor.
1763 if (bindings[bindingIdx]->getType() == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
1764 {
1765 const InlineUniformBlockDescriptor *iub =
1766 static_cast<InlineUniformBlockDescriptor *>(bindings[bindingIdx].get());
1767 const uint32_t bytes = iub->getSizeInBytes();
1768
1769 // Check inline uniform block size.
1770 if (bytes > iubProperties.maxInlineUniformBlockSize)
1771 {
1772 std::ostringstream msg;
1773 msg << "Maximum size for an inline uniform block exceeded by binding " << bindingIdx
1774 << " from set " << descriptorSetIdx;
1775 TCU_THROW(NotSupportedError, msg.str().c_str());
1776 }
1777
1778 ++numTotalResources;
1779 }
1780 else
1781 #endif
1782 {
1783 numTotalResources += arraySize;
1784 }
1785
1786 switch (bindings[bindingIdx]->getType())
1787 {
1788 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1789 numUniformBuffers += arraySize;
1790 usesUniformBuffer = true;
1791 break;
1792
1793 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1794 numUniformBuffers += arraySize;
1795 numUniformBuffersDynamic += arraySize;
1796 break;
1797
1798 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1799 numStorageBuffers += arraySize;
1800 usesStorageBuffer = true;
1801 break;
1802
1803 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1804 numStorageBuffers += arraySize;
1805 numStorageBuffersDynamic += arraySize;
1806 break;
1807
1808 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1809 numSamplers += arraySize;
1810 numSampledImages += arraySize;
1811 usesSampledImage = true;
1812 break;
1813
1814 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1815 numStorageImages += arraySize;
1816 usesStorageImage = true;
1817 break;
1818
1819 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1820 numStorageImages += arraySize;
1821 usesStorageTexelBuffer = true;
1822 break;
1823
1824 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1825 numInputAttachments += arraySize;
1826 break;
1827
1828 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1829 numSampledImages += arraySize;
1830 usesSampledImage = true;
1831 break;
1832
1833 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1834 numSampledImages += arraySize;
1835 usesUniformTexelBuffer = true;
1836 break;
1837
1838 case VK_DESCRIPTOR_TYPE_SAMPLER:
1839 numSamplers += arraySize;
1840 usesSampledImage = true;
1841 break;
1842
1843 #ifndef CTS_USES_VULKANSC
1844 case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
1845 ++numTotalIUBs;
1846 break;
1847 #endif
1848 default:
1849 DE_FATAL("Unexpected descriptor type");
1850 break;
1851 }
1852 }
1853
1854 if (numSamplers > limits.maxDescriptorSetSamplers)
1855 TCU_THROW(NotSupportedError, "Maximum per descriptor set sampler limit exceeded.");
1856
1857 if (numUniformBuffers > limits.maxDescriptorSetUniformBuffers)
1858 TCU_THROW(NotSupportedError, "Maximum per descriptor set uniform buffer limit exceeded.");
1859
1860 if (numUniformBuffersDynamic > limits.maxDescriptorSetUniformBuffersDynamic)
1861 TCU_THROW(NotSupportedError, "Maximum per descriptor set uniform buffer dynamic limit exceeded.");
1862
1863 if (numStorageBuffers > limits.maxDescriptorSetStorageBuffers)
1864 TCU_THROW(NotSupportedError, "Maximum per descriptor set storage buffer limit exceeded.");
1865
1866 if (numStorageBuffersDynamic > limits.maxDescriptorSetStorageBuffersDynamic)
1867 TCU_THROW(NotSupportedError, "Maximum per descriptor set storage buffer dynamic limit exceeded.");
1868
1869 if (numSampledImages > limits.maxDescriptorSetSampledImages)
1870 TCU_THROW(NotSupportedError, "Maximum per descriptor set sampled image limit exceeded.");
1871
1872 if (numStorageImages > limits.maxDescriptorSetStorageImages)
1873 TCU_THROW(NotSupportedError, "Maximum per descriptor set storage image limit exceeded.");
1874
1875 if (numInputAttachments > limits.maxDescriptorSetInputAttachments)
1876 TCU_THROW(NotSupportedError, "Maximum per descriptor set input attachment limit exceeded.");
1877
1878 numPerStageSamplers += numSamplers;
1879 numPerStageUniformBuffers += numUniformBuffers;
1880 numPerStageStorageBuffers += numStorageBuffers;
1881 numPerStageSampledImages += numSampledImages;
1882 numPerStageStorageImages += numStorageImages;
1883 numPerStageInputAttachments += numInputAttachments;
1884 numPerStageTotalResources += numTotalResources;
1885 }
1886
1887 if (numPerStageTotalResources > limits.maxPerStageResources)
1888 TCU_THROW(NotSupportedError, "Maximum per stage total resource limit exceeded.");
1889
1890 if (numPerStageSamplers > limits.maxPerStageDescriptorSamplers)
1891 TCU_THROW(NotSupportedError, "Maximum per stage sampler limit exceeded.");
1892
1893 if (numPerStageUniformBuffers > limits.maxPerStageDescriptorUniformBuffers)
1894 TCU_THROW(NotSupportedError, "Maximum per stage uniform buffer limit exceeded.");
1895
1896 if (numPerStageStorageBuffers > limits.maxPerStageDescriptorStorageBuffers)
1897 TCU_THROW(NotSupportedError, "Maximum per stage storage buffer limit exceeded.");
1898
1899 if (numPerStageSampledImages > limits.maxPerStageDescriptorSampledImages)
1900 TCU_THROW(NotSupportedError, "Maximum per stage sampled image limit exceeded.");
1901
1902 if (numPerStageStorageImages > limits.maxPerStageDescriptorStorageImages)
1903 TCU_THROW(NotSupportedError, "Maximum per stage storage image limit exceeded.");
1904
1905 if (numPerStageInputAttachments > limits.maxPerStageDescriptorInputAttachments)
1906 TCU_THROW(NotSupportedError, "Maximum per stage input attachment limit exceeded.");
1907
1908 #ifndef CTS_USES_VULKANSC
1909 if (numTotalIUBs > iubProperties.maxDescriptorSetInlineUniformBlocks ||
1910 numTotalIUBs > iubProperties.maxPerStageDescriptorInlineUniformBlocks)
1911 {
1912 TCU_THROW(NotSupportedError, "Number of per stage inline uniform blocks exceeds limits.");
1913 }
1914 #endif
1915 if (m_useUpdateAfterBind)
1916 {
1917 if (usesUniformBuffer &&
1918 !context.getDescriptorIndexingFeatures().descriptorBindingUniformBufferUpdateAfterBind)
1919 TCU_THROW(NotSupportedError, "descriptorBindingUniformBufferUpdateAfterBind not supported.");
1920
1921 if (usesSampledImage &&
1922 !context.getDescriptorIndexingFeatures().descriptorBindingSampledImageUpdateAfterBind)
1923 TCU_THROW(NotSupportedError, "descriptorBindingSampledImageUpdateAfterBind not supported.");
1924
1925 if (usesStorageImage &&
1926 !context.getDescriptorIndexingFeatures().descriptorBindingStorageImageUpdateAfterBind)
1927 TCU_THROW(NotSupportedError, "descriptorBindingStorageImageUpdateAfterBind not supported.");
1928
1929 if (usesStorageBuffer &&
1930 !context.getDescriptorIndexingFeatures().descriptorBindingStorageBufferUpdateAfterBind)
1931 TCU_THROW(NotSupportedError, "descriptorBindingStorageBufferUpdateAfterBind not supported.");
1932
1933 if (usesUniformTexelBuffer &&
1934 !context.getDescriptorIndexingFeatures().descriptorBindingUniformTexelBufferUpdateAfterBind)
1935 TCU_THROW(NotSupportedError, "descriptorBindingUniformTexelBufferUpdateAfterBind not supported.");
1936
1937 if (usesStorageTexelBuffer &&
1938 !context.getDescriptorIndexingFeatures().descriptorBindingStorageTexelBufferUpdateAfterBind)
1939 TCU_THROW(NotSupportedError, "descriptorBindingStorageTexelBufferUpdateAfterBind not supported.");
1940 }
1941 }
1942 }
1943
run(Context & context)1944 tcu::TestStatus DescriptorCommands::run(Context &context)
1945 {
1946 const DeviceInterface &vk = context.getDeviceInterface();
1947 const VkDevice device = context.getDevice();
1948 const VkQueue queue = context.getUniversalQueue();
1949 const uint32_t queueFamilyIndex = context.getUniversalQueueFamilyIndex();
1950 Allocator &allocator = context.getDefaultAllocator();
1951 tcu::TestLog &log = context.getTestContext().getLog();
1952 const Unique<VkCommandPool> commandPool(
1953 createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex));
1954 const Unique<VkCommandBuffer> commandBuffer(
1955 allocateCommandBuffer(vk, device, *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1956 const VkShaderStageFlags shaderStage =
1957 m_pipelineType == PIPELINE_TYPE_COMPUTE ? VK_SHADER_STAGE_COMPUTE_BIT : VK_SHADER_STAGE_FRAGMENT_BIT;
1958 const VkFormat resultFormat = VK_FORMAT_R8G8B8A8_UNORM;
1959 de::MovePtr<ImageWithMemory> resultImage;
1960 de::MovePtr<BufferWithMemory> resultImageBuffer;
1961 Move<VkImageView> resultImageView;
1962 Move<VkRenderPass> renderPass;
1963 Move<VkFramebuffer> framebuffer;
1964 Move<VkDescriptorPool> descriptorPool;
1965 vector<VkDescriptorSetLayoutSp> descriptorSetLayouts;
1966 vector<VkDescriptorSet> descriptorSets;
1967 Move<VkPipelineLayout> pipelineLayout;
1968 Move<VkPipeline> pipeline;
1969 vector<VkAttachmentReference> inputAttachments;
1970 vector<VkAttachmentDescription> attachmentDescriptions;
1971 vector<VkImageView> imageViews;
1972
1973 // Initialize all descriptors
1974 for (vector<DescriptorSp>::iterator desc = m_descriptors.begin(); desc != m_descriptors.end(); desc++)
1975 (*desc)->init(context, m_pipelineType);
1976
1977 uint32_t numTotalIUBs = 0;
1978 uint32_t iubTotalBytes = 0;
1979 VkDescriptorPoolCreateFlags poolCreateFlags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
1980 VkDescriptorSetLayoutCreateFlags descriptorSetLayoutCreateFlags = 0u;
1981 VkDescriptorBindingFlags bindingFlag = 0u;
1982 if (m_useUpdateAfterBind)
1983 {
1984 poolCreateFlags |= VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT;
1985 descriptorSetLayoutCreateFlags |= VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT;
1986 bindingFlag |= VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT;
1987 }
1988
1989 #ifndef CTS_USES_VULKANSC
1990 for (size_t descriptorSetIdx = 0; descriptorSetIdx < m_descriptorSets.size(); descriptorSetIdx++)
1991 {
1992 const vector<DescriptorSp> &bindings = m_descriptorSets[descriptorSetIdx]->getBindings();
1993 for (size_t bindingIdx = 0; bindingIdx < bindings.size(); bindingIdx++)
1994 {
1995 // Inline uniform blocks cannot form arrays. The array size is the size of the data array in the descriptor.
1996 if (bindings[bindingIdx]->getType() == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
1997 {
1998 const InlineUniformBlockDescriptor *iub =
1999 static_cast<InlineUniformBlockDescriptor *>(bindings[bindingIdx].get());
2000 iubTotalBytes += iub->getSizeInBytes();
2001
2002 ++numTotalIUBs;
2003 }
2004 }
2005 }
2006 #else
2007 DE_UNREF(numTotalIUBs);
2008 DE_UNREF(iubTotalBytes);
2009 #endif // CTS_USES_VULKANSC
2010
2011 // Create descriptor pool
2012 {
2013 vector<VkDescriptorPoolSize> poolSizes;
2014
2015 for (map<VkDescriptorType, uint32_t>::iterator i = m_descriptorCounts.begin(); i != m_descriptorCounts.end();
2016 i++)
2017 {
2018 VkDescriptorPoolSize poolSize = {
2019 i->first, // VkDescriptorType type
2020 i->second // uint32_t descriptorCount
2021 };
2022
2023 #ifndef CTS_USES_VULKANSC
2024 // Inline uniform blocks have a special meaning for descriptorCount.
2025 if (poolSize.type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
2026 poolSize.descriptorCount = iubTotalBytes;
2027 #endif
2028
2029 poolSizes.push_back(poolSize);
2030 }
2031
2032 VkDescriptorPoolCreateInfo descriptorPoolCreateInfo = {
2033 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // VkStructureType sType
2034 DE_NULL, // const void* pNext
2035 poolCreateFlags, // VkDescriptorPoolCreateFlags flags
2036 (uint32_t)m_descriptorSets.size(), // uint32_t maxSets
2037 (uint32_t)poolSizes.size(), // uint32_t poolSizeCount
2038 poolSizes.data(), // const VkDescriptorPoolSize* pPoolSizes
2039 };
2040
2041 // Include information about inline uniform blocks if needed.
2042 #ifndef CTS_USES_VULKANSC
2043 VkDescriptorPoolInlineUniformBlockCreateInfoEXT iubPoolCreateInfo = {
2044 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT, DE_NULL, numTotalIUBs};
2045 if (numTotalIUBs > 0)
2046 descriptorPoolCreateInfo.pNext = &iubPoolCreateInfo;
2047 #endif
2048
2049 descriptorPool = createDescriptorPool(vk, device, &descriptorPoolCreateInfo);
2050 }
2051
2052 // Create descriptor set layouts. One for each descriptor set used in this test.
2053 {
2054 for (size_t descriptorSetIdx = 0; descriptorSetIdx < m_descriptorSets.size(); descriptorSetIdx++)
2055 {
2056 vector<VkDescriptorSetLayoutBinding> layoutBindings;
2057 const vector<DescriptorSp> &bindings = m_descriptorSets[descriptorSetIdx]->getBindings();
2058 const vector<VkDescriptorBindingFlags> bindingsFlags(bindings.size(), bindingFlag);
2059
2060 for (size_t bindingIdx = 0; bindingIdx < bindings.size(); bindingIdx++)
2061 {
2062 VkDescriptorSetLayoutBinding layoutBinding = {
2063 (uint32_t)bindingIdx, // uint32_t binding
2064 bindings[bindingIdx]->getType(), // VkDescriptorType descriptorType
2065 bindings[bindingIdx]->getArraySize(), // uint32_t descriptorCount
2066 shaderStage, // VkShaderStageFlags stageFlags
2067 DE_NULL // const VkSampler* pImmutableSamplers
2068 };
2069
2070 #ifndef CTS_USES_VULKANSC
2071 // Inline uniform blocks have a special meaning for descriptorCount.
2072 if (layoutBinding.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
2073 {
2074 const InlineUniformBlockDescriptor *iub =
2075 static_cast<InlineUniformBlockDescriptor *>(bindings[bindingIdx].get());
2076 layoutBinding.descriptorCount = iub->getSizeInBytes();
2077 }
2078 #endif
2079 layoutBindings.push_back(layoutBinding);
2080 }
2081
2082 const VkDescriptorSetLayoutBindingFlagsCreateInfo bindingFlagsInfo{
2083 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO, // VkStructureType sType;
2084 DE_NULL, // const void* pNext;
2085 (uint32_t)layoutBindings.size(), // uint32_t bindingCount;
2086 layoutBindings.empty() ? DE_NULL :
2087 bindingsFlags.data(), // const VkDescriptorBindingFlags* pBindingFlags;
2088 };
2089
2090 const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo{
2091 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType
2092 m_useUpdateAfterBind ? &bindingFlagsInfo : DE_NULL, // const void* pNext
2093 descriptorSetLayoutCreateFlags, // VkDescriptorSetLayoutCreateFlags flags
2094 (uint32_t)layoutBindings.size(), // uint32_t bindingCount
2095 layoutBindings.data() // const VkDescriptorSetLayoutBinding* pBindings
2096 };
2097
2098 descriptorSetLayouts.push_back(VkDescriptorSetLayoutSp(new Unique<VkDescriptorSetLayout>(
2099 createDescriptorSetLayout(vk, device, &descriptorSetLayoutCreateInfo, DE_NULL))));
2100 }
2101 }
2102
2103 // Create descriptor sets
2104 {
2105 for (size_t descriptorSetIdx = 0; descriptorSetIdx < m_descriptorSets.size(); descriptorSetIdx++)
2106 {
2107 const VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = {
2108 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType
2109 DE_NULL, // const void* pNext
2110 *descriptorPool, // VkDescriptorPool descriptorPool
2111 1u, // uint32_t descriptorSetCount
2112 &(descriptorSetLayouts[descriptorSetIdx]->get()) // const VkDescriptorSetLayout* pSetLayouts
2113 };
2114
2115 VkDescriptorSet descriptorSet = 0;
2116 VK_CHECK(vk.allocateDescriptorSets(device, &descriptorSetAllocateInfo, &descriptorSet));
2117 descriptorSets.push_back(descriptorSet);
2118 }
2119 }
2120
2121 // Update descriptor sets when this should be done before bind
2122 if (!m_useUpdateAfterBind)
2123 updateDescriptorSets(context, descriptorSets);
2124
2125 // Create pipeline layout
2126 {
2127 vector<VkDescriptorSetLayout> descriptorSetLayoutHandles;
2128
2129 for (size_t i = 0; i < descriptorSetLayouts.size(); i++)
2130 descriptorSetLayoutHandles.push_back(descriptorSetLayouts[i]->get());
2131
2132 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {
2133 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType
2134 DE_NULL, // const void* pNext
2135 0u, // VkPipelineLayoutCreateFlags flags
2136 (uint32_t)descriptorSetLayoutHandles.size(), // uint32_t setLayoutCount
2137 descriptorSetLayoutHandles.data(), // const VkDescriptorSetLayout* pSetLayouts
2138 0u, // uint32_t pushConstantRangeCount
2139 DE_NULL // const VkPushConstantRange* pPushConstantRanges
2140 };
2141
2142 pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
2143 }
2144
2145 if (m_pipelineType == PIPELINE_TYPE_COMPUTE)
2146 {
2147 // Create compute pipeline
2148 {
2149 const Unique<VkShaderModule> shaderModule(
2150 createShaderModule(vk, device, context.getBinaryCollection().get("compute"), 0u));
2151 const VkPipelineShaderStageCreateInfo shaderStageInfo = {
2152 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType
2153 DE_NULL, // const void* pNext
2154 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags
2155 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage
2156 *shaderModule, // VkShaderModule module
2157 "main", // const char* pName
2158 DE_NULL // const VkSpecializationInfo* pSpecializationInfo
2159 };
2160
2161 const VkComputePipelineCreateInfo pipelineInfo = {
2162 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType
2163 DE_NULL, // const void* pNext
2164 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags
2165 shaderStageInfo, // VkPipelineShaderStageCreateInfo stage
2166 *pipelineLayout, // VkPipelineLayout layout
2167 DE_NULL, // VkPipeline basePipelineHandle
2168 0 // int32_t basePipelineIndex
2169 };
2170
2171 pipeline = createComputePipeline(vk, device, DE_NULL, &pipelineInfo);
2172 }
2173 }
2174 else
2175 {
2176 // Create result image
2177 {
2178 const VkImageCreateInfo imageCreateInfo = {
2179 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType stype
2180 DE_NULL, // const void* pNext
2181 0u, // VkImageCreateFlags flags
2182 VK_IMAGE_TYPE_2D, // VkImageType imageType
2183 resultFormat, // VkFormat format
2184 {(uint32_t)renderSize.x(), (uint32_t)renderSize.y(), 1}, // VkExtent3D extent
2185 1u, // uint32_t mipLevels
2186 1u, // uint32_t arrayLayers
2187 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
2188 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
2189 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage
2190 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
2191 1u, // uint32_t queueFamilyIndexCount
2192 &queueFamilyIndex, // const uint32_t* pQueueFamilyIndices
2193 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout
2194 };
2195
2196 resultImage = de::MovePtr<ImageWithMemory>(
2197 new ImageWithMemory(vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
2198 }
2199
2200 // Create result image view
2201 {
2202 const VkComponentMapping componentMapping = makeComponentMappingRGBA();
2203
2204 const VkImageSubresourceRange subresourceRange = {
2205 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
2206 0u, // uint32_t baseMipLevel
2207 1u, // uint32_t levelCount
2208 0u, // uint32_t baseArrayLayer
2209 1u, // uint32_t layerCount
2210 };
2211
2212 const VkImageViewCreateInfo imageViewCreateInfo = {
2213 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType
2214 DE_NULL, // const void* pNext
2215 0u, // VkImageViewCreateFlags flags
2216 **resultImage, // VkImage image
2217 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType
2218 resultFormat, // VkFormat format
2219 componentMapping, // VkComponentMapping components
2220 subresourceRange // VkImageSubresourceRange subresourceRange
2221 };
2222
2223 resultImageView = createImageView(vk, device, &imageViewCreateInfo);
2224 }
2225
2226 // Create result buffer
2227 {
2228 const VkDeviceSize bufferSize =
2229 renderSize.x() * renderSize.y() * tcu::getPixelSize(mapVkFormat(resultFormat));
2230 const VkBufferCreateInfo bufferCreateInfo = {
2231 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType
2232 DE_NULL, // const void* pNext
2233 0u, // VkBufferCreateFlags flags
2234 bufferSize, // VkDeviceSize size
2235 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage
2236 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
2237 0u, // uint32_t queueFamilyIndexCount
2238 DE_NULL // const uint32_t* pQueueFamilyIndices
2239 };
2240
2241 resultImageBuffer = de::MovePtr<BufferWithMemory>(
2242 new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible));
2243 }
2244
2245 // Create render pass
2246 {
2247 const VkAttachmentReference colorAttachmentRef = {
2248 0u, // uint32_t attachment
2249 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout
2250 };
2251
2252 for (vector<DescriptorSp>::const_iterator desc = m_descriptors.begin(); desc != m_descriptors.end(); desc++)
2253 {
2254 vector<VkAttachmentReference> references = (*desc)->getAttachmentReferences();
2255 inputAttachments.insert(inputAttachments.end(), references.begin(), references.end());
2256 }
2257
2258 const VkAttachmentDescription colorAttachmentDesc = {
2259 0u, // VkAttachmentDescriptionFlags flags
2260 VK_FORMAT_R8G8B8A8_UNORM, // VkFormat format
2261 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
2262 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp
2263 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
2264 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp
2265 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp
2266 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout
2267 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout
2268 };
2269
2270 attachmentDescriptions.push_back(colorAttachmentDesc);
2271
2272 const VkAttachmentDescription inputAttachmentDesc = {
2273 0u, // VkAttachmentDescriptionFlags flags
2274 VK_FORMAT_R32_SFLOAT, // VkFormat format
2275 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
2276 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp
2277 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp storeOp
2278 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp
2279 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp
2280 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout initialLayout
2281 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout finalLayout
2282 };
2283
2284 for (size_t inputAttachmentIdx = 0; inputAttachmentIdx < inputAttachments.size(); inputAttachmentIdx++)
2285 attachmentDescriptions.push_back(inputAttachmentDesc);
2286
2287 const VkSubpassDescription subpassDescription = {
2288 0u, // VkSubpassDescriptionFlags flags
2289 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
2290 (uint32_t)inputAttachments.size(), // uint32_t inputAttachmentCount
2291 inputAttachments.empty() ? DE_NULL :
2292 inputAttachments.data(), // const VkAttachmentReference* pInputAttachments
2293 1u, // uint32_t colorAttachmentCount
2294 &colorAttachmentRef, // const VkAttachmentReference* pColorAttachments
2295 DE_NULL, // const VkAttachmentReference* pResolveAttachments
2296 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment
2297 0u, // uint32_t preserveAttachmentCount
2298 DE_NULL // const uint32_t* pPreserveAttachments
2299 };
2300
2301 const VkRenderPassCreateInfo renderPassCreateInfo = {
2302 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType
2303 DE_NULL, // const void* pNext
2304 0u, // VkRenderPassCreateFlags flags
2305 (uint32_t)attachmentDescriptions.size(), // uint32_t attachmentCount
2306 attachmentDescriptions.data(), // const VkAttachmentDescription* pAttachments
2307 1u, // uint32_t subpassCount
2308 &subpassDescription, // const VkSubpassDescription* pSubpasses
2309 0u, // uint32_t dependencyCount
2310 DE_NULL // const VkSubpassDependency* pDependencies
2311 };
2312
2313 renderPass = createRenderPass(vk, device, &renderPassCreateInfo);
2314 }
2315
2316 // Create framebuffer
2317 {
2318 imageViews.push_back(*resultImageView);
2319
2320 // Add input attachment image views
2321 for (vector<DescriptorSp>::const_iterator desc = m_descriptors.begin(); desc != m_descriptors.end(); desc++)
2322 {
2323 vector<VkImageViewSp> inputAttachmentViews = (*desc)->getImageViews();
2324
2325 for (size_t imageViewIdx = 0; imageViewIdx < inputAttachmentViews.size(); imageViewIdx++)
2326 imageViews.push_back(**inputAttachmentViews[imageViewIdx]);
2327 }
2328
2329 const VkFramebufferCreateInfo framebufferCreateInfo = {
2330 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType
2331 DE_NULL, // const void* pNext
2332 0u, // VkFramebufferCreateFlags flags
2333 *renderPass, // VkRenderPass renderPass
2334 (uint32_t)imageViews.size(), // uint32_t attachmentCount
2335 imageViews.data(), // const VkImageView* pAttachments
2336 (uint32_t)renderSize.x(), // uint32_t width
2337 (uint32_t)renderSize.y(), // uint32_t height
2338 1u, // uint32_t layers
2339 };
2340
2341 framebuffer = createFramebuffer(vk, device, &framebufferCreateInfo);
2342 }
2343
2344 // Create graphics pipeline
2345 {
2346 const Unique<VkShaderModule> vertexShaderModule(
2347 createShaderModule(vk, device, context.getBinaryCollection().get("vertex"), 0u));
2348 const Unique<VkShaderModule> fragmentShaderModule(
2349 createShaderModule(vk, device, context.getBinaryCollection().get("fragment"), 0u));
2350
2351 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = {
2352 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType
2353 DE_NULL, // const void* pNext
2354 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags
2355 0u, // uint32_t bindingCount
2356 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions
2357 0u, // uint32_t attributeCount
2358 DE_NULL, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions
2359 };
2360
2361 const std::vector<VkViewport> viewports(1, makeViewport(renderSize));
2362 const std::vector<VkRect2D> scissors(1, makeRect2D(renderSize));
2363
2364 pipeline = makeGraphicsPipeline(
2365 vk, // const DeviceInterface& vk
2366 device, // const VkDevice device
2367 *pipelineLayout, // const VkPipelineLayout pipelineLayout
2368 *vertexShaderModule, // const VkShaderModule vertexShaderModule
2369 DE_NULL, // const VkShaderModule tessellationControlShaderModule
2370 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
2371 DE_NULL, // const VkShaderModule geometryShaderModule
2372 *fragmentShaderModule, // const VkShaderModule fragmentShaderModule
2373 *renderPass, // const VkRenderPass renderPass
2374 viewports, // const std::vector<VkViewport>& viewports
2375 scissors, // const std::vector<VkRect2D>& scissors
2376 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
2377 0u, // const uint32_t subpass
2378 0u, // const uint32_t patchControlPoints
2379 &vertexInputStateParams); // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
2380 }
2381 }
2382
2383 // Run verification shader
2384 {
2385 const VkPipelineBindPoint pipelineBindPoint =
2386 m_pipelineType == PIPELINE_TYPE_COMPUTE ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS;
2387 vector<uint32_t> offsets;
2388
2389 if (hasDynamicAreas())
2390 {
2391 for (size_t areaIdx = 0; areaIdx < m_dynamicAreas.size(); areaIdx++)
2392 offsets.push_back(m_dynamicAreas[areaIdx] * 256u);
2393 }
2394
2395 beginCommandBuffer(vk, *commandBuffer);
2396
2397 if (m_pipelineType == PIPELINE_TYPE_GRAPHICS)
2398 {
2399 const VkRect2D renderArea = makeRect2D(renderSize);
2400 const tcu::Vec4 clearColor(1.0f, 0.0f, 0.0f, 1.0f);
2401
2402 beginRenderPass(vk, *commandBuffer, *renderPass, *framebuffer, renderArea, clearColor);
2403 }
2404
2405 vk.cmdBindPipeline(*commandBuffer, pipelineBindPoint, *pipeline);
2406 vk.cmdBindDescriptorSets(*commandBuffer, pipelineBindPoint, *pipelineLayout, 0u,
2407 (uint32_t)descriptorSets.size(), descriptorSets.data(), (uint32_t)offsets.size(),
2408 offsets.empty() ? DE_NULL : offsets.data());
2409
2410 // Update descriptor sets when this should be done after bind
2411 if (m_useUpdateAfterBind)
2412 updateDescriptorSets(context, descriptorSets);
2413
2414 if (m_pipelineType == PIPELINE_TYPE_COMPUTE)
2415 {
2416 vk.cmdDispatch(*commandBuffer, 1u, 1u, 1u);
2417 }
2418 else
2419 {
2420 vk.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
2421 endRenderPass(vk, *commandBuffer);
2422 copyImageToBuffer(vk, *commandBuffer, **resultImage, resultImageBuffer->get(), renderSize);
2423 }
2424
2425 endCommandBuffer(vk, *commandBuffer);
2426 submitCommandsAndWait(vk, device, queue, *commandBuffer);
2427 }
2428
2429 if (m_pipelineType == PIPELINE_TYPE_COMPUTE)
2430 {
2431 // Invalidate result buffer
2432 m_resultBuffer->invalidate(context);
2433
2434 // Verify result data
2435 const auto data = m_resultBuffer->getData();
2436 if (data[0] == 1)
2437 return tcu::TestStatus::pass("Pass");
2438 else
2439 return tcu::TestStatus::fail("Data validation failed");
2440 }
2441 else
2442 {
2443 invalidateAlloc(vk, device, resultImageBuffer->getAllocation());
2444
2445 // Verify result image
2446 tcu::ConstPixelBufferAccess resultBufferAccess(mapVkFormat(resultFormat), renderSize.x(), renderSize.y(), 1,
2447 resultImageBuffer->getAllocation().getHostPtr());
2448
2449 for (int32_t y = 0; y < renderSize.y(); y++)
2450 for (int32_t x = 0; x < renderSize.x(); x++)
2451 {
2452 Vec4 pixel = resultBufferAccess.getPixel(x, y, 0);
2453
2454 if (pixel.x() != 0.0f || pixel.y() != 1.0f || pixel.z() != 0.0f || pixel.w() != 1.0f)
2455 {
2456 // Log result image before failing.
2457 log << tcu::TestLog::ImageSet("Result", "")
2458 << tcu::TestLog::Image("Rendered", "Rendered image", resultBufferAccess)
2459 << tcu::TestLog::EndImageSet;
2460 return tcu::TestStatus::fail("Result image validation failed");
2461 }
2462 }
2463
2464 return tcu::TestStatus::pass("Pass");
2465 }
2466 }
2467
updateDescriptorSets(Context & context,const vector<VkDescriptorSet> & descriptorSets)2468 void DescriptorCommands::updateDescriptorSets(Context &context, const vector<VkDescriptorSet> &descriptorSets)
2469 {
2470 const DeviceInterface &vk = context.getDeviceInterface();
2471 const VkDevice device = context.getDevice();
2472 vector<VkWriteDescriptorSet> descriptorWrites;
2473 vector<VkCopyDescriptorSet> descriptorCopies;
2474
2475 // Write descriptors that are marked as needing initialization
2476 for (size_t descriptorSetIdx = 0; descriptorSetIdx < m_descriptorSets.size(); descriptorSetIdx++)
2477 {
2478 const vector<DescriptorSp> &bindings = m_descriptorSets[descriptorSetIdx]->getBindings();
2479
2480 for (size_t bindingIdx = 0; bindingIdx < bindings.size(); bindingIdx++)
2481 {
2482 VkWriteDescriptorSet descriptorWrite = bindings[bindingIdx]->getDescriptorWrite();
2483
2484 descriptorWrite.dstSet = descriptorSets[descriptorSetIdx];
2485 descriptorWrite.dstBinding = (uint32_t)bindingIdx;
2486
2487 if (descriptorWrite.descriptorCount > 0)
2488 descriptorWrites.push_back(descriptorWrite);
2489 }
2490 }
2491
2492 for (size_t copyIdx = 0; copyIdx < m_descriptorCopies.size(); copyIdx++)
2493 {
2494 const DescriptorCopy indices = m_descriptorCopies[copyIdx];
2495 const VkCopyDescriptorSet copy = {
2496 VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET, // VkStructureType sType
2497 DE_NULL, // const void* pNext
2498 descriptorSets[indices.srcSet], // VkDescriptorSet srcSet
2499 indices.srcBinding, // uint32_t srcBinding
2500 indices.srcArrayElement, // uint32_t srcArrayElement
2501 descriptorSets[indices.dstSet], // VkDescriptorSet dstSet
2502 indices.dstBinding, // uint32_t dstBinding
2503 indices.dstArrayElement, // uint32_t dstArrayElement
2504 indices.descriptorCount // uint32_t descriptorCount
2505 };
2506
2507 descriptorCopies.push_back(copy);
2508 }
2509
2510 // Update descriptors with writes and copies
2511 vk.updateDescriptorSets(device, (uint32_t)descriptorWrites.size(), descriptorWrites.data(),
2512 (uint32_t)descriptorCopies.size(), descriptorCopies.data());
2513 }
2514
DescriptorCopyTestInstance(Context & context,DescriptorCommandsSp commands)2515 DescriptorCopyTestInstance::DescriptorCopyTestInstance(Context &context, DescriptorCommandsSp commands)
2516 : vkt::TestInstance(context)
2517 , m_commands(commands)
2518 {
2519 }
2520
~DescriptorCopyTestInstance(void)2521 DescriptorCopyTestInstance::~DescriptorCopyTestInstance(void)
2522 {
2523 }
2524
DescriptorCopyTestCase(tcu::TestContext & context,const char * name,DescriptorCommandsSp commands)2525 DescriptorCopyTestCase::DescriptorCopyTestCase(tcu::TestContext &context, const char *name,
2526 DescriptorCommandsSp commands)
2527 : vkt::TestCase(context, name)
2528 , m_commands(commands)
2529 {
2530 }
2531
~DescriptorCopyTestCase(void)2532 DescriptorCopyTestCase::~DescriptorCopyTestCase(void)
2533 {
2534 }
2535
initPrograms(SourceCollections & programCollection) const2536 void DescriptorCopyTestCase::initPrograms(SourceCollections &programCollection) const
2537 {
2538 if (m_commands->getPipelineType() == PIPELINE_TYPE_COMPUTE)
2539 {
2540 string computeSrc = "#version 430\n"
2541 "\n" +
2542 m_commands->getShaderDeclarations() +
2543 "\n"
2544 "void main()\n"
2545 "{\n"
2546 "int result = 1;\n" +
2547 m_commands->getDescriptorVerifications() + "storageBuffer" +
2548 de::toString(m_commands->getResultBufferId()) +
2549 ".data = result;\n"
2550 "}\n";
2551
2552 programCollection.glslSources.add("compute") << glu::ComputeSource(computeSrc);
2553 }
2554 else
2555 {
2556 // Produce quad vertices using vertex index
2557 string vertexSrc = "#version 450\n"
2558 "out gl_PerVertex\n"
2559 "{\n"
2560 " vec4 gl_Position;\n"
2561 "};\n"
2562 "void main()\n"
2563 "{\n"
2564 " gl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
2565 " ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
2566 "}\n";
2567
2568 programCollection.glslSources.add("vertex") << glu::VertexSource(vertexSrc);
2569
2570 string fragmentSrc = "#version 430\n"
2571 "\n" +
2572 m_commands->getShaderDeclarations() +
2573 "layout (location = 0) out vec4 outColor;\n"
2574 "\n"
2575 "void main()\n"
2576 "{\n"
2577 "int result = 1;\n" +
2578 m_commands->getDescriptorVerifications() +
2579 "if (result == 1) outColor = vec4(0, 1, 0, 1);\n"
2580 "else outColor = vec4(1, 0, 1, 0);\n"
2581 "}\n";
2582
2583 programCollection.glslSources.add("fragment") << glu::FragmentSource(fragmentSrc);
2584 }
2585 }
2586
createInstance(Context & context) const2587 TestInstance *DescriptorCopyTestCase::createInstance(Context &context) const
2588 {
2589 TestInstance *result = new DescriptorCopyTestInstance(context, m_commands);
2590 m_commands.clear();
2591 return result;
2592 }
2593
checkSupport(Context & context) const2594 void DescriptorCopyTestCase::checkSupport(Context &context) const
2595 {
2596 m_commands->checkSupport(context);
2597 }
2598
iterate(void)2599 tcu::TestStatus DescriptorCopyTestInstance::iterate(void)
2600 {
2601 return m_commands->run(m_context);
2602 }
2603
2604 template <class T>
addDescriptorCopyTests(tcu::TestContext & testCtx,de::MovePtr<tcu::TestCaseGroup> & group,string name,PipelineType pipelineType,bool useUpdateAfterBind)2605 void addDescriptorCopyTests(tcu::TestContext &testCtx, de::MovePtr<tcu::TestCaseGroup> &group, string name,
2606 PipelineType pipelineType, bool useUpdateAfterBind)
2607 {
2608 // Simple test copying inside the same set.
2609 {
2610 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, useUpdateAfterBind));
2611 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 3u)), 0u);
2612 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 2u)), 0u);
2613
2614 commands->copyDescriptor(0u, 0u, // from
2615 0u, 1u); // to
2616
2617 vector<uint32_t> dynamicAreas;
2618 dynamicAreas.push_back(2u);
2619 dynamicAreas.push_back(1u);
2620 commands->setDynamicAreas(dynamicAreas);
2621
2622 commands->addResultBuffer();
2623
2624 group->addChild(new DescriptorCopyTestCase(testCtx, (name + "_0").c_str(), commands));
2625 }
2626
2627 // Simple test copying between different sets.
2628 {
2629 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, useUpdateAfterBind));
2630 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 2u)), 0u);
2631 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 4u)), 1u);
2632
2633 commands->copyDescriptor(0u, 0u, // from
2634 1u, 0u); // to
2635
2636 vector<uint32_t> dynamicAreas;
2637 dynamicAreas.push_back(0u);
2638 dynamicAreas.push_back(1u);
2639 commands->setDynamicAreas(dynamicAreas);
2640
2641 commands->addResultBuffer();
2642
2643 group->addChild(new DescriptorCopyTestCase(testCtx, (name + "_1").c_str(), commands));
2644 }
2645
2646 // Simple test copying between different sets. Destination not updated.
2647 {
2648 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, useUpdateAfterBind));
2649 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 2u)), 0u);
2650 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 0u, 1u)), 1u);
2651
2652 commands->copyDescriptor(0u, 0u, // from
2653 1u, 0u); // to
2654
2655 vector<uint32_t> dynamicAreas;
2656 dynamicAreas.push_back(1u);
2657 dynamicAreas.push_back(0u);
2658 commands->setDynamicAreas(dynamicAreas);
2659
2660 commands->addResultBuffer();
2661
2662 group->addChild(new DescriptorCopyTestCase(testCtx, (name + "_2").c_str(), commands));
2663 }
2664
2665 // Five sets and several copies.
2666 {
2667 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, useUpdateAfterBind));
2668 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 3u)), 0u);
2669 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 4u)), 0u);
2670 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 2u)), 1u);
2671 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 1u)), 1u);
2672 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 2u)), 1u);
2673 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 5u)), 4u);
2674
2675 commands->copyDescriptor(4u, 0u, // from
2676 0u, 0u); // to
2677
2678 commands->copyDescriptor(0u, 1u, // from
2679 1u, 2u); // to
2680
2681 commands->copyDescriptor(0u, 1u, // from
2682 1u, 1u); // to
2683
2684 vector<uint32_t> dynamicAreas;
2685 dynamicAreas.push_back(1u);
2686 dynamicAreas.push_back(0u);
2687 dynamicAreas.push_back(1u);
2688 dynamicAreas.push_back(0u);
2689 dynamicAreas.push_back(0u);
2690 dynamicAreas.push_back(4u);
2691 commands->setDynamicAreas(dynamicAreas);
2692
2693 commands->addResultBuffer();
2694
2695 group->addChild(new DescriptorCopyTestCase(testCtx, (name + "_3").c_str(), commands));
2696 }
2697
2698 // Several identical copies
2699 {
2700 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, useUpdateAfterBind));
2701 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 2u)), 0u);
2702 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 4u)), 1u);
2703 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 2u)), 1u);
2704
2705 for (uint32_t i = 0; i < 100; i++)
2706 {
2707 commands->copyDescriptor(0u, 0u, // from
2708 1u, 0u); // to
2709 }
2710
2711 commands->copyDescriptor(1u, 1u, // from
2712 0u, 0u); // to
2713
2714 for (uint32_t i = 0; i < 100; i++)
2715 {
2716 commands->copyDescriptor(1u, 0u, // from
2717 1u, 1u); // to
2718 }
2719
2720 vector<uint32_t> dynamicAreas;
2721 dynamicAreas.push_back(0u);
2722 dynamicAreas.push_back(1u);
2723 dynamicAreas.push_back(1u);
2724 commands->setDynamicAreas(dynamicAreas);
2725
2726 commands->addResultBuffer();
2727
2728 group->addChild(new DescriptorCopyTestCase(testCtx, (name + "_4").c_str(), commands));
2729 }
2730
2731 // Copy descriptors back and forth
2732 {
2733 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, useUpdateAfterBind));
2734 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 3u)), 0u);
2735 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 3u)), 1u);
2736 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 3u)), 1u);
2737
2738 commands->copyDescriptor(0u, 0u, // from
2739 1u, 0u); // to
2740
2741 commands->copyDescriptor(1u, 0u, // from
2742 0u, 0u); // to
2743
2744 commands->copyDescriptor(1u, 1u, // from
2745 0u, 0u); // to
2746
2747 commands->copyDescriptor(1u, 1u, // from
2748 0u, 0u); // to
2749
2750 commands->copyDescriptor(1u, 0u, // from
2751 1u, 1u); // to
2752
2753 vector<uint32_t> dynamicAreas;
2754 dynamicAreas.push_back(1u);
2755 dynamicAreas.push_back(0u);
2756 dynamicAreas.push_back(0u);
2757 commands->setDynamicAreas(dynamicAreas);
2758
2759 commands->addResultBuffer();
2760
2761 group->addChild(new DescriptorCopyTestCase(testCtx, (name + "_5").c_str(), commands));
2762 }
2763
2764 // Copy between non-consecutive descriptor sets
2765 {
2766 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, useUpdateAfterBind));
2767 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 3u)), 0u);
2768 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 2u)), 5u);
2769 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 2u)), 5u);
2770
2771 commands->copyDescriptor(0u, 0u, // from
2772 5u, 1u); // to
2773
2774 vector<uint32_t> dynamicAreas;
2775 dynamicAreas.push_back(2u);
2776 dynamicAreas.push_back(1u);
2777 dynamicAreas.push_back(1u);
2778 commands->setDynamicAreas(dynamicAreas);
2779
2780 commands->addResultBuffer();
2781
2782 group->addChild(new DescriptorCopyTestCase(testCtx, (name + "_6").c_str(), commands));
2783 }
2784
2785 // Simple 3 sized array to 3 sized array inside the same set.
2786 {
2787 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, useUpdateAfterBind));
2788 commands->addDescriptor(DescriptorSp(new T(3u, 0u, 3u, 3u)), 0u);
2789 commands->addDescriptor(DescriptorSp(new T(3u, 0u, 3u, 4u)), 0u);
2790
2791 commands->copyDescriptor(0u, 0u, 0u, // from
2792 0u, 1u, 0u, // to
2793 3u); // num descriptors
2794
2795 vector<uint32_t> dynamicAreas;
2796 dynamicAreas.push_back(1u);
2797 dynamicAreas.push_back(0u);
2798 dynamicAreas.push_back(2u);
2799
2800 dynamicAreas.push_back(2u);
2801 dynamicAreas.push_back(1u);
2802 dynamicAreas.push_back(0u);
2803 commands->setDynamicAreas(dynamicAreas);
2804
2805 commands->addResultBuffer();
2806
2807 group->addChild(new DescriptorCopyTestCase(testCtx, (name + "_array0").c_str(), commands));
2808 }
2809
2810 // Simple 2 sized array to 3 sized array into different set.
2811 {
2812 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, useUpdateAfterBind));
2813 commands->addDescriptor(DescriptorSp(new T(2u, 0u, 2u, 2u)), 0u);
2814 commands->addDescriptor(DescriptorSp(new T(3u, 0u, 3u, 5u)), 1u);
2815
2816 commands->copyDescriptor(0u, 0u, 0u, // from
2817 1u, 0u, 0u, // to
2818 2u); // num descriptors
2819
2820 vector<uint32_t> dynamicAreas;
2821 dynamicAreas.push_back(1u);
2822 dynamicAreas.push_back(0u);
2823
2824 dynamicAreas.push_back(1u);
2825 dynamicAreas.push_back(0u);
2826 dynamicAreas.push_back(1u);
2827 commands->setDynamicAreas(dynamicAreas);
2828
2829 commands->addResultBuffer();
2830
2831 group->addChild(new DescriptorCopyTestCase(testCtx, (name + "_array1").c_str(), commands));
2832 }
2833
2834 // Update array partially with writes and partially with a copy
2835 {
2836 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, useUpdateAfterBind));
2837 commands->addDescriptor(DescriptorSp(new T(4u, 0u, 4u, 3u)), 0u);
2838 commands->addDescriptor(DescriptorSp(new T(8u, 0u, 5u, 4u)), 0u);
2839
2840 commands->copyDescriptor(0u, 0u, 1u, // from
2841 0u, 1u, 5u, // to
2842 3u); // num descriptors
2843
2844 vector<uint32_t> dynamicAreas;
2845 dynamicAreas.push_back(2u);
2846 dynamicAreas.push_back(0u);
2847 dynamicAreas.push_back(1u);
2848 dynamicAreas.push_back(1u);
2849
2850 dynamicAreas.push_back(2u);
2851 dynamicAreas.push_back(0u);
2852 dynamicAreas.push_back(1u);
2853 dynamicAreas.push_back(2u);
2854 dynamicAreas.push_back(0u);
2855 dynamicAreas.push_back(1u);
2856 dynamicAreas.push_back(1u);
2857 dynamicAreas.push_back(2u);
2858 commands->setDynamicAreas(dynamicAreas);
2859
2860 commands->addResultBuffer();
2861
2862 group->addChild(new DescriptorCopyTestCase(testCtx, (name + "_array2").c_str(), commands));
2863 }
2864 }
2865
addSamplerCopyTests(tcu::TestContext & testCtx,de::MovePtr<tcu::TestCaseGroup> & group,PipelineType pipelineType,bool useUpdateAfterBind)2866 void addSamplerCopyTests(tcu::TestContext &testCtx, de::MovePtr<tcu::TestCaseGroup> &group, PipelineType pipelineType,
2867 bool useUpdateAfterBind)
2868 {
2869 // Simple copy between two samplers in the same set
2870 {
2871 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, useUpdateAfterBind));
2872 SamplerDescriptor *sampler0(new SamplerDescriptor());
2873 SamplerDescriptor *sampler1(new SamplerDescriptor());
2874 SampledImageDescriptor *image(new SampledImageDescriptor());
2875 sampler0->addImage(image);
2876 sampler1->addImage(image);
2877
2878 commands->addDescriptor(DescriptorSp(sampler0), 0u);
2879 commands->addDescriptor(DescriptorSp(sampler1), 0u);
2880 commands->addDescriptor(DescriptorSp(image), 0u);
2881
2882 commands->copyDescriptor(0u, 0u, // from
2883 0u, 1u); // to
2884
2885 commands->addResultBuffer();
2886
2887 group->addChild(new DescriptorCopyTestCase(testCtx, "sampler_0", commands));
2888 }
2889
2890 // Simple 3 sized array to 3 sized array inside the same set.
2891 {
2892 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, useUpdateAfterBind));
2893 SamplerDescriptor *sampler0(new SamplerDescriptor(3u, 0u, 3u));
2894 // One sampler in between to get the border colors to originally mismatch between sampler0 and sampler1.
2895 SamplerDescriptor *sampler1(new SamplerDescriptor());
2896 SamplerDescriptor *sampler2(new SamplerDescriptor(3u, 0u, 3u));
2897 SampledImageDescriptor *image(new SampledImageDescriptor());
2898
2899 sampler0->addImage(image, 3u);
2900 sampler2->addImage(image, 3u);
2901
2902 commands->addDescriptor(DescriptorSp(sampler0), 0u);
2903 commands->addDescriptor(DescriptorSp(sampler1), 0u);
2904 commands->addDescriptor(DescriptorSp(sampler2), 0u);
2905 commands->addDescriptor(DescriptorSp(image), 0u);
2906
2907 commands->copyDescriptor(0u, 0u, 0u, // from
2908 0u, 2u, 0u, // to
2909 3u); // num descriptors
2910
2911 commands->addResultBuffer();
2912
2913 group->addChild(new DescriptorCopyTestCase(testCtx, "sampler_array0", commands));
2914 }
2915
2916 // Simple 2 sized array to 3 sized array into different set.
2917 {
2918 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, useUpdateAfterBind));
2919 SamplerDescriptor *sampler0(new SamplerDescriptor(2u, 0u, 2u));
2920 SamplerDescriptor *sampler1(new SamplerDescriptor(3u, 0u, 3u));
2921 SampledImageDescriptor *image(new SampledImageDescriptor());
2922
2923 sampler0->addImage(image, 2u);
2924 sampler1->addImage(image, 3u);
2925
2926 commands->addDescriptor(DescriptorSp(sampler0), 0u);
2927 commands->addDescriptor(DescriptorSp(sampler1), 1u);
2928 commands->addDescriptor(DescriptorSp(image), 0u);
2929
2930 commands->copyDescriptor(0u, 0u, 0u, // from
2931 1u, 0u, 1u, // to
2932 2u); // num descriptors
2933
2934 commands->addResultBuffer();
2935
2936 group->addChild(new DescriptorCopyTestCase(testCtx, "sampler_array1", commands));
2937 }
2938 }
2939
addSampledImageCopyTests(tcu::TestContext & testCtx,de::MovePtr<tcu::TestCaseGroup> & group,PipelineType pipelineType,bool useUpdateAfterBind)2940 void addSampledImageCopyTests(tcu::TestContext &testCtx, de::MovePtr<tcu::TestCaseGroup> &group,
2941 PipelineType pipelineType, bool useUpdateAfterBind)
2942 {
2943 // Simple copy between two images in the same set
2944 {
2945 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, useUpdateAfterBind));
2946 SamplerDescriptor *sampler(new SamplerDescriptor());
2947 SampledImageDescriptor *image0(new SampledImageDescriptor());
2948 SampledImageDescriptor *image1(new SampledImageDescriptor());
2949 image0->addSampler(sampler);
2950 image1->addSampler(sampler);
2951
2952 commands->addDescriptor(DescriptorSp(image0), 0u);
2953 commands->addDescriptor(DescriptorSp(image1), 0u);
2954 commands->addDescriptor(DescriptorSp(sampler), 0u);
2955
2956 commands->copyDescriptor(0u, 0u, // from
2957 0u, 1u); // to
2958
2959 commands->addResultBuffer();
2960
2961 group->addChild(new DescriptorCopyTestCase(testCtx, "sampled_image_0", commands));
2962 }
2963
2964 // Simple 3 sized array to 3 sized array inside the same set.
2965 {
2966 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, useUpdateAfterBind));
2967 SamplerDescriptor *sampler(new SamplerDescriptor());
2968 SampledImageDescriptor *image0(new SampledImageDescriptor(3u, 0u, 3u));
2969 SampledImageDescriptor *image1(new SampledImageDescriptor(3u, 0u, 3u));
2970 image0->addSampler(sampler, 3u);
2971 image1->addSampler(sampler, 3u);
2972
2973 commands->addDescriptor(DescriptorSp(sampler), 0u);
2974 commands->addDescriptor(DescriptorSp(image0), 0u);
2975 commands->addDescriptor(DescriptorSp(image1), 0u);
2976
2977 commands->copyDescriptor(0u, 1u, 0u, // from
2978 0u, 2u, 0u, // to
2979 3u); // num descriptors
2980
2981 commands->addResultBuffer();
2982
2983 group->addChild(new DescriptorCopyTestCase(testCtx, "sampled_image_array0", commands));
2984 }
2985 }
2986
2987 // Mixture of different descriptors in the same test
addMixedDescriptorCopyTests(tcu::TestContext & testCtx,de::MovePtr<tcu::TestCaseGroup> & group,PipelineType pipelineType)2988 void addMixedDescriptorCopyTests(tcu::TestContext &testCtx, de::MovePtr<tcu::TestCaseGroup> &group,
2989 PipelineType pipelineType)
2990 {
2991 {
2992 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, false));
2993 SamplerDescriptor *sampler0(new SamplerDescriptor());
2994 SamplerDescriptor *sampler1(new SamplerDescriptor());
2995 SampledImageDescriptor *image0(new SampledImageDescriptor());
2996 SampledImageDescriptor *image1(new SampledImageDescriptor());
2997 StorageBufferDescriptor *storageBuffer0(new StorageBufferDescriptor());
2998 StorageBufferDescriptor *storageBuffer1(new StorageBufferDescriptor());
2999 StorageBufferDescriptor *storageBuffer2 = new StorageBufferDescriptor();
3000 sampler0->addImage(image0);
3001 sampler1->addImage(image1);
3002
3003 commands->addDescriptor(DescriptorSp(sampler0), 0u); // Set 0, binding 0
3004 commands->addDescriptor(DescriptorSp(storageBuffer0), 0u); // Set 0, binding 1
3005 commands->addDescriptor(DescriptorSp(image0), 0u); // Set 0, binding 2
3006 commands->addDescriptor(DescriptorSp(storageBuffer1), 0u); // Set 0, binding 3
3007 commands->addDescriptor(DescriptorSp(sampler1), 1u); // Set 1, binding 0
3008 commands->addDescriptor(DescriptorSp(image1), 1u); // Set 1, binding 1
3009 commands->addDescriptor(DescriptorSp(storageBuffer2), 1u); // Set 1, binding 2
3010
3011 // image1 to image0
3012 commands->copyDescriptor(1u, 1u, // from
3013 0u, 2u); // to
3014
3015 // storageBuffer0 to storageBuffer1
3016 commands->copyDescriptor(0u, 1u, // from
3017 0u, 3u); // to
3018
3019 // storageBuffer1 to storageBuffer2
3020 commands->copyDescriptor(0u, 3u, // from
3021 1u, 2u); // to
3022
3023 commands->addResultBuffer();
3024
3025 group->addChild(new DescriptorCopyTestCase(testCtx, "mix_0", commands));
3026 }
3027
3028 {
3029 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, false));
3030 StorageTexelBufferDescriptor *storageTexelBuffer0(new StorageTexelBufferDescriptor());
3031 StorageTexelBufferDescriptor *storageTexelBuffer1(new StorageTexelBufferDescriptor());
3032 UniformBufferDescriptor *uniformBuffer0(new UniformBufferDescriptor());
3033 UniformBufferDescriptor *uniformBuffer1(new UniformBufferDescriptor());
3034 UniformBufferDescriptor *uniformBuffer2(new UniformBufferDescriptor());
3035 DynamicStorageBufferDescriptor *dynamicStorageBuffer0(new DynamicStorageBufferDescriptor(1u, 0u, 1u, 3u));
3036 DynamicStorageBufferDescriptor *dynamicStorageBuffer1(new DynamicStorageBufferDescriptor(1u, 0u, 1u, 4u));
3037
3038 commands->addDescriptor(DescriptorSp(storageTexelBuffer0), 0u); // Set 0, binding 0
3039 commands->addDescriptor(DescriptorSp(uniformBuffer0), 0u); // Set 0, binding 1
3040 commands->addDescriptor(DescriptorSp(dynamicStorageBuffer0), 0u); // Set 0, binding 2
3041 commands->addDescriptor(DescriptorSp(uniformBuffer1), 0u); // Set 0, binding 3
3042 commands->addDescriptor(DescriptorSp(dynamicStorageBuffer1), 1u); // Set 1, binding 0
3043 commands->addDescriptor(DescriptorSp(storageTexelBuffer1), 1u); // Set 1, binding 1
3044 commands->addDescriptor(DescriptorSp(uniformBuffer2), 1u); // Set 1, binding 2
3045
3046 vector<uint32_t> dynamicAreas;
3047 dynamicAreas.push_back(2u);
3048 dynamicAreas.push_back(1u);
3049 commands->setDynamicAreas(dynamicAreas);
3050
3051 // uniformBuffer0 to uniformBuffer2
3052 commands->copyDescriptor(0u, 1u, // from
3053 1u, 2u); // to
3054
3055 // uniformBuffer1 to uniformBuffer2
3056 commands->copyDescriptor(0u, 3u, // from
3057 1u, 2u); // to
3058
3059 // storageTexelBuffer1 to storageTexelBuffer0
3060 commands->copyDescriptor(1u, 1u, // from
3061 0u, 0u); // to
3062
3063 // dynamicStorageBuffer0 to dynamicStorageBuffer1
3064 commands->copyDescriptor(0u, 2u, // from
3065 1u, 0u); // to
3066
3067 commands->addResultBuffer();
3068
3069 group->addChild(new DescriptorCopyTestCase(testCtx, "mix_1", commands));
3070 }
3071
3072 if (pipelineType == PIPELINE_TYPE_GRAPHICS)
3073 {
3074 // Mixture of descriptors, including input attachment.
3075 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, false));
3076 InputAttachmentDescriptor *inputAttachment0(new InputAttachmentDescriptor());
3077 InputAttachmentDescriptor *inputAttachment1(new InputAttachmentDescriptor());
3078 CombinedImageSamplerDescriptor *combinedImageSampler0(new CombinedImageSamplerDescriptor());
3079 CombinedImageSamplerDescriptor *combinedImageSampler1(new CombinedImageSamplerDescriptor());
3080 UniformTexelBufferDescriptor *uniformTexelBuffer0(new UniformTexelBufferDescriptor(5u, 0u, 5u));
3081 UniformTexelBufferDescriptor *uniformTexelBuffer1(new UniformTexelBufferDescriptor(3u, 1u, 1u));
3082
3083 commands->addDescriptor(DescriptorSp(combinedImageSampler0), 0u); // Set 0, binding 0
3084 commands->addDescriptor(DescriptorSp(inputAttachment0), 0u); // Set 0, binding 1
3085 commands->addDescriptor(DescriptorSp(uniformTexelBuffer0), 0u); // Set 0, binding 2
3086 commands->addDescriptor(DescriptorSp(combinedImageSampler1), 1u); // Set 1, binding 0
3087 commands->addDescriptor(DescriptorSp(inputAttachment1), 1u); // Set 1, binding 1
3088 commands->addDescriptor(DescriptorSp(uniformTexelBuffer1), 1u); // Set 1, binding 2
3089
3090 // uniformTexelBuffer0[1..3] to uniformTexelBuffer1[0..2]
3091 commands->copyDescriptor(0u, 2u, 1u, // from
3092 1u, 2u, 0u, // to
3093 3u); // num descriptors
3094
3095 // inputAttachment0 to inputAttachment1
3096 commands->copyDescriptor(0u, 1u, // from
3097 1u, 1u); // to
3098
3099 // combinedImageSampler0 to combinedImageSampler1
3100 commands->copyDescriptor(0u, 0u, // from
3101 1u, 0u); // to
3102
3103 commands->addResultBuffer();
3104
3105 group->addChild(new DescriptorCopyTestCase(testCtx, "mix_2", commands));
3106 }
3107
3108 #ifndef CTS_USES_VULKANSC
3109 if (pipelineType == PIPELINE_TYPE_GRAPHICS)
3110 {
3111 // Similar to the previous one, but adding inline uniform blocks to the mix.
3112 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, false));
3113 InlineUniformBlockDescriptor *iub0(new InlineUniformBlockDescriptor(4u, 0u, 4u));
3114 InlineUniformBlockDescriptor *iub1(new InlineUniformBlockDescriptor(4u, 0u, 1u));
3115 InputAttachmentDescriptor *inputAttachment0(new InputAttachmentDescriptor());
3116 InputAttachmentDescriptor *inputAttachment1(new InputAttachmentDescriptor());
3117 CombinedImageSamplerDescriptor *combinedImageSampler0(new CombinedImageSamplerDescriptor());
3118 CombinedImageSamplerDescriptor *combinedImageSampler1(new CombinedImageSamplerDescriptor());
3119 UniformTexelBufferDescriptor *uniformTexelBuffer0(new UniformTexelBufferDescriptor(5u, 0u, 5u));
3120 UniformTexelBufferDescriptor *uniformTexelBuffer1(new UniformTexelBufferDescriptor(3u, 1u, 1u));
3121
3122 commands->addDescriptor(DescriptorSp(iub0), 0u); // Set 0, binding 0
3123 commands->addDescriptor(DescriptorSp(combinedImageSampler0), 0u); // Set 0, binding 1
3124 commands->addDescriptor(DescriptorSp(inputAttachment0), 0u); // Set 0, binding 2
3125 commands->addDescriptor(DescriptorSp(uniformTexelBuffer0), 0u); // Set 0, binding 3
3126 commands->addDescriptor(DescriptorSp(iub1), 1u); // Set 1, binding 0
3127 commands->addDescriptor(DescriptorSp(combinedImageSampler1), 1u); // Set 1, binding 1
3128 commands->addDescriptor(DescriptorSp(inputAttachment1), 1u); // Set 1, binding 2
3129 commands->addDescriptor(DescriptorSp(uniformTexelBuffer1), 1u); // Set 1, binding 3
3130
3131 // iub0.data[0..2] to iub1.data[1..3]
3132 commands->copyDescriptor(0u, 0u, 0u, // from
3133 1u, 0u, 1u, // to
3134 3u); // num descriptors
3135
3136 // uniformTexelBuffer0[1..3] to uniformTexelBuffer1[0..2]
3137 commands->copyDescriptor(0u, 3u, 1u, // from
3138 1u, 3u, 0u, // to
3139 3u); // num descriptors
3140
3141 // inputAttachment0 to inputAttachment1
3142 commands->copyDescriptor(0u, 2u, // from
3143 1u, 2u); // to
3144
3145 // combinedImageSampler0 to combinedImageSampler1
3146 commands->copyDescriptor(0u, 1u, // from
3147 1u, 1u); // to
3148
3149 commands->addResultBuffer();
3150
3151 group->addChild(new DescriptorCopyTestCase(testCtx, "mix_3", commands));
3152 }
3153 #endif
3154
3155 // Mixture of descriptors using descriptor arrays
3156 {
3157 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, false));
3158 CombinedImageSamplerDescriptor *combinedImageSampler0(new CombinedImageSamplerDescriptor(3u, 0u, 3u));
3159 CombinedImageSamplerDescriptor *combinedImageSampler1(new CombinedImageSamplerDescriptor(4u, 0u, 2u));
3160 CombinedImageSamplerDescriptor *combinedImageSampler2(new CombinedImageSamplerDescriptor(3u, 0u, 3u));
3161 StorageImageDescriptor *storageImage0(new StorageImageDescriptor(5u, 0u, 5u));
3162 StorageImageDescriptor *storageImage1(new StorageImageDescriptor(3u, 0u, 0u));
3163 StorageBufferDescriptor *storageBuffer0(new StorageBufferDescriptor(2u, 0u, 1u));
3164 StorageBufferDescriptor *storageBuffer1(new StorageBufferDescriptor(3u, 0u, 3u));
3165
3166 commands->addDescriptor(DescriptorSp(combinedImageSampler0), 0u); // Set 0, binding 0
3167 commands->addDescriptor(DescriptorSp(storageImage0), 0u); // Set 0, binding 1
3168 commands->addDescriptor(DescriptorSp(combinedImageSampler1), 0u); // Set 0, binding 2
3169 commands->addDescriptor(DescriptorSp(storageBuffer0), 0u); // Set 0, binding 3
3170 commands->addDescriptor(DescriptorSp(storageBuffer1), 0u); // Set 0, binding 4
3171 commands->addDescriptor(DescriptorSp(storageImage1), 1u); // Set 1, binding 0
3172 commands->addDescriptor(DescriptorSp(combinedImageSampler2), 1u); // Set 1, binding 1
3173
3174 // combinedImageSampler0[1..2] to combinedImageSampler1[2..3]
3175 commands->copyDescriptor(0u, 0u, 1u, // from
3176 0u, 2u, 2u, // to
3177 2u); // num descriptors
3178
3179 // storageImage0[2..4] to storageImage1[0..2]
3180 commands->copyDescriptor(0u, 1u, 2u, // from
3181 1u, 0u, 0u, // to
3182 3u); // num descriptors
3183
3184 // storageBuffer1[1..2] to storageBuffer0[0..1]
3185 commands->copyDescriptor(0u, 4u, 1u, // from
3186 0u, 3u, 0u, // to
3187 2u); // num descriptors
3188
3189 commands->addResultBuffer();
3190
3191 group->addChild(new DescriptorCopyTestCase(testCtx, "mix_array0", commands));
3192 }
3193
3194 // Similar to the previous one but including inline uniform blocks.
3195 #ifndef CTS_USES_VULKANSC
3196 {
3197 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, false));
3198 InlineUniformBlockDescriptor *iub0(new InlineUniformBlockDescriptor(4u, 0u, 1u));
3199 InlineUniformBlockDescriptor *iub1(new InlineUniformBlockDescriptor(4u, 0u, 4u));
3200 CombinedImageSamplerDescriptor *combinedImageSampler0(new CombinedImageSamplerDescriptor(3u, 0u, 3u));
3201 CombinedImageSamplerDescriptor *combinedImageSampler1(new CombinedImageSamplerDescriptor(4u, 0u, 2u));
3202 CombinedImageSamplerDescriptor *combinedImageSampler2(new CombinedImageSamplerDescriptor(3u, 0u, 3u));
3203 StorageImageDescriptor *storageImage0(new StorageImageDescriptor(5u, 0u, 5u));
3204 StorageImageDescriptor *storageImage1(new StorageImageDescriptor(3u, 0u, 0u));
3205 StorageBufferDescriptor *storageBuffer0(new StorageBufferDescriptor(2u, 0u, 1u));
3206 StorageBufferDescriptor *storageBuffer1(new StorageBufferDescriptor(3u, 0u, 3u));
3207
3208 commands->addDescriptor(DescriptorSp(iub0), 0u); // Set 0, binding 0
3209 commands->addDescriptor(DescriptorSp(combinedImageSampler0), 0u); // Set 0, binding 1
3210 commands->addDescriptor(DescriptorSp(storageImage0), 0u); // Set 0, binding 2
3211 commands->addDescriptor(DescriptorSp(combinedImageSampler1), 0u); // Set 0, binding 3
3212 commands->addDescriptor(DescriptorSp(storageBuffer0), 0u); // Set 0, binding 4
3213 commands->addDescriptor(DescriptorSp(storageBuffer1), 0u); // Set 0, binding 5
3214 commands->addDescriptor(DescriptorSp(combinedImageSampler2), 0u); // Set 0, binding 6
3215 commands->addDescriptor(DescriptorSp(iub1), 1u); // Set 1, binding 0
3216 commands->addDescriptor(DescriptorSp(storageImage1), 1u); // Set 1, binding 1
3217
3218 // iub1.data[0..2] to iub0.data[1..3]
3219 commands->copyDescriptor(1u, 0u, 0u, // from
3220 0u, 0u, 1u, // to
3221 3u); // num descriptors
3222
3223 // combinedImageSampler0[1..2] to combinedImageSampler1[2..3]
3224 commands->copyDescriptor(0u, 1u, 1u, // from
3225 0u, 3u, 2u, // to
3226 2u); // num descriptors
3227
3228 // storageImage0[2..4] to storageImage1[0..2]
3229 commands->copyDescriptor(0u, 2u, 2u, // from
3230 1u, 1u, 0u, // to
3231 3u); // num descriptors
3232
3233 // storageBuffer1[1..2] to storageBuffer0[0..1]
3234 commands->copyDescriptor(0u, 5u, 1u, // from
3235 0u, 4u, 0u, // to
3236 2u); // num descriptors
3237
3238 commands->addResultBuffer();
3239
3240 group->addChild(new DescriptorCopyTestCase(testCtx, "mix_array1", commands));
3241 }
3242 #endif
3243 }
3244
3245 } // namespace
3246
createTestsForAllDescriptorTypes(tcu::TestContext & testCtx,de::MovePtr<tcu::TestCaseGroup> & parentGroup,PipelineType pipelineType,bool useUpdateAfterBind=false)3247 void createTestsForAllDescriptorTypes(tcu::TestContext &testCtx, de::MovePtr<tcu::TestCaseGroup> &parentGroup,
3248 PipelineType pipelineType, bool useUpdateAfterBind = false)
3249 {
3250 addDescriptorCopyTests<UniformBufferDescriptor>(testCtx, parentGroup, "uniform_buffer", pipelineType,
3251 useUpdateAfterBind);
3252 addDescriptorCopyTests<StorageBufferDescriptor>(testCtx, parentGroup, "storage_buffer", pipelineType,
3253 useUpdateAfterBind);
3254 addDescriptorCopyTests<CombinedImageSamplerDescriptor>(testCtx, parentGroup, "combined_image_sampler", pipelineType,
3255 useUpdateAfterBind);
3256 addDescriptorCopyTests<StorageImageDescriptor>(testCtx, parentGroup, "storage_image", pipelineType,
3257 useUpdateAfterBind);
3258 addDescriptorCopyTests<UniformTexelBufferDescriptor>(testCtx, parentGroup, "uniform_texel_buffer", pipelineType,
3259 useUpdateAfterBind);
3260 addDescriptorCopyTests<StorageTexelBufferDescriptor>(testCtx, parentGroup, "storage_texel_buffer", pipelineType,
3261 useUpdateAfterBind);
3262
3263 #ifndef CTS_USES_VULKANSC
3264 addDescriptorCopyTests<InlineUniformBlockDescriptor>(testCtx, parentGroup, "inline_uniform_block", pipelineType,
3265 useUpdateAfterBind);
3266 #endif
3267
3268 // create tests that can be run only without UpdateAfterBind
3269 if (useUpdateAfterBind == false)
3270 {
3271 addDescriptorCopyTests<DynamicUniformBufferDescriptor>(testCtx, parentGroup, "uniform_buffer_dynamic",
3272 pipelineType, false);
3273 addDescriptorCopyTests<DynamicStorageBufferDescriptor>(testCtx, parentGroup, "storage_buffer_dynamic",
3274 pipelineType, false);
3275
3276 // create tests that are graphics pipeline specific
3277 if (pipelineType == PIPELINE_TYPE_GRAPHICS)
3278 addDescriptorCopyTests<InputAttachmentDescriptor>(testCtx, parentGroup, "input_attachment",
3279 PIPELINE_TYPE_GRAPHICS, false);
3280
3281 addMixedDescriptorCopyTests(testCtx, parentGroup, pipelineType);
3282 }
3283
3284 addSamplerCopyTests(testCtx, parentGroup, pipelineType, useUpdateAfterBind);
3285 addSampledImageCopyTests(testCtx, parentGroup, pipelineType, useUpdateAfterBind);
3286 }
3287
createDescriptorCopyTests(tcu::TestContext & testCtx)3288 tcu::TestCaseGroup *createDescriptorCopyTests(tcu::TestContext &testCtx)
3289 {
3290 de::MovePtr<tcu::TestCaseGroup> descriptorCopyGroup(new tcu::TestCaseGroup(testCtx, "descriptor_copy"));
3291
3292 de::MovePtr<tcu::TestCaseGroup> computeGroup(new tcu::TestCaseGroup(testCtx, "compute"));
3293 de::MovePtr<tcu::TestCaseGroup> graphicsGroup(new tcu::TestCaseGroup(testCtx, "graphics"));
3294 // Graphics tests with update after bind
3295 de::MovePtr<tcu::TestCaseGroup> graphicsUABGroup(new tcu::TestCaseGroup(testCtx, "graphics_uab"));
3296
3297 createTestsForAllDescriptorTypes(testCtx, computeGroup, PIPELINE_TYPE_COMPUTE);
3298 createTestsForAllDescriptorTypes(testCtx, graphicsGroup, PIPELINE_TYPE_GRAPHICS);
3299 createTestsForAllDescriptorTypes(testCtx, graphicsUABGroup, PIPELINE_TYPE_GRAPHICS, true);
3300
3301 descriptorCopyGroup->addChild(computeGroup.release());
3302 descriptorCopyGroup->addChild(graphicsGroup.release());
3303 descriptorCopyGroup->addChild(graphicsUABGroup.release());
3304
3305 return descriptorCopyGroup.release();
3306 }
3307
3308 } // namespace BindingModel
3309 } // namespace vkt
3310