Go to the source code of this file.
Data Structures | |
struct | tgsi_transform_context |
Subclass this to add caller-specific data. More... | |
Functions | |
int | tgsi_transform_shader (const struct tgsi_token *tokens_in, struct tgsi_token *tokens_out, uint max_tokens_out, struct tgsi_transform_context *ctx) |
Apply user-defined transformations to the input shader to produce the output shader. |
int tgsi_transform_shader | ( | const struct tgsi_token * | tokens_in, | |
struct tgsi_token * | tokens_out, | |||
uint | max_tokens_out, | |||
struct tgsi_transform_context * | ctx | |||
) |
Apply user-defined transformations to the input shader to produce the output shader.
For example, a register search-and-replace operation could be applied by defining a transform_instruction() callback that examined and changed the instruction src/dest regs.
callback context init
Setup to begin parsing input shader
Setup output shader
Loop over incoming program tokens/instructions
Definition at line 93 of file tgsi_transform.c.
References assert, debug_printf(), emit_declaration(), tgsi_transform_context::emit_declaration, emit_immediate(), tgsi_transform_context::emit_immediate, emit_instruction(), tgsi_transform_context::emit_instruction, tgsi_transform_context::epilog, tgsi_full_token::FullDeclaration, tgsi_parse_context::FullHeader, tgsi_full_token::FullImmediate, tgsi_full_token::FullInstruction, tgsi_parse_context::FullToken, tgsi_transform_context::header, tgsi_transform_context::max_tokens_out, tgsi_processor::Processor, tgsi_full_header::Processor, tgsi_build_header(), tgsi_build_processor(), tgsi_build_version(), tgsi_parse_end_of_tokens(), tgsi_parse_free(), tgsi_parse_init(), TGSI_PARSE_OK, tgsi_parse_token(), TGSI_PROCESSOR_FRAGMENT, TGSI_PROCESSOR_GEOMETRY, TGSI_PROCESSOR_VERTEX, TGSI_TOKEN_TYPE_DECLARATION, TGSI_TOKEN_TYPE_IMMEDIATE, TGSI_TOKEN_TYPE_INSTRUCTION, tgsi_transform_context::ti, tgsi_full_token::Token, tgsi_transform_context::tokens_out, tgsi_transform_context::transform_declaration, tgsi_transform_context::transform_immediate, tgsi_transform_context::transform_instruction, and tgsi_token::Type.
00097 { 00098 uint procType; 00099 00100 /* input shader */ 00101 struct tgsi_parse_context parse; 00102 00103 /* output shader */ 00104 struct tgsi_processor *processor; 00105 00106 00110 ctx->emit_instruction = emit_instruction; 00111 ctx->emit_declaration = emit_declaration; 00112 ctx->emit_immediate = emit_immediate; 00113 ctx->tokens_out = tokens_out; 00114 ctx->max_tokens_out = max_tokens_out; 00115 00116 00120 if (tgsi_parse_init( &parse, tokens_in ) != TGSI_PARSE_OK) { 00121 debug_printf("tgsi_parse_init() failed in tgsi_transform_shader()!\n"); 00122 return -1; 00123 } 00124 procType = parse.FullHeader.Processor.Processor; 00125 assert(procType == TGSI_PROCESSOR_FRAGMENT || 00126 procType == TGSI_PROCESSOR_VERTEX || 00127 procType == TGSI_PROCESSOR_GEOMETRY); 00128 00129 00133 *(struct tgsi_version *) &tokens_out[0] = tgsi_build_version(); 00134 00135 ctx->header = (struct tgsi_header *) (tokens_out + 1); 00136 *ctx->header = tgsi_build_header(); 00137 00138 processor = (struct tgsi_processor *) (tokens_out + 2); 00139 *processor = tgsi_build_processor( procType, ctx->header ); 00140 00141 ctx->ti = 3; 00142 00143 00147 while( !tgsi_parse_end_of_tokens( &parse ) ) { 00148 00149 tgsi_parse_token( &parse ); 00150 00151 switch( parse.FullToken.Token.Type ) { 00152 case TGSI_TOKEN_TYPE_INSTRUCTION: 00153 { 00154 struct tgsi_full_instruction *fullinst 00155 = &parse.FullToken.FullInstruction; 00156 00157 if (ctx->transform_instruction) 00158 ctx->transform_instruction(ctx, fullinst); 00159 else 00160 ctx->emit_instruction(ctx, fullinst); 00161 } 00162 break; 00163 00164 case TGSI_TOKEN_TYPE_DECLARATION: 00165 { 00166 struct tgsi_full_declaration *fulldecl 00167 = &parse.FullToken.FullDeclaration; 00168 00169 if (ctx->transform_declaration) 00170 ctx->transform_declaration(ctx, fulldecl); 00171 else 00172 ctx->emit_declaration(ctx, fulldecl); 00173 } 00174 break; 00175 00176 case TGSI_TOKEN_TYPE_IMMEDIATE: 00177 { 00178 struct tgsi_full_immediate *fullimm 00179 = &parse.FullToken.FullImmediate; 00180 00181 if (ctx->transform_immediate) 00182 ctx->transform_immediate(ctx, fullimm); 00183 else 00184 ctx->emit_immediate(ctx, fullimm); 00185 } 00186 break; 00187 00188 default: 00189 assert( 0 ); 00190 } 00191 } 00192 00193 if (ctx->epilog) { 00194 ctx->epilog(ctx); 00195 } 00196 00197 tgsi_parse_free (&parse); 00198 00199 return ctx->ti; 00200 }