shader_query.cpp revision b12b5d9ab5c0153c93ca5ad9cd93cb36e41be4eb
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 struct gl_shader_program *const shProg = 492fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick _mesa_lookup_shader_program_err(ctx, program, "glBindAttribLocation"); 502fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick if (!shProg) 512fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick return; 522fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick 532fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick if (!name) 542fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick return; 552fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick 562fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick if (strncmp(name, "gl_", 3) == 0) { 572fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick _mesa_error(ctx, GL_INVALID_OPERATION, 582fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick "glBindAttribLocation(illegal name)"); 592fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick return; 602fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick } 612fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick 622fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick if (index >= ctx->Const.VertexProgram.MaxAttribs) { 632fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick _mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocation(index)"); 642fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick return; 652fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick } 662fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick 67a339ee8d852c08ce7af51a518e0b18b9f0ab324cIan Romanick /* Replace the current value if it's already in the list. Add 68a339ee8d852c08ce7af51a518e0b18b9f0ab324cIan Romanick * VERT_ATTRIB_GENERIC0 because that's how the linker differentiates 69015d4f61ef9116c9e844299ab9f2b15c653c0450Ian Romanick * between built-in attributes and user-defined attributes. 70015d4f61ef9116c9e844299ab9f2b15c653c0450Ian Romanick */ 71015d4f61ef9116c9e844299ab9f2b15c653c0450Ian Romanick shProg->AttributeBindings->put(index + VERT_ATTRIB_GENERIC0, name); 722fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick 732fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick /* 742fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick * Note that this attribute binding won't go into effect until 752fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick * glLinkProgram is called again. 762fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick */ 772fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick} 782fd80534f01a5c684c47eff3946f412192ae3c0bIan Romanick 797a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanickvoid GLAPIENTRY 8084d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick_mesa_GetActiveAttribARB(GLhandleARB program, GLuint desired_index, 817a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick GLsizei maxLength, GLsizei * length, GLint * size, 827a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick GLenum * type, GLcharARB * name) 837a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick{ 847a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick GET_CURRENT_CONTEXT(ctx); 857a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick struct gl_shader_program *shProg; 867a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick 877a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveAttrib"); 887a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick if (!shProg) 897a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick return; 907a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick 9184d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick if (!shProg->LinkStatus) { 9284d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick _mesa_error(ctx, GL_INVALID_VALUE, 9384d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick "glGetActiveAttrib(program not linked)"); 9484d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick return; 9584d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick } 967a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick 9784d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick if (shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL) { 9884d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(no vertex shader)"); 997a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick return; 1007a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick } 1017a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick 10284d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick exec_list *const ir = shProg->_LinkedShaders[MESA_SHADER_VERTEX]->ir; 10384d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick unsigned current_index = 0; 10484d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick 10584d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick foreach_list(node, ir) { 10684d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick const ir_variable *const var = ((ir_instruction *) node)->as_variable(); 10784d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick 10884d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick if (var == NULL 10984d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick || var->mode != ir_var_in 11084d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick || var->location == -1 11184d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick || var->location < VERT_ATTRIB_GENERIC0) 11284d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick continue; 11384d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick 11484d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick if (current_index == desired_index) { 11584d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick _mesa_copy_string(name, maxLength, length, var->name); 1167a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick 11784d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick if (size) 11884d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick *size = (var->type->is_array()) ? var->type->length : 1; 1197a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick 12084d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick if (type) 12184d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick *type = var->type->gl_type; 12284d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick 12384d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick return; 12484d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick } 12584d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick 12684d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick current_index++; 12784d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick } 12884d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick 12984d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick /* If the loop did not return early, the caller must have asked for 13084d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick * an index that did not exit. Set an error. 13184d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick */ 13284d71a07bb06fe5fe231b8983558fbd3608ec6f0Ian Romanick _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)"); 1337a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick} 1347a80c1bbc56b61525634f2b699f995e863dfade2Ian Romanick 135b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan RomanickGLint GLAPIENTRY 136b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick_mesa_GetAttribLocationARB(GLhandleARB program, const GLcharARB * name) 137b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick{ 138b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick GET_CURRENT_CONTEXT(ctx); 139b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick struct gl_shader_program *const shProg = 140b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick _mesa_lookup_shader_program_err(ctx, program, "glGetAttribLocation"); 141b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick 142b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick if (!shProg) { 143b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick return -1; 144b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick } 145b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick 146b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick if (!shProg->LinkStatus) { 147b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick _mesa_error(ctx, GL_INVALID_OPERATION, 148b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick "glGetAttribLocation(program not linked)"); 149b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick return -1; 150b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick } 151b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick 152b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick if (!name) 153b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick return -1; 154b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick 155b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick /* Not having a vertex shader is not an error. 156b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick */ 157b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick if (shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL) 158b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick return -1; 159b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick 160b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick exec_list *ir = shProg->_LinkedShaders[MESA_SHADER_VERTEX]->ir; 161b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick foreach_list(node, ir) { 162b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick const ir_variable *const var = ((ir_instruction *) node)->as_variable(); 163b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick 164b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick /* The extra check against VERT_ATTRIB_GENERIC0 is because 165b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick * glGetAttribLocation cannot be used on "conventional" attributes. 166b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick * 167b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick * From page 95 of the OpenGL 3.0 spec: 168b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick * 169b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick * "If name is not an active attribute, if name is a conventional 170b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick * attribute, or if an error occurs, -1 will be returned." 171b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick */ 172b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick if (var == NULL 173b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick || var->mode != ir_var_in 174b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick || var->location == -1 175b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick || var->location < VERT_ATTRIB_GENERIC0) 176b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick continue; 177b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick 178b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick if (strcmp(var->name, name) == 0) 179b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick return var->location - VERT_ATTRIB_GENERIC0; 180b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick } 181b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick 182b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick return -1; 183b7fa0d0727a3a9e1f64d3cfc7a0f157b35dec09eIan Romanick} 184c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick 185c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick 186c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanickunsigned 187c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick_mesa_count_active_attribs(struct gl_shader_program *shProg) 188c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick{ 189c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick if (!shProg->LinkStatus 190c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick || shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL) { 191c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick return 0; 192c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick } 193c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick 194c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick exec_list *const ir = shProg->_LinkedShaders[MESA_SHADER_VERTEX]->ir; 195c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick unsigned i = 0; 196c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick 197c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick foreach_list(node, ir) { 198c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick const ir_variable *const var = ((ir_instruction *) node)->as_variable(); 199c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick 200c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick if (var == NULL 201c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick || var->mode != ir_var_in 202c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick || var->location == -1 203c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick || var->location < VERT_ATTRIB_GENERIC0) 204c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick continue; 205c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick 206c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick i++; 207c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick } 208c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick 209c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick return i; 210c097c63aa880e2b84e6b1d78a8808d42864f72fcIan Romanick} 21124409ba1968cc49cbde6a111464c91271babc68aIan Romanick 21224409ba1968cc49cbde6a111464c91271babc68aIan Romanick 21324409ba1968cc49cbde6a111464c91271babc68aIan Romanicksize_t 21424409ba1968cc49cbde6a111464c91271babc68aIan Romanick_mesa_longest_attribute_name_length(struct gl_shader_program *shProg) 21524409ba1968cc49cbde6a111464c91271babc68aIan Romanick{ 21624409ba1968cc49cbde6a111464c91271babc68aIan Romanick if (!shProg->LinkStatus 21724409ba1968cc49cbde6a111464c91271babc68aIan Romanick || shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL) { 21824409ba1968cc49cbde6a111464c91271babc68aIan Romanick return 0; 21924409ba1968cc49cbde6a111464c91271babc68aIan Romanick } 22024409ba1968cc49cbde6a111464c91271babc68aIan Romanick 22124409ba1968cc49cbde6a111464c91271babc68aIan Romanick exec_list *const ir = shProg->_LinkedShaders[MESA_SHADER_VERTEX]->ir; 22224409ba1968cc49cbde6a111464c91271babc68aIan Romanick size_t longest = 0; 22324409ba1968cc49cbde6a111464c91271babc68aIan Romanick 22424409ba1968cc49cbde6a111464c91271babc68aIan Romanick foreach_list(node, ir) { 22524409ba1968cc49cbde6a111464c91271babc68aIan Romanick const ir_variable *const var = ((ir_instruction *) node)->as_variable(); 22624409ba1968cc49cbde6a111464c91271babc68aIan Romanick 22724409ba1968cc49cbde6a111464c91271babc68aIan Romanick if (var == NULL 22824409ba1968cc49cbde6a111464c91271babc68aIan Romanick || var->mode != ir_var_in 22924409ba1968cc49cbde6a111464c91271babc68aIan Romanick || var->location == -1 23024409ba1968cc49cbde6a111464c91271babc68aIan Romanick || var->location < VERT_ATTRIB_GENERIC0) 23124409ba1968cc49cbde6a111464c91271babc68aIan Romanick continue; 23224409ba1968cc49cbde6a111464c91271babc68aIan Romanick 23324409ba1968cc49cbde6a111464c91271babc68aIan Romanick const size_t len = strlen(var->name); 23424409ba1968cc49cbde6a111464c91271babc68aIan Romanick if (len >= longest) 23524409ba1968cc49cbde6a111464c91271babc68aIan Romanick longest = len + 1; 23624409ba1968cc49cbde6a111464c91271babc68aIan Romanick } 23724409ba1968cc49cbde6a111464c91271babc68aIan Romanick 23824409ba1968cc49cbde6a111464c91271babc68aIan Romanick return longest; 23924409ba1968cc49cbde6a111464c91271babc68aIan Romanick} 2404464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick 2414464a4b27b66f832acbe52b0a002c04415924c14Ian Romanickvoid GLAPIENTRY 2424464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick_mesa_BindFragDataLocation(GLuint program, GLuint colorNumber, 2434464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick const GLchar *name) 2444464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick{ 2454464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick GET_CURRENT_CONTEXT(ctx); 2464464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick 2474464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick struct gl_shader_program *const shProg = 2484464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick _mesa_lookup_shader_program_err(ctx, program, "glBindFragDataLocation"); 2494464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick if (!shProg) 2504464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick return; 2514464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick 2524464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick if (!name) 2534464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick return; 2544464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick 2554464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick if (strncmp(name, "gl_", 3) == 0) { 2564464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick _mesa_error(ctx, GL_INVALID_OPERATION, 2574464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick "glBindFragDataLocation(illegal name)"); 2584464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick return; 2594464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick } 2604464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick 2614464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick if (colorNumber >= ctx->Const.MaxDrawBuffers) { 2624464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick _mesa_error(ctx, GL_INVALID_VALUE, "glBindFragDataLocation(index)"); 2634464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick return; 2644464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick } 2654464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick 2664464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick /* Replace the current value if it's already in the list. Add 2674464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick * FRAG_RESULT_DATA0 because that's how the linker differentiates 2684464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick * between built-in attributes and user-defined attributes. 2694464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick */ 270b12b5d9ab5c0153c93ca5ad9cd93cb36e41be4ebIan Romanick shProg->FragDataBindings->put(colorNumber + FRAG_RESULT_DATA0, name); 2714464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick 2724464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick /* 2734464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick * Note that this binding won't go into effect until 2744464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick * glLinkProgram is called again. 2754464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick */ 2764464a4b27b66f832acbe52b0a002c04415924c14Ian Romanick} 277