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 #include "pipe/p_debug.h"
00029 #include "pipe/p_shader_tokens.h"
00030 #include "tgsi_parse.h"
00031 #include "tgsi_build.h"
00032 #include "util/u_memory.h"
00033
00034 void
00035 tgsi_full_token_init(
00036 union tgsi_full_token *full_token )
00037 {
00038 full_token->Token.Type = TGSI_TOKEN_TYPE_DECLARATION;
00039 }
00040
00041 void
00042 tgsi_full_token_free(
00043 union tgsi_full_token *full_token )
00044 {
00045 if( full_token->Token.Type == TGSI_TOKEN_TYPE_IMMEDIATE ) {
00046 FREE( (void *) full_token->FullImmediate.u.Pointer );
00047 }
00048 }
00049
00050 unsigned
00051 tgsi_parse_init(
00052 struct tgsi_parse_context *ctx,
00053 const struct tgsi_token *tokens )
00054 {
00055 ctx->FullVersion.Version = *(struct tgsi_version *) &tokens[0];
00056 if( ctx->FullVersion.Version.MajorVersion > 1 ) {
00057 return TGSI_PARSE_ERROR;
00058 }
00059
00060 ctx->FullHeader.Header = *(struct tgsi_header *) &tokens[1];
00061 if( ctx->FullHeader.Header.HeaderSize >= 2 ) {
00062 ctx->FullHeader.Processor = *(struct tgsi_processor *) &tokens[2];
00063 }
00064 else {
00065 ctx->FullHeader.Processor = tgsi_default_processor();
00066 }
00067
00068 ctx->Tokens = tokens;
00069 ctx->Position = 1 + ctx->FullHeader.Header.HeaderSize;
00070
00071 tgsi_full_token_init( &ctx->FullToken );
00072
00073 return TGSI_PARSE_OK;
00074 }
00075
00076 void
00077 tgsi_parse_free(
00078 struct tgsi_parse_context *ctx )
00079 {
00080 tgsi_full_token_free( &ctx->FullToken );
00081 }
00082
00083 boolean
00084 tgsi_parse_end_of_tokens(
00085 struct tgsi_parse_context *ctx )
00086 {
00087 return ctx->Position >=
00088 1 + ctx->FullHeader.Header.HeaderSize + ctx->FullHeader.Header.BodySize;
00089 }
00090
00091 static void
00092 next_token(
00093 struct tgsi_parse_context *ctx,
00094 void *token )
00095 {
00096 assert( !tgsi_parse_end_of_tokens( ctx ) );
00097
00098 *(struct tgsi_token *) token = ctx->Tokens[ctx->Position++];
00099 }
00100
00101 void
00102 tgsi_parse_token(
00103 struct tgsi_parse_context *ctx )
00104 {
00105 struct tgsi_token token;
00106 unsigned i;
00107
00108 tgsi_full_token_free( &ctx->FullToken );
00109 tgsi_full_token_init( &ctx->FullToken );
00110
00111 next_token( ctx, &token );
00112
00113 switch( token.Type ) {
00114 case TGSI_TOKEN_TYPE_DECLARATION:
00115 {
00116 struct tgsi_full_declaration *decl = &ctx->FullToken.FullDeclaration;
00117
00118 *decl = tgsi_default_full_declaration();
00119 decl->Declaration = *(struct tgsi_declaration *) &token;
00120
00121 next_token( ctx, &decl->DeclarationRange );
00122
00123 if( decl->Declaration.Semantic ) {
00124 next_token( ctx, &decl->Semantic );
00125 }
00126
00127 break;
00128 }
00129
00130 case TGSI_TOKEN_TYPE_IMMEDIATE:
00131 {
00132 struct tgsi_full_immediate *imm = &ctx->FullToken.FullImmediate;
00133
00134 *imm = tgsi_default_full_immediate();
00135 imm->Immediate = *(struct tgsi_immediate *) &token;
00136
00137 assert( !imm->Immediate.Extended );
00138
00139 switch (imm->Immediate.DataType) {
00140 case TGSI_IMM_FLOAT32:
00141 imm->u.Pointer = MALLOC(
00142 sizeof( struct tgsi_immediate_float32 ) * (imm->Immediate.Size - 1) );
00143 for( i = 0; i < imm->Immediate.Size - 1; i++ ) {
00144 next_token( ctx, (struct tgsi_immediate_float32 *) &imm->u.ImmediateFloat32[i] );
00145 }
00146 break;
00147
00148 default:
00149 assert( 0 );
00150 }
00151
00152 break;
00153 }
00154
00155 case TGSI_TOKEN_TYPE_INSTRUCTION:
00156 {
00157 struct tgsi_full_instruction *inst = &ctx->FullToken.FullInstruction;
00158 unsigned extended;
00159
00160 *inst = tgsi_default_full_instruction();
00161 inst->Instruction = *(struct tgsi_instruction *) &token;
00162
00163 extended = inst->Instruction.Extended;
00164
00165 while( extended ) {
00166 struct tgsi_src_register_ext token;
00167
00168 next_token( ctx, &token );
00169
00170 switch( token.Type ) {
00171 case TGSI_INSTRUCTION_EXT_TYPE_NV:
00172 inst->InstructionExtNv =
00173 *(struct tgsi_instruction_ext_nv *) &token;
00174 break;
00175
00176 case TGSI_INSTRUCTION_EXT_TYPE_LABEL:
00177 inst->InstructionExtLabel =
00178 *(struct tgsi_instruction_ext_label *) &token;
00179 break;
00180
00181 case TGSI_INSTRUCTION_EXT_TYPE_TEXTURE:
00182 inst->InstructionExtTexture =
00183 *(struct tgsi_instruction_ext_texture *) &token;
00184 break;
00185
00186 default:
00187 assert( 0 );
00188 }
00189
00190 extended = token.Extended;
00191 }
00192
00193 assert( inst->Instruction.NumDstRegs <= TGSI_FULL_MAX_DST_REGISTERS );
00194
00195 for( i = 0; i < inst->Instruction.NumDstRegs; i++ ) {
00196 unsigned extended;
00197
00198 next_token( ctx, &inst->FullDstRegisters[i].DstRegister );
00199
00200
00201
00202
00203 assert( !inst->FullDstRegisters[i].DstRegister.Indirect );
00204 assert( !inst->FullDstRegisters[i].DstRegister.Dimension );
00205
00206 extended = inst->FullDstRegisters[i].DstRegister.Extended;
00207
00208 while( extended ) {
00209 struct tgsi_src_register_ext token;
00210
00211 next_token( ctx, &token );
00212
00213 switch( token.Type ) {
00214 case TGSI_DST_REGISTER_EXT_TYPE_CONDCODE:
00215 inst->FullDstRegisters[i].DstRegisterExtConcode =
00216 *(struct tgsi_dst_register_ext_concode *) &token;
00217 break;
00218
00219 case TGSI_DST_REGISTER_EXT_TYPE_MODULATE:
00220 inst->FullDstRegisters[i].DstRegisterExtModulate =
00221 *(struct tgsi_dst_register_ext_modulate *) &token;
00222 break;
00223
00224 default:
00225 assert( 0 );
00226 }
00227
00228 extended = token.Extended;
00229 }
00230 }
00231
00232 assert( inst->Instruction.NumSrcRegs <= TGSI_FULL_MAX_SRC_REGISTERS );
00233
00234 for( i = 0; i < inst->Instruction.NumSrcRegs; i++ ) {
00235 unsigned extended;
00236
00237 next_token( ctx, &inst->FullSrcRegisters[i].SrcRegister );
00238
00239 extended = inst->FullSrcRegisters[i].SrcRegister.Extended;
00240
00241 while( extended ) {
00242 struct tgsi_src_register_ext token;
00243
00244 next_token( ctx, &token );
00245
00246 switch( token.Type ) {
00247 case TGSI_SRC_REGISTER_EXT_TYPE_SWZ:
00248 inst->FullSrcRegisters[i].SrcRegisterExtSwz =
00249 *(struct tgsi_src_register_ext_swz *) &token;
00250 break;
00251
00252 case TGSI_SRC_REGISTER_EXT_TYPE_MOD:
00253 inst->FullSrcRegisters[i].SrcRegisterExtMod =
00254 *(struct tgsi_src_register_ext_mod *) &token;
00255 break;
00256
00257 default:
00258 assert( 0 );
00259 }
00260
00261 extended = token.Extended;
00262 }
00263
00264 if( inst->FullSrcRegisters[i].SrcRegister.Indirect ) {
00265 next_token( ctx, &inst->FullSrcRegisters[i].SrcRegisterInd );
00266
00267
00268
00269
00270 assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Indirect );
00271 assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Dimension );
00272 assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Extended );
00273 }
00274
00275 if( inst->FullSrcRegisters[i].SrcRegister.Dimension ) {
00276 next_token( ctx, &inst->FullSrcRegisters[i].SrcRegisterDim );
00277
00278
00279
00280
00281 assert( !inst->FullSrcRegisters[i].SrcRegisterDim.Dimension );
00282 assert( !inst->FullSrcRegisters[i].SrcRegisterDim.Extended );
00283
00284 if( inst->FullSrcRegisters[i].SrcRegisterDim.Indirect ) {
00285 next_token( ctx, &inst->FullSrcRegisters[i].SrcRegisterDimInd );
00286
00287
00288
00289
00290 assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Indirect );
00291 assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Dimension );
00292 assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Extended );
00293 }
00294 }
00295 }
00296
00297 break;
00298 }
00299
00300 default:
00301 assert( 0 );
00302 }
00303 }
00304
00305
00306 unsigned
00307 tgsi_num_tokens(const struct tgsi_token *tokens)
00308 {
00309 struct tgsi_parse_context ctx;
00310 if (tgsi_parse_init(&ctx, tokens) == TGSI_PARSE_OK) {
00311 unsigned len = (ctx.FullHeader.Header.HeaderSize +
00312 ctx.FullHeader.Header.BodySize +
00313 1);
00314 return len;
00315 }
00316 return 0;
00317 }
00318
00319
00323 struct tgsi_token *
00324 tgsi_dup_tokens(const struct tgsi_token *tokens)
00325 {
00326 unsigned n = tgsi_num_tokens(tokens);
00327 unsigned bytes = n * sizeof(struct tgsi_token);
00328 struct tgsi_token *new_tokens = (struct tgsi_token *) MALLOC(bytes);
00329 if (new_tokens)
00330 memcpy(new_tokens, tokens, bytes);
00331 return new_tokens;
00332 }