From 23f3b99003da63c275771b295d6b9069fc56205e Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 19 Nov 2015 21:17:57 +0100 Subject: vo_opengl: create FBOs in a more GLES conformant way While desktop GL's glTexImage2D() essentially accepts anything, GLES is much stricter. The combination of allowed formats/types/internal formats is exactly specified. The GLES 3.0.4 specification lists them in table 3.2. (The ANGLE API validation code references this table.) The table could probably be extended into a general declarative table about GL formats covering other uses, but this would be a big non-trivial project, so don't bother and accept a minor degree of duplication with other tables. Note that the format and type do (or should) not matter here, because no image data is transferred to the GPU. --- video/out/opengl/utils.c | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) (limited to 'video') diff --git a/video/out/opengl/utils.c b/video/out/opengl/utils.c index 83bed06498..cdd549a791 100644 --- a/video/out/opengl/utils.c +++ b/video/out/opengl/utils.c @@ -312,6 +312,32 @@ void gl_vao_draw_data(struct gl_vao *vao, GLenum prim, void *ptr, size_t num) gl_vao_unbind(vao); } +struct gl_format { + GLenum format; + GLenum type; + GLint internal_format; +}; + +static const struct gl_format gl_formats[] = { + // GLES 3.0 + {GL_RGB, GL_UNSIGNED_BYTE, GL_RGB}, + {GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA}, + {GL_RGB, GL_UNSIGNED_BYTE, GL_RGB8}, + {GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA8}, + {GL_RGB, GL_UNSIGNED_SHORT, GL_RGB16}, + {GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2}, + // not texture filterable in GLES 3.0 + {GL_RGB, GL_FLOAT, GL_RGB16F}, + {GL_RGBA, GL_FLOAT, GL_RGBA16F}, + {GL_RGB, GL_FLOAT, GL_RGB32F}, + {GL_RGBA, GL_FLOAT, GL_RGBA32F}, + // Desktop GL + {GL_RGB, GL_UNSIGNED_SHORT, GL_RGB10}, + {GL_RGBA, GL_UNSIGNED_SHORT, GL_RGBA12}, + {GL_RGBA, GL_UNSIGNED_SHORT, GL_RGBA16}, + {0} +}; + // Create a texture and a FBO using the texture as color attachments. // iformat: texture internal format // Returns success. @@ -349,6 +375,18 @@ bool fbotex_change(struct fbotex *fbo, GL *gl, struct mp_log *log, int w, int h, GLenum filter = fbo->tex_filter; + struct gl_format format = { + .format = GL_RGBA, + .type = GL_UNSIGNED_BYTE, + .internal_format = iformat, + }; + for (int n = 0; gl_formats[n].format; n++) { + if (gl_formats[n].internal_format == format.internal_format) { + format = gl_formats[n]; + break; + } + } + *fbo = (struct fbotex) { .gl = gl, .w = w, @@ -364,8 +402,8 @@ bool fbotex_change(struct fbotex *fbo, GL *gl, struct mp_log *log, int w, int h, gl->GenFramebuffers(1, &fbo->fbo); gl->GenTextures(1, &fbo->texture); gl->BindTexture(GL_TEXTURE_2D, fbo->texture); - gl->TexImage2D(GL_TEXTURE_2D, 0, iformat, fbo->w, fbo->h, 0, - GL_RGBA, GL_UNSIGNED_BYTE, NULL); + gl->TexImage2D(GL_TEXTURE_2D, 0, format.internal_format, fbo->w, fbo->h, 0, + format.format, format.type, NULL); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); gl->BindTexture(GL_TEXTURE_2D, 0); -- cgit v1.2.3