~ubuntu-branches/ubuntu/natty/mesa/natty-proposed

« back to all changes in this revision

Viewing changes to src/mesa/shader/shader_api.c

  • Committer: Bazaar Package Importer
  • Author(s): Robert Hooker, Robert Hooker, Christopher James Halse Rogers
  • Date: 2010-09-14 08:55:40 UTC
  • mfrom: (1.2.28 upstream)
  • Revision ID: james.westby@ubuntu.com-20100914085540-m4fpl0hdjlfd4jgz
Tags: 7.9~git20100909-0ubuntu1
[ Robert Hooker ]
* New upstream git snapshot up to commit 94118fe2d4b1e5 (LP: #631413)
* New features include ATI HD5xxx series support in r600, and a vastly
  improved glsl compiler.
* Remove pre-generated .pc's, use the ones generated at build time
  instead.
* Remove all references to mesa-utils now that its no longer shipped
  with the mesa source.
* Disable the experimental ARB_fragment_shader option by default on
  i915, it exposes incomplete functionality that breaks KDE compositing
  among other things. It can be enabled via driconf still. (LP: #628930).

[ Christopher James Halse Rogers ]
* debian/patches/04_osmesa_version.diff:
  - Refresh for new upstream
* Bugs fixed in this release:
  - Fixes severe rendering corruption in Unity on radeon (LP: #628727,
    LP: #596292, LP: #599741, LP: #630315, LP: #613694, LP: #599741).
  - Also fixes rendering in gnome-shell (LP: #578619).
  - Flickering in OpenGL apps on radeon (LP: #626943, LP: #610541).
  - Provides preliminary support for new intel chips (LP: #601052).
* debian/rules:
  - Update configure flags to match upstream reshuffling.
  - Explicitly remove gallium DRI drivers that we don't want to ship.
* Update debian/gbp.conf for this Maverick-specific packaging
* libegl1-mesa-dri-x11,kms: There are no longer separate kms or x11 drivers
  for EGL, libegl1-mesa-drivers now contains a single driver that provides
  both backends.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Mesa 3-D graphics library
3
 
 * Version:  7.6
4
 
 *
5
 
 * Copyright (C) 2004-2008  Brian Paul   All Rights Reserved.
6
 
 * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
7
 
 *
8
 
 * Permission is hereby granted, free of charge, to any person obtaining a
9
 
 * copy of this software and associated documentation files (the "Software"),
10
 
 * to deal in the Software without restriction, including without limitation
11
 
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12
 
 * and/or sell copies of the Software, and to permit persons to whom the
13
 
 * Software is furnished to do so, subject to the following conditions:
14
 
 *
15
 
 * The above copyright notice and this permission notice shall be included
16
 
 * in all copies or substantial portions of the Software.
17
 
 *
18
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19
 
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21
 
 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22
 
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
 
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
 
 */
25
 
 
26
 
/**
27
 
 * \file shader_api.c
28
 
 * Implementation of GLSL-related API functions
29
 
 * \author Brian Paul
30
 
 */
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/hash.h"
42
 
#include "shader/program.h"
43
 
#include "shader/prog_parameter.h"
44
 
#include "shader/prog_statevars.h"
45
 
#include "shader/prog_uniform.h"
46
 
#include "shader/shader_api.h"
47
 
#include "shader/slang/slang_compile.h"
48
 
#include "shader/slang/slang_link.h"
49
 
#include "main/dispatch.h"
50
 
 
51
 
 
52
 
/**
53
 
 * Allocate a new gl_shader_program object, initialize it.
54
 
 */
55
 
static struct gl_shader_program *
56
 
_mesa_new_shader_program(GLcontext *ctx, GLuint name)
57
 
{
58
 
   struct gl_shader_program *shProg;
59
 
   shProg = CALLOC_STRUCT(gl_shader_program);
60
 
   if (shProg) {
61
 
      shProg->Type = GL_SHADER_PROGRAM_MESA;
62
 
      shProg->Name = name;
63
 
      shProg->RefCount = 1;
64
 
      shProg->Attributes = _mesa_new_parameter_list();
65
 
   }
66
 
   return shProg;
67
 
}
68
 
 
69
 
 
70
 
/**
71
 
 * Clear (free) the shader program state that gets produced by linking.
72
 
 */
73
 
void
74
 
_mesa_clear_shader_program_data(GLcontext *ctx,
75
 
                                struct gl_shader_program *shProg)
76
 
{
77
 
   _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL);
78
 
   _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL);
79
 
 
80
 
   if (shProg->Uniforms) {
81
 
      _mesa_free_uniform_list(shProg->Uniforms);
82
 
      shProg->Uniforms = NULL;
83
 
   }
84
 
 
85
 
   if (shProg->Varying) {
86
 
      _mesa_free_parameter_list(shProg->Varying);
87
 
      shProg->Varying = NULL;
88
 
   }
89
 
}
90
 
 
91
 
 
92
 
/**
93
 
 * Free all the data that hangs off a shader program object, but not the
94
 
 * object itself.
95
 
 */
96
 
void
97
 
_mesa_free_shader_program_data(GLcontext *ctx,
98
 
                               struct gl_shader_program *shProg)
99
 
{
100
 
   GLuint i;
101
 
 
102
 
   assert(shProg->Type == GL_SHADER_PROGRAM_MESA);
103
 
 
104
 
   _mesa_clear_shader_program_data(ctx, shProg);
105
 
 
106
 
   if (shProg->Attributes) {
107
 
      _mesa_free_parameter_list(shProg->Attributes);
108
 
      shProg->Attributes = NULL;
109
 
   }
110
 
 
111
 
   /* detach shaders */
112
 
   for (i = 0; i < shProg->NumShaders; i++) {
113
 
      _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
114
 
   }
115
 
   shProg->NumShaders = 0;
116
 
 
117
 
   if (shProg->Shaders) {
118
 
      free(shProg->Shaders);
119
 
      shProg->Shaders = NULL;
120
 
   }
121
 
 
122
 
   if (shProg->InfoLog) {
123
 
      free(shProg->InfoLog);
124
 
      shProg->InfoLog = NULL;
125
 
   }
126
 
}
127
 
 
128
 
 
129
 
/**
130
 
 * Free/delete a shader program object.
131
 
 */
132
 
void
133
 
_mesa_free_shader_program(GLcontext *ctx, struct gl_shader_program *shProg)
134
 
{
135
 
   _mesa_free_shader_program_data(ctx, shProg);
136
 
 
137
 
   free(shProg);
138
 
}
139
 
 
140
 
 
141
 
/**
142
 
 * Set ptr to point to shProg.
143
 
 * If ptr is pointing to another object, decrement its refcount (and delete
144
 
 * if refcount hits zero).
145
 
 * Then set ptr to point to shProg, incrementing its refcount.
146
 
 */
147
 
/* XXX this could be static */
148
 
void
149
 
_mesa_reference_shader_program(GLcontext *ctx,
150
 
                               struct gl_shader_program **ptr,
151
 
                               struct gl_shader_program *shProg)
152
 
{
153
 
   assert(ptr);
154
 
   if (*ptr == shProg) {
155
 
      /* no-op */
156
 
      return;
157
 
   }
158
 
   if (*ptr) {
159
 
      /* Unreference the old shader program */
160
 
      GLboolean deleteFlag = GL_FALSE;
161
 
      struct gl_shader_program *old = *ptr;
162
 
 
163
 
      ASSERT(old->RefCount > 0);
164
 
      old->RefCount--;
165
 
#if 0
166
 
      printf("ShaderProgram %p ID=%u  RefCount-- to %d\n",
167
 
             (void *) old, old->Name, old->RefCount);
168
 
#endif
169
 
      deleteFlag = (old->RefCount == 0);
170
 
 
171
 
      if (deleteFlag) {
172
 
         _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name);
173
 
         _mesa_free_shader_program(ctx, old);
174
 
      }
175
 
 
176
 
      *ptr = NULL;
177
 
   }
178
 
   assert(!*ptr);
179
 
 
180
 
   if (shProg) {
181
 
      shProg->RefCount++;
182
 
#if 0
183
 
      printf("ShaderProgram %p ID=%u  RefCount++ to %d\n",
184
 
             (void *) shProg, shProg->Name, shProg->RefCount);
185
 
#endif
186
 
      *ptr = shProg;
187
 
   }
188
 
}
189
 
 
190
 
 
191
 
/**
192
 
 * Lookup a GLSL program object.
193
 
 */
194
 
struct gl_shader_program *
195
 
_mesa_lookup_shader_program(GLcontext *ctx, GLuint name)
196
 
{
197
 
   struct gl_shader_program *shProg;
198
 
   if (name) {
199
 
      shProg = (struct gl_shader_program *)
200
 
         _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
201
 
      /* Note that both gl_shader and gl_shader_program objects are kept
202
 
       * in the same hash table.  Check the object's type to be sure it's
203
 
       * what we're expecting.
204
 
       */
205
 
      if (shProg && shProg->Type != GL_SHADER_PROGRAM_MESA) {
206
 
         return NULL;
207
 
      }
208
 
      return shProg;
209
 
   }
210
 
   return NULL;
211
 
}
212
 
 
213
 
 
214
 
/**
215
 
 * As above, but record an error if program is not found.
216
 
 */
217
 
static struct gl_shader_program *
218
 
_mesa_lookup_shader_program_err(GLcontext *ctx, GLuint name,
219
 
                                const char *caller)
220
 
{
221
 
   if (!name) {
222
 
      _mesa_error(ctx, GL_INVALID_VALUE, caller);
223
 
      return NULL;
224
 
   }
225
 
   else {
226
 
      struct gl_shader_program *shProg = (struct gl_shader_program *)
227
 
         _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
228
 
      if (!shProg) {
229
 
         _mesa_error(ctx, GL_INVALID_VALUE, caller);
230
 
         return NULL;
231
 
      }
232
 
      if (shProg->Type != GL_SHADER_PROGRAM_MESA) {
233
 
         _mesa_error(ctx, GL_INVALID_OPERATION, caller);
234
 
         return NULL;
235
 
      }
236
 
      return shProg;
237
 
   }
238
 
}
239
 
 
240
 
 
241
 
 
242
 
 
243
 
/**
244
 
 * Allocate a new gl_shader object, initialize it.
245
 
 */
246
 
struct gl_shader *
247
 
_mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type)
248
 
{
249
 
   struct gl_shader *shader;
250
 
   assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER);
251
 
   shader = CALLOC_STRUCT(gl_shader);
252
 
   if (shader) {
253
 
      shader->Type = type;
254
 
      shader->Name = name;
255
 
      shader->RefCount = 1;
256
 
   }
257
 
   return shader;
258
 
}
259
 
 
260
 
 
261
 
void
262
 
_mesa_free_shader(GLcontext *ctx, struct gl_shader *sh)
263
 
{
264
 
   if (sh->Source)
265
 
      free((void *) sh->Source);
266
 
   if (sh->InfoLog)
267
 
      free(sh->InfoLog);
268
 
   _mesa_reference_program(ctx, &sh->Program, NULL);
269
 
   free(sh);
270
 
}
271
 
 
272
 
 
273
 
/**
274
 
 * Set ptr to point to sh.
275
 
 * If ptr is pointing to another shader, decrement its refcount (and delete
276
 
 * if refcount hits zero).
277
 
 * Then set ptr to point to sh, incrementing its refcount.
278
 
 */
279
 
/* XXX this could be static */
280
 
void
281
 
_mesa_reference_shader(GLcontext *ctx, struct gl_shader **ptr,
282
 
                       struct gl_shader *sh)
283
 
{
284
 
   assert(ptr);
285
 
   if (*ptr == sh) {
286
 
      /* no-op */
287
 
      return;
288
 
   }
289
 
   if (*ptr) {
290
 
      /* Unreference the old shader */
291
 
      GLboolean deleteFlag = GL_FALSE;
292
 
      struct gl_shader *old = *ptr;
293
 
 
294
 
      ASSERT(old->RefCount > 0);
295
 
      old->RefCount--;
296
 
      /*printf("SHADER DECR %p (%d) to %d\n",
297
 
        (void*) old, old->Name, old->RefCount);*/
298
 
      deleteFlag = (old->RefCount == 0);
299
 
 
300
 
      if (deleteFlag) {
301
 
         _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name);
302
 
         _mesa_free_shader(ctx, old);
303
 
      }
304
 
 
305
 
      *ptr = NULL;
306
 
   }
307
 
   assert(!*ptr);
308
 
 
309
 
   if (sh) {
310
 
      /* reference new */
311
 
      sh->RefCount++;
312
 
      /*printf("SHADER INCR %p (%d) to %d\n",
313
 
        (void*) sh, sh->Name, sh->RefCount);*/
314
 
      *ptr = sh;
315
 
   }
316
 
}
317
 
 
318
 
 
319
 
