diff options
Diffstat (limited to '0006-wined3d-Switch-wined3d_buffer_heap-to-be-backed-by-a.patch')
-rw-r--r-- | 0006-wined3d-Switch-wined3d_buffer_heap-to-be-backed-by-a.patch | 383 |
1 files changed, 0 insertions, 383 deletions
diff --git a/0006-wined3d-Switch-wined3d_buffer_heap-to-be-backed-by-a.patch b/0006-wined3d-Switch-wined3d_buffer_heap-to-be-backed-by-a.patch deleted file mode 100644 index 89c9c8ec9eda..000000000000 --- a/0006-wined3d-Switch-wined3d_buffer_heap-to-be-backed-by-a.patch +++ /dev/null @@ -1,383 +0,0 @@ -From 2acd4b6ca9cadb84eb38bf1fc4bd5b2ccab3c532 Mon Sep 17 00:00:00 2001 -From: Andrew Comminos <andrew@comminos.com> -Date: Tue, 27 Feb 2018 16:11:10 -0800 -Subject: [PATCH 6/8] wined3d: Switch wined3d_buffer_heap to be backed by an - rb-tree. - ---- - dlls/wined3d/buffer_heap.c | 230 ++++++++++++++++++----------------------- - dlls/wined3d/wined3d_private.h | 6 +- - 2 files changed, 105 insertions(+), 131 deletions(-) - -diff --git a/dlls/wined3d/buffer_heap.c b/dlls/wined3d/buffer_heap.c -index 165a957edd..45d3a2c7d7 100644 ---- a/dlls/wined3d/buffer_heap.c -+++ b/dlls/wined3d/buffer_heap.c -@@ -19,6 +19,7 @@ - - #include "config.h" - #include "wine/port.h" -+#include "wine/rbtree.h" - #include "wined3d_private.h" - - WINE_DEFAULT_DEBUG_CHANNEL(d3d); -@@ -26,21 +27,26 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d_perf); - - struct wined3d_buffer_heap_element - { -+ struct wine_rb_entry entry; - struct wined3d_map_range range; -+}; - -- struct wined3d_buffer_heap_element *prev; -- struct wined3d_buffer_heap_element *next; -+struct wined3d_buffer_heap_range -+{ -+ struct wined3d_map_range range; -+ -+ struct wined3d_buffer_heap_range *next; - }; - - struct wined3d_buffer_heap_fenced_element - { -- struct wined3d_buffer_heap_element *ranges; -+ struct wined3d_buffer_heap_range *ranges; - struct wined3d_fence *fence; - -- struct wined3d_buffer_heap_element *next; -+ struct wined3d_buffer_heap_fenced_element *next; - }; - --static struct wined3d_buffer_heap_element* element_new(GLintptr offset, GLsizeiptr size) -+static struct wined3d_buffer_heap_element* element_new(GLsizei offset, GLsizei size) - { - struct wined3d_buffer_heap_element* elem; - elem = HeapAlloc(GetProcessHeap(), 0, sizeof(struct wined3d_buffer_heap_element)); -@@ -48,12 +54,10 @@ static struct wined3d_buffer_heap_element* element_new(GLintptr offset, GLsizeip - return NULL; - elem->range.offset = offset; - elem->range.size = size; -- elem->next = NULL; -- elem->prev = NULL; - return elem; - } - --static struct wined3d_buffer_heap_fenced_element* fenced_element_new(struct wined3d_buffer_heap_element *ranges, struct wined3d_fence* fence) -+static struct wined3d_buffer_heap_fenced_element* fenced_element_new(struct wined3d_buffer_heap_range *ranges, struct wined3d_fence* fence) - { - struct wined3d_buffer_heap_fenced_element* elem; - elem = HeapAlloc(GetProcessHeap(), 0, sizeof(struct wined3d_buffer_heap_fenced_element)); -@@ -65,97 +69,16 @@ static struct wined3d_buffer_heap_fenced_element* fenced_element_new(struct wine - return elem; - } - --static void element_merge_adjacent(struct wined3d_buffer_heap_element **head, struct wined3d_buffer_heap_element *elem) --{ -- struct wined3d_buffer_heap_element *cur_prev = elem->prev; -- struct wined3d_buffer_heap_element *cur_next = elem->next; -- if (cur_prev && cur_prev->range.offset + cur_prev->range.size == elem->range.offset) -- { -- elem->range.offset = cur_prev->range.offset; -- elem->range.size += cur_prev->range.size; -- -- elem->prev = cur_prev->prev; -- if (cur_prev->prev) -- cur_prev->prev->next = elem; -- -- if (cur_prev == *head) -- *head = elem; -- -- HeapFree(GetProcessHeap(), 0, cur_prev); -- } -- if (cur_next && cur_next->range.offset == elem->range.offset + elem->range.size) -- { -- elem->range.size += cur_next->range.size; -- elem->next = cur_next->next; -- if (cur_next->next) -- { -- cur_next->next->prev = elem; -- } -- HeapFree(GetProcessHeap(), 0, cur_next); -- } --} -- --// Inserts a range into the list starting at `elem`. --// Updates the head of the list, if necessary. --static void element_insert_range(struct wined3d_buffer_heap_element **head, struct wined3d_map_range range) -+static int free_tree_compare(const void *key, const struct wine_rb_entry *entry) - { -- struct wined3d_buffer_heap_element *elem = *head; -- struct wined3d_buffer_heap_element *new_elem; -- struct wined3d_buffer_heap_element *last_elem = NULL; -- -- // Special case where the head doesn't exist. -- if (!elem) -- { -- new_elem = element_new(range.offset, range.size); -- *head = new_elem; -- return; -- } -- -- while (elem) -- { -- struct wined3d_map_range *erange = &elem->range; -- if (range.offset + range.size == erange->offset) -- { -- // Left side merge -- erange->offset = range.offset; -- erange->size += range.size; -- // Check if this causes a merge with elem->prev -- element_merge_adjacent(head, elem); -- return; -- } -- else if (erange->offset + erange->size == range.offset) -- { -- // Right side merge -- erange->size += range.size; -- // Check if this causes a merge with elem->prev -- element_merge_adjacent(head, elem); -- return; -- } -- else if (range.offset < erange->offset) -- { -- // Append to left, non-merge case. -- new_elem = element_new(range.offset, range.size); -- new_elem->prev = elem->prev; -- new_elem->next = elem; -- if (elem->prev) -- { -- elem->prev->next = new_elem; -- } -- if (*head == elem) -- { -- *head = new_elem; -- } -- elem->prev = new_elem; -- return; -- } -- last_elem = elem; -- elem = elem->next; -- } -- -- // Larger offset than all other elements in the list, append to the end. -- new_elem = element_new(range.offset, range.size); -- new_elem->prev = last_elem; -- last_elem->next = new_elem; -+ const GLsizei offset = (const GLsizei) key; -+ struct wined3d_buffer_heap_element *elem = WINE_RB_ENTRY_VALUE(entry, struct wined3d_buffer_heap_element, entry); -+ -+ if (offset < elem->range.offset) -+ return -1; -+ if (offset > elem->range.offset) -+ return 1; -+ return 0; - } - - /* Context activation is done by the caller. */ -@@ -165,6 +88,7 @@ HRESULT wined3d_buffer_heap_create(struct wined3d_context *context, GLsizeiptr s - const GLenum buffer_target = GL_ARRAY_BUFFER; - GLbitfield access_flags; - GLbitfield storage_flags; -+ struct wined3d_buffer_heap_element *initial_elem; - - struct wined3d_buffer_heap *object; - -@@ -195,7 +119,11 @@ HRESULT wined3d_buffer_heap_create(struct wined3d_context *context, GLsizeiptr s - } - context_bind_bo(context, buffer_target, 0); - -- object->free_list_head = element_new(0, size); -+ wine_rb_init(&object->free_tree, free_tree_compare); -+ -+ initial_elem = element_new(0, size); -+ wine_rb_put(&object->free_tree, initial_elem->range.offset, &initial_elem->entry); -+ - object->fenced_head = object->fenced_tail = NULL; - object->alignment = alignment; - object->pending_fenced_bytes = 0; -@@ -217,10 +145,10 @@ HRESULT wined3d_buffer_heap_destroy(struct wined3d_buffer_heap *heap, struct win - - HRESULT wined3d_buffer_heap_alloc(struct wined3d_buffer_heap *heap, GLsizeiptr size, struct wined3d_map_range *out_range) - { -- EnterCriticalSection(&heap->temp_lock); -+ struct wine_rb_entry *iter; - - // TODO(acomminos): free list binning? -- struct wined3d_buffer_heap_element *elem = heap->free_list_head; -+ EnterCriticalSection(&heap->temp_lock); - - // Round to the nearest power of two to reduce fragmentation. - size = 1ULL << (int)ceil(log2(size)); -@@ -229,40 +157,35 @@ HRESULT wined3d_buffer_heap_alloc(struct wined3d_buffer_heap *heap, GLsizeiptr s - if (heap->alignment) - size += heap->alignment - (size % heap->alignment); - -- while (elem != NULL) -+ iter = wine_rb_head(heap->free_tree.root); -+ while (iter) - { -- TRACE("allocation at %p, size %lld\n", heap->map_ptr + elem->range.offset, elem->range.size); -- // XXX(acomminos): first fit is highly likely to be dumb, needs more analysis. -+ struct wined3d_buffer_heap_element *elem = WINE_RB_ENTRY_VALUE(iter, struct wined3d_buffer_heap_element, entry); - if (elem->range.size >= size) - { -- // Pull the range from the start of the free list element. -- out_range->offset = elem->range.offset; -- out_range->size = size; // XXX(acomminos): should we really give the exact size requested? -+ // FIXME(acomminos): should key based on end so that we can slice -+ // off the front without changing the key. -+ GLsizei remaining = elem->range.size - size; - -- elem->range.offset += size; -- elem->range.size -= size; -+ out_range->offset = elem->range.offset; -+ out_range->size = size; - -- if (elem->range.size == 0) -+ wine_rb_remove(&heap->free_tree, iter); -+ if (remaining > 0) -+ { -+ elem->range.offset += size; -+ elem->range.size -= size; -+ wine_rb_put(&heap->free_tree, (const void*) elem->range.offset, &elem->entry); -+ } -+ else - { -- if (elem->prev) -- { -- elem->prev->next = elem->next; -- } -- if (elem->next) -- { -- elem->next->prev = elem->prev; -- } -- if (heap->free_list_head == elem) -- { -- heap->free_list_head = elem->next; -- } - HeapFree(GetProcessHeap(), 0, elem); - } -- -+ TRACE("Allocated %lld bytes at %lld\n", out_range->size, out_range->offset); - LeaveCriticalSection(&heap->temp_lock); - return WINED3D_OK; - } -- elem = elem->next; -+ iter = wine_rb_next(iter); - } - - LeaveCriticalSection(&heap->temp_lock); -@@ -271,17 +194,68 @@ HRESULT wined3d_buffer_heap_alloc(struct wined3d_buffer_heap *heap, GLsizeiptr s - - HRESULT wined3d_buffer_heap_free(struct wined3d_buffer_heap *heap, struct wined3d_map_range range) - { -+ struct wined3d_buffer_heap_element *elem = element_new(range.offset, range.size); -+ struct wine_rb_entry *entry; -+ HRESULT hr; -+ -+ if (!elem) -+ return E_OUTOFMEMORY; -+ - EnterCriticalSection(&heap->temp_lock); -+ if (wine_rb_put(&heap->free_tree, (const void*) elem->range.offset, &elem->entry) == -1) -+ { -+ LeaveCriticalSection(&heap->temp_lock); -+ HeapFree(GetProcessHeap(), 0, elem); -+ return E_FAIL; -+ } - -- element_insert_range(&heap->free_list_head, range); -+ // Coalesce left. -+ entry = wine_rb_prev(&elem->entry); -+ if (entry) -+ { -+ TRACE("Coalesced left.\n"); -+ struct wined3d_buffer_heap_element *left_elem = WINE_RB_ENTRY_VALUE(elem, struct wined3d_buffer_heap_element, entry); -+ if (left_elem->range.offset + left_elem->range.size == elem->range.offset) -+ { -+ // Replace the newly inserted element with an extended node to its -+ // left. This doesn't change the key properties of the left node. -+ left_elem->range.size += range.size; -+ -+ wine_rb_remove(&heap->free_tree, &elem->entry); -+ HeapFree(GetProcessHeap(), 0, elem); -+ -+ elem = left_elem; -+ } -+ } -+ -+ // Coalesce right. -+ entry = wine_rb_next(&elem->entry); -+ if (entry) -+ { -+ TRACE("Coalesced right.\n"); -+ struct wined3d_buffer_heap_element *right_elem = WINE_RB_ENTRY_VALUE(elem, struct wined3d_buffer_heap_element, entry); -+ if (elem->range.offset + elem->range.size == right_elem->range.offset) -+ { -+ // Remove the right element, this doesn't change the keying of our -+ // newly inserted element. -+ elem->range.size += right_elem->range.size; -+ -+ wine_rb_remove(&heap->free_tree, &right_elem->entry); -+ HeapFree(GetProcessHeap(), 0, right_elem); -+ } -+ } - - LeaveCriticalSection(&heap->temp_lock); -+ - return WINED3D_OK; - } - - HRESULT wined3d_buffer_heap_free_fenced(struct wined3d_buffer_heap *heap, struct wined3d_device *device, struct wined3d_map_range range) - { -- element_insert_range(&heap->pending_fenced_head, range); -+ struct wined3d_buffer_heap_range *elem = HeapAlloc(GetProcessHeap(), 0, sizeof(struct wined3d_buffer_heap_range)); -+ elem->range = range; -+ elem->next = heap->pending_fenced_head; -+ heap->pending_fenced_head = elem; - - heap->pending_fenced_bytes += range.size; - if (heap->pending_fenced_bytes >= heap->pending_fenced_threshold_bytes) -@@ -338,11 +312,11 @@ HRESULT wined3d_buffer_heap_cs_poll_fences(struct wined3d_buffer_heap *heap, str - case WINED3D_FENCE_NOT_STARTED: - { - TRACE_(d3d_perf)("Freed fence group.\n"); -- struct wined3d_buffer_heap_element *range_elem = elem->ranges; -+ struct wined3d_buffer_heap_range *range_elem = elem->ranges; - // FIXME(acomminos): this might take a while. incrementally do this? - while (range_elem) - { -- struct wined3d_buffer_heap_element *next = range_elem->next; -+ struct wined3d_buffer_heap_range *next = range_elem->next; - wined3d_buffer_heap_free(heap, range_elem->range); - HeapFree(GetProcessHeap(), 0, range_elem); - range_elem = next; -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 62433a39b1..3a45d9931e 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -3665,7 +3665,7 @@ enum wined3d_buffer_conversion_type - CONV_POSITIONT, - }; - --struct wined3d_buffer_heap_element; -+struct wined3d_buffer_heap_range; - struct wined3d_buffer_heap_fenced_element; - - // A heap that manages allocations with a single GL buffer. -@@ -3677,10 +3677,10 @@ struct wined3d_buffer_heap - CRITICAL_SECTION temp_lock; // Temporary lock while we implement the fenced free list. - - // TODO: add buckets for free regions of a given size. -- struct wined3d_buffer_heap_element *free_list_head; -+ struct wine_rb_tree free_tree; // Free regions keyed on their base address. - - // Elements that need to be fenced, but haven't reached the required size. -- struct wined3d_buffer_heap_element *pending_fenced_head; -+ struct wined3d_buffer_heap_range *pending_fenced_head; - GLsizeiptr pending_fenced_bytes; // Number of free bytes in the active fenced region. - GLsizeiptr pending_fenced_threshold_bytes; // Number of bytes required before fencing. - --- -2.16.2 - |