[PATCH] d3d9: CreateDevice() requires a valid window to be passed in.

Jeff Smith whydoubt at gmail.com
Tue Sep 8 01:02:12 CDT 2020


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 <whydoubt at gmail.com>
---
 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




More information about the wine-devel mailing list