• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_shader_tokens.h"
33 #include "tgsi/tgsi_parse.h"
34 #include "tgsi/tgsi_build.h"
35 
36 
37 
38 /**
39  * Subclass this to add caller-specific data
40  */
41 struct tgsi_transform_context
42 {
43 /**** PUBLIC ***/
44 
45    /**
46     * User-defined callbacks invoked per instruction.
47     */
48    void (*transform_instruction)(struct tgsi_transform_context *ctx,
49                                  struct tgsi_full_instruction *inst);
50 
51    void (*transform_declaration)(struct tgsi_transform_context *ctx,
52                                  struct tgsi_full_declaration *decl);
53 
54    void (*transform_immediate)(struct tgsi_transform_context *ctx,
55                                struct tgsi_full_immediate *imm);
56    void (*transform_property)(struct tgsi_transform_context *ctx,
57                               struct tgsi_full_property *prop);
58 
59    /**
60     * Called after last declaration, before first instruction.  This is
61     * where the user might insert new declarations and/or instructions.
62     */
63    void (*prolog)(struct tgsi_transform_context *ctx);
64 
65    /**
66     * Called at end of input program to allow caller to append extra
67     * instructions.  Return number of tokens emitted.
68     */
69    void (*epilog)(struct tgsi_transform_context *ctx);
70 
71 
72 /*** PRIVATE ***/
73 
74    /**
75     * These are setup by tgsi_transform_shader() and cannot be overridden.
76     * Meant to be called from in the above user callback functions.
77     */
78    void (*emit_instruction)(struct tgsi_transform_context *ctx,
79                             const struct tgsi_full_instruction *inst);
80    void (*emit_declaration)(struct tgsi_transform_context *ctx,
81                             const struct tgsi_full_declaration *decl);
82    void (*emit_immediate)(struct tgsi_transform_context *ctx,
83                           const struct tgsi_full_immediate *imm);
84    void (*emit_property)(struct tgsi_transform_context *ctx,
85                          const struct tgsi_full_property *prop);
86 
87    struct tgsi_header *header;
88    uint max_tokens_out;
89    struct tgsi_token *tokens_out;
90    uint ti;
91 };
92 
93 
94 /**
95  * Helper for emitting temporary register declarations.
96  */
97 static inline void
tgsi_transform_temps_decl(struct tgsi_transform_context * ctx,unsigned firstIdx,unsigned lastIdx)98 tgsi_transform_temps_decl(struct tgsi_transform_context *ctx,
99                           unsigned firstIdx, unsigned lastIdx)
100 {
101    struct tgsi_full_declaration decl;
102 
103    decl = tgsi_default_full_declaration();
104    decl.Declaration.File = TGSI_FILE_TEMPORARY;
105    decl.Range.First = firstIdx;
106    decl.Range.Last = lastIdx;
107    ctx->emit_declaration(ctx, &decl);
108 }
109 
110 static inline void
tgsi_transform_temp_decl(struct tgsi_transform_context * ctx,unsigned index)111 tgsi_transform_temp_decl(struct tgsi_transform_context *ctx,
112                          unsigned index)
113 {
114    tgsi_transform_temps_decl(ctx, index, index);
115 }
116 
117 static inline void
tgsi_transform_const_decl(struct tgsi_transform_context * ctx,unsigned firstIdx,unsigned lastIdx)118 tgsi_transform_const_decl(struct tgsi_transform_context *ctx,
119                           unsigned firstIdx, unsigned lastIdx)
120 {
121    struct tgsi_full_declaration decl;
122 
123    decl = tgsi_default_full_declaration();
124    decl.Declaration.File = TGSI_FILE_CONSTANT;
125    decl.Range.First = firstIdx;
126    decl.Range.Last = lastIdx;
127    ctx->emit_declaration(ctx, &decl);
128 }
129 
130 static inline void
tgsi_transform_input_decl(struct tgsi_transform_context * ctx,unsigned index,unsigned sem_name,unsigned sem_index,unsigned interp)131 tgsi_transform_input_decl(struct tgsi_transform_context *ctx,
132                           unsigned index,
133                           unsigned sem_name, unsigned sem_index,
134                           unsigned interp)
135 {
136    struct tgsi_full_declaration decl;
137 
138    decl = tgsi_default_full_declaration();
139    decl.Declaration.File = TGSI_FILE_INPUT;
140    decl.Declaration.Interpolate = 1;
141    decl.Declaration.Semantic = 1;
142    decl.Semantic.Name = sem_name;
143    decl.Semantic.Index = sem_index;
144    decl.Range.First =
145    decl.Range.Last = index;
146    decl.Interp.Interpolate = interp;
147 
148    ctx->emit_declaration(ctx, &decl);
149 }
150 
151 static inline void
tgsi_transform_output_decl(struct tgsi_transform_context * ctx,unsigned index,unsigned sem_name,unsigned sem_index,unsigned interp)152 tgsi_transform_output_decl(struct tgsi_transform_context *ctx,
153                           unsigned index,
154                           unsigned sem_name, unsigned sem_index,
155                           unsigned interp)
156 {
157    struct tgsi_full_declaration decl;
158 
159    decl = tgsi_default_full_declaration();
160    decl.Declaration.File = TGSI_FILE_OUTPUT;
161    decl.Declaration.Interpolate = 1;
162    decl.Declaration.Semantic = 1;
163    decl.Semantic.Name = sem_name;
164    decl.Semantic.Index = sem_index;
165    decl.Range.First =
166    decl.Range.Last = index;
167    decl.Interp.Interpolate = interp;
168 
169    ctx->emit_declaration(ctx, &decl);
170 }
171 
172 static inline void
tgsi_transform_sampler_decl(struct tgsi_transform_context * ctx,unsigned index)173 tgsi_transform_sampler_decl(struct tgsi_transform_context *ctx,
174                             unsigned index)
175 {
176    struct tgsi_full_declaration decl;
177 
178    decl = tgsi_default_full_declaration();
179    decl.Declaration.File = TGSI_FILE_SAMPLER;
180    decl.Range.First =
181    decl.Range.Last = index;
182    ctx->emit_declaration(ctx, &decl);
183 }
184 
185 static inline void
tgsi_transform_sampler_view_decl(struct tgsi_transform_context * ctx,unsigned index,unsigned target,enum tgsi_return_type type)186 tgsi_transform_sampler_view_decl(struct tgsi_transform_context *ctx,
187                                  unsigned index,
188                                  unsigned target,
189                                  enum tgsi_return_type type)
190 {
191    struct tgsi_full_declaration decl;
192 
193    decl = tgsi_default_full_declaration();
194    decl.Declaration.File = TGSI_FILE_SAMPLER_VIEW;
195    decl.Declaration.UsageMask = TGSI_WRITEMASK_XYZW;
196    decl.Range.First =
197    decl.Range.Last = index;
198    decl.SamplerView.Resource = target;
199    decl.SamplerView.ReturnTypeX = type;
200    decl.SamplerView.ReturnTypeY = type;
201    decl.SamplerView.ReturnTypeZ = type;
202    decl.SamplerView.ReturnTypeW = type;
203 
204    ctx->emit_declaration(ctx, &decl);
205 }
206 
207 static inline void
tgsi_transform_immediate_decl(struct tgsi_transform_context * ctx,float x,float y,float z,float w)208 tgsi_transform_immediate_decl(struct tgsi_transform_context *ctx,
209                               float x, float y, float z, float w)
210 {
211    struct tgsi_full_immediate immed;
212    unsigned size = 4;
213 
214    immed = tgsi_default_full_immediate();
215    immed.Immediate.NrTokens = 1 + size; /* one for the token itself */
216    immed.u[0].Float = x;
217    immed.u[1].Float = y;
218    immed.u[2].Float = z;
219    immed.u[3].Float = w;
220 
221    ctx->emit_immediate(ctx, &immed);
222 }
223 
224 static inline void
tgsi_transform_dst_reg(struct tgsi_full_dst_register * reg,unsigned file,unsigned index,unsigned writemask)225 tgsi_transform_dst_reg(struct tgsi_full_dst_register *reg,
226                        unsigned file, unsigned index, unsigned writemask)
227 {
228    reg->Register.File = file;
229    reg->Register.Index = index;
230    reg->Register.WriteMask = writemask;
231 }
232 
233 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)234 tgsi_transform_src_reg(struct tgsi_full_src_register *reg,
235                        unsigned file, unsigned index,
236                        unsigned swizzleX, unsigned swizzleY,
237                        unsigned swizzleZ, unsigned swizzleW)
238 {
239    reg->Register.File = file;
240    reg->Register.Index = index;
241    reg->Register.SwizzleX = swizzleX;
242    reg->Register.SwizzleY = swizzleY;
243    reg->Register.SwizzleZ = swizzleZ;
244    reg->Register.SwizzleW = swizzleW;
245 }
246 
247 /**
248  * Helper for emitting 1-operand instructions.
249  */
250 static inline void
tgsi_transform_op1_inst(struct tgsi_transform_context * ctx,unsigned opcode,unsigned dst_file,unsigned dst_index,unsigned dst_writemask,unsigned src0_file,unsigned src0_index)251 tgsi_transform_op1_inst(struct tgsi_transform_context *ctx,
252                         unsigned opcode,
253                         unsigned dst_file,
254                         unsigned dst_index,
255                         unsigned dst_writemask,
256                         unsigned src0_file,
257                         unsigned src0_index)
258 {
259    struct tgsi_full_instruction inst;
260 
261    inst = tgsi_default_full_instruction();
262    inst.Instruction.Opcode = opcode;
263    inst.Instruction.NumDstRegs = 1;
264    inst.Dst[0].Register.File = dst_file,
265    inst.Dst[0].Register.Index = dst_index;
266    inst.Dst[0].Register.WriteMask = dst_writemask;
267    inst.Instruction.NumSrcRegs = 1;
268    inst.Src[0].Register.File = src0_file;
269    inst.Src[0].Register.Index = src0_index;
270 
271    ctx->emit_instruction(ctx, &inst);
272 }
273 
274 
275 static inline void
tgsi_transform_op2_inst(struct tgsi_transform_context * ctx,unsigned 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)276 tgsi_transform_op2_inst(struct tgsi_transform_context *ctx,
277                         unsigned opcode,
278                         unsigned dst_file,
279                         unsigned dst_index,
280                         unsigned dst_writemask,
281                         unsigned src0_file,
282                         unsigned src0_index,
283                         unsigned src1_file,
284                         unsigned src1_index,
285                         bool src1_negate)
286 {
287    struct tgsi_full_instruction inst;
288 
289    inst = tgsi_default_full_instruction();
290    inst.Instruction.Opcode = opcode;
291    inst.Instruction.NumDstRegs = 1;
292    inst.Dst[0].Register.File = dst_file,
293    inst.Dst[0].Register.Index = dst_index;
294    inst.Dst[0].Register.WriteMask = dst_writemask;
295    inst.Instruction.NumSrcRegs = 2;
296    inst.Src[0].Register.File = src0_file;
297    inst.Src[0].Register.Index = src0_index;
298    inst.Src[1].Register.File = src1_file;
299    inst.Src[1].Register.Index = src1_index;
300    inst.Src[1].Register.Negate = src1_negate;
301 
302    ctx->emit_instruction(ctx, &inst);
303 }
304 
305 
306 static inline void
tgsi_transform_op3_inst(struct tgsi_transform_context * ctx,unsigned opcode,unsigned dst_file,unsigned dst_index,unsigned dst_writemask,unsigned src0_file,unsigned src0_index,unsigned src1_file,unsigned src1_index,unsigned src2_file,unsigned src2_index)307 tgsi_transform_op3_inst(struct tgsi_transform_context *ctx,
308                         unsigned opcode,
309                         unsigned dst_file,
310                         unsigned dst_index,
311                         unsigned dst_writemask,
312                         unsigned src0_file,
313                         unsigned src0_index,
314                         unsigned src1_file,
315                         unsigned src1_index,
316                         unsigned src2_file,
317                         unsigned src2_index)
318 {
319    struct tgsi_full_instruction inst;
320 
321    inst = tgsi_default_full_instruction();
322    inst.Instruction.Opcode = opcode;
323    inst.Instruction.NumDstRegs = 1;
324    inst.Dst[0].Register.File = dst_file,
325    inst.Dst[0].Register.Index = dst_index;
326    inst.Dst[0].Register.WriteMask = dst_writemask;
327    inst.Instruction.NumSrcRegs = 3;
328    inst.Src[0].Register.File = src0_file;
329    inst.Src[0].Register.Index = src0_index;
330    inst.Src[1].Register.File = src1_file;
331    inst.Src[1].Register.Index = src1_index;
332    inst.Src[2].Register.File = src2_file;
333    inst.Src[2].Register.Index = src2_index;
334 
335    ctx->emit_instruction(ctx, &inst);
336 }
337 
338 
339 
340 static inline void
tgsi_transform_op1_swz_inst(struct tgsi_transform_context * ctx,unsigned opcode,unsigned dst_file,unsigned dst_index,unsigned dst_writemask,unsigned src0_file,unsigned src0_index,unsigned src0_swizzle)341 tgsi_transform_op1_swz_inst(struct tgsi_transform_context *ctx,
342                             unsigned opcode,
343                             unsigned dst_file,
344                             unsigned dst_index,
345                             unsigned dst_writemask,
346                             unsigned src0_file,
347                             unsigned src0_index,
348                             unsigned src0_swizzle)
349 {
350    struct tgsi_full_instruction inst;
351 
352    inst = tgsi_default_full_instruction();
353    inst.Instruction.Opcode = opcode;
354    inst.Instruction.NumDstRegs = 1;
355    inst.Dst[0].Register.File = dst_file,
356    inst.Dst[0].Register.Index = dst_index;
357    inst.Dst[0].Register.WriteMask = dst_writemask;
358    inst.Instruction.NumSrcRegs = 1;
359    inst.Src[0].Register.File = src0_file;
360    inst.Src[0].Register.Index = src0_index;
361    switch (dst_writemask) {
362    case TGSI_WRITEMASK_X:
363       inst.Src[0].Register.SwizzleX = src0_swizzle;
364       break;
365    case TGSI_WRITEMASK_Y:
366       inst.Src[0].Register.SwizzleY = src0_swizzle;
367       break;
368    case TGSI_WRITEMASK_Z:
369       inst.Src[0].Register.SwizzleZ = src0_swizzle;
370       break;
371    case TGSI_WRITEMASK_W:
372       inst.Src[0].Register.SwizzleW = src0_swizzle;
373       break;
374    default:
375       ; /* nothing */
376    }
377 
378    ctx->emit_instruction(ctx, &inst);
379 }
380 
381 
382 static inline void
tgsi_transform_op2_swz_inst(struct tgsi_transform_context * ctx,unsigned 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)383 tgsi_transform_op2_swz_inst(struct tgsi_transform_context *ctx,
384                             unsigned opcode,
385                             unsigned dst_file,
386                             unsigned dst_index,
387                             unsigned dst_writemask,
388                             unsigned src0_file,
389                             unsigned src0_index,
390                             unsigned src0_swizzle,
391                             unsigned src1_file,
392                             unsigned src1_index,
393                             unsigned src1_swizzle,
394                             bool src1_negate)
395 {
396    struct tgsi_full_instruction inst;
397 
398    inst = tgsi_default_full_instruction();
399    inst.Instruction.Opcode = opcode;
400    inst.Instruction.NumDstRegs = 1;
401    inst.Dst[0].Register.File = dst_file,
402    inst.Dst[0].Register.Index = dst_index;
403    inst.Dst[0].Register.WriteMask = dst_writemask;
404    inst.Instruction.NumSrcRegs = 2;
405    inst.Src[0].Register.File = src0_file;
406    inst.Src[0].Register.Index = src0_index;
407    inst.Src[1].Register.File = src1_file;
408    inst.Src[1].Register.Index = src1_index;
409    inst.Src[1].Register.Negate = src1_negate;
410    switch (dst_writemask) {
411    case TGSI_WRITEMASK_X:
412       inst.Src[0].Register.SwizzleX = src0_swizzle;
413       inst.Src[1].Register.SwizzleX = src1_swizzle;
414       break;
415    case TGSI_WRITEMASK_Y:
416       inst.Src[0].Register.SwizzleY = src0_swizzle;
417       inst.Src[1].Register.SwizzleY = src1_swizzle;
418       break;
419    case TGSI_WRITEMASK_Z:
420       inst.Src[0].Register.SwizzleZ = src0_swizzle;
421       inst.Src[1].Register.SwizzleZ = src1_swizzle;
422       break;
423    case TGSI_WRITEMASK_W:
424       inst.Src[0].Register.SwizzleW = src0_swizzle;
425       inst.Src[1].Register.SwizzleW = src1_swizzle;
426       break;
427    default:
428       ; /* nothing */
429    }
430 
431    ctx->emit_instruction(ctx, &inst);
432 }
433 
434 
435 static inline void
tgsi_transform_op3_swz_inst(struct tgsi_transform_context * ctx,unsigned 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)436 tgsi_transform_op3_swz_inst(struct tgsi_transform_context *ctx,
437                             unsigned opcode,
438                             unsigned dst_file,
439                             unsigned dst_index,
440                             unsigned dst_writemask,
441                             unsigned src0_file,
442                             unsigned src0_index,
443                             unsigned src0_swizzle,
444                             unsigned src0_negate,
445                             unsigned src1_file,
446                             unsigned src1_index,
447                             unsigned src1_swizzle,
448                             unsigned src2_file,
449                             unsigned src2_index,
450                             unsigned src2_swizzle)
451 {
452    struct tgsi_full_instruction inst;
453 
454    inst = tgsi_default_full_instruction();
455    inst.Instruction.Opcode = opcode;
456    inst.Instruction.NumDstRegs = 1;
457    inst.Dst[0].Register.File = dst_file,
458    inst.Dst[0].Register.Index = dst_index;
459    inst.Dst[0].Register.WriteMask = dst_writemask;
460    inst.Instruction.NumSrcRegs = 3;
461    inst.Src[0].Register.File = src0_file;
462    inst.Src[0].Register.Index = src0_index;
463    inst.Src[0].Register.Negate = src0_negate;
464    inst.Src[1].Register.File = src1_file;
465    inst.Src[1].Register.Index = src1_index;
466    inst.Src[2].Register.File = src2_file;
467    inst.Src[2].Register.Index = src2_index;
468    switch (dst_writemask) {
469    case TGSI_WRITEMASK_X:
470       inst.Src[0].Register.SwizzleX = src0_swizzle;
471       inst.Src[1].Register.SwizzleX = src1_swizzle;
472       inst.Src[2].Register.SwizzleX = src2_swizzle;
473       break;
474    case TGSI_WRITEMASK_Y:
475       inst.Src[0].Register.SwizzleY = src0_swizzle;
476       inst.Src[1].Register.SwizzleY = src1_swizzle;
477       inst.Src[2].Register.SwizzleY = src2_swizzle;
478       break;
479    case TGSI_WRITEMASK_Z:
480       inst.Src[0].Register.SwizzleZ = src0_swizzle;
481       inst.Src[1].Register.SwizzleZ = src1_swizzle;
482       inst.Src[2].Register.SwizzleZ = src2_swizzle;
483       break;
484    case TGSI_WRITEMASK_W:
485       inst.Src[0].Register.SwizzleW = src0_swizzle;
486       inst.Src[1].Register.SwizzleW = src1_swizzle;
487       inst.Src[2].Register.SwizzleW = src2_swizzle;
488       break;
489    default:
490       ; /* nothing */
491    }
492 
493    ctx->emit_instruction(ctx, &inst);
494 }
495 
496 
497 static inline void
tgsi_transform_kill_inst(struct tgsi_transform_context * ctx,unsigned src_file,unsigned src_index,unsigned src_swizzle,boolean negate)498 tgsi_transform_kill_inst(struct tgsi_transform_context *ctx,
499                          unsigned src_file,
500                          unsigned src_index,
501                          unsigned src_swizzle,
502                          boolean negate)
503 {
504    struct tgsi_full_instruction inst;
505 
506    inst = tgsi_default_full_instruction();
507    inst.Instruction.Opcode = TGSI_OPCODE_KILL_IF;
508    inst.Instruction.NumDstRegs = 0;
509    inst.Instruction.NumSrcRegs = 1;
510    inst.Src[0].Register.File = src_file;
511    inst.Src[0].Register.Index = src_index;
512    inst.Src[0].Register.SwizzleX =
513    inst.Src[0].Register.SwizzleY =
514    inst.Src[0].Register.SwizzleZ =
515    inst.Src[0].Register.SwizzleW = src_swizzle;
516    inst.Src[0].Register.Negate = negate;
517 
518    ctx->emit_instruction(ctx, &inst);
519 }
520 
521 
522 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)523 tgsi_transform_tex_inst(struct tgsi_transform_context *ctx,
524                         unsigned dst_file,
525                         unsigned dst_index,
526                         unsigned src_file,
527                         unsigned src_index,
528                         unsigned tex_target,
529                         unsigned sampler_index)
530 {
531    struct tgsi_full_instruction inst;
532 
533    assert(tex_target < TGSI_TEXTURE_COUNT);
534 
535    inst = tgsi_default_full_instruction();
536    inst.Instruction.Opcode = TGSI_OPCODE_TEX;
537    inst.Instruction.NumDstRegs = 1;
538    inst.Dst[0].Register.File = dst_file;
539    inst.Dst[0].Register.Index = dst_index;
540    inst.Instruction.NumSrcRegs = 2;
541    inst.Instruction.Texture = TRUE;
542    inst.Texture.Texture = tex_target;
543    inst.Src[0].Register.File = src_file;
544    inst.Src[0].Register.Index = src_index;
545    inst.Src[1].Register.File = TGSI_FILE_SAMPLER;
546    inst.Src[1].Register.Index = sampler_index;
547 
548    ctx->emit_instruction(ctx, &inst);
549 }
550 
551 
552 extern int
553 tgsi_transform_shader(const struct tgsi_token *tokens_in,
554                       struct tgsi_token *tokens_out,
555                       uint max_tokens_out,
556                       struct tgsi_transform_context *ctx);
557 
558 
559 #endif /* TGSI_TRANSFORM_H */
560