panfrost/docs: Document varyings
Signed-off-by: Lorenzo Rossi <lorenzo.rossi@collabora.com> Reviewed-by: Faith Ekstrand <faith.ekstrand@collabora.com> Acked-by: Eric R. Smith <eric.smith@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38681>
This commit is contained in:
parent
51f8bf028b
commit
f9819925ca
1 changed files with 110 additions and 0 deletions
110
docs/drivers/panfrost/varyings.rst
Normal file
110
docs/drivers/panfrost/varyings.rst
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
Varyings
|
||||
========
|
||||
|
||||
This is the naming convention followed by the hardware (slightly different
|
||||
from Vulkan naming):
|
||||
|
||||
- "Attribute": per-vertex data
|
||||
- "Varying": per-fragment data
|
||||
|
||||
Thus vertex shaders always interact with attributes and fragment/pixel shaders
|
||||
only interact with varyings (commonly shortened to "VAR").
|
||||
|
||||
|
||||
Hardware descriptors
|
||||
====================
|
||||
|
||||
Before Valhall there were two types of hardware descriptors:
|
||||
|
||||
- ``AttributeDescriptor``: Descriptor for a single attribute in a larger buffer,
|
||||
contains offset, stride and the in-memory format.
|
||||
- ``BufferDescriptor``: Buffer, when used for attributes and varyings it
|
||||
contains: pointer, size and stride
|
||||
|
||||
Midgard (v5)
|
||||
============
|
||||
Attributes are loaded/stored using ``LD_ATTR``/``ST_ATTR``, those query the
|
||||
attribute descriptors and buffer descriptors to find the real global memory
|
||||
offset before loading/storing.
|
||||
All varyings are loaded using ``LD_VAR``, including flat attributes (using a
|
||||
modifier), and special attributes (position, psiz, ecc...). Special attributes
|
||||
require a special descriptor, that is not backed by any buffer, it generates
|
||||
data on-the-fly.
|
||||
There is a concept of in-memory format and register format, the first is written
|
||||
inside of the ``AttributeDescriptor`` while the register format is a modifier of
|
||||
the instructions, when those two disagree the hardware will try to convert them,
|
||||
this is only supported between int-int or float-float operations.
|
||||
|
||||
|
||||
Bifrost (v6)
|
||||
============
|
||||
Changes:
|
||||
|
||||
- ``ST_ATTR`` is replaced by ``LEA_ATTR`` and ``ST_CVT`` pairs.
|
||||
|
||||
- ``LEA_ATTR`` queries memory address and format from the appropriate
|
||||
descriptor.
|
||||
- ``ST_CVT`` performs the actual conversion and memory store.
|
||||
- A new ``LD_VAR_SPECIAL`` is introduced, now special attributes do not need
|
||||
special descriptors.
|
||||
- ``LD_VAR`` only handles interpolated varyings, flat varyings are now handled
|
||||
by ``LD_VAR_FLAT``.
|
||||
|
||||
Valhall (v9)
|
||||
============
|
||||
Valhall introduced layout-specific instructions, ``LEA_BUF`` and ``LD_VAR_BUF``,
|
||||
those do not use ``AttributeDescriptor`` but read ``BufferDescriptor`` directly.
|
||||
These new instructions bake the offset and in-memory format of the attribute
|
||||
inside of the shader code itself, saving a lookup. If all shaders in a program
|
||||
use those instructions, we can remove all ``AttributeDescriptor``. If the
|
||||
shaders aren't compiled together, one of the shaders cannot know the data layout,
|
||||
and it needs to fall back to the old ``AttributeDescriptor``-based path. We
|
||||
also have to fall back to ``AttributeDescriptor`` completely if the attribute
|
||||
offset overflows the immediate field.
|
||||
|
||||
``LD_VAR_BUF`` only supports ``.f16`` and ``.f32`` as register modifiers, we can
|
||||
also load (flat) ints with those. We need to specify no conversion
|
||||
(``.f16.src_flat16`` or ``.f32.src_flat32``), but with those we can load both
|
||||
16-bit and 32-bit integers.
|
||||
|
||||
In this architecture the descriptors got a major update too and now there is
|
||||
just one set of descriptors for both the VS and FS.
|
||||
|
||||
|
||||
Challenges
|
||||
==========
|
||||
Theoretically, the output types from the VS and input types from the FS should
|
||||
always agree. In practice we cannot always trust the varyings types given to us,
|
||||
here are some challenging examples:
|
||||
|
||||
* Shaders are allowed to use the same types with different precision modifiers.
|
||||
* ``nir_opt_varying`` erases highp flat types with "float32" and packs them
|
||||
together.
|
||||
* Some games like to play with ``intBitsToFloat`` / ``floatBitsToInt``, so it's
|
||||
possible to have VS write int and FS read float (in that case, we treat the
|
||||
underlying bits as float, allowing for NaN normalization)
|
||||
|
||||
In practice you have to follow these rules:
|
||||
|
||||
* Only FS knows a varying smoothness, VS sees everything as flat.
|
||||
* When linked together, you cannot trust highp flat types, but you can trust
|
||||
precision
|
||||
* While loading/storing data, mistaking a float for an int is ok, mistaking an
|
||||
int for a float seems to be lossy even without bit-size conversions. Be
|
||||
conservative on what you say is a float.
|
||||
* You cannot lower flat varyings after they passed through ``nir_opt_varying``
|
||||
|
||||
Current implementation rules:
|
||||
|
||||
* VS decides the memory layout
|
||||
* On v9+, FS decides the descriptor formats, VS uses auto32 for 32-bit types
|
||||
* On v7-, descriptor formats can mismatch (VS int - FS float)
|
||||
* Descriptor formats always match what the instructions are using (unless V9
|
||||
auto32)
|
||||
|
||||
|
||||
To regain the type information:
|
||||
|
||||
* in VS, every highp varying is written as U32
|
||||
* in FS, highp flat varyings are read as U32, highp smooth are read as F32
|
||||
* for mediump, we trust the original type
|
||||
Loading…
Add table
Add a link
Reference in a new issue