xref: /aosp_15_r20/external/mesa3d/src/compiler/glsl/README (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard WorkerWelcome to Mesa's GLSL compiler.  A brief overview of how things flow:
2*61046927SAndroid Build Coastguard Worker
3*61046927SAndroid Build Coastguard Worker1) lex and yacc-based preprocessor takes the incoming shader string
4*61046927SAndroid Build Coastguard Workerand produces a new string containing the preprocessed shader.  This
5*61046927SAndroid Build Coastguard Workertakes care of things like #if, #ifdef, #define, and preprocessor macro
6*61046927SAndroid Build Coastguard Workerinvocations.  Note that #version, #extension, and some others are
7*61046927SAndroid Build Coastguard Workerpassed straight through.  See glcpp/*
8*61046927SAndroid Build Coastguard Worker
9*61046927SAndroid Build Coastguard Worker2) lex and yacc-based parser takes the preprocessed string and
10*61046927SAndroid Build Coastguard Workergenerates the AST (abstract syntax tree).  Almost no checking is
11*61046927SAndroid Build Coastguard Workerperformed in this stage.  See glsl_lexer.ll and glsl_parser.yy.
12*61046927SAndroid Build Coastguard Worker
13*61046927SAndroid Build Coastguard Worker3) The AST is converted to "HIR".  This is the intermediate
14*61046927SAndroid Build Coastguard Workerrepresentation of the compiler.  Constructors are generated, function
15*61046927SAndroid Build Coastguard Workercalls are resolved to particular function signatures, and all the
16*61046927SAndroid Build Coastguard Workersemantic checking is performed.  See ast_*.cpp for the conversion, and
17*61046927SAndroid Build Coastguard Workerir.h for the IR structures.
18*61046927SAndroid Build Coastguard Worker
19*61046927SAndroid Build Coastguard Worker4) The driver (Mesa, or main.cpp for the standalone binary) performs
20*61046927SAndroid Build Coastguard Workeroptimizations.  These include copy propagation, dead code elimination,
21*61046927SAndroid Build Coastguard Workerconstant folding, and others.  Generally the driver will call
22*61046927SAndroid Build Coastguard Workeroptimizations in a loop, as each may open up opportunities for other
23*61046927SAndroid Build Coastguard Workeroptimizations to do additional work.  See most files called ir_*.cpp
24*61046927SAndroid Build Coastguard Worker
25*61046927SAndroid Build Coastguard Worker5) linking is performed.  This does checking to ensure that the
26*61046927SAndroid Build Coastguard Workeroutputs of the vertex shader match the inputs of the fragment shader,
27*61046927SAndroid Build Coastguard Workerand assigns locations to uniforms, attributes, and varyings.  See
28*61046927SAndroid Build Coastguard Workerlinker.cpp.
29*61046927SAndroid Build Coastguard Worker
30*61046927SAndroid Build Coastguard Worker6) The driver may perform additional optimization at this point, as
31*61046927SAndroid Build Coastguard Workerfor example dead code elimination previously couldn't remove functions
32*61046927SAndroid Build Coastguard Workeror global variable usage when we didn't know what other code would be
33*61046927SAndroid Build Coastguard Workerlinked in.
34*61046927SAndroid Build Coastguard Worker
35*61046927SAndroid Build Coastguard Worker7) The driver performs code generation out of the IR, taking a linked
36*61046927SAndroid Build Coastguard Workershader program and producing a compiled program for each stage.  See
37*61046927SAndroid Build Coastguard Worker../mesa/program/ir_to_mesa.cpp for Mesa IR code generation.
38*61046927SAndroid Build Coastguard Worker
39*61046927SAndroid Build Coastguard WorkerFAQ:
40*61046927SAndroid Build Coastguard Worker
41*61046927SAndroid Build Coastguard WorkerQ: What is HIR versus IR versus LIR?
42*61046927SAndroid Build Coastguard Worker
43*61046927SAndroid Build Coastguard WorkerA: The idea behind the naming was that ast_to_hir would produce a
44*61046927SAndroid Build Coastguard Workerhigh-level IR ("HIR"), with things like matrix operations, structure
45*61046927SAndroid Build Coastguard Workerassignments, etc., present.  A series of lowering passes would occur
46*61046927SAndroid Build Coastguard Workerthat do things like break matrix multiplication into a series of dot
47*61046927SAndroid Build Coastguard Workerproducts/MADs, make structure assignment be a series of assignment of
48*61046927SAndroid Build Coastguard Workercomponents, flatten if statements into conditional moves, and such,
49*61046927SAndroid Build Coastguard Workerproducing a low level IR ("LIR").
50*61046927SAndroid Build Coastguard Worker
51*61046927SAndroid Build Coastguard WorkerHowever, it now appears that each driver will have different
52*61046927SAndroid Build Coastguard Workerrequirements from a LIR.  A 915-generation chipset wants all functions
53*61046927SAndroid Build Coastguard Workerinlined, all loops unrolled, all ifs flattened, no variable array
54*61046927SAndroid Build Coastguard Workeraccesses, and matrix multiplication broken down.  The Mesa IR backend
55*61046927SAndroid Build Coastguard Workerfor swrast would like matrices and structure assignment broken down,
56*61046927SAndroid Build Coastguard Workerbut it can support function calls and dynamic branching.  A 965 vertex
57*61046927SAndroid Build Coastguard Workershader IR backend could potentially even handle some matrix operations
58*61046927SAndroid Build Coastguard Workerwithout breaking them down, but the 965 fragment shader IR backend
59*61046927SAndroid Build Coastguard Workerwould want to break to have (almost) all operations down channel-wise
60*61046927SAndroid Build Coastguard Workerand perform optimization on that.  As a result, there's no single
61*61046927SAndroid Build Coastguard Workerlow-level IR that will make everyone happy.  So that usage has fallen
62*61046927SAndroid Build Coastguard Workerout of favor, and each driver will perform a series of lowering passes
63*61046927SAndroid Build Coastguard Workerto take the HIR down to whatever restrictions it wants to impose
64*61046927SAndroid Build Coastguard Workerbefore doing codegen.
65*61046927SAndroid Build Coastguard Worker
66*61046927SAndroid Build Coastguard WorkerQ: How is the IR structured?
67*61046927SAndroid Build Coastguard Worker
68*61046927SAndroid Build Coastguard WorkerA: The best way to get started seeing it would be to run the
69*61046927SAndroid Build Coastguard Workerstandalone compiler against a shader:
70*61046927SAndroid Build Coastguard Worker
71*61046927SAndroid Build Coastguard Worker./glsl_compiler --dump-lir \
72*61046927SAndroid Build Coastguard Worker	~/src/piglit/tests/shaders/glsl-orangebook-ch06-bump.frag
73*61046927SAndroid Build Coastguard Worker
74*61046927SAndroid Build Coastguard WorkerSo for example one of the ir_instructions in main() contains:
75*61046927SAndroid Build Coastguard Worker
76*61046927SAndroid Build Coastguard Worker(assign (constant bool (1)) (var_ref litColor)  (expression vec3 * (var_ref Surf
77*61046927SAndroid Build Coastguard WorkeraceColor) (var_ref __retval) ) )
78*61046927SAndroid Build Coastguard Worker
79*61046927SAndroid Build Coastguard WorkerOr more visually:
80*61046927SAndroid Build Coastguard Worker                     (assign)
81*61046927SAndroid Build Coastguard Worker                 /       |        \
82*61046927SAndroid Build Coastguard Worker        (var_ref)  (expression *)  (constant bool 1)
83*61046927SAndroid Build Coastguard Worker         /          /           \
84*61046927SAndroid Build Coastguard Worker(litColor)      (var_ref)    (var_ref)
85*61046927SAndroid Build Coastguard Worker                  /                  \
86*61046927SAndroid Build Coastguard Worker           (SurfaceColor)          (__retval)
87*61046927SAndroid Build Coastguard Worker
88*61046927SAndroid Build Coastguard Workerwhich came from:
89*61046927SAndroid Build Coastguard Worker
90*61046927SAndroid Build Coastguard WorkerlitColor = SurfaceColor * max(dot(normDelta, LightDir), 0.0);
91*61046927SAndroid Build Coastguard Worker
92*61046927SAndroid Build Coastguard Worker(the max call is not represented in this expression tree, as it was a
93*61046927SAndroid Build Coastguard Workerfunction call that got inlined but not brought into this expression
94*61046927SAndroid Build Coastguard Workertree)
95*61046927SAndroid Build Coastguard Worker
96*61046927SAndroid Build Coastguard WorkerEach of those nodes is a subclass of ir_instruction.  A particular
97*61046927SAndroid Build Coastguard Workerir_instruction instance may only appear once in the whole IR tree with
98*61046927SAndroid Build Coastguard Workerthe exception of ir_variables, which appear once as variable
99*61046927SAndroid Build Coastguard Workerdeclarations:
100*61046927SAndroid Build Coastguard Worker
101*61046927SAndroid Build Coastguard Worker(declare () vec3 normDelta)
102*61046927SAndroid Build Coastguard Worker
103*61046927SAndroid Build Coastguard Workerand multiple times as the targets of variable dereferences:
104*61046927SAndroid Build Coastguard Worker...
105*61046927SAndroid Build Coastguard Worker(assign (constant bool (1)) (var_ref __retval) (expression float dot
106*61046927SAndroid Build Coastguard Worker (var_ref normDelta) (var_ref LightDir) ) )
107*61046927SAndroid Build Coastguard Worker...
108*61046927SAndroid Build Coastguard Worker(assign (constant bool (1)) (var_ref __retval) (expression vec3 -
109*61046927SAndroid Build Coastguard Worker (var_ref LightDir) (expression vec3 * (constant float (2.000000))
110*61046927SAndroid Build Coastguard Worker (expression vec3 * (expression float dot (var_ref normDelta) (var_ref
111*61046927SAndroid Build Coastguard Worker LightDir) ) (var_ref normDelta) ) ) ) )
112*61046927SAndroid Build Coastguard Worker...
113*61046927SAndroid Build Coastguard Worker
114*61046927SAndroid Build Coastguard WorkerEach node has a type.  Expressions may involve several different types:
115*61046927SAndroid Build Coastguard Worker(declare (uniform ) mat4 gl_ModelViewMatrix)
116*61046927SAndroid Build Coastguard Worker((assign (constant bool (1)) (var_ref constructor_tmp) (expression
117*61046927SAndroid Build Coastguard Worker vec4 * (var_ref gl_ModelViewMatrix) (var_ref gl_Vertex) ) )
118*61046927SAndroid Build Coastguard Worker
119*61046927SAndroid Build Coastguard WorkerAn expression tree can be arbitrarily deep, and the compiler tries to
120*61046927SAndroid Build Coastguard Workerkeep them structured like that so that things like algebraic
121*61046927SAndroid Build Coastguard Workeroptimizations ((color * 1.0 == color) and ((mat1 * mat2) * vec == mat1
122*61046927SAndroid Build Coastguard Worker* (mat2 * vec))) or recognizing operation patterns for code generation
123*61046927SAndroid Build Coastguard Worker(vec1 * vec2 + vec3 == mad(vec1, vec2, vec3)) are easier.  This comes
124*61046927SAndroid Build Coastguard Workerat the expense of additional trickery in implementing some
125*61046927SAndroid Build Coastguard Workeroptimizations like CSE where one must navigate an expression tree.
126*61046927SAndroid Build Coastguard Worker
127*61046927SAndroid Build Coastguard WorkerQ: Why no SSA representation?
128*61046927SAndroid Build Coastguard Worker
129*61046927SAndroid Build Coastguard WorkerA: Converting an IR tree to SSA form makes dead code elimination,
130*61046927SAndroid Build Coastguard Workercommon subexpression elimination, and many other optimizations much
131*61046927SAndroid Build Coastguard Workereasier.  However, in our primarily vector-based language, there's some
132*61046927SAndroid Build Coastguard Workermajor questions as to how it would work.  Do we do SSA on the scalar
133*61046927SAndroid Build Coastguard Workeror vector level?  If we do it at the vector level, we're going to end
134*61046927SAndroid Build Coastguard Workerup with many different versions of the variable when encountering code
135*61046927SAndroid Build Coastguard Workerlike:
136*61046927SAndroid Build Coastguard Worker
137*61046927SAndroid Build Coastguard Worker(assign (constant bool (1)) (swiz x (var_ref __retval) ) (var_ref a) )
138*61046927SAndroid Build Coastguard Worker(assign (constant bool (1)) (swiz y (var_ref __retval) ) (var_ref b) )
139*61046927SAndroid Build Coastguard Worker(assign (constant bool (1)) (swiz z (var_ref __retval) ) (var_ref c) )
140*61046927SAndroid Build Coastguard Worker
141*61046927SAndroid Build Coastguard WorkerIf every masked update of a component relies on the previous value of
142*61046927SAndroid Build Coastguard Workerthe variable, then we're probably going to be quite limited in our
143*61046927SAndroid Build Coastguard Workerdead code elimination wins, and recognizing common expressions may
144*61046927SAndroid Build Coastguard Workerjust not happen.  On the other hand, if we operate channel-wise, then
145*61046927SAndroid Build Coastguard Workerwe'll be prone to optimizing the operation on one of the channels at
146*61046927SAndroid Build Coastguard Workerthe expense of making its instruction flow different from the other
147*61046927SAndroid Build Coastguard Workerchannels, and a vector-based GPU would end up with worse code than if
148*61046927SAndroid Build Coastguard Workerwe didn't optimize operations on that channel!
149*61046927SAndroid Build Coastguard Worker
150*61046927SAndroid Build Coastguard WorkerOnce again, it appears that our optimization requirements are driven
151*61046927SAndroid Build Coastguard Workersignificantly by the target architecture.  For now, targeting the Mesa
152*61046927SAndroid Build Coastguard WorkerIR backend, SSA does not appear to be that important to producing
153*61046927SAndroid Build Coastguard Workerexcellent code, but we do expect to do some SSA-based optimizations
154*61046927SAndroid Build Coastguard Workerfor the 965 fragment shader backend when that is developed.
155*61046927SAndroid Build Coastguard Worker
156*61046927SAndroid Build Coastguard WorkerQ: How should I expand instructions that take multiple backend instructions?
157*61046927SAndroid Build Coastguard Worker
158*61046927SAndroid Build Coastguard WorkerSometimes you'll have to do the expansion in your code generation.
159*61046927SAndroid Build Coastguard WorkerHowever, in many cases you'll want to do a pass over the IR to convert
160*61046927SAndroid Build Coastguard Workernon-native instructions to a series of native instructions.  For
161*61046927SAndroid Build Coastguard Workerexample, for the Mesa backend we have ir_div_to_mul_rcp.cpp because
162*61046927SAndroid Build Coastguard WorkerMesa IR (and many hardware backends) only have a reciprocal
163*61046927SAndroid Build Coastguard Workerinstruction, not a divide.  Implementing non-native instructions this
164*61046927SAndroid Build Coastguard Workerway gives the chance for constant folding to occur, so (a / 2.0)
165*61046927SAndroid Build Coastguard Workerbecomes (a * 0.5) after codegen instead of (a * (1.0 / 2.0))
166*61046927SAndroid Build Coastguard Worker
167*61046927SAndroid Build Coastguard WorkerQ: How shoud I handle my special hardware instructions with respect to IR?
168*61046927SAndroid Build Coastguard Worker
169*61046927SAndroid Build Coastguard WorkerOur current theory is that if multiple targets have an instruction for
170*61046927SAndroid Build Coastguard Workersome operation, then we should probably be able to represent that in
171*61046927SAndroid Build Coastguard Workerthe IR.  Generally this is in the form of an ir_{bin,un}op expression
172*61046927SAndroid Build Coastguard Workertype.  For example, we initially implemented fract() using (a -
173*61046927SAndroid Build Coastguard Workerfloor(a)), but both 945 and 965 have instructions to give that result,
174*61046927SAndroid Build Coastguard Workerand it would also simplify the implementation of mod(), so
175*61046927SAndroid Build Coastguard Workerir_unop_fract was added.  The following areas need updating to add a
176*61046927SAndroid Build Coastguard Workernew expression type:
177*61046927SAndroid Build Coastguard Worker
178*61046927SAndroid Build Coastguard Workerir.h (new enum)
179*61046927SAndroid Build Coastguard Workerir.cpp:operator_strs (used for ir_reader)
180*61046927SAndroid Build Coastguard Workerir_constant_expression.cpp (you probably want to be able to constant fold)
181*61046927SAndroid Build Coastguard Workerir_validate.cpp (check users have the right types)
182*61046927SAndroid Build Coastguard Worker
183*61046927SAndroid Build Coastguard WorkerYou may also need to update the backends if they will see the new expr type:
184*61046927SAndroid Build Coastguard Worker
185*61046927SAndroid Build Coastguard Worker../mesa/program/ir_to_mesa.cpp
186*61046927SAndroid Build Coastguard Worker
187*61046927SAndroid Build Coastguard WorkerYou can then use the new expression from builtins (if all backends
188*61046927SAndroid Build Coastguard Workerwould rather see it), or scan the IR and convert to use your new
189*61046927SAndroid Build Coastguard Workerexpression type (see ir_mod_to_floor, for example).
190*61046927SAndroid Build Coastguard Worker
191*61046927SAndroid Build Coastguard WorkerQ: How is memory management handled in the compiler?
192*61046927SAndroid Build Coastguard Worker
193*61046927SAndroid Build Coastguard WorkerThe hierarchical memory allocator "talloc" developed for the Samba
194*61046927SAndroid Build Coastguard Workerproject is used, so that things like optimization passes don't have to
195*61046927SAndroid Build Coastguard Workerworry about their garbage collection so much.  It has a few nice
196*61046927SAndroid Build Coastguard Workerfeatures, including low performance overhead and good debugging
197*61046927SAndroid Build Coastguard Workersupport that's trivially available.
198*61046927SAndroid Build Coastguard Worker
199*61046927SAndroid Build Coastguard WorkerGenerally, each stage of the compile creates a talloc context and
200*61046927SAndroid Build Coastguard Workerallocates its memory out of that or children of it.  At the end of the
201*61046927SAndroid Build Coastguard Workerstage, the pieces still live are stolen to a new context and the old
202*61046927SAndroid Build Coastguard Workerone freed, or the whole context is kept for use by the next stage.
203*61046927SAndroid Build Coastguard Worker
204*61046927SAndroid Build Coastguard WorkerFor IR transformations, a temporary context is used, then at the end
205*61046927SAndroid Build Coastguard Workerof all transformations, reparent_ir reparents all live nodes under the
206*61046927SAndroid Build Coastguard Workershader's IR list, and the old context full of dead nodes is freed.
207*61046927SAndroid Build Coastguard WorkerWhen developing a single IR transformation pass, this means that you
208*61046927SAndroid Build Coastguard Workerwant to allocate instruction nodes out of the temporary context, so if
209*61046927SAndroid Build Coastguard Workerit becomes dead it doesn't live on as the child of a live node.  At
210*61046927SAndroid Build Coastguard Workerthe moment, optimization passes aren't passed that temporary context,
211*61046927SAndroid Build Coastguard Workerso they find it by calling talloc_parent() on a nearby IR node.  The
212*61046927SAndroid Build Coastguard Workertalloc_parent() call is expensive, so many passes will cache the
213*61046927SAndroid Build Coastguard Workerresult of the first talloc_parent().  Cleaning up all the optimization
214*61046927SAndroid Build Coastguard Workerpasses to take a context argument and not call talloc_parent() is left
215*61046927SAndroid Build Coastguard Workeras an exercise.
216*61046927SAndroid Build Coastguard Worker
217*61046927SAndroid Build Coastguard WorkerQ: What is the file naming convention in this directory?
218*61046927SAndroid Build Coastguard Worker
219*61046927SAndroid Build Coastguard WorkerInitially, there really wasn't one.  We have since adopted one:
220*61046927SAndroid Build Coastguard Worker
221*61046927SAndroid Build Coastguard Worker - Files that implement code lowering passes should be named lower_*
222*61046927SAndroid Build Coastguard Worker   (e.g., lower_builtins.cpp).
223*61046927SAndroid Build Coastguard Worker - Files that implement optimization passes should be named opt_*.
224*61046927SAndroid Build Coastguard Worker - Files that implement a class that is used throught the code should
225*61046927SAndroid Build Coastguard Worker   take the name of that class (e.g., ir_hierarchical_visitor.cpp).
226*61046927SAndroid Build Coastguard Worker - Files that contain code not fitting in one of the previous
227*61046927SAndroid Build Coastguard Worker   categories should have a sensible name (e.g., glsl_parser.yy).
228