[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