xref: /aosp_15_r20/external/mesa3d/src/gallium/auxiliary/tgsi/tgsi_transform.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /**************************************************************************
2  *
3  * Copyright 2008 VMware, Inc.
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  **************************************************************************/
27 
28 #ifndef TGSI_TRANSFORM_H
29 #define TGSI_TRANSFORM_H
30 
31 
32 #include "pipe/p_defines.h"
33 #include "pipe/p_shader_tokens.h"
34 #include "tgsi/tgsi_parse.h"
35 #include "tgsi/tgsi_build.h"
36 
37 
38 
39 /**
40  * Subclass this to add caller-specific data
41  */
42 struct tgsi_transform_context
43 {
44 /**** PUBLIC ***/
45 
46    /**
47     * User-defined callbacks invoked per instruction.
48     */
49    void (*transform_instruction)(struct tgsi_transform_context *ctx,
50                                  struct tgsi_full_instruction *inst);
51 
52    void (*transform_declaration)(struct tgsi_transform_context *ctx,
53                                  struct tgsi_full_declaration *decl);
54 
55    void (*transform_immediate)(struct tgsi_transform_context *ctx,
56                                struct tgsi_full_immediate *imm);
57    void (*transform_property)(struct tgsi_transform_context *ctx,
58                               struct tgsi_full_property *prop);
59 
60    /**
61     * Called after last declaration, before first instruction.  This is
62     * where the user might insert new declarations and/or instructions.
63     */
64    void (*prolog)(struct tgsi_transform_context *ctx);
65 
66    /**
67     * Called at end of input program to allow caller to append extra
68     * instructions.
69     */
70    void (*epilog)(struct tgsi_transform_context *ctx);
71 
72    enum pipe_shader_type processor;
73 
74 /*** PRIVATE ***/
75 
76    /**
77     * These are setup by tgsi_transform_shader() and cannot be overridden.
78     * Meant to be called from in the above user callback functions.
79     */
80    void (*emit_instruction)(struct tgsi_transform_context *ctx,
81                             const struct tgsi_full_instruction *inst);
82    void (*emit_declaration)(struct tgsi_transform_context *ctx,
83                             const struct tgsi_full_declaration *decl);
84    void (*emit_immediate)(struct tgsi_transform_context *ctx,
85                           const struct tgsi_full_immediate *imm);
86    void (*emit_property)(struct tgsi_transform_context *ctx,
87                          const struct tgsi_full_property *prop);
88 
89    struct tgsi_header *header;
90    unsigned max_tokens_out;
91    struct tgsi_token *tokens_out;
92    unsigned ti;
93    bool fail;
94 };
95 
96 
97 /**
98  * Helper for emitting temporary register declarations.
99  */
100 static inline void
tgsi_transform_temps_decl(struct tgsi_transform_context * ctx,unsigned firstIdx,unsigned lastIdx)101 tgsi_transform_temps_decl(struct tgsi_transform_context *ctx,
102                           unsigned firstIdx, unsigned lastIdx)
103 {
104    struct tgsi_full_declaration decl;
105 
106    decl = tgsi_default_full_declaration();
107    decl.Declaration.File = TGSI_FILE_TEMPORARY;
108    decl.Range.First = firstIdx;
109    decl.Range.Last = lastIdx;
110    ctx->emit_declaration(ctx, &decl);
111 }
112 
113 static inline void
tgsi_transform_temp_decl(struct tgsi_transform_context * ctx,unsigned index)114 tgsi_transform_temp_decl(struct tgsi_transform_context *ctx,
115                          unsigned index)
116 {
117    tgsi_transform_temps_decl(ctx, index, index);
118 }
119 
120 static inline void
tgsi_transform_const_decl(struct tgsi_transform_context * ctx,unsigned firstIdx,unsigned lastIdx)121 tgsi_transform_const_decl(struct tgsi_transform_context *ctx,
122                           unsigned firstIdx, unsigned lastIdx)
123 {
124    struct tgsi_full_declaration decl;
125 
126    decl = tgsi_default_full_declaration();
127    decl.Declaration.File = TGSI_FILE_CONSTANT;
128    decl.Range.First = firstIdx;
129    decl.Range.Last = lastIdx;
130    decl.Declaration.Dimension = 1;
131    /* Dim.Index2D is already 0 */
132    ctx->emit_declaration(ctx, &decl);
133 }
134 
135 static inline void
tgsi_transform_input_decl(struct tgsi_transform_context * ctx,unsigned index,unsigned sem_name,unsigned sem_index,unsigned interp)136 tgsi_transform_input_decl(struct tgsi_transform_context *ctx,
137                           unsigned index,
138                           unsigned sem_name, unsigned sem_index,
139                           unsigned interp)
140 {
141    struct tgsi_full_declaration decl;
142 
143    decl = tgsi_default_full_declaration();
144    decl.Declaration.File = TGSI_FILE_INPUT;
145    decl.Declaration.Interpolate = 1;
146    decl.Declaration.Semantic = 1;
147    decl.Semantic.Name = sem_name;
148    decl.Semantic.Index = sem_index;
149    decl.Range.First =
150    decl.Range.Last = index;
151    decl.Interp.Interpolate = interp;
152 
153    ctx->emit_declaration(ctx, &decl);
154 }
155 
156 static inline void
tgsi_transform_output_decl(struct tgsi_transform_context * ctx,unsigned index,unsigned sem_name,unsigned sem_index,unsigned interp)157 tgsi_transform_output_decl(struct tgsi_transform_context *ctx,
158                           unsigned index,
159                           unsigned sem_name, unsigned sem_index,
160                           unsigned interp)
161 {
162    struct tgsi_full_declaration decl;
163 
164    decl = tgsi_default_full_declaration();
165    decl.Declaration.File = TGSI_FILE_OUTPUT;
166    decl.Declaration.Interpolate = 1;
167    decl.Declaration.Semantic = 1;
168    decl.Semantic.Name = sem_name;
169    decl.Semantic.Index = sem_index;
170    decl.Range.First =
171    decl.Range.Last = index;
172    decl.Interp.Interpolate = interp;
173 
174    ctx->emit_declaration(ctx, &decl);
175 }
176 
177 static inline void
tgsi_transform_sampler_decl(struct tgsi_transform_context * ctx,unsigned index)178 tgsi_transform_sampler_decl(struct tgsi_transform_context *ctx,
179                             unsigned index)
180 {
181    struct tgsi_full_declaration decl;
182 
183    decl = tgsi_default_full_declaration();
184    decl.Declaration.File = TGSI_FILE_SAMPLER;
185    decl.Range.First =
186    decl.Range.Last = index;
187    ctx->emit_declaration(ctx, &decl);
188 }
189 
190 static inline void
tgsi_transform_sampler_view_decl(struct tgsi_transform_context * ctx,unsigned index,unsigned target,enum tgsi_return_type type)191 tgsi_transform_sampler_view_decl(struct tgsi_transform_context *ctx,
192                                  unsigned index,
193                                  unsigned target,
194                                  enum tgsi_return_type type)
195 {
196    struct tgsi_full_declaration decl;
197 
198    decl = tgsi_default_full_declaration();
199    decl.Declaration.File = TGSI_FILE_SAMPLER_VIEW;
200    decl.Declaration.UsageMask = TGSI_WRITEMASK_XYZW;
201    decl.Range.First =
202    decl.Range.Last = index;
203    decl.SamplerView.Resource = target;
204    decl.SamplerView.ReturnTypeX = type;
205    decl.SamplerView.ReturnTypeY = type;
206    decl.SamplerView.ReturnTypeZ = type;
207    decl.SamplerView.ReturnTypeW = type;
208 
209    ctx->emit_declaration(ctx, &decl);
210 }
211 
212 static inline void
tgsi_transform_immediate_decl(struct tgsi_transform_context * ctx,float x,float y,float z,float w)213 tgsi_transform_immediate_decl(struct tgsi_transform_context *ctx,
214                               float x, float y, float z, float w)
215 {
216    struct tgsi_full_immediate immed;
217    unsigned size = 4;
218 
219    immed = tgsi_default_full_immediate();
220    immed.Immediate.NrTokens = 1 + size; /* one for the token itself */
221    immed.u[0].Float = x;
222    immed.u[1].Float = y;
223    immed.u[2].Float = z;
224    immed.u[3].Float = w;
225 
226    ctx->emit_immediate(ctx, &immed);
227 }
228 
229 static inline void
tgsi_transform_immediate_int_decl(struct tgsi_transform_context * ctx,int x,int y,int z,int w)230 tgsi_transform_immediate_int_decl(struct tgsi_transform_context *ctx,
231                                   int x, int y, int z, int w)
232 {
233    struct tgsi_full_immediate immed;
234    unsigned size = 4;
235 
236    immed = tgsi_default_full_immediate();
237    immed.Immediate.DataType = TGSI_IMM_INT32;
238    immed.Immediate.NrTokens = 1 + size; /* one for the token itself */
239    immed.u[0].Int = x;
240    immed.u[1].Int = y;
241    immed.u[2].Int = z;
242    immed.u[3].Int = w;
243 
244    ctx->emit_immediate(ctx, &immed);
245 }
246 
247 static inline void
tgsi_transform_dst_reg(struct tgsi_full_dst_register * reg,unsigned file,unsigned index,unsigned writemask)248 tgsi_transform_dst_reg(struct tgsi_full_dst_register *reg,
249                        unsigned file, unsigned index, unsigned writemask)
250 {
251    reg->Register.File = file;
252    reg->Register.Index = index;
253    reg->Register.WriteMask = writemask;
254 }
255 
256 static inline void
tgsi_transform_src_reg_xyzw(struct tgsi_full_src_register * reg,unsigned file,unsigned index)257 tgsi_transform_src_reg_xyzw(struct tgsi_full_src_register *reg,
258                             unsigned file, unsigned index)
259 {
260    reg->Register.File = file;
261    reg->Register.Index = index;
262    if (file == TGSI_FILE_CONSTANT) {
263       reg->Register.Dimension = 1;
264       reg->Dimension.Index = 0;
265    }
266 }
267 
268 static inline void
tgsi_transform_src_reg(struct tgsi_full_src_register * reg,unsigned file,unsigned index,unsigned swizzleX,unsigned swizzleY,unsigned swizzleZ,unsigned swizzleW)269 tgsi_transform_src_reg(struct tgsi_full_src_register *reg,
270                        unsigned file, unsigned index,
271                        unsigned swizzleX, unsigned swizzleY,
272                        unsigned swizzleZ, unsigned swizzleW)
273 {
274    reg->Register.File = file;
275    reg->Register.Index = index;
276    if (file == TGSI_FILE_CONSTANT) {
277       reg->Register.Dimension = 1;
278       reg->Dimension.Index = 0;
279    }
280    reg->Register.SwizzleX = swizzleX;
281    reg->Register.SwizzleY = swizzleY;
282    reg->Register.SwizzleZ = swizzleZ;
283    reg->Register.SwizzleW = swizzleW;
284 }
285 
286 /**
287  * Helper for emitting 1-operand instructions.
288  */
289 static inline void
tgsi_transform_op1_inst(struct tgsi_transform_context * ctx,enum tgsi_opcode opcode,unsigned dst_file,unsigned dst_index,unsigned dst_writemask,unsigned src0_file,unsigned src0_index)290 tgsi_transform_op1_inst(struct tgsi_transform_context *ctx,
291                         enum tgsi_opcode opcode,
292                         unsigned dst_file,
293                         unsigned dst_index,
294                         unsigned dst_writemask,
295                         unsigned src0_file,
296                         unsigned src0_index)
297 {
298    struct tgsi_full_instruction inst;
299 
300    inst = tgsi_default_full_instruction();
301    inst.Instruction.Opcode = opcode;
302    inst.Instruction.NumDstRegs = 1;
303    inst.Dst[0].Register.File = dst_file,
304    inst.Dst[0].Register.Index = dst_index;
305    inst.Dst[0].Register.WriteMask = dst_writemask;
306    inst.Instruction.NumSrcRegs = 1;
307    tgsi_transform_src_reg_xyzw(&inst.Src[0], src0_file, src0_index);
308 
309    ctx->emit_instruction(ctx, &inst);
310 }
311 
312 
313 static inline void
tgsi_transform_op2_inst(struct tgsi_transform_context * ctx,enum tgsi_opcode opcode,unsigned dst_file,unsigned dst_index,unsigned dst_writemask,unsigned src0_file,unsigned src0_index,unsigned src1_file,unsigned src1_index,bool src1_negate)314 tgsi_transform_op2_inst(struct tgsi_transform_context *ctx,
315                         enum tgsi_opcode opcode,
316                         unsigned dst_file,
317                         unsigned dst_index,
318                         unsigned dst_writemask,
319                         unsigned src0_file,
320                         unsigned src0_index,
321                         unsigned src1_file,
322                         unsigned src1_index,
323                         bool src1_negate)
324 {
325    struct tgsi_full_instruction inst;
326 
327    inst = tgsi_default_full_instruction();
328    inst.Instruction.Opcode = opcode;
329    inst.Instruction.NumDstRegs = 1;
330    inst.Dst[0].Register.File = dst_file,
331    inst.Dst[0].Register.Index = dst_index;
332    inst.Dst[0].Register.WriteMask = dst_writemask;
333    inst.Instruction.NumSrcRegs = 2;
334    tgsi_transform_src_reg_xyzw(&inst.Src[0], src0_file, src0_index);
335    tgsi_transform_src_reg_xyzw(&inst.Src[1], src1_file, src1_index);
336    inst.Src[1].Register.Negate = src1_negate;
337 
338    ctx->emit_instruction(ctx, &inst);
339 }
340 
341 
342 static inline void
tgsi_transform_op1_swz_inst(struct tgsi_transform_context * ctx,enum tgsi_opcode opcode,unsigned dst_file,unsigned dst_index,unsigned dst_writemask,unsigned src0_file,unsigned src0_index,unsigned src0_swizzle)343 tgsi_transform_op1_swz_inst(struct tgsi_transform_context *ctx,
344                             enum tgsi_opcode opcode,
345                             unsigned dst_file,
346                             unsigned dst_index,
347                             unsigned dst_writemask,
348                             unsigned src0_file,
349                             unsigned src0_index,
350                             unsigned src0_swizzle)
351 {
352    struct tgsi_full_instruction inst;
353 
354    inst = tgsi_default_full_instruction();
355    inst.Instruction.Opcode = opcode;
356    inst.Instruction.NumDstRegs = 1;
357    inst.Dst[0].Register.File = dst_file,
358    inst.Dst[0].Register.Index = dst_index;
359    inst.Dst[0].Register.WriteMask = dst_writemask;
360    inst.Instruction.NumSrcRegs = 1;
361    tgsi_transform_src_reg_xyzw(&inst.Src[0], src0_file, src0_index);
362    switch (dst_writemask) {
363    case TGSI_WRITEMASK_X:
364       inst.Src[0].Register.SwizzleX = src0_swizzle;
365       break;
366    case TGSI_WRITEMASK_Y:
367       inst.Src[0].Register.SwizzleY = src0_swizzle;
368       break;
369    case TGSI_WRITEMASK_Z:
370       inst.Src[0].Register.SwizzleZ = src0_swizzle;
371       break;
372    case TGSI_WRITEMASK_W:
373       inst.Src[0].Register.SwizzleW = src0_swizzle;
374       break;
375    default:
376       ; /* nothing */
377    }
378 
379    ctx->emit_instruction(ctx, &inst);
380 }
381 
382 
383 static inline void
tgsi_transform_op2_swz_inst(struct tgsi_transform_context * ctx,enum tgsi_opcode opcode,unsigned dst_file,unsigned dst_index,unsigned dst_writemask,unsigned src0_file,unsigned src0_index,unsigned src0_swizzle,unsigned src1_file,unsigned src1_index,unsigned src1_swizzle,bool src1_negate)384 tgsi_transform_op2_swz_inst(struct tgsi_transform_context *ctx,
385                             enum tgsi_opcode opcode,
386                             unsigned dst_file,
387                             unsigned dst_index,
388                             unsigned dst_writemask,
389                             unsigned src0_file,
390                             unsigned src0_index,
391                             unsigned src0_swizzle,
392                             unsigned src1_file,
393                             unsigned src1_index,
394                             unsigned src1_swizzle,
395                             bool src1_negate)
396 {
397    struct tgsi_full_instruction inst;
398 
399    inst = tgsi_default_full_instruction();
400    inst.Instruction.Opcode = opcode;
401    inst.Instruction.NumDstRegs = 1;
402    inst.Dst[0].Register.File = dst_file,
403    inst.Dst[0].Register.Index = dst_index;
404    inst.Dst[0].Register.WriteMask = dst_writemask;
405    inst.Instruction.NumSrcRegs = 2;
406    tgsi_transform_src_reg_xyzw(&inst.Src[0], src0_file, src0_index);
407    tgsi_transform_src_reg_xyzw(&inst.Src[1], src1_file, src1_index);
408    inst.Src[1].Register.Negate = src1_negate;
409    switch (dst_writemask) {
410    case TGSI_WRITEMASK_X:
411       inst.Src[0].Register.SwizzleX = src0_swizzle;
412       inst.Src[1].Register.SwizzleX = src1_swizzle;
413       break;
414    case TGSI_WRITEMASK_Y:
415       inst.Src[0].Register.SwizzleY = src0_swizzle;
416       inst.Src[1].Register.SwizzleY = src1_swizzle;
417       break;
418    case TGSI_WRITEMASK_Z:
419       inst.Src[0].Register.SwizzleZ = src0_swizzle;
420       inst.Src[1].Register.SwizzleZ = src1_swizzle;
421       break;
422    case TGSI_WRITEMASK_W:
423       inst.Src[0].Register.SwizzleW = src0_swizzle;
424       inst.Src[1].Register.SwizzleW = src1_swizzle;
425       break;
426    default:
427       ; /* nothing */
428    }
429 
430    ctx->emit_instruction(ctx, &inst);
431 }
432 
433 
434 static inline void
tgsi_transform_op3_swz_inst(struct tgsi_transform_context * ctx,enum tgsi_opcode opcode,unsigned dst_file,unsigned dst_index,unsigned dst_writemask,unsigned src0_file,unsigned src0_index,unsigned src0_swizzle,unsigned src0_negate,unsigned src1_file,unsigned src1_index,unsigned src1_swizzle,unsigned src2_file,unsigned src2_index,unsigned src2_swizzle)435 tgsi_transform_op3_swz_inst(struct tgsi_transform_context *ctx,
436                             enum tgsi_opcode opcode,
437                             unsigned dst_file,
438                             unsigned dst_index,
439                             unsigned dst_writemask,
440                             unsigned src0_file,
441                             unsigned src0_index,
442                             unsigned src0_swizzle,
443                             unsigned src0_negate,
444                             unsigned src1_file,
445                             unsigned src1_index,
446                             unsigned src1_swizzle,
447                             unsigned src2_file,
448                             unsigned src2_index,
449                             unsigned src2_swizzle)
450 {
451    struct tgsi_full_instruction inst;
452 
453    inst = tgsi_default_full_instruction();
454    inst.Instruction.Opcode = opcode;
455    inst.Instruction.NumDstRegs = 1;
456    inst.Dst[0].Register.File = dst_file,
457    inst.Dst[0].Register.Index = dst_index;
458    inst.Dst[0].Register.WriteMask = dst_writemask;
459    inst.Instruction.NumSrcRegs = 3;
460    tgsi_transform_src_reg_xyzw(&inst.Src[0], src0_file, src0_index);
461    inst.Src[0].Register.Negate = src0_negate;
462    tgsi_transform_src_reg_xyzw(&inst.Src[1], src1_file, src1_index);
463    tgsi_transform_src_reg_xyzw(&inst.Src[2], src2_file, src2_index);
464    switch (dst_writemask) {
465    case TGSI_WRITEMASK_X:
466       inst.Src[0].Register.SwizzleX = src0_swizzle;
467       inst.Src[1].Register.SwizzleX = src1_swizzle;
468       inst.Src[2].Register.SwizzleX = src2_swizzle;
469       break;
470    case TGSI_WRITEMASK_Y:
471       inst.Src[0].Register.SwizzleY = src0_swizzle;
472       inst.Src[1].Register.SwizzleY = src1_swizzle;
473       inst.Src[2].Register.SwizzleY = src2_swizzle;
474       break;
475    case TGSI_WRITEMASK_Z:
476       inst.Src[0].Register.SwizzleZ = src0_swizzle;
477       inst.Src[1].Register.SwizzleZ = src1_swizzle;
478       inst.Src[2].Register.SwizzleZ = src2_swizzle;
479       break;
480    case TGSI_WRITEMASK_W:
481       inst.Src[0].Register.SwizzleW = src0_swizzle;
482       inst.Src[1].Register.SwizzleW = src1_swizzle;
483       inst.Src[2].Register.SwizzleW = src2_swizzle;
484       break;
485    default:
486       ; /* nothing */
487    }
488 
489    ctx->emit_instruction(ctx, &inst);
490 }
491 
492 
493 static inline void
tgsi_transform_kill_inst(struct tgsi_transform_context * ctx,unsigned src_file,unsigned src_index,unsigned src_swizzle,bool negate)494 tgsi_transform_kill_inst(struct tgsi_transform_context *ctx,
495                          unsigned src_file,
496                          unsigned src_index,
497                          unsigned src_swizzle,
498                          bool negate)
499 {
500    struct tgsi_full_instruction inst;
501 
502    inst = tgsi_default_full_instruction();
503    inst.Instruction.Opcode = TGSI_OPCODE_KILL_IF;
504    inst.Instruction.NumDstRegs = 0;
505    inst.Instruction.NumSrcRegs = 1;
506    tgsi_transform_src_reg_xyzw(&inst.Src[0], src_file, src_index);
507    inst.Src[0].Register.SwizzleX =
508    inst.Src[0].Register.SwizzleY =
509    inst.Src[0].Register.SwizzleZ =
510    inst.Src[0].Register.SwizzleW = src_swizzle;
511    inst.Src[0].Register.Negate = negate;
512 
513    ctx->emit_instruction(ctx, &inst);
514 }
515 
516 
517 static inline void
tgsi_transform_tex_inst(struct tgsi_transform_context * ctx,unsigned dst_file,unsigned dst_index,unsigned src_file,unsigned src_index,unsigned tex_target,unsigned sampler_index)518 tgsi_transform_tex_inst(struct tgsi_transform_context *ctx,
519                         unsigned dst_file,
520                         unsigned dst_index,
521                         unsigned src_file,
522                         unsigned src_index,
523                         unsigned tex_target,
524                         unsigned sampler_index)
525 {
526    struct tgsi_full_instruction inst;
527 
528    assert(tex_target < TGSI_TEXTURE_COUNT);
529 
530    inst = tgsi_default_full_instruction();
531    inst.Instruction.Opcode = TGSI_OPCODE_TEX;
532    inst.Instruction.NumDstRegs = 1;
533    inst.Dst[0].Register.File = dst_file;
534    inst.Dst[0].Register.Index = dst_index;
535    inst.Instruction.NumSrcRegs = 2;
536    inst.Instruction.Texture = true;
537    inst.Texture.Texture = tex_target;
538    tgsi_transform_src_reg_xyzw(&inst.Src[0], src_file, src_index);
539    tgsi_transform_src_reg_xyzw(&inst.Src[1], TGSI_FILE_SAMPLER, sampler_index);
540 
541    ctx->emit_instruction(ctx, &inst);
542 }
543 
544 
545 extern struct tgsi_token *
546 tgsi_transform_shader(const struct tgsi_token *tokens_in,
547                       unsigned initial_tokens_len,
548                       struct tgsi_transform_context *ctx);
549 
550 
551 #endif /* TGSI_TRANSFORM_H */
552