From 3861b4bb3771cf5fa4116bb50883fb13718b1c02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zef=20Kucia?= Date: Wed, 27 Jul 2016 23:33:41 +0200 Subject: [PATCH] wined3d: Introduce rasterizer state object. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Józef Kucia Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/wined3d/cs.c | 28 +++++++++++++++ dlls/wined3d/device.c | 26 ++++++++++++++ dlls/wined3d/state.c | 62 +++++++++++++++++++++++++++++----- dlls/wined3d/wined3d.spec | 6 ++++ dlls/wined3d/wined3d_private.h | 11 ++++++ include/wine/wined3d.h | 14 ++++++++ 6 files changed, 138 insertions(+), 9 deletions(-) diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 8ed049e76f8..a898c2c4d71 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -44,6 +44,7 @@ enum wined3d_cs_op WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW, WINED3D_CS_OP_SET_SAMPLER, WINED3D_CS_OP_SET_SHADER, + WINED3D_CS_OP_SET_RASTERIZER_STATE, WINED3D_CS_OP_SET_RENDER_STATE, WINED3D_CS_OP_SET_TEXTURE_STATE, WINED3D_CS_OP_SET_SAMPLER_STATE, @@ -205,6 +206,12 @@ struct wined3d_cs_set_shader struct wined3d_shader *shader; }; +struct wined3d_cs_set_rasterizer_state +{ + enum wined3d_cs_op opcode; + struct wined3d_rasterizer_state *state; +}; + struct wined3d_cs_set_render_state { enum wined3d_cs_op opcode; @@ -941,6 +948,26 @@ void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type cs->ops->submit(cs); } +static void wined3d_cs_exec_set_rasterizer_state(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_set_rasterizer_state *op = data; + + cs->state.rasterizer_state = op->state; + device_invalidate_state(cs->device, STATE_FRONTFACE); +} + +void wined3d_cs_emit_set_rasterizer_state(struct wined3d_cs *cs, + struct wined3d_rasterizer_state *rasterizer_state) +{ + struct wined3d_cs_set_rasterizer_state *op; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_SET_RASTERIZER_STATE; + op->state = rasterizer_state; + + cs->ops->submit(cs); +} + static void wined3d_cs_exec_set_render_state(struct wined3d_cs *cs, const void *data) { const struct wined3d_cs_set_render_state *op = data; @@ -1208,6 +1235,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void /* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW */ wined3d_cs_exec_set_shader_resource_view, /* WINED3D_CS_OP_SET_SAMPLER */ wined3d_cs_exec_set_sampler, /* WINED3D_CS_OP_SET_SHADER */ wined3d_cs_exec_set_shader, + /* 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, /* WINED3D_CS_OP_SET_SAMPLER_STATE */ wined3d_cs_exec_set_sampler_state, diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 32e7092d144..dfcebc01dbb 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -2059,6 +2059,32 @@ static void resolve_depth_buffer(struct wined3d_state *state) src_view->sub_resource_idx, &src_rect, 0, NULL, WINED3D_TEXF_POINT); } +void CDECL wined3d_device_set_rasterizer_state(struct wined3d_device *device, + struct wined3d_rasterizer_state *rasterizer_state) +{ + struct wined3d_rasterizer_state *prev; + + TRACE("device %p, rasterizer_state %p.\n", device, rasterizer_state); + + prev = device->update_state->rasterizer_state; + if (prev == rasterizer_state) + return; + + if (rasterizer_state) + wined3d_rasterizer_state_incref(rasterizer_state); + device->update_state->rasterizer_state = rasterizer_state; + wined3d_cs_emit_set_rasterizer_state(device->cs, rasterizer_state); + if (prev) + wined3d_rasterizer_state_decref(prev); +} + +struct wined3d_rasterizer_state * CDECL wined3d_device_get_rasterizer_state(struct wined3d_device *device) +{ + TRACE("device %p.\n", device); + + return device->state.rasterizer_state; +} + void CDECL wined3d_device_set_render_state(struct wined3d_device *device, enum wined3d_render_state state, DWORD value) { diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 42416a1cbb7..4096caf33fc 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -38,6 +38,53 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); WINE_DECLARE_DEBUG_CHANNEL(d3d_shader); +ULONG CDECL wined3d_rasterizer_state_incref(struct wined3d_rasterizer_state *state) +{ + ULONG refcount = InterlockedIncrement(&state->refcount); + + TRACE("%p increasing refcount to %u.\n", state, refcount); + + return refcount; +} + +static void wined3d_rasterizer_state_destroy_object(void *object) +{ + HeapFree(GetProcessHeap(), 0, object); +} + +ULONG CDECL wined3d_rasterizer_state_decref(struct wined3d_rasterizer_state *state) +{ + ULONG refcount = InterlockedDecrement(&state->refcount); + struct wined3d_device *device = state->device; + + TRACE("%p decreasing refcount to %u.\n", state, refcount); + + if (!refcount) + wined3d_cs_emit_destroy_object(device->cs, wined3d_rasterizer_state_destroy_object, state); + + return refcount; +} + +HRESULT CDECL wined3d_rasterizer_state_create(struct wined3d_device *device, + const struct wined3d_rasterizer_state_desc *desc, struct wined3d_rasterizer_state **state) +{ + struct wined3d_rasterizer_state *object; + + TRACE("device %p, desc %p, state %p.\n", device, desc, state); + + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) + return E_OUTOFMEMORY; + + object->refcount = 1; + object->desc = *desc; + object->device = device; + + TRACE("Created rasterizer state %p.\n", object); + *state = object; + + return WINED3D_OK; +} + /* Context activation for state handler is done by the caller. */ static void state_undefined(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) @@ -4792,17 +4839,14 @@ static void indexbuffer(struct wined3d_context *context, const struct wined3d_st static void frontface(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const struct wined3d_gl_info *gl_info = context->gl_info; + GLenum mode; + mode = state->rasterizer_state && state->rasterizer_state->desc.front_ccw ? GL_CCW : GL_CW; if (context->render_offscreen) - { - gl_info->gl_ops.gl.p_glFrontFace(GL_CCW); - checkGLcall("glFrontFace(GL_CCW)"); - } - else - { - gl_info->gl_ops.gl.p_glFrontFace(GL_CW); - checkGLcall("glFrontFace(GL_CW)"); - } + mode = (mode == GL_CW) ? GL_CCW : GL_CW; + + gl_info->gl_ops.gl.p_glFrontFace(mode); + checkGLcall("glFrontFace"); } static void psorigin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 87fdb81b482..77b506d8da2 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -76,6 +76,7 @@ @ cdecl wined3d_device_get_ps_resource_view(ptr long) @ cdecl wined3d_device_get_ps_sampler(ptr long) @ cdecl wined3d_device_get_raster_status(ptr long ptr) +@ cdecl wined3d_device_get_rasterizer_state(ptr) @ cdecl wined3d_device_get_render_state(ptr long) @ cdecl wined3d_device_get_rendertarget_view(ptr long) @ cdecl wined3d_device_get_sampler_state(ptr long long) @@ -134,6 +135,7 @@ @ cdecl wined3d_device_set_ps_consts_i(ptr long long ptr) @ cdecl wined3d_device_set_ps_resource_view(ptr long ptr) @ cdecl wined3d_device_set_ps_sampler(ptr long ptr) +@ cdecl wined3d_device_set_rasterizer_state(ptr ptr) @ cdecl wined3d_device_set_render_state(ptr long long) @ cdecl wined3d_device_set_rendertarget_view(ptr long ptr long) @ cdecl wined3d_device_set_sampler_state(ptr long long long) @@ -178,6 +180,10 @@ @ cdecl wined3d_query_incref(ptr) @ cdecl wined3d_query_issue(ptr long) +@ cdecl wined3d_rasterizer_state_create(ptr ptr ptr) +@ cdecl wined3d_rasterizer_state_decref(ptr) +@ cdecl wined3d_rasterizer_state_incref(ptr) + @ cdecl wined3d_resource_get_desc(ptr ptr) @ cdecl wined3d_resource_get_parent(ptr) @ cdecl wined3d_resource_get_priority(ptr) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 71a8e2bbd02..2c30ec6c1b1 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2317,6 +2317,14 @@ HRESULT wined3d_init(struct wined3d *wined3d, DWORD flags) DECLSPEC_HIDDEN; BOOL wined3d_register_window(HWND window, struct wined3d_device *device) DECLSPEC_HIDDEN; void wined3d_unregister_window(HWND window) DECLSPEC_HIDDEN; +struct wined3d_rasterizer_state +{ + LONG refcount; + struct wined3d_rasterizer_state_desc desc; + + struct wined3d_device *device; +}; + struct wined3d_stream_output { struct wined3d_buffer *buffer; @@ -2382,6 +2390,7 @@ struct wined3d_state const struct wined3d_light_info *lights[MAX_ACTIVE_LIGHTS]; DWORD render_states[WINEHIGHEST_RENDER_STATE + 1]; + struct wined3d_rasterizer_state *rasterizer_state; }; #define WINED3D_UNMAPPED_STAGE ~0U @@ -3051,6 +3060,8 @@ void wined3d_cs_emit_set_index_buffer(struct wined3d_cs *cs, struct wined3d_buff void wined3d_cs_emit_set_material(struct wined3d_cs *cs, const struct wined3d_material *material) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_predication(struct wined3d_cs *cs, struct wined3d_query *predicate, BOOL value) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_rasterizer_state(struct wined3d_cs *cs, + struct wined3d_rasterizer_state *rasterizer_state) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_render_state(struct wined3d_cs *cs, enum wined3d_render_state state, DWORD value) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_rendertarget_view(struct wined3d_cs *cs, unsigned int view_idx, diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index ff1a949a11e..52c20a4a5b7 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -1893,6 +1893,11 @@ struct wined3d_buffer_desc UINT misc_flags; }; +struct wined3d_rasterizer_state_desc +{ + BOOL front_ccw; +}; + struct wined3d_rendertarget_view_desc { enum wined3d_format_id format_id; @@ -2014,6 +2019,7 @@ struct wined3d_buffer; struct wined3d_device; struct wined3d_palette; struct wined3d_query; +struct wined3d_rasterizer_state; struct wined3d_rendertarget_view; struct wined3d_resource; struct wined3d_sampler; @@ -2197,6 +2203,7 @@ struct wined3d_shader_resource_view * __cdecl wined3d_device_get_ps_resource_vie struct wined3d_sampler * __cdecl wined3d_device_get_ps_sampler(const struct wined3d_device *device, UINT idx); HRESULT __cdecl wined3d_device_get_raster_status(const struct wined3d_device *device, UINT swapchain_idx, struct wined3d_raster_status *raster_status); +struct wined3d_rasterizer_state * __cdecl wined3d_device_get_rasterizer_state(struct wined3d_device *device); DWORD __cdecl wined3d_device_get_render_state(const struct wined3d_device *device, enum wined3d_render_state state); struct wined3d_rendertarget_view * __cdecl wined3d_device_get_rendertarget_view(const struct wined3d_device *device, unsigned int view_idx); @@ -2287,6 +2294,8 @@ HRESULT __cdecl wined3d_device_set_ps_consts_i(struct wined3d_device *device, void __cdecl wined3d_device_set_ps_resource_view(struct wined3d_device *device, UINT idx, struct wined3d_shader_resource_view *view); void __cdecl wined3d_device_set_ps_sampler(struct wined3d_device *device, UINT idx, struct wined3d_sampler *sampler); +void __cdecl wined3d_device_set_rasterizer_state(struct wined3d_device *device, + struct wined3d_rasterizer_state *rasterizer_state); void __cdecl wined3d_device_set_render_state(struct wined3d_device *device, enum wined3d_render_state state, DWORD value); HRESULT __cdecl wined3d_device_set_rendertarget_view(struct wined3d_device *device, @@ -2424,6 +2433,11 @@ static inline HRESULT wined3d_private_store_set_private_data(struct wined3d_priv return WINED3D_OK; } +HRESULT __cdecl wined3d_rasterizer_state_create(struct wined3d_device *device, + const struct wined3d_rasterizer_state_desc *desc, struct wined3d_rasterizer_state **state); +ULONG __cdecl wined3d_rasterizer_state_decref(struct wined3d_rasterizer_state *state); +ULONG __cdecl wined3d_rasterizer_state_incref(struct wined3d_rasterizer_state *state); + void __cdecl wined3d_resource_get_desc(const struct wined3d_resource *resource, struct wined3d_resource_desc *desc); void * __cdecl wined3d_resource_get_parent(const struct wined3d_resource *resource);