shader_query.cpp revision 24409ba1968cc49cbde6a111464c91271babc68a
1b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick/*
2b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick * Copyright © 2011 Intel Corporation
3b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick *
4b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick * Permission is hereby granted, free of charge, to any person obtaining a
5b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick * copy of this software and associated documentation files (the "Software"),
6b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick * to deal in the Software without restriction, including without limitation
7b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick * and/or sell copies of the Software, and to permit persons to whom the
9b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick * Software is furnished to do so, subject to the following conditions:
10b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick *
11b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick * The above copyright notice and this permission notice (including the next
12b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick * paragraph) shall be included in all copies or substantial portions of the
13b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick * Software.
14b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick *
15b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick * DEALINGS IN THE SOFTWARE.
22b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick */
23b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick
24b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick/**
25b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick * \file shader_query.cpp
26b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick * C-to-C++ bridge functions to query GLSL shader data
27b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick *
28b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick * \author Ian Romanick <ian.d.romanick@intel.com>
29b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick */
30b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick
31b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick#include "main/core.h"
32b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick#include "glsl_symbol_table.h"
33b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick#include "ir.h"
34b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick#include "shaderobj.h"
35015d4f61ef9116c9e844299ab9f2b15c653c0450Ian Romanick#include "program/hash_table.h"
3684d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick#include "../glsl/program.h"
37b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick
38b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanickextern "C" {
39b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick#include "shaderapi.h"
40b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick}
41b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick
422fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanickvoid GLAPIENTRY
432fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick_mesa_BindAttribLocationARB(GLhandleARB program, GLuint index,
442fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick                            const GLcharARB *name)
452fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick{
462fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick   GET_CURRENT_CONTEXT(ctx);
472fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick
482fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick   const GLint size = -1; /* unknown size */
492fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick   GLint i;
502fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick   GLenum datatype = GL_FLOAT_VEC4;
512fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick
522fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick   struct gl_shader_program *const shProg =
532fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick      _mesa_lookup_shader_program_err(ctx, program, "glBindAttribLocation");
542fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick   if (!shProg)
552fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick      return;
562fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick
572fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick   if (!name)
582fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick      return;
592fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick
602fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick   if (strncmp(name, "gl_", 3) == 0) {
612fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick      _mesa_error(ctx, GL_INVALID_OPERATION,
622fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick                  "glBindAttribLocation(illegal name)");
632fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick      return;
642fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick   }
652fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick
662fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick   if (index >= ctx->Const.VertexProgram.MaxAttribs) {
672fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick      _mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocation(index)");
682fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick      return;
692fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick   }
702fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick
71a339ee8d852c08ce7af51a518e0b18b9f0ab324cIan Romanick   /* Replace the current value if it's already in the list.  Add
72a339ee8d852c08ce7af51a518e0b18b9f0ab324cIan Romanick    * VERT_ATTRIB_GENERIC0 because that's how the linker differentiates
73015d4f61ef9116c9e844299ab9f2b15c653c0450Ian Romanick    * between built-in attributes and user-defined attributes.
74015d4f61ef9116c9e844299ab9f2b15c653c0450Ian Romanick    */
75015d4f61ef9116c9e844299ab9f2b15c653c0450Ian Romanick   shProg->AttributeBindings->put(index + VERT_ATTRIB_GENERIC0, name);
762fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick
772fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick   /*
782fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick    * Note that this attribute binding won't go into effect until
792fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick    * glLinkProgram is called again.
802fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick    */
812fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick}
822fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick
837a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanickvoid GLAPIENTRY
8484d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick_mesa_GetActiveAttribARB(GLhandleARB program, GLuint desired_index,
857a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick                         GLsizei maxLength, GLsizei * length, GLint * size,
867a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick                         GLenum * type, GLcharARB * name)
877a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick{
887a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick   GET_CURRENT_CONTEXT(ctx);
897a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick   struct gl_shader_program *shProg;
907a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick
917a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick   shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveAttrib");
927a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick   if (!shProg)
937a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick      return;
947a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick
9584d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick   if (!shProg->LinkStatus) {
9684d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick      _mesa_error(ctx, GL_INVALID_VALUE,
9784d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick                  "glGetActiveAttrib(program not linked)");
9884d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick      return;
9984d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick   }
1007a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick
10184d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick   if (shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL) {
10284d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick      _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(no vertex shader)");
1037a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick      return;
1047a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick   }
1057a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick
10684d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick   exec_list *const ir = shProg->_LinkedShaders[MESA_SHADER_VERTEX]->ir;
10784d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick   unsigned current_index = 0;
10884d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick
10984d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick   foreach_list(node, ir) {
11084d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick      const ir_variable *const var = ((ir_instruction *) node)->as_variable();
11184d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick
11284d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick      if (var == NULL
11384d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick	  || var->mode != ir_var_in
11484d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick	  || var->location == -1
11584d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick	  || var->location < VERT_ATTRIB_GENERIC0)
11684d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick	 continue;
11784d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick
11884d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick      if (current_index == desired_index) {
11984d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick	 _mesa_copy_string(name, maxLength, length, var->name);
1207a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick
12184d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick	 if (size)
12284d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick	    *size = (var->type->is_array()) ? var->type->length : 1;
1237a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick
12484d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick	 if (type)
12584d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick	    *type = var->type->gl_type;
12684d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick
12784d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick	 return;
12884d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick      }
12984d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick
13084d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick      current_index++;
13184d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick   }
13284d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick
13384d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick   /* If the loop did not return early, the caller must have asked for
13484d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick    * an index that did not exit.  Set an error.
13584d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick    */
13684d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick   _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)");
1377a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick}
1387a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick
139b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan RomanickGLint GLAPIENTRY
140b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick_mesa_GetAttribLocationARB(GLhandleARB program, const GLcharARB * name)
141b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick{
142b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick   GET_CURRENT_CONTEXT(ctx);
143b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick   struct gl_shader_program *const shProg =
144b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick      _mesa_lookup_shader_program_err(ctx, program, "glGetAttribLocation");
145b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick
146b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick   if (!shProg) {
147b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick      return -1;
148b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick   }
149b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick
150b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick   if (!shProg->LinkStatus) {
151b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick      _mesa_error(ctx, GL_INVALID_OPERATION,
152b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick                  "glGetAttribLocation(program not linked)");
153b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick      return -1;
154b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick   }
155b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick
156b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick   if (!name)
157b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick      return -1;
158b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick
159b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick   /* Not having a vertex shader is not an error.
160b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick    */
161b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick   if (shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL)
162b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick      return -1;
163b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick
164b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick   exec_list *ir = shProg->_LinkedShaders[MESA_SHADER_VERTEX]->ir;
165b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick   foreach_list(node, ir) {
166b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick      const ir_variable *const var = ((ir_instruction *) node)->as_variable();
167b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick
168b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick      /* The extra check against VERT_ATTRIB_GENERIC0 is because
169b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick       * glGetAttribLocation cannot be used on "conventional" attributes.
170b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick       *
171b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick       * From page 95 of the OpenGL 3.0 spec:
172b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick       *
173b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick       *     "If name is not an active attribute, if name is a conventional
174b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick       *     attribute, or if an error occurs, -1 will be returned."
175b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick       */
176b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick      if (var == NULL
177b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick	  || var->mode != ir_var_in
178b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick	  || var->location == -1
179b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick	  || var->location < VERT_ATTRIB_GENERIC0)
180b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick	 continue;
181b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick
182b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick      if (strcmp(var->name, name) == 0)
183b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick	 return var->location - VERT_ATTRIB_GENERIC0;
184b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick   }
185b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick
186b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick   return -1;
187b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick}
188c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick
189c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick
190c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanickunsigned
191c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick_mesa_count_active_attribs(struct gl_shader_program *shProg)
192c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick{
193c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick   if (!shProg->LinkStatus
194c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick       || shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL) {
195c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick      return 0;
196c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick   }
197c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick
198c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick   exec_list *const ir = shProg->_LinkedShaders[MESA_SHADER_VERTEX]->ir;
199c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick   unsigned i = 0;
200c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick
201c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick   foreach_list(node, ir) {
202c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick      const ir_variable *const var = ((ir_instruction *) node)->as_variable();
203c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick
204c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick      if (var == NULL
205c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick	  || var->mode != ir_var_in
206c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick	  || var->location == -1
207c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick	  || var->location < VERT_ATTRIB_GENERIC0)
208c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick	 continue;
209c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick
210c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick      i++;
211c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick   }
212c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick
213c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick   return i;
214c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick}
21524409ba1968cc49cbde6a111464c91271babc68aIan Romanick
21624409ba1968cc49cbde6a111464c91271babc68aIan Romanick
21724409ba1968cc49cbde6a111464c91271babc68aIan Romanicksize_t
21824409ba1968cc49cbde6a111464c91271babc68aIan Romanick_mesa_longest_attribute_name_length(struct gl_shader_program *shProg)
21924409ba1968cc49cbde6a111464c91271babc68aIan Romanick{
22024409ba1968cc49cbde6a111464c91271babc68aIan Romanick   if (!shProg->LinkStatus
22124409ba1968cc49cbde6a111464c91271babc68aIan Romanick       || shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL) {
22224409ba1968cc49cbde6a111464c91271babc68aIan Romanick      return 0;
22324409ba1968cc49cbde6a111464c91271babc68aIan Romanick   }
22424409ba1968cc49cbde6a111464c91271babc68aIan Romanick
22524409ba1968cc49cbde6a111464c91271babc68aIan Romanick   exec_list *const ir = shProg->_LinkedShaders[MESA_SHADER_VERTEX]->ir;
22624409ba1968cc49cbde6a111464c91271babc68aIan Romanick   size_t longest = 0;
22724409ba1968cc49cbde6a111464c91271babc68aIan Romanick
22824409ba1968cc49cbde6a111464c91271babc68aIan Romanick   foreach_list(node, ir) {
22924409ba1968cc49cbde6a111464c91271babc68aIan Romanick      const ir_variable *const var = ((ir_instruction *) node)->as_variable();
23024409ba1968cc49cbde6a111464c91271babc68aIan Romanick
23124409ba1968cc49cbde6a111464c91271babc68aIan Romanick      if (var == NULL
23224409ba1968cc49cbde6a111464c91271babc68aIan Romanick	  || var->mode != ir_var_in
23324409ba1968cc49cbde6a111464c91271babc68aIan Romanick	  || var->location == -1
23424409ba1968cc49cbde6a111464c91271babc68aIan Romanick	  || var->location < VERT_ATTRIB_GENERIC0)
23524409ba1968cc49cbde6a111464c91271babc68aIan Romanick	 continue;
23624409ba1968cc49cbde6a111464c91271babc68aIan Romanick
23724409ba1968cc49cbde6a111464c91271babc68aIan Romanick      const size_t len = strlen(var->name);
23824409ba1968cc49cbde6a111464c91271babc68aIan Romanick      if (len >= longest)
23924409ba1968cc49cbde6a111464c91271babc68aIan Romanick	 longest = len + 1;
24024409ba1968cc49cbde6a111464c91271babc68aIan Romanick   }
24124409ba1968cc49cbde6a111464c91271babc68aIan Romanick
24224409ba1968cc49cbde6a111464c91271babc68aIan Romanick   return longest;
24324409ba1968cc49cbde6a111464c91271babc68aIan Romanick}
244