1 #include "tgsi_platform.h"
3 #include "pipe/tgsi/mesa/mesa_to_tgsi.h"
9 * Map mesa register file to TGSI register file.
13 enum register_file file
)
16 case PROGRAM_UNDEFINED
:
17 return TGSI_FILE_NULL
;
18 case PROGRAM_TEMPORARY
:
19 return TGSI_FILE_TEMPORARY
;
20 //case PROGRAM_LOCAL_PARAM:
21 //case PROGRAM_ENV_PARAM:
22 case PROGRAM_STATE_VAR
:
23 case PROGRAM_NAMED_PARAM
:
24 case PROGRAM_CONSTANT
:
26 return TGSI_FILE_CONSTANT
;
28 return TGSI_FILE_INPUT
;
30 return TGSI_FILE_OUTPUT
;
32 return TGSI_FILE_ADDRESS
;
35 return TGSI_FILE_NULL
;
40 * Map mesa register file index to TGSI index.
41 * Take special care when processing input and output indices.
42 * \param processor either TGSI_PROCESSOR_FRAGMENT or TGSI_PROCESSOR_VERTEX
43 * \param file one of TGSI_FILE_x
44 * \param index the mesa register file index
45 * \param usage_bitmask ???
48 map_register_file_index(
52 const GLuint inputMapping
[],
53 const GLuint outputMapping
[])
57 assert(processor
== TGSI_PROCESSOR_FRAGMENT
58 || processor
== TGSI_PROCESSOR_VERTEX
);
63 * The fragment/vertex program input indexes (FRAG/VERT_ATTRIB_x) get
64 * mapped to a packed sequence of integers.
65 * If a program uses one input attribute, the mapped index will be 1.
66 * If a program uses two input attribs, the mapped indexes will be 1,2.
67 * If a program uses 3 input attribs, the mapped indexes will be 1,2,3.
70 printf("Map %d input %d to %d\n", processor
, index
, mapped_index
);
71 return inputMapping
[index
];
73 case TGSI_FILE_OUTPUT
:
75 assert( usage_bitmask == 0x0 );
77 if( processor
== TGSI_PROCESSOR_FRAGMENT
) {
78 /* depth result -> index 0
79 * color results -> index 1, 2, ...
81 if( index
== FRAG_RESULT_DEPR
) {
82 mapped_index
= 0; /**TGSI_ATTRIB_POS;**/
85 assert( index
== FRAG_RESULT_COLR
);
86 mapped_index
= 1; /**TGSI_ATTRIB_COLOR0;**/
90 /* vertex output slots are tightly packed, find mapped pos */
91 /* mapped_index = VERT_RESULT_x */
92 mapped_index
= outputMapping
[index
];
93 printf("Map VP output from %d to %d\n", index
, mapped_index
);
105 * Map mesa texture target to TGSI texture target.
111 switch( textarget
) {
112 case TEXTURE_1D_INDEX
:
113 return TGSI_TEXTURE_1D
;
114 case TEXTURE_2D_INDEX
:
115 return TGSI_TEXTURE_2D
;
116 case TEXTURE_3D_INDEX
:
117 return TGSI_TEXTURE_3D
;
118 case TEXTURE_CUBE_INDEX
:
119 return TGSI_TEXTURE_CUBE
;
120 case TEXTURE_RECT_INDEX
:
121 return TGSI_TEXTURE_RECT
;
126 return TGSI_TEXTURE_1D
;
135 return TGSI_SAT_NONE
;
136 case SATURATE_ZERO_ONE
:
137 return TGSI_SAT_ZERO_ONE
;
138 case SATURATE_PLUS_MINUS_ONE
:
139 return TGSI_SAT_MINUS_PLUS_ONE
;
142 return TGSI_SAT_NONE
;
150 assert( WRITEMASK_X
== TGSI_WRITEMASK_X
);
151 assert( WRITEMASK_Y
== TGSI_WRITEMASK_Y
);
152 assert( WRITEMASK_Z
== TGSI_WRITEMASK_Z
);
153 assert( WRITEMASK_W
== TGSI_WRITEMASK_W
);
154 assert( (writemask
& ~TGSI_WRITEMASK_XYZW
) == 0 );
161 const struct prog_instruction
*inst
,
162 struct tgsi_full_instruction
*fullinst
,
163 const GLuint inputMapping
[],
164 const GLuint outputMapping
[],
165 GLuint preamble_size
,
169 struct tgsi_full_dst_register
*fulldst
;
170 struct tgsi_full_src_register
*fullsrc
;
172 *fullinst
= tgsi_default_full_instruction();
174 fullinst
->Instruction
.Saturate
= convert_sat( inst
->SaturateMode
);
175 fullinst
->Instruction
.NumDstRegs
= _mesa_num_inst_dst_regs( inst
->Opcode
);
176 fullinst
->Instruction
.NumSrcRegs
= _mesa_num_inst_src_regs( inst
->Opcode
);
178 fulldst
= &fullinst
->FullDstRegisters
[0];
179 fulldst
->DstRegister
.File
= map_register_file( inst
->DstReg
.File
);
180 fulldst
->DstRegister
.Index
= map_register_file_index(
182 fulldst
->DstRegister
.File
,
187 fulldst
->DstRegister
.WriteMask
= convert_writemask( inst
->DstReg
.WriteMask
);
189 for( i
= 0; i
< fullinst
->Instruction
.NumSrcRegs
; i
++ ) {
192 fullsrc
= &fullinst
->FullSrcRegisters
[i
];
193 fullsrc
->SrcRegister
.File
= map_register_file( inst
->SrcReg
[i
].File
);
194 fullsrc
->SrcRegister
.Index
= map_register_file_index(
196 fullsrc
->SrcRegister
.File
,
197 inst
->SrcReg
[i
].Index
,
201 for( j
= 0; j
< 4; j
++ ) {
204 swz
= GET_SWZ( inst
->SrcReg
[i
].Swizzle
, j
);
205 if( swz
> SWIZZLE_W
) {
206 tgsi_util_set_src_register_extswizzle(
207 &fullsrc
->SrcRegisterExtSwz
,
212 tgsi_util_set_src_register_swizzle(
213 &fullsrc
->SrcRegister
,
219 if( inst
->SrcReg
[i
].NegateBase
== NEGATE_XYZW
) {
220 fullsrc
->SrcRegister
.Negate
= 1;
222 else if( inst
->SrcReg
[i
].NegateBase
!= NEGATE_NONE
) {
223 if( inst
->SrcReg
[i
].NegateBase
& NEGATE_X
) {
224 fullsrc
->SrcRegisterExtSwz
.NegateX
= 1;
226 if( inst
->SrcReg
[i
].NegateBase
& NEGATE_Y
) {
227 fullsrc
->SrcRegisterExtSwz
.NegateY
= 1;
229 if( inst
->SrcReg
[i
].NegateBase
& NEGATE_Z
) {
230 fullsrc
->SrcRegisterExtSwz
.NegateZ
= 1;
232 if( inst
->SrcReg
[i
].NegateBase
& NEGATE_W
) {
233 fullsrc
->SrcRegisterExtSwz
.NegateW
= 1;
237 if( inst
->SrcReg
[i
].Abs
) {
238 fullsrc
->SrcRegisterExtMod
.Absolute
= 1;
241 if( inst
->SrcReg
[i
].NegateAbs
) {
242 fullsrc
->SrcRegisterExtMod
.Negate
= 1;
245 if( inst
->SrcReg
[i
].RelAddr
) {
246 fullsrc
->SrcRegister
.Indirect
= 1;
248 fullsrc
->SrcRegisterInd
.File
= TGSI_FILE_ADDRESS
;
249 fullsrc
->SrcRegisterInd
.Index
= 0;
253 switch( inst
->Opcode
) {
255 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_ARL
;
258 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_ABS
;
261 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_ADD
;
264 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_BGNLOOP2
;
267 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_BGNSUB
;
270 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_BRA
;
273 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_BRK
;
276 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_CMP
;
279 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_CONT
;
282 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_COS
;
285 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_DDX
;
288 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_DDY
;
291 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_DP3
;
294 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_DP4
;
297 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_DPH
;
300 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_DST
;
303 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_ELSE
;
304 fullinst
->InstructionExtLabel
.Label
= inst
->BranchTarget
+ preamble_size
;
307 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_ENDIF
;
310 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_ENDLOOP2
;
313 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_ENDSUB
;
316 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_EX2
;
319 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_EXP
;
322 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_FLR
;
325 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_FRC
;
328 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_IF
;
329 fullinst
->InstructionExtLabel
.Label
= inst
->BranchTarget
+ preamble_size
;
332 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_INT
;
335 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_KIL
;
338 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_LG2
;
341 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_LOG
;
344 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_LIT
;
347 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_LRP
;
350 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_MAD
;
353 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_MAX
;
356 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_MIN
;
359 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_MOV
;
362 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_MUL
;
365 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_NOISE1
;
368 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_NOISE2
;
371 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_NOISE3
;
374 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_NOISE4
;
377 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_NOP
;
380 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_POW
;
383 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_RCP
;
386 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_RSQ
;
387 tgsi_util_set_full_src_register_sign_mode(
388 &fullinst
->FullSrcRegisters
[0],
389 TGSI_UTIL_SIGN_CLEAR
);
392 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_SCS
;
393 fulldst
->DstRegister
.WriteMask
&= TGSI_WRITEMASK_XY
;
396 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_SEQ
;
399 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_SGE
;
402 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_SGT
;
405 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_SIN
;
408 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_SLE
;
411 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_SLT
;
414 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_SNE
;
417 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_SUB
;
420 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_SWZ
;
423 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_TEX
;
424 fullinst
->Instruction
.NumSrcRegs
= 2;
425 fullinst
->InstructionExtTexture
.Texture
= map_texture_target( inst
->TexSrcTarget
);
426 fullinst
->FullSrcRegisters
[1].SrcRegister
.File
= TGSI_FILE_SAMPLER
;
427 fullinst
->FullSrcRegisters
[1].SrcRegister
.Index
= inst
->TexSrcUnit
;
430 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_TXB
;
431 fullinst
->Instruction
.NumSrcRegs
= 2;
432 fullinst
->InstructionExtTexture
.Texture
= map_texture_target( inst
->TexSrcTarget
);
433 fullinst
->FullSrcRegisters
[1].SrcRegister
.File
= TGSI_FILE_SAMPLER
;
434 fullinst
->FullSrcRegisters
[1].SrcRegister
.Index
= inst
->TexSrcUnit
;
437 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_TXD
;
438 fullinst
->Instruction
.NumSrcRegs
= 2;
439 fullinst
->InstructionExtTexture
.Texture
= map_texture_target( inst
->TexSrcTarget
);
440 fullinst
->FullSrcRegisters
[1].SrcRegister
.File
= TGSI_FILE_SAMPLER
;
441 fullinst
->FullSrcRegisters
[1].SrcRegister
.Index
= inst
->TexSrcUnit
;
444 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_TXL
;
445 fullinst
->Instruction
.NumSrcRegs
= 2;
446 fullinst
->InstructionExtTexture
.Texture
= map_texture_target( inst
->TexSrcTarget
);
447 fullinst
->FullSrcRegisters
[1].SrcRegister
.File
= TGSI_FILE_SAMPLER
;
448 fullinst
->FullSrcRegisters
[1].SrcRegister
.Index
= inst
->TexSrcUnit
;
451 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_TEX
;
452 fullinst
->Instruction
.NumSrcRegs
= 2;
453 fullinst
->InstructionExtTexture
.Texture
= map_texture_target( inst
->TexSrcTarget
);
454 fullinst
->FullSrcRegisters
[0].SrcRegisterExtSwz
.ExtDivide
= TGSI_EXTSWIZZLE_W
;
455 fullinst
->FullSrcRegisters
[1].SrcRegister
.File
= TGSI_FILE_SAMPLER
;
456 fullinst
->FullSrcRegisters
[1].SrcRegister
.Index
= inst
->TexSrcUnit
;
459 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_XPD
;
460 fulldst
->DstRegister
.WriteMask
&= TGSI_WRITEMASK_XYZ
;
471 static struct tgsi_full_declaration
476 GLuint semantic_name
,
477 GLuint semantic_index
)
479 struct tgsi_full_declaration decl
;
481 decl
= tgsi_default_full_declaration();
482 decl
.Declaration
.File
= TGSI_FILE_INPUT
;
483 decl
.Declaration
.Declare
= TGSI_DECLARE_RANGE
;
484 decl
.Declaration
.UsageMask
= usage_mask
;
485 decl
.Declaration
.Semantic
= 1;
486 decl
.Declaration
.Interpolate
= 1;
487 decl
.u
.DeclarationRange
.First
= index
;
488 decl
.u
.DeclarationRange
.Last
= index
;
489 decl
.Semantic
.SemanticName
= semantic_name
;
490 decl
.Semantic
.SemanticIndex
= semantic_index
;
491 decl
.Interpolation
.Interpolate
= interpolate
;
496 static struct tgsi_full_declaration
497 make_frag_output_decl(
499 GLuint semantic_name
,
500 GLuint semantic_index
,
503 struct tgsi_full_declaration decl
;
505 decl
= tgsi_default_full_declaration();
506 decl
.Declaration
.File
= TGSI_FILE_OUTPUT
;
507 decl
.Declaration
.Declare
= TGSI_DECLARE_RANGE
;
508 decl
.Declaration
.UsageMask
= usage_mask
;
509 decl
.Declaration
.Semantic
= 1;
510 decl
.u
.DeclarationRange
.First
= index
;
511 decl
.u
.DeclarationRange
.Last
= index
;
512 decl
.Semantic
.SemanticName
= semantic_name
;
513 decl
.Semantic
.SemanticIndex
= semantic_index
;
520 * Convert Mesa fragment program to TGSI format.
521 * \param inputMapping maps Mesa fragment program inputs to TGSI generic
523 * \param inputSemantic the TGSI_SEMANTIC flag for each input
524 * \param interpMode the TGSI_INTERPOLATE_LINEAR/PERSP mode for each input
525 * \param outputMapping maps Mesa fragment program outputs to TGSI
530 tgsi_mesa_compile_fp_program(
531 const struct gl_fragment_program
*program
,
533 const GLuint inputMapping
[],
534 const ubyte inputSemanticName
[],
535 const ubyte inputSemanticIndex
[],
536 const GLuint interpMode
[],
537 const GLuint outputMapping
[],
538 struct tgsi_token
*tokens
,
542 GLuint ti
; /* token index */
543 struct tgsi_header
*header
;
544 struct tgsi_processor
*processor
;
545 struct tgsi_full_declaration fulldecl
;
546 struct tgsi_full_instruction fullinst
;
547 GLuint preamble_size
= 0;
549 *(struct tgsi_version
*) &tokens
[0] = tgsi_build_version();
551 header
= (struct tgsi_header
*) &tokens
[1];
552 *header
= tgsi_build_header();
554 processor
= (struct tgsi_processor
*) &tokens
[2];
555 *processor
= tgsi_build_processor( TGSI_PROCESSOR_FRAGMENT
, header
);
559 for (i
= 0; i
< numInputs
; i
++) {
560 switch (inputSemanticName
[i
]) {
561 case TGSI_SEMANTIC_POSITION
:
562 /* Fragment XY pos */
563 fulldecl
= make_input_decl(i
,
564 TGSI_INTERPOLATE_CONSTANT
,
566 TGSI_SEMANTIC_POSITION
, 0 );
567 ti
+= tgsi_build_full_declaration(
572 /* Fragment ZW pos */
573 fulldecl
= make_input_decl(i
,
574 TGSI_INTERPOLATE_LINEAR
,
576 TGSI_SEMANTIC_POSITION
, 0 );
577 ti
+= tgsi_build_full_declaration(
584 fulldecl
= make_input_decl(i
,
587 inputSemanticName
[i
],
588 inputSemanticIndex
[i
]);
589 ti
+= tgsi_build_full_declaration(&fulldecl
,
599 * Declare output attributes.
602 program
->Base
.OutputsWritten
==
603 (program
->Base
.OutputsWritten
& ((1 << FRAG_RESULT_COLR
) | (1 << FRAG_RESULT_DEPR
))) );
605 fulldecl
= make_frag_output_decl(
607 TGSI_SEMANTIC_POSITION
, 0, /* Z / Depth */
609 ti
+= tgsi_build_full_declaration(
615 if( program
->Base
.OutputsWritten
& (1 << FRAG_RESULT_COLR
) ) {
616 fulldecl
= make_frag_output_decl(
618 TGSI_SEMANTIC_COLOR
, 0,
619 TGSI_WRITEMASK_XYZW
);
620 ti
+= tgsi_build_full_declaration(
628 * Copy fragment z if the shader does not write it.
631 if( !(program
->Base
.OutputsWritten
& (1 << FRAG_RESULT_DEPR
)) ) {
632 fullinst
= tgsi_default_full_instruction();
634 fullinst
.Instruction
.Opcode
= TGSI_OPCODE_MOV
;
635 fullinst
.Instruction
.NumDstRegs
= 1;
636 fullinst
.Instruction
.NumSrcRegs
= 1;
638 fulldst
= &fullinst
.FullDstRegisters
[0];
639 fulldst
->DstRegister
.File
= TGSI_FILE_OUTPUT
;
640 fulldst
->DstRegister
.Index
= 0;
641 fulldst
->DstRegister
.WriteMask
= TGSI_WRITEMASK_Z
;
643 fullsrc
= &fullinst
.FullSrcRegisters
[0];
644 fullsrc
->SrcRegister
.File
= TGSI_FILE_INPUT
;
645 fullsrc
->SrcRegister
.Index
= 0;
647 ti
+= tgsi_build_full_instruction(
656 for( i
= 0; i
< program
->Base
.NumInstructions
; i
++ ) {
657 if( compile_instruction(
658 &program
->Base
.Instructions
[i
],
663 TGSI_PROCESSOR_FRAGMENT
) ) {
664 assert( i
== program
->Base
.NumInstructions
- 1 );
667 tgsi_dump( tokens
, 0 );
672 ti
+= tgsi_build_full_instruction(
683 tgsi_mesa_compile_vp_program(
684 const struct gl_vertex_program
*program
,
686 const GLuint inputMapping
[],
687 const ubyte inputSemanticName
[],
688 const ubyte inputSemanticIndex
[],
689 const GLuint outputMapping
[],
690 struct tgsi_token
*tokens
,
694 struct tgsi_header
*header
;
695 struct tgsi_processor
*processor
;
696 struct tgsi_full_instruction fullinst
;
698 *(struct tgsi_version
*) &tokens
[0] = tgsi_build_version();
700 header
= (struct tgsi_header
*) &tokens
[1];
701 *header
= tgsi_build_header();
703 processor
= (struct tgsi_processor
*) &tokens
[2];
704 *processor
= tgsi_build_processor( TGSI_PROCESSOR_VERTEX
, header
);
708 /* XXX todo: input/output declarations
710 for (i
= 0; i
< numInputs
; i
++) {
711 struct tgsi_full_declaration fulldecl
;
712 fulldecl
= make_input_decl(i
,
713 TGSI_INTERPOLATE_CONSTANT
, /* no interp */
715 inputSemanticName
[i
],
716 inputSemanticIndex
[i
]);
717 ti
+= tgsi_build_full_declaration(&fulldecl
,
724 for( i
= 0; i
< program
->Base
.NumInstructions
; i
++ ) {
725 if( compile_instruction(
726 &program
->Base
.Instructions
[i
],
731 TGSI_PROCESSOR_VERTEX
) ) {
732 assert( i
== program
->Base
.NumInstructions
- 1 );
735 tgsi_dump( tokens
, 0 );
740 ti
+= tgsi_build_full_instruction(