docs/isl: use hawkmoth instead of doxygen

Use the hawkmoth c:auto* directives to incorporate isl documentation.

Convert @param style parameter descriptions to rst info field lists.
Add static stubs for generated headers. Fix a lot of references, in
particular the symbols are now in the Sphinx C domain, not C++
domain. Tweak syntax here and there.

Based on the earlier work by Erik Faye-Lund <kusmabite@gmail.com>

Reviewed-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24507>
This commit is contained in:
Jani Nikula
2023-08-04 18:59:58 +03:00
committed by Marge Bot
parent eabd93bba8
commit ae74d486ad
12 changed files with 294 additions and 237 deletions

View File

@@ -8,7 +8,7 @@ more memory is allocated, the scheme allows us to reduce our over-all memory
bandwidth since the auxiliary data is much smaller than the main surface.
The simplest example of this is single-sample fast clears
(:cpp:enumerator:`isl_aux_usage::ISL_AUX_USAGE_CCS_D`) on Ivy Bridge through
(:c:enumerator:`isl_aux_usage.ISL_AUX_USAGE_CCS_D`) on Ivy Bridge through
Broadwell and later. For this scheme, the auxiliary surface stores a single
bit for each cache-line-pair in the main surface. If that bit is set, then the
entire cache line pair contains only the clear color as provided in the
@@ -43,12 +43,19 @@ Types of surface compression
Intel hardware has several different compression schemes that all work along
similar lines:
.. doxygenenum:: isl_aux_usage
.. doxygenfunction:: isl_aux_usage_has_fast_clears
.. doxygenfunction:: isl_aux_usage_has_compression
.. doxygenfunction:: isl_aux_usage_has_hiz
.. doxygenfunction:: isl_aux_usage_has_mcs
.. doxygenfunction:: isl_aux_usage_has_ccs
.. c:autoenum:: isl_aux_usage
:file: src/intel/isl/isl.h
:members:
.. c:autofunction:: isl_aux_usage_has_fast_clears
.. c:autofunction:: isl_aux_usage_has_compression
.. c:autofunction:: isl_aux_usage_has_hiz
.. c:autofunction:: isl_aux_usage_has_mcs
.. c:autofunction:: isl_aux_usage_has_ccs
Creating auxiliary surfaces
---------------------------
@@ -57,10 +64,13 @@ Each type of data compression requires some type of auxiliary data on the side.
For most, this involves a second auxiliary surface. ISL provides helpers for
creating each of these types of surfaces:
.. doxygenfunction:: isl_surf_get_hiz_surf
.. doxygenfunction:: isl_surf_get_mcs_surf
.. doxygenfunction:: isl_surf_supports_ccs
.. doxygenfunction:: isl_surf_get_ccs_surf
.. c:autofunction:: isl_surf_get_hiz_surf
.. c:autofunction:: isl_surf_get_mcs_surf
.. c:autofunction:: isl_surf_supports_ccs
.. c:autofunction:: isl_surf_get_ccs_surf
Compression state tracking
--------------------------
@@ -76,14 +86,20 @@ given surface.
To help drivers keep track of what all is going on and when resolves need to be
inserted, ISL provides a finite state machine which tracks the current state of
the main surface and auxiliary data and their relationship to each other. The
states are encoded with the :cpp:enum:`isl_aux_state` enum. ISL also provides
states are encoded with the :c:enum:`isl_aux_state` enum. ISL also provides
helper functions for operating the state machine and determining what aux op
(if any) is required to get to the right state for a given operation.
.. doxygenenum:: isl_aux_state
.. doxygenfunction:: isl_aux_state_has_valid_primary
.. doxygenfunction:: isl_aux_state_has_valid_aux
.. doxygenenum:: isl_aux_op
.. doxygenfunction:: isl_aux_prepare_access
.. doxygenfunction:: isl_aux_state_transition_aux_op
.. doxygenfunction:: isl_aux_state_transition_write
.. c:autoenum:: isl_aux_state
.. c:autofunction:: isl_aux_state_has_valid_primary
.. c:autofunction:: isl_aux_state_has_valid_aux
.. c:autoenum:: isl_aux_op
.. c:autofunction:: isl_aux_prepare_access
.. c:autofunction:: isl_aux_state_transition_aux_op
.. c:autofunction:: isl_aux_state_transition_write

