Merge pull request #101217 from BlueCube3310/gl-uncomp-formats

Compatibility: Improve gl texture format detection
This commit is contained in:
Rémi Verschelde
2025-01-12 18:07:12 +01:00

View File

@ -334,16 +334,7 @@ void TextureStorage::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS:
/* Texture API */
Ref<Image> TextureStorage::_get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, Image::Format &r_real_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed, bool p_force_decompress) const {
Config *config = Config::get_singleton();
r_gl_format = 0;
Ref<Image> image = p_image;
r_compressed = false;
r_real_format = p_format;
bool need_decompress = false;
bool decompress_ra_to_rg = false;
static inline Error _get_gl_uncompressed_format(Image::Format p_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type) {
switch (p_format) {
case Image::FORMAT_L8: {
if (RasterizerGLES3::is_gles_over_gl()) {
@ -371,55 +362,51 @@ Ref<Image> TextureStorage::_get_gl_image_and_format(const Ref<Image> &p_image, I
r_gl_internal_format = GL_R8;
r_gl_format = GL_RED;
r_gl_type = GL_UNSIGNED_BYTE;
} break;
case Image::FORMAT_RG8: {
r_gl_internal_format = GL_RG8;
r_gl_format = GL_RG;
r_gl_type = GL_UNSIGNED_BYTE;
} break;
case Image::FORMAT_RGB8: {
r_gl_internal_format = GL_RGB8;
r_gl_format = GL_RGB;
r_gl_type = GL_UNSIGNED_BYTE;
} break;
case Image::FORMAT_RGBA8: {
r_gl_format = GL_RGBA;
r_gl_internal_format = GL_RGBA8;
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
} break;
case Image::FORMAT_RGBA4444: {
r_gl_internal_format = GL_RGBA4;
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_SHORT_4_4_4_4;
} break;
case Image::FORMAT_RGB565: {
r_gl_internal_format = GL_RGB565;
r_gl_format = GL_RGB;
r_gl_type = GL_UNSIGNED_SHORT_5_6_5;
} break;
case Image::FORMAT_RF: {
r_gl_internal_format = GL_R32F;
r_gl_format = GL_RED;
r_gl_type = GL_FLOAT;
} break;
case Image::FORMAT_RGF: {
r_gl_internal_format = GL_RG32F;
r_gl_format = GL_RG;
r_gl_type = GL_FLOAT;
} break;
case Image::FORMAT_RGBF: {
r_gl_internal_format = GL_RGB32F;
r_gl_format = GL_RGB;
r_gl_type = GL_FLOAT;
} break;
case Image::FORMAT_RGBAF: {
r_gl_internal_format = GL_RGBA32F;
r_gl_format = GL_RGBA;
r_gl_type = GL_FLOAT;
} break;
case Image::FORMAT_RH: {
r_gl_internal_format = GL_R16F;
@ -430,26 +417,48 @@ Ref<Image> TextureStorage::_get_gl_image_and_format(const Ref<Image> &p_image, I
r_gl_internal_format = GL_RG16F;
r_gl_format = GL_RG;
r_gl_type = GL_HALF_FLOAT;
} break;
case Image::FORMAT_RGBH: {
r_gl_internal_format = GL_RGB16F;
r_gl_format = GL_RGB;
r_gl_type = GL_HALF_FLOAT;
} break;
case Image::FORMAT_RGBAH: {
r_gl_internal_format = GL_RGBA16F;
r_gl_format = GL_RGBA;
r_gl_type = GL_HALF_FLOAT;
} break;
case Image::FORMAT_RGBE9995: {
r_gl_internal_format = GL_RGB9_E5;
r_gl_format = GL_RGB;
r_gl_type = GL_UNSIGNED_INT_5_9_9_9_REV;
} break;
default: {
return ERR_UNAVAILABLE;
}
}
return OK;
}
Ref<Image> TextureStorage::_get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, Image::Format &r_real_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed, bool p_force_decompress) const {
Config *config = Config::get_singleton();
r_gl_format = 0;
Ref<Image> image = p_image;
r_compressed = false;
r_real_format = p_format;
if (!Image::is_format_compressed(p_format)) {
Error err = _get_gl_uncompressed_format(p_format, r_gl_format, r_gl_internal_format, r_gl_type);
ERR_FAIL_COND_V_MSG(err != OK, Ref<Image>(), vformat("The image format %d is not supported by the Compatibility renderer.", p_format));
return p_image;
}
// For compressed images, some formats may not be supported by the current device and will require decompression.
bool need_decompress = false;
bool decompress_ra_to_rg = false;
switch (p_format) {
case Image::FORMAT_DXT1: {
if (config->s3tc_supported) {
r_gl_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT1_EXT;
@ -536,7 +545,6 @@ Ref<Image> TextureStorage::_get_gl_image_and_format(const Ref<Image> &p_image, I
r_gl_format = GL_RED;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = true;
} else {
need_decompress = true;
}
@ -547,7 +555,6 @@ Ref<Image> TextureStorage::_get_gl_image_and_format(const Ref<Image> &p_image, I
r_gl_format = GL_RED;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = true;
} else {
need_decompress = true;
}
@ -558,7 +565,6 @@ Ref<Image> TextureStorage::_get_gl_image_and_format(const Ref<Image> &p_image, I
r_gl_format = GL_RG;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = true;
} else {
need_decompress = true;
}
@ -569,7 +575,6 @@ Ref<Image> TextureStorage::_get_gl_image_and_format(const Ref<Image> &p_image, I
r_gl_format = GL_RG;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = true;
} else {
need_decompress = true;
}
@ -581,7 +586,6 @@ Ref<Image> TextureStorage::_get_gl_image_and_format(const Ref<Image> &p_image, I
r_gl_format = GL_RGB;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = true;
} else {
need_decompress = true;
}
@ -592,7 +596,6 @@ Ref<Image> TextureStorage::_get_gl_image_and_format(const Ref<Image> &p_image, I
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = true;
} else {
need_decompress = true;
}
@ -603,7 +606,6 @@ Ref<Image> TextureStorage::_get_gl_image_and_format(const Ref<Image> &p_image, I
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = true;
} else {
need_decompress = true;
}
@ -642,7 +644,6 @@ Ref<Image> TextureStorage::_get_gl_image_and_format(const Ref<Image> &p_image, I
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = true;
} else {
need_decompress = true;
}
@ -653,7 +654,6 @@ Ref<Image> TextureStorage::_get_gl_image_and_format(const Ref<Image> &p_image, I
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = true;
} else {
need_decompress = true;
}
@ -664,7 +664,6 @@ Ref<Image> TextureStorage::_get_gl_image_and_format(const Ref<Image> &p_image, I
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = true;
} else {
need_decompress = true;
}
@ -675,7 +674,6 @@ Ref<Image> TextureStorage::_get_gl_image_and_format(const Ref<Image> &p_image, I
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = true;
} else {
need_decompress = true;
}
@ -690,41 +688,17 @@ Ref<Image> TextureStorage::_get_gl_image_and_format(const Ref<Image> &p_image, I
image = image->duplicate();
image->decompress();
ERR_FAIL_COND_V(image->is_compressed(), image);
if (decompress_ra_to_rg) {
image->convert_ra_rgba8_to_rg();
image->convert(Image::FORMAT_RG8);
}
switch (image->get_format()) {
case Image::FORMAT_RG8: {
r_gl_format = GL_RG;
r_gl_internal_format = GL_RG8;
r_gl_type = GL_UNSIGNED_BYTE;
r_real_format = Image::FORMAT_RG8;
r_compressed = false;
} break;
case Image::FORMAT_RGB8: {
r_gl_format = GL_RGB;
r_gl_internal_format = GL_RGB;
r_gl_type = GL_UNSIGNED_BYTE;
r_real_format = Image::FORMAT_RGB8;
r_compressed = false;
} break;
case Image::FORMAT_RGBA8: {
r_gl_format = GL_RGBA;
r_gl_internal_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
r_real_format = Image::FORMAT_RGBA8;
r_compressed = false;
} break;
default: {
image->convert(Image::FORMAT_RGBA8);
r_gl_format = GL_RGBA;
r_gl_internal_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
r_real_format = Image::FORMAT_RGBA8;
r_compressed = false;
} break;
}
Error err = _get_gl_uncompressed_format(image->get_format(), r_gl_format, r_gl_internal_format, r_gl_type);
ERR_FAIL_COND_V_MSG(err != OK, Ref<Image>(), vformat("The image format %d is not supported by the Compatibility renderer.", image->get_format()));
r_real_format = image->get_format();
r_compressed = false;
}
return image;