From: Brendan McGrath bmcgrath@codeweavers.com
--- dlls/ddraw/tests/ddraw7.c | 38 ++++++++++++++++++-------------------- dlls/wined3d/glsl_shader.c | 25 +++++++++++++++++++------ 2 files changed, 37 insertions(+), 26 deletions(-)
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index b1ea54702cd..ff3ba02ae52 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -13696,7 +13696,6 @@ static void test_yuv_to_rgb_blt(void) BYTE u; BYTE v; UINT32 expected; - BOOL todo; /* due to differing implementations, for some values, some systems * will return an alternative result */ BOOL allow_expected2; @@ -13707,26 +13706,26 @@ static void test_yuv_to_rgb_blt(void) } test_colors[] = { - {"black SD", 8, 0x10, 0x80, 0x80, 0x000000, TRUE}, - {"white SD", 8, 0xeb, 0x80, 0x80, 0xffffff, TRUE}, - {"red SD", 8, 0x51, 0x5a, 0xf0, 0xfe0000, TRUE}, - {"green SD", 8, 0x91, 0x36, 0x22, 0x00ff01, TRUE}, - {"blue SD", 8, 0x29, 0xf0, 0x6e, 0x0000ff, TRUE}, - {"gray SD", 8, 0x7e, 0x80, 0x80, 0x808080, TRUE}, - {"past black SD", 8, 0x00, 0x80, 0x80, 0x000000, TRUE}, - {"past white SD", 8, 0xff, 0x80, 0x80, 0xffffff, TRUE}, - {"zeros SD", 8, 0x00, 0x00, 0x00, 0x008700, TRUE, TRUE, 0x008800}, + {"black SD", 8, 0x10, 0x80, 0x80, 0x000000}, + {"white SD", 8, 0xeb, 0x80, 0x80, 0xffffff}, + {"red SD", 8, 0x51, 0x5a, 0xf0, 0xfe0000}, + {"green SD", 8, 0x91, 0x36, 0x22, 0x00ff01}, + {"blue SD", 8, 0x29, 0xf0, 0x6e, 0x0000ff}, + {"gray SD", 8, 0x7e, 0x80, 0x80, 0x808080}, + {"past black SD", 8, 0x00, 0x80, 0x80, 0x000000}, + {"past white SD", 8, 0xff, 0x80, 0x80, 0xffffff}, + {"zeros SD", 8, 0x00, 0x00, 0x00, 0x008700, TRUE, 0x008800}, /* 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", 600, 0x10, 0x80, 0x80, 0x000000, TRUE}, - {"white HD", 600, 0xeb, 0x80, 0x80, 0xffffff, TRUE}, - {"red HD", 600, 0x3f, 0x66, 0xf0, 0xff0000, TRUE, TRUE, 0xff0100, TRUE, 0xe90002}, - {"green HD", 600, 0xad, 0x2a, 0x1a, 0x00ff01, TRUE}, - {"blue HD", 600, 0x20, 0xf0, 0x76, 0x0100ff, TRUE}, - {"gray HD", 600, 0x7e, 0x80, 0x80, 0x808080, TRUE}, - {"past black HD", 600, 0x00, 0x80, 0x80, 0x000000, TRUE}, - {"past white HD", 600, 0xff, 0x80, 0x80, 0xffffff, TRUE}, - {"zeros HD", 600, 0x00, 0x00, 0x00, 0x004d00, TRUE}, + {"black HD", 600, 0x10, 0x80, 0x80, 0x000000}, + {"white HD", 600, 0xeb, 0x80, 0x80, 0xffffff}, + {"red HD", 600, 0x3f, 0x66, 0xf0, 0xff0000, TRUE, 0xff0100, TRUE, 0xe90002}, + {"green HD", 600, 0xad, 0x2a, 0x1a, 0x00ff01}, + {"blue HD", 600, 0x20, 0xf0, 0x76, 0x0100ff}, + {"gray HD", 600, 0x7e, 0x80, 0x80, 0x808080}, + {"past black HD", 600, 0x00, 0x80, 0x80, 0x000000}, + {"past white HD", 600, 0xff, 0x80, 0x80, 0xffffff}, + {"zeros HD", 600, 0x00, 0x00, 0x00, 0x004d00}, };
window = create_window(); @@ -13862,7 +13861,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((pixel[x] & 0xffffff) == test_colors[j].expected || (test_colors[j].allow_expected2 && (pixel[x] & 0xffffff) == test_colors[j].expected2), "Test %u (%s / %s): 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..e41d64fc6aa 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,14 +12717,25 @@ 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. + * Values are converted from their normalized values [0.0, 1.0] to byte values [0, 255] before calculations begin to avoid off by one rounding errors. + * 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 * 255 - 16) * 1.164;\n"); + shader_addline(buffer, " chroma.xy = chroma.xy * 255 - 128;\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); + shader_addline(buffer, " %s /= 255;\n", output); if (args->use_colour_key) shader_glsl_generate_colour_key_test(buffer, output, "colour_key.low", "colour_key.high");