[PATCH v2 3/5] wined3d: Move the fill mode to wined3d_rasterizer_state.

Zebediah Figura z.figura12 at gmail.com
Thu Mar 5 19:28:09 CST 2020


Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/d3d11/device.c            |  2 -
 dlls/d3d11/state.c             |  1 +
 dlls/wined3d/device.c          | 70 ++++++++++++++++++++++++++++++----
 dlls/wined3d/state.c           | 19 +++++----
 dlls/wined3d/wined3d_private.h |  3 +-
 include/wine/wined3d.h         |  1 +
 6 files changed, 77 insertions(+), 19 deletions(-)

diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c
index 212881a9b7..4c42fa284c 100644
--- a/dlls/d3d11/device.c
+++ b/dlls/d3d11/device.c
@@ -941,7 +941,6 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_RSSetState(ID3D11DeviceCon
     if (!(rasterizer_state_impl = unsafe_impl_from_ID3D11RasterizerState(rasterizer_state)))
     {
         wined3d_device_set_rasterizer_state(device->wined3d_device, NULL);
-        wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_FILLMODE, WINED3D_FILL_SOLID);
         wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_CULLMODE, WINED3D_CULL_BACK);
         wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_SLOPESCALEDEPTHBIAS, 0);
         wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_DEPTHBIAS, 0);
@@ -955,7 +954,6 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_RSSetState(ID3D11DeviceCon
     wined3d_device_set_rasterizer_state(device->wined3d_device, rasterizer_state_impl->wined3d_state);
 
     desc = &rasterizer_state_impl->desc;
-    wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_FILLMODE, desc->FillMode);
     wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_CULLMODE, desc->CullMode);
     scale_bias.f = desc->SlopeScaledDepthBias;
     const_bias.f = desc->DepthBias;
diff --git a/dlls/d3d11/state.c b/dlls/d3d11/state.c
index 92b75f8e1f..d63a1bc699 100644
--- a/dlls/d3d11/state.c
+++ b/dlls/d3d11/state.c
@@ -1076,6 +1076,7 @@ static HRESULT d3d_rasterizer_state_init(struct d3d_rasterizer_state *state, str
         return E_FAIL;
     }
 
+    wined3d_desc.fill_mode = desc->FillMode;
     wined3d_desc.front_ccw = desc->FrontCounterClockwise;
     wined3d_desc.depth_clip = desc->DepthClipEnable;
     wined3d_desc.depth_bias_clamp = desc->DepthBiasClamp;
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index cdb3202ac1..69ff7dd0cd 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -521,6 +521,13 @@ static void device_leftover_sampler(struct wine_rb_entry *entry, void *context)
     ERR("Leftover sampler %p.\n", sampler);
 }
 
+static void device_free_rasterizer_state(struct wine_rb_entry *entry, void *context)
+{
+    struct wined3d_rasterizer_state *state = WINE_RB_ENTRY_VALUE(entry, struct wined3d_rasterizer_state, entry);
+
+    wined3d_rasterizer_state_decref(state);
+}
+
 void wined3d_device_cleanup(struct wined3d_device *device)
 {
     unsigned int i;
@@ -529,6 +536,7 @@ void wined3d_device_cleanup(struct wined3d_device *device)
         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);
 
     wined3d_cs_destroy(device->cs);
 
@@ -3477,11 +3485,11 @@ 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;
     unsigned int i, j, start, idx;
     struct wined3d_color colour;
     struct wined3d_range range;
-    BOOL set_blend_state;
     DWORD map, stage;
 
     TRACE("device %p, stateblock %p.\n", device, stateblock);
@@ -3578,17 +3586,53 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device,
         {
             j = wined3d_bit_scan(&map);
             idx = i * word_bit_count + j;
-            if (idx != WINED3D_RS_BLENDFACTOR)
+
+            switch (idx)
             {
-                wined3d_device_set_render_state(device, idx, state->rs[idx]);
-                continue;
+                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);
+                    }
+                    break;
+
+                case WINED3D_RS_FILLMODE:
+                    set_rasterizer_state = TRUE;
+                    break;
+
+                default:
+                    wined3d_device_set_render_state(device, idx, state->rs[idx]);
+                    break;
             }
+        }
+    }
 
-            if (!set_blend_state)
+    if (set_rasterizer_state)
+    {
+        struct wined3d_rasterizer_state *rasterizer_state;
+        struct wined3d_rasterizer_state_desc desc;
+        struct wine_rb_entry *entry;
+
+        desc.fill_mode = state->rs[WINED3D_RS_FILLMODE];
+        desc.front_ccw = FALSE;
+        desc.depth_bias_clamp = 0.0f;
+        desc.depth_clip = TRUE;
+
+        if ((entry = wine_rb_get(&device->rasterizer_states, &desc)))
+        {
+            rasterizer_state = WINE_RB_ENTRY_VALUE(entry, struct wined3d_rasterizer_state, entry);
+            wined3d_device_set_rasterizer_state(device, rasterizer_state);
+        }
+        else if (SUCCEEDED(wined3d_rasterizer_state_create(device, &desc, NULL,
+                &wined3d_null_parent_ops, &rasterizer_state)))
+        {
+            wined3d_device_set_rasterizer_state(device, rasterizer_state);
+            if (wine_rb_put(&device->rasterizer_states, &desc, &rasterizer_state->entry) == -1)
             {
-                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);
+                ERR("Failed to insert rasterizer state.\n");
+                wined3d_rasterizer_state_decref(rasterizer_state);
             }
         }
     }