/**
320
 
 * Lookup a GLSL shader object.
321
 
 */
322
 
struct gl_shader *
323
 
_mesa_lookup_shader(GLcontext *ctx, GLuint name)
324
 
{
325
 
   if (name) {
326
 
      struct gl_shader *sh = (struct gl_shader *)
327
 
         _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
328
 
      /* Note that both gl_shader and gl_shader_program objects are kept
329
 
       * in the same hash table.  Check the object's type to be sure it's
330
 
       * what we're expecting.
331
 
       */
332
 
      if (sh && sh->Type == GL_SHADER_PROGRAM_MESA) {
333
 
         return NULL;
334
 
      }
335
 
      return sh;
336
 
   }
337
 
   return NULL;
338
 
}
339
 
 
340
 
 
341
 
/**
342
 
 * As above, but record an error if shader is not found.
343
 
 */
344
 
static struct gl_shader *
345
 
_mesa_lookup_shader_err(GLcontext *ctx, GLuint name, const char *caller)
346
 
{
347
 
   if (!name) {
348
 
      _mesa_error(ctx, GL_INVALID_VALUE, caller);
349
 
      return NULL;
350
 
   }
351
 
   else {
352
 
      struct gl_shader *sh = (struct gl_shader *)
353
 
         _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
354
 
      if (!sh) {
355
 
         _mesa_error(ctx, GL_INVALID_VALUE, caller);
356
 
         return NULL;
357
 
      }
358
 
      if (sh->Type == GL_SHADER_PROGRAM_MESA) {
359
 
         _mesa_error(ctx, GL_INVALID_OPERATION, caller);
360
 
         return NULL;
361
 
      }
362
 
      return sh;
363
 
   }
364
 
}
365
 
 
366
 
 
367
 
/**
368
 
 * Return mask of GLSL_x flags by examining the MESA_GLSL env var.
369
 
 */
370
 
static GLbitfield
371
 
get_shader_flags(void)
372
 
{
373
 
   GLbitfield flags = 0x0;
374
 
   const char *env = _mesa_getenv("MESA_GLSL");
375
 
 
376
 
   if (env) {
377
 
      if (strstr(env, "dump"))
378
 
         flags |= GLSL_DUMP;
379
 
      if (strstr(env, "log"))
380
 
         flags |= GLSL_LOG;
381
 
      if (strstr(env, "nopvert"))
382
 
         flags |= GLSL_NOP_VERT;
383
 
      if (strstr(env, "nopfrag"))
384
 
         flags |= GLSL_NOP_FRAG;
385
 
      if (strstr(env, "nopt"))
386
 
         flags |= GLSL_NO_OPT;
387
 
      else if (strstr(env, "opt"))
388
 
         flags |= GLSL_OPT;
389
 
      if (strstr(env, "uniform"))
390
 
         flags |= GLSL_UNIFORMS;
391
 
      if (strstr(env, "useprog"))
392
 
         flags |= GLSL_USE_PROG;
393
 
   }
394
 
 
395
 
   return flags;
396
 
}
397
 
 
398
 
 
399
 
/**
400
 
 * Initialize context's shader state.
401
 
 */
402
 
void
403
 
_mesa_init_shader_state(GLcontext * ctx)
404
 
{
405
 
   /* Device drivers may override these to control what kind of instructions
406
 
    * are generated by the GLSL compiler.
407
 
    */
408
 
   ctx->Shader.EmitHighLevelInstructions = GL_TRUE;
409
 
   ctx->Shader.EmitContReturn = GL_TRUE;
410
 
   ctx->Shader.EmitCondCodes = GL_FALSE;
411
 
   ctx->Shader.EmitComments = GL_FALSE;
412
 
   ctx->Shader.Flags = get_shader_flags();
413
 
 
414
 
   /* Default pragma settings */
415
 
   ctx->Shader.DefaultPragmas.IgnoreOptimize = GL_FALSE;
416
 
   ctx->Shader.DefaultPragmas.IgnoreDebug = GL_FALSE;
417
 
   ctx->Shader.DefaultPragmas.Optimize = GL_TRUE;
418
 
   ctx->Shader.DefaultPragmas.Debug = GL_FALSE;
419
 
}
420
 
 
421
 
 
422
 
/**
423
 
 * Free the per-context shader-related state.
424
 
 */
425
 
void
426
 
_mesa_free_shader_state(GLcontext *ctx)
427
 
{
428
 
   _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram, NULL);
429
 
}
430
 
 
431
 
 
432
 
/**
433
 
 * Copy string from <src> to <dst>, up to maxLength characters, returning
434
 
 * length of <dst> in <length>.
435
 
 * \param src  the strings source
436
 
 * \param maxLength  max chars to copy
437
 
 * \param length  returns number of chars copied
438
 
 * \param dst  the string destination
439
 
 */
440
 
static void
441
 
copy_string(GLchar *dst, GLsizei maxLength, GLsizei *length, const GLchar *src)
442
 
{
443
 
   GLsizei len;
444
 
   for (len = 0; len < maxLength - 1 && src && src[len]; len++)
445
 
      dst[len] = src[len];
446
 
   if (maxLength > 0)
447
 
      dst[len] = 0;
448
 
   if (length)
449
 
      *length = len;
450
 
}
451
 
 
452
 
 
453
 
static GLboolean
454
 
_mesa_is_program(GLcontext *ctx, GLuint name)
455
 
{
456
 
   struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, name);
457
 
   return shProg ? GL_TRUE : GL_FALSE;
458
 
}
459
 
 
460
 
 
461
 
static GLboolean
462
 
_mesa_is_shader(GLcontext *ctx, GLuint name)
463
 
{
464
 
   struct gl_shader *shader = _mesa_lookup_shader(ctx, name);
465
 
   return shader ? GL_TRUE : GL_FALSE;
466
 
}
467
 
 
468
 
 
469
 
/**
470
 
 * Called via ctx->Driver.AttachShader()
471
 
 */
472
 
static void
473
 
_mesa_attach_shader(GLcontext *ctx, GLuint program, GLuint shader)
474
 
{
475
 
   struct gl_shader_program *shProg;
476
 
   struct gl_shader *sh;
477
 
   GLuint i, n;
478
 
 
479
 
   shProg = _mesa_lookup_shader_program_err(ctx, program, "glAttachShader");
480
 
   if (!shProg)
481
 
      return;
482
 
 
483
 
   sh = _mesa_lookup_shader_err(ctx, shader, "glAttachShader");
484
 
   if (!sh) {
485
 
      return;
486
 
   }
487
 
 
488
 
   n = shProg->NumShaders;
489
 
   for (i = 0; i < n; i++) {
490
 
      if (shProg->Shaders[i] == sh) {
491
 
         /* The shader is already attched to this program.  The
492
 
          * GL_ARB_shader_objects spec says:
493
 
          *
494
 
          *     "The error INVALID_OPERATION is generated by AttachObjectARB
495
 
          *     if <obj> is already attached to <containerObj>."
496
 
          */
497
 
         _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader");
498
 
         return;
499
 
      }
500
 
   }
501
 
 
502
 
   /* grow list */
503
 
   shProg->Shaders = (struct gl_shader **)
504
 
      _mesa_realloc(shProg->Shaders,
505
 
                    n * sizeof(struct gl_shader *),
506
 
                    (n + 1) * sizeof(struct gl_shader *));
507
 
   if (!shProg->Shaders) {
508
 
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAttachShader");
509
 
      return;
510
 
   }
511
 
 
512
 
   /* append */
513
 
   shProg->Shaders[n] = NULL; /* since realloc() didn't zero the new space */
514
 
   _mesa_reference_shader(ctx, &shProg->Shaders[n], sh);
515
 
   shProg->NumShaders++;
516
 
}
517
 
 
518
 
 
519
 
static GLint
520
 
_mesa_get_attrib_location(GLcontext *ctx, GLuint program,
521
 
                          const GLchar *name)
522
 
{
523
 
   struct gl_shader_program *shProg
524
 
      = _mesa_lookup_shader_program_err(ctx, program, "glGetAttribLocation");
525
 
 
526
 
   if (!shProg) {
527
 
      return -1;
528
 
   }
529
 
 
530
 
   if (!shProg->LinkStatus) {
531
 
      _mesa_error(ctx, GL_INVALID_OPERATION,
532
 
                  "glGetAttribLocation(program not linked)");
533
 
      return -1;
534
 
   }
535
 
 
536
 
   if (!name)
537
 
      return -1;
538
 
 
539
 
   if (shProg->VertexProgram) {
540
 
      const struct gl_program_parameter_list *attribs =
541
 
         shProg->VertexProgram->Base.Attributes;
542
 
      if (attribs) {
543
 
         GLint i = _mesa_lookup_parameter_index(attribs, -1, name);
544
 
         if (i >= 0) {
545
 
            return attribs->Parameters[i].StateIndexes[0];
546
 
         }
547
 
      }
548
 
   }
549
 
   return -1;
550
 
}
551
 
 
552
 
 
553
 
static void
554
 
_mesa_bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index,
555
 
                           const GLchar *name)
556
 
