• 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  vktPipelineMultisampleTestsUtil.cpp
21  * \brief Multisample Tests Utility Classes
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktPipelineMultisampleTestsUtil.hpp"
25 #include "vkQueryUtil.hpp"
26 #include "vkTypeUtil.hpp"
27 #include "tcuTextureUtil.hpp"
28 
29 #include <deMath.h>
30 
31 using namespace vk;
32 
33 namespace vkt
34 {
35 namespace pipeline
36 {
37 namespace multisample
38 {
39 
getShaderGridSize(const ImageType imageType,const tcu::UVec3 & imageSize,const deUint32 mipLevel)40 tcu::UVec3 getShaderGridSize (const ImageType imageType, const tcu::UVec3& imageSize, const deUint32 mipLevel)
41 {
42 	const deUint32 mipLevelX = std::max(imageSize.x() >> mipLevel, 1u);
43 	const deUint32 mipLevelY = std::max(imageSize.y() >> mipLevel, 1u);
44 	const deUint32 mipLevelZ = std::max(imageSize.z() >> mipLevel, 1u);
45 
46 	switch (imageType)
47 	{
48 	case IMAGE_TYPE_1D:
49 		return tcu::UVec3(mipLevelX, 1u, 1u);
50 
51 	case IMAGE_TYPE_BUFFER:
52 		return tcu::UVec3(imageSize.x(), 1u, 1u);
53 
54 	case IMAGE_TYPE_1D_ARRAY:
55 		return tcu::UVec3(mipLevelX, imageSize.z(), 1u);
56 
57 	case IMAGE_TYPE_2D:
58 		return tcu::UVec3(mipLevelX, mipLevelY, 1u);
59 
60 	case IMAGE_TYPE_2D_ARRAY:
61 		return tcu::UVec3(mipLevelX, mipLevelY, imageSize.z());
62 
63 	case IMAGE_TYPE_3D:
64 		return tcu::UVec3(mipLevelX, mipLevelY, mipLevelZ);
65 
66 	case IMAGE_TYPE_CUBE:
67 		return tcu::UVec3(mipLevelX, mipLevelY, 6u);
68 
69 	case IMAGE_TYPE_CUBE_ARRAY:
70 		return tcu::UVec3(mipLevelX, mipLevelY, 6u * imageSize.z());
71 
72 	default:
73 		DE_FATAL("Unknown image type");
74 		return tcu::UVec3(1u, 1u, 1u);
75 	}
76 }
77 
getLayerSize(const ImageType imageType,const tcu::UVec3 & imageSize)78 tcu::UVec3 getLayerSize (const ImageType imageType, const tcu::UVec3& imageSize)
79 {
80 	switch (imageType)
81 	{
82 	case IMAGE_TYPE_1D:
83 	case IMAGE_TYPE_1D_ARRAY:
84 	case IMAGE_TYPE_BUFFER:
85 		return tcu::UVec3(imageSize.x(), 1u, 1u);
86 
87 	case IMAGE_TYPE_2D:
88 	case IMAGE_TYPE_2D_ARRAY:
89 	case IMAGE_TYPE_CUBE:
90 	case IMAGE_TYPE_CUBE_ARRAY:
91 		return tcu::UVec3(imageSize.x(), imageSize.y(), 1u);
92 
93 	case IMAGE_TYPE_3D:
94 		return tcu::UVec3(imageSize.x(), imageSize.y(), imageSize.z());
95 
96 	default:
97 		DE_FATAL("Unknown image type");
98 		return tcu::UVec3(1u, 1u, 1u);
99 	}
100 }
101 
getNumLayers(const ImageType imageType,const tcu::UVec3 & imageSize)102 deUint32 getNumLayers (const ImageType imageType, const tcu::UVec3& imageSize)
103 {
104 	switch (imageType)
105 	{
106 	case IMAGE_TYPE_1D:
107 	case IMAGE_TYPE_2D:
108 	case IMAGE_TYPE_3D:
109 	case IMAGE_TYPE_BUFFER:
110 		return 1u;
111 
112 	case IMAGE_TYPE_1D_ARRAY:
113 	case IMAGE_TYPE_2D_ARRAY:
114 		return imageSize.z();
115 
116 	case IMAGE_TYPE_CUBE:
117 		return 6u;
118 
119 	case IMAGE_TYPE_CUBE_ARRAY:
120 		return imageSize.z() * 6u;
121 
122 	default:
123 		DE_FATAL("Unknown image type");
124 		return 0u;
125 	}
126 }
127 
getNumPixels(const ImageType imageType,const tcu::UVec3 & imageSize)128 deUint32 getNumPixels (const ImageType imageType, const tcu::UVec3& imageSize)
129 {
130 	const tcu::UVec3 gridSize = getShaderGridSize(imageType, imageSize);
131 
132 	return gridSize.x() * gridSize.y() * gridSize.z();
133 }
134 
getDimensions(const ImageType imageType)135 deUint32 getDimensions (const ImageType imageType)
136 {
137 	switch (imageType)
138 	{
139 	case IMAGE_TYPE_1D:
140 	case IMAGE_TYPE_BUFFER:
141 		return 1u;
142 
143 	case IMAGE_TYPE_1D_ARRAY:
144 	case IMAGE_TYPE_2D:
145 		return 2u;
146 
147 	case IMAGE_TYPE_2D_ARRAY:
148 	case IMAGE_TYPE_CUBE:
149 	case IMAGE_TYPE_CUBE_ARRAY:
150 	case IMAGE_TYPE_3D:
151 		return 3u;
152 
153 	default:
154 		DE_FATAL("Unknown image type");
155 		return 0u;
156 	}
157 }
158 
getLayerDimensions(const ImageType imageType)159 deUint32 getLayerDimensions (const ImageType imageType)
160 {
161 	switch (imageType)
162 	{
163 	case IMAGE_TYPE_1D:
164 	case IMAGE_TYPE_BUFFER:
165 	case IMAGE_TYPE_1D_ARRAY:
166 		return 1u;
167 
168 	case IMAGE_TYPE_2D:
169 	case IMAGE_TYPE_2D_ARRAY:
170 	case IMAGE_TYPE_CUBE:
171 	case IMAGE_TYPE_CUBE_ARRAY:
172 		return 2u;
173 
174 	case IMAGE_TYPE_3D:
175 		return 3u;
176 
177 	default:
178 		DE_FATAL("Unknown image type");
179 		return 0u;
180 	}
181 }
182 
mapImageType(const ImageType imageType)183 VkImageType	mapImageType (const ImageType imageType)
184 {
185 	switch (imageType)
186 	{
187 		case IMAGE_TYPE_1D:
188 		case IMAGE_TYPE_1D_ARRAY:
189 		case IMAGE_TYPE_BUFFER:
190 			return VK_IMAGE_TYPE_1D;
191 
192 		case IMAGE_TYPE_2D:
193 		case IMAGE_TYPE_2D_ARRAY:
194 		case IMAGE_TYPE_CUBE:
195 		case IMAGE_TYPE_CUBE_ARRAY:
196 			return VK_IMAGE_TYPE_2D;
197 
198 		case IMAGE_TYPE_3D:
199 			return VK_IMAGE_TYPE_3D;
200 
201 		default:
202 			DE_ASSERT(false);
203 			return VK_IMAGE_TYPE_LAST;
204 	}
205 }
206 
mapImageViewType(const ImageType imageType)207 VkImageViewType	mapImageViewType (const ImageType imageType)
208 {
209 	switch (imageType)
210 	{
211 		case IMAGE_TYPE_1D:			return VK_IMAGE_VIEW_TYPE_1D;
212 		case IMAGE_TYPE_1D_ARRAY:	return VK_IMAGE_VIEW_TYPE_1D_ARRAY;
213 		case IMAGE_TYPE_2D:			return VK_IMAGE_VIEW_TYPE_2D;
214 		case IMAGE_TYPE_2D_ARRAY:	return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
215 		case IMAGE_TYPE_3D:			return VK_IMAGE_VIEW_TYPE_3D;
216 		case IMAGE_TYPE_CUBE:		return VK_IMAGE_VIEW_TYPE_CUBE;
217 		case IMAGE_TYPE_CUBE_ARRAY:	return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
218 
219 		default:
220 			DE_ASSERT(false);
221 			return VK_IMAGE_VIEW_TYPE_LAST;
222 	}
223 }
224 
getImageTypeName(const ImageType imageType)225 std::string getImageTypeName (const ImageType imageType)
226 {
227 	switch (imageType)
228 	{
229 		case IMAGE_TYPE_1D:			return "1d";
230 		case IMAGE_TYPE_1D_ARRAY:	return "1d_array";
231 		case IMAGE_TYPE_2D:			return "2d";
232 		case IMAGE_TYPE_2D_ARRAY:	return "2d_array";
233 		case IMAGE_TYPE_3D:			return "3d";
234 		case IMAGE_TYPE_CUBE:		return "cube";
235 		case IMAGE_TYPE_CUBE_ARRAY:	return "cube_array";
236 		case IMAGE_TYPE_BUFFER:		return "buffer";
237 
238 		default:
239 			DE_ASSERT(false);
240 			return "";
241 	}
242 }
243 
getShaderImageType(const tcu::TextureFormat & format,const ImageType imageType)244 std::string getShaderImageType (const tcu::TextureFormat& format, const ImageType imageType)
245 {
246 	std::string formatPart = tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ? "u" :
247 							 tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER   ? "i" : "";
248 
249 	std::string imageTypePart;
250 	switch (imageType)
251 	{
252 		case IMAGE_TYPE_1D:			imageTypePart = "1D";			break;
253 		case IMAGE_TYPE_1D_ARRAY:	imageTypePart = "1DArray";		break;
254 		case IMAGE_TYPE_2D:			imageTypePart = "2D";			break;
255 		case IMAGE_TYPE_2D_ARRAY:	imageTypePart = "2DArray";		break;
256 		case IMAGE_TYPE_3D:			imageTypePart = "3D";			break;
257 		case IMAGE_TYPE_CUBE:		imageTypePart = "Cube";			break;
258 		case IMAGE_TYPE_CUBE_ARRAY:	imageTypePart = "CubeArray";	break;
259 		case IMAGE_TYPE_BUFFER:		imageTypePart = "Buffer";		break;
260 
261 		default:
262 			DE_ASSERT(false);
263 	}
264 
265 	return formatPart + "image" + imageTypePart;
266 }
267 
268 
getShaderImageDataType(const tcu::TextureFormat & format)269 std::string getShaderImageDataType (const tcu::TextureFormat& format)
270 {
271 	switch (tcu::getTextureChannelClass(format.type))
272 	{
273 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
274 			return "uvec4";
275 		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
276 			return "ivec4";
277 		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
278 			return "vec4";
279 		default:
280 			DE_ASSERT(false);
281 			return "";
282 	}
283 }
284 
getShaderImageFormatQualifier(const tcu::TextureFormat & format)285 std::string getShaderImageFormatQualifier (const tcu::TextureFormat& format)
286 {
287 	const char* orderPart;
288 	const char* typePart;
289 
290 	switch (format.order)
291 	{
292 		case tcu::TextureFormat::R:		orderPart = "r";	break;
293 		case tcu::TextureFormat::RG:	orderPart = "rg";	break;
294 		case tcu::TextureFormat::RGB:	orderPart = "rgb";	break;
295 		case tcu::TextureFormat::RGBA:	orderPart = "rgba";	break;
296 
297 		default:
298 			DE_ASSERT(false);
299 			orderPart = DE_NULL;
300 	}
301 
302 	switch (format.type)
303 	{
304 		case tcu::TextureFormat::FLOAT:				typePart = "32f";		break;
305 		case tcu::TextureFormat::HALF_FLOAT:		typePart = "16f";		break;
306 
307 		case tcu::TextureFormat::UNSIGNED_INT32:	typePart = "32ui";		break;
308 		case tcu::TextureFormat::UNSIGNED_INT16:	typePart = "16ui";		break;
309 		case tcu::TextureFormat::UNSIGNED_INT8:		typePart = "8ui";		break;
310 
311 		case tcu::TextureFormat::SIGNED_INT32:		typePart = "32i";		break;
312 		case tcu::TextureFormat::SIGNED_INT16:		typePart = "16i";		break;
313 		case tcu::TextureFormat::SIGNED_INT8:		typePart = "8i";		break;
314 
315 		case tcu::TextureFormat::UNORM_INT16:		typePart = "16";		break;
316 		case tcu::TextureFormat::UNORM_INT8:		typePart = "8";			break;
317 
318 		case tcu::TextureFormat::SNORM_INT16:		typePart = "16_snorm";	break;
319 		case tcu::TextureFormat::SNORM_INT8:		typePart = "8_snorm";	break;
320 
321 		default:
322 			DE_ASSERT(false);
323 			typePart = DE_NULL;
324 	}
325 
326 	return std::string() + orderPart + typePart;
327 }
328 
getShaderImageCoordinates(const ImageType imageType,const std::string & x,const std::string & xy,const std::string & xyz)329 std::string getShaderImageCoordinates	(const ImageType	imageType,
330 										 const std::string&	x,
331 										 const std::string&	xy,
332 										 const std::string&	xyz)
333 {
334 	switch (imageType)
335 	{
336 		case IMAGE_TYPE_1D:
337 		case IMAGE_TYPE_BUFFER:
338 			return x;
339 
340 		case IMAGE_TYPE_1D_ARRAY:
341 		case IMAGE_TYPE_2D:
342 			return xy;
343 
344 		case IMAGE_TYPE_2D_ARRAY:
345 		case IMAGE_TYPE_3D:
346 		case IMAGE_TYPE_CUBE:
347 		case IMAGE_TYPE_CUBE_ARRAY:
348 			return xyz;
349 
350 		default:
351 			DE_ASSERT(0);
352 			return "";
353 	}
354 }
355 
getImageMaxMipLevels(const VkImageFormatProperties & imageFormatProperties,const VkExtent3D & extent)356 deUint32 getImageMaxMipLevels (const VkImageFormatProperties& imageFormatProperties, const VkExtent3D& extent)
357 {
358 	const deUint32 widestEdge = std::max(std::max(extent.width, extent.height), extent.depth);
359 
360 	return std::min(static_cast<deUint32>(deFloatLog2(static_cast<float>(widestEdge))) + 1u, imageFormatProperties.maxMipLevels);
361 }
362 
getImageMipLevelSizeInBytes(const VkExtent3D & baseExtents,const deUint32 layersCount,const tcu::TextureFormat & format,const deUint32 mipmapLevel,const deUint32 numSamples)363 deUint32 getImageMipLevelSizeInBytes (const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevel, const deUint32 numSamples)
364 {
365 	const VkExtent3D extents = mipLevelExtents(baseExtents, mipmapLevel);
366 
367 	return extents.width * extents.height * extents.depth * layersCount * numSamples * tcu::getPixelSize(format);
368 }
369 
getImageSizeInBytes(const VkExtent3D & baseExtents,const deUint32 layersCount,const tcu::TextureFormat & format,const deUint32 mipmapLevelsCount,const deUint32 numSamples)370 deUint32 getImageSizeInBytes (const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevelsCount, const deUint32 numSamples)
371 {
372 	deUint32 imageSizeInBytes = 0;
373 	for (deUint32 mipmapLevel = 0; mipmapLevel < mipmapLevelsCount; ++mipmapLevel)
374 	{
375 		imageSizeInBytes += getImageMipLevelSizeInBytes(baseExtents, layersCount, format, mipmapLevel, numSamples);
376 	}
377 
378 	return imageSizeInBytes;
379 }
380 
requireFeatures(const InstanceInterface & instanceInterface,const VkPhysicalDevice physicalDevice,const FeatureFlags flags)381 void requireFeatures (const InstanceInterface& instanceInterface, const VkPhysicalDevice physicalDevice, const FeatureFlags flags)
382 {
383 	const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(instanceInterface, physicalDevice);
384 
385 	if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
386 		throw tcu::NotSupportedError("Tessellation shader not supported");
387 
388 	if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
389 		throw tcu::NotSupportedError("Geometry shader not supported");
390 
391 	if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
392 		throw tcu::NotSupportedError("Double-precision floats not supported");
393 
394 	if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
395 		throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
396 
397 	if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
398 		throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
399 
400 	if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize)
401 		throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in");
402 }
403 
404 } // multisample
405 } // pipeline
406 } // vkt
407