1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2017 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Memory binding test excercising VK_KHR_bind_memory2 extension.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktMemoryBindingTests.hpp"
25 
26 #include "vktTestCase.hpp"
27 #include "tcuTestLog.hpp"
28 
29 #include "vkPlatform.hpp"
30 #include "gluVarType.hpp"
31 #include "deStringUtil.hpp"
32 #include "vkPrograms.hpp"
33 #include "vkQueryUtil.hpp"
34 #include "vkRefUtil.hpp"
35 #include "deSharedPtr.hpp"
36 #include "vktTestCase.hpp"
37 #include "vkTypeUtil.hpp"
38 #include "vkCmdUtil.hpp"
39 #include "vkImageUtil.hpp"
40 
41 #include <algorithm>
42 
43 namespace vkt
44 {
45 namespace memory
46 {
47 namespace
48 {
49 
50 using namespace vk;
51 
52 typedef const VkMemoryDedicatedAllocateInfo									ConstDedicatedInfo;
53 typedef de::SharedPtr<Move<VkDeviceMemory> >								MemoryRegionPtr;
54 typedef std::vector<MemoryRegionPtr>										MemoryRegionsList;
55 typedef de::SharedPtr<Move<VkBuffer> >										BufferPtr;
56 typedef std::vector<BufferPtr>												BuffersList;
57 typedef de::SharedPtr<Move<VkImage> >										ImagePtr;
58 typedef std::vector<ImagePtr>												ImagesList;
59 typedef std::vector<VkBindBufferMemoryInfo>									BindBufferMemoryInfosList;
60 typedef std::vector<VkBindImageMemoryInfo>									BindImageMemoryInfosList;
61 
62 class MemoryMappingRAII
63 {
64 public:
MemoryMappingRAII(const DeviceInterface & deviceInterface,const VkDevice & device,VkDeviceMemory deviceMemory,VkDeviceSize offset,VkDeviceSize size,VkMemoryMapFlags flags)65 										MemoryMappingRAII					(const DeviceInterface&	deviceInterface,
66 																			 const VkDevice&		device,
67 																			 VkDeviceMemory			deviceMemory,
68 																			 VkDeviceSize			offset,
69 																			 VkDeviceSize			size,
70 																			 VkMemoryMapFlags		flags)
71 										: vk								(deviceInterface)
72 										, dev								(device)
73 										, memory							(deviceMemory)
74 										, hostPtr							(DE_NULL)
75 
76 	{
77 		vk.mapMemory(dev, memory, offset, size, flags, &hostPtr);
78 	}
79 
~MemoryMappingRAII()80 										~MemoryMappingRAII					()
81 	{
82 		vk.unmapMemory(dev, memory);
83 		hostPtr = DE_NULL;
84 	}
85 
ptr()86 	void*								ptr									()
87 	{
88 		return hostPtr;
89 	}
90 
flush()91 	void								flush								()
92 	{
93 		const VkMappedMemoryRange		range								= makeMemoryRange(0, VK_WHOLE_SIZE);
94 		VK_CHECK(vk.flushMappedMemoryRanges(dev, 1u, &range));
95 	}
96 
invalidate()97 	void								invalidate							()
98 	{
99 		const VkMappedMemoryRange		range								= makeMemoryRange(0, VK_WHOLE_SIZE);
100 		VK_CHECK(vk.invalidateMappedMemoryRanges(dev, 1u, &range));
101 	}
102 
103 
104 protected:
105 	const DeviceInterface&				vk;
106 	const VkDevice&						dev;
107 	VkDeviceMemory						memory;
108 	void*								hostPtr;
109 
makeMemoryRange(VkDeviceSize offset,VkDeviceSize size)110 	const VkMappedMemoryRange			makeMemoryRange						(VkDeviceSize			offset,
111 																			 VkDeviceSize			size)
112 	{
113 		const VkMappedMemoryRange		range								=
114 		{
115 			VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
116 			DE_NULL,
117 			memory,
118 			offset,
119 			size
120 		};
121 		return range;
122 	}
123 };
124 
125 class SimpleRandomGenerator
126 {
127 public:
SimpleRandomGenerator(deUint32 seed)128 										SimpleRandomGenerator				(deUint32				seed)
129 										: value								(seed)
130 	{}
getNext()131 	deUint32							getNext								()
132 	{
133 		value += 1;
134 		value ^= (value << 21);
135 		value ^= (value >> 15);
136 		value ^= (value << 4);
137 		return value;
138 	}
139 protected:
140 	deUint32							value;
141 };
142 
143 struct BindingCaseParameters
144 {
145 	VkBufferCreateFlags					flags;
146 	VkBufferUsageFlags					usage;
147 	VkSharingMode						sharing;
148 	VkDeviceSize						bufferSize;
149 	VkExtent3D							imageSize;
150 	deUint32							targetsCount;
151 	VkImageCreateFlags					imageCreateFlags;
152 	bool								usePriority;
153 };
154 
makeBindingCaseParameters(deUint32 targetsCount,deUint32 width,deUint32 height,VkImageCreateFlags imageCreateFlags,bool usePriority)155 BindingCaseParameters					makeBindingCaseParameters			(deUint32				targetsCount,
156 																			 deUint32				width,
157 																			 deUint32				height,
158 																			 VkImageCreateFlags		imageCreateFlags,
159 																			 bool					usePriority)
160 {
161 	BindingCaseParameters				params;
162 	deMemset(&params, 0, sizeof(BindingCaseParameters));
163 	params.imageSize.width = width;
164 	params.imageSize.height = height;
165 	params.imageSize.depth = 1;
166 	params.bufferSize = params.imageSize.width * params.imageSize.height * params.imageSize.depth * sizeof(deUint32);
167 	params.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
168 	params.targetsCount = targetsCount;
169 	params.imageCreateFlags = imageCreateFlags;
170 	params.usePriority = usePriority;
171 	return params;
172 }
173 
makeBindingCaseParameters(deUint32 targetsCount,VkBufferUsageFlags usage,VkSharingMode sharing,VkDeviceSize bufferSize,VkImageCreateFlags imageCreateFlags,bool usePriority)174 BindingCaseParameters					makeBindingCaseParameters			(deUint32				targetsCount,
175 																			 VkBufferUsageFlags		usage,
176 																			 VkSharingMode			sharing,
177 																			 VkDeviceSize			bufferSize,
178 																			 VkImageCreateFlags		imageCreateFlags,
179 																			 bool					usePriority)
180 {
181 	BindingCaseParameters				params								=
182 	{
183 		0,																	// VkBufferCreateFlags	flags;
184 		usage,																// VkBufferUsageFlags	usage;
185 		sharing,															// VkSharingMode		sharing;
186 		bufferSize,															// VkDeviceSize			bufferSize;
187 		{0u, 0u, 0u},														// VkExtent3D			imageSize;
188 		targetsCount,														// deUint32				targetsCount;
189 		imageCreateFlags,													// VkImageCreateFlags	imageCreateFlags
190 		usePriority,														// bool					usePriority
191 	};
192 	return params;
193 }
194 
makeImageCreateInfo(BindingCaseParameters & params)195 VkImageCreateInfo						makeImageCreateInfo					(BindingCaseParameters&	params)
196 {
197 	const VkImageCreateInfo				imageParams							=
198 	{
199 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,								// VkStructureType		sType;
200 		DE_NULL,															// const void*			pNext;
201 		params.imageCreateFlags,											// VkImageCreateFlags	flags;
202 		VK_IMAGE_TYPE_2D,													// VkImageType			imageType;
203 		VK_FORMAT_R8G8B8A8_UINT,											// VkFormat				format;
204 		params.imageSize,													// VkExtent3D			extent;
205 		1u,																	// deUint32				mipLevels;
206 		1u,																	// deUint32				arrayLayers;
207 		VK_SAMPLE_COUNT_1_BIT,												// VkSampleCountFlagBits samples;
208 		VK_IMAGE_TILING_LINEAR,												// VkImageTiling		tiling;
209 		VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
210 		VK_SHARING_MODE_EXCLUSIVE,											// VkSharingMode		sharingMode;
211 		0u,																	// deUint32				queueFamilyIndexCount;
212 		DE_NULL,															// const deUint32*		pQueueFamilyIndices;
213 		VK_IMAGE_LAYOUT_UNDEFINED,											// VkImageLayout		initialLayout;
214 	};
215 	return imageParams;
216 }
217 
makeBufferCreateInfo(Context & ctx,BindingCaseParameters & params)218 VkBufferCreateInfo						makeBufferCreateInfo				(Context&				ctx,
219 																			 BindingCaseParameters&	params)
220 {
221 	const deUint32						queueFamilyIndex					= ctx.getUniversalQueueFamilyIndex();
222 	VkBufferCreateInfo					bufferParams						=
223 	{
224 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,								// VkStructureType		sType;
225 		DE_NULL,															// const void*			pNext;
226 		params.flags,														// VkBufferCreateFlags	flags;
227 		params.bufferSize,													// VkDeviceSize			size;
228 		params.usage,														// VkBufferUsageFlags	usage;
229 		params.sharing,														// VkSharingMode		sharingMode;
230 		1u,																	// uint32_t				queueFamilyIndexCount;
231 		&queueFamilyIndex,													// const uint32_t*		pQueueFamilyIndices;
232 	};
233 	return bufferParams;
234 }
235 
makeMemoryAllocateInfo(VkMemoryRequirements & memReqs,const void * next)236 const VkMemoryAllocateInfo				makeMemoryAllocateInfo				(VkMemoryRequirements&	memReqs,
237 																			 const void*	next)
238 {
239 	const deUint32						heapTypeIndex						= (deUint32)deCtz32(memReqs.memoryTypeBits);
240 	const VkMemoryAllocateInfo			allocateParams						=
241 	{
242 		VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,								// VkStructureType		sType;
243 		next,																// const void*			pNext;
244 		memReqs.size,														// VkDeviceSize			allocationSize;
245 		heapTypeIndex,														// uint32_t				memoryTypeIndex;
246 	};
247 	return allocateParams;
248 }
249 
250 enum MemoryHostVisibility
251 {
252 	MemoryAny,
253 	MemoryHostVisible
254 };
255 
selectMatchingMemoryType(Context & ctx,VkMemoryRequirements & memReqs,MemoryHostVisibility memoryVisibility)256 deUint32								selectMatchingMemoryType			(Context&				ctx,
257 																			 VkMemoryRequirements&	memReqs,
258 																			 MemoryHostVisibility	memoryVisibility)
259 {
260 	const VkPhysicalDevice				vkPhysicalDevice					= ctx.getPhysicalDevice();
261 	const InstanceInterface&			vkInstance							= ctx.getInstanceInterface();
262 	VkPhysicalDeviceMemoryProperties	memoryProperties;
263 
264 	vkInstance.getPhysicalDeviceMemoryProperties(vkPhysicalDevice, &memoryProperties);
265 	if (memoryVisibility == MemoryHostVisible)
266 	{
267 		for (deUint32 typeNdx = 0; typeNdx < memoryProperties.memoryTypeCount; ++typeNdx)
268 		{
269 			const deBool				isInAllowed							= (memReqs.memoryTypeBits & (1u << typeNdx)) != 0u;
270 			const deBool				hasRightProperties					= (memoryProperties.memoryTypes[typeNdx].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0u;
271 			if (isInAllowed && hasRightProperties)
272 				return typeNdx;
273 		}
274 	}
275 	return (deUint32)deCtz32(memReqs.memoryTypeBits);
276 }
277 
makeMemoryAllocateInfo(Context & ctx,VkMemoryRequirements & memReqs,MemoryHostVisibility memoryVisibility)278 const VkMemoryAllocateInfo				makeMemoryAllocateInfo				(Context&				ctx,
279 																			 VkMemoryRequirements&	memReqs,
280 																			 MemoryHostVisibility	memoryVisibility)
281 {
282 	const deUint32						heapTypeIndex						= selectMatchingMemoryType(ctx, memReqs, memoryVisibility);
283 	const VkMemoryAllocateInfo			allocateParams						=
284 	{
285 		VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,								// VkStructureType		sType;
286 		DE_NULL,															// const void*			pNext;
287 		memReqs.size,														// VkDeviceSize			allocationSize;
288 		heapTypeIndex,														// uint32_t				memoryTypeIndex;
289 	};
290 	return allocateParams;
291 }
292 
makeDedicatedAllocationInfo(VkBuffer buffer)293 ConstDedicatedInfo						makeDedicatedAllocationInfo			(VkBuffer				buffer)
294 {
295 	ConstDedicatedInfo					dedicatedAllocationInfo				=
296 	{
297 		VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,				// VkStructureType		sType
298 		DE_NULL,															// const void*			pNext
299 		DE_NULL,															// VkImage				image
300 		buffer																// VkBuffer				buffer
301 	};
302 	return dedicatedAllocationInfo;
303 }
304 
makeDedicatedAllocationInfo(VkImage image)305 ConstDedicatedInfo						makeDedicatedAllocationInfo			(VkImage				image)
306 {
307 	ConstDedicatedInfo					dedicatedAllocationInfo				=
308 	{
309 		VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,				// VkStructureType		sType
310 		DE_NULL,															// const void*			pNext
311 		image,																// VkImage				image
312 		DE_NULL																// VkBuffer				buffer
313 	};
314 	return dedicatedAllocationInfo;
315 }
316 
makeBufferMemoryBindingInfo(VkBuffer buffer,VkDeviceMemory memory)317 const VkBindBufferMemoryInfo			makeBufferMemoryBindingInfo			(VkBuffer				buffer,
318 																			 VkDeviceMemory			memory)
319 {
320 	const VkBindBufferMemoryInfo		bufferMemoryBinding					=
321 	{
322 		VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHR,						// VkStructureType		sType;
323 		DE_NULL,															// const void*			pNext;
324 		buffer,																// VkBuffer				buffer;
325 		memory,																// VkDeviceMemory		memory;
326 		0u,																	// VkDeviceSize			memoryOffset;
327 	};
328 	return bufferMemoryBinding;
329 }
330 
makeImageMemoryBindingInfo(VkImage image,VkDeviceMemory memory)331 const VkBindImageMemoryInfo				makeImageMemoryBindingInfo			(VkImage				image,
332 																			 VkDeviceMemory			memory)
333 {
334 	const VkBindImageMemoryInfo		imageMemoryBinding					=
335 	{
336 		VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR,						// VkStructureType		sType;
337 		DE_NULL,															// const void*			pNext;
338 		image,																// VkImage				image;
339 		memory,																// VkDeviceMemory		memory;
340 		0u,																	// VkDeviceSize			memoryOffset;
341 	};
342 	return imageMemoryBinding;
343 }
344 
makeMemoryPriorityAllocateInfo(const void * pNext,float priority)345 const VkMemoryPriorityAllocateInfoEXT	makeMemoryPriorityAllocateInfo		(const void *	pNext,
346 																			 float			priority)
347 {
348 	const VkMemoryPriorityAllocateInfoEXT	info						=
349 	{
350 		VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT,				// VkStructureType		sType;
351 		pNext,																// const void*			pNext;
352 		priority,															// float				priority
353 	};
354 	return info;
355 }
356 
357 enum TransferDirection
358 {
359 	TransferToResource														= 0,
360 	TransferFromResource													= 1
361 };
362 
makeMemoryBarrierInfo(VkBuffer buffer,VkDeviceSize size,TransferDirection direction)363 const VkBufferMemoryBarrier				makeMemoryBarrierInfo				(VkBuffer				buffer,
364 																			 VkDeviceSize			size,
365 																			 TransferDirection		direction)
366 {
367 	const deBool fromRes													= direction == TransferFromResource;
368 	const VkAccessFlags					srcMask								= static_cast<VkAccessFlags>(fromRes ? VK_ACCESS_HOST_WRITE_BIT : VK_ACCESS_TRANSFER_WRITE_BIT);
369 	const VkAccessFlags					dstMask								= static_cast<VkAccessFlags>(fromRes ? VK_ACCESS_TRANSFER_READ_BIT : VK_ACCESS_HOST_READ_BIT);
370 	const VkBufferMemoryBarrier			bufferBarrier						=
371 	{
372 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,							// VkStructureType		sType;
373 		DE_NULL,															// const void*			pNext;
374 		srcMask,															// VkAccessFlags		srcAccessMask;
375 		dstMask,															// VkAccessFlags		dstAccessMask;
376 		VK_QUEUE_FAMILY_IGNORED,											// deUint32				srcQueueFamilyIndex;
377 		VK_QUEUE_FAMILY_IGNORED,											// deUint32				dstQueueFamilyIndex;
378 		buffer,																// VkBuffer				buffer;
379 		0u,																	// VkDeviceSize			offset;
380 		size																// VkDeviceSize			size;
381 	};
382 	return bufferBarrier;
383 }
384 
makeMemoryBarrierInfo(VkImage image,VkAccessFlags srcAccess,VkAccessFlags dstAccess,VkImageLayout oldLayout,VkImageLayout newLayout)385 const VkImageMemoryBarrier				makeMemoryBarrierInfo				(VkImage				image,
386 																			 VkAccessFlags			srcAccess,
387 																			 VkAccessFlags			dstAccess,
388 																			 VkImageLayout			oldLayout,
389 																			 VkImageLayout			newLayout)
390 {
391 	const VkImageAspectFlags			aspect								= VK_IMAGE_ASPECT_COLOR_BIT;
392 	const VkImageMemoryBarrier			imageBarrier						=
393 	{
394 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,								// VkStructureType		sType;
395 		DE_NULL,															// const void*			pNext;
396 		srcAccess,															// VkAccessFlags		srcAccessMask;
397 		dstAccess,															// VkAccessFlags		dstAccessMask;
398 		oldLayout,															// VkImageLayout		oldLayout;
399 		newLayout,															// VkImageLayout		newLayout;
400 		VK_QUEUE_FAMILY_IGNORED,											// deUint32				srcQueueFamilyIndex;
401 		VK_QUEUE_FAMILY_IGNORED,											// deUint32				dstQueueFamilyIndex;
402 		image,																// VkImage				image;
403 		{																	// VkImageSubresourceRange subresourceRange;
404 			aspect,															// VkImageAspectFlags	aspect;
405 			0u,																// deUint32				baseMipLevel;
406 			1u,																// deUint32				mipLevels;
407 			0u,																// deUint32				baseArraySlice;
408 			1u,																// deUint32				arraySize;
409 		}
410 	};
411 	return imageBarrier;
412 }
413 
createCommandBuffer(const DeviceInterface & vk,VkDevice device,VkCommandPool commandPool)414 Move<VkCommandBuffer>					createCommandBuffer					(const DeviceInterface&	vk,
415 																			 VkDevice				device,
416 																			 VkCommandPool			commandPool)
417 {
418 	const VkCommandBufferAllocateInfo allocInfo =
419 	{
420 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
421 		DE_NULL,
422 		commandPool,
423 		VK_COMMAND_BUFFER_LEVEL_PRIMARY,
424 		1
425 	};
426 	return allocateCommandBuffer(vk, device, &allocInfo);
427 }
428 
429 
430 template<typename TTarget>
431 void									createBindingTargets				(std::vector<de::SharedPtr<Move<TTarget> > >&
432 																									targets,
433 																			 Context&				ctx,
434 																			 BindingCaseParameters	params);
435 
436 template<>
createBindingTargets(BuffersList & targets,Context & ctx,BindingCaseParameters params)437 void									createBindingTargets<VkBuffer>		(BuffersList&			targets,
438 																			 Context&				ctx,
439 																			 BindingCaseParameters	params)
440 {
441 	const deUint32						count								= params.targetsCount;
442 	const VkDevice						vkDevice							= ctx.getDevice();
443 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
444 
445 	targets.reserve(count);
446 	for (deUint32 i = 0u; i < count; ++i)
447 	{
448 		VkBufferCreateInfo				bufferParams						= makeBufferCreateInfo(ctx, params);
449 		targets.push_back(BufferPtr(new Move<VkBuffer>(createBuffer(vk, vkDevice, &bufferParams))));
450 	}
451 }
452 
453 template<>
createBindingTargets(ImagesList & targets,Context & ctx,BindingCaseParameters params)454 void									createBindingTargets<VkImage>		(ImagesList&			targets,
455 																			 Context&				ctx,
456 																			 BindingCaseParameters	params)
457 {
458 	const deUint32						count								= params.targetsCount;
459 	const VkDevice						vkDevice							= ctx.getDevice();
460 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
461 
462 	targets.reserve(count);
463 	for (deUint32 i = 0u; i < count; ++i)
464 	{
465 		VkImageCreateInfo				imageParams							= makeImageCreateInfo(params);
466 		targets.push_back(ImagePtr(new Move<VkImage>(createImage(vk, vkDevice, &imageParams))));
467 	}
468 }
469 
470 template<typename TTarget, deBool TDedicated>
471 void									createMemory						(std::vector<de::SharedPtr<Move<TTarget> > >&
472 																									targets,
473 																			 MemoryRegionsList&		memory,
474 																			 Context&				ctx,
475 																			 BindingCaseParameters	params);
476 
477 template<>
createMemory(BuffersList & targets,MemoryRegionsList & memory,Context & ctx,BindingCaseParameters params)478 void									createMemory<VkBuffer, DE_FALSE>	(BuffersList&			targets,
479 																			 MemoryRegionsList&		memory,
480 																			 Context&				ctx,
481 																			 BindingCaseParameters	params)
482 {
483 	DE_UNREF(params);
484 	const deUint32						count								= static_cast<deUint32>(targets.size());
485 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
486 	const VkDevice						vkDevice							= ctx.getDevice();
487 
488 	memory.reserve(count);
489 	for (deUint32 i = 0; i < count; ++i)
490 	{
491 		VkMemoryRequirements			memReqs;
492 
493 		vk.getBufferMemoryRequirements(vkDevice, **targets[i], &memReqs);
494 
495 		VkMemoryPriorityAllocateInfoEXT	priority							= makeMemoryPriorityAllocateInfo(DE_NULL, ((float)i)/((float)count));
496 		const VkMemoryAllocateInfo		memAlloc							= makeMemoryAllocateInfo(memReqs, params.usePriority ? &priority : DE_NULL);
497 		VkDeviceMemory					rawMemory							= DE_NULL;
498 
499 		vk.allocateMemory(vkDevice, &memAlloc, (VkAllocationCallbacks*)DE_NULL, &rawMemory);
500 		memory.push_back(MemoryRegionPtr(new Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL))));
501 	}
502 }
503 
504 template<>
createMemory(ImagesList & targets,MemoryRegionsList & memory,Context & ctx,BindingCaseParameters params)505 void									createMemory<VkImage, DE_FALSE>		(ImagesList&			targets,
506 																			 MemoryRegionsList&		memory,
507 																			 Context&				ctx,
508 																			 BindingCaseParameters	params)
509 {
510 	DE_UNREF(params);
511 	const deUint32						count								= static_cast<deUint32>(targets.size());
512 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
513 	const VkDevice						vkDevice							= ctx.getDevice();
514 
515 	memory.reserve(count);
516 	for (deUint32 i = 0; i < count; ++i)
517 	{
518 		VkMemoryRequirements			memReqs;
519 		vk.getImageMemoryRequirements(vkDevice, **targets[i], &memReqs);
520 
521 		VkMemoryPriorityAllocateInfoEXT	priority							= makeMemoryPriorityAllocateInfo(DE_NULL, ((float)i)/((float)count));
522 		const VkMemoryAllocateInfo		memAlloc							= makeMemoryAllocateInfo(memReqs, params.usePriority ? &priority : DE_NULL);
523 		VkDeviceMemory					rawMemory							= DE_NULL;
524 
525 		vk.allocateMemory(vkDevice, &memAlloc, (VkAllocationCallbacks*)DE_NULL, &rawMemory);
526 		memory.push_back(de::SharedPtr<Move<VkDeviceMemory> >(new Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL))));
527 	}
528 }
529 
530 template<>
createMemory(BuffersList & targets,MemoryRegionsList & memory,Context & ctx,BindingCaseParameters params)531 void									createMemory<VkBuffer, DE_TRUE>		(BuffersList&			targets,
532 																			 MemoryRegionsList&		memory,
533 																			 Context&				ctx,
534 																			 BindingCaseParameters	params)
535 {
536 	DE_UNREF(params);
537 	const deUint32						count								= static_cast<deUint32>(targets.size());
538 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
539 	const VkDevice						vkDevice							= ctx.getDevice();
540 
541 	memory.reserve(count);
542 	for (deUint32 i = 0; i < count; ++i)
543 	{
544 		VkMemoryRequirements			memReqs;
545 
546 		vk.getBufferMemoryRequirements(vkDevice, **targets[i], &memReqs);
547 
548 		ConstDedicatedInfo				dedicatedAllocationInfo				= makeDedicatedAllocationInfo(**targets[i]);;
549 		VkMemoryPriorityAllocateInfoEXT	priority							= makeMemoryPriorityAllocateInfo(&dedicatedAllocationInfo, ((float)i)/((float)count));
550 		const VkMemoryAllocateInfo		memAlloc							= makeMemoryAllocateInfo(memReqs, params.usePriority ? &priority : (const void *)&dedicatedAllocationInfo);
551 		VkDeviceMemory					rawMemory							= DE_NULL;
552 
553 		vk.allocateMemory(vkDevice, &memAlloc, static_cast<VkAllocationCallbacks*>(DE_NULL), &rawMemory);
554 		memory.push_back(MemoryRegionPtr(new Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL))));
555 	}
556 }
557 
558 template<>
createMemory(ImagesList & targets,MemoryRegionsList & memory,Context & ctx,BindingCaseParameters params)559 void									createMemory<VkImage, DE_TRUE>		(ImagesList&			targets,
560 																			 MemoryRegionsList&		memory,
561 																			 Context&				ctx,
562 																			 BindingCaseParameters	params)
563 {
564 	DE_UNREF(params);
565 	const deUint32						count								= static_cast<deUint32>(targets.size());
566 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
567 	const VkDevice						vkDevice							= ctx.getDevice();
568 
569 	memory.reserve(count);
570 	for (deUint32 i = 0; i < count; ++i)
571 	{
572 		VkMemoryRequirements			memReqs;
573 		vk.getImageMemoryRequirements(vkDevice, **targets[i], &memReqs);
574 
575 		ConstDedicatedInfo				dedicatedAllocationInfo				= makeDedicatedAllocationInfo(**targets[i]);
576 		VkMemoryPriorityAllocateInfoEXT	priority							= makeMemoryPriorityAllocateInfo(&dedicatedAllocationInfo, ((float)i)/((float)count));
577 		const VkMemoryAllocateInfo		memAlloc							= makeMemoryAllocateInfo(memReqs, params.usePriority ? &priority : (const void *)&dedicatedAllocationInfo);
578 		VkDeviceMemory					rawMemory							= DE_NULL;
579 
580 		vk.allocateMemory(vkDevice, &memAlloc, static_cast<VkAllocationCallbacks*>(DE_NULL), &rawMemory);
581 		memory.push_back(MemoryRegionPtr(new Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL))));
582 	}
583 }
584 
585 template<typename TTarget>
586 void									makeBinding							(std::vector<de::SharedPtr<Move<TTarget> > >&
587 																									targets,
588 																			 MemoryRegionsList&		memory,
589 																			 Context&				ctx,
590 																			 BindingCaseParameters	params);
591 
592 template<>
makeBinding(BuffersList & targets,MemoryRegionsList & memory,Context & ctx,BindingCaseParameters params)593 void									makeBinding<VkBuffer>				(BuffersList&			targets,
594 																			 MemoryRegionsList&		memory,
595 																			 Context&				ctx,
596 																			 BindingCaseParameters	params)
597 {
598 	DE_UNREF(params);
599 	const deUint32						count								= static_cast<deUint32>(targets.size());
600 	const VkDevice						vkDevice							= ctx.getDevice();
601 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
602 	BindBufferMemoryInfosList			bindMemoryInfos;
603 
604 	for (deUint32 i = 0; i < count; ++i)
605 	{
606 		bindMemoryInfos.push_back(makeBufferMemoryBindingInfo(**targets[i], **memory[i]));
607 	}
608 
609 	VK_CHECK(vk.bindBufferMemory2(vkDevice, count, &bindMemoryInfos.front()));
610 }
611 
612 template<>
makeBinding(ImagesList & targets,MemoryRegionsList & memory,Context & ctx,BindingCaseParameters params)613 void									makeBinding<VkImage>				(ImagesList&			targets,
614 																			 MemoryRegionsList&		memory,
615 																			 Context&				ctx,
616 																			 BindingCaseParameters	params)
617 {
618 	DE_UNREF(params);
619 	const deUint32						count								= static_cast<deUint32>(targets.size());
620 	const VkDevice						vkDevice							= ctx.getDevice();
621 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
622 	BindImageMemoryInfosList			bindMemoryInfos;
623 
624 	for (deUint32 i = 0; i < count; ++i)
625 	{
626 		bindMemoryInfos.push_back(makeImageMemoryBindingInfo(**targets[i], **memory[i]));
627 	}
628 
629 	VK_CHECK(vk.bindImageMemory2(vkDevice, count, &bindMemoryInfos.front()));
630 }
631 
632 template <typename TTarget>
633 void									fillUpResource						(Move<VkBuffer>&		source,
634 																			 Move<TTarget>&			target,
635 																			 Context&				ctx,
636 																			 BindingCaseParameters	params);
637 
638 template <>
fillUpResource(Move<VkBuffer> & source,Move<VkBuffer> & target,Context & ctx,BindingCaseParameters params)639 void									fillUpResource<VkBuffer>			(Move<VkBuffer>&		source,
640 																			 Move<VkBuffer>&		target,
641 																			 Context&				ctx,
642 																			 BindingCaseParameters	params)
643 {
644 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
645 	const VkDevice						vkDevice							= ctx.getDevice();
646 	const VkQueue						queue								= ctx.getUniversalQueue();
647 
648 	const VkBufferMemoryBarrier			srcBufferBarrier					= makeMemoryBarrierInfo(*source, params.bufferSize, TransferFromResource);
649 	const VkBufferMemoryBarrier			dstBufferBarrier					= makeMemoryBarrierInfo(*target, params.bufferSize, TransferToResource);
650 
651 	Move<VkCommandPool>					commandPool							= createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, 0);
652 	Move<VkCommandBuffer>				cmdBuffer							= createCommandBuffer(vk, vkDevice, *commandPool);
653 	VkBufferCopy						bufferCopy							= { 0u, 0u, params.bufferSize };
654 
655 	beginCommandBuffer(vk, *cmdBuffer);
656 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &srcBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
657 	vk.cmdCopyBuffer(*cmdBuffer, *source, *target, 1, &bufferCopy);
658 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &dstBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
659 	endCommandBuffer(vk, *cmdBuffer);
660 
661 	submitCommandsAndWait(vk, vkDevice, queue, *cmdBuffer);
662 }
663 
664 template <>
fillUpResource(Move<VkBuffer> & source,Move<VkImage> & target,Context & ctx,BindingCaseParameters params)665 void									fillUpResource<VkImage>				(Move<VkBuffer>&		source,
666 																			 Move<VkImage>&			target,
667 																			 Context&				ctx,
668 																			 BindingCaseParameters	params)
669 {
670 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
671 	const VkDevice						vkDevice							= ctx.getDevice();
672 	const VkQueue						queue								= ctx.getUniversalQueue();
673 
674 	const VkBufferMemoryBarrier			srcBufferBarrier					= makeMemoryBarrierInfo(*source, params.bufferSize, TransferFromResource);
675 	const VkImageMemoryBarrier			preImageBarrier						= makeMemoryBarrierInfo(*target, 0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
676 	const VkImageMemoryBarrier			dstImageBarrier						= makeMemoryBarrierInfo(*target, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
677 
678 	Move<VkCommandPool>					commandPool							= createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, 0);
679 	Move<VkCommandBuffer>				cmdBuffer							= createCommandBuffer(vk, vkDevice, *commandPool);
680 
681 	const VkBufferImageCopy				copyRegion							=
682 	{
683 		0u,																	// VkDeviceSize			bufferOffset;
684 		params.imageSize.width,												// deUint32				bufferRowLength;
685 		params.imageSize.height,											// deUint32				bufferImageHeight;
686 		{
687 			VK_IMAGE_ASPECT_COLOR_BIT,										// VkImageAspectFlags	aspect;
688 			0u,																// deUint32				mipLevel;
689 			0u,																// deUint32				baseArrayLayer;
690 			1u,																// deUint32				layerCount;
691 		},																	// VkImageSubresourceLayers imageSubresource;
692 		{ 0, 0, 0 },														// VkOffset3D			imageOffset;
693 		params.imageSize													// VkExtent3D			imageExtent;
694 	};
695 
696 	beginCommandBuffer(vk, *cmdBuffer);
697 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &srcBufferBarrier, 1, &preImageBarrier);
698 	vk.cmdCopyBufferToImage(*cmdBuffer, *source, *target, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, (&copyRegion));
699 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &dstImageBarrier);
700 	endCommandBuffer(vk, *cmdBuffer);
701 
702 	submitCommandsAndWait(vk, vkDevice, queue, *cmdBuffer);
703 }
704 
705 template <typename TTarget>
706 void									readUpResource						(Move<TTarget>&			source,
707 																			 Move<VkBuffer>&		target,
708 																			 Context&				ctx,
709 																			 BindingCaseParameters	params);
710 
711 template <>
readUpResource(Move<VkBuffer> & source,Move<VkBuffer> & target,Context & ctx,BindingCaseParameters params)712 void									readUpResource						(Move<VkBuffer>&		source,
713 																			 Move<VkBuffer>&		target,
714 																			 Context&				ctx,
715 																			 BindingCaseParameters	params)
716 {
717 	fillUpResource(source, target, ctx, params);
718 }
719 
720 template <>
readUpResource(Move<VkImage> & source,Move<VkBuffer> & target,Context & ctx,BindingCaseParameters params)721 void									readUpResource						(Move<VkImage>&			source,
722 																			 Move<VkBuffer>&		target,
723 																			 Context&				ctx,
724 																			 BindingCaseParameters	params)
725 {
726 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
727 	const VkDevice						vkDevice							= ctx.getDevice();
728 	const VkQueue						queue								= ctx.getUniversalQueue();
729 
730 	Move<VkCommandPool>					commandPool							= createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, 0);
731 	Move<VkCommandBuffer>				cmdBuffer							= createCommandBuffer(vk, vkDevice, *commandPool);
732 
733 	beginCommandBuffer(vk, *cmdBuffer);
734 	copyImageToBuffer(vk, *cmdBuffer, *source, *target, tcu::IVec2(params.imageSize.width, params.imageSize.height), VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
735 	endCommandBuffer(vk, *cmdBuffer);
736 
737 	submitCommandsAndWait(vk, vkDevice, queue, *cmdBuffer);
738 }
739 
740 
741 template <typename TTarget>
742 void									layoutTransitionResource			(Move<TTarget>&			target,
743 																			 Context&				ctx);
744 
745 template <>
layoutTransitionResource(Move<VkBuffer> & target,Context & ctx)746 void									layoutTransitionResource			(Move<VkBuffer>&		target,
747 																			 Context&				ctx)
748 {
749 	DE_UNREF(target);
750 	DE_UNREF(ctx);
751 }
752 
753 template <>
layoutTransitionResource(Move<VkImage> & target,Context & ctx)754 void									layoutTransitionResource<VkImage>	(Move<VkImage>&			target,
755 																			 Context&				ctx)
756 {
757 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
758 	const VkDevice						vkDevice							= ctx.getDevice();
759 	const VkQueue						queue								= ctx.getUniversalQueue();
760 
761 	const VkImageMemoryBarrier			preImageBarrier						= makeMemoryBarrierInfo(*target, 0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
762 
763 	Move<VkCommandPool>					commandPool							= createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, 0);
764 	Move<VkCommandBuffer>				cmdBuffer							= createCommandBuffer(vk, vkDevice, *commandPool);
765 
766 	beginCommandBuffer(vk, *cmdBuffer);
767 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &preImageBarrier);
768 	endCommandBuffer(vk, *cmdBuffer);
769 
770 	submitCommandsAndWait(vk, vkDevice, queue, *cmdBuffer);
771 }
772 
773 
createBuffer(Move<VkBuffer> & buffer,Move<VkDeviceMemory> & memory,Context & ctx,BindingCaseParameters params)774 void									createBuffer						(Move<VkBuffer>&		buffer,
775 																			 Move<VkDeviceMemory>&	memory,
776 																			 Context&				ctx,
777 																			 BindingCaseParameters	params)
778 {
779 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
780 	const VkDevice						vkDevice							= ctx.getDevice();
781 	VkBufferCreateInfo					bufferParams						= makeBufferCreateInfo(ctx, params);
782 	VkMemoryRequirements				memReqs;
783 
784 	buffer = createBuffer(vk, vkDevice, &bufferParams);
785 	vk.getBufferMemoryRequirements(vkDevice, *buffer, &memReqs);
786 
787 	const VkMemoryAllocateInfo			memAlloc							= makeMemoryAllocateInfo(ctx, memReqs, MemoryHostVisible);
788 	VkDeviceMemory						rawMemory							= DE_NULL;
789 
790 	vk.allocateMemory(vkDevice, &memAlloc, static_cast<VkAllocationCallbacks*>(DE_NULL), &rawMemory);
791 	memory = Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL));
792 	VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, *memory, 0u));
793 }
794 
pushData(VkDeviceMemory memory,deUint32 dataSeed,Context & ctx,BindingCaseParameters params)795 void									pushData							(VkDeviceMemory			memory,
796 																			 deUint32				dataSeed,
797 																			 Context&				ctx,
798 																			 BindingCaseParameters	params)
799 {
800 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
801 	const VkDevice						vkDevice							= ctx.getDevice();
802 	MemoryMappingRAII					hostMemory							(vk, vkDevice, memory, 0u, params.bufferSize, 0u);
803 	deUint8*							hostBuffer							= static_cast<deUint8*>(hostMemory.ptr());
804 	SimpleRandomGenerator				random								(dataSeed);
805 
806 	for (deUint32 i = 0u; i < params.bufferSize; ++i)
807 	{
808 		hostBuffer[i] = static_cast<deUint8>(random.getNext() & 0xFFu);
809 	}
810 	hostMemory.flush();
811 }
812 
checkData(VkDeviceMemory memory,deUint32 dataSeed,Context & ctx,BindingCaseParameters params)813 deBool									checkData							(VkDeviceMemory			memory,
814 																			 deUint32				dataSeed,
815 																			 Context&				ctx,
816 																			 BindingCaseParameters	params)
817 {
818 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
819 	const VkDevice						vkDevice							= ctx.getDevice();
820 	MemoryMappingRAII					hostMemory							(vk, vkDevice, memory, 0u, params.bufferSize, 0u);
821 	deUint8*							hostBuffer							= static_cast<deUint8*>(hostMemory.ptr());
822 	SimpleRandomGenerator				random								(dataSeed);
823 
824 	hostMemory.invalidate();
825 
826 	for (deUint32 i = 0u; i < params.bufferSize; ++i)
827 	{
828 		if (hostBuffer[i] != static_cast<deUint8>(random.getNext() & 0xFFu) )
829 			return DE_FALSE;
830 	}
831 	return DE_TRUE;
832 }
833 
834 template<typename TTarget, deBool TDedicated>
835 class MemoryBindingInstance : public TestInstance
836 {
837 public:
MemoryBindingInstance(Context & ctx,BindingCaseParameters params)838 										MemoryBindingInstance				(Context&				ctx,
839 																			 BindingCaseParameters	params)
840 										: TestInstance						(ctx)
841 										, m_params							(params)
842 	{
843 	}
844 
iterate(void)845 	virtual tcu::TestStatus				iterate								(void)
846 	{
847 		std::vector<de::SharedPtr<Move<TTarget> > >
848 										targets;
849 		MemoryRegionsList				memory;
850 
851 		createBindingTargets<TTarget>(targets, m_context, m_params);
852 		createMemory<TTarget, TDedicated>(targets, memory, m_context, m_params);
853 		makeBinding<TTarget>(targets, memory, m_context, m_params);
854 
855 		Move<VkBuffer>					srcBuffer;
856 		Move<VkDeviceMemory>			srcMemory;
857 
858 		createBuffer(srcBuffer, srcMemory, m_context, m_params);
859 		pushData(*srcMemory, 1, m_context, m_params);
860 
861 		Move<VkBuffer>					dstBuffer;
862 		Move<VkDeviceMemory>			dstMemory;
863 
864 		createBuffer(dstBuffer, dstMemory, m_context, m_params);
865 
866 		deBool							passed								= DE_TRUE;
867 		for (deUint32 i = 0; passed && i < m_params.targetsCount; ++i)
868 		{
869 			fillUpResource(srcBuffer, *targets[i], m_context, m_params);
870 			readUpResource(*targets[i], dstBuffer, m_context, m_params);
871 			passed = checkData(*dstMemory, 1, m_context, m_params);
872 		}
873 
874 		return passed ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Failed");
875 	}
876 private:
877 	BindingCaseParameters				m_params;
878 };
879 
880 template<typename TTarget, deBool TDedicated>
881 class AliasedMemoryBindingInstance : public TestInstance
882 {
883 public:
AliasedMemoryBindingInstance(Context & ctx,BindingCaseParameters params)884 										AliasedMemoryBindingInstance		(Context&				ctx,
885 																			 BindingCaseParameters	params)
886 										: TestInstance						(ctx)
887 										, m_params							(params)
888 	{
889 	}
890 
iterate(void)891 	virtual tcu::TestStatus				iterate								(void)
892 	{
893 		std::vector<de::SharedPtr<Move<TTarget> > >
894 										targets[2];
895 		MemoryRegionsList				memory;
896 
897 		for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(targets); ++i)
898 			createBindingTargets<TTarget>(targets[i], m_context, m_params);
899 		createMemory<TTarget, TDedicated>(targets[0], memory, m_context, m_params);
900 		for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(targets); ++i)
901 			makeBinding<TTarget>(targets[i], memory, m_context, m_params);
902 
903 		Move<VkBuffer>					srcBuffer;
904 		Move<VkDeviceMemory>			srcMemory;
905 
906 		createBuffer(srcBuffer, srcMemory, m_context, m_params);
907 		pushData(*srcMemory, 2, m_context, m_params);
908 
909 		Move<VkBuffer>					dstBuffer;
910 		Move<VkDeviceMemory>			dstMemory;
911 
912 		createBuffer(dstBuffer, dstMemory, m_context, m_params);
913 
914 		deBool							passed								= DE_TRUE;
915 		for (deUint32 i = 0; passed && i < m_params.targetsCount; ++i)
916 		{
917 			// Do a layout transition on alias 1 before we transition and write to alias 0
918 			layoutTransitionResource(*(targets[1][i]), m_context);
919 			fillUpResource(srcBuffer, *(targets[0][i]), m_context, m_params);
920 			readUpResource(*(targets[1][i]), dstBuffer, m_context, m_params);
921 			passed = checkData(*dstMemory, 2, m_context, m_params);
922 		}
923 
924 		return passed ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Failed");
925 	}
926 private:
927 	BindingCaseParameters				m_params;
928 };
929 
930 template<typename TInstance>
931 class MemoryBindingTest : public TestCase
932 {
933 public:
MemoryBindingTest(tcu::TestContext & testCtx,const std::string & name,const std::string & description,BindingCaseParameters params)934 										MemoryBindingTest					(tcu::TestContext&		testCtx,
935 																			 const std::string&		name,
936 																			 const std::string&		description,
937 																			 BindingCaseParameters	params)
938 										: TestCase							(testCtx, name, description)
939 										, m_params							(params)
940 	{
941 	}
942 
~MemoryBindingTest(void)943 	virtual								~MemoryBindingTest					(void)
944 	{
945 	}
946 
createInstance(Context & ctx) const947 	virtual TestInstance*				createInstance						(Context&				ctx) const
948 	{
949 		return new TInstance(ctx, m_params);
950 	}
951 
checkSupport(Context & ctx) const952 	virtual void						checkSupport						(Context&				ctx) const
953 	{
954 		ctx.requireDeviceFunctionality("VK_KHR_bind_memory2");
955 
956 		if (m_params.usePriority && !ctx.getMemoryPriorityFeaturesEXT().memoryPriority)
957 			TCU_THROW(NotSupportedError, "VK_EXT_memory_priority Not supported");
958 	}
959 
960 private:
961 	BindingCaseParameters				m_params;
962 };
963 
964 } // unnamed namespace
965 
createMemoryBindingTests(tcu::TestContext & testCtx)966 tcu::TestCaseGroup* createMemoryBindingTests (tcu::TestContext& testCtx)
967 {
968 	de::MovePtr<tcu::TestCaseGroup>		group								(new tcu::TestCaseGroup(testCtx, "binding", "Memory binding tests."));
969 
970 	for (int i = 0; i < 2; ++i)
971 	{
972 		bool usePriority = i != 0;
973 		de::MovePtr<tcu::TestCaseGroup>		regular								(new tcu::TestCaseGroup(testCtx, "regular", "Basic memory binding tests."));
974 		de::MovePtr<tcu::TestCaseGroup>		aliasing							(new tcu::TestCaseGroup(testCtx, "aliasing", "Memory binding tests with aliasing of two resources."));
975 
976 		de::MovePtr<tcu::TestCaseGroup>		regular_suballocated				(new tcu::TestCaseGroup(testCtx, "suballocated", "Basic memory binding tests with suballocated memory."));
977 		de::MovePtr<tcu::TestCaseGroup>		regular_dedicated					(new tcu::TestCaseGroup(testCtx, "dedicated", "Basic memory binding tests with deditatedly allocated memory."));
978 
979 		de::MovePtr<tcu::TestCaseGroup>		aliasing_suballocated				(new tcu::TestCaseGroup(testCtx, "suballocated", "Memory binding tests with aliasing of two resources with suballocated mamory."));
980 
981 		const VkDeviceSize					allocationSizes[]					= {	33, 257, 4087, 8095, 1*1024*1024 + 1	};
982 
983 		for (deUint32 sizeNdx = 0u; sizeNdx < DE_LENGTH_OF_ARRAY(allocationSizes); ++sizeNdx )
984 		{
985 			const VkDeviceSize				bufferSize							= allocationSizes[sizeNdx];
986 			const BindingCaseParameters		params								= makeBindingCaseParameters(10, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, bufferSize, 0u, usePriority);
987 			const BindingCaseParameters		aliasparams							= makeBindingCaseParameters(10, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, bufferSize, VK_IMAGE_CREATE_ALIAS_BIT, usePriority);
988 			std::ostringstream				testName;
989 
990 			testName << "buffer_" << bufferSize;
991 			regular_suballocated->addChild(new MemoryBindingTest<MemoryBindingInstance<VkBuffer, DE_FALSE> >(testCtx, testName.str(), " ", params));
992 			regular_dedicated->addChild(new MemoryBindingTest<MemoryBindingInstance<VkBuffer, DE_TRUE> >(testCtx, testName.str(), " ", params));
993 			aliasing_suballocated->addChild(new MemoryBindingTest<AliasedMemoryBindingInstance<VkBuffer, DE_FALSE> >(testCtx, testName.str(), " ", aliasparams));
994 		}
995 
996 		const deUint32						imageSizes[]						= {	8, 33, 257	};
997 
998 		for (deUint32 widthNdx = 0u; widthNdx < DE_LENGTH_OF_ARRAY(imageSizes); ++widthNdx )
999 		for (deUint32 heightNdx = 0u; heightNdx < DE_LENGTH_OF_ARRAY(imageSizes); ++heightNdx )
1000 		{
1001 			const deUint32					width								= imageSizes[widthNdx];
1002 			const deUint32					height								= imageSizes[heightNdx];
1003 			const BindingCaseParameters		regularparams						= makeBindingCaseParameters(10, width, height, 0u, usePriority);
1004 			const BindingCaseParameters		aliasparams							= makeBindingCaseParameters(10, width, height, VK_IMAGE_CREATE_ALIAS_BIT, usePriority);
1005 			std::ostringstream				testName;
1006 
1007 			testName << "image_" << width << '_' << height;
1008 			regular_suballocated->addChild(new MemoryBindingTest<MemoryBindingInstance<VkImage, DE_FALSE> >(testCtx, testName.str(), " ", regularparams));
1009 			regular_dedicated->addChild(new MemoryBindingTest<MemoryBindingInstance<VkImage, DE_TRUE> >(testCtx, testName.str(), "", regularparams));
1010 			aliasing_suballocated->addChild(new MemoryBindingTest<AliasedMemoryBindingInstance<VkImage, DE_FALSE> >(testCtx, testName.str(), " ", aliasparams));
1011 		}
1012 
1013 		regular->addChild(regular_suballocated.release());
1014 		regular->addChild(regular_dedicated.release());
1015 
1016 		aliasing->addChild(aliasing_suballocated.release());
1017 		if (usePriority) {
1018 			de::MovePtr<tcu::TestCaseGroup>		priority	(new tcu::TestCaseGroup(testCtx, "priority", "Using VK_EXT_memory_priority."));
1019 			priority->addChild(regular.release());
1020 			priority->addChild(aliasing.release());
1021 			group->addChild(priority.release());
1022 		} else {
1023 			group->addChild(regular.release());
1024 			group->addChild(aliasing.release());
1025 		}
1026 	}
1027 
1028 	return group.release();
1029 }
1030 
1031 } // memory
1032 } // vkt
1033