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