View File

@@ -14,9 +14,9 @@ powerful Sky Lake form.
The documentation for Ivy Bridge through Broadwell overloads the term MCS for
referring both to the *multisample control surface* used for multisample
compression and the control surface used for fast-clears. In ISL, the
:cpp:enumerator:`isl_aux_usage::ISL_AUX_USAGE_MCS` enum always refers to
:c:enumerator:`isl_aux_usage.ISL_AUX_USAGE_MCS` enum always refers to
multisample color compression while the
:cpp:enumerator:`isl_aux_usage::ISL_AUX_USAGE_CCS_` enums always refer to
:c:enumerator:`isl_aux_usage.ISL_AUX_USAGE_CCS_` enums always refer to
single-sampled color compression. Throughout this chapter and the rest of the
ISL documentation, we will use the term "color control surface", abbreviated
CCS, to denote the control surface used for both fast-clears and color
@@ -143,10 +143,10 @@ itself. The way ISL does CCS layout calculations is by a very careful and
subtle application of its normal surface layout code.
Above, we described the CCS data layout as mapping of address bits. In
ISL, this is represented by :cpp:enumerator:`isl_tiling::ISL_TILING_CCS`. The
ISL, this is represented by :c:enumerator:`isl_tiling.ISL_TILING_CCS`. The
logical and physical tile dimensions corresponding to the above mapping.
We also have special :cpp:enum:`isl_format` enums for CCS. These formats are 1
We also have special :c:enum:`isl_format` enums for CCS. These formats are 1
bit-per-pixel on Ivy Bridge through Broadwell and 2 bits-per-pixel on Skylake
and above to correspond to the 1 and 2-bit values represented in the CCS data.
They have a block size (similar to a block compressed format such as BC or
@@ -154,10 +154,10 @@ ASTC) which says what area (in surface elements) in the main surface is covered
by a single CCS element (1 or 2-bit). Because this depends on the main surface
tiling and format, we have several different CCS formats.
Once the appropriate :cpp:enum:`isl_format` has been selected, computing the
Once the appropriate :c:enum:`isl_format` has been selected, computing the
size and layout of a CCS surface is as simple as passing the same surface
creation parameters to :cpp:func:`isl_surf_init_s` as were used to create the
primary surface only with :cpp:enumerator:`isl_tiling::ISL_TILING_CCS` and the
creation parameters to :c:func:`isl_surf_init_s` as were used to create the
primary surface only with :c:enumerator:`isl_tiling.ISL_TILING_CCS` and the
correct CCS format. This not only results in a correctly sized surface but
most other ISL helpers for things such as computing offsets into surfaces work
correctly as well.

View File

