summarylogtreecommitdiffstats
path: root/0006-wined3d-Perform-initial-allocation-of-persistent-buf.patch
blob: 2777b6a5324ecfc47b9d0d179bff0a7fd8ed3acd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
From 71b7b3340d147bf7a9b5567c080b32ccd3a39dc6 Mon Sep 17 00:00:00 2001
From: Andrew Comminos <andrew@comminos.com>
Date: Thu, 8 Mar 2018 22:42:03 -0800
Subject: [PATCH 6/9] wined3d: Perform initial allocation of persistent buffers
 asynchronously.

---
 dlls/wined3d/buffer.c | 30 ++++++++++++++++++++----------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index a2ac411b5e..c492fcc8c6 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -272,7 +272,7 @@ fail:
 }
 
 /* Context activation is done by the caller. */
-static BOOL buffer_alloc_persistent_map(struct wined3d_buffer *buffer, struct wined3d_context *context)
+static BOOL buffer_alloc_persistent_map(struct wined3d_buffer *buffer)
 {
     struct wined3d_device *device = buffer->resource.device;
     struct wined3d_buffer_heap *heap;
@@ -688,7 +688,7 @@ static BOOL wined3d_buffer_prepare_location(struct wined3d_buffer *buffer,
                 WARN("Trying to map a persistent region for buffer %p without WINED3D_BUFFER_PERSISTENT.\n", buffer);
                 return FALSE;
             }
-            return buffer_alloc_persistent_map(buffer, context);
+            return buffer_alloc_persistent_map(buffer);
 
         default:
             ERR("Invalid location %s.\n", wined3d_debug_location(location));
@@ -1116,7 +1116,7 @@ static HRESULT wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UI
         const struct wined3d_gl_info *gl_info;
         context = context_acquire(device, NULL, 0);
 
-        FIXME_(d3d_perf)("Fences not used for persistent buffer maps on CS thread, using glFinish.\n");
+        FIXME_(d3d_perf)("Fences not used for persistent buffer maps on CS thread, using glFinish (flags: %x)\n", flags);
 
         gl_info = context->gl_info;
         gl_info->gl_ops.gl.p_glFinish();
@@ -1394,8 +1394,20 @@ static HRESULT buffer_resource_sub_resource_map(struct wined3d_resource *resourc
 
     // Support immediate mapping of persistent buffers off the command thread,
     // which require no GL calls to interface with.
-    if (buffer->locations & WINED3D_LOCATION_PERSISTENT_MAP)
+    if (buffer->flags & WINED3D_BUFFER_PERSISTENT)
     {
+        // Attempt to load a persistent map without syncing, if possible.
+        if (!(buffer->locations & WINED3D_LOCATION_PERSISTENT_MAP))
+        {
+            wined3d_resource_wait_idle(resource);
+            if (!buffer_alloc_persistent_map(buffer))
+            {
+                ERR_(d3d_perf)("Failed to allocate persistent buffer, falling back to sync path.");
+                return E_FAIL;
+            }
+            wined3d_buffer_validate_location(buffer, WINED3D_LOCATION_PERSISTENT_MAP);
+        }
+
         map_desc->row_pitch = map_desc->slice_pitch = buffer->desc.byte_width;
         if (flags & WINED3D_MAP_DISCARD)
         {
@@ -1415,6 +1427,7 @@ static HRESULT buffer_resource_sub_resource_map(struct wined3d_resource *resourc
             // 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);
+
             return WINED3D_OK;
         }
         else if (flags & WINED3D_MAP_NOOVERWRITE)
@@ -1425,14 +1438,11 @@ static HRESULT buffer_resource_sub_resource_map(struct wined3d_resource *resourc
             struct wined3d_map_range map_range = buffer->mt_persistent_map;
             map_desc->data = buffer->buffer_heap->map_ptr + map_range.offset + offset;
             resource->map_count++;
+
             return WINED3D_OK;
         }
-        else
-        {
-            // TODO(acomminos): Should check mapped ranges to see if the region is writeable even though NOOVERWRITE is specified.
-            WARN_(d3d_perf)("Mapping persistent buffer %p in sync with CS thread.\n", buffer);
-            // XXX(acomminos): kill this early return. they're the worst.
-        }
+
+        WARN_(d3d_perf)("Mapping persistent buffer %p in sync with CS thread.\n", buffer);
     }
 
     return E_NOTIMPL;
-- 
2.16.2