[PATCH 3/5] wined3d: Introduce public API to set a wined3d_state object on a device.

Henri Verbeet hverbeet at codeweavers.com
Tue Feb 23 12:50:45 CST 2021


From: Rémi Bernon <rbernon at codeweavers.com>

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
This supersedes patches 200183 and 200187.

 dlls/wined3d/device.c     | 139 ++++++++++++++++++++++++++++++++++++--
 dlls/wined3d/stateblock.c |  22 ++++++
 dlls/wined3d/wined3d.spec |   5 ++
 include/wine/wined3d.h    |   6 ++
 4 files changed, 167 insertions(+), 5 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index c9df09b53483..7405a38e13b8 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -251,7 +251,7 @@ void wined3d_device_cleanup(struct wined3d_device *device)
     wine_rb_destroy(&device->depth_stencil_states, device_leftover_depth_stencil_state, NULL);
     wine_rb_destroy(&device->so_descs, device_free_so_desc, NULL);
 
-    heap_free(device->state);
+    wined3d_state_destroy(device->state);
     device->state = NULL;
     wined3d_decref(device->wined3d);
     device->wined3d = NULL;
@@ -1926,6 +1926,136 @@ void CDECL wined3d_device_get_scissor_rects(const struct wined3d_device *device,
         *rect_count = state->scissor_rect_count;
 }
 
