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