From 2d86752198ea3289e12909697b5d67b4cc07fc02 Mon Sep 17 00:00:00 2001 From: Chip Davis Date: Fri, 17 Apr 2020 20:21:22 +0430 Subject: [PATCH] wined3d: Use GL_APPLE_rgb_422 for UYVY and YUY2 surfaces. Theoretically, we could use it to support UYVY and YUY2 *textures* as well, but it would still require converting from YUV to RGB after sampling. Signed-off-by: Chip Davis Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/wined3d/arb_program_shader.c | 6 +++++- dlls/wined3d/glsl_shader.c | 11 +++++++++++ dlls/wined3d/utils.c | 20 +++++++++++++++++++- dlls/wined3d/wined3d_private.h | 1 + 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index 36c920dc6e0..e6daa88afd5 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -7649,11 +7649,15 @@ static HRESULT arbfp_blit_set(struct wined3d_arbfp_blitter *blitter, struct wine case COMPLEX_FIXUP_NV12: shader = gen_yuv_shader(gl_info, &type); break; + + default: + FIXME("Unsupported fixup %#x.\n", fixup); + return E_NOTIMPL; } if (!shader) { - FIXME("Unsupported complex fixup %#x, not setting a shader\n", fixup); + ERR("Failed to get shader for fixup %#x.\n", fixup); return E_NOTIMPL; } diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index c7feff85efb..6a247f46441 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -12713,6 +12713,15 @@ static void glsl_blitter_generate_yuv_shader(struct wined3d_string_buffer *buffe gen_nv12_read(buffer, gl_info, tex_type); break; + case COMPLEX_FIXUP_YUV: + /* With APPLE_rgb_422, things are much simpler. The only thing we + * have to do here is Y'CbCr to RGB conversion. */ + shader_addline(buffer, " vec3 yuv = vec3(texture%s(sampler, out_texcoord.xy));\n", + needs_legacy_glsl_syntax(gl_info) ? tex_type : ""); + shader_addline(buffer, " luminance = yuv.y;\n"); + shader_addline(buffer, " chroma = yuv.xz;\n"); + break; + default: FIXME("Unsupported fixup %#x.\n", complex_fixup); string_buffer_free(buffer); @@ -12836,6 +12845,7 @@ static GLuint glsl_blitter_generate_program(struct wined3d_glsl_blitter *blitter case COMPLEX_FIXUP_UYVY: case COMPLEX_FIXUP_YV12: case COMPLEX_FIXUP_NV12: + case COMPLEX_FIXUP_YUV: glsl_blitter_generate_yuv_shader(buffer, gl_info, args, output->buffer, tex_type, swizzle); break; case COMPLEX_FIXUP_NONE: @@ -13183,6 +13193,7 @@ static DWORD glsl_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bli case COMPLEX_FIXUP_UYVY: case COMPLEX_FIXUP_YV12: case COMPLEX_FIXUP_NV12: + case COMPLEX_FIXUP_YUV: src_level = src_sub_resource_idx % src_texture->level_count; location = GL_EXTCALL(glGetUniformLocation(program->id, "size")); GL_EXTCALL(glUniform2f(location, wined3d_texture_get_level_pow2_width(src_texture, src_level), diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 0ed9eae78ea..926a6a51edf 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -1320,6 +1320,10 @@ static const struct wined3d_format_texture_info format_texture_info[] = GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0, WINED3DFMT_FLAG_FILTERING, WINED3D_GL_LEGACY_CONTEXT, NULL}, + {WINED3DFMT_UYVY, GL_RGB_RAW_422_APPLE, GL_RGB_RAW_422_APPLE, 0, + GL_RGB_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE, 0, + WINED3DFMT_FLAG_FILTERING, + APPLE_RGB_422, NULL}, {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0, GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_FILTERING, @@ -1332,6 +1336,10 @@ static const struct wined3d_format_texture_info format_texture_info[] = GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0, WINED3DFMT_FLAG_FILTERING, WINED3D_GL_LEGACY_CONTEXT, NULL}, + {WINED3DFMT_YUY2, GL_RGB_RAW_422_APPLE, GL_RGB_RAW_422_APPLE, 0, + GL_RGB_422_APPLE, GL_UNSIGNED_SHORT_8_8_REV_APPLE, 0, + WINED3DFMT_FLAG_FILTERING, + APPLE_RGB_422, NULL}, {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0, GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_REV_APPLE, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_FILTERING, @@ -3577,7 +3585,8 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_ format->f.color_fixup = create_color_fixup_desc_from_string(fixups[i].fixup); } - if (!gl_info->supported[APPLE_YCBCR_422] && (gl_info->supported[ARB_FRAGMENT_PROGRAM] + if (!gl_info->supported[APPLE_YCBCR_422] && !gl_info->supported[APPLE_RGB_422] + && (gl_info->supported[ARB_FRAGMENT_PROGRAM] || (gl_info->supported[ARB_FRAGMENT_SHADER] && gl_info->supported[ARB_VERTEX_SHADER]))) { format = get_format_gl_internal(adapter, WINED3DFMT_YUY2); @@ -3586,6 +3595,14 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_ format = get_format_gl_internal(adapter, WINED3DFMT_UYVY); format->f.color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY); } + else if (!gl_info->supported[APPLE_YCBCR_422] && gl_info->supported[APPLE_RGB_422]) + { + format = get_format_gl_internal(adapter, WINED3DFMT_YUY2); + format->f.color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUV); + + format = get_format_gl_internal(adapter, WINED3DFMT_UYVY); + format->f.color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUV); + } else if (!gl_info->supported[APPLE_YCBCR_422] && (!gl_info->supported[ARB_FRAGMENT_PROGRAM] && (!gl_info->supported[ARB_FRAGMENT_SHADER] || !gl_info->supported[ARB_VERTEX_SHADER]))) { @@ -5389,6 +5406,7 @@ static const char *debug_complex_fixup(enum complex_fixup fixup) WINED3D_TO_STR(COMPLEX_FIXUP_YV12); WINED3D_TO_STR(COMPLEX_FIXUP_NV12); WINED3D_TO_STR(COMPLEX_FIXUP_P8); + WINED3D_TO_STR(COMPLEX_FIXUP_YUV); #undef WINED3D_TO_STR default: FIXME("Unrecognized complex fixup %#x\n", fixup); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index ade1eae352c..7e78cb60df5 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -154,6 +154,7 @@ enum complex_fixup COMPLEX_FIXUP_YV12 = 3, COMPLEX_FIXUP_P8 = 4, COMPLEX_FIXUP_NV12 = 5, + COMPLEX_FIXUP_YUV = 6, }; #include