Only glUniform1i() can be used to set sampler uniforms. Generate error otherwise.
[mesa.git] / src / mesa / shader / shader_api.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.5.3
4 *
5 * Copyright (C) 2004-2007 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /**
26 * \file shader_api.c
27 * Implementation of GLSL-related API functions
28 * \author Brian Paul
29 */
30
31 /**
32 * XXX things to do:
33 * 1. Check that the right error code is generated for all _mesa_error() calls.
34 * 2. Insert FLUSH_VERTICES calls in various places
35 */
36
37
38 #include "glheader.h"
39 #include "context.h"
40 #include "hash.h"
41 #include "program.h"
42 #include "prog_parameter.h"
43 #include "prog_print.h"
44 #include "prog_statevars.h"
45 #include "shader_api.h"
46
47 #include "slang_compile.h"
48 #include "slang_link.h"
49
50
51
52 /**
53 * Allocate a new gl_shader_program object, initialize it.
54 */
55 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;
62 shProg->Name = name;
63 shProg->RefCount = 1;
64 shProg->Attributes = _mesa_new_parameter_list();
65 }
66 return shProg;
67 }
68
69
70 void
71 _mesa_free_shader_program_data(GLcontext *ctx,
72 struct gl_shader_program *shProg)
73 {
74 assert(shProg->Type == GL_SHADER_PROGRAM);
75
76 if (shProg->VertexProgram) {
77 if (shProg->VertexProgram->Base.Parameters == shProg->Uniforms) {
78 /* to prevent a double-free in the next call */
79 shProg->VertexProgram->Base.Parameters = NULL;
80 }
81 _mesa_delete_program(ctx, &shProg->VertexProgram->Base);
82 shProg->VertexProgram = NULL;
83 }
84
85 if (shProg->FragmentProgram) {
86 if (shProg->FragmentProgram->Base.Parameters == shProg->Uniforms) {
87 /* to prevent a double-free in the next call */
88 shProg->FragmentProgram->Base.Parameters = NULL;
89 }
90 _mesa_delete_program(ctx, &shProg->FragmentProgram->Base);
91 shProg->FragmentProgram = NULL;
92 }
93
94
95 if (shProg->Uniforms) {
96 _mesa_free_parameter_list(shProg->Uniforms);
97 shProg->Uniforms = NULL;
98 }
99
100 if (shProg->Varying) {
101 _mesa_free_parameter_list(shProg->Varying);
102 shProg->Varying = NULL;
103 }
104 }
105
106
107
108 void
109 _mesa_free_shader_program(GLcontext *ctx, struct gl_shader_program *shProg)
110 {
111 _mesa_free_shader_program_data(ctx, shProg);
112 _mesa_free(shProg);
113 }
114
115
116 /**
117 * Lookup a GLSL program object.
118 */
119 struct gl_shader_program *
120 _mesa_lookup_shader_program(GLcontext *ctx, GLuint name)
121 {
122 struct gl_shader_program *shProg;
123 if (name) {
124 shProg = (struct gl_shader_program *)
125 _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
126 /* Note that both gl_shader and gl_shader_program objects are kept
127 * in the same hash table. Check the object's type to be sure it's
128 * what we're expecting.
129 */
130 if (shProg && shProg->Type != GL_SHADER_PROGRAM) {
131 return NULL;
132 }
133 return shProg;
134 }
135 return NULL;
136 }
137
138
139 /**
140 * Allocate a new gl_shader object, initialize it.
141 */
142 struct gl_shader *
143 _mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type)
144 {
145 struct gl_shader *shader;
146 assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER);
147 shader = CALLOC_STRUCT(gl_shader);
148 if (shader) {
149 shader->Type = type;
150 shader->Name = name;
151 shader->RefCount = 1;
152 }
153 return shader;
154 }
155
156
157 void
158 _mesa_free_shader(GLcontext *ctx, struct gl_shader *sh)
159 {
160 GLuint i;
161 if (sh->Source)
162 _mesa_free((void *) sh->Source);
163 if (sh->InfoLog)
164 _mesa_free(sh->InfoLog);
165 for (i = 0; i < sh->NumPrograms; i++) {
166 assert(sh->Programs[i]);
167 _mesa_delete_program(ctx, sh->Programs[i]);
168 }
169 if (sh->Programs)
170 _mesa_free(sh->Programs);
171 _mesa_free(sh);
172 }
173
174
175 /**
176 * Lookup a GLSL shader object.
177 */
178 struct gl_shader *
179 _mesa_lookup_shader(GLcontext *ctx, GLuint name)
180 {
181 if (name) {
182 struct gl_shader *sh = (struct gl_shader *)
183 _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
184 /* Note that both gl_shader and gl_shader_program objects are kept
185 * in the same hash table. Check the object's type to be sure it's
186 * what we're expecting.
187 */
188 if (sh && sh->Type == GL_SHADER_PROGRAM) {
189 assert(sh->Type == GL_VERTEX_SHADER ||
190 sh->Type == GL_FRAGMENT_SHADER);
191 return NULL;
192 }
193 return sh;
194 }
195 return NULL;
196 }
197
198
199 void
200 _mesa_init_shader_state(GLcontext * ctx)
201 {
202 ctx->Shader._FragmentShaderPresent = GL_FALSE;
203 ctx->Shader._VertexShaderPresent = GL_FALSE;
204 }
205
206
207
208
209
210 /**
211 * Copy string from <src> to <dst>, up to maxLength characters, returning
212 * length of <dst> in <length>.
213 * \param src the strings source
214 * \param maxLength max chars to copy
215 * \param length returns number of chars copied
216 * \param dst the string destination
217 */
218 static void
219 copy_string(GLchar *dst, GLsizei maxLength, GLsizei *length, const GLchar *src)
220 {
221 GLsizei len;
222 for (len = 0; len < maxLength - 1 && src && src[len]; len++)
223 dst[len] = src[len];
224 if (maxLength > 0)
225 dst[len] = 0;
226 if (length)
227 *length = len;
228 }
229
230
231
232
233 /**
234 * Called via ctx->Driver.AttachShader()
235 */
236 void
237 _mesa_attach_shader(GLcontext *ctx, GLuint program, GLuint shader)
238 {
239 struct gl_shader_program *shProg
240 = _mesa_lookup_shader_program(ctx, program);
241 struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
242 const GLuint n = shProg->NumShaders;
243 GLuint i;
244
245 if (!shProg || !sh) {
246 _mesa_error(ctx, GL_INVALID_VALUE,
247 "glAttachShader(bad program or shader name)");
248 return;
249 }
250
251 for (i = 0; i < n; i++) {
252 if (shProg->Shaders[i] == sh) {
253 /* already attached */
254 return;
255 }
256 }
257
258 /* grow list */
259 shProg->Shaders = (struct gl_shader **)
260 _mesa_realloc(shProg->Shaders,
261 n * sizeof(struct gl_shader *),
262 (n + 1) * sizeof(struct gl_shader *));
263 if (!shProg->Shaders) {
264 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAttachShader");
265 return;
266 }
267
268 /* append */
269 shProg->Shaders[n] = sh;
270 sh->RefCount++;
271 shProg->NumShaders++;
272 }
273
274
275 void
276 _mesa_bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index,
277 const GLchar *name)
278 {
279 struct gl_shader_program *shProg
280 = _mesa_lookup_shader_program(ctx, program);
281 const GLint size = -1; /* unknown size */
282 GLint i, oldIndex;
283
284 if (!shProg) {
285 _mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocation(program)");
286 return;
287 }
288
289 if (!name)
290 return;
291
292 if (strncmp(name, "gl_", 3) == 0) {
293 _mesa_error(ctx, GL_INVALID_OPERATION,
294 "glBindAttribLocation(illegal name)");
295 return;
296 }
297
298 oldIndex = _mesa_get_attrib_location(ctx, program, name);
299
300 /* this will replace the current value if it's already in the list */
301 i = _mesa_add_attribute(shProg->Attributes, name, size, index);
302 if (i < 0) {
303 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindAttribLocation");
304 }
305
306 if (shProg->VertexProgram && oldIndex >= 0) {
307 _slang_remap_attribute(&shProg->VertexProgram->Base, oldIndex, index);
308 }
309
310 #if 0
311 printf("===== post BindAttrib:\n");
312 _mesa_print_program(&shProg->VertexProgram->Base);
313 #endif
314 }
315
316
317 GLuint
318 _mesa_create_shader(GLcontext *ctx, GLenum type)
319 {
320 struct gl_shader *sh;
321 GLuint name;
322
323 name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
324
325 switch (type) {
326 case GL_FRAGMENT_SHADER:
327 case GL_VERTEX_SHADER:
328 sh = _mesa_new_shader(ctx, name, type);
329 break;
330 default:
331 _mesa_error(ctx, GL_INVALID_ENUM, "CreateShader(type)");
332 return 0;
333 }
334
335 _mesa_HashInsert(ctx->Shared->ShaderObjects, name, sh);
336
337 return name;
338 }
339
340
341 GLuint
342 _mesa_create_program(GLcontext *ctx)
343 {
344 GLuint name;
345 struct gl_shader_program *shProg;
346
347 name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
348 shProg = _mesa_new_shader_program(ctx, name);
349
350 _mesa_HashInsert(ctx->Shared->ShaderObjects, name, shProg);
351
352 return name;
353 }
354
355
356 void
357 _mesa_delete_program2(GLcontext *ctx, GLuint name)
358 {
359 struct gl_shader_program *shProg;
360
361 shProg = _mesa_lookup_shader_program(ctx, name);
362 if (!shProg) {
363 _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteProgram(name)");
364 return;
365 }
366
367 /* always remove from hash table */
368 _mesa_HashRemove(ctx->Shared->ShaderObjects, name);
369
370 shProg->DeletePending = GL_TRUE;
371
372 /* decrement refcount, delete if zero */
373 shProg->RefCount--;
374 if (shProg->RefCount <= 0) {
375 _mesa_free_shader_program(ctx, shProg);
376 }
377 }
378
379
380 void
381 _mesa_delete_shader(GLcontext *ctx, GLuint shader)
382 {
383 struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
384 if (!sh) {
385 return;
386 }
387
388 sh->DeletePending = GL_TRUE;
389 sh->RefCount--;
390 if (sh->RefCount <= 0) {
391 _mesa_free_shader(ctx, sh);
392 }
393 }
394
395
396 void
397 _mesa_detach_shader(GLcontext *ctx, GLuint program, GLuint shader)
398 {
399 struct gl_shader_program *shProg
400 = _mesa_lookup_shader_program(ctx, program);
401 const GLuint n = shProg->NumShaders;
402 GLuint i, j;
403
404 if (!shProg) {
405 _mesa_error(ctx, GL_INVALID_VALUE,
406 "glDetachShader(bad program or shader name)");
407 return;
408 }
409
410 for (i = 0; i < n; i++) {
411 if (shProg->Shaders[i]->Name == shader) {
412 struct gl_shader **newList;
413 /* found it */
414
415 shProg->Shaders[i]->RefCount--;
416
417 /* alloc new, smaller array */
418 newList = (struct gl_shader **)
419 _mesa_malloc((n - 1) * sizeof(struct gl_shader *));
420 if (!newList) {
421 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDetachShader");
422 return;
423 }
424 for (j = 0; j < i; j++) {
425 newList[j] = shProg->Shaders[j];
426 }
427 while (++i < n)
428 newList[j++] = shProg->Shaders[i];
429 _mesa_free(shProg->Shaders);
430
431 /* XXX refcounting! */
432
433 shProg->Shaders = newList;
434 return;
435 }
436 }
437
438 /* not found */
439 _mesa_error(ctx, GL_INVALID_VALUE,
440 "glDetachShader(shader not found)");
441 }
442
443
444 void
445 _mesa_get_active_attrib(GLcontext *ctx, GLuint program, GLuint index,
446 GLsizei maxLength, GLsizei *length, GLint *size,
447 GLenum *type, GLchar *nameOut)
448 {
449 static const GLenum vec_types[] = {
450 GL_FLOAT, GL_FLOAT_VEC2, GL_FLOAT_VEC3, GL_FLOAT_VEC4
451 };
452 struct gl_shader_program *shProg
453 = _mesa_lookup_shader_program(ctx, program);
454 GLint sz;
455
456 if (!shProg) {
457 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform");
458 return;
459 }
460
461 if (!shProg->Attributes || index >= shProg->Attributes->NumParameters) {
462 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)");
463 return;
464 }
465
466 copy_string(nameOut, maxLength, length,
467 shProg->Attributes->Parameters[index].Name);
468 sz = shProg->Attributes->Parameters[index].Size;
469 if (size)
470 *size = sz;
471 if (type)
472 *type = vec_types[sz]; /* XXX this is a temporary hack */
473 }
474
475
476 /**
477 * Called via ctx->Driver.GetActiveUniform().
478 */
479 void
480 _mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index,
481 GLsizei maxLength, GLsizei *length, GLint *size,
482 GLenum *type, GLchar *nameOut)
483 {
484 static const GLenum vec_types[] = {
485 GL_FLOAT, GL_FLOAT_VEC2, GL_FLOAT_VEC3, GL_FLOAT_VEC4
486 };
487 struct gl_shader_program *shProg
488 = _mesa_lookup_shader_program(ctx, program);
489 GLint sz;
490
491 if (!shProg) {
492 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform");
493 return;
494 }
495
496 if (!shProg->Uniforms || index >= shProg->Uniforms->NumParameters) {
497 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)");
498 return;
499 }
500
501 copy_string(nameOut, maxLength, length,
502 shProg->Uniforms->Parameters[index].Name);
503 sz = shProg->Uniforms->Parameters[index].Size;
504 if (size)
505 *size = sz;
506 if (type)
507 *type = vec_types[sz]; /* XXX this is a temporary hack */
508 }
509
510
511 /**
512 * Called via ctx->Driver.GetAttachedShaders().
513 */
514 void
515 _mesa_get_attached_shaders(GLcontext *ctx, GLuint program, GLsizei maxCount,
516 GLsizei *count, GLuint *obj)
517 {
518 struct gl_shader_program *shProg
519 = _mesa_lookup_shader_program(ctx, program);
520 if (shProg) {
521 GLint i;
522 for (i = 0; i < maxCount && i < shProg->NumShaders; i++) {
523 obj[i] = shProg->Shaders[i]->Name;
524 }
525 if (count)
526 *count = i;
527 }
528 else {
529 _mesa_error(ctx, GL_INVALID_VALUE, "glGetAttachedShaders");
530 }
531 }
532
533
534 GLint
535 _mesa_get_attrib_location(GLcontext *ctx, GLuint program,
536 const GLchar *name)
537 {
538 struct gl_shader_program *shProg
539 = _mesa_lookup_shader_program(ctx, program);
540
541 if (!shProg) {
542 _mesa_error(ctx, GL_INVALID_VALUE, "glGetAttribLocation");
543 return -1;
544 }
545
546 if (!shProg->LinkStatus) {
547 _mesa_error(ctx, GL_INVALID_OPERATION,
548 "glGetAttribLocation(program not linked)");
549 return -1;
550 }
551
552 if (!name)
553 return -1;
554
555 if (shProg->Attributes) {
556 GLint i = _mesa_lookup_parameter_index(shProg->Attributes, -1, name);
557 if (i >= 0) {
558 return shProg->Attributes->Parameters[i].StateIndexes[0];
559 }
560 }
561 return -1;
562 }
563
564
565 GLuint
566 _mesa_get_handle(GLcontext *ctx, GLenum pname)
567 {
568 #if 0
569 GET_CURRENT_CONTEXT(ctx);
570
571 switch (pname) {
572 case GL_PROGRAM_OBJECT_ARB:
573 {
574 struct gl2_program_intf **pro = ctx->Shader.CurrentProgram;
575
576 if (pro != NULL)
577 return (**pro)._container._generic.
578 GetName((struct gl2_generic_intf **) (pro));
579 }
580 break;
581 default:
582 _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB");
583 }
584 #endif
585 return 0;
586 }
587
588
589 void
590 _mesa_get_programiv(GLcontext *ctx, GLuint program,
591 GLenum pname, GLint *params)
592 {
593 struct gl_shader_program *shProg
594 = _mesa_lookup_shader_program(ctx, program);
595
596 if (!shProg) {
597 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramiv(program)");
598 return;
599 }
600
601 switch (pname) {
602 case GL_DELETE_STATUS:
603 *params = shProg->DeletePending;
604 break;
605 case GL_LINK_STATUS:
606 *params = shProg->LinkStatus;
607 break;
608 case GL_VALIDATE_STATUS:
609 *params = shProg->Validated;
610 break;
611 case GL_INFO_LOG_LENGTH:
612 *params = shProg->InfoLog ? strlen(shProg->InfoLog) : 0;
613 break;
614 case GL_ATTACHED_SHADERS:
615 *params = shProg->NumShaders;
616 break;
617 case GL_ACTIVE_ATTRIBUTES:
618 *params = shProg->Attributes ? shProg->Attributes->NumParameters : 0;
619 break;
620 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
621 *params = _mesa_parameter_longest_name(shProg->Attributes);
622 break;
623 case GL_ACTIVE_UNIFORMS:
624 *params = shProg->Uniforms ? shProg->Uniforms->NumParameters : 0;
625 break;
626 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
627 *params = _mesa_parameter_longest_name(shProg->Uniforms);
628 break;
629 default:
630 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname)");
631 return;
632 }
633 }
634
635
636 void
637 _mesa_get_shaderiv(GLcontext *ctx, GLuint name, GLenum pname, GLint *params)
638 {
639 struct gl_shader *shader = _mesa_lookup_shader(ctx, name);
640
641 if (!shader) {
642 _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderiv(shader)");
643 return;
644 }
645
646 switch (pname) {
647 case GL_SHADER_TYPE:
648 *params = shader->Type;
649 break;
650 case GL_DELETE_STATUS:
651 *params = shader->DeletePending;
652 break;
653 case GL_COMPILE_STATUS:
654 *params = shader->CompileStatus;
655 break;
656 case GL_INFO_LOG_LENGTH:
657 *params = shader->InfoLog ? strlen(shader->InfoLog) : 0;
658 break;
659 case GL_SHADER_SOURCE_LENGTH:
660 *params = shader->Source ? strlen((char *) shader->Source) : 0;
661 break;
662 default:
663 _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)");
664 return;
665 }
666 }
667
668
669 void
670 _mesa_get_program_info_log(GLcontext *ctx, GLuint program, GLsizei bufSize,
671 GLsizei *length, GLchar *infoLog)
672 {
673 struct gl_shader_program *shProg
674 = _mesa_lookup_shader_program(ctx, program);
675 if (!shProg) {
676 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramInfoLog(program)");
677 return;
678 }
679 copy_string(infoLog, bufSize, length, shProg->InfoLog);
680 }
681
682
683 void
684 _mesa_get_shader_info_log(GLcontext *ctx, GLuint shader, GLsizei bufSize,
685 GLsizei *length, GLchar *infoLog)
686 {
687 struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
688 if (!sh) {
689 _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderInfoLog(shader)");
690 return;
691 }
692 copy_string(infoLog, bufSize, length, sh->InfoLog);
693 }
694
695
696 /**
697 * Called via ctx->Driver.GetShaderSource().
698 */
699 void
700 _mesa_get_shader_source(GLcontext *ctx, GLuint shader, GLsizei maxLength,
701 GLsizei *length, GLchar *sourceOut)
702 {
703 struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
704 if (!sh) {
705 _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderSource(shader)");
706 return;
707 }
708 copy_string(sourceOut, maxLength, length, sh->Source);
709 }
710
711
712 /**
713 * Called via ctx->Driver.GetUniformfv().
714 */
715 void
716 _mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
717 GLfloat *params)
718 {
719 struct gl_shader_program *shProg
720 = _mesa_lookup_shader_program(ctx, program);
721 if (shProg) {
722 GLint i;
723 if (location >= 0 && location < shProg->Uniforms->NumParameters) {
724 for (i = 0; i < shProg->Uniforms->Parameters[location].Size; i++) {
725 params[i] = shProg->Uniforms->ParameterValues[location][i];
726 }
727 }
728 else {
729 _mesa_error(ctx, GL_INVALID_VALUE, "glGetUniformfv(location)");
730 }
731 }
732 else {
733 _mesa_error(ctx, GL_INVALID_VALUE, "glGetUniformfv(program)");
734 }
735 }
736
737
738 /**
739 * Called via ctx->Driver.GetUniformLocation().
740 */
741 GLint
742 _mesa_get_uniform_location(GLcontext *ctx, GLuint program, const GLchar *name)
743 {
744 struct gl_shader_program *shProg
745 = _mesa_lookup_shader_program(ctx, program);
746 if (shProg) {
747 GLuint loc;
748 for (loc = 0; loc < shProg->Uniforms->NumParameters; loc++) {
749 const struct gl_program_parameter *u
750 = shProg->Uniforms->Parameters + loc;
751 /* XXX this is a temporary simplification / short-cut.
752 * We need to handle things like "e.c[0].b" as seen in the
753 * GLSL orange book, page 189.
754 */
755 if ((u->Type == PROGRAM_UNIFORM ||
756 u->Type == PROGRAM_SAMPLER) && !strcmp(u->Name, name)) {
757 return loc;
758 }
759 }
760 }
761 return -1;
762
763 }
764
765
766 GLboolean
767 _mesa_is_program(GLcontext *ctx, GLuint name)
768 {
769 struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, name);
770 return shProg ? GL_TRUE : GL_FALSE;
771 }
772
773
774 GLboolean
775 _mesa_is_shader(GLcontext *ctx, GLuint name)
776 {
777 struct gl_shader *shader = _mesa_lookup_shader(ctx, name);
778 return shader ? GL_TRUE : GL_FALSE;
779 }
780
781
782
783 /**
784 * Called via ctx->Driver.ShaderSource()
785 */
786 void
787 _mesa_shader_source(GLcontext *ctx, GLuint shader, const GLchar *source)
788 {
789 struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
790 if (!sh) {
791 _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSource(shaderObj)");
792 return;
793 }
794
795 /* free old shader source string and install new one */
796 if (sh->Source) {
797 _mesa_free((void *) sh->Source);
798 }
799 sh->Source = source;
800 sh->CompileStatus = GL_FALSE;
801 }
802
803
804 /**
805 * Called via ctx->Driver.CompileShader()
806 */
807 void
808 _mesa_compile_shader(GLcontext *ctx, GLuint shaderObj)
809 {
810 struct gl_shader *sh = _mesa_lookup_shader(ctx, shaderObj);
811
812 if (!sh) {
813 _mesa_error(ctx, GL_INVALID_VALUE, "glCompileShader(shaderObj)");
814 return;
815 }
816
817 sh->CompileStatus = _slang_compile(ctx, sh);
818 }
819
820
821 /**
822 * Called via ctx->Driver.LinkProgram()
823 */
824 void
825 _mesa_link_program(GLcontext *ctx, GLuint program)
826 {
827 struct gl_shader_program *shProg;
828
829 shProg = _mesa_lookup_shader_program(ctx, program);
830 if (!shProg) {
831 _mesa_error(ctx, GL_INVALID_VALUE, "glLinkProgram(program)");
832 return;
833 }
834
835 _slang_link2(ctx, program, shProg);
836 }
837
838
839 /**
840 * Called via ctx->Driver.UseProgram()
841 */
842 void
843 _mesa_use_program(GLcontext *ctx, GLuint program)
844 {
845 /* unbind old */
846 if (ctx->Shader.CurrentProgram) {
847 ctx->Shader.CurrentProgram->RefCount--;
848 if (ctx->Shader.CurrentProgram->RefCount <= 0) {
849 _mesa_free_shader_program(ctx, ctx->Shader.CurrentProgram);
850 }
851 ctx->Shader.CurrentProgram = NULL;
852 }
853
854 if (program) {
855 struct gl_shader_program *shProg;
856 shProg = _mesa_lookup_shader_program(ctx, program);
857 if (!shProg) {
858 _mesa_error(ctx, GL_INVALID_VALUE,
859 "glUseProgramObjectARB(programObj)");
860 return;
861 }
862 ctx->Shader.CurrentProgram = shProg;
863 shProg->RefCount++;
864 }
865 else {
866 /* don't use a shader program */
867 ctx->Shader.CurrentProgram = NULL;
868 }
869 }
870
871
872 /**
873 * Called via ctx->Driver.Uniform().
874 */
875 void
876 _mesa_uniform(GLcontext *ctx, GLint location, GLsizei count,
877 const GLvoid *values, GLenum type)
878 {
879 struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
880 GLfloat *uniformVal;
881
882 if (!shProg || !shProg->LinkStatus) {
883 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(program not linked)");
884 return;
885 }
886
887 if (location < 0 || location >= (GLint) shProg->Uniforms->NumParameters) {
888 _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(location)");
889 return;
890 }
891
892 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
893
894 /*
895 * If we're setting a sampler, we must use glUniformi1()!
896 */
897 if (shProg->Uniforms->Parameters[location].Type == PROGRAM_SAMPLER) {
898 if (type != GL_INT || count != 1) {
899 _mesa_error(ctx, GL_INVALID_OPERATION,
900 "glUniform(only glUniform1i can be used "
901 "to set sampler uniforms)");
902 return;
903 }
904 }
905
906 uniformVal = shProg->Uniforms->ParameterValues[location];
907
908 /* XXX obey 'count' parameter! */
909
910 if (type == GL_INT ||
911 type == GL_INT_VEC2 ||
912 type == GL_INT_VEC3 ||
913 type == GL_INT_VEC4) {
914 const GLint *iValues = (const GLint *) values;
915 switch (type) {
916 case GL_INT_VEC4:
917 uniformVal[3] = (GLfloat) iValues[3];
918 /* fall-through */
919 case GL_INT_VEC3:
920 uniformVal[2] = (GLfloat) iValues[2];
921 /* fall-through */
922 case GL_INT_VEC2:
923 uniformVal[1] = (GLfloat) iValues[1];
924 /* fall-through */
925 case GL_INT:
926 uniformVal[0] = (GLfloat) iValues[0];
927 break;
928 default:
929 _mesa_problem(ctx, "Invalid type in _mesa_uniform");
930 return;
931 }
932 }
933 else {
934 const GLfloat *fValues = (const GLfloat *) values;
935 switch (type) {
936 case GL_FLOAT_VEC4:
937 uniformVal[3] = fValues[3];
938 /* fall-through */
939 case GL_FLOAT_VEC3:
940 uniformVal[2] = fValues[2];
941 /* fall-through */
942 case GL_FLOAT_VEC2:
943 uniformVal[1] = fValues[1];
944 /* fall-through */
945 case GL_FLOAT:
946 uniformVal[0] = fValues[0];
947 break;
948 default:
949 _mesa_problem(ctx, "Invalid type in _mesa_uniform");
950 return;
951 }
952 }
953
954 if (shProg->Uniforms->Parameters[location].Type == PROGRAM_SAMPLER) {
955 _slang_resolve_samplers(shProg, &shProg->VertexProgram->Base);
956 _slang_resolve_samplers(shProg, &shProg->FragmentProgram->Base);
957 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
958 }
959 }
960
961
962 /**
963 * Called by ctx->Driver.UniformMatrix().
964 */
965 void
966 _mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows,
967 GLenum matrixType, GLint location, GLsizei count,
968 GLboolean transpose, const GLfloat *values)
969 {
970 struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
971 if (!shProg || !shProg->LinkStatus) {
972 _mesa_error(ctx, GL_INVALID_OPERATION,
973 "glUniformMatrix(program not linked)");
974 return;
975 }
976 if (location < 0 || location >= shProg->Uniforms->NumParameters) {
977 _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix(location)");
978 return;
979 }
980 if (values == NULL) {
981 _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix");
982 return;
983 }
984
985 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
986
987 /*
988 * Note: the _columns_ of a matrix are stored in program registers, not
989 * the rows.
990 */
991 /* XXXX need to test 3x3 and 2x2 matrices... */
992 if (transpose) {
993 GLuint row, col;
994 for (col = 0; col < cols; col++) {
995 GLfloat *v = shProg->Uniforms->ParameterValues[location + col];
996 for (row = 0; row < rows; row++) {
997 v[row] = values[col * rows + row];
998 }
999 }
1000 }
1001 else {
1002 GLuint row, col;
1003 for (col = 0; col < cols; col++) {
1004 GLfloat *v = shProg->Uniforms->ParameterValues[location + col];
1005 for (row = 0; row < rows; row++) {
1006 v[row] = values[row * cols + col];
1007 }
1008 }
1009 }
1010 }
1011
1012
1013 void
1014 _mesa_validate_program(GLcontext *ctx, GLuint program)
1015 {
1016 struct gl_shader_program *shProg;
1017 shProg = _mesa_lookup_shader_program(ctx, program);
1018 if (!shProg) {
1019 _mesa_error(ctx, GL_INVALID_VALUE, "glValidateProgram(program)");
1020 return;
1021 }
1022 /* XXX temporary */
1023 shProg->Validated = GL_TRUE;
1024
1025 /* From the GL spec:
1026 any two active samplers in the current program object are of
1027 different types, but refer to the same texture image unit,
1028
1029 any active sampler in the current program object refers to a texture
1030 image unit where fixed-function fragment processing accesses a
1031 texture target that does not match the sampler type, or
1032
1033 the sum of the number of active samplers in the program and the
1034 number of texture image units enabled for fixed-function fragment
1035 processing exceeds the combined limit on the total number of texture
1036 image units allowed.
1037 */
1038 }