@@ -5392,6 +5436,13 @@ static int wined3d_sampler_compare(const void *key, const struct wine_rb_entry *
     return memcmp(&sampler->desc, key, sizeof(sampler->desc));
 }
 
+static int wined3d_rasterizer_state_compare(const void *key, const struct wine_rb_entry *entry)
+{
+    const struct wined3d_rasterizer_state *state = WINE_RB_ENTRY_VALUE(entry, struct wined3d_rasterizer_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)
@@ -5452,6 +5503,7 @@ HRESULT wined3d_device_init(struct wined3d_device *device, struct wined3d *wined
     fragment_pipeline = adapter->fragment_pipe;
 
     wine_rb_init(&device->samplers, wined3d_sampler_compare);
+    wine_rb_init(&device->rasterizer_states, wined3d_rasterizer_state_compare);
 
     if (vertex_pipeline->vp_states && fragment_pipeline->states
             && FAILED(hr = compile_state_table(device->state_table, device->multistate_funcs,
@@ -5460,6 +5512,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);
         wined3d_decref(device->wined3d);
         return hr;
     }
@@ -5496,6 +5549,7 @@ err:
         heap_free(device->multistate_funcs[i]);
     }
     wine_rb_destroy(&device->samplers, NULL, NULL);
+    wine_rb_destroy(&device->rasterizer_states, NULL, NULL);
     wined3d_decref(device->wined3d);
     return hr;
 }
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index a4d88e1bfc..388116bc66 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -171,10 +171,9 @@ void state_nop(struct wined3d_context *context, const struct wined3d_state *stat
     TRACE("%s: nop in current pipe config.\n", debug_d3dstate(state_id));
 }
 
-static void state_fillmode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+static void fillmode(const struct wined3d_rasterizer_state *r, const struct wined3d_gl_info *gl_info)
 {
-    const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info;
-    enum wined3d_fill_mode mode = state->render_states[WINED3D_RS_FILLMODE];
+    enum wined3d_fill_mode mode = r ? r->desc.fill_mode : WINED3D_FILL_SOLID;
 
     switch (mode)
     {
@@ -4324,9 +4323,10 @@ static void depth_clip(const struct wined3d_rasterizer_state *r, const struct wi
 static void rasterizer(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_rasterizer_state *r = state->rasterizer_state;
     GLenum mode;
 
-    mode = state->rasterizer_state && state->rasterizer_state->desc.front_ccw ? GL_CCW : GL_CW;
+    mode = r && r->desc.front_ccw ? GL_CCW : GL_CW;
     if (context->render_offscreen)
         mode = (mode == GL_CW) ? GL_CCW : GL_CW;
 
@@ -4334,21 +4334,24 @@ static void rasterizer(struct wined3d_context *context, const struct wined3d_sta
     checkGLcall("glFrontFace");
     if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_DEPTHBIAS)))
         state_depthbias(context, state, STATE_RENDER(WINED3D_RS_DEPTHBIAS));
-    depth_clip(state->rasterizer_state, gl_info);
+    fillmode(r, gl_info);
+    depth_clip(r, gl_info);
 }
 
 static void rasterizer_cc(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_rasterizer_state *r = state->rasterizer_state;
     GLenum mode;
 
-    mode = state->rasterizer_state && state->rasterizer_state->desc.front_ccw ? GL_CCW : GL_CW;
+    mode = r && r->desc.front_ccw ? GL_CCW : GL_CW;
 
     gl_info->gl_ops.gl.p_glFrontFace(mode);
     checkGLcall("glFrontFace");
     if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_DEPTHBIAS)))
         state_depthbias(context, state, STATE_RENDER(WINED3D_RS_DEPTHBIAS));
-    depth_clip(state->rasterizer_state, gl_info);
+    fillmode(r, gl_info);
+    depth_clip(r, gl_info);
 }
 
 static void psorigin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
@@ -4588,7 +4591,6 @@ const struct wined3d_state_entry_template misc_state_template[] =
     { 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_FILLMODE),                  { STATE_RENDER(WINED3D_RS_FILLMODE),                  state_fillmode      }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3D_RS_LINEPATTERN),               { STATE_RENDER(WINED3D_RS_LINEPATTERN),               state_linepattern   }, WINED3D_GL_LEGACY_CONTEXT       },
     { STATE_RENDER(WINED3D_RS_LINEPATTERN),               { STATE_RENDER(WINED3D_RS_LINEPATTERN),               state_linepattern_w }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3D_RS_MONOENABLE),                { STATE_RENDER(WINED3D_RS_MONOENABLE),                state_monoenable    }, WINED3D_GL_EXT_NONE             },
@@ -5426,6 +5428,7 @@ static void validate_state_table(struct wined3d_state_entry *state_table)
     {
         {  1,   1},
         {  3,   3},
+        {  8,   8},
         { 17,  18},
         { 21,  21},
         { 42,  45},
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 23540295bb..db4660cf58 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3155,6 +3155,7 @@ struct wined3d_rasterizer_state
     const struct wined3d_parent_ops *parent_ops;
 
     struct wined3d_device *device;
+    struct wine_rb_entry entry;
 };
 
 struct wined3d_stream_output
@@ -3293,7 +3294,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;
+    struct wine_rb_tree samplers, rasterizer_states;
 
     /* Render Target Support */
     struct wined3d_fb_state fb;
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index cb8f19981a..2370ca469f 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2033,6 +2033,7 @@ struct wined3d_blend_state_desc
 
 struct wined3d_rasterizer_state_desc
 {
+    enum wined3d_fill_mode fill_mode;
     BOOL front_ccw;
     float depth_bias_clamp;
     BOOL depth_clip;
-- 
2.25.1




More information about the wine-devel mailing list