Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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