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_temp_decl(struct tgsi_transform_context
*ctx
,
101 struct tgsi_full_declaration decl
;
103 decl
= tgsi_default_full_declaration();
104 decl
.Declaration
.File
= TGSI_FILE_TEMPORARY
;
106 decl
.Range
.Last
= index
;
107 ctx
->emit_declaration(ctx
, &decl
);
112 tgsi_transform_input_decl(struct tgsi_transform_context
*ctx
,
114 unsigned sem_name
, unsigned sem_index
,
117 struct tgsi_full_declaration decl
;
119 decl
= tgsi_default_full_declaration();
120 decl
.Declaration
.File
= TGSI_FILE_INPUT
;
121 decl
.Declaration
.Interpolate
= 1;
122 decl
.Declaration
.Semantic
= 1;
123 decl
.Semantic
.Name
= TGSI_SEMANTIC_GENERIC
;
124 decl
.Semantic
.Index
= sem_index
;
126 decl
.Range
.Last
= index
;
127 decl
.Interp
.Interpolate
= interp
;
129 ctx
->emit_declaration(ctx
, &decl
);
134 tgsi_transform_sampler_decl(struct tgsi_transform_context
*ctx
,
137 struct tgsi_full_declaration decl
;
139 decl
= tgsi_default_full_declaration();
140 decl
.Declaration
.File
= TGSI_FILE_SAMPLER
;
142 decl
.Range
.Last
= index
;
143 ctx
->emit_declaration(ctx
, &decl
);
148 tgsi_transform_immediate_decl(struct tgsi_transform_context
*ctx
,
149 float x
, float y
, float z
, float w
)
151 struct tgsi_full_immediate immed
;
154 immed
= tgsi_default_full_immediate();
155 immed
.Immediate
.NrTokens
= 1 + size
; /* one for the token itself */
156 immed
.u
[0].Float
= x
;
157 immed
.u
[1].Float
= y
;
158 immed
.u
[2].Float
= z
;
159 immed
.u
[3].Float
= w
;
161 ctx
->emit_immediate(ctx
, &immed
);
166 * Helper for emitting 1-operand instructions.
169 tgsi_transform_op1_inst(struct tgsi_transform_context
*ctx
,
173 unsigned dst_writemask
,
177 struct tgsi_full_instruction inst
;
179 inst
= tgsi_default_full_instruction();
180 inst
.Instruction
.Opcode
= opcode
;
181 inst
.Instruction
.NumDstRegs
= 1;
182 inst
.Dst
[0].Register
.File
= dst_file
,
183 inst
.Dst
[0].Register
.Index
= dst_index
;
184 inst
.Dst
[0].Register
.WriteMask
= dst_writemask
;
185 inst
.Instruction
.NumSrcRegs
= 1;
186 inst
.Src
[0].Register
.File
= src0_file
;
187 inst
.Src
[0].Register
.Index
= src0_index
;
189 ctx
->emit_instruction(ctx
, &inst
);
194 tgsi_transform_op2_inst(struct tgsi_transform_context
*ctx
,
198 unsigned dst_writemask
,
204 struct tgsi_full_instruction inst
;
206 inst
= tgsi_default_full_instruction();
207 inst
.Instruction
.Opcode
= opcode
;
208 inst
.Instruction
.NumDstRegs
= 1;
209 inst
.Dst
[0].Register
.File
= dst_file
,
210 inst
.Dst
[0].Register
.Index
= dst_index
;
211 inst
.Dst
[0].Register
.WriteMask
= dst_writemask
;
212 inst
.Instruction
.NumSrcRegs
= 2;
213 inst
.Src
[0].Register
.File
= src0_file
;
214 inst
.Src
[0].Register
.Index
= src0_index
;
215 inst
.Src
[1].Register
.File
= src1_file
;
216 inst
.Src
[1].Register
.Index
= src1_index
;
218 ctx
->emit_instruction(ctx
, &inst
);
223 tgsi_transform_op1_swz_inst(struct tgsi_transform_context
*ctx
,
227 unsigned dst_writemask
,
230 unsigned src0_swizzle
)
232 struct tgsi_full_instruction inst
;
234 inst
= tgsi_default_full_instruction();
235 inst
.Instruction
.Opcode
= opcode
;
236 inst
.Instruction
.NumDstRegs
= 1;
237 inst
.Dst
[0].Register
.File
= dst_file
,
238 inst
.Dst
[0].Register
.Index
= dst_index
;
239 inst
.Dst
[0].Register
.WriteMask
= dst_writemask
;
240 inst
.Instruction
.NumSrcRegs
= 1;
241 inst
.Src
[0].Register
.File
= src0_file
;
242 inst
.Src
[0].Register
.Index
= src0_index
;
243 switch (dst_writemask
) {
244 case TGSI_WRITEMASK_X
:
245 inst
.Src
[0].Register
.SwizzleX
= src0_swizzle
;
247 case TGSI_WRITEMASK_Y
:
248 inst
.Src
[0].Register
.SwizzleY
= src0_swizzle
;
250 case TGSI_WRITEMASK_Z
:
251 inst
.Src
[0].Register
.SwizzleZ
= src0_swizzle
;
253 case TGSI_WRITEMASK_W
:
254 inst
.Src
[0].Register
.SwizzleW
= src0_swizzle
;
260 ctx
->emit_instruction(ctx
, &inst
);
265 tgsi_transform_op2_swz_inst(struct tgsi_transform_context
*ctx
,
269 unsigned dst_writemask
,
272 unsigned src0_swizzle
,
275 unsigned src1_swizzle
)
277 struct tgsi_full_instruction inst
;
279 inst
= tgsi_default_full_instruction();
280 inst
.Instruction
.Opcode
= opcode
;
281 inst
.Instruction
.NumDstRegs
= 1;
282 inst
.Dst
[0].Register
.File
= dst_file
,
283 inst
.Dst
[0].Register
.Index
= dst_index
;
284 inst
.Dst
[0].Register
.WriteMask
= dst_writemask
;
285 inst
.Instruction
.NumSrcRegs
= 2;
286 inst
.Src
[0].Register
.File
= src0_file
;
287 inst
.Src
[0].Register
.Index
= src0_index
;
288 inst
.Src
[1].Register
.File
= src1_file
;
289 inst
.Src
[1].Register
.Index
= src1_index
;
290 switch (dst_writemask
) {
291 case TGSI_WRITEMASK_X
:
292 inst
.Src
[0].Register
.SwizzleX
= src0_swizzle
;
293 inst
.Src
[1].Register
.SwizzleX
= src1_swizzle
;
295 case TGSI_WRITEMASK_Y
:
296 inst
.Src
[0].Register
.SwizzleY
= src0_swizzle
;
297 inst
.Src
[1].Register
.SwizzleY
= src1_swizzle
;
299 case TGSI_WRITEMASK_Z
:
300 inst
.Src
[0].Register
.SwizzleZ
= src0_swizzle
;
301 inst
.Src
[1].Register
.SwizzleZ
= src1_swizzle
;
303 case TGSI_WRITEMASK_W
:
304 inst
.Src
[0].Register
.SwizzleW
= src0_swizzle
;
305 inst
.Src
[1].Register
.SwizzleW
= src1_swizzle
;
311 ctx
->emit_instruction(ctx
, &inst
);
316 tgsi_transform_op3_swz_inst(struct tgsi_transform_context
*ctx
,
320 unsigned dst_writemask
,
323 unsigned src0_swizzle
,
324 unsigned src0_negate
,
327 unsigned src1_swizzle
,
330 unsigned src2_swizzle
)
332 struct tgsi_full_instruction inst
;
334 inst
= tgsi_default_full_instruction();
335 inst
.Instruction
.Opcode
= opcode
;
336 inst
.Instruction
.NumDstRegs
= 1;
337 inst
.Dst
[0].Register
.File
= dst_file
,
338 inst
.Dst
[0].Register
.Index
= dst_index
;
339 inst
.Dst
[0].Register
.WriteMask
= dst_writemask
;
340 inst
.Instruction
.NumSrcRegs
= 3;
341 inst
.Src
[0].Register
.File
= src0_file
;
342 inst
.Src
[0].Register
.Index
= src0_index
;
343 inst
.Src
[0].Register
.Negate
= src0_negate
;
344 inst
.Src
[1].Register
.File
= src1_file
;
345 inst
.Src
[1].Register
.Index
= src1_index
;
346 inst
.Src
[2].Register
.File
= src2_file
;
347 inst
.Src
[2].Register
.Index
= src2_index
;
348 switch (dst_writemask
) {
349 case TGSI_WRITEMASK_X
:
350 inst
.Src
[0].Register
.SwizzleX
= src0_swizzle
;
351 inst
.Src
[1].Register
.SwizzleX
= src1_swizzle
;
352 inst
.Src
[2].Register
.SwizzleX
= src2_swizzle
;
354 case TGSI_WRITEMASK_Y
:
355 inst
.Src
[0].Register
.SwizzleY
= src0_swizzle
;
356 inst
.Src
[1].Register
.SwizzleY
= src1_swizzle
;
357 inst
.Src
[2].Register
.SwizzleY
= src2_swizzle
;
359 case TGSI_WRITEMASK_Z
:
360 inst
.Src
[0].Register
.SwizzleZ
= src0_swizzle
;
361 inst
.Src
[1].Register
.SwizzleZ
= src1_swizzle
;
362 inst
.Src
[2].Register
.SwizzleZ
= src2_swizzle
;
364 case TGSI_WRITEMASK_W
:
365 inst
.Src
[0].Register
.SwizzleW
= src0_swizzle
;
366 inst
.Src
[1].Register
.SwizzleW
= src1_swizzle
;
367 inst
.Src
[2].Register
.SwizzleW
= src2_swizzle
;
373 ctx
->emit_instruction(ctx
, &inst
);
378 tgsi_transform_kill_inst(struct tgsi_transform_context
*ctx
,
381 unsigned src_swizzle
)
383 struct tgsi_full_instruction inst
;
385 inst
= tgsi_default_full_instruction();
386 inst
.Instruction
.Opcode
= TGSI_OPCODE_KILL_IF
;
387 inst
.Instruction
.NumDstRegs
= 0;
388 inst
.Instruction
.NumSrcRegs
= 1;
389 inst
.Src
[0].Register
.File
= src_file
;
390 inst
.Src
[0].Register
.Index
= src_index
;
391 inst
.Src
[0].Register
.SwizzleX
=
392 inst
.Src
[0].Register
.SwizzleY
=
393 inst
.Src
[0].Register
.SwizzleZ
=
394 inst
.Src
[0].Register
.SwizzleW
= src_swizzle
;
395 inst
.Src
[0].Register
.Negate
= 1;
397 ctx
->emit_instruction(ctx
, &inst
);
402 tgsi_transform_tex_2d_inst(struct tgsi_transform_context
*ctx
,
407 unsigned sampler_index
)
409 struct tgsi_full_instruction inst
;
411 inst
= tgsi_default_full_instruction();
412 inst
.Instruction
.Opcode
= TGSI_OPCODE_TEX
;
413 inst
.Instruction
.NumDstRegs
= 1;
414 inst
.Dst
[0].Register
.File
= dst_file
;
415 inst
.Dst
[0].Register
.Index
= dst_index
;
416 inst
.Instruction
.NumSrcRegs
= 2;
417 inst
.Instruction
.Texture
= TRUE
;
418 inst
.Texture
.Texture
= TGSI_TEXTURE_2D
;
419 inst
.Src
[0].Register
.File
= src_file
;
420 inst
.Src
[0].Register
.Index
= src_index
;
421 inst
.Src
[1].Register
.File
= TGSI_FILE_SAMPLER
;
422 inst
.Src
[1].Register
.Index
= sampler_index
;
424 ctx
->emit_instruction(ctx
, &inst
);
429 tgsi_transform_shader(const struct tgsi_token
*tokens_in
,
430 struct tgsi_token
*tokens_out
,
432 struct tgsi_transform_context
*ctx
);
435 #endif /* TGSI_TRANSFORM_H */