Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/wined3d/device.c | 92 ++++++++++++++++++++-------------- dlls/wined3d/stateblock.c | 45 ++++------------- dlls/wined3d/wined3d_private.h | 6 +-- include/wine/wined3d.h | 2 +- 4 files changed, 68 insertions(+), 77 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index bcad597178..c3775934ca 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -528,6 +528,13 @@ static void device_free_rasterizer_state(struct wine_rb_entry *entry, void *cont wined3d_rasterizer_state_decref(state); }
+static void device_free_blend_state(struct wine_rb_entry *entry, void *context) +{ + struct wined3d_blend_state *state = WINE_RB_ENTRY_VALUE(entry, struct wined3d_blend_state, entry); + + wined3d_blend_state_decref(state); +} + void wined3d_device_cleanup(struct wined3d_device *device) { unsigned int i; @@ -535,8 +542,8 @@ void wined3d_device_cleanup(struct wined3d_device *device) if (device->swapchain_count) wined3d_device_uninit_3d(device);
- wined3d_blend_state_decref(device->blend_state_atoc_enabled); wine_rb_destroy(&device->rasterizer_states, device_free_rasterizer_state, NULL); + wine_rb_destroy(&device->blend_states, device_free_blend_state, NULL);
wined3d_cs_destroy(device->cs);
@@ -3485,10 +3492,8 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, const struct wined3d_stateblock_state *state = &stateblock->stateblock_state; const struct wined3d_saved_states *changed = &stateblock->changed; const unsigned int word_bit_count = sizeof(DWORD) * CHAR_BIT; - BOOL set_blend_state, set_rasterizer_state = FALSE; - struct wined3d_blend_state *blend_state; + BOOL set_blend_state = FALSE, set_rasterizer_state = FALSE; unsigned int i, j, start, idx; - struct wined3d_color colour; struct wined3d_range range; DWORD map, stage;
@@ -3565,20 +3570,6 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, } }
- if ((set_blend_state = changed->blend_state - || wined3d_bitmap_is_set(changed->renderState, WINED3D_RS_ADAPTIVETESS_Y))) - { - blend_state = state->rs[WINED3D_RS_ADAPTIVETESS_Y] == WINED3DFMT_ATOC - ? device->blend_state_atoc_enabled : state->blend_state; - - if (wined3d_bitmap_is_set(changed->renderState, WINED3D_RS_BLENDFACTOR)) - wined3d_color_from_d3dcolor(&colour, stateblock->stateblock_state.rs[WINED3D_RS_BLENDFACTOR]); - else - wined3d_device_get_blend_state(device, &colour); - - wined3d_device_set_blend_state(device, blend_state, &colour); - } - for (i = 0; i < ARRAY_SIZE(changed->renderState); ++i) { map = changed->renderState[i]; @@ -3590,12 +3581,7 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, switch (idx) { case WINED3D_RS_BLENDFACTOR: - if (!set_blend_state) - { - blend_state = wined3d_device_get_blend_state(device, &colour); - wined3d_color_from_d3dcolor(&colour, state->rs[idx]); - wined3d_device_set_blend_state(device, blend_state, &colour); - } + set_blend_state = TRUE; break;
case WINED3D_RS_FILLMODE: @@ -3653,6 +3639,41 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, } }
+ if (set_blend_state || changed->alpha_to_coverage + || wined3d_bitmap_is_set(changed->renderState, WINED3D_RS_ADAPTIVETESS_Y)) + { + struct wined3d_blend_state *blend_state; + struct wined3d_blend_state_desc desc; + struct wine_rb_entry *entry; + struct wined3d_color colour; + + memset(&desc, 0, sizeof(desc)); + desc.alpha_to_coverage = state->alpha_to_coverage; + if (state->rs[WINED3D_RS_ADAPTIVETESS_Y] == WINED3DFMT_ATOC) + desc.alpha_to_coverage = TRUE; + + if (wined3d_bitmap_is_set(changed->renderState, WINED3D_RS_BLENDFACTOR)) + wined3d_color_from_d3dcolor(&colour, state->rs[WINED3D_RS_BLENDFACTOR]); + else + wined3d_device_get_blend_state(device, &colour); + + if ((entry = wine_rb_get(&device->blend_states, &desc))) + { + blend_state = WINE_RB_ENTRY_VALUE(entry, struct wined3d_blend_state, entry); + wined3d_device_set_blend_state(device, blend_state, &colour); + } + else if (SUCCEEDED(wined3d_blend_state_create(device, &desc, NULL, + &wined3d_null_parent_ops, &blend_state))) + { + wined3d_device_set_blend_state(device, blend_state, &colour); + if (wine_rb_put(&device->blend_states, &desc, &blend_state->entry) == -1) + { + ERR("Failed to insert blend state.\n"); + wined3d_blend_state_decref(blend_state); + } + } + } + for (i = 0; i < ARRAY_SIZE(changed->textureState); ++i) { map = changed->textureState[i]; @@ -5459,6 +5480,13 @@ static int wined3d_rasterizer_state_compare(const void *key, const struct wine_r return memcmp(&state->desc, key, sizeof(state->desc)); }
+static int wined3d_blend_state_compare(const void *key, const struct wine_rb_entry *entry) +{ + const struct wined3d_blend_state *state = WINE_RB_ENTRY_VALUE(entry, struct wined3d_blend_state, entry); + + return memcmp(&state->desc, key, sizeof(state->desc)); +} + static BOOL wined3d_select_feature_level(const struct wined3d_adapter *adapter, const enum wined3d_feature_level *levels, unsigned int level_count, enum wined3d_feature_level *selected_level) @@ -5488,7 +5516,6 @@ HRESULT wined3d_device_init(struct wined3d_device *device, struct wined3d *wined struct wined3d_adapter *adapter = wined3d->adapters[adapter_idx]; const struct wined3d_fragment_pipe_ops *fragment_pipeline; const struct wined3d_vertex_pipe_ops *vertex_pipeline; - struct wined3d_blend_state_desc blend_state_desc; unsigned int i; HRESULT hr;
@@ -5520,6 +5547,7 @@ HRESULT wined3d_device_init(struct wined3d_device *device, struct wined3d *wined
wine_rb_init(&device->samplers, wined3d_sampler_compare); wine_rb_init(&device->rasterizer_states, wined3d_rasterizer_state_compare); + wine_rb_init(&device->blend_states, wined3d_blend_state_compare);
if (vertex_pipeline->vp_states && fragment_pipeline->states && FAILED(hr = compile_state_table(device->state_table, device->multistate_funcs, @@ -5529,6 +5557,7 @@ HRESULT wined3d_device_init(struct wined3d_device *device, struct wined3d *wined ERR("Failed to compile state table, hr %#x.\n", hr); wine_rb_destroy(&device->samplers, NULL, NULL); wine_rb_destroy(&device->rasterizer_states, NULL, NULL); + wine_rb_destroy(&device->blend_states, NULL, NULL); wined3d_decref(device->wined3d); return hr; } @@ -5545,18 +5574,6 @@ HRESULT wined3d_device_init(struct wined3d_device *device, struct wined3d *wined goto err; }
- memset(&blend_state_desc, 0, sizeof(blend_state_desc)); - blend_state_desc.alpha_to_coverage = TRUE; - - if (FAILED(hr = wined3d_blend_state_create(device, &blend_state_desc, - NULL, &wined3d_null_parent_ops, &device->blend_state_atoc_enabled))) - { - ERR("Failed to create blend state object, hr %#x.\n", hr); - wined3d_cs_destroy(device->cs); - state_cleanup(&device->state); - goto err; - } - return WINED3D_OK;
err: @@ -5566,6 +5583,7 @@ err: } wine_rb_destroy(&device->samplers, NULL, NULL); wine_rb_destroy(&device->rasterizer_states, NULL, NULL); + wine_rb_destroy(&device->blend_states, NULL, NULL); wined3d_decref(device->wined3d); return hr; } diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 70943afdda..248f413f62 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -208,7 +208,7 @@ static void stateblock_savedstates_set_all(struct wined3d_saved_states *states, states->pixelShader = 1; states->vertexShader = 1; states->scissorRect = 1; - states->blend_state = 1; + states->alpha_to_coverage = 1; states->lights = 1; states->transforms = 1;
@@ -263,7 +263,7 @@ static void stateblock_savedstates_set_vertex(struct wined3d_saved_states *state
states->vertexDecl = 1; states->vertexShader = 1; - states->blend_state = 1; + states->alpha_to_coverage = 1; states->lights = 1;
for (i = 0; i < ARRAY_SIZE(vertex_states_render); ++i) @@ -479,7 +479,6 @@ void wined3d_stateblock_state_cleanup(struct wined3d_stateblock_state *state) { struct wined3d_light_info *light, *cursor; struct wined3d_vertex_declaration *decl; - struct wined3d_blend_state *blend_state; struct wined3d_texture *texture; struct wined3d_buffer *buffer; struct wined3d_shader *shader; @@ -535,12 +534,6 @@ void wined3d_stateblock_state_cleanup(struct wined3d_stateblock_state *state) heap_free(light); } } - - if ((blend_state = state->blend_state)) - { - state->blend_state = NULL; - wined3d_blend_state_decref(blend_state); - } }
void state_cleanup(struct wined3d_state *state) @@ -974,14 +967,8 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock, if (stateblock->changed.lights) wined3d_state_record_lights(stateblock->stateblock_state.light_state, state->light_state);
- if (stateblock->changed.blend_state && stateblock->stateblock_state.blend_state != state->blend_state) - { - if (state->blend_state) - wined3d_blend_state_incref(state->blend_state); - if (stateblock->stateblock_state.blend_state) - wined3d_blend_state_decref(stateblock->stateblock_state.blend_state); - stateblock->stateblock_state.blend_state = state->blend_state; - } + if (stateblock->changed.alpha_to_coverage) + stateblock->stateblock_state.alpha_to_coverage = state->alpha_to_coverage;
TRACE("Capture done.\n"); } @@ -1058,14 +1045,10 @@ void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock, wined3d_stateblock_set_ps_consts_b(device_state, range.offset, range.size, &state->ps_consts_b[range.offset]); }
- if (stateblock->changed.blend_state) + if (stateblock->changed.alpha_to_coverage) { - if (state->blend_state) - wined3d_blend_state_incref(state->blend_state); - if (device_state->stateblock_state.blend_state) - wined3d_blend_state_decref(device_state->stateblock_state.blend_state); - device_state->stateblock_state.blend_state = state->blend_state; - device_state->changed.blend_state = 1; + device_state->stateblock_state.alpha_to_coverage = state->alpha_to_coverage; + device_state->changed.alpha_to_coverage = 1; }
/* Render states. */ @@ -1359,18 +1342,8 @@ void CDECL wined3d_stateblock_set_render_state(struct wined3d_stateblock *stateb if (state == WINED3D_RS_POINTSIZE && (value == WINED3D_ALPHA_TO_COVERAGE_ENABLE || value == WINED3D_ALPHA_TO_COVERAGE_DISABLE)) { - stateblock->changed.blend_state = 1; - - if (value == WINED3D_ALPHA_TO_COVERAGE_ENABLE && !stateblock->stateblock_state.blend_state) - { - wined3d_blend_state_incref(stateblock->device->blend_state_atoc_enabled); - stateblock->stateblock_state.blend_state = stateblock->device->blend_state_atoc_enabled; - } - else if (value == WINED3D_ALPHA_TO_COVERAGE_DISABLE && stateblock->stateblock_state.blend_state) - { - wined3d_blend_state_decref(stateblock->stateblock_state.blend_state); - stateblock->stateblock_state.blend_state = NULL; - } + stateblock->changed.alpha_to_coverage = 1; + stateblock->stateblock_state.alpha_to_coverage = (value == WINED3D_ALPHA_TO_COVERAGE_ENABLE); } }
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 5c00883d41..4034ed28f0 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3144,6 +3144,7 @@ struct wined3d_blend_state const struct wined3d_parent_ops *parent_ops;
struct wined3d_device *device; + struct wine_rb_entry entry; };
struct wined3d_rasterizer_state @@ -3294,7 +3295,7 @@ struct wined3d_device
struct list resources; /* a linked list to track resources created by the device */ struct list shaders; /* a linked list to track shaders (pixel and vertex) */ - struct wine_rb_tree samplers, rasterizer_states; + struct wine_rb_tree samplers, rasterizer_states, blend_states;
/* Render Target Support */ struct wined3d_fb_state fb; @@ -3322,7 +3323,6 @@ struct wined3d_device /* Context management */ struct wined3d_context **contexts; UINT context_count; - struct wined3d_blend_state *blend_state_atoc_enabled; };
void wined3d_device_cleanup(struct wined3d_device *device) DECLSPEC_HIDDEN; @@ -3941,7 +3941,7 @@ struct wined3d_saved_states DWORD vertexShader : 1; DWORD scissorRect : 1; DWORD store_stream_offset : 1; - DWORD blend_state : 1; + DWORD alpha_to_coverage : 1; DWORD lights : 1; DWORD transforms : 1; DWORD padding : 1; diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index fbcc6bb332..571e3d8d35 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2163,6 +2163,7 @@ struct wined3d_stateblock_state BOOL ps_consts_b[WINED3D_MAX_CONSTS_B];
DWORD rs[WINEHIGHEST_RENDER_STATE + 1]; + BOOL alpha_to_coverage;
struct wined3d_texture *textures[WINED3D_MAX_COMBINED_SAMPLERS]; DWORD sampler_states[WINED3D_MAX_COMBINED_SAMPLERS][WINED3D_HIGHEST_SAMPLER_STATE + 1]; @@ -2175,7 +2176,6 @@ struct wined3d_stateblock_state RECT scissor_rect;
struct wined3d_light_state *light_state; - struct wined3d_blend_state *blend_state; };
struct wined3d_parent_ops