Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
4358 Serge 1
/*
2
 * Mesa 3-D graphics library
3
 *
4
 * Copyright (C) 2004-2008  Brian Paul   All Rights Reserved.
5
 * Copyright (C) 2009-2010  VMware, Inc.  All Rights Reserved.
6
 * Copyright © 2010, 2011 Intel Corporation
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
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24
 * OTHER DEALINGS IN THE SOFTWARE.
25
 */
26
 
27
#include 
28
 
29
#include "main/core.h"
30
#include "main/context.h"
31
#include "ir.h"
32
#include "ir_uniform.h"
33
#include "program/hash_table.h"
34
#include "../glsl/program.h"
35
#include "../glsl/ir_uniform.h"
36
#include "../glsl/glsl_parser_extras.h"
37
#include "main/shaderapi.h"
38
#include "main/shaderobj.h"
39
#include "uniforms.h"
40
 
41
 
42
extern "C" void GLAPIENTRY
43
_mesa_GetActiveUniform(GLhandleARB program, GLuint index,
44
                          GLsizei maxLength, GLsizei *length, GLint *size,
45
                          GLenum *type, GLcharARB *nameOut)
46
{
47
   GET_CURRENT_CONTEXT(ctx);
48
   struct gl_shader_program *shProg =
49
      _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform");
50
 
51
   if (!shProg)
52
      return;
53
 
54
   if (index >= shProg->NumUserUniformStorage) {
55
      _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)");
56
      return;
57
   }
58
 
59
   const struct gl_uniform_storage *const uni = &shProg->UniformStorage[index];
60
 
61
   if (nameOut) {
62
      _mesa_get_uniform_name(uni, maxLength, length, nameOut);
63
   }
64
 
65
   if (size) {
66
      /* array_elements is zero for non-arrays, but the API requires that 1 be
67
       * returned.
68
       */
69
      *size = MAX2(1, uni->array_elements);
70
   }
71
 
72
   if (type) {
73
      *type = uni->type->gl_type;
74
   }
75
}
76
 
77
extern "C" void GLAPIENTRY
78
_mesa_GetActiveUniformsiv(GLuint program,
79
			  GLsizei uniformCount,
80
			  const GLuint *uniformIndices,
81
			  GLenum pname,
82
			  GLint *params)
83
{
84
   GET_CURRENT_CONTEXT(ctx);
85
   struct gl_shader_program *shProg;
86
   GLsizei i;
87
 
88
   shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform");
89
   if (!shProg)
90
      return;
91
 
92
   if (uniformCount < 0) {
93
      _mesa_error(ctx, GL_INVALID_VALUE,
94
		  "glGetUniformIndices(uniformCount < 0)");
95
      return;
96
   }
97
 
98
   for (i = 0; i < uniformCount; i++) {
99
      GLuint index = uniformIndices[i];
100
 
101
      if (index >= shProg->NumUserUniformStorage) {
102
	 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformsiv(index)");
103
	 return;
104
      }
105
   }
106
 
107
   for (i = 0; i < uniformCount; i++) {
108
      GLuint index = uniformIndices[i];
109
      const struct gl_uniform_storage *uni = &shProg->UniformStorage[index];
110
 
111
      switch (pname) {
112
      case GL_UNIFORM_TYPE:
113
	 params[i] = uni->type->gl_type;
114
	 break;
115
 
116
      case GL_UNIFORM_SIZE:
117
	 /* array_elements is zero for non-arrays, but the API requires that 1 be
118
	  * returned.
119
	  */
120
	 params[i] = MAX2(1, uni->array_elements);
121
	 break;
122
 
123
      case GL_UNIFORM_NAME_LENGTH:
124
	 params[i] = strlen(uni->name) + 1;
125
 
126
         /* Page 61 (page 73 of the PDF) in section 2.11 of the OpenGL ES 3.0
127
          * spec says:
128
          *
129
          *     "If the active uniform is an array, the uniform name returned
130
          *     in name will always be the name of the uniform array appended
131
          *     with "[0]"."
132
          */
133
         if (uni->array_elements != 0)
134
            params[i] += 3;
135
	 break;
136
 
137
      case GL_UNIFORM_BLOCK_INDEX:
138
	 params[i] = uni->block_index;
139
	 break;
140
 
141
      case GL_UNIFORM_OFFSET:
142
	 params[i] = uni->offset;
143
	 break;
144
 
145
      case GL_UNIFORM_ARRAY_STRIDE:
146
	 params[i] = uni->array_stride;
147
	 break;
148
 
149
      case GL_UNIFORM_MATRIX_STRIDE:
150
	 params[i] = uni->matrix_stride;
151
	 break;
152
 
153
      case GL_UNIFORM_IS_ROW_MAJOR:
154
	 params[i] = uni->row_major;
155
	 break;
156
 
157
      default:
158
	 _mesa_error(ctx, GL_INVALID_ENUM, "glGetActiveUniformsiv(pname)");
159
	 return;
160
      }
161
   }
162
}
163
 
