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