From: Jeff Smith Subject: [PATCH] d3d9: CreateDevice() requires a valid window to be passed in. Message-Id: <20200908060212.463849-1-whydoubt@gmail.com> Date: Tue, 8 Sep 2020 01:02:12 -0500 CreateDevice() and CreateDeviceEx() expect the focus window to be non-NULL. If windowed mode is used, the focus window can be NULL as long as the device window is non-NULL instead. Signed-off-by: Jeff Smith --- dlls/d3d9/device.c | 3 ++ dlls/d3d9/tests/device.c | 87 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index b92193d46f..3f9004c4c0 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -4711,6 +4711,9 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine if (output_idx >= parent->wined3d_output_count) return D3DERR_INVALIDCALL; + if (focus_window == 0 && (parameters->hDeviceWindow == 0 || !parameters->Windowed)) + return D3DERR_INVALIDCALL; + if (mode) FIXME("Ignoring display mode.\n"); diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c index 53a83ad887..0fb439bbe3 100644 --- a/dlls/d3d9/tests/device.c +++ b/dlls/d3d9/tests/device.c @@ -289,6 +289,92 @@ static HRESULT reset_device(IDirect3DDevice9 *device, const struct device_desc * if (container_ptr && container_ptr != (void *)0x1337c0d3) IUnknown_Release((IUnknown *)container_ptr); \ } +static void test_create_device(void) +{ + IDirect3D9 *d3d9; + IDirect3DDevice9 *device; + HWND window; + HRESULT hr; + D3DPRESENT_PARAMETERS present_parameters = {0}; + DWORD behavior_flags = D3DCREATE_HARDWARE_VERTEXPROCESSING; + + window = create_window(); + d3d9 = Direct3DCreate9(D3D_SDK_VERSION); + ok(!!d3d9, "Failed to create a D3D object.\n"); + + if (!(device = create_device(d3d9, window, NULL))) + { + skip("Failed to create a D3D device, skipping tests.\n"); + goto done; + } + IDirect3DDevice9_Release(device); + + /* Presentation parameters = NULL causes a crash in Windows. */ + + /* In windowed mode, focus window or device window must be set. */ + + present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD; + present_parameters.Windowed = TRUE; + hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window, + behavior_flags, &present_parameters, &device); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + ok(present_parameters.BackBufferWidth == 640, + "Got unexpected BackBufferWidth %u.\n", present_parameters.BackBufferWidth); + ok(present_parameters.BackBufferHeight == 480, + "Got unexpected BackBufferHeight %u.\n", present_parameters.BackBufferHeight); + ok(present_parameters.BackBufferFormat == D3DFMT_X8R8G8B8, + "Got unexpected BackBufferFormat %u.\n", present_parameters.BackBufferFormat); + IDirect3DDevice9_Release(device); + + memset(&present_parameters, 0, sizeof(D3DPRESENT_PARAMETERS)); + present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD; + present_parameters.Windowed = TRUE; + present_parameters.hDeviceWindow = window; + hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, NULL, + behavior_flags, &present_parameters, &device); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + ok(present_parameters.BackBufferWidth == 640, + "Got unexpected BackBufferWidth %u.\n", present_parameters.BackBufferWidth); + ok(present_parameters.BackBufferHeight == 480, + "Got unexpected BackBufferHeight %u.\n", present_parameters.BackBufferHeight); + ok(present_parameters.BackBufferFormat == D3DFMT_X8R8G8B8, + "Got unexpected BackBufferFormat %u.\n", present_parameters.BackBufferFormat); + IDirect3DDevice9_Release(device); + + memset(&present_parameters, 0, sizeof(D3DPRESENT_PARAMETERS)); + present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD; + present_parameters.Windowed = TRUE; + hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, NULL, + behavior_flags, &present_parameters, &device); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr); + + /* In fullscreen mode, focus window must be set. */ + + memset(&present_parameters, 0, sizeof(D3DPRESENT_PARAMETERS)); + present_parameters.BackBufferWidth = 640; + present_parameters.BackBufferHeight = 480; + present_parameters.BackBufferFormat = D3DFMT_X8R8G8B8; + present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD; + hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window, + behavior_flags, &present_parameters, &device); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + IDirect3DDevice9_Release(device); + + memset(&present_parameters, 0, sizeof(D3DPRESENT_PARAMETERS)); + present_parameters.BackBufferWidth = 640; + present_parameters.BackBufferHeight = 480; + present_parameters.BackBufferFormat = D3DFMT_X8R8G8B8; + present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD; + present_parameters.hDeviceWindow = window; + hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, NULL, + behavior_flags, &present_parameters, &device); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr); + +done: + IDirect3D9_Release(d3d9); + DestroyWindow(window); +} + static void test_get_set_vertex_declaration(void) { IDirect3DVertexDeclaration9 *declaration, *tmp; @@ -14136,6 +14222,7 @@ START_TEST(device) Direct3DShaderValidatorCreate9 = (void *)GetProcAddress(d3d9_handle, "Direct3DShaderValidatorCreate9"); + test_create_device(); test_get_set_vertex_declaration(); test_get_declaration(); test_fvf_decl_conversion(); -- 2.23.0