Home | History | Annotate | only in /xsrc/external/mit/MesaLib/dist/src/amd/compiler
Up to higher level directory
NameDateSize
.clang-format09-May-20223.6K
aco_assembler.cpp09-May-202237K
aco_builder_h.py09-May-202221K
aco_dead_code_analysis.cpp09-May-20223.5K
aco_dominance.cpp09-May-20223.1K
aco_form_hard_clauses.cpp09-May-20223.6K
aco_insert_exec_mask.cpp09-May-202243.7K
aco_insert_NOPs.cpp09-May-202235.1K
aco_insert_waitcnt.cpp09-May-202227.3K
aco_instruction_selection.cpp09-May-2022499.5K
aco_instruction_selection.h09-May-20223.8K
aco_instruction_selection_setup.cpp09-May-202237.1K
aco_interface.cpp09-May-202211K
aco_interface.h09-May-20221.8K
aco_ir.cpp09-May-202228.1K
aco_ir.h09-May-202271.2K
aco_live_var_analysis.cpp09-May-202215.5K
aco_lower_phis.cpp09-May-202213.3K
aco_lower_to_cssa.cpp09-May-202218.5K
aco_lower_to_hw_instr.cpp09-May-2022102.4K
aco_opcodes.py09-May-202284.3K
aco_opcodes_cpp.py09-May-20222.7K
aco_opcodes_h.py09-May-20221.6K
aco_opt_value_numbering.cpp09-May-202218K
aco_optimizer.cpp09-May-2022150.9K
aco_optimizer_postRA.cpp09-May-202216.8K
aco_print_asm.cpp09-May-20229.7K
aco_print_ir.cpp09-May-202231.1K
aco_reduce_assign.cpp09-May-20226.9K
aco_register_allocation.cpp09-May-2022107.2K
aco_reindex_ssa.cpp09-May-20223.6K
aco_scheduler.cpp09-May-202239.3K
aco_spill.cpp09-May-202277.4K
aco_ssa_elimination.cpp09-May-202213.9K
aco_statistics.cpp09-May-202220.4K
aco_util.h09-May-202210.8K
aco_validate.cpp09-May-202248.8K
meson.build09-May-20223.2K
README-ISA.md09-May-20229.6K
README.md09-May-202216.8K
tests/19-Feb-2026

