Go to the source code of this file.
Data Structures | |
struct | tgsi_shader_info |
Shader summary info. More... | |
Functions | |
void | tgsi_scan_shader (const struct tgsi_token *tokens, struct tgsi_shader_info *info) |
TGSI program scan utility. | |
boolean | tgsi_is_passthrough_shader (const struct tgsi_token *tokens) |
Check if the given shader is a "passthrough" shader consisting of only MOV instructions of the form: MOV OUT[n], IN[n]. |
boolean tgsi_is_passthrough_shader | ( | const struct tgsi_token * | tokens | ) |
Check if the given shader is a "passthrough" shader consisting of only MOV instructions of the form: MOV OUT[n], IN[n].
Setup to begin parsing input shader
Loop over incoming program tokens/instructions
Definition at line 174 of file tgsi_scan.c.
References tgsi_src_register_ext_mod::Absolute, tgsi_src_register_ext_mod::Bias, tgsi_src_register_ext_mod::Complement, debug_printf(), tgsi_full_dst_register::DstRegister, tgsi_src_register_ext_swz::ExtSwizzleW, tgsi_src_register_ext_swz::ExtSwizzleX, tgsi_src_register_ext_swz::ExtSwizzleY, tgsi_src_register_ext_swz::ExtSwizzleZ, FALSE, tgsi_dst_register::File, tgsi_src_register::File, tgsi_full_instruction::FullDstRegisters, tgsi_full_token::FullInstruction, tgsi_full_instruction::FullSrcRegisters, tgsi_parse_context::FullToken, tgsi_dst_register::Index, tgsi_src_register::Index, tgsi_full_instruction::Instruction, tgsi_src_register_ext_mod::Negate, tgsi_src_register::Negate, tgsi_instruction::Opcode, tgsi_src_register_ext_mod::Scale2X, tgsi_full_src_register::SrcRegister, tgsi_full_src_register::SrcRegisterExtMod, tgsi_full_src_register::SrcRegisterExtSwz, tgsi_src_register::SwizzleW, tgsi_src_register::SwizzleX, tgsi_src_register::SwizzleY, tgsi_src_register::SwizzleZ, TGSI_EXTSWIZZLE_W, TGSI_EXTSWIZZLE_X, TGSI_EXTSWIZZLE_Y, TGSI_EXTSWIZZLE_Z, TGSI_FILE_INPUT, TGSI_FILE_OUTPUT, TGSI_OPCODE_MOV, tgsi_parse_end_of_tokens(), tgsi_parse_free(), tgsi_parse_init(), TGSI_PARSE_OK, tgsi_parse_token(), TGSI_SWIZZLE_W, TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y, TGSI_SWIZZLE_Z, TGSI_TOKEN_TYPE_DECLARATION, TGSI_TOKEN_TYPE_IMMEDIATE, TGSI_TOKEN_TYPE_INSTRUCTION, TGSI_WRITEMASK_XYZW, tgsi_full_token::Token, TRUE, tgsi_token::Type, and tgsi_dst_register::WriteMask.
00175 { 00176 struct tgsi_parse_context parse; 00177 00181 if (tgsi_parse_init(&parse, tokens) != TGSI_PARSE_OK) { 00182 debug_printf("tgsi_parse_init() failed in tgsi_is_passthrough_shader()!\n"); 00183 return FALSE; 00184 } 00185 00189 while (!tgsi_parse_end_of_tokens(&parse)) { 00190 00191 tgsi_parse_token(&parse); 00192 00193 switch (parse.FullToken.Token.Type) { 00194 case TGSI_TOKEN_TYPE_INSTRUCTION: 00195 { 00196 struct tgsi_full_instruction *fullinst = 00197 &parse.FullToken.FullInstruction; 00198 const struct tgsi_full_src_register *src = 00199 &fullinst->FullSrcRegisters[0]; 00200 const struct tgsi_full_dst_register *dst = 00201 &fullinst->FullDstRegisters[0]; 00202 00203 /* Do a whole bunch of checks for a simple move */ 00204 if (fullinst->Instruction.Opcode != TGSI_OPCODE_MOV || 00205 src->SrcRegister.File != TGSI_FILE_INPUT || 00206 dst->DstRegister.File != TGSI_FILE_OUTPUT || 00207 src->SrcRegister.Index != dst->DstRegister.Index || 00208 00209 src->SrcRegister.Negate || 00210 src->SrcRegisterExtMod.Negate || 00211 src->SrcRegisterExtMod.Absolute || 00212 src->SrcRegisterExtMod.Scale2X || 00213 src->SrcRegisterExtMod.Bias || 00214 src->SrcRegisterExtMod.Complement || 00215 00216 src->SrcRegister.SwizzleX != TGSI_SWIZZLE_X || 00217 src->SrcRegister.SwizzleY != TGSI_SWIZZLE_Y || 00218 src->SrcRegister.SwizzleZ != TGSI_SWIZZLE_Z || 00219 src->SrcRegister.SwizzleW != TGSI_SWIZZLE_W || 00220 00221 src->SrcRegisterExtSwz.ExtSwizzleX != TGSI_EXTSWIZZLE_X || 00222 src->SrcRegisterExtSwz.ExtSwizzleY != TGSI_EXTSWIZZLE_Y || 00223 src->SrcRegisterExtSwz.ExtSwizzleZ != TGSI_EXTSWIZZLE_Z || 00224 src->SrcRegisterExtSwz.ExtSwizzleW != TGSI_EXTSWIZZLE_W || 00225 00226 dst->DstRegister.WriteMask != TGSI_WRITEMASK_XYZW) 00227 { 00228 tgsi_parse_free(&parse); 00229 return FALSE; 00230 } 00231 } 00232 break; 00233 00234 case TGSI_TOKEN_TYPE_DECLARATION: 00235 /* fall-through */ 00236 case TGSI_TOKEN_TYPE_IMMEDIATE: 00237 /* fall-through */ 00238 default: 00239 ; /* no-op */ 00240 } 00241 } 00242 00243 tgsi_parse_free(&parse); 00244 00245 /* if we get here, it's a pass-through shader */ 00246 return TRUE; 00247 }
void tgsi_scan_shader | ( | const struct tgsi_token * | tokens, | |
struct tgsi_shader_info * | info | |||
) |
TGSI program scan utility.
Used to determine which registers and instructions are used by a shader.
Authors: Brian Paul
Setup to begin parsing input shader
Loop over incoming program tokens/instructions
Definition at line 48 of file tgsi_scan.c.
References assert, debug_printf(), tgsi_full_declaration::Declaration, tgsi_full_declaration::DeclarationRange, tgsi_declaration::File, tgsi_src_register::File, tgsi_shader_info::file_count, tgsi_shader_info::file_mask, tgsi_shader_info::file_max, tgsi_declaration_range::First, tgsi_full_token::FullDeclaration, tgsi_parse_context::FullHeader, tgsi_full_token::FullInstruction, tgsi_full_instruction::FullSrcRegisters, tgsi_parse_context::FullToken, tgsi_shader_info::immediate_count, tgsi_src_register::Index, tgsi_shader_info::input_semantic_index, tgsi_shader_info::input_semantic_name, tgsi_full_instruction::Instruction, tgsi_declaration_range::Last, MAX2, tgsi_shader_info::num_inputs, tgsi_shader_info::num_outputs, tgsi_shader_info::num_tokens, tgsi_instruction::NumSrcRegs, tgsi_instruction::Opcode, tgsi_shader_info::opcode_count, tgsi_shader_info::output_semantic_index, tgsi_shader_info::output_semantic_name, tgsi_processor::Processor, tgsi_full_header::Processor, tgsi_full_declaration::Semantic, tgsi_declaration_semantic::SemanticIndex, tgsi_declaration_semantic::SemanticName, tgsi_full_src_register::SrcRegister, tgsi_src_register::SwizzleX, TGSI_FILE_COUNT, TGSI_FILE_INPUT, TGSI_FILE_OUTPUT, TGSI_OPCODE_KIL, TGSI_OPCODE_KILP, TGSI_OPCODE_LAST, 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_SEMANTIC_FOG, TGSI_SEMANTIC_POSITION, TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y, TGSI_TOKEN_TYPE_DECLARATION, TGSI_TOKEN_TYPE_IMMEDIATE, TGSI_TOKEN_TYPE_INSTRUCTION, tgsi_full_token::Token, TRUE, tgsi_token::Type, tgsi_shader_info::uses_fogcoord, tgsi_shader_info::uses_frontfacing, tgsi_shader_info::uses_kill, and tgsi_shader_info::writes_z.
00050 { 00051 uint procType, i; 00052 struct tgsi_parse_context parse; 00053 00054 memset(info, 0, sizeof(*info)); 00055 for (i = 0; i < TGSI_FILE_COUNT; i++) 00056 info->file_max[i] = -1; 00057 00061 if (tgsi_parse_init( &parse, tokens ) != TGSI_PARSE_OK) { 00062 debug_printf("tgsi_parse_init() failed in tgsi_scan_shader()!\n"); 00063 return; 00064 } 00065 procType = parse.FullHeader.Processor.Processor; 00066 assert(procType == TGSI_PROCESSOR_FRAGMENT || 00067 procType == TGSI_PROCESSOR_VERTEX || 00068 procType == TGSI_PROCESSOR_GEOMETRY); 00069 00070 00074 while( !tgsi_parse_end_of_tokens( &parse ) ) { 00075 00076 info->num_tokens++; 00077 00078 tgsi_parse_token( &parse ); 00079 00080 switch( parse.FullToken.Token.Type ) { 00081 case TGSI_TOKEN_TYPE_INSTRUCTION: 00082 { 00083 const struct tgsi_full_instruction *fullinst 00084 = &parse.FullToken.FullInstruction; 00085 00086 assert(fullinst->Instruction.Opcode < TGSI_OPCODE_LAST); 00087 info->opcode_count[fullinst->Instruction.Opcode]++; 00088 00089 /* special case: scan fragment shaders for use of the fog 00090 * input/attribute. The X component is fog, the Y component 00091 * is the front/back-face flag. 00092 */ 00093 if (procType == TGSI_PROCESSOR_FRAGMENT) { 00094 uint i; 00095 for (i = 0; i < fullinst->Instruction.NumSrcRegs; i++) { 00096 const struct tgsi_full_src_register *src = 00097 &fullinst->FullSrcRegisters[i]; 00098 if (src->SrcRegister.File == TGSI_FILE_INPUT) { 00099 const int ind = src->SrcRegister.Index; 00100 if (info->input_semantic_name[ind] == TGSI_SEMANTIC_FOG) { 00101 if (src->SrcRegister.SwizzleX == TGSI_SWIZZLE_X) { 00102 info->uses_fogcoord = TRUE; 00103 } 00104 else if (src->SrcRegister.SwizzleX == TGSI_SWIZZLE_Y) { 00105 info->uses_frontfacing = TRUE; 00106 } 00107 } 00108 } 00109 } 00110 } 00111 } 00112 break; 00113 00114 case TGSI_TOKEN_TYPE_DECLARATION: 00115 { 00116 const struct tgsi_full_declaration *fulldecl 00117 = &parse.FullToken.FullDeclaration; 00118 uint file = fulldecl->Declaration.File; 00119 uint reg; 00120 for (reg = fulldecl->DeclarationRange.First; 00121 reg <= fulldecl->DeclarationRange.Last; 00122 reg++) { 00123 00124 /* only first 32 regs will appear in this bitfield */ 00125 info->file_mask[file] |= (1 << reg); 00126 info->file_count[file]++; 00127 info->file_max[file] = MAX2(info->file_max[file], (int)reg); 00128 00129 if (file == TGSI_FILE_INPUT) { 00130 info->input_semantic_name[reg] = (ubyte)fulldecl->Semantic.SemanticName; 00131 info->input_semantic_index[reg] = (ubyte)fulldecl->Semantic.SemanticIndex; 00132 info->num_inputs++; 00133 } 00134 00135 if (file == TGSI_FILE_OUTPUT) { 00136 info->output_semantic_name[reg] = (ubyte)fulldecl->Semantic.SemanticName; 00137 info->output_semantic_index[reg] = (ubyte)fulldecl->Semantic.SemanticIndex; 00138 info->num_outputs++; 00139 } 00140 00141 /* special case */ 00142 if (procType == TGSI_PROCESSOR_FRAGMENT && 00143 file == TGSI_FILE_OUTPUT && 00144 fulldecl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION) { 00145 info->writes_z = TRUE; 00146 } 00147 } 00148 } 00149 break; 00150 00151 case TGSI_TOKEN_TYPE_IMMEDIATE: 00152 info->immediate_count++; 00153 break; 00154 00155 default: 00156 assert( 0 ); 00157 } 00158 } 00159 00160 info->uses_kill = (info->opcode_count[TGSI_OPCODE_KIL] || 00161 info->opcode_count[TGSI_OPCODE_KILP]); 00162 00163 tgsi_parse_free (&parse); 00164 }