[PATCH v3 0/3] MR10874: wined3d: Disallow locking of multisampled back buffers.
-- v3: wined3d: Disallow locking of multisampled back buffers. d3d9/tests: Test multisampled back buffer locking. d3d8/tests: Test multisampled back buffer locking. https://gitlab.winehq.org/wine/wine/-/merge_requests/10874
From: Conor McCarthy <cmccarthy@codeweavers.com> --- dlls/d3d8/tests/device.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/dlls/d3d8/tests/device.c b/dlls/d3d8/tests/device.c index 02383233cff..7e8fa3d5c26 100644 --- a/dlls/d3d8/tests/device.c +++ b/dlls/d3d8/tests/device.c @@ -9507,7 +9507,9 @@ static void test_clip_planes_limits(void) static void test_swapchain_multisample_reset(void) { D3DPRESENT_PARAMETERS present_parameters; + IDirect3DSurface8 *surface; IDirect3DDevice8 *device; + D3DLOCKED_RECT lr; IDirect3D8 *d3d; ULONG refcount; HWND window; @@ -9552,6 +9554,23 @@ static void test_swapchain_multisample_reset(void) hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0); ok(hr == D3D_OK, "Failed to clear, hr %#lx.\n", hr); + /* Lockable back buffer flag is allowed. */ + present_parameters.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; + hr = IDirect3DDevice8_Reset(device, &present_parameters); + ok(hr == D3D_OK, "Failed to reset device, hr %#lx.\n", hr); + + hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &surface); + ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#lx.\n", hr); + + /* But locking is not allowed. */ + hr = IDirect3DSurface8_LockRect(surface, &lr, NULL, 0); + todo_wine + ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + IDirect3DSurface8_UnlockRect(surface); + + IDirect3DSurface8_Release(surface); + refcount = IDirect3DDevice8_Release(device); ok(!refcount, "Device has %lu references left.\n", refcount); IDirect3D8_Release(d3d); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10874
From: Conor McCarthy <cmccarthy@codeweavers.com> --- dlls/d3d9/tests/device.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c index 3dc9bff4dc2..cb16b747f1f 100644 --- a/dlls/d3d9/tests/device.c +++ b/dlls/d3d9/tests/device.c @@ -13269,6 +13269,15 @@ static void test_swapchain_multisample_reset(void) hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0); ok(hr == D3D_OK, "Failed to clear, hr %#lx.\n", hr); + /* Lockable back buffer flag is not allowed. */ + d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; + hr = IDirect3DDevice9_Reset(device, &d3dpp); + todo_wine + ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#lx.\n", hr); + hr = IDirect3DDevice9_TestCooperativeLevel(device); + todo_wine + ok(hr == D3DERR_DEVICENOTRESET, "TestCooperativeLevel returned hr %#lx.\n", hr); + refcount = IDirect3DDevice9_Release(device); ok(!refcount, "Device has %lu references left.\n", refcount); IDirect3D9_Release(d3d); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10874
From: Conor McCarthy <cmccarthy@codeweavers.com> --- dlls/d3d8/directx.c | 2 +- dlls/d3d8/tests/device.c | 3 --- dlls/d3d9/tests/device.c | 2 -- dlls/wined3d/device.c | 7 +++++++ include/wine/wined3d.h | 1 + 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/dlls/d3d8/directx.c b/dlls/d3d8/directx.c index 9f4cecee49c..db27da831d7 100644 --- a/dlls/d3d8/directx.c +++ b/dlls/d3d8/directx.c @@ -476,7 +476,7 @@ BOOL d3d8_init(struct d3d8 *d3d8) DWORD flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_HANDLE_RESTORE | WINED3D_PIXEL_CENTER_INTEGER | WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR | WINED3D_NO_PRIMITIVE_RESTART | WINED3D_LEGACY_CUBEMAP_FILTERING - | WINED3D_NO_DRAW_INDIRECT; + | WINED3D_NO_DRAW_INDIRECT | WINED3D_MULTISAMPLED_LOCKABLE_BACKBUFFER_FLAG; unsigned int adapter_idx, output_idx, adapter_count, output_count = 0; struct wined3d_adapter *wined3d_adapter; diff --git a/dlls/d3d8/tests/device.c b/dlls/d3d8/tests/device.c index 7e8fa3d5c26..e57f31dfef1 100644 --- a/dlls/d3d8/tests/device.c +++ b/dlls/d3d8/tests/device.c @@ -9564,10 +9564,7 @@ static void test_swapchain_multisample_reset(void) /* But locking is not allowed. */ hr = IDirect3DSurface8_LockRect(surface, &lr, NULL, 0); - todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#lx.\n", hr); - if (SUCCEEDED(hr)) - IDirect3DSurface8_UnlockRect(surface); IDirect3DSurface8_Release(surface); diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c index cb16b747f1f..421b5e67b1e 100644 --- a/dlls/d3d9/tests/device.c +++ b/dlls/d3d9/tests/device.c @@ -13272,10 +13272,8 @@ static void test_swapchain_multisample_reset(void) /* Lockable back buffer flag is not allowed. */ d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; hr = IDirect3DDevice9_Reset(device, &d3dpp); - todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#lx.\n", hr); hr = IDirect3DDevice9_TestCooperativeLevel(device); - todo_wine ok(hr == D3DERR_DEVICENOTRESET, "TestCooperativeLevel returned hr %#lx.\n", hr); refcount = IDirect3DDevice9_Release(device); diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index e754cc633b7..1b466430463 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -5082,6 +5082,11 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, TRACE("refresh_rate %u\n", swapchain_desc->refresh_rate); TRACE("auto_restore_display_mode %#x\n", swapchain_desc->auto_restore_display_mode); + /* d3d8 allows the lockable flag even though the backbuffer is not lockable. */ + if (swapchain_desc->multisample_type && !(d3d_info->wined3d_creation_flags & WINED3D_MULTISAMPLED_LOCKABLE_BACKBUFFER_FLAG) + && (swapchain_desc->flags & WINED3D_SWAPCHAIN_LOCKABLE_BACKBUFFER)) + return WINED3DERR_INVALIDCALL; + if (swapchain_desc->backbuffer_bind_flags && swapchain_desc->backbuffer_bind_flags != WINED3D_BIND_RENDER_TARGET) FIXME("Got unexpected backbuffer bind flags %#x.\n", swapchain_desc->backbuffer_bind_flags); @@ -5169,6 +5174,8 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, if (swapchain_desc->flags != current_desc->flags) { current_desc->flags = swapchain_desc->flags; + if (swapchain_desc->multisample_type) + current_desc->flags &= ~WINED3D_SWAPCHAIN_LOCKABLE_BACKBUFFER; update_swapchain_flags(swapchain->front_buffer); for (i = 0; i < current_desc->backbuffer_count; ++i) diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index cfb098adfb0..35e983ca333 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -1353,6 +1353,7 @@ enum wined3d_memory_segment_group #define WINED3D_LEGACY_CUBEMAP_FILTERING 0x00001000 #define WINED3D_NORMALIZED_DEPTH_BIAS 0x00002000 #define WINED3D_NO_DRAW_INDIRECT 0x00004000 +#define WINED3D_MULTISAMPLED_LOCKABLE_BACKBUFFER_FLAG 0x00008000 /* Allow the swapchain flag, but not actual locking */ #define WINED3D_RESZ_CODE 0x7fa05000 -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10874
Rebased, and got rid of everything except the backbuffer locking changes. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10874#note_141025
On Mon May 18 23:30:02 2026 +0000, Elizabeth Figura wrote:
See 7c8dab24e6a2, and for that matter the other listed formats in the same commit. If 24-bit RGB is never supported for a render target, that makes things even easier; we can just remove that support bit. 24-bit RGB is supported for render targets. In `init_format_texture_info()`, multisampling support is initialised via `query_internal_format()` and it only checks GL support, there being no flag for it in the `caps` member of `struct wined3d_format_texture_info`. If I were to add one, should it be enabled for all formats except `WINED3DFMT_B8G8R8_UNORM` and maybe a few others we should test?
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10874#note_141026
```diff #define WINED3D_LEGACY_CUBEMAP_FILTERING 0x00001000 #define WINED3D_NORMALIZED_DEPTH_BIAS 0x00002000 #define WINED3D_NO_DRAW_INDIRECT 0x00004000 +#define WINED3D_MULTISAMPLED_LOCKABLE_BACKBUFFER_FLAG 0x00008000 /* Allow the swapchain flag, but not actual locking */ ```
Do we need this to be a global wined3d flag? (As opposed to something like WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH.) Also, this modifies wined3d_device_reset(), but wouldn't we need to account for this in places like wined3d_swapchain_init(), swapchain_create_texture() and update_swapchain_flags() as well? -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10874#note_141120
participants (3)
-
Conor McCarthy -
Conor McCarthy (@cmccarthy) -
Henri Verbeet (@hverbeet)