Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55773
-- v3: wined3d: Store the resource heap memory pointer separately. wined3d: Add more padding to resource memory allocations.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/wined3d/resource.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c index 9d3fd0a426d..5351fbd3025 100644 --- a/dlls/wined3d/resource.c +++ b/dlls/wined3d/resource.c @@ -332,7 +332,11 @@ void CDECL wined3d_resource_preload(struct wined3d_resource *resource) static BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) { void **p; - SIZE_T align = RESOURCE_ALIGNMENT - 1 + sizeof(*p); + /* Overallocate and add padding to the allocated pointer, to guard against + * games (for instance Railroad Tycoon 2) writing before the locked resource + * memory pointer. + */ + SIZE_T align = RESOURCE_ALIGNMENT + sizeof(*p); void *mem;
if (!(mem = heap_alloc_zero(resource->size + align)))
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55773 --- dlls/wined3d/resource.c | 19 ++++++++----------- dlls/wined3d/wined3d_private.h | 1 + 2 files changed, 9 insertions(+), 11 deletions(-)
diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c index 5351fbd3025..9f27a9100e6 100644 --- a/dlls/wined3d/resource.c +++ b/dlls/wined3d/resource.c @@ -208,6 +208,7 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * resource->parent_ops = parent_ops; resource->resource_ops = resource_ops; resource->map_binding = WINED3D_LOCATION_SYSMEM; + resource->heap_pointer = NULL; resource->heap_memory = NULL;
/* Check that we have enough video ram left */ @@ -331,12 +332,11 @@ void CDECL wined3d_resource_preload(struct wined3d_resource *resource)
static BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) { - void **p; /* Overallocate and add padding to the allocated pointer, to guard against * games (for instance Railroad Tycoon 2) writing before the locked resource * memory pointer. */ - SIZE_T align = RESOURCE_ALIGNMENT + sizeof(*p); + static const SIZE_T align = RESOURCE_ALIGNMENT; void *mem;
if (!(mem = heap_alloc_zero(resource->size + align))) @@ -345,10 +345,8 @@ static BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) return FALSE; }
- p = (void **)(((ULONG_PTR)mem + align) & ~(RESOURCE_ALIGNMENT - 1)) - 1; - *p = mem; - - resource->heap_memory = ++p; + resource->heap_memory = (void *)(((ULONG_PTR)mem + align) & ~(RESOURCE_ALIGNMENT - 1)); + resource->heap_pointer = mem;
return TRUE; } @@ -363,13 +361,12 @@ BOOL wined3d_resource_prepare_sysmem(struct wined3d_resource *resource)
void wined3d_resource_free_sysmem(struct wined3d_resource *resource) { - void **p = resource->heap_memory; - - if (!p) + if (!resource->heap_memory) return; - - heap_free(*(--p)); resource->heap_memory = NULL; + + heap_free(resource->heap_pointer); + resource->heap_pointer = NULL; }
GLbitfield wined3d_resource_gl_storage_flags(const struct wined3d_resource *resource) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index c17e29cddf2..238456e78d8 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3199,6 +3199,7 @@ struct wined3d_resource UINT depth; UINT size; unsigned int priority; + void *heap_pointer; void *heap_memory;
uint32_t pin_sysmem : 1;
I changed it to overallocate and store the pointer separately. Heap pointers are always aligned to 2 * sizeof(void *), so after the 16 byte alignment, this always ends up with either 8 or 16 bytes of padding on 32-bit (and always 16 bytes on 64-bit).