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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
From d64aafc0ede047d1eff93ee7aa77411c0d27aa21 Mon Sep 17 00:00:00 2001
From: Andrew Comminos <andrew@comminos.com>
Date: Mon, 5 Mar 2018 20:28:34 -0800
Subject: [PATCH 3/5] wined3d: Use ARB_multi_bind to speed up UBO updates.
More frequent UBO remaps as a result of the persistent buffer allocator
causes glBindBufferRange to be a bottleneck. Using ARB_multi_bind
massively reduces state change overhead.
---
dlls/wined3d/directx.c | 4 ++++
dlls/wined3d/state.c | 46 +++++++++++++++++++++++++++++++++++++++-------
dlls/wined3d/wined3d_gl.h | 1 +
3 files changed, 44 insertions(+), 7 deletions(-)
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 46c6a59536..8789a501ec 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -149,6 +149,7 @@ static const struct wined3d_extension_map gl_extension_map[] =
{"GL_ARB_internalformat_query2", ARB_INTERNALFORMAT_QUERY2 },
{"GL_ARB_map_buffer_alignment", ARB_MAP_BUFFER_ALIGNMENT },
{"GL_ARB_map_buffer_range", ARB_MAP_BUFFER_RANGE },
+ {"GL_ARB_multi_bind", ARB_MULTI_BIND },
{"GL_ARB_multisample", ARB_MULTISAMPLE },
{"GL_ARB_multitexture", ARB_MULTITEXTURE },
{"GL_ARB_occlusion_query", ARB_OCCLUSION_QUERY },
@@ -2796,6 +2797,8 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info)
/* GL_ARB_map_buffer_range */
USE_GL_FUNC(glFlushMappedBufferRange)
USE_GL_FUNC(glMapBufferRange)
+ /* GL_ARB_multi_bind */
+ USE_GL_FUNC(glBindBuffersRange)
/* GL_ARB_multisample */
USE_GL_FUNC(glSampleCoverageARB)
/* GL_ARB_multitexture */
@@ -3973,6 +3976,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter,
{ARB_TEXTURE_VIEW, MAKEDWORD_VERSION(4, 3)},
{ARB_CLEAR_TEXTURE, MAKEDWORD_VERSION(4, 4)},
+ {ARB_MULTI_BIND, MAKEDWORD_VERSION(4, 4)},
{ARB_CLIP_CONTROL, MAKEDWORD_VERSION(4, 5)},
{ARB_CULL_DISTANCE, MAKEDWORD_VERSION(4, 5)},
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index 6f7805b8bd..4d0718514f 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -5014,19 +5014,51 @@ static void state_cb(struct wined3d_context *context, const struct wined3d_state
shader_type = WINED3D_SHADER_TYPE_COMPUTE;
wined3d_gl_limits_get_uniform_block_range(&gl_info->limits, shader_type, &base, &count);
- for (i = 0; i < count; ++i)
+
+ if (gl_info->supported[ARB_MULTI_BIND])
{
- buffer = state->cb[shader_type][i];
- if (buffer)
+ GLuint buffer_objects[count];
+ GLsizeiptr buffer_offsets[count];
+ GLsizeiptr buffer_sizes[count];
+
+ for (i = 0; i < count; ++i)
{
- wined3d_buffer_get_memory(buffer, &bo_addr, buffer->locations);
- GL_EXTCALL(glBindBufferRange(GL_UNIFORM_BUFFER, base + i, bo_addr.buffer_object, bo_addr.addr, bo_addr.length));
+ buffer = state->cb[shader_type][i];
+ if (buffer)
+ {
+ wined3d_buffer_get_memory(buffer, &bo_addr, buffer->locations);
+ buffer_objects[i] = bo_addr.buffer_object;
+ buffer_offsets[i] = bo_addr.addr;
+ buffer_sizes[i] = bo_addr.length;
+ }
+ else
+ {
+ buffer_objects[i] = buffer_offsets[i] = 0;
+ // The ARB_multi_bind spec states that an error may be thrown if
+ // `size` is less than or equal to zero, Thus, we specify a size for
+ // unused buffers anyway.
+ buffer_sizes[i] = 1;
+ }
}
- else
+ GL_EXTCALL(glBindBuffersRange(GL_UNIFORM_BUFFER, base, count, buffer_objects, buffer_offsets, buffer_sizes));
+ }
+ else
+ {
+ for (i = 0; i < count; ++i)
{
- GL_EXTCALL(glBindBufferBase(GL_UNIFORM_BUFFER, base + i, 0));
+ buffer = state->cb[shader_type][i];
+ if (buffer)
+ {
+ wined3d_buffer_get_memory(buffer, &bo_addr, buffer->locations);
+ GL_EXTCALL(glBindBufferRange(GL_UNIFORM_BUFFER, base + i, bo_addr.buffer_object, bo_addr.addr, bo_addr.length));
+ }
+ else
+ {
+ GL_EXTCALL(glBindBufferBase(GL_UNIFORM_BUFFER, base + i, 0));
+ }
}
}
+
checkGLcall("bind constant buffers");
}
diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h
index 7626864ef2..25c3301c94 100644
--- a/dlls/wined3d/wined3d_gl.h
+++ b/dlls/wined3d/wined3d_gl.h
@@ -82,6 +82,7 @@ enum wined3d_gl_extension
ARB_INTERNALFORMAT_QUERY2,
ARB_MAP_BUFFER_ALIGNMENT,
ARB_MAP_BUFFER_RANGE,
+ ARB_MULTI_BIND,
ARB_MULTISAMPLE,
ARB_MULTITEXTURE,
ARB_OCCLUSION_QUERY,
--
2.16.2
|