bc57868af28b87b7573b43b86f65f4d72f933930
[mesa.git] / src / mesa / state_tracker / st_mesa_to_tgsi.c
1 /**************************************************************************
2 *
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
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 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.
25 *
26 **************************************************************************/
27
28 /*
29 * \author
30 * Michal Krol
31 */
32
33
34 #include "tgsi_platform.h"
35 #include "pipe/tgsi/exec/tgsi_core.h"
36 #include "st_mesa_to_tgsi.h"
37 #include "shader/prog_instruction.h"
38 #include "shader/prog_parameter.h"
39
40 #define TGSI_DEBUG 0
41
42
43 /*
44 * Map mesa register file to TGSI register file.
45 */
46 static GLuint
47 map_register_file(
48 enum register_file file )
49 {
50 switch( file ) {
51 case PROGRAM_UNDEFINED:
52 return TGSI_FILE_NULL;
53 case PROGRAM_TEMPORARY:
54 return TGSI_FILE_TEMPORARY;
55 //case PROGRAM_LOCAL_PARAM:
56 //case PROGRAM_ENV_PARAM:
57 case PROGRAM_STATE_VAR:
58 case PROGRAM_NAMED_PARAM:
59 case PROGRAM_UNIFORM:
60 return TGSI_FILE_CONSTANT;
61 case PROGRAM_CONSTANT:
62 return TGSI_FILE_IMMEDIATE;
63 case PROGRAM_INPUT:
64 return TGSI_FILE_INPUT;
65 case PROGRAM_OUTPUT:
66 return TGSI_FILE_OUTPUT;
67 case PROGRAM_ADDRESS:
68 return TGSI_FILE_ADDRESS;
69 default:
70 assert( 0 );
71 return TGSI_FILE_NULL;
72 }
73 }
74
75 /**
76 * Map mesa register file index to TGSI index.
77 * Take special care when processing input and output indices.
78 * \param file one of TGSI_FILE_x
79 * \param index the mesa register file index
80 * \param inputMapping maps Mesa input indexes to TGSI input indexes
81 * \param outputMapping maps Mesa output indexes to TGSI output indexes
82 */
83 static GLuint
84 map_register_file_index(
85 GLuint file,
86 GLuint index,
87 const GLuint inputMapping[],
88 const GLuint outputMapping[],
89 const GLuint immediateMapping[])
90 {
91 switch( file ) {
92 case TGSI_FILE_INPUT:
93 /* inputs are mapped according to the user-defined map */
94 return inputMapping[index];
95
96 case TGSI_FILE_OUTPUT:
97 return outputMapping[index];
98
99 case TGSI_FILE_IMMEDIATE:
100 return immediateMapping[index];
101
102 default:
103 return index;
104 }
105 }
106
107 /*
108 * Map mesa texture target to TGSI texture target.
109 */
110 static GLuint
111 map_texture_target(
112 GLuint textarget )
113 {
114 switch( textarget ) {
115 case TEXTURE_1D_INDEX:
116 return TGSI_TEXTURE_1D;
117 case TEXTURE_2D_INDEX:
118 return TGSI_TEXTURE_2D;
119 case TEXTURE_3D_INDEX:
120 return TGSI_TEXTURE_3D;
121 case TEXTURE_CUBE_INDEX:
122 return TGSI_TEXTURE_CUBE;
123 case TEXTURE_RECT_INDEX:
124 return TGSI_TEXTURE_RECT;
125 default:
126 assert( 0 );
127 }
128
129 return TGSI_TEXTURE_1D;
130 }
131
132 static GLuint
133 convert_sat(
134 GLuint sat )
135 {
136 switch( sat ) {
137 case SATURATE_OFF:
138 return TGSI_SAT_NONE;
139 case SATURATE_ZERO_ONE:
140 return TGSI_SAT_ZERO_ONE;
141 case SATURATE_PLUS_MINUS_ONE:
142 return TGSI_SAT_MINUS_PLUS_ONE;
143 default:
144 assert( 0 );
145 return TGSI_SAT_NONE;
146 }
147 }
148
149 static GLuint
150 convert_writemask(
151 GLuint writemask )
152 {
153 assert( WRITEMASK_X == TGSI_WRITEMASK_X );
154 assert( WRITEMASK_Y == TGSI_WRITEMASK_Y );
155 assert( WRITEMASK_Z == TGSI_WRITEMASK_Z );
156 assert( WRITEMASK_W == TGSI_WRITEMASK_W );
157 assert( (writemask & ~TGSI_WRITEMASK_XYZW) == 0 );
158
159 return writemask;
160 }
161
162 static struct tgsi_full_immediate
163 make_immediate(const float *value, uint size)
164 {
165 struct tgsi_full_immediate imm;
166 imm.Immediate.Type = TGSI_TOKEN_TYPE_IMMEDIATE;
167 imm.Immediate.Size = 1 + size; /* one for the token itself */
168 imm.Immediate.DataType = TGSI_IMM_FLOAT32;
169 imm.u.ImmediateFloat32 = (struct tgsi_immediate_float32 *) value;
170 return imm;
171 }
172
173 static void
174 compile_instruction(
175 const struct prog_instruction *inst,
176 struct tgsi_full_instruction *fullinst,
177 const GLuint inputMapping[],
178 const GLuint outputMapping[],
179 const GLuint immediateMapping[],
180 GLuint preamble_size,
181 GLuint processor )
182 {
183 GLuint i;
184 struct tgsi_full_dst_register *fulldst;
185 struct tgsi_full_src_register *fullsrc;
186
187 *fullinst = tgsi_default_full_instruction();
188
189 fullinst->Instruction.Saturate = convert_sat( inst->SaturateMode );
190 fullinst->Instruction.NumDstRegs = _mesa_num_inst_dst_regs( inst->Opcode );
191 fullinst->Instruction.NumSrcRegs = _mesa_num_inst_src_regs( inst->Opcode );
192
193 fulldst = &fullinst->FullDstRegisters[0];
194 fulldst->DstRegister.File = map_register_file( inst->DstReg.File );
195 fulldst->DstRegister.Index = map_register_file_index(
196 fulldst->DstRegister.File,
197 inst->DstReg.Index,
198 inputMapping,
199 outputMapping,
200 NULL
201 );
202 fulldst->DstRegister.WriteMask = convert_writemask( inst->DstReg.WriteMask );
203
204 for( i = 0; i < fullinst->Instruction.NumSrcRegs; i++ ) {
205 GLuint j;
206
207 fullsrc = &fullinst->FullSrcRegisters[i];
208 fullsrc->SrcRegister.File = map_register_file( inst->SrcReg[i].File );
209 fullsrc->SrcRegister.Index = map_register_file_index(
210 fullsrc->SrcRegister.File,
211 inst->SrcReg[i].Index,
212 inputMapping,
213 outputMapping,
214 immediateMapping);
215
216 for( j = 0; j < 4; j++ ) {
217 GLuint swz;
218
219 swz = GET_SWZ( inst->SrcReg[i].Swizzle, j );
220 if( swz > SWIZZLE_W ) {
221 tgsi_util_set_src_register_extswizzle(
222 &fullsrc->SrcRegisterExtSwz,
223 swz,
224 j );
225 }
226 else {
227 tgsi_util_set_src_register_swizzle(
228 &fullsrc->SrcRegister,
229 swz,
230 j );
231 }
232 }
233
234 if( inst->SrcReg[i].NegateBase == NEGATE_XYZW ) {
235 fullsrc->SrcRegister.Negate = 1;
236 }
237 else if( inst->SrcReg[i].NegateBase != NEGATE_NONE ) {
238 if( inst->SrcReg[i].NegateBase & NEGATE_X ) {
239 fullsrc->SrcRegisterExtSwz.NegateX = 1;
240 }
241 if( inst->SrcReg[i].NegateBase & NEGATE_Y ) {
242 fullsrc->SrcRegisterExtSwz.NegateY = 1;
243 }
244 if( inst->SrcReg[i].NegateBase & NEGATE_Z ) {
245 fullsrc->SrcRegisterExtSwz.NegateZ = 1;
246 }
247 if( inst->SrcReg[i].NegateBase & NEGATE_W ) {
248 fullsrc->SrcRegisterExtSwz.NegateW = 1;
249 }
250 }
251
252 if( inst->SrcReg[i].Abs ) {
253 fullsrc->SrcRegisterExtMod.Absolute = 1;
254 }
255
256 if( inst->SrcReg[i].NegateAbs ) {
257 fullsrc->SrcRegisterExtMod.Negate = 1;
258 }
259
260 if( inst->SrcReg[i].RelAddr ) {
261 fullsrc->SrcRegister.Indirect = 1;
262
263 fullsrc->SrcRegisterInd.File = TGSI_FILE_ADDRESS;
264 fullsrc->SrcRegisterInd.Index = 0;
265 }
266 }
267
268 switch( inst->Opcode ) {
269 case OPCODE_ARL:
270 fullinst->Instruction.Opcode = TGSI_OPCODE_ARL;
271 break;
272 case OPCODE_ABS:
273 fullinst->Instruction.Opcode = TGSI_OPCODE_ABS;
274 break;
275 case OPCODE_ADD:
276 fullinst->Instruction.Opcode = TGSI_OPCODE_ADD;
277 break;
278 case OPCODE_BGNLOOP:
279 fullinst->Instruction.Opcode = TGSI_OPCODE_BGNLOOP2;
280 fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;
281 break;
282 case OPCODE_BGNSUB:
283 fullinst->Instruction.Opcode = TGSI_OPCODE_BGNSUB;
284 break;
285 case OPCODE_BRA:
286 fullinst->Instruction.Opcode = TGSI_OPCODE_BRA;
287 break;
288 case OPCODE_BRK:
289 fullinst->Instruction.Opcode = TGSI_OPCODE_BRK;
290 break;
291 case OPCODE_CAL:
292 fullinst->Instruction.Opcode = TGSI_OPCODE_CAL;
293 fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;
294 break;
295 case OPCODE_CMP:
296 fullinst->Instruction.Opcode = TGSI_OPCODE_CMP;
297 break;
298 case OPCODE_CONT:
299 fullinst->Instruction.Opcode = TGSI_OPCODE_CONT;
300 break;
301 case OPCODE_COS:
302 fullinst->Instruction.Opcode = TGSI_OPCODE_COS;
303 break;
304 case OPCODE_DDX:
305 fullinst->Instruction.Opcode = TGSI_OPCODE_DDX;
306 break;
307 case OPCODE_DDY:
308 fullinst->Instruction.Opcode = TGSI_OPCODE_DDY;
309 break;
310 case OPCODE_DP3:
311 fullinst->Instruction.Opcode = TGSI_OPCODE_DP3;
312 break;
313 case OPCODE_DP4:
314 fullinst->Instruction.Opcode = TGSI_OPCODE_DP4;
315 break;
316 case OPCODE_DPH:
317 fullinst->Instruction.Opcode = TGSI_OPCODE_DPH;
318 break;
319 case OPCODE_DST:
320 fullinst->Instruction.Opcode = TGSI_OPCODE_DST;
321 break;
322 case OPCODE_ELSE:
323 fullinst->Instruction.Opcode = TGSI_OPCODE_ELSE;
324 fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;
325 break;
326 case OPCODE_ENDIF:
327 fullinst->Instruction.Opcode = TGSI_OPCODE_ENDIF;
328 break;
329 case OPCODE_ENDLOOP:
330 fullinst->Instruction.Opcode = TGSI_OPCODE_ENDLOOP2;
331 fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;
332 break;
333 case OPCODE_ENDSUB:
334 fullinst->Instruction.Opcode = TGSI_OPCODE_ENDSUB;
335 break;
336 case OPCODE_EX2:
337 fullinst->Instruction.Opcode = TGSI_OPCODE_EX2;
338 break;
339 case OPCODE_EXP:
340 fullinst->Instruction.Opcode = TGSI_OPCODE_EXP;
341 break;
342 case OPCODE_FLR:
343 fullinst->Instruction.Opcode = TGSI_OPCODE_FLR;
344 break;
345 case OPCODE_FRC:
346 fullinst->Instruction.Opcode = TGSI_OPCODE_FRC;
347 break;
348 case OPCODE_IF:
349 fullinst->Instruction.Opcode = TGSI_OPCODE_IF;
350 fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;
351 break;
352 case OPCODE_INT:
353 fullinst->Instruction.Opcode = TGSI_OPCODE_INT;
354 break;
355 case OPCODE_KIL:
356 /* predicated w/ a register */
357 fullinst->Instruction.Opcode = TGSI_OPCODE_KILP;
358 break;
359 case OPCODE_KIL_NV:
360 /* unpredicated */
361 assert(inst->DstReg.CondMask == COND_TR);
362 fullinst->Instruction.Opcode = TGSI_OPCODE_KIL;
363 break;
364 case OPCODE_LG2:
365 fullinst->Instruction.Opcode = TGSI_OPCODE_LG2;
366 break;
367 case OPCODE_LOG:
368 fullinst->Instruction.Opcode = TGSI_OPCODE_LOG;
369 break;
370 case OPCODE_LIT:
371 fullinst->Instruction.Opcode = TGSI_OPCODE_LIT;
372 break;
373 case OPCODE_LRP:
374 fullinst->Instruction.Opcode = TGSI_OPCODE_LRP;
375 break;
376 case OPCODE_MAD:
377 fullinst->Instruction.Opcode = TGSI_OPCODE_MAD;
378 break;
379 case OPCODE_MAX:
380 fullinst->Instruction.Opcode = TGSI_OPCODE_MAX;
381 break;
382 case OPCODE_MIN:
383 fullinst->Instruction.Opcode = TGSI_OPCODE_MIN;
384 break;
385 case OPCODE_MOV:
386 fullinst->Instruction.Opcode = TGSI_OPCODE_MOV;
387 break;
388 case OPCODE_MUL:
389 fullinst->Instruction.Opcode = TGSI_OPCODE_MUL;
390 break;
391 case OPCODE_NOISE1:
392 fullinst->Instruction.Opcode = TGSI_OPCODE_NOISE1;
393 break;
394 case OPCODE_NOISE2:
395 fullinst->Instruction.Opcode = TGSI_OPCODE_NOISE2;
396 break;
397 case OPCODE_NOISE3:
398 fullinst->Instruction.Opcode = TGSI_OPCODE_NOISE3;
399 break;
400 case OPCODE_NOISE4:
401 fullinst->Instruction.Opcode = TGSI_OPCODE_NOISE4;
402 break;
403 case OPCODE_NOP:
404 fullinst->Instruction.Opcode = TGSI_OPCODE_NOP;
405 break;
406 case OPCODE_POW:
407 fullinst->Instruction.Opcode = TGSI_OPCODE_POW;
408 break;
409 case OPCODE_RCP:
410 fullinst->Instruction.Opcode = TGSI_OPCODE_RCP;
411 break;
412 case OPCODE_RET:
413 fullinst->Instruction.Opcode = TGSI_OPCODE_RET;
414 break;
415 case OPCODE_RSQ:
416 fullinst->Instruction.Opcode = TGSI_OPCODE_RSQ;
417 tgsi_util_set_full_src_register_sign_mode(
418 &fullinst->FullSrcRegisters[0],
419 TGSI_UTIL_SIGN_CLEAR );
420 break;
421 case OPCODE_SCS:
422 fullinst->Instruction.Opcode = TGSI_OPCODE_SCS;
423 fulldst->DstRegister.WriteMask &= TGSI_WRITEMASK_XY;
424 break;
425 case OPCODE_SEQ:
426 fullinst->Instruction.Opcode = TGSI_OPCODE_SEQ;
427 break;
428 case OPCODE_SGE:
429 fullinst->Instruction.Opcode = TGSI_OPCODE_SGE;
430 break;
431 case OPCODE_SGT:
432 fullinst->Instruction.Opcode = TGSI_OPCODE_SGT;
433 break;
434 case OPCODE_SIN:
435 fullinst->Instruction.Opcode = TGSI_OPCODE_SIN;
436 break;
437 case OPCODE_SLE:
438 fullinst->Instruction.Opcode = TGSI_OPCODE_SLE;
439 break;
440 case OPCODE_SLT:
441 fullinst->Instruction.Opcode = TGSI_OPCODE_SLT;
442 break;
443 case OPCODE_SNE:
444 fullinst->Instruction.Opcode = TGSI_OPCODE_SNE;
445 break;
446 case OPCODE_SUB:
447 fullinst->Instruction.Opcode = TGSI_OPCODE_SUB;
448 break;
449 case OPCODE_SWZ:
450 fullinst->Instruction.Opcode = TGSI_OPCODE_SWZ;
451 break;
452 case OPCODE_TEX:
453 /* ordinary texture lookup */
454 fullinst->Instruction.Opcode = TGSI_OPCODE_TEX;
455 fullinst->Instruction.NumSrcRegs = 2;
456 fullinst->InstructionExtTexture.Texture = map_texture_target( inst->TexSrcTarget );
457 fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
458 fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;
459 break;
460 case OPCODE_TXB:
461 /* texture lookup with LOD bias */
462 fullinst->Instruction.Opcode = TGSI_OPCODE_TXB;
463 fullinst->Instruction.NumSrcRegs = 2;
464 fullinst->InstructionExtTexture.Texture = map_texture_target( inst->TexSrcTarget );
465 fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
466 fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;
467 break;
468 case OPCODE_TXD:
469 /* texture lookup with explicit partial derivatives */
470 fullinst->Instruction.Opcode = TGSI_OPCODE_TXD;
471 fullinst->Instruction.NumSrcRegs = 4;
472 fullinst->InstructionExtTexture.Texture = map_texture_target( inst->TexSrcTarget );
473 /* src[0] = coord, src[1] = d[strq]/dx, src[2] = d[strq]/dy */
474 fullinst->FullSrcRegisters[3].SrcRegister.File = TGSI_FILE_SAMPLER;
475 fullinst->FullSrcRegisters[3].SrcRegister.Index = inst->TexSrcUnit;
476 break;
477 case OPCODE_TXL:
478 /* texture lookup with explicit LOD */
479 fullinst->Instruction.Opcode = TGSI_OPCODE_TXL;
480 fullinst->Instruction.NumSrcRegs = 2;
481 fullinst->InstructionExtTexture.Texture = map_texture_target( inst->TexSrcTarget );
482 fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
483 fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;
484 break;
485 case OPCODE_TXP:
486 /* texture lookup with divide by Q component */
487 /* convert to TEX w/ special flag for division */
488 fullinst->Instruction.Opcode = TGSI_OPCODE_TEX;
489 fullinst->Instruction.NumSrcRegs = 2;
490 fullinst->InstructionExtTexture.Texture = map_texture_target( inst->TexSrcTarget );
491 fullinst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide = TGSI_EXTSWIZZLE_W;
492 fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
493 fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;
494 break;
495 case OPCODE_XPD:
496 fullinst->Instruction.Opcode = TGSI_OPCODE_XPD;
497 fulldst->DstRegister.WriteMask &= TGSI_WRITEMASK_XYZ;
498 break;
499 case OPCODE_END:
500 fullinst->Instruction.Opcode = TGSI_OPCODE_RET;
501 break;
502 default:
503 assert( 0 );
504 }
505 }
506
507 /**
508 * \param usage_mask bitfield of TGSI_WRITEMASK_{XYZW} tokens
509 */
510 static struct tgsi_full_declaration
511 make_input_decl(
512 GLuint index,
513 GLboolean interpolate_info,
514 GLuint interpolate,
515 GLuint usage_mask,
516 GLboolean semantic_info,
517 GLuint semantic_name,
518 GLbitfield semantic_index )
519 {
520 struct tgsi_full_declaration decl;
521
522 assert(semantic_name < TGSI_SEMANTIC_COUNT);
523
524 decl = tgsi_default_full_declaration();
525 decl.Declaration.File = TGSI_FILE_INPUT;
526 decl.Declaration.Declare = TGSI_DECLARE_RANGE;
527 decl.Declaration.UsageMask = usage_mask;
528 decl.Declaration.Semantic = semantic_info;
529 decl.u.DeclarationRange.First = index;
530 decl.u.DeclarationRange.Last = index;
531 if (semantic_info) {
532 decl.Semantic.SemanticName = semantic_name;
533 decl.Semantic.SemanticIndex = semantic_index;
534 }
535 if (interpolate_info) {
536 decl.Declaration.Interpolate = 1;
537 decl.Interpolation.Interpolate = interpolate;
538 }
539
540 return decl;
541 }
542
543 /**
544 * \param usage_mask bitfield of TGSI_WRITEMASK_{XYZW} tokens
545 */
546 static struct tgsi_full_declaration
547 make_output_decl(
548 GLuint index,
549 GLuint semantic_name,
550 GLuint semantic_index,
551 GLbitfield usage_mask )
552 {
553 struct tgsi_full_declaration decl;
554
555 assert(semantic_name < TGSI_SEMANTIC_COUNT);
556
557 decl = tgsi_default_full_declaration();
558 decl.Declaration.File = TGSI_FILE_OUTPUT;
559 decl.Declaration.Declare = TGSI_DECLARE_RANGE;
560 decl.Declaration.UsageMask = usage_mask;
561 decl.Declaration.Semantic = 1;
562 decl.u.DeclarationRange.First = index;
563 decl.u.DeclarationRange.Last = index;
564 decl.Semantic.SemanticName = semantic_name;
565 decl.Semantic.SemanticIndex = semantic_index;
566
567 return decl;
568 }
569
570
571 static struct tgsi_full_declaration
572 make_temp_decl(
573 GLuint start_index,
574 GLuint end_index )
575 {
576 struct tgsi_full_declaration decl;
577 decl = tgsi_default_full_declaration();
578 decl.Declaration.File = TGSI_FILE_TEMPORARY;
579 decl.Declaration.Declare = TGSI_DECLARE_RANGE;
580 decl.u.DeclarationRange.First = start_index;
581 decl.u.DeclarationRange.Last = end_index;
582 return decl;
583 }
584
585
586 /**
587 * Find the temporaries which are used in the given program.
588 */
589 static void
590 find_temporaries(const struct gl_program *program,
591 GLboolean tempsUsed[MAX_PROGRAM_TEMPS])
592 {
593 GLuint i, j;
594
595 for (i = 0; i < MAX_PROGRAM_TEMPS; i++)
596 tempsUsed[i] = GL_FALSE;
597
598 for (i = 0; i < program->NumInstructions; i++) {
599 const struct prog_instruction *inst = program->Instructions + i;
600 const GLuint n = _mesa_num_inst_src_regs( inst->Opcode );
601 for (j = 0; j < n; j++) {
602 if (inst->SrcReg[j].File == PROGRAM_TEMPORARY)
603 tempsUsed[inst->SrcReg[j].Index] = GL_TRUE;
604 if (inst->DstReg.File == PROGRAM_TEMPORARY)
605 tempsUsed[inst->DstReg.Index] = GL_TRUE;
606 }
607 }
608 }
609
610
611
612
613 /**
614 * Translate Mesa program to TGSI format.
615 * \param program the program to translate
616 * \param numInputs number of input registers used
617 * \param inputMapping maps Mesa fragment program inputs to TGSI generic
618 * input indexes
619 * \param inputSemanticName the TGSI_SEMANTIC flag for each input
620 * \param inputSemanticIndex the semantic index (ex: which texcoord) for each input
621 * \param interpMode the TGSI_INTERPOLATE_LINEAR/PERSP mode for each input
622
623 * \param numOutputs number of output registers used
624 * \param outputMapping maps Mesa fragment program outputs to TGSI
625 * generic outputs
626 * \param outputSemanticName the TGSI_SEMANTIC flag for each output
627 * \param outputSemanticIndex the semantic index (ex: which texcoord) for each output
628 * \param tokens array to store translated tokens in
629 * \param maxTokens size of the tokens array
630 *
631 */
632 GLboolean
633 tgsi_translate_mesa_program(
634 uint procType,
635 const struct gl_program *program,
636 GLuint numInputs,
637 const GLuint inputMapping[],
638 const ubyte inputSemanticName[],
639 const ubyte inputSemanticIndex[],
640 const GLuint interpMode[],
641 GLuint numOutputs,
642 const GLuint outputMapping[],
643 const ubyte outputSemanticName[],
644 const ubyte outputSemanticIndex[],
645 struct tgsi_token *tokens,
646 GLuint maxTokens )
647 {
648 GLuint i;
649 GLuint ti; /* token index */
650 struct tgsi_header *header;
651 struct tgsi_processor *processor;
652 struct tgsi_full_instruction fullinst;
653 GLuint preamble_size = 0;
654 GLuint immediates[1000];
655 GLuint numImmediates = 0;
656
657 assert(procType == TGSI_PROCESSOR_FRAGMENT ||
658 procType == TGSI_PROCESSOR_VERTEX);
659
660 *(struct tgsi_version *) &tokens[0] = tgsi_build_version();
661
662 header = (struct tgsi_header *) &tokens[1];
663 *header = tgsi_build_header();
664
665 processor = (struct tgsi_processor *) &tokens[2];
666 *processor = tgsi_build_processor( procType, header );
667
668 ti = 3;
669
670 /*
671 * Declare input attributes.
672 */
673 if (procType == TGSI_PROCESSOR_FRAGMENT) {
674 for (i = 0; i < numInputs; i++) {
675 struct tgsi_full_declaration fulldecl;
676 switch (inputSemanticName[i]) {
677 case TGSI_SEMANTIC_POSITION:
678 /* Fragment XY pos */
679 fulldecl = make_input_decl(i,
680 GL_TRUE, TGSI_INTERPOLATE_CONSTANT,
681 TGSI_WRITEMASK_XY,
682 GL_TRUE, TGSI_SEMANTIC_POSITION, 0 );
683 ti += tgsi_build_full_declaration(
684 &fulldecl,
685 &tokens[ti],
686 header,
687 maxTokens - ti );
688 /* Fragment ZW pos */
689 fulldecl = make_input_decl(i,
690 GL_TRUE, TGSI_INTERPOLATE_LINEAR,
691 TGSI_WRITEMASK_ZW,
692 GL_TRUE, TGSI_SEMANTIC_POSITION, 0 );
693 ti += tgsi_build_full_declaration(&fulldecl,
694 &tokens[ti],
695 header,
696 maxTokens - ti );
697 break;
698 default:
699 fulldecl = make_input_decl(i,
700 GL_TRUE, interpMode[i],
701 TGSI_WRITEMASK_XYZW,
702 GL_TRUE, inputSemanticName[i],
703 inputSemanticIndex[i]);
704 ti += tgsi_build_full_declaration(&fulldecl,
705 &tokens[ti],
706 header,
707 maxTokens - ti );
708 break;
709 }
710 }
711 }
712 else {
713 /* vertex prog */
714 for (i = 0; i < numInputs; i++) {
715 struct tgsi_full_declaration fulldecl;
716 fulldecl = make_input_decl(i,
717 GL_FALSE, 0,
718 TGSI_WRITEMASK_XYZW,
719 GL_FALSE, 0, 0);
720 ti += tgsi_build_full_declaration(&fulldecl,
721 &tokens[ti],
722 header,
723 maxTokens - ti );
724 }
725 }
726
727 /*
728 * Declare output attributes.
729 */
730 if (procType == TGSI_PROCESSOR_FRAGMENT) {
731 for (i = 0; i < numOutputs; i++) {
732 struct tgsi_full_declaration fulldecl;
733 switch (outputSemanticName[i]) {
734 case TGSI_SEMANTIC_POSITION:
735 fulldecl = make_output_decl(i,
736 TGSI_SEMANTIC_POSITION, 0, /* Z / Depth */
737 TGSI_WRITEMASK_Z );
738 break;
739 case TGSI_SEMANTIC_COLOR:
740 fulldecl = make_output_decl(i,
741 TGSI_SEMANTIC_COLOR, 0,
742 TGSI_WRITEMASK_XYZW );
743 break;
744 default:
745 abort();
746 }
747 ti += tgsi_build_full_declaration(&fulldecl,
748 &tokens[ti],
749 header,
750 maxTokens - ti );
751 }
752 }
753 else {
754 /* vertex prog */
755 for (i = 0; i < numOutputs; i++) {
756 struct tgsi_full_declaration fulldecl;
757 fulldecl = make_output_decl(i,
758 outputSemanticName[i],
759 outputSemanticIndex[i],
760 TGSI_WRITEMASK_XYZW );
761 ti += tgsi_build_full_declaration(&fulldecl,
762 &tokens[ti],
763 header,
764 maxTokens - ti );
765 }
766 }
767
768 /* temporary decls */
769 {
770 GLboolean tempsUsed[MAX_PROGRAM_TEMPS + 1];
771 GLboolean inside_range = GL_FALSE;
772 GLuint start_range;
773
774 find_temporaries(program, tempsUsed);
775 tempsUsed[MAX_PROGRAM_TEMPS] = GL_FALSE;
776 for (i = 0; i < MAX_PROGRAM_TEMPS + 1; i++) {
777 if (tempsUsed[i] && !inside_range) {
778 inside_range = GL_TRUE;
779 start_range = i;
780 }
781 else if (!tempsUsed[i] && inside_range) {
782 struct tgsi_full_declaration fulldecl;
783
784 inside_range = GL_FALSE;
785 fulldecl = make_temp_decl( start_range, i - 1 );
786 ti += tgsi_build_full_declaration(
787 &fulldecl,
788 &tokens[ti],
789 header,
790 maxTokens - ti );
791 }
792 }
793 }
794
795 /* immediates/literals */
796 for (i = 0; program->Parameters && i < program->Parameters->NumParameters;
797 i++) {
798 if (program->Parameters->Parameters[i].Type == PROGRAM_CONSTANT) {
799 struct tgsi_full_immediate fullimm
800 = make_immediate(program->Parameters->ParameterValues[i],
801 program->Parameters->Parameters[i].Size);
802 ti += tgsi_build_full_immediate(&fullimm,
803 &tokens[ti],
804 header,
805 maxTokens - ti);
806 immediates[i] = numImmediates;
807 numImmediates++;
808 }
809 }
810
811 for( i = 0; i < program->NumInstructions; i++ ) {
812 compile_instruction(
813 &program->Instructions[i],
814 &fullinst,
815 inputMapping,
816 outputMapping,
817 immediates,
818 preamble_size,
819 procType );
820
821 ti += tgsi_build_full_instruction(
822 &fullinst,
823 &tokens[ti],
824 header,
825 maxTokens - ti );
826 }
827
828 return GL_TRUE;
829 }
830