[PATCH 5/6] d3d9: Handle stateblocks in d3d9_device_SetVertexShader().

Zebediah Figura z.figura12 at gmail.com
Thu Feb 21 18:53:58 CST 2019


Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/d3d9/d3d9_private.h       |   1 +
 dlls/d3d9/device.c             |  19 ++++-
 dlls/wined3d/device.c          |   6 ++
 dlls/wined3d/wined3d.spec      |   1 +
 dlls/wined3d/wined3d_private.h | 128 --------------------------------
 include/wine/wined3d.h         | 130 +++++++++++++++++++++++++++++++++
 6 files changed, 155 insertions(+), 130 deletions(-)

diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h
index 2c959057e7..7b1d04afad 100644
--- a/dlls/d3d9/d3d9_private.h
+++ b/dlls/d3d9/d3d9_private.h
@@ -118,6 +118,7 @@ struct d3d9_device
     struct d3d9_swapchain **implicit_swapchains;
 
     struct wined3d_stateblock *recording;
+    struct wined3d_stateblock_state *update_state;
 };
 
 HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wined3d *wined3d,
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index 1edfa375ca..3a270a4eac 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -990,6 +990,7 @@ static HRESULT d3d9_device_reset(struct d3d9_device *device,
 
         if (!extended)
         {
+            device->update_state = wined3d_device_get_stateblock_state(device->wined3d_device);
             wined3d_stateblock_decref(device->recording);
             device->recording = NULL;
             device->auto_mipmaps = 0;
@@ -2341,7 +2342,10 @@ static HRESULT WINAPI d3d9_device_BeginStateBlock(IDirect3DDevice9Ex *iface)
 
     wined3d_mutex_lock();
     if (SUCCEEDED(hr = wined3d_device_begin_stateblock(device->wined3d_device, &stateblock)))
+    {
         device->recording = stateblock;
+        device->update_state = &stateblock->stateblock_state;
+    }
     wined3d_mutex_unlock();
 
     return hr;
@@ -2357,6 +2361,7 @@ static HRESULT WINAPI d3d9_device_EndStateBlock(IDirect3DDevice9Ex *iface, IDire
     TRACE("iface %p, stateblock %p.\n", iface, stateblock);
 
     wined3d_mutex_lock();
+    device->update_state = wined3d_device_get_stateblock_state(device->wined3d_device);
     hr = wined3d_device_end_stateblock(device->wined3d_device);
     if (FAILED(hr))
     {
@@ -3385,8 +3390,16 @@ static HRESULT WINAPI d3d9_device_SetVertexShader(IDirect3DDevice9Ex *iface, IDi
     TRACE("iface %p, shader %p.\n", iface, shader);
 
     wined3d_mutex_lock();
-    wined3d_device_set_vertex_shader(device->wined3d_device,
-            shader_obj ? shader_obj->wined3d_shader : NULL);
+    if (shader_obj)
+        wined3d_shader_incref(shader_obj->wined3d_shader);
+    if (device->update_state->vs)
+        wined3d_shader_decref(device->update_state->vs);
+    device->update_state->vs = shader_obj ? shader_obj->wined3d_shader : NULL;
+    if (device->recording)
+        device->recording->changed.vertexShader = TRUE;
+    else
+        wined3d_device_set_vertex_shader(device->wined3d_device,
+                shader_obj ? shader_obj->wined3d_shader : NULL);
     wined3d_mutex_unlock();
 
     return D3D_OK;
@@ -4470,6 +4483,8 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine
         return hr;
     }
 
+    device->update_state = wined3d_device_get_stateblock_state(device->wined3d_device);
+
     wined3d_get_device_caps(wined3d, adapter, device_type, &caps);
     device->max_user_clip_planes = caps.MaxUserClipPlanes;
     if (flags & D3DCREATE_ADAPTERGROUP_DEVICE)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 7520d43d90..029a9b4ce2 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -5143,6 +5143,12 @@ HRESULT CDECL wined3d_device_set_dialog_box_mode(struct wined3d_device *device,
     return WINED3D_OK;
 }
 
+struct wined3d_stateblock_state * CDECL wined3d_device_get_stateblock_state(struct wined3d_device *device)
+{
+    TRACE("device %p.\n", device);
+
+    return &device->stateblock_state;
+}
 
 void CDECL wined3d_device_get_creation_parameters(const struct wined3d_device *device,
         struct wined3d_device_creation_parameters *parameters)
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index ac87f01f50..a976d82e99 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -101,6 +101,7 @@
 @ cdecl wined3d_device_get_sampler_state(ptr long long)
 @ cdecl wined3d_device_get_scissor_rects(ptr ptr ptr)
 @ cdecl wined3d_device_get_software_vertex_processing(ptr)
+@ cdecl wined3d_device_get_stateblock_state(ptr)
 @ cdecl wined3d_device_get_stream_output(ptr long ptr)
 @ cdecl wined3d_device_get_stream_source(ptr long ptr ptr ptr)
 @ cdecl wined3d_device_get_stream_source_freq(ptr long ptr)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 7096925534..c07e686ff4 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -258,13 +258,6 @@ static inline enum complex_fixup get_complex_fixup(struct color_fixup_desc fixup
 }
 
 /* Device caps */
-#define WINED3D_MAX_STREAMS         16
-#define WINED3D_MAX_TEXTURES        8
-#define WINED3D_MAX_FRAGMENT_SAMPLERS 16
-#define WINED3D_MAX_VERTEX_SAMPLERS 4
-#define WINED3D_MAX_COMBINED_SAMPLERS (WINED3D_MAX_FRAGMENT_SAMPLERS + WINED3D_MAX_VERTEX_SAMPLERS)
-#define WINED3D_MAX_ACTIVE_LIGHTS   8
-#define WINED3D_MAX_CLIP_DISTANCES  8
 #define MAX_CONSTANT_BUFFERS        15
 #define MAX_SAMPLER_OBJECTS         16
 #define MAX_SHADER_RESOURCE_VIEWS   128
@@ -667,10 +660,6 @@ enum wined3d_shader_conditional_op
 #define MAX_REG_INPUT 32
 #define MAX_REG_OUTPUT 32
 #define WINED3D_MAX_CBS 15
-#define WINED3D_MAX_CONSTS_B 16
-#define WINED3D_MAX_CONSTS_I 16
-#define WINED3D_MAX_VS_CONSTS_F 256
-#define WINED3D_MAX_PS_CONSTS_F 224
 
 /* FIXME: This needs to go up to 2048 for
  * Shader model 3 according to msdn (and for software shaders) */
@@ -2882,25 +2871,6 @@ struct wined3d_stream_output
     UINT offset;
 };
 
-struct wined3d_stream_state
-{
-    struct wined3d_buffer *buffer;
-    UINT offset;
-    UINT stride;
-    UINT frequency;
-    UINT flags;
-};
-
-#define LIGHTMAP_SIZE 43
-#define LIGHTMAP_HASHFUNC(x) ((x) % LIGHTMAP_SIZE)
-
-struct wined3d_light_state
-{
-    /* Light hashmap. Collisions are handled using linked lists. */
-    struct list light_map[LIGHTMAP_SIZE];
-    const struct wined3d_light_info *lights[WINED3D_MAX_ACTIVE_LIGHTS];
-};
-
 #define WINED3D_STATE_NO_REF        0x00000001
 #define WINED3D_STATE_INIT_DEFAULT  0x00000002
 
@@ -2977,40 +2947,6 @@ struct wined3d_dummy_textures
  * wined3d_device_create() ignores it. */
 #define WINED3DCREATE_MULTITHREADED 0x00000004
 
-struct wined3d_stateblock_state
-{
-    struct wined3d_vertex_declaration *vertex_declaration;
-    struct wined3d_stream_state streams[WINED3D_MAX_STREAMS + 1];
-    struct wined3d_buffer *index_buffer;
-    enum wined3d_format_id index_format;
-    int base_vertex_index;
-
-    struct wined3d_shader *vs;
-    struct wined3d_vec4 vs_consts_f[WINED3D_MAX_VS_CONSTS_F];
-    struct wined3d_ivec4 vs_consts_i[WINED3D_MAX_CONSTS_I];
-    BOOL vs_consts_b[WINED3D_MAX_CONSTS_B];
-
-    struct wined3d_shader *ps;
-    struct wined3d_vec4 ps_consts_f[WINED3D_MAX_PS_CONSTS_F];
-    struct wined3d_ivec4 ps_consts_i[WINED3D_MAX_CONSTS_I];
-    BOOL ps_consts_b[WINED3D_MAX_CONSTS_B];
-
-    DWORD rs[WINEHIGHEST_RENDER_STATE + 1];
-    struct wined3d_color blend_factor;
-
-    struct wined3d_texture *textures[WINED3D_MAX_COMBINED_SAMPLERS];
-    DWORD sampler_states[WINED3D_MAX_COMBINED_SAMPLERS][WINED3D_HIGHEST_SAMPLER_STATE + 1];
-    DWORD texture_states[WINED3D_MAX_TEXTURES][WINED3D_HIGHEST_TEXTURE_STATE + 1];
-
-    struct wined3d_matrix transforms[WINED3D_HIGHEST_TRANSFORM_STATE + 1];
-    struct wined3d_vec4 clip_planes[WINED3D_MAX_CLIP_DISTANCES];
-    struct wined3d_material material;
-    struct wined3d_viewport viewport;
-    RECT scissor_rect;
-
-    struct wined3d_light_state light_state;
-};
-
 struct wined3d_device
 {
     LONG ref;
@@ -3565,70 +3501,6 @@ struct wined3d_vertex_declaration
     BOOL have_half_floats;
 };
 
-struct wined3d_saved_states
-{
-    DWORD transform[(WINED3D_HIGHEST_TRANSFORM_STATE >> 5) + 1];
-    WORD streamSource;                          /* WINED3D_MAX_STREAMS, 16 */
-    WORD streamFreq;                            /* WINED3D_MAX_STREAMS, 16 */
-    DWORD renderState[(WINEHIGHEST_RENDER_STATE >> 5) + 1];
-    DWORD textureState[WINED3D_MAX_TEXTURES];   /* WINED3D_HIGHEST_TEXTURE_STATE + 1, 18 */
-    WORD samplerState[WINED3D_MAX_COMBINED_SAMPLERS];   /* WINED3D_HIGHEST_SAMPLER_STATE + 1, 14 */
-    DWORD clipplane;                            /* WINED3D_MAX_USER_CLIP_PLANES, 32 */
-    WORD pixelShaderConstantsB;                 /* WINED3D_MAX_CONSTS_B, 16 */
-    WORD pixelShaderConstantsI;                 /* WINED3D_MAX_CONSTS_I, 16 */
-    BOOL ps_consts_f[WINED3D_MAX_PS_CONSTS_F];
-    WORD vertexShaderConstantsB;                /* WINED3D_MAX_CONSTS_B, 16 */
-    WORD vertexShaderConstantsI;                /* WINED3D_MAX_CONSTS_I, 16 */
-    BOOL vs_consts_f[WINED3D_MAX_VS_CONSTS_F];
-    DWORD textures : 20;                        /* WINED3D_MAX_COMBINED_SAMPLERS, 20 */
-    DWORD indices : 1;
-    DWORD material : 1;
-    DWORD viewport : 1;
-    DWORD vertexDecl : 1;
-    DWORD pixelShader : 1;
-    DWORD vertexShader : 1;
-    DWORD scissorRect : 1;
-    DWORD blend_state : 1;
-    DWORD padding : 4;
-};
-
-struct StageState {
-    DWORD stage;
-    DWORD state;
-};
-
-struct wined3d_stateblock
-{
-    LONG                      ref;     /* Note: Ref counting not required */
-    struct wined3d_device *device;
-
-    /* Array indicating whether things have been set or changed */
-    struct wined3d_saved_states changed;
-    struct wined3d_stateblock_state stateblock_state;
-
-    /* Contained state management */
-    DWORD                     contained_render_states[WINEHIGHEST_RENDER_STATE + 1];
-    unsigned int              num_contained_render_states;
-    DWORD                     contained_transform_states[WINED3D_HIGHEST_TRANSFORM_STATE + 1];
-    unsigned int              num_contained_transform_states;
-    DWORD                     contained_vs_consts_i[WINED3D_MAX_CONSTS_I];
-    unsigned int              num_contained_vs_consts_i;
-    DWORD                     contained_vs_consts_b[WINED3D_MAX_CONSTS_B];
-    unsigned int              num_contained_vs_consts_b;
-    DWORD                     contained_vs_consts_f[WINED3D_MAX_VS_CONSTS_F];
-    unsigned int              num_contained_vs_consts_f;
-    DWORD                     contained_ps_consts_i[WINED3D_MAX_CONSTS_I];
-    unsigned int              num_contained_ps_consts_i;
-    DWORD                     contained_ps_consts_b[WINED3D_MAX_CONSTS_B];
-    unsigned int              num_contained_ps_consts_b;
-    DWORD                     contained_ps_consts_f[WINED3D_MAX_PS_CONSTS_F];
-    unsigned int              num_contained_ps_consts_f;
-    struct StageState         contained_tss_states[WINED3D_MAX_TEXTURES * (WINED3D_HIGHEST_TEXTURE_STATE + 1)];
-    unsigned int              num_contained_tss_states;
-    struct StageState         contained_sampler_states[WINED3D_MAX_COMBINED_SAMPLERS * WINED3D_HIGHEST_SAMPLER_STATE];
-    unsigned int              num_contained_sampler_states;
-};
-
 void stateblock_init_contained_states(struct wined3d_stateblock *stateblock) DECLSPEC_HIDDEN;
 
 void wined3d_stateblock_state_init(struct wined3d_stateblock_state *state,
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 9bd71878f0..1481ee9613 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -672,6 +672,7 @@ enum wined3d_transform_state
 };
 
 #define WINED3D_TS_WORLD_MATRIX(index)                          (enum wined3d_transform_state)(index + 256)
+#define WINED3D_HIGHEST_TRANSFORM_STATE WINED3D_TS_WORLD_MATRIX(255)
 
 enum wined3d_basis_type
 {
@@ -1583,6 +1584,17 @@ enum wined3d_shader_type
 #define WINED3D_VIEW_TEXTURE_ARRAY                              0x00000010
 
 #define WINED3D_MAX_VIEWPORTS                                   16
+#define WINED3D_MAX_STREAMS                                     16
+#define WINED3D_MAX_TEXTURES                                    8
+#define WINED3D_MAX_FRAGMENT_SAMPLERS                           16
+#define WINED3D_MAX_VERTEX_SAMPLERS                             4
+#define WINED3D_MAX_COMBINED_SAMPLERS                           (WINED3D_MAX_FRAGMENT_SAMPLERS + WINED3D_MAX_VERTEX_SAMPLERS)
+#define WINED3D_MAX_ACTIVE_LIGHTS                               8
+#define WINED3D_MAX_CLIP_DISTANCES                              8
+#define WINED3D_MAX_CONSTS_B                                    16
+#define WINED3D_MAX_CONSTS_I                                    16
+#define WINED3D_MAX_VS_CONSTS_F                                 256
+#define WINED3D_MAX_PS_CONSTS_F                                 224
 
 struct wined3d_display_mode
 {
@@ -2105,6 +2117,123 @@ struct wined3d_output_desc
     HMONITOR monitor;
 };
 
+struct wined3d_stream_state
+{
+    struct wined3d_buffer *buffer;
+    UINT offset;
+    UINT stride;
+    UINT frequency;
+    UINT flags;
+};
+
+#define LIGHTMAP_SIZE 43
+#define LIGHTMAP_HASHFUNC(x) ((x) % LIGHTMAP_SIZE)
+
+struct wined3d_light_state
+{
+    /* Light hashmap. Collisions are handled using linked lists. */
+    struct list light_map[LIGHTMAP_SIZE];
+    const struct wined3d_light_info *lights[WINED3D_MAX_ACTIVE_LIGHTS];
+};
+
+struct wined3d_stateblock_state
+{
+    struct wined3d_vertex_declaration *vertex_declaration;
+    struct wined3d_stream_state streams[WINED3D_MAX_STREAMS + 1];
+    struct wined3d_buffer *index_buffer;
+    enum wined3d_format_id index_format;
+    int base_vertex_index;
+
+    struct wined3d_shader *vs;
+    struct wined3d_vec4 vs_consts_f[WINED3D_MAX_VS_CONSTS_F];
+    struct wined3d_ivec4 vs_consts_i[WINED3D_MAX_CONSTS_I];
+    BOOL vs_consts_b[WINED3D_MAX_CONSTS_B];
+
+    struct wined3d_shader *ps;
+    struct wined3d_vec4 ps_consts_f[WINED3D_MAX_PS_CONSTS_F];
+    struct wined3d_ivec4 ps_consts_i[WINED3D_MAX_CONSTS_I];
+    BOOL ps_consts_b[WINED3D_MAX_CONSTS_B];
+
+    DWORD rs[WINEHIGHEST_RENDER_STATE + 1];
+    struct wined3d_color blend_factor;
+
+    struct wined3d_texture *textures[WINED3D_MAX_COMBINED_SAMPLERS];
+    DWORD sampler_states[WINED3D_MAX_COMBINED_SAMPLERS][WINED3D_HIGHEST_SAMPLER_STATE + 1];
+    DWORD texture_states[WINED3D_MAX_TEXTURES][WINED3D_HIGHEST_TEXTURE_STATE + 1];
+
+    struct wined3d_matrix transforms[WINED3D_HIGHEST_TRANSFORM_STATE + 1];
+    struct wined3d_vec4 clip_planes[WINED3D_MAX_CLIP_DISTANCES];
+    struct wined3d_material material;
+    struct wined3d_viewport viewport;
+    RECT scissor_rect;
+
+    struct wined3d_light_state light_state;
+};
+
+struct wined3d_saved_states
+{
+    DWORD transform[(WINED3D_HIGHEST_TRANSFORM_STATE >> 5) + 1];
+    WORD streamSource;                          /* WINED3D_MAX_STREAMS, 16 */
+    WORD streamFreq;                            /* WINED3D_MAX_STREAMS, 16 */
+    DWORD renderState[(WINEHIGHEST_RENDER_STATE >> 5) + 1];
+    DWORD textureState[WINED3D_MAX_TEXTURES];   /* WINED3D_HIGHEST_TEXTURE_STATE + 1, 18 */
+    WORD samplerState[WINED3D_MAX_COMBINED_SAMPLERS];   /* WINED3D_HIGHEST_SAMPLER_STATE + 1, 14 */
+    DWORD clipplane;                            /* WINED3D_MAX_USER_CLIP_PLANES, 32 */
+    WORD pixelShaderConstantsB;                 /* WINED3D_MAX_CONSTS_B, 16 */
+    WORD pixelShaderConstantsI;                 /* WINED3D_MAX_CONSTS_I, 16 */
+    BOOL ps_consts_f[WINED3D_MAX_PS_CONSTS_F];
+    WORD vertexShaderConstantsB;                /* WINED3D_MAX_CONSTS_B, 16 */
+    WORD vertexShaderConstantsI;                /* WINED3D_MAX_CONSTS_I, 16 */
+    BOOL vs_consts_f[WINED3D_MAX_VS_CONSTS_F];
+    DWORD textures : 20;                        /* WINED3D_MAX_COMBINED_SAMPLERS, 20 */
+    DWORD indices : 1;
+    DWORD material : 1;
+    DWORD viewport : 1;
+    DWORD vertexDecl : 1;
+    DWORD pixelShader : 1;
+    DWORD vertexShader : 1;
+    DWORD scissorRect : 1;
+    DWORD blend_state : 1;
+    DWORD padding : 4;
+};
+
+struct StageState {
+    DWORD stage;
+    DWORD state;
+};
+
+struct wined3d_stateblock
+{
+    LONG                      ref;     /* Note: Ref counting not required */
+    struct wined3d_device *device;
+
+    /* Array indicating whether things have been set or changed */
+    struct wined3d_saved_states changed;
+    struct wined3d_stateblock_state stateblock_state;
+
+    /* Contained state management */
+    DWORD                     contained_render_states[WINEHIGHEST_RENDER_STATE + 1];
+    unsigned int              num_contained_render_states;
+    DWORD                     contained_transform_states[WINED3D_HIGHEST_TRANSFORM_STATE + 1];
+    unsigned int              num_contained_transform_states;
+    DWORD                     contained_vs_consts_i[WINED3D_MAX_CONSTS_I];
+    unsigned int              num_contained_vs_consts_i;
+    DWORD                     contained_vs_consts_b[WINED3D_MAX_CONSTS_B];
+    unsigned int              num_contained_vs_consts_b;
+    DWORD                     contained_vs_consts_f[WINED3D_MAX_VS_CONSTS_F];
+    unsigned int              num_contained_vs_consts_f;
+    DWORD                     contained_ps_consts_i[WINED3D_MAX_CONSTS_I];
+    unsigned int              num_contained_ps_consts_i;
+    DWORD                     contained_ps_consts_b[WINED3D_MAX_CONSTS_B];
+    unsigned int              num_contained_ps_consts_b;
+    DWORD                     contained_ps_consts_f[WINED3D_MAX_PS_CONSTS_F];
+    unsigned int              num_contained_ps_consts_f;
+    struct StageState         contained_tss_states[WINED3D_MAX_TEXTURES * (WINED3D_HIGHEST_TEXTURE_STATE + 1)];
+    unsigned int              num_contained_tss_states;
+    struct StageState         contained_sampler_states[WINED3D_MAX_COMBINED_SAMPLERS * WINED3D_HIGHEST_SAMPLER_STATE];
+    unsigned int              num_contained_sampler_states;
+};
+
 struct wined3d_parent_ops
 {
     void (__stdcall *wined3d_object_destroyed)(void *parent);
@@ -2330,6 +2459,7 @@ DWORD __cdecl wined3d_device_get_sampler_state(const struct wined3d_device *devi
 void __cdecl wined3d_device_get_scissor_rects(const struct wined3d_device *device, unsigned int *rect_count,
         RECT *rect);
 BOOL __cdecl wined3d_device_get_software_vertex_processing(const struct wined3d_device *device);
+struct wined3d_stateblock_state * __cdecl wined3d_device_get_stateblock_state(struct wined3d_device *device);
 struct wined3d_buffer * __cdecl wined3d_device_get_stream_output(struct wined3d_device *device,
         UINT idx, UINT *offset);
 HRESULT __cdecl wined3d_device_get_stream_source(const struct wined3d_device *device,
-- 
2.20.1




More information about the wine-devel mailing list