Signed-off-by: Zebediah Figura <z.figura12(a)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
--
2.25.1