{
557
 
   struct gl_shader_program *shProg;
558
 
   const GLint size = -1; /* unknown size */
559
 
   GLint i, oldIndex;
560
 
   GLenum datatype = GL_FLOAT_VEC4;
561
 
 
562
 
   shProg = _mesa_lookup_shader_program_err(ctx, program,
563
 
                                            "glBindAttribLocation");
564
 
   if (!shProg) {
565
 
      return;
566
 
   }
567
 
 
568
 
   if (!name)
569
 
      return;
570
 
 
571
 
   if (strncmp(name, "gl_", 3) == 0) {
572
 
      _mesa_error(ctx, GL_INVALID_OPERATION,
573
 
                  "glBindAttribLocation(illegal name)");
574
 
      return;
575
 
   }
576
 
 
577
 
   if (index >= ctx->Const.VertexProgram.MaxAttribs) {
578
 
      _mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocation(index)");
579
 
      return;
580
 
   }
581
 
 
582
 
   if (shProg->LinkStatus) {
583
 
      /* get current index/location for the attribute */
584
 
      oldIndex = _mesa_get_attrib_location(ctx, program, name);
585
 
   }
586
 
   else {
587
 
      oldIndex = -1;
588
 
   }
589
 
 
590
 
   /* this will replace the current value if it's already in the list */
591
 
   i = _mesa_add_attribute(shProg->Attributes, name, size, datatype, index);
592
 
   if (i < 0) {
593
 
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindAttribLocation");
594
 
      return;
595
 
   }
596
 
 
597
 
   /*
598
 
    * Note that this attribute binding won't go into effect until
599
 
    * glLinkProgram is called again.
600
 
    */
601
 
}
602
 
 
603
 
 
604
 
static GLuint
605
 
_mesa_create_shader(GLcontext *ctx, GLenum type)
606
 
{
607
 
   struct gl_shader *sh;
608
 
   GLuint name;
609
 
 
610
 
   name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
611
 
 
612
 
   switch (type) {
613
 
   case GL_FRAGMENT_SHADER:
614
 
   case GL_VERTEX_SHADER:
615
 
      sh = _mesa_new_shader(ctx, name, type);
616
 
      break;
617
 
   default:
618
 
      _mesa_error(ctx, GL_INVALID_ENUM, "CreateShader(type)");
619
 
      return 0;
620
 
   }
621
 
 
622
 
   _mesa_HashInsert(ctx->Shared->ShaderObjects, name, sh);
623
 
 
624
 
   return name;
625
 
}
626
 
 
627
 
 
628
 
static GLuint 
629
 
_mesa_create_program(GLcontext *ctx)
630
 
{
631
 
   GLuint name;
632
 
   struct gl_shader_program *shProg;
633
 
 
634
 
   name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
635
 
   shProg = _mesa_new_shader_program(ctx, name);
636
 
 
637
 
   _mesa_HashInsert(ctx->Shared->ShaderObjects, name, shProg);
638
 
 
639
 
   assert(shProg->RefCount == 1);
640
 
 
641
 
   return name;
642
 
}
643
 
 
644
 
 
645
 
/**
646
 
 * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
647
 
 * DeleteProgramARB.
648
 
 */
649
 
static void
650
 
_mesa_delete_program2(GLcontext *ctx, GLuint name)
651
 
{
652
 
   /*
653
 
    * NOTE: deleting shaders/programs works a bit differently than
654
 
    * texture objects (and buffer objects, etc).  Shader/program
655
 
    * handles/IDs exist in the hash table until the object is really
656
 
    * deleted (refcount==0).  With texture objects, the handle/ID is
657
 
    * removed from the hash table in glDeleteTextures() while the tex
658
 
    * object itself might linger until its refcount goes to zero.
659
 
    */
660
 
   struct gl_shader_program *shProg;
661
 
 
662
 
   shProg = _mesa_lookup_shader_program_err(ctx, name, "glDeleteProgram");
663
 
   if (!shProg)
664
 
      return;
665
 
 
666
 
   shProg->DeletePending = GL_TRUE;
667
 
 
668
 
   /* effectively, decr shProg's refcount */
669
 
   _mesa_reference_shader_program(ctx, &shProg, NULL);
670
 
}
671
 
 
672
 
 
673
 
static void
674
 
_mesa_delete_shader(GLcontext *ctx, GLuint shader)
675
 
{
676
 
   struct gl_shader *sh;
677
 
 
678
 
   sh = _mesa_lookup_shader_err(ctx, shader, "glDeleteShader");
679
 
   if (!sh)
680
 
      return;
681
 
 
682
 
   sh->DeletePending = GL_TRUE;
683
 
 
684
 
   /* effectively, decr sh's refcount */
685
 
   _mesa_reference_shader(ctx, &sh, NULL);
686
 
}
687
 
 
688
 
 
689
 
static void
690
 
_mesa_detach_shader(GLcontext *ctx, GLuint program, GLuint shader)
691
 
{
692
 
   struct gl_shader_program *shProg;
693
 
   GLuint n;
694
 
   GLuint i, j;
695
 
 
696
 
   shProg = _mesa_lookup_shader_program_err(ctx, program, "glDetachShader");
697
 
   if (!shProg)
698
 
      return;
699
 
 
700
 
   n = shProg->NumShaders;
701
 
 
702
 
   for (i = 0; i < n; i++) {
703
 
      if (shProg->Shaders[i]->Name == shader) {
704
 
         /* found it */
705
 
         struct gl_shader **newList;
706
 
 
707
 
         /* release */
708
 
         _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
709
 
 
710
 
         /* alloc new, smaller array */
711
 
         newList = (struct gl_shader **)
712
 
            malloc((n - 1) * sizeof(struct gl_shader *));
713
 
         if (!newList) {
714
 
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDetachShader");
715
 
            return;
716
 
         }
717
 
         for (j = 0; j < i; j++) {
718
 
            newList[j] = shProg->Shaders[j];
719
 
         }
720
 
         while (++i < n)
721
 
            newList[j++] = shProg->Shaders[i];
722
 
         free(shProg->Shaders);
723
 
 
724
 
         shProg->Shaders = newList;
725
 
         shProg->NumShaders = n - 1;
726
 
 
727
 
#ifdef DEBUG
728
 
         /* sanity check */
729
 
         {
730
 
            for (j = 0; j < shProg->NumShaders; j++) {
731
 
               assert(shProg->Shaders[j]->Type == GL_VERTEX_SHADER ||
732
 
                      shProg->Shaders[j]->Type == GL_FRAGMENT_SHADER);
733
 
               assert(shProg->Shaders[j]->RefCount > 0);
734
 
            }
735
 
         }
736
 
#endif
737
 
 
738
 
         return;
739
 
      }
740
 
   }
741
 
 
742
 
   /* not found */
743
 
   {
744
 
      GLenum err;
745
 
      if (_mesa_is_shader(ctx, shader))
746
 
         err = GL_INVALID_OPERATION;
747
 
      else if (_mesa_is_program(ctx, shader))
748
 
         err = GL_INVALID_OPERATION;
749
 
      else
750
 
         err = GL_INVALID_VALUE;
751
 
      _mesa_error(ctx, err, "glDetachProgram(shader)");
752
 
      return;
753
 
   }
754
 
}
755
 
 
756
 
 
757
 
static GLint
758
 
sizeof_glsl_type(GLenum type)
759
 
{
760
 
   switch (type) {
761
 
   case GL_FLOAT:
762
 
   case GL_INT:
763
 
   case GL_BOOL:
764
 
   case GL_SAMPLER_1D:
765
 
   case GL_SAMPLER_2D:
766
 
   case GL_SAMPLER_3D:
767
 
   case GL_SAMPLER_CUBE:
768
 
   case GL_SAMPLER_1D_SHADOW:
769
 
   case GL_SAMPLER_2D_SHADOW:
770
 
   case GL_SAMPLER_2D_RECT_ARB:
771
 
   case GL_SAMPLER_2D_RECT_SHADOW_ARB:
772
 
   case GL_SAMPLER_1D_ARRAY_EXT:
773
 
   case GL_SAMPLER_2D_ARRAY_EXT:
774
 
   case GL_SAMPLER_1D_ARRAY_SHADOW_EXT:
775
 
   case GL_SAMPLER_2D_ARRAY_SHADOW_EXT:
776
 
   case GL_SAMPLER_CUBE_SHADOW_EXT:
777
 
      return 1;
778
 
   case GL_FLOAT_VEC2:
779
 
   case GL_INT_VEC2:
780
 
   case GL_BOOL_VEC2:
781
 
      return 2;
782
 
   case GL_FLOAT_VEC3:
783
 
   case GL_INT_VEC3:
784
 
   case GL_BOOL_VEC3:
785
 
      return 3;
786
 
   case GL_FLOAT_VEC4:
787
 
   case GL_INT_VEC4:
788
 
   case GL_BOOL_VEC4:
789
 
      return 4;
790
 
   case GL_FLOAT_MAT2:
791
 
   case GL_FLOAT_MAT2x3:
792
 
   case GL_FLOAT_MAT2x4:
793
 
      return 8; /* two float[4] vectors */
794
 
   case GL_FLOAT_MAT3:
795
 
   case GL_FLOAT_MAT3x2:
796
 
   case GL_FLOAT_MAT3x4:
797
 
      return 12; /* three float[4] vectors */
798
 
   case GL_FLOAT_MAT4:
799
 
   case GL_FLOAT_MAT4x2:
800
 
   case GL_FLOAT_MAT4x3:
801
 
      return 16;  /* four float[4] vectors */
802
 
   default:
803
 
      _mesa_problem(NULL, "Invalid type in sizeof_glsl_type()");
804
 
      return 1;
805
 
   }
806
 
}
807
 
 
808
 
 
809
 
static GLboolean
810
 
is_boolean_type(GLenum type)
811
 
{
812
 
   switch (type) {
813
 
   case GL_BOOL:
814
 
   case GL_BOOL_VEC2:
815
 
   case GL_BOOL_VEC3:
816
 
   case GL_BOOL_VEC4:
817
 
      return GL_TRUE;
818
 
   default:
819
 
      return GL_FALSE;
820
 
   }
821
 
}
822
 
 
823
 
 
824
 
static GLboolean
825
 
is_integer_type(GLenum type)
826
 
{
827
 
   switch (type) {
828
 
   case GL_INT:
829
 
   case GL_INT_VEC2:
830
 
   case GL_INT_VEC3:
831
 
   case GL_INT_VEC4:
832
 
      return GL_TRUE;
833
 
   default:
834
 
      return GL_FALSE;
835
 
   }
836
 
}
837
 
 
838
 
 
839
 
static GLboolean
840
 
is_sampler_type(GLenum type)
841
 
{
842
 
   switch (type) {
843
 
   case GL_SAMPLER_1D:
844
 
   case GL_SAMPLER_2D:
845
 
   case GL_SAMPLER_3D:
846
 
   case GL_SAMPLER_CUBE:
847
 
   case GL_SAMPLER_1D_SHADOW:
848
 
   case GL_SAMPLER_2D_SHADOW:
849
 
   case GL_SAMPLER_2D_RECT_ARB:
850
 
   case GL_SAMPLER_2D_RECT_SHADOW_ARB:
851
 
   case GL_SAMPLER_1D_ARRAY_EXT:
852
 
   case GL_SAMPLER_2D_ARRAY_EXT:
853
 
   case GL_SAMPLER_1D_ARRAY_SHADOW_EXT:
854
 
   case GL_SAMPLER_2D_ARRAY_SHADOW_EXT:
855
 
      return GL_TRUE;
856
 
   default:
857
 
      return GL_FALSE;
858
 
   }
859
 
}
860
 
 
861
 
 
862
 