README-ISA.md

      1 # Unofficial GCN/RDNA ISA reference errata
      2 
      3 ## `v_sad_u32`
      4 
      5 The Vega ISA reference writes its behaviour as:
      6 
      7 ```
      8 D.u = abs(S0.i - S1.i) + S2.u.
      9 ```
     10 
     11 This is incorrect. The actual behaviour is what is written in the GCN3 reference
     12 guide:
     13 
     14 ```
     15 ABS_DIFF (A,B) = (A>B) ? (A-B) : (B-A)
     16 D.u = ABS_DIFF (S0.u,S1.u) + S2.u
     17 ```
     18 
     19 The instruction doesn't subtract the S0 and S1 and use the absolute value (the
     20 _signed_ distance), it uses the _unsigned_ distance between the operands. So
     21 `v_sad_u32(-5, 0, 0)` would return `4294967291` (`-5` interpreted as unsigned),
     22 not `5`.
     23 
     24 ## `s_bfe_*`
     25 
     26 Both the RDNA, Vega and GCN3 ISA references write that these instructions don't write
     27 SCC. They do.
     28 
     29 ## `v_bcnt_u32_b32`
     30 
     31 The Vega ISA reference writes its behaviour as:
     32 
     33 ```
     34 D.u = 0;
     35 for i in 0 ... 31 do
     36 D.u += (S0.u[i] == 1 ? 1 : 0);
     37 endfor.
     38 ```
     39 
     40 This is incorrect. The actual behaviour (and number of operands) is what
     41 is written in the GCN3 reference guide:
     42 
     43 ```
     44 D.u = CountOneBits(S0.u) + S1.u.
     45 ```
     46 
     47 ## `v_alignbyte_b32`
     48 
     49 All versions of the ISA document are vague about it, but after some trial and
     50 error we discovered that only 2 bits of the 3rd operand are used.
     51 Therefore, this instruction can't shift more than 24 bits.
     52 
     53 The correct description of `v_alignbyte_b32` is probably the following:
     54 
     55 ```
     56 D.u = ({S0, S1} >> (8 * S2.u[1:0])) & 0xffffffff
     57 ```
     58 
     59 ## SMEM stores
     60 
     61 The Vega ISA references doesn't say this (or doesn't make it clear), but
     62 the offset for SMEM stores must be in m0 if IMM == 0.
     63 
     64 The RDNA ISA doesn't mention SMEM stores at all, but they seem to be supported
     65 by the chip and are present in LLVM. AMD devs however highly recommend avoiding
     66 these instructions.
     67 
     68 ## SMEM atomics
     69 
     70 RDNA ISA: same as the SMEM stores, the ISA pretends they don't exist, but they
     71 are there in LLVM.
     72 
     73 ## VMEM stores
     74 
     75 All reference guides say (under "Vector Memory Instruction Data Dependencies"):
     76 
     77 > When a VM instruction is issued, the address is immediately read out of VGPRs
     78 > and sent to the texture cache. Any texture or buffer resources and samplers
     79 > are also sent immediately. However, write-data is not immediately sent to the
     80 > texture cache.
     81 
     82 Reading that, one might think that waitcnts need to be added when writing to
     83 the registers used for a VMEM store's data. Experimentation has shown that this
     84 does not seem to be the case on GFX8 and GFX9 (GFX6 and GFX7 are untested). It
     85 also seems unlikely, since NOPs are apparently needed in a subset of these
     86 situations.
     87 
     88 ## MIMG opcodes on GFX8/GCN3
     89 
     90 The `image_atomic_{swap,cmpswap,add,sub}` opcodes in the GCN3 ISA reference
     91 guide are incorrect. The Vega ISA reference guide has the correct ones.
     92 
     93 ## VINTRP encoding
     94 
     95 VEGA ISA doc says the encoding should be `110010` but `110101` works.
     96 
     97 ## VOP1 instructions encoded as VOP3
     98 
     99 RDNA ISA doc says that `0x140` should be added to the opcode, but that doesn't
    100 work. What works is adding `0x180`, which LLVM also does.
    101 
    102 ## FLAT, Scratch, Global instructions
    103 
    104 The NV bit was removed in RDNA, but some parts of the doc still mention it.
    105 
    106 RDNA ISA doc 13.8.1 says that SADDR should be set to 0x7f when ADDR is used, but
    107 9.3.1 says it should be set to NULL. We assume 9.3.1 is correct and set it to
    108 SGPR_NULL.
    109 
    110 ## Legacy instructions
    111 
    112 Some instructions have a `_LEGACY` variant which implements "DX9 rules", in which
    113 the zero "wins" in multiplications, ie. `0.0*x` is always `0.0`. The VEGA ISA
    114 mentions `V_MAC_LEGACY_F32` but this instruction is not really there on VEGA.
    115 
    116 ## `m0` with LDS instructions on Vega and newer
    117 
    118 The Vega ISA doc (both the old one and the "7nm" one) claims that LDS instructions
    119 use the `m0` register for address clamping like older GPUs, but this is not the case.
    120 
    121 In reality, only the `_addtid` variants of LDS instructions use `m0` on Vega and
    122 newer GPUs, so the relevant section of the RDNA ISA doc seems to apply.
    123 LLVM also doesn't emit any initialization of `m0` for LDS instructions, and this
    124 was also confirmed by AMD devs.
    125 
    126 ## RDNA L0, L1 cache and DLC, GLC bits
    127 
    128 The old L1 cache was renamed to L0, and a new L1 cache was added to RDNA. The
    129 L1 cache is 1 cache per shader array. Some instruction encodings have DLC and
    130 GLC bits that interact with the cache.
    131 
    132 * DLC ("device level coherent") bit: controls the L1 cache
    133 * GLC ("globally coherent") bit: controls the L0 cache
    134 
    135 The recommendation from AMD devs is to always set these two bits at the same time,
    136 as it doesn't make too much sense to set them independently, aside from some
    137 circumstances (eg. we needn't set DLC when only one shader array is used).
    138 
    139 Stores and atomics always bypass the L1 cache, so they don't support the DLC bit,
    140 and it shouldn't be set in these cases. Setting the DLC for these cases can result
    141 in graphical glitches or hangs.
    142 
    143 ## RDNA `s_dcache_wb`
    144 
    145 The `s_dcache_wb` is not mentioned in the RDNA ISA doc, but it is needed in order
    146 to achieve correct behavior in some SSBO CTS tests.
    147 
    148 ## RDNA subvector mode
    149 
    150 The documentation of `s_subvector_loop_begin` and `s_subvector_mode_end` is not clear
    151 on what sort of addressing should be used, but it says that it
    152 "is equivalent to an `S_CBRANCH` with extra math", so the subvector loop handling
    153 in ACO is done according to the `s_cbranch` doc.
    154 
    155 ## RDNA early rasterization
    156 
    157 The ISA documentation says about `s_endpgm`:
    158 
    159 > The hardware implicitly executes S_WAITCNT 0 and S_WAITCNT_VSCNT 0
    160 > before executing this instruction.
    161 
    162 What the doc doesn't say is that in case of NGG (and legacy VS) when there
    163 are no param exports, the driver sets `NO_PC_EXPORT=1` for optimal performance,
    164 and when this is set, the hardware will start clipping and rasterization
    165 as soon as it encounters a position export with `DONE=1`, without waiting
    166 for the NGG (or VS) to finish.
    167 
    168 It can even launch PS waves before NGG (or VS) ends.
    169 
    170 When this happens, any store performed by a VS is not guaranteed
    171 to be complete when PS tries to load it, so we need to manually
    172 make sure to insert wait instructions before the position exports.
    173 
    174 # Hardware Bugs
    175 
    176 ## SMEM corrupts VCCZ on SI/CI
    177 
    178 [See this LLVM source.](https://github.com/llvm/llvm-project/blob/acb089e12ae48b82c0b05c42326196a030df9b82/llvm/lib/Target/AMDGPU/SIInsertWaits.cpp#L580-L616)
    179 
    180 After issuing a SMEM instructions, we need to wait for the SMEM instructions to
    181 finish and then write to vcc (for example, `s_mov_b64 vcc, vcc`) to correct vccz
    182 
    183 Currently, we don't do this.
    184 
    185 ## SGPR offset on MUBUF prevents addr clamping on SI/CI
    186 
    187 [See this LLVM source.](https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp#L1917-L1922)
    188 
    189 This leads to wrong bounds checking, using a VGPR offset fixes it.
    190 
    191 ## GCN / GFX6 hazards
    192 
    193 ### VINTRP followed by a read with `v_readfirstlane` or `v_readlane`
    194 
    195 It's required to insert 1 wait state if the dst VGPR of any  `v_interp_*` is
    196 followed by a read with `v_readfirstlane` or `v_readlane` to fix GPU hangs on GFX6.
    197 Note that `v_writelane_*` is apparently not affected. This hazard isn't
    198 documented anywhere but AMD confirmed it.
    199 
    200 ## RDNA / GFX10 hazards
    201 
    202 ### SMEM store followed by a load with the same address
    203 
    204 We found that an `s_buffer_load` will produce incorrect results if it is preceded
    205 by an `s_buffer_store` with the same address. Inserting an `s_nop` between them
    206 does not mitigate the issue, so an `s_waitcnt lgkmcnt(0)` must be inserted.
    207 This is not mentioned by LLVM among the other GFX10 bugs, but LLVM doesn't use
    208 SMEM stores, so it's not surprising that they didn't notice it.
    209 
    210 ### VMEMtoScalarWriteHazard
    211 
    212 Triggered by:
    213 VMEM/FLAT/GLOBAL/SCRATCH/DS instruction reads an SGPR (or EXEC, or M0).
    214 Then, a SALU/SMEM instruction writes the same SGPR.
    215 
    216 Mitigated by:
    217 A VALU instruction or an `s_waitcnt vmcnt(0)` between the two instructions.
    218 
    219 ### SMEMtoVectorWriteHazard
    220 
    221 Triggered by:
    222 An SMEM instruction reads an SGPR. Then, a VALU instruction writes that same SGPR.
    223 
    224 Mitigated by:
    225 Any non-SOPP SALU instruction (except `s_setvskip`, `s_version`, and any non-lgkmcnt `s_waitcnt`).
    226 
    227 ### Offset3fBug
    228 
    229 Any branch that is located at offset 0x3f will be buggy. Just insert some NOPs to make sure no branch
    230 is located at this offset.
    231 
    232 ### InstFwdPrefetchBug
    233 
    234 According to LLVM, the `s_inst_prefetch` instruction can cause a hang.
    235 There are no further details.
    236 
    237 ### LdsMisalignedBug
    238 
    239 When there is a misaligned multi-dword FLAT load/store instruction in WGP mode,
    240 it needs to be split into multiple single-dword FLAT instructions.
    241 
    242 ACO doesn't use FLAT load/store on GFX10, so is unaffected.
    243 
    244 ### FlatSegmentOffsetBug
    245 
    246 The 12-bit immediate OFFSET field of FLAT instructions must always be 0.
    247 GLOBAL and SCRATCH are unaffected.
    248 
    249 ACO doesn't use FLAT load/store on GFX10, so is unaffected.
    250 
    251 ### VcmpxPermlaneHazard
    252 
    253 Triggered by:
    254 Any permlane instruction that follows any VOPC instruction.
    255 Confirmed by AMD devs that despite the name, this doesn't only affect v_cmpx.
    256 
    257 Mitigated by: any VALU instruction except `v_nop`.
    258 
    259 ### VcmpxExecWARHazard
    260 
    261 Triggered by:
    262 Any non-VALU instruction reads the EXEC mask. Then, any VALU instruction writes the EXEC mask.
    263 
    264 Mitigated by:
    265 A VALU instruction that writes an SGPR (or has a valid SDST operand), or `s_waitcnt_depctr 0xfffe`.
    266 Note: `s_waitcnt_depctr` is an internal instruction, so there is no further information
    267 about what it does or what its operand means.
    268 
    269 ### LdsBranchVmemWARHazard
    270 
    271 Triggered by:
    272 VMEM/GLOBAL/SCRATCH instruction, then a branch, then a DS instruction,
    273 or vice versa: DS instruction, then a branch, then a VMEM/GLOBAL/SCRATCH instruction.
    274 
    275 Mitigated by:
    276 Only `s_waitcnt_vscnt null, 0`. Needed even if the first instruction is a load.
    277 
    278 ### NSAClauseBug
    279 
    280 "MIMG-NSA in a hard clause has unpredictable results on GFX10.1"
    281 
    282 ### NSAMaxSize5
    283 
    284 NSA MIMG instructions should be limited to 3 dwords before GFX10.3 to avoid
    285 stability issues: https://reviews.llvm.org/D103348
    286 

README.md

      1 # Welcome to ACO
      2 
      3 ACO (short for *AMD compiler*) is a back-end compiler for AMD GCN / RDNA GPUs, based on the NIR compiler infrastructure.
      4 Simply put, ACO translates shader programs from the NIR intermediate representation into a GCN / RDNA binary which the GPU can execute.
      5 
      6 ## Motivation
      7 
      8 Why did we choose to develop a new compiler backend?
      9 
     10 1. We'd like to give gamers a fluid, stutter-free experience, so we prioritize compilation speed.
     11 2. Good divergence analysis allows us to better optimize runtime performance.
     12 3. Issues can be fixed within mesa releases, independently of the schedule of other projects.
     13 
     14 ## Control flow
     15 
     16 Modern GPUs are SIMD machines that execute the shader in parallel.
     17 In case of GCN / RDNA the parallelism is achieved by executing the shader on several waves, and each wave has several lanes (32 or 64).
     18 When every lane executes exactly the same instructions, and takes the same path, it's uniform control flow;
     19 otherwise when some lanes take one path while other lanes take a different path, it's divergent.
     20 
     21 Each hardware lane corresponds to a shader invocation from a software perspective.
     22 
     23 The hardware doesn't directly support divergence,
     24 so in case of divergent control flow, the GPU must execute both code paths, each with some lanes disabled.
     25 This is why divergence is a performance concern in shader programming.
     26 
     27 ACO deals with divergent control flow by maintaining two control flow graphs (CFG):
     28 
     29 * logical CFG - directly translated from NIR and shows the intended control flow of the program.
     30 * linear CFG - created according to Whole-Function Vectorization by Ralf Karrenberg and Sebastian Hack.
     31   The linear CFG represents how the program is physically executed on GPU and may contain additional blocks for control flow handling and to avoid critical edges.
     32   Note that all nodes of the logical CFG also participate in the linear CFG, but not vice versa.
     33 
     34 ## Compilation phases
     35 
     36 #### Instruction Selection
     37 
     38 The instruction selection is based around the divergence analysis and works in 3 passes on the NIR shader.
     39 
     40 1. The divergence analysis pass calculates for each SSA definition if its value is guaranteed to be uniform across all threads of the workgroup.
     41 2. We determine the register class for each SSA definition.
     42 3. Actual instruction selection. The advanced divergence analysis allows for better usage of the scalar unit, scalar memory loads and the scalar register file.
     43 
     44 We have two types of instructions:
     45 
     46 * Hardware instructions as specified by the GCN / RDNA instruction set architecture manuals.
     47 * Pseudo instructions which are helpers that encapsulate more complex functionality.
     48   They eventually get lowered to real hardware instructions.
     49 
     50 Each instruction can have operands (temporaries that it reads), and definitions (temporaries that it writes).
     51 Temporaries can be fixed to a specific register, or just specify a register class (either a single register, or a vector of several registers).
     52 
     53 #### Value Numbering
     54 
     55 The value numbering pass is necessary for two reasons: the lack of descriptor load representation in NIR,
     56 and every NIR instruction that gets emitted as multiple ACO instructions also has potential for CSE.
     57 This pass does dominator-tree value numbering.
     58 
     59 #### Optimization
     60 
     61 In this phase, simpler instructions are combined into more complex instructions (like the different versions of multiply-add as well as neg, abs, clamp, and output modifiers) and constants are inlined, moves are eliminated, etc.
     62 Exactly which optimizations are performed depends on the hardware for which the shader is being compiled.
     63 
     64 #### Setup of reduction temporaries
     65 
     66 This pass is responsible for making sure that register allocation is correct for reductions, by adding pseudo instructions that utilize linear VGPRs.
     67 When a temporary has a linear VGPR register class, this means that the variable is considered *live* in the linear control flow graph.
     68 
     69 #### Insert exec mask
     70 
     71 In the GCN/RDNA architecture, there is a special register called `exec` which is used for manually controlling which VALU threads (aka. *lanes*) are active. The value of `exec` has to change in divergent branches, loops, etc. and it needs to be restored after the branch or loop is complete. This pass ensures that the correct lanes are active in every branch.
     72 
     73 #### Live-Variable Analysis
     74 
     75 A live-variable analysis is used to calculate the register need of the shader.
     76 This information is used for spilling and scheduling before register allocation.
     77 
     78 #### Spilling
     79 
     80 First, we lower the shader program to CSSA form.
     81 Then, if the register demand exceeds the global limit, this pass lowers register usage by temporarily storing excess scalar values in free vector registers, or excess vector values in scratch memory, and reloading them when needed. It is based on the paper "Register Spilling and Live-Range Splitting for SSA-Form Programs".
     82 
     83 #### Instruction Scheduling
     84 
     85 Scheduling is another NP-complete problem where basically all known heuristics suffer from unpredictable change in register pressure. For that reason, the implemented scheduler does not completely re-schedule all instructions, but only aims to move up memory loads as far as possible without exceeding the maximum register limit for the pre-calculated wave count. The reason this works is that ILP is very limited on GCN. This approach looks promising so far.
     86 
     87 #### Register Allocation
     88 
     89 The register allocator works on SSA (as opposed to LLVM's which works on virtual registers). The SSA properties guarantee that there are always as many registers available as needed. The problem is that some instructions require a vector of neighboring registers to be available, but the free regs might be scattered. In this case, the register allocator inserts shuffle code (moving some temporaries to other registers) to make space for the variable. The assumption is that it is (almost) always better to have a few more moves than to sacrifice a wave. The RA does SSA-reconstruction on the fly, which makes its runtime linear.
     90 
     91 #### SSA Elimination
     92 
     93 The next step is a pass out of SSA by inserting parallelcopies at the end of blocks to match the phi nodes' semantics.
     94 
     95 #### Lower to HW instructions
     96 
     97 Most pseudo instructions are lowered to actual machine instructions.
     98 These are mostly parallel copy instructions created by instruction selection or register allocation and spill/reload code.
     99 
    100 #### Insert wait states
    101 
    102 GCN requires some wait states to be manually inserted in order to ensure correct behavior on memory instructions and some register dependencies.
    103 This means that we need to insert `s_waitcnt` instructions (and its variants) so that the shader program waits until the eg. a memory operation is complete.
    104 
    105 #### Resolve hazards and insert NOPs
    106 
    107 Some instructions require wait states or other instructions to resolve hazards which are not handled by the hardware.
    108 This pass makes sure that no known hazards occour.
    109 
    110 #### Emit program - Assembler
    111 
    112 The assembler emits the actual binary that will be sent to the hardware for execution. ACO's assembler is straight-forward because all instructions have their format, opcode, registers and potential fields already available, so it only needs to cater to the some differences between each hardware generation.
    113 
    114 ## Supported shader stages
    115 
    116 Hardware stages (as executed on the chip) don't exactly match software stages (as defined in OpenGL / Vulkan).
    117 Which software stage gets executed on which hardware stage depends on what kind of software stages are present in the current pipeline.
    118 
    119 An important difference is that VS is always the first stage to run in SW models,
    120 whereas HW VS refers to the last HW stage before fragment shading in GCN/RDNA terminology.
    121 That's why, among other things, the HW VS is no longer used to execute the SW VS when tesselation or geometry shading are used.
    122 
    123 #### Glossary of software stages
    124 
    125 * VS = Vertex Shader
    126 * TCS = Tessellation Control Shader, equivalent to D3D HS = Hull Shader
    127 * TES = Tessellation Evaluation Shader, equivalent to D3D DS = Domain Shader
    128 * GS = Geometry Shader
    129 * FS = Fragment Shader, equivalent to D3D PS = Pixel Shader
    130 * CS = Compute Shader
    131 
    132 #### Glossary of hardware stages
    133 
    134 * LS = Local Shader (merged into HS on GFX9+), only runs SW VS when tessellation is used
    135 * HS = Hull Shader, the HW equivalent of a Tessellation Control Shader, runs before the fixed function hardware performs tessellation
    136 * ES = Export Shader (merged into GS on GFX9+), if there is a GS in the SW pipeline, the preceding stage (ie. SW VS or SW TES) always has to run on this HW stage
    137 * GS = Geometry Shader, also known as legacy GS
    138 * VS = Vertex Shader, **not equivalent to SW VS**: when there is a GS in the SW pipeline this stage runs a "GS copy" shader, otherwise it always runs the SW stage before FS
    139 * NGG = Next Generation Geometry, a new hardware stage that replaces legacy HW GS and HW VS on RDNA GPUs
    140 * PS = Pixel Shader, the HW equivalent to SW FS
    141 * CS = Compute Shader
    142 
    143 ##### Notes about HW VS and the "GS copy" shader
    144 
    145 HW PS reads its inputs from a special buffer that only HW VS can write to, using export instructions.
    146 However, GS store their output in VRAM (except GFX10/NGG).
    147 So in order for HW PS to be able to read the GS outputs, we must run something on the VS stage which reads the GS outputs
    148 from VRAM and exports them to this special buffer. This is what we call a "GS copy" shader.
    149 From a HW perspective the "GS copy" shader is in fact VS (it runs on the HW VS stage),
    150 but from a SW perspective it's not part of the traditional pipeline,
    151 it's just some "glue code" that we need for outputs to play nicely.
    152 
    153 On GFX10/NGG this limitation no longer exists, as the HW NGG GS can now export directly where it needs to.
    154 
    155 ##### Notes about merged shaders
    156 
    157 The merged stages on GFX9 (and GFX10/legacy) are: LSHS and ESGS. On GFX10/NGG the ESGS is merged with HW VS into NGG GS.
    158 
    159 This might be confusing due to a mismatch between the number of invocations of these shaders.
    160 For example, ES is per-vertex, but GS is per-primitive.
    161 This is why merged shaders get an argument called `merged_wave_info` which tells how many invocations each part needs,
    162 and there is some code at the beginning of each part to ensure the correct number of invocations by disabling some threads.
    163 So, think about these as two independent shader programs slapped together.
    164 
    165 ### Which software stage runs on which hardware stage?
    166 
    167 #### Graphics Pipeline
    168 
    169 ##### GFX6-8:
    170 
    171 * Each SW stage has its own HW stage
    172 * LS and HS share the same LDS space, so LS can store its output to LDS, where HS can read it
    173 * HS, ES, GS outputs are stored in VRAM, next stage reads these from VRAM
    174 * GS outputs got to VRAM, so they have to be copied by a GS copy shader running on the HW VS stage
    175 
    176 | GFX6-8 HW stages:       | LS  | HS  | ES  | GS  | VS     | PS | ACO terminology |
    177 | -----------------------:|:----|:----|:----|:----|:-------|:---|:----------------|
    178 | SW stages: only VS+PS:  |     |     |     |     | VS     | FS | `vertex_vs`, `fragment_fs` |
    179 |            with tess:   | VS  | TCS |     |     | TES    | FS | `vertex_ls`, `tess_control_hs`, `tess_eval_vs`, `fragment_fs` |
    180 |            with GS:     |     |     | VS  | GS  | GS copy| FS | `vertex_es`, `geometry_gs`, `gs_copy_vs`, `fragment_fs` |
    181 |            with both:   | VS  | TCS | TES | GS  | GS copy| FS | `vertex_ls`, `tess_control_hs`, `tess_eval_es`, `geometry_gs`, `gs_copy_vs`, `fragment_fs` |
    182 
    183 ##### GFX9+ (including GFX10/legacy):
    184 
    185 * HW LS and HS stages are merged, and the merged shader still uses LDS in the same way as before
    186 * HW ES and GS stages are merged, so ES outputs can go to LDS instead of VRAM
    187 * LSHS outputs and ESGS outputs are still stored in VRAM, so a GS copy shader is still necessary
    188 
    189 | GFX9+ HW stages:        | LSHS      | ESGS      | VS     | PS | ACO terminology |
    190 | -----------------------:|:----------|:----------|:-------|:---|:----------------|
    191 | SW stages: only VS+PS:  |           |           | VS     | FS | `vertex_vs`, `fragment_fs` |
    192 |            with tess:   | VS + TCS  |           | TES    | FS | `vertex_tess_control_hs`, `tess_eval_vs`, `fragment_fs` |
    193 |            with GS:     |           | VS + GS   | GS copy| FS | `vertex_geometry_gs`, `gs_copy_vs`, `fragment_fs` |
    194 |            with both:   | VS + TCS  | TES + GS  | GS copy| FS | `vertex_tess_control_hs`, `tess_eval_geometry_gs`, `gs_copy_vs`, `fragment_fs` |
    195 
    196 ##### NGG (GFX10+ only):
    197 
    198  * HW GS and VS stages are now merged, and NGG GS can export directly
    199  * GS copy shaders are no longer needed
    200 
    201 | GFX10/NGG HW stages:    | LSHS      | NGG GS             | PS | ACO terminology |
    202 | -----------------------:|:----------|:-------------------|:---|:----------------|
    203 | SW stages: only VS+PS:  |           | VS                 | FS | `vertex_ngg`, `fragment_fs` |
    204 |            with tess:   | VS + TCS  | TES                | FS | `vertex_tess_control_hs`, `tess_eval_ngg`, `fragment_fs` |
    205 |            with GS:     |           | VS + GS            | FS | `vertex_geometry_ngg`, `fragment_fs` |
    206 |            with both:   | VS + TCS  | TES + GS           | FS | `vertex_tess_control_hs`, `tess_eval_geometry_ngg`, `fragment_fs` |
    207 
    208 #### Compute pipeline
    209 
    210 GFX6-10:
    211 
    212 * Note that the SW CS always runs on the HW CS stage on all HW generations.
    213 
    214 | GFX6-10 HW stage        | CS   | ACO terminology |
    215 | -----------------------:|:-----|:----------------|
    216 | SW stage                | CS   | `compute_cs`    |
    217 
    218 
    219 ## How to debug
    220 
    221 Handy `RADV_DEBUG` options that help with ACO debugging:
    222 
    223 * `nocache` - you always want to use this when debugging, otherwise you risk using a broken shader from the cache.
    224 * `shaders` - makes ACO print the IR after register allocation, as well as the disassembled shader binary.
    225 * `metashaders` - does the same thing as `shaders` but for built-in RADV shaders.
    226 * `preoptir` - makes ACO print the final NIR shader before instruction selection, as well as the ACO IR after instruction selection.
    227 * `nongg` - disables NGG support
    228 
    229 We also have `ACO_DEBUG` options:
    230 
    231 * `validateir` - Validate the ACO IR between compilation stages. By default, enabled in debug builds and disabled in release builds.
    232 * `validatera` - Perform a RA (register allocation) validation.
    233 * `perfwarn` - Warn when sub-optimal instructions are found.
    234 * `force-waitcnt` - Forces ACO to emit a wait state after each instruction when there is something to wait for. Harms performance.
    235 * `novn` - Disables the ACO value numbering stage.
    236 * `noopt` - Disables the ACO optimizer.
    237 * `nosched` - Disables the ACO scheduler.
    238 
    239 Note that you need to **combine these options into a comma-separated list**, for example: `RADV_DEBUG=nocache,shaders` otherwise only the last one will take effect. (This is how all environment variables work, yet this is an often made mistake.) Example:
    240 
    241 ```
    242 RADV_DEBUG=nocache,shaders ACO_DEBUG=validateir,validatera vkcube
    243 ```
    244 
    245 ### Using GCC sanitizers
    246 
    247 GCC has several sanitizers which can help figure out hard to diagnose issues. To use these, you need to pass
    248 the `-Dbsanitize` flag to `meson` when building mesa. For example `-Dbsanitize=undefined` will add support for
    249 the undefined behavior sanitizer.
    250 
    251 ### Hardened builds and glibc++ assertions
    252 
    253 Several Linux distributions use "hardened" builds meaning several special compiler flags are added by
    254 downstream packaging which are not used in mesa builds by default. These may be responsible for
    255 some bug reports of inexplicable crashes with assertion failures you can't reproduce.
    256 
    257 Most notable are the glibc++ debug flags, which you can use by adding the `-D_GLIBCXX_ASSERTIONS=1` and
    258 `-D_GLIBCXX_DEBUG=1` flags.
    259 
    260 To see the full list of downstream compiler flags, you can use eg. `rpm --eval "%optflags"`
    261 on Red Hat based distros like Fedora.
    262 
    263 ### Good practices
    264 
    265 Here are some good practices we learned while debugging visual corruption and hangs.
    266 
    267 1. Bisecting shaders:
    268     * Use renderdoc when examining shaders. This is deterministic while real games often use multi-threading or change the order in which shaders get compiled.
    269     * Edit `radv_shader.c` or `radv_pipeline.c` to change if they are compiled with LLVM or ACO.
    270 2. Things to check early:
    271     * Disable value_numbering, optimizer and/or scheduler.
    272       Note that if any of these change the output, it does not necessarily mean that the error is there, as register assignment does also change.
    273 3. Finding the instruction causing a hang:
    274     * The ability to directly manipulate the binaries gives us an easy way to find the exact instruction which causes the hang.
    275       Use NULL exports (for FS and VS) and `s_endpgm` to end the shader early to find the problematic instruction.
    276 4. Other faulty instructions:
    277     * Use print_asm and check for illegal instructions.
    278     * Compare to the ACO IR to see if the assembly matches what we want (this can take a while).
    279       Typical issues might be a wrong instruction format leading to a wrong opcode or an sgpr used for vgpr field.
    280 5. Comparing to the LLVM backend:
    281    * If everything else didn't help, we probably just do something wrong. The LLVM backend is quite mature, so its output might help find differences, but this can be a long road.
    282