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