shaderapi.c 81.1 KB
Newer Older
Brian's avatar
Brian committed
1 2 3
/*
 * Mesa 3-D graphics library
 *
4
 * Copyright (C) 2004-2008  Brian Paul   All Rights Reserved.
5
 * Copyright (C) 2009-2010  VMware, Inc.  All Rights Reserved.
Brian's avatar
Brian committed
6 7 8 9 10 11 12 13 14 15 16 17 18 19
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20 21 22 23
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
Brian's avatar
Brian committed
24 25 26
 */

/**
27
 * \file shaderapi.c
Brian's avatar
Brian committed
28
 * \author Brian Paul
29 30 31 32 33
 *
 * Implementation of GLSL-related API functions.
 * The glUniform* functions are in uniforms.c
 *
 *
Brian's avatar
Brian committed
34 35
 * XXX things to do:
 * 1. Check that the right error code is generated for all _mesa_error() calls.
36
 * 2. Insert FLUSH_VERTICES calls in various places
Brian's avatar
Brian committed
37 38 39
 */


40
#include <stdbool.h>
41 42
#include "main/glheader.h"
#include "main/context.h"
43
#include "main/dispatch.h"
44
#include "main/enums.h"
45
#include "main/hash.h"
46
#include "main/mtypes.h"
47
#include "main/pipelineobj.h"
48 49
#include "main/shaderapi.h"
#include "main/shaderobj.h"
50
#include "main/transformfeedback.h"
51
#include "main/uniforms.h"
Emil Velikov's avatar
Emil Velikov committed
52 53 54 55
#include "compiler/glsl/glsl_parser_extras.h"
#include "compiler/glsl/ir.h"
#include "compiler/glsl/ir_uniform.h"
#include "compiler/glsl/program.h"
56
#include "program/program.h"
57
#include "program/prog_print.h"
58
#include "program/prog_parameter.h"
59
#include "util/ralloc.h"
60
#include "util/hash_table.h"
61
#include "util/mesa-sha1.h"
62
#include "util/crc32.h"
Brian's avatar
Brian committed
63

64 65 66
/**
 * Return mask of GLSL_x flags by examining the MESA_GLSL env var.
 */
67 68
GLbitfield
_mesa_get_shader_flags(void)
69 70
{
   GLbitfield flags = 0x0;
71
   const char *env = getenv("MESA_GLSL");
72 73

   if (env) {
74 75 76
      if (strstr(env, "dump_on_error"))
         flags |= GLSL_DUMP_ON_ERROR;
      else if (strstr(env, "dump"))
77
         flags |= GLSL_DUMP;
78
      if (strstr(env, "log"))
79
         flags |= GLSL_LOG;
80
      if (strstr(env, "nopvert"))
81
         flags |= GLSL_NOP_VERT;
82
      if (strstr(env, "nopfrag"))
83
         flags |= GLSL_NOP_FRAG;
84
      if (strstr(env, "nopt"))
85
         flags |= GLSL_NO_OPT;
86
      else if (strstr(env, "opt"))
87
         flags |= GLSL_OPT;
88
      if (strstr(env, "uniform"))
89
         flags |= GLSL_UNIFORMS;
90
      if (strstr(env, "useprog"))
91
         flags |= GLSL_USE_PROG;
92 93
      if (strstr(env, "errors"))
         flags |= GLSL_REPORT_ERRORS;
94 95 96 97 98
   }

   return flags;
}

99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
/**
 * Memoized version of getenv("MESA_SHADER_CAPTURE_PATH").
 */
const char *
_mesa_get_shader_capture_path(void)
{
   static bool read_env_var = false;
   static const char *path = NULL;

   if (!read_env_var) {
      path = getenv("MESA_SHADER_CAPTURE_PATH");
      read_env_var = true;
   }

   return path;
}
115

116 117 118
/**
 * Initialize context's shader state.
 */
Brian's avatar
Brian committed
119
void
120
_mesa_init_shader_state(struct gl_context *ctx)
Brian's avatar
Brian committed
121
{
122 123 124
   /* Device drivers may override these to control what kind of instructions
    * are generated by the GLSL compiler.
    */
125
   struct gl_shader_compiler_options options;
126
   gl_shader_stage sh;
127
   int i;
128 129

   memset(&options, 0, sizeof(options));
130
   options.MaxUnrollIterations = 32;
131
   options.MaxIfDepth = UINT_MAX;
132

133
   for (sh = 0; sh < MESA_SHADER_STAGES; ++sh)
134
      memcpy(&ctx->Const.ShaderCompilerOptions[sh], &options, sizeof(options));
135

136
   ctx->Shader.Flags = _mesa_get_shader_flags();
137

138 139 140
   if (ctx->Shader.Flags != 0)
      ctx->Const.GenerateTemporaryNames = true;

141 142
   /* Extended for ARB_separate_shader_objects */
   ctx->Shader.RefCount = 1;
143
   mtx_init(&ctx->Shader.Mutex, mtx_plain);
144 145 146 147 148 149

   ctx->TessCtrlProgram.patch_vertices = 3;
   for (i = 0; i < 4; ++i)
      ctx->TessCtrlProgram.patch_default_outer_level[i] = 1.0;
   for (i = 0; i < 2; ++i)
      ctx->TessCtrlProgram.patch_default_inner_level[i] = 1.0;
Brian's avatar
Brian committed
150 151 152
}


