1Name
2
3    ARB_copy_buffer
4
5Name Strings
6
7    GL_ARB_copy_buffer
8
9Contact
10
11    Jeff Bolz, NVIDIA Corporation (jbolz 'at' nvidia.com)
12
13Contributors
14
15    Rob Barris, Blizzard Entertainment
16    Bruce Merry, ARM
17    Eric Werness, NVIDIA
18    Greg Roth, NVIDIA
19
20Notice
21
22    Copyright (c) 2009-2013 The Khronos Group Inc. Copyright terms at
23        http://www.khronos.org/registry/speccopyright.html
24
25Status
26
27    Complete. Approved by the ARB on March 19, 2009.
28
29Version
30
31    Last Modified Date: September 6, 2017
32    Author Revision: 7
33
34Number
35
36    ARB Extension #59
37
38Dependencies
39
40    Written based on the wording of the OpenGL 3.0 (August 11, 2008 draft)
41    specification.
42
43Overview
44
45    This extension provides a mechanism to do an accelerated copy from one
46    buffer object to another. This may be useful to load buffer objects
47    in a "loading thread" while minimizing cost and synchronization effort
48    in the "rendering thread."
49
50IP Status
51
52    No known IP claims.
53
54New Tokens
55
56    Accepted by the target parameters of BindBuffer, BufferData,
57    BufferSubData, MapBuffer, UnmapBuffer, GetBufferSubData,
58    GetBufferPointerv, MapBufferRange, FlushMappedBufferRange,
59    GetBufferParameteriv, BindBufferRange, BindBufferBase,
60    and CopyBufferSubData:
61
62    COPY_READ_BUFFER                    0x8F36
63    COPY_WRITE_BUFFER                   0x8F37
64
65New Procedures and Functions
66
67    void CopyBufferSubData(enum readtarget, enum writetarget,
68                           intptr readoffset, intptr writeoffset,
69                           sizeiptr size);
70
71Additions to Chapter 2 of the OpenGL 3.0 Specification (Rasterization)
72
73    Add a new subsection "Copying Between Buffers" to section 2.9:
74
75    All or part of one buffer object's data store may be copied to the
76    data store of another buffer object by calling
77
78    void CopyBufferSubData(enum readtarget, enum writetarget,
79                           intptr readoffset, intptr writeoffset,
80                           sizeiptr size);
81
82    with readtarget and writetarget each set to one of the targets
83    ARRAY_BUFFER, COPY_READ_BUFFER, COPY_WRITE_BUFFER,
84    ELEMENT_ARRAY_BUFFER, PIXEL_PACK_BUFFER, PIXEL_UNPACK_BUFFER,
85    TEXTURE_BUFFER, TRANSFORM_FEEDBACK_BUFFER, or UNIFORM_BUFFER. While
86    any of these targets may be used, the COPY_READ_BUFFER and
87    COPY_WRITE_BUFFER targets are provided specifically for copies, so
88    that they can be done without affecting other buffer binding targets
89    that may be in use. writeoffset and size specify the range of data
90    in the buffer object bound to writetarget that is to be replaced, in
91    terms of basic machine units. readoffset and size specify the range
92    of data in the buffer object bound to readtarget that is to be
93    copied to the corresponding region of writetarget.
94
95    An INVALID_VALUE error is generated if any of readoffset,
96    writeoffset, or size are negative, if readoffset+size exceeds the
97    size of the buffer object bound to readtarget, or if
98    writeoffset+size exceeds the size of the buffer object bound to
99    writetarget.
100
101    An INVALID_VALUE error is generated if the same buffer object is
102    bound to both readtarget and writetarget, and the ranges
103    [readoffset, readoffset+size) and [writeoffset, writeoffset+size)
104    overlap.
105
106    An INVALID_OPERATION error is generated if zero is bound to
107    readtarget or writetarget.
108
109    An INVALID_OPERATION error is generated if the buffer objects bound
110    to either readtarget or writetarget are mapped.
111
112Additions to Chapter 5 of the OpenGL 3.0 Specification (Special Functions)
113
114    Add to the list (page 310) of "Vertex Buffer Objects" commands "not
115    compiled into the display list but are executed immediately":
116
117        CopyBufferSubData
118
119Additions to the AGL/EGL/GLX/WGL Specifications
120
121    None
122
123GLX Protocol
124
125    The following single command is sent to the server as
126    a glxsingle request:
127
128    CopyBufferSubData
129
130        1       CARD8           opcode
131        1       221             GLX opcode
132        2       10              request length
133        4       GLX_CONTEXT_TAG context tag
134        8       CARD64          readoffset
135        8       CARD64          writeoffset
136        8       CARD64          size
137        4       ENUM            readtarget
138        4       ENUM            writetarget
139
140Errors
141
142    The error INVALID_VALUE is generated by CopyBufferSubData if
143    readoffset, writeoffset, or size are less than zero, or if
144    readoffset+size is greater than the value of BUFFER_SIZE of
145    readtarget/readBuffer, or if writeoffset+size is greater than the
146    value of BUFFER_SIZE of writetarget/writeBuffer.
147
148    The error INVALID_OPERATION is generated by CopyBufferSubData if
149    either readtarget/readBuffer or writetarget/writeBuffer are mapped.
150
151    The error INVALID_VALUE is generated by CopyBufferSubData if
152    readtarget/readBuffer and writetarget/writeBuffer are the same
153    buffer object, and the ranges [readoffset, readoffset+size) and
154    [writeoffset, writeoffset+size) overlap.
155
156New State
157
158    (add to table 6.52, Miscellaneous State, p. 390)
159
160                                            Initial
161    Get Value           Type    Get Command Value   Description                 Sec.    Attribute
162    ----------------    ----    ----------- ------- --------------------------- ------  ---------
163    COPY_READ_BUFFER    Z+      GetIntegerv 0       Buffer object bound to the  2.9     none
164                                                    copy buffer "read" binding
165                                                    point
166    COPY_WRITE_BUFFE    Z+      GetIntegerv 0       Buffer object bound to the  2.9     none
167                                                    copy buffer "write"
168                                                    binding point
169
170Usage Examples
171
172    Replace BufferSubData with a non-cache-polluting update:
173
174        BindBuffer(COPY_READ_BUFFER, tempBuffer);
175        BufferData(COPY_READ_BUFFER, updateSize, NULL, STREAM_DRAW);
176        // this may return a WriteCombined mapping!
177        ptr = MapBuffer(COPY_READ_BUFFER, WRITE_ONLY);
178        // fill ptr
179        UnmapBuffer(COPY_READ_BUFFER);
180
181        BindBuffer(COPY_WRITE_BUFFER, vtxBuffer);
182        // this copy ideally requires no CPU work on the data itself.
183        CopyBufferSubData(COPY_READ_BUFFER, COPY_WRITE_BUFFER,
184                          0, writeoffset, updateSize);
185
186Issues
187
188    1) What should the new targets and parameters be named? READ/WRITE?
189       SOURCE/DEST? Something else?
190
191    RESOLVED: READ and WRITE, because it's consistent with the <access>
192    parameters and state.
193
194    2) How is this extension useful?
195
196    This can be a desirable replacement to BufferSubData if there are
197    large updates that will pollute the CPU cache. If generating the data
198    can be offloaded to another thread, then the CPU cost of the update
199    in the rendering thread can be very small.
200
201    This can also be an alternate mechanism to MapBufferRange with the
202    MAP_UNSYNCHRONIZED_BIT, by allowing the CPU to write into a temp
203    buffer and then scheduling the update to be in-band with the
204    rendering. MAP_UNSYNCHRONIZED_BIT can lead to hard-to-detect
205    synchronization bugs if the GPU hasn't finished consuming the data
206    that is overwritten (Write After Read hazard). Also, mapping a buffer
207    may, on some implementations, require forcing the data store into a
208    memory space more local to the CPU than to the GPU, which can adversely
209    affect rendering performance.
210
211    Finally, if an implementation supports concurrent data transfers in
212    one context/thread while doing rendering in another context/thread,
213    this extension may be used to move data from system memory to video
214    memory in preparation for copying it into another buffer, or texture,
215    etc., in the rendering thread.
216
217    (3) Why don't the new tokens and entry points in this extension have
218       "ARB" suffixes like other ARB extensions?
219
220        RESOLVED: Unlike most ARB extensions, this is a strict subset of
221        functionality already approved in OpenGL 3.1. This extension
222        exists only to support that functionality on older hardware that
223        cannot implement a full OpenGL 3.1 driver. Since there are no
224        possible behavior changes between the ARB extension and core
225        features, source code compatibility is improved by not using
226        suffixes on the extension.
227
228Revision History
229
230    Revision 1, 2008/09/09
231     - Initial draft
232    Revision 2, 2008/09/26
233     - Make EXT_direct_state_access interaction explicit.
234    Revision 3, 2008/10/10
235     - Fix missing entry points for the new targets.
236    Revision 4, 2009/03/13
237     - Move Named* entry point to EXT_direct_state_access.
238    Revision 5, 2009/03/19
239     - ARBify and remove ARB suffix from entry points and tokens.
240    Revision 6, 2009/06/03
241     - Add buffer target list and fix capitalization differences on
242       parameter names per feedback from Jonathan Knispel
243    Revision 7, 2017/09/06
244     - Add GLX protocol.
245