164
static bool
165
validate_uniform_parameters(struct gl_context *ctx,
166
			    struct gl_shader_program *shProg,
167
			    GLint location, GLsizei count,
168
			    unsigned *loc,
169
			    unsigned *array_index,
170
			    const char *caller,
171
			    bool negative_one_is_not_valid)
172
{
173
   if (!shProg || !shProg->LinkStatus) {
174
      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)", caller);
175
      return false;
176
   }
177
 
178
   if (location == -1) {
179
      /* For glGetUniform, page 264 (page 278 of the PDF) of the OpenGL 2.1
180
       * spec says:
181
       *
182
       *     "The error INVALID_OPERATION is generated if program has not been
183
       *     linked successfully, or if location is not a valid location for
184
       *     program."
185
       *
186
       * For glUniform, page 82 (page 96 of the PDF) of the OpenGL 2.1 spec
187
       * says:
188
       *
189
       *     "If the value of location is -1, the Uniform* commands will
190
       *     silently ignore the data passed in, and the current uniform
191
       *     values will not be changed."
192
       *
193
       * Allowing -1 for the location parameter of glUniform allows
194
       * applications to avoid error paths in the case that, for example, some
195
       * uniform variable is removed by the compiler / linker after
196
       * optimization.  In this case, the new value of the uniform is dropped
197
       * on the floor.  For the case of glGetUniform, there is nothing
198
       * sensible to do for a location of -1.
199
       *
200
       * The negative_one_is_not_valid flag selects between the two behaviors.
201
       */
202
      if (negative_one_is_not_valid) {
203
	 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)",
204
		     caller, location);
205
      }
206
 
207
      return false;
208
   }
209
 
210
   /* From page 12 (page 26 of the PDF) of the OpenGL 2.1 spec:
211
    *
212
    *     "If a negative number is provided where an argument of type sizei or
213
    *     sizeiptr is specified, the error INVALID_VALUE is generated."
214
    */
215
   if (count < 0) {
216
      _mesa_error(ctx, GL_INVALID_VALUE, "%s(count < 0)", caller);
217
      return false;
218
   }
219
 
220
   /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says:
221
    *
222
    *     "If any of the following conditions occur, an INVALID_OPERATION
223
    *     error is generated by the Uniform* commands, and no uniform values
224
    *     are changed:
225
    *
226
    *     ...
227
    *
228
    *         - if no variable with a location of location exists in the
229
    *           program object currently in use and location is not -1,
230
    *         - if count is greater than one, and the uniform declared in the
231
    *           shader is not an array variable,
232
    */
233
   if (location < -1) {
234
      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)",
235
                  caller, location);
236
      return false;
237
   }
238
 
239
   _mesa_uniform_split_location_offset(shProg, location, loc, array_index);
240
 
241
   if (*loc >= shProg->NumUserUniformStorage) {
242
      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)",
243
		  caller, location);
244
      return false;
245
   }
246
 
247
   if (shProg->UniformStorage[*loc].array_elements == 0 && count > 1) {
248
      _mesa_error(ctx, GL_INVALID_OPERATION,
249
		  "%s(count > 1 for non-array, location=%d)",
250
		  caller, location);
251
      return false;
252
   }
253
 
254
   /* If the uniform is an array, check that array_index is in bounds.
255
    * If not an array, check that array_index is zero.
256
    * array_index is unsigned so no need to check for less than zero.
257
    */
258
   unsigned limit = shProg->UniformStorage[*loc].array_elements;
259
   if (limit == 0)
260
      limit = 1;
261
   if (*array_index >= limit) {
262
      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)",
263
		  caller, location);
264
      return false;
265
   }
266
   return true;
267
}
268
 
269
/**
270
 * Called via glGetUniform[fiui]v() to get the current value of a uniform.
271
 */
272
extern "C" void
273
_mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location,
274
		  GLsizei bufSize, enum glsl_base_type returnType,
275
		  GLvoid *paramsOut)