153 154 155 156
/**
 * Free the per-context shader-related state.
 */
void
157
_mesa_free_shader_state(struct gl_context *ctx)
158
{
159 160 161 162 163
   int i;
   for (i = 0; i < MESA_SHADER_STAGES; i++) {
      _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram[i],
                                     NULL);
   }
164
   _mesa_reference_program(ctx, &ctx->Shader._CurrentFragmentProgram, NULL);
165
   _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, NULL);
166 167

   /* Extended for ARB_separate_shader_objects */
168 169
   _mesa_reference_pipeline_object(ctx, &ctx->_Shader, NULL);

170
   assert(ctx->Shader.RefCount == 1);
171
   mtx_destroy(&ctx->Shader.Mutex);
172 173 174
}


175 176 177 178 179 180 181 182
/**
 * Copy string from <src> to <dst>, up to maxLength characters, returning
 * length of <dst> in <length>.
 * \param src  the strings source
 * \param maxLength  max chars to copy
 * \param length  returns number of chars copied
 * \param dst  the string destination
 */
183 184 185
void
_mesa_copy_string(GLchar *dst, GLsizei maxLength,
                  GLsizei *length, const GLchar *src)
Brian's avatar
Brian committed
186
{
187 188 189 190 191 192 193 194
   GLsizei len;
   for (len = 0; len < maxLength - 1 && src && src[len]; len++)
      dst[len] = src[len];
   if (maxLength > 0)
      dst[len] = 0;
   if (length)
      *length = len;
}
Brian's avatar
Brian committed
195 196


197

198 199 200 201 202 203 204
/**
 * Confirm that the a shader type is valid and supported by the implementation
 *
 * \param ctx   Current GL context
 * \param type  Shader target
 *
 */
205 206
bool
_mesa_validate_shader_target(const struct gl_context *ctx, GLenum type)
207
{
208 209 210 211 212 213 214
   /* Note: when building built-in GLSL functions, this function may be
    * invoked with ctx == NULL.  In that case, we can only validate that it's
    * a shader target we recognize, not that it's supported in the current
    * context.  But that's fine--we don't need any further validation than
    * that when building built-in GLSL functions.
    */

215 216
   switch (type) {
   case GL_FRAGMENT_SHADER:
217
      return ctx == NULL || ctx->Extensions.ARB_fragment_shader;
218
   case GL_VERTEX_SHADER:
219
      return ctx == NULL || ctx->Extensions.ARB_vertex_shader;
220
   case GL_GEOMETRY_SHADER_ARB:
221
      return ctx == NULL || _mesa_has_geometry_shaders(ctx);
222 223 224
   case GL_TESS_CONTROL_SHADER:
   case GL_TESS_EVALUATION_SHADER:
      return ctx == NULL || _mesa_has_tessellation(ctx);
225
   case GL_COMPUTE_SHADER:
226
      return ctx == NULL || _mesa_has_compute_shaders(ctx);
227 228 229 230 231 232
   default:
      return false;
   }
}


233
static GLboolean
234
is_program(struct gl_context *ctx, GLuint name)
235 236 237 238 239 240 241
{
   struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, name);
   return shProg ? GL_TRUE : GL_FALSE;
}


static GLboolean
242
is_shader(struct gl_context *ctx, GLuint name)
243 244 245 246 247 248
{
   struct gl_shader *shader = _mesa_lookup_shader(ctx, name);
   return shader ? GL_TRUE : GL_FALSE;
}


249
/**
250
 * Attach shader to a shader program.
251
 */
252
static void
253
attach_shader(struct gl_context *ctx, GLuint program, GLuint shader)
Brian's avatar
Brian committed
254
{
255 256 257
   struct gl_shader_program *shProg;
   struct gl_shader *sh;
   GLuint i, n;
Brian's avatar
Brian committed
258

bma's avatar
bma committed
259 260
   const bool same_type_disallowed = _mesa_is_gles(ctx);

261 262
   shProg = _mesa_lookup_shader_program_err(ctx, program, "glAttachShader");
   if (!shProg)
263 264
      return;

265
   sh = _mesa_lookup_shader_err(ctx, shader, "glAttachShader");
266
   if (!sh) {
Brian's avatar
Brian committed
267 268 269
      return;
   }

270
   n = shProg->NumShaders;
Brian's avatar
Brian committed
271
   for (i = 0; i < n; i++) {
272
      if (shProg->Shaders[i] == sh) {
273 274 275 276 277 278 279
         /* The shader is already attched to this program.  The
          * GL_ARB_shader_objects spec says:
          *
          *     "The error INVALID_OPERATION is generated by AttachObjectARB
          *     if <obj> is already attached to <containerObj>."
          */
         _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader");
Brian's avatar
Brian committed
280
         return;
bma's avatar
bma committed
281
      } else if (same_type_disallowed &&
282
                 shProg->Shaders[i]->Stage == sh->Stage) {
bma's avatar
bma committed
283 284 285 286 287 288 289 290 291 292
        /* Shader with the same type is already attached to this program,
         * OpenGL ES 2.0 and 3.0 specs say:
         *
         *      "Multiple shader objects of the same type may not be attached
         *      to a single program object. [...] The error INVALID_OPERATION
         *      is generated if [...] another shader object of the same type
         *      as shader is already attached to program."
         */
         _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader");
         return;
Brian's avatar
Brian committed
293 294 295
      }
   }

296
   /* grow list */
297 298
   shProg->Shaders = realloc(shProg->Shaders,
                             (n + 1) * sizeof(struct gl_shader *));
299
   if (!shProg->Shaders) {
300 301 302 303 304
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAttachShader");
      return;
   }

   /* append */
305 306
   shProg->Shaders[n] = NULL; /* since realloc() didn't zero the new space */
   _mesa_reference_shader(ctx, &shProg->Shaders[n], sh);
307
   shProg->NumShaders++;
Brian's avatar
Brian committed
308 309 310
}


