blob: 67252695947df6e210e1d37a60ddcc32526d8520 [file] [log] [blame]
/*------------------------------------------------------------------------
* Vulkan Conformance Tests
* ------------------------
*
* Copyright (c) 2016 The Khronos Group Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*//*!
* \file vktSparseResourcesTestsUtil.cpp
* \brief Sparse Resources Tests Utility Classes
*//*--------------------------------------------------------------------*/
#include "vktSparseResourcesTestsUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkDeviceUtil.hpp"
#include "vkTypeUtil.hpp"
#include "tcuTextureUtil.hpp"
#include "deStringUtil.hpp"
#include <deMath.h>
using namespace vk;
namespace vkt
{
namespace sparse
{
bool formatIsR64 (const VkFormat& format)
{
switch (format)
{
case VK_FORMAT_R64_SINT:
case VK_FORMAT_R64_UINT:
return true;
default:
return false;
}
}
std::vector<TestFormat> getTestFormats (const ImageType& imageType)
{
std::vector<TestFormat> results =
{
{ VK_FORMAT_R64_SINT }, { VK_FORMAT_R32_SINT }, { VK_FORMAT_R16_SINT }, { VK_FORMAT_R8_SINT },
{ VK_FORMAT_R64_UINT }, { VK_FORMAT_R32_UINT }, { VK_FORMAT_R16_UINT }, { VK_FORMAT_R8_UINT },
{ VK_FORMAT_R16_UNORM }, { VK_FORMAT_R8_UNORM },
{ VK_FORMAT_R16_SNORM }, { VK_FORMAT_R8_SNORM },
{ VK_FORMAT_R32G32_SINT }, { VK_FORMAT_R16G16_SINT }, { VK_FORMAT_R8G8_SINT },
{ VK_FORMAT_R32G32_UINT }, { VK_FORMAT_R16G16_UINT }, { VK_FORMAT_R8G8_UINT },
{ VK_FORMAT_R16G16_UNORM }, { VK_FORMAT_R8G8_UNORM },
{ VK_FORMAT_R16G16_SNORM }, { VK_FORMAT_R8G8_SNORM },
{ VK_FORMAT_R32G32B32A32_SINT }, { VK_FORMAT_R16G16B16A16_SINT }, { VK_FORMAT_R8G8B8A8_SINT },
{ VK_FORMAT_R32G32B32A32_UINT }, { VK_FORMAT_R16G16B16A16_UINT }, { VK_FORMAT_R8G8B8A8_UINT },
{ VK_FORMAT_R16G16B16A16_UNORM }, { VK_FORMAT_R8G8B8A8_UNORM },
{ VK_FORMAT_R16G16B16A16_SNORM }, { VK_FORMAT_R8G8B8A8_SNORM }
};
if (imageType == IMAGE_TYPE_2D || imageType == IMAGE_TYPE_2D_ARRAY)
{
std::vector<TestFormat> ycbcrFormats =
{
{ VK_FORMAT_G8B8G8R8_422_UNORM },
{ VK_FORMAT_B8G8R8G8_422_UNORM },
{ VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM },
{ VK_FORMAT_G8_B8R8_2PLANE_420_UNORM },
{ VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM },
{ VK_FORMAT_G8_B8R8_2PLANE_422_UNORM },
{ VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM },
{ VK_FORMAT_R10X6_UNORM_PACK16 },
{ VK_FORMAT_R10X6G10X6_UNORM_2PACK16 },
{ VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16 },
{ VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16 },
{ VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16 },
{ VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16 },
{ VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16 },
{ VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16 },
{ VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16 },
{ VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16 },
{ VK_FORMAT_R12X4_UNORM_PACK16 },
{ VK_FORMAT_R12X4G12X4_UNORM_2PACK16 },
{ VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16 },
{ VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16 },
{ VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16 },
{ VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16 },
{ VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16 },
{ VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16 },
{ VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16 },
{ VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16 },
{ VK_FORMAT_G16B16G16R16_422_UNORM },
{ VK_FORMAT_B16G16R16G16_422_UNORM },
{ VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM },
{ VK_FORMAT_G16_B16R16_2PLANE_420_UNORM },
{ VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM },
{ VK_FORMAT_G16_B16R16_2PLANE_422_UNORM },
{ VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM },
{ VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT },
{ VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT },
{ VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT },
{ VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT },
};
std::copy(begin(ycbcrFormats), end(ycbcrFormats), std::back_inserter(results));
}
return results;
}
tcu::UVec3 getShaderGridSize (const ImageType imageType, const tcu::UVec3& imageSize, const deUint32 mipLevel)
{
const deUint32 mipLevelX = std::max(imageSize.x() >> mipLevel, 1u);
const deUint32 mipLevelY = std::max(imageSize.y() >> mipLevel, 1u);
const deUint32 mipLevelZ = std::max(imageSize.z() >> mipLevel, 1u);
switch (imageType)
{
case IMAGE_TYPE_1D:
return tcu::UVec3(mipLevelX, 1u, 1u);
case IMAGE_TYPE_BUFFER:
return tcu::UVec3(imageSize.x(), 1u, 1u);
case IMAGE_TYPE_1D_ARRAY:
return tcu::UVec3(mipLevelX, imageSize.z(), 1u);
case IMAGE_TYPE_2D:
return tcu::UVec3(mipLevelX, mipLevelY, 1u);
case IMAGE_TYPE_2D_ARRAY:
return tcu::UVec3(mipLevelX, mipLevelY, imageSize.z());
case IMAGE_TYPE_3D:
return tcu::UVec3(mipLevelX, mipLevelY, mipLevelZ);
case IMAGE_TYPE_CUBE:
return tcu::UVec3(mipLevelX, mipLevelY, 6u);
case IMAGE_TYPE_CUBE_ARRAY:
return tcu::UVec3(mipLevelX, mipLevelY, 6u * imageSize.z());
default:
DE_FATAL("Unknown image type");
return tcu::UVec3(1u, 1u, 1u);
}
}
tcu::UVec3 getLayerSize (const ImageType imageType, const tcu::UVec3& imageSize)
{
switch (imageType)
{
case IMAGE_TYPE_1D:
case IMAGE_TYPE_1D_ARRAY:
case IMAGE_TYPE_BUFFER:
return tcu::UVec3(imageSize.x(), 1u, 1u);
case IMAGE_TYPE_2D:
case IMAGE_TYPE_2D_ARRAY:
case IMAGE_TYPE_CUBE:
case IMAGE_TYPE_CUBE_ARRAY:
return tcu::UVec3(imageSize.x(), imageSize.y(), 1u);
case IMAGE_TYPE_3D:
return tcu::UVec3(imageSize.x(), imageSize.y(), imageSize.z());
default:
DE_FATAL("Unknown image type");
return tcu::UVec3(1u, 1u, 1u);
}
}
deUint32 getNumLayers (const ImageType imageType, const tcu::UVec3& imageSize)
{
switch (imageType)
{
case IMAGE_TYPE_1D:
case IMAGE_TYPE_2D:
case IMAGE_TYPE_3D:
case IMAGE_TYPE_BUFFER:
return 1u;
case IMAGE_TYPE_1D_ARRAY:
case IMAGE_TYPE_2D_ARRAY:
return imageSize.z();
case IMAGE_TYPE_CUBE:
return 6u;
case IMAGE_TYPE_CUBE_ARRAY:
return imageSize.z() * 6u;
default:
DE_FATAL("Unknown image type");
return 0u;
}
}
deUint32 getNumPixels (const ImageType imageType, const tcu::UVec3& imageSize)
{
const tcu::UVec3 gridSize = getShaderGridSize(imageType, imageSize);
return gridSize.x() * gridSize.y() * gridSize.z();
}
deUint32 getDimensions (const ImageType imageType)
{
switch (imageType)
{
case IMAGE_TYPE_1D:
case IMAGE_TYPE_BUFFER:
return 1u;
case IMAGE_TYPE_1D_ARRAY:
case IMAGE_TYPE_2D:
return 2u;
case IMAGE_TYPE_2D_ARRAY:
case IMAGE_TYPE_CUBE:
case IMAGE_TYPE_CUBE_ARRAY:
case IMAGE_TYPE_3D:
return 3u;
default:
DE_FATAL("Unknown image type");
return 0u;
}
}
deUint32 getLayerDimensions (const ImageType imageType)
{
switch (imageType)
{
case IMAGE_TYPE_1D:
case IMAGE_TYPE_BUFFER:
case IMAGE_TYPE_1D_ARRAY:
return 1u;
case IMAGE_TYPE_2D:
case IMAGE_TYPE_2D_ARRAY:
case IMAGE_TYPE_CUBE:
case IMAGE_TYPE_CUBE_ARRAY:
return 2u;
case IMAGE_TYPE_3D:
return 3u;
default:
DE_FATAL("Unknown image type");
return 0u;
}
}
bool isImageSizeSupported (const InstanceInterface& instance, const VkPhysicalDevice physicalDevice, const ImageType imageType, const tcu::UVec3& imageSize)
{
const VkPhysicalDeviceProperties deviceProperties = getPhysicalDeviceProperties(instance, physicalDevice);
switch (imageType)
{
case IMAGE_TYPE_1D:
return imageSize.x() <= deviceProperties.limits.maxImageDimension1D;
case IMAGE_TYPE_1D_ARRAY:
return imageSize.x() <= deviceProperties.limits.maxImageDimension1D &&
imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
case IMAGE_TYPE_2D:
return imageSize.x() <= deviceProperties.limits.maxImageDimension2D &&
imageSize.y() <= deviceProperties.limits.maxImageDimension2D;
case IMAGE_TYPE_2D_ARRAY:
return imageSize.x() <= deviceProperties.limits.maxImageDimension2D &&
imageSize.y() <= deviceProperties.limits.maxImageDimension2D &&
imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
case IMAGE_TYPE_CUBE:
return imageSize.x() <= deviceProperties.limits.maxImageDimensionCube &&
imageSize.y() <= deviceProperties.limits.maxImageDimensionCube;
case IMAGE_TYPE_CUBE_ARRAY:
return imageSize.x() <= deviceProperties.limits.maxImageDimensionCube &&
imageSize.y() <= deviceProperties.limits.maxImageDimensionCube &&
imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
case IMAGE_TYPE_3D:
return imageSize.x() <= deviceProperties.limits.maxImageDimension3D &&
imageSize.y() <= deviceProperties.limits.maxImageDimension3D &&
imageSize.z() <= deviceProperties.limits.maxImageDimension3D;
case IMAGE_TYPE_BUFFER:
return true;
default:
DE_FATAL("Unknown image type");
return false;
}
}
VkBufferImageCopy makeBufferImageCopy (const VkExtent3D extent,
const deUint32 layerCount,
const deUint32 mipmapLevel,
const VkDeviceSize bufferOffset)
{
const VkBufferImageCopy copyParams =
{
bufferOffset, // VkDeviceSize bufferOffset;
0u, // deUint32 bufferRowLength;
0u, // deUint32 bufferImageHeight;
makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, mipmapLevel, 0u, layerCount), // VkImageSubresourceLayers imageSubresource;
makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
extent, // VkExtent3D imageExtent;
};
return copyParams;
}
Move<VkPipeline> makeComputePipeline (const DeviceInterface& vk,
const VkDevice device,
const VkPipelineLayout pipelineLayout,
const VkShaderModule shaderModule,
const VkSpecializationInfo* specializationInfo)
{
const VkPipelineShaderStageCreateInfo pipelineShaderStageParams =
{
VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
DE_NULL, // const void* pNext;
0u, // VkPipelineShaderStageCreateFlags flags;
VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage;
shaderModule, // VkShaderModule module;
"main", // const char* pName;
specializationInfo, // const VkSpecializationInfo* pSpecializationInfo;
};
const VkComputePipelineCreateInfo pipelineCreateInfo =
{
VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
DE_NULL, // const void* pNext;
0u, // VkPipelineCreateFlags flags;
pipelineShaderStageParams, // VkPipelineShaderStageCreateInfo stage;
pipelineLayout, // VkPipelineLayout layout;
DE_NULL, // VkPipeline basePipelineHandle;
0, // deInt32 basePipelineIndex;
};
return createComputePipeline(vk, device, DE_NULL , &pipelineCreateInfo);
}
void submitCommands (const DeviceInterface& vk,
const VkQueue queue,
const VkCommandBuffer commandBuffer,
const deUint32 waitSemaphoreCount,
const VkSemaphore* pWaitSemaphores,
const VkPipelineStageFlags* pWaitDstStageMask,
const deUint32 signalSemaphoreCount,
const VkSemaphore* pSignalSemaphores)
{
const VkSubmitInfo submitInfo =
{
VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
DE_NULL, // const void* pNext;
waitSemaphoreCount, // deUint32 waitSemaphoreCount;
pWaitSemaphores, // const VkSemaphore* pWaitSemaphores;
pWaitDstStageMask, // const VkPipelineStageFlags* pWaitDstStageMask;
1u, // deUint32 commandBufferCount;
&commandBuffer, // const VkCommandBuffer* pCommandBuffers;
signalSemaphoreCount, // deUint32 signalSemaphoreCount;
pSignalSemaphores, // const VkSemaphore* pSignalSemaphores;
};
VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, DE_NULL));
}
void submitCommandsAndWait (const DeviceInterface& vk,
const VkDevice device,
const VkQueue queue,
const VkCommandBuffer commandBuffer,
const deUint32 waitSemaphoreCount,
const VkSemaphore* pWaitSemaphores,
const VkPipelineStageFlags* pWaitDstStageMask,
const deUint32 signalSemaphoreCount,
const VkSemaphore* pSignalSemaphores,
const bool useDeviceGroups,
const deUint32 physicalDeviceID)
{
const VkFenceCreateInfo fenceParams =
{
VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
DE_NULL, // const void* pNext;
0u, // VkFenceCreateFlags flags;
};
const Unique<VkFence> fence(createFence (vk, device, &fenceParams));
const deUint32 deviceMask = 1 << physicalDeviceID;
std::vector<deUint32> deviceIndices (waitSemaphoreCount, physicalDeviceID);
VkDeviceGroupSubmitInfo deviceGroupSubmitInfo =
{
VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO_KHR, //VkStructureType sType
DE_NULL, // const void* pNext
waitSemaphoreCount, // uint32_t waitSemaphoreCount
deviceIndices.size() ? &deviceIndices[0] : DE_NULL, // const uint32_t* pWaitSemaphoreDeviceIndices
1u, // uint32_t commandBufferCount
&deviceMask, // const uint32_t* pCommandBufferDeviceMasks
0u, // uint32_t signalSemaphoreCount
DE_NULL, // const uint32_t* pSignalSemaphoreDeviceIndices
};
const VkSubmitInfo submitInfo =
{
VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
useDeviceGroups ? &deviceGroupSubmitInfo : DE_NULL, // const void* pNext;
waitSemaphoreCount, // deUint32 waitSemaphoreCount;
pWaitSemaphores, // const VkSemaphore* pWaitSemaphores;
pWaitDstStageMask, // const VkPipelineStageFlags* pWaitDstStageMask;
1u, // deUint32 commandBufferCount;
&commandBuffer, // const VkCommandBuffer* pCommandBuffers;
signalSemaphoreCount, // deUint32 signalSemaphoreCount;
pSignalSemaphores, // const VkSemaphore* pSignalSemaphores;
};
VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull));
}
VkImageType mapImageType (const ImageType imageType)
{
switch (imageType)
{
case IMAGE_TYPE_1D:
case IMAGE_TYPE_1D_ARRAY:
case IMAGE_TYPE_BUFFER:
return VK_IMAGE_TYPE_1D;
case IMAGE_TYPE_2D:
case IMAGE_TYPE_2D_ARRAY:
case IMAGE_TYPE_CUBE:
case IMAGE_TYPE_CUBE_ARRAY:
return VK_IMAGE_TYPE_2D;
case IMAGE_TYPE_3D:
return VK_IMAGE_TYPE_3D;
default:
DE_FATAL("Unexpected image type");
return VK_IMAGE_TYPE_LAST;
}
}
VkImageViewType mapImageViewType (const ImageType imageType)
{
switch (imageType)
{
case IMAGE_TYPE_1D: return VK_IMAGE_VIEW_TYPE_1D;
case IMAGE_TYPE_1D_ARRAY: return VK_IMAGE_VIEW_TYPE_1D_ARRAY;
case IMAGE_TYPE_2D: return VK_IMAGE_VIEW_TYPE_2D;
case IMAGE_TYPE_2D_ARRAY: return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
case IMAGE_TYPE_3D: return VK_IMAGE_VIEW_TYPE_3D;
case IMAGE_TYPE_CUBE: return VK_IMAGE_VIEW_TYPE_CUBE;
case IMAGE_TYPE_CUBE_ARRAY: return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
default:
DE_FATAL("Unexpected image type");
return VK_IMAGE_VIEW_TYPE_LAST;
}
}
std::string getImageTypeName (const ImageType imageType)
{
switch (imageType)
{
case IMAGE_TYPE_1D: return "1d";
case IMAGE_TYPE_1D_ARRAY: return "1d_array";
case IMAGE_TYPE_2D: return "2d";
case IMAGE_TYPE_2D_ARRAY: return "2d_array";
case IMAGE_TYPE_3D: return "3d";
case IMAGE_TYPE_CUBE: return "cube";
case IMAGE_TYPE_CUBE_ARRAY: return "cube_array";
case IMAGE_TYPE_BUFFER: return "buffer";
default:
DE_FATAL("Unexpected image type");
return "";
}
}
std::string getShaderImageType (const tcu::TextureFormat& format, const ImageType imageType)
{
std::string formatPart = tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ? "u" :
tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? "i" : "";
std::string imageTypePart;
switch (imageType)
{
case IMAGE_TYPE_1D: imageTypePart = "1D"; break;
case IMAGE_TYPE_1D_ARRAY: imageTypePart = "1DArray"; break;
case IMAGE_TYPE_2D: imageTypePart = "2D"; break;
case IMAGE_TYPE_2D_ARRAY: imageTypePart = "2DArray"; break;
case IMAGE_TYPE_3D: imageTypePart = "3D"; break;
case IMAGE_TYPE_CUBE: imageTypePart = "Cube"; break;
case IMAGE_TYPE_CUBE_ARRAY: imageTypePart = "CubeArray"; break;
case IMAGE_TYPE_BUFFER: imageTypePart = "Buffer"; break;
default:
DE_FATAL("Unexpected image type");
}
return formatPart + "image" + imageTypePart;
}
std::string getShaderImageType (const vk::PlanarFormatDescription& description, const ImageType imageType)
{
std::string formatPart;
std::string imageTypePart;
// all PlanarFormatDescription types have at least one channel ( 0 ) and all channel types are the same :
switch (description.channels[0].type)
{
case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
formatPart = "i";
break;
case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
formatPart = "u";
break;
case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
break;
default:
DE_FATAL("Unexpected channel type");
}
if (formatIsR64(description.planes[0].planeCompatibleFormat))
formatPart += "64";
switch (imageType)
{
case IMAGE_TYPE_1D: imageTypePart = "1D"; break;
case IMAGE_TYPE_1D_ARRAY: imageTypePart = "1DArray"; break;
case IMAGE_TYPE_2D: imageTypePart = "2D"; break;
case IMAGE_TYPE_2D_ARRAY: imageTypePart = "2DArray"; break;
case IMAGE_TYPE_3D: imageTypePart = "3D"; break;
case IMAGE_TYPE_CUBE: imageTypePart = "Cube"; break;
case IMAGE_TYPE_CUBE_ARRAY: imageTypePart = "CubeArray"; break;
case IMAGE_TYPE_BUFFER: imageTypePart = "Buffer"; break;
default:
DE_FATAL("Unexpected image type");
}
return formatPart + "image" + imageTypePart;
}
std::string getShaderImageDataType(const tcu::TextureFormat& format)
{
switch (tcu::getTextureChannelClass(format.type))
{
case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
return "uvec4";
case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
return "ivec4";
case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
return "vec4";
default:
DE_FATAL("Unexpected channel type");
return "";
}
}
std::string getShaderImageDataType (const vk::PlanarFormatDescription& description)
{
switch (description.channels[0].type)
{
case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
return (formatIsR64(description.planes[0].planeCompatibleFormat) ? "u64vec4" : "uvec4");
case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
return (formatIsR64(description.planes[0].planeCompatibleFormat) ? "i64vec4" : "ivec4");
case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
return "vec4";
default:
DE_FATAL("Unexpected channel type");
return "";
}
}
std::string getShaderImageFormatQualifier (const tcu::TextureFormat& format)
{
const char* orderPart;
const char* typePart;
switch (format.order)
{
case tcu::TextureFormat::R: orderPart = "r"; break;
case tcu::TextureFormat::RG: orderPart = "rg"; break;
case tcu::TextureFormat::RGB: orderPart = "rgb"; break;
case tcu::TextureFormat::RGBA: orderPart = "rgba"; break;
default:
DE_FATAL("Unexpected channel order");
orderPart = DE_NULL;
}
switch (format.type)
{
case tcu::TextureFormat::FLOAT: typePart = "32f"; break;
case tcu::TextureFormat::HALF_FLOAT: typePart = "16f"; break;
case tcu::TextureFormat::UNSIGNED_INT32: typePart = "32ui"; break;
case tcu::TextureFormat::UNSIGNED_INT16: typePart = "16ui"; break;
case tcu::TextureFormat::UNSIGNED_INT8: typePart = "8ui"; break;
case tcu::TextureFormat::SIGNED_INT32: typePart = "32i"; break;
case tcu::TextureFormat::SIGNED_INT16: typePart = "16i"; break;
case tcu::TextureFormat::SIGNED_INT8: typePart = "8i"; break;
case tcu::TextureFormat::UNORM_INT16: typePart = "16"; break;
case tcu::TextureFormat::UNORM_INT8: typePart = "8"; break;
case tcu::TextureFormat::SNORM_INT16: typePart = "16_snorm"; break;
case tcu::TextureFormat::SNORM_INT8: typePart = "8_snorm"; break;
default:
DE_FATAL("Unexpected channel type");
typePart = DE_NULL;
}
return std::string() + orderPart + typePart;
}
std::string getShaderImageFormatQualifier (VkFormat format)
{
switch (format)
{
case VK_FORMAT_R8_SINT: return "r8i";
case VK_FORMAT_R16_SINT: return "r16i";
case VK_FORMAT_R32_SINT: return "r32i";
case VK_FORMAT_R64_SINT: return "r64i";
case VK_FORMAT_R8_UINT: return "r8ui";
case VK_FORMAT_R16_UINT: return "r16ui";
case VK_FORMAT_R32_UINT: return "r32ui";
case VK_FORMAT_R64_UINT: return "r64ui";
case VK_FORMAT_R8_SNORM: return "r8_snorm";
case VK_FORMAT_R16_SNORM: return "r16_snorm";
case VK_FORMAT_R8_UNORM: return "r8";
case VK_FORMAT_R16_UNORM: return "r16";
case VK_FORMAT_R8G8_SINT: return "rg8i";
case VK_FORMAT_R16G16_SINT: return "rg16i";
case VK_FORMAT_R32G32_SINT: return "rg32i";
case VK_FORMAT_R8G8_UINT: return "rg8ui";
case VK_FORMAT_R16G16_UINT: return "rg16ui";
case VK_FORMAT_R32G32_UINT: return "rg32ui";
case VK_FORMAT_R8G8_SNORM: return "rg8_snorm";
case VK_FORMAT_R16G16_SNORM: return "rg16_snorm";
case VK_FORMAT_R8G8_UNORM: return "rg8";
case VK_FORMAT_R16G16_UNORM: return "rg16";
case VK_FORMAT_R8G8B8A8_SINT: return "rgba8i";
case VK_FORMAT_R16G16B16A16_SINT: return "rgba16i";
case VK_FORMAT_R32G32B32A32_SINT: return "rgba32i";
case VK_FORMAT_R8G8B8A8_UINT: return "rgba8ui";
case VK_FORMAT_R16G16B16A16_UINT: return "rgba16ui";
case VK_FORMAT_R32G32B32A32_UINT: return "rgba32ui";
case VK_FORMAT_R8G8B8A8_SNORM: return "rgba8_snorm";
case VK_FORMAT_R16G16B16A16_SNORM: return "rgba16_snorm";
case VK_FORMAT_R8G8B8A8_UNORM: return "rgba8";
case VK_FORMAT_R16G16B16A16_UNORM: return "rgba16";
case VK_FORMAT_G8B8G8R8_422_UNORM: return "rgba8";
case VK_FORMAT_B8G8R8G8_422_UNORM: return "rgba8";
case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM: return "rgba8";
case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM: return "rgba8";
case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM: return "rgba8";
case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM: return "rgba8";
case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM: return "rgba8";
case VK_FORMAT_R10X6_UNORM_PACK16: return "r16";
case VK_FORMAT_R10X6G10X6_UNORM_2PACK16: return "rg16";
case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16: return "rgba16";
case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16: return "rgba16";
case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16: return "rgba16";
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16: return "rgba16";
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16: return "rgba16";
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16: return "rgba16";
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16: return "rgba16";
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16: return "rgba16";
case VK_FORMAT_R12X4_UNORM_PACK16: return "r16";
case VK_FORMAT_R12X4G12X4_UNORM_2PACK16: return "rg16";
case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16: return "rgba16";
case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16: return "rgba16";
case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16: return "rgba16";
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16: return "rgba16";
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16: return "rgba16";
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16: return "rgba16";
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16: return "rgba16";
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16: return "rgba16";
case VK_FORMAT_G16B16G16R16_422_UNORM: return "rgba16";
case VK_FORMAT_B16G16R16G16_422_UNORM: return "rgba16";
case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM: return "rgba16";
case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM: return "rgba16";
case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM: return "rgba16";
case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM: return "rgba16";
case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM: return "rgba16";
case VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT: return "rgba8";
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT:return "rgba16";
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT:return "rgba16";
case VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT: return "rgba16";
default:
DE_FATAL("Unexpected texture format");
return "error";
}
}
std::string getImageFormatID (VkFormat format)
{
switch (format)
{
case VK_FORMAT_R8_SINT: return "r8i";
case VK_FORMAT_R16_SINT: return "r16i";
case VK_FORMAT_R32_SINT: return "r32i";
case VK_FORMAT_R64_SINT: return "r64i";
case VK_FORMAT_R8_UINT: return "r8ui";
case VK_FORMAT_R16_UINT: return "r16ui";
case VK_FORMAT_R32_UINT: return "r32ui";
case VK_FORMAT_R64_UINT: return "r64ui";
case VK_FORMAT_R8_SNORM: return "r8_snorm";
case VK_FORMAT_R16_SNORM: return "r16_snorm";
case VK_FORMAT_R8_UNORM: return "r8";
case VK_FORMAT_R16_UNORM: return "r16";
case VK_FORMAT_R8G8_SINT: return "rg8i";
case VK_FORMAT_R16G16_SINT: return "rg16i";
case VK_FORMAT_R32G32_SINT: return "rg32i";
case VK_FORMAT_R8G8_UINT: return "rg8ui";
case VK_FORMAT_R16G16_UINT: return "rg16ui";
case VK_FORMAT_R32G32_UINT: return "rg32ui";
case VK_FORMAT_R8G8_SNORM: return "rg8_snorm";
case VK_FORMAT_R16G16_SNORM: return "rg16_snorm";
case VK_FORMAT_R8G8_UNORM: return "rg8";
case VK_FORMAT_R16G16_UNORM: return "rg16";
case VK_FORMAT_R8G8B8A8_SINT: return "rgba8i";
case VK_FORMAT_R16G16B16A16_SINT: return "rgba16i";
case VK_FORMAT_R32G32B32A32_SINT: return "rgba32i";
case VK_FORMAT_R8G8B8A8_UINT: return "rgba8ui";
case VK_FORMAT_R16G16B16A16_UINT: return "rgba16ui";
case VK_FORMAT_R32G32B32A32_UINT: return "rgba32ui";
case VK_FORMAT_R8G8B8A8_SNORM: return "rgba8_snorm";
case VK_FORMAT_R16G16B16A16_SNORM: return "rgba16_snorm";
case VK_FORMAT_R8G8B8A8_UNORM: return "rgba8";
case VK_FORMAT_R16G16B16A16_UNORM: return "rgba16";
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 de::toLower(std::string(getFormatName(format)).substr(10));
default:
DE_FATAL("Unexpected texture format");
return "error";
}
}
std::string getShaderImageCoordinates (const ImageType imageType,
const std::string& x,
const std::string& xy,
const std::string& xyz)
{
switch (imageType)
{
case IMAGE_TYPE_1D:
case IMAGE_TYPE_BUFFER:
return x;
case IMAGE_TYPE_1D_ARRAY:
case IMAGE_TYPE_2D:
return xy;
case IMAGE_TYPE_2D_ARRAY:
case IMAGE_TYPE_3D:
case IMAGE_TYPE_CUBE:
case IMAGE_TYPE_CUBE_ARRAY:
return xyz;
default:
DE_FATAL("Unexpected image type");
return "";
}
}
deUint32 getImageMipLevelSizeInBytes(const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevel, const deUint32 mipmapMemoryAlignment)
{
const VkExtent3D extents = mipLevelExtents(baseExtents, mipmapLevel);
return deAlign32(extents.width * extents.height * extents.depth * layersCount * tcu::getPixelSize(format), mipmapMemoryAlignment);
}
deUint32 getImageSizeInBytes(const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevelsCount, const deUint32 mipmapMemoryAlignment)
{
deUint32 imageSizeInBytes = 0;
for (deUint32 mipmapLevel = 0; mipmapLevel < mipmapLevelsCount; ++mipmapLevel)
imageSizeInBytes += getImageMipLevelSizeInBytes(baseExtents, layersCount, format, mipmapLevel, mipmapMemoryAlignment);
return imageSizeInBytes;
}
deUint32 getImageMipLevelSizeInBytes (const VkExtent3D& baseExtents, const deUint32 layersCount, const vk::PlanarFormatDescription& formatDescription, const deUint32 planeNdx, const deUint32 mipmapLevel, const deUint32 mipmapMemoryAlignment)
{
return layersCount * getPlaneSizeInBytes(formatDescription, baseExtents, planeNdx, mipmapLevel, mipmapMemoryAlignment);
}
deUint32 getImageSizeInBytes (const VkExtent3D& baseExtents, const deUint32 layersCount, const vk::PlanarFormatDescription& formatDescription, const deUint32 planeNdx, const deUint32 mipmapLevelsCount, const deUint32 mipmapMemoryAlignment)
{
deUint32 imageSizeInBytes = 0;
for (deUint32 mipmapLevel = 0; mipmapLevel < mipmapLevelsCount; ++mipmapLevel)
imageSizeInBytes += getImageMipLevelSizeInBytes(baseExtents, layersCount, formatDescription, planeNdx, mipmapLevel, mipmapMemoryAlignment);
return imageSizeInBytes;
}
VkSparseImageMemoryBind makeSparseImageMemoryBind (const DeviceInterface& vk,
const VkDevice device,
const VkDeviceSize allocationSize,
const deUint32 memoryType,
const VkImageSubresource& subresource,
const VkOffset3D& offset,
const VkExtent3D& extent)
{
const VkMemoryAllocateInfo allocInfo =
{
VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // VkStructureType sType;
DE_NULL, // const void* pNext;
allocationSize, // VkDeviceSize allocationSize;
memoryType, // deUint32 memoryTypeIndex;
};
VkDeviceMemory deviceMemory = 0;
VK_CHECK(vk.allocateMemory(device, &allocInfo, DE_NULL, &deviceMemory));
VkSparseImageMemoryBind imageMemoryBind;
imageMemoryBind.subresource = subresource;
imageMemoryBind.memory = deviceMemory;
imageMemoryBind.memoryOffset = 0u;
imageMemoryBind.flags = 0u;
imageMemoryBind.offset = offset;
imageMemoryBind.extent = extent;
return imageMemoryBind;
}
VkSparseMemoryBind makeSparseMemoryBind (const DeviceInterface& vk,
const VkDevice device,
const VkDeviceSize allocationSize,
const deUint32 memoryType,
const VkDeviceSize resourceOffset,
const VkSparseMemoryBindFlags flags)
{
const VkMemoryAllocateInfo allocInfo =
{
VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // VkStructureType sType;
DE_NULL, // const void* pNext;
allocationSize, // VkDeviceSize allocationSize;
memoryType, // deUint32 memoryTypeIndex;
};
VkDeviceMemory deviceMemory = 0;
VK_CHECK(vk.allocateMemory(device, &allocInfo, DE_NULL, &deviceMemory));
VkSparseMemoryBind memoryBind;
memoryBind.resourceOffset = resourceOffset;
memoryBind.size = allocationSize;
memoryBind.memory = deviceMemory;
memoryBind.memoryOffset = 0u;
memoryBind.flags = flags;
return memoryBind;
}
void requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags)
{
const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
throw tcu::NotSupportedError("Tessellation shader not supported");
if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
throw tcu::NotSupportedError("Geometry shader not supported");
if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
throw tcu::NotSupportedError("Double-precision floats not supported");
if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize)
throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in");
}
deUint32 findMatchingMemoryType (const InstanceInterface& instance,
const VkPhysicalDevice physicalDevice,
const VkMemoryRequirements& objectMemoryRequirements,
const MemoryRequirement& memoryRequirement)
{
const VkPhysicalDeviceMemoryProperties deviceMemoryProperties = getPhysicalDeviceMemoryProperties(instance, physicalDevice);
for (deUint32 memoryTypeNdx = 0; memoryTypeNdx < deviceMemoryProperties.memoryTypeCount; ++memoryTypeNdx)
{
if ((objectMemoryRequirements.memoryTypeBits & (1u << memoryTypeNdx)) != 0 &&
memoryRequirement.matchesHeap(deviceMemoryProperties.memoryTypes[memoryTypeNdx].propertyFlags))
{
return memoryTypeNdx;
}
}
return NO_MATCH_FOUND;
}
deUint32 getHeapIndexForMemoryType (const InstanceInterface& instance,
const VkPhysicalDevice physicalDevice,
const deUint32 memoryType)
{
const VkPhysicalDeviceMemoryProperties deviceMemoryProperties = getPhysicalDeviceMemoryProperties(instance, physicalDevice);
DE_ASSERT(memoryType < deviceMemoryProperties.memoryTypeCount);
return deviceMemoryProperties.memoryTypes[memoryType].heapIndex;
}
bool checkSparseSupportForImageType (const InstanceInterface& instance,
const VkPhysicalDevice physicalDevice,
const ImageType imageType)
{
const VkPhysicalDeviceFeatures deviceFeatures = getPhysicalDeviceFeatures(instance, physicalDevice);
if (!deviceFeatures.sparseBinding)
return false;
switch (mapImageType(imageType))
{
case VK_IMAGE_TYPE_2D:
return deviceFeatures.sparseResidencyImage2D == VK_TRUE;
case VK_IMAGE_TYPE_3D:
return deviceFeatures.sparseResidencyImage3D == VK_TRUE;
default:
DE_FATAL("Unexpected image type");
return false;
};
}
bool checkSparseSupportForImageFormat (const InstanceInterface& instance,
const VkPhysicalDevice physicalDevice,
const VkImageCreateInfo& imageInfo)
{
const std::vector<VkSparseImageFormatProperties> sparseImageFormatPropVec = getPhysicalDeviceSparseImageFormatProperties(
instance, physicalDevice, imageInfo.format, imageInfo.imageType, imageInfo.samples, imageInfo.usage, imageInfo.tiling);
return sparseImageFormatPropVec.size() > 0u;
}
bool checkImageFormatFeatureSupport (const InstanceInterface& instance,
const VkPhysicalDevice physicalDevice,
const VkFormat format,
const VkFormatFeatureFlags featureFlags)
{
const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(instance, physicalDevice, format);
return (formatProperties.optimalTilingFeatures & featureFlags) == featureFlags;
}
deUint32 getSparseAspectRequirementsIndex (const std::vector<VkSparseImageMemoryRequirements>& requirements,
const VkImageAspectFlags aspectFlags)
{
for (deUint32 memoryReqNdx = 0; memoryReqNdx < requirements.size(); ++memoryReqNdx)
{
if (requirements[memoryReqNdx].formatProperties.aspectMask & aspectFlags)
return memoryReqNdx;
}
return NO_MATCH_FOUND;
}
vk::VkFormat getPlaneCompatibleFormatForWriting(const vk::PlanarFormatDescription& formatInfo, deUint32 planeNdx)
{
DE_ASSERT(planeNdx < formatInfo.numPlanes);
vk::VkFormat result = formatInfo.planes[planeNdx].planeCompatibleFormat;
// redirect result for some of the YCbCr image formats
static const std::pair<vk::VkFormat, vk::VkFormat> ycbcrFormats[] =
{
{ VK_FORMAT_G8B8G8R8_422_UNORM_KHR, VK_FORMAT_R8G8B8A8_UNORM },
{ VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR, VK_FORMAT_R16G16B16A16_UNORM },
{ VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR, VK_FORMAT_R16G16B16A16_UNORM },
{ VK_FORMAT_G16B16G16R16_422_UNORM_KHR, VK_FORMAT_R16G16B16A16_UNORM },
{ VK_FORMAT_B8G8R8G8_422_UNORM_KHR, VK_FORMAT_R8G8B8A8_UNORM },
{ VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR, VK_FORMAT_R16G16B16A16_UNORM },
{ VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR, VK_FORMAT_R16G16B16A16_UNORM },
{ VK_FORMAT_B16G16R16G16_422_UNORM_KHR, VK_FORMAT_R16G16B16A16_UNORM }
};
auto it = std::find_if(std::begin(ycbcrFormats), std::end(ycbcrFormats), [result](const std::pair<vk::VkFormat, vk::VkFormat>& p) { return p.first == result; });
if (it != std::end(ycbcrFormats))
result = it->second;
return result;
}
bool areLsb6BitsDontCare(vk::VkFormat format)
{
if ((format == vk::VK_FORMAT_R10X6_UNORM_PACK16) ||
(format == vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16) ||
(format == vk::VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16) ||
(format == vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16) ||
(format == vk::VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16) ||
(format == vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16) ||
(format == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16) ||
(format == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16) ||
(format == vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16) ||
(format == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16))
{
return true;
}
return false;
}
bool areLsb4BitsDontCare(vk::VkFormat format)
{
if ((format == vk::VK_FORMAT_R12X4_UNORM_PACK16) ||
(format == vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16) ||
(format == vk::VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16) ||
(format == vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16) ||
(format == vk::VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16) ||
(format == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16) ||
(format == vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16) ||
(format == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16) ||
(format == vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16) ||
(format == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16))
{
return true;
}
return false;
}
} // sparse
} // vkt