• 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 
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)317 void submitCommands (const DeviceInterface&			vk,
318 					 const VkQueue					queue,
319 					 const VkCommandBuffer			commandBuffer,
320 					 const deUint32					waitSemaphoreCount,
321 					 const VkSemaphore*				pWaitSemaphores,
322 					 const VkPipelineStageFlags*	pWaitDstStageMask,
323 					 const deUint32					signalSemaphoreCount,
324 					 const VkSemaphore*				pSignalSemaphores)
325 {
326 	const VkSubmitInfo submitInfo =
327 	{
328 		VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType				sType;
329 		DE_NULL,						// const void*					pNext;
330 		waitSemaphoreCount,				// deUint32						waitSemaphoreCount;
331 		pWaitSemaphores,				// const VkSemaphore*			pWaitSemaphores;
332 		pWaitDstStageMask,				// const VkPipelineStageFlags*	pWaitDstStageMask;
333 		1u,								// deUint32						commandBufferCount;
334 		&commandBuffer,					// const VkCommandBuffer*		pCommandBuffers;
335 		signalSemaphoreCount,			// deUint32						signalSemaphoreCount;
336 		pSignalSemaphores,				// const VkSemaphore*			pSignalSemaphores;
337 	};
338 
339 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, DE_NULL));
340 }
341 
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)342 void submitCommandsAndWait (const DeviceInterface&		vk,
343 							const VkDevice				device,
344 							const VkQueue				queue,
345 							const VkCommandBuffer		commandBuffer,
346 							const deUint32				waitSemaphoreCount,
347 							const VkSemaphore*			pWaitSemaphores,
348 							const VkPipelineStageFlags*	pWaitDstStageMask,
349 							const deUint32				signalSemaphoreCount,
350 							const VkSemaphore*			pSignalSemaphores,
351 							const bool					useDeviceGroups,
352 							const deUint32				physicalDeviceID)
353 {
354 	const VkFenceCreateInfo	fenceParams				=
355 	{
356 		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,				// VkStructureType		sType;
357 		DE_NULL,											// const void*			pNext;
358 		0u,													// VkFenceCreateFlags	flags;
359 	};
360 	const Unique<VkFence>	fence(createFence		(vk, device, &fenceParams));
361 
362 	const deUint32			deviceMask				= 1 << physicalDeviceID;
363 	std::vector<deUint32>	deviceIndices			(waitSemaphoreCount, physicalDeviceID);
364 	VkDeviceGroupSubmitInfo deviceGroupSubmitInfo	=
365 	{
366 		VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO,			//VkStructureType		sType
367 		DE_NULL,											// const void*			pNext
368 		waitSemaphoreCount,									// uint32_t				waitSemaphoreCount
369 		deviceIndices.size() ? &deviceIndices[0] : DE_NULL,	// const uint32_t*		pWaitSemaphoreDeviceIndices
370 		1u,													// uint32_t				commandBufferCount
371 		&deviceMask,										// const uint32_t*		pCommandBufferDeviceMasks
372 		0u,													// uint32_t				signalSemaphoreCount
373 		DE_NULL,											// const uint32_t*		pSignalSemaphoreDeviceIndices
374 	};
375 	const VkSubmitInfo		submitInfo				=
376 	{
377 		VK_STRUCTURE_TYPE_SUBMIT_INFO,						// VkStructureType				sType;
378 		useDeviceGroups ? &deviceGroupSubmitInfo : DE_NULL,	// const void*					pNext;
379 		waitSemaphoreCount,									// deUint32						waitSemaphoreCount;
380 		pWaitSemaphores,									// const VkSemaphore*			pWaitSemaphores;
381 		pWaitDstStageMask,									// const VkPipelineStageFlags*	pWaitDstStageMask;
382 		1u,													// deUint32						commandBufferCount;
383 		&commandBuffer,										// const VkCommandBuffer*		pCommandBuffers;
384 		signalSemaphoreCount,								// deUint32						signalSemaphoreCount;
385 		pSignalSemaphores,									// const VkSemaphore*			pSignalSemaphores;
386 	};
387 
388 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
389 	VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull));
390 }
391 
mapImageType(const ImageType imageType)392 VkImageType	mapImageType (const ImageType imageType)
393 {
394 	switch (imageType)
395 	{
396 		case IMAGE_TYPE_1D:
397 		case IMAGE_TYPE_1D_ARRAY:
398 		case IMAGE_TYPE_BUFFER:
399 			return VK_IMAGE_TYPE_1D;
400 
401 		case IMAGE_TYPE_2D:
402 		case IMAGE_TYPE_2D_ARRAY:
403 		case IMAGE_TYPE_CUBE:
404 		case IMAGE_TYPE_CUBE_ARRAY:
405 			return VK_IMAGE_TYPE_2D;
406 
407 		case IMAGE_TYPE_3D:
408 			return VK_IMAGE_TYPE_3D;
409 
410 		default:
411 			DE_FATAL("Unexpected image type");
412 			return VK_IMAGE_TYPE_LAST;
413 	}
414 }
415 
mapImageViewType(const ImageType imageType)416 VkImageViewType	mapImageViewType (const ImageType imageType)
417 {
418 	switch (imageType)
419 	{
420 		case IMAGE_TYPE_1D:			return VK_IMAGE_VIEW_TYPE_1D;
421 		case IMAGE_TYPE_1D_ARRAY:	return VK_IMAGE_VIEW_TYPE_1D_ARRAY;
422 		case IMAGE_TYPE_2D:			return VK_IMAGE_VIEW_TYPE_2D;
423 		case IMAGE_TYPE_2D_ARRAY:	return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
424 		case IMAGE_TYPE_3D:			return VK_IMAGE_VIEW_TYPE_3D;
425 		case IMAGE_TYPE_CUBE:		return VK_IMAGE_VIEW_TYPE_CUBE;
426 		case IMAGE_TYPE_CUBE_ARRAY:	return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
427 
428 		default:
429 			DE_FATAL("Unexpected image type");
430 			return VK_IMAGE_VIEW_TYPE_LAST;
431 	}
432 }
433 
getImageTypeName(const ImageType imageType)434 std::string getImageTypeName (const ImageType imageType)
435 {
436 	switch (imageType)
437 	{
438 		case IMAGE_TYPE_1D:			return "1d";
439 		case IMAGE_TYPE_1D_ARRAY:	return "1d_array";
440 		case IMAGE_TYPE_2D:			return "2d";
441 		case IMAGE_TYPE_2D_ARRAY:	return "2d_array";
442 		case IMAGE_TYPE_3D:			return "3d";
443 		case IMAGE_TYPE_CUBE:		return "cube";
444 		case IMAGE_TYPE_CUBE_ARRAY:	return "cube_array";
445 		case IMAGE_TYPE_BUFFER:		return "buffer";
446 
447 		default:
448 			DE_FATAL("Unexpected image type");
449 			return "";
450 	}
451 }
452 
getShaderImageType(const tcu::TextureFormat & format,const ImageType imageType)453 std::string getShaderImageType (const tcu::TextureFormat& format, const ImageType imageType)
454 {
455 	std::string formatPart = tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ? "u" :
456 							 tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER   ? "i" : "";
457 
458 	std::string imageTypePart;
459 	switch (imageType)
460 	{
461 		case IMAGE_TYPE_1D:			imageTypePart = "1D";			break;
462 		case IMAGE_TYPE_1D_ARRAY:	imageTypePart = "1DArray";		break;
463 		case IMAGE_TYPE_2D:			imageTypePart = "2D";			break;
464 		case IMAGE_TYPE_2D_ARRAY:	imageTypePart = "2DArray";		break;
465 		case IMAGE_TYPE_3D:			imageTypePart = "3D";			break;
466 		case IMAGE_TYPE_CUBE:		imageTypePart = "Cube";			break;
467 		case IMAGE_TYPE_CUBE_ARRAY:	imageTypePart = "CubeArray";	break;
468 		case IMAGE_TYPE_BUFFER:		imageTypePart = "Buffer";		break;
469 
470 		default:
471 			DE_FATAL("Unexpected image type");
472 	}
473 
474 	return formatPart + "image" + imageTypePart;
475 }
476 
getShaderImageType(const vk::PlanarFormatDescription & description,const ImageType imageType)477 std::string getShaderImageType (const vk::PlanarFormatDescription& description, const ImageType imageType)
478 {
479 	std::string	formatPart;
480 	std::string	imageTypePart;
481 
482 	// all PlanarFormatDescription types have at least one channel ( 0 ) and all channel types are the same :
483 	switch (description.channels[0].type)
484 	{
485 		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
486 			formatPart = "i";
487 			break;
488 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
489 			formatPart = "u";
490 			break;
491 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
492 		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
493 		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
494 			break;
495 
496 		default:
497 			DE_FATAL("Unexpected channel type");
498 	}
499 
500 	if (formatIsR64(description.planes[0].planeCompatibleFormat))
501 		formatPart += "64";
502 
503 	switch (imageType)
504 	{
505 		case IMAGE_TYPE_1D:			imageTypePart = "1D";			break;
506 		case IMAGE_TYPE_1D_ARRAY:	imageTypePart = "1DArray";		break;
507 		case IMAGE_TYPE_2D:			imageTypePart = "2D";			break;
508 		case IMAGE_TYPE_2D_ARRAY:	imageTypePart = "2DArray";		break;
509 		case IMAGE_TYPE_3D:			imageTypePart = "3D";			break;
510 		case IMAGE_TYPE_CUBE:		imageTypePart = "Cube";			break;
511 		case IMAGE_TYPE_CUBE_ARRAY:	imageTypePart = "CubeArray";	break;
512 		case IMAGE_TYPE_BUFFER:		imageTypePart = "Buffer";		break;
513 
514 		default:
515 			DE_FATAL("Unexpected image type");
516 	}
517 
518 	return formatPart + "image" + imageTypePart;
519 }
520 
getShaderImageDataType(const tcu::TextureFormat & format)521 std::string getShaderImageDataType(const tcu::TextureFormat& format)
522 {
523 	switch (tcu::getTextureChannelClass(format.type))
524 	{
525 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
526 			return "uvec4";
527 		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
528 			return "ivec4";
529 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
530 		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
531 		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
532 			return "vec4";
533 		default:
534 			DE_FATAL("Unexpected channel type");
535 			return "";
536 	}
537 }
538 
getShaderImageDataType(const vk::PlanarFormatDescription & description)539 std::string getShaderImageDataType (const vk::PlanarFormatDescription& description)
540 {
541 	switch (description.channels[0].type)
542 	{
543 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
544 			return (formatIsR64(description.planes[0].planeCompatibleFormat) ? "u64vec4" : "uvec4");
545 		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
546 			return (formatIsR64(description.planes[0].planeCompatibleFormat) ? "i64vec4" : "ivec4");
547 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
548 		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
549 		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
550 			return "vec4";
551 		default:
552 			DE_FATAL("Unexpected channel type");
553 			return "";
554 	}
555 }
556 
getShaderImageFormatQualifier(const tcu::TextureFormat & format)557 std::string getShaderImageFormatQualifier (const tcu::TextureFormat& format)
558 {
559 	const char* orderPart;
560 	const char* typePart;
561 
562 	switch (format.order)
563 	{
564 		case tcu::TextureFormat::R:		orderPart = "r";	break;
565 		case tcu::TextureFormat::RG:	orderPart = "rg";	break;
566 		case tcu::TextureFormat::RGB:	orderPart = "rgb";	break;
567 		case tcu::TextureFormat::RGBA:	orderPart = "rgba";	break;
568 
569 		default:
570 			DE_FATAL("Unexpected channel order");
571 			orderPart = DE_NULL;
572 	}
573 
574 	switch (format.type)
575 	{
576 		case tcu::TextureFormat::FLOAT:				typePart = "32f";		break;
577 		case tcu::TextureFormat::HALF_FLOAT:		typePart = "16f";		break;
578 
579 		case tcu::TextureFormat::UNSIGNED_INT32:	typePart = "32ui";		break;
580 		case tcu::TextureFormat::UNSIGNED_INT16:	typePart = "16ui";		break;
581 		case tcu::TextureFormat::UNSIGNED_INT8:		typePart = "8ui";		break;
582 
583 		case tcu::TextureFormat::SIGNED_INT32:		typePart = "32i";		break;
584 		case tcu::TextureFormat::SIGNED_INT16:		typePart = "16i";		break;
585 		case tcu::TextureFormat::SIGNED_INT8:		typePart = "8i";		break;
586 
587 		case tcu::TextureFormat::UNORM_INT16:		typePart = "16";		break;
588 		case tcu::TextureFormat::UNORM_INT8:		typePart = "8";			break;
589 
590 		case tcu::TextureFormat::SNORM_INT16:		typePart = "16_snorm";	break;
591 		case tcu::TextureFormat::SNORM_INT8:		typePart = "8_snorm";	break;
592 
593 		default:
594 			DE_FATAL("Unexpected channel type");
595 			typePart = DE_NULL;
596 	}
597 
598 	return std::string() + orderPart + typePart;
599 }
600 
getShaderImageFormatQualifier(VkFormat format)601 std::string getShaderImageFormatQualifier (VkFormat format)
602 {
603 	switch (format)
604 	{
605 		case VK_FORMAT_R8_SINT:										return "r8i";
606 		case VK_FORMAT_R16_SINT:									return "r16i";
607 		case VK_FORMAT_R32_SINT:									return "r32i";
608 		case VK_FORMAT_R64_SINT:									return "r64i";
609 		case VK_FORMAT_R8_UINT:										return "r8ui";
610 		case VK_FORMAT_R16_UINT:									return "r16ui";
611 		case VK_FORMAT_R32_UINT:									return "r32ui";
612 		case VK_FORMAT_R64_UINT:									return "r64ui";
613 		case VK_FORMAT_R8_SNORM:									return "r8_snorm";
614 		case VK_FORMAT_R16_SNORM:									return "r16_snorm";
615 		case VK_FORMAT_R8_UNORM:									return "r8";
616 		case VK_FORMAT_R16_UNORM:									return "r16";
617 
618 		case VK_FORMAT_R8G8_SINT:									return "rg8i";
619 		case VK_FORMAT_R16G16_SINT:									return "rg16i";
620 		case VK_FORMAT_R32G32_SINT:									return "rg32i";
621 		case VK_FORMAT_R8G8_UINT:									return "rg8ui";
622 		case VK_FORMAT_R16G16_UINT:									return "rg16ui";
623 		case VK_FORMAT_R32G32_UINT:									return "rg32ui";
624 		case VK_FORMAT_R8G8_SNORM:									return "rg8_snorm";
625 		case VK_FORMAT_R16G16_SNORM:								return "rg16_snorm";
626 		case VK_FORMAT_R8G8_UNORM:									return "rg8";
627 		case VK_FORMAT_R16G16_UNORM:								return "rg16";
628 
629 		case VK_FORMAT_R8G8B8A8_SINT:								return "rgba8i";
630 		case VK_FORMAT_R16G16B16A16_SINT:							return "rgba16i";
631 		case VK_FORMAT_R32G32B32A32_SINT:							return "rgba32i";
632 		case VK_FORMAT_R8G8B8A8_UINT:								return "rgba8ui";
633 		case VK_FORMAT_R16G16B16A16_UINT:							return "rgba16ui";
634 		case VK_FORMAT_R32G32B32A32_UINT:							return "rgba32ui";
635 		case VK_FORMAT_R8G8B8A8_SNORM:								return "rgba8_snorm";
636 		case VK_FORMAT_R16G16B16A16_SNORM:							return "rgba16_snorm";
637 		case VK_FORMAT_R8G8B8A8_UNORM:								return "rgba8";
638 		case VK_FORMAT_R16G16B16A16_UNORM:							return "rgba16";
639 
640 		case VK_FORMAT_G8B8G8R8_422_UNORM:							return "rgba8";
641 		case VK_FORMAT_B8G8R8G8_422_UNORM:							return "rgba8";
642 		case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:					return "rgba8";
643 		case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:					return "rgba8";
644 		case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:					return "rgba8";
645 		case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:					return "rgba8";
646 		case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:					return "rgba8";
647 		case VK_FORMAT_R10X6_UNORM_PACK16:							return "r16";
648 		case VK_FORMAT_R10X6G10X6_UNORM_2PACK16:					return "rg16";
649 		case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:			return "rgba16";
650 		case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:		return "rgba16";
651 		case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:		return "rgba16";
652 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:	return "rgba16";
653 		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:	return "rgba16";
654 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:	return "rgba16";
655 		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:	return "rgba16";
656 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:	return "rgba16";
657 		case VK_FORMAT_R12X4_UNORM_PACK16:							return "r16";
658 		case VK_FORMAT_R12X4G12X4_UNORM_2PACK16:					return "rg16";
659 		case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:			return "rgba16";
660 		case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:		return "rgba16";
661 		case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:		return "rgba16";
662 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:	return "rgba16";
663 		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:	return "rgba16";
664 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:	return "rgba16";
665 		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:	return "rgba16";
666 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:	return "rgba16";
667 		case VK_FORMAT_G16B16G16R16_422_UNORM:						return "rgba16";
668 		case VK_FORMAT_B16G16R16G16_422_UNORM:						return "rgba16";
669 		case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:				return "rgba16";
670 		case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:					return "rgba16";
671 		case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:				return "rgba16";
672 		case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:					return "rgba16";
673 		case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:				return "rgba16";
674 		case VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT:				return "rgba8";
675 		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT:return "rgba16";
676 		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT:return "rgba16";
677 		case VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT:				return "rgba16";
678 
679 		default:
680 			DE_FATAL("Unexpected texture format");
681 			return "error";
682 	}
683 }
684 
getImageFormatID(VkFormat format)685 std::string getImageFormatID (VkFormat format)
686 {
687 	switch (format)
688 	{
689 		case VK_FORMAT_R8_SINT:				return "r8i";
690 		case VK_FORMAT_R16_SINT:			return "r16i";
691 		case VK_FORMAT_R32_SINT:			return "r32i";
692 		case VK_FORMAT_R64_SINT:			return "r64i";
693 		case VK_FORMAT_R8_UINT:				return "r8ui";
694 		case VK_FORMAT_R16_UINT:			return "r16ui";
695 		case VK_FORMAT_R32_UINT:			return "r32ui";
696 		case VK_FORMAT_R64_UINT:			return "r64ui";
697 		case VK_FORMAT_R8_SNORM:			return "r8_snorm";
698 		case VK_FORMAT_R16_SNORM:			return "r16_snorm";
699 		case VK_FORMAT_R8_UNORM:			return "r8";
700 		case VK_FORMAT_R16_UNORM:			return "r16";
701 
702 		case VK_FORMAT_R8G8_SINT:			return "rg8i";
703 		case VK_FORMAT_R16G16_SINT:			return "rg16i";
704 		case VK_FORMAT_R32G32_SINT:			return "rg32i";
705 		case VK_FORMAT_R8G8_UINT:			return "rg8ui";
706 		case VK_FORMAT_R16G16_UINT:			return "rg16ui";
707 		case VK_FORMAT_R32G32_UINT:			return "rg32ui";
708 		case VK_FORMAT_R8G8_SNORM:			return "rg8_snorm";
709 		case VK_FORMAT_R16G16_SNORM:		return "rg16_snorm";
710 		case VK_FORMAT_R8G8_UNORM:			return "rg8";
711 		case VK_FORMAT_R16G16_UNORM:		return "rg16";
712 
713 		case VK_FORMAT_R8G8B8A8_SINT:		return "rgba8i";
714 		case VK_FORMAT_R16G16B16A16_SINT:	return "rgba16i";
715 		case VK_FORMAT_R32G32B32A32_SINT:	return "rgba32i";
716 		case VK_FORMAT_R8G8B8A8_UINT:		return "rgba8ui";
717 		case VK_FORMAT_R16G16B16A16_UINT:	return "rgba16ui";
718 		case VK_FORMAT_R32G32B32A32_UINT:	return "rgba32ui";
719 		case VK_FORMAT_R8G8B8A8_SNORM:		return "rgba8_snorm";
720 		case VK_FORMAT_R16G16B16A16_SNORM:	return "rgba16_snorm";
721 		case VK_FORMAT_R8G8B8A8_UNORM:		return "rgba8";
722 		case VK_FORMAT_R16G16B16A16_UNORM:	return "rgba16";
723 
724 		case VK_FORMAT_G8B8G8R8_422_UNORM:
725 		case VK_FORMAT_B8G8R8G8_422_UNORM:
726 		case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
727 		case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
728 		case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
729 		case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
730 		case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
731 		case VK_FORMAT_R10X6_UNORM_PACK16:
732 		case VK_FORMAT_R10X6G10X6_UNORM_2PACK16:
733 		case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:
734 		case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
735 		case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
736 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
737 		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
738 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
739 		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
740 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
741 		case VK_FORMAT_R12X4_UNORM_PACK16:
742 		case VK_FORMAT_R12X4G12X4_UNORM_2PACK16:
743 		case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:
744 		case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
745 		case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
746 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
747 		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
748 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
749 		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
750 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
751 		case VK_FORMAT_G16B16G16R16_422_UNORM:
752 		case VK_FORMAT_B16G16R16G16_422_UNORM:
753 		case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
754 		case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
755 		case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
756 		case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
757 		case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
758 		case VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT:
759 		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT:
760 		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT:
761 		case VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT:
762 			return de::toLower(std::string(getFormatName(format)).substr(10));
763 
764 		default:
765 			DE_FATAL("Unexpected texture format");
766 			return "error";
767 	}
768 }
769 
getShaderImageCoordinates(const ImageType imageType,const std::string & x,const std::string & xy,const std::string & xyz)770 std::string getShaderImageCoordinates	(const ImageType	imageType,
771 										 const std::string&	x,
772 										 const std::string&	xy,
773 										 const std::string&	xyz)
774 {
775 	switch (imageType)
776 	{
777 		case IMAGE_TYPE_1D:
778 		case IMAGE_TYPE_BUFFER:
779 			return x;
780 
781 		case IMAGE_TYPE_1D_ARRAY:
782 		case IMAGE_TYPE_2D:
783 			return xy;
784 
785 		case IMAGE_TYPE_2D_ARRAY:
786 		case IMAGE_TYPE_3D:
787 		case IMAGE_TYPE_CUBE:
788 		case IMAGE_TYPE_CUBE_ARRAY:
789 			return xyz;
790 
791 		default:
792 			DE_FATAL("Unexpected image type");
793 			return "";
794 	}
795 }
796 
getImageMipLevelSizeInBytes(const VkExtent3D & baseExtents,const deUint32 layersCount,const tcu::TextureFormat & format,const deUint32 mipmapLevel,const deUint32 mipmapMemoryAlignment)797 deUint32 getImageMipLevelSizeInBytes(const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevel, const deUint32 mipmapMemoryAlignment)
798 {
799 	const VkExtent3D extents = mipLevelExtents(baseExtents, mipmapLevel);
800 
801 	return deAlign32(extents.width * extents.height * extents.depth * layersCount * tcu::getPixelSize(format), mipmapMemoryAlignment);
802 }
803 
getImageSizeInBytes(const VkExtent3D & baseExtents,const deUint32 layersCount,const tcu::TextureFormat & format,const deUint32 mipmapLevelsCount,const deUint32 mipmapMemoryAlignment)804 deUint32 getImageSizeInBytes(const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevelsCount, const deUint32 mipmapMemoryAlignment)
805 {
806 	deUint32 imageSizeInBytes = 0;
807 	for (deUint32 mipmapLevel = 0; mipmapLevel < mipmapLevelsCount; ++mipmapLevel)
808 		imageSizeInBytes += getImageMipLevelSizeInBytes(baseExtents, layersCount, format, mipmapLevel, mipmapMemoryAlignment);
809 
810 	return imageSizeInBytes;
811 }
812 
getImageMipLevelSizeInBytes(const VkExtent3D & baseExtents,const deUint32 layersCount,const vk::PlanarFormatDescription & formatDescription,const deUint32 planeNdx,const deUint32 mipmapLevel,const deUint32 mipmapMemoryAlignment)813 deUint32 getImageMipLevelSizeInBytes (const VkExtent3D& baseExtents, const deUint32 layersCount, const vk::PlanarFormatDescription& formatDescription, const deUint32 planeNdx, const deUint32 mipmapLevel, const deUint32 mipmapMemoryAlignment)
814 {
815 	return layersCount * getPlaneSizeInBytes(formatDescription, baseExtents, planeNdx, mipmapLevel, mipmapMemoryAlignment);
816 }
817 
getImageSizeInBytes(const VkExtent3D & baseExtents,const deUint32 layersCount,const vk::PlanarFormatDescription & formatDescription,const deUint32 planeNdx,const deUint32 mipmapLevelsCount,const deUint32 mipmapMemoryAlignment)818 deUint32 getImageSizeInBytes (const VkExtent3D& baseExtents, const deUint32 layersCount, const vk::PlanarFormatDescription& formatDescription, const deUint32 planeNdx, const deUint32 mipmapLevelsCount, const deUint32 mipmapMemoryAlignment)
819 {
820 	deUint32 imageSizeInBytes = 0;
821 
822 	for (deUint32 mipmapLevel = 0; mipmapLevel < mipmapLevelsCount; ++mipmapLevel)
823 		imageSizeInBytes += getImageMipLevelSizeInBytes(baseExtents, layersCount, formatDescription, planeNdx, mipmapLevel, mipmapMemoryAlignment);
824 
825 	return imageSizeInBytes;
826 }
827 
makeSparseImageMemoryBind(const DeviceInterface & vk,const VkDevice device,const VkDeviceSize allocationSize,const deUint32 memoryType,const VkImageSubresource & subresource,const VkOffset3D & offset,const VkExtent3D & extent)828 VkSparseImageMemoryBind	makeSparseImageMemoryBind  (const DeviceInterface&			vk,
829 													const VkDevice					device,
830 													const VkDeviceSize				allocationSize,
831 													const deUint32					memoryType,
832 													const VkImageSubresource&		subresource,
833 													const VkOffset3D&				offset,
834 													const VkExtent3D&				extent)
835 {
836 	const VkMemoryAllocateInfo	allocInfo =
837 	{
838 		VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,	//	VkStructureType			sType;
839 		DE_NULL,								//	const void*				pNext;
840 		allocationSize,							//	VkDeviceSize			allocationSize;
841 		memoryType,								//	deUint32				memoryTypeIndex;
842 	};
843 
844 	VkDeviceMemory deviceMemory = 0;
845 	VK_CHECK(vk.allocateMemory(device, &allocInfo, DE_NULL, &deviceMemory));
846 
847 	VkSparseImageMemoryBind imageMemoryBind;
848 
849 	imageMemoryBind.subresource		= subresource;
850 	imageMemoryBind.memory			= deviceMemory;
851 	imageMemoryBind.memoryOffset	= 0u;
852 	imageMemoryBind.flags			= 0u;
853 	imageMemoryBind.offset			= offset;
854 	imageMemoryBind.extent			= extent;
855 
856 	return imageMemoryBind;
857 }
858 
makeSparseMemoryBind(const DeviceInterface & vk,const VkDevice device,const VkDeviceSize allocationSize,const deUint32 memoryType,const VkDeviceSize resourceOffset,const VkSparseMemoryBindFlags flags)859 VkSparseMemoryBind makeSparseMemoryBind	(const DeviceInterface&			vk,
860 										 const VkDevice					device,
861 										 const VkDeviceSize				allocationSize,
862 										 const deUint32					memoryType,
863 										 const VkDeviceSize				resourceOffset,
864 										 const VkSparseMemoryBindFlags	flags)
865 {
866 	const VkMemoryAllocateInfo allocInfo =
867 	{
868 		VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,	//	VkStructureType	sType;
869 		DE_NULL,								//	const void*		pNext;
870 		allocationSize,							//	VkDeviceSize	allocationSize;
871 		memoryType,								//	deUint32		memoryTypeIndex;
872 	};
873 
874 	VkDeviceMemory deviceMemory = 0;
875 	VK_CHECK(vk.allocateMemory(device, &allocInfo, DE_NULL, &deviceMemory));
876 
877 	VkSparseMemoryBind memoryBind;
878 
879 	memoryBind.resourceOffset	= resourceOffset;
880 	memoryBind.size				= allocationSize;
881 	memoryBind.memory			= deviceMemory;
882 	memoryBind.memoryOffset		= 0u;
883 	memoryBind.flags			= flags;
884 
885 	return memoryBind;
886 }
887 
requireFeatures(const InstanceInterface & vki,const VkPhysicalDevice physDevice,const FeatureFlags flags)888 void requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags)
889 {
890 	const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
891 
892 	if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
893 		throw tcu::NotSupportedError("Tessellation shader not supported");
894 
895 	if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
896 		throw tcu::NotSupportedError("Geometry shader not supported");
897 
898 	if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
899 		throw tcu::NotSupportedError("Double-precision floats not supported");
900 
901 	if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
902 		throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
903 
904 	if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
905 		throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
906 
907 	if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize)
908 		throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in");
909 }
910 
findMatchingMemoryType(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const VkMemoryRequirements & objectMemoryRequirements,const MemoryRequirement & memoryRequirement)911 deUint32 findMatchingMemoryType (const InstanceInterface&		instance,
912 								 const VkPhysicalDevice			physicalDevice,
913 								 const VkMemoryRequirements&	objectMemoryRequirements,
914 								 const MemoryRequirement&		memoryRequirement)
915 {
916 	const VkPhysicalDeviceMemoryProperties deviceMemoryProperties = getPhysicalDeviceMemoryProperties(instance, physicalDevice);
917 
918 	for (deUint32 memoryTypeNdx = 0; memoryTypeNdx < deviceMemoryProperties.memoryTypeCount; ++memoryTypeNdx)
919 	{
920 		if ((objectMemoryRequirements.memoryTypeBits & (1u << memoryTypeNdx)) != 0 &&
921 			memoryRequirement.matchesHeap(deviceMemoryProperties.memoryTypes[memoryTypeNdx].propertyFlags))
922 		{
923 			return memoryTypeNdx;
924 		}
925 	}
926 
927 	return NO_MATCH_FOUND;
928 }
929 
getHeapIndexForMemoryType(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const deUint32 memoryType)930 deUint32 getHeapIndexForMemoryType (const InstanceInterface&	instance,
931 									const VkPhysicalDevice		physicalDevice,
932 									const deUint32				memoryType)
933 {
934 	const VkPhysicalDeviceMemoryProperties deviceMemoryProperties = getPhysicalDeviceMemoryProperties(instance, physicalDevice);
935 	DE_ASSERT(memoryType < deviceMemoryProperties.memoryTypeCount);
936 	return deviceMemoryProperties.memoryTypes[memoryType].heapIndex;
937 }
938 
checkSparseSupportForImageType(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const ImageType imageType)939 bool checkSparseSupportForImageType (const InstanceInterface&	instance,
940 									 const VkPhysicalDevice		physicalDevice,
941 									 const ImageType			imageType)
942 {
943 	const VkPhysicalDeviceFeatures deviceFeatures = getPhysicalDeviceFeatures(instance, physicalDevice);
944 
945 	if (!deviceFeatures.sparseBinding)
946 		return false;
947 
948 	switch (mapImageType(imageType))
949 	{
950 		case VK_IMAGE_TYPE_2D:
951 			return deviceFeatures.sparseResidencyImage2D == VK_TRUE;
952 		case VK_IMAGE_TYPE_3D:
953 			return deviceFeatures.sparseResidencyImage3D == VK_TRUE;
954 		default:
955 			DE_FATAL("Unexpected image type");
956 			return false;
957 	}
958 }
959 
checkSparseSupportForImageFormat(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const VkImageCreateInfo & imageInfo)960 bool checkSparseSupportForImageFormat (const InstanceInterface&	instance,
961 									   const VkPhysicalDevice	physicalDevice,
962 									   const VkImageCreateInfo&	imageInfo)
963 {
964 	const std::vector<VkSparseImageFormatProperties> sparseImageFormatPropVec = getPhysicalDeviceSparseImageFormatProperties(
965 		instance, physicalDevice, imageInfo.format, imageInfo.imageType, imageInfo.samples, imageInfo.usage, imageInfo.tiling);
966 
967 	return sparseImageFormatPropVec.size() > 0u;
968 }
969 
checkImageFormatFeatureSupport(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const VkFormat format,const VkFormatFeatureFlags featureFlags)970 bool checkImageFormatFeatureSupport (const InstanceInterface&	instance,
971 									 const VkPhysicalDevice		physicalDevice,
972 									 const VkFormat				format,
973 									 const VkFormatFeatureFlags	featureFlags)
974 {
975 	const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(instance, physicalDevice, format);
976 
977 	return (formatProperties.optimalTilingFeatures & featureFlags) == featureFlags;
978 }
979 
getSparseAspectRequirementsIndex(const std::vector<VkSparseImageMemoryRequirements> & requirements,const VkImageAspectFlags aspectFlags)980 deUint32 getSparseAspectRequirementsIndex (const std::vector<VkSparseImageMemoryRequirements>&	requirements,
981 										   const VkImageAspectFlags								aspectFlags)
982 {
983 	for (deUint32 memoryReqNdx = 0; memoryReqNdx < requirements.size(); ++memoryReqNdx)
984 	{
985 		if (requirements[memoryReqNdx].formatProperties.aspectMask & aspectFlags)
986 			return memoryReqNdx;
987 	}
988 
989 	return NO_MATCH_FOUND;
990 }
991 
getPlaneCompatibleFormatForWriting(const vk::PlanarFormatDescription & formatInfo,deUint32 planeNdx)992 vk::VkFormat getPlaneCompatibleFormatForWriting(const vk::PlanarFormatDescription& formatInfo, deUint32 planeNdx)
993 {
994 	DE_ASSERT(planeNdx < formatInfo.numPlanes);
995 	vk::VkFormat result = formatInfo.planes[planeNdx].planeCompatibleFormat;
996 
997 	// redirect result for some of the YCbCr image formats
998 	static const std::pair<vk::VkFormat, vk::VkFormat> ycbcrFormats[] =
999 	{
1000 		{ VK_FORMAT_G8B8G8R8_422_UNORM,						VK_FORMAT_R8G8B8A8_UNORM		},
1001 		{ VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16,	VK_FORMAT_R16G16B16A16_UNORM	},
1002 		{ VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16,	VK_FORMAT_R16G16B16A16_UNORM	},
1003 		{ VK_FORMAT_G16B16G16R16_422_UNORM,					VK_FORMAT_R16G16B16A16_UNORM	},
1004 		{ VK_FORMAT_B8G8R8G8_422_UNORM,						VK_FORMAT_R8G8B8A8_UNORM		},
1005 		{ VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16,	VK_FORMAT_R16G16B16A16_UNORM	},
1006 		{ VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16,	VK_FORMAT_R16G16B16A16_UNORM	},
1007 		{ VK_FORMAT_B16G16R16G16_422_UNORM,					VK_FORMAT_R16G16B16A16_UNORM	}
1008 	};
1009 	auto it = std::find_if(std::begin(ycbcrFormats), std::end(ycbcrFormats), [result](const std::pair<vk::VkFormat, vk::VkFormat>& p) { return p.first == result; });
1010 	if (it != std::end(ycbcrFormats))
1011 		result = it->second;
1012 	return result;
1013 }
1014 
areLsb6BitsDontCare(vk::VkFormat format)1015 bool areLsb6BitsDontCare(vk::VkFormat format)
1016 {
1017 	if ((format == vk::VK_FORMAT_R10X6_UNORM_PACK16)                         ||
1018 		(format == vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16)                   ||
1019 		(format == vk::VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16)         ||
1020 		(format == vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16)     ||
1021 		(format == vk::VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16)     ||
1022 		(format == vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16)  ||
1023 		(format == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16) ||
1024 		(format == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16) ||
1025 		(format == vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16)  ||
1026 		(format == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16))
1027 	{
1028 		return true;
1029 	}
1030 
1031 	return false;
1032 }
1033 
areLsb4BitsDontCare(vk::VkFormat format)1034 bool areLsb4BitsDontCare(vk::VkFormat format)
1035 {
1036 	if ((format == vk::VK_FORMAT_R12X4_UNORM_PACK16)                         ||
1037 		(format == vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16)                   ||
1038 		(format == vk::VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16)         ||
1039 		(format == vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16)     ||
1040 		(format == vk::VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16)     ||
1041 		(format == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16) ||
1042 		(format == vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16)  ||
1043 		(format == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16) ||
1044 		(format == vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16)  ||
1045 		(format == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16))
1046 	{
1047 		return true;
1048 	}
1049 
1050 	return false;
1051 }
1052 
1053 } // sparse
1054 } // vkt
1055