311
static GLuint
312
create_shader(struct gl_context *ctx, GLenum type)
Brian's avatar
Brian committed
313
{
314
   struct gl_shader *sh;
Brian's avatar
Brian committed
315 316
   GLuint name;

317
   if (!_mesa_validate_shader_target(ctx, type)) {
318 319
      _mesa_error(ctx, GL_INVALID_ENUM, "CreateShader(%s)",
                  _mesa_enum_to_string(type));
Brian's avatar
Brian committed
320 321 322
      return 0;
   }

323
   _mesa_HashLockMutex(ctx->Shared->ShaderObjects);
324
   name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
325
   sh = _mesa_new_shader(name, _mesa_shader_enum_to_shader_stage(type));
326
   sh->Type = type;
327 328
   _mesa_HashInsertLocked(ctx->Shared->ShaderObjects, name, sh);
   _mesa_HashUnlockMutex(ctx->Shared->ShaderObjects);
Brian's avatar
Brian committed
329 330 331 332 333

   return name;
}


334
static GLuint
335
create_shader_program(struct gl_context *ctx)
Brian's avatar
Brian committed
336
{
337
   GLuint name;
338
   struct gl_shader_program *shProg;
Brian's avatar
Brian committed
339

340 341
   _mesa_HashLockMutex(ctx->Shared->ShaderObjects);

342
   name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
343

344
   shProg = _mesa_new_shader_program(name);
Brian's avatar
Brian committed
345

346
   _mesa_HashInsertLocked(ctx->Shared->ShaderObjects, name, shProg);
Brian's avatar
Brian committed
347

348 349
   assert(shProg->RefCount == 1);

350 351
   _mesa_HashUnlockMutex(ctx->Shared->ShaderObjects);

352
   return name;
Brian's avatar
Brian committed
353 354 355
}


356
/**
357 358 359
 * Delete a shader program.  Actually, just decrement the program's
 * reference count and mark it as DeletePending.
 * Used to implement glDeleteProgram() and glDeleteObjectARB().
360
 */
361
static void
362
delete_shader_program(struct gl_context *ctx, GLuint name)
Brian's avatar
Brian committed
363
{
364 365 366 367 368 369 370 371
   /*
    * NOTE: deleting shaders/programs works a bit differently than
    * texture objects (and buffer objects, etc).  Shader/program
    * handles/IDs exist in the hash table until the object is really
    * deleted (refcount==0).  With texture objects, the handle/ID is
    * removed from the hash table in glDeleteTextures() while the tex
    * object itself might linger until its refcount goes to zero.
    */
372
   struct gl_shader_program *shProg;
Brian's avatar
Brian committed
373

374 375
   shProg = _mesa_lookup_shader_program_err(ctx, name, "glDeleteProgram");
   if (!shProg)
Brian's avatar
Brian committed
376 377
      return;

378 379
   if (!shProg->DeletePending) {
      shProg->DeletePending = GL_TRUE;
380

381 382 383
      /* effectively, decr shProg's refcount */
      _mesa_reference_shader_program(ctx, &shProg, NULL);
   }
Brian's avatar
Brian committed
384 385 386
}


387
static void
388
delete_shader(struct gl_context *ctx, GLuint shader)
Brian's avatar
Brian committed
389
{
390 391 392 393
   struct gl_shader *sh;

   sh = _mesa_lookup_shader_err(ctx, shader, "glDeleteShader");
   if (!sh)
394
      return;
Brian's avatar
Brian committed
395

396 397
   if (!sh->DeletePending) {
      sh->DeletePending = GL_TRUE;
398

399 400 401
      /* effectively, decr sh's refcount */
      _mesa_reference_shader(ctx, &sh, NULL);
   }
Brian's avatar
Brian committed
402 403 404
}


