• 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_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    uint max_tokens_out;
91    struct tgsi_token *tokens_out;
92    uint 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_op3_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,unsigned src2_file,unsigned src2_index)343 tgsi_transform_op3_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 src1_file,
351                         unsigned src1_index,
352                         unsigned src2_file,
353                         unsigned src2_index)
354 {
355    struct tgsi_full_instruction inst;
356 
357    inst = tgsi_default_full_instruction();
358    inst.Instruction.Opcode = opcode;
359    inst.Instruction.NumDstRegs = 1;
360    inst.Dst[0].Register.File = dst_file,
361    inst.Dst[0].Register.Index = dst_index;
362    inst.Dst[0].Register.WriteMask = dst_writemask;
363    inst.Instruction.NumSrcRegs = 3;
364    tgsi_transform_src_reg_xyzw(&inst.Src[0], src0_file, src0_index);
365    tgsi_transform_src_reg_xyzw(&inst.Src[1], src1_file, src1_index);
366    tgsi_transform_src_reg_xyzw(&inst.Src[2], src2_file, src2_index);
367 
368    ctx->emit_instruction(ctx, &inst);
369 }
370 
371 
372 
373 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)374 tgsi_transform_op1_swz_inst(struct tgsi_transform_context *ctx,
375                             enum tgsi_opcode opcode,
376                             unsigned dst_file,
377                             unsigned dst_index,
378                             unsigned dst_writemask,
379                             unsigned src0_file,
380                             unsigned src0_index,
381                             unsigned src0_swizzle)
382 {
383    struct tgsi_full_instruction inst;
384 
385    inst = tgsi_default_full_instruction();
386    inst.Instruction.Opcode = opcode;
387    inst.Instruction.NumDstRegs = 1;
388    inst.Dst[0].Register.File = dst_file,
389    inst.Dst[0].Register.Index = dst_index;
390    inst.Dst[0].Register.WriteMask = dst_writemask;
391    inst.Instruction.NumSrcRegs = 1;
392    tgsi_transform_src_reg_xyzw(&inst.Src[0], src0_file, src0_index);
393    switch (dst_writemask) {
394    case TGSI_WRITEMASK_X:
395       inst.Src[0].Register.SwizzleX = src0_swizzle;
396       break;
397    case TGSI_WRITEMASK_Y:
398       inst.Src[0].Register.SwizzleY = src0_swizzle;
399       break;
400    case TGSI_WRITEMASK_Z:
401       inst.Src[0].Register.SwizzleZ = src0_swizzle;
402       break;
403    case TGSI_WRITEMASK_W:
404       inst.Src[0].Register.SwizzleW = src0_swizzle;
405       break;
406    default:
407       ; /* nothing */
408    }
409 
410    ctx->emit_instruction(ctx, &inst);
411 }
412 
413 
414 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)415 tgsi_transform_op2_swz_inst(struct tgsi_transform_context *ctx,
416                             enum tgsi_opcode opcode,
417                             unsigned dst_file,
418                             unsigned dst_index,
419                             unsigned dst_writemask,
420                             unsigned src0_file,
421                             unsigned src0_index,
422                             unsigned src0_swizzle,
423                             unsigned src1_file,
424                             unsigned src1_index,
425                             unsigned src1_swizzle,
426                             bool src1_negate)
427 {
428    struct tgsi_full_instruction inst;
429 
430    inst = tgsi_default_full_instruction();
431    inst.Instruction.Opcode = opcode;
432    inst.Instruction.NumDstRegs = 1;
433    inst.Dst[0].Register.File = dst_file,
434    inst.Dst[0].Register.Index = dst_index;
435    inst.Dst[0].Register.WriteMask = dst_writemask;
436    inst.Instruction.NumSrcRegs = 2;
437    tgsi_transform_src_reg_xyzw(&inst.Src[0], src0_file, src0_index);
438    tgsi_transform_src_reg_xyzw(&inst.Src[1], src1_file, src1_index);
439    inst.Src[1].Register.Negate = src1_negate;
440    switch (dst_writemask) {
441    case TGSI_WRITEMASK_X:
442       inst.Src[0].Register.SwizzleX = src0_swizzle;
443       inst.Src[1].Register.SwizzleX = src1_swizzle;
444       break;
445    case TGSI_WRITEMASK_Y:
446       inst.Src[0].Register.SwizzleY = src0_swizzle;
447       inst.Src[1].Register.SwizzleY = src1_swizzle;
448       break;
449    case TGSI_WRITEMASK_Z:
450       inst.Src[0].Register.SwizzleZ = src0_swizzle;
451       inst.Src[1].Register.SwizzleZ = src1_swizzle;
452       break;
453    case TGSI_WRITEMASK_W:
454       inst.Src[0].Register.SwizzleW = src0_swizzle;
455       inst.Src[1].Register.SwizzleW = src1_swizzle;
456       break;
457    default:
458       ; /* nothing */
459    }
460 
461    ctx->emit_instruction(ctx, &inst);
462 }
463 
464 
465 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)466 tgsi_transform_op3_swz_inst(struct tgsi_transform_context *ctx,
467                             enum tgsi_opcode opcode,
468                             unsigned dst_file,
469                             unsigned dst_index,
470                             unsigned dst_writemask,
471                             unsigned src0_file,
472                             unsigned src0_index,
473                             unsigned src0_swizzle,
474                             unsigned src0_negate,
475                             unsigned src1_file,
476                             unsigned src1_index,
477                             unsigned src1_swizzle,
478                             unsigned src2_file,
479                             unsigned src2_index,
480                             unsigned src2_swizzle)
481 {
482    struct tgsi_full_instruction inst;
483 
484    inst = tgsi_default_full_instruction();
485    inst.Instruction.Opcode = opcode;
486    inst.Instruction.NumDstRegs = 1;
487    inst.Dst[0].Register.File = dst_file,
488    inst.Dst[0].Register.Index = dst_index;
489    inst.Dst[0].Register.WriteMask = dst_writemask;
490    inst.Instruction.NumSrcRegs = 3;
491    tgsi_transform_src_reg_xyzw(&inst.Src[0], src0_file, src0_index);
492    inst.Src[0].Register.Negate = src0_negate;
493    tgsi_transform_src_reg_xyzw(&inst.Src[1], src1_file, src1_index);
494    tgsi_transform_src_reg_xyzw(&inst.Src[2], src2_file, src2_index);
495    switch (dst_writemask) {
496    case TGSI_WRITEMASK_X:
497       inst.Src[0].Register.SwizzleX = src0_swizzle;
498       inst.Src[1].Register.SwizzleX = src1_swizzle;
499       inst.Src[2].Register.SwizzleX = src2_swizzle;
500       break;
501    case TGSI_WRITEMASK_Y:
502       inst.Src[0].Register.SwizzleY = src0_swizzle;
503       inst.Src[1].Register.SwizzleY = src1_swizzle;
504       inst.Src[2].Register.SwizzleY = src2_swizzle;
505       break;
506    case TGSI_WRITEMASK_Z:
507       inst.Src[0].Register.SwizzleZ = src0_swizzle;
508       inst.Src[1].Register.SwizzleZ = src1_swizzle;
509       inst.Src[2].Register.SwizzleZ = src2_swizzle;
510       break;
511    case TGSI_WRITEMASK_W:
512       inst.Src[0].Register.SwizzleW = src0_swizzle;
513       inst.Src[1].Register.SwizzleW = src1_swizzle;
514       inst.Src[2].Register.SwizzleW = src2_swizzle;
515       break;
516    default:
517       ; /* nothing */
518    }
519 
520    ctx->emit_instruction(ctx, &inst);
521 }
522 
523 
524 static inline void
tgsi_transform_kill_inst(struct tgsi_transform_context * ctx,unsigned src_file,unsigned src_index,unsigned src_swizzle,boolean negate)525 tgsi_transform_kill_inst(struct tgsi_transform_context *ctx,
526                          unsigned src_file,
527                          unsigned src_index,
528                          unsigned src_swizzle,
529                          boolean negate)
530 {
531    struct tgsi_full_instruction inst;
532 
533    inst = tgsi_default_full_instruction();
534    inst.Instruction.Opcode = TGSI_OPCODE_KILL_IF;
535    inst.Instruction.NumDstRegs = 0;
536    inst.Instruction.NumSrcRegs = 1;
537    tgsi_transform_src_reg_xyzw(&inst.Src[0], src_file, src_index);
538    inst.Src[0].Register.SwizzleX =
539    inst.Src[0].Register.SwizzleY =
540    inst.Src[0].Register.SwizzleZ =
541    inst.Src[0].Register.SwizzleW = src_swizzle;
542    inst.Src[0].Register.Negate = negate;
543 
544    ctx->emit_instruction(ctx, &inst);
545 }
546 
547 
548 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)549 tgsi_transform_tex_inst(struct tgsi_transform_context *ctx,
550                         unsigned dst_file,
551                         unsigned dst_index,
552                         unsigned src_file,
553                         unsigned src_index,
554                         unsigned tex_target,
555                         unsigned sampler_index)
556 {
557    struct tgsi_full_instruction inst;
558 
559    assert(tex_target < TGSI_TEXTURE_COUNT);
560 
561    inst = tgsi_default_full_instruction();
562    inst.Instruction.Opcode = TGSI_OPCODE_TEX;
563    inst.Instruction.NumDstRegs = 1;
564    inst.Dst[0].Register.File = dst_file;
565    inst.Dst[0].Register.Index = dst_index;
566    inst.Instruction.NumSrcRegs = 2;
567    inst.Instruction.Texture = TRUE;
568    inst.Texture.Texture = tex_target;
569    tgsi_transform_src_reg_xyzw(&inst.Src[0], src_file, src_index);
570    tgsi_transform_src_reg_xyzw(&inst.Src[1], TGSI_FILE_SAMPLER, sampler_index);
571 
572    ctx->emit_instruction(ctx, &inst);
573 }
574 
575 
576 extern struct tgsi_token *
577 tgsi_transform_shader(const struct tgsi_token *tokens_in,
578                       uint initial_tokens_len,
579                       struct tgsi_transform_context *ctx);
580 
581 
582 #endif /* TGSI_TRANSFORM_H */
583