[PATCH 4/6] wined3d: Pass feature levels to wined3d_device_create().
Józef Kucia
jkucia at codeweavers.com
Sun Sep 23 18:09:31 CDT 2018
Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
dlls/d3d8/device.c | 14 +++++++++++---
dlls/d3d9/device.c | 14 +++++++++++++-
dlls/ddraw/ddraw.c | 10 +++++++++-
dlls/dxgi/device.c | 7 ++++---
dlls/dxgi/dxgi_private.h | 1 +
dlls/wined3d/device.c | 31 +++++++++++++++++++++++++++++--
dlls/wined3d/directx.c | 20 +++++++++++---------
dlls/wined3d/utils.c | 22 ++++++++++++++++++++++
dlls/wined3d/wined3d.spec | 2 +-
dlls/wined3d/wined3d_private.h | 6 +++++-
include/wine/wined3d.h | 3 ++-
11 files changed, 108 insertions(+), 22 deletions(-)
diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c
index 364798f79b3a..12d025383514 100644
--- a/dlls/d3d8/device.c
+++ b/dlls/d3d8/device.c
@@ -3399,6 +3399,14 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine
struct wined3d_swapchain *wined3d_swapchain;
HRESULT hr;
+ static const enum wined3d_feature_level feature_levels[] =
+ {
+ WINED3D_FEATURE_LEVEL_8,
+ WINED3D_FEATURE_LEVEL_7,
+ WINED3D_FEATURE_LEVEL_6,
+ WINED3D_FEATURE_LEVEL_5,
+ };
+
device->IDirect3DDevice8_iface.lpVtbl = &d3d8_device_vtbl;
device->device_parent.ops = &d3d8_wined3d_device_parent_ops;
device->ref = 1;
@@ -3413,9 +3421,9 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine
if (!(flags & D3DCREATE_FPU_PRESERVE)) setup_fpu();
wined3d_mutex_lock();
- hr = wined3d_device_create(wined3d, adapter, device_type, focus_window, flags, 4,
- &device->device_parent, &device->wined3d_device);
- if (FAILED(hr))
+ if (FAILED(hr = wined3d_device_create(wined3d, adapter, device_type,
+ focus_window, flags, 4, feature_levels, ARRAY_SIZE(feature_levels),
+ &device->device_parent, &device->wined3d_device)))
{
WARN("Failed to create wined3d device, hr %#x.\n", hr);
wined3d_mutex_unlock();
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index a8dc7097c487..a31360886b6a 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -4230,6 +4230,17 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine
unsigned i, count = 1;
HRESULT hr;
+ static const enum wined3d_feature_level feature_levels[] =
+ {
+ WINED3D_FEATURE_LEVEL_9_SM3,
+ WINED3D_FEATURE_LEVEL_9_SM2,
+ WINED3D_FEATURE_LEVEL_9_1,
+ WINED3D_FEATURE_LEVEL_8,
+ WINED3D_FEATURE_LEVEL_7,
+ WINED3D_FEATURE_LEVEL_6,
+ WINED3D_FEATURE_LEVEL_5,
+ };
+
if (mode)
FIXME("Ignoring display mode.\n");
@@ -4240,7 +4251,8 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine
if (!(flags & D3DCREATE_FPU_PRESERVE)) setup_fpu();
wined3d_mutex_lock();
- if (FAILED(hr = wined3d_device_create(wined3d, adapter, device_type, focus_window, flags, 4,
+ if (FAILED(hr = wined3d_device_create(wined3d, adapter, device_type,
+ focus_window, flags, 4, feature_levels, ARRAY_SIZE(feature_levels),
&device->device_parent, &device->wined3d_device)))
{
WARN("Failed to create wined3d device, hr %#x.\n", hr);
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index c83d0ca15689..56a74cb3285f 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -4986,6 +4986,13 @@ HRESULT ddraw_init(struct ddraw *ddraw, DWORD flags, enum wined3d_device_type de
struct wined3d_caps caps;
HRESULT hr;
+ static const enum wined3d_feature_level feature_levels[] =
+ {
+ WINED3D_FEATURE_LEVEL_7,
+ WINED3D_FEATURE_LEVEL_6,
+ WINED3D_FEATURE_LEVEL_5,
+ };
+
ddraw->IDirectDraw7_iface.lpVtbl = &ddraw7_vtbl;
ddraw->IDirectDraw_iface.lpVtbl = &ddraw1_vtbl;
ddraw->IDirectDraw2_iface.lpVtbl = &ddraw2_vtbl;
@@ -5023,7 +5030,8 @@ HRESULT ddraw_init(struct ddraw *ddraw, DWORD flags, enum wined3d_device_type de
}
if (FAILED(hr = wined3d_device_create(ddraw->wined3d, WINED3DADAPTER_DEFAULT, device_type,
- NULL, 0, DDRAW_STRIDE_ALIGNMENT, &ddraw->device_parent, &ddraw->wined3d_device)))
+ NULL, 0, DDRAW_STRIDE_ALIGNMENT, feature_levels, ARRAY_SIZE(feature_levels),
+ &ddraw->device_parent, &ddraw->wined3d_device)))
{
WARN("Failed to create a wined3d device, hr %#x.\n", hr);
wined3d_decref(ddraw->wined3d);
diff --git a/dlls/dxgi/device.c b/dlls/dxgi/device.c
index 67cadd5a3f89..deb07ca0d821 100644
--- a/dlls/dxgi/device.c
+++ b/dlls/dxgi/device.c
@@ -464,9 +464,10 @@ HRESULT dxgi_device_init(struct dxgi_device *device, struct dxgi_device_layer *l
return E_FAIL;
}
- hr = wined3d_device_create(dxgi_factory->wined3d, dxgi_adapter->ordinal, WINED3D_DEVICE_TYPE_HAL,
- NULL, 0, 4, wined3d_device_parent, &device->wined3d_device);
- if (FAILED(hr))
+ if (FAILED(hr = wined3d_device_create(dxgi_factory->wined3d,
+ dxgi_adapter->ordinal, WINED3D_DEVICE_TYPE_HAL, NULL, 0, 4,
+ (const enum wined3d_feature_level *)feature_levels, level_count,
+ wined3d_device_parent, &device->wined3d_device)))
{
WARN("Failed to create a wined3d device, returning %#x.\n", hr);
IUnknown_Release(device->child_layer);
diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h
index f74514f0d326..3a59196e1abd 100644
--- a/dlls/dxgi/dxgi_private.h
+++ b/dlls/dxgi/dxgi_private.h
@@ -97,6 +97,7 @@ DXGI_USAGE dxgi_usage_from_wined3d_usage(DWORD wined3d_usage) DECLSPEC_HIDDEN;
DWORD wined3d_usage_from_dxgi_usage(DXGI_USAGE usage) DECLSPEC_HIDDEN;
unsigned int dxgi_swapchain_flags_from_wined3d(unsigned int wined3d_flags) DECLSPEC_HIDDEN;
unsigned int wined3d_swapchain_flags_from_dxgi(unsigned int flags) DECLSPEC_HIDDEN;
+
HRESULT dxgi_get_private_data(struct wined3d_private_store *store,
REFGUID guid, UINT *data_size, void *data) DECLSPEC_HIDDEN;
HRESULT dxgi_set_private_data(struct wined3d_private_store *store,
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 3fc3ae557dc6..38c37d4c536d 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -5158,16 +5158,43 @@ static int wined3d_sampler_compare(const void *key, const struct wine_rb_entry *
return memcmp(&sampler->desc, key, sizeof(sampler->desc));
}
+static BOOL wined3d_select_feature_level(const struct wined3d_adapter *adapter,
+ const enum wined3d_feature_level *levels, unsigned int level_count,
+ enum wined3d_feature_level *selected_level)
+{
+ const struct wined3d_d3d_info *d3d_info = &adapter->d3d_info;
+ unsigned int i;
+
+ for (i = 0; i < level_count; ++i)
+ {
+ if (levels[i] && d3d_info->feature_level >= levels[i])
+ {
+ *selected_level = levels[i];
+ return TRUE;
+ }
+ }
+
+ FIXME_(winediag)("None of the requested D3D feature levels is supported on this GPU "
+ "with the current shader backend.\n");
+ return FALSE;
+}
+
HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d,
UINT adapter_idx, enum wined3d_device_type device_type, HWND focus_window, DWORD flags,
- BYTE surface_alignment, struct wined3d_device_parent *device_parent)
+ BYTE surface_alignment, const enum wined3d_feature_level *levels, unsigned int level_count,
+ struct wined3d_device_parent *device_parent)
{
struct wined3d_adapter *adapter = &wined3d->adapters[adapter_idx];
- const struct fragment_pipeline *fragment_pipeline;
const struct wined3d_vertex_pipe_ops *vertex_pipeline;
+ const struct fragment_pipeline *fragment_pipeline;
unsigned int i;
HRESULT hr;
+ if (!wined3d_select_feature_level(adapter, levels, level_count, &device->feature_level))
+ return E_FAIL;
+
+ TRACE("Device feature level %s.\n", wined3d_debug_feature_level(device->feature_level));
+
device->ref = 1;
device->wined3d = wined3d;
wined3d_incref(device->wined3d);
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 4e8afed0a938..b893e0541946 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -2448,16 +2448,18 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte
return WINED3D_OK;
}
-HRESULT CDECL wined3d_device_create(struct wined3d *wined3d, UINT adapter_idx, enum wined3d_device_type device_type,
- HWND focus_window, DWORD flags, BYTE surface_alignment, struct wined3d_device_parent *device_parent,
- struct wined3d_device **device)
+HRESULT CDECL wined3d_device_create(struct wined3d *wined3d, unsigned int adapter_idx,
+ enum wined3d_device_type device_type, HWND focus_window, DWORD flags, BYTE surface_alignment,
+ const enum wined3d_feature_level *feature_levels, unsigned int feature_level_count,
+ struct wined3d_device_parent *device_parent, struct wined3d_device **device)
{
struct wined3d_device *object;
HRESULT hr;
- TRACE("wined3d %p, adapter_idx %u, device_type %#x, focus_window %p, "
- "flags %#x, surface_alignment %u, device_parent %p, device %p.\n",
- wined3d, adapter_idx, device_type, focus_window, flags, surface_alignment, device_parent, device);
+ TRACE("wined3d %p, adapter_idx %u, device_type %#x, focus_window %p, flags %#x, "
+ "surface_alignment %u, feature_levels %p, feature_level_count %u, device_parent %p, device %p.\n",
+ wined3d, adapter_idx, device_type, focus_window, flags, surface_alignment,
+ feature_levels, feature_level_count, device_parent, device);
if (adapter_idx >= wined3d->adapter_count)
return WINED3DERR_INVALIDCALL;
@@ -2465,9 +2467,9 @@ HRESULT CDECL wined3d_device_create(struct wined3d *wined3d, UINT adapter_idx, e
if (!(object = heap_alloc_zero(sizeof(*object))))
return E_OUTOFMEMORY;
- hr = device_init(object, wined3d, adapter_idx, device_type,
- focus_window, flags, surface_alignment, device_parent);
- if (FAILED(hr))
+ if (FAILED(hr = device_init(object, wined3d, adapter_idx,
+ device_type, focus_window, flags, surface_alignment,
+ feature_levels, feature_level_count, device_parent)))
{
WARN("Failed to initialize device, hr %#x.\n", hr);
heap_free(object);
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index bf32953032ea..23f5fd70c675 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -6243,6 +6243,28 @@ const char *wined3d_debug_location(DWORD location)
return wine_dbg_sprintf("%s%s%s", prefix, buffer.str, suffix);
}
+const char *wined3d_debug_feature_level(enum wined3d_feature_level level)
+{
+ switch (level)
+ {
+#define LEVEL_TO_STR(level) case level: return #level
+ LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_5);
+ LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_6);
+ LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_7);
+ LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_8);
+ LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_9_1);
+ LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_9_SM2);
+ LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_9_SM3);
+ LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_10);
+ LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_10_1);
+ LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_11);
+ LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_11_1);
+#undef LEVEL_TO_STR
+ default:
+ return wine_dbg_sprintf("%#x", level);
+ }
+}
+
/* Print a floating point value with the %.8e format specifier, always using
* '.' as decimal separator. */
void wined3d_ftoa(float value, char *s)
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index 93cecf0d3bb4..a401e04dcf3b 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -42,7 +42,7 @@
@ cdecl wined3d_device_copy_resource(ptr ptr ptr)
@ cdecl wined3d_device_copy_sub_resource_region(ptr ptr long long long long ptr long ptr long)
@ cdecl wined3d_device_copy_uav_counter(ptr ptr long ptr)
-@ cdecl wined3d_device_create(ptr long long ptr long long ptr ptr)
+@ cdecl wined3d_device_create(ptr long long ptr long long ptr long ptr ptr)
@ cdecl wined3d_device_decref(ptr)
@ cdecl wined3d_device_dispatch_compute(ptr long long long)
@ cdecl wined3d_device_dispatch_compute_indirect(ptr ptr long)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 637c7218c184..423dda83e731 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2981,6 +2981,8 @@ struct wined3d_device
WORD padding2 : 16;
+ enum wined3d_feature_level feature_level;
+
struct wined3d_state state;
struct wined3d_state *update_state;
struct wined3d_stateblock *recording;
@@ -3036,7 +3038,8 @@ BOOL device_context_add(struct wined3d_device *device, struct wined3d_context *c
void device_context_remove(struct wined3d_device *device, struct wined3d_context *context) DECLSPEC_HIDDEN;
HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d,
UINT adapter_idx, enum wined3d_device_type device_type, HWND focus_window, DWORD flags,
- BYTE surface_alignment, struct wined3d_device_parent *device_parent) DECLSPEC_HIDDEN;
+ BYTE surface_alignment, const enum wined3d_feature_level *levels, unsigned int level_count,
+ struct wined3d_device_parent *device_parent) DECLSPEC_HIDDEN;
LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL unicode,
UINT message, WPARAM wparam, LPARAM lparam, WNDPROC proc) DECLSPEC_HIDDEN;
void device_resource_add(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN;
@@ -3913,6 +3916,7 @@ const char *debug_ivec4(const struct wined3d_ivec4 *v) DECLSPEC_HIDDEN;
const char *debug_uvec4(const struct wined3d_uvec4 *v) DECLSPEC_HIDDEN;
const char *debug_shader_type(enum wined3d_shader_type shader_type) DECLSPEC_HIDDEN;
const char *debug_vec4(const struct wined3d_vec4 *v) DECLSPEC_HIDDEN;
+const char *wined3d_debug_feature_level(enum wined3d_feature_level level) DECLSPEC_HIDDEN;
void dump_color_fixup_desc(struct color_fixup_desc fixup) DECLSPEC_HIDDEN;
BOOL is_invalid_op(const struct wined3d_state *state, int stage,
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 17b0fd4c456d..6b81b3ab1df1 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2248,8 +2248,9 @@ HRESULT __cdecl wined3d_device_copy_sub_resource_region(struct wined3d_device *d
unsigned int src_sub_resource_idx, const struct wined3d_box *src_box, unsigned int flags);
void __cdecl wined3d_device_copy_uav_counter(struct wined3d_device *device,
struct wined3d_buffer *dst_buffer, unsigned int offset, struct wined3d_unordered_access_view *uav);
-HRESULT __cdecl wined3d_device_create(struct wined3d *wined3d, UINT adapter_idx,
+HRESULT __cdecl wined3d_device_create(struct wined3d *wined3d, unsigned int adapter_idx,
enum wined3d_device_type device_type, HWND focus_window, DWORD behaviour_flags, BYTE surface_alignment,
+ const enum wined3d_feature_level *feature_levels, unsigned int feature_level_count,
struct wined3d_device_parent *device_parent, struct wined3d_device **device);
ULONG __cdecl wined3d_device_decref(struct wined3d_device *device);
void __cdecl wined3d_device_dispatch_compute(struct wined3d_device *device,
--
2.16.4
More information about the wine-devel
mailing list