Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com --- dlls/d3d8/tests/device.c | 98 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 97 insertions(+), 1 deletion(-)
diff --git a/dlls/d3d8/tests/device.c b/dlls/d3d8/tests/device.c index 2b7a768f65..f63004054a 100644 --- a/dlls/d3d8/tests/device.c +++ b/dlls/d3d8/tests/device.c @@ -931,16 +931,30 @@ cleanup:
static void test_cursor(void) { + unsigned int adapter_idx, adapter_count, test_idx; IDirect3DSurface8 *cursor = NULL; + struct device_desc device_desc; + unsigned int width, height; IDirect3DDevice8 *device; + HRESULT expected_hr, hr; + D3DDISPLAYMODE mode; CURSORINFO info; IDirect3D8 *d3d; ULONG refcount; HCURSOR cur; HWND window; - HRESULT hr; BOOL ret;
+ static const DWORD device_flags[] = {0, CREATE_DEVICE_FULLSCREEN}; + static const SIZE cursor_sizes[] = + { + {1, 1}, + {2, 4}, + {3, 2}, + {2, 3}, + {6, 6}, + }; + window = create_window(); ok(!!window, "Failed to create a window.\n");
@@ -1001,8 +1015,90 @@ static void test_cursor(void) ok(info.flags & (CURSOR_SHOWING|CURSOR_SUPPRESSED), "The gdi cursor is hidden (%08x)\n", info.flags); ok(info.hCursor != cur, "The cursor handle is %p\n", info.hCursor);
+ /* Cursor dimensions must all be powers of two */ + for (test_idx = 0; test_idx < ARRAY_SIZE(cursor_sizes); ++test_idx) + { + width = cursor_sizes[test_idx].cx; + height = cursor_sizes[test_idx].cy; + hr = IDirect3DDevice8_CreateImageSurface(device, width, height, D3DFMT_A8R8G8B8, &cursor); + ok(hr == D3D_OK, "Test %u: CreateImageSurface failed, hr %#x.\n", test_idx, hr); + hr = IDirect3DDevice8_SetCursorProperties(device, 0, 0, cursor); + /* http://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2 */ + if (width && !(width & (width - 1)) && height && !(height & (height - 1))) + expected_hr = D3D_OK; + else + expected_hr = D3DERR_INVALIDCALL; + todo_wine_if(expected_hr == D3DERR_INVALIDCALL) + ok(hr == expected_hr, "Test %u: Expect SetCursorProperties return %#x, got %#x.\n", + test_idx, expected_hr, hr); + IDirect3DSurface8_Release(cursor); + } + refcount = IDirect3DDevice8_Release(device); ok(!refcount, "Device has %u references left.\n", refcount); + + /* Cursor dimensions must not exceed adapter display mode */ + device_desc.device_window = window; + device_desc.width = 640; + device_desc.height = 480; + + adapter_count = IDirect3D8_GetAdapterCount(d3d); + for (adapter_idx = 0; adapter_idx < adapter_count; ++adapter_idx) + { + for (test_idx = 0; test_idx < ARRAY_SIZE(device_flags); ++test_idx) + { + device_desc.adapter_ordinal = adapter_idx; + device_desc.flags = device_flags[test_idx]; + if (!(device = create_device(d3d, window, &device_desc))) + { + skip("Adapter %u test %u: Failed to create a D3D device.\n", adapter_idx, test_idx); + break; + } + + hr = IDirect3D8_GetAdapterDisplayMode(d3d, adapter_idx, &mode); + ok(hr == D3D_OK, "Adapter %u test %u: GetAdapterDisplayMode failed, hr %#x.\n", + adapter_idx, test_idx, hr); + + /* Find the largest width and height that are powers of two and less than the display mode */ + width = 1; + height = 1; + while (width * 2 <= mode.Width) + width *= 2; + while (height * 2 <= mode.Height) + height *= 2; + + hr = IDirect3DDevice8_CreateImageSurface(device, width, height, D3DFMT_A8R8G8B8, &cursor); + ok(hr == D3D_OK, "Adapter %u test %u: CreateImageSurface failed, hr %#x.\n", + adapter_idx, test_idx, hr); + hr = IDirect3DDevice8_SetCursorProperties(device, 0, 0, cursor); + ok(hr == D3D_OK, "Adapter %u test %u: SetCursorProperties failed, hr %#x.\n", + adapter_idx, test_idx, hr); + IDirect3DSurface8_Release(cursor); + + hr = IDirect3DDevice8_CreateImageSurface(device, width * 2, height, D3DFMT_A8R8G8B8, + &cursor); + ok(hr == D3D_OK, "Adapter %u test %u: CreateImageSurface failed, hr %#x.\n", + adapter_idx, test_idx, hr); + hr = IDirect3DDevice8_SetCursorProperties(device, 0, 0, cursor); + ok(hr == D3DERR_INVALIDCALL, + "Adapter %u test %u: Expect SetCursorProperties return %#x, got %#x.\n", + adapter_idx, test_idx, D3DERR_INVALIDCALL, hr); + IDirect3DSurface8_Release(cursor); + + hr = IDirect3DDevice8_CreateImageSurface(device, width, height * 2, D3DFMT_A8R8G8B8, + &cursor); + ok(hr == D3D_OK, "Adapter %u test %u: CreateImageSurface failed, hr %#x.\n", + adapter_idx, test_idx, hr); + hr = IDirect3DDevice8_SetCursorProperties(device, 0, 0, cursor); + ok(hr == D3DERR_INVALIDCALL, + "Adapter %u test %u: Expect SetCursorProperties return %#x, got %#x.\n", + adapter_idx, test_idx, D3DERR_INVALIDCALL, hr); + IDirect3DSurface8_Release(cursor); + + refcount = IDirect3DDevice8_Release(device); + ok(!refcount, "Adapter %u: Device has %u references left.\n", adapter_idx, refcount); + } + } cleanup: IDirect3D8_Release(d3d); DestroyWindow(window);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=68433
Your paranoid android.
=== w8 (32 bit report) ===
d3d8: device.c:1762: Test failed: Reset failed, hr 0x80070057.
On Mon, 30 Mar 2020 at 11:49, Zhiyi Zhang zzhang@codeweavers.com wrote:
/* http://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2 */
if (width && !(width & (width - 1)) && height && !(height & (height - 1)))
URLs are best avoided, they're only rarely stable. In the general case, for an algorithm, mention its name if any, its authors, and the publication/standard. In the rare case that that's not an option, there's archive.org. In this particular case though, I think this kind of check is (or should be) common knowledge; we have that kind of power-of-two check in plenty of places (e.g. wined3d_texture_init(), wined3d_texture_update_desc()), and in its related version of an alignment check in even more.