276
{
277
   struct gl_shader_program *shProg =
278
      _mesa_lookup_shader_program_err(ctx, program, "glGetUniformfv");
279
   struct gl_uniform_storage *uni;
280
   unsigned loc, offset;
281
 
282
   if (!validate_uniform_parameters(ctx, shProg, location, 1,
283
				    &loc, &offset, "glGetUniform", true))
284
      return;
285
 
286
   uni = &shProg->UniformStorage[loc];
287
 
288
   {
289
      unsigned elements = (uni->type->is_sampler())
290
	 ? 1 : uni->type->components();
291
 
292
      /* Calculate the source base address *BEFORE* modifying elements to
293
       * account for the size of the user's buffer.
294
       */
295
      const union gl_constant_value *const src =
296
	 &uni->storage[offset * elements];
297
 
298
      assert(returnType == GLSL_TYPE_FLOAT || returnType == GLSL_TYPE_INT ||
299
             returnType == GLSL_TYPE_UINT);
300
      /* The three (currently) supported types all have the same size,
301
       * which is of course the same as their union. That'll change
302
       * with glGetUniformdv()...
303
       */
304
      unsigned bytes = sizeof(src[0]) * elements;
305
      if (bufSize < 0 || bytes > (unsigned) bufSize) {
306
	 _mesa_error( ctx, GL_INVALID_OPERATION,
307
	             "glGetnUniform*vARB(out of bounds: bufSize is %d,"
308
	             " but %u bytes are required)", bufSize, bytes );
309
	 return;
310
      }
311
 
312
      /* If the return type and the uniform's native type are "compatible,"
313
       * just memcpy the data.  If the types are not compatible, perform a
314
       * slower convert-and-copy process.
315
       */
316
      if (returnType == uni->type->base_type
317
	  || ((returnType == GLSL_TYPE_INT
318
	       || returnType == GLSL_TYPE_UINT
319
	       || returnType == GLSL_TYPE_SAMPLER)
320
	      &&
321
	      (uni->type->base_type == GLSL_TYPE_INT
322
	       || uni->type->base_type == GLSL_TYPE_UINT
323
	       || uni->type->base_type == GLSL_TYPE_SAMPLER))) {
324
	 memcpy(paramsOut, src, bytes);
325
      } else {
326
	 union gl_constant_value *const dst =
327
	    (union gl_constant_value *) paramsOut;
328
 
329
	 /* This code could be optimized by putting the loop inside the switch
330
	  * statements.  However, this is not expected to be
331
	  * performance-critical code.
332
	  */
333
	 for (unsigned i = 0; i < elements; i++) {
334
	    switch (returnType) {
335
	    case GLSL_TYPE_FLOAT:
336
	       switch (uni->type->base_type) {
337
	       case GLSL_TYPE_UINT:
338
		  dst[i].f = (float) src[i].u;
339
		  break;
340
	       case GLSL_TYPE_INT:
341
	       case GLSL_TYPE_SAMPLER:
342
		  dst[i].f = (float) src[i].i;
343
		  break;
344
	       case GLSL_TYPE_BOOL:
345
		  dst[i].f = src[i].i ? 1.0f : 0.0f;
346
		  break;
347
	       default:
348
		  assert(!"Should not get here.");
349
		  break;
350
	       }
351
	       break;
352
 
353
	    case GLSL_TYPE_INT:
354
	    case GLSL_TYPE_UINT:
355
	       switch (uni->type->base_type) {
356
	       case GLSL_TYPE_FLOAT:
357
		  /* While the GL 3.2 core spec doesn't explicitly
358
		   * state how conversion of float uniforms to integer
359
		   * values works, in section 6.2 "State Tables" on
360
		   * page 267 it says:
361
		   *
362
		   *     "Unless otherwise specified, when floating
363
		   *      point state is returned as integer values or
364
		   *      integer state is returned as floating-point
365
		   *      values it is converted in the fashion
366
		   *      described in section 6.1.2"
367
		   *
368
		   * That section, on page 248, says:
369
		   *
370
		   *     "If GetIntegerv or GetInteger64v are called,
371
		   *      a floating-point value is rounded to the
372
		   *      nearest integer..."
373
		   */
374
		  dst[i].i = IROUND(src[i].f);
375
		  break;
376
	       case GLSL_TYPE_BOOL:
377
		  dst[i].i = src[i].i ? 1 : 0;
378
		  break;
379
	       default:
380
		  assert(!"Should not get here.");
381
		  break;
382
	       }
383
	       break;
384
 
385
	    default:
386
	       assert(!"Should not get here.");
387
	       break;
388
	    }
389
	 }
390
      }
391
   }
392
}
393
 
394
static void
395
log_uniform(const void *values, enum glsl_base_type basicType,
396
	    unsigned rows, unsigned cols, unsigned count,
397
	    bool transpose,
398
	    const struct gl_shader_program *shProg,
399
	    GLint location,
400
	    const struct gl_uniform_storage *uni)
