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.
This commit is contained in:
wm4 2015-11-19 21:17:57 +01:00
parent b86a59aa4f
commit 23f3b99003
1 changed files with 40 additions and 2 deletions

View File

@ -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);