1*61046927SAndroid Build Coastguard WorkerBuffer mapping patterns 2*61046927SAndroid Build Coastguard Worker----------------------- 3*61046927SAndroid Build Coastguard Worker 4*61046927SAndroid Build Coastguard WorkerThere are two main strategies the driver has for CPU access to GL buffer 5*61046927SAndroid Build Coastguard Workerobjects. One is that the GL calls allocate temporary storage and blit to the GPU 6*61046927SAndroid Build Coastguard Workerat 7*61046927SAndroid Build Coastguard Worker``glBufferSubData()``/``glBufferData()``/``glFlushMappedBufferRange()``/``glUnmapBuffer()`` 8*61046927SAndroid Build Coastguard Workertime. This makes the behavior easily match. However, this may be more costly 9*61046927SAndroid Build Coastguard Workerthan direct mapping of the GL BO on some platforms, and is essentially not 10*61046927SAndroid Build Coastguard Workeravailable to tiling GPUs (since tiling involves running through the command 11*61046927SAndroid Build Coastguard Workerstream multiple times). Thus, GL has additional interfaces to help make it so 12*61046927SAndroid Build Coastguard Workerapps can directly access memory while avoiding implicit blocking on the GPU 13*61046927SAndroid Build Coastguard Workerrendering from those BOs. 14*61046927SAndroid Build Coastguard Worker 15*61046927SAndroid Build Coastguard WorkerRendering engines have a variety of knobs to set on those GL interfaces for data 16*61046927SAndroid Build Coastguard Workerupload, and as a whole they seem to take just about every path available. Let's 17*61046927SAndroid Build Coastguard Workerlook at some examples to see how they might constrain GL driver buffer upload 18*61046927SAndroid Build Coastguard Workerbehavior. 19*61046927SAndroid Build Coastguard Worker 20*61046927SAndroid Build Coastguard WorkerPortal 2 21*61046927SAndroid Build Coastguard Worker======== 22*61046927SAndroid Build Coastguard Worker 23*61046927SAndroid Build Coastguard Worker.. code-block:: text 24*61046927SAndroid Build Coastguard Worker 25*61046927SAndroid Build Coastguard Worker 1030842 glXSwapBuffers(dpy = 0x82a8000, drawable = 20971540) 26*61046927SAndroid Build Coastguard Worker 1030876 glBufferDataARB(target = GL_ELEMENT_ARRAY_BUFFER, size = 65536, data = NULL, usage = GL_DYNAMIC_DRAW) 27*61046927SAndroid Build Coastguard Worker 1030877 glBufferSubData(target = GL_ELEMENT_ARRAY_BUFFER, offset = 0, size = 576, data = blob(576)) 28*61046927SAndroid Build Coastguard Worker 1030896 glDrawRangeElementsBaseVertex(mode = GL_TRIANGLES, start = 0, end = 526, count = 252, type = GL_UNSIGNED_SHORT, indices = NULL, basevertex = 0) 29*61046927SAndroid Build Coastguard Worker 1030915 glDrawRangeElementsBaseVertex(mode = GL_TRIANGLES, start = 0, end = 19657, count = 36, type = GL_UNSIGNED_SHORT, indices = 0x1f8, basevertex = 0) 30*61046927SAndroid Build Coastguard Worker 1030917 glBufferDataARB(target = GL_ARRAY_BUFFER, size = 1572864, data = NULL, usage = GL_DYNAMIC_DRAW) 31*61046927SAndroid Build Coastguard Worker 1030918 glBufferSubData(target = GL_ARRAY_BUFFER, offset = 0, size = 128, data = blob(128)) 32*61046927SAndroid Build Coastguard Worker 1030919 glBufferSubData(target = GL_ELEMENT_ARRAY_BUFFER, offset = 576, size = 12, data = blob(12)) 33*61046927SAndroid Build Coastguard Worker 1030936 glDrawRangeElementsBaseVertex(mode = GL_TRIANGLES, start = 0, end = 3, count = 6, type = GL_UNSIGNED_SHORT, indices = 0x240, basevertex = 0) 34*61046927SAndroid Build Coastguard Worker 1030937 glBufferSubData(target = GL_ARRAY_BUFFER, offset = 128, size = 128, data = blob(128)) 35*61046927SAndroid Build Coastguard Worker 1030938 glBufferSubData(target = GL_ELEMENT_ARRAY_BUFFER, offset = 588, size = 12, data = blob(12)) 36*61046927SAndroid Build Coastguard Worker 1030940 glDrawRangeElementsBaseVertex(mode = GL_TRIANGLES, start = 4, end = 7, count = 6, type = GL_UNSIGNED_SHORT, indices = 0x24c, basevertex = 0) 37*61046927SAndroid Build Coastguard Worker [... repeated draws at increasing offsets] 38*61046927SAndroid Build Coastguard Worker 1033097 glXSwapBuffers(dpy = 0x82a8000, drawable = 20971540) 39*61046927SAndroid Build Coastguard Worker 40*61046927SAndroid Build Coastguard WorkerFrom this sequence, we can see that it is important that the driver either 41*61046927SAndroid Build Coastguard Workerimplement ``glBufferSubData()`` as a blit from a streaming uploader in sequence with 42*61046927SAndroid Build Coastguard Workerthe ``glDraw*()`` calls (a common behavior for non-tiled GPUs, particularly those with 43*61046927SAndroid Build Coastguard Workerdedicated memory), or that you: 44*61046927SAndroid Build Coastguard Worker 45*61046927SAndroid Build Coastguard Worker1) Track the valid range of the buffer so that you don't have to flush the draws 46*61046927SAndroid Build Coastguard Worker and synchronize on each following ``glBufferSubData()``. 47*61046927SAndroid Build Coastguard Worker 48*61046927SAndroid Build Coastguard Worker2) Reallocate the buffer storage on ``glBufferData`` so that your first 49*61046927SAndroid Build Coastguard Worker ``glBufferSubData()`` of the frame doesn't stall on the last frame's 50*61046927SAndroid Build Coastguard Worker rendering completing. 51*61046927SAndroid Build Coastguard Worker 52*61046927SAndroid Build Coastguard WorkerYou can't just empty your valid range on ``glBufferData()`` unless you know that 53*61046927SAndroid Build Coastguard Workerthe GPU access from the previous frame has completed. This pattern of 54*61046927SAndroid Build Coastguard Workerincrementing ``glBufferSubData()`` offsets interleaved with draws from that data 55*61046927SAndroid Build Coastguard Workeris common among newer Valve games. 56*61046927SAndroid Build Coastguard Worker 57*61046927SAndroid Build Coastguard Worker.. code-block:: text 58*61046927SAndroid Build Coastguard Worker 59*61046927SAndroid Build Coastguard Worker [ during setup ] 60*61046927SAndroid Build Coastguard Worker 61*61046927SAndroid Build Coastguard Worker 679259 glGenBuffersARB(n = 1, buffers = &1314) 62*61046927SAndroid Build Coastguard Worker 679260 glBindBufferARB(target = GL_ELEMENT_ARRAY_BUFFER, buffer = 1314) 63*61046927SAndroid Build Coastguard Worker 679261 glBufferDataARB(target = GL_ELEMENT_ARRAY_BUFFER, size = 3072, data = NULL, usage = GL_STATIC_DRAW) 64*61046927SAndroid Build Coastguard Worker 679264 glMapBufferRange(target = GL_ELEMENT_ARRAY_BUFFER, offset = 0, length = 3072, access = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT) = 0xd7384000 65*61046927SAndroid Build Coastguard Worker 679269 glFlushMappedBufferRange(target = GL_ELEMENT_ARRAY_BUFFER, offset = 0, length = 3072) 66*61046927SAndroid Build Coastguard Worker 679270 glUnmapBuffer(target = GL_ELEMENT_ARRAY_BUFFER) = GL_TRUE 67*61046927SAndroid Build Coastguard Worker 68*61046927SAndroid Build Coastguard Worker [... setup of other buffers on this binding point] 69*61046927SAndroid Build Coastguard Worker 70*61046927SAndroid Build Coastguard Worker 679343 glBindBufferARB(target = GL_ELEMENT_ARRAY_BUFFER, buffer = 1314) 71*61046927SAndroid Build Coastguard Worker 679344 glMapBufferRange(target = GL_ELEMENT_ARRAY_BUFFER, offset = 0, length = 768, access = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT) = 0xd7384000 72*61046927SAndroid Build Coastguard Worker 679346 glFlushMappedBufferRange(target = GL_ELEMENT_ARRAY_BUFFER, offset = 0, length = 768) 73*61046927SAndroid Build Coastguard Worker 679347 glUnmapBuffer(target = GL_ELEMENT_ARRAY_BUFFER) = GL_TRUE 74*61046927SAndroid Build Coastguard Worker 679348 glMapBufferRange(target = GL_ELEMENT_ARRAY_BUFFER, offset = 768, length = 768, access = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT) = 0xd7384300 75*61046927SAndroid Build Coastguard Worker 679350 glFlushMappedBufferRange(target = GL_ELEMENT_ARRAY_BUFFER, offset = 0, length = 768) 76*61046927SAndroid Build Coastguard Worker 679351 glUnmapBuffer(target = GL_ELEMENT_ARRAY_BUFFER) = GL_TRUE 77*61046927SAndroid Build Coastguard Worker 679352 glMapBufferRange(target = GL_ELEMENT_ARRAY_BUFFER, offset = 1536, length = 768, access = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT) = 0xd7384600 78*61046927SAndroid Build Coastguard Worker 679354 glFlushMappedBufferRange(target = GL_ELEMENT_ARRAY_BUFFER, offset = 0, length = 768) 79*61046927SAndroid Build Coastguard Worker 679355 glUnmapBuffer(target = GL_ELEMENT_ARRAY_BUFFER) = GL_TRUE 80*61046927SAndroid Build Coastguard Worker 679356 glMapBufferRange(target = GL_ELEMENT_ARRAY_BUFFER, offset = 2304, length = 768, access = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT) = 0xd7384900 81*61046927SAndroid Build Coastguard Worker 679358 glFlushMappedBufferRange(target = GL_ELEMENT_ARRAY_BUFFER, offset = 0, length = 768) 82*61046927SAndroid Build Coastguard Worker 679359 glUnmapBuffer(target = GL_ELEMENT_ARRAY_BUFFER) = GL_TRUE 83*61046927SAndroid Build Coastguard Worker 84*61046927SAndroid Build Coastguard Worker [... setup completes and we start drawing later] 85*61046927SAndroid Build Coastguard Worker 86*61046927SAndroid Build Coastguard Worker 761845 glBindBufferARB(target = GL_ELEMENT_ARRAY_BUFFER, buffer = 1314) 87*61046927SAndroid Build Coastguard Worker 761846 glDrawRangeElementsBaseVertex(mode = GL_TRIANGLES, start = 0, end = 323, count = 384, type = GL_UNSIGNED_SHORT, indices = NULL, basevertex = 0) 88*61046927SAndroid Build Coastguard Worker 89*61046927SAndroid Build Coastguard WorkerThis suggests that, for non-blitting drivers, resetting your "might be used on 90*61046927SAndroid Build Coastguard Workerthe GPU" range after a stall could save you a bunch of additional GPU stalls 91*61046927SAndroid Build Coastguard Workerduring setup. 92*61046927SAndroid Build Coastguard Worker 93*61046927SAndroid Build Coastguard WorkerTerraria 94*61046927SAndroid Build Coastguard Worker======== 95*61046927SAndroid Build Coastguard Worker 96*61046927SAndroid Build Coastguard Worker.. code-block:: text 97*61046927SAndroid Build Coastguard Worker 98*61046927SAndroid Build Coastguard Worker 167581 glXSwapBuffers(dpy = 0x3004630, drawable = 25165844) 99*61046927SAndroid Build Coastguard Worker 100*61046927SAndroid Build Coastguard Worker 167585 glBufferData(target = GL_ARRAY_BUFFER, size = 196608, data = NULL, usage = GL_STREAM_DRAW) 101*61046927SAndroid Build Coastguard Worker 167586 glBufferSubData(target = GL_ARRAY_BUFFER, offset = 0, size = 1728, data = blob(1728)) 102*61046927SAndroid Build Coastguard Worker 167588 glDrawRangeElementsBaseVertex(mode = GL_TRIANGLES, start = 0, end = 71, count = 108, type = GL_UNSIGNED_SHORT, indices = NULL, basevertex = 0) 103*61046927SAndroid Build Coastguard Worker 167589 glBufferData(target = GL_ARRAY_BUFFER, size = 196608, data = NULL, usage = GL_STREAM_DRAW) 104*61046927SAndroid Build Coastguard Worker 167590 glBufferSubData(target = GL_ARRAY_BUFFER, offset = 0, size = 27456, data = blob(27456)) 105*61046927SAndroid Build Coastguard Worker 167592 glDrawRangeElementsBaseVertex(mode = GL_TRIANGLES, start = 0, end = 7, count = 12, type = GL_UNSIGNED_SHORT, indices = NULL, basevertex = 0) 106*61046927SAndroid Build Coastguard Worker 167594 glDrawRangeElementsBaseVertex(mode = GL_TRIANGLES, start = 0, end = 3, count = 6, type = GL_UNSIGNED_SHORT, indices = NULL, basevertex = 8) 107*61046927SAndroid Build Coastguard Worker 167596 glDrawRangeElementsBaseVertex(mode = GL_TRIANGLES, start = 0, end = 3, count = 6, type = GL_UNSIGNED_SHORT, indices = NULL, basevertex = 12) 108*61046927SAndroid Build Coastguard Worker [...] 109*61046927SAndroid Build Coastguard Worker 110*61046927SAndroid Build Coastguard WorkerIn this game, we can see ``glBufferData()`` being used on the same array buffer 111*61046927SAndroid Build Coastguard Workerthroughout, to get new storage so that the ``glBufferSubData()`` doesn't cause 112*61046927SAndroid Build Coastguard Workersynchronization. 113*61046927SAndroid Build Coastguard Worker 114*61046927SAndroid Build Coastguard WorkerDon't Starve 115*61046927SAndroid Build Coastguard Worker============ 116*61046927SAndroid Build Coastguard Worker 117*61046927SAndroid Build Coastguard Worker.. code-block:: text 118*61046927SAndroid Build Coastguard Worker 119*61046927SAndroid Build Coastguard Worker 7251917 glGenBuffers(n = 1, buffers = &115052) 120*61046927SAndroid Build Coastguard Worker 7251918 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 115052) 121*61046927SAndroid Build Coastguard Worker 7251919 glBufferData(target = GL_ARRAY_BUFFER, size = 144, data = blob(144), usage = GL_STREAM_DRAW) 122*61046927SAndroid Build Coastguard Worker 7251921 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 115052) 123*61046927SAndroid Build Coastguard Worker 7251928 glDrawArrays(mode = GL_TRIANGLES, first = 0, count = 6) 124*61046927SAndroid Build Coastguard Worker 7251930 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 114872) 125*61046927SAndroid Build Coastguard Worker 7251936 glDrawArrays(mode = GL_TRIANGLES, first = 0, count = 18) 126*61046927SAndroid Build Coastguard Worker 7251938 glGenBuffers(n = 1, buffers = &115053) 127*61046927SAndroid Build Coastguard Worker 7251939 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 115053) 128*61046927SAndroid Build Coastguard Worker 7251940 glBufferData(target = GL_ARRAY_BUFFER, size = 144, data = blob(144), usage = GL_STREAM_DRAW) 129*61046927SAndroid Build Coastguard Worker 7251942 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 115053) 130*61046927SAndroid Build Coastguard Worker 7251949 glDrawArrays(mode = GL_TRIANGLES, first = 0, count = 6) 131*61046927SAndroid Build Coastguard Worker 7251973 glXSwapBuffers(dpy = 0x86dd860, drawable = 20971540) 132*61046927SAndroid Build Coastguard Worker [... drawing next frame] 133*61046927SAndroid Build Coastguard Worker 7252388 glDeleteBuffers(n = 1, buffers = &115052) 134*61046927SAndroid Build Coastguard Worker 7252389 glDeleteBuffers(n = 1, buffers = &115053) 135*61046927SAndroid Build Coastguard Worker 7252390 glXSwapBuffers(dpy = 0x86dd860, drawable = 20971540) 136*61046927SAndroid Build Coastguard Worker 137*61046927SAndroid Build Coastguard WorkerIn this game we have a lot of tiny ``glBufferData()`` calls, suggesting that we 138*61046927SAndroid Build Coastguard Workercould see working set wins and possibly CPU overhead reduction by packing small 139*61046927SAndroid Build Coastguard WorkerGL buffers in the same BO. Interestingly, the deletes of the temporary buffers 140*61046927SAndroid Build Coastguard Workeralways happen at the end of the next frame. 141*61046927SAndroid Build Coastguard Worker 142*61046927SAndroid Build Coastguard WorkerEuro Truck Simulator 143*61046927SAndroid Build Coastguard Worker==================== 144*61046927SAndroid Build Coastguard Worker 145*61046927SAndroid Build Coastguard Worker.. code-block:: text 146*61046927SAndroid Build Coastguard Worker 147*61046927SAndroid Build Coastguard Worker [usage of VBO 14,15] 148*61046927SAndroid Build Coastguard Worker [...] 149*61046927SAndroid Build Coastguard Worker 885199 glXSwapBuffers(dpy = 0x379a3e0, drawable = 20971527) 150*61046927SAndroid Build Coastguard Worker 885203 glInvalidateBufferData(buffer = 14) 151*61046927SAndroid Build Coastguard Worker 885204 glInvalidateBufferData(buffer = 15) 152*61046927SAndroid Build Coastguard Worker [...] 153*61046927SAndroid Build Coastguard Worker 889330 glXSwapBuffers(dpy = 0x379a3e0, drawable = 20971527) 154*61046927SAndroid Build Coastguard Worker 889334 glInvalidateBufferData(buffer = 12) 155*61046927SAndroid Build Coastguard Worker 889335 glInvalidateBufferData(buffer = 16) 156*61046927SAndroid Build Coastguard Worker [...] 157*61046927SAndroid Build Coastguard Worker 893461 glXSwapBuffers(dpy = 0x379a3e0, drawable = 20971527) 158*61046927SAndroid Build Coastguard Worker 893462 glClientWaitSync(sync = 0x77eee10, flags = 0x0, timeout = 0) = GL_ALREADY_SIGNALED 159*61046927SAndroid Build Coastguard Worker 893463 glDeleteSync(sync = 0x780a630) 160*61046927SAndroid Build Coastguard Worker 893464 glFenceSync(condition = GL_SYNC_GPU_COMMANDS_COMPLETE, flags = 0) = 0x78ec730 161*61046927SAndroid Build Coastguard Worker 893465 glInvalidateBufferData(buffer = 13) 162*61046927SAndroid Build Coastguard Worker 893466 glInvalidateBufferData(buffer = 17) 163*61046927SAndroid Build Coastguard Worker 893505 glBindBuffer(target = GL_COPY_READ_BUFFER, buffer = 14) 164*61046927SAndroid Build Coastguard Worker 893506 glMapBufferRange(target = GL_COPY_READ_BUFFER, offset = 0, length = 788, access = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT) = 0x7b034efd1000 165*61046927SAndroid Build Coastguard Worker 893508 glUnmapBuffer(target = GL_COPY_READ_BUFFER) = GL_TRUE 166*61046927SAndroid Build Coastguard Worker 893509 glBindBuffer(target = GL_COPY_READ_BUFFER, buffer = 15) 167*61046927SAndroid Build Coastguard Worker 893510 glMapBufferRange(target = GL_COPY_READ_BUFFER, offset = 0, length = 32, access = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT) = 0x7b034e5df000 168*61046927SAndroid Build Coastguard Worker 893512 glUnmapBuffer(target = GL_COPY_READ_BUFFER) = GL_TRUE 169*61046927SAndroid Build Coastguard Worker 893532 glBindVertexBuffers(first = 0, count = 2, buffers = {10, 15}, offsets = {0, 0}, strides = {52, 16}) 170*61046927SAndroid Build Coastguard Worker 893552 glDrawElementsInstancedBaseVertex(mode = GL_TRIANGLES, count = 18, type = GL_UNSIGNED_SHORT, indices = 0x13f280, instancecount = 1, basevertex = 25131) 171*61046927SAndroid Build Coastguard Worker 893609 glDrawArrays(mode = GL_TRIANGLES, first = 0, count = 6) 172*61046927SAndroid Build Coastguard Worker 893732 glBindVertexBuffers(first = 0, count = 1, buffers = &14, offsets = &0, strides = &48) 173*61046927SAndroid Build Coastguard Worker 893733 glBindBuffer(target = GL_ELEMENT_ARRAY_BUFFER, buffer = 14) 174*61046927SAndroid Build Coastguard Worker 893744 glDrawElementsBaseVertex(mode = GL_TRIANGLES, count = 6, type = GL_UNSIGNED_SHORT, indices = 0xf0, basevertex = 0) 175*61046927SAndroid Build Coastguard Worker 893759 glDrawElementsBaseVertex(mode = GL_TRIANGLES, count = 24, type = GL_UNSIGNED_SHORT, indices = 0x2e0, basevertex = 6) 176*61046927SAndroid Build Coastguard Worker 893786 glDrawElementsBaseVertex(mode = GL_TRIANGLES, count = 600, type = GL_UNSIGNED_SHORT, indices = 0xe87b0, basevertex = 21515) 177*61046927SAndroid Build Coastguard Worker 893822 glDrawArrays(mode = GL_TRIANGLES, first = 0, count = 6) 178*61046927SAndroid Build Coastguard Worker 893845 glBindBuffer(target = GL_COPY_READ_BUFFER, buffer = 14) 179*61046927SAndroid Build Coastguard Worker 893846 glMapBufferRange(target = GL_COPY_READ_BUFFER, offset = 788, length = 788, access = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT) = 0x7b034efd1314 180*61046927SAndroid Build Coastguard Worker 893848 glUnmapBuffer(target = GL_COPY_READ_BUFFER) = GL_TRUE 181*61046927SAndroid Build Coastguard Worker 893886 glDrawElementsInstancedBaseVertex(mode = GL_TRIANGLES, count = 18, type = GL_UNSIGNED_SHORT, indices = 0x13f280, instancecount = 1, basevertex = 25131) 182*61046927SAndroid Build Coastguard Worker 893943 glDrawArrays(mode = GL_TRIANGLES, first = 0, count = 6) 183*61046927SAndroid Build Coastguard Worker 184*61046927SAndroid Build Coastguard WorkerAt the start of this frame, buffer 14 and 15 haven't been used in the previous 2 185*61046927SAndroid Build Coastguard Workerframes, and the :ext:`GL_ARB_sync` fence has ensured that the GPU has at least started 186*61046927SAndroid Build Coastguard Workerframe n-1 as the CPU starts the current frame. The first map is ``offset = 0, 187*61046927SAndroid Build Coastguard WorkerINVALIDATE_BUFFER | UNSYNCHRONIZED``, which suggests that the driver should 188*61046927SAndroid Build Coastguard Workerreallocate storage for the mapping even in the ``UNSYNCHRONIZED`` case, except 189*61046927SAndroid Build Coastguard Workerthat the buffer is definitely going to be idle, making reallocation unnecessary 190*61046927SAndroid Build Coastguard Worker(you may need to empty your valid range, though, to prevent unnecessary batch 191*61046927SAndroid Build Coastguard Workerflushes). 192*61046927SAndroid Build Coastguard Worker 193*61046927SAndroid Build Coastguard WorkerAlso note the use of a totally unrelated binding point for the mapping of the 194*61046927SAndroid Build Coastguard Workervertex array -- you can't effectively use it as a hint for any buffer placement 195*61046927SAndroid Build Coastguard Workerin memory. The game does also use ``glCopyBufferSubData()``, but only on a 196*61046927SAndroid Build Coastguard Workerdifferent buffer. 197*61046927SAndroid Build Coastguard Worker 198*61046927SAndroid Build Coastguard Worker 199*61046927SAndroid Build Coastguard WorkerPlague Inc 200*61046927SAndroid Build Coastguard Worker========== 201*61046927SAndroid Build Coastguard Worker 202*61046927SAndroid Build Coastguard Worker.. code-block:: text 203*61046927SAndroid Build Coastguard Worker 204*61046927SAndroid Build Coastguard Worker 1640732 glXSwapBuffers(dpy = 0xb218f20, drawable = 23068674) 205*61046927SAndroid Build Coastguard Worker 1640733 glClientWaitSync(sync = 0xb4141430, flags = 0x0, timeout = 0) = GL_ALREADY_SIGNALED 206*61046927SAndroid Build Coastguard Worker 1640734 glDeleteSync(sync = 0xb4141430) 207*61046927SAndroid Build Coastguard Worker 1640735 glFenceSync(condition = GL_SYNC_GPU_COMMANDS_COMPLETE, flags = 0) = 0xb4141430 208*61046927SAndroid Build Coastguard Worker 209*61046927SAndroid Build Coastguard Worker 1640780 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 78) 210*61046927SAndroid Build Coastguard Worker 1640787 glBindBuffer(target = GL_ELEMENT_ARRAY_BUFFER, buffer = 79) 211*61046927SAndroid Build Coastguard Worker 1640788 glDrawElements(mode = GL_TRIANGLES, count = 9636, type = GL_UNSIGNED_SHORT, indices = NULL) 212*61046927SAndroid Build Coastguard Worker 1640795 glDrawElements(mode = GL_TRIANGLES, count = 9636, type = GL_UNSIGNED_SHORT, indices = NULL) 213*61046927SAndroid Build Coastguard Worker 1640813 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 1096) 214*61046927SAndroid Build Coastguard Worker 1640814 glMapBufferRange(target = GL_COPY_WRITE_BUFFER, offset = 0, length = 67584, access = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_UNSYNCHRONIZED_BIT) = 0xbfef4000 215*61046927SAndroid Build Coastguard Worker 1640815 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 1091) 216*61046927SAndroid Build Coastguard Worker 1640816 glMapBufferRange(target = GL_COPY_WRITE_BUFFER, offset = 0, length = 12, access = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_UNSYNCHRONIZED_BIT) = 0xc3998000 217*61046927SAndroid Build Coastguard Worker 1640817 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 1096) 218*61046927SAndroid Build Coastguard Worker 1640819 glFlushMappedBufferRange(target = GL_COPY_WRITE_BUFFER, offset = 0, length = 352) 219*61046927SAndroid Build Coastguard Worker 1640820 glUnmapBuffer(target = GL_COPY_WRITE_BUFFER) = GL_TRUE 220*61046927SAndroid Build Coastguard Worker 1640821 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 1091) 221*61046927SAndroid Build Coastguard Worker 1640823 glFlushMappedBufferRange(target = GL_COPY_WRITE_BUFFER, offset = 0, length = 12) 222*61046927SAndroid Build Coastguard Worker 1640824 glUnmapBuffer(target = GL_COPY_WRITE_BUFFER) = GL_TRUE 223*61046927SAndroid Build Coastguard Worker 1640825 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 1096) 224*61046927SAndroid Build Coastguard Worker 1640831 glBindBuffer(target = GL_ELEMENT_ARRAY_BUFFER, buffer = 1091) 225*61046927SAndroid Build Coastguard Worker 1640832 glDrawElements(mode = GL_TRIANGLES, count = 6, type = GL_UNSIGNED_SHORT, indices = NULL) 226*61046927SAndroid Build Coastguard Worker 227*61046927SAndroid Build Coastguard Worker 1640847 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 1096) 228*61046927SAndroid Build Coastguard Worker 1640848 glMapBufferRange(target = GL_COPY_WRITE_BUFFER, offset = 352, length = 67584, access = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_UNSYNCHRONIZED_BIT) = 0xbfef4160 229*61046927SAndroid Build Coastguard Worker 1640849 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 1091) 230*61046927SAndroid Build Coastguard Worker 1640850 glMapBufferRange(target = GL_COPY_WRITE_BUFFER, offset = 88, length = 12, access = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_UNSYNCHRONIZED_BIT) = 0xc3998058 231*61046927SAndroid Build Coastguard Worker 1640851 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 1096) 232*61046927SAndroid Build Coastguard Worker 1640853 glFlushMappedBufferRange(target = GL_COPY_WRITE_BUFFER, offset = 0, length = 352) 233*61046927SAndroid Build Coastguard Worker 1640854 glUnmapBuffer(target = GL_COPY_WRITE_BUFFER) = GL_TRUE 234*61046927SAndroid Build Coastguard Worker 1640855 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 1091) 235*61046927SAndroid Build Coastguard Worker 1640857 glFlushMappedBufferRange(target = GL_COPY_WRITE_BUFFER, offset = 0, length = 12) 236*61046927SAndroid Build Coastguard Worker 1640858 glUnmapBuffer(target = GL_COPY_WRITE_BUFFER) = GL_TRUE 237*61046927SAndroid Build Coastguard Worker 1640863 glDrawElementsBaseVertex(mode = GL_TRIANGLES, count = 6, type = GL_UNSIGNED_SHORT, indices = 0x58, basevertex = 4) 238*61046927SAndroid Build Coastguard Worker 239*61046927SAndroid Build Coastguard WorkerAt the start of this frame, the VBOs haven't been used in about 6 frames, and 240*61046927SAndroid Build Coastguard Workerthe :ext:`GL_ARB_sync` fence has ensured that the GPU has started frame n-1. 241*61046927SAndroid Build Coastguard Worker 242*61046927SAndroid Build Coastguard WorkerNote the use of ``glFlushMappedBufferRange()`` on a small fraction of the size 243*61046927SAndroid Build Coastguard Workerof the VBO -- it is important that a blitting driver make use of the flush 244*61046927SAndroid Build Coastguard Workerranges when in explicit mode. 245*61046927SAndroid Build Coastguard Worker 246*61046927SAndroid Build Coastguard WorkerDarkest Dungeon 247*61046927SAndroid Build Coastguard Worker=============== 248*61046927SAndroid Build Coastguard Worker 249*61046927SAndroid Build Coastguard Worker.. code-block:: text 250*61046927SAndroid Build Coastguard Worker 251*61046927SAndroid Build Coastguard Worker 938384 glXSwapBuffers(dpy = 0x377fcd0, drawable = 23068692) 252*61046927SAndroid Build Coastguard Worker 253*61046927SAndroid Build Coastguard Worker 938385 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 2) 254*61046927SAndroid Build Coastguard Worker 938386 glBufferData(target = GL_ARRAY_BUFFER, size = 1048576, data = NULL, usage = GL_STREAM_DRAW) 255*61046927SAndroid Build Coastguard Worker 938511 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 2) 256*61046927SAndroid Build Coastguard Worker 938512 glMapBufferRange(target = GL_ARRAY_BUFFER, offset = 0, length = 1048576, access = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_UNSYNCHRONIZED_BIT) = 0x7a73fcaa7000 257*61046927SAndroid Build Coastguard Worker 938514 glFlushMappedBufferRange(target = GL_ARRAY_BUFFER, offset = 0, length = 512) 258*61046927SAndroid Build Coastguard Worker 938515 glUnmapBuffer(target = GL_ARRAY_BUFFER) = GL_TRUE 259*61046927SAndroid Build Coastguard Worker 938523 glBindBuffer(target = GL_ELEMENT_ARRAY_BUFFER, buffer = 1) 260*61046927SAndroid Build Coastguard Worker 938524 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 2) 261*61046927SAndroid Build Coastguard Worker 938525 glDrawElements(mode = GL_TRIANGLES, count = 24, type = GL_UNSIGNED_SHORT, indices = NULL) 262*61046927SAndroid Build Coastguard Worker 938527 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 2) 263*61046927SAndroid Build Coastguard Worker 938528 glMapBufferRange(target = GL_ARRAY_BUFFER, offset = 0, length = 1048576, access = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_UNSYNCHRONIZED_BIT) = 0x7a73fcaa7000 264*61046927SAndroid Build Coastguard Worker 938530 glFlushMappedBufferRange(target = GL_ARRAY_BUFFER, offset = 512, length = 512) 265*61046927SAndroid Build Coastguard Worker 938531 glUnmapBuffer(target = GL_ARRAY_BUFFER) = GL_TRUE 266*61046927SAndroid Build Coastguard Worker 938539 glBindBuffer(target = GL_ELEMENT_ARRAY_BUFFER, buffer = 1) 267*61046927SAndroid Build Coastguard Worker 938540 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 2) 268*61046927SAndroid Build Coastguard Worker 938541 glDrawElements(mode = GL_TRIANGLES, count = 24, type = GL_UNSIGNED_SHORT, indices = 0x30) 269*61046927SAndroid Build Coastguard Worker [... more maps and draws at increasing offsets] 270*61046927SAndroid Build Coastguard Worker 271*61046927SAndroid Build Coastguard WorkerInteresting note for this game, after the initial ``glBufferData()`` in the 272*61046927SAndroid Build Coastguard Workerframe to reallocate the storage, it unsync maps the whole buffer each time, and 273*61046927SAndroid Build Coastguard Workerjust changes which region it flushes. The same GL buffer name is used in every 274*61046927SAndroid Build Coastguard Workerframe. 275*61046927SAndroid Build Coastguard Worker 276*61046927SAndroid Build Coastguard WorkerTabletop Simulator 277*61046927SAndroid Build Coastguard Worker================== 278*61046927SAndroid Build Coastguard Worker 279*61046927SAndroid Build Coastguard Worker.. code-block:: text 280*61046927SAndroid Build Coastguard Worker 281*61046927SAndroid Build Coastguard Worker 1287594 glXSwapBuffers(dpy = 0x3e10810, drawable = 23068692) 282*61046927SAndroid Build Coastguard Worker 1287595 glClientWaitSync(sync = 0x7abf554e37b0, flags = 0x0, timeout = 0) = GL_ALREADY_SIGNALED 283*61046927SAndroid Build Coastguard Worker 1287596 glDeleteSync(sync = 0x7abf554e37b0) 284*61046927SAndroid Build Coastguard Worker 1287597 glFenceSync(condition = GL_SYNC_GPU_COMMANDS_COMPLETE, flags = 0) = 0x7abf56647490 285*61046927SAndroid Build Coastguard Worker 286*61046927SAndroid Build Coastguard Worker 1287614 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 480) 287*61046927SAndroid Build Coastguard Worker 1287615 glMapBufferRange(target = GL_COPY_WRITE_BUFFER, offset = 0, length = 384, access = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_UNSYNCHRONIZED_BIT) = 0x7abf2e79a000 288*61046927SAndroid Build Coastguard Worker 1287642 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 614) 289*61046927SAndroid Build Coastguard Worker 1287650 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 5) 290*61046927SAndroid Build Coastguard Worker 1287651 glBufferSubData(target = GL_COPY_WRITE_BUFFER, offset = 0, size = 1088, data = blob(1088)) 291*61046927SAndroid Build Coastguard Worker 1287652 glBindBuffer(target = GL_ELEMENT_ARRAY_BUFFER, buffer = 615) 292*61046927SAndroid Build Coastguard Worker 1287653 glDrawElements(mode = GL_TRIANGLES, count = 1788, type = GL_UNSIGNED_SHORT, indices = NULL) 293*61046927SAndroid Build Coastguard Worker [... more draw calls] 294*61046927SAndroid Build Coastguard Worker 1289055 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 480) 295*61046927SAndroid Build Coastguard Worker 1289057 glFlushMappedBufferRange(target = GL_COPY_WRITE_BUFFER, offset = 0, length = 384) 296*61046927SAndroid Build Coastguard Worker 1289058 glUnmapBuffer(target = GL_COPY_WRITE_BUFFER) = GL_TRUE 297*61046927SAndroid Build Coastguard Worker 1289059 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 480) 298*61046927SAndroid Build Coastguard Worker 1289066 glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 12, count = 4) 299*61046927SAndroid Build Coastguard Worker 1289068 glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 8, count = 4) 300*61046927SAndroid Build Coastguard Worker 1289553 glXSwapBuffers(dpy = 0x3e10810, drawable = 23068692) 301*61046927SAndroid Build Coastguard Worker 302*61046927SAndroid Build Coastguard WorkerIn this app, buffer 480 gets used like this every other frame. The :ext:`GL_ARB_sync` 303*61046927SAndroid Build Coastguard Workerfence ensures that frame n-1 has started on the GPU before CPU work starts on 304*61046927SAndroid Build Coastguard Workerthe current frame, so the unsynchronized access to the buffers is safe. 305*61046927SAndroid Build Coastguard Worker 306*61046927SAndroid Build Coastguard WorkerHollow Knight 307*61046927SAndroid Build Coastguard Worker============= 308*61046927SAndroid Build Coastguard Worker 309*61046927SAndroid Build Coastguard Worker.. code-block:: text 310*61046927SAndroid Build Coastguard Worker 311*61046927SAndroid Build Coastguard Worker 1873034 glXSwapBuffers(dpy = 0x28609d0, drawable = 23068692) 312*61046927SAndroid Build Coastguard Worker 1873035 glClientWaitSync(sync = 0x7b1a5ca6e130, flags = 0x0, timeout = 0) = GL_ALREADY_SIGNALED 313*61046927SAndroid Build Coastguard Worker 1873036 glDeleteSync(sync = 0x7b1a5ca6e130) 314*61046927SAndroid Build Coastguard Worker 1873037 glFenceSync(condition = GL_SYNC_GPU_COMMANDS_COMPLETE, flags = 0) = 0x7b1a5ca6e130 315*61046927SAndroid Build Coastguard Worker 1873038 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 29) 316*61046927SAndroid Build Coastguard Worker 1873039 glMapBufferRange(target = GL_COPY_WRITE_BUFFER, offset = 0, length = 8640, access = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_UNSYNCHRONIZED_BIT) = 0x7b1a04c7e000 317*61046927SAndroid Build Coastguard Worker 1873040 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 30) 318*61046927SAndroid Build Coastguard Worker 1873041 glMapBufferRange(target = GL_COPY_WRITE_BUFFER, offset = 0, length = 720, access = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_UNSYNCHRONIZED_BIT) = 0x7b1a07430000 319*61046927SAndroid Build Coastguard Worker 1873065 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 29) 320*61046927SAndroid Build Coastguard Worker 1873067 glFlushMappedBufferRange(target = GL_COPY_WRITE_BUFFER, offset = 0, length = 8640) 321*61046927SAndroid Build Coastguard Worker 1873068 glUnmapBuffer(target = GL_COPY_WRITE_BUFFER) = GL_TRUE 322*61046927SAndroid Build Coastguard Worker 1873069 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 30) 323*61046927SAndroid Build Coastguard Worker 1873071 glFlushMappedBufferRange(target = GL_COPY_WRITE_BUFFER, offset = 0, length = 720) 324*61046927SAndroid Build Coastguard Worker 1873072 glUnmapBuffer(target = GL_COPY_WRITE_BUFFER) = GL_TRUE 325*61046927SAndroid Build Coastguard Worker 1873073 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 29) 326*61046927SAndroid Build Coastguard Worker 1873074 glMapBufferRange(target = GL_COPY_WRITE_BUFFER, offset = 8640, length = 576, access = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_UNSYNCHRONIZED_BIT) = 0x7b1a04c801c0 327*61046927SAndroid Build Coastguard Worker 1873075 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 30) 328*61046927SAndroid Build Coastguard Worker 1873076 glMapBufferRange(target = GL_COPY_WRITE_BUFFER, offset = 720, length = 72, access = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_UNSYNCHRONIZED_BIT) = 0x7b1a074302d0 329*61046927SAndroid Build Coastguard Worker 1873077 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 29) 330*61046927SAndroid Build Coastguard Worker 1873079 glFlushMappedBufferRange(target = GL_COPY_WRITE_BUFFER, offset = 0, length = 576) 331*61046927SAndroid Build Coastguard Worker 1873080 glUnmapBuffer(target = GL_COPY_WRITE_BUFFER) = GL_TRUE 332*61046927SAndroid Build Coastguard Worker 1873081 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 30) 333*61046927SAndroid Build Coastguard Worker 1873083 glFlushMappedBufferRange(target = GL_COPY_WRITE_BUFFER, offset = 0, length = 72) 334*61046927SAndroid Build Coastguard Worker 1873084 glUnmapBuffer(target = GL_COPY_WRITE_BUFFER) = GL_TRUE 335*61046927SAndroid Build Coastguard Worker 1873085 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 29) 336*61046927SAndroid Build Coastguard Worker 1873096 glBindBuffer(target = GL_ELEMENT_ARRAY_BUFFER, buffer = 30) 337*61046927SAndroid Build Coastguard Worker 1873097 glDrawElementsBaseVertex(mode = GL_TRIANGLES, count = 36, type = GL_UNSIGNED_SHORT, indices = 0x2d0, basevertex = 240) 338*61046927SAndroid Build Coastguard Worker 339*61046927SAndroid Build Coastguard WorkerIn this app, buffer 29/30 get used like this starting from offset 0 every other 340*61046927SAndroid Build Coastguard Workerframe. The :ext:`GL_ARB_sync` fence is used to make sure that the GPU has reached the 341*61046927SAndroid Build Coastguard Workerstart of the previous frame before we go unsynchronized writing over the n-2 342*61046927SAndroid Build Coastguard Workerframe's buffer. 343*61046927SAndroid Build Coastguard Worker 344*61046927SAndroid Build Coastguard WorkerBorderlands 2 345*61046927SAndroid Build Coastguard Worker============= 346*61046927SAndroid Build Coastguard Worker 347*61046927SAndroid Build Coastguard Worker.. code-block:: text 348*61046927SAndroid Build Coastguard Worker 349*61046927SAndroid Build Coastguard Worker 3561998 glFlush() 350*61046927SAndroid Build Coastguard Worker 3562004 glXSwapBuffers(dpy = 0xbaf0f90, drawable = 23068705) 351*61046927SAndroid Build Coastguard Worker 3562006 glClientWaitSync(sync = 0x231c2ab0, flags = GL_SYNC_FLUSH_COMMANDS_BIT, timeout = 10000000000) = GL_ALREADY_SIGNALED 352*61046927SAndroid Build Coastguard Worker 3562007 glDeleteSync(sync = 0x231c2ab0) 353*61046927SAndroid Build Coastguard Worker 3562008 glFenceSync(condition = GL_SYNC_GPU_COMMANDS_COMPLETE, flags = 0) = 0x231aadc0 354*61046927SAndroid Build Coastguard Worker 355*61046927SAndroid Build Coastguard Worker 3562050 glBindBufferARB(target = GL_ARRAY_BUFFER, buffer = 1193) 356*61046927SAndroid Build Coastguard Worker 3562051 glMapBufferRange(target = GL_ARRAY_BUFFER, offset = 0, length = 1792, access = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT) = 0xde056000 357*61046927SAndroid Build Coastguard Worker 3562053 glUnmapBufferARB(target = GL_ARRAY_BUFFER) = GL_TRUE 358*61046927SAndroid Build Coastguard Worker 3562054 glBindBufferARB(target = GL_ARRAY_BUFFER, buffer = 1194) 359*61046927SAndroid Build Coastguard Worker 3562055 glMapBufferRange(target = GL_ARRAY_BUFFER, offset = 0, length = 1280, access = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT) = 0xd9426000 360*61046927SAndroid Build Coastguard Worker 3562057 glUnmapBufferARB(target = GL_ARRAY_BUFFER) = GL_TRUE 361*61046927SAndroid Build Coastguard Worker [... unrelated draws] 362*61046927SAndroid Build Coastguard Worker 3563051 glBindBufferARB(target = GL_ARRAY_BUFFER, buffer = 1193) 363*61046927SAndroid Build Coastguard Worker 3563064 glBindBufferARB(target = GL_ELEMENT_ARRAY_BUFFER, buffer = 875) 364*61046927SAndroid Build Coastguard Worker 3563065 glDrawElementsInstancedARB(mode = GL_TRIANGLES, count = 72, type = GL_UNSIGNED_SHORT, indices = NULL, instancecount = 28) 365*61046927SAndroid Build Coastguard Worker 366*61046927SAndroid Build Coastguard WorkerThe :ext:`GL_ARB_sync` fence ensures that the GPU has started frame n-1 before the CPU 367*61046927SAndroid Build Coastguard Workerstarts on the current frame. 368*61046927SAndroid Build Coastguard Worker 369*61046927SAndroid Build Coastguard WorkerThis sequence of buffer uploads appears in each frame with the same buffer 370*61046927SAndroid Build Coastguard Workernames, so you do need to handle the ``GL_MAP_INVALIDATE_BUFFER_BIT`` as a 371*61046927SAndroid Build Coastguard Workerreallocate if the buffer is GPU-busy (it wasn't in this trace capture) to avoid 372*61046927SAndroid Build Coastguard Workerstalls on the n-1 frame completing. 373*61046927SAndroid Build Coastguard Worker 374*61046927SAndroid Build Coastguard WorkerNote that this is just one small buffer. Most of the vertex data goes through a 375*61046927SAndroid Build Coastguard Worker``glBufferSubData()``/``glDraw*()`` path with the VBO used across multiple 376*61046927SAndroid Build Coastguard Workerframes, with a ``glBufferData()`` when needing to wrap. 377*61046927SAndroid Build Coastguard Worker 378*61046927SAndroid Build Coastguard WorkerBuffer mapping conclusions 379*61046927SAndroid Build Coastguard Worker-------------------------- 380*61046927SAndroid Build Coastguard Worker 381*61046927SAndroid Build Coastguard Worker* Non-blitting drivers must track the valid range of a freshly allocated buffer 382*61046927SAndroid Build Coastguard Worker as it gets uploaded in ``pipe_transfer_map()`` and avoid stalling on the GPU 383*61046927SAndroid Build Coastguard Worker when mapping an undefined portion of the buffer when ``glBufferSubData()`` is 384*61046927SAndroid Build Coastguard Worker interleaved with drawing. 385*61046927SAndroid Build Coastguard Worker 386*61046927SAndroid Build Coastguard Worker* Non-blitting drivers must reallocate storage on ``glBufferData(NULL)`` so that 387*61046927SAndroid Build Coastguard Worker the following ``glBufferSubData()`` won't stall. That ``glBufferData(NULL)`` 388*61046927SAndroid Build Coastguard Worker call will appear in the driver as an ``invalidate_resource()`` call if 389*61046927SAndroid Build Coastguard Worker ``PIPE_CAP_INVALIDATE_BUFFER`` is available. (If that flag is not set, then 390*61046927SAndroid Build Coastguard Worker mesa/st will create a new pipe_resource for you). Storage reallocation may be 391*61046927SAndroid Build Coastguard Worker skipped if you for some reason know that the buffer is idle, in which case you 392*61046927SAndroid Build Coastguard Worker can just empty the valid region. 393*61046927SAndroid Build Coastguard Worker 394*61046927SAndroid Build Coastguard Worker* Blitting drivers must use the ``transfer_flush_region()`` region 395*61046927SAndroid Build Coastguard Worker instead of the mapped range when ``PIPE_MAP_FLUSH_EXPLICIT`` is set, to avoid 396*61046927SAndroid Build Coastguard Worker blitting too much data. (When that bit is unset, you just blit the whole 397*61046927SAndroid Build Coastguard Worker mapped range at unmap time.) 398*61046927SAndroid Build Coastguard Worker 399*61046927SAndroid Build Coastguard Worker* Buffer valid range tracking in non-blitting drivers must use the 400*61046927SAndroid Build Coastguard Worker ``transfer_flush_region()`` region instead of the mapped range when 401*61046927SAndroid Build Coastguard Worker ``PIPE_MAP_FLUSH_EXPLICIT`` is set, to avoid excess stalls. 402*61046927SAndroid Build Coastguard Worker 403*61046927SAndroid Build Coastguard Worker* Buffer valid range tracking doesn't need to be fancy, "number of bytes 404*61046927SAndroid Build Coastguard Worker valid starting from 0" is sufficient for all examples found. 405*61046927SAndroid Build Coastguard Worker 406*61046927SAndroid Build Coastguard Worker* Use the ``util_debug_callback`` to report stalls on buffer mapping to ease 407*61046927SAndroid Build Coastguard Worker debug. 408*61046927SAndroid Build Coastguard Worker 409*61046927SAndroid Build Coastguard Worker* Buffer binding points are not useful for tuning buffer placement (See all the 410*61046927SAndroid Build Coastguard Worker ``PIPE_COPY_WRITE_BUFFER`` instances), you have to track the actual usage 411*61046927SAndroid Build Coastguard Worker history of a GL BO name. mesa/st does this for optimizing its state updates 412*61046927SAndroid Build Coastguard Worker on reallocation in the ``!PIPE_CAP_INVALIDATE_BUFFER`` case, and if you set 413*61046927SAndroid Build Coastguard Worker ``PIPE_CAP_INVALIDATE_BUFFER`` then you have to flag your own internal state 414*61046927SAndroid Build Coastguard Worker updates (VBO addresses, XFB addresses, texture buffer addresses, etc.) on 415*61046927SAndroid Build Coastguard Worker reallocation based on usage history. 416