From 5f74cb0c8380ffb6f38714c8a523757e07496f5a Mon Sep 17 00:00:00 2001 From: Andrei Alexeyev Date: Tue, 1 Oct 2024 04:05:40 +0200 Subject: [PATCH] gl33: use glTexStorage* and glInvalidateTexImage* when available glTexStorage is mostly intended to work around a regression in ANGLE's Metal backend; see https://issues.chromium.org/issues/355605685 Potentially fixes #386 --- src/renderer/gl33/texture.c | 36 +++++++++++++++++++++++++--------- src/renderer/glcommon/opengl.c | 21 ++++++++++++++++++++ src/renderer/glcommon/opengl.h | 2 ++ 3 files changed, 50 insertions(+), 9 deletions(-) diff --git a/src/renderer/gl33/texture.c b/src/renderer/gl33/texture.c index d80ef5c88f..0886727763 100644 --- a/src/renderer/gl33/texture.c +++ b/src/renderer/gl33/texture.c @@ -229,28 +229,29 @@ static void gl33_texture_set(Texture *tex, uint mipmap, uint layer, const Pixmap GLenum gl_target = target_from_class_and_layer(tex->params.class, layer); GLenum ifmt = tex->fmt_info->internal_format; + GLenum xfmt = xfer->gl_format; + GLenum xtype = xfer->gl_type; if(tex->fmt_info->flags & GLTEX_COMPRESSED) { - glCompressedTexImage2D( + glCompressedTexSubImage2D( gl_target, mipmap, - ifmt, + 0, + 0, width, height, - 0, + ifmt, image->data_size, image_data ); } else { - GLenum xfmt = xfer->gl_format; - GLenum xtype = xfer->gl_type; - glTexImage2D( + glTexSubImage2D( gl_target, mipmap, - tex->fmt_info->internal_format, + 0, + 0, width, height, - 0, xfmt, xtype, image_data @@ -394,7 +395,9 @@ Texture *gl33_texture_create(const TextureParams *params) { GLenum xfmt = xfer->gl_format; GLenum xtype = xfer->gl_type; - for(uint i = 0; i < p->mipmaps; ++i) { + if(glext.texture_storage) { + glTexStorage2D(gl_target, p->mipmaps, ifmt, p->width, p->height); + } else for(uint i = 0; i < p->mipmaps; ++i) { uint w, h; gl33_texture_get_size(tex, i, &w, &h); @@ -457,6 +460,21 @@ void gl33_texture_invalidate(Texture *tex) { return; } + if(glext.texture_storage) { + if(glext.invalidate_subdata) { + gl33_bind_texture(tex, 0, -1); + gl33_sync_texunit(tex->binding_unit, false, true); + + for(uint i = 0; i < tex->params.mipmaps; ++i) { + glInvalidateTexImage(tex->bind_target, i); + } + } else { + log_debug("TODO/FIXME: can't invalidate immutable texture without GL_ARB_invalidate_subdata!"); + } + + return; + } + gl33_bind_texture(tex, 0, -1); gl33_sync_texunit(tex->binding_unit, false, true); diff --git a/src/renderer/glcommon/opengl.c b/src/renderer/glcommon/opengl.c index c62ebf95e0..beca681089 100644 --- a/src/renderer/glcommon/opengl.c +++ b/src/renderer/glcommon/opengl.c @@ -650,6 +650,25 @@ static void glcommon_ext_texture_format_fxt1(void) { EXT_MISSING(); } +static void glcommon_ext_texture_storage(void) { + EXT_FLAG(texture_storage); + + CHECK_CORE(GL_ATLEAST(4, 2)); + CHECK_CORE(GLES_ATLEAST(3, 0)); + CHECK_EXT(GL_ARB_texture_storage); + + EXT_MISSING(); +} + +static void glcommon_ext_invalidate_subdata(void) { + EXT_FLAG(invalidate_subdata); + + CHECK_CORE(GL_ATLEAST(4, 3)); + CHECK_EXT(GL_ARB_invalidate_subdata); + + EXT_MISSING(); +} + static const char *get_unmasked_property(GLenum prop, bool fallback) { const char *val = NULL; @@ -933,6 +952,7 @@ void glcommon_check_capabilities(void) { glcommon_ext_float_blend(); glcommon_ext_instanced_arrays(); glcommon_ext_internalformat_query2(); + glcommon_ext_invalidate_subdata(); glcommon_ext_pixel_buffer_object(); glcommon_ext_seamless_cubemap(); glcommon_ext_texture_filter_anisotropic(); @@ -942,6 +962,7 @@ void glcommon_check_capabilities(void) { glcommon_ext_texture_half_float_linear(); glcommon_ext_texture_norm16(); glcommon_ext_texture_rg(); + glcommon_ext_texture_storage(); glcommon_ext_texture_swizzle(); glcommon_ext_vertex_array_object(); glcommon_ext_viewport_array(); diff --git a/src/renderer/glcommon/opengl.h b/src/renderer/glcommon/opengl.h index 859157bec9..2efdf2f9ca 100644 --- a/src/renderer/glcommon/opengl.h +++ b/src/renderer/glcommon/opengl.h @@ -168,6 +168,7 @@ struct glext_s { ext_flag_t float_blend; ext_flag_t instanced_arrays; ext_flag_t internalformat_query2; + ext_flag_t invalidate_subdata; ext_flag_t pixel_buffer_object; ext_flag_t seamless_cubemap; ext_flag_t texture_filter_anisotropic; @@ -177,6 +178,7 @@ struct glext_s { ext_flag_t texture_half_float_linear; ext_flag_t texture_norm16; ext_flag_t texture_rg; + ext_flag_t texture_storage; ext_flag_t texture_swizzle; ext_flag_t vertex_array_object; ext_flag_t viewport_array;