1 /**************************************************************************
3 * Copyright 2008 VMware, Inc.
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
28 #ifndef TGSI_TRANSFORM_H
29 #define TGSI_TRANSFORM_H
32 #include "pipe/p_shader_tokens.h"
33 #include "tgsi/tgsi_parse.h"
34 #include "tgsi/tgsi_build.h"
39 * Subclass this to add caller-specific data
41 struct tgsi_transform_context
46 * User-defined callbacks invoked per instruction.
48 void (*transform_instruction
)(struct tgsi_transform_context
*ctx
,
49 struct tgsi_full_instruction
*inst
);
51 void (*transform_declaration
)(struct tgsi_transform_context
*ctx
,
52 struct tgsi_full_declaration
*decl
);
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
);
60 * Called after last declaration, before first instruction. This is
61 * where the user might insert new declarations and/or instructions.
63 void (*prolog
)(struct tgsi_transform_context
*ctx
);
66 * Called at end of input program to allow caller to append extra
67 * instructions. Return number of tokens emitted.
69 void (*epilog
)(struct tgsi_transform_context
*ctx
);
75 * These are setup by tgsi_transform_shader() and cannot be overridden.
76 * Meant to be called from in the above user callback functions.
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
);
87 struct tgsi_header
*header
;
89 struct tgsi_token
*tokens_out
;
95 * Helper for emitting temporary register declarations.
98 tgsi_transform_temps_decl(struct tgsi_transform_context
*ctx
,
99 unsigned firstIdx
, unsigned lastIdx
)
101 struct tgsi_full_declaration decl
;
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
);
111 tgsi_transform_temp_decl(struct tgsi_transform_context
*ctx
,
114 tgsi_transform_temps_decl(ctx
, index
, index
);
118 tgsi_transform_const_decl(struct tgsi_transform_context
*ctx
,
119 unsigned firstIdx
, unsigned lastIdx
)
121 struct tgsi_full_declaration decl
;
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
);
133 tgsi_transform_input_decl(struct tgsi_transform_context
*ctx
,
135 unsigned sem_name
, unsigned sem_index
,
138 struct tgsi_full_declaration decl
;
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
;
147 decl
.Range
.Last
= index
;
148 decl
.Interp
.Interpolate
= interp
;
150 ctx
->emit_declaration(ctx
, &decl
);
154 tgsi_transform_output_decl(struct tgsi_transform_context
*ctx
,
156 unsigned sem_name
, unsigned sem_index
,
159 struct tgsi_full_declaration decl
;
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
;
168 decl
.Range
.Last
= index
;
169 decl
.Interp
.Interpolate
= interp
;
171 ctx
->emit_declaration(ctx
, &decl
);
175 tgsi_transform_sampler_decl(struct tgsi_transform_context
*ctx
,
178 struct tgsi_full_declaration decl
;
180 decl
= tgsi_default_full_declaration();
181 decl
.Declaration
.File
= TGSI_FILE_SAMPLER
;
183 decl
.Range
.Last
= index
;
184 ctx
->emit_declaration(ctx
, &decl
);
188 tgsi_transform_sampler_view_decl(struct tgsi_transform_context
*ctx
,
191 enum tgsi_return_type type
)
193 struct tgsi_full_declaration decl
;
195 decl
= tgsi_default_full_declaration();
196 decl
.Declaration
.File
= TGSI_FILE_SAMPLER_VIEW
;
197 decl
.Declaration
.UsageMask
= TGSI_WRITEMASK_XYZW
;
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
;
206 ctx
->emit_declaration(ctx
, &decl
);
210 tgsi_transform_immediate_decl(struct tgsi_transform_context
*ctx
,
211 float x
, float y
, float z
, float w
)
213 struct tgsi_full_immediate immed
;
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
;
223 ctx
->emit_immediate(ctx
, &immed
);
227 tgsi_transform_immediate_int_decl(struct tgsi_transform_context
*ctx
,
228 int x
, int y
, int z
, int w
)
230 struct tgsi_full_immediate immed
;
233 immed
= tgsi_default_full_immediate();
234 immed
.Immediate
.DataType
= TGSI_IMM_INT32
;
235 immed
.Immediate
.NrTokens
= 1 + size
; /* one for the token itself */
241 ctx
->emit_immediate(ctx
, &immed
);
245 tgsi_transform_dst_reg(struct tgsi_full_dst_register
*reg
,
246 unsigned file
, unsigned index
, unsigned writemask
)
248 reg
->Register
.File
= file
;
249 reg
->Register
.Index
= index
;
250 reg
->Register
.WriteMask
= writemask
;
254 tgsi_transform_src_reg_xyzw(struct tgsi_full_src_register
*reg
,
255 unsigned file
, unsigned index
)
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;
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
)
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;
277 reg
->Register
.SwizzleX
= swizzleX
;
278 reg
->Register
.SwizzleY
= swizzleY
;
279 reg
->Register
.SwizzleZ
= swizzleZ
;
280 reg
->Register
.SwizzleW
= swizzleW
;
284 * Helper for emitting 1-operand instructions.
287 tgsi_transform_op1_inst(struct tgsi_transform_context
*ctx
,
288 enum tgsi_opcode opcode
,
291 unsigned dst_writemask
,
295 struct tgsi_full_instruction inst
;
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
);
306 ctx
->emit_instruction(ctx
, &inst
);
311 tgsi_transform_op2_inst(struct tgsi_transform_context
*ctx
,
312 enum tgsi_opcode opcode
,
315 unsigned dst_writemask
,
322 struct tgsi_full_instruction inst
;
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
;
335 ctx
->emit_instruction(ctx
, &inst
);
340 tgsi_transform_op3_inst(struct tgsi_transform_context
*ctx
,
341 enum tgsi_opcode opcode
,
344 unsigned dst_writemask
,
352 struct tgsi_full_instruction inst
;
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
);
365 ctx
->emit_instruction(ctx
, &inst
);
371 tgsi_transform_op1_swz_inst(struct tgsi_transform_context
*ctx
,
372 enum tgsi_opcode opcode
,
375 unsigned dst_writemask
,
378 unsigned src0_swizzle
)
380 struct tgsi_full_instruction inst
;
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
;
394 case TGSI_WRITEMASK_Y
:
395 inst
.Src
[0].Register
.SwizzleY
= src0_swizzle
;
397 case TGSI_WRITEMASK_Z
:
398 inst
.Src
[0].Register
.SwizzleZ
= src0_swizzle
;
400 case TGSI_WRITEMASK_W
:
401 inst
.Src
[0].Register
.SwizzleW
= src0_swizzle
;
407 ctx
->emit_instruction(ctx
, &inst
);
412 tgsi_transform_op2_swz_inst(struct tgsi_transform_context
*ctx
,
413 enum tgsi_opcode opcode
,
416 unsigned dst_writemask
,
419 unsigned src0_swizzle
,
422 unsigned src1_swizzle
,
425 struct tgsi_full_instruction inst
;
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
;
442 case TGSI_WRITEMASK_Y
:
443 inst
.Src
[0].Register
.SwizzleY
= src0_swizzle
;
444 inst
.Src
[1].Register
.SwizzleY
= src1_swizzle
;
446 case TGSI_WRITEMASK_Z
:
447 inst
.Src
[0].Register
.SwizzleZ
= src0_swizzle
;
448 inst
.Src
[1].Register
.SwizzleZ
= src1_swizzle
;
450 case TGSI_WRITEMASK_W
:
451 inst
.Src
[0].Register
.SwizzleW
= src0_swizzle
;
452 inst
.Src
[1].Register
.SwizzleW
= src1_swizzle
;
458 ctx
->emit_instruction(ctx
, &inst
);
463 tgsi_transform_op3_swz_inst(struct tgsi_transform_context
*ctx
,
464 enum tgsi_opcode opcode
,
467 unsigned dst_writemask
,
470 unsigned src0_swizzle
,
471 unsigned src0_negate
,
474 unsigned src1_swizzle
,
477 unsigned src2_swizzle
)
479 struct tgsi_full_instruction inst
;
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
;
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
;
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
;
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
;
517 ctx
->emit_instruction(ctx
, &inst
);
522 tgsi_transform_kill_inst(struct tgsi_transform_context
*ctx
,
525 unsigned src_swizzle
,
528 struct tgsi_full_instruction inst
;
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
;
541 ctx
->emit_instruction(ctx
, &inst
);
546 tgsi_transform_tex_inst(struct tgsi_transform_context
*ctx
,
552 unsigned sampler_index
)
554 struct tgsi_full_instruction inst
;
556 assert(tex_target
< TGSI_TEXTURE_COUNT
);
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
);
569 ctx
->emit_instruction(ctx
, &inst
);
574 tgsi_transform_shader(const struct tgsi_token
*tokens_in
,
575 struct tgsi_token
*tokens_out
,
577 struct tgsi_transform_context
*ctx
);
580 #endif /* TGSI_TRANSFORM_H */