diff options
author | wm4 <wm4@nowhere> | 2017-07-29 20:12:43 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2017-07-29 20:12:43 +0200 |
commit | 0f9fcf0ed4ecb54eaadbddd3cbbc14d39ab93227 (patch) | |
tree | 391346a8333d9d3dcf692c853310839a4556b164 | |
parent | 6fcc09ff3d0db649ff7a8d9fdcb49c0d0b700905 (diff) |
vo_opengl: do not use GL format conversion on texture upload
The dither texture data is created as a float array, but uploaded to a
texture with GL_R16 as internal format. We relied on GL to do the
conversion from float to uint16_t. Not all GL variants even support
this: GLES does not provide this conversion (one of the reasons why this
code has a float16 code path). Also, ra is not going to do this. So just
convert on the fly.
Still keep the float16 texture format fallback, because not all GLES
implementations provide GL_R16.
There is some possibility that we'll need to provide some kind of upload
conversion anyway for float->float16. We still rely on GL doing this
implicitly, and all GL variants support it, but with RA there might be
the need for explicit conversion. Even then, it might be best to reduce
the number of conversion cases. I'll worry about this later.
-rw-r--r-- | video/out/opengl/video.c | 32 |
1 files changed, 16 insertions, 16 deletions
diff --git a/video/out/opengl/video.c b/video/out/opengl/video.c index ac8c9462ee..2cf0d11783 100644 --- a/video/out/opengl/video.c +++ b/video/out/opengl/video.c @@ -2597,10 +2597,8 @@ static void pass_dither(struct gl_video *p) int tex_size = 0; void *tex_data = NULL; - GLint tex_iformat = 0; - GLint tex_format = 0; - GLenum tex_type = 0; - unsigned char temp[256]; + const struct gl_format *fmt = NULL; + void *temp = NULL; if (p->opts.dither_algo == DITHER_FRUIT) { int sizeb = p->opts.dither_size; @@ -2614,15 +2612,18 @@ static void pass_dither(struct gl_video *p) } // Prefer R16 texture since they provide higher precision. - const struct gl_format *fmt = gl_find_unorm_format(gl, 2, 1); - if (!fmt || gl->es) + fmt = gl_find_unorm_format(gl, 2, 1); + if (!fmt) fmt = gl_find_float16_format(gl, 1); if (fmt) { tex_size = size; - tex_iformat = fmt->internal_format; - tex_format = fmt->format; - tex_type = GL_FLOAT; tex_data = p->last_dither_matrix; + if (fmt->type == GL_UNSIGNED_SHORT) { + uint16_t *t = temp = talloc_array(NULL, uint16_t, size * size); + for (int n = 0; n < size * size; n++) + t[n] = p->last_dither_matrix[n] * UINT16_MAX; + tex_data = t; + } } else { MP_VERBOSE(p, "GL too old. Falling back to ordered dither.\n"); p->opts.dither_algo = DITHER_ORDERED; @@ -2630,14 +2631,11 @@ static void pass_dither(struct gl_video *p) } if (p->opts.dither_algo == DITHER_ORDERED) { - assert(sizeof(temp) >= 8 * 8); + temp = talloc_array(NULL, char, 8 * 8); mp_make_ordered_dither_matrix(temp, 8); - const struct gl_format *fmt = gl_find_unorm_format(gl, 1, 1); + fmt = gl_find_unorm_format(gl, 1, 1); tex_size = 8; - tex_iformat = fmt->internal_format; - tex_format = fmt->format; - tex_type = fmt->type; tex_data = temp; } @@ -2646,8 +2644,8 @@ static void pass_dither(struct gl_video *p) gl->GenTextures(1, &p->dither_texture); gl->BindTexture(GL_TEXTURE_2D, p->dither_texture); gl->PixelStorei(GL_UNPACK_ALIGNMENT, 1); - gl->TexImage2D(GL_TEXTURE_2D, 0, tex_iformat, tex_size, tex_size, 0, - tex_format, tex_type, tex_data); + gl->TexImage2D(GL_TEXTURE_2D, 0, fmt->internal_format, tex_size, tex_size, + 0, fmt->format, fmt->type, tex_data); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); @@ -2656,6 +2654,8 @@ static void pass_dither(struct gl_video *p) gl->BindTexture(GL_TEXTURE_2D, 0); debug_check_gl(p, "dither setup"); + + talloc_free(temp); } GLSLF("// dithering\n"); |