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;
#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

View File

@ -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 "

View File

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