401
{
402
 
403
   const union gl_constant_value *v = (const union gl_constant_value *) values;
404
   const unsigned elems = rows * cols * count;
405
   const char *const extra = (cols == 1) ? "uniform" : "uniform matrix";
406
 
407
   printf("Mesa: set program %u %s \"%s\" (loc %d, type \"%s\", "
408
	  "transpose = %s) to: ",
409
	  shProg->Name, extra, uni->name, location, uni->type->name,
410
	  transpose ? "true" : "false");
411
   for (unsigned i = 0; i < elems; i++) {
412
      if (i != 0 && ((i % rows) == 0))
413
	 printf(", ");
414
 
415
      switch (basicType) {
416
      case GLSL_TYPE_UINT:
417
	 printf("%u ", v[i].u);
418
	 break;
419
      case GLSL_TYPE_INT:
420
	 printf("%d ", v[i].i);
421
	 break;
422
      case GLSL_TYPE_FLOAT:
423
	 printf("%g ", v[i].f);
424
	 break;
425
      default:
426
	 assert(!"Should not get here.");
427
	 break;
428
      }
429
   }
430
   printf("\n");
431
   fflush(stdout);
432
}
433
 
434
#if 0
435
static void
436
log_program_parameters(const struct gl_shader_program *shProg)
437
{
438
   for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
439
      if (shProg->_LinkedShaders[i] == NULL)
440
	 continue;
441
 
442
      const struct gl_program *const prog = shProg->_LinkedShaders[i]->Program;
443
 
444
      printf("Program %d %s shader parameters:\n",
445
             shProg->Name, _mesa_glsl_shader_target_name(prog->Target));
446
      for (unsigned j = 0; j < prog->Parameters->NumParameters; j++) {
447
	 printf("%s: %p %f %f %f %f\n",
448
		prog->Parameters->Parameters[j].Name,
449
		prog->Parameters->ParameterValues[j],
450
		prog->Parameters->ParameterValues[j][0].f,
451
		prog->Parameters->ParameterValues[j][1].f,
452
		prog->Parameters->ParameterValues[j][2].f,
453
		prog->Parameters->ParameterValues[j][3].f);
454
      }
455
   }
456
   fflush(stdout);
457
}
458
#endif
459
 
460
/**
461
 * Propagate some values from uniform backing storage to driver storage
462
 *
463
 * Values propagated from uniform backing storage to driver storage
464
 * have all format / type conversions previously requested by the
465
 * driver applied.  This function is most often called by the
466
 * implementations of \c glUniform1f, etc. and \c glUniformMatrix2f,
467
 * etc.
468
 *
469
 * \param uni          Uniform whose data is to be propagated to driver storage
470
 * \param array_index  If \c uni is an array, this is the element of
471
 *                     the array to be propagated.
472
 * \param count        Number of array elements to propagate.
473
 */
474
extern "C" void
475
_mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage *uni,
476
					   unsigned array_index,
477
					   unsigned count)
478
{
479
   unsigned i;
480
 
481
   /* vector_elements and matrix_columns can be 0 for samplers.
482
    */
483
   const unsigned components = MAX2(1, uni->type->vector_elements);
484
   const unsigned vectors = MAX2(1, uni->type->matrix_columns);
485
 
486
   /* Store the data in the driver's requested type in the driver's storage
487
    * areas.
488
    */
489
   unsigned src_vector_byte_stride = components * 4;
490
 
491
   for (i = 0; i < uni->num_driver_storage; i++) {
492
      struct gl_uniform_driver_storage *const store = &uni->driver_storage[i];
493
      uint8_t *dst = (uint8_t *) store->data;
494
      const unsigned extra_stride =
495
	 store->element_stride - (vectors * store->vector_stride);
496
      const uint8_t *src =
497
	 (uint8_t *) (&uni->storage[array_index * (components * vectors)].i);
498
 
499
#if 0
500
      printf("%s: %p[%d] components=%u vectors=%u count=%u vector_stride=%u "
501
	     "extra_stride=%u\n",
502
	     __func__, dst, array_index, components,
503
	     vectors, count, store->vector_stride, extra_stride);
504
#endif
505
 
506
      dst += array_index * store->element_stride;
507
 
508
      switch (store->format) {
509
      case uniform_native:
510
      case uniform_bool_int_0_1: {
511
	 unsigned j;
512
	 unsigned v;
513
 
514
	 for (j = 0; j < count; j++) {
515
	    for (v = 0; v < vectors; v++) {
516
	       memcpy(dst, src, src_vector_byte_stride);
517
	       src += src_vector_byte_stride;
518
	       dst += store->vector_stride;
519
	    }
520
 
521
	    dst += extra_stride;
522
	 }
523
	 break;
524
      }
525
 
526
      case uniform_int_float:
527
      case uniform_bool_float: {
528
	 const int *isrc = (const int *) src;
529
	 unsigned j;
530
	 unsigned v;
531
	 unsigned c;
532
 
533
	 for (j = 0; j < count; j++) {
534
	    for (v = 0; v < vectors; v++) {
535
	       for (c = 0; c < components; c++) {
536
		  ((float *) dst)[c] = (float) *isrc;
537
		  isrc++;
538
	       }
539
 
540
	       dst += store->vector_stride;
541
	    }
542
 
543
	    dst += extra_stride;
544
	 }
545
	 break;
546
      }
547
 
548
      case uniform_bool_int_0_not0: {
549
	 const int *isrc = (const int *) src;
550
	 unsigned j;
551
	 unsigned v;
552
	 unsigned c;
553
 
554
	 for (j = 0; j < count; j++) {
555
	    for (v = 0; v < vectors; v++) {
556
	       for (c = 0; c < components; c++) {
557
		  ((int *) dst)[c] = *isrc == 0 ? 0 : ~0;
558
		  isrc++;
559
	       }
560
 
561
	       dst += store->vector_stride;
562
	    }
563
 
564
	    dst += extra_stride;
565
	 }
566
	 break;
567
      }
568
 
569
      default:
570
	 assert(!"Should not get here.");
571
	 break;
572
      }
573
   }
574
}
575
 
