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