+void CDECL wined3d_device_set_state(struct wined3d_device *device, struct wined3d_state *state)
+{
+    const struct wined3d_light_info *light;
+    unsigned int i, j;
+
+    TRACE("device %p, state %p.\n", device, state);
+
+    device->state = state;
+
+    for (i = 0; i < WINED3D_MAX_RENDER_TARGETS; ++i)
+    {
+        wined3d_cs_emit_set_rendertarget_view(device->cs, i, state->fb.render_targets[i]);
+    }
+
+    wined3d_cs_emit_set_depth_stencil_view(device->cs, state->fb.depth_stencil);
+    wined3d_cs_emit_set_vertex_declaration(device->cs, state->vertex_declaration);
+
+    for (i = 0; i < WINED3D_MAX_STREAM_OUTPUT_BUFFERS; ++i)
+    {
+        wined3d_cs_emit_set_stream_output(device->cs, i,
+                state->stream_output[i].buffer, state->stream_output[i].offset);
+    }
+
+    for (i = 0; i < WINED3D_MAX_STREAMS; ++i)
+    {
+        wined3d_cs_emit_set_stream_source(device->cs, i, state->streams[i].buffer,
+                state->streams[i].offset, state->streams[i].stride);
+    }
+
+    wined3d_cs_emit_set_index_buffer(device->cs, state->index_buffer, state->index_format, state->index_offset);
+
+    wined3d_cs_emit_set_predication(device->cs, state->predicate, state->predicate_value);
+
+    for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i)
+    {
+        wined3d_cs_emit_set_shader(device->cs, i, state->shader[i]);
+        for (j = 0; j < MAX_CONSTANT_BUFFERS; ++j)
+        {
+            wined3d_cs_emit_set_constant_buffer(device->cs, i, j, state->cb[i][j]);
+        }
+        for (j = 0; j < MAX_SAMPLER_OBJECTS; ++j)
+        {
+            wined3d_cs_emit_set_sampler(device->cs, i, j, state->sampler[i][j]);
+        }
+        for (j = 0; j < MAX_SHADER_RESOURCE_VIEWS; ++j)
+        {
+            wined3d_cs_emit_set_shader_resource_view(device->cs, i, j, state->shader_resource_view[i][j]);
+        }
+    }
+
+    for (i = 0; i < WINED3D_PIPELINE_COUNT; ++i)
+    {
+        for (j = 0; j < MAX_UNORDERED_ACCESS_VIEWS; ++j)
+        {
+            wined3d_cs_emit_set_unordered_access_view(device->cs, i, j, state->unordered_access_view[i][j], ~0);
+        }
+    }
+
+    wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_VS_F,
+            0, WINED3D_MAX_VS_CONSTS_F, state->vs_consts_f);
+    wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_VS_I,
+            0, WINED3D_MAX_CONSTS_I, state->vs_consts_i);
+    wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_VS_B,
+            0, WINED3D_MAX_CONSTS_B, state->vs_consts_b);
+
+    wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_PS_F,
+            0, WINED3D_MAX_PS_CONSTS_F, state->ps_consts_f);
+    wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_PS_I,
+            0, WINED3D_MAX_CONSTS_I, state->ps_consts_i);
+    wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_PS_B,
+            0, WINED3D_MAX_CONSTS_B, state->ps_consts_b);
+
+    for (i = 0; i < WINED3D_MAX_COMBINED_SAMPLERS; ++i)
+    {
+        wined3d_cs_emit_set_texture(device->cs, i, state->textures[i]);
+        for (j = 0; j < WINED3D_HIGHEST_SAMPLER_STATE + 1; ++j)
+        {
+            wined3d_cs_emit_set_sampler_state(device->cs, i, j, state->sampler_states[i][j]);
+        }
+    }
+
+    for (i = 0; i < WINED3D_MAX_TEXTURES; ++i)
+    {
+        for (j = 0; j < WINED3D_HIGHEST_TEXTURE_STATE + 1; ++j)
+        {
+            wined3d_cs_emit_set_texture_state(device->cs, i, j, state->texture_states[i][j]);
+        }
+    }
+
+    for (i = 0; i < WINED3D_HIGHEST_TRANSFORM_STATE + 1; ++i)
+    {
+        wined3d_cs_emit_set_transform(device->cs, i, state->transforms + i);
+    }
+
+    for (i = 0; i < WINED3D_MAX_CLIP_DISTANCES; ++i)
+    {
+        wined3d_cs_emit_set_clip_plane(device->cs, i, state->clip_planes + i);
+    }
+
+    wined3d_cs_emit_set_material(device->cs, &state->material);
+
+    wined3d_cs_emit_set_viewports(device->cs, state->viewport_count, state->viewports);
+    wined3d_cs_emit_set_scissor_rects(device->cs, state->scissor_rect_count, state->scissor_rects);
+
+    for (i = 0; i < LIGHTMAP_SIZE; ++i)
+    {
+        LIST_FOR_EACH_ENTRY(light, &state->light_state.light_map[i], struct wined3d_light_info, entry)
+        {
+            wined3d_device_set_light(device, light->OriginalIndex, &light->OriginalParms);
+            wined3d_cs_emit_set_light_enable(device->cs, light->OriginalIndex, light->glIndex != -1);
+        }
+    }
+
+    for (i = 0; i < WINEHIGHEST_RENDER_STATE + 1; ++i)
+    {
+        wined3d_cs_emit_set_render_state(device->cs, i, state->render_states[i]);
+    }
+
+    wined3d_cs_emit_set_blend_state(device->cs, state->blend_state, &state->blend_factor, state->sample_mask);
+    wined3d_cs_emit_set_depth_stencil_state(device->cs, state->depth_stencil_state, state->stencil_ref);
+    wined3d_cs_emit_set_rasterizer_state(device->cs, state->rasterizer_state);
+}
+
+struct wined3d_state * CDECL wined3d_device_get_state(struct wined3d_device *device)
+{
+    TRACE("device %p.\n", device);
+
+    return device->state;
+}
+
 void CDECL wined3d_device_set_vertex_declaration(struct wined3d_device *device,
         struct wined3d_vertex_declaration *declaration)
 {
@@ -5952,12 +6082,11 @@ HRESULT wined3d_device_init(struct wined3d_device *device, struct wined3d *wined
         return hr;
     }
 
-    if (!(state = heap_alloc_zero(sizeof(*state))))
+    if (FAILED(hr = wined3d_state_create(device, &state)))
     {
-        hr = E_OUTOFMEMORY;
+        ERR("Failed to create device state, hr %#x.\n", hr);
         goto err;
     }
-    state_init(state, &adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT);
 
     device->state = state;
     device->max_frame_latency = 3;
@@ -5974,7 +6103,7 @@ HRESULT wined3d_device_init(struct wined3d_device *device, struct wined3d *wined
 
 err:
     if (state)
-        heap_free(state);
+        wined3d_state_destroy(state);
     for (i = 0; i < ARRAY_SIZE(device->multistate_funcs); ++i)
     {
         heap_free(device->multistate_funcs[i]);
diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c
index 52124583c90c..97020e1cd407 100644
--- a/dlls/wined3d/stateblock.c
+++ b/dlls/wined3d/stateblock.c
@@ -1885,6 +1885,28 @@ void state_init(struct wined3d_state *state, const struct wined3d_d3d_info *d3d_
         state_init_default(state, d3d_info);
 }
 
+HRESULT CDECL wined3d_state_create(struct wined3d_device *device, struct wined3d_state **state)
+{
+    struct wined3d_state *object;
+
+    TRACE("device %p, state %p.\n", device, state);
+
+    if (!(object = heap_alloc_zero(sizeof(*object))))
+        return E_OUTOFMEMORY;
+    state_init(object, &device->adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT);
+
+    *state = object;
+    return S_OK;
+}
+
+void CDECL wined3d_state_destroy(struct wined3d_state *state)
+{
+    TRACE("state %p.\n", state);
+
+    state_cleanup(state);
+    heap_free(state);
+}
+
 static void stateblock_state_init_default(struct wined3d_stateblock_state *state,
         const struct wined3d_d3d_info *d3d_info)
 {
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index 44008119a8dd..6b6480cec8f0 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -98,6 +98,7 @@
 @ cdecl wined3d_device_get_rendertarget_view(ptr long)
 @ cdecl wined3d_device_get_scissor_rects(ptr ptr ptr)
 @ cdecl wined3d_device_get_software_vertex_processing(ptr)
+@ cdecl wined3d_device_get_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_swapchain(ptr long)
@@ -151,6 +152,7 @@
 @ cdecl wined3d_device_set_rendertarget_view(ptr long ptr long)
 @ cdecl wined3d_device_set_scissor_rects(ptr long ptr)
 @ cdecl wined3d_device_set_software_vertex_processing(ptr long)
+@ cdecl wined3d_device_set_state(ptr ptr)
 @ cdecl wined3d_device_set_stream_output(ptr long ptr long)
 @ cdecl wined3d_device_set_stream_source(ptr long ptr long long)
 @ cdecl wined3d_device_set_unordered_access_view(ptr long ptr long)
@@ -237,6 +239,9 @@
 @ cdecl wined3d_shader_resource_view_get_parent(ptr)
 @ cdecl wined3d_shader_resource_view_incref(ptr)
 
+@ cdecl wined3d_state_create(ptr ptr)
+@ cdecl wined3d_state_destroy(ptr)
+
 @ cdecl wined3d_stateblock_apply(ptr ptr)
 @ cdecl wined3d_stateblock_capture(ptr ptr)
 @ cdecl wined3d_stateblock_create(ptr ptr long ptr)
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 96cb6fc1d863..0d67e8c89d17 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2223,6 +2223,7 @@ struct wined3d_resource;
 struct wined3d_sampler;
 struct wined3d_shader;
 struct wined3d_shader_resource_view;
+struct wined3d_state;
 struct wined3d_stateblock;
 struct wined3d_swapchain;
 struct wined3d_swapchain_state;
@@ -2432,6 +2433,7 @@ struct wined3d_rendertarget_view * __cdecl wined3d_device_get_rendertarget_view(
 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_state * __cdecl wined3d_device_get_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,
@@ -2522,6 +2524,7 @@ HRESULT __cdecl wined3d_device_set_rendertarget_view(struct wined3d_device *devi
 void __cdecl wined3d_device_set_scissor_rects(struct wined3d_device *device,
         unsigned int rect_count, const RECT *rect);
 void __cdecl wined3d_device_set_software_vertex_processing(struct wined3d_device *device, BOOL software);
+void __cdecl wined3d_device_set_state(struct wined3d_device *device, struct wined3d_state *state);
 void __cdecl wined3d_device_set_stream_output(struct wined3d_device *device, UINT idx,
         struct wined3d_buffer *buffer, UINT offset);
 HRESULT __cdecl wined3d_device_set_stream_source(struct wined3d_device *device,
@@ -2730,6 +2733,9 @@ void __cdecl wined3d_shader_resource_view_generate_mipmaps(struct wined3d_shader
 void * __cdecl wined3d_shader_resource_view_get_parent(const struct wined3d_shader_resource_view *view);
 ULONG __cdecl wined3d_shader_resource_view_incref(struct wined3d_shader_resource_view *view);
 
+HRESULT __cdecl wined3d_state_create(struct wined3d_device *device, struct wined3d_state **state);
+void __cdecl wined3d_state_destroy(struct wined3d_state *state);
+
 void __cdecl wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock,
         struct wined3d_stateblock *device_state);
 void __cdecl wined3d_stateblock_capture(struct wined3d_stateblock *stateblock,
-- 
2.20.1




More information about the wine-devel mailing list