v2: Specify the maximum allowed feature level when creating the device. v3: Rebased.
-- v3: wined3d: Use the chunk allocator for GL element array buffers. wined3d: Specify the maximum allowed feature level when creating the device.
From: Anton Baskanov baskanov@gmail.com
--- dlls/d3d8/device.c | 2 +- dlls/d3d9/device.c | 2 +- dlls/ddraw/ddraw.c | 2 +- dlls/dxgi/device.c | 3 ++- dlls/wined3d/adapter_gl.c | 5 +++-- dlls/wined3d/adapter_vk.c | 5 +++-- dlls/wined3d/device.c | 4 +++- dlls/wined3d/directx.c | 10 ++++++---- dlls/wined3d/stateblock.c | 9 ++++----- dlls/wined3d/wined3d.spec | 2 +- dlls/wined3d/wined3d_private.h | 7 +++++-- include/wine/wined3d.h | 3 ++- 12 files changed, 32 insertions(+), 22 deletions(-)
diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c index fb7e25a6bc1..b852149f171 100644 --- a/dlls/d3d8/device.c +++ b/dlls/d3d8/device.c @@ -3664,7 +3664,7 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine wined3d_adapter = wined3d_output_get_adapter(wined3d_output); if (FAILED(hr = wined3d_device_create(wined3d, wined3d_adapter, wined3d_device_type_from_d3d(device_type), focus_window, flags, 4, feature_levels, ARRAY_SIZE(feature_levels), - &device->device_parent, &device->wined3d_device))) + WINED3D_FEATURE_LEVEL_8, &device->device_parent, &device->wined3d_device))) { WARN("Failed to create wined3d device, hr %#lx.\n", hr); wined3d_mutex_unlock(); diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index 55641670665..6eb8464d2df 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -4613,7 +4613,7 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine wined3d_adapter = wined3d_output_get_adapter(parent->wined3d_outputs[output_idx]); if (FAILED(hr = wined3d_device_create(wined3d, wined3d_adapter, wined3d_device_type_from_d3d(device_type), focus_window, flags, 4, feature_levels, ARRAY_SIZE(feature_levels), - &device->device_parent, &device->wined3d_device))) + WINED3D_FEATURE_LEVEL_9_3, &device->device_parent, &device->wined3d_device))) { WARN("Failed to create wined3d device, hr %#lx.\n", hr); wined3d_mutex_unlock(); diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index fd4c5bd4862..bc5b888c3f2 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -5180,7 +5180,7 @@ HRESULT ddraw_init(struct ddraw *ddraw, DWORD flags, enum wined3d_device_type de
if (FAILED(hr = wined3d_device_create(ddraw->wined3d, ddraw->wined3d_adapter, device_type, NULL, 0, DDRAW_STRIDE_ALIGNMENT, feature_levels, ARRAY_SIZE(feature_levels), - &ddraw->device_parent, &ddraw->wined3d_device))) + WINED3D_FEATURE_LEVEL_7, &ddraw->device_parent, &ddraw->wined3d_device))) { WARN("Failed to create a wined3d device, hr %#lx.\n", hr); wined3d_decref(ddraw->wined3d); diff --git a/dlls/dxgi/device.c b/dlls/dxgi/device.c index efa04e0f495..c46a85fe05f 100644 --- a/dlls/dxgi/device.c +++ b/dlls/dxgi/device.c @@ -538,7 +538,8 @@ HRESULT dxgi_device_init(struct dxgi_device *device, struct dxgi_device_layer *l if (FAILED(hr = wined3d_device_create(dxgi_factory->wined3d, dxgi_adapter->wined3d_adapter, WINED3D_DEVICE_TYPE_HAL, NULL, 0, 4, (const enum wined3d_feature_level *)feature_levels, level_count, - wined3d_device_parent, &device->wined3d_device))) + WINED3D_FEATURE_LEVEL_11_1, wined3d_device_parent, + &device->wined3d_device))) { WARN("Failed to create a wined3d device, returning %#lx.\n", hr); IUnknown_Release(device->child_layer); diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c index 60a168b5cef..8fb60651d8c 100644 --- a/dlls/wined3d/adapter_gl.c +++ b/dlls/wined3d/adapter_gl.c @@ -4250,7 +4250,8 @@ static void adapter_gl_destroy(struct wined3d_adapter *adapter) static HRESULT adapter_gl_create_device(struct wined3d *wined3d, const struct wined3d_adapter *adapter, enum wined3d_device_type device_type, HWND focus_window, unsigned int flags, BYTE surface_alignment, const enum wined3d_feature_level *levels, unsigned int level_count, - struct wined3d_device_parent *device_parent, struct wined3d_device **device) + enum wined3d_feature_level max_level, struct wined3d_device_parent *device_parent, + struct wined3d_device **device) { struct wined3d_device_gl *device_gl; HRESULT hr; @@ -4261,7 +4262,7 @@ static HRESULT adapter_gl_create_device(struct wined3d *wined3d, const struct wi device_gl->current_fence_id = 1;
if (FAILED(hr = wined3d_device_init(&device_gl->d, wined3d, adapter->ordinal, device_type, focus_window, - flags, surface_alignment, levels, level_count, adapter->gl_info.supported, device_parent))) + flags, surface_alignment, levels, level_count, max_level, adapter->gl_info.supported, device_parent))) { WARN("Failed to initialize device, hr %#x.\n", hr); heap_free(device_gl); diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c index 90ffec4b1f7..7f5ba0056de 100644 --- a/dlls/wined3d/adapter_vk.c +++ b/dlls/wined3d/adapter_vk.c @@ -379,7 +379,8 @@ static const struct wined3d_allocator_ops wined3d_allocator_vk_ops = static HRESULT adapter_vk_create_device(struct wined3d *wined3d, const struct wined3d_adapter *adapter, enum wined3d_device_type device_type, HWND focus_window, unsigned int flags, BYTE surface_alignment, const enum wined3d_feature_level *levels, unsigned int level_count, - struct wined3d_device_parent *device_parent, struct wined3d_device **device) + enum wined3d_feature_level max_level, struct wined3d_device_parent *device_parent, + struct wined3d_device **device) { const struct wined3d_adapter_vk *adapter_vk = wined3d_adapter_vk_const(adapter); VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *vertex_divisor_features; @@ -493,7 +494,7 @@ static HRESULT adapter_vk_create_device(struct wined3d *wined3d, const struct wi }
if (FAILED(hr = wined3d_device_init(&device_vk->d, wined3d, adapter->ordinal, device_type, focus_window, - flags, surface_alignment, levels, level_count, vk_info->supported, device_parent))) + flags, surface_alignment, levels, level_count, max_level, vk_info->supported, device_parent))) { WARN("Failed to initialize device, hr %#x.\n", hr); wined3d_allocator_cleanup(&device_vk->allocator); diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 913376ee3ee..9243291dfdd 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -6063,7 +6063,8 @@ static int wined3d_depth_stencil_state_compare(const void *key, const struct win HRESULT wined3d_device_init(struct wined3d_device *device, struct wined3d *wined3d, unsigned int adapter_idx, enum wined3d_device_type device_type, HWND focus_window, unsigned int flags, BYTE surface_alignment, const enum wined3d_feature_level *levels, unsigned int level_count, - const BOOL *supported_extensions, struct wined3d_device_parent *device_parent) + enum wined3d_feature_level max_level, const BOOL *supported_extensions, + struct wined3d_device_parent *device_parent) { struct wined3d_adapter *adapter = wined3d->adapters[adapter_idx]; const struct wined3d_fragment_pipe_ops *fragment_pipeline; @@ -6079,6 +6080,7 @@ HRESULT wined3d_device_init(struct wined3d_device *device, struct wined3d *wined list_init(&device->resources); list_init(&device->shaders); device->surface_alignment = surface_alignment; + device->max_feature_level = min(max_level, adapter->d3d_info.feature_level);
/* Save the creation parameters. */ device->create_parms.adapter_idx = adapter_idx; diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 8590bd4800a..09ab74e1bb7 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -2709,7 +2709,8 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d_adapter *adapter, HRESULT CDECL wined3d_device_create(struct wined3d *wined3d, struct wined3d_adapter *adapter, 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) + enum wined3d_feature_level max_feature_level, struct wined3d_device_parent *device_parent, + struct wined3d_device **device) { struct wined3d_device *object; HRESULT hr; @@ -2721,7 +2722,7 @@ HRESULT CDECL wined3d_device_create(struct wined3d *wined3d, struct wined3d_adap
if (FAILED(hr = adapter->adapter_ops->adapter_create_device(wined3d, adapter, device_type, focus_window, flags, surface_alignment, - feature_levels, feature_level_count, device_parent, &object))) + feature_levels, feature_level_count, max_feature_level, device_parent, &object))) return hr;
TRACE("Created device %p.\n", object); @@ -2899,7 +2900,8 @@ static void adapter_no3d_destroy(struct wined3d_adapter *adapter) static HRESULT adapter_no3d_create_device(struct wined3d *wined3d, const struct wined3d_adapter *adapter, enum wined3d_device_type device_type, HWND focus_window, unsigned int flags, BYTE surface_alignment, const enum wined3d_feature_level *levels, unsigned int level_count, - struct wined3d_device_parent *device_parent, struct wined3d_device **device) + enum wined3d_feature_level max_level, struct wined3d_device_parent *device_parent, + struct wined3d_device **device) { struct wined3d_device_no3d *device_no3d; HRESULT hr; @@ -2908,7 +2910,7 @@ static HRESULT adapter_no3d_create_device(struct wined3d *wined3d, const struct return E_OUTOFMEMORY;
if (FAILED(hr = wined3d_device_init(&device_no3d->d, wined3d, adapter->ordinal, device_type, focus_window, - flags, surface_alignment, levels, level_count, adapter->gl_info.supported, device_parent))) + flags, surface_alignment, levels, level_count, max_level, adapter->gl_info.supported, device_parent))) { WARN("Failed to initialize device, hr %#x.\n", hr); heap_free(device_no3d); diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 1b82d387de8..72941c3da92 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -1892,16 +1892,15 @@ void state_init(struct wined3d_state *state, const struct wined3d_d3d_info *d3d_ state_init_default(state, d3d_info); }
-static bool wined3d_select_feature_level(const struct wined3d_adapter *adapter, - const enum wined3d_feature_level *levels, unsigned int level_count, +static bool wined3d_select_feature_level(const enum wined3d_feature_level *levels, + unsigned int level_count, enum wined3d_feature_level max_feature_level, 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]) + if (levels[i] && max_feature_level >= levels[i]) { *selected_level = levels[i]; return true; @@ -1921,7 +1920,7 @@ HRESULT CDECL wined3d_state_create(struct wined3d_device *device,
TRACE("device %p, levels %p, level_count %u, state %p.\n", device, levels, level_count, state);
- if (!wined3d_select_feature_level(device->adapter, levels, level_count, &feature_level)) + if (!wined3d_select_feature_level(levels, level_count, device->max_feature_level, &feature_level)) return E_FAIL;
TRACE("Selected feature level %s.\n", wined3d_debug_feature_level(feature_level)); diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index e6126faf838..934f4bac935 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -52,7 +52,7 @@ @ cdecl wined3d_device_apply_stateblock(ptr ptr) @ cdecl wined3d_device_begin_scene(ptr) @ cdecl wined3d_device_clear(ptr long ptr long ptr float long) -@ cdecl wined3d_device_create(ptr ptr long ptr long long ptr long ptr ptr) +@ cdecl wined3d_device_create(ptr ptr long ptr long long ptr long long ptr ptr) @ cdecl wined3d_device_decref(ptr) @ cdecl wined3d_device_end_scene(ptr) @ cdecl wined3d_device_evict_managed_resources(ptr) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index b7d3b579ed2..3f891640c58 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3475,7 +3475,8 @@ struct wined3d_adapter_ops HRESULT (*adapter_create_device)(struct wined3d *wined3d, const struct wined3d_adapter *adapter, enum wined3d_device_type device_type, HWND focus_window, unsigned int flags, BYTE surface_alignment, const enum wined3d_feature_level *levels, unsigned int level_count, - struct wined3d_device_parent *device_parent, struct wined3d_device **device); + enum wined3d_feature_level max_level, struct wined3d_device_parent *device_parent, + struct wined3d_device **device); void (*adapter_destroy_device)(struct wined3d_device *device); struct wined3d_context *(*adapter_acquire_context)(struct wined3d_device *device, struct wined3d_texture *texture, unsigned int sub_resource_idx); @@ -4000,6 +4001,7 @@ struct wined3d_device
/* Internal use fields */ struct wined3d_device_creation_parameters create_parms; + enum wined3d_feature_level max_feature_level; HWND focus_window;
struct wined3d_rendertarget_view *back_buffer_view; @@ -4050,7 +4052,8 @@ void wined3d_device_destroy_default_samplers(struct wined3d_device *device) DECL HRESULT wined3d_device_init(struct wined3d_device *device, struct wined3d *wined3d, unsigned int adapter_idx, enum wined3d_device_type device_type, HWND focus_window, unsigned int flags, BYTE surface_alignment, const enum wined3d_feature_level *levels, unsigned int level_count, - const BOOL *supported_extensions, struct wined3d_device_parent *device_parent) DECLSPEC_HIDDEN; + enum wined3d_feature_level max_level, const BOOL *supported_extensions, + 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; diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index d1147e03f66..fc7f6ba7923 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2361,7 +2361,8 @@ HRESULT __cdecl wined3d_device_clear(struct wined3d_device *device, DWORD rect_c HRESULT __cdecl wined3d_device_create(struct wined3d *wined3d, struct wined3d_adapter *adapter, 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); + enum wined3d_feature_level max_feature_level, struct wined3d_device_parent *device_parent, + struct wined3d_device **device); ULONG __cdecl wined3d_device_decref(struct wined3d_device *device); HRESULT __cdecl wined3d_device_end_scene(struct wined3d_device *device); void __cdecl wined3d_device_evict_managed_resources(struct wined3d_device *device);
From: Anton Baskanov baskanov@gmail.com
--- dlls/wined3d/device.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 9243291dfdd..19ef22a6dd8 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1084,7 +1084,8 @@ static struct wined3d_allocator_block *wined3d_device_gl_allocate_memory(struct return block; }
-static bool use_buffer_chunk_suballocation(const struct wined3d_gl_info *gl_info, GLenum binding) +static bool use_buffer_chunk_suballocation(struct wined3d_device_gl *device_gl, + const struct wined3d_gl_info *gl_info, GLenum binding) { switch (binding) { @@ -1095,6 +1096,11 @@ static bool use_buffer_chunk_suballocation(const struct wined3d_gl_info *gl_info case GL_UNIFORM_BUFFER: return true;
+ case GL_ELEMENT_ARRAY_BUFFER: + /* There is no way to specify an element array buffer offset for + * indirect draws in OpenGL. */ + return device_gl->d.max_feature_level < WINED3D_FEATURE_LEVEL_11; + case GL_TEXTURE_BUFFER: return gl_info->supported[ARB_TEXTURE_BUFFER_RANGE];
@@ -1117,7 +1123,7 @@ bool wined3d_device_gl_create_bo(struct wined3d_device_gl *device_gl, struct win
if (gl_info->supported[ARB_BUFFER_STORAGE]) { - if (use_buffer_chunk_suballocation(gl_info, binding)) + if (use_buffer_chunk_suballocation(device_gl, gl_info, binding)) { if ((memory = wined3d_device_gl_allocate_memory(device_gl, context_gl, memory_type_idx, size, &id))) buffer_offset = memory->offset;
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=126039
Your paranoid android.
=== debian11 (32 bit zh:CN report) ===
d3d8: device.c:2232: Test failed: Failed to create a D3D object.
I think we'd rather not bring back "dxVersion". We could use the "flags" parameter to wined3d_init() though. E.g. similar to WINED3D_NO_PRIMITIVE_RESTART, we could perhaps introduce WINED3D_NO_DRAW_INDIRECT, or something along those lines.