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