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