From: Brendan McGrath bmcgrath@codeweavers.com
--- dlls/ddraw/tests/ddraw7.c | 28 +++++++++++++--------------- dlls/wined3d/glsl_shader.c | 23 +++++++++++++++++------ 2 files changed, 30 insertions(+), 21 deletions(-)
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index 60d74bf77fc..b4b1498039e 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -13696,33 +13696,32 @@ static void test_yuv_to_rgb_blt(void) BYTE u; BYTE v; UINT32 expected; - BOOL todo; /* some systems use SD values for HD. */ BOOL test_for_broken; UINT32 broken_value; } test_colors[] = { - {"black SD", 576, 0x10, 0x80, 0x80, 0x000000, TRUE}, - {"white SD", 576, 0xeb, 0x80, 0x80, 0xffffff, TRUE}, - {"red SD", 576, 0x51, 0x5a, 0xf0, 0xfe0000, TRUE}, - {"green SD", 576, 0x91, 0x36, 0x22, 0x00ff01, TRUE}, - {"blue SD", 576, 0x29, 0xf0, 0x6e, 0x0000ff, TRUE}, - {"gray SD", 576, 0x7e, 0x80, 0x80, 0x808080, TRUE}, + {"black SD", 576, 0x10, 0x80, 0x80, 0x000000}, + {"white SD", 576, 0xeb, 0x80, 0x80, 0xffffff}, + {"red SD", 576, 0x51, 0x5a, 0xf0, 0xfe0000}, + {"green SD", 576, 0x91, 0x36, 0x22, 0x00ff01}, + {"blue SD", 576, 0x29, 0xf0, 0x6e, 0x0000ff}, + {"gray SD", 576, 0x7e, 0x80, 0x80, 0x808080}, {"past black SD", 576, 0x00, 0x80, 0x80, 0x000000}, {"past white SD", 576, 0xff, 0x80, 0x80, 0xffffff}, {"zeros SD", 576, 0x00, 0x00, 0x00, 0x008700}, /* Windows will treat anything with a height greater than 576 as HD and, * as per ITU-R Recommendation BT.709, change the color scheme */ - {"black HD", 580, 0x10, 0x80, 0x80, 0x000000, TRUE}, - {"white HD", 580, 0xeb, 0x80, 0x80, 0xffffff, TRUE}, - {"red HD", 580, 0x3f, 0x66, 0xf0, 0xff0000, TRUE, TRUE, 0xe90002}, - {"green HD", 580, 0xad, 0x2a, 0x1a, 0x00ff01, TRUE, TRUE, 0x14ff09}, - {"blue HD", 580, 0x20, 0xf0, 0x76, 0x0100ff, TRUE, TRUE, 0x0300f5}, - {"gray HD", 580, 0x7e, 0x80, 0x80, 0x808080, TRUE}, + {"black HD", 580, 0x10, 0x80, 0x80, 0x000000}, + {"white HD", 580, 0xeb, 0x80, 0x80, 0xffffff}, + {"red HD", 580, 0x3f, 0x66, 0xf0, 0xff0000, TRUE, 0xe90002}, + {"green HD", 580, 0xad, 0x2a, 0x1a, 0x00ff01, TRUE, 0x14ff09}, + {"blue HD", 580, 0x20, 0xf0, 0x76, 0x0100ff, TRUE, 0x0300f5}, + {"gray HD", 580, 0x7e, 0x80, 0x80, 0x808080}, {"past black HD", 580, 0x00, 0x80, 0x80, 0x000000}, {"past white HD", 580, 0xff, 0x80, 0x80, 0xffffff}, - {"zeros HD", 580, 0x00, 0x00, 0x00, 0x004d00, TRUE, TRUE, 0x008700}, + {"zeros HD", 580, 0x00, 0x00, 0x00, 0x004d00, TRUE, 0x008700}, };
window = create_window(); @@ -13857,7 +13856,6 @@ static void test_yuv_to_rgb_blt(void) { pixel = (UINT32*)((BYTE*)lock_desc.lpSurface + lock_desc.lPitch * y); for (x = 0; x < 4; x++) - todo_wine_if(test_colors[j].todo) ok(compare_color(pixel[x] & 0xffffff, test_colors[j].expected, 1) || broken(test_colors[j].test_for_broken && compare_color(pixel[x] & 0xffffff, test_colors[j].broken_value, 1)), "Got unexpected value at (%d,%d). Got %#lx, expected %#lx.\n", diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index df60415f062..7a1f351b2db 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -12677,10 +12677,12 @@ static void glsl_blitter_generate_yuv_shader(struct wined3d_string_buffer *buffe { enum complex_fixup complex_fixup = get_complex_fixup(args->fixup);
- shader_addline(buffer, "const vec4 yuv_coef = vec4(1.403, -0.344, -0.714, 1.770);\n"); + shader_addline(buffer, "const vec4 yuv_coef_sd = vec4(1.596, -0.392, -0.813, 2.017);\n"); + shader_addline(buffer, "const vec4 yuv_coef_hd = vec4(1.793, -0.213, -0.533, 2.112);\n"); shader_addline(buffer, "float luminance;\n"); shader_addline(buffer, "vec2 texcoord;\n"); shader_addline(buffer, "vec2 chroma;\n"); + shader_addline(buffer, "vec4 yuv_coef;\n"); shader_addline(buffer, "uniform vec2 size;\n");
shader_addline(buffer, "\nvoid main()\n{\n"); @@ -12715,11 +12717,20 @@ static void glsl_blitter_generate_yuv_shader(struct wined3d_string_buffer *buffe return; }
- /* Calculate the final result. Formula is taken from - * http://www.fourcc.org/fccyvrgb.php. Note that the chroma - * ranges from -0.5 to 0.5. */ - shader_addline(buffer, "\n chroma.xy -= 0.5;\n"); - + /* Calculate the final result. Formula is taken from: + * https://learn.microsoft.com/en-us/windows/win32/medfound/recommended-8-bit-y.... + * SD and HD textures use different coefficients. SD is anything with both width and height smaller or equal to 720x576. + * Note that input values are clamped for SD, but not HD. Luminance is clamped to [16,235] ([0.063, 0.922] when normalized). + * Chroma is clamped to [16,240] ([0.063, 0.941] when normalized). */ + shader_addline(buffer, "\n if (size.x <= 720 && size.y <= 576)\n {\n"); + shader_addline(buffer, " luminance = clamp(luminance, 0.063, 0.922);\n"); + shader_addline(buffer, " chroma.xy = clamp(chroma.xy, 0.063, 0.941);\n"); + shader_addline(buffer, " yuv_coef = yuv_coef_sd;\n"); + shader_addline(buffer, " }\n else\n {\n"); + shader_addline(buffer, " yuv_coef = yuv_coef_hd;\n"); + shader_addline(buffer, " }\n"); + shader_addline(buffer, " luminance = (luminance - 0.063) * 1.164;\n"); + shader_addline(buffer, " chroma.xy = chroma.xy - 0.5;\n"); shader_addline(buffer, " %s.x = luminance + chroma.x * yuv_coef.x;\n", output); shader_addline(buffer, " %s.y = luminance + chroma.y * yuv_coef.y + chroma.x * yuv_coef.z;\n", output); shader_addline(buffer, " %s.z = luminance + chroma.y * yuv_coef.w;\n", output);