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
This commit is contained in:
rdb 2023-12-09 21:06:44 +01:00
parent 3097d2637c
commit 89701270dd
3 changed files with 43 additions and 7 deletions

View File

@ -3098,7 +3098,7 @@ reset() {
_max_image_units = 0; _max_image_units = 0;
#ifndef OPENGLES_1 #ifndef OPENGLES_1
#ifdef OPENGLES #ifdef OPENGLES
if (is_at_least_gl_version(3, 1)) { if (is_at_least_gles_version(3, 1) && gl_immutable_texture_storage) {
#else #else
if (is_at_least_gl_version(4, 2) || has_extension("GL_ARB_shader_image_load_store")) { if (is_at_least_gl_version(4, 2) || has_extension("GL_ARB_shader_image_load_store")) {
#endif #endif

View File

@ -1744,13 +1744,35 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
#endif #endif
// This won't really change at runtime, so we might as well bind once // This won't really change at runtime, so we might as well bind once
// and then forget about it. // 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; ImageInput input;
input._name = InternalName::make(param_name); input._name = InternalName::make(param_name);
input._writable = false; _glsl_img_inputs.push_back(std::move(input));
input._gtc = nullptr; #endif
_glsl_img_inputs.push_back(input);
} }
return; return;
default: default:
@ -2749,6 +2771,10 @@ update_shader_texture_bindings(ShaderContext *prev) {
const ParamTextureImage *param = nullptr; const ParamTextureImage *param = nullptr;
Texture *tex; Texture *tex;
if (input._name == nullptr) {
continue;
}
const ShaderInput &sinp = _glgsg->_target_shader->get_shader_input(input._name); const ShaderInput &sinp = _glgsg->_target_shader->get_shader_input(input._name);
switch (sinp.get_value_type()) { switch (sinp.get_value_type()) {
case ShaderInput::M_texture_image: 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 // TODO: automatically convert to sized type instead of plain GL_RGBA
// If a base type is used, it will crash. // If a base type is used, it will crash.
GLenum internal_format = gtc->_internal_format; 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) { if (internal_format == GL_RGBA || internal_format == GL_RGB) {
GLCAT.error() GLCAT.error()
<< "Texture " << tex->get_name() << " has an unsized format. Textures bound " << "Texture " << tex->get_name() << " has an unsized format. Textures bound "

View File

@ -109,8 +109,8 @@ private:
struct ImageInput { struct ImageInput {
CPT(InternalName) _name; CPT(InternalName) _name;
CLP(TextureContext) *_gtc; CLP(TextureContext) *_gtc = nullptr;
bool _writable; bool _writable = false;
}; };
pvector<ImageInput> _glsl_img_inputs; pvector<ImageInput> _glsl_img_inputs;