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 "vkTypeUtil.hpp"
27 #include "tcuTextureUtil.hpp"
28 
29 #include <deMath.h>
30 
31 using namespace vk;
32 
33 namespace vkt
34 {
35 namespace sparse
36 {
37 
Buffer(const DeviceInterface & vk,const VkDevice device,Allocator & allocator,const VkBufferCreateInfo & bufferCreateInfo,const MemoryRequirement memoryRequirement)38 Buffer::Buffer (const DeviceInterface&		vk,
39 				const VkDevice				device,
40 				Allocator&					allocator,
41 				const VkBufferCreateInfo&	bufferCreateInfo,
42 				const MemoryRequirement		memoryRequirement)
43 	: m_buffer		(createBuffer(vk, device, &bufferCreateInfo))
44 	, m_allocation	(allocator.allocate(getBufferMemoryRequirements(vk, device, *m_buffer), memoryRequirement))
45 {
46 	VK_CHECK(vk.bindBufferMemory(device, *m_buffer, m_allocation->getMemory(), m_allocation->getOffset()));
47 }
48 
Image(const DeviceInterface & vk,const VkDevice device,Allocator & allocator,const VkImageCreateInfo & imageCreateInfo,const MemoryRequirement memoryRequirement)49 Image::Image (const DeviceInterface&	vk,
50 			  const VkDevice			device,
51 			  Allocator&				allocator,
52 			  const VkImageCreateInfo&	imageCreateInfo,
53 			  const MemoryRequirement	memoryRequirement)
54 	: m_image		(createImage(vk, device, &imageCreateInfo))
55 	, m_allocation	(allocator.allocate(getImageMemoryRequirements(vk, device, *m_image), memoryRequirement))
56 {
57 	VK_CHECK(vk.bindImageMemory(device, *m_image, m_allocation->getMemory(), m_allocation->getOffset()));
58 }
59 
getShaderGridSize(const ImageType imageType,const tcu::UVec3 & imageSize,const deUint32 mipLevel)60 tcu::UVec3 getShaderGridSize(const ImageType imageType, const tcu::UVec3& imageSize, const deUint32 mipLevel)
61 {
62 	const deUint32 mipLevelX = std::max(imageSize.x() >> mipLevel, 1u);
63 	const deUint32 mipLevelY = std::max(imageSize.y() >> mipLevel, 1u);
64 	const deUint32 mipLevelZ = std::max(imageSize.z() >> mipLevel, 1u);
65 
66 	switch (imageType)
67 	{
68 	case IMAGE_TYPE_1D:
69 		return tcu::UVec3(mipLevelX, 1u, 1u);
70 
71 	case IMAGE_TYPE_BUFFER:
72 		return tcu::UVec3(imageSize.x(), 1u, 1u);
73 
74 	case IMAGE_TYPE_1D_ARRAY:
75 		return tcu::UVec3(mipLevelX, imageSize.z(), 1u);
76 
77 	case IMAGE_TYPE_2D:
78 		return tcu::UVec3(mipLevelX, mipLevelY, 1u);
79 
80 	case IMAGE_TYPE_2D_ARRAY:
81 		return tcu::UVec3(mipLevelX, mipLevelY, imageSize.z());
82 
83 	case IMAGE_TYPE_3D:
84 		return tcu::UVec3(mipLevelX, mipLevelY, mipLevelZ);
85 
86 	case IMAGE_TYPE_CUBE:
87 		return tcu::UVec3(mipLevelX, mipLevelY, 6u);
88 
89 	case IMAGE_TYPE_CUBE_ARRAY:
90 		return tcu::UVec3(mipLevelX, mipLevelY, 6u * imageSize.z());
91 
92 	default:
93 		DE_FATAL("Unknown image type");
94 		return tcu::UVec3(1u, 1u, 1u);
95 	}
96 }
97 
getLayerSize(const ImageType imageType,const tcu::UVec3 & imageSize)98 tcu::UVec3 getLayerSize(const ImageType imageType, const tcu::UVec3& imageSize)
99 {
100 	switch (imageType)
101 	{
102 	case IMAGE_TYPE_1D:
103 	case IMAGE_TYPE_1D_ARRAY:
104 	case IMAGE_TYPE_BUFFER:
105 		return tcu::UVec3(imageSize.x(), 1u, 1u);
106 
107 	case IMAGE_TYPE_2D:
108 	case IMAGE_TYPE_2D_ARRAY:
109 	case IMAGE_TYPE_CUBE:
110 	case IMAGE_TYPE_CUBE_ARRAY:
111 		return tcu::UVec3(imageSize.x(), imageSize.y(), 1u);
112 
113 	case IMAGE_TYPE_3D:
114 		return tcu::UVec3(imageSize.x(), imageSize.y(), imageSize.z());
115 
116 	default:
117 		DE_FATAL("Unknown image type");
118 		return tcu::UVec3(1u, 1u, 1u);
119 	}
120 }
121 
getNumLayers(const ImageType imageType,const tcu::UVec3 & imageSize)122 deUint32 getNumLayers(const ImageType imageType, const tcu::UVec3& imageSize)
123 {
124 	switch (imageType)
125 	{
126 	case IMAGE_TYPE_1D:
127 	case IMAGE_TYPE_2D:
128 	case IMAGE_TYPE_3D:
129 	case IMAGE_TYPE_BUFFER:
130 		return 1u;
131 
132 	case IMAGE_TYPE_1D_ARRAY:
133 	case IMAGE_TYPE_2D_ARRAY:
134 		return imageSize.z();
135 
136 	case IMAGE_TYPE_CUBE:
137 		return 6u;
138 
139 	case IMAGE_TYPE_CUBE_ARRAY:
140 		return imageSize.z() * 6u;
141 
142 	default:
143 		DE_FATAL("Unknown image type");
144 		return 0u;
145 	}
146 }
147 
getNumPixels(const ImageType imageType,const tcu::UVec3 & imageSize)148 deUint32 getNumPixels(const ImageType imageType, const tcu::UVec3& imageSize)
149 {
150 	const tcu::UVec3 gridSize = getShaderGridSize(imageType, imageSize);
151 
152 	return gridSize.x() * gridSize.y() * gridSize.z();
153 }
154 
getDimensions(const ImageType imageType)155 deUint32 getDimensions(const ImageType imageType)
156 {
157 	switch (imageType)
158 	{
159 	case IMAGE_TYPE_1D:
160 	case IMAGE_TYPE_BUFFER:
161 		return 1u;
162 
163 	case IMAGE_TYPE_1D_ARRAY:
164 	case IMAGE_TYPE_2D:
165 		return 2u;
166 
167 	case IMAGE_TYPE_2D_ARRAY:
168 	case IMAGE_TYPE_CUBE:
169 	case IMAGE_TYPE_CUBE_ARRAY:
170 	case IMAGE_TYPE_3D:
171 		return 3u;
172 
173 	default:
174 		DE_FATAL("Unknown image type");
175 		return 0u;
176 	}
177 }
178 
getLayerDimensions(const ImageType imageType)179 deUint32 getLayerDimensions(const ImageType imageType)
180 {
181 	switch (imageType)
182 	{
183 	case IMAGE_TYPE_1D:
184 	case IMAGE_TYPE_BUFFER:
185 	case IMAGE_TYPE_1D_ARRAY:
186 		return 1u;
187 
188 	case IMAGE_TYPE_2D:
189 	case IMAGE_TYPE_2D_ARRAY:
190 	case IMAGE_TYPE_CUBE:
191 	case IMAGE_TYPE_CUBE_ARRAY:
192 		return 2u;
193 
194 	case IMAGE_TYPE_3D:
195 		return 3u;
196 
197 	default:
198 		DE_FATAL("Unknown image type");
199 		return 0u;
200 	}
201 }
202 
isImageSizeSupported(const ImageType imageType,const tcu::UVec3 & imageSize,const vk::VkPhysicalDeviceLimits & limits)203 bool isImageSizeSupported(const ImageType imageType, const tcu::UVec3& imageSize, const vk::VkPhysicalDeviceLimits& limits)
204 {
205 	switch (imageType)
206 	{
207 		case IMAGE_TYPE_1D:
208 			return	imageSize.x() <= limits.maxImageDimension1D;
209 		case IMAGE_TYPE_1D_ARRAY:
210 			return	imageSize.x() <= limits.maxImageDimension1D &&
211 					imageSize.z() <= limits.maxImageArrayLayers;
212 		case IMAGE_TYPE_2D:
213 			return	imageSize.x() <= limits.maxImageDimension2D &&
214 					imageSize.y() <= limits.maxImageDimension2D;
215 		case IMAGE_TYPE_2D_ARRAY:
216 			return	imageSize.x() <= limits.maxImageDimension2D &&
217 					imageSize.y() <= limits.maxImageDimension2D &&
218 					imageSize.z() <= limits.maxImageArrayLayers;
219 		case IMAGE_TYPE_CUBE:
220 			return	imageSize.x() <= limits.maxImageDimensionCube &&
221 					imageSize.y() <= limits.maxImageDimensionCube;
222 		case IMAGE_TYPE_CUBE_ARRAY:
223 			return	imageSize.x() <= limits.maxImageDimensionCube &&
224 					imageSize.y() <= limits.maxImageDimensionCube &&
225 					imageSize.z() <= limits.maxImageArrayLayers;
226 		case IMAGE_TYPE_3D:
227 			return	imageSize.x() <= limits.maxImageDimension3D &&
228 					imageSize.y() <= limits.maxImageDimension3D &&
229 					imageSize.z() <= limits.maxImageDimension3D;
230 		case IMAGE_TYPE_BUFFER:
231 			return true;
232 		default:
233 			DE_FATAL("Unknown image type");
234 			return false;
235 	}
236 }
237 
makeBufferCreateInfo(const VkDeviceSize bufferSize,const VkBufferUsageFlags usage)238 VkBufferCreateInfo makeBufferCreateInfo (const VkDeviceSize			bufferSize,
239 										 const VkBufferUsageFlags	usage)
240 {
241 	const VkBufferCreateInfo bufferCreateInfo =
242 	{
243 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
244 		DE_NULL,								// const void*			pNext;
245 		0u,										// VkBufferCreateFlags	flags;
246 		bufferSize,								// VkDeviceSize			size;
247 		usage,									// VkBufferUsageFlags	usage;
248 		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
249 		0u,										// deUint32				queueFamilyIndexCount;
250 		DE_NULL,								// const deUint32*		pQueueFamilyIndices;
251 	};
252 	return bufferCreateInfo;
253 }
254 
makeBufferImageCopy(const VkExtent3D extent,const deUint32 layerCount,const deUint32 mipmapLevel,const VkDeviceSize bufferOffset)255 VkBufferImageCopy makeBufferImageCopy (const VkExtent3D		extent,
256 									   const deUint32		layerCount,
257 									   const deUint32		mipmapLevel,
258 									   const VkDeviceSize	bufferOffset)
259 {
260 	const VkBufferImageCopy copyParams =
261 	{
262 		bufferOffset,																		//	VkDeviceSize				bufferOffset;
263 		0u,																					//	deUint32					bufferRowLength;
264 		0u,																					//	deUint32					bufferImageHeight;
265 		makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, mipmapLevel, 0u, layerCount),	//	VkImageSubresourceLayers	imageSubresource;
266 		makeOffset3D(0, 0, 0),																//	VkOffset3D					imageOffset;
267 		extent,																				//	VkExtent3D					imageExtent;
268 	};
269 	return copyParams;
270 }
271 
makeCommandPool(const DeviceInterface & vk,const VkDevice device,const deUint32 queueFamilyIndex)272 Move<VkCommandPool> makeCommandPool (const DeviceInterface& vk, const VkDevice device, const deUint32 queueFamilyIndex)
273 {
274 	const VkCommandPoolCreateInfo commandPoolParams =
275 	{
276 		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,			// VkStructureType			sType;
277 		DE_NULL,											// const void*				pNext;
278 		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,	// VkCommandPoolCreateFlags	flags;
279 		queueFamilyIndex,									// deUint32					queueFamilyIndex;
280 	};
281 	return createCommandPool(vk, device, &commandPoolParams);
282 }
283 
makeCommandBuffer(const DeviceInterface & vk,const VkDevice device,const VkCommandPool commandPool)284 Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
285 {
286 	const VkCommandBufferAllocateInfo bufferAllocateParams =
287 	{
288 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,		// VkStructureType			sType;
289 		DE_NULL,											// const void*				pNext;
290 		commandPool,										// VkCommandPool			commandPool;
291 		VK_COMMAND_BUFFER_LEVEL_PRIMARY,					// VkCommandBufferLevel		level;
292 		1u,													// deUint32					bufferCount;
293 	};
294 	return allocateCommandBuffer(vk, device, &bufferAllocateParams);
295 }
296 
makePipelineLayout(const DeviceInterface & vk,const VkDevice device,const VkDescriptorSetLayout descriptorSetLayout)297 Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface&		vk,
298 										   const VkDevice				device,
299 										   const VkDescriptorSetLayout	descriptorSetLayout)
300 {
301 	const VkPipelineLayoutCreateInfo pipelineLayoutParams =
302 	{
303 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType					sType;
304 		DE_NULL,											// const void*						pNext;
305 		0u,													// VkPipelineLayoutCreateFlags		flags;
306 		1u,													// deUint32							setLayoutCount;
307 		&descriptorSetLayout,								// const VkDescriptorSetLayout*		pSetLayouts;
308 		0u,													// deUint32							pushConstantRangeCount;
309 		DE_NULL,											// const VkPushConstantRange*		pPushConstantRanges;
310 	};
311 	return createPipelineLayout(vk, device, &pipelineLayoutParams);
312 }
313 
makeComputePipeline(const DeviceInterface & vk,const VkDevice device,const VkPipelineLayout pipelineLayout,const VkShaderModule shaderModule)314 Move<VkPipeline> makeComputePipeline (const DeviceInterface&	vk,
315 									  const VkDevice			device,
316 									  const VkPipelineLayout	pipelineLayout,
317 									  const VkShaderModule		shaderModule)
318 {
319 	const VkPipelineShaderStageCreateInfo pipelineShaderStageParams =
320 	{
321 		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
322 		DE_NULL,												// const void*							pNext;
323 		0u,														// VkPipelineShaderStageCreateFlags		flags;
324 		VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits				stage;
325 		shaderModule,											// VkShaderModule						module;
326 		"main",													// const char*							pName;
327 		DE_NULL,												// const VkSpecializationInfo*			pSpecializationInfo;
328 	};
329 	const VkComputePipelineCreateInfo pipelineCreateInfo =
330 	{
331 		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,		// VkStructureType					sType;
332 		DE_NULL,											// const void*						pNext;
333 		0u,													// VkPipelineCreateFlags			flags;
334 		pipelineShaderStageParams,							// VkPipelineShaderStageCreateInfo	stage;
335 		pipelineLayout,										// VkPipelineLayout					layout;
336 		DE_NULL,											// VkPipeline						basePipelineHandle;
337 		0,													// deInt32							basePipelineIndex;
338 	};
339 	return createComputePipeline(vk, device, DE_NULL , &pipelineCreateInfo);
340 }
341 
makeBufferView(const DeviceInterface & vk,const VkDevice vkDevice,const VkBuffer buffer,const VkFormat format,const VkDeviceSize offset,const VkDeviceSize size)342 Move<VkBufferView> makeBufferView (const DeviceInterface&	vk,
343 								   const VkDevice			vkDevice,
344 								   const VkBuffer			buffer,
345 								   const VkFormat			format,
346 								   const VkDeviceSize		offset,
347 								   const VkDeviceSize		size)
348 {
349 	const VkBufferViewCreateInfo bufferViewParams =
350 	{
351 		VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,	// VkStructureType			sType;
352 		DE_NULL,									// const void*				pNext;
353 		0u,											// VkBufferViewCreateFlags	flags;
354 		buffer,										// VkBuffer					buffer;
355 		format,										// VkFormat					format;
356 		offset,										// VkDeviceSize				offset;
357 		size,										// VkDeviceSize				range;
358 	};
359 	return createBufferView(vk, vkDevice, &bufferViewParams);
360 }
361 
makeImageView(const DeviceInterface & vk,const VkDevice vkDevice,const VkImage image,const VkImageViewType imageViewType,const VkFormat format,const VkImageSubresourceRange subresourceRange)362 Move<VkImageView> makeImageView (const DeviceInterface&			vk,
363 								 const VkDevice					vkDevice,
364 								 const VkImage					image,
365 								 const VkImageViewType			imageViewType,
366 								 const VkFormat					format,
367 								 const VkImageSubresourceRange	subresourceRange)
368 {
369 	const VkImageViewCreateInfo imageViewParams =
370 	{
371 		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
372 		DE_NULL,										// const void*				pNext;
373 		0u,												// VkImageViewCreateFlags	flags;
374 		image,											// VkImage					image;
375 		imageViewType,									// VkImageViewType			viewType;
376 		format,											// VkFormat					format;
377 		makeComponentMappingRGBA(),						// VkComponentMapping		components;
378 		subresourceRange,								// VkImageSubresourceRange	subresourceRange;
379 	};
380 	return createImageView(vk, vkDevice, &imageViewParams);
381 }
382 
makeDescriptorSet(const DeviceInterface & vk,const VkDevice device,const VkDescriptorPool descriptorPool,const VkDescriptorSetLayout setLayout)383 Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface&			vk,
384 										 const VkDevice					device,
385 										 const VkDescriptorPool			descriptorPool,
386 										 const VkDescriptorSetLayout	setLayout)
387 {
388 	const VkDescriptorSetAllocateInfo allocateParams =
389 	{
390 		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,		// VkStructureType				sType;
391 		DE_NULL,											// const void*					pNext;
392 		descriptorPool,										// VkDescriptorPool				descriptorPool;
393 		1u,													// deUint32						setLayoutCount;
394 		&setLayout,											// const VkDescriptorSetLayout*	pSetLayouts;
395 	};
396 	return allocateDescriptorSet(vk, device, &allocateParams);
397 }
398 
makeSemaphore(const DeviceInterface & vk,const VkDevice device)399 Move<VkSemaphore> makeSemaphore (const DeviceInterface& vk, const VkDevice device)
400 {
401 	const VkSemaphoreCreateInfo semaphoreCreateInfo =
402 	{
403 		VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
404 		DE_NULL,
405 		0u
406 	};
407 
408 	return createSemaphore(vk, device, &semaphoreCreateInfo);
409 }
410 
makeBufferMemoryBarrier(const VkAccessFlags srcAccessMask,const VkAccessFlags dstAccessMask,const VkBuffer buffer,const VkDeviceSize offset,const VkDeviceSize bufferSizeBytes)411 VkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags	srcAccessMask,
412 											   const VkAccessFlags	dstAccessMask,
413 											   const VkBuffer		buffer,
414 											   const VkDeviceSize	offset,
415 											   const VkDeviceSize	bufferSizeBytes)
416 {
417 	const VkBufferMemoryBarrier barrier =
418 	{
419 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
420 		DE_NULL,									// const void*		pNext;
421 		srcAccessMask,								// VkAccessFlags	srcAccessMask;
422 		dstAccessMask,								// VkAccessFlags	dstAccessMask;
423 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
424 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			destQueueFamilyIndex;
425 		buffer,										// VkBuffer			buffer;
426 		offset,										// VkDeviceSize		offset;
427 		bufferSizeBytes,							// VkDeviceSize		size;
428 	};
429 	return barrier;
430 }
431 
makeImageMemoryBarrier(const VkAccessFlags srcAccessMask,const VkAccessFlags dstAccessMask,const VkImageLayout oldLayout,const VkImageLayout newLayout,const VkImage image,const VkImageSubresourceRange subresourceRange)432 VkImageMemoryBarrier makeImageMemoryBarrier	(const VkAccessFlags			srcAccessMask,
433 											 const VkAccessFlags			dstAccessMask,
434 											 const VkImageLayout			oldLayout,
435 											 const VkImageLayout			newLayout,
436 											 const VkImage					image,
437 											 const VkImageSubresourceRange	subresourceRange)
438 {
439 	const VkImageMemoryBarrier barrier =
440 	{
441 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
442 		DE_NULL,										// const void*				pNext;
443 		srcAccessMask,									// VkAccessFlags			outputMask;
444 		dstAccessMask,									// VkAccessFlags			inputMask;
445 		oldLayout,										// VkImageLayout			oldLayout;
446 		newLayout,										// VkImageLayout			newLayout;
447 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
448 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					destQueueFamilyIndex;
449 		image,											// VkImage					image;
450 		subresourceRange,								// VkImageSubresourceRange	subresourceRange;
451 	};
452 	return barrier;
453 }
454 
makeMemoryBarrier(const vk::VkAccessFlags srcAccessMask,const vk::VkAccessFlags dstAccessMask)455 vk::VkMemoryBarrier makeMemoryBarrier (const vk::VkAccessFlags	srcAccessMask,
456 									   const vk::VkAccessFlags	dstAccessMask)
457 {
458 	const VkMemoryBarrier barrier =
459 	{
460 		VK_STRUCTURE_TYPE_MEMORY_BARRIER,	// VkStructureType			sType;
461 		DE_NULL,							// const void*				pNext;
462 		srcAccessMask,						// VkAccessFlags			outputMask;
463 		dstAccessMask,						// VkAccessFlags			inputMask;
464 	};
465 	return barrier;
466 }
467 
beginCommandBuffer(const DeviceInterface & vk,const VkCommandBuffer commandBuffer)468 void beginCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
469 {
470 	const VkCommandBufferBeginInfo commandBufBeginParams =
471 	{
472 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType					sType;
473 		DE_NULL,										// const void*						pNext;
474 		0u,												// VkCommandBufferUsageFlags		flags;
475 		(const VkCommandBufferInheritanceInfo*)DE_NULL,
476 	};
477 	VK_CHECK(vk.beginCommandBuffer(commandBuffer, &commandBufBeginParams));
478 }
479 
endCommandBuffer(const DeviceInterface & vk,const VkCommandBuffer commandBuffer)480 void endCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
481 {
482 	VK_CHECK(vk.endCommandBuffer(commandBuffer));
483 }
484 
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)485 void submitCommands (const DeviceInterface&			vk,
486 					 const VkQueue					queue,
487 					 const VkCommandBuffer			commandBuffer,
488 					 const deUint32					waitSemaphoreCount,
489 					 const VkSemaphore*				pWaitSemaphores,
490 					 const VkPipelineStageFlags*	pWaitDstStageMask,
491 					 const deUint32					signalSemaphoreCount,
492 					 const VkSemaphore*				pSignalSemaphores)
493 {
494 	const VkSubmitInfo submitInfo =
495 	{
496 		VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType				sType;
497 		DE_NULL,						// const void*					pNext;
498 		waitSemaphoreCount,				// deUint32						waitSemaphoreCount;
499 		pWaitSemaphores,				// const VkSemaphore*			pWaitSemaphores;
500 		pWaitDstStageMask,				// const VkPipelineStageFlags*	pWaitDstStageMask;
501 		1u,								// deUint32						commandBufferCount;
502 		&commandBuffer,					// const VkCommandBuffer*		pCommandBuffers;
503 		signalSemaphoreCount,			// deUint32						signalSemaphoreCount;
504 		pSignalSemaphores,				// const VkSemaphore*			pSignalSemaphores;
505 	};
506 
507 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, DE_NULL));
508 }
509 
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)510 void submitCommandsAndWait (const DeviceInterface&		vk,
511 							const VkDevice				device,
512 							const VkQueue				queue,
513 							const VkCommandBuffer		commandBuffer,
514 							const deUint32				waitSemaphoreCount,
515 							const VkSemaphore*			pWaitSemaphores,
516 							const VkPipelineStageFlags*	pWaitDstStageMask,
517 							const deUint32				signalSemaphoreCount,
518 							const VkSemaphore*			pSignalSemaphores)
519 {
520 	const VkFenceCreateInfo	fenceParams =
521 	{
522 		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,	// VkStructureType		sType;
523 		DE_NULL,								// const void*			pNext;
524 		0u,										// VkFenceCreateFlags	flags;
525 	};
526 	const Unique<VkFence> fence(createFence(vk, device, &fenceParams));
527 
528 	const VkSubmitInfo submitInfo =
529 	{
530 		VK_STRUCTURE_TYPE_SUBMIT_INFO,		// VkStructureType				sType;
531 		DE_NULL,							// const void*					pNext;
532 		waitSemaphoreCount,					// deUint32						waitSemaphoreCount;
533 		pWaitSemaphores,					// const VkSemaphore*			pWaitSemaphores;
534 		pWaitDstStageMask,					// const VkPipelineStageFlags*	pWaitDstStageMask;
535 		1u,									// deUint32						commandBufferCount;
536 		&commandBuffer,						// const VkCommandBuffer*		pCommandBuffers;
537 		signalSemaphoreCount,				// deUint32						signalSemaphoreCount;
538 		pSignalSemaphores,					// const VkSemaphore*			pSignalSemaphores;
539 	};
540 
541 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
542 	VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull));
543 }
544 
mapImageType(const ImageType imageType)545 VkImageType	mapImageType (const ImageType imageType)
546 {
547 	switch (imageType)
548 	{
549 		case IMAGE_TYPE_1D:
550 		case IMAGE_TYPE_1D_ARRAY:
551 		case IMAGE_TYPE_BUFFER:
552 			return VK_IMAGE_TYPE_1D;
553 
554 		case IMAGE_TYPE_2D:
555 		case IMAGE_TYPE_2D_ARRAY:
556 		case IMAGE_TYPE_CUBE:
557 		case IMAGE_TYPE_CUBE_ARRAY:
558 			return VK_IMAGE_TYPE_2D;
559 
560 		case IMAGE_TYPE_3D:
561 			return VK_IMAGE_TYPE_3D;
562 
563 		default:
564 			DE_ASSERT(false);
565 			return VK_IMAGE_TYPE_LAST;
566 	}
567 }
568 
mapImageViewType(const ImageType imageType)569 VkImageViewType	mapImageViewType (const ImageType imageType)
570 {
571 	switch (imageType)
572 	{
573 		case IMAGE_TYPE_1D:			return VK_IMAGE_VIEW_TYPE_1D;
574 		case IMAGE_TYPE_1D_ARRAY:	return VK_IMAGE_VIEW_TYPE_1D_ARRAY;
575 		case IMAGE_TYPE_2D:			return VK_IMAGE_VIEW_TYPE_2D;
576 		case IMAGE_TYPE_2D_ARRAY:	return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
577 		case IMAGE_TYPE_3D:			return VK_IMAGE_VIEW_TYPE_3D;
578 		case IMAGE_TYPE_CUBE:		return VK_IMAGE_VIEW_TYPE_CUBE;
579 		case IMAGE_TYPE_CUBE_ARRAY:	return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
580 
581 		default:
582 			DE_ASSERT(false);
583 			return VK_IMAGE_VIEW_TYPE_LAST;
584 	}
585 }
586 
getImageTypeName(const ImageType imageType)587 std::string getImageTypeName (const ImageType imageType)
588 {
589 	switch (imageType)
590 	{
591 		case IMAGE_TYPE_1D:			return "1d";
592 		case IMAGE_TYPE_1D_ARRAY:	return "1d_array";
593 		case IMAGE_TYPE_2D:			return "2d";
594 		case IMAGE_TYPE_2D_ARRAY:	return "2d_array";
595 		case IMAGE_TYPE_3D:			return "3d";
596 		case IMAGE_TYPE_CUBE:		return "cube";
597 		case IMAGE_TYPE_CUBE_ARRAY:	return "cube_array";
598 		case IMAGE_TYPE_BUFFER:		return "buffer";
599 
600 		default:
601 			DE_ASSERT(false);
602 			return "";
603 	}
604 }
605 
getShaderImageType(const tcu::TextureFormat & format,const ImageType imageType)606 std::string getShaderImageType (const tcu::TextureFormat& format, const ImageType imageType)
607 {
608 	std::string formatPart = tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ? "u" :
609 							 tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER   ? "i" : "";
610 
611 	std::string imageTypePart;
612 	switch (imageType)
613 	{
614 		case IMAGE_TYPE_1D:			imageTypePart = "1D";			break;
615 		case IMAGE_TYPE_1D_ARRAY:	imageTypePart = "1DArray";		break;
616 		case IMAGE_TYPE_2D:			imageTypePart = "2D";			break;
617 		case IMAGE_TYPE_2D_ARRAY:	imageTypePart = "2DArray";		break;
618 		case IMAGE_TYPE_3D:			imageTypePart = "3D";			break;
619 		case IMAGE_TYPE_CUBE:		imageTypePart = "Cube";			break;
620 		case IMAGE_TYPE_CUBE_ARRAY:	imageTypePart = "CubeArray";	break;
621 		case IMAGE_TYPE_BUFFER:		imageTypePart = "Buffer";		break;
622 
623 		default:
624 			DE_ASSERT(false);
625 	}
626 
627 	return formatPart + "image" + imageTypePart;
628 }
629 
630 
getShaderImageDataType(const tcu::TextureFormat & format)631 std::string getShaderImageDataType(const tcu::TextureFormat& format)
632 {
633 	switch (tcu::getTextureChannelClass(format.type))
634 	{
635 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
636 			return "uvec4";
637 		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
638 			return "ivec4";
639 		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
640 			return "vec4";
641 		default:
642 			DE_ASSERT(false);
643 			return "";
644 	}
645 }
646 
647 
getShaderImageFormatQualifier(const tcu::TextureFormat & format)648 std::string getShaderImageFormatQualifier (const tcu::TextureFormat& format)
649 {
650 	const char* orderPart;
651 	const char* typePart;
652 
653 	switch (format.order)
654 	{
655 		case tcu::TextureFormat::R:		orderPart = "r";	break;
656 		case tcu::TextureFormat::RG:	orderPart = "rg";	break;
657 		case tcu::TextureFormat::RGB:	orderPart = "rgb";	break;
658 		case tcu::TextureFormat::RGBA:	orderPart = "rgba";	break;
659 
660 		default:
661 			DE_ASSERT(false);
662 			orderPart = DE_NULL;
663 	}
664 
665 	switch (format.type)
666 	{
667 		case tcu::TextureFormat::FLOAT:				typePart = "32f";		break;
668 		case tcu::TextureFormat::HALF_FLOAT:		typePart = "16f";		break;
669 
670 		case tcu::TextureFormat::UNSIGNED_INT32:	typePart = "32ui";		break;
671 		case tcu::TextureFormat::UNSIGNED_INT16:	typePart = "16ui";		break;
672 		case tcu::TextureFormat::UNSIGNED_INT8:		typePart = "8ui";		break;
673 
674 		case tcu::TextureFormat::SIGNED_INT32:		typePart = "32i";		break;
675 		case tcu::TextureFormat::SIGNED_INT16:		typePart = "16i";		break;
676 		case tcu::TextureFormat::SIGNED_INT8:		typePart = "8i";		break;
677 
678 		case tcu::TextureFormat::UNORM_INT16:		typePart = "16";		break;
679 		case tcu::TextureFormat::UNORM_INT8:		typePart = "8";			break;
680 
681 		case tcu::TextureFormat::SNORM_INT16:		typePart = "16_snorm";	break;
682 		case tcu::TextureFormat::SNORM_INT8:		typePart = "8_snorm";	break;
683 
684 		default:
685 			DE_ASSERT(false);
686 			typePart = DE_NULL;
687 	}
688 
689 	return std::string() + orderPart + typePart;
690 }
691 
mipLevelExtents(const VkExtent3D & baseExtents,const deUint32 mipLevel)692 VkExtent3D mipLevelExtents (const VkExtent3D& baseExtents, const deUint32 mipLevel)
693 {
694 	VkExtent3D result;
695 
696 	result.width	= std::max(baseExtents.width  >> mipLevel, 1u);
697 	result.height	= std::max(baseExtents.height >> mipLevel, 1u);
698 	result.depth	= std::max(baseExtents.depth  >> mipLevel, 1u);
699 
700 	return result;
701 }
702 
getImageMaxMipLevels(const VkImageFormatProperties & imageFormatProperties,const VkImageCreateInfo & imageInfo)703 deUint32 getImageMaxMipLevels (const VkImageFormatProperties& imageFormatProperties, const VkImageCreateInfo &imageInfo)
704 {
705 	const deUint32 widestEdge = std::max(std::max(imageInfo.extent.width, imageInfo.extent.height), imageInfo.extent.depth);
706 
707 	return std::min(static_cast<deUint32>(deFloatLog2(static_cast<float>(widestEdge))) + 1u, imageFormatProperties.maxMipLevels);
708 }
709 
getImageMipLevelSizeInBytes(const VkExtent3D & baseExtents,const deUint32 layersCount,const tcu::TextureFormat & format,const deUint32 mipmapLevel)710 deUint32 getImageMipLevelSizeInBytes (const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevel)
711 {
712 	const VkExtent3D extents = mipLevelExtents(baseExtents, mipmapLevel);
713 
714 	return extents.width * extents.height * extents.depth * layersCount * tcu::getPixelSize(format);
715 }
716 
getImageSizeInBytes(const VkExtent3D & baseExtents,const deUint32 layersCount,const tcu::TextureFormat & format,const deUint32 mipmapLevelsCount)717 deUint32 getImageSizeInBytes (const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevelsCount)
718 {
719 	deUint32 imageSizeInBytes = 0;
720 	for (deUint32 mipmapLevel = 0; mipmapLevel < mipmapLevelsCount; ++mipmapLevel)
721 	{
722 		imageSizeInBytes += getImageMipLevelSizeInBytes(baseExtents, layersCount, format, mipmapLevel);
723 	}
724 
725 	return imageSizeInBytes;
726 }
727 
728 } // sparse
729 } // vkt
730