From: DarkZeros Subject: Re: [PATCH] wined3d: Refactor blend factor from DWORD to wined3d_color Message-Id: Date: Thu, 11 Oct 2018 02:22:00 +0100 In-Reply-To: References: <20181008224736.8111-1-mailszeros@gmail.com> <80962284-cdab-c690-45aa-5cc267d1aeb6@gmail.com> After having gone trough the code a second time. I think the cleanest way to tackle this is that: - Keep D3D9 blend factor as is (if D3D9 and D3D11 functions will not be called on the same device, then this is safe) - Store the blend state, factor, and mask in "OMSetBlendState", and call "wined3d_device_set_blend_state" for storing the state, and emit the CS. - In the exec of blend state invalidate the Blend state and blend factor, calling the appropiate calls. This makes sense since for D3D11 the call OMSetBlendState does all the state & factor & mask change atomically. I have a draft patch here attached that works. I need to just write the tests for D3D11 El mar., 9 oct. 2018 a las 23:40, DarkZeros () escribió: > Hi, > > I think the best place is to put it under "wined3d_blend_state", not > inside the "wined3d_blend_state_desc". > And also reuse the CS of the blend state for the blend factor. > The only thing I am worried about is if we are setting the blend factor > each time the blend state is changed, even if they are unrelated. > > Also this patch as it currently is, is breaking some d3d state tests (just > the test, the blending works fine), because they will have to be updated to > check the new state area. > > I will do all the modifications soon and post another patch. > > Cheers. > > BR, > Daniel > > El mar., 9 oct. 2018 a las 19:28, Stefan Dösinger (< > stefandoesinger@gmail.com>) escribió: > >> Hi, >> >> Am 2018-10-09 um 16:31 schrieb Henri Verbeet: >> > Hi Daniel, thank you for the patch. Unfortunately the blend factor >> > should be part of the wined3d_blend_state object >> Are you sure this is the way to go? Creating a blend state object for >> every possible color combination seems highly inefficient. >> >> It could work if we add a setter to change the blend factor after >> creating a wined3d blend state object, but I don't see an advantage over >> Daniel's approach. >> >
After having gone trough the code a second time. I think the cleanest way to tackle this is that:
- Keep D3D9 blend factor as is (if D3D9 and D3D11 functions will not be called on the same device, then this is safe)
- Store the blend state, factor, and mask in "OMSetBlendState", and call "wined3d_device_set_blend_state" for storing the state, and emit the CS.
- In the exec of blend state invalidate the Blend state and blend factor, calling the appropiate calls. This makes sense since for D3D11 the call OMSetBlendState does all the state & factor & mask change atomically.

I have a draft patch here attached that works. I need to just write the tests for D3D11

El mar., 9 oct. 2018 a las 23:40, DarkZeros (<mailszeros@gmail.com>) escribió:
Hi,

I think the best place is to put it under "wined3d_blend_state", not inside the "wined3d_blend_state_desc".
And also reuse the CS of the blend state for the blend factor.
The only thing I am worried about is if we are setting the blend factor each time the blend state is changed, even if they are unrelated.

Also this patch as it currently is, is breaking some d3d state tests (just the test, the blending works fine), because they will have to be updated to check the new state area.

I will do all the modifications soon and post another patch.

Cheers.

BR,
Daniel

El mar., 9 oct. 2018 a las 19:28, Stefan Dösinger (<stefandoesinger@gmail.com>) escribió:
Hi,

Am 2018-10-09 um 16:31 schrieb Henri Verbeet:
> Hi Daniel, thank you for the patch. Unfortunately the blend factor
> should be part of the wined3d_blend_state object
Are you sure this is the way to go? Creating a blend state object for
every possible color combination seems highly inefficient.

