From 71d21c7ccb9a78f573d674e717906012c7a5eb39 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Mon, 5 Sep 2022 21:11:34 +0200 Subject: Implement basic ASTC support Implements basic ASTC support: * Only 4x4 and 8x8 block sizes. * Other block sizes are too complex to handle for Godot image compression handling. May be implemented sometime in the future. The need for ASTC is mostly for the following use cases: * Implement a high quality compression option for textures on mobile and M1 Apple hardware. * For this, the 4x4 is sufficient, since it uses the same size as BPTC. ASTC supports a lot of block sizes, but the benefit of supporting most of them is slim, while the implementation complexity in Godot is very high. Supporting only 4x4 (and 8x8) solves the real problem, which is lack of a BPTC alternative on hardware where it's missing. Note: This does not yet support encoding on import, an ASTC encoder will need to be added. --- .../renderer_rd/storage_rd/texture_storage.cpp | 40 ++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'servers/rendering/renderer_rd') diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp index b87b4d4a0f..247c630095 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp @@ -1740,6 +1740,46 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO; r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; } break; + case Image::FORMAT_ASTC_4x4: + case Image::FORMAT_ASTC_4x4_HDR: { + if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ASTC_4x4_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { + r_format.format = RD::DATA_FORMAT_ASTC_4x4_UNORM_BLOCK; + if (p_image->get_format() == Image::FORMAT_ASTC_4x4) { + r_format.format_srgb = RD::DATA_FORMAT_ASTC_4x4_SRGB_BLOCK; + } + } else { + //not supported, reconvert + r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; + r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB; + image->decompress(); + image->convert(Image::FORMAT_RGBA8); + } + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A; + + } break; // astc 4x4 + case Image::FORMAT_ASTC_8x8: + case Image::FORMAT_ASTC_8x8_HDR: { + if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ASTC_8x8_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { + r_format.format = RD::DATA_FORMAT_ASTC_8x8_UNORM_BLOCK; + if (p_image->get_format() == Image::FORMAT_ASTC_8x8) { + r_format.format_srgb = RD::DATA_FORMAT_ASTC_8x8_SRGB_BLOCK; + } + } else { + //not supported, reconvert + r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; + r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB; + image->decompress(); + image->convert(Image::FORMAT_RGBA8); + } + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A; + + } break; // astc 8x8 default: { } -- cgit v1.2.3