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