@@ -3,7 +3,7 @@ Surface Formats
A surface format describes the encoding of color information into the actual
data stored in memory. Surface formats in isl are specified via the
:cpp:enum:`isl_format` enum. A complete list of surface formats is included at
:c:enum:`isl_format` enum. A complete list of surface formats is included at
the end of this chapter.
In general, a surface format definition consists of two parts: encoding and
@@ -19,9 +19,11 @@ data is unsigned normalized where the range of an unsigned integer of a
particular size is mapped linearly onto the interval [0, 1]. While normalized
is certainly the most common representation for color data, not all data is
color data, and not all values are nicely bounded. The possible data encodings
are specified by :cpp:enum:`isl_base_type`:
are specified by :c:enum:`isl_base_type`:
.. doxygenenum:: isl_base_type
.. c:autoenum:: isl_base_type
:file: src/intel/isl/isl.h
:members:
Data Layout
-----------
@@ -170,27 +172,27 @@ target.
Surface Format Introspection API
--------------------------------
ISL provides an API for introspecting the :cpp:enum:`isl_format` enum and
ISL provides an API for introspecting the :c:enum:`isl_format` enum and
getting various bits of information about a format. ISL provides helpers for
introspecting both the data layout of an :cpp:enum:`isl_format` and the
introspecting both the data layout of an :c:enum:`isl_format` and the
capabilities of that format for a particular piece of Intel hardware.
Format Layout Introspection
^^^^^^^^^^^^^^^^^^^^^^^^^^^
To get the layout of a given :cpp:enum:`isl_format`, call
:cpp:func:`isl_format_get_layout`:
To get the layout of a given :c:enum:`isl_format`, call
:c:func:`isl_format_get_layout`:
.. doxygenfunction:: isl_format_get_layout
.. c:autofunction:: isl_format_get_layout
.. doxygenstruct:: isl_format_layout
.. c:autostruct:: isl_format_layout
:members:
.. doxygenstruct:: isl_channel_layout
.. c:autostruct:: isl_channel_layout
:members:
There are also quite a few helpers for many of the common cases that allow you
to avoid using :cpp:struct:`isl_format_layout` manually. There are a lot of
to avoid using :c:struct:`isl_format_layout` manually. There are a lot of
them so we won't include a full list here. Look at isl.h for more details.
Hardware Format Support Introspection
@@ -202,27 +204,39 @@ formats. However, for the purposes of code cleanliness, the table is not
exposed directly and, instead, hardware support information is exposed via
a set of helper functions:
.. doxygenfunction:: isl_format_supports_rendering
.. doxygenfunction:: isl_format_supports_alpha_blending
.. doxygenfunction:: isl_format_supports_sampling
.. doxygenfunction:: isl_format_supports_filtering
.. doxygenfunction:: isl_format_supports_vertex_fetch
.. doxygenfunction:: isl_format_supports_typed_writes
.. doxygenfunction:: isl_format_supports_typed_reads
.. doxygenfunction:: isl_format_supports_ccs_d
.. doxygenfunction:: isl_format_supports_ccs_e
.. doxygenfunction:: isl_format_supports_multisampling
.. doxygenfunction:: isl_formats_are_ccs_e_compatible
.. c:autofunction:: isl_format_supports_rendering
.. c:autofunction:: isl_format_supports_alpha_blending
.. c:autofunction:: isl_format_supports_sampling
.. c:autofunction:: isl_format_supports_filtering
.. c:autofunction:: isl_format_supports_vertex_fetch
.. c:autofunction:: isl_format_supports_typed_writes
:file: src/intel/isl/isl_format.c
.. c:autofunction:: isl_format_supports_typed_reads
.. c:autofunction:: isl_format_supports_ccs_d
.. c:autofunction:: isl_format_supports_ccs_e
.. c:autofunction:: isl_format_supports_multisampling
.. c:autofunction:: isl_formats_are_ccs_e_compatible
Surface Format Enums
--------------------
Everything in ISL is done in terms of the :cpp:enum:`isl_format` enum. However,
Everything in ISL is done in terms of the :c:enum:`isl_format` enum. However,
for the sake of interacting with other parts of Mesa, we provide a helper for
converting a :cpp:enum:`pipe_format` to an :cpp:enum:`isl_format`:
converting a :c:enum:`pipe_format` to an :c:enum:`isl_format`:
.. doxygenfunction:: isl_format_for_pipe_format
.. c:autofunction:: isl_format_for_pipe_format
The :cpp:enum:`isl_format` enum is as follows:
The :c:enum:`isl_format` enum is as follows:
.. doxygenenum:: isl_format
.. c:autoenum:: isl_format
:members:

View File