405
static void
406
detach_shader(struct gl_context *ctx, GLuint program, GLuint shader)
Brian's avatar
Brian committed
407
{
408
   struct gl_shader_program *shProg;
409
   GLuint n;
410
   GLuint i, j;
Brian's avatar
Brian committed
411

412 413
   shProg = _mesa_lookup_shader_program_err(ctx, program, "glDetachShader");
   if (!shProg)
Brian's avatar
Brian committed
414 415
      return;

416 417
   n = shProg->NumShaders;

Brian's avatar
Brian committed
418
   for (i = 0; i < n; i++) {
419
      if (shProg->Shaders[i]->Name == shader) {
420
         /* found it */
421
         struct gl_shader **newList;
422

423
         /* release */
424
         _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
425

426
         /* alloc new, smaller array */
427
         newList = malloc((n - 1) * sizeof(struct gl_shader *));
428 429 430 431
         if (!newList) {
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDetachShader");
            return;
         }
432
         /* Copy old list entries to new list, skipping removed entry at [i] */
433
         for (j = 0; j < i; j++) {
434
            newList[j] = shProg->Shaders[j];
435
         }
436
         while (++i < n) {
437
            newList[j++] = shProg->Shaders[i];
438
         }
439

440 441
         /* Free old list and install new one */
         free(shProg->Shaders);
442
         shProg->Shaders = newList;
443
         shProg->NumShaders = n - 1;
444 445

#ifdef DEBUG
446 447
         /* sanity check - make sure the new list's entries are sensible */
         for (j = 0; j < shProg->NumShaders; j++) {
448 449 450 451 452
            assert(shProg->Shaders[j]->Stage == MESA_SHADER_VERTEX ||
                   shProg->Shaders[j]->Stage == MESA_SHADER_TESS_CTRL ||
                   shProg->Shaders[j]->Stage == MESA_SHADER_TESS_EVAL ||
                   shProg->Shaders[j]->Stage == MESA_SHADER_GEOMETRY ||
                   shProg->Shaders[j]->Stage == MESA_SHADER_FRAGMENT);
453
            assert(shProg->Shaders[j]->RefCount > 0);
454 455 456
         }
#endif

Brian's avatar
Brian committed
457 458 459 460
         return;
      }
   }

461
   /* not found */
462 463
   {
      GLenum err;
464
      if (is_shader(ctx, shader) || is_program(ctx, shader))
465 466 467
         err = GL_INVALID_OPERATION;
      else
         err = GL_INVALID_VALUE;
468
      _mesa_error(ctx, err, "glDetachShader(shader)");
469 470
      return;
   }
Brian's avatar
Brian committed
471 472 473
}


474
/**
475
 * Return list of shaders attached to shader program.
476
 */
477
static void
478
get_attached_shaders(struct gl_context *ctx, GLuint program, GLsizei maxCount,
479
                     GLsizei *count, GLuint *obj)
Brian's avatar
Brian committed
480
{
481 482 483 484 485 486 487 488
   struct gl_shader_program *shProg;

   if (maxCount < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glGetAttachedShaders(maxCount < 0)");
      return;
   }

   shProg =
489
      _mesa_lookup_shader_program_err(ctx, program, "glGetAttachedShaders");
490

491
   if (shProg) {
492 493
      GLuint i;
      for (i = 0; i < (GLuint) maxCount && i < shProg->NumShaders; i++) {
494
         obj[i] = shProg->Shaders[i]->Name;
495 496 497 498
      }
      if (count)
         *count = i;
   }
Brian's avatar
Brian committed
499 500 501
}


502 503 504
/**
 * glGetHandleARB() - return ID/name of currently bound shader program.
 */
505
static GLuint
506
get_handle(struct gl_context *ctx, GLenum pname)
Brian's avatar
Brian committed
507
{
508
   if (pname == GL_PROGRAM_OBJECT_ARB) {
509 510
      if (ctx->_Shader->ActiveProgram)
         return ctx->_Shader->ActiveProgram->Name;
511 512 513 514
      else
         return 0;
   }
   else {
515
      _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB");
516
      return 0;
Brian's avatar
Brian committed
517 518 519 520
   }
}


521 522 523 524 525 526 527 528 529 530 531 532 533 534
/**
 * Check if a geometry shader query is valid at this time.  If not, report an
 * error and return false.
 *
 * From GL 3.2 section 6.1.16 (Shader and Program Queries):
 *
 *     "If GEOMETRY_VERTICES_OUT, GEOMETRY_INPUT_TYPE, or GEOMETRY_OUTPUT_TYPE
 *     are queried for a program which has not been linked successfully, or
 *     which does not contain objects to form a geometry shader, then an
 *     INVALID_OPERATION error is generated."
 */
static bool
check_gs_query(struct gl_context *ctx, const struct gl_shader_program *shProg)
{
535
   if (shProg->data->LinkStatus &&
536 537 538 539 540 541 542 543 544 545
       shProg->_LinkedShaders[MESA_SHADER_GEOMETRY] != NULL) {
      return true;
   }

   _mesa_error(ctx, GL_INVALID_OPERATION,
               "glGetProgramv(linked geometry shader required)");
   return false;
}


546 547 548 549 550 551 552 553 554 555 556 557 558 559
/**
 * Check if a tessellation control shader query is valid at this time.
 * If not, report an error and return false.
 *
 * From GL 4.0 section 6.1.12 (Shader and Program Queries):
 *
 *     "If TESS_CONTROL_OUTPUT_VERTICES is queried for a program which has
 *     not been linked successfully, or which does not contain objects to
 *     form a tessellation control shader, then an INVALID_OPERATION error is
 *     generated."
 */
static bool
check_tcs_query(struct gl_context *ctx, const struct gl_shader_program *shProg)
{
560
   if (shProg->data->LinkStatus &&
561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585
       shProg->_LinkedShaders[MESA_SHADER_TESS_CTRL] != NULL) {
      return true;
   }

   _mesa_error(ctx, GL_INVALID_OPERATION,
               "glGetProgramv(linked tessellation control shader required)");
   return false;
}


/**
 * Check if a tessellation evaluation shader query is valid at this time.
 * If not, report an error and return false.
 *
 * From GL 4.0 section 6.1.12 (Shader and Program Queries):
 *
 *     "If any of the pname values in this paragraph are queried for a program
 *     which has not been linked successfully, or which does not contain
 *     objects to form a tessellation evaluation shader, then an
 *     INVALID_OPERATION error is generated."
 *
 */
