From: Stefan Dösinger stefan@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=54701
---
The private draw texture did not get evicted on reset(), causing us to try to read from a non-existent texture with the new contest. For more details see comment 9 on the bug. --- dlls/d3d8/d3d8_private.h | 2 +- dlls/d3d8/directx.c | 8 ++++---- dlls/d3d9/buffer.c | 6 ++++++ dlls/d3d9/device.c | 3 +++ dlls/d3d9/directx.c | 4 +--- dlls/d3d9/texture.c | 9 +++++++++ dlls/ddraw/ddraw_private.h | 7 +++---- dlls/ddraw/surface.c | 4 ++-- dlls/ddraw/vertexbuffer.c | 2 +- dlls/wined3d/resource.c | 33 ++++++++++++++------------------- dlls/wined3d/texture.c | 5 ++--- dlls/wined3d/utils.c | 1 + include/wine/wined3d.h | 26 +++++++++++++------------- 13 files changed, 60 insertions(+), 50 deletions(-)
diff --git a/dlls/d3d8/d3d8_private.h b/dlls/d3d8/d3d8_private.h index dda85062dea..1471ef97708 100644 --- a/dlls/d3d8/d3d8_private.h +++ b/dlls/d3d8/d3d8_private.h @@ -371,7 +371,7 @@ static inline unsigned int wined3d_usage_from_d3d(D3DPOOL pool, DWORD usage) usage |= WINED3DUSAGE_SCRATCH; else if (pool == D3DPOOL_MANAGED) usage |= WINED3DUSAGE_MANAGED; - return usage; + return usage | WINED3DUSAGE_VIDMEM_ACCOUNTING; }
static inline unsigned int wined3d_bind_flags_from_d3d8_usage(DWORD usage) diff --git a/dlls/d3d8/directx.c b/dlls/d3d8/directx.c index 973c7fea779..b35abc6b699 100644 --- a/dlls/d3d8/directx.c +++ b/dlls/d3d8/directx.c @@ -473,10 +473,10 @@ static const struct IDirect3D8Vtbl d3d8_vtbl =
BOOL d3d8_init(struct d3d8 *d3d8) { - DWORD flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING - | WINED3D_HANDLE_RESTORE | WINED3D_PIXEL_CENTER_INTEGER - | WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR | WINED3D_NO_PRIMITIVE_RESTART - | WINED3D_LEGACY_CUBEMAP_FILTERING | WINED3D_NO_DRAW_INDIRECT; + DWORD flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_HANDLE_RESTORE + | WINED3D_PIXEL_CENTER_INTEGER | WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR + | WINED3D_NO_PRIMITIVE_RESTART | WINED3D_LEGACY_CUBEMAP_FILTERING + | WINED3D_NO_DRAW_INDIRECT; unsigned int adapter_idx, output_idx, adapter_count, output_count = 0; struct wined3d_adapter *wined3d_adapter;
diff --git a/dlls/d3d9/buffer.c b/dlls/d3d9/buffer.c index 511dafe5f9c..822b2c00df3 100644 --- a/dlls/d3d9/buffer.c +++ b/dlls/d3d9/buffer.c @@ -312,6 +312,9 @@ HRESULT vertexbuffer_init(struct d3d9_vertexbuffer *buffer, struct d3d9_device * desc.misc_flags = 0; desc.structure_byte_stride = 0;
+ if (!device->d3d_parent->extended) + desc.usage |= WINED3DUSAGE_VIDMEM_ACCOUNTING; + if (desc.access & WINED3D_RESOURCE_ACCESS_GPU) { desc.bind_flags = WINED3D_BIND_VERTEX_BUFFER; @@ -620,6 +623,9 @@ HRESULT indexbuffer_init(struct d3d9_indexbuffer *buffer, struct d3d9_device *de desc.misc_flags = 0; desc.structure_byte_stride = 0;
+ if (!device->d3d_parent->extended) + desc.usage |= WINED3DUSAGE_VIDMEM_ACCOUNTING; + if (desc.access & WINED3D_RESOURCE_ACCESS_GPU) desc.bind_flags = WINED3D_BIND_INDEX_BUFFER;
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index bb3e0b8e6d4..c6083d351e3 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -1986,6 +1986,9 @@ static HRESULT WINAPI d3d9_device_CreateOffscreenPlainSurface(IDirect3DDevice9Ex access = wined3daccess_from_d3dpool(pool, 0) | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
+ if (!device->d3d_parent->extended) + usage |= WINED3DUSAGE_VIDMEM_ACCOUNTING; + return d3d9_device_create_surface(device, 0, wined3dformat_from_d3dformat(format), WINED3D_MULTISAMPLE_NONE, 0, usage, 0, access, width, height, user_mem, surface); } diff --git a/dlls/d3d9/directx.c b/dlls/d3d9/directx.c index 64291c586bb..3dc7ff6da53 100644 --- a/dlls/d3d9/directx.c +++ b/dlls/d3d9/directx.c @@ -689,9 +689,7 @@ BOOL d3d9_init(struct d3d9 *d3d9, BOOL extended) unsigned int adapter_idx, output_idx, adapter_count, output_count = 0; struct wined3d_adapter *wined3d_adapter;
- if (!extended) - flags |= WINED3D_VIDMEM_ACCOUNTING; - else + if (extended) flags |= WINED3D_RESTORE_MODE_ON_ACTIVATE;
d3d9->IDirect3D9Ex_iface.lpVtbl = &d3d9_vtbl; diff --git a/dlls/d3d9/texture.c b/dlls/d3d9/texture.c index 0a27941ac2b..3adfaaee2f3 100644 --- a/dlls/d3d9/texture.c +++ b/dlls/d3d9/texture.c @@ -1409,6 +1409,9 @@ HRESULT d3d9_texture_2d_init(struct d3d9_texture *texture, struct d3d9_device *d desc.depth = 1; desc.size = 0;
+ if (!device->d3d_parent->extended) + desc.usage |= WINED3DUSAGE_VIDMEM_ACCOUNTING; + texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_2d_vtbl; return d3d9_texture_init(texture, device, &desc, pool, usage, 1, level_count); } @@ -1430,6 +1433,9 @@ HRESULT d3d9_texture_cube_init(struct d3d9_texture *texture, struct d3d9_device desc.depth = 1; desc.size = 0;
+ if (!device->d3d_parent->extended) + desc.usage |= WINED3DUSAGE_VIDMEM_ACCOUNTING; + texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl; return d3d9_texture_init(texture, device, &desc, pool, usage, 6, level_count); } @@ -1455,6 +1461,9 @@ HRESULT d3d9_texture_3d_init(struct d3d9_texture *texture, struct d3d9_device *d desc.depth = depth; desc.size = 0;
+ if (!device->d3d_parent->extended) + desc.usage |= WINED3DUSAGE_VIDMEM_ACCOUNTING; + texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl; return d3d9_texture_init(texture, device, &desc, pool, usage, 1, level_count); } diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index e3fac63a38f..f49ac361036 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -63,10 +63,9 @@ struct FvfToDecl
#define DDRAW_STRIDE_ALIGNMENT 8
-#define DDRAW_WINED3D_FLAGS (WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING \ - | WINED3D_RESTORE_MODE_ON_ACTIVATE | WINED3D_FOCUS_MESSAGES | WINED3D_PIXEL_CENTER_INTEGER \ - | WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR | WINED3D_NO_PRIMITIVE_RESTART \ - | WINED3D_LEGACY_CUBEMAP_FILTERING | WINED3D_NO_DRAW_INDIRECT) +#define DDRAW_WINED3D_FLAGS (WINED3D_LEGACY_DEPTH_BIAS | WINED3D_RESTORE_MODE_ON_ACTIVATE \ + | WINED3D_FOCUS_MESSAGES | WINED3D_PIXEL_CENTER_INTEGER | WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR \ + | WINED3D_NO_PRIMITIVE_RESTART | WINED3D_LEGACY_CUBEMAP_FILTERING | WINED3D_NO_DRAW_INDIRECT)
#define DDRAW_MAX_ACTIVE_LIGHTS 32 #define DDRAW_MAX_TEXTURES 8 diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index 4d8812cf106..8a55844d5f7 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -5987,7 +5987,7 @@ static void wined3d_resource_desc_from_ddraw(struct ddraw *ddraw, wined3d_desc->format = wined3dformat_from_ddrawformat(&desc->u4.ddpfPixelFormat); wined3d_desc->multisample_type = WINED3D_MULTISAMPLE_NONE; wined3d_desc->multisample_quality = 0; - wined3d_desc->usage = 0; + wined3d_desc->usage = WINED3DUSAGE_VIDMEM_ACCOUNTING; wined3d_desc->bind_flags = 0; wined3d_desc->access = WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; wined3d_desc->width = desc->dwWidth; @@ -6114,7 +6114,7 @@ static HRESULT ddraw_texture_init(struct ddraw_texture *texture, struct ddraw *d draw_texture_desc = wined3d_desc; draw_texture_desc.bind_flags = bind_flags; draw_texture_desc.access = WINED3D_RESOURCE_ACCESS_GPU; - draw_texture_desc.usage = WINED3DUSAGE_PRIVATE; + draw_texture_desc.usage = 0;
if (SUCCEEDED(hr = wined3d_texture_create(wined3d_device, &draw_texture_desc, layers, levels, 0, NULL, texture, &ddraw_texture_wined3d_parent_ops, &draw_texture))) diff --git a/dlls/ddraw/vertexbuffer.c b/dlls/ddraw/vertexbuffer.c index 56a4c3e93e4..6bd9c7a9893 100644 --- a/dlls/ddraw/vertexbuffer.c +++ b/dlls/ddraw/vertexbuffer.c @@ -111,7 +111,7 @@ static HRESULT d3d_vertex_buffer_create_wined3d_buffer(struct d3d_vertex_buffer struct wined3d_buffer_desc desc;
desc.byte_width = buffer->size; - desc.usage = WINED3DUSAGE_STATICDECL; + desc.usage = WINED3DUSAGE_STATICDECL | WINED3DUSAGE_VIDMEM_ACCOUNTING; if (dynamic) desc.usage |= WINED3DUSAGE_DYNAMIC; desc.bind_flags = WINED3D_BIND_VERTEX_BUFFER; diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c index e2100627198..7df4fb2ba0a 100644 --- a/dlls/wined3d/resource.c +++ b/dlls/wined3d/resource.c @@ -210,21 +210,19 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * resource->map_binding = WINED3D_LOCATION_SYSMEM; resource->heap_memory = NULL;
- if (!(usage & WINED3DUSAGE_PRIVATE)) + /* Check that we have enough video ram left */ + if (!(access & WINED3D_RESOURCE_ACCESS_CPU) && usage & WINED3DUSAGE_VIDMEM_ACCOUNTING) { - /* Check that we have enough video ram left */ - if (!(access & WINED3D_RESOURCE_ACCESS_CPU) && device->wined3d->flags & WINED3D_VIDMEM_ACCOUNTING) + if (size > wined3d_device_get_available_texture_mem(device)) { - if (size > wined3d_device_get_available_texture_mem(device)) - { - ERR("Out of adapter memory.\n"); - return WINED3DERR_OUTOFVIDEOMEMORY; - } - adapter_adjust_memory(device->adapter, size); + ERR("Out of adapter memory.\n"); + return WINED3DERR_OUTOFVIDEOMEMORY; } + adapter_adjust_memory(device->adapter, size); + }
+ if (!(usage & WINED3DUSAGE_PRIVATE)) device_resource_add(device, resource); - }
return WINED3D_OK; } @@ -241,20 +239,17 @@ static void wined3d_resource_destroy_object(void *object)
void resource_cleanup(struct wined3d_resource *resource) { - const struct wined3d *d3d = resource->device->wined3d; - TRACE("Cleaning up resource %p.\n", resource);
- if (!(resource->usage & WINED3DUSAGE_PRIVATE)) + if (!(resource->access & WINED3D_RESOURCE_ACCESS_CPU) && resource->usage & WINED3DUSAGE_VIDMEM_ACCOUNTING) { - if (!(resource->access & WINED3D_RESOURCE_ACCESS_CPU) && d3d->flags & WINED3D_VIDMEM_ACCOUNTING) - { - TRACE("Decrementing device memory pool by %u.\n", resource->size); - adapter_adjust_memory(resource->device->adapter, (INT64)0 - resource->size); - } + TRACE("Decrementing device memory pool by %u.\n", resource->size); + adapter_adjust_memory(resource->device->adapter, (INT64)0 - resource->size); + }
+ if (!(resource->usage & WINED3DUSAGE_PRIVATE)) device_resource_released(resource->device, resource); - } + wined3d_resource_reference(resource); wined3d_cs_destroy_object(resource->device->cs, wined3d_resource_destroy_object, resource); } diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 33b938ad460..9a4d593b97f 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -1899,7 +1899,6 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, unsig const struct wined3d_format *format; struct wined3d_device *device; unsigned int resource_size; - const struct wined3d *d3d; unsigned int slice_pitch; bool update_memory_only; bool create_dib = false; @@ -1910,7 +1909,6 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, unsig sub_resource_idx);
device = texture->resource.device; - d3d = device->wined3d; gl_info = &device->adapter->gl_info; d3d_info = &device->adapter->d3d_info; format = wined3d_get_format(device->adapter, format_id, texture->resource.bind_flags); @@ -2008,7 +2006,8 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, unsig texture->resource.multisample_quality = multisample_quality; texture->resource.width = width; texture->resource.height = height; - if (!(texture->resource.access & WINED3D_RESOURCE_ACCESS_CPU) && d3d->flags & WINED3D_VIDMEM_ACCOUNTING) + if (!(texture->resource.access & WINED3D_RESOURCE_ACCESS_CPU) + && texture->resource.usage & WINED3DUSAGE_VIDMEM_ACCOUNTING) adapter_adjust_memory(device->adapter, (INT64)texture->slice_pitch - texture->resource.size); texture->resource.size = texture->slice_pitch; sub_resource->size = texture->slice_pitch; diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index aff2b00e08d..e34be2996b1 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -4952,6 +4952,7 @@ const char *debug_d3dusage(uint32_t usage) WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL); WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY); WINED3DUSAGE_TO_STR(WINED3DUSAGE_MANAGED); + WINED3DUSAGE_TO_STR(WINED3DUSAGE_VIDMEM_ACCOUNTING); WINED3DUSAGE_TO_STR(WINED3DUSAGE_QUERY_FILTER); WINED3DUSAGE_TO_STR(WINED3DUSAGE_QUERY_GENMIPMAP); WINED3DUSAGE_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP); diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 5d8a1156b21..7c7d2ba3bdd 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -927,6 +927,7 @@ enum wined3d_memory_segment_group #define WINED3DUSAGE_STATICDECL 0x04000000 #define WINED3DUSAGE_OVERLAY 0x08000000 #define WINED3DUSAGE_MANAGED 0x20000000 +#define WINED3DUSAGE_VIDMEM_ACCOUNTING 0x40000000
#define WINED3DUSAGE_QUERY_GENMIPMAP 0x00000400 #define WINED3DUSAGE_QUERY_LEGACYBUMPMAP 0x00008000 @@ -1311,19 +1312,18 @@ enum wined3d_memory_segment_group
#define WINED3D_LEGACY_DEPTH_BIAS 0x00000001 #define WINED3D_NO3D 0x00000002 -#define WINED3D_VIDMEM_ACCOUNTING 0x00000004 -#define WINED3D_PRESENT_CONVERSION 0x00000008 -#define WINED3D_RESTORE_MODE_ON_ACTIVATE 0x00000010 -#define WINED3D_FOCUS_MESSAGES 0x00000020 -#define WINED3D_HANDLE_RESTORE 0x00000040 -#define WINED3D_PIXEL_CENTER_INTEGER 0x00000080 -#define WINED3D_LEGACY_FFP_LIGHTING 0x00000100 -#define WINED3D_SRGB_READ_WRITE_CONTROL 0x00000200 -#define WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR 0x00000400 -#define WINED3D_NO_PRIMITIVE_RESTART 0x00000800 -#define WINED3D_LEGACY_CUBEMAP_FILTERING 0x00001000 -#define WINED3D_NORMALIZED_DEPTH_BIAS 0x00002000 -#define WINED3D_NO_DRAW_INDIRECT 0x00004000 +#define WINED3D_PRESENT_CONVERSION 0x00000004 +#define WINED3D_RESTORE_MODE_ON_ACTIVATE 0x00000008 +#define WINED3D_FOCUS_MESSAGES 0x00000010 +#define WINED3D_HANDLE_RESTORE 0x00000020 +#define WINED3D_PIXEL_CENTER_INTEGER 0x00000040 +#define WINED3D_LEGACY_FFP_LIGHTING 0x00000080 +#define WINED3D_SRGB_READ_WRITE_CONTROL 0x00000100 +#define WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR 0x00000200 +#define WINED3D_NO_PRIMITIVE_RESTART 0x00000400 +#define WINED3D_LEGACY_CUBEMAP_FILTERING 0x00000800 +#define WINED3D_NORMALIZED_DEPTH_BIAS 0x00001000 +#define WINED3D_NO_DRAW_INDIRECT 0x00002000
#define WINED3D_RESZ_CODE 0x7fa05000