fix in/out typos
[mesa.git] / src / mesa / pipe / tgsi / mesa / mesa_to_tgsi.c
1 #include "tgsi_platform.h"
2 #include "tgsi_mesa.h"
3 #include "pipe/tgsi/mesa/mesa_to_tgsi.h"
4
5 #define TGSI_DEBUG 0
6
7
8 /*
9 * Map mesa register file to TGSI register file.
10 */
11 static GLuint
12 map_register_file(
13 enum register_file file )
14 {
15 switch( file ) {
16 case PROGRAM_UNDEFINED:
17 return TGSI_FILE_NULL;
18 case PROGRAM_TEMPORARY:
19 return TGSI_FILE_TEMPORARY;
20 //case PROGRAM_LOCAL_PARAM:
21 //case PROGRAM_ENV_PARAM:
22 case PROGRAM_STATE_VAR:
23 case PROGRAM_NAMED_PARAM:
24 case PROGRAM_CONSTANT:
25 case PROGRAM_UNIFORM:
26 return TGSI_FILE_CONSTANT;
27 case PROGRAM_INPUT:
28 return TGSI_FILE_INPUT;
29 case PROGRAM_OUTPUT:
30 return TGSI_FILE_OUTPUT;
31 case PROGRAM_ADDRESS:
32 return TGSI_FILE_ADDRESS;
33 default:
34 assert( 0 );
35 return TGSI_FILE_NULL;
36 }
37 }
38
39 /**
40 * Map mesa register file index to TGSI index.
41 * Take special care when processing input and output indices.
42 * \param processor either TGSI_PROCESSOR_FRAGMENT or TGSI_PROCESSOR_VERTEX
43 * \param file one of TGSI_FILE_x
44 * \param index the mesa register file index
45 * \param usage_bitmask ???
46 */
47 static GLuint
48 map_register_file_index(
49 GLuint processor,
50 GLuint file,
51 GLuint index,
52 const GLuint inputMapping[],
53 const GLuint outputMapping[])
54 {
55 GLuint mapped_index;
56
57 assert(processor == TGSI_PROCESSOR_FRAGMENT
58 || processor == TGSI_PROCESSOR_VERTEX);
59
60 switch( file ) {
61 case TGSI_FILE_INPUT:
62 /*
63 * The fragment/vertex program input indexes (FRAG/VERT_ATTRIB_x) get
64 * mapped to a packed sequence of integers.
65 * If a program uses one input attribute, the mapped index will be 1.
66 * If a program uses two input attribs, the mapped indexes will be 1,2.
67 * If a program uses 3 input attribs, the mapped indexes will be 1,2,3.
68 * etc.
69 */
70 printf("Map %d input %d to %d\n", processor, index, mapped_index);
71 return inputMapping[index];
72
73 case TGSI_FILE_OUTPUT:
74 /*
75 assert( usage_bitmask == 0x0 );
76 */
77 if( processor == TGSI_PROCESSOR_FRAGMENT ) {
78 /* depth result -> index 0
79 * color results -> index 1, 2, ...
80 */
81 if( index == FRAG_RESULT_DEPR ) {
82 mapped_index = 0; /**TGSI_ATTRIB_POS;**/
83 }
84 else {
85 assert( index == FRAG_RESULT_COLR );
86 mapped_index = 1; /**TGSI_ATTRIB_COLOR0;**/
87 }
88 }
89 else {
90 /* vertex output slots are tightly packed, find mapped pos */
91 /* mapped_index = VERT_RESULT_x */
92 mapped_index = outputMapping[index];
93 printf("Map VP output from %d to %d\n", index, mapped_index);
94 }
95 break;
96
97 default:
98 mapped_index = index;
99 }
100
101 return mapped_index;
102 }
103
104 /*
105 * Map mesa texture target to TGSI texture target.
106 */
107 static GLuint
108 map_texture_target(
109 GLuint textarget )
110 {
111 switch( textarget ) {
112 case TEXTURE_1D_INDEX:
113 return TGSI_TEXTURE_1D;
114 case TEXTURE_2D_INDEX:
115 return TGSI_TEXTURE_2D;
116 case TEXTURE_3D_INDEX:
117 return TGSI_TEXTURE_3D;
118 case TEXTURE_CUBE_INDEX:
119 return TGSI_TEXTURE_CUBE;
120 case TEXTURE_RECT_INDEX:
121 return TGSI_TEXTURE_RECT;
122 default:
123 assert( 0 );
124 }
125
126 return TGSI_TEXTURE_1D;
127 }
128
129 static GLuint
130 convert_sat(
131 GLuint sat )
132 {
133 switch( sat ) {
134 case SATURATE_OFF:
135 return TGSI_SAT_NONE;
136 case SATURATE_ZERO_ONE:
137 return TGSI_SAT_ZERO_ONE;
138 case SATURATE_PLUS_MINUS_ONE:
139 return TGSI_SAT_MINUS_PLUS_ONE;
140 default:
141 assert( 0 );
142 return TGSI_SAT_NONE;
143 }
144 }
145
146 static GLuint
147 convert_writemask(
148 GLuint writemask )
149 {
150 assert( WRITEMASK_X == TGSI_WRITEMASK_X );
151 assert( WRITEMASK_Y == TGSI_WRITEMASK_Y );
152 assert( WRITEMASK_Z == TGSI_WRITEMASK_Z );
153 assert( WRITEMASK_W == TGSI_WRITEMASK_W );
154 assert( (writemask & ~TGSI_WRITEMASK_XYZW) == 0 );
155
156 return writemask;
157 }
158
159 static GLboolean
160 compile_instruction(
161 const struct prog_instruction *inst,
162 struct tgsi_full_instruction *fullinst,
163 const GLuint inputMapping[],
164 const GLuint outputMapping[],
165 GLuint preamble_size,
166 GLuint processor )
167 {
168 GLuint i;
169 struct tgsi_full_dst_register *fulldst;
170 struct tgsi_full_src_register *fullsrc;
171
172 *fullinst = tgsi_default_full_instruction();
173
174 fullinst->Instruction.Saturate = convert_sat( inst->SaturateMode );
175 fullinst->Instruction.NumDstRegs = _mesa_num_inst_dst_regs( inst->Opcode );
176 fullinst->Instruction.NumSrcRegs = _mesa_num_inst_src_regs( inst->Opcode );
177
178 fulldst = &fullinst->FullDstRegisters[0];
179 fulldst->DstRegister.File = map_register_file( inst->DstReg.File );
180 fulldst->DstRegister.Index = map_register_file_index(
181 processor,
182 fulldst->DstRegister.File,
183 inst->DstReg.Index,
184 inputMapping,
185 outputMapping
186 );
187 fulldst->DstRegister.WriteMask = convert_writemask( inst->DstReg.WriteMask );
188
189 for( i = 0; i < fullinst->Instruction.NumSrcRegs; i++ ) {
190 GLuint j;
191
192 fullsrc = &fullinst->FullSrcRegisters[i];
193 fullsrc->SrcRegister.File = map_register_file( inst->SrcReg[i].File );
194 fullsrc->SrcRegister.Index = map_register_file_index(
195 processor,
196 fullsrc->SrcRegister.File,
197 inst->SrcReg[i].Index,
198 inputMapping,
199 outputMapping );
200
201 for( j = 0; j < 4; j++ ) {
202 GLuint swz;
203
204 swz = GET_SWZ( inst->SrcReg[i].Swizzle, j );
205 if( swz > SWIZZLE_W ) {
206 tgsi_util_set_src_register_extswizzle(
207 &fullsrc->SrcRegisterExtSwz,
208 swz,
209 j );
210 }
211 else {
212 tgsi_util_set_src_register_swizzle(
213 &fullsrc->SrcRegister,
214 swz,
215 j );
216 }
217 }
218
219 if( inst->SrcReg[i].NegateBase == NEGATE_XYZW ) {
220 fullsrc->SrcRegister.Negate = 1;
221 }
222 else if( inst->SrcReg[i].NegateBase != NEGATE_NONE ) {
223 if( inst->SrcReg[i].NegateBase & NEGATE_X ) {
224 fullsrc->SrcRegisterExtSwz.NegateX = 1;
225 }
226 if( inst->SrcReg[i].NegateBase & NEGATE_Y ) {
227 fullsrc->SrcRegisterExtSwz.NegateY = 1;
228 }
229 if( inst->SrcReg[i].NegateBase & NEGATE_Z ) {
230 fullsrc->SrcRegisterExtSwz.NegateZ = 1;
231 }
232 if( inst->SrcReg[i].NegateBase & NEGATE_W ) {
233 fullsrc->SrcRegisterExtSwz.NegateW = 1;
234 }
235 }
236
237 if( inst->SrcReg[i].Abs ) {
238 fullsrc->SrcRegisterExtMod.Absolute = 1;
239 }
240
241 if( inst->SrcReg[i].NegateAbs ) {
242 fullsrc->SrcRegisterExtMod.Negate = 1;
243 }
244
245 if( inst->SrcReg[i].RelAddr ) {
246 fullsrc->SrcRegister.Indirect = 1;
247
248 fullsrc->SrcRegisterInd.File = TGSI_FILE_ADDRESS;
249 fullsrc->SrcRegisterInd.Index = 0;
250 }
251 }
252
253 switch( inst->Opcode ) {
254 case OPCODE_ARL:
255 fullinst->Instruction.Opcode = TGSI_OPCODE_ARL;
256 break;
257 case OPCODE_ABS:
258 fullinst->Instruction.Opcode = TGSI_OPCODE_ABS;
259 break;
260 case OPCODE_ADD:
261 fullinst->Instruction.Opcode = TGSI_OPCODE_ADD;
262 break;
263 case OPCODE_BGNLOOP:
264 fullinst->Instruction.Opcode = TGSI_OPCODE_BGNLOOP2;
265 break;
266 case OPCODE_BGNSUB:
267 fullinst->Instruction.Opcode = TGSI_OPCODE_BGNSUB;
268 break;
269 case OPCODE_BRA:
270 fullinst->Instruction.Opcode = TGSI_OPCODE_BRA;
271 break;
272 case OPCODE_BRK:
273 fullinst->Instruction.Opcode = TGSI_OPCODE_BRK;
274 break;
275 case OPCODE_CMP:
276 fullinst->Instruction.Opcode = TGSI_OPCODE_CMP;
277 break;
278 case OPCODE_CONT:
279 fullinst->Instruction.Opcode = TGSI_OPCODE_CONT;
280 break;
281 case OPCODE_COS:
282 fullinst->Instruction.Opcode = TGSI_OPCODE_COS;
283 break;
284 case OPCODE_DDX:
285 fullinst->Instruction.Opcode = TGSI_OPCODE_DDX;
286 break;
287 case OPCODE_DDY:
288 fullinst->Instruction.Opcode = TGSI_OPCODE_DDY;
289 break;
290 case OPCODE_DP3:
291 fullinst->Instruction.Opcode = TGSI_OPCODE_DP3;
292 break;
293 case OPCODE_DP4:
294 fullinst->Instruction.Opcode = TGSI_OPCODE_DP4;
295 break;
296 case OPCODE_DPH:
297 fullinst->Instruction.Opcode = TGSI_OPCODE_DPH;
298 break;
299 case OPCODE_DST:
300 fullinst->Instruction.Opcode = TGSI_OPCODE_DST;
301 break;
302 case OPCODE_ELSE:
303 fullinst->Instruction.Opcode = TGSI_OPCODE_ELSE;
304 fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;
305 break;
306 case OPCODE_ENDIF:
307 fullinst->Instruction.Opcode = TGSI_OPCODE_ENDIF;
308 break;
309 case OPCODE_ENDLOOP:
310 fullinst->Instruction.Opcode = TGSI_OPCODE_ENDLOOP2;
311 break;
312 case OPCODE_ENDSUB:
313 fullinst->Instruction.Opcode = TGSI_OPCODE_ENDSUB;
314 break;
315 case OPCODE_EX2:
316 fullinst->Instruction.Opcode = TGSI_OPCODE_EX2;
317 break;
318 case OPCODE_EXP:
319 fullinst->Instruction.Opcode = TGSI_OPCODE_EXP;
320 break;
321 case OPCODE_FLR:
322 fullinst->Instruction.Opcode = TGSI_OPCODE_FLR;
323 break;
324 case OPCODE_FRC:
325 fullinst->Instruction.Opcode = TGSI_OPCODE_FRC;
326 break;
327 case OPCODE_IF:
328 fullinst->Instruction.Opcode = TGSI_OPCODE_IF;
329 fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;
330 break;
331 case OPCODE_INT:
332 fullinst->Instruction.Opcode = TGSI_OPCODE_INT;
333 break;
334 case OPCODE_KIL:
335 fullinst->Instruction.Opcode = TGSI_OPCODE_KIL;
336 break;
337 case OPCODE_LG2:
338 fullinst->Instruction.Opcode = TGSI_OPCODE_LG2;
339 break;
340 case OPCODE_LOG:
341 fullinst->Instruction.Opcode = TGSI_OPCODE_LOG;
342 break;
343 case OPCODE_LIT:
344 fullinst->Instruction.Opcode = TGSI_OPCODE_LIT;
345 break;
346 case OPCODE_LRP:
347 fullinst->Instruction.Opcode = TGSI_OPCODE_LRP;
348 break;
349 case OPCODE_MAD:
350 fullinst->Instruction.Opcode = TGSI_OPCODE_MAD;
351 break;
352 case OPCODE_MAX:
353 fullinst->Instruction.Opcode = TGSI_OPCODE_MAX;
354 break;
355 case OPCODE_MIN:
356 fullinst->Instruction.Opcode = TGSI_OPCODE_MIN;
357 break;
358 case OPCODE_MOV:
359 fullinst->Instruction.Opcode = TGSI_OPCODE_MOV;
360 break;
361 case OPCODE_MUL:
362 fullinst->Instruction.Opcode = TGSI_OPCODE_MUL;
363 break;
364 case OPCODE_NOISE1:
365 fullinst->Instruction.Opcode = TGSI_OPCODE_NOISE1;
366 break;
367 case OPCODE_NOISE2:
368 fullinst->Instruction.Opcode = TGSI_OPCODE_NOISE2;
369 break;
370 case OPCODE_NOISE3:
371 fullinst->Instruction.Opcode = TGSI_OPCODE_NOISE3;
372 break;
373 case OPCODE_NOISE4:
374 fullinst->Instruction.Opcode = TGSI_OPCODE_NOISE4;
375 break;
376 case OPCODE_NOP:
377 fullinst->Instruction.Opcode = TGSI_OPCODE_NOP;
378 break;
379 case OPCODE_POW:
380 fullinst->Instruction.Opcode = TGSI_OPCODE_POW;
381 break;
382 case OPCODE_RCP:
383 fullinst->Instruction.Opcode = TGSI_OPCODE_RCP;
384 break;
385 case OPCODE_RSQ:
386 fullinst->Instruction.Opcode = TGSI_OPCODE_RSQ;
387 tgsi_util_set_full_src_register_sign_mode(
388 &fullinst->FullSrcRegisters[0],
389 TGSI_UTIL_SIGN_CLEAR );
390 break;
391 case OPCODE_SCS:
392 fullinst->Instruction.Opcode = TGSI_OPCODE_SCS;
393 fulldst->DstRegister.WriteMask &= TGSI_WRITEMASK_XY;
394 break;
395 case OPCODE_SEQ:
396 fullinst->Instruction.Opcode = TGSI_OPCODE_SEQ;
397 break;
398 case OPCODE_SGE:
399 fullinst->Instruction.Opcode = TGSI_OPCODE_SGE;
400 break;
401 case OPCODE_SGT:
402 fullinst->Instruction.Opcode = TGSI_OPCODE_SGT;
403 break;
404 case OPCODE_SIN:
405 fullinst->Instruction.Opcode = TGSI_OPCODE_SIN;
406 break;
407 case OPCODE_SLE:
408 fullinst->Instruction.Opcode = TGSI_OPCODE_SLE;
409 break;
410 case OPCODE_SLT:
411 fullinst->Instruction.Opcode = TGSI_OPCODE_SLT;
412 break;
413 case OPCODE_SNE:
414 fullinst->Instruction.Opcode = TGSI_OPCODE_SNE;
415 break;
416 case OPCODE_SUB:
417 fullinst->Instruction.Opcode = TGSI_OPCODE_SUB;
418 break;
419 case OPCODE_SWZ:
420 fullinst->Instruction.Opcode = TGSI_OPCODE_SWZ;
421 break;
422 case OPCODE_TEX:
423 fullinst->Instruction.Opcode = TGSI_OPCODE_TEX;
424 fullinst->Instruction.NumSrcRegs = 2;
425 fullinst->InstructionExtTexture.Texture = map_texture_target( inst->TexSrcTarget );
426 fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
427 fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;
428 break;
429 case OPCODE_TXB:
430 fullinst->Instruction.Opcode = TGSI_OPCODE_TXB;
431 fullinst->Instruction.NumSrcRegs = 2;
432 fullinst->InstructionExtTexture.Texture = map_texture_target( inst->TexSrcTarget );
433 fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
434 fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;
435 break;
436 case OPCODE_TXD:
437 fullinst->Instruction.Opcode = TGSI_OPCODE_TXD;
438 fullinst->Instruction.NumSrcRegs = 2;
439 fullinst->InstructionExtTexture.Texture = map_texture_target( inst->TexSrcTarget );
440 fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
441 fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;
442 break;
443 case OPCODE_TXL:
444 fullinst->Instruction.Opcode = TGSI_OPCODE_TXL;
445 fullinst->Instruction.NumSrcRegs = 2;
446 fullinst->InstructionExtTexture.Texture = map_texture_target( inst->TexSrcTarget );
447 fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
448 fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;
449 break;
450 case OPCODE_TXP:
451 fullinst->Instruction.Opcode = TGSI_OPCODE_TEX;
452 fullinst->Instruction.NumSrcRegs = 2;
453 fullinst->InstructionExtTexture.Texture = map_texture_target( inst->TexSrcTarget );
454 fullinst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide = TGSI_EXTSWIZZLE_W;
455 fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
456 fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;
457 break;
458 case OPCODE_XPD:
459 fullinst->Instruction.Opcode = TGSI_OPCODE_XPD;
460 fulldst->DstRegister.WriteMask &= TGSI_WRITEMASK_XYZ;
461 break;
462 case OPCODE_END:
463 return GL_TRUE;
464 default:
465 assert( 0 );
466 }
467
468 return GL_FALSE;
469 }
470
471 static struct tgsi_full_declaration
472 make_input_decl(
473 GLuint index,
474 GLuint interpolate,
475 GLuint usage_mask,
476 GLuint semantic_name,
477 GLuint semantic_index )
478 {
479 struct tgsi_full_declaration decl;
480
481 decl = tgsi_default_full_declaration();
482 decl.Declaration.File = TGSI_FILE_INPUT;
483 decl.Declaration.Declare = TGSI_DECLARE_RANGE;
484 decl.Declaration.UsageMask = usage_mask;
485 decl.Declaration.Semantic = 1;
486 decl.Declaration.Interpolate = 1;
487 decl.u.DeclarationRange.First = index;
488 decl.u.DeclarationRange.Last = index;
489 decl.Semantic.SemanticName = semantic_name;
490 decl.Semantic.SemanticIndex = semantic_index;
491 decl.Interpolation.Interpolate = interpolate;
492
493 return decl;
494 }
495
496 static struct tgsi_full_declaration
497 make_frag_output_decl(
498 GLuint index,
499 GLuint semantic_name,
500 GLuint semantic_index,
501 GLuint usage_mask )
502 {
503 struct tgsi_full_declaration decl;
504
505 decl = tgsi_default_full_declaration();
506 decl.Declaration.File = TGSI_FILE_OUTPUT;
507 decl.Declaration.Declare = TGSI_DECLARE_RANGE;
508 decl.Declaration.UsageMask = usage_mask;
509 decl.Declaration.Semantic = 1;
510 decl.u.DeclarationRange.First = index;
511 decl.u.DeclarationRange.Last = index;
512 decl.Semantic.SemanticName = semantic_name;
513 decl.Semantic.SemanticIndex = semantic_index;
514
515 return decl;
516 }
517
518
519 /**
520 * Convert Mesa fragment program to TGSI format.
521 * \param inputMapping maps Mesa fragment program inputs to TGSI generic
522 * input indexes
523 * \param inputSemantic the TGSI_SEMANTIC flag for each input
524 * \param interpMode the TGSI_INTERPOLATE_LINEAR/PERSP mode for each input
525 * \param outputMapping maps Mesa fragment program outputs to TGSI
526 * generic outputs
527 *
528 */
529 GLboolean
530 tgsi_mesa_compile_fp_program(
531 const struct gl_fragment_program *program,
532 GLuint numInputs,
533 const GLuint inputMapping[],
534 const ubyte inputSemanticName[],
535 const ubyte inputSemanticIndex[],
536 const GLuint interpMode[],
537 const GLuint outputMapping[],
538 struct tgsi_token *tokens,
539 GLuint maxTokens )
540 {
541 GLuint i;
542 GLuint ti; /* token index */
543 struct tgsi_header *header;
544 struct tgsi_processor *processor;
545 struct tgsi_full_declaration fulldecl;
546 struct tgsi_full_instruction fullinst;
547 GLuint preamble_size = 0;
548
549 *(struct tgsi_version *) &tokens[0] = tgsi_build_version();
550
551 header = (struct tgsi_header *) &tokens[1];
552 *header = tgsi_build_header();
553
554 processor = (struct tgsi_processor *) &tokens[2];
555 *processor = tgsi_build_processor( TGSI_PROCESSOR_FRAGMENT, header );
556
557 ti = 3;
558
559 for (i = 0; i < numInputs; i++) {
560 switch (inputSemanticName[i]) {
561 case TGSI_SEMANTIC_POSITION:
562 /* Fragment XY pos */
563 fulldecl = make_input_decl(i,
564 TGSI_INTERPOLATE_CONSTANT,
565 TGSI_WRITEMASK_XY,
566 TGSI_SEMANTIC_POSITION, 0 );
567 ti += tgsi_build_full_declaration(
568 &fulldecl,
569 &tokens[ti],
570 header,
571 maxTokens - ti );
572 /* Fragment ZW pos */
573 fulldecl = make_input_decl(i,
574 TGSI_INTERPOLATE_LINEAR,
575 TGSI_WRITEMASK_ZW,
576 TGSI_SEMANTIC_POSITION, 0 );
577 ti += tgsi_build_full_declaration(
578 &fulldecl,
579 &tokens[ti],
580 header,
581 maxTokens - ti );
582 break;
583 default:
584 fulldecl = make_input_decl(i,
585 interpMode[i],
586 TGSI_WRITEMASK_XYZW,
587 inputSemanticName[i],
588 inputSemanticIndex[i]);
589 ti += tgsi_build_full_declaration(&fulldecl,
590 &tokens[ti],
591 header,
592 maxTokens - ti );
593 break;
594 }
595 }
596
597
598 /*
599 * Declare output attributes.
600 */
601 assert(
602 program->Base.OutputsWritten ==
603 (program->Base.OutputsWritten & ((1 << FRAG_RESULT_COLR) | (1 << FRAG_RESULT_DEPR))) );
604
605 fulldecl = make_frag_output_decl(
606 0,
607 TGSI_SEMANTIC_POSITION, 0, /* Z / Depth */
608 TGSI_WRITEMASK_Z );
609 ti += tgsi_build_full_declaration(
610 &fulldecl,
611 &tokens[ti],
612 header,
613 maxTokens - ti );
614
615 if( program->Base.OutputsWritten & (1 << FRAG_RESULT_COLR) ) {
616 fulldecl = make_frag_output_decl(
617 1,
618 TGSI_SEMANTIC_COLOR, 0,
619 TGSI_WRITEMASK_XYZW );
620 ti += tgsi_build_full_declaration(
621 &fulldecl,
622 &tokens[ti],
623 header,
624 maxTokens - ti );
625 }
626
627 /*
628 * Copy fragment z if the shader does not write it.
629 */
630 #if 0
631 if( !(program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) ) {
632 fullinst = tgsi_default_full_instruction();
633
634 fullinst.Instruction.Opcode = TGSI_OPCODE_MOV;
635 fullinst.Instruction.NumDstRegs = 1;
636 fullinst.Instruction.NumSrcRegs = 1;
637
638 fulldst = &fullinst.FullDstRegisters[0];
639 fulldst->DstRegister.File = TGSI_FILE_OUTPUT;
640 fulldst->DstRegister.Index = 0;
641 fulldst->DstRegister.WriteMask = TGSI_WRITEMASK_Z;
642
643 fullsrc = &fullinst.FullSrcRegisters[0];
644 fullsrc->SrcRegister.File = TGSI_FILE_INPUT;
645 fullsrc->SrcRegister.Index = 0;
646
647 ti += tgsi_build_full_instruction(
648 &fullinst,
649 &tokens[ti],
650 header,
651 maxTokens - ti );
652 preamble_size++;
653 }
654 #endif
655
656 for( i = 0; i < program->Base.NumInstructions; i++ ) {
657 if( compile_instruction(
658 &program->Base.Instructions[i],
659 &fullinst,
660 inputMapping,
661 outputMapping,
662 preamble_size,
663 TGSI_PROCESSOR_FRAGMENT ) ) {
664 assert( i == program->Base.NumInstructions - 1 );
665
666 if( TGSI_DEBUG ) {
667 tgsi_dump( tokens, 0 );
668 }
669 break;
670 }
671
672 ti += tgsi_build_full_instruction(
673 &fullinst,
674 &tokens[ti],
675 header,
676 maxTokens - ti );
677 }
678
679 return GL_TRUE;
680 }
681
682 GLboolean
683 tgsi_mesa_compile_vp_program(
684 const struct gl_vertex_program *program,
685 GLuint numInputs,
686 const GLuint inputMapping[],
687 const ubyte inputSemanticName[],
688 const ubyte inputSemanticIndex[],
689 const GLuint outputMapping[],
690 struct tgsi_token *tokens,
691 GLuint maxTokens)
692 {
693 GLuint i, ti;
694 struct tgsi_header *header;
695 struct tgsi_processor *processor;
696 struct tgsi_full_instruction fullinst;
697
698 *(struct tgsi_version *) &tokens[0] = tgsi_build_version();
699
700 header = (struct tgsi_header *) &tokens[1];
701 *header = tgsi_build_header();
702
703 processor = (struct tgsi_processor *) &tokens[2];
704 *processor = tgsi_build_processor( TGSI_PROCESSOR_VERTEX, header );
705
706 ti = 3;
707
708 /* XXX todo: input/output declarations
709 */
710 for (i = 0; i < numInputs; i++) {
711 struct tgsi_full_declaration fulldecl;
712 fulldecl = make_input_decl(i,
713 TGSI_INTERPOLATE_CONSTANT, /* no interp */
714 TGSI_WRITEMASK_XYZW,
715 inputSemanticName[i],
716 inputSemanticIndex[i]);
717 ti += tgsi_build_full_declaration(&fulldecl,
718 &tokens[ti],
719 header,
720 maxTokens - ti );
721 }
722
723
724 for( i = 0; i < program->Base.NumInstructions; i++ ) {
725 if( compile_instruction(
726 &program->Base.Instructions[i],
727 &fullinst,
728 inputMapping,
729 outputMapping,
730 0,
731 TGSI_PROCESSOR_VERTEX ) ) {
732 assert( i == program->Base.NumInstructions - 1 );
733
734 if( TGSI_DEBUG ) {
735 tgsi_dump( tokens, 0 );
736 }
737 break;
738 }
739
740 ti += tgsi_build_full_instruction(
741 &fullinst,
742 &tokens[ti],
743 header,
744 maxTokens - ti );
745 }
746
747 return GL_TRUE;
748 }
749