Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/d3d10core/tests/d3d10core.c | 3 +- dlls/d3d11/state.c | 22 ++-- dlls/d3d11/tests/d3d11.c | 7 +- dlls/wined3d/adapter_gl.c | 7 + dlls/wined3d/device.c | 21 +-- dlls/wined3d/shader.c | 2 +- dlls/wined3d/state.c | 214 ++++++++++++++++++++++++------- dlls/wined3d/utils.c | 4 +- dlls/wined3d/wined3d_gl.h | 1 + include/wine/wined3d.h | 19 ++- 10 files changed, 220 insertions(+), 80 deletions(-)
diff --git a/dlls/d3d10core/tests/d3d10core.c b/dlls/d3d10core/tests/d3d10core.c index 6b19379900..0aa998c6a6 100644 --- a/dlls/d3d10core/tests/d3d10core.c +++ b/dlls/d3d10core/tests/d3d10core.c @@ -18276,8 +18276,7 @@ static void test_independent_blend(void) { get_texture_readback(rts[i], 0, &rb); color = get_readback_color(&rb, 320, 240); - todo_wine_if (i & 1) - ok(color == ((i & 1) ? 0x80008080 : 0x8000ff00), "%u: Got unexpected color 0x%08x.\n", i, color); + ok(color == ((i & 1) ? 0x80008080 : 0x8000ff00), "%u: Got unexpected color 0x%08x.\n", i, color); release_resource_readback(&rb);
ID3D10Texture2D_Release(rts[i]); diff --git a/dlls/d3d11/state.c b/dlls/d3d11/state.c index 3bd10dd547..85ee67e272 100644 --- a/dlls/d3d11/state.c +++ b/dlls/d3d11/state.c @@ -350,10 +350,6 @@ HRESULT d3d_blend_state_create(struct d3d_device *device, const D3D11_BLEND_DESC tmp_desc.RenderTarget[i].RenderTargetWriteMask, i); }
- /* glEnableIndexedEXT(GL_BLEND, ...) */ - if (tmp_desc.IndependentBlendEnable) - FIXME("Per-rendertarget blend not implemented.\n"); - wined3d_mutex_lock(); if ((entry = wine_rb_get(&device->blend_states, &tmp_desc))) { @@ -389,13 +385,17 @@ HRESULT d3d_blend_state_create(struct d3d_device *device, const D3D11_BLEND_DESC }
wined3d_desc.alpha_to_coverage = desc->AlphaToCoverageEnable; - wined3d_desc.enable = desc->RenderTarget[0].BlendEnable; - wined3d_desc.src = desc->RenderTarget[0].SrcBlend; - wined3d_desc.dst = desc->RenderTarget[0].DestBlend; - wined3d_desc.op = desc->RenderTarget[0].BlendOp; - wined3d_desc.src_alpha = desc->RenderTarget[0].SrcBlendAlpha; - wined3d_desc.dst_alpha = desc->RenderTarget[0].DestBlendAlpha; - wined3d_desc.op_alpha = desc->RenderTarget[0].BlendOpAlpha; + wined3d_desc.independent = desc->IndependentBlendEnable; + for (i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) + { + wined3d_desc.rt[i].enable = desc->RenderTarget[i].BlendEnable; + wined3d_desc.rt[i].src = desc->RenderTarget[i].SrcBlend; + wined3d_desc.rt[i].dst = desc->RenderTarget[i].DestBlend; + wined3d_desc.rt[i].op = desc->RenderTarget[i].BlendOp; + wined3d_desc.rt[i].src_alpha = desc->RenderTarget[i].SrcBlendAlpha; + wined3d_desc.rt[i].dst_alpha = desc->RenderTarget[i].DestBlendAlpha; + wined3d_desc.rt[i].op_alpha = desc->RenderTarget[i].BlendOpAlpha; + }
/* We cannot fail after creating a wined3d_blend_state object. It * would lead to double free. */ diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index 22c7b0d4fb..60c6e92cd9 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -29919,7 +29919,7 @@ static void test_independent_blend(void) D3D11_BLEND_ZERO, D3D11_BLEND_ONE, D3D11_BLEND_OP_ADD, D3D11_COLOR_WRITE_ENABLE_ALL}, {TRUE, D3D11_BLEND_INV_SRC_ALPHA, D3D11_BLEND_INV_BLEND_FACTOR, D3D11_BLEND_OP_SUBTRACT, D3D11_BLEND_ONE, D3D11_BLEND_ONE, D3D11_BLEND_OP_REV_SUBTRACT, D3D11_COLOR_WRITE_ENABLE_ALL}, - {FALSE}, + {FALSE, 0, 0, 0, 0, 0, 0, D3D11_COLOR_WRITE_ENABLE_ALL}, {TRUE, D3D11_BLEND_DEST_COLOR, D3D11_BLEND_SRC_COLOR, D3D11_BLEND_OP_ADD, D3D11_BLEND_INV_SRC_ALPHA, D3D11_BLEND_INV_DEST_ALPHA, D3D11_BLEND_OP_SUBTRACT, D3D11_COLOR_WRITE_ENABLE_ALL}, @@ -29927,7 +29927,7 @@ static void test_independent_blend(void) };
static const DWORD expected_colors[] = - {0x66426e1c, 0xb34c3319, 0xa6214a05, 0x66333319, 0xb34c4829, 0x4d19000a, 0xb333801a, 0x081f3305}; + {0x66426e1c, 0xb34c3319, 0xa6214a05, 0x66333319, 0xb34c4829, 0x4d19000a, 0x664c3319, 0x081f3305};
static const float clear_color[] = {0.1f, 0.5f, 0.2f, 0.7f}; static const float blend_factor[] = {0.8f, 0.4f, 0.6f, 0.2f}; @@ -29967,8 +29967,7 @@ static void test_independent_blend(void) { get_texture_readback(rts[i], 0, &rb); color = get_readback_color(&rb, 320, 240, 0); - todo_wine_if (i) - ok(compare_color(color, expected_colors[i], 1), "%u: Got unexpected color 0x%08x.\n", i, color); + ok(compare_color(color, expected_colors[i], 1), "%u: Got unexpected color 0x%08x.\n", i, color); release_resource_readback(&rb); }
diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c index c04656173d..1860dd4bd0 100644 --- a/dlls/wined3d/adapter_gl.c +++ b/dlls/wined3d/adapter_gl.c @@ -74,6 +74,7 @@ static const struct wined3d_extension_map gl_extension_map[] = {"GL_ARB_depth_texture", ARB_DEPTH_TEXTURE }, {"GL_ARB_derivative_control", ARB_DERIVATIVE_CONTROL }, {"GL_ARB_draw_buffers", ARB_DRAW_BUFFERS }, + {"GL_ARB_draw_buffers_blend", ARB_DRAW_BUFFERS_BLEND }, {"GL_ARB_draw_elements_base_vertex", ARB_DRAW_ELEMENTS_BASE_VERTEX }, {"GL_ARB_draw_indirect", ARB_DRAW_INDIRECT }, {"GL_ARB_draw_instanced", ARB_DRAW_INSTANCED }, @@ -1310,6 +1311,7 @@ static enum wined3d_feature_level feature_level_from_caps(const struct wined3d_g
if (gl_info->supported[WINED3D_GL_VERSION_3_2] && gl_info->supported[ARB_POLYGON_OFFSET_CLAMP] + && gl_info->supported[ARB_DRAW_BUFFERS_BLEND] && gl_info->supported[ARB_SAMPLER_OBJECTS]) { if (shader_model >= 5 @@ -2679,8 +2681,12 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) USE_GL_FUNC(glBindVertexArray) /* OpenGL 3.0 */ USE_GL_FUNC(glBlendColor) /* OpenGL 1.4 */ USE_GL_FUNC(glBlendEquation) /* OpenGL 1.4 */ + USE_GL_FUNC(glBlendEquationi) /* OpenGL 4.0 */ USE_GL_FUNC(glBlendEquationSeparate) /* OpenGL 2.0 */ + USE_GL_FUNC(glBlendEquationSeparatei) /* OpenGL 4.0 */ + USE_GL_FUNC(glBlendFunci) /* OpenGL 4.0 */ USE_GL_FUNC(glBlendFuncSeparate) /* OpenGL 1.4 */ + USE_GL_FUNC(glBlendFuncSeparatei) /* OpenGL 4.0 */ USE_GL_FUNC(glBufferData) /* OpenGL 1.5 */ USE_GL_FUNC(glBufferSubData) /* OpenGL 1.5 */ USE_GL_FUNC(glColorMaski) /* OpenGL 3.0 */ @@ -3370,6 +3376,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, {ARB_TIMER_QUERY, MAKEDWORD_VERSION(3, 3)}, {ARB_VERTEX_TYPE_2_10_10_10_REV, MAKEDWORD_VERSION(3, 3)},
+ {ARB_DRAW_BUFFERS_BLEND, MAKEDWORD_VERSION(4, 0)}, {ARB_DRAW_INDIRECT, MAKEDWORD_VERSION(4, 0)}, {ARB_GPU_SHADER5, MAKEDWORD_VERSION(4, 0)}, {ARB_SAMPLE_SHADING, MAKEDWORD_VERSION(4, 0)}, diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index d94b1e2f2d..889aac0506 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -3657,23 +3657,24 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device,
memset(&desc, 0, sizeof(desc)); desc.alpha_to_coverage = state->alpha_to_coverage; + desc.independent = FALSE; if (state->rs[WINED3D_RS_ADAPTIVETESS_Y] == WINED3DFMT_ATOC) desc.alpha_to_coverage = TRUE; - desc.enable = state->rs[WINED3D_RS_ALPHABLENDENABLE]; - desc.src = state->rs[WINED3D_RS_SRCBLEND]; - desc.dst = state->rs[WINED3D_RS_DESTBLEND]; - desc.op = state->rs[WINED3D_RS_BLENDOP]; + desc.rt[0].enable = state->rs[WINED3D_RS_ALPHABLENDENABLE]; + desc.rt[0].src = state->rs[WINED3D_RS_SRCBLEND]; + desc.rt[0].dst = state->rs[WINED3D_RS_DESTBLEND]; + desc.rt[0].op = state->rs[WINED3D_RS_BLENDOP]; if (state->rs[WINED3D_RS_SEPARATEALPHABLENDENABLE]) { - desc.src_alpha = state->rs[WINED3D_RS_SRCBLENDALPHA]; - desc.dst_alpha = state->rs[WINED3D_RS_DESTBLENDALPHA]; - desc.op_alpha = state->rs[WINED3D_RS_BLENDOPALPHA]; + desc.rt[0].src_alpha = state->rs[WINED3D_RS_SRCBLENDALPHA]; + desc.rt[0].dst_alpha = state->rs[WINED3D_RS_DESTBLENDALPHA]; + desc.rt[0].op_alpha = state->rs[WINED3D_RS_BLENDOPALPHA]; } else { - desc.src_alpha = state->rs[WINED3D_RS_SRCBLEND]; - desc.dst_alpha = state->rs[WINED3D_RS_DESTBLEND]; - desc.op_alpha = state->rs[WINED3D_RS_BLENDOP]; + desc.rt[0].src_alpha = state->rs[WINED3D_RS_SRCBLEND]; + desc.rt[0].dst_alpha = state->rs[WINED3D_RS_DESTBLEND]; + desc.rt[0].op_alpha = state->rs[WINED3D_RS_BLENDOP]; }
if (wined3d_bitmap_is_set(changed->renderState, WINED3D_RS_BLENDFACTOR)) diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index 13e55cff8a..d9ef1a96e2 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -3909,7 +3909,7 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 static unsigned int warned = 0;
args->srgb_correction = 1; - if (state->blend_state && state->blend_state->desc.enable && !warned++) + if (state->blend_state && state->blend_state->desc.rt[0].enable && !warned++) WARN("Blending into a sRGB render target with no GL_ARB_framebuffer_sRGB " "support, expect rendering artifacts.\n"); } diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 19f47f834e..ad3ce37501 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -426,17 +426,17 @@ static void blendop(const struct wined3d_state *state, const struct wined3d_gl_i }
/* BLENDOPALPHA requires GL_EXT_blend_equation_separate, so make sure it is around */ - if (b->desc.op_alpha && !gl_info->supported[EXT_BLEND_EQUATION_SEPARATE]) + if (b->desc.rt[0].op_alpha && !gl_info->supported[EXT_BLEND_EQUATION_SEPARATE]) { WARN("Unsupported in local OpenGL implementation: glBlendEquationSeparate.\n"); return; }
- blend_equation = gl_blend_op(gl_info, b->desc.op); - blend_equation_alpha = gl_blend_op(gl_info, b->desc.op_alpha); + blend_equation = gl_blend_op(gl_info, b->desc.rt[0].op); + blend_equation_alpha = gl_blend_op(gl_info, b->desc.rt[0].op_alpha); TRACE("blend_equation %#x, blend_equation_alpha %#x.\n", blend_equation, blend_equation_alpha);
- if (b->desc.op != b->desc.op_alpha) + if (b->desc.rt[0].op != b->desc.rt[0].op_alpha) { GL_EXTCALL(glBlendEquationSeparate(blend_equation, blend_equation_alpha)); checkGLcall("glBlendEquationSeparate"); @@ -525,43 +525,78 @@ static void gl_blend_from_d3d(GLenum *src_blend, GLenum *dst_blend, } }
-static void state_blend(struct wined3d_context *context, const struct wined3d_state *state) +static void state_blend_factor_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +{ + WARN("Unsupported in local OpenGL implementation: glBlendColor.\n"); +} + +static void state_blend_factor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +{ + const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; + const struct wined3d_color *factor = &state->blend_factor; + + TRACE("Setting blend factor to %s.\n", debug_color(factor)); + + GL_EXTCALL(glBlendColor(factor->r, factor->g, factor->b, factor->a)); + checkGLcall("glBlendColor"); +} + +static BOOL is_blend_enabled(struct wined3d_context *context, const struct wined3d_state *state, UINT index) +{ + const struct wined3d_blend_state *b = state->blend_state; + + if (!state->fb->render_targets[index]) + return FALSE; + + if (!b->desc.rt[index].enable) + return FALSE; + + /* Disable blending in all cases even without pixel shaders. + * With blending on we could face a big performance penalty. + * The d3d9 visual test confirms the behavior. */ + if (context->render_offscreen + && !(state->fb->render_targets[index]->format_flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)) + return FALSE; + + return TRUE; +} + +static void blend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; const struct wined3d_blend_state *b = state->blend_state; const struct wined3d_format *rt_format; GLenum src_blend, dst_blend; - unsigned int rt_fmt_flags; - BOOL enable_blend;
- enable_blend = state->fb->render_targets[0] && b && b->desc.enable; - if (enable_blend) + if (gl_info->supported[ARB_MULTISAMPLE]) { - rt_format = state->fb->render_targets[0]->format; - rt_fmt_flags = state->fb->render_targets[0]->format_flags; - - /* Disable blending in all cases even without pixelshaders. - * With blending on we could face a big performance penalty. - * The d3d9 visual test confirms the behavior. */ - if (context->render_offscreen && !(rt_fmt_flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)) - enable_blend = FALSE; + if (b && b->desc.alpha_to_coverage) + gl_info->gl_ops.gl.p_glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE); + else + gl_info->gl_ops.gl.p_glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE); + checkGLcall("glEnable GL_SAMPLE_ALPHA_TO_COVERAGE"); }
- if (!enable_blend) + if (b && b->desc.independent) + WARN("Independent blend is not supported by this GL implementation.\n"); + + if (!b || !is_blend_enabled(context, state, 0)) { gl_info->gl_ops.gl.p_glDisable(GL_BLEND); - checkGLcall("glDisable(GL_BLEND)"); + checkGLcall("glDisable GL_BLEND"); return; }
gl_info->gl_ops.gl.p_glEnable(GL_BLEND); - checkGLcall("glEnable(GL_BLEND)"); + checkGLcall("glEnable GL_BLEND"); + + rt_format = state->fb->render_targets[0]->format;
- gl_blend_from_d3d(&src_blend, &dst_blend, b->desc.src, b->desc.dst, rt_format); + gl_blend_from_d3d(&src_blend, &dst_blend, b->desc.rt[0].src, b->desc.rt[0].dst, rt_format);
blendop(state, gl_info);
- if (b->desc.src != b->desc.src_alpha || b->desc.dst != b->desc.dst_alpha) + if (b->desc.rt[0].src != b->desc.rt[0].src_alpha || b->desc.rt[0].dst != b->desc.rt[0].dst_alpha) { GLenum src_blend_alpha, dst_blend_alpha;
@@ -572,7 +607,7 @@ static void state_blend(struct wined3d_context *context, const struct wined3d_st return; }
- gl_blend_from_d3d(&src_blend_alpha, &dst_blend_alpha, b->desc.src_alpha, b->desc.dst_alpha, rt_format); + gl_blend_from_d3d(&src_blend_alpha, &dst_blend_alpha, b->desc.rt[0].src_alpha, b->desc.rt[0].dst_alpha, rt_format);
GL_EXTCALL(glBlendFuncSeparate(src_blend, dst_blend, src_blend_alpha, dst_blend_alpha)); checkGLcall("glBlendFuncSeparate"); @@ -590,37 +625,128 @@ static void state_blend(struct wined3d_context *context, const struct wined3d_st context_apply_state(context, state, STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP)); }
-static void state_blend_factor_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) -{ - WARN("Unsupported in local OpenGL implementation: glBlendColor.\n"); -} - -static void state_blend_factor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +static void blend_db2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; - const struct wined3d_color *factor = &state->blend_factor; + GLenum src_blend, dst_blend, src_blend_alpha, dst_blend_alpha; + const struct wined3d_blend_state *b = state->blend_state; + const struct wined3d_format *rt_format; + unsigned int i;
- TRACE("Setting blend factor to %s.\n", debug_color(factor)); + if (b && b->desc.alpha_to_coverage) + gl_info->gl_ops.gl.p_glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE); + else + gl_info->gl_ops.gl.p_glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE); + checkGLcall("glEnable GL_SAMPLE_ALPHA_TO_COVERAGE");
- GL_EXTCALL(glBlendColor(factor->r, factor->g, factor->b, factor->a)); - checkGLcall("glBlendColor"); + if (!b) + { + gl_info->gl_ops.gl.p_glDisable(GL_BLEND); + checkGLcall("glDisable GL_BLEND"); + return; + } + + if (!b->desc.independent) + { + blend(context, state, state_id); + return; + } + + rt_format = state->fb->render_targets[0]->format; + gl_blend_from_d3d(&src_blend, &dst_blend, b->desc.rt[0].src, b->desc.rt[0].dst, rt_format); + gl_blend_from_d3d(&src_blend_alpha, &dst_blend_alpha, b->desc.rt[0].src_alpha, b->desc.rt[0].dst_alpha, rt_format); + + GL_EXTCALL(glBlendFuncSeparate(src_blend, dst_blend, src_blend_alpha, dst_blend_alpha)); + checkGLcall("glBlendFuncSeparate"); + + GL_EXTCALL(glBlendEquationSeparate(gl_blend_op(gl_info, b->desc.rt[0].op), + gl_blend_op(gl_info, b->desc.rt[0].op_alpha))); + checkGLcall("glBlendEquationSeparate"); + + for (i = 0; i < WINED3D_MAX_RENDER_TARGETS; ++i) + { + if (!is_blend_enabled(context, state, i)) + { + GL_EXTCALL(glDisablei(GL_BLEND, i)); + checkGLcall("glDisablei GL_BLEND"); + continue; + } + + GL_EXTCALL(glEnablei(GL_BLEND, i)); + checkGLcall("glEnablei GL_BLEND"); + + if (b->desc.rt[i].src != b->desc.rt[0].src + || b->desc.rt[i].dst != b->desc.rt[0].dst + || b->desc.rt[i].op != b->desc.rt[0].op + || b->desc.rt[i].src_alpha != b->desc.rt[0].src_alpha + || b->desc.rt[i].dst_alpha != b->desc.rt[0].dst_alpha + || b->desc.rt[i].op_alpha != b->desc.rt[0].op_alpha) + WARN("Independent blend equations and blend functions are not supported by this GL implementation.\n"); + } + + /* Colorkey fixup for stage 0 alphaop depends on blend state, so it may need + * updating. */ + if (state->render_states[WINED3D_RS_COLORKEYENABLE]) + context_apply_state(context, state, STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP)); }
-static void blend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +static void blend_dbb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; const struct wined3d_blend_state *b = state->blend_state; + unsigned int i;
- if (gl_info->supported[ARB_MULTISAMPLE]) + if (b && b->desc.alpha_to_coverage) + gl_info->gl_ops.gl.p_glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE); + else + gl_info->gl_ops.gl.p_glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE); + checkGLcall("glEnable GL_SAMPLE_ALPHA_TO_COVERAGE"); + + if (!b) { - if (b && b->desc.alpha_to_coverage) - gl_info->gl_ops.gl.p_glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE); - else - gl_info->gl_ops.gl.p_glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE); - checkGLcall("glEnable GL_SAMPLE_ALPHA_TO_COVERAGE"); + gl_info->gl_ops.gl.p_glDisable(GL_BLEND); + checkGLcall("glDisable GL_BLEND"); + return; + } + + if (!b->desc.independent) + { + blend(context, state, state_id); + return; + } + + for (i = 0; i < WINED3D_MAX_RENDER_TARGETS; ++i) + { + GLenum src_blend, dst_blend, src_blend_alpha, dst_blend_alpha; + const struct wined3d_format *rt_format; + + if (!is_blend_enabled(context, state, i)) + { + GL_EXTCALL(glDisablei(GL_BLEND, i)); + checkGLcall("glDisablei GL_BLEND"); + continue; + } + + GL_EXTCALL(glEnablei(GL_BLEND, i)); + checkGLcall("glEnablei GL_BLEND"); + + rt_format = state->fb->render_targets[i]->format; + gl_blend_from_d3d(&src_blend, &dst_blend, b->desc.rt[i].src, b->desc.rt[i].dst, rt_format); + gl_blend_from_d3d(&src_blend_alpha, &dst_blend_alpha, + b->desc.rt[i].src_alpha, b->desc.rt[i].dst_alpha, rt_format); + + GL_EXTCALL(glBlendFuncSeparatei(i, src_blend, dst_blend, src_blend_alpha, dst_blend_alpha)); + checkGLcall("glBlendFuncSeparatei"); + + GL_EXTCALL(glBlendEquationSeparatei(i, gl_blend_op(gl_info, b->desc.rt[i].op), + gl_blend_op(gl_info, b->desc.rt[i].op_alpha))); + checkGLcall("glBlendEquationSeparatei"); }
- state_blend(context, state); + /* Colorkey fixup for stage 0 alphaop depends on blend state, so it may need + * updating. */ + if (state->render_states[WINED3D_RS_COLORKEYENABLE]) + context_apply_state(context, state, STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP)); }
void state_alpha_test(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) @@ -3225,7 +3351,7 @@ void tex_alphaop(struct wined3d_context *context, const struct wined3d_state *st } else if (op == WINED3D_TOP_SELECT_ARG1 && arg1 != WINED3DTA_TEXTURE) { - if (state->blend_state && state->blend_state->desc.enable) + if (state->blend_state && state->blend_state->desc.rt[0].enable) { arg2 = WINED3DTA_TEXTURE; op = WINED3D_TOP_MODULATE; @@ -3234,7 +3360,7 @@ void tex_alphaop(struct wined3d_context *context, const struct wined3d_state *st } else if (op == WINED3D_TOP_SELECT_ARG2 && arg2 != WINED3DTA_TEXTURE) { - if (state->blend_state && state->blend_state->desc.enable) + if (state->blend_state && state->blend_state->desc.rt[0].enable) { arg1 = WINED3DTA_TEXTURE; op = WINED3D_TOP_MODULATE; @@ -4499,6 +4625,8 @@ const struct wined3d_state_entry_template misc_state_template[] = { STATE_STREAM_OUTPUT, { STATE_STREAM_OUTPUT, state_so, }, WINED3D_GL_VERSION_3_2 }, { STATE_STREAM_OUTPUT, { STATE_STREAM_OUTPUT, state_so_warn, }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_EDGEANTIALIAS), { STATE_RENDER(WINED3D_RS_EDGEANTIALIAS), state_line_antialias}, WINED3D_GL_EXT_NONE }, + { STATE_BLEND, { STATE_BLEND, blend_dbb }, ARB_DRAW_BUFFERS_BLEND }, + { STATE_BLEND, { STATE_BLEND, blend_db2 }, EXT_DRAW_BUFFERS2 }, { STATE_BLEND, { STATE_BLEND, blend }, WINED3D_GL_EXT_NONE }, { STATE_BLEND_FACTOR, { STATE_BLEND_FACTOR, state_blend_factor }, EXT_BLEND_COLOR }, { STATE_BLEND_FACTOR, { STATE_BLEND_FACTOR, state_blend_factor_w}, WINED3D_GL_EXT_NONE }, diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 82a4e2ca0d..54866da533 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -6134,7 +6134,7 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d } else if (aop == WINED3D_TOP_SELECT_ARG1 && aarg1 != WINED3DTA_TEXTURE) { - if (state->blend_state && state->blend_state->desc.enable) + if (state->blend_state && state->blend_state->desc.rt[0].enable) { aarg2 = WINED3DTA_TEXTURE; aop = WINED3D_TOP_MODULATE; @@ -6143,7 +6143,7 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d } else if (aop == WINED3D_TOP_SELECT_ARG2 && aarg2 != WINED3DTA_TEXTURE) { - if (state->blend_state && state->blend_state->desc.enable) + if (state->blend_state && state->blend_state->desc.rt[0].enable) { aarg1 = WINED3DTA_TEXTURE; aop = WINED3D_TOP_MODULATE; diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h index 2cb25a3776..6b1c99e6da 100644 --- a/dlls/wined3d/wined3d_gl.h +++ b/dlls/wined3d/wined3d_gl.h @@ -57,6 +57,7 @@ enum wined3d_gl_extension ARB_DEPTH_TEXTURE, ARB_DERIVATIVE_CONTROL, ARB_DRAW_BUFFERS, + ARB_DRAW_BUFFERS_BLEND, ARB_DRAW_ELEMENTS_BASE_VERTEX, ARB_DRAW_INDIRECT, ARB_DRAW_INSTANCED, diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 9ec097ea5f..16800a8e40 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -1605,6 +1605,7 @@ enum wined3d_shader_type #define WINED3D_MAX_CONSTS_I 16 #define WINED3D_MAX_VS_CONSTS_F 256 #define WINED3D_MAX_PS_CONSTS_F 224 +#define WINED3D_MAX_RENDER_TARGETS 8
struct wined3d_display_mode { @@ -2029,13 +2030,17 @@ struct wined3d_buffer_desc struct wined3d_blend_state_desc { BOOL alpha_to_coverage; - BOOL enable; - enum wined3d_blend src; - enum wined3d_blend dst; - enum wined3d_blend_op op; - enum wined3d_blend src_alpha; - enum wined3d_blend dst_alpha; - enum wined3d_blend_op op_alpha; + BOOL independent; + struct + { + BOOL enable; + enum wined3d_blend src; + enum wined3d_blend dst; + enum wined3d_blend_op op; + enum wined3d_blend src_alpha; + enum wined3d_blend dst_alpha; + enum wined3d_blend_op op_alpha; + } rt[WINED3D_MAX_RENDER_TARGETS]; };
struct wined3d_rasterizer_state_desc