Mesa (main): docs/isl: Document ISL's units

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Jun 18 13:29:58 UTC 2021


Module: Mesa
Branch: main
Commit: 3894e42590a79551541819185fbf0161990f7953
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=3894e42590a79551541819185fbf0161990f7953

Author: Jason Ekstrand <jason at jlekstrand.net>
Date:   Mon Jun 14 21:33:35 2021 -0500

docs/isl: Document ISL's units

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11366>

---

 docs/isl/index.rst |  5 ++++
 docs/isl/units.rst | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 86 insertions(+)

diff --git a/docs/isl/index.rst b/docs/isl/index.rst
index a8d2a517b6c..e3dbd694a19 100644
--- a/docs/isl/index.rst
+++ b/docs/isl/index.rst
@@ -6,6 +6,11 @@ surface layout calculations for Intel graphics drivers.  It was originally
 written by Chad Versace and is now maintained by Jason Ekstrand and Nanley
 Chery.
 
+.. toctree::
+   :maxdepth: 2
+
+   units
+
 The core representation of a surface in ISL is :cpp:struct:`isl_surf`.
 
 .. doxygenstruct:: isl_surf
diff --git a/docs/isl/units.rst b/docs/isl/units.rst
new file mode 100644
index 00000000000..5b0db004413
--- /dev/null
+++ b/docs/isl/units.rst
@@ -0,0 +1,81 @@
+Units
+=====
+
+Almost every variable, function parameter, or struct field in ISL that carries
+a numeric value has explicit units associated with it.  The units used in ISL
+are as follows:
+
+ * Pixels (px)
+ * Samples (sa)
+ * Elements (el)
+ * Tiles (tl)
+ * Bytes (B)
+ * Rows of some other unit size (<unit>_rows)
+
+These units are fundamental to ISL because they allow us to specify information
+about a surface in a canonical way that isn't dependent on hardware generation.
+Each field in an ISL data structure that stores any sort of dimension has a
+suffix that declares the units for that particular value: ":c:expr:`_el`" for
+elements, ":c:expr:`_sa`" for samples, etc.  If the units of the particular
+field aren't quite what is wanted by the hardware, we do the conversion when we
+emit :c:expr:`RENDER_SURFACE_STATE`.
+
+This is one of the primary differences between ISL and the old miptree code and
+one of the core design principles of ISL.  In the old miptree code, we tried to
+keep everything in the same units as the hardware expects but this lead to
+unnecessary complications as the hardware evolved.  One example of this
+difference is QPitch which specifies the distance between array slices.  On
+Broadwell and earlier, QPitch field in :c:expr:`RENDER_SURFACE_STATE` was in
+rows of samples.  For block-compressed images, this meant it had to be
+a multiple of the block height.  On Skylake, it changed to always being in rows
+of elements so you have to divide the pitch in samples by the compresssion
+block height.  Since the old surface state code tries to store things in
+hardware units, everyone who ever reads :cpp:expr:`brw_mipmap_tree::qpitch` has
+to change their interpretation based on hardware generation and whether or not
+the surface was block-compressed.  In ISL, we have
+:cpp:member:`isl_surf::array_pitch_el_rows` which, as the name says, is in rows
+of elements.  On Broadwell and earlier, we have to multiply by the block size
+of the texture when we finally fill out the hardware packet.  However, the
+consistency of always being in rows of elements makes any other users of the
+field much simpler because they never have to look at hardware generation or
+whether or not the image is block-compressed.
+
+**Pixels** are the most straightforward unit and are where everything starts. A
+pixel simply corresponds to a single pixel (or texel if you prefer) in the
+surface.  For multisampled surfaces, a pixel may contain one or more samples.
+For compressed textures, a compression block may contain one or more pixels.
+When initially creating a surface, everything passed to isl_surf_init is
+implicitly in terms of pixels because this is what all of the APIs use.
+
+The next unit in ISL's repertoire is **samples**.  In a multisampled surface,
+each pixel corresponds to some number of samples given by
+:cpp:member:`isl_surf::samples`.  The exact layout of the samples depends on
+the value of :cpp:member:`isl_surf::msaa_layout`.  If the layout is
+:cpp:enumerator:`ISL_MSAA_LAYOUT_ARRAY` then each logical array in the surface
+corresponds to :cpp:member:`isl_surf::samples` actual slices
+in the resulting surface, one per array slice.  If the layout is
+:cpp:enumerator:`ISL_MSAA_LAYOUT_INTERLEAVED` then each pixel corresponds to a
+2x1, 2x2, 4x2, or 4x4 grid of samples.  In order to aid in calculations, one of
+the first things ISL does is to compute :cpp:member:`isl_surf::phys_level0_sa`
+which gives the dimensions of the base miplevel of the surface in samples.  The
+type of :cpp:member:`isl_surf::phys_level0_sa` is :cpp:struct:`isl_extent4d`
+which allows us to express both the array and interleaved cases. Most of the
+calculations of how the different miplevels and array slices are laid out is
+done in terms of samples.
+
+Next, we have surface **elements**.  An element is the basic unit of actual
+surface memory. For multisampled textures, an element is equal to a single
+sample. For block compressed textures, an element corresponds to an entire
+compression block. The conversion from samples to elements is given by dividing
+by the block width and block height of the surface format. This is true
+regardless of whether or not the surface is multisampled; for multisampled
+compressed textures (these exist for certain auxiliary formats), the block
+width and block height are expressed in samples. Pixels cannot be converted
+directly to elements or vice versa; any conversion between pixels and elements
+*must* go through samples.
+
+The final surface unit is **tiles**. A tile is a large rectangular block of
+surface data that all fits in a single contiguous block of memory (usually a 4K
+or 64K page, depending on tile format). Tiles are used to provide an
+arrangement of the data in memory that yields better cache performance. The
+size of a tile is always specified in surface elements.



More information about the mesa-commit mailing list