shaderapi.c revision b8e80941
1848b8605Smrg/* 2848b8605Smrg * Mesa 3-D graphics library 3848b8605Smrg * 4848b8605Smrg * Copyright (C) 2004-2008 Brian Paul All Rights Reserved. 5848b8605Smrg * Copyright (C) 2009-2010 VMware, Inc. All Rights Reserved. 6848b8605Smrg * 7848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 8848b8605Smrg * copy of this software and associated documentation files (the "Software"), 9848b8605Smrg * to deal in the Software without restriction, including without limitation 10848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the 12848b8605Smrg * Software is furnished to do so, subject to the following conditions: 13848b8605Smrg * 14848b8605Smrg * The above copyright notice and this permission notice shall be included 15848b8605Smrg * in all copies or substantial portions of the Software. 16848b8605Smrg * 17848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21848b8605Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22848b8605Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23848b8605Smrg * OTHER DEALINGS IN THE SOFTWARE. 24848b8605Smrg */ 25848b8605Smrg 26848b8605Smrg/** 27848b8605Smrg * \file shaderapi.c 28848b8605Smrg * \author Brian Paul 29848b8605Smrg * 30848b8605Smrg * Implementation of GLSL-related API functions. 31848b8605Smrg * The glUniform* functions are in uniforms.c 32848b8605Smrg * 33848b8605Smrg * 34848b8605Smrg * XXX things to do: 35848b8605Smrg * 1. Check that the right error code is generated for all _mesa_error() calls. 36848b8605Smrg * 2. Insert FLUSH_VERTICES calls in various places 37848b8605Smrg */ 38848b8605Smrg 39848b8605Smrg 40b8e80941Smrg#include <stdbool.h> 41b8e80941Smrg#include <c99_alloca.h> 42848b8605Smrg#include "main/glheader.h" 43848b8605Smrg#include "main/context.h" 44848b8605Smrg#include "main/enums.h" 45b8e80941Smrg#include "main/glspirv.h" 46848b8605Smrg#include "main/hash.h" 47848b8605Smrg#include "main/mtypes.h" 48848b8605Smrg#include "main/pipelineobj.h" 49b8e80941Smrg#include "main/program_binary.h" 50848b8605Smrg#include "main/shaderapi.h" 51848b8605Smrg#include "main/shaderobj.h" 52b8e80941Smrg#include "main/state.h" 53848b8605Smrg#include "main/transformfeedback.h" 54848b8605Smrg#include "main/uniforms.h" 55b8e80941Smrg#include "compiler/glsl/glsl_parser_extras.h" 56b8e80941Smrg#include "compiler/glsl/ir.h" 57b8e80941Smrg#include "compiler/glsl/ir_uniform.h" 58b8e80941Smrg#include "compiler/glsl/program.h" 59848b8605Smrg#include "program/program.h" 60848b8605Smrg#include "program/prog_print.h" 61848b8605Smrg#include "program/prog_parameter.h" 62848b8605Smrg#include "util/ralloc.h" 63848b8605Smrg#include "util/hash_table.h" 64b8e80941Smrg#include "util/mesa-sha1.h" 65b8e80941Smrg#include "util/crc32.h" 66848b8605Smrg 67848b8605Smrg/** 68848b8605Smrg * Return mask of GLSL_x flags by examining the MESA_GLSL env var. 69848b8605Smrg */ 70848b8605SmrgGLbitfield 71848b8605Smrg_mesa_get_shader_flags(void) 72848b8605Smrg{ 73848b8605Smrg GLbitfield flags = 0x0; 74b8e80941Smrg const char *env = getenv("MESA_GLSL"); 75848b8605Smrg 76848b8605Smrg if (env) { 77848b8605Smrg if (strstr(env, "dump_on_error")) 78848b8605Smrg flags |= GLSL_DUMP_ON_ERROR; 79848b8605Smrg else if (strstr(env, "dump")) 80848b8605Smrg flags |= GLSL_DUMP; 81848b8605Smrg if (strstr(env, "log")) 82848b8605Smrg flags |= GLSL_LOG; 83b8e80941Smrg if (strstr(env, "cache_fb")) 84b8e80941Smrg flags |= GLSL_CACHE_FALLBACK; 85b8e80941Smrg if (strstr(env, "cache_info")) 86b8e80941Smrg flags |= GLSL_CACHE_INFO; 87848b8605Smrg if (strstr(env, "nopvert")) 88848b8605Smrg flags |= GLSL_NOP_VERT; 89848b8605Smrg if (strstr(env, "nopfrag")) 90848b8605Smrg flags |= GLSL_NOP_FRAG; 91848b8605Smrg if (strstr(env, "uniform")) 92848b8605Smrg flags |= GLSL_UNIFORMS; 93848b8605Smrg if (strstr(env, "useprog")) 94848b8605Smrg flags |= GLSL_USE_PROG; 95848b8605Smrg if (strstr(env, "errors")) 96848b8605Smrg flags |= GLSL_REPORT_ERRORS; 97848b8605Smrg } 98848b8605Smrg 99848b8605Smrg return flags; 100848b8605Smrg} 101848b8605Smrg 102b8e80941Smrg/** 103b8e80941Smrg * Memoized version of getenv("MESA_SHADER_CAPTURE_PATH"). 104b8e80941Smrg */ 105b8e80941Smrgconst char * 106b8e80941Smrg_mesa_get_shader_capture_path(void) 107b8e80941Smrg{ 108b8e80941Smrg static bool read_env_var = false; 109b8e80941Smrg static const char *path = NULL; 110b8e80941Smrg 111b8e80941Smrg if (!read_env_var) { 112b8e80941Smrg path = getenv("MESA_SHADER_CAPTURE_PATH"); 113b8e80941Smrg read_env_var = true; 114b8e80941Smrg } 115b8e80941Smrg 116b8e80941Smrg return path; 117b8e80941Smrg} 118848b8605Smrg 119848b8605Smrg/** 120848b8605Smrg * Initialize context's shader state. 121848b8605Smrg */ 122848b8605Smrgvoid 123848b8605Smrg_mesa_init_shader_state(struct gl_context *ctx) 124848b8605Smrg{ 125848b8605Smrg /* Device drivers may override these to control what kind of instructions 126848b8605Smrg * are generated by the GLSL compiler. 127848b8605Smrg */ 128848b8605Smrg struct gl_shader_compiler_options options; 129848b8605Smrg gl_shader_stage sh; 130b8e80941Smrg int i; 131848b8605Smrg 132848b8605Smrg memset(&options, 0, sizeof(options)); 133848b8605Smrg options.MaxUnrollIterations = 32; 134848b8605Smrg options.MaxIfDepth = UINT_MAX; 135848b8605Smrg 136848b8605Smrg for (sh = 0; sh < MESA_SHADER_STAGES; ++sh) 137848b8605Smrg memcpy(&ctx->Const.ShaderCompilerOptions[sh], &options, sizeof(options)); 138848b8605Smrg 139848b8605Smrg ctx->Shader.Flags = _mesa_get_shader_flags(); 140848b8605Smrg 141b8e80941Smrg if (ctx->Shader.Flags != 0) 142b8e80941Smrg ctx->Const.GenerateTemporaryNames = true; 143b8e80941Smrg 144848b8605Smrg /* Extended for ARB_separate_shader_objects */ 145848b8605Smrg ctx->Shader.RefCount = 1; 146b8e80941Smrg ctx->TessCtrlProgram.patch_vertices = 3; 147b8e80941Smrg for (i = 0; i < 4; ++i) 148b8e80941Smrg ctx->TessCtrlProgram.patch_default_outer_level[i] = 1.0; 149b8e80941Smrg for (i = 0; i < 2; ++i) 150b8e80941Smrg ctx->TessCtrlProgram.patch_default_inner_level[i] = 1.0; 151848b8605Smrg} 152848b8605Smrg 153848b8605Smrg 154848b8605Smrg/** 155848b8605Smrg * Free the per-context shader-related state. 156848b8605Smrg */ 157848b8605Smrgvoid 158848b8605Smrg_mesa_free_shader_state(struct gl_context *ctx) 159848b8605Smrg{ 160b8e80941Smrg for (int i = 0; i < MESA_SHADER_STAGES; i++) { 161b8e80941Smrg _mesa_reference_program(ctx, &ctx->Shader.CurrentProgram[i], NULL); 162b8e80941Smrg _mesa_reference_shader_program(ctx, 163b8e80941Smrg &ctx->Shader.ReferencedPrograms[i], 164848b8605Smrg NULL); 165b8e80941Smrg free(ctx->SubroutineIndex[i].IndexPtr); 166b8e80941Smrg ctx->SubroutineIndex[i].IndexPtr = NULL; 167848b8605Smrg } 168848b8605Smrg _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, NULL); 169848b8605Smrg 170848b8605Smrg /* Extended for ARB_separate_shader_objects */ 171848b8605Smrg _mesa_reference_pipeline_object(ctx, &ctx->_Shader, NULL); 172848b8605Smrg 173848b8605Smrg assert(ctx->Shader.RefCount == 1); 174848b8605Smrg} 175848b8605Smrg 176848b8605Smrg 177848b8605Smrg/** 178848b8605Smrg * Copy string from <src> to <dst>, up to maxLength characters, returning 179848b8605Smrg * length of <dst> in <length>. 180848b8605Smrg * \param src the strings source 181848b8605Smrg * \param maxLength max chars to copy 182848b8605Smrg * \param length returns number of chars copied 183848b8605Smrg * \param dst the string destination 184848b8605Smrg */ 185848b8605Smrgvoid 186848b8605Smrg_mesa_copy_string(GLchar *dst, GLsizei maxLength, 187848b8605Smrg GLsizei *length, const GLchar *src) 188848b8605Smrg{ 189848b8605Smrg GLsizei len; 190848b8605Smrg for (len = 0; len < maxLength - 1 && src && src[len]; len++) 191848b8605Smrg dst[len] = src[len]; 192848b8605Smrg if (maxLength > 0) 193848b8605Smrg dst[len] = 0; 194848b8605Smrg if (length) 195848b8605Smrg *length = len; 196848b8605Smrg} 197848b8605Smrg 198848b8605Smrg 199848b8605Smrg 200848b8605Smrg/** 201848b8605Smrg * Confirm that the a shader type is valid and supported by the implementation 202848b8605Smrg * 203848b8605Smrg * \param ctx Current GL context 204848b8605Smrg * \param type Shader target 205848b8605Smrg * 206848b8605Smrg */ 207848b8605Smrgbool 208848b8605Smrg_mesa_validate_shader_target(const struct gl_context *ctx, GLenum type) 209848b8605Smrg{ 210848b8605Smrg /* Note: when building built-in GLSL functions, this function may be 211848b8605Smrg * invoked with ctx == NULL. In that case, we can only validate that it's 212848b8605Smrg * a shader target we recognize, not that it's supported in the current 213848b8605Smrg * context. But that's fine--we don't need any further validation than 214848b8605Smrg * that when building built-in GLSL functions. 215848b8605Smrg */ 216848b8605Smrg 217848b8605Smrg switch (type) { 218848b8605Smrg case GL_FRAGMENT_SHADER: 219848b8605Smrg return ctx == NULL || ctx->Extensions.ARB_fragment_shader; 220848b8605Smrg case GL_VERTEX_SHADER: 221848b8605Smrg return ctx == NULL || ctx->Extensions.ARB_vertex_shader; 222848b8605Smrg case GL_GEOMETRY_SHADER_ARB: 223848b8605Smrg return ctx == NULL || _mesa_has_geometry_shaders(ctx); 224b8e80941Smrg case GL_TESS_CONTROL_SHADER: 225b8e80941Smrg case GL_TESS_EVALUATION_SHADER: 226b8e80941Smrg return ctx == NULL || _mesa_has_tessellation(ctx); 227848b8605Smrg case GL_COMPUTE_SHADER: 228b8e80941Smrg return ctx == NULL || _mesa_has_compute_shaders(ctx); 229848b8605Smrg default: 230848b8605Smrg return false; 231848b8605Smrg } 232848b8605Smrg} 233848b8605Smrg 234848b8605Smrg 235848b8605Smrgstatic GLboolean 236848b8605Smrgis_program(struct gl_context *ctx, GLuint name) 237848b8605Smrg{ 238848b8605Smrg struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, name); 239848b8605Smrg return shProg ? GL_TRUE : GL_FALSE; 240848b8605Smrg} 241848b8605Smrg 242848b8605Smrg 243848b8605Smrgstatic GLboolean 244848b8605Smrgis_shader(struct gl_context *ctx, GLuint name) 245848b8605Smrg{ 246848b8605Smrg struct gl_shader *shader = _mesa_lookup_shader(ctx, name); 247848b8605Smrg return shader ? GL_TRUE : GL_FALSE; 248848b8605Smrg} 249848b8605Smrg 250848b8605Smrg 251848b8605Smrg/** 252848b8605Smrg * Attach shader to a shader program. 253848b8605Smrg */ 254848b8605Smrgstatic void 255b8e80941Smrgattach_shader(struct gl_context *ctx, struct gl_shader_program *shProg, 256b8e80941Smrg struct gl_shader *sh) 257b8e80941Smrg{ 258b8e80941Smrg GLuint n = shProg->NumShaders; 259b8e80941Smrg 260b8e80941Smrg shProg->Shaders = realloc(shProg->Shaders, 261b8e80941Smrg (n + 1) * sizeof(struct gl_shader *)); 262b8e80941Smrg if (!shProg->Shaders) { 263b8e80941Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAttachShader"); 264b8e80941Smrg return; 265b8e80941Smrg } 266b8e80941Smrg 267b8e80941Smrg /* append */ 268b8e80941Smrg shProg->Shaders[n] = NULL; /* since realloc() didn't zero the new space */ 269b8e80941Smrg _mesa_reference_shader(ctx, &shProg->Shaders[n], sh); 270b8e80941Smrg shProg->NumShaders++; 271b8e80941Smrg} 272b8e80941Smrg 273b8e80941Smrgstatic void 274b8e80941Smrgattach_shader_err(struct gl_context *ctx, GLuint program, GLuint shader, 275b8e80941Smrg const char *caller) 276848b8605Smrg{ 277848b8605Smrg struct gl_shader_program *shProg; 278848b8605Smrg struct gl_shader *sh; 279848b8605Smrg GLuint i, n; 280848b8605Smrg 281848b8605Smrg const bool same_type_disallowed = _mesa_is_gles(ctx); 282848b8605Smrg 283b8e80941Smrg shProg = _mesa_lookup_shader_program_err(ctx, program, caller); 284848b8605Smrg if (!shProg) 285848b8605Smrg return; 286848b8605Smrg 287b8e80941Smrg sh = _mesa_lookup_shader_err(ctx, shader, caller); 288848b8605Smrg if (!sh) { 289848b8605Smrg return; 290848b8605Smrg } 291848b8605Smrg 292848b8605Smrg n = shProg->NumShaders; 293848b8605Smrg for (i = 0; i < n; i++) { 294848b8605Smrg if (shProg->Shaders[i] == sh) { 295848b8605Smrg /* The shader is already attched to this program. The 296848b8605Smrg * GL_ARB_shader_objects spec says: 297848b8605Smrg * 298848b8605Smrg * "The error INVALID_OPERATION is generated by AttachObjectARB 299848b8605Smrg * if <obj> is already attached to <containerObj>." 300848b8605Smrg */ 301b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller); 302848b8605Smrg return; 303848b8605Smrg } else if (same_type_disallowed && 304b8e80941Smrg shProg->Shaders[i]->Stage == sh->Stage) { 305848b8605Smrg /* Shader with the same type is already attached to this program, 306848b8605Smrg * OpenGL ES 2.0 and 3.0 specs say: 307848b8605Smrg * 308848b8605Smrg * "Multiple shader objects of the same type may not be attached 309848b8605Smrg * to a single program object. [...] The error INVALID_OPERATION 310848b8605Smrg * is generated if [...] another shader object of the same type 311848b8605Smrg * as shader is already attached to program." 312848b8605Smrg */ 313b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller); 314848b8605Smrg return; 315848b8605Smrg } 316848b8605Smrg } 317848b8605Smrg 318b8e80941Smrg attach_shader(ctx, shProg, sh); 319848b8605Smrg} 320848b8605Smrg 321b8e80941Smrgstatic void 322b8e80941Smrgattach_shader_no_error(struct gl_context *ctx, GLuint program, GLuint shader) 323b8e80941Smrg{ 324b8e80941Smrg struct gl_shader_program *shProg; 325b8e80941Smrg struct gl_shader *sh; 326b8e80941Smrg 327b8e80941Smrg shProg = _mesa_lookup_shader_program(ctx, program); 328b8e80941Smrg sh = _mesa_lookup_shader(ctx, shader); 329b8e80941Smrg 330b8e80941Smrg attach_shader(ctx, shProg, sh); 331b8e80941Smrg} 332848b8605Smrg 333848b8605Smrgstatic GLuint 334848b8605Smrgcreate_shader(struct gl_context *ctx, GLenum type) 335848b8605Smrg{ 336848b8605Smrg struct gl_shader *sh; 337848b8605Smrg GLuint name; 338848b8605Smrg 339b8e80941Smrg _mesa_HashLockMutex(ctx->Shared->ShaderObjects); 340b8e80941Smrg name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1); 341b8e80941Smrg sh = _mesa_new_shader(name, _mesa_shader_enum_to_shader_stage(type)); 342b8e80941Smrg sh->Type = type; 343b8e80941Smrg _mesa_HashInsertLocked(ctx->Shared->ShaderObjects, name, sh); 344b8e80941Smrg _mesa_HashUnlockMutex(ctx->Shared->ShaderObjects); 345b8e80941Smrg 346b8e80941Smrg return name; 347b8e80941Smrg} 348b8e80941Smrg 349b8e80941Smrg 350b8e80941Smrgstatic GLuint 351b8e80941Smrgcreate_shader_err(struct gl_context *ctx, GLenum type, const char *caller) 352b8e80941Smrg{ 353848b8605Smrg if (!_mesa_validate_shader_target(ctx, type)) { 354b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, "%s(%s)", 355b8e80941Smrg caller, _mesa_enum_to_string(type)); 356848b8605Smrg return 0; 357848b8605Smrg } 358848b8605Smrg 359b8e80941Smrg return create_shader(ctx, type); 360848b8605Smrg} 361848b8605Smrg 362848b8605Smrg 363b8e80941Smrgstatic GLuint 364848b8605Smrgcreate_shader_program(struct gl_context *ctx) 365848b8605Smrg{ 366848b8605Smrg GLuint name; 367848b8605Smrg struct gl_shader_program *shProg; 368848b8605Smrg 369b8e80941Smrg _mesa_HashLockMutex(ctx->Shared->ShaderObjects); 370b8e80941Smrg 371848b8605Smrg name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1); 372848b8605Smrg 373b8e80941Smrg shProg = _mesa_new_shader_program(name); 374848b8605Smrg 375b8e80941Smrg _mesa_HashInsertLocked(ctx->Shared->ShaderObjects, name, shProg); 376848b8605Smrg 377848b8605Smrg assert(shProg->RefCount == 1); 378848b8605Smrg 379b8e80941Smrg _mesa_HashUnlockMutex(ctx->Shared->ShaderObjects); 380b8e80941Smrg 381848b8605Smrg return name; 382848b8605Smrg} 383848b8605Smrg 384848b8605Smrg 385848b8605Smrg/** 386b8e80941Smrg * Delete a shader program. Actually, just decrement the program's 387b8e80941Smrg * reference count and mark it as DeletePending. 388b8e80941Smrg * Used to implement glDeleteProgram() and glDeleteObjectARB(). 389848b8605Smrg */ 390848b8605Smrgstatic void 391848b8605Smrgdelete_shader_program(struct gl_context *ctx, GLuint name) 392848b8605Smrg{ 393848b8605Smrg /* 394848b8605Smrg * NOTE: deleting shaders/programs works a bit differently than 395848b8605Smrg * texture objects (and buffer objects, etc). Shader/program 396848b8605Smrg * handles/IDs exist in the hash table until the object is really 397848b8605Smrg * deleted (refcount==0). With texture objects, the handle/ID is 398848b8605Smrg * removed from the hash table in glDeleteTextures() while the tex 399848b8605Smrg * object itself might linger until its refcount goes to zero. 400848b8605Smrg */ 401848b8605Smrg struct gl_shader_program *shProg; 402848b8605Smrg 403848b8605Smrg shProg = _mesa_lookup_shader_program_err(ctx, name, "glDeleteProgram"); 404848b8605Smrg if (!shProg) 405848b8605Smrg return; 406848b8605Smrg 407848b8605Smrg if (!shProg->DeletePending) { 408848b8605Smrg shProg->DeletePending = GL_TRUE; 409848b8605Smrg 410848b8605Smrg /* effectively, decr shProg's refcount */ 411848b8605Smrg _mesa_reference_shader_program(ctx, &shProg, NULL); 412848b8605Smrg } 413848b8605Smrg} 414848b8605Smrg 415848b8605Smrg 416848b8605Smrgstatic void 417848b8605Smrgdelete_shader(struct gl_context *ctx, GLuint shader) 418848b8605Smrg{ 419848b8605Smrg struct gl_shader *sh; 420848b8605Smrg 421848b8605Smrg sh = _mesa_lookup_shader_err(ctx, shader, "glDeleteShader"); 422848b8605Smrg if (!sh) 423848b8605Smrg return; 424848b8605Smrg 425848b8605Smrg if (!sh->DeletePending) { 426848b8605Smrg sh->DeletePending = GL_TRUE; 427848b8605Smrg 428848b8605Smrg /* effectively, decr sh's refcount */ 429848b8605Smrg _mesa_reference_shader(ctx, &sh, NULL); 430848b8605Smrg } 431848b8605Smrg} 432848b8605Smrg 433848b8605Smrg 434b8e80941Smrgstatic ALWAYS_INLINE void 435b8e80941Smrgdetach_shader(struct gl_context *ctx, GLuint program, GLuint shader, 436b8e80941Smrg bool no_error) 437848b8605Smrg{ 438848b8605Smrg struct gl_shader_program *shProg; 439848b8605Smrg GLuint n; 440848b8605Smrg GLuint i, j; 441848b8605Smrg 442b8e80941Smrg if (!no_error) { 443b8e80941Smrg shProg = _mesa_lookup_shader_program_err(ctx, program, "glDetachShader"); 444b8e80941Smrg if (!shProg) 445b8e80941Smrg return; 446b8e80941Smrg } else { 447b8e80941Smrg shProg = _mesa_lookup_shader_program(ctx, program); 448b8e80941Smrg } 449848b8605Smrg 450848b8605Smrg n = shProg->NumShaders; 451848b8605Smrg 452848b8605Smrg for (i = 0; i < n; i++) { 453848b8605Smrg if (shProg->Shaders[i]->Name == shader) { 454848b8605Smrg /* found it */ 455848b8605Smrg struct gl_shader **newList; 456848b8605Smrg 457848b8605Smrg /* release */ 458848b8605Smrg _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL); 459848b8605Smrg 460848b8605Smrg /* alloc new, smaller array */ 461848b8605Smrg newList = malloc((n - 1) * sizeof(struct gl_shader *)); 462848b8605Smrg if (!newList) { 463848b8605Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDetachShader"); 464848b8605Smrg return; 465848b8605Smrg } 466848b8605Smrg /* Copy old list entries to new list, skipping removed entry at [i] */ 467848b8605Smrg for (j = 0; j < i; j++) { 468848b8605Smrg newList[j] = shProg->Shaders[j]; 469848b8605Smrg } 470848b8605Smrg while (++i < n) { 471848b8605Smrg newList[j++] = shProg->Shaders[i]; 472848b8605Smrg } 473848b8605Smrg 474848b8605Smrg /* Free old list and install new one */ 475848b8605Smrg free(shProg->Shaders); 476848b8605Smrg shProg->Shaders = newList; 477848b8605Smrg shProg->NumShaders = n - 1; 478848b8605Smrg 479848b8605Smrg#ifdef DEBUG 480848b8605Smrg /* sanity check - make sure the new list's entries are sensible */ 481848b8605Smrg for (j = 0; j < shProg->NumShaders; j++) { 482b8e80941Smrg assert(shProg->Shaders[j]->Stage == MESA_SHADER_VERTEX || 483b8e80941Smrg shProg->Shaders[j]->Stage == MESA_SHADER_TESS_CTRL || 484b8e80941Smrg shProg->Shaders[j]->Stage == MESA_SHADER_TESS_EVAL || 485b8e80941Smrg shProg->Shaders[j]->Stage == MESA_SHADER_GEOMETRY || 486b8e80941Smrg shProg->Shaders[j]->Stage == MESA_SHADER_FRAGMENT); 487848b8605Smrg assert(shProg->Shaders[j]->RefCount > 0); 488848b8605Smrg } 489848b8605Smrg#endif 490848b8605Smrg 491848b8605Smrg return; 492848b8605Smrg } 493848b8605Smrg } 494848b8605Smrg 495848b8605Smrg /* not found */ 496b8e80941Smrg if (!no_error) { 497848b8605Smrg GLenum err; 498b8e80941Smrg if (is_shader(ctx, shader) || is_program(ctx, shader)) 499848b8605Smrg err = GL_INVALID_OPERATION; 500848b8605Smrg else 501848b8605Smrg err = GL_INVALID_VALUE; 502848b8605Smrg _mesa_error(ctx, err, "glDetachShader(shader)"); 503848b8605Smrg return; 504848b8605Smrg } 505848b8605Smrg} 506848b8605Smrg 507848b8605Smrg 508b8e80941Smrgstatic void 509b8e80941Smrgdetach_shader_error(struct gl_context *ctx, GLuint program, GLuint shader) 510b8e80941Smrg{ 511b8e80941Smrg detach_shader(ctx, program, shader, false); 512b8e80941Smrg} 513b8e80941Smrg 514b8e80941Smrg 515b8e80941Smrgstatic void 516b8e80941Smrgdetach_shader_no_error(struct gl_context *ctx, GLuint program, GLuint shader) 517b8e80941Smrg{ 518b8e80941Smrg detach_shader(ctx, program, shader, true); 519b8e80941Smrg} 520b8e80941Smrg 521b8e80941Smrg 522848b8605Smrg/** 523848b8605Smrg * Return list of shaders attached to shader program. 524b8e80941Smrg * \param objOut returns GLuint ids 525b8e80941Smrg * \param handleOut returns GLhandleARB handles 526848b8605Smrg */ 527848b8605Smrgstatic void 528848b8605Smrgget_attached_shaders(struct gl_context *ctx, GLuint program, GLsizei maxCount, 529b8e80941Smrg GLsizei *countOut, GLuint *objOut, GLhandleARB *handleOut) 530848b8605Smrg{ 531b8e80941Smrg struct gl_shader_program *shProg; 532b8e80941Smrg 533b8e80941Smrg if (maxCount < 0) { 534b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glGetAttachedShaders(maxCount < 0)"); 535b8e80941Smrg return; 536b8e80941Smrg } 537b8e80941Smrg 538b8e80941Smrg shProg = 539848b8605Smrg _mesa_lookup_shader_program_err(ctx, program, "glGetAttachedShaders"); 540b8e80941Smrg 541848b8605Smrg if (shProg) { 542848b8605Smrg GLuint i; 543848b8605Smrg for (i = 0; i < (GLuint) maxCount && i < shProg->NumShaders; i++) { 544b8e80941Smrg if (objOut) { 545b8e80941Smrg objOut[i] = shProg->Shaders[i]->Name; 546b8e80941Smrg } 547b8e80941Smrg 548b8e80941Smrg if (handleOut) { 549b8e80941Smrg handleOut[i] = (GLhandleARB) shProg->Shaders[i]->Name; 550b8e80941Smrg } 551b8e80941Smrg } 552b8e80941Smrg if (countOut) { 553b8e80941Smrg *countOut = i; 554848b8605Smrg } 555848b8605Smrg } 556848b8605Smrg} 557848b8605Smrg 558848b8605Smrg/** 559848b8605Smrg * glGetHandleARB() - return ID/name of currently bound shader program. 560848b8605Smrg */ 561848b8605Smrgstatic GLuint 562848b8605Smrgget_handle(struct gl_context *ctx, GLenum pname) 563848b8605Smrg{ 564848b8605Smrg if (pname == GL_PROGRAM_OBJECT_ARB) { 565848b8605Smrg if (ctx->_Shader->ActiveProgram) 566848b8605Smrg return ctx->_Shader->ActiveProgram->Name; 567848b8605Smrg else 568848b8605Smrg return 0; 569848b8605Smrg } 570848b8605Smrg else { 571848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB"); 572848b8605Smrg return 0; 573848b8605Smrg } 574848b8605Smrg} 575848b8605Smrg 576848b8605Smrg 577848b8605Smrg/** 578848b8605Smrg * Check if a geometry shader query is valid at this time. If not, report an 579848b8605Smrg * error and return false. 580848b8605Smrg * 581848b8605Smrg * From GL 3.2 section 6.1.16 (Shader and Program Queries): 582848b8605Smrg * 583848b8605Smrg * "If GEOMETRY_VERTICES_OUT, GEOMETRY_INPUT_TYPE, or GEOMETRY_OUTPUT_TYPE 584848b8605Smrg * are queried for a program which has not been linked successfully, or 585848b8605Smrg * which does not contain objects to form a geometry shader, then an 586848b8605Smrg * INVALID_OPERATION error is generated." 587848b8605Smrg */ 588848b8605Smrgstatic bool 589848b8605Smrgcheck_gs_query(struct gl_context *ctx, const struct gl_shader_program *shProg) 590848b8605Smrg{ 591b8e80941Smrg if (shProg->data->LinkStatus && 592848b8605Smrg shProg->_LinkedShaders[MESA_SHADER_GEOMETRY] != NULL) { 593848b8605Smrg return true; 594848b8605Smrg } 595848b8605Smrg 596848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 597848b8605Smrg "glGetProgramv(linked geometry shader required)"); 598848b8605Smrg return false; 599848b8605Smrg} 600848b8605Smrg 601848b8605Smrg 602b8e80941Smrg/** 603b8e80941Smrg * Check if a tessellation control shader query is valid at this time. 604b8e80941Smrg * If not, report an error and return false. 605b8e80941Smrg * 606b8e80941Smrg * From GL 4.0 section 6.1.12 (Shader and Program Queries): 607b8e80941Smrg * 608b8e80941Smrg * "If TESS_CONTROL_OUTPUT_VERTICES is queried for a program which has 609b8e80941Smrg * not been linked successfully, or which does not contain objects to 610b8e80941Smrg * form a tessellation control shader, then an INVALID_OPERATION error is 611b8e80941Smrg * generated." 612b8e80941Smrg */ 613b8e80941Smrgstatic bool 614b8e80941Smrgcheck_tcs_query(struct gl_context *ctx, const struct gl_shader_program *shProg) 615b8e80941Smrg{ 616b8e80941Smrg if (shProg->data->LinkStatus && 617b8e80941Smrg shProg->_LinkedShaders[MESA_SHADER_TESS_CTRL] != NULL) { 618b8e80941Smrg return true; 619b8e80941Smrg } 620b8e80941Smrg 621b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 622b8e80941Smrg "glGetProgramv(linked tessellation control shader required)"); 623b8e80941Smrg return false; 624b8e80941Smrg} 625b8e80941Smrg 626b8e80941Smrg 627b8e80941Smrg/** 628b8e80941Smrg * Check if a tessellation evaluation shader query is valid at this time. 629b8e80941Smrg * If not, report an error and return false. 630b8e80941Smrg * 631b8e80941Smrg * From GL 4.0 section 6.1.12 (Shader and Program Queries): 632b8e80941Smrg * 633b8e80941Smrg * "If any of the pname values in this paragraph are queried for a program 634b8e80941Smrg * which has not been linked successfully, or which does not contain 635b8e80941Smrg * objects to form a tessellation evaluation shader, then an 636b8e80941Smrg * INVALID_OPERATION error is generated." 637b8e80941Smrg * 638b8e80941Smrg */ 639b8e80941Smrgstatic bool 640b8e80941Smrgcheck_tes_query(struct gl_context *ctx, const struct gl_shader_program *shProg) 641b8e80941Smrg{ 642b8e80941Smrg if (shProg->data->LinkStatus && 643b8e80941Smrg shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL] != NULL) { 644b8e80941Smrg return true; 645b8e80941Smrg } 646b8e80941Smrg 647b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramv(linked tessellation " 648b8e80941Smrg "evaluation shader required)"); 649b8e80941Smrg return false; 650b8e80941Smrg} 651b8e80941Smrg 652b8e80941Smrg 653848b8605Smrg/** 654848b8605Smrg * glGetProgramiv() - get shader program state. 655848b8605Smrg * Note that this is for GLSL shader programs, not ARB vertex/fragment 656848b8605Smrg * programs (see glGetProgramivARB). 657848b8605Smrg */ 658848b8605Smrgstatic void 659b8e80941Smrgget_programiv(struct gl_context *ctx, GLuint program, GLenum pname, 660b8e80941Smrg GLint *params) 661848b8605Smrg{ 662848b8605Smrg struct gl_shader_program *shProg 663b8e80941Smrg = _mesa_lookup_shader_program_err(ctx, program, "glGetProgramiv(program)"); 664848b8605Smrg 665848b8605Smrg /* Is transform feedback available in this context? 666848b8605Smrg */ 667848b8605Smrg const bool has_xfb = 668848b8605Smrg (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.EXT_transform_feedback) 669848b8605Smrg || ctx->API == API_OPENGL_CORE 670848b8605Smrg || _mesa_is_gles3(ctx); 671848b8605Smrg 672848b8605Smrg /* True if geometry shaders (of the form that was adopted into GLSL 1.50 673848b8605Smrg * and GL 3.2) are available in this context 674848b8605Smrg */ 675b8e80941Smrg const bool has_gs = _mesa_has_geometry_shaders(ctx); 676b8e80941Smrg const bool has_tess = _mesa_has_tessellation(ctx); 677848b8605Smrg 678848b8605Smrg /* Are uniform buffer objects available in this context? 679848b8605Smrg */ 680848b8605Smrg const bool has_ubo = 681b8e80941Smrg (ctx->API == API_OPENGL_COMPAT && 682b8e80941Smrg ctx->Extensions.ARB_uniform_buffer_object) 683848b8605Smrg || ctx->API == API_OPENGL_CORE 684848b8605Smrg || _mesa_is_gles3(ctx); 685848b8605Smrg 686848b8605Smrg if (!shProg) { 687848b8605Smrg return; 688848b8605Smrg } 689848b8605Smrg 690848b8605Smrg switch (pname) { 691848b8605Smrg case GL_DELETE_STATUS: 692848b8605Smrg *params = shProg->DeletePending; 693848b8605Smrg return; 694b8e80941Smrg case GL_COMPLETION_STATUS_ARB: 695b8e80941Smrg if (ctx->Driver.GetShaderProgramCompletionStatus) 696b8e80941Smrg *params = ctx->Driver.GetShaderProgramCompletionStatus(ctx, shProg); 697b8e80941Smrg else 698b8e80941Smrg *params = GL_TRUE; 699b8e80941Smrg return; 700848b8605Smrg case GL_LINK_STATUS: 701b8e80941Smrg *params = shProg->data->LinkStatus ? GL_TRUE : GL_FALSE; 702848b8605Smrg return; 703848b8605Smrg case GL_VALIDATE_STATUS: 704b8e80941Smrg *params = shProg->data->Validated; 705848b8605Smrg return; 706848b8605Smrg case GL_INFO_LOG_LENGTH: 707b8e80941Smrg *params = (shProg->data->InfoLog && shProg->data->InfoLog[0] != '\0') ? 708b8e80941Smrg strlen(shProg->data->InfoLog) + 1 : 0; 709848b8605Smrg return; 710848b8605Smrg case GL_ATTACHED_SHADERS: 711848b8605Smrg *params = shProg->NumShaders; 712848b8605Smrg return; 713848b8605Smrg case GL_ACTIVE_ATTRIBUTES: 714848b8605Smrg *params = _mesa_count_active_attribs(shProg); 715848b8605Smrg return; 716848b8605Smrg case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: 717848b8605Smrg *params = _mesa_longest_attribute_name_length(shProg); 718848b8605Smrg return; 719b8e80941Smrg case GL_ACTIVE_UNIFORMS: { 720b8e80941Smrg unsigned i; 721b8e80941Smrg const unsigned num_uniforms = 722b8e80941Smrg shProg->data->NumUniformStorage - shProg->data->NumHiddenUniforms; 723b8e80941Smrg for (*params = 0, i = 0; i < num_uniforms; i++) { 724b8e80941Smrg if (!shProg->data->UniformStorage[i].is_shader_storage) 725b8e80941Smrg (*params)++; 726b8e80941Smrg } 727848b8605Smrg return; 728b8e80941Smrg } 729848b8605Smrg case GL_ACTIVE_UNIFORM_MAX_LENGTH: { 730848b8605Smrg unsigned i; 731848b8605Smrg GLint max_len = 0; 732b8e80941Smrg const unsigned num_uniforms = 733b8e80941Smrg shProg->data->NumUniformStorage - shProg->data->NumHiddenUniforms; 734b8e80941Smrg 735b8e80941Smrg for (i = 0; i < num_uniforms; i++) { 736b8e80941Smrg if (shProg->data->UniformStorage[i].is_shader_storage) 737b8e80941Smrg continue; 738848b8605Smrg 739848b8605Smrg /* Add one for the terminating NUL character for a non-array, and 740848b8605Smrg * 4 for the "[0]" and the NUL for an array. 741848b8605Smrg */ 742b8e80941Smrg const GLint len = strlen(shProg->data->UniformStorage[i].name) + 1 + 743b8e80941Smrg ((shProg->data->UniformStorage[i].array_elements != 0) ? 3 : 0); 744848b8605Smrg 745848b8605Smrg if (len > max_len) 746848b8605Smrg max_len = len; 747848b8605Smrg } 748848b8605Smrg 749848b8605Smrg *params = max_len; 750848b8605Smrg return; 751848b8605Smrg } 752848b8605Smrg case GL_TRANSFORM_FEEDBACK_VARYINGS: 753848b8605Smrg if (!has_xfb) 754848b8605Smrg break; 755848b8605Smrg *params = shProg->TransformFeedback.NumVarying; 756848b8605Smrg return; 757848b8605Smrg case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: { 758848b8605Smrg unsigned i; 759848b8605Smrg GLint max_len = 0; 760848b8605Smrg if (!has_xfb) 761848b8605Smrg break; 762848b8605Smrg 763848b8605Smrg for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) { 764848b8605Smrg /* Add one for the terminating NUL character. 765848b8605Smrg */ 766b8e80941Smrg const GLint len = 767b8e80941Smrg strlen(shProg->TransformFeedback.VaryingNames[i]) + 1; 768848b8605Smrg 769848b8605Smrg if (len > max_len) 770848b8605Smrg max_len = len; 771848b8605Smrg } 772848b8605Smrg 773848b8605Smrg *params = max_len; 774848b8605Smrg return; 775848b8605Smrg } 776848b8605Smrg case GL_TRANSFORM_FEEDBACK_BUFFER_MODE: 777848b8605Smrg if (!has_xfb) 778848b8605Smrg break; 779848b8605Smrg *params = shProg->TransformFeedback.BufferMode; 780848b8605Smrg return; 781848b8605Smrg case GL_GEOMETRY_VERTICES_OUT: 782b8e80941Smrg if (!has_gs) 783848b8605Smrg break; 784b8e80941Smrg if (check_gs_query(ctx, shProg)) { 785b8e80941Smrg *params = shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]-> 786b8e80941Smrg Program->info.gs.vertices_out; 787b8e80941Smrg } 788848b8605Smrg return; 789848b8605Smrg case GL_GEOMETRY_SHADER_INVOCATIONS: 790b8e80941Smrg if (!has_gs || !ctx->Extensions.ARB_gpu_shader5) 791848b8605Smrg break; 792b8e80941Smrg if (check_gs_query(ctx, shProg)) { 793b8e80941Smrg *params = shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]-> 794b8e80941Smrg Program->info.gs.invocations; 795b8e80941Smrg } 796848b8605Smrg return; 797848b8605Smrg case GL_GEOMETRY_INPUT_TYPE: 798b8e80941Smrg if (!has_gs) 799848b8605Smrg break; 800b8e80941Smrg if (check_gs_query(ctx, shProg)) { 801b8e80941Smrg *params = shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]-> 802b8e80941Smrg Program->info.gs.input_primitive; 803b8e80941Smrg } 804848b8605Smrg return; 805848b8605Smrg case GL_GEOMETRY_OUTPUT_TYPE: 806b8e80941Smrg if (!has_gs) 807848b8605Smrg break; 808b8e80941Smrg if (check_gs_query(ctx, shProg)) { 809b8e80941Smrg *params = shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]-> 810b8e80941Smrg Program->info.gs.output_primitive; 811b8e80941Smrg } 812848b8605Smrg return; 813848b8605Smrg case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: { 814848b8605Smrg unsigned i; 815848b8605Smrg GLint max_len = 0; 816848b8605Smrg 817848b8605Smrg if (!has_ubo) 818848b8605Smrg break; 819848b8605Smrg 820b8e80941Smrg for (i = 0; i < shProg->data->NumUniformBlocks; i++) { 821848b8605Smrg /* Add one for the terminating NUL character. 822848b8605Smrg */ 823b8e80941Smrg const GLint len = strlen(shProg->data->UniformBlocks[i].Name) + 1; 824848b8605Smrg 825848b8605Smrg if (len > max_len) 826848b8605Smrg max_len = len; 827848b8605Smrg } 828848b8605Smrg 829848b8605Smrg *params = max_len; 830848b8605Smrg return; 831848b8605Smrg } 832848b8605Smrg case GL_ACTIVE_UNIFORM_BLOCKS: 833848b8605Smrg if (!has_ubo) 834848b8605Smrg break; 835848b8605Smrg 836b8e80941Smrg *params = shProg->data->NumUniformBlocks; 837848b8605Smrg return; 838848b8605Smrg case GL_PROGRAM_BINARY_RETRIEVABLE_HINT: 839848b8605Smrg /* This enum isn't part of the OES extension for OpenGL ES 2.0. It is 840848b8605Smrg * only available with desktop OpenGL 3.0+ with the 841848b8605Smrg * GL_ARB_get_program_binary extension or OpenGL ES 3.0. 842848b8605Smrg * 843848b8605Smrg * On desktop, we ignore the 3.0+ requirement because it is silly. 844848b8605Smrg */ 845848b8605Smrg if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 846848b8605Smrg break; 847848b8605Smrg 848848b8605Smrg *params = shProg->BinaryRetreivableHint; 849848b8605Smrg return; 850848b8605Smrg case GL_PROGRAM_BINARY_LENGTH: 851b8e80941Smrg if (ctx->Const.NumProgramBinaryFormats == 0 || !shProg->data->LinkStatus) { 852b8e80941Smrg *params = 0; 853b8e80941Smrg } else { 854b8e80941Smrg _mesa_get_program_binary_length(ctx, shProg, params); 855b8e80941Smrg } 856848b8605Smrg return; 857848b8605Smrg case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS: 858848b8605Smrg if (!ctx->Extensions.ARB_shader_atomic_counters) 859848b8605Smrg break; 860848b8605Smrg 861b8e80941Smrg *params = shProg->data->NumAtomicBuffers; 862848b8605Smrg return; 863848b8605Smrg case GL_COMPUTE_WORK_GROUP_SIZE: { 864848b8605Smrg int i; 865b8e80941Smrg if (!_mesa_has_compute_shaders(ctx)) 866848b8605Smrg break; 867b8e80941Smrg if (!shProg->data->LinkStatus) { 868848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramiv(program not " 869848b8605Smrg "linked)"); 870848b8605Smrg return; 871848b8605Smrg } 872848b8605Smrg if (shProg->_LinkedShaders[MESA_SHADER_COMPUTE] == NULL) { 873848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramiv(no compute " 874848b8605Smrg "shaders)"); 875848b8605Smrg return; 876848b8605Smrg } 877848b8605Smrg for (i = 0; i < 3; i++) 878b8e80941Smrg params[i] = shProg->_LinkedShaders[MESA_SHADER_COMPUTE]-> 879b8e80941Smrg Program->info.cs.local_size[i]; 880848b8605Smrg return; 881848b8605Smrg } 882848b8605Smrg case GL_PROGRAM_SEPARABLE: 883b8e80941Smrg /* If the program has not been linked, return initial value 0. */ 884b8e80941Smrg *params = (shProg->data->LinkStatus == LINKING_FAILURE) ? 0 : shProg->SeparateShader; 885b8e80941Smrg return; 886b8e80941Smrg 887b8e80941Smrg /* ARB_tessellation_shader */ 888b8e80941Smrg case GL_TESS_CONTROL_OUTPUT_VERTICES: 889b8e80941Smrg if (!has_tess) 890b8e80941Smrg break; 891b8e80941Smrg if (check_tcs_query(ctx, shProg)) { 892b8e80941Smrg *params = shProg->_LinkedShaders[MESA_SHADER_TESS_CTRL]-> 893b8e80941Smrg Program->info.tess.tcs_vertices_out; 894b8e80941Smrg } 895b8e80941Smrg return; 896b8e80941Smrg case GL_TESS_GEN_MODE: 897b8e80941Smrg if (!has_tess) 898b8e80941Smrg break; 899b8e80941Smrg if (check_tes_query(ctx, shProg)) { 900b8e80941Smrg *params = shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]-> 901b8e80941Smrg Program->info.tess.primitive_mode; 902b8e80941Smrg } 903b8e80941Smrg return; 904b8e80941Smrg case GL_TESS_GEN_SPACING: 905b8e80941Smrg if (!has_tess) 906b8e80941Smrg break; 907b8e80941Smrg if (check_tes_query(ctx, shProg)) { 908b8e80941Smrg const struct gl_linked_shader *tes = 909b8e80941Smrg shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]; 910b8e80941Smrg switch (tes->Program->info.tess.spacing) { 911b8e80941Smrg case TESS_SPACING_EQUAL: 912b8e80941Smrg *params = GL_EQUAL; 913b8e80941Smrg break; 914b8e80941Smrg case TESS_SPACING_FRACTIONAL_ODD: 915b8e80941Smrg *params = GL_FRACTIONAL_ODD; 916b8e80941Smrg break; 917b8e80941Smrg case TESS_SPACING_FRACTIONAL_EVEN: 918b8e80941Smrg *params = GL_FRACTIONAL_EVEN; 919b8e80941Smrg break; 920b8e80941Smrg case TESS_SPACING_UNSPECIFIED: 921b8e80941Smrg *params = 0; 922b8e80941Smrg break; 923b8e80941Smrg } 924b8e80941Smrg } 925b8e80941Smrg return; 926b8e80941Smrg case GL_TESS_GEN_VERTEX_ORDER: 927b8e80941Smrg if (!has_tess) 928b8e80941Smrg break; 929b8e80941Smrg if (check_tes_query(ctx, shProg)) { 930b8e80941Smrg *params = shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]-> 931b8e80941Smrg Program->info.tess.ccw ? GL_CCW : GL_CW; 932b8e80941Smrg } 933b8e80941Smrg return; 934b8e80941Smrg case GL_TESS_GEN_POINT_MODE: 935b8e80941Smrg if (!has_tess) 936b8e80941Smrg break; 937b8e80941Smrg if (check_tes_query(ctx, shProg)) { 938b8e80941Smrg *params = shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]-> 939b8e80941Smrg Program->info.tess.point_mode ? GL_TRUE : GL_FALSE; 940b8e80941Smrg } 941848b8605Smrg return; 942848b8605Smrg default: 943848b8605Smrg break; 944848b8605Smrg } 945848b8605Smrg 946848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname=%s)", 947b8e80941Smrg _mesa_enum_to_string(pname)); 948848b8605Smrg} 949848b8605Smrg 950848b8605Smrg 951848b8605Smrg/** 952848b8605Smrg * glGetShaderiv() - get GLSL shader state 953848b8605Smrg */ 954848b8605Smrgstatic void 955848b8605Smrgget_shaderiv(struct gl_context *ctx, GLuint name, GLenum pname, GLint *params) 956848b8605Smrg{ 957848b8605Smrg struct gl_shader *shader = 958848b8605Smrg _mesa_lookup_shader_err(ctx, name, "glGetShaderiv"); 959848b8605Smrg 960848b8605Smrg if (!shader) { 961848b8605Smrg return; 962848b8605Smrg } 963848b8605Smrg 964848b8605Smrg switch (pname) { 965848b8605Smrg case GL_SHADER_TYPE: 966848b8605Smrg *params = shader->Type; 967848b8605Smrg break; 968848b8605Smrg case GL_DELETE_STATUS: 969848b8605Smrg *params = shader->DeletePending; 970848b8605Smrg break; 971b8e80941Smrg case GL_COMPLETION_STATUS_ARB: 972b8e80941Smrg /* _mesa_glsl_compile_shader is not offloaded to other threads. */ 973b8e80941Smrg *params = GL_TRUE; 974b8e80941Smrg return; 975848b8605Smrg case GL_COMPILE_STATUS: 976b8e80941Smrg *params = shader->CompileStatus ? GL_TRUE : GL_FALSE; 977848b8605Smrg break; 978848b8605Smrg case GL_INFO_LOG_LENGTH: 979b8e80941Smrg *params = (shader->InfoLog && shader->InfoLog[0] != '\0') ? 980b8e80941Smrg strlen(shader->InfoLog) + 1 : 0; 981848b8605Smrg break; 982848b8605Smrg case GL_SHADER_SOURCE_LENGTH: 983848b8605Smrg *params = shader->Source ? strlen((char *) shader->Source) + 1 : 0; 984848b8605Smrg break; 985b8e80941Smrg case GL_SPIR_V_BINARY_ARB: 986b8e80941Smrg *params = (shader->spirv_data != NULL); 987b8e80941Smrg break; 988848b8605Smrg default: 989848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)"); 990848b8605Smrg return; 991848b8605Smrg } 992848b8605Smrg} 993848b8605Smrg 994848b8605Smrg 995848b8605Smrgstatic void 996848b8605Smrgget_program_info_log(struct gl_context *ctx, GLuint program, GLsizei bufSize, 997848b8605Smrg GLsizei *length, GLchar *infoLog) 998848b8605Smrg{ 999b8e80941Smrg struct gl_shader_program *shProg; 1000b8e80941Smrg 1001b8e80941Smrg /* Section 2.5 GL Errors (page 18) of the OpenGL ES 3.0.4 spec and 1002b8e80941Smrg * section 2.3.1 (Errors) of the OpenGL 4.5 spec say: 1003b8e80941Smrg * 1004b8e80941Smrg * "If a negative number is provided where an argument of type sizei or 1005b8e80941Smrg * sizeiptr is specified, an INVALID_VALUE error is generated." 1006b8e80941Smrg */ 1007b8e80941Smrg if (bufSize < 0) { 1008b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramInfoLog(bufSize < 0)"); 1009b8e80941Smrg return; 1010b8e80941Smrg } 1011b8e80941Smrg 1012b8e80941Smrg shProg = _mesa_lookup_shader_program_err(ctx, program, 1013b8e80941Smrg "glGetProgramInfoLog(program)"); 1014848b8605Smrg if (!shProg) { 1015848b8605Smrg return; 1016848b8605Smrg } 1017b8e80941Smrg 1018b8e80941Smrg _mesa_copy_string(infoLog, bufSize, length, shProg->data->InfoLog); 1019848b8605Smrg} 1020848b8605Smrg 1021848b8605Smrg 1022848b8605Smrgstatic void 1023848b8605Smrgget_shader_info_log(struct gl_context *ctx, GLuint shader, GLsizei bufSize, 1024848b8605Smrg GLsizei *length, GLchar *infoLog) 1025848b8605Smrg{ 1026b8e80941Smrg struct gl_shader *sh; 1027b8e80941Smrg 1028b8e80941Smrg /* Section 2.5 GL Errors (page 18) of the OpenGL ES 3.0.4 spec and 1029b8e80941Smrg * section 2.3.1 (Errors) of the OpenGL 4.5 spec say: 1030b8e80941Smrg * 1031b8e80941Smrg * "If a negative number is provided where an argument of type sizei or 1032b8e80941Smrg * sizeiptr is specified, an INVALID_VALUE error is generated." 1033b8e80941Smrg */ 1034b8e80941Smrg if (bufSize < 0) { 1035b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderInfoLog(bufSize < 0)"); 1036b8e80941Smrg return; 1037b8e80941Smrg } 1038b8e80941Smrg 1039b8e80941Smrg sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderInfoLog(shader)"); 1040848b8605Smrg if (!sh) { 1041848b8605Smrg return; 1042848b8605Smrg } 1043b8e80941Smrg 1044848b8605Smrg _mesa_copy_string(infoLog, bufSize, length, sh->InfoLog); 1045848b8605Smrg} 1046848b8605Smrg 1047848b8605Smrg 1048848b8605Smrg/** 1049848b8605Smrg * Return shader source code. 1050848b8605Smrg */ 1051848b8605Smrgstatic void 1052848b8605Smrgget_shader_source(struct gl_context *ctx, GLuint shader, GLsizei maxLength, 1053848b8605Smrg GLsizei *length, GLchar *sourceOut) 1054848b8605Smrg{ 1055848b8605Smrg struct gl_shader *sh; 1056b8e80941Smrg 1057b8e80941Smrg if (maxLength < 0) { 1058b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderSource(bufSize < 0)"); 1059b8e80941Smrg return; 1060b8e80941Smrg } 1061b8e80941Smrg 1062848b8605Smrg sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderSource"); 1063848b8605Smrg if (!sh) { 1064848b8605Smrg return; 1065848b8605Smrg } 1066848b8605Smrg _mesa_copy_string(sourceOut, maxLength, length, sh->Source); 1067848b8605Smrg} 1068848b8605Smrg 1069848b8605Smrg 1070848b8605Smrg/** 1071848b8605Smrg * Set/replace shader source code. A helper function used by 1072848b8605Smrg * glShaderSource[ARB]. 1073848b8605Smrg */ 1074848b8605Smrgstatic void 1075b8e80941Smrgset_shader_source(struct gl_shader *sh, const GLchar *source) 1076848b8605Smrg{ 1077b8e80941Smrg assert(sh); 1078848b8605Smrg 1079b8e80941Smrg /* The GL_ARB_gl_spirv spec adds the following to the end of the description 1080b8e80941Smrg * of ShaderSource: 1081b8e80941Smrg * 1082b8e80941Smrg * "If <shader> was previously associated with a SPIR-V module (via the 1083b8e80941Smrg * ShaderBinary command), that association is broken. Upon successful 1084b8e80941Smrg * completion of this command the SPIR_V_BINARY_ARB state of <shader> 1085b8e80941Smrg * is set to FALSE." 1086b8e80941Smrg */ 1087b8e80941Smrg _mesa_shader_spirv_data_reference(&sh->spirv_data, NULL); 1088b8e80941Smrg 1089b8e80941Smrg if (sh->CompileStatus == COMPILE_SKIPPED && !sh->FallbackSource) { 1090b8e80941Smrg /* If shader was previously compiled back-up the source in case of cache 1091b8e80941Smrg * fallback. 1092b8e80941Smrg */ 1093b8e80941Smrg sh->FallbackSource = sh->Source; 1094b8e80941Smrg sh->Source = source; 1095b8e80941Smrg } else { 1096b8e80941Smrg /* free old shader source string and install new one */ 1097b8e80941Smrg free((void *)sh->Source); 1098b8e80941Smrg sh->Source = source; 1099b8e80941Smrg } 1100848b8605Smrg 1101848b8605Smrg#ifdef DEBUG 1102b8e80941Smrg sh->SourceChecksum = util_hash_crc32(sh->Source, strlen(sh->Source)); 1103848b8605Smrg#endif 1104848b8605Smrg} 1105848b8605Smrg 1106848b8605Smrg 1107848b8605Smrg/** 1108848b8605Smrg * Compile a shader. 1109848b8605Smrg */ 1110b8e80941Smrgvoid 1111b8e80941Smrg_mesa_compile_shader(struct gl_context *ctx, struct gl_shader *sh) 1112848b8605Smrg{ 1113848b8605Smrg if (!sh) 1114848b8605Smrg return; 1115848b8605Smrg 1116b8e80941Smrg /* The GL_ARB_gl_spirv spec says: 1117b8e80941Smrg * 1118b8e80941Smrg * "Add a new error for the CompileShader command: 1119b8e80941Smrg * 1120b8e80941Smrg * An INVALID_OPERATION error is generated if the SPIR_V_BINARY_ARB 1121b8e80941Smrg * state of <shader> is TRUE." 1122b8e80941Smrg */ 1123b8e80941Smrg if (sh->spirv_data) { 1124b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "glCompileShader(SPIR-V)"); 1125b8e80941Smrg return; 1126b8e80941Smrg } 1127848b8605Smrg 1128848b8605Smrg if (!sh->Source) { 1129848b8605Smrg /* If the user called glCompileShader without first calling 1130848b8605Smrg * glShaderSource, we should fail to compile, but not raise a GL_ERROR. 1131848b8605Smrg */ 1132b8e80941Smrg sh->CompileStatus = COMPILE_FAILURE; 1133848b8605Smrg } else { 1134848b8605Smrg if (ctx->_Shader->Flags & GLSL_DUMP) { 1135b8e80941Smrg _mesa_log("GLSL source for %s shader %d:\n", 1136848b8605Smrg _mesa_shader_stage_to_string(sh->Stage), sh->Name); 1137b8e80941Smrg _mesa_log("%s\n", sh->Source); 1138848b8605Smrg } 1139848b8605Smrg 1140848b8605Smrg /* this call will set the shader->CompileStatus field to indicate if 1141848b8605Smrg * compilation was successful. 1142848b8605Smrg */ 1143b8e80941Smrg _mesa_glsl_compile_shader(ctx, sh, false, false, false); 1144848b8605Smrg 1145848b8605Smrg if (ctx->_Shader->Flags & GLSL_LOG) { 1146848b8605Smrg _mesa_write_shader_to_file(sh); 1147848b8605Smrg } 1148848b8605Smrg 1149848b8605Smrg if (ctx->_Shader->Flags & GLSL_DUMP) { 1150848b8605Smrg if (sh->CompileStatus) { 1151b8e80941Smrg if (sh->ir) { 1152b8e80941Smrg _mesa_log("GLSL IR for shader %d:\n", sh->Name); 1153b8e80941Smrg _mesa_print_ir(_mesa_get_log_file(), sh->ir, NULL); 1154b8e80941Smrg } else { 1155b8e80941Smrg _mesa_log("No GLSL IR for shader %d (shader may be from " 1156b8e80941Smrg "cache)\n", sh->Name); 1157b8e80941Smrg } 1158b8e80941Smrg _mesa_log("\n\n"); 1159848b8605Smrg } else { 1160b8e80941Smrg _mesa_log("GLSL shader %d failed to compile.\n", sh->Name); 1161848b8605Smrg } 1162848b8605Smrg if (sh->InfoLog && sh->InfoLog[0] != 0) { 1163b8e80941Smrg _mesa_log("GLSL shader %d info log:\n", sh->Name); 1164b8e80941Smrg _mesa_log("%s\n", sh->InfoLog); 1165848b8605Smrg } 1166848b8605Smrg } 1167848b8605Smrg } 1168848b8605Smrg 1169848b8605Smrg if (!sh->CompileStatus) { 1170848b8605Smrg if (ctx->_Shader->Flags & GLSL_DUMP_ON_ERROR) { 1171b8e80941Smrg _mesa_log("GLSL source for %s shader %d:\n", 1172848b8605Smrg _mesa_shader_stage_to_string(sh->Stage), sh->Name); 1173b8e80941Smrg _mesa_log("%s\n", sh->Source); 1174b8e80941Smrg _mesa_log("Info Log:\n%s\n", sh->InfoLog); 1175848b8605Smrg } 1176848b8605Smrg 1177848b8605Smrg if (ctx->_Shader->Flags & GLSL_REPORT_ERRORS) { 1178848b8605Smrg _mesa_debug(ctx, "Error compiling shader %u:\n%s\n", 1179848b8605Smrg sh->Name, sh->InfoLog); 1180848b8605Smrg } 1181848b8605Smrg } 1182848b8605Smrg} 1183848b8605Smrg 1184848b8605Smrg 1185848b8605Smrg/** 1186848b8605Smrg * Link a program's shaders. 1187848b8605Smrg */ 1188b8e80941Smrgstatic ALWAYS_INLINE void 1189b8e80941Smrglink_program(struct gl_context *ctx, struct gl_shader_program *shProg, 1190b8e80941Smrg bool no_error) 1191848b8605Smrg{ 1192848b8605Smrg if (!shProg) 1193848b8605Smrg return; 1194848b8605Smrg 1195b8e80941Smrg if (!no_error) { 1196b8e80941Smrg /* From the ARB_transform_feedback2 specification: 1197b8e80941Smrg * "The error INVALID_OPERATION is generated by LinkProgram if <program> 1198b8e80941Smrg * is the name of a program being used by one or more transform feedback 1199b8e80941Smrg * objects, even if the objects are not currently bound or are paused." 1200b8e80941Smrg */ 1201b8e80941Smrg if (_mesa_transform_feedback_is_using_program(ctx, shProg)) { 1202b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 1203b8e80941Smrg "glLinkProgram(transform feedback is using the program)"); 1204b8e80941Smrg return; 1205b8e80941Smrg } 1206848b8605Smrg } 1207848b8605Smrg 1208b8e80941Smrg unsigned programs_in_use = 0; 1209b8e80941Smrg if (ctx->_Shader) 1210b8e80941Smrg for (unsigned stage = 0; stage < MESA_SHADER_STAGES; stage++) { 1211b8e80941Smrg if (ctx->_Shader->CurrentProgram[stage] && 1212b8e80941Smrg ctx->_Shader->CurrentProgram[stage]->Id == shProg->Name) { 1213b8e80941Smrg programs_in_use |= 1 << stage; 1214b8e80941Smrg } 1215b8e80941Smrg } 1216848b8605Smrg 1217b8e80941Smrg FLUSH_VERTICES(ctx, 0); 1218848b8605Smrg _mesa_glsl_link_shader(ctx, shProg); 1219848b8605Smrg 1220b8e80941Smrg /* From section 7.3 (Program Objects) of the OpenGL 4.5 spec: 1221b8e80941Smrg * 1222b8e80941Smrg * "If LinkProgram or ProgramBinary successfully re-links a program 1223b8e80941Smrg * object that is active for any shader stage, then the newly generated 1224b8e80941Smrg * executable code will be installed as part of the current rendering 1225b8e80941Smrg * state for all shader stages where the program is active. 1226b8e80941Smrg * Additionally, the newly generated executable code is made part of 1227b8e80941Smrg * the state of any program pipeline for all stages where the program 1228b8e80941Smrg * is attached." 1229b8e80941Smrg */ 1230b8e80941Smrg if (shProg->data->LinkStatus && programs_in_use) { 1231b8e80941Smrg while (programs_in_use) { 1232b8e80941Smrg const int stage = u_bit_scan(&programs_in_use); 1233b8e80941Smrg 1234b8e80941Smrg struct gl_program *prog = NULL; 1235b8e80941Smrg if (shProg->_LinkedShaders[stage]) 1236b8e80941Smrg prog = shProg->_LinkedShaders[stage]->Program; 1237b8e80941Smrg 1238b8e80941Smrg _mesa_use_program(ctx, stage, shProg, prog, ctx->_Shader); 1239b8e80941Smrg } 1240b8e80941Smrg } 1241b8e80941Smrg 1242b8e80941Smrg /* Capture .shader_test files. */ 1243b8e80941Smrg const char *capture_path = _mesa_get_shader_capture_path(); 1244b8e80941Smrg if (shProg->Name != 0 && shProg->Name != ~0 && capture_path != NULL) { 1245b8e80941Smrg /* Find an unused filename. */ 1246b8e80941Smrg char *filename = NULL; 1247b8e80941Smrg for (unsigned i = 0;; i++) { 1248b8e80941Smrg if (i) { 1249b8e80941Smrg filename = ralloc_asprintf(NULL, "%s/%u-%u.shader_test", 1250b8e80941Smrg capture_path, shProg->Name, i); 1251b8e80941Smrg } else { 1252b8e80941Smrg filename = ralloc_asprintf(NULL, "%s/%u.shader_test", 1253b8e80941Smrg capture_path, shProg->Name); 1254b8e80941Smrg } 1255b8e80941Smrg FILE *file = fopen(filename, "r"); 1256b8e80941Smrg if (!file) 1257b8e80941Smrg break; 1258b8e80941Smrg fclose(file); 1259b8e80941Smrg ralloc_free(filename); 1260b8e80941Smrg } 1261b8e80941Smrg 1262b8e80941Smrg FILE *file = fopen(filename, "w"); 1263b8e80941Smrg if (file) { 1264b8e80941Smrg fprintf(file, "[require]\nGLSL%s >= %u.%02u\n", 1265b8e80941Smrg shProg->IsES ? " ES" : "", 1266b8e80941Smrg shProg->data->Version / 100, shProg->data->Version % 100); 1267b8e80941Smrg if (shProg->SeparateShader) 1268b8e80941Smrg fprintf(file, "GL_ARB_separate_shader_objects\nSSO ENABLED\n"); 1269b8e80941Smrg fprintf(file, "\n"); 1270b8e80941Smrg 1271b8e80941Smrg for (unsigned i = 0; i < shProg->NumShaders; i++) { 1272b8e80941Smrg fprintf(file, "[%s shader]\n%s\n", 1273b8e80941Smrg _mesa_shader_stage_to_string(shProg->Shaders[i]->Stage), 1274b8e80941Smrg shProg->Shaders[i]->Source); 1275b8e80941Smrg } 1276b8e80941Smrg fclose(file); 1277b8e80941Smrg } else { 1278b8e80941Smrg _mesa_warning(ctx, "Failed to open %s", filename); 1279b8e80941Smrg } 1280b8e80941Smrg 1281b8e80941Smrg ralloc_free(filename); 1282b8e80941Smrg } 1283b8e80941Smrg 1284b8e80941Smrg if (shProg->data->LinkStatus == LINKING_FAILURE && 1285848b8605Smrg (ctx->_Shader->Flags & GLSL_REPORT_ERRORS)) { 1286848b8605Smrg _mesa_debug(ctx, "Error linking program %u:\n%s\n", 1287b8e80941Smrg shProg->Name, shProg->data->InfoLog); 1288848b8605Smrg } 1289848b8605Smrg 1290b8e80941Smrg _mesa_update_vertex_processing_mode(ctx); 1291b8e80941Smrg 1292848b8605Smrg /* debug code */ 1293848b8605Smrg if (0) { 1294848b8605Smrg GLuint i; 1295848b8605Smrg 1296848b8605Smrg printf("Link %u shaders in program %u: %s\n", 1297848b8605Smrg shProg->NumShaders, shProg->Name, 1298b8e80941Smrg shProg->data->LinkStatus ? "Success" : "Failed"); 1299848b8605Smrg 1300848b8605Smrg for (i = 0; i < shProg->NumShaders; i++) { 1301b8e80941Smrg printf(" shader %u, stage %u\n", 1302848b8605Smrg shProg->Shaders[i]->Name, 1303b8e80941Smrg shProg->Shaders[i]->Stage); 1304848b8605Smrg } 1305848b8605Smrg } 1306848b8605Smrg} 1307848b8605Smrg 1308848b8605Smrg 1309b8e80941Smrgstatic void 1310b8e80941Smrglink_program_error(struct gl_context *ctx, struct gl_shader_program *shProg) 1311b8e80941Smrg{ 1312b8e80941Smrg link_program(ctx, shProg, false); 1313b8e80941Smrg} 1314b8e80941Smrg 1315b8e80941Smrg 1316b8e80941Smrgstatic void 1317b8e80941Smrglink_program_no_error(struct gl_context *ctx, struct gl_shader_program *shProg) 1318b8e80941Smrg{ 1319b8e80941Smrg link_program(ctx, shProg, true); 1320b8e80941Smrg} 1321b8e80941Smrg 1322b8e80941Smrg 1323b8e80941Smrgvoid 1324b8e80941Smrg_mesa_link_program(struct gl_context *ctx, struct gl_shader_program *shProg) 1325b8e80941Smrg{ 1326b8e80941Smrg link_program_error(ctx, shProg); 1327b8e80941Smrg} 1328b8e80941Smrg 1329b8e80941Smrg 1330848b8605Smrg/** 1331848b8605Smrg * Print basic shader info (for debug). 1332848b8605Smrg */ 1333848b8605Smrgstatic void 1334848b8605Smrgprint_shader_info(const struct gl_shader_program *shProg) 1335848b8605Smrg{ 1336848b8605Smrg GLuint i; 1337848b8605Smrg 1338848b8605Smrg printf("Mesa: glUseProgram(%u)\n", shProg->Name); 1339848b8605Smrg for (i = 0; i < shProg->NumShaders; i++) { 1340b8e80941Smrg#ifdef DEBUG 1341848b8605Smrg printf(" %s shader %u, checksum %u\n", 1342848b8605Smrg _mesa_shader_stage_to_string(shProg->Shaders[i]->Stage), 1343848b8605Smrg shProg->Shaders[i]->Name, 1344848b8605Smrg shProg->Shaders[i]->SourceChecksum); 1345b8e80941Smrg#else 1346b8e80941Smrg printf(" %s shader %u\n", 1347b8e80941Smrg _mesa_shader_stage_to_string(shProg->Shaders[i]->Stage), 1348b8e80941Smrg shProg->Shaders[i]->Name); 1349b8e80941Smrg#endif 1350848b8605Smrg } 1351848b8605Smrg if (shProg->_LinkedShaders[MESA_SHADER_VERTEX]) 1352848b8605Smrg printf(" vert prog %u\n", 1353848b8605Smrg shProg->_LinkedShaders[MESA_SHADER_VERTEX]->Program->Id); 1354848b8605Smrg if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]) 1355848b8605Smrg printf(" frag prog %u\n", 1356848b8605Smrg shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program->Id); 1357848b8605Smrg if (shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]) 1358848b8605Smrg printf(" geom prog %u\n", 1359848b8605Smrg shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program->Id); 1360b8e80941Smrg if (shProg->_LinkedShaders[MESA_SHADER_TESS_CTRL]) 1361b8e80941Smrg printf(" tesc prog %u\n", 1362b8e80941Smrg shProg->_LinkedShaders[MESA_SHADER_TESS_CTRL]->Program->Id); 1363b8e80941Smrg if (shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]) 1364b8e80941Smrg printf(" tese prog %u\n", 1365b8e80941Smrg shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]->Program->Id); 1366848b8605Smrg} 1367848b8605Smrg 1368848b8605Smrg 1369848b8605Smrg/** 1370848b8605Smrg * Use the named shader program for subsequent glUniform calls 1371848b8605Smrg */ 1372848b8605Smrgvoid 1373848b8605Smrg_mesa_active_program(struct gl_context *ctx, struct gl_shader_program *shProg, 1374848b8605Smrg const char *caller) 1375848b8605Smrg{ 1376b8e80941Smrg if ((shProg != NULL) && !shProg->data->LinkStatus) { 1377848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 1378848b8605Smrg "%s(program %u not linked)", caller, shProg->Name); 1379848b8605Smrg return; 1380848b8605Smrg } 1381848b8605Smrg 1382848b8605Smrg if (ctx->Shader.ActiveProgram != shProg) { 1383848b8605Smrg _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, shProg); 1384848b8605Smrg } 1385848b8605Smrg} 1386848b8605Smrg 1387b8e80941Smrg 1388848b8605Smrg/** 1389b8e80941Smrg * Use the named shader program for subsequent rendering. 1390848b8605Smrg */ 1391b8e80941Smrgvoid 1392b8e80941Smrg_mesa_use_shader_program(struct gl_context *ctx, 1393b8e80941Smrg struct gl_shader_program *shProg) 1394848b8605Smrg{ 1395b8e80941Smrg for (int i = 0; i < MESA_SHADER_STAGES; i++) { 1396b8e80941Smrg struct gl_program *new_prog = NULL; 1397b8e80941Smrg if (shProg && shProg->_LinkedShaders[i]) 1398b8e80941Smrg new_prog = shProg->_LinkedShaders[i]->Program; 1399b8e80941Smrg _mesa_use_program(ctx, i, shProg, new_prog, &ctx->Shader); 1400b8e80941Smrg } 1401b8e80941Smrg _mesa_active_program(ctx, shProg, "glUseProgram"); 1402b8e80941Smrg} 1403848b8605Smrg 1404848b8605Smrg 1405848b8605Smrg/** 1406848b8605Smrg * Do validation of the given shader program. 1407848b8605Smrg * \param errMsg returns error message if validation fails. 1408848b8605Smrg * \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg) 1409848b8605Smrg */ 1410848b8605Smrgstatic GLboolean 1411848b8605Smrgvalidate_shader_program(const struct gl_shader_program *shProg, 1412848b8605Smrg char *errMsg) 1413848b8605Smrg{ 1414b8e80941Smrg if (!shProg->data->LinkStatus) { 1415848b8605Smrg return GL_FALSE; 1416848b8605Smrg } 1417848b8605Smrg 1418848b8605Smrg /* From the GL spec, a program is invalid if any of these are true: 1419848b8605Smrg 1420848b8605Smrg any two active samplers in the current program object are of 1421848b8605Smrg different types, but refer to the same texture image unit, 1422848b8605Smrg 1423848b8605Smrg any active sampler in the current program object refers to a texture 1424848b8605Smrg image unit where fixed-function fragment processing accesses a 1425b8e80941Smrg texture target that does not match the sampler type, or 1426848b8605Smrg 1427848b8605Smrg the sum of the number of active samplers in the program and the 1428848b8605Smrg number of texture image units enabled for fixed-function fragment 1429848b8605Smrg processing exceeds the combined limit on the total number of texture 1430848b8605Smrg image units allowed. 1431848b8605Smrg */ 1432848b8605Smrg 1433848b8605Smrg /* 1434848b8605Smrg * Check: any two active samplers in the current program object are of 1435848b8605Smrg * different types, but refer to the same texture image unit, 1436848b8605Smrg */ 1437848b8605Smrg if (!_mesa_sampler_uniforms_are_valid(shProg, errMsg, 100)) 1438848b8605Smrg return GL_FALSE; 1439848b8605Smrg 1440848b8605Smrg return GL_TRUE; 1441848b8605Smrg} 1442848b8605Smrg 1443848b8605Smrg 1444848b8605Smrg/** 1445848b8605Smrg * Called via glValidateProgram() 1446848b8605Smrg */ 1447848b8605Smrgstatic void 1448848b8605Smrgvalidate_program(struct gl_context *ctx, GLuint program) 1449848b8605Smrg{ 1450848b8605Smrg struct gl_shader_program *shProg; 1451848b8605Smrg char errMsg[100] = ""; 1452848b8605Smrg 1453848b8605Smrg shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram"); 1454848b8605Smrg if (!shProg) { 1455848b8605Smrg return; 1456848b8605Smrg } 1457848b8605Smrg 1458b8e80941Smrg shProg->data->Validated = validate_shader_program(shProg, errMsg); 1459b8e80941Smrg if (!shProg->data->Validated) { 1460848b8605Smrg /* update info log */ 1461b8e80941Smrg if (shProg->data->InfoLog) { 1462b8e80941Smrg ralloc_free(shProg->data->InfoLog); 1463848b8605Smrg } 1464b8e80941Smrg shProg->data->InfoLog = ralloc_strdup(shProg->data, errMsg); 1465848b8605Smrg } 1466848b8605Smrg} 1467848b8605Smrg 1468848b8605Smrg 1469b8e80941Smrgvoid GLAPIENTRY 1470b8e80941Smrg_mesa_AttachObjectARB_no_error(GLhandleARB program, GLhandleARB shader) 1471b8e80941Smrg{ 1472b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 1473b8e80941Smrg attach_shader_no_error(ctx, program, shader); 1474b8e80941Smrg} 1475b8e80941Smrg 1476848b8605Smrg 1477848b8605Smrgvoid GLAPIENTRY 1478848b8605Smrg_mesa_AttachObjectARB(GLhandleARB program, GLhandleARB shader) 1479848b8605Smrg{ 1480848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1481b8e80941Smrg attach_shader_err(ctx, program, shader, "glAttachObjectARB"); 1482b8e80941Smrg} 1483b8e80941Smrg 1484b8e80941Smrg 1485b8e80941Smrgvoid GLAPIENTRY 1486b8e80941Smrg_mesa_AttachShader_no_error(GLuint program, GLuint shader) 1487b8e80941Smrg{ 1488b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 1489b8e80941Smrg attach_shader_no_error(ctx, program, shader); 1490848b8605Smrg} 1491848b8605Smrg 1492848b8605Smrg 1493848b8605Smrgvoid GLAPIENTRY 1494848b8605Smrg_mesa_AttachShader(GLuint program, GLuint shader) 1495848b8605Smrg{ 1496848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1497b8e80941Smrg attach_shader_err(ctx, program, shader, "glAttachShader"); 1498848b8605Smrg} 1499848b8605Smrg 1500848b8605Smrg 1501848b8605Smrgvoid GLAPIENTRY 1502b8e80941Smrg_mesa_CompileShader(GLuint shaderObj) 1503848b8605Smrg{ 1504848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1505848b8605Smrg if (MESA_VERBOSE & VERBOSE_API) 1506848b8605Smrg _mesa_debug(ctx, "glCompileShader %u\n", shaderObj); 1507b8e80941Smrg _mesa_compile_shader(ctx, _mesa_lookup_shader_err(ctx, shaderObj, 1508b8e80941Smrg "glCompileShader")); 1509b8e80941Smrg} 1510b8e80941Smrg 1511b8e80941Smrg 1512b8e80941SmrgGLuint GLAPIENTRY 1513b8e80941Smrg_mesa_CreateShader_no_error(GLenum type) 1514b8e80941Smrg{ 1515b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 1516b8e80941Smrg return create_shader(ctx, type); 1517848b8605Smrg} 1518848b8605Smrg 1519848b8605Smrg 1520848b8605SmrgGLuint GLAPIENTRY 1521848b8605Smrg_mesa_CreateShader(GLenum type) 1522848b8605Smrg{ 1523848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1524b8e80941Smrg 1525848b8605Smrg if (MESA_VERBOSE & VERBOSE_API) 1526b8e80941Smrg _mesa_debug(ctx, "glCreateShader %s\n", _mesa_enum_to_string(type)); 1527b8e80941Smrg 1528b8e80941Smrg return create_shader_err(ctx, type, "glCreateShader"); 1529b8e80941Smrg} 1530b8e80941Smrg 1531b8e80941Smrg 1532b8e80941SmrgGLhandleARB GLAPIENTRY 1533b8e80941Smrg_mesa_CreateShaderObjectARB_no_error(GLenum type) 1534b8e80941Smrg{ 1535b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 1536848b8605Smrg return create_shader(ctx, type); 1537848b8605Smrg} 1538848b8605Smrg 1539848b8605Smrg 1540848b8605SmrgGLhandleARB GLAPIENTRY 1541848b8605Smrg_mesa_CreateShaderObjectARB(GLenum type) 1542848b8605Smrg{ 1543848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1544b8e80941Smrg return create_shader_err(ctx, type, "glCreateShaderObjectARB"); 1545848b8605Smrg} 1546848b8605Smrg 1547848b8605Smrg 1548848b8605SmrgGLuint GLAPIENTRY 1549848b8605Smrg_mesa_CreateProgram(void) 1550848b8605Smrg{ 1551848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1552848b8605Smrg if (MESA_VERBOSE & VERBOSE_API) 1553848b8605Smrg _mesa_debug(ctx, "glCreateProgram\n"); 1554848b8605Smrg return create_shader_program(ctx); 1555848b8605Smrg} 1556848b8605Smrg 1557848b8605Smrg 1558848b8605SmrgGLhandleARB GLAPIENTRY 1559848b8605Smrg_mesa_CreateProgramObjectARB(void) 1560848b8605Smrg{ 1561848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1562848b8605Smrg return create_shader_program(ctx); 1563848b8605Smrg} 1564848b8605Smrg 1565848b8605Smrg 1566848b8605Smrgvoid GLAPIENTRY 1567848b8605Smrg_mesa_DeleteObjectARB(GLhandleARB obj) 1568848b8605Smrg{ 1569848b8605Smrg if (MESA_VERBOSE & VERBOSE_API) { 1570848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1571b8e80941Smrg _mesa_debug(ctx, "glDeleteObjectARB(%lu)\n", (unsigned long)obj); 1572848b8605Smrg } 1573848b8605Smrg 1574848b8605Smrg if (obj) { 1575848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1576848b8605Smrg FLUSH_VERTICES(ctx, 0); 1577848b8605Smrg if (is_program(ctx, obj)) { 1578848b8605Smrg delete_shader_program(ctx, obj); 1579848b8605Smrg } 1580848b8605Smrg else if (is_shader(ctx, obj)) { 1581848b8605Smrg delete_shader(ctx, obj); 1582848b8605Smrg } 1583848b8605Smrg else { 1584848b8605Smrg /* error? */ 1585848b8605Smrg } 1586848b8605Smrg } 1587848b8605Smrg} 1588848b8605Smrg 1589848b8605Smrg 1590848b8605Smrgvoid GLAPIENTRY 1591848b8605Smrg_mesa_DeleteProgram(GLuint name) 1592848b8605Smrg{ 1593848b8605Smrg if (name) { 1594848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1595848b8605Smrg FLUSH_VERTICES(ctx, 0); 1596848b8605Smrg delete_shader_program(ctx, name); 1597848b8605Smrg } 1598848b8605Smrg} 1599848b8605Smrg 1600848b8605Smrg 1601848b8605Smrgvoid GLAPIENTRY 1602848b8605Smrg_mesa_DeleteShader(GLuint name) 1603848b8605Smrg{ 1604848b8605Smrg if (name) { 1605848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1606848b8605Smrg FLUSH_VERTICES(ctx, 0); 1607848b8605Smrg delete_shader(ctx, name); 1608848b8605Smrg } 1609848b8605Smrg} 1610848b8605Smrg 1611848b8605Smrg 1612b8e80941Smrgvoid GLAPIENTRY 1613b8e80941Smrg_mesa_DetachObjectARB_no_error(GLhandleARB program, GLhandleARB shader) 1614b8e80941Smrg{ 1615b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 1616b8e80941Smrg detach_shader_no_error(ctx, program, shader); 1617b8e80941Smrg} 1618b8e80941Smrg 1619b8e80941Smrg 1620848b8605Smrgvoid GLAPIENTRY 1621848b8605Smrg_mesa_DetachObjectARB(GLhandleARB program, GLhandleARB shader) 1622848b8605Smrg{ 1623848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1624b8e80941Smrg detach_shader_error(ctx, program, shader); 1625b8e80941Smrg} 1626b8e80941Smrg 1627b8e80941Smrg 1628b8e80941Smrgvoid GLAPIENTRY 1629b8e80941Smrg_mesa_DetachShader_no_error(GLuint program, GLuint shader) 1630b8e80941Smrg{ 1631b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 1632b8e80941Smrg detach_shader_no_error(ctx, program, shader); 1633848b8605Smrg} 1634848b8605Smrg 1635848b8605Smrg 1636848b8605Smrgvoid GLAPIENTRY 1637848b8605Smrg_mesa_DetachShader(GLuint program, GLuint shader) 1638848b8605Smrg{ 1639848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1640b8e80941Smrg detach_shader_error(ctx, program, shader); 1641848b8605Smrg} 1642848b8605Smrg 1643848b8605Smrg 1644848b8605Smrgvoid GLAPIENTRY 1645848b8605Smrg_mesa_GetAttachedObjectsARB(GLhandleARB container, GLsizei maxCount, 1646848b8605Smrg GLsizei * count, GLhandleARB * obj) 1647848b8605Smrg{ 1648848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1649b8e80941Smrg get_attached_shaders(ctx, (GLuint)container, maxCount, count, NULL, obj); 1650848b8605Smrg} 1651848b8605Smrg 1652848b8605Smrg 1653848b8605Smrgvoid GLAPIENTRY 1654848b8605Smrg_mesa_GetAttachedShaders(GLuint program, GLsizei maxCount, 1655848b8605Smrg GLsizei *count, GLuint *obj) 1656848b8605Smrg{ 1657848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1658b8e80941Smrg get_attached_shaders(ctx, program, maxCount, count, obj, NULL); 1659848b8605Smrg} 1660848b8605Smrg 1661848b8605Smrg 1662848b8605Smrgvoid GLAPIENTRY 1663848b8605Smrg_mesa_GetInfoLogARB(GLhandleARB object, GLsizei maxLength, GLsizei * length, 1664848b8605Smrg GLcharARB * infoLog) 1665848b8605Smrg{ 1666848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1667848b8605Smrg if (is_program(ctx, object)) { 1668848b8605Smrg get_program_info_log(ctx, object, maxLength, length, infoLog); 1669848b8605Smrg } 1670848b8605Smrg else if (is_shader(ctx, object)) { 1671848b8605Smrg get_shader_info_log(ctx, object, maxLength, length, infoLog); 1672848b8605Smrg } 1673848b8605Smrg else { 1674848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInfoLogARB"); 1675848b8605Smrg } 1676848b8605Smrg} 1677848b8605Smrg 1678848b8605Smrg 1679848b8605Smrgvoid GLAPIENTRY 1680848b8605Smrg_mesa_GetObjectParameterivARB(GLhandleARB object, GLenum pname, GLint *params) 1681848b8605Smrg{ 1682848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1683848b8605Smrg /* Implement in terms of GetProgramiv, GetShaderiv */ 1684848b8605Smrg if (is_program(ctx, object)) { 1685848b8605Smrg if (pname == GL_OBJECT_TYPE_ARB) { 1686848b8605Smrg *params = GL_PROGRAM_OBJECT_ARB; 1687848b8605Smrg } 1688848b8605Smrg else { 1689848b8605Smrg get_programiv(ctx, object, pname, params); 1690848b8605Smrg } 1691848b8605Smrg } 1692848b8605Smrg else if (is_shader(ctx, object)) { 1693848b8605Smrg if (pname == GL_OBJECT_TYPE_ARB) { 1694848b8605Smrg *params = GL_SHADER_OBJECT_ARB; 1695848b8605Smrg } 1696848b8605Smrg else { 1697848b8605Smrg get_shaderiv(ctx, object, pname, params); 1698848b8605Smrg } 1699848b8605Smrg } 1700848b8605Smrg else { 1701848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectParameterivARB"); 1702848b8605Smrg } 1703848b8605Smrg} 1704848b8605Smrg 1705848b8605Smrg 1706848b8605Smrgvoid GLAPIENTRY 1707848b8605Smrg_mesa_GetObjectParameterfvARB(GLhandleARB object, GLenum pname, 1708848b8605Smrg GLfloat *params) 1709848b8605Smrg{ 1710b8e80941Smrg GLint iparams[1] = {0}; /* XXX is one element enough? */ 1711848b8605Smrg _mesa_GetObjectParameterivARB(object, pname, iparams); 1712848b8605Smrg params[0] = (GLfloat) iparams[0]; 1713848b8605Smrg} 1714848b8605Smrg 1715848b8605Smrg 1716848b8605Smrgvoid GLAPIENTRY 1717848b8605Smrg_mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params) 1718848b8605Smrg{ 1719848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1720848b8605Smrg get_programiv(ctx, program, pname, params); 1721848b8605Smrg} 1722848b8605Smrg 1723848b8605Smrg 1724848b8605Smrgvoid GLAPIENTRY 1725848b8605Smrg_mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params) 1726848b8605Smrg{ 1727848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1728848b8605Smrg get_shaderiv(ctx, shader, pname, params); 1729848b8605Smrg} 1730848b8605Smrg 1731848b8605Smrg 1732848b8605Smrgvoid GLAPIENTRY 1733848b8605Smrg_mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize, 1734848b8605Smrg GLsizei *length, GLchar *infoLog) 1735848b8605Smrg{ 1736848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1737848b8605Smrg get_program_info_log(ctx, program, bufSize, length, infoLog); 1738848b8605Smrg} 1739848b8605Smrg 1740848b8605Smrg 1741848b8605Smrgvoid GLAPIENTRY 1742848b8605Smrg_mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize, 1743848b8605Smrg GLsizei *length, GLchar *infoLog) 1744848b8605Smrg{ 1745848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1746848b8605Smrg get_shader_info_log(ctx, shader, bufSize, length, infoLog); 1747848b8605Smrg} 1748848b8605Smrg 1749848b8605Smrg 1750848b8605Smrgvoid GLAPIENTRY 1751b8e80941Smrg_mesa_GetShaderSource(GLuint shader, GLsizei maxLength, 1752b8e80941Smrg GLsizei *length, GLchar *sourceOut) 1753848b8605Smrg{ 1754848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1755848b8605Smrg get_shader_source(ctx, shader, maxLength, length, sourceOut); 1756848b8605Smrg} 1757848b8605Smrg 1758848b8605Smrg 1759848b8605SmrgGLhandleARB GLAPIENTRY 1760848b8605Smrg_mesa_GetHandleARB(GLenum pname) 1761848b8605Smrg{ 1762848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1763848b8605Smrg return get_handle(ctx, pname); 1764848b8605Smrg} 1765848b8605Smrg 1766848b8605Smrg 1767848b8605SmrgGLboolean GLAPIENTRY 1768848b8605Smrg_mesa_IsProgram(GLuint name) 1769848b8605Smrg{ 1770848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1771848b8605Smrg return is_program(ctx, name); 1772848b8605Smrg} 1773848b8605Smrg 1774848b8605Smrg 1775848b8605SmrgGLboolean GLAPIENTRY 1776848b8605Smrg_mesa_IsShader(GLuint name) 1777848b8605Smrg{ 1778848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1779848b8605Smrg return is_shader(ctx, name); 1780848b8605Smrg} 1781848b8605Smrg 1782848b8605Smrg 1783848b8605Smrgvoid GLAPIENTRY 1784b8e80941Smrg_mesa_LinkProgram_no_error(GLuint programObj) 1785b8e80941Smrg{ 1786b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 1787b8e80941Smrg 1788b8e80941Smrg struct gl_shader_program *shProg = 1789b8e80941Smrg _mesa_lookup_shader_program(ctx, programObj); 1790b8e80941Smrg link_program_no_error(ctx, shProg); 1791b8e80941Smrg} 1792b8e80941Smrg 1793b8e80941Smrg 1794b8e80941Smrgvoid GLAPIENTRY 1795b8e80941Smrg_mesa_LinkProgram(GLuint programObj) 1796848b8605Smrg{ 1797848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1798b8e80941Smrg 1799b8e80941Smrg if (MESA_VERBOSE & VERBOSE_API) 1800b8e80941Smrg _mesa_debug(ctx, "glLinkProgram %u\n", programObj); 1801b8e80941Smrg 1802b8e80941Smrg struct gl_shader_program *shProg = 1803b8e80941Smrg _mesa_lookup_shader_program_err(ctx, programObj, "glLinkProgram"); 1804b8e80941Smrg link_program_error(ctx, shProg); 1805b8e80941Smrg} 1806b8e80941Smrg 1807b8e80941Smrg#ifdef ENABLE_SHADER_CACHE 1808b8e80941Smrg/** 1809b8e80941Smrg * Generate a SHA-1 hash value string for given source string. 1810b8e80941Smrg */ 1811b8e80941Smrgstatic void 1812b8e80941Smrggenerate_sha1(const char *source, char sha_str[64]) 1813b8e80941Smrg{ 1814b8e80941Smrg unsigned char sha[20]; 1815b8e80941Smrg _mesa_sha1_compute(source, strlen(source), sha); 1816b8e80941Smrg _mesa_sha1_format(sha_str, sha); 1817b8e80941Smrg} 1818b8e80941Smrg 1819b8e80941Smrg/** 1820b8e80941Smrg * Construct a full path for shader replacement functionality using 1821b8e80941Smrg * following format: 1822b8e80941Smrg * 1823b8e80941Smrg * <path>/<stage prefix>_<CHECKSUM>.glsl 1824b8e80941Smrg * <path>/<stage prefix>_<CHECKSUM>.arb 1825b8e80941Smrg */ 1826b8e80941Smrgstatic char * 1827b8e80941Smrgconstruct_name(const gl_shader_stage stage, const char *source, 1828b8e80941Smrg const char *path) 1829b8e80941Smrg{ 1830b8e80941Smrg char sha[64]; 1831b8e80941Smrg static const char *types[] = { 1832b8e80941Smrg "VS", "TC", "TE", "GS", "FS", "CS", 1833b8e80941Smrg }; 1834b8e80941Smrg 1835b8e80941Smrg const char *format = strncmp(source, "!!ARB", 5) ? "glsl" : "arb"; 1836b8e80941Smrg 1837b8e80941Smrg generate_sha1(source, sha); 1838b8e80941Smrg return ralloc_asprintf(NULL, "%s/%s_%s.%s", path, types[stage], sha, format); 1839848b8605Smrg} 1840848b8605Smrg 1841b8e80941Smrg/** 1842b8e80941Smrg * Write given shader source to a file in MESA_SHADER_DUMP_PATH. 1843b8e80941Smrg */ 1844b8e80941Smrgvoid 1845b8e80941Smrg_mesa_dump_shader_source(const gl_shader_stage stage, const char *source) 1846b8e80941Smrg{ 1847b8e80941Smrg static bool path_exists = true; 1848b8e80941Smrg char *dump_path; 1849b8e80941Smrg FILE *f; 1850b8e80941Smrg 1851b8e80941Smrg if (!path_exists) 1852b8e80941Smrg return; 1853b8e80941Smrg 1854b8e80941Smrg dump_path = getenv("MESA_SHADER_DUMP_PATH"); 1855b8e80941Smrg if (!dump_path) { 1856b8e80941Smrg path_exists = false; 1857b8e80941Smrg return; 1858b8e80941Smrg } 1859b8e80941Smrg 1860b8e80941Smrg char *name = construct_name(stage, source, dump_path); 1861848b8605Smrg 1862b8e80941Smrg f = fopen(name, "w"); 1863b8e80941Smrg if (f) { 1864b8e80941Smrg fputs(source, f); 1865b8e80941Smrg fclose(f); 1866b8e80941Smrg } else { 1867b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 1868b8e80941Smrg _mesa_warning(ctx, "could not open %s for dumping shader (%s)", name, 1869b8e80941Smrg strerror(errno)); 1870b8e80941Smrg } 1871b8e80941Smrg ralloc_free(name); 1872b8e80941Smrg} 1873848b8605Smrg 1874848b8605Smrg/** 1875848b8605Smrg * Read shader source code from a file. 1876848b8605Smrg * Useful for debugging to override an app's shader. 1877848b8605Smrg */ 1878b8e80941SmrgGLcharARB * 1879b8e80941Smrg_mesa_read_shader_source(const gl_shader_stage stage, const char *source) 1880848b8605Smrg{ 1881b8e80941Smrg char *read_path; 1882b8e80941Smrg static bool path_exists = true; 1883b8e80941Smrg int len, shader_size = 0; 1884b8e80941Smrg GLcharARB *buffer; 1885b8e80941Smrg FILE *f; 1886b8e80941Smrg 1887b8e80941Smrg if (!path_exists) 1888b8e80941Smrg return NULL; 1889848b8605Smrg 1890b8e80941Smrg read_path = getenv("MESA_SHADER_READ_PATH"); 1891b8e80941Smrg if (!read_path) { 1892b8e80941Smrg path_exists = false; 1893848b8605Smrg return NULL; 1894848b8605Smrg } 1895848b8605Smrg 1896b8e80941Smrg char *name = construct_name(stage, source, read_path); 1897b8e80941Smrg f = fopen(name, "r"); 1898b8e80941Smrg ralloc_free(name); 1899b8e80941Smrg if (!f) 1900b8e80941Smrg return NULL; 1901b8e80941Smrg 1902848b8605Smrg /* allocate enough room for the entire shader */ 1903848b8605Smrg fseek(f, 0, SEEK_END); 1904848b8605Smrg shader_size = ftell(f); 1905848b8605Smrg rewind(f); 1906848b8605Smrg assert(shader_size); 1907848b8605Smrg 1908848b8605Smrg /* add one for terminating zero */ 1909848b8605Smrg shader_size++; 1910848b8605Smrg 1911848b8605Smrg buffer = malloc(shader_size); 1912848b8605Smrg assert(buffer); 1913848b8605Smrg 1914848b8605Smrg len = fread(buffer, 1, shader_size, f); 1915848b8605Smrg buffer[len] = 0; 1916848b8605Smrg 1917848b8605Smrg fclose(f); 1918848b8605Smrg 1919b8e80941Smrg return buffer; 1920848b8605Smrg} 1921848b8605Smrg 1922b8e80941Smrg#endif /* ENABLE_SHADER_CACHE */ 1923848b8605Smrg 1924848b8605Smrg/** 1925848b8605Smrg * Called via glShaderSource() and glShaderSourceARB() API functions. 1926848b8605Smrg * Basically, concatenate the source code strings into one long string 1927848b8605Smrg * and pass it to _mesa_shader_source(). 1928848b8605Smrg */ 1929b8e80941Smrgstatic ALWAYS_INLINE void 1930b8e80941Smrgshader_source(struct gl_context *ctx, GLuint shaderObj, GLsizei count, 1931b8e80941Smrg const GLchar *const *string, const GLint *length, bool no_error) 1932848b8605Smrg{ 1933848b8605Smrg GLint *offsets; 1934848b8605Smrg GLsizei i, totalLength; 1935848b8605Smrg GLcharARB *source; 1936b8e80941Smrg struct gl_shader *sh; 1937848b8605Smrg 1938b8e80941Smrg if (!no_error) { 1939b8e80941Smrg sh = _mesa_lookup_shader_err(ctx, shaderObj, "glShaderSourceARB"); 1940b8e80941Smrg if (!sh) 1941b8e80941Smrg return; 1942b8e80941Smrg 1943b8e80941Smrg if (string == NULL) { 1944b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB"); 1945b8e80941Smrg return; 1946b8e80941Smrg } 1947b8e80941Smrg } else { 1948b8e80941Smrg sh = _mesa_lookup_shader(ctx, shaderObj); 1949848b8605Smrg } 1950848b8605Smrg 1951848b8605Smrg /* 1952848b8605Smrg * This array holds offsets of where the appropriate string ends, thus the 1953848b8605Smrg * last element will be set to the total length of the source code. 1954848b8605Smrg */ 1955848b8605Smrg offsets = malloc(count * sizeof(GLint)); 1956848b8605Smrg if (offsets == NULL) { 1957848b8605Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB"); 1958848b8605Smrg return; 1959848b8605Smrg } 1960848b8605Smrg 1961848b8605Smrg for (i = 0; i < count; i++) { 1962b8e80941Smrg if (!no_error && string[i] == NULL) { 1963848b8605Smrg free((GLvoid *) offsets); 1964848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 1965848b8605Smrg "glShaderSourceARB(null string)"); 1966848b8605Smrg return; 1967848b8605Smrg } 1968848b8605Smrg if (length == NULL || length[i] < 0) 1969848b8605Smrg offsets[i] = strlen(string[i]); 1970848b8605Smrg else 1971848b8605Smrg offsets[i] = length[i]; 1972848b8605Smrg /* accumulate string lengths */ 1973848b8605Smrg if (i > 0) 1974848b8605Smrg offsets[i] += offsets[i - 1]; 1975848b8605Smrg } 1976848b8605Smrg 1977848b8605Smrg /* Total length of source string is sum off all strings plus two. 1978848b8605Smrg * One extra byte for terminating zero, another extra byte to silence 1979848b8605Smrg * valgrind warnings in the parser/grammer code. 1980848b8605Smrg */ 1981848b8605Smrg totalLength = offsets[count - 1] + 2; 1982848b8605Smrg source = malloc(totalLength * sizeof(GLcharARB)); 1983848b8605Smrg if (source == NULL) { 1984848b8605Smrg free((GLvoid *) offsets); 1985848b8605Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB"); 1986848b8605Smrg return; 1987848b8605Smrg } 1988848b8605Smrg 1989848b8605Smrg for (i = 0; i < count; i++) { 1990848b8605Smrg GLint start = (i > 0) ? offsets[i - 1] : 0; 1991848b8605Smrg memcpy(source + start, string[i], 1992848b8605Smrg (offsets[i] - start) * sizeof(GLcharARB)); 1993848b8605Smrg } 1994848b8605Smrg source[totalLength - 1] = '\0'; 1995848b8605Smrg source[totalLength - 2] = '\0'; 1996848b8605Smrg 1997b8e80941Smrg#ifdef ENABLE_SHADER_CACHE 1998b8e80941Smrg GLcharARB *replacement; 1999848b8605Smrg 2000b8e80941Smrg /* Dump original shader source to MESA_SHADER_DUMP_PATH and replace 2001b8e80941Smrg * if corresponding entry found from MESA_SHADER_READ_PATH. 2002b8e80941Smrg */ 2003b8e80941Smrg _mesa_dump_shader_source(sh->Stage, source); 2004848b8605Smrg 2005b8e80941Smrg replacement = _mesa_read_shader_source(sh->Stage, source); 2006b8e80941Smrg if (replacement) { 2007b8e80941Smrg free(source); 2008b8e80941Smrg source = replacement; 2009848b8605Smrg } 2010b8e80941Smrg#endif /* ENABLE_SHADER_CACHE */ 2011848b8605Smrg 2012b8e80941Smrg set_shader_source(sh, source); 2013848b8605Smrg 2014848b8605Smrg free(offsets); 2015848b8605Smrg} 2016848b8605Smrg 2017848b8605Smrg 2018848b8605Smrgvoid GLAPIENTRY 2019b8e80941Smrg_mesa_ShaderSource_no_error(GLuint shaderObj, GLsizei count, 2020b8e80941Smrg const GLchar *const *string, const GLint *length) 2021848b8605Smrg{ 2022848b8605Smrg GET_CURRENT_CONTEXT(ctx); 2023b8e80941Smrg shader_source(ctx, shaderObj, count, string, length, true); 2024b8e80941Smrg} 2025848b8605Smrg 2026848b8605Smrg 2027b8e80941Smrgvoid GLAPIENTRY 2028b8e80941Smrg_mesa_ShaderSource(GLuint shaderObj, GLsizei count, 2029b8e80941Smrg const GLchar *const *string, const GLint *length) 2030b8e80941Smrg{ 2031b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 2032b8e80941Smrg shader_source(ctx, shaderObj, count, string, length, false); 2033b8e80941Smrg} 2034b8e80941Smrg 2035b8e80941Smrg 2036b8e80941Smrgstatic ALWAYS_INLINE void 2037b8e80941Smrguse_program(GLuint program, bool no_error) 2038b8e80941Smrg{ 2039b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 2040b8e80941Smrg struct gl_shader_program *shProg = NULL; 2041b8e80941Smrg 2042b8e80941Smrg if (MESA_VERBOSE & VERBOSE_API) 2043b8e80941Smrg _mesa_debug(ctx, "glUseProgram %u\n", program); 2044b8e80941Smrg 2045b8e80941Smrg if (no_error) { 2046b8e80941Smrg if (program) { 2047b8e80941Smrg shProg = _mesa_lookup_shader_program(ctx, program); 2048848b8605Smrg } 2049b8e80941Smrg } else { 2050b8e80941Smrg if (_mesa_is_xfb_active_and_unpaused(ctx)) { 2051848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 2052b8e80941Smrg "glUseProgram(transform feedback active)"); 2053848b8605Smrg return; 2054848b8605Smrg } 2055848b8605Smrg 2056b8e80941Smrg if (program) { 2057b8e80941Smrg shProg = 2058b8e80941Smrg _mesa_lookup_shader_program_err(ctx, program, "glUseProgram"); 2059b8e80941Smrg if (!shProg) 2060b8e80941Smrg return; 2061b8e80941Smrg 2062b8e80941Smrg if (!shProg->data->LinkStatus) { 2063b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 2064b8e80941Smrg "glUseProgram(program %u not linked)", program); 2065b8e80941Smrg return; 2066b8e80941Smrg } 2067b8e80941Smrg 2068b8e80941Smrg /* debug code */ 2069b8e80941Smrg if (ctx->_Shader->Flags & GLSL_USE_PROG) { 2070b8e80941Smrg print_shader_info(shProg); 2071b8e80941Smrg } 2072848b8605Smrg } 2073848b8605Smrg } 2074848b8605Smrg 2075848b8605Smrg /* The ARB_separate_shader_object spec says: 2076848b8605Smrg * 2077848b8605Smrg * "The executable code for an individual shader stage is taken from 2078848b8605Smrg * the current program for that stage. If there is a current program 2079848b8605Smrg * object established by UseProgram, that program is considered current 2080848b8605Smrg * for all stages. Otherwise, if there is a bound program pipeline 2081848b8605Smrg * object (section 2.14.PPO), the program bound to the appropriate 2082848b8605Smrg * stage of the pipeline object is considered current." 2083848b8605Smrg */ 2084b8e80941Smrg if (shProg) { 2085848b8605Smrg /* Attach shader state to the binding point */ 2086848b8605Smrg _mesa_reference_pipeline_object(ctx, &ctx->_Shader, &ctx->Shader); 2087848b8605Smrg /* Update the program */ 2088b8e80941Smrg _mesa_use_shader_program(ctx, shProg); 2089848b8605Smrg } else { 2090848b8605Smrg /* Must be done first: detach the progam */ 2091b8e80941Smrg _mesa_use_shader_program(ctx, shProg); 2092848b8605Smrg /* Unattach shader_state binding point */ 2093b8e80941Smrg _mesa_reference_pipeline_object(ctx, &ctx->_Shader, 2094b8e80941Smrg ctx->Pipeline.Default); 2095848b8605Smrg /* If a pipeline was bound, rebind it */ 2096848b8605Smrg if (ctx->Pipeline.Current) { 2097b8e80941Smrg if (no_error) 2098b8e80941Smrg _mesa_BindProgramPipeline_no_error(ctx->Pipeline.Current->Name); 2099b8e80941Smrg else 2100b8e80941Smrg _mesa_BindProgramPipeline(ctx->Pipeline.Current->Name); 2101848b8605Smrg } 2102848b8605Smrg } 2103b8e80941Smrg 2104b8e80941Smrg _mesa_update_vertex_processing_mode(ctx); 2105848b8605Smrg} 2106848b8605Smrg 2107848b8605Smrg 2108848b8605Smrgvoid GLAPIENTRY 2109b8e80941Smrg_mesa_UseProgram_no_error(GLuint program) 2110b8e80941Smrg{ 2111b8e80941Smrg use_program(program, true); 2112b8e80941Smrg} 2113b8e80941Smrg 2114b8e80941Smrg 2115b8e80941Smrgvoid GLAPIENTRY 2116b8e80941Smrg_mesa_UseProgram(GLuint program) 2117b8e80941Smrg{ 2118b8e80941Smrg use_program(program, false); 2119b8e80941Smrg} 2120b8e80941Smrg 2121b8e80941Smrg 2122b8e80941Smrgvoid GLAPIENTRY 2123b8e80941Smrg_mesa_ValidateProgram(GLuint program) 2124848b8605Smrg{ 2125848b8605Smrg GET_CURRENT_CONTEXT(ctx); 2126848b8605Smrg validate_program(ctx, program); 2127848b8605Smrg} 2128848b8605Smrg 2129848b8605Smrg 2130848b8605Smrg/** 2131848b8605Smrg * For OpenGL ES 2.0, GL_ARB_ES2_compatibility 2132848b8605Smrg */ 2133848b8605Smrgvoid GLAPIENTRY 2134848b8605Smrg_mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, 2135848b8605Smrg GLint* range, GLint* precision) 2136848b8605Smrg{ 2137848b8605Smrg const struct gl_program_constants *limits; 2138848b8605Smrg const struct gl_precision *p; 2139848b8605Smrg GET_CURRENT_CONTEXT(ctx); 2140848b8605Smrg 2141848b8605Smrg switch (shadertype) { 2142848b8605Smrg case GL_VERTEX_SHADER: 2143848b8605Smrg limits = &ctx->Const.Program[MESA_SHADER_VERTEX]; 2144848b8605Smrg break; 2145848b8605Smrg case GL_FRAGMENT_SHADER: 2146848b8605Smrg limits = &ctx->Const.Program[MESA_SHADER_FRAGMENT]; 2147848b8605Smrg break; 2148848b8605Smrg default: 2149848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, 2150848b8605Smrg "glGetShaderPrecisionFormat(shadertype)"); 2151848b8605Smrg return; 2152848b8605Smrg } 2153848b8605Smrg 2154848b8605Smrg switch (precisiontype) { 2155848b8605Smrg case GL_LOW_FLOAT: 2156848b8605Smrg p = &limits->LowFloat; 2157848b8605Smrg break; 2158848b8605Smrg case GL_MEDIUM_FLOAT: 2159848b8605Smrg p = &limits->MediumFloat; 2160848b8605Smrg break; 2161848b8605Smrg case GL_HIGH_FLOAT: 2162848b8605Smrg p = &limits->HighFloat; 2163848b8605Smrg break; 2164848b8605Smrg case GL_LOW_INT: 2165848b8605Smrg p = &limits->LowInt; 2166848b8605Smrg break; 2167848b8605Smrg case GL_MEDIUM_INT: 2168848b8605Smrg p = &limits->MediumInt; 2169848b8605Smrg break; 2170848b8605Smrg case GL_HIGH_INT: 2171848b8605Smrg p = &limits->HighInt; 2172848b8605Smrg break; 2173848b8605Smrg default: 2174848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, 2175848b8605Smrg "glGetShaderPrecisionFormat(precisiontype)"); 2176848b8605Smrg return; 2177848b8605Smrg } 2178848b8605Smrg 2179848b8605Smrg range[0] = p->RangeMin; 2180848b8605Smrg range[1] = p->RangeMax; 2181848b8605Smrg precision[0] = p->Precision; 2182848b8605Smrg} 2183848b8605Smrg 2184848b8605Smrg 2185848b8605Smrg/** 2186848b8605Smrg * For OpenGL ES 2.0, GL_ARB_ES2_compatibility 2187848b8605Smrg */ 2188848b8605Smrgvoid GLAPIENTRY 2189848b8605Smrg_mesa_ReleaseShaderCompiler(void) 2190848b8605Smrg{ 2191848b8605Smrg _mesa_destroy_shader_compiler_caches(); 2192848b8605Smrg} 2193848b8605Smrg 2194848b8605Smrg 2195848b8605Smrg/** 2196848b8605Smrg * For OpenGL ES 2.0, GL_ARB_ES2_compatibility 2197848b8605Smrg */ 2198848b8605Smrgvoid GLAPIENTRY 2199848b8605Smrg_mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat, 2200848b8605Smrg const void* binary, GLint length) 2201848b8605Smrg{ 2202848b8605Smrg GET_CURRENT_CONTEXT(ctx); 2203b8e80941Smrg struct gl_shader **sh; 2204b8e80941Smrg 2205b8e80941Smrg /* Page 68, section 7.2 'Shader Binaries" of the of the OpenGL ES 3.1, and 2206b8e80941Smrg * page 88 of the OpenGL 4.5 specs state: 2207b8e80941Smrg * 2208b8e80941Smrg * "An INVALID_VALUE error is generated if count or length is negative. 2209b8e80941Smrg * An INVALID_ENUM error is generated if binaryformat is not a supported 2210b8e80941Smrg * format returned in SHADER_BINARY_FORMATS." 2211b8e80941Smrg */ 2212b8e80941Smrg if (n < 0 || length < 0) { 2213b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glShaderBinary(count or length < 0)"); 2214b8e80941Smrg return; 2215b8e80941Smrg } 2216b8e80941Smrg 2217b8e80941Smrg /* Get all shader objects at once so we can make the operation 2218b8e80941Smrg * all-or-nothing. 2219b8e80941Smrg */ 2220b8e80941Smrg if (n > SIZE_MAX / sizeof(*sh)) { 2221b8e80941Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderBinary(count)"); 2222b8e80941Smrg return; 2223b8e80941Smrg } 2224b8e80941Smrg 2225b8e80941Smrg sh = alloca(sizeof(*sh) * (size_t)n); 2226b8e80941Smrg if (!sh) { 2227b8e80941Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderBinary"); 2228b8e80941Smrg return; 2229b8e80941Smrg } 2230b8e80941Smrg 2231b8e80941Smrg for (int i = 0; i < n; ++i) { 2232b8e80941Smrg sh[i] = _mesa_lookup_shader_err(ctx, shaders[i], "glShaderBinary"); 2233b8e80941Smrg if (!sh[i]) 2234b8e80941Smrg return; 2235b8e80941Smrg } 2236b8e80941Smrg 2237b8e80941Smrg if (binaryformat == GL_SHADER_BINARY_FORMAT_SPIR_V_ARB) { 2238b8e80941Smrg if (!ctx->Extensions.ARB_gl_spirv) { 2239b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "glShaderBinary(SPIR-V)"); 2240b8e80941Smrg } else if (n > 0) { 2241b8e80941Smrg _mesa_spirv_shader_binary(ctx, (unsigned) n, sh, binary, 2242b8e80941Smrg (size_t) length); 2243b8e80941Smrg } 2244b8e80941Smrg 2245b8e80941Smrg return; 2246b8e80941Smrg } 2247b8e80941Smrg 2248b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glShaderBinary(format)"); 2249848b8605Smrg} 2250848b8605Smrg 2251848b8605Smrg 2252848b8605Smrgvoid GLAPIENTRY 2253848b8605Smrg_mesa_GetProgramBinary(GLuint program, GLsizei bufSize, GLsizei *length, 2254848b8605Smrg GLenum *binaryFormat, GLvoid *binary) 2255848b8605Smrg{ 2256848b8605Smrg struct gl_shader_program *shProg; 2257b8e80941Smrg GLsizei length_dummy; 2258848b8605Smrg GET_CURRENT_CONTEXT(ctx); 2259848b8605Smrg 2260848b8605Smrg if (bufSize < 0){ 2261848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramBinary(bufSize < 0)"); 2262848b8605Smrg return; 2263848b8605Smrg } 2264848b8605Smrg 2265b8e80941Smrg shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetProgramBinary"); 2266b8e80941Smrg if (!shProg) 2267b8e80941Smrg return; 2268b8e80941Smrg 2269848b8605Smrg /* The ARB_get_program_binary spec says: 2270848b8605Smrg * 2271848b8605Smrg * "If <length> is NULL, then no length is returned." 2272b8e80941Smrg * 2273b8e80941Smrg * Ensure that length always points to valid storage to avoid multiple NULL 2274b8e80941Smrg * pointer checks below. 2275b8e80941Smrg */ 2276b8e80941Smrg if (length == NULL) 2277b8e80941Smrg length = &length_dummy; 2278b8e80941Smrg 2279b8e80941Smrg 2280b8e80941Smrg /* The ARB_get_program_binary spec says: 2281b8e80941Smrg * 2282b8e80941Smrg * "When a program object's LINK_STATUS is FALSE, its program binary 2283b8e80941Smrg * length is zero, and a call to GetProgramBinary will generate an 2284b8e80941Smrg * INVALID_OPERATION error. 2285848b8605Smrg */ 2286b8e80941Smrg if (!shProg->data->LinkStatus) { 2287b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 2288b8e80941Smrg "glGetProgramBinary(program %u not linked)", 2289b8e80941Smrg shProg->Name); 2290848b8605Smrg *length = 0; 2291b8e80941Smrg return; 2292b8e80941Smrg } 2293848b8605Smrg 2294b8e80941Smrg if (ctx->Const.NumProgramBinaryFormats == 0) { 2295b8e80941Smrg *length = 0; 2296b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 2297b8e80941Smrg "glGetProgramBinary(driver supports zero binary formats)"); 2298b8e80941Smrg } else { 2299b8e80941Smrg _mesa_get_program_binary(ctx, shProg, bufSize, length, binaryFormat, 2300b8e80941Smrg binary); 2301b8e80941Smrg assert(*length == 0 || *binaryFormat == GL_PROGRAM_BINARY_FORMAT_MESA); 2302b8e80941Smrg } 2303848b8605Smrg} 2304848b8605Smrg 2305848b8605Smrgvoid GLAPIENTRY 2306848b8605Smrg_mesa_ProgramBinary(GLuint program, GLenum binaryFormat, 2307848b8605Smrg const GLvoid *binary, GLsizei length) 2308848b8605Smrg{ 2309848b8605Smrg struct gl_shader_program *shProg; 2310848b8605Smrg GET_CURRENT_CONTEXT(ctx); 2311848b8605Smrg 2312848b8605Smrg shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramBinary"); 2313848b8605Smrg if (!shProg) 2314848b8605Smrg return; 2315848b8605Smrg 2316b8e80941Smrg _mesa_clear_shader_program_data(ctx, shProg); 2317b8e80941Smrg shProg->data = _mesa_create_shader_program_data(); 2318848b8605Smrg 2319b8e80941Smrg /* Section 2.3.1 (Errors) of the OpenGL 4.5 spec says: 2320b8e80941Smrg * 2321b8e80941Smrg * "If a negative number is provided where an argument of type sizei or 2322b8e80941Smrg * sizeiptr is specified, an INVALID_VALUE error is generated." 2323b8e80941Smrg */ 2324b8e80941Smrg if (length < 0) { 2325b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glProgramBinary(length < 0)"); 2326b8e80941Smrg return; 2327b8e80941Smrg } 2328848b8605Smrg 2329b8e80941Smrg if (ctx->Const.NumProgramBinaryFormats == 0 || 2330b8e80941Smrg binaryFormat != GL_PROGRAM_BINARY_FORMAT_MESA) { 2331b8e80941Smrg /* The ARB_get_program_binary spec says: 2332b8e80941Smrg * 2333b8e80941Smrg * "<binaryFormat> and <binary> must be those returned by a previous 2334b8e80941Smrg * call to GetProgramBinary, and <length> must be the length of the 2335b8e80941Smrg * program binary as returned by GetProgramBinary or GetProgramiv with 2336b8e80941Smrg * <pname> PROGRAM_BINARY_LENGTH. Loading the program binary will fail, 2337b8e80941Smrg * setting the LINK_STATUS of <program> to FALSE, if these conditions 2338b8e80941Smrg * are not met." 2339b8e80941Smrg * 2340b8e80941Smrg * Since any value of binaryFormat passed "is not one of those specified as 2341b8e80941Smrg * allowable for [this] command, an INVALID_ENUM error is generated." 2342b8e80941Smrg */ 2343b8e80941Smrg shProg->data->LinkStatus = LINKING_FAILURE; 2344b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glProgramBinary"); 2345b8e80941Smrg } else { 2346b8e80941Smrg _mesa_program_binary(ctx, shProg, binaryFormat, binary, length); 2347b8e80941Smrg } 2348b8e80941Smrg} 2349848b8605Smrg 2350848b8605Smrg 2351b8e80941Smrgstatic ALWAYS_INLINE void 2352b8e80941Smrgprogram_parameteri(struct gl_context *ctx, struct gl_shader_program *shProg, 2353b8e80941Smrg GLuint pname, GLint value, bool no_error) 2354b8e80941Smrg{ 2355848b8605Smrg switch (pname) { 2356848b8605Smrg case GL_PROGRAM_BINARY_RETRIEVABLE_HINT: 2357848b8605Smrg /* This enum isn't part of the OES extension for OpenGL ES 2.0, but it 2358848b8605Smrg * is part of OpenGL ES 3.0. For the ES2 case, this function shouldn't 2359848b8605Smrg * even be in the dispatch table, so we shouldn't need to expclicitly 2360848b8605Smrg * check here. 2361848b8605Smrg * 2362848b8605Smrg * On desktop, we ignore the 3.0+ requirement because it is silly. 2363848b8605Smrg */ 2364848b8605Smrg 2365848b8605Smrg /* The ARB_get_program_binary extension spec says: 2366848b8605Smrg * 2367848b8605Smrg * "An INVALID_VALUE error is generated if the <value> argument to 2368848b8605Smrg * ProgramParameteri is not TRUE or FALSE." 2369848b8605Smrg */ 2370b8e80941Smrg if (!no_error && value != GL_TRUE && value != GL_FALSE) { 2371b8e80941Smrg goto invalid_value; 2372848b8605Smrg } 2373848b8605Smrg 2374848b8605Smrg /* No need to notify the driver. Any changes will actually take effect 2375848b8605Smrg * the next time the shader is linked. 2376848b8605Smrg * 2377848b8605Smrg * The ARB_get_program_binary extension spec says: 2378848b8605Smrg * 2379848b8605Smrg * "To indicate that a program binary is likely to be retrieved, 2380848b8605Smrg * ProgramParameteri should be called with <pname> 2381848b8605Smrg * PROGRAM_BINARY_RETRIEVABLE_HINT and <value> TRUE. This setting 2382848b8605Smrg * will not be in effect until the next time LinkProgram or 2383848b8605Smrg * ProgramBinary has been called successfully." 2384848b8605Smrg * 2385848b8605Smrg * The resloution of issue 9 in the extension spec also says: 2386848b8605Smrg * 2387848b8605Smrg * "The application may use the PROGRAM_BINARY_RETRIEVABLE_HINT hint 2388848b8605Smrg * to indicate to the GL implementation that this program will 2389848b8605Smrg * likely be saved with GetProgramBinary at some point. This will 2390848b8605Smrg * give the GL implementation the opportunity to track any state 2391848b8605Smrg * changes made to the program before being saved such that when it 2392848b8605Smrg * is loaded again a recompile can be avoided." 2393848b8605Smrg */ 2394848b8605Smrg shProg->BinaryRetreivableHint = value; 2395848b8605Smrg return; 2396848b8605Smrg 2397848b8605Smrg case GL_PROGRAM_SEPARABLE: 2398848b8605Smrg /* Spec imply that the behavior is the same as ARB_get_program_binary 2399848b8605Smrg * Chapter 7.3 Program Objects 2400848b8605Smrg */ 2401b8e80941Smrg if (!no_error && value != GL_TRUE && value != GL_FALSE) { 2402b8e80941Smrg goto invalid_value; 2403848b8605Smrg } 2404848b8605Smrg shProg->SeparateShader = value; 2405848b8605Smrg return; 2406848b8605Smrg 2407848b8605Smrg default: 2408b8e80941Smrg if (!no_error) { 2409b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameteri(pname=%s)", 2410b8e80941Smrg _mesa_enum_to_string(pname)); 2411b8e80941Smrg } 2412b8e80941Smrg return; 2413848b8605Smrg } 2414848b8605Smrg 2415b8e80941Smrginvalid_value: 2416b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, 2417b8e80941Smrg "glProgramParameteri(pname=%s, value=%d): " 2418b8e80941Smrg "value must be 0 or 1.", 2419b8e80941Smrg _mesa_enum_to_string(pname), 2420b8e80941Smrg value); 2421848b8605Smrg} 2422848b8605Smrg 2423b8e80941Smrg 2424b8e80941Smrgvoid GLAPIENTRY 2425b8e80941Smrg_mesa_ProgramParameteri_no_error(GLuint program, GLenum pname, GLint value) 2426848b8605Smrg{ 2427b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 2428848b8605Smrg 2429b8e80941Smrg struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, program); 2430b8e80941Smrg program_parameteri(ctx, shProg, pname, value, true); 2431848b8605Smrg} 2432848b8605Smrg 2433848b8605Smrg 2434b8e80941Smrgvoid GLAPIENTRY 2435b8e80941Smrg_mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value) 2436848b8605Smrg{ 2437b8e80941Smrg struct gl_shader_program *shProg; 2438b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 2439848b8605Smrg 2440b8e80941Smrg shProg = _mesa_lookup_shader_program_err(ctx, program, 2441b8e80941Smrg "glProgramParameteri"); 2442b8e80941Smrg if (!shProg) 2443b8e80941Smrg return; 2444848b8605Smrg 2445b8e80941Smrg program_parameteri(ctx, shProg, pname, value, false); 2446b8e80941Smrg} 2447848b8605Smrg 2448848b8605Smrg 2449b8e80941Smrgvoid 2450b8e80941Smrg_mesa_use_program(struct gl_context *ctx, gl_shader_stage stage, 2451b8e80941Smrg struct gl_shader_program *shProg, struct gl_program *prog, 2452b8e80941Smrg struct gl_pipeline_object *shTarget) 2453b8e80941Smrg{ 2454b8e80941Smrg struct gl_program **target; 2455b8e80941Smrg 2456b8e80941Smrg target = &shTarget->CurrentProgram[stage]; 2457b8e80941Smrg if (prog) { 2458b8e80941Smrg _mesa_program_init_subroutine_defaults(ctx, prog); 2459b8e80941Smrg } 2460b8e80941Smrg 2461b8e80941Smrg if (*target != prog) { 2462b8e80941Smrg /* Program is current, flush it */ 2463b8e80941Smrg if (shTarget == ctx->_Shader) { 2464b8e80941Smrg FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); 2465b8e80941Smrg } 2466b8e80941Smrg 2467b8e80941Smrg _mesa_reference_shader_program(ctx, 2468b8e80941Smrg &shTarget->ReferencedPrograms[stage], 2469b8e80941Smrg shProg); 2470b8e80941Smrg _mesa_reference_program(ctx, target, prog); 2471b8e80941Smrg if (stage == MESA_SHADER_VERTEX) 2472b8e80941Smrg _mesa_update_vertex_processing_mode(ctx); 2473b8e80941Smrg return; 2474b8e80941Smrg } 2475b8e80941Smrg 2476b8e80941Smrg} 2477b8e80941Smrg 2478b8e80941Smrg 2479b8e80941Smrg/** 2480b8e80941Smrg * Copy program-specific data generated by linking from the gl_shader_program 2481b8e80941Smrg * object to the gl_program object referred to by the gl_linked_shader. 2482b8e80941Smrg * 2483b8e80941Smrg * This function expects _mesa_reference_program() to have been previously 2484b8e80941Smrg * called setting the gl_linked_shaders program reference. 2485b8e80941Smrg */ 2486b8e80941Smrgvoid 2487b8e80941Smrg_mesa_copy_linked_program_data(const struct gl_shader_program *src, 2488b8e80941Smrg struct gl_linked_shader *dst_sh) 2489b8e80941Smrg{ 2490b8e80941Smrg assert(dst_sh->Program); 2491b8e80941Smrg 2492b8e80941Smrg struct gl_program *dst = dst_sh->Program; 2493b8e80941Smrg 2494b8e80941Smrg dst->info.separate_shader = src->SeparateShader; 2495b8e80941Smrg 2496b8e80941Smrg switch (dst_sh->Stage) { 2497b8e80941Smrg case MESA_SHADER_GEOMETRY: { 2498b8e80941Smrg dst->info.gs.vertices_in = src->Geom.VerticesIn; 2499b8e80941Smrg dst->info.gs.uses_end_primitive = src->Geom.UsesEndPrimitive; 2500b8e80941Smrg dst->info.gs.uses_streams = src->Geom.UsesStreams; 2501b8e80941Smrg break; 2502b8e80941Smrg } 2503b8e80941Smrg case MESA_SHADER_FRAGMENT: { 2504b8e80941Smrg dst->info.fs.depth_layout = src->FragDepthLayout; 2505b8e80941Smrg break; 2506b8e80941Smrg } 2507b8e80941Smrg case MESA_SHADER_COMPUTE: { 2508b8e80941Smrg dst->info.cs.shared_size = src->Comp.SharedSize; 2509b8e80941Smrg break; 2510b8e80941Smrg } 2511b8e80941Smrg default: 2512b8e80941Smrg break; 2513b8e80941Smrg } 2514b8e80941Smrg} 2515b8e80941Smrg 2516b8e80941Smrg/** 2517b8e80941Smrg * ARB_separate_shader_objects: Compile & Link Program 2518b8e80941Smrg */ 2519b8e80941SmrgGLuint GLAPIENTRY 2520b8e80941Smrg_mesa_CreateShaderProgramv(GLenum type, GLsizei count, 2521b8e80941Smrg const GLchar* const *strings) 2522b8e80941Smrg{ 2523b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 2524b8e80941Smrg 2525b8e80941Smrg const GLuint shader = create_shader_err(ctx, type, "glCreateShaderProgramv"); 2526b8e80941Smrg GLuint program = 0; 2527b8e80941Smrg 2528b8e80941Smrg /* 2529b8e80941Smrg * According to OpenGL 4.5 and OpenGL ES 3.1 standards, section 7.3: 2530b8e80941Smrg * GL_INVALID_VALUE should be generated if count < 0 2531b8e80941Smrg */ 2532b8e80941Smrg if (count < 0) { 2533b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glCreateShaderProgram (count < 0)"); 2534b8e80941Smrg return program; 2535b8e80941Smrg } 2536b8e80941Smrg 2537b8e80941Smrg if (shader) { 2538b8e80941Smrg struct gl_shader *sh = _mesa_lookup_shader(ctx, shader); 2539b8e80941Smrg 2540b8e80941Smrg _mesa_ShaderSource(shader, count, strings, NULL); 2541b8e80941Smrg _mesa_compile_shader(ctx, sh); 2542b8e80941Smrg 2543b8e80941Smrg program = create_shader_program(ctx); 2544b8e80941Smrg if (program) { 2545b8e80941Smrg struct gl_shader_program *shProg; 2546b8e80941Smrg GLint compiled = GL_FALSE; 2547b8e80941Smrg 2548b8e80941Smrg shProg = _mesa_lookup_shader_program(ctx, program); 2549b8e80941Smrg 2550b8e80941Smrg shProg->SeparateShader = GL_TRUE; 2551848b8605Smrg 2552848b8605Smrg get_shaderiv(ctx, shader, GL_COMPILE_STATUS, &compiled); 2553848b8605Smrg if (compiled) { 2554b8e80941Smrg attach_shader_err(ctx, program, shader, "glCreateShaderProgramv"); 2555b8e80941Smrg _mesa_link_program(ctx, shProg); 2556b8e80941Smrg detach_shader_error(ctx, program, shader); 2557848b8605Smrg 2558848b8605Smrg#if 0 2559848b8605Smrg /* Possibly... */ 2560848b8605Smrg if (active-user-defined-varyings-in-linked-program) { 2561848b8605Smrg append-error-to-info-log; 2562b8e80941Smrg shProg->data->LinkStatus = LINKING_FAILURE; 2563848b8605Smrg } 2564848b8605Smrg#endif 2565848b8605Smrg } 2566b8e80941Smrg if (sh->InfoLog) 2567b8e80941Smrg ralloc_strcat(&shProg->data->InfoLog, sh->InfoLog); 2568848b8605Smrg } 2569848b8605Smrg 2570848b8605Smrg delete_shader(ctx, shader); 2571848b8605Smrg } 2572848b8605Smrg 2573848b8605Smrg return program; 2574848b8605Smrg} 2575848b8605Smrg 2576848b8605Smrg 2577848b8605Smrg/** 2578b8e80941Smrg * For GL_ARB_tessellation_shader 2579848b8605Smrg */ 2580b8e80941Smrgvoid GLAPIENTRY 2581b8e80941Smrg_mesa_PatchParameteri_no_error(GLenum pname, GLint value) 2582848b8605Smrg{ 2583b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 2584b8e80941Smrg ctx->TessCtrlProgram.patch_vertices = value; 2585b8e80941Smrg} 2586b8e80941Smrg 2587b8e80941Smrg 2588b8e80941Smrgextern void GLAPIENTRY 2589b8e80941Smrg_mesa_PatchParameteri(GLenum pname, GLint value) 2590b8e80941Smrg{ 2591b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 2592b8e80941Smrg 2593b8e80941Smrg if (!_mesa_has_tessellation(ctx)) { 2594b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "glPatchParameteri"); 2595b8e80941Smrg return; 2596b8e80941Smrg } 2597b8e80941Smrg 2598b8e80941Smrg if (pname != GL_PATCH_VERTICES) { 2599b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glPatchParameteri"); 2600b8e80941Smrg return; 2601b8e80941Smrg } 2602b8e80941Smrg 2603b8e80941Smrg if (value <= 0 || value > ctx->Const.MaxPatchVertices) { 2604b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glPatchParameteri"); 2605b8e80941Smrg return; 2606b8e80941Smrg } 2607b8e80941Smrg 2608b8e80941Smrg ctx->TessCtrlProgram.patch_vertices = value; 2609b8e80941Smrg} 2610b8e80941Smrg 2611b8e80941Smrg 2612b8e80941Smrgextern void GLAPIENTRY 2613b8e80941Smrg_mesa_PatchParameterfv(GLenum pname, const GLfloat *values) 2614b8e80941Smrg{ 2615b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 2616b8e80941Smrg 2617b8e80941Smrg if (!_mesa_has_tessellation(ctx)) { 2618b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "glPatchParameterfv"); 2619b8e80941Smrg return; 2620b8e80941Smrg } 2621b8e80941Smrg 2622b8e80941Smrg switch(pname) { 2623b8e80941Smrg case GL_PATCH_DEFAULT_OUTER_LEVEL: 2624b8e80941Smrg FLUSH_VERTICES(ctx, 0); 2625b8e80941Smrg memcpy(ctx->TessCtrlProgram.patch_default_outer_level, values, 2626b8e80941Smrg 4 * sizeof(GLfloat)); 2627b8e80941Smrg ctx->NewDriverState |= ctx->DriverFlags.NewDefaultTessLevels; 2628b8e80941Smrg return; 2629b8e80941Smrg case GL_PATCH_DEFAULT_INNER_LEVEL: 2630b8e80941Smrg FLUSH_VERTICES(ctx, 0); 2631b8e80941Smrg memcpy(ctx->TessCtrlProgram.patch_default_inner_level, values, 2632b8e80941Smrg 2 * sizeof(GLfloat)); 2633b8e80941Smrg ctx->NewDriverState |= ctx->DriverFlags.NewDefaultTessLevels; 2634b8e80941Smrg return; 2635b8e80941Smrg default: 2636b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glPatchParameterfv"); 2637b8e80941Smrg return; 2638b8e80941Smrg } 2639b8e80941Smrg} 2640b8e80941Smrg 2641b8e80941Smrg/** 2642b8e80941Smrg * ARB_shader_subroutine 2643b8e80941Smrg */ 2644b8e80941SmrgGLint GLAPIENTRY 2645b8e80941Smrg_mesa_GetSubroutineUniformLocation(GLuint program, GLenum shadertype, 2646b8e80941Smrg const GLchar *name) 2647b8e80941Smrg{ 2648b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 2649b8e80941Smrg const char *api_name = "glGetSubroutineUniformLocation"; 2650b8e80941Smrg struct gl_shader_program *shProg; 2651b8e80941Smrg GLenum resource_type; 2652b8e80941Smrg gl_shader_stage stage; 2653b8e80941Smrg 2654b8e80941Smrg if (!_mesa_validate_shader_target(ctx, shadertype)) { 2655b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name); 2656b8e80941Smrg return -1; 2657b8e80941Smrg } 2658b8e80941Smrg 2659b8e80941Smrg shProg = _mesa_lookup_shader_program_err(ctx, program, api_name); 2660b8e80941Smrg if (!shProg) 2661b8e80941Smrg return -1; 2662b8e80941Smrg 2663b8e80941Smrg stage = _mesa_shader_enum_to_shader_stage(shadertype); 2664b8e80941Smrg if (!shProg->_LinkedShaders[stage]) { 2665b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name); 2666b8e80941Smrg return -1; 2667b8e80941Smrg } 2668b8e80941Smrg 2669b8e80941Smrg resource_type = _mesa_shader_stage_to_subroutine_uniform(stage); 2670b8e80941Smrg return _mesa_program_resource_location(shProg, resource_type, name); 2671b8e80941Smrg} 2672b8e80941Smrg 2673b8e80941SmrgGLuint GLAPIENTRY 2674b8e80941Smrg_mesa_GetSubroutineIndex(GLuint program, GLenum shadertype, 2675b8e80941Smrg const GLchar *name) 2676b8e80941Smrg{ 2677b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 2678b8e80941Smrg const char *api_name = "glGetSubroutineIndex"; 2679b8e80941Smrg struct gl_shader_program *shProg; 2680b8e80941Smrg struct gl_program_resource *res; 2681b8e80941Smrg GLenum resource_type; 2682b8e80941Smrg gl_shader_stage stage; 2683b8e80941Smrg 2684b8e80941Smrg if (!_mesa_validate_shader_target(ctx, shadertype)) { 2685b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name); 2686b8e80941Smrg return -1; 2687b8e80941Smrg } 2688b8e80941Smrg 2689b8e80941Smrg shProg = _mesa_lookup_shader_program_err(ctx, program, api_name); 2690b8e80941Smrg if (!shProg) 2691b8e80941Smrg return -1; 2692b8e80941Smrg 2693b8e80941Smrg stage = _mesa_shader_enum_to_shader_stage(shadertype); 2694b8e80941Smrg if (!shProg->_LinkedShaders[stage]) { 2695b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name); 2696b8e80941Smrg return -1; 2697b8e80941Smrg } 2698b8e80941Smrg 2699b8e80941Smrg resource_type = _mesa_shader_stage_to_subroutine(stage); 2700b8e80941Smrg res = _mesa_program_resource_find_name(shProg, resource_type, name, NULL); 2701b8e80941Smrg if (!res) { 2702b8e80941Smrg return -1; 2703b8e80941Smrg } 2704b8e80941Smrg 2705b8e80941Smrg return _mesa_program_resource_index(shProg, res); 2706b8e80941Smrg} 2707b8e80941Smrg 2708b8e80941Smrg 2709b8e80941SmrgGLvoid GLAPIENTRY 2710b8e80941Smrg_mesa_GetActiveSubroutineUniformiv(GLuint program, GLenum shadertype, 2711b8e80941Smrg GLuint index, GLenum pname, GLint *values) 2712b8e80941Smrg{ 2713b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 2714b8e80941Smrg const char *api_name = "glGetActiveSubroutineUniformiv"; 2715b8e80941Smrg struct gl_shader_program *shProg; 2716b8e80941Smrg struct gl_linked_shader *sh; 2717b8e80941Smrg gl_shader_stage stage; 2718b8e80941Smrg struct gl_program_resource *res; 2719b8e80941Smrg const struct gl_uniform_storage *uni; 2720b8e80941Smrg GLenum resource_type; 2721b8e80941Smrg int count, i, j; 2722b8e80941Smrg 2723b8e80941Smrg if (!_mesa_validate_shader_target(ctx, shadertype)) { 2724b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name); 2725b8e80941Smrg return; 2726b8e80941Smrg } 2727b8e80941Smrg 2728b8e80941Smrg shProg = _mesa_lookup_shader_program_err(ctx, program, api_name); 2729b8e80941Smrg if (!shProg) 2730b8e80941Smrg return; 2731b8e80941Smrg 2732b8e80941Smrg stage = _mesa_shader_enum_to_shader_stage(shadertype); 2733b8e80941Smrg resource_type = _mesa_shader_stage_to_subroutine_uniform(stage); 2734b8e80941Smrg 2735b8e80941Smrg sh = shProg->_LinkedShaders[stage]; 2736b8e80941Smrg if (!sh) { 2737b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name); 2738b8e80941Smrg return; 2739b8e80941Smrg } 2740b8e80941Smrg 2741b8e80941Smrg struct gl_program *p = shProg->_LinkedShaders[stage]->Program; 2742b8e80941Smrg if (index >= p->sh.NumSubroutineUniforms) { 2743b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, "%s: invalid index greater than GL_ACTIVE_SUBROUTINE_UNIFORMS", api_name); 2744b8e80941Smrg return; 2745b8e80941Smrg } 2746b8e80941Smrg 2747b8e80941Smrg switch (pname) { 2748b8e80941Smrg case GL_NUM_COMPATIBLE_SUBROUTINES: { 2749b8e80941Smrg res = _mesa_program_resource_find_index(shProg, resource_type, index); 2750b8e80941Smrg if (res) { 2751b8e80941Smrg uni = res->Data; 2752b8e80941Smrg values[0] = uni->num_compatible_subroutines; 2753b8e80941Smrg } 2754848b8605Smrg break; 2755848b8605Smrg } 2756b8e80941Smrg case GL_COMPATIBLE_SUBROUTINES: { 2757b8e80941Smrg res = _mesa_program_resource_find_index(shProg, resource_type, index); 2758b8e80941Smrg if (res) { 2759b8e80941Smrg uni = res->Data; 2760b8e80941Smrg count = 0; 2761b8e80941Smrg for (i = 0; i < p->sh.NumSubroutineFunctions; i++) { 2762b8e80941Smrg struct gl_subroutine_function *fn = &p->sh.SubroutineFunctions[i]; 2763b8e80941Smrg for (j = 0; j < fn->num_compat_types; j++) { 2764b8e80941Smrg if (fn->types[j] == uni->type) { 2765b8e80941Smrg values[count++] = i; 2766b8e80941Smrg break; 2767b8e80941Smrg } 2768b8e80941Smrg } 2769b8e80941Smrg } 2770b8e80941Smrg } 2771848b8605Smrg break; 2772848b8605Smrg } 2773b8e80941Smrg case GL_UNIFORM_SIZE: 2774b8e80941Smrg res = _mesa_program_resource_find_index(shProg, resource_type, index); 2775b8e80941Smrg if (res) { 2776b8e80941Smrg uni = res->Data; 2777b8e80941Smrg values[0] = uni->array_elements ? uni->array_elements : 1; 2778b8e80941Smrg } 2779848b8605Smrg break; 2780b8e80941Smrg case GL_UNIFORM_NAME_LENGTH: 2781b8e80941Smrg res = _mesa_program_resource_find_index(shProg, resource_type, index); 2782b8e80941Smrg if (res) { 2783b8e80941Smrg values[0] = strlen(_mesa_program_resource_name(res)) + 1 2784b8e80941Smrg + ((_mesa_program_resource_array_size(res) != 0) ? 3 : 0); 2785b8e80941Smrg } 2786b8e80941Smrg break; 2787b8e80941Smrg default: 2788b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name); 2789b8e80941Smrg return; 2790b8e80941Smrg } 2791b8e80941Smrg} 2792b8e80941Smrg 2793b8e80941Smrg 2794b8e80941SmrgGLvoid GLAPIENTRY 2795b8e80941Smrg_mesa_GetActiveSubroutineUniformName(GLuint program, GLenum shadertype, 2796b8e80941Smrg GLuint index, GLsizei bufsize, 2797b8e80941Smrg GLsizei *length, GLchar *name) 2798b8e80941Smrg{ 2799b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 2800b8e80941Smrg const char *api_name = "glGetActiveSubroutineUniformName"; 2801b8e80941Smrg struct gl_shader_program *shProg; 2802b8e80941Smrg GLenum resource_type; 2803b8e80941Smrg gl_shader_stage stage; 2804b8e80941Smrg 2805b8e80941Smrg if (!_mesa_validate_shader_target(ctx, shadertype)) { 2806b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name); 2807b8e80941Smrg return; 2808b8e80941Smrg } 2809b8e80941Smrg 2810b8e80941Smrg shProg = _mesa_lookup_shader_program_err(ctx, program, api_name); 2811b8e80941Smrg if (!shProg) 2812b8e80941Smrg return; 2813b8e80941Smrg 2814b8e80941Smrg stage = _mesa_shader_enum_to_shader_stage(shadertype); 2815b8e80941Smrg if (!shProg->_LinkedShaders[stage]) { 2816b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name); 2817b8e80941Smrg return; 2818b8e80941Smrg } 2819b8e80941Smrg 2820b8e80941Smrg resource_type = _mesa_shader_stage_to_subroutine_uniform(stage); 2821b8e80941Smrg /* get program resource name */ 2822b8e80941Smrg _mesa_get_program_resource_name(shProg, resource_type, 2823b8e80941Smrg index, bufsize, 2824b8e80941Smrg length, name, api_name); 2825b8e80941Smrg} 2826b8e80941Smrg 2827b8e80941Smrg 2828b8e80941SmrgGLvoid GLAPIENTRY 2829b8e80941Smrg_mesa_GetActiveSubroutineName(GLuint program, GLenum shadertype, 2830b8e80941Smrg GLuint index, GLsizei bufsize, 2831b8e80941Smrg GLsizei *length, GLchar *name) 2832b8e80941Smrg{ 2833b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 2834b8e80941Smrg const char *api_name = "glGetActiveSubroutineName"; 2835b8e80941Smrg struct gl_shader_program *shProg; 2836b8e80941Smrg GLenum resource_type; 2837b8e80941Smrg gl_shader_stage stage; 2838b8e80941Smrg 2839b8e80941Smrg if (!_mesa_validate_shader_target(ctx, shadertype)) { 2840b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name); 2841b8e80941Smrg return; 2842b8e80941Smrg } 2843b8e80941Smrg 2844b8e80941Smrg shProg = _mesa_lookup_shader_program_err(ctx, program, api_name); 2845b8e80941Smrg if (!shProg) 2846b8e80941Smrg return; 2847b8e80941Smrg 2848b8e80941Smrg stage = _mesa_shader_enum_to_shader_stage(shadertype); 2849b8e80941Smrg if (!shProg->_LinkedShaders[stage]) { 2850b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name); 2851b8e80941Smrg return; 2852b8e80941Smrg } 2853b8e80941Smrg resource_type = _mesa_shader_stage_to_subroutine(stage); 2854b8e80941Smrg _mesa_get_program_resource_name(shProg, resource_type, 2855b8e80941Smrg index, bufsize, 2856b8e80941Smrg length, name, api_name); 2857b8e80941Smrg} 2858b8e80941Smrg 2859b8e80941SmrgGLvoid GLAPIENTRY 2860b8e80941Smrg_mesa_UniformSubroutinesuiv(GLenum shadertype, GLsizei count, 2861b8e80941Smrg const GLuint *indices) 2862b8e80941Smrg{ 2863b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 2864b8e80941Smrg const char *api_name = "glUniformSubroutinesuiv"; 2865b8e80941Smrg gl_shader_stage stage; 2866b8e80941Smrg int i; 2867b8e80941Smrg 2868b8e80941Smrg if (!_mesa_validate_shader_target(ctx, shadertype)) { 2869b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name); 2870b8e80941Smrg return; 2871b8e80941Smrg } 2872b8e80941Smrg 2873b8e80941Smrg stage = _mesa_shader_enum_to_shader_stage(shadertype); 2874b8e80941Smrg struct gl_program *p = ctx->_Shader->CurrentProgram[stage]; 2875b8e80941Smrg if (!p) { 2876b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name); 2877b8e80941Smrg return; 2878b8e80941Smrg } 2879b8e80941Smrg 2880b8e80941Smrg if (count != p->sh.NumSubroutineUniformRemapTable) { 2881b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, "%s", api_name); 2882b8e80941Smrg return; 2883b8e80941Smrg } 2884b8e80941Smrg 2885b8e80941Smrg i = 0; 2886b8e80941Smrg bool flushed = false; 2887b8e80941Smrg do { 2888b8e80941Smrg struct gl_uniform_storage *uni = p->sh.SubroutineUniformRemapTable[i]; 2889b8e80941Smrg if (uni == NULL) { 2890b8e80941Smrg i++; 2891b8e80941Smrg continue; 2892b8e80941Smrg } 2893b8e80941Smrg 2894b8e80941Smrg if (!flushed) { 2895b8e80941Smrg _mesa_flush_vertices_for_uniforms(ctx, uni); 2896b8e80941Smrg flushed = true; 2897b8e80941Smrg } 2898b8e80941Smrg 2899b8e80941Smrg int uni_count = uni->array_elements ? uni->array_elements : 1; 2900b8e80941Smrg int j, k, f; 2901b8e80941Smrg 2902b8e80941Smrg for (j = i; j < i + uni_count; j++) { 2903b8e80941Smrg struct gl_subroutine_function *subfn = NULL; 2904b8e80941Smrg if (indices[j] > p->sh.MaxSubroutineFunctionIndex) { 2905b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, "%s", api_name); 2906b8e80941Smrg return; 2907b8e80941Smrg } 2908b8e80941Smrg 2909b8e80941Smrg for (f = 0; f < p->sh.NumSubroutineFunctions; f++) { 2910b8e80941Smrg if (p->sh.SubroutineFunctions[f].index == indices[j]) 2911b8e80941Smrg subfn = &p->sh.SubroutineFunctions[f]; 2912b8e80941Smrg } 2913b8e80941Smrg 2914b8e80941Smrg if (!subfn) { 2915b8e80941Smrg continue; 2916b8e80941Smrg } 2917b8e80941Smrg 2918b8e80941Smrg for (k = 0; k < subfn->num_compat_types; k++) { 2919b8e80941Smrg if (subfn->types[k] == uni->type) 2920b8e80941Smrg break; 2921b8e80941Smrg } 2922b8e80941Smrg if (k == subfn->num_compat_types) { 2923b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name); 2924b8e80941Smrg return; 2925b8e80941Smrg } 2926b8e80941Smrg 2927b8e80941Smrg ctx->SubroutineIndex[p->info.stage].IndexPtr[j] = indices[j]; 2928b8e80941Smrg } 2929b8e80941Smrg i += uni_count; 2930b8e80941Smrg } while(i < count); 2931b8e80941Smrg} 2932b8e80941Smrg 2933b8e80941Smrg 2934b8e80941SmrgGLvoid GLAPIENTRY 2935b8e80941Smrg_mesa_GetUniformSubroutineuiv(GLenum shadertype, GLint location, 2936b8e80941Smrg GLuint *params) 2937b8e80941Smrg{ 2938b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 2939b8e80941Smrg const char *api_name = "glGetUniformSubroutineuiv"; 2940b8e80941Smrg gl_shader_stage stage; 2941b8e80941Smrg 2942b8e80941Smrg if (!_mesa_validate_shader_target(ctx, shadertype)) { 2943b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name); 2944b8e80941Smrg return; 2945b8e80941Smrg } 2946b8e80941Smrg 2947b8e80941Smrg stage = _mesa_shader_enum_to_shader_stage(shadertype); 2948b8e80941Smrg struct gl_program *p = ctx->_Shader->CurrentProgram[stage]; 2949b8e80941Smrg if (!p) { 2950b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name); 2951b8e80941Smrg return; 2952b8e80941Smrg } 2953b8e80941Smrg 2954b8e80941Smrg if (location >= p->sh.NumSubroutineUniformRemapTable) { 2955b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, "%s", api_name); 2956b8e80941Smrg return; 2957b8e80941Smrg } 2958b8e80941Smrg 2959b8e80941Smrg *params = ctx->SubroutineIndex[p->info.stage].IndexPtr[location]; 2960b8e80941Smrg} 2961b8e80941Smrg 2962b8e80941Smrg 2963b8e80941SmrgGLvoid GLAPIENTRY 2964b8e80941Smrg_mesa_GetProgramStageiv(GLuint program, GLenum shadertype, 2965b8e80941Smrg GLenum pname, GLint *values) 2966b8e80941Smrg{ 2967b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 2968b8e80941Smrg const char *api_name = "glGetProgramStageiv"; 2969b8e80941Smrg struct gl_shader_program *shProg; 2970b8e80941Smrg struct gl_linked_shader *sh; 2971b8e80941Smrg gl_shader_stage stage; 2972b8e80941Smrg 2973b8e80941Smrg if (!_mesa_validate_shader_target(ctx, shadertype)) { 2974b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name); 2975b8e80941Smrg return; 2976b8e80941Smrg } 2977b8e80941Smrg 2978b8e80941Smrg shProg = _mesa_lookup_shader_program_err(ctx, program, api_name); 2979b8e80941Smrg if (!shProg) 2980b8e80941Smrg return; 2981b8e80941Smrg 2982b8e80941Smrg stage = _mesa_shader_enum_to_shader_stage(shadertype); 2983b8e80941Smrg sh = shProg->_LinkedShaders[stage]; 2984b8e80941Smrg 2985b8e80941Smrg /* ARB_shader_subroutine doesn't ask the program to be linked, or list any 2986b8e80941Smrg * INVALID_OPERATION in the case of not be linked. 2987b8e80941Smrg * 2988b8e80941Smrg * And for some pnames, like GL_ACTIVE_SUBROUTINE_UNIFORMS, you can ask the 2989b8e80941Smrg * same info using other specs (ARB_program_interface_query), without the 2990b8e80941Smrg * need of the program to be linked, being the value for that case 0. 2991b8e80941Smrg * 2992b8e80941Smrg * But at the same time, some other methods require the program to be 2993b8e80941Smrg * linked for pname related to locations, so it would be inconsistent to 2994b8e80941Smrg * not do the same here. So we are: 2995b8e80941Smrg * * Return GL_INVALID_OPERATION if not linked only for locations. 2996b8e80941Smrg * * Setting a default value of 0, to be returned if not linked. 2997b8e80941Smrg */ 2998b8e80941Smrg if (!sh) { 2999b8e80941Smrg values[0] = 0; 3000b8e80941Smrg if (pname == GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS) { 3001b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name); 3002b8e80941Smrg } 3003b8e80941Smrg return; 3004848b8605Smrg } 3005b8e80941Smrg 3006b8e80941Smrg struct gl_program *p = sh->Program; 3007b8e80941Smrg switch (pname) { 3008b8e80941Smrg case GL_ACTIVE_SUBROUTINES: 3009b8e80941Smrg values[0] = p->sh.NumSubroutineFunctions; 3010b8e80941Smrg break; 3011b8e80941Smrg case GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS: 3012b8e80941Smrg values[0] = p->sh.NumSubroutineUniformRemapTable; 3013b8e80941Smrg break; 3014b8e80941Smrg case GL_ACTIVE_SUBROUTINE_UNIFORMS: 3015b8e80941Smrg values[0] = p->sh.NumSubroutineUniforms; 3016848b8605Smrg break; 3017b8e80941Smrg case GL_ACTIVE_SUBROUTINE_MAX_LENGTH: 3018b8e80941Smrg { 3019b8e80941Smrg unsigned i; 3020b8e80941Smrg GLint max_len = 0; 3021b8e80941Smrg GLenum resource_type; 3022b8e80941Smrg struct gl_program_resource *res; 3023b8e80941Smrg 3024b8e80941Smrg resource_type = _mesa_shader_stage_to_subroutine(stage); 3025b8e80941Smrg for (i = 0; i < p->sh.NumSubroutineFunctions; i++) { 3026b8e80941Smrg res = _mesa_program_resource_find_index(shProg, resource_type, i); 3027b8e80941Smrg if (res) { 3028b8e80941Smrg const GLint len = strlen(_mesa_program_resource_name(res)) + 1; 3029b8e80941Smrg if (len > max_len) 3030b8e80941Smrg max_len = len; 3031b8e80941Smrg } 3032b8e80941Smrg } 3033b8e80941Smrg values[0] = max_len; 3034b8e80941Smrg break; 3035b8e80941Smrg } 3036b8e80941Smrg case GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH: 3037b8e80941Smrg { 3038b8e80941Smrg unsigned i; 3039b8e80941Smrg GLint max_len = 0; 3040b8e80941Smrg GLenum resource_type; 3041b8e80941Smrg struct gl_program_resource *res; 3042b8e80941Smrg 3043b8e80941Smrg resource_type = _mesa_shader_stage_to_subroutine_uniform(stage); 3044b8e80941Smrg for (i = 0; i < p->sh.NumSubroutineUniformRemapTable; i++) { 3045b8e80941Smrg res = _mesa_program_resource_find_index(shProg, resource_type, i); 3046b8e80941Smrg if (res) { 3047b8e80941Smrg const GLint len = strlen(_mesa_program_resource_name(res)) + 1 3048b8e80941Smrg + ((_mesa_program_resource_array_size(res) != 0) ? 3 : 0); 3049b8e80941Smrg 3050b8e80941Smrg if (len > max_len) 3051b8e80941Smrg max_len = len; 3052b8e80941Smrg } 3053b8e80941Smrg } 3054b8e80941Smrg values[0] = max_len; 3055b8e80941Smrg break; 3056b8e80941Smrg } 3057848b8605Smrg default: 3058b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, "%s", api_name); 3059b8e80941Smrg values[0] = -1; 3060848b8605Smrg break; 3061848b8605Smrg } 3062848b8605Smrg} 3063848b8605Smrg 3064b8e80941Smrgstatic int 3065b8e80941Smrgfind_compat_subroutine(struct gl_program *p, const struct glsl_type *type) 3066848b8605Smrg{ 3067b8e80941Smrg int i, j; 3068b8e80941Smrg 3069b8e80941Smrg for (i = 0; i < p->sh.NumSubroutineFunctions; i++) { 3070b8e80941Smrg struct gl_subroutine_function *fn = &p->sh.SubroutineFunctions[i]; 3071b8e80941Smrg for (j = 0; j < fn->num_compat_types; j++) { 3072b8e80941Smrg if (fn->types[j] == type) 3073b8e80941Smrg return i; 3074b8e80941Smrg } 3075b8e80941Smrg } 3076b8e80941Smrg return 0; 3077b8e80941Smrg} 3078b8e80941Smrg 3079b8e80941Smrgstatic void 3080b8e80941Smrg_mesa_shader_write_subroutine_index(struct gl_context *ctx, 3081b8e80941Smrg struct gl_program *p) 3082b8e80941Smrg{ 3083b8e80941Smrg int i, j; 3084b8e80941Smrg 3085b8e80941Smrg if (p->sh.NumSubroutineUniformRemapTable == 0) 3086b8e80941Smrg return; 3087848b8605Smrg 3088b8e80941Smrg i = 0; 3089b8e80941Smrg do { 3090b8e80941Smrg struct gl_uniform_storage *uni = p->sh.SubroutineUniformRemapTable[i]; 3091b8e80941Smrg int uni_count; 3092b8e80941Smrg int val; 3093b8e80941Smrg 3094b8e80941Smrg if (!uni) { 3095b8e80941Smrg i++; 3096b8e80941Smrg continue; 3097b8e80941Smrg } 3098b8e80941Smrg 3099b8e80941Smrg uni_count = uni->array_elements ? uni->array_elements : 1; 3100b8e80941Smrg for (j = 0; j < uni_count; j++) { 3101b8e80941Smrg val = ctx->SubroutineIndex[p->info.stage].IndexPtr[i + j]; 3102b8e80941Smrg memcpy(&uni->storage[j], &val, sizeof(int)); 3103b8e80941Smrg } 3104b8e80941Smrg 3105b8e80941Smrg _mesa_propagate_uniforms_to_driver_storage(uni, 0, uni_count); 3106b8e80941Smrg i += uni_count; 3107b8e80941Smrg } while(i < p->sh.NumSubroutineUniformRemapTable); 3108b8e80941Smrg} 3109b8e80941Smrg 3110b8e80941Smrgvoid 3111b8e80941Smrg_mesa_shader_write_subroutine_indices(struct gl_context *ctx, 3112b8e80941Smrg gl_shader_stage stage) 3113b8e80941Smrg{ 3114b8e80941Smrg if (ctx->_Shader->CurrentProgram[stage]) 3115b8e80941Smrg _mesa_shader_write_subroutine_index(ctx, 3116b8e80941Smrg ctx->_Shader->CurrentProgram[stage]); 3117b8e80941Smrg} 3118b8e80941Smrg 3119b8e80941Smrgvoid 3120b8e80941Smrg_mesa_program_init_subroutine_defaults(struct gl_context *ctx, 3121b8e80941Smrg struct gl_program *p) 3122b8e80941Smrg{ 3123b8e80941Smrg assert(p); 3124b8e80941Smrg 3125b8e80941Smrg struct gl_subroutine_index_binding *binding = &ctx->SubroutineIndex[p->info.stage]; 3126b8e80941Smrg if (binding->NumIndex != p->sh.NumSubroutineUniformRemapTable) { 3127b8e80941Smrg binding->IndexPtr = realloc(binding->IndexPtr, 3128b8e80941Smrg p->sh.NumSubroutineUniformRemapTable * (sizeof(GLuint))); 3129b8e80941Smrg binding->NumIndex = p->sh.NumSubroutineUniformRemapTable; 3130b8e80941Smrg } 3131b8e80941Smrg 3132b8e80941Smrg for (int i = 0; i < p->sh.NumSubroutineUniformRemapTable; i++) { 3133b8e80941Smrg struct gl_uniform_storage *uni = p->sh.SubroutineUniformRemapTable[i]; 3134b8e80941Smrg 3135b8e80941Smrg if (!uni) 3136b8e80941Smrg continue; 3137b8e80941Smrg 3138b8e80941Smrg binding->IndexPtr[i] = find_compat_subroutine(p, uni->type); 3139b8e80941Smrg } 3140848b8605Smrg} 3141