aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar wm4 <wm4@nowhere>2017-07-29 20:12:43 +0200
committerGravatar wm4 <wm4@nowhere>2017-07-29 20:12:43 +0200
commit0f9fcf0ed4ecb54eaadbddd3cbbc14d39ab93227 (patch)
tree391346a8333d9d3dcf692c853310839a4556b164
parent6fcc09ff3d0db649ff7a8d9fdcb49c0d0b700905 (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.c32
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");