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 31using namespace vk; 32 33namespace vkt 34{ 35namespace pipeline 36{ 37namespace multisample 38{ 39 40tcu::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 78tcu::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 102deUint32 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 128deUint32 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 135deUint32 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 159deUint32 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 183VkImageType 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 207VkImageViewType 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 225std::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 244std::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 269std::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 285std::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 329std::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 356VkExtent3D mipLevelExtents (const VkExtent3D& baseExtents, const deUint32 mipLevel) 357{ 358 VkExtent3D result; 359 360 result.width = std::max(baseExtents.width >> mipLevel, 1u); 361 result.height = std::max(baseExtents.height >> mipLevel, 1u); 362 result.depth = std::max(baseExtents.depth >> mipLevel, 1u); 363 364 return result; 365} 366 367deUint32 getImageMaxMipLevels (const VkImageFormatProperties& imageFormatProperties, const VkExtent3D& extent) 368{ 369 const deUint32 widestEdge = std::max(std::max(extent.width, extent.height), extent.depth); 370 371 return std::min(static_cast<deUint32>(deFloatLog2(static_cast<float>(widestEdge))) + 1u, imageFormatProperties.maxMipLevels); 372} 373 374deUint32 getImageMipLevelSizeInBytes (const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevel, const deUint32 numSamples) 375{ 376 const VkExtent3D extents = mipLevelExtents(baseExtents, mipmapLevel); 377 378 return extents.width * extents.height * extents.depth * layersCount * numSamples * tcu::getPixelSize(format); 379} 380 381deUint32 getImageSizeInBytes (const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevelsCount, const deUint32 numSamples) 382{ 383 deUint32 imageSizeInBytes = 0; 384 for (deUint32 mipmapLevel = 0; mipmapLevel < mipmapLevelsCount; ++mipmapLevel) 385 { 386 imageSizeInBytes += getImageMipLevelSizeInBytes(baseExtents, layersCount, format, mipmapLevel, numSamples); 387 } 388 389 return imageSizeInBytes; 390} 391 392void requireFeatures (const InstanceInterface& instanceInterface, const VkPhysicalDevice physicalDevice, const FeatureFlags flags) 393{ 394 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(instanceInterface, physicalDevice); 395 396 if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader) 397 throw tcu::NotSupportedError("Tessellation shader not supported"); 398 399 if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader) 400 throw tcu::NotSupportedError("Geometry shader not supported"); 401 402 if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64) 403 throw tcu::NotSupportedError("Double-precision floats not supported"); 404 405 if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics) 406 throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline"); 407 408 if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics) 409 throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader"); 410 411 if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize) 412 throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in"); 413} 414 415} // multisample 416} // pipeline 417} // vkt 418