shaderapi.c revision b63f8f7906e4bc8a074cee8dbdbcb1c66e90448f
1/* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 2004-2008 Brian Paul All Rights Reserved. 5 * Copyright (C) 2009-2010 VMware, Inc. All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25/** 26 * \file shaderapi.c 27 * \author Brian Paul 28 * 29 * Implementation of GLSL-related API functions. 30 * The glUniform* functions are in uniforms.c 31 * 32 * 33 * XXX things to do: 34 * 1. Check that the right error code is generated for all _mesa_error() calls. 35 * 2. Insert FLUSH_VERTICES calls in various places 36 */ 37 38 39#include "main/glheader.h" 40#include "main/context.h" 41#include "main/dispatch.h" 42#include "main/enums.h" 43#include "main/hash.h" 44#include "main/mfeatures.h" 45#include "main/mtypes.h" 46#include "main/shaderapi.h" 47#include "main/shaderobj.h" 48#include "main/uniforms.h" 49#include "program/program.h" 50#include "program/prog_parameter.h" 51#include "ralloc.h" 52#include <stdbool.h> 53#include "../glsl/glsl_parser_extras.h" 54#include "../glsl/ir_uniform.h" 55 56/** Define this to enable shader substitution (see below) */ 57#define SHADER_SUBST 0 58 59 60/** 61 * Return mask of GLSL_x flags by examining the MESA_GLSL env var. 62 */ 63static GLbitfield 64get_shader_flags(void) 65{ 66 GLbitfield flags = 0x0; 67 const char *env = _mesa_getenv("MESA_GLSL"); 68 69 if (env) { 70 if (strstr(env, "dump")) 71 flags |= GLSL_DUMP; 72 if (strstr(env, "log")) 73 flags |= GLSL_LOG; 74 if (strstr(env, "nopvert")) 75 flags |= GLSL_NOP_VERT; 76 if (strstr(env, "nopfrag")) 77 flags |= GLSL_NOP_FRAG; 78 if (strstr(env, "nopt")) 79 flags |= GLSL_NO_OPT; 80 else if (strstr(env, "opt")) 81 flags |= GLSL_OPT; 82 if (strstr(env, "uniform")) 83 flags |= GLSL_UNIFORMS; 84 if (strstr(env, "useprog")) 85 flags |= GLSL_USE_PROG; 86 if (strstr(env, "errors")) 87 flags |= GLSL_REPORT_ERRORS; 88 } 89 90 return flags; 91} 92 93 94/** 95 * Initialize context's shader state. 96 */ 97void 98_mesa_init_shader_state(struct gl_context *ctx) 99{ 100 /* Device drivers may override these to control what kind of instructions 101 * are generated by the GLSL compiler. 102 */ 103 struct gl_shader_compiler_options options; 104 gl_shader_type sh; 105 106 memset(&options, 0, sizeof(options)); 107 options.MaxUnrollIterations = 32; 108 options.MaxIfDepth = UINT_MAX; 109 110 /* Default pragma settings */ 111 options.DefaultPragmas.Optimize = GL_TRUE; 112 113 for (sh = 0; sh < MESA_SHADER_TYPES; ++sh) 114 memcpy(&ctx->ShaderCompilerOptions[sh], &options, sizeof(options)); 115 116 ctx->Shader.Flags = get_shader_flags(); 117} 118 119 120/** 121 * Free the per-context shader-related state. 122 */ 123void 124_mesa_free_shader_state(struct gl_context *ctx) 125{ 126 _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentVertexProgram, NULL); 127 _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentGeometryProgram, 128 NULL); 129 _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentFragmentProgram, 130 NULL); 131 _mesa_reference_shader_program(ctx, &ctx->Shader._CurrentFragmentProgram, 132 NULL); 133 _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, NULL); 134} 135 136 137/** 138 * Copy string from <src> to <dst>, up to maxLength characters, returning 139 * length of <dst> in <length>. 140 * \param src the strings source 141 * \param maxLength max chars to copy 142 * \param length returns number of chars copied 143 * \param dst the string destination 144 */ 145void 146_mesa_copy_string(GLchar *dst, GLsizei maxLength, 147 GLsizei *length, const GLchar *src) 148{ 149 GLsizei len; 150 for (len = 0; len < maxLength - 1 && src && src[len]; len++) 151 dst[len] = src[len]; 152 if (maxLength > 0) 153 dst[len] = 0; 154 if (length) 155 *length = len; 156} 157 158 159 160/** 161 * Confirm that the a shader type is valid and supported by the implementation 162 * 163 * \param ctx Current GL context 164 * \param type Shader target 165 * 166 */ 167static bool 168validate_shader_target(const struct gl_context *ctx, GLenum type) 169{ 170 switch (type) { 171#if FEATURE_ARB_fragment_shader 172 case GL_FRAGMENT_SHADER: 173 return ctx->Extensions.ARB_fragment_shader; 174#endif 175#if FEATURE_ARB_vertex_shader 176 case GL_VERTEX_SHADER: 177 return ctx->Extensions.ARB_vertex_shader; 178#endif 179#if FEATURE_ARB_geometry_shader4 180 case GL_GEOMETRY_SHADER_ARB: 181 return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_geometry_shader4; 182#endif 183 default: 184 return false; 185 } 186} 187 188 189/** 190 * Find the length of the longest transform feedback varying name 191 * which was specified with glTransformFeedbackVaryings(). 192 */ 193static GLint 194longest_feedback_varying_name(const struct gl_shader_program *shProg) 195{ 196 GLuint i; 197 GLint max = 0; 198 for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) { 199 GLint len = strlen(shProg->TransformFeedback.VaryingNames[i]); 200 if (len > max) 201 max = len; 202 } 203 return max; 204} 205 206 207 208static GLboolean 209is_program(struct gl_context *ctx, GLuint name) 210{ 211 struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, name); 212 return shProg ? GL_TRUE : GL_FALSE; 213} 214 215 216static GLboolean 217is_shader(struct gl_context *ctx, GLuint name) 218{ 219 struct gl_shader *shader = _mesa_lookup_shader(ctx, name); 220 return shader ? GL_TRUE : GL_FALSE; 221} 222 223 224/** 225 * Attach shader to a shader program. 226 */ 227static void 228attach_shader(struct gl_context *ctx, GLuint program, GLuint shader) 229{ 230 struct gl_shader_program *shProg; 231 struct gl_shader *sh; 232 GLuint i, n; 233 234 shProg = _mesa_lookup_shader_program_err(ctx, program, "glAttachShader"); 235 if (!shProg) 236 return; 237 238 sh = _mesa_lookup_shader_err(ctx, shader, "glAttachShader"); 239 if (!sh) { 240 return; 241 } 242 243 n = shProg->NumShaders; 244 for (i = 0; i < n; i++) { 245 if (shProg->Shaders[i] == sh) { 246 /* The shader is already attched to this program. The 247 * GL_ARB_shader_objects spec says: 248 * 249 * "The error INVALID_OPERATION is generated by AttachObjectARB 250 * if <obj> is already attached to <containerObj>." 251 */ 252 _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader"); 253 return; 254 } 255 } 256 257 /* grow list */ 258 shProg->Shaders = (struct gl_shader **) 259 _mesa_realloc(shProg->Shaders, 260 n * sizeof(struct gl_shader *), 261 (n + 1) * sizeof(struct gl_shader *)); 262 if (!shProg->Shaders) { 263 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAttachShader"); 264 return; 265 } 266 267 /* append */ 268 shProg->Shaders[n] = NULL; /* since realloc() didn't zero the new space */ 269 _mesa_reference_shader(ctx, &shProg->Shaders[n], sh); 270 shProg->NumShaders++; 271} 272 273 274static GLuint 275create_shader(struct gl_context *ctx, GLenum type) 276{ 277 struct gl_shader *sh; 278 GLuint name; 279 280 if (!validate_shader_target(ctx, type)) { 281 _mesa_error(ctx, GL_INVALID_ENUM, "CreateShader(type)"); 282 return 0; 283 } 284 285 name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1); 286 sh = ctx->Driver.NewShader(ctx, name, type); 287 _mesa_HashInsert(ctx->Shared->ShaderObjects, name, sh); 288 289 return name; 290} 291 292 293static GLuint 294create_shader_program(struct gl_context *ctx) 295{ 296 GLuint name; 297 struct gl_shader_program *shProg; 298 299 name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1); 300 301 shProg = ctx->Driver.NewShaderProgram(ctx, name); 302 303 _mesa_HashInsert(ctx->Shared->ShaderObjects, name, shProg); 304 305 assert(shProg->RefCount == 1); 306 307 return name; 308} 309 310 311/** 312 * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's 313 * DeleteProgramARB. 314 */ 315static void 316delete_shader_program(struct gl_context *ctx, GLuint name) 317{ 318 /* 319 * NOTE: deleting shaders/programs works a bit differently than 320 * texture objects (and buffer objects, etc). Shader/program 321 * handles/IDs exist in the hash table until the object is really 322 * deleted (refcount==0). With texture objects, the handle/ID is 323 * removed from the hash table in glDeleteTextures() while the tex 324 * object itself might linger until its refcount goes to zero. 325 */ 326 struct gl_shader_program *shProg; 327 328 shProg = _mesa_lookup_shader_program_err(ctx, name, "glDeleteProgram"); 329 if (!shProg) 330 return; 331 332 if (!shProg->DeletePending) { 333 shProg->DeletePending = GL_TRUE; 334 335 /* effectively, decr shProg's refcount */ 336 _mesa_reference_shader_program(ctx, &shProg, NULL); 337 } 338} 339 340 341static void 342delete_shader(struct gl_context *ctx, GLuint shader) 343{ 344 struct gl_shader *sh; 345 346 sh = _mesa_lookup_shader_err(ctx, shader, "glDeleteShader"); 347 if (!sh) 348 return; 349 350 if (!sh->DeletePending) { 351 sh->DeletePending = GL_TRUE; 352 353 /* effectively, decr sh's refcount */ 354 _mesa_reference_shader(ctx, &sh, NULL); 355 } 356} 357 358 359static void 360detach_shader(struct gl_context *ctx, GLuint program, GLuint shader) 361{ 362 struct gl_shader_program *shProg; 363 GLuint n; 364 GLuint i, j; 365 366 shProg = _mesa_lookup_shader_program_err(ctx, program, "glDetachShader"); 367 if (!shProg) 368 return; 369 370 n = shProg->NumShaders; 371 372 for (i = 0; i < n; i++) { 373 if (shProg->Shaders[i]->Name == shader) { 374 /* found it */ 375 struct gl_shader **newList; 376 377 /* release */ 378 _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL); 379 380 /* alloc new, smaller array */ 381 newList = (struct gl_shader **) 382 malloc((n - 1) * sizeof(struct gl_shader *)); 383 if (!newList) { 384 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDetachShader"); 385 return; 386 } 387 for (j = 0; j < i; j++) { 388 newList[j] = shProg->Shaders[j]; 389 } 390 while (++i < n) 391 newList[j++] = shProg->Shaders[i]; 392 free(shProg->Shaders); 393 394 shProg->Shaders = newList; 395 shProg->NumShaders = n - 1; 396 397#ifdef DEBUG 398 /* sanity check */ 399 { 400 for (j = 0; j < shProg->NumShaders; j++) { 401 assert(shProg->Shaders[j]->Type == GL_VERTEX_SHADER || 402 shProg->Shaders[j]->Type == GL_FRAGMENT_SHADER); 403 assert(shProg->Shaders[j]->RefCount > 0); 404 } 405 } 406#endif 407 408 return; 409 } 410 } 411 412 /* not found */ 413 { 414 GLenum err; 415 if (is_shader(ctx, shader)) 416 err = GL_INVALID_OPERATION; 417 else if (is_program(ctx, shader)) 418 err = GL_INVALID_OPERATION; 419 else 420 err = GL_INVALID_VALUE; 421 _mesa_error(ctx, err, "glDetachProgram(shader)"); 422 return; 423 } 424} 425 426 427/** 428 * Return list of shaders attached to shader program. 429 */ 430static void 431get_attached_shaders(struct gl_context *ctx, GLuint program, GLsizei maxCount, 432 GLsizei *count, GLuint *obj) 433{ 434 struct gl_shader_program *shProg = 435 _mesa_lookup_shader_program_err(ctx, program, "glGetAttachedShaders"); 436 if (shProg) { 437 GLuint i; 438 for (i = 0; i < (GLuint) maxCount && i < shProg->NumShaders; i++) { 439 obj[i] = shProg->Shaders[i]->Name; 440 } 441 if (count) 442 *count = i; 443 } 444} 445 446 447/** 448 * glGetHandleARB() - return ID/name of currently bound shader program. 449 */ 450static GLuint 451get_handle(struct gl_context *ctx, GLenum pname) 452{ 453 if (pname == GL_PROGRAM_OBJECT_ARB) { 454 if (ctx->Shader.ActiveProgram) 455 return ctx->Shader.ActiveProgram->Name; 456 else 457 return 0; 458 } 459 else { 460 _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB"); 461 return 0; 462 } 463} 464 465 466/** 467 * glGetProgramiv() - get shader program state. 468 * Note that this is for GLSL shader programs, not ARB vertex/fragment 469 * programs (see glGetProgramivARB). 470 */ 471static void 472get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *params) 473{ 474 struct gl_shader_program *shProg 475 = _mesa_lookup_shader_program(ctx, program); 476 477#if FEATURE_EXT_transform_feedback 478 /* Is transform feedback available in this context? 479 */ 480 const bool has_xfb = 481 (ctx->API == API_OPENGL && ctx->Extensions.EXT_transform_feedback) 482 || ctx->API == API_OPENGL_CORE 483 || _mesa_is_gles3(ctx); 484#endif 485 486#if FEATURE_ARB_geometry_shader4 487 /* Are geometry shaders available in this context? 488 */ 489 const bool has_gs = 490 _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_geometry_shader4; 491#endif 492 493 /* Are uniform buffer objects available in this context? 494 */ 495 const bool has_ubo = 496 (ctx->API == API_OPENGL && ctx->Extensions.ARB_uniform_buffer_object) 497 || ctx->API == API_OPENGL_CORE 498 || _mesa_is_gles3(ctx); 499 500 if (!shProg) { 501 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramiv(program)"); 502 return; 503 } 504 505 switch (pname) { 506 case GL_DELETE_STATUS: 507 *params = shProg->DeletePending; 508 return; 509 case GL_LINK_STATUS: 510 *params = shProg->LinkStatus; 511 return; 512 case GL_VALIDATE_STATUS: 513 *params = shProg->Validated; 514 return; 515 case GL_INFO_LOG_LENGTH: 516 *params = shProg->InfoLog ? strlen(shProg->InfoLog) + 1 : 0; 517 return; 518 case GL_ATTACHED_SHADERS: 519 *params = shProg->NumShaders; 520 return; 521 case GL_ACTIVE_ATTRIBUTES: 522 *params = _mesa_count_active_attribs(shProg); 523 return; 524 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: 525 *params = _mesa_longest_attribute_name_length(shProg); 526 return; 527 case GL_ACTIVE_UNIFORMS: 528 *params = shProg->NumUserUniformStorage; 529 return; 530 case GL_ACTIVE_UNIFORM_MAX_LENGTH: { 531 unsigned i; 532 GLint max_len = 0; 533 534 for (i = 0; i < shProg->NumUserUniformStorage; i++) { 535 /* Add one for the terminating NUL character. 536 */ 537 const GLint len = strlen(shProg->UniformStorage[i].name) + 1; 538 539 if (len > max_len) 540 max_len = len; 541 } 542 543 *params = max_len; 544 return; 545 } 546#if FEATURE_EXT_transform_feedback 547 case GL_TRANSFORM_FEEDBACK_VARYINGS: 548 if (!has_xfb) 549 break; 550 *params = shProg->TransformFeedback.NumVarying; 551 return; 552 case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: 553 if (!has_xfb) 554 break; 555 *params = longest_feedback_varying_name(shProg) + 1; 556 return; 557 case GL_TRANSFORM_FEEDBACK_BUFFER_MODE: 558 if (!has_xfb) 559 break; 560 *params = shProg->TransformFeedback.BufferMode; 561 return; 562#endif 563#if FEATURE_ARB_geometry_shader4 564 case GL_GEOMETRY_VERTICES_OUT_ARB: 565 if (!has_gs) 566 break; 567 *params = shProg->Geom.VerticesOut; 568 return; 569 case GL_GEOMETRY_INPUT_TYPE_ARB: 570 if (!has_gs) 571 break; 572 *params = shProg->Geom.InputType; 573 return; 574 case GL_GEOMETRY_OUTPUT_TYPE_ARB: 575 if (!has_gs) 576 break; 577 *params = shProg->Geom.OutputType; 578 return; 579#endif 580 case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: { 581 unsigned i; 582 GLint max_len = 0; 583 584 if (!has_ubo) 585 break; 586 587 for (i = 0; i < shProg->NumUniformBlocks; i++) { 588 /* Add one for the terminating NUL character. 589 */ 590 const GLint len = strlen(shProg->UniformBlocks[i].Name) + 1; 591 592 if (len > max_len) 593 max_len = len; 594 } 595 596 *params = max_len; 597 return; 598 } 599 case GL_ACTIVE_UNIFORM_BLOCKS: 600 if (!has_ubo) 601 break; 602 603 *params = shProg->NumUniformBlocks; 604 return; 605 default: 606 break; 607 } 608 609 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname=%s)", 610 _mesa_lookup_enum_by_nr(pname)); 611} 612 613 614/** 615 * glGetShaderiv() - get GLSL shader state 616 */ 617static void 618get_shaderiv(struct gl_context *ctx, GLuint name, GLenum pname, GLint *params) 619{ 620 struct gl_shader *shader = 621 _mesa_lookup_shader_err(ctx, name, "glGetShaderiv"); 622 623 if (!shader) { 624 return; 625 } 626 627 switch (pname) { 628 case GL_SHADER_TYPE: 629 *params = shader->Type; 630 break; 631 case GL_DELETE_STATUS: 632 *params = shader->DeletePending; 633 break; 634 case GL_COMPILE_STATUS: 635 *params = shader->CompileStatus; 636 break; 637 case GL_INFO_LOG_LENGTH: 638 *params = shader->InfoLog ? strlen(shader->InfoLog) + 1 : 0; 639 break; 640 case GL_SHADER_SOURCE_LENGTH: 641 *params = shader->Source ? strlen((char *) shader->Source) + 1 : 0; 642 break; 643 default: 644 _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)"); 645 return; 646 } 647} 648 649 650static void 651get_program_info_log(struct gl_context *ctx, GLuint program, GLsizei bufSize, 652 GLsizei *length, GLchar *infoLog) 653{ 654 struct gl_shader_program *shProg 655 = _mesa_lookup_shader_program(ctx, program); 656 if (!shProg) { 657 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramInfoLog(program)"); 658 return; 659 } 660 _mesa_copy_string(infoLog, bufSize, length, shProg->InfoLog); 661} 662 663 664static void 665get_shader_info_log(struct gl_context *ctx, GLuint shader, GLsizei bufSize, 666 GLsizei *length, GLchar *infoLog) 667{ 668 struct gl_shader *sh = _mesa_lookup_shader(ctx, shader); 669 if (!sh) { 670 _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderInfoLog(shader)"); 671 return; 672 } 673 _mesa_copy_string(infoLog, bufSize, length, sh->InfoLog); 674} 675 676 677/** 678 * Return shader source code. 679 */ 680static void 681get_shader_source(struct gl_context *ctx, GLuint shader, GLsizei maxLength, 682 GLsizei *length, GLchar *sourceOut) 683{ 684 struct gl_shader *sh; 685 sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderSource"); 686 if (!sh) { 687 return; 688 } 689 _mesa_copy_string(sourceOut, maxLength, length, sh->Source); 690} 691 692 693/** 694 * Set/replace shader source code. A helper function used by 695 * glShaderSource[ARB] and glCreateShaderProgramEXT. 696 */ 697static void 698shader_source(struct gl_context *ctx, GLuint shader, const GLchar *source) 699{ 700 struct gl_shader *sh; 701 702 sh = _mesa_lookup_shader_err(ctx, shader, "glShaderSource"); 703 if (!sh) 704 return; 705 706 /* free old shader source string and install new one */ 707 if (sh->Source) { 708 free((void *) sh->Source); 709 } 710 sh->Source = source; 711 sh->CompileStatus = GL_FALSE; 712#ifdef DEBUG 713 sh->SourceChecksum = _mesa_str_checksum(sh->Source); 714#endif 715} 716 717 718/** 719 * Compile a shader. 720 */ 721static void 722compile_shader(struct gl_context *ctx, GLuint shaderObj) 723{ 724 struct gl_shader *sh; 725 struct gl_shader_compiler_options *options; 726 727 sh = _mesa_lookup_shader_err(ctx, shaderObj, "glCompileShader"); 728 if (!sh) 729 return; 730 731 options = &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(sh->Type)]; 732 733 /* set default pragma state for shader */ 734 sh->Pragmas = options->DefaultPragmas; 735 736 /* this call will set the sh->CompileStatus field to indicate if 737 * compilation was successful. 738 */ 739 _mesa_glsl_compile_shader(ctx, sh); 740 741 if (sh->CompileStatus == GL_FALSE && 742 (ctx->Shader.Flags & GLSL_REPORT_ERRORS)) { 743 _mesa_debug(ctx, "Error compiling shader %u:\n%s\n", 744 sh->Name, sh->InfoLog); 745 } 746} 747 748 749/** 750 * Link a program's shaders. 751 */ 752static void 753link_program(struct gl_context *ctx, GLuint program) 754{ 755 struct gl_shader_program *shProg; 756 struct gl_transform_feedback_object *obj = 757 ctx->TransformFeedback.CurrentObject; 758 759 shProg = _mesa_lookup_shader_program_err(ctx, program, "glLinkProgram"); 760 if (!shProg) 761 return; 762 763 if (obj->Active 764 && (shProg == ctx->Shader.CurrentVertexProgram 765 || shProg == ctx->Shader.CurrentGeometryProgram 766 || shProg == ctx->Shader.CurrentFragmentProgram)) { 767 _mesa_error(ctx, GL_INVALID_OPERATION, 768 "glLinkProgram(transform feedback active)"); 769 return; 770 } 771 772 FLUSH_VERTICES(ctx, _NEW_PROGRAM); 773 774 _mesa_glsl_link_shader(ctx, shProg); 775 776 if (shProg->LinkStatus == GL_FALSE && 777 (ctx->Shader.Flags & GLSL_REPORT_ERRORS)) { 778 _mesa_debug(ctx, "Error linking program %u:\n%s\n", 779 shProg->Name, shProg->InfoLog); 780 } 781 782 /* debug code */ 783 if (0) { 784 GLuint i; 785 786 printf("Link %u shaders in program %u: %s\n", 787 shProg->NumShaders, shProg->Name, 788 shProg->LinkStatus ? "Success" : "Failed"); 789 790 for (i = 0; i < shProg->NumShaders; i++) { 791 printf(" shader %u, type 0x%x\n", 792 shProg->Shaders[i]->Name, 793 shProg->Shaders[i]->Type); 794 } 795 } 796} 797 798 799/** 800 * Print basic shader info (for debug). 801 */ 802static void 803print_shader_info(const struct gl_shader_program *shProg) 804{ 805 GLuint i; 806 807 printf("Mesa: glUseProgram(%u)\n", shProg->Name); 808 for (i = 0; i < shProg->NumShaders; i++) { 809 const char *s; 810 switch (shProg->Shaders[i]->Type) { 811 case GL_VERTEX_SHADER: 812 s = "vertex"; 813 break; 814 case GL_FRAGMENT_SHADER: 815 s = "fragment"; 816 break; 817 case GL_GEOMETRY_SHADER: 818 s = "geometry"; 819 break; 820 default: 821 s = ""; 822 } 823 printf(" %s shader %u, checksum %u\n", s, 824 shProg->Shaders[i]->Name, 825 shProg->Shaders[i]->SourceChecksum); 826 } 827 if (shProg->_LinkedShaders[MESA_SHADER_VERTEX]) 828 printf(" vert prog %u\n", 829 shProg->_LinkedShaders[MESA_SHADER_VERTEX]->Program->Id); 830 if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]) 831 printf(" frag prog %u\n", 832 shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program->Id); 833 if (shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]) 834 printf(" geom prog %u\n", 835 shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program->Id); 836} 837 838 839/** 840 * Use the named shader program for subsequent glUniform calls 841 */ 842void 843_mesa_active_program(struct gl_context *ctx, struct gl_shader_program *shProg, 844 const char *caller) 845{ 846 if ((shProg != NULL) && !shProg->LinkStatus) { 847 _mesa_error(ctx, GL_INVALID_OPERATION, 848 "%s(program %u not linked)", caller, shProg->Name); 849 return; 850 } 851 852 if (ctx->Shader.ActiveProgram != shProg) { 853 _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, shProg); 854 } 855} 856 857/** 858 */ 859static bool 860use_shader_program(struct gl_context *ctx, GLenum type, 861 struct gl_shader_program *shProg) 862{ 863 struct gl_shader_program **target; 864 865 switch (type) { 866#if FEATURE_ARB_vertex_shader 867 case GL_VERTEX_SHADER: 868 target = &ctx->Shader.CurrentVertexProgram; 869 if ((shProg == NULL) 870 || (shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL)) { 871 shProg = NULL; 872 } 873 break; 874#endif 875#if FEATURE_ARB_geometry_shader4 876 case GL_GEOMETRY_SHADER_ARB: 877 target = &ctx->Shader.CurrentGeometryProgram; 878 if ((shProg == NULL) 879 || (shProg->_LinkedShaders[MESA_SHADER_GEOMETRY] == NULL)) { 880 shProg = NULL; 881 } 882 break; 883#endif 884#if FEATURE_ARB_fragment_shader 885 case GL_FRAGMENT_SHADER: 886 target = &ctx->Shader.CurrentFragmentProgram; 887 if ((shProg == NULL) 888 || (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL)) { 889 shProg = NULL; 890 } 891 break; 892#endif 893 default: 894 return false; 895 } 896 897 if (*target != shProg) { 898 FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); 899 900 /* If the shader is also bound as the current rendering shader, unbind 901 * it from that binding point as well. This ensures that the correct 902 * semantics of glDeleteProgram are maintained. 903 */ 904 switch (type) { 905#if FEATURE_ARB_vertex_shader 906 case GL_VERTEX_SHADER: 907 /* Empty for now. */ 908 break; 909#endif 910#if FEATURE_ARB_geometry_shader4 911 case GL_GEOMETRY_SHADER_ARB: 912 /* Empty for now. */ 913 break; 914#endif 915#if FEATURE_ARB_fragment_shader 916 case GL_FRAGMENT_SHADER: 917 if (*target == ctx->Shader._CurrentFragmentProgram) { 918 _mesa_reference_shader_program(ctx, 919 &ctx->Shader._CurrentFragmentProgram, 920 NULL); 921 } 922 break; 923#endif 924 } 925 926 _mesa_reference_shader_program(ctx, target, shProg); 927 return true; 928 } 929 930 return false; 931} 932 933/** 934 * Use the named shader program for subsequent rendering. 935 */ 936void 937_mesa_use_program(struct gl_context *ctx, struct gl_shader_program *shProg) 938{ 939 use_shader_program(ctx, GL_VERTEX_SHADER, shProg); 940 use_shader_program(ctx, GL_GEOMETRY_SHADER_ARB, shProg); 941 use_shader_program(ctx, GL_FRAGMENT_SHADER, shProg); 942 _mesa_active_program(ctx, shProg, "glUseProgram"); 943 944 if (ctx->Driver.UseProgram) 945 ctx->Driver.UseProgram(ctx, shProg); 946} 947 948 949/** 950 * Do validation of the given shader program. 951 * \param errMsg returns error message if validation fails. 952 * \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg) 953 */ 954static GLboolean 955validate_shader_program(const struct gl_shader_program *shProg, 956 char *errMsg) 957{ 958 if (!shProg->LinkStatus) { 959 return GL_FALSE; 960 } 961 962 /* From the GL spec, a program is invalid if any of these are true: 963 964 any two active samplers in the current program object are of 965 different types, but refer to the same texture image unit, 966 967 any active sampler in the current program object refers to a texture 968 image unit where fixed-function fragment processing accesses a 969 texture target that does not match the sampler type, or 970 971 the sum of the number of active samplers in the program and the 972 number of texture image units enabled for fixed-function fragment 973 processing exceeds the combined limit on the total number of texture 974 image units allowed. 975 */ 976 977 978 /* 979 * Check: any two active samplers in the current program object are of 980 * different types, but refer to the same texture image unit, 981 */ 982 if (!_mesa_sampler_uniforms_are_valid(shProg, errMsg, 100)) 983 return GL_FALSE; 984 985 return GL_TRUE; 986} 987 988 989/** 990 * Called via glValidateProgram() 991 */ 992static void 993validate_program(struct gl_context *ctx, GLuint program) 994{ 995 struct gl_shader_program *shProg; 996 char errMsg[100] = ""; 997 998 shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram"); 999 if (!shProg) { 1000 return; 1001 } 1002 1003 shProg->Validated = validate_shader_program(shProg, errMsg); 1004 if (!shProg->Validated) { 1005 /* update info log */ 1006 if (shProg->InfoLog) { 1007 ralloc_free(shProg->InfoLog); 1008 } 1009 shProg->InfoLog = ralloc_strdup(shProg, errMsg); 1010 } 1011} 1012 1013 1014 1015void GLAPIENTRY 1016_mesa_AttachObjectARB(GLhandleARB program, GLhandleARB shader) 1017{ 1018 GET_CURRENT_CONTEXT(ctx); 1019 attach_shader(ctx, program, shader); 1020} 1021 1022 1023void GLAPIENTRY 1024_mesa_AttachShader(GLuint program, GLuint shader) 1025{ 1026 GET_CURRENT_CONTEXT(ctx); 1027 attach_shader(ctx, program, shader); 1028} 1029 1030 1031void GLAPIENTRY 1032_mesa_CompileShaderARB(GLhandleARB shaderObj) 1033{ 1034 GET_CURRENT_CONTEXT(ctx); 1035 if (MESA_VERBOSE & VERBOSE_API) 1036 _mesa_debug(ctx, "glCompileShader %u\n", shaderObj); 1037 compile_shader(ctx, shaderObj); 1038} 1039 1040 1041GLuint GLAPIENTRY 1042_mesa_CreateShader(GLenum type) 1043{ 1044 GET_CURRENT_CONTEXT(ctx); 1045 if (MESA_VERBOSE & VERBOSE_API) 1046 _mesa_debug(ctx, "glCreateShader %s\n", _mesa_lookup_enum_by_nr(type)); 1047 return create_shader(ctx, type); 1048} 1049 1050 1051GLhandleARB GLAPIENTRY 1052_mesa_CreateShaderObjectARB(GLenum type) 1053{ 1054 GET_CURRENT_CONTEXT(ctx); 1055 return create_shader(ctx, type); 1056} 1057 1058 1059GLuint GLAPIENTRY 1060_mesa_CreateProgram(void) 1061{ 1062 GET_CURRENT_CONTEXT(ctx); 1063 if (MESA_VERBOSE & VERBOSE_API) 1064 _mesa_debug(ctx, "glCreateProgram\n"); 1065 return create_shader_program(ctx); 1066} 1067 1068 1069GLhandleARB GLAPIENTRY 1070_mesa_CreateProgramObjectARB(void) 1071{ 1072 GET_CURRENT_CONTEXT(ctx); 1073 return create_shader_program(ctx); 1074} 1075 1076 1077void GLAPIENTRY 1078_mesa_DeleteObjectARB(GLhandleARB obj) 1079{ 1080 if (MESA_VERBOSE & VERBOSE_API) { 1081 GET_CURRENT_CONTEXT(ctx); 1082 _mesa_debug(ctx, "glDeleteObjectARB(%u)\n", obj); 1083 } 1084 1085 if (obj) { 1086 GET_CURRENT_CONTEXT(ctx); 1087 FLUSH_VERTICES(ctx, 0); 1088 if (is_program(ctx, obj)) { 1089 delete_shader_program(ctx, obj); 1090 } 1091 else if (is_shader(ctx, obj)) { 1092 delete_shader(ctx, obj); 1093 } 1094 else { 1095 /* error? */ 1096 } 1097 } 1098} 1099 1100 1101void GLAPIENTRY 1102_mesa_DeleteProgram(GLuint name) 1103{ 1104 if (name) { 1105 GET_CURRENT_CONTEXT(ctx); 1106 FLUSH_VERTICES(ctx, 0); 1107 delete_shader_program(ctx, name); 1108 } 1109} 1110 1111 1112void GLAPIENTRY 1113_mesa_DeleteShader(GLuint name) 1114{ 1115 if (name) { 1116 GET_CURRENT_CONTEXT(ctx); 1117 FLUSH_VERTICES(ctx, 0); 1118 delete_shader(ctx, name); 1119 } 1120} 1121 1122 1123void GLAPIENTRY 1124_mesa_DetachObjectARB(GLhandleARB program, GLhandleARB shader) 1125{ 1126 GET_CURRENT_CONTEXT(ctx); 1127 detach_shader(ctx, program, shader); 1128} 1129 1130 1131void GLAPIENTRY 1132_mesa_DetachShader(GLuint program, GLuint shader) 1133{ 1134 GET_CURRENT_CONTEXT(ctx); 1135 detach_shader(ctx, program, shader); 1136} 1137 1138 1139void GLAPIENTRY 1140_mesa_GetAttachedObjectsARB(GLhandleARB container, GLsizei maxCount, 1141 GLsizei * count, GLhandleARB * obj) 1142{ 1143 GET_CURRENT_CONTEXT(ctx); 1144 get_attached_shaders(ctx, container, maxCount, count, obj); 1145} 1146 1147 1148void GLAPIENTRY 1149_mesa_GetAttachedShaders(GLuint program, GLsizei maxCount, 1150 GLsizei *count, GLuint *obj) 1151{ 1152 GET_CURRENT_CONTEXT(ctx); 1153 get_attached_shaders(ctx, program, maxCount, count, obj); 1154} 1155 1156 1157void GLAPIENTRY 1158_mesa_GetInfoLogARB(GLhandleARB object, GLsizei maxLength, GLsizei * length, 1159 GLcharARB * infoLog) 1160{ 1161 GET_CURRENT_CONTEXT(ctx); 1162 if (is_program(ctx, object)) { 1163 get_program_info_log(ctx, object, maxLength, length, infoLog); 1164 } 1165 else if (is_shader(ctx, object)) { 1166 get_shader_info_log(ctx, object, maxLength, length, infoLog); 1167 } 1168 else { 1169 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInfoLogARB"); 1170 } 1171} 1172 1173 1174void GLAPIENTRY 1175_mesa_GetObjectParameterivARB(GLhandleARB object, GLenum pname, GLint *params) 1176{ 1177 GET_CURRENT_CONTEXT(ctx); 1178 /* Implement in terms of GetProgramiv, GetShaderiv */ 1179 if (is_program(ctx, object)) { 1180 if (pname == GL_OBJECT_TYPE_ARB) { 1181 *params = GL_PROGRAM_OBJECT_ARB; 1182 } 1183 else { 1184 get_programiv(ctx, object, pname, params); 1185 } 1186 } 1187 else if (is_shader(ctx, object)) { 1188 if (pname == GL_OBJECT_TYPE_ARB) { 1189 *params = GL_SHADER_OBJECT_ARB; 1190 } 1191 else { 1192 get_shaderiv(ctx, object, pname, params); 1193 } 1194 } 1195 else { 1196 _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectParameterivARB"); 1197 } 1198} 1199 1200 1201void GLAPIENTRY 1202_mesa_GetObjectParameterfvARB(GLhandleARB object, GLenum pname, 1203 GLfloat *params) 1204{ 1205 GLint iparams[1]; /* XXX is one element enough? */ 1206 _mesa_GetObjectParameterivARB(object, pname, iparams); 1207 params[0] = (GLfloat) iparams[0]; 1208} 1209 1210 1211void GLAPIENTRY 1212_mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params) 1213{ 1214 GET_CURRENT_CONTEXT(ctx); 1215 get_programiv(ctx, program, pname, params); 1216} 1217 1218 1219void GLAPIENTRY 1220_mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params) 1221{ 1222 GET_CURRENT_CONTEXT(ctx); 1223 get_shaderiv(ctx, shader, pname, params); 1224} 1225 1226 1227void GLAPIENTRY 1228_mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize, 1229 GLsizei *length, GLchar *infoLog) 1230{ 1231 GET_CURRENT_CONTEXT(ctx); 1232 get_program_info_log(ctx, program, bufSize, length, infoLog); 1233} 1234 1235 1236void GLAPIENTRY 1237_mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize, 1238 GLsizei *length, GLchar *infoLog) 1239{ 1240 GET_CURRENT_CONTEXT(ctx); 1241 get_shader_info_log(ctx, shader, bufSize, length, infoLog); 1242} 1243 1244 1245void GLAPIENTRY 1246_mesa_GetShaderSourceARB(GLhandleARB shader, GLsizei maxLength, 1247 GLsizei *length, GLcharARB *sourceOut) 1248{ 1249 GET_CURRENT_CONTEXT(ctx); 1250 get_shader_source(ctx, shader, maxLength, length, sourceOut); 1251} 1252 1253 1254GLhandleARB GLAPIENTRY 1255_mesa_GetHandleARB(GLenum pname) 1256{ 1257 GET_CURRENT_CONTEXT(ctx); 1258 return get_handle(ctx, pname); 1259} 1260 1261 1262GLboolean GLAPIENTRY 1263_mesa_IsProgram(GLuint name) 1264{ 1265 GET_CURRENT_CONTEXT(ctx); 1266 return is_program(ctx, name); 1267} 1268 1269 1270GLboolean GLAPIENTRY 1271_mesa_IsShader(GLuint name) 1272{ 1273 GET_CURRENT_CONTEXT(ctx); 1274 return is_shader(ctx, name); 1275} 1276 1277 1278void GLAPIENTRY 1279_mesa_LinkProgramARB(GLhandleARB programObj) 1280{ 1281 GET_CURRENT_CONTEXT(ctx); 1282 link_program(ctx, programObj); 1283} 1284 1285 1286 1287/** 1288 * Read shader source code from a file. 1289 * Useful for debugging to override an app's shader. 1290 */ 1291static GLcharARB * 1292read_shader(const char *fname) 1293{ 1294 const int max = 50*1000; 1295 FILE *f = fopen(fname, "r"); 1296 GLcharARB *buffer, *shader; 1297 int len; 1298 1299 if (!f) { 1300 return NULL; 1301 } 1302 1303 buffer = (char *) malloc(max); 1304 len = fread(buffer, 1, max, f); 1305 buffer[len] = 0; 1306 1307 fclose(f); 1308 1309 shader = _mesa_strdup(buffer); 1310 free(buffer); 1311 1312 return shader; 1313} 1314 1315 1316/** 1317 * Called via glShaderSource() and glShaderSourceARB() API functions. 1318 * Basically, concatenate the source code strings into one long string 1319 * and pass it to _mesa_shader_source(). 1320 */ 1321void GLAPIENTRY 1322_mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count, 1323 const GLcharARB ** string, const GLint * length) 1324{ 1325 GET_CURRENT_CONTEXT(ctx); 1326 GLint *offsets; 1327 GLsizei i, totalLength; 1328 GLcharARB *source; 1329 GLuint checksum; 1330 1331 if (!shaderObj || string == NULL) { 1332 _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB"); 1333 return; 1334 } 1335 1336 /* 1337 * This array holds offsets of where the appropriate string ends, thus the 1338 * last element will be set to the total length of the source code. 1339 */ 1340 offsets = (GLint *) malloc(count * sizeof(GLint)); 1341 if (offsets == NULL) { 1342 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB"); 1343 return; 1344 } 1345 1346 for (i = 0; i < count; i++) { 1347 if (string[i] == NULL) { 1348 free((GLvoid *) offsets); 1349 _mesa_error(ctx, GL_INVALID_OPERATION, 1350 "glShaderSourceARB(null string)"); 1351 return; 1352 } 1353 if (length == NULL || length[i] < 0) 1354 offsets[i] = strlen(string[i]); 1355 else 1356 offsets[i] = length[i]; 1357 /* accumulate string lengths */ 1358 if (i > 0) 1359 offsets[i] += offsets[i - 1]; 1360 } 1361 1362 /* Total length of source string is sum off all strings plus two. 1363 * One extra byte for terminating zero, another extra byte to silence 1364 * valgrind warnings in the parser/grammer code. 1365 */ 1366 totalLength = offsets[count - 1] + 2; 1367 source = (GLcharARB *) malloc(totalLength * sizeof(GLcharARB)); 1368 if (source == NULL) { 1369 free((GLvoid *) offsets); 1370 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB"); 1371 return; 1372 } 1373 1374 for (i = 0; i < count; i++) { 1375 GLint start = (i > 0) ? offsets[i - 1] : 0; 1376 memcpy(source + start, string[i], 1377 (offsets[i] - start) * sizeof(GLcharARB)); 1378 } 1379 source[totalLength - 1] = '\0'; 1380 source[totalLength - 2] = '\0'; 1381 1382 if (SHADER_SUBST) { 1383 /* Compute the shader's source code checksum then try to open a file 1384 * named newshader_<CHECKSUM>. If it exists, use it in place of the 1385 * original shader source code. For debugging. 1386 */ 1387 char filename[100]; 1388 GLcharARB *newSource; 1389 1390 checksum = _mesa_str_checksum(source); 1391 1392 _mesa_snprintf(filename, sizeof(filename), "newshader_%d", checksum); 1393 1394 newSource = read_shader(filename); 1395 if (newSource) { 1396 fprintf(stderr, "Mesa: Replacing shader %u chksum=%d with %s\n", 1397 shaderObj, checksum, filename); 1398 free(source); 1399 source = newSource; 1400 } 1401 } 1402 1403 shader_source(ctx, shaderObj, source); 1404 1405 if (SHADER_SUBST) { 1406 struct gl_shader *sh = _mesa_lookup_shader(ctx, shaderObj); 1407 if (sh) 1408 sh->SourceChecksum = checksum; /* save original checksum */ 1409 } 1410 1411 free(offsets); 1412} 1413 1414 1415void GLAPIENTRY 1416_mesa_UseProgramObjectARB(GLhandleARB program) 1417{ 1418 GET_CURRENT_CONTEXT(ctx); 1419 struct gl_shader_program *shProg; 1420 struct gl_transform_feedback_object *obj = 1421 ctx->TransformFeedback.CurrentObject; 1422 1423 ASSERT_OUTSIDE_BEGIN_END(ctx); 1424 1425 if (obj->Active && !obj->Paused) { 1426 _mesa_error(ctx, GL_INVALID_OPERATION, 1427 "glUseProgram(transform feedback active)"); 1428 return; 1429 } 1430 1431 if (program) { 1432 shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram"); 1433 if (!shProg) { 1434 return; 1435 } 1436 if (!shProg->LinkStatus) { 1437 _mesa_error(ctx, GL_INVALID_OPERATION, 1438 "glUseProgram(program %u not linked)", program); 1439 return; 1440 } 1441 1442 /* debug code */ 1443 if (ctx->Shader.Flags & GLSL_USE_PROG) { 1444 print_shader_info(shProg); 1445 } 1446 } 1447 else { 1448 shProg = NULL; 1449 } 1450 1451 _mesa_use_program(ctx, shProg); 1452} 1453 1454 1455void GLAPIENTRY 1456_mesa_ValidateProgramARB(GLhandleARB program) 1457{ 1458 GET_CURRENT_CONTEXT(ctx); 1459 validate_program(ctx, program); 1460} 1461 1462#ifdef FEATURE_ES2 1463 1464void GLAPIENTRY 1465_mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, 1466 GLint* range, GLint* precision) 1467{ 1468 const struct gl_program_constants *limits; 1469 const struct gl_precision *p; 1470 GET_CURRENT_CONTEXT(ctx); 1471 1472 switch (shadertype) { 1473 case GL_VERTEX_SHADER: 1474 limits = &ctx->Const.VertexProgram; 1475 break; 1476 case GL_FRAGMENT_SHADER: 1477 limits = &ctx->Const.FragmentProgram; 1478 break; 1479 default: 1480 _mesa_error(ctx, GL_INVALID_ENUM, 1481 "glGetShaderPrecisionFormat(shadertype)"); 1482 return; 1483 } 1484 1485 switch (precisiontype) { 1486 case GL_LOW_FLOAT: 1487 p = &limits->LowFloat; 1488 break; 1489 case GL_MEDIUM_FLOAT: 1490 p = &limits->MediumFloat; 1491 break; 1492 case GL_HIGH_FLOAT: 1493 p = &limits->HighFloat; 1494 break; 1495 case GL_LOW_INT: 1496 p = &limits->LowInt; 1497 break; 1498 case GL_MEDIUM_INT: 1499 p = &limits->MediumInt; 1500 break; 1501 case GL_HIGH_INT: 1502 p = &limits->HighInt; 1503 break; 1504 default: 1505 _mesa_error(ctx, GL_INVALID_ENUM, 1506 "glGetShaderPrecisionFormat(precisiontype)"); 1507 return; 1508 } 1509 1510 range[0] = p->RangeMin; 1511 range[1] = p->RangeMax; 1512 precision[0] = p->Precision; 1513} 1514 1515 1516void GLAPIENTRY 1517_mesa_ReleaseShaderCompiler(void) 1518{ 1519 _mesa_destroy_shader_compiler_caches(); 1520} 1521 1522 1523void GLAPIENTRY 1524_mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat, 1525 const void* binary, GLint length) 1526{ 1527 GET_CURRENT_CONTEXT(ctx); 1528 (void) n; 1529 (void) shaders; 1530 (void) binaryformat; 1531 (void) binary; 1532 (void) length; 1533 _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__); 1534} 1535 1536#endif /* FEATURE_ES2 */ 1537 1538 1539#if FEATURE_ARB_geometry_shader4 1540 1541void GLAPIENTRY 1542_mesa_ProgramParameteriARB(GLuint program, GLenum pname, GLint value) 1543{ 1544 struct gl_shader_program *shProg; 1545 GET_CURRENT_CONTEXT(ctx); 1546 1547 ASSERT_OUTSIDE_BEGIN_END(ctx); 1548 1549 shProg = _mesa_lookup_shader_program_err(ctx, program, 1550 "glProgramParameteri"); 1551 if (!shProg) 1552 return; 1553 1554 switch (pname) { 1555 case GL_GEOMETRY_VERTICES_OUT_ARB: 1556 if (value < 1 || 1557 (unsigned) value > ctx->Const.MaxGeometryOutputVertices) { 1558 _mesa_error(ctx, GL_INVALID_VALUE, 1559 "glProgramParameteri(GL_GEOMETRY_VERTICES_OUT_ARB=%d", 1560 value); 1561 return; 1562 } 1563 shProg->Geom.VerticesOut = value; 1564 break; 1565 case GL_GEOMETRY_INPUT_TYPE_ARB: 1566 switch (value) { 1567 case GL_POINTS: 1568 case GL_LINES: 1569 case GL_LINES_ADJACENCY_ARB: 1570 case GL_TRIANGLES: 1571 case GL_TRIANGLES_ADJACENCY_ARB: 1572 shProg->Geom.InputType = value; 1573 break; 1574 default: 1575 _mesa_error(ctx, GL_INVALID_VALUE, 1576 "glProgramParameteri(geometry input type = %s", 1577 _mesa_lookup_enum_by_nr(value)); 1578 return; 1579 } 1580 break; 1581 case GL_GEOMETRY_OUTPUT_TYPE_ARB: 1582 switch (value) { 1583 case GL_POINTS: 1584 case GL_LINE_STRIP: 1585 case GL_TRIANGLE_STRIP: 1586 shProg->Geom.OutputType = value; 1587 break; 1588 default: 1589 _mesa_error(ctx, GL_INVALID_VALUE, 1590 "glProgramParameteri(geometry output type = %s", 1591 _mesa_lookup_enum_by_nr(value)); 1592 return; 1593 } 1594 break; 1595 default: 1596 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameteriARB(pname=%s)", 1597 _mesa_lookup_enum_by_nr(pname)); 1598 break; 1599 } 1600} 1601 1602#endif 1603 1604void 1605_mesa_use_shader_program(struct gl_context *ctx, GLenum type, 1606 struct gl_shader_program *shProg) 1607{ 1608 use_shader_program(ctx, type, shProg); 1609 1610 if (ctx->Driver.UseProgram) 1611 ctx->Driver.UseProgram(ctx, shProg); 1612} 1613 1614 1615/** 1616 * For GL_EXT_separate_shader_objects 1617 */ 1618void GLAPIENTRY 1619_mesa_UseShaderProgramEXT(GLenum type, GLuint program) 1620{ 1621 GET_CURRENT_CONTEXT(ctx); 1622 struct gl_shader_program *shProg = NULL; 1623 1624 ASSERT_OUTSIDE_BEGIN_END(ctx); 1625 1626 if (!validate_shader_target(ctx, type)) { 1627 _mesa_error(ctx, GL_INVALID_ENUM, "glUseShaderProgramEXT(type)"); 1628 return; 1629 } 1630 1631 if (ctx->TransformFeedback.CurrentObject->Active && 1632 !ctx->TransformFeedback.CurrentObject->Paused) { 1633 _mesa_error(ctx, GL_INVALID_OPERATION, 1634 "glUseShaderProgramEXT(transform feedback is active)"); 1635 return; 1636 } 1637 1638 if (program) { 1639 shProg = _mesa_lookup_shader_program_err(ctx, program, 1640 "glUseShaderProgramEXT"); 1641 if (shProg == NULL) 1642 return; 1643 1644 if (!shProg->LinkStatus) { 1645 _mesa_error(ctx, GL_INVALID_OPERATION, 1646 "glUseShaderProgramEXT(program not linked)"); 1647 return; 1648 } 1649 } 1650 1651 _mesa_use_shader_program(ctx, type, shProg); 1652} 1653 1654 1655/** 1656 * For GL_EXT_separate_shader_objects 1657 */ 1658void GLAPIENTRY 1659_mesa_ActiveProgramEXT(GLuint program) 1660{ 1661 GET_CURRENT_CONTEXT(ctx); 1662 struct gl_shader_program *shProg = (program != 0) 1663 ? _mesa_lookup_shader_program_err(ctx, program, "glActiveProgramEXT") 1664 : NULL; 1665 1666 _mesa_active_program(ctx, shProg, "glActiveProgramEXT"); 1667 return; 1668} 1669 1670 1671/** 1672 * For GL_EXT_separate_shader_objects 1673 */ 1674GLuint GLAPIENTRY 1675_mesa_CreateShaderProgramEXT(GLenum type, const GLchar *string) 1676{ 1677 GET_CURRENT_CONTEXT(ctx); 1678 const GLuint shader = create_shader(ctx, type); 1679 GLuint program = 0; 1680 1681 if (shader) { 1682 shader_source(ctx, shader, _mesa_strdup(string)); 1683 compile_shader(ctx, shader); 1684 1685 program = create_shader_program(ctx); 1686 if (program) { 1687 struct gl_shader_program *shProg; 1688 struct gl_shader *sh; 1689 GLint compiled = GL_FALSE; 1690 1691 shProg = _mesa_lookup_shader_program(ctx, program); 1692 sh = _mesa_lookup_shader(ctx, shader); 1693 1694 get_shaderiv(ctx, shader, GL_COMPILE_STATUS, &compiled); 1695 if (compiled) { 1696 attach_shader(ctx, program, shader); 1697 link_program(ctx, program); 1698 detach_shader(ctx, program, shader); 1699 1700#if 0 1701 /* Possibly... */ 1702 if (active-user-defined-varyings-in-linked-program) { 1703 append-error-to-info-log; 1704 shProg->LinkStatus = GL_FALSE; 1705 } 1706#endif 1707 } 1708 1709 ralloc_strcat(&shProg->InfoLog, sh->InfoLog); 1710 } 1711 1712 delete_shader(ctx, shader); 1713 } 1714 1715 return program; 1716} 1717 1718/** 1719 * Plug in shader-related functions into API dispatch table. 1720 */ 1721void 1722_mesa_init_shader_dispatch(const struct gl_context *ctx, 1723 struct _glapi_table *exec) 1724{ 1725#if FEATURE_GL 1726 /* GL_ARB_vertex/fragment_shader */ 1727 if (ctx->API != API_OPENGLES2) { 1728 SET_DeleteObjectARB(exec, _mesa_DeleteObjectARB); 1729 SET_GetHandleARB(exec, _mesa_GetHandleARB); 1730 SET_DetachObjectARB(exec, _mesa_DetachObjectARB); 1731 SET_CreateShaderObjectARB(exec, _mesa_CreateShaderObjectARB); 1732 SET_CreateProgramObjectARB(exec, _mesa_CreateProgramObjectARB); 1733 SET_AttachObjectARB(exec, _mesa_AttachObjectARB); 1734 SET_GetObjectParameterfvARB(exec, _mesa_GetObjectParameterfvARB); 1735 SET_GetObjectParameterivARB(exec, _mesa_GetObjectParameterivARB); 1736 SET_GetInfoLogARB(exec, _mesa_GetInfoLogARB); 1737 SET_GetAttachedObjectsARB(exec, _mesa_GetAttachedObjectsARB); 1738 } 1739 1740 SET_ShaderSourceARB(exec, _mesa_ShaderSourceARB); 1741 SET_CompileShaderARB(exec, _mesa_CompileShaderARB); 1742 SET_LinkProgramARB(exec, _mesa_LinkProgramARB); 1743 SET_UseProgramObjectARB(exec, _mesa_UseProgramObjectARB); 1744 SET_ValidateProgramARB(exec, _mesa_ValidateProgramARB); 1745 SET_GetShaderSourceARB(exec, _mesa_GetShaderSourceARB); 1746 1747 /* OpenGL 2.0 */ 1748 SET_AttachShader(exec, _mesa_AttachShader); 1749 SET_CreateProgram(exec, _mesa_CreateProgram); 1750 SET_CreateShader(exec, _mesa_CreateShader); 1751 SET_DeleteProgram(exec, _mesa_DeleteProgram); 1752 SET_DeleteShader(exec, _mesa_DeleteShader); 1753 SET_DetachShader(exec, _mesa_DetachShader); 1754 SET_GetAttachedShaders(exec, _mesa_GetAttachedShaders); 1755 SET_GetProgramiv(exec, _mesa_GetProgramiv); 1756 SET_GetProgramInfoLog(exec, _mesa_GetProgramInfoLog); 1757 SET_GetShaderiv(exec, _mesa_GetShaderiv); 1758 SET_GetShaderInfoLog(exec, _mesa_GetShaderInfoLog); 1759 SET_IsProgram(exec, _mesa_IsProgram); 1760 SET_IsShader(exec, _mesa_IsShader); 1761 1762#if FEATURE_ARB_vertex_shader 1763 SET_BindAttribLocationARB(exec, _mesa_BindAttribLocationARB); 1764 SET_GetActiveAttribARB(exec, _mesa_GetActiveAttribARB); 1765 SET_GetAttribLocationARB(exec, _mesa_GetAttribLocationARB); 1766#endif 1767 1768 if (ctx->API != API_OPENGLES2) { 1769#if FEATURE_ARB_geometry_shader4 1770 SET_ProgramParameteriARB(exec, _mesa_ProgramParameteriARB); 1771#endif 1772 1773 SET_UseShaderProgramEXT(exec, _mesa_UseShaderProgramEXT); 1774 SET_ActiveProgramEXT(exec, _mesa_ActiveProgramEXT); 1775 SET_CreateShaderProgramEXT(exec, _mesa_CreateShaderProgramEXT); 1776 } 1777 1778 /* GL_EXT_gpu_shader4 / GL 3.0 */ 1779 if (ctx->API != API_OPENGLES2) { 1780 SET_BindFragDataLocationEXT(exec, _mesa_BindFragDataLocation); 1781 } 1782 if (ctx->API != API_OPENGLES2 || _mesa_is_gles3(ctx)) { 1783 SET_GetFragDataLocationEXT(exec, _mesa_GetFragDataLocation); 1784 } 1785 1786 /* GL_ARB_ES2_compatibility */ 1787 SET_ReleaseShaderCompiler(exec, _mesa_ReleaseShaderCompiler); 1788 SET_GetShaderPrecisionFormat(exec, _mesa_GetShaderPrecisionFormat); 1789 1790 /* GL_ARB_blend_func_extended */ 1791 if (ctx->API != API_OPENGLES2) { 1792 SET_BindFragDataLocationIndexed(exec, _mesa_BindFragDataLocationIndexed); 1793 SET_GetFragDataIndex(exec, _mesa_GetFragDataIndex); 1794 } 1795#endif /* FEATURE_GL */ 1796} 1797 1798