576
/**
577
 * Called via glUniform*() functions.
578
 */
579
extern "C" void
580
_mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg,
581
	      GLint location, GLsizei count,
582
              const GLvoid *values, GLenum type)
583
{
584
   unsigned loc, offset;
585
   unsigned components;
586
   unsigned src_components;
587
   enum glsl_base_type basicType;
588
   struct gl_uniform_storage *uni;
589
 
590
   if (!validate_uniform_parameters(ctx, shProg, location, count,
591
				    &loc, &offset, "glUniform", false))
592
      return;
593
 
594
   uni = &shProg->UniformStorage[loc];
595
 
596
   /* Verify that the types are compatible.
597
    */
598
   switch (type) {
599
   case GL_FLOAT:
600
      basicType = GLSL_TYPE_FLOAT;
601
      src_components = 1;
602
      break;
603
   case GL_FLOAT_VEC2:
604
      basicType = GLSL_TYPE_FLOAT;
605
      src_components = 2;
606
      break;
607
   case GL_FLOAT_VEC3:
608
      basicType = GLSL_TYPE_FLOAT;
609
      src_components = 3;
610
      break;
611
   case GL_FLOAT_VEC4:
612
      basicType = GLSL_TYPE_FLOAT;
613
      src_components = 4;
614
      break;
615
   case GL_UNSIGNED_INT:
616
      basicType = GLSL_TYPE_UINT;
617
      src_components = 1;
618
      break;
619
   case GL_UNSIGNED_INT_VEC2:
620
      basicType = GLSL_TYPE_UINT;
621
      src_components = 2;
622
      break;
623
   case GL_UNSIGNED_INT_VEC3:
624
      basicType = GLSL_TYPE_UINT;
625
      src_components = 3;
626
      break;
627
   case GL_UNSIGNED_INT_VEC4:
628
      basicType = GLSL_TYPE_UINT;
629
      src_components = 4;
630
      break;
631
   case GL_INT:
632
      basicType = GLSL_TYPE_INT;
633
      src_components = 1;
634
      break;
635
   case GL_INT_VEC2:
636
      basicType = GLSL_TYPE_INT;
637
      src_components = 2;
638
      break;
639
   case GL_INT_VEC3:
640
      basicType = GLSL_TYPE_INT;
641
      src_components = 3;
642
      break;
643
   case GL_INT_VEC4:
644
      basicType = GLSL_TYPE_INT;
645
      src_components = 4;
646
      break;
647
   case GL_BOOL:
648
   case GL_BOOL_VEC2:
649
   case GL_BOOL_VEC3:
650
   case GL_BOOL_VEC4:
651
   case GL_FLOAT_MAT2:
652
   case GL_FLOAT_MAT2x3:
653
   case GL_FLOAT_MAT2x4:
654
   case GL_FLOAT_MAT3x2:
655
   case GL_FLOAT_MAT3:
656
   case GL_FLOAT_MAT3x4:
657
   case GL_FLOAT_MAT4x2:
658
   case GL_FLOAT_MAT4x3:
659
   case GL_FLOAT_MAT4:
660
   default:
661
      _mesa_problem(NULL, "Invalid type in %s", __func__);
662
      return;
663
   }
664
 
665
   if (uni->type->is_sampler()) {
666
      components = 1;
667
   } else {
668
      components = uni->type->vector_elements;
669
   }
670
 
671
   bool match;
672
   switch (uni->type->base_type) {
673
   case GLSL_TYPE_BOOL:
674
      match = true;
675
      break;
676
   case GLSL_TYPE_SAMPLER:
677
      match = (basicType == GLSL_TYPE_INT);
678
      break;
679
   default:
680
      match = (basicType == uni->type->base_type);
681
      break;
682
   }
683
 
684
   if (uni->type->is_matrix() || components != src_components || !match) {
685
      _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(type mismatch)");
686
      return;
687
   }
688
 
689
   if (ctx->Shader.Flags & GLSL_UNIFORMS) {
690
      log_uniform(values, basicType, components, 1, count,
691
		  false, shProg, location, uni);
692
   }
693
 
694
   /* Page 100 (page 116 of the PDF) of the OpenGL 3.0 spec says:
695
    *
696
    *     "Setting a sampler's value to i selects texture image unit number
697
    *     i. The values of i range from zero to the implementation- dependent
698
    *     maximum supported number of texture image units."
699
    *
700
    * In addition, table 2.3, "Summary of GL errors," on page 17 (page 33 of
701
    * the PDF) says:
702
    *
703
    *     "Error         Description                    Offending command
704
    *                                                   ignored?
705
    *     ...
706
    *     INVALID_VALUE  Numeric argument out of range  Yes"
707
    *
708
    * Based on that, when an invalid sampler is specified, we generate a
709
    * GL_INVALID_VALUE error and ignore the command.
710
    */
711
   if (uni->type->is_sampler()) {
712
      int i;
713
 
714
      for (i = 0; i < count; i++) {
715
	 const unsigned texUnit = ((unsigned *) values)[i];
716
 
717
         /* check that the sampler (tex unit index) is legal */
718
         if (texUnit >= ctx->Const.MaxCombinedTextureImageUnits) {
719
            _mesa_error(ctx, GL_INVALID_VALUE,
720
                        "glUniform1i(invalid sampler/tex unit index for "
721
			"uniform %d)",
722
                        location);
723
            return;
724
         }
725
      }
726
   }
727
 
728
   /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says:
729
    *
730
    *     "When loading N elements starting at an arbitrary position k in a
731
    *     uniform declared as an array, elements k through k + N - 1 in the
732
    *     array will be replaced with the new values. Values for any array
733
    *     element that exceeds the highest array element index used, as
734
    *     reported by GetActiveUniform, will be ignored by the GL."
735
    *
736
    * Clamp 'count' to a valid value.  Note that for non-arrays a count > 1
737
    * will have already generated an error.
738
    */
739
   if (uni->array_elements != 0) {
740
      count = MIN2(count, (int) (uni->array_elements - offset));
741
   }
742
 
743
   FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
744
 
745
   /* Store the data in the "actual type" backing storage for the uniform.
746
    */
747
   if (!uni->type->is_boolean()) {
748
      memcpy(&uni->storage[components * offset], values,
749
	     sizeof(uni->storage[0]) * components * count);
750
   } else {
751
      const union gl_constant_value *src =
752
	 (const union gl_constant_value *) values;
753
      union gl_constant_value *dst = &uni->storage[components * offset];
754
      const unsigned elems = components * count;
755
      unsigned i;
756
 
757
      for (i = 0; i < elems; i++) {
758
	 if (basicType == GLSL_TYPE_FLOAT) {
759
	    dst[i].i = src[i].f != 0.0f ? 1 : 0;
760
	 } else {
761
	    dst[i].i = src[i].i != 0    ? 1 : 0;
762
	 }
763
      }
764
   }
765
 
766
   uni->initialized = true;
767
 
768
   _mesa_propagate_uniforms_to_driver_storage(uni, offset, count);
769
 
770
   /* If the uniform is a sampler, do the extra magic necessary to propagate
771
    * the changes through.
772
    */
773
   if (uni->type->is_sampler()) {
774
      int i;
775
 
776
      bool flushed = false;
777
      for (i = 0; i < MESA_SHADER_TYPES; i++) {
778
	 struct gl_shader *const sh = shProg->_LinkedShaders[i];
779
         int j;
780
 
781
	 /* If the shader stage doesn't use the sampler uniform, skip this.
782
	  */
783
	 if (sh == NULL || !uni->sampler[i].active)
784
	    continue;
785
 
786
         for (j = 0; j < count; j++) {
787
            sh->SamplerUnits[uni->sampler[i].index + offset + j] =
788
               ((unsigned *) values)[j];
789
         }
790
 
791
	 struct gl_program *const prog = sh->Program;
792
 
793
	 assert(sizeof(prog->SamplerUnits) == sizeof(sh->SamplerUnits));
794
 
795
	 /* Determine if any of the samplers used by this shader stage have
796
	  * been modified.
797
	  */
798
	 bool changed = false;
799
	 for (unsigned j = 0; j < Elements(prog->SamplerUnits); j++) {
800
	    if ((sh->active_samplers & (1U << j)) != 0
801
		&& (prog->SamplerUnits[j] != sh->SamplerUnits[j])) {
802
	       changed = true;
803
	       break;
804
	    }
805
	 }
806
 
807
	 if (changed) {
808
	    if (!flushed) {
809
	       FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM);
810
	       flushed = true;
811
	    }
812
 
813
	    memcpy(prog->SamplerUnits,
814
		   sh->SamplerUnits,
815
		   sizeof(sh->SamplerUnits));
816
 
817
	    _mesa_update_shader_textures_used(shProg, prog);
818
            if (ctx->Driver.SamplerUniformChange)
819
	       ctx->Driver.SamplerUniformChange(ctx, prog->Target, prog);
820
	 }
821
      }
822
   }
