1 /**************************************************************************
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
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 TUNGSTEN GRAPHICS 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 **************************************************************************/
33 #include "pipe/p_compiler.h"
34 #include "pipe/p_shader_tokens.h"
35 #include "tgsi/util/tgsi_parse.h"
36 #include "tgsi/util/tgsi_build.h"
37 #include "tgsi/util/tgsi_util.h"
38 #include "st_mesa_to_tgsi.h"
39 #include "shader/prog_instruction.h"
40 #include "shader/prog_parameter.h"
46 * Map mesa register file to TGSI register file.
50 enum register_file file
,
52 const GLuint immediateMapping
[] )
55 case PROGRAM_UNDEFINED
:
56 return TGSI_FILE_NULL
;
57 case PROGRAM_TEMPORARY
:
58 return TGSI_FILE_TEMPORARY
;
59 //case PROGRAM_LOCAL_PARAM:
60 //case PROGRAM_ENV_PARAM:
62 /* Because of the longstanding problem with mesa arb shaders
63 * where constants, immediates and state variables are all
64 * bundled together as PROGRAM_STATE_VAR, we can't tell from the
65 * mesa register file whether this is a CONSTANT or an
66 * IMMEDIATE, hence we need all the other information.
68 case PROGRAM_STATE_VAR
:
69 case PROGRAM_NAMED_PARAM
:
71 if (immediateMapping
[index
] != ~0)
72 return TGSI_FILE_IMMEDIATE
;
74 return TGSI_FILE_CONSTANT
;
75 case PROGRAM_CONSTANT
:
76 return TGSI_FILE_IMMEDIATE
;
78 return TGSI_FILE_INPUT
;
80 return TGSI_FILE_OUTPUT
;
82 return TGSI_FILE_ADDRESS
;
85 return TGSI_FILE_NULL
;
90 * Map mesa register file index to TGSI index.
91 * Take special care when processing input and output indices.
92 * \param file one of TGSI_FILE_x
93 * \param index the mesa register file index
94 * \param inputMapping maps Mesa input indexes to TGSI input indexes
95 * \param outputMapping maps Mesa output indexes to TGSI output indexes
98 map_register_file_index(
101 const GLuint inputMapping
[],
102 const GLuint outputMapping
[],
103 const GLuint immediateMapping
[])
106 case TGSI_FILE_INPUT
:
107 /* inputs are mapped according to the user-defined map */
108 return inputMapping
[index
];
110 case TGSI_FILE_OUTPUT
:
111 return outputMapping
[index
];
113 case TGSI_FILE_IMMEDIATE
:
114 return immediateMapping
[index
];
122 * Map mesa texture target to TGSI texture target.
128 switch( textarget
) {
129 case TEXTURE_1D_INDEX
:
130 return TGSI_TEXTURE_1D
;
131 case TEXTURE_2D_INDEX
:
132 return TGSI_TEXTURE_2D
;
133 case TEXTURE_3D_INDEX
:
134 return TGSI_TEXTURE_3D
;
135 case TEXTURE_CUBE_INDEX
:
136 return TGSI_TEXTURE_CUBE
;
137 case TEXTURE_RECT_INDEX
:
138 return TGSI_TEXTURE_RECT
;
143 return TGSI_TEXTURE_1D
;
152 return TGSI_SAT_NONE
;
153 case SATURATE_ZERO_ONE
:
154 return TGSI_SAT_ZERO_ONE
;
155 case SATURATE_PLUS_MINUS_ONE
:
156 return TGSI_SAT_MINUS_PLUS_ONE
;
159 return TGSI_SAT_NONE
;
167 assert( WRITEMASK_X
== TGSI_WRITEMASK_X
);
168 assert( WRITEMASK_Y
== TGSI_WRITEMASK_Y
);
169 assert( WRITEMASK_Z
== TGSI_WRITEMASK_Z
);
170 assert( WRITEMASK_W
== TGSI_WRITEMASK_W
);
171 assert( (writemask
& ~TGSI_WRITEMASK_XYZW
) == 0 );
176 static struct tgsi_full_immediate
177 make_immediate(const float *value
, uint size
)
179 struct tgsi_full_immediate imm
;
180 imm
.Immediate
.Type
= TGSI_TOKEN_TYPE_IMMEDIATE
;
181 imm
.Immediate
.Size
= 1 + size
; /* one for the token itself */
182 imm
.Immediate
.DataType
= TGSI_IMM_FLOAT32
;
183 imm
.u
.ImmediateFloat32
= (struct tgsi_immediate_float32
*) value
;
189 const struct prog_instruction
*inst
,
190 struct tgsi_full_instruction
*fullinst
,
191 const GLuint inputMapping
[],
192 const GLuint outputMapping
[],
193 const GLuint immediateMapping
[],
194 GLuint preamble_size
,
196 GLboolean
*insideSubroutine
)
199 struct tgsi_full_dst_register
*fulldst
;
200 struct tgsi_full_src_register
*fullsrc
;
202 *fullinst
= tgsi_default_full_instruction();
204 fullinst
->Instruction
.Saturate
= convert_sat( inst
->SaturateMode
);
205 fullinst
->Instruction
.NumDstRegs
= _mesa_num_inst_dst_regs( inst
->Opcode
);
206 fullinst
->Instruction
.NumSrcRegs
= _mesa_num_inst_src_regs( inst
->Opcode
);
208 fulldst
= &fullinst
->FullDstRegisters
[0];
209 fulldst
->DstRegister
.File
= map_register_file( inst
->DstReg
.File
, 0, NULL
);
210 fulldst
->DstRegister
.Index
= map_register_file_index(
211 fulldst
->DstRegister
.File
,
217 fulldst
->DstRegister
.WriteMask
= convert_writemask( inst
->DstReg
.WriteMask
);
219 for( i
= 0; i
< fullinst
->Instruction
.NumSrcRegs
; i
++ ) {
222 fullsrc
= &fullinst
->FullSrcRegisters
[i
];
223 fullsrc
->SrcRegister
.File
= map_register_file( inst
->SrcReg
[i
].File
,
224 inst
->SrcReg
[i
].Index
,
226 fullsrc
->SrcRegister
.Index
= map_register_file_index(
227 fullsrc
->SrcRegister
.File
,
228 inst
->SrcReg
[i
].Index
,
233 for( j
= 0; j
< 4; j
++ ) {
236 swz
= GET_SWZ( inst
->SrcReg
[i
].Swizzle
, j
);
237 if( swz
> SWIZZLE_W
) {
238 tgsi_util_set_src_register_extswizzle(
239 &fullsrc
->SrcRegisterExtSwz
,
244 tgsi_util_set_src_register_swizzle(
245 &fullsrc
->SrcRegister
,
251 if( inst
->SrcReg
[i
].NegateBase
== NEGATE_XYZW
) {
252 fullsrc
->SrcRegister
.Negate
= 1;
254 else if( inst
->SrcReg
[i
].NegateBase
!= NEGATE_NONE
) {
255 if( inst
->SrcReg
[i
].NegateBase
& NEGATE_X
) {
256 fullsrc
->SrcRegisterExtSwz
.NegateX
= 1;
258 if( inst
->SrcReg
[i
].NegateBase
& NEGATE_Y
) {
259 fullsrc
->SrcRegisterExtSwz
.NegateY
= 1;
261 if( inst
->SrcReg
[i
].NegateBase
& NEGATE_Z
) {
262 fullsrc
->SrcRegisterExtSwz
.NegateZ
= 1;
264 if( inst
->SrcReg
[i
].NegateBase
& NEGATE_W
) {
265 fullsrc
->SrcRegisterExtSwz
.NegateW
= 1;
269 if( inst
->SrcReg
[i
].Abs
) {
270 fullsrc
->SrcRegisterExtMod
.Absolute
= 1;
273 if( inst
->SrcReg
[i
].NegateAbs
) {
274 fullsrc
->SrcRegisterExtMod
.Negate
= 1;
277 if( inst
->SrcReg
[i
].RelAddr
) {
278 fullsrc
->SrcRegister
.Indirect
= 1;
280 fullsrc
->SrcRegisterInd
.File
= TGSI_FILE_ADDRESS
;
281 fullsrc
->SrcRegisterInd
.Index
= 0;
285 switch( inst
->Opcode
) {
287 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_ARL
;
290 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_ABS
;
293 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_ADD
;
296 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_BGNLOOP2
;
297 fullinst
->InstructionExtLabel
.Label
= inst
->BranchTarget
+ preamble_size
;
300 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_BGNSUB
;
301 *insideSubroutine
= GL_TRUE
;
304 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_BRA
;
307 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_BRK
;
310 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_CAL
;
311 fullinst
->InstructionExtLabel
.Label
= inst
->BranchTarget
+ preamble_size
;
314 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_CMP
;
317 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_CONT
;
320 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_COS
;
323 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_DDX
;
326 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_DDY
;
329 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_DP3
;
332 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_DP4
;
335 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_DPH
;
338 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_DST
;
341 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_ELSE
;
342 fullinst
->InstructionExtLabel
.Label
= inst
->BranchTarget
+ preamble_size
;
345 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_ENDIF
;
348 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_ENDLOOP2
;
349 fullinst
->InstructionExtLabel
.Label
= inst
->BranchTarget
+ preamble_size
;
352 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_ENDSUB
;
353 *insideSubroutine
= GL_FALSE
;
356 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_EX2
;
359 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_EXP
;
362 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_FLR
;
365 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_FRC
;
368 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_IF
;
369 fullinst
->InstructionExtLabel
.Label
= inst
->BranchTarget
+ preamble_size
;
372 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_INT
;
375 /* predicated w/ a register */
376 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_KILP
;
380 assert(inst
->DstReg
.CondMask
== COND_TR
);
381 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_KIL
;
384 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_LG2
;
387 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_LOG
;
390 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_LIT
;
393 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_LRP
;
396 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_MAD
;
399 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_MAX
;
402 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_MIN
;
405 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_MOV
;
408 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_MUL
;
411 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_NOISE1
;
414 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_NOISE2
;
417 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_NOISE3
;
420 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_NOISE4
;
423 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_NOP
;
426 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_POW
;
429 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_RCP
;
432 /* If RET is used inside main (not a real subroutine) we may want
433 * to execute END instead of RET. TBD...
435 if (1 /* *insideSubroutine */) {
436 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_RET
;
439 /* inside main() pseudo-function */
440 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_END
;
444 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_RSQ
;
445 tgsi_util_set_full_src_register_sign_mode(
446 &fullinst
->FullSrcRegisters
[0],
447 TGSI_UTIL_SIGN_CLEAR
);
450 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_SCS
;
451 fulldst
->DstRegister
.WriteMask
&= TGSI_WRITEMASK_XY
;
454 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_SEQ
;
457 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_SGE
;
460 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_SGT
;
463 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_SIN
;
466 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_SLE
;
469 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_SLT
;
472 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_SNE
;
475 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_SUB
;
478 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_SWZ
;
481 /* ordinary texture lookup */
482 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_TEX
;
483 fullinst
->Instruction
.NumSrcRegs
= 2;
484 fullinst
->InstructionExtTexture
.Texture
= map_texture_target( inst
->TexSrcTarget
);
485 fullinst
->FullSrcRegisters
[1].SrcRegister
.File
= TGSI_FILE_SAMPLER
;
486 fullinst
->FullSrcRegisters
[1].SrcRegister
.Index
= inst
->TexSrcUnit
;
489 /* texture lookup with LOD bias */
490 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_TXB
;
491 fullinst
->Instruction
.NumSrcRegs
= 2;
492 fullinst
->InstructionExtTexture
.Texture
= map_texture_target( inst
->TexSrcTarget
);
493 fullinst
->FullSrcRegisters
[1].SrcRegister
.File
= TGSI_FILE_SAMPLER
;
494 fullinst
->FullSrcRegisters
[1].SrcRegister
.Index
= inst
->TexSrcUnit
;
497 /* texture lookup with explicit partial derivatives */
498 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_TXD
;
499 fullinst
->Instruction
.NumSrcRegs
= 4;
500 fullinst
->InstructionExtTexture
.Texture
= map_texture_target( inst
->TexSrcTarget
);
501 /* src[0] = coord, src[1] = d[strq]/dx, src[2] = d[strq]/dy */
502 fullinst
->FullSrcRegisters
[3].SrcRegister
.File
= TGSI_FILE_SAMPLER
;
503 fullinst
->FullSrcRegisters
[3].SrcRegister
.Index
= inst
->TexSrcUnit
;
506 /* texture lookup with explicit LOD */
507 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_TXL
;
508 fullinst
->Instruction
.NumSrcRegs
= 2;
509 fullinst
->InstructionExtTexture
.Texture
= map_texture_target( inst
->TexSrcTarget
);
510 fullinst
->FullSrcRegisters
[1].SrcRegister
.File
= TGSI_FILE_SAMPLER
;
511 fullinst
->FullSrcRegisters
[1].SrcRegister
.Index
= inst
->TexSrcUnit
;
514 /* texture lookup with divide by Q component */
515 /* convert to TEX w/ special flag for division */
516 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_TXP
;
517 fullinst
->Instruction
.NumSrcRegs
= 2;
518 fullinst
->InstructionExtTexture
.Texture
= map_texture_target( inst
->TexSrcTarget
);
519 fullinst
->FullSrcRegisters
[1].SrcRegister
.File
= TGSI_FILE_SAMPLER
;
520 fullinst
->FullSrcRegisters
[1].SrcRegister
.Index
= inst
->TexSrcUnit
;
523 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_XPD
;
524 fulldst
->DstRegister
.WriteMask
&= TGSI_WRITEMASK_XYZ
;
527 fullinst
->Instruction
.Opcode
= TGSI_OPCODE_END
;
535 * \param usage_mask bitfield of TGSI_WRITEMASK_{XYZW} tokens
537 static struct tgsi_full_declaration
540 GLboolean interpolate_info
,
543 GLboolean semantic_info
,
544 GLuint semantic_name
,
545 GLbitfield semantic_index
)
547 struct tgsi_full_declaration decl
;
549 assert(semantic_name
< TGSI_SEMANTIC_COUNT
);
551 decl
= tgsi_default_full_declaration();
552 decl
.Declaration
.File
= TGSI_FILE_INPUT
;
553 decl
.Declaration
.Declare
= TGSI_DECLARE_RANGE
;
554 decl
.Declaration
.UsageMask
= usage_mask
;
555 decl
.Declaration
.Semantic
= semantic_info
;
556 decl
.u
.DeclarationRange
.First
= index
;
557 decl
.u
.DeclarationRange
.Last
= index
;
559 decl
.Semantic
.SemanticName
= semantic_name
;
560 decl
.Semantic
.SemanticIndex
= semantic_index
;
562 if (interpolate_info
) {
563 decl
.Declaration
.Interpolate
= 1;
564 decl
.Interpolation
.Interpolate
= interpolate
;
571 * \param usage_mask bitfield of TGSI_WRITEMASK_{XYZW} tokens
573 static struct tgsi_full_declaration
576 GLuint semantic_name
,
577 GLuint semantic_index
,
578 GLbitfield usage_mask
)
580 struct tgsi_full_declaration decl
;
582 assert(semantic_name
< TGSI_SEMANTIC_COUNT
);
584 decl
= tgsi_default_full_declaration();
585 decl
.Declaration
.File
= TGSI_FILE_OUTPUT
;
586 decl
.Declaration
.Declare
= TGSI_DECLARE_RANGE
;
587 decl
.Declaration
.UsageMask
= usage_mask
;
588 decl
.Declaration
.Semantic
= 1;
589 decl
.u
.DeclarationRange
.First
= index
;
590 decl
.u
.DeclarationRange
.Last
= index
;
591 decl
.Semantic
.SemanticName
= semantic_name
;
592 decl
.Semantic
.SemanticIndex
= semantic_index
;
598 static struct tgsi_full_declaration
603 struct tgsi_full_declaration decl
;
604 decl
= tgsi_default_full_declaration();
605 decl
.Declaration
.File
= TGSI_FILE_TEMPORARY
;
606 decl
.Declaration
.Declare
= TGSI_DECLARE_RANGE
;
607 decl
.u
.DeclarationRange
.First
= start_index
;
608 decl
.u
.DeclarationRange
.Last
= end_index
;
613 static struct tgsi_full_declaration
614 make_sampler_decl(GLuint index
)
616 struct tgsi_full_declaration decl
;
617 decl
= tgsi_default_full_declaration();
618 decl
.Declaration
.File
= TGSI_FILE_SAMPLER
;
619 decl
.Declaration
.Declare
= TGSI_DECLARE_RANGE
;
620 decl
.u
.DeclarationRange
.First
= index
;
621 decl
.u
.DeclarationRange
.Last
= index
;
625 /** Reference into a constant buffer */
626 static struct tgsi_full_declaration
627 make_constant_decl(GLuint first
, GLuint last
)
629 struct tgsi_full_declaration decl
;
630 decl
= tgsi_default_full_declaration();
631 decl
.Declaration
.File
= TGSI_FILE_CONSTANT
;
632 decl
.Declaration
.Declare
= TGSI_DECLARE_RANGE
;
633 decl
.u
.DeclarationRange
.First
= first
;
634 decl
.u
.DeclarationRange
.Last
= last
;
641 * Find the temporaries which are used in the given program.
644 find_temporaries(const struct gl_program
*program
,
645 GLboolean tempsUsed
[MAX_PROGRAM_TEMPS
])
649 for (i
= 0; i
< MAX_PROGRAM_TEMPS
; i
++)
650 tempsUsed
[i
] = GL_FALSE
;
652 for (i
= 0; i
< program
->NumInstructions
; i
++) {
653 const struct prog_instruction
*inst
= program
->Instructions
+ i
;
654 const GLuint n
= _mesa_num_inst_src_regs( inst
->Opcode
);
655 for (j
= 0; j
< n
; j
++) {
656 if (inst
->SrcReg
[j
].File
== PROGRAM_TEMPORARY
)
657 tempsUsed
[inst
->SrcReg
[j
].Index
] = GL_TRUE
;
658 if (inst
->DstReg
.File
== PROGRAM_TEMPORARY
)
659 tempsUsed
[inst
->DstReg
.Index
] = GL_TRUE
;
668 * Translate Mesa program to TGSI format.
669 * \param program the program to translate
670 * \param numInputs number of input registers used
671 * \param inputMapping maps Mesa fragment program inputs to TGSI generic
673 * \param inputSemanticName the TGSI_SEMANTIC flag for each input
674 * \param inputSemanticIndex the semantic index (ex: which texcoord) for each input
675 * \param interpMode the TGSI_INTERPOLATE_LINEAR/PERSP mode for each input
677 * \param numOutputs number of output registers used
678 * \param outputMapping maps Mesa fragment program outputs to TGSI
680 * \param outputSemanticName the TGSI_SEMANTIC flag for each output
681 * \param outputSemanticIndex the semantic index (ex: which texcoord) for each output
682 * \param tokens array to store translated tokens in
683 * \param maxTokens size of the tokens array
685 * \return number of tokens placed in 'tokens' buffer, or zero if error
688 tgsi_translate_mesa_program(
690 const struct gl_program
*program
,
692 const GLuint inputMapping
[],
693 const ubyte inputSemanticName
[],
694 const ubyte inputSemanticIndex
[],
695 const GLuint interpMode
[],
697 const GLuint outputMapping
[],
698 const ubyte outputSemanticName
[],
699 const ubyte outputSemanticIndex
[],
700 struct tgsi_token
*tokens
,
704 GLuint ti
; /* token index */
705 struct tgsi_header
*header
;
706 struct tgsi_processor
*processor
;
707 struct tgsi_full_instruction fullinst
;
708 GLuint preamble_size
= 0;
709 GLuint immediates
[1000];
710 GLuint numImmediates
= 0;
711 GLboolean insideSubroutine
= GL_FALSE
;
713 assert(procType
== TGSI_PROCESSOR_FRAGMENT
||
714 procType
== TGSI_PROCESSOR_VERTEX
);
716 *(struct tgsi_version
*) &tokens
[0] = tgsi_build_version();
718 header
= (struct tgsi_header
*) &tokens
[1];
719 *header
= tgsi_build_header();
721 processor
= (struct tgsi_processor
*) &tokens
[2];
722 *processor
= tgsi_build_processor( procType
, header
);
727 * Declare input attributes.
729 if (procType
== TGSI_PROCESSOR_FRAGMENT
) {
730 for (i
= 0; i
< numInputs
; i
++) {
731 struct tgsi_full_declaration fulldecl
;
732 fulldecl
= make_input_decl(i
,
733 GL_TRUE
, interpMode
[i
],
735 GL_TRUE
, inputSemanticName
[i
],
736 inputSemanticIndex
[i
]);
737 ti
+= tgsi_build_full_declaration(&fulldecl
,
745 /* XXX: this could probaby be merged with the clause above.
746 * the only difference is the semantic tags.
748 for (i
= 0; i
< numInputs
; i
++) {
749 struct tgsi_full_declaration fulldecl
;
750 fulldecl
= make_input_decl(i
,
754 ti
+= tgsi_build_full_declaration(&fulldecl
,
762 * Declare output attributes.
764 if (procType
== TGSI_PROCESSOR_FRAGMENT
) {
765 for (i
= 0; i
< numOutputs
; i
++) {
766 struct tgsi_full_declaration fulldecl
;
767 switch (outputSemanticName
[i
]) {
768 case TGSI_SEMANTIC_POSITION
:
769 fulldecl
= make_output_decl(i
,
770 TGSI_SEMANTIC_POSITION
, 0, /* Z / Depth */
773 case TGSI_SEMANTIC_COLOR
:
774 fulldecl
= make_output_decl(i
,
775 TGSI_SEMANTIC_COLOR
, 0,
776 TGSI_WRITEMASK_XYZW
);
781 ti
+= tgsi_build_full_declaration(&fulldecl
,
789 for (i
= 0; i
< numOutputs
; i
++) {
790 struct tgsi_full_declaration fulldecl
;
791 fulldecl
= make_output_decl(i
,
792 outputSemanticName
[i
],
793 outputSemanticIndex
[i
],
794 TGSI_WRITEMASK_XYZW
);
795 ti
+= tgsi_build_full_declaration(&fulldecl
,
802 /* temporary decls */
804 GLboolean tempsUsed
[MAX_PROGRAM_TEMPS
+ 1];
805 GLboolean inside_range
= GL_FALSE
;
808 find_temporaries(program
, tempsUsed
);
809 tempsUsed
[MAX_PROGRAM_TEMPS
] = GL_FALSE
;
810 for (i
= 0; i
< MAX_PROGRAM_TEMPS
+ 1; i
++) {
811 if (tempsUsed
[i
] && !inside_range
) {
812 inside_range
= GL_TRUE
;
815 else if (!tempsUsed
[i
] && inside_range
) {
816 struct tgsi_full_declaration fulldecl
;
818 inside_range
= GL_FALSE
;
819 fulldecl
= make_temp_decl( start_range
, i
- 1 );
820 ti
+= tgsi_build_full_declaration(
829 /* immediates/literals */
830 memset(immediates
, ~0, sizeof(immediates
));
832 for (i
= 0; program
->Parameters
&& i
< program
->Parameters
->NumParameters
;
834 if (program
->Parameters
->Parameters
[i
].Type
== PROGRAM_CONSTANT
) {
835 struct tgsi_full_immediate fullimm
836 = make_immediate(program
->Parameters
->ParameterValues
[i
],
837 program
->Parameters
->Parameters
[i
].Size
);
838 ti
+= tgsi_build_full_immediate(&fullimm
,
842 immediates
[i
] = numImmediates
;
847 /* constant buffer refs */
849 GLint start
= -1, end
= -1;
852 program
->Parameters
&& i
< program
->Parameters
->NumParameters
;
854 GLboolean emit
= (i
== program
->Parameters
->NumParameters
- 1);
856 switch (program
->Parameters
->Parameters
[i
].Type
) {
857 case PROGRAM_ENV_PARAM
:
858 case PROGRAM_STATE_VAR
:
859 case PROGRAM_NAMED_PARAM
:
860 case PROGRAM_UNIFORM
:
862 /* begin a sequence */
867 /* continue sequence */
873 /* end of sequence */
878 if (emit
&& start
>= 0) {
879 struct tgsi_full_declaration fulldecl
;
880 fulldecl
= make_constant_decl( start
, end
);
881 ti
+= tgsi_build_full_declaration(&fulldecl
,
890 /* texture samplers */
891 for (i
= 0; i
< 8; i
++) {
892 if (program
->SamplersUsed
& (1 << i
)) {
893 struct tgsi_full_declaration fulldecl
;
894 fulldecl
= make_sampler_decl( i
);
895 ti
+= tgsi_build_full_declaration(&fulldecl
,
903 for( i
= 0; i
< program
->NumInstructions
; i
++ ) {
905 &program
->Instructions
[i
],
914 ti
+= tgsi_build_full_instruction(