mirror of
https://github.com/elwrcl/intel-hard-graphics.git
synced 2026-10-31 19:08:03 +03:00
init
This commit is contained in:
12511 files changed
+6156641
No files matched your search
@@ -0,0 +1,415 @@
|
||||
Buffer mapping patterns
|
||||
-----------------------
|
||||
|
||||
There are two main strategies the driver has for CPU access to GL buffer
|
||||
objects. One is that the GL calls allocate temporary storage and blit to the GPU
|
||||
at
|
||||
``glBufferSubData()``/``glBufferData()``/``glFlushMappedBufferRange()``/``glUnmapBuffer()``
|
||||
time. This makes the behavior easily match. However, this may be more costly
|
||||
than direct mapping of the GL BO on some platforms, and is essentially not
|
||||
available to tiling GPUs (since tiling involves running through the command
|
||||
stream multiple times). Thus, GL has additional interfaces to help make it so
|
||||
apps can directly access memory while avoiding implicit blocking on the GPU
|
||||
rendering from those BOs.
|
||||
|
||||
Rendering engines have a variety of knobs to set on those GL interfaces for data
|
||||
upload, and as a whole they seem to take just about every path available. Let's
|
||||
look at some examples to see how they might constrain GL driver buffer upload
|
||||
behavior.
|
||||
|
||||
Portal 2
|
||||
========
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
1030842 glXSwapBuffers(dpy = 0x82a8000, drawable = 20971540)
|
||||
1030876 glBufferDataARB(target = GL_ELEMENT_ARRAY_BUFFER, size = 65536, data = NULL, usage = GL_DYNAMIC_DRAW)
|
||||
1030877 glBufferSubData(target = GL_ELEMENT_ARRAY_BUFFER, offset = 0, size = 576, data = blob(576))
|
||||
1030896 glDrawRangeElementsBaseVertex(mode = GL_TRIANGLES, start = 0, end = 526, count = 252, type = GL_UNSIGNED_SHORT, indices = NULL, basevertex = 0)
|
||||
1030915 glDrawRangeElementsBaseVertex(mode = GL_TRIANGLES, start = 0, end = 19657, count = 36, type = GL_UNSIGNED_SHORT, indices = 0x1f8, basevertex = 0)
|
||||
1030917 glBufferDataARB(target = GL_ARRAY_BUFFER, size = 1572864, data = NULL, usage = GL_DYNAMIC_DRAW)
|
||||
1030918 glBufferSubData(target = GL_ARRAY_BUFFER, offset = 0, size = 128, data = blob(128))
|
||||
1030919 glBufferSubData(target = GL_ELEMENT_ARRAY_BUFFER, offset = 576, size = 12, data = blob(12))
|
||||
1030936 glDrawRangeElementsBaseVertex(mode = GL_TRIANGLES, start = 0, end = 3, count = 6, type = GL_UNSIGNED_SHORT, indices = 0x240, basevertex = 0)
|
||||
1030937 glBufferSubData(target = GL_ARRAY_BUFFER, offset = 128, size = 128, data = blob(128))
|
||||
1030938 glBufferSubData(target = GL_ELEMENT_ARRAY_BUFFER, offset = 588, size = 12, data = blob(12))
|
||||
1030940 glDrawRangeElementsBaseVertex(mode = GL_TRIANGLES, start = 4, end = 7, count = 6, type = GL_UNSIGNED_SHORT, indices = 0x24c, basevertex = 0)
|
||||
[... repeated draws at increasing offsets]
|
||||
1033097 glXSwapBuffers(dpy = 0x82a8000, drawable = 20971540)
|
||||
|
||||
From this sequence, we can see that it is important that the driver either
|
||||
implement ``glBufferSubData()`` as a blit from a streaming uploader in sequence with
|
||||
the ``glDraw*()`` calls (a common behavior for non-tiled GPUs, particularly those with
|
||||
dedicated memory), or that you:
|
||||
|
||||
1) Track the valid range of the buffer so that you don't have to flush the draws
|
||||
and synchronize on each following ``glBufferSubData()``.
|
||||
|
||||
2) Reallocate the buffer storage on ``glBufferData`` so that your first
|
||||
``glBufferSubData()`` of the frame doesn't stall on the last frame's
|
||||
rendering completing.
|
||||
|
||||
You can't just empty your valid range on ``glBufferData()`` unless you know that
|
||||
the GPU access from the previous frame has completed. This pattern of
|
||||
incrementing ``glBufferSubData()`` offsets interleaved with draws from that data
|
||||
is common among newer Valve games.
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
[ during setup ]
|
||||
|
||||
679259 glGenBuffersARB(n = 1, buffers = &1314)
|
||||
679260 glBindBufferARB(target = GL_ELEMENT_ARRAY_BUFFER, buffer = 1314)
|
||||
679261 glBufferDataARB(target = GL_ELEMENT_ARRAY_BUFFER, size = 3072, data = NULL, usage = GL_STATIC_DRAW)
|
||||
679264 glMapBufferRange(target = GL_ELEMENT_ARRAY_BUFFER, offset = 0, length = 3072, access = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT) = 0xd7384000
|
||||
679269 glFlushMappedBufferRange(target = GL_ELEMENT_ARRAY_BUFFER, offset = 0, length = 3072)
|
||||
679270 glUnmapBuffer(target = GL_ELEMENT_ARRAY_BUFFER) = GL_TRUE
|
||||
|
||||
[... setup of other buffers on this binding point]
|
||||
|
||||
679343 glBindBufferARB(target = GL_ELEMENT_ARRAY_BUFFER, buffer = 1314)
|
||||
679344 glMapBufferRange(target = GL_ELEMENT_ARRAY_BUFFER, offset = 0, length = 768, access = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT) = 0xd7384000
|
||||
679346 glFlushMappedBufferRange(target = GL_ELEMENT_ARRAY_BUFFER, offset = 0, length = 768)
|
||||
679347 glUnmapBuffer(target = GL_ELEMENT_ARRAY_BUFFER) = GL_TRUE
|
||||
679348 glMapBufferRange(target = GL_ELEMENT_ARRAY_BUFFER, offset = 768, length = 768, access = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT) = 0xd7384300
|
||||
679350 glFlushMappedBufferRange(target = GL_ELEMENT_ARRAY_BUFFER, offset = 0, length = 768)
|
||||
679351 glUnmapBuffer(target = GL_ELEMENT_ARRAY_BUFFER) = GL_TRUE
|
||||
679352 glMapBufferRange(target = GL_ELEMENT_ARRAY_BUFFER, offset = 1536, length = 768, access = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT) = 0xd7384600
|
||||
679354 glFlushMappedBufferRange(target = GL_ELEMENT_ARRAY_BUFFER, offset = 0, length = 768)
|
||||
679355 glUnmapBuffer(target = GL_ELEMENT_ARRAY_BUFFER) = GL_TRUE
|
||||
679356 glMapBufferRange(target = GL_ELEMENT_ARRAY_BUFFER, offset = 2304, length = 768, access = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT) = 0xd7384900
|
||||
679358 glFlushMappedBufferRange(target = GL_ELEMENT_ARRAY_BUFFER, offset = 0, length = 768)
|
||||
679359 glUnmapBuffer(target = GL_ELEMENT_ARRAY_BUFFER) = GL_TRUE
|
||||
|
||||
[... setup completes and we start drawing later]
|
||||
|
||||
761845 glBindBufferARB(target = GL_ELEMENT_ARRAY_BUFFER, buffer = 1314)
|
||||
761846 glDrawRangeElementsBaseVertex(mode = GL_TRIANGLES, start = 0, end = 323, count = 384, type = GL_UNSIGNED_SHORT, indices = NULL, basevertex = 0)
|
||||
|
||||
This suggests that, for non-blitting drivers, resetting your "might be used on
|
||||
the GPU" range after a stall could save you a bunch of additional GPU stalls
|
||||
during setup.
|
||||
|
||||
Terraria
|
||||
========
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
167581 glXSwapBuffers(dpy = 0x3004630, drawable = 25165844)
|
||||
|
||||
167585 glBufferData(target = GL_ARRAY_BUFFER, size = 196608, data = NULL, usage = GL_STREAM_DRAW)
|
||||
167586 glBufferSubData(target = GL_ARRAY_BUFFER, offset = 0, size = 1728, data = blob(1728))
|
||||
167588 glDrawRangeElementsBaseVertex(mode = GL_TRIANGLES, start = 0, end = 71, count = 108, type = GL_UNSIGNED_SHORT, indices = NULL, basevertex = 0)
|
||||
167589 glBufferData(target = GL_ARRAY_BUFFER, size = 196608, data = NULL, usage = GL_STREAM_DRAW)
|
||||
167590 glBufferSubData(target = GL_ARRAY_BUFFER, offset = 0, size = 27456, data = blob(27456))
|
||||
167592 glDrawRangeElementsBaseVertex(mode = GL_TRIANGLES, start = 0, end = 7, count = 12, type = GL_UNSIGNED_SHORT, indices = NULL, basevertex = 0)
|
||||
167594 glDrawRangeElementsBaseVertex(mode = GL_TRIANGLES, start = 0, end = 3, count = 6, type = GL_UNSIGNED_SHORT, indices = NULL, basevertex = 8)
|
||||
167596 glDrawRangeElementsBaseVertex(mode = GL_TRIANGLES, start = 0, end = 3, count = 6, type = GL_UNSIGNED_SHORT, indices = NULL, basevertex = 12)
|
||||
[...]
|
||||
|
||||
In this game, we can see ``glBufferData()`` being used on the same array buffer
|
||||
throughout, to get new storage so that the ``glBufferSubData()`` doesn't cause
|
||||
synchronization.
|
||||
|
||||
Don't Starve
|
||||
============
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
7251917 glGenBuffers(n = 1, buffers = &115052)
|
||||
7251918 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 115052)
|
||||
7251919 glBufferData(target = GL_ARRAY_BUFFER, size = 144, data = blob(144), usage = GL_STREAM_DRAW)
|
||||
7251921 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 115052)
|
||||
7251928 glDrawArrays(mode = GL_TRIANGLES, first = 0, count = 6)
|
||||
7251930 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 114872)
|
||||
7251936 glDrawArrays(mode = GL_TRIANGLES, first = 0, count = 18)
|
||||
7251938 glGenBuffers(n = 1, buffers = &115053)
|
||||
7251939 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 115053)
|
||||
7251940 glBufferData(target = GL_ARRAY_BUFFER, size = 144, data = blob(144), usage = GL_STREAM_DRAW)
|
||||
7251942 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 115053)
|
||||
7251949 glDrawArrays(mode = GL_TRIANGLES, first = 0, count = 6)
|
||||
7251973 glXSwapBuffers(dpy = 0x86dd860, drawable = 20971540)
|
||||
[... drawing next frame]
|
||||
7252388 glDeleteBuffers(n = 1, buffers = &115052)
|
||||
7252389 glDeleteBuffers(n = 1, buffers = &115053)
|
||||
7252390 glXSwapBuffers(dpy = 0x86dd860, drawable = 20971540)
|
||||
|
||||
In this game we have a lot of tiny ``glBufferData()`` calls, suggesting that we
|
||||
could see working set wins and possibly CPU overhead reduction by packing small
|
||||
GL buffers in the same BO. Interestingly, the deletes of the temporary buffers
|
||||
always happen at the end of the next frame.
|
||||
|
||||
Euro Truck Simulator
|
||||
====================
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
[usage of VBO 14,15]
|
||||
[...]
|
||||
885199 glXSwapBuffers(dpy = 0x379a3e0, drawable = 20971527)
|
||||
885203 glInvalidateBufferData(buffer = 14)
|
||||
885204 glInvalidateBufferData(buffer = 15)
|
||||
[...]
|
||||
889330 glXSwapBuffers(dpy = 0x379a3e0, drawable = 20971527)
|
||||
889334 glInvalidateBufferData(buffer = 12)
|
||||
889335 glInvalidateBufferData(buffer = 16)
|
||||
[...]
|
||||
893461 glXSwapBuffers(dpy = 0x379a3e0, drawable = 20971527)
|
||||
893462 glClientWaitSync(sync = 0x77eee10, flags = 0x0, timeout = 0) = GL_ALREADY_SIGNALED
|
||||
893463 glDeleteSync(sync = 0x780a630)
|
||||
893464 glFenceSync(condition = GL_SYNC_GPU_COMMANDS_COMPLETE, flags = 0) = 0x78ec730
|
||||
893465 glInvalidateBufferData(buffer = 13)
|
||||
893466 glInvalidateBufferData(buffer = 17)
|
||||
893505 glBindBuffer(target = GL_COPY_READ_BUFFER, buffer = 14)
|
||||
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
|
||||
893508 glUnmapBuffer(target = GL_COPY_READ_BUFFER) = GL_TRUE
|
||||
893509 glBindBuffer(target = GL_COPY_READ_BUFFER, buffer = 15)
|
||||
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
|
||||
893512 glUnmapBuffer(target = GL_COPY_READ_BUFFER) = GL_TRUE
|
||||
893532 glBindVertexBuffers(first = 0, count = 2, buffers = {10, 15}, offsets = {0, 0}, strides = {52, 16})
|
||||
893552 glDrawElementsInstancedBaseVertex(mode = GL_TRIANGLES, count = 18, type = GL_UNSIGNED_SHORT, indices = 0x13f280, instancecount = 1, basevertex = 25131)
|
||||
893609 glDrawArrays(mode = GL_TRIANGLES, first = 0, count = 6)
|
||||
893732 glBindVertexBuffers(first = 0, count = 1, buffers = &14, offsets = &0, strides = &48)
|
||||
893733 glBindBuffer(target = GL_ELEMENT_ARRAY_BUFFER, buffer = 14)
|
||||
893744 glDrawElementsBaseVertex(mode = GL_TRIANGLES, count = 6, type = GL_UNSIGNED_SHORT, indices = 0xf0, basevertex = 0)
|
||||
893759 glDrawElementsBaseVertex(mode = GL_TRIANGLES, count = 24, type = GL_UNSIGNED_SHORT, indices = 0x2e0, basevertex = 6)
|
||||
893786 glDrawElementsBaseVertex(mode = GL_TRIANGLES, count = 600, type = GL_UNSIGNED_SHORT, indices = 0xe87b0, basevertex = 21515)
|
||||
893822 glDrawArrays(mode = GL_TRIANGLES, first = 0, count = 6)
|
||||
893845 glBindBuffer(target = GL_COPY_READ_BUFFER, buffer = 14)
|
||||
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
|
||||
893848 glUnmapBuffer(target = GL_COPY_READ_BUFFER) = GL_TRUE
|
||||
893886 glDrawElementsInstancedBaseVertex(mode = GL_TRIANGLES, count = 18, type = GL_UNSIGNED_SHORT, indices = 0x13f280, instancecount = 1, basevertex = 25131)
|
||||
893943 glDrawArrays(mode = GL_TRIANGLES, first = 0, count = 6)
|
||||
|
||||
At the start of this frame, buffer 14 and 15 haven't been used in the previous 2
|
||||
frames, and the :ext:`GL_ARB_sync` fence has ensured that the GPU has at least started
|
||||
frame n-1 as the CPU starts the current frame. The first map is ``offset = 0,
|
||||
INVALIDATE_BUFFER | UNSYNCHRONIZED``, which suggests that the driver should
|
||||
reallocate storage for the mapping even in the ``UNSYNCHRONIZED`` case, except
|
||||
that the buffer is definitely going to be idle, making reallocation unnecessary
|
||||
(you may need to empty your valid range, though, to prevent unnecessary batch
|
||||
flushes).
|
||||
|
||||
Also note the use of a totally unrelated binding point for the mapping of the
|
||||
vertex array -- you can't effectively use it as a hint for any buffer placement
|
||||
in memory. The game does also use ``glCopyBufferSubData()``, but only on a
|
||||
different buffer.
|
||||
|
||||
|
||||
Plague Inc
|
||||
==========
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
1640732 glXSwapBuffers(dpy = 0xb218f20, drawable = 23068674)
|
||||
1640733 glClientWaitSync(sync = 0xb4141430, flags = 0x0, timeout = 0) = GL_ALREADY_SIGNALED
|
||||
1640734 glDeleteSync(sync = 0xb4141430)
|
||||
1640735 glFenceSync(condition = GL_SYNC_GPU_COMMANDS_COMPLETE, flags = 0) = 0xb4141430
|
||||
|
||||
1640780 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 78)
|
||||
1640787 glBindBuffer(target = GL_ELEMENT_ARRAY_BUFFER, buffer = 79)
|
||||
1640788 glDrawElements(mode = GL_TRIANGLES, count = 9636, type = GL_UNSIGNED_SHORT, indices = NULL)
|
||||
1640795 glDrawElements(mode = GL_TRIANGLES, count = 9636, type = GL_UNSIGNED_SHORT, indices = NULL)
|
||||
1640813 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 1096)
|
||||
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
|
||||
1640815 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 1091)
|
||||
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
|
||||
1640817 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 1096)
|
||||
1640819 glFlushMappedBufferRange(target = GL_COPY_WRITE_BUFFER, offset = 0, length = 352)
|
||||
1640820 glUnmapBuffer(target = GL_COPY_WRITE_BUFFER) = GL_TRUE
|
||||
1640821 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 1091)
|
||||
1640823 glFlushMappedBufferRange(target = GL_COPY_WRITE_BUFFER, offset = 0, length = 12)
|
||||
1640824 glUnmapBuffer(target = GL_COPY_WRITE_BUFFER) = GL_TRUE
|
||||
1640825 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 1096)
|
||||
1640831 glBindBuffer(target = GL_ELEMENT_ARRAY_BUFFER, buffer = 1091)
|
||||
1640832 glDrawElements(mode = GL_TRIANGLES, count = 6, type = GL_UNSIGNED_SHORT, indices = NULL)
|
||||
|
||||
1640847 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 1096)
|
||||
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
|
||||
1640849 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 1091)
|
||||
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
|
||||
1640851 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 1096)
|
||||
1640853 glFlushMappedBufferRange(target = GL_COPY_WRITE_BUFFER, offset = 0, length = 352)
|
||||
1640854 glUnmapBuffer(target = GL_COPY_WRITE_BUFFER) = GL_TRUE
|
||||
1640855 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 1091)
|
||||
1640857 glFlushMappedBufferRange(target = GL_COPY_WRITE_BUFFER, offset = 0, length = 12)
|
||||
1640858 glUnmapBuffer(target = GL_COPY_WRITE_BUFFER) = GL_TRUE
|
||||
1640863 glDrawElementsBaseVertex(mode = GL_TRIANGLES, count = 6, type = GL_UNSIGNED_SHORT, indices = 0x58, basevertex = 4)
|
||||
|
||||
At the start of this frame, the VBOs haven't been used in about 6 frames, and
|
||||
the :ext:`GL_ARB_sync` fence has ensured that the GPU has started frame n-1.
|
||||
|
||||
Note the use of ``glFlushMappedBufferRange()`` on a small fraction of the size
|
||||
of the VBO -- it is important that a blitting driver make use of the flush
|
||||
ranges when in explicit mode.
|
||||
|
||||
Darkest Dungeon
|
||||
===============
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
938384 glXSwapBuffers(dpy = 0x377fcd0, drawable = 23068692)
|
||||
|
||||
938385 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 2)
|
||||
938386 glBufferData(target = GL_ARRAY_BUFFER, size = 1048576, data = NULL, usage = GL_STREAM_DRAW)
|
||||
938511 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 2)
|
||||
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
|
||||
938514 glFlushMappedBufferRange(target = GL_ARRAY_BUFFER, offset = 0, length = 512)
|
||||
938515 glUnmapBuffer(target = GL_ARRAY_BUFFER) = GL_TRUE
|
||||
938523 glBindBuffer(target = GL_ELEMENT_ARRAY_BUFFER, buffer = 1)
|
||||
938524 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 2)
|
||||
938525 glDrawElements(mode = GL_TRIANGLES, count = 24, type = GL_UNSIGNED_SHORT, indices = NULL)
|
||||
938527 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 2)
|
||||
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
|
||||
938530 glFlushMappedBufferRange(target = GL_ARRAY_BUFFER, offset = 512, length = 512)
|
||||
938531 glUnmapBuffer(target = GL_ARRAY_BUFFER) = GL_TRUE
|
||||
938539 glBindBuffer(target = GL_ELEMENT_ARRAY_BUFFER, buffer = 1)
|
||||
938540 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 2)
|
||||
938541 glDrawElements(mode = GL_TRIANGLES, count = 24, type = GL_UNSIGNED_SHORT, indices = 0x30)
|
||||
[... more maps and draws at increasing offsets]
|
||||
|
||||
Interesting note for this game, after the initial ``glBufferData()`` in the
|
||||
frame to reallocate the storage, it unsync maps the whole buffer each time, and
|
||||
just changes which region it flushes. The same GL buffer name is used in every
|
||||
frame.
|
||||
|
||||
Tabletop Simulator
|
||||
==================
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
1287594 glXSwapBuffers(dpy = 0x3e10810, drawable = 23068692)
|
||||
1287595 glClientWaitSync(sync = 0x7abf554e37b0, flags = 0x0, timeout = 0) = GL_ALREADY_SIGNALED
|
||||
1287596 glDeleteSync(sync = 0x7abf554e37b0)
|
||||
1287597 glFenceSync(condition = GL_SYNC_GPU_COMMANDS_COMPLETE, flags = 0) = 0x7abf56647490
|
||||
|
||||
1287614 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 480)
|
||||
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
|
||||
1287642 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 614)
|
||||
1287650 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 5)
|
||||
1287651 glBufferSubData(target = GL_COPY_WRITE_BUFFER, offset = 0, size = 1088, data = blob(1088))
|
||||
1287652 glBindBuffer(target = GL_ELEMENT_ARRAY_BUFFER, buffer = 615)
|
||||
1287653 glDrawElements(mode = GL_TRIANGLES, count = 1788, type = GL_UNSIGNED_SHORT, indices = NULL)
|
||||
[... more draw calls]
|
||||
1289055 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 480)
|
||||
1289057 glFlushMappedBufferRange(target = GL_COPY_WRITE_BUFFER, offset = 0, length = 384)
|
||||
1289058 glUnmapBuffer(target = GL_COPY_WRITE_BUFFER) = GL_TRUE
|
||||
1289059 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 480)
|
||||
1289066 glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 12, count = 4)
|
||||
1289068 glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 8, count = 4)
|
||||
1289553 glXSwapBuffers(dpy = 0x3e10810, drawable = 23068692)
|
||||
|
||||
In this app, buffer 480 gets used like this every other frame. The :ext:`GL_ARB_sync`
|
||||
fence ensures that frame n-1 has started on the GPU before CPU work starts on
|
||||
the current frame, so the unsynchronized access to the buffers is safe.
|
||||
|
||||
Hollow Knight
|
||||
=============
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
1873034 glXSwapBuffers(dpy = 0x28609d0, drawable = 23068692)
|
||||
1873035 glClientWaitSync(sync = 0x7b1a5ca6e130, flags = 0x0, timeout = 0) = GL_ALREADY_SIGNALED
|
||||
1873036 glDeleteSync(sync = 0x7b1a5ca6e130)
|
||||
1873037 glFenceSync(condition = GL_SYNC_GPU_COMMANDS_COMPLETE, flags = 0) = 0x7b1a5ca6e130
|
||||
1873038 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 29)
|
||||
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
|
||||
1873040 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 30)
|
||||
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
|
||||
1873065 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 29)
|
||||
1873067 glFlushMappedBufferRange(target = GL_COPY_WRITE_BUFFER, offset = 0, length = 8640)
|
||||
1873068 glUnmapBuffer(target = GL_COPY_WRITE_BUFFER) = GL_TRUE
|
||||
1873069 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 30)
|
||||
1873071 glFlushMappedBufferRange(target = GL_COPY_WRITE_BUFFER, offset = 0, length = 720)
|
||||
1873072 glUnmapBuffer(target = GL_COPY_WRITE_BUFFER) = GL_TRUE
|
||||
1873073 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 29)
|
||||
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
|
||||
1873075 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 30)
|
||||
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
|
||||
1873077 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 29)
|
||||
1873079 glFlushMappedBufferRange(target = GL_COPY_WRITE_BUFFER, offset = 0, length = 576)
|
||||
1873080 glUnmapBuffer(target = GL_COPY_WRITE_BUFFER) = GL_TRUE
|
||||
1873081 glBindBuffer(target = GL_COPY_WRITE_BUFFER, buffer = 30)
|
||||
1873083 glFlushMappedBufferRange(target = GL_COPY_WRITE_BUFFER, offset = 0, length = 72)
|
||||
1873084 glUnmapBuffer(target = GL_COPY_WRITE_BUFFER) = GL_TRUE
|
||||
1873085 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 29)
|
||||
1873096 glBindBuffer(target = GL_ELEMENT_ARRAY_BUFFER, buffer = 30)
|
||||
1873097 glDrawElementsBaseVertex(mode = GL_TRIANGLES, count = 36, type = GL_UNSIGNED_SHORT, indices = 0x2d0, basevertex = 240)
|
||||
|
||||
In this app, buffer 29/30 get used like this starting from offset 0 every other
|
||||
frame. The :ext:`GL_ARB_sync` fence is used to make sure that the GPU has reached the
|
||||
start of the previous frame before we go unsynchronized writing over the n-2
|
||||
frame's buffer.
|
||||
|
||||
Borderlands 2
|
||||
=============
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
3561998 glFlush()
|
||||
3562004 glXSwapBuffers(dpy = 0xbaf0f90, drawable = 23068705)
|
||||
3562006 glClientWaitSync(sync = 0x231c2ab0, flags = GL_SYNC_FLUSH_COMMANDS_BIT, timeout = 10000000000) = GL_ALREADY_SIGNALED
|
||||
3562007 glDeleteSync(sync = 0x231c2ab0)
|
||||
3562008 glFenceSync(condition = GL_SYNC_GPU_COMMANDS_COMPLETE, flags = 0) = 0x231aadc0
|
||||
|
||||
3562050 glBindBufferARB(target = GL_ARRAY_BUFFER, buffer = 1193)
|
||||
3562051 glMapBufferRange(target = GL_ARRAY_BUFFER, offset = 0, length = 1792, access = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT) = 0xde056000
|
||||
3562053 glUnmapBufferARB(target = GL_ARRAY_BUFFER) = GL_TRUE
|
||||
3562054 glBindBufferARB(target = GL_ARRAY_BUFFER, buffer = 1194)
|
||||
3562055 glMapBufferRange(target = GL_ARRAY_BUFFER, offset = 0, length = 1280, access = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT) = 0xd9426000
|
||||
3562057 glUnmapBufferARB(target = GL_ARRAY_BUFFER) = GL_TRUE
|
||||
[... unrelated draws]
|
||||
3563051 glBindBufferARB(target = GL_ARRAY_BUFFER, buffer = 1193)
|
||||
3563064 glBindBufferARB(target = GL_ELEMENT_ARRAY_BUFFER, buffer = 875)
|
||||
3563065 glDrawElementsInstancedARB(mode = GL_TRIANGLES, count = 72, type = GL_UNSIGNED_SHORT, indices = NULL, instancecount = 28)
|
||||
|
||||
The :ext:`GL_ARB_sync` fence ensures that the GPU has started frame n-1 before the CPU
|
||||
starts on the current frame.
|
||||
|
||||
This sequence of buffer uploads appears in each frame with the same buffer
|
||||
names, so you do need to handle the ``GL_MAP_INVALIDATE_BUFFER_BIT`` as a
|
||||
reallocate if the buffer is GPU-busy (it wasn't in this trace capture) to avoid
|
||||
stalls on the n-1 frame completing.
|
||||
|
||||
Note that this is just one small buffer. Most of the vertex data goes through a
|
||||
``glBufferSubData()``/``glDraw*()`` path with the VBO used across multiple
|
||||
frames, with a ``glBufferData()`` when needing to wrap.
|
||||
|
||||
Buffer mapping conclusions
|
||||
--------------------------
|
||||
|
||||
* Non-blitting drivers must track the valid range of a freshly allocated buffer
|
||||
as it gets uploaded in ``pipe_transfer_map()`` and avoid stalling on the GPU
|
||||
when mapping an undefined portion of the buffer when ``glBufferSubData()`` is
|
||||
interleaved with drawing.
|
||||
|
||||
* Non-blitting drivers must reallocate storage on ``glBufferData(NULL)`` so that
|
||||
the following ``glBufferSubData()`` won't stall. That ``glBufferData(NULL)``
|
||||
call will appear in the driver as an ``invalidate_resource()`` call if
|
||||
``pipe_caps.invalidate_buffer`` is available. (If that flag is not set, then
|
||||
mesa/st will create a new pipe_resource for you). Storage reallocation may be
|
||||
skipped if you for some reason know that the buffer is idle, in which case you
|
||||
can just empty the valid region.
|
||||
|
||||
* Blitting drivers must use the ``transfer_flush_region()`` region
|
||||
instead of the mapped range when ``PIPE_MAP_FLUSH_EXPLICIT`` is set, to avoid
|
||||
blitting too much data. (When that bit is unset, you just blit the whole
|
||||
mapped range at unmap time.)
|
||||
|
||||
* Buffer valid range tracking in non-blitting drivers must use the
|
||||
``transfer_flush_region()`` region instead of the mapped range when
|
||||
``PIPE_MAP_FLUSH_EXPLICIT`` is set, to avoid excess stalls.
|
||||
|
||||
* Buffer valid range tracking doesn't need to be fancy, "number of bytes
|
||||
valid starting from 0" is sufficient for all examples found.
|
||||
|
||||
* Use the ``util_debug_callback`` to report stalls on buffer mapping to ease
|
||||
debug.
|
||||
|
||||
* Buffer binding points are not useful for tuning buffer placement (See all the
|
||||
``PIPE_COPY_WRITE_BUFFER`` instances), you have to track the actual usage
|
||||
history of a GL BO name. mesa/st does this for optimizing its state updates
|
||||
on reallocation in the ``!pipe_caps.invalidate_buffer`` case, and if you set
|
||||
``pipe_caps.invalidate_buffer`` then you have to flag your own internal state
|
||||
updates (VBO addresses, XFB addresses, texture buffer addresses, etc.) on
|
||||
reallocation based on usage history.
|
||||
@@ -0,0 +1,976 @@
|
||||
.. _context:
|
||||
|
||||
Context
|
||||
=======
|
||||
|
||||
A Gallium rendering context encapsulates the state which effects 3D
|
||||
rendering such as blend state, depth/stencil state, texture samplers,
|
||||
etc.
|
||||
|
||||
Note that resource/texture allocation is not per-context but per-screen.
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
CSO State
|
||||
^^^^^^^^^
|
||||
|
||||
All Constant State Object (CSO) state is created, bound, and destroyed,
|
||||
with triplets of methods that all follow a specific naming scheme.
|
||||
For example, ``create_blend_state``, ``bind_blend_state``, and
|
||||
``destroy_blend_state``.
|
||||
|
||||
CSO objects handled by the context object:
|
||||
|
||||
* :ref:`Blend`: ``*_blend_state``
|
||||
* :ref:`Sampler`: Texture sampler states are bound separately for fragment,
|
||||
vertex, geometry and compute shaders with the ``bind_sampler_states``
|
||||
function. The ``start`` and ``num_samplers`` parameters indicate a range
|
||||
of samplers to change. NOTE: at this time, start is always zero and
|
||||
the CSO module will always replace all samplers at once (no sub-ranges).
|
||||
This may change in the future.
|
||||
* :ref:`Rasterizer`: ``*_rasterizer_state``
|
||||
* :ref:`depth-stencil-alpha`: ``*_depth_stencil_alpha_state``
|
||||
* :ref:`Shader`: These are create, bind and destroy methods for vertex,
|
||||
fragment and geometry shaders.
|
||||
* :ref:`vertexelements`: ``*_vertex_elements_state``
|
||||
|
||||
|
||||
Resource Binding State
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This state describes how resources in various flavors (textures,
|
||||
buffers, surfaces) are bound to the driver.
|
||||
|
||||
|
||||
* ``set_constant_buffer`` sets a constant buffer to be used for a given shader
|
||||
type. index is used to indicate which buffer to set (some APIs may allow
|
||||
multiple ones to be set, and binding a specific one later, though drivers
|
||||
are mostly restricted to the first one right now).
|
||||
If take_ownership is true, the buffer reference is passed to the driver, so
|
||||
that the driver doesn't have to increment the reference count.
|
||||
|
||||
* ``set_inlinable_constants`` sets inlinable constants for constant buffer 0.
|
||||
|
||||
These are constants that the driver would like to inline in the IR
|
||||
of the current shader and recompile it. Drivers can determine which
|
||||
constants they prefer to inline in finalize_nir and store that
|
||||
information in shader_info::*inlinable_uniform*. When the state tracker
|
||||
or frontend uploads constants to a constant buffer, it can pass
|
||||
inlinable constants separately via this call.
|
||||
|
||||
Any ``set_constant_buffer`` call invalidates inlinable constants, so
|
||||
``set_inlinable_constants`` must be called after it. Binding a shader also
|
||||
invalidates this state.
|
||||
|
||||
There is no ``PIPE_CAP`` for this. Drivers shouldn't set the shader_info
|
||||
fields if they don't implement ``set_inlinable_constants``.
|
||||
|
||||
* ``set_framebuffer_state``
|
||||
|
||||
* ``set_vertex_buffers``
|
||||
|
||||
|
||||
Non-CSO State
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
These pieces of state are too small, variable, and/or trivial to have CSO
|
||||
objects. They all follow simple, one-method binding calls, e.g.
|
||||
``set_blend_color``.
|
||||
|
||||
* ``set_stencil_ref`` sets the stencil front and back reference values
|
||||
which are used as comparison values in stencil test.
|
||||
* ``set_blend_color``
|
||||
* ``set_sample_mask`` sets the per-context multisample sample mask. Note
|
||||
that this takes effect even if multisampling is not explicitly enabled if
|
||||
the framebuffer surface(s) are multisampled. Also, this mask is AND-ed
|
||||
with the optional fragment shader sample mask output (when emitted).
|
||||
* ``set_sample_locations`` sets the sample locations used for rasterization.
|
||||
```get_sample_position``` still returns the default locations. When NULL,
|
||||
the default locations are used.
|
||||
* ``set_min_samples`` sets the minimum number of samples that must be run.
|
||||
* ``set_clip_state``
|
||||
* ``set_polygon_stipple``
|
||||
* ``set_scissor_states`` sets the bounds for the scissor test, which culls
|
||||
pixels before blending to render targets. If the :ref:`Rasterizer` does
|
||||
not have the scissor test enabled, then the scissor bounds never need to
|
||||
be set since they will not be used. Note that scissor xmin and ymin are
|
||||
inclusive, but xmax and ymax are exclusive. The inclusive ranges in x
|
||||
and y would be [xmin..xmax-1] and [ymin..ymax-1]. The number of scissors
|
||||
should be the same as the number of set viewports and can be up to
|
||||
PIPE_MAX_VIEWPORTS.
|
||||
* ``set_viewport_states``
|
||||
* ``set_window_rectangles`` sets the window rectangles to be used for
|
||||
rendering, as defined by :ext:`GL_EXT_window_rectangles`. There are two
|
||||
modes - include and exclude, which define whether the supplied
|
||||
rectangles are to be used for including fragments or excluding
|
||||
them. All of the rectangles are ORed together, so in exclude mode,
|
||||
any fragment inside any rectangle would be culled, while in include
|
||||
mode, any fragment outside all rectangles would be culled. xmin/ymin
|
||||
are inclusive, while xmax/ymax are exclusive (same as scissor states
|
||||
above). Note that this only applies to draws, not clears or
|
||||
blits. (Blits have their own way to pass the requisite rectangles
|
||||
in.)
|
||||
* ``set_tess_state`` configures the default tessellation parameters:
|
||||
|
||||
* ``default_outer_level`` is the default value for the outer tessellation
|
||||
levels. This corresponds to GL's ``PATCH_DEFAULT_OUTER_LEVEL``.
|
||||
* ``default_inner_level`` is the default value for the inner tessellation
|
||||
levels. This corresponds to GL's ``PATCH_DEFAULT_INNER_LEVEL``.
|
||||
* ``set_patch_vertices`` sets the number of vertices per input patch
|
||||
for tessellation.
|
||||
|
||||
* ``set_debug_callback`` sets the callback to be used for reporting
|
||||
various debug messages, eventually reported via :ext:`GL_KHR_debug` and
|
||||
similar mechanisms.
|
||||
|
||||
Samplers
|
||||
^^^^^^^^
|
||||
|
||||
pipe_sampler_state objects control how textures are sampled (coordinate wrap
|
||||
modes, interpolation modes, etc). Samplers are only required for texture
|
||||
instructions for which nir_tex_instr_need_sampler returns true. Drivers must
|
||||
ignore samplers for other texture instructions. Frontends may or may not bind
|
||||
samplers when no texture instruction use them. Notably, frontends may not bind
|
||||
samplers for texture buffer objects, which are never accessed with samplers.
|
||||
|
||||
Sampler Views
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
These are the means to bind textures to shader stages. To create one, specify
|
||||
its format, swizzle and LOD range in sampler view template.
|
||||
|
||||
If texture format is different than template format, it is said the texture
|
||||
is being cast to another format. Casting can be done only between compatible
|
||||
formats, that is formats that have matching component order and sizes.
|
||||
|
||||
Swizzle fields specify the way in which fetched texel components are placed
|
||||
in the result register. For example, ``swizzle_r`` specifies what is going to be
|
||||
placed in first component of result register.
|
||||
|
||||
The ``first_level`` and ``last_level`` fields of sampler view template specify
|
||||
the LOD range the texture is going to be constrained to. Note that these
|
||||
values are in addition to the respective min_lod, max_lod values in the
|
||||
pipe_sampler_state (that is if min_lod is 2.0, and first_level 3, the first mip
|
||||
level used for sampling from the resource is effectively the fifth).
|
||||
|
||||
The ``first_layer`` and ``last_layer`` fields specify the layer range the
|
||||
texture is going to be constrained to. Similar to the LOD range, this is added
|
||||
to the array index which is used for sampling.
|
||||
|
||||
* ``set_sampler_views`` binds an array of sampler views to a shader stage.
|
||||
Every binding point acquires a reference
|
||||
to a respective sampler view and releases a reference to the previous
|
||||
sampler view.
|
||||
|
||||
Sampler views outside of ``[start_slot, start_slot + num_views)`` are
|
||||
unmodified. If ``views`` is NULL, the behavior is the same as if
|
||||
``views[n]`` was NULL for the entire range, i.e. releasing the reference
|
||||
for all the sampler views in the specified range.
|
||||
|
||||
* ``create_sampler_view`` creates a new sampler view. ``texture`` is associated
|
||||
with the sampler view which results in sampler view holding a reference
|
||||
to the texture. Format specified in template must be compatible
|
||||
with texture format.
|
||||
|
||||
* ``sampler_view_destroy`` destroys a sampler view and releases its reference
|
||||
to associated texture.
|
||||
|
||||
Hardware Atomic buffers
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Buffers containing HW atomics are required to support the feature
|
||||
on some drivers.
|
||||
|
||||
Drivers that require this need to fill the ``set_hw_atomic_buffers`` method.
|
||||
|
||||
Shader Resources
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
Shader resources are textures or buffers that may be read or written
|
||||
from a shader without an associated sampler. This means that they
|
||||
have no support for floating point coordinates, address wrap modes or
|
||||
filtering.
|
||||
|
||||
There are 2 types of shader resources: buffers and images.
|
||||
|
||||
Buffers are specified using the ``set_shader_buffers`` method.
|
||||
|
||||
Images are specified using the ``set_shader_images`` method. When binding
|
||||
images, the ``level``, ``first_layer`` and ``last_layer`` pipe_image_view
|
||||
fields specify the mipmap level and the range of layers the image will be
|
||||
constrained to.
|
||||
|
||||
Surfaces
|
||||
^^^^^^^^
|
||||
|
||||
These are the means to use resources as color render targets or depthstencil
|
||||
attachments. To create one, specify the mip level, the range of layers, and
|
||||
the bind flags (either PIPE_BIND_DEPTH_STENCIL or PIPE_BIND_RENDER_TARGET).
|
||||
Note that layer values are in addition to what is indicated by the geometry
|
||||
shader output variable XXX_FIXME (that is if first_layer is 3 and geometry
|
||||
shader indicates index 2, the 5th layer of the resource will be used). These
|
||||
first_layer and last_layer parameters will only be used for 1d array, 2d array,
|
||||
cube, and 3d textures otherwise they are 0.
|
||||
|
||||
* ``create_surface`` creates a new surface.
|
||||
|
||||
* ``surface_destroy`` destroys a surface and releases its reference to the
|
||||
associated resource.
|
||||
|
||||
Stream output targets
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Stream output, also known as transform feedback, allows writing the primitives
|
||||
produced by the vertex pipeline to buffers. This is done after the geometry
|
||||
shader or vertex shader if no geometry shader is present.
|
||||
|
||||
The stream output targets are views into buffer resources which can be bound
|
||||
as stream outputs and specify a memory range where it's valid to write
|
||||
primitives. The pipe driver must implement memory protection such that any
|
||||
primitives written outside of the specified memory range are discarded.
|
||||
|
||||
Two stream output targets can use the same resource at the same time, but
|
||||
with a disjoint memory range.
|
||||
|
||||
Additionally, the stream output target internally maintains the offset
|
||||
into the buffer which is incremented every time something is written to it.
|
||||
The internal offset is equal to how much data has already been written.
|
||||
It can be stored in device memory and the CPU actually doesn't have to query
|
||||
it.
|
||||
|
||||
The stream output target can be used in a draw command to provide
|
||||
the vertex count. The vertex count is derived from the internal offset
|
||||
discussed above.
|
||||
|
||||
* ``create_stream_output_target`` create a new target.
|
||||
|
||||
* ``stream_output_target_destroy`` destroys a target. Users of this should
|
||||
use pipe_so_target_reference instead.
|
||||
|
||||
* ``set_stream_output_targets`` binds stream output targets. The parameter
|
||||
offset is an array which specifies the internal offset of the buffer. The
|
||||
internal offset is, besides writing, used for reading the data during the
|
||||
draw_auto stage, i.e. it specifies how much data there is in the buffer
|
||||
for the purposes of the draw_auto stage. -1 means the buffer should
|
||||
be appended to, and everything else sets the internal offset.
|
||||
|
||||
* ``stream_output_target_offset`` Retrieve the internal stream offset from
|
||||
an streamout target. This is used to implement Vulkan pause/resume support
|
||||
which needs to pass the internal offset to the API.
|
||||
|
||||
NOTE: The currently-bound vertex or geometry shader must be compiled with
|
||||
the properly-filled-in structure pipe_stream_output_info describing which
|
||||
outputs should be written to buffers and how. The structure is part of
|
||||
pipe_shader_state.
|
||||
|
||||
Clearing
|
||||
^^^^^^^^
|
||||
|
||||
Clear is one of the most difficult concepts to nail down to a single
|
||||
interface (due to both different requirements from APIs and also driver/HW
|
||||
specific differences).
|
||||
|
||||
``clear`` initializes some or all of the surfaces currently bound to
|
||||
the framebuffer to particular RGBA, depth, or stencil values.
|
||||
Currently, this does not take into account color or stencil write masks (as
|
||||
used by GL), and always clears the whole surfaces (no scissoring as used by
|
||||
GL clear or explicit rectangles like d3d9 uses). It can, however, also clear
|
||||
only depth or stencil in a combined depth/stencil surface.
|
||||
If a surface includes several layers then all layers will be cleared.
|
||||
|
||||
``clear_render_target`` clears a single color rendertarget with the specified
|
||||
color value. While it is only possible to clear one surface at a time (which can
|
||||
include several layers), this surface need not be bound to the framebuffer.
|
||||
If render_condition_enabled is false, any current rendering condition is ignored
|
||||
and the clear will be unconditional.
|
||||
|
||||
``clear_depth_stencil`` clears a single depth, stencil or depth/stencil surface
|
||||
with the specified depth and stencil values (for combined depth/stencil buffers,
|
||||
it is also possible to only clear one or the other part). While it is only
|
||||
possible to clear one surface at a time (which can include several layers),
|
||||
this surface need not be bound to the framebuffer.
|
||||
If render_condition_enabled is false, any current rendering condition is ignored
|
||||
and the clear will be unconditional.
|
||||
|
||||
``clear_texture`` clears a non-PIPE_BUFFER resource's specified level
|
||||
and bounding box with a clear value provided in that resource's native
|
||||
format.
|
||||
|
||||
``clear_buffer`` clears a PIPE_BUFFER resource with the specified clear value
|
||||
(which may be multiple bytes in length). Logically this is a memset with a
|
||||
multi-byte element value starting at offset bytes from resource start, going
|
||||
for size bytes. It is guaranteed that size % clear_value_size == 0.
|
||||
|
||||
Evaluating Depth Buffers
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
``evaluate_depth_buffer`` is a hint to decompress the current depth buffer
|
||||
assuming the current sample locations to avoid problems that could arise when
|
||||
using programmable sample locations.
|
||||
|
||||
If a depth buffer is rendered with different sample location state than
|
||||
what is current at the time of reading the depth buffer, the values may differ
|
||||
because depth buffer compression can depend the sample locations.
|
||||
|
||||
|
||||
Uploading
|
||||
^^^^^^^^^
|
||||
|
||||
For simple single-use uploads, use ``pipe_context::stream_uploader`` or
|
||||
``pipe_context::const_uploader``. The latter should be used for uploading
|
||||
constants, while the former should be used for uploading everything else.
|
||||
PIPE_USAGE_STREAM is implied in both cases, so don't use the uploaders
|
||||
for static allocations.
|
||||
|
||||
Usage:
|
||||
|
||||
Call u_upload_alloc or u_upload_data as many times as you want. After you are
|
||||
done, call u_upload_unmap. If the driver doesn't support persistent mappings,
|
||||
u_upload_unmap makes sure the previously mapped memory is unmapped.
|
||||
|
||||
Gotchas:
|
||||
- Always fill the memory immediately after u_upload_alloc. Any following call
|
||||
to u_upload_alloc and u_upload_data can unmap memory returned by previous
|
||||
u_upload_alloc.
|
||||
- Don't interleave calls using stream_uploader and const_uploader. If you use
|
||||
one of them, do the upload, unmap, and only then can you use the other one.
|
||||
|
||||
|
||||
Drawing
|
||||
^^^^^^^
|
||||
|
||||
``draw_vbo`` draws a specified primitive. The primitive mode and other
|
||||
properties are described by ``pipe_draw_info``.
|
||||
|
||||
The ``mode``, ``start``, and ``count`` fields of ``pipe_draw_info`` specify the
|
||||
the mode of the primitive and the vertices to be fetched, in the range between
|
||||
``start`` to ``start``+``count``-1, inclusive.
|
||||
|
||||
Every instance with instanceID in the range between ``start_instance`` and
|
||||
``start_instance``+``instance_count``-1, inclusive, will be drawn.
|
||||
|
||||
If ``index_size`` != 0, all vertex indices will be looked up from the index
|
||||
buffer.
|
||||
|
||||
In indexed draw, ``min_index`` and ``max_index`` respectively provide a lower
|
||||
and upper bound of the indices contained in the index buffer inside the range
|
||||
between ``start`` to ``start``+``count``-1. This allows the driver to
|
||||
determine which subset of vertices will be referenced during the draw call
|
||||
without having to scan the index buffer. Providing a over-estimation of the
|
||||
the true bounds, for example, a ``min_index`` and ``max_index`` of 0 and
|
||||
0xffffffff respectively, must give exactly the same rendering, albeit with less
|
||||
performance due to unreferenced vertex buffers being unnecessarily DMA'ed or
|
||||
processed. Providing a underestimation of the true bounds will result in
|
||||
undefined behavior, but should not result in program or system failure.
|
||||
|
||||
In case of non-indexed draw, ``min_index`` should be set to
|
||||
``start`` and ``max_index`` should be set to ``start``+``count``-1.
|
||||
|
||||
``index_bias`` is a value added to every vertex index after lookup and before
|
||||
fetching vertex attributes.
|
||||
|
||||
When drawing indexed primitives, the primitive restart index can be
|
||||
used to draw disjoint primitive strips. For example, several separate
|
||||
line strips can be drawn by designating a special index value as the
|
||||
restart index. The ``primitive_restart`` flag enables/disables this
|
||||
feature. The ``restart_index`` field specifies the restart index value.
|
||||
|
||||
When primitive restart is in use, array indexes are compared to the
|
||||
restart index before adding the index_bias offset.
|
||||
|
||||
If a given vertex element has ``instance_divisor`` set to 0, it is said
|
||||
it contains per-vertex data and effective vertex attribute address needs
|
||||
to be recalculated for every index.
|
||||
|
||||
attribAddr = ``stride`` * index + ``src_offset``
|
||||
|
||||
If a given vertex element has ``instance_divisor`` set to non-zero,
|
||||
it is said it contains per-instance data and effective vertex attribute
|
||||
address needs to recalculated for every ``instance_divisor``-th instance.
|
||||
|
||||
attribAddr = ``stride`` * instanceID / ``instance_divisor`` + ``src_offset``
|
||||
|
||||
In the above formulas, ``src_offset`` is taken from the given vertex element
|
||||
and ``stride`` is taken from a vertex buffer associated with the given
|
||||
vertex element.
|
||||
|
||||
The calculated attribAddr is used as an offset into the vertex buffer to
|
||||
fetch the attribute data.
|
||||
|
||||
The value of ``instanceID`` can be read in a vertex shader through a system
|
||||
value register declared with INSTANCEID semantic name.
|
||||
|
||||
|
||||
Queries
|
||||
^^^^^^^
|
||||
|
||||
Queries gather some statistic from the 3D pipeline over one or more
|
||||
draws. Queries may be nested, though not all gallium frontends exercise this.
|
||||
|
||||
Queries can be created with ``create_query`` and deleted with
|
||||
``destroy_query``. To start a query, use ``begin_query``, and when finished,
|
||||
use ``end_query`` to end the query.
|
||||
|
||||
``create_query`` takes a query type (``PIPE_QUERY_*``), as well as an index,
|
||||
which is the vertex stream for ``PIPE_QUERY_PRIMITIVES_GENERATED`` and
|
||||
``PIPE_QUERY_PRIMITIVES_EMITTED``, and allocates a query structure.
|
||||
|
||||
``begin_query`` will clear/reset previous query results.
|
||||
|
||||
``get_query_result`` is used to retrieve the results of a query. If
|
||||
the ``wait`` parameter is TRUE, then the ``get_query_result`` call
|
||||
will block until the results of the query are ready (and TRUE will be
|
||||
returned). Otherwise, if the ``wait`` parameter is FALSE, the call
|
||||
will not block and the return value will be TRUE if the query has
|
||||
completed or FALSE otherwise.
|
||||
|
||||
``get_query_result_resource`` is used to store the result of a query into
|
||||
a resource without synchronizing with the CPU. This write will optionally
|
||||
wait for the query to complete, and will optionally write whether the value
|
||||
is available instead of the value itself.
|
||||
|
||||
``set_active_query_state`` Set whether all current non-driver queries except
|
||||
TIME_ELAPSED are active or paused.
|
||||
|
||||
The interface currently includes the following types of queries:
|
||||
|
||||
``PIPE_QUERY_OCCLUSION_COUNTER`` counts the number of fragments which
|
||||
are written to the framebuffer without being culled by
|
||||
:ref:`depth-stencil-alpha` testing or shader KILL instructions.
|
||||
The result is an unsigned 64-bit integer.
|
||||
This query can be used with ``render_condition``.
|
||||
|
||||
In cases where a boolean result of an occlusion query is enough,
|
||||
``PIPE_QUERY_OCCLUSION_PREDICATE`` should be used. It is just like
|
||||
``PIPE_QUERY_OCCLUSION_COUNTER`` except that the result is a boolean
|
||||
value of FALSE for cases where COUNTER would result in 0 and TRUE
|
||||
for all other cases.
|
||||
This query can be used with ``render_condition``.
|
||||
|
||||
In cases where a conservative approximation of an occlusion query is enough,
|
||||
``PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE`` should be used. It behaves
|
||||
like ``PIPE_QUERY_OCCLUSION_PREDICATE``, except that it may return TRUE in
|
||||
additional, implementation-dependent cases.
|
||||
This query can be used with ``render_condition``.
|
||||
|
||||
``PIPE_QUERY_TIME_ELAPSED`` returns the amount of time, in nanoseconds,
|
||||
the context takes to perform operations.
|
||||
The result is an unsigned 64-bit integer.
|
||||
|
||||
``PIPE_QUERY_TIMESTAMP`` returns a device/driver internal timestamp,
|
||||
scaled to nanoseconds, recorded after all commands issued prior to
|
||||
``end_query`` have been processed.
|
||||
This query does not require a call to ``begin_query``.
|
||||
The result is an unsigned 64-bit integer.
|
||||
|
||||
``PIPE_QUERY_TIMESTAMP_RAW`` returns a device/driver timestamp, recorded
|
||||
after all commands issued prior to ``end_query`` have been processed.
|
||||
This query does not require a call to ``begin_query``.
|
||||
The result is an unsigned 64-bit integer. ``pipe_screen::convert_timestamp()``
|
||||
should be implemented, to covert the raw timestamp to nanoseconds, if
|
||||
this query type is supported.
|
||||
``PIPE_QUERY_TIMESTAMP_DISJOINT`` can be used to check the
|
||||
internal timer resolution and whether the timestamp counter has become
|
||||
unreliable due to things like throttling etc. - only if this is FALSE
|
||||
a timestamp query (within the timestamp_disjoint query) should be trusted.
|
||||
The result is a 64-bit integer specifying the timer resolution in Hz,
|
||||
followed by a boolean value indicating whether the timestamp counter
|
||||
is discontinuous or disjoint.
|
||||
|
||||
``PIPE_QUERY_PRIMITIVES_GENERATED`` returns a 64-bit integer indicating
|
||||
the number of primitives processed by the pipeline (regardless of whether
|
||||
stream output is active or not).
|
||||
|
||||
``PIPE_QUERY_PRIMITIVES_EMITTED`` returns a 64-bit integer indicating
|
||||
the number of primitives written to stream output buffers.
|
||||
|
||||
``PIPE_QUERY_SO_STATISTICS`` returns 2 64-bit integers corresponding to
|
||||
the result of
|
||||
``PIPE_QUERY_PRIMITIVES_EMITTED`` and
|
||||
the number of primitives that would have been written to stream output buffers
|
||||
if they had infinite space available (primitives_storage_needed), in this order.
|
||||
XXX the 2nd value is equivalent to ``PIPE_QUERY_PRIMITIVES_GENERATED`` but it is
|
||||
unclear if it should be increased if stream output is not active.
|
||||
|
||||
``PIPE_QUERY_SO_OVERFLOW_PREDICATE`` returns a boolean value indicating
|
||||
whether a selected stream output target has overflowed as a result of the
|
||||
commands issued between ``begin_query`` and ``end_query``.
|
||||
This query can be used with ``render_condition``. The output stream is
|
||||
selected by the stream number passed to ``create_query``.
|
||||
|
||||
``PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE`` returns a boolean value indicating
|
||||
whether any stream output target has overflowed as a result of the commands
|
||||
issued between ``begin_query`` and ``end_query``. This query can be used
|
||||
with ``render_condition``, and its result is the logical OR of multiple
|
||||
``PIPE_QUERY_SO_OVERFLOW_PREDICATE`` queries, one for each stream output
|
||||
target.
|
||||
|
||||
``PIPE_QUERY_GPU_FINISHED`` returns a boolean value indicating whether
|
||||
all commands issued before ``end_query`` have completed. However, this
|
||||
does not imply serialization.
|
||||
This query does not require a call to ``begin_query``.
|
||||
|
||||
``PIPE_QUERY_PIPELINE_STATISTICS`` returns an array of the following
|
||||
64-bit integers:
|
||||
Number of vertices read from vertex buffers.
|
||||
Number of primitives read from vertex buffers.
|
||||
Number of vertex shader threads launched.
|
||||
Number of geometry shader threads launched.
|
||||
Number of primitives generated by geometry shaders.
|
||||
Number of primitives forwarded to the rasterizer.
|
||||
Number of primitives rasterized.
|
||||
Number of fragment shader threads launched.
|
||||
Number of tessellation control shader threads launched.
|
||||
Number of tessellation evaluation shader threads launched.
|
||||
If a shader type is not supported by the device/driver,
|
||||
the corresponding values should be set to 0.
|
||||
|
||||
``PIPE_QUERY_PIPELINE_STATISTICS_SINGLE`` returns a single counter from
|
||||
the ``PIPE_QUERY_PIPELINE_STATISTICS`` group. The specific counter must
|
||||
be selected when calling ``create_query`` by passing one of the
|
||||
``PIPE_STAT_QUERY`` enums as the query's ``index``.
|
||||
|
||||
Gallium does not guarantee the availability of any query types; one must
|
||||
always check the capabilities of the :ref:`Screen` first.
|
||||
|
||||
|
||||
Conditional Rendering
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
A drawing command can be skipped depending on the outcome of a query
|
||||
(typically an occlusion query, or streamout overflow predicate).
|
||||
The ``render_condition`` function specifies the query which should be checked
|
||||
prior to rendering anything. Functions always honoring render_condition include
|
||||
(and are limited to) draw_vbo and clear.
|
||||
The blit, clear_render_target and clear_depth_stencil functions (but
|
||||
not resource_copy_region, which seems inconsistent) can also optionally honor
|
||||
the current render condition.
|
||||
|
||||
If ``render_condition`` is called with ``query`` = NULL, conditional
|
||||
rendering is disabled and drawing takes place normally.
|
||||
|
||||
If ``render_condition`` is called with a non-null ``query`` subsequent
|
||||
drawing commands will be predicated on the outcome of the query.
|
||||
Commands will be skipped if ``condition`` is equal to the predicate result
|
||||
(for non-boolean queries such as OCCLUSION_QUERY, zero counts as FALSE,
|
||||
non-zero as TRUE).
|
||||
|
||||
If ``mode`` is PIPE_RENDER_COND_WAIT the driver will wait for the
|
||||
query to complete before deciding whether to render.
|
||||
|
||||
If ``mode`` is PIPE_RENDER_COND_NO_WAIT and the query has not yet
|
||||
completed, the drawing command will be executed normally. If the query
|
||||
has completed, drawing will be predicated on the outcome of the query.
|
||||
|
||||
If ``mode`` is PIPE_RENDER_COND_BY_REGION_WAIT or
|
||||
PIPE_RENDER_COND_BY_REGION_NO_WAIT rendering will be predicated as above
|
||||
for the non-REGION modes but in the case that an occlusion query returns
|
||||
a non-zero result, regions which were occluded may be omitted by subsequent
|
||||
drawing commands. This can result in better performance with some GPUs.
|
||||
Normally, if the occlusion query returned a non-zero result subsequent
|
||||
drawing happens normally so fragments may be generated, shaded and
|
||||
processed even where they're known to be obscured.
|
||||
|
||||
The ''render_condition_mem'' function specifies the drawing is dependent
|
||||
on a value in memory. A buffer resource and offset denote which 32-bit
|
||||
value to use for the query. This is used for Vulkan API.
|
||||
|
||||
Flushing
|
||||
^^^^^^^^
|
||||
|
||||
``flush``
|
||||
|
||||
PIPE_FLUSH_END_OF_FRAME: Whether the flush marks the end of frame.
|
||||
|
||||
PIPE_FLUSH_DEFERRED: It is not required to flush right away, but it is required
|
||||
to return a valid fence. If fence_finish is called with the returned fence
|
||||
and the context is still unflushed, and the ctx parameter of fence_finish is
|
||||
equal to the context where the fence was created, fence_finish will flush
|
||||
the context.
|
||||
|
||||
PIPE_FLUSH_ASYNC: The flush is allowed to be asynchronous. Unlike
|
||||
``PIPE_FLUSH_DEFERRED``, the driver must still ensure that the returned fence
|
||||
will finish in finite time. However, subsequent operations in other contexts of
|
||||
the same screen are no longer guaranteed to happen after the flush. Drivers
|
||||
which use this flag must implement pipe_context::fence_server_sync.
|
||||
|
||||
PIPE_FLUSH_HINT_FINISH: Hints to the driver that the caller will immediately
|
||||
wait for the returned fence.
|
||||
|
||||
Additional flags may be set together with ``PIPE_FLUSH_DEFERRED`` for even
|
||||
finer-grained fences. Note that as a general rule, GPU caches may not have been
|
||||
flushed yet when these fences are signaled. Drivers are free to ignore these
|
||||
flags and create normal fences instead. At most one of the following flags can
|
||||
be specified:
|
||||
|
||||
PIPE_FLUSH_TOP_OF_PIPE: The fence should be signaled as soon as the next
|
||||
command is ready to start executing at the top of the pipeline, before any of
|
||||
its data is actually read (including indirect draw parameters).
|
||||
|
||||
PIPE_FLUSH_BOTTOM_OF_PIPE: The fence should be signaled as soon as the previous
|
||||
command has finished executing on the GPU entirely (but data written by the
|
||||
command may still be in caches and inaccessible to the CPU).
|
||||
|
||||
|
||||
``flush_resource``
|
||||
|
||||
Flush the resource cache, so that the resource can be used
|
||||
by an external client. Possible usage:
|
||||
- flushing a resource before presenting it on the screen
|
||||
- flushing a resource if some other process or device wants to use it
|
||||
This shouldn't be used to flush caches if the resource is only managed
|
||||
by a single pipe_screen and is not shared with another process.
|
||||
(i.e. you shouldn't use it to flush caches explicitly if you want to e.g.
|
||||
use the resource for texturing)
|
||||
|
||||
Fences
|
||||
^^^^^^
|
||||
|
||||
``pipe_fence_handle``, and related methods, are used to synchronize
|
||||
execution between multiple parties. Examples include CPU <-> GPU synchronization,
|
||||
renderer <-> windowing system, multiple external APIs, etc.
|
||||
|
||||
A ``pipe_fence_handle`` can either be 'one time use' or 're-usable'. A 'one time use'
|
||||
fence behaves like a traditional GPU fence. Once it reaches the signaled state it
|
||||
is forever considered to be signaled.
|
||||
|
||||
Once a re-usable ``pipe_fence_handle`` becomes signaled, it can be reset
|
||||
back into an unsignaled state. The ``pipe_fence_handle`` will be reset to
|
||||
the unsignaled state by performing a wait operation on said object, i.e.
|
||||
``fence_server_sync``. As a corollary to this behavior, a re-usable
|
||||
``pipe_fence_handle`` can only have one waiter.
|
||||
|
||||
This behavior is useful in producer <-> consumer chains. It helps avoid
|
||||
unnecessarily sharing a new ``pipe_fence_handle`` each time a new frame is
|
||||
ready. Instead, the fences are exchanged once ahead of time, and access is synchronized
|
||||
through GPU signaling instead of direct producer <-> consumer communication.
|
||||
|
||||
``fence_server_sync`` inserts a wait command into the GPU's command stream.
|
||||
|
||||
``fence_server_signal`` inserts a signal command into the GPU's command stream.
|
||||
|
||||
There are no guarantees that the wait/signal commands will be flushed when
|
||||
calling ``fence_server_sync`` or ``fence_server_signal``. An explicit
|
||||
call to ``flush`` is required to make sure the commands are emitted to the GPU.
|
||||
|
||||
The Gallium implementation may implicitly ``flush`` the command stream during a
|
||||
``fence_server_sync`` or ``fence_server_signal`` call if necessary.
|
||||
|
||||
Gallium frontends must ensure that ``fence_server_signal`` returns before calling
|
||||
``fence_server_sync`` on the same ``pipe_fence_handle`` even if those calls are made on
|
||||
a different ``pipe_context``.
|
||||
|
||||
Resource Busy Queries
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
``is_resource_referenced``
|
||||
|
||||
|
||||
|
||||
Blitting
|
||||
^^^^^^^^
|
||||
|
||||
These methods emulate classic blitter controls.
|
||||
|
||||
These methods operate directly on ``pipe_resource`` objects, and stand
|
||||
apart from any 3D state in the context. Each method is assumed to have an
|
||||
implicit memory barrier around itself. They do not need any explicit
|
||||
``memory_barrier``. Blitting functionality may be moved to a separate
|
||||
abstraction at some point in the future.
|
||||
|
||||
``resource_copy_region`` blits a region of a resource to a region of another
|
||||
resource, provided that both resources have the same format, or compatible
|
||||
formats, i.e., formats for which copying the bytes from the source resource
|
||||
unmodified to the destination resource will achieve the same effect of a
|
||||
textured quad blitter.. The source and destination may be the same resource,
|
||||
but overlapping blits are not permitted.
|
||||
This can be considered the equivalent of a CPU memcpy.
|
||||
|
||||
``blit`` blits a region of a resource to a region of another resource, including
|
||||
scaling, format conversion, and up-/downsampling, as well as a destination clip
|
||||
rectangle (scissors) and window rectangles. It can also optionally honor the
|
||||
current render condition (but either way the blit itself never contributes
|
||||
anything to queries currently gathering data).
|
||||
As opposed to manually drawing a textured quad, this lets the pipe driver choose
|
||||
the optimal method for blitting (like using a special 2D engine), and usually
|
||||
offers, for example, accelerated stencil-only copies even where
|
||||
pipe_caps.shader_stencil_export is not available.
|
||||
|
||||
|
||||
Transfers
|
||||
^^^^^^^^^
|
||||
|
||||
These methods are used to get data to/from a resource.
|
||||
|
||||
``transfer_map`` creates a memory mapping and the transfer object
|
||||
associated with it.
|
||||
The returned pointer points to the start of the mapped range according to
|
||||
the box region, not the beginning of the resource. If transfer_map fails,
|
||||
the returned pointer to the buffer memory is NULL, and the pointer
|
||||
to the transfer object remains unchanged (i.e. it can be non-NULL).
|
||||
|
||||
When mapping an MSAA surface, the samples are implicitly resolved to
|
||||
single-sampled for reads (returning the first sample for depth/stencil/integer,
|
||||
averaged for others). See u_transfer_helper's U_TRANSFER_HELPER_MSAA_MAP for a
|
||||
way to get that behavior using a resolve blit.
|
||||
|
||||
``transfer_unmap`` remove the memory mapping for and destroy
|
||||
the transfer object. The pointer into the resource should be considered
|
||||
invalid and discarded.
|
||||
|
||||
``texture_subdata`` and ``buffer_subdata`` perform a simplified
|
||||
transfer for simple writes. Basically transfer_map, data write, and
|
||||
transfer_unmap all in one.
|
||||
|
||||
|
||||
The box parameter to some of these functions defines a 1D, 2D or 3D
|
||||
region of pixels. This is self-explanatory for 1D, 2D and 3D texture
|
||||
targets.
|
||||
|
||||
For PIPE_TEXTURE_1D_ARRAY and PIPE_TEXTURE_2D_ARRAY, the box::z and box::depth
|
||||
fields refer to the array dimension of the texture.
|
||||
|
||||
For PIPE_TEXTURE_CUBE, the box:z and box::depth fields refer to the
|
||||
faces of the cube map (z + depth <= 6).
|
||||
|
||||
For PIPE_TEXTURE_CUBE_ARRAY, the box:z and box::depth fields refer to both
|
||||
the face and array dimension of the texture (face = z % 6, array = z / 6).
|
||||
|
||||
|
||||
.. _transfer_flush_region:
|
||||
|
||||
transfer_flush_region
|
||||
%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
If a transfer was created with ``FLUSH_EXPLICIT``, it will not automatically
|
||||
be flushed on write or unmap. Flushes must be requested with
|
||||
``transfer_flush_region``. Flush ranges are relative to the mapped range, not
|
||||
the beginning of the resource.
|
||||
|
||||
|
||||
|
||||
.. _texture_barrier:
|
||||
|
||||
texture_barrier
|
||||
%%%%%%%%%%%%%%%
|
||||
|
||||
This function flushes all pending writes to the currently-set surfaces and
|
||||
invalidates all read caches of the currently-set samplers. This can be used
|
||||
for both regular textures as well as for framebuffers read via FBFETCH.
|
||||
|
||||
|
||||
|
||||
.. _memory_barrier:
|
||||
|
||||
memory_barrier
|
||||
%%%%%%%%%%%%%%%
|
||||
|
||||
This function flushes caches according to which of the PIPE_BARRIER_* flags
|
||||
are set.
|
||||
|
||||
|
||||
|
||||
.. _resource_commit:
|
||||
|
||||
resource_commit
|
||||
%%%%%%%%%%%%%%%
|
||||
|
||||
This function changes the commit state of a part of a sparse resource. Sparse
|
||||
resources are created by setting the ``PIPE_RESOURCE_FLAG_SPARSE`` flag when
|
||||
calling ``resource_create``. Initially, sparse resources only reserve a virtual
|
||||
memory region that is not backed by memory (i.e., it is uncommitted). The
|
||||
``resource_commit`` function can be called to commit or uncommit parts (or all)
|
||||
of a resource. The driver manages the underlying backing memory.
|
||||
|
||||
The contents of newly committed memory regions are undefined. Calling this
|
||||
function to commit an already committed memory region is allowed and leaves its
|
||||
content unchanged. Similarly, calling this function to uncommit an already
|
||||
uncommitted memory region is allowed.
|
||||
|
||||
For buffers, the given box must be aligned to multiples of
|
||||
``pipe_caps.sparse_buffer_page_size``. As an exception to this rule, if the size
|
||||
of the buffer is not a multiple of the page size, changing the commit state of
|
||||
the last (partial) page requires a box that ends at the end of the buffer
|
||||
(i.e., box->x + box->width == buffer->width0).
|
||||
|
||||
|
||||
|
||||
.. _pipe_transfer:
|
||||
|
||||
PIPE_MAP
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
These flags control the behavior of a transfer object.
|
||||
|
||||
``PIPE_MAP_READ``
|
||||
Resource contents read back (or accessed directly) at transfer create time.
|
||||
|
||||
``PIPE_MAP_WRITE``
|
||||
Resource contents will be written back at transfer_unmap time (or modified
|
||||
as a result of being accessed directly).
|
||||
|
||||
``PIPE_MAP_DIRECTLY``
|
||||
a transfer should directly map the resource. May return NULL if not supported.
|
||||
|
||||
``PIPE_MAP_DISCARD_RANGE``
|
||||
The memory within the mapped region is discarded. Cannot be used with
|
||||
``PIPE_MAP_READ``.
|
||||
|
||||
``PIPE_MAP_DISCARD_WHOLE_RESOURCE``
|
||||
Discards all memory backing the resource. It should not be used with
|
||||
``PIPE_MAP_READ``.
|
||||
|
||||
``PIPE_MAP_DONTBLOCK``
|
||||
Fail if the resource cannot be mapped immediately.
|
||||
|
||||
``PIPE_MAP_UNSYNCHRONIZED``
|
||||
Do not synchronize pending operations on the resource when mapping. The
|
||||
interaction of any writes to the map and any operations pending on the
|
||||
resource are undefined. Cannot be used with ``PIPE_MAP_READ``.
|
||||
|
||||
``PIPE_MAP_FLUSH_EXPLICIT``
|
||||
Written ranges will be notified later with :ref:`transfer_flush_region`.
|
||||
Cannot be used with ``PIPE_MAP_READ``.
|
||||
|
||||
``PIPE_MAP_PERSISTENT``
|
||||
Allows the resource to be used for rendering while mapped.
|
||||
PIPE_RESOURCE_FLAG_MAP_PERSISTENT must be set when creating
|
||||
the resource.
|
||||
If COHERENT is not set, memory_barrier(PIPE_BARRIER_MAPPED_BUFFER)
|
||||
must be called to ensure the device can see what the CPU has written.
|
||||
|
||||
``PIPE_MAP_COHERENT``
|
||||
If PERSISTENT is set, this ensures any writes done by the device are
|
||||
immediately visible to the CPU and vice versa.
|
||||
PIPE_RESOURCE_FLAG_MAP_COHERENT must be set when creating
|
||||
the resource.
|
||||
|
||||
Compute kernel execution
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
A compute program can be defined, bound or destroyed using
|
||||
``create_compute_state``, ``bind_compute_state`` or
|
||||
``destroy_compute_state`` respectively.
|
||||
|
||||
Any of the subroutines contained within the compute program can be
|
||||
executed on the device using the ``launch_grid`` method. This method
|
||||
will execute as many instances of the program as elements in the
|
||||
specified N-dimensional grid, hopefully in parallel.
|
||||
|
||||
The compute program has access to four special resources:
|
||||
|
||||
* ``GLOBAL`` represents a memory space shared among all the threads
|
||||
running on the device. An arbitrary buffer created with the
|
||||
``PIPE_BIND_GLOBAL`` flag can be mapped into it using the
|
||||
``set_global_binding`` method.
|
||||
|
||||
* ``LOCAL`` represents a memory space shared among all the threads
|
||||
running in the same working group. The initial contents of this
|
||||
resource are undefined.
|
||||
|
||||
* ``PRIVATE`` represents a memory space local to a single thread.
|
||||
The initial contents of this resource are undefined.
|
||||
|
||||
* ``INPUT`` represents a read-only memory space that can be
|
||||
initialized at ``launch_grid`` time.
|
||||
|
||||
These resources use a byte-based addressing scheme, and they can be
|
||||
accessed from the compute program by means of the LOAD/STORE TGSI
|
||||
opcodes.
|
||||
|
||||
In addition, normal texture sampling is allowed from the compute
|
||||
program: ``bind_sampler_states`` may be used to set up texture
|
||||
samplers for the compute stage and ``set_sampler_views`` may
|
||||
be used to bind a number of sampler views to it.
|
||||
|
||||
Compute kernel queries
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. _get_compute_state_info:
|
||||
|
||||
get_compute_state_info
|
||||
%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
This function allows frontends to query kernel information defined inside
|
||||
``pipe_compute_state_object_info``.
|
||||
|
||||
.. _get_compute_state_subgroup_size:
|
||||
|
||||
get_compute_state_subgroup_size
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
This function returns the choosen subgroup size when ``launch_grid`` is
|
||||
called with the given block size. This doesn't need to be implemented when
|
||||
only one size is reported through ``pipe_compute_caps.subgroup_sizes`` or
|
||||
``pipe_compute_state_object_info::simd_sizes``.
|
||||
|
||||
Mipmap generation
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
If pipe_caps.generate_mipmap is true, ``generate_mipmap`` can be used
|
||||
to generate mipmaps for the specified texture resource.
|
||||
It replaces texel image levels base_level+1 through
|
||||
last_level for layers range from first_layer through last_layer.
|
||||
It returns TRUE if mipmap generation succeeds, otherwise it
|
||||
returns FALSE. Mipmap generation may fail when it is not supported
|
||||
for particular texture types or formats.
|
||||
|
||||
Device resets
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
Gallium frontends can query or request notifications of when the GPU
|
||||
is reset for whatever reason (application error, driver error). When
|
||||
a GPU reset happens, the context becomes unusable and all related state
|
||||
should be considered lost and undefined. Despite that, context
|
||||
notifications are single-shot, i.e. subsequent calls to
|
||||
``get_device_reset_status`` will return PIPE_NO_RESET.
|
||||
|
||||
* ``get_device_reset_status`` queries whether a device reset has happened
|
||||
since the last call or since the last notification by callback.
|
||||
* ``set_device_reset_callback`` sets a callback which will be called when
|
||||
a device reset is detected. The callback is only called synchronously.
|
||||
|
||||
Bindless
|
||||
^^^^^^^^
|
||||
|
||||
If pipe_caps.bindless_texture is TRUE, the following ``pipe_context`` functions
|
||||
are used to create/delete bindless handles, and to make them resident in the
|
||||
current context when they are going to be used by shaders.
|
||||
|
||||
* ``create_texture_handle`` creates a 64-bit unsigned integer texture handle
|
||||
that is going to be directly used in shaders.
|
||||
* ``delete_texture_handle`` deletes a 64-bit unsigned integer texture handle.
|
||||
* ``make_texture_handle_resident`` makes a 64-bit unsigned texture handle
|
||||
resident in the current context to be accessible by shaders for texture
|
||||
mapping.
|
||||
* ``create_image_handle`` creates a 64-bit unsigned integer image handle that
|
||||
is going to be directly used in shaders.
|
||||
* ``delete_image_handle`` deletes a 64-bit unsigned integer image handle.
|
||||
* ``make_image_handle_resident`` makes a 64-bit unsigned integer image handle
|
||||
resident in the current context to be accessible by shaders for image loads,
|
||||
stores and atomic operations.
|
||||
|
||||
Using several contexts
|
||||
----------------------
|
||||
|
||||
Several contexts from the same screen can be used at the same time. Objects
|
||||
created on one context cannot be used in another context, but the objects
|
||||
created by the screen methods can be used by all contexts.
|
||||
|
||||
Transfers
|
||||
^^^^^^^^^
|
||||
A transfer on one context is not expected to synchronize properly with
|
||||
rendering on other contexts, thus only areas not yet used for rendering should
|
||||
be locked.
|
||||
|
||||
A flush is required after transfer_unmap to expect other contexts to see the
|
||||
uploaded data, unless:
|
||||
|
||||
* Using persistent mapping. Associated with coherent mapping, unmapping the
|
||||
resource is also not required to use it in other contexts. Without coherent
|
||||
mapping, memory_barrier(PIPE_BARRIER_MAPPED_BUFFER) should be called on the
|
||||
context that has mapped the resource. No flush is required.
|
||||
|
||||
* Mapping the resource with PIPE_MAP_DIRECTLY.
|
||||
@@ -0,0 +1,14 @@
|
||||
CSO
|
||||
===
|
||||
|
||||
CSO, Constant State Objects, are a core part of Gallium's API.
|
||||
|
||||
CSO work on the principle of reusable state; they are created by filling
|
||||
out a state object with the desired properties, then passing that object
|
||||
to a context. The context returns an opaque context-specific handle which
|
||||
can be bound at any time for the desired effect.
|
||||
|
||||
.. toctree::
|
||||
:glob:
|
||||
|
||||
cso/*
|
||||
@@ -0,0 +1,124 @@
|
||||
.. _blend:
|
||||
|
||||
Blend
|
||||
=====
|
||||
|
||||
This state controls blending of the final fragments into the target rendering
|
||||
buffers.
|
||||
|
||||
Blend Factors
|
||||
-------------
|
||||
|
||||
The blend factors largely follow the same pattern as their counterparts
|
||||
in other modern and legacy drawing APIs.
|
||||
|
||||
Dual source blend factors are supported for up to 1 MRT, although
|
||||
you can advertise > 1 MRT, the stack cannot handle them for a few reasons.
|
||||
There is no definition on how the 1D array of shader outputs should be mapped
|
||||
to something that would be a 2D array (location, index). No current hardware
|
||||
exposes > 1 MRT, and we should revisit this issue if anyone ever does.
|
||||
|
||||
Logical Operations
|
||||
------------------
|
||||
|
||||
Logical operations, also known as logicops, LOPs, or ROPs, are supported.
|
||||
Only two-operand logicops are available. When logicops are enabled, all other
|
||||
blend state is ignored, including per-render-target state, so logicops are
|
||||
performed on all render targets.
|
||||
|
||||
.. warning::
|
||||
The blend_enable flag is ignored for all render targets when logical
|
||||
operations are enabled.
|
||||
|
||||
For a source component ``s`` and destination component ``d``, the logical
|
||||
operations are defined as taking the bits of each channel of each component,
|
||||
and performing one of the following operations per-channel:
|
||||
|
||||
================== =========================
|
||||
Operation Equation
|
||||
================== =========================
|
||||
``CLEAR`` :math:`0`
|
||||
``NOR`` :math:`\lnot(s \lor d)`
|
||||
``AND_INVERTED`` :math:`\lnot s \land d`
|
||||
``COPY_INVERTED`` :math:`\lnot s`
|
||||
``AND_REVERSE`` :math:`s \land \lnot d`
|
||||
``INVERT`` :math:`\lnot d`
|
||||
``XOR`` :math:`s \oplus d`
|
||||
``NAND`` :math:`\lnot(s \land d)`
|
||||
``AND`` :math:`s \land d`
|
||||
``EQUIV`` :math:`\lnot(s \oplus d)`
|
||||
``NOOP`` :math:`d`
|
||||
``OR_INVERTED`` :math:`\lnot s \lor d`
|
||||
``COPY`` :math:`s`
|
||||
``OR_REVERSE`` :math:`s \lor \lnot d`
|
||||
``OR`` :math:`s \lor d`
|
||||
``SET`` :math:`1`
|
||||
================== =========================
|
||||
|
||||
.. note::
|
||||
The logical operation names and definitions match those of the OpenGL API,
|
||||
and are similar to the ROP2 and ROP3 definitions of GDI. This is
|
||||
intentional, to ease transitions to Gallium.
|
||||
|
||||
Members
|
||||
-------
|
||||
|
||||
These members affect all render targets.
|
||||
|
||||
dither
|
||||
Whether dithering is enabled.
|
||||
|
||||
.. note::
|
||||
Dithering is completely implementation-dependent. It may be ignored by
|
||||
drivers for any reason, and some render targets may always or never be
|
||||
dithered depending on their format or usage flags.
|
||||
|
||||
logicop_enable
|
||||
Whether the blender should perform a logicop instead of blending.
|
||||
logicop_func
|
||||
The logicop to use. One of ``PIPE_LOGICOP``.
|
||||
independent_blend_enable
|
||||
If enabled, blend state is different for each render target, and
|
||||
for each render target set in the respective member of the rt array.
|
||||
If disabled, blend state is the same for all render targets, and only
|
||||
the first member of the rt array contains valid data.
|
||||
rt
|
||||
Contains the per-rendertarget blend state.
|
||||
alpha_to_coverage
|
||||
If enabled, the fragment's alpha value is used to override the fragment's
|
||||
coverage mask. The coverage mask will be all zeros if the alpha value is
|
||||
zero. The coverage mask will be all ones if the alpha value is one.
|
||||
Otherwise, the number of bits set in the coverage mask will be proportional
|
||||
to the alpha value. Note that this step happens regardless of whether
|
||||
multisample is enabled or the destination buffer is multisampled.
|
||||
alpha_to_one
|
||||
If enabled, the fragment's alpha value will be set to one. As with
|
||||
alpha_to_coverage, this step happens regardless of whether multisample
|
||||
is enabled or the destination buffer is multisampled.
|
||||
max_rt
|
||||
The index of the max render target (irrespective of whether independent
|
||||
blend is enabled), i.e. the number of MRTs minus one. This is provided
|
||||
so that the driver can avoid the overhead of programming unused MRTs.
|
||||
|
||||
|
||||
Per-rendertarget Members
|
||||
------------------------
|
||||
|
||||
blend_enable
|
||||
If blending is enabled, perform a blend calculation according to blend
|
||||
functions and source/destination factors. Otherwise, the incoming fragment
|
||||
color gets passed unmodified (but colormask still applies).
|
||||
rgb_func
|
||||
The blend function to use for RGB channels. One of PIPE_BLEND.
|
||||
rgb_src_factor
|
||||
The blend source factor to use for RGB channels. One of PIPE_BLENDFACTOR.
|
||||
rgb_dst_factor
|
||||
The blend destination factor to use for RGB channels. One of PIPE_BLENDFACTOR.
|
||||
alpha_func
|
||||
The blend function to use for the alpha channel. One of PIPE_BLEND.
|
||||
alpha_src_factor
|
||||
The blend source factor to use for the alpha channel. One of PIPE_BLENDFACTOR.
|
||||
alpha_dst_factor
|
||||
The blend destination factor to use for alpha channel. One of PIPE_BLENDFACTOR.
|
||||
colormask
|
||||
Bitmask of which channels to write. Combination of PIPE_MASK bits.
|
||||
@@ -0,0 +1,61 @@
|
||||
.. _depth-stencil-alpha:
|
||||
|
||||
Depth, Stencil, & Alpha
|
||||
=======================
|
||||
|
||||
These three states control the depth, stencil, and alpha tests, used to
|
||||
discard fragments that have passed through the fragment shader.
|
||||
|
||||
Traditionally, these three tests have been clumped together in hardware, so
|
||||
they are all stored in one structure.
|
||||
|
||||
During actual execution, the order of operations done on fragments is always:
|
||||
|
||||
* Alpha
|
||||
* Stencil
|
||||
* Depth
|
||||
|
||||
Depth Members
|
||||
-------------
|
||||
|
||||
enabled
|
||||
Whether the depth test is enabled.
|
||||
writemask
|
||||
Whether the depth buffer receives depth writes.
|
||||
func
|
||||
The depth test function. One of PIPE_FUNC.
|
||||
|
||||
Stencil Members
|
||||
---------------
|
||||
|
||||
enabled
|
||||
Whether the stencil test is enabled. For the second stencil, whether the
|
||||
two-sided stencil is enabled. If two-sided stencil is disabled, the other
|
||||
fields for the second array member are not valid.
|
||||
func
|
||||
The stencil test function. One of PIPE_FUNC.
|
||||
valuemask
|
||||
Stencil test value mask; this is ANDed with the value in the stencil
|
||||
buffer and the reference value before doing the stencil comparison test.
|
||||
writemask
|
||||
Stencil test writemask; this controls which bits of the stencil buffer
|
||||
are written.
|
||||
fail_op
|
||||
The operation to carry out if the stencil test fails. One of
|
||||
PIPE_STENCIL_OP.
|
||||
zfail_op
|
||||
The operation to carry out if the stencil test passes but the depth test
|
||||
fails. One of PIPE_STENCIL_OP.
|
||||
zpass_op
|
||||
The operation to carry out if the stencil test and depth test both pass.
|
||||
One of PIPE_STENCIL_OP.
|
||||
|
||||
Alpha Members
|
||||
-------------
|
||||
|
||||
enabled
|
||||
Whether the alpha test is enabled.
|
||||
func
|
||||
The alpha test function. One of PIPE_FUNC.
|
||||
ref_value
|
||||
Alpha test reference value; used for certain functions.
|
||||
@@ -0,0 +1,352 @@
|
||||
.. _rasterizer:
|
||||
|
||||
Rasterizer
|
||||
==========
|
||||
|
||||
The rasterizer state controls the rendering of points, lines and triangles.
|
||||
Attributes include polygon culling state, line width, line stipple,
|
||||
multisample state, scissoring and flat/smooth shading.
|
||||
|
||||
Linkage
|
||||
-------
|
||||
|
||||
clamp_vertex_color
|
||||
If set, TGSI_SEMANTIC_COLOR registers are clamped to the [0, 1] range after
|
||||
the execution of the vertex shader, before being passed to the geometry
|
||||
shader or fragment shader.
|
||||
|
||||
OpenGL: glClampColor(GL_CLAMP_VERTEX_COLOR) in GL 3.0 or
|
||||
:ext:`GL_ARB_color_buffer_float`
|
||||
|
||||
D3D11: seems always disabled
|
||||
|
||||
Note pipe_caps.vertex_color_clamped indicates whether or not the
|
||||
driver supports this control. If it's not supported, gallium frontends may
|
||||
have to insert extra clamping code.
|
||||
|
||||
|
||||
clamp_fragment_color
|
||||
Controls whether TGSI_SEMANTIC_COLOR outputs of the fragment shader
|
||||
are clamped to [0, 1].
|
||||
|
||||
OpenGL: glClampColor(GL_CLAMP_FRAGMENT_COLOR) in GL 3.0 or
|
||||
:ext:`GL_ARB_color_buffer_float`
|
||||
|
||||
D3D11: seems always disabled
|
||||
|
||||
Note pipe_caps.fragment_color_clamped indicates whether or not the
|
||||
driver supports this control. If it's not supported, gallium frontends may
|
||||
have to insert extra clamping code.
|
||||
|
||||
|
||||
Shading
|
||||
-------
|
||||
|
||||
flatshade
|
||||
If set, the provoking vertex of each polygon is used to determine the color
|
||||
of the entire polygon. If not set, fragment colors will be interpolated
|
||||
between the vertex colors.
|
||||
|
||||
The actual interpolated shading algorithm is obviously
|
||||
implementation-dependent, but will usually be Gouraud for most hardware.
|
||||
|
||||
.. note::
|
||||
|
||||
This is separate from the fragment shader input attributes
|
||||
CONSTANT, LINEAR and PERSPECTIVE. The flatshade state is needed at
|
||||
clipping time to determine how to set the color of new vertices.
|
||||
|
||||
Draw can implement flat shading by copying the provoking vertex
|
||||
color to all the other vertices in the primitive.
|
||||
|
||||
flatshade_first
|
||||
Whether the first vertex should be the provoking vertex, for most primitives.
|
||||
If not set, the last vertex is the provoking vertex.
|
||||
|
||||
There are a few important exceptions to the specification of this rule.
|
||||
|
||||
* ``PIPE_PRIMITIVE_POLYGON``: The provoking vertex is always the first
|
||||
vertex. If the caller wishes to change the provoking vertex, they merely
|
||||
need to rotate the vertices themselves.
|
||||
* ``PIPE_PRIMITIVE_QUAD``, ``PIPE_PRIMITIVE_QUAD_STRIP``: The option only has
|
||||
an effect if ``pipe_caps.quads_follow_provoking_vertex_convention`` is true.
|
||||
If it is not, the provoking vertex is always the last vertex.
|
||||
* ``PIPE_PRIMITIVE_TRIANGLE_FAN``: When set, the provoking vertex is the
|
||||
second vertex, not the first. This permits each segment of the fan to have
|
||||
a different color.
|
||||
|
||||
Polygons
|
||||
--------
|
||||
|
||||
light_twoside
|
||||
If set, there are per-vertex back-facing colors. The hardware
|
||||
(perhaps assisted by Draw) should be set up to use this state
|
||||
along with the front/back information to set the final vertex colors
|
||||
prior to rasterization.
|
||||
|
||||
The front-face vertex shader color output is marked with TGSI semantic
|
||||
COLOR[0], and back-face COLOR[1].
|
||||
|
||||
front_ccw
|
||||
Indicates whether the window order of front-facing polygons is
|
||||
counter-clockwise (TRUE) or clockwise (FALSE).
|
||||
|
||||
cull_mode
|
||||
Indicates which faces of polygons to cull, either PIPE_FACE_NONE
|
||||
(cull no polygons), PIPE_FACE_FRONT (cull front-facing polygons),
|
||||
PIPE_FACE_BACK (cull back-facing polygons), or
|
||||
PIPE_FACE_FRONT_AND_BACK (cull all polygons).
|
||||
|
||||
fill_front
|
||||
Indicates how to fill front-facing polygons, either
|
||||
PIPE_POLYGON_MODE_FILL, PIPE_POLYGON_MODE_LINE or
|
||||
PIPE_POLYGON_MODE_POINT.
|
||||
fill_back
|
||||
Indicates how to fill back-facing polygons, either
|
||||
PIPE_POLYGON_MODE_FILL, PIPE_POLYGON_MODE_LINE or
|
||||
PIPE_POLYGON_MODE_POINT.
|
||||
|
||||
poly_stipple_enable
|
||||
Whether polygon stippling is enabled.
|
||||
poly_smooth
|
||||
Controls OpenGL-style polygon smoothing/antialiasing
|
||||
|
||||
offset_point
|
||||
If set, point-filled polygons will have polygon offset factors applied
|
||||
offset_line
|
||||
If set, line-filled polygons will have polygon offset factors applied
|
||||
offset_tri
|
||||
If set, filled polygons will have polygon offset factors applied
|
||||
|
||||
offset_units
|
||||
Specifies the polygon offset bias
|
||||
offset_scale
|
||||
Specifies the polygon offset scale
|
||||
offset_clamp
|
||||
Upper (if > 0) or lower (if < 0) bound on the polygon offset result
|
||||
|
||||
|
||||
|
||||
Lines
|
||||
-----
|
||||
|
||||
line_width
|
||||
The width of lines.
|
||||
line_smooth
|
||||
Whether lines should be smoothed. Line smoothing is simply anti-aliasing.
|
||||
line_stipple_enable
|
||||
Whether line stippling is enabled.
|
||||
line_stipple_pattern
|
||||
16-bit bitfield of on/off flags, used to pattern the line stipple.
|
||||
line_stipple_factor
|
||||
When drawing a stippled line, each bit in the stipple pattern is
|
||||
repeated N times, where N = line_stipple_factor + 1.
|
||||
line_last_pixel
|
||||
Controls whether the last pixel in a line is drawn or not. OpenGL
|
||||
omits the last pixel to avoid double-drawing pixels at the ends of lines
|
||||
when drawing connected lines.
|
||||
|
||||
|
||||
Points
|
||||
------
|
||||
|
||||
sprite_coord_enable
|
||||
The effect of this state depends on pipe_caps.tgsi_texcoord !
|
||||
|
||||
Controls automatic texture coordinate generation for rendering sprite points.
|
||||
|
||||
If pipe_caps.tgsi_texcoord is false:
|
||||
When bit k in the sprite_coord_enable bitfield is set, then generic
|
||||
input k to the fragment shader will get an automatically computed
|
||||
texture coordinate.
|
||||
|
||||
If pipe_caps.tgsi_texcoord is true:
|
||||
The bitfield refers to inputs with TEXCOORD semantic instead of generic inputs.
|
||||
|
||||
The texture coordinate will be of the form (s, t, 0, 1) where s varies
|
||||
from 0 to 1 from left to right while t varies from 0 to 1 according to
|
||||
the state of 'sprite_coord_mode' (see below).
|
||||
|
||||
If any bit is set, then point_smooth MUST be disabled (there are no
|
||||
round sprites) and point_quad_rasterization MUST be true (sprites are
|
||||
always rasterized as quads). Any mismatch between these states should
|
||||
be considered a bug in the gallium frontend.
|
||||
|
||||
This feature is implemented in the Draw module but may also be
|
||||
implemented natively by GPUs or implemented with a geometry shader.
|
||||
|
||||
|
||||
sprite_coord_mode
|
||||
Specifies how the value for each shader output should be computed when drawing
|
||||
point sprites. For PIPE_SPRITE_COORD_LOWER_LEFT, the lower-left vertex will
|
||||
have coordinates (0,0,0,1). For PIPE_SPRITE_COORD_UPPER_LEFT, the upper-left
|
||||
vertex will have coordinates (0,0,0,1).
|
||||
This state is used by Draw to generate texcoords.
|
||||
|
||||
|
||||
point_quad_rasterization
|
||||
Determines if points should be rasterized according to quad or point
|
||||
rasterization rules.
|
||||
|
||||
(Legacy-only) OpenGL actually has quite different rasterization rules
|
||||
for points and point sprites - hence this indicates if points should be
|
||||
rasterized as points or according to point sprite (which decomposes them
|
||||
into quads, basically) rules. Newer GL versions no longer support the old
|
||||
point rules at all.
|
||||
|
||||
Additionally Direct3D will always use quad rasterization rules for
|
||||
points, regardless of whether point sprites are enabled or not.
|
||||
|
||||
If this state is enabled, point smoothing and antialiasing are
|
||||
disabled. If it is disabled, point sprite coordinates are not
|
||||
generated.
|
||||
|
||||
.. note::
|
||||
|
||||
Some renderers always internally translate points into quads; this state
|
||||
still affects those renderers by overriding other rasterization state.
|
||||
|
||||
point_tri_clip
|
||||
Determines if clipping of points should happen after they are converted
|
||||
to "rectangles" (required by d3d) or before (required by OpenGL, though
|
||||
this rule is ignored by some IHVs).
|
||||
It is not valid to set this to enabled but have point_quad_rasterization
|
||||
disabled.
|
||||
point_smooth
|
||||
Whether points should be smoothed. Point smoothing turns rectangular
|
||||
points into circles or ovals.
|
||||
point_size_per_vertex
|
||||
Whether the vertex shader is expected to have a point size output.
|
||||
Undefined behavior is permitted if there is disagreement between
|
||||
this flag and the actual bound shader.
|
||||
point_size
|
||||
The size of points, if not specified per-vertex.
|
||||
|
||||
|
||||
|
||||
Other Members
|
||||
-------------
|
||||
|
||||
scissor
|
||||
Whether the scissor test is enabled.
|
||||
|
||||
multisample
|
||||
Whether :term:`MSAA` is enabled.
|
||||
|
||||
half_pixel_center
|
||||
When true, the rasterizer should use (0.5, 0.5) pixel centers for
|
||||
determining pixel ownership (e.g, OpenGL, D3D10 and higher)::
|
||||
|
||||
0 0.5 1
|
||||
0 +-----+
|
||||
| |
|
||||
0.5 | X |
|
||||
| |
|
||||
1 +-----+
|
||||
|
||||
When false, the rasterizer should use (0, 0) pixel centers for determining
|
||||
pixel ownership (e.g., D3D9 or earlier)::
|
||||
|
||||
-0.5 0 0.5
|
||||
-0.5 +-----+
|
||||
| |
|
||||
0 | X |
|
||||
| |
|
||||
0.5 +-----+
|
||||
|
||||
bottom_edge_rule
|
||||
Determines what happens when a pixel sample lies precisely on a triangle
|
||||
edge.
|
||||
|
||||
When true, a pixel sample is considered to lie inside of a triangle if it
|
||||
lies on the *bottom edge* or *left edge* (e.g., OpenGL drawables)::
|
||||
|
||||
0 x
|
||||
0 +--------------------->
|
||||
|
|
||||
| +-------------+
|
||||
| | |
|
||||
| | |
|
||||
| | |
|
||||
| +=============+
|
||||
|
|
||||
y V
|
||||
|
||||
When false, a pixel sample is considered to lie inside of a triangle if it
|
||||
lies on the *top edge* or *left edge* (e.g., OpenGL FBOs, D3D)::
|
||||
|
||||
0 x
|
||||
0 +--------------------->
|
||||
|
|
||||
| +=============+
|
||||
| | |
|
||||
| | |
|
||||
| | |
|
||||
| +-------------+
|
||||
|
|
||||
y V
|
||||
|
||||
Where:
|
||||
- a *top edge* is an edge that is horizontal and is above the other edges;
|
||||
- a *bottom edge* is an edge that is horizontal and is below the other
|
||||
edges;
|
||||
- a *left edge* is an edge that is not horizontal and is on the left side of
|
||||
the triangle.
|
||||
|
||||
.. note::
|
||||
|
||||
Actually all graphics APIs use a top-left rasterization rule for pixel
|
||||
ownership, but their notion of top varies with the axis origin (which
|
||||
can be either at y = 0 or at y = height). Gallium instead always
|
||||
assumes that top is always at y=0.
|
||||
|
||||
See also:
|
||||
- https://learn.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-rasterizer-stage-rules
|
||||
- https://learn.microsoft.com/en-us/windows/win32/direct3d9/rasterization-rules
|
||||
|
||||
clip_halfz
|
||||
When true clip space in the z axis goes from [0..1] (D3D). When false
|
||||
[-1, 1] (GL)
|
||||
|
||||
depth_clip_near
|
||||
When false, the near depth clipping plane of the view volume is disabled.
|
||||
depth_clip_far
|
||||
When false, the far depth clipping plane of the view volume is disabled.
|
||||
depth_clamp
|
||||
Whether the depth value will be clamped to the interval defined by the
|
||||
near and far depth range at the per-pixel level, after polygon offset has
|
||||
been applied and before depth testing. Note that a clamp to [0,1] according
|
||||
to GL rules should always happen even if this is disabled.
|
||||
|
||||
clip_plane_enable
|
||||
For each k in [0, PIPE_MAX_CLIP_PLANES), if bit k of this field is set,
|
||||
clipping half-space k is enabled, if it is clear, it is disabled.
|
||||
The clipping half-spaces are defined either by the user clip planes in
|
||||
``pipe_clip_state``, or by the clip distance outputs of the shader stage
|
||||
preceding the fragment shader.
|
||||
If any clip distance output is written, those half-spaces for which no
|
||||
clip distance is written count as disabled; i.e. user clip planes and
|
||||
shader clip distances cannot be mixed, and clip distances take precedence.
|
||||
|
||||
conservative_raster_mode
|
||||
The conservative rasterization mode. For PIPE_CONSERVATIVE_RASTER_OFF,
|
||||
conservative rasterization is disabled. For PIPE_CONSERVATIVE_RASTER_POST_SNAP
|
||||
or PIPE_CONSERVATIVE_RASTER_PRE_SNAP, conservative rasterization is enabled.
|
||||
When conservative rasterization is enabled, the polygon smooth, line smooth,
|
||||
point smooth and line stipple settings are ignored.
|
||||
With the post-snap mode, unlike the pre-snap mode, fragments are never
|
||||
generated for degenerate primitives. Degenerate primitives, when rasterized,
|
||||
are considered back-facing and the vertex attributes and depth are that of
|
||||
the provoking vertex.
|
||||
If the post-snap mode is used with an unsupported primitive, the pre-snap
|
||||
mode is used, if supported. Behavior is similar for the pre-snap mode.
|
||||
If the pre-snap mode is used, fragments are generated with respect to the primitive
|
||||
before vertex snapping.
|
||||
|
||||
conservative_raster_dilate
|
||||
The amount of dilation during conservative rasterization.
|
||||
|
||||
subpixel_precision_x
|
||||
A bias added to the horizontal subpixel precision during conservative rasterization.
|
||||
subpixel_precision_y
|
||||
A bias added to the vertical subpixel precision during conservative rasterization.
|
||||
@@ -0,0 +1,116 @@
|
||||
.. _sampler:
|
||||
|
||||
Sampler
|
||||
=======
|
||||
|
||||
Texture units have many options for selecting texels from loaded textures;
|
||||
this state controls an individual texture unit's texel-sampling settings.
|
||||
|
||||
Texture coordinates are always treated as four-dimensional, and referred to
|
||||
with the traditional (S, T, R, Q) notation.
|
||||
|
||||
Members
|
||||
-------
|
||||
|
||||
wrap_s
|
||||
How to wrap the S coordinate. One of PIPE_TEX_WRAP_*.
|
||||
wrap_t
|
||||
How to wrap the T coordinate. One of PIPE_TEX_WRAP_*.
|
||||
wrap_r
|
||||
How to wrap the R coordinate. One of PIPE_TEX_WRAP_*.
|
||||
|
||||
The wrap modes are:
|
||||
|
||||
* ``PIPE_TEX_WRAP_REPEAT``: Standard coord repeat/wrap-around mode.
|
||||
* ``PIPE_TEX_WRAP_CLAMP_TO_EDGE``: Clamp coord to edge of texture, the border
|
||||
color is never sampled.
|
||||
* ``PIPE_TEX_WRAP_CLAMP_TO_BORDER``: Clamp coord to border of texture, the
|
||||
border color is sampled when coords go outside the range [0,1].
|
||||
* ``PIPE_TEX_WRAP_CLAMP``: The coord is clamped to the range [0,1] before
|
||||
scaling to the texture size. This corresponds to the legacy OpenGL GL_CLAMP
|
||||
texture wrap mode. Historically, this mode hasn't acted consistently across
|
||||
all graphics hardware. It sometimes acts like CLAMP_TO_EDGE or
|
||||
CLAMP_TO_BORDER. The behavior may also vary depending on linear vs.
|
||||
nearest sampling mode.
|
||||
* ``PIPE_TEX_WRAP_MIRROR_REPEAT``: If the integer part of the coordinate
|
||||
is odd, the coord becomes (1 - coord). Then, normal texture REPEAT is
|
||||
applied to the coord.
|
||||
* ``PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE``: First, the absolute value of the
|
||||
coordinate is computed. Then, regular CLAMP_TO_EDGE is applied to the coord.
|
||||
* ``PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER``: First, the absolute value of the
|
||||
coordinate is computed. Then, regular CLAMP_TO_BORDER is applied to the
|
||||
coord.
|
||||
* ``PIPE_TEX_WRAP_MIRROR_CLAMP``: First, the absolute value of the coord is
|
||||
computed. Then, regular CLAMP is applied to the coord.
|
||||
|
||||
|
||||
min_img_filter
|
||||
The image filter to use when minifying texels. One of PIPE_TEX_FILTER_*.
|
||||
mag_img_filter
|
||||
The image filter to use when magnifying texels. One of PIPE_TEX_FILTER_*.
|
||||
|
||||
The texture image filter modes are:
|
||||
|
||||
* ``PIPE_TEX_FILTER_NEAREST``: One texel is fetched from the texture image
|
||||
at the texture coordinate.
|
||||
* ``PIPE_TEX_FILTER_LINEAR``: Two, four or eight texels (depending on the
|
||||
texture dimensions; 1D/2D/3D) are fetched from the texture image and
|
||||
linearly weighted and blended together.
|
||||
|
||||
min_mip_filter
|
||||
The filter to use when minifying mipmapped textures. One of
|
||||
PIPE_TEX_MIPFILTER_*.
|
||||
|
||||
The texture mip filter modes are:
|
||||
|
||||
* ``PIPE_TEX_MIPFILTER_NEAREST``: A single mipmap level/image is selected
|
||||
according to the texture LOD (lambda) value.
|
||||
* ``PIPE_TEX_MIPFILTER_LINEAR``: The two mipmap levels/images above/below
|
||||
the texture LOD value are sampled from. The results of sampling from
|
||||
those two images are blended together with linear interpolation.
|
||||
* ``PIPE_TEX_MIPFILTER_NONE``: Mipmap filtering is disabled. All texels
|
||||
are taken from the level 0 image.
|
||||
|
||||
|
||||
compare_mode
|
||||
If set to PIPE_TEX_COMPARE_R_TO_TEXTURE, the result of texture sampling
|
||||
is not a color but a true/false value which is the result of comparing the
|
||||
sampled texture value (typically a Z value from a depth texture) to the
|
||||
texture coordinate's R component.
|
||||
If set to PIPE_TEX_COMPARE_NONE, no comparison calculation is performed.
|
||||
compare_func
|
||||
The inequality operator used when compare_mode=1. One of PIPE_FUNC_x.
|
||||
unnormalized_coords
|
||||
If set, incoming texture coordinates are used as-is to compute
|
||||
texel addresses. When set, only a subset of the texture wrap
|
||||
modes are allowed: PIPE_TEX_WRAP_CLAMP, PIPE_TEX_WRAP_CLAMP_TO_EDGE,
|
||||
and PIPE_TEX_WRAP_CLAMP_TO_BORDER. If unset, the incoming texture
|
||||
coordinates are assumed to be normalized to the range [0, 1],
|
||||
and will be scaled by the texture dimensions to compute texel
|
||||
addresses.
|
||||
lod_bias
|
||||
Bias factor which is added to the computed level of detail.
|
||||
The normal level of detail is computed from the partial derivatives of
|
||||
the texture coordinates and/or the fragment shader TEX/TXB/TXL
|
||||
instruction.
|
||||
min_lod
|
||||
Minimum level of detail, used to clamp LOD after bias. The LOD values
|
||||
correspond to mipmap levels where LOD=0 is the level 0 mipmap image.
|
||||
max_lod
|
||||
Maximum level of detail, used to clamp LOD after bias.
|
||||
border_color
|
||||
Color union used for texel coordinates that are outside the [0,width-1],
|
||||
[0, height-1] or [0, depth-1] ranges. Interpreted according to sampler
|
||||
view format, unless the driver reports
|
||||
pipe_caps.texture_border_color_quirk, in which case special care has to be
|
||||
taken (see description of the cap).
|
||||
max_anisotropy
|
||||
Maximum anisotropy ratio to use when sampling from textures. For example,
|
||||
if max_anisotropy=4, a region of up to 1 by 4 texels will be sampled.
|
||||
Set to zero to disable anisotropic filtering. Any other setting enables
|
||||
anisotropic filtering, however it's not unexpected some drivers only will
|
||||
change their filtering with a setting of 2 and higher.
|
||||
seamless_cube_map
|
||||
If set, the bilinear filter of a cube map may take samples from adjacent
|
||||
cube map faces when sampled near a texture border to produce a seamless
|
||||
look.
|
||||
@@ -0,0 +1,12 @@
|
||||
.. _shader:
|
||||
|
||||
Shader
|
||||
======
|
||||
|
||||
One of the two types of shaders supported by Gallium.
|
||||
|
||||
Members
|
||||
-------
|
||||
|
||||
tokens
|
||||
A list of tgsi_tokens.
|
||||
@@ -0,0 +1,60 @@
|
||||
.. _vertexelements:
|
||||
|
||||
Vertex Elements
|
||||
===============
|
||||
|
||||
This state controls the format of the input attributes contained in
|
||||
pipe_vertex_buffers. There is one pipe_vertex_element array member for each
|
||||
input attribute.
|
||||
|
||||
Input Formats
|
||||
-------------
|
||||
|
||||
Gallium supports a diverse range of formats for vertex data. Drivers are
|
||||
guaranteed to support 32-bit floating-point vectors of one to four components.
|
||||
Additionally, they may support the following formats:
|
||||
|
||||
* Integers, signed or unsigned, normalized or non-normalized, 8, 16, or 32
|
||||
bits wide
|
||||
* Floating-point, 16, 32, or 64 bits wide
|
||||
|
||||
At this time, support for varied vertex data formats is limited by driver
|
||||
deficiencies. It is planned to support a single uniform set of formats for all
|
||||
Gallium drivers at some point.
|
||||
|
||||
Rather than attempt to specify every small nuance of behavior, Gallium uses a
|
||||
very simple set of rules for padding out unspecified components. If an input
|
||||
uses less than four components, it will be padded out with the constant vector
|
||||
``(0, 0, 0, 1)``.
|
||||
|
||||
Fog, point size, the facing bit, and edge flags, all are in the standard
|
||||
format of ``(x, 0, 0, 1)``, and so only the first component of those inputs is
|
||||
used.
|
||||
|
||||
Position
|
||||
%%%%%%%%
|
||||
|
||||
Vertex position may be specified with two to four components. Using less than
|
||||
two components is not allowed.
|
||||
|
||||
Colors
|
||||
%%%%%%
|
||||
|
||||
Colors, both front- and back-facing, may omit the alpha component, only using
|
||||
three components. Using less than three components is not allowed.
|
||||
|
||||
Members
|
||||
-------
|
||||
|
||||
src_offset
|
||||
The byte offset of the attribute in the buffer given by
|
||||
vertex_buffer_index for the first vertex.
|
||||
instance_divisor
|
||||
The instance data rate divisor, used for instancing.
|
||||
0 means this is per-vertex data, n means per-instance data used for
|
||||
n consecutive instances (n > 0).
|
||||
vertex_buffer_index
|
||||
The vertex buffer this attribute lives in. Several attributes may
|
||||
live in the same vertex buffer.
|
||||
src_format
|
||||
The format of the attribute data. One of the PIPE_FORMAT tokens.
|
||||
@@ -0,0 +1,15 @@
|
||||
Debugging
|
||||
=========
|
||||
|
||||
Debugging utilities in gallium.
|
||||
|
||||
Debug Variables
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
All drivers respond to a set of common debug environment variables, as well as
|
||||
some driver-specific variables. Set them as normal environment variables for
|
||||
the platform or operating system you are running. For example, for Linux this
|
||||
can be done by typing "export var=value" into a console and then running the
|
||||
program from that console.
|
||||
|
||||
See :doc:`../envvars` for details.
|
||||
@@ -0,0 +1,66 @@
|
||||
Formats in gallium
|
||||
==================
|
||||
|
||||
Gallium format names mostly follow D3D10 conventions, with some extensions.
|
||||
|
||||
Format names like XnYnZnWn have the X component in the lowest-address n bits
|
||||
and the W component in the highest-address n bits; for B8G8R8A8, byte 0 is
|
||||
blue and byte 3 is alpha. Note that platform endianness is not considered
|
||||
in this definition. In C::
|
||||
|
||||
struct x8y8z8w8 { uint8_t x, y, z, w; };
|
||||
|
||||
Format aliases like XYZWstrq are (s+t+r+q)-bit integers in host endianness,
|
||||
with the X component in the s least-significant bits of the integer. In C::
|
||||
|
||||
uint32_t xyzw8888 = (x << 0) | (y << 8) | (z << 16) | (w << 24);
|
||||
|
||||
Format suffixes affect the interpretation of the channel:
|
||||
|
||||
- ``SINT``: N bit signed integer [-2^(N-1) ... 2^(N-1) - 1]
|
||||
- ``SNORM``: N bit signed integer normalized to [-1 ... 1]
|
||||
- ``SSCALED``: N bit signed integer [-2^(N-1) ... 2^(N-1) - 1]
|
||||
- ``FIXED``: Signed fixed point integer, (N/2 - 1) bits of mantissa
|
||||
- ``FLOAT``: N bit IEEE754 float
|
||||
- ``NORM``: Normalized integers, signed or unsigned per channel
|
||||
- ``UINT``: N bit unsigned integer [0 ... 2^N - 1]
|
||||
- ``UNORM``: N bit unsigned integer normalized to [0 ... 1]
|
||||
- ``USCALED``: N bit unsigned integer [0 ... 2^N - 1]
|
||||
|
||||
The difference between ``SINT`` and ``SSCALED`` is that the former are pure
|
||||
integers in shaders, while the latter are floats; likewise for ``UINT`` versus
|
||||
``USCALED``.
|
||||
|
||||
There are two exceptions for ``FLOAT``. ``R9G9B9E5_FLOAT`` is nine bits
|
||||
each of red green and blue mantissa, with a shared five bit exponent.
|
||||
``R11G11B10_FLOAT`` is five bits of exponent and five or six bits of mantissa
|
||||
for each color channel.
|
||||
|
||||
For the ``NORM`` suffix, the signedness of each channel is indicated with an
|
||||
S or U after the number of channel bits, as in ``R5SG5SB6U_NORM``.
|
||||
|
||||
The ``SRGB`` suffix is like ``UNORM`` in range, but in the sRGB colorspace.
|
||||
|
||||
Compressed formats are named first by the compression format string (``DXT1``,
|
||||
``ETC1``, etc), followed by a format-specific subtype. Refer to the
|
||||
appropriate compression spec for details.
|
||||
|
||||
Formats used in video playback are named by their FOURCC code.
|
||||
|
||||
Format names with an embedded underscore are subsampled. ``R8G8_B8G8`` is a
|
||||
single 32-bit block of two pixels, where the R and B values are repeated in
|
||||
both pixels.
|
||||
|
||||
Index buffers do not have a natural format in Gallium structures. For purposes
|
||||
of ``is_format_supported`` queries, the formats ``R8_UINT``, ``R16_UINT``, and
|
||||
``R32_UINT`` are used with ``PIPE_BIND_INDEX_BUFFER`` for 8-bit, 16-bit, and
|
||||
32-bit index buffers respectively.
|
||||
|
||||
References
|
||||
----------
|
||||
|
||||
DirectX Graphics Infrastructure documentation on DXGI_FORMAT enum:
|
||||
https://learn.microsoft.com/en-us/windows/win32/api/dxgiformat/ne-dxgiformat-dxgi_format
|
||||
|
||||
FOURCC codes for YUV formats:
|
||||
http://web.archive.org/web/20220523043110/https://www.fourcc.org/yuv/
|
||||
@@ -0,0 +1,35 @@
|
||||
Glossary
|
||||
========
|
||||
|
||||
.. glossary::
|
||||
:sorted:
|
||||
|
||||
MSAA
|
||||
Multi-Sampled Anti-Aliasing. A basic anti-aliasing technique that takes
|
||||
multiple samples of the depth buffer, and uses this information to
|
||||
smooth the edges of polygons.
|
||||
|
||||
TCL
|
||||
Transform, Clipping, & Lighting. The three stages of preparation in a
|
||||
rasterizing pipeline prior to the actual rasterization of vertices into
|
||||
fragments.
|
||||
|
||||
NPOT
|
||||
Non-power-of-two. Usually applied to textures which have at least one
|
||||
dimension which is not a power of two.
|
||||
|
||||
LOD
|
||||
Level of Detail. Also spelled "LoD". The value that determines when the
|
||||
switches between mipmaps occur during texture sampling.
|
||||
|
||||
layer
|
||||
This term is used as the name of the "3rd coordinate" of a resource.
|
||||
3D textures have zslices, cube maps have faces, 1D and 2D array textures
|
||||
have array members (other resources do not have multiple layers).
|
||||
Since the functions only take one parameter no matter what type of
|
||||
resource is used, use the term "layer" instead of a resource type
|
||||
specific one.
|
||||
|
||||
GLSL
|
||||
GL Shading Language. The official, common high-level shader language used
|
||||
in GL 2.0 and above.
|
||||
@@ -0,0 +1,24 @@
|
||||
Gallium
|
||||
=======
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
intro
|
||||
debugging
|
||||
tgsi
|
||||
screen
|
||||
resources
|
||||
format
|
||||
context
|
||||
cso
|
||||
buffermapping
|
||||
glossary
|
||||
|
||||
Indices and tables
|
||||
------------------
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`search`
|
||||
@@ -0,0 +1,9 @@
|
||||
Introduction
|
||||
============
|
||||
|
||||
What is Gallium?
|
||||
----------------
|
||||
|
||||
Gallium is essentially an API for writing graphics drivers in a largely
|
||||
device-agnostic fashion. It provides several objects which encapsulate the
|
||||
core services of graphics hardware in a straightforward manner.
|
||||
@@ -0,0 +1,128 @@
|
||||
XXX this could be converted/formatted for Sphinx someday.
|
||||
XXX do not use tabs in this file.
|
||||
|
||||
|
||||
|
||||
position ]
|
||||
primary/secondary colors ]
|
||||
generics (normals, ]
|
||||
texcoords, fog) ] User vertices / arrays
|
||||
point size ]
|
||||
edge flag ]
|
||||
primitive ID } System-generated values
|
||||
vertex ID }
|
||||
| | |
|
||||
V V V
|
||||
+-------------------+
|
||||
| Vertex shader |
|
||||
+-------------------+
|
||||
| | |
|
||||
V V V
|
||||
position
|
||||
clip distance
|
||||
generics
|
||||
front/back & primary/secondary colors
|
||||
point size
|
||||
edge flag
|
||||
primitive ID
|
||||
| | |
|
||||
V V V
|
||||
+------------------------+
|
||||
| Geometry shader |
|
||||
| (consume vertex ID) |
|
||||
| (may change prim type) |
|
||||
+------------------------+
|
||||
| | |
|
||||
V V V
|
||||
[...]
|
||||
fb layer
|
||||
| | |
|
||||
V V V
|
||||
+--------------------------+
|
||||
| Clipper |
|
||||
| (consume clip distances) |
|
||||
+--------------------------+
|
||||
| | |
|
||||
V V V
|
||||
+-------------------+
|
||||
| Polygon Culling |
|
||||
+-------------------+
|
||||
| | |
|
||||
V V V
|
||||
+-----------------------+
|
||||
| Choose front or |
|
||||
| back face color |
|
||||
| (consume other color) |
|
||||
+-----------------------+
|
||||
| | |
|
||||
V V V
|
||||
[...]
|
||||
primary/secondary colors only
|
||||
| | |
|
||||
V V V
|
||||
+-------------------+
|
||||
| Polygon Offset |
|
||||
+-------------------+
|
||||
| | |
|
||||
V V V
|
||||
+----------------------+
|
||||
| Unfilled polygons |
|
||||
| (consume edge flags) |
|
||||
| (change prim type) |
|
||||
+----------------------+
|
||||
| | |
|
||||
V V V
|
||||
position
|
||||
generics
|
||||
primary/secondary colors
|
||||
point size
|
||||
primitive ID
|
||||
fb layer
|
||||
| | |
|
||||
V V V
|
||||
+---------------------------------+
|
||||
| Optional Draw module helpers |
|
||||
| * Polygon Stipple |
|
||||
| * Line Stipple |
|
||||
| * Line AA/smooth (as tris) |
|
||||
| * Wide lines (as tris) |
|
||||
| * Wide points/sprites (as tris) |
|
||||
| * Point AA/smooth (as tris) |
|
||||
| (NOTE: these stages may emit |
|
||||
| new/extra generic attributes |
|
||||
| such as texcoords) |
|
||||
+---------------------------------+
|
||||
| | |
|
||||
V V V
|
||||
position ]
|
||||
generics (+ new/extra ones) ]
|
||||
primary/secondary colors ] Software rast vertices
|
||||
point size ]
|
||||
primitive ID ]
|
||||
fb layer ]
|
||||
| | |
|
||||
V V V
|
||||
+---------------------+
|
||||
| Triangle/Line/Point |
|
||||
| Rasterization |
|
||||
+---------------------+
|
||||
| | |
|
||||
V V V
|
||||
generic attribs
|
||||
primary/secondary colors
|
||||
primitive ID
|
||||
fragment win coord pos } System-generated values
|
||||
front/back face flag }
|
||||
| | |
|
||||
V V V
|
||||
+-------------------+
|
||||
| Fragment shader |
|
||||
+-------------------+
|
||||
| | |
|
||||
V V V
|
||||
zero or more colors
|
||||
zero or one Z value
|
||||
|
||||
|
||||
NOTE: The instance ID is not shown. It can be imagined to be a global variable
|
||||
accessible to all shader stages.
|
||||
@@ -0,0 +1,208 @@
|
||||
.. _resource:
|
||||
|
||||
Resources and derived objects
|
||||
=============================
|
||||
|
||||
Resources represent objects that hold data: textures and buffers.
|
||||
|
||||
They are mostly modelled after the resources in Direct3D 10/11, but with a
|
||||
different transfer/update mechanism, and more features for OpenGL support.
|
||||
|
||||
Resources can be used in several ways, and it is required to specify all planned uses through an appropriate set of bind flags.
|
||||
|
||||
TODO: write much more on resources
|
||||
|
||||
Transfers
|
||||
---------
|
||||
|
||||
Transfers are the mechanism used to access resources with the CPU.
|
||||
|
||||
OpenGL: OpenGL supports mapping buffers and has inline transfer functions for both buffers and textures
|
||||
|
||||
D3D11: D3D11 lacks transfers, but has special resource types that are mappable to the CPU address space
|
||||
|
||||
TODO: write much more on transfers
|
||||
|
||||
Resource targets
|
||||
----------------
|
||||
|
||||
Resource targets determine the type of a resource.
|
||||
|
||||
Note that drivers may not actually have the restrictions listed regarding
|
||||
coordinate normalization and wrap modes, and in fact efficient OpenCL
|
||||
support will probably require drivers that don't have any of them, which
|
||||
will probably be advertised with an appropriate cap.
|
||||
|
||||
TODO: document all targets. Note that both 3D and cube have restrictions
|
||||
that depend on the hardware generation.
|
||||
|
||||
|
||||
PIPE_BUFFER
|
||||
^^^^^^^^^^^
|
||||
|
||||
Buffer resource: can be used as a vertex, index, constant buffer
|
||||
(appropriate bind flags must be requested).
|
||||
|
||||
Buffers do not really have a format, it's just bytes, but they are required
|
||||
to have their type set to a R8 format (without a specific "just byte" format,
|
||||
R8_UINT would probably make the most sense, but for historic reasons R8_UNORM
|
||||
is OK too). (This is just to make some shared buffer/texture code easier so
|
||||
format size can be queried.)
|
||||
width0 serves as size, most other resource properties don't apply but must be
|
||||
set appropriately (depth0/height0/array_size must be 1, last_level 0).
|
||||
|
||||
They can be bound to stream output if supported.
|
||||
TODO: what about the restrictions lifted by the several later GL transform feedback extensions? How does one advertise that in Gallium?
|
||||
|
||||
They can be also be bound to a shader stage (for sampling) as usual by
|
||||
creating an appropriate sampler view, if the driver supports pipe_caps.texture_buffer_objects.
|
||||
This supports larger width than a 1d texture would
|
||||
(TODO limit currently unspecified, minimum must be at least 65536).
|
||||
Only the "direct fetch" sample opcodes are supported (TGSI_OPCODE_TXF,
|
||||
TGSI_OPCODE_SAMPLE_I) so the sampler state (coord wrapping etc.)
|
||||
is mostly ignored (with SAMPLE_I there's no sampler state at all).
|
||||
|
||||
They can be also be bound to the framebuffer (only as color render target, not
|
||||
depth buffer, also there cannot be a depth buffer bound at the same time) as usual
|
||||
by creating an appropriate view (this is not usable in OpenGL).
|
||||
TODO there's no CAP bit currently for this, there's also unspecified size etc. limits
|
||||
TODO: is there any chance of supporting GL pixel buffer object acceleration with this?
|
||||
|
||||
|
||||
OpenGL: vertex buffers in GL 1.5 or :ext:`GL_ARB_vertex_buffer_object`
|
||||
|
||||
- Binding to stream out requires GL 3.0 or :ext:`GL_NV_transform_feedback`
|
||||
- Binding as constant buffers requires GL 3.1 or :ext:`GL_ARB_uniform_buffer_object`
|
||||
- Binding to a sampling stage requires GL 3.1 or :ext:`GL_ARB_texture_buffer_object`
|
||||
|
||||
D3D11: buffer resources
|
||||
- Binding to a render target requires D3D_FEATURE_LEVEL_10_0
|
||||
|
||||
PIPE_TEXTURE_1D / PIPE_TEXTURE_1D_ARRAY
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
1D surface accessed with normalized coordinates.
|
||||
1D array textures are supported depending on pipe_caps.max_texture_array_layers.
|
||||
|
||||
- If pipe_caps.npot_textures is not supported,
|
||||
width must be a power of two
|
||||
- height0 must be 1
|
||||
- depth0 must be 1
|
||||
- array_size must be 1 for PIPE_TEXTURE_1D
|
||||
- Mipmaps can be used
|
||||
- Must use normalized coordinates
|
||||
|
||||
OpenGL: GL_TEXTURE_1D in GL 1.0
|
||||
|
||||
- pipe_caps.npot_textures is equivalent to GL 2.0 or :ext:`GL_ARB_texture_non_power_of_two`
|
||||
|
||||
D3D11: 1D textures in D3D_FEATURE_LEVEL_10_0
|
||||
|
||||
PIPE_TEXTURE_RECT
|
||||
^^^^^^^^^^^^^^^^^
|
||||
2D surface with OpenGL GL_TEXTURE_RECTANGLE semantics.
|
||||
|
||||
- depth0 must be 1
|
||||
- array_size must be 1
|
||||
- last_level must be 0
|
||||
- Must use unnormalized coordinates
|
||||
- Must use a clamp wrap mode
|
||||
|
||||
OpenGL: GL_TEXTURE_RECTANGLE in GL 3.1 or :ext:`GL_ARB_texture_rectangle` or
|
||||
:ext:`GL_NV_texture_rectangle`
|
||||
|
||||
OpenCL: can create OpenCL images based on this, that can then be sampled arbitrarily
|
||||
|
||||
D3D11: not supported (only PIPE_TEXTURE_2D with normalized coordinates is supported)
|
||||
|
||||
PIPE_TEXTURE_2D / PIPE_TEXTURE_2D_ARRAY
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
2D surface accessed with normalized coordinates.
|
||||
2D array textures are supported depending on pipe_caps.max_texture_array_layers.
|
||||
|
||||
- If pipe_caps.npot_textures is not supported,
|
||||
width and height must be powers of two
|
||||
- depth0 must be 1
|
||||
- array_size must be 1 for PIPE_TEXTURE_2D
|
||||
- Mipmaps can be used
|
||||
- Must use normalized coordinates
|
||||
- No special restrictions on wrap modes
|
||||
|
||||
OpenGL: GL_TEXTURE_2D in GL 1.0
|
||||
|
||||
- pipe_caps.npot_textures is equivalent to GL 2.0 or :ext:`GL_ARB_texture_non_power_of_two`
|
||||
|
||||
OpenCL: can create OpenCL images based on this, that can then be sampled arbitrarily
|
||||
|
||||
D3D11: 2D textures
|
||||
|
||||
- pipe_caps.npot_textures is equivalent to D3D_FEATURE_LEVEL_9_3
|
||||
|
||||
PIPE_TEXTURE_3D
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
3-dimensional array of texels.
|
||||
Mipmap dimensions are reduced in all 3 coordinates.
|
||||
|
||||
- If pipe_caps.npot_textures is not supported,
|
||||
width, height and depth must be powers of two
|
||||
- array_size must be 1
|
||||
- Must use normalized coordinates
|
||||
|
||||
OpenGL: GL_TEXTURE_3D in GL 1.2 or :ext:`GL_EXT_texture3D`
|
||||
|
||||
- pipe_caps.npot_textures is equivalent to GL 2.0 or :ext:`GL_ARB_texture_non_power_of_two`
|
||||
|
||||
D3D11: 3D textures
|
||||
|
||||
- pipe_caps.npot_textures is equivalent to D3D_FEATURE_LEVEL_10_0
|
||||
|
||||
PIPE_TEXTURE_CUBE / PIPE_TEXTURE_CUBE_ARRAY
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Cube maps consist of 6 2D faces.
|
||||
The 6 surfaces form an imaginary cube, and sampling happens by mapping an
|
||||
input 3-vector to the point of the cube surface in that direction.
|
||||
Cube map arrays are supported depending on pipe_caps.cube_map_array.
|
||||
|
||||
Sampling may be optionally seamless if a driver supports it (pipe_caps.seamless_cube_map),
|
||||
resulting in filtering taking samples from multiple surfaces near to the edge.
|
||||
|
||||
- Width and height must be equal
|
||||
- depth0 must be 1
|
||||
- array_size must be a multiple of 6
|
||||
- If pipe_caps.npot_textures is not supported,
|
||||
width and height must be powers of two
|
||||
- Must use normalized coordinates
|
||||
|
||||
OpenGL: GL_TEXTURE_CUBE_MAP in GL 1.3 or :ext:`GL_EXT_texture_cube_map`
|
||||
|
||||
- pipe_caps.npot_textures is equivalent to GL 2.0 or :ext:`GL_ARB_texture_non_power_of_two`
|
||||
- Seamless cube maps require GL 3.2 or :ext:`GL_ARB_seamless_cube_map` or :ext:`GL_AMD_seamless_cubemap_per_texture`
|
||||
- Cube map arrays require GL 4.0 or :ext:`GL_ARB_texture_cube_map_array`
|
||||
|
||||
D3D11: 2D array textures with the D3D11_RESOURCE_MISC_TEXTURECUBE flag
|
||||
|
||||
- pipe_caps.npot_textures is equivalent to D3D_FEATURE_LEVEL_10_0
|
||||
- Cube map arrays require D3D_FEATURE_LEVEL_10_1
|
||||
|
||||
Surfaces
|
||||
--------
|
||||
|
||||
Surfaces are views of a resource that can be bound as a framebuffer to serve as the render target or depth buffer.
|
||||
|
||||
TODO: write much more on surfaces
|
||||
|
||||
OpenGL: FBOs are collections of surfaces in GL 3.0 or :ext:`GL_ARB_framebuffer_object`
|
||||
|
||||
D3D11: render target views and depth/stencil views
|
||||
|
||||
Sampler views
|
||||
-------------
|
||||
|
||||
Sampler views are views of a resource that can be bound to a pipeline stage to be sampled from shaders.
|
||||
|
||||
TODO: write much more on sampler views
|
||||
|
||||
OpenGL: texture objects are actually sampler view and resource in a single unit
|
||||
|
||||
D3D11: shader resource views
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user