tgsi_scan.c

Go to the documentation of this file.
00001 /**************************************************************************
00002  * 
00003  * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
00004  * All Rights Reserved.
00005  * Copyright 2008 VMware, Inc.  All rights Reserved.
00006  *
00007  * Permission is hereby granted, free of charge, to any person obtaining a
00008  * copy of this software and associated documentation files (the
00009  * "Software"), to deal in the Software without restriction, including
00010  * without limitation the rights to use, copy, modify, merge, publish,
00011  * distribute, sub license, and/or sell copies of the Software, and to
00012  * permit persons to whom the Software is furnished to do so, subject to
00013  * the following conditions:
00014  * 
00015  * The above copyright notice and this permission notice (including the
00016  * next paragraph) shall be included in all copies or substantial portions
00017  * of the Software.
00018  * 
00019  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00020  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00021  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
00022  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
00023  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
00024  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
00025  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00026  * 
00027  **************************************************************************/
00028 
00037 #include "util/u_math.h"
00038 #include "tgsi/tgsi_build.h"
00039 #include "tgsi/tgsi_parse.h"
00040 #include "tgsi/tgsi_scan.h"
00041 
00042 
00043 
00044 
00047 void
00048 tgsi_scan_shader(const struct tgsi_token *tokens,
00049                  struct tgsi_shader_info *info)
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 }
00165 
00166 
00167 
00173 boolean
00174 tgsi_is_passthrough_shader(const struct tgsi_token *tokens)
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 }

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