static bool
check_tes_query(struct gl_context *ctx, const struct gl_shader_program *shProg)
{
586
   if (shProg->data->LinkStatus &&
587 588 589 590 591 592 593 594 595 596
       shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL] != NULL) {
      return true;
   }

   _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramv(linked tessellation "
               "evaluation shader required)");
   return false;
}


597 598 599 600 601
/**
 * glGetProgramiv() - get shader program state.
 * Note that this is for GLSL shader programs, not ARB vertex/fragment
 * programs (see glGetProgramivARB).
 */
602
static void
603 604
get_programiv(struct gl_context *ctx, GLuint program, GLenum pname,
              GLint *params)
Brian's avatar
Brian committed
605
{
606
   struct gl_shader_program *shProg
607
      = _mesa_lookup_shader_program_err(ctx, program, "glGetProgramiv(program)");
Brian's avatar
Brian committed
608

609 610 611
   /* Is transform feedback available in this context?
    */
   const bool has_xfb =
612
      (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.EXT_transform_feedback)
613 614 615
      || ctx->API == API_OPENGL_CORE
      || _mesa_is_gles3(ctx);

616 617
   /* True if geometry shaders (of the form that was adopted into GLSL 1.50
    * and GL 3.2) are available in this context
618
    */
619
   const bool has_core_gs = _mesa_has_geometry_shaders(ctx);
620
   const bool has_tess = _mesa_has_tessellation(ctx);
621 622 623 624

   /* Are uniform buffer objects available in this context?
    */
   const bool has_ubo =
625 626
      (ctx->API == API_OPENGL_COMPAT &&
       ctx->Extensions.ARB_uniform_buffer_object)
627 628 629
      || ctx->API == API_OPENGL_CORE
      || _mesa_is_gles3(ctx);

630
   if (!shProg) {
Brian's avatar
Brian committed
631
      return;
632
   }
Brian's avatar
Brian committed
633 634 635

   switch (pname) {
   case GL_DELETE_STATUS:
636
      *params = shProg->DeletePending;
637
      return;
Brian's avatar
Brian committed
638
   case GL_LINK_STATUS:
639
      *params = shProg->data->LinkStatus;
640
      return;
Brian's avatar
Brian committed
641
   case GL_VALIDATE_STATUS:
642
      *params = shProg->data->Validated;
643
      return;
Brian's avatar
Brian committed
644
   case GL_INFO_LOG_LENGTH:
645 646
      *params = (shProg->data->InfoLog && shProg->data->InfoLog[0] != '\0') ?
         strlen(shProg->data->InfoLog) + 1 : 0;
647
      return;
Brian's avatar
Brian committed
648
   case GL_ATTACHED_SHADERS:
649
      *params = shProg->NumShaders;
650
      return;
Brian's avatar
Brian committed
651
   case GL_ACTIVE_ATTRIBUTES:
652
      *params = _mesa_count_active_attribs(shProg);
653
      return;
Brian's avatar
Brian committed
654
   case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
655
      *params = _mesa_longest_attribute_name_length(shProg);
656
      return;
657 658 659
   case GL_ACTIVE_UNIFORMS: {
      unsigned i;
      const unsigned num_uniforms =
660
         shProg->data->NumUniformStorage - shProg->data->NumHiddenUniforms;
661
      for (*params = 0, i = 0; i < num_uniforms; i++) {
662
         if (!shProg->data->UniformStorage[i].is_shader_storage)
663 664
            (*params)++;
      }
665
      return;
666
   }
667 668 669
   case GL_ACTIVE_UNIFORM_MAX_LENGTH: {
      unsigned i;
      GLint max_len = 0;
670
      const unsigned num_uniforms =
671
         shProg->data->NumUniformStorage - shProg->data->NumHiddenUniforms;
672

673
      for (i = 0; i < num_uniforms; i++) {
674
         if (shProg->data->UniformStorage[i].is_shader_storage)
675 676
            continue;

677 678
	 /* Add one for the terminating NUL character for a non-array, and
	  * 4 for the "[0]" and the NUL for an array.
679
	  */
680 681
         const GLint len = strlen(shProg->data->UniformStorage[i].name) + 1 +
             ((shProg->data->UniformStorage[i].array_elements != 0) ? 3 : 0);
682 683 684 685 686 687

	 if (len > max_len)
	    max_len = len;
      }

      *params = max_len;
688
      return;
689
   }
690
   case GL_TRANSFORM_FEEDBACK_VARYINGS:
691
      if (!has_xfb)
692
         break;
693
      *params = shProg->TransformFeedback.NumVarying;
694
      return;
695 696 697
   case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: {
      unsigned i;
      GLint max_len = 0;
698
      if (!has_xfb)
699
         break;
700 701 702 703

      for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) {
         /* Add one for the terminating NUL character.
          */
704 705
         const GLint len =
            strlen(shProg->TransformFeedback.VaryingNames[i]) + 1;
706 707 708 709 710 711

         if (len > max_len)
            max_len = len;
      }

      *params = max_len;
712
      return;
713
   }
714
   case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
715
      if (!has_xfb)
716
         break;
717
      *params = shProg->TransformFeedback.BufferMode;
718
      return;
719 720
   case GL_GEOMETRY_VERTICES_OUT:
      if (!has_core_gs)
721
         break;
722 723
      if (check_gs_query(ctx, shProg)) {
         *params = shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->
724
            info.Geom.VerticesOut;
725
      }
726
      return;
727 728 729
   case GL_GEOMETRY_SHADER_INVOCATIONS:
      if (!has_core_gs || !ctx->Extensions.ARB_gpu_shader5)
         break;
730 731
      if (check_gs_query(ctx, shProg)) {
         *params = shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->
732
            info.Geom.Invocations;
733
      }
734
      return;
735 736
   case GL_GEOMETRY_INPUT_TYPE:
      if (!has_core_gs)
737
         break;
738 739
      if (check_gs_query(ctx, shProg)) {
         *params = shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->
740
            info.Geom.InputType;
741
      }
742
      return;
743 744
   case GL_GEOMETRY_OUTPUT_TYPE:
      if (!has_core_gs)
745
         break;
746 747
      if (check_gs_query(ctx, shProg)) {
         *params = shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->
748
            info.Geom.OutputType;
749
      }
750
      return;
751 752 753 754
   case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: {
      unsigned i;
      GLint max_len = 0;

755
      if (!has_ubo)
756
         break;
757

758
      for (i = 0; i < shProg->data->NumUniformBlocks; i++) {
759 760
	 /* Add one for the terminating NUL character.
	  */
761
         const GLint len = strlen(shProg->data->UniformBlocks[i].Name) + 1;
762 763 764 765 766 767

	 if (len > max_len)
	    max_len = len;
      }

      *params = max_len;
768
      return;
769 770
   }
   case GL_ACTIVE_UNIFORM_BLOCKS:
771
      if (!has_ubo)
772
         break;
773

774
      *params = shProg->data->NumUniformBlocks;
Brian's avatar
Brian committed
775
      return;
776 777 778 779 780 781 782 783 784 785 786 787
   case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
      /* This enum isn't part of the OES extension for OpenGL ES 2.0.  It is
       * only available with desktop OpenGL 3.0+ with the
       * GL_ARB_get_program_binary extension or OpenGL ES 3.0.
       *
       * On desktop, we ignore the 3.0+ requirement because it is silly.
       */
      if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
         break;

      *params = shProg->BinaryRetreivableHint;
      return;
788 789 790
   case GL_PROGRAM_BINARY_LENGTH:
      *params = 0;
      return;
791 792 793 794
   case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS:
      if (!ctx->Extensions.ARB_shader_atomic_counters)
         break;

795
      *params = shProg->data->NumAtomicBuffers;
796
      return;
797 798
   case GL_COMPUTE_WORK_GROUP_SIZE: {
      int i;
799
      if (!_mesa_has_compute_shaders(ctx))
800
         break;
801
      if (!shProg->data->LinkStatus) {
802 803 804 805 806 807 808 809 810 811 812 813 814
         _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramiv(program not "
                     "linked)");
         return;
      }
      if (shProg->_LinkedShaders[MESA_SHADER_COMPUTE] == NULL) {
         _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramiv(no compute "
                     "shaders)");
         return;
      }
      for (i = 0; i < 3; i++)
         params[i] = shProg->Comp.LocalSize[i];
      return;
   }
815
   case GL_PROGRAM_SEPARABLE:
816
      /* If the program has not been linked, return initial value 0. */
817
      *params = (shProg->data->LinkStatus == GL_FALSE) ? 0 : shProg->SeparateShader;
818
      return;
819 820 821 822 823

   /* ARB_tessellation_shader */
   case GL_TESS_CONTROL_OUTPUT_VERTICES:
      if (!has_tess)
         break;
824 825
      if (check_tcs_query(ctx, shProg)) {
         *params = shProg->_LinkedShaders[MESA_SHADER_TESS_CTRL]->
826
            info.TessCtrl.VerticesOut;
827
      }
828 829 830 831
      return;
   case GL_TESS_GEN_MODE:
      if (!has_tess)
         break;
832 833
      if (check_tes_query(ctx, shProg)) {
         *params = shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]->
834
            info.TessEval.PrimitiveMode;
835
      }