@@ -26,10 +26,10 @@ rendering, things are pretty straightforward: you need one HiZ surface for each
main surface slice. With layered rendering, however, we have to be a bit more
clever because we need a "real" array surface at each LOD. ISL solves this
with a special miptree layout for layered rendering
:cpp:enumerator:`isl_dim_layout::ISL_DIM_LAYOUT_GFX6_STENCIL_HIZ` which lays
:c:enumerator:`isl_dim_layout.ISL_DIM_LAYOUT_GFX6_STENCIL_HIZ` which lays
out the surface as a miptree of layered images instead of an array of miptrees.
See the docs for
:cpp:enumerator:`isl_dim_layout::ISL_DIM_LAYOUT_GFX6_STENCIL_HIZ` for a nice
:c:enumerator:`isl_dim_layout.ISL_DIM_LAYOUT_GFX6_STENCIL_HIZ` for a nice
description along with an ASCII art diagram of the layout.
Also, neither ``3DSTATE_STENCIL_BUFFER`` nor ``3DSTATE_HIER_DEPTH_BUFFER`` have
@@ -39,16 +39,16 @@ pulled from ``3DSTATE_DEPTH_BUFFER``. When you combine this with the lack of
LOD, this means that, technically, we have a full-sized single-LOD stencil or
HiZ surface at each miplevel of which only the upper left-hand corner of each
array slice ever gets used. The net effect of this is that, in
:cpp:enumerator:`isl_dim_layout::ISL_DIM_LAYOUT_GFX6_STENCIL_HIZ`, all LODs
:c:enumerator:`isl_dim_layout.ISL_DIM_LAYOUT_GFX6_STENCIL_HIZ`, all LODs
share the same QPitch even though it's horribly wasteful. This is actually
pretty convenient for ISL because we only have the one
:cpp:member:`isl_surf::array_pitch_el_rows` field.
:c:member:`isl_surf.array_pitch_el_rows` field.
Due to difficulties with plumbing relocation deltas through ISL's
depth/stencil/hiz emit interface, we can't handle this all automatically in
ISL. Instead, it's left up to the driver to do this offsetting. ISL does
provide helpers for computing the offsets and they work fine with
:cpp:enumerator:`isl_dim_layout::ISL_DIM_LAYOUT_GFX6_STENCIL_HIZ` so all that's
:c:enumerator:`isl_dim_layout.ISL_DIM_LAYOUT_GFX6_STENCIL_HIZ` so all that's
really required is to call the ISL helper and add the computed offset to the
HiZ or stencil buffer address. The following is an excerpt from BLORP where we
do this as an example:

View File

@@ -16,7 +16,8 @@ Chery.
ccs
hiz
The core representation of a surface in ISL is :cpp:struct:`isl_surf`.
The core representation of a surface in ISL is :c:struct:`isl_surf`.
.. doxygenstruct:: isl_surf
.. c:autostruct:: isl_surf
:file: src/intel/isl/isl.h
:members:

View File

