From 8b7ac24752f3c2d29f6f44aa5da1cc1203d53e55 Mon Sep 17 00:00:00 2001 From: Paul Gofman Date: Fri, 15 Mar 2024 21:40:03 -0600 Subject: [PATCH] ddraw/tests: Add tests for multiple devices. --- dlls/ddraw/tests/ddraw1.c | 104 +++++++++++++++++++++++++ dlls/ddraw/tests/ddraw2.c | 160 ++++++++++++++++++++++++++++++++++++-- dlls/ddraw/tests/ddraw4.c | 125 +++++++++++++++++++++++++++-- dlls/ddraw/tests/ddraw7.c | 88 +++++++++++++++++++-- 4 files changed, 454 insertions(+), 23 deletions(-) diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index d8fcb188c40..0940aa8d78a 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -15530,6 +15530,109 @@ static void test_pinned_sysmem(void) DestroyWindow(window); } +static void test_multiple_devices(void) +{ + static D3DMATRIX test_matrix = + { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 2.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 3.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 4.0f, + }; + + D3DTEXTUREHANDLE texture_handle, texture_handle2; + D3DMATERIALHANDLE mat_handle, mat_handle2; + IDirect3DViewport *viewport, *viewport2; + IDirect3DDevice *device, *device2; + IDirectDrawSurface *texture_surf; + D3DMATRIXHANDLE matrix_handle; + IDirectDraw *ddraw, *ddraw2; + IDirect3DMaterial *material; + DDSURFACEDESC surface_desc; + IDirect3DTexture *texture; + D3DMATRIX matrix; + ULONG refcount; + HWND window; + HRESULT hr; + + window = create_window(); + ddraw = create_ddraw(); + ok(!!ddraw, "Failed to create a ddraw object.\n"); + + if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, &IID_IDirect3DHALDevice))) + { + skip("Failed to create a 3D device, skipping test.\n"); + DestroyWindow(window); + return; + } + + ddraw2 = create_ddraw(); + ok(!!ddraw2, "Failed to create a ddraw object.\n"); + + device2 = create_device_ex(ddraw2, window, DDSCL_NORMAL, &IID_IDirect3DHALDevice); + ok(!!device2, "got NULL.\n"); + + viewport = create_viewport(device, 0, 0, 640, 480); + viewport2 = create_viewport(device2, 0, 0, 640, 480); + + material = create_diffuse_material(device, 1.0f, 0.0f, 0.0f, 1.0f); + hr = IDirect3DMaterial2_GetHandle(material, device, &mat_handle); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DMaterial2_GetHandle(material, device, &mat_handle2); + ok(hr == D3D_OK, "got %#lx.\n", hr); + ok(mat_handle == mat_handle2, "got different handles.\n"); + + hr = IDirect3DMaterial_GetHandle(material, device2, &mat_handle2); + ok(hr == D3D_OK, "got %#lx.\n", hr); + todo_wine ok(mat_handle != mat_handle2, "got same handles.\n"); + + hr = IDirect3DViewport_SetBackground(viewport, mat_handle); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DViewport_SetBackground(viewport2, mat_handle); + ok(hr == D3D_OK, "got %#lx.\n", hr); + + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE; + surface_desc.dwWidth = 256; + surface_desc.dwHeight = 256; + hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &texture_surf, NULL); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirectDrawSurface_QueryInterface(texture_surf, &IID_IDirect3DTexture2, (void **)&texture); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DTexture_GetHandle(texture, device, &texture_handle); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DTexture_GetHandle(texture, device2, &texture_handle2); + ok(hr == D3D_OK, "got %#lx.\n", hr); + ok(texture_handle != texture_handle2, "got same handles.\n"); + + hr = IDirect3DDevice_CreateMatrix(device, &matrix_handle); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DDevice_SetMatrix(device, matrix_handle, &test_matrix); + ok(hr == D3D_OK, "got %#lx.\n", hr); + + memset(&matrix, 0xcc, sizeof(matrix)); + hr = IDirect3DDevice_GetMatrix(device2, matrix_handle, &matrix); + ok(hr == D3D_OK, "got %#lx.\n", hr); + ok(!memcmp(&matrix, &test_matrix, sizeof(matrix)), "matrix does not match.\n"); + + IDirect3DTexture_Release(texture); + IDirectDrawSurface_Release(texture_surf); + IDirect3DMaterial_Release(material); + IDirect3DViewport_Release(viewport); + IDirect3DViewport_Release(viewport2); + + refcount = IDirect3DDevice_Release(device); + ok(!refcount, "Device has %lu references left.\n", refcount); + refcount = IDirect3DDevice_Release(device2); + ok(!refcount, "Device has %lu references left.\n", refcount); + + IDirectDraw_Release(ddraw); + IDirectDraw_Release(ddraw2); + DestroyWindow(window); +} + START_TEST(ddraw1) { DDDEVICEIDENTIFIER identifier; @@ -15650,4 +15753,5 @@ START_TEST(ddraw1) test_filling_convention(); test_enum_devices(); test_pinned_sysmem(); + test_multiple_devices(); } diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c index f4cc5df0558..1a95d4e66f1 100644 --- a/dlls/ddraw/tests/ddraw2.c +++ b/dlls/ddraw/tests/ddraw2.c @@ -462,7 +462,8 @@ static IDirectDraw2 *create_ddraw(void) return ddraw2; } -static IDirect3DDevice2 *create_device_ex(IDirectDraw2 *ddraw, HWND window, DWORD coop_level, const GUID *device_guid) +static IDirect3DDevice2 *create_device_ex(IDirectDraw2 *ddraw, HWND window, DWORD coop_level, const GUID *device_guid, + IDirectDrawSurface **ret_surface) { /* Prefer 16 bit depth buffers because Nvidia gives us an unpadded D24 buffer if we ask * for 24 bit and handles such buffers incorrectly in DDBLT_DEPTHFILL. AMD only supports @@ -541,13 +542,17 @@ static IDirect3DDevice2 *create_device_ex(IDirectDraw2 *ddraw, HWND window, DWOR } IDirect3D2_Release(d3d); - IDirectDrawSurface_Release(surface); + if (ret_surface) + *ret_surface = surface; + else + IDirectDrawSurface_Release(surface); + return device; } static IDirect3DDevice2 *create_device(IDirectDraw2 *ddraw, HWND window, DWORD coop_level) { - return create_device_ex(ddraw, window, coop_level, &IID_IDirect3DHALDevice); + return create_device_ex(ddraw, window, coop_level, &IID_IDirect3DHALDevice, NULL); } static IDirect3DViewport2 *create_viewport(IDirect3DDevice2 *device, UINT x, UINT y, UINT w, UINT h) @@ -1330,7 +1335,7 @@ static void test_depth_blit(const GUID *device_guid) window = create_window(); ddraw = create_ddraw(); ok(!!ddraw, "Failed to create a ddraw object.\n"); - if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid))) + if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid, NULL))) { skip("Failed to create a 3D device, skipping test.\n"); IDirectDraw2_Release(ddraw); @@ -1856,7 +1861,7 @@ static void test_zenable(const GUID *device_guid) window = create_window(); ddraw = create_ddraw(); ok(!!ddraw, "Failed to create a ddraw object.\n"); - if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid))) + if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid, NULL))) { skip("Failed to create a 3D device, skipping test.\n"); IDirectDraw2_Release(ddraw); @@ -1971,7 +1976,7 @@ static void test_ck_rgba(const GUID *device_guid) window = create_window(); ddraw = create_ddraw(); ok(!!ddraw, "Failed to create a ddraw object.\n"); - if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid))) + if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid, NULL))) { skip("Failed to create a 3D device, skipping test.\n"); IDirectDraw2_Release(ddraw); @@ -5204,7 +5209,7 @@ static void test_rt_caps(const GUID *device_guid) window = create_window(); ddraw = create_ddraw(); ok(!!ddraw, "Failed to create a ddraw object.\n"); - if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid))) + if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid, NULL))) { skip("Failed to create a 3D device, skipping test.\n"); IDirectDraw2_Release(ddraw); @@ -15692,7 +15697,7 @@ static void test_texture_wrong_caps(const GUID *device_guid) window = create_window(); ddraw = create_ddraw(); ok(!!ddraw, "Failed to create a ddraw object.\n"); - if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid))) + if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid, NULL))) { skip("Failed to create a 3D device, skipping test.\n"); DestroyWindow(window); @@ -16442,6 +16447,144 @@ static void run_for_each_device_type(void (*test_func)(const GUID *)) test_func(&IID_IDirect3DRGBDevice); } +static void test_multiple_devices(void) +{ + D3DTEXTUREHANDLE texture_handle, texture_handle2; + IDirect3DDevice2 *device, *device2, *device3; + IDirectDrawSurface *surface, *texture_surf; + D3DMATERIALHANDLE mat_handle, mat_handle2; + IDirect3DViewport2 *viewport, *viewport2; + IDirectDraw2 *ddraw, *ddraw2; + IDirect3DMaterial2 *material; + DDSURFACEDESC surface_desc; + IDirect3DTexture2 *texture; + IDirect3D2 *d3d; + ULONG refcount; + DWORD value; + HWND window; + HRESULT hr; + + window = create_window(); + ddraw = create_ddraw(); + ok(!!ddraw, "Failed to create a ddraw object.\n"); + + if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, &IID_IDirect3DHALDevice, &surface))) + { + skip("Failed to create a 3D device, skipping test.\n"); + DestroyWindow(window); + return; + } + + hr = IDirect3DDevice2_GetDirect3D(device, &d3d); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3D2_CreateDevice(d3d, &IID_IDirect3DHALDevice, surface, &device2); + ok(hr == D3D_OK, "got %#lx.\n", hr); + + ddraw2 = create_ddraw(); + ok(!!ddraw2, "Failed to create a ddraw object.\n"); + device3 = create_device(ddraw2, window, DDSCL_NORMAL); + ok(!!device3, "got NULL.\n"); + + viewport = create_viewport(device, 0, 0, 640, 480); + viewport2 = create_viewport(device2, 0, 0, 640, 480); + hr = IDirect3DDevice2_SetCurrentViewport(device, viewport); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DDevice2_SetCurrentViewport(device2, viewport); + ok(hr == DDERR_INVALIDPARAMS, "got %#lx.\n", hr); + hr = IDirect3DDevice2_SetCurrentViewport(device2, viewport2); + ok(hr == D3D_OK, "got %#lx.\n", hr); + + material = create_diffuse_material(device, 1.0f, 0.0f, 0.0f, 1.0f); + hr = IDirect3DMaterial2_GetHandle(material, device, &mat_handle); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DMaterial2_GetHandle(material, device, &mat_handle2); + ok(hr == D3D_OK, "got %#lx.\n", hr); + ok(mat_handle == mat_handle2, "got different handles.\n"); + + hr = IDirect3DMaterial2_GetHandle(material, device2, &mat_handle2); + ok(hr == D3D_OK, "got %#lx.\n", hr); + todo_wine ok(mat_handle != mat_handle2, "got same handles.\n"); + + hr = IDirect3DDevice2_SetLightState(device, D3DLIGHTSTATE_MATERIAL, mat_handle); + ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr); + hr = IDirect3DDevice2_SetLightState(device2, D3DLIGHTSTATE_MATERIAL, mat_handle); + ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr); + hr = IDirect3DDevice2_SetLightState(device3, D3DLIGHTSTATE_MATERIAL, mat_handle); + ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr); + hr = IDirect3DDevice2_SetLightState(device, D3DLIGHTSTATE_MATERIAL, mat_handle2); + ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr); + + hr = IDirect3DViewport2_SetBackground(viewport, mat_handle); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DViewport2_SetBackground(viewport2, mat_handle); + ok(hr == D3D_OK, "got %#lx.\n", hr); + + hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + hr = IDirect3DDevice2_SetRenderState(device2, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + hr = IDirect3DDevice2_SetRenderState(device3, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + + hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, TRUE); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + value = 0xdeadbeef; + hr = IDirect3DDevice2_GetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, &value); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + ok(value == TRUE, "got %#lx.\n", value); + hr = IDirect3DDevice2_GetRenderState(device2, D3DRENDERSTATE_ALPHABLENDENABLE, &value); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + ok(!value, "got %#lx.\n", value); + hr = IDirect3DDevice2_GetRenderState(device3, D3DRENDERSTATE_ALPHABLENDENABLE, &value); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + ok(!value, "got %#lx.\n", value); + + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE; + surface_desc.dwWidth = 256; + surface_desc.dwHeight = 256; + hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &texture_surf, NULL); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirectDrawSurface_QueryInterface(texture_surf, &IID_IDirect3DTexture2, (void **)&texture); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DTexture2_GetHandle(texture, device, &texture_handle); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DTexture2_GetHandle(texture, device2, &texture_handle2); + ok(hr == D3D_OK, "got %#lx.\n", hr); + ok(texture_handle == texture_handle2, "got different handles.\n"); + hr = IDirect3DTexture2_GetHandle(texture, device3, &texture_handle2); + ok(hr == D3D_OK, "got %#lx.\n", hr); + ok(texture_handle == texture_handle2, "got different handles.\n"); + hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_TEXTUREHANDLE, texture_handle); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DDevice2_SetRenderState(device2, D3DRENDERSTATE_TEXTUREHANDLE, texture_handle); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DDevice2_SetRenderState(device3, D3DRENDERSTATE_TEXTUREHANDLE, texture_handle); + ok(hr == D3D_OK, "got %#lx.\n", hr); + + IDirect3DTexture2_Release(texture); + IDirectDrawSurface_Release(texture_surf); + IDirect3DMaterial2_Release(material); + IDirect3DViewport2_Release(viewport); + IDirect3DViewport2_Release(viewport2); + + refcount = IDirect3DDevice2_Release(device); + ok(!refcount, "Device has %lu references left.\n", refcount); + refcount = IDirect3DDevice2_Release(device2); + ok(!refcount, "Device has %lu references left.\n", refcount); + refcount = IDirect3DDevice2_Release(device3); + ok(!refcount, "Device has %lu references left.\n", refcount); + refcount = IDirectDrawSurface_Release(surface); + ok(!refcount, "Surface has %lu references left.\n", refcount); + + IDirectDraw2_Release(ddraw); + IDirectDraw_Release(ddraw2); + IDirect3D2_Release(d3d); + DestroyWindow(window); +} + START_TEST(ddraw2) { DDDEVICEIDENTIFIER identifier; @@ -16567,4 +16710,5 @@ START_TEST(ddraw2) run_for_each_device_type(test_texture_wrong_caps); test_filling_convention(); test_enum_devices(); + test_multiple_devices(); } diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c index 4811053a231..69dc0f13704 100644 --- a/dlls/ddraw/tests/ddraw4.c +++ b/dlls/ddraw/tests/ddraw4.c @@ -450,7 +450,8 @@ static IDirectDraw4 *create_ddraw(void) return ddraw4; } -static IDirect3DDevice3 *create_device_ex(HWND window, DWORD coop_level, const GUID *device_guid) +static IDirect3DDevice3 *create_device_ex(HWND window, DWORD coop_level, const GUID *device_guid, + IDirectDrawSurface4 **ret_surface) { IDirectDrawSurface4 *surface, *ds; IDirect3DDevice3 *device = NULL; @@ -539,16 +540,22 @@ static IDirect3DDevice3 *create_device_ex(HWND window, DWORD coop_level, const G hr = IDirect3D3_CreateDevice(d3d3, device_guid, surface, &device, NULL); IDirect3D3_Release(d3d3); - IDirectDrawSurface4_Release(surface); if (FAILED(hr)) + { + IDirectDrawSurface4_Release(surface); return NULL; + } + if (ret_surface) + *ret_surface = surface; + else + IDirectDrawSurface4_Release(surface); return device; } static IDirect3DDevice3 *create_device(HWND window, DWORD coop_level) { - return create_device_ex(window, coop_level, &IID_IDirect3DHALDevice); + return create_device_ex(window, coop_level, &IID_IDirect3DHALDevice, NULL); } static IDirect3DViewport3 *create_viewport(IDirect3DDevice3 *device, UINT x, UINT y, UINT w, UINT h) @@ -1506,7 +1513,7 @@ static void test_depth_blit(const GUID *device_guid) D3DRECT d3drect; window = create_window(); - if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid))) + if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid, NULL))) { skip("Failed to create a 3D device, skipping test.\n"); DestroyWindow(window); @@ -2101,7 +2108,7 @@ static void test_zenable(const GUID *device_guid) HRESULT hr; window = create_window(); - if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid))) + if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid, NULL))) { skip("Failed to create a 3D device, skipping test.\n"); DestroyWindow(window); @@ -2213,7 +2220,7 @@ static void test_ck_rgba(const GUID *device_guid) HRESULT hr; window = create_window(); - if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid))) + if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid, NULL))) { skip("Failed to create a 3D device, skipping test.\n"); DestroyWindow(window); @@ -18750,7 +18757,7 @@ static void test_texture_wrong_caps(const GUID *device_guid) HRESULT hr; window = create_window(); - if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid))) + if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid, NULL))) { skip("Failed to create a 3D device, skipping test.\n"); DestroyWindow(window); @@ -19506,6 +19513,109 @@ static void test_enum_devices(void) ok(!refcount, "Device has %lu references left.\n", refcount); } +static void test_multiple_devices(void) +{ + IDirect3DDevice3 *device, *device2, *device3; + D3DMATERIALHANDLE mat_handle, mat_handle2; + IDirect3DViewport3 *viewport, *viewport2; + IDirect3DMaterial3 *material; + IDirectDrawSurface4 *surface; + IDirectDraw4 *ddraw; + IDirect3D3 *d3d; + ULONG refcount; + DWORD value; + HWND window; + HRESULT hr; + + window = create_window(); + if (!(device = create_device_ex(window, DDSCL_NORMAL, &IID_IDirect3DHALDevice, &surface))) + { + skip("Failed to create a 3D device, skipping test.\n"); + DestroyWindow(window); + return; + } + + hr = IDirect3DDevice3_GetDirect3D(device, &d3d); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DDevice3_QueryInterface(d3d, &IID_IDirectDraw4, (void **)&ddraw); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3D3_CreateDevice(d3d, &IID_IDirect3DHALDevice, surface, &device2, NULL); + ok(hr == D3D_OK, "got %#lx.\n", hr); + + device3 = create_device(window, DDSCL_NORMAL); + ok(!!device3, "got NULL.\n"); + + viewport = create_viewport(device, 0, 0, 640, 480); + viewport2 = create_viewport(device2, 0, 0, 640, 480); + hr = IDirect3DDevice3_SetCurrentViewport(device, viewport); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DDevice3_SetCurrentViewport(device2, viewport); + ok(hr == DDERR_INVALIDPARAMS, "got %#lx.\n", hr); + hr = IDirect3DDevice3_SetCurrentViewport(device2, viewport2); + ok(hr == D3D_OK, "got %#lx.\n", hr); + + material = create_diffuse_material(device, 1.0f, 0.0f, 0.0f, 1.0f); + hr = IDirect3DMaterial3_GetHandle(material, device, &mat_handle); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DMaterial3_GetHandle(material, device, &mat_handle2); + ok(hr == D3D_OK, "got %#lx.\n", hr); + ok(mat_handle == mat_handle2, "got different handles.\n"); + + hr = IDirect3DMaterial3_GetHandle(material, device2, &mat_handle2); + ok(hr == D3D_OK, "got %#lx.\n", hr); + todo_wine ok(mat_handle != mat_handle2, "got same handles.\n"); + + hr = IDirect3DDevice3_SetLightState(device, D3DLIGHTSTATE_MATERIAL, mat_handle); + ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr); + hr = IDirect3DDevice3_SetLightState(device2, D3DLIGHTSTATE_MATERIAL, mat_handle); + ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr); + hr = IDirect3DDevice3_SetLightState(device3, D3DLIGHTSTATE_MATERIAL, mat_handle); + ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr); + hr = IDirect3DDevice3_SetLightState(device, D3DLIGHTSTATE_MATERIAL, mat_handle2); + ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr); + + hr = IDirect3DViewport3_SetBackground(viewport, mat_handle); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DViewport3_SetBackground(viewport2, mat_handle); + ok(hr == D3D_OK, "got %#lx.\n", hr); + + hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + hr = IDirect3DDevice3_SetRenderState(device2, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + hr = IDirect3DDevice3_SetRenderState(device3, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + + hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, TRUE); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + value = 0xdeadbeef; + hr = IDirect3DDevice3_GetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, &value); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + ok(value == TRUE, "got %#lx.\n", value); + hr = IDirect3DDevice3_GetRenderState(device2, D3DRENDERSTATE_ALPHABLENDENABLE, &value); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + ok(!value, "got %#lx.\n", value); + hr = IDirect3DDevice3_GetRenderState(device3, D3DRENDERSTATE_ALPHABLENDENABLE, &value); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + ok(!value, "got %#lx.\n", value); + + IDirect3DMaterial3_Release(material); + IDirect3DViewport3_Release(viewport); + IDirect3DViewport3_Release(viewport2); + + refcount = IDirect3DDevice3_Release(device); + ok(!refcount, "Device has %lu references left.\n", refcount); + refcount = IDirect3DDevice3_Release(device2); + ok(!refcount, "Device has %lu references left.\n", refcount); + refcount = IDirect3DDevice3_Release(device3); + ok(!refcount, "Device has %lu references left.\n", refcount); + refcount = IDirectDrawSurface4_Release(surface); + ok(!refcount, "Surface has %lu references left.\n", refcount); + IDirectDraw4_Release(ddraw); + IDirect3D3_Release(d3d); + DestroyWindow(window); +} + START_TEST(ddraw4) { DDDEVICEIDENTIFIER identifier; @@ -19647,4 +19757,5 @@ START_TEST(ddraw4) run_for_each_device_type(test_texture_wrong_caps); test_filling_convention(); test_enum_devices(); + test_multiple_devices(); } diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index 2771a4ed368..8bd93c77b32 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -498,7 +498,8 @@ static HRESULT WINAPI enum_devtype_cb(char *desc_str, char *name, D3DDEVICEDESC7 return DDENUMRET_OK; } -static IDirect3DDevice7 *create_device_ex(HWND window, DWORD coop_level, const GUID *device_guid) +static IDirect3DDevice7 *create_device_ex(HWND window, DWORD coop_level, const GUID *device_guid, + IDirectDrawSurface7 **ret_surface) { IDirectDrawSurface7 *surface, *ds; IDirect3DDevice7 *device = NULL; @@ -586,9 +587,16 @@ static IDirect3DDevice7 *create_device_ex(HWND window, DWORD coop_level, const G hr = IDirect3D7_CreateDevice(d3d7, device_guid, surface, &device); IDirect3D7_Release(d3d7); - IDirectDrawSurface7_Release(surface); if (FAILED(hr)) + { + IDirectDrawSurface7_Release(surface); return NULL; + } + + if (ret_surface) + *ret_surface = surface; + else + IDirectDrawSurface7_Release(surface); return device; } @@ -615,7 +623,7 @@ static IDirect3DDevice7 *create_device(HWND window, DWORD coop_level) IDirect3D7_Release(d3d7); - return create_device_ex(window, coop_level, device_guid); + return create_device_ex(window, coop_level, device_guid, NULL); } static bool init_3d_test_context_guid(struct ddraw_test_context *context, const GUID *device_guid) @@ -625,7 +633,7 @@ static bool init_3d_test_context_guid(struct ddraw_test_context *context, const memset(context, 0, sizeof(*context)); context->window = create_window(); - if (!(context->device = create_device_ex(context->window, DDSCL_NORMAL, device_guid))) + if (!(context->device = create_device_ex(context->window, DDSCL_NORMAL, device_guid, NULL))) { skip("Failed to create a D3D device.\n"); DestroyWindow(context->window); @@ -1586,7 +1594,7 @@ static void test_depth_blit(const GUID *device_guid) HWND window; window = create_window(); - if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid))) + if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid, NULL))) { skip("Failed to create a 3D device, skipping test.\n"); DestroyWindow(window); @@ -1844,7 +1852,7 @@ static void test_zenable(const GUID *device_guid) HRESULT hr; window = create_window(); - if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid))) + if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid, NULL))) { skip("Failed to create a 3D device, skipping test.\n"); DestroyWindow(window); @@ -1948,7 +1956,7 @@ static void test_ck_rgba(const GUID *device_guid) HRESULT hr; window = create_window(); - if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid))) + if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid, NULL))) { skip("Failed to create a 3D device, skipping test.\n"); DestroyWindow(window); @@ -19134,7 +19142,7 @@ static void test_texture_wrong_caps(const GUID *device_guid) HRESULT hr; window = create_window(); - if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid))) + if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid, NULL))) { skip("Failed to create a 3D device, skipping test.\n"); DestroyWindow(window); @@ -20001,6 +20009,69 @@ static void run_for_each_device_type(void (*test_func)(const GUID *)) winetest_pop_context(); } +static void test_multiple_devices(void) +{ + IDirect3DDevice7 *device, *device2; + IDirectDrawSurface7 *surface; + IDirectDraw7 *ddraw; + IDirect3D7 *d3d; + ULONG refcount; + DWORD stateblock; + DWORD value; + HWND window; + HRESULT hr; + + window = create_window(); + if (!(device = create_device_ex(window, DDSCL_NORMAL, &IID_IDirect3DTnLHalDevice, &surface))) + { + skip("Failed to create a 3D device, skipping test.\n"); + DestroyWindow(window); + return; + } + + hr = IDirect3DDevice7_GetDirect3D(device, &d3d); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DDevice7_QueryInterface(d3d, &IID_IDirectDraw7, (void **)&ddraw); + ok(hr == D3D_OK, "got %#lx.\n", hr); + + hr = IDirect3D7_CreateDevice(d3d, &IID_IDirect3DHALDevice, surface, &device2); + ok(hr == D3D_OK, "got %#lx.\n", hr); + + hr = IDirect3DDevice7_CreateStateBlock(device, D3DSBT_ALL, &stateblock); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DDevice7_CaptureStateBlock(device2, stateblock); + ok(hr == D3DERR_INVALIDSTATEBLOCK, "got %#lx.\n", hr); + hr = IDirect3DDevice7_CaptureStateBlock(device, stateblock); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DDevice7_DeleteStateBlock(device, stateblock); + ok(hr == D3D_OK, "got %#lx.\n", hr); + + hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + hr = IDirect3DDevice3_SetRenderState(device2, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + + hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, TRUE); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + value = 0xdeadbeef; + hr = IDirect3DDevice3_GetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, &value); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + ok(value == TRUE, "got %#lx.\n", value); + hr = IDirect3DDevice3_GetRenderState(device2, D3DRENDERSTATE_ALPHABLENDENABLE, &value); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + ok(!value, "got %#lx.\n", value); + + refcount = IDirect3DDevice3_Release(device); + ok(!refcount, "Device has %lu references left.\n", refcount); + refcount = IDirect3DDevice3_Release(device2); + ok(!refcount, "Device has %lu references left.\n", refcount); + refcount = IDirectDrawSurface4_Release(surface); + ok(!refcount, "Surface has %lu references left.\n", refcount); + IDirectDraw4_Release(ddraw); + IDirect3D3_Release(d3d); + DestroyWindow(window); +} + START_TEST(ddraw7) { DDDEVICEIDENTIFIER2 identifier; @@ -20176,4 +20247,5 @@ START_TEST(ddraw7) test_enum_devices(); run_for_each_device_type(test_user_memory); test_flip_3d(); + test_multiple_devices(); }