836 837 838 839
      return;
   case GL_TESS_GEN_SPACING:
      if (!has_tess)
         break;
840
      if (check_tes_query(ctx, shProg)) {
841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856
         const struct gl_linked_shader *tes =
            shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL];
         switch (tes->info.TessEval.Spacing) {
         case TESS_SPACING_EQUAL:
            *params = GL_EQUAL;
            break;
         case TESS_SPACING_FRACTIONAL_ODD:
            *params = GL_FRACTIONAL_ODD;
            break;
         case TESS_SPACING_FRACTIONAL_EVEN:
            *params = GL_FRACTIONAL_EVEN;
            break;
         case TESS_SPACING_UNSPECIFIED:
            *params = 0;
            break;
         }
857
      }
858 859 860 861
      return;
   case GL_TESS_GEN_VERTEX_ORDER:
      if (!has_tess)
         break;
862 863
      if (check_tes_query(ctx, shProg)) {
         *params = shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]->
864
            info.TessEval.VertexOrder;
865
         }
866 867 868 869
      return;
   case GL_TESS_GEN_POINT_MODE:
      if (!has_tess)
         break;
870 871
      if (check_tes_query(ctx, shProg)) {
         *params = shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]->
872
            info.TessEval.PointMode;
873
      }
874
      return;
875 876
   default:
      break;
Brian's avatar
Brian committed
877
   }
