Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45874 Signed-off-by: Henri Verbeet hverbeet@codeweavers.com --- dlls/wined3d/glsl_shader.c | 45 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 8 deletions(-)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 5f1a86608ba..fc0b2c78bd0 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -7659,6 +7659,14 @@ static void shader_glsl_generate_alpha_test(struct wined3d_string_buffer *buffer shader_addline(buffer, " discard;\n"); }
+static void shader_glsl_generate_colour_key_test(struct wined3d_string_buffer *buffer, + const char *colour, const char *colour_key_low, const char *colour_key_high) +{ + shader_addline(buffer, "if (all(greaterThanEqual(%s, %s)) && all(lessThan(%s, %s)))\n", + colour, colour_key_low, colour, colour_key_high); + shader_addline(buffer, " discard;\n"); +} + static void shader_glsl_enable_extensions(struct wined3d_string_buffer *buffer, const struct wined3d_gl_info *gl_info) { @@ -9952,10 +9960,7 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * }
if (settings->color_key_enabled) - { - shader_addline(buffer, "if (all(greaterThanEqual(tex0, color_key[0])) && all(lessThan(tex0, color_key[1])))\n"); - shader_addline(buffer, " discard;\n"); - } + shader_glsl_generate_colour_key_test(buffer, "tex0", "color_key[0]", "color_key[1]");
shader_addline(buffer, "ret = ffp_varying_diffuse;\n");
@@ -12499,7 +12504,7 @@ struct glsl_blitter_args { GLenum texture_type; struct color_fixup_desc fixup; - unsigned short padding; + unsigned short use_colour_key; };
struct glsl_blitter_program @@ -12573,6 +12578,8 @@ static void glsl_blitter_generate_p8_shader(struct wined3d_string_buffer *buffer shader_addline(buffer, " index = (index * 255.0 + 0.5) / 256.0;\n"); shader_addline(buffer, " %s = texture%s(sampler_palette, index);\n", output, needs_legacy_glsl_syntax(gl_info) ? "1D" : ""); + if (args->use_colour_key) + shader_glsl_generate_colour_key_test(buffer, output, "colour_key.low", "colour_key.high"); shader_addline(buffer, "}\n"); }
@@ -12866,6 +12873,8 @@ static void glsl_blitter_generate_yuv_shader(struct wined3d_string_buffer *buffe 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); + if (args->use_colour_key) + shader_glsl_generate_colour_key_test(buffer, output, "colour_key.low", "colour_key.high");
shader_addline(buffer, "}\n"); } @@ -12878,6 +12887,8 @@ static void glsl_blitter_generate_plain_shader(struct wined3d_string_buffer *buf shader_addline(buffer, " %s = texture%s(sampler, out_texcoord.%s);\n", output, needs_legacy_glsl_syntax(gl_info) ? tex_type : "", swizzle); shader_glsl_color_correction_ext(buffer, output, WINED3DSP_WRITEMASK_ALL, args->fixup); + if (args->use_colour_key) + shader_glsl_generate_colour_key_test(buffer, output, "colour_key.low", "colour_key.high"); shader_addline(buffer, "}\n"); }
@@ -12947,6 +12958,12 @@ static GLuint glsl_blitter_generate_program(struct wined3d_glsl_blitter *blitter string_buffer_clear(buffer); shader_glsl_add_version_declaration(buffer, gl_info); shader_addline(buffer, "uniform sampler%s sampler;\n", tex_type); + if (args->use_colour_key) + { + shader_addline(buffer, "uniform struct\n{\n"); + shader_addline(buffer, " vec4 low, high;\n"); + shader_addline(buffer, "} colour_key;\n"); + } declare_in_varying(gl_info, buffer, FALSE, "vec3 out_texcoord;\n"); /* TODO: Declare the out variable with the correct type (and put it in the * blitter args). */ @@ -13041,7 +13058,7 @@ static void glsl_blitter_upload_palette(struct wined3d_glsl_blitter *blitter,
/* Context activation is done by the caller. */ static struct glsl_blitter_program *glsl_blitter_get_program(struct wined3d_glsl_blitter *blitter, - struct wined3d_context *context, const struct wined3d_texture_gl *texture_gl) + struct wined3d_context *context, const struct wined3d_texture_gl *texture_gl, BOOL use_colour_key) { const struct wined3d_gl_info *gl_info = context->gl_info; struct glsl_blitter_program *program; @@ -13051,6 +13068,7 @@ static struct glsl_blitter_program *glsl_blitter_get_program(struct wined3d_glsl memset(&args, 0, sizeof(args)); args.texture_type = texture_gl->target; args.fixup = texture_gl->t.resource.format->color_fixup; + args.use_colour_key = use_colour_key;
if ((entry = wine_rb_get(&blitter->programs, &args))) return WINE_RB_ENTRY_VALUE(entry, struct glsl_blitter_program, entry); @@ -13098,7 +13116,7 @@ static BOOL glsl_blitter_supported(enum wined3d_blit_op blit_op, const struct wi blit_op = WINED3D_BLIT_OP_COLOR_BLIT; }
- if (blit_op != WINED3D_BLIT_OP_COLOR_BLIT) + if (blit_op != WINED3D_BLIT_OP_COLOR_BLIT && blit_op != WINED3D_BLIT_OP_COLOR_BLIT_CKEY) { TRACE("Unsupported blit_op %#x.\n", blit_op); return FALSE; @@ -13266,7 +13284,8 @@ static DWORD glsl_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bli context_invalidate_state(context, STATE_FRAMEBUFFER); }
- if (!(program = glsl_blitter_get_program(glsl_blitter, context, src_texture_gl))) + if (!(program = glsl_blitter_get_program(glsl_blitter, context, src_texture_gl, + op == WINED3D_BLIT_OP_COLOR_BLIT_CKEY))) { ERR("Failed to get blitter program.\n"); return dst_location; @@ -13291,6 +13310,16 @@ static DWORD glsl_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bli default: break; } + if (op == WINED3D_BLIT_OP_COLOR_BLIT_CKEY) + { + struct wined3d_color float_key[2]; + + wined3d_format_get_float_color_key(src_texture->resource.format, colour_key, float_key); + location = GL_EXTCALL(glGetUniformLocation(program->id, "colour_key.low")); + GL_EXTCALL(glUniform4fv(location, 1, &float_key[0].r)); + location = GL_EXTCALL(glGetUniformLocation(program->id, "colour_key.high")); + GL_EXTCALL(glUniform4fv(location, 1, &float_key[1].r)); + } context_draw_shaded_quad(context, src_texture_gl, src_sub_resource_idx, src_rect, dst_rect, filter); GL_EXTCALL(glUseProgram(0));