ddraw: Check surface flags when marking surface as lost.
Fixes a regression triggered by 530a3d94de
.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48923
Signed-off-by: Paul Gofman <pgofman@codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
e1a79d4d7c
commit
3acc26dc22
|
@ -4899,7 +4899,7 @@ void ddraw_update_lost_surfaces(struct ddraw *ddraw)
|
|||
|
||||
LIST_FOR_EACH_ENTRY(surface, &ddraw->surface_list, struct ddraw_surface, surface_list_entry)
|
||||
{
|
||||
surface->is_lost = TRUE;
|
||||
surface->is_lost = ddraw_surface_can_be_lost(surface);
|
||||
}
|
||||
ddraw->device_state = DDRAW_DEVICE_STATE_OK;
|
||||
}
|
||||
|
|
|
@ -197,6 +197,7 @@ struct ddraw_surface
|
|||
*/
|
||||
unsigned int is_complex_root : 1;
|
||||
unsigned int is_lost : 1;
|
||||
unsigned int sysmem_fallback : 1;
|
||||
|
||||
/* Surface description, for GetAttachedSurface */
|
||||
DDSURFACEDESC2 surface_desc;
|
||||
|
@ -637,6 +638,19 @@ static inline BOOL format_is_paletteindexed(const DDPIXELFORMAT *fmt)
|
|||
return !!(fmt->dwFlags & flags);
|
||||
}
|
||||
|
||||
static inline BOOL ddraw_surface_can_be_lost(const struct ddraw_surface *surface)
|
||||
{
|
||||
DWORD caps = surface->surface_desc.ddsCaps.dwCaps;
|
||||
|
||||
/* Testing with DDCREATE_EMULATIONONLY showed that primary surfaces and Z buffers can
|
||||
* be lost even if created with explicit DDCAPS_SYSTEMMEMORY. Textures can or cannot be lost
|
||||
* depending on whether _SYSTEMMEMORY was given explicitly by the application. */
|
||||
if (!(caps & DDSCAPS_SYSTEMMEMORY) || caps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_ZBUFFER))
|
||||
return TRUE;
|
||||
|
||||
return surface->sysmem_fallback;
|
||||
}
|
||||
|
||||
/* Used for generic dumping */
|
||||
struct flag_info
|
||||
{
|
||||
|
|
|
@ -35,7 +35,8 @@ static inline struct ddraw_surface *impl_from_IDirectDrawGammaControl(IDirectDra
|
|||
|
||||
static BOOL ddraw_surface_is_lost(const struct ddraw_surface *surface)
|
||||
{
|
||||
return surface->ddraw->device_state != DDRAW_DEVICE_STATE_OK || surface->is_lost;
|
||||
return ddraw_surface_can_be_lost(surface)
|
||||
&& (surface->ddraw->device_state != DDRAW_DEVICE_STATE_OK || surface->is_lost);
|
||||
}
|
||||
|
||||
/* This is slow, of course. Also, in case of locks, we can't prevent other
|
||||
|
@ -5891,6 +5892,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
|
|||
struct wined3d_display_mode mode;
|
||||
DDSURFACEDESC2 *desc, *mip_desc;
|
||||
struct ddraw_texture *texture;
|
||||
BOOL sysmem_fallback = FALSE;
|
||||
unsigned int layers = 1;
|
||||
unsigned int pitch = 0;
|
||||
BOOL reserve_memory;
|
||||
|
@ -6213,9 +6215,14 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
|
|||
if (!(ddraw->flags & DDRAW_NO3D) && SUCCEEDED(hr = wined3d_check_device_format(ddraw->wined3d,
|
||||
ddraw->wined3d_adapter, WINED3D_DEVICE_TYPE_HAL, mode.format_id,
|
||||
usage, bind_flags, WINED3D_RTYPE_TEXTURE_2D, wined3d_desc.format)))
|
||||
{
|
||||
desc->ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
desc->ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
|
||||
sysmem_fallback = TRUE;
|
||||
}
|
||||
}
|
||||
else if (!(desc->ddsCaps.dwCaps & DDSCAPS_TEXTURE))
|
||||
{
|
||||
|
@ -6389,6 +6396,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
|
|||
root = wined3d_texture_get_sub_resource_parent(wined3d_texture, 0);
|
||||
wined3d_texture_decref(wined3d_texture);
|
||||
root->is_complex_root = TRUE;
|
||||
root->sysmem_fallback = sysmem_fallback;
|
||||
texture->root = root;
|
||||
wined3d_device_incref(texture->wined3d_device = ddraw->wined3d_device);
|
||||
|
||||
|
@ -6412,6 +6420,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
|
|||
for (j = 0; j < levels; ++j)
|
||||
{
|
||||
mip = wined3d_texture_get_sub_resource_parent(wined3d_texture, i * levels + j);
|
||||
mip->sysmem_fallback = sysmem_fallback;
|
||||
mip_desc = &mip->surface_desc;
|
||||
if (desc->ddsCaps.dwCaps & DDSCAPS_MIPMAP)
|
||||
mip_desc->u2.dwMipMapCount = levels - j;
|
||||
|
@ -6520,6 +6529,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
|
|||
}
|
||||
|
||||
last = wined3d_texture_get_sub_resource_parent(wined3d_texture, 0);
|
||||
last->sysmem_fallback = sysmem_fallback;
|
||||
wined3d_texture_decref(wined3d_texture);
|
||||
texture->root = last;
|
||||
wined3d_device_incref(texture->wined3d_device = ddraw->wined3d_device);
|
||||
|
|
|
@ -9269,6 +9269,7 @@ static void test_vb_writeonly(void)
|
|||
static void test_lost_device(void)
|
||||
{
|
||||
IDirectDrawSurface7 *surface, *back_buffer;
|
||||
IDirectDrawSurface7 *sysmem_surface;
|
||||
DDSURFACEDESC2 surface_desc;
|
||||
HWND window1, window2;
|
||||
IDirectDraw7 *ddraw;
|
||||
|
@ -9284,7 +9285,7 @@ static void test_lost_device(void)
|
|||
ddraw = create_ddraw();
|
||||
ok(!!ddraw, "Failed to create a ddraw object.\n");
|
||||
hr = IDirectDraw7_SetCooperativeLevel(ddraw, window1, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
|
||||
ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
memset(&surface_desc, 0, sizeof(surface_desc));
|
||||
surface_desc.dwSize = sizeof(surface_desc);
|
||||
|
@ -9292,7 +9293,16 @@ static void test_lost_device(void)
|
|||
surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
|
||||
U5(surface_desc).dwBackBufferCount = 1;
|
||||
hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL);
|
||||
ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\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_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
|
||||
surface_desc.dwWidth = 100;
|
||||
surface_desc.dwHeight = 100;
|
||||
hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &sysmem_surface, NULL);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDraw7_TestCooperativeLevel(ddraw);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
@ -9300,6 +9310,8 @@ static void test_lost_device(void)
|
|||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_IsLost(sysmem_surface);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
ret = SetForegroundWindow(GetDesktopWindow());
|
||||
ok(ret, "Failed to set foreground window.\n");
|
||||
|
@ -9309,6 +9321,8 @@ static void test_lost_device(void)
|
|||
ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT);
|
||||
ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_IsLost(sysmem_surface);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
ret = SetForegroundWindow(window1);
|
||||
ok(ret, "Failed to set foreground window.\n");
|
||||
|
@ -9318,6 +9332,8 @@ static void test_lost_device(void)
|
|||
ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT);
|
||||
ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_IsLost(sysmem_surface);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDraw7_RestoreAllSurfaces(ddraw);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
@ -9327,6 +9343,8 @@ static void test_lost_device(void)
|
|||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_IsLost(sysmem_surface);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDraw7_SetCooperativeLevel(ddraw, window1, DDSCL_NORMAL);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
@ -9336,6 +9354,8 @@ static void test_lost_device(void)
|
|||
todo_wine ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT);
|
||||
todo_wine ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_IsLost(sysmem_surface);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
/* Trying to restore the primary will crash, probably because flippable
|
||||
* surfaces can't exist in DDSCL_NORMAL. */
|
||||
|
@ -9345,12 +9365,16 @@ static void test_lost_device(void)
|
|||
surface_desc.dwFlags = DDSD_CAPS;
|
||||
surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
|
||||
hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL);
|
||||
ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_IsLost(sysmem_surface);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDraw7_TestCooperativeLevel(ddraw);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_IsLost(surface);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_IsLost(sysmem_surface);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
ret = SetForegroundWindow(GetDesktopWindow());
|
||||
ok(ret, "Failed to set foreground window.\n");
|
||||
|
@ -9358,6 +9382,8 @@ static void test_lost_device(void)
|
|||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_IsLost(surface);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_IsLost(sysmem_surface);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
ret = SetForegroundWindow(window1);
|
||||
ok(ret, "Failed to set foreground window.\n");
|
||||
|
@ -9365,6 +9391,8 @@ static void test_lost_device(void)
|
|||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_IsLost(surface);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_IsLost(sysmem_surface);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDraw7_SetCooperativeLevel(ddraw, window1, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
@ -9372,6 +9400,8 @@ static void test_lost_device(void)
|
|||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_IsLost(surface);
|
||||
ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_IsLost(sysmem_surface);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDraw7_RestoreAllSurfaces(ddraw);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
@ -9379,6 +9409,8 @@ static void test_lost_device(void)
|
|||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_IsLost(surface);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_IsLost(sysmem_surface);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
IDirectDrawSurface7_Release(surface);
|
||||
memset(&surface_desc, 0, sizeof(surface_desc));
|
||||
|
@ -9387,7 +9419,7 @@ static void test_lost_device(void)
|
|||
surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
|
||||
U5(surface_desc).dwBackBufferCount = 1;
|
||||
hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL);
|
||||
ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDraw7_SetCooperativeLevel(ddraw, window1, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
@ -9397,6 +9429,8 @@ static void test_lost_device(void)
|
|||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_IsLost(sysmem_surface);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDraw7_SetCooperativeLevel(ddraw, window1, DDSCL_NORMAL | DDSCL_FULLSCREEN);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
@ -9406,6 +9440,8 @@ static void test_lost_device(void)
|
|||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT);
|
||||
ok(hr == DDERR_NOEXCLUSIVEMODE, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_IsLost(sysmem_surface);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDraw7_SetCooperativeLevel(ddraw, window1, DDSCL_NORMAL);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
@ -9415,6 +9451,8 @@ static void test_lost_device(void)
|
|||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT);
|
||||
ok(hr == DDERR_NOEXCLUSIVEMODE, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_IsLost(sysmem_surface);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDraw7_SetCooperativeLevel(ddraw, window2, DDSCL_NORMAL);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
@ -9424,6 +9462,8 @@ static void test_lost_device(void)
|
|||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT);
|
||||
ok(hr == DDERR_NOEXCLUSIVEMODE, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_IsLost(sysmem_surface);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDraw7_SetCooperativeLevel(ddraw, window2, DDSCL_NORMAL | DDSCL_FULLSCREEN);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
@ -9433,6 +9473,8 @@ static void test_lost_device(void)
|
|||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT);
|
||||
ok(hr == DDERR_NOEXCLUSIVEMODE, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_IsLost(sysmem_surface);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDraw7_SetCooperativeLevel(ddraw, window2, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
@ -9442,6 +9484,8 @@ static void test_lost_device(void)
|
|||
ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT);
|
||||
ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_IsLost(sysmem_surface);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
memset(&caps, 0, sizeof(caps));
|
||||
caps.dwCaps = DDSCAPS_FLIP;
|
||||
|
@ -9454,8 +9498,10 @@ static void test_lost_device(void)
|
|||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface7_IsLost(back_buffer);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
IDirectDrawSurface7_Release(back_buffer);
|
||||
|
||||
IDirectDrawSurface7_Release(sysmem_surface);
|
||||
IDirectDrawSurface7_Release(surface);
|
||||
refcount = IDirectDraw7_Release(ddraw);
|
||||
ok(!refcount, "Got unexpected refcount %u.\n", refcount);
|
||||
|
|
Loading…
Reference in New Issue