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
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- v2: Fix copy-paste error; thanks Chip.
dlls/d3d10core/tests/d3d10core.c | 3 +- dlls/d3d11/device.c | 28 +------- dlls/d3d11/state.c | 5 +- dlls/d3d11/tests/d3d11.c | 6 +- dlls/wined3d/context.c | 8 +-- dlls/wined3d/device.c | 29 ++++++-- dlls/wined3d/state.c | 111 ++++++++----------------------- dlls/wined3d/surface.c | 5 +- include/wine/wined3d.h | 1 + 9 files changed, 63 insertions(+), 133 deletions(-)
diff --git a/dlls/d3d10core/tests/d3d10core.c b/dlls/d3d10core/tests/d3d10core.c index 0aa998c6a6..e84b4a47b5 100644 --- a/dlls/d3d10core/tests/d3d10core.c +++ b/dlls/d3d10core/tests/d3d10core.c @@ -18164,8 +18164,7 @@ static void test_color_mask(void) { get_texture_readback(rts[i], 0, &rb); color = get_readback_color(&rb, 320, 240); - todo_wine_if (i >= 4) - ok(color == expected_colors[i], "%u: Got unexpected color 0x%08x.\n", i, color); + ok(color == expected_colors[i], "%u: Got unexpected color 0x%08x.\n", i, color); release_resource_readback(&rb);
ID3D10Texture2D_Release(rts[i]); diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index ab52fb1311..4683ce5f3b 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -707,7 +707,6 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_OMSetBlendState(ID3D11Devi struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); static const float default_blend_factor[] = {1.0f, 1.0f, 1.0f, 1.0f}; struct d3d_blend_state *blend_state_impl; - const D3D11_BLEND_DESC *desc;
TRACE("iface %p, blend_state %p, blend_factor %s, sample_mask 0x%08x.\n", iface, blend_state, debug_float4(blend_factor), sample_mask); @@ -718,32 +717,11 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_OMSetBlendState(ID3D11Devi wined3d_mutex_lock(); wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_MULTISAMPLEMASK, sample_mask); if (!(blend_state_impl = unsafe_impl_from_ID3D11BlendState(blend_state))) - { wined3d_device_set_blend_state(device->wined3d_device, NULL, (const struct wined3d_color *)blend_factor); - wined3d_device_set_render_state(device->wined3d_device, - WINED3D_RS_COLORWRITEENABLE, D3D11_COLOR_WRITE_ENABLE_ALL); - wined3d_device_set_render_state(device->wined3d_device, - WINED3D_RS_COLORWRITEENABLE1, D3D11_COLOR_WRITE_ENABLE_ALL); - wined3d_device_set_render_state(device->wined3d_device, - WINED3D_RS_COLORWRITEENABLE2, D3D11_COLOR_WRITE_ENABLE_ALL); - wined3d_device_set_render_state(device->wined3d_device, - WINED3D_RS_COLORWRITEENABLE3, D3D11_COLOR_WRITE_ENABLE_ALL); - wined3d_mutex_unlock(); - return; - } - - wined3d_device_set_blend_state(device->wined3d_device, blend_state_impl->wined3d_state, - (const struct wined3d_color *)blend_factor); - desc = &blend_state_impl->desc; - wined3d_device_set_render_state(device->wined3d_device, - WINED3D_RS_COLORWRITEENABLE, desc->RenderTarget[0].RenderTargetWriteMask); - wined3d_device_set_render_state(device->wined3d_device, - WINED3D_RS_COLORWRITEENABLE1, desc->RenderTarget[1].RenderTargetWriteMask); - wined3d_device_set_render_state(device->wined3d_device, - WINED3D_RS_COLORWRITEENABLE2, desc->RenderTarget[2].RenderTargetWriteMask); - wined3d_device_set_render_state(device->wined3d_device, - WINED3D_RS_COLORWRITEENABLE3, desc->RenderTarget[3].RenderTargetWriteMask); + else + wined3d_device_set_blend_state(device->wined3d_device, blend_state_impl->wined3d_state, + (const struct wined3d_color *)blend_factor); wined3d_mutex_unlock(); }
diff --git a/dlls/d3d11/state.c b/dlls/d3d11/state.c index 85ee67e272..d48d62e0a8 100644 --- a/dlls/d3d11/state.c +++ b/dlls/d3d11/state.c @@ -344,10 +344,6 @@ HRESULT d3d_blend_state_create(struct d3d_device *device, const D3D11_BLEND_DESC tmp_desc.RenderTarget[i].BlendOpAlpha = D3D11_BLEND_OP_ADD; } tmp_desc.RenderTarget[i].RenderTargetWriteMask = desc->RenderTarget[j].RenderTargetWriteMask; - - if (i > 3 && tmp_desc.RenderTarget[i].RenderTargetWriteMask != D3D11_COLOR_WRITE_ENABLE_ALL) - FIXME("Color mask %#x not supported for render target %u.\n", - tmp_desc.RenderTarget[i].RenderTargetWriteMask, i); }
wined3d_mutex_lock(); @@ -395,6 +391,7 @@ HRESULT d3d_blend_state_create(struct d3d_device *device, const D3D11_BLEND_DESC 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; + wined3d_desc.rt[i].writemask = desc->RenderTarget[i].RenderTargetWriteMask; }
/* We cannot fail after creating a wined3d_blend_state object. It diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index 60c6e92cd9..0a076ef67d 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -29820,8 +29820,7 @@ static void test_color_mask(void) { get_texture_readback(rts[i], 0, &rb); color = get_readback_color(&rb, 320, 240, 0); - todo_wine_if (i >= 4) - ok(color == expected_colors[i], "%u: Got unexpected color 0x%08x.\n", i, color); + ok(color == expected_colors[i], "%u: Got unexpected color 0x%08x.\n", i, color); release_resource_readback(&rb); }
@@ -29839,8 +29838,7 @@ static void test_color_mask(void) { get_texture_readback(rts[i], 0, &rb); color = get_readback_color(&rb, 320, 240, 0); - todo_wine_if (i >= 4) - ok(color == expected_colors[0], "%u: Got unexpected color 0x%08x.\n", i, color); + ok(color == expected_colors[0], "%u: Got unexpected color 0x%08x.\n", i, color); release_resource_readback(&rb);
ID3D11Texture2D_Release(rts[i]); diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index eda09d95af..e4f174b9f1 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -3148,6 +3148,7 @@ void wined3d_context_gl_apply_blit_state(struct wined3d_context_gl *context_gl, gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_TEST); context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ZENABLE)); gl_info->gl_ops.gl.p_glDisable(GL_BLEND); + gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); context_invalidate_state(context, STATE_BLEND); gl_info->gl_ops.gl.p_glDisable(GL_CULL_FACE); gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST); @@ -3164,11 +3165,6 @@ void wined3d_context_gl_apply_blit_state(struct wined3d_context_gl *context_gl, gl_info->gl_ops.gl.p_glDisable(GL_FRAMEBUFFER_SRGB); context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE)); } - gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE)); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1)); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2)); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3));
context->last_was_rhw = TRUE; context_invalidate_state(context, STATE_VDECL); /* because of last_was_rhw = TRUE */ @@ -5158,7 +5154,7 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s if (!(rtv = fb->render_targets[i]) || rtv->format->id == WINED3DFMT_NULL) continue;
- if (state->render_states[WINED3D_RS_COLORWRITEENABLE]) + if (!state->blend_state || state->blend_state->desc.rt[0].writemask) { wined3d_rendertarget_view_load_location(rtv, context, rtv->resource->draw_binding); wined3d_rendertarget_view_invalidate_location(rtv, ~rtv->resource->draw_binding); diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 889aac0506..927c9456ec 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -437,10 +437,7 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c }
gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE)); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1)); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2)); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3)); + context_invalidate_state(context, STATE_BLEND); gl_info->gl_ops.gl.p_glClearColor(color->r, color->g, color->b, color->a); checkGLcall("glClearColor"); clear_mask = clear_mask | GL_COLOR_BUFFER_BIT; @@ -3589,6 +3586,10 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, case WINED3D_RS_SRCBLENDALPHA: case WINED3D_RS_DESTBLENDALPHA: case WINED3D_RS_BLENDOPALPHA: + case WINED3D_RS_COLORWRITEENABLE: + case WINED3D_RS_COLORWRITEENABLE1: + case WINED3D_RS_COLORWRITEENABLE2: + case WINED3D_RS_COLORWRITEENABLE3: set_blend_state = TRUE; break;
@@ -3676,6 +3677,26 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, desc.rt[0].dst_alpha = state->rs[WINED3D_RS_DESTBLEND]; desc.rt[0].op_alpha = state->rs[WINED3D_RS_BLENDOP]; } + desc.rt[0].writemask = state->rs[WINED3D_RS_COLORWRITEENABLE]; + desc.rt[1].writemask = state->rs[WINED3D_RS_COLORWRITEENABLE1]; + desc.rt[2].writemask = state->rs[WINED3D_RS_COLORWRITEENABLE2]; + desc.rt[3].writemask = state->rs[WINED3D_RS_COLORWRITEENABLE3]; + if (desc.rt[1].writemask != desc.rt[0].writemask + || desc.rt[2].writemask != desc.rt[0].writemask + || desc.rt[3].writemask != desc.rt[0].writemask) + { + desc.independent = TRUE; + for (i = 1; i < 4; ++i) + { + desc.rt[i].enable = desc.rt[0].enable; + desc.rt[i].src = desc.rt[0].src; + desc.rt[i].dst = desc.rt[0].dst; + desc.rt[i].op = desc.rt[0].op; + desc.rt[i].src_alpha = desc.rt[0].src_alpha; + desc.rt[i].dst_alpha = desc.rt[0].dst_alpha; + desc.rt[i].op_alpha = desc.rt[0].op_alpha; + } + }
if (wined3d_bitmap_is_set(changed->renderState, WINED3D_RS_BLENDFACTOR)) wined3d_color_from_d3dcolor(&colour, state->rs[WINED3D_RS_BLENDFACTOR]); diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index ad3ce37501..6289317936 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -567,6 +567,7 @@ static void blend(struct wined3d_context *context, const struct wined3d_state *s const struct wined3d_blend_state *b = state->blend_state; const struct wined3d_format *rt_format; GLenum src_blend, dst_blend; + unsigned int mask;
if (gl_info->supported[ARB_MULTISAMPLE]) { @@ -580,6 +581,14 @@ static void blend(struct wined3d_context *context, const struct wined3d_state *s if (b && b->desc.independent) WARN("Independent blend is not supported by this GL implementation.\n");
+ mask = b ? b->desc.rt[0].writemask : 0xf; + + gl_info->gl_ops.gl.p_glColorMask(mask & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE, + mask & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE, + mask & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE, + mask & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE); + checkGLcall("glColorMask"); + if (!b || !is_blend_enabled(context, state, 0)) { gl_info->gl_ops.gl.p_glDisable(GL_BLEND); @@ -625,6 +634,16 @@ static void blend(struct wined3d_context *context, const struct wined3d_state *s context_apply_state(context, state, STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP)); }
+static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DWORD mask) +{ + GL_EXTCALL(glColorMaski(index, + mask & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE, + mask & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE, + mask & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE, + mask & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE)); + checkGLcall("glColorMaski"); +} + 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; @@ -639,14 +658,7 @@ static void blend_db2(struct wined3d_context *context, const struct wined3d_stat gl_info->gl_ops.gl.p_glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE); checkGLcall("glEnable GL_SAMPLE_ALPHA_TO_COVERAGE");
- if (!b) - { - gl_info->gl_ops.gl.p_glDisable(GL_BLEND); - checkGLcall("glDisable GL_BLEND"); - return; - } - - if (!b->desc.independent) + if (!b || !b->desc.independent) { blend(context, state, state_id); return; @@ -665,6 +677,8 @@ static void blend_db2(struct wined3d_context *context, const struct wined3d_stat
for (i = 0; i < WINED3D_MAX_RENDER_TARGETS; ++i) { + set_color_mask(gl_info, i, b->desc.rt[i].writemask); + if (!is_blend_enabled(context, state, i)) { GL_EXTCALL(glDisablei(GL_BLEND, i)); @@ -702,14 +716,7 @@ static void blend_dbb(struct wined3d_context *context, const struct wined3d_stat gl_info->gl_ops.gl.p_glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE); checkGLcall("glEnable GL_SAMPLE_ALPHA_TO_COVERAGE");
- if (!b) - { - gl_info->gl_ops.gl.p_glDisable(GL_BLEND); - checkGLcall("glDisable GL_BLEND"); - return; - } - - if (!b->desc.independent) + if (!b || !b->desc.independent) { blend(context, state, state_id); return; @@ -720,6 +727,8 @@ static void blend_dbb(struct wined3d_context *context, const struct wined3d_stat GLenum src_blend, dst_blend, src_blend_alpha, dst_blend_alpha; const struct wined3d_format *rt_format;
+ set_color_mask(gl_info, i, b->desc.rt[i].writemask); + if (!is_blend_enabled(context, state, i)) { GL_EXTCALL(glDisablei(GL_BLEND, i)); @@ -1653,64 +1662,6 @@ static void state_debug_monitor(struct wined3d_context *context, const struct wi WARN("token: %#x.\n", state->render_states[WINED3D_RS_DEBUGMONITORTOKEN]); }
-static void state_colorwrite(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; - DWORD mask0 = state->render_states[WINED3D_RS_COLORWRITEENABLE]; - DWORD mask1 = state->render_states[WINED3D_RS_COLORWRITEENABLE1]; - DWORD mask2 = state->render_states[WINED3D_RS_COLORWRITEENABLE2]; - DWORD mask3 = state->render_states[WINED3D_RS_COLORWRITEENABLE3]; - - TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n", - mask0 & WINED3DCOLORWRITEENABLE_RED ? 1 : 0, - mask0 & WINED3DCOLORWRITEENABLE_GREEN ? 1 : 0, - mask0 & WINED3DCOLORWRITEENABLE_BLUE ? 1 : 0, - mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? 1 : 0); - gl_info->gl_ops.gl.p_glColorMask(mask0 & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE, - mask0 & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE, - mask0 & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE, - mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE); - checkGLcall("glColorMask(...)"); - - if (!((mask1 == mask0 && mask2 == mask0 && mask3 == mask0) - || (mask1 == 0xf && mask2 == 0xf && mask3 == 0xf))) - { - FIXME("WINED3D_RS_COLORWRITEENABLE/1/2/3, %#x/%#x/%#x/%#x not yet implemented.\n", - mask0, mask1, mask2, mask3); - FIXME("Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n"); - } -} - -static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DWORD mask) -{ - GL_EXTCALL(glColorMaski(index, - mask & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE, - mask & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE, - mask & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE, - mask & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE)); - checkGLcall("glColorMaski"); -} - -static void state_colorwrite0(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) -{ - set_color_mask(wined3d_context_gl(context)->gl_info, 0, state->render_states[WINED3D_RS_COLORWRITEENABLE]); -} - -static void state_colorwrite1(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) -{ - set_color_mask(wined3d_context_gl(context)->gl_info, 1, state->render_states[WINED3D_RS_COLORWRITEENABLE1]); -} - -static void state_colorwrite2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) -{ - set_color_mask(wined3d_context_gl(context)->gl_info, 2, state->render_states[WINED3D_RS_COLORWRITEENABLE2]); -} - -static void state_colorwrite3(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) -{ - set_color_mask(wined3d_context_gl(context)->gl_info, 3, state->render_states[WINED3D_RS_COLORWRITEENABLE3]); -} - static void state_localviewer(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; @@ -4766,14 +4717,6 @@ const struct wined3d_state_entry_template misc_state_template[] = { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), state_msaa_w }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), state_multisampmask }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), state_debug_monitor }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite0 }, EXT_DRAW_BUFFERS2 }, - { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), state_colorwrite1 }, EXT_DRAW_BUFFERS2 }, - { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), state_colorwrite2 }, EXT_DRAW_BUFFERS2 }, - { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), state_colorwrite3 }, EXT_DRAW_BUFFERS2 }, - { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_ZVISIBLE), { STATE_RENDER(WINED3D_RS_ZVISIBLE), state_zvisible }, WINED3D_GL_EXT_NONE }, /* Samplers */ { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler }, WINED3D_GL_EXT_NONE }, @@ -5538,10 +5481,10 @@ static void validate_state_table(struct wined3d_state_entry *state_table) { 47, 47}, { 61, 127}, {149, 150}, - {169, 169}, + {168, 169}, {171, 171}, {174, 177}, - {193, 193}, + {190, 193}, {195, 197}, {206, 209}, { 0, 0}, diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index b7dd54cb61..3745d8dde7 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -259,10 +259,7 @@ void texture2d_blt_fbo(struct wined3d_device *device, struct wined3d_context *co context_invalidate_state(context, STATE_FRAMEBUFFER);
gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE)); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1)); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2)); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3)); + context_invalidate_state(context, STATE_BLEND);
gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST); context_invalidate_state(context, STATE_RASTERIZER); diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 16800a8e40..0dd09f4a3f 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2040,6 +2040,7 @@ struct wined3d_blend_state_desc enum wined3d_blend src_alpha; enum wined3d_blend dst_alpha; enum wined3d_blend_op op_alpha; + unsigned int writemask; } rt[WINED3D_MAX_RENDER_TARGETS]; };
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=67043
Your paranoid android.
=== build (build log) ===
error: patch failed: dlls/d3d11/state.c:389 error: patch failed: dlls/wined3d/device.c:3657 error: patch failed: dlls/wined3d/state.c:426 error: patch failed: include/wine/wined3d.h:2029 error: patch failed: dlls/d3d11/device.c:718 error: patch failed: dlls/d3d11/state.c:344 error: patch failed: dlls/wined3d/device.c:3589 error: patch failed: dlls/wined3d/state.c:567 error: patch failed: include/wine/wined3d.h:2040 Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/d3d11/state.c:389 error: patch failed: dlls/wined3d/device.c:3657 error: patch failed: dlls/wined3d/state.c:426 error: patch failed: include/wine/wined3d.h:2029 error: patch failed: dlls/d3d11/device.c:718 error: patch failed: dlls/d3d11/state.c:344 error: patch failed: dlls/wined3d/device.c:3589 error: patch failed: dlls/wined3d/state.c:567 error: patch failed: include/wine/wined3d.h:2040 Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/d3d11/state.c:389 error: patch failed: dlls/wined3d/device.c:3657 error: patch failed: dlls/wined3d/state.c:426 error: patch failed: include/wine/wined3d.h:2029 error: patch failed: dlls/d3d11/device.c:718 error: patch failed: dlls/d3d11/state.c:344 error: patch failed: dlls/wined3d/device.c:3589 error: patch failed: dlls/wined3d/state.c:567 error: patch failed: include/wine/wined3d.h:2040 Task: Patch failed to apply
On Fri, 13 Mar 2020 at 08:02, Zebediah Figura z.figura12@gmail.com wrote:
@@ -5158,7 +5154,7 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s if (!(rtv = fb->render_targets[i]) || rtv->format->id == WINED3DFMT_NULL) continue;
if (state->render_states[WINED3D_RS_COLORWRITEENABLE])
if (!state->blend_state || state->blend_state->desc.rt[0].writemask) {
This is mostly an existing issue, but that should probably use "rt[i]" when independent blend states are enabled.
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=67042
Your paranoid android.
=== build (build log) ===
error: patch failed: dlls/d3d11/state.c:389 error: patch failed: dlls/wined3d/device.c:3657 error: patch failed: dlls/wined3d/state.c:426 error: patch failed: include/wine/wined3d.h:2029 Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/d3d11/state.c:389 error: patch failed: dlls/wined3d/device.c:3657 error: patch failed: dlls/wined3d/state.c:426 error: patch failed: include/wine/wined3d.h:2029 Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/d3d11/state.c:389 error: patch failed: dlls/wined3d/device.c:3657 error: patch failed: dlls/wined3d/state.c:426 error: patch failed: include/wine/wined3d.h:2029 Task: Patch failed to apply