• 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 #include "deStringUtil.hpp"
30 
31 #include <deMath.h>
32 
33 using namespace vk;
34 
35 namespace vkt
36 {
37 namespace sparse
38 {
39 
formatIsR64(const VkFormat & format)40 bool formatIsR64 (const VkFormat& format)
41 {
42 	switch (format)
43 	{
44 	case VK_FORMAT_R64_SINT:
45 	case VK_FORMAT_R64_UINT:
46 		return true;
47 	default:
48 		return false;
49 	}
50 }
51 
getTestFormats(const ImageType & imageType)52 std::vector<TestFormat> getTestFormats (const ImageType& imageType)
53 {
54 	std::vector<TestFormat> results =
55 	{
56 		{ VK_FORMAT_R64_SINT },				{ VK_FORMAT_R32_SINT },				{ VK_FORMAT_R16_SINT },				{ VK_FORMAT_R8_SINT },
57 		{ VK_FORMAT_R64_UINT },				{ VK_FORMAT_R32_UINT },				{ VK_FORMAT_R16_UINT },				{ VK_FORMAT_R8_UINT },
58 
59 											{ VK_FORMAT_R16_UNORM },			{ VK_FORMAT_R8_UNORM },
60 											{ VK_FORMAT_R16_SNORM },			{ VK_FORMAT_R8_SNORM },
61 		{ VK_FORMAT_R32G32_SINT },			{ VK_FORMAT_R16G16_SINT },			{ VK_FORMAT_R8G8_SINT },
62 		{ VK_FORMAT_R32G32_UINT },			{ VK_FORMAT_R16G16_UINT },			{ VK_FORMAT_R8G8_UINT },
63 											{ VK_FORMAT_R16G16_UNORM },			{ VK_FORMAT_R8G8_UNORM },
64 											{ VK_FORMAT_R16G16_SNORM },			{ VK_FORMAT_R8G8_SNORM },
65 		{ VK_FORMAT_R32G32B32A32_SINT },	{ VK_FORMAT_R16G16B16A16_SINT },	{ VK_FORMAT_R8G8B8A8_SINT },
66 		{ VK_FORMAT_R32G32B32A32_UINT },	{ VK_FORMAT_R16G16B16A16_UINT },	{ VK_FORMAT_R8G8B8A8_UINT },
67 											{ VK_FORMAT_R16G16B16A16_UNORM },	{ VK_FORMAT_R8G8B8A8_UNORM },
68 											{ VK_FORMAT_R16G16B16A16_SNORM },	{ VK_FORMAT_R8G8B8A8_SNORM }
69 	};
70 
71 	if (imageType == IMAGE_TYPE_2D || imageType == IMAGE_TYPE_2D_ARRAY)
72 	{
73 		std::vector<TestFormat> ycbcrFormats =
74 		{
75 			{ VK_FORMAT_G8B8G8R8_422_UNORM },
76 			{ VK_FORMAT_B8G8R8G8_422_UNORM },
77 			{ VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM },
78 			{ VK_FORMAT_G8_B8R8_2PLANE_420_UNORM },
79 			{ VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM },
80 			{ VK_FORMAT_G8_B8R8_2PLANE_422_UNORM },
81 			{ VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM },
82 			{ VK_FORMAT_R10X6_UNORM_PACK16 },
83 			{ VK_FORMAT_R10X6G10X6_UNORM_2PACK16 },
84 			{ VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16 },
85 			{ VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16 },
86 			{ VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16 },
87 			{ VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16 },
88 			{ VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16 },
89 			{ VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16 },
90 			{ VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16 },
91 			{ VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16 },
92 			{ VK_FORMAT_R12X4_UNORM_PACK16 },
93 			{ VK_FORMAT_R12X4G12X4_UNORM_2PACK16 },
94 			{ VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16 },
95 			{ VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16 },
96 			{ VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16 },
97 			{ VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16 },
98 			{ VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16 },
99 			{ VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16 },
100 			{ VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16 },
101 			{ VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16 },
102 			{ VK_FORMAT_G16B16G16R16_422_UNORM },
103 			{ VK_FORMAT_B16G16R16G16_422_UNORM },
104 			{ VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM },
105 			{ VK_FORMAT_G16_B16R16_2PLANE_420_UNORM },
106 			{ VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM },
107 			{ VK_FORMAT_G16_B16R16_2PLANE_422_UNORM },
108 			{ VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM },
109 			{ VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT },
110 			{ VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT },
111 			{ VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT },
112 			{ VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT },
113 		};
114 		std::copy(begin(ycbcrFormats), end(ycbcrFormats), std::back_inserter(results));
115 	}
116 
117 	return results;
118 }
119 
getShaderGridSize(const ImageType imageType,const tcu::UVec3 & imageSize,const deUint32 mipLevel)120 tcu::UVec3 getShaderGridSize (const ImageType imageType, const tcu::UVec3& imageSize, const deUint32 mipLevel)
121 {
122 	const deUint32 mipLevelX = std::max(imageSize.x() >> mipLevel, 1u);
123 	const deUint32 mipLevelY = std::max(imageSize.y() >> mipLevel, 1u);
124 	const deUint32 mipLevelZ = std::max(imageSize.z() >> mipLevel, 1u);
125 
126 	switch (imageType)
127 	{
128 		case IMAGE_TYPE_1D:
129 			return tcu::UVec3(mipLevelX, 1u, 1u);
130 
131 		case IMAGE_TYPE_BUFFER:
132 			return tcu::UVec3(imageSize.x(), 1u, 1u);
133 
134 		case IMAGE_TYPE_1D_ARRAY:
135 			return tcu::UVec3(mipLevelX, imageSize.z(), 1u);
136 
137 		case IMAGE_TYPE_2D:
138 			return tcu::UVec3(mipLevelX, mipLevelY, 1u);
139 
140 		case IMAGE_TYPE_2D_ARRAY:
141 			return tcu::UVec3(mipLevelX, mipLevelY, imageSize.z());
142 
143 		case IMAGE_TYPE_3D:
144 			return tcu::UVec3(mipLevelX, mipLevelY, mipLevelZ);
145 
146 		case IMAGE_TYPE_CUBE:
147 			return tcu::UVec3(mipLevelX, mipLevelY, 6u);
148 
149 		case IMAGE_TYPE_CUBE_ARRAY:
150 			return tcu::UVec3(mipLevelX, mipLevelY, 6u * imageSize.z());
151 
152 		default:
153 			DE_FATAL("Unknown image type");
154 			return tcu::UVec3(1u, 1u, 1u);
155 	}
156 }
157 
getLayerSize(const ImageType imageType,const tcu::UVec3 & imageSize)158 tcu::UVec3 getLayerSize (const ImageType imageType, const tcu::UVec3& imageSize)
159 {
160 	switch (imageType)
161 	{
162 		case IMAGE_TYPE_1D:
163 		case IMAGE_TYPE_1D_ARRAY:
164 		case IMAGE_TYPE_BUFFER:
165 			return tcu::UVec3(imageSize.x(), 1u, 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 tcu::UVec3(imageSize.x(), imageSize.y(), 1u);
172 
173 		case IMAGE_TYPE_3D:
174 			return tcu::UVec3(imageSize.x(), imageSize.y(), imageSize.z());
175 
176 		default:
177 			DE_FATAL("Unknown image type");
178 			return tcu::UVec3(1u, 1u, 1u);
179 	}
180 }
181 
getNumLayers(const ImageType imageType,const tcu::UVec3 & imageSize)182 deUint32 getNumLayers (const ImageType imageType, const tcu::UVec3& imageSize)
183 {
184 	switch (imageType)
185 	{
186 		case IMAGE_TYPE_1D:
187 		case IMAGE_TYPE_2D:
188 		case IMAGE_TYPE_3D:
189 		case IMAGE_TYPE_BUFFER:
190 			return 1u;
191 
192 		case IMAGE_TYPE_1D_ARRAY:
193 		case IMAGE_TYPE_2D_ARRAY:
194 			return imageSize.z();
195 
196 		case IMAGE_TYPE_CUBE:
197 			return 6u;
198 
199 		case IMAGE_TYPE_CUBE_ARRAY:
200 			return imageSize.z() * 6u;
201 
202 		default:
203 			DE_FATAL("Unknown image type");
204 			return 0u;
205 	}
206 }
207 
getNumPixels(const ImageType imageType,const tcu::UVec3 & imageSize)208 deUint32 getNumPixels (const ImageType imageType, const tcu::UVec3& imageSize)
209 {
210 	const tcu::UVec3 gridSize = getShaderGridSize(imageType, imageSize);
211 
212 	return gridSize.x() * gridSize.y() * gridSize.z();
213 }
214 
getDimensions(const ImageType imageType)215 deUint32 getDimensions (const ImageType imageType)
216 {
217 	switch (imageType)
218 	{
219 		case IMAGE_TYPE_1D:
220 		case IMAGE_TYPE_BUFFER:
221 			return 1u;
222 
223 		case IMAGE_TYPE_1D_ARRAY:
224 		case IMAGE_TYPE_2D:
225 			return 2u;
226 
227 		case IMAGE_TYPE_2D_ARRAY:
228 		case IMAGE_TYPE_CUBE:
229 		case IMAGE_TYPE_CUBE_ARRAY:
230 		case IMAGE_TYPE_3D:
231 			return 3u;
232 
233 		default:
234 			DE_FATAL("Unknown image type");
235 			return 0u;
236 	}
237 }
238 
getLayerDimensions(const ImageType imageType)239 deUint32 getLayerDimensions (const ImageType imageType)
240 {
241 	switch (imageType)
242 	{
243 		case IMAGE_TYPE_1D:
244 		case IMAGE_TYPE_BUFFER:
245 		case IMAGE_TYPE_1D_ARRAY:
246 			return 1u;
247 
248 		case IMAGE_TYPE_2D:
249 		case IMAGE_TYPE_2D_ARRAY:
250 		case IMAGE_TYPE_CUBE:
251 		case IMAGE_TYPE_CUBE_ARRAY:
252 			return 2u;
253 
254 		case IMAGE_TYPE_3D:
255 			return 3u;
256 
257 		default:
258 			DE_FATAL("Unknown image type");
259 			return 0u;
260 	}
261 }
262 
isImageSizeSupported(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const ImageType imageType,const tcu::UVec3 & imageSize)263 bool isImageSizeSupported (const InstanceInterface& instance, const VkPhysicalDevice physicalDevice, const ImageType imageType, const tcu::UVec3& imageSize)
264 {
265 	const VkPhysicalDeviceProperties deviceProperties = getPhysicalDeviceProperties(instance, physicalDevice);
266 
267 	switch (imageType)
268 	{
269 		case IMAGE_TYPE_1D:
270 			return	imageSize.x() <= deviceProperties.limits.maxImageDimension1D;
271 		case IMAGE_TYPE_1D_ARRAY:
272 			return	imageSize.x() <= deviceProperties.limits.maxImageDimension1D &&
273 					imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
274 		case IMAGE_TYPE_2D:
275 			return	imageSize.x() <= deviceProperties.limits.maxImageDimension2D &&
276 					imageSize.y() <= deviceProperties.limits.maxImageDimension2D;
277 		case IMAGE_TYPE_2D_ARRAY:
278 			return	imageSize.x() <= deviceProperties.limits.maxImageDimension2D &&
279 					imageSize.y() <= deviceProperties.limits.maxImageDimension2D &&
280 					imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
281 		case IMAGE_TYPE_CUBE:
282 			return	imageSize.x() <= deviceProperties.limits.maxImageDimensionCube &&
283 					imageSize.y() <= deviceProperties.limits.maxImageDimensionCube;
284 		case IMAGE_TYPE_CUBE_ARRAY:
285 			return	imageSize.x() <= deviceProperties.limits.maxImageDimensionCube &&
286 					imageSize.y() <= deviceProperties.limits.maxImageDimensionCube &&
287 					imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
288 		case IMAGE_TYPE_3D:
289 			return	imageSize.x() <= deviceProperties.limits.maxImageDimension3D &&
290 					imageSize.y() <= deviceProperties.limits.maxImageDimension3D &&
291 					imageSize.z() <= deviceProperties.limits.maxImageDimension3D;
292 		case IMAGE_TYPE_BUFFER:
293 			return true;
294 		default:
295 			DE_FATAL("Unknown image type");
296 			return false;
297 	}
298 }
299 
makeBufferImageCopy(const VkExtent3D extent,const deUint32 layerCount,const deUint32 mipmapLevel,const VkDeviceSize bufferOffset)300 VkBufferImageCopy makeBufferImageCopy (const VkExtent3D		extent,
301 									   const deUint32		layerCount,
302 									   const deUint32		mipmapLevel,
303 									   const VkDeviceSize	bufferOffset)
304 {
305 	const VkBufferImageCopy copyParams =
306 	{
307 		bufferOffset,																		//	VkDeviceSize				bufferOffset;
308 		0u,																					//	deUint32					bufferRowLength;
309 		0u,																					//	deUint32					bufferImageHeight;
310 		makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, mipmapLevel, 0u, layerCount),	//	VkImageSubresourceLayers	imageSubresource;
311 		makeOffset3D(0, 0, 0),																//	VkOffset3D					imageOffset;
312 		extent,																				//	VkExtent3D					imageExtent;
313 	};
314 	return copyParams;
315 }
316 
makeComputePipeline(const DeviceInterface & vk,const VkDevice device,const VkPipelineLayout pipelineLayout,const VkShaderModule shaderModule,const VkSpecializationInfo * specializationInfo)317 Move<VkPipeline> makeComputePipeline (const DeviceInterface&		vk,
318 									  const VkDevice				device,
319 									  const VkPipelineLayout		pipelineLayout,
320 									  const VkShaderModule			shaderModule,
321 									  const VkSpecializationInfo*	specializationInfo)
322 {
323 	const VkPipelineShaderStageCreateInfo pipelineShaderStageParams =
324 	{
325 		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
326 		DE_NULL,												// const void*							pNext;
327 		0u,														// VkPipelineShaderStageCreateFlags		flags;
328 		VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits				stage;
329 		shaderModule,											// VkShaderModule						module;
330 		"main",													// const char*							pName;
331 		specializationInfo,										// const VkSpecializationInfo*			pSpecializationInfo;
332 	};
333 	const VkComputePipelineCreateInfo pipelineCreateInfo =
334 	{
335 		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,		// VkStructureType					sType;
336 		DE_NULL,											// const void*						pNext;
337 		0u,													// VkPipelineCreateFlags			flags;
338 		pipelineShaderStageParams,							// VkPipelineShaderStageCreateInfo	stage;
339 		pipelineLayout,										// VkPipelineLayout					layout;
340 		DE_NULL,											// VkPipeline						basePipelineHandle;
341 		0,													// deInt32							basePipelineIndex;
342 	};
343 	return createComputePipeline(vk, device, DE_NULL , &pipelineCreateInfo);
344 }
345 
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)346 void submitCommands (const DeviceInterface&			vk,
347 					 const VkQueue					queue,
348 					 const VkCommandBuffer			commandBuffer,
349 					 const deUint32					waitSemaphoreCount,
350 					 const VkSemaphore*				pWaitSemaphores,
351 					 const VkPipelineStageFlags*	pWaitDstStageMask,
352 					 const deUint32					signalSemaphoreCount,
353 					 const VkSemaphore*				pSignalSemaphores)
354 {
355 	const VkSubmitInfo submitInfo =
356 	{
357 		VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType				sType;
358 		DE_NULL,						// const void*					pNext;
359 		waitSemaphoreCount,				// deUint32						waitSemaphoreCount;
360 		pWaitSemaphores,				// const VkSemaphore*			pWaitSemaphores;
361 		pWaitDstStageMask,				// const VkPipelineStageFlags*	pWaitDstStageMask;
362 		1u,								// deUint32						commandBufferCount;
363 		&commandBuffer,					// const VkCommandBuffer*		pCommandBuffers;
364 		signalSemaphoreCount,			// deUint32						signalSemaphoreCount;
365 		pSignalSemaphores,				// const VkSemaphore*			pSignalSemaphores;
366 	};
367 
368 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, DE_NULL));
369 }
370 
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)371 void submitCommandsAndWait (const DeviceInterface&		vk,
372 							const VkDevice				device,
373 							const VkQueue				queue,
374 							const VkCommandBuffer		commandBuffer,
375 							const deUint32				waitSemaphoreCount,
376 							const VkSemaphore*			pWaitSemaphores,
377 							const VkPipelineStageFlags*	pWaitDstStageMask,
378 							const deUint32				signalSemaphoreCount,
379 							const VkSemaphore*			pSignalSemaphores,
380 							const bool					useDeviceGroups,
381 							const deUint32				physicalDeviceID)
382 {
383 	const VkFenceCreateInfo	fenceParams				=
384 	{
385 		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,				// VkStructureType		sType;
386 		DE_NULL,											// const void*			pNext;
387 		0u,													// VkFenceCreateFlags	flags;
388 	};
389 	const Unique<VkFence>	fence(createFence		(vk, device, &fenceParams));
390 
391 	const deUint32			deviceMask				= 1 << physicalDeviceID;
392 	std::vector<deUint32>	deviceIndices			(waitSemaphoreCount, physicalDeviceID);
393 	VkDeviceGroupSubmitInfo deviceGroupSubmitInfo	=
394 	{
395 		VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO_KHR,		//VkStructureType		sType
396 		DE_NULL,											// const void*			pNext
397 		waitSemaphoreCount,									// uint32_t				waitSemaphoreCount
398 		deviceIndices.size() ? &deviceIndices[0] : DE_NULL,	// const uint32_t*		pWaitSemaphoreDeviceIndices
399 		1u,													// uint32_t				commandBufferCount
400 		&deviceMask,										// const uint32_t*		pCommandBufferDeviceMasks
401 		0u,													// uint32_t				signalSemaphoreCount
402 		DE_NULL,											// const uint32_t*		pSignalSemaphoreDeviceIndices
403 	};
404 	const VkSubmitInfo		submitInfo				=
405 	{
406 		VK_STRUCTURE_TYPE_SUBMIT_INFO,						// VkStructureType				sType;
407 		useDeviceGroups ? &deviceGroupSubmitInfo : DE_NULL,	// const void*					pNext;
408 		waitSemaphoreCount,									// deUint32						waitSemaphoreCount;
409 		pWaitSemaphores,									// const VkSemaphore*			pWaitSemaphores;
410 		pWaitDstStageMask,									// const VkPipelineStageFlags*	pWaitDstStageMask;
411 		1u,													// deUint32						commandBufferCount;
412 		&commandBuffer,										// const VkCommandBuffer*		pCommandBuffers;
413 		signalSemaphoreCount,								// deUint32						signalSemaphoreCount;
414 		pSignalSemaphores,									// const VkSemaphore*			pSignalSemaphores;
415 	};
416 
417 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
418 	VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull));
419 }
420 
mapImageType(const ImageType imageType)421 VkImageType	mapImageType (const ImageType imageType)
422 {
423 	switch (imageType)
424 	{
425 		case IMAGE_TYPE_1D:
426 		case IMAGE_TYPE_1D_ARRAY:
427 		case IMAGE_TYPE_BUFFER:
428 			return VK_IMAGE_TYPE_1D;
429 
430 		case IMAGE_TYPE_2D:
431 		case IMAGE_TYPE_2D_ARRAY:
432 		case IMAGE_TYPE_CUBE:
433 		case IMAGE_TYPE_CUBE_ARRAY:
434 			return VK_IMAGE_TYPE_2D;
435 
436 		case IMAGE_TYPE_3D:
437 			return VK_IMAGE_TYPE_3D;
438 
439 		default:
440 			DE_FATAL("Unexpected image type");
441 			return VK_IMAGE_TYPE_LAST;
442 	}
443 }
444 
mapImageViewType(const ImageType imageType)445 VkImageViewType	mapImageViewType (const ImageType imageType)
446 {
447 	switch (imageType)
448 	{
449 		case IMAGE_TYPE_1D:			return VK_IMAGE_VIEW_TYPE_1D;
450 		case IMAGE_TYPE_1D_ARRAY:	return VK_IMAGE_VIEW_TYPE_1D_ARRAY;
451 		case IMAGE_TYPE_2D:			return VK_IMAGE_VIEW_TYPE_2D;
452 		case IMAGE_TYPE_2D_ARRAY:	return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
453 		case IMAGE_TYPE_3D:			return VK_IMAGE_VIEW_TYPE_3D;
454 		case IMAGE_TYPE_CUBE:		return VK_IMAGE_VIEW_TYPE_CUBE;
455 		case IMAGE_TYPE_CUBE_ARRAY:	return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
456 
457 		default:
458 			DE_FATAL("Unexpected image type");
459 			return VK_IMAGE_VIEW_TYPE_LAST;
460 	}
461 }
462 
getImageTypeName(const ImageType imageType)463 std::string getImageTypeName (const ImageType imageType)
464 {
465 	switch (imageType)
466 	{
467 		case IMAGE_TYPE_1D:			return "1d";
468 		case IMAGE_TYPE_1D_ARRAY:	return "1d_array";
469 		case IMAGE_TYPE_2D:			return "2d";
470 		case IMAGE_TYPE_2D_ARRAY:	return "2d_array";
471 		case IMAGE_TYPE_3D:			return "3d";
472 		case IMAGE_TYPE_CUBE:		return "cube";
473 		case IMAGE_TYPE_CUBE_ARRAY:	return "cube_array";
474 		case IMAGE_TYPE_BUFFER:		return "buffer";
475 
476 		default:
477 			DE_FATAL("Unexpected image type");
478 			return "";
479 	}
480 }
481 
getShaderImageType(const tcu::TextureFormat & format,const ImageType imageType)482 std::string getShaderImageType (const tcu::TextureFormat& format, const ImageType imageType)
483 {
484 	std::string formatPart = tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ? "u" :
485 							 tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER   ? "i" : "";
486 
487 	std::string imageTypePart;
488 	switch (imageType)
489 	{
490 		case IMAGE_TYPE_1D:			imageTypePart = "1D";			break;
491 		case IMAGE_TYPE_1D_ARRAY:	imageTypePart = "1DArray";		break;
492 		case IMAGE_TYPE_2D:			imageTypePart = "2D";			break;
493 		case IMAGE_TYPE_2D_ARRAY:	imageTypePart = "2DArray";		break;
494 		case IMAGE_TYPE_3D:			imageTypePart = "3D";			break;
495 		case IMAGE_TYPE_CUBE:		imageTypePart = "Cube";			break;
496 		case IMAGE_TYPE_CUBE_ARRAY:	imageTypePart = "CubeArray";	break;
497 		case IMAGE_TYPE_BUFFER:		imageTypePart = "Buffer";		break;
498 
499 		default:
500 			DE_FATAL("Unexpected image type");
501 	}
502 
503 	return formatPart + "image" + imageTypePart;
504 }
505 
getShaderImageType(const vk::PlanarFormatDescription & description,const ImageType imageType)506 std::string getShaderImageType (const vk::PlanarFormatDescription& description, const ImageType imageType)
507 {
508 	std::string	formatPart;
509 	std::string	imageTypePart;
510 
511 	// all PlanarFormatDescription types have at least one channel ( 0 ) and all channel types are the same :
512 	switch (description.channels[0].type)
513 	{
514 		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
515 			formatPart = "i";
516 			break;
517 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
518 			formatPart = "u";
519 			break;
520 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
521 		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
522 		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
523 			break;
524 
525 		default:
526 			DE_FATAL("Unexpected channel type");
527 	}
528 
529 	if (formatIsR64(description.planes[0].planeCompatibleFormat))
530 		formatPart += "64";
531 
532 	switch (imageType)
533 	{
534 		case IMAGE_TYPE_1D:			imageTypePart = "1D";			break;
535 		case IMAGE_TYPE_1D_ARRAY:	imageTypePart = "1DArray";		break;
536 		case IMAGE_TYPE_2D:			imageTypePart = "2D";			break;
537 		case IMAGE_TYPE_2D_ARRAY:	imageTypePart = "2DArray";		break;
538 		case IMAGE_TYPE_3D:			imageTypePart = "3D";			break;
539 		case IMAGE_TYPE_CUBE:		imageTypePart = "Cube";			break;
540 		case IMAGE_TYPE_CUBE_ARRAY:	imageTypePart = "CubeArray";	break;
541 		case IMAGE_TYPE_BUFFER:		imageTypePart = "Buffer";		break;
542 
543 		default:
544 			DE_FATAL("Unexpected image type");
545 	}
546 
547 	return formatPart + "image" + imageTypePart;
548 }
549 
getShaderImageDataType(const tcu::TextureFormat & format)550 std::string getShaderImageDataType(const tcu::TextureFormat& format)
551 {
552 	switch (tcu::getTextureChannelClass(format.type))
553 	{
554 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
555 			return "uvec4";
556 		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
557 			return "ivec4";
558 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
559 		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
560 		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
561 			return "vec4";
562 		default:
563 			DE_FATAL("Unexpected channel type");
564 			return "";
565 	}
566 }
567 
getShaderImageDataType(const vk::PlanarFormatDescription & description)568 std::string getShaderImageDataType (const vk::PlanarFormatDescription& description)
569 {
570 	switch (description.channels[0].type)
571 	{
572 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
573 			return (formatIsR64(description.planes[0].planeCompatibleFormat) ? "u64vec4" : "uvec4");
574 		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
575 			return (formatIsR64(description.planes[0].planeCompatibleFormat) ? "i64vec4" : "ivec4");
576 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
577 		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
578 		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
579 			return "vec4";
580 		default:
581 			DE_FATAL("Unexpected channel type");
582 			return "";
583 	}
584 }
585 
getShaderImageFormatQualifier(const tcu::TextureFormat & format)586 std::string getShaderImageFormatQualifier (const tcu::TextureFormat& format)
587 {
588 	const char* orderPart;
589 	const char* typePart;
590 
591 	switch (format.order)
592 	{
593 		case tcu::TextureFormat::R:		orderPart = "r";	break;
594 		case tcu::TextureFormat::RG:	orderPart = "rg";	break;
595 		case tcu::TextureFormat::RGB:	orderPart = "rgb";	break;
596 		case tcu::TextureFormat::RGBA:	orderPart = "rgba";	break;
597 
598 		default:
599 			DE_FATAL("Unexpected channel order");
600 			orderPart = DE_NULL;
601 	}
602 
603 	switch (format.type)
604 	{
605 		case tcu::TextureFormat::FLOAT:				typePart = "32f";		break;
606 		case tcu::TextureFormat::HALF_FLOAT:		typePart = "16f";		break;
607 
608 		case tcu::TextureFormat::UNSIGNED_INT32:	typePart = "32ui";		break;
609 		case tcu::TextureFormat::UNSIGNED_INT16:	typePart = "16ui";		break;
610 		case tcu::TextureFormat::UNSIGNED_INT8:		typePart = "8ui";		break;
611 
612 		case tcu::TextureFormat::SIGNED_INT32:		typePart = "32i";		break;
613 		case tcu::TextureFormat::SIGNED_INT16:		typePart = "16i";		break;
614 		case tcu::TextureFormat::SIGNED_INT8:		typePart = "8i";		break;
615 
616 		case tcu::TextureFormat::UNORM_INT16:		typePart = "16";		break;
617 		case tcu::TextureFormat::UNORM_INT8:		typePart = "8";			break;
618 
619 		case tcu::TextureFormat::SNORM_INT16:		typePart = "16_snorm";	break;
620 		case tcu::TextureFormat::SNORM_INT8:		typePart = "8_snorm";	break;
621 
622 		default:
623 			DE_FATAL("Unexpected channel type");
624 			typePart = DE_NULL;
625 	}
626 
627 	return std::string() + orderPart + typePart;
628 }
629 
getShaderImageFormatQualifier(VkFormat format)630 std::string getShaderImageFormatQualifier (VkFormat format)
631 {
632 	switch (format)
633 	{
634 		case VK_FORMAT_R8_SINT:										return "r8i";
635 		case VK_FORMAT_R16_SINT:									return "r16i";
636 		case VK_FORMAT_R32_SINT:									return "r32i";
637 		case VK_FORMAT_R64_SINT:									return "r64i";
638 		case VK_FORMAT_R8_UINT:										return "r8ui";
639 		case VK_FORMAT_R16_UINT:									return "r16ui";
640 		case VK_FORMAT_R32_UINT:									return "r32ui";
641 		case VK_FORMAT_R64_UINT:									return "r64ui";
642 		case VK_FORMAT_R8_SNORM:									return "r8_snorm";
643 		case VK_FORMAT_R16_SNORM:									return "r16_snorm";
644 		case VK_FORMAT_R8_UNORM:									return "r8";
645 		case VK_FORMAT_R16_UNORM:									return "r16";
646 
647 		case VK_FORMAT_R8G8_SINT:									return "rg8i";
648 		case VK_FORMAT_R16G16_SINT:									return "rg16i";
649 		case VK_FORMAT_R32G32_SINT:									return "rg32i";
650 		case VK_FORMAT_R8G8_UINT:									return "rg8ui";
651 		case VK_FORMAT_R16G16_UINT:									return "rg16ui";
652 		case VK_FORMAT_R32G32_UINT:									return "rg32ui";
653 		case VK_FORMAT_R8G8_SNORM:									return "rg8_snorm";
654 		case VK_FORMAT_R16G16_SNORM:								return "rg16_snorm";
655 		case VK_FORMAT_R8G8_UNORM:									return "rg8";
656 		case VK_FORMAT_R16G16_UNORM:								return "rg16";
657 
658 		case VK_FORMAT_R8G8B8A8_SINT:								return "rgba8i";
659 		case VK_FORMAT_R16G16B16A16_SINT:							return "rgba16i";
660 		case VK_FORMAT_R32G32B32A32_SINT:							return "rgba32i";
661 		case VK_FORMAT_R8G8B8A8_UINT:								return "rgba8ui";
662 		case VK_FORMAT_R16G16B16A16_UINT:							return "rgba16ui";
663 		case VK_FORMAT_R32G32B32A32_UINT:							return "rgba32ui";
664 		case VK_FORMAT_R8G8B8A8_SNORM:								return "rgba8_snorm";
665 		case VK_FORMAT_R16G16B16A16_SNORM:							return "rgba16_snorm";
666 		case VK_FORMAT_R8G8B8A8_UNORM:								return "rgba8";
667 		case VK_FORMAT_R16G16B16A16_UNORM:							return "rgba16";
668 
669 		case VK_FORMAT_G8B8G8R8_422_UNORM:							return "rgba8";
670 		case VK_FORMAT_B8G8R8G8_422_UNORM:							return "rgba8";
671 		case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:					return "rgba8";
672 		case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:					return "rgba8";
673 		case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:					return "rgba8";
674 		case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:					return "rgba8";
675 		case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:					return "rgba8";
676 		case VK_FORMAT_R10X6_UNORM_PACK16:							return "r16";
677 		case VK_FORMAT_R10X6G10X6_UNORM_2PACK16:					return "rg16";
678 		case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:			return "rgba16";
679 		case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:		return "rgba16";
680 		case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:		return "rgba16";
681 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:	return "rgba16";
682 		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:	return "rgba16";
683 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:	return "rgba16";
684 		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:	return "rgba16";
685 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:	return "rgba16";
686 		case VK_FORMAT_R12X4_UNORM_PACK16:							return "r16";
687 		case VK_FORMAT_R12X4G12X4_UNORM_2PACK16:					return "rg16";
688 		case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:			return "rgba16";
689 		case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:		return "rgba16";
690 		case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:		return "rgba16";
691 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:	return "rgba16";
692 		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:	return "rgba16";
693 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:	return "rgba16";
694 		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:	return "rgba16";
695 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:	return "rgba16";
696 		case VK_FORMAT_G16B16G16R16_422_UNORM:						return "rgba16";
697 		case VK_FORMAT_B16G16R16G16_422_UNORM:						return "rgba16";
698 		case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:				return "rgba16";
699 		case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:					return "rgba16";
700 		case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:				return "rgba16";
701 		case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:					return "rgba16";
702 		case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:				return "rgba16";
703 		case VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT:				return "rgba8";
704 		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT:return "rgba16";
705 		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT:return "rgba16";
706 		case VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT:				return "rgba16";
707 
708 		default:
709 			DE_FATAL("Unexpected texture format");
710 			return "error";
711 	}
712 }
713 
getImageFormatID(VkFormat format)714 std::string getImageFormatID (VkFormat format)
715 {
716 	switch (format)
717 	{
718 		case VK_FORMAT_R8_SINT:				return "r8i";
719 		case VK_FORMAT_R16_SINT:			return "r16i";
720 		case VK_FORMAT_R32_SINT:			return "r32i";
721 		case VK_FORMAT_R64_SINT:			return "r64i";
722 		case VK_FORMAT_R8_UINT:				return "r8ui";
723 		case VK_FORMAT_R16_UINT:			return "r16ui";
724 		case VK_FORMAT_R32_UINT:			return "r32ui";
725 		case VK_FORMAT_R64_UINT:			return "r64ui";
726 		case VK_FORMAT_R8_SNORM:			return "r8_snorm";
727 		case VK_FORMAT_R16_SNORM:			return "r16_snorm";
728 		case VK_FORMAT_R8_UNORM:			return "r8";
729 		case VK_FORMAT_R16_UNORM:			return "r16";
730 
731 		case VK_FORMAT_R8G8_SINT:			return "rg8i";
732 		case VK_FORMAT_R16G16_SINT:			return "rg16i";
733 		case VK_FORMAT_R32G32_SINT:			return "rg32i";
734 		case VK_FORMAT_R8G8_UINT:			return "rg8ui";
735 		case VK_FORMAT_R16G16_UINT:			return "rg16ui";
736 		case VK_FORMAT_R32G32_UINT:			return "rg32ui";
737 		case VK_FORMAT_R8G8_SNORM:			return "rg8_snorm";
738 		case VK_FORMAT_R16G16_SNORM:		return "rg16_snorm";
739 		case VK_FORMAT_R8G8_UNORM:			return "rg8";
740 		case VK_FORMAT_R16G16_UNORM:		return "rg16";
741 
742 		case VK_FORMAT_R8G8B8A8_SINT:		return "rgba8i";
743 		case VK_FORMAT_R16G16B16A16_SINT:	return "rgba16i";
744 		case VK_FORMAT_R32G32B32A32_SINT:	return "rgba32i";
745 		case VK_FORMAT_R8G8B8A8_UINT:		return "rgba8ui";
746 		case VK_FORMAT_R16G16B16A16_UINT:	return "rgba16ui";
747 		case VK_FORMAT_R32G32B32A32_UINT:	return "rgba32ui";
748 		case VK_FORMAT_R8G8B8A8_SNORM:		return "rgba8_snorm";
749 		case VK_FORMAT_R16G16B16A16_SNORM:	return "rgba16_snorm";
750 		case VK_FORMAT_R8G8B8A8_UNORM:		return "rgba8";
751 		case VK_FORMAT_R16G16B16A16_UNORM:	return "rgba16";
752 
753 		case VK_FORMAT_G8B8G8R8_422_UNORM:
754 		case VK_FORMAT_B8G8R8G8_422_UNORM:
755 		case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
756 		case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
757 		case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
758 		case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
759 		case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
760 		case VK_FORMAT_R10X6_UNORM_PACK16:
761 		case VK_FORMAT_R10X6G10X6_UNORM_2PACK16:
762 		case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:
763 		case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
764 		case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
765 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
766 		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
767 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
768 		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
769 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
770 		case VK_FORMAT_R12X4_UNORM_PACK16:
771 		case VK_FORMAT_R12X4G12X4_UNORM_2PACK16:
772 		case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:
773 		case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
774 		case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
775 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
776 		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
777 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
778 		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
779 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
780 		case VK_FORMAT_G16B16G16R16_422_UNORM:
781 		case VK_FORMAT_B16G16R16G16_422_UNORM:
782 		case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
783 		case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
784 		case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
785 		case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
786 		case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
787 		case VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT:
788 		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT:
789 		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT:
790 		case VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT:
791 			return de::toLower(std::string(getFormatName(format)).substr(10));
792 
793 		default:
794 			DE_FATAL("Unexpected texture format");
795 			return "error";
796 	}
797 }
798 
getShaderImageCoordinates(const ImageType imageType,const std::string & x,const std::string & xy,const std::string & xyz)799 std::string getShaderImageCoordinates	(const ImageType	imageType,
800 										 const std::string&	x,
801 										 const std::string&	xy,
802 										 const std::string&	xyz)
803 {
804 	switch (imageType)
805 	{
806 		case IMAGE_TYPE_1D:
807 		case IMAGE_TYPE_BUFFER:
808 			return x;
809 
810 		case IMAGE_TYPE_1D_ARRAY:
811 		case IMAGE_TYPE_2D:
812 			return xy;
813 
814 		case IMAGE_TYPE_2D_ARRAY:
815 		case IMAGE_TYPE_3D:
816 		case IMAGE_TYPE_CUBE:
817 		case IMAGE_TYPE_CUBE_ARRAY:
818 			return xyz;
819 
820 		default:
821 			DE_FATAL("Unexpected image type");
822 			return "";
823 	}
824 }
825 
getImageMipLevelSizeInBytes(const VkExtent3D & baseExtents,const deUint32 layersCount,const tcu::TextureFormat & format,const deUint32 mipmapLevel,const deUint32 mipmapMemoryAlignment)826 deUint32 getImageMipLevelSizeInBytes(const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevel, const deUint32 mipmapMemoryAlignment)
827 {
828 	const VkExtent3D extents = mipLevelExtents(baseExtents, mipmapLevel);
829 
830 	return deAlign32(extents.width * extents.height * extents.depth * layersCount * tcu::getPixelSize(format), mipmapMemoryAlignment);
831 }
832 
getImageSizeInBytes(const VkExtent3D & baseExtents,const deUint32 layersCount,const tcu::TextureFormat & format,const deUint32 mipmapLevelsCount,const deUint32 mipmapMemoryAlignment)833 deUint32 getImageSizeInBytes(const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevelsCount, const deUint32 mipmapMemoryAlignment)
834 {
835 	deUint32 imageSizeInBytes = 0;
836 	for (deUint32 mipmapLevel = 0; mipmapLevel < mipmapLevelsCount; ++mipmapLevel)
837 		imageSizeInBytes += getImageMipLevelSizeInBytes(baseExtents, layersCount, format, mipmapLevel, mipmapMemoryAlignment);
838 
839 	return imageSizeInBytes;
840 }
841 
getImageMipLevelSizeInBytes(const VkExtent3D & baseExtents,const deUint32 layersCount,const vk::PlanarFormatDescription & formatDescription,const deUint32 planeNdx,const deUint32 mipmapLevel,const deUint32 mipmapMemoryAlignment)842 deUint32 getImageMipLevelSizeInBytes (const VkExtent3D& baseExtents, const deUint32 layersCount, const vk::PlanarFormatDescription& formatDescription, const deUint32 planeNdx, const deUint32 mipmapLevel, const deUint32 mipmapMemoryAlignment)
843 {
844 	return layersCount * getPlaneSizeInBytes(formatDescription, baseExtents, planeNdx, mipmapLevel, mipmapMemoryAlignment);
845 }
846 
getImageSizeInBytes(const VkExtent3D & baseExtents,const deUint32 layersCount,const vk::PlanarFormatDescription & formatDescription,const deUint32 planeNdx,const deUint32 mipmapLevelsCount,const deUint32 mipmapMemoryAlignment)847 deUint32 getImageSizeInBytes (const VkExtent3D& baseExtents, const deUint32 layersCount, const vk::PlanarFormatDescription& formatDescription, const deUint32 planeNdx, const deUint32 mipmapLevelsCount, const deUint32 mipmapMemoryAlignment)
848 {
849 	deUint32 imageSizeInBytes = 0;
850 
851 	for (deUint32 mipmapLevel = 0; mipmapLevel < mipmapLevelsCount; ++mipmapLevel)
852 		imageSizeInBytes += getImageMipLevelSizeInBytes(baseExtents, layersCount, formatDescription, planeNdx, mipmapLevel, mipmapMemoryAlignment);
853 
854 	return imageSizeInBytes;
855 }
856 
makeSparseImageMemoryBind(const DeviceInterface & vk,const VkDevice device,const VkDeviceSize allocationSize,const deUint32 memoryType,const VkImageSubresource & subresource,const VkOffset3D & offset,const VkExtent3D & extent)857 VkSparseImageMemoryBind	makeSparseImageMemoryBind  (const DeviceInterface&			vk,
858 													const VkDevice					device,
859 													const VkDeviceSize				allocationSize,
860 													const deUint32					memoryType,
861 													const VkImageSubresource&		subresource,
862 													const VkOffset3D&				offset,
863 													const VkExtent3D&				extent)
864 {
865 	const VkMemoryAllocateInfo	allocInfo =
866 	{
867 		VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,	//	VkStructureType			sType;
868 		DE_NULL,								//	const void*				pNext;
869 		allocationSize,							//	VkDeviceSize			allocationSize;
870 		memoryType,								//	deUint32				memoryTypeIndex;
871 	};
872 
873 	VkDeviceMemory deviceMemory = 0;
874 	VK_CHECK(vk.allocateMemory(device, &allocInfo, DE_NULL, &deviceMemory));
875 
876 	VkSparseImageMemoryBind imageMemoryBind;
877 
878 	imageMemoryBind.subresource		= subresource;
879 	imageMemoryBind.memory			= deviceMemory;
880 	imageMemoryBind.memoryOffset	= 0u;
881 	imageMemoryBind.flags			= 0u;
882 	imageMemoryBind.offset			= offset;
883 	imageMemoryBind.extent			= extent;
884 
885 	return imageMemoryBind;
886 }
887 
makeSparseMemoryBind(const DeviceInterface & vk,const VkDevice device,const VkDeviceSize allocationSize,const deUint32 memoryType,const VkDeviceSize resourceOffset,const VkSparseMemoryBindFlags flags)888 VkSparseMemoryBind makeSparseMemoryBind	(const DeviceInterface&			vk,
889 										 const VkDevice					device,
890 										 const VkDeviceSize				allocationSize,
891 										 const deUint32					memoryType,
892 										 const VkDeviceSize				resourceOffset,
893 										 const VkSparseMemoryBindFlags	flags)
894 {
895 	const VkMemoryAllocateInfo allocInfo =
896 	{
897 		VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,	//	VkStructureType	sType;
898 		DE_NULL,								//	const void*		pNext;
899 		allocationSize,							//	VkDeviceSize	allocationSize;
900 		memoryType,								//	deUint32		memoryTypeIndex;
901 	};
902 
903 	VkDeviceMemory deviceMemory = 0;
904 	VK_CHECK(vk.allocateMemory(device, &allocInfo, DE_NULL, &deviceMemory));
905 
906 	VkSparseMemoryBind memoryBind;
907 
908 	memoryBind.resourceOffset	= resourceOffset;
909 	memoryBind.size				= allocationSize;
910 	memoryBind.memory			= deviceMemory;
911 	memoryBind.memoryOffset		= 0u;
912 	memoryBind.flags			= flags;
913 
914 	return memoryBind;
915 }
916 
requireFeatures(const InstanceInterface & vki,const VkPhysicalDevice physDevice,const FeatureFlags flags)917 void requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags)
918 {
919 	const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
920 
921 	if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
922 		throw tcu::NotSupportedError("Tessellation shader not supported");
923 
924 	if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
925 		throw tcu::NotSupportedError("Geometry shader not supported");
926 
927 	if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
928 		throw tcu::NotSupportedError("Double-precision floats not supported");
929 
930 	if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
931 		throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
932 
933 	if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
934 		throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
935 
936 	if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize)
937 		throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in");
938 }
939 
findMatchingMemoryType(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const VkMemoryRequirements & objectMemoryRequirements,const MemoryRequirement & memoryRequirement)940 deUint32 findMatchingMemoryType (const InstanceInterface&		instance,
941 								 const VkPhysicalDevice			physicalDevice,
942 								 const VkMemoryRequirements&	objectMemoryRequirements,
943 								 const MemoryRequirement&		memoryRequirement)
944 {
945 	const VkPhysicalDeviceMemoryProperties deviceMemoryProperties = getPhysicalDeviceMemoryProperties(instance, physicalDevice);
946 
947 	for (deUint32 memoryTypeNdx = 0; memoryTypeNdx < deviceMemoryProperties.memoryTypeCount; ++memoryTypeNdx)
948 	{
949 		if ((objectMemoryRequirements.memoryTypeBits & (1u << memoryTypeNdx)) != 0 &&
950 			memoryRequirement.matchesHeap(deviceMemoryProperties.memoryTypes[memoryTypeNdx].propertyFlags))
951 		{
952 			return memoryTypeNdx;
953 		}
954 	}
955 
956 	return NO_MATCH_FOUND;
957 }
958 
getHeapIndexForMemoryType(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const deUint32 memoryType)959 deUint32 getHeapIndexForMemoryType (const InstanceInterface&	instance,
960 									const VkPhysicalDevice		physicalDevice,
961 									const deUint32				memoryType)
962 {
963 	const VkPhysicalDeviceMemoryProperties deviceMemoryProperties = getPhysicalDeviceMemoryProperties(instance, physicalDevice);
964 	DE_ASSERT(memoryType < deviceMemoryProperties.memoryTypeCount);
965 	return deviceMemoryProperties.memoryTypes[memoryType].heapIndex;
966 }
967 
checkSparseSupportForImageType(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const ImageType imageType)968 bool checkSparseSupportForImageType (const InstanceInterface&	instance,
969 									 const VkPhysicalDevice		physicalDevice,
970 									 const ImageType			imageType)
971 {
972 	const VkPhysicalDeviceFeatures deviceFeatures = getPhysicalDeviceFeatures(instance, physicalDevice);
973 
974 	if (!deviceFeatures.sparseBinding)
975 		return false;
976 
977 	switch (mapImageType(imageType))
978 	{
979 		case VK_IMAGE_TYPE_2D:
980 			return deviceFeatures.sparseResidencyImage2D == VK_TRUE;
981 		case VK_IMAGE_TYPE_3D:
982 			return deviceFeatures.sparseResidencyImage3D == VK_TRUE;
983 		default:
984 			DE_FATAL("Unexpected image type");
985 			return false;
986 	}
987 }
988 
checkSparseSupportForImageFormat(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const VkImageCreateInfo & imageInfo)989 bool checkSparseSupportForImageFormat (const InstanceInterface&	instance,
990 									   const VkPhysicalDevice	physicalDevice,
991 									   const VkImageCreateInfo&	imageInfo)
992 {
993 	const std::vector<VkSparseImageFormatProperties> sparseImageFormatPropVec = getPhysicalDeviceSparseImageFormatProperties(
994 		instance, physicalDevice, imageInfo.format, imageInfo.imageType, imageInfo.samples, imageInfo.usage, imageInfo.tiling);
995 
996 	return sparseImageFormatPropVec.size() > 0u;
997 }
998 
checkImageFormatFeatureSupport(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const VkFormat format,const VkFormatFeatureFlags featureFlags)999 bool checkImageFormatFeatureSupport (const InstanceInterface&	instance,
1000 									 const VkPhysicalDevice		physicalDevice,
1001 									 const VkFormat				format,
1002 									 const VkFormatFeatureFlags	featureFlags)
1003 {
1004 	const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(instance, physicalDevice, format);
1005 
1006 	return (formatProperties.optimalTilingFeatures & featureFlags) == featureFlags;
1007 }
1008 
getSparseAspectRequirementsIndex(const std::vector<VkSparseImageMemoryRequirements> & requirements,const VkImageAspectFlags aspectFlags)1009 deUint32 getSparseAspectRequirementsIndex (const std::vector<VkSparseImageMemoryRequirements>&	requirements,
1010 										   const VkImageAspectFlags								aspectFlags)
1011 {
1012 	for (deUint32 memoryReqNdx = 0; memoryReqNdx < requirements.size(); ++memoryReqNdx)
1013 	{
1014 		if (requirements[memoryReqNdx].formatProperties.aspectMask & aspectFlags)
1015 			return memoryReqNdx;
1016 	}
1017 
1018 	return NO_MATCH_FOUND;
1019 }
1020 
getPlaneCompatibleFormatForWriting(const vk::PlanarFormatDescription & formatInfo,deUint32 planeNdx)1021 vk::VkFormat getPlaneCompatibleFormatForWriting(const vk::PlanarFormatDescription& formatInfo, deUint32 planeNdx)
1022 {
1023 	DE_ASSERT(planeNdx < formatInfo.numPlanes);
1024 	vk::VkFormat result = formatInfo.planes[planeNdx].planeCompatibleFormat;
1025 
1026 	// redirect result for some of the YCbCr image formats
1027 	static const std::pair<vk::VkFormat, vk::VkFormat> ycbcrFormats[] =
1028 	{
1029 		{ VK_FORMAT_G8B8G8R8_422_UNORM_KHR,						VK_FORMAT_R8G8B8A8_UNORM		},
1030 		{ VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR,	VK_FORMAT_R16G16B16A16_UNORM	},
1031 		{ VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR,	VK_FORMAT_R16G16B16A16_UNORM	},
1032 		{ VK_FORMAT_G16B16G16R16_422_UNORM_KHR,					VK_FORMAT_R16G16B16A16_UNORM	},
1033 		{ VK_FORMAT_B8G8R8G8_422_UNORM_KHR,						VK_FORMAT_R8G8B8A8_UNORM		},
1034 		{ VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR,	VK_FORMAT_R16G16B16A16_UNORM	},
1035 		{ VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR,	VK_FORMAT_R16G16B16A16_UNORM	},
1036 		{ VK_FORMAT_B16G16R16G16_422_UNORM_KHR,					VK_FORMAT_R16G16B16A16_UNORM	}
1037 	};
1038 	auto it = std::find_if(std::begin(ycbcrFormats), std::end(ycbcrFormats), [result](const std::pair<vk::VkFormat, vk::VkFormat>& p) { return p.first == result; });
1039 	if (it != std::end(ycbcrFormats))
1040 		result = it->second;
1041 	return result;
1042 }
1043 
areLsb6BitsDontCare(vk::VkFormat format)1044 bool areLsb6BitsDontCare(vk::VkFormat format)
1045 {
1046 	if ((format == vk::VK_FORMAT_R10X6_UNORM_PACK16)                         ||
1047 		(format == vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16)                   ||
1048 		(format == vk::VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16)         ||
1049 		(format == vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16)     ||
1050 		(format == vk::VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16)     ||
1051 		(format == vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16)  ||
1052 		(format == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16) ||
1053 		(format == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16) ||
1054 		(format == vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16)  ||
1055 		(format == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16))
1056 	{
1057 		return true;
1058 	}
1059 
1060 	return false;
1061 }
1062 
areLsb4BitsDontCare(vk::VkFormat format)1063 bool areLsb4BitsDontCare(vk::VkFormat format)
1064 {
1065 	if ((format == vk::VK_FORMAT_R12X4_UNORM_PACK16)                         ||
1066 		(format == vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16)                   ||
1067 		(format == vk::VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16)         ||
1068 		(format == vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16)     ||
1069 		(format == vk::VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16)     ||
1070 		(format == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16) ||
1071 		(format == vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16)  ||
1072 		(format == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16) ||
1073 		(format == vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16)  ||
1074 		(format == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16))
1075 	{
1076 		return true;
1077 	}
1078 
1079 	return false;
1080 }
1081 
1082 } // sparse
1083 } // vkt
1084