blob: aaaf942cf5796b0ccc7783856214b11f261c7fb5 [file] [log] [blame]
Brian34ae99d2006-12-18 08:28:54 -07001/*
2 * Mesa 3-D graphics library
3 * Version: 6.5
4 *
5 * Copyright (C) 2004-2006 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 * API functions for shader objects
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 *
35 */
36
37
38#include "glheader.h"
39#include "context.h"
40#include "hash.h"
41#include "macros.h"
42#include "program.h"
43#include "prog_parameter.h"
44#include "shaderobjects.h"
45#include "shader_api.h"
46
47#include "slang_compile.h"
48#include "slang_link.h"
49
50
51
52GLvoid GLAPIENTRY
53_mesa_DeleteObjectARB(GLhandleARB obj)
54{
55#if 000
56 if (obj != 0) {
57 GET_CURRENT_CONTEXT(ctx);
58 GET_GENERIC(gen, obj, "glDeleteObjectARB");
59
60 if (gen != NULL) {
61 (**gen).Delete(gen);
62 RELEASE_GENERIC(gen);
63 }
64 }
65#endif
66}
67
68
69GLhandleARB GLAPIENTRY
70_mesa_GetHandleARB(GLenum pname)
71{
72#if 0
73 GET_CURRENT_CONTEXT(ctx);
74
75 switch (pname) {
76 case GL_PROGRAM_OBJECT_ARB:
77 {
78 struct gl2_program_intf **pro = ctx->ShaderObjects.CurrentProgram;
79
80 if (pro != NULL)
81 return (**pro)._container._generic.
82 GetName((struct gl2_generic_intf **) (pro));
83 }
84 break;
85 default:
86 _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB");
87 }
88#endif
89 return 0;
90}
91
92
93GLvoid GLAPIENTRY
94_mesa_DetachObjectARB(GLhandleARB program, GLhandleARB shader)
95{
96 GET_CURRENT_CONTEXT(ctx);
97 struct gl_linked_program *linked
98 = _mesa_lookup_linked_program(ctx, program);
99 struct gl_program *prog = _mesa_lookup_shader(ctx, shader);
100 const GLuint n = linked->NumShaders;
101 GLuint i, j;
102
103 if (!linked || !prog) {
104 _mesa_error(ctx, GL_INVALID_OPERATION,
105 "glDetachObjectARB(bad program or shader name)");
106 return;
107 }
108
109 for (i = 0; i < n; i++) {
110 if (linked->Shaders[i] == prog) {
111 struct gl_program **newList;
112 /* found it */
113 /* alloc new list */
114 newList = (struct gl_program **)
115 _mesa_malloc((n - 1) * sizeof(struct gl_program *));
116 if (!newList) {
117 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDetachObjectARB");
118 return;
119 }
120 for (j = 0; j < i; j++) {
121 newList[j] = linked->Shaders[j];
122 }
123 while (++i < n)
124 newList[j++] = linked->Shaders[i];
125 _mesa_free(linked->Shaders);
126 linked->Shaders = newList;
127 return;
128 }
129 }
130
131 _mesa_error(ctx, GL_INVALID_OPERATION,
132 "glDetachObjectARB(shader not found)");
133}
134
135
136GLhandleARB GLAPIENTRY
137_mesa_CreateShaderObjectARB(GLenum shaderType)
138{
139 GET_CURRENT_CONTEXT(ctx);
140 struct gl_program *newProg;
141 GLuint name;
142
143 name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
144
145 switch (shaderType) {
146 case GL_FRAGMENT_SHADER_ARB:
147 /* alloc new gl_fragment_program */
148 newProg = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, name);
149 break;
150 case GL_VERTEX_SHADER_ARB:
151 /* alloc new gl_vertex_program */
152 newProg = ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, name);
153 break;
154 default:
155 _mesa_error(ctx, GL_INVALID_ENUM, "CreateShaderObject(shaderType)");
156 return 0;
157 }
158
159 _mesa_HashInsert(ctx->Shared->ShaderObjects, name, newProg);
160
161 return name;
162}
163
164
165
166GLvoid GLAPIENTRY
167_mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count,
168 const GLcharARB ** string, const GLint * length)
169{
170 GET_CURRENT_CONTEXT(ctx);
171 struct gl_program *shader;
172 GLint *offsets;
173 GLsizei i;
174 GLcharARB *source;
175
176 if (string == NULL) {
177 _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB");
178 return;
179 }
180
181 shader = _mesa_lookup_shader(ctx, shaderObj);
182 if (!shader) {
183 _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB(shaderObj)");
184 return;
185 }
186
187 /*
188 * This array holds offsets of where the appropriate string ends, thus the
189 * last element will be set to the total length of the source code.
190 */
191 offsets = (GLint *) _mesa_malloc(count * sizeof(GLint));
192 if (offsets == NULL) {
193 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
194 return;
195 }
196
197 for (i = 0; i < count; i++) {
198 if (string[i] == NULL) {
199 _mesa_free((GLvoid *) offsets);
200 _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB(null string)");
201 return;
202 }
203 if (length == NULL || length[i] < 0)
204 offsets[i] = _mesa_strlen(string[i]);
205 else
206 offsets[i] = length[i];
207 /* accumulate string lengths */
208 if (i > 0)
209 offsets[i] += offsets[i - 1];
210 }
211
212 source = (GLcharARB *) _mesa_malloc((offsets[count - 1] + 1) *
213 sizeof(GLcharARB));
214 if (source == NULL) {
215 _mesa_free((GLvoid *) offsets);
216 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
217 return;
218 }
219
220 for (i = 0; i < count; i++) {
221 GLint start = (i > 0) ? offsets[i - 1] : 0;
222 _mesa_memcpy(source + start, string[i],
223 (offsets[i] - start) * sizeof(GLcharARB));
224 }
225 source[offsets[count - 1]] = '\0';
226
227 /* free old shader source string and install new one */
228 if (shader->String) {
229 _mesa_free(shader->String);
230 }
231 shader->String = (GLubyte *) source;
232}
233
234
235GLvoid GLAPIENTRY
236_mesa_CompileShaderARB(GLhandleARB shaderObj)
237{
238 GET_CURRENT_CONTEXT(ctx);
239 struct gl_program *prog = _mesa_lookup_shader(ctx, shaderObj);
240 slang_info_log info_log;
241 slang_code_object obj;
242 slang_unit_type type;
243
244 if (!prog) {
245 _mesa_error(ctx, GL_INVALID_VALUE, "glCompileShader(shaderObj)");
246 return;
247 }
248
249 slang_info_log_construct(&info_log);
250 _slang_code_object_ctr(&obj);
251
252 if (prog->Target == GL_VERTEX_PROGRAM_ARB) {
253 type = slang_unit_vertex_shader;
254 }
255 else {
256 assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB);
257 type = slang_unit_fragment_shader;
258 }
259
260 if (_slang_compile((const char*) prog->String, &obj,
261 type, &info_log, prog)) {
262 /*
263 prog->CompileStatus = GL_TRUE;
264 */
265 }
266 else {
267 /*
268 prog->CompileStatus = GL_FALSE;
269 */
270 _mesa_problem(ctx, "Program did not compile!");
271 }
272}
273
274
275GLhandleARB GLAPIENTRY
276_mesa_CreateProgramObjectARB(GLvoid)
277{
278 GET_CURRENT_CONTEXT(ctx);
279 GLuint name;
280 struct gl_linked_program *linked;
281
282 name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ProgramObjects, 1);
283 linked = _mesa_new_linked_program(ctx, name);
284
285 _mesa_HashInsert(ctx->Shared->ProgramObjects, name, linked);
286
287 return name;
288}
289
290
291GLvoid GLAPIENTRY
292_mesa_AttachObjectARB(GLhandleARB program, GLhandleARB shader)
293{
294 GET_CURRENT_CONTEXT(ctx);
295 struct gl_linked_program *linked
296 = _mesa_lookup_linked_program(ctx, program);
297 struct gl_program *prog = _mesa_lookup_shader(ctx, shader);
298 const GLuint n = linked->NumShaders;
299 GLuint i;
300
301 if (!linked || !prog) {
302 _mesa_error(ctx, GL_INVALID_OPERATION,
303 "glAttachShader(bad program or shader name)");
304 return;
305 }
306
307 for (i = 0; i < n; i++) {
308 if (linked->Shaders[i] == prog) {
309 /* already attached */
310 return;
311 }
312 }
313
314 /* grow list */
315 linked->Shaders = (struct gl_program **)
316 _mesa_realloc(linked->Shaders,
317 n * sizeof(struct gl_program *),
318 (n + 1) * sizeof(struct gl_program *));
319 /* append */
320 linked->Shaders[n] = prog;
321 prog->RefCount++;
322 linked->NumShaders++;
323}
324
325
326
327
328GLvoid GLAPIENTRY
329_mesa_LinkProgramARB(GLhandleARB programObj)
330{
331 GET_CURRENT_CONTEXT(ctx);
332 struct gl_linked_program *linked;
333
334 linked = _mesa_lookup_linked_program(ctx, programObj);
335 if (!linked) {
336 _mesa_error(ctx, GL_INVALID_OPERATION, "glLinkProgram(programObj)");
337 return;
338 }
339 _slang_link2(ctx, programObj, linked);
340}
341
342
343
344GLvoid GLAPIENTRY
345_mesa_UseProgramObjectARB(GLhandleARB programObj)
346{
347 GET_CURRENT_CONTEXT(ctx);
348 struct gl_linked_program *linked;
349
350 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
351
352 linked = _mesa_lookup_linked_program(ctx, programObj);
353 if (!linked) {
354 _mesa_error(ctx, GL_INVALID_OPERATION,
355 "glUseProgramObjectARB(programObj)");
356 return;
357 }
358
359 ctx->ShaderObjects.Linked = linked;
360}
361
362
363GLvoid GLAPIENTRY
364_mesa_ValidateProgramARB(GLhandleARB programObj)
365{
366#if 0
367 GET_CURRENT_CONTEXT(ctx);
368 GET_PROGRAM(pro, programObj, "glValidateProgramARB");
369
370 if (pro != NULL) {
371 (**pro).Validate(pro);
372 RELEASE_PROGRAM(pro);
373 }
374#endif
375}
376
377
378/**
379 * Helper function for all the _mesa_Uniform*() functions below.
380 */
381static INLINE void
382uniform(GLint location, GLsizei count, const GLvoid *values, GLenum type,
383 const char *caller)
384{
385 GET_CURRENT_CONTEXT(ctx);
386
387 if (ctx->ShaderObjects.Linked) {
388 struct gl_linked_program *linked = ctx->ShaderObjects.Linked;
389 if (location >= 0 && location < linked->Uniforms->NumParameters) {
390 GLfloat *v = linked->Uniforms->ParameterValues[location];
391 const GLfloat *fValues = (const GLfloat *) values; /* XXX */
392 GLint i;
393 if (type == GL_FLOAT_VEC4)
394 count *= 4;
395 else if (type == GL_FLOAT_VEC3)
396 count *= 3;
397 else
398 abort();
399
400 for (i = 0; i < count; i++)
401 v[i] = fValues[i];
402 return;
403 }
404 }
405}
406
407
408GLvoid GLAPIENTRY
409_mesa_Uniform1fARB(GLint location, GLfloat v0)
410{
411 uniform(location, 1, &v0, GL_FLOAT, "glUniform1fARB");
412}
413
414GLvoid GLAPIENTRY
415_mesa_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1)
416{
417 GLfloat v[2];
418 v[0] = v0;
419 v[1] = v1;
420 uniform(location, 1, v, GL_FLOAT_VEC2, "glUniform2fARB");
421}
422
423GLvoid GLAPIENTRY
424_mesa_Uniform3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
425{
426 GLfloat v[3];
427 v[0] = v0;
428 v[1] = v1;
429 v[2] = v2;
430 uniform(location, 1, v, GL_FLOAT_VEC3, "glUniform3fARB");
431}
432
433GLvoid GLAPIENTRY
434_mesa_Uniform4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2,
435 GLfloat v3)
436{
437 GLfloat v[4];
438 v[0] = v0;
439 v[1] = v1;
440 v[2] = v2;
441 v[3] = v3;
442 uniform(location, 1, v, GL_FLOAT_VEC4, "glUniform4fARB");
443}
444
445GLvoid GLAPIENTRY
446_mesa_Uniform1iARB(GLint location, GLint v0)
447{
448 uniform(location, 1, &v0, GL_INT, "glUniform1iARB");
449}
450
451GLvoid GLAPIENTRY
452_mesa_Uniform2iARB(GLint location, GLint v0, GLint v1)
453{
454 GLint v[2];
455 v[0] = v0;
456 v[1] = v1;
457 uniform(location, 1, v, GL_INT_VEC2, "glUniform2iARB");
458}
459
460GLvoid GLAPIENTRY
461_mesa_Uniform3iARB(GLint location, GLint v0, GLint v1, GLint v2)
462{
463 GLint v[3];
464 v[0] = v0;
465 v[1] = v1;
466 v[2] = v2;
467 uniform(location, 1, v, GL_INT_VEC3, "glUniform3iARB");
468}
469
470GLvoid GLAPIENTRY
471_mesa_Uniform4iARB(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
472{
473 GLint v[4];
474 v[0] = v0;
475 v[1] = v1;
476 v[2] = v2;
477 v[3] = v3;
478 uniform(location, 1, v, GL_INT_VEC4, "glUniform4iARB");
479}
480
481GLvoid GLAPIENTRY
482_mesa_Uniform1fvARB(GLint location, GLsizei count, const GLfloat * value)
483{
484 uniform(location, count, value, GL_FLOAT, "glUniform1fvARB");
485}
486
487GLvoid GLAPIENTRY
488_mesa_Uniform2fvARB(GLint location, GLsizei count, const GLfloat * value)
489{
490 uniform(location, count, value, GL_FLOAT_VEC2, "glUniform2fvARB");
491}
492
493GLvoid GLAPIENTRY
494_mesa_Uniform3fvARB(GLint location, GLsizei count, const GLfloat * value)
495{
496 uniform(location, count, value, GL_FLOAT_VEC3, "glUniform3fvARB");
497}
498
499GLvoid GLAPIENTRY
500_mesa_Uniform4fvARB(GLint location, GLsizei count, const GLfloat * value)
501{
502 uniform(location, count, value, GL_FLOAT_VEC4, "glUniform4fvARB");
503}
504
505GLvoid GLAPIENTRY
506_mesa_Uniform1ivARB(GLint location, GLsizei count, const GLint * value)
507{
508 uniform(location, count, value, GL_INT, "glUniform1ivARB");
509}
510
511GLvoid GLAPIENTRY
512_mesa_Uniform2ivARB(GLint location, GLsizei count, const GLint * value)
513{
514 uniform(location, count, value, GL_INT_VEC2, "glUniform2ivARB");
515}
516
517GLvoid GLAPIENTRY
518_mesa_Uniform3ivARB(GLint location, GLsizei count, const GLint * value)
519{
520 uniform(location, count, value, GL_INT_VEC3, "glUniform3ivARB");
521}
522
523GLvoid GLAPIENTRY
524_mesa_Uniform4ivARB(GLint location, GLsizei count, const GLint * value)
525{
526 uniform(location, count, value, GL_INT_VEC4, "glUniform4ivARB");
527}
528
529
530/**
531 * Helper function used by UniformMatrix**vARB() functions below.
532 */
533static void
534uniform_matrix(GLint cols, GLint rows, const char *caller,
535 GLenum matrixType,
536 GLint location, GLsizei count, GLboolean transpose,
537 const GLfloat *values)
538{
539 const GLint matElements = rows * cols;
540 GET_CURRENT_CONTEXT(ctx);
541
542#ifdef OLD
543 GET_CURRENT_LINKED_PROGRAM(pro, caller);
544#endif
545
546 if (values == NULL) {
547 _mesa_error(ctx, GL_INVALID_VALUE, caller);
548 return;
549 }
550
551 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
552
553 if (transpose) {
554 GLfloat *trans, *pt;
555 const GLfloat *pv;
556 GLint i, j, k;
557
558 trans = (GLfloat *) _mesa_malloc(count * matElements * sizeof(GLfloat));
559 if (!trans) {
560 _mesa_error(ctx, GL_OUT_OF_MEMORY, caller);
561 return;
562 }
563
564 pt = trans;
565 pv = values;
566 for (i = 0; i < count; i++) {
567 /* transpose from pv matrix into pt matrix */
568 for (j = 0; j < cols; j++) {
569 for (k = 0; k < rows; k++) {
570 /* XXX verify this */
571 pt[j * rows + k] = pv[k * cols + j];
572 }
573 }
574 pt += matElements;
575 pv += matElements;
576 }
577
578#ifdef OLD
579 if (!(**pro).WriteUniform(pro, location, count, trans, matrixType))
580 _mesa_error(ctx, GL_INVALID_OPERATION, caller);
581#endif
582 _mesa_free(trans);
583 }
584 else {
585#ifdef OLD
586 if (!(**pro).WriteUniform(pro, location, count, values, matrixType))
587 _mesa_error(ctx, GL_INVALID_OPERATION, caller);
588#endif
589 }
590}
591
592
593GLvoid GLAPIENTRY
594_mesa_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose,
595 const GLfloat * value)
596{
597 uniform_matrix(2, 2, "glUniformMatrix2fvARB", GL_FLOAT_MAT2,
598 location, count, transpose, value);
599}
600
601GLvoid GLAPIENTRY
602_mesa_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose,
603 const GLfloat * value)
604{
605 uniform_matrix(3, 3, "glUniformMatrix3fvARB", GL_FLOAT_MAT3,
606 location, count, transpose, value);
607}
608
609GLvoid GLAPIENTRY
610_mesa_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose,
611 const GLfloat * value)
612{
613 uniform_matrix(4, 4, "glUniformMatrix4fvARB", GL_FLOAT_MAT4,
614 location, count, transpose, value);
615}
616
617static GLboolean
618_mesa_get_object_parameter(GLhandleARB obj, GLenum pname, GLvoid * params,
619 GLboolean * integral, GLint * size)
620{
621#if 000
622 GET_CURRENT_CONTEXT(ctx);
623 GLint *ipar = (GLint *) params;
624
625 /* set default values */
626 *integral = GL_TRUE; /* indicates param type, TRUE: GLint, FALSE: GLfloat */
627 *size = 1; /* param array size */
628
629 switch (pname) {
630 case GL_OBJECT_TYPE_ARB:
631 case GL_OBJECT_DELETE_STATUS_ARB:
632 case GL_OBJECT_INFO_LOG_LENGTH_ARB:
633 {
634 GET_GENERIC(gen, obj, "glGetObjectParameterivARB");
635
636 if (gen == NULL)
637 return GL_FALSE;
638
639 switch (pname) {
640 case GL_OBJECT_TYPE_ARB:
641 *ipar = (**gen).GetType(gen);
642 break;
643 case GL_OBJECT_DELETE_STATUS_ARB:
644 *ipar = (**gen).GetDeleteStatus(gen);
645 break;
646 case GL_OBJECT_INFO_LOG_LENGTH_ARB:
647 *ipar = (**gen).GetInfoLogLength(gen);
648 break;
649 }
650
651 RELEASE_GENERIC(gen);
652 }
653 break;
654 case GL_OBJECT_SUBTYPE_ARB:
655 case GL_OBJECT_COMPILE_STATUS_ARB:
656 case GL_OBJECT_SHADER_SOURCE_LENGTH_ARB:
657 {
658 GET_SHADER(sha, obj, "glGetObjectParameterivARB");
659
660 if (sha == NULL)
661 return GL_FALSE;
662
663 switch (pname) {
664 case GL_OBJECT_SUBTYPE_ARB:
665 *ipar = (**sha).GetSubType(sha);
666 break;
667 case GL_OBJECT_COMPILE_STATUS_ARB:
668 *ipar = (**sha).GetCompileStatus(sha);
669 break;
670 case GL_OBJECT_SHADER_SOURCE_LENGTH_ARB:
671 {
672 const GLcharARB *src = (**sha).GetSource(sha);
673 if (src == NULL)
674 *ipar = 0;
675 else
676 *ipar = _mesa_strlen(src) + 1;
677 }
678 break;
679 }
680
681 RELEASE_SHADER(sha);
682 }
683 break;
684 case GL_OBJECT_LINK_STATUS_ARB:
685 case GL_OBJECT_VALIDATE_STATUS_ARB:
686 case GL_OBJECT_ATTACHED_OBJECTS_ARB:
687 case GL_OBJECT_ACTIVE_UNIFORMS_ARB:
688 case GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB:
689 {
690 GET_PROGRAM(pro, obj, "glGetObjectParameterivARB");
691
692 if (pro == NULL)
693 return GL_FALSE;
694
695 switch (pname) {
696 case GL_OBJECT_LINK_STATUS_ARB:
697 *ipar = (**pro).GetLinkStatus(pro);
698 break;
699 case GL_OBJECT_VALIDATE_STATUS_ARB:
700 *ipar = (**pro).GetValidateStatus(pro);
701 break;
702 case GL_OBJECT_ATTACHED_OBJECTS_ARB:
703 *ipar =
704 (**pro)._container.
705 GetAttachedCount((struct gl2_container_intf **) (pro));
706 break;
707 case GL_OBJECT_ACTIVE_UNIFORMS_ARB:
708 *ipar = (**pro).GetActiveUniformCount(pro);
709 break;
710 case GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB:
711 *ipar = (**pro).GetActiveUniformMaxLength(pro);
712 break;
713 case GL_OBJECT_ACTIVE_ATTRIBUTES_ARB:
714 *ipar = (**pro).GetActiveAttribCount(pro);
715 break;
716 case GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB:
717 *ipar = (**pro).GetActiveAttribMaxLength(pro);
718 break;
719 }
720
721 RELEASE_PROGRAM(pro);
722 }
723 break;
724 default:
725 _mesa_error(ctx, GL_INVALID_ENUM, "glGetObjectParameterivARB");
726 return GL_FALSE;
727 }
728#endif
729 return GL_TRUE;
730}
731
732GLvoid GLAPIENTRY
733_mesa_GetObjectParameterfvARB(GLhandleARB obj, GLenum pname, GLfloat * params)
734{
735 GET_CURRENT_CONTEXT(ctx);
736 GLboolean integral;
737 GLint size;
738
739 if (params == NULL) {
740 _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectParameterfvARB");
741 return;
742 }
743
744 assert(sizeof(GLfloat) == sizeof(GLint));
745
746 if (_mesa_get_object_parameter(obj, pname, (GLvoid *) params,
747 &integral, &size)) {
748 if (integral) {
749 GLint i;
750 for (i = 0; i < size; i++)
751 params[i] = (GLfloat) ((GLint *) params)[i];
752 }
753 }
754}
755
756GLvoid GLAPIENTRY
757_mesa_GetObjectParameterivARB(GLhandleARB obj, GLenum pname, GLint * params)
758{
759 GET_CURRENT_CONTEXT(ctx);
760 GLboolean integral;
761 GLint size;
762
763 if (params == NULL) {
764 _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectParameterivARB");
765 return;
766 }
767
768 assert(sizeof(GLfloat) == sizeof(GLint));
769
770 if (_mesa_get_object_parameter(obj, pname, (GLvoid *) params,
771 &integral, &size)) {
772 if (!integral) {
773 GLint i;
774 for (i = 0; i < size; i++)
775 params[i] = (GLint) ((GLfloat *) params)[i];
776 }
777 }
778}
779
780
781/**
782 * Copy string from <src> to <dst>, up to maxLength characters, returning
783 * length of <dst> in <length>.
784 * \param src the strings source
785 * \param maxLength max chars to copy
786 * \param length returns numberof chars copied
787 * \param dst the string destination
788 */
789static GLvoid
790copy_string(const GLcharARB * src, GLsizei maxLength, GLsizei * length,
791 GLcharARB * dst)
792{
793 GLsizei len;
794 for (len = 0; len < maxLength - 1 && src && src[len]; len++)
795 dst[len] = src[len];
796 if (maxLength > 0)
797 dst[len] = 0;
798 if (length)
799 *length = len;
800}
801
802
803GLvoid GLAPIENTRY
804_mesa_GetInfoLogARB(GLhandleARB obj, GLsizei maxLength, GLsizei * length,
805 GLcharARB * infoLog)
806{
807#if 0
808 GET_CURRENT_CONTEXT(ctx);
809 GET_GENERIC(gen, obj, "glGetInfoLogARB");
810
811 if (gen == NULL)
812 return;
813
814 if (infoLog == NULL)
815 _mesa_error(ctx, GL_INVALID_VALUE, "glGetInfoLogARB");
816 else {
817 GLsizei actualsize = (**gen).GetInfoLogLength(gen);
818 if (actualsize > maxLength)
819 actualsize = maxLength;
820 (**gen).GetInfoLog(gen, actualsize, infoLog);
821 if (length != NULL)
822 *length = (actualsize > 0) ? actualsize - 1 : 0;
823 }
824 RELEASE_GENERIC(gen);
825#endif
826}
827
828
829GLvoid GLAPIENTRY
830_mesa_GetAttachedObjectsARB(GLhandleARB containerObj, GLsizei maxCount,
831 GLsizei * count, GLhandleARB * obj)
832{
833#if 0
834 GET_CURRENT_CONTEXT(ctx);
835 GET_CONTAINER(con, containerObj, "glGetAttachedObjectsARB");
836
837 if (con == NULL)
838 return;
839
840 if (obj == NULL)
841 _mesa_error(ctx, GL_INVALID_VALUE, "glGetAttachedObjectsARB");
842 else {
843 GLsizei cnt, i;
844
845 cnt = (**con).GetAttachedCount(con);
846 if (cnt > maxCount)
847 cnt = maxCount;
848 if (count != NULL)
849 *count = cnt;
850
851 for (i = 0; i < cnt; i++) {
852 struct gl2_generic_intf **x = (**con).GetAttached(con, i);
853 obj[i] = (**x).GetName(x);
854 RELEASE_GENERIC(x);
855 }
856 }
857 RELEASE_CONTAINER(con);
858#endif
859}
860
861GLint GLAPIENTRY
862_mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB * name)
863{
864 GET_CURRENT_CONTEXT(ctx);
865
866 if (ctx->ShaderObjects.Linked) {
867 const struct gl_linked_program *linked = ctx->ShaderObjects.Linked;
868 GLuint loc;
869 for (loc = 0; loc < linked->Uniforms->NumParameters; loc++) {
870 const struct gl_program_parameter *u
871 = linked->Uniforms->Parameters + loc;
872 if (u->Type == PROGRAM_UNIFORM && !strcmp(u->Name, name)) {
873 return loc;
874 }
875 }
876 }
877 return -1;
878
879}
880
881
882GLvoid GLAPIENTRY
883_mesa_GetActiveUniformARB(GLhandleARB programObj, GLuint index,
884 GLsizei maxLength, GLsizei * length, GLint * size,
885 GLenum * type, GLcharARB * name)
886{
887#if 0
888 GET_CURRENT_CONTEXT(ctx);
889 GET_PROGRAM(pro, programObj, "glGetActiveUniformARB");
890
891 if (pro == NULL)
892 return;
893
894 if (size == NULL || type == NULL || name == NULL)
895 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformARB");
896 else {
897 if (index < (**pro).GetActiveUniformCount(pro))
898 (**pro).GetActiveUniform(pro, index, maxLength, length, size, type,
899 name);
900 else
901 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformARB");
902 }
903 RELEASE_PROGRAM(pro);
904#endif
905}
906
907
908GLvoid GLAPIENTRY
909_mesa_GetUniformfvARB(GLhandleARB programObj, GLint location, GLfloat * params)
910{
911#if 0
912 GET_CURRENT_CONTEXT(ctx);
913 GET_LINKED_PROGRAM(pro, programObj, "glGetUniformfvARB");
914
915 if (!pro)
916 return;
917
918 if (!(**pro).ReadUniform(pro, location, 1, params, GL_FLOAT))
919 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfvARB");
920
921 RELEASE_PROGRAM(pro);
922#endif
923}
924
925
926GLvoid GLAPIENTRY
927_mesa_GetUniformivARB(GLhandleARB programObj, GLint location, GLint * params)
928{
929#if 0
930 GET_CURRENT_CONTEXT(ctx);
931 GET_LINKED_PROGRAM(pro, programObj, "glGetUniformivARB");
932
933 if (!pro)
934 return;
935
936 if (!(**pro).ReadUniform(pro, location, 1, params, GL_INT))
937 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformivARB");
938 RELEASE_PROGRAM(pro);
939#endif
940}
941
942GLvoid GLAPIENTRY
943_mesa_GetShaderSourceARB(GLhandleARB obj, GLsizei maxLength, GLsizei * length,
944 GLcharARB * sourceOut)
945{
946 GET_CURRENT_CONTEXT(ctx);
947 struct gl_program *shader = _mesa_lookup_shader(ctx, obj);
948
949 if (!shader) {
950 _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderSourceARB(obj)");
951 return;
952 }
953
954 copy_string((GLcharARB *) shader->String, maxLength, length, sourceOut);
955}
956
957
958/* GL_ARB_vertex_shader */
959
960GLvoid GLAPIENTRY
961_mesa_BindAttribLocationARB(GLhandleARB programObj, GLuint index,
962 const GLcharARB * name)
963{
964#if 0
965 GET_CURRENT_CONTEXT(ctx);
966 GET_PROGRAM(pro, programObj, "glBindAttribLocationARB");
967
968 if (pro == NULL)
969 return;
970
971 if (name == NULL || index >= MAX_VERTEX_ATTRIBS)
972 _mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocationARB");
973 else if (IS_NAME_WITH_GL_PREFIX(name))
974 _mesa_error(ctx, GL_INVALID_OPERATION, "glBindAttribLocationARB");
975 else
976 (**pro).OverrideAttribBinding(pro, index, name);
977 RELEASE_PROGRAM(pro);
978#endif
979}
980
981
982GLvoid GLAPIENTRY
983_mesa_GetActiveAttribARB(GLhandleARB programObj, GLuint index,
984 GLsizei maxLength, GLsizei * length, GLint * size,
985 GLenum * type, GLcharARB * name)
986{
987#if 0
988 GET_CURRENT_CONTEXT(ctx);
989 GET_PROGRAM(pro, programObj, "glGetActiveAttribARB");
990
991 if (pro == NULL)
992 return;
993
994 if (name == NULL || index >= (**pro).GetActiveAttribCount(pro))
995 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttribARB");
996 else
997 (**pro).GetActiveAttrib(pro, index, maxLength, length, size, type,
998 name);
999 RELEASE_PROGRAM(pro);
1000#endif
1001}
1002
1003
1004GLint GLAPIENTRY
1005_mesa_GetAttribLocationARB(GLhandleARB programObj, const GLcharARB * name)
1006{
1007#if 0
1008 GET_CURRENT_CONTEXT(ctx);
1009 GLint loc = -1;
1010 GET_LINKED_PROGRAM(pro, programObj, "glGetAttribLocationARB");
1011
1012 if (!pro)
1013 return -1;
1014
1015 if (name == NULL)
1016 _mesa_error(ctx, GL_INVALID_VALUE, "glGetAttribLocationARB");
1017 else if (!IS_NAME_WITH_GL_PREFIX(name))
1018 loc = (**pro).GetAttribLocation(pro, name);
1019 RELEASE_PROGRAM(pro);
1020 return loc;
1021#endif
1022 return 0;
1023}
1024
1025
1026/**
1027 ** OpenGL 2.0 functions which basically wrap the ARB_shader functions
1028 **/
1029
1030void GLAPIENTRY
1031_mesa_AttachShader(GLuint program, GLuint shader)
1032{
1033 _mesa_AttachObjectARB(program, shader);
1034}
1035
1036
1037GLuint GLAPIENTRY
1038_mesa_CreateShader(GLenum type)
1039{
1040 return (GLuint) _mesa_CreateShaderObjectARB(type);
1041}
1042
1043GLuint GLAPIENTRY
1044_mesa_CreateProgram(void)
1045{
1046 return (GLuint) _mesa_CreateProgramObjectARB();
1047}
1048
1049
1050void GLAPIENTRY
1051_mesa_DeleteProgram(GLuint name)
1052{
1053 GET_CURRENT_CONTEXT(ctx);
1054 struct gl_linked_program *linked;
1055
1056 linked = _mesa_lookup_linked_program(ctx, name);
1057 if (!linked) {
1058 _mesa_error(ctx, GL_INVALID_OPERATION, "glDeleteProgram(name)");
1059 return;
1060 }
1061
1062 _mesa_HashRemove(ctx->Shared->ProgramObjects, name);
1063 _mesa_delete_linked_program(ctx, linked);
1064}
1065
1066
1067void GLAPIENTRY
1068_mesa_DeleteShader(GLuint shader)
1069{
1070 _mesa_DeleteObjectARB(shader);
1071}
1072
1073void GLAPIENTRY
1074_mesa_DetachShader(GLuint program, GLuint shader)
1075{
1076 _mesa_DetachObjectARB(program, shader);
1077}
1078
1079void GLAPIENTRY
1080_mesa_GetAttachedShaders(GLuint program, GLsizei maxCount,
1081 GLsizei *count, GLuint *obj)
1082{
1083 {
1084 GET_CURRENT_CONTEXT(ctx);
1085 struct gl_linked_program *linked
1086 = _mesa_lookup_linked_program(ctx, program);
1087 if (linked) {
1088 GLuint i;
1089 for (i = 0; i < maxCount && i < linked->NumShaders; i++) {
1090 obj[i] = linked->Shaders[i]->Id;
1091 }
1092 if (count)
1093 *count = i;
1094 }
1095 else {
1096 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetAttachedShaders");
1097 }
1098 }
1099}
1100
1101
1102void GLAPIENTRY
1103_mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params)
1104{
1105#if 0
1106 GET_CURRENT_CONTEXT(ctx);
1107 GET_PROGRAM(pro, program, "glGetProgramiv");
1108
1109 if (!pro)
1110 return;
1111
1112 switch (pname) {
1113 case GL_DELETE_STATUS:
1114 *params = (**pro)._container._generic.GetDeleteStatus((struct gl2_generic_intf **) pro);
1115 break;
1116 case GL_LINK_STATUS:
1117 *params = (**pro).GetLinkStatus(pro);
1118 break;
1119 case GL_VALIDATE_STATUS:
1120 *params = (**pro).GetValidateStatus(pro);
1121 break;
1122 case GL_INFO_LOG_LENGTH:
1123 *params = (**pro)._container._generic.GetInfoLogLength( (struct gl2_generic_intf **) pro );
1124 break;
1125 case GL_ATTACHED_SHADERS:
1126 *params = (**pro)._container.GetAttachedCount( (struct gl2_container_intf **) pro );
1127 break;
1128 case GL_ACTIVE_ATTRIBUTES:
1129 *params = (**pro).GetActiveAttribCount(pro);
1130 break;
1131 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
1132 *params = (**pro).GetActiveAttribMaxLength(pro);
1133 break;
1134 case GL_ACTIVE_UNIFORMS:
1135 *params = (**pro).GetActiveUniformCount(pro);
1136 break;
1137 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
1138 *params = (**pro).GetActiveUniformMaxLength(pro);
1139 break;
1140 default:
1141 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname)");
1142 return;
1143 }
1144#endif
1145}
1146
1147
1148void GLAPIENTRY
1149_mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize,
1150 GLsizei *length, GLchar *infoLog)
1151{
1152 _mesa_GetInfoLogARB(program, bufSize, length, infoLog);
1153}
1154
1155
1156void GLAPIENTRY
1157_mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params)
1158{
1159#if 0
1160 GET_CURRENT_CONTEXT(ctx);
1161 GET_SHADER(sh, shader, "glGetShaderiv");
1162
1163 if (!sh)
1164 return;
1165
1166 switch (pname) {
1167 case GL_SHADER_TYPE:
1168 *params = (**sh).GetSubType(sh);
1169 break;
1170 case GL_DELETE_STATUS:
1171 *params = (**sh)._generic.GetDeleteStatus((struct gl2_generic_intf **) sh);
1172 break;
1173 case GL_COMPILE_STATUS:
1174 *params = (**sh).GetCompileStatus(sh);
1175 break;
1176 case GL_INFO_LOG_LENGTH:
1177 *params = (**sh)._generic.GetInfoLogLength((struct gl2_generic_intf **)sh);
1178 break;
1179 case GL_SHADER_SOURCE_LENGTH:
1180 {
1181 const GLchar *src = (**sh).GetSource(sh);
1182 *params = src ? (_mesa_strlen(src) + 1) : 0;
1183 }
1184 break;
1185 default:
1186 _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)");
1187 return;
1188 }
1189#endif
1190}
1191
1192
1193void GLAPIENTRY
1194_mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize,
1195 GLsizei *length, GLchar *infoLog)
1196{
1197 _mesa_GetInfoLogARB(shader, bufSize, length, infoLog);
1198}
1199
1200
1201GLboolean GLAPIENTRY
1202_mesa_IsProgram(GLuint name)
1203{
1204 GET_CURRENT_CONTEXT(ctx);
1205 struct gl_linked_program *linked = _mesa_lookup_linked_program(ctx, name);
1206 if (linked)
1207 return GL_TRUE;
1208 else
1209 return GL_FALSE;
1210}
1211
1212
1213GLboolean GLAPIENTRY
1214_mesa_IsShader(GLuint name)
1215{
1216 GET_CURRENT_CONTEXT(ctx);
1217 struct gl_program *shader = _mesa_lookup_shader(ctx, name);
1218 if (shader)
1219 return GL_TRUE;
1220 else
1221 return GL_FALSE;
1222}
1223
1224
1225/**
1226 ** 2.1 functions
1227 **/
1228
1229void GLAPIENTRY
1230_mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
1231 const GLfloat *value)
1232{
1233 uniform_matrix(2, 3, "glUniformMatrix2x3fv", GL_FLOAT_MAT2x3,
1234 location, count, transpose, value);
1235}
1236
1237void GLAPIENTRY
1238_mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
1239 const GLfloat *value)
1240{
1241 uniform_matrix(3, 2, "glUniformMatrix3x2fv", GL_FLOAT_MAT3x2,
1242 location, count, transpose, value);
1243}
1244
1245void GLAPIENTRY
1246_mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
1247 const GLfloat *value)
1248{
1249 uniform_matrix(2, 4, "glUniformMatrix2x4fv", GL_FLOAT_MAT2x4,
1250 location, count, transpose, value);
1251}
1252
1253void GLAPIENTRY
1254_mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
1255 const GLfloat *value)
1256{
1257 uniform_matrix(4, 2, "glUniformMatrix4x2fv", GL_FLOAT_MAT4x2,
1258 location, count, transpose, value);
1259}
1260
1261void GLAPIENTRY
1262_mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
1263 const GLfloat *value)
1264{
1265 uniform_matrix(3, 4, "glUniformMatrix3x4fv", GL_FLOAT_MAT3x4,
1266 location, count, transpose, value);
1267}
1268
1269void GLAPIENTRY
1270_mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
1271 const GLfloat *value)
1272{
1273 uniform_matrix(4, 3, "glUniformMatrix4x3fv", GL_FLOAT_MAT4x3,
1274 location, count, transpose, value);
1275}
1276
1277
1278/**
1279 * Create a new GLSL program object.
1280 */
1281struct gl_linked_program *
1282_mesa_new_linked_program(GLcontext *ctx, GLuint name)
1283{
1284 struct gl_linked_program *linked;
1285 linked = CALLOC_STRUCT(gl_linked_program);
1286 if (linked) {
1287 linked->Name = name;
1288 }
1289 return linked;
1290}
1291
1292
1293void
1294_mesa_free_linked_program_data(GLcontext *ctx,
1295 struct gl_linked_program *linked)
1296{
1297 if (linked->VertexProgram) {
1298 if (linked->VertexProgram->Base.Parameters == linked->Uniforms) {
1299 /* to prevent a double-free in the next call */
1300 linked->VertexProgram->Base.Parameters = NULL;
1301 }
1302 _mesa_delete_program(ctx, &linked->VertexProgram->Base);
1303 linked->VertexProgram = NULL;
1304 }
1305
1306 if (linked->FragmentProgram) {
1307 if (linked->FragmentProgram->Base.Parameters == linked->Uniforms) {
1308 /* to prevent a double-free in the next call */
1309 linked->FragmentProgram->Base.Parameters = NULL;
1310 }
1311 _mesa_delete_program(ctx, &linked->FragmentProgram->Base);
1312 linked->FragmentProgram = NULL;
1313 }
1314
1315
1316 if (linked->Uniforms) {
1317 _mesa_free_parameter_list(linked->Uniforms);
1318 linked->Uniforms = NULL;
1319 }
1320
1321 if (linked->Varying) {
1322 _mesa_free_parameter_list(linked->Varying);
1323 linked->Varying = NULL;
1324 }
1325}
1326
1327
1328
1329void
1330_mesa_delete_linked_program(GLcontext *ctx, struct gl_linked_program *linked)
1331{
1332 _mesa_free_linked_program_data(ctx, linked);
1333 _mesa_free(linked);
1334}
1335
1336
1337/**
1338 * Lookup a GLSL program object.
1339 */
1340struct gl_linked_program *
1341_mesa_lookup_linked_program(GLcontext *ctx, GLuint name)
1342{
1343 if (name)
1344 return (struct gl_linked_program *)
1345 _mesa_HashLookup(ctx->Shared->ProgramObjects, name);
1346 else
1347 return NULL;
1348}
1349
1350
1351struct gl_shader *
1352_mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type)
1353{
1354 struct gl_shader *shader;
1355 assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER);
1356 shader = CALLOC_STRUCT(gl_shader);
1357 if (shader) {
1358 shader->Name = name;
1359 shader->Type = type;
1360 }
1361 return shader;
1362}
1363
1364
1365/**
1366 * Lookup a GLSL shader object.
1367 */
1368struct gl_program *
1369_mesa_lookup_shader(GLcontext *ctx, GLuint name)
1370{
1371 if (name)
1372 return (struct gl_program *)
1373 _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
1374 else
1375 return NULL;
1376}
1377
1378
1379GLvoid
1380_mesa_init_shaderobjects(GLcontext * ctx)
1381{
1382
1383 ctx->ShaderObjects.CurrentProgram = NULL;
1384 ctx->ShaderObjects._FragmentShaderPresent = GL_FALSE;
1385 ctx->ShaderObjects._VertexShaderPresent = GL_FALSE;
1386
1387#if 0
1388 _mesa_init_shaderobjects_3dlabs(ctx);
1389#endif
1390}