00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "pipe/p_compiler.h"
00034 #include "pipe/p_shader_tokens.h"
00035 #include "tgsi/tgsi_parse.h"
00036 #include "tgsi/tgsi_build.h"
00037 #include "tgsi/tgsi_util.h"
00038 #include "tgsi/tgsi_dump.h"
00039 #include "tgsi/tgsi_sanity.h"
00040 #include "st_mesa_to_tgsi.h"
00041 #include "shader/prog_instruction.h"
00042 #include "shader/prog_parameter.h"
00043 #include "shader/prog_print.h"
00044 #include "pipe/p_debug.h"
00045
00046
00047
00048
00049 static GLuint
00050 map_register_file(
00051 enum register_file file,
00052 GLuint index,
00053 const GLuint immediateMapping[],
00054 GLboolean indirectAccess )
00055 {
00056 switch( file ) {
00057 case PROGRAM_UNDEFINED:
00058 return TGSI_FILE_NULL;
00059 case PROGRAM_TEMPORARY:
00060 return TGSI_FILE_TEMPORARY;
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 case PROGRAM_STATE_VAR:
00071 case PROGRAM_NAMED_PARAM:
00072 case PROGRAM_UNIFORM:
00073 if (!indirectAccess && immediateMapping && immediateMapping[index] != ~0)
00074 return TGSI_FILE_IMMEDIATE;
00075 else
00076 return TGSI_FILE_CONSTANT;
00077 case PROGRAM_CONSTANT:
00078 if (indirectAccess)
00079 return TGSI_FILE_CONSTANT;
00080 assert(immediateMapping[index] != ~0);
00081 return TGSI_FILE_IMMEDIATE;
00082 case PROGRAM_INPUT:
00083 return TGSI_FILE_INPUT;
00084 case PROGRAM_OUTPUT:
00085 return TGSI_FILE_OUTPUT;
00086 case PROGRAM_ADDRESS:
00087 return TGSI_FILE_ADDRESS;
00088 default:
00089 assert( 0 );
00090 return TGSI_FILE_NULL;
00091 }
00092 }
00093
00102 static GLuint
00103 map_register_file_index(
00104 GLuint file,
00105 GLuint index,
00106 const GLuint inputMapping[],
00107 const GLuint outputMapping[],
00108 const GLuint immediateMapping[],
00109 GLboolean indirectAccess )
00110 {
00111 switch( file ) {
00112 case TGSI_FILE_INPUT:
00113
00114 return inputMapping[index];
00115
00116 case TGSI_FILE_OUTPUT:
00117 return outputMapping[index];
00118
00119 case TGSI_FILE_IMMEDIATE:
00120 if (indirectAccess)
00121 return index;
00122 assert(immediateMapping[index] != ~0);
00123 return immediateMapping[index];
00124
00125 default:
00126 return index;
00127 }
00128 }
00129
00130
00131
00132
00133 static GLuint
00134 map_texture_target(
00135 GLuint textarget )
00136 {
00137 switch( textarget ) {
00138 case TEXTURE_1D_INDEX:
00139 return TGSI_TEXTURE_1D;
00140 case TEXTURE_2D_INDEX:
00141 return TGSI_TEXTURE_2D;
00142 case TEXTURE_3D_INDEX:
00143 return TGSI_TEXTURE_3D;
00144 case TEXTURE_CUBE_INDEX:
00145 return TGSI_TEXTURE_CUBE;
00146 case TEXTURE_RECT_INDEX:
00147 return TGSI_TEXTURE_RECT;
00148 default:
00149 assert( 0 );
00150 }
00151
00152 return TGSI_TEXTURE_1D;
00153 }
00154
00155 static GLuint
00156 convert_sat(
00157 GLuint sat )
00158 {
00159 switch( sat ) {
00160 case SATURATE_OFF:
00161 return TGSI_SAT_NONE;
00162 case SATURATE_ZERO_ONE:
00163 return TGSI_SAT_ZERO_ONE;
00164 case SATURATE_PLUS_MINUS_ONE:
00165 return TGSI_SAT_MINUS_PLUS_ONE;
00166 default:
00167 assert( 0 );
00168 return TGSI_SAT_NONE;
00169 }
00170 }
00171
00172 static GLuint
00173 convert_writemask(
00174 GLuint writemask )
00175 {
00176 assert( WRITEMASK_X == TGSI_WRITEMASK_X );
00177 assert( WRITEMASK_Y == TGSI_WRITEMASK_Y );
00178 assert( WRITEMASK_Z == TGSI_WRITEMASK_Z );
00179 assert( WRITEMASK_W == TGSI_WRITEMASK_W );
00180 assert( (writemask & ~TGSI_WRITEMASK_XYZW) == 0 );
00181
00182 return writemask;
00183 }
00184
00185 static struct tgsi_full_immediate
00186 make_immediate(const float *value, uint size)
00187 {
00188 struct tgsi_full_immediate imm;
00189
00190 imm = tgsi_default_full_immediate();
00191 imm.Immediate.Size += size;
00192 imm.Immediate.DataType = TGSI_IMM_FLOAT32;
00193 imm.u.Pointer = value;
00194 return imm;
00195 }
00196
00197 static void
00198 compile_instruction(
00199 const struct prog_instruction *inst,
00200 struct tgsi_full_instruction *fullinst,
00201 const GLuint inputMapping[],
00202 const GLuint outputMapping[],
00203 const GLuint immediateMapping[],
00204 GLboolean indirectAccess,
00205 GLuint preamble_size,
00206 GLuint processor,
00207 GLboolean *insideSubroutine)
00208 {
00209 GLuint i;
00210 struct tgsi_full_dst_register *fulldst;
00211 struct tgsi_full_src_register *fullsrc;
00212
00213 *fullinst = tgsi_default_full_instruction();
00214
00215 fullinst->Instruction.Saturate = convert_sat( inst->SaturateMode );
00216 fullinst->Instruction.NumDstRegs = _mesa_num_inst_dst_regs( inst->Opcode );
00217 fullinst->Instruction.NumSrcRegs = _mesa_num_inst_src_regs( inst->Opcode );
00218
00219 fulldst = &fullinst->FullDstRegisters[0];
00220 fulldst->DstRegister.File = map_register_file( inst->DstReg.File, 0, NULL, GL_FALSE );
00221 fulldst->DstRegister.Index = map_register_file_index(
00222 fulldst->DstRegister.File,
00223 inst->DstReg.Index,
00224 inputMapping,
00225 outputMapping,
00226 NULL,
00227 GL_FALSE );
00228 fulldst->DstRegister.WriteMask = convert_writemask( inst->DstReg.WriteMask );
00229
00230 for (i = 0; i < fullinst->Instruction.NumSrcRegs; i++) {
00231 GLuint j;
00232
00233 fullsrc = &fullinst->FullSrcRegisters[i];
00234 fullsrc->SrcRegister.File = map_register_file(
00235 inst->SrcReg[i].File,
00236 inst->SrcReg[i].Index,
00237 immediateMapping,
00238 indirectAccess );
00239 fullsrc->SrcRegister.Index = map_register_file_index(
00240 fullsrc->SrcRegister.File,
00241 inst->SrcReg[i].Index,
00242 inputMapping,
00243 outputMapping,
00244 immediateMapping,
00245 indirectAccess );
00246
00247
00248
00249 {
00250 GLuint swz[4];
00251 GLboolean extended = (inst->SrcReg[i].NegateBase != NEGATE_NONE &&
00252 inst->SrcReg[i].NegateBase != NEGATE_XYZW);
00253 for( j = 0; j < 4; j++ ) {
00254 swz[j] = GET_SWZ( inst->SrcReg[i].Swizzle, j );
00255 if (swz[j] > SWIZZLE_W)
00256 extended = GL_TRUE;
00257 }
00258 if (extended) {
00259 for (j = 0; j < 4; j++) {
00260 tgsi_util_set_src_register_extswizzle(&fullsrc->SrcRegisterExtSwz,
00261 swz[j], j);
00262 }
00263 }
00264 else {
00265 for (j = 0; j < 4; j++) {
00266 tgsi_util_set_src_register_swizzle(&fullsrc->SrcRegister,
00267 swz[j], j);
00268 }
00269 }
00270 }
00271
00272 if( inst->SrcReg[i].NegateBase == NEGATE_XYZW ) {
00273 fullsrc->SrcRegister.Negate = 1;
00274 }
00275 else if( inst->SrcReg[i].NegateBase != NEGATE_NONE ) {
00276 if( inst->SrcReg[i].NegateBase & NEGATE_X ) {
00277 fullsrc->SrcRegisterExtSwz.NegateX = 1;
00278 }
00279 if( inst->SrcReg[i].NegateBase & NEGATE_Y ) {
00280 fullsrc->SrcRegisterExtSwz.NegateY = 1;
00281 }
00282 if( inst->SrcReg[i].NegateBase & NEGATE_Z ) {
00283 fullsrc->SrcRegisterExtSwz.NegateZ = 1;
00284 }
00285 if( inst->SrcReg[i].NegateBase & NEGATE_W ) {
00286 fullsrc->SrcRegisterExtSwz.NegateW = 1;
00287 }
00288 }
00289
00290 if( inst->SrcReg[i].Abs ) {
00291 fullsrc->SrcRegisterExtMod.Absolute = 1;
00292 }
00293
00294 if( inst->SrcReg[i].NegateAbs ) {
00295 fullsrc->SrcRegisterExtMod.Negate = 1;
00296 }
00297
00298 if( inst->SrcReg[i].RelAddr ) {
00299 fullsrc->SrcRegister.Indirect = 1;
00300
00301 fullsrc->SrcRegisterInd.File = TGSI_FILE_ADDRESS;
00302 fullsrc->SrcRegisterInd.Index = 0;
00303 }
00304 }
00305
00306 switch( inst->Opcode ) {
00307 case OPCODE_ARL:
00308 fullinst->Instruction.Opcode = TGSI_OPCODE_ARL;
00309 break;
00310 case OPCODE_ABS:
00311 fullinst->Instruction.Opcode = TGSI_OPCODE_ABS;
00312 break;
00313 case OPCODE_ADD:
00314 fullinst->Instruction.Opcode = TGSI_OPCODE_ADD;
00315 break;
00316 case OPCODE_BGNLOOP:
00317 fullinst->Instruction.Opcode = TGSI_OPCODE_BGNLOOP2;
00318 fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;
00319 break;
00320 case OPCODE_BGNSUB:
00321 fullinst->Instruction.Opcode = TGSI_OPCODE_BGNSUB;
00322 *insideSubroutine = GL_TRUE;
00323 break;
00324 case OPCODE_BRA:
00325 fullinst->Instruction.Opcode = TGSI_OPCODE_BRA;
00326 break;
00327 case OPCODE_BRK:
00328 fullinst->Instruction.Opcode = TGSI_OPCODE_BRK;
00329 break;
00330 case OPCODE_CAL:
00331 fullinst->Instruction.Opcode = TGSI_OPCODE_CAL;
00332 fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;
00333 break;
00334 case OPCODE_CMP:
00335 fullinst->Instruction.Opcode = TGSI_OPCODE_CMP;
00336 break;
00337 case OPCODE_CONT:
00338 fullinst->Instruction.Opcode = TGSI_OPCODE_CONT;
00339 break;
00340 case OPCODE_COS:
00341 fullinst->Instruction.Opcode = TGSI_OPCODE_COS;
00342 break;
00343 case OPCODE_DDX:
00344 fullinst->Instruction.Opcode = TGSI_OPCODE_DDX;
00345 break;
00346 case OPCODE_DDY:
00347 fullinst->Instruction.Opcode = TGSI_OPCODE_DDY;
00348 break;
00349 case OPCODE_DP3:
00350 fullinst->Instruction.Opcode = TGSI_OPCODE_DP3;
00351 break;
00352 case OPCODE_DP4:
00353 fullinst->Instruction.Opcode = TGSI_OPCODE_DP4;
00354 break;
00355 case OPCODE_DPH:
00356 fullinst->Instruction.Opcode = TGSI_OPCODE_DPH;
00357 break;
00358 case OPCODE_DST:
00359 fullinst->Instruction.Opcode = TGSI_OPCODE_DST;
00360 break;
00361 case OPCODE_ELSE:
00362 fullinst->Instruction.Opcode = TGSI_OPCODE_ELSE;
00363 fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;
00364 break;
00365 case OPCODE_ENDIF:
00366 fullinst->Instruction.Opcode = TGSI_OPCODE_ENDIF;
00367 break;
00368 case OPCODE_ENDLOOP:
00369 fullinst->Instruction.Opcode = TGSI_OPCODE_ENDLOOP2;
00370 fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;
00371 break;
00372 case OPCODE_ENDSUB:
00373 fullinst->Instruction.Opcode = TGSI_OPCODE_ENDSUB;
00374 *insideSubroutine = GL_FALSE;
00375 break;
00376 case OPCODE_EX2:
00377 fullinst->Instruction.Opcode = TGSI_OPCODE_EX2;
00378 break;
00379 case OPCODE_EXP:
00380 fullinst->Instruction.Opcode = TGSI_OPCODE_EXP;
00381 break;
00382 case OPCODE_FLR:
00383 fullinst->Instruction.Opcode = TGSI_OPCODE_FLR;
00384 break;
00385 case OPCODE_FRC:
00386 fullinst->Instruction.Opcode = TGSI_OPCODE_FRC;
00387 break;
00388 case OPCODE_IF:
00389 fullinst->Instruction.Opcode = TGSI_OPCODE_IF;
00390 fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;
00391 break;
00392 case OPCODE_INT:
00393 fullinst->Instruction.Opcode = TGSI_OPCODE_INT;
00394 break;
00395 case OPCODE_KIL:
00396
00397 fullinst->Instruction.Opcode = TGSI_OPCODE_KIL;
00398 break;
00399 case OPCODE_KIL_NV:
00400
00401 assert(inst->DstReg.CondMask == COND_TR);
00402 fullinst->Instruction.Opcode = TGSI_OPCODE_KILP;
00403 break;
00404 case OPCODE_LG2:
00405 fullinst->Instruction.Opcode = TGSI_OPCODE_LG2;
00406 break;
00407 case OPCODE_LOG:
00408 fullinst->Instruction.Opcode = TGSI_OPCODE_LOG;
00409 break;
00410 case OPCODE_LIT:
00411 fullinst->Instruction.Opcode = TGSI_OPCODE_LIT;
00412 break;
00413 case OPCODE_LRP:
00414 fullinst->Instruction.Opcode = TGSI_OPCODE_LRP;
00415 break;
00416 case OPCODE_MAD:
00417 fullinst->Instruction.Opcode = TGSI_OPCODE_MAD;
00418 break;
00419 case OPCODE_MAX:
00420 fullinst->Instruction.Opcode = TGSI_OPCODE_MAX;
00421 break;
00422 case OPCODE_MIN:
00423 fullinst->Instruction.Opcode = TGSI_OPCODE_MIN;
00424 break;
00425 case OPCODE_MOV:
00426 fullinst->Instruction.Opcode = TGSI_OPCODE_MOV;
00427 break;
00428 case OPCODE_MUL:
00429 fullinst->Instruction.Opcode = TGSI_OPCODE_MUL;
00430 break;
00431 case OPCODE_NOISE1:
00432 fullinst->Instruction.Opcode = TGSI_OPCODE_NOISE1;
00433 break;
00434 case OPCODE_NOISE2:
00435 fullinst->Instruction.Opcode = TGSI_OPCODE_NOISE2;
00436 break;
00437 case OPCODE_NOISE3:
00438 fullinst->Instruction.Opcode = TGSI_OPCODE_NOISE3;
00439 break;
00440 case OPCODE_NOISE4:
00441 fullinst->Instruction.Opcode = TGSI_OPCODE_NOISE4;
00442 break;
00443 case OPCODE_NOP:
00444 fullinst->Instruction.Opcode = TGSI_OPCODE_NOP;
00445 break;
00446 case OPCODE_POW:
00447 fullinst->Instruction.Opcode = TGSI_OPCODE_POW;
00448 break;
00449 case OPCODE_RCP:
00450 fullinst->Instruction.Opcode = TGSI_OPCODE_RCP;
00451 break;
00452 case OPCODE_RET:
00453
00454
00455
00456 if (1 ) {
00457 fullinst->Instruction.Opcode = TGSI_OPCODE_RET;
00458 }
00459 else {
00460
00461 fullinst->Instruction.Opcode = TGSI_OPCODE_END;
00462 }
00463 break;
00464 case OPCODE_RSQ:
00465 fullinst->Instruction.Opcode = TGSI_OPCODE_RSQ;
00466
00467
00468
00469
00470 #if 0
00471 tgsi_util_set_full_src_register_sign_mode(
00472 &fullinst->FullSrcRegisters[0],
00473 TGSI_UTIL_SIGN_CLEAR );
00474 #endif
00475 break;
00476 case OPCODE_SCS:
00477 fullinst->Instruction.Opcode = TGSI_OPCODE_SCS;
00478 fulldst->DstRegister.WriteMask &= TGSI_WRITEMASK_XY;
00479 break;
00480 case OPCODE_SEQ:
00481 fullinst->Instruction.Opcode = TGSI_OPCODE_SEQ;
00482 break;
00483 case OPCODE_SGE:
00484 fullinst->Instruction.Opcode = TGSI_OPCODE_SGE;
00485 break;
00486 case OPCODE_SGT:
00487 fullinst->Instruction.Opcode = TGSI_OPCODE_SGT;
00488 break;
00489 case OPCODE_SIN:
00490 fullinst->Instruction.Opcode = TGSI_OPCODE_SIN;
00491 break;
00492 case OPCODE_SLE:
00493 fullinst->Instruction.Opcode = TGSI_OPCODE_SLE;
00494 break;
00495 case OPCODE_SLT:
00496 fullinst->Instruction.Opcode = TGSI_OPCODE_SLT;
00497 break;
00498 case OPCODE_SNE:
00499 fullinst->Instruction.Opcode = TGSI_OPCODE_SNE;
00500 break;
00501 case OPCODE_SUB:
00502 fullinst->Instruction.Opcode = TGSI_OPCODE_SUB;
00503 break;
00504 case OPCODE_SWZ:
00505 fullinst->Instruction.Opcode = TGSI_OPCODE_SWZ;
00506 break;
00507 case OPCODE_TEX:
00508
00509 fullinst->Instruction.Opcode = TGSI_OPCODE_TEX;
00510 fullinst->Instruction.NumSrcRegs = 2;
00511 fullinst->InstructionExtTexture.Texture = map_texture_target( inst->TexSrcTarget );
00512 fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
00513 fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;
00514 break;
00515 case OPCODE_TXB:
00516
00517 fullinst->Instruction.Opcode = TGSI_OPCODE_TXB;
00518 fullinst->Instruction.NumSrcRegs = 2;
00519 fullinst->InstructionExtTexture.Texture = map_texture_target( inst->TexSrcTarget );
00520 fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
00521 fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;
00522 break;
00523 case OPCODE_TXD:
00524
00525 fullinst->Instruction.Opcode = TGSI_OPCODE_TXD;
00526 fullinst->Instruction.NumSrcRegs = 4;
00527 fullinst->InstructionExtTexture.Texture = map_texture_target( inst->TexSrcTarget );
00528
00529 fullinst->FullSrcRegisters[3].SrcRegister.File = TGSI_FILE_SAMPLER;
00530 fullinst->FullSrcRegisters[3].SrcRegister.Index = inst->TexSrcUnit;
00531 break;
00532 case OPCODE_TXL:
00533
00534 fullinst->Instruction.Opcode = TGSI_OPCODE_TXL;
00535 fullinst->Instruction.NumSrcRegs = 2;
00536 fullinst->InstructionExtTexture.Texture = map_texture_target( inst->TexSrcTarget );
00537 fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
00538 fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;
00539 break;
00540 case OPCODE_TXP:
00541
00542
00543 fullinst->Instruction.Opcode = TGSI_OPCODE_TXP;
00544 fullinst->Instruction.NumSrcRegs = 2;
00545 fullinst->InstructionExtTexture.Texture = map_texture_target( inst->TexSrcTarget );
00546 fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
00547 fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;
00548 break;
00549 case OPCODE_XPD:
00550 fullinst->Instruction.Opcode = TGSI_OPCODE_XPD;
00551 fulldst->DstRegister.WriteMask &= TGSI_WRITEMASK_XYZ;
00552 break;
00553 case OPCODE_END:
00554 fullinst->Instruction.Opcode = TGSI_OPCODE_END;
00555 break;
00556 default:
00557 assert( 0 );
00558 }
00559 }
00560
00564 static struct tgsi_full_declaration
00565 make_input_decl(
00566 GLuint index,
00567 GLboolean interpolate_info,
00568 GLuint interpolate,
00569 GLuint usage_mask,
00570 GLboolean semantic_info,
00571 GLuint semantic_name,
00572 GLbitfield semantic_index,
00573 GLbitfield input_flags)
00574 {
00575 struct tgsi_full_declaration decl;
00576
00577 assert(semantic_name < TGSI_SEMANTIC_COUNT);
00578
00579 decl = tgsi_default_full_declaration();
00580 decl.Declaration.File = TGSI_FILE_INPUT;
00581 decl.Declaration.UsageMask = usage_mask;
00582 decl.Declaration.Semantic = semantic_info;
00583 decl.DeclarationRange.First = index;
00584 decl.DeclarationRange.Last = index;
00585 if (semantic_info) {
00586 decl.Semantic.SemanticName = semantic_name;
00587 decl.Semantic.SemanticIndex = semantic_index;
00588 }
00589 if (interpolate_info) {
00590 decl.Declaration.Interpolate = interpolate;
00591 }
00592 if (input_flags & PROG_PARAM_BIT_CENTROID)
00593 decl.Declaration.Centroid = 1;
00594 if (input_flags & PROG_PARAM_BIT_INVARIANT)
00595 decl.Declaration.Invariant = 1;
00596
00597 return decl;
00598 }
00599
00603 static struct tgsi_full_declaration
00604 make_output_decl(
00605 GLuint index,
00606 GLuint semantic_name,
00607 GLuint semantic_index,
00608 GLuint usage_mask,
00609 GLbitfield output_flags)
00610 {
00611 struct tgsi_full_declaration decl;
00612
00613 assert(semantic_name < TGSI_SEMANTIC_COUNT);
00614
00615 decl = tgsi_default_full_declaration();
00616 decl.Declaration.File = TGSI_FILE_OUTPUT;
00617 decl.Declaration.UsageMask = usage_mask;
00618 decl.Declaration.Semantic = 1;
00619 decl.DeclarationRange.First = index;
00620 decl.DeclarationRange.Last = index;
00621 decl.Semantic.SemanticName = semantic_name;
00622 decl.Semantic.SemanticIndex = semantic_index;
00623 if (output_flags & PROG_PARAM_BIT_CENTROID)
00624 decl.Declaration.Centroid = 1;
00625 if (output_flags & PROG_PARAM_BIT_INVARIANT)
00626 decl.Declaration.Invariant = 1;
00627
00628 return decl;
00629 }
00630
00631
00632 static struct tgsi_full_declaration
00633 make_temp_decl(
00634 GLuint start_index,
00635 GLuint end_index )
00636 {
00637 struct tgsi_full_declaration decl;
00638 decl = tgsi_default_full_declaration();
00639 decl.Declaration.File = TGSI_FILE_TEMPORARY;
00640 decl.DeclarationRange.First = start_index;
00641 decl.DeclarationRange.Last = end_index;
00642 return decl;
00643 }
00644
00645 static struct tgsi_full_declaration
00646 make_addr_decl(
00647 GLuint start_index,
00648 GLuint end_index )
00649 {
00650 struct tgsi_full_declaration decl;
00651
00652 decl = tgsi_default_full_declaration();
00653 decl.Declaration.File = TGSI_FILE_ADDRESS;
00654 decl.DeclarationRange.First = start_index;
00655 decl.DeclarationRange.Last = end_index;
00656 return decl;
00657 }
00658
00659 static struct tgsi_full_declaration
00660 make_sampler_decl(GLuint index)
00661 {
00662 struct tgsi_full_declaration decl;
00663 decl = tgsi_default_full_declaration();
00664 decl.Declaration.File = TGSI_FILE_SAMPLER;
00665 decl.DeclarationRange.First = index;
00666 decl.DeclarationRange.Last = index;
00667 return decl;
00668 }
00669
00671 static struct tgsi_full_declaration
00672 make_constant_decl(GLuint first, GLuint last)
00673 {
00674 struct tgsi_full_declaration decl;
00675 decl = tgsi_default_full_declaration();
00676 decl.Declaration.File = TGSI_FILE_CONSTANT;
00677 decl.DeclarationRange.First = first;
00678 decl.DeclarationRange.Last = last;
00679 return decl;
00680 }
00681
00682
00683
00687 static void
00688 find_temporaries(const struct gl_program *program,
00689 GLboolean tempsUsed[MAX_PROGRAM_TEMPS])
00690 {
00691 GLuint i, j;
00692
00693 for (i = 0; i < MAX_PROGRAM_TEMPS; i++)
00694 tempsUsed[i] = GL_FALSE;
00695
00696 for (i = 0; i < program->NumInstructions; i++) {
00697 const struct prog_instruction *inst = program->Instructions + i;
00698 const GLuint n = _mesa_num_inst_src_regs( inst->Opcode );
00699 for (j = 0; j < n; j++) {
00700 if (inst->SrcReg[j].File == PROGRAM_TEMPORARY)
00701 tempsUsed[inst->SrcReg[j].Index] = GL_TRUE;
00702 if (inst->DstReg.File == PROGRAM_TEMPORARY)
00703 tempsUsed[inst->DstReg.Index] = GL_TRUE;
00704 }
00705 }
00706 }
00707
00708
00709
00710
00731 GLuint
00732 st_translate_mesa_program(
00733 uint procType,
00734 const struct gl_program *program,
00735 GLuint numInputs,
00736 const GLuint inputMapping[],
00737 const ubyte inputSemanticName[],
00738 const ubyte inputSemanticIndex[],
00739 const GLuint interpMode[],
00740 const GLbitfield inputFlags[],
00741 GLuint numOutputs,
00742 const GLuint outputMapping[],
00743 const ubyte outputSemanticName[],
00744 const ubyte outputSemanticIndex[],
00745 const GLbitfield outputFlags[],
00746 struct tgsi_token *tokens,
00747 GLuint maxTokens )
00748 {
00749 GLuint i;
00750 GLuint ti;
00751 struct tgsi_header *header;
00752 struct tgsi_processor *processor;
00753 struct tgsi_full_instruction fullinst;
00754 GLuint preamble_size = 0;
00755 GLuint immediates[1000];
00756 GLuint numImmediates = 0;
00757 GLboolean insideSubroutine = GL_FALSE;
00758 GLboolean indirectAccess = GL_FALSE;
00759
00760 assert(procType == TGSI_PROCESSOR_FRAGMENT ||
00761 procType == TGSI_PROCESSOR_VERTEX);
00762
00763 *(struct tgsi_version *) &tokens[0] = tgsi_build_version();
00764
00765 header = (struct tgsi_header *) &tokens[1];
00766 *header = tgsi_build_header();
00767
00768 processor = (struct tgsi_processor *) &tokens[2];
00769 *processor = tgsi_build_processor( procType, header );
00770
00771 ti = 3;
00772
00773
00774
00775
00776 if (procType == TGSI_PROCESSOR_FRAGMENT) {
00777 for (i = 0; i < numInputs; i++) {
00778 struct tgsi_full_declaration fulldecl;
00779 fulldecl = make_input_decl(i,
00780 GL_TRUE, interpMode[i],
00781 TGSI_WRITEMASK_XYZW,
00782 GL_TRUE, inputSemanticName[i],
00783 inputSemanticIndex[i],
00784 inputFlags[i]);
00785 ti += tgsi_build_full_declaration(&fulldecl,
00786 &tokens[ti],
00787 header,
00788 maxTokens - ti );
00789 }
00790 }
00791 else {
00792
00793
00794
00795
00796 for (i = 0; i < numInputs; i++) {
00797 struct tgsi_full_declaration fulldecl;
00798 fulldecl = make_input_decl(i,
00799 GL_FALSE, 0,
00800 TGSI_WRITEMASK_XYZW,
00801 GL_FALSE, 0, 0,
00802 inputFlags[i]);
00803 ti += tgsi_build_full_declaration(&fulldecl,
00804 &tokens[ti],
00805 header,
00806 maxTokens - ti );
00807 }
00808 }
00809
00810
00811
00812
00813 if (procType == TGSI_PROCESSOR_FRAGMENT) {
00814 for (i = 0; i < numOutputs; i++) {
00815 struct tgsi_full_declaration fulldecl;
00816 switch (outputSemanticName[i]) {
00817 case TGSI_SEMANTIC_POSITION:
00818 fulldecl = make_output_decl(i,
00819 TGSI_SEMANTIC_POSITION,
00820 outputSemanticIndex[i],
00821 TGSI_WRITEMASK_Z,
00822 outputFlags[i]);
00823 break;
00824 case TGSI_SEMANTIC_COLOR:
00825 fulldecl = make_output_decl(i,
00826 TGSI_SEMANTIC_COLOR,
00827 outputSemanticIndex[i],
00828 TGSI_WRITEMASK_XYZW,
00829 outputFlags[i]);
00830 break;
00831 default:
00832 assert(0);
00833 return 0;
00834 }
00835 ti += tgsi_build_full_declaration(&fulldecl,
00836 &tokens[ti],
00837 header,
00838 maxTokens - ti );
00839 }
00840 }
00841 else {
00842
00843 for (i = 0; i < numOutputs; i++) {
00844 struct tgsi_full_declaration fulldecl;
00845 fulldecl = make_output_decl(i,
00846 outputSemanticName[i],
00847 outputSemanticIndex[i],
00848 TGSI_WRITEMASK_XYZW,
00849 outputFlags[i]);
00850 ti += tgsi_build_full_declaration(&fulldecl,
00851 &tokens[ti],
00852 header,
00853 maxTokens - ti );
00854 }
00855 }
00856
00857
00858 {
00859 GLboolean tempsUsed[MAX_PROGRAM_TEMPS + 1];
00860 GLboolean inside_range = GL_FALSE;
00861 GLuint start_range = 0;
00862
00863 find_temporaries(program, tempsUsed);
00864 tempsUsed[MAX_PROGRAM_TEMPS] = GL_FALSE;
00865 for (i = 0; i < MAX_PROGRAM_TEMPS + 1; i++) {
00866 if (tempsUsed[i] && !inside_range) {
00867 inside_range = GL_TRUE;
00868 start_range = i;
00869 }
00870 else if (!tempsUsed[i] && inside_range) {
00871 struct tgsi_full_declaration fulldecl;
00872
00873 inside_range = GL_FALSE;
00874 fulldecl = make_temp_decl( start_range, i - 1 );
00875 ti += tgsi_build_full_declaration(
00876 &fulldecl,
00877 &tokens[ti],
00878 header,
00879 maxTokens - ti );
00880 }
00881 }
00882 }
00883
00884
00885
00886 if (program->NumAddressRegs > 0) {
00887 struct tgsi_full_declaration fulldecl;
00888
00889 assert( program->NumAddressRegs == 1 );
00890
00891 fulldecl = make_addr_decl( 0, 0 );
00892 ti += tgsi_build_full_declaration(
00893 &fulldecl,
00894 &tokens[ti],
00895 header,
00896 maxTokens - ti );
00897
00898 indirectAccess = GL_TRUE;
00899 }
00900
00901
00902 memset(immediates, ~0, sizeof(immediates));
00903
00904
00905
00906
00907
00908 if (program->Parameters && !indirectAccess) {
00909 for (i = 0; i < program->Parameters->NumParameters; i++) {
00910 if (program->Parameters->Parameters[i].Type == PROGRAM_CONSTANT) {
00911 struct tgsi_full_immediate fullimm;
00912
00913 fullimm = make_immediate( program->Parameters->ParameterValues[i], 4 );
00914 ti += tgsi_build_full_immediate(
00915 &fullimm,
00916 &tokens[ti],
00917 header,
00918 maxTokens - ti );
00919 immediates[i] = numImmediates;
00920 numImmediates++;
00921 }
00922 }
00923 }
00924
00925
00926 if (program->Parameters) {
00927 GLint start = -1, end = -1;
00928
00929 for (i = 0; i < program->Parameters->NumParameters; i++) {
00930 GLboolean emit = (i == program->Parameters->NumParameters - 1);
00931 GLboolean matches;
00932
00933 switch (program->Parameters->Parameters[i].Type) {
00934 case PROGRAM_ENV_PARAM:
00935 case PROGRAM_STATE_VAR:
00936 case PROGRAM_NAMED_PARAM:
00937 case PROGRAM_UNIFORM:
00938 matches = GL_TRUE;
00939 break;
00940 case PROGRAM_CONSTANT:
00941 matches = indirectAccess;
00942 break;
00943 default:
00944 matches = GL_FALSE;
00945 }
00946
00947 if (matches) {
00948 if (start == -1) {
00949
00950 start = i;
00951 end = i;
00952 }
00953 else {
00954
00955 end = i;
00956 }
00957 }
00958 else {
00959 if (start != -1) {
00960
00961 emit = GL_TRUE;
00962 }
00963 }
00964
00965 if (emit && start >= 0) {
00966 struct tgsi_full_declaration fulldecl;
00967
00968 fulldecl = make_constant_decl( start, end );
00969 ti += tgsi_build_full_declaration(
00970 &fulldecl,
00971 &tokens[ti],
00972 header,
00973 maxTokens - ti );
00974 start = end = -1;
00975 }
00976 }
00977 }
00978
00979
00980 for (i = 0; i < 8; i++) {
00981 if (program->SamplersUsed & (1 << i)) {
00982 struct tgsi_full_declaration fulldecl;
00983
00984 fulldecl = make_sampler_decl( i );
00985 ti += tgsi_build_full_declaration(
00986 &fulldecl,
00987 &tokens[ti],
00988 header,
00989 maxTokens - ti );
00990 }
00991 }
00992
00993 for (i = 0; i < program->NumInstructions; i++) {
00994 compile_instruction(
00995 &program->Instructions[i],
00996 &fullinst,
00997 inputMapping,
00998 outputMapping,
00999 immediates,
01000 indirectAccess,
01001 preamble_size,
01002 procType,
01003 &insideSubroutine );
01004
01005 ti += tgsi_build_full_instruction(
01006 &fullinst,
01007 &tokens[ti],
01008 header,
01009 maxTokens - ti );
01010 }
01011
01012 #if DEBUG
01013 if(!tgsi_sanity_check(tokens)) {
01014 debug_printf("Due to sanity check failure(s) above the following shader program is invalid:\n");
01015 debug_printf("\nOriginal program:\n%s", program->String);
01016 debug_printf("\nMesa program:\n");
01017 _mesa_print_program(program);
01018 debug_printf("\nTGSI program:\n");
01019 tgsi_dump(tokens, 0);
01020 assert(0);
01021 }
01022 #endif
01023
01024 return ti;
01025 }