Commit 2e9706d8 by Jamie Madill Committed by Commit Bot

Vulkan: Use angle::FormatID instead of VkFormat.

This change switches the internal enums we pass around from VkFormat to FormatID. The end goal of the refactor is to allow the Vulkan back-end to store packed tables indexed by FormatID. Because VkFormat has large gaps in its enum space we'd otherwise need to use unordered data structures like unordered_map. The change removes the redundant VkFormat storage from vk::Format and uses a new table query to return the VkFormat that 1:1 matches an angle::FormatID. We also include a reverse mapping for use with native Vulkan get functions for Android. Also moves sRGB conversion functions into renderer_utils. A couple sRGB formats that don't exist in GL are no longer handled by the sRGB conversion functions. These formats should be extremely rare. Bug: angleproject:5438 Change-Id: Id8b49773ca0c556f9f5a6a10fcf0d9762b93bbea Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2618204 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarIan Elliott <ianelliott@google.com>
parent d21d682d
...@@ -4,9 +4,9 @@ ...@@ -4,9 +4,9 @@
"src/libANGLE/renderer/angle_format_map.json": "src/libANGLE/renderer/angle_format_map.json":
"aa4a0d3463b76858a75787b9cdec8e98", "aa4a0d3463b76858a75787b9cdec8e98",
"src/libANGLE/renderer/vulkan/gen_vk_format_table.py": "src/libANGLE/renderer/vulkan/gen_vk_format_table.py":
"bf2279d1d8da7e3e271a352e101c8956", "0bc8a6deefd856387da0bccf3817dde7",
"src/libANGLE/renderer/vulkan/vk_format_map.json": "src/libANGLE/renderer/vulkan/vk_format_map.json":
"b62588b1e9f6d9fa98aeea886d8ed2bd", "b62588b1e9f6d9fa98aeea886d8ed2bd",
"src/libANGLE/renderer/vulkan/vk_format_table_autogen.cpp": "src/libANGLE/renderer/vulkan/vk_format_table_autogen.cpp":
"4dfb7525b4f45690091d6642e77481a3" "ff081c37d8dfabdf87f46af9bf8e295a"
} }
\ No newline at end of file
...@@ -109,12 +109,12 @@ const TextureCaps &TextureCapsMap::get(GLenum internalFormat) const ...@@ -109,12 +109,12 @@ const TextureCaps &TextureCapsMap::get(GLenum internalFormat) const
const TextureCaps &TextureCapsMap::get(angle::FormatID formatID) const const TextureCaps &TextureCapsMap::get(angle::FormatID formatID) const
{ {
return mFormatData[static_cast<size_t>(formatID)]; return mFormatData[formatID];
} }
TextureCaps &TextureCapsMap::get(angle::FormatID formatID) TextureCaps &TextureCapsMap::get(angle::FormatID formatID)
{ {
return mFormatData[static_cast<size_t>(formatID)]; return mFormatData[formatID];
} }
void TextureCapsMap::set(angle::FormatID formatID, const TextureCaps &caps) void TextureCapsMap::set(angle::FormatID formatID, const TextureCaps &caps)
......
...@@ -79,7 +79,7 @@ class TextureCapsMap final : angle::NonCopyable ...@@ -79,7 +79,7 @@ class TextureCapsMap final : angle::NonCopyable
TextureCaps &get(angle::FormatID formatID); TextureCaps &get(angle::FormatID formatID);
// Indexed by angle::FormatID // Indexed by angle::FormatID
std::array<TextureCaps, angle::kNumANGLEFormats> mFormatData; angle::FormatMap<TextureCaps> mFormatData;
}; };
void InitMinimumTextureCapsMap(const Version &clientVersion, void InitMinimumTextureCapsMap(const Version &clientVersion,
......
...@@ -226,6 +226,9 @@ constexpr bool Format::isVertexTypeHalfFloat() const ...@@ -226,6 +226,9 @@ constexpr bool Format::isVertexTypeHalfFloat() const
return vertexAttribType == gl::VertexAttribType::HalfFloat; return vertexAttribType == gl::VertexAttribType::HalfFloat;
} }
template <typename T>
using FormatMap = PackedEnumMap<FormatID, T, kNumANGLEFormats>;
} // namespace angle } // namespace angle
#endif // LIBANGLE_RENDERER_FORMAT_H_ #endif // LIBANGLE_RENDERER_FORMAT_H_
...@@ -1238,4 +1238,130 @@ ResetBaseVertexBaseInstance::~ResetBaseVertexBaseInstance() ...@@ -1238,4 +1238,130 @@ ResetBaseVertexBaseInstance::~ResetBaseVertexBaseInstance()
} }
} }
angle::FormatID ConvertToSRGB(angle::FormatID formatID)
{
switch (formatID)
{
case angle::FormatID::R8_UNORM:
return angle::FormatID::R8_UNORM_SRGB;
case angle::FormatID::R8G8B8_UNORM:
return angle::FormatID::R8G8B8_UNORM_SRGB;
case angle::FormatID::R8G8B8A8_UNORM:
return angle::FormatID::R8G8B8A8_UNORM_SRGB;
case angle::FormatID::B8G8R8A8_UNORM:
return angle::FormatID::B8G8R8A8_UNORM_SRGB;
case angle::FormatID::BC1_RGB_UNORM_BLOCK:
return angle::FormatID::BC1_RGB_UNORM_SRGB_BLOCK;
case angle::FormatID::BC1_RGBA_UNORM_BLOCK:
return angle::FormatID::BC1_RGBA_UNORM_SRGB_BLOCK;
case angle::FormatID::BC2_RGBA_UNORM_BLOCK:
return angle::FormatID::BC2_RGBA_UNORM_SRGB_BLOCK;
case angle::FormatID::BC3_RGBA_UNORM_BLOCK:
return angle::FormatID::BC3_RGBA_UNORM_SRGB_BLOCK;
case angle::FormatID::BPTC_RGBA_UNORM_BLOCK:
return angle::FormatID::BPTC_SRGB_ALPHA_UNORM_BLOCK;
case angle::FormatID::ETC2_R8G8B8_UNORM_BLOCK:
return angle::FormatID::ETC2_R8G8B8_SRGB_BLOCK;
case angle::FormatID::ETC2_R8G8B8A1_UNORM_BLOCK:
return angle::FormatID::ETC2_R8G8B8A1_SRGB_BLOCK;
case angle::FormatID::ETC2_R8G8B8A8_UNORM_BLOCK:
return angle::FormatID::ETC2_R8G8B8A8_SRGB_BLOCK;
case angle::FormatID::ASTC_4x4_UNORM_BLOCK:
return angle::FormatID::ASTC_4x4_SRGB_BLOCK;
case angle::FormatID::ASTC_5x4_UNORM_BLOCK:
return angle::FormatID::ASTC_5x4_SRGB_BLOCK;
case angle::FormatID::ASTC_5x5_UNORM_BLOCK:
return angle::FormatID::ASTC_5x5_SRGB_BLOCK;
case angle::FormatID::ASTC_6x5_UNORM_BLOCK:
return angle::FormatID::ASTC_6x5_SRGB_BLOCK;
case angle::FormatID::ASTC_6x6_UNORM_BLOCK:
return angle::FormatID::ASTC_6x6_SRGB_BLOCK;
case angle::FormatID::ASTC_8x5_UNORM_BLOCK:
return angle::FormatID::ASTC_8x5_SRGB_BLOCK;
case angle::FormatID::ASTC_8x6_UNORM_BLOCK:
return angle::FormatID::ASTC_8x6_SRGB_BLOCK;
case angle::FormatID::ASTC_8x8_UNORM_BLOCK:
return angle::FormatID::ASTC_8x8_SRGB_BLOCK;
case angle::FormatID::ASTC_10x5_UNORM_BLOCK:
return angle::FormatID::ASTC_10x5_SRGB_BLOCK;
case angle::FormatID::ASTC_10x6_UNORM_BLOCK:
return angle::FormatID::ASTC_10x6_SRGB_BLOCK;
case angle::FormatID::ASTC_10x8_UNORM_BLOCK:
return angle::FormatID::ASTC_10x8_SRGB_BLOCK;
case angle::FormatID::ASTC_10x10_UNORM_BLOCK:
return angle::FormatID::ASTC_10x10_SRGB_BLOCK;
case angle::FormatID::ASTC_12x10_UNORM_BLOCK:
return angle::FormatID::ASTC_12x10_SRGB_BLOCK;
case angle::FormatID::ASTC_12x12_UNORM_BLOCK:
return angle::FormatID::ASTC_12x12_SRGB_BLOCK;
default:
return angle::FormatID::NONE;
}
}
angle::FormatID ConvertToLinear(angle::FormatID formatID)
{
switch (formatID)
{
case angle::FormatID::R8_UNORM_SRGB:
return angle::FormatID::R8_UNORM;
case angle::FormatID::R8G8B8_UNORM_SRGB:
return angle::FormatID::R8G8B8_UNORM;
case angle::FormatID::R8G8B8A8_UNORM_SRGB:
return angle::FormatID::R8G8B8A8_UNORM;
case angle::FormatID::B8G8R8A8_UNORM_SRGB:
return angle::FormatID::B8G8R8A8_UNORM;
case angle::FormatID::BC1_RGB_UNORM_SRGB_BLOCK:
return angle::FormatID::BC1_RGB_UNORM_BLOCK;
case angle::FormatID::BC1_RGBA_UNORM_SRGB_BLOCK:
return angle::FormatID::BC1_RGBA_UNORM_BLOCK;
case angle::FormatID::BC2_RGBA_UNORM_SRGB_BLOCK:
return angle::FormatID::BC2_RGBA_UNORM_BLOCK;
case angle::FormatID::BC3_RGBA_UNORM_SRGB_BLOCK:
return angle::FormatID::BC3_RGBA_UNORM_BLOCK;
case angle::FormatID::BPTC_SRGB_ALPHA_UNORM_BLOCK:
return angle::FormatID::BPTC_RGBA_UNORM_BLOCK;
case angle::FormatID::ETC2_R8G8B8_SRGB_BLOCK:
return angle::FormatID::ETC2_R8G8B8_UNORM_BLOCK;
case angle::FormatID::ETC2_R8G8B8A1_SRGB_BLOCK:
return angle::FormatID::ETC2_R8G8B8A1_UNORM_BLOCK;
case angle::FormatID::ETC2_R8G8B8A8_SRGB_BLOCK:
return angle::FormatID::ETC2_R8G8B8A8_UNORM_BLOCK;
case angle::FormatID::ASTC_4x4_SRGB_BLOCK:
return angle::FormatID::ASTC_4x4_UNORM_BLOCK;
case angle::FormatID::ASTC_5x4_SRGB_BLOCK:
return angle::FormatID::ASTC_5x4_UNORM_BLOCK;
case angle::FormatID::ASTC_5x5_SRGB_BLOCK:
return angle::FormatID::ASTC_5x5_UNORM_BLOCK;
case angle::FormatID::ASTC_6x5_SRGB_BLOCK:
return angle::FormatID::ASTC_6x5_UNORM_BLOCK;
case angle::FormatID::ASTC_6x6_SRGB_BLOCK:
return angle::FormatID::ASTC_6x6_UNORM_BLOCK;
case angle::FormatID::ASTC_8x5_SRGB_BLOCK:
return angle::FormatID::ASTC_8x5_UNORM_BLOCK;
case angle::FormatID::ASTC_8x6_SRGB_BLOCK:
return angle::FormatID::ASTC_8x6_UNORM_BLOCK;
case angle::FormatID::ASTC_8x8_SRGB_BLOCK:
return angle::FormatID::ASTC_8x8_UNORM_BLOCK;
case angle::FormatID::ASTC_10x5_SRGB_BLOCK:
return angle::FormatID::ASTC_10x5_UNORM_BLOCK;
case angle::FormatID::ASTC_10x6_SRGB_BLOCK:
return angle::FormatID::ASTC_10x6_UNORM_BLOCK;
case angle::FormatID::ASTC_10x8_SRGB_BLOCK:
return angle::FormatID::ASTC_10x8_UNORM_BLOCK;
case angle::FormatID::ASTC_10x10_SRGB_BLOCK:
return angle::FormatID::ASTC_10x10_UNORM_BLOCK;
case angle::FormatID::ASTC_12x10_SRGB_BLOCK:
return angle::FormatID::ASTC_12x10_UNORM_BLOCK;
case angle::FormatID::ASTC_12x12_SRGB_BLOCK:
return angle::FormatID::ASTC_12x12_UNORM_BLOCK;
default:
return angle::FormatID::NONE;
}
}
bool IsOverridableLinearFormat(angle::FormatID formatID)
{
return ConvertToSRGB(formatID) != angle::FormatID::NONE;
}
} // namespace rx } // namespace rx
...@@ -417,6 +417,9 @@ class ResetBaseVertexBaseInstance : angle::NonCopyable ...@@ -417,6 +417,9 @@ class ResetBaseVertexBaseInstance : angle::NonCopyable
bool mResetBaseInstance; bool mResetBaseInstance;
}; };
angle::FormatID ConvertToSRGB(angle::FormatID formatID);
angle::FormatID ConvertToLinear(angle::FormatID formatID);
bool IsOverridableLinearFormat(angle::FormatID formatID);
} // namespace rx } // namespace rx
// MultiDraw macro patterns // MultiDraw macro patterns
......
...@@ -49,13 +49,13 @@ constexpr unsigned int kEmulatedAlphaValue = 1; ...@@ -49,13 +49,13 @@ constexpr unsigned int kEmulatedAlphaValue = 1;
bool HasSrcBlitFeature(RendererVk *renderer, RenderTargetVk *srcRenderTarget) bool HasSrcBlitFeature(RendererVk *renderer, RenderTargetVk *srcRenderTarget)
{ {
const VkFormat srcFormat = srcRenderTarget->getImageFormat().actualImageVkFormat; angle::FormatID srcFormat = srcRenderTarget->getImageFormat().actualImageFormatID;
return renderer->hasImageFormatFeatureBits(srcFormat, VK_FORMAT_FEATURE_BLIT_SRC_BIT); return renderer->hasImageFormatFeatureBits(srcFormat, VK_FORMAT_FEATURE_BLIT_SRC_BIT);
} }
bool HasDstBlitFeature(RendererVk *renderer, RenderTargetVk *dstRenderTarget) bool HasDstBlitFeature(RendererVk *renderer, RenderTargetVk *dstRenderTarget)
{ {
const VkFormat dstFormat = dstRenderTarget->getImageFormat().actualImageVkFormat; angle::FormatID dstFormat = dstRenderTarget->getImageFormat().actualImageFormatID;
return renderer->hasImageFormatFeatureBits(dstFormat, VK_FORMAT_FEATURE_BLIT_DST_BIT); return renderer->hasImageFormatFeatureBits(dstFormat, VK_FORMAT_FEATURE_BLIT_DST_BIT);
} }
...@@ -87,7 +87,7 @@ bool AreSrcAndDstFormatsIdentical(RenderTargetVk *srcRenderTarget, RenderTargetV ...@@ -87,7 +87,7 @@ bool AreSrcAndDstFormatsIdentical(RenderTargetVk *srcRenderTarget, RenderTargetV
const vk::Format &srcFormat = srcRenderTarget->getImageFormat(); const vk::Format &srcFormat = srcRenderTarget->getImageFormat();
const vk::Format &dstFormat = dstRenderTarget->getImageFormat(); const vk::Format &dstFormat = dstRenderTarget->getImageFormat();
return srcFormat.actualImageVkFormat == dstFormat.actualImageVkFormat; return srcFormat.actualImageFormatID == dstFormat.actualImageFormatID;
} }
bool AreSrcAndDstDepthStencilChannelsBlitCompatible(RenderTargetVk *srcRenderTarget, bool AreSrcAndDstDepthStencilChannelsBlitCompatible(RenderTargetVk *srcRenderTarget,
......
...@@ -178,7 +178,7 @@ angle::Result MemoryObjectVk::createImage(ContextVk *contextVk, ...@@ -178,7 +178,7 @@ angle::Result MemoryObjectVk::createImage(ContextVk *contextVk,
// values constituting the bits of |usageFlags| are identical to their corresponding Vulkan // values constituting the bits of |usageFlags| are identical to their corresponding Vulkan
// value. // value.
const VkImageUsageFlags imageUsageFlags = const VkImageUsageFlags imageUsageFlags =
vk::GetMaximalImageUsageFlags(renderer, vkFormat.actualImageVkFormat) & usageFlags; vk::GetMaximalImageUsageFlags(renderer, vkFormat.actualImageFormatID) & usageFlags;
VkExternalMemoryImageCreateInfo externalMemoryImageCreateInfo = {}; VkExternalMemoryImageCreateInfo externalMemoryImageCreateInfo = {};
externalMemoryImageCreateInfo.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO; externalMemoryImageCreateInfo.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO;
......
...@@ -217,7 +217,7 @@ angle::Result OverlayVk::onPresent(ContextVk *contextVk, ...@@ -217,7 +217,7 @@ angle::Result OverlayVk::onPresent(ContextVk *contextVk,
// If the swapchain image doesn't support storage image, we can't output to it. // If the swapchain image doesn't support storage image, we can't output to it.
VkFormatFeatureFlags featureBits = renderer->getImageFormatFeatureBits( VkFormatFeatureFlags featureBits = renderer->getImageFormatFeatureBits(
imageToPresent->getFormat().actualImageVkFormat, VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT); imageToPresent->getFormat().actualImageFormatID, VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT);
if ((featureBits & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) == 0) if ((featureBits & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) == 0)
{ {
return angle::Result::Continue; return angle::Result::Continue;
......
...@@ -45,9 +45,9 @@ angle::Result RenderbufferVk::setStorageImpl(const gl::Context *context, ...@@ -45,9 +45,9 @@ angle::Result RenderbufferVk::setStorageImpl(const gl::Context *context,
GLsizei height, GLsizei height,
gl::MultisamplingMode mode) gl::MultisamplingMode mode)
{ {
ContextVk *contextVk = vk::GetImpl(context); ContextVk *contextVk = vk::GetImpl(context);
RendererVk *renderer = contextVk->getRenderer(); RendererVk *renderer = contextVk->getRenderer();
const vk::Format &vkFormat = renderer->getFormat(internalformat); const vk::Format &format = renderer->getFormat(internalformat);
if (!mOwnsImage) if (!mOwnsImage)
{ {
...@@ -82,10 +82,11 @@ angle::Result RenderbufferVk::setStorageImpl(const gl::Context *context, ...@@ -82,10 +82,11 @@ angle::Result RenderbufferVk::setStorageImpl(const gl::Context *context,
// causing it to be interpreted in a different colorspace. Create the VkImage accordingly. // causing it to be interpreted in a different colorspace. Create the VkImage accordingly.
VkImageCreateFlags imageCreateFlags = vk::kVkImageCreateFlagsNone; VkImageCreateFlags imageCreateFlags = vk::kVkImageCreateFlagsNone;
VkImageFormatListCreateInfoKHR *additionalCreateInfo = nullptr; VkImageFormatListCreateInfoKHR *additionalCreateInfo = nullptr;
VkFormat vkImageFormat = vkFormat.actualImageVkFormat; angle::FormatID imageFormat = format.actualImageFormatID;
VkFormat vkImageListFormat = vkFormat.actualImageFormat().isSRGB angle::FormatID imageListFormat = format.actualImageFormat().isSRGB
? vk::ConvertToLinear(vkImageFormat) ? ConvertToLinear(imageFormat)
: vk::ConvertToSRGB(vkImageFormat); : ConvertToSRGB(imageFormat);
VkFormat vkFormat = vk::GetVkFormatFromFormatID(imageListFormat);
VkImageFormatListCreateInfoKHR formatListInfo = {}; VkImageFormatListCreateInfoKHR formatListInfo = {};
if (renderer->getFeatures().supportsImageFormatList.enabled) if (renderer->getFeatures().supportsImageFormatList.enabled)
...@@ -97,11 +98,11 @@ angle::Result RenderbufferVk::setStorageImpl(const gl::Context *context, ...@@ -97,11 +98,11 @@ angle::Result RenderbufferVk::setStorageImpl(const gl::Context *context,
formatListInfo.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR; formatListInfo.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR;
formatListInfo.pNext = nullptr; formatListInfo.pNext = nullptr;
formatListInfo.viewFormatCount = 1; formatListInfo.viewFormatCount = 1;
formatListInfo.pViewFormats = &vkImageListFormat; formatListInfo.pViewFormats = &vkFormat;
additionalCreateInfo = &formatListInfo; additionalCreateInfo = &formatListInfo;
} }
const angle::Format &textureFormat = vkFormat.actualImageFormat(); const angle::Format &textureFormat = format.actualImageFormat();
const bool isDepthStencilFormat = textureFormat.hasDepthOrStencilBits(); const bool isDepthStencilFormat = textureFormat.hasDepthOrStencilBits();
ASSERT(textureFormat.redBits > 0 || isDepthStencilFormat); ASSERT(textureFormat.redBits > 0 || isDepthStencilFormat);
...@@ -124,7 +125,7 @@ angle::Result RenderbufferVk::setStorageImpl(const gl::Context *context, ...@@ -124,7 +125,7 @@ angle::Result RenderbufferVk::setStorageImpl(const gl::Context *context,
bool robustInit = contextVk->isRobustResourceInitEnabled(); bool robustInit = contextVk->isRobustResourceInitEnabled();
VkExtent3D extents = {static_cast<uint32_t>(width), static_cast<uint32_t>(height), 1u}; VkExtent3D extents = {static_cast<uint32_t>(width), static_cast<uint32_t>(height), 1u};
ANGLE_TRY(mImage->initExternal(contextVk, gl::TextureType::_2D, extents, vkFormat, imageSamples, ANGLE_TRY(mImage->initExternal(contextVk, gl::TextureType::_2D, extents, format, imageSamples,
usage, imageCreateFlags, vk::ImageLayout::Undefined, usage, imageCreateFlags, vk::ImageLayout::Undefined,
additionalCreateInfo, gl::LevelIndex(0), gl::LevelIndex(0), 1, 1, additionalCreateInfo, gl::LevelIndex(0), gl::LevelIndex(0), 1, 1,
robustInit)); robustInit));
......
...@@ -2244,36 +2244,36 @@ Serial RendererVk::issueShaderSerial() ...@@ -2244,36 +2244,36 @@ Serial RendererVk::issueShaderSerial()
// These functions look at the mandatory format for support, and fallback to querying the device (if // These functions look at the mandatory format for support, and fallback to querying the device (if
// necessary) to test the availability of the bits. // necessary) to test the availability of the bits.
bool RendererVk::hasLinearImageFormatFeatureBits(VkFormat format, bool RendererVk::hasLinearImageFormatFeatureBits(angle::FormatID formatID,
const VkFormatFeatureFlags featureBits) const const VkFormatFeatureFlags featureBits) const
{ {
return hasFormatFeatureBits<&VkFormatProperties::linearTilingFeatures>(format, featureBits); return hasFormatFeatureBits<&VkFormatProperties::linearTilingFeatures>(formatID, featureBits);
} }
VkFormatFeatureFlags RendererVk::getLinearImageFormatFeatureBits( VkFormatFeatureFlags RendererVk::getLinearImageFormatFeatureBits(
VkFormat format, angle::FormatID formatID,
const VkFormatFeatureFlags featureBits) const const VkFormatFeatureFlags featureBits) const
{ {
return getFormatFeatureBits<&VkFormatProperties::linearTilingFeatures>(format, featureBits); return getFormatFeatureBits<&VkFormatProperties::linearTilingFeatures>(formatID, featureBits);
} }
VkFormatFeatureFlags RendererVk::getImageFormatFeatureBits( VkFormatFeatureFlags RendererVk::getImageFormatFeatureBits(
VkFormat format, angle::FormatID formatID,
const VkFormatFeatureFlags featureBits) const const VkFormatFeatureFlags featureBits) const
{ {
return getFormatFeatureBits<&VkFormatProperties::optimalTilingFeatures>(format, featureBits); return getFormatFeatureBits<&VkFormatProperties::optimalTilingFeatures>(formatID, featureBits);
} }
bool RendererVk::hasImageFormatFeatureBits(VkFormat format, bool RendererVk::hasImageFormatFeatureBits(angle::FormatID formatID,
const VkFormatFeatureFlags featureBits) const const VkFormatFeatureFlags featureBits) const
{ {
return hasFormatFeatureBits<&VkFormatProperties::optimalTilingFeatures>(format, featureBits); return hasFormatFeatureBits<&VkFormatProperties::optimalTilingFeatures>(formatID, featureBits);
} }
bool RendererVk::hasBufferFormatFeatureBits(VkFormat format, bool RendererVk::hasBufferFormatFeatureBits(angle::FormatID formatID,
const VkFormatFeatureFlags featureBits) const const VkFormatFeatureFlags featureBits) const
{ {
return hasFormatFeatureBits<&VkFormatProperties::bufferFeatures>(format, featureBits); return hasFormatFeatureBits<&VkFormatProperties::bufferFeatures>(formatID, featureBits);
} }
void RendererVk::outputVmaStatString() void RendererVk::outputVmaStatString()
...@@ -2323,27 +2323,28 @@ angle::Result RendererVk::queueSubmitOneOff(vk::Context *context, ...@@ -2323,27 +2323,28 @@ angle::Result RendererVk::queueSubmitOneOff(vk::Context *context,
} }
template <VkFormatFeatureFlags VkFormatProperties::*features> template <VkFormatFeatureFlags VkFormatProperties::*features>
VkFormatFeatureFlags RendererVk::getFormatFeatureBits(VkFormat format, VkFormatFeatureFlags RendererVk::getFormatFeatureBits(angle::FormatID formatID,
const VkFormatFeatureFlags featureBits) const const VkFormatFeatureFlags featureBits) const
{ {
ASSERT(static_cast<uint32_t>(format) < vk::kNumVkFormats); VkFormatProperties &deviceProperties = mFormatProperties[formatID];
VkFormatProperties &deviceProperties = mFormatProperties[format];
if (deviceProperties.bufferFeatures == kInvalidFormatFeatureFlags) if (deviceProperties.bufferFeatures == kInvalidFormatFeatureFlags)
{ {
VkFormat vkFormat = vk::GetVkFormatFromFormatID(formatID);
// If we don't have the actual device features, see if the requested features are mandatory. // If we don't have the actual device features, see if the requested features are mandatory.
// If so, there's no need to query the device. // If so, there's no need to query the device.
const VkFormatProperties &mandatoryProperties = vk::GetMandatoryFormatSupport(format); const VkFormatProperties &mandatoryProperties = vk::GetMandatoryFormatSupport(vkFormat);
if (IsMaskFlagSet(mandatoryProperties.*features, featureBits)) if (IsMaskFlagSet(mandatoryProperties.*features, featureBits))
{ {
return featureBits; return featureBits;
} }
// Otherwise query the format features and cache it. // Otherwise query the format features and cache it.
vkGetPhysicalDeviceFormatProperties(mPhysicalDevice, format, &deviceProperties); vkGetPhysicalDeviceFormatProperties(mPhysicalDevice, vkFormat, &deviceProperties);
// Workaround for some Android devices that don't indicate filtering // Workaround for some Android devices that don't indicate filtering
// support on D16_UNORM and they should. // support on D16_UNORM and they should.
if (mFeatures.forceD16TexFilter.enabled && format == VK_FORMAT_D16_UNORM) if (mFeatures.forceD16TexFilter.enabled && vkFormat == VK_FORMAT_D16_UNORM)
{ {
deviceProperties.*features |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT; deviceProperties.*features |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
} }
...@@ -2353,14 +2354,16 @@ VkFormatFeatureFlags RendererVk::getFormatFeatureBits(VkFormat format, ...@@ -2353,14 +2354,16 @@ VkFormatFeatureFlags RendererVk::getFormatFeatureBits(VkFormat format,
} }
template <VkFormatFeatureFlags VkFormatProperties::*features> template <VkFormatFeatureFlags VkFormatProperties::*features>
bool RendererVk::hasFormatFeatureBits(VkFormat format, const VkFormatFeatureFlags featureBits) const bool RendererVk::hasFormatFeatureBits(angle::FormatID formatID,
const VkFormatFeatureFlags featureBits) const
{ {
return IsMaskFlagSet(getFormatFeatureBits<features>(format, featureBits), featureBits); return IsMaskFlagSet(getFormatFeatureBits<features>(formatID, featureBits), featureBits);
} }
bool RendererVk::haveSameFormatFeatureBits(VkFormat fmt1, VkFormat fmt2) const bool RendererVk::haveSameFormatFeatureBits(angle::FormatID formatID1,
angle::FormatID formatID2) const
{ {
if (fmt1 == VK_FORMAT_UNDEFINED || fmt2 == VK_FORMAT_UNDEFINED) if (formatID1 == angle::FormatID::NONE || formatID2 == angle::FormatID::NONE)
{ {
return false; return false;
} }
...@@ -2370,12 +2373,12 @@ bool RendererVk::haveSameFormatFeatureBits(VkFormat fmt1, VkFormat fmt2) const ...@@ -2370,12 +2373,12 @@ bool RendererVk::haveSameFormatFeatureBits(VkFormat fmt1, VkFormat fmt2) const
VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT; VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
VkFormatFeatureFlags fmt1LinearFeatureBits = VkFormatFeatureFlags fmt1LinearFeatureBits =
getLinearImageFormatFeatureBits(fmt1, kImageUsageFeatureBits); getLinearImageFormatFeatureBits(formatID1, kImageUsageFeatureBits);
VkFormatFeatureFlags fmt1OptimalFeatureBits = VkFormatFeatureFlags fmt1OptimalFeatureBits =
getImageFormatFeatureBits(fmt1, kImageUsageFeatureBits); getImageFormatFeatureBits(formatID1, kImageUsageFeatureBits);
return hasLinearImageFormatFeatureBits(fmt2, fmt1LinearFeatureBits) && return hasLinearImageFormatFeatureBits(formatID2, fmt1LinearFeatureBits) &&
hasImageFormatFeatureBits(fmt2, fmt1OptimalFeatureBits); hasImageFormatFeatureBits(formatID2, fmt1OptimalFeatureBits);
} }
angle::Result RendererVk::cleanupGarbage(Serial lastCompletedQueueSerial) angle::Result RendererVk::cleanupGarbage(Serial lastCompletedQueueSerial)
......
...@@ -184,15 +184,17 @@ class RendererVk : angle::NonCopyable ...@@ -184,15 +184,17 @@ class RendererVk : angle::NonCopyable
// Query the format properties for select bits (linearTilingFeatures, optimalTilingFeatures and // Query the format properties for select bits (linearTilingFeatures, optimalTilingFeatures and
// bufferFeatures). Looks through mandatory features first, and falls back to querying the // bufferFeatures). Looks through mandatory features first, and falls back to querying the
// device (first time only). // device (first time only).
bool hasLinearImageFormatFeatureBits(VkFormat format, bool hasLinearImageFormatFeatureBits(angle::FormatID format,
const VkFormatFeatureFlags featureBits) const; const VkFormatFeatureFlags featureBits) const;
VkFormatFeatureFlags getLinearImageFormatFeatureBits( VkFormatFeatureFlags getLinearImageFormatFeatureBits(
VkFormat format, angle::FormatID format,
const VkFormatFeatureFlags featureBits) const; const VkFormatFeatureFlags featureBits) const;
VkFormatFeatureFlags getImageFormatFeatureBits(VkFormat format, VkFormatFeatureFlags getImageFormatFeatureBits(angle::FormatID format,
const VkFormatFeatureFlags featureBits) const; const VkFormatFeatureFlags featureBits) const;
bool hasImageFormatFeatureBits(VkFormat format, const VkFormatFeatureFlags featureBits) const; bool hasImageFormatFeatureBits(angle::FormatID format,
bool hasBufferFormatFeatureBits(VkFormat format, const VkFormatFeatureFlags featureBits) const; const VkFormatFeatureFlags featureBits) const;
bool hasBufferFormatFeatureBits(angle::FormatID format,
const VkFormatFeatureFlags featureBits) const;
ANGLE_INLINE egl::ContextPriority getDriverPriority(egl::ContextPriority priority) ANGLE_INLINE egl::ContextPriority getDriverPriority(egl::ContextPriority priority)
{ {
...@@ -323,7 +325,7 @@ class RendererVk : angle::NonCopyable ...@@ -323,7 +325,7 @@ class RendererVk : angle::NonCopyable
void outputVmaStatString(); void outputVmaStatString();
bool haveSameFormatFeatureBits(VkFormat fmt1, VkFormat fmt2) const; bool haveSameFormatFeatureBits(angle::FormatID formatID1, angle::FormatID formatID2) const;
angle::Result cleanupGarbage(Serial lastCompletedQueueSerial); angle::Result cleanupGarbage(Serial lastCompletedQueueSerial);
...@@ -386,11 +388,12 @@ class RendererVk : angle::NonCopyable ...@@ -386,11 +388,12 @@ class RendererVk : angle::NonCopyable
bool *success); bool *success);
template <VkFormatFeatureFlags VkFormatProperties::*features> template <VkFormatFeatureFlags VkFormatProperties::*features>
VkFormatFeatureFlags getFormatFeatureBits(VkFormat format, VkFormatFeatureFlags getFormatFeatureBits(angle::FormatID formatID,
const VkFormatFeatureFlags featureBits) const; const VkFormatFeatureFlags featureBits) const;
template <VkFormatFeatureFlags VkFormatProperties::*features> template <VkFormatFeatureFlags VkFormatProperties::*features>
bool hasFormatFeatureBits(VkFormat format, const VkFormatFeatureFlags featureBits) const; bool hasFormatFeatureBits(angle::FormatID formatID,
const VkFormatFeatureFlags featureBits) const;
egl::Display *mDisplay; egl::Display *mDisplay;
...@@ -453,7 +456,7 @@ class RendererVk : angle::NonCopyable ...@@ -453,7 +456,7 @@ class RendererVk : angle::NonCopyable
bool mPipelineCacheInitialized; bool mPipelineCacheInitialized;
// A cache of VkFormatProperties as queried from the device over time. // A cache of VkFormatProperties as queried from the device over time.
mutable std::array<VkFormatProperties, vk::kNumVkFormats> mFormatProperties; mutable angle::FormatMap<VkFormatProperties> mFormatProperties;
// Latest validation data for debug overlay. // Latest validation data for debug overlay.
std::string mLastValidationMessage; std::string mLastValidationMessage;
......
...@@ -136,10 +136,11 @@ angle::Result InitImageHelper(DisplayVk *displayVk, ...@@ -136,10 +136,11 @@ angle::Result InitImageHelper(DisplayVk *displayVk,
// causing it to be interpreted in a different colorspace. Create the VkImage accordingly. // causing it to be interpreted in a different colorspace. Create the VkImage accordingly.
VkImageCreateFlags imageCreateFlags = vk::kVkImageCreateFlagsNone; VkImageCreateFlags imageCreateFlags = vk::kVkImageCreateFlagsNone;
VkImageFormatListCreateInfoKHR *additionalCreateInfo = nullptr; VkImageFormatListCreateInfoKHR *additionalCreateInfo = nullptr;
VkFormat vkImageFormat = vkFormat.actualImageVkFormat; angle::FormatID imageFormat = vkFormat.actualImageFormatID;
VkFormat vkImageListFormat = vkFormat.actualImageFormat().isSRGB angle::FormatID imageListFormat = vkFormat.actualImageFormat().isSRGB
? vk::ConvertToLinear(vkImageFormat) ? ConvertToLinear(imageFormat)
: vk::ConvertToSRGB(vkImageFormat); : ConvertToSRGB(imageFormat);
VkFormat imageListVkFormat = vk::GetVkFormatFromFormatID(imageListFormat);
VkImageFormatListCreateInfoKHR formatListInfo = {}; VkImageFormatListCreateInfoKHR formatListInfo = {};
if (renderer->getFeatures().supportsImageFormatList.enabled) if (renderer->getFeatures().supportsImageFormatList.enabled)
...@@ -151,7 +152,7 @@ angle::Result InitImageHelper(DisplayVk *displayVk, ...@@ -151,7 +152,7 @@ angle::Result InitImageHelper(DisplayVk *displayVk,
formatListInfo.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR; formatListInfo.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR;
formatListInfo.pNext = nullptr; formatListInfo.pNext = nullptr;
formatListInfo.viewFormatCount = 1; formatListInfo.viewFormatCount = 1;
formatListInfo.pViewFormats = &vkImageListFormat; formatListInfo.pViewFormats = &imageListVkFormat;
additionalCreateInfo = &formatListInfo; additionalCreateInfo = &formatListInfo;
} }
...@@ -680,7 +681,7 @@ angle::Result WindowSurfaceVk::initializeImpl(DisplayVk *displayVk) ...@@ -680,7 +681,7 @@ angle::Result WindowSurfaceVk::initializeImpl(DisplayVk *displayVk)
surfaceFormats.data())); surfaceFormats.data()));
const vk::Format &format = renderer->getFormat(mState.config->renderTargetFormat); const vk::Format &format = renderer->getFormat(mState.config->renderTargetFormat);
VkFormat nativeFormat = format.actualImageVkFormat; VkFormat nativeFormat = format.actualImageVkFormat();
if (surfaceFormatCount == 1u && surfaceFormats[0].format == VK_FORMAT_UNDEFINED) if (surfaceFormatCount == 1u && surfaceFormats[0].format == VK_FORMAT_UNDEFINED)
{ {
...@@ -929,7 +930,7 @@ angle::Result WindowSurfaceVk::createSwapChain(vk::Context *context, ...@@ -929,7 +930,7 @@ angle::Result WindowSurfaceVk::createSwapChain(vk::Context *context,
VkDevice device = renderer->getDevice(); VkDevice device = renderer->getDevice();
const vk::Format &format = renderer->getFormat(mState.config->renderTargetFormat); const vk::Format &format = renderer->getFormat(mState.config->renderTargetFormat);
VkFormat nativeFormat = format.actualImageVkFormat; VkFormat nativeFormat = format.actualImageVkFormat();
gl::Extents rotatedExtents = extents; gl::Extents rotatedExtents = extents;
if (Is90DegreeRotation(getPreTransform())) if (Is90DegreeRotation(getPreTransform()))
......
...@@ -152,10 +152,10 @@ bool CanCopyWithDraw(RendererVk *renderer, ...@@ -152,10 +152,10 @@ bool CanCopyWithDraw(RendererVk *renderer,
{ {
// Checks that the formats in copy by drawing have the appropriate feature bits // Checks that the formats in copy by drawing have the appropriate feature bits
bool srcFormatHasNecessaryFeature = bool srcFormatHasNecessaryFeature =
vk::FormatHasNecessaryFeature(renderer, srcFormat.actualImageVkFormat, srcTilingMode, vk::FormatHasNecessaryFeature(renderer, srcFormat.actualImageFormatID, srcTilingMode,
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT); VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT);
bool dstFormatHasNecessaryFeature = bool dstFormatHasNecessaryFeature =
vk::FormatHasNecessaryFeature(renderer, destFormat.actualImageVkFormat, destTilingMode, vk::FormatHasNecessaryFeature(renderer, destFormat.actualImageFormatID, destTilingMode,
VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT); VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);
return srcFormatHasNecessaryFeature && dstFormatHasNecessaryFeature; return srcFormatHasNecessaryFeature && dstFormatHasNecessaryFeature;
...@@ -180,7 +180,7 @@ bool CanGenerateMipmapWithCompute(RendererVk *renderer, ...@@ -180,7 +180,7 @@ bool CanGenerateMipmapWithCompute(RendererVk *renderer,
// Format must have STORAGE support. // Format must have STORAGE support.
const bool hasStorageSupport = renderer->hasImageFormatFeatureBits( const bool hasStorageSupport = renderer->hasImageFormatFeatureBits(
format.actualImageVkFormat, VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT); format.actualImageFormatID, VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT);
// No support for sRGB formats yet. // No support for sRGB formats yet.
const bool isSRGB = angleFormat.isSRGB; const bool isSRGB = angleFormat.isSRGB;
...@@ -1436,13 +1436,13 @@ void TextureVk::initImageUsageFlags(ContextVk *contextVk, const vk::Format &form ...@@ -1436,13 +1436,13 @@ void TextureVk::initImageUsageFlags(ContextVk *contextVk, const vk::Format &form
{ {
// Work around a bug in the Mock ICD: // Work around a bug in the Mock ICD:
// https://github.com/KhronosGroup/Vulkan-Tools/issues/445 // https://github.com/KhronosGroup/Vulkan-Tools/issues/445
if (renderer->hasImageFormatFeatureBits(format.actualImageVkFormat, if (renderer->hasImageFormatFeatureBits(format.actualImageFormatID,
VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
{ {
mImageUsageFlags |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; mImageUsageFlags |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
} }
} }
else if (renderer->hasImageFormatFeatureBits(format.actualImageVkFormat, else if (renderer->hasImageFormatFeatureBits(format.actualImageFormatID,
VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
{ {
mImageUsageFlags |= mImageUsageFlags |=
...@@ -1859,7 +1859,7 @@ angle::Result TextureVk::generateMipmap(const gl::Context *context) ...@@ -1859,7 +1859,7 @@ angle::Result TextureVk::generateMipmap(const gl::Context *context)
return generateMipmapsWithCompute(contextVk); return generateMipmapsWithCompute(contextVk);
} }
else if (renderer->hasImageFormatFeatureBits(mImage->getFormat().actualImageVkFormat, else if (renderer->hasImageFormatFeatureBits(mImage->getFormat().actualImageFormatID,
kBlitFeatureFlags)) kBlitFeatureFlags))
{ {
// Otherwise, use blit if possible. // Otherwise, use blit if possible.
...@@ -2484,7 +2484,7 @@ bool TextureVk::shouldDecodeSRGB(ContextVk *contextVk, ...@@ -2484,7 +2484,7 @@ bool TextureVk::shouldDecodeSRGB(ContextVk *contextVk,
bool decodeSRGB = format.actualImageFormat().isSRGB; bool decodeSRGB = format.actualImageFormat().isSRGB;
// If the SRGB override is enabled, we also decode SRGB. // If the SRGB override is enabled, we also decode SRGB.
if (isSRGBOverrideEnabled() && vk::IsOverridableLinearFormat(format.actualImageVkFormat)) if (isSRGBOverrideEnabled() && IsOverridableLinearFormat(format.actualImageFormatID))
{ {
decodeSRGB = true; decodeSRGB = true;
} }
...@@ -2558,7 +2558,7 @@ const vk::ImageView &TextureVk::getCopyImageViewAndRecordUse(ContextVk *contextV ...@@ -2558,7 +2558,7 @@ const vk::ImageView &TextureVk::getCopyImageViewAndRecordUse(ContextVk *contextV
imageViews.retain(&contextVk->getResourceUseList()); imageViews.retain(&contextVk->getResourceUseList());
ASSERT(mImage->getFormat().actualImageFormat().isSRGB == ASSERT(mImage->getFormat().actualImageFormat().isSRGB ==
(vk::ConvertToLinear(mImage->getFormat().actualImageVkFormat) != VK_FORMAT_UNDEFINED)); (ConvertToLinear(mImage->getFormat().actualImageFormatID) != angle::FormatID::NONE));
if (mImage->getFormat().actualImageFormat().isSRGB) if (mImage->getFormat().actualImageFormat().isSRGB)
{ {
return imageViews.getSRGBCopyImageView(); return imageViews.getSRGBCopyImageView();
...@@ -2598,7 +2598,7 @@ angle::Result TextureVk::getStorageImageView(ContextVk *contextVk, ...@@ -2598,7 +2598,7 @@ angle::Result TextureVk::getStorageImageView(ContextVk *contextVk,
return getImageViews().getLevelLayerStorageImageView( return getImageViews().getLevelLayerStorageImageView(
contextVk, *mImage, nativeLevelVk, nativeLayer, contextVk, *mImage, nativeLevelVk, nativeLayer,
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, format.actualImageVkFormat, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, format.actualImageFormatID,
imageViewOut); imageViewOut);
} }
...@@ -2606,7 +2606,7 @@ angle::Result TextureVk::getStorageImageView(ContextVk *contextVk, ...@@ -2606,7 +2606,7 @@ angle::Result TextureVk::getStorageImageView(ContextVk *contextVk,
return getImageViews().getLevelStorageImageView( return getImageViews().getLevelStorageImageView(
contextVk, mState.getType(), *mImage, nativeLevelVk, nativeLayer, contextVk, mState.getType(), *mImage, nativeLevelVk, nativeLayer,
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, format.actualImageVkFormat, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, format.actualImageFormatID,
imageViewOut); imageViewOut);
} }
...@@ -2648,13 +2648,15 @@ angle::Result TextureVk::initImage(ContextVk *contextVk, ...@@ -2648,13 +2648,15 @@ angle::Result TextureVk::initImage(ContextVk *contextVk,
// With the introduction of sRGB related GLES extensions any texture could be respecified // With the introduction of sRGB related GLES extensions any texture could be respecified
// causing it to be interpreted in a different colorspace. Create the VkImage accordingly. // causing it to be interpreted in a different colorspace. Create the VkImage accordingly.
VkImageFormatListCreateInfoKHR *additionalCreateInfo = nullptr; VkImageFormatListCreateInfoKHR *additionalCreateInfo = nullptr;
VkFormat imageFormat = format.actualImageVkFormat; angle::FormatID imageFormat = format.actualImageFormatID;
VkFormat imageListFormat = format.actualImageFormat().isSRGB ? vk::ConvertToLinear(imageFormat) angle::FormatID imageListFormat = format.actualImageFormat().isSRGB
: vk::ConvertToSRGB(imageFormat); ? ConvertToLinear(imageFormat)
: ConvertToSRGB(imageFormat);
VkFormat vkFormat = vk::GetVkFormatFromFormatID(imageListFormat);
VkImageFormatListCreateInfoKHR formatListInfo = {}; VkImageFormatListCreateInfoKHR formatListInfo = {};
if (renderer->getFeatures().supportsImageFormatList.enabled && if (renderer->getFeatures().supportsImageFormatList.enabled &&
renderer->haveSameFormatFeatureBits(imageFormat, imageListFormat)) renderer->haveSameFormatFeatureBits(format.actualImageFormatID, imageListFormat))
{ {
mRequiresMutableStorage = true; mRequiresMutableStorage = true;
...@@ -2665,7 +2667,7 @@ angle::Result TextureVk::initImage(ContextVk *contextVk, ...@@ -2665,7 +2667,7 @@ angle::Result TextureVk::initImage(ContextVk *contextVk,
formatListInfo.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR; formatListInfo.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR;
formatListInfo.pNext = nullptr; formatListInfo.pNext = nullptr;
formatListInfo.viewFormatCount = 1; formatListInfo.viewFormatCount = 1;
formatListInfo.pViewFormats = &imageListFormat; formatListInfo.pViewFormats = &vkFormat;
additionalCreateInfo = &formatListInfo; additionalCreateInfo = &formatListInfo;
} }
......
...@@ -82,10 +82,14 @@ egl::Error HardwareBufferImageSiblingVkAndroid::ValidateHardwareBuffer(RendererV ...@@ -82,10 +82,14 @@ egl::Error HardwareBufferImageSiblingVkAndroid::ValidateHardwareBuffer(RendererV
<< bufferFormatProperties.externalFormat << " is unsupported "; << bufferFormatProperties.externalFormat << " is unsupported ";
} }
} }
else if (!HasFullTextureFormatSupport(renderer, bufferFormatProperties.format)) else
{ {
return egl::EglBadParameter() angle::FormatID formatID = vk::GetFormatIDFromVkFormat(bufferFormatProperties.format);
<< "AHardwareBuffer format does not support enough features to use as a texture."; if (!HasFullTextureFormatSupport(renderer, formatID))
{
return egl::EglBadParameter() << "AHardwareBuffer format does not support enough "
"features to use as a texture.";
}
} }
return egl::NoError(); return egl::NoError();
...@@ -199,10 +203,11 @@ angle::Result HardwareBufferImageSiblingVkAndroid::initImpl(DisplayVk *displayVk ...@@ -199,10 +203,11 @@ angle::Result HardwareBufferImageSiblingVkAndroid::initImpl(DisplayVk *displayVk
// With the introduction of sRGB related GLES extensions any texture could be respecified // With the introduction of sRGB related GLES extensions any texture could be respecified
// causing it to be interpreted in a different colorspace. Create the VkImage accordingly. // causing it to be interpreted in a different colorspace. Create the VkImage accordingly.
VkImageCreateFlags imageCreateFlags = vk::kVkImageCreateFlagsNone; VkImageCreateFlags imageCreateFlags = vk::kVkImageCreateFlagsNone;
VkFormat vkImageFormat = vkFormat.actualImageVkFormat; angle::FormatID imageFormatID = vkFormat.actualImageFormatID;
VkFormat vkImageListFormat = vkFormat.actualImageFormat().isSRGB angle::FormatID imageListFormatID = vkFormat.actualImageFormat().isSRGB
? vk::ConvertToLinear(vkImageFormat) ? ConvertToLinear(imageFormatID)
: vk::ConvertToSRGB(vkImageFormat); : ConvertToSRGB(imageFormatID);
VkFormat imageListVkFormat = vk::GetVkFormatFromFormatID(imageListFormatID);
VkImageFormatListCreateInfoKHR formatListInfo = {}; VkImageFormatListCreateInfoKHR formatListInfo = {};
if (renderer->getFeatures().supportsImageFormatList.enabled) if (renderer->getFeatures().supportsImageFormatList.enabled)
...@@ -213,7 +218,7 @@ angle::Result HardwareBufferImageSiblingVkAndroid::initImpl(DisplayVk *displayVk ...@@ -213,7 +218,7 @@ angle::Result HardwareBufferImageSiblingVkAndroid::initImpl(DisplayVk *displayVk
// There is just 1 additional format we might use to create a VkImageView for this VkImage // There is just 1 additional format we might use to create a VkImageView for this VkImage
formatListInfo.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR; formatListInfo.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR;
formatListInfo.viewFormatCount = 1; formatListInfo.viewFormatCount = 1;
formatListInfo.pViewFormats = &vkImageListFormat; formatListInfo.pViewFormats = &imageListVkFormat;
externalFormat.pNext = &formatListInfo; externalFormat.pNext = &formatListInfo;
} }
...@@ -290,15 +295,15 @@ angle::Result HardwareBufferImageSiblingVkAndroid::initImpl(DisplayVk *displayVk ...@@ -290,15 +295,15 @@ angle::Result HardwareBufferImageSiblingVkAndroid::initImpl(DisplayVk *displayVk
constexpr uint32_t kColorRenderableRequiredBits = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT; constexpr uint32_t kColorRenderableRequiredBits = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
constexpr uint32_t kDepthStencilRenderableRequiredBits = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT; constexpr uint32_t kDepthStencilRenderableRequiredBits = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
mRenderable = renderer->hasImageFormatFeatureBits(vkFormat.actualImageVkFormat, mRenderable = renderer->hasImageFormatFeatureBits(vkFormat.actualImageFormatID,
kColorRenderableRequiredBits) || kColorRenderableRequiredBits) ||
renderer->hasImageFormatFeatureBits(vkFormat.actualImageVkFormat, renderer->hasImageFormatFeatureBits(vkFormat.actualImageFormatID,
kDepthStencilRenderableRequiredBits); kDepthStencilRenderableRequiredBits);
constexpr uint32_t kTextureableRequiredBits = constexpr uint32_t kTextureableRequiredBits =
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT; VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
mTextureable = mTextureable =
renderer->hasImageFormatFeatureBits(vkFormat.actualImageVkFormat, kTextureableRequiredBits); renderer->hasImageFormatFeatureBits(vkFormat.actualImageFormatID, kTextureableRequiredBits);
return angle::Result::Continue; return angle::Result::Continue;
} }
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
# Code generation for vk format map. See vk_format_map.json for data source. # Code generation for vk format map. See vk_format_map.json for data source.
# NOTE: don't run this script directly. Run scripts/run_code_generation.py. # NOTE: don't run this script directly. Run scripts/run_code_generation.py.
from datetime import date
import json import json
import math import math
import pprint import pprint
...@@ -21,7 +20,7 @@ import angle_format ...@@ -21,7 +20,7 @@ import angle_format
template_table_autogen_cpp = """// GENERATED FILE - DO NOT EDIT. template_table_autogen_cpp = """// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {input_file_name} // Generated by {script_name} using data from {input_file_name}
// //
// Copyright {copyright_year} The ANGLE Project Authors. All rights reserved. // Copyright 2020 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// //
...@@ -38,7 +37,6 @@ using namespace angle; ...@@ -38,7 +37,6 @@ using namespace angle;
namespace rx namespace rx
{{ {{
namespace vk namespace vk
{{ {{
...@@ -54,8 +52,25 @@ void Format::initialize(RendererVk *renderer, ...@@ -54,8 +52,25 @@ void Format::initialize(RendererVk *renderer,
}} }}
}} }}
}} // namespace vk VkFormat GetVkFormatFromFormatID(angle::FormatID formatID)
{{
static constexpr angle::FormatMap<VkFormat> kMap = {{
{format_id_cases}
}};
return kMap[formatID];
}}
angle::FormatID GetFormatIDFromVkFormat(VkFormat vkFormat)
{{
switch (vkFormat)
{{
{vk_format_cases}
default:
return angle::FormatID::NONE;
}}
}}
}} // namespace vk
}} // namespace rx }} // namespace rx
""" """
...@@ -72,10 +87,9 @@ break; ...@@ -72,10 +87,9 @@ break;
""" """
image_basic_template = """actualImageFormatID = {image}; image_basic_template = """actualImageFormatID = {image};
actualImageVkFormat = {vk_image_format};
imageInitializerFunction = {image_initializer};""" imageInitializerFunction = {image_initializer};"""
image_struct_template = "{{{image}, {vk_image_format}, {image_initializer}}}" image_struct_template = "{{{image}, {image_initializer}}}"
image_fallback_template = """{{ image_fallback_template = """{{
static constexpr ImageFormatInitInfo kInfo[] = {{{image_list}}}; static constexpr ImageFormatInitInfo kInfo[] = {{{image_list}}};
...@@ -83,12 +97,11 @@ initImageFallback(renderer, kInfo, ArraySize(kInfo)); ...@@ -83,12 +97,11 @@ initImageFallback(renderer, kInfo, ArraySize(kInfo));
}}""" }}"""
buffer_basic_template = """actualBufferFormatID = {buffer}; buffer_basic_template = """actualBufferFormatID = {buffer};
actualBufferVkFormat = {vk_buffer_format};
vkBufferFormatIsPacked = {vk_buffer_format_is_packed}; vkBufferFormatIsPacked = {vk_buffer_format_is_packed};
vertexLoadFunction = {vertex_load_function}; vertexLoadFunction = {vertex_load_function};
vertexLoadRequiresConversion = {vertex_load_converts};""" vertexLoadRequiresConversion = {vertex_load_converts};"""
buffer_struct_template = """{{{buffer}, {vk_buffer_format}, {vk_buffer_format_is_packed}, buffer_struct_template = """{{{buffer}, {vk_buffer_format_is_packed},
{vertex_load_function}, {vertex_load_converts}}}""" {vertex_load_function}, {vertex_load_converts}}}"""
buffer_fallback_template = """{{ buffer_fallback_template = """{{
...@@ -170,7 +183,6 @@ def gen_format_case(angle, internal_format, vk_json_data): ...@@ -170,7 +183,6 @@ def gen_format_case(angle, internal_format, vk_json_data):
def image_args(format): def image_args(format):
return dict( return dict(
image="angle::FormatID::" + format, image="angle::FormatID::" + format,
vk_image_format=vk_map[format],
image_initializer=angle_format.get_internal_format_initializer( image_initializer=angle_format.get_internal_format_initializer(
internal_format, format)) internal_format, format))
...@@ -178,7 +190,6 @@ def gen_format_case(angle, internal_format, vk_json_data): ...@@ -178,7 +190,6 @@ def gen_format_case(angle, internal_format, vk_json_data):
vk_buffer_format = vk_map[format] vk_buffer_format = vk_map[format]
return dict( return dict(
buffer="angle::FormatID::" + format, buffer="angle::FormatID::" + format,
vk_buffer_format=vk_buffer_format,
vk_buffer_format_is_packed=is_packed(vk_buffer_format), vk_buffer_format_is_packed=is_packed(vk_buffer_format),
vertex_load_function=get_vertex_copy_function(angle, format, vk_buffer_format), vertex_load_function=get_vertex_copy_function(angle, format, vk_buffer_format),
vertex_load_converts='false' if angle == format else 'true', vertex_load_converts='false' if angle == format else 'true',
...@@ -207,6 +218,17 @@ def gen_format_case(angle, internal_format, vk_json_data): ...@@ -207,6 +218,17 @@ def gen_format_case(angle, internal_format, vk_json_data):
return format_entry_template.format(**args).format(**args) return format_entry_template.format(**args).format(**args)
def get_format_id_case(format_id, vk_format):
return "{angle::FormatID::%s, %s}" % (format_id, vk_format)
def get_vk_format_case(format_id, vk_format):
return """\
case %s:
return angle::FormatID::%s;
""" % (vk_format, format_id)
def main(): def main():
input_file_name = 'vk_format_map.json' input_file_name = 'vk_format_map.json'
...@@ -232,13 +254,24 @@ def main(): ...@@ -232,13 +254,24 @@ def main():
if not verify_vk_map_keys(angle_to_gl, vk_json_data): if not verify_vk_map_keys(angle_to_gl, vk_json_data):
return 1 return 1
format_id_cases = [
get_format_id_case(format_id, vk_format)
for format_id, vk_format in vk_json_data["map"].iteritems()
]
vk_format_cases = [
get_vk_format_case(format_id, vk_format)
for format_id, vk_format in vk_json_data["map"].iteritems()
]
vk_cases = [ vk_cases = [
gen_format_case(angle, gl, vk_json_data) for angle, gl in sorted(angle_to_gl.iteritems()) gen_format_case(angle, gl, vk_json_data) for angle, gl in sorted(angle_to_gl.iteritems())
] ]
output_cpp = template_table_autogen_cpp.format( output_cpp = template_table_autogen_cpp.format(
copyright_year=date.today().year,
format_case_data="\n".join(vk_cases), format_case_data="\n".join(vk_cases),
format_id_cases=",\n".join(format_id_cases),
vk_format_cases="".join(vk_format_cases),
script_name=__file__, script_name=__file__,
out_file_name=out_file_name, out_file_name=out_file_name,
input_file_name=input_file_name) input_file_name=input_file_name)
......
...@@ -155,7 +155,7 @@ void UnpackAttachmentDesc(VkAttachmentDescription *desc, ...@@ -155,7 +155,7 @@ void UnpackAttachmentDesc(VkAttachmentDescription *desc,
{ {
// We would only need this flag for duplicated attachments. Apply it conservatively. // We would only need this flag for duplicated attachments. Apply it conservatively.
desc->flags = VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT; desc->flags = VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT;
desc->format = format.actualImageVkFormat; desc->format = format.actualImageVkFormat();
desc->samples = gl_vk::GetSamples(samples); desc->samples = gl_vk::GetSamples(samples);
desc->loadOp = static_cast<VkAttachmentLoadOp>(ops.loadOp); desc->loadOp = static_cast<VkAttachmentLoadOp>(ops.loadOp);
desc->storeOp = desc->storeOp =
...@@ -179,7 +179,7 @@ void UnpackColorResolveAttachmentDesc(VkAttachmentDescription *desc, ...@@ -179,7 +179,7 @@ void UnpackColorResolveAttachmentDesc(VkAttachmentDescription *desc,
// attachments simultaneously, so this flag can likely be removed without any issue if it incurs // attachments simultaneously, so this flag can likely be removed without any issue if it incurs
// a performance penalty. // a performance penalty.
desc->flags = VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT; desc->flags = VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT;
desc->format = format.actualImageVkFormat; desc->format = format.actualImageVkFormat();
// This function is for color resolve attachments. // This function is for color resolve attachments.
const angle::Format &angleFormat = format.actualImageFormat(); const angle::Format &angleFormat = format.actualImageFormat();
...@@ -212,7 +212,7 @@ void UnpackDepthStencilResolveAttachmentDesc(VkAttachmentDescription *desc, ...@@ -212,7 +212,7 @@ void UnpackDepthStencilResolveAttachmentDesc(VkAttachmentDescription *desc,
// There cannot be simultaneous usages of the depth/stencil resolve image, as depth/stencil // There cannot be simultaneous usages of the depth/stencil resolve image, as depth/stencil
// resolve currently only comes from depth/stencil renderbuffers. // resolve currently only comes from depth/stencil renderbuffers.
desc->flags = 0; desc->flags = 0;
desc->format = format.actualImageVkFormat; desc->format = format.actualImageVkFormat();
// This function is for depth/stencil resolve attachment. // This function is for depth/stencil resolve attachment.
const angle::Format &angleFormat = format.intendedFormat(); const angle::Format &angleFormat = format.intendedFormat();
...@@ -1712,8 +1712,7 @@ angle::Result GraphicsPipelineDesc::initializePipeline( ...@@ -1712,8 +1712,7 @@ angle::Result GraphicsPipelineDesc::initializePipeline(
angle::FormatID formatID = static_cast<angle::FormatID>(packedAttrib.format); angle::FormatID formatID = static_cast<angle::FormatID>(packedAttrib.format);
const Format &format = contextVk->getRenderer()->getFormat(formatID); const Format &format = contextVk->getRenderer()->getFormat(formatID);
const angle::Format &angleFormat = format.intendedFormat(); const angle::Format &angleFormat = format.intendedFormat();
VkFormat vkFormat = packedAttrib.compressed ? format.actualCompressedBufferVkFormat VkFormat vkFormat = format.actualBufferVkFormat(packedAttrib.compressed);
: format.actualBufferVkFormat;
gl::ComponentType attribType = gl::ComponentType attribType =
GetVertexAttributeComponentType(angleFormat.isPureInt(), angleFormat.vertexAttribType); GetVertexAttributeComponentType(angleFormat.isPureInt(), angleFormat.vertexAttribType);
......
...@@ -40,12 +40,12 @@ bool HasShaderImageAtomicsSupport(const RendererVk *rendererVk, ...@@ -40,12 +40,12 @@ bool HasShaderImageAtomicsSupport(const RendererVk *rendererVk,
const Format &formatVk = rendererVk->getFormat(GL_R32F); const Format &formatVk = rendererVk->getFormat(GL_R32F);
const bool hasImageAtomicSupport = rendererVk->hasImageFormatFeatureBits( const bool hasImageAtomicSupport = rendererVk->hasImageFormatFeatureBits(
formatVk.actualImageVkFormat, VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT); formatVk.actualImageFormatID, VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT);
bool hasBufferAtomicSupport = true; bool hasBufferAtomicSupport = true;
if (supportedExtensions.textureBufferAny()) if (supportedExtensions.textureBufferAny())
{ {
hasBufferAtomicSupport = rendererVk->hasBufferFormatFeatureBits( hasBufferAtomicSupport = rendererVk->hasBufferFormatFeatureBits(
formatVk.actualBufferVkFormat, VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT); formatVk.actualBufferFormatID, VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT);
} }
return hasImageAtomicSupport && hasBufferAtomicSupport; return hasImageAtomicSupport && hasBufferAtomicSupport;
...@@ -65,12 +65,19 @@ bool FormatReinterpretationSupported(const std::vector<GLenum> &optionalSizedFor ...@@ -65,12 +65,19 @@ bool FormatReinterpretationSupported(const std::vector<GLenum> &optionalSizedFor
{ {
const Format &vkFormat = rendererVk->getFormat(glFormat); const Format &vkFormat = rendererVk->getFormat(glFormat);
VkFormat reinterpretedFormat = checkLinearColorspace angle::FormatID reinterpretedFormatID =
? ConvertToLinear(vkFormat.actualImageVkFormat) checkLinearColorspace ? ConvertToLinear(vkFormat.actualImageFormatID)
: ConvertToSRGB(vkFormat.actualImageVkFormat); : ConvertToSRGB(vkFormat.actualImageFormatID);
if (!rendererVk->haveSameFormatFeatureBits(vkFormat.actualImageVkFormat, const Format &reinterpretedVkFormat = rendererVk->getFormat(reinterpretedFormatID);
reinterpretedFormat))
if (reinterpretedVkFormat.actualImageFormatID != reinterpretedFormatID)
{
return false;
}
if (!rendererVk->haveSameFormatFeatureBits(vkFormat.actualImageFormatID,
reinterpretedFormatID))
{ {
return false; return false;
} }
...@@ -179,7 +186,7 @@ bool HasTexelBufferSupport(const RendererVk *rendererVk, GLenum formatGL) ...@@ -179,7 +186,7 @@ bool HasTexelBufferSupport(const RendererVk *rendererVk, GLenum formatGL)
const Format &formatVk = rendererVk->getFormat(formatGL); const Format &formatVk = rendererVk->getFormat(formatGL);
return rendererVk->hasBufferFormatFeatureBits( return rendererVk->hasBufferFormatFeatureBits(
formatVk.actualBufferVkFormat, formatVk.actualBufferFormatID,
VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT); VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT);
} }
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -37,19 +37,20 @@ constexpr uint32_t kNumVkFormats = 185; ...@@ -37,19 +37,20 @@ constexpr uint32_t kNumVkFormats = 185;
struct ImageFormatInitInfo final struct ImageFormatInitInfo final
{ {
angle::FormatID format; angle::FormatID format;
VkFormat vkFormat;
InitializeTextureDataFunction initializer; InitializeTextureDataFunction initializer;
}; };
struct BufferFormatInitInfo final struct BufferFormatInitInfo final
{ {
angle::FormatID format; angle::FormatID format;
VkFormat vkFormat;
bool vkFormatIsPacked; bool vkFormatIsPacked;
VertexCopyFunction vertexLoadFunction; VertexCopyFunction vertexLoadFunction;
bool vertexLoadRequiresConversion; bool vertexLoadRequiresConversion;
}; };
VkFormat GetVkFormatFromFormatID(angle::FormatID formatID);
angle::FormatID GetFormatIDFromVkFormat(VkFormat vkFormat);
// Describes a Vulkan format. For more information on formats in the Vulkan back-end please see // Describes a Vulkan format. For more information on formats in the Vulkan back-end please see
// https://chromium.googlesource.com/angle/angle/+/master/src/libANGLE/renderer/vulkan/doc/FormatTablesAndEmulation.md // https://chromium.googlesource.com/angle/angle/+/master/src/libANGLE/renderer/vulkan/doc/FormatTablesAndEmulation.md
struct Format final : private angle::NonCopyable struct Format final : private angle::NonCopyable
...@@ -69,6 +70,8 @@ struct Format final : private angle::NonCopyable ...@@ -69,6 +70,8 @@ struct Format final : private angle::NonCopyable
return angle::Format::Get(actualImageFormatID); return angle::Format::Get(actualImageFormatID);
} }
VkFormat actualImageVkFormat() const { return GetVkFormatFromFormatID(actualImageFormatID); }
// The actual Buffer format is used to implement the front-end format for Buffers. This format // The actual Buffer format is used to implement the front-end format for Buffers. This format
// is used by vertex buffers as well as texture buffers. Note that all formats required for // is used by vertex buffers as well as texture buffers. Note that all formats required for
// GL_EXT_texture_buffer have mandatory support for vertex buffers in Vulkan, so they won't be // GL_EXT_texture_buffer have mandatory support for vertex buffers in Vulkan, so they won't be
...@@ -79,6 +82,12 @@ struct Format final : private angle::NonCopyable ...@@ -79,6 +82,12 @@ struct Format final : private angle::NonCopyable
: actualBufferFormatID); : actualBufferFormatID);
} }
VkFormat actualBufferVkFormat(bool compressed) const
{
return GetVkFormatFromFormatID(compressed ? actualCompressedBufferFormatID
: actualBufferFormatID);
}
VertexCopyFunction getVertexLoadFunction(bool compressed) const VertexCopyFunction getVertexLoadFunction(bool compressed) const
{ {
return compressed ? compressedVertexLoadFunction : vertexLoadFunction; return compressed ? compressedVertexLoadFunction : vertexLoadFunction;
...@@ -119,11 +128,8 @@ struct Format final : private angle::NonCopyable ...@@ -119,11 +128,8 @@ struct Format final : private angle::NonCopyable
angle::FormatID intendedFormatID; angle::FormatID intendedFormatID;
GLenum intendedGLFormat; GLenum intendedGLFormat;
angle::FormatID actualImageFormatID; angle::FormatID actualImageFormatID;
VkFormat actualImageVkFormat;
angle::FormatID actualBufferFormatID; angle::FormatID actualBufferFormatID;
VkFormat actualBufferVkFormat;
angle::FormatID actualCompressedBufferFormatID; angle::FormatID actualCompressedBufferFormatID;
VkFormat actualCompressedBufferVkFormat;
InitializeTextureDataFunction imageInitializerFunction; InitializeTextureDataFunction imageInitializerFunction;
LoadFunctionMap textureLoadFunctions; LoadFunctionMap textureLoadFunctions;
...@@ -174,16 +180,14 @@ class FormatTable final : angle::NonCopyable ...@@ -174,16 +180,14 @@ class FormatTable final : angle::NonCopyable
// initialized to 0. // initialized to 0.
const VkFormatProperties &GetMandatoryFormatSupport(VkFormat vkFormat); const VkFormatProperties &GetMandatoryFormatSupport(VkFormat vkFormat);
VkImageUsageFlags GetMaximalImageUsageFlags(RendererVk *renderer, VkFormat format); VkImageUsageFlags GetMaximalImageUsageFlags(RendererVk *renderer, angle::FormatID formatID);
} // namespace vk } // namespace vk
// Checks if a vkFormat supports all the features needed to use it as a GL texture format // Checks if a Vulkan format supports all the features needed to use it as a GL texture format.
bool HasFullTextureFormatSupport(RendererVk *renderer, VkFormat vkFormat); bool HasFullTextureFormatSupport(RendererVk *renderer, angle::FormatID formatID);
// Checks if a vkFormat supports all the features except texture filtering // Checks if a Vulkan format supports all the features except rendering.
bool HasNonFilterableTextureFormatSupport(RendererVk *renderer, VkFormat vkFormat); bool HasNonRenderableTextureFormatSupport(RendererVk *renderer, angle::FormatID formatID);
// Checks if a vkFormat supports all the features except rendering
bool HasNonRenderableTextureFormatSupport(RendererVk *renderer, VkFormat vkFormat);
// Returns the alignment for a buffer to be used with the vertex input stage in Vulkan. This // Returns the alignment for a buffer to be used with the vertex input stage in Vulkan. This
// calculation is listed in the Vulkan spec at the end of the section 'Vertex Input Description'. // calculation is listed in the Vulkan spec at the end of the section 'Vertex Input Description'.
...@@ -198,144 +202,6 @@ gl::SwizzleState GetFormatSwizzle(const ContextVk *contextVk, ...@@ -198,144 +202,6 @@ gl::SwizzleState GetFormatSwizzle(const ContextVk *contextVk,
gl::SwizzleState ApplySwizzle(const gl::SwizzleState &formatSwizzle, gl::SwizzleState ApplySwizzle(const gl::SwizzleState &formatSwizzle,
const gl::SwizzleState &toApply); const gl::SwizzleState &toApply);
namespace vk
{
ANGLE_INLINE VkFormat ConvertToSRGB(VkFormat format)
{
switch (format)
{
case VK_FORMAT_R8_UNORM:
return VK_FORMAT_R8_SRGB;
case VK_FORMAT_R8G8_UNORM:
return VK_FORMAT_R8G8_SRGB;
case VK_FORMAT_R8G8B8_UNORM:
return VK_FORMAT_R8G8B8_SRGB;
case VK_FORMAT_B8G8R8_UNORM:
return VK_FORMAT_B8G8R8_SRGB;
case VK_FORMAT_R8G8B8A8_UNORM:
return VK_FORMAT_R8G8B8A8_SRGB;
case VK_FORMAT_B8G8R8A8_UNORM:
return VK_FORMAT_B8G8R8A8_SRGB;
case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
return VK_FORMAT_BC1_RGB_SRGB_BLOCK;
case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
return VK_FORMAT_BC1_RGBA_SRGB_BLOCK;
case VK_FORMAT_BC2_UNORM_BLOCK:
return VK_FORMAT_BC2_SRGB_BLOCK;
case VK_FORMAT_BC3_UNORM_BLOCK:
return VK_FORMAT_BC3_SRGB_BLOCK;
case VK_FORMAT_BC7_UNORM_BLOCK:
return VK_FORMAT_BC7_SRGB_BLOCK;
case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
return VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK;
case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
return VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK;
case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
return VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK;
case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
return VK_FORMAT_ASTC_4x4_SRGB_BLOCK;
case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
return VK_FORMAT_ASTC_5x4_SRGB_BLOCK;
case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
return VK_FORMAT_ASTC_5x5_SRGB_BLOCK;
case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
return VK_FORMAT_ASTC_6x5_SRGB_BLOCK;
case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
return VK_FORMAT_ASTC_6x6_SRGB_BLOCK;
case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
return VK_FORMAT_ASTC_8x5_SRGB_BLOCK;
case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
return VK_FORMAT_ASTC_8x6_SRGB_BLOCK;
case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
return VK_FORMAT_ASTC_8x8_SRGB_BLOCK;
case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
return VK_FORMAT_ASTC_10x5_SRGB_BLOCK;
case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
return VK_FORMAT_ASTC_10x6_SRGB_BLOCK;
case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
return VK_FORMAT_ASTC_10x8_SRGB_BLOCK;
case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
return VK_FORMAT_ASTC_10x10_SRGB_BLOCK;
case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
return VK_FORMAT_ASTC_12x10_SRGB_BLOCK;
case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
return VK_FORMAT_ASTC_12x12_SRGB_BLOCK;
default:
return VK_FORMAT_UNDEFINED;
}
}
ANGLE_INLINE VkFormat ConvertToLinear(VkFormat format)
{
switch (format)
{
case VK_FORMAT_R8_SRGB:
return VK_FORMAT_R8_UNORM;
case VK_FORMAT_R8G8_SRGB:
return VK_FORMAT_R8G8_UNORM;
case VK_FORMAT_R8G8B8_SRGB:
return VK_FORMAT_R8G8B8_UNORM;
case VK_FORMAT_B8G8R8_SRGB:
return VK_FORMAT_B8G8R8_UNORM;
case VK_FORMAT_R8G8B8A8_SRGB:
return VK_FORMAT_R8G8B8A8_UNORM;
case VK_FORMAT_B8G8R8A8_SRGB:
return VK_FORMAT_B8G8R8A8_UNORM;
case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
return VK_FORMAT_BC1_RGB_UNORM_BLOCK;
case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
return VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
case VK_FORMAT_BC2_SRGB_BLOCK:
return VK_FORMAT_BC2_UNORM_BLOCK;
case VK_FORMAT_BC3_SRGB_BLOCK:
return VK_FORMAT_BC3_UNORM_BLOCK;
case VK_FORMAT_BC7_SRGB_BLOCK:
return VK_FORMAT_BC7_UNORM_BLOCK;
case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
return VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;
case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
return VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK;
case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
return VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
return VK_FORMAT_ASTC_4x4_UNORM_BLOCK;
case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
return VK_FORMAT_ASTC_5x4_UNORM_BLOCK;
case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
return VK_FORMAT_ASTC_5x5_UNORM_BLOCK;
case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
return VK_FORMAT_ASTC_6x5_UNORM_BLOCK;
case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
return VK_FORMAT_ASTC_6x6_UNORM_BLOCK;
case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
return VK_FORMAT_ASTC_8x5_UNORM_BLOCK;
case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
return VK_FORMAT_ASTC_8x6_UNORM_BLOCK;
case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
return VK_FORMAT_ASTC_8x8_UNORM_BLOCK;
case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
return VK_FORMAT_ASTC_10x5_UNORM_BLOCK;
case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
return VK_FORMAT_ASTC_10x6_UNORM_BLOCK;
case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
return VK_FORMAT_ASTC_10x8_UNORM_BLOCK;
case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
return VK_FORMAT_ASTC_10x10_UNORM_BLOCK;
case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
return VK_FORMAT_ASTC_12x10_UNORM_BLOCK;
case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
return VK_FORMAT_ASTC_12x12_UNORM_BLOCK;
default:
return VK_FORMAT_UNDEFINED;
}
}
ANGLE_INLINE bool IsOverridableLinearFormat(VkFormat format)
{
return ConvertToSRGB(format) != VK_FORMAT_UNDEFINED;
}
} // namespace vk
} // namespace rx } // namespace rx
#endif // LIBANGLE_RENDERER_VULKAN_VK_FORMAT_UTILS_H_ #endif // LIBANGLE_RENDERER_VULKAN_VK_FORMAT_UTILS_H_
...@@ -1302,7 +1302,7 @@ enum class ImageLayout ...@@ -1302,7 +1302,7 @@ enum class ImageLayout
VkImageLayout ConvertImageLayoutToVkImageLayout(ImageLayout imageLayout); VkImageLayout ConvertImageLayoutToVkImageLayout(ImageLayout imageLayout);
bool FormatHasNecessaryFeature(RendererVk *renderer, bool FormatHasNecessaryFeature(RendererVk *renderer,
VkFormat format, angle::FormatID formatID,
VkImageTiling tilingMode, VkImageTiling tilingMode,
VkFormatFeatureFlags featureBits); VkFormatFeatureFlags featureBits);
...@@ -1389,7 +1389,7 @@ class ImageHelper final : public Resource, public angle::Subject ...@@ -1389,7 +1389,7 @@ class ImageHelper final : public Resource, public angle::Subject
uint32_t baseArrayLayer, uint32_t baseArrayLayer,
uint32_t layerCount, uint32_t layerCount,
VkImageUsageFlags imageUsageFlags, VkImageUsageFlags imageUsageFlags,
VkFormat imageViewFormat) const; angle::FormatID imageViewFormat) const;
angle::Result initImageView(Context *context, angle::Result initImageView(Context *context,
gl::TextureType textureType, gl::TextureType textureType,
VkImageAspectFlags aspectMask, VkImageAspectFlags aspectMask,
...@@ -2089,7 +2089,7 @@ class ImageViewHelper final : public Resource ...@@ -2089,7 +2089,7 @@ class ImageViewHelper final : public Resource
LevelIndex levelVk, LevelIndex levelVk,
uint32_t layer, uint32_t layer,
VkImageUsageFlags imageUsageFlags, VkImageUsageFlags imageUsageFlags,
VkFormat vkImageFormat, angle::FormatID formatID,
const ImageView **imageViewOut); const ImageView **imageViewOut);
// Creates a storage view with a single layer of the level. // Creates a storage view with a single layer of the level.
...@@ -2098,7 +2098,7 @@ class ImageViewHelper final : public Resource ...@@ -2098,7 +2098,7 @@ class ImageViewHelper final : public Resource
LevelIndex levelVk, LevelIndex levelVk,
uint32_t layer, uint32_t layer,
VkImageUsageFlags imageUsageFlags, VkImageUsageFlags imageUsageFlags,
VkFormat vkImageFormat, angle::FormatID formatID,
const ImageView **imageViewOut); const ImageView **imageViewOut);
// Creates a draw view with all layers of the level. // Creates a draw view with all layers of the level.
......
...@@ -989,7 +989,7 @@ void InitExternalSemaphoreCapabilitiesFunctions(VkInstance instance) ...@@ -989,7 +989,7 @@ void InitExternalSemaphoreCapabilitiesFunctions(VkInstance instance)
GLenum CalculateGenerateMipmapFilter(ContextVk *contextVk, const vk::Format &format) GLenum CalculateGenerateMipmapFilter(ContextVk *contextVk, const vk::Format &format)
{ {
const bool formatSupportsLinearFiltering = contextVk->getRenderer()->hasImageFormatFeatureBits( const bool formatSupportsLinearFiltering = contextVk->getRenderer()->hasImageFormatFeatureBits(
format.actualImageVkFormat, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT); format.actualImageFormatID, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT);
const bool hintFastest = contextVk->getState().getGenerateMipmapHint() == GL_FASTEST; const bool hintFastest = contextVk->getState().getGenerateMipmapHint() == GL_FASTEST;
return formatSupportsLinearFiltering && !hintFastest ? GL_LINEAR : GL_NEAREST; return formatSupportsLinearFiltering && !hintFastest ? GL_LINEAR : GL_NEAREST;
......
...@@ -163,7 +163,7 @@ void DisplayVkWin32::checkConfigSupport(egl::Config *config) ...@@ -163,7 +163,7 @@ void DisplayVkWin32::checkConfigSupport(egl::Config *config)
for (const VkSurfaceFormatKHR &surfaceFormat : mSurfaceFormats) for (const VkSurfaceFormatKHR &surfaceFormat : mSurfaceFormats)
{ {
if (surfaceFormat.format == formatVk.actualImageVkFormat) if (surfaceFormat.format == formatVk.actualImageVkFormat())
{ {
return; return;
} }
......
...@@ -70,20 +70,23 @@ TEST_P(VulkanFormatTablesTest, TestFormatSupport) ...@@ -70,20 +70,23 @@ TEST_P(VulkanFormatTablesTest, TestFormatSupport)
for (const ParametersToTest params : parametersToTest) for (const ParametersToTest params : parametersToTest)
{ {
VkFormat actualImageVkFormat =
rx::vk::GetVkFormatFromFormatID(vkFormat.actualImageFormatID);
// Now let's verify that against vulkan. // Now let's verify that against vulkan.
VkFormatProperties formatProperties; VkFormatProperties formatProperties;
vkGetPhysicalDeviceFormatProperties(renderer->getPhysicalDevice(), vkGetPhysicalDeviceFormatProperties(renderer->getPhysicalDevice(), actualImageVkFormat,
vkFormat.actualImageVkFormat, &formatProperties); &formatProperties);
VkImageFormatProperties imageProperties; VkImageFormatProperties imageProperties;
// isTexturable? // isTexturable?
bool isTexturable = bool isTexturable =
vkGetPhysicalDeviceImageFormatProperties( vkGetPhysicalDeviceImageFormatProperties(
renderer->getPhysicalDevice(), vkFormat.actualImageVkFormat, params.imageType, renderer->getPhysicalDevice(), actualImageVkFormat, params.imageType,
VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT, params.createFlags, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT, params.createFlags,
&imageProperties) == VK_SUCCESS; &imageProperties) == VK_SUCCESS;
EXPECT_EQ(isTexturable, textureCaps.texturable) << vkFormat.actualImageVkFormat; EXPECT_EQ(isTexturable, textureCaps.texturable) << actualImageVkFormat;
// TODO(jmadill): Support ES3 textures. // TODO(jmadill): Support ES3 textures.
...@@ -91,23 +94,23 @@ TEST_P(VulkanFormatTablesTest, TestFormatSupport) ...@@ -91,23 +94,23 @@ TEST_P(VulkanFormatTablesTest, TestFormatSupport)
bool isFilterable = (formatProperties.optimalTilingFeatures & bool isFilterable = (formatProperties.optimalTilingFeatures &
VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) == VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) ==
VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT; VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
EXPECT_EQ(isFilterable, textureCaps.filterable) << vkFormat.actualImageVkFormat; EXPECT_EQ(isFilterable, textureCaps.filterable) << actualImageVkFormat;
// isRenderable? // isRenderable?
const bool isRenderableColor = const bool isRenderableColor =
(vkGetPhysicalDeviceImageFormatProperties( (vkGetPhysicalDeviceImageFormatProperties(
renderer->getPhysicalDevice(), vkFormat.actualImageVkFormat, params.imageType, renderer->getPhysicalDevice(), actualImageVkFormat, params.imageType,
VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
params.createFlags, &imageProperties)) == VK_SUCCESS; params.createFlags, &imageProperties)) == VK_SUCCESS;
const bool isRenderableDepthStencil = const bool isRenderableDepthStencil =
(vkGetPhysicalDeviceImageFormatProperties( (vkGetPhysicalDeviceImageFormatProperties(
renderer->getPhysicalDevice(), vkFormat.actualImageVkFormat, params.imageType, renderer->getPhysicalDevice(), actualImageVkFormat, params.imageType,
VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
params.createFlags, &imageProperties)) == VK_SUCCESS; params.createFlags, &imageProperties)) == VK_SUCCESS;
bool isRenderable = isRenderableColor || isRenderableDepthStencil; bool isRenderable = isRenderableColor || isRenderableDepthStencil;
EXPECT_EQ(isRenderable, textureCaps.textureAttachment) << vkFormat.actualImageVkFormat; EXPECT_EQ(isRenderable, textureCaps.textureAttachment) << actualImageVkFormat;
EXPECT_EQ(isRenderable, textureCaps.renderbuffer) << vkFormat.actualImageVkFormat; EXPECT_EQ(isRenderable, textureCaps.renderbuffer) << actualImageVkFormat;
} }
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment