Zebediah Figura : wined3d: Introduce a separate structure for stateblock state and store vertex shader state therein.

Alexandre Julliard julliard at winehq.org
Mon Jan 28 16:17:01 CST 2019


Module: wine
Branch: master
Commit: f2e7906d9cd17b4cdab28a71cc9ca8ecaaf0c26c
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=f2e7906d9cd17b4cdab28a71cc9ca8ecaaf0c26c

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Sun Jan 27 22:44:52 2019 -0600

wined3d: Introduce a separate structure for stateblock state and store vertex shader state therein.

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/wined3d/device.c          | 25 +++++++++++++++++++++----
 dlls/wined3d/stateblock.c      | 40 +++++++++++++++++++++++++++++-----------
 dlls/wined3d/wined3d_private.h | 10 ++++++++++
 3 files changed, 60 insertions(+), 15 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index a7e274d..b7071db 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -486,6 +486,8 @@ ULONG CDECL wined3d_device_decref(struct wined3d_device *device)
     {
         UINT i;
 
+        wined3d_stateblock_state_cleanup(&device->stateblock_state);
+
         wined3d_cs_destroy(device->cs);
 
         if (device->recording && wined3d_stateblock_decref(device->recording))
@@ -2208,21 +2210,29 @@ struct wined3d_vertex_declaration * CDECL wined3d_device_get_vertex_declaration(
 
 void CDECL wined3d_device_set_vertex_shader(struct wined3d_device *device, struct wined3d_shader *shader)
 {
-    struct wined3d_shader *prev = device->update_state->shader[WINED3D_SHADER_TYPE_VERTEX];
+    struct wined3d_shader *prev = device->state.shader[WINED3D_SHADER_TYPE_VERTEX];
 
     TRACE("device %p, shader %p.\n", device, shader);
 
+    if (shader)
+        wined3d_shader_incref(shader);
+    if (device->update_stateblock_state->vs)
+        wined3d_shader_decref(device->update_stateblock_state->vs);
+    device->update_stateblock_state->vs = shader;
+
     if (device->recording)
+    {
         device->recording->changed.vertexShader = TRUE;
+        return;
+    }
 
     if (shader == prev)
         return;
 
     if (shader)
         wined3d_shader_incref(shader);
-    device->update_state->shader[WINED3D_SHADER_TYPE_VERTEX] = shader;
-    if (!device->recording)
-        wined3d_cs_emit_set_shader(device->cs, WINED3D_SHADER_TYPE_VERTEX, shader);
+    device->state.shader[WINED3D_SHADER_TYPE_VERTEX] = shader;
+    wined3d_cs_emit_set_shader(device->cs, WINED3D_SHADER_TYPE_VERTEX, shader);
     if (prev)
         wined3d_shader_decref(prev);
 }
@@ -3552,6 +3562,7 @@ HRESULT CDECL wined3d_device_begin_stateblock(struct wined3d_device *device)
 
     device->recording = stateblock;
     device->update_state = &stateblock->state;
+    device->update_stateblock_state = &stateblock->stateblock_state;
 
     TRACE("Recording stateblock %p.\n", stateblock);
 
@@ -3577,6 +3588,7 @@ HRESULT CDECL wined3d_device_end_stateblock(struct wined3d_device *device,
     *stateblock = object;
     device->recording = NULL;
     device->update_state = &device->state;
+    device->update_stateblock_state = &device->stateblock_state;
 
     TRACE("Returning stateblock %p.\n", *stateblock);
 
@@ -4998,6 +5010,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
         }
         wined3d_cs_emit_reset_state(device->cs);
         state_cleanup(&device->state);
+        wined3d_stateblock_state_cleanup(&device->stateblock_state);
 
         if (device->d3d_initialized)
             wined3d_device_delete_opengl_contexts(device);
@@ -5005,6 +5018,8 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
         memset(&device->state, 0, sizeof(device->state));
         state_init(&device->state, &device->fb, &device->adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT);
         device->update_state = &device->state;
+        memset(&device->stateblock_state, 0, sizeof(device->stateblock_state));
+        device->update_stateblock_state = &device->stateblock_state;
 
         device_init_swapchain_state(device, swapchain);
         if (wined3d_settings.logo)
@@ -5279,6 +5294,7 @@ HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d,
 
     state_init(&device->state, &device->fb, &adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT);
     device->update_state = &device->state;
+    device->update_stateblock_state = &device->stateblock_state;
 
     device->max_frame_latency = 3;
 
@@ -5286,6 +5302,7 @@ HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d,
     {
         WARN("Failed to create command stream.\n");
         state_cleanup(&device->state);
+        wined3d_stateblock_state_cleanup(&device->stateblock_state);
         hr = E_FAIL;
         goto err;
     }
diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c
index 9539ae0..4ead27b 100644
--- a/dlls/wined3d/stateblock.c
+++ b/dlls/wined3d/stateblock.c
@@ -521,6 +521,17 @@ void state_unbind_resources(struct wined3d_state *state)
     }
 }
 
