summarylogtreecommitdiffstats
path: root/0006-wined3d-Switch-wined3d_buffer_heap-to-be-backed-by-a.patch
diff options
context:
space:
mode:
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.patch383
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
-