Subversion Repositories Kolibri OS

Rev

Rev 1901 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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