From 89701270dd160a8a4cdced98526320175514f8b4 Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 9 Dec 2023 21:06:44 +0100 Subject: [PATCH] gles2gsg: Fix image load/store support in OpenGL ES 3.1 This does require gl-immutable-texture-storage to be on, so it is not enabled by default unless that variable is set. That is not a breaking change since before this change, support was never enabled to begin with --- .../glstuff/glGraphicsStateGuardian_src.cxx | 2 +- panda/src/glstuff/glShaderContext_src.cxx | 44 +++++++++++++++++-- panda/src/glstuff/glShaderContext_src.h | 4 +- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 0a8b769bf6..e6217ed4c9 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -3098,7 +3098,7 @@ reset() { _max_image_units = 0; #ifndef OPENGLES_1 #ifdef OPENGLES - if (is_at_least_gl_version(3, 1)) { + if (is_at_least_gles_version(3, 1) && gl_immutable_texture_storage) { #else if (is_at_least_gl_version(4, 2) || has_extension("GL_ARB_shader_image_load_store")) { #endif diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index aa6af13edf..f3c9a106c7 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -1744,13 +1744,35 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { #endif // This won't really change at runtime, so we might as well bind once // and then forget about it. - _glgsg->_glUniform1i(p, _glsl_img_inputs.size()); { +#ifdef OPENGLES + // In OpenGL ES, we can't choose our own binding, but we can ask the + // driver what it assigned (or what the shader specified). + GLint binding = 0; + glGetUniformiv(_glsl_program, p, &binding); + if (GLCAT.is_debug()) { + GLCAT.debug() + << "Active uniform " << param_name + << " is bound to image unit " << binding << "\n"; + } + + if (binding >= _glsl_img_inputs.size()) { + _glsl_img_inputs.resize(binding + 1); + } + + ImageInput &input = _glsl_img_inputs[binding]; + input._name = InternalName::make(param_name); +#else + if (GLCAT.is_debug()) { + GLCAT.debug() + << "Binding image uniform " << param_name + << " to image unit " << _glsl_img_inputs.size() << "\n"; + } + _glgsg->_glUniform1i(p, _glsl_img_inputs.size()); ImageInput input; input._name = InternalName::make(param_name); - input._writable = false; - input._gtc = nullptr; - _glsl_img_inputs.push_back(input); + _glsl_img_inputs.push_back(std::move(input)); +#endif } return; default: @@ -2749,6 +2771,10 @@ update_shader_texture_bindings(ShaderContext *prev) { const ParamTextureImage *param = nullptr; Texture *tex; + if (input._name == nullptr) { + continue; + } + const ShaderInput &sinp = _glgsg->_target_shader->get_shader_input(input._name); switch (sinp.get_value_type()) { case ShaderInput::M_texture_image: @@ -2800,6 +2826,16 @@ update_shader_texture_bindings(ShaderContext *prev) { // TODO: automatically convert to sized type instead of plain GL_RGBA // If a base type is used, it will crash. GLenum internal_format = gtc->_internal_format; +#ifdef OPENGLES + if (!gtc->_immutable) { + static bool error_shown = false; + if (!error_shown) { + error_shown = true; + GLCAT.error() + << "Enable gl-immutable-texture-storage to use image textures in OpenGL ES.\n"; + } + } +#endif if (internal_format == GL_RGBA || internal_format == GL_RGB) { GLCAT.error() << "Texture " << tex->get_name() << " has an unsized format. Textures bound " diff --git a/panda/src/glstuff/glShaderContext_src.h b/panda/src/glstuff/glShaderContext_src.h index 0ccb99fe90..52c9f6f853 100644 --- a/panda/src/glstuff/glShaderContext_src.h +++ b/panda/src/glstuff/glShaderContext_src.h @@ -109,8 +109,8 @@ private: struct ImageInput { CPT(InternalName) _name; - CLP(TextureContext) *_gtc; - bool _writable; + CLP(TextureContext) *_gtc = nullptr; + bool _writable = false; }; pvector _glsl_img_inputs;