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 uint32_t mipLevel)40 tcu::UVec3 getShaderGridSize(const ImageType imageType, const tcu::UVec3 &imageSize, const uint32_t mipLevel)
41 {
42 const uint32_t mipLevelX = std::max(imageSize.x() >> mipLevel, 1u);
43 const uint32_t mipLevelY = std::max(imageSize.y() >> mipLevel, 1u);
44 const uint32_t 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 uint32_t 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 uint32_t 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 uint32_t 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 uint32_t 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:
212 return VK_IMAGE_VIEW_TYPE_1D;
213 case IMAGE_TYPE_1D_ARRAY:
214 return VK_IMAGE_VIEW_TYPE_1D_ARRAY;
215 case IMAGE_TYPE_2D:
216 return VK_IMAGE_VIEW_TYPE_2D;
217 case IMAGE_TYPE_2D_ARRAY:
218 return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
219 case IMAGE_TYPE_3D:
220 return VK_IMAGE_VIEW_TYPE_3D;
221 case IMAGE_TYPE_CUBE:
222 return VK_IMAGE_VIEW_TYPE_CUBE;
223 case IMAGE_TYPE_CUBE_ARRAY:
224 return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
225
226 default:
227 DE_ASSERT(false);
228 return VK_IMAGE_VIEW_TYPE_LAST;
229 }
230 }
231
getImageTypeName(const ImageType imageType)232 std::string getImageTypeName(const ImageType imageType)
233 {
234 switch (imageType)
235 {
236 case IMAGE_TYPE_1D:
237 return "1d";
238 case IMAGE_TYPE_1D_ARRAY:
239 return "1d_array";
240 case IMAGE_TYPE_2D:
241 return "2d";
242 case IMAGE_TYPE_2D_ARRAY:
243 return "2d_array";
244 case IMAGE_TYPE_3D:
245 return "3d";
246 case IMAGE_TYPE_CUBE:
247 return "cube";
248 case IMAGE_TYPE_CUBE_ARRAY:
249 return "cube_array";
250 case IMAGE_TYPE_BUFFER:
251 return "buffer";
252
253 default:
254 DE_ASSERT(false);
255 return "";
256 }
257 }
258
getShaderImageType(const tcu::TextureFormat & format,const ImageType imageType)259 std::string getShaderImageType(const tcu::TextureFormat &format, const ImageType imageType)
260 {
261 std::string formatPart = tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ?
262 "u" :
263 tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? "i" :
264 "";
265
266 std::string imageTypePart;
267 switch (imageType)
268 {
269 case IMAGE_TYPE_1D:
270 imageTypePart = "1D";
271 break;
272 case IMAGE_TYPE_1D_ARRAY:
273 imageTypePart = "1DArray";
274 break;
275 case IMAGE_TYPE_2D:
276 imageTypePart = "2D";
277 break;
278 case IMAGE_TYPE_2D_ARRAY:
279 imageTypePart = "2DArray";
280 break;
281 case IMAGE_TYPE_3D:
282 imageTypePart = "3D";
283 break;
284 case IMAGE_TYPE_CUBE:
285 imageTypePart = "Cube";
286 break;
287 case IMAGE_TYPE_CUBE_ARRAY:
288 imageTypePart = "CubeArray";
289 break;
290 case IMAGE_TYPE_BUFFER:
291 imageTypePart = "Buffer";
292 break;
293
294 default:
295 DE_ASSERT(false);
296 }
297
298 return formatPart + "image" + imageTypePart;
299 }
300
getShaderImageDataType(const tcu::TextureFormat & format)301 std::string getShaderImageDataType(const tcu::TextureFormat &format)
302 {
303 switch (tcu::getTextureChannelClass(format.type))
304 {
305 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
306 return "uvec4";
307 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
308 return "ivec4";
309 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
310 return "vec4";
311 default:
312 DE_ASSERT(false);
313 return "";
314 }
315 }
316
getShaderImageFormatQualifier(const tcu::TextureFormat & format)317 std::string getShaderImageFormatQualifier(const tcu::TextureFormat &format)
318 {
319 const char *orderPart;
320 const char *typePart;
321
322 switch (format.order)
323 {
324 case tcu::TextureFormat::R:
325 orderPart = "r";
326 break;
327 case tcu::TextureFormat::RG:
328 orderPart = "rg";
329 break;
330 case tcu::TextureFormat::RGB:
331 orderPart = "rgb";
332 break;
333 case tcu::TextureFormat::RGBA:
334 orderPart = "rgba";
335 break;
336
337 default:
338 DE_ASSERT(false);
339 orderPart = DE_NULL;
340 }
341
342 switch (format.type)
343 {
344 case tcu::TextureFormat::FLOAT:
345 typePart = "32f";
346 break;
347 case tcu::TextureFormat::HALF_FLOAT:
348 typePart = "16f";
349 break;
350
351 case tcu::TextureFormat::UNSIGNED_INT32:
352 typePart = "32ui";
353 break;
354 case tcu::TextureFormat::UNSIGNED_INT16:
355 typePart = "16ui";
356 break;
357 case tcu::TextureFormat::UNSIGNED_INT8:
358 typePart = "8ui";
359 break;
360
361 case tcu::TextureFormat::SIGNED_INT32:
362 typePart = "32i";
363 break;
364 case tcu::TextureFormat::SIGNED_INT16:
365 typePart = "16i";
366 break;
367 case tcu::TextureFormat::SIGNED_INT8:
368 typePart = "8i";
369 break;
370
371 case tcu::TextureFormat::UNORM_INT16:
372 typePart = "16";
373 break;
374 case tcu::TextureFormat::UNORM_INT8:
375 typePart = "8";
376 break;
377
378 case tcu::TextureFormat::SNORM_INT16:
379 typePart = "16_snorm";
380 break;
381 case tcu::TextureFormat::SNORM_INT8:
382 typePart = "8_snorm";
383 break;
384
385 default:
386 DE_ASSERT(false);
387 typePart = DE_NULL;
388 }
389
390 return std::string() + orderPart + typePart;
391 }
392
getShaderImageCoordinates(const ImageType imageType,const std::string & x,const std::string & xy,const std::string & xyz)393 std::string getShaderImageCoordinates(const ImageType imageType, const std::string &x, const std::string &xy,
394 const std::string &xyz)
395 {
396 switch (imageType)
397 {
398 case IMAGE_TYPE_1D:
399 case IMAGE_TYPE_BUFFER:
400 return x;
401
402 case IMAGE_TYPE_1D_ARRAY:
403 case IMAGE_TYPE_2D:
404 return xy;
405
406 case IMAGE_TYPE_2D_ARRAY:
407 case IMAGE_TYPE_3D:
408 case IMAGE_TYPE_CUBE:
409 case IMAGE_TYPE_CUBE_ARRAY:
410 return xyz;
411
412 default:
413 DE_ASSERT(0);
414 return "";
415 }
416 }
417
getImageMaxMipLevels(const VkImageFormatProperties & imageFormatProperties,const VkExtent3D & extent)418 uint32_t getImageMaxMipLevels(const VkImageFormatProperties &imageFormatProperties, const VkExtent3D &extent)
419 {
420 const uint32_t widestEdge = std::max(std::max(extent.width, extent.height), extent.depth);
421
422 return std::min(static_cast<uint32_t>(deFloatLog2(static_cast<float>(widestEdge))) + 1u,
423 imageFormatProperties.maxMipLevels);
424 }
425
getImageMipLevelSizeInBytes(const VkExtent3D & baseExtents,const uint32_t layersCount,const tcu::TextureFormat & format,const uint32_t mipmapLevel,const uint32_t numSamples)426 uint32_t getImageMipLevelSizeInBytes(const VkExtent3D &baseExtents, const uint32_t layersCount,
427 const tcu::TextureFormat &format, const uint32_t mipmapLevel,
428 const uint32_t numSamples)
429 {
430 const VkExtent3D extents = mipLevelExtents(baseExtents, mipmapLevel);
431
432 return extents.width * extents.height * extents.depth * layersCount * numSamples * tcu::getPixelSize(format);
433 }
434
getImageSizeInBytes(const VkExtent3D & baseExtents,const uint32_t layersCount,const tcu::TextureFormat & format,const uint32_t mipmapLevelsCount,const uint32_t numSamples)435 uint32_t getImageSizeInBytes(const VkExtent3D &baseExtents, const uint32_t layersCount,
436 const tcu::TextureFormat &format, const uint32_t mipmapLevelsCount,
437 const uint32_t numSamples)
438 {
439 uint32_t imageSizeInBytes = 0;
440 for (uint32_t mipmapLevel = 0; mipmapLevel < mipmapLevelsCount; ++mipmapLevel)
441 {
442 imageSizeInBytes += getImageMipLevelSizeInBytes(baseExtents, layersCount, format, mipmapLevel, numSamples);
443 }
444
445 return imageSizeInBytes;
446 }
447
requireFeatures(const InstanceInterface & instanceInterface,const VkPhysicalDevice physicalDevice,const FeatureFlags flags)448 void requireFeatures(const InstanceInterface &instanceInterface, const VkPhysicalDevice physicalDevice,
449 const FeatureFlags flags)
450 {
451 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(instanceInterface, physicalDevice);
452
453 if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
454 throw tcu::NotSupportedError("Tessellation shader not supported");
455
456 if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
457 throw tcu::NotSupportedError("Geometry shader not supported");
458
459 if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
460 throw tcu::NotSupportedError("Double-precision floats not supported");
461
462 if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
463 throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
464
465 if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
466 throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
467
468 if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) &&
469 !features.shaderTessellationAndGeometryPointSize)
470 throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in");
471 }
472
473 } // namespace multisample
474 } // namespace pipeline
475 } // namespace vkt
476