+++ /dev/null
-#include "tgsi_platform.h"\r
-#include "tgsi_mesa.h"\r
-#include "pipe/tgsi/mesa/mesa_to_tgsi.h"\r
-#include "shader/prog_parameter.h"\r
-\r
-#define TGSI_DEBUG 0\r
-\r
-#define EMIT_IMMEDIATES 0\r
-\r
-\r
-/*\r
- * Map mesa register file to TGSI register file.\r
- */\r
-static GLuint\r
-map_register_file(\r
- enum register_file file )\r
-{\r
- switch( file ) {\r
- case PROGRAM_UNDEFINED:\r
- return TGSI_FILE_NULL;\r
- case PROGRAM_TEMPORARY:\r
- return TGSI_FILE_TEMPORARY;\r
- //case PROGRAM_LOCAL_PARAM:\r
- //case PROGRAM_ENV_PARAM:\r
- case PROGRAM_STATE_VAR:\r
- case PROGRAM_NAMED_PARAM:\r
- case PROGRAM_UNIFORM:\r
- return TGSI_FILE_CONSTANT;\r
- case PROGRAM_CONSTANT:\r
-#if EMIT_IMMEDIATES\r
- return TGSI_FILE_IMMEDIATE;\r
-#else\r
- return TGSI_FILE_CONSTANT;\r
-#endif\r
- case PROGRAM_INPUT:\r
- return TGSI_FILE_INPUT;\r
- case PROGRAM_OUTPUT:\r
- return TGSI_FILE_OUTPUT;\r
- case PROGRAM_ADDRESS:\r
- return TGSI_FILE_ADDRESS;\r
- default:\r
- assert( 0 );\r
- return TGSI_FILE_NULL;\r
- }\r
-}\r
-\r
-/**\r
- * Map mesa register file index to TGSI index.\r
- * Take special care when processing input and output indices.\r
- * \param file one of TGSI_FILE_x\r
- * \param index the mesa register file index\r
- * \param inputMapping maps Mesa input indexes to TGSI input indexes\r
- * \param outputMapping maps Mesa output indexes to TGSI output indexes\r
- */\r
-static GLuint\r
-map_register_file_index(\r
- GLuint file,\r
- GLuint index,\r
- const GLuint inputMapping[],\r
- const GLuint outputMapping[],\r
- const GLuint immediateMapping[])\r
-{\r
- switch( file ) {\r
- case TGSI_FILE_INPUT:\r
- /* inputs are mapped according to the user-defined map */\r
- return inputMapping[index];\r
-\r
- case TGSI_FILE_OUTPUT:\r
- return outputMapping[index];\r
-\r
-#if EMIT_IMMEDIATES\r
- case TGSI_FILE_IMMEDIATE:\r
- return immediateMapping[index];\r
-#endif\r
-\r
- default:\r
- return index;\r
- }\r
-}\r
-\r
-/*\r
- * Map mesa texture target to TGSI texture target.\r
- */\r
-static GLuint\r
-map_texture_target(\r
- GLuint textarget )\r
-{\r
- switch( textarget ) {\r
- case TEXTURE_1D_INDEX:\r
- return TGSI_TEXTURE_1D;\r
- case TEXTURE_2D_INDEX:\r
- return TGSI_TEXTURE_2D;\r
- case TEXTURE_3D_INDEX:\r
- return TGSI_TEXTURE_3D;\r
- case TEXTURE_CUBE_INDEX:\r
- return TGSI_TEXTURE_CUBE;\r
- case TEXTURE_RECT_INDEX:\r
- return TGSI_TEXTURE_RECT;\r
- default:\r
- assert( 0 );\r
- }\r
-\r
- return TGSI_TEXTURE_1D;\r
-}\r
-\r
-static GLuint\r
-convert_sat(\r
- GLuint sat )\r
-{\r
- switch( sat ) {\r
- case SATURATE_OFF:\r
- return TGSI_SAT_NONE;\r
- case SATURATE_ZERO_ONE:\r
- return TGSI_SAT_ZERO_ONE;\r
- case SATURATE_PLUS_MINUS_ONE:\r
- return TGSI_SAT_MINUS_PLUS_ONE;\r
- default:\r
- assert( 0 );\r
- return TGSI_SAT_NONE;\r
- }\r
-}\r
-\r
-static GLuint\r
-convert_writemask(\r
- GLuint writemask )\r
-{\r
- assert( WRITEMASK_X == TGSI_WRITEMASK_X );\r
- assert( WRITEMASK_Y == TGSI_WRITEMASK_Y );\r
- assert( WRITEMASK_Z == TGSI_WRITEMASK_Z );\r
- assert( WRITEMASK_W == TGSI_WRITEMASK_W );\r
- assert( (writemask & ~TGSI_WRITEMASK_XYZW) == 0 );\r
-\r
- return writemask;\r
-}\r
-\r
-#if EMIT_IMMEDIATES\r
-static struct tgsi_full_immediate\r
-make_immediate(const float *value, uint size)\r
-{\r
- struct tgsi_full_immediate imm;\r
- imm.Immediate.Type = TGSI_TOKEN_TYPE_IMMEDIATE;\r
- imm.Immediate.Size = 1 + size; /* one for the token itself */\r
- imm.Immediate.DataType = TGSI_IMM_FLOAT32;\r
- imm.u.ImmediateFloat32 = (struct tgsi_immediate_float32 *) value;\r
- return imm;\r
-}\r
-#endif\r
-\r
-static void\r
-compile_instruction(\r
- const struct prog_instruction *inst,\r
- struct tgsi_full_instruction *fullinst,\r
- const GLuint inputMapping[],\r
- const GLuint outputMapping[],\r
- const GLuint immediateMapping[],\r
- GLuint preamble_size,\r
- GLuint processor )\r
-{\r
- GLuint i;\r
- struct tgsi_full_dst_register *fulldst;\r
- struct tgsi_full_src_register *fullsrc;\r
-\r
- *fullinst = tgsi_default_full_instruction();\r
-\r
- fullinst->Instruction.Saturate = convert_sat( inst->SaturateMode );\r
- fullinst->Instruction.NumDstRegs = _mesa_num_inst_dst_regs( inst->Opcode );\r
- fullinst->Instruction.NumSrcRegs = _mesa_num_inst_src_regs( inst->Opcode );\r
-\r
- fulldst = &fullinst->FullDstRegisters[0];\r
- fulldst->DstRegister.File = map_register_file( inst->DstReg.File );\r
- fulldst->DstRegister.Index = map_register_file_index(\r
- fulldst->DstRegister.File,\r
- inst->DstReg.Index,\r
- inputMapping,\r
- outputMapping,\r
- NULL\r
- );\r
- fulldst->DstRegister.WriteMask = convert_writemask( inst->DstReg.WriteMask );\r
-\r
- for( i = 0; i < fullinst->Instruction.NumSrcRegs; i++ ) {\r
- GLuint j;\r
-\r
- fullsrc = &fullinst->FullSrcRegisters[i];\r
- fullsrc->SrcRegister.File = map_register_file( inst->SrcReg[i].File );\r
- fullsrc->SrcRegister.Index = map_register_file_index(\r
- fullsrc->SrcRegister.File,\r
- inst->SrcReg[i].Index,\r
- inputMapping,\r
- outputMapping,\r
- immediateMapping);\r
-\r
- for( j = 0; j < 4; j++ ) {\r
- GLuint swz;\r
-\r
- swz = GET_SWZ( inst->SrcReg[i].Swizzle, j );\r
- if( swz > SWIZZLE_W ) {\r
- tgsi_util_set_src_register_extswizzle(\r
- &fullsrc->SrcRegisterExtSwz,\r
- swz,\r
- j );\r
- }\r
- else {\r
- tgsi_util_set_src_register_swizzle(\r
- &fullsrc->SrcRegister,\r
- swz,\r
- j );\r
- }\r
- }\r
-\r
- if( inst->SrcReg[i].NegateBase == NEGATE_XYZW ) {\r
- fullsrc->SrcRegister.Negate = 1;\r
- }\r
- else if( inst->SrcReg[i].NegateBase != NEGATE_NONE ) {\r
- if( inst->SrcReg[i].NegateBase & NEGATE_X ) {\r
- fullsrc->SrcRegisterExtSwz.NegateX = 1;\r
- }\r
- if( inst->SrcReg[i].NegateBase & NEGATE_Y ) {\r
- fullsrc->SrcRegisterExtSwz.NegateY = 1;\r
- }\r
- if( inst->SrcReg[i].NegateBase & NEGATE_Z ) {\r
- fullsrc->SrcRegisterExtSwz.NegateZ = 1;\r
- }\r
- if( inst->SrcReg[i].NegateBase & NEGATE_W ) {\r
- fullsrc->SrcRegisterExtSwz.NegateW = 1;\r
- }\r
- }\r
-\r
- if( inst->SrcReg[i].Abs ) {\r
- fullsrc->SrcRegisterExtMod.Absolute = 1;\r
- }\r
-\r
- if( inst->SrcReg[i].NegateAbs ) {\r
- fullsrc->SrcRegisterExtMod.Negate = 1;\r
- }\r
-\r
- if( inst->SrcReg[i].RelAddr ) {\r
- fullsrc->SrcRegister.Indirect = 1;\r
-\r
- fullsrc->SrcRegisterInd.File = TGSI_FILE_ADDRESS;\r
- fullsrc->SrcRegisterInd.Index = 0;\r
- }\r
- }\r
-\r
- switch( inst->Opcode ) {\r
- case OPCODE_ARL:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_ARL;\r
- break;\r
- case OPCODE_ABS:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_ABS;\r
- break;\r
- case OPCODE_ADD:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_ADD;\r
- break;\r
- case OPCODE_BGNLOOP:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_BGNLOOP2;\r
- fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;\r
- break;\r
- case OPCODE_BGNSUB:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_BGNSUB;\r
- break;\r
- case OPCODE_BRA:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_BRA;\r
- break;\r
- case OPCODE_BRK:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_BRK;\r
- break;\r
- case OPCODE_CAL:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_CAL;\r
- fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;\r
- break;\r
- case OPCODE_CMP:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_CMP;\r
- break;\r
- case OPCODE_CONT:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_CONT;\r
- break;\r
- case OPCODE_COS:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_COS;\r
- break;\r
- case OPCODE_DDX:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_DDX;\r
- break;\r
- case OPCODE_DDY:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_DDY;\r
- break;\r
- case OPCODE_DP3:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_DP3;\r
- break;\r
- case OPCODE_DP4:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_DP4;\r
- break;\r
- case OPCODE_DPH:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_DPH;\r
- break;\r
- case OPCODE_DST:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_DST;\r
- break;\r
- case OPCODE_ELSE:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_ELSE;\r
- fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;\r
- break;\r
- case OPCODE_ENDIF:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_ENDIF;\r
- break;\r
- case OPCODE_ENDLOOP:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_ENDLOOP2;\r
- fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;\r
- break;\r
- case OPCODE_ENDSUB:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_ENDSUB;\r
- break;\r
- case OPCODE_EX2:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_EX2;\r
- break;\r
- case OPCODE_EXP:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_EXP;\r
- break;\r
- case OPCODE_FLR:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_FLR;\r
- break;\r
- case OPCODE_FRC:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_FRC;\r
- break;\r
- case OPCODE_IF:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_IF;\r
- fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;\r
- break;\r
- case OPCODE_INT:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_INT;\r
- break;\r
- case OPCODE_KIL:\r
- /* predicated w/ a register */\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_KILP;\r
- break;\r
- case OPCODE_KIL_NV:\r
- /* unpredicated */\r
- assert(inst->DstReg.CondMask == COND_TR);\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_KIL;\r
- break;\r
- case OPCODE_LG2:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_LG2;\r
- break;\r
- case OPCODE_LOG:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_LOG;\r
- break;\r
- case OPCODE_LIT:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_LIT;\r
- break;\r
- case OPCODE_LRP:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_LRP;\r
- break;\r
- case OPCODE_MAD:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_MAD;\r
- break;\r
- case OPCODE_MAX:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_MAX;\r
- break;\r
- case OPCODE_MIN:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_MIN;\r
- break;\r
- case OPCODE_MOV:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_MOV;\r
- break;\r
- case OPCODE_MUL:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_MUL;\r
- break;\r
- case OPCODE_NOISE1:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_NOISE1;\r
- break;\r
- case OPCODE_NOISE2:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_NOISE2;\r
- break;\r
- case OPCODE_NOISE3:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_NOISE3;\r
- break;\r
- case OPCODE_NOISE4:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_NOISE4;\r
- break;\r
- case OPCODE_NOP:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_NOP;\r
- break;\r
- case OPCODE_POW:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_POW;\r
- break;\r
- case OPCODE_RCP:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_RCP;\r
- break;\r
- case OPCODE_RET:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_RET;\r
- break;\r
- case OPCODE_RSQ:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_RSQ;\r
- tgsi_util_set_full_src_register_sign_mode(\r
- &fullinst->FullSrcRegisters[0],\r
- TGSI_UTIL_SIGN_CLEAR );\r
- break;\r
- case OPCODE_SCS:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_SCS;\r
- fulldst->DstRegister.WriteMask &= TGSI_WRITEMASK_XY;\r
- break;\r
- case OPCODE_SEQ:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_SEQ;\r
- break;\r
- case OPCODE_SGE:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_SGE;\r
- break;\r
- case OPCODE_SGT:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_SGT;\r
- break;\r
- case OPCODE_SIN:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_SIN;\r
- break;\r
- case OPCODE_SLE:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_SLE;\r
- break;\r
- case OPCODE_SLT:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_SLT;\r
- break;\r
- case OPCODE_SNE:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_SNE;\r
- break;\r
- case OPCODE_SUB:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_SUB;\r
- break;\r
- case OPCODE_SWZ:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_SWZ;\r
- break;\r
- case OPCODE_TEX:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_TEX;\r
- fullinst->Instruction.NumSrcRegs = 2;\r
- fullinst->InstructionExtTexture.Texture = map_texture_target( inst->TexSrcTarget );\r
- fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;\r
- fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;\r
- break;\r
- case OPCODE_TXB:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_TXB;\r
- fullinst->Instruction.NumSrcRegs = 2;\r
- fullinst->InstructionExtTexture.Texture = map_texture_target( inst->TexSrcTarget );\r
- fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;\r
- fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;\r
- break;\r
- case OPCODE_TXD:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_TXD;\r
- fullinst->Instruction.NumSrcRegs = 2;\r
- fullinst->InstructionExtTexture.Texture = map_texture_target( inst->TexSrcTarget );\r
- fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;\r
- fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;\r
- break;\r
- case OPCODE_TXL:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_TXL;\r
- fullinst->Instruction.NumSrcRegs = 2;\r
- fullinst->InstructionExtTexture.Texture = map_texture_target( inst->TexSrcTarget );\r
- fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;\r
- fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;\r
- break;\r
- case OPCODE_TXP:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_TEX;\r
- fullinst->Instruction.NumSrcRegs = 2;\r
- fullinst->InstructionExtTexture.Texture = map_texture_target( inst->TexSrcTarget );\r
- fullinst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide = TGSI_EXTSWIZZLE_W;\r
- fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;\r
- fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;\r
- break;\r
- case OPCODE_XPD:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_XPD;\r
- fulldst->DstRegister.WriteMask &= TGSI_WRITEMASK_XYZ;\r
- break;\r
- case OPCODE_END:\r
- fullinst->Instruction.Opcode = TGSI_OPCODE_RET;\r
- break;\r
- default:\r
- assert( 0 );\r
- }\r
-}\r
-\r
-/**\r
- * \param usage_mask bitfield of TGSI_WRITEMASK_{XYZW} tokens\r
- */\r
-static struct tgsi_full_declaration\r
-make_input_decl(\r
- GLuint index,\r
- GLuint interpolate,\r
- GLuint usage_mask,\r
- GLboolean semantic_info,\r
- GLuint semantic_name,\r
- GLbitfield semantic_index )\r
-{\r
- struct tgsi_full_declaration decl;\r
-\r
- assert(semantic_name < TGSI_SEMANTIC_COUNT);\r
-\r
- decl = tgsi_default_full_declaration();\r
- decl.Declaration.File = TGSI_FILE_INPUT;\r
- decl.Declaration.Declare = TGSI_DECLARE_RANGE;\r
- decl.Declaration.UsageMask = usage_mask;\r
- decl.Declaration.Semantic = semantic_info;\r
- decl.Declaration.Interpolate = 1;\r
- decl.u.DeclarationRange.First = index;\r
- decl.u.DeclarationRange.Last = index;\r
- if (semantic_info) {\r
- decl.Semantic.SemanticName = semantic_name;\r
- decl.Semantic.SemanticIndex = semantic_index;\r
- }\r
- decl.Interpolation.Interpolate = interpolate;\r
-\r
- return decl;\r
-}\r
-\r
-/**\r
- * \param usage_mask bitfield of TGSI_WRITEMASK_{XYZW} tokens\r
- */\r
-static struct tgsi_full_declaration\r
-make_output_decl(\r
- GLuint index,\r
- GLuint semantic_name,\r
- GLuint semantic_index,\r
- GLbitfield usage_mask )\r
-{\r
- struct tgsi_full_declaration decl;\r
-\r
- assert(semantic_name < TGSI_SEMANTIC_COUNT);\r
-\r
- decl = tgsi_default_full_declaration();\r
- decl.Declaration.File = TGSI_FILE_OUTPUT;\r
- decl.Declaration.Declare = TGSI_DECLARE_RANGE;\r
- decl.Declaration.UsageMask = usage_mask;\r
- decl.Declaration.Semantic = 1;\r
- decl.u.DeclarationRange.First = index;\r
- decl.u.DeclarationRange.Last = index;\r
- decl.Semantic.SemanticName = semantic_name;\r
- decl.Semantic.SemanticIndex = semantic_index;\r
-\r
- return decl;\r
-}\r
-\r
-\r
-static struct tgsi_full_declaration\r
-make_temp_decl(GLuint index)\r
-{\r
- struct tgsi_full_declaration decl;\r
- decl = tgsi_default_full_declaration();\r
- decl.Declaration.File = TGSI_FILE_TEMPORARY;\r
- decl.Declaration.Declare = TGSI_DECLARE_RANGE;\r
- decl.u.DeclarationRange.First = index;\r
- decl.u.DeclarationRange.Last = index;\r
- return decl;\r
-}\r
-\r
-\r
-/**\r
- * Find the temporaries which are used in the given program.\r
- * Put the indices of the temporaries in 'tempsUsed'.\r
- * \return number of temporaries used\r
- */\r
-static GLuint\r
-find_temporaries(const struct gl_program *program,\r
- GLuint tempsUsed[MAX_PROGRAM_TEMPS])\r
-{\r
- GLuint i, j, count;\r
-\r
- for (i = 0; i < MAX_PROGRAM_TEMPS; i++)\r
- tempsUsed[i] = GL_FALSE;\r
-\r
- for (i = 0; i < program->NumInstructions; i++) {\r
- const struct prog_instruction *inst = program->Instructions + i;\r
- const GLuint n = _mesa_num_inst_src_regs( inst->Opcode );\r
- for (j = 0; j < n; j++) {\r
- if (inst->SrcReg[j].File == PROGRAM_TEMPORARY)\r
- tempsUsed[inst->SrcReg[j].Index] = GL_TRUE;\r
- if (inst->DstReg.File == PROGRAM_TEMPORARY)\r
- tempsUsed[inst->DstReg.Index] = GL_TRUE;\r
- }\r
- }\r
-\r
- /* convert flags to list of indices */\r
- count = 0;\r
- for (i = 0; i < MAX_PROGRAM_TEMPS; i++) {\r
- if (tempsUsed[i])\r
- tempsUsed[count++] = i;\r
- }\r
- return count;\r
-}\r
-\r
-\r
-\r
-\r
-/**\r
- * Translate Mesa program to TGSI format.\r
- * \param program the program to translate\r
- * \param numInputs number of input registers used\r
- * \param inputMapping maps Mesa fragment program inputs to TGSI generic\r
- * input indexes\r
- * \param inputSemanticName the TGSI_SEMANTIC flag for each input\r
- * \param inputSemanticIndex the semantic index (ex: which texcoord) for each input\r
- * \param interpMode the TGSI_INTERPOLATE_LINEAR/PERSP mode for each input\r
-\r
- * \param numOutputs number of output registers used\r
- * \param outputMapping maps Mesa fragment program outputs to TGSI\r
- * generic outputs\r
- * \param outputSemanticName the TGSI_SEMANTIC flag for each output\r
- * \param outputSemanticIndex the semantic index (ex: which texcoord) for each output\r
- * \param tokens array to store translated tokens in\r
- * \param maxTokens size of the tokens array\r
- *\r
- */\r
-GLboolean\r
-tgsi_translate_mesa_program(\r
- uint procType,\r
- const struct gl_program *program,\r
- GLuint numInputs,\r
- const GLuint inputMapping[],\r
- const ubyte inputSemanticName[],\r
- const ubyte inputSemanticIndex[],\r
- const GLuint interpMode[],\r
- GLuint numOutputs,\r
- const GLuint outputMapping[],\r
- const ubyte outputSemanticName[],\r
- const ubyte outputSemanticIndex[],\r
- struct tgsi_token *tokens,\r
- GLuint maxTokens )\r
-{\r
- GLuint i;\r
- GLuint ti; /* token index */\r
- struct tgsi_header *header;\r
- struct tgsi_processor *processor;\r
- struct tgsi_full_instruction fullinst;\r
- GLuint preamble_size = 0;\r
- GLuint immediates[1000];\r
-#if EMIT_IMMEDIATES\r
- GLuint numImmediates = 0;\r
-#endif\r
-\r
- assert(procType == TGSI_PROCESSOR_FRAGMENT ||\r
- procType == TGSI_PROCESSOR_VERTEX);\r
-\r
- *(struct tgsi_version *) &tokens[0] = tgsi_build_version();\r
-\r
- header = (struct tgsi_header *) &tokens[1];\r
- *header = tgsi_build_header();\r
-\r
- processor = (struct tgsi_processor *) &tokens[2];\r
- *processor = tgsi_build_processor( procType, header );\r
-\r
- ti = 3;\r
-\r
- /*\r
- * Declare input attributes.\r
- */\r
- if (procType == TGSI_PROCESSOR_FRAGMENT) {\r
- for (i = 0; i < numInputs; i++) {\r
- struct tgsi_full_declaration fulldecl;\r
- switch (inputSemanticName[i]) {\r
- case TGSI_SEMANTIC_POSITION:\r
- /* Fragment XY pos */\r
- fulldecl = make_input_decl(i,\r
- TGSI_INTERPOLATE_CONSTANT,\r
- TGSI_WRITEMASK_XY,\r
- GL_TRUE, TGSI_SEMANTIC_POSITION, 0 );\r
- ti += tgsi_build_full_declaration(\r
- &fulldecl,\r
- &tokens[ti],\r
- header,\r
- maxTokens - ti );\r
- /* Fragment ZW pos */\r
- fulldecl = make_input_decl(i,\r
- TGSI_INTERPOLATE_LINEAR,\r
- TGSI_WRITEMASK_ZW,\r
- GL_TRUE, TGSI_SEMANTIC_POSITION, 0 );\r
- ti += tgsi_build_full_declaration(&fulldecl,\r
- &tokens[ti],\r
- header,\r
- maxTokens - ti );\r
- break;\r
- default:\r
- fulldecl = make_input_decl(i,\r
- interpMode[i],\r
- TGSI_WRITEMASK_XYZW,\r
- GL_TRUE, inputSemanticName[i],\r
- inputSemanticIndex[i]);\r
- ti += tgsi_build_full_declaration(&fulldecl,\r
- &tokens[ti],\r
- header,\r
- maxTokens - ti );\r
- break;\r
- }\r
- }\r
- }\r
- else {\r
- /* vertex prog */\r
- for (i = 0; i < numInputs; i++) {\r
- struct tgsi_full_declaration fulldecl;\r
- fulldecl = make_input_decl(i,\r
- TGSI_INTERPOLATE_ATTRIB,\r
- TGSI_WRITEMASK_XYZW,\r
- GL_FALSE, inputSemanticName[i],\r
- inputSemanticIndex[i]);\r
- ti += tgsi_build_full_declaration(&fulldecl,\r
- &tokens[ti],\r
- header,\r
- maxTokens - ti );\r
- }\r
- }\r
-\r
- /*\r
- * Declare output attributes.\r
- */\r
- if (procType == TGSI_PROCESSOR_FRAGMENT) {\r
- for (i = 0; i < numOutputs; i++) {\r
- struct tgsi_full_declaration fulldecl;\r
- switch (outputSemanticName[i]) {\r
- case TGSI_SEMANTIC_POSITION:\r
- fulldecl = make_output_decl(i,\r
- TGSI_SEMANTIC_POSITION, 0, /* Z / Depth */\r
- TGSI_WRITEMASK_Z );\r
- break;\r
- case TGSI_SEMANTIC_COLOR:\r
- fulldecl = make_output_decl(i,\r
- TGSI_SEMANTIC_COLOR, 0,\r
- TGSI_WRITEMASK_XYZW );\r
- break;\r
- default:\r
- abort();\r
- }\r
- ti += tgsi_build_full_declaration(&fulldecl,\r
- &tokens[ti],\r
- header,\r
- maxTokens - ti );\r
- }\r
- }\r
- else {\r
- /* vertex prog */\r
- for (i = 0; i < numOutputs; i++) {\r
- struct tgsi_full_declaration fulldecl;\r
- fulldecl = make_output_decl(i,\r
- outputSemanticName[i],\r
- outputSemanticIndex[i],\r
- TGSI_WRITEMASK_XYZW );\r
- ti += tgsi_build_full_declaration(&fulldecl,\r
- &tokens[ti],\r
- header,\r
- maxTokens - ti );\r
- }\r
- }\r
-\r
- /* temporary decls */\r
- {\r
- GLuint tempsUsed[MAX_PROGRAM_TEMPS];\r
- uint numTemps = find_temporaries(program, tempsUsed);\r
- for (i = 0; i < numTemps; i++) {\r
- struct tgsi_full_declaration fulldecl;\r
- fulldecl = make_temp_decl(tempsUsed[i]);\r
- ti += tgsi_build_full_declaration(\r
- &fulldecl,\r
- &tokens[ti],\r
- header,\r
- maxTokens - ti );\r
- }\r
- }\r
-\r
- /* immediates/literals */\r
-#if EMIT_IMMEDIATES\r
- for (i = 0; i < program->Parameters->NumParameters; i++) {\r
- if (program->Parameters->Parameters[i].Type == PROGRAM_CONSTANT) {\r
- struct tgsi_full_immediate fullimm\r
- = make_immediate(program->Parameters->ParameterValues[i],\r
- program->Parameters->Parameters[i].Size);\r
- ti += tgsi_build_full_immediate(&fullimm,\r
- &tokens[ti],\r
- header,\r
- maxTokens - ti);\r
- immediates[i] = numImmediates;\r
- numImmediates++;\r
- }\r
- }\r
-#endif\r
-\r
- for( i = 0; i < program->NumInstructions; i++ ) {\r
- compile_instruction(\r
- &program->Instructions[i],\r
- &fullinst,\r
- inputMapping,\r
- outputMapping,\r
- immediates,\r
- preamble_size,\r
- procType );\r
-\r
- ti += tgsi_build_full_instruction(\r
- &fullinst,\r
- &tokens[ti],\r
- header,\r
- maxTokens - ti );\r
- }\r
-\r
- return GL_TRUE;\r
-}\r
-\r
+++ /dev/null
-#if !defined MESA_TO_TGSI_H\r
-#define MESA_TO_TGSI_H\r
-\r
-#if defined __cplusplus\r
-extern "C" {\r
-#endif // defined __cplusplus\r
-\r
-struct tgsi_token;\r
-\r
-GLboolean\r
-tgsi_translate_mesa_program(\r
- uint procType,\r
- const struct gl_program *program,\r
- GLuint numInputs,\r
- const GLuint inputMapping[],\r
- const ubyte inputSemanticName[],\r
- const ubyte inputSemanticIndex[],\r
- const GLuint interpMode[],\r
- GLuint numOutputs,\r
- const GLuint outputMapping[],\r
- const ubyte outputSemanticName[],\r
- const ubyte outputSemanticIndex[],\r
- struct tgsi_token *tokens,\r
- GLuint maxTokens );\r
-\r
-\r
-#if defined __cplusplus\r
-} // extern "C"\r
-#endif // defined __cplusplus\r
-\r
-#endif // !defined MESA_TO_TGSI_H\r
-\r
--- /dev/null
+#include "tgsi_platform.h"\r
+#include "tgsi_mesa.h"\r
+#include "pipe/tgsi/mesa/mesa_to_tgsi.h"\r
+#include "shader/prog_parameter.h"\r
+\r
+#define TGSI_DEBUG 0\r
+\r
+#define EMIT_IMMEDIATES 0\r
+\r
+\r
+/*\r
+ * Map mesa register file to TGSI register file.\r
+ */\r
+static GLuint\r
+map_register_file(\r
+ enum register_file file )\r
+{\r
+ switch( file ) {\r
+ case PROGRAM_UNDEFINED:\r
+ return TGSI_FILE_NULL;\r
+ case PROGRAM_TEMPORARY:\r
+ return TGSI_FILE_TEMPORARY;\r
+ //case PROGRAM_LOCAL_PARAM:\r
+ //case PROGRAM_ENV_PARAM:\r
+ case PROGRAM_STATE_VAR:\r
+ case PROGRAM_NAMED_PARAM:\r
+ case PROGRAM_UNIFORM:\r
+ return TGSI_FILE_CONSTANT;\r
+ case PROGRAM_CONSTANT:\r
+#if EMIT_IMMEDIATES\r
+ return TGSI_FILE_IMMEDIATE;\r
+#else\r
+ return TGSI_FILE_CONSTANT;\r
+#endif\r
+ case PROGRAM_INPUT:\r
+ return TGSI_FILE_INPUT;\r
+ case PROGRAM_OUTPUT:\r
+ return TGSI_FILE_OUTPUT;\r
+ case PROGRAM_ADDRESS:\r
+ return TGSI_FILE_ADDRESS;\r
+ default:\r
+ assert( 0 );\r
+ return TGSI_FILE_NULL;\r
+ }\r
+}\r
+\r
+/**\r
+ * Map mesa register file index to TGSI index.\r
+ * Take special care when processing input and output indices.\r
+ * \param file one of TGSI_FILE_x\r
+ * \param index the mesa register file index\r
+ * \param inputMapping maps Mesa input indexes to TGSI input indexes\r
+ * \param outputMapping maps Mesa output indexes to TGSI output indexes\r
+ */\r
+static GLuint\r
+map_register_file_index(\r
+ GLuint file,\r
+ GLuint index,\r
+ const GLuint inputMapping[],\r
+ const GLuint outputMapping[],\r
+ const GLuint immediateMapping[])\r
+{\r
+ switch( file ) {\r
+ case TGSI_FILE_INPUT:\r
+ /* inputs are mapped according to the user-defined map */\r
+ return inputMapping[index];\r
+\r
+ case TGSI_FILE_OUTPUT:\r
+ return outputMapping[index];\r
+\r
+#if EMIT_IMMEDIATES\r
+ case TGSI_FILE_IMMEDIATE:\r
+ return immediateMapping[index];\r
+#endif\r
+\r
+ default:\r
+ return index;\r
+ }\r
+}\r
+\r
+/*\r
+ * Map mesa texture target to TGSI texture target.\r
+ */\r
+static GLuint\r
+map_texture_target(\r
+ GLuint textarget )\r
+{\r
+ switch( textarget ) {\r
+ case TEXTURE_1D_INDEX:\r
+ return TGSI_TEXTURE_1D;\r
+ case TEXTURE_2D_INDEX:\r
+ return TGSI_TEXTURE_2D;\r
+ case TEXTURE_3D_INDEX:\r
+ return TGSI_TEXTURE_3D;\r
+ case TEXTURE_CUBE_INDEX:\r
+ return TGSI_TEXTURE_CUBE;\r
+ case TEXTURE_RECT_INDEX:\r
+ return TGSI_TEXTURE_RECT;\r
+ default:\r
+ assert( 0 );\r
+ }\r
+\r
+ return TGSI_TEXTURE_1D;\r
+}\r
+\r
+static GLuint\r
+convert_sat(\r
+ GLuint sat )\r
+{\r
+ switch( sat ) {\r
+ case SATURATE_OFF:\r
+ return TGSI_SAT_NONE;\r
+ case SATURATE_ZERO_ONE:\r
+ return TGSI_SAT_ZERO_ONE;\r
+ case SATURATE_PLUS_MINUS_ONE:\r
+ return TGSI_SAT_MINUS_PLUS_ONE;\r
+ default:\r
+ assert( 0 );\r
+ return TGSI_SAT_NONE;\r
+ }\r
+}\r
+\r
+static GLuint\r
+convert_writemask(\r
+ GLuint writemask )\r
+{\r
+ assert( WRITEMASK_X == TGSI_WRITEMASK_X );\r
+ assert( WRITEMASK_Y == TGSI_WRITEMASK_Y );\r
+ assert( WRITEMASK_Z == TGSI_WRITEMASK_Z );\r
+ assert( WRITEMASK_W == TGSI_WRITEMASK_W );\r
+ assert( (writemask & ~TGSI_WRITEMASK_XYZW) == 0 );\r
+\r
+ return writemask;\r
+}\r
+\r
+#if EMIT_IMMEDIATES\r
+static struct tgsi_full_immediate\r
+make_immediate(const float *value, uint size)\r
+{\r
+ struct tgsi_full_immediate imm;\r
+ imm.Immediate.Type = TGSI_TOKEN_TYPE_IMMEDIATE;\r
+ imm.Immediate.Size = 1 + size; /* one for the token itself */\r
+ imm.Immediate.DataType = TGSI_IMM_FLOAT32;\r
+ imm.u.ImmediateFloat32 = (struct tgsi_immediate_float32 *) value;\r
+ return imm;\r
+}\r
+#endif\r
+\r
+static void\r
+compile_instruction(\r
+ const struct prog_instruction *inst,\r
+ struct tgsi_full_instruction *fullinst,\r
+ const GLuint inputMapping[],\r
+ const GLuint outputMapping[],\r
+ const GLuint immediateMapping[],\r
+ GLuint preamble_size,\r
+ GLuint processor )\r
+{\r
+ GLuint i;\r
+ struct tgsi_full_dst_register *fulldst;\r
+ struct tgsi_full_src_register *fullsrc;\r
+\r
+ *fullinst = tgsi_default_full_instruction();\r
+\r
+ fullinst->Instruction.Saturate = convert_sat( inst->SaturateMode );\r
+ fullinst->Instruction.NumDstRegs = _mesa_num_inst_dst_regs( inst->Opcode );\r
+ fullinst->Instruction.NumSrcRegs = _mesa_num_inst_src_regs( inst->Opcode );\r
+\r
+ fulldst = &fullinst->FullDstRegisters[0];\r
+ fulldst->DstRegister.File = map_register_file( inst->DstReg.File );\r
+ fulldst->DstRegister.Index = map_register_file_index(\r
+ fulldst->DstRegister.File,\r
+ inst->DstReg.Index,\r
+ inputMapping,\r
+ outputMapping,\r
+ NULL\r
+ );\r
+ fulldst->DstRegister.WriteMask = convert_writemask( inst->DstReg.WriteMask );\r
+\r
+ for( i = 0; i < fullinst->Instruction.NumSrcRegs; i++ ) {\r
+ GLuint j;\r
+\r
+ fullsrc = &fullinst->FullSrcRegisters[i];\r
+ fullsrc->SrcRegister.File = map_register_file( inst->SrcReg[i].File );\r
+ fullsrc->SrcRegister.Index = map_register_file_index(\r
+ fullsrc->SrcRegister.File,\r
+ inst->SrcReg[i].Index,\r
+ inputMapping,\r
+ outputMapping,\r
+ immediateMapping);\r
+\r
+ for( j = 0; j < 4; j++ ) {\r
+ GLuint swz;\r
+\r
+ swz = GET_SWZ( inst->SrcReg[i].Swizzle, j );\r
+ if( swz > SWIZZLE_W ) {\r
+ tgsi_util_set_src_register_extswizzle(\r
+ &fullsrc->SrcRegisterExtSwz,\r
+ swz,\r
+ j );\r
+ }\r
+ else {\r
+ tgsi_util_set_src_register_swizzle(\r
+ &fullsrc->SrcRegister,\r
+ swz,\r
+ j );\r
+ }\r
+ }\r
+\r
+ if( inst->SrcReg[i].NegateBase == NEGATE_XYZW ) {\r
+ fullsrc->SrcRegister.Negate = 1;\r
+ }\r
+ else if( inst->SrcReg[i].NegateBase != NEGATE_NONE ) {\r
+ if( inst->SrcReg[i].NegateBase & NEGATE_X ) {\r
+ fullsrc->SrcRegisterExtSwz.NegateX = 1;\r
+ }\r
+ if( inst->SrcReg[i].NegateBase & NEGATE_Y ) {\r
+ fullsrc->SrcRegisterExtSwz.NegateY = 1;\r
+ }\r
+ if( inst->SrcReg[i].NegateBase & NEGATE_Z ) {\r
+ fullsrc->SrcRegisterExtSwz.NegateZ = 1;\r
+ }\r
+ if( inst->SrcReg[i].NegateBase & NEGATE_W ) {\r
+ fullsrc->SrcRegisterExtSwz.NegateW = 1;\r
+ }\r
+ }\r
+\r
+ if( inst->SrcReg[i].Abs ) {\r
+ fullsrc->SrcRegisterExtMod.Absolute = 1;\r
+ }\r
+\r
+ if( inst->SrcReg[i].NegateAbs ) {\r
+ fullsrc->SrcRegisterExtMod.Negate = 1;\r
+ }\r
+\r
+ if( inst->SrcReg[i].RelAddr ) {\r
+ fullsrc->SrcRegister.Indirect = 1;\r
+\r
+ fullsrc->SrcRegisterInd.File = TGSI_FILE_ADDRESS;\r
+ fullsrc->SrcRegisterInd.Index = 0;\r
+ }\r
+ }\r
+\r
+ switch( inst->Opcode ) {\r
+ case OPCODE_ARL:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_ARL;\r
+ break;\r
+ case OPCODE_ABS:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_ABS;\r
+ break;\r
+ case OPCODE_ADD:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_ADD;\r
+ break;\r
+ case OPCODE_BGNLOOP:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_BGNLOOP2;\r
+ fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;\r
+ break;\r
+ case OPCODE_BGNSUB:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_BGNSUB;\r
+ break;\r
+ case OPCODE_BRA:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_BRA;\r
+ break;\r
+ case OPCODE_BRK:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_BRK;\r
+ break;\r
+ case OPCODE_CAL:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_CAL;\r
+ fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;\r
+ break;\r
+ case OPCODE_CMP:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_CMP;\r
+ break;\r
+ case OPCODE_CONT:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_CONT;\r
+ break;\r
+ case OPCODE_COS:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_COS;\r
+ break;\r
+ case OPCODE_DDX:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_DDX;\r
+ break;\r
+ case OPCODE_DDY:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_DDY;\r
+ break;\r
+ case OPCODE_DP3:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_DP3;\r
+ break;\r
+ case OPCODE_DP4:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_DP4;\r
+ break;\r
+ case OPCODE_DPH:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_DPH;\r
+ break;\r
+ case OPCODE_DST:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_DST;\r
+ break;\r
+ case OPCODE_ELSE:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_ELSE;\r
+ fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;\r
+ break;\r
+ case OPCODE_ENDIF:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_ENDIF;\r
+ break;\r
+ case OPCODE_ENDLOOP:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_ENDLOOP2;\r
+ fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;\r
+ break;\r
+ case OPCODE_ENDSUB:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_ENDSUB;\r
+ break;\r
+ case OPCODE_EX2:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_EX2;\r
+ break;\r
+ case OPCODE_EXP:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_EXP;\r
+ break;\r
+ case OPCODE_FLR:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_FLR;\r
+ break;\r
+ case OPCODE_FRC:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_FRC;\r
+ break;\r
+ case OPCODE_IF:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_IF;\r
+ fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;\r
+ break;\r
+ case OPCODE_INT:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_INT;\r
+ break;\r
+ case OPCODE_KIL:\r
+ /* predicated w/ a register */\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_KILP;\r
+ break;\r
+ case OPCODE_KIL_NV:\r
+ /* unpredicated */\r
+ assert(inst->DstReg.CondMask == COND_TR);\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_KIL;\r
+ break;\r
+ case OPCODE_LG2:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_LG2;\r
+ break;\r
+ case OPCODE_LOG:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_LOG;\r
+ break;\r
+ case OPCODE_LIT:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_LIT;\r
+ break;\r
+ case OPCODE_LRP:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_LRP;\r
+ break;\r
+ case OPCODE_MAD:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_MAD;\r
+ break;\r
+ case OPCODE_MAX:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_MAX;\r
+ break;\r
+ case OPCODE_MIN:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_MIN;\r
+ break;\r
+ case OPCODE_MOV:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_MOV;\r
+ break;\r
+ case OPCODE_MUL:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_MUL;\r
+ break;\r
+ case OPCODE_NOISE1:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_NOISE1;\r
+ break;\r
+ case OPCODE_NOISE2:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_NOISE2;\r
+ break;\r
+ case OPCODE_NOISE3:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_NOISE3;\r
+ break;\r
+ case OPCODE_NOISE4:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_NOISE4;\r
+ break;\r
+ case OPCODE_NOP:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_NOP;\r
+ break;\r
+ case OPCODE_POW:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_POW;\r
+ break;\r
+ case OPCODE_RCP:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_RCP;\r
+ break;\r
+ case OPCODE_RET:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_RET;\r
+ break;\r
+ case OPCODE_RSQ:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_RSQ;\r
+ tgsi_util_set_full_src_register_sign_mode(\r
+ &fullinst->FullSrcRegisters[0],\r
+ TGSI_UTIL_SIGN_CLEAR );\r
+ break;\r
+ case OPCODE_SCS:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_SCS;\r
+ fulldst->DstRegister.WriteMask &= TGSI_WRITEMASK_XY;\r
+ break;\r
+ case OPCODE_SEQ:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_SEQ;\r
+ break;\r
+ case OPCODE_SGE:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_SGE;\r
+ break;\r
+ case OPCODE_SGT:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_SGT;\r
+ break;\r
+ case OPCODE_SIN:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_SIN;\r
+ break;\r
+ case OPCODE_SLE:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_SLE;\r
+ break;\r
+ case OPCODE_SLT:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_SLT;\r
+ break;\r
+ case OPCODE_SNE:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_SNE;\r
+ break;\r
+ case OPCODE_SUB:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_SUB;\r
+ break;\r
+ case OPCODE_SWZ:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_SWZ;\r
+ break;\r
+ case OPCODE_TEX:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_TEX;\r
+ fullinst->Instruction.NumSrcRegs = 2;\r
+ fullinst->InstructionExtTexture.Texture = map_texture_target( inst->TexSrcTarget );\r
+ fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;\r
+ fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;\r
+ break;\r
+ case OPCODE_TXB:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_TXB;\r
+ fullinst->Instruction.NumSrcRegs = 2;\r
+ fullinst->InstructionExtTexture.Texture = map_texture_target( inst->TexSrcTarget );\r
+ fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;\r
+ fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;\r
+ break;\r
+ case OPCODE_TXD:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_TXD;\r
+ fullinst->Instruction.NumSrcRegs = 2;\r
+ fullinst->InstructionExtTexture.Texture = map_texture_target( inst->TexSrcTarget );\r
+ fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;\r
+ fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;\r
+ break;\r
+ case OPCODE_TXL:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_TXL;\r
+ fullinst->Instruction.NumSrcRegs = 2;\r
+ fullinst->InstructionExtTexture.Texture = map_texture_target( inst->TexSrcTarget );\r
+ fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;\r
+ fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;\r
+ break;\r
+ case OPCODE_TXP:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_TEX;\r
+ fullinst->Instruction.NumSrcRegs = 2;\r
+ fullinst->InstructionExtTexture.Texture = map_texture_target( inst->TexSrcTarget );\r
+ fullinst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide = TGSI_EXTSWIZZLE_W;\r
+ fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;\r
+ fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;\r
+ break;\r
+ case OPCODE_XPD:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_XPD;\r
+ fulldst->DstRegister.WriteMask &= TGSI_WRITEMASK_XYZ;\r
+ break;\r
+ case OPCODE_END:\r
+ fullinst->Instruction.Opcode = TGSI_OPCODE_RET;\r
+ break;\r
+ default:\r
+ assert( 0 );\r
+ }\r
+}\r
+\r
+/**\r
+ * \param usage_mask bitfield of TGSI_WRITEMASK_{XYZW} tokens\r
+ */\r
+static struct tgsi_full_declaration\r
+make_input_decl(\r
+ GLuint index,\r
+ GLuint interpolate,\r
+ GLuint usage_mask,\r
+ GLboolean semantic_info,\r
+ GLuint semantic_name,\r
+ GLbitfield semantic_index )\r
+{\r
+ struct tgsi_full_declaration decl;\r
+\r
+ assert(semantic_name < TGSI_SEMANTIC_COUNT);\r
+\r
+ decl = tgsi_default_full_declaration();\r
+ decl.Declaration.File = TGSI_FILE_INPUT;\r
+ decl.Declaration.Declare = TGSI_DECLARE_RANGE;\r
+ decl.Declaration.UsageMask = usage_mask;\r
+ decl.Declaration.Semantic = semantic_info;\r
+ decl.Declaration.Interpolate = 1;\r
+ decl.u.DeclarationRange.First = index;\r
+ decl.u.DeclarationRange.Last = index;\r
+ if (semantic_info) {\r
+ decl.Semantic.SemanticName = semantic_name;\r
+ decl.Semantic.SemanticIndex = semantic_index;\r
+ }\r
+ decl.Interpolation.Interpolate = interpolate;\r
+\r
+ return decl;\r
+}\r
+\r
+/**\r
+ * \param usage_mask bitfield of TGSI_WRITEMASK_{XYZW} tokens\r
+ */\r
+static struct tgsi_full_declaration\r
+make_output_decl(\r
+ GLuint index,\r
+ GLuint semantic_name,\r
+ GLuint semantic_index,\r
+ GLbitfield usage_mask )\r
+{\r
+ struct tgsi_full_declaration decl;\r
+\r
+ assert(semantic_name < TGSI_SEMANTIC_COUNT);\r
+\r
+ decl = tgsi_default_full_declaration();\r
+ decl.Declaration.File = TGSI_FILE_OUTPUT;\r
+ decl.Declaration.Declare = TGSI_DECLARE_RANGE;\r
+ decl.Declaration.UsageMask = usage_mask;\r
+ decl.Declaration.Semantic = 1;\r
+ decl.u.DeclarationRange.First = index;\r
+ decl.u.DeclarationRange.Last = index;\r
+ decl.Semantic.SemanticName = semantic_name;\r
+ decl.Semantic.SemanticIndex = semantic_index;\r
+\r
+ return decl;\r
+}\r
+\r
+\r
+static struct tgsi_full_declaration\r
+make_temp_decl(GLuint index)\r
+{\r
+ struct tgsi_full_declaration decl;\r
+ decl = tgsi_default_full_declaration();\r
+ decl.Declaration.File = TGSI_FILE_TEMPORARY;\r
+ decl.Declaration.Declare = TGSI_DECLARE_RANGE;\r
+ decl.u.DeclarationRange.First = index;\r
+ decl.u.DeclarationRange.Last = index;\r
+ return decl;\r
+}\r
+\r
+\r
+/**\r
+ * Find the temporaries which are used in the given program.\r
+ * Put the indices of the temporaries in 'tempsUsed'.\r
+ * \return number of temporaries used\r
+ */\r
+static GLuint\r
+find_temporaries(const struct gl_program *program,\r
+ GLuint tempsUsed[MAX_PROGRAM_TEMPS])\r
+{\r
+ GLuint i, j, count;\r
+\r
+ for (i = 0; i < MAX_PROGRAM_TEMPS; i++)\r
+ tempsUsed[i] = GL_FALSE;\r
+\r
+ for (i = 0; i < program->NumInstructions; i++) {\r
+ const struct prog_instruction *inst = program->Instructions + i;\r
+ const GLuint n = _mesa_num_inst_src_regs( inst->Opcode );\r
+ for (j = 0; j < n; j++) {\r
+ if (inst->SrcReg[j].File == PROGRAM_TEMPORARY)\r
+ tempsUsed[inst->SrcReg[j].Index] = GL_TRUE;\r
+ if (inst->DstReg.File == PROGRAM_TEMPORARY)\r
+ tempsUsed[inst->DstReg.Index] = GL_TRUE;\r
+ }\r
+ }\r
+\r
+ /* convert flags to list of indices */\r
+ count = 0;\r
+ for (i = 0; i < MAX_PROGRAM_TEMPS; i++) {\r
+ if (tempsUsed[i])\r
+ tempsUsed[count++] = i;\r
+ }\r
+ return count;\r
+}\r
+\r
+\r
+\r
+\r
+/**\r
+ * Translate Mesa program to TGSI format.\r
+ * \param program the program to translate\r
+ * \param numInputs number of input registers used\r
+ * \param inputMapping maps Mesa fragment program inputs to TGSI generic\r
+ * input indexes\r
+ * \param inputSemanticName the TGSI_SEMANTIC flag for each input\r
+ * \param inputSemanticIndex the semantic index (ex: which texcoord) for each input\r
+ * \param interpMode the TGSI_INTERPOLATE_LINEAR/PERSP mode for each input\r
+\r
+ * \param numOutputs number of output registers used\r
+ * \param outputMapping maps Mesa fragment program outputs to TGSI\r
+ * generic outputs\r
+ * \param outputSemanticName the TGSI_SEMANTIC flag for each output\r
+ * \param outputSemanticIndex the semantic index (ex: which texcoord) for each output\r
+ * \param tokens array to store translated tokens in\r
+ * \param maxTokens size of the tokens array\r
+ *\r
+ */\r
+GLboolean\r
+tgsi_translate_mesa_program(\r
+ uint procType,\r
+ const struct gl_program *program,\r
+ GLuint numInputs,\r
+ const GLuint inputMapping[],\r
+ const ubyte inputSemanticName[],\r
+ const ubyte inputSemanticIndex[],\r
+ const GLuint interpMode[],\r
+ GLuint numOutputs,\r
+ const GLuint outputMapping[],\r
+ const ubyte outputSemanticName[],\r
+ const ubyte outputSemanticIndex[],\r
+ struct tgsi_token *tokens,\r
+ GLuint maxTokens )\r
+{\r
+ GLuint i;\r
+ GLuint ti; /* token index */\r
+ struct tgsi_header *header;\r
+ struct tgsi_processor *processor;\r
+ struct tgsi_full_instruction fullinst;\r
+ GLuint preamble_size = 0;\r
+ GLuint immediates[1000];\r
+#if EMIT_IMMEDIATES\r
+ GLuint numImmediates = 0;\r
+#endif\r
+\r
+ assert(procType == TGSI_PROCESSOR_FRAGMENT ||\r
+ procType == TGSI_PROCESSOR_VERTEX);\r
+\r
+ *(struct tgsi_version *) &tokens[0] = tgsi_build_version();\r
+\r
+ header = (struct tgsi_header *) &tokens[1];\r
+ *header = tgsi_build_header();\r
+\r
+ processor = (struct tgsi_processor *) &tokens[2];\r
+ *processor = tgsi_build_processor( procType, header );\r
+\r
+ ti = 3;\r
+\r
+ /*\r
+ * Declare input attributes.\r
+ */\r
+ if (procType == TGSI_PROCESSOR_FRAGMENT) {\r
+ for (i = 0; i < numInputs; i++) {\r
+ struct tgsi_full_declaration fulldecl;\r
+ switch (inputSemanticName[i]) {\r
+ case TGSI_SEMANTIC_POSITION:\r
+ /* Fragment XY pos */\r
+ fulldecl = make_input_decl(i,\r
+ TGSI_INTERPOLATE_CONSTANT,\r
+ TGSI_WRITEMASK_XY,\r
+ GL_TRUE, TGSI_SEMANTIC_POSITION, 0 );\r
+ ti += tgsi_build_full_declaration(\r
+ &fulldecl,\r
+ &tokens[ti],\r
+ header,\r
+ maxTokens - ti );\r
+ /* Fragment ZW pos */\r
+ fulldecl = make_input_decl(i,\r
+ TGSI_INTERPOLATE_LINEAR,\r
+ TGSI_WRITEMASK_ZW,\r
+ GL_TRUE, TGSI_SEMANTIC_POSITION, 0 );\r
+ ti += tgsi_build_full_declaration(&fulldecl,\r
+ &tokens[ti],\r
+ header,\r
+ maxTokens - ti );\r
+ break;\r
+ default:\r
+ fulldecl = make_input_decl(i,\r
+ interpMode[i],\r
+ TGSI_WRITEMASK_XYZW,\r
+ GL_TRUE, inputSemanticName[i],\r
+ inputSemanticIndex[i]);\r
+ ti += tgsi_build_full_declaration(&fulldecl,\r
+ &tokens[ti],\r
+ header,\r
+ maxTokens - ti );\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ else {\r
+ /* vertex prog */\r
+ for (i = 0; i < numInputs; i++) {\r
+ struct tgsi_full_declaration fulldecl;\r
+ fulldecl = make_input_decl(i,\r
+ TGSI_INTERPOLATE_ATTRIB,\r
+ TGSI_WRITEMASK_XYZW,\r
+ GL_FALSE, inputSemanticName[i],\r
+ inputSemanticIndex[i]);\r
+ ti += tgsi_build_full_declaration(&fulldecl,\r
+ &tokens[ti],\r
+ header,\r
+ maxTokens - ti );\r
+ }\r
+ }\r
+\r
+ /*\r
+ * Declare output attributes.\r
+ */\r
+ if (procType == TGSI_PROCESSOR_FRAGMENT) {\r
+ for (i = 0; i < numOutputs; i++) {\r
+ struct tgsi_full_declaration fulldecl;\r
+ switch (outputSemanticName[i]) {\r
+ case TGSI_SEMANTIC_POSITION:\r
+ fulldecl = make_output_decl(i,\r
+ TGSI_SEMANTIC_POSITION, 0, /* Z / Depth */\r
+ TGSI_WRITEMASK_Z );\r
+ break;\r
+ case TGSI_SEMANTIC_COLOR:\r
+ fulldecl = make_output_decl(i,\r
+ TGSI_SEMANTIC_COLOR, 0,\r
+ TGSI_WRITEMASK_XYZW );\r
+ break;\r
+ default:\r
+ abort();\r
+ }\r
+ ti += tgsi_build_full_declaration(&fulldecl,\r
+ &tokens[ti],\r
+ header,\r
+ maxTokens - ti );\r
+ }\r
+ }\r
+ else {\r
+ /* vertex prog */\r
+ for (i = 0; i < numOutputs; i++) {\r
+ struct tgsi_full_declaration fulldecl;\r
+ fulldecl = make_output_decl(i,\r
+ outputSemanticName[i],\r
+ outputSemanticIndex[i],\r
+ TGSI_WRITEMASK_XYZW );\r
+ ti += tgsi_build_full_declaration(&fulldecl,\r
+ &tokens[ti],\r
+ header,\r
+ maxTokens - ti );\r
+ }\r
+ }\r
+\r
+ /* temporary decls */\r
+ {\r
+ GLuint tempsUsed[MAX_PROGRAM_TEMPS];\r
+ uint numTemps = find_temporaries(program, tempsUsed);\r
+ for (i = 0; i < numTemps; i++) {\r
+ struct tgsi_full_declaration fulldecl;\r
+ fulldecl = make_temp_decl(tempsUsed[i]);\r
+ ti += tgsi_build_full_declaration(\r
+ &fulldecl,\r
+ &tokens[ti],\r
+ header,\r
+ maxTokens - ti );\r
+ }\r
+ }\r
+\r
+ /* immediates/literals */\r
+#if EMIT_IMMEDIATES\r
+ for (i = 0; i < program->Parameters->NumParameters; i++) {\r
+ if (program->Parameters->Parameters[i].Type == PROGRAM_CONSTANT) {\r
+ struct tgsi_full_immediate fullimm\r
+ = make_immediate(program->Parameters->ParameterValues[i],\r
+ program->Parameters->Parameters[i].Size);\r
+ ti += tgsi_build_full_immediate(&fullimm,\r
+ &tokens[ti],\r
+ header,\r
+ maxTokens - ti);\r
+ immediates[i] = numImmediates;\r
+ numImmediates++;\r
+ }\r
+ }\r
+#endif\r
+\r
+ for( i = 0; i < program->NumInstructions; i++ ) {\r
+ compile_instruction(\r
+ &program->Instructions[i],\r
+ &fullinst,\r
+ inputMapping,\r
+ outputMapping,\r
+ immediates,\r
+ preamble_size,\r
+ procType );\r
+\r
+ ti += tgsi_build_full_instruction(\r
+ &fullinst,\r
+ &tokens[ti],\r
+ header,\r
+ maxTokens - ti );\r
+ }\r
+\r
+ return GL_TRUE;\r
+}\r
+\r
--- /dev/null
+#if !defined MESA_TO_TGSI_H\r
+#define MESA_TO_TGSI_H\r
+\r
+#if defined __cplusplus\r
+extern "C" {\r
+#endif // defined __cplusplus\r
+\r
+struct tgsi_token;\r
+\r
+GLboolean\r
+tgsi_translate_mesa_program(\r
+ uint procType,\r
+ const struct gl_program *program,\r
+ GLuint numInputs,\r
+ const GLuint inputMapping[],\r
+ const ubyte inputSemanticName[],\r
+ const ubyte inputSemanticIndex[],\r
+ const GLuint interpMode[],\r
+ GLuint numOutputs,\r
+ const GLuint outputMapping[],\r
+ const ubyte outputSemanticName[],\r
+ const ubyte outputSemanticIndex[],\r
+ struct tgsi_token *tokens,\r
+ GLuint maxTokens );\r
+\r
+\r
+#if defined __cplusplus\r
+} // extern "C"\r
+#endif // defined __cplusplus\r
+\r
+#endif // !defined MESA_TO_TGSI_H\r
+\r