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