diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp index 6ff8802f9481..31ef588398dd 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp @@ -2275,11 +2275,27 @@ uint64_t TextureStorage::texture_get_native_handle(RID p_texture, bool p_srgb) c } } +static Ref duplicate_and_convert(const Ref &p_source_image, Image::Format p_format) { + Ref image = p_source_image->duplicate(); + image->convert(p_format); + return image; +} + +static Ref duplicate_decompress_and_convert(const Ref &p_source_image, Image::Format p_format) { + Ref image = p_source_image->duplicate(); + image->decompress(); + image->convert(p_format); + return image; +} + Ref TextureStorage::_validate_texture_format(const Ref &p_image, TextureToRDFormat &r_format) { - Image::Format original_format = p_image->get_format(); - Ref image = p_image->duplicate(); + const Image::Format original_format = p_image->get_format(); - switch (p_image->get_format()) { + // Assume we have a supported format. If the format is not supported it will be converted + // to a supported format for only those cases. + Ref image = p_image; + + switch (original_format) { case Image::FORMAT_L8: { r_format.format = RD::DATA_FORMAT_R8_UNORM; r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; @@ -2317,7 +2333,7 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T //not supported, reconvert r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB; - image->convert(Image::FORMAT_RGBA8); + image = duplicate_and_convert(p_image, Image::FORMAT_RGBA8); } r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; @@ -2368,7 +2384,7 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T } else { //not supported, reconvert r_format.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT; - image->convert(Image::FORMAT_RGBAF); + image = duplicate_and_convert(p_image, Image::FORMAT_RGBAF); } r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; @@ -2407,7 +2423,7 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T } else { //not supported, reconvert r_format.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; - image->convert(Image::FORMAT_RGBAH); + image = duplicate_and_convert(p_image, Image::FORMAT_RGBAH); } r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; @@ -2439,8 +2455,7 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T //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); + image = duplicate_decompress_and_convert(p_image, Image::FORMAT_RGBA8); } r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; @@ -2456,8 +2471,7 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T //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); + image = duplicate_decompress_and_convert(p_image, Image::FORMAT_RGBA8); } r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; @@ -2473,8 +2487,7 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T //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); + image = duplicate_decompress_and_convert(p_image, Image::FORMAT_RGBA8); } r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; @@ -2487,8 +2500,7 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T } else { //not supported, reconvert r_format.format = RD::DATA_FORMAT_R8_UNORM; - image->decompress(); - image->convert(Image::FORMAT_R8); + image = duplicate_decompress_and_convert(p_image, Image::FORMAT_R8); } r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO; @@ -2502,8 +2514,7 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T } else { //not supported, reconvert r_format.format = RD::DATA_FORMAT_R8G8_UNORM; - image->decompress(); - image->convert(Image::FORMAT_RG8); + image = duplicate_decompress_and_convert(p_image, Image::FORMAT_RG8); } r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; @@ -2519,8 +2530,7 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T //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); + image = duplicate_decompress_and_convert(p_image, Image::FORMAT_RGBA8); } r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; @@ -2534,8 +2544,7 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T } else { //not supported, reconvert r_format.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; - image->decompress(); - image->convert(Image::FORMAT_RGBAH); + image = duplicate_decompress_and_convert(p_image, Image::FORMAT_RGBAH); } r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; @@ -2548,8 +2557,7 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T } else { //not supported, reconvert r_format.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; - image->decompress(); - image->convert(Image::FORMAT_RGBAH); + image = duplicate_decompress_and_convert(p_image, Image::FORMAT_RGBAH); } r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; @@ -2562,8 +2570,7 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T } else { //not supported, reconvert r_format.format = RD::DATA_FORMAT_R8_UNORM; - image->decompress(); - image->convert(Image::FORMAT_R8); + image = duplicate_decompress_and_convert(p_image, Image::FORMAT_R8); } r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO; @@ -2577,8 +2584,7 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T } else { //not supported, reconvert r_format.format = RD::DATA_FORMAT_R8_SNORM; - image->decompress(); - image->convert(Image::FORMAT_R8); + image = duplicate_decompress_and_convert(p_image, Image::FORMAT_R8); } r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO; @@ -2591,8 +2597,7 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T } else { //not supported, reconvert r_format.format = RD::DATA_FORMAT_R8G8_UNORM; - image->decompress(); - image->convert(Image::FORMAT_RG8); + image = duplicate_decompress_and_convert(p_image, Image::FORMAT_RG8); } r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; @@ -2605,8 +2610,7 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T } else { //not supported, reconvert r_format.format = RD::DATA_FORMAT_R8G8_SNORM; - image->decompress(); - image->convert(Image::FORMAT_RG8); + image = duplicate_decompress_and_convert(p_image, Image::FORMAT_RG8); } r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; @@ -2623,8 +2627,7 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T //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); + image = duplicate_decompress_and_convert(p_image, Image::FORMAT_RGBA8); } r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; @@ -2640,8 +2643,7 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T //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); + image = duplicate_decompress_and_convert(p_image, Image::FORMAT_RGBA8); } r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; @@ -2656,8 +2658,7 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T //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); + image = duplicate_decompress_and_convert(p_image, Image::FORMAT_RGBA8); } r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; @@ -2672,8 +2673,7 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T //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); + image = duplicate_decompress_and_convert(p_image, Image::FORMAT_RGBA8); } r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; r_format.swizzle_g = RD::TEXTURE_SWIZZLE_A; @@ -2688,8 +2688,7 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T //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); + image = duplicate_decompress_and_convert(p_image, Image::FORMAT_RGBA8); } r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; r_format.swizzle_g = RD::TEXTURE_SWIZZLE_A; @@ -2702,10 +2701,9 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T r_format.format_srgb = RD::DATA_FORMAT_ASTC_4x4_SRGB_BLOCK; } else { //not supported, reconvert - image->decompress(); r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB; - image->convert(Image::FORMAT_RGBA8); + image = duplicate_decompress_and_convert(p_image, Image::FORMAT_RGBA8); } r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; @@ -2718,9 +2716,8 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T r_format.format = RD::DATA_FORMAT_ASTC_4x4_SFLOAT_BLOCK; } else { //not supported, reconvert - image->decompress(); r_format.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; - image->convert(Image::FORMAT_RGBAH); + image = duplicate_decompress_and_convert(p_image, Image::FORMAT_RGBAH); } r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; @@ -2734,10 +2731,9 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T r_format.format_srgb = RD::DATA_FORMAT_ASTC_6x6_SRGB_BLOCK; } else { //not supported, reconvert - image->decompress(); r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB; - image->convert(Image::FORMAT_RGBA8); + image = duplicate_decompress_and_convert(p_image, Image::FORMAT_RGBA8); } r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; @@ -2750,9 +2746,8 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T r_format.format = RD::DATA_FORMAT_ASTC_6x6_SFLOAT_BLOCK; } else { //not supported, reconvert - image->decompress(); r_format.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; - image->convert(Image::FORMAT_RGBAH); + image = duplicate_decompress_and_convert(p_image, Image::FORMAT_RGBAH); } r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; @@ -2766,10 +2761,9 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T r_format.format_srgb = RD::DATA_FORMAT_ASTC_8x8_SRGB_BLOCK; } else { //not supported, reconvert - image->decompress(); r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB; - image->convert(Image::FORMAT_RGBA8); + image = duplicate_decompress_and_convert(p_image, Image::FORMAT_RGBA8); } r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; @@ -2782,9 +2776,8 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T r_format.format = RD::DATA_FORMAT_ASTC_8x8_SFLOAT_BLOCK; } else { //not supported, reconvert - image->decompress(); r_format.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; - image->convert(Image::FORMAT_RGBAH); + image = duplicate_decompress_and_convert(p_image, Image::FORMAT_RGBAH); } r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; @@ -2798,7 +2791,7 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T } else { // Not supported, reconvert. r_format.format = RD::DATA_FORMAT_R32_SFLOAT; - image->convert(Image::FORMAT_RF); + image = duplicate_and_convert(p_image, Image::FORMAT_RF); } r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO; @@ -2811,7 +2804,7 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T } else { // Not supported, reconvert. r_format.format = RD::DATA_FORMAT_R32G32_SFLOAT; - image->convert(Image::FORMAT_RGF); + image = duplicate_and_convert(p_image, Image::FORMAT_RGF); } r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; @@ -2825,10 +2818,10 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T // Not supported, reconvert. if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_R16G16B16A16_UNORM, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { r_format.format = RD::DATA_FORMAT_R16G16B16A16_UNORM; - image->convert(Image::FORMAT_RGBA16); + image = duplicate_and_convert(p_image, Image::FORMAT_RGBA16); } else { r_format.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT; - image->convert(Image::FORMAT_RGBAF); + image = duplicate_and_convert(p_image, Image::FORMAT_RGBAF); } } r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; @@ -2842,7 +2835,7 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T } else { // Not supported, reconvert. r_format.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT; - image->convert(Image::FORMAT_RGBAF); + image = duplicate_and_convert(p_image, Image::FORMAT_RGBAF); } r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; @@ -2870,7 +2863,7 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T } else { //not supported, reconvert r_format.format = RD::DATA_FORMAT_R16G16B16A16_UINT; - image->convert(Image::FORMAT_RGBA16I); + image = duplicate_and_convert(p_image, Image::FORMAT_RGBA16I); } r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; @@ -2888,7 +2881,6 @@ Ref TextureStorage::_validate_texture_format(const Ref &p_image, T default: { } } - // RGB formats are often not supported, only print warnings about them when launched with the --verbose flag. const bool is_rgb_format = original_format == Image::FORMAT_RGB8 || original_format == Image::FORMAT_RGBH || original_format == Image::FORMAT_RGBF; if ((is_print_verbose_enabled() || !is_rgb_format) && original_format != image->get_format()) {