/*------------------------------------------------------------------------ * Vulkan Conformance Tests * ------------------------ * * Copyright (c) 2016 The Khronos Group Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *//*! * \file vktPipelineMultisampleTestsUtil.cpp * \brief Multisample Tests Utility Classes *//*--------------------------------------------------------------------*/ #include "vktPipelineMultisampleTestsUtil.hpp" #include "vkQueryUtil.hpp" #include "vkTypeUtil.hpp" #include "tcuTextureUtil.hpp" #include using namespace vk; namespace vkt { namespace pipeline { namespace multisample { tcu::UVec3 getShaderGridSize (const ImageType imageType, const tcu::UVec3& imageSize, const deUint32 mipLevel) { const deUint32 mipLevelX = std::max(imageSize.x() >> mipLevel, 1u); const deUint32 mipLevelY = std::max(imageSize.y() >> mipLevel, 1u); const deUint32 mipLevelZ = std::max(imageSize.z() >> mipLevel, 1u); switch (imageType) { case IMAGE_TYPE_1D: return tcu::UVec3(mipLevelX, 1u, 1u); case IMAGE_TYPE_BUFFER: return tcu::UVec3(imageSize.x(), 1u, 1u); case IMAGE_TYPE_1D_ARRAY: return tcu::UVec3(mipLevelX, imageSize.z(), 1u); case IMAGE_TYPE_2D: return tcu::UVec3(mipLevelX, mipLevelY, 1u); case IMAGE_TYPE_2D_ARRAY: return tcu::UVec3(mipLevelX, mipLevelY, imageSize.z()); case IMAGE_TYPE_3D: return tcu::UVec3(mipLevelX, mipLevelY, mipLevelZ); case IMAGE_TYPE_CUBE: return tcu::UVec3(mipLevelX, mipLevelY, 6u); case IMAGE_TYPE_CUBE_ARRAY: return tcu::UVec3(mipLevelX, mipLevelY, 6u * imageSize.z()); default: DE_FATAL("Unknown image type"); return tcu::UVec3(1u, 1u, 1u); } } tcu::UVec3 getLayerSize (const ImageType imageType, const tcu::UVec3& imageSize) { switch (imageType) { case IMAGE_TYPE_1D: case IMAGE_TYPE_1D_ARRAY: case IMAGE_TYPE_BUFFER: return tcu::UVec3(imageSize.x(), 1u, 1u); case IMAGE_TYPE_2D: case IMAGE_TYPE_2D_ARRAY: case IMAGE_TYPE_CUBE: case IMAGE_TYPE_CUBE_ARRAY: return tcu::UVec3(imageSize.x(), imageSize.y(), 1u); case IMAGE_TYPE_3D: return tcu::UVec3(imageSize.x(), imageSize.y(), imageSize.z()); default: DE_FATAL("Unknown image type"); return tcu::UVec3(1u, 1u, 1u); } } deUint32 getNumLayers (const ImageType imageType, const tcu::UVec3& imageSize) { switch (imageType) { case IMAGE_TYPE_1D: case IMAGE_TYPE_2D: case IMAGE_TYPE_3D: case IMAGE_TYPE_BUFFER: return 1u; case IMAGE_TYPE_1D_ARRAY: case IMAGE_TYPE_2D_ARRAY: return imageSize.z(); case IMAGE_TYPE_CUBE: return 6u; case IMAGE_TYPE_CUBE_ARRAY: return imageSize.z() * 6u; default: DE_FATAL("Unknown image type"); return 0u; } } deUint32 getNumPixels (const ImageType imageType, const tcu::UVec3& imageSize) { const tcu::UVec3 gridSize = getShaderGridSize(imageType, imageSize); return gridSize.x() * gridSize.y() * gridSize.z(); } deUint32 getDimensions (const ImageType imageType) { switch (imageType) { case IMAGE_TYPE_1D: case IMAGE_TYPE_BUFFER: return 1u; case IMAGE_TYPE_1D_ARRAY: case IMAGE_TYPE_2D: return 2u; case IMAGE_TYPE_2D_ARRAY: case IMAGE_TYPE_CUBE: case IMAGE_TYPE_CUBE_ARRAY: case IMAGE_TYPE_3D: return 3u; default: DE_FATAL("Unknown image type"); return 0u; } } deUint32 getLayerDimensions (const ImageType imageType) { switch (imageType) { case IMAGE_TYPE_1D: case IMAGE_TYPE_BUFFER: case IMAGE_TYPE_1D_ARRAY: return 1u; case IMAGE_TYPE_2D: case IMAGE_TYPE_2D_ARRAY: case IMAGE_TYPE_CUBE: case IMAGE_TYPE_CUBE_ARRAY: return 2u; case IMAGE_TYPE_3D: return 3u; default: DE_FATAL("Unknown image type"); return 0u; } } VkImageType mapImageType (const ImageType imageType) { switch (imageType) { case IMAGE_TYPE_1D: case IMAGE_TYPE_1D_ARRAY: case IMAGE_TYPE_BUFFER: return VK_IMAGE_TYPE_1D; case IMAGE_TYPE_2D: case IMAGE_TYPE_2D_ARRAY: case IMAGE_TYPE_CUBE: case IMAGE_TYPE_CUBE_ARRAY: return VK_IMAGE_TYPE_2D; case IMAGE_TYPE_3D: return VK_IMAGE_TYPE_3D; default: DE_ASSERT(false); return VK_IMAGE_TYPE_LAST; } } VkImageViewType mapImageViewType (const ImageType imageType) { switch (imageType) { case IMAGE_TYPE_1D: return VK_IMAGE_VIEW_TYPE_1D; case IMAGE_TYPE_1D_ARRAY: return VK_IMAGE_VIEW_TYPE_1D_ARRAY; case IMAGE_TYPE_2D: return VK_IMAGE_VIEW_TYPE_2D; case IMAGE_TYPE_2D_ARRAY: return VK_IMAGE_VIEW_TYPE_2D_ARRAY; case IMAGE_TYPE_3D: return VK_IMAGE_VIEW_TYPE_3D; case IMAGE_TYPE_CUBE: return VK_IMAGE_VIEW_TYPE_CUBE; case IMAGE_TYPE_CUBE_ARRAY: return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; default: DE_ASSERT(false); return VK_IMAGE_VIEW_TYPE_LAST; } } std::string getImageTypeName (const ImageType imageType) { switch (imageType) { case IMAGE_TYPE_1D: return "1d"; case IMAGE_TYPE_1D_ARRAY: return "1d_array"; case IMAGE_TYPE_2D: return "2d"; case IMAGE_TYPE_2D_ARRAY: return "2d_array"; case IMAGE_TYPE_3D: return "3d"; case IMAGE_TYPE_CUBE: return "cube"; case IMAGE_TYPE_CUBE_ARRAY: return "cube_array"; case IMAGE_TYPE_BUFFER: return "buffer"; default: DE_ASSERT(false); return ""; } } std::string getShaderImageType (const tcu::TextureFormat& format, const ImageType imageType) { std::string formatPart = tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ? "u" : tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? "i" : ""; std::string imageTypePart; switch (imageType) { case IMAGE_TYPE_1D: imageTypePart = "1D"; break; case IMAGE_TYPE_1D_ARRAY: imageTypePart = "1DArray"; break; case IMAGE_TYPE_2D: imageTypePart = "2D"; break; case IMAGE_TYPE_2D_ARRAY: imageTypePart = "2DArray"; break; case IMAGE_TYPE_3D: imageTypePart = "3D"; break; case IMAGE_TYPE_CUBE: imageTypePart = "Cube"; break; case IMAGE_TYPE_CUBE_ARRAY: imageTypePart = "CubeArray"; break; case IMAGE_TYPE_BUFFER: imageTypePart = "Buffer"; break; default: DE_ASSERT(false); } return formatPart + "image" + imageTypePart; } std::string getShaderImageDataType (const tcu::TextureFormat& format) { switch (tcu::getTextureChannelClass(format.type)) { case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: return "uvec4"; case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: return "ivec4"; case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: return "vec4"; default: DE_ASSERT(false); return ""; } } std::string getShaderImageFormatQualifier (const tcu::TextureFormat& format) { const char* orderPart; const char* typePart; switch (format.order) { case tcu::TextureFormat::R: orderPart = "r"; break; case tcu::TextureFormat::RG: orderPart = "rg"; break; case tcu::TextureFormat::RGB: orderPart = "rgb"; break; case tcu::TextureFormat::RGBA: orderPart = "rgba"; break; default: DE_ASSERT(false); orderPart = DE_NULL; } switch (format.type) { case tcu::TextureFormat::FLOAT: typePart = "32f"; break; case tcu::TextureFormat::HALF_FLOAT: typePart = "16f"; break; case tcu::TextureFormat::UNSIGNED_INT32: typePart = "32ui"; break; case tcu::TextureFormat::UNSIGNED_INT16: typePart = "16ui"; break; case tcu::TextureFormat::UNSIGNED_INT8: typePart = "8ui"; break; case tcu::TextureFormat::SIGNED_INT32: typePart = "32i"; break; case tcu::TextureFormat::SIGNED_INT16: typePart = "16i"; break; case tcu::TextureFormat::SIGNED_INT8: typePart = "8i"; break; case tcu::TextureFormat::UNORM_INT16: typePart = "16"; break; case tcu::TextureFormat::UNORM_INT8: typePart = "8"; break; case tcu::TextureFormat::SNORM_INT16: typePart = "16_snorm"; break; case tcu::TextureFormat::SNORM_INT8: typePart = "8_snorm"; break; default: DE_ASSERT(false); typePart = DE_NULL; } return std::string() + orderPart + typePart; } std::string getShaderImageCoordinates (const ImageType imageType, const std::string& x, const std::string& xy, const std::string& xyz) { switch (imageType) { case IMAGE_TYPE_1D: case IMAGE_TYPE_BUFFER: return x; case IMAGE_TYPE_1D_ARRAY: case IMAGE_TYPE_2D: return xy; case IMAGE_TYPE_2D_ARRAY: case IMAGE_TYPE_3D: case IMAGE_TYPE_CUBE: case IMAGE_TYPE_CUBE_ARRAY: return xyz; default: DE_ASSERT(0); return ""; } } deUint32 getImageMaxMipLevels (const VkImageFormatProperties& imageFormatProperties, const VkExtent3D& extent) { const deUint32 widestEdge = std::max(std::max(extent.width, extent.height), extent.depth); return std::min(static_cast(deFloatLog2(static_cast(widestEdge))) + 1u, imageFormatProperties.maxMipLevels); } deUint32 getImageMipLevelSizeInBytes (const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevel, const deUint32 numSamples) { const VkExtent3D extents = mipLevelExtents(baseExtents, mipmapLevel); return extents.width * extents.height * extents.depth * layersCount * numSamples * tcu::getPixelSize(format); } deUint32 getImageSizeInBytes (const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevelsCount, const deUint32 numSamples) { deUint32 imageSizeInBytes = 0; for (deUint32 mipmapLevel = 0; mipmapLevel < mipmapLevelsCount; ++mipmapLevel) { imageSizeInBytes += getImageMipLevelSizeInBytes(baseExtents, layersCount, format, mipmapLevel, numSamples); } return imageSizeInBytes; } void requireFeatures (const InstanceInterface& instanceInterface, const VkPhysicalDevice physicalDevice, const FeatureFlags flags) { const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(instanceInterface, physicalDevice); if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader) throw tcu::NotSupportedError("Tessellation shader not supported"); if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader) throw tcu::NotSupportedError("Geometry shader not supported"); if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64) throw tcu::NotSupportedError("Double-precision floats not supported"); if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics) throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline"); if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics) throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader"); if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize) throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in"); } } // multisample } // pipeline } // vkt