Browse Source

recognize and use ETC2 (if available) textures natively

pull/3278/head
lizzie 1 month ago
committed by Caio Oliveira
parent
commit
ec185eea47
No known key found for this signature in database GPG Key ID: AAAE6C7FD4186B0C
  1. 11
      src/video_core/renderer_vulkan/maxwell_to_vk.cpp
  2. 17
      src/video_core/surface.cpp
  3. 9
      src/video_core/surface.h
  4. 17
      src/video_core/texture_cache/format_lookup_table.cpp
  5. 5
      src/video_core/vulkan_common/vulkan_device.h

11
src/video_core/renderer_vulkan/maxwell_to_vk.cpp

@ -217,6 +217,12 @@ FormatInfo SurfaceFormat(const Device& device, FormatType format_type, bool with
SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_6x5_UNORM_BLOCK, 0, ASTC_2D_6X5_UNORM) \ SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_6x5_UNORM_BLOCK, 0, ASTC_2D_6X5_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_6x5_SRGB_BLOCK, 0, ASTC_2D_6X5_SRGB) \ SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_6x5_SRGB_BLOCK, 0, ASTC_2D_6X5_SRGB) \
SURFACE_FORMAT_ELEM(VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, 0, E5B9G9R9_FLOAT) \ SURFACE_FORMAT_ELEM(VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, 0, E5B9G9R9_FLOAT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, 0, ETC2_RGB_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, 0, ETC2_RGBA_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, 0, ETC2_RGB_PTA_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK, 0, ETC2_RGB_SRGB) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK, 0, ETC2_RGBA_SRGB) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK, 0, ETC2_RGB_PTA_SRGB) \
/* Depth formats */ \ /* Depth formats */ \
SURFACE_FORMAT_ELEM(VK_FORMAT_D32_SFLOAT, usage_attachable, D32_FLOAT) \ SURFACE_FORMAT_ELEM(VK_FORMAT_D32_SFLOAT, usage_attachable, D32_FLOAT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_D16_UNORM, usage_attachable, D16_UNORM) \ SURFACE_FORMAT_ELEM(VK_FORMAT_D16_UNORM, usage_attachable, D16_UNORM) \
@ -253,8 +259,8 @@ FormatInfo SurfaceFormat(const Device& device, FormatType format_type, bool with
break; break;
} }
} }
// Transcode on hardware that doesn't support BCn natively
if (!device.IsOptimalBcnSupported() && VideoCore::Surface::IsPixelFormatBCn(pixel_format)) { if (!device.IsOptimalBcnSupported() && VideoCore::Surface::IsPixelFormatBCn(pixel_format)) {
// Transcode on hardware that doesn't support BCn natively
if (pixel_format == PixelFormat::BC4_SNORM) { if (pixel_format == PixelFormat::BC4_SNORM) {
tuple.format = VK_FORMAT_R8_SNORM; tuple.format = VK_FORMAT_R8_SNORM;
} else if (pixel_format == PixelFormat::BC4_UNORM) { } else if (pixel_format == PixelFormat::BC4_UNORM) {
@ -270,6 +276,9 @@ FormatInfo SurfaceFormat(const Device& device, FormatType format_type, bool with
} else { } else {
tuple.format = VK_FORMAT_A8B8G8R8_UNORM_PACK32; tuple.format = VK_FORMAT_A8B8G8R8_UNORM_PACK32;
} }
} else if (!device.IsOptimalEtc2Supported() && VideoCore::Surface::IsPixelFormatETC2(pixel_format)) {
// Transcode on hardware that doesn't support ETC2 natively
tuple.format = is_srgb ? VK_FORMAT_A8B8G8R8_SRGB_PACK32 : VK_FORMAT_A8B8G8R8_UNORM_PACK32;
} }
bool const attachable = (tuple.usage & usage_attachable) != 0; bool const attachable = (tuple.usage & usage_attachable) != 0;
bool const storage = (tuple.usage & usage_storage) != 0; bool const storage = (tuple.usage & usage_storage) != 0;

17
src/video_core/surface.cpp

@ -336,6 +336,20 @@ bool IsPixelFormatBCn(PixelFormat format) {
} }
} }
bool IsPixelFormatETC2(PixelFormat format) {
switch (format) {
case PixelFormat::ETC2_RGB_UNORM:
case PixelFormat::ETC2_RGBA_UNORM:
case PixelFormat::ETC2_RGB_PTA_UNORM:
case PixelFormat::ETC2_RGB_SRGB:
case PixelFormat::ETC2_RGBA_SRGB:
case PixelFormat::ETC2_RGB_PTA_SRGB:
return true;
default:
return false;
}
}
bool IsPixelFormatSRGB(PixelFormat format) { bool IsPixelFormatSRGB(PixelFormat format) {
switch (format) { switch (format) {
case PixelFormat::A8B8G8R8_SRGB: case PixelFormat::A8B8G8R8_SRGB:
@ -344,6 +358,9 @@ bool IsPixelFormatSRGB(PixelFormat format) {
case PixelFormat::BC2_SRGB: case PixelFormat::BC2_SRGB:
case PixelFormat::BC3_SRGB: case PixelFormat::BC3_SRGB:
case PixelFormat::BC7_SRGB: case PixelFormat::BC7_SRGB:
case PixelFormat::ETC2_RGB_SRGB:
case PixelFormat::ETC2_RGBA_SRGB:
case PixelFormat::ETC2_RGB_PTA_SRGB:
case PixelFormat::ASTC_2D_4X4_SRGB: case PixelFormat::ASTC_2D_4X4_SRGB:
case PixelFormat::ASTC_2D_8X8_SRGB: case PixelFormat::ASTC_2D_8X8_SRGB:
case PixelFormat::ASTC_2D_8X5_SRGB: case PixelFormat::ASTC_2D_8X5_SRGB:

9
src/video_core/surface.h

@ -111,6 +111,12 @@ namespace VideoCore::Surface {
PIXEL_FORMAT_ELEM(ASTC_2D_6X5_UNORM, 6, 5, 128) \ PIXEL_FORMAT_ELEM(ASTC_2D_6X5_UNORM, 6, 5, 128) \
PIXEL_FORMAT_ELEM(ASTC_2D_6X5_SRGB, 6, 5, 128) \ PIXEL_FORMAT_ELEM(ASTC_2D_6X5_SRGB, 6, 5, 128) \
PIXEL_FORMAT_ELEM(E5B9G9R9_FLOAT, 1, 1, 32) \ PIXEL_FORMAT_ELEM(E5B9G9R9_FLOAT, 1, 1, 32) \
PIXEL_FORMAT_ELEM(ETC2_RGB_UNORM, 4, 4, 64) \
PIXEL_FORMAT_ELEM(ETC2_RGBA_UNORM, 4, 4, 128) \
PIXEL_FORMAT_ELEM(ETC2_RGB_PTA_UNORM, 4, 4, 64) \
PIXEL_FORMAT_ELEM(ETC2_RGB_SRGB, 4, 4, 64) \
PIXEL_FORMAT_ELEM(ETC2_RGBA_SRGB, 4, 4, 128) \
PIXEL_FORMAT_ELEM(ETC2_RGB_PTA_SRGB, 4, 4, 64) \
/* Depth formats */ \ /* Depth formats */ \
PIXEL_FORMAT_ELEM(D32_FLOAT, 1, 1, 32) \ PIXEL_FORMAT_ELEM(D32_FLOAT, 1, 1, 32) \
PIXEL_FORMAT_ELEM(D16_UNORM, 1, 1, 16) \ PIXEL_FORMAT_ELEM(D16_UNORM, 1, 1, 16) \
@ -181,8 +187,6 @@ constexpr u32 BitsPerBlock(PixelFormat format) noexcept {
} }
} }
#undef PIXEL_FORMAT_LIST
/// Returns the sizer in bytes of the specified pixel format /// Returns the sizer in bytes of the specified pixel format
constexpr u32 BytesPerBlock(PixelFormat pixel_format) { constexpr u32 BytesPerBlock(PixelFormat pixel_format) {
return BitsPerBlock(pixel_format) / CHAR_BIT; return BitsPerBlock(pixel_format) / CHAR_BIT;
@ -198,6 +202,7 @@ SurfaceType GetFormatType(PixelFormat pixel_format);
bool HasAlpha(PixelFormat pixel_format); bool HasAlpha(PixelFormat pixel_format);
bool IsPixelFormatASTC(PixelFormat format); bool IsPixelFormatASTC(PixelFormat format);
bool IsPixelFormatBCn(PixelFormat format); bool IsPixelFormatBCn(PixelFormat format);
bool IsPixelFormatETC2(PixelFormat format);
bool IsPixelFormatSRGB(PixelFormat format); bool IsPixelFormatSRGB(PixelFormat format);
bool IsPixelFormatInteger(PixelFormat format); bool IsPixelFormatInteger(PixelFormat format);
bool IsPixelFormatSignedInteger(PixelFormat format); bool IsPixelFormatSignedInteger(PixelFormat format);

17
src/video_core/texture_cache/format_lookup_table.cpp

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@ -188,6 +191,20 @@ PixelFormat PixelFormatFromTextureInfo(TextureFormat format, ComponentType red,
return PixelFormat::BC6H_SFLOAT; return PixelFormat::BC6H_SFLOAT;
case Hash(TextureFormat::BC6H_U16, FLOAT): case Hash(TextureFormat::BC6H_U16, FLOAT):
return PixelFormat::BC6H_UFLOAT; return PixelFormat::BC6H_UFLOAT;
/* ETC2 */
case Hash(TextureFormat::ETC2_RGB, UNORM, LINEAR):
return PixelFormat::ETC2_RGB_UNORM;
case Hash(TextureFormat::ETC2_RGB_PTA, UNORM, LINEAR):
return PixelFormat::ETC2_RGB_PTA_UNORM;
case Hash(TextureFormat::ETC2_RGBA, UNORM, LINEAR):
return PixelFormat::ETC2_RGBA_UNORM;
case Hash(TextureFormat::ETC2_RGB, UNORM, SRGB):
return PixelFormat::ETC2_RGB_SRGB;
case Hash(TextureFormat::ETC2_RGB_PTA, UNORM, SRGB):
return PixelFormat::ETC2_RGB_PTA_SRGB;
case Hash(TextureFormat::ETC2_RGBA, UNORM, SRGB):
return PixelFormat::ETC2_RGBA_SRGB;
/* ASTC */
case Hash(TextureFormat::ASTC_2D_4X4, UNORM, LINEAR): case Hash(TextureFormat::ASTC_2D_4X4, UNORM, LINEAR):
return PixelFormat::ASTC_2D_4X4_UNORM; return PixelFormat::ASTC_2D_4X4_UNORM;
case Hash(TextureFormat::ASTC_2D_4X4, UNORM, SRGB): case Hash(TextureFormat::ASTC_2D_4X4, UNORM, SRGB):

5
src/video_core/vulkan_common/vulkan_device.h

@ -341,6 +341,11 @@ public:
return features.features.textureCompressionBC; return features.features.textureCompressionBC;
} }
/// Returns true if ETC2 is natively supported.
bool IsOptimalEtc2Supported() const {
return features.features.textureCompressionETC2;
}
/// Returns true if descriptor aliasing is natively supported. /// Returns true if descriptor aliasing is natively supported.
bool IsDescriptorAliasingSupported() const { bool IsDescriptorAliasingSupported() const {
return GetDriverID() != VK_DRIVER_ID_QUALCOMM_PROPRIETARY; return GetDriverID() != VK_DRIVER_ID_QUALCOMM_PROPRIETARY;

Loading…
Cancel
Save