878 879

   _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname=%s)",
880
               _mesa_enum_to_string(pname));
Brian's avatar
Brian committed
881 882 883
}


884 885 886
/**
 * glGetShaderiv() - get GLSL shader state
 */
887
static void
888
get_shaderiv(struct gl_context *ctx, GLuint name, GLenum pname, GLint *params)
Brian's avatar
Brian committed
889
{
890 891
   struct gl_shader *shader =
      _mesa_lookup_shader_err(ctx, name, "glGetShaderiv");
Brian's avatar
Brian committed
892

893
   if (!shader) {
Brian's avatar
Brian committed
894
      return;
895
   }
896

Brian's avatar
Brian committed
897 898
   switch (pname) {
   case GL_SHADER_TYPE:
899
      *params = shader->Type;
Brian's avatar
Brian committed
900 901
      break;
   case GL_DELETE_STATUS:
902
      *params = shader->DeletePending;
Brian's avatar
Brian committed
903 904
      break;
   case GL_COMPILE_STATUS:
905
      *params = shader->CompileStatus;
Brian's avatar
Brian committed
906 907
      break;
   case GL_INFO_LOG_LENGTH:
908 909
      *params = (shader->InfoLog && shader->InfoLog[0] != '\0') ?
         strlen(shader->InfoLog) + 1 : 0;
Brian's avatar
Brian committed
910 911
      break;
   case GL_SHADER_SOURCE_LENGTH:
912
      *params = shader->Source ? strlen((char *) shader->Source) + 1 : 0;
Brian's avatar
Brian committed
913 914 915 916 917 918 919 920
      break;
   default:
      _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)");
      return;
   }
}


921
static void
922
get_program_info_log(struct gl_context *ctx, GLuint program, GLsizei bufSize,
923
                     GLsizei *length, GLchar *infoLog)
Brian's avatar
Brian committed
924
{
925 926 927 928 929 930 931 932 933 934 935 936 937 938 939
   struct gl_shader_program *shProg;

   /* Section 2.5 GL Errors (page 18) of the OpenGL ES 3.0.4 spec and
    * section 2.3.1 (Errors) of the OpenGL 4.5 spec say:
    *
    *     "If a negative number is provided where an argument of type sizei or
    *     sizeiptr is specified, an INVALID_VALUE error is generated."
    */
   if (bufSize < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramInfoLog(bufSize < 0)");
      return;
   }

   shProg = _mesa_lookup_shader_program_err(ctx, program,
                                            "glGetProgramInfoLog(program)");
940
   if (!shProg) {
941 942
      return;
   }
943

944
   _mesa_copy_string(infoLog, bufSize, length, shProg->data->InfoLog);
Brian's avatar
Brian committed
945 946 947
}


948
static void
949
get_shader_info_log(struct gl_context *ctx, GLuint shader, GLsizei bufSize,
950
                    GLsizei *length, GLchar *infoLog)
951
{
952 953 954 955 956 957 958 959 960 961 962 963 964 965
   struct gl_shader *sh;

   /* Section 2.5 GL Errors (page 18) of the OpenGL ES 3.0.4 spec and
    * section 2.3.1 (Errors) of the OpenGL 4.5 spec say:
    *
    *     "If a negative number is provided where an argument of type sizei or
    *     sizeiptr is specified, an INVALID_VALUE error is generated."
    */
   if (bufSize < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderInfoLog(bufSize < 0)");
      return;
   }

   sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderInfoLog(shader)");
966
   if (!sh) {
967 968
      return;
   }
969

970
   _mesa_copy_string(infoLog, bufSize, length, sh->InfoLog);
971 972 973 974
}


/**
975
 * Return shader source code.
976
 */
977
static void
978
get_shader_source(struct gl_context *ctx, GLuint shader, GLsizei maxLength,
979
                  GLsizei *length, GLchar *sourceOut)
980
{
981
   struct gl_shader *sh;
982 983 984 985 986 987

   if (maxLength < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderSource(bufSize < 0)");
      return;
   }

988
   sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderSource");
989
   if (!sh) {
990 991
      return;
   }
992
   _mesa_copy_string(sourceOut, maxLength, length, sh->Source);
993 994 995 996
}


/**
997
 * Set/replace shader source code.  A helper function used by
998
 * glShaderSource[ARB].
999
 */
1000
static void
1001
shader_source(struct gl_shader *sh, const GLchar *source)
Brian's avatar
Brian committed
1002
{
1003
   assert(sh);
1004 1005

   /* free old shader source string and install new one */
1006
   free((void *)sh->Source);
1007
   sh->Source = source;
1008
#ifdef DEBUG
1009
   sh->SourceChecksum = util_hash_crc32(sh->Source, strlen(sh->Source));
1010
#endif
Brian's avatar
Brian committed
1011 1012
}

1013 1014

/**
1015
 * Compile a shader.
1016
 */