static void
863
 
_mesa_get_active_attrib(GLcontext *ctx, GLuint program, GLuint index,
864
 
                        GLsizei maxLength, GLsizei *length, GLint *size,
865
 
                        GLenum *type, GLchar *nameOut)
866
 
{
867
 
   const struct gl_program_parameter_list *attribs = NULL;
868
 
   struct gl_shader_program *shProg;
869
 
 
870
 
   shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveAttrib");
871
 
   if (!shProg)
872
 
      return;
873
 
 
874
 
   if (shProg->VertexProgram)
875
 
      attribs = shProg->VertexProgram->Base.Attributes;
876
 
 
877
 
   if (!attribs || index >= attribs->NumParameters) {
878
 
      _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)");
879
 
      return;
880
 
   }
881
 
 
882
 
   copy_string(nameOut, maxLength, length, attribs->Parameters[index].Name);
883
 
 
884
 
   if (size)
885
 
      *size = attribs->Parameters[index].Size
886
 
         / sizeof_glsl_type(attribs->Parameters[index].DataType);
887
 
 
888
 
   if (type)
889
 
      *type = attribs->Parameters[index].DataType;
890
 
}
891
 
 
892
 
 
893
 
static struct gl_program_parameter *
894
 
get_uniform_parameter(const struct gl_shader_program *shProg, GLuint index)
895
 
{
896
 
   const struct gl_program *prog = NULL;
897
 
   GLint progPos;
898
 
 
899
 
   progPos = shProg->Uniforms->Uniforms[index].VertPos;
900
 
   if (progPos >= 0) {
901
 
      prog = &shProg->VertexProgram->Base;
902
 
   }
903
 
   else {
904
 
      progPos = shProg->Uniforms->Uniforms[index].FragPos;
905
 
      if (progPos >= 0) {
906
 
         prog = &shProg->FragmentProgram->Base;
907
 
      }
908
 
   }
909
 
 
910
 
   if (!prog || progPos < 0)
911
 
      return NULL; /* should never happen */
912
 
 
913
 
   return &prog->Parameters->Parameters[progPos];
914
 
}
915
 
 
916
 
 
917
 
/**
918
 
 * Called via ctx->Driver.GetActiveUniform().
919
 
 */
920
 
static void
921
 
_mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index,
922
 
                         GLsizei maxLength, GLsizei *length, GLint *size,
923
 
                         GLenum *type, GLchar *nameOut)
924
 
{
925
 
   const struct gl_shader_program *shProg;
926
 
   const struct gl_program *prog = NULL;
927
 
   const struct gl_program_parameter *param;
928
 
   GLint progPos;
929
 
 
930
 
   shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform");
931
 
   if (!shProg)
932
 
      return;
933
 
 
934
 
   if (!shProg->Uniforms || index >= shProg->Uniforms->NumUniforms) {
935
 
      _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)");
936
 
      return;
937
 
   }
938
 
 
939
 
   progPos = shProg->Uniforms->Uniforms[index].VertPos;
940
 
   if (progPos >= 0) {
941
 
      prog = &shProg->VertexProgram->Base;
942
 
   }
943
 
   else {
944
 
      progPos = shProg->Uniforms->Uniforms[index].FragPos;
945
 
      if (progPos >= 0) {
946
 
         prog = &shProg->FragmentProgram->Base;
947
 
      }
948
 
   }
949
 
 
950
 
   if (!prog || progPos < 0)
951
 
      return; /* should never happen */
952
 
 
953
 
   ASSERT(progPos < prog->Parameters->NumParameters);
954
 
   param = &prog->Parameters->Parameters[progPos];
955
 
 
956
 
   if (nameOut) {
957
 
      copy_string(nameOut, maxLength, length, param->Name);
958
 
   }
959
 
 
960
 
   if (size) {
961
 
      GLint typeSize = sizeof_glsl_type(param->DataType);
962
 
      if ((GLint) param->Size > typeSize) {
963
 
         /* This is an array.
964
 
          * Array elements are placed on vector[4] boundaries so they're
965
 
          * a multiple of four floats.  We round typeSize up to next multiple
966
 
          * of four to get the right size below.
967
 
          */
968
 
         typeSize = (typeSize + 3) & ~3;
969
 
      }
970
 
      /* Note that the returned size is in units of the <type>, not bytes */
971
 
      *size = param->Size / typeSize;
972
 
   }
973
 
 
974
 
   if (type) {
975
 
      *type = param->DataType;
976
 
   }
977
 
}
978
 
 
979
 
 
980
 
/**
981
 
 * Called via ctx->Driver.GetAttachedShaders().
982
 
 */
983
 
static void
984
 
_mesa_get_attached_shaders(GLcontext *ctx, GLuint program, GLsizei maxCount,
985
 
                           GLsizei *count, GLuint *obj)
986
 
{
987
 
   struct gl_shader_program *shProg =
988
 
      _mesa_lookup_shader_program_err(ctx, program, "glGetAttachedShaders");
989
 
   if (shProg) {
990
 
      GLuint i;
991
 
      for (i = 0; i < (GLuint) maxCount && i < shProg->NumShaders; i++) {
992
 
         obj[i] = shProg->Shaders[i]->Name;
993
 
      }
994
 
      if (count)
995
 
         *count = i;
996
 
   }
997
 
}
998
 
 
999
 
 
1000
 
static GLuint
1001
 
_mesa_get_handle(GLcontext *ctx, GLenum pname)
1002
 
{
1003
 
   GLint handle = 0;
1004
 
   
1005
 
   if (pname == GL_PROGRAM_OBJECT_ARB) {
1006
 
      CALL_GetIntegerv(ctx->Exec, (GL_CURRENT_PROGRAM, &handle));
1007
 
   } else {
1008
 
      _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB");
1009
 
   }
1010
 
 
1011
 
   return handle;
1012
 
}
1013
 
 
1014
 
 
1015
 
static void
1016
 
_mesa_get_programiv(GLcontext *ctx, GLuint program,
1017
 
                    GLenum pname, GLint *params)
1018
 
{
1019
 
   const struct gl_program_parameter_list *attribs;
1020
 
   struct gl_shader_program *shProg
1021
 
      = _mesa_lookup_shader_program(ctx, program);
1022
 
 
1023
 
   if (!shProg) {
1024
 
      _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramiv(program)");
1025
 
      return;
1026
 
   }
1027
 
 
1028
 
   if (shProg->VertexProgram)
1029
 
      attribs = shProg->VertexProgram->Base.Attributes;
1030
 
   else
1031
 
      attribs = NULL;
1032
 
 
1033
 
   switch (pname) {
1034
 
   case GL_DELETE_STATUS:
1035
 
      *params = shProg->DeletePending;
1036
 
      break; 
1037
 
   case GL_LINK_STATUS:
1038
 
      *params = shProg->LinkStatus;
1039
 
      break;
1040
 
   case GL_VALIDATE_STATUS:
1041
 
      *params = shProg->Validated;
1042
 
      break;
1043
 
   case GL_INFO_LOG_LENGTH:
1044
 
      *params = shProg->InfoLog ? strlen(shProg->InfoLog) + 1 : 0;
1045
 
      break;
1046
 
   case GL_ATTACHED_SHADERS:
1047
 
      *params = shProg->NumShaders;
1048
 
      break;
1049
 
   case GL_ACTIVE_ATTRIBUTES:
1050
 
      *params = attribs ? attribs->NumParameters : 0;
1051
 
      break;
1052
 
   case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
1053
 
      *params = _mesa_longest_parameter_name(attribs, PROGRAM_INPUT) + 1;
1054
 
      break;
1055
 
   case GL_ACTIVE_UNIFORMS:
1056
 
      *params = shProg->Uniforms ? shProg->Uniforms->NumUniforms : 0;
1057
 
      break;
1058
 
   case GL_ACTIVE_UNIFORM_MAX_LENGTH:
1059
 
      *params = _mesa_longest_uniform_name(shProg->Uniforms);
1060
 
      if (*params > 0)
1061
 
         (*params)++;  /* add one for terminating zero */
1062
 
      break;
1063
 
   case GL_PROGRAM_BINARY_LENGTH_OES:
1064
 
      *params = 0;
1065
 
      break;
1066
 
   default:
1067
 
      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname)");
1068
 
      return;
1069
 
   }
1070
 
}
1071
 
 
1072
 
 
1073
 
static void
1074
 
_mesa_get_shaderiv(GLcontext *ctx, GLuint name, GLenum pname, GLint *params)
1075
 
{
1076
 
   struct gl_shader *shader = _mesa_lookup_shader_err(ctx, name, "glGetShaderiv");
1077
 
 
1078
 
   if (!shader) {
1079
 
      return;
1080
 
   }
1081
 
 
1082
 
   switch (pname) {
1083
 
   case GL_SHADER_TYPE:
1084
 
      *params = shader->Type;
1085
 
      break;
1086
 
   case GL_DELETE_STATUS:
1087
 
      *params = shader->DeletePending;
1088
 
      break;
1089
 
   case GL_COMPILE_STATUS:
1090
 
      *params = shader->CompileStatus;
1091
 
      break;
1092
 
   case GL_INFO_LOG_LENGTH:
1093
 
      *params = shader->InfoLog ? strlen(shader->InfoLog) + 1 : 0;
1094
 
      break;
1095
 
   case GL_SHADER_SOURCE_LENGTH:
1096
 
      *params = shader->Source ? strlen((char *) shader->Source) + 1 : 0;
1097
 
      break;
1098
 
   default:
1099
 
      _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)");
1100
 
      return;
1101
 
   }
1102
 
}
1103
 
 
1104
 
 
1105
 
static void
1106
 
_mesa_get_program_info_log(GLcontext *ctx, GLuint program, GLsizei bufSize,
1107
 
                           GLsizei *length, GLchar *infoLog)
1108
 
{
1109
 
   struct gl_shader_program *shProg
1110
 
      = _mesa_lookup_shader_program(ctx, program);
1111
 
   if (!shProg) {
1112
 
      _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramInfoLog(program)");
1113
 
      return;
1114
 
   }
1115
 
   copy_string(infoLog, bufSize, length, shProg->InfoLog);
1116
 
}
1117
 
 
1118
 
 
1119
 
static void
1120
 
_mesa_get_shader_info_log(GLcontext *ctx, GLuint shader, GLsizei bufSize,
1121
 
                          GLsizei *length, GLchar *infoLog)
1122
 
{
1123
 
   struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
1124
 
   if (!sh) {
1125
 
      _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderInfoLog(shader)");
1126
 
      return;
1127
 
   }
1128
 
   copy_string(infoLog, bufSize, length, sh->InfoLog);
1129
 
}
1130
 
 
1131
 
 
1132
 
/**
1133
 
 * Called via ctx->Driver.GetShaderSource().
1134
 
 */
1135
 
static void
1136
 
_mesa_get_shader_source(GLcontext *ctx, GLuint shader, GLsizei maxLength,
1137
 
                        GLsizei *length, GLchar *sourceOut)
1138
 
{
1139
 
   struct gl_shader *sh;
1140
 
   sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderSource");
1141
 
   if (!sh) {
1142
 
      return;
1143
 
   }
1144
 
   copy_string(sourceOut, maxLength, length, sh->Source);
1145
 
}
1146
 
 
1147
 
 
1148
 