@@ -73,13 +73,16 @@ ISL Representation
------------------
The structure of any given tiling format is represented by ISL using the
:cpp:enum:`isl_tiling` enum and the :cpp:struct:`isl_tile_info` structure:
:c:enum:`isl_tiling` enum and the :c:struct:`isl_tile_info` structure:
.. doxygenenum:: isl_tiling
.. c:autoenum:: isl_tiling
:file: src/intel/isl/isl.h
:members:
.. doxygenfunction:: isl_tiling_get_info
.. c:autofunction:: isl_tiling_get_info
:file: src/intel/isl/isl.c
.. doxygenstruct:: isl_tile_info
.. c:autostruct:: isl_tile_info
:members:
The ``isl_tile_info`` structure has two different sizes for a tile: a logical
@@ -97,11 +100,11 @@ image in bytes given a width and height in elements is as follows:
uint32_t size = height_tl * tile_info.phys_extent_el.h * row_pitch;
It is very important to note that there is no direct conversion between
:cpp:member:`isl_tile_info::logical_extent_el` and
:cpp:member:`isl_tile_info::phys_extent_B`. It is tempting to assume that the
:c:member:`isl_tile_info.logical_extent_el` and
:c:member:`isl_tile_info.phys_extent_B`. It is tempting to assume that the
logical and physical heights are the same and simply divide the width of
:cpp:member:`isl_tile_info::phys_extent_B` by the size of the format (which is
what the PRM does) to get :cpp:member:`isl_tile_info::logical_extent_el` but
:c:member:`isl_tile_info.phys_extent_B` by the size of the format (which is
what the PRM does) to get :c:member:`isl_tile_info.logical_extent_el` but
this is not at all correct. Some tiling formats have logical and physical
heights that differ and so no such calculation will work in general. The
easiest case study for this is W-tiling. From the Sky Lake PRM Vol. 2d,
@@ -302,10 +305,10 @@ the tile are given by the table below:
=========================================== =========== =========== =========== =========== =========== =========== =========== =========== =========== =========== =========== ===========
Tiling 11 10 9 8 7 6 5 4 3 2 1 0
=========================================== =========== =========== =========== =========== =========== =========== =========== =========== =========== =========== =========== ===========
:cpp:enumerator:`isl_tiling::ISL_TILING_X` :math:`v_2` :math:`v_1` :math:`v_0` :math:`u_8` :math:`u_7` :math:`u_6` :math:`u_5` :math:`u_4` :math:`u_3` :math:`u_2` :math:`u_1` :math:`u_0`
:cpp:enumerator:`isl_tiling::ISL_TILING_Y0` :math:`u_6` :math:`u_5` :math:`u_4` :math:`v_4` :math:`v_3` :math:`v_2` :math:`v_1` :math:`v_0` :math:`u_3` :math:`u_2` :math:`u_1` :math:`u_0`
:cpp:enumerator:`isl_tiling::ISL_TILING_W` :math:`u_5` :math:`u_4` :math:`u_3` :math:`v_5` :math:`v_4` :math:`v_3` :math:`v_2` :math:`u_2` :math:`v_1` :math:`u_1` :math:`v_0` :math:`u_0`
:cpp:enumerator:`isl_tiling::ISL_TILING_4` :math:`v_4` :math:`v_3` :math:`u_6` :math:`v_2` :math:`u_5` :math:`u_4` :math:`v_1` :math:`v_0` :math:`u_3` :math:`u_2` :math:`u_1` :math:`u_0`
:c:enumerator:`isl_tiling.ISL_TILING_X` :math:`v_2` :math:`v_1` :math:`v_0` :math:`u_8` :math:`u_7` :math:`u_6` :math:`u_5` :math:`u_4` :math:`u_3` :math:`u_2` :math:`u_1` :math:`u_0`
:c:enumerator:`isl_tiling.ISL_TILING_Y0` :math:`u_6` :math:`u_5` :math:`u_4` :math:`v_4` :math:`v_3` :math:`v_2` :math:`v_1` :math:`v_0` :math:`u_3` :math:`u_2` :math:`u_1` :math:`u_0`
:c:enumerator:`isl_tiling.ISL_TILING_W` :math:`u_5` :math:`u_4` :math:`u_3` :math:`v_5` :math:`v_4` :math:`v_3` :math:`v_2` :math:`u_2` :math:`v_1` :math:`u_1` :math:`v_0` :math:`u_0`
:c:enumerator:`isl_tiling.ISL_TILING_4` :math:`v_4` :math:`v_3` :math:`u_6` :math:`v_2` :math:`u_5` :math:`u_4` :math:`v_1` :math:`v_0` :math:`u_3` :math:`u_2` :math:`u_1` :math:`u_0`
=========================================== =========== =========== =========== =========== =========== =========== =========== =========== =========== =========== =========== ===========
Constructing the mapping this way makes a lot of sense when you think about

View File

@@ -30,10 +30,10 @@ 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 compression
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
hardware units, everyone who ever reads :c: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
:c: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
@@ -49,16 +49,16 @@ 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
:c:member:`isl_surf.samples`. The exact layout of the samples depends on
the value of :c:member:`isl_surf.msaa_layout`. If the layout is
:c:enumerator:`ISL_MSAA_LAYOUT_ARRAY` then each logical array in the surface
corresponds to :c: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
:c: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`
the first things ISL does is to compute :c: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`
type of :c:member:`isl_surf.phys_level0_sa` is :c: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.