11d77d6caf647424f9c1c481145be0465e96c9e3eBrian/**************************************************************************
21d77d6caf647424f9c1c481145be0465e96c9e3eBrian *
31d77d6caf647424f9c1c481145be0465e96c9e3eBrian * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
41d77d6caf647424f9c1c481145be0465e96c9e3eBrian * All Rights Reserved.
559a168d5c9b5f478e4e8bedcd8522e359e98987eBrian Paul * Copyright 2008 VMware, Inc.  All rights Reserved.
61d77d6caf647424f9c1c481145be0465e96c9e3eBrian *
71d77d6caf647424f9c1c481145be0465e96c9e3eBrian * Permission is hereby granted, free of charge, to any person obtaining a
81d77d6caf647424f9c1c481145be0465e96c9e3eBrian * copy of this software and associated documentation files (the
91d77d6caf647424f9c1c481145be0465e96c9e3eBrian * "Software"), to deal in the Software without restriction, including
101d77d6caf647424f9c1c481145be0465e96c9e3eBrian * without limitation the rights to use, copy, modify, merge, publish,
111d77d6caf647424f9c1c481145be0465e96c9e3eBrian * distribute, sub license, and/or sell copies of the Software, and to
121d77d6caf647424f9c1c481145be0465e96c9e3eBrian * permit persons to whom the Software is furnished to do so, subject to
131d77d6caf647424f9c1c481145be0465e96c9e3eBrian * the following conditions:
141d77d6caf647424f9c1c481145be0465e96c9e3eBrian *
151d77d6caf647424f9c1c481145be0465e96c9e3eBrian * The above copyright notice and this permission notice (including the
161d77d6caf647424f9c1c481145be0465e96c9e3eBrian * next paragraph) shall be included in all copies or substantial portions
171d77d6caf647424f9c1c481145be0465e96c9e3eBrian * of the Software.
181d77d6caf647424f9c1c481145be0465e96c9e3eBrian *
191d77d6caf647424f9c1c481145be0465e96c9e3eBrian * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
201d77d6caf647424f9c1c481145be0465e96c9e3eBrian * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
211d77d6caf647424f9c1c481145be0465e96c9e3eBrian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
221d77d6caf647424f9c1c481145be0465e96c9e3eBrian * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
231d77d6caf647424f9c1c481145be0465e96c9e3eBrian * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
241d77d6caf647424f9c1c481145be0465e96c9e3eBrian * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
251d77d6caf647424f9c1c481145be0465e96c9e3eBrian * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
261d77d6caf647424f9c1c481145be0465e96c9e3eBrian *
271d77d6caf647424f9c1c481145be0465e96c9e3eBrian **************************************************************************/
281d77d6caf647424f9c1c481145be0465e96c9e3eBrian
291d77d6caf647424f9c1c481145be0465e96c9e3eBrian/**
301d77d6caf647424f9c1c481145be0465e96c9e3eBrian * TGSI program scan utility.
311d77d6caf647424f9c1c481145be0465e96c9e3eBrian * Used to determine which registers and instructions are used by a shader.
321d77d6caf647424f9c1c481145be0465e96c9e3eBrian *
331d77d6caf647424f9c1c481145be0465e96c9e3eBrian * Authors:  Brian Paul
341d77d6caf647424f9c1c481145be0465e96c9e3eBrian */
351d77d6caf647424f9c1c481145be0465e96c9e3eBrian
361d77d6caf647424f9c1c481145be0465e96c9e3eBrian
374f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_math.h"
384f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "tgsi/tgsi_parse.h"
39abe4f3d1aa68aec70d329447abc890b3eaaba9cbJosé Fonseca#include "tgsi/tgsi_util.h"
404f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "tgsi/tgsi_scan.h"
411d77d6caf647424f9c1c481145be0465e96c9e3eBrian
421d77d6caf647424f9c1c481145be0465e96c9e3eBrian
431d77d6caf647424f9c1c481145be0465e96c9e3eBrian
441d77d6caf647424f9c1c481145be0465e96c9e3eBrian
451d77d6caf647424f9c1c481145be0465e96c9e3eBrian/**
461907135235a684872706d1a28ea8e2b4e1b6e7d3Brian Paul * Scan the given TGSI shader to collect information such as number of
471907135235a684872706d1a28ea8e2b4e1b6e7d3Brian Paul * registers used, special instructions used, etc.
481907135235a684872706d1a28ea8e2b4e1b6e7d3Brian Paul * \return info  the result of the scan
491d77d6caf647424f9c1c481145be0465e96c9e3eBrian */
501d77d6caf647424f9c1c481145be0465e96c9e3eBrianvoid
511d77d6caf647424f9c1c481145be0465e96c9e3eBriantgsi_scan_shader(const struct tgsi_token *tokens,
521d77d6caf647424f9c1c481145be0465e96c9e3eBrian                 struct tgsi_shader_info *info)
531d77d6caf647424f9c1c481145be0465e96c9e3eBrian{
543197ad5a56ee94773f974ac727b316c5adfe1b6fBrian   uint procType, i;
551d77d6caf647424f9c1c481145be0465e96c9e3eBrian   struct tgsi_parse_context parse;
561d77d6caf647424f9c1c481145be0465e96c9e3eBrian
571d77d6caf647424f9c1c481145be0465e96c9e3eBrian   memset(info, 0, sizeof(*info));
583197ad5a56ee94773f974ac727b316c5adfe1b6fBrian   for (i = 0; i < TGSI_FILE_COUNT; i++)
593197ad5a56ee94773f974ac727b316c5adfe1b6fBrian      info->file_max[i] = -1;
601d77d6caf647424f9c1c481145be0465e96c9e3eBrian
611d77d6caf647424f9c1c481145be0465e96c9e3eBrian   /**
621d77d6caf647424f9c1c481145be0465e96c9e3eBrian    ** Setup to begin parsing input shader
631d77d6caf647424f9c1c481145be0465e96c9e3eBrian    **/
641d77d6caf647424f9c1c481145be0465e96c9e3eBrian   if (tgsi_parse_init( &parse, tokens ) != TGSI_PARSE_OK) {
651d77d6caf647424f9c1c481145be0465e96c9e3eBrian      debug_printf("tgsi_parse_init() failed in tgsi_scan_shader()!\n");
661d77d6caf647424f9c1c481145be0465e96c9e3eBrian      return;
671d77d6caf647424f9c1c481145be0465e96c9e3eBrian   }
681d77d6caf647424f9c1c481145be0465e96c9e3eBrian   procType = parse.FullHeader.Processor.Processor;
691d77d6caf647424f9c1c481145be0465e96c9e3eBrian   assert(procType == TGSI_PROCESSOR_FRAGMENT ||
701d77d6caf647424f9c1c481145be0465e96c9e3eBrian          procType == TGSI_PROCESSOR_VERTEX ||
7163428372cadc73a7124f4e7d383eb86a0c7affd7Francisco Jerez          procType == TGSI_PROCESSOR_GEOMETRY ||
7263428372cadc73a7124f4e7d383eb86a0c7affd7Francisco Jerez          procType == TGSI_PROCESSOR_COMPUTE);
731d77d6caf647424f9c1c481145be0465e96c9e3eBrian
741d77d6caf647424f9c1c481145be0465e96c9e3eBrian
751d77d6caf647424f9c1c481145be0465e96c9e3eBrian   /**
761d77d6caf647424f9c1c481145be0465e96c9e3eBrian    ** Loop over incoming program tokens/instructions
771d77d6caf647424f9c1c481145be0465e96c9e3eBrian    */
781d77d6caf647424f9c1c481145be0465e96c9e3eBrian   while( !tgsi_parse_end_of_tokens( &parse ) ) {
791d77d6caf647424f9c1c481145be0465e96c9e3eBrian
801410b7bb509ef37c41043b173bc1047257483af0Brian      info->num_tokens++;
811410b7bb509ef37c41043b173bc1047257483af0Brian
821d77d6caf647424f9c1c481145be0465e96c9e3eBrian      tgsi_parse_token( &parse );
831d77d6caf647424f9c1c481145be0465e96c9e3eBrian
841d77d6caf647424f9c1c481145be0465e96c9e3eBrian      switch( parse.FullToken.Token.Type ) {
851d77d6caf647424f9c1c481145be0465e96c9e3eBrian      case TGSI_TOKEN_TYPE_INSTRUCTION:
861d77d6caf647424f9c1c481145be0465e96c9e3eBrian         {
8759a168d5c9b5f478e4e8bedcd8522e359e98987eBrian Paul            const struct tgsi_full_instruction *fullinst
881d77d6caf647424f9c1c481145be0465e96c9e3eBrian               = &parse.FullToken.FullInstruction;
89abe4f3d1aa68aec70d329447abc890b3eaaba9cbJosé Fonseca            uint i;
901d77d6caf647424f9c1c481145be0465e96c9e3eBrian
911d77d6caf647424f9c1c481145be0465e96c9e3eBrian            assert(fullinst->Instruction.Opcode < TGSI_OPCODE_LAST);
921d77d6caf647424f9c1c481145be0465e96c9e3eBrian            info->opcode_count[fullinst->Instruction.Opcode]++;
9359a168d5c9b5f478e4e8bedcd8522e359e98987eBrian Paul
94abe4f3d1aa68aec70d329447abc890b3eaaba9cbJosé Fonseca            for (i = 0; i < fullinst->Instruction.NumSrcRegs; i++) {
95abe4f3d1aa68aec70d329447abc890b3eaaba9cbJosé Fonseca               const struct tgsi_full_src_register *src =
96abe4f3d1aa68aec70d329447abc890b3eaaba9cbJosé Fonseca                  &fullinst->Src[i];
97abe4f3d1aa68aec70d329447abc890b3eaaba9cbJosé Fonseca               int ind = src->Register.Index;
98abe4f3d1aa68aec70d329447abc890b3eaaba9cbJosé Fonseca
99abe4f3d1aa68aec70d329447abc890b3eaaba9cbJosé Fonseca               /* Mark which inputs are effectively used */
100abe4f3d1aa68aec70d329447abc890b3eaaba9cbJosé Fonseca               if (src->Register.File == TGSI_FILE_INPUT) {
101abe4f3d1aa68aec70d329447abc890b3eaaba9cbJosé Fonseca                  unsigned usage_mask;
102abe4f3d1aa68aec70d329447abc890b3eaaba9cbJosé Fonseca                  usage_mask = tgsi_util_get_inst_usage_mask(fullinst, i);
103abe4f3d1aa68aec70d329447abc890b3eaaba9cbJosé Fonseca                  if (src->Register.Indirect) {
104abe4f3d1aa68aec70d329447abc890b3eaaba9cbJosé Fonseca                     for (ind = 0; ind < info->num_inputs; ++ind) {
105abe4f3d1aa68aec70d329447abc890b3eaaba9cbJosé Fonseca                        info->input_usage_mask[ind] |= usage_mask;
106abe4f3d1aa68aec70d329447abc890b3eaaba9cbJosé Fonseca                     }
107abe4f3d1aa68aec70d329447abc890b3eaaba9cbJosé Fonseca                  } else {
108abe4f3d1aa68aec70d329447abc890b3eaaba9cbJosé Fonseca                     assert(ind >= 0);
109abe4f3d1aa68aec70d329447abc890b3eaaba9cbJosé Fonseca                     assert(ind < PIPE_MAX_SHADER_INPUTS);
110abe4f3d1aa68aec70d329447abc890b3eaaba9cbJosé Fonseca                     info->input_usage_mask[ind] |= usage_mask;
111abe4f3d1aa68aec70d329447abc890b3eaaba9cbJosé Fonseca                  }
112c8c2fc9a7a029bb61520973e55fb3cec18f13e20Jakob Bornecrantz
113c8c2fc9a7a029bb61520973e55fb3cec18f13e20Jakob Bornecrantz                  if (procType == TGSI_PROCESSOR_FRAGMENT &&
114c8c2fc9a7a029bb61520973e55fb3cec18f13e20Jakob Bornecrantz                      src->Register.File == TGSI_FILE_INPUT &&
115c8c2fc9a7a029bb61520973e55fb3cec18f13e20Jakob Bornecrantz                      info->reads_position &&
116c8c2fc9a7a029bb61520973e55fb3cec18f13e20Jakob Bornecrantz                      src->Register.Index == 0 &&
117c8c2fc9a7a029bb61520973e55fb3cec18f13e20Jakob Bornecrantz                      (src->Register.SwizzleX == TGSI_SWIZZLE_Z ||
118c8c2fc9a7a029bb61520973e55fb3cec18f13e20Jakob Bornecrantz                       src->Register.SwizzleY == TGSI_SWIZZLE_Z ||
119c8c2fc9a7a029bb61520973e55fb3cec18f13e20Jakob Bornecrantz                       src->Register.SwizzleZ == TGSI_SWIZZLE_Z ||
120c8c2fc9a7a029bb61520973e55fb3cec18f13e20Jakob Bornecrantz                       src->Register.SwizzleW == TGSI_SWIZZLE_Z)) {
121c8c2fc9a7a029bb61520973e55fb3cec18f13e20Jakob Bornecrantz                     info->reads_z = TRUE;
122c8c2fc9a7a029bb61520973e55fb3cec18f13e20Jakob Bornecrantz                  }
123abe4f3d1aa68aec70d329447abc890b3eaaba9cbJosé Fonseca               }
12485206e56a1c3400be47229d4a8c6a1cd7a2f476eBrian Paul
12585206e56a1c3400be47229d4a8c6a1cd7a2f476eBrian Paul               /* check for indirect register reads */
12685206e56a1c3400be47229d4a8c6a1cd7a2f476eBrian Paul               if (src->Register.Indirect) {
12785206e56a1c3400be47229d4a8c6a1cd7a2f476eBrian Paul                  info->indirect_files |= (1 << src->Register.File);
12885206e56a1c3400be47229d4a8c6a1cd7a2f476eBrian Paul               }
12985206e56a1c3400be47229d4a8c6a1cd7a2f476eBrian Paul            }
13085206e56a1c3400be47229d4a8c6a1cd7a2f476eBrian Paul
13185206e56a1c3400be47229d4a8c6a1cd7a2f476eBrian Paul            /* check for indirect register writes */
13285206e56a1c3400be47229d4a8c6a1cd7a2f476eBrian Paul            for (i = 0; i < fullinst->Instruction.NumDstRegs; i++) {
13385206e56a1c3400be47229d4a8c6a1cd7a2f476eBrian Paul               const struct tgsi_full_dst_register *dst = &fullinst->Dst[i];
13485206e56a1c3400be47229d4a8c6a1cd7a2f476eBrian Paul               if (dst->Register.Indirect) {
13585206e56a1c3400be47229d4a8c6a1cd7a2f476eBrian Paul                  info->indirect_files |= (1 << dst->Register.File);
13685206e56a1c3400be47229d4a8c6a1cd7a2f476eBrian Paul               }
13759a168d5c9b5f478e4e8bedcd8522e359e98987eBrian Paul            }
1386080e567f0ca1fdcce21e76271d4239c33a50db3Brian Paul
1396080e567f0ca1fdcce21e76271d4239c33a50db3Brian Paul            info->num_instructions++;
1401d77d6caf647424f9c1c481145be0465e96c9e3eBrian         }
1411d77d6caf647424f9c1c481145be0465e96c9e3eBrian         break;
1421d77d6caf647424f9c1c481145be0465e96c9e3eBrian
1431d77d6caf647424f9c1c481145be0465e96c9e3eBrian      case TGSI_TOKEN_TYPE_DECLARATION:
1441d77d6caf647424f9c1c481145be0465e96c9e3eBrian         {
14559a168d5c9b5f478e4e8bedcd8522e359e98987eBrian Paul            const struct tgsi_full_declaration *fulldecl
1461d77d6caf647424f9c1c481145be0465e96c9e3eBrian               = &parse.FullToken.FullDeclaration;
1471907135235a684872706d1a28ea8e2b4e1b6e7d3Brian Paul            const uint file = fulldecl->Declaration.File;
14859a168d5c9b5f478e4e8bedcd8522e359e98987eBrian Paul            uint reg;
149fe2b31e4a896167a33d267822b36eb2de0ceecbaKeith Whitwell            for (reg = fulldecl->Range.First;
150fe2b31e4a896167a33d267822b36eb2de0ceecbaKeith Whitwell                 reg <= fulldecl->Range.Last;
15159a168d5c9b5f478e4e8bedcd8522e359e98987eBrian Paul                 reg++) {
1521410b7bb509ef37c41043b173bc1047257483af0Brian
1531410b7bb509ef37c41043b173bc1047257483af0Brian               /* only first 32 regs will appear in this bitfield */
15459a168d5c9b5f478e4e8bedcd8522e359e98987eBrian Paul               info->file_mask[file] |= (1 << reg);
1551d77d6caf647424f9c1c481145be0465e96c9e3eBrian               info->file_count[file]++;
156fc4cea08fe8320438c72de7f4af2d7091681dca3Keith Whitwell               info->file_max[file] = MAX2(info->file_max[file], (int)reg);
1571d77d6caf647424f9c1c481145be0465e96c9e3eBrian
158b550d8d76b42ef5ba5e8293dcc24220d5b683369Brian Paul               if (file == TGSI_FILE_INPUT) {
159763426a0256f0ab06f8af53947bd630f8600183aKeith Whitwell                  info->input_semantic_name[reg] = (ubyte)fulldecl->Semantic.Name;
160763426a0256f0ab06f8af53947bd630f8600183aKeith Whitwell                  info->input_semantic_index[reg] = (ubyte)fulldecl->Semantic.Index;
1611279923d72942ee201fcc6ad40d552143f651f03Francisco Jerez                  info->input_interpolate[reg] = (ubyte)fulldecl->Interp.Interpolate;
1621279923d72942ee201fcc6ad40d552143f651f03Francisco Jerez                  info->input_centroid[reg] = (ubyte)fulldecl->Interp.Centroid;
1631279923d72942ee201fcc6ad40d552143f651f03Francisco Jerez                  info->input_cylindrical_wrap[reg] = (ubyte)fulldecl->Interp.CylindricalWrap;
1641410b7bb509ef37c41043b173bc1047257483af0Brian                  info->num_inputs++;
165c8c2fc9a7a029bb61520973e55fb3cec18f13e20Jakob Bornecrantz
166c8c2fc9a7a029bb61520973e55fb3cec18f13e20Jakob Bornecrantz                  if (procType == TGSI_PROCESSOR_FRAGMENT &&
167c8c2fc9a7a029bb61520973e55fb3cec18f13e20Jakob Bornecrantz                      fulldecl->Semantic.Name == TGSI_SEMANTIC_POSITION)
168c8c2fc9a7a029bb61520973e55fb3cec18f13e20Jakob Bornecrantz                        info->reads_position = TRUE;
1691410b7bb509ef37c41043b173bc1047257483af0Brian               }
170b550d8d76b42ef5ba5e8293dcc24220d5b683369Brian Paul               else if (file == TGSI_FILE_SYSTEM_VALUE) {
171b550d8d76b42ef5ba5e8293dcc24220d5b683369Brian Paul                  unsigned index = fulldecl->Range.First;
172b550d8d76b42ef5ba5e8293dcc24220d5b683369Brian Paul                  unsigned semName = fulldecl->Semantic.Name;
173b550d8d76b42ef5ba5e8293dcc24220d5b683369Brian Paul
174b550d8d76b42ef5ba5e8293dcc24220d5b683369Brian Paul                  info->system_value_semantic_name[index] = semName;
175b550d8d76b42ef5ba5e8293dcc24220d5b683369Brian Paul                  info->num_system_values = MAX2(info->num_system_values,
176b550d8d76b42ef5ba5e8293dcc24220d5b683369Brian Paul                                                 index + 1);
177b550d8d76b42ef5ba5e8293dcc24220d5b683369Brian Paul
178b550d8d76b42ef5ba5e8293dcc24220d5b683369Brian Paul                  /*
179b550d8d76b42ef5ba5e8293dcc24220d5b683369Brian Paul                  info->system_value_semantic_name[info->num_system_values++] =
180b550d8d76b42ef5ba5e8293dcc24220d5b683369Brian Paul                     fulldecl->Semantic.Name;
181b550d8d76b42ef5ba5e8293dcc24220d5b683369Brian Paul                  */
182b550d8d76b42ef5ba5e8293dcc24220d5b683369Brian Paul
183b550d8d76b42ef5ba5e8293dcc24220d5b683369Brian Paul                  if (fulldecl->Semantic.Name == TGSI_SEMANTIC_INSTANCEID) {
184b550d8d76b42ef5ba5e8293dcc24220d5b683369Brian Paul                     info->uses_instanceid = TRUE;
185b550d8d76b42ef5ba5e8293dcc24220d5b683369Brian Paul                  }
186e7ccd703a28e14431b90f29540cec0bf67be1e0fChristoph Bumiller                  else if (fulldecl->Semantic.Name == TGSI_SEMANTIC_VERTEXID) {
187e7ccd703a28e14431b90f29540cec0bf67be1e0fChristoph Bumiller                     info->uses_vertexid = TRUE;
188e7ccd703a28e14431b90f29540cec0bf67be1e0fChristoph Bumiller                  }
189b550d8d76b42ef5ba5e8293dcc24220d5b683369Brian Paul               }
1901907135235a684872706d1a28ea8e2b4e1b6e7d3Brian Paul               else if (file == TGSI_FILE_OUTPUT) {
191763426a0256f0ab06f8af53947bd630f8600183aKeith Whitwell                  info->output_semantic_name[reg] = (ubyte)fulldecl->Semantic.Name;
192763426a0256f0ab06f8af53947bd630f8600183aKeith Whitwell                  info->output_semantic_index[reg] = (ubyte)fulldecl->Semantic.Index;
1931410b7bb509ef37c41043b173bc1047257483af0Brian                  info->num_outputs++;
1941410b7bb509ef37c41043b173bc1047257483af0Brian
195f7e3e46f72fffe4b83cd3f922173ff28e9ab9c7cDave Airlie                  if (procType == TGSI_PROCESSOR_VERTEX &&
196f7e3e46f72fffe4b83cd3f922173ff28e9ab9c7cDave Airlie                      fulldecl->Semantic.Name == TGSI_SEMANTIC_CLIPDIST) {
197f7e3e46f72fffe4b83cd3f922173ff28e9ab9c7cDave Airlie                     info->num_written_clipdistance += util_bitcount(fulldecl->Declaration.UsageMask);
198f7e3e46f72fffe4b83cd3f922173ff28e9ab9c7cDave Airlie                  }
199ff5b0c72db20be099f9fc7dee22aeebbda75ab42Roland Scheidegger                  /* extra info for special outputs */
200ff5b0c72db20be099f9fc7dee22aeebbda75ab42Roland Scheidegger                  if (procType == TGSI_PROCESSOR_FRAGMENT &&
2014ecb2c105da590abf79421a06234b636cd1afcd6Dave Airlie                      fulldecl->Semantic.Name == TGSI_SEMANTIC_POSITION)
2024ecb2c105da590abf79421a06234b636cd1afcd6Dave Airlie                        info->writes_z = TRUE;
2034ecb2c105da590abf79421a06234b636cd1afcd6Dave Airlie                  if (procType == TGSI_PROCESSOR_FRAGMENT &&
2044ecb2c105da590abf79421a06234b636cd1afcd6Dave Airlie                      fulldecl->Semantic.Name == TGSI_SEMANTIC_STENCIL)
2054ecb2c105da590abf79421a06234b636cd1afcd6Dave Airlie                        info->writes_stencil = TRUE;
206ff5b0c72db20be099f9fc7dee22aeebbda75ab42Roland Scheidegger                  if (procType == TGSI_PROCESSOR_VERTEX &&
207ff5b0c72db20be099f9fc7dee22aeebbda75ab42Roland Scheidegger                      fulldecl->Semantic.Name == TGSI_SEMANTIC_EDGEFLAG) {
208ff5b0c72db20be099f9fc7dee22aeebbda75ab42Roland Scheidegger                     info->writes_edgeflag = TRUE;
209ff5b0c72db20be099f9fc7dee22aeebbda75ab42Roland Scheidegger                  }
2101d77d6caf647424f9c1c481145be0465e96c9e3eBrian               }
211ff5b0c72db20be099f9fc7dee22aeebbda75ab42Roland Scheidegger
212ff5b0c72db20be099f9fc7dee22aeebbda75ab42Roland Scheidegger             }
2131d77d6caf647424f9c1c481145be0465e96c9e3eBrian         }
2141d77d6caf647424f9c1c481145be0465e96c9e3eBrian         break;
2151d77d6caf647424f9c1c481145be0465e96c9e3eBrian
2161d77d6caf647424f9c1c481145be0465e96c9e3eBrian      case TGSI_TOKEN_TYPE_IMMEDIATE:
217f5cca127b0ddcfe36b8dc98a5f405979e8afe673Keith Whitwell         {
218f5cca127b0ddcfe36b8dc98a5f405979e8afe673Keith Whitwell            uint reg = info->immediate_count++;
219f5cca127b0ddcfe36b8dc98a5f405979e8afe673Keith Whitwell            uint file = TGSI_FILE_IMMEDIATE;
220f5cca127b0ddcfe36b8dc98a5f405979e8afe673Keith Whitwell
221f5cca127b0ddcfe36b8dc98a5f405979e8afe673Keith Whitwell            info->file_mask[file] |= (1 << reg);
222f5cca127b0ddcfe36b8dc98a5f405979e8afe673Keith Whitwell            info->file_count[file]++;
223f5cca127b0ddcfe36b8dc98a5f405979e8afe673Keith Whitwell            info->file_max[file] = MAX2(info->file_max[file], (int)reg);
224f5cca127b0ddcfe36b8dc98a5f405979e8afe673Keith Whitwell         }
2251d77d6caf647424f9c1c481145be0465e96c9e3eBrian         break;
2262253906da3c506bb5378a8f2fa203ed0c9021171Brian Paul
2273ff688ea299581e60caf5d6e1a464f68c717fe83Zack Rusin      case TGSI_TOKEN_TYPE_PROPERTY:
2282253906da3c506bb5378a8f2fa203ed0c9021171Brian Paul         {
2292253906da3c506bb5378a8f2fa203ed0c9021171Brian Paul            const struct tgsi_full_property *fullprop
2302253906da3c506bb5378a8f2fa203ed0c9021171Brian Paul               = &parse.FullToken.FullProperty;
2313ff688ea299581e60caf5d6e1a464f68c717fe83Zack Rusin
2322253906da3c506bb5378a8f2fa203ed0c9021171Brian Paul            info->properties[info->num_properties].name =
2332253906da3c506bb5378a8f2fa203ed0c9021171Brian Paul               fullprop->Property.PropertyName;
2342253906da3c506bb5378a8f2fa203ed0c9021171Brian Paul            memcpy(info->properties[info->num_properties].data,
2352253906da3c506bb5378a8f2fa203ed0c9021171Brian Paul                   fullprop->u, 8 * sizeof(unsigned));;
2363ff688ea299581e60caf5d6e1a464f68c717fe83Zack Rusin
2372253906da3c506bb5378a8f2fa203ed0c9021171Brian Paul            ++info->num_properties;
2382253906da3c506bb5378a8f2fa203ed0c9021171Brian Paul         }
2392253906da3c506bb5378a8f2fa203ed0c9021171Brian Paul         break;
2401d77d6caf647424f9c1c481145be0465e96c9e3eBrian
2411d77d6caf647424f9c1c481145be0465e96c9e3eBrian      default:
2421d77d6caf647424f9c1c481145be0465e96c9e3eBrian         assert( 0 );
2431d77d6caf647424f9c1c481145be0465e96c9e3eBrian      }
2441d77d6caf647424f9c1c481145be0465e96c9e3eBrian   }
2451d77d6caf647424f9c1c481145be0465e96c9e3eBrian
246fb40c5a9c7dc91c03f80780e0a09be0cade98705Brian   info->uses_kill = (info->opcode_count[TGSI_OPCODE_KIL] ||
247fb40c5a9c7dc91c03f80780e0a09be0cade98705Brian                      info->opcode_count[TGSI_OPCODE_KILP]);
248fb40c5a9c7dc91c03f80780e0a09be0cade98705Brian
2492253906da3c506bb5378a8f2fa203ed0c9021171Brian Paul   /* extract simple properties */
2502253906da3c506bb5378a8f2fa203ed0c9021171Brian Paul   for (i = 0; i < info->num_properties; ++i) {
2512253906da3c506bb5378a8f2fa203ed0c9021171Brian Paul      switch (info->properties[i].name) {
2522253906da3c506bb5378a8f2fa203ed0c9021171Brian Paul      case TGSI_PROPERTY_FS_COORD_ORIGIN:
2532253906da3c506bb5378a8f2fa203ed0c9021171Brian Paul         info->origin_lower_left = info->properties[i].data[0];
2542253906da3c506bb5378a8f2fa203ed0c9021171Brian Paul         break;
2552253906da3c506bb5378a8f2fa203ed0c9021171Brian Paul      case TGSI_PROPERTY_FS_COORD_PIXEL_CENTER:
2562253906da3c506bb5378a8f2fa203ed0c9021171Brian Paul         info->pixel_center_integer = info->properties[i].data[0];
2572253906da3c506bb5378a8f2fa203ed0c9021171Brian Paul         break;
2582253906da3c506bb5378a8f2fa203ed0c9021171Brian Paul      case TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS:
2592253906da3c506bb5378a8f2fa203ed0c9021171Brian Paul         info->color0_writes_all_cbufs = info->properties[i].data[0];
2602253906da3c506bb5378a8f2fa203ed0c9021171Brian Paul         break;
2612253906da3c506bb5378a8f2fa203ed0c9021171Brian Paul      default:
2622253906da3c506bb5378a8f2fa203ed0c9021171Brian Paul         ;
2632253906da3c506bb5378a8f2fa203ed0c9021171Brian Paul      }
2642253906da3c506bb5378a8f2fa203ed0c9021171Brian Paul   }
2652253906da3c506bb5378a8f2fa203ed0c9021171Brian Paul
2661d77d6caf647424f9c1c481145be0465e96c9e3eBrian   tgsi_parse_free (&parse);
2671d77d6caf647424f9c1c481145be0465e96c9e3eBrian}
2688223add3304451d5e75737a6d1be1739e4517943Brian Paul
2698223add3304451d5e75737a6d1be1739e4517943Brian Paul
2708223add3304451d5e75737a6d1be1739e4517943Brian Paul
2718223add3304451d5e75737a6d1be1739e4517943Brian Paul/**
2728223add3304451d5e75737a6d1be1739e4517943Brian Paul * Check if the given shader is a "passthrough" shader consisting of only
2738223add3304451d5e75737a6d1be1739e4517943Brian Paul * MOV instructions of the form:  MOV OUT[n], IN[n]
2748223add3304451d5e75737a6d1be1739e4517943Brian Paul *
2758223add3304451d5e75737a6d1be1739e4517943Brian Paul */
2768223add3304451d5e75737a6d1be1739e4517943Brian Paulboolean
2778223add3304451d5e75737a6d1be1739e4517943Brian Paultgsi_is_passthrough_shader(const struct tgsi_token *tokens)
2788223add3304451d5e75737a6d1be1739e4517943Brian Paul{
2798223add3304451d5e75737a6d1be1739e4517943Brian Paul   struct tgsi_parse_context parse;
2808223add3304451d5e75737a6d1be1739e4517943Brian Paul
2818223add3304451d5e75737a6d1be1739e4517943Brian Paul   /**
2828223add3304451d5e75737a6d1be1739e4517943Brian Paul    ** Setup to begin parsing input shader
2838223add3304451d5e75737a6d1be1739e4517943Brian Paul    **/
2848223add3304451d5e75737a6d1be1739e4517943Brian Paul   if (tgsi_parse_init(&parse, tokens) != TGSI_PARSE_OK) {
2858223add3304451d5e75737a6d1be1739e4517943Brian Paul      debug_printf("tgsi_parse_init() failed in tgsi_is_passthrough_shader()!\n");
2868223add3304451d5e75737a6d1be1739e4517943Brian Paul      return FALSE;
2878223add3304451d5e75737a6d1be1739e4517943Brian Paul   }
2888223add3304451d5e75737a6d1be1739e4517943Brian Paul
2898223add3304451d5e75737a6d1be1739e4517943Brian Paul   /**
2908223add3304451d5e75737a6d1be1739e4517943Brian Paul    ** Loop over incoming program tokens/instructions
2918223add3304451d5e75737a6d1be1739e4517943Brian Paul    */
2928223add3304451d5e75737a6d1be1739e4517943Brian Paul   while (!tgsi_parse_end_of_tokens(&parse)) {
2938223add3304451d5e75737a6d1be1739e4517943Brian Paul
2948223add3304451d5e75737a6d1be1739e4517943Brian Paul      tgsi_parse_token(&parse);
2958223add3304451d5e75737a6d1be1739e4517943Brian Paul
2968223add3304451d5e75737a6d1be1739e4517943Brian Paul      switch (parse.FullToken.Token.Type) {
2978223add3304451d5e75737a6d1be1739e4517943Brian Paul      case TGSI_TOKEN_TYPE_INSTRUCTION:
2988223add3304451d5e75737a6d1be1739e4517943Brian Paul         {
2998223add3304451d5e75737a6d1be1739e4517943Brian Paul            struct tgsi_full_instruction *fullinst =
3008223add3304451d5e75737a6d1be1739e4517943Brian Paul               &parse.FullToken.FullInstruction;
3018223add3304451d5e75737a6d1be1739e4517943Brian Paul            const struct tgsi_full_src_register *src =
3027d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell               &fullinst->Src[0];
3038223add3304451d5e75737a6d1be1739e4517943Brian Paul            const struct tgsi_full_dst_register *dst =
3047d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell               &fullinst->Dst[0];
3058223add3304451d5e75737a6d1be1739e4517943Brian Paul
3068223add3304451d5e75737a6d1be1739e4517943Brian Paul            /* Do a whole bunch of checks for a simple move */
3078223add3304451d5e75737a6d1be1739e4517943Brian Paul            if (fullinst->Instruction.Opcode != TGSI_OPCODE_MOV ||
3084a531fb46a6ab544666c5eeb362f3622bd44aaffAlan Hourihane                (src->Register.File != TGSI_FILE_INPUT &&
3094a531fb46a6ab544666c5eeb362f3622bd44aaffAlan Hourihane                 src->Register.File != TGSI_FILE_SYSTEM_VALUE) ||
3105b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell                dst->Register.File != TGSI_FILE_OUTPUT ||
31191a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell                src->Register.Index != dst->Register.Index ||
3128223add3304451d5e75737a6d1be1739e4517943Brian Paul
31391a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell                src->Register.Negate ||
31491a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell                src->Register.Absolute ||
3158223add3304451d5e75737a6d1be1739e4517943Brian Paul
31691a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell                src->Register.SwizzleX != TGSI_SWIZZLE_X ||
31791a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell                src->Register.SwizzleY != TGSI_SWIZZLE_Y ||
31891a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell                src->Register.SwizzleZ != TGSI_SWIZZLE_Z ||
31991a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell                src->Register.SwizzleW != TGSI_SWIZZLE_W ||
3208223add3304451d5e75737a6d1be1739e4517943Brian Paul
3215b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell                dst->Register.WriteMask != TGSI_WRITEMASK_XYZW)
3228223add3304451d5e75737a6d1be1739e4517943Brian Paul            {
3238223add3304451d5e75737a6d1be1739e4517943Brian Paul               tgsi_parse_free(&parse);
3248223add3304451d5e75737a6d1be1739e4517943Brian Paul               return FALSE;
3258223add3304451d5e75737a6d1be1739e4517943Brian Paul            }
3268223add3304451d5e75737a6d1be1739e4517943Brian Paul         }
3278223add3304451d5e75737a6d1be1739e4517943Brian Paul         break;
3288223add3304451d5e75737a6d1be1739e4517943Brian Paul
3298223add3304451d5e75737a6d1be1739e4517943Brian Paul      case TGSI_TOKEN_TYPE_DECLARATION:
3308223add3304451d5e75737a6d1be1739e4517943Brian Paul         /* fall-through */
3318223add3304451d5e75737a6d1be1739e4517943Brian Paul      case TGSI_TOKEN_TYPE_IMMEDIATE:
3328223add3304451d5e75737a6d1be1739e4517943Brian Paul         /* fall-through */
3333ff688ea299581e60caf5d6e1a464f68c717fe83Zack Rusin      case TGSI_TOKEN_TYPE_PROPERTY:
3343ff688ea299581e60caf5d6e1a464f68c717fe83Zack Rusin         /* fall-through */
3358223add3304451d5e75737a6d1be1739e4517943Brian Paul      default:
3368223add3304451d5e75737a6d1be1739e4517943Brian Paul         ; /* no-op */
3378223add3304451d5e75737a6d1be1739e4517943Brian Paul      }
3388223add3304451d5e75737a6d1be1739e4517943Brian Paul   }
3398223add3304451d5e75737a6d1be1739e4517943Brian Paul
3408223add3304451d5e75737a6d1be1739e4517943Brian Paul   tgsi_parse_free(&parse);
3418223add3304451d5e75737a6d1be1739e4517943Brian Paul
3428223add3304451d5e75737a6d1be1739e4517943Brian Paul   /* if we get here, it's a pass-through shader */
3438223add3304451d5e75737a6d1be1739e4517943Brian Paul   return TRUE;
3448223add3304451d5e75737a6d1be1739e4517943Brian Paul}
345