blob: 3d3d417fd005c41ee7ea06fc4e52b907fc1c8954 [file] [log] [blame]
/*-------------------------------------------------------------------------
* Vulkan CTS Framework
* --------------------
*
* Copyright (c) 2015 The Khronos Group Inc.
* Copyright (c) 2015 Imagination Technologies Ltd.
* Copyright (c) 2015 Google 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
* \brief Utilities for images.
*//*--------------------------------------------------------------------*/
#include "vkImageUtil.hpp"
#include "vkRefUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkCmdUtil.hpp"
#include "tcuTextureUtil.hpp"
#include "deMath.h"
#include "vkMemUtil.hpp"
#include "vkObjUtil.hpp"
#include <map>
#include <assert.h>
namespace vk
{
bool isFloatFormat(VkFormat format)
{
return tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
}
bool isUnormFormat(VkFormat format)
{
return tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
}
bool isSnormFormat(VkFormat format)
{
return tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT;
}
bool isIntFormat(VkFormat format)
{
return tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER;
}
bool isUintFormat(VkFormat format)
{
return tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
}
bool isScaledFormat(VkFormat format)
{
// update this mapping if VkFormat changes
DE_STATIC_ASSERT(VK_CORE_FORMAT_LAST == 185);
switch (format)
{
case VK_FORMAT_R8_USCALED:
case VK_FORMAT_R8_SSCALED:
case VK_FORMAT_R8G8_USCALED:
case VK_FORMAT_R8G8_SSCALED:
case VK_FORMAT_R8G8B8_USCALED:
case VK_FORMAT_R8G8B8_SSCALED:
case VK_FORMAT_R8G8B8A8_USCALED:
case VK_FORMAT_R8G8B8A8_SSCALED:
case VK_FORMAT_A2B10G10R10_USCALED_PACK32:
case VK_FORMAT_A2B10G10R10_SSCALED_PACK32:
case VK_FORMAT_R16_USCALED:
case VK_FORMAT_R16_SSCALED:
case VK_FORMAT_R16G16_USCALED:
case VK_FORMAT_R16G16_SSCALED:
case VK_FORMAT_R16G16B16_USCALED:
case VK_FORMAT_R16G16B16_SSCALED:
case VK_FORMAT_R16G16B16A16_USCALED:
case VK_FORMAT_R16G16B16A16_SSCALED:
case VK_FORMAT_B8G8R8_USCALED:
case VK_FORMAT_B8G8R8_SSCALED:
case VK_FORMAT_B8G8R8A8_USCALED:
case VK_FORMAT_B8G8R8A8_SSCALED:
case VK_FORMAT_A2R10G10B10_USCALED_PACK32:
case VK_FORMAT_A2R10G10B10_SSCALED_PACK32:
case VK_FORMAT_A8B8G8R8_USCALED_PACK32:
case VK_FORMAT_A8B8G8R8_SSCALED_PACK32:
return true;
default:
return false;
}
}
bool isDepthStencilFormat(VkFormat format)
{
if (isCompressedFormat(format))
return false;
if (isYCbCrFormat(format))
return false;
const tcu::TextureFormat tcuFormat = mapVkFormat(format);
return tcuFormat.order == tcu::TextureFormat::D || tcuFormat.order == tcu::TextureFormat::S ||
tcuFormat.order == tcu::TextureFormat::DS;
}
bool isSrgbFormat(VkFormat format)
{
switch (mapVkFormat(format).order)
{
case tcu::TextureFormat::sR:
case tcu::TextureFormat::sRG:
case tcu::TextureFormat::sRGB:
case tcu::TextureFormat::sRGBA:
case tcu::TextureFormat::sBGR:
case tcu::TextureFormat::sBGRA:
return true;
default:
return false;
}
}
// Returns true if the format has padding bits.
bool isPaddedFormat(VkFormat format)
{
bool isPadded = false;
switch (format)
{
case VK_FORMAT_X8_D24_UNORM_PACK32:
case VK_FORMAT_R10X6_UNORM_PACK16:
case VK_FORMAT_R10X6G10X6_UNORM_2PACK16:
case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:
case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
case VK_FORMAT_R12X4_UNORM_PACK16:
case VK_FORMAT_R12X4G12X4_UNORM_2PACK16:
case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:
case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
#ifndef CTS_USES_VULKANSC
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16:
#endif // CTS_USES_VULKANSC
isPadded = true;
break;
default:
break;
}
return isPadded;
}
bool isAlphaOnlyFormat(VkFormat format)
{
if (isCompressedFormat(format))
return false;
if (isYCbCrFormat(format))
return false;
return (mapVkFormat(format).order == tcu::TextureFormat::A);
}
bool isUfloatFormat(VkFormat format)
{
DE_STATIC_ASSERT(VK_CORE_FORMAT_LAST == 185);
switch (format)
{
case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:
case VK_FORMAT_BC6H_UFLOAT_BLOCK:
return true;
default:
return false;
}
}
bool isSfloatFormat(VkFormat format)
{
DE_STATIC_ASSERT(VK_CORE_FORMAT_LAST == 185);
switch (format)
{
case VK_FORMAT_R16_SFLOAT:
case VK_FORMAT_R16G16_SFLOAT:
case VK_FORMAT_R16G16B16_SFLOAT:
case VK_FORMAT_R16G16B16A16_SFLOAT:
case VK_FORMAT_R32_SFLOAT:
case VK_FORMAT_R32G32_SFLOAT:
case VK_FORMAT_R32G32B32_SFLOAT:
case VK_FORMAT_R32G32B32A32_SFLOAT:
case VK_FORMAT_R64_SFLOAT:
case VK_FORMAT_R64G64_SFLOAT:
case VK_FORMAT_R64G64B64_SFLOAT:
case VK_FORMAT_R64G64B64A64_SFLOAT:
case VK_FORMAT_D32_SFLOAT:
case VK_FORMAT_BC6H_SFLOAT_BLOCK:
return true;
default:
return false;
}
}
bool isCompressedFormat(VkFormat format)
{
// update this mapping if VkFormat changes
DE_STATIC_ASSERT(VK_CORE_FORMAT_LAST == 185);
switch (format)
{
case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
case VK_FORMAT_BC2_UNORM_BLOCK:
case VK_FORMAT_BC2_SRGB_BLOCK:
case VK_FORMAT_BC3_UNORM_BLOCK:
case VK_FORMAT_BC3_SRGB_BLOCK:
case VK_FORMAT_BC4_UNORM_BLOCK:
case VK_FORMAT_BC4_SNORM_BLOCK:
case VK_FORMAT_BC5_UNORM_BLOCK:
case VK_FORMAT_BC5_SNORM_BLOCK:
case VK_FORMAT_BC6H_UFLOAT_BLOCK:
case VK_FORMAT_BC6H_SFLOAT_BLOCK:
case VK_FORMAT_BC7_UNORM_BLOCK:
case VK_FORMAT_BC7_SRGB_BLOCK:
case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
case VK_FORMAT_EAC_R11_UNORM_BLOCK:
case VK_FORMAT_EAC_R11_SNORM_BLOCK:
case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
return true;
default:
return false;
}
}
bool isYCbCrFormat(VkFormat format)
{
switch (format)
{
case VK_FORMAT_G8B8G8R8_422_UNORM:
case VK_FORMAT_B8G8R8G8_422_UNORM:
case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
case VK_FORMAT_R10X6_UNORM_PACK16:
case VK_FORMAT_R10X6G10X6_UNORM_2PACK16:
case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:
case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
case VK_FORMAT_R12X4_UNORM_PACK16:
case VK_FORMAT_R12X4G12X4_UNORM_2PACK16:
case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:
case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
case VK_FORMAT_G16B16G16R16_422_UNORM:
case VK_FORMAT_B16G16R16G16_422_UNORM:
case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
case VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT:
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT:
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT:
case VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT:
return true;
default:
return false;
}
}
bool isYCbCrExtensionFormat(VkFormat format)
{
switch (format)
{
case VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT:
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT:
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT:
case VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT:
return true;
default:
return false;
}
}
bool isYCbCrConversionFormat(VkFormat format)
{
switch (format)
{
case VK_FORMAT_G8B8G8R8_422_UNORM:
case VK_FORMAT_B8G8R8G8_422_UNORM:
case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:
case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:
case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
case VK_FORMAT_G16B16G16R16_422_UNORM:
case VK_FORMAT_B16G16R16G16_422_UNORM:
case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT:
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT:
case VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT:
case VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT:
return true;
default:
return false;
}
}
bool isYCbCr420Format(VkFormat format)
{
switch (format)
{
case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
return true;
default:
return false;
}
}
bool isYCbCr422Format(VkFormat format)
{
switch (format)
{
case VK_FORMAT_G8B8G8R8_422_UNORM:
case VK_FORMAT_B8G8R8G8_422_UNORM:
case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G16B16G16R16_422_UNORM:
case VK_FORMAT_B16G16R16G16_422_UNORM:
case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
return true;
default:
return false;
}
}
bool isPvrtcFormat(VkFormat format)
{
#ifndef CTS_USES_VULKANSC
switch (format)
{
case VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG:
case VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG:
case VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG:
case VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG:
case VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG:
case VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG:
case VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG:
case VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG:
return true;
default:
return false;
}
#else
DE_UNREF(format);
#endif
return false;
}
const std::map<VkFormat, std::string> spirvFormats = {
{VK_FORMAT_R32G32B32A32_SFLOAT, "Rgba32f"},
{VK_FORMAT_R32G32_SFLOAT, "Rg32f"},
{VK_FORMAT_R32_SFLOAT, "R32f"},
{VK_FORMAT_R16G16B16A16_SFLOAT, "Rgba16f"},
{VK_FORMAT_R16G16_SFLOAT, "Rg16f"},
{VK_FORMAT_R16_SFLOAT, "R16f"},
{VK_FORMAT_R16G16B16A16_UNORM, "Rgba16"},
{VK_FORMAT_R16G16_UNORM, "Rg16"},
{VK_FORMAT_R16_UNORM, "R16"},
{VK_FORMAT_R16G16B16A16_SNORM, "Rgba16Snorm"},
{VK_FORMAT_R16G16_SNORM, "Rg16Snorm"},
{VK_FORMAT_R16_SNORM, "R16Snorm"},
{VK_FORMAT_A2B10G10R10_UNORM_PACK32, "Rgb10A2"},
{VK_FORMAT_B10G11R11_UFLOAT_PACK32, "R11fG11fB10f"},
{VK_FORMAT_R8G8B8A8_UNORM, "Rgba8"},
{VK_FORMAT_R8G8_UNORM, "Rg8"},
{VK_FORMAT_R8_UNORM, "R8"},
{VK_FORMAT_R8G8B8A8_SNORM, "Rgba8Snorm"},
{VK_FORMAT_R8G8_SNORM, "Rg8Snorm"},
{VK_FORMAT_R8_SNORM, "R8Snorm"},
{VK_FORMAT_R32G32B32A32_SINT, "Rgba32i"},
{VK_FORMAT_R32G32_SINT, "Rg32i"},
{VK_FORMAT_R32_SINT, "R32i"},
{VK_FORMAT_R16G16B16A16_SINT, "Rgba16i"},
{VK_FORMAT_R16G16_SINT, "Rg16i"},
{VK_FORMAT_R16_SINT, "R16i"},
{VK_FORMAT_R8G8B8A8_SINT, "Rgba8i"},
{VK_FORMAT_R8G8_SINT, "Rg8i"},
{VK_FORMAT_R8_SINT, "R8i"},
{VK_FORMAT_R32G32B32A32_UINT, "Rgba32ui"},
{VK_FORMAT_R32G32_UINT, "Rg32ui"},
{VK_FORMAT_R32_UINT, "R32ui"},
{VK_FORMAT_R16G16B16A16_UINT, "Rgba16ui"},
{VK_FORMAT_R16G16_UINT, "Rg16ui"},
{VK_FORMAT_R16_UINT, "R16ui"},
{VK_FORMAT_A2B10G10R10_UINT_PACK32, "Rgb10a2ui"},
{VK_FORMAT_R8G8B8A8_UINT, "Rgba8ui"},
{VK_FORMAT_R8G8_UINT, "Rg8ui"},
{VK_FORMAT_R8_UINT, "R8ui"},
{VK_FORMAT_R64_SINT, "R64i"},
{VK_FORMAT_R64_UINT, "R64ui"},
};
bool hasSpirvFormat(VkFormat fmt)
{
auto iter = spirvFormats.find(fmt);
return (iter != spirvFormats.end());
}
const std::string getSpirvFormat(VkFormat fmt)
{
auto iter = spirvFormats.find(fmt);
assert(iter != spirvFormats.end());
return iter->second;
}
bool is64BitIntegerFormat(VkFormat format)
{
const auto tcuFormat = mapVkFormat(format);
return (tcuFormat.type == tcu::TextureFormat::UNSIGNED_INT64 || tcuFormat.type == tcu::TextureFormat::SIGNED_INT64);
}
const PlanarFormatDescription &getYCbCrPlanarFormatDescription(VkFormat format)
{
using tcu::TextureFormat;
const uint32_t chanR = PlanarFormatDescription::CHANNEL_R;
const uint32_t chanG = PlanarFormatDescription::CHANNEL_G;
const uint32_t chanB = PlanarFormatDescription::CHANNEL_B;
const uint32_t chanA = PlanarFormatDescription::CHANNEL_A;
const uint8_t unorm = (uint8_t)tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
if (format >= VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT && format <= VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT)
{
static const PlanarFormatDescription s_formatInfo[] = {
// VK_FORMAT_G8_B8R8_2PLANE_444_UNORM
{2, // planes
chanR | chanG | chanB,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{1, 1, 1, VK_FORMAT_R8_UNORM},
{2, 1, 1, VK_FORMAT_R8G8_UNORM},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{ // Plane Type Offs Size Stride
{1, unorm, 8, 8, 2}, // R
{0, unorm, 0, 8, 1}, // G
{1, unorm, 0, 8, 2}, // B
{0, 0, 0, 0, 0}}},
// VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT
{2, // planes
chanR | chanG | chanB,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_R10X6_UNORM_PACK16},
{4, 1, 1, VK_FORMAT_R10X6G10X6_UNORM_2PACK16},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{ // Plane Type Offs Size Stride
{1, unorm, 22, 10, 4}, // R
{0, unorm, 6, 10, 2}, // G
{1, unorm, 6, 10, 4}, // B
{0, 0, 0, 0, 0}}},
// VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT
{2, // planes
chanR | chanG | chanB,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_R12X4_UNORM_PACK16},
{4, 1, 1, VK_FORMAT_R12X4G12X4_UNORM_2PACK16},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{ // Plane Type Offs Size Stride
{1, unorm, 20, 12, 4}, // R
{0, unorm, 4, 12, 2}, // G
{1, unorm, 4, 12, 4}, // B
{0, 0, 0, 0, 0}}},
// VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT
{2, // planes
chanR | chanG | chanB,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_R16_UNORM},
{4, 1, 1, VK_FORMAT_R16G16_UNORM},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{ // Plane Type Offs Size Stride
{1, unorm, 16, 16, 4}, // R
{0, unorm, 0, 16, 2}, // G
{1, unorm, 0, 16, 4}, // B
{0, 0, 0, 0, 0}}},
};
const size_t offset = (size_t)VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT;
DE_ASSERT(de::inBounds<size_t>((size_t)format, offset, offset + (size_t)DE_LENGTH_OF_ARRAY(s_formatInfo)));
return s_formatInfo[(size_t)format - offset];
}
static const PlanarFormatDescription s_formatInfo[] = {
// VK_FORMAT_G8B8G8R8_422_UNORM
{1, // planes
chanR | chanG | chanB,
2,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{4, 1, 1, VK_FORMAT_G8B8G8R8_422_UNORM},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{ // Plane Type Offs Size Stride
{0, unorm, 24, 8, 4}, // R
{0, unorm, 0, 8, 2}, // G
{0, unorm, 8, 8, 4}, // B
{0, 0, 0, 0, 0}}},
// VK_FORMAT_B8G8R8G8_422_UNORM
{1, // planes
chanR | chanG | chanB,
2,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{4, 1, 1, VK_FORMAT_B8G8R8G8_422_UNORM},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{ // Plane Type Offs Size Stride
{0, unorm, 16, 8, 4}, // R
{0, unorm, 8, 8, 2}, // G
{0, unorm, 0, 8, 4}, // B
{0, 0, 0, 0, 0}}},
// VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM
{3, // planes
chanR | chanG | chanB,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{1, 1, 1, VK_FORMAT_R8_UNORM},
{1, 2, 2, VK_FORMAT_R8_UNORM},
{1, 2, 2, VK_FORMAT_R8_UNORM},
},
{ // Plane Type Offs Size Stride
{2, unorm, 0, 8, 1}, // R
{0, unorm, 0, 8, 1}, // G
{1, unorm, 0, 8, 1}, // B
{0, 0, 0, 0, 0}}},
// VK_FORMAT_G8_B8R8_2PLANE_420_UNORM
{2, // planes
chanR | chanG | chanB,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{1, 1, 1, VK_FORMAT_R8_UNORM},
{2, 2, 2, VK_FORMAT_R8G8_UNORM},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{ // Plane Type Offs Size Stride
{1, unorm, 8, 8, 2}, // R
{0, unorm, 0, 8, 1}, // G
{1, unorm, 0, 8, 2}, // B
{0, 0, 0, 0, 0}}},
// VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM
{3, // planes
chanR | chanG | chanB,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{1, 1, 1, VK_FORMAT_R8_UNORM},
{1, 2, 1, VK_FORMAT_R8_UNORM},
{1, 2, 1, VK_FORMAT_R8_UNORM},
},
{ // Plane Type Offs Size Stride
{2, unorm, 0, 8, 1}, // R
{0, unorm, 0, 8, 1}, // G
{1, unorm, 0, 8, 1}, // B
{0, 0, 0, 0, 0}}},
// VK_FORMAT_G8_B8R8_2PLANE_422_UNORM
{2, // planes
chanR | chanG | chanB,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{1, 1, 1, VK_FORMAT_R8_UNORM},
{2, 2, 1, VK_FORMAT_R8G8_UNORM},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{ // Plane Type Offs Size Stride
{1, unorm, 8, 8, 2}, // R
{0, unorm, 0, 8, 1}, // G
{1, unorm, 0, 8, 2}, // B
{0, 0, 0, 0, 0}}},
// VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM
{3, // planes
chanR | chanG | chanB,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{1, 1, 1, VK_FORMAT_R8_UNORM},
{1, 1, 1, VK_FORMAT_R8_UNORM},
{1, 1, 1, VK_FORMAT_R8_UNORM},
},
{ // Plane Type Offs Size Stride
{2, unorm, 0, 8, 1}, // R
{0, unorm, 0, 8, 1}, // G
{1, unorm, 0, 8, 1}, // B
{0, 0, 0, 0, 0}}},
// VK_FORMAT_R10X6_UNORM_PACK16
{1, // planes
chanR,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_R10X6_UNORM_PACK16},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, unorm, 6, 10, 2}, // R
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
}},
// VK_FORMAT_R10X6G10X6_UNORM_2PACK16
{1, // planes
chanR | chanG,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{4, 1, 1, VK_FORMAT_R10X6G10X6_UNORM_2PACK16},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, unorm, 6, 10, 4}, // R
{0, unorm, 22, 10, 4}, // G
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
}},
// VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16
{1, // planes
chanR | chanG | chanB | chanA,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{8, 1, 1, VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, unorm, 6, 10, 8}, // R
{0, unorm, 22, 10, 8}, // G
{0, unorm, 38, 10, 8}, // B
{0, unorm, 54, 10, 8}, // A
}},
// VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16
{1, // planes
chanR | chanG | chanB,
2,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{8, 1, 1, VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{ // Plane Type Offs Size Stride
{0, unorm, 54, 10, 8}, // R
{0, unorm, 6, 10, 4}, // G
{0, unorm, 22, 10, 8}, // B
{0, 0, 0, 0, 0}}},
// VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16
{1, // planes
chanR | chanG | chanB,
2,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{8, 1, 1, VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{ // Plane Type Offs Size Stride
{0, unorm, 38, 10, 8}, // R
{0, unorm, 22, 10, 4}, // G
{0, unorm, 6, 10, 8}, // B
{0, 0, 0, 0, 0}}},
// VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16
{3, // planes
chanR | chanG | chanB,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_R10X6_UNORM_PACK16},
{2, 2, 2, VK_FORMAT_R10X6_UNORM_PACK16},
{2, 2, 2, VK_FORMAT_R10X6_UNORM_PACK16},
},
{ // Plane Type Offs Size Stride
{2, unorm, 6, 10, 2}, // R
{0, unorm, 6, 10, 2}, // G
{1, unorm, 6, 10, 2}, // B
{0, 0, 0, 0, 0}}},
// VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16
{2, // planes
chanR | chanG | chanB,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_R10X6_UNORM_PACK16},
{4, 2, 2, VK_FORMAT_R10X6G10X6_UNORM_2PACK16},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{ // Plane Type Offs Size Stride
{1, unorm, 22, 10, 4}, // R
{0, unorm, 6, 10, 2}, // G
{1, unorm, 6, 10, 4}, // B
{0, 0, 0, 0, 0}}},
// VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16
{3, // planes
chanR | chanG | chanB,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_R10X6_UNORM_PACK16},
{2, 2, 1, VK_FORMAT_R10X6_UNORM_PACK16},
{2, 2, 1, VK_FORMAT_R10X6_UNORM_PACK16},
},
{ // Plane Type Offs Size Stride
{2, unorm, 6, 10, 2}, // R
{0, unorm, 6, 10, 2}, // G
{1, unorm, 6, 10, 2}, // B
{0, 0, 0, 0, 0}}},
// VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16
{2, // planes
chanR | chanG | chanB,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_R10X6_UNORM_PACK16},
{4, 2, 1, VK_FORMAT_R10X6G10X6_UNORM_2PACK16},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{ // Plane Type Offs Size Stride
{1, unorm, 22, 10, 4}, // R
{0, unorm, 6, 10, 2}, // G
{1, unorm, 6, 10, 4}, // B
{0, 0, 0, 0, 0}}},
// VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16
{3, // planes
chanR | chanG | chanB,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_R10X6_UNORM_PACK16},
{2, 1, 1, VK_FORMAT_R10X6_UNORM_PACK16},
{2, 1, 1, VK_FORMAT_R10X6_UNORM_PACK16},
},
{ // Plane Type Offs Size Stride
{2, unorm, 6, 10, 2}, // R
{0, unorm, 6, 10, 2}, // G
{1, unorm, 6, 10, 2}, // B
{0, 0, 0, 0, 0}}},
// VK_FORMAT_R12X4_UNORM_PACK16
{1, // planes
chanR,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_R12X4_UNORM_PACK16},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, unorm, 4, 12, 2}, // R
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
}},
// VK_FORMAT_R12X4G12X4_UNORM_2PACK16
{1, // planes
chanR | chanG,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{4, 1, 1, VK_FORMAT_R12X4G12X4_UNORM_2PACK16},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, unorm, 4, 12, 4}, // R
{0, unorm, 20, 12, 4}, // G
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
}},
// VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16
{1, // planes
chanR | chanG | chanB | chanA,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{8, 1, 1, VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, unorm, 4, 12, 8}, // R
{0, unorm, 20, 12, 8}, // G
{0, unorm, 36, 12, 8}, // B
{0, unorm, 52, 12, 8}, // A
}},
// VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16
{1, // planes
chanR | chanG | chanB,
2,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{8, 1, 1, VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{ // Plane Type Offs Size Stride
{0, unorm, 52, 12, 8}, // R
{0, unorm, 4, 12, 4}, // G
{0, unorm, 20, 12, 8}, // B
{0, 0, 0, 0, 0}}},
// VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16
{1, // planes
chanR | chanG | chanB,
2,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{8, 1, 1, VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{ // Plane Type Offs Size Stride
{0, unorm, 36, 12, 8}, // R
{0, unorm, 20, 12, 4}, // G
{0, unorm, 4, 12, 8}, // B
{0, 0, 0, 0, 0}}},
// VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16
{3, // planes
chanR | chanG | chanB,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_R12X4_UNORM_PACK16},
{2, 2, 2, VK_FORMAT_R12X4_UNORM_PACK16},
{2, 2, 2, VK_FORMAT_R12X4_UNORM_PACK16},
},
{ // Plane Type Offs Size Stride
{2, unorm, 4, 12, 2}, // R
{0, unorm, 4, 12, 2}, // G
{1, unorm, 4, 12, 2}, // B
{0, 0, 0, 0, 0}}},
// VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16
{2, // planes
chanR | chanG | chanB,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_R12X4_UNORM_PACK16},
{4, 2, 2, VK_FORMAT_R12X4G12X4_UNORM_2PACK16},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{ // Plane Type Offs Size Stride
{1, unorm, 20, 12, 4}, // R
{0, unorm, 4, 12, 2}, // G
{1, unorm, 4, 12, 4}, // B
{0, 0, 0, 0, 0}}},
// VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16
{3, // planes
chanR | chanG | chanB,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_R12X4_UNORM_PACK16},
{2, 2, 1, VK_FORMAT_R12X4_UNORM_PACK16},
{2, 2, 1, VK_FORMAT_R12X4_UNORM_PACK16},
},
{ // Plane Type Offs Size Stride
{2, unorm, 4, 12, 2}, // R
{0, unorm, 4, 12, 2}, // G
{1, unorm, 4, 12, 2}, // B
{0, 0, 0, 0, 0}}},
// VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16
{2, // planes
chanR | chanG | chanB,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_R12X4_UNORM_PACK16},
{4, 2, 1, VK_FORMAT_R12X4G12X4_UNORM_2PACK16},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{ // Plane Type Offs Size Stride
{1, unorm, 20, 12, 4}, // R
{0, unorm, 4, 12, 2}, // G
{1, unorm, 4, 12, 4}, // B
{0, 0, 0, 0, 0}}},
// VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16
{3, // planes
chanR | chanG | chanB,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_R12X4_UNORM_PACK16},
{2, 1, 1, VK_FORMAT_R12X4_UNORM_PACK16},
{2, 1, 1, VK_FORMAT_R12X4_UNORM_PACK16},
},
{ // Plane Type Offs Size Stride
{2, unorm, 4, 12, 2}, // R
{0, unorm, 4, 12, 2}, // G
{1, unorm, 4, 12, 2}, // B
{0, 0, 0, 0, 0}}},
// VK_FORMAT_G16B16G16R16_422_UNORM
{1, // planes
chanR | chanG | chanB,
2,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{8, 1, 1, VK_FORMAT_G16B16G16R16_422_UNORM},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{ // Plane Type Offs Size Stride
{0, unorm, 48, 16, 8}, // R
{0, unorm, 0, 16, 4}, // G
{0, unorm, 16, 16, 8}, // B
{0, 0, 0, 0, 0}}},
// VK_FORMAT_B16G16R16G16_422_UNORM
{1, // planes
chanR | chanG | chanB,
2,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{8, 1, 1, VK_FORMAT_B16G16R16G16_422_UNORM},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{ // Plane Type Offs Size Stride
{0, unorm, 32, 16, 8}, // R
{0, unorm, 16, 16, 4}, // G
{0, unorm, 0, 16, 8}, // B
{0, 0, 0, 0, 0}}},
// VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM
{3, // planes
chanR | chanG | chanB,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_R16_UNORM},
{2, 2, 2, VK_FORMAT_R16_UNORM},
{2, 2, 2, VK_FORMAT_R16_UNORM},
},
{ // Plane Type Offs Size Stride
{2, unorm, 0, 16, 2}, // R
{0, unorm, 0, 16, 2}, // G
{1, unorm, 0, 16, 2}, // B
{0, 0, 0, 0, 0}}},
// VK_FORMAT_G16_B16R16_2PLANE_420_UNORM
{2, // planes
chanR | chanG | chanB,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_R16_UNORM},
{4, 2, 2, VK_FORMAT_R16G16_UNORM},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{ // Plane Type Offs Size Stride
{1, unorm, 16, 16, 4}, // R
{0, unorm, 0, 16, 2}, // G
{1, unorm, 0, 16, 4}, // B
{0, 0, 0, 0, 0}}},
// VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM
{3, // planes
chanR | chanG | chanB,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_R16_UNORM},
{2, 2, 1, VK_FORMAT_R16_UNORM},
{2, 2, 1, VK_FORMAT_R16_UNORM},
},
{ // Plane Type Offs Size Stride
{2, unorm, 0, 16, 2}, // R
{0, unorm, 0, 16, 2}, // G
{1, unorm, 0, 16, 2}, // B
{0, 0, 0, 0, 0}}},
// VK_FORMAT_G16_B16R16_2PLANE_422_UNORM
{2, // planes
chanR | chanG | chanB,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_R16_UNORM},
{4, 2, 1, VK_FORMAT_R16G16_UNORM},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{ // Plane Type Offs Size Stride
{1, unorm, 16, 16, 4}, // R
{0, unorm, 0, 16, 2}, // G
{1, unorm, 0, 16, 4}, // B
{0, 0, 0, 0, 0}}},
// VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM
{3, // planes
chanR | chanG | chanB,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_R16_UNORM},
{2, 1, 1, VK_FORMAT_R16_UNORM},
{2, 1, 1, VK_FORMAT_R16_UNORM},
},
{ // Plane Type Offs Size Stride
{2, unorm, 0, 16, 2}, // R
{0, unorm, 0, 16, 2}, // G
{1, unorm, 0, 16, 2}, // B
{0, 0, 0, 0, 0}}},
};
const size_t offset = (size_t)VK_FORMAT_G8B8G8R8_422_UNORM;
DE_ASSERT(de::inBounds<size_t>((size_t)format, offset, offset + (size_t)DE_LENGTH_OF_ARRAY(s_formatInfo)));
return s_formatInfo[(size_t)format - offset];
}
PlanarFormatDescription getCorePlanarFormatDescription(VkFormat format)
{
const uint8_t snorm = (uint8_t)tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT;
const uint8_t unorm = (uint8_t)tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
const uint8_t sint = (uint8_t)tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER;
const uint8_t uint = (uint8_t)tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
const uint8_t sfloat = (uint8_t)tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
const uint8_t chanR = (uint8_t)PlanarFormatDescription::CHANNEL_R;
const uint8_t chanG = (uint8_t)PlanarFormatDescription::CHANNEL_G;
const uint8_t chanB = (uint8_t)PlanarFormatDescription::CHANNEL_B;
const uint8_t chanA = (uint8_t)PlanarFormatDescription::CHANNEL_A;
DE_ASSERT(de::inBounds<uint32_t>(format, VK_FORMAT_UNDEFINED + 1, VK_CORE_FORMAT_LAST));
#if (DE_ENDIANNESS != DE_LITTLE_ENDIAN)
#error "Big-endian is not supported"
#endif
switch (format)
{
case VK_FORMAT_R8_UNORM:
{
const PlanarFormatDescription desc = {1, // planes
chanR,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{1, 1, 1, VK_FORMAT_R8_UNORM},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, unorm, 0, 8, 1}, // R
{0, 0, 0, 0, 0}, // G
{0, 0, 0, 0, 0}, // B
{0, 0, 0, 0, 0} // A
}};
return desc;
}
case VK_FORMAT_R8_SNORM:
{
const PlanarFormatDescription desc = {1, // planes
chanR,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{1, 1, 1, VK_FORMAT_R8_SNORM},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, snorm, 0, 8, 1}, // R
{0, 0, 0, 0, 0}, // G
{0, 0, 0, 0, 0}, // B
{0, 0, 0, 0, 0} // A
}};
return desc;
}
case VK_FORMAT_R8G8_UNORM:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_R8G8_UNORM},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, unorm, 0, 8, 2}, // R
{0, unorm, 8, 8, 2}, // G
{0, 0, 0, 0, 0}, // B
{0, 0, 0, 0, 0} // A
}};
return desc;
}
case VK_FORMAT_R8G8_SNORM:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_R8G8_SNORM},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, snorm, 0, 8, 2}, // R
{0, snorm, 8, 8, 2}, // G
{0, 0, 0, 0, 0}, // B
{0, 0, 0, 0, 0} // A
}};
return desc;
}
case VK_FORMAT_R16_UNORM:
{
const PlanarFormatDescription desc = {1, // planes
chanR,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_R16_UNORM},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, unorm, 0, 16, 2}, // R
{0, 0, 0, 0, 0}, // G
{0, 0, 0, 0, 0}, // B
{0, 0, 0, 0, 0} // A
}};
return desc;
}
case VK_FORMAT_R16_SNORM:
{
const PlanarFormatDescription desc = {1, // planes
chanR,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_R16_SNORM},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, snorm, 0, 16, 2}, // R
{0, 0, 0, 0, 0}, // G
{0, 0, 0, 0, 0}, // B
{0, 0, 0, 0, 0} // A
}};
return desc;
}
case VK_FORMAT_R16G16_UNORM:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{4, 1, 1, VK_FORMAT_R16G16_UNORM},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, unorm, 0, 16, 4}, // R
{0, unorm, 16, 16, 4}, // G
{0, 0, 0, 0, 0}, // B
{0, 0, 0, 0, 0} // A
}};
return desc;
}
case VK_FORMAT_R16G16_SNORM:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{4, 1, 1, VK_FORMAT_R16G16_SNORM},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, snorm, 0, 16, 4}, // R
{0, snorm, 16, 16, 4}, // G
{0, 0, 0, 0, 0}, // B
{0, 0, 0, 0, 0} // A
}};
return desc;
}
case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG | chanB,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{4, 1, 1, VK_FORMAT_B10G11R11_UFLOAT_PACK32},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, unorm, 0, 11, 4}, // R
{0, unorm, 11, 11, 4}, // G
{0, unorm, 22, 10, 4}, // B
{0, 0, 0, 0, 0} // A
}};
return desc;
}
case VK_FORMAT_R4G4_UNORM_PACK8:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{1, 1, 1, VK_FORMAT_R4G4_UNORM_PACK8},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, unorm, 4, 4, 1}, // R
{0, unorm, 0, 4, 1}, // G
{0, 0, 0, 0, 0}, // B
{0, 0, 0, 0, 0} // A
}};
return desc;
}
case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG | chanB | chanA,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_R4G4B4A4_UNORM_PACK16},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, unorm, 12, 4, 2}, // R
{0, unorm, 8, 4, 2}, // G
{0, unorm, 4, 4, 2}, // B
{0, unorm, 0, 4, 2} // A
}};
return desc;
}
case VK_FORMAT_B4G4R4A4_UNORM_PACK16:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG | chanB | chanA,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_B4G4R4A4_UNORM_PACK16},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, unorm, 4, 4, 2}, // R
{0, unorm, 8, 4, 2}, // G
{0, unorm, 12, 4, 2}, // B
{0, unorm, 0, 4, 2} // A
}};
return desc;
}
case VK_FORMAT_R5G6B5_UNORM_PACK16:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG | chanB,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_R5G6B5_UNORM_PACK16},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, unorm, 11, 5, 2}, // R
{0, unorm, 5, 6, 2}, // G
{0, unorm, 0, 5, 2}, // B
{0, 0, 0, 0, 0} // A
}};
return desc;
}
case VK_FORMAT_B5G6R5_UNORM_PACK16:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG | chanB,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_B5G6R5_UNORM_PACK16},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, unorm, 0, 5, 2}, // R
{0, unorm, 5, 6, 2}, // G
{0, unorm, 11, 5, 2}, // B
{0, 0, 0, 0, 0} // A
}};
return desc;
}
case VK_FORMAT_R5G5B5A1_UNORM_PACK16:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG | chanB | chanA,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_R5G5B5A1_UNORM_PACK16},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, unorm, 11, 5, 2}, // R
{0, unorm, 6, 5, 2}, // G
{0, unorm, 1, 5, 2}, // B
{0, unorm, 0, 1, 2} // A
}};
return desc;
}
case VK_FORMAT_B5G5R5A1_UNORM_PACK16:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG | chanB | chanA,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_B5G5R5A1_UNORM_PACK16},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, unorm, 1, 5, 2}, // R
{0, unorm, 6, 5, 2}, // G
{0, unorm, 11, 5, 2}, // B
{0, unorm, 0, 1, 2} // A
}};
return desc;
}
case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG | chanB | chanA,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_A1R5G5B5_UNORM_PACK16},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, unorm, 10, 5, 2}, // R
{0, unorm, 5, 5, 2}, // G
{0, unorm, 0, 5, 2}, // B
{0, unorm, 15, 1, 2} // A
}};
return desc;
}
case VK_FORMAT_R8G8B8_UNORM:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG | chanB,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{3, 1, 1, VK_FORMAT_R8G8B8_UNORM},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, unorm, 0, 8, 3}, // R
{0, unorm, 8, 8, 3}, // G
{0, unorm, 16, 8, 3}, // B
{0, 0, 0, 0, 0} // A
}};
return desc;
}
case VK_FORMAT_B8G8R8_UNORM:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG | chanB,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{3, 1, 1, VK_FORMAT_B8G8R8_UNORM},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, unorm, 16, 8, 3}, // R
{0, unorm, 8, 8, 3}, // G
{0, unorm, 0, 8, 3}, // B
{0, 0, 0, 0, 0} // A
}};
return desc;
}
case VK_FORMAT_R8G8B8A8_UNORM:
case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG | chanB | chanA,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{4, 1, 1, VK_FORMAT_R8G8B8A8_UNORM},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, unorm, 0, 8, 4}, // R
{0, unorm, 8, 8, 4}, // G
{0, unorm, 16, 8, 4}, // B
{0, unorm, 24, 8, 4} // A
}};
return desc;
}
case VK_FORMAT_B8G8R8A8_UNORM:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG | chanB | chanA,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{4, 1, 1, VK_FORMAT_B8G8R8A8_UNORM},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, unorm, 16, 8, 4}, // R
{0, unorm, 8, 8, 4}, // G
{0, unorm, 0, 8, 4}, // B
{0, unorm, 24, 8, 4} // A
}};
return desc;
}
case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG | chanB | chanA,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{4, 1, 1, VK_FORMAT_A2R10G10B10_UNORM_PACK32},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, unorm, 20, 10, 4}, // R
{0, unorm, 10, 10, 4}, // G
{0, unorm, 0, 10, 4}, // B
{0, unorm, 30, 2, 4} // A
}};
return desc;
}
case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG | chanB | chanA,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{4, 1, 1, VK_FORMAT_A2B10G10R10_UNORM_PACK32},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, unorm, 0, 10, 4}, // R
{0, unorm, 10, 10, 4}, // G
{0, unorm, 20, 10, 4}, // B
{0, unorm, 30, 2, 4} // A
}};
return desc;
}
case VK_FORMAT_R16G16B16_UNORM:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG | chanB,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{6, 1, 1, VK_FORMAT_R16G16B16_UNORM},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, unorm, 0, 16, 6}, // R
{0, unorm, 16, 16, 6}, // G
{0, unorm, 32, 16, 6}, // B
{0, 0, 0, 0, 0} // A
}};
return desc;
}
case VK_FORMAT_R16G16B16A16_UNORM:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG | chanB | chanA,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{8, 1, 1, VK_FORMAT_R16G16B16A16_UNORM},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, unorm, 0, 16, 8}, // R
{0, unorm, 16, 16, 8}, // G
{0, unorm, 32, 16, 8}, // B
{0, unorm, 48, 16, 8} // A
}};
return desc;
}
case VK_FORMAT_R8_SINT:
{
const PlanarFormatDescription desc = {1, // planes
chanR,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{1, 1, 1, VK_FORMAT_R8_SINT},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, sint, 0, 8, 1}, // R
{0, 0, 0, 0, 0}, // G
{0, 0, 0, 0, 0}, // B
{0, 0, 0, 0, 0} // A
}};
return desc;
}
case VK_FORMAT_R16_SINT:
{
const PlanarFormatDescription desc = {1, // planes
chanR,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_R16_SINT},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, sint, 0, 16, 2}, // R
{0, 0, 0, 0, 0}, // G
{0, 0, 0, 0, 0}, // B
{0, 0, 0, 0, 0} // A
}};
return desc;
}
case VK_FORMAT_R32_SINT:
{
const PlanarFormatDescription desc = {1, // planes
chanR,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{4, 1, 1, VK_FORMAT_R32_SINT},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, sint, 0, 32, 4}, // R
{0, 0, 0, 0, 0}, // G
{0, 0, 0, 0, 0}, // B
{0, 0, 0, 0, 0} // A
}};
return desc;
}
case VK_FORMAT_R64_SINT:
{
const PlanarFormatDescription desc = {1, // planes
chanR,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{8, 1, 1, VK_FORMAT_R64_SINT},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, sint, 0, 64, 8}, // R
{0, 0, 0, 0, 0}, // G
{0, 0, 0, 0, 0}, // B
{0, 0, 0, 0, 0} // A
}};
return desc;
}
case VK_FORMAT_R8G8_SINT:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_R8G8_SINT},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, sint, 0, 8, 2}, // R
{0, sint, 8, 8, 2}, // G
{0, 0, 0, 0, 0}, // B
{0, 0, 0, 0, 0} // A
}};
return desc;
}
case VK_FORMAT_R16G16_SINT:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{4, 1, 1, VK_FORMAT_R16G16_SINT},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, sint, 0, 16, 4}, // R
{0, sint, 16, 16, 4}, // G
{0, 0, 0, 0, 0}, // B
{0, 0, 0, 0, 0} // A
}};
return desc;
}
case VK_FORMAT_R32G32_SINT:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{8, 1, 1, VK_FORMAT_R32G32_SINT},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, sint, 0, 32, 8}, // R
{0, sint, 32, 32, 8}, // G
{0, 0, 0, 0, 0}, // B
{0, 0, 0, 0, 0} // A
}};
return desc;
}
case VK_FORMAT_R8G8B8A8_SINT:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG | chanB | chanA,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{4, 1, 1, VK_FORMAT_R8G8B8A8_SINT},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, sint, 0, 8, 4}, // R
{0, sint, 8, 8, 4}, // G
{0, sint, 16, 8, 4}, // B
{0, sint, 24, 8, 4} // A
}};
return desc;
}
case VK_FORMAT_R16G16B16A16_SINT:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG | chanB | chanA,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{8, 1, 1, VK_FORMAT_R16G16B16A16_SINT},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, sint, 0, 16, 8}, // R
{0, sint, 16, 16, 8}, // G
{0, sint, 32, 16, 8}, // B
{0, sint, 48, 16, 8} // A
}};
return desc;
}
case VK_FORMAT_R32G32B32A32_SINT:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG | chanB | chanA,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{16, 1, 1, VK_FORMAT_R32G32B32A32_SINT},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, sint, 0, 32, 16}, // R
{0, sint, 32, 32, 16}, // G
{0, sint, 64, 32, 16}, // B
{0, sint, 96, 32, 16} // A
}};
return desc;
}
case VK_FORMAT_R8_UINT:
{
const PlanarFormatDescription desc = {1, // planes
chanR,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{1, 1, 1, VK_FORMAT_R8_UINT},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, uint, 0, 8, 1}, // R
{0, 0, 0, 0, 0}, // G
{0, 0, 0, 0, 0}, // B
{0, 0, 0, 0, 0} // A
}};
return desc;
}
case VK_FORMAT_R16_UINT:
{
const PlanarFormatDescription desc = {1, // planes
chanR,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_R16_UINT},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, uint, 0, 16, 2}, // R
{0, 0, 0, 0, 0}, // G
{0, 0, 0, 0, 0}, // B
{0, 0, 0, 0, 0} // A
}};
return desc;
}
case VK_FORMAT_R32_UINT:
{
const PlanarFormatDescription desc = {1, // planes
chanR,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{4, 1, 1, VK_FORMAT_R32_UINT},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, uint, 0, 32, 4}, // R
{0, 0, 0, 0, 0}, // G
{0, 0, 0, 0, 0}, // B
{0, 0, 0, 0, 0} // A
}};
return desc;
}
case VK_FORMAT_R64_UINT:
{
const PlanarFormatDescription desc = {1, // planes
chanR,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{8, 1, 1, VK_FORMAT_R64_UINT},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, uint, 0, 64, 8}, // R
{0, 0, 0, 0, 0}, // G
{0, 0, 0, 0, 0}, // B
{0, 0, 0, 0, 0} // A
}};
return desc;
}
case VK_FORMAT_R8G8_UINT:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_R8G8_UINT},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, uint, 0, 8, 2}, // R
{0, uint, 8, 8, 2}, // G
{0, 0, 0, 0, 0}, // B
{0, 0, 0, 0, 0} // A
}};
return desc;
}
case VK_FORMAT_R16G16_UINT:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{4, 1, 1, VK_FORMAT_R16G16_UINT},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, uint, 0, 16, 4}, // R
{0, uint, 16, 16, 4}, // G
{0, 0, 0, 0, 0}, // B
{0, 0, 0, 0, 0} // A
}};
return desc;
}
case VK_FORMAT_R32G32_UINT:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{8, 1, 1, VK_FORMAT_R32G32_UINT},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, uint, 0, 32, 8}, // R
{0, uint, 32, 32, 8}, // G
{0, 0, 0, 0, 0}, // B
{0, 0, 0, 0, 0} // A
}};
return desc;
}
case VK_FORMAT_R8G8B8A8_UINT:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG | chanB | chanA,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{4, 1, 1, VK_FORMAT_R8G8B8A8_UINT},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, uint, 0, 8, 4}, // R
{0, uint, 8, 8, 4}, // G
{0, uint, 16, 8, 4}, // B
{0, uint, 24, 8, 4} // A
}};
return desc;
}
case VK_FORMAT_R16G16B16A16_UINT:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG | chanB | chanA,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{8, 1, 1, VK_FORMAT_R16G16B16A16_UINT},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, uint, 0, 16, 8}, // R
{0, uint, 16, 16, 8}, // G
{0, uint, 32, 16, 8}, // B
{0, uint, 48, 16, 8} // A
}};
return desc;
}
case VK_FORMAT_R32G32B32A32_UINT:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG | chanB | chanA,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{16, 1, 1, VK_FORMAT_R32G32B32A32_UINT},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, uint, 0, 32, 16}, // R
{0, uint, 32, 32, 16}, // G
{0, uint, 64, 32, 16}, // B
{0, uint, 96, 32, 16} // A
}};
return desc;
}
case VK_FORMAT_R8G8B8A8_SNORM:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG | chanB | chanA,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{4, 1, 1, VK_FORMAT_R8G8B8A8_SNORM},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, snorm, 0, 8, 4}, // R
{0, snorm, 8, 8, 4}, // G
{0, snorm, 16, 8, 4}, // B
{0, snorm, 24, 8, 4} // A
}};
return desc;
}
case VK_FORMAT_R16G16B16A16_SNORM:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG | chanB | chanA,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{8, 1, 1, VK_FORMAT_R16G16B16A16_SNORM},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, snorm, 0, 16, 8}, // R
{0, snorm, 16, 16, 8}, // G
{0, snorm, 32, 16, 8}, // B
{0, snorm, 48, 16, 8} // A
}};
return desc;
}
case VK_FORMAT_R32_SFLOAT:
case VK_FORMAT_D32_SFLOAT:
{
const PlanarFormatDescription desc = {1, // planes
chanR,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{4, 1, 1, VK_FORMAT_R32_SFLOAT},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, sfloat, 0, 32, 4}, // R
{0, 0, 0, 0, 0}, // G
{0, 0, 0, 0, 0}, // B
{0, 0, 0, 0, 0} // A
}};
return desc;
}
case VK_FORMAT_D16_UNORM:
{
const PlanarFormatDescription desc = {1, // planes
chanR,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_D16_UNORM},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, unorm, 0, 16, 2}, // R
{0, 0, 0, 0, 0}, // G
{0, 0, 0, 0, 0}, // B
{0, 0, 0, 0, 0} // A
}};
return desc;
}
case VK_FORMAT_S8_UINT:
{
const PlanarFormatDescription desc = {1, // planes
chanR,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{1, 1, 1, VK_FORMAT_S8_UINT},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, uint, 0, 8, 1}, // R
{0, 0, 0, 0, 0}, // G
{0, 0, 0, 0, 0}, // B
{0, 0, 0, 0, 0} // A
}};
return desc;
}
case VK_FORMAT_R32G32B32A32_SFLOAT:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG | chanB | chanA,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{16, 1, 1, VK_FORMAT_R32G32B32A32_SFLOAT},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, sfloat, 0, 32, 16}, // R
{0, sfloat, 32, 32, 16}, // G
{0, sfloat, 64, 32, 16}, // B
{0, sfloat, 96, 32, 16}, // A
}};
return desc;
}
case VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG | chanB | chanA,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, unorm, 8, 4, 2}, // R
{0, unorm, 4, 4, 2}, // G
{0, unorm, 0, 4, 2}, // B
{0, unorm, 12, 4, 2} // A
}};
return desc;
}
case VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT:
{
const PlanarFormatDescription desc = {1, // planes
chanR | chanG | chanB | chanA,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, unorm, 0, 4, 2}, // R
{0, unorm, 4, 4, 2}, // G
{0, unorm, 8, 4, 2}, // B
{0, unorm, 12, 4, 2} // A
}};
return desc;
}
#ifndef CTS_USES_VULKANSC
case VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR:
{
const PlanarFormatDescription desc{1, // planes
chanR | chanG | chanB | chanA,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{2, 1, 1, VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, unorm, 11, 5, 2}, // R
{0, unorm, 6, 5, 2}, // G
{0, unorm, 1, 5, 2}, // B
{0, unorm, 0, 1, 2} // A
}};
return desc;
}
#endif // CTS_USES_VULKANSC
default:
TCU_THROW(InternalError, "Not implemented");
}
}
PlanarFormatDescription getPlanarFormatDescription(VkFormat format)
{
if (isYCbCrFormat(format))
return getYCbCrPlanarFormatDescription(format);
#ifndef CTS_USES_VULKANSC
else if (format == VK_FORMAT_A8_UNORM_KHR)
{
const auto unorm = static_cast<uint8_t>(tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT);
const auto chanA = static_cast<uint8_t>(PlanarFormatDescription::CHANNEL_A);
const PlanarFormatDescription desc = {1, // planes
chanA,
1,
1,
{
// Size WDiv HDiv planeCompatibleFormat
{1, 1, 1, VK_FORMAT_A8_UNORM_KHR},
{0, 0, 0, VK_FORMAT_UNDEFINED},
{0, 0, 0, VK_FORMAT_UNDEFINED},
},
{
// Plane Type Offs Size Stride
{0, 0, 0, 0, 0}, // R
{0, 0, 0, 0, 0}, // G
{0, 0, 0, 0, 0}, // B
{0, unorm, 0, 8, 1}, // A
}};
return desc;
}
#endif // CTS_USES_VULKANSC
else
return getCorePlanarFormatDescription(format);
}
int getPlaneCount(VkFormat format)
{
switch (format)
{
case VK_FORMAT_G8B8G8R8_422_UNORM:
case VK_FORMAT_B8G8R8G8_422_UNORM:
case VK_FORMAT_R10X6_UNORM_PACK16:
case VK_FORMAT_R10X6G10X6_UNORM_2PACK16:
case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:
case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
case VK_FORMAT_R12X4_UNORM_PACK16:
case VK_FORMAT_R12X4G12X4_UNORM_2PACK16:
case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:
case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
case VK_FORMAT_G16B16G16R16_422_UNORM:
case VK_FORMAT_B16G16R16G16_422_UNORM:
return 1;
case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
case VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT:
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT:
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT:
case VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT:
return 2;
case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
return 3;
default:
DE_FATAL("Not YCbCr format");
return 0;
}
}
uint32_t getMipmapCount(VkFormat format, const vk::PlanarFormatDescription &formatDescription,
const VkImageFormatProperties &imageFormatProperties, const VkExtent3D &extent)
{
if (isYCbCrFormat(format))
return 1;
tcu::UVec3 imageAlignment = getImageSizeAlignment(formatDescription);
uint32_t mipmapEdge = std::max(std::max(extent.width, extent.height), extent.depth);
if (imageAlignment.x() > 1)
mipmapEdge = std::min(mipmapEdge, extent.width / imageAlignment.x());
if (imageAlignment.y() > 1)
mipmapEdge = std::min(mipmapEdge, extent.height / imageAlignment.y());
if (imageAlignment.z() > 1)
mipmapEdge = std::min(mipmapEdge, extent.depth / imageAlignment.z());
return std::min(static_cast<uint32_t>(deFloatLog2(static_cast<float>(mipmapEdge))) + 1u,
imageFormatProperties.maxMipLevels);
}
uint32_t getPlaneSizeInBytes(const PlanarFormatDescription &formatInfo, const VkExtent3D &baseExtents,
const uint32_t planeNdx, const uint32_t mipmapLevel, const uint32_t mipmapMemoryAlignment)
{
VkExtent3D imageExtent = getPlaneExtent(formatInfo, baseExtents, planeNdx, mipmapLevel);
imageExtent.width /= formatInfo.blockWidth;
imageExtent.height /= formatInfo.blockHeight;
return deAlign32(formatInfo.planes[planeNdx].elementSizeBytes * imageExtent.width * imageExtent.height *
imageExtent.depth,
mipmapMemoryAlignment);
}
uint32_t getPlaneSizeInBytes(const PlanarFormatDescription &formatInfo, const tcu::UVec2 &baseExtents,
const uint32_t planeNdx, const uint32_t mipmapLevel, const uint32_t mipmapMemoryAlignment)
{
tcu::UVec2 mipExtents = getPlaneExtent(formatInfo, baseExtents, planeNdx, mipmapLevel) /
tcu::UVec2(formatInfo.blockWidth, formatInfo.blockHeight);
return deAlign32(formatInfo.planes[planeNdx].elementSizeBytes * mipExtents.x() * mipExtents.y(),
mipmapMemoryAlignment);
}
VkExtent3D getPlaneExtent(const PlanarFormatDescription &formatInfo, const VkExtent3D &baseExtents,
const uint32_t planeNdx, const uint32_t mipmapLevel)
{
uint32_t widthDivisor = formatInfo.planes[planeNdx].widthDivisor;
uint32_t heightDivisor = formatInfo.planes[planeNdx].heightDivisor;
uint32_t depthDivisor = 1u;
VkExtent3D mip0Extents{baseExtents.width / widthDivisor, baseExtents.height / heightDivisor,
baseExtents.depth / depthDivisor};
return mipLevelExtents(mip0Extents, mipmapLevel);
}
tcu::UVec2 getPlaneExtent(const PlanarFormatDescription &formatInfo, const tcu::UVec2 &baseExtents,
const uint32_t planeNdx, const uint32_t mipmapLevel)
{
uint32_t widthDivisor = formatInfo.planes[planeNdx].widthDivisor;
uint32_t heightDivisor = formatInfo.planes[planeNdx].heightDivisor;
tcu::UVec2 mip0Extents{baseExtents.x() / widthDivisor, baseExtents.y() / heightDivisor};
return tcu::UVec2{std::max(mip0Extents.x() >> mipmapLevel, 1u), std::max(mip0Extents.y() >> mipmapLevel, 1u)};
}
tcu::UVec3 getImageSizeAlignment(VkFormat format)
{
return getImageSizeAlignment(getPlanarFormatDescription(format));
}
tcu::UVec3 getImageSizeAlignment(const PlanarFormatDescription &formatInfo)
{
tcu::UVec3 imgAlignment{formatInfo.blockWidth, formatInfo.blockHeight, 1};
for (uint32_t planeNdx = 0; planeNdx < formatInfo.numPlanes; ++planeNdx)
{
imgAlignment.x() = std::max(imgAlignment.x(), static_cast<uint32_t>(formatInfo.planes[planeNdx].widthDivisor));
imgAlignment.y() = std::max(imgAlignment.y(), static_cast<uint32_t>(formatInfo.planes[planeNdx].heightDivisor));
}
return imgAlignment;
}
tcu::UVec2 getBlockExtent(VkFormat format)
{
return getBlockExtent(getPlanarFormatDescription(format));
}
tcu::UVec2 getBlockExtent(const PlanarFormatDescription &formatInfo)
{
return tcu::UVec2{formatInfo.blockWidth, formatInfo.blockHeight};
}
VkFormat getPlaneCompatibleFormat(VkFormat format, uint32_t planeNdx)
{
return getPlaneCompatibleFormat(getPlanarFormatDescription(format), planeNdx);
}
VkFormat getPlaneCompatibleFormat(const PlanarFormatDescription &formatInfo, uint32_t planeNdx)
{
DE_ASSERT(planeNdx < formatInfo.numPlanes);
return formatInfo.planes[planeNdx].planeCompatibleFormat;
}
VkImageAspectFlagBits getPlaneAspect(uint32_t planeNdx)
{
DE_ASSERT(de::inBounds(planeNdx, 0u, 3u));
return (VkImageAspectFlagBits)(VK_IMAGE_ASPECT_PLANE_0_BIT << planeNdx);
}
uint32_t getAspectPlaneNdx(VkImageAspectFlagBits flags)
{
switch (flags)
{
case VK_IMAGE_ASPECT_PLANE_0_BIT:
return 0;
case VK_IMAGE_ASPECT_PLANE_1_BIT:
return 1;
case VK_IMAGE_ASPECT_PLANE_2_BIT:
return 2;
default:
DE_FATAL("Invalid plane aspect");
return 0;
}
}
bool isChromaSubsampled(VkFormat format)
{
switch (format)
{
case VK_FORMAT_G8B8G8R8_422_UNORM:
case VK_FORMAT_B8G8R8G8_422_UNORM:
case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G16B16G16R16_422_UNORM:
case VK_FORMAT_B16G16R16G16_422_UNORM:
case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
return true;
default:
return false;
}
}
bool isSupportedByFramework(VkFormat format)
{
#ifndef CTS_USES_VULKANSC
if (format == VK_FORMAT_A8_UNORM_KHR || format == VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR)
return true;
#endif // CTS_USES_VULKANSC
if (format == VK_FORMAT_UNDEFINED || format > VK_CORE_FORMAT_LAST)
return false;
switch (format)
{
case VK_FORMAT_R64_UINT:
case VK_FORMAT_R64_SINT:
case VK_FORMAT_R64_SFLOAT:
case VK_FORMAT_R64G64_UINT:
case VK_FORMAT_R64G64_SINT:
case VK_FORMAT_R64G64_SFLOAT:
case VK_FORMAT_R64G64B64_UINT:
case VK_FORMAT_R64G64B64_SINT:
case VK_FORMAT_R64G64B64_SFLOAT:
case VK_FORMAT_R64G64B64A64_UINT:
case VK_FORMAT_R64G64B64A64_SINT:
case VK_FORMAT_R64G64B64A64_SFLOAT:
// \todo [2016-12-01 pyry] Support 64-bit channel types
return false;
case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
case VK_FORMAT_BC2_UNORM_BLOCK:
case VK_FORMAT_BC2_SRGB_BLOCK:
case VK_FORMAT_BC3_UNORM_BLOCK:
case VK_FORMAT_BC3_SRGB_BLOCK:
case VK_FORMAT_BC4_UNORM_BLOCK:
case VK_FORMAT_BC4_SNORM_BLOCK:
case VK_FORMAT_BC5_UNORM_BLOCK:
case VK_FORMAT_BC5_SNORM_BLOCK:
case VK_FORMAT_BC6H_UFLOAT_BLOCK:
case VK_FORMAT_BC6H_SFLOAT_BLOCK:
case VK_FORMAT_BC7_UNORM_BLOCK:
case VK_FORMAT_BC7_SRGB_BLOCK:
return false;
default:
return true;
}
}
void checkImageSupport(const InstanceInterface &vki, VkPhysicalDevice physicalDevice,
const VkImageCreateInfo &imageCreateInfo)
{
VkImageFormatProperties imageFormatProperties;
if (vki.getPhysicalDeviceImageFormatProperties(physicalDevice, imageCreateInfo.format, imageCreateInfo.imageType,
imageCreateInfo.tiling, imageCreateInfo.usage, imageCreateInfo.flags,
&imageFormatProperties))
{
TCU_THROW(NotSupportedError, "Image format not supported.");
}
if (((VkSampleCountFlagBits)imageFormatProperties.sampleCounts & imageCreateInfo.samples) == 0)
{
TCU_THROW(NotSupportedError, "Sample count not supported.");
}
if (imageFormatProperties.maxArrayLayers < imageCreateInfo.arrayLayers)
{
TCU_THROW(NotSupportedError, "Layer count not supported.");
}
}
VkFormat mapTextureFormat(const tcu::TextureFormat &format)
{
DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST < (1 << 16));
DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELTYPE_LAST < (1 << 16));
#define PACK_FMT(ORDER, TYPE) ((int(ORDER) << 16) | int(TYPE))
#define FMT_CASE(ORDER, TYPE) PACK_FMT(tcu::TextureFormat::ORDER, tcu::TextureFormat::TYPE)
// update this mapping if VkFormat changes
DE_STATIC_ASSERT(VK_CORE_FORMAT_LAST == 185);
switch (PACK_FMT(format.order, format.type))
{
case FMT_CASE(RG, UNORM_BYTE_44):
return VK_FORMAT_R4G4_UNORM_PACK8;
case FMT_CASE(RGB, UNORM_SHORT_565):
return VK_FORMAT_R5G6B5_UNORM_PACK16;
case FMT_CASE(RGBA, UNORM_SHORT_4444):
return VK_FORMAT_R4G4B4A4_UNORM_PACK16;
case FMT_CASE(RGBA, UNORM_SHORT_5551):
return VK_FORMAT_R5G5B5A1_UNORM_PACK16;
#ifndef CTS_USES_VULKANSC
case FMT_CASE(ABGR, UNORM_SHORT_1555):
return VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR;
#endif // CTS_USES_VULKANSC
case FMT_CASE(BGR, UNORM_SHORT_565):
return VK_FORMAT_B5G6R5_UNORM_PACK16;
case FMT_CASE(BGRA, UNORM_SHORT_4444):
return VK_FORMAT_B4G4R4A4_UNORM_PACK16;
case FMT_CASE(BGRA, UNORM_SHORT_5551):
return VK_FORMAT_B5G5R5A1_UNORM_PACK16;
case FMT_CASE(ARGB, UNORM_SHORT_1555):
return VK_FORMAT_A1R5G5B5_UNORM_PACK16;
case FMT_CASE(R, UNORM_INT8):
return VK_FORMAT_R8_UNORM;
case FMT_CASE(R, SNORM_INT8):
return VK_FORMAT_R8_SNORM;
case FMT_CASE(R, UNSIGNED_INT8):
return VK_FORMAT_R8_UINT;
case FMT_CASE(R, SIGNED_INT8):
return VK_FORMAT_R8_SINT;
case FMT_CASE(sR, UNORM_INT8):
return VK_FORMAT_R8_SRGB;
#ifndef CTS_USES_VULKANSC
case FMT_CASE(A, UNORM_INT8):
return VK_FORMAT_A8_UNORM_KHR;
#endif // CTS_USES_VULKANSC
case FMT_CASE(RG, UNORM_INT8):
return VK_FORMAT_R8G8_UNORM;
case FMT_CASE(RG, SNORM_INT8):
return VK_FORMAT_R8G8_SNORM;
case FMT_CASE(RG, UNSIGNED_INT8):
return VK_FORMAT_R8G8_UINT;
case FMT_CASE(RG, SIGNED_INT8):
return VK_FORMAT_R8G8_SINT;
case FMT_CASE(sRG, UNORM_INT8):
return VK_FORMAT_R8G8_SRGB;
case FMT_CASE(RGB, UNORM_INT8):
return VK_FORMAT_R8G8B8_UNORM;
case FMT_CASE(RGB, SNORM_INT8):
return VK_FORMAT_R8G8B8_SNORM;
case FMT_CASE(RGB, UNSIGNED_INT8):
return VK_FORMAT_R8G8B8_UINT;
case FMT_CASE(RGB, SIGNED_INT8):
return VK_FORMAT_R8G8B8_SINT;
case FMT_CASE(sRGB, UNORM_INT8):
return VK_FORMAT_R8G8B8_SRGB;
case FMT_CASE(RGBA, UNORM_INT8):
return VK_FORMAT_R8G8B8A8_UNORM;
case FMT_CASE(RGBA, SNORM_INT8):
return VK_FORMAT_R8G8B8A8_SNORM;
case FMT_CASE(RGBA, UNSIGNED_INT8):
return VK_FORMAT_R8G8B8A8_UINT;
case FMT_CASE(RGBA, SIGNED_INT8):
return VK_FORMAT_R8G8B8A8_SINT;
case FMT_CASE(sRGBA, UNORM_INT8):
return VK_FORMAT_R8G8B8A8_SRGB;
case FMT_CASE(RGBA, UNORM_INT_1010102_REV):
return VK_FORMAT_A2B10G10R10_UNORM_PACK32;
case FMT_CASE(RGBA, SNORM_INT_1010102_REV):
return VK_FORMAT_A2B10G10R10_SNORM_PACK32;
case FMT_CASE(RGBA, UNSIGNED_INT_1010102_REV):
return VK_FORMAT_A2B10G10R10_UINT_PACK32;
case FMT_CASE(RGBA, SIGNED_INT_1010102_REV):
return VK_FORMAT_A2B10G10R10_SINT_PACK32;
case FMT_CASE(R, UNORM_INT16):
return VK_FORMAT_R16_UNORM;
case FMT_CASE(R, SNORM_INT16):
return VK_FORMAT_R16_SNORM;
case FMT_CASE(R, UNSIGNED_INT16):
return VK_FORMAT_R16_UINT;
case FMT_CASE(R, SIGNED_INT16):
return VK_FORMAT_R16_SINT;
case FMT_CASE(R, HALF_FLOAT):
return VK_FORMAT_R16_SFLOAT;
case FMT_CASE(RG, UNORM_INT16):
return VK_FORMAT_R16G16_UNORM;
case FMT_CASE(RG, SNORM_INT16):
return VK_FORMAT_R16G16_SNORM;
case FMT_CASE(RG, UNSIGNED_INT16):
return VK_FORMAT_R16G16_UINT;
case FMT_CASE(RG, SIGNED_INT16):
return VK_FORMAT_R16G16_SINT;
case FMT_CASE(RG, HALF_FLOAT):
return VK_FORMAT_R16G16_SFLOAT;
case FMT_CASE(RGB, UNORM_INT16):
return VK_FORMAT_R16G16B16_UNORM;
case FMT_CASE(RGB, SNORM_INT16):
return VK_FORMAT_R16G16B16_SNORM;
case FMT_CASE(RGB, UNSIGNED_INT16):
return VK_FORMAT_R16G16B16_UINT;
case FMT_CASE(RGB, SIGNED_INT16):
return VK_FORMAT_R16G16B16_SINT;
case FMT_CASE(RGB, HALF_FLOAT):
return VK_FORMAT_R16G16B16_SFLOAT;
case FMT_CASE(RGBA, UNORM_INT16):
return VK_FORMAT_R16G16B16A16_UNORM;
case FMT_CASE(RGBA, SNORM_INT16):
return VK_FORMAT_R16G16B16A16_SNORM;
case FMT_CASE(RGBA, UNSIGNED_INT16):
return VK_FORMAT_R16G16B16A16_UINT;
case FMT_CASE(RGBA, SIGNED_INT16):
return VK_FORMAT_R16G16B16A16_SINT;
case FMT_CASE(RGBA, HALF_FLOAT):
return VK_FORMAT_R16G16B16A16_SFLOAT;
case FMT_CASE(R, UNSIGNED_INT32):
return VK_FORMAT_R32_UINT;
case FMT_CASE(R, SIGNED_INT32):
return VK_FORMAT_R32_SINT;
case FMT_CASE(R, UNSIGNED_INT64):
return VK_FORMAT_R64_UINT;
case FMT_CASE(R, SIGNED_INT64):
return VK_FORMAT_R64_SINT;
case FMT_CASE(R, FLOAT):
return VK_FORMAT_R32_SFLOAT;
case FMT_CASE(RG, UNSIGNED_INT32):
return VK_FORMAT_R32G32_UINT;
case FMT_CASE(RG, SIGNED_INT32):
return VK_FORMAT_R32G32_SINT;
case FMT_CASE(RG, FLOAT):
return VK_FORMAT_R32G32_SFLOAT;
case FMT_CASE(RGB, UNSIGNED_INT32):
return VK_FORMAT_R32G32B32_UINT;
case FMT_CASE(RGB, SIGNED_INT32):
return VK_FORMAT_R32G32B32_SINT;
case FMT_CASE(RGB, FLOAT):
return VK_FORMAT_R32G32B32_SFLOAT;
case FMT_CASE(RGBA, UNSIGNED_INT32):
return VK_FORMAT_R32G32B32A32_UINT;
case FMT_CASE(RGBA, SIGNED_INT32):
return VK_FORMAT_R32G32B32A32_SINT;
case FMT_CASE(RGBA, FLOAT):
return VK_FORMAT_R32G32B32A32_SFLOAT;
case FMT_CASE(R, FLOAT64):
return VK_FORMAT_R64_SFLOAT;
case FMT_CASE(RG, FLOAT64):
return VK_FORMAT_R64G64_SFLOAT;
case FMT_CASE(RGB, FLOAT64):
return VK_FORMAT_R64G64B64_SFLOAT;
case FMT_CASE(RGBA, FLOAT64):
return VK_FORMAT_R64G64B64A64_SFLOAT;
case FMT_CASE(RGB, UNSIGNED_INT_11F_11F_10F_REV):
return VK_FORMAT_B10G11R11_UFLOAT_PACK32;
case FMT_CASE(RGB, UNSIGNED_INT_999_E5_REV):
return VK_FORMAT_E5B9G9R9_UFLOAT_PACK32;
case FMT_CASE(BGR, UNORM_INT8):
return VK_FORMAT_B8G8R8_UNORM;
case FMT_CASE(BGR, SNORM_INT8):
return VK_FORMAT_B8G8R8_SNORM;
case FMT_CASE(BGR, UNSIGNED_INT8):
return VK_FORMAT_B8G8R8_UINT;
case FMT_CASE(BGR, SIGNED_INT8):
return VK_FORMAT_B8G8R8_SINT;
case FMT_CASE(BGR, USCALED_INT8):
return VK_FORMAT_B8G8R8_USCALED;
case FMT_CASE(BGR, SSCALED_INT8):
return VK_FORMAT_B8G8R8_SSCALED;
case FMT_CASE(sBGR, UNORM_INT8):
return VK_FORMAT_B8G8R8_SRGB;
case FMT_CASE(BGRA, UNORM_INT8):
return VK_FORMAT_B8G8R8A8_UNORM;
case FMT_CASE(BGRA, SNORM_INT8):
return VK_FORMAT_B8G8R8A8_SNORM;
case FMT_CASE(BGRA, UNSIGNED_INT8):
return VK_FORMAT_B8G8R8A8_UINT;
case FMT_CASE(BGRA, SIGNED_INT8):
return VK_FORMAT_B8G8R8A8_SINT;
case FMT_CASE(BGRA, USCALED_INT8):
return VK_FORMAT_B8G8R8A8_USCALED;
case FMT_CASE(BGRA, SSCALED_INT8):
return VK_FORMAT_B8G8R8A8_SSCALED;
case FMT_CASE(sBGRA, UNORM_INT8):
return VK_FORMAT_B8G8R8A8_SRGB;
case FMT_CASE(BGRA, UNORM_INT_1010102_REV):
return VK_FORMAT_A2R10G10B10_UNORM_PACK32;
case FMT_CASE(BGRA, SNORM_INT_1010102_REV):
return VK_FORMAT_A2R10G10B10_SNORM_PACK32;
case FMT_CASE(BGRA, UNSIGNED_INT_1010102_REV):
return VK_FORMAT_A2R10G10B10_UINT_PACK32;
case FMT_CASE(BGRA, SIGNED_INT_1010102_REV):
return VK_FORMAT_A2R10G10B10_SINT_PACK32;
case FMT_CASE(D, UNORM_INT16):
return VK_FORMAT_D16_UNORM;
case FMT_CASE(D, UNSIGNED_INT_24_8_REV):
return VK_FORMAT_X8_D24_UNORM_PACK32;
case FMT_CASE(D, FLOAT):
return VK_FORMAT_D32_SFLOAT;
case FMT_CASE(D, UNORM_INT24):
return VK_FORMAT_D24_UNORM_S8_UINT;
case FMT_CASE(S, UNSIGNED_INT8):
return VK_FORMAT_S8_UINT;
case FMT_CASE(DS, UNSIGNED_INT_16_8_8):
return VK_FORMAT_D16_UNORM_S8_UINT;
case FMT_CASE(DS, UNSIGNED_INT_24_8_REV):
return VK_FORMAT_D24_UNORM_S8_UINT;
case FMT_CASE(DS, FLOAT_UNSIGNED_INT_24_8_REV):
return VK_FORMAT_D32_SFLOAT_S8_UINT;
case FMT_CASE(R, UNORM_SHORT_10):
return VK_FORMAT_R10X6_UNORM_PACK16;
case FMT_CASE(RG, UNORM_SHORT_10):
return VK_FORMAT_R10X6G10X6_UNORM_2PACK16;
case FMT_CASE(RGBA, UNORM_SHORT_10):
return VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16;
case FMT_CASE(R, UNORM_SHORT_12):
return VK_FORMAT_R12X4_UNORM_PACK16;
case FMT_CASE(RG, UNORM_SHORT_12):
return VK_FORMAT_R12X4G12X4_UNORM_2PACK16;
case FMT_CASE(RGBA, UNORM_SHORT_12):
return VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16;
case FMT_CASE(R, USCALED_INT8):
return VK_FORMAT_R8_USCALED;
case FMT_CASE(RG, USCALED_INT8):
return VK_FORMAT_R8G8_USCALED;
case FMT_CASE(RGB, USCALED_INT8):
return VK_FORMAT_R8G8B8_USCALED;
case FMT_CASE(RGBA, USCALED_INT8):
return VK_FORMAT_R8G8B8A8_USCALED;
case FMT_CASE(R, USCALED_INT16):
return VK_FORMAT_R16_USCALED;
case FMT_CASE(RG, USCALED_INT16):
return VK_FORMAT_R16G16_USCALED;
case FMT_CASE(RGB, USCALED_INT16):
return VK_FORMAT_R16G16B16_USCALED;
case FMT_CASE(RGBA, USCALED_INT16):
return VK_FORMAT_R16G16B16A16_USCALED;
case FMT_CASE(R, SSCALED_INT8):
return VK_FORMAT_R8_SSCALED;
case FMT_CASE(RG, SSCALED_INT8):
return VK_FORMAT_R8G8_SSCALED;
case FMT_CASE(RGB, SSCALED_INT8):
return VK_FORMAT_R8G8B8_SSCALED;
case FMT_CASE(RGBA, SSCALED_INT8):
return VK_FORMAT_R8G8B8A8_SSCALED;
case FMT_CASE(R, SSCALED_INT16):
return VK_FORMAT_R16_SSCALED;
case FMT_CASE(RG, SSCALED_INT16):
return VK_FORMAT_R16G16_SSCALED;
case FMT_CASE(RGB, SSCALED_INT16):
return VK_FORMAT_R16G16B16_SSCALED;
case FMT_CASE(RGBA, SSCALED_INT16):
return VK_FORMAT_R16G16B16A16_SSCALED;
case FMT_CASE(RGBA, USCALED_INT_1010102_REV):
return VK_FORMAT_A2B10G10R10_USCALED_PACK32;
case FMT_CASE(RGBA, SSCALED_INT_1010102_REV):
return VK_FORMAT_A2B10G10R10_SSCALED_PACK32;
case FMT_CASE(BGRA, USCALED_INT_1010102_REV):
return VK_FORMAT_A2R10G10B10_USCALED_PACK32;
case FMT_CASE(BGRA, SSCALED_INT_1010102_REV):
return VK_FORMAT_A2R10G10B10_SSCALED_PACK32;
case FMT_CASE(ARGB, UNORM_SHORT_4444):
return VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT;
case FMT_CASE(ABGR, UNORM_SHORT_4444):
return VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT;
default:
TCU_THROW(InternalError, "Unknown texture format");
}
#undef PACK_FMT
#undef FMT_CASE
}
VkFormat mapCompressedTextureFormat(const tcu::CompressedTexFormat format)
{
// update this mapping if CompressedTexFormat changes
// 55 needed for Vulkan and 2 for AHB that won't have mapping here
DE_STATIC_ASSERT(tcu::COMPRESSEDTEXFORMAT_LAST == 57);
switch (format)
{
case tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8:
return VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8:
return VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
return VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
return VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8:
return VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8:
return VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_EAC_R11:
return VK_FORMAT_EAC_R11_UNORM_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_R11:
return VK_FORMAT_EAC_R11_SNORM_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_EAC_RG11:
return VK_FORMAT_EAC_R11G11_UNORM_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11:
return VK_FORMAT_EAC_R11G11_SNORM_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_RGBA:
return VK_FORMAT_ASTC_4x4_UNORM_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8:
return VK_FORMAT_ASTC_4x4_SRGB_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_RGBA:
return VK_FORMAT_ASTC_5x4_UNORM_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8:
return VK_FORMAT_ASTC_5x4_SRGB_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_RGBA:
return VK_FORMAT_ASTC_5x5_UNORM_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8:
return VK_FORMAT_ASTC_5x5_SRGB_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_RGBA:
return VK_FORMAT_ASTC_6x5_UNORM_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8:
return VK_FORMAT_ASTC_6x5_SRGB_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_RGBA:
return VK_FORMAT_ASTC_6x6_UNORM_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8:
return VK_FORMAT_ASTC_6x6_SRGB_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_RGBA:
return VK_FORMAT_ASTC_8x5_UNORM_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8:
return VK_FORMAT_ASTC_8x5_SRGB_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_RGBA:
return VK_FORMAT_ASTC_8x6_UNORM_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8:
return VK_FORMAT_ASTC_8x6_SRGB_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_RGBA:
return VK_FORMAT_ASTC_8x8_UNORM_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8:
return VK_FORMAT_ASTC_8x8_SRGB_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_RGBA:
return VK_FORMAT_ASTC_10x5_UNORM_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8:
return VK_FORMAT_ASTC_10x5_SRGB_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_RGBA:
return VK_FORMAT_ASTC_10x6_UNORM_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8:
return VK_FORMAT_ASTC_10x6_SRGB_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_RGBA:
return VK_FORMAT_ASTC_10x8_UNORM_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8:
return VK_FORMAT_ASTC_10x8_SRGB_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_RGBA:
return VK_FORMAT_ASTC_10x10_UNORM_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8:
return VK_FORMAT_ASTC_10x10_SRGB_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_RGBA:
return VK_FORMAT_ASTC_12x10_UNORM_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8:
return VK_FORMAT_ASTC_12x10_SRGB_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_RGBA:
return VK_FORMAT_ASTC_12x12_UNORM_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8:
return VK_FORMAT_ASTC_12x12_SRGB_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_BC1_RGB_UNORM_BLOCK:
return VK_FORMAT_BC1_RGB_UNORM_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_BC1_RGB_SRGB_BLOCK:
return VK_FORMAT_BC1_RGB_SRGB_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_BC1_RGBA_UNORM_BLOCK:
return VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_BC1_RGBA_SRGB_BLOCK:
return VK_FORMAT_BC1_RGBA_SRGB_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_BC2_UNORM_BLOCK:
return VK_FORMAT_BC2_UNORM_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_BC2_SRGB_BLOCK:
return VK_FORMAT_BC2_SRGB_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_BC3_UNORM_BLOCK:
return VK_FORMAT_BC3_UNORM_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_BC3_SRGB_BLOCK:
return VK_FORMAT_BC3_SRGB_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_BC4_UNORM_BLOCK:
return VK_FORMAT_BC4_UNORM_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK:
return VK_FORMAT_BC4_SNORM_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_BC5_UNORM_BLOCK:
return VK_FORMAT_BC5_UNORM_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK:
return VK_FORMAT_BC5_SNORM_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK:
return VK_FORMAT_BC6H_UFLOAT_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK:
return VK_FORMAT_BC6H_SFLOAT_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_BC7_UNORM_BLOCK:
return VK_FORMAT_BC7_UNORM_BLOCK;
case tcu::COMPRESSEDTEXFORMAT_BC7_SRGB_BLOCK:
return VK_FORMAT_BC7_SRGB_BLOCK;
default:
TCU_THROW(InternalError, "Unknown texture format");
return VK_FORMAT_UNDEFINED;
}
}
tcu::TextureFormat mapVkFormat(VkFormat format)
{
using tcu::TextureFormat;
// update this mapping if VkFormat changes
DE_STATIC_ASSERT(VK_CORE_FORMAT_LAST == 185);
switch (format)
{
case VK_FORMAT_R4G4_UNORM_PACK8:
return TextureFormat(TextureFormat::RG, TextureFormat::UNORM_BYTE_44);
case VK_FORMAT_R5G6B5_UNORM_PACK16:
return TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_SHORT_565);
case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
return TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_SHORT_4444);
case VK_FORMAT_R5G5B5A1_UNORM_PACK16:
return TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_SHORT_5551);
case VK_FORMAT_B5G6R5_UNORM_PACK16:
return TextureFormat(TextureFormat::BGR, TextureFormat::UNORM_SHORT_565);
case VK_FORMAT_B4G4R4A4_UNORM_PACK16:
return TextureFormat(TextureFormat::BGRA, TextureFormat::UNORM_SHORT_4444);
case VK_FORMAT_B5G5R5A1_UNORM_PACK16:
return TextureFormat(TextureFormat::BGRA, TextureFormat::UNORM_SHORT_5551);
case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
return TextureFormat(TextureFormat::ARGB, TextureFormat::UNORM_SHORT_1555);
#ifndef CTS_USES_VULKANSC
case VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR:
return TextureFormat(TextureFormat::ABGR, TextureFormat::UNORM_SHORT_1555);
#endif // CTS_USES_VULKANSC
case VK_FORMAT_R8_UNORM:
return TextureFormat(TextureFormat::R, TextureFormat::UNORM_INT8);
case VK_FORMAT_R8_SNORM:
return TextureFormat(TextureFormat::R, TextureFormat::SNORM_INT8);
case VK_FORMAT_R8_USCALED:
return TextureFormat(TextureFormat::R, TextureFormat::USCALED_INT8);
case VK_FORMAT_R8_SSCALED:
return TextureFormat(TextureFormat::R, TextureFormat::SSCALED_INT8);
case VK_FORMAT_R8_UINT:
return TextureFormat(TextureFormat::R, TextureFormat::UNSIGNED_INT8);
case VK_FORMAT_R8_SINT:
return TextureFormat(TextureFormat::R, TextureFormat::SIGNED_INT8);
case VK_FORMAT_R8_SRGB:
return TextureFormat(TextureFormat::sR, TextureFormat::UNORM_INT8);
#ifndef CTS_USES_VULKANSC
case VK_FORMAT_A8_UNORM_KHR:
return TextureFormat(TextureFormat::A, TextureFormat::UNORM_INT8);
#endif // CTS_USES_VULKANSC
case VK_FORMAT_R8G8_UNORM:
return TextureFormat(TextureFormat::RG, TextureFormat::UNORM_INT8);
case VK_FORMAT_R8G8_SNORM:
return TextureFormat(TextureFormat::RG, TextureFormat::SNORM_INT8);
case VK_FORMAT_R8G8_USCALED:
return TextureFormat(TextureFormat::RG, TextureFormat::USCALED_INT8);
case VK_FORMAT_R8G8_SSCALED:
return TextureFormat(TextureFormat::RG, TextureFormat::SSCALED_INT8);
case VK_FORMAT_R8G8_UINT:
return TextureFormat(TextureFormat::RG, TextureFormat::UNSIGNED_INT8);
case VK_FORMAT_R8G8_SINT:
return TextureFormat(TextureFormat::RG, TextureFormat::SIGNED_INT8);
case VK_FORMAT_R8G8_SRGB:
return TextureFormat(TextureFormat::sRG, TextureFormat::UNORM_INT8);
case VK_FORMAT_R8G8B8_UNORM:
return TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8);
case VK_FORMAT_R8G8B8_SNORM:
return TextureFormat(TextureFormat::RGB, TextureFormat::SNORM_INT8);
case VK_FORMAT_R8G8B8_USCALED:
return TextureFormat(TextureFormat::RGB, TextureFormat::USCALED_INT8);
case VK_FORMAT_R8G8B8_SSCALED:
return TextureFormat(TextureFormat::RGB, TextureFormat::SSCALED_INT8);
case VK_FORMAT_R8G8B8_UINT:
return TextureFormat(TextureFormat::RGB, TextureFormat::UNSIGNED_INT8);
case VK_FORMAT_R8G8B8_SINT:
return TextureFormat(TextureFormat::RGB, TextureFormat::SIGNED_INT8);
case VK_FORMAT_R8G8B8_SRGB:
return TextureFormat(TextureFormat::sRGB, TextureFormat::UNORM_INT8);
case VK_FORMAT_R8G8B8A8_UNORM:
return TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8);
case VK_FORMAT_R8G8B8A8_SNORM:
return TextureFormat(TextureFormat::RGBA, TextureFormat::SNORM_INT8);
case VK_FORMAT_R8G8B8A8_USCALED:
return TextureFormat(TextureFormat::RGBA, TextureFormat::USCALED_INT8);
case VK_FORMAT_R8G8B8A8_SSCALED:
return TextureFormat(TextureFormat::RGBA, TextureFormat::SSCALED_INT8);
case VK_FORMAT_R8G8B8A8_UINT:
return TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT8);
case VK_FORMAT_R8G8B8A8_SINT:
return TextureFormat(TextureFormat::RGBA, TextureFormat::SIGNED_INT8);
case VK_FORMAT_R8G8B8A8_SRGB:
return TextureFormat(TextureFormat::sRGBA, TextureFormat::UNORM_INT8);
case VK_FORMAT_R16_UNORM:
return TextureFormat(TextureFormat::R, TextureFormat::UNORM_INT16);
case VK_FORMAT_R16_SNORM:
return TextureFormat(TextureFormat::R, TextureFormat::SNORM_INT16);
case VK_FORMAT_R16_USCALED:
return TextureFormat(TextureFormat::R, TextureFormat::USCALED_INT16);
case VK_FORMAT_R16_SSCALED:
return TextureFormat(TextureFormat::R, TextureFormat::SSCALED_INT16);
case VK_FORMAT_R16_UINT:
return TextureFormat(TextureFormat::R, TextureFormat::UNSIGNED_INT16);
case VK_FORMAT_R16_SINT:
return TextureFormat(TextureFormat::R, TextureFormat::SIGNED_INT16);
case VK_FORMAT_R16_SFLOAT:
return TextureFormat(TextureFormat::R, TextureFormat::HALF_FLOAT);
case VK_FORMAT_R16G16_UNORM:
return TextureFormat(TextureFormat::RG, TextureFormat::UNORM_INT16);
case VK_FORMAT_R16G16_SNORM:
return TextureFormat(TextureFormat::RG, TextureFormat::SNORM_INT16);
case VK_FORMAT_R16G16_USCALED:
return TextureFormat(TextureFormat::RG, TextureFormat::USCALED_INT16);
case VK_FORMAT_R16G16_SSCALED:
return TextureFormat(TextureFormat::RG, TextureFormat::SSCALED_INT16);
case VK_FORMAT_R16G16_UINT:
return TextureFormat(TextureFormat::RG, TextureFormat::UNSIGNED_INT16);
case VK_FORMAT_R16G16_SINT:
return TextureFormat(TextureFormat::RG, TextureFormat::SIGNED_INT16);
case VK_FORMAT_R16G16_SFLOAT:
return TextureFormat(TextureFormat::RG, TextureFormat::HALF_FLOAT);
case VK_FORMAT_R16G16B16_UNORM:
return TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT16);
case VK_FORMAT_R16G16B16_SNORM:
return TextureFormat(TextureFormat::RGB, TextureFormat::SNORM_INT16);
case VK_FORMAT_R16G16B16_USCALED:
return TextureFormat(TextureFormat::RGB, TextureFormat::USCALED_INT16);
case VK_FORMAT_R16G16B16_SSCALED:
return TextureFormat(TextureFormat::RGB, TextureFormat::SSCALED_INT16);
case VK_FORMAT_R16G16B16_UINT:
return TextureFormat(TextureFormat::RGB, TextureFormat::UNSIGNED_INT16);
case VK_FORMAT_R16G16B16_SINT:
return TextureFormat(TextureFormat::RGB, TextureFormat::SIGNED_INT16);
case VK_FORMAT_R16G16B16_SFLOAT:
return TextureFormat(TextureFormat::RGB, TextureFormat::HALF_FLOAT);
case VK_FORMAT_R16G16B16A16_UNORM:
return TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT16);
case VK_FORMAT_R16G16B16A16_SNORM:
return TextureFormat(TextureFormat::RGBA, TextureFormat::SNORM_INT16);
case VK_FORMAT_R16G16B16A16_USCALED:
return TextureFormat(TextureFormat::RGBA, TextureFormat::USCALED_INT16);
case VK_FORMAT_R16G16B16A16_SSCALED:
return TextureFormat(TextureFormat::RGBA, TextureFormat::SSCALED_INT16);
case VK_FORMAT_R16G16B16A16_UINT:
return TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT16);
case VK_FORMAT_R16G16B16A16_SINT:
return TextureFormat(TextureFormat::RGBA, TextureFormat::SIGNED_INT16);
case VK_FORMAT_R16G16B16A16_SFLOAT:
return TextureFormat(TextureFormat::RGBA, TextureFormat::HALF_FLOAT);
case VK_FORMAT_R32_UINT:
return TextureFormat(TextureFormat::R, TextureFormat::UNSIGNED_INT32);
case VK_FORMAT_R32_SINT:
return TextureFormat(TextureFormat::R, TextureFormat::SIGNED_INT32);
case VK_FORMAT_R32_SFLOAT:
return TextureFormat(TextureFormat::R, TextureFormat::FLOAT);
case VK_FORMAT_R32G32_UINT:
return TextureFormat(TextureFormat::RG, TextureFormat::UNSIGNED_INT32);
case VK_FORMAT_R32G32_SINT:
return TextureFormat(TextureFormat::RG, TextureFormat::SIGNED_INT32);
case VK_FORMAT_R32G32_SFLOAT:
return TextureFormat(TextureFormat::RG, TextureFormat::FLOAT);
case VK_FORMAT_R32G32B32_UINT:
return TextureFormat(TextureFormat::RGB, TextureFormat::UNSIGNED_INT32);
case VK_FORMAT_R32G32B32_SINT:
return TextureFormat(TextureFormat::RGB, TextureFormat::SIGNED_INT32);
case VK_FORMAT_R32G32B32_SFLOAT:
return TextureFormat(TextureFormat::RGB, TextureFormat::FLOAT);
case VK_FORMAT_R32G32B32A32_UINT:
return TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32);
case VK_FORMAT_R32G32B32A32_SINT:
return TextureFormat(TextureFormat::RGBA, TextureFormat::SIGNED_INT32);
case VK_FORMAT_R32G32B32A32_SFLOAT:
return TextureFormat(TextureFormat::RGBA, TextureFormat::FLOAT);
case VK_FORMAT_R64_UINT:
return TextureFormat(TextureFormat::R, TextureFormat::UNSIGNED_INT64);
case VK_FORMAT_R64G64_UINT:
return TextureFormat(TextureFormat::RG, TextureFormat::UNSIGNED_INT64);
case VK_FORMAT_R64G64B64_UINT:
return TextureFormat(TextureFormat::RGB, TextureFormat::UNSIGNED_INT64);
case VK_FORMAT_R64G64B64A64_UINT:
return TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT64);
case VK_FORMAT_R64_SINT:
return TextureFormat(TextureFormat::R, TextureFormat::SIGNED_INT64);
case VK_FORMAT_R64G64_SINT:
return TextureFormat(TextureFormat::RG, TextureFormat::SIGNED_INT64);
case VK_FORMAT_R64G64B64_SINT:
return TextureFormat(TextureFormat::RGB, TextureFormat::SIGNED_INT64);
case VK_FORMAT_R64G64B64A64_SINT:
return TextureFormat(TextureFormat::RGBA, TextureFormat::SIGNED_INT64);
case VK_FORMAT_R64_SFLOAT:
return TextureFormat(TextureFormat::R, TextureFormat::FLOAT64);
case VK_FORMAT_R64G64_SFLOAT:
return TextureFormat(TextureFormat::RG, TextureFormat::FLOAT64);
case VK_FORMAT_R64G64B64_SFLOAT:
return TextureFormat(TextureFormat::RGB, TextureFormat::FLOAT64);
case VK_FORMAT_R64G64B64A64_SFLOAT:
return TextureFormat(TextureFormat::RGBA, TextureFormat::FLOAT64);
case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
return TextureFormat(TextureFormat::RGB, TextureFormat::UNSIGNED_INT_11F_11F_10F_REV);
case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:
return TextureFormat(TextureFormat::RGB, TextureFormat::UNSIGNED_INT_999_E5_REV);
case VK_FORMAT_B8G8R8_UNORM:
return TextureFormat(TextureFormat::BGR, TextureFormat::UNORM_INT8);
case VK_FORMAT_B8G8R8_SNORM:
return TextureFormat(TextureFormat::BGR, TextureFormat::SNORM_INT8);
case VK_FORMAT_B8G8R8_USCALED:
return TextureFormat(TextureFormat::BGR, TextureFormat::USCALED_INT8);
case VK_FORMAT_B8G8R8_SSCALED:
return TextureFormat(TextureFormat::BGR, TextureFormat::SSCALED_INT8);
case VK_FORMAT_B8G8R8_UINT:
return TextureFormat(TextureFormat::BGR, TextureFormat::UNSIGNED_INT8);
case VK_FORMAT_B8G8R8_SINT:
return TextureFormat(TextureFormat::BGR, TextureFormat::SIGNED_INT8);
case VK_FORMAT_B8G8R8_SRGB:
return TextureFormat(TextureFormat::sBGR, TextureFormat::UNORM_INT8);
case VK_FORMAT_B8G8R8A8_UNORM:
return TextureFormat(TextureFormat::BGRA, TextureFormat::UNORM_INT8);
case VK_FORMAT_B8G8R8A8_SNORM:
return TextureFormat(TextureFormat::BGRA, TextureFormat::SNORM_INT8);
case VK_FORMAT_B8G8R8A8_USCALED:
return TextureFormat(TextureFormat::BGRA, TextureFormat::USCALED_INT8);
case VK_FORMAT_B8G8R8A8_SSCALED:
return TextureFormat(TextureFormat::BGRA, TextureFormat::SSCALED_INT8);
case VK_FORMAT_B8G8R8A8_UINT:
return TextureFormat(TextureFormat::BGRA, TextureFormat::UNSIGNED_INT8);
case VK_FORMAT_B8G8R8A8_SINT:
return TextureFormat(TextureFormat::BGRA, TextureFormat::SIGNED_INT8);
case VK_FORMAT_B8G8R8A8_SRGB:
return TextureFormat(TextureFormat::sBGRA, TextureFormat::UNORM_INT8);
case VK_FORMAT_D16_UNORM:
return TextureFormat(TextureFormat::D, TextureFormat::UNORM_INT16);
case VK_FORMAT_X8_D24_UNORM_PACK32:
return TextureFormat(TextureFormat::D, TextureFormat::UNSIGNED_INT_24_8_REV);
case VK_FORMAT_D32_SFLOAT:
return TextureFormat(TextureFormat::D, TextureFormat::FLOAT);
case VK_FORMAT_S8_UINT:
return TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8);
// \note There is no standard interleaved memory layout for DS formats; buffer-image copies
// will always operate on either D or S aspect only. See Khronos bug 12998
case VK_FORMAT_D16_UNORM_S8_UINT:
return TextureFormat(TextureFormat::DS, TextureFormat::UNSIGNED_INT_16_8_8);
case VK_FORMAT_D24_UNORM_S8_UINT:
return TextureFormat(TextureFormat::DS, TextureFormat::UNSIGNED_INT_24_8_REV);
case VK_FORMAT_D32_SFLOAT_S8_UINT:
return TextureFormat(TextureFormat::DS, TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV);
#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
return TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8);
case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
return TextureFormat(TextureFormat::RGBA, TextureFormat::SNORM_INT8);
case VK_FORMAT_A8B8G8R8_USCALED_PACK32:
return TextureFormat(TextureFormat::RGBA, TextureFormat::USCALED_INT8);
case VK_FORMAT_A8B8G8R8_SSCALED_PACK32:
return TextureFormat(TextureFormat::RGBA, TextureFormat::SSCALED_INT8);
case VK_FORMAT_A8B8G8R8_UINT_PACK32:
return TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT8);
case VK_FORMAT_A8B8G8R8_SINT_PACK32:
return TextureFormat(TextureFormat::RGBA, TextureFormat::SIGNED_INT8);
case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
return TextureFormat(TextureFormat::sRGBA, TextureFormat::UNORM_INT8);
#else
#error "Big-endian not supported"
#endif
case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
return TextureFormat(TextureFormat::BGRA, TextureFormat::UNORM_INT_1010102_REV);
case VK_FORMAT_A2R10G10B10_SNORM_PACK32:
return TextureFormat(TextureFormat::BGRA, TextureFormat::SNORM_INT_1010102_REV);
case VK_FORMAT_A2R10G10B10_USCALED_PACK32:
return TextureFormat(TextureFormat::BGRA, TextureFormat::USCALED_INT_1010102_REV);
case VK_FORMAT_A2R10G10B10_SSCALED_PACK32:
return TextureFormat(TextureFormat::BGRA, TextureFormat::SSCALED_INT_1010102_REV);
case VK_FORMAT_A2R10G10B10_UINT_PACK32:
return TextureFormat(TextureFormat::BGRA, TextureFormat::UNSIGNED_INT_1010102_REV);
case VK_FORMAT_A2R10G10B10_SINT_PACK32:
return TextureFormat(TextureFormat::BGRA, TextureFormat::SIGNED_INT_1010102_REV);
case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
return TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT_1010102_REV);
case VK_FORMAT_A2B10G10R10_SNORM_PACK32:
return TextureFormat(TextureFormat::RGBA, TextureFormat::SNORM_INT_1010102_REV);
case VK_FORMAT_A2B10G10R10_USCALED_PACK32:
return TextureFormat(TextureFormat::RGBA, TextureFormat::USCALED_INT_1010102_REV);
case VK_FORMAT_A2B10G10R10_SSCALED_PACK32:
return TextureFormat(TextureFormat::RGBA, TextureFormat::SSCALED_INT_1010102_REV);
case VK_FORMAT_A2B10G10R10_UINT_PACK32:
return TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT_1010102_REV);
case VK_FORMAT_A2B10G10R10_SINT_PACK32:
return TextureFormat(TextureFormat::RGBA, TextureFormat::SIGNED_INT_1010102_REV);
// YCbCr formats that can be mapped
case VK_FORMAT_R10X6_UNORM_PACK16:
return TextureFormat(TextureFormat::R, TextureFormat::UNORM_SHORT_10);
case VK_FORMAT_R10X6G10X6_UNORM_2PACK16:
return TextureFormat(TextureFormat::RG, TextureFormat::UNORM_SHORT_10);
case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:
return TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_SHORT_10);
case VK_FORMAT_R12X4_UNORM_PACK16:
return TextureFormat(TextureFormat::R, TextureFormat::UNORM_SHORT_12);
case VK_FORMAT_R12X4G12X4_UNORM_2PACK16:
return TextureFormat(TextureFormat::RG, TextureFormat::UNORM_SHORT_12);
case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:
return TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_SHORT_12);
case VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT:
return TextureFormat(TextureFormat::ARGB, TextureFormat::UNORM_SHORT_4444);
case VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT:
return TextureFormat(TextureFormat::ABGR, TextureFormat::UNORM_SHORT_4444);
default:
TCU_THROW(InternalError, "Unknown image format");
}
}
tcu::CompressedTexFormat mapVkCompressedFormat(VkFormat format)
{
// update this mapping if VkFormat changes
DE_STATIC_ASSERT(VK_CORE_FORMAT_LAST == 185);
switch (format)
{
case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8;
case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8;
case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1;
case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1;
case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8;
case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8;
case VK_FORMAT_EAC_R11_UNORM_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_EAC_R11;
case VK_FORMAT_EAC_R11_SNORM_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_R11;
case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_EAC_RG11;
case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11;
case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_RGBA;
case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8;
case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_RGBA;
case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8;
case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_RGBA;
case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8;
case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_RGBA;
case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8;
case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_RGBA;
case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8;
case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_RGBA;
case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8;
case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_RGBA;
case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8;
case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_RGBA;
case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8;
case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_RGBA;
case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8;
case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_RGBA;
case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8;
case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_RGBA;
case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8;
case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_RGBA;
case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8;
case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_RGBA;
case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8;
case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_RGBA;
case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8;
case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_BC1_RGB_UNORM_BLOCK;
case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_BC1_RGB_SRGB_BLOCK;
case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_BC1_RGBA_UNORM_BLOCK;
case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_BC1_RGBA_SRGB_BLOCK;
case VK_FORMAT_BC2_UNORM_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_BC2_UNORM_BLOCK;
case VK_FORMAT_BC2_SRGB_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_BC2_SRGB_BLOCK;
case VK_FORMAT_BC3_UNORM_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_BC3_UNORM_BLOCK;
case VK_FORMAT_BC3_SRGB_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_BC3_SRGB_BLOCK;
case VK_FORMAT_BC4_UNORM_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_BC4_UNORM_BLOCK;
case VK_FORMAT_BC4_SNORM_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK;
case VK_FORMAT_BC5_UNORM_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_BC5_UNORM_BLOCK;
case VK_FORMAT_BC5_SNORM_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK;
case VK_FORMAT_BC6H_UFLOAT_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK;
case VK_FORMAT_BC6H_SFLOAT_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK;
case VK_FORMAT_BC7_UNORM_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_BC7_UNORM_BLOCK;
case VK_FORMAT_BC7_SRGB_BLOCK:
return tcu::COMPRESSEDTEXFORMAT_BC7_SRGB_BLOCK;
default:
TCU_THROW(InternalError, "Unknown image format");
return tcu::COMPRESSEDTEXFORMAT_LAST;
}
}
static bool fullTextureFormatRoundTripSupported(VkFormat format)
{
if (isScaledFormat(format))
{
// *SCALED formats get mapped to correspoding (u)int formats since
// accessing them through (float) getPixel/setPixel has same behavior
// as in shader access in Vulkan.
// Unfortunately full round-trip between tcu::TextureFormat and VkFormat
// for most SCALED formats is not supported though.
const tcu::TextureFormat tcuFormat = mapVkFormat(format);
switch (tcuFormat.type)
{
case tcu::TextureFormat::UNSIGNED_INT8:
case tcu::TextureFormat::UNSIGNED_INT16:
case tcu::TextureFormat::UNSIGNED_INT32:
case tcu::TextureFormat::SIGNED_INT8:
case tcu::TextureFormat::SIGNED_INT16:
case tcu::TextureFormat::SIGNED_INT32:
case tcu::TextureFormat::UNSIGNED_INT_1010102_REV:
case tcu::TextureFormat::SIGNED_INT_1010102_REV:
return false;
default:
return true;
}
}
else
{
switch (format)
{
case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
case VK_FORMAT_A8B8G8R8_USCALED_PACK32:
case VK_FORMAT_A8B8G8R8_SSCALED_PACK32:
case VK_FORMAT_A8B8G8R8_UINT_PACK32:
case VK_FORMAT_A8B8G8R8_SINT_PACK32:
case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
return false; // These map to regular byte array formats
default:
break;
}
return (format != VK_FORMAT_UNDEFINED);
}
}
tcu::TextureFormat getChannelAccessFormat(tcu::TextureChannelClass type, uint32_t offsetBits, uint32_t sizeBits)
{
using tcu::TextureFormat;
if (offsetBits == 0)
{
static const TextureFormat::ChannelType s_size8[tcu::TEXTURECHANNELCLASS_LAST] = {
TextureFormat::SNORM_INT8, // snorm
TextureFormat::UNORM_INT8, // unorm
TextureFormat::SIGNED_INT8, // sint
TextureFormat::UNSIGNED_INT8, // uint
TextureFormat::CHANNELTYPE_LAST, // float
};
static const TextureFormat::ChannelType s_size16[tcu::TEXTURECHANNELCLASS_LAST] = {
TextureFormat::SNORM_INT16, // snorm
TextureFormat::UNORM_INT16, // unorm
TextureFormat::SIGNED_INT16, // sint
TextureFormat::UNSIGNED_INT16, // uint
TextureFormat::HALF_FLOAT, // float
};
static const TextureFormat::ChannelType s_size32[tcu::TEXTURECHANNELCLASS_LAST] = {
TextureFormat::SNORM_INT32, // snorm
TextureFormat::UNORM_INT32, // unorm
TextureFormat::SIGNED_INT32, // sint
TextureFormat::UNSIGNED_INT32, // uint
TextureFormat::FLOAT, // float
};
static const TextureFormat::ChannelType s_size64[tcu::TEXTURECHANNELCLASS_LAST] = {
TextureFormat::CHANNELTYPE_LAST, // snorm
TextureFormat::CHANNELTYPE_LAST, // unorm
TextureFormat::SIGNED_INT64, // sint
TextureFormat::UNSIGNED_INT64, // uint
TextureFormat::FLOAT64, // float
};
TextureFormat::ChannelType chnType = TextureFormat::CHANNELTYPE_LAST;
if (sizeBits == 8)
chnType = s_size8[type];
else if (sizeBits == 16)
chnType = s_size16[type];
else if (sizeBits == 32)
chnType = s_size32[type];
else if (sizeBits == 64)
chnType = s_size64[type];
if (chnType != TextureFormat::CHANNELTYPE_LAST)
return TextureFormat(TextureFormat::R, chnType);
}
else
{
if (type == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT && offsetBits == 6 && sizeBits == 10)
return TextureFormat(TextureFormat::R, TextureFormat::UNORM_SHORT_10);
else if (type == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT && offsetBits == 4 && sizeBits == 12)
return TextureFormat(TextureFormat::R, TextureFormat::UNORM_SHORT_12);
}
TCU_THROW(InternalError, "Channel access format is not supported");
}
tcu::PixelBufferAccess getChannelAccess(const PlanarFormatDescription &formatInfo, const tcu::UVec2 &size,
const uint32_t *planeRowPitches, void *const *planePtrs, uint32_t channelNdx)
{
DE_ASSERT(formatInfo.hasChannelNdx(channelNdx));
const uint32_t planeNdx = formatInfo.channels[channelNdx].planeNdx;
const uint32_t planeOffsetBytes = formatInfo.channels[channelNdx].offsetBits / 8;
const uint32_t valueOffsetBits = formatInfo.channels[channelNdx].offsetBits % 8;
const uint32_t pixelStrideBytes = formatInfo.channels[channelNdx].strideBytes;
DE_ASSERT(size.x() % (formatInfo.blockWidth * formatInfo.planes[planeNdx].widthDivisor) == 0);
DE_ASSERT(size.y() % (formatInfo.blockHeight * formatInfo.planes[planeNdx].heightDivisor) == 0);
const uint32_t accessHeight = size.y() / (formatInfo.blockHeight * formatInfo.planes[planeNdx].heightDivisor);
const uint32_t elementSizeBytes = formatInfo.planes[planeNdx].elementSizeBytes;
const uint32_t rowPitch = planeRowPitches[planeNdx];
DE_ASSERT(elementSizeBytes % pixelStrideBytes == 0);
tcu::IVec3 texDivider(
std::max(formatInfo.blockWidth * formatInfo.planes[planeNdx].widthDivisor * pixelStrideBytes / elementSizeBytes,
1u),
std::max(formatInfo.blockHeight * formatInfo.planes[planeNdx].heightDivisor * pixelStrideBytes /
elementSizeBytes,
1u),
1);
return tcu::PixelBufferAccess(getChannelAccessFormat((tcu::TextureChannelClass)formatInfo.channels[channelNdx].type,
valueOffsetBits, formatInfo.channels[channelNdx].sizeBits),
tcu::IVec3((int)size.x(), (int)size.y(), 1),
tcu::IVec3((int)pixelStrideBytes, (int)rowPitch, (int)(accessHeight * rowPitch)),
texDivider, (uint8_t *)planePtrs[planeNdx] + planeOffsetBytes);
}
tcu::ConstPixelBufferAccess getChannelAccess(const PlanarFormatDescription &formatInfo, const tcu::UVec2 &size,
const uint32_t *planeRowPitches, const void *const *planePtrs,
uint32_t channelNdx)
{
return getChannelAccess(formatInfo, size, planeRowPitches, const_cast<void *const *>(planePtrs), channelNdx);
}
tcu::PixelBufferAccess getChannelAccess(const PlanarFormatDescription &formatInfo, const tcu::UVec3 &size,
const uint32_t *planeRowPitches, void *const *planePtrs, uint32_t channelNdx)
{
DE_ASSERT(formatInfo.hasChannelNdx(channelNdx));
const uint32_t planeNdx = formatInfo.channels[channelNdx].planeNdx;
const uint32_t planeOffsetBytes = formatInfo.channels[channelNdx].offsetBits / 8;
const uint32_t valueOffsetBits = formatInfo.channels[channelNdx].offsetBits % 8;
const uint32_t pixelStrideBytes = formatInfo.channels[channelNdx].strideBytes;
DE_ASSERT(size.x() % (formatInfo.blockWidth * formatInfo.planes[planeNdx].widthDivisor) == 0);
DE_ASSERT(size.y() % (formatInfo.blockHeight * formatInfo.planes[planeNdx].heightDivisor) == 0);
const uint32_t accessHeight = size.y() / (formatInfo.blockHeight * formatInfo.planes[planeNdx].heightDivisor);
const uint32_t elementSizeBytes = formatInfo.planes[planeNdx].elementSizeBytes;
const uint32_t rowPitch = planeRowPitches[planeNdx];
DE_ASSERT(elementSizeBytes % pixelStrideBytes == 0);
tcu::IVec3 texDivider(
std::max(formatInfo.blockWidth * formatInfo.planes[planeNdx].widthDivisor * pixelStrideBytes / elementSizeBytes,
1u),
std::max(formatInfo.blockHeight * formatInfo.planes[planeNdx].heightDivisor * pixelStrideBytes /
elementSizeBytes,
1u),
1);
return tcu::PixelBufferAccess(getChannelAccessFormat((tcu::TextureChannelClass)formatInfo.channels[channelNdx].type,
valueOffsetBits, formatInfo.channels[channelNdx].sizeBits),
tcu::IVec3((int)size.x(), (int)size.y(), (int)size.z()),
tcu::IVec3((int)pixelStrideBytes, (int)rowPitch, (int)(accessHeight * rowPitch)),
texDivider, (uint8_t *)planePtrs[planeNdx] + planeOffsetBytes);
}
tcu::ConstPixelBufferAccess getChannelAccess(const PlanarFormatDescription &formatInfo, const tcu::UVec3 &size,
const uint32_t *planeRowPitches, const void *const *planePtrs,
uint32_t channelNdx)
{
return getChannelAccess(formatInfo, size, planeRowPitches, const_cast<void *const *>(planePtrs), channelNdx);
}
void imageUtilSelfTest(void)
{
for (int formatNdx = 0; formatNdx < VK_CORE_FORMAT_LAST; formatNdx++)
{
const VkFormat format = (VkFormat)formatNdx;
if (format == VK_FORMAT_R64_UINT || format == VK_FORMAT_R64_SINT || format == VK_FORMAT_R64G64_UINT ||
format == VK_FORMAT_R64G64_SINT || format == VK_FORMAT_R64G64B64_UINT ||
format == VK_FORMAT_R64G64B64_SINT || format == VK_FORMAT_R64G64B64A64_UINT ||
format == VK_FORMAT_R64G64B64A64_SINT)
continue; // \todo [2015-12-05 pyry] Add framework support for (u)int64 channel type
if (format != VK_FORMAT_UNDEFINED && !isCompressedFormat(format))
{
const tcu::TextureFormat tcuFormat = mapVkFormat(format);
const VkFormat remappedFormat = mapTextureFormat(tcuFormat);
DE_TEST_ASSERT(isValid(tcuFormat));
if (fullTextureFormatRoundTripSupported(format))
DE_TEST_ASSERT(format == remappedFormat);
}
}
for (int formatNdx = VK_FORMAT_G8B8G8R8_422_UNORM; formatNdx <= VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM; formatNdx++)
{
const VkFormat format = (VkFormat)formatNdx;
const PlanarFormatDescription &info = getPlanarFormatDescription(format);
DE_TEST_ASSERT(isYCbCrFormat(format));
DE_TEST_ASSERT(de::inRange<uint8_t>(info.numPlanes, 1u, 3u));
DE_TEST_ASSERT(info.numPlanes == getPlaneCount(format));
}
for (int formatNdx = VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT; formatNdx <= VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT;
formatNdx++)
{
const VkFormat format = (VkFormat)formatNdx;
const PlanarFormatDescription &info = getPlanarFormatDescription(format);
DE_TEST_ASSERT(isYCbCrFormat(format));
DE_TEST_ASSERT(de::inRange<uint8_t>(info.numPlanes, 1u, 3u));
DE_TEST_ASSERT(info.numPlanes == getPlaneCount(format));
}
}
struct CompressedFormatParameters
{
VkFormat format;
uint32_t blockBytes;
uint32_t blockWidth;
uint32_t blockHeight;
};
CompressedFormatParameters compressedFormatParameters[VK_FORMAT_ASTC_12x12_SRGB_BLOCK - VK_FORMAT_BC1_RGB_UNORM_BLOCK +
1] = {{VK_FORMAT_BC1_RGB_UNORM_BLOCK, 8, 4, 4},
{VK_FORMAT_BC1_RGB_SRGB_BLOCK, 8, 4, 4},
{VK_FORMAT_BC1_RGBA_UNORM_BLOCK, 8, 4, 4},
{VK_FORMAT_BC1_RGBA_SRGB_BLOCK, 8, 4, 4},
{VK_FORMAT_BC2_UNORM_BLOCK, 16, 4, 4},
{VK_FORMAT_BC2_SRGB_BLOCK, 16, 4, 4},
{VK_FORMAT_BC3_UNORM_BLOCK, 16, 4, 4},
{VK_FORMAT_BC3_SRGB_BLOCK, 16, 4, 4},
{VK_FORMAT_BC4_UNORM_BLOCK, 8, 4, 4},
{VK_FORMAT_BC4_SNORM_BLOCK, 8, 4, 4},
{VK_FORMAT_BC5_UNORM_BLOCK, 16, 4, 4},
{VK_FORMAT_BC5_SNORM_BLOCK, 16, 4, 4},
{VK_FORMAT_BC6H_UFLOAT_BLOCK, 16, 4, 4},
{VK_FORMAT_BC6H_SFLOAT_BLOCK, 16, 4, 4},
{VK_FORMAT_BC7_UNORM_BLOCK, 16, 4, 4},
{VK_FORMAT_BC7_SRGB_BLOCK, 16, 4, 4},
{VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, 8, 4, 4},
{VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK, 8, 4, 4},
{VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, 8, 4, 4},
{VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK, 8, 4, 4},
{VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, 16, 4, 4},
{VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK, 16, 4, 4},
{VK_FORMAT_EAC_R11_UNORM_BLOCK, 8, 4, 4},
{VK_FORMAT_EAC_R11_SNORM_BLOCK, 8, 4, 4},
{VK_FORMAT_EAC_R11G11_UNORM_BLOCK, 16, 4, 4},
{VK_FORMAT_EAC_R11G11_SNORM_BLOCK, 16, 4, 4},
{VK_FORMAT_ASTC_4x4_UNORM_BLOCK, 16, 4, 4},
{VK_FORMAT_ASTC_4x4_SRGB_BLOCK, 16, 4, 4},
{VK_FORMAT_ASTC_5x4_UNORM_BLOCK, 16, 5, 4},
{VK_FORMAT_ASTC_5x4_SRGB_BLOCK, 16, 5, 4},
{VK_FORMAT_ASTC_5x5_UNORM_BLOCK, 16, 5, 5},
{VK_FORMAT_ASTC_5x5_SRGB_BLOCK, 16, 5, 5},
{VK_FORMAT_ASTC_6x5_UNORM_BLOCK, 16, 6, 5},
{VK_FORMAT_ASTC_6x5_SRGB_BLOCK, 16, 6, 5},
{VK_FORMAT_ASTC_6x6_UNORM_BLOCK, 16, 6, 6},
{VK_FORMAT_ASTC_6x6_SRGB_BLOCK, 16, 6, 6},
{VK_FORMAT_ASTC_8x5_UNORM_BLOCK, 16, 8, 5},
{VK_FORMAT_ASTC_8x5_SRGB_BLOCK, 16, 8, 5},
{VK_FORMAT_ASTC_8x6_UNORM_BLOCK, 16, 8, 6},
{VK_FORMAT_ASTC_8x6_SRGB_BLOCK, 16, 8, 6},
{VK_FORMAT_ASTC_8x8_UNORM_BLOCK, 16, 8, 8},
{VK_FORMAT_ASTC_8x8_SRGB_BLOCK, 16, 8, 8},
{VK_FORMAT_ASTC_10x5_UNORM_BLOCK, 16, 10, 5},
{VK_FORMAT_ASTC_10x5_SRGB_BLOCK, 16, 10, 5},
{VK_FORMAT_ASTC_10x6_UNORM_BLOCK, 16, 10, 6},
{VK_FORMAT_ASTC_10x6_SRGB_BLOCK, 16, 10, 6},
{VK_FORMAT_ASTC_10x8_UNORM_BLOCK, 16, 10, 8},
{VK_FORMAT_ASTC_10x8_SRGB_BLOCK, 16, 10, 8},
{VK_FORMAT_ASTC_10x10_UNORM_BLOCK, 16, 10, 10},
{VK_FORMAT_ASTC_10x10_SRGB_BLOCK, 16, 10, 10},
{VK_FORMAT_ASTC_12x10_UNORM_BLOCK, 16, 12, 10},
{VK_FORMAT_ASTC_12x10_SRGB_BLOCK, 16, 12, 10},
{VK_FORMAT_ASTC_12x12_UNORM_BLOCK, 16, 12, 12},
{VK_FORMAT_ASTC_12x12_SRGB_BLOCK, 16, 12, 12}};
uint32_t getFormatComponentWidth(const VkFormat format, const uint32_t componentNdx)
{
const bool isAlphaOnly = isAlphaOnlyFormat(format);
const tcu::TextureFormat tcuFormat(mapVkFormat(format));
const uint32_t componentCount(isAlphaOnly ? 4u : tcu::getNumUsedChannels(tcuFormat.order));
if (isAlphaOnly && componentCount < 3u)
return 0; // RGB has no width for A8_UNORM
if (componentNdx >= componentCount)
DE_FATAL("Component index out of range");
else
{
switch (tcuFormat.type)
{
case tcu::TextureFormat::UNORM_INT8:
case tcu::TextureFormat::SNORM_INT8:
case tcu::TextureFormat::UNSIGNED_INT8:
case tcu::TextureFormat::SIGNED_INT8:
return 8;
case tcu::TextureFormat::UNORM_SHORT_10:
return 10;
case tcu::TextureFormat::UNORM_SHORT_12:
return 12;
case tcu::TextureFormat::UNORM_INT16:
case tcu::TextureFormat::SNORM_INT16:
case tcu::TextureFormat::UNSIGNED_INT16:
case tcu::TextureFormat::SIGNED_INT16:
case tcu::TextureFormat::HALF_FLOAT:
return 16;
case tcu::TextureFormat::UNORM_INT24:
case tcu::TextureFormat::UNSIGNED_INT24:
return 24;
case tcu::TextureFormat::UNORM_INT32:
case tcu::TextureFormat::SNORM_INT32:
case tcu::TextureFormat::UNSIGNED_INT32:
case tcu::TextureFormat::SIGNED_INT32:
case tcu::TextureFormat::FLOAT:
return 32;
case tcu::TextureFormat::FLOAT64:
case tcu::TextureFormat::UNSIGNED_INT64:
case tcu::TextureFormat::SIGNED_INT64:
return 64;
// Packed formats
case tcu::TextureFormat::UNORM_SHORT_4444:
case tcu::TextureFormat::UNSIGNED_SHORT_4444:
return 4;
case tcu::TextureFormat::UNORM_SHORT_565:
case tcu::TextureFormat::UNSIGNED_SHORT_565:
return (componentNdx == 1 ? 6 : 5);
case tcu::TextureFormat::UNSIGNED_INT_24_8:
case tcu::TextureFormat::UNSIGNED_INT_24_8_REV:
case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
return (componentNdx == 0 ? 24 : 8);
case tcu::TextureFormat::UNORM_SHORT_1555:
return (componentNdx == 0 ? 1 : 5);
case tcu::TextureFormat::UNORM_INT_1010102_REV:
case tcu::TextureFormat::SNORM_INT_1010102_REV:
case tcu::TextureFormat::UNSIGNED_INT_1010102_REV:
case tcu::TextureFormat::SIGNED_INT_1010102_REV:
return (componentNdx == 3 ? 2 : 10);
default:
DE_FATAL("Format unimplemented");
}
}
return 0;
}
float getRepresentableDiffUnorm(const VkFormat format, const uint32_t componentNdx)
{
const uint32_t size(getFormatComponentWidth(format, componentNdx));
return 1.0f / float((1 << (size)) - 1);
}
float getRepresentableDiffSnorm(const VkFormat format, const uint32_t componentNdx)
{
const uint32_t size(getFormatComponentWidth(format, componentNdx));
return 1.0f / float((1 << (size - 1)) - 1);
}
uint32_t getBlockSizeInBytes(const VkFormat compressedFormat)
{
uint32_t formatNdx = static_cast<uint32_t>(compressedFormat - VK_FORMAT_BC1_RGB_UNORM_BLOCK);
DE_ASSERT(deInRange32(formatNdx, 0, DE_LENGTH_OF_ARRAY(compressedFormatParameters)));
DE_ASSERT(compressedFormatParameters[formatNdx].format == compressedFormat);
return compressedFormatParameters[formatNdx].blockBytes;
}
uint32_t getBlockWidth(const VkFormat compressedFormat)
{
uint32_t formatNdx = static_cast<uint32_t>(compressedFormat - VK_FORMAT_BC1_RGB_UNORM_BLOCK);
DE_ASSERT(deInRange32(formatNdx, 0, DE_LENGTH_OF_ARRAY(compressedFormatParameters)));
DE_ASSERT(compressedFormatParameters[formatNdx].format == compressedFormat);
return compressedFormatParameters[formatNdx].blockWidth;
}
uint32_t getBlockHeight(const VkFormat compressedFormat)
{
uint32_t formatNdx = static_cast<uint32_t>(compressedFormat - VK_FORMAT_BC1_RGB_UNORM_BLOCK);
DE_ASSERT(deInRange32(formatNdx, 0, DE_LENGTH_OF_ARRAY(compressedFormatParameters)));
DE_ASSERT(compressedFormatParameters[formatNdx].format == compressedFormat);
return compressedFormatParameters[formatNdx].blockHeight;
}
VkFilter mapFilterMode(tcu::Sampler::FilterMode filterMode)
{
DE_STATIC_ASSERT(tcu::Sampler::FILTERMODE_LAST == 9);
switch (filterMode)
{
case tcu::Sampler::NEAREST:
return VK_FILTER_NEAREST;
case tcu::Sampler::LINEAR:
return VK_FILTER_LINEAR;
case tcu::Sampler::CUBIC:
return VK_FILTER_CUBIC_EXT;
case tcu::Sampler::NEAREST_MIPMAP_NEAREST:
return VK_FILTER_NEAREST;
case tcu::Sampler::NEAREST_MIPMAP_LINEAR:
return VK_FILTER_NEAREST;
case tcu::Sampler::LINEAR_MIPMAP_NEAREST:
return VK_FILTER_LINEAR;
case tcu::Sampler::LINEAR_MIPMAP_LINEAR:
return VK_FILTER_LINEAR;
case tcu::Sampler::CUBIC_MIPMAP_NEAREST:
return VK_FILTER_CUBIC_EXT;
case tcu::Sampler::CUBIC_MIPMAP_LINEAR:
return VK_FILTER_CUBIC_EXT;
default:
DE_FATAL("Illegal filter mode");
return (VkFilter)0;
}
}
VkSamplerMipmapMode mapMipmapMode(tcu::Sampler::FilterMode filterMode)
{
DE_STATIC_ASSERT(tcu::Sampler::FILTERMODE_LAST == 9);
// \note VkSamplerCreateInfo doesn't have a flag for disabling mipmapping. Instead
// minLod = 0 and maxLod = 0.25 should be used to match OpenGL NEAREST and LINEAR
// filtering mode behavior.
switch (filterMode)
{
case tcu::Sampler::NEAREST:
return VK_SAMPLER_MIPMAP_MODE_NEAREST;
case tcu::Sampler::LINEAR:
return VK_SAMPLER_MIPMAP_MODE_NEAREST;
case tcu::Sampler::CUBIC:
return VK_SAMPLER_MIPMAP_MODE_NEAREST;
case tcu::Sampler::NEAREST_MIPMAP_NEAREST:
return VK_SAMPLER_MIPMAP_MODE_NEAREST;
case tcu::Sampler::NEAREST_MIPMAP_LINEAR:
return VK_SAMPLER_MIPMAP_MODE_LINEAR;
case tcu::Sampler::LINEAR_MIPMAP_NEAREST:
return VK_SAMPLER_MIPMAP_MODE_NEAREST;
case tcu::Sampler::LINEAR_MIPMAP_LINEAR:
return VK_SAMPLER_MIPMAP_MODE_LINEAR;
case tcu::Sampler::CUBIC_MIPMAP_NEAREST:
return VK_SAMPLER_MIPMAP_MODE_NEAREST;
case tcu::Sampler::CUBIC_MIPMAP_LINEAR:
return VK_SAMPLER_MIPMAP_MODE_LINEAR;
default:
DE_FATAL("Illegal filter mode");
return (VkSamplerMipmapMode)0;
}
}
VkSamplerAddressMode mapWrapMode(tcu::Sampler::WrapMode wrapMode)
{
switch (wrapMode)
{
case tcu::Sampler::CLAMP_TO_EDGE:
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
case tcu::Sampler::CLAMP_TO_BORDER:
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
case tcu::Sampler::REPEAT_GL:
return VK_SAMPLER_ADDRESS_MODE_REPEAT;
case tcu::Sampler::MIRRORED_REPEAT_GL:
return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
case tcu::Sampler::MIRRORED_ONCE:
return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
default:
DE_FATAL("Wrap mode can't be mapped to Vulkan");
return (vk::VkSamplerAddressMode)0;
}
}
vk::VkCompareOp mapCompareMode(tcu::Sampler::CompareMode mode)
{
switch (mode)
{
case tcu::Sampler::COMPAREMODE_NONE:
return vk::VK_COMPARE_OP_NEVER;
case tcu::Sampler::COMPAREMODE_LESS:
return vk::VK_COMPARE_OP_LESS;
case tcu::Sampler::COMPAREMODE_LESS_OR_EQUAL:
return vk::VK_COMPARE_OP_LESS_OR_EQUAL;
case tcu::Sampler::COMPAREMODE_GREATER:
return vk::VK_COMPARE_OP_GREATER;
case tcu::Sampler::COMPAREMODE_GREATER_OR_EQUAL:
return vk::VK_COMPARE_OP_GREATER_OR_EQUAL;
case tcu::Sampler::COMPAREMODE_EQUAL:
return vk::VK_COMPARE_OP_EQUAL;
case tcu::Sampler::COMPAREMODE_NOT_EQUAL:
return vk::VK_COMPARE_OP_NOT_EQUAL;
case tcu::Sampler::COMPAREMODE_ALWAYS:
return vk::VK_COMPARE_OP_ALWAYS;
case tcu::Sampler::COMPAREMODE_NEVER:
return vk::VK_COMPARE_OP_NEVER;
default:
DE_FATAL("Illegal compare mode");
return (vk::VkCompareOp)0;
}
}
static VkBorderColor mapBorderColor(tcu::TextureChannelClass channelClass, const rr::GenericVec4 &color)
{
if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
{
const tcu::UVec4 uColor = color.get<uint32_t>();
if (uColor == tcu::UVec4(0, 0, 0, 0))
return VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
else if (uColor == tcu::UVec4(0, 0, 0, 1))
return VK_BORDER_COLOR_INT_OPAQUE_BLACK;
else if (uColor == tcu::UVec4(1, 1, 1, 1))
return VK_BORDER_COLOR_INT_OPAQUE_WHITE;
else
return VK_BORDER_COLOR_INT_CUSTOM_EXT;
}
else if (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
{
const tcu::IVec4 sColor = color.get<int32_t>();
if (sColor == tcu::IVec4(0, 0, 0, 0))
return VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
else if (sColor == tcu::IVec4(0, 0, 0, 1))
return VK_BORDER_COLOR_INT_OPAQUE_BLACK;
else if (sColor == tcu::IVec4(1, 1, 1, 1))
return VK_BORDER_COLOR_INT_OPAQUE_WHITE;
else
return VK_BORDER_COLOR_INT_CUSTOM_EXT;
}
else
{
const tcu::Vec4 fColor = color.get<float>();
if (fColor == tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f))
return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
else if (fColor == tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f))
return VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
else if (fColor == tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f))
return VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
else
return VK_BORDER_COLOR_FLOAT_CUSTOM_EXT;
}
// note: never reached
DE_FATAL("Unsupported border color");
return VK_BORDER_COLOR_MAX_ENUM;
}
VkSamplerCreateInfo mapSampler(const tcu::Sampler &sampler, const tcu::TextureFormat &format, float minLod,
float maxLod, bool unnormal)
{
const bool compareEnabled = (sampler.compare != tcu::Sampler::COMPAREMODE_NONE);
const VkCompareOp compareOp = (compareEnabled) ? (mapCompareMode(sampler.compare)) : (VK_COMPARE_OP_ALWAYS);
const VkBorderColor borderColor = mapBorderColor(getTextureChannelClass(format.type), sampler.borderColor);
const bool isMipmapEnabled =
(sampler.minFilter != tcu::Sampler::NEAREST && sampler.minFilter != tcu::Sampler::LINEAR &&
sampler.minFilter != tcu::Sampler::CUBIC);
#ifndef CTS_USES_VULKANSC
const VkSamplerCreateFlags flags =
sampler.seamlessCubeMap ? 0u : (VkSamplerCreateFlags)VK_SAMPLER_CREATE_NON_SEAMLESS_CUBE_MAP_BIT_EXT;
#else
const VkSamplerCreateFlags flags = 0u;
#endif // CTS_USES_VULKANSC
const VkSamplerCreateInfo createInfo = {
VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
DE_NULL,
flags,
mapFilterMode(sampler.magFilter), // magFilter
mapFilterMode(sampler.minFilter), // minFilter
mapMipmapMode(sampler.minFilter), // mipMode
mapWrapMode(sampler.wrapS), // addressU
mapWrapMode(sampler.wrapT), // addressV
mapWrapMode(sampler.wrapR), // addressW
0.0f, // mipLodBias
VK_FALSE, // anisotropyEnable
1.0f, // maxAnisotropy
(VkBool32)(compareEnabled ? VK_TRUE : VK_FALSE), // compareEnable
compareOp, // compareOp
(isMipmapEnabled ? minLod : 0.0f), // minLod
(isMipmapEnabled ? maxLod : (unnormal ? 0.0f : 0.25f)), // maxLod
borderColor, // borderColor
(VkBool32)(sampler.normalizedCoords ? VK_FALSE : VK_TRUE), // unnormalizedCoords
};
return createInfo;
}
rr::GenericVec4 mapVkColor(const VkClearColorValue &color)
{
rr::GenericVec4 value;
static_assert(sizeof(rr::GenericVec4) == sizeof(VkClearColorValue),
"GenericVec4 and VkClearColorValue size mismatch");
deMemcpy(&value, &color, sizeof(rr::GenericVec4));
return value;
}
VkClearColorValue mapVkColor(const rr::GenericVec4 &color)
{
VkClearColorValue value;
static_assert(sizeof(rr::GenericVec4) == sizeof(VkClearColorValue),
"GenericVec4 and VkClearColorValue size mismatch");
deMemcpy(&value, &color, sizeof(VkClearColorValue));
return value;
}
tcu::Sampler mapVkSampler(const VkSamplerCreateInfo &samplerCreateInfo)
{
// \note minLod & maxLod are not supported by tcu::Sampler. LOD must be clamped
// before passing it to tcu::Texture*::sample*()
tcu::Sampler::ReductionMode reductionMode = tcu::Sampler::WEIGHTED_AVERAGE;
rr::GenericVec4 borderColorValue;
void const *pNext = samplerCreateInfo.pNext;
while (pNext != DE_NULL)
{
const VkStructureType nextType = *reinterpret_cast<const VkStructureType *>(pNext);
switch (nextType)
{
case VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO:
{
const VkSamplerReductionModeCreateInfo reductionModeCreateInfo =
*reinterpret_cast<const VkSamplerReductionModeCreateInfo *>(pNext);
reductionMode = mapVkSamplerReductionMode(reductionModeCreateInfo.reductionMode);
pNext = reinterpret_cast<const VkSamplerReductionModeCreateInfo *>(pNext)->pNext;
break;
}
case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO:
pNext = reinterpret_cast<const VkSamplerYcbcrConversionInfo *>(pNext)->pNext;
break;
case VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT:
{
const VkSamplerCustomBorderColorCreateInfoEXT customBorderColorCreateInfo =
*reinterpret_cast<const VkSamplerCustomBorderColorCreateInfoEXT *>(pNext);
borderColorValue = mapVkColor(customBorderColorCreateInfo.customBorderColor);
pNext = reinterpret_cast<const VkSamplerCustomBorderColorCreateInfoEXT *>(pNext)->pNext;
break;
}
default:
TCU_FAIL("Unrecognized sType in chained sampler create info");
}
}
tcu::Sampler sampler(mapVkSamplerAddressMode(samplerCreateInfo.addressModeU),
mapVkSamplerAddressMode(samplerCreateInfo.addressModeV),
mapVkSamplerAddressMode(samplerCreateInfo.addressModeW),
mapVkMinTexFilter(samplerCreateInfo.minFilter, samplerCreateInfo.mipmapMode),
mapVkMagTexFilter(samplerCreateInfo.magFilter), 0.0f,
!samplerCreateInfo.unnormalizedCoordinates,
samplerCreateInfo.compareEnable ? mapVkSamplerCompareOp(samplerCreateInfo.compareOp) :
tcu::Sampler::COMPAREMODE_NONE,
0, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
#ifndef CTS_USES_VULKANSC
!(samplerCreateInfo.flags & VK_SAMPLER_CREATE_NON_SEAMLESS_CUBE_MAP_BIT_EXT),
#else
true,
#endif // CTS_USES_VULKANSC
tcu::Sampler::MODE_DEPTH, reductionMode);
if (samplerCreateInfo.anisotropyEnable)
TCU_THROW(InternalError, "Anisotropic filtering is not supported by tcu::Sampler");
switch (samplerCreateInfo.borderColor)
{
case VK_BORDER_COLOR_INT_OPAQUE_BLACK:
sampler.borderColor = tcu::UVec4(0, 0, 0, 1);
break;
case VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK:
sampler.borderColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
break;
case VK_BORDER_COLOR_INT_OPAQUE_WHITE:
sampler.borderColor = tcu::UVec4(1, 1, 1, 1);
break;
case VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE:
sampler.borderColor = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
break;
case VK_BORDER_COLOR_INT_TRANSPARENT_BLACK:
sampler.borderColor = tcu::UVec4(0, 0, 0, 0);
break;
case VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK:
sampler.borderColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
break;
case VK_BORDER_COLOR_FLOAT_CUSTOM_EXT:
case VK_BORDER_COLOR_INT_CUSTOM_EXT:
sampler.borderColor = borderColorValue;
break;
default:
DE_ASSERT(false);
break;
}
return sampler;
}
tcu::Sampler::CompareMode mapVkSamplerCompareOp(VkCompareOp compareOp)
{
switch (compareOp)
{
case VK_COMPARE_OP_NEVER:
return tcu::Sampler::COMPAREMODE_NEVER;
case VK_COMPARE_OP_LESS:
return tcu::Sampler::COMPAREMODE_LESS;
case VK_COMPARE_OP_EQUAL:
return tcu::Sampler::COMPAREMODE_EQUAL;
case VK_COMPARE_OP_LESS_OR_EQUAL:
return tcu::Sampler::COMPAREMODE_LESS_OR_EQUAL;
case VK_COMPARE_OP_GREATER:
return tcu::Sampler::COMPAREMODE_GREATER;
case VK_COMPARE_OP_NOT_EQUAL:
return tcu::Sampler::COMPAREMODE_NOT_EQUAL;
case VK_COMPARE_OP_GREATER_OR_EQUAL:
return tcu::Sampler::COMPAREMODE_GREATER_OR_EQUAL;
case VK_COMPARE_OP_ALWAYS:
return tcu::Sampler::COMPAREMODE_ALWAYS;
default:
break;
}
DE_ASSERT(false);
return tcu::Sampler::COMPAREMODE_LAST;
}
tcu::Sampler::WrapMode mapVkSamplerAddressMode(VkSamplerAddressMode addressMode)
{
switch (addressMode)
{
case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE:
return tcu::Sampler::CLAMP_TO_EDGE;
case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER:
return tcu::Sampler::CLAMP_TO_BORDER;
case VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT:
return tcu::Sampler::MIRRORED_REPEAT_GL;
case VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE:
return tcu::Sampler::MIRRORED_ONCE;
case VK_SAMPLER_ADDRESS_MODE_REPEAT:
return tcu::Sampler::REPEAT_GL;
default:
break;
}
DE_ASSERT(false);
return tcu::Sampler::WRAPMODE_LAST;
}
tcu::Sampler::ReductionMode mapVkSamplerReductionMode(VkSamplerReductionMode reductionMode)
{
switch (reductionMode)
{
case VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE:
return tcu::Sampler::WEIGHTED_AVERAGE;
case VK_SAMPLER_REDUCTION_MODE_MIN:
return tcu::Sampler::MIN;
case VK_SAMPLER_REDUCTION_MODE_MAX:
return tcu::Sampler::MAX;
default:
break;
}
DE_ASSERT(false);
return tcu::Sampler::REDUCTIONMODE_LAST;
}
tcu::Sampler::FilterMode mapVkMinTexFilter(VkFilter filter, VkSamplerMipmapMode mipMode)
{
switch (filter)
{
case VK_FILTER_LINEAR:
switch (mipMode)
{
case VK_SAMPLER_MIPMAP_MODE_LINEAR:
return tcu::Sampler::LINEAR_MIPMAP_LINEAR;
case VK_SAMPLER_MIPMAP_MODE_NEAREST:
return tcu::Sampler::LINEAR_MIPMAP_NEAREST;
default:
break;
}
break;
case VK_FILTER_NEAREST:
switch (mipMode)
{
case VK_SAMPLER_MIPMAP_MODE_LINEAR:
return tcu::Sampler::NEAREST_MIPMAP_LINEAR;
case VK_SAMPLER_MIPMAP_MODE_NEAREST:
return tcu::Sampler::NEAREST_MIPMAP_NEAREST;
default:
break;
}
break;
case VK_FILTER_CUBIC_EXT:
switch (mipMode)
{
case VK_SAMPLER_MIPMAP_MODE_LINEAR:
return tcu::Sampler::CUBIC_MIPMAP_LINEAR;
case VK_SAMPLER_MIPMAP_MODE_NEAREST:
return tcu::Sampler::CUBIC_MIPMAP_NEAREST;
default:
break;
}
break;
default:
break;
}
DE_ASSERT(false);
return tcu::Sampler::FILTERMODE_LAST;
}
tcu::Sampler::FilterMode mapVkMagTexFilter(VkFilter filter)
{
switch (filter)
{
case VK_FILTER_LINEAR:
return tcu::Sampler::LINEAR;
case VK_FILTER_NEAREST:
return tcu::Sampler::NEAREST;
case VK_FILTER_CUBIC_EXT:
return tcu::Sampler::CUBIC;
default:
break;
}
DE_ASSERT(false);
return tcu::Sampler::FILTERMODE_LAST;
}
//! Get a format that matches the layout in buffer memory used for a
//! buffer<->image copy on a depth/stencil format.
tcu::TextureFormat getDepthCopyFormat(VkFormat combinedFormat)
{
switch (combinedFormat)
{
case VK_FORMAT_D16_UNORM:
case VK_FORMAT_X8_D24_UNORM_PACK32:
case VK_FORMAT_D32_SFLOAT:
return mapVkFormat(combinedFormat);
case VK_FORMAT_D16_UNORM_S8_UINT:
return mapVkFormat(VK_FORMAT_D16_UNORM);
case VK_FORMAT_D24_UNORM_S8_UINT:
return mapVkFormat(VK_FORMAT_X8_D24_UNORM_PACK32);
case VK_FORMAT_D32_SFLOAT_S8_UINT:
return mapVkFormat(VK_FORMAT_D32_SFLOAT);
case VK_FORMAT_S8_UINT:
default:
DE_FATAL("Unexpected depth/stencil format");
return tcu::TextureFormat();
}
}
//! Get a format that matches the layout in buffer memory used for a
//! buffer<->image copy on a depth/stencil format.
tcu::TextureFormat getStencilCopyFormat(VkFormat combinedFormat)
{
switch (combinedFormat)
{
case VK_FORMAT_D16_UNORM_S8_UINT:
case VK_FORMAT_D24_UNORM_S8_UINT:
case VK_FORMAT_D32_SFLOAT_S8_UINT:
case VK_FORMAT_S8_UINT:
return mapVkFormat(VK_FORMAT_S8_UINT);
case VK_FORMAT_D16_UNORM:
case VK_FORMAT_X8_D24_UNORM_PACK32:
case VK_FORMAT_D32_SFLOAT:
default:
DE_FATAL("Unexpected depth/stencil format");
return tcu::TextureFormat();
}
}
VkImageAspectFlags getImageAspectFlags(const tcu::TextureFormat textureFormat)
{
VkImageAspectFlags imageAspectFlags = 0;
if (tcu::hasDepthComponent(textureFormat.order))
imageAspectFlags |= VK_IMAGE_ASPECT_DEPTH_BIT;
if (tcu::hasStencilComponent(textureFormat.order))
imageAspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT;
if (imageAspectFlags == 0)
imageAspectFlags = VK_IMAGE_ASPECT_COLOR_BIT;
return imageAspectFlags;
}
VkExtent3D mipLevelExtents(const VkExtent3D &baseExtents, const uint32_t mipLevel)
{
VkExtent3D result;
result.width = std::max(baseExtents.width >> mipLevel, 1u);
result.height = std::max(baseExtents.height >> mipLevel, 1u);
result.depth = std::max(baseExtents.depth >> mipLevel, 1u);
return result;
}
tcu::UVec3 alignedDivide(const VkExtent3D &extent, const VkExtent3D &divisor)
{
tcu::UVec3 result;
result.x() = extent.width / divisor.width + ((extent.width % divisor.width != 0) ? 1u : 0u);
result.y() = extent.height / divisor.height + ((extent.height % divisor.height != 0) ? 1u : 0u);
result.z() = extent.depth / divisor.depth + ((extent.depth % divisor.depth != 0) ? 1u : 0u);
return result;
}
void copyBufferToImage(const DeviceInterface &vk, const VkCommandBuffer &cmdBuffer, const VkBuffer &buffer,
VkDeviceSize bufferSize, const std::vector<VkBufferImageCopy> &copyRegions,
VkImageAspectFlags imageAspectFlags, uint32_t mipLevels, uint32_t arrayLayers, VkImage destImage,
VkImageLayout destImageLayout, VkPipelineStageFlags destImageDstStageFlags,
VkAccessFlags destImageDstAccessMask, uint32_t baseMipLevel)
{
// Barriers for copying buffer to image
const VkBufferMemoryBarrier preBufferBarrier = {
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
DE_NULL, // const void* pNext;
VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask;
VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
buffer, // VkBuffer buffer;
0u, // VkDeviceSize offset;
bufferSize // VkDeviceSize size;
};
const VkImageMemoryBarrier preImageBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
DE_NULL, // const void* pNext;
0u, // VkAccessFlags srcAccessMask;
VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
destImage, // VkImage image;
{
// VkImageSubresourceRange subresourceRange;
imageAspectFlags, // VkImageAspectFlags aspect;
baseMipLevel, // uint32_t baseMipLevel;
mipLevels, // uint32_t mipLevels;
0u, // uint32_t baseArraySlice;
arrayLayers // uint32_t arraySize;
}};
const VkImageMemoryBarrier postImageBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
DE_NULL, // const void* pNext;
VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
destImageDstAccessMask, // VkAccessFlags dstAccessMask;
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
destImageLayout, // VkImageLayout newLayout;
VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
destImage, // VkImage image;
{
// VkImageSubresourceRange subresourceRange;
imageAspectFlags, // VkImageAspectFlags aspect;
baseMipLevel, // uint32_t baseMipLevel;
mipLevels, // uint32_t mipLevels;
0u, // uint32_t baseArraySlice;
arrayLayers // uint32_t arraySize;
}};
// Copy buffer to image
vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
0, nullptr, 1, &preBufferBarrier, 1, &preImageBarrier);
vk.cmdCopyBufferToImage(cmdBuffer, buffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
(uint32_t)copyRegions.size(), copyRegions.data());
vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, destImageDstStageFlags, (VkDependencyFlags)0, 0,
nullptr, 0, nullptr, 1, &postImageBarrier);
}
void copyBufferToImage(const DeviceInterface &vk, VkDevice device, VkQueue queue, uint32_t queueFamilyIndex,
const VkBuffer &buffer, VkDeviceSize bufferSize,
const std::vector<VkBufferImageCopy> &copyRegions, const VkSemaphore *waitSemaphore,
VkImageAspectFlags imageAspectFlags, uint32_t mipLevels, uint32_t arrayLayers, VkImage destImage,
VkImageLayout destImageLayout, VkPipelineStageFlags destImageDstStageFlags,
VkAccessFlags destImageDstAccessMask, const VkCommandPool *externalCommandPool,
uint32_t baseMipLevel)
{
Move<VkCommandPool> cmdPool;
VkCommandPool activeCmdPool;
if (externalCommandPool == DE_NULL)
{
// Create local command pool
cmdPool = createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
activeCmdPool = *cmdPool;
}
else
{
// Use external command pool if available
activeCmdPool = *externalCommandPool;
}
Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, device, activeCmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
Move<VkFence> fence = createFence(vk, device);
const VkCommandBufferBeginInfo cmdBufferBeginInfo = {
VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
DE_NULL, // const void* pNext;
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags;
nullptr,
};
VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
copyBufferToImage(vk, *cmdBuffer, buffer, bufferSize, copyRegions, imageAspectFlags, mipLevels, arrayLayers,
destImage, destImageLayout, destImageDstStageFlags, destImageDstAccessMask, baseMipLevel);
VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
const VkPipelineStageFlags pipelineStageFlags = VK_PIPELINE_STAGE_TRANSFER_BIT;
const VkSubmitInfo submitInfo = {
VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
DE_NULL, // const void* pNext;
waitSemaphore ? 1u : 0u, // uint32_t waitSemaphoreCount;
waitSemaphore, // const VkSemaphore* pWaitSemaphores;
&pipelineStageFlags, // const VkPipelineStageFlags* pWaitDstStageMask;
1u, // uint32_t commandBufferCount;
&cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
0u, // uint32_t signalSemaphoreCount;
DE_NULL // const VkSemaphore* pSignalSemaphores;
};
try
{
VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
VK_CHECK(vk.waitForFences(device, 1, &fence.get(), true, ~(0ull) /* infinity */));
}
catch (...)
{
VK_CHECK(vk.deviceWaitIdle(device));
throw;
}
}
void copyImageToBuffer(const DeviceInterface &vk, VkCommandBuffer cmdBuffer, VkImage image, VkBuffer buffer,
tcu::IVec2 size, VkAccessFlags srcAccessMask, VkImageLayout oldLayout, uint32_t numLayers,
VkImageAspectFlags barrierAspect, VkImageAspectFlags copyAspect,
VkPipelineStageFlags srcStageMask)
{
const VkImageMemoryBarrier imageBarrier = {
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
DE_NULL, // const void* pNext;
srcAccessMask, // VkAccessFlags srcAccessMask;
VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
oldLayout, // VkImageLayout oldLayout;
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
VK_QUEUE_FAMILY_IGNORED, // uint32_t destQueueFamilyIndex;
image, // VkImage image;
makeImageSubresourceRange(barrierAspect, 0u, 1u, 0, numLayers) // VkImageSubresourceRange subresourceRange;
};
vk.cmdPipelineBarrier(cmdBuffer, srcStageMask, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u,
&imageBarrier);
const VkImageSubresourceLayers subresource = {
copyAspect, // VkImageAspectFlags aspectMask;
0u, // uint32_t mipLevel;
0u, // uint32_t baseArrayLayer;
numLayers // uint32_t layerCount;
};
const VkBufferImageCopy region = {
0ull, // VkDeviceSize bufferOffset;
0u, // uint32_t bufferRowLength;
0u, // uint32_t bufferImageHeight;
subresource, // VkImageSubresourceLayers imageSubresource;
makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
makeExtent3D(size.x(), size.y(), 1u) // VkExtent3D imageExtent;
};
vk.cmdCopyImageToBuffer(cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer, 1u, &region);
const VkBufferMemoryBarrier bufferBarrier = {
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
DE_NULL, // const void* pNext;
VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
buffer, // VkBuffer buffer;
0ull, // VkDeviceSize offset;
VK_WHOLE_SIZE // VkDeviceSize size;
};
vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u,
&bufferBarrier, 0u, DE_NULL);
}
void copyImageToBuffer(const DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer, vk::VkImage image, vk::VkBuffer buffer,
vk::VkFormat format, tcu::IVec2 size, uint32_t mipLevel, vk::VkAccessFlags srcAccessMask,
vk::VkImageLayout oldLayout, uint32_t numLayers, VkImageAspectFlags barrierAspect,
VkImageAspectFlags copyAspect)
{
const VkImageMemoryBarrier imageBarrier = {
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
DE_NULL, // const void* pNext;
srcAccessMask, // VkAccessFlags srcAccessMask;
VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
oldLayout, // VkImageLayout oldLayout;
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
VK_QUEUE_FAMILY_IGNORED, // uint32_t destQueueFamilyIndex;
image, // VkImage image;
makeImageSubresourceRange(barrierAspect, mipLevel, 1u, 0,
numLayers) // VkImageSubresourceRange subresourceRange;
};
vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u,
DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
const VkImageSubresourceLayers subresource = {
copyAspect, // VkImageAspectFlags aspectMask;
mipLevel, // uint32_t mipLevel;
0u, // uint32_t baseArrayLayer;
numLayers // uint32_t layerCount;
};
VkDeviceSize offset = 0ull;
uint32_t width = size.x();
uint32_t height = size.y();
uint32_t pixelSize = tcu::getPixelSize(mapVkFormat(format));
for (uint32_t level = 0; level < mipLevel; ++level)
{
offset += (width * height * pixelSize);
height /= 2;
width /= 2;
}
const VkBufferImageCopy region = {
offset, // VkDeviceSize bufferOffset;
0u, // uint32_t bufferRowLength;
0u, // uint32_t bufferImageHeight;
subresource, // VkImageSubresourceLayers imageSubresource;
makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
makeExtent3D(width, height, 1u) // VkExtent3D imageExtent;
};
vk.cmdCopyImageToBuffer(cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer, 1u, &region);
const VkBufferMemoryBarrier bufferBarrier = {
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
DE_NULL, // const void* pNext;
VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
buffer, // VkBuffer buffer;
offset, // VkDeviceSize offset;
VK_WHOLE_SIZE // VkDeviceSize size;
};
vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u,
&bufferBarrier, 0u, DE_NULL);
}
void clearColorImage(const DeviceInterface &vk, const VkDevice device, const VkQueue queue, uint32_t queueFamilyIndex,
VkImage image, VkClearColorValue clearColor, VkImageLayout oldLayout, VkImageLayout newLayout,
VkAccessFlags dstAccessFlags, VkPipelineStageFlags dstStageFlags, uint32_t baseArrayLayer,
uint32_t layerCount, uint32_t baseMipLevel, uint32_t levelCount)
{
Move<VkCommandPool> cmdPool = createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
const VkImageSubresourceRange subresourceRange = {
VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
baseMipLevel, // uint32_t baseMipLevel
levelCount, // uint32_t levelCount
baseArrayLayer, // uint32_t baseArrayLayer
layerCount, // uint32_t layerCount
};
const VkImageMemoryBarrier preImageBarrier = {
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
DE_NULL, // const void* pNext;
0u, // VkAccessFlags srcAccessMask;
VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
oldLayout, // VkImageLayout oldLayout;
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
queueFamilyIndex, // uint32_t srcQueueFamilyIndex;
queueFamilyIndex, // uint32_t dstQueueFamilyIndex;
image, // VkImage image;
subresourceRange // VkImageSubresourceRange subresourceRange;
};
const VkImageMemoryBarrier postImageBarrier = {
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
DE_NULL, // const void* pNext;
VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
dstAccessFlags, // VkAccessFlags dstAccessMask;
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
newLayout, // VkImageLayout newLayout;
queueFamilyIndex, // uint32_t srcQueueFamilyIndex;
queueFamilyIndex, // uint32_t dstQueueFamilyIndex;
image, // VkImage image;
subresourceRange // VkImageSubresourceRange subresourceRange;
};
beginCommandBuffer(vk, *cmdBuffer);
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
0, (const VkMemoryBarrier *)DE_NULL, 0, (const VkBufferMemoryBarrier *)DE_NULL, 1,
&preImageBarrier);
vk.cmdClearColorImage(*cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &subresourceRange);
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, dstStageFlags, (VkDependencyFlags)0, 0,
(const VkMemoryBarrier *)DE_NULL, 0, (const VkBufferMemoryBarrier *)DE_NULL, 1,
&postImageBarrier);
endCommandBuffer(vk, *cmdBuffer);
submitCommandsAndWait(vk, device, queue, *cmdBuffer);
}
void clearColorImage(const DeviceInterface &vk, const VkDevice device, const VkQueue queue, uint32_t queueFamilyIndex,
VkImage image, tcu::Vec4 clearColor, VkImageLayout oldLayout, VkImageLayout newLayout,
VkPipelineStageFlags dstStageFlags, uint32_t baseArrayLayer, uint32_t layerCount,
uint32_t baseMipLevel, uint32_t levelCount)
{
clearColorImage(vk, device, queue, queueFamilyIndex, image, makeClearValueColor(clearColor).color, oldLayout,
newLayout, VK_ACCESS_SHADER_WRITE_BIT, dstStageFlags, baseArrayLayer, layerCount, baseMipLevel,
levelCount);
}
std::vector<VkBufferImageCopy> generateChessboardCopyRegions(uint32_t tileSize, uint32_t imageWidth,
uint32_t imageHeight, uint32_t tileIdx,
VkImageAspectFlags aspectMask)
{
std::vector<VkBufferImageCopy> copyRegions;
for (uint32_t x = 0; x < (uint32_t)deFloatCeil((float)imageWidth / (float)tileSize); x++)
for (uint32_t y = 0; y < (uint32_t)deFloatCeil((float)imageHeight / (float)tileSize); y++)
{
if ((x + tileIdx) % 2 == y % 2)
continue;
const uint32_t tileWidth = de::min(tileSize, imageWidth - tileSize * x);
const uint32_t tileHeight = de::min(tileSize, imageHeight - tileSize * y);
const VkOffset3D offset = {
(int32_t)x * (int32_t)tileWidth, // int32_t x
(int32_t)y * (int32_t)tileHeight, // int32_t y
0 // int32_t z
};
const VkExtent3D extent = {
tileWidth, // uint32_t width
tileHeight, // uint32_t height
1u // uint32_t depth
};
const VkImageSubresourceLayers subresourceLayers = {
aspectMask, // VkImageAspectFlags aspectMask
0u, // uint32_t mipLevel
0u, // uint32_t baseArrayLayer
1u, // uint32_t layerCount
};
const VkBufferImageCopy copy = {
(VkDeviceSize)0, // VkDeviceSize bufferOffset
0u, // uint32_t bufferRowLength
0u, // uint32_t bufferImageHeight
subresourceLayers, // VkImageSubresourceLayers imageSubresource
offset, // VkOffset3D imageOffset
extent // VkExtent3D imageExtent
};
copyRegions.push_back(copy);
}
return copyRegions;
}
void initColorImageChessboardPattern(const DeviceInterface &vk, const VkDevice device, const VkQueue queue,
uint32_t queueFamilyIndex, Allocator &allocator, VkImage image, VkFormat format,
tcu::Vec4 colorValue0, tcu::Vec4 colorValue1, uint32_t imageWidth,
uint32_t imageHeight, uint32_t tileSize, VkImageLayout oldLayout,
VkImageLayout newLayout, VkPipelineStageFlags dstStageFlags)
{
Move<VkCommandPool> cmdPool = createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
const tcu::TextureFormat tcuFormat = mapVkFormat(format);
const tcu::Vec4 colorValues[] = {colorValue0, colorValue1};
const uint32_t bufferSize = tileSize * tileSize * tcuFormat.getPixelSize();
const VkImageSubresourceRange subresourceRange = {
VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
0u, // uint32_t baseMipLevel
1u, // uint32_t levelCount
0u, // uint32_t baseArrayLayer
1u // uint32_t layerCount
};
const VkImageMemoryBarrier preImageBarrier = {
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
DE_NULL, // const void* pNext;
0u, // VkAccessFlags srcAccessMask;
VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
oldLayout, // VkImageLayout oldLayout;
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
queueFamilyIndex, // uint32_t srcQueueFamilyIndex;
queueFamilyIndex, // uint32_t dstQueueFamilyIndex;
image, // VkImage image;
subresourceRange // VkImageSubresourceRange subresourceRange;
};
const VkImageMemoryBarrier postImageBarrier = {
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
DE_NULL, // const void* pNext;
VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask;
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
newLayout, // VkImageLayout newLayout;
queueFamilyIndex, // uint32_t srcQueueFamilyIndex;
queueFamilyIndex, // uint32_t dstQueueFamilyIndex;
image, // VkImage image;
subresourceRange // VkImageSubresourceRange subresourceRange;
};
// Create staging buffers for both color values
Move<VkBuffer> buffers[2];
de::MovePtr<Allocation> bufferAllocs[2];
const VkBufferCreateInfo bufferParams = {
VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType
DE_NULL, // const void* pNext
0u, // VkBufferCreateFlags flags
(VkDeviceSize)bufferSize, // VkDeviceSize size
VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage
VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
0u, // uint32_t queueFamilyIndexCount
DE_NULL // const uint32_t* pQueueFamilyIndices
};
for (uint32_t bufferIdx = 0; bufferIdx < 2; bufferIdx++)
{
buffers[bufferIdx] = createBuffer(vk, device, &bufferParams);
bufferAllocs[bufferIdx] = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffers[bufferIdx]),
MemoryRequirement::HostVisible);
VK_CHECK(vk.bindBufferMemory(device, *buffers[bufferIdx], bufferAllocs[bufferIdx]->getMemory(),
bufferAllocs[bufferIdx]->getOffset()));
uint32_t *dstPtr = (uint32_t *)bufferAllocs[bufferIdx]->getHostPtr();
tcu::PixelBufferAccess access(tcuFormat, tileSize, tileSize, 1, dstPtr);
for (uint32_t x = 0; x < tileSize; x++)
for (uint32_t y = 0; y < tileSize; y++)
access.setPixel(colorValues[bufferIdx], x, y, 0);
flushAlloc(vk, device, *bufferAllocs[bufferIdx]);
}
beginCommandBuffer(vk, *cmdBuffer);
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
0, (const VkMemoryBarrier *)DE_NULL, 0, (const VkBufferMemoryBarrier *)DE_NULL, 1,
&preImageBarrier);
for (uint32_t bufferIdx = 0; bufferIdx < 2; bufferIdx++)
{
std::vector<VkBufferImageCopy> copyRegions =
generateChessboardCopyRegions(tileSize, imageWidth, imageHeight, bufferIdx, VK_IMAGE_ASPECT_COLOR_BIT);
vk.cmdCopyBufferToImage(*cmdBuffer, *buffers[bufferIdx], image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
(uint32_t)copyRegions.size(), copyRegions.data());
}
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, dstStageFlags, (VkDependencyFlags)0, 0,
(const VkMemoryBarrier *)DE_NULL, 0, (const VkBufferMemoryBarrier *)DE_NULL, 1,
&postImageBarrier);
endCommandBuffer(vk, *cmdBuffer);
submitCommandsAndWait(vk, device, queue, *cmdBuffer);
}
void copyDepthStencilImageToBuffers(const DeviceInterface &vk, VkCommandBuffer cmdBuffer, VkImage image,
VkBuffer depthBuffer, VkBuffer stencilBuffer, tcu::IVec2 size,
VkAccessFlags srcAccessMask, VkImageLayout oldLayout, uint32_t numLayers)
{
const VkImageAspectFlags aspect = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
const VkImageMemoryBarrier imageBarrier = {
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
DE_NULL, // const void* pNext;
srcAccessMask, // VkAccessFlags srcAccessMask;
VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
oldLayout, // VkImageLayout oldLayout;
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
VK_QUEUE_FAMILY_IGNORED, // uint32_t destQueueFamilyIndex;
image, // VkImage image;
makeImageSubresourceRange(aspect, 0u, 1u, 0, numLayers) // VkImageSubresourceRange subresourceRange;
};
vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u,
DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
const VkImageSubresourceLayers subresourceDepth = {
VK_IMAGE_ASPECT_DEPTH_BIT, // VkImageAspectFlags aspectMask;
0u, // uint32_t mipLevel;
0u, // uint32_t baseArrayLayer;
numLayers // uint32_t layerCount;
};
const VkBufferImageCopy regionDepth = {
0ull, // VkDeviceSize bufferOffset;
0u, // uint32_t bufferRowLength;
0u, // uint32_t bufferImageHeight;
subresourceDepth, // VkImageSubresourceLayers imageSubresource;
makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
makeExtent3D(size.x(), size.y(), 1u) // VkExtent3D imageExtent;
};
const VkImageSubresourceLayers subresourceStencil = {
VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags aspectMask;
0u, // uint32_t mipLevel;
0u, // uint32_t baseArrayLayer;
numLayers // uint32_t layerCount;
};
const VkBufferImageCopy regionStencil = {
0ull, // VkDeviceSize bufferOffset;
0u, // uint32_t bufferRowLength;
0u, // uint32_t bufferImageHeight;
subresourceStencil, // VkImageSubresourceLayers imageSubresource;
makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
makeExtent3D(size.x(), size.y(), 1u) // VkExtent3D imageExtent;
};
vk.cmdCopyImageToBuffer(cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, depthBuffer, 1u, &regionDepth);
vk.cmdCopyImageToBuffer(cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, stencilBuffer, 1u, &regionStencil);
const VkBufferMemoryBarrier bufferBarriers[] = {
{
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
DE_NULL, // const void* pNext;
VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
depthBuffer, // VkBuffer buffer;
0ull, // VkDeviceSize offset;
VK_WHOLE_SIZE // VkDeviceSize size;
},
{
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
DE_NULL, // const void* pNext;
VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
stencilBuffer, // VkBuffer buffer;
0ull, // VkDeviceSize offset;
VK_WHOLE_SIZE // VkDeviceSize size;
}};
vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 2u,
bufferBarriers, 0u, DE_NULL);
}
void clearDepthStencilImage(const DeviceInterface &vk, const VkDevice device, const VkQueue queue,
uint32_t queueFamilyIndex, VkImage image, VkFormat format, float depthValue,
uint32_t stencilValue, VkImageLayout oldLayout, VkImageLayout newLayout,
VkAccessFlags dstAccessFlags, VkPipelineStageFlags dstStageFlags)
{
Move<VkCommandPool> cmdPool = createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
const VkClearDepthStencilValue clearValue = makeClearValueDepthStencil(depthValue, stencilValue).depthStencil;
const auto aspectMask = getImageAspectFlags(mapVkFormat(format));
const VkImageSubresourceRange subresourceRange = {
aspectMask, // VkImageAspectFlags aspectMask
0u, // uint32_t baseMipLevel
1u, // uint32_t levelCount
0u, // uint32_t baseArrayLayer
1u // uint32_t layerCount
};
const VkImageMemoryBarrier preImageBarrier = {
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
DE_NULL, // const void* pNext;
0u, // VkAccessFlags srcAccessMask;
VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
oldLayout, // VkImageLayout oldLayout;
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
queueFamilyIndex, // uint32_t srcQueueFamilyIndex;
queueFamilyIndex, // uint32_t dstQueueFamilyIndex;
image, // VkImage image;
subresourceRange // VkImageSubresourceRange subresourceRange;
};
const VkImageMemoryBarrier postImageBarrier = {
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
DE_NULL, // const void* pNext;
VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
dstAccessFlags, // VkAccessFlags dstAccessMask;
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
newLayout, // VkImageLayout newLayout;
queueFamilyIndex, // uint32_t srcQueueFamilyIndex;
queueFamilyIndex, // uint32_t dstQueueFamilyIndex;
image, // VkImage image;
subresourceRange // VkImageSubresourceRange subresourceRange;
};
beginCommandBuffer(vk, *cmdBuffer);
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
0, (const VkMemoryBarrier *)DE_NULL, 0, (const VkBufferMemoryBarrier *)DE_NULL, 1,
&preImageBarrier);
vk.cmdClearDepthStencilImage(*cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue, 1,
&subresourceRange);
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, dstStageFlags, (VkDependencyFlags)0, 0,
(const VkMemoryBarrier *)DE_NULL, 0, (const VkBufferMemoryBarrier *)DE_NULL, 1,
&postImageBarrier);
endCommandBuffer(vk, *cmdBuffer);
submitCommandsAndWait(vk, device, queue, *cmdBuffer);
}
void initDepthStencilImageChessboardPattern(const DeviceInterface &vk, const VkDevice device, const VkQueue queue,
uint32_t queueFamilyIndex, Allocator &allocator, VkImage image,
VkFormat format, float depthValue0, float depthValue1,
uint32_t stencilValue0, uint32_t stencilValue1, uint32_t imageWidth,
uint32_t imageHeight, uint32_t tileSize, VkImageLayout oldLayout,
VkImageLayout newLayout, VkPipelineStageFlags dstStageFlags)
{
Move<VkCommandPool> cmdPool = createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
const uint32_t depthBufferSize = tileSize * tileSize * 4;
const uint32_t stencilBufferSize = tileSize * tileSize;
const float depthValues[] = {depthValue0, depthValue1};
const uint32_t stencilValues[] = {stencilValue0, stencilValue1};
const tcu::TextureFormat tcuFormat = mapVkFormat(format);
const VkImageSubresourceRange subresourceRange = {
VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags aspectMask
0u, // uint32_t baseMipLevel
1u, // uint32_t levelCount
0u, // uint32_t baseArrayLayer
1u // uint32_t layerCount
};
const VkImageMemoryBarrier preImageBarrier = {
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
DE_NULL, // const void* pNext;
0u, // VkAccessFlags srcAccessMask;
VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
oldLayout, // VkImageLayout oldLayout;
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
queueFamilyIndex, // uint32_t srcQueueFamilyIndex;
queueFamilyIndex, // uint32_t dstQueueFamilyIndex;
image, // VkImage image;
subresourceRange // VkImageSubresourceRange subresourceRange;
};
const VkImageMemoryBarrier postImageBarrier = {
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
DE_NULL, // const void* pNext;
VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask;
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
newLayout, // VkImageLayout newLayout;
queueFamilyIndex, // uint32_t srcQueueFamilyIndex;
queueFamilyIndex, // uint32_t dstQueueFamilyIndex;
image, // VkImage image;
subresourceRange // VkImageSubresourceRange subresourceRange;
};
// Create staging buffers for depth and stencil values
Move<VkBuffer> depthBuffers[2];
de::MovePtr<Allocation> depthBufferAllocs[2];
Move<VkBuffer> stencilBuffers[2];
de::MovePtr<Allocation> stencilBufferAllocs[2];
const VkBufferCreateInfo depthBufferParams = {
VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType
DE_NULL, // const void* pNext
0u, // VkBufferCreateFlags flags
(VkDeviceSize)depthBufferSize, // VkDeviceSize size
VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage
VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
0u, // uint32_t queueFamilyIndexCount
DE_NULL // const uint32_t* pQueueFamilyIndices
};
const VkBufferCreateInfo stencilBufferParams = {
VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType
DE_NULL, // const void* pNext
0u, // VkBufferCreateFlags flags
(VkDeviceSize)stencilBufferSize, // VkDeviceSize size
VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage
VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
0u, // uint32_t queueFamilyIndexCount
DE_NULL // const uint32_t* pQueueFamilyIndices
};
for (uint32_t bufferIdx = 0; bufferIdx < 2; bufferIdx++)
{
depthBuffers[bufferIdx] = createBuffer(vk, device, &depthBufferParams);
depthBufferAllocs[bufferIdx] = allocator.allocate(
getBufferMemoryRequirements(vk, device, *depthBuffers[bufferIdx]), MemoryRequirement::HostVisible);
VK_CHECK(vk.bindBufferMemory(device, *depthBuffers[bufferIdx], depthBufferAllocs[bufferIdx]->getMemory(),
depthBufferAllocs[bufferIdx]->getOffset()));
stencilBuffers[bufferIdx] = createBuffer(vk, device, &stencilBufferParams);
stencilBufferAllocs[bufferIdx] = allocator.allocate(
getBufferMemoryRequirements(vk, device, *stencilBuffers[bufferIdx]), MemoryRequirement::HostVisible);
VK_CHECK(vk.bindBufferMemory(device, *stencilBuffers[bufferIdx], stencilBufferAllocs[bufferIdx]->getMemory(),
stencilBufferAllocs[bufferIdx]->getOffset()));
uint32_t *depthPtr = (uint32_t *)depthBufferAllocs[bufferIdx]->getHostPtr();
uint32_t *stencilPtr = (uint32_t *)stencilBufferAllocs[bufferIdx]->getHostPtr();
if (format == VK_FORMAT_D24_UNORM_S8_UINT)
{
tcu::PixelBufferAccess access(tcuFormat, tileSize, tileSize, 1, depthPtr);
for (uint32_t x = 0; x < tileSize; x++)
for (uint32_t y = 0; y < tileSize; y++)
access.setPixDepth(depthValues[bufferIdx], x, y, 0);
}
else
{
DE_ASSERT(format == VK_FORMAT_D32_SFLOAT_S8_UINT);
for (uint32_t i = 0; i < tileSize * tileSize; i++)
((float *)depthPtr)[i] = depthValues[bufferIdx];
}
deMemset(stencilPtr, stencilValues[bufferIdx], stencilBufferSize);
flushAlloc(vk, device, *depthBufferAllocs[bufferIdx]);
flushAlloc(vk, device, *stencilBufferAllocs[bufferIdx]);
}
beginCommandBuffer(vk, *cmdBuffer);
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
0, (const VkMemoryBarrier *)DE_NULL, 0, (const VkBufferMemoryBarrier *)DE_NULL, 1,
&preImageBarrier);
for (uint32_t bufferIdx = 0; bufferIdx < 2; bufferIdx++)
{
std::vector<VkBufferImageCopy> copyRegionsDepth =
generateChessboardCopyRegions(tileSize, imageWidth, imageHeight, bufferIdx, VK_IMAGE_ASPECT_DEPTH_BIT);
std::vector<VkBufferImageCopy> copyRegionsStencil =
generateChessboardCopyRegions(tileSize, imageWidth, imageHeight, bufferIdx, VK_IMAGE_ASPECT_STENCIL_BIT);
vk.cmdCopyBufferToImage(*cmdBuffer, *depthBuffers[bufferIdx], image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
(uint32_t)copyRegionsDepth.size(), copyRegionsDepth.data());
vk.cmdCopyBufferToImage(*cmdBuffer, *stencilBuffers[bufferIdx], image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
(uint32_t)copyRegionsStencil.size(), copyRegionsStencil.data());
}
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, dstStageFlags, (VkDependencyFlags)0, 0,
(const VkMemoryBarrier *)DE_NULL, 0, (const VkBufferMemoryBarrier *)DE_NULL, 1,
&postImageBarrier);
endCommandBuffer(vk, *cmdBuffer);
submitCommandsAndWait(vk, device, queue, *cmdBuffer);
}
vk::VkImageSubresourceRange makeDefaultImageSubresourceRange()
{
return vk::makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
}
vk::VkImageSubresourceLayers makeDefaultImageSubresourceLayers()
{
return makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
}
ImageWithBuffer::ImageWithBuffer(const DeviceInterface &vkd, const VkDevice device, Allocator &alloc,
vk::VkExtent3D extent, vk::VkFormat imageFormat, vk::VkImageUsageFlags usage,
vk::VkImageType imageType, vk::VkImageSubresourceRange ssr, uint32_t arrayLayers,
vk::VkSampleCountFlagBits samples, vk::VkImageTiling tiling, uint32_t mipLevels,
vk::VkSharingMode sharingMode)
{
if (imageType == VK_IMAGE_TYPE_3D)
DE_ASSERT(arrayLayers == 1);
DE_ASSERT(extent.width > 0 && extent.height > 0 && extent.depth > 0);
DE_ASSERT(mipLevels > 0 && arrayLayers > 0);
// Color attachment.
const VkImageCreateInfo colorAttachmentCreateInfo = {
VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
nullptr, // const void* pNext;
0u, // VkImageCreateFlags flags;
imageType, // VkImageType imageType;
imageFormat, // VkFormat format;
extent, // VkExtent3D extent;
mipLevels, // uint32_t mipLevels;
arrayLayers, // uint32_t arrayLayers;
samples, // VkSampleCountFlagBits samples;
tiling, // VkImageTiling tiling;
usage, // VkImageUsageFlags usage;
sharingMode, // VkSharingMode sharingMode;
0u, // uint32_t queueFamilyIndexCount;
nullptr, // const uint32_t* pQueueFamilyIndices;
VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
};
image = std::unique_ptr<ImageWithMemory>(
new ImageWithMemory(vkd, device, alloc, colorAttachmentCreateInfo, MemoryRequirement::Any));
VkImageViewType viewType;
switch (imageType)
{
case VK_IMAGE_TYPE_1D:
viewType = ((arrayLayers == 1) ? VK_IMAGE_VIEW_TYPE_1D : VK_IMAGE_VIEW_TYPE_1D_ARRAY);
break;
case VK_IMAGE_TYPE_2D:
viewType = ((arrayLayers == 1) ? VK_IMAGE_VIEW_TYPE_2D : VK_IMAGE_VIEW_TYPE_2D_ARRAY);
break;
case VK_IMAGE_TYPE_3D:
viewType = VK_IMAGE_VIEW_TYPE_3D;
break;
default:
viewType = VK_IMAGE_VIEW_TYPE_LAST;
DE_ASSERT(imageType <= VK_IMAGE_TYPE_3D);
}
// Color attachment view.
imageView = makeImageView(vkd, device, (*image).get(), viewType, imageFormat, ssr);
// Verification buffer.
const auto tcuFormat = mapVkFormat(imageFormat);
const auto verificationBufferSize =
tcuFormat.getPixelSize() * extent.width * extent.height * arrayLayers * extent.depth;
const auto verificationBufferCreateInfo =
makeBufferCreateInfo(verificationBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
buffer = std::unique_ptr<BufferWithMemory>(
new BufferWithMemory(vkd, device, alloc, verificationBufferCreateInfo, MemoryRequirement::HostVisible));
size = verificationBufferSize;
}
VkImage ImageWithBuffer::getImage()
{
return (*image).get();
}
VkImageView ImageWithBuffer::getImageView()
{
return imageView.get();
}
VkBuffer ImageWithBuffer::getBuffer()
{
return (*buffer).get();
}
VkDeviceSize ImageWithBuffer::getBufferSize()
{
return size;
}
Allocation &ImageWithBuffer::getImageAllocation()
{
return (*image).getAllocation();
}
Allocation &ImageWithBuffer::getBufferAllocation()
{
return (*buffer).getAllocation();
}
#ifndef CTS_USES_VULKANSC
void allocateAndBindSparseImage(const DeviceInterface &vk, VkDevice device, const VkPhysicalDevice physicalDevice,
const InstanceInterface &instance, const VkImageCreateInfo &imageCreateInfo,
const VkSemaphore &signalSemaphore, VkQueue queue, Allocator &allocator,
std::vector<de::SharedPtr<Allocation>> &allocations, tcu::TextureFormat format,
VkImage destImage)
{
const VkImageAspectFlags imageAspectFlags = getImageAspectFlags(format);
const VkPhysicalDeviceProperties deviceProperties = getPhysicalDeviceProperties(instance, physicalDevice);
const VkPhysicalDeviceMemoryProperties deviceMemoryProperties =
getPhysicalDeviceMemoryProperties(instance, physicalDevice);
uint32_t sparseMemoryReqCount = 0;
// Check if the image format supports sparse operations
if (!checkSparseImageFormatSupport(physicalDevice, instance, imageCreateInfo))
TCU_THROW(NotSupportedError, "The image format does not support sparse operations.");
vk.getImageSparseMemoryRequirements(device, destImage, &sparseMemoryReqCount, DE_NULL);
DE_ASSERT(sparseMemoryReqCount != 0);
std::vector<VkSparseImageMemoryRequirements> sparseImageMemoryRequirements;
sparseImageMemoryRequirements.resize(sparseMemoryReqCount);
vk.getImageSparseMemoryRequirements(device, destImage, &sparseMemoryReqCount, &sparseImageMemoryRequirements[0]);
const uint32_t noMatchFound = ~((uint32_t)0);
uint32_t aspectIndex = noMatchFound;
for (uint32_t memoryReqNdx = 0; memoryReqNdx < sparseMemoryReqCount; ++memoryReqNdx)
{
if (sparseImageMemoryRequirements[memoryReqNdx].formatProperties.aspectMask == imageAspectFlags)
{
aspectIndex = memoryReqNdx;
break;
}
}
uint32_t metadataAspectIndex = noMatchFound;
for (uint32_t memoryReqNdx = 0; memoryReqNdx < sparseMemoryReqCount; ++memoryReqNdx)
{
if (sparseImageMemoryRequirements[memoryReqNdx].formatProperties.aspectMask & VK_IMAGE_ASPECT_METADATA_BIT)
{
metadataAspectIndex = memoryReqNdx;
break;
}
}
if (aspectIndex == noMatchFound)
TCU_THROW(NotSupportedError, "Required image aspect not supported.");
const VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vk, device, destImage);
uint32_t memoryType = noMatchFound;
for (uint32_t memoryTypeNdx = 0; memoryTypeNdx < deviceMemoryProperties.memoryTypeCount; ++memoryTypeNdx)
{
if ((memoryRequirements.memoryTypeBits & (1u << memoryTypeNdx)) != 0 &&
MemoryRequirement::Any.matchesHeap(deviceMemoryProperties.memoryTypes[memoryTypeNdx].propertyFlags))
{
memoryType = memoryTypeNdx;
break;
}
}
if (memoryType == noMatchFound)
TCU_THROW(NotSupportedError, "No matching memory type found.");
if (memoryRequirements.size > deviceProperties.limits.sparseAddressSpaceSize)
TCU_THROW(NotSupportedError, "Required memory size for sparse resource exceeds device limits.");
const VkSparseImageMemoryRequirements aspectRequirements = sparseImageMemoryRequirements[aspectIndex];
VkExtent3D blockSize = aspectRequirements.formatProperties.imageGranularity;
std::vector<VkSparseImageMemoryBind> imageResidencyMemoryBinds;
std::vector<VkSparseMemoryBind> imageMipTailMemoryBinds;
for (uint32_t layerNdx = 0; layerNdx < imageCreateInfo.arrayLayers; ++layerNdx)
{
for (uint32_t mipLevelNdx = 0; mipLevelNdx < aspectRequirements.imageMipTailFirstLod; ++mipLevelNdx)
{
const VkExtent3D mipExtent = mipLevelExtents(imageCreateInfo.extent, mipLevelNdx);
const tcu::UVec3 numSparseBinds = alignedDivide(mipExtent, blockSize);
const tcu::UVec3 lastBlockExtent =
tcu::UVec3(mipExtent.width % blockSize.width ? mipExtent.width % blockSize.width : blockSize.width,
mipExtent.height % blockSize.height ? mipExtent.height % blockSize.height : blockSize.height,
mipExtent.depth % blockSize.depth ? mipExtent.depth % blockSize.depth : blockSize.depth);
for (uint32_t z = 0; z < numSparseBinds.z(); ++z)
for (uint32_t y = 0; y < numSparseBinds.y(); ++y)
for (uint32_t x = 0; x < numSparseBinds.x(); ++x)
{
const VkMemoryRequirements allocRequirements = {
// 28.7.5 alignment shows the block size in bytes
memoryRequirements.alignment, // VkDeviceSize size;
memoryRequirements.alignment, // VkDeviceSize alignment;
memoryRequirements.memoryTypeBits, // uint32_t memoryTypeBits;
};
de::SharedPtr<Allocation> allocation(
allocator.allocate(allocRequirements, MemoryRequirement::Any).release());
allocations.push_back(allocation);
VkOffset3D offset;
offset.x = x * blockSize.width;
offset.y = y * blockSize.height;
offset.z = z * blockSize.depth;
VkExtent3D extent;
extent.width = (x == numSparseBinds.x() - 1) ? lastBlockExtent.x() : blockSize.width;
extent.height = (y == numSparseBinds.y() - 1) ? lastBlockExtent.y() : blockSize.height;
extent.depth = (z == numSparseBinds.z() - 1) ? lastBlockExtent.z() : blockSize.depth;
const VkSparseImageMemoryBind imageMemoryBind = {
{
imageAspectFlags, // VkImageAspectFlags aspectMask;
mipLevelNdx, // uint32_t mipLevel;
layerNdx, // uint32_t arrayLayer;
}, // VkImageSubresource subresource;
offset, // VkOffset3D offset;
extent, // VkExtent3D extent;
allocation->getMemory(), // VkDeviceMemory memory;
allocation->getOffset(), // VkDeviceSize memoryOffset;
0u, // VkSparseMemoryBindFlags flags;
};
imageResidencyMemoryBinds.push_back(imageMemoryBind);
}
}
// Handle MIP tail. There are two cases to consider here:
//
// 1) VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT is requested by the driver: each layer needs a separate tail.
// 2) otherwise: only one tail is needed.
if (aspectRequirements.imageMipTailSize > 0)
{
if (layerNdx == 0 ||
(aspectRequirements.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT) == 0)
{
const VkMemoryRequirements allocRequirements = {
aspectRequirements.imageMipTailSize, // VkDeviceSize size;
memoryRequirements.alignment, // VkDeviceSize alignment;
memoryRequirements.memoryTypeBits, // uint32_t memoryTypeBits;
};
const de::SharedPtr<Allocation> allocation(
allocator.allocate(allocRequirements, MemoryRequirement::Any).release());
const VkSparseMemoryBind imageMipTailMemoryBind = {
aspectRequirements.imageMipTailOffset +
layerNdx * aspectRequirements.imageMipTailStride, // VkDeviceSize resourceOffset;
aspectRequirements.imageMipTailSize, // VkDeviceSize size;
allocation->getMemory(), // VkDeviceMemory memory;
allocation->getOffset(), // VkDeviceSize memoryOffset;
0u, // VkSparseMemoryBindFlags flags;
};
allocations.push_back(allocation);
imageMipTailMemoryBinds.push_back(imageMipTailMemoryBind);
}
}
// Handle Metadata. Similarly to MIP tail in aspectRequirements, there are two cases to consider here:
//
// 1) VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT is requested by the driver: each layer needs a separate tail.
// 2) otherwise:
if (metadataAspectIndex != noMatchFound)
{
const VkSparseImageMemoryRequirements metadataAspectRequirements =
sparseImageMemoryRequirements[metadataAspectIndex];
if (layerNdx == 0 ||
(metadataAspectRequirements.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT) == 0)
{
const VkMemoryRequirements metadataAllocRequirements = {
metadataAspectRequirements.imageMipTailSize, // VkDeviceSize size;
memoryRequirements.alignment, // VkDeviceSize alignment;
memoryRequirements.memoryTypeBits, // uint32_t memoryTypeBits;
};
const de::SharedPtr<Allocation> metadataAllocation(
allocator.allocate(metadataAllocRequirements, MemoryRequirement::Any).release());
const VkSparseMemoryBind metadataMipTailMemoryBind = {
metadataAspectRequirements.imageMipTailOffset +
layerNdx * metadataAspectRequirements.imageMipTailStride, // VkDeviceSize resourceOffset;
metadataAspectRequirements.imageMipTailSize, // VkDeviceSize size;
metadataAllocation->getMemory(), // VkDeviceMemory memory;
metadataAllocation->getOffset(), // VkDeviceSize memoryOffset;
VK_SPARSE_MEMORY_BIND_METADATA_BIT // VkSparseMemoryBindFlags flags;
};
allocations.push_back(metadataAllocation);
imageMipTailMemoryBinds.push_back(metadataMipTailMemoryBind);
}
}
}
VkBindSparseInfo bindSparseInfo = {
VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, //VkStructureType sType;
DE_NULL, //const void* pNext;
0u, //uint32_t waitSemaphoreCount;
DE_NULL, //const VkSemaphore* pWaitSemaphores;
0u, //uint32_t bufferBindCount;
DE_NULL, //const VkSparseBufferMemoryBindInfo* pBufferBinds;
0u, //uint32_t imageOpaqueBindCount;
DE_NULL, //const VkSparseImageOpaqueMemoryBindInfo* pImageOpaqueBinds;
0u, //uint32_t imageBindCount;
DE_NULL, //const VkSparseImageMemoryBindInfo* pImageBinds;
1u, //uint32_t signalSemaphoreCount;
&signalSemaphore //const VkSemaphore* pSignalSemaphores;
};
VkSparseImageMemoryBindInfo imageResidencyBindInfo;
VkSparseImageOpaqueMemoryBindInfo imageMipTailBindInfo;
if (imageResidencyMemoryBinds.size() > 0)
{
imageResidencyBindInfo.image = destImage;
imageResidencyBindInfo.bindCount = static_cast<uint32_t>(imageResidencyMemoryBinds.size());
imageResidencyBindInfo.pBinds = &imageResidencyMemoryBinds[0];
bindSparseInfo.imageBindCount = 1u;
bindSparseInfo.pImageBinds = &imageResidencyBindInfo;
}
if (imageMipTailMemoryBinds.size() > 0)
{
imageMipTailBindInfo.image = destImage;
imageMipTailBindInfo.bindCount = static_cast<uint32_t>(imageMipTailMemoryBinds.size());
imageMipTailBindInfo.pBinds = &imageMipTailMemoryBinds[0];
bindSparseInfo.imageOpaqueBindCount = 1u;
bindSparseInfo.pImageOpaqueBinds = &imageMipTailBindInfo;
}
VK_CHECK(vk.queueBindSparse(queue, 1u, &bindSparseInfo, VK_NULL_HANDLE));
}
bool checkSparseImageFormatSupport(const VkPhysicalDevice physicalDevice, const InstanceInterface &instance,
const VkFormat format, const VkImageType imageType,
const VkSampleCountFlagBits sampleCount, const VkImageUsageFlags usageFlags,
const VkImageTiling imageTiling)
{
const auto propVec = getPhysicalDeviceSparseImageFormatProperties(instance, physicalDevice, format, imageType,
sampleCount, usageFlags, imageTiling);
return (propVec.size() != 0);
}
bool checkSparseImageFormatSupport(const VkPhysicalDevice physicalDevice, const InstanceInterface &instance,
const VkImageCreateInfo &imageCreateInfo)
{
return checkSparseImageFormatSupport(physicalDevice, instance, imageCreateInfo.format, imageCreateInfo.imageType,
imageCreateInfo.samples, imageCreateInfo.usage, imageCreateInfo.tiling);
}
#endif // CTS_USES_VULKANSC
} // namespace vk