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