gallium: remove the swizzling parts of ExtSwizzle
[mesa.git] / src / gallium / auxiliary / tgsi / tgsi_scan.c
index be4870a498362939618e0cb43be917b7e983b54f..f9c16f1b6cb78968ed029ad4862bfe9af6775057 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
@@ -42,6 +43,9 @@
 
 
 /**
+ * Scan the given TGSI shader to collect information such as number of
+ * registers used, special instructions used, etc.
+ * \return info  the result of the scan
  */
 void
 tgsi_scan_shader(const struct tgsi_token *tokens,
@@ -79,38 +83,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++) {
+            const uint file = fulldecl->Declaration.File;
+            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);
+               info->file_max[file] = MAX2(info->file_max[file], (int)reg);
 
                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->input_interpolate[reg] = (ubyte)fulldecl->Declaration.Interpolate;
                   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;
+               else if (file == TGSI_FILE_OUTPUT) {
+                  info->output_semantic_name[reg] = (ubyte)fulldecl->Semantic.SemanticName;
+                  info->output_semantic_index[reg] = (ubyte)fulldecl->Semantic.SemanticIndex;
                   info->num_outputs++;
                }
 
@@ -125,7 +152,14 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
          break;
 
       case TGSI_TOKEN_TYPE_IMMEDIATE:
-         info->immediate_count++;
+         {
+            uint reg = info->immediate_count++;
+            uint file = TGSI_FILE_IMMEDIATE;
+
+            info->file_mask[file] |= (1 << reg);
+            info->file_count[file]++;
+            info->file_max[file] = MAX2(info->file_max[file], (int)reg);
+         }
          break;
 
       default:
@@ -133,9 +167,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]);
 
@@ -197,11 +228,6 @@ tgsi_is_passthrough_shader(const struct tgsi_token *tokens)
                 src->SrcRegister.SwizzleZ != TGSI_SWIZZLE_Z ||
                 src->SrcRegister.SwizzleW != TGSI_SWIZZLE_W ||
 
-                src->SrcRegisterExtSwz.ExtSwizzleX != TGSI_EXTSWIZZLE_X ||
-                src->SrcRegisterExtSwz.ExtSwizzleY != TGSI_EXTSWIZZLE_Y ||
-                src->SrcRegisterExtSwz.ExtSwizzleZ != TGSI_EXTSWIZZLE_Z ||
-                src->SrcRegisterExtSwz.ExtSwizzleW != TGSI_EXTSWIZZLE_W ||
-
                 dst->DstRegister.WriteMask != TGSI_WRITEMASK_XYZW)
             {
                tgsi_parse_free(&parse);