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