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::__anonbca3896c0111::InlineUniformBlockDescriptor::PaddedUint222 PaddedUint() : value(0)
223 {
224 deMemset(padding, 0, sizeof(padding));
225 }
PaddedUintvkt::BindingModel::__anonbca3896c0111::InlineUniformBlockDescriptor::PaddedUint226 PaddedUint(uint32_t value_) : value(value_)
227 {
228 deMemset(padding, 0, sizeof(padding));
229 }
operator =vkt::BindingModel::__anonbca3896c0111::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 nullptr, // 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 nullptr // 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 nullptr, // 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 nullptr, // const void* pNext
793 VK_NULL_HANDLE, // VkDescriptorSet dstSet
794 0u, // uint32_t dstBinding
795 firstElement, // uint32_t dstArrayElement
796 getNumWrittenElements(), // uint32_t descriptorCount
797 getType(), // VkDescriptorType descriptorType
798 nullptr, // const VkDescriptorImageInfo pImageInfo
799 usesBufferView() ? nullptr :
800 &m_descriptorBufferInfos[firstElement], // const VkDescriptorBufferInfo* pBufferInfo
801 usesBufferView() ? &m_bufferViewHandles[firstElement] :
802 nullptr // 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 = nullptr;
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 VK_NULL_HANDLE, // VkDescriptorSet dstSet
871 0u, // uint32_t dstBinding
872 m_writeStartByteOffset, // uint32_t dstArrayElement
873 m_bytesToWrite, // uint32_t descriptorCount
874 getType(), // VkDescriptorType descriptorType
875 nullptr, // const VkDescriptorImageInfo pImageInfo
876 nullptr, // const VkDescriptorBufferInfo* pBufferInfo
877 nullptr // 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 nullptr, // 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 nullptr, // 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 nullptr, // 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 nullptr, // 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, nullptr, 0u, nullptr, 1u, &preImageBarrier);
1254 vk.cmdClearColorImage(*cmdBuffer, **m_images[imageIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor.color,
1255 1, &subresourceRange);
1256 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
1257 pipelineType == PIPELINE_TYPE_COMPUTE ? VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT :
1258 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
1259 (VkDependencyFlags)0u, 0u, nullptr, 0u, nullptr, 1u, &postImageBarrier);
1260 endCommandBuffer(vk, *cmdBuffer);
1261 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
1262 }
1263 }
1264
getDescriptorWrite(void)1265 VkWriteDescriptorSet ImageDescriptor::getDescriptorWrite(void)
1266 {
1267 const uint32_t firstElement = getFirstWrittenElement();
1268
1269 // Set and binding will be overwritten later
1270 const VkWriteDescriptorSet descriptorWrite = {
1271 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType
1272 nullptr, // const void* pNext
1273 VK_NULL_HANDLE, // VkDescriptorSet dstSet
1274 0u, // uint32_t dstBinding
1275 firstElement, // uint32_t dstArrayElement
1276 getNumWrittenElements(), // uint32_t descriptorCount
1277 getType(), // VkDescriptorType descriptorType
1278 &m_descriptorImageInfos[firstElement], // const VkDescriptorImageInfo pImageInfo
1279 nullptr, // const VkDescriptorBufferInfo* pBufferInfo
1280 nullptr // const VkBufferView* pTexelBufferView
1281 };
1282
1283 return descriptorWrite;
1284 }
1285
InputAttachmentDescriptor(uint32_t arraySize,uint32_t writeStart,uint32_t elementsToWrite,uint32_t numDynamicAreas)1286 InputAttachmentDescriptor::InputAttachmentDescriptor(uint32_t arraySize, uint32_t writeStart, uint32_t elementsToWrite,
1287 uint32_t numDynamicAreas)
1288 : ImageDescriptor(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, arraySize, writeStart, elementsToWrite, 1u)
1289 , m_originalAttachmentIndex(s_nextAttachmentIndex)
1290 {
1291 DE_UNREF(numDynamicAreas);
1292
1293 for (uint32_t i = 0; i < m_arraySize; i++)
1294 m_attachmentIndices.push_back(s_nextAttachmentIndex++);
1295 }
1296
~InputAttachmentDescriptor(void)1297 InputAttachmentDescriptor::~InputAttachmentDescriptor(void)
1298 {
1299 }
1300
getShaderDeclaration(void) const1301 string InputAttachmentDescriptor::getShaderDeclaration(void) const
1302 {
1303 return string(", input_attachment_index=" + de::toString(m_originalAttachmentIndex) +
1304 ") uniform subpassInput inputAttachment" + de::toString(m_id) + getArrayString(m_arraySize) + ";\n");
1305 }
1306
getShaderVerifyCode(void) const1307 string InputAttachmentDescriptor::getShaderVerifyCode(void) const
1308 {
1309 string ret;
1310
1311 for (uint32_t i = 0; i < m_arraySize; i++)
1312 {
1313 if (m_data[i].written || m_data[i].copiedInto)
1314 ret += string("if (subpassLoad(inputAttachment") + de::toString(m_id) + getArrayString(i) +
1315 ").x != " + de::toString(m_data[i].data[0]) + ") result = 0;\n";
1316 }
1317
1318 return ret;
1319 }
1320
copyValue(const Descriptor & src,uint32_t srcElement,uint32_t dstElement,uint32_t numElements)1321 void InputAttachmentDescriptor::copyValue(const Descriptor &src, uint32_t srcElement, uint32_t dstElement,
1322 uint32_t numElements)
1323 {
1324 Descriptor::copyValue(src, srcElement, dstElement, numElements);
1325
1326 for (uint32_t elementIdx = 0; elementIdx < numElements; elementIdx++)
1327 {
1328 m_attachmentIndices[elementIdx + dstElement] =
1329 reinterpret_cast<const InputAttachmentDescriptor &>(src).m_attachmentIndices[elementIdx + srcElement];
1330 }
1331 }
1332
getAttachmentReferences(void) const1333 vector<VkAttachmentReference> InputAttachmentDescriptor::getAttachmentReferences(void) const
1334 {
1335 vector<VkAttachmentReference> references;
1336 for (uint32_t i = 0; i < m_arraySize; i++)
1337 {
1338 const VkAttachmentReference attachmentReference = {
1339 // The first attachment is the color buffer, thus +1
1340 m_attachmentIndices[i] + 1, // uint32_t attachment
1341 getImageLayout() // VkImageLayout layout
1342 };
1343
1344 references.push_back(attachmentReference);
1345 }
1346
1347 return references;
1348 }
1349
CombinedImageSamplerDescriptor(uint32_t arraySize,uint32_t writeStart,uint32_t elementsToWrite,uint32_t numDynamicAreas)1350 CombinedImageSamplerDescriptor::CombinedImageSamplerDescriptor(uint32_t arraySize, uint32_t writeStart,
1351 uint32_t elementsToWrite, uint32_t numDynamicAreas)
1352 : ImageDescriptor(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, arraySize, writeStart, elementsToWrite, 1u)
1353 {
1354 DE_UNREF(numDynamicAreas);
1355 }
1356
~CombinedImageSamplerDescriptor(void)1357 CombinedImageSamplerDescriptor::~CombinedImageSamplerDescriptor(void)
1358 {
1359 }
1360
getShaderDeclaration(void) const1361 string CombinedImageSamplerDescriptor::getShaderDeclaration(void) const
1362 {
1363 return string(") uniform sampler2D texSampler" + de::toString(m_id) + getArrayString(m_arraySize) + ";\n");
1364 }
1365
getShaderVerifyCode(void) const1366 string CombinedImageSamplerDescriptor::getShaderVerifyCode(void) const
1367 {
1368 string ret;
1369
1370 for (uint32_t i = 0; i < m_arraySize; i++)
1371 {
1372 if (m_data[i].written || m_data[i].copiedInto)
1373 ret += string("if (texture(texSampler") + de::toString(m_id) + getArrayString(i) +
1374 ", vec2(0)).x != " + de::toString(m_data[i].data[0]) + ") result = 0;\n";
1375 }
1376
1377 return ret;
1378 }
1379
SampledImageDescriptor(uint32_t arraySize,uint32_t writeStart,uint32_t elementsToWrite,uint32_t numDynamicAreas)1380 SampledImageDescriptor::SampledImageDescriptor(uint32_t arraySize, uint32_t writeStart, uint32_t elementsToWrite,
1381 uint32_t numDynamicAreas)
1382 : ImageDescriptor(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, arraySize, writeStart, elementsToWrite, 1u)
1383 {
1384 DE_UNREF(numDynamicAreas);
1385 }
1386
~SampledImageDescriptor(void)1387 SampledImageDescriptor::~SampledImageDescriptor(void)
1388 {
1389 }
1390
getShaderDeclaration(void) const1391 string SampledImageDescriptor::getShaderDeclaration(void) const
1392 {
1393 return string(") uniform texture2D sampledImage" + de::toString(m_id) + getArrayString(m_arraySize) + ";\n");
1394 }
1395
getShaderVerifyCode(void) const1396 string SampledImageDescriptor::getShaderVerifyCode(void) const
1397 {
1398 string ret;
1399
1400 for (uint32_t i = 0; i < m_arraySize; i++)
1401 {
1402 if ((m_data[i].written || m_data[i].copiedInto) && m_samplers.size() > i)
1403 {
1404 ret += string("if (texture(sampler2D(sampledImage") + de::toString(m_id) + getArrayString(i) + ", sampler" +
1405 de::toString(m_samplers[i]->getId()) + "), vec2(0)).x != " + de::toString(m_data[i].data[0]) +
1406 ") result = 0;\n";
1407 }
1408 }
1409
1410 return ret;
1411 }
1412
StorageImageDescriptor(uint32_t arraySize,uint32_t writeStart,uint32_t elementsToWrite,uint32_t numDynamicAreas)1413 StorageImageDescriptor::StorageImageDescriptor(uint32_t arraySize, uint32_t writeStart, uint32_t elementsToWrite,
1414 uint32_t numDynamicAreas)
1415 : ImageDescriptor(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, arraySize, writeStart, elementsToWrite, 1u)
1416 {
1417 DE_UNREF(numDynamicAreas);
1418 }
1419
~StorageImageDescriptor(void)1420 StorageImageDescriptor::~StorageImageDescriptor(void)
1421 {
1422 }
1423
getShaderDeclaration(void) const1424 string StorageImageDescriptor::getShaderDeclaration(void) const
1425 {
1426 return string(", r32f) readonly uniform image2D image" + de::toString(m_id) + getArrayString(m_arraySize) + ";\n");
1427 }
1428
getShaderVerifyCode(void) const1429 string StorageImageDescriptor::getShaderVerifyCode(void) const
1430 {
1431 string ret;
1432
1433 for (uint32_t i = 0; i < m_arraySize; i++)
1434 {
1435 if (m_data[i].written || m_data[i].copiedInto)
1436 ret += string("if (imageLoad(image") + de::toString(m_id) + getArrayString(i) +
1437 ", ivec2(0)).x != " + de::toString(m_data[i].data[0]) + ") result = 0;\n";
1438 }
1439
1440 return ret;
1441 }
1442
SamplerDescriptor(uint32_t arraySize,uint32_t writeStart,uint32_t elementsToWrite,uint32_t numDynamicAreas)1443 SamplerDescriptor::SamplerDescriptor(uint32_t arraySize, uint32_t writeStart, uint32_t elementsToWrite,
1444 uint32_t numDynamicAreas)
1445 : Descriptor(VK_DESCRIPTOR_TYPE_SAMPLER, arraySize, writeStart, elementsToWrite, 1u)
1446 {
1447 DE_UNREF(numDynamicAreas);
1448 }
1449
~SamplerDescriptor(void)1450 SamplerDescriptor::~SamplerDescriptor(void)
1451 {
1452 }
1453
init(Context & context,PipelineType pipelineType)1454 void SamplerDescriptor::init(Context &context, PipelineType pipelineType)
1455 {
1456 DE_UNREF(pipelineType);
1457
1458 const DeviceInterface &vk = context.getDeviceInterface();
1459 const VkDevice device = context.getDevice();
1460 const VkFormat format = VK_FORMAT_R32_SFLOAT;
1461
1462 // Create samplers
1463 for (uint32_t i = 0; i < m_arraySize; i++)
1464 {
1465 const float borderValue = (float)((m_id + i) % 2);
1466 const tcu::Sampler sampler =
1467 tcu::Sampler(tcu::Sampler::CLAMP_TO_BORDER, tcu::Sampler::CLAMP_TO_BORDER, tcu::Sampler::CLAMP_TO_BORDER,
1468 tcu::Sampler::NEAREST, tcu::Sampler::NEAREST, 0.0f, true, tcu::Sampler::COMPAREMODE_NONE, 0,
1469 Vec4(borderValue), true);
1470 const tcu::TextureFormat texFormat = mapVkFormat(format);
1471 const VkSamplerCreateInfo samplerParams = mapSampler(sampler, texFormat);
1472
1473 m_samplers.push_back(VkSamplerSp(new Unique<VkSampler>(createSampler(vk, device, &samplerParams))));
1474 }
1475
1476 // Create descriptor image infos
1477 for (uint32_t i = 0; i < m_arraySize; i++)
1478 {
1479 const VkDescriptorImageInfo imageInfo = {
1480 **m_samplers[i], // VkSampler sampler
1481 VK_NULL_HANDLE, // VkImageView imageView
1482 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout imageLayout
1483 };
1484
1485 m_descriptorImageInfos.push_back(imageInfo);
1486 }
1487 }
1488
getDescriptorWrite(void)1489 VkWriteDescriptorSet SamplerDescriptor::getDescriptorWrite(void)
1490 {
1491 const uint32_t firstElement = getFirstWrittenElement();
1492
1493 // Set and binding will be overwritten later
1494 const VkWriteDescriptorSet descriptorWrite = {
1495 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType
1496 nullptr, // const void* pNext
1497 VK_NULL_HANDLE, // VkDescriptorSet dstSet
1498 0u, // uint32_t dstBinding
1499 firstElement, // uint32_t dstArrayElement
1500 getNumWrittenElements(), // uint32_t descriptorCount
1501 getType(), // VkDescriptorType descriptorType
1502 &m_descriptorImageInfos[firstElement], // const VkDescriptorImageInfo pImageInfo
1503 nullptr, // const VkDescriptorBufferInfo* pBufferInfo
1504 nullptr // const VkBufferView* pTexelBufferView
1505 };
1506
1507 return descriptorWrite;
1508 }
1509
getShaderDeclaration(void) const1510 string SamplerDescriptor::getShaderDeclaration(void) const
1511 {
1512 return string(") uniform sampler sampler" + de::toString(m_id) + getArrayString(m_arraySize) + ";\n");
1513 }
1514
getShaderVerifyCode(void) const1515 string SamplerDescriptor::getShaderVerifyCode(void) const
1516 {
1517 string ret;
1518
1519 for (uint32_t i = 0; i < m_arraySize; i++)
1520 {
1521 if ((m_data[i].written || m_data[i].copiedInto) && m_images.size() > i)
1522 {
1523 // Sample from (-1, -1) to get border color.
1524 ret += string("if (texture(sampler2D(sampledImage") + de::toString(m_images[i]->getId()) + ", sampler" +
1525 de::toString(m_id) + getArrayString(i) + "), vec2(-1)).x != " + de::toString(m_data[i].data[0] % 2) +
1526 ") result = 0;\n";
1527 }
1528 }
1529
1530 return ret;
1531 }
1532
DescriptorSet(void)1533 DescriptorSet::DescriptorSet(void)
1534 {
1535 }
1536
~DescriptorSet(void)1537 DescriptorSet::~DescriptorSet(void)
1538 {
1539 }
1540
addBinding(DescriptorSp descriptor)1541 void DescriptorSet::addBinding(DescriptorSp descriptor)
1542 {
1543 m_bindings.push_back(descriptor);
1544 }
1545
DescriptorCommands(PipelineType pipelineType,bool useUpdateAfterBind)1546 DescriptorCommands::DescriptorCommands(PipelineType pipelineType, bool useUpdateAfterBind)
1547 : m_pipelineType(pipelineType)
1548 , m_useUpdateAfterBind(useUpdateAfterBind)
1549 {
1550 // Reset counters
1551 Descriptor::s_nextId = 0xabc;
1552 InputAttachmentDescriptor::s_nextAttachmentIndex = 0;
1553 }
1554
~DescriptorCommands(void)1555 DescriptorCommands::~DescriptorCommands(void)
1556 {
1557 }
1558
addDescriptor(DescriptorSp descriptor,uint32_t descriptorSet)1559 void DescriptorCommands::addDescriptor(DescriptorSp descriptor, uint32_t descriptorSet)
1560 {
1561 const VkDescriptorType type = descriptor->getType();
1562
1563 // Create descriptor set objects until one with the given index exists
1564 while (m_descriptorSets.size() <= descriptorSet)
1565 m_descriptorSets.push_back(DescriptorSetSp(new DescriptorSet()));
1566
1567 m_descriptorSets[descriptorSet]->addBinding(descriptor);
1568
1569 // Keep track of how many descriptors of each type is needed. Inline uniform blocks cannot form arrays. We reuse the array size
1570 // as size of the data array for them, within a single descriptor.
1571
1572 #ifndef CTS_USES_VULKANSC
1573 const uint32_t count = ((type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) ? 1u : descriptor->getArraySize());
1574 #else
1575 const uint32_t count = descriptor->getArraySize();
1576 #endif
1577
1578 if (m_descriptorCounts.find(type) != m_descriptorCounts.end())
1579 m_descriptorCounts[type] += count;
1580 else
1581 m_descriptorCounts[type] = count;
1582
1583 // Keep descriptors also in a flat list for easier iteration
1584 m_descriptors.push_back(descriptor);
1585 }
1586
copyDescriptor(uint32_t srcSet,uint32_t srcBinding,uint32_t srcArrayElement,uint32_t dstSet,uint32_t dstBinding,uint32_t dstArrayElement,uint32_t descriptorCount)1587 void DescriptorCommands::copyDescriptor(uint32_t srcSet, uint32_t srcBinding, uint32_t srcArrayElement, uint32_t dstSet,
1588 uint32_t dstBinding, uint32_t dstArrayElement, uint32_t descriptorCount)
1589 {
1590 // For inline uniform blocks, (src|dst)ArrayElement are data array indices and descriptorCount is the number of integers to copy.
1591 DescriptorCopy descriptorCopy = {srcSet, srcBinding, srcArrayElement, dstSet,
1592 dstBinding, dstArrayElement, descriptorCount};
1593
1594 #ifndef CTS_USES_VULKANSC
1595 if (m_descriptorSets[srcSet]->getBindings()[srcBinding]->getType() == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
1596 {
1597 // For inline uniform blocks, these members of VkCopyDescriptorSet are offsets and sizes in bytes.
1598 const InlineUniformBlockDescriptor *iub =
1599 static_cast<InlineUniformBlockDescriptor *>(m_descriptorSets[srcSet]->getBindings()[srcBinding].get());
1600 const uint32_t elementSize = iub->getElementSizeInBytes();
1601
1602 descriptorCopy.srcArrayElement *= elementSize;
1603 descriptorCopy.dstArrayElement *= elementSize;
1604 descriptorCopy.descriptorCount *= elementSize;
1605 }
1606 #endif
1607
1608 m_descriptorCopies.push_back(descriptorCopy);
1609 m_descriptorSets[descriptorCopy.dstSet]->getBindings()[descriptorCopy.dstBinding]->copyValue(
1610 *m_descriptorSets[descriptorCopy.srcSet]->getBindings()[descriptorCopy.srcBinding], srcArrayElement,
1611 dstArrayElement, descriptorCount);
1612 }
1613
1614 // Generates shader source code for declarations of all descriptors
getShaderDeclarations(void) const1615 string DescriptorCommands::getShaderDeclarations(void) const
1616 {
1617 string ret;
1618
1619 for (size_t descriptorSetIdx = 0; descriptorSetIdx < m_descriptorSets.size(); descriptorSetIdx++)
1620 {
1621 const vector<DescriptorSp> bindings = m_descriptorSets[descriptorSetIdx]->getBindings();
1622
1623 for (size_t bindingIdx = 0; bindingIdx < bindings.size(); bindingIdx++)
1624 {
1625 ret += "layout (set=" + de::toString(descriptorSetIdx) + ", binding=" + de::toString(bindingIdx) +
1626 bindings[bindingIdx]->getShaderDeclaration();
1627 }
1628 }
1629
1630 return ret;
1631 }
1632
1633 // Generates shader source code for verification of all descriptor data
getDescriptorVerifications(void) const1634 string DescriptorCommands::getDescriptorVerifications(void) const
1635 {
1636 string ret;
1637
1638 for (size_t descriptorSetIdx = 0; descriptorSetIdx < m_descriptorSets.size(); descriptorSetIdx++)
1639 {
1640 const vector<DescriptorSp> bindings = m_descriptorSets[descriptorSetIdx]->getBindings();
1641
1642 for (size_t bindingIdx = 0; bindingIdx < bindings.size(); bindingIdx++)
1643 {
1644 if (m_pipelineType == PIPELINE_TYPE_COMPUTE && descriptorSetIdx == 0 && bindingIdx == bindings.size() - 1)
1645 continue; // Skip the result buffer which is always the last descriptor of set 0
1646 ret += bindings[bindingIdx]->getShaderVerifyCode();
1647 }
1648 }
1649
1650 return ret;
1651 }
1652
addResultBuffer(void)1653 void DescriptorCommands::addResultBuffer(void)
1654 {
1655 // Add result buffer if using compute pipeline
1656 if (m_pipelineType == PIPELINE_TYPE_COMPUTE)
1657 {
1658 m_resultBuffer = DescriptorSp(new StorageBufferDescriptor());
1659 addDescriptor(m_resultBuffer, 0u);
1660 }
1661 }
1662
1663 // Sets the list of dynamic areas selected for each dynamic descriptor when running the verification shader
setDynamicAreas(vector<uint32_t> areas)1664 void DescriptorCommands::setDynamicAreas(vector<uint32_t> areas)
1665 {
1666 m_dynamicAreas = areas;
1667 uint32_t areaIdx = 0;
1668
1669 for (vector<DescriptorSp>::iterator desc = m_descriptors.begin(); desc != m_descriptors.end(); desc++)
1670 {
1671 if ((*desc)->isDynamic())
1672 {
1673 vector<uint32_t> dynamicAreas;
1674
1675 for (uint32_t elementIdx = 0; elementIdx < (*desc)->getArraySize(); elementIdx++)
1676 dynamicAreas.push_back(areas[areaIdx++]);
1677
1678 (*desc)->setDynamicAreas(dynamicAreas);
1679 }
1680 }
1681 }
1682
hasDynamicAreas(void) const1683 bool DescriptorCommands::hasDynamicAreas(void) const
1684 {
1685 for (vector<DescriptorSp>::const_iterator desc = m_descriptors.begin(); desc != m_descriptors.end(); desc++)
1686 if ((*desc)->isDynamic())
1687 return true;
1688
1689 return false;
1690 }
1691
checkSupport(Context & context) const1692 void DescriptorCommands::checkSupport(Context &context) const
1693 {
1694 const InstanceInterface &vki = context.getInstanceInterface();
1695 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
1696 const VkPhysicalDeviceLimits limits = getPhysicalDeviceProperties(vki, physicalDevice).limits;
1697
1698 if (limits.maxBoundDescriptorSets <= m_descriptorSets.size())
1699 TCU_THROW(NotSupportedError, "Maximum bound descriptor sets limit exceeded.");
1700
1701 if (m_useUpdateAfterBind)
1702 context.requireDeviceFunctionality("VK_EXT_descriptor_indexing");
1703
1704 #ifndef CTS_USES_VULKANSC
1705 uint32_t numTotalIUBs = 0;
1706
1707 // Check if inline uniform blocks are supported.
1708 VkPhysicalDeviceInlineUniformBlockFeaturesEXT iubFeatures{
1709 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT, nullptr, VK_FALSE, VK_FALSE};
1710 VkPhysicalDeviceInlineUniformBlockPropertiesEXT iubProperties{
1711 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT, nullptr, 0u, 0u, 0u, 0u, 0u};
1712
1713 if (context.isDeviceFunctionalitySupported("VK_EXT_inline_uniform_block"))
1714 {
1715 VkPhysicalDeviceFeatures2 features2 = initVulkanStructure(&iubFeatures);
1716 vki.getPhysicalDeviceFeatures2(physicalDevice, &features2);
1717
1718 VkPhysicalDeviceProperties2 properties2 = initVulkanStructure(&iubProperties);
1719 vki.getPhysicalDeviceProperties2(physicalDevice, &properties2);
1720 }
1721 #endif
1722
1723 // Check physical device limits of per stage and per desriptor set descriptor count
1724 {
1725 uint32_t numPerStageSamplers = 0;
1726 uint32_t numPerStageUniformBuffers = 0;
1727 uint32_t numPerStageStorageBuffers = 0;
1728 uint32_t numPerStageSampledImages = 0;
1729 uint32_t numPerStageStorageImages = 0;
1730 uint32_t numPerStageInputAttachments = 0;
1731 uint32_t numPerStageTotalResources = 0;
1732
1733 bool usesUniformBuffer = false;
1734 bool usesSampledImage = false;
1735 bool usesStorageImage = false;
1736 bool usesStorageBuffer = false;
1737 bool usesUniformTexelBuffer = false;
1738 bool usesStorageTexelBuffer = false;
1739
1740 for (size_t descriptorSetIdx = 0; descriptorSetIdx < m_descriptorSets.size(); descriptorSetIdx++)
1741 {
1742 uint32_t numSamplers = 0;
1743 uint32_t numUniformBuffers = 0;
1744 uint32_t numUniformBuffersDynamic = 0;
1745 uint32_t numStorageBuffers = 0;
1746 uint32_t numStorageBuffersDynamic = 0;
1747 uint32_t numSampledImages = 0;
1748 uint32_t numStorageImages = 0;
1749 uint32_t numInputAttachments = 0;
1750 uint32_t numTotalResources =
1751 m_pipelineType == PIPELINE_TYPE_GRAPHICS ? 1u : 0u; // Color buffer counts as a resource.
1752
1753 const vector<DescriptorSp> &bindings = m_descriptorSets[descriptorSetIdx]->getBindings();
1754
1755 for (size_t bindingIdx = 0; bindingIdx < bindings.size(); bindingIdx++)
1756 {
1757 const uint32_t arraySize = bindings[bindingIdx]->getArraySize();
1758
1759 #ifndef CTS_USES_VULKANSC
1760 // Inline uniform blocks cannot form arrays. The array size is the size of the data array in the descriptor.
1761 if (bindings[bindingIdx]->getType() == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
1762 {
1763 const InlineUniformBlockDescriptor *iub =
1764 static_cast<InlineUniformBlockDescriptor *>(bindings[bindingIdx].get());
1765 const uint32_t bytes = iub->getSizeInBytes();
1766
1767 // Check inline uniform block size.
1768 if (bytes > iubProperties.maxInlineUniformBlockSize)
1769 {
1770 std::ostringstream msg;
1771 msg << "Maximum size for an inline uniform block exceeded by binding " << bindingIdx
1772 << " from set " << descriptorSetIdx;
1773 TCU_THROW(NotSupportedError, msg.str().c_str());
1774 }
1775
1776 ++numTotalResources;
1777 }
1778 else
1779 #endif
1780 {
1781 numTotalResources += arraySize;
1782 }
1783
1784 switch (bindings[bindingIdx]->getType())
1785 {
1786 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1787 numUniformBuffers += arraySize;
1788 usesUniformBuffer = true;
1789 break;
1790
1791 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1792 numUniformBuffers += arraySize;
1793 numUniformBuffersDynamic += arraySize;
1794 break;
1795
1796 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1797 numStorageBuffers += arraySize;
1798 usesStorageBuffer = true;
1799 break;
1800
1801 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1802 numStorageBuffers += arraySize;
1803 numStorageBuffersDynamic += arraySize;
1804 break;
1805
1806 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1807 numSamplers += arraySize;
1808 numSampledImages += arraySize;
1809 usesSampledImage = true;
1810 break;
1811
1812 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1813 numStorageImages += arraySize;
1814 usesStorageImage = true;
1815 break;
1816
1817 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1818 numStorageImages += arraySize;
1819 usesStorageTexelBuffer = true;
1820 break;
1821
1822 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1823 numInputAttachments += arraySize;
1824 break;
1825
1826 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1827 numSampledImages += arraySize;
1828 usesSampledImage = true;
1829 break;
1830
1831 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1832 numSampledImages += arraySize;
1833 usesUniformTexelBuffer = true;
1834 break;
1835
1836 case VK_DESCRIPTOR_TYPE_SAMPLER:
1837 numSamplers += arraySize;
1838 usesSampledImage = true;
1839 break;
1840
1841 #ifndef CTS_USES_VULKANSC
1842 case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
1843 ++numTotalIUBs;
1844 break;
1845 #endif
1846 default:
1847 DE_FATAL("Unexpected descriptor type");
1848 break;
1849 }
1850 }
1851
1852 if (numSamplers > limits.maxDescriptorSetSamplers)
1853 TCU_THROW(NotSupportedError, "Maximum per descriptor set sampler limit exceeded.");
1854
1855 if (numUniformBuffers > limits.maxDescriptorSetUniformBuffers)
1856 TCU_THROW(NotSupportedError, "Maximum per descriptor set uniform buffer limit exceeded.");
1857
1858 if (numUniformBuffersDynamic > limits.maxDescriptorSetUniformBuffersDynamic)
1859 TCU_THROW(NotSupportedError, "Maximum per descriptor set uniform buffer dynamic limit exceeded.");
1860
1861 if (numStorageBuffers > limits.maxDescriptorSetStorageBuffers)
1862 TCU_THROW(NotSupportedError, "Maximum per descriptor set storage buffer limit exceeded.");
1863
1864 if (numStorageBuffersDynamic > limits.maxDescriptorSetStorageBuffersDynamic)
1865 TCU_THROW(NotSupportedError, "Maximum per descriptor set storage buffer dynamic limit exceeded.");
1866
1867 if (numSampledImages > limits.maxDescriptorSetSampledImages)
1868 TCU_THROW(NotSupportedError, "Maximum per descriptor set sampled image limit exceeded.");
1869
1870 if (numStorageImages > limits.maxDescriptorSetStorageImages)
1871 TCU_THROW(NotSupportedError, "Maximum per descriptor set storage image limit exceeded.");
1872
1873 if (numInputAttachments > limits.maxDescriptorSetInputAttachments)
1874 TCU_THROW(NotSupportedError, "Maximum per descriptor set input attachment limit exceeded.");
1875
1876 numPerStageSamplers += numSamplers;
1877 numPerStageUniformBuffers += numUniformBuffers;
1878 numPerStageStorageBuffers += numStorageBuffers;
1879 numPerStageSampledImages += numSampledImages;
1880 numPerStageStorageImages += numStorageImages;
1881 numPerStageInputAttachments += numInputAttachments;
1882 numPerStageTotalResources += numTotalResources;
1883 }
1884
1885 if (numPerStageTotalResources > limits.maxPerStageResources)
1886 TCU_THROW(NotSupportedError, "Maximum per stage total resource limit exceeded.");
1887
1888 if (numPerStageSamplers > limits.maxPerStageDescriptorSamplers)
1889 TCU_THROW(NotSupportedError, "Maximum per stage sampler limit exceeded.");
1890
1891 if (numPerStageUniformBuffers > limits.maxPerStageDescriptorUniformBuffers)
1892 TCU_THROW(NotSupportedError, "Maximum per stage uniform buffer limit exceeded.");
1893
1894 if (numPerStageStorageBuffers > limits.maxPerStageDescriptorStorageBuffers)
1895 TCU_THROW(NotSupportedError, "Maximum per stage storage buffer limit exceeded.");
1896
1897 if (numPerStageSampledImages > limits.maxPerStageDescriptorSampledImages)
1898 TCU_THROW(NotSupportedError, "Maximum per stage sampled image limit exceeded.");
1899
1900 if (numPerStageStorageImages > limits.maxPerStageDescriptorStorageImages)
1901 TCU_THROW(NotSupportedError, "Maximum per stage storage image limit exceeded.");
1902
1903 if (numPerStageInputAttachments > limits.maxPerStageDescriptorInputAttachments)
1904 TCU_THROW(NotSupportedError, "Maximum per stage input attachment limit exceeded.");
1905
1906 #ifndef CTS_USES_VULKANSC
1907 if (numTotalIUBs > iubProperties.maxDescriptorSetInlineUniformBlocks ||
1908 numTotalIUBs > iubProperties.maxPerStageDescriptorInlineUniformBlocks)
1909 {
1910 TCU_THROW(NotSupportedError, "Number of per stage inline uniform blocks exceeds limits.");
1911 }
1912 #endif
1913 if (m_useUpdateAfterBind)
1914 {
1915 if (usesUniformBuffer &&
1916 !context.getDescriptorIndexingFeatures().descriptorBindingUniformBufferUpdateAfterBind)
1917 TCU_THROW(NotSupportedError, "descriptorBindingUniformBufferUpdateAfterBind not supported.");
1918
1919 if (usesSampledImage &&
1920 !context.getDescriptorIndexingFeatures().descriptorBindingSampledImageUpdateAfterBind)
1921 TCU_THROW(NotSupportedError, "descriptorBindingSampledImageUpdateAfterBind not supported.");
1922
1923 if (usesStorageImage &&
1924 !context.getDescriptorIndexingFeatures().descriptorBindingStorageImageUpdateAfterBind)
1925 TCU_THROW(NotSupportedError, "descriptorBindingStorageImageUpdateAfterBind not supported.");
1926
1927 if (usesStorageBuffer &&
1928 !context.getDescriptorIndexingFeatures().descriptorBindingStorageBufferUpdateAfterBind)
1929 TCU_THROW(NotSupportedError, "descriptorBindingStorageBufferUpdateAfterBind not supported.");
1930
1931 if (usesUniformTexelBuffer &&
1932 !context.getDescriptorIndexingFeatures().descriptorBindingUniformTexelBufferUpdateAfterBind)
1933 TCU_THROW(NotSupportedError, "descriptorBindingUniformTexelBufferUpdateAfterBind not supported.");
1934
1935 if (usesStorageTexelBuffer &&
1936 !context.getDescriptorIndexingFeatures().descriptorBindingStorageTexelBufferUpdateAfterBind)
1937 TCU_THROW(NotSupportedError, "descriptorBindingStorageTexelBufferUpdateAfterBind not supported.");
1938 }
1939 }
1940 }
1941
run(Context & context)1942 tcu::TestStatus DescriptorCommands::run(Context &context)
1943 {
1944 const DeviceInterface &vk = context.getDeviceInterface();
1945 const VkDevice device = context.getDevice();
1946 const VkQueue queue = context.getUniversalQueue();
1947 const uint32_t queueFamilyIndex = context.getUniversalQueueFamilyIndex();
1948 Allocator &allocator = context.getDefaultAllocator();
1949 tcu::TestLog &log = context.getTestContext().getLog();
1950 const Unique<VkCommandPool> commandPool(
1951 createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex));
1952 const Unique<VkCommandBuffer> commandBuffer(
1953 allocateCommandBuffer(vk, device, *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1954 const VkShaderStageFlags shaderStage =
1955 m_pipelineType == PIPELINE_TYPE_COMPUTE ? VK_SHADER_STAGE_COMPUTE_BIT : VK_SHADER_STAGE_FRAGMENT_BIT;
1956 const VkFormat resultFormat = VK_FORMAT_R8G8B8A8_UNORM;
1957 de::MovePtr<ImageWithMemory> resultImage;
1958 de::MovePtr<BufferWithMemory> resultImageBuffer;
1959 Move<VkImageView> resultImageView;
1960 Move<VkRenderPass> renderPass;
1961 Move<VkFramebuffer> framebuffer;
1962 Move<VkDescriptorPool> descriptorPool;
1963 vector<VkDescriptorSetLayoutSp> descriptorSetLayouts;
1964 vector<VkDescriptorSet> descriptorSets;
1965 Move<VkPipelineLayout> pipelineLayout;
1966 Move<VkPipeline> pipeline;
1967 vector<VkAttachmentReference> inputAttachments;
1968 vector<VkAttachmentDescription> attachmentDescriptions;
1969 vector<VkImageView> imageViews;
1970
1971 // Initialize all descriptors
1972 for (vector<DescriptorSp>::iterator desc = m_descriptors.begin(); desc != m_descriptors.end(); desc++)
1973 (*desc)->init(context, m_pipelineType);
1974
1975 uint32_t numTotalIUBs = 0;
1976 uint32_t iubTotalBytes = 0;
1977 VkDescriptorPoolCreateFlags poolCreateFlags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
1978 VkDescriptorSetLayoutCreateFlags descriptorSetLayoutCreateFlags = 0u;
1979 VkDescriptorBindingFlags bindingFlag = 0u;
1980 if (m_useUpdateAfterBind)
1981 {
1982 poolCreateFlags |= VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT;
1983 descriptorSetLayoutCreateFlags |= VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT;
1984 bindingFlag |= VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT;
1985 }
1986
1987 #ifndef CTS_USES_VULKANSC
1988 for (size_t descriptorSetIdx = 0; descriptorSetIdx < m_descriptorSets.size(); descriptorSetIdx++)
1989 {
1990 const vector<DescriptorSp> &bindings = m_descriptorSets[descriptorSetIdx]->getBindings();
1991 for (size_t bindingIdx = 0; bindingIdx < bindings.size(); bindingIdx++)
1992 {
1993 // Inline uniform blocks cannot form arrays. The array size is the size of the data array in the descriptor.
1994 if (bindings[bindingIdx]->getType() == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
1995 {
1996 const InlineUniformBlockDescriptor *iub =
1997 static_cast<InlineUniformBlockDescriptor *>(bindings[bindingIdx].get());
1998 iubTotalBytes += iub->getSizeInBytes();
1999
2000 ++numTotalIUBs;
2001 }
2002 }
2003 }
2004 #else
2005 DE_UNREF(numTotalIUBs);
2006 DE_UNREF(iubTotalBytes);
2007 #endif // CTS_USES_VULKANSC
2008
2009 // Create descriptor pool
2010 {
2011 vector<VkDescriptorPoolSize> poolSizes;
2012
2013 for (map<VkDescriptorType, uint32_t>::iterator i = m_descriptorCounts.begin(); i != m_descriptorCounts.end();
2014 i++)
2015 {
2016 VkDescriptorPoolSize poolSize = {
2017 i->first, // VkDescriptorType type
2018 i->second // uint32_t descriptorCount
2019 };
2020
2021 #ifndef CTS_USES_VULKANSC
2022 // Inline uniform blocks have a special meaning for descriptorCount.
2023 if (poolSize.type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
2024 poolSize.descriptorCount = iubTotalBytes;
2025 #endif
2026
2027 poolSizes.push_back(poolSize);
2028 }
2029
2030 VkDescriptorPoolCreateInfo descriptorPoolCreateInfo = {
2031 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // VkStructureType sType
2032 nullptr, // const void* pNext
2033 poolCreateFlags, // VkDescriptorPoolCreateFlags flags
2034 (uint32_t)m_descriptorSets.size(), // uint32_t maxSets
2035 (uint32_t)poolSizes.size(), // uint32_t poolSizeCount
2036 poolSizes.data(), // const VkDescriptorPoolSize* pPoolSizes
2037 };
2038
2039 // Include information about inline uniform blocks if needed.
2040 #ifndef CTS_USES_VULKANSC
2041 VkDescriptorPoolInlineUniformBlockCreateInfoEXT iubPoolCreateInfo = {
2042 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT, nullptr, numTotalIUBs};
2043 if (numTotalIUBs > 0)
2044 descriptorPoolCreateInfo.pNext = &iubPoolCreateInfo;
2045 #endif
2046
2047 descriptorPool = createDescriptorPool(vk, device, &descriptorPoolCreateInfo);
2048 }
2049
2050 // Create descriptor set layouts. One for each descriptor set used in this test.
2051 {
2052 for (size_t descriptorSetIdx = 0; descriptorSetIdx < m_descriptorSets.size(); descriptorSetIdx++)
2053 {
2054 vector<VkDescriptorSetLayoutBinding> layoutBindings;
2055 const vector<DescriptorSp> &bindings = m_descriptorSets[descriptorSetIdx]->getBindings();
2056 const vector<VkDescriptorBindingFlags> bindingsFlags(bindings.size(), bindingFlag);
2057
2058 for (size_t bindingIdx = 0; bindingIdx < bindings.size(); bindingIdx++)
2059 {
2060 VkDescriptorSetLayoutBinding layoutBinding = {
2061 (uint32_t)bindingIdx, // uint32_t binding
2062 bindings[bindingIdx]->getType(), // VkDescriptorType descriptorType
2063 bindings[bindingIdx]->getArraySize(), // uint32_t descriptorCount
2064 shaderStage, // VkShaderStageFlags stageFlags
2065 nullptr // const VkSampler* pImmutableSamplers
2066 };
2067
2068 #ifndef CTS_USES_VULKANSC
2069 // Inline uniform blocks have a special meaning for descriptorCount.
2070 if (layoutBinding.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
2071 {
2072 const InlineUniformBlockDescriptor *iub =
2073 static_cast<InlineUniformBlockDescriptor *>(bindings[bindingIdx].get());
2074 layoutBinding.descriptorCount = iub->getSizeInBytes();
2075 }
2076 #endif
2077 layoutBindings.push_back(layoutBinding);
2078 }
2079
2080 const VkDescriptorSetLayoutBindingFlagsCreateInfo bindingFlagsInfo{
2081 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO, // VkStructureType sType;
2082 nullptr, // const void* pNext;
2083 (uint32_t)layoutBindings.size(), // uint32_t bindingCount;
2084 layoutBindings.empty() ? nullptr :
2085 bindingsFlags.data(), // const VkDescriptorBindingFlags* pBindingFlags;
2086 };
2087
2088 const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo{
2089 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType
2090 m_useUpdateAfterBind ? &bindingFlagsInfo : nullptr, // const void* pNext
2091 descriptorSetLayoutCreateFlags, // VkDescriptorSetLayoutCreateFlags flags
2092 (uint32_t)layoutBindings.size(), // uint32_t bindingCount
2093 layoutBindings.data() // const VkDescriptorSetLayoutBinding* pBindings
2094 };
2095
2096 descriptorSetLayouts.push_back(VkDescriptorSetLayoutSp(new Unique<VkDescriptorSetLayout>(
2097 createDescriptorSetLayout(vk, device, &descriptorSetLayoutCreateInfo, nullptr))));
2098 }
2099 }
2100
2101 // Create descriptor sets
2102 {
2103 for (size_t descriptorSetIdx = 0; descriptorSetIdx < m_descriptorSets.size(); descriptorSetIdx++)
2104 {
2105 const VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = {
2106 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType
2107 nullptr, // const void* pNext
2108 *descriptorPool, // VkDescriptorPool descriptorPool
2109 1u, // uint32_t descriptorSetCount
2110 &(descriptorSetLayouts[descriptorSetIdx]->get()) // const VkDescriptorSetLayout* pSetLayouts
2111 };
2112
2113 VkDescriptorSet descriptorSet = VK_NULL_HANDLE;
2114 VK_CHECK(vk.allocateDescriptorSets(device, &descriptorSetAllocateInfo, &descriptorSet));
2115 descriptorSets.push_back(descriptorSet);
2116 }
2117 }
2118
2119 // Update descriptor sets when this should be done before bind
2120 if (!m_useUpdateAfterBind)
2121 updateDescriptorSets(context, descriptorSets);
2122
2123 // Create pipeline layout
2124 {
2125 vector<VkDescriptorSetLayout> descriptorSetLayoutHandles;
2126
2127 for (size_t i = 0; i < descriptorSetLayouts.size(); i++)
2128 descriptorSetLayoutHandles.push_back(descriptorSetLayouts[i]->get());
2129
2130 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {
2131 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType
2132 nullptr, // const void* pNext
2133 0u, // VkPipelineLayoutCreateFlags flags
2134 (uint32_t)descriptorSetLayoutHandles.size(), // uint32_t setLayoutCount
2135 descriptorSetLayoutHandles.data(), // const VkDescriptorSetLayout* pSetLayouts
2136 0u, // uint32_t pushConstantRangeCount
2137 nullptr // const VkPushConstantRange* pPushConstantRanges
2138 };
2139
2140 pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
2141 }
2142
2143 if (m_pipelineType == PIPELINE_TYPE_COMPUTE)
2144 {
2145 // Create compute pipeline
2146 {
2147 const Unique<VkShaderModule> shaderModule(
2148 createShaderModule(vk, device, context.getBinaryCollection().get("compute"), 0u));
2149 const VkPipelineShaderStageCreateInfo shaderStageInfo = {
2150 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType
2151 nullptr, // const void* pNext
2152 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags
2153 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage
2154 *shaderModule, // VkShaderModule module
2155 "main", // const char* pName
2156 nullptr // const VkSpecializationInfo* pSpecializationInfo
2157 };
2158
2159 const VkComputePipelineCreateInfo pipelineInfo = {
2160 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType
2161 nullptr, // const void* pNext
2162 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags
2163 shaderStageInfo, // VkPipelineShaderStageCreateInfo stage
2164 *pipelineLayout, // VkPipelineLayout layout
2165 VK_NULL_HANDLE, // VkPipeline basePipelineHandle
2166 0 // int32_t basePipelineIndex
2167 };
2168
2169 pipeline = createComputePipeline(vk, device, VK_NULL_HANDLE, &pipelineInfo);
2170 }
2171 }
2172 else
2173 {
2174 // Create result image
2175 {
2176 const VkImageCreateInfo imageCreateInfo = {
2177 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType stype
2178 nullptr, // const void* pNext
2179 0u, // VkImageCreateFlags flags
2180 VK_IMAGE_TYPE_2D, // VkImageType imageType
2181 resultFormat, // VkFormat format
2182 {(uint32_t)renderSize.x(), (uint32_t)renderSize.y(), 1}, // VkExtent3D extent
2183 1u, // uint32_t mipLevels
2184 1u, // uint32_t arrayLayers
2185 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
2186 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
2187 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage
2188 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
2189 1u, // uint32_t queueFamilyIndexCount
2190 &queueFamilyIndex, // const uint32_t* pQueueFamilyIndices
2191 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout
2192 };
2193
2194 resultImage = de::MovePtr<ImageWithMemory>(
2195 new ImageWithMemory(vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
2196 }
2197
2198 // Create result image view
2199 {
2200 const VkComponentMapping componentMapping = makeComponentMappingRGBA();
2201
2202 const VkImageSubresourceRange subresourceRange = {
2203 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
2204 0u, // uint32_t baseMipLevel
2205 1u, // uint32_t levelCount
2206 0u, // uint32_t baseArrayLayer
2207 1u, // uint32_t layerCount
2208 };
2209
2210 const VkImageViewCreateInfo imageViewCreateInfo = {
2211 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType
2212 nullptr, // const void* pNext
2213 0u, // VkImageViewCreateFlags flags
2214 **resultImage, // VkImage image
2215 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType
2216 resultFormat, // VkFormat format
2217 componentMapping, // VkComponentMapping components
2218 subresourceRange // VkImageSubresourceRange subresourceRange
2219 };
2220
2221 resultImageView = createImageView(vk, device, &imageViewCreateInfo);
2222 }
2223
2224 // Create result buffer
2225 {
2226 const VkDeviceSize bufferSize =
2227 renderSize.x() * renderSize.y() * tcu::getPixelSize(mapVkFormat(resultFormat));
2228 const VkBufferCreateInfo bufferCreateInfo = {
2229 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType
2230 nullptr, // const void* pNext
2231 0u, // VkBufferCreateFlags flags
2232 bufferSize, // VkDeviceSize size
2233 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage
2234 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
2235 0u, // uint32_t queueFamilyIndexCount
2236 nullptr // const uint32_t* pQueueFamilyIndices
2237 };
2238
2239 resultImageBuffer = de::MovePtr<BufferWithMemory>(
2240 new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible));
2241 }
2242
2243 // Create render pass
2244 {
2245 const VkAttachmentReference colorAttachmentRef = {
2246 0u, // uint32_t attachment
2247 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout
2248 };
2249
2250 for (vector<DescriptorSp>::const_iterator desc = m_descriptors.begin(); desc != m_descriptors.end(); desc++)
2251 {
2252 vector<VkAttachmentReference> references = (*desc)->getAttachmentReferences();
2253 inputAttachments.insert(inputAttachments.end(), references.begin(), references.end());
2254 }
2255
2256 const VkAttachmentDescription colorAttachmentDesc = {
2257 0u, // VkAttachmentDescriptionFlags flags
2258 VK_FORMAT_R8G8B8A8_UNORM, // VkFormat format
2259 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
2260 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp
2261 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
2262 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp
2263 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp
2264 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout
2265 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout
2266 };
2267
2268 attachmentDescriptions.push_back(colorAttachmentDesc);
2269
2270 const VkAttachmentDescription inputAttachmentDesc = {
2271 0u, // VkAttachmentDescriptionFlags flags
2272 VK_FORMAT_R32_SFLOAT, // VkFormat format
2273 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
2274 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp
2275 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp storeOp
2276 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp
2277 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp
2278 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout initialLayout
2279 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout finalLayout
2280 };
2281
2282 for (size_t inputAttachmentIdx = 0; inputAttachmentIdx < inputAttachments.size(); inputAttachmentIdx++)
2283 attachmentDescriptions.push_back(inputAttachmentDesc);
2284
2285 const VkSubpassDescription subpassDescription = {
2286 0u, // VkSubpassDescriptionFlags flags
2287 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
2288 (uint32_t)inputAttachments.size(), // uint32_t inputAttachmentCount
2289 inputAttachments.empty() ? nullptr :
2290 inputAttachments.data(), // const VkAttachmentReference* pInputAttachments
2291 1u, // uint32_t colorAttachmentCount
2292 &colorAttachmentRef, // const VkAttachmentReference* pColorAttachments
2293 nullptr, // const VkAttachmentReference* pResolveAttachments
2294 nullptr, // const VkAttachmentReference* pDepthStencilAttachment
2295 0u, // uint32_t preserveAttachmentCount
2296 nullptr // const uint32_t* pPreserveAttachments
2297 };
2298
2299 const VkRenderPassCreateInfo renderPassCreateInfo = {
2300 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType
2301 nullptr, // const void* pNext
2302 0u, // VkRenderPassCreateFlags flags
2303 (uint32_t)attachmentDescriptions.size(), // uint32_t attachmentCount
2304 attachmentDescriptions.data(), // const VkAttachmentDescription* pAttachments
2305 1u, // uint32_t subpassCount
2306 &subpassDescription, // const VkSubpassDescription* pSubpasses
2307 0u, // uint32_t dependencyCount
2308 nullptr // const VkSubpassDependency* pDependencies
2309 };
2310
2311 renderPass = createRenderPass(vk, device, &renderPassCreateInfo);
2312 }
2313
2314 // Create framebuffer
2315 {
2316 imageViews.push_back(*resultImageView);
2317
2318 // Add input attachment image views
2319 for (vector<DescriptorSp>::const_iterator desc = m_descriptors.begin(); desc != m_descriptors.end(); desc++)
2320 {
2321 vector<VkImageViewSp> inputAttachmentViews = (*desc)->getImageViews();
2322
2323 for (size_t imageViewIdx = 0; imageViewIdx < inputAttachmentViews.size(); imageViewIdx++)
2324 imageViews.push_back(**inputAttachmentViews[imageViewIdx]);
2325 }
2326
2327 const VkFramebufferCreateInfo framebufferCreateInfo = {
2328 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType
2329 nullptr, // const void* pNext
2330 0u, // VkFramebufferCreateFlags flags
2331 *renderPass, // VkRenderPass renderPass
2332 (uint32_t)imageViews.size(), // uint32_t attachmentCount
2333 imageViews.data(), // const VkImageView* pAttachments
2334 (uint32_t)renderSize.x(), // uint32_t width
2335 (uint32_t)renderSize.y(), // uint32_t height
2336 1u, // uint32_t layers
2337 };
2338
2339 framebuffer = createFramebuffer(vk, device, &framebufferCreateInfo);
2340 }
2341
2342 // Create graphics pipeline
2343 {
2344 const Unique<VkShaderModule> vertexShaderModule(
2345 createShaderModule(vk, device, context.getBinaryCollection().get("vertex"), 0u));
2346 const Unique<VkShaderModule> fragmentShaderModule(
2347 createShaderModule(vk, device, context.getBinaryCollection().get("fragment"), 0u));
2348
2349 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = {
2350 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType
2351 nullptr, // const void* pNext
2352 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags
2353 0u, // uint32_t bindingCount
2354 nullptr, // const VkVertexInputBindingDescription* pVertexBindingDescriptions
2355 0u, // uint32_t attributeCount
2356 nullptr, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions
2357 };
2358
2359 const std::vector<VkViewport> viewports(1, makeViewport(renderSize));
2360 const std::vector<VkRect2D> scissors(1, makeRect2D(renderSize));
2361
2362 pipeline = makeGraphicsPipeline(
2363 vk, // const DeviceInterface& vk
2364 device, // const VkDevice device
2365 *pipelineLayout, // const VkPipelineLayout pipelineLayout
2366 *vertexShaderModule, // const VkShaderModule vertexShaderModule
2367 VK_NULL_HANDLE, // const VkShaderModule tessellationControlShaderModule
2368 VK_NULL_HANDLE, // const VkShaderModule tessellationEvalShaderModule
2369 VK_NULL_HANDLE, // const VkShaderModule geometryShaderModule
2370 *fragmentShaderModule, // const VkShaderModule fragmentShaderModule
2371 *renderPass, // const VkRenderPass renderPass
2372 viewports, // const std::vector<VkViewport>& viewports
2373 scissors, // const std::vector<VkRect2D>& scissors
2374 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
2375 0u, // const uint32_t subpass
2376 0u, // const uint32_t patchControlPoints
2377 &vertexInputStateParams); // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
2378 }
2379 }
2380
2381 // Run verification shader
2382 {
2383 const VkPipelineBindPoint pipelineBindPoint =
2384 m_pipelineType == PIPELINE_TYPE_COMPUTE ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS;
2385 vector<uint32_t> offsets;
2386
2387 if (hasDynamicAreas())
2388 {
2389 for (size_t areaIdx = 0; areaIdx < m_dynamicAreas.size(); areaIdx++)
2390 offsets.push_back(m_dynamicAreas[areaIdx] * 256u);
2391 }
2392
2393 beginCommandBuffer(vk, *commandBuffer);
2394
2395 if (m_pipelineType == PIPELINE_TYPE_GRAPHICS)
2396 {
2397 const VkRect2D renderArea = makeRect2D(renderSize);
2398 const tcu::Vec4 clearColor(1.0f, 0.0f, 0.0f, 1.0f);
2399
2400 beginRenderPass(vk, *commandBuffer, *renderPass, *framebuffer, renderArea, clearColor);
2401 }
2402
2403 vk.cmdBindPipeline(*commandBuffer, pipelineBindPoint, *pipeline);
2404 vk.cmdBindDescriptorSets(*commandBuffer, pipelineBindPoint, *pipelineLayout, 0u,
2405 (uint32_t)descriptorSets.size(), descriptorSets.data(), (uint32_t)offsets.size(),
2406 offsets.empty() ? nullptr : offsets.data());
2407
2408 // Update descriptor sets when this should be done after bind
2409 if (m_useUpdateAfterBind)
2410 updateDescriptorSets(context, descriptorSets);
2411
2412 if (m_pipelineType == PIPELINE_TYPE_COMPUTE)
2413 {
2414 vk.cmdDispatch(*commandBuffer, 1u, 1u, 1u);
2415 }
2416 else
2417 {
2418 vk.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
2419 endRenderPass(vk, *commandBuffer);
2420 copyImageToBuffer(vk, *commandBuffer, **resultImage, resultImageBuffer->get(), renderSize);
2421 }
2422
2423 endCommandBuffer(vk, *commandBuffer);
2424 submitCommandsAndWait(vk, device, queue, *commandBuffer);
2425 }
2426
2427 if (m_pipelineType == PIPELINE_TYPE_COMPUTE)
2428 {
2429 // Invalidate result buffer
2430 m_resultBuffer->invalidate(context);
2431
2432 // Verify result data
2433 const auto data = m_resultBuffer->getData();
2434 if (data[0] == 1)
2435 return tcu::TestStatus::pass("Pass");
2436 else
2437 return tcu::TestStatus::fail("Data validation failed");
2438 }
2439 else
2440 {
2441 invalidateAlloc(vk, device, resultImageBuffer->getAllocation());
2442
2443 // Verify result image
2444 tcu::ConstPixelBufferAccess resultBufferAccess(mapVkFormat(resultFormat), renderSize.x(), renderSize.y(), 1,
2445 resultImageBuffer->getAllocation().getHostPtr());
2446
2447 for (int32_t y = 0; y < renderSize.y(); y++)
2448 for (int32_t x = 0; x < renderSize.x(); x++)
2449 {
2450 Vec4 pixel = resultBufferAccess.getPixel(x, y, 0);
2451
2452 if (pixel.x() != 0.0f || pixel.y() != 1.0f || pixel.z() != 0.0f || pixel.w() != 1.0f)
2453 {
2454 // Log result image before failing.
2455 log << tcu::TestLog::ImageSet("Result", "")
2456 << tcu::TestLog::Image("Rendered", "Rendered image", resultBufferAccess)
2457 << tcu::TestLog::EndImageSet;
2458 return tcu::TestStatus::fail("Result image validation failed");
2459 }
2460 }
2461
2462 return tcu::TestStatus::pass("Pass");
2463 }
2464 }
2465
updateDescriptorSets(Context & context,const vector<VkDescriptorSet> & descriptorSets)2466 void DescriptorCommands::updateDescriptorSets(Context &context, const vector<VkDescriptorSet> &descriptorSets)
2467 {
2468 const DeviceInterface &vk = context.getDeviceInterface();
2469 const VkDevice device = context.getDevice();
2470 vector<VkWriteDescriptorSet> descriptorWrites;
2471 vector<VkCopyDescriptorSet> descriptorCopies;
2472
2473 // Write descriptors that are marked as needing initialization
2474 for (size_t descriptorSetIdx = 0; descriptorSetIdx < m_descriptorSets.size(); descriptorSetIdx++)
2475 {
2476 const vector<DescriptorSp> &bindings = m_descriptorSets[descriptorSetIdx]->getBindings();
2477
2478 for (size_t bindingIdx = 0; bindingIdx < bindings.size(); bindingIdx++)
2479 {
2480 VkWriteDescriptorSet descriptorWrite = bindings[bindingIdx]->getDescriptorWrite();
2481
2482 descriptorWrite.dstSet = descriptorSets[descriptorSetIdx];
2483 descriptorWrite.dstBinding = (uint32_t)bindingIdx;
2484
2485 if (descriptorWrite.descriptorCount > 0)
2486 descriptorWrites.push_back(descriptorWrite);
2487 }
2488 }
2489
2490 for (size_t copyIdx = 0; copyIdx < m_descriptorCopies.size(); copyIdx++)
2491 {
2492 const DescriptorCopy indices = m_descriptorCopies[copyIdx];
2493 const VkCopyDescriptorSet copy = {
2494 VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET, // VkStructureType sType
2495 nullptr, // const void* pNext
2496 descriptorSets[indices.srcSet], // VkDescriptorSet srcSet
2497 indices.srcBinding, // uint32_t srcBinding
2498 indices.srcArrayElement, // uint32_t srcArrayElement
2499 descriptorSets[indices.dstSet], // VkDescriptorSet dstSet
2500 indices.dstBinding, // uint32_t dstBinding
2501 indices.dstArrayElement, // uint32_t dstArrayElement
2502 indices.descriptorCount // uint32_t descriptorCount
2503 };
2504
2505 descriptorCopies.push_back(copy);
2506 }
2507
2508 // Update descriptors with writes and copies
2509 vk.updateDescriptorSets(device, (uint32_t)descriptorWrites.size(), descriptorWrites.data(),
2510 (uint32_t)descriptorCopies.size(), descriptorCopies.data());
2511 }
2512
DescriptorCopyTestInstance(Context & context,DescriptorCommandsSp commands)2513 DescriptorCopyTestInstance::DescriptorCopyTestInstance(Context &context, DescriptorCommandsSp commands)
2514 : vkt::TestInstance(context)
2515 , m_commands(commands)
2516 {
2517 }
2518
~DescriptorCopyTestInstance(void)2519 DescriptorCopyTestInstance::~DescriptorCopyTestInstance(void)
2520 {
2521 }
2522
DescriptorCopyTestCase(tcu::TestContext & context,const char * name,DescriptorCommandsSp commands)2523 DescriptorCopyTestCase::DescriptorCopyTestCase(tcu::TestContext &context, const char *name,
2524 DescriptorCommandsSp commands)
2525 : vkt::TestCase(context, name)
2526 , m_commands(commands)
2527 {
2528 }
2529
~DescriptorCopyTestCase(void)2530 DescriptorCopyTestCase::~DescriptorCopyTestCase(void)
2531 {
2532 }
2533
initPrograms(SourceCollections & programCollection) const2534 void DescriptorCopyTestCase::initPrograms(SourceCollections &programCollection) const
2535 {
2536 if (m_commands->getPipelineType() == PIPELINE_TYPE_COMPUTE)
2537 {
2538 string computeSrc = "#version 430\n"
2539 "\n" +
2540 m_commands->getShaderDeclarations() +
2541 "\n"
2542 "void main()\n"
2543 "{\n"
2544 "int result = 1;\n" +
2545 m_commands->getDescriptorVerifications() + "storageBuffer" +
2546 de::toString(m_commands->getResultBufferId()) +
2547 ".data = result;\n"
2548 "}\n";
2549
2550 programCollection.glslSources.add("compute") << glu::ComputeSource(computeSrc);
2551 }
2552 else
2553 {
2554 // Produce quad vertices using vertex index
2555 string vertexSrc = "#version 450\n"
2556 "out gl_PerVertex\n"
2557 "{\n"
2558 " vec4 gl_Position;\n"
2559 "};\n"
2560 "void main()\n"
2561 "{\n"
2562 " gl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
2563 " ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
2564 "}\n";
2565
2566 programCollection.glslSources.add("vertex") << glu::VertexSource(vertexSrc);
2567
2568 string fragmentSrc = "#version 430\n"
2569 "\n" +
2570 m_commands->getShaderDeclarations() +
2571 "layout (location = 0) out vec4 outColor;\n"
2572 "\n"
2573 "void main()\n"
2574 "{\n"
2575 "int result = 1;\n" +
2576 m_commands->getDescriptorVerifications() +
2577 "if (result == 1) outColor = vec4(0, 1, 0, 1);\n"
2578 "else outColor = vec4(1, 0, 1, 0);\n"
2579 "}\n";
2580
2581 programCollection.glslSources.add("fragment") << glu::FragmentSource(fragmentSrc);
2582 }
2583 }
2584
createInstance(Context & context) const2585 TestInstance *DescriptorCopyTestCase::createInstance(Context &context) const
2586 {
2587 TestInstance *result = new DescriptorCopyTestInstance(context, m_commands);
2588 m_commands.clear();
2589 return result;
2590 }
2591
checkSupport(Context & context) const2592 void DescriptorCopyTestCase::checkSupport(Context &context) const
2593 {
2594 m_commands->checkSupport(context);
2595 }
2596
iterate(void)2597 tcu::TestStatus DescriptorCopyTestInstance::iterate(void)
2598 {
2599 return m_commands->run(m_context);
2600 }
2601
2602 template <class T>
addDescriptorCopyTests(tcu::TestContext & testCtx,de::MovePtr<tcu::TestCaseGroup> & group,string name,PipelineType pipelineType,bool useUpdateAfterBind)2603 void addDescriptorCopyTests(tcu::TestContext &testCtx, de::MovePtr<tcu::TestCaseGroup> &group, string name,
2604 PipelineType pipelineType, bool useUpdateAfterBind)
2605 {
2606 // Simple test copying inside the same set.
2607 {
2608 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, useUpdateAfterBind));
2609 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 3u)), 0u);
2610 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 2u)), 0u);
2611
2612 commands->copyDescriptor(0u, 0u, // from
2613 0u, 1u); // to
2614
2615 vector<uint32_t> dynamicAreas;
2616 dynamicAreas.push_back(2u);
2617 dynamicAreas.push_back(1u);
2618 commands->setDynamicAreas(dynamicAreas);
2619
2620 commands->addResultBuffer();
2621
2622 group->addChild(new DescriptorCopyTestCase(testCtx, (name + "_0").c_str(), commands));
2623 }
2624
2625 // Simple test copying between different sets.
2626 {
2627 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, useUpdateAfterBind));
2628 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 2u)), 0u);
2629 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 4u)), 1u);
2630
2631 commands->copyDescriptor(0u, 0u, // from
2632 1u, 0u); // to
2633
2634 vector<uint32_t> dynamicAreas;
2635 dynamicAreas.push_back(0u);
2636 dynamicAreas.push_back(1u);
2637 commands->setDynamicAreas(dynamicAreas);
2638
2639 commands->addResultBuffer();
2640
2641 group->addChild(new DescriptorCopyTestCase(testCtx, (name + "_1").c_str(), commands));
2642 }
2643
2644 // Simple test copying between different sets. Destination not updated.
2645 {
2646 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, useUpdateAfterBind));
2647 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 2u)), 0u);
2648 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 0u, 1u)), 1u);
2649
2650 commands->copyDescriptor(0u, 0u, // from
2651 1u, 0u); // to
2652
2653 vector<uint32_t> dynamicAreas;
2654 dynamicAreas.push_back(1u);
2655 dynamicAreas.push_back(0u);
2656 commands->setDynamicAreas(dynamicAreas);
2657
2658 commands->addResultBuffer();
2659
2660 group->addChild(new DescriptorCopyTestCase(testCtx, (name + "_2").c_str(), commands));
2661 }
2662
2663 // Five sets and several copies.
2664 {
2665 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, useUpdateAfterBind));
2666 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 3u)), 0u);
2667 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 4u)), 0u);
2668 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 2u)), 1u);
2669 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 1u)), 1u);
2670 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 2u)), 1u);
2671 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 5u)), 4u);
2672
2673 commands->copyDescriptor(4u, 0u, // from
2674 0u, 0u); // to
2675
2676 commands->copyDescriptor(0u, 1u, // from
2677 1u, 2u); // to
2678
2679 commands->copyDescriptor(0u, 1u, // from
2680 1u, 1u); // to
2681
2682 vector<uint32_t> dynamicAreas;
2683 dynamicAreas.push_back(1u);
2684 dynamicAreas.push_back(0u);
2685 dynamicAreas.push_back(1u);
2686 dynamicAreas.push_back(0u);
2687 dynamicAreas.push_back(0u);
2688 dynamicAreas.push_back(4u);
2689 commands->setDynamicAreas(dynamicAreas);
2690
2691 commands->addResultBuffer();
2692
2693 group->addChild(new DescriptorCopyTestCase(testCtx, (name + "_3").c_str(), commands));
2694 }
2695
2696 // Several identical copies
2697 {
2698 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, useUpdateAfterBind));
2699 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 2u)), 0u);
2700 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 4u)), 1u);
2701 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 2u)), 1u);
2702
2703 for (uint32_t i = 0; i < 100; i++)
2704 {
2705 commands->copyDescriptor(0u, 0u, // from
2706 1u, 0u); // to
2707 }
2708
2709 commands->copyDescriptor(1u, 1u, // from
2710 0u, 0u); // to
2711
2712 for (uint32_t i = 0; i < 100; i++)
2713 {
2714 commands->copyDescriptor(1u, 0u, // from
2715 1u, 1u); // to
2716 }
2717
2718 vector<uint32_t> dynamicAreas;
2719 dynamicAreas.push_back(0u);
2720 dynamicAreas.push_back(1u);
2721 dynamicAreas.push_back(1u);
2722 commands->setDynamicAreas(dynamicAreas);
2723
2724 commands->addResultBuffer();
2725
2726 group->addChild(new DescriptorCopyTestCase(testCtx, (name + "_4").c_str(), commands));
2727 }
2728
2729 // Copy descriptors back and forth
2730 {
2731 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, useUpdateAfterBind));
2732 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 3u)), 0u);
2733 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 3u)), 1u);
2734 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 3u)), 1u);
2735
2736 commands->copyDescriptor(0u, 0u, // from
2737 1u, 0u); // to
2738
2739 commands->copyDescriptor(1u, 0u, // from
2740 0u, 0u); // to
2741
2742 commands->copyDescriptor(1u, 1u, // from
2743 0u, 0u); // to
2744
2745 commands->copyDescriptor(1u, 1u, // from
2746 0u, 0u); // to
2747
2748 commands->copyDescriptor(1u, 0u, // from
2749 1u, 1u); // to
2750
2751 vector<uint32_t> dynamicAreas;
2752 dynamicAreas.push_back(1u);
2753 dynamicAreas.push_back(0u);
2754 dynamicAreas.push_back(0u);
2755 commands->setDynamicAreas(dynamicAreas);
2756
2757 commands->addResultBuffer();
2758
2759 group->addChild(new DescriptorCopyTestCase(testCtx, (name + "_5").c_str(), commands));
2760 }
2761
2762 // Copy between non-consecutive descriptor sets
2763 {
2764 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, useUpdateAfterBind));
2765 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 3u)), 0u);
2766 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 2u)), 5u);
2767 commands->addDescriptor(DescriptorSp(new T(1u, 0u, 1u, 2u)), 5u);
2768
2769 commands->copyDescriptor(0u, 0u, // from
2770 5u, 1u); // to
2771
2772 vector<uint32_t> dynamicAreas;
2773 dynamicAreas.push_back(2u);
2774 dynamicAreas.push_back(1u);
2775 dynamicAreas.push_back(1u);
2776 commands->setDynamicAreas(dynamicAreas);
2777
2778 commands->addResultBuffer();
2779
2780 group->addChild(new DescriptorCopyTestCase(testCtx, (name + "_6").c_str(), commands));
2781 }
2782
2783 // Simple 3 sized array to 3 sized array inside the same set.
2784 {
2785 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, useUpdateAfterBind));
2786 commands->addDescriptor(DescriptorSp(new T(3u, 0u, 3u, 3u)), 0u);
2787 commands->addDescriptor(DescriptorSp(new T(3u, 0u, 3u, 4u)), 0u);
2788
2789 commands->copyDescriptor(0u, 0u, 0u, // from
2790 0u, 1u, 0u, // to
2791 3u); // num descriptors
2792
2793 vector<uint32_t> dynamicAreas;
2794 dynamicAreas.push_back(1u);
2795 dynamicAreas.push_back(0u);
2796 dynamicAreas.push_back(2u);
2797
2798 dynamicAreas.push_back(2u);
2799 dynamicAreas.push_back(1u);
2800 dynamicAreas.push_back(0u);
2801 commands->setDynamicAreas(dynamicAreas);
2802
2803 commands->addResultBuffer();
2804
2805 group->addChild(new DescriptorCopyTestCase(testCtx, (name + "_array0").c_str(), commands));
2806 }
2807
2808 // Simple 2 sized array to 3 sized array into different set.
2809 {
2810 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, useUpdateAfterBind));
2811 commands->addDescriptor(DescriptorSp(new T(2u, 0u, 2u, 2u)), 0u);
2812 commands->addDescriptor(DescriptorSp(new T(3u, 0u, 3u, 5u)), 1u);
2813
2814 commands->copyDescriptor(0u, 0u, 0u, // from
2815 1u, 0u, 0u, // to
2816 2u); // num descriptors
2817
2818 vector<uint32_t> dynamicAreas;
2819 dynamicAreas.push_back(1u);
2820 dynamicAreas.push_back(0u);
2821
2822 dynamicAreas.push_back(1u);
2823 dynamicAreas.push_back(0u);
2824 dynamicAreas.push_back(1u);
2825 commands->setDynamicAreas(dynamicAreas);
2826
2827 commands->addResultBuffer();
2828
2829 group->addChild(new DescriptorCopyTestCase(testCtx, (name + "_array1").c_str(), commands));
2830 }
2831
2832 // Update array partially with writes and partially with a copy
2833 {
2834 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, useUpdateAfterBind));
2835 commands->addDescriptor(DescriptorSp(new T(4u, 0u, 4u, 3u)), 0u);
2836 commands->addDescriptor(DescriptorSp(new T(8u, 0u, 5u, 4u)), 0u);
2837
2838 commands->copyDescriptor(0u, 0u, 1u, // from
2839 0u, 1u, 5u, // to
2840 3u); // num descriptors
2841
2842 vector<uint32_t> dynamicAreas;
2843 dynamicAreas.push_back(2u);
2844 dynamicAreas.push_back(0u);
2845 dynamicAreas.push_back(1u);
2846 dynamicAreas.push_back(1u);
2847
2848 dynamicAreas.push_back(2u);
2849 dynamicAreas.push_back(0u);
2850 dynamicAreas.push_back(1u);
2851 dynamicAreas.push_back(2u);
2852 dynamicAreas.push_back(0u);
2853 dynamicAreas.push_back(1u);
2854 dynamicAreas.push_back(1u);
2855 dynamicAreas.push_back(2u);
2856 commands->setDynamicAreas(dynamicAreas);
2857
2858 commands->addResultBuffer();
2859
2860 group->addChild(new DescriptorCopyTestCase(testCtx, (name + "_array2").c_str(), commands));
2861 }
2862 }
2863
addSamplerCopyTests(tcu::TestContext & testCtx,de::MovePtr<tcu::TestCaseGroup> & group,PipelineType pipelineType,bool useUpdateAfterBind)2864 void addSamplerCopyTests(tcu::TestContext &testCtx, de::MovePtr<tcu::TestCaseGroup> &group, PipelineType pipelineType,
2865 bool useUpdateAfterBind)
2866 {
2867 // Simple copy between two samplers in the same set
2868 {
2869 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, useUpdateAfterBind));
2870 SamplerDescriptor *sampler0(new SamplerDescriptor());
2871 SamplerDescriptor *sampler1(new SamplerDescriptor());
2872 SampledImageDescriptor *image(new SampledImageDescriptor());
2873 sampler0->addImage(image);
2874 sampler1->addImage(image);
2875
2876 commands->addDescriptor(DescriptorSp(sampler0), 0u);
2877 commands->addDescriptor(DescriptorSp(sampler1), 0u);
2878 commands->addDescriptor(DescriptorSp(image), 0u);
2879
2880 commands->copyDescriptor(0u, 0u, // from
2881 0u, 1u); // to
2882
2883 commands->addResultBuffer();
2884
2885 group->addChild(new DescriptorCopyTestCase(testCtx, "sampler_0", commands));
2886 }
2887
2888 // Simple 3 sized array to 3 sized array inside the same set.
2889 {
2890 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, useUpdateAfterBind));
2891 SamplerDescriptor *sampler0(new SamplerDescriptor(3u, 0u, 3u));
2892 // One sampler in between to get the border colors to originally mismatch between sampler0 and sampler1.
2893 SamplerDescriptor *sampler1(new SamplerDescriptor());
2894 SamplerDescriptor *sampler2(new SamplerDescriptor(3u, 0u, 3u));
2895 SampledImageDescriptor *image(new SampledImageDescriptor());
2896
2897 sampler0->addImage(image, 3u);
2898 sampler2->addImage(image, 3u);
2899
2900 commands->addDescriptor(DescriptorSp(sampler0), 0u);
2901 commands->addDescriptor(DescriptorSp(sampler1), 0u);
2902 commands->addDescriptor(DescriptorSp(sampler2), 0u);
2903 commands->addDescriptor(DescriptorSp(image), 0u);
2904
2905 commands->copyDescriptor(0u, 0u, 0u, // from
2906 0u, 2u, 0u, // to
2907 3u); // num descriptors
2908
2909 commands->addResultBuffer();
2910
2911 group->addChild(new DescriptorCopyTestCase(testCtx, "sampler_array0", commands));
2912 }
2913
2914 // Simple 2 sized array to 3 sized array into different set.
2915 {
2916 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, useUpdateAfterBind));
2917 SamplerDescriptor *sampler0(new SamplerDescriptor(2u, 0u, 2u));
2918 SamplerDescriptor *sampler1(new SamplerDescriptor(3u, 0u, 3u));
2919 SampledImageDescriptor *image(new SampledImageDescriptor());
2920
2921 sampler0->addImage(image, 2u);
2922 sampler1->addImage(image, 3u);
2923
2924 commands->addDescriptor(DescriptorSp(sampler0), 0u);
2925 commands->addDescriptor(DescriptorSp(sampler1), 1u);
2926 commands->addDescriptor(DescriptorSp(image), 0u);
2927
2928 commands->copyDescriptor(0u, 0u, 0u, // from
2929 1u, 0u, 1u, // to
2930 2u); // num descriptors
2931
2932 commands->addResultBuffer();
2933
2934 group->addChild(new DescriptorCopyTestCase(testCtx, "sampler_array1", commands));
2935 }
2936 }
2937
addSampledImageCopyTests(tcu::TestContext & testCtx,de::MovePtr<tcu::TestCaseGroup> & group,PipelineType pipelineType,bool useUpdateAfterBind)2938 void addSampledImageCopyTests(tcu::TestContext &testCtx, de::MovePtr<tcu::TestCaseGroup> &group,
2939 PipelineType pipelineType, bool useUpdateAfterBind)
2940 {
2941 // Simple copy between two images in the same set
2942 {
2943 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, useUpdateAfterBind));
2944 SamplerDescriptor *sampler(new SamplerDescriptor());
2945 SampledImageDescriptor *image0(new SampledImageDescriptor());
2946 SampledImageDescriptor *image1(new SampledImageDescriptor());
2947 image0->addSampler(sampler);
2948 image1->addSampler(sampler);
2949
2950 commands->addDescriptor(DescriptorSp(image0), 0u);
2951 commands->addDescriptor(DescriptorSp(image1), 0u);
2952 commands->addDescriptor(DescriptorSp(sampler), 0u);
2953
2954 commands->copyDescriptor(0u, 0u, // from
2955 0u, 1u); // to
2956
2957 commands->addResultBuffer();
2958
2959 group->addChild(new DescriptorCopyTestCase(testCtx, "sampled_image_0", commands));
2960 }
2961
2962 // Simple 3 sized array to 3 sized array inside the same set.
2963 {
2964 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, useUpdateAfterBind));
2965 SamplerDescriptor *sampler(new SamplerDescriptor());
2966 SampledImageDescriptor *image0(new SampledImageDescriptor(3u, 0u, 3u));
2967 SampledImageDescriptor *image1(new SampledImageDescriptor(3u, 0u, 3u));
2968 image0->addSampler(sampler, 3u);
2969 image1->addSampler(sampler, 3u);
2970
2971 commands->addDescriptor(DescriptorSp(sampler), 0u);
2972 commands->addDescriptor(DescriptorSp(image0), 0u);
2973 commands->addDescriptor(DescriptorSp(image1), 0u);
2974
2975 commands->copyDescriptor(0u, 1u, 0u, // from
2976 0u, 2u, 0u, // to
2977 3u); // num descriptors
2978
2979 commands->addResultBuffer();
2980
2981 group->addChild(new DescriptorCopyTestCase(testCtx, "sampled_image_array0", commands));
2982 }
2983 }
2984
2985 // Mixture of different descriptors in the same test
addMixedDescriptorCopyTests(tcu::TestContext & testCtx,de::MovePtr<tcu::TestCaseGroup> & group,PipelineType pipelineType)2986 void addMixedDescriptorCopyTests(tcu::TestContext &testCtx, de::MovePtr<tcu::TestCaseGroup> &group,
2987 PipelineType pipelineType)
2988 {
2989 {
2990 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, false));
2991 SamplerDescriptor *sampler0(new SamplerDescriptor());
2992 SamplerDescriptor *sampler1(new SamplerDescriptor());
2993 SampledImageDescriptor *image0(new SampledImageDescriptor());
2994 SampledImageDescriptor *image1(new SampledImageDescriptor());
2995 StorageBufferDescriptor *storageBuffer0(new StorageBufferDescriptor());
2996 StorageBufferDescriptor *storageBuffer1(new StorageBufferDescriptor());
2997 StorageBufferDescriptor *storageBuffer2 = new StorageBufferDescriptor();
2998 sampler0->addImage(image0);
2999 sampler1->addImage(image1);
3000
3001 commands->addDescriptor(DescriptorSp(sampler0), 0u); // Set 0, binding 0
3002 commands->addDescriptor(DescriptorSp(storageBuffer0), 0u); // Set 0, binding 1
3003 commands->addDescriptor(DescriptorSp(image0), 0u); // Set 0, binding 2
3004 commands->addDescriptor(DescriptorSp(storageBuffer1), 0u); // Set 0, binding 3
3005 commands->addDescriptor(DescriptorSp(sampler1), 1u); // Set 1, binding 0
3006 commands->addDescriptor(DescriptorSp(image1), 1u); // Set 1, binding 1
3007 commands->addDescriptor(DescriptorSp(storageBuffer2), 1u); // Set 1, binding 2
3008
3009 // image1 to image0
3010 commands->copyDescriptor(1u, 1u, // from
3011 0u, 2u); // to
3012
3013 // storageBuffer0 to storageBuffer1
3014 commands->copyDescriptor(0u, 1u, // from
3015 0u, 3u); // to
3016
3017 // storageBuffer1 to storageBuffer2
3018 commands->copyDescriptor(0u, 3u, // from
3019 1u, 2u); // to
3020
3021 commands->addResultBuffer();
3022
3023 group->addChild(new DescriptorCopyTestCase(testCtx, "mix_0", commands));
3024 }
3025
3026 {
3027 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, false));
3028 StorageTexelBufferDescriptor *storageTexelBuffer0(new StorageTexelBufferDescriptor());
3029 StorageTexelBufferDescriptor *storageTexelBuffer1(new StorageTexelBufferDescriptor());
3030 UniformBufferDescriptor *uniformBuffer0(new UniformBufferDescriptor());
3031 UniformBufferDescriptor *uniformBuffer1(new UniformBufferDescriptor());
3032 UniformBufferDescriptor *uniformBuffer2(new UniformBufferDescriptor());
3033 DynamicStorageBufferDescriptor *dynamicStorageBuffer0(new DynamicStorageBufferDescriptor(1u, 0u, 1u, 3u));
3034 DynamicStorageBufferDescriptor *dynamicStorageBuffer1(new DynamicStorageBufferDescriptor(1u, 0u, 1u, 4u));
3035
3036 commands->addDescriptor(DescriptorSp(storageTexelBuffer0), 0u); // Set 0, binding 0
3037 commands->addDescriptor(DescriptorSp(uniformBuffer0), 0u); // Set 0, binding 1
3038 commands->addDescriptor(DescriptorSp(dynamicStorageBuffer0), 0u); // Set 0, binding 2
3039 commands->addDescriptor(DescriptorSp(uniformBuffer1), 0u); // Set 0, binding 3
3040 commands->addDescriptor(DescriptorSp(dynamicStorageBuffer1), 1u); // Set 1, binding 0
3041 commands->addDescriptor(DescriptorSp(storageTexelBuffer1), 1u); // Set 1, binding 1
3042 commands->addDescriptor(DescriptorSp(uniformBuffer2), 1u); // Set 1, binding 2
3043
3044 vector<uint32_t> dynamicAreas;
3045 dynamicAreas.push_back(2u);
3046 dynamicAreas.push_back(1u);
3047 commands->setDynamicAreas(dynamicAreas);
3048
3049 // uniformBuffer0 to uniformBuffer2
3050 commands->copyDescriptor(0u, 1u, // from
3051 1u, 2u); // to
3052
3053 // uniformBuffer1 to uniformBuffer2
3054 commands->copyDescriptor(0u, 3u, // from
3055 1u, 2u); // to
3056
3057 // storageTexelBuffer1 to storageTexelBuffer0
3058 commands->copyDescriptor(1u, 1u, // from
3059 0u, 0u); // to
3060
3061 // dynamicStorageBuffer0 to dynamicStorageBuffer1
3062 commands->copyDescriptor(0u, 2u, // from
3063 1u, 0u); // to
3064
3065 commands->addResultBuffer();
3066
3067 group->addChild(new DescriptorCopyTestCase(testCtx, "mix_1", commands));
3068 }
3069
3070 if (pipelineType == PIPELINE_TYPE_GRAPHICS)
3071 {
3072 // Mixture of descriptors, including input attachment.
3073 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, false));
3074 InputAttachmentDescriptor *inputAttachment0(new InputAttachmentDescriptor());
3075 InputAttachmentDescriptor *inputAttachment1(new InputAttachmentDescriptor());
3076 CombinedImageSamplerDescriptor *combinedImageSampler0(new CombinedImageSamplerDescriptor());
3077 CombinedImageSamplerDescriptor *combinedImageSampler1(new CombinedImageSamplerDescriptor());
3078 UniformTexelBufferDescriptor *uniformTexelBuffer0(new UniformTexelBufferDescriptor(5u, 0u, 5u));
3079 UniformTexelBufferDescriptor *uniformTexelBuffer1(new UniformTexelBufferDescriptor(3u, 1u, 1u));
3080
3081 commands->addDescriptor(DescriptorSp(combinedImageSampler0), 0u); // Set 0, binding 0
3082 commands->addDescriptor(DescriptorSp(inputAttachment0), 0u); // Set 0, binding 1
3083 commands->addDescriptor(DescriptorSp(uniformTexelBuffer0), 0u); // Set 0, binding 2
3084 commands->addDescriptor(DescriptorSp(combinedImageSampler1), 1u); // Set 1, binding 0
3085 commands->addDescriptor(DescriptorSp(inputAttachment1), 1u); // Set 1, binding 1
3086 commands->addDescriptor(DescriptorSp(uniformTexelBuffer1), 1u); // Set 1, binding 2
3087
3088 // uniformTexelBuffer0[1..3] to uniformTexelBuffer1[0..2]
3089 commands->copyDescriptor(0u, 2u, 1u, // from
3090 1u, 2u, 0u, // to
3091 3u); // num descriptors
3092
3093 // inputAttachment0 to inputAttachment1
3094 commands->copyDescriptor(0u, 1u, // from
3095 1u, 1u); // to
3096
3097 // combinedImageSampler0 to combinedImageSampler1
3098 commands->copyDescriptor(0u, 0u, // from
3099 1u, 0u); // to
3100
3101 commands->addResultBuffer();
3102
3103 group->addChild(new DescriptorCopyTestCase(testCtx, "mix_2", commands));
3104 }
3105
3106 #ifndef CTS_USES_VULKANSC
3107 if (pipelineType == PIPELINE_TYPE_GRAPHICS)
3108 {
3109 // Similar to the previous one, but adding inline uniform blocks to the mix.
3110 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, false));
3111 InlineUniformBlockDescriptor *iub0(new InlineUniformBlockDescriptor(4u, 0u, 4u));
3112 InlineUniformBlockDescriptor *iub1(new InlineUniformBlockDescriptor(4u, 0u, 1u));
3113 InputAttachmentDescriptor *inputAttachment0(new InputAttachmentDescriptor());
3114 InputAttachmentDescriptor *inputAttachment1(new InputAttachmentDescriptor());
3115 CombinedImageSamplerDescriptor *combinedImageSampler0(new CombinedImageSamplerDescriptor());
3116 CombinedImageSamplerDescriptor *combinedImageSampler1(new CombinedImageSamplerDescriptor());
3117 UniformTexelBufferDescriptor *uniformTexelBuffer0(new UniformTexelBufferDescriptor(5u, 0u, 5u));
3118 UniformTexelBufferDescriptor *uniformTexelBuffer1(new UniformTexelBufferDescriptor(3u, 1u, 1u));
3119
3120 commands->addDescriptor(DescriptorSp(iub0), 0u); // Set 0, binding 0
3121 commands->addDescriptor(DescriptorSp(combinedImageSampler0), 0u); // Set 0, binding 1
3122 commands->addDescriptor(DescriptorSp(inputAttachment0), 0u); // Set 0, binding 2
3123 commands->addDescriptor(DescriptorSp(uniformTexelBuffer0), 0u); // Set 0, binding 3
3124 commands->addDescriptor(DescriptorSp(iub1), 1u); // Set 1, binding 0
3125 commands->addDescriptor(DescriptorSp(combinedImageSampler1), 1u); // Set 1, binding 1
3126 commands->addDescriptor(DescriptorSp(inputAttachment1), 1u); // Set 1, binding 2
3127 commands->addDescriptor(DescriptorSp(uniformTexelBuffer1), 1u); // Set 1, binding 3
3128
3129 // iub0.data[0..2] to iub1.data[1..3]
3130 commands->copyDescriptor(0u, 0u, 0u, // from
3131 1u, 0u, 1u, // to
3132 3u); // num descriptors
3133
3134 // uniformTexelBuffer0[1..3] to uniformTexelBuffer1[0..2]
3135 commands->copyDescriptor(0u, 3u, 1u, // from
3136 1u, 3u, 0u, // to
3137 3u); // num descriptors
3138
3139 // inputAttachment0 to inputAttachment1
3140 commands->copyDescriptor(0u, 2u, // from
3141 1u, 2u); // to
3142
3143 // combinedImageSampler0 to combinedImageSampler1
3144 commands->copyDescriptor(0u, 1u, // from
3145 1u, 1u); // to
3146
3147 commands->addResultBuffer();
3148
3149 group->addChild(new DescriptorCopyTestCase(testCtx, "mix_3", commands));
3150 }
3151 #endif
3152
3153 // Mixture of descriptors using descriptor arrays
3154 {
3155 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, false));
3156 CombinedImageSamplerDescriptor *combinedImageSampler0(new CombinedImageSamplerDescriptor(3u, 0u, 3u));
3157 CombinedImageSamplerDescriptor *combinedImageSampler1(new CombinedImageSamplerDescriptor(4u, 0u, 2u));
3158 CombinedImageSamplerDescriptor *combinedImageSampler2(new CombinedImageSamplerDescriptor(3u, 0u, 3u));
3159 StorageImageDescriptor *storageImage0(new StorageImageDescriptor(5u, 0u, 5u));
3160 StorageImageDescriptor *storageImage1(new StorageImageDescriptor(3u, 0u, 0u));
3161 StorageBufferDescriptor *storageBuffer0(new StorageBufferDescriptor(2u, 0u, 1u));
3162 StorageBufferDescriptor *storageBuffer1(new StorageBufferDescriptor(3u, 0u, 3u));
3163
3164 commands->addDescriptor(DescriptorSp(combinedImageSampler0), 0u); // Set 0, binding 0
3165 commands->addDescriptor(DescriptorSp(storageImage0), 0u); // Set 0, binding 1
3166 commands->addDescriptor(DescriptorSp(combinedImageSampler1), 0u); // Set 0, binding 2
3167 commands->addDescriptor(DescriptorSp(storageBuffer0), 0u); // Set 0, binding 3
3168 commands->addDescriptor(DescriptorSp(storageBuffer1), 0u); // Set 0, binding 4
3169 commands->addDescriptor(DescriptorSp(storageImage1), 1u); // Set 1, binding 0
3170 commands->addDescriptor(DescriptorSp(combinedImageSampler2), 1u); // Set 1, binding 1
3171
3172 // combinedImageSampler0[1..2] to combinedImageSampler1[2..3]
3173 commands->copyDescriptor(0u, 0u, 1u, // from
3174 0u, 2u, 2u, // to
3175 2u); // num descriptors
3176
3177 // storageImage0[2..4] to storageImage1[0..2]
3178 commands->copyDescriptor(0u, 1u, 2u, // from
3179 1u, 0u, 0u, // to
3180 3u); // num descriptors
3181
3182 // storageBuffer1[1..2] to storageBuffer0[0..1]
3183 commands->copyDescriptor(0u, 4u, 1u, // from
3184 0u, 3u, 0u, // to
3185 2u); // num descriptors
3186
3187 commands->addResultBuffer();
3188
3189 group->addChild(new DescriptorCopyTestCase(testCtx, "mix_array0", commands));
3190 }
3191
3192 // Similar to the previous one but including inline uniform blocks.
3193 #ifndef CTS_USES_VULKANSC
3194 {
3195 DescriptorCommandsSp commands(new DescriptorCommands(pipelineType, false));
3196 InlineUniformBlockDescriptor *iub0(new InlineUniformBlockDescriptor(4u, 0u, 1u));
3197 InlineUniformBlockDescriptor *iub1(new InlineUniformBlockDescriptor(4u, 0u, 4u));
3198 CombinedImageSamplerDescriptor *combinedImageSampler0(new CombinedImageSamplerDescriptor(3u, 0u, 3u));
3199 CombinedImageSamplerDescriptor *combinedImageSampler1(new CombinedImageSamplerDescriptor(4u, 0u, 2u));
3200 CombinedImageSamplerDescriptor *combinedImageSampler2(new CombinedImageSamplerDescriptor(3u, 0u, 3u));
3201 StorageImageDescriptor *storageImage0(new StorageImageDescriptor(5u, 0u, 5u));
3202 StorageImageDescriptor *storageImage1(new StorageImageDescriptor(3u, 0u, 0u));
3203 StorageBufferDescriptor *storageBuffer0(new StorageBufferDescriptor(2u, 0u, 1u));
3204 StorageBufferDescriptor *storageBuffer1(new StorageBufferDescriptor(3u, 0u, 3u));
3205
3206 commands->addDescriptor(DescriptorSp(iub0), 0u); // Set 0, binding 0
3207 commands->addDescriptor(DescriptorSp(combinedImageSampler0), 0u); // Set 0, binding 1
3208 commands->addDescriptor(DescriptorSp(storageImage0), 0u); // Set 0, binding 2
3209 commands->addDescriptor(DescriptorSp(combinedImageSampler1), 0u); // Set 0, binding 3
3210 commands->addDescriptor(DescriptorSp(storageBuffer0), 0u); // Set 0, binding 4
3211 commands->addDescriptor(DescriptorSp(storageBuffer1), 0u); // Set 0, binding 5
3212 commands->addDescriptor(DescriptorSp(combinedImageSampler2), 0u); // Set 0, binding 6
3213 commands->addDescriptor(DescriptorSp(iub1), 1u); // Set 1, binding 0
3214 commands->addDescriptor(DescriptorSp(storageImage1), 1u); // Set 1, binding 1
3215
3216 // iub1.data[0..2] to iub0.data[1..3]
3217 commands->copyDescriptor(1u, 0u, 0u, // from
3218 0u, 0u, 1u, // to
3219 3u); // num descriptors
3220
3221 // combinedImageSampler0[1..2] to combinedImageSampler1[2..3]
3222 commands->copyDescriptor(0u, 1u, 1u, // from
3223 0u, 3u, 2u, // to
3224 2u); // num descriptors
3225
3226 // storageImage0[2..4] to storageImage1[0..2]
3227 commands->copyDescriptor(0u, 2u, 2u, // from
3228 1u, 1u, 0u, // to
3229 3u); // num descriptors
3230
3231 // storageBuffer1[1..2] to storageBuffer0[0..1]
3232 commands->copyDescriptor(0u, 5u, 1u, // from
3233 0u, 4u, 0u, // to
3234 2u); // num descriptors
3235
3236 commands->addResultBuffer();
3237
3238 group->addChild(new DescriptorCopyTestCase(testCtx, "mix_array1", commands));
3239 }
3240 #endif
3241 }
3242
3243 } // namespace
3244
createTestsForAllDescriptorTypes(tcu::TestContext & testCtx,de::MovePtr<tcu::TestCaseGroup> & parentGroup,PipelineType pipelineType,bool useUpdateAfterBind=false)3245 void createTestsForAllDescriptorTypes(tcu::TestContext &testCtx, de::MovePtr<tcu::TestCaseGroup> &parentGroup,
3246 PipelineType pipelineType, bool useUpdateAfterBind = false)
3247 {
3248 addDescriptorCopyTests<UniformBufferDescriptor>(testCtx, parentGroup, "uniform_buffer", pipelineType,
3249 useUpdateAfterBind);
3250 addDescriptorCopyTests<StorageBufferDescriptor>(testCtx, parentGroup, "storage_buffer", pipelineType,
3251 useUpdateAfterBind);
3252 addDescriptorCopyTests<CombinedImageSamplerDescriptor>(testCtx, parentGroup, "combined_image_sampler", pipelineType,
3253 useUpdateAfterBind);
3254 addDescriptorCopyTests<StorageImageDescriptor>(testCtx, parentGroup, "storage_image", pipelineType,
3255 useUpdateAfterBind);
3256 addDescriptorCopyTests<UniformTexelBufferDescriptor>(testCtx, parentGroup, "uniform_texel_buffer", pipelineType,
3257 useUpdateAfterBind);
3258 addDescriptorCopyTests<StorageTexelBufferDescriptor>(testCtx, parentGroup, "storage_texel_buffer", pipelineType,
3259 useUpdateAfterBind);
3260
3261 #ifndef CTS_USES_VULKANSC
3262 addDescriptorCopyTests<InlineUniformBlockDescriptor>(testCtx, parentGroup, "inline_uniform_block", pipelineType,
3263 useUpdateAfterBind);
3264 #endif
3265
3266 // create tests that can be run only without UpdateAfterBind
3267 if (useUpdateAfterBind == false)
3268 {
3269 addDescriptorCopyTests<DynamicUniformBufferDescriptor>(testCtx, parentGroup, "uniform_buffer_dynamic",
3270 pipelineType, false);
3271 addDescriptorCopyTests<DynamicStorageBufferDescriptor>(testCtx, parentGroup, "storage_buffer_dynamic",
3272 pipelineType, false);
3273
3274 // create tests that are graphics pipeline specific
3275 if (pipelineType == PIPELINE_TYPE_GRAPHICS)
3276 addDescriptorCopyTests<InputAttachmentDescriptor>(testCtx, parentGroup, "input_attachment",
3277 PIPELINE_TYPE_GRAPHICS, false);
3278
3279 addMixedDescriptorCopyTests(testCtx, parentGroup, pipelineType);
3280 }
3281
3282 addSamplerCopyTests(testCtx, parentGroup, pipelineType, useUpdateAfterBind);
3283 addSampledImageCopyTests(testCtx, parentGroup, pipelineType, useUpdateAfterBind);
3284 }
3285
createDescriptorCopyTests(tcu::TestContext & testCtx)3286 tcu::TestCaseGroup *createDescriptorCopyTests(tcu::TestContext &testCtx)
3287 {
3288 de::MovePtr<tcu::TestCaseGroup> descriptorCopyGroup(new tcu::TestCaseGroup(testCtx, "descriptor_copy"));
3289
3290 de::MovePtr<tcu::TestCaseGroup> computeGroup(new tcu::TestCaseGroup(testCtx, "compute"));
3291 de::MovePtr<tcu::TestCaseGroup> graphicsGroup(new tcu::TestCaseGroup(testCtx, "graphics"));
3292 // Graphics tests with update after bind
3293 de::MovePtr<tcu::TestCaseGroup> graphicsUABGroup(new tcu::TestCaseGroup(testCtx, "graphics_uab"));
3294
3295 createTestsForAllDescriptorTypes(testCtx, computeGroup, PIPELINE_TYPE_COMPUTE);
3296 createTestsForAllDescriptorTypes(testCtx, graphicsGroup, PIPELINE_TYPE_GRAPHICS);
3297 createTestsForAllDescriptorTypes(testCtx, graphicsUABGroup, PIPELINE_TYPE_GRAPHICS, true);
3298
3299 descriptorCopyGroup->addChild(computeGroup.release());
3300 descriptorCopyGroup->addChild(graphicsGroup.release());
3301 descriptorCopyGroup->addChild(graphicsUABGroup.release());
3302
3303 return descriptorCopyGroup.release();
3304 }
3305
3306 } // namespace BindingModel
3307 } // namespace vkt
3308