st_mesa_to_tgsi.c revision 2bbd714fda7b0fb21184bea8ed0c08f155cba528
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 */
47static GLuint
48map_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 */
88static GLuint
89map_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 */
117static GLuint
118map_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
139static GLuint
140convert_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
156static GLuint
157convert_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
170static struct tgsi_full_immediate
171make_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
182static void
183compile_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 */
519static struct tgsi_full_declaration
520make_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 */
552static struct tgsi_full_declaration
553make_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
577static struct tgsi_full_declaration
578make_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 */
595static void
596find_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 */
638GLboolean
639tgsi_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
841