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