823
}
824
 
825
/**
826
 * Called by glUniformMatrix*() functions.
827
 * Note: cols=2, rows=4  ==>  array[2] of vec4
828
 */
829
extern "C" void
830
_mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg,
831
		     GLuint cols, GLuint rows,
832
                     GLint location, GLsizei count,
833
                     GLboolean transpose, const GLfloat *values)
834
{
835
   unsigned loc, offset;
836
   unsigned vectors;
837
   unsigned components;
838
   unsigned elements;
839
   struct gl_uniform_storage *uni;
840
 
841
   if (!validate_uniform_parameters(ctx, shProg, location, count,
842
				    &loc, &offset, "glUniformMatrix", false))
843
      return;
844
 
845
   uni = &shProg->UniformStorage[loc];
846
   if (!uni->type->is_matrix()) {
847
      _mesa_error(ctx, GL_INVALID_OPERATION,
848
		  "glUniformMatrix(non-matrix uniform)");
849
      return;
850
   }
851
 
852
   assert(!uni->type->is_sampler());
853
   vectors = uni->type->matrix_columns;
854
   components = uni->type->vector_elements;
855
 
856
   /* Verify that the types are compatible.  This is greatly simplified for
857
    * matrices because they can only have a float base type.
858
    */
859
   if (vectors != cols || components != rows) {
860
      _mesa_error(ctx, GL_INVALID_OPERATION,
861
		  "glUniformMatrix(matrix size mismatch)");
862
      return;
863
   }
864
 
865
   /* GL_INVALID_VALUE is generated if `transpose' is not GL_FALSE.
866
    * http://www.khronos.org/opengles/sdk/docs/man/xhtml/glUniform.xml */
867
   if (ctx->API == API_OPENGLES
868
       || (ctx->API == API_OPENGLES2 && ctx->Version < 30)) {
869
      if (transpose) {
870
	 _mesa_error(ctx, GL_INVALID_VALUE,
871
		     "glUniformMatrix(matrix transpose is not GL_FALSE)");
872
	 return;
873
      }
874
   }
875
 
876
   if (ctx->Shader.Flags & GLSL_UNIFORMS) {
877
      log_uniform(values, GLSL_TYPE_FLOAT, components, vectors, count,
878
		  bool(transpose), shProg, location, uni);
879
   }
880
 
881
   /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says:
882
    *
883
    *     "When loading N elements starting at an arbitrary position k in a
884
    *     uniform declared as an array, elements k through k + N - 1 in the
885
    *     array will be replaced with the new values. Values for any array
886
    *     element that exceeds the highest array element index used, as
887
    *     reported by GetActiveUniform, will be ignored by the GL."
888
    *
889
    * Clamp 'count' to a valid value.  Note that for non-arrays a count > 1
890
    * will have already generated an error.
891
    */
892
   if (uni->array_elements != 0) {
893
      count = MIN2(count, (int) (uni->array_elements - offset));
894
   }
895
 
896
   FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
897
 
898
   /* Store the data in the "actual type" backing storage for the uniform.
899
    */
900
   elements = components * vectors;
901
 
902
   if (!transpose) {
903
      memcpy(&uni->storage[elements * offset], values,
904
	     sizeof(uni->storage[0]) * elements * count);
905
   } else {
906
      /* Copy and transpose the matrix.
907
       */
908
      const float *src = values;
909
      float *dst = &uni->storage[elements * offset].f;
910
 
911
      for (int i = 0; i < count; i++) {
912
	 for (unsigned r = 0; r < rows; r++) {
913
	    for (unsigned c = 0; c < cols; c++) {
914
	       dst[(c * components) + r] = src[c + (r * vectors)];
915
	    }
916
	 }
917
 
918
	 dst += elements;
919
	 src += elements;
920
      }
921
   }
922
 
923
   uni->initialized = true;
924
 
925
   _mesa_propagate_uniforms_to_driver_storage(uni, offset, count);
926
}
927
 
