diff --git a/drivers/gles3/storage/config.cpp b/drivers/gles3/storage/config.cpp index fb45fdeaca7b..8e1d08274f4f 100644 --- a/drivers/gles3/storage/config.cpp +++ b/drivers/gles3/storage/config.cpp @@ -84,12 +84,14 @@ Config::Config() { if (RasterizerGLES3::is_gles_over_gl()) { float_texture_supported = true; + float_texture_linear_supported = true; etc2_supported = false; s3tc_supported = true; rgtc_supported = true; //RGTC - core since OpenGL version 3.0 srgb_framebuffer_supported = true; } else { float_texture_supported = extensions.has("GL_EXT_color_buffer_float"); + float_texture_linear_supported = extensions.has("GL_OES_texture_float_linear"); etc2_supported = true; #if defined(ANDROID_ENABLED) || defined(IOS_ENABLED) // Some Android devices report support for S3TC but we don't expect that and don't export the textures. diff --git a/drivers/gles3/storage/config.h b/drivers/gles3/storage/config.h index e4dfe6a35ee9..36fae084b0e6 100644 --- a/drivers/gles3/storage/config.h +++ b/drivers/gles3/storage/config.h @@ -72,6 +72,7 @@ class Config { HashSet<String> extensions; bool float_texture_supported = false; + bool float_texture_linear_supported = false; bool s3tc_supported = false; bool rgtc_supported = false; bool bptc_supported = false; diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp index c1b2784bfc05..de5938176857 100644 --- a/drivers/gles3/storage/texture_storage.cpp +++ b/drivers/gles3/storage/texture_storage.cpp @@ -334,7 +334,9 @@ void TextureStorage::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS: /* Texture API */ -static inline Error _get_gl_uncompressed_format(Image::Format p_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type) { +static inline Error _get_gl_uncompressed_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) { + Config *config = Config::get_singleton(); + switch (p_format) { case Image::FORMAT_L8: { if (RasterizerGLES3::is_gles_over_gl()) { @@ -389,24 +391,68 @@ static inline Error _get_gl_uncompressed_format(Image::Format p_format, GLenum & 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; + if (config->float_texture_linear_supported) { + r_gl_internal_format = GL_R32F; + r_gl_format = GL_RED; + r_gl_type = GL_FLOAT; + } else { + ERR_PRINT("R32 float texture not supported, converting to R16."); + if (p_image.is_valid()) { + p_image->convert(Image::FORMAT_RH); + } + r_real_format = Image::FORMAT_RH; + r_gl_internal_format = GL_R16F; + r_gl_format = GL_RED; + r_gl_type = GL_HALF_FLOAT; + } } break; case Image::FORMAT_RGF: { - r_gl_internal_format = GL_RG32F; - r_gl_format = GL_RG; - r_gl_type = GL_FLOAT; + if (config->float_texture_linear_supported) { + r_gl_internal_format = GL_RG32F; + r_gl_format = GL_RG; + r_gl_type = GL_FLOAT; + } else { + ERR_PRINT("RG32 float texture not supported, converting to RG16."); + if (p_image.is_valid()) { + p_image->convert(Image::FORMAT_RGH); + } + r_real_format = Image::FORMAT_RGH; + r_gl_internal_format = GL_RG16F; + r_gl_format = GL_RG; + r_gl_type = GL_HALF_FLOAT; + } } break; case Image::FORMAT_RGBF: { - r_gl_internal_format = GL_RGB32F; - r_gl_format = GL_RGB; - r_gl_type = GL_FLOAT; + if (config->float_texture_linear_supported) { + r_gl_internal_format = GL_RGB32F; + r_gl_format = GL_RGB; + r_gl_type = GL_FLOAT; + } else { + ERR_PRINT("RGB32 float texture not supported, converting to RGB16."); + if (p_image.is_valid()) { + p_image->convert(Image::FORMAT_RGBH); + } + r_real_format = Image::FORMAT_RGBH; + r_gl_internal_format = GL_RGB16F; + r_gl_format = GL_RGB; + r_gl_type = GL_HALF_FLOAT; + } } break; case Image::FORMAT_RGBAF: { - r_gl_internal_format = GL_RGBA32F; - r_gl_format = GL_RGBA; - r_gl_type = GL_FLOAT; + if (config->float_texture_linear_supported) { + r_gl_internal_format = GL_RGBA32F; + r_gl_format = GL_RGBA; + r_gl_type = GL_FLOAT; + } else { + ERR_PRINT("RGBA32 float texture not supported, converting to RGBA16."); + if (p_image.is_valid()) { + p_image->convert(Image::FORMAT_RGBAH); + } + r_real_format = Image::FORMAT_RGBAH; + r_gl_internal_format = GL_RGBA16F; + r_gl_format = GL_RGBA; + r_gl_type = GL_HALF_FLOAT; + } } break; case Image::FORMAT_RH: { r_gl_internal_format = GL_R16F; @@ -449,7 +495,7 @@ Ref<Image> TextureStorage::_get_gl_image_and_format(const Ref<Image> &p_image, I 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); + Error err = _get_gl_uncompressed_format(p_image, p_format, r_real_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; } @@ -694,7 +740,7 @@ Ref<Image> TextureStorage::_get_gl_image_and_format(const Ref<Image> &p_image, I image->convert(Image::FORMAT_RG8); } - Error err = _get_gl_uncompressed_format(image->get_format(), r_gl_format, r_gl_internal_format, r_gl_type); + Error err = _get_gl_uncompressed_format(image, image->get_format(), r_real_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();