diff options
Diffstat (limited to '0007-wined3d-Avoid-freeing-persistent-buffer-heap-element.patch')
-rw-r--r-- | 0007-wined3d-Avoid-freeing-persistent-buffer-heap-element.patch | 351 |
1 files changed, 0 insertions, 351 deletions
diff --git a/0007-wined3d-Avoid-freeing-persistent-buffer-heap-element.patch b/0007-wined3d-Avoid-freeing-persistent-buffer-heap-element.patch deleted file mode 100644 index d0872df82707..000000000000 --- a/0007-wined3d-Avoid-freeing-persistent-buffer-heap-element.patch +++ /dev/null @@ -1,351 +0,0 @@ -From fc7907d5264c1606477f9287c949c3c8794859ec Mon Sep 17 00:00:00 2001 -From: Andrew Comminos <andrew@comminos.com> -Date: Thu, 8 Mar 2018 23:01:50 -0800 -Subject: [PATCH 7/9] wined3d: Avoid freeing persistent buffer heap elements - during use. - -Using HeapFree is expensive, especially when we don't have our buffers -for long. ---- - dlls/wined3d/buffer.c | 29 +++++++++++---------- - dlls/wined3d/buffer_heap.c | 57 ++++++++++++++++++------------------------ - dlls/wined3d/context.c | 4 +-- - dlls/wined3d/cs.c | 6 ++--- - dlls/wined3d/wined3d_private.h | 25 ++++++++++++------ - 5 files changed, 61 insertions(+), 60 deletions(-) - -diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c -index c492fcc8c6..74b3ba8abd 100644 ---- a/dlls/wined3d/buffer.c -+++ b/dlls/wined3d/buffer.c -@@ -276,7 +276,7 @@ static BOOL buffer_alloc_persistent_map(struct wined3d_buffer *buffer) - { - struct wined3d_device *device = buffer->resource.device; - struct wined3d_buffer_heap *heap; -- struct wined3d_map_range map_range; -+ struct wined3d_buffer_heap_element *elem; - HRESULT hr; - - if (buffer->bind_flags & WINED3D_BIND_CONSTANT_BUFFER) -@@ -292,12 +292,12 @@ static BOOL buffer_alloc_persistent_map(struct wined3d_buffer *buffer) - } - - buffer->buffer_heap = heap; -- if (FAILED(hr = wined3d_buffer_heap_alloc(heap, buffer->resource.size, &map_range))) -+ if (FAILED(hr = wined3d_buffer_heap_alloc(heap, buffer->resource.size, &elem))) - { - goto fail; - } -- buffer->cs_persistent_map = map_range; -- buffer->mt_persistent_map = map_range; -+ buffer->cs_persistent_map = elem; -+ buffer->mt_persistent_map = elem; - return TRUE; - - fail: -@@ -753,7 +753,7 @@ BOOL wined3d_buffer_load_location(struct wined3d_buffer *buffer, - if (buffer->conversion_map) - FIXME("Attempting to use conversion map with persistent mapping.\n"); - memcpy(buffer->buffer_heap->map_ptr + -- buffer->cs_persistent_map.offset, -+ buffer->cs_persistent_map->range.offset, - buffer->resource.heap_memory, buffer->resource.size); - break; - -@@ -801,11 +801,11 @@ DWORD wined3d_buffer_get_memory(struct wined3d_buffer *buffer, - { - // FIXME(acomminos): should we expose a buffer object we don't wholly own here? - data->buffer_object = buffer->buffer_heap->buffer_object; -- data->addr = buffer->cs_persistent_map.offset; -+ data->addr = buffer->cs_persistent_map->range.offset; - // Note that the size of the underlying buffer allocation may be larger - // than the buffer knows about. In this case, we've rounded it up to be - // aligned (e.g. for uniform buffer offsets). -- data->length = buffer->cs_persistent_map.size; -+ data->length = buffer->cs_persistent_map->range.size; - return WINED3D_LOCATION_PERSISTENT_MAP; - } - if (locations & WINED3D_LOCATION_SYSMEM) -@@ -1122,7 +1122,7 @@ static HRESULT wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UI - gl_info->gl_ops.gl.p_glFinish(); - - base = buffer->buffer_heap->map_ptr -- + buffer->cs_persistent_map.offset; -+ + buffer->cs_persistent_map->range.offset; - *data = base + offset; - - context_release(context); -@@ -1412,22 +1412,21 @@ static HRESULT buffer_resource_sub_resource_map(struct wined3d_resource *resourc - if (flags & WINED3D_MAP_DISCARD) - { - HRESULT hr; -- struct wined3d_map_range map_range; -- if (FAILED(hr = wined3d_buffer_heap_alloc(buffer->buffer_heap, resource->size, &map_range))) -+ struct wined3d_buffer_heap_element *mt_elem; -+ if (FAILED(hr = wined3d_buffer_heap_alloc(buffer->buffer_heap, resource->size, &mt_elem))) - { - FIXME_(d3d_perf)("Failed to allocate new buffer, falling back to sync path.\n"); - return hr; - } -- map_desc->data = buffer->buffer_heap->map_ptr + map_range.offset + offset; -+ map_desc->data = buffer->buffer_heap->map_ptr + mt_elem->range.offset + offset; - resource->map_count++; - -- buffer->mt_persistent_map = map_range; -+ buffer->mt_persistent_map = mt_elem; - - // Discard handler on CSMT thread is responsible for returning the - // currently used buffer to the free pool, along with the fence that - // must be called before the buffer can be reused. -- wined3d_cs_emit_discard_buffer(resource->device->cs, buffer, map_range); -- -+ wined3d_cs_emit_discard_buffer(resource->device->cs, buffer, mt_elem); - return WINED3D_OK; - } - else if (flags & WINED3D_MAP_NOOVERWRITE) -@@ -1435,7 +1434,7 @@ static HRESULT buffer_resource_sub_resource_map(struct wined3d_resource *resourc - // Allow immediate access for persistent buffers without a fence. - // Always use the latest buffer in this case in case the latest - // DISCARDed one hasn't reached the command stream yet. -- struct wined3d_map_range map_range = buffer->mt_persistent_map; -+ struct wined3d_map_range map_range = buffer->mt_persistent_map->range; - map_desc->data = buffer->buffer_heap->map_ptr + map_range.offset + offset; - resource->map_count++; - -diff --git a/dlls/wined3d/buffer_heap.c b/dlls/wined3d/buffer_heap.c -index 75f84b0088..80670c515f 100644 ---- a/dlls/wined3d/buffer_heap.c -+++ b/dlls/wined3d/buffer_heap.c -@@ -25,18 +25,6 @@ - WINE_DEFAULT_DEBUG_CHANNEL(d3d); - WINE_DECLARE_DEBUG_CHANNEL(d3d_perf); - --struct wined3d_buffer_heap_element --{ -- struct wined3d_map_range range; -- -- // rbtree data -- struct wine_rb_entry entry; -- -- // Binned free list positions -- struct wined3d_buffer_heap_element *next; -- struct wined3d_buffer_heap_element *prev; --}; -- - struct wined3d_buffer_heap_fenced_element - { - struct wined3d_buffer_heap_bin_set free_list; -@@ -82,6 +70,11 @@ static int element_bin(struct wined3d_buffer_heap_element *elem) - // Inserts an element into the appropriate free list bin. - static void element_insert_free_bin(struct wined3d_buffer_heap *heap, struct wined3d_buffer_heap_element *elem) - { -+ if (elem->prev || elem->next) -+ { -+ ERR("Element %p in already in a free list (for some reason).\n", elem); -+ } -+ - int bin = element_bin(elem); - - elem->prev = NULL; -@@ -206,7 +199,7 @@ HRESULT wined3d_buffer_heap_destroy(struct wined3d_buffer_heap *heap, struct win - return WINED3D_OK; - } - --HRESULT wined3d_buffer_heap_alloc(struct wined3d_buffer_heap *heap, GLsizeiptr size, struct wined3d_map_range *out_range) -+HRESULT wined3d_buffer_heap_alloc(struct wined3d_buffer_heap *heap, GLsizeiptr size, struct wined3d_buffer_heap_element **out_elem) - { - int initial_bin; - int initial_size = size; -@@ -233,24 +226,24 @@ HRESULT wined3d_buffer_heap_alloc(struct wined3d_buffer_heap *heap, GLsizeiptr s - remaining_range.offset = elem->range.offset + size; - remaining_range.size = elem->range.size - size; - -- out_range->offset = elem->range.offset; -- out_range->size = size; -+ // Take the element from the free list, transferring ownership to -+ // the caller. -+ element_remove_free(heap, elem); -+ // Resize the element so that we can free the remainder. -+ elem->range.size = size; - -- TRACE_(d3d_perf)("Allocated %d (requested %d) at %p from bin %d (initial %d)\n", size, initial_size, elem->range.offset, i, initial_bin); -+ *out_elem = elem; - -- // Remove the element from its current free bin to move it to the correct list. -- element_remove_free(heap, elem); -+ TRACE_(d3d_perf)("Allocated %d (requested %d) at %p from bin %d (initial %d)\n", size, initial_size, elem->range.offset, i, initial_bin); - - if (remaining_range.size > 0) - { -+ struct wined3d_buffer_heap_element *remaining_elem; -+ - TRACE_(d3d_perf)("Imperfect fit allocated, fragmenting remainder of %lld at %p.\n", remaining_range.size, remaining_range.offset); - -- elem->range = remaining_range; -- element_insert_free_bin(heap, elem); -- } -- else -- { -- HeapFree(GetProcessHeap(), 0, elem); -+ remaining_elem = element_new(remaining_range.offset, remaining_range.size); -+ element_insert_free_bin(heap, remaining_elem); - } - - LeaveCriticalSection(&heap->temp_lock); -@@ -265,7 +258,7 @@ HRESULT wined3d_buffer_heap_alloc(struct wined3d_buffer_heap *heap, GLsizeiptr s - if (SUCCEEDED(wined3d_buffer_heap_deferred_coalesce(heap, &num_coalesced))) - { - if (num_coalesced > 0) -- return wined3d_buffer_heap_alloc(heap, size, out_range); -+ return wined3d_buffer_heap_alloc(heap, size, out_elem); - } - - FIXME_(d3d_perf)("Coalescing did not create new blocks, failing.\n"); -@@ -273,16 +266,15 @@ HRESULT wined3d_buffer_heap_alloc(struct wined3d_buffer_heap *heap, GLsizeiptr s - return WINED3DERR_OUTOFVIDEOMEMORY; - } - --HRESULT wined3d_buffer_heap_free(struct wined3d_buffer_heap *heap, struct wined3d_map_range range) -+HRESULT wined3d_buffer_heap_free(struct wined3d_buffer_heap *heap, struct wined3d_buffer_heap_element *elem) - { -- struct wined3d_buffer_heap_element *elem = element_new(range.offset, range.size); -- -- if (!elem) -- return E_OUTOFMEMORY; -- - EnterCriticalSection(&heap->temp_lock); - - // Only insert the element into a free bin, coalescing will occur later. -+ // -+ // Note that the reason that we pass around wined3d_buffer_heap_element -+ // instead of a range is to avoid frequent HeapAlloc/HeapFree operations -+ // when we're reusing buffers. - element_insert_free_bin(heap, elem); - - LeaveCriticalSection(&heap->temp_lock); -@@ -290,9 +282,8 @@ HRESULT wined3d_buffer_heap_free(struct wined3d_buffer_heap *heap, struct wined3 - return WINED3D_OK; - } - --HRESULT wined3d_buffer_heap_free_fenced(struct wined3d_buffer_heap *heap, struct wined3d_device *device, struct wined3d_map_range range) -+HRESULT wined3d_buffer_heap_free_fenced(struct wined3d_buffer_heap *heap, struct wined3d_device *device, struct wined3d_buffer_heap_element *elem) - { -- struct wined3d_buffer_heap_element *elem = element_new(range.offset, range.size); - int bin_index = element_bin(elem); - struct wined3d_buffer_heap_bin *bin = &heap->pending_fenced_bins.bins[bin_index]; - -diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c -index eae2c3a79d..01aa53597f 100644 ---- a/dlls/wined3d/context.c -+++ b/dlls/wined3d/context.c -@@ -5005,9 +5005,9 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s - if (parameters->indexed) - { - struct wined3d_buffer *index_buffer = state->index_buffer; -- if (index_buffer->locations & WINED3D_LOCATION_PERSISTENT_MAP) -+ if (index_buffer->cs_persistent_map) - { -- idx_data = index_buffer->cs_persistent_map.offset; -+ idx_data = index_buffer->cs_persistent_map->range.offset; - } - else if (!index_buffer->buffer_object || !stream_info->all_vbo) - { -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index e61b8dedbb..d1f665d505 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -444,7 +444,7 @@ struct wined3d_cs_discard_buffer - { - enum wined3d_cs_op opcode; - struct wined3d_buffer *buffer; -- struct wined3d_map_range map_range; -+ struct wined3d_buffer_heap_element *map_range; - }; - - struct wined3d_cs_stop -@@ -2496,14 +2496,14 @@ static void wined3d_cs_exec_discard_buffer(struct wined3d_cs *cs, const void *da - wined3d_resource_release(&op->buffer->resource); - } - --void wined3d_cs_emit_discard_buffer(struct wined3d_cs *cs, struct wined3d_buffer *buffer, struct wined3d_map_range map_range) -+void wined3d_cs_emit_discard_buffer(struct wined3d_cs *cs, struct wined3d_buffer *buffer, struct wined3d_buffer_heap_element *elem) - { - struct wined3d_cs_discard_buffer *op; - - op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); - op->opcode = WINED3D_CS_OP_DISCARD_BUFFER; - op->buffer = buffer; -- op->map_range = map_range; -+ op->map_range = elem; - - wined3d_resource_acquire(&buffer->resource); - -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index b3fd0136ff..0114444943 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -3531,6 +3531,18 @@ struct wined3d_map_range - GLsizeiptr size; - }; - -+struct wined3d_buffer_heap_element -+{ -+ struct wined3d_map_range range; -+ -+ // rbtree data -+ struct wine_rb_entry entry; -+ -+ // Binned free list positions -+ struct wined3d_buffer_heap_element *next; -+ struct wined3d_buffer_heap_element *prev; -+}; -+ - enum wined3d_cs_queue_id - { - WINED3D_CS_QUEUE_DEFAULT = 0, -@@ -3677,7 +3689,7 @@ void wined3d_cs_emit_unload_resource(struct wined3d_cs *cs, struct wined3d_resou - void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_resource *resource, - unsigned int sub_resource_idx, const struct wined3d_box *box, const void *data, unsigned int row_pitch, - unsigned int slice_pitch) DECLSPEC_HIDDEN; --void wined3d_cs_emit_discard_buffer(struct wined3d_cs *cs, struct wined3d_buffer *buffer, struct wined3d_map_range map_range) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_discard_buffer(struct wined3d_cs *cs, struct wined3d_buffer *buffer, struct wined3d_buffer_heap_element *map_range) DECLSPEC_HIDDEN; - void wined3d_cs_init_object(struct wined3d_cs *cs, - void (*callback)(void *object), void *object) DECLSPEC_HIDDEN; - HRESULT wined3d_cs_map(struct wined3d_cs *cs, struct wined3d_resource *resource, unsigned int sub_resource_idx, -@@ -3711,7 +3723,6 @@ enum wined3d_buffer_conversion_type - CONV_POSITIONT, - }; - --struct wined3d_buffer_heap_element; - struct wined3d_buffer_heap_fenced_element; - - // Number of power-of-two buckets to populate. -@@ -3750,11 +3761,11 @@ HRESULT wined3d_buffer_heap_create(struct wined3d_context *context, GLsizeiptr s - HRESULT wined3d_buffer_heap_destroy(struct wined3d_buffer_heap *heap, struct wined3d_context *context) DECLSPEC_HIDDEN; - // Fetches a buffer from the heap of at least the given size. - // Attempts to coalesce blocks under memory pressure. --HRESULT wined3d_buffer_heap_alloc(struct wined3d_buffer_heap *heap, GLsizeiptr size, struct wined3d_map_range* out_range) DECLSPEC_HIDDEN; -+HRESULT wined3d_buffer_heap_alloc(struct wined3d_buffer_heap *heap, GLsizeiptr size, struct wined3d_buffer_heap_element** out_elem) DECLSPEC_HIDDEN; - // Immediately frees a heap-allocated buffer segment. --HRESULT wined3d_buffer_heap_free(struct wined3d_buffer_heap *heap, struct wined3d_map_range range) DECLSPEC_HIDDEN; -+HRESULT wined3d_buffer_heap_free(struct wined3d_buffer_heap *heap, struct wined3d_buffer_heap_element *elem) DECLSPEC_HIDDEN; - // Enqueues a buffer segment to return to the heap once its fence has been signaled. --HRESULT wined3d_buffer_heap_free_fenced(struct wined3d_buffer_heap *heap, struct wined3d_device *device, struct wined3d_map_range range) DECLSPEC_HIDDEN; -+HRESULT wined3d_buffer_heap_free_fenced(struct wined3d_buffer_heap *heap, struct wined3d_device *device, struct wined3d_buffer_heap_element *elem) DECLSPEC_HIDDEN; - // Issues a fence for the current set of pending fenced buffers. - // Double-buffered: if the last fence issued has not yet been triggered, waits - // on it. -@@ -3793,8 +3804,8 @@ struct wined3d_buffer - - /* persistent mapped buffer */ - struct wined3d_buffer_heap *buffer_heap; -- struct wined3d_map_range cs_persistent_map; -- struct wined3d_map_range mt_persistent_map; // TODO: make struct list? -+ struct wined3d_buffer_heap_element *cs_persistent_map; -+ struct wined3d_buffer_heap_element *mt_persistent_map; - }; - - static inline struct wined3d_buffer *buffer_from_resource(struct wined3d_resource *resource) --- -2.16.2 - |