[PATCH 4/5] wined3d: Store the feature level in the wined3d_state structure.

Henri Verbeet hverbeet at codeweavers.com
Mon Mar 15 10:11:36 CDT 2021


Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 dlls/d3d11/device.c            |  4 ++--
 dlls/wined3d/cs.c              | 34 +++++++++++++++++++++++++++++++---
 dlls/wined3d/device.c          | 17 ++++++-----------
 dlls/wined3d/shader.c          |  4 ++--
 dlls/wined3d/stateblock.c      | 13 +++++++++++--
 dlls/wined3d/wined3d.spec      |  2 +-
 dlls/wined3d/wined3d_private.h | 15 +++++++++------
 include/wine/wined3d.h         |  2 +-
 8 files changed, 63 insertions(+), 28 deletions(-)

diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c
index ff628eeaae1..414560be72a 100644
--- a/dlls/d3d11/device.c
+++ b/dlls/d3d11/device.c
@@ -6475,7 +6475,8 @@ static void CDECL device_parent_wined3d_device_created(struct wined3d_device_par
     device->wined3d_device = wined3d_device;
     device->immediate_context.wined3d_context = wined3d_device_get_immediate_context(wined3d_device);
 
-    device->feature_level = d3d_feature_level_from_wined3d(wined3d_device_get_feature_level(wined3d_device));
+    wined3d_state = wined3d_device_get_state(device->wined3d_device);
+    device->feature_level = d3d_feature_level_from_wined3d(wined3d_state_get_feature_level(wined3d_state));
 
     if (FAILED(hr = d3d11_device_CreateDeviceContextState(&device->ID3D11Device2_iface, 0, &device->feature_level,
             1, D3D11_SDK_VERSION, device->d3d11_only ? &IID_ID3D11Device2 : &IID_ID3D10Device1, NULL,
@@ -6486,7 +6487,6 @@ static void CDECL device_parent_wined3d_device_created(struct wined3d_device_par
     }
 
     device->state = impl_from_ID3DDeviceContextState(state);
-    wined3d_state = wined3d_device_get_state(device->wined3d_device);
     if (!d3d_device_context_state_add_entry(device->state, device, wined3d_state))
         ERR("Failed to add entry for wined3d state %p, device %p.\n", wined3d_state, device);
 
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 0d28cb7e0b1..69f6a437e97 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -62,6 +62,7 @@ enum wined3d_cs_op
     WINED3D_CS_OP_SET_MATERIAL,
     WINED3D_CS_OP_SET_LIGHT,
     WINED3D_CS_OP_SET_LIGHT_ENABLE,
+    WINED3D_CS_OP_SET_FEATURE_LEVEL,
     WINED3D_CS_OP_PUSH_CONSTANTS,
     WINED3D_CS_OP_RESET_STATE,
     WINED3D_CS_OP_CALLBACK,
@@ -340,6 +341,12 @@ struct wined3d_cs_set_light_enable
     BOOL enable;
 };
 
+struct wined3d_cs_set_feature_level
+{
+    enum wined3d_cs_op opcode;
+    enum wined3d_feature_level level;
+};
+
 struct wined3d_cs_push_constants
 {
     enum wined3d_cs_op opcode;
@@ -506,6 +513,7 @@ static const char *debug_cs_op(enum wined3d_cs_op op)
         WINED3D_TO_STR(WINED3D_CS_OP_SET_MATERIAL);
         WINED3D_TO_STR(WINED3D_CS_OP_SET_LIGHT);
         WINED3D_TO_STR(WINED3D_CS_OP_SET_LIGHT_ENABLE);
+        WINED3D_TO_STR(WINED3D_CS_OP_SET_FEATURE_LEVEL);
         WINED3D_TO_STR(WINED3D_CS_OP_PUSH_CONSTANTS);
         WINED3D_TO_STR(WINED3D_CS_OP_RESET_STATE);
         WINED3D_TO_STR(WINED3D_CS_OP_CALLBACK);
@@ -2002,6 +2010,24 @@ void wined3d_cs_emit_set_light_enable(struct wined3d_cs *cs, unsigned int idx, B
     wined3d_device_context_submit(&cs->c, WINED3D_CS_QUEUE_DEFAULT);
 }
 
+static void wined3d_cs_exec_set_feature_level(struct wined3d_cs *cs, const void *data)
+{
+    const struct wined3d_cs_set_feature_level *op = data;
+
+    cs->state.feature_level = op->level;
+}
+
+void wined3d_cs_emit_set_feature_level(struct wined3d_cs *cs, enum wined3d_feature_level level)
+{
+    struct wined3d_cs_set_feature_level *op;
+
+    op = wined3d_device_context_require_space(&cs->c, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT);
+    op->opcode = WINED3D_CS_OP_SET_FEATURE_LEVEL;
+    op->level = level;
+
+    wined3d_device_context_submit(&cs->c, WINED3D_CS_QUEUE_DEFAULT);
+}
+
 static const struct
 {
     size_t offset;
@@ -2662,6 +2688,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void
     /* WINED3D_CS_OP_SET_MATERIAL                */ wined3d_cs_exec_set_material,
     /* WINED3D_CS_OP_SET_LIGHT                   */ wined3d_cs_exec_set_light,
     /* WINED3D_CS_OP_SET_LIGHT_ENABLE            */ wined3d_cs_exec_set_light_enable,
+    /* WINED3D_CS_OP_SET_FEATURE_LEVEL           */ wined3d_cs_exec_set_feature_level,
     /* WINED3D_CS_OP_PUSH_CONSTANTS              */ wined3d_cs_exec_push_constants,
     /* WINED3D_CS_OP_RESET_STATE                 */ wined3d_cs_exec_reset_state,
     /* WINED3D_CS_OP_CALLBACK                    */ wined3d_cs_exec_callback,
@@ -2981,7 +3008,7 @@ static DWORD WINAPI wined3d_cs_run(void *ctx)
     FreeLibraryAndExitThread(wined3d_module, 0);
 }
 
-struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device)
+struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device, enum wined3d_feature_level feature_level)
 {
     const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
     struct wined3d_cs *cs;
@@ -2989,17 +3016,18 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device)
     if (!(cs = heap_alloc_zero(sizeof(*cs))))
         return NULL;
 
-    if (FAILED(wined3d_state_create(device, &cs->c.state)))
+    if (!(cs->c.state = heap_alloc_zero(sizeof(*cs->c.state))))
     {
         heap_free(cs);
         return NULL;
     }
+    state_init(cs->c.state, &device->adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT, feature_level);
 
     cs->c.ops = &wined3d_cs_st_ops;
     cs->c.device = device;
     cs->serialize_commands = TRACE_ON(d3d_sync) || wined3d_settings.cs_multithreaded & WINED3D_CSMT_SERIALIZE;
 
-    state_init(&cs->state, d3d_info, WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT);
+    state_init(&cs->state, d3d_info, WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT, cs->c.state->feature_level);
 
     cs->data_size = WINED3D_INITIAL_CS_SIZE;
     if (!(cs->data = heap_alloc(cs->data_size)))
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 4fb6063741a..42d97b2eb85 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -1891,6 +1891,7 @@ void CDECL wined3d_device_set_state(struct wined3d_device *device, struct wined3
     TRACE("device %p, state %p.\n", device, state);
 
     device->cs->c.state = state;
+    wined3d_cs_emit_set_feature_level(device->cs, state->feature_level);
 
     for (i = 0; i < WINED3D_MAX_RENDER_TARGETS; ++i)
     {
@@ -4690,7 +4691,7 @@ static bool resources_format_compatible(const struct wined3d_resource *src_resou
         return true;
     if (src_resource->format->typeless_id && src_resource->format->typeless_id == dst_resource->format->typeless_id)
         return true;
-    if (src_resource->device->feature_level < WINED3D_FEATURE_LEVEL_10_1)
+    if (src_resource->device->cs->c.state->feature_level < WINED3D_FEATURE_LEVEL_10_1)
         return false;
     if ((src_resource->format_flags & WINED3DFMT_FLAG_BLOCKS)
             && (dst_resource->format_flags & WINED3DFMT_FLAG_CAST_TO_BLOCK))
@@ -5801,13 +5802,6 @@ struct wined3d * CDECL wined3d_device_get_wined3d(const struct wined3d_device *d
     return device->wined3d;
 }
 
-enum wined3d_feature_level CDECL wined3d_device_get_feature_level(const struct wined3d_device *device)
-{
-    TRACE("device %p.\n", device);
-
-    return device->feature_level;
-}
-
 void CDECL wined3d_device_set_gamma_ramp(const struct wined3d_device *device,
         UINT swapchain_idx, DWORD flags, const struct wined3d_gamma_ramp *ramp)
 {
@@ -6011,13 +6005,14 @@ HRESULT wined3d_device_init(struct wined3d_device *device, struct wined3d *wined
     struct wined3d_adapter *adapter = wined3d->adapters[adapter_idx];
     const struct wined3d_fragment_pipe_ops *fragment_pipeline;
     const struct wined3d_vertex_pipe_ops *vertex_pipeline;
+    enum wined3d_feature_level feature_level;
     unsigned int i;
     HRESULT hr;
 
-    if (!wined3d_select_feature_level(adapter, levels, level_count, &device->feature_level))
+    if (!wined3d_select_feature_level(adapter, levels, level_count, &feature_level))
         return E_FAIL;
 
-    TRACE("Device feature level %s.\n", wined3d_debug_feature_level(device->feature_level));
+    TRACE("Device feature level %s.\n", wined3d_debug_feature_level(feature_level));
 
     device->ref = 1;
     device->wined3d = wined3d;
@@ -6063,7 +6058,7 @@ HRESULT wined3d_device_init(struct wined3d_device *device, struct wined3d *wined
 
     device->max_frame_latency = 3;
 
-    if (!(device->cs = wined3d_cs_create(device)))
+    if (!(device->cs = wined3d_cs_create(device, feature_level)))
     {
         WARN("Failed to create command stream.\n");
         hr = E_FAIL;
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index e1142990139..ff44969d022 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -3349,7 +3349,7 @@ static HRESULT shader_set_function(struct wined3d_shader *shader, struct wined3d
         WARN("Wrong shader type %s.\n", debug_shader_type(reg_maps->shader_version.type));
         return WINED3DERR_INVALIDCALL;
     }
-    if (version->major > shader_max_version_from_feature_level(device->feature_level))
+    if (version->major > shader_max_version_from_feature_level(device->cs->c.state->feature_level))
     {
         WARN("Shader version %u not supported by this device.\n", version->major);
         return WINED3DERR_INVALIDCALL;
@@ -3661,7 +3661,7 @@ static HRESULT shader_init(struct wined3d_shader *shader, struct wined3d_device
         memcpy(shader->byte_code, desc->byte_code, desc->byte_code_size);
         shader->byte_code_size = desc->byte_code_size;
 
-        max_version = shader_max_version_from_feature_level(device->feature_level);
+        max_version = shader_max_version_from_feature_level(device->cs->c.state->feature_level);
         if (FAILED(hr = shader_extract_from_dxbc(shader, max_version, &format)))
             goto fail;
 
diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c
index 97020e1cd40..2cef5a6498a 100644
--- a/dlls/wined3d/stateblock.c
+++ b/dlls/wined3d/stateblock.c
@@ -1870,10 +1870,12 @@ static void state_init_default(struct wined3d_state *state, const struct wined3d
         state->streams[i].frequency = 1;
 }
 
-void state_init(struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info, DWORD flags)
+void state_init(struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info,
+        uint32_t flags, enum wined3d_feature_level feature_level)
 {
     unsigned int i;
 
+    state->feature_level = feature_level;
     state->flags = flags;
 
     for (i = 0; i < LIGHTMAP_SIZE; i++)
@@ -1893,12 +1895,19 @@ HRESULT CDECL wined3d_state_create(struct wined3d_device *device, struct wined3d
 
     if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
-    state_init(object, &device->adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT);
+    state_init(object, &device->adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT, device->cs->c.state->feature_level);
 
     *state = object;
     return S_OK;
 }
 
+enum wined3d_feature_level CDECL wined3d_state_get_feature_level(const struct wined3d_state *state)
+{
+    TRACE("state %p.\n", state);
+
+    return state->feature_level;
+}
+
 void CDECL wined3d_state_destroy(struct wined3d_state *state)
 {
     TRACE("state %p.\n", state);
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index afa945eeb92..c91f488a7b4 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -76,7 +76,6 @@
 @ cdecl wined3d_device_get_domain_shader(ptr)
 @ cdecl wined3d_device_get_ds_resource_view(ptr long)
 @ cdecl wined3d_device_get_ds_sampler(ptr long)
-@ cdecl wined3d_device_get_feature_level(ptr)
 @ cdecl wined3d_device_get_gamma_ramp(ptr long ptr)
 @ cdecl wined3d_device_get_geometry_shader(ptr)
 @ cdecl wined3d_device_get_gs_resource_view(ptr long)
@@ -248,6 +247,7 @@
 
 @ cdecl wined3d_state_create(ptr ptr)
 @ cdecl wined3d_state_destroy(ptr)
+@ cdecl wined3d_state_get_feature_level(ptr)
 
 @ cdecl wined3d_stateblock_apply(ptr ptr)
 @ cdecl wined3d_stateblock_capture(ptr ptr)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 06c7d74d199..e934d0f4b87 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3657,7 +3657,8 @@ struct wined3d_light_state
 
 struct wined3d_state
 {
-    DWORD flags;
+    enum wined3d_feature_level feature_level;
+    uint32_t flags;
     struct wined3d_fb_state fb;
 
     struct wined3d_vertex_declaration *vertex_declaration;
@@ -3711,15 +3712,17 @@ struct wined3d_state
 };
 
 void state_cleanup(struct wined3d_state *state) DECLSPEC_HIDDEN;
-void state_init(struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info, uint32_t flags) DECLSPEC_HIDDEN;
+void state_init(struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info,
+        uint32_t flags, enum wined3d_feature_level feature_level) DECLSPEC_HIDDEN;
 void state_unbind_resources(struct wined3d_state *state) DECLSPEC_HIDDEN;
 
 static inline void wined3d_state_reset(struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info)
 {
+    enum wined3d_feature_level feature_level = state->feature_level;
     uint32_t flags = state->flags;
 
     memset(state, 0, sizeof(*state));
-    state_init(state, d3d_info, flags);
+    state_init(state, d3d_info, flags, feature_level);
 }
 
 static inline bool wined3d_state_uses_depth_buffer(const struct wined3d_state *state)
@@ -3787,8 +3790,6 @@ struct wined3d_device
 
     WORD padding2 : 16;
 
-    enum wined3d_feature_level feature_level;
-
     /* Internal use fields  */
     struct wined3d_device_creation_parameters create_parms;
     HWND focus_window;
@@ -4715,7 +4716,8 @@ struct wined3d_cs
     LONG pending_presents;
 };
 
-struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) DECLSPEC_HIDDEN;
+struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device,
+        enum wined3d_feature_level feature_level) DECLSPEC_HIDDEN;
 void wined3d_cs_destroy(struct wined3d_cs *cs) DECLSPEC_HIDDEN;
 void wined3d_cs_destroy_object(struct wined3d_cs *cs,
         void (*callback)(void *object), void *object) DECLSPEC_HIDDEN;
@@ -4756,6 +4758,7 @@ void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture
         WORD flags, const struct wined3d_color_key *color_key) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_set_depth_stencil_view(struct wined3d_cs *cs,
         struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN;
+void wined3d_cs_emit_set_feature_level(struct wined3d_cs *cs, enum wined3d_feature_level level) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_set_index_buffer(struct wined3d_cs *cs, struct wined3d_buffer *buffer,
         enum wined3d_format_id format_id, unsigned int offset) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_set_light(struct wined3d_cs *cs, const struct wined3d_light_info *light) DECLSPEC_HIDDEN;
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 87ffe04f40f..77c6c223b7b 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2403,7 +2403,6 @@ struct wined3d_shader * __cdecl wined3d_device_get_domain_shader(const struct wi
 struct wined3d_shader_resource_view * __cdecl wined3d_device_get_ds_resource_view(const struct wined3d_device *device,
         unsigned int idx);
 struct wined3d_sampler * __cdecl wined3d_device_get_ds_sampler(const struct wined3d_device *device, unsigned int idx);
-enum wined3d_feature_level __cdecl wined3d_device_get_feature_level(const struct wined3d_device *device);
 void __cdecl wined3d_device_get_gamma_ramp(const struct wined3d_device *device,
         UINT swapchain_idx, struct wined3d_gamma_ramp *ramp);
 struct wined3d_shader * __cdecl wined3d_device_get_geometry_shader(const struct wined3d_device *device);
@@ -2748,6 +2747,7 @@ ULONG __cdecl wined3d_shader_resource_view_incref(struct wined3d_shader_resource
 
 HRESULT __cdecl wined3d_state_create(struct wined3d_device *device, struct wined3d_state **state);
 void __cdecl wined3d_state_destroy(struct wined3d_state *state);
+enum wined3d_feature_level __cdecl wined3d_state_get_feature_level(const struct wined3d_state *state);
 
 void __cdecl wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock,
         struct wined3d_stateblock *device_state);
-- 
2.20.1




More information about the wine-devel mailing list