static void
1149
 
get_matrix_dims(GLenum type, GLint *rows, GLint *cols)
1150
 
{
1151
 
   switch (type) {
1152
 
   case GL_FLOAT_MAT2:
1153
 
      *rows = *cols = 2;
1154
 
      break;
1155
 
   case GL_FLOAT_MAT2x3:
1156
 
      *rows = 3;
1157
 
      *cols = 2;
1158
 
      break;
1159
 
   case GL_FLOAT_MAT2x4:
1160
 
      *rows = 4;
1161
 
      *cols = 2;
1162
 
      break;
1163
 
   case GL_FLOAT_MAT3:
1164
 
      *rows = 3;
1165
 
      *cols = 3;
1166
 
      break;
1167
 
   case GL_FLOAT_MAT3x2:
1168
 
      *rows = 2;
1169
 
      *cols = 3;
1170
 
      break;
1171
 
   case GL_FLOAT_MAT3x4:
1172
 
      *rows = 4;
1173
 
      *cols = 3;
1174
 
      break;
1175
 
   case GL_FLOAT_MAT4:
1176
 
      *rows = 4;
1177
 
      *cols = 4;
1178
 
      break;
1179
 
   case GL_FLOAT_MAT4x2:
1180
 
      *rows = 2;
1181
 
      *cols = 4;
1182
 
      break;
1183
 
   case GL_FLOAT_MAT4x3:
1184
 
      *rows = 3;
1185
 
      *cols = 4;
1186
 
      break;
1187
 
   default:
1188
 
      *rows = *cols = 0;
1189
 
   }
1190
 
}
1191
 
 
1192
 
 
1193
 
/**
1194
 
 * Determine the number of rows and columns occupied by a uniform
1195
 
 * according to its datatype.  For non-matrix types (such as GL_FLOAT_VEC4),
1196
 
 * the number of rows = 1 and cols = number of elements in the vector.
1197
 
 */
1198
 
static void
1199
 
get_uniform_rows_cols(const struct gl_program_parameter *p,
1200
 
                      GLint *rows, GLint *cols)
1201
 
{
1202
 
   get_matrix_dims(p->DataType, rows, cols);
1203
 
   if (*rows == 0 && *cols == 0) {
1204
 
      /* not a matrix type, probably a float or vector */
1205
 
      if (p->Size <= 4) {
1206
 
         *rows = 1;
1207
 
         *cols = p->Size;
1208
 
      }
1209
 
      else {
1210
 
         *rows = p->Size / 4 + 1;
1211
 
         if (p->Size % 4 == 0)
1212
 
            *cols = 4;
1213
 
         else
1214
 
            *cols = p->Size % 4;
1215
 
      }
1216
 
   }
1217
 
}
1218
 
 
1219
 
 
1220
 
/**
1221
 
 * Helper for get_uniform[fi]v() functions.
1222
 
 * Given a shader program name and uniform location, return a pointer
1223
 
 * to the shader program and return the program parameter position.
1224
 
 */
1225
 
static void
1226
 
lookup_uniform_parameter(GLcontext *ctx, GLuint program, GLint location,
1227
 
                         struct gl_program **progOut, GLint *paramPosOut)
1228
 
{
1229
 
   struct gl_shader_program *shProg
1230
 
      = _mesa_lookup_shader_program_err(ctx, program, "glGetUniform[if]v");
1231
 
   struct gl_program *prog = NULL;
1232
 
   GLint progPos = -1;
1233
 
 
1234
 
   /* if shProg is NULL, we'll have already recorded an error */
1235
 
 
1236
 
   if (shProg) {
1237
 
      if (!shProg->Uniforms ||
1238
 
          location < 0 ||
1239
 
          location >= (GLint) shProg->Uniforms->NumUniforms) {
1240
 
         _mesa_error(ctx, GL_INVALID_OPERATION,  "glGetUniformfv(location)");
1241
 
      }
1242
 
      else {
1243
 
         /* OK, find the gl_program and program parameter location */
1244
 
         progPos = shProg->Uniforms->Uniforms[location].VertPos;
1245
 
         if (progPos >= 0) {
1246
 
            prog = &shProg->VertexProgram->Base;
1247
 
         }
1248
 
         else {
1249
 
            progPos = shProg->Uniforms->Uniforms[location].FragPos;
1250
 
            if (progPos >= 0) {
1251
 
               prog = &shProg->FragmentProgram->Base;
1252
 
            }
1253
 
         }
1254
 
      }
1255
 
   }
1256
 
 
1257
 
   *progOut = prog;
1258
 
   *paramPosOut = progPos;
1259
 
}
1260
 
 
1261
 
 
1262
 
/**
1263
 
 * GLGL uniform arrays and structs require special handling.
1264
 
 *
1265
 
 * The GL_ARB_shader_objects spec says that if you use
1266
 
 * glGetUniformLocation to get the location of an array, you CANNOT
1267
 
 * access other elements of the array by adding an offset to the
1268
 
 * returned location.  For example, you must call
1269
 
 * glGetUniformLocation("foo[16]") if you want to set the 16th element
1270
 
 * of the array with glUniform().
1271
 
 *
1272
 
 * HOWEVER, some other OpenGL drivers allow accessing array elements
1273
 
 * by adding an offset to the returned array location.  And some apps
1274
 
 * seem to depend on that behaviour.
1275
 
 *
1276
 
 * Mesa's gl_uniform_list doesn't directly support this since each
1277
 
 * entry in the list describes one uniform variable, not one uniform
1278
 
 * element.  We could insert dummy entries in the list for each array
1279
 
 * element after [0] but that causes complications elsewhere.
1280
 
 *
1281
 
 * We solve this problem by encoding two values in the location that's
1282
 
 * returned by glGetUniformLocation():
1283
 
 *  a) index into gl_uniform_list::Uniforms[] for the uniform
1284
 
 *  b) an array/field offset (0 for simple types)
1285
 
 *
1286
 
 * These two values are encoded in the high and low halves of a GLint.
1287
 
 * By putting the uniform number in the high part and the offset in the
1288
 
 * low part, we can support the unofficial ability to index into arrays
1289
 
 * by adding offsets to the location value.
1290
 
 */
1291
 
static void
1292
 
merge_location_offset(GLint *location, GLint offset)
1293
 
{
1294
 
   *location = (*location << 16) | offset;
1295
 
}
1296
 
 
1297
 
 
1298
 
/**
1299
 
 * Seperate the uniform location and parameter offset.  See above.
1300
 
 */
1301
 
static void
1302
 
split_location_offset(GLint *location, GLint *offset)
1303
 
{
1304
 
   *offset = *location & 0xffff;
1305
 
   *location = *location >> 16;
1306
 
}
1307
 
 
1308
 
 
1309
 
 
1310
 
/**
1311
 
 * Called via ctx->Driver.GetUniformfv().
1312
 
 */
1313
 
static void
1314
 
_mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
1315
 
                    GLfloat *params)
1316
 
{
1317
 
   struct gl_program *prog;
1318
 
   GLint paramPos;
1319
 
   GLint offset;
1320
 
 
1321
 
   split_location_offset(&location, &offset);
1322
 
 
1323
 
   lookup_uniform_parameter(ctx, program, location, &prog, &paramPos);
1324
 
 
1325
 
   if (prog) {
1326
 
      const struct gl_program_parameter *p =
1327
 
         &prog->Parameters->Parameters[paramPos];
1328
 
      GLint rows, cols, i, j, k;
1329
 
 
1330
 
      get_uniform_rows_cols(p, &rows, &cols);
1331
 
 
1332
 
      k = 0;
1333
 
      for (i = 0; i < rows; i++) {
1334
 
         for (j = 0; j < cols; j++ ) {
1335
 
            params[k++] = prog->Parameters->ParameterValues[paramPos+i][j];
1336
 
         }
1337
 
      }
1338
 
   }
1339
 
}
1340
 
 
1341
 
 
1342
 
/**
1343
 
 * Called via ctx->Driver.GetUniformiv().
1344
 
 * \sa _mesa_get_uniformfv, only difference is a cast.
1345
 
 */
1346
 
static void
1347
 
_mesa_get_uniformiv(GLcontext *ctx, GLuint program, GLint location,
1348
 
                    GLint *params)
1349
 
{
1350
 
   struct gl_program *prog;
1351
 
   GLint paramPos;
1352
 
   GLint offset;
1353
 
 
1354
 
   split_location_offset(&location, &offset);
1355
 
 
1356
 
   lookup_uniform_parameter(ctx, program, location, &prog, &paramPos);
1357
 
 
1358
 
   if (prog) {
1359
 
      const struct gl_program_parameter *p =
1360
 
         &prog->Parameters->Parameters[paramPos];
1361
 
      GLint rows, cols, i, j, k;
1362
 
 
1363
 
      get_uniform_rows_cols(p, &rows, &cols);
1364
 
 
1365
 
      k = 0;
1366
 
      for (i = 0; i < rows; i++) {
1367
 
         for (j = 0; j < cols; j++ ) {
1368
 
            params[k++] = (GLint) prog->Parameters->ParameterValues[paramPos+i][j];
1369
 
         }
1370
 
      }
1371
 
   }
1372
 
}
1373
 
 
1374
 
 
1375
 
/**
1376
 
 * Called via ctx->Driver.GetUniformLocation().
1377
 
 *
1378
 
 * The return value will encode two values, the uniform location and an
1379
 
 * offset (used for arrays, structs).
1380
 
 */
1381
 
static GLint
1382
 
_mesa_get_uniform_location(GLcontext *ctx, GLuint program, const GLchar *name)
1383
 
{
1384
 
   GLint offset = 0, location = -1;
1385
 
 
1386
 
   struct gl_shader_program *shProg =
1387
 
      _mesa_lookup_shader_program_err(ctx, program, "glGetUniformLocation");
1388
 
 
1389
 
   if (!shProg)
1390
 
      return -1;
1391
 
 
1392
 
   if (shProg->LinkStatus == GL_FALSE) {
1393
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(program)");
1394
 
      return -1;
1395
 
   }
1396
 
 
1397
 
   /* XXX we should return -1 if the uniform was declared, but not
1398
 
    * actually used.
1399
 
    */
1400
 
 
1401
 
   /* XXX we need to be able to parse uniform names for structs and arrays
1402
 
    * such as:
1403
 
    *   mymatrix[1]
1404
 
    *   mystruct.field1
1405
 
    */
1406
 
 
1407
 
   {
1408
 
      /* handle 1-dimension arrays here... */
1409
 
      char *c = strchr(name, '[');
1410
 
      if (c) {
1411
 
         /* truncate name at [ */
1412
 
         const GLint len = c - name;
1413
 
         GLchar *newName = malloc(len + 1);
1414
 
         if (!newName)
1415
 
            return -1; /* out of mem */
1416
 
         memcpy(newName, name, len);
1417
 
         newName[len] = 0;
1418
 
 
1419
 
         location = _mesa_lookup_uniform(shProg->Uniforms, newName);
1420
 
         if (location >= 0) {
1421
 
            const GLint element = atoi(c + 1);
1422
 
            if (element > 0) {
1423
 
               /* get type of the uniform array element */
1424
 
               struct gl_program_parameter *p;
1425
 
               p = get_uniform_parameter(shProg, location);
1426
 
               if (p) {
1427
 
                  GLint rows, cols;
1428
 
                  get_matrix_dims(p->DataType, &rows, &cols);
1429
 
                  if (rows < 1)
1430
 
                     rows = 1;
1431
 
                  offset = element * rows;
1432
 
               }
1433
 
            }
1434
 
         }
1435
 
 
1436
 
         free(newName);
1437
 
      }
1438
 
   }
1439
 
 
1440
 
   if (location < 0) {
1441
 
      location = _mesa_lookup_uniform(shProg->Uniforms, name);
1442
 
   }
1443
 
 
1444
 
   if (location >= 0) {
1445
 
      merge_location_offset(&location, offset);
1446
 
   }
1447
 
 
1448
 
   return location;
1449
 
}
1450
 
 
1451
 
 
1452
 
 
1453
 
