2 * Mesa 3-D graphics library
5 * Copyright (C) 2004-2008 Brian Paul All Rights Reserved.
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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.
32 * These are basically just wrappers/adaptors for calling the
33 * ctx->Driver.foobar() GLSL-related functions.
35 * Things are biased toward the OpenGL 2.0 functions rather than the
36 * ARB extensions (i.e. the ARB functions are layered on the 2.0 functions).
38 * The general idea here is to allow enough modularity such that a
39 * completely different GLSL implemenation can be plugged in and co-exist
40 * with Mesa's native GLSL code.
46 _mesa_AttachObjectARB(GLhandleARB program
, GLhandleARB shader
)
48 GET_CURRENT_CONTEXT(ctx
);
49 ctx
->Driver
.AttachShader(ctx
, program
, shader
);
54 _mesa_AttachShader(GLuint program
, GLuint shader
)
56 GET_CURRENT_CONTEXT(ctx
);
57 ctx
->Driver
.AttachShader(ctx
, program
, shader
);
62 _mesa_BindAttribLocationARB(GLhandleARB program
, GLuint index
,
63 const GLcharARB
*name
)
65 GET_CURRENT_CONTEXT(ctx
);
66 ctx
->Driver
.BindAttribLocation(ctx
, program
, index
, name
);
71 _mesa_CompileShaderARB(GLhandleARB shaderObj
)
73 GET_CURRENT_CONTEXT(ctx
);
74 ctx
->Driver
.CompileShader(ctx
, shaderObj
);
79 _mesa_CreateShader(GLenum type
)
81 GET_CURRENT_CONTEXT(ctx
);
82 return ctx
->Driver
.CreateShader(ctx
, type
);
86 GLhandleARB GLAPIENTRY
87 _mesa_CreateShaderObjectARB(GLenum type
)
89 GET_CURRENT_CONTEXT(ctx
);
90 return ctx
->Driver
.CreateShader(ctx
, type
);
95 _mesa_CreateProgram(void)
97 GET_CURRENT_CONTEXT(ctx
);
98 return ctx
->Driver
.CreateProgram(ctx
);
102 GLhandleARB GLAPIENTRY
103 _mesa_CreateProgramObjectARB(void)
105 GET_CURRENT_CONTEXT(ctx
);
106 return ctx
->Driver
.CreateProgram(ctx
);
111 _mesa_DeleteObjectARB(GLhandleARB obj
)
114 GET_CURRENT_CONTEXT(ctx
);
115 if (ctx
->Driver
.IsProgram(ctx
, obj
)) {
116 ctx
->Driver
.DeleteProgram2(ctx
, obj
);
118 else if (ctx
->Driver
.IsShader(ctx
, obj
)) {
119 ctx
->Driver
.DeleteShader(ctx
, obj
);
129 _mesa_DeleteProgram(GLuint name
)
132 GET_CURRENT_CONTEXT(ctx
);
133 ctx
->Driver
.DeleteProgram2(ctx
, name
);
139 _mesa_DeleteShader(GLuint name
)
142 GET_CURRENT_CONTEXT(ctx
);
143 ctx
->Driver
.DeleteShader(ctx
, name
);
149 _mesa_DetachObjectARB(GLhandleARB program
, GLhandleARB shader
)
151 GET_CURRENT_CONTEXT(ctx
);
152 ctx
->Driver
.DetachShader(ctx
, program
, shader
);
157 _mesa_DetachShader(GLuint program
, GLuint shader
)
159 GET_CURRENT_CONTEXT(ctx
);
160 ctx
->Driver
.DetachShader(ctx
, program
, shader
);
165 _mesa_GetActiveAttribARB(GLhandleARB program
, GLuint index
,
166 GLsizei maxLength
, GLsizei
* length
, GLint
* size
,
167 GLenum
* type
, GLcharARB
* name
)
169 GET_CURRENT_CONTEXT(ctx
);
170 ctx
->Driver
.GetActiveAttrib(ctx
, program
, index
, maxLength
, length
, size
,
176 _mesa_GetActiveUniformARB(GLhandleARB program
, GLuint index
,
177 GLsizei maxLength
, GLsizei
* length
, GLint
* size
,
178 GLenum
* type
, GLcharARB
* name
)
180 GET_CURRENT_CONTEXT(ctx
);
181 ctx
->Driver
.GetActiveUniform(ctx
, program
, index
, maxLength
, length
, size
,
187 _mesa_GetAttachedObjectsARB(GLhandleARB container
, GLsizei maxCount
,
188 GLsizei
* count
, GLhandleARB
* obj
)
190 GET_CURRENT_CONTEXT(ctx
);
191 ctx
->Driver
.GetAttachedShaders(ctx
, container
, maxCount
, count
, obj
);
196 _mesa_GetAttachedShaders(GLuint program
, GLsizei maxCount
,
197 GLsizei
*count
, GLuint
*obj
)
199 GET_CURRENT_CONTEXT(ctx
);
200 ctx
->Driver
.GetAttachedShaders(ctx
, program
, maxCount
, count
, obj
);
205 _mesa_GetAttribLocationARB(GLhandleARB program
, const GLcharARB
* name
)
207 GET_CURRENT_CONTEXT(ctx
);
208 return ctx
->Driver
.GetAttribLocation(ctx
, program
, name
);
213 _mesa_GetInfoLogARB(GLhandleARB object
, GLsizei maxLength
, GLsizei
* length
,
216 GET_CURRENT_CONTEXT(ctx
);
217 /* Implement in terms of GetProgramInfoLog, GetShaderInfoLog */
218 if (ctx
->Driver
.IsProgram(ctx
, object
)) {
219 ctx
->Driver
.GetProgramInfoLog(ctx
, object
, maxLength
, length
, infoLog
);
221 else if (ctx
->Driver
.IsShader(ctx
, object
)) {
222 ctx
->Driver
.GetShaderInfoLog(ctx
, object
, maxLength
, length
, infoLog
);
225 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetInfoLogARB");
231 _mesa_GetObjectParameterivARB(GLhandleARB object
, GLenum pname
, GLint
*params
)
233 GET_CURRENT_CONTEXT(ctx
);
234 /* Implement in terms of GetProgramiv, GetShaderiv */
235 if (ctx
->Driver
.IsProgram(ctx
, object
)) {
236 if (pname
== GL_OBJECT_TYPE_ARB
) {
237 *params
= GL_PROGRAM_OBJECT_ARB
;
240 ctx
->Driver
.GetProgramiv(ctx
, object
, pname
, params
);
243 else if (ctx
->Driver
.IsShader(ctx
, object
)) {
244 if (pname
== GL_OBJECT_TYPE_ARB
) {
245 *params
= GL_SHADER_OBJECT_ARB
;
248 ctx
->Driver
.GetShaderiv(ctx
, object
, pname
, params
);
252 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetObjectParameterivARB");
258 _mesa_GetObjectParameterfvARB(GLhandleARB object
, GLenum pname
,
261 GLint iparams
[1]; /* XXX is one element enough? */
262 _mesa_GetObjectParameterivARB(object
, pname
, iparams
);
263 params
[0] = (GLfloat
) iparams
[0];
268 _mesa_GetProgramiv(GLuint program
, GLenum pname
, GLint
*params
)
270 GET_CURRENT_CONTEXT(ctx
);
271 ctx
->Driver
.GetProgramiv(ctx
, program
, pname
, params
);
276 _mesa_GetShaderiv(GLuint shader
, GLenum pname
, GLint
*params
)
278 GET_CURRENT_CONTEXT(ctx
);
279 ctx
->Driver
.GetShaderiv(ctx
, shader
, pname
, params
);
284 _mesa_GetProgramInfoLog(GLuint program
, GLsizei bufSize
,
285 GLsizei
*length
, GLchar
*infoLog
)
287 GET_CURRENT_CONTEXT(ctx
);
288 ctx
->Driver
.GetProgramInfoLog(ctx
, program
, bufSize
, length
, infoLog
);
293 _mesa_GetShaderInfoLog(GLuint shader
, GLsizei bufSize
,
294 GLsizei
*length
, GLchar
*infoLog
)
296 GET_CURRENT_CONTEXT(ctx
);
297 ctx
->Driver
.GetShaderInfoLog(ctx
, shader
, bufSize
, length
, infoLog
);
302 _mesa_GetShaderSourceARB(GLhandleARB shader
, GLsizei maxLength
,
303 GLsizei
*length
, GLcharARB
*sourceOut
)
305 GET_CURRENT_CONTEXT(ctx
);
306 ctx
->Driver
.GetShaderSource(ctx
, shader
, maxLength
, length
, sourceOut
);
311 _mesa_GetUniformfvARB(GLhandleARB program
, GLint location
, GLfloat
* params
)
313 GET_CURRENT_CONTEXT(ctx
);
314 ctx
->Driver
.GetUniformfv(ctx
, program
, location
, params
);
319 _mesa_GetUniformivARB(GLhandleARB program
, GLint location
, GLint
* params
)
321 GET_CURRENT_CONTEXT(ctx
);
322 ctx
->Driver
.GetUniformiv(ctx
, program
, location
, params
);
329 _mesa_GetUniformLocation(GLuint program
, const GLcharARB
*name
)
331 GET_CURRENT_CONTEXT(ctx
);
332 return ctx
->Driver
.GetUniformLocation(ctx
, program
, name
);
337 GLhandleARB GLAPIENTRY
338 _mesa_GetHandleARB(GLenum pname
)
340 GET_CURRENT_CONTEXT(ctx
);
341 return ctx
->Driver
.GetHandle(ctx
, pname
);
346 _mesa_GetUniformLocationARB(GLhandleARB programObj
, const GLcharARB
*name
)
348 GET_CURRENT_CONTEXT(ctx
);
349 return ctx
->Driver
.GetUniformLocation(ctx
, programObj
, name
);
354 _mesa_IsProgram(GLuint name
)
356 GET_CURRENT_CONTEXT(ctx
);
357 return ctx
->Driver
.IsProgram(ctx
, name
);
362 _mesa_IsShader(GLuint name
)
364 GET_CURRENT_CONTEXT(ctx
);
365 return ctx
->Driver
.IsShader(ctx
, name
);
370 _mesa_LinkProgramARB(GLhandleARB programObj
)
372 GET_CURRENT_CONTEXT(ctx
);
373 ctx
->Driver
.LinkProgram(ctx
, programObj
);
379 * Read shader source code from a file.
380 * Useful for debugging to override an app's shader.
383 _mesa_read_shader(const char *fname
)
385 const int max
= 50*1000;
386 FILE *f
= fopen(fname
, "r");
387 GLcharARB
*buffer
, *shader
;
391 _mesa_fprintf(stderr
, "Unable to open shader file %s\n", fname
);
395 buffer
= (char *) malloc(max
);
396 len
= fread(buffer
, 1, max
, f
);
401 shader
= _mesa_strdup(buffer
);
405 _mesa_fprintf(stderr
, "Read shader %s:\n", fname
);
406 _mesa_fprintf(stderr
, "%s\n", shader
);
415 * Called via glShaderSource() and glShaderSourceARB() API functions.
416 * Basically, concatenate the source code strings into one long string
417 * and pass it to ctx->Driver.ShaderSource().
420 _mesa_ShaderSourceARB(GLhandleARB shaderObj
, GLsizei count
,
421 const GLcharARB
** string
, const GLint
* length
)
423 GET_CURRENT_CONTEXT(ctx
);
425 GLsizei i
, totalLength
;
428 if (!shaderObj
|| string
== NULL
) {
429 _mesa_error(ctx
, GL_INVALID_VALUE
, "glShaderSourceARB");
434 * This array holds offsets of where the appropriate string ends, thus the
435 * last element will be set to the total length of the source code.
437 offsets
= (GLint
*) _mesa_malloc(count
* sizeof(GLint
));
438 if (offsets
== NULL
) {
439 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glShaderSourceARB");
443 for (i
= 0; i
< count
; i
++) {
444 if (string
[i
] == NULL
) {
445 _mesa_free((GLvoid
*) offsets
);
446 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glShaderSourceARB(null string)");
449 if (length
== NULL
|| length
[i
] < 0)
450 offsets
[i
] = _mesa_strlen(string
[i
]);
452 offsets
[i
] = length
[i
];
453 /* accumulate string lengths */
455 offsets
[i
] += offsets
[i
- 1];
458 /* Total length of source string is sum off all strings plus two.
459 * One extra byte for terminating zero, another extra byte to silence
460 * valgrind warnings in the parser/grammer code.
462 totalLength
= offsets
[count
- 1] + 2;
463 source
= (GLcharARB
*) _mesa_malloc(totalLength
* sizeof(GLcharARB
));
464 if (source
== NULL
) {
465 _mesa_free((GLvoid
*) offsets
);
466 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glShaderSourceARB");
470 for (i
= 0; i
< count
; i
++) {
471 GLint start
= (i
> 0) ? offsets
[i
- 1] : 0;
472 _mesa_memcpy(source
+ start
, string
[i
],
473 (offsets
[i
] - start
) * sizeof(GLcharARB
));
475 source
[totalLength
- 1] = '\0';
476 source
[totalLength
- 2] = '\0';
480 GLcharARB
*newSource
;
482 newSource
= _mesa_read_shader("newshader.frag");
489 (void) _mesa_read_shader
;
492 ctx
->Driver
.ShaderSource(ctx
, shaderObj
, source
);
499 _mesa_Uniform1fARB(GLint location
, GLfloat v0
)
501 GET_CURRENT_CONTEXT(ctx
);
502 ctx
->Driver
.Uniform(ctx
, location
, 1, &v0
, GL_FLOAT
);
506 _mesa_Uniform2fARB(GLint location
, GLfloat v0
, GLfloat v1
)
508 GET_CURRENT_CONTEXT(ctx
);
512 ctx
->Driver
.Uniform(ctx
, location
, 1, v
, GL_FLOAT_VEC2
);
516 _mesa_Uniform3fARB(GLint location
, GLfloat v0
, GLfloat v1
, GLfloat v2
)
518 GET_CURRENT_CONTEXT(ctx
);
523 ctx
->Driver
.Uniform(ctx
, location
, 1, v
, GL_FLOAT_VEC3
);
527 _mesa_Uniform4fARB(GLint location
, GLfloat v0
, GLfloat v1
, GLfloat v2
,
530 GET_CURRENT_CONTEXT(ctx
);
536 ctx
->Driver
.Uniform(ctx
, location
, 1, v
, GL_FLOAT_VEC4
);
540 _mesa_Uniform1iARB(GLint location
, GLint v0
)
542 GET_CURRENT_CONTEXT(ctx
);
543 ctx
->Driver
.Uniform(ctx
, location
, 1, &v0
, GL_INT
);
547 _mesa_Uniform2iARB(GLint location
, GLint v0
, GLint v1
)
549 GET_CURRENT_CONTEXT(ctx
);
553 ctx
->Driver
.Uniform(ctx
, location
, 1, v
, GL_INT_VEC2
);
557 _mesa_Uniform3iARB(GLint location
, GLint v0
, GLint v1
, GLint v2
)
559 GET_CURRENT_CONTEXT(ctx
);
564 ctx
->Driver
.Uniform(ctx
, location
, 1, v
, GL_INT_VEC3
);
568 _mesa_Uniform4iARB(GLint location
, GLint v0
, GLint v1
, GLint v2
, GLint v3
)
570 GET_CURRENT_CONTEXT(ctx
);
576 ctx
->Driver
.Uniform(ctx
, location
, 1, v
, GL_INT_VEC4
);
580 _mesa_Uniform1fvARB(GLint location
, GLsizei count
, const GLfloat
* value
)
582 GET_CURRENT_CONTEXT(ctx
);
583 ctx
->Driver
.Uniform(ctx
, location
, count
, value
, GL_FLOAT
);
587 _mesa_Uniform2fvARB(GLint location
, GLsizei count
, const GLfloat
* value
)
589 GET_CURRENT_CONTEXT(ctx
);
590 ctx
->Driver
.Uniform(ctx
, location
, count
, value
, GL_FLOAT_VEC2
);
594 _mesa_Uniform3fvARB(GLint location
, GLsizei count
, const GLfloat
* value
)
596 GET_CURRENT_CONTEXT(ctx
);
597 ctx
->Driver
.Uniform(ctx
, location
, count
, value
, GL_FLOAT_VEC3
);
601 _mesa_Uniform4fvARB(GLint location
, GLsizei count
, const GLfloat
* value
)
603 GET_CURRENT_CONTEXT(ctx
);
604 ctx
->Driver
.Uniform(ctx
, location
, count
, value
, GL_FLOAT_VEC4
);
608 _mesa_Uniform1ivARB(GLint location
, GLsizei count
, const GLint
* value
)
610 GET_CURRENT_CONTEXT(ctx
);
611 ctx
->Driver
.Uniform(ctx
, location
, count
, value
, GL_INT
);
615 _mesa_Uniform2ivARB(GLint location
, GLsizei count
, const GLint
* value
)
617 GET_CURRENT_CONTEXT(ctx
);
618 ctx
->Driver
.Uniform(ctx
, location
, count
, value
, GL_INT_VEC2
);
622 _mesa_Uniform3ivARB(GLint location
, GLsizei count
, const GLint
* value
)
624 GET_CURRENT_CONTEXT(ctx
);
625 ctx
->Driver
.Uniform(ctx
, location
, count
, value
, GL_INT_VEC3
);
629 _mesa_Uniform4ivARB(GLint location
, GLsizei count
, const GLint
* value
)
631 GET_CURRENT_CONTEXT(ctx
);
632 ctx
->Driver
.Uniform(ctx
, location
, count
, value
, GL_INT_VEC4
);
637 _mesa_UniformMatrix2fvARB(GLint location
, GLsizei count
, GLboolean transpose
,
638 const GLfloat
* value
)
640 GET_CURRENT_CONTEXT(ctx
);
641 ctx
->Driver
.UniformMatrix(ctx
, 2, 2, GL_FLOAT_MAT2
,
642 location
, count
, transpose
, value
);
646 _mesa_UniformMatrix3fvARB(GLint location
, GLsizei count
, GLboolean transpose
,
647 const GLfloat
* value
)
649 GET_CURRENT_CONTEXT(ctx
);
650 ctx
->Driver
.UniformMatrix(ctx
, 3, 3, GL_FLOAT_MAT3
,
651 location
, count
, transpose
, value
);
655 _mesa_UniformMatrix4fvARB(GLint location
, GLsizei count
, GLboolean transpose
,
656 const GLfloat
* value
)
658 GET_CURRENT_CONTEXT(ctx
);
659 ctx
->Driver
.UniformMatrix(ctx
, 4, 4, GL_FLOAT_MAT4
,
660 location
, count
, transpose
, value
);
665 * Non-square UniformMatrix are OpenGL 2.1
668 _mesa_UniformMatrix2x3fv(GLint location
, GLsizei count
, GLboolean transpose
,
669 const GLfloat
*value
)
671 GET_CURRENT_CONTEXT(ctx
);
672 ctx
->Driver
.UniformMatrix(ctx
, 2, 3, GL_FLOAT_MAT2x3
,
673 location
, count
, transpose
, value
);
677 _mesa_UniformMatrix3x2fv(GLint location
, GLsizei count
, GLboolean transpose
,
678 const GLfloat
*value
)
680 GET_CURRENT_CONTEXT(ctx
);
681 ctx
->Driver
.UniformMatrix(ctx
, 3, 2, GL_FLOAT_MAT3x2
,
682 location
, count
, transpose
, value
);
686 _mesa_UniformMatrix2x4fv(GLint location
, GLsizei count
, GLboolean transpose
,
687 const GLfloat
*value
)
689 GET_CURRENT_CONTEXT(ctx
);
690 ctx
->Driver
.UniformMatrix(ctx
, 2, 4, GL_FLOAT_MAT2x4
,
691 location
, count
, transpose
, value
);
695 _mesa_UniformMatrix4x2fv(GLint location
, GLsizei count
, GLboolean transpose
,
696 const GLfloat
*value
)
698 GET_CURRENT_CONTEXT(ctx
);
699 ctx
->Driver
.UniformMatrix(ctx
, 4, 2, GL_FLOAT_MAT4x2
,
700 location
, count
, transpose
, value
);
704 _mesa_UniformMatrix3x4fv(GLint location
, GLsizei count
, GLboolean transpose
,
705 const GLfloat
*value
)
707 GET_CURRENT_CONTEXT(ctx
);
708 ctx
->Driver
.UniformMatrix(ctx
, 3, 4, GL_FLOAT_MAT3x4
,
709 location
, count
, transpose
, value
);
713 _mesa_UniformMatrix4x3fv(GLint location
, GLsizei count
, GLboolean transpose
,
714 const GLfloat
*value
)
716 GET_CURRENT_CONTEXT(ctx
);
717 ctx
->Driver
.UniformMatrix(ctx
, 4, 3, GL_FLOAT_MAT4x3
,
718 location
, count
, transpose
, value
);
723 _mesa_UseProgramObjectARB(GLhandleARB program
)
725 GET_CURRENT_CONTEXT(ctx
);
726 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
727 ctx
->Driver
.UseProgram(ctx
, program
);
732 _mesa_ValidateProgramARB(GLhandleARB program
)
734 GET_CURRENT_CONTEXT(ctx
);
735 ctx
->Driver
.ValidateProgram(ctx
, program
);