928
 
929
/**
930
 * Called via glGetUniformLocation().
931
 *
932
 * Returns the uniform index into UniformStorage (also the
933
 * glGetActiveUniformsiv uniform index), and stores the referenced
934
 * array offset in *offset, or GL_INVALID_INDEX (-1).  Those two
935
 * return values can be encoded into a uniform location for
936
 * glUniform* using _mesa_uniform_merge_location_offset(index, offset).
937
 */
938
extern "C" unsigned
939
_mesa_get_uniform_location(struct gl_context *ctx,
940
                           struct gl_shader_program *shProg,
941
                           const GLchar *name,
942
                           unsigned *out_offset)
943
{
944
   /* Page 80 (page 94 of the PDF) of the OpenGL 2.1 spec says:
945
    *
946
    *     "The first element of a uniform array is identified using the
947
    *     name of the uniform array appended with "[0]". Except if the last
948
    *     part of the string name indicates a uniform array, then the
949
    *     location of the first element of that array can be retrieved by
950
    *     either using the name of the uniform array, or the name of the
951
    *     uniform array appended with "[0]"."
952
    *
953
    * Note: since uniform names are not allowed to use whitespace, and array
954
    * indices within uniform names are not allowed to use "+", "-", or leading
955
    * zeros, it follows that each uniform has a unique name up to the possible
956
    * ambiguity with "[0]" noted above.  Therefore we don't need to worry
957
    * about mal-formed inputs--they will properly fail when we try to look up
958
    * the uniform name in shProg->UniformHash.
959
    */
960
 
961
   const GLchar *base_name_end;
962
   long offset = parse_program_resource_name(name, &base_name_end);
963
   bool array_lookup = offset >= 0;
964
   char *name_copy;
965
 
966
   if (array_lookup) {
967
      name_copy = (char *) malloc(base_name_end - name + 1);
968
      memcpy(name_copy, name, base_name_end - name);
969
      name_copy[base_name_end - name] = '\0';
970
   } else {
971
      name_copy = (char *) name;
972
      offset = 0;
973
   }
974
 
975
   unsigned location = 0;
976
   const bool found = shProg->UniformHash->get(location, name_copy);
977
 
978
   assert(!found
979
	  || strcmp(name_copy, shProg->UniformStorage[location].name) == 0);
980
 
981
   /* Free the temporary buffer *before* possibly returning an error.
982
    */
983
   if (name_copy != name)
984
      free(name_copy);
985
 
986
   if (!found)
987
      return GL_INVALID_INDEX;
988
 
989
   /* If the uniform is an array, fail if the index is out of bounds.
990
    * (A negative index is caught above.)  This also fails if the uniform
991
    * is not an array, but the user is trying to index it, because
992
    * array_elements is zero and offset >= 0.
993
    */
994
   if (array_lookup
995
       && offset >= (long) shProg->UniformStorage[location].array_elements) {
996
      return GL_INVALID_INDEX;
997
   }
998
 
999
   *out_offset = offset;
1000
   return location;
1001
}
1002
 