/**
1454
 
 * Called via ctx->Driver.ShaderSource()
1455
 
 */
1456
 
static void
1457
 
_mesa_shader_source(GLcontext *ctx, GLuint shader, const GLchar *source)
1458
 
{
1459
 
   struct gl_shader *sh;
1460
 
 
1461
 
   sh = _mesa_lookup_shader_err(ctx, shader, "glShaderSource");
1462
 
   if (!sh)
1463
 
      return;
1464
 
 
1465
 
   /* free old shader source string and install new one */
1466
 
   if (sh->Source) {
1467
 
      free((void *) sh->Source);
1468
 
   }
1469
 
   sh->Source = source;
1470
 
   sh->CompileStatus = GL_FALSE;
1471
 
#ifdef DEBUG
1472
 
   sh->SourceChecksum = _mesa_str_checksum(sh->Source);
1473
 
#endif
1474
 
}
1475
 
 
1476
 
 
1477
 
/**
1478
 
 * Called via ctx->Driver.CompileShader()
1479
 
 */
1480
 
static void
1481
 
_mesa_compile_shader(GLcontext *ctx, GLuint shaderObj)
1482
 
{
1483
 
   struct gl_shader *sh;
1484
 
 
1485
 
   sh = _mesa_lookup_shader_err(ctx, shaderObj, "glCompileShader");
1486
 
   if (!sh)
1487
 
      return;
1488
 
 
1489
 
   /* set default pragma state for shader */
1490
 
   sh->Pragmas = ctx->Shader.DefaultPragmas;
1491
 
 
1492
 
   /* this call will set the sh->CompileStatus field to indicate if
1493
 
    * compilation was successful.
1494
 
    */
1495
 
   (void) _slang_compile(ctx, sh);
1496
 
}
1497
 
 
1498
 
 
1499
 
/**
1500
 
 * Called via ctx->Driver.LinkProgram()
1501
 
 */
1502
 
static void
1503
 
_mesa_link_program(GLcontext *ctx, GLuint program)
1504
 
{
1505
 
   struct gl_shader_program *shProg;
1506
 
 
1507
 
   shProg = _mesa_lookup_shader_program_err(ctx, program, "glLinkProgram");
1508
 
   if (!shProg)
1509
 
      return;
1510
 
 
1511
 
   FLUSH_VERTICES(ctx, _NEW_PROGRAM);
1512
 
 
1513
 
   _slang_link(ctx, program, shProg);
1514
 
 
1515
 
   /* debug code */
1516
 
   if (0) {
1517
 
      GLuint i;
1518
 
 
1519
 
      printf("Link %u shaders in program %u: %s\n",
1520
 
                   shProg->NumShaders, shProg->Name,
1521
 
                   shProg->LinkStatus ? "Success" : "Failed");
1522
 
 
1523
 
      for (i = 0; i < shProg->NumShaders; i++) {
1524
 
         printf(" shader %u, type 0x%x\n",
1525
 
                      shProg->Shaders[i]->Name,
1526
 
                      shProg->Shaders[i]->Type);
1527
 
      }
1528
 
   }
1529
 
}
1530
 
 
1531
 
 
1532
 
/**
1533
 
 * Print basic shader info (for debug).
1534
 
 */
1535
 
static void
1536
 
print_shader_info(const struct gl_shader_program *shProg)
1537
 
{
1538
 
   GLuint i;
1539
 
 
1540
 
   printf("Mesa: glUseProgram(%u)\n", shProg->Name);
1541
 
   for (i = 0; i < shProg->NumShaders; i++) {
1542
 
      const char *s;
1543
 
      switch (shProg->Shaders[i]->Type) {
1544
 
      case GL_VERTEX_SHADER:
1545
 
         s = "vertex";
1546
 
         break;
1547
 
      case GL_FRAGMENT_SHADER:
1548
 
         s = "fragment";
1549
 
         break;
1550
 
      case GL_GEOMETRY_SHADER:
1551
 
         s = "geometry";
1552
 
         break;
1553
 
      default:
1554
 
         s = "";
1555
 
      }
1556
 
      printf("  %s shader %u, checksum %u\n", s, 
1557
 
             shProg->Shaders[i]->Name,
1558
 
             shProg->Shaders[i]->SourceChecksum);
1559
 
   }
1560
 
   if (shProg->VertexProgram)
1561
 
      printf("  vert prog %u\n", shProg->VertexProgram->Base.Id);
1562
 
   if (shProg->FragmentProgram)
1563
 
      printf("  frag prog %u\n", shProg->FragmentProgram->Base.Id);
1564
 
}
1565
 
 
1566
 
 
1567
 
/**
1568
 
 * Called via ctx->Driver.UseProgram()
1569
 
 */
1570
 
void
1571
 
_mesa_use_program(GLcontext *ctx, GLuint program)
1572
 
{
1573
 
   struct gl_shader_program *shProg;
1574
 
 
1575
 
   if (ctx->Shader.CurrentProgram &&
1576
 
       ctx->Shader.CurrentProgram->Name == program) {
1577
 
      /* no-op */
1578
 
      return;
1579
 
   }
1580
 
 
1581
 
   if (program) {
1582
 
      shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
1583
 
      if (!shProg) {
1584
 
         return;
1585
 
      }
1586
 
      if (!shProg->LinkStatus) {
1587
 
         _mesa_error(ctx, GL_INVALID_OPERATION,
1588
 
                     "glUseProgram(program %u not linked)", program);
1589
 
         return;
1590
 
      }
1591
 
 
1592
 
      /* debug code */
1593
 
      if (ctx->Shader.Flags & GLSL_USE_PROG) {
1594
 
         print_shader_info(shProg);
1595
 
      }
1596
 
   }
1597
 
   else {
1598
 
      shProg = NULL;
1599
 
   }
1600
 
 
1601
 
   if (ctx->Shader.CurrentProgram != shProg) {
1602
 
      FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
1603
 
      _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram, shProg);
1604
 
   }
1605
 
}
1606
 
 
1607
 
 
1608
 
 
1609
 
/**
1610
 
 * Update the vertex/fragment program's TexturesUsed array.
1611
 
 *
1612
 
 * This needs to be called after glUniform(set sampler var) is called.
1613
 
 * A call to glUniform(samplerVar, value) causes a sampler to point to a
1614
 
 * particular texture unit.  We know the sampler's texture target
1615
 
 * (1D/2D/3D/etc) from compile time but the sampler's texture unit is
1616
 
 * set by glUniform() calls.
1617
 
 *
1618
 
 * So, scan the program->SamplerUnits[] and program->SamplerTargets[]
1619
 
 * information to update the prog->TexturesUsed[] values.
1620
 
 * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX,
1621
 
 * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc.
1622
 
 * We'll use that info for state validation before rendering.
1623
 
 */
1624
 
void
1625
 
_mesa_update_shader_textures_used(struct gl_program *prog)
1626
 
{
1627
 
   GLuint s;
1628
 
 
1629
 
   memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed));
1630
 
 
1631
 
   for (s = 0; s < MAX_SAMPLERS; s++) {
1632
 
      if (prog->SamplersUsed & (1 << s)) {
1633
 
         GLuint unit = prog->SamplerUnits[s];
1634
 
         GLuint tgt = prog->SamplerTargets[s];
1635
 
         assert(unit < MAX_TEXTURE_IMAGE_UNITS);
1636
 
         assert(tgt < NUM_TEXTURE_TARGETS);
1637
 
         prog->TexturesUsed[unit] |= (1 << tgt);
1638
 
      }
1639
 
   }
1640
 
}
1641
 
 
1642
 
 
1643
 
/**
1644
 
 * Check if the type given by userType is allowed to set a uniform of the
1645
 
 * target type.  Generally, equivalence is required, but setting Boolean
1646
 
 * uniforms can be done with glUniformiv or glUniformfv.
1647
 
 */
1648
 
static GLboolean
1649
 
compatible_types(GLenum userType, GLenum targetType)
1650
 
{
1651
 
   if (userType == targetType)
1652
 
      return GL_TRUE;
1653
 
 
1654
 
   if (targetType == GL_BOOL && (userType == GL_FLOAT || userType == GL_INT))
1655
 
      return GL_TRUE;
1656
 
 
1657
 
   if (targetType == GL_BOOL_VEC2 && (userType == GL_FLOAT_VEC2 ||
1658
 
                                      userType == GL_INT_VEC2))
1659
 
      return GL_TRUE;
1660
 
 
1661
 
   if (targetType == GL_BOOL_VEC3 && (userType == GL_FLOAT_VEC3 ||
1662
 
                                      userType == GL_INT_VEC3))
1663
 
      return GL_TRUE;
1664
 
 
1665
 
   if (targetType == GL_BOOL_VEC4 && (userType == GL_FLOAT_VEC4 ||
1666
 
                                      userType == GL_INT_VEC4))
1667
 
      return GL_TRUE;
1668
 
 
1669
 
   if (is_sampler_type(targetType) && userType == GL_INT)
1670
 
      return GL_TRUE;
1671
 
 
1672
 
   return GL_FALSE;
1673
 
}
1674
 
 
1675
 
 
1676
 
/**
1677
 
 * Set the value of a program's uniform variable.
1678
 
 * \param program  the program whose uniform to update
1679
 
 * \param index  the index of the program parameter for the uniform
1680
 
 * \param offset  additional parameter slot offset (for arrays)
1681
 
 * \param type  the incoming datatype of 'values'
1682
 
 * \param count  the number of uniforms to set
1683
 
 * \param elems  number of elements per uniform (1, 2, 3 or 4)
1684
 
 * \param values  the new values, of datatype 'type'
1685
 
 */
1686
 
static void
1687
 
set_program_uniform(GLcontext *ctx, struct gl_program *program,
1688
 
                    GLint index, GLint offset,
1689
 
                    GLenum type, GLsizei count, GLint elems,
1690
 
                    const void *values)
1691
 