1017 1018
void
_mesa_compile_shader(struct gl_context *ctx, struct gl_shader *sh)
Brian's avatar
Brian committed
1019
{
1020
   if (!sh)
1021 1022
      return;

1023 1024 1025 1026 1027 1028
   if (!sh->Source) {
      /* If the user called glCompileShader without first calling
       * glShaderSource, we should fail to compile, but not raise a GL_ERROR.
       */
      sh->CompileStatus = GL_FALSE;
   } else {
1029
      if (ctx->_Shader->Flags & GLSL_DUMP) {
1030
         _mesa_log("GLSL source for %s shader %d:\n",
1031
                 _mesa_shader_stage_to_string(sh->Stage), sh->Name);
1032
         _mesa_log("%s\n", sh->Source);
1033 1034 1035 1036 1037
      }

      /* this call will set the shader->CompileStatus field to indicate if
       * compilation was successful.
       */
1038
      _mesa_glsl_compile_shader(ctx, sh, false, false);
1039

1040
      if (ctx->_Shader->Flags & GLSL_LOG) {
1041 1042 1043
         _mesa_write_shader_to_file(sh);
      }

1044
      if (ctx->_Shader->Flags & GLSL_DUMP) {
1045
         if (sh->CompileStatus) {
1046 1047 1048 1049 1050 1051 1052
            if (sh->ir) {
               _mesa_log("GLSL IR for shader %d:\n", sh->Name);
               _mesa_print_ir(_mesa_get_log_file(), sh->ir, NULL);
            } else {
               _mesa_log("No GLSL IR for shader %d (shader may be from "
                         "cache)\n", sh->Name);
            }
1053
            _mesa_log("\n\n");
1054
         } else {
1055
            _mesa_log("GLSL shader %d failed to compile.\n", sh->Name);
1056 1057
         }
         if (sh->InfoLog && sh->InfoLog[0] != 0) {
1058 1059
            _mesa_log("GLSL shader %d info log:\n", sh->Name);
            _mesa_log("%s\n", sh->InfoLog);
1060 1061 1062
         }
      }
   }
1063

1064
   if (!sh->CompileStatus) {
1065
      if (ctx->_Shader->Flags & GLSL_DUMP_ON_ERROR) {
1066
         _mesa_log("GLSL source for %s shader %d:\n",
1067
                 _mesa_shader_stage_to_string(sh->Stage), sh->Name);
1068 1069
         _mesa_log("%s\n", sh->Source);
         _mesa_log("Info Log:\n%s\n", sh->InfoLog);
1070 1071
      }

1072
      if (ctx->_Shader->Flags & GLSL_REPORT_ERRORS) {
1073 1074 1075
         _mesa_debug(ctx, "Error compiling shader %u:\n%s\n",
                     sh->Name, sh->InfoLog);
      }
1076
   }
Brian's avatar
Brian committed
1077 1078
}

1079 1080

/**
1081
 * Link a program's shaders.
1082
 */
1083 1084
void
_mesa_link_program(struct gl_context *ctx, struct gl_shader_program *shProg)
Brian's avatar
Brian committed
1085
{
1086
   if (!shProg)
1087 1088
      return;

1089 1090 1091 1092 1093 1094
   /* From the ARB_transform_feedback2 specification:
    * "The error INVALID_OPERATION is generated by LinkProgram if <program> is
    *  the name of a program being used by one or more transform feedback
    *  objects, even if the objects are not currently bound or are paused."
    */
   if (_mesa_transform_feedback_is_using_program(ctx, shProg)) {
1095
      _mesa_error(ctx, GL_INVALID_OPERATION,
1096
                  "glLinkProgram(transform feedback is using the program)");
1097 1098 1099
      return;
   }

1100 1101
   FLUSH_VERTICES(ctx, _NEW_PROGRAM);

1102
   _mesa_glsl_link_shader(ctx, shProg);
1103

1104 1105
   /* Capture .shader_test files. */
   const char *capture_path = _mesa_get_shader_capture_path();
1106
   if (shProg->Name != 0 && shProg->Name != ~0 && capture_path != NULL) {
1107
      FILE *file;
1108 1109
      char *filename = ralloc_asprintf(NULL, "%s/%u.shader_test",
                                       capture_path, shProg->Name);
1110 1111 1112 1113
      file = fopen(filename, "w");
      if (file) {
         fprintf(file, "[require]\nGLSL%s >= %u.%02u\n",
                 shProg->IsES ? " ES" : "",
1114
                 shProg->data->Version / 100, shProg->data->Version % 100);
1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127
         if (shProg->SeparateShader)
            fprintf(file, "GL_ARB_separate_shader_objects\nSSO ENABLED\n");
         fprintf(file, "\n");

         for (unsigned i = 0; i < shProg->NumShaders; i++) {
            fprintf(file, "[%s shader]\n%s\n",
                    _mesa_shader_stage_to_string(shProg->Shaders[i]->Stage),
                    shProg->Shaders[i]->Source);
         }
         fclose(file);
      } else {
         _mesa_warning(ctx, "Failed to open %s", filename);
      }
1128 1129

      ralloc_free(filename);
1130 1131
   }

1132
   if (shProg->data->LinkStatus == GL_FALSE &&
1133
       (ctx->_Shader->Flags & GLSL_REPORT_ERRORS)) {
1134
      _mesa_debug(ctx, "Error linking program %u:\n%s\n",
1135
                  shProg->Name, shProg->data->InfoLog);
1136 1137
   }

1138 1139 1140 1141
   /* debug code */
   if (0) {
      GLuint i;

1142
      printf("Link %u shaders in program %u: %s\n",
1143
                   shProg->NumShaders, shProg->Name,
1144
                   shProg->data->LinkStatus ? "Success" : "Failed");
1145 1146

      for (i = 0; i < shProg->NumShaders; i++) {
1147
         printf(" shader %u, stage %u\n",
1148