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