• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 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  vktSparseResourcesTestsUtil.cpp
21  * \brief Sparse Resources Tests Utility Classes
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktSparseResourcesTestsUtil.hpp"
25 #include "vkQueryUtil.hpp"
26 #include "vkDeviceUtil.hpp"
27 #include "vkTypeUtil.hpp"
28 #include "tcuTextureUtil.hpp"
29 
30 #include <deMath.h>
31 
32 using namespace vk;
33 
34 namespace vkt
35 {
36 namespace sparse
37 {
38 
getShaderGridSize(const ImageType imageType,const tcu::UVec3 & imageSize,const deUint32 mipLevel)39 tcu::UVec3 getShaderGridSize (const ImageType imageType, const tcu::UVec3& imageSize, const deUint32 mipLevel)
40 {
41 	const deUint32 mipLevelX = std::max(imageSize.x() >> mipLevel, 1u);
42 	const deUint32 mipLevelY = std::max(imageSize.y() >> mipLevel, 1u);
43 	const deUint32 mipLevelZ = std::max(imageSize.z() >> mipLevel, 1u);
44 
45 	switch (imageType)
46 	{
47 	case IMAGE_TYPE_1D:
48 		return tcu::UVec3(mipLevelX, 1u, 1u);
49 
50 	case IMAGE_TYPE_BUFFER:
51 		return tcu::UVec3(imageSize.x(), 1u, 1u);
52 
53 	case IMAGE_TYPE_1D_ARRAY:
54 		return tcu::UVec3(mipLevelX, imageSize.z(), 1u);
55 
56 	case IMAGE_TYPE_2D:
57 		return tcu::UVec3(mipLevelX, mipLevelY, 1u);
58 
59 	case IMAGE_TYPE_2D_ARRAY:
60 		return tcu::UVec3(mipLevelX, mipLevelY, imageSize.z());
61 
62 	case IMAGE_TYPE_3D:
63 		return tcu::UVec3(mipLevelX, mipLevelY, mipLevelZ);
64 
65 	case IMAGE_TYPE_CUBE:
66 		return tcu::UVec3(mipLevelX, mipLevelY, 6u);
67 
68 	case IMAGE_TYPE_CUBE_ARRAY:
69 		return tcu::UVec3(mipLevelX, mipLevelY, 6u * imageSize.z());
70 
71 	default:
72 		DE_FATAL("Unknown image type");
73 		return tcu::UVec3(1u, 1u, 1u);
74 	}
75 }
76 
getLayerSize(const ImageType imageType,const tcu::UVec3 & imageSize)77 tcu::UVec3 getLayerSize (const ImageType imageType, const tcu::UVec3& imageSize)
78 {
79 	switch (imageType)
80 	{
81 	case IMAGE_TYPE_1D:
82 	case IMAGE_TYPE_1D_ARRAY:
83 	case IMAGE_TYPE_BUFFER:
84 		return tcu::UVec3(imageSize.x(), 1u, 1u);
85 
86 	case IMAGE_TYPE_2D:
87 	case IMAGE_TYPE_2D_ARRAY:
88 	case IMAGE_TYPE_CUBE:
89 	case IMAGE_TYPE_CUBE_ARRAY:
90 		return tcu::UVec3(imageSize.x(), imageSize.y(), 1u);
91 
92 	case IMAGE_TYPE_3D:
93 		return tcu::UVec3(imageSize.x(), imageSize.y(), imageSize.z());
94 
95 	default:
96 		DE_FATAL("Unknown image type");
97 		return tcu::UVec3(1u, 1u, 1u);
98 	}
99 }
100 
getNumLayers(const ImageType imageType,const tcu::UVec3 & imageSize)101 deUint32 getNumLayers (const ImageType imageType, const tcu::UVec3& imageSize)
102 {
103 	switch (imageType)
104 	{
105 	case IMAGE_TYPE_1D:
106 	case IMAGE_TYPE_2D:
107 	case IMAGE_TYPE_3D:
108 	case IMAGE_TYPE_BUFFER:
109 		return 1u;
110 
111 	case IMAGE_TYPE_1D_ARRAY:
112 	case IMAGE_TYPE_2D_ARRAY:
113 		return imageSize.z();
114 
115 	case IMAGE_TYPE_CUBE:
116 		return 6u;
117 
118 	case IMAGE_TYPE_CUBE_ARRAY:
119 		return imageSize.z() * 6u;
120 
121 	default:
122 		DE_FATAL("Unknown image type");
123 		return 0u;
124 	}
125 }
126 
getNumPixels(const ImageType imageType,const tcu::UVec3 & imageSize)127 deUint32 getNumPixels (const ImageType imageType, const tcu::UVec3& imageSize)
128 {
129 	const tcu::UVec3 gridSize = getShaderGridSize(imageType, imageSize);
130 
131 	return gridSize.x() * gridSize.y() * gridSize.z();
132 }
133 
getDimensions(const ImageType imageType)134 deUint32 getDimensions (const ImageType imageType)
135 {
136 	switch (imageType)
137 	{
138 	case IMAGE_TYPE_1D:
139 	case IMAGE_TYPE_BUFFER:
140 		return 1u;
141 
142 	case IMAGE_TYPE_1D_ARRAY:
143 	case IMAGE_TYPE_2D:
144 		return 2u;
145 
146 	case IMAGE_TYPE_2D_ARRAY:
147 	case IMAGE_TYPE_CUBE:
148 	case IMAGE_TYPE_CUBE_ARRAY:
149 	case IMAGE_TYPE_3D:
150 		return 3u;
151 
152 	default:
153 		DE_FATAL("Unknown image type");
154 		return 0u;
155 	}
156 }
157 
getLayerDimensions(const ImageType imageType)158 deUint32 getLayerDimensions (const ImageType imageType)
159 {
160 	switch (imageType)
161 	{
162 	case IMAGE_TYPE_1D:
163 	case IMAGE_TYPE_BUFFER:
164 	case IMAGE_TYPE_1D_ARRAY:
165 		return 1u;
166 
167 	case IMAGE_TYPE_2D:
168 	case IMAGE_TYPE_2D_ARRAY:
169 	case IMAGE_TYPE_CUBE:
170 	case IMAGE_TYPE_CUBE_ARRAY:
171 		return 2u;
172 
173 	case IMAGE_TYPE_3D:
174 		return 3u;
175 
176 	default:
177 		DE_FATAL("Unknown image type");
178 		return 0u;
179 	}
180 }
181 
isImageSizeSupported(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const ImageType imageType,const tcu::UVec3 & imageSize)182 bool isImageSizeSupported (const InstanceInterface& instance, const VkPhysicalDevice physicalDevice, const ImageType imageType, const tcu::UVec3& imageSize)
183 {
184 	const VkPhysicalDeviceProperties deviceProperties = getPhysicalDeviceProperties(instance, physicalDevice);
185 
186 	switch (imageType)
187 	{
188 		case IMAGE_TYPE_1D:
189 			return	imageSize.x() <= deviceProperties.limits.maxImageDimension1D;
190 		case IMAGE_TYPE_1D_ARRAY:
191 			return	imageSize.x() <= deviceProperties.limits.maxImageDimension1D &&
192 					imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
193 		case IMAGE_TYPE_2D:
194 			return	imageSize.x() <= deviceProperties.limits.maxImageDimension2D &&
195 					imageSize.y() <= deviceProperties.limits.maxImageDimension2D;
196 		case IMAGE_TYPE_2D_ARRAY:
197 			return	imageSize.x() <= deviceProperties.limits.maxImageDimension2D &&
198 					imageSize.y() <= deviceProperties.limits.maxImageDimension2D &&
199 					imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
200 		case IMAGE_TYPE_CUBE:
201 			return	imageSize.x() <= deviceProperties.limits.maxImageDimensionCube &&
202 					imageSize.y() <= deviceProperties.limits.maxImageDimensionCube;
203 		case IMAGE_TYPE_CUBE_ARRAY:
204 			return	imageSize.x() <= deviceProperties.limits.maxImageDimensionCube &&
205 					imageSize.y() <= deviceProperties.limits.maxImageDimensionCube &&
206 					imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
207 		case IMAGE_TYPE_3D:
208 			return	imageSize.x() <= deviceProperties.limits.maxImageDimension3D &&
209 					imageSize.y() <= deviceProperties.limits.maxImageDimension3D &&
210 					imageSize.z() <= deviceProperties.limits.maxImageDimension3D;
211 		case IMAGE_TYPE_BUFFER:
212 			return true;
213 		default:
214 			DE_FATAL("Unknown image type");
215 			return false;
216 	}
217 }
218 
makeBufferCreateInfo(const VkDeviceSize bufferSize,const VkBufferUsageFlags usage)219 VkBufferCreateInfo makeBufferCreateInfo (const VkDeviceSize			bufferSize,
220 										 const VkBufferUsageFlags	usage)
221 {
222 	const VkBufferCreateInfo bufferCreateInfo =
223 	{
224 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
225 		DE_NULL,								// const void*			pNext;
226 		0u,										// VkBufferCreateFlags	flags;
227 		bufferSize,								// VkDeviceSize			size;
228 		usage,									// VkBufferUsageFlags	usage;
229 		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
230 		0u,										// deUint32				queueFamilyIndexCount;
231 		DE_NULL,								// const deUint32*		pQueueFamilyIndices;
232 	};
233 	return bufferCreateInfo;
234 }
235 
makeBufferImageCopy(const VkExtent3D extent,const deUint32 layerCount,const deUint32 mipmapLevel,const VkDeviceSize bufferOffset)236 VkBufferImageCopy makeBufferImageCopy (const VkExtent3D		extent,
237 									   const deUint32		layerCount,
238 									   const deUint32		mipmapLevel,
239 									   const VkDeviceSize	bufferOffset)
240 {
241 	const VkBufferImageCopy copyParams =
242 	{
243 		bufferOffset,																		//	VkDeviceSize				bufferOffset;
244 		0u,																					//	deUint32					bufferRowLength;
245 		0u,																					//	deUint32					bufferImageHeight;
246 		makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, mipmapLevel, 0u, layerCount),	//	VkImageSubresourceLayers	imageSubresource;
247 		makeOffset3D(0, 0, 0),																//	VkOffset3D					imageOffset;
248 		extent,																				//	VkExtent3D					imageExtent;
249 	};
250 	return copyParams;
251 }
252 
makeCommandPool(const DeviceInterface & vk,const VkDevice device,const deUint32 queueFamilyIndex)253 Move<VkCommandPool> makeCommandPool (const DeviceInterface& vk, const VkDevice device, const deUint32 queueFamilyIndex)
254 {
255 	const VkCommandPoolCreateInfo commandPoolParams =
256 	{
257 		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,			// VkStructureType			sType;
258 		DE_NULL,											// const void*				pNext;
259 		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,	// VkCommandPoolCreateFlags	flags;
260 		queueFamilyIndex,									// deUint32					queueFamilyIndex;
261 	};
262 	return createCommandPool(vk, device, &commandPoolParams);
263 }
264 
makePipelineLayout(const DeviceInterface & vk,const VkDevice device,const VkDescriptorSetLayout descriptorSetLayout)265 Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface&		vk,
266 										   const VkDevice				device,
267 										   const VkDescriptorSetLayout	descriptorSetLayout)
268 {
269 	const VkPipelineLayoutCreateInfo pipelineLayoutParams =
270 	{
271 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,						// VkStructureType					sType;
272 		DE_NULL,															// const void*						pNext;
273 		0u,																	// VkPipelineLayoutCreateFlags		flags;
274 		(descriptorSetLayout != DE_NULL ? 1u : 0u),							// deUint32							setLayoutCount;
275 		(descriptorSetLayout != DE_NULL ? &descriptorSetLayout : DE_NULL),	// const VkDescriptorSetLayout*		pSetLayouts;
276 		0u,																	// deUint32							pushConstantRangeCount;
277 		DE_NULL,															// const VkPushConstantRange*		pPushConstantRanges;
278 	};
279 	return createPipelineLayout(vk, device, &pipelineLayoutParams);
280 }
281 
makeComputePipeline(const DeviceInterface & vk,const VkDevice device,const VkPipelineLayout pipelineLayout,const VkShaderModule shaderModule,const VkSpecializationInfo * specializationInfo)282 Move<VkPipeline> makeComputePipeline (const DeviceInterface&		vk,
283 									  const VkDevice				device,
284 									  const VkPipelineLayout		pipelineLayout,
285 									  const VkShaderModule			shaderModule,
286 									  const VkSpecializationInfo*	specializationInfo)
287 {
288 	const VkPipelineShaderStageCreateInfo pipelineShaderStageParams =
289 	{
290 		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
291 		DE_NULL,												// const void*							pNext;
292 		0u,														// VkPipelineShaderStageCreateFlags		flags;
293 		VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits				stage;
294 		shaderModule,											// VkShaderModule						module;
295 		"main",													// const char*							pName;
296 		specializationInfo,										// const VkSpecializationInfo*			pSpecializationInfo;
297 	};
298 	const VkComputePipelineCreateInfo pipelineCreateInfo =
299 	{
300 		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,		// VkStructureType					sType;
301 		DE_NULL,											// const void*						pNext;
302 		0u,													// VkPipelineCreateFlags			flags;
303 		pipelineShaderStageParams,							// VkPipelineShaderStageCreateInfo	stage;
304 		pipelineLayout,										// VkPipelineLayout					layout;
305 		DE_NULL,											// VkPipeline						basePipelineHandle;
306 		0,													// deInt32							basePipelineIndex;
307 	};
308 	return createComputePipeline(vk, device, DE_NULL , &pipelineCreateInfo);
309 }
310 
makeBufferView(const DeviceInterface & vk,const VkDevice vkDevice,const VkBuffer buffer,const VkFormat format,const VkDeviceSize offset,const VkDeviceSize size)311 Move<VkBufferView> makeBufferView (const DeviceInterface&	vk,
312 								   const VkDevice			vkDevice,
313 								   const VkBuffer			buffer,
314 								   const VkFormat			format,
315 								   const VkDeviceSize		offset,
316 								   const VkDeviceSize		size)
317 {
318 	const VkBufferViewCreateInfo bufferViewParams =
319 	{
320 		VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,	// VkStructureType			sType;
321 		DE_NULL,									// const void*				pNext;
322 		0u,											// VkBufferViewCreateFlags	flags;
323 		buffer,										// VkBuffer					buffer;
324 		format,										// VkFormat					format;
325 		offset,										// VkDeviceSize				offset;
326 		size,										// VkDeviceSize				range;
327 	};
328 	return createBufferView(vk, vkDevice, &bufferViewParams);
329 }
330 
makeImageView(const DeviceInterface & vk,const VkDevice vkDevice,const VkImage image,const VkImageViewType imageViewType,const VkFormat format,const VkImageSubresourceRange subresourceRange)331 Move<VkImageView> makeImageView (const DeviceInterface&			vk,
332 								 const VkDevice					vkDevice,
333 								 const VkImage					image,
334 								 const VkImageViewType			imageViewType,
335 								 const VkFormat					format,
336 								 const VkImageSubresourceRange	subresourceRange)
337 {
338 	const VkImageViewCreateInfo imageViewParams =
339 	{
340 		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
341 		DE_NULL,										// const void*				pNext;
342 		0u,												// VkImageViewCreateFlags	flags;
343 		image,											// VkImage					image;
344 		imageViewType,									// VkImageViewType			viewType;
345 		format,											// VkFormat					format;
346 		makeComponentMappingRGBA(),						// VkComponentMapping		components;
347 		subresourceRange,								// VkImageSubresourceRange	subresourceRange;
348 	};
349 	return createImageView(vk, vkDevice, &imageViewParams);
350 }
351 
makeDescriptorSet(const DeviceInterface & vk,const VkDevice device,const VkDescriptorPool descriptorPool,const VkDescriptorSetLayout setLayout)352 Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface&			vk,
353 										 const VkDevice					device,
354 										 const VkDescriptorPool			descriptorPool,
355 										 const VkDescriptorSetLayout	setLayout)
356 {
357 	const VkDescriptorSetAllocateInfo allocateParams =
358 	{
359 		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,		// VkStructureType				sType;
360 		DE_NULL,											// const void*					pNext;
361 		descriptorPool,										// VkDescriptorPool				descriptorPool;
362 		1u,													// deUint32						setLayoutCount;
363 		&setLayout,											// const VkDescriptorSetLayout*	pSetLayouts;
364 	};
365 	return allocateDescriptorSet(vk, device, &allocateParams);
366 }
367 
makeFramebuffer(const DeviceInterface & vk,const VkDevice device,const VkRenderPass renderPass,const deUint32 attachmentCount,const VkImageView * pAttachments,const deUint32 width,const deUint32 height,const deUint32 layers)368 Move<VkFramebuffer> makeFramebuffer (const DeviceInterface&		vk,
369 									 const VkDevice				device,
370 									 const VkRenderPass			renderPass,
371 									 const deUint32				attachmentCount,
372 									 const VkImageView*			pAttachments,
373 									 const deUint32				width,
374 									 const deUint32				height,
375 									 const deUint32				layers)
376 {
377 	const VkFramebufferCreateInfo framebufferInfo =
378 	{
379 		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,		// VkStructureType				 sType;
380 		DE_NULL,										// const void*					 pNext;
381 		(VkFramebufferCreateFlags)0,					// VkFramebufferCreateFlags		flags;
382 		renderPass,										// VkRenderPass					renderPass;
383 		attachmentCount,								// uint32_t						attachmentCount;
384 		pAttachments,									// const VkImageView*			  pAttachments;
385 		width,											// uint32_t						width;
386 		height,											// uint32_t						height;
387 		layers,											// uint32_t						layers;
388 	};
389 
390 	return createFramebuffer(vk, device, &framebufferInfo);
391 }
392 
bindImage(const DeviceInterface & vk,const VkDevice device,Allocator & allocator,const VkImage image,const MemoryRequirement requirement)393 de::MovePtr<Allocation> bindImage (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkImage image, const MemoryRequirement requirement)
394 {
395 	de::MovePtr<Allocation> alloc = allocator.allocate(getImageMemoryRequirements(vk, device, image), requirement);
396 	VK_CHECK(vk.bindImageMemory(device, image, alloc->getMemory(), alloc->getOffset()));
397 	return alloc;
398 }
399 
bindBuffer(const DeviceInterface & vk,const VkDevice device,Allocator & allocator,const VkBuffer buffer,const MemoryRequirement requirement)400 de::MovePtr<Allocation> bindBuffer (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkBuffer buffer, const MemoryRequirement requirement)
401 {
402 	de::MovePtr<Allocation> alloc(allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), requirement));
403 	VK_CHECK(vk.bindBufferMemory(device, buffer, alloc->getMemory(), alloc->getOffset()));
404 	return alloc;
405 }
406 
submitCommands(const DeviceInterface & vk,const VkQueue queue,const VkCommandBuffer commandBuffer,const deUint32 waitSemaphoreCount,const VkSemaphore * pWaitSemaphores,const VkPipelineStageFlags * pWaitDstStageMask,const deUint32 signalSemaphoreCount,const VkSemaphore * pSignalSemaphores)407 void submitCommands (const DeviceInterface&			vk,
408 					 const VkQueue					queue,
409 					 const VkCommandBuffer			commandBuffer,
410 					 const deUint32					waitSemaphoreCount,
411 					 const VkSemaphore*				pWaitSemaphores,
412 					 const VkPipelineStageFlags*	pWaitDstStageMask,
413 					 const deUint32					signalSemaphoreCount,
414 					 const VkSemaphore*				pSignalSemaphores)
415 {
416 	const VkSubmitInfo submitInfo =
417 	{
418 		VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType				sType;
419 		DE_NULL,						// const void*					pNext;
420 		waitSemaphoreCount,				// deUint32						waitSemaphoreCount;
421 		pWaitSemaphores,				// const VkSemaphore*			pWaitSemaphores;
422 		pWaitDstStageMask,				// const VkPipelineStageFlags*	pWaitDstStageMask;
423 		1u,								// deUint32						commandBufferCount;
424 		&commandBuffer,					// const VkCommandBuffer*		pCommandBuffers;
425 		signalSemaphoreCount,			// deUint32						signalSemaphoreCount;
426 		pSignalSemaphores,				// const VkSemaphore*			pSignalSemaphores;
427 	};
428 
429 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, DE_NULL));
430 }
431 
submitCommandsAndWait(const DeviceInterface & vk,const VkDevice device,const VkQueue queue,const VkCommandBuffer commandBuffer,const deUint32 waitSemaphoreCount,const VkSemaphore * pWaitSemaphores,const VkPipelineStageFlags * pWaitDstStageMask,const deUint32 signalSemaphoreCount,const VkSemaphore * pSignalSemaphores,const bool useDeviceGroups,const deUint32 physicalDeviceID)432 void submitCommandsAndWait (const DeviceInterface&		vk,
433 							const VkDevice				device,
434 							const VkQueue				queue,
435 							const VkCommandBuffer		commandBuffer,
436 							const deUint32				waitSemaphoreCount,
437 							const VkSemaphore*			pWaitSemaphores,
438 							const VkPipelineStageFlags*	pWaitDstStageMask,
439 							const deUint32				signalSemaphoreCount,
440 							const VkSemaphore*			pSignalSemaphores,
441 							const bool					useDeviceGroups,
442 							const deUint32				physicalDeviceID)
443 {
444 	const VkFenceCreateInfo	fenceParams				=
445 	{
446 		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,				// VkStructureType		sType;
447 		DE_NULL,											// const void*			pNext;
448 		0u,													// VkFenceCreateFlags	flags;
449 	};
450 	const Unique<VkFence>	fence(createFence		(vk, device, &fenceParams));
451 
452 	const deUint32			deviceMask				= 1 << physicalDeviceID;
453 	std::vector<deUint32>	deviceIndices			(waitSemaphoreCount, physicalDeviceID);
454 	VkDeviceGroupSubmitInfo deviceGroupSubmitInfo	=
455 	{
456 		VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO_KHR,		//VkStructureType		sType
457 		DE_NULL,											// const void*			pNext
458 		waitSemaphoreCount,									// uint32_t				waitSemaphoreCount
459 		deviceIndices.size() ? &deviceIndices[0] : DE_NULL,	// const uint32_t*		pWaitSemaphoreDeviceIndices
460 		1u,													// uint32_t				commandBufferCount
461 		&deviceMask,										// const uint32_t*		pCommandBufferDeviceMasks
462 		0u,													// uint32_t				signalSemaphoreCount
463 		DE_NULL,											// const uint32_t*		pSignalSemaphoreDeviceIndices
464 	};
465 	const VkSubmitInfo		submitInfo				=
466 	{
467 		VK_STRUCTURE_TYPE_SUBMIT_INFO,						// VkStructureType				sType;
468 		useDeviceGroups ? &deviceGroupSubmitInfo : DE_NULL,	// const void*					pNext;
469 		waitSemaphoreCount,									// deUint32						waitSemaphoreCount;
470 		pWaitSemaphores,									// const VkSemaphore*			pWaitSemaphores;
471 		pWaitDstStageMask,									// const VkPipelineStageFlags*	pWaitDstStageMask;
472 		1u,													// deUint32						commandBufferCount;
473 		&commandBuffer,										// const VkCommandBuffer*		pCommandBuffers;
474 		signalSemaphoreCount,								// deUint32						signalSemaphoreCount;
475 		pSignalSemaphores,									// const VkSemaphore*			pSignalSemaphores;
476 	};
477 
478 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
479 	VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull));
480 }
481 
mapImageType(const ImageType imageType)482 VkImageType	mapImageType (const ImageType imageType)
483 {
484 	switch (imageType)
485 	{
486 		case IMAGE_TYPE_1D:
487 		case IMAGE_TYPE_1D_ARRAY:
488 		case IMAGE_TYPE_BUFFER:
489 			return VK_IMAGE_TYPE_1D;
490 
491 		case IMAGE_TYPE_2D:
492 		case IMAGE_TYPE_2D_ARRAY:
493 		case IMAGE_TYPE_CUBE:
494 		case IMAGE_TYPE_CUBE_ARRAY:
495 			return VK_IMAGE_TYPE_2D;
496 
497 		case IMAGE_TYPE_3D:
498 			return VK_IMAGE_TYPE_3D;
499 
500 		default:
501 			DE_ASSERT(false);
502 			return VK_IMAGE_TYPE_LAST;
503 	}
504 }
505 
mapImageViewType(const ImageType imageType)506 VkImageViewType	mapImageViewType (const ImageType imageType)
507 {
508 	switch (imageType)
509 	{
510 		case IMAGE_TYPE_1D:			return VK_IMAGE_VIEW_TYPE_1D;
511 		case IMAGE_TYPE_1D_ARRAY:	return VK_IMAGE_VIEW_TYPE_1D_ARRAY;
512 		case IMAGE_TYPE_2D:			return VK_IMAGE_VIEW_TYPE_2D;
513 		case IMAGE_TYPE_2D_ARRAY:	return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
514 		case IMAGE_TYPE_3D:			return VK_IMAGE_VIEW_TYPE_3D;
515 		case IMAGE_TYPE_CUBE:		return VK_IMAGE_VIEW_TYPE_CUBE;
516 		case IMAGE_TYPE_CUBE_ARRAY:	return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
517 
518 		default:
519 			DE_ASSERT(false);
520 			return VK_IMAGE_VIEW_TYPE_LAST;
521 	}
522 }
523 
getImageTypeName(const ImageType imageType)524 std::string getImageTypeName (const ImageType imageType)
525 {
526 	switch (imageType)
527 	{
528 		case IMAGE_TYPE_1D:			return "1d";
529 		case IMAGE_TYPE_1D_ARRAY:	return "1d_array";
530 		case IMAGE_TYPE_2D:			return "2d";
531 		case IMAGE_TYPE_2D_ARRAY:	return "2d_array";
532 		case IMAGE_TYPE_3D:			return "3d";
533 		case IMAGE_TYPE_CUBE:		return "cube";
534 		case IMAGE_TYPE_CUBE_ARRAY:	return "cube_array";
535 		case IMAGE_TYPE_BUFFER:		return "buffer";
536 
537 		default:
538 			DE_ASSERT(false);
539 			return "";
540 	}
541 }
542 
getShaderImageType(const tcu::TextureFormat & format,const ImageType imageType)543 std::string getShaderImageType (const tcu::TextureFormat& format, const ImageType imageType)
544 {
545 	std::string formatPart = tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ? "u" :
546 							 tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER   ? "i" : "";
547 
548 	std::string imageTypePart;
549 	switch (imageType)
550 	{
551 		case IMAGE_TYPE_1D:			imageTypePart = "1D";			break;
552 		case IMAGE_TYPE_1D_ARRAY:	imageTypePart = "1DArray";		break;
553 		case IMAGE_TYPE_2D:			imageTypePart = "2D";			break;
554 		case IMAGE_TYPE_2D_ARRAY:	imageTypePart = "2DArray";		break;
555 		case IMAGE_TYPE_3D:			imageTypePart = "3D";			break;
556 		case IMAGE_TYPE_CUBE:		imageTypePart = "Cube";			break;
557 		case IMAGE_TYPE_CUBE_ARRAY:	imageTypePart = "CubeArray";	break;
558 		case IMAGE_TYPE_BUFFER:		imageTypePart = "Buffer";		break;
559 
560 		default:
561 			DE_ASSERT(false);
562 	}
563 
564 	return formatPart + "image" + imageTypePart;
565 }
566 
567 
getShaderImageDataType(const tcu::TextureFormat & format)568 std::string getShaderImageDataType(const tcu::TextureFormat& format)
569 {
570 	switch (tcu::getTextureChannelClass(format.type))
571 	{
572 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
573 			return "uvec4";
574 		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
575 			return "ivec4";
576 		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
577 			return "vec4";
578 		default:
579 			DE_ASSERT(false);
580 			return "";
581 	}
582 }
583 
584 
getShaderImageFormatQualifier(const tcu::TextureFormat & format)585 std::string getShaderImageFormatQualifier (const tcu::TextureFormat& format)
586 {
587 	const char* orderPart;
588 	const char* typePart;
589 
590 	switch (format.order)
591 	{
592 		case tcu::TextureFormat::R:		orderPart = "r";	break;
593 		case tcu::TextureFormat::RG:	orderPart = "rg";	break;
594 		case tcu::TextureFormat::RGB:	orderPart = "rgb";	break;
595 		case tcu::TextureFormat::RGBA:	orderPart = "rgba";	break;
596 
597 		default:
598 			DE_ASSERT(false);
599 			orderPart = DE_NULL;
600 	}
601 
602 	switch (format.type)
603 	{
604 		case tcu::TextureFormat::FLOAT:				typePart = "32f";		break;
605 		case tcu::TextureFormat::HALF_FLOAT:		typePart = "16f";		break;
606 
607 		case tcu::TextureFormat::UNSIGNED_INT32:	typePart = "32ui";		break;
608 		case tcu::TextureFormat::UNSIGNED_INT16:	typePart = "16ui";		break;
609 		case tcu::TextureFormat::UNSIGNED_INT8:		typePart = "8ui";		break;
610 
611 		case tcu::TextureFormat::SIGNED_INT32:		typePart = "32i";		break;
612 		case tcu::TextureFormat::SIGNED_INT16:		typePart = "16i";		break;
613 		case tcu::TextureFormat::SIGNED_INT8:		typePart = "8i";		break;
614 
615 		case tcu::TextureFormat::UNORM_INT16:		typePart = "16";		break;
616 		case tcu::TextureFormat::UNORM_INT8:		typePart = "8";			break;
617 
618 		case tcu::TextureFormat::SNORM_INT16:		typePart = "16_snorm";	break;
619 		case tcu::TextureFormat::SNORM_INT8:		typePart = "8_snorm";	break;
620 
621 		default:
622 			DE_ASSERT(false);
623 			typePart = DE_NULL;
624 	}
625 
626 	return std::string() + orderPart + typePart;
627 }
628 
getShaderImageCoordinates(const ImageType imageType,const std::string & x,const std::string & xy,const std::string & xyz)629 std::string getShaderImageCoordinates	(const ImageType	imageType,
630 										 const std::string&	x,
631 										 const std::string&	xy,
632 										 const std::string&	xyz)
633 {
634 	switch (imageType)
635 	{
636 		case IMAGE_TYPE_1D:
637 		case IMAGE_TYPE_BUFFER:
638 			return x;
639 
640 		case IMAGE_TYPE_1D_ARRAY:
641 		case IMAGE_TYPE_2D:
642 			return xy;
643 
644 		case IMAGE_TYPE_2D_ARRAY:
645 		case IMAGE_TYPE_3D:
646 		case IMAGE_TYPE_CUBE:
647 		case IMAGE_TYPE_CUBE_ARRAY:
648 			return xyz;
649 
650 		default:
651 			DE_ASSERT(0);
652 			return "";
653 	}
654 }
655 
getImageMaxMipLevels(const VkImageFormatProperties & imageFormatProperties,const VkExtent3D & extent)656 deUint32 getImageMaxMipLevels (const VkImageFormatProperties& imageFormatProperties, const VkExtent3D& extent)
657 {
658 	const deUint32 widestEdge = std::max(std::max(extent.width, extent.height), extent.depth);
659 
660 	return std::min(static_cast<deUint32>(deFloatLog2(static_cast<float>(widestEdge))) + 1u, imageFormatProperties.maxMipLevels);
661 }
662 
getImageMipLevelSizeInBytes(const VkExtent3D & baseExtents,const deUint32 layersCount,const tcu::TextureFormat & format,const deUint32 mipmapLevel,const deUint32 mipmapMemoryAlignment)663 deUint32 getImageMipLevelSizeInBytes(const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevel, const deUint32 mipmapMemoryAlignment)
664 {
665 	const VkExtent3D extents = mipLevelExtents(baseExtents, mipmapLevel);
666 
667 	return deAlign32(extents.width * extents.height * extents.depth * layersCount * tcu::getPixelSize(format), mipmapMemoryAlignment);
668 }
669 
getImageSizeInBytes(const VkExtent3D & baseExtents,const deUint32 layersCount,const tcu::TextureFormat & format,const deUint32 mipmapLevelsCount,const deUint32 mipmapMemoryAlignment)670 deUint32 getImageSizeInBytes(const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevelsCount, const deUint32 mipmapMemoryAlignment)
671 {
672 	deUint32 imageSizeInBytes = 0;
673 	for (deUint32 mipmapLevel = 0; mipmapLevel < mipmapLevelsCount; ++mipmapLevel)
674 		imageSizeInBytes += getImageMipLevelSizeInBytes(baseExtents, layersCount, format, mipmapLevel, mipmapMemoryAlignment);
675 
676 	return imageSizeInBytes;
677 }
678 
makeSparseImageMemoryBind(const DeviceInterface & vk,const VkDevice device,const VkDeviceSize allocationSize,const deUint32 memoryType,const VkImageSubresource & subresource,const VkOffset3D & offset,const VkExtent3D & extent)679 VkSparseImageMemoryBind	makeSparseImageMemoryBind  (const DeviceInterface&			vk,
680 													const VkDevice					device,
681 													const VkDeviceSize				allocationSize,
682 													const deUint32					memoryType,
683 													const VkImageSubresource&		subresource,
684 													const VkOffset3D&				offset,
685 													const VkExtent3D&				extent)
686 {
687 	const VkMemoryAllocateInfo	allocInfo =
688 	{
689 		VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,	//	VkStructureType			sType;
690 		DE_NULL,								//	const void*				pNext;
691 		allocationSize,							//	VkDeviceSize			allocationSize;
692 		memoryType,								//	deUint32				memoryTypeIndex;
693 	};
694 
695 	VkDeviceMemory deviceMemory = 0;
696 	VK_CHECK(vk.allocateMemory(device, &allocInfo, DE_NULL, &deviceMemory));
697 
698 	VkSparseImageMemoryBind imageMemoryBind;
699 
700 	imageMemoryBind.subresource		= subresource;
701 	imageMemoryBind.memory			= deviceMemory;
702 	imageMemoryBind.memoryOffset	= 0u;
703 	imageMemoryBind.flags			= 0u;
704 	imageMemoryBind.offset			= offset;
705 	imageMemoryBind.extent			= extent;
706 
707 	return imageMemoryBind;
708 }
709 
makeSparseMemoryBind(const DeviceInterface & vk,const VkDevice device,const VkDeviceSize allocationSize,const deUint32 memoryType,const VkDeviceSize resourceOffset,const VkSparseMemoryBindFlags flags)710 VkSparseMemoryBind makeSparseMemoryBind	(const DeviceInterface&			vk,
711 										 const VkDevice					device,
712 										 const VkDeviceSize				allocationSize,
713 										 const deUint32					memoryType,
714 										 const VkDeviceSize				resourceOffset,
715 										 const VkSparseMemoryBindFlags	flags)
716 {
717 	const VkMemoryAllocateInfo allocInfo =
718 	{
719 		VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,	//	VkStructureType	sType;
720 		DE_NULL,								//	const void*		pNext;
721 		allocationSize,							//	VkDeviceSize	allocationSize;
722 		memoryType,								//	deUint32		memoryTypeIndex;
723 	};
724 
725 	VkDeviceMemory deviceMemory = 0;
726 	VK_CHECK(vk.allocateMemory(device, &allocInfo, DE_NULL, &deviceMemory));
727 
728 	VkSparseMemoryBind memoryBind;
729 
730 	memoryBind.resourceOffset	= resourceOffset;
731 	memoryBind.size				= allocationSize;
732 	memoryBind.memory			= deviceMemory;
733 	memoryBind.memoryOffset		= 0u;
734 	memoryBind.flags			= flags;
735 
736 	return memoryBind;
737 }
738 
requireFeatures(const InstanceInterface & vki,const VkPhysicalDevice physDevice,const FeatureFlags flags)739 void requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags)
740 {
741 	const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
742 
743 	if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
744 		throw tcu::NotSupportedError("Tessellation shader not supported");
745 
746 	if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
747 		throw tcu::NotSupportedError("Geometry shader not supported");
748 
749 	if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
750 		throw tcu::NotSupportedError("Double-precision floats not supported");
751 
752 	if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
753 		throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
754 
755 	if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
756 		throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
757 
758 	if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize)
759 		throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in");
760 }
761 
findMatchingMemoryType(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const VkMemoryRequirements & objectMemoryRequirements,const MemoryRequirement & memoryRequirement)762 deUint32 findMatchingMemoryType (const InstanceInterface&		instance,
763 								 const VkPhysicalDevice			physicalDevice,
764 								 const VkMemoryRequirements&	objectMemoryRequirements,
765 								 const MemoryRequirement&		memoryRequirement)
766 {
767 	const VkPhysicalDeviceMemoryProperties deviceMemoryProperties = getPhysicalDeviceMemoryProperties(instance, physicalDevice);
768 
769 	for (deUint32 memoryTypeNdx = 0; memoryTypeNdx < deviceMemoryProperties.memoryTypeCount; ++memoryTypeNdx)
770 	{
771 		if ((objectMemoryRequirements.memoryTypeBits & (1u << memoryTypeNdx)) != 0 &&
772 			memoryRequirement.matchesHeap(deviceMemoryProperties.memoryTypes[memoryTypeNdx].propertyFlags))
773 		{
774 			return memoryTypeNdx;
775 		}
776 	}
777 
778 	return NO_MATCH_FOUND;
779 }
780 
getHeapIndexForMemoryType(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const deUint32 memoryType)781 deUint32 getHeapIndexForMemoryType (const InstanceInterface&	instance,
782 									const VkPhysicalDevice		physicalDevice,
783 									const deUint32				memoryType)
784 {
785 	const VkPhysicalDeviceMemoryProperties deviceMemoryProperties = getPhysicalDeviceMemoryProperties(instance, physicalDevice);
786 	DE_ASSERT(memoryType < deviceMemoryProperties.memoryTypeCount);
787 	return deviceMemoryProperties.memoryTypes[memoryType].heapIndex;
788 }
789 
checkSparseSupportForImageType(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const ImageType imageType)790 bool checkSparseSupportForImageType (const InstanceInterface&	instance,
791 									 const VkPhysicalDevice		physicalDevice,
792 									 const ImageType			imageType)
793 {
794 	const VkPhysicalDeviceFeatures deviceFeatures = getPhysicalDeviceFeatures(instance, physicalDevice);
795 
796 	if (!deviceFeatures.sparseBinding)
797 		return false;
798 
799 	switch (mapImageType(imageType))
800 	{
801 		case VK_IMAGE_TYPE_2D:
802 			return deviceFeatures.sparseResidencyImage2D == VK_TRUE;
803 		case VK_IMAGE_TYPE_3D:
804 			return deviceFeatures.sparseResidencyImage3D == VK_TRUE;
805 		default:
806 			DE_ASSERT(0);
807 			return false;
808 	};
809 }
810 
checkSparseSupportForImageFormat(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const VkImageCreateInfo & imageInfo)811 bool checkSparseSupportForImageFormat (const InstanceInterface&	instance,
812 									   const VkPhysicalDevice	physicalDevice,
813 									   const VkImageCreateInfo&	imageInfo)
814 {
815 	const std::vector<VkSparseImageFormatProperties> sparseImageFormatPropVec = getPhysicalDeviceSparseImageFormatProperties(
816 		instance, physicalDevice, imageInfo.format, imageInfo.imageType, imageInfo.samples, imageInfo.usage, imageInfo.tiling);
817 
818 	return sparseImageFormatPropVec.size() > 0u;
819 }
820 
checkImageFormatFeatureSupport(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const VkFormat format,const VkFormatFeatureFlags featureFlags)821 bool checkImageFormatFeatureSupport (const InstanceInterface&	instance,
822 									 const VkPhysicalDevice		physicalDevice,
823 									 const VkFormat				format,
824 									 const VkFormatFeatureFlags	featureFlags)
825 {
826 	const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(instance, physicalDevice, format);
827 
828 	return (formatProperties.optimalTilingFeatures & featureFlags) == featureFlags;
829 }
830 
getSparseAspectRequirementsIndex(const std::vector<VkSparseImageMemoryRequirements> & requirements,const VkImageAspectFlags aspectFlags)831 deUint32 getSparseAspectRequirementsIndex (const std::vector<VkSparseImageMemoryRequirements>&	requirements,
832 										   const VkImageAspectFlags								aspectFlags)
833 {
834 	for (deUint32 memoryReqNdx = 0; memoryReqNdx < requirements.size(); ++memoryReqNdx)
835 	{
836 		if (requirements[memoryReqNdx].formatProperties.aspectMask & aspectFlags)
837 			return memoryReqNdx;
838 	}
839 
840 	return NO_MATCH_FOUND;
841 }
842 
843 } // sparse
844 } // vkt
845