Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

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