From ae1a4ed28a0b10a61bc055b65f1e7aa9a01a074d Mon Sep 17 00:00:00 2001 From: nanahi <130121847+na-na-hi@users.noreply.github.com> Date: Tue, 20 Feb 2024 01:35:00 -0500 Subject: [PATCH] vo_gpu: fix fragment coordinate calculation when dithering When doing the dithering pass, the fragment coordinate is queried, but doesn't take the fbo texture flipped property into account. This results in different dithering patterns when toggling between fbo flipped and non-flipped state. This can be reproduced with --vo=gpu --gpu-api=opengl and easily seen with --dither-depth=1 when toggling between playing and pausing. Fix this by flipping the fragment y coordinate if the fbo is flipped when calculating dithering coordinate. --- video/out/gpu/video.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/video/out/gpu/video.c b/video/out/gpu/video.c index 2429b9b602..61af661e6f 100644 --- a/video/out/gpu/video.c +++ b/video/out/gpu/video.c @@ -2727,7 +2727,7 @@ void gl_video_set_fb_depth(struct gl_video *p, int fb_depth) p->fb_depth = fb_depth; } -static void pass_dither(struct gl_video *p) +static void pass_dither(struct gl_video *p, const struct ra_fbo *fbo) { // Assume 8 bits per component if unknown. int dst_depth = p->fb_depth > 0 ? p->fb_depth : 8; @@ -2860,7 +2860,9 @@ static void pass_dither(struct gl_video *p) gl_sc_uniform_texture(p->sc, "dither", p->dither_texture); - GLSLF("vec2 dither_pos = gl_FragCoord.xy * 1.0/%d.0;\n", dither_size); + GLSLF("vec2 dither_coord = vec2(gl_FragCoord.x, %d.0 + %f * gl_FragCoord.y);", + fbo->flip ? p->dst_rect.y1 : 0, fbo->flip ? -1.0 : 1.0); + GLSLF("vec2 dither_pos = dither_coord * 1.0/%d.0;\n", dither_size); if (p->opts.temporal_dither) { int phase = (p->frames_rendered / p->opts.temporal_dither_period) % 8u; @@ -3097,7 +3099,7 @@ static void pass_draw_to_screen(struct gl_video *p, const struct ra_fbo *fbo, in pass_opt_hook_point(p, "OUTPUT", NULL); if (flags & RENDER_SCREEN_COLOR) - pass_dither(p); + pass_dither(p, fbo); pass_describe(p, "output to screen"); finish_pass_fbo(p, fbo, false, &p->dst_rect); }