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 };
153 
makeBindingCaseParameters(deUint32 targetsCount,deUint32 width,deUint32 height,VkImageCreateFlags imageCreateFlags)154 BindingCaseParameters					makeBindingCaseParameters			(deUint32				targetsCount,
155 																			 deUint32				width,
156 																			 deUint32				height,
157 																			 VkImageCreateFlags		imageCreateFlags)
158 {
159 	BindingCaseParameters				params;
160 	deMemset(&params, 0, sizeof(BindingCaseParameters));
161 	params.imageSize.width = width;
162 	params.imageSize.height = height;
163 	params.imageSize.depth = 1;
164 	params.bufferSize = params.imageSize.width * params.imageSize.height * params.imageSize.depth * sizeof(deUint32);
165 	params.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
166 	params.targetsCount = targetsCount;
167 	params.imageCreateFlags = imageCreateFlags;
168 	return params;
169 }
170 
makeBindingCaseParameters(deUint32 targetsCount,VkBufferUsageFlags usage,VkSharingMode sharing,VkDeviceSize bufferSize,VkImageCreateFlags imageCreateFlags)171 BindingCaseParameters					makeBindingCaseParameters			(deUint32				targetsCount,
172 																			 VkBufferUsageFlags		usage,
173 																			 VkSharingMode			sharing,
174 																			 VkDeviceSize			bufferSize,
175 																			 VkImageCreateFlags		imageCreateFlags)
176 {
177 	BindingCaseParameters				params								=
178 	{
179 		0,																	// VkBufferCreateFlags	flags;
180 		usage,																// VkBufferUsageFlags	usage;
181 		sharing,															// VkSharingMode		sharing;
182 		bufferSize,															// VkDeviceSize			bufferSize;
183 		{0u, 0u, 0u},														// VkExtent3D			imageSize;
184 		targetsCount,														// deUint32				targetsCount;
185 		imageCreateFlags,													// VkImageCreateFlags	imageCreateFlags
186 	};
187 	return params;
188 }
189 
makeImageCreateInfo(BindingCaseParameters & params)190 VkImageCreateInfo						makeImageCreateInfo					(BindingCaseParameters&	params)
191 {
192 	const VkImageCreateInfo				imageParams							=
193 	{
194 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,								// VkStructureType		sType;
195 		DE_NULL,															// const void*			pNext;
196 		params.imageCreateFlags,											// VkImageCreateFlags	flags;
197 		VK_IMAGE_TYPE_2D,													// VkImageType			imageType;
198 		VK_FORMAT_R8G8B8A8_UINT,											// VkFormat				format;
199 		params.imageSize,													// VkExtent3D			extent;
200 		1u,																	// deUint32				mipLevels;
201 		1u,																	// deUint32				arrayLayers;
202 		VK_SAMPLE_COUNT_1_BIT,												// VkSampleCountFlagBits samples;
203 		VK_IMAGE_TILING_LINEAR,												// VkImageTiling		tiling;
204 		VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
205 		VK_SHARING_MODE_EXCLUSIVE,											// VkSharingMode		sharingMode;
206 		0u,																	// deUint32				queueFamilyIndexCount;
207 		DE_NULL,															// const deUint32*		pQueueFamilyIndices;
208 		VK_IMAGE_LAYOUT_UNDEFINED,											// VkImageLayout		initialLayout;
209 	};
210 	return imageParams;
211 }
212 
makeBufferCreateInfo(Context & ctx,BindingCaseParameters & params)213 VkBufferCreateInfo						makeBufferCreateInfo				(Context&				ctx,
214 																			 BindingCaseParameters&	params)
215 {
216 	const deUint32						queueFamilyIndex					= ctx.getUniversalQueueFamilyIndex();
217 	VkBufferCreateInfo					bufferParams						=
218 	{
219 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,								// VkStructureType		sType;
220 		DE_NULL,															// const void*			pNext;
221 		params.flags,														// VkBufferCreateFlags	flags;
222 		params.bufferSize,													// VkDeviceSize			size;
223 		params.usage,														// VkBufferUsageFlags	usage;
224 		params.sharing,														// VkSharingMode		sharingMode;
225 		1u,																	// uint32_t				queueFamilyIndexCount;
226 		&queueFamilyIndex,													// const uint32_t*		pQueueFamilyIndices;
227 	};
228 	return bufferParams;
229 }
230 
makeMemoryAllocateInfo(VkMemoryRequirements & memReqs,ConstDedicatedInfo * next)231 const VkMemoryAllocateInfo				makeMemoryAllocateInfo				(VkMemoryRequirements&	memReqs,
232 																			 ConstDedicatedInfo*	next)
233 {
234 	const deUint32						heapTypeIndex						= (deUint32)deCtz32(memReqs.memoryTypeBits);
235 	const VkMemoryAllocateInfo			allocateParams						=
236 	{
237 		VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,								// VkStructureType		sType;
238 		next,																// const void*			pNext;
239 		memReqs.size,														// VkDeviceSize			allocationSize;
240 		heapTypeIndex,														// uint32_t				memoryTypeIndex;
241 	};
242 	return allocateParams;
243 }
244 
245 enum MemoryHostVisibility
246 {
247 	MemoryAny,
248 	MemoryHostVisible
249 };
250 
selectMatchingMemoryType(Context & ctx,VkMemoryRequirements & memReqs,MemoryHostVisibility memoryVisibility)251 deUint32								selectMatchingMemoryType			(Context&				ctx,
252 																			 VkMemoryRequirements&	memReqs,
253 																			 MemoryHostVisibility	memoryVisibility)
254 {
255 	const VkPhysicalDevice				vkPhysicalDevice					= ctx.getPhysicalDevice();
256 	const InstanceInterface&			vkInstance							= ctx.getInstanceInterface();
257 	VkPhysicalDeviceMemoryProperties	memoryProperties;
258 
259 	vkInstance.getPhysicalDeviceMemoryProperties(vkPhysicalDevice, &memoryProperties);
260 	if (memoryVisibility == MemoryHostVisible)
261 	{
262 		for (deUint32 typeNdx = 0; typeNdx < memoryProperties.memoryTypeCount; ++typeNdx)
263 		{
264 			const deBool				isInAllowed							= (memReqs.memoryTypeBits & (1u << typeNdx)) != 0u;
265 			const deBool				hasRightProperties					= (memoryProperties.memoryTypes[typeNdx].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0u;
266 			if (isInAllowed && hasRightProperties)
267 				return typeNdx;
268 		}
269 	}
270 	return (deUint32)deCtz32(memReqs.memoryTypeBits);
271 }
272 
makeMemoryAllocateInfo(Context & ctx,VkMemoryRequirements & memReqs,MemoryHostVisibility memoryVisibility)273 const VkMemoryAllocateInfo				makeMemoryAllocateInfo				(Context&				ctx,
274 																			 VkMemoryRequirements&	memReqs,
275 																			 MemoryHostVisibility	memoryVisibility)
276 {
277 	const deUint32						heapTypeIndex						= selectMatchingMemoryType(ctx, memReqs, memoryVisibility);
278 	const VkMemoryAllocateInfo			allocateParams						=
279 	{
280 		VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,								// VkStructureType		sType;
281 		DE_NULL,															// const void*			pNext;
282 		memReqs.size,														// VkDeviceSize			allocationSize;
283 		heapTypeIndex,														// uint32_t				memoryTypeIndex;
284 	};
285 	return allocateParams;
286 }
287 
makeDedicatedAllocationInfo(VkBuffer buffer)288 ConstDedicatedInfo						makeDedicatedAllocationInfo			(VkBuffer				buffer)
289 {
290 	ConstDedicatedInfo					dedicatedAllocationInfo				=
291 	{
292 		VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,				// VkStructureType		sType
293 		DE_NULL,															// const void*			pNext
294 		DE_NULL,															// VkImage				image
295 		buffer																// VkBuffer				buffer
296 	};
297 	return dedicatedAllocationInfo;
298 }
299 
makeDedicatedAllocationInfo(VkImage image)300 ConstDedicatedInfo						makeDedicatedAllocationInfo			(VkImage				image)
301 {
302 	ConstDedicatedInfo					dedicatedAllocationInfo				=
303 	{
304 		VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,				// VkStructureType		sType
305 		DE_NULL,															// const void*			pNext
306 		image,																// VkImage				image
307 		DE_NULL																// VkBuffer				buffer
308 	};
309 	return dedicatedAllocationInfo;
310 }
311 
makeBufferMemoryBindingInfo(VkBuffer buffer,VkDeviceMemory memory)312 const VkBindBufferMemoryInfo			makeBufferMemoryBindingInfo			(VkBuffer				buffer,
313 																			 VkDeviceMemory			memory)
314 {
315 	const VkBindBufferMemoryInfo		bufferMemoryBinding					=
316 	{
317 		VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHR,						// VkStructureType		sType;
318 		DE_NULL,															// const void*			pNext;
319 		buffer,																// VkBuffer				buffer;
320 		memory,																// VkDeviceMemory		memory;
321 		0u,																	// VkDeviceSize			memoryOffset;
322 	};
323 	return bufferMemoryBinding;
324 }
325 
makeImageMemoryBindingInfo(VkImage image,VkDeviceMemory memory)326 const VkBindImageMemoryInfo				makeImageMemoryBindingInfo			(VkImage				image,
327 																			 VkDeviceMemory			memory)
328 {
329 	const VkBindImageMemoryInfo		imageMemoryBinding					=
330 	{
331 		VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR,						// VkStructureType		sType;
332 		DE_NULL,															// const void*			pNext;
333 		image,																// VkImage				image;
334 		memory,																// VkDeviceMemory		memory;
335 		0u,																	// VkDeviceSize			memoryOffset;
336 	};
337 	return imageMemoryBinding;
338 }
339 
340 enum TransferDirection
341 {
342 	TransferToResource														= 0,
343 	TransferFromResource													= 1
344 };
345 
makeMemoryBarrierInfo(VkBuffer buffer,VkDeviceSize size,TransferDirection direction)346 const VkBufferMemoryBarrier				makeMemoryBarrierInfo				(VkBuffer				buffer,
347 																			 VkDeviceSize			size,
348 																			 TransferDirection		direction)
349 {
350 	const deBool fromRes													= direction == TransferFromResource;
351 	const VkAccessFlags					srcMask								= static_cast<VkAccessFlags>(fromRes ? VK_ACCESS_HOST_WRITE_BIT : VK_ACCESS_TRANSFER_WRITE_BIT);
352 	const VkAccessFlags					dstMask								= static_cast<VkAccessFlags>(fromRes ? VK_ACCESS_TRANSFER_READ_BIT : VK_ACCESS_HOST_READ_BIT);
353 	const VkBufferMemoryBarrier			bufferBarrier						=
354 	{
355 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,							// VkStructureType		sType;
356 		DE_NULL,															// const void*			pNext;
357 		srcMask,															// VkAccessFlags		srcAccessMask;
358 		dstMask,															// VkAccessFlags		dstAccessMask;
359 		VK_QUEUE_FAMILY_IGNORED,											// deUint32				srcQueueFamilyIndex;
360 		VK_QUEUE_FAMILY_IGNORED,											// deUint32				dstQueueFamilyIndex;
361 		buffer,																// VkBuffer				buffer;
362 		0u,																	// VkDeviceSize			offset;
363 		size																// VkDeviceSize			size;
364 	};
365 	return bufferBarrier;
366 }
367 
makeMemoryBarrierInfo(VkImage image,VkAccessFlags srcAccess,VkAccessFlags dstAccess,VkImageLayout oldLayout,VkImageLayout newLayout)368 const VkImageMemoryBarrier				makeMemoryBarrierInfo				(VkImage				image,
369 																			 VkAccessFlags			srcAccess,
370 																			 VkAccessFlags			dstAccess,
371 																			 VkImageLayout			oldLayout,
372 																			 VkImageLayout			newLayout)
373 {
374 	const VkImageAspectFlags			aspect								= VK_IMAGE_ASPECT_COLOR_BIT;
375 	const VkImageMemoryBarrier			imageBarrier						=
376 	{
377 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,								// VkStructureType		sType;
378 		DE_NULL,															// const void*			pNext;
379 		srcAccess,															// VkAccessFlags		srcAccessMask;
380 		dstAccess,															// VkAccessFlags		dstAccessMask;
381 		oldLayout,															// VkImageLayout		oldLayout;
382 		newLayout,															// VkImageLayout		newLayout;
383 		VK_QUEUE_FAMILY_IGNORED,											// deUint32				srcQueueFamilyIndex;
384 		VK_QUEUE_FAMILY_IGNORED,											// deUint32				dstQueueFamilyIndex;
385 		image,																// VkImage				image;
386 		{																	// VkImageSubresourceRange subresourceRange;
387 			aspect,															// VkImageAspectFlags	aspect;
388 			0u,																// deUint32				baseMipLevel;
389 			1u,																// deUint32				mipLevels;
390 			0u,																// deUint32				baseArraySlice;
391 			1u,																// deUint32				arraySize;
392 		}
393 	};
394 	return imageBarrier;
395 }
396 
createCommandBuffer(const DeviceInterface & vk,VkDevice device,VkCommandPool commandPool)397 Move<VkCommandBuffer>					createCommandBuffer					(const DeviceInterface&	vk,
398 																			 VkDevice				device,
399 																			 VkCommandPool			commandPool)
400 {
401 	const VkCommandBufferAllocateInfo allocInfo =
402 	{
403 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
404 		DE_NULL,
405 		commandPool,
406 		VK_COMMAND_BUFFER_LEVEL_PRIMARY,
407 		1
408 	};
409 	return allocateCommandBuffer(vk, device, &allocInfo);
410 }
411 
412 
413 template<typename TTarget>
414 void									createBindingTargets				(std::vector<de::SharedPtr<Move<TTarget> > >&
415 																									targets,
416 																			 Context&				ctx,
417 																			 BindingCaseParameters	params);
418 
419 template<>
createBindingTargets(BuffersList & targets,Context & ctx,BindingCaseParameters params)420 void									createBindingTargets<VkBuffer>		(BuffersList&			targets,
421 																			 Context&				ctx,
422 																			 BindingCaseParameters	params)
423 {
424 	const deUint32						count								= params.targetsCount;
425 	const VkDevice						vkDevice							= ctx.getDevice();
426 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
427 
428 	targets.reserve(count);
429 	for (deUint32 i = 0u; i < count; ++i)
430 	{
431 		VkBufferCreateInfo				bufferParams						= makeBufferCreateInfo(ctx, params);
432 		targets.push_back(BufferPtr(new Move<VkBuffer>(createBuffer(vk, vkDevice, &bufferParams))));
433 	}
434 }
435 
436 template<>
createBindingTargets(ImagesList & targets,Context & ctx,BindingCaseParameters params)437 void									createBindingTargets<VkImage>		(ImagesList&			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 		VkImageCreateInfo				imageParams							= makeImageCreateInfo(params);
449 		targets.push_back(ImagePtr(new Move<VkImage>(createImage(vk, vkDevice, &imageParams))));
450 	}
451 }
452 
453 template<typename TTarget, deBool TDedicated>
454 void									createMemory						(std::vector<de::SharedPtr<Move<TTarget> > >&
455 																									targets,
456 																			 MemoryRegionsList&		memory,
457 																			 Context&				ctx,
458 																			 BindingCaseParameters	params);
459 
460 template<>
createMemory(BuffersList & targets,MemoryRegionsList & memory,Context & ctx,BindingCaseParameters params)461 void									createMemory<VkBuffer, DE_FALSE>	(BuffersList&			targets,
462 																			 MemoryRegionsList&		memory,
463 																			 Context&				ctx,
464 																			 BindingCaseParameters	params)
465 {
466 	DE_UNREF(params);
467 	const deUint32						count								= static_cast<deUint32>(targets.size());
468 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
469 	const VkDevice						vkDevice							= ctx.getDevice();
470 
471 	memory.reserve(count);
472 	for (deUint32 i = 0; i < count; ++i)
473 	{
474 		VkMemoryRequirements			memReqs;
475 
476 		vk.getBufferMemoryRequirements(vkDevice, **targets[i], &memReqs);
477 
478 		const VkMemoryAllocateInfo		memAlloc							= makeMemoryAllocateInfo(memReqs, DE_NULL);
479 		VkDeviceMemory					rawMemory							= DE_NULL;
480 
481 		vk.allocateMemory(vkDevice, &memAlloc, (VkAllocationCallbacks*)DE_NULL, &rawMemory);
482 		memory.push_back(MemoryRegionPtr(new Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL))));
483 	}
484 }
485 
486 template<>
createMemory(ImagesList & targets,MemoryRegionsList & memory,Context & ctx,BindingCaseParameters params)487 void									createMemory<VkImage, DE_FALSE>		(ImagesList&			targets,
488 																			 MemoryRegionsList&		memory,
489 																			 Context&				ctx,
490 																			 BindingCaseParameters	params)
491 {
492 	DE_UNREF(params);
493 	const deUint32						count								= static_cast<deUint32>(targets.size());
494 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
495 	const VkDevice						vkDevice							= ctx.getDevice();
496 
497 	memory.reserve(count);
498 	for (deUint32 i = 0; i < count; ++i)
499 	{
500 		VkMemoryRequirements			memReqs;
501 		vk.getImageMemoryRequirements(vkDevice, **targets[i], &memReqs);
502 
503 		const VkMemoryAllocateInfo		memAlloc							= makeMemoryAllocateInfo(memReqs, DE_NULL);
504 		VkDeviceMemory					rawMemory							= DE_NULL;
505 
506 		vk.allocateMemory(vkDevice, &memAlloc, (VkAllocationCallbacks*)DE_NULL, &rawMemory);
507 		memory.push_back(de::SharedPtr<Move<VkDeviceMemory> >(new Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL))));
508 	}
509 }
510 
511 template<>
createMemory(BuffersList & targets,MemoryRegionsList & memory,Context & ctx,BindingCaseParameters params)512 void									createMemory<VkBuffer, DE_TRUE>		(BuffersList&			targets,
513 																			 MemoryRegionsList&		memory,
514 																			 Context&				ctx,
515 																			 BindingCaseParameters	params)
516 {
517 	DE_UNREF(params);
518 	const deUint32						count								= static_cast<deUint32>(targets.size());
519 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
520 	const VkDevice						vkDevice							= ctx.getDevice();
521 
522 	memory.reserve(count);
523 	for (deUint32 i = 0; i < count; ++i)
524 	{
525 		VkMemoryRequirements			memReqs;
526 
527 		vk.getBufferMemoryRequirements(vkDevice, **targets[i], &memReqs);
528 
529 		ConstDedicatedInfo				dedicatedAllocationInfo				= makeDedicatedAllocationInfo(**targets[i]);;
530 		const VkMemoryAllocateInfo		memAlloc							= makeMemoryAllocateInfo(memReqs, &dedicatedAllocationInfo);
531 		VkDeviceMemory					rawMemory							= DE_NULL;
532 
533 		vk.allocateMemory(vkDevice, &memAlloc, static_cast<VkAllocationCallbacks*>(DE_NULL), &rawMemory);
534 		memory.push_back(MemoryRegionPtr(new Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL))));
535 	}
536 }
537 
538 template<>
createMemory(ImagesList & targets,MemoryRegionsList & memory,Context & ctx,BindingCaseParameters params)539 void									createMemory<VkImage, DE_TRUE>		(ImagesList&			targets,
540 																			 MemoryRegionsList&		memory,
541 																			 Context&				ctx,
542 																			 BindingCaseParameters	params)
543 {
544 	DE_UNREF(params);
545 	const deUint32						count								= static_cast<deUint32>(targets.size());
546 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
547 	const VkDevice						vkDevice							= ctx.getDevice();
548 
549 	memory.reserve(count);
550 	for (deUint32 i = 0; i < count; ++i)
551 	{
552 		VkMemoryRequirements			memReqs;
553 		vk.getImageMemoryRequirements(vkDevice, **targets[i], &memReqs);
554 
555 		ConstDedicatedInfo				dedicatedAllocationInfo				= makeDedicatedAllocationInfo(**targets[i]);
556 		const VkMemoryAllocateInfo		memAlloc							= makeMemoryAllocateInfo(memReqs, &dedicatedAllocationInfo);
557 		VkDeviceMemory					rawMemory							= DE_NULL;
558 
559 		vk.allocateMemory(vkDevice, &memAlloc, static_cast<VkAllocationCallbacks*>(DE_NULL), &rawMemory);
560 		memory.push_back(MemoryRegionPtr(new Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL))));
561 	}
562 }
563 
564 template<typename TTarget>
565 void									makeBinding							(std::vector<de::SharedPtr<Move<TTarget> > >&
566 																									targets,
567 																			 MemoryRegionsList&		memory,
568 																			 Context&				ctx,
569 																			 BindingCaseParameters	params);
570 
571 template<>
makeBinding(BuffersList & targets,MemoryRegionsList & memory,Context & ctx,BindingCaseParameters params)572 void									makeBinding<VkBuffer>				(BuffersList&			targets,
573 																			 MemoryRegionsList&		memory,
574 																			 Context&				ctx,
575 																			 BindingCaseParameters	params)
576 {
577 	DE_UNREF(params);
578 	const deUint32						count								= static_cast<deUint32>(targets.size());
579 	const VkDevice						vkDevice							= ctx.getDevice();
580 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
581 	BindBufferMemoryInfosList			bindMemoryInfos;
582 
583 	for (deUint32 i = 0; i < count; ++i)
584 	{
585 		bindMemoryInfos.push_back(makeBufferMemoryBindingInfo(**targets[i], **memory[i]));
586 	}
587 
588 	VK_CHECK(vk.bindBufferMemory2(vkDevice, count, &bindMemoryInfos.front()));
589 }
590 
591 template<>
makeBinding(ImagesList & targets,MemoryRegionsList & memory,Context & ctx,BindingCaseParameters params)592 void									makeBinding<VkImage>				(ImagesList&			targets,
593 																			 MemoryRegionsList&		memory,
594 																			 Context&				ctx,
595 																			 BindingCaseParameters	params)
596 {
597 	DE_UNREF(params);
598 	const deUint32						count								= static_cast<deUint32>(targets.size());
599 	const VkDevice						vkDevice							= ctx.getDevice();
600 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
601 	BindImageMemoryInfosList			bindMemoryInfos;
602 
603 	for (deUint32 i = 0; i < count; ++i)
604 	{
605 		bindMemoryInfos.push_back(makeImageMemoryBindingInfo(**targets[i], **memory[i]));
606 	}
607 
608 	VK_CHECK(vk.bindImageMemory2(vkDevice, count, &bindMemoryInfos.front()));
609 }
610 
611 template <typename TTarget>
612 void									fillUpResource						(Move<VkBuffer>&		source,
613 																			 Move<TTarget>&			target,
614 																			 Context&				ctx,
615 																			 BindingCaseParameters	params);
616 
617 template <>
fillUpResource(Move<VkBuffer> & source,Move<VkBuffer> & target,Context & ctx,BindingCaseParameters params)618 void									fillUpResource<VkBuffer>			(Move<VkBuffer>&		source,
619 																			 Move<VkBuffer>&		target,
620 																			 Context&				ctx,
621 																			 BindingCaseParameters	params)
622 {
623 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
624 	const VkDevice						vkDevice							= ctx.getDevice();
625 	const VkQueue						queue								= ctx.getUniversalQueue();
626 
627 	const VkBufferMemoryBarrier			srcBufferBarrier					= makeMemoryBarrierInfo(*source, params.bufferSize, TransferFromResource);
628 	const VkBufferMemoryBarrier			dstBufferBarrier					= makeMemoryBarrierInfo(*target, params.bufferSize, TransferToResource);
629 
630 	Move<VkCommandPool>					commandPool							= createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, 0);
631 	Move<VkCommandBuffer>				cmdBuffer							= createCommandBuffer(vk, vkDevice, *commandPool);
632 	VkBufferCopy						bufferCopy							= { 0u, 0u, params.bufferSize };
633 
634 	beginCommandBuffer(vk, *cmdBuffer);
635 	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);
636 	vk.cmdCopyBuffer(*cmdBuffer, *source, *target, 1, &bufferCopy);
637 	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);
638 	endCommandBuffer(vk, *cmdBuffer);
639 
640 	submitCommandsAndWait(vk, vkDevice, queue, *cmdBuffer);
641 }
642 
643 template <>
fillUpResource(Move<VkBuffer> & source,Move<VkImage> & target,Context & ctx,BindingCaseParameters params)644 void									fillUpResource<VkImage>				(Move<VkBuffer>&		source,
645 																			 Move<VkImage>&			target,
646 																			 Context&				ctx,
647 																			 BindingCaseParameters	params)
648 {
649 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
650 	const VkDevice						vkDevice							= ctx.getDevice();
651 	const VkQueue						queue								= ctx.getUniversalQueue();
652 
653 	const VkBufferMemoryBarrier			srcBufferBarrier					= makeMemoryBarrierInfo(*source, params.bufferSize, TransferFromResource);
654 	const VkImageMemoryBarrier			preImageBarrier						= makeMemoryBarrierInfo(*target, 0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
655 	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);
656 
657 	Move<VkCommandPool>					commandPool							= createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, 0);
658 	Move<VkCommandBuffer>				cmdBuffer							= createCommandBuffer(vk, vkDevice, *commandPool);
659 
660 	const VkBufferImageCopy				copyRegion							=
661 	{
662 		0u,																	// VkDeviceSize			bufferOffset;
663 		params.imageSize.width,												// deUint32				bufferRowLength;
664 		params.imageSize.height,											// deUint32				bufferImageHeight;
665 		{
666 			VK_IMAGE_ASPECT_COLOR_BIT,										// VkImageAspectFlags	aspect;
667 			0u,																// deUint32				mipLevel;
668 			0u,																// deUint32				baseArrayLayer;
669 			1u,																// deUint32				layerCount;
670 		},																	// VkImageSubresourceLayers imageSubresource;
671 		{ 0, 0, 0 },														// VkOffset3D			imageOffset;
672 		params.imageSize													// VkExtent3D			imageExtent;
673 	};
674 
675 	beginCommandBuffer(vk, *cmdBuffer);
676 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &srcBufferBarrier, 1, &preImageBarrier);
677 	vk.cmdCopyBufferToImage(*cmdBuffer, *source, *target, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, (&copyRegion));
678 	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);
679 	endCommandBuffer(vk, *cmdBuffer);
680 
681 	submitCommandsAndWait(vk, vkDevice, queue, *cmdBuffer);
682 }
683 
684 template <typename TTarget>
685 void									readUpResource						(Move<TTarget>&			source,
686 																			 Move<VkBuffer>&		target,
687 																			 Context&				ctx,
688 																			 BindingCaseParameters	params);
689 
690 template <>
readUpResource(Move<VkBuffer> & source,Move<VkBuffer> & target,Context & ctx,BindingCaseParameters params)691 void									readUpResource						(Move<VkBuffer>&		source,
692 																			 Move<VkBuffer>&		target,
693 																			 Context&				ctx,
694 																			 BindingCaseParameters	params)
695 {
696 	fillUpResource(source, target, ctx, params);
697 }
698 
699 template <>
readUpResource(Move<VkImage> & source,Move<VkBuffer> & target,Context & ctx,BindingCaseParameters params)700 void									readUpResource						(Move<VkImage>&			source,
701 																			 Move<VkBuffer>&		target,
702 																			 Context&				ctx,
703 																			 BindingCaseParameters	params)
704 {
705 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
706 	const VkDevice						vkDevice							= ctx.getDevice();
707 	const VkQueue						queue								= ctx.getUniversalQueue();
708 
709 	Move<VkCommandPool>					commandPool							= createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, 0);
710 	Move<VkCommandBuffer>				cmdBuffer							= createCommandBuffer(vk, vkDevice, *commandPool);
711 
712 	beginCommandBuffer(vk, *cmdBuffer);
713 	copyImageToBuffer(vk, *cmdBuffer, *source, *target, tcu::IVec2(params.imageSize.width, params.imageSize.height), VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
714 	endCommandBuffer(vk, *cmdBuffer);
715 
716 	submitCommandsAndWait(vk, vkDevice, queue, *cmdBuffer);
717 }
718 
719 
720 template <typename TTarget>
721 void									layoutTransitionResource			(Move<TTarget>&			target,
722 																			 Context&				ctx);
723 
724 template <>
layoutTransitionResource(Move<VkBuffer> & target,Context & ctx)725 void									layoutTransitionResource			(Move<VkBuffer>&		target,
726 																			 Context&				ctx)
727 {
728 	DE_UNREF(target);
729 	DE_UNREF(ctx);
730 }
731 
732 template <>
layoutTransitionResource(Move<VkImage> & target,Context & ctx)733 void									layoutTransitionResource<VkImage>	(Move<VkImage>&			target,
734 																			 Context&				ctx)
735 {
736 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
737 	const VkDevice						vkDevice							= ctx.getDevice();
738 	const VkQueue						queue								= ctx.getUniversalQueue();
739 
740 	const VkImageMemoryBarrier			preImageBarrier						= makeMemoryBarrierInfo(*target, 0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
741 
742 	Move<VkCommandPool>					commandPool							= createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, 0);
743 	Move<VkCommandBuffer>				cmdBuffer							= createCommandBuffer(vk, vkDevice, *commandPool);
744 
745 	beginCommandBuffer(vk, *cmdBuffer);
746 	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);
747 	endCommandBuffer(vk, *cmdBuffer);
748 
749 	submitCommandsAndWait(vk, vkDevice, queue, *cmdBuffer);
750 }
751 
752 
createBuffer(Move<VkBuffer> & buffer,Move<VkDeviceMemory> & memory,Context & ctx,BindingCaseParameters params)753 void									createBuffer						(Move<VkBuffer>&		buffer,
754 																			 Move<VkDeviceMemory>&	memory,
755 																			 Context&				ctx,
756 																			 BindingCaseParameters	params)
757 {
758 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
759 	const VkDevice						vkDevice							= ctx.getDevice();
760 	VkBufferCreateInfo					bufferParams						= makeBufferCreateInfo(ctx, params);
761 	VkMemoryRequirements				memReqs;
762 
763 	buffer = createBuffer(vk, vkDevice, &bufferParams);
764 	vk.getBufferMemoryRequirements(vkDevice, *buffer, &memReqs);
765 
766 	const VkMemoryAllocateInfo			memAlloc							= makeMemoryAllocateInfo(ctx, memReqs, MemoryHostVisible);
767 	VkDeviceMemory						rawMemory							= DE_NULL;
768 
769 	vk.allocateMemory(vkDevice, &memAlloc, static_cast<VkAllocationCallbacks*>(DE_NULL), &rawMemory);
770 	memory = Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL));
771 	VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, *memory, 0u));
772 }
773 
pushData(VkDeviceMemory memory,deUint32 dataSeed,Context & ctx,BindingCaseParameters params)774 void									pushData							(VkDeviceMemory			memory,
775 																			 deUint32				dataSeed,
776 																			 Context&				ctx,
777 																			 BindingCaseParameters	params)
778 {
779 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
780 	const VkDevice						vkDevice							= ctx.getDevice();
781 	MemoryMappingRAII					hostMemory							(vk, vkDevice, memory, 0u, params.bufferSize, 0u);
782 	deUint8*							hostBuffer							= static_cast<deUint8*>(hostMemory.ptr());
783 	SimpleRandomGenerator				random								(dataSeed);
784 
785 	for (deUint32 i = 0u; i < params.bufferSize; ++i)
786 	{
787 		hostBuffer[i] = static_cast<deUint8>(random.getNext() & 0xFFu);
788 	}
789 	hostMemory.flush();
790 }
791 
checkData(VkDeviceMemory memory,deUint32 dataSeed,Context & ctx,BindingCaseParameters params)792 deBool									checkData							(VkDeviceMemory			memory,
793 																			 deUint32				dataSeed,
794 																			 Context&				ctx,
795 																			 BindingCaseParameters	params)
796 {
797 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
798 	const VkDevice						vkDevice							= ctx.getDevice();
799 	MemoryMappingRAII					hostMemory							(vk, vkDevice, memory, 0u, params.bufferSize, 0u);
800 	deUint8*							hostBuffer							= static_cast<deUint8*>(hostMemory.ptr());
801 	SimpleRandomGenerator				random								(dataSeed);
802 
803 	hostMemory.invalidate();
804 
805 	for (deUint32 i = 0u; i < params.bufferSize; ++i)
806 	{
807 		if (hostBuffer[i] != static_cast<deUint8>(random.getNext() & 0xFFu) )
808 			return DE_FALSE;
809 	}
810 	return DE_TRUE;
811 }
812 
813 template<typename TTarget, deBool TDedicated>
814 class MemoryBindingInstance : public TestInstance
815 {
816 public:
MemoryBindingInstance(Context & ctx,BindingCaseParameters params)817 										MemoryBindingInstance				(Context&				ctx,
818 																			 BindingCaseParameters	params)
819 										: TestInstance						(ctx)
820 										, m_params							(params)
821 	{
822 	}
823 
iterate(void)824 	virtual tcu::TestStatus				iterate								(void)
825 	{
826 		const std::vector<std::string>&	extensions							= m_context.getDeviceExtensions();
827 		const deBool					isSupported							= isDeviceExtensionSupported(m_context.getUsedApiVersion(), extensions, "VK_KHR_bind_memory2");
828 		if (!isSupported)
829 		{
830 			TCU_THROW(NotSupportedError, "Not supported");
831 		}
832 
833 		std::vector<de::SharedPtr<Move<TTarget> > >
834 										targets;
835 		MemoryRegionsList				memory;
836 
837 		createBindingTargets<TTarget>(targets, m_context, m_params);
838 		createMemory<TTarget, TDedicated>(targets, memory, m_context, m_params);
839 		makeBinding<TTarget>(targets, memory, m_context, m_params);
840 
841 		Move<VkBuffer>					srcBuffer;
842 		Move<VkDeviceMemory>			srcMemory;
843 
844 		createBuffer(srcBuffer, srcMemory, m_context, m_params);
845 		pushData(*srcMemory, 1, m_context, m_params);
846 
847 		Move<VkBuffer>					dstBuffer;
848 		Move<VkDeviceMemory>			dstMemory;
849 
850 		createBuffer(dstBuffer, dstMemory, m_context, m_params);
851 
852 		deBool							passed								= DE_TRUE;
853 		for (deUint32 i = 0; passed && i < m_params.targetsCount; ++i)
854 		{
855 			fillUpResource(srcBuffer, *targets[i], m_context, m_params);
856 			readUpResource(*targets[i], dstBuffer, m_context, m_params);
857 			passed = checkData(*dstMemory, 1, m_context, m_params);
858 		}
859 
860 		return passed ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Failed");
861 	}
862 private:
863 	BindingCaseParameters				m_params;
864 };
865 
866 template<typename TTarget, deBool TDedicated>
867 class AliasedMemoryBindingInstance : public TestInstance
868 {
869 public:
AliasedMemoryBindingInstance(Context & ctx,BindingCaseParameters params)870 										AliasedMemoryBindingInstance		(Context&				ctx,
871 																			 BindingCaseParameters	params)
872 										: TestInstance						(ctx)
873 										, m_params							(params)
874 	{
875 	}
876 
iterate(void)877 	virtual tcu::TestStatus				iterate								(void)
878 	{
879 		const std::vector<std::string>&	extensions							= m_context.getDeviceExtensions();
880 		const deBool					isSupported							= isDeviceExtensionSupported(m_context.getUsedApiVersion(), extensions, "VK_KHR_bind_memory2");
881 		if (!isSupported)
882 		{
883 			TCU_THROW(NotSupportedError, "Not supported");
884 		}
885 
886 		std::vector<de::SharedPtr<Move<TTarget> > >
887 										targets[2];
888 		MemoryRegionsList				memory;
889 
890 		for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(targets); ++i)
891 			createBindingTargets<TTarget>(targets[i], m_context, m_params);
892 		createMemory<TTarget, TDedicated>(targets[0], memory, m_context, m_params);
893 		for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(targets); ++i)
894 			makeBinding<TTarget>(targets[i], memory, m_context, m_params);
895 
896 		Move<VkBuffer>					srcBuffer;
897 		Move<VkDeviceMemory>			srcMemory;
898 
899 		createBuffer(srcBuffer, srcMemory, m_context, m_params);
900 		pushData(*srcMemory, 2, m_context, m_params);
901 
902 		Move<VkBuffer>					dstBuffer;
903 		Move<VkDeviceMemory>			dstMemory;
904 
905 		createBuffer(dstBuffer, dstMemory, m_context, m_params);
906 
907 		deBool							passed								= DE_TRUE;
908 		for (deUint32 i = 0; passed && i < m_params.targetsCount; ++i)
909 		{
910 			// Do a layout transition on alias 1 before we transition and write to alias 0
911 			layoutTransitionResource(*(targets[1][i]), m_context);
912 			fillUpResource(srcBuffer, *(targets[0][i]), m_context, m_params);
913 			readUpResource(*(targets[1][i]), dstBuffer, m_context, m_params);
914 			passed = checkData(*dstMemory, 2, m_context, m_params);
915 		}
916 
917 		return passed ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Failed");
918 	}
919 private:
920 	BindingCaseParameters				m_params;
921 };
922 
923 template<typename TInstance>
924 class MemoryBindingTest : public TestCase
925 {
926 public:
MemoryBindingTest(tcu::TestContext & testCtx,const std::string & name,const std::string & description,BindingCaseParameters params)927 										MemoryBindingTest					(tcu::TestContext&		testCtx,
928 																			 const std::string&		name,
929 																			 const std::string&		description,
930 																			 BindingCaseParameters	params)
931 										: TestCase							(testCtx, name, description)
932 										, m_params							(params)
933 	{
934 	}
935 
~MemoryBindingTest(void)936 	virtual								~MemoryBindingTest					(void)
937 	{
938 	}
939 
createInstance(Context & ctx) const940 	virtual TestInstance*				createInstance						(Context&				ctx) const
941 	{
942 		return new TInstance(ctx, m_params);
943 	}
944 
945 private:
946 	BindingCaseParameters				m_params;
947 };
948 
949 } // unnamed namespace
950 
createMemoryBindingTests(tcu::TestContext & testCtx)951 tcu::TestCaseGroup* createMemoryBindingTests (tcu::TestContext& testCtx)
952 {
953 	de::MovePtr<tcu::TestCaseGroup>		group								(new tcu::TestCaseGroup(testCtx, "binding", "Memory binding tests."));
954 
955 	de::MovePtr<tcu::TestCaseGroup>		regular								(new tcu::TestCaseGroup(testCtx, "regular", "Basic memory binding tests."));
956 	de::MovePtr<tcu::TestCaseGroup>		aliasing							(new tcu::TestCaseGroup(testCtx, "aliasing", "Memory binding tests with aliasing of two resources."));
957 
958 	de::MovePtr<tcu::TestCaseGroup>		regular_suballocated				(new tcu::TestCaseGroup(testCtx, "suballocated", "Basic memory binding tests with suballocated memory."));
959 	de::MovePtr<tcu::TestCaseGroup>		regular_dedicated					(new tcu::TestCaseGroup(testCtx, "dedicated", "Basic memory binding tests with deditatedly allocated memory."));
960 
961 	de::MovePtr<tcu::TestCaseGroup>		aliasing_suballocated				(new tcu::TestCaseGroup(testCtx, "suballocated", "Memory binding tests with aliasing of two resources with suballocated mamory."));
962 
963 	const VkDeviceSize					allocationSizes[]					= {	33, 257, 4087, 8095, 1*1024*1024 + 1	};
964 
965 	for (deUint32 sizeNdx = 0u; sizeNdx < DE_LENGTH_OF_ARRAY(allocationSizes); ++sizeNdx )
966 	{
967 		const VkDeviceSize				bufferSize							= allocationSizes[sizeNdx];
968 		const BindingCaseParameters		params								= makeBindingCaseParameters(10, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, bufferSize, 0u);
969 		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);
970 		std::ostringstream				testName;
971 
972 		testName << "buffer_" << bufferSize;
973 		regular_suballocated->addChild(new MemoryBindingTest<MemoryBindingInstance<VkBuffer, DE_FALSE> >(testCtx, testName.str(), " ", params));
974 		regular_dedicated->addChild(new MemoryBindingTest<MemoryBindingInstance<VkBuffer, DE_TRUE> >(testCtx, testName.str(), " ", params));
975 		aliasing_suballocated->addChild(new MemoryBindingTest<AliasedMemoryBindingInstance<VkBuffer, DE_FALSE> >(testCtx, testName.str(), " ", aliasparams));
976 	}
977 
978 	const deUint32						imageSizes[]						= {	8, 33, 257	};
979 
980 	for (deUint32 widthNdx = 0u; widthNdx < DE_LENGTH_OF_ARRAY(imageSizes); ++widthNdx )
981 	for (deUint32 heightNdx = 0u; heightNdx < DE_LENGTH_OF_ARRAY(imageSizes); ++heightNdx )
982 	{
983 		const deUint32					width								= imageSizes[widthNdx];
984 		const deUint32					height								= imageSizes[heightNdx];
985 		const BindingCaseParameters		regularparams						= makeBindingCaseParameters(10, width, height, 0u);
986 		const BindingCaseParameters		aliasparams							= makeBindingCaseParameters(10, width, height, VK_IMAGE_CREATE_ALIAS_BIT);
987 		std::ostringstream				testName;
988 
989 		testName << "image_" << width << '_' << height;
990 		regular_suballocated->addChild(new MemoryBindingTest<MemoryBindingInstance<VkImage, DE_FALSE> >(testCtx, testName.str(), " ", regularparams));
991 		regular_dedicated->addChild(new MemoryBindingTest<MemoryBindingInstance<VkImage, DE_TRUE> >(testCtx, testName.str(), "", regularparams));
992 		aliasing_suballocated->addChild(new MemoryBindingTest<AliasedMemoryBindingInstance<VkImage, DE_FALSE> >(testCtx, testName.str(), " ", aliasparams));
993 	}
994 
995 	regular->addChild(regular_suballocated.release());
996 	regular->addChild(regular_dedicated.release());
997 
998 	aliasing->addChild(aliasing_suballocated.release());
999 
1000 	group->addChild(regular.release());
1001 	group->addChild(aliasing.release());
1002 
1003 	return group.release();
1004 }
1005 
1006 } // memory
1007 } // vkt
1008