{
1692
 
   const struct gl_program_parameter *param =
1693
 
      &program->Parameters->Parameters[index];
1694
 
 
1695
 
   assert(offset >= 0);
1696
 
   assert(elems >= 1);
1697
 
   assert(elems <= 4);
1698
 
 
1699
 
   if (!compatible_types(type, param->DataType)) {
1700
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(type mismatch)");
1701
 
      return;
1702
 
   }
1703
 
 
1704
 
   if (index + offset > (GLint) program->Parameters->Size) {
1705
 
      /* out of bounds! */
1706
 
      return;
1707
 
   }
1708
 
 
1709
 
   if (param->Type == PROGRAM_SAMPLER) {
1710
 
      /* This controls which texture unit which is used by a sampler */
1711
 
      GLboolean changed = GL_FALSE;
1712
 
      GLint i;
1713
 
 
1714
 
      /* this should have been caught by the compatible_types() check */
1715
 
      ASSERT(type == GL_INT);
1716
 
 
1717
 
      /* loop over number of samplers to change */
1718
 
      for (i = 0; i < count; i++) {
1719
 
         GLuint sampler =
1720
 
            (GLuint) program->Parameters->ParameterValues[index + offset + i][0];
1721
 
         GLuint texUnit = ((GLuint *) values)[i];
1722
 
 
1723
 
         /* check that the sampler (tex unit index) is legal */
1724
 
         if (texUnit >= ctx->Const.MaxTextureImageUnits) {
1725
 
            _mesa_error(ctx, GL_INVALID_VALUE,
1726
 
                        "glUniform1(invalid sampler/tex unit index)");
1727
 
            return;
1728
 
         }
1729
 
 
1730
 
         /* This maps a sampler to a texture unit: */
1731
 
         if (sampler < MAX_SAMPLERS) {
1732
 
#if 0
1733
 
            printf("Set program %p sampler %d '%s' to unit %u\n",
1734
 
                   program, sampler, param->Name, texUnit);
1735
 
#endif
1736
 
            if (program->SamplerUnits[sampler] != texUnit) {
1737
 
               program->SamplerUnits[sampler] = texUnit;
1738
 
               changed = GL_TRUE;
1739
 
            }
1740
 
         }
1741
 
      }
1742
 
 
1743
 
      if (changed) {
1744
 
         /* When a sampler's value changes it usually requires rewriting
1745
 
          * a GPU program's TEX instructions since there may not be a
1746
 
          * sampler->texture lookup table.  We signal this with the
1747
 
          * ProgramStringNotify() callback.
1748
 
          */
1749
 
         FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM);
1750
 
         _mesa_update_shader_textures_used(program);
1751
 
         /* Do we need to care about the return value here?
1752
 
          * This should not be the first time the driver was notified of
1753
 
          * this program.
1754
 
          */
1755
 
         (void) ctx->Driver.ProgramStringNotify(ctx, program->Target, program);
1756
 
      }
1757
 
   }
1758
 
   else {
1759
 
      /* ordinary uniform variable */
1760
 
      const GLboolean isUniformBool = is_boolean_type(param->DataType);
1761
 
      const GLboolean areIntValues = is_integer_type(type);
1762
 
      const GLint slots = (param->Size + 3) / 4;
1763
 
      const GLint typeSize = sizeof_glsl_type(param->DataType);
1764
 
      GLsizei k, i;
1765
 
 
1766
 
      if ((GLint) param->Size > typeSize) {
1767
 
         /* an array */
1768
 
         /* we'll ignore extra data below */
1769
 
      }
1770
 
      else {
1771
 
         /* non-array: count must be at most one; count == 0 is handled by the loop below */
1772
 
         if (count > 1) {
1773
 
            _mesa_error(ctx, GL_INVALID_OPERATION,
1774
 
                        "glUniform(uniform is not an array)");
1775
 
            return;
1776
 
         }
1777
 
      }
1778
 
 
1779
 
      /* loop over number of array elements */
1780
 
      for (k = 0; k < count; k++) {
1781
 
         GLfloat *uniformVal;
1782
 
 
1783
 
         if (offset + k >= slots) {
1784
 
            /* Extra array data is ignored */
1785
 
            break;
1786
 
         }
1787
 
 
1788
 
         /* uniformVal (the destination) is always float[4] */
1789
 
         uniformVal = program->Parameters->ParameterValues[index + offset + k];
1790
 
 
1791
 
         if (areIntValues) {
1792
 
            /* convert user's ints to floats */
1793
 
            const GLint *iValues = ((const GLint *) values) + k * elems;
1794
 
            for (i = 0; i < elems; i++) {
1795
 
               uniformVal[i] = (GLfloat) iValues[i];
1796
 
            }
1797
 
         }
1798
 
         else {
1799
 
            const GLfloat *fValues = ((const GLfloat *) values) + k * elems;
1800
 
            for (i = 0; i < elems; i++) {
1801
 
               uniformVal[i] = fValues[i];
1802
 
            }
1803
 
         }
1804
 
 
1805
 
         /* if the uniform is bool-valued, convert to 1.0 or 0.0 */
1806
 
         if (isUniformBool) {
1807
 
            for (i = 0; i < elems; i++) {
1808
 
               uniformVal[i] = uniformVal[i] ? 1.0f : 0.0f;
1809
 
            }
1810
 
         }
1811
 
      }
1812
 
   }
1813
 
}
1814
 
 
1815
 
 
1816
 
/**
1817
 
 * Called via ctx->Driver.Uniform().
1818
 
 */
1819
 
static void
1820
 
_mesa_uniform(GLcontext *ctx, GLint location, GLsizei count,
1821
 
              const GLvoid *values, GLenum type)
1822
 
{
1823
 
   struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
1824
 
   struct gl_uniform *uniform;
1825
 
   GLint elems, offset;
1826
 
   GLenum basicType;
1827
 
 
1828
 
   if (!shProg || !shProg->LinkStatus) {
1829
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(program not linked)");
1830
 
      return;
1831
 
   }
1832
 
 
1833
 
   if (location == -1)
1834
 
      return;   /* The standard specifies this as a no-op */
1835
 
 
1836
 
   if (location < -1) {
1837
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(location)");
1838
 
      return;
1839
 
   }
1840
 
 
1841
 
   split_location_offset(&location, &offset);
1842
 
 
1843
 
   if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
1844
 
      _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(location)");
1845
 
      return;
1846
 
   }
1847
 
 
1848
 
   if (count < 0) {
1849
 
      _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(count < 0)");
1850
 
      return;
1851
 
   }
1852
 
 
1853
 
   switch (type) {
1854
 
   case GL_FLOAT:
1855
 
      basicType = GL_FLOAT;
1856
 
      elems = 1;
1857
 
      break;
1858
 
   case GL_INT:
1859
 
      basicType = GL_INT;
1860
 
      elems = 1;
1861
 
      break;
1862
 
   case GL_FLOAT_VEC2:
1863
 
      basicType = GL_FLOAT;
1864
 
      elems = 2;
1865
 
      break;
1866
 
   case GL_INT_VEC2:
1867
 
      basicType = GL_INT;
1868
 
      elems = 2;
1869
 
      break;
1870
 
   case GL_FLOAT_VEC3:
1871
 
      basicType = GL_FLOAT;
1872
 
      elems = 3;
1873
 
      break;
1874
 
   case GL_INT_VEC3:
1875
 
      basicType = GL_INT;
1876
 
      elems = 3;
1877
 
      break;
1878
 
   case GL_FLOAT_VEC4:
1879
 
      basicType = GL_FLOAT;
1880
 
      elems = 4;
1881
 
      break;
1882
 
   case GL_INT_VEC4:
1883
 
      basicType = GL_INT;
1884
 
      elems = 4;
1885
 
      break;
1886
 
   default:
1887
 
      _mesa_problem(ctx, "Invalid type in _mesa_uniform");
1888
 
      return;
1889
 
   }
1890
 
 
1891
 
   FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
1892
 
 
1893
 
   uniform = &shProg->Uniforms->Uniforms[location];
1894
 
 
1895
 
   if (ctx->Shader.Flags & GLSL_UNIFORMS) {
1896
 
      GLint i;
1897
 
      printf("Mesa: set program %u uniform %s (loc %d) to: ",
1898
 
             shProg->Name, uniform->Name, location);
1899
 
      if (basicType == GL_INT) {
1900
 
         const GLint *v = (const GLint *) values;
1901
 
         for (i = 0; i < count * elems; i++) {
1902
 
            printf("%d ", v[i]);
1903
 
         }
1904
 
      }
1905
 
      else {
1906
 
         const GLfloat *v = (const GLfloat *) values;
1907
 
         for (i = 0; i < count * elems; i++) {
1908
 
            printf("%g ", v[i]);
1909
 
         }
1910
 
      }
1911
 
      printf("\n");
1912
 
   }
1913
 
 
1914
 
   /* A uniform var may be used by both a vertex shader and a fragment
1915
 
    * shader.  We may need to update one or both shader's uniform here:
1916
 
    */
1917
 
   if (shProg->VertexProgram) {
1918
 
      /* convert uniform location to program parameter index */
1919
 
      GLint index = uniform->VertPos;
1920
 
      if (index >= 0) {
1921
 
         set_program_uniform(ctx, &shProg->VertexProgram->Base,
1922
 
                             index, offset, type, count, elems, values);
1923
 
      }
1924
 
   }
1925
 
 
1926
 
   if (shProg->FragmentProgram) {
1927
 
      /* convert uniform location to program parameter index */
1928
 
      GLint index = uniform->FragPos;
1929
 
      if (index >= 0) {
1930
 
         set_program_uniform(ctx, &shProg->FragmentProgram->Base,
1931
 
                             index, offset, type, count, elems, values);
1932
 
      }
1933
 
   }
1934
 
 
1935
 
   uniform->Initialized = GL_TRUE;
1936
 
}
1937
 
 
1938
 
 
1939
 
/**
1940
 
 * Set a matrix-valued program parameter.
1941
 
 */
1942
 
static void
1943
 
set_program_uniform_matrix(GLcontext *ctx, struct gl_program *program,
1944
 
                           GLuint index, GLuint offset,
1945
 
                           GLuint count, GLuint rows, GLuint cols,
1946
 
                           GLboolean transpose, const GLfloat *values)
1947
 
{
1948
 
   GLuint mat, row, col;
1949
 
   GLuint src = 0;
1950
 
   const struct gl_program_parameter * param = &program->Parameters->Parameters[index];
1951
 
   const GLuint slots = (param->Size + 3) / 4;
1952
 
   const GLint typeSize = sizeof_glsl_type(param->DataType);
1953
 
   GLint nr, nc;
1954
 
 
1955
 
   /* check that the number of rows, columns is correct */
1956
 
   get_matrix_dims(param->DataType, &nr, &nc);
1957
 
   if (rows != nr || cols != nc) {
1958
 
      _mesa_error(ctx, GL_INVALID_OPERATION,
1959
 
                  "glUniformMatrix(matrix size mismatch)");
1960
 
      return;
1961
 
   }
1962
 
 
1963
 
   if ((GLint) param->Size <= typeSize) {
1964
 
      /* non-array: count must be at most one; count == 0 is handled by the loop below */
1965
 
      if (count > 1) {
1966
 
         _mesa_error(ctx, GL_INVALID_OPERATION,
1967
 
                     "glUniformMatrix(uniform is not an array)");
1968
 
         return;
1969
 
      }
1970
 
   }
1971
 
 
1972
 
   /*
1973
 
    * Note: the _columns_ of a matrix are stored in program registers, not
1974
 
    * the rows.  So, the loops below look a little funny.
1975
 
    * XXX could optimize this a bit...
1976
 
    */
1977
 
 
1978
 
   /* loop over matrices */
1979
 
   for (mat = 0; mat < count; mat++) {
1980
 
 
1981
 
      /* each matrix: */
1982
 
      for (col = 0; col < cols; col++) {
1983
 
         GLfloat *v;
1984
 
         if (offset >= slots) {
1985
 
            /* Ignore writes beyond the end of (the used part of) an array */
1986
 
            return;
1987
 
         }
1988
 
         v = program->Parameters->ParameterValues[index + offset];
1989
 
         for (row = 0; row < rows; row++) {
1990
 
            if (transpose) {
1991
 
               v[row] = values[src + row * cols + col];
1992
 
            }
1993
 
            else {
1994
 
               v[row] = values[src + col * rows + row];
1995
 
            }
1996
 
         }
1997
 
 
1998
 
         offset++;
1999
 
      }
2000
 
 
2001
 
      src += rows * cols;  /* next matrix */
2002
 
   }
2003
 
}
2004
 
 
2005
 
 
2006
 