+void wined3d_stateblock_state_cleanup(struct wined3d_stateblock_state *state)
+{
+    struct wined3d_shader *shader;
+
+    if ((shader = state->vs))
+    {
+        state->vs = NULL;
+        wined3d_shader_decref(shader);
+    }
+}
+
 void state_cleanup(struct wined3d_state *state)
 {
     unsigned int counter;
@@ -554,6 +565,7 @@ ULONG CDECL wined3d_stateblock_decref(struct wined3d_stateblock *stateblock)
     if (!refcount)
     {
         state_cleanup(&stateblock->state);
+        wined3d_stateblock_state_cleanup(&stateblock->stateblock_state);
         heap_free(stateblock);
     }
 
@@ -669,6 +681,7 @@ static void wined3d_state_record_lights(struct wined3d_state *dst_state, const s
 
 void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock)
 {
+    const struct wined3d_stateblock_state *state = &stateblock->device->stateblock_state;
     const struct wined3d_state *src_state = &stateblock->device->state;
     unsigned int i;
     DWORD map;
@@ -677,18 +690,15 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock)
 
     TRACE("Capturing state %p.\n", src_state);
 
-    if (stateblock->changed.vertexShader && stateblock->state.shader[WINED3D_SHADER_TYPE_VERTEX]
-            != src_state->shader[WINED3D_SHADER_TYPE_VERTEX])
+    if (stateblock->changed.vertexShader && stateblock->stateblock_state.vs != state->vs)
     {
-        TRACE("Updating vertex shader from %p to %p\n",
-                stateblock->state.shader[WINED3D_SHADER_TYPE_VERTEX],
-                src_state->shader[WINED3D_SHADER_TYPE_VERTEX]);
+        TRACE("Updating vertex shader from %p to %p.\n", stateblock->stateblock_state.vs, state->vs);
 
-        if (src_state->shader[WINED3D_SHADER_TYPE_VERTEX])
-            wined3d_shader_incref(src_state->shader[WINED3D_SHADER_TYPE_VERTEX]);
-        if (stateblock->state.shader[WINED3D_SHADER_TYPE_VERTEX])
-            wined3d_shader_decref(stateblock->state.shader[WINED3D_SHADER_TYPE_VERTEX]);
-        stateblock->state.shader[WINED3D_SHADER_TYPE_VERTEX] = src_state->shader[WINED3D_SHADER_TYPE_VERTEX];
+        if (state->vs)
+            wined3d_shader_incref(state->vs);
+        if (stateblock->stateblock_state.vs)
+            wined3d_shader_decref(stateblock->stateblock_state.vs);
+        stateblock->stateblock_state.vs = state->vs;
     }
 
     /* Vertex shader float constants. */
@@ -978,6 +988,7 @@ static void apply_lights(struct wined3d_device *device, const struct wined3d_sta
 
 void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock)
 {
+    struct wined3d_stateblock_state *state = &stateblock->device->stateblock_state;
     struct wined3d_device *device = stateblock->device;
     unsigned int i;
     DWORD map;
@@ -985,7 +996,14 @@ void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock)
     TRACE("Applying stateblock %p to device %p.\n", stateblock, device);
 
     if (stateblock->changed.vertexShader)
-        wined3d_device_set_vertex_shader(device, stateblock->state.shader[WINED3D_SHADER_TYPE_VERTEX]);
+    {
+        if (stateblock->stateblock_state.vs)
+            wined3d_shader_incref(stateblock->stateblock_state.vs);
+        if (state->vs)
+            wined3d_shader_decref(state->vs);
+        state->vs = stateblock->stateblock_state.vs;
+        wined3d_device_set_vertex_shader(device, stateblock->stateblock_state.vs);
+    }
 
     /* Vertex Shader Constants. */
     for (i = 0; i < stateblock->num_contained_vs_consts_f; ++i)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 7b265f3..e45ee7b 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2968,6 +2968,11 @@ struct wined3d_dummy_textures
  * wined3d_device_create() ignores it. */
 #define WINED3DCREATE_MULTITHREADED 0x00000004
 
+struct wined3d_stateblock_state
+{
+    struct wined3d_shader *vs;
+};
+
 struct wined3d_device
 {
     LONG ref;
@@ -3006,6 +3011,8 @@ struct wined3d_device
     struct wined3d_state state;
     struct wined3d_state *update_state;
     struct wined3d_stateblock *recording;
+    struct wined3d_stateblock_state stateblock_state;
+    struct wined3d_stateblock_state *update_stateblock_state;
 
     /* Internal use fields  */
     struct wined3d_device_creation_parameters create_parms;
@@ -3556,6 +3563,7 @@ struct wined3d_stateblock
     /* Array indicating whether things have been set or changed */
     struct wined3d_saved_states changed;
     struct wined3d_state state;
+    struct wined3d_stateblock_state stateblock_state;
 
     /* Contained state management */
     DWORD                     contained_render_states[WINEHIGHEST_RENDER_STATE + 1];
@@ -3582,6 +3590,8 @@ struct wined3d_stateblock
 
 void stateblock_init_contained_states(struct wined3d_stateblock *stateblock) DECLSPEC_HIDDEN;
 
+void wined3d_stateblock_state_cleanup(struct wined3d_stateblock_state *state) DECLSPEC_HIDDEN;
+
 void state_cleanup(struct wined3d_state *state) DECLSPEC_HIDDEN;
 void wined3d_state_enable_light(struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info,
         struct wined3d_light_info *light_info, BOOL enable) DECLSPEC_HIDDEN;




More information about the wine-cvs mailing list