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