diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index 98b83334122..5bfca430086 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -4413,23 +4413,31 @@ static void test_surface_discard(void) unsigned int i; window = create_window(); - ddraw = create_ddraw(); - ok(!!ddraw, "Failed to create a ddraw object.\n"); - if (!(device = create_device(ddraw, window, DDSCL_NORMAL))) - { - skip("Failed to create a 3D device, skipping test.\n"); - IDirectDraw_Release(ddraw); - DestroyWindow(window); - return; - } - - hr = IDirect3DDevice_QueryInterface(device, &IID_IDirectDrawSurface, (void **)&target); - ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr); for (i = 0; i < ARRAY_SIZE(tests); i++) { BOOL discarded; + /* Sigh. Anything other than the first run of the loop randomly fails with + * DDERR_SURFACELOST on my Radeon Pro 560 on Win10 19.09. Most of the time + * the blit fails, but with sleeps added between surface creation and lock + * the lock can fail too. Interestingly ddraw claims the render target has + * been lost, not the test surface. + * + * Recreating ddraw every iteration seems to fix this. */ + ddraw = create_ddraw(); + ok(!!ddraw, "Failed to create a ddraw object.\n"); + if (!(device = create_device(ddraw, window, DDSCL_NORMAL))) + { + skip("Failed to create a 3D device, skipping test.\n"); + IDirectDraw_Release(ddraw); + DestroyWindow(window); + return; + } + + hr = IDirect3DDevice_QueryInterface(device, &IID_IDirectDrawSurface, (void**)&target); + ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr); + memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; @@ -4475,11 +4483,12 @@ static void test_surface_discard(void) /* Windows 7 reliably changes the address of surfaces that are discardable (Nvidia Kepler, * AMD r500, evergreen). Windows XP, at least on AMD r200, never changes the pointer. */ ok(!discarded || tests[i].discard, "Expected surface not to be discarded, case %u\n", i); + + IDirectDrawSurface_Release(target); + IDirect3DDevice_Release(device); + IDirectDraw_Release(ddraw); } - IDirectDrawSurface_Release(target); - IDirect3DDevice_Release(device); - IDirectDraw_Release(ddraw); DestroyWindow(window); } diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c index 7dfb35d2d3a..b472b3d5883 100644 --- a/dlls/ddraw/tests/ddraw2.c +++ b/dlls/ddraw/tests/ddraw2.c @@ -4943,23 +4943,31 @@ static void test_surface_discard(void) unsigned int i; window = create_window(); - ddraw = create_ddraw(); - ok(!!ddraw, "Failed to create a ddraw object.\n"); - if (!(device = create_device(ddraw, window, DDSCL_NORMAL))) - { - skip("Failed to create a 3D device, skipping test.\n"); - DestroyWindow(window); - IDirectDraw2_Release(ddraw); - return; - } - - hr = IDirect3DDevice2_GetRenderTarget(device, &target); - ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr); for (i = 0; i < ARRAY_SIZE(tests); i++) { BOOL discarded; + /* Sigh. Anything other than the first run of the loop randomly fails with + * DDERR_SURFACELOST on my Radeon Pro 560 on Win10 19.09. Most of the time + * the blit fails, but with sleeps added between surface creation and lock + * the lock can fail too. Interestingly ddraw claims the render target has + * been lost, not the test surface. + * + * Recreating ddraw every iteration seems to fix this. */ + ddraw = create_ddraw(); + ok(!!ddraw, "Failed to create a ddraw object.\n"); + if (!(device = create_device(ddraw, window, DDSCL_NORMAL))) + { + skip("Failed to create a 3D device, skipping test.\n"); + DestroyWindow(window); + IDirectDraw2_Release(ddraw); + return; + } + + hr = IDirect3DDevice2_GetRenderTarget(device, &target); + ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr); + memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; @@ -5005,11 +5013,12 @@ static void test_surface_discard(void) /* Windows 7 reliably changes the address of surfaces that are discardable (Nvidia Kepler, * AMD r500, evergreen). Windows XP, at least on AMD r200, never changes the pointer. */ ok(!discarded || tests[i].discard, "Expected surface not to be discarded, case %u\n", i); + + IDirectDrawSurface_Release(target); + IDirect3DDevice2_Release(device); + IDirectDraw2_Release(ddraw); } - IDirectDrawSurface_Release(target); - IDirect3DDevice2_Release(device); - IDirectDraw2_Release(ddraw); DestroyWindow(window); } diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c index e1d5bac18bb..1e6cf4c446a 100644 --- a/dlls/ddraw/tests/ddraw4.c +++ b/dlls/ddraw/tests/ddraw4.c @@ -6565,23 +6565,31 @@ static void test_surface_discard(void) unsigned int i; window = create_window(); - if (!(device = create_device(window, DDSCL_NORMAL))) - { - skip("Failed to create a 3D device, skipping test.\n"); - DestroyWindow(window); - return; - } - hr = IDirect3DDevice3_GetDirect3D(device, &d3d); - ok(SUCCEEDED(hr), "Failed to get d3d interface, hr %#x.\n", hr); - hr = IDirect3D3_QueryInterface(d3d, &IID_IDirectDraw4, (void **)&ddraw); - ok(SUCCEEDED(hr), "Failed to get ddraw interface, hr %#x.\n", hr); - hr = IDirect3DDevice3_GetRenderTarget(device, &target); - ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr); for (i = 0; i < ARRAY_SIZE(tests); i++) { BOOL discarded; + /* Sigh. Anything other than the first run of the loop randomly fails with + * DDERR_SURFACELOST on my Radeon Pro 560 on Win10 19.09. Most of the time + * the blit fails, but with sleeps added between surface creation and lock + * the lock can fail too. Interestingly ddraw claims the render target has + * been lost, not the test surface. + * + * Recreating ddraw every iteration seems to fix this. */ + if (!(device = create_device(window, DDSCL_NORMAL))) + { + skip("Failed to create a 3D device, skipping test.\n"); + DestroyWindow(window); + return; + } + hr = IDirect3DDevice3_GetDirect3D(device, &d3d); + ok(SUCCEEDED(hr), "Failed to get d3d interface, hr %#x.\n", hr); + hr = IDirect3D3_QueryInterface(d3d, &IID_IDirectDraw4, (void **)&ddraw); + ok(SUCCEEDED(hr), "Failed to get ddraw interface, hr %#x.\n", hr); + hr = IDirect3DDevice3_GetRenderTarget(device, &target); + ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr); + memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; @@ -6624,12 +6632,13 @@ static void test_surface_discard(void) /* Windows 7 reliably changes the address of surfaces that are discardable (Nvidia Kepler, * AMD r500, evergreen). Windows XP, at least on AMD r200, does not. */ ok(!discarded || tests[i].discard, "Expected surface not to be discarded, case %u\n", i); + + IDirectDrawSurface4_Release(target); + IDirectDraw4_Release(ddraw); + IDirect3D3_Release(d3d); + IDirect3DDevice3_Release(device); } - IDirectDrawSurface4_Release(target); - IDirectDraw4_Release(ddraw); - IDirect3D3_Release(d3d); - IDirect3DDevice3_Release(device); DestroyWindow(window); } diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index 3ad44991863..bdec30621e3 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -6379,23 +6379,31 @@ static void test_surface_discard(void) unsigned int i; window = create_window(); - if (!(device = create_device(window, DDSCL_NORMAL))) - { - skip("Failed to create a 3D device, skipping test.\n"); - DestroyWindow(window); - return; - } - hr = IDirect3DDevice7_GetDirect3D(device, &d3d); - ok(SUCCEEDED(hr), "Failed to get d3d interface, hr %#x.\n", hr); - hr = IDirect3D7_QueryInterface(d3d, &IID_IDirectDraw7, (void **)&ddraw); - ok(SUCCEEDED(hr), "Failed to get ddraw interface, hr %#x.\n", hr); - hr = IDirect3DDevice7_GetRenderTarget(device, &target); - ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr); for (i = 0; i < ARRAY_SIZE(tests); ++i) { BOOL discarded; + /* Sigh. Anything other than the first run of the loop randomly fails with + * DDERR_SURFACELOST on my Radeon Pro 560 on Win10 19.09. Most of the time + * the blit fails, but with sleeps added between surface creation and lock + * the lock can fail too. Interestingly ddraw claims the render target has + * been lost, not the test surface. + * + * Recreating ddraw every iteration seems to fix this. */ + if (!(device = create_device(window, DDSCL_NORMAL))) + { + skip("Failed to create a 3D device, skipping test.\n"); + DestroyWindow(window); + return; + } + hr = IDirect3DDevice7_GetDirect3D(device, &d3d); + ok(SUCCEEDED(hr), "Failed to get d3d interface, hr %#x.\n", hr); + hr = IDirect3D7_QueryInterface(d3d, &IID_IDirectDraw7, (void **)&ddraw); + ok(SUCCEEDED(hr), "Failed to get ddraw interface, hr %#x.\n", hr); + hr = IDirect3DDevice7_GetRenderTarget(device, &target); + ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr); + memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; @@ -6438,12 +6446,13 @@ static void test_surface_discard(void) /* Windows 7 reliably changes the address of surfaces that are discardable (Nvidia Kepler, * AMD r500, evergreen). Windows XP, at least on AMD r200, does not. */ ok(!discarded || tests[i].discard, "Expected surface not to be discarded, case %u\n", i); + + IDirectDrawSurface7_Release(target); + IDirectDraw7_Release(ddraw); + IDirect3D7_Release(d3d); + IDirect3DDevice7_Release(device); } - IDirectDrawSurface7_Release(target); - IDirectDraw7_Release(ddraw); - IDirect3D7_Release(d3d); - IDirect3DDevice7_Release(device); DestroyWindow(window); }