uniform_query.cpp revision 5f8a8716b6b58a470be0b0d176e38d37eda2c8f7
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Mesa 3-D graphics library 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (C) 2004-2008 Brian Paul All Rights Reserved. 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (C) 2009-2010 VMware, Inc. All Rights Reserved. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright © 2010, 2011 Intel Corporation 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Permission is hereby granted, free of charge, to any person obtaining a 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * copy of this software and associated documentation files (the "Software"), 10d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * to deal in the Software without restriction, including without limitation 11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * the rights to use, copy, modify, merge, publish, distribute, sublicense, 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and/or sell copies of the Software, and to permit persons to whom the 13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Software is furnished to do so, subject to the following conditions: 14c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The above copyright notice and this permission notice shall be included 164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * in all copies or substantial portions of the Software. 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <stdlib.h> 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "main/core.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "main/context.h" 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ir.h" 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ir_uniform.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "program/hash_table.h" 33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "../glsl/program.h" 344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "../glsl/ir_uniform.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "main/shaderapi.h" 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "main/shaderobj.h" 370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "uniforms.h" 381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuextern "C" void GLAPIENTRY 4168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)_mesa_GetActiveUniformARB(GLhandleARB program, GLuint index, 42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) GLsizei maxLength, GLsizei *length, GLint *size, 43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) GLenum *type, GLcharARB *nameOut) 44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles){ 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GET_CURRENT_CONTEXT(ctx); 46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) struct gl_shader_program *shProg = 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform"); 48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_OUTSIDE_BEGIN_END(ctx); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!shProg) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 53a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index >= shProg->NumUserUniformStorage) { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)"); 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const struct gl_uniform_storage *const uni = &shProg->UniformStorage[index]; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (nameOut) { 62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) _mesa_copy_string(nameOut, maxLength, length, uni->name); 63c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 65a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (size) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* array_elements is zero for non-arrays, but the API requires that 1 be 673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) * returned. 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *size = MAX2(1, uni->array_elements); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type) { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *type = uni->type->gl_type; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern "C" void GLAPIENTRY 78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)_mesa_GetActiveUniformsiv(GLuint program, 794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) GLsizei uniformCount, 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GLuint *uniformIndices, 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLenum pname, 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLint *params) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) GET_CURRENT_CONTEXT(ctx); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct gl_shader_program *shProg; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLsizei i; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform"); 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!shProg) 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (uniformCount < 0) { 93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) _mesa_error(ctx, GL_INVALID_VALUE, 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "glGetUniformIndices(uniformCount < 0)"); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (i = 0; i < uniformCount; i++) { 994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) GLuint index = uniformIndices[i]; 1001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (index >= shProg->NumUserUniformStorage) { 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformsiv(index)"); 1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < uniformCount; i++) { 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GLuint index = uniformIndices[i]; 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const struct gl_uniform_storage *uni = &shProg->UniformStorage[index]; 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) switch (pname) { 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case GL_UNIFORM_TYPE: 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params[i] = uni->type->gl_type; 114c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch break; 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case GL_UNIFORM_SIZE: 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* array_elements is zero for non-arrays, but the API requires that 1 be 118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * returned. 119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch */ 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params[i] = MAX2(1, uni->array_elements); 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 123a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch case GL_UNIFORM_NAME_LENGTH: 124effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch params[i] = strlen(uni->name) + 1; 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case GL_UNIFORM_BLOCK_INDEX: 1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params[i] = uni->block_index; 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case GL_UNIFORM_OFFSET: 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params[i] = uni->offset; 1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) break; 1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch case GL_UNIFORM_ARRAY_STRIDE: 1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) params[i] = uni->array_stride; 137effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch break; 138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case GL_UNIFORM_MATRIX_STRIDE: 140effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch params[i] = uni->matrix_stride; 1410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch break; 142c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case GL_UNIFORM_IS_ROW_MAJOR: 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params[i] = uni->row_major; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _mesa_error(ctx, GL_INVALID_ENUM, "glGetActiveUniformsiv(pname)"); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static bool 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)validate_uniform_parameters(struct gl_context *ctx, 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct gl_shader_program *shProg, 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLint location, GLsizei count, 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned *loc, 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned *array_index, 160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const char *caller, 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool negative_one_is_not_valid) 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!shProg || !shProg->LinkStatus) { 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) _mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)", caller); 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (location == -1) { 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* For glGetUniform, page 264 (page 278 of the PDF) of the OpenGL 2.1 170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * spec says: 171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * 172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * "The error INVALID_OPERATION is generated if program has not been 173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * linked successfully, or if location is not a valid location for 174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * program." 175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * 176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * For glUniform, page 82 (page 96 of the PDF) of the OpenGL 2.1 spec 177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * says: 178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * "If the value of location is -1, the Uniform* commands will 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * silently ignore the data passed in, and the current uniform 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * values will not be changed." 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Allowing -1 for the location parameter of glUniform allows 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * applications to avoid error paths in the case that, for example, some 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * uniform variable is removed by the compiler / linker after 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * optimization. In this case, the new value of the uniform is dropped 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * on the floor. For the case of glGetUniform, there is nothing 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sensible to do for a location of -1. 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * The negative_one_is_not_valid flag selects between the two behaviors. 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (negative_one_is_not_valid) { 193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)", 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) caller, location); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* From page 12 (page 26 of the PDF) of the OpenGL 2.1 spec: 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * "If a negative number is provided where an argument of type sizei or 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sizeiptr is specified, the error INVALID_VALUE is generated." 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (count < 0) { 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _mesa_error(ctx, GL_INVALID_VALUE, "%s(count < 0)", caller); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says: 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * "If any of the following conditions occur, an INVALID_OPERATION 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * error is generated by the Uniform* commands, and no uniform values 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * are changed: 215c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * 216c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * ... 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - if no variable with a location of location exists in the 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * program object currently in use and location is not -1, 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - if count is greater than one, and the uniform declared in the 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * shader is not an array variable, 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (location < -1) { 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)", 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) caller, location); 2261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return false; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _mesa_uniform_split_location_offset(location, loc, array_index); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (*loc >= shProg->NumUserUniformStorage) { 232a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)", 233a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) caller, location); 234a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return false; 235a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shProg->UniformStorage[*loc].array_elements == 0 && count > 1) { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _mesa_error(ctx, GL_INVALID_OPERATION, 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "%s(count > 1 for non-array, location=%d)", 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) caller, location); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* This case should be impossible. The implication is that a call like 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * glGetUniformLocation(prog, "foo[8]") was successful but "foo" is not an 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * array. 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*array_index != 0 && shProg->UniformStorage[*loc].array_elements == 0) { 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)", 2501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) caller, location); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)/** 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Called via glGetUniform[fiui]v() to get the current value of a uniform. 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern "C" void 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location, 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLsizei bufSize, enum glsl_base_type returnType, 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLvoid *paramsOut) 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 2641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) struct gl_shader_program *shProg = 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _mesa_lookup_shader_program_err(ctx, program, "glGetUniformfv"); 266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) struct gl_uniform_storage *uni; 267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned loc, offset; 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!validate_uniform_parameters(ctx, shProg, location, 1, 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &loc, &offset, "glGetUniform", true)) 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uni = &shProg->UniformStorage[loc]; 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned elements = (uni->type->is_sampler()) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ? 1 : uni->type->components(); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Calculate the source base address *BEFORE* modifying elements to 2804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * account for the size of the user's buffer. 2814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 2824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const union gl_constant_value *const src = 2834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) &uni->storage[offset * elements]; 2844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) assert(returnType == GLSL_TYPE_FLOAT || returnType == GLSL_TYPE_INT || 2864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) returnType == GLSL_TYPE_UINT); 2874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) /* The three (currently) supported types all have the same size, 28890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * which is of course the same as their union. That'll change 2891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) * with glGetUniformdv()... 2904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 291c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch unsigned bytes = sizeof(src[0]) * elements; 292c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (bufSize < 0 || bytes > (unsigned) bufSize) { 2934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) _mesa_error( ctx, GL_INVALID_OPERATION, 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "glGetnUniform*vARB(out of bounds: bufSize is %d," 2956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) " but %u bytes are required)", bufSize, bytes ); 2964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 2974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) /* If the return type and the uniform's native type are "compatible," 300c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * just memcpy the data. If the types are not compatible, perform a 3016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * slower convert-and-copy process. 3026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) */ 3036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (returnType == uni->type->base_type 3046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) || ((returnType == GLSL_TYPE_INT 3056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) || returnType == GLSL_TYPE_UINT 3066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) || returnType == GLSL_TYPE_SAMPLER) 3076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) && 3086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) (uni->type->base_type == GLSL_TYPE_INT 3096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) || uni->type->base_type == GLSL_TYPE_UINT 3106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) || uni->type->base_type == GLSL_TYPE_SAMPLER))) { 3116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) memcpy(paramsOut, src, bytes); 3126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } else { 3136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) union gl_constant_value *const dst = 3146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) (union gl_constant_value *) paramsOut; 3156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 3166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) /* This code could be optimized by putting the loop inside the switch 3174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * statements. However, this is not expected to be 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * performance-critical code. 3194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 3204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (unsigned i = 0; i < elements; i++) { 3214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) switch (returnType) { 3224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case GLSL_TYPE_FLOAT: 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (uni->type->base_type) { 3244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case GLSL_TYPE_UINT: 3254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) dst[i].f = (float) src[i].u; 3264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) break; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case GLSL_TYPE_INT: 3288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) case GLSL_TYPE_SAMPLER: 3298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) dst[i].f = (float) src[i].i; 3308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) break; 3318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) case GLSL_TYPE_BOOL: 3324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) dst[i].f = src[i].i ? 1.0f : 0.0f; 3334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) break; 3344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) default: 3354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) assert(!"Should not get here."); 336c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch break; 3374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 3384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) break; 3394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case GLSL_TYPE_INT: 3414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case GLSL_TYPE_UINT: 3424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) switch (uni->type->base_type) { 3434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case GLSL_TYPE_FLOAT: 3444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) /* While the GL 3.2 core spec doesn't explicitly 3454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * state how conversion of float uniforms to integer 3464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * values works, in section 6.2 "State Tables" on 3474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * page 267 it says: 3484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * 34990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * "Unless otherwise specified, when floating 3504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * point state is returned as integer values or 3514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * integer state is returned as floating-point 3524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * values it is converted in the fashion 3538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * described in section 6.1.2" 3544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * That section, on page 248, says: 3564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * 357c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * "If GetIntegerv or GetInteger64v are called, 358c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * a floating-point value is rounded to the 3594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * nearest integer..." 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dst[i].i = IROUND(src[i].f); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch case GLSL_TYPE_BOOL: 3647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch dst[i].i = src[i].i ? 1 : 0; 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch default: 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(!"Should not get here."); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(!"Should not get here."); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 377f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 378f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 379f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)log_uniform(const void *values, enum glsl_base_type basicType, 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned rows, unsigned cols, unsigned count, 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool transpose, 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct gl_shader_program *shProg, 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLint location, 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct gl_uniform_storage *uni) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const union gl_constant_value *v = (const union gl_constant_value *) values; 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const unsigned elems = rows * cols * count; 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *const extra = (cols == 1) ? "uniform" : "uniform matrix"; 393ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 394ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch printf("Mesa: set program %u %s \"%s\" (loc %d, type \"%s\", " 395ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "transpose = %s) to: ", 396ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch shProg->Name, extra, uni->name, location, uni->type->name, 397c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch transpose ? "true" : "false"); 398ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (unsigned i = 0; i < elems; i++) { 399ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (i != 0 && ((i % rows) == 0)) 400ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch printf(", "); 401ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 402ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch switch (basicType) { 403ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case GLSL_TYPE_UINT: 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("%u ", v[i].u); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case GLSL_TYPE_INT: 4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) printf("%d ", v[i].i); 4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case GLSL_TYPE_FLOAT: 4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) printf("%g ", v[i].f); 4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) default: 413a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) assert(!"Should not get here."); 414a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 415a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 416a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 417a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) printf("\n"); 418a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) fflush(stdout); 419a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 420a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 421a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if 0 422a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static void 423a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)log_program_parameters(const struct gl_shader_program *shProg) 424a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles){ 425a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) static const char *stages[] = { 426a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "vertex", "fragment", "geometry" 427a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) }; 428a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 429a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch assert(Elements(stages) == MESA_SHADER_TYPES); 430a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 431a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 432a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (shProg->_LinkedShaders[i] == NULL) 4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) continue; 434b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 435b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const struct gl_program *const prog = shProg->_LinkedShaders[i]->Program; 436b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) printf("Program %d %s shader parameters:\n", 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shProg->Name, stages[i]); 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned j = 0; j < prog->Parameters->NumParameters; j++) { 4400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch printf("%s: %p %f %f %f %f\n", 4410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch prog->Parameters->Parameters[j].Name, 4420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch prog->Parameters->ParameterValues[j], 4430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch prog->Parameters->ParameterValues[j][0].f, 4440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch prog->Parameters->ParameterValues[j][1].f, 4450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch prog->Parameters->ParameterValues[j][2].f, 446f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) prog->Parameters->ParameterValues[j][3].f); 447f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 448f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 449f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) fflush(stdout); 450f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 451f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif 452c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 453f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/** 454f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Propagate some values from uniform backing storage to driver storage 455c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * 456f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Values propagated from uniform backing storage to driver storage 457f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * have all format / type conversions previously requested by the 458f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * driver applied. This function is most often called by the 4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * implementations of \c glUniform1f, etc. and \c glUniformMatrix2f, 460c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * etc. 4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * 4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * \param uni Uniform whose data is to be propagated to driver storage 4635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * \param array_index If \c uni is an array, this is the element of 464c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * the array to be propagated. 4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * \param count Number of array elements to propagate. 4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 467c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochextern "C" void 4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)_mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage *uni, 4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) unsigned array_index, 4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) unsigned count) 471b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles){ 472b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) unsigned i; 473b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 4745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /* vector_elements and matrix_columns can be 0 for samplers. 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const unsigned components = MAX2(1, uni->type->vector_elements); 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const unsigned vectors = MAX2(1, uni->type->matrix_columns); 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Store the data in the driver's requested type in the driver's storage 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * areas. 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned src_vector_byte_stride = components * 4; 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < uni->num_driver_storage; i++) { 485cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) struct gl_uniform_driver_storage *const store = &uni->driver_storage[i]; 486cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) uint8_t *dst = (uint8_t *) store->data; 487f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const unsigned extra_stride = 488cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) store->element_stride - (vectors * store->vector_stride); 489cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const uint8_t *src = 490cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) (uint8_t *) (&uni->storage[array_index * (components * vectors)].i); 491cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 492cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if 0 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("%s: %p[%d] components=%u vectors=%u count=%u vector_stride=%u " 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "extra_stride=%u\n", 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __func__, dst, array_index, components, 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vectors, count, store->vector_stride, extra_stride); 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dst += array_index * store->element_stride; 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (store->format) { 5021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) case uniform_native: 503c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch case uniform_bool_int_0_1: { 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned j; 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned v; 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) for (j = 0; j < count; j++) { 508c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch for (v = 0; v < vectors; v++) { 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(dst, src, src_vector_byte_stride); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) src += src_vector_byte_stride; 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dst += store->vector_stride; 5121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 513c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dst += extra_stride; 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 519f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case uniform_int_float: 520c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch case uniform_bool_float: { 521c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const int *isrc = (const int *) src; 522c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch unsigned j; 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned v; 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned c; 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (j = 0; j < count; j++) { 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (v = 0; v < vectors; v++) { 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (c = 0; c < components; c++) { 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((float *) dst)[c] = (float) *isrc; 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) isrc++; 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) dst += store->vector_stride; 5344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 5354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) dst += extra_stride; 5374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 539c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 540c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case uniform_bool_int_0_not0: { 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int *isrc = (const int *) src; 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned j; 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned v; 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned c; 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (j = 0; j < count; j++) { 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (v = 0; v < vectors; v++) { 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (c = 0; c < components; c++) { 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((int *) dst)[c] = *isrc == 0 ? 0 : ~0; 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) isrc++; 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dst += store->vector_stride; 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dst += extra_stride; 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(!"Should not get here."); 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Called via glUniform*() functions. 5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern "C" void 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)_mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg, 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLint location, GLsizei count, 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GLvoid *values, GLenum type) 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned loc, offset; 5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned components; 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned src_components; 580a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) enum glsl_base_type basicType; 581a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) struct gl_uniform_storage *uni; 582f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 583a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ASSERT_OUTSIDE_BEGIN_END(ctx); 584a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 585a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!validate_uniform_parameters(ctx, shProg, location, count, 5864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) &loc, &offset, "glUniform", false)) 587a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 588c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 5894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uni = &shProg->UniformStorage[loc]; 590f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 591a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) /* Verify that the types are compatible. 592f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */ 5931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) switch (type) { 5945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case GL_FLOAT: 5954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) basicType = GLSL_TYPE_FLOAT; 596a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) src_components = 1; 597a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) break; 598c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch case GL_FLOAT_VEC2: 599c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch basicType = GLSL_TYPE_FLOAT; 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) src_components = 2; 601a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) break; 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case GL_FLOAT_VEC3: 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) basicType = GLSL_TYPE_FLOAT; 604eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch src_components = 3; 605eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 606eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch case GL_FLOAT_VEC4: 607eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch basicType = GLSL_TYPE_FLOAT; 608eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch src_components = 4; 6097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch break; 6107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch case GL_UNSIGNED_INT: 611eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch basicType = GLSL_TYPE_UINT; 612eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch src_components = 1; 6138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) break; 6148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) case GL_UNSIGNED_INT_VEC2: 6158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) basicType = GLSL_TYPE_UINT; 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) src_components = 2; 6175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 6185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case GL_UNSIGNED_INT_VEC3: 6195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) basicType = GLSL_TYPE_UINT; 6205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) src_components = 3; 6215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 6225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case GL_UNSIGNED_INT_VEC4: 6238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) basicType = GLSL_TYPE_UINT; 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) src_components = 4; 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case GL_INT: 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) basicType = GLSL_TYPE_INT; 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) src_components = 1; 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case GL_INT_VEC2: 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) basicType = GLSL_TYPE_INT; 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) src_components = 2; 6334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) break; 6345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case GL_INT_VEC3: 6354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) basicType = GLSL_TYPE_INT; 6364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) src_components = 3; 6374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) break; 6384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case GL_INT_VEC4: 639c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch basicType = GLSL_TYPE_INT; 640effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch src_components = 4; 641c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch break; 642effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch case GL_BOOL: 6434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case GL_BOOL_VEC2: 644effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch case GL_BOOL_VEC3: 645effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch case GL_BOOL_VEC4: 6464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case GL_FLOAT_MAT2: 6474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case GL_FLOAT_MAT2x3: 6484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case GL_FLOAT_MAT2x4: 6495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case GL_FLOAT_MAT3x2: 650c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch case GL_FLOAT_MAT3: 6514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case GL_FLOAT_MAT3x4: 6524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case GL_FLOAT_MAT4x2: 6535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case GL_FLOAT_MAT4x3: 6544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case GL_FLOAT_MAT4: 6554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) default: 6564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) _mesa_problem(NULL, "Invalid type in %s", __func__); 657c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 6584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (uni->type->is_sampler()) { 6614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) components = 1; 6624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 6634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) components = uni->type->vector_elements; 664effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 665effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 6664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool match; 6674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) switch (uni->type->base_type) { 6684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case GLSL_TYPE_BOOL: 6694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) match = true; 6704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) break; 6714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case GLSL_TYPE_SAMPLER: 6724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) match = (basicType == GLSL_TYPE_INT); 6734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) break; 6744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) default: 6754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) match = (basicType == uni->type->base_type); 6765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 6775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (uni->type->is_matrix() || components != src_components || !match) { 6805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(type mismatch)"); 6815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 6825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (ctx->Shader.Flags & GLSL_UNIFORMS) { 6854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) log_uniform(values, basicType, components, 1, count, 6865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) false, shProg, location, uni); 6875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /* Page 100 (page 116 of the PDF) of the OpenGL 3.0 spec says: 6904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * 6914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * "Setting a sampler's value to i selects texture image unit number 692cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * i. The values of i range from zero to the implementation- dependent 6934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * maximum supported number of texture image units." 6944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * 6954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * In addition, table 2.3, "Summary of GL errors," on page 17 (page 33 of 6964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * the PDF) says: 697f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) * 698a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * "Error Description Offending command 699f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) * ignored? 700c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * ... 701a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * INVALID_VALUE Numeric argument out of range Yes" 7024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * 7035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Based on that, when an invalid sampler is specified, we generate a 7045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * GL_INVALID_VALUE error and ignore the command. 7054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 7064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (uni->type->is_sampler()) { 7074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int i; 708a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 709a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (i = 0; i < count; i++) { 710a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const unsigned texUnit = ((unsigned *) values)[i]; 711a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 712a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /* check that the sampler (tex unit index) is legal */ 713a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (texUnit >= ctx->Const.MaxCombinedTextureImageUnits) { 714a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) _mesa_error(ctx, GL_INVALID_VALUE, 715a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "glUniform1i(invalid sampler/tex unit index for " 716a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "uniform %d)", 7174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) location); 7184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 7194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 7204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 7214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 7224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says: 7244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * 7254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * "When loading N elements starting at an arbitrary position k in a 726a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * uniform declared as an array, elements k through k + N - 1 in the 727a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * array will be replaced with the new values. Values for any array 728a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * element that exceeds the highest array element index used, as 729a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * reported by GetActiveUniform, will be ignored by the GL." 730a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * 731a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * Clamp 'count' to a valid value. Note that for non-arrays a count > 1 732a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * will have already generated an error. 733a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) */ 734a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (uni->array_elements != 0) { 735a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (offset >= uni->array_elements) 736a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return; 737a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 738a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) count = MIN2(count, (int) (uni->array_elements - offset)); 739a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 740a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 741cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); 7425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 743a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) /* Store the data in the "actual type" backing storage for the uniform. 744a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) */ 745a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!uni->type->is_boolean()) { 746a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) memcpy(&uni->storage[components * offset], values, 747a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) sizeof(uni->storage[0]) * components * count); 748a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else { 7494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const union gl_constant_value *src = 7504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) (const union gl_constant_value *) values; 751f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) union gl_constant_value *dst = &uni->storage[components * offset]; 7524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const unsigned elems = components * count; 753a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) unsigned i; 754a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 755a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (i = 0; i < elems; i++) { 756a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (basicType == GLSL_TYPE_FLOAT) { 757a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) dst[i].i = src[i].f != 0.0f ? 1 : 0; 7584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 7594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) dst[i].i = src[i].i != 0 ? 1 : 0; 7604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 7614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 7624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 7634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uni->initialized = true; 7654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) _mesa_propagate_uniforms_to_driver_storage(uni, offset, count); 7674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) /* If the uniform is a sampler, do the extra magic necessary to propagate 769cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * the changes through. 7705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 7714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (uni->type->is_sampler()) { 772a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int i; 773f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 774a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (i = 0; i < count; i++) { 775f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) shProg->SamplerUnits[uni->sampler + offset + i] = 7764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ((unsigned *) values)[i]; 7774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 7784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool flushed = false; 7805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (i = 0; i < MESA_SHADER_TYPES; i++) { 7814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) struct gl_shader *const sh = shProg->_LinkedShaders[i]; 7825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 7834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) /* If the shader stage doesn't use any samplers, don't bother 784cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * checking if any samplers have changed. 785cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 786cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (sh == NULL || sh->active_samplers == 0) 787cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) continue; 788cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 7894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) struct gl_program *const prog = sh->Program; 7904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) assert(sizeof(prog->SamplerUnits) == sizeof(shProg->SamplerUnits)); 7924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /* Determine if any of the samplers used by this shader stage have 7944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * been modified. 7954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 7964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool changed = false; 7971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) for (unsigned j = 0; j < Elements(prog->SamplerUnits); j++) { 7980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if ((sh->active_samplers & (1U << j)) != 0 7990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) && (prog->SamplerUnits[j] != shProg->SamplerUnits[j])) { 8004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) changed = true; 801c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch break; 802c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 803effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 8045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 805c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (changed) { 8065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!flushed) { 8075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM); 8085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu flushed = true; 8094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 810c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 8115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) memcpy(prog->SamplerUnits, 812c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch shProg->SamplerUnits, 8134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sizeof(shProg->SamplerUnits)); 8144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 8154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) _mesa_update_shader_textures_used(shProg, prog); 8164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (ctx->Driver.SamplerUniformChange) 817c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ctx->Driver.SamplerUniformChange(ctx, prog->Target, prog); 8184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 8194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 8204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 8214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 8224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 8234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/** 824cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Called by glUniformMatrix*() functions. 8254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Note: cols=2, rows=4 ==> array[2] of vec4 826f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */ 827c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochextern "C" void 8281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)_mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg, 8290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) GLuint cols, GLuint rows, 830effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch GLint location, GLsizei count, 831c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GLboolean transpose, const GLfloat *values) 8325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu{ 8335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu unsigned loc, offset; 8340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) unsigned vectors; 835c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch unsigned components; 836c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch unsigned elements; 8375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct gl_uniform_storage *uni; 8380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 839c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ASSERT_OUTSIDE_BEGIN_END(ctx); 8404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 8414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!validate_uniform_parameters(ctx, shProg, location, count, 842c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch &loc, &offset, "glUniformMatrix", false)) 843c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 844c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 845c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch uni = &shProg->UniformStorage[loc]; 846c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!uni->type->is_matrix()) { 847c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch _mesa_error(ctx, GL_INVALID_OPERATION, 8484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "glUniformMatrix(non-matrix uniform)"); 8494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 8504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 851effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 8524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) assert(!uni->type->is_sampler()); 8530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) vectors = uni->type->matrix_columns; 8544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) components = uni->type->vector_elements; 8554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 8565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /* Verify that the types are compatible. This is greatly simplified for 8574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * matrices because they can only have a float base type. 8584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 859010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (vectors != cols || components != rows) { 860cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) _mesa_error(ctx, GL_INVALID_OPERATION, 8614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "glUniformMatrix(matrix size mismatch)"); 8624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 8634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 8644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 8654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) /* GL_INVALID_VALUE is generated if `transpose' is not GL_FALSE. 866a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * http://www.khronos.org/opengles/sdk/docs/man/xhtml/glUniform.xml */ 8674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (ctx->API == API_OPENGLES || ctx->API == API_OPENGLES2) { 868a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (transpose) { 8694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) _mesa_error(ctx, GL_INVALID_VALUE, 8704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "glUniformMatrix(matrix transpose is not GL_FALSE)"); 871a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 872a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 8734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 8744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 8754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (ctx->Shader.Flags & GLSL_UNIFORMS) { 876c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch log_uniform(values, GLSL_TYPE_FLOAT, components, vectors, count, 8774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool(transpose), shProg, location, uni); 878c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 8794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 8804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says: 881cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * 882cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * "When loading N elements starting at an arbitrary position k in a 8831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) * uniform declared as an array, elements k through k + N - 1 in the 8844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * array will be replaced with the new values. Values for any array 8854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * element that exceeds the highest array element index used, as 8865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * reported by GetActiveUniform, will be ignored by the GL." 8874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * 888c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * Clamp 'count' to a valid value. Note that for non-arrays a count > 1 8895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * will have already generated an error. 8904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 8915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (uni->array_elements != 0) { 8924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (offset >= uni->array_elements) 893cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 894cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 8954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) count = MIN2(count, (int) (uni->array_elements - offset)); 896c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 8974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 8985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); 8995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 9005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /* Store the data in the "actual type" backing storage for the uniform. 9015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 9025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) elements = components * vectors; 9035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 9045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!transpose) { 9054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) memcpy(&uni->storage[elements * offset], values, 9064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sizeof(uni->storage[0]) * elements * count); 907c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } else { 9084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) /* Copy and transpose the matrix. 909c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch */ 9104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const float *src = values; 9114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) float *dst = &uni->storage[elements * offset].f; 912c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 9134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (int i = 0; i < count; i++) { 9144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (unsigned r = 0; r < rows; r++) { 9154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (unsigned c = 0; c < cols; c++) { 916a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) dst[(c * components) + r] = src[c + (r * vectors)]; 917a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 9184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 9194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 920cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) dst += elements; 921cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) src += elements; 9224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 9234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 924c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 9254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uni->initialized = true; 9264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 9275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) _mesa_propagate_uniforms_to_driver_storage(uni, offset, count); 9285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 929c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 9304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/** 9314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Called via glGetUniformLocation(). 932c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * 9334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Returns the uniform index into UniformStorage (also the 9344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * glGetActiveUniformsiv uniform index), and stores the referenced 9354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * array offset in *offset, or GL_INVALID_INDEX (-1). Those two 9364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * return values can be encoded into a uniform location for 9375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * glUniform* using _mesa_uniform_merge_location_offset(index, offset). 9384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 9395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)extern "C" unsigned 9404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)_mesa_get_uniform_location(struct gl_context *ctx, 941116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch struct gl_shader_program *shProg, 942116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const GLchar *name, 943116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch unsigned *out_offset) 944116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch{ 9454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const size_t len = strlen(name); 9464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) long offset; 9474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool array_lookup; 948effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch char *name_copy; 949a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 950a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /* If the name ends with a ']', assume that it refers to some element of an 951c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * array. Malformed array references will fail the hash table look up 952a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * below, so it doesn't matter that they are not caught here. This code 9534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * only wants to catch the "leaf" array references so that arrays of 9544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * structures containing arrays will be handled correctly. 955c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch */ 956c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (name[len-1] == ']') { 9574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) unsigned i; 9584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 9594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) /* Walk backwards over the string looking for a non-digit character. 9604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * This had better be the opening bracket for an array index. 9614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * 9624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Initially, i specifies the location of the ']'. Since the string may 9634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * contain only the ']' charcater, walk backwards very carefully. 9644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 9654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (i = len - 1; (i > 0) && isdigit(name[i-1]); --i) 9664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) /* empty */ ; 9674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 9684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) /* Page 80 (page 94 of the PDF) of the OpenGL 2.1 spec says: 9694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * 9704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * "The first element of a uniform array is identified using the 9714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * name of the uniform array appended with "[0]". Except if the last 9724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * part of the string name indicates a uniform array, then the 9734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * location of the first element of that array can be retrieved by 9744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * either using the name of the uniform array, or the name of the 9754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * uniform array appended with "[0]"." 976cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * 9774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Page 79 (page 93 of the PDF) of the OpenGL 2.1 spec says: 9784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * 9794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * "name must be a null terminated string, without white space." 9804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * 9814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Return an error if there is no opening '[' to match the closing ']'. 9824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * An error will also be returned if there is intervening white space 9834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * (or other non-digit characters) before the opening '['. 984c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch */ 9854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if ((i == 0) || name[i-1] != '[') 9864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return GL_INVALID_INDEX; 9874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 9884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) /* Return an error if there are no digits between the opening '[' to 9894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * match the closing ']'. 9904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 9911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (i == (len - 1)) 9921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return GL_INVALID_INDEX; 9930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 9944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) /* Make a new string that is a copy of the old string up to (but not 995c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * including) the '[' character. 996a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) */ 997a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) name_copy = (char *) malloc(i); 9984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) memcpy(name_copy, name, i - 1); 9994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) name_copy[i-1] = '\0'; 10004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 10014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) offset = strtol(&name[i], NULL, 10); 10024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (offset < 0) { 10034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) free(name_copy); 10044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return GL_INVALID_INDEX; 10054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1006c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 10074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) array_lookup = true; 10084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 10094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) name_copy = (char *) name; 10104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) offset = 0; 1011a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) array_lookup = false; 1012a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 1013c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 1014c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch unsigned location = 0; 1015c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const bool found = shProg->UniformHash->get(location, name_copy); 1016a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1017a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) assert(!found 1018cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) || strcmp(name_copy, shProg->UniformStorage[location].name) == 0); 1019cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1020cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /* Free the temporary buffer *before* possibly returning an error. 1021cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 1022cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (name_copy != name) 1023cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) free(name_copy); 1024cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1025a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!found) 10264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return GL_INVALID_INDEX; 10278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 10288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) /* Since array_elements is 0 for non-arrays, this causes look-ups of 'a[0]' 10294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * to (correctly) fail if 'a' is not an array. 10304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 10314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (array_lookup && shProg->UniformStorage[location].array_elements == 0) { 10324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return GL_INVALID_INDEX; 10334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 10344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 10354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) *out_offset = offset; 10364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return location; 10374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 10384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 10394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)extern "C" bool 10404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)_mesa_sampler_uniforms_are_valid(const struct gl_shader_program *shProg, 10414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) char *errMsg, size_t errMsgLength) 10424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles){ 10434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const glsl_type *unit_types[MAX_COMBINED_TEXTURE_IMAGE_UNITS]; 1044c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 10454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) memset(unit_types, 0, sizeof(unit_types)); 10460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 10474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (unsigned i = 0; i < shProg->NumUserUniformStorage; i++) { 1048c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const struct gl_uniform_storage *const storage = 1049c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch &shProg->UniformStorage[i]; 1050c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const glsl_type *const t = (storage->type->is_array()) 10514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ? storage->type->fields.array : storage->type; 10524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 10531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!t->is_sampler()) 1054c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch continue; 10554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 10564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const unsigned count = MAX2(1, storage->type->array_size()); 10574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (unsigned j = 0; j < count; j++) { 10584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const unsigned unit = storage->storage[j].i; 10594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1060c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch /* The types of the samplers associated with a particular texture 10611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) * unit must be an exact match. Page 74 (page 89 of the PDF) of the 10624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * OpenGL 3.3 core spec says: 10634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * 1064f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * "It is not allowed to have variables of different sampler 10654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * types pointing to the same texture image unit within a program 1066c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * object." 10674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 10684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (unit_types[unit] == NULL) { 10694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) unit_types[unit] = t; 1070c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } else if (unit_types[unit] != t) { 1071c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch _mesa_snprintf(errMsg, errMsgLength, 10724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "Texture unit %d is accessed both as %s and %s", 10734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) unit, unit_types[unit]->name, t->name); 10744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return false; 10754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1076c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 10774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 10784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 10794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return true; 10804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1081f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)