It could work if we add a setter to change the blend factor after
creating a wined3d blend state object, but I don't see an advantage over
Daniel's approach.
From 026c58f52f98dc2aa2c6fb05c8254d70d4fa6181 Mon Sep 17 00:00:00 2001 From: Daniel Ansorregui Date: Sun, 7 Oct 2018 20:30:58 +0100 Subject: [PATCH] wined3d: Add blend_factor to blend_state Signed-off-by: Daniel Ansorregui --- dlls/d3d11/device.c | 13 ++++--------- dlls/wined3d/cs.c | 8 +++++++- dlls/wined3d/device.c | 10 ++++++---- dlls/wined3d/state.c | 19 +++++++++++++++---- dlls/wined3d/utils.c | 2 ++ dlls/wined3d/wined3d.spec | 2 +- dlls/wined3d/wined3d_private.h | 9 +++++++-- include/wine/wined3d.h | 3 ++- 8 files changed, 44 insertions(+), 22 deletions(-) diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 157ff0341a..aab0c53bfa 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -714,7 +714,8 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_OMSetBlendState(ID3D11Devi 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); + 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_ALPHABLENDENABLE, FALSE); wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_COLORWRITEENABLE, D3D11_COLOR_WRITE_ENABLE_ALL); @@ -728,7 +729,8 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_OMSetBlendState(ID3D11Devi return; } - wined3d_device_set_blend_state(device->wined3d_device, blend_state_impl->wined3d_state); + 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_ALPHABLENDENABLE, desc->RenderTarget[0].BlendEnable); @@ -743,13 +745,6 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_OMSetBlendState(ID3D11Devi wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_SRCBLENDALPHA, d->SrcBlendAlpha); wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_DESTBLENDALPHA, d->DestBlendAlpha); wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_BLENDOPALPHA, d->BlendOpAlpha); - - if (memcmp(blend_factor, default_blend_factor, sizeof(default_blend_factor)) - && (d->SrcBlend == D3D11_BLEND_BLEND_FACTOR || d->SrcBlend == D3D11_BLEND_INV_BLEND_FACTOR - || d->DestBlend == D3D11_BLEND_BLEND_FACTOR || d->DestBlend == D3D11_BLEND_INV_BLEND_FACTOR - || d->SrcBlendAlpha == D3D11_BLEND_BLEND_FACTOR || d->SrcBlendAlpha == D3D11_BLEND_INV_BLEND_FACTOR - || d->DestBlendAlpha == D3D11_BLEND_BLEND_FACTOR || d->DestBlendAlpha == D3D11_BLEND_INV_BLEND_FACTOR)) - FIXME("Ignoring blend factor %s.\n", debug_float4(blend_factor)); } wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_COLORWRITEENABLE, desc->RenderTarget[0].RenderTargetWriteMask); diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index af1dbef84c..96f704f84f 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -264,6 +264,7 @@ struct wined3d_cs_set_blend_state { enum wined3d_cs_op opcode; struct wined3d_blend_state *state; + struct wined3d_color factor; }; struct wined3d_cs_set_rasterizer_state @@ -1542,15 +1543,20 @@ static void wined3d_cs_exec_set_blend_state(struct wined3d_cs *cs, const void *d cs->state.blend_state = op->state; device_invalidate_state(cs->device, STATE_BLEND); + + cs->state.blend_factor = op->factor; + device_invalidate_state(cs->device, STATE_BLENDFACTOR); } -void wined3d_cs_emit_set_blend_state(struct wined3d_cs *cs, struct wined3d_blend_state *state) +void wined3d_cs_emit_set_blend_state(struct wined3d_cs *cs, struct wined3d_blend_state *state, + const struct wined3d_color *blend_factor) { struct wined3d_cs_set_blend_state *op; op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_BLEND_STATE; op->state = state; + op->factor = *blend_factor; cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index abb2a89363..709fa7ff0a 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1968,20 +1968,22 @@ static void resolve_depth_buffer(struct wined3d_device *device) src_view->resource, src_view->sub_resource_idx, dst_resource->format->id); } -void CDECL wined3d_device_set_blend_state(struct wined3d_device *device, struct wined3d_blend_state *blend_state) +void CDECL wined3d_device_set_blend_state(struct wined3d_device *device, struct wined3d_blend_state *blend_state, + const struct wined3d_color *blend_factor) { struct wined3d_blend_state *prev; - TRACE("device %p, blend_state %p.\n", device, blend_state); + TRACE("device %p, blend_state %p, blend_factor %s.\n", device, blend_state, debug_color(blend_factor)); prev = device->update_state->blend_state; - if (prev == blend_state) + if (prev == blend_state && !memcmp(blend_factor, &device->update_state->blend_factor, sizeof(*blend_factor))) return; if (blend_state) wined3d_blend_state_incref(blend_state); device->update_state->blend_state = blend_state; - wined3d_cs_emit_set_blend_state(device->cs, blend_state); + device->update_state->blend_factor = *blend_factor; + wined3d_cs_emit_set_blend_state(device->cs, blend_state, blend_factor); if (prev) wined3d_blend_state_decref(prev); } diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 375bc6562a..4e8a42d9d4 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -597,12 +597,12 @@ 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_blendfactor_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +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_blendfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +static void state_blend_factor_i(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const struct wined3d_gl_info *gl_info = context->gl_info; struct wined3d_color color; @@ -614,6 +614,16 @@ static void state_blendfactor(struct wined3d_context *context, const struct wine checkGLcall("glBlendColor"); } +static void state_blend_factor_f(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + + TRACE("Setting blend factor to %s.\n", debug_color(&state->blend_factor)); + + GL_EXTCALL(glBlendColor(state->blend_factor.r, state->blend_factor.g, state->blend_factor.b, state->blend_factor.a)); + checkGLcall("glBlendColor"); +} + static void state_blend_object(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const struct wined3d_gl_info *gl_info = context->gl_info; @@ -4539,6 +4549,7 @@ const struct StateEntryTemplate misc_state_template[] = { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_BLENDOPALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_BLEND, { STATE_BLEND, state_blend_object }, WINED3D_GL_EXT_NONE }, + { STATE_BLENDFACTOR, { STATE_BLENDFACTOR, state_blend_factor_f}, WINED3D_GL_EXT_NONE }, { STATE_STREAMSRC, { STATE_STREAMSRC, streamsrc }, WINED3D_GL_EXT_NONE }, { STATE_VDECL, { STATE_VDECL, vdecl_miscpart }, WINED3D_GL_EXT_NONE }, { STATE_RASTERIZER, { STATE_RASTERIZER, rasterizer_cc }, ARB_CLIP_CONTROL }, @@ -4689,8 +4700,8 @@ const struct StateEntryTemplate misc_state_template[] = { 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_BLENDFACTOR), { STATE_RENDER(WINED3D_RS_BLENDFACTOR), state_blendfactor }, EXT_BLEND_COLOR }, - { STATE_RENDER(WINED3D_RS_BLENDFACTOR), { STATE_RENDER(WINED3D_RS_BLENDFACTOR), state_blendfactor_w }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3D_RS_BLENDFACTOR), { STATE_RENDER(WINED3D_RS_BLENDFACTOR), state_blend_factor_i}, EXT_BLEND_COLOR }, + { STATE_RENDER(WINED3D_RS_BLENDFACTOR), { STATE_RENDER(WINED3D_RS_BLENDFACTOR), state_blend_factor_w}, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_DEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), state_depthbias }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_ZVISIBLE), { STATE_RENDER(WINED3D_RS_ZVISIBLE), state_zvisible }, WINED3D_GL_EXT_NONE }, /* Samplers */ diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index e3df24ade4..02b63970b3 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -4965,6 +4965,8 @@ const char *debug_d3dstate(DWORD state) return "STATE_STREAM_OUTPUT"; if (STATE_IS_BLEND(state)) return "STATE_BLEND"; + if (STATE_IS_BLENDFACTOR(state)) + return "STATE_BLENDFACTOR"; return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state); } diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 7944387bca..948e47c3f5 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -129,7 +129,7 @@ @ cdecl wined3d_device_resolve_sub_resource(ptr ptr long ptr long long) @ cdecl wined3d_device_restore_fullscreen_window(ptr ptr ptr) @ cdecl wined3d_device_set_base_vertex_index(ptr long) -@ cdecl wined3d_device_set_blend_state(ptr ptr) +@ cdecl wined3d_device_set_blend_state(ptr ptr ptr) @ cdecl wined3d_device_set_clip_plane(ptr long ptr) @ cdecl wined3d_device_set_clip_status(ptr ptr) @ cdecl wined3d_device_set_compute_shader(ptr ptr) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 19945cf30e..1264514af7 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1645,7 +1645,10 @@ enum wined3d_pipeline #define STATE_BLEND (STATE_STREAM_OUTPUT + 1) #define STATE_IS_BLEND(a) ((a) == STATE_BLEND) -#define STATE_COMPUTE_OFFSET (STATE_BLEND + 1) +#define STATE_BLENDFACTOR (STATE_BLEND + 1) +#define STATE_IS_BLENDFACTOR(a) ((a) == STATE_BLENDFACTOR) + +#define STATE_COMPUTE_OFFSET (STATE_BLENDFACTOR + 1) #define STATE_COMPUTE_SHADER (STATE_COMPUTE_OFFSET) #define STATE_IS_COMPUTE_SHADER(a) ((a) == STATE_COMPUTE_SHADER) @@ -2934,6 +2937,7 @@ struct wined3d_state DWORD render_states[WINEHIGHEST_RENDER_STATE + 1]; struct wined3d_blend_state *blend_state; + struct wined3d_color blend_factor; struct wined3d_rasterizer_state *rasterizer_state; }; @@ -3643,7 +3647,8 @@ void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *sw const RECT *dst_rect, HWND dst_window_override, unsigned int swap_interval, DWORD flags) DECLSPEC_HIDDEN; void wined3d_cs_emit_query_issue(struct wined3d_cs *cs, struct wined3d_query *query, DWORD flags) DECLSPEC_HIDDEN; void wined3d_cs_emit_reset_state(struct wined3d_cs *cs) DECLSPEC_HIDDEN; -void wined3d_cs_emit_set_blend_state(struct wined3d_cs *cs, struct wined3d_blend_state *state) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_blend_state(struct wined3d_cs *cs, struct wined3d_blend_state *state, + const struct wined3d_color *blend_factor) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_clip_plane(struct wined3d_cs *cs, UINT plane_idx, const struct wined3d_vec4 *plane) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture *texture, diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index c62d3640e5..884783e0ca 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2379,7 +2379,8 @@ void __cdecl wined3d_device_resolve_sub_resource(struct wined3d_device *device, void __cdecl wined3d_device_restore_fullscreen_window(struct wined3d_device *device, HWND window, const RECT *window_rect); void __cdecl wined3d_device_set_base_vertex_index(struct wined3d_device *device, INT base_index); -void __cdecl wined3d_device_set_blend_state(struct wined3d_device *device, struct wined3d_blend_state *blend_state); +void __cdecl wined3d_device_set_blend_state(struct wined3d_device *device, struct wined3d_blend_state *blend_state, + const struct wined3d_color *blend_factor); HRESULT __cdecl wined3d_device_set_clip_plane(struct wined3d_device *device, UINT plane_idx, const struct wined3d_vec4 *plane); HRESULT __cdecl wined3d_device_set_clip_status(struct wined3d_device *device, -- 2.17.1