Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add check for float texture linear filtering support #102089

Merged
merged 1 commit into from
Jan 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions drivers/gles3/storage/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions drivers/gles3/storage/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
76 changes: 61 additions & 15 deletions drivers/gles3/storage/texture_storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()) {
Expand Down Expand Up @@ -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.");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ERR_PRINT() might be a bit spammy in projects using lots of CurveTextures, so maybe we should use WARN_PRINT_ONCE() instead. The condition can't change at runtime anyway – if float textures aren't supported when the project starts, they won't be supported afterwards in the same session.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can change this in a followup PR if it ends up being too intrusive

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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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();
Expand Down