shaderapi.c revision 848b8605
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 40848b8605Smrg#include "main/glheader.h" 41848b8605Smrg#include "main/context.h" 42848b8605Smrg#include "main/dispatch.h" 43848b8605Smrg#include "main/enums.h" 44848b8605Smrg#include "main/hash.h" 45848b8605Smrg#include "main/mtypes.h" 46848b8605Smrg#include "main/pipelineobj.h" 47848b8605Smrg#include "main/shaderapi.h" 48848b8605Smrg#include "main/shaderobj.h" 49848b8605Smrg#include "main/transformfeedback.h" 50848b8605Smrg#include "main/uniforms.h" 51848b8605Smrg#include "program/program.h" 52848b8605Smrg#include "program/prog_print.h" 53848b8605Smrg#include "program/prog_parameter.h" 54848b8605Smrg#include "util/ralloc.h" 55848b8605Smrg#include "util/hash_table.h" 56848b8605Smrg#include <stdbool.h> 57848b8605Smrg#include "../glsl/glsl_parser_extras.h" 58848b8605Smrg#include "../glsl/ir.h" 59848b8605Smrg#include "../glsl/ir_uniform.h" 60848b8605Smrg#include "../glsl/program.h" 61848b8605Smrg 62848b8605Smrg/** Define this to enable shader substitution (see below) */ 63848b8605Smrg#define SHADER_SUBST 0 64848b8605Smrg 65848b8605Smrg 66848b8605Smrg/** 67848b8605Smrg * Return mask of GLSL_x flags by examining the MESA_GLSL env var. 68848b8605Smrg */ 69848b8605SmrgGLbitfield 70848b8605Smrg_mesa_get_shader_flags(void) 71848b8605Smrg{ 72848b8605Smrg GLbitfield flags = 0x0; 73848b8605Smrg const char *env = _mesa_getenv("MESA_GLSL"); 74848b8605Smrg 75848b8605Smrg if (env) { 76848b8605Smrg if (strstr(env, "dump_on_error")) 77848b8605Smrg flags |= GLSL_DUMP_ON_ERROR; 78848b8605Smrg else if (strstr(env, "dump")) 79848b8605Smrg flags |= GLSL_DUMP; 80848b8605Smrg if (strstr(env, "log")) 81848b8605Smrg flags |= GLSL_LOG; 82848b8605Smrg if (strstr(env, "nopvert")) 83848b8605Smrg flags |= GLSL_NOP_VERT; 84848b8605Smrg if (strstr(env, "nopfrag")) 85848b8605Smrg flags |= GLSL_NOP_FRAG; 86848b8605Smrg if (strstr(env, "nopt")) 87848b8605Smrg flags |= GLSL_NO_OPT; 88848b8605Smrg else if (strstr(env, "opt")) 89848b8605Smrg flags |= GLSL_OPT; 90848b8605Smrg if (strstr(env, "uniform")) 91848b8605Smrg flags |= GLSL_UNIFORMS; 92848b8605Smrg if (strstr(env, "useprog")) 93848b8605Smrg flags |= GLSL_USE_PROG; 94848b8605Smrg if (strstr(env, "errors")) 95848b8605Smrg flags |= GLSL_REPORT_ERRORS; 96848b8605Smrg } 97848b8605Smrg 98848b8605Smrg return flags; 99848b8605Smrg} 100848b8605Smrg 101848b8605Smrg 102848b8605Smrg/** 103848b8605Smrg * Initialize context's shader state. 104848b8605Smrg */ 105848b8605Smrgvoid 106848b8605Smrg_mesa_init_shader_state(struct gl_context *ctx) 107848b8605Smrg{ 108848b8605Smrg /* Device drivers may override these to control what kind of instructions 109848b8605Smrg * are generated by the GLSL compiler. 110848b8605Smrg */ 111848b8605Smrg struct gl_shader_compiler_options options; 112848b8605Smrg gl_shader_stage sh; 113848b8605Smrg 114848b8605Smrg memset(&options, 0, sizeof(options)); 115848b8605Smrg options.MaxUnrollIterations = 32; 116848b8605Smrg options.MaxIfDepth = UINT_MAX; 117848b8605Smrg 118848b8605Smrg /* Default pragma settings */ 119848b8605Smrg options.DefaultPragmas.Optimize = GL_TRUE; 120848b8605Smrg 121848b8605Smrg for (sh = 0; sh < MESA_SHADER_STAGES; ++sh) 122848b8605Smrg memcpy(&ctx->Const.ShaderCompilerOptions[sh], &options, sizeof(options)); 123848b8605Smrg 124848b8605Smrg ctx->Shader.Flags = _mesa_get_shader_flags(); 125848b8605Smrg 126848b8605Smrg /* Extended for ARB_separate_shader_objects */ 127848b8605Smrg ctx->Shader.RefCount = 1; 128848b8605Smrg mtx_init(&ctx->Shader.Mutex, mtx_plain); 129848b8605Smrg} 130848b8605Smrg 131848b8605Smrg 132848b8605Smrg/** 133848b8605Smrg * Free the per-context shader-related state. 134848b8605Smrg */ 135848b8605Smrgvoid 136848b8605Smrg_mesa_free_shader_state(struct gl_context *ctx) 137848b8605Smrg{ 138848b8605Smrg int i; 139848b8605Smrg for (i = 0; i < MESA_SHADER_STAGES; i++) { 140848b8605Smrg _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram[i], 141848b8605Smrg NULL); 142848b8605Smrg } 143848b8605Smrg _mesa_reference_shader_program(ctx, &ctx->Shader._CurrentFragmentProgram, 144848b8605Smrg NULL); 145848b8605Smrg _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, NULL); 146848b8605Smrg 147848b8605Smrg /* Extended for ARB_separate_shader_objects */ 148848b8605Smrg _mesa_reference_pipeline_object(ctx, &ctx->_Shader, NULL); 149848b8605Smrg 150848b8605Smrg assert(ctx->Shader.RefCount == 1); 151848b8605Smrg mtx_destroy(&ctx->Shader.Mutex); 152848b8605Smrg} 153848b8605Smrg 154848b8605Smrg 155848b8605Smrg/** 156848b8605Smrg * Copy string from <src> to <dst>, up to maxLength characters, returning 157848b8605Smrg * length of <dst> in <length>. 158848b8605Smrg * \param src the strings source 159848b8605Smrg * \param maxLength max chars to copy 160848b8605Smrg * \param length returns number of chars copied 161848b8605Smrg * \param dst the string destination 162848b8605Smrg */ 163848b8605Smrgvoid 164848b8605Smrg_mesa_copy_string(GLchar *dst, GLsizei maxLength, 165848b8605Smrg GLsizei *length, const GLchar *src) 166848b8605Smrg{ 167848b8605Smrg GLsizei len; 168848b8605Smrg for (len = 0; len < maxLength - 1 && src && src[len]; len++) 169848b8605Smrg dst[len] = src[len]; 170848b8605Smrg if (maxLength > 0) 171848b8605Smrg dst[len] = 0; 172848b8605Smrg if (length) 173848b8605Smrg *length = len; 174848b8605Smrg} 175848b8605Smrg 176848b8605Smrg 177848b8605Smrg 178848b8605Smrg/** 179848b8605Smrg * Confirm that the a shader type is valid and supported by the implementation 180848b8605Smrg * 181848b8605Smrg * \param ctx Current GL context 182848b8605Smrg * \param type Shader target 183848b8605Smrg * 184848b8605Smrg */ 185848b8605Smrgbool 186848b8605Smrg_mesa_validate_shader_target(const struct gl_context *ctx, GLenum type) 187848b8605Smrg{ 188848b8605Smrg /* Note: when building built-in GLSL functions, this function may be 189848b8605Smrg * invoked with ctx == NULL. In that case, we can only validate that it's 190848b8605Smrg * a shader target we recognize, not that it's supported in the current 191848b8605Smrg * context. But that's fine--we don't need any further validation than 192848b8605Smrg * that when building built-in GLSL functions. 193848b8605Smrg */ 194848b8605Smrg 195848b8605Smrg switch (type) { 196848b8605Smrg case GL_FRAGMENT_SHADER: 197848b8605Smrg return ctx == NULL || ctx->Extensions.ARB_fragment_shader; 198848b8605Smrg case GL_VERTEX_SHADER: 199848b8605Smrg return ctx == NULL || ctx->Extensions.ARB_vertex_shader; 200848b8605Smrg case GL_GEOMETRY_SHADER_ARB: 201848b8605Smrg return ctx == NULL || _mesa_has_geometry_shaders(ctx); 202848b8605Smrg case GL_COMPUTE_SHADER: 203848b8605Smrg return ctx == NULL || ctx->Extensions.ARB_compute_shader; 204848b8605Smrg default: 205848b8605Smrg return false; 206848b8605Smrg } 207848b8605Smrg} 208848b8605Smrg 209848b8605Smrg 210848b8605Smrgstatic GLboolean 211848b8605Smrgis_program(struct gl_context *ctx, GLuint name) 212848b8605Smrg{ 213848b8605Smrg struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, name); 214848b8605Smrg return shProg ? GL_TRUE : GL_FALSE; 215848b8605Smrg} 216848b8605Smrg 217848b8605Smrg 218848b8605Smrgstatic GLboolean 219848b8605Smrgis_shader(struct gl_context *ctx, GLuint name) 220848b8605Smrg{ 221848b8605Smrg struct gl_shader *shader = _mesa_lookup_shader(ctx, name); 222848b8605Smrg return shader ? GL_TRUE : GL_FALSE; 223848b8605Smrg} 224848b8605Smrg 225848b8605Smrg 226848b8605Smrg/** 227848b8605Smrg * Attach shader to a shader program. 228848b8605Smrg */ 229848b8605Smrgstatic void 230848b8605Smrgattach_shader(struct gl_context *ctx, GLuint program, GLuint shader) 231848b8605Smrg{ 232848b8605Smrg struct gl_shader_program *shProg; 233848b8605Smrg struct gl_shader *sh; 234848b8605Smrg GLuint i, n; 235848b8605Smrg 236848b8605Smrg const bool same_type_disallowed = _mesa_is_gles(ctx); 237848b8605Smrg 238848b8605Smrg shProg = _mesa_lookup_shader_program_err(ctx, program, "glAttachShader"); 239848b8605Smrg if (!shProg) 240848b8605Smrg return; 241848b8605Smrg 242848b8605Smrg sh = _mesa_lookup_shader_err(ctx, shader, "glAttachShader"); 243848b8605Smrg if (!sh) { 244848b8605Smrg return; 245848b8605Smrg } 246848b8605Smrg 247848b8605Smrg n = shProg->NumShaders; 248848b8605Smrg for (i = 0; i < n; i++) { 249848b8605Smrg if (shProg->Shaders[i] == sh) { 250848b8605Smrg /* The shader is already attched to this program. The 251848b8605Smrg * GL_ARB_shader_objects spec says: 252848b8605Smrg * 253848b8605Smrg * "The error INVALID_OPERATION is generated by AttachObjectARB 254848b8605Smrg * if <obj> is already attached to <containerObj>." 255848b8605Smrg */ 256848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader"); 257848b8605Smrg return; 258848b8605Smrg } else if (same_type_disallowed && 259848b8605Smrg shProg->Shaders[i]->Type == sh->Type) { 260848b8605Smrg /* Shader with the same type is already attached to this program, 261848b8605Smrg * OpenGL ES 2.0 and 3.0 specs say: 262848b8605Smrg * 263848b8605Smrg * "Multiple shader objects of the same type may not be attached 264848b8605Smrg * to a single program object. [...] The error INVALID_OPERATION 265848b8605Smrg * is generated if [...] another shader object of the same type 266848b8605Smrg * as shader is already attached to program." 267848b8605Smrg */ 268848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader"); 269848b8605Smrg return; 270848b8605Smrg } 271848b8605Smrg } 272848b8605Smrg 273848b8605Smrg /* grow list */ 274848b8605Smrg shProg->Shaders = (struct gl_shader **) 275848b8605Smrg _mesa_realloc(shProg->Shaders, 276848b8605Smrg n * sizeof(struct gl_shader *), 277848b8605Smrg (n + 1) * sizeof(struct gl_shader *)); 278848b8605Smrg if (!shProg->Shaders) { 279848b8605Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAttachShader"); 280848b8605Smrg return; 281848b8605Smrg } 282848b8605Smrg 283848b8605Smrg /* append */ 284848b8605Smrg shProg->Shaders[n] = NULL; /* since realloc() didn't zero the new space */ 285848b8605Smrg _mesa_reference_shader(ctx, &shProg->Shaders[n], sh); 286848b8605Smrg shProg->NumShaders++; 287848b8605Smrg} 288848b8605Smrg 289848b8605Smrg 290848b8605Smrgstatic GLuint 291848b8605Smrgcreate_shader(struct gl_context *ctx, GLenum type) 292848b8605Smrg{ 293848b8605Smrg struct gl_shader *sh; 294848b8605Smrg GLuint name; 295848b8605Smrg 296848b8605Smrg if (!_mesa_validate_shader_target(ctx, type)) { 297848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "CreateShader(type)"); 298848b8605Smrg return 0; 299848b8605Smrg } 300848b8605Smrg 301848b8605Smrg name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1); 302848b8605Smrg sh = ctx->Driver.NewShader(ctx, name, type); 303848b8605Smrg _mesa_HashInsert(ctx->Shared->ShaderObjects, name, sh); 304848b8605Smrg 305848b8605Smrg return name; 306848b8605Smrg} 307848b8605Smrg 308848b8605Smrg 309848b8605Smrgstatic GLuint 310848b8605Smrgcreate_shader_program(struct gl_context *ctx) 311848b8605Smrg{ 312848b8605Smrg GLuint name; 313848b8605Smrg struct gl_shader_program *shProg; 314848b8605Smrg 315848b8605Smrg name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1); 316848b8605Smrg 317848b8605Smrg shProg = ctx->Driver.NewShaderProgram(ctx, name); 318848b8605Smrg 319848b8605Smrg _mesa_HashInsert(ctx->Shared->ShaderObjects, name, shProg); 320848b8605Smrg 321848b8605Smrg assert(shProg->RefCount == 1); 322848b8605Smrg 323848b8605Smrg return name; 324848b8605Smrg} 325848b8605Smrg 326848b8605Smrg 327848b8605Smrg/** 328848b8605Smrg * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's 329848b8605Smrg * DeleteProgramARB. 330848b8605Smrg */ 331848b8605Smrgstatic void 332848b8605Smrgdelete_shader_program(struct gl_context *ctx, GLuint name) 333848b8605Smrg{ 334848b8605Smrg /* 335848b8605Smrg * NOTE: deleting shaders/programs works a bit differently than 336848b8605Smrg * texture objects (and buffer objects, etc). Shader/program 337848b8605Smrg * handles/IDs exist in the hash table until the object is really 338848b8605Smrg * deleted (refcount==0). With texture objects, the handle/ID is 339848b8605Smrg * removed from the hash table in glDeleteTextures() while the tex 340848b8605Smrg * object itself might linger until its refcount goes to zero. 341848b8605Smrg */ 342848b8605Smrg struct gl_shader_program *shProg; 343848b8605Smrg 344848b8605Smrg shProg = _mesa_lookup_shader_program_err(ctx, name, "glDeleteProgram"); 345848b8605Smrg if (!shProg) 346848b8605Smrg return; 347848b8605Smrg 348848b8605Smrg if (!shProg->DeletePending) { 349848b8605Smrg shProg->DeletePending = GL_TRUE; 350848b8605Smrg 351848b8605Smrg /* effectively, decr shProg's refcount */ 352848b8605Smrg _mesa_reference_shader_program(ctx, &shProg, NULL); 353848b8605Smrg } 354848b8605Smrg} 355848b8605Smrg 356848b8605Smrg 357848b8605Smrgstatic void 358848b8605Smrgdelete_shader(struct gl_context *ctx, GLuint shader) 359848b8605Smrg{ 360848b8605Smrg struct gl_shader *sh; 361848b8605Smrg 362848b8605Smrg sh = _mesa_lookup_shader_err(ctx, shader, "glDeleteShader"); 363848b8605Smrg if (!sh) 364848b8605Smrg return; 365848b8605Smrg 366848b8605Smrg if (!sh->DeletePending) { 367848b8605Smrg sh->DeletePending = GL_TRUE; 368848b8605Smrg 369848b8605Smrg /* effectively, decr sh's refcount */ 370848b8605Smrg _mesa_reference_shader(ctx, &sh, NULL); 371848b8605Smrg } 372848b8605Smrg} 373848b8605Smrg 374848b8605Smrg 375848b8605Smrgstatic void 376848b8605Smrgdetach_shader(struct gl_context *ctx, GLuint program, GLuint shader) 377848b8605Smrg{ 378848b8605Smrg struct gl_shader_program *shProg; 379848b8605Smrg GLuint n; 380848b8605Smrg GLuint i, j; 381848b8605Smrg 382848b8605Smrg shProg = _mesa_lookup_shader_program_err(ctx, program, "glDetachShader"); 383848b8605Smrg if (!shProg) 384848b8605Smrg return; 385848b8605Smrg 386848b8605Smrg n = shProg->NumShaders; 387848b8605Smrg 388848b8605Smrg for (i = 0; i < n; i++) { 389848b8605Smrg if (shProg->Shaders[i]->Name == shader) { 390848b8605Smrg /* found it */ 391848b8605Smrg struct gl_shader **newList; 392848b8605Smrg 393848b8605Smrg /* release */ 394848b8605Smrg _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL); 395848b8605Smrg 396848b8605Smrg /* alloc new, smaller array */ 397848b8605Smrg newList = malloc((n - 1) * sizeof(struct gl_shader *)); 398848b8605Smrg if (!newList) { 399848b8605Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDetachShader"); 400848b8605Smrg return; 401848b8605Smrg } 402848b8605Smrg /* Copy old list entries to new list, skipping removed entry at [i] */ 403848b8605Smrg for (j = 0; j < i; j++) { 404848b8605Smrg newList[j] = shProg->Shaders[j]; 405848b8605Smrg } 406848b8605Smrg while (++i < n) { 407848b8605Smrg newList[j++] = shProg->Shaders[i]; 408848b8605Smrg } 409848b8605Smrg 410848b8605Smrg /* Free old list and install new one */ 411848b8605Smrg free(shProg->Shaders); 412848b8605Smrg shProg->Shaders = newList; 413848b8605Smrg shProg->NumShaders = n - 1; 414848b8605Smrg 415848b8605Smrg#ifdef DEBUG 416848b8605Smrg /* sanity check - make sure the new list's entries are sensible */ 417848b8605Smrg for (j = 0; j < shProg->NumShaders; j++) { 418848b8605Smrg assert(shProg->Shaders[j]->Type == GL_VERTEX_SHADER || 419848b8605Smrg shProg->Shaders[j]->Type == GL_GEOMETRY_SHADER || 420848b8605Smrg shProg->Shaders[j]->Type == GL_FRAGMENT_SHADER); 421848b8605Smrg assert(shProg->Shaders[j]->RefCount > 0); 422848b8605Smrg } 423848b8605Smrg#endif 424848b8605Smrg 425848b8605Smrg return; 426848b8605Smrg } 427848b8605Smrg } 428848b8605Smrg 429848b8605Smrg /* not found */ 430848b8605Smrg { 431848b8605Smrg GLenum err; 432848b8605Smrg if (is_shader(ctx, shader)) 433848b8605Smrg err = GL_INVALID_OPERATION; 434848b8605Smrg else if (is_program(ctx, shader)) 435848b8605Smrg err = GL_INVALID_OPERATION; 436848b8605Smrg else 437848b8605Smrg err = GL_INVALID_VALUE; 438848b8605Smrg _mesa_error(ctx, err, "glDetachShader(shader)"); 439848b8605Smrg return; 440848b8605Smrg } 441848b8605Smrg} 442848b8605Smrg 443848b8605Smrg 444848b8605Smrg/** 445848b8605Smrg * Return list of shaders attached to shader program. 446848b8605Smrg */ 447848b8605Smrgstatic void 448848b8605Smrgget_attached_shaders(struct gl_context *ctx, GLuint program, GLsizei maxCount, 449848b8605Smrg GLsizei *count, GLuint *obj) 450848b8605Smrg{ 451848b8605Smrg struct gl_shader_program *shProg = 452848b8605Smrg _mesa_lookup_shader_program_err(ctx, program, "glGetAttachedShaders"); 453848b8605Smrg if (shProg) { 454848b8605Smrg GLuint i; 455848b8605Smrg for (i = 0; i < (GLuint) maxCount && i < shProg->NumShaders; i++) { 456848b8605Smrg obj[i] = shProg->Shaders[i]->Name; 457848b8605Smrg } 458848b8605Smrg if (count) 459848b8605Smrg *count = i; 460848b8605Smrg } 461848b8605Smrg} 462848b8605Smrg 463848b8605Smrg 464848b8605Smrg/** 465848b8605Smrg * glGetHandleARB() - return ID/name of currently bound shader program. 466848b8605Smrg */ 467848b8605Smrgstatic GLuint 468848b8605Smrgget_handle(struct gl_context *ctx, GLenum pname) 469848b8605Smrg{ 470848b8605Smrg if (pname == GL_PROGRAM_OBJECT_ARB) { 471848b8605Smrg if (ctx->_Shader->ActiveProgram) 472848b8605Smrg return ctx->_Shader->ActiveProgram->Name; 473848b8605Smrg else 474848b8605Smrg return 0; 475848b8605Smrg } 476848b8605Smrg else { 477848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB"); 478848b8605Smrg return 0; 479848b8605Smrg } 480848b8605Smrg} 481848b8605Smrg 482848b8605Smrg 483848b8605Smrg/** 484848b8605Smrg * Check if a geometry shader query is valid at this time. If not, report an 485848b8605Smrg * error and return false. 486848b8605Smrg * 487848b8605Smrg * From GL 3.2 section 6.1.16 (Shader and Program Queries): 488848b8605Smrg * 489848b8605Smrg * "If GEOMETRY_VERTICES_OUT, GEOMETRY_INPUT_TYPE, or GEOMETRY_OUTPUT_TYPE 490848b8605Smrg * are queried for a program which has not been linked successfully, or 491848b8605Smrg * which does not contain objects to form a geometry shader, then an 492848b8605Smrg * INVALID_OPERATION error is generated." 493848b8605Smrg */ 494848b8605Smrgstatic bool 495848b8605Smrgcheck_gs_query(struct gl_context *ctx, const struct gl_shader_program *shProg) 496848b8605Smrg{ 497848b8605Smrg if (shProg->LinkStatus && 498848b8605Smrg shProg->_LinkedShaders[MESA_SHADER_GEOMETRY] != NULL) { 499848b8605Smrg return true; 500848b8605Smrg } 501848b8605Smrg 502848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 503848b8605Smrg "glGetProgramv(linked geometry shader required)"); 504848b8605Smrg return false; 505848b8605Smrg} 506848b8605Smrg 507848b8605Smrg 508848b8605Smrg/** 509848b8605Smrg * glGetProgramiv() - get shader program state. 510848b8605Smrg * Note that this is for GLSL shader programs, not ARB vertex/fragment 511848b8605Smrg * programs (see glGetProgramivARB). 512848b8605Smrg */ 513848b8605Smrgstatic void 514848b8605Smrgget_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *params) 515848b8605Smrg{ 516848b8605Smrg struct gl_shader_program *shProg 517848b8605Smrg = _mesa_lookup_shader_program(ctx, program); 518848b8605Smrg 519848b8605Smrg /* Is transform feedback available in this context? 520848b8605Smrg */ 521848b8605Smrg const bool has_xfb = 522848b8605Smrg (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.EXT_transform_feedback) 523848b8605Smrg || ctx->API == API_OPENGL_CORE 524848b8605Smrg || _mesa_is_gles3(ctx); 525848b8605Smrg 526848b8605Smrg /* True if geometry shaders (of the form that was adopted into GLSL 1.50 527848b8605Smrg * and GL 3.2) are available in this context 528848b8605Smrg */ 529848b8605Smrg const bool has_core_gs = _mesa_is_desktop_gl(ctx) && ctx->Version >= 32; 530848b8605Smrg 531848b8605Smrg /* Are uniform buffer objects available in this context? 532848b8605Smrg */ 533848b8605Smrg const bool has_ubo = 534848b8605Smrg (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.ARB_uniform_buffer_object) 535848b8605Smrg || ctx->API == API_OPENGL_CORE 536848b8605Smrg || _mesa_is_gles3(ctx); 537848b8605Smrg 538848b8605Smrg if (!shProg) { 539848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramiv(program)"); 540848b8605Smrg return; 541848b8605Smrg } 542848b8605Smrg 543848b8605Smrg switch (pname) { 544848b8605Smrg case GL_DELETE_STATUS: 545848b8605Smrg *params = shProg->DeletePending; 546848b8605Smrg return; 547848b8605Smrg case GL_LINK_STATUS: 548848b8605Smrg *params = shProg->LinkStatus; 549848b8605Smrg return; 550848b8605Smrg case GL_VALIDATE_STATUS: 551848b8605Smrg *params = shProg->Validated; 552848b8605Smrg return; 553848b8605Smrg case GL_INFO_LOG_LENGTH: 554848b8605Smrg *params = shProg->InfoLog ? strlen(shProg->InfoLog) + 1 : 0; 555848b8605Smrg return; 556848b8605Smrg case GL_ATTACHED_SHADERS: 557848b8605Smrg *params = shProg->NumShaders; 558848b8605Smrg return; 559848b8605Smrg case GL_ACTIVE_ATTRIBUTES: 560848b8605Smrg *params = _mesa_count_active_attribs(shProg); 561848b8605Smrg return; 562848b8605Smrg case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: 563848b8605Smrg *params = _mesa_longest_attribute_name_length(shProg); 564848b8605Smrg return; 565848b8605Smrg case GL_ACTIVE_UNIFORMS: 566848b8605Smrg *params = shProg->NumUserUniformStorage; 567848b8605Smrg return; 568848b8605Smrg case GL_ACTIVE_UNIFORM_MAX_LENGTH: { 569848b8605Smrg unsigned i; 570848b8605Smrg GLint max_len = 0; 571848b8605Smrg 572848b8605Smrg for (i = 0; i < shProg->NumUserUniformStorage; i++) { 573848b8605Smrg /* Add one for the terminating NUL character for a non-array, and 574848b8605Smrg * 4 for the "[0]" and the NUL for an array. 575848b8605Smrg */ 576848b8605Smrg const GLint len = strlen(shProg->UniformStorage[i].name) + 1 + 577848b8605Smrg ((shProg->UniformStorage[i].array_elements != 0) ? 3 : 0); 578848b8605Smrg 579848b8605Smrg if (len > max_len) 580848b8605Smrg max_len = len; 581848b8605Smrg } 582848b8605Smrg 583848b8605Smrg *params = max_len; 584848b8605Smrg return; 585848b8605Smrg } 586848b8605Smrg case GL_TRANSFORM_FEEDBACK_VARYINGS: 587848b8605Smrg if (!has_xfb) 588848b8605Smrg break; 589848b8605Smrg *params = shProg->TransformFeedback.NumVarying; 590848b8605Smrg return; 591848b8605Smrg case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: { 592848b8605Smrg unsigned i; 593848b8605Smrg GLint max_len = 0; 594848b8605Smrg if (!has_xfb) 595848b8605Smrg break; 596848b8605Smrg 597848b8605Smrg for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) { 598848b8605Smrg /* Add one for the terminating NUL character. 599848b8605Smrg */ 600848b8605Smrg const GLint len = strlen(shProg->TransformFeedback.VaryingNames[i]) + 1; 601848b8605Smrg 602848b8605Smrg if (len > max_len) 603848b8605Smrg max_len = len; 604848b8605Smrg } 605848b8605Smrg 606848b8605Smrg *params = max_len; 607848b8605Smrg return; 608848b8605Smrg } 609848b8605Smrg case GL_TRANSFORM_FEEDBACK_BUFFER_MODE: 610848b8605Smrg if (!has_xfb) 611848b8605Smrg break; 612848b8605Smrg *params = shProg->TransformFeedback.BufferMode; 613848b8605Smrg return; 614848b8605Smrg case GL_GEOMETRY_VERTICES_OUT: 615848b8605Smrg if (!has_core_gs) 616848b8605Smrg break; 617848b8605Smrg if (check_gs_query(ctx, shProg)) 618848b8605Smrg *params = shProg->Geom.VerticesOut; 619848b8605Smrg return; 620848b8605Smrg case GL_GEOMETRY_SHADER_INVOCATIONS: 621848b8605Smrg if (!has_core_gs || !ctx->Extensions.ARB_gpu_shader5) 622848b8605Smrg break; 623848b8605Smrg if (check_gs_query(ctx, shProg)) 624848b8605Smrg *params = shProg->Geom.Invocations; 625848b8605Smrg return; 626848b8605Smrg case GL_GEOMETRY_INPUT_TYPE: 627848b8605Smrg if (!has_core_gs) 628848b8605Smrg break; 629848b8605Smrg if (check_gs_query(ctx, shProg)) 630848b8605Smrg *params = shProg->Geom.InputType; 631848b8605Smrg return; 632848b8605Smrg case GL_GEOMETRY_OUTPUT_TYPE: 633848b8605Smrg if (!has_core_gs) 634848b8605Smrg break; 635848b8605Smrg if (check_gs_query(ctx, shProg)) 636848b8605Smrg *params = shProg->Geom.OutputType; 637848b8605Smrg return; 638848b8605Smrg case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: { 639848b8605Smrg unsigned i; 640848b8605Smrg GLint max_len = 0; 641848b8605Smrg 642848b8605Smrg if (!has_ubo) 643848b8605Smrg break; 644848b8605Smrg 645848b8605Smrg for (i = 0; i < shProg->NumUniformBlocks; i++) { 646848b8605Smrg /* Add one for the terminating NUL character. 647848b8605Smrg */ 648848b8605Smrg const GLint len = strlen(shProg->UniformBlocks[i].Name) + 1; 649848b8605Smrg 650848b8605Smrg if (len > max_len) 651848b8605Smrg max_len = len; 652848b8605Smrg } 653848b8605Smrg 654848b8605Smrg *params = max_len; 655848b8605Smrg return; 656848b8605Smrg } 657848b8605Smrg case GL_ACTIVE_UNIFORM_BLOCKS: 658848b8605Smrg if (!has_ubo) 659848b8605Smrg break; 660848b8605Smrg 661848b8605Smrg *params = shProg->NumUniformBlocks; 662848b8605Smrg return; 663848b8605Smrg case GL_PROGRAM_BINARY_RETRIEVABLE_HINT: 664848b8605Smrg /* This enum isn't part of the OES extension for OpenGL ES 2.0. It is 665848b8605Smrg * only available with desktop OpenGL 3.0+ with the 666848b8605Smrg * GL_ARB_get_program_binary extension or OpenGL ES 3.0. 667848b8605Smrg * 668848b8605Smrg * On desktop, we ignore the 3.0+ requirement because it is silly. 669848b8605Smrg */ 670848b8605Smrg if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 671848b8605Smrg break; 672848b8605Smrg 673848b8605Smrg *params = shProg->BinaryRetreivableHint; 674848b8605Smrg return; 675848b8605Smrg case GL_PROGRAM_BINARY_LENGTH: 676848b8605Smrg *params = 0; 677848b8605Smrg return; 678848b8605Smrg case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS: 679848b8605Smrg if (!ctx->Extensions.ARB_shader_atomic_counters) 680848b8605Smrg break; 681848b8605Smrg 682848b8605Smrg *params = shProg->NumAtomicBuffers; 683848b8605Smrg return; 684848b8605Smrg case GL_COMPUTE_WORK_GROUP_SIZE: { 685848b8605Smrg int i; 686848b8605Smrg if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_compute_shader) 687848b8605Smrg break; 688848b8605Smrg if (!shProg->LinkStatus) { 689848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramiv(program not " 690848b8605Smrg "linked)"); 691848b8605Smrg return; 692848b8605Smrg } 693848b8605Smrg if (shProg->_LinkedShaders[MESA_SHADER_COMPUTE] == NULL) { 694848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramiv(no compute " 695848b8605Smrg "shaders)"); 696848b8605Smrg return; 697848b8605Smrg } 698848b8605Smrg for (i = 0; i < 3; i++) 699848b8605Smrg params[i] = shProg->Comp.LocalSize[i]; 700848b8605Smrg return; 701848b8605Smrg } 702848b8605Smrg case GL_PROGRAM_SEPARABLE: 703848b8605Smrg *params = shProg->SeparateShader; 704848b8605Smrg return; 705848b8605Smrg default: 706848b8605Smrg break; 707848b8605Smrg } 708848b8605Smrg 709848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname=%s)", 710848b8605Smrg _mesa_lookup_enum_by_nr(pname)); 711848b8605Smrg} 712848b8605Smrg 713848b8605Smrg 714848b8605Smrg/** 715848b8605Smrg * glGetShaderiv() - get GLSL shader state 716848b8605Smrg */ 717848b8605Smrgstatic void 718848b8605Smrgget_shaderiv(struct gl_context *ctx, GLuint name, GLenum pname, GLint *params) 719848b8605Smrg{ 720848b8605Smrg struct gl_shader *shader = 721848b8605Smrg _mesa_lookup_shader_err(ctx, name, "glGetShaderiv"); 722848b8605Smrg 723848b8605Smrg if (!shader) { 724848b8605Smrg return; 725848b8605Smrg } 726848b8605Smrg 727848b8605Smrg switch (pname) { 728848b8605Smrg case GL_SHADER_TYPE: 729848b8605Smrg *params = shader->Type; 730848b8605Smrg break; 731848b8605Smrg case GL_DELETE_STATUS: 732848b8605Smrg *params = shader->DeletePending; 733848b8605Smrg break; 734848b8605Smrg case GL_COMPILE_STATUS: 735848b8605Smrg *params = shader->CompileStatus; 736848b8605Smrg break; 737848b8605Smrg case GL_INFO_LOG_LENGTH: 738848b8605Smrg *params = shader->InfoLog ? strlen(shader->InfoLog) + 1 : 0; 739848b8605Smrg break; 740848b8605Smrg case GL_SHADER_SOURCE_LENGTH: 741848b8605Smrg *params = shader->Source ? strlen((char *) shader->Source) + 1 : 0; 742848b8605Smrg break; 743848b8605Smrg default: 744848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)"); 745848b8605Smrg return; 746848b8605Smrg } 747848b8605Smrg} 748848b8605Smrg 749848b8605Smrg 750848b8605Smrgstatic void 751848b8605Smrgget_program_info_log(struct gl_context *ctx, GLuint program, GLsizei bufSize, 752848b8605Smrg GLsizei *length, GLchar *infoLog) 753848b8605Smrg{ 754848b8605Smrg struct gl_shader_program *shProg 755848b8605Smrg = _mesa_lookup_shader_program(ctx, program); 756848b8605Smrg if (!shProg) { 757848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramInfoLog(program)"); 758848b8605Smrg return; 759848b8605Smrg } 760848b8605Smrg _mesa_copy_string(infoLog, bufSize, length, shProg->InfoLog); 761848b8605Smrg} 762848b8605Smrg 763848b8605Smrg 764848b8605Smrgstatic void 765848b8605Smrgget_shader_info_log(struct gl_context *ctx, GLuint shader, GLsizei bufSize, 766848b8605Smrg GLsizei *length, GLchar *infoLog) 767848b8605Smrg{ 768848b8605Smrg struct gl_shader *sh = _mesa_lookup_shader(ctx, shader); 769848b8605Smrg if (!sh) { 770848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderInfoLog(shader)"); 771848b8605Smrg return; 772848b8605Smrg } 773848b8605Smrg _mesa_copy_string(infoLog, bufSize, length, sh->InfoLog); 774848b8605Smrg} 775848b8605Smrg 776848b8605Smrg 777848b8605Smrg/** 778848b8605Smrg * Return shader source code. 779848b8605Smrg */ 780848b8605Smrgstatic void 781848b8605Smrgget_shader_source(struct gl_context *ctx, GLuint shader, GLsizei maxLength, 782848b8605Smrg GLsizei *length, GLchar *sourceOut) 783848b8605Smrg{ 784848b8605Smrg struct gl_shader *sh; 785848b8605Smrg sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderSource"); 786848b8605Smrg if (!sh) { 787848b8605Smrg return; 788848b8605Smrg } 789848b8605Smrg _mesa_copy_string(sourceOut, maxLength, length, sh->Source); 790848b8605Smrg} 791848b8605Smrg 792848b8605Smrg 793848b8605Smrg/** 794848b8605Smrg * Set/replace shader source code. A helper function used by 795848b8605Smrg * glShaderSource[ARB]. 796848b8605Smrg */ 797848b8605Smrgstatic void 798848b8605Smrgshader_source(struct gl_context *ctx, GLuint shader, const GLchar *source) 799848b8605Smrg{ 800848b8605Smrg struct gl_shader *sh; 801848b8605Smrg 802848b8605Smrg sh = _mesa_lookup_shader_err(ctx, shader, "glShaderSource"); 803848b8605Smrg if (!sh) 804848b8605Smrg return; 805848b8605Smrg 806848b8605Smrg /* free old shader source string and install new one */ 807848b8605Smrg free((void *)sh->Source); 808848b8605Smrg sh->Source = source; 809848b8605Smrg sh->CompileStatus = GL_FALSE; 810848b8605Smrg#ifdef DEBUG 811848b8605Smrg sh->SourceChecksum = _mesa_str_checksum(sh->Source); 812848b8605Smrg#endif 813848b8605Smrg} 814848b8605Smrg 815848b8605Smrg 816848b8605Smrg/** 817848b8605Smrg * Compile a shader. 818848b8605Smrg */ 819848b8605Smrgstatic void 820848b8605Smrgcompile_shader(struct gl_context *ctx, GLuint shaderObj) 821848b8605Smrg{ 822848b8605Smrg struct gl_shader *sh; 823848b8605Smrg struct gl_shader_compiler_options *options; 824848b8605Smrg 825848b8605Smrg sh = _mesa_lookup_shader_err(ctx, shaderObj, "glCompileShader"); 826848b8605Smrg if (!sh) 827848b8605Smrg return; 828848b8605Smrg 829848b8605Smrg options = &ctx->Const.ShaderCompilerOptions[sh->Stage]; 830848b8605Smrg 831848b8605Smrg /* set default pragma state for shader */ 832848b8605Smrg sh->Pragmas = options->DefaultPragmas; 833848b8605Smrg 834848b8605Smrg if (!sh->Source) { 835848b8605Smrg /* If the user called glCompileShader without first calling 836848b8605Smrg * glShaderSource, we should fail to compile, but not raise a GL_ERROR. 837848b8605Smrg */ 838848b8605Smrg sh->CompileStatus = GL_FALSE; 839848b8605Smrg } else { 840848b8605Smrg if (ctx->_Shader->Flags & GLSL_DUMP) { 841848b8605Smrg fprintf(stderr, "GLSL source for %s shader %d:\n", 842848b8605Smrg _mesa_shader_stage_to_string(sh->Stage), sh->Name); 843848b8605Smrg fprintf(stderr, "%s\n", sh->Source); 844848b8605Smrg fflush(stderr); 845848b8605Smrg } 846848b8605Smrg 847848b8605Smrg /* this call will set the shader->CompileStatus field to indicate if 848848b8605Smrg * compilation was successful. 849848b8605Smrg */ 850848b8605Smrg _mesa_glsl_compile_shader(ctx, sh, false, false); 851848b8605Smrg 852848b8605Smrg if (ctx->_Shader->Flags & GLSL_LOG) { 853848b8605Smrg _mesa_write_shader_to_file(sh); 854848b8605Smrg } 855848b8605Smrg 856848b8605Smrg if (ctx->_Shader->Flags & GLSL_DUMP) { 857848b8605Smrg if (sh->CompileStatus) { 858848b8605Smrg fprintf(stderr, "GLSL IR for shader %d:\n", sh->Name); 859848b8605Smrg _mesa_print_ir(stderr, sh->ir, NULL); 860848b8605Smrg fprintf(stderr, "\n\n"); 861848b8605Smrg } else { 862848b8605Smrg fprintf(stderr, "GLSL shader %d failed to compile.\n", sh->Name); 863848b8605Smrg } 864848b8605Smrg if (sh->InfoLog && sh->InfoLog[0] != 0) { 865848b8605Smrg fprintf(stderr, "GLSL shader %d info log:\n", sh->Name); 866848b8605Smrg fprintf(stderr, "%s\n", sh->InfoLog); 867848b8605Smrg } 868848b8605Smrg fflush(stderr); 869848b8605Smrg } 870848b8605Smrg 871848b8605Smrg } 872848b8605Smrg 873848b8605Smrg if (!sh->CompileStatus) { 874848b8605Smrg if (ctx->_Shader->Flags & GLSL_DUMP_ON_ERROR) { 875848b8605Smrg fprintf(stderr, "GLSL source for %s shader %d:\n", 876848b8605Smrg _mesa_shader_stage_to_string(sh->Stage), sh->Name); 877848b8605Smrg fprintf(stderr, "%s\n", sh->Source); 878848b8605Smrg fprintf(stderr, "Info Log:\n%s\n", sh->InfoLog); 879848b8605Smrg fflush(stderr); 880848b8605Smrg } 881848b8605Smrg 882848b8605Smrg if (ctx->_Shader->Flags & GLSL_REPORT_ERRORS) { 883848b8605Smrg _mesa_debug(ctx, "Error compiling shader %u:\n%s\n", 884848b8605Smrg sh->Name, sh->InfoLog); 885848b8605Smrg } 886848b8605Smrg } 887848b8605Smrg} 888848b8605Smrg 889848b8605Smrg 890848b8605Smrg/** 891848b8605Smrg * Link a program's shaders. 892848b8605Smrg */ 893848b8605Smrgstatic void 894848b8605Smrglink_program(struct gl_context *ctx, GLuint program) 895848b8605Smrg{ 896848b8605Smrg struct gl_shader_program *shProg; 897848b8605Smrg 898848b8605Smrg shProg = _mesa_lookup_shader_program_err(ctx, program, "glLinkProgram"); 899848b8605Smrg if (!shProg) 900848b8605Smrg return; 901848b8605Smrg 902848b8605Smrg /* From the ARB_transform_feedback2 specification: 903848b8605Smrg * "The error INVALID_OPERATION is generated by LinkProgram if <program> is 904848b8605Smrg * the name of a program being used by one or more transform feedback 905848b8605Smrg * objects, even if the objects are not currently bound or are paused." 906848b8605Smrg */ 907848b8605Smrg if (_mesa_transform_feedback_is_using_program(ctx, shProg)) { 908848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 909848b8605Smrg "glLinkProgram(transform feedback is using the program)"); 910848b8605Smrg return; 911848b8605Smrg } 912848b8605Smrg 913848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PROGRAM); 914848b8605Smrg 915848b8605Smrg _mesa_glsl_link_shader(ctx, shProg); 916848b8605Smrg 917848b8605Smrg if (shProg->LinkStatus == GL_FALSE && 918848b8605Smrg (ctx->_Shader->Flags & GLSL_REPORT_ERRORS)) { 919848b8605Smrg _mesa_debug(ctx, "Error linking program %u:\n%s\n", 920848b8605Smrg shProg->Name, shProg->InfoLog); 921848b8605Smrg } 922848b8605Smrg 923848b8605Smrg /* debug code */ 924848b8605Smrg if (0) { 925848b8605Smrg GLuint i; 926848b8605Smrg 927848b8605Smrg printf("Link %u shaders in program %u: %s\n", 928848b8605Smrg shProg->NumShaders, shProg->Name, 929848b8605Smrg shProg->LinkStatus ? "Success" : "Failed"); 930848b8605Smrg 931848b8605Smrg for (i = 0; i < shProg->NumShaders; i++) { 932848b8605Smrg printf(" shader %u, type 0x%x\n", 933848b8605Smrg shProg->Shaders[i]->Name, 934848b8605Smrg shProg->Shaders[i]->Type); 935848b8605Smrg } 936848b8605Smrg } 937848b8605Smrg} 938848b8605Smrg 939848b8605Smrg 940848b8605Smrg/** 941848b8605Smrg * Print basic shader info (for debug). 942848b8605Smrg */ 943848b8605Smrgstatic void 944848b8605Smrgprint_shader_info(const struct gl_shader_program *shProg) 945848b8605Smrg{ 946848b8605Smrg GLuint i; 947848b8605Smrg 948848b8605Smrg printf("Mesa: glUseProgram(%u)\n", shProg->Name); 949848b8605Smrg for (i = 0; i < shProg->NumShaders; i++) { 950848b8605Smrg printf(" %s shader %u, checksum %u\n", 951848b8605Smrg _mesa_shader_stage_to_string(shProg->Shaders[i]->Stage), 952848b8605Smrg shProg->Shaders[i]->Name, 953848b8605Smrg shProg->Shaders[i]->SourceChecksum); 954848b8605Smrg } 955848b8605Smrg if (shProg->_LinkedShaders[MESA_SHADER_VERTEX]) 956848b8605Smrg printf(" vert prog %u\n", 957848b8605Smrg shProg->_LinkedShaders[MESA_SHADER_VERTEX]->Program->Id); 958848b8605Smrg if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]) 959848b8605Smrg printf(" frag prog %u\n", 960848b8605Smrg shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program->Id); 961848b8605Smrg if (shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]) 962848b8605Smrg printf(" geom prog %u\n", 963848b8605Smrg shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program->Id); 964848b8605Smrg} 965848b8605Smrg 966848b8605Smrg 967848b8605Smrg/** 968848b8605Smrg * Use the named shader program for subsequent glUniform calls 969848b8605Smrg */ 970848b8605Smrgvoid 971848b8605Smrg_mesa_active_program(struct gl_context *ctx, struct gl_shader_program *shProg, 972848b8605Smrg const char *caller) 973848b8605Smrg{ 974848b8605Smrg if ((shProg != NULL) && !shProg->LinkStatus) { 975848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 976848b8605Smrg "%s(program %u not linked)", caller, shProg->Name); 977848b8605Smrg return; 978848b8605Smrg } 979848b8605Smrg 980848b8605Smrg if (ctx->Shader.ActiveProgram != shProg) { 981848b8605Smrg _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, shProg); 982848b8605Smrg } 983848b8605Smrg} 984848b8605Smrg 985848b8605Smrg/** 986848b8605Smrg */ 987848b8605Smrgstatic void 988848b8605Smrguse_shader_program(struct gl_context *ctx, GLenum type, 989848b8605Smrg struct gl_shader_program *shProg, 990848b8605Smrg struct gl_pipeline_object *shTarget) 991848b8605Smrg{ 992848b8605Smrg struct gl_shader_program **target; 993848b8605Smrg gl_shader_stage stage = _mesa_shader_enum_to_shader_stage(type); 994848b8605Smrg 995848b8605Smrg target = &shTarget->CurrentProgram[stage]; 996848b8605Smrg if ((shProg == NULL) || (shProg->_LinkedShaders[stage] == NULL)) 997848b8605Smrg shProg = NULL; 998848b8605Smrg 999848b8605Smrg if (*target != shProg) { 1000848b8605Smrg /* Program is current, flush it */ 1001848b8605Smrg if (shTarget == ctx->_Shader) { 1002848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); 1003848b8605Smrg } 1004848b8605Smrg 1005848b8605Smrg /* If the shader is also bound as the current rendering shader, unbind 1006848b8605Smrg * it from that binding point as well. This ensures that the correct 1007848b8605Smrg * semantics of glDeleteProgram are maintained. 1008848b8605Smrg */ 1009848b8605Smrg switch (type) { 1010848b8605Smrg case GL_VERTEX_SHADER: 1011848b8605Smrg /* Empty for now. */ 1012848b8605Smrg break; 1013848b8605Smrg case GL_GEOMETRY_SHADER_ARB: 1014848b8605Smrg /* Empty for now. */ 1015848b8605Smrg break; 1016848b8605Smrg case GL_COMPUTE_SHADER: 1017848b8605Smrg /* Empty for now. */ 1018848b8605Smrg break; 1019848b8605Smrg case GL_FRAGMENT_SHADER: 1020848b8605Smrg if (*target == ctx->_Shader->_CurrentFragmentProgram) { 1021848b8605Smrg _mesa_reference_shader_program(ctx, 1022848b8605Smrg &ctx->_Shader->_CurrentFragmentProgram, 1023848b8605Smrg NULL); 1024848b8605Smrg } 1025848b8605Smrg break; 1026848b8605Smrg } 1027848b8605Smrg 1028848b8605Smrg _mesa_reference_shader_program(ctx, target, shProg); 1029848b8605Smrg return; 1030848b8605Smrg } 1031848b8605Smrg} 1032848b8605Smrg 1033848b8605Smrg/** 1034848b8605Smrg * Use the named shader program for subsequent rendering. 1035848b8605Smrg */ 1036848b8605Smrgvoid 1037848b8605Smrg_mesa_use_program(struct gl_context *ctx, struct gl_shader_program *shProg) 1038848b8605Smrg{ 1039848b8605Smrg use_shader_program(ctx, GL_VERTEX_SHADER, shProg, &ctx->Shader); 1040848b8605Smrg use_shader_program(ctx, GL_GEOMETRY_SHADER_ARB, shProg, &ctx->Shader); 1041848b8605Smrg use_shader_program(ctx, GL_FRAGMENT_SHADER, shProg, &ctx->Shader); 1042848b8605Smrg use_shader_program(ctx, GL_COMPUTE_SHADER, shProg, &ctx->Shader); 1043848b8605Smrg _mesa_active_program(ctx, shProg, "glUseProgram"); 1044848b8605Smrg 1045848b8605Smrg if (ctx->Driver.UseProgram) 1046848b8605Smrg ctx->Driver.UseProgram(ctx, shProg); 1047848b8605Smrg} 1048848b8605Smrg 1049848b8605Smrg 1050848b8605Smrg/** 1051848b8605Smrg * Do validation of the given shader program. 1052848b8605Smrg * \param errMsg returns error message if validation fails. 1053848b8605Smrg * \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg) 1054848b8605Smrg */ 1055848b8605Smrgstatic GLboolean 1056848b8605Smrgvalidate_shader_program(const struct gl_shader_program *shProg, 1057848b8605Smrg char *errMsg) 1058848b8605Smrg{ 1059848b8605Smrg if (!shProg->LinkStatus) { 1060848b8605Smrg return GL_FALSE; 1061848b8605Smrg } 1062848b8605Smrg 1063848b8605Smrg /* From the GL spec, a program is invalid if any of these are true: 1064848b8605Smrg 1065848b8605Smrg any two active samplers in the current program object are of 1066848b8605Smrg different types, but refer to the same texture image unit, 1067848b8605Smrg 1068848b8605Smrg any active sampler in the current program object refers to a texture 1069848b8605Smrg image unit where fixed-function fragment processing accesses a 1070848b8605Smrg texture target that does not match the sampler type, or 1071848b8605Smrg 1072848b8605Smrg the sum of the number of active samplers in the program and the 1073848b8605Smrg number of texture image units enabled for fixed-function fragment 1074848b8605Smrg processing exceeds the combined limit on the total number of texture 1075848b8605Smrg image units allowed. 1076848b8605Smrg */ 1077848b8605Smrg 1078848b8605Smrg 1079848b8605Smrg /* 1080848b8605Smrg * Check: any two active samplers in the current program object are of 1081848b8605Smrg * different types, but refer to the same texture image unit, 1082848b8605Smrg */ 1083848b8605Smrg if (!_mesa_sampler_uniforms_are_valid(shProg, errMsg, 100)) 1084848b8605Smrg return GL_FALSE; 1085848b8605Smrg 1086848b8605Smrg return GL_TRUE; 1087848b8605Smrg} 1088848b8605Smrg 1089848b8605Smrg 1090848b8605Smrg/** 1091848b8605Smrg * Called via glValidateProgram() 1092848b8605Smrg */ 1093848b8605Smrgstatic void 1094848b8605Smrgvalidate_program(struct gl_context *ctx, GLuint program) 1095848b8605Smrg{ 1096848b8605Smrg struct gl_shader_program *shProg; 1097848b8605Smrg char errMsg[100] = ""; 1098848b8605Smrg 1099848b8605Smrg shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram"); 1100848b8605Smrg if (!shProg) { 1101848b8605Smrg return; 1102848b8605Smrg } 1103848b8605Smrg 1104848b8605Smrg shProg->Validated = validate_shader_program(shProg, errMsg); 1105848b8605Smrg if (!shProg->Validated) { 1106848b8605Smrg /* update info log */ 1107848b8605Smrg if (shProg->InfoLog) { 1108848b8605Smrg ralloc_free(shProg->InfoLog); 1109848b8605Smrg } 1110848b8605Smrg shProg->InfoLog = ralloc_strdup(shProg, errMsg); 1111848b8605Smrg } 1112848b8605Smrg} 1113848b8605Smrg 1114848b8605Smrg 1115848b8605Smrg 1116848b8605Smrgvoid GLAPIENTRY 1117848b8605Smrg_mesa_AttachObjectARB(GLhandleARB program, GLhandleARB shader) 1118848b8605Smrg{ 1119848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1120848b8605Smrg attach_shader(ctx, program, shader); 1121848b8605Smrg} 1122848b8605Smrg 1123848b8605Smrg 1124848b8605Smrgvoid GLAPIENTRY 1125848b8605Smrg_mesa_AttachShader(GLuint program, GLuint shader) 1126848b8605Smrg{ 1127848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1128848b8605Smrg attach_shader(ctx, program, shader); 1129848b8605Smrg} 1130848b8605Smrg 1131848b8605Smrg 1132848b8605Smrgvoid GLAPIENTRY 1133848b8605Smrg_mesa_CompileShader(GLhandleARB shaderObj) 1134848b8605Smrg{ 1135848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1136848b8605Smrg if (MESA_VERBOSE & VERBOSE_API) 1137848b8605Smrg _mesa_debug(ctx, "glCompileShader %u\n", shaderObj); 1138848b8605Smrg compile_shader(ctx, shaderObj); 1139848b8605Smrg} 1140848b8605Smrg 1141848b8605Smrg 1142848b8605SmrgGLuint GLAPIENTRY 1143848b8605Smrg_mesa_CreateShader(GLenum type) 1144848b8605Smrg{ 1145848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1146848b8605Smrg if (MESA_VERBOSE & VERBOSE_API) 1147848b8605Smrg _mesa_debug(ctx, "glCreateShader %s\n", _mesa_lookup_enum_by_nr(type)); 1148848b8605Smrg return create_shader(ctx, type); 1149848b8605Smrg} 1150848b8605Smrg 1151848b8605Smrg 1152848b8605SmrgGLhandleARB GLAPIENTRY 1153848b8605Smrg_mesa_CreateShaderObjectARB(GLenum type) 1154848b8605Smrg{ 1155848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1156848b8605Smrg return create_shader(ctx, type); 1157848b8605Smrg} 1158848b8605Smrg 1159848b8605Smrg 1160848b8605SmrgGLuint GLAPIENTRY 1161848b8605Smrg_mesa_CreateProgram(void) 1162848b8605Smrg{ 1163848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1164848b8605Smrg if (MESA_VERBOSE & VERBOSE_API) 1165848b8605Smrg _mesa_debug(ctx, "glCreateProgram\n"); 1166848b8605Smrg return create_shader_program(ctx); 1167848b8605Smrg} 1168848b8605Smrg 1169848b8605Smrg 1170848b8605SmrgGLhandleARB GLAPIENTRY 1171848b8605Smrg_mesa_CreateProgramObjectARB(void) 1172848b8605Smrg{ 1173848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1174848b8605Smrg return create_shader_program(ctx); 1175848b8605Smrg} 1176848b8605Smrg 1177848b8605Smrg 1178848b8605Smrgvoid GLAPIENTRY 1179848b8605Smrg_mesa_DeleteObjectARB(GLhandleARB obj) 1180848b8605Smrg{ 1181848b8605Smrg if (MESA_VERBOSE & VERBOSE_API) { 1182848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1183848b8605Smrg _mesa_debug(ctx, "glDeleteObjectARB(%u)\n", obj); 1184848b8605Smrg } 1185848b8605Smrg 1186848b8605Smrg if (obj) { 1187848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1188848b8605Smrg FLUSH_VERTICES(ctx, 0); 1189848b8605Smrg if (is_program(ctx, obj)) { 1190848b8605Smrg delete_shader_program(ctx, obj); 1191848b8605Smrg } 1192848b8605Smrg else if (is_shader(ctx, obj)) { 1193848b8605Smrg delete_shader(ctx, obj); 1194848b8605Smrg } 1195848b8605Smrg else { 1196848b8605Smrg /* error? */ 1197848b8605Smrg } 1198848b8605Smrg } 1199848b8605Smrg} 1200848b8605Smrg 1201848b8605Smrg 1202848b8605Smrgvoid GLAPIENTRY 1203848b8605Smrg_mesa_DeleteProgram(GLuint name) 1204848b8605Smrg{ 1205848b8605Smrg if (name) { 1206848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1207848b8605Smrg FLUSH_VERTICES(ctx, 0); 1208848b8605Smrg delete_shader_program(ctx, name); 1209848b8605Smrg } 1210848b8605Smrg} 1211848b8605Smrg 1212848b8605Smrg 1213848b8605Smrgvoid GLAPIENTRY 1214848b8605Smrg_mesa_DeleteShader(GLuint name) 1215848b8605Smrg{ 1216848b8605Smrg if (name) { 1217848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1218848b8605Smrg FLUSH_VERTICES(ctx, 0); 1219848b8605Smrg delete_shader(ctx, name); 1220848b8605Smrg } 1221848b8605Smrg} 1222848b8605Smrg 1223848b8605Smrg 1224848b8605Smrgvoid GLAPIENTRY 1225848b8605Smrg_mesa_DetachObjectARB(GLhandleARB program, GLhandleARB shader) 1226848b8605Smrg{ 1227848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1228848b8605Smrg detach_shader(ctx, program, shader); 1229848b8605Smrg} 1230848b8605Smrg 1231848b8605Smrg 1232848b8605Smrgvoid GLAPIENTRY 1233848b8605Smrg_mesa_DetachShader(GLuint program, GLuint shader) 1234848b8605Smrg{ 1235848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1236848b8605Smrg detach_shader(ctx, program, shader); 1237848b8605Smrg} 1238848b8605Smrg 1239848b8605Smrg 1240848b8605Smrgvoid GLAPIENTRY 1241848b8605Smrg_mesa_GetAttachedObjectsARB(GLhandleARB container, GLsizei maxCount, 1242848b8605Smrg GLsizei * count, GLhandleARB * obj) 1243848b8605Smrg{ 1244848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1245848b8605Smrg get_attached_shaders(ctx, container, maxCount, count, obj); 1246848b8605Smrg} 1247848b8605Smrg 1248848b8605Smrg 1249848b8605Smrgvoid GLAPIENTRY 1250848b8605Smrg_mesa_GetAttachedShaders(GLuint program, GLsizei maxCount, 1251848b8605Smrg GLsizei *count, GLuint *obj) 1252848b8605Smrg{ 1253848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1254848b8605Smrg get_attached_shaders(ctx, program, maxCount, count, obj); 1255848b8605Smrg} 1256848b8605Smrg 1257848b8605Smrg 1258848b8605Smrgvoid GLAPIENTRY 1259848b8605Smrg_mesa_GetInfoLogARB(GLhandleARB object, GLsizei maxLength, GLsizei * length, 1260848b8605Smrg GLcharARB * infoLog) 1261848b8605Smrg{ 1262848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1263848b8605Smrg if (is_program(ctx, object)) { 1264848b8605Smrg get_program_info_log(ctx, object, maxLength, length, infoLog); 1265848b8605Smrg } 1266848b8605Smrg else if (is_shader(ctx, object)) { 1267848b8605Smrg get_shader_info_log(ctx, object, maxLength, length, infoLog); 1268848b8605Smrg } 1269848b8605Smrg else { 1270848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInfoLogARB"); 1271848b8605Smrg } 1272848b8605Smrg} 1273848b8605Smrg 1274848b8605Smrg 1275848b8605Smrgvoid GLAPIENTRY 1276848b8605Smrg_mesa_GetObjectParameterivARB(GLhandleARB object, GLenum pname, GLint *params) 1277848b8605Smrg{ 1278848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1279848b8605Smrg /* Implement in terms of GetProgramiv, GetShaderiv */ 1280848b8605Smrg if (is_program(ctx, object)) { 1281848b8605Smrg if (pname == GL_OBJECT_TYPE_ARB) { 1282848b8605Smrg *params = GL_PROGRAM_OBJECT_ARB; 1283848b8605Smrg } 1284848b8605Smrg else { 1285848b8605Smrg get_programiv(ctx, object, pname, params); 1286848b8605Smrg } 1287848b8605Smrg } 1288848b8605Smrg else if (is_shader(ctx, object)) { 1289848b8605Smrg if (pname == GL_OBJECT_TYPE_ARB) { 1290848b8605Smrg *params = GL_SHADER_OBJECT_ARB; 1291848b8605Smrg } 1292848b8605Smrg else { 1293848b8605Smrg get_shaderiv(ctx, object, pname, params); 1294848b8605Smrg } 1295848b8605Smrg } 1296848b8605Smrg else { 1297848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectParameterivARB"); 1298848b8605Smrg } 1299848b8605Smrg} 1300848b8605Smrg 1301848b8605Smrg 1302848b8605Smrgvoid GLAPIENTRY 1303848b8605Smrg_mesa_GetObjectParameterfvARB(GLhandleARB object, GLenum pname, 1304848b8605Smrg GLfloat *params) 1305848b8605Smrg{ 1306848b8605Smrg GLint iparams[1]; /* XXX is one element enough? */ 1307848b8605Smrg _mesa_GetObjectParameterivARB(object, pname, iparams); 1308848b8605Smrg params[0] = (GLfloat) iparams[0]; 1309848b8605Smrg} 1310848b8605Smrg 1311848b8605Smrg 1312848b8605Smrgvoid GLAPIENTRY 1313848b8605Smrg_mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params) 1314848b8605Smrg{ 1315848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1316848b8605Smrg get_programiv(ctx, program, pname, params); 1317848b8605Smrg} 1318848b8605Smrg 1319848b8605Smrg 1320848b8605Smrgvoid GLAPIENTRY 1321848b8605Smrg_mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params) 1322848b8605Smrg{ 1323848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1324848b8605Smrg get_shaderiv(ctx, shader, pname, params); 1325848b8605Smrg} 1326848b8605Smrg 1327848b8605Smrg 1328848b8605Smrgvoid GLAPIENTRY 1329848b8605Smrg_mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize, 1330848b8605Smrg GLsizei *length, GLchar *infoLog) 1331848b8605Smrg{ 1332848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1333848b8605Smrg get_program_info_log(ctx, program, bufSize, length, infoLog); 1334848b8605Smrg} 1335848b8605Smrg 1336848b8605Smrg 1337848b8605Smrgvoid GLAPIENTRY 1338848b8605Smrg_mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize, 1339848b8605Smrg GLsizei *length, GLchar *infoLog) 1340848b8605Smrg{ 1341848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1342848b8605Smrg get_shader_info_log(ctx, shader, bufSize, length, infoLog); 1343848b8605Smrg} 1344848b8605Smrg 1345848b8605Smrg 1346848b8605Smrgvoid GLAPIENTRY 1347848b8605Smrg_mesa_GetShaderSource(GLhandleARB shader, GLsizei maxLength, 1348848b8605Smrg GLsizei *length, GLcharARB *sourceOut) 1349848b8605Smrg{ 1350848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1351848b8605Smrg get_shader_source(ctx, shader, maxLength, length, sourceOut); 1352848b8605Smrg} 1353848b8605Smrg 1354848b8605Smrg 1355848b8605SmrgGLhandleARB GLAPIENTRY 1356848b8605Smrg_mesa_GetHandleARB(GLenum pname) 1357848b8605Smrg{ 1358848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1359848b8605Smrg return get_handle(ctx, pname); 1360848b8605Smrg} 1361848b8605Smrg 1362848b8605Smrg 1363848b8605SmrgGLboolean GLAPIENTRY 1364848b8605Smrg_mesa_IsProgram(GLuint name) 1365848b8605Smrg{ 1366848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1367848b8605Smrg return is_program(ctx, name); 1368848b8605Smrg} 1369848b8605Smrg 1370848b8605Smrg 1371848b8605SmrgGLboolean GLAPIENTRY 1372848b8605Smrg_mesa_IsShader(GLuint name) 1373848b8605Smrg{ 1374848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1375848b8605Smrg return is_shader(ctx, name); 1376848b8605Smrg} 1377848b8605Smrg 1378848b8605Smrg 1379848b8605Smrgvoid GLAPIENTRY 1380848b8605Smrg_mesa_LinkProgram(GLhandleARB programObj) 1381848b8605Smrg{ 1382848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1383848b8605Smrg link_program(ctx, programObj); 1384848b8605Smrg} 1385848b8605Smrg 1386848b8605Smrg 1387848b8605Smrg 1388848b8605Smrg/** 1389848b8605Smrg * Read shader source code from a file. 1390848b8605Smrg * Useful for debugging to override an app's shader. 1391848b8605Smrg */ 1392848b8605Smrgstatic GLcharARB * 1393848b8605Smrgread_shader(const char *fname) 1394848b8605Smrg{ 1395848b8605Smrg int shader_size = 0; 1396848b8605Smrg FILE *f = fopen(fname, "r"); 1397848b8605Smrg GLcharARB *buffer, *shader; 1398848b8605Smrg int len; 1399848b8605Smrg 1400848b8605Smrg if (!f) { 1401848b8605Smrg return NULL; 1402848b8605Smrg } 1403848b8605Smrg 1404848b8605Smrg /* allocate enough room for the entire shader */ 1405848b8605Smrg fseek(f, 0, SEEK_END); 1406848b8605Smrg shader_size = ftell(f); 1407848b8605Smrg rewind(f); 1408848b8605Smrg assert(shader_size); 1409848b8605Smrg 1410848b8605Smrg /* add one for terminating zero */ 1411848b8605Smrg shader_size++; 1412848b8605Smrg 1413848b8605Smrg buffer = malloc(shader_size); 1414848b8605Smrg assert(buffer); 1415848b8605Smrg 1416848b8605Smrg len = fread(buffer, 1, shader_size, f); 1417848b8605Smrg buffer[len] = 0; 1418848b8605Smrg 1419848b8605Smrg fclose(f); 1420848b8605Smrg 1421848b8605Smrg shader = _mesa_strdup(buffer); 1422848b8605Smrg free(buffer); 1423848b8605Smrg 1424848b8605Smrg return shader; 1425848b8605Smrg} 1426848b8605Smrg 1427848b8605Smrg 1428848b8605Smrg/** 1429848b8605Smrg * Called via glShaderSource() and glShaderSourceARB() API functions. 1430848b8605Smrg * Basically, concatenate the source code strings into one long string 1431848b8605Smrg * and pass it to _mesa_shader_source(). 1432848b8605Smrg */ 1433848b8605Smrgvoid GLAPIENTRY 1434848b8605Smrg_mesa_ShaderSource(GLhandleARB shaderObj, GLsizei count, 1435848b8605Smrg const GLcharARB * const * string, const GLint * length) 1436848b8605Smrg{ 1437848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1438848b8605Smrg GLint *offsets; 1439848b8605Smrg GLsizei i, totalLength; 1440848b8605Smrg GLcharARB *source; 1441848b8605Smrg GLuint checksum; 1442848b8605Smrg 1443848b8605Smrg if (!shaderObj || string == NULL) { 1444848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB"); 1445848b8605Smrg return; 1446848b8605Smrg } 1447848b8605Smrg 1448848b8605Smrg /* 1449848b8605Smrg * This array holds offsets of where the appropriate string ends, thus the 1450848b8605Smrg * last element will be set to the total length of the source code. 1451848b8605Smrg */ 1452848b8605Smrg offsets = malloc(count * sizeof(GLint)); 1453848b8605Smrg if (offsets == NULL) { 1454848b8605Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB"); 1455848b8605Smrg return; 1456848b8605Smrg } 1457848b8605Smrg 1458848b8605Smrg for (i = 0; i < count; i++) { 1459848b8605Smrg if (string[i] == NULL) { 1460848b8605Smrg free((GLvoid *) offsets); 1461848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 1462848b8605Smrg "glShaderSourceARB(null string)"); 1463848b8605Smrg return; 1464848b8605Smrg } 1465848b8605Smrg if (length == NULL || length[i] < 0) 1466848b8605Smrg offsets[i] = strlen(string[i]); 1467848b8605Smrg else 1468848b8605Smrg offsets[i] = length[i]; 1469848b8605Smrg /* accumulate string lengths */ 1470848b8605Smrg if (i > 0) 1471848b8605Smrg offsets[i] += offsets[i - 1]; 1472848b8605Smrg } 1473848b8605Smrg 1474848b8605Smrg /* Total length of source string is sum off all strings plus two. 1475848b8605Smrg * One extra byte for terminating zero, another extra byte to silence 1476848b8605Smrg * valgrind warnings in the parser/grammer code. 1477848b8605Smrg */ 1478848b8605Smrg totalLength = offsets[count - 1] + 2; 1479848b8605Smrg source = malloc(totalLength * sizeof(GLcharARB)); 1480848b8605Smrg if (source == NULL) { 1481848b8605Smrg free((GLvoid *) offsets); 1482848b8605Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB"); 1483848b8605Smrg return; 1484848b8605Smrg } 1485848b8605Smrg 1486848b8605Smrg for (i = 0; i < count; i++) { 1487848b8605Smrg GLint start = (i > 0) ? offsets[i - 1] : 0; 1488848b8605Smrg memcpy(source + start, string[i], 1489848b8605Smrg (offsets[i] - start) * sizeof(GLcharARB)); 1490848b8605Smrg } 1491848b8605Smrg source[totalLength - 1] = '\0'; 1492848b8605Smrg source[totalLength - 2] = '\0'; 1493848b8605Smrg 1494848b8605Smrg if (SHADER_SUBST) { 1495848b8605Smrg /* Compute the shader's source code checksum then try to open a file 1496848b8605Smrg * named newshader_<CHECKSUM>. If it exists, use it in place of the 1497848b8605Smrg * original shader source code. For debugging. 1498848b8605Smrg */ 1499848b8605Smrg char filename[100]; 1500848b8605Smrg GLcharARB *newSource; 1501848b8605Smrg 1502848b8605Smrg checksum = _mesa_str_checksum(source); 1503848b8605Smrg 1504848b8605Smrg _mesa_snprintf(filename, sizeof(filename), "newshader_%d", checksum); 1505848b8605Smrg 1506848b8605Smrg newSource = read_shader(filename); 1507848b8605Smrg if (newSource) { 1508848b8605Smrg fprintf(stderr, "Mesa: Replacing shader %u chksum=%d with %s\n", 1509848b8605Smrg shaderObj, checksum, filename); 1510848b8605Smrg free(source); 1511848b8605Smrg source = newSource; 1512848b8605Smrg } 1513848b8605Smrg } 1514848b8605Smrg 1515848b8605Smrg shader_source(ctx, shaderObj, source); 1516848b8605Smrg 1517848b8605Smrg if (SHADER_SUBST) { 1518848b8605Smrg struct gl_shader *sh = _mesa_lookup_shader(ctx, shaderObj); 1519848b8605Smrg if (sh) 1520848b8605Smrg sh->SourceChecksum = checksum; /* save original checksum */ 1521848b8605Smrg } 1522848b8605Smrg 1523848b8605Smrg free(offsets); 1524848b8605Smrg} 1525848b8605Smrg 1526848b8605Smrg 1527848b8605Smrgvoid GLAPIENTRY 1528848b8605Smrg_mesa_UseProgram(GLhandleARB program) 1529848b8605Smrg{ 1530848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1531848b8605Smrg struct gl_shader_program *shProg; 1532848b8605Smrg 1533848b8605Smrg if (_mesa_is_xfb_active_and_unpaused(ctx)) { 1534848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 1535848b8605Smrg "glUseProgram(transform feedback active)"); 1536848b8605Smrg return; 1537848b8605Smrg } 1538848b8605Smrg 1539848b8605Smrg if (program) { 1540848b8605Smrg shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram"); 1541848b8605Smrg if (!shProg) { 1542848b8605Smrg return; 1543848b8605Smrg } 1544848b8605Smrg if (!shProg->LinkStatus) { 1545848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 1546848b8605Smrg "glUseProgram(program %u not linked)", program); 1547848b8605Smrg return; 1548848b8605Smrg } 1549848b8605Smrg 1550848b8605Smrg /* debug code */ 1551848b8605Smrg if (ctx->_Shader->Flags & GLSL_USE_PROG) { 1552848b8605Smrg print_shader_info(shProg); 1553848b8605Smrg } 1554848b8605Smrg } 1555848b8605Smrg else { 1556848b8605Smrg shProg = NULL; 1557848b8605Smrg } 1558848b8605Smrg 1559848b8605Smrg /* The ARB_separate_shader_object spec says: 1560848b8605Smrg * 1561848b8605Smrg * "The executable code for an individual shader stage is taken from 1562848b8605Smrg * the current program for that stage. If there is a current program 1563848b8605Smrg * object established by UseProgram, that program is considered current 1564848b8605Smrg * for all stages. Otherwise, if there is a bound program pipeline 1565848b8605Smrg * object (section 2.14.PPO), the program bound to the appropriate 1566848b8605Smrg * stage of the pipeline object is considered current." 1567848b8605Smrg */ 1568848b8605Smrg if (program) { 1569848b8605Smrg /* Attach shader state to the binding point */ 1570848b8605Smrg _mesa_reference_pipeline_object(ctx, &ctx->_Shader, &ctx->Shader); 1571848b8605Smrg /* Update the program */ 1572848b8605Smrg _mesa_use_program(ctx, shProg); 1573848b8605Smrg } else { 1574848b8605Smrg /* Must be done first: detach the progam */ 1575848b8605Smrg _mesa_use_program(ctx, shProg); 1576848b8605Smrg /* Unattach shader_state binding point */ 1577848b8605Smrg _mesa_reference_pipeline_object(ctx, &ctx->_Shader, ctx->Pipeline.Default); 1578848b8605Smrg /* If a pipeline was bound, rebind it */ 1579848b8605Smrg if (ctx->Pipeline.Current) { 1580848b8605Smrg _mesa_BindProgramPipeline(ctx->Pipeline.Current->Name); 1581848b8605Smrg } 1582848b8605Smrg } 1583848b8605Smrg} 1584848b8605Smrg 1585848b8605Smrg 1586848b8605Smrgvoid GLAPIENTRY 1587848b8605Smrg_mesa_ValidateProgram(GLhandleARB program) 1588848b8605Smrg{ 1589848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1590848b8605Smrg validate_program(ctx, program); 1591848b8605Smrg} 1592848b8605Smrg 1593848b8605Smrg 1594848b8605Smrg/** 1595848b8605Smrg * For OpenGL ES 2.0, GL_ARB_ES2_compatibility 1596848b8605Smrg */ 1597848b8605Smrgvoid GLAPIENTRY 1598848b8605Smrg_mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, 1599848b8605Smrg GLint* range, GLint* precision) 1600848b8605Smrg{ 1601848b8605Smrg const struct gl_program_constants *limits; 1602848b8605Smrg const struct gl_precision *p; 1603848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1604848b8605Smrg 1605848b8605Smrg switch (shadertype) { 1606848b8605Smrg case GL_VERTEX_SHADER: 1607848b8605Smrg limits = &ctx->Const.Program[MESA_SHADER_VERTEX]; 1608848b8605Smrg break; 1609848b8605Smrg case GL_FRAGMENT_SHADER: 1610848b8605Smrg limits = &ctx->Const.Program[MESA_SHADER_FRAGMENT]; 1611848b8605Smrg break; 1612848b8605Smrg default: 1613848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, 1614848b8605Smrg "glGetShaderPrecisionFormat(shadertype)"); 1615848b8605Smrg return; 1616848b8605Smrg } 1617848b8605Smrg 1618848b8605Smrg switch (precisiontype) { 1619848b8605Smrg case GL_LOW_FLOAT: 1620848b8605Smrg p = &limits->LowFloat; 1621848b8605Smrg break; 1622848b8605Smrg case GL_MEDIUM_FLOAT: 1623848b8605Smrg p = &limits->MediumFloat; 1624848b8605Smrg break; 1625848b8605Smrg case GL_HIGH_FLOAT: 1626848b8605Smrg p = &limits->HighFloat; 1627848b8605Smrg break; 1628848b8605Smrg case GL_LOW_INT: 1629848b8605Smrg p = &limits->LowInt; 1630848b8605Smrg break; 1631848b8605Smrg case GL_MEDIUM_INT: 1632848b8605Smrg p = &limits->MediumInt; 1633848b8605Smrg break; 1634848b8605Smrg case GL_HIGH_INT: 1635848b8605Smrg p = &limits->HighInt; 1636848b8605Smrg break; 1637848b8605Smrg default: 1638848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, 1639848b8605Smrg "glGetShaderPrecisionFormat(precisiontype)"); 1640848b8605Smrg return; 1641848b8605Smrg } 1642848b8605Smrg 1643848b8605Smrg range[0] = p->RangeMin; 1644848b8605Smrg range[1] = p->RangeMax; 1645848b8605Smrg precision[0] = p->Precision; 1646848b8605Smrg} 1647848b8605Smrg 1648848b8605Smrg 1649848b8605Smrg/** 1650848b8605Smrg * For OpenGL ES 2.0, GL_ARB_ES2_compatibility 1651848b8605Smrg */ 1652848b8605Smrgvoid GLAPIENTRY 1653848b8605Smrg_mesa_ReleaseShaderCompiler(void) 1654848b8605Smrg{ 1655848b8605Smrg _mesa_destroy_shader_compiler_caches(); 1656848b8605Smrg} 1657848b8605Smrg 1658848b8605Smrg 1659848b8605Smrg/** 1660848b8605Smrg * For OpenGL ES 2.0, GL_ARB_ES2_compatibility 1661848b8605Smrg */ 1662848b8605Smrgvoid GLAPIENTRY 1663848b8605Smrg_mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat, 1664848b8605Smrg const void* binary, GLint length) 1665848b8605Smrg{ 1666848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1667848b8605Smrg (void) n; 1668848b8605Smrg (void) shaders; 1669848b8605Smrg (void) binaryformat; 1670848b8605Smrg (void) binary; 1671848b8605Smrg (void) length; 1672848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__); 1673848b8605Smrg} 1674848b8605Smrg 1675848b8605Smrg 1676848b8605Smrgvoid GLAPIENTRY 1677848b8605Smrg_mesa_GetProgramBinary(GLuint program, GLsizei bufSize, GLsizei *length, 1678848b8605Smrg GLenum *binaryFormat, GLvoid *binary) 1679848b8605Smrg{ 1680848b8605Smrg struct gl_shader_program *shProg; 1681848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1682848b8605Smrg 1683848b8605Smrg shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetProgramBinary"); 1684848b8605Smrg if (!shProg) 1685848b8605Smrg return; 1686848b8605Smrg 1687848b8605Smrg if (!shProg->LinkStatus) { 1688848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 1689848b8605Smrg "glGetProgramBinary(program %u not linked)", 1690848b8605Smrg shProg->Name); 1691848b8605Smrg return; 1692848b8605Smrg } 1693848b8605Smrg 1694848b8605Smrg if (bufSize < 0){ 1695848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramBinary(bufSize < 0)"); 1696848b8605Smrg return; 1697848b8605Smrg } 1698848b8605Smrg 1699848b8605Smrg /* The ARB_get_program_binary spec says: 1700848b8605Smrg * 1701848b8605Smrg * "If <length> is NULL, then no length is returned." 1702848b8605Smrg */ 1703848b8605Smrg if (length != NULL) 1704848b8605Smrg *length = 0; 1705848b8605Smrg 1706848b8605Smrg (void) binaryFormat; 1707848b8605Smrg (void) binary; 1708848b8605Smrg} 1709848b8605Smrg 1710848b8605Smrgvoid GLAPIENTRY 1711848b8605Smrg_mesa_ProgramBinary(GLuint program, GLenum binaryFormat, 1712848b8605Smrg const GLvoid *binary, GLsizei length) 1713848b8605Smrg{ 1714848b8605Smrg struct gl_shader_program *shProg; 1715848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1716848b8605Smrg 1717848b8605Smrg shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramBinary"); 1718848b8605Smrg if (!shProg) 1719848b8605Smrg return; 1720848b8605Smrg 1721848b8605Smrg (void) binaryFormat; 1722848b8605Smrg (void) binary; 1723848b8605Smrg (void) length; 1724848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__); 1725848b8605Smrg} 1726848b8605Smrg 1727848b8605Smrg 1728848b8605Smrgvoid GLAPIENTRY 1729848b8605Smrg_mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value) 1730848b8605Smrg{ 1731848b8605Smrg struct gl_shader_program *shProg; 1732848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1733848b8605Smrg 1734848b8605Smrg shProg = _mesa_lookup_shader_program_err(ctx, program, 1735848b8605Smrg "glProgramParameteri"); 1736848b8605Smrg if (!shProg) 1737848b8605Smrg return; 1738848b8605Smrg 1739848b8605Smrg switch (pname) { 1740848b8605Smrg case GL_PROGRAM_BINARY_RETRIEVABLE_HINT: 1741848b8605Smrg /* This enum isn't part of the OES extension for OpenGL ES 2.0, but it 1742848b8605Smrg * is part of OpenGL ES 3.0. For the ES2 case, this function shouldn't 1743848b8605Smrg * even be in the dispatch table, so we shouldn't need to expclicitly 1744848b8605Smrg * check here. 1745848b8605Smrg * 1746848b8605Smrg * On desktop, we ignore the 3.0+ requirement because it is silly. 1747848b8605Smrg */ 1748848b8605Smrg 1749848b8605Smrg /* The ARB_get_program_binary extension spec says: 1750848b8605Smrg * 1751848b8605Smrg * "An INVALID_VALUE error is generated if the <value> argument to 1752848b8605Smrg * ProgramParameteri is not TRUE or FALSE." 1753848b8605Smrg */ 1754848b8605Smrg if (value != GL_TRUE && value != GL_FALSE) { 1755848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, 1756848b8605Smrg "glProgramParameteri(pname=%s, value=%d): " 1757848b8605Smrg "value must be 0 or 1.", 1758848b8605Smrg _mesa_lookup_enum_by_nr(pname), 1759848b8605Smrg value); 1760848b8605Smrg return; 1761848b8605Smrg } 1762848b8605Smrg 1763848b8605Smrg /* No need to notify the driver. Any changes will actually take effect 1764848b8605Smrg * the next time the shader is linked. 1765848b8605Smrg * 1766848b8605Smrg * The ARB_get_program_binary extension spec says: 1767848b8605Smrg * 1768848b8605Smrg * "To indicate that a program binary is likely to be retrieved, 1769848b8605Smrg * ProgramParameteri should be called with <pname> 1770848b8605Smrg * PROGRAM_BINARY_RETRIEVABLE_HINT and <value> TRUE. This setting 1771848b8605Smrg * will not be in effect until the next time LinkProgram or 1772848b8605Smrg * ProgramBinary has been called successfully." 1773848b8605Smrg * 1774848b8605Smrg * The resloution of issue 9 in the extension spec also says: 1775848b8605Smrg * 1776848b8605Smrg * "The application may use the PROGRAM_BINARY_RETRIEVABLE_HINT hint 1777848b8605Smrg * to indicate to the GL implementation that this program will 1778848b8605Smrg * likely be saved with GetProgramBinary at some point. This will 1779848b8605Smrg * give the GL implementation the opportunity to track any state 1780848b8605Smrg * changes made to the program before being saved such that when it 1781848b8605Smrg * is loaded again a recompile can be avoided." 1782848b8605Smrg */ 1783848b8605Smrg shProg->BinaryRetreivableHint = value; 1784848b8605Smrg return; 1785848b8605Smrg 1786848b8605Smrg case GL_PROGRAM_SEPARABLE: 1787848b8605Smrg /* Spec imply that the behavior is the same as ARB_get_program_binary 1788848b8605Smrg * Chapter 7.3 Program Objects 1789848b8605Smrg */ 1790848b8605Smrg if (value != GL_TRUE && value != GL_FALSE) { 1791848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, 1792848b8605Smrg "glProgramParameteri(pname=%s, value=%d): " 1793848b8605Smrg "value must be 0 or 1.", 1794848b8605Smrg _mesa_lookup_enum_by_nr(pname), 1795848b8605Smrg value); 1796848b8605Smrg return; 1797848b8605Smrg } 1798848b8605Smrg shProg->SeparateShader = value; 1799848b8605Smrg return; 1800848b8605Smrg 1801848b8605Smrg default: 1802848b8605Smrg break; 1803848b8605Smrg } 1804848b8605Smrg 1805848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameteri(pname=%s)", 1806848b8605Smrg _mesa_lookup_enum_by_nr(pname)); 1807848b8605Smrg} 1808848b8605Smrg 1809848b8605Smrgvoid 1810848b8605Smrg_mesa_use_shader_program(struct gl_context *ctx, GLenum type, 1811848b8605Smrg struct gl_shader_program *shProg, 1812848b8605Smrg struct gl_pipeline_object *shTarget) 1813848b8605Smrg{ 1814848b8605Smrg use_shader_program(ctx, type, shProg, shTarget); 1815848b8605Smrg 1816848b8605Smrg if (ctx->Driver.UseProgram) 1817848b8605Smrg ctx->Driver.UseProgram(ctx, shProg); 1818848b8605Smrg} 1819848b8605Smrg 1820848b8605Smrg 1821848b8605Smrgstatic GLuint 1822848b8605Smrg_mesa_create_shader_program(struct gl_context* ctx, GLboolean separate, 1823848b8605Smrg GLenum type, GLsizei count, const GLchar* const *strings) 1824848b8605Smrg{ 1825848b8605Smrg const GLuint shader = create_shader(ctx, type); 1826848b8605Smrg GLuint program = 0; 1827848b8605Smrg 1828848b8605Smrg if (shader) { 1829848b8605Smrg _mesa_ShaderSource(shader, count, strings, NULL); 1830848b8605Smrg 1831848b8605Smrg compile_shader(ctx, shader); 1832848b8605Smrg 1833848b8605Smrg program = create_shader_program(ctx); 1834848b8605Smrg if (program) { 1835848b8605Smrg struct gl_shader_program *shProg; 1836848b8605Smrg struct gl_shader *sh; 1837848b8605Smrg GLint compiled = GL_FALSE; 1838848b8605Smrg 1839848b8605Smrg shProg = _mesa_lookup_shader_program(ctx, program); 1840848b8605Smrg sh = _mesa_lookup_shader(ctx, shader); 1841848b8605Smrg 1842848b8605Smrg shProg->SeparateShader = separate; 1843848b8605Smrg 1844848b8605Smrg get_shaderiv(ctx, shader, GL_COMPILE_STATUS, &compiled); 1845848b8605Smrg if (compiled) { 1846848b8605Smrg attach_shader(ctx, program, shader); 1847848b8605Smrg link_program(ctx, program); 1848848b8605Smrg detach_shader(ctx, program, shader); 1849848b8605Smrg 1850848b8605Smrg#if 0 1851848b8605Smrg /* Possibly... */ 1852848b8605Smrg if (active-user-defined-varyings-in-linked-program) { 1853848b8605Smrg append-error-to-info-log; 1854848b8605Smrg shProg->LinkStatus = GL_FALSE; 1855848b8605Smrg } 1856848b8605Smrg#endif 1857848b8605Smrg } 1858848b8605Smrg 1859848b8605Smrg ralloc_strcat(&shProg->InfoLog, sh->InfoLog); 1860848b8605Smrg } 1861848b8605Smrg 1862848b8605Smrg delete_shader(ctx, shader); 1863848b8605Smrg } 1864848b8605Smrg 1865848b8605Smrg return program; 1866848b8605Smrg} 1867848b8605Smrg 1868848b8605Smrg 1869848b8605Smrg/** 1870848b8605Smrg * Copy program-specific data generated by linking from the gl_shader_program 1871848b8605Smrg * object to a specific gl_program object. 1872848b8605Smrg */ 1873848b8605Smrgvoid 1874848b8605Smrg_mesa_copy_linked_program_data(gl_shader_stage type, 1875848b8605Smrg const struct gl_shader_program *src, 1876848b8605Smrg struct gl_program *dst) 1877848b8605Smrg{ 1878848b8605Smrg switch (type) { 1879848b8605Smrg case MESA_SHADER_VERTEX: 1880848b8605Smrg dst->UsesClipDistanceOut = src->Vert.UsesClipDistance; 1881848b8605Smrg break; 1882848b8605Smrg case MESA_SHADER_GEOMETRY: { 1883848b8605Smrg struct gl_geometry_program *dst_gp = (struct gl_geometry_program *) dst; 1884848b8605Smrg dst_gp->VerticesIn = src->Geom.VerticesIn; 1885848b8605Smrg dst_gp->VerticesOut = src->Geom.VerticesOut; 1886848b8605Smrg dst_gp->Invocations = src->Geom.Invocations; 1887848b8605Smrg dst_gp->InputType = src->Geom.InputType; 1888848b8605Smrg dst_gp->OutputType = src->Geom.OutputType; 1889848b8605Smrg dst->UsesClipDistanceOut = src->Geom.UsesClipDistance; 1890848b8605Smrg dst_gp->UsesEndPrimitive = src->Geom.UsesEndPrimitive; 1891848b8605Smrg dst_gp->UsesStreams = src->Geom.UsesStreams; 1892848b8605Smrg } 1893848b8605Smrg break; 1894848b8605Smrg case MESA_SHADER_FRAGMENT: { 1895848b8605Smrg struct gl_fragment_program *dst_fp = (struct gl_fragment_program *) dst; 1896848b8605Smrg dst_fp->FragDepthLayout = src->FragDepthLayout; 1897848b8605Smrg } 1898848b8605Smrg break; 1899848b8605Smrg case MESA_SHADER_COMPUTE: { 1900848b8605Smrg struct gl_compute_program *dst_cp = (struct gl_compute_program *) dst; 1901848b8605Smrg int i; 1902848b8605Smrg for (i = 0; i < 3; i++) 1903848b8605Smrg dst_cp->LocalSize[i] = src->Comp.LocalSize[i]; 1904848b8605Smrg } 1905848b8605Smrg break; 1906848b8605Smrg default: 1907848b8605Smrg break; 1908848b8605Smrg } 1909848b8605Smrg} 1910848b8605Smrg 1911848b8605Smrg/** 1912848b8605Smrg * ARB_separate_shader_objects: Compile & Link Program 1913848b8605Smrg */ 1914848b8605SmrgGLuint GLAPIENTRY 1915848b8605Smrg_mesa_CreateShaderProgramv(GLenum type, GLsizei count, 1916848b8605Smrg const GLchar* const *strings) 1917848b8605Smrg{ 1918848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1919848b8605Smrg 1920848b8605Smrg return _mesa_create_shader_program(ctx, GL_TRUE, type, count, strings); 1921848b8605Smrg} 1922