tgsi_scan.h File Reference

Include dependency graph for tgsi_scan.h:

This graph shows which files directly or indirectly include this file:

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].


Function Documentation

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 }


Generated on Tue Sep 29 06:25:26 2009 for Gallium3D by  doxygen 1.5.4