blob: 4744c7f9271961ff1bcf9f9e302bffa19a1b3611 [file] [log] [blame]
/*------------------------------------------------------------------------
* 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 <deMath.h>
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<deUint32>(deFloatLog2(static_cast<float>(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