1003
extern "C" bool
1004
_mesa_sampler_uniforms_are_valid(const struct gl_shader_program *shProg,
1005
				 char *errMsg, size_t errMsgLength)
1006
{
1007
   const glsl_type *unit_types[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
1008
 
1009
   memset(unit_types, 0, sizeof(unit_types));
1010
 
1011
   for (unsigned i = 0; i < shProg->NumUserUniformStorage; i++) {
1012
      const struct gl_uniform_storage *const storage =
1013
	 &shProg->UniformStorage[i];
1014
      const glsl_type *const t = (storage->type->is_array())
1015
	 ? storage->type->fields.array : storage->type;
1016
 
1017
      if (!t->is_sampler())
1018
	 continue;
1019
 
1020
      const unsigned count = MAX2(1, storage->type->array_size());
1021
      for (unsigned j = 0; j < count; j++) {
1022
	 const unsigned unit = storage->storage[j].i;
1023
 
1024
	 /* The types of the samplers associated with a particular texture
1025
	  * unit must be an exact match.  Page 74 (page 89 of the PDF) of the
1026
	  * OpenGL 3.3 core spec says:
1027
	  *
1028
	  *     "It is not allowed to have variables of different sampler
1029
	  *     types pointing to the same texture image unit within a program
1030
	  *     object."
1031
	  */
1032
	 if (unit_types[unit] == NULL) {
1033
	    unit_types[unit] = t;
1034
	 } else if (unit_types[unit] != t) {
1035
	    _mesa_snprintf(errMsg, errMsgLength,
1036
			   "Texture unit %d is accessed both as %s and %s",
1037
			   unit, unit_types[unit]->name, t->name);
1038
	    return false;
1039
	 }
1040
      }
1041
   }
1042
 
1043
   return true;
1044
}