This fixes the visual glitches and crashes of Worms Blast that were reported here: https://bugs.winehq.org/show_bug.cgi?id=54898 (and here: https://github.com/ValveSoftware/Proton/issues/706). There is, however, still an issue with the background music, which is not playing.
-- v5: wined3d: Improve d3d8 compatibility of texture filters. d3d8/tests: Test IDirect3DDevice8::ValidateDevice() with various min, mag and mip filters.
From: Sebastian Mayr me@sam.st
This test is an adaptation of the corresponding d3d9 test.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=54898 --- dlls/d3d8/tests/device.c | 67 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+)
diff --git a/dlls/d3d8/tests/device.c b/dlls/d3d8/tests/device.c index 6a585458bae..ec6f2ce51b3 100644 --- a/dlls/d3d8/tests/device.c +++ b/dlls/d3d8/tests/device.c @@ -10910,6 +10910,72 @@ static void test_window_position(void) IDirect3D8_Release(d3d); }
+static void test_filter(void) +{ + unsigned int mag, min, mip; + IDirect3DTexture8 *texture; + IDirect3DDevice8 *device; + BOOL has_texture; + IDirect3D8 *d3d; + ULONG refcount; + DWORD passes; + HWND window; + HRESULT hr; + + d3d = Direct3DCreate8(D3D_SDK_VERSION); + ok(!!d3d, "Failed to create a D3D object.\n"); + + window = create_window(); + if (!(device = create_device(d3d, window, NULL))) + { + skip("Failed to create a D3D device, skipping tests.\n"); + IDirect3D8_Release(d3d); + DestroyWindow(window); + return; + } + + hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture); + ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr); + + for (has_texture = FALSE; has_texture <= TRUE; ++has_texture) + for (mag = 0; mag <= D3DTEXF_GAUSSIANCUBIC + 1; ++mag) + for (min = 0; min <= D3DTEXF_GAUSSIANCUBIC + 1; ++min) + for (mip = 0; mip <= D3DTEXF_GAUSSIANCUBIC + 1; ++mip) + { + if (has_texture) + { + hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture); + ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr); + } + else + { + hr = IDirect3DDevice8_SetTexture(device, 0, NULL); + ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr); + } + + hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, mag); + ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr); + hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, min); + ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr); + hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, mip); + ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr); + + passes = 0xdeadbeef; + hr = IDirect3DDevice8_ValidateDevice(device, &passes); + ok(SUCCEEDED(hr), "Failed to validate device, hr %#lx.\n", hr); + ok(passes && passes != 0xdeadbeef, "Got unexpected passes %#lx.\n", passes); + } + + hr = IDirect3DDevice8_SetTexture(device, 0, NULL); + ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr); + IDirect3DTexture8_Release(texture); + + refcount = IDirect3DDevice8_Release(device); + ok(!refcount, "Device has %lu references left.\n", refcount); + IDirect3D8_Release(d3d); + DestroyWindow(window); +} + START_TEST(device) { HMODULE d3d8_handle = GetModuleHandleA("d3d8.dll"); @@ -11031,6 +11097,7 @@ START_TEST(device) test_creation_parameters(); test_cursor_clipping(); test_window_position(); + test_filter();
UnregisterClassA("d3d8_test_wc", GetModuleHandleA(NULL)); }
From: Sebastian Mayr me@sam.st
In d3d8, setting texture filters to invalid values does not yield an error when calling IDirect3DDevice8::ValidateDevice. Some applications, such as Worms Blast, rely on this behaviour.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=54898 --- dlls/d3d8/device.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c index 3727ad3e4eb..5cf22b08f79 100644 --- a/dlls/d3d8/device.c +++ b/dlls/d3d8/device.c @@ -2409,6 +2409,15 @@ static HRESULT WINAPI d3d8_device_ValidateDevice(IDirect3DDevice8 *iface, DWORD hr = wined3d_device_validate_device(device->wined3d_device, pass_count); wined3d_mutex_unlock();
+ /* In d3d8, texture filters are not validated, so errors concerning + * unsupported ones are ignored here. */ + if (hr == WINED3DERR_UNSUPPORTEDTEXTUREFILTER) + { + WARN("Ignoring invalid texture filter settings.\n"); + *pass_count = 1; + return D3D_OK; + } + return hr; }
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=132806
Your paranoid android.
=== w1064_tsign (32 bit report) ===
d3d8: device.c:1984: Test failed: GetDepthStencilSurface failed, hr 0x88760866. device.c:1985: Test failed: Depth / stencil buffer should not be NULL.
=== debian11 (32 bit report) ===
winhttp: notification.c:118: Test failed: 994: expected status 0x20000 got 0x4000 notification.c:118: Test failed: 994: expected status 0x20000 got 0x1 notification.c:123: Test failed: 994: expected callback 0x1 to be called from the same thread notification.c:118: Test failed: 994: expected status 0x20000 got 0x2 notification.c:123: Test failed: 994: expected callback 0x2 to be called from the same thread notification.c:118: Test failed: 994: expected status 0x20000 got 0x4 notification.c:123: Test failed: 994: expected callback 0x4 to be called from the same thread notification.c:118: Test failed: 994: expected status 0x20000 got 0x8 notification.c:123: Test failed: 994: expected callback 0x8 to be called from the same thread notification.c:118: Test failed: 994: expected status 0x20000 got 0x10 notification.c:123: Test failed: 994: expected callback 0x10 to be called from the same thread notification.c:118: Test failed: 994: expected status 0x20000 got 0x20 notification.c:123: Test failed: 994: expected callback 0x20 to be called from the same thread notification.c:118: Test failed: 994: expected status 0x20000 got 0x40 notification.c:123: Test failed: 994: expected callback 0x40 to be called from the same thread notification.c:118: Test failed: 994: expected status 0x20000 got 0x80 notification.c:123: Test failed: 994: expected callback 0x80 to be called from the same thread notification.c:123: Test failed: 994: expected callback 0x20000 to be called from the same thread notification.c:1174: Test failed: got 400 notification.c:118: Test failed: 1181: expected status 0x80000 got 0x200000 notification: Timeout winhttp.c:3611: Test failed: got 32
On Thu May 18 15:15:25 2023 +0000, Sebastian Mayr wrote:
changed this line in [version 5 of the diff](/wine/wine/-/merge_requests/2821/diffs?diff_id=47541&start_sha=0e82e1444116efd904fd04f8bc7a5144dbb29143#8dcd39f3ce7a30da5a0a0cc4bf9dba516814a9f7_10932_10915)
TL;DR: Old HW is weird, I vote not to bother too much
Never ask d3d too many questions, you might not like the answer...
That r200 driver *does* care about the texture type. Binding a volume texture makes ValidateDevice fail with D3DERR_UNSUPPORTEDTEXTUREFILTER in the following conditions:
*) A non-zero mip filter is used *) min filter != mag filter. As long as min == mag it is fine, even if both are 0xdeadbeef.
But it only validates stage 0. On stage 1 and up everything goes.
I still think we should stay the course and just ignore D3DERR_UNSUPPORTEDTEXTUREFILTER in d3d8. We don't implement texture type dependent filter capabilities and I don't know of a way to query this info from OpenGL. There is GL_ARB_internalformat_query2, but it requires OpenGL 2.0, which this GPU will never support. While I do have a fetish for making old games run on old hardware, the work to properly detect and communicate this restriction to the game is weeks of work and probably involves hardcoding restrictions based on the renderer string. Finding one user (other than myself) who runs a 2023 Wine on a 2003 hardware is probably impossible.
If you have read this far, to satisfy my curiosity though: What texture type does the game bind on stage 0 when it validates the device? 2D? Cube? Volume? If 2D, are the sizes powers of 2?
But now I have an excuse to update Linux on this box and build Wine git on it to see if it runs Worms Blast :-)
This merge request was approved by Stefan Dösinger.
On Thu May 18 15:35:24 2023 +0000, Stefan Dösinger wrote:
TL;DR: Old HW is weird, I vote not to bother too much Never ask d3d too many questions, you might not like the answer... That r200 driver *does* care about the texture type. Binding a volume texture makes ValidateDevice fail with D3DERR_UNSUPPORTEDTEXTUREFILTER in the following conditions: *) A non-zero mip filter is used *) min filter != mag filter. As long as min == mag it is fine, even if both are 0xdeadbeef. But it only validates stage 0. On stage 1 and up everything goes. I still think we should stay the course and just ignore D3DERR_UNSUPPORTEDTEXTUREFILTER in d3d8. We don't implement texture type dependent filter capabilities and I don't know of a way to query this info from OpenGL. There is GL_ARB_internalformat_query2, but it requires OpenGL 2.0, which this GPU will never support. While I do have a fetish for making old games run on old hardware, the work to properly detect and communicate this restriction to the game is weeks of work and probably involves hardcoding restrictions based on the renderer string. Finding one user (other than myself) who runs a 2023 Wine on a 2003 hardware is probably impossible. If you have read this far, to satisfy my curiosity though: What texture type does the game bind on stage 0 when it validates the device? 2D? Cube? Volume? If 2D, are the sizes powers of 2? But now I have an excuse to update Linux on this box and build Wine git on it to see if it runs Worms Blast :-)
Huh, these are some weird conditions that ValidateDevice is checking on your r200... I wonder why they only care about stage 0. But I guess not asking too many questions about this is indeed better. :)
I'm obviously also fine with just ignoring D3DERR_UNSUPPORTEDTEXTUREFILTER, it's a pretty trivial fix after all.
Concerning the texture types used by Worms Blast, it's a bit disappointing: afaict nothing fancy is going on. Just regular, power of 2 sized, 2D textures with format D3DFMT_A8R8G8B8.
Can I ignore the reports about failed tests? They seem unrelated.
Many thanks for the review!
This merge request was approved by Zebediah Figura.