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