• 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    decl.Declaration.Dimension = 1;
128    /* Dim.Index2D is already 0 */
129    ctx->emit_declaration(ctx, &decl);
130 }
131 
132 static inline void
tgsi_transform_input_decl(struct tgsi_transform_context * ctx,unsigned index,unsigned sem_name,unsigned sem_index,unsigned interp)133 tgsi_transform_input_decl(struct tgsi_transform_context *ctx,
134                           unsigned index,
135                           unsigned sem_name, unsigned sem_index,
136                           unsigned interp)
137 {
138    struct tgsi_full_declaration decl;
139 
140    decl = tgsi_default_full_declaration();
141    decl.Declaration.File = TGSI_FILE_INPUT;
142    decl.Declaration.Interpolate = 1;
143    decl.Declaration.Semantic = 1;
144    decl.Semantic.Name = sem_name;
145    decl.Semantic.Index = sem_index;
146    decl.Range.First =
147    decl.Range.Last = index;
148    decl.Interp.Interpolate = interp;
149 
150    ctx->emit_declaration(ctx, &decl);
151 }
152 
153 static inline void
tgsi_transform_output_decl(struct tgsi_transform_context * ctx,unsigned index,unsigned sem_name,unsigned sem_index,unsigned interp)154 tgsi_transform_output_decl(struct tgsi_transform_context *ctx,
155                           unsigned index,
156                           unsigned sem_name, unsigned sem_index,
157                           unsigned interp)
158 {
159    struct tgsi_full_declaration decl;
160 
161    decl = tgsi_default_full_declaration();
162    decl.Declaration.File = TGSI_FILE_OUTPUT;
163    decl.Declaration.Interpolate = 1;
164    decl.Declaration.Semantic = 1;
165    decl.Semantic.Name = sem_name;
166    decl.Semantic.Index = sem_index;
167    decl.Range.First =
168    decl.Range.Last = index;
169    decl.Interp.Interpolate = interp;
170 
171    ctx->emit_declaration(ctx, &decl);
172 }
173 
174 static inline void
tgsi_transform_sampler_decl(struct tgsi_transform_context * ctx,unsigned index)175 tgsi_transform_sampler_decl(struct tgsi_transform_context *ctx,
176                             unsigned index)
177 {
178    struct tgsi_full_declaration decl;
179 
180    decl = tgsi_default_full_declaration();
181    decl.Declaration.File = TGSI_FILE_SAMPLER;
182    decl.Range.First =
183    decl.Range.Last = index;
184    ctx->emit_declaration(ctx, &decl);
185 }
186 
187 static inline void
tgsi_transform_sampler_view_decl(struct tgsi_transform_context * ctx,unsigned index,unsigned target,enum tgsi_return_type type)188 tgsi_transform_sampler_view_decl(struct tgsi_transform_context *ctx,
189                                  unsigned index,
190                                  unsigned target,
191                                  enum tgsi_return_type type)
192 {
193    struct tgsi_full_declaration decl;
194 
195    decl = tgsi_default_full_declaration();
196    decl.Declaration.File = TGSI_FILE_SAMPLER_VIEW;
197    decl.Declaration.UsageMask = TGSI_WRITEMASK_XYZW;
198    decl.Range.First =
199    decl.Range.Last = index;
200    decl.SamplerView.Resource = target;
201    decl.SamplerView.ReturnTypeX = type;
202    decl.SamplerView.ReturnTypeY = type;
203    decl.SamplerView.ReturnTypeZ = type;
204    decl.SamplerView.ReturnTypeW = type;
205 
206    ctx->emit_declaration(ctx, &decl);
207 }
208 
209 static inline void
tgsi_transform_immediate_decl(struct tgsi_transform_context * ctx,float x,float y,float z,float w)210 tgsi_transform_immediate_decl(struct tgsi_transform_context *ctx,
211                               float x, float y, float z, float w)
212 {
213    struct tgsi_full_immediate immed;
214    unsigned size = 4;
215 
216    immed = tgsi_default_full_immediate();
217    immed.Immediate.NrTokens = 1 + size; /* one for the token itself */
218    immed.u[0].Float = x;
219    immed.u[1].Float = y;
220    immed.u[2].Float = z;
221    immed.u[3].Float = w;
222 
223    ctx->emit_immediate(ctx, &immed);
224 }
225 
226 static inline void
tgsi_transform_immediate_int_decl(struct tgsi_transform_context * ctx,int x,int y,int z,int w)227 tgsi_transform_immediate_int_decl(struct tgsi_transform_context *ctx,
228                                   int x, int y, int z, int w)
229 {
230    struct tgsi_full_immediate immed;
231    unsigned size = 4;
232 
233    immed = tgsi_default_full_immediate();
234    immed.Immediate.DataType = TGSI_IMM_INT32;
235    immed.Immediate.NrTokens = 1 + size; /* one for the token itself */
236    immed.u[0].Int = x;
237    immed.u[1].Int = y;
238    immed.u[2].Int = z;
239    immed.u[3].Int = w;
240 
241    ctx->emit_immediate(ctx, &immed);
242 }
243 
244 static inline void
tgsi_transform_dst_reg(struct tgsi_full_dst_register * reg,unsigned file,unsigned index,unsigned writemask)245 tgsi_transform_dst_reg(struct tgsi_full_dst_register *reg,
246                        unsigned file, unsigned index, unsigned writemask)
247 {
248    reg->Register.File = file;
249    reg->Register.Index = index;
250    reg->Register.WriteMask = writemask;
251 }
252 
253 static inline void
tgsi_transform_src_reg_xyzw(struct tgsi_full_src_register * reg,unsigned file,unsigned index)254 tgsi_transform_src_reg_xyzw(struct tgsi_full_src_register *reg,
255                             unsigned file, unsigned index)
256 {
257    reg->Register.File = file;
258    reg->Register.Index = index;
259    if (file == TGSI_FILE_CONSTANT) {
260       reg->Register.Dimension = 1;
261       reg->Dimension.Index = 0;
262    }
263 }
264 
265 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)266 tgsi_transform_src_reg(struct tgsi_full_src_register *reg,
267                        unsigned file, unsigned index,
268                        unsigned swizzleX, unsigned swizzleY,
269                        unsigned swizzleZ, unsigned swizzleW)
270 {
271    reg->Register.File = file;
272    reg->Register.Index = index;
273    if (file == TGSI_FILE_CONSTANT) {
274       reg->Register.Dimension = 1;
275       reg->Dimension.Index = 0;
276    }
277    reg->Register.SwizzleX = swizzleX;
278    reg->Register.SwizzleY = swizzleY;
279    reg->Register.SwizzleZ = swizzleZ;
280    reg->Register.SwizzleW = swizzleW;
281 }
282 
283 /**
284  * Helper for emitting 1-operand instructions.
285  */
286 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)287 tgsi_transform_op1_inst(struct tgsi_transform_context *ctx,
288                         enum tgsi_opcode opcode,
289                         unsigned dst_file,
290                         unsigned dst_index,
291                         unsigned dst_writemask,
292                         unsigned src0_file,
293                         unsigned src0_index)
294 {
295    struct tgsi_full_instruction inst;
296 
297    inst = tgsi_default_full_instruction();
298    inst.Instruction.Opcode = opcode;
299    inst.Instruction.NumDstRegs = 1;
300    inst.Dst[0].Register.File = dst_file,
301    inst.Dst[0].Register.Index = dst_index;
302    inst.Dst[0].Register.WriteMask = dst_writemask;
303    inst.Instruction.NumSrcRegs = 1;
304    tgsi_transform_src_reg_xyzw(&inst.Src[0], src0_file, src0_index);
305 
306    ctx->emit_instruction(ctx, &inst);
307 }
308 
309 
310 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)311 tgsi_transform_op2_inst(struct tgsi_transform_context *ctx,
312                         enum tgsi_opcode opcode,
313                         unsigned dst_file,
314                         unsigned dst_index,
315                         unsigned dst_writemask,
316                         unsigned src0_file,
317                         unsigned src0_index,
318                         unsigned src1_file,
319                         unsigned src1_index,
320                         bool src1_negate)
321 {
322    struct tgsi_full_instruction inst;
323 
324    inst = tgsi_default_full_instruction();
325    inst.Instruction.Opcode = opcode;
326    inst.Instruction.NumDstRegs = 1;
327    inst.Dst[0].Register.File = dst_file,
328    inst.Dst[0].Register.Index = dst_index;
329    inst.Dst[0].Register.WriteMask = dst_writemask;
330    inst.Instruction.NumSrcRegs = 2;
331    tgsi_transform_src_reg_xyzw(&inst.Src[0], src0_file, src0_index);
332    tgsi_transform_src_reg_xyzw(&inst.Src[1], src1_file, src1_index);
333    inst.Src[1].Register.Negate = src1_negate;
334 
335    ctx->emit_instruction(ctx, &inst);
336 }
337 
338 
339 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)340 tgsi_transform_op3_inst(struct tgsi_transform_context *ctx,
341                         enum tgsi_opcode opcode,
342                         unsigned dst_file,
343                         unsigned dst_index,
344                         unsigned dst_writemask,
345                         unsigned src0_file,
346                         unsigned src0_index,
347                         unsigned src1_file,
348                         unsigned src1_index,
349                         unsigned src2_file,
350                         unsigned src2_index)
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 = 3;
361    tgsi_transform_src_reg_xyzw(&inst.Src[0], src0_file, src0_index);
362    tgsi_transform_src_reg_xyzw(&inst.Src[1], src1_file, src1_index);
363    tgsi_transform_src_reg_xyzw(&inst.Src[2], src2_file, src2_index);
364 
365    ctx->emit_instruction(ctx, &inst);
366 }
367 
368 
369 
370 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)371 tgsi_transform_op1_swz_inst(struct tgsi_transform_context *ctx,
372                             enum tgsi_opcode opcode,
373                             unsigned dst_file,
374                             unsigned dst_index,
375                             unsigned dst_writemask,
376                             unsigned src0_file,
377                             unsigned src0_index,
378                             unsigned src0_swizzle)
379 {
380    struct tgsi_full_instruction inst;
381 
382    inst = tgsi_default_full_instruction();
383    inst.Instruction.Opcode = opcode;
384    inst.Instruction.NumDstRegs = 1;
385    inst.Dst[0].Register.File = dst_file,
386    inst.Dst[0].Register.Index = dst_index;
387    inst.Dst[0].Register.WriteMask = dst_writemask;
388    inst.Instruction.NumSrcRegs = 1;
389    tgsi_transform_src_reg_xyzw(&inst.Src[0], src0_file, src0_index);
390    switch (dst_writemask) {
391    case TGSI_WRITEMASK_X:
392       inst.Src[0].Register.SwizzleX = src0_swizzle;
393       break;
394    case TGSI_WRITEMASK_Y:
395       inst.Src[0].Register.SwizzleY = src0_swizzle;
396       break;
397    case TGSI_WRITEMASK_Z:
398       inst.Src[0].Register.SwizzleZ = src0_swizzle;
399       break;
400    case TGSI_WRITEMASK_W:
401       inst.Src[0].Register.SwizzleW = src0_swizzle;
402       break;
403    default:
404       ; /* nothing */
405    }
406 
407    ctx->emit_instruction(ctx, &inst);
408 }
409 
410 
411 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)412 tgsi_transform_op2_swz_inst(struct tgsi_transform_context *ctx,
413                             enum tgsi_opcode opcode,
414                             unsigned dst_file,
415                             unsigned dst_index,
416                             unsigned dst_writemask,
417                             unsigned src0_file,
418                             unsigned src0_index,
419                             unsigned src0_swizzle,
420                             unsigned src1_file,
421                             unsigned src1_index,
422                             unsigned src1_swizzle,
423                             bool src1_negate)
424 {
425    struct tgsi_full_instruction inst;
426 
427    inst = tgsi_default_full_instruction();
428    inst.Instruction.Opcode = opcode;
429    inst.Instruction.NumDstRegs = 1;
430    inst.Dst[0].Register.File = dst_file,
431    inst.Dst[0].Register.Index = dst_index;
432    inst.Dst[0].Register.WriteMask = dst_writemask;
433    inst.Instruction.NumSrcRegs = 2;
434    tgsi_transform_src_reg_xyzw(&inst.Src[0], src0_file, src0_index);
435    tgsi_transform_src_reg_xyzw(&inst.Src[1], src1_file, src1_index);
436    inst.Src[1].Register.Negate = src1_negate;
437    switch (dst_writemask) {
438    case TGSI_WRITEMASK_X:
439       inst.Src[0].Register.SwizzleX = src0_swizzle;
440       inst.Src[1].Register.SwizzleX = src1_swizzle;
441       break;
442    case TGSI_WRITEMASK_Y:
443       inst.Src[0].Register.SwizzleY = src0_swizzle;
444       inst.Src[1].Register.SwizzleY = src1_swizzle;
445       break;
446    case TGSI_WRITEMASK_Z:
447       inst.Src[0].Register.SwizzleZ = src0_swizzle;
448       inst.Src[1].Register.SwizzleZ = src1_swizzle;
449       break;
450    case TGSI_WRITEMASK_W:
451       inst.Src[0].Register.SwizzleW = src0_swizzle;
452       inst.Src[1].Register.SwizzleW = src1_swizzle;
453       break;
454    default:
455       ; /* nothing */
456    }
457 
458    ctx->emit_instruction(ctx, &inst);
459 }
460 
461 
462 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)463 tgsi_transform_op3_swz_inst(struct tgsi_transform_context *ctx,
464                             enum tgsi_opcode opcode,
465                             unsigned dst_file,
466                             unsigned dst_index,
467                             unsigned dst_writemask,
468                             unsigned src0_file,
469                             unsigned src0_index,
470                             unsigned src0_swizzle,
471                             unsigned src0_negate,
472                             unsigned src1_file,
473                             unsigned src1_index,
474                             unsigned src1_swizzle,
475                             unsigned src2_file,
476                             unsigned src2_index,
477                             unsigned src2_swizzle)
478 {
479    struct tgsi_full_instruction inst;
480 
481    inst = tgsi_default_full_instruction();
482    inst.Instruction.Opcode = opcode;
483    inst.Instruction.NumDstRegs = 1;
484    inst.Dst[0].Register.File = dst_file,
485    inst.Dst[0].Register.Index = dst_index;
486    inst.Dst[0].Register.WriteMask = dst_writemask;
487    inst.Instruction.NumSrcRegs = 3;
488    tgsi_transform_src_reg_xyzw(&inst.Src[0], src0_file, src0_index);
489    inst.Src[0].Register.Negate = src0_negate;
490    tgsi_transform_src_reg_xyzw(&inst.Src[1], src1_file, src1_index);
491    tgsi_transform_src_reg_xyzw(&inst.Src[2], src2_file, src2_index);
492    switch (dst_writemask) {
493    case TGSI_WRITEMASK_X:
494       inst.Src[0].Register.SwizzleX = src0_swizzle;
495       inst.Src[1].Register.SwizzleX = src1_swizzle;
496       inst.Src[2].Register.SwizzleX = src2_swizzle;
497       break;
498    case TGSI_WRITEMASK_Y:
499       inst.Src[0].Register.SwizzleY = src0_swizzle;
500       inst.Src[1].Register.SwizzleY = src1_swizzle;
501       inst.Src[2].Register.SwizzleY = src2_swizzle;
502       break;
503    case TGSI_WRITEMASK_Z:
504       inst.Src[0].Register.SwizzleZ = src0_swizzle;
505       inst.Src[1].Register.SwizzleZ = src1_swizzle;
506       inst.Src[2].Register.SwizzleZ = src2_swizzle;
507       break;
508    case TGSI_WRITEMASK_W:
509       inst.Src[0].Register.SwizzleW = src0_swizzle;
510       inst.Src[1].Register.SwizzleW = src1_swizzle;
511       inst.Src[2].Register.SwizzleW = src2_swizzle;
512       break;
513    default:
514       ; /* nothing */
515    }
516 
517    ctx->emit_instruction(ctx, &inst);
518 }
519 
520 
521 static inline void
tgsi_transform_kill_inst(struct tgsi_transform_context * ctx,unsigned src_file,unsigned src_index,unsigned src_swizzle,boolean negate)522 tgsi_transform_kill_inst(struct tgsi_transform_context *ctx,
523                          unsigned src_file,
524                          unsigned src_index,
525                          unsigned src_swizzle,
526                          boolean negate)
527 {
528    struct tgsi_full_instruction inst;
529 
530    inst = tgsi_default_full_instruction();
531    inst.Instruction.Opcode = TGSI_OPCODE_KILL_IF;
532    inst.Instruction.NumDstRegs = 0;
533    inst.Instruction.NumSrcRegs = 1;
534    tgsi_transform_src_reg_xyzw(&inst.Src[0], src_file, src_index);
535    inst.Src[0].Register.SwizzleX =
536    inst.Src[0].Register.SwizzleY =
537    inst.Src[0].Register.SwizzleZ =
538    inst.Src[0].Register.SwizzleW = src_swizzle;
539    inst.Src[0].Register.Negate = negate;
540 
541    ctx->emit_instruction(ctx, &inst);
542 }
543 
544 
545 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)546 tgsi_transform_tex_inst(struct tgsi_transform_context *ctx,
547                         unsigned dst_file,
548                         unsigned dst_index,
549                         unsigned src_file,
550                         unsigned src_index,
551                         unsigned tex_target,
552                         unsigned sampler_index)
553 {
554    struct tgsi_full_instruction inst;
555 
556    assert(tex_target < TGSI_TEXTURE_COUNT);
557 
558    inst = tgsi_default_full_instruction();
559    inst.Instruction.Opcode = TGSI_OPCODE_TEX;
560    inst.Instruction.NumDstRegs = 1;
561    inst.Dst[0].Register.File = dst_file;
562    inst.Dst[0].Register.Index = dst_index;
563    inst.Instruction.NumSrcRegs = 2;
564    inst.Instruction.Texture = TRUE;
565    inst.Texture.Texture = tex_target;
566    tgsi_transform_src_reg_xyzw(&inst.Src[0], src_file, src_index);
567    tgsi_transform_src_reg_xyzw(&inst.Src[1], TGSI_FILE_SAMPLER, sampler_index);
568 
569    ctx->emit_instruction(ctx, &inst);
570 }
571 
572 
573 extern int
574 tgsi_transform_shader(const struct tgsi_token *tokens_in,
575                       struct tgsi_token *tokens_out,
576                       uint max_tokens_out,
577                       struct tgsi_transform_context *ctx);
578 
579 
580 #endif /* TGSI_TRANSFORM_H */
581