/**
2007
 
 * Called by ctx->Driver.UniformMatrix().
2008
 
 * Note: cols=2, rows=4  ==>  array[2] of vec4
2009
 
 */
2010
 
static void
2011
 
_mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows,
2012
 
                     GLint location, GLsizei count,
2013
 
                     GLboolean transpose, const GLfloat *values)
2014
 
{
2015
 
   struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
2016
 
   struct gl_uniform *uniform;
2017
 
   GLint offset;
2018
 
 
2019
 
   if (!shProg || !shProg->LinkStatus) {
2020
 
      _mesa_error(ctx, GL_INVALID_OPERATION,
2021
 
         "glUniformMatrix(program not linked)");
2022
 
      return;
2023
 
   }
2024
 
 
2025
 
   if (location == -1)
2026
 
      return;   /* The standard specifies this as a no-op */
2027
 
 
2028
 
   if (location < -1) {
2029
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformMatrix(location)");
2030
 
      return;
2031
 
   }
2032
 
 
2033
 
   split_location_offset(&location, &offset);
2034
 
 
2035
 
   if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
2036
 
      _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix(location)");
2037
 
      return;
2038
 
   }
2039
 
   if (values == NULL) {
2040
 
      _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix");
2041
 
      return;
2042
 
   }
2043
 
 
2044
 
   FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
2045
 
 
2046
 
   uniform = &shProg->Uniforms->Uniforms[location];
2047
 
 
2048
 
   if (shProg->VertexProgram) {
2049
 
      /* convert uniform location to program parameter index */
2050
 
      GLint index = uniform->VertPos;
2051
 
      if (index >= 0) {
2052
 
         set_program_uniform_matrix(ctx, &shProg->VertexProgram->Base,
2053
 
                                    index, offset,
2054
 
                                    count, rows, cols, transpose, values);
2055
 
      }
2056
 
   }
2057
 
 
2058
 
   if (shProg->FragmentProgram) {
2059
 
      /* convert uniform location to program parameter index */
2060
 
      GLint index = uniform->FragPos;
2061
 
      if (index >= 0) {
2062
 
         set_program_uniform_matrix(ctx, &shProg->FragmentProgram->Base,
2063
 
                                    index, offset,
2064
 
                                    count, rows, cols, transpose, values);
2065
 
      }
2066
 
   }
2067
 
 
2068
 
   uniform->Initialized = GL_TRUE;
2069
 
}
2070
 
 
2071
 
 
2072
 
/**
2073
 
 * Validate a program's samplers.
2074
 
 * Specifically, check that there aren't two samplers of different types
2075
 
 * pointing to the same texture unit.
2076
 
 * \return GL_TRUE if valid, GL_FALSE if invalid
2077
 
 */
2078
 
static GLboolean
2079
 
validate_samplers(GLcontext *ctx, const struct gl_program *prog, char *errMsg)
2080
 
{
2081
 
   static const char *targetName[] = {
2082
 
      "TEXTURE_2D_ARRAY",
2083
 
      "TEXTURE_1D_ARRAY",
2084
 
      "TEXTURE_CUBE",
2085
 
      "TEXTURE_3D",
2086
 
      "TEXTURE_RECT",
2087
 
      "TEXTURE_2D",
2088
 
      "TEXTURE_1D",
2089
 
   };
2090
 
   GLint targetUsed[MAX_TEXTURE_IMAGE_UNITS];
2091
 
   GLbitfield samplersUsed = prog->SamplersUsed;
2092
 
   GLuint i;
2093
 
 
2094
 
   assert(Elements(targetName) == NUM_TEXTURE_TARGETS);
2095
 
 
2096
 
   if (samplersUsed == 0x0)
2097
 
      return GL_TRUE;
2098
 
 
2099
 
   for (i = 0; i < Elements(targetUsed); i++)
2100
 
      targetUsed[i] = -1;
2101
 
 
2102
 
   /* walk over bits which are set in 'samplers' */
2103
 
   while (samplersUsed) {
2104
 
      GLuint unit;
2105
 
      gl_texture_index target;
2106
 
      GLint sampler = _mesa_ffs(samplersUsed) - 1;
2107
 
      assert(sampler >= 0);
2108
 
      assert(sampler < MAX_TEXTURE_IMAGE_UNITS);
2109
 
      unit = prog->SamplerUnits[sampler];
2110
 
      target = prog->SamplerTargets[sampler];
2111
 
      if (targetUsed[unit] != -1 && targetUsed[unit] != target) {
2112
 
         _mesa_snprintf(errMsg, 100,
2113
 
                  "Texture unit %d is accessed both as %s and %s",
2114
 
                  unit, targetName[targetUsed[unit]], targetName[target]);
2115
 
         return GL_FALSE;
2116
 
      }
2117
 
      targetUsed[unit] = target;
2118
 
      samplersUsed ^= (1 << sampler);
2119
 
   }
2120
 
 
2121
 
   return GL_TRUE;
2122
 
}
2123
 
 
2124
 
 
2125
 
/**
2126
 
 * Do validation of the given shader program.
2127
 
 * \param errMsg  returns error message if validation fails.
2128
 
 * \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg)
2129
 
 */
2130
 
GLboolean
2131
 
_mesa_validate_shader_program(GLcontext *ctx,
2132
 
                              const struct gl_shader_program *shProg,
2133
 
                              char *errMsg)
2134
 
{
2135
 
   const struct gl_vertex_program *vp = shProg->VertexProgram;
2136
 
   const struct gl_fragment_program *fp = shProg->FragmentProgram;
2137
 
 
2138
 
   if (!shProg->LinkStatus) {
2139
 
      return GL_FALSE;
2140
 
   }
2141
 
 
2142
 
   /* From the GL spec, a program is invalid if any of these are true:
2143
 
 
2144
 
     any two active samplers in the current program object are of
2145
 
     different types, but refer to the same texture image unit,
2146
 
 
2147
 
     any active sampler in the current program object refers to a texture
2148
 
     image unit where fixed-function fragment processing accesses a
2149
 
     texture target that does not match the sampler type, or 
2150
 
 
2151
 
     the sum of the number of active samplers in the program and the
2152
 
     number of texture image units enabled for fixed-function fragment
2153
 
     processing exceeds the combined limit on the total number of texture
2154
 
     image units allowed.
2155
 
   */
2156
 
 
2157
 
 
2158
 
   /*
2159
 
    * Check: any two active samplers in the current program object are of
2160
 
    * different types, but refer to the same texture image unit,
2161
 
    */
2162
 
   if (vp && !validate_samplers(ctx, &vp->Base, errMsg)) {
2163
 
      return GL_FALSE;
2164
 
   }
2165
 
   if (fp && !validate_samplers(ctx, &fp->Base, errMsg)) {
2166
 
      return GL_FALSE;
2167
 
   }
2168
 
 
2169
 
   return GL_TRUE;
2170
 
}
2171
 
 
2172
 
 
2173
 
/**
2174
 
 * Called via glValidateProgram()
2175
 
 */
2176
 
static void
2177
 
_mesa_validate_program(GLcontext *ctx, GLuint program)
2178
 
{
2179
 
   struct gl_shader_program *shProg;
2180
 
   char errMsg[100];
2181
 
 
2182
 
   shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram");
2183
 
   if (!shProg) {
2184
 
      return;
2185
 
   }
2186
 
 
2187
 
   shProg->Validated = _mesa_validate_shader_program(ctx, shProg, errMsg);
2188
 
   if (!shProg->Validated) {
2189
 
      /* update info log */
2190
 
      if (shProg->InfoLog) {
2191
 
         free(shProg->InfoLog);
2192
 
      }
2193
 
      shProg->InfoLog = _mesa_strdup(errMsg);
2194
 
   }
2195
 
}
2196
 
 
2197
 
 
2198
 
/**
2199
 
 * Plug in Mesa's GLSL functions into the device driver function table.
2200
 
 */
2201
 
void
2202
 
_mesa_init_glsl_driver_functions(struct dd_function_table *driver)
2203
 
{
2204
 
   driver->AttachShader = _mesa_attach_shader;
2205
 
   driver->BindAttribLocation = _mesa_bind_attrib_location;
2206
 
   driver->CompileShader = _mesa_compile_shader;
2207
 
   driver->CreateProgram = _mesa_create_program;
2208
 
   driver->CreateShader = _mesa_create_shader;
2209
 
   driver->DeleteProgram2 = _mesa_delete_program2;
2210
 
   driver->DeleteShader = _mesa_delete_shader;
2211
 
   driver->DetachShader = _mesa_detach_shader;
2212
 
   driver->GetActiveAttrib = _mesa_get_active_attrib;
2213
 
   driver->GetActiveUniform = _mesa_get_active_uniform;
2214
 
   driver->GetAttachedShaders = _mesa_get_attached_shaders;
2215
 
   driver->GetAttribLocation = _mesa_get_attrib_location;
2216
 
   driver->GetHandle = _mesa_get_handle;
2217
 
   driver->GetProgramiv = _mesa_get_programiv;
2218
 
   driver->GetProgramInfoLog = _mesa_get_program_info_log;
2219
 
   driver->GetShaderiv = _mesa_get_shaderiv;
2220
 
   driver->GetShaderInfoLog = _mesa_get_shader_info_log;
2221
 
   driver->GetShaderSource = _mesa_get_shader_source;
2222
 
   driver->GetUniformfv = _mesa_get_uniformfv;
2223
 
   driver->GetUniformiv = _mesa_get_uniformiv;
2224
 
   driver->GetUniformLocation = _mesa_get_uniform_location;
2225
 
   driver->IsProgram = _mesa_is_program;
2226
 
   driver->IsShader = _mesa_is_shader;
2227
 
   driver->LinkProgram = _mesa_link_program;
2228
 
   driver->ShaderSource = _mesa_shader_source;
2229
 
   driver->Uniform = _mesa_uniform;
2230
 
   driver->UniformMatrix = _mesa_uniform_matrix;
2231
 
   driver->UseProgram = _mesa_use_program;
2232
 
   driver->ValidateProgram = _mesa_validate_program;
2233
 
}