Signed-off-by: Zebediah Figura z.figura12@gmail.com --- v3: Actually send the right patches this time...
dlls/wined3d/adapter_vk.c | 1 + dlls/wined3d/cs.c | 29 +++++++++++ dlls/wined3d/device.c | 53 ++++++++++++++++++++ dlls/wined3d/directx.c | 1 + dlls/wined3d/state.c | 90 ++++++++++++++++++++++++++++++++++ dlls/wined3d/wined3d.spec | 7 +++ dlls/wined3d/wined3d_private.h | 22 ++++++++- include/wine/wined3d.h | 17 +++++++ 8 files changed, 218 insertions(+), 2 deletions(-)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c index 0736b984920..f3a8d8f89db 100644 --- a/dlls/wined3d/adapter_vk.c +++ b/dlls/wined3d/adapter_vk.c @@ -42,6 +42,7 @@ static const struct wined3d_state_entry_template misc_state_template_vk[] = {STATE_SAMPLE_MASK, {STATE_SAMPLE_MASK, state_nop}}, {STATE_STREAMSRC, {STATE_STREAMSRC, state_nop}}, {STATE_VDECL, {STATE_VDECL, state_nop}}, + {STATE_DEPTH_STENCIL, {STATE_DEPTH_STENCIL, state_nop}}, {STATE_RASTERIZER, {STATE_RASTERIZER, state_nop}}, {STATE_SCISSORRECT, {STATE_SCISSORRECT, state_nop}}, {STATE_POINTSPRITECOORDORIGIN, {STATE_POINTSPRITECOORDORIGIN, state_nop}}, diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index fdecea2d020..d6a78cc5d65 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -50,6 +50,7 @@ enum wined3d_cs_op WINED3D_CS_OP_SET_SAMPLER, WINED3D_CS_OP_SET_SHADER, WINED3D_CS_OP_SET_BLEND_STATE, + WINED3D_CS_OP_SET_DEPTH_STENCIL_STATE, WINED3D_CS_OP_SET_RASTERIZER_STATE, WINED3D_CS_OP_SET_RENDER_STATE, WINED3D_CS_OP_SET_TEXTURE_STATE, @@ -269,6 +270,12 @@ struct wined3d_cs_set_blend_state unsigned int sample_mask; };
+struct wined3d_cs_set_depth_stencil_state +{ + enum wined3d_cs_op opcode; + struct wined3d_depth_stencil_state *state; +}; + struct wined3d_cs_set_rasterizer_state { enum wined3d_cs_op opcode; @@ -485,6 +492,7 @@ static const char *debug_cs_op(enum wined3d_cs_op op) WINED3D_TO_STR(WINED3D_CS_OP_SET_SAMPLER); WINED3D_TO_STR(WINED3D_CS_OP_SET_SHADER); WINED3D_TO_STR(WINED3D_CS_OP_SET_BLEND_STATE); + WINED3D_TO_STR(WINED3D_CS_OP_SET_DEPTH_STENCIL_STATE); WINED3D_TO_STR(WINED3D_CS_OP_SET_RASTERIZER_STATE); WINED3D_TO_STR(WINED3D_CS_OP_SET_RENDER_STATE); WINED3D_TO_STR(WINED3D_CS_OP_SET_TEXTURE_STATE); @@ -1655,6 +1663,26 @@ void wined3d_cs_emit_set_blend_state(struct wined3d_cs *cs, struct wined3d_blend wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); }
+static void wined3d_cs_exec_set_depth_stencil_state(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_set_depth_stencil_state *op = data; + + cs->state.depth_stencil_state = op->state; + device_invalidate_state(cs->device, STATE_DEPTH_STENCIL); +} + +void wined3d_cs_emit_set_depth_stencil_state(struct wined3d_cs *cs, + struct wined3d_depth_stencil_state *state) +{ + struct wined3d_cs_set_depth_stencil_state *op; + + op = wined3d_cs_require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_SET_DEPTH_STENCIL_STATE; + op->state = state; + + wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT); +} + static void wined3d_cs_exec_set_rasterizer_state(struct wined3d_cs *cs, const void *data) { const struct wined3d_cs_set_rasterizer_state *op = data; @@ -2606,6 +2634,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void /* WINED3D_CS_OP_SET_SAMPLER */ wined3d_cs_exec_set_sampler, /* WINED3D_CS_OP_SET_SHADER */ wined3d_cs_exec_set_shader, /* WINED3D_CS_OP_SET_BLEND_STATE */ wined3d_cs_exec_set_blend_state, + /* WINED3D_CS_OP_SET_DEPTH_STENCIL_STATE */ wined3d_cs_exec_set_depth_stencil_state, /* WINED3D_CS_OP_SET_RASTERIZER_STATE */ wined3d_cs_exec_set_rasterizer_state, /* WINED3D_CS_OP_SET_RENDER_STATE */ wined3d_cs_exec_set_render_state, /* WINED3D_CS_OP_SET_TEXTURE_STATE */ wined3d_cs_exec_set_texture_state, diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 9080426695f..a59a1efeab7 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -197,6 +197,13 @@ static void device_leftover_blend_state(struct wine_rb_entry *entry, void *conte ERR("Leftover blend state %p.\n", blend_state); }
+static void device_leftover_depth_stencil_state(struct wine_rb_entry *entry, void *context) +{ + struct wined3d_depth_stencil_state *state = WINE_RB_ENTRY_VALUE(entry, struct wined3d_depth_stencil_state, entry); + + ERR("Leftover depth/stencil state %p.\n", state); +} + void wined3d_device_cleanup(struct wined3d_device *device) { unsigned int i; @@ -234,6 +241,7 @@ void wined3d_device_cleanup(struct wined3d_device *device) wine_rb_destroy(&device->samplers, device_leftover_sampler, NULL); wine_rb_destroy(&device->rasterizer_states, device_leftover_rasterizer_state, NULL); wine_rb_destroy(&device->blend_states, device_leftover_blend_state, NULL); + wine_rb_destroy(&device->depth_stencil_states, device_leftover_depth_stencil_state, NULL);
wined3d_decref(device->wined3d); device->wined3d = NULL; @@ -1157,6 +1165,13 @@ static void device_free_blend_state(struct wine_rb_entry *entry, void *context) wined3d_blend_state_decref(blend_state); }
+static void device_free_depth_stencil_state(struct wine_rb_entry *entry, void *context) +{ + struct wined3d_depth_stencil_state *state = WINE_RB_ENTRY_VALUE(entry, struct wined3d_depth_stencil_state, entry); + + wined3d_depth_stencil_state_decref(state); +} + void wined3d_device_uninit_3d(struct wined3d_device *device) { struct wined3d_resource *resource, *cursor; @@ -1745,6 +1760,32 @@ struct wined3d_blend_state * CDECL wined3d_device_get_blend_state(const struct w return state->blend_state; }
+void CDECL wined3d_device_set_depth_stencil_state(struct wined3d_device *device, + struct wined3d_depth_stencil_state *state) +{ + struct wined3d_depth_stencil_state *prev; + + TRACE("device %p, state %p.\n", device, state); + + prev = device->state.depth_stencil_state; + if (prev == state) + return; + + if (state) + wined3d_depth_stencil_state_incref(state); + device->state.depth_stencil_state = state; + wined3d_cs_emit_set_depth_stencil_state(device->cs, state); + if (prev) + wined3d_depth_stencil_state_decref(prev); +} + +struct wined3d_depth_stencil_state * CDECL wined3d_device_get_depth_stencil_state(const struct wined3d_device *device) +{ + TRACE("device %p.\n", device); + + return device->state.depth_stencil_state; +} + void CDECL wined3d_device_set_rasterizer_state(struct wined3d_device *device, struct wined3d_rasterizer_state *rasterizer_state) { @@ -5391,6 +5432,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, wine_rb_clear(&device->samplers, device_free_sampler, NULL); wine_rb_clear(&device->rasterizer_states, device_free_rasterizer_state, NULL); wine_rb_clear(&device->blend_states, device_free_blend_state, NULL); + wine_rb_clear(&device->depth_stencil_states, device_free_depth_stencil_state, NULL);
if (reset_state) { @@ -5584,6 +5626,14 @@ static int wined3d_blend_state_compare(const void *key, const struct wine_rb_ent return memcmp(&state->desc, key, sizeof(state->desc)); }
+static int wined3d_depth_stencil_state_compare(const void *key, const struct wine_rb_entry *entry) +{ + const struct wined3d_depth_stencil_state *state + = WINE_RB_ENTRY_VALUE(entry, struct wined3d_depth_stencil_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) @@ -5645,6 +5695,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); + wine_rb_init(&device->depth_stencil_states, wined3d_depth_stencil_state_compare);
if (vertex_pipeline->vp_states && fragment_pipeline->states && FAILED(hr = compile_state_table(device->state_table, device->multistate_funcs, @@ -5655,6 +5706,7 @@ HRESULT wined3d_device_init(struct wined3d_device *device, struct wined3d *wined wine_rb_destroy(&device->samplers, NULL, NULL); wine_rb_destroy(&device->rasterizer_states, NULL, NULL); wine_rb_destroy(&device->blend_states, NULL, NULL); + wine_rb_destroy(&device->depth_stencil_states, NULL, NULL); wined3d_decref(device->wined3d); return hr; } @@ -5681,6 +5733,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); + wine_rb_destroy(&device->depth_stencil_states, NULL, NULL); wined3d_decref(device->wined3d); return hr; } diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index f53b98abc24..cd05c264645 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -2362,6 +2362,7 @@ static const struct wined3d_state_entry_template misc_state_template_no3d[] = {STATE_BLEND, {STATE_VDECL}}, {STATE_BLEND_FACTOR, {STATE_VDECL}}, {STATE_SAMPLE_MASK, {STATE_VDECL}}, + {STATE_DEPTH_STENCIL, {STATE_VDECL}}, {STATE_STREAMSRC, {STATE_VDECL}}, {STATE_VDECL, {STATE_VDECL, state_nop}}, {STATE_RASTERIZER, {STATE_VDECL}}, diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 51a24753c82..ac3afe881d6 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -109,6 +109,67 @@ HRESULT CDECL wined3d_blend_state_create(struct wined3d_device *device, return WINED3D_OK; }
+ULONG CDECL wined3d_depth_stencil_state_incref(struct wined3d_depth_stencil_state *state) +{ + ULONG refcount = InterlockedIncrement(&state->refcount); + + TRACE("%p increasing refcount to %u.\n", state, refcount); + + return refcount; +} + +static void wined3d_depth_stencil_state_destroy_object(void *object) +{ + heap_free(object); +} + +ULONG CDECL wined3d_depth_stencil_state_decref(struct wined3d_depth_stencil_state *state) +{ + ULONG refcount = InterlockedDecrement(&state->refcount); + struct wined3d_device *device = state->device; + + TRACE("%p decreasing refcount to %u.\n", state, refcount); + + if (!refcount) + { + state->parent_ops->wined3d_object_destroyed(state->parent); + wined3d_cs_destroy_object(device->cs, wined3d_depth_stencil_state_destroy_object, state); + } + + return refcount; +} + +void * CDECL wined3d_depth_stencil_state_get_parent(const struct wined3d_depth_stencil_state *state) +{ + TRACE("state %p.\n", state); + + return state->parent; +} + +HRESULT CDECL wined3d_depth_stencil_state_create(struct wined3d_device *device, + const struct wined3d_depth_stencil_state_desc *desc, void *parent, + const struct wined3d_parent_ops *parent_ops, struct wined3d_depth_stencil_state **state) +{ + struct wined3d_depth_stencil_state *object; + + TRACE("device %p, desc %p, parent %p, parent_ops %p, state %p.\n", + device, desc, parent, parent_ops, state); + + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY; + + object->refcount = 1; + object->desc = *desc; + object->parent = parent; + object->parent_ops = parent_ops; + object->device = device; + + TRACE("Created depth/stencil state %p.\n", object); + *state = object; + + return WINED3D_OK; +} + ULONG CDECL wined3d_rasterizer_state_incref(struct wined3d_rasterizer_state *state) { ULONG refcount = InterlockedIncrement(&state->refcount); @@ -1178,6 +1239,33 @@ static void state_stencilwrite(struct wined3d_context *context, const struct win checkGLcall("glStencilMask"); }
+static void depth_stencil(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_depth_stencil_state *d = state->depth_stencil_state; + BOOL enable_depth = d ? d->desc.depth : TRUE; + + if (!state->fb.depth_stencil) + { + TRACE("No depth/stencil buffer is attached; disabling depth test.\n"); + enable_depth = FALSE; + } + + if (enable_depth) + { + gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_TEST); + checkGLcall("glEnable GL_DEPTH_TEST"); + } + else + { + gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_TEST); + checkGLcall("glDisable GL_DEPTH_TEST"); + } + + if (context->last_was_rhw && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION))) + context_apply_state(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION)); +} + static void state_fog_vertexpart(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; @@ -4624,6 +4712,7 @@ const struct wined3d_state_entry_template misc_state_template_gl[] = { STATE_BLEND_FACTOR, { STATE_BLEND_FACTOR, state_blend_factor_w}, WINED3D_GL_EXT_NONE }, { STATE_SAMPLE_MASK, { STATE_SAMPLE_MASK, state_sample_mask }, ARB_TEXTURE_MULTISAMPLE }, { STATE_SAMPLE_MASK, { STATE_SAMPLE_MASK, state_sample_mask_w }, WINED3D_GL_EXT_NONE }, + { STATE_DEPTH_STENCIL, { STATE_DEPTH_STENCIL, depth_stencil }, 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 }, @@ -5566,6 +5655,7 @@ static void validate_state_table(struct wined3d_state_entry *state_table) STATE_COLOR_KEY, STATE_BLEND, STATE_BLEND_FACTOR, + STATE_DEPTH_STENCIL, }; unsigned int i, current;
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 295b50a32c7..cf792746cc7 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -32,6 +32,11 @@ @ cdecl wined3d_buffer_get_resource(ptr) @ cdecl wined3d_buffer_incref(ptr)
+@ cdecl wined3d_depth_stencil_state_create(ptr ptr ptr ptr ptr) +@ cdecl wined3d_depth_stencil_state_decref(ptr) +@ cdecl wined3d_depth_stencil_state_get_parent(ptr) +@ cdecl wined3d_depth_stencil_state_incref(ptr) + @ cdecl wined3d_device_acquire_focus_window(ptr ptr) @ cdecl wined3d_device_apply_stateblock(ptr ptr) @ cdecl wined3d_device_begin_scene(ptr) @@ -63,6 +68,7 @@ @ cdecl wined3d_device_get_cs_resource_view(ptr long) @ cdecl wined3d_device_get_cs_sampler(ptr long) @ cdecl wined3d_device_get_cs_uav(ptr long) +@ cdecl wined3d_device_get_depth_stencil_state(ptr) @ cdecl wined3d_device_get_depth_stencil_view(ptr) @ cdecl wined3d_device_get_device_caps(ptr ptr) @ cdecl wined3d_device_get_display_mode(ptr long ptr ptr) @@ -117,6 +123,7 @@ @ cdecl wined3d_device_set_cs_uav(ptr long ptr long) @ cdecl wined3d_device_set_cursor_position(ptr long long long) @ cdecl wined3d_device_set_cursor_properties(ptr long long ptr long) +@ cdecl wined3d_device_set_depth_stencil_state(ptr ptr) @ cdecl wined3d_device_set_depth_stencil_view(ptr ptr) @ cdecl wined3d_device_set_dialog_box_mode(ptr long) @ cdecl wined3d_device_set_domain_shader(ptr ptr) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index b0bf863d217..177d4d01337 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1779,7 +1779,10 @@ enum wined3d_pipeline #define STATE_SAMPLE_MASK (STATE_BLEND_FACTOR + 1) #define STATE_IS_SAMPLE_MASK(a) ((a) == STATE_SAMPLE_MASK)
-#define STATE_COMPUTE_OFFSET (STATE_SAMPLE_MASK + 1) +#define STATE_DEPTH_STENCIL (STATE_SAMPLE_MASK + 1) +#define STATE_IS_DEPTH_STENCIL(a) ((a) == STATE_DEPTH_STENCIL) + +#define STATE_COMPUTE_OFFSET (STATE_DEPTH_STENCIL + 1)
#define STATE_COMPUTE_SHADER (STATE_COMPUTE_OFFSET) #define STATE_IS_COMPUTE_SHADER(a) ((a) == STATE_COMPUTE_SHADER) @@ -3541,6 +3544,18 @@ static inline unsigned int wined3d_blend_state_get_writemask(const struct wined3 return state->desc.rt[index].writemask; }
+struct wined3d_depth_stencil_state +{ + LONG refcount; + struct wined3d_depth_stencil_state_desc desc; + + void *parent; + const struct wined3d_parent_ops *parent_ops; + + struct wined3d_device *device; + struct wine_rb_entry entry; +}; + struct wined3d_rasterizer_state { LONG refcount; @@ -3622,6 +3637,7 @@ struct wined3d_state struct wined3d_blend_state *blend_state; struct wined3d_color blend_factor; unsigned int sample_mask; + struct wined3d_depth_stencil_state *depth_stencil_state; struct wined3d_rasterizer_state *rasterizer_state; };
@@ -3695,7 +3711,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, blend_states; + struct wine_rb_tree samplers, rasterizer_states, blend_states, depth_stencil_states;
/* Render Target Support */ struct wined3d_rendertarget_view *auto_depth_stencil_view; @@ -4641,6 +4657,8 @@ void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture WORD flags, const struct wined3d_color_key *color_key) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_constant_buffer(struct wined3d_cs *cs, enum wined3d_shader_type type, UINT cb_idx, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_depth_stencil_state(struct wined3d_cs *cs, + struct wined3d_depth_stencil_state *state) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_depth_stencil_view(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_index_buffer(struct wined3d_cs *cs, struct wined3d_buffer *buffer, diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index db4ca3d256b..77dbb775532 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2036,6 +2036,11 @@ struct wined3d_blend_state_desc } rt[WINED3D_MAX_RENDER_TARGETS]; };
+struct wined3d_depth_stencil_state_desc +{ + BOOL depth; +}; + struct wined3d_rasterizer_state_desc { enum wined3d_fill_mode fill_mode; @@ -2193,6 +2198,7 @@ struct wined3d; struct wined3d_adapter; struct wined3d_blend_state; struct wined3d_buffer; +struct wined3d_depth_stencil_state; struct wined3d_device; struct wined3d_output; struct wined3d_palette; @@ -2297,6 +2303,13 @@ void * __cdecl wined3d_buffer_get_parent(const struct wined3d_buffer *buffer); struct wined3d_resource * __cdecl wined3d_buffer_get_resource(struct wined3d_buffer *buffer); ULONG __cdecl wined3d_buffer_incref(struct wined3d_buffer *buffer);
+HRESULT __cdecl wined3d_depth_stencil_state_create(struct wined3d_device *device, + const struct wined3d_depth_stencil_state_desc *desc, void *parent, + const struct wined3d_parent_ops *parent_ops, struct wined3d_depth_stencil_state **state); +ULONG __cdecl wined3d_depth_stencil_state_decref(struct wined3d_depth_stencil_state *state); +void * __cdecl wined3d_depth_stencil_state_get_parent(const struct wined3d_depth_stencil_state *state); +ULONG __cdecl wined3d_depth_stencil_state_incref(struct wined3d_depth_stencil_state *state); + HRESULT __cdecl wined3d_device_acquire_focus_window(struct wined3d_device *device, HWND window); void __cdecl wined3d_device_apply_stateblock(struct wined3d_device *device, struct wined3d_stateblock *stateblock); HRESULT __cdecl wined3d_device_begin_scene(struct wined3d_device *device); @@ -2352,6 +2365,8 @@ struct wined3d_shader_resource_view * __cdecl wined3d_device_get_cs_resource_vie struct wined3d_sampler * __cdecl wined3d_device_get_cs_sampler(const struct wined3d_device *device, unsigned int idx); struct wined3d_unordered_access_view * __cdecl wined3d_device_get_cs_uav(const struct wined3d_device *device, unsigned int idx); +struct wined3d_depth_stencil_state * __cdecl wined3d_device_get_depth_stencil_state( + const struct wined3d_device *device); struct wined3d_rendertarget_view * __cdecl wined3d_device_get_depth_stencil_view(const struct wined3d_device *device); HRESULT __cdecl wined3d_device_get_device_caps(const struct wined3d_device *device, struct wined3d_caps *caps); HRESULT __cdecl wined3d_device_get_display_mode(const struct wined3d_device *device, UINT swapchain_idx, @@ -2438,6 +2453,8 @@ void __cdecl wined3d_device_set_cursor_position(struct wined3d_device *device, int x_screen_space, int y_screen_space, DWORD flags); HRESULT __cdecl wined3d_device_set_cursor_properties(struct wined3d_device *device, UINT x_hotspot, UINT y_hotspot, struct wined3d_texture *texture, unsigned int sub_resource_idx); +void __cdecl wined3d_device_set_depth_stencil_state(struct wined3d_device *device, + struct wined3d_depth_stencil_state *state); HRESULT __cdecl wined3d_device_set_depth_stencil_view(struct wined3d_device *device, struct wined3d_rendertarget_view *view); HRESULT __cdecl wined3d_device_set_dialog_box_mode(struct wined3d_device *device, BOOL enable_dialogs);
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/d3d11/d3d11_private.h | 2 +- dlls/d3d11/device.c | 23 +++++++++--- dlls/d3d11/state.c | 75 ++++++++++++++++++++++++-------------- 3 files changed, 66 insertions(+), 34 deletions(-)
diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h index cb2b9c3aedc..3248285fcda 100644 --- a/dlls/d3d11/d3d11_private.h +++ b/dlls/d3d11/d3d11_private.h @@ -440,6 +440,7 @@ struct d3d_depthstencil_state LONG refcount;
struct wined3d_private_store private_store; + struct wined3d_depth_stencil_state *wined3d_state; D3D11_DEPTH_STENCIL_DESC desc; struct wine_rb_entry entry; ID3D11Device2 *device; @@ -549,7 +550,6 @@ struct d3d_device struct wine_rb_tree rasterizer_states; struct wine_rb_tree sampler_states;
- struct d3d_depthstencil_state *depth_stencil_state; UINT stencil_ref; };
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 2a68e025852..055e243a439 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -737,6 +737,7 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_OMSetDepthStencilState(ID3 { struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); const D3D11_DEPTH_STENCILOP_DESC *front, *back; + struct d3d_depthstencil_state *state_impl; const D3D11_DEPTH_STENCIL_DESC *desc;
TRACE("iface %p, depth_stencil_state %p, stencil_ref %u.\n", @@ -744,14 +745,16 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_OMSetDepthStencilState(ID3
wined3d_mutex_lock(); device->stencil_ref = stencil_ref; - if (!(device->depth_stencil_state = unsafe_impl_from_ID3D11DepthStencilState(depth_stencil_state))) + if (!(state_impl = unsafe_impl_from_ID3D11DepthStencilState(depth_stencil_state))) { + wined3d_device_set_depth_stencil_state(device->wined3d_device, NULL); set_default_depth_stencil_state(device->wined3d_device); wined3d_mutex_unlock(); return; }
- desc = &device->depth_stencil_state->desc; + wined3d_device_set_depth_stencil_state(device->wined3d_device, state_impl->wined3d_state); + desc = &state_impl->desc;
front = &desc->FrontFace; back = &desc->BackFace; @@ -1904,14 +1907,24 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_OMGetDepthStencilState(ID3 ID3D11DepthStencilState **depth_stencil_state, UINT *stencil_ref) { struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct wined3d_depth_stencil_state *wined3d_state; + struct d3d_depthstencil_state *state_impl;
TRACE("iface %p, depth_stencil_state %p, stencil_ref %p.\n", iface, depth_stencil_state, stencil_ref);
- if ((*depth_stencil_state = device->depth_stencil_state - ? &device->depth_stencil_state->ID3D11DepthStencilState_iface : NULL)) - ID3D11DepthStencilState_AddRef(*depth_stencil_state); + wined3d_mutex_lock(); + if ((wined3d_state = wined3d_device_get_depth_stencil_state(device->wined3d_device))) + { + state_impl = wined3d_depth_stencil_state_get_parent(wined3d_state); + ID3D11DepthStencilState_AddRef(*depth_stencil_state = &state_impl->ID3D11DepthStencilState_iface); + } + else + { + *depth_stencil_state = NULL; + } *stencil_ref = device->stencil_ref; + wined3d_mutex_unlock(); }
static void STDMETHODCALLTYPE d3d11_immediate_context_SOGetTargets(ID3D11DeviceContext1 *iface, diff --git a/dlls/d3d11/state.c b/dlls/d3d11/state.c index 32ef44091c4..5d4c3526595 100644 --- a/dlls/d3d11/state.c +++ b/dlls/d3d11/state.c @@ -493,13 +493,15 @@ static ULONG STDMETHODCALLTYPE d3d11_depthstencil_state_AddRef(ID3D11DepthStenci
TRACE("%p increasing refcount to %u.\n", state, refcount);
- return refcount; -} + if (refcount == 1) + { + ID3D11Device2_AddRef(state->device); + wined3d_mutex_lock(); + wined3d_depth_stencil_state_incref(state->wined3d_state); + wined3d_mutex_unlock(); + }
-static void d3d_depthstencil_state_cleanup(struct d3d_depthstencil_state *state) -{ - wined3d_private_store_cleanup(&state->private_store); - ID3D11Device2_Release(state->device); + return refcount; }
static ULONG STDMETHODCALLTYPE d3d11_depthstencil_state_Release(ID3D11DepthStencilState *iface) @@ -511,12 +513,12 @@ static ULONG STDMETHODCALLTYPE d3d11_depthstencil_state_Release(ID3D11DepthStenc
if (!refcount) { - struct d3d_device *device = impl_from_ID3D11Device2(state->device); + ID3D11Device2 *device = state->device; + wined3d_mutex_lock(); - wine_rb_remove(&device->depthstencil_states, &state->entry); - d3d_depthstencil_state_cleanup(state); + wined3d_depth_stencil_state_decref(state->wined3d_state); wined3d_mutex_unlock(); - heap_free(state); + ID3D11Device2_Release(device); }
return refcount; @@ -695,23 +697,25 @@ static const struct ID3D10DepthStencilStateVtbl d3d10_depthstencil_state_vtbl = d3d10_depthstencil_state_GetDesc, };
-static HRESULT d3d_depthstencil_state_init(struct d3d_depthstencil_state *state, struct d3d_device *device, - const D3D11_DEPTH_STENCIL_DESC *desc) +static void STDMETHODCALLTYPE d3d_depthstencil_state_wined3d_object_destroyed(void *parent) { - state->ID3D11DepthStencilState_iface.lpVtbl = &d3d11_depthstencil_state_vtbl; - state->ID3D10DepthStencilState_iface.lpVtbl = &d3d10_depthstencil_state_vtbl; - state->refcount = 1; - wined3d_private_store_init(&state->private_store); - state->desc = *desc; - - ID3D11Device2_AddRef(state->device = &device->ID3D11Device2_iface); + struct d3d_depthstencil_state *state = parent; + struct d3d_device *device = impl_from_ID3D11Device2(state->device);
- return S_OK; + wine_rb_remove(&device->depthstencil_states, &state->entry); + wined3d_private_store_cleanup(&state->private_store); + heap_free(parent); }
+static const struct wined3d_parent_ops d3d_depthstencil_state_wined3d_parent_ops = +{ + d3d_depthstencil_state_wined3d_object_destroyed, +}; + HRESULT d3d_depthstencil_state_create(struct d3d_device *device, const D3D11_DEPTH_STENCIL_DESC *desc, struct d3d_depthstencil_state **state) { + struct wined3d_depth_stencil_state_desc wined3d_desc; struct d3d_depthstencil_state *object; D3D11_DEPTH_STENCIL_DESC tmp_desc; struct wine_rb_entry *entry; @@ -775,25 +779,40 @@ HRESULT d3d_depthstencil_state_create(struct d3d_device *device, const D3D11_DEP return E_OUTOFMEMORY; }
- if (FAILED(hr = d3d_depthstencil_state_init(object, device, &tmp_desc))) + object->ID3D11DepthStencilState_iface.lpVtbl = &d3d11_depthstencil_state_vtbl; + object->ID3D10DepthStencilState_iface.lpVtbl = &d3d10_depthstencil_state_vtbl; + object->refcount = 1; + wined3d_private_store_init(&object->private_store); + object->desc = tmp_desc; + + if (wine_rb_put(&device->depthstencil_states, &tmp_desc, &object->entry) == -1) { - WARN("Failed to initialize depthstencil state, hr %#x.\n", hr); + ERR("Failed to insert depth/stencil state entry.\n"); + wined3d_private_store_cleanup(&object->private_store); heap_free(object); wined3d_mutex_unlock(); - return hr; + return E_FAIL; }
- if (wine_rb_put(&device->depthstencil_states, &tmp_desc, &object->entry) == -1) + wined3d_desc.depth = desc->DepthEnable; + + /* We cannot fail after creating a wined3d_depth_stencil_state object. It + * would lead to double free. */ + if (FAILED(hr = wined3d_depth_stencil_state_create(device->wined3d_device, &wined3d_desc, + object, &d3d_depthstencil_state_wined3d_parent_ops, &object->wined3d_state))) { - ERR("Failed to insert depthstencil state entry.\n"); - d3d_depthstencil_state_cleanup(object); + WARN("Failed to create wined3d depth/stencil state, hr %#x.\n", hr); + wined3d_private_store_cleanup(&object->private_store); + wine_rb_remove(&device->depthstencil_states, &object->entry); heap_free(object); wined3d_mutex_unlock(); - return E_FAIL; + return hr; } wined3d_mutex_unlock();
- TRACE("Created depthstencil state %p.\n", object); + ID3D11Device2_AddRef(object->device = &device->ID3D11Device2_iface); + + TRACE("Created depth/stencil state %p.\n", object); *state = object;
return S_OK;
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/d3d11/device.c | 2 -- dlls/wined3d/adapter_vk.c | 31 +++++++++++------------ dlls/wined3d/context_gl.c | 2 +- dlls/wined3d/context_vk.c | 13 ++++++++-- dlls/wined3d/cs.c | 2 +- dlls/wined3d/device.c | 46 +++++++++++++++++++++++++++++++++- dlls/wined3d/directx.c | 1 - dlls/wined3d/state.c | 39 +--------------------------- dlls/wined3d/utils.c | 4 +-- dlls/wined3d/wined3d_private.h | 3 ++- 10 files changed, 78 insertions(+), 65 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 055e243a439..ca9975d6a22 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -726,7 +726,6 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_OMSetBlendState(ID3D11Devi
static void set_default_depth_stencil_state(struct wined3d_device *wined3d_device) { - wined3d_device_set_render_state(wined3d_device, WINED3D_RS_ZENABLE, TRUE); wined3d_device_set_render_state(wined3d_device, WINED3D_RS_ZWRITEENABLE, D3D11_DEPTH_WRITE_MASK_ALL); wined3d_device_set_render_state(wined3d_device, WINED3D_RS_ZFUNC, WINED3D_CMP_LESS); wined3d_device_set_render_state(wined3d_device, WINED3D_RS_STENCILENABLE, FALSE); @@ -759,7 +758,6 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_OMSetDepthStencilState(ID3 front = &desc->FrontFace; back = &desc->BackFace;
- wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_ZENABLE, desc->DepthEnable); if (desc->DepthEnable) { wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_ZWRITEENABLE, desc->DepthWriteMask); diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c index f3a8d8f89db..7b0c0c89897 100644 --- a/dlls/wined3d/adapter_vk.c +++ b/dlls/wined3d/adapter_vk.c @@ -100,16 +100,15 @@ static const struct wined3d_state_entry_template misc_state_template_vk[] = {STATE_INDEXBUFFER, {STATE_INDEXBUFFER, state_nop}}, {STATE_RENDER(WINED3D_RS_ANTIALIAS), {STATE_RENDER(WINED3D_RS_ANTIALIAS), state_nop}}, {STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE), {STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE), state_nop}}, - {STATE_RENDER(WINED3D_RS_ZENABLE), {STATE_RENDER(WINED3D_RS_ZENABLE), state_nop}}, {STATE_RENDER(WINED3D_RS_WRAPU), {STATE_RENDER(WINED3D_RS_WRAPU), state_nop}}, {STATE_RENDER(WINED3D_RS_WRAPV), {STATE_RENDER(WINED3D_RS_WRAPV), state_nop}}, {STATE_RENDER(WINED3D_RS_LINEPATTERN), {STATE_RENDER(WINED3D_RS_LINEPATTERN), state_nop}}, {STATE_RENDER(WINED3D_RS_MONOENABLE), {STATE_RENDER(WINED3D_RS_MONOENABLE), state_nop}}, {STATE_RENDER(WINED3D_RS_ROP2), {STATE_RENDER(WINED3D_RS_ROP2), state_nop}}, {STATE_RENDER(WINED3D_RS_PLANEMASK), {STATE_RENDER(WINED3D_RS_PLANEMASK), state_nop}}, - {STATE_RENDER(WINED3D_RS_ZWRITEENABLE), {STATE_RENDER(WINED3D_RS_ZENABLE)}}, + {STATE_RENDER(WINED3D_RS_ZWRITEENABLE), {STATE_RENDER(WINED3D_RS_ZWRITEENABLE), state_nop}}, {STATE_RENDER(WINED3D_RS_LASTPIXEL), {STATE_RENDER(WINED3D_RS_LASTPIXEL), state_nop}}, - {STATE_RENDER(WINED3D_RS_ZFUNC), {STATE_RENDER(WINED3D_RS_ZENABLE)}}, + {STATE_RENDER(WINED3D_RS_ZFUNC), {STATE_RENDER(WINED3D_RS_ZWRITEENABLE)}}, {STATE_RENDER(WINED3D_RS_DITHERENABLE), {STATE_RENDER(WINED3D_RS_DITHERENABLE), state_nop}}, {STATE_RENDER(WINED3D_RS_SUBPIXEL), {STATE_RENDER(WINED3D_RS_SUBPIXEL), state_nop}}, {STATE_RENDER(WINED3D_RS_SUBPIXELX), {STATE_RENDER(WINED3D_RS_SUBPIXELX), state_nop}}, @@ -119,19 +118,19 @@ static const struct wined3d_state_entry_template misc_state_template_vk[] = {STATE_RENDER(WINED3D_RS_ANISOTROPY), {STATE_RENDER(WINED3D_RS_ANISOTROPY), state_nop}}, {STATE_RENDER(WINED3D_RS_FLUSHBATCH), {STATE_RENDER(WINED3D_RS_FLUSHBATCH), state_nop}}, {STATE_RENDER(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT), {STATE_RENDER(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT), state_nop}}, - {STATE_RENDER(WINED3D_RS_STENCILENABLE), {STATE_RENDER(WINED3D_RS_ZENABLE)}}, - {STATE_RENDER(WINED3D_RS_STENCILFAIL), {STATE_RENDER(WINED3D_RS_ZENABLE)}}, - {STATE_RENDER(WINED3D_RS_STENCILZFAIL), {STATE_RENDER(WINED3D_RS_ZENABLE)}}, - {STATE_RENDER(WINED3D_RS_STENCILPASS), {STATE_RENDER(WINED3D_RS_ZENABLE)}}, - {STATE_RENDER(WINED3D_RS_STENCILFUNC), {STATE_RENDER(WINED3D_RS_ZENABLE)}}, - {STATE_RENDER(WINED3D_RS_STENCILREF), {STATE_RENDER(WINED3D_RS_ZENABLE)}}, - {STATE_RENDER(WINED3D_RS_STENCILMASK), {STATE_RENDER(WINED3D_RS_ZENABLE)}}, - {STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), {STATE_RENDER(WINED3D_RS_ZENABLE)}}, - {STATE_RENDER(WINED3D_RS_TWOSIDEDSTENCILMODE), {STATE_RENDER(WINED3D_RS_ZENABLE)}}, - {STATE_RENDER(WINED3D_RS_BACK_STENCILFAIL), {STATE_RENDER(WINED3D_RS_ZENABLE)}}, - {STATE_RENDER(WINED3D_RS_BACK_STENCILZFAIL), {STATE_RENDER(WINED3D_RS_ZENABLE)}}, - {STATE_RENDER(WINED3D_RS_BACK_STENCILPASS), {STATE_RENDER(WINED3D_RS_ZENABLE)}}, - {STATE_RENDER(WINED3D_RS_BACK_STENCILFUNC), {STATE_RENDER(WINED3D_RS_ZENABLE)}}, + {STATE_RENDER(WINED3D_RS_STENCILENABLE), {STATE_RENDER(WINED3D_RS_ZWRITEENABLE)}}, + {STATE_RENDER(WINED3D_RS_STENCILFAIL), {STATE_RENDER(WINED3D_RS_ZWRITEENABLE)}}, + {STATE_RENDER(WINED3D_RS_STENCILZFAIL), {STATE_RENDER(WINED3D_RS_ZWRITEENABLE)}}, + {STATE_RENDER(WINED3D_RS_STENCILPASS), {STATE_RENDER(WINED3D_RS_ZWRITEENABLE)}}, + {STATE_RENDER(WINED3D_RS_STENCILFUNC), {STATE_RENDER(WINED3D_RS_ZWRITEENABLE)}}, + {STATE_RENDER(WINED3D_RS_STENCILREF), {STATE_RENDER(WINED3D_RS_ZWRITEENABLE)}}, + {STATE_RENDER(WINED3D_RS_STENCILMASK), {STATE_RENDER(WINED3D_RS_ZWRITEENABLE)}}, + {STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), {STATE_RENDER(WINED3D_RS_ZWRITEENABLE)}}, + {STATE_RENDER(WINED3D_RS_TWOSIDEDSTENCILMODE), {STATE_RENDER(WINED3D_RS_ZWRITEENABLE)}}, + {STATE_RENDER(WINED3D_RS_BACK_STENCILFAIL), {STATE_RENDER(WINED3D_RS_ZWRITEENABLE)}}, + {STATE_RENDER(WINED3D_RS_BACK_STENCILZFAIL), {STATE_RENDER(WINED3D_RS_ZWRITEENABLE)}}, + {STATE_RENDER(WINED3D_RS_BACK_STENCILPASS), {STATE_RENDER(WINED3D_RS_ZWRITEENABLE)}}, + {STATE_RENDER(WINED3D_RS_BACK_STENCILFUNC), {STATE_RENDER(WINED3D_RS_ZWRITEENABLE)}}, {STATE_RENDER(WINED3D_RS_WRAP0), {STATE_RENDER(WINED3D_RS_WRAP0), state_nop}}, {STATE_RENDER(WINED3D_RS_WRAP1), {STATE_RENDER(WINED3D_RS_WRAP0)}}, {STATE_RENDER(WINED3D_RS_WRAP2), {STATE_RENDER(WINED3D_RS_WRAP0)}}, diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index e3eae3aab58..186d70b45ad 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -2818,7 +2818,7 @@ void wined3d_context_gl_apply_blit_state(struct wined3d_context_gl *context_gl, context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHATESTENABLE)); } gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_TEST); - context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ZENABLE)); + context_invalidate_state(context, STATE_DEPTH_STENCIL); 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); diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c index a4f5f317f1f..356fec27a78 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -2034,10 +2034,19 @@ static bool wined3d_context_vk_update_graphics_pipeline_key(struct wined3d_conte update = true; }
- if (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_RENDER(WINED3D_RS_ZENABLE)) + if (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_DEPTH_STENCIL) || wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_FRAMEBUFFER)) { - key->ds_desc.depthTestEnable = !!state->render_states[WINED3D_RS_ZENABLE]; + const struct wined3d_depth_stencil_state *d = state->depth_stencil_state; + + if (d) + { + key->ds_desc.depthTestEnable = d->desc.depth; + } + else + { + key->ds_desc.depthTestEnable = VK_TRUE; + } key->ds_desc.depthWriteEnable = !!state->render_states[WINED3D_RS_ZWRITEENABLE]; key->ds_desc.depthCompareOp = vk_compare_op_from_wined3d(state->render_states[WINED3D_RS_ZFUNC]); key->ds_desc.stencilTestEnable = state->fb.depth_stencil && state->render_states[WINED3D_RS_STENCILENABLE]; diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index d6a78cc5d65..6509887afa9 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -1226,7 +1226,7 @@ static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const if (!prev != !op->view) { /* Swapping NULL / non NULL depth stencil affects the depth and tests */ - device_invalidate_state(device, STATE_RENDER(WINED3D_RS_ZENABLE)); + device_invalidate_state(device, STATE_DEPTH_STENCIL); device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILENABLE)); device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILWRITEMASK)); device_invalidate_state(device, STATE_RASTERIZER); diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index a59a1efeab7..38b488cba81 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -3576,10 +3576,10 @@ static void wined3d_device_set_texture(struct wined3d_device *device, void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, struct wined3d_stateblock *stateblock) { + BOOL set_blend_state = FALSE, set_depth_stencil_state = FALSE, set_rasterizer_state = FALSE; 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 = FALSE, set_rasterizer_state = FALSE; unsigned int i, j, start, idx; struct wined3d_range range; uint32_t map; @@ -3684,6 +3684,10 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, set_blend_state = TRUE; break;
+ case WINED3D_RS_ZENABLE: + set_depth_stencil_state = TRUE; + break; + case WINED3D_RS_FILLMODE: case WINED3D_RS_CULLMODE: case WINED3D_RS_SLOPESCALEDEPTHBIAS: @@ -3812,6 +3816,46 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, } }
+ if (set_depth_stencil_state) + { + struct wined3d_depth_stencil_state *depth_stencil_state; + struct wined3d_depth_stencil_state_desc desc; + struct wine_rb_entry *entry; + + memset(&desc, 0, sizeof(desc)); + switch (state->rs[WINED3D_RS_ZENABLE]) + { + case WINED3D_ZB_FALSE: + desc.depth = FALSE; + break; + + case WINED3D_ZB_USEW: + FIXME("W buffer is not well handled.\n"); + case WINED3D_ZB_TRUE: + desc.depth = TRUE; + break; + + default: + FIXME("Unrecognized depth buffer type %#x.\n", state->rs[WINED3D_RS_ZENABLE]); + } + + if ((entry = wine_rb_get(&device->depth_stencil_states, &desc))) + { + depth_stencil_state = WINE_RB_ENTRY_VALUE(entry, struct wined3d_depth_stencil_state, entry); + wined3d_device_set_depth_stencil_state(device, depth_stencil_state); + } + else if (SUCCEEDED(wined3d_depth_stencil_state_create(device, &desc, NULL, + &wined3d_null_parent_ops, &depth_stencil_state))) + { + wined3d_device_set_depth_stencil_state(device, depth_stencil_state); + if (wine_rb_put(&device->depth_stencil_states, &desc, &depth_stencil_state->entry) == -1) + { + ERR("Failed to insert depth/stencil state.\n"); + wined3d_depth_stencil_state_decref(depth_stencil_state); + } + } + } + for (i = 0; i < ARRAY_SIZE(changed->textureState); ++i) { map = changed->textureState[i]; diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index cd05c264645..fced1eb110c 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -2422,7 +2422,6 @@ static const struct wined3d_state_entry_template misc_state_template_no3d[] = {STATE_INDEXBUFFER, {STATE_VDECL}}, {STATE_RENDER(WINED3D_RS_ANTIALIAS), {STATE_VDECL}}, {STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE), {STATE_VDECL}}, - {STATE_RENDER(WINED3D_RS_ZENABLE), {STATE_VDECL}}, {STATE_RENDER(WINED3D_RS_WRAPU), {STATE_VDECL}}, {STATE_RENDER(WINED3D_RS_WRAPV), {STATE_VDECL}}, {STATE_RENDER(WINED3D_RS_LINEPATTERN), {STATE_VDECL}}, diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index ac3afe881d6..d77722c00d4 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -291,42 +291,6 @@ static void state_lighting(struct wined3d_context *context, const struct wined3d } }
-static void state_zenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) -{ - enum wined3d_depth_buffer_type zenable = state->render_states[WINED3D_RS_ZENABLE]; - const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; - - /* No z test without depth stencil buffers */ - if (!state->fb.depth_stencil) - { - TRACE("No Z buffer - disabling depth test\n"); - zenable = WINED3D_ZB_FALSE; - } - - switch (zenable) - { - case WINED3D_ZB_FALSE: - gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_TEST); - checkGLcall("glDisable GL_DEPTH_TEST"); - break; - case WINED3D_ZB_TRUE: - gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_TEST); - checkGLcall("glEnable GL_DEPTH_TEST"); - break; - case WINED3D_ZB_USEW: - gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_TEST); - checkGLcall("glEnable GL_DEPTH_TEST"); - FIXME("W buffer is not well handled\n"); - break; - default: - FIXME("Unrecognized depth buffer type %#x.\n", zenable); - break; - } - - if (context->last_was_rhw && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION))) - context_apply_state(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION)); -} - static void cullmode(const struct wined3d_rasterizer_state *r, const struct wined3d_gl_info *gl_info) { enum wined3d_cull mode = r ? r->desc.cull_mode : WINED3D_CULL_BACK; @@ -4780,7 +4744,6 @@ const struct wined3d_state_entry_template misc_state_template_gl[] = { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, state_nop }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_ANTIALIAS), { STATE_RENDER(WINED3D_RS_ANTIALIAS), state_antialias }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE), { STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE), state_nop }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3D_RS_ZENABLE), { STATE_RENDER(WINED3D_RS_ZENABLE), state_zenable }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_WRAPU), { STATE_RENDER(WINED3D_RS_WRAPU), state_wrapu }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_WRAPV), { STATE_RENDER(WINED3D_RS_WRAPV), state_wrapv }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_LINEPATTERN), { STATE_RENDER(WINED3D_RS_LINEPATTERN), state_linepattern }, WINED3D_GL_LEGACY_CONTEXT }, @@ -5605,7 +5568,7 @@ static void validate_state_table(struct wined3d_state_entry *state_table) { { 1, 1}, { 3, 3}, - { 8, 8}, + { 7, 8}, { 17, 22}, { 27, 27}, { 40, 40}, diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 8d790c52945..01a838db897 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -5446,8 +5446,8 @@ void get_projection_matrix(const struct wined3d_context *context, const struct w float y_offset = flip ? (center_offset - (2.0f * y) - h) / h : (center_offset - (2.0f * y) - h) / -h; - enum wined3d_depth_buffer_type zenable = state->fb.depth_stencil ? - state->render_states[WINED3D_RS_ZENABLE] : WINED3D_ZB_FALSE; + bool zenable = state->fb.depth_stencil ? + (state->depth_stencil_state ? state->depth_stencil_state->desc.depth : true) : false; float z_scale = zenable ? clip_control ? 1.0f : 2.0f : 0.0f; float z_offset = zenable ? clip_control ? 0.0f : -1.0f : 0.0f; const struct wined3d_matrix projection = diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 177d4d01337..da3974973a1 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3643,7 +3643,8 @@ struct wined3d_state
static inline bool wined3d_state_uses_depth_buffer(const struct wined3d_state *state) { - return state->render_states[WINED3D_RS_ZWRITEENABLE] || state->render_states[WINED3D_RS_ZENABLE]; + return state->render_states[WINED3D_RS_ZWRITEENABLE] + || !state->depth_stencil_state || state->depth_stencil_state->desc.depth; }
struct wined3d_dummy_textures
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com