tgsi: scan for additional info: uses_fogcoord, uses_frontfacing
authorBrian Paul <brianp@vmware.com>
Fri, 19 Dec 2008 01:06:38 +0000 (18:06 -0700)
committerBrian Paul <brianp@vmware.com>
Fri, 19 Dec 2008 01:08:32 +0000 (18:08 -0700)
src/gallium/auxiliary/tgsi/tgsi_scan.c
src/gallium/auxiliary/tgsi/tgsi_scan.h

index be4870a498362939618e0cb43be917b7e983b54f..cfc7ea8e898fb3e5988ebd330338530f3bb4231b 100644 (file)
@@ -2,6 +2,7 @@
  * 
  * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
  * All Rights Reserved.
+ * Copyright 2008 VMware, Inc.  All rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the
@@ -79,38 +80,61 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
       switch( parse.FullToken.Token.Type ) {
       case TGSI_TOKEN_TYPE_INSTRUCTION:
          {
-            struct tgsi_full_instruction *fullinst
+            const struct tgsi_full_instruction *fullinst
                = &parse.FullToken.FullInstruction;
 
             assert(fullinst->Instruction.Opcode < TGSI_OPCODE_LAST);
             info->opcode_count[fullinst->Instruction.Opcode]++;
+
+            /* special case: scan fragment shaders for use of the fog
+             * input/attribute.  The X component is fog, the Y component
+             * is the front/back-face flag.
+             */
+            if (procType == TGSI_PROCESSOR_FRAGMENT) {
+               uint i;
+               for (i = 0; i < fullinst->Instruction.NumSrcRegs; i++) {
+                  const struct tgsi_full_src_register *src =
+                     &fullinst->FullSrcRegisters[i];
+                  if (src->SrcRegister.File == TGSI_FILE_INPUT) {
+                     const int ind = src->SrcRegister.Index;
+                     if (info->input_semantic_name[ind] == TGSI_SEMANTIC_FOG) {
+                        if (src->SrcRegister.SwizzleX == TGSI_SWIZZLE_X) {
+                           info->uses_fogcoord = TRUE;
+                        }
+                        else if (src->SrcRegister.SwizzleX == TGSI_SWIZZLE_Y) {
+                           info->uses_frontfacing = TRUE;
+                        }
+                     }
+                  }
+               }
+            }
          }
          break;
 
       case TGSI_TOKEN_TYPE_DECLARATION:
          {
-            struct tgsi_full_declaration *fulldecl
+            const struct tgsi_full_declaration *fulldecl
                = &parse.FullToken.FullDeclaration;
             uint file = fulldecl->Declaration.File;
-            uint i;
-            for (i = fulldecl->DeclarationRange.First;
-                 i <= fulldecl->DeclarationRange.Last;
-                 i++) {
+            uint reg;
+            for (reg = fulldecl->DeclarationRange.First;
+                 reg <= fulldecl->DeclarationRange.Last;
+                 reg++) {
 
                /* only first 32 regs will appear in this bitfield */
-               info->file_mask[file] |= (1 << i);
+               info->file_mask[file] |= (1 << reg);
                info->file_count[file]++;
                info->file_max[file] = MAX2(info->file_max[file], (int)i);
 
                if (file == TGSI_FILE_INPUT) {
-                  info->input_semantic_name[i] = (ubyte)fulldecl->Semantic.SemanticName;
-                  info->input_semantic_index[i] = (ubyte)fulldecl->Semantic.SemanticIndex;
+                  info->input_semantic_name[reg] = (ubyte)fulldecl->Semantic.SemanticName;
+                  info->input_semantic_index[reg] = (ubyte)fulldecl->Semantic.SemanticIndex;
                   info->num_inputs++;
                }
 
                if (file == TGSI_FILE_OUTPUT) {
-                  info->output_semantic_name[i] = (ubyte)fulldecl->Semantic.SemanticName;
-                  info->output_semantic_index[i] = (ubyte)fulldecl->Semantic.SemanticIndex;
+                  info->output_semantic_name[reg] = (ubyte)fulldecl->Semantic.SemanticName;
+                  info->output_semantic_index[reg] = (ubyte)fulldecl->Semantic.SemanticIndex;
                   info->num_outputs++;
                }
 
@@ -133,9 +157,6 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
       }
    }
 
-   assert( info->file_max[TGSI_FILE_INPUT] + 1 == info->num_inputs );
-   assert( info->file_max[TGSI_FILE_OUTPUT] + 1 == info->num_outputs );
-
    info->uses_kill = (info->opcode_count[TGSI_OPCODE_KIL] ||
                       info->opcode_count[TGSI_OPCODE_KILP]);
 
index 5cb6efb3439dd04a7fd1816e59d3e356b9e06711..2c1a75bc812e85a0466a51cd2dab7343338b2b54 100644 (file)
@@ -41,7 +41,6 @@ struct tgsi_shader_info
 {
    uint num_tokens;
 
-   /* XXX eventually remove the corresponding fields from pipe_shader_state: */
    ubyte num_inputs;
    ubyte num_outputs;
    ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS]; /**< TGSI_SEMANTIC_x */
@@ -59,6 +58,8 @@ struct tgsi_shader_info
 
    boolean writes_z;  /**< does fragment shader write Z value? */
    boolean uses_kill;  /**< KIL or KILP instruction used? */
+   boolean uses_fogcoord; /**< fragment shader uses fog coord? */
+   boolean uses_frontfacing; /**< fragment shader uses front/back-face flag? */
 };