blob: c7a1cec48e24d8bc49ac85d8187a17698485a909 [file] [log] [blame]
Michal Krol1d7f7192005-03-25 12:12:50 +00001/*
2 * Mesa 3-D graphics library
Michal Krol07135702006-03-21 10:37:40 +00003 * Version: 6.5
Michal Krol1d7f7192005-03-25 12:12:50 +00004 *
Michal Krol07135702006-03-21 10:37:40 +00005 * Copyright (C) 2004-2006 Brian Paul All Rights Reserved.
Michal Krol1d7f7192005-03-25 12:12:50 +00006 *
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 shaderobjects.c
27 * ARB_shader_objects state management functions
28 * \author Michal Krol
29 */
30
Michal Krolc1fe4692004-10-27 17:09:10 +000031
32#include "glheader.h"
Michal Krol9ac96052006-02-27 14:41:41 +000033#include "context.h"
34#include "hash.h"
Michal Krol1d7f7192005-03-25 12:12:50 +000035#include "shaderobjects.h"
Michal Krol6324f732005-01-13 14:12:50 +000036#include "shaderobjects_3dlabs.h"
Michal Krol1d7f7192005-03-25 12:12:50 +000037
38
Michal Krol365582d2006-08-01 20:07:31 +000039#if FEATURE_ARB_shader_objects
40
Michal Krol9ac96052006-02-27 14:41:41 +000041#define RELEASE_GENERIC(x)\
Michal Krola1a02e62006-05-16 09:40:30 +000042 (**x)._unknown.Release ((struct gl2_unknown_intf **) (x))
Michal Krol9ac96052006-02-27 14:41:41 +000043
44#define RELEASE_CONTAINER(x)\
Michal Krola1a02e62006-05-16 09:40:30 +000045 (**x)._generic._unknown.Release ((struct gl2_unknown_intf **) (x))
Michal Krol9ac96052006-02-27 14:41:41 +000046
47#define RELEASE_PROGRAM(x)\
Michal Krola1a02e62006-05-16 09:40:30 +000048 (**x)._container._generic._unknown.Release ((struct gl2_unknown_intf **) (x))
Michal Krol9ac96052006-02-27 14:41:41 +000049
50#define RELEASE_SHADER(x)\
Michal Krola1a02e62006-05-16 09:40:30 +000051 (**x)._generic._unknown.Release ((struct gl2_unknown_intf **) (x))
Michal Krol9ac96052006-02-27 14:41:41 +000052
Brian Paulbdb251b2006-11-03 17:29:31 +000053
54
Michal Krola1a02e62006-05-16 09:40:30 +000055static struct gl2_unknown_intf **
Brian Paule71e4c92006-11-02 16:09:10 +000056lookup_handle(GLcontext * ctx, GLhandleARB handle, enum gl2_uiid uiid,
57 const char *function)
Michal Krola1a02e62006-05-16 09:40:30 +000058{
59 struct gl2_unknown_intf **unk;
Michal Krol9ac96052006-02-27 14:41:41 +000060
Michal Krola1a02e62006-05-16 09:40:30 +000061 /*
Brian Paulbdb251b2006-11-03 17:29:31 +000062 * Note: _mesa_HashLookup() requires non-zero input values, so the
63 * passed-in handle value must be checked beforehand.
Michal Krola1a02e62006-05-16 09:40:30 +000064 */
65 if (handle == 0) {
Brian Paule71e4c92006-11-02 16:09:10 +000066 _mesa_error(ctx, GL_INVALID_VALUE, function);
Michal Krola1a02e62006-05-16 09:40:30 +000067 return NULL;
68 }
Brian Paule71e4c92006-11-02 16:09:10 +000069 _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
Brian Paul3bef6002006-11-03 22:15:43 +000070 unk = (struct gl2_unknown_intf **) _mesa_HashLookup(ctx->Shared->GL2Objects,
71 handle);
Brian Paule71e4c92006-11-02 16:09:10 +000072 _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
Brian Paulbdb251b2006-11-03 17:29:31 +000073
74 if (unk == NULL) {
Brian Paule71e4c92006-11-02 16:09:10 +000075 _mesa_error(ctx, GL_INVALID_VALUE, function);
Brian Paulbdb251b2006-11-03 17:29:31 +000076 }
Michal Krola1a02e62006-05-16 09:40:30 +000077 else {
Brian Paule71e4c92006-11-02 16:09:10 +000078 unk = (**unk).QueryInterface(unk, uiid);
Michal Krola1a02e62006-05-16 09:40:30 +000079 if (unk == NULL)
Brian Paule71e4c92006-11-02 16:09:10 +000080 _mesa_error(ctx, GL_INVALID_OPERATION, function);
Michal Krola1a02e62006-05-16 09:40:30 +000081 }
82 return unk;
83}
Michal Krol9ac96052006-02-27 14:41:41 +000084
85#define GET_GENERIC(x, handle, function)\
Michal Krola1a02e62006-05-16 09:40:30 +000086 struct gl2_generic_intf **x = (struct gl2_generic_intf **)\
87 lookup_handle (ctx, handle, UIID_GENERIC, function);
Michal Krol9ac96052006-02-27 14:41:41 +000088
89#define GET_CONTAINER(x, handle, function)\
Michal Krola1a02e62006-05-16 09:40:30 +000090 struct gl2_container_intf **x = (struct gl2_container_intf **)\
91 lookup_handle (ctx, handle, UIID_CONTAINER, function);
Michal Krol9ac96052006-02-27 14:41:41 +000092
93#define GET_PROGRAM(x, handle, function)\
Michal Krola1a02e62006-05-16 09:40:30 +000094 struct gl2_program_intf **x = (struct gl2_program_intf **)\
95 lookup_handle (ctx, handle, UIID_PROGRAM, function);
Michal Krol9ac96052006-02-27 14:41:41 +000096
97#define GET_SHADER(x, handle, function)\
Michal Krola1a02e62006-05-16 09:40:30 +000098 struct gl2_shader_intf **x = (struct gl2_shader_intf **)\
99 lookup_handle (ctx, handle, UIID_SHADER, function);
Michal Krol9ac96052006-02-27 14:41:41 +0000100
Brian Paul7e6701c2006-11-03 21:51:58 +0000101
102#define GET_LINKED_PROGRAM(x, handle, function) \
103 GET_PROGRAM(x, handle, function); \
104 if (x && (**x).GetLinkStatus(x) == GL_FALSE) { \
105 RELEASE_PROGRAM(x); \
106 _mesa_error(ctx, GL_INVALID_OPERATION, function); \
107 x = NULL; \
Michal Krola1a02e62006-05-16 09:40:30 +0000108 }
Michal Krol9ac96052006-02-27 14:41:41 +0000109
Brian Paul7e6701c2006-11-03 21:51:58 +0000110#define GET_CURRENT_LINKED_PROGRAM(x, function) \
111 struct gl2_program_intf **x = ctx->ShaderObjects.CurrentProgram; \
112 if (!x || (**x).GetLinkStatus(x) == GL_FALSE) { \
113 _mesa_error(ctx, GL_INVALID_OPERATION, function); \
114 return; \
Michal Krola1a02e62006-05-16 09:40:30 +0000115 }
Michal Krol9ac96052006-02-27 14:41:41 +0000116
Brian Paul7e6701c2006-11-03 21:51:58 +0000117
118
Michal Krold55de652006-04-18 10:30:29 +0000119#define IS_NAME_WITH_GL_PREFIX(x) ((x)[0] == 'g' && (x)[1] == 'l' && (x)[2] == '_')
120
Michal Krol9ac96052006-02-27 14:41:41 +0000121
122GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000123_mesa_DeleteObjectARB(GLhandleARB obj)
Michal Krol1d7f7192005-03-25 12:12:50 +0000124{
Brian Paule71e4c92006-11-02 16:09:10 +0000125 if (obj != 0) {
Michal Krola1a02e62006-05-16 09:40:30 +0000126 GET_CURRENT_CONTEXT(ctx);
127 GET_GENERIC(gen, obj, "glDeleteObjectARB");
Michal Krol1d7f7192005-03-25 12:12:50 +0000128
Brian Paule71e4c92006-11-02 16:09:10 +0000129 if (gen != NULL) {
130 (**gen).Delete(gen);
Michal Krola1a02e62006-05-16 09:40:30 +0000131 RELEASE_GENERIC(gen);
132 }
133 }
Michal Krolc1fe4692004-10-27 17:09:10 +0000134}
135
136GLhandleARB GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000137_mesa_GetHandleARB(GLenum pname)
Michal Krol1d7f7192005-03-25 12:12:50 +0000138{
Brian Paule71e4c92006-11-02 16:09:10 +0000139 GET_CURRENT_CONTEXT(ctx);
Michal Krol1d7f7192005-03-25 12:12:50 +0000140
Brian Paule71e4c92006-11-02 16:09:10 +0000141 switch (pname) {
Michal Krola1a02e62006-05-16 09:40:30 +0000142 case GL_PROGRAM_OBJECT_ARB:
143 {
144 struct gl2_program_intf **pro = ctx->ShaderObjects.CurrentProgram;
Michal Krol9ac96052006-02-27 14:41:41 +0000145
Michal Krola1a02e62006-05-16 09:40:30 +0000146 if (pro != NULL)
Brian Paule71e4c92006-11-02 16:09:10 +0000147 return (**pro)._container._generic.
148 GetName((struct gl2_generic_intf **) (pro));
Michal Krola1a02e62006-05-16 09:40:30 +0000149 }
150 break;
Brian Paule71e4c92006-11-02 16:09:10 +0000151 default:
152 _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB");
153 }
Michal Krol6324f732005-01-13 14:12:50 +0000154
Brian Paule71e4c92006-11-02 16:09:10 +0000155 return 0;
Michal Krolc1fe4692004-10-27 17:09:10 +0000156}
157
Michal Krol9ac96052006-02-27 14:41:41 +0000158GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000159_mesa_DetachObjectARB(GLhandleARB containerObj, GLhandleARB attachedObj)
Michal Krol1d7f7192005-03-25 12:12:50 +0000160{
Brian Paule71e4c92006-11-02 16:09:10 +0000161 GET_CURRENT_CONTEXT(ctx);
162 GET_CONTAINER(con, containerObj, "glDetachObjectARB");
Michal Krol1d7f7192005-03-25 12:12:50 +0000163
Brian Paule71e4c92006-11-02 16:09:10 +0000164 if (con != NULL) {
165 GET_GENERIC(att, attachedObj, "glDetachObjectARB");
Michal Krol1d7f7192005-03-25 12:12:50 +0000166
Brian Paule71e4c92006-11-02 16:09:10 +0000167 if (att != NULL) {
168 (**con).Detach(con, att);
169 RELEASE_GENERIC(att);
170 }
171 RELEASE_CONTAINER(con);
172 }
Michal Krolc1fe4692004-10-27 17:09:10 +0000173}
174
175GLhandleARB GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000176_mesa_CreateShaderObjectARB(GLenum shaderType)
Michal Krol1d7f7192005-03-25 12:12:50 +0000177{
Brian Paule71e4c92006-11-02 16:09:10 +0000178 return _mesa_3dlabs_create_shader_object(shaderType);
Michal Krolc1fe4692004-10-27 17:09:10 +0000179}
180
Michal Krol9ac96052006-02-27 14:41:41 +0000181GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000182_mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count,
183 const GLcharARB ** string, const GLint * length)
Michal Krol1d7f7192005-03-25 12:12:50 +0000184{
Brian Paule71e4c92006-11-02 16:09:10 +0000185 GET_CURRENT_CONTEXT(ctx);
186 GLint *offsets;
187 GLsizei i;
188 GLcharARB *source;
189 GET_SHADER(sha, shaderObj, "glShaderSourceARB");
Michal Krol1d7f7192005-03-25 12:12:50 +0000190
Brian Paule71e4c92006-11-02 16:09:10 +0000191 if (sha == NULL)
192 return;
Brian Paul93269622006-04-14 03:43:39 +0000193
Brian Paule71e4c92006-11-02 16:09:10 +0000194 if (string == NULL) {
195 RELEASE_SHADER(sha);
196 _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB");
197 return;
198 }
Michal Krol1d7f7192005-03-25 12:12:50 +0000199
Brian Paule71e4c92006-11-02 16:09:10 +0000200 /*
201 * This array holds offsets of where the appropriate string ends, thus the last
202 * element will be set to the total length of the source code.
203 */
204 offsets = (GLint *) _mesa_malloc(count * sizeof(GLint));
205 if (offsets == NULL) {
206 RELEASE_SHADER(sha);
207 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
208 return;
209 }
Michal Krol1d7f7192005-03-25 12:12:50 +0000210
Brian Paule71e4c92006-11-02 16:09:10 +0000211 for (i = 0; i < count; i++) {
212 if (string[i] == NULL) {
213 _mesa_free((GLvoid *) offsets);
214 RELEASE_SHADER(sha);
215 _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB");
216 return;
217 }
218 if (length == NULL || length[i] < 0)
219 offsets[i] = _mesa_strlen(string[i]);
220 else
221 offsets[i] = length[i];
222 /* accumulate string lengths */
223 if (i > 0)
224 offsets[i] += offsets[i - 1];
225 }
Michal Krol1d7f7192005-03-25 12:12:50 +0000226
Brian Paule71e4c92006-11-02 16:09:10 +0000227 source =
228 (GLcharARB *) _mesa_malloc((offsets[count - 1] + 1) *
229 sizeof(GLcharARB));
230 if (source == NULL) {
231 _mesa_free((GLvoid *) offsets);
232 RELEASE_SHADER(sha);
233 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
234 return;
235 }
Michal Krol1d7f7192005-03-25 12:12:50 +0000236
Brian Paule71e4c92006-11-02 16:09:10 +0000237 for (i = 0; i < count; i++) {
238 GLint start = (i > 0) ? offsets[i - 1] : 0;
239 _mesa_memcpy(source + start, string[i],
240 (offsets[i] - start) * sizeof(GLcharARB));
241 }
242 source[offsets[count - 1]] = '\0';
Michal Krol1d7f7192005-03-25 12:12:50 +0000243
Brian Paule71e4c92006-11-02 16:09:10 +0000244 (**sha).SetSource(sha, source, offsets, count);
245 RELEASE_SHADER(sha);
Michal Krolc1fe4692004-10-27 17:09:10 +0000246}
247
Brian Paule71e4c92006-11-02 16:09:10 +0000248GLvoid GLAPIENTRY
249_mesa_CompileShaderARB(GLhandleARB shaderObj)
Michal Krol1d7f7192005-03-25 12:12:50 +0000250{
Brian Paule71e4c92006-11-02 16:09:10 +0000251 GET_CURRENT_CONTEXT(ctx);
252 GET_SHADER(sha, shaderObj, "glCompileShaderARB");
Michal Krol1d7f7192005-03-25 12:12:50 +0000253
Brian Paule71e4c92006-11-02 16:09:10 +0000254 if (sha != NULL) {
255 (**sha).Compile(sha);
256 RELEASE_SHADER(sha);
257 }
Michal Krolc1fe4692004-10-27 17:09:10 +0000258}
259
260GLhandleARB GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000261_mesa_CreateProgramObjectARB(GLvoid)
Michal Krolc1fe4692004-10-27 17:09:10 +0000262{
Brian Paule71e4c92006-11-02 16:09:10 +0000263 return _mesa_3dlabs_create_program_object();
Michal Krolc1fe4692004-10-27 17:09:10 +0000264}
265
Michal Krol9ac96052006-02-27 14:41:41 +0000266GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000267_mesa_AttachObjectARB(GLhandleARB containerObj, GLhandleARB obj)
Michal Krol1d7f7192005-03-25 12:12:50 +0000268{
Brian Paule71e4c92006-11-02 16:09:10 +0000269 GET_CURRENT_CONTEXT(ctx);
270 GET_CONTAINER(con, containerObj, "glAttachObjectARB");
Michal Krol1d7f7192005-03-25 12:12:50 +0000271
Brian Paule71e4c92006-11-02 16:09:10 +0000272 if (con != NULL) {
273 GET_GENERIC(att, obj, "glAttachObjectARB");
Michal Krol1d7f7192005-03-25 12:12:50 +0000274
Brian Paule71e4c92006-11-02 16:09:10 +0000275 if (att != NULL) {
276 (**con).Attach(con, att);
277 RELEASE_GENERIC(att);
278 }
279 RELEASE_CONTAINER(con);
280 }
Michal Krolc1fe4692004-10-27 17:09:10 +0000281}
282
Michal Krol9ac96052006-02-27 14:41:41 +0000283GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000284_mesa_LinkProgramARB(GLhandleARB programObj)
Michal Krol1d7f7192005-03-25 12:12:50 +0000285{
Brian Paule71e4c92006-11-02 16:09:10 +0000286 GET_CURRENT_CONTEXT(ctx);
287 GET_PROGRAM(pro, programObj, "glLinkProgramARB");
Michal Krol1d7f7192005-03-25 12:12:50 +0000288
Brian Paule71e4c92006-11-02 16:09:10 +0000289 if (pro != NULL) {
290 (**pro).Link(pro);
291 if (pro == ctx->ShaderObjects.CurrentProgram) {
292 if ((**pro).GetLinkStatus(pro))
293 _mesa_UseProgramObjectARB(programObj);
294 else
295 _mesa_UseProgramObjectARB(0);
296 }
297 RELEASE_PROGRAM(pro);
298 }
Michal Krolc1fe4692004-10-27 17:09:10 +0000299}
300
Michal Krol9ac96052006-02-27 14:41:41 +0000301GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000302_mesa_UseProgramObjectARB(GLhandleARB programObj)
Michal Krol1d7f7192005-03-25 12:12:50 +0000303{
Brian Paule71e4c92006-11-02 16:09:10 +0000304 GET_CURRENT_CONTEXT(ctx);
Michal Krola1a02e62006-05-16 09:40:30 +0000305 struct gl2_program_intf **program = NULL;
Michal Krol9ac96052006-02-27 14:41:41 +0000306
Brian Paule71e4c92006-11-02 16:09:10 +0000307 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
Michal Krol1d7f7192005-03-25 12:12:50 +0000308
Brian Paule71e4c92006-11-02 16:09:10 +0000309 if (programObj != 0) {
310 GET_PROGRAM(pro, programObj, "glUseProgramObjectARB");
Michal Krol1d7f7192005-03-25 12:12:50 +0000311
Brian Paule71e4c92006-11-02 16:09:10 +0000312 if (pro == NULL)
313 return;
Michal Krol1d7f7192005-03-25 12:12:50 +0000314
Brian Paule71e4c92006-11-02 16:09:10 +0000315 if ((**pro).GetLinkStatus(pro) == GL_FALSE) {
316 RELEASE_PROGRAM(pro);
317 _mesa_error(ctx, GL_INVALID_OPERATION, "glUseProgramObjectARB");
318 return;
319 }
Michal Krol9ac96052006-02-27 14:41:41 +0000320
Brian Paule71e4c92006-11-02 16:09:10 +0000321 program = pro;
Brian Paul93269622006-04-14 03:43:39 +0000322
Brian Paule71e4c92006-11-02 16:09:10 +0000323 ctx->ShaderObjects._VertexShaderPresent =
324 (**pro).IsShaderPresent(pro, GL_VERTEX_SHADER_ARB);
325 ctx->ShaderObjects._FragmentShaderPresent =
326 (**pro).IsShaderPresent(pro, GL_FRAGMENT_SHADER_ARB);
327 }
328 else {
329 ctx->ShaderObjects._VertexShaderPresent = GL_FALSE;
330 ctx->ShaderObjects._FragmentShaderPresent = GL_FALSE;
331 }
Michal Krol1d7f7192005-03-25 12:12:50 +0000332
Brian Paule71e4c92006-11-02 16:09:10 +0000333 if (ctx->ShaderObjects.CurrentProgram != NULL)
334 RELEASE_PROGRAM(ctx->ShaderObjects.CurrentProgram);
335 ctx->ShaderObjects.CurrentProgram = program;
Michal Krolc1fe4692004-10-27 17:09:10 +0000336}
337
Michal Krol9ac96052006-02-27 14:41:41 +0000338GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000339_mesa_ValidateProgramARB(GLhandleARB programObj)
Michal Krol1d7f7192005-03-25 12:12:50 +0000340{
Brian Paule71e4c92006-11-02 16:09:10 +0000341 GET_CURRENT_CONTEXT(ctx);
342 GET_PROGRAM(pro, programObj, "glValidateProgramARB");
Michal Krol1d7f7192005-03-25 12:12:50 +0000343
Brian Paule71e4c92006-11-02 16:09:10 +0000344 if (pro != NULL) {
345 (**pro).Validate(pro);
346 RELEASE_PROGRAM(pro);
347 }
Michal Krol1d7f7192005-03-25 12:12:50 +0000348}
349
Brian Paul2659ee92006-11-03 21:30:16 +0000350
351/**
352 * Helper function for all the _mesa_Uniform*() functions below.
353 */
354static INLINE void
355uniform(GLint location, GLsizei count, const GLvoid *values, GLenum type,
356 const char *caller)
Michal Krol9ac96052006-02-27 14:41:41 +0000357{
Brian Paule71e4c92006-11-02 16:09:10 +0000358 GET_CURRENT_CONTEXT(ctx);
Brian Paul2659ee92006-11-03 21:30:16 +0000359 GET_CURRENT_LINKED_PROGRAM(pro, caller);
Brian Paul93269622006-04-14 03:43:39 +0000360
Brian Paule71e4c92006-11-02 16:09:10 +0000361 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
Michal Krol9ac96052006-02-27 14:41:41 +0000362
Brian Paul2659ee92006-11-03 21:30:16 +0000363 if (!(**pro).WriteUniform(pro, location, count, values, type))
364 _mesa_error(ctx, GL_INVALID_OPERATION, caller);
365}
366
367
368GLvoid GLAPIENTRY
369_mesa_Uniform1fARB(GLint location, GLfloat v0)
370{
371 uniform(location, 1, &v0, GL_FLOAT, "glUniform1fARB");
Michal Krolc1fe4692004-10-27 17:09:10 +0000372}
373
Michal Krol9ac96052006-02-27 14:41:41 +0000374GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000375_mesa_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1)
Michal Krol1d7f7192005-03-25 12:12:50 +0000376{
Brian Paul2659ee92006-11-03 21:30:16 +0000377 GLfloat v[2];
378 v[0] = v0;
379 v[1] = v1;
380 uniform(location, 1, v, GL_FLOAT_VEC2, "glUniform2fARB");
Michal Krolc1fe4692004-10-27 17:09:10 +0000381}
382
Michal Krol9ac96052006-02-27 14:41:41 +0000383GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000384_mesa_Uniform3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
Michal Krol1d7f7192005-03-25 12:12:50 +0000385{
Brian Paul2659ee92006-11-03 21:30:16 +0000386 GLfloat v[3];
387 v[0] = v0;
388 v[1] = v1;
389 v[2] = v2;
390 uniform(location, 1, v, GL_FLOAT_VEC3, "glUniform3fARB");
Michal Krolc1fe4692004-10-27 17:09:10 +0000391}
392
Michal Krol9ac96052006-02-27 14:41:41 +0000393GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000394_mesa_Uniform4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2,
395 GLfloat v3)
Michal Krol1d7f7192005-03-25 12:12:50 +0000396{
Brian Paul2659ee92006-11-03 21:30:16 +0000397 GLfloat v[4];
398 v[0] = v0;
399 v[1] = v1;
400 v[2] = v2;
401 v[3] = v3;
402 uniform(location, 1, v, GL_FLOAT_VEC4, "glUniform4fARB");
Michal Krolc1fe4692004-10-27 17:09:10 +0000403}
404
Michal Krol9ac96052006-02-27 14:41:41 +0000405GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000406_mesa_Uniform1iARB(GLint location, GLint v0)
Michal Krol1d7f7192005-03-25 12:12:50 +0000407{
Brian Paul2659ee92006-11-03 21:30:16 +0000408 uniform(location, 1, &v0, GL_INT, "glUniform1iARB");
Michal Krolc1fe4692004-10-27 17:09:10 +0000409}
410
Michal Krol9ac96052006-02-27 14:41:41 +0000411GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000412_mesa_Uniform2iARB(GLint location, GLint v0, GLint v1)
Michal Krol1d7f7192005-03-25 12:12:50 +0000413{
Brian Paul2659ee92006-11-03 21:30:16 +0000414 GLint v[2];
415 v[0] = v0;
416 v[1] = v1;
417 uniform(location, 1, v, GL_INT_VEC2, "glUniform2iARB");
Michal Krolc1fe4692004-10-27 17:09:10 +0000418}
419
Michal Krol9ac96052006-02-27 14:41:41 +0000420GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000421_mesa_Uniform3iARB(GLint location, GLint v0, GLint v1, GLint v2)
Michal Krol1d7f7192005-03-25 12:12:50 +0000422{
Brian Paul2659ee92006-11-03 21:30:16 +0000423 GLint v[3];
424 v[0] = v0;
425 v[1] = v1;
426 v[2] = v2;
427 uniform(location, 1, v, GL_INT_VEC3, "glUniform3iARB");
Michal Krolc1fe4692004-10-27 17:09:10 +0000428}
429
Michal Krol9ac96052006-02-27 14:41:41 +0000430GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000431_mesa_Uniform4iARB(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
Michal Krol1d7f7192005-03-25 12:12:50 +0000432{
Brian Paul2659ee92006-11-03 21:30:16 +0000433 GLint v[4];
434 v[0] = v0;
435 v[1] = v1;
436 v[2] = v2;
437 v[3] = v3;
438 uniform(location, 1, v, GL_INT_VEC4, "glUniform4iARB");
Michal Krolc1fe4692004-10-27 17:09:10 +0000439}
440
Michal Krol9ac96052006-02-27 14:41:41 +0000441GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000442_mesa_Uniform1fvARB(GLint location, GLsizei count, const GLfloat * value)
Michal Krol1d7f7192005-03-25 12:12:50 +0000443{
Brian Paul2659ee92006-11-03 21:30:16 +0000444 uniform(location, count, value, GL_FLOAT, "glUniform1fvARB");
Michal Krolc1fe4692004-10-27 17:09:10 +0000445}
446
Michal Krol9ac96052006-02-27 14:41:41 +0000447GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000448_mesa_Uniform2fvARB(GLint location, GLsizei count, const GLfloat * value)
Michal Krol1d7f7192005-03-25 12:12:50 +0000449{
Brian Paul2659ee92006-11-03 21:30:16 +0000450 uniform(location, count, value, GL_FLOAT_VEC2, "glUniform2fvARB");
Michal Krolc1fe4692004-10-27 17:09:10 +0000451}
452
Michal Krol9ac96052006-02-27 14:41:41 +0000453GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000454_mesa_Uniform3fvARB(GLint location, GLsizei count, const GLfloat * value)
Michal Krol1d7f7192005-03-25 12:12:50 +0000455{
Brian Paul2659ee92006-11-03 21:30:16 +0000456 uniform(location, count, value, GL_FLOAT_VEC3, "glUniform3fvARB");
Michal Krolc1fe4692004-10-27 17:09:10 +0000457}
458
Michal Krol9ac96052006-02-27 14:41:41 +0000459GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000460_mesa_Uniform4fvARB(GLint location, GLsizei count, const GLfloat * value)
Michal Krol1d7f7192005-03-25 12:12:50 +0000461{
Brian Paul2659ee92006-11-03 21:30:16 +0000462 uniform(location, count, value, GL_FLOAT_VEC4, "glUniform4fvARB");
Michal Krolc1fe4692004-10-27 17:09:10 +0000463}
464
Michal Krol9ac96052006-02-27 14:41:41 +0000465GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000466_mesa_Uniform1ivARB(GLint location, GLsizei count, const GLint * value)
Michal Krol1d7f7192005-03-25 12:12:50 +0000467{
Brian Paul2659ee92006-11-03 21:30:16 +0000468 uniform(location, count, value, GL_INT, "glUniform1ivARB");
Michal Krolc1fe4692004-10-27 17:09:10 +0000469}
470
Michal Krol9ac96052006-02-27 14:41:41 +0000471GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000472_mesa_Uniform2ivARB(GLint location, GLsizei count, const GLint * value)
Michal Krol1d7f7192005-03-25 12:12:50 +0000473{
Brian Paul2659ee92006-11-03 21:30:16 +0000474 uniform(location, count, value, GL_INT_VEC2, "glUniform2ivARB");
Michal Krolc1fe4692004-10-27 17:09:10 +0000475}
476
Michal Krol9ac96052006-02-27 14:41:41 +0000477GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000478_mesa_Uniform3ivARB(GLint location, GLsizei count, const GLint * value)
Michal Krol1d7f7192005-03-25 12:12:50 +0000479{
Brian Paul2659ee92006-11-03 21:30:16 +0000480 uniform(location, count, value, GL_INT_VEC3, "glUniform3ivARB");
Michal Krolc1fe4692004-10-27 17:09:10 +0000481}
482
Michal Krol9ac96052006-02-27 14:41:41 +0000483GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000484_mesa_Uniform4ivARB(GLint location, GLsizei count, const GLint * value)
Michal Krol1d7f7192005-03-25 12:12:50 +0000485{
Brian Paul2659ee92006-11-03 21:30:16 +0000486 uniform(location, count, value, GL_INT_VEC4, "glUniform4ivARB");
Michal Krolc1fe4692004-10-27 17:09:10 +0000487}
488
Brian Paul93269622006-04-14 03:43:39 +0000489
Brian Paulbdb251b2006-11-03 17:29:31 +0000490/**
491 * Helper function used by UniformMatrix**vARB() functions below.
492 */
493static void
494uniform_matrix(GLint cols, GLint rows, const char *caller,
495 GLenum matrixType,
496 GLint location, GLsizei count, GLboolean transpose,
497 const GLfloat *values)
498{
499 const GLint matElements = rows * cols;
500 GET_CURRENT_CONTEXT(ctx);
501 GET_CURRENT_LINKED_PROGRAM(pro, caller);
502
503 if (values == NULL) {
504 _mesa_error(ctx, GL_INVALID_VALUE, caller);
Brian Paule71e4c92006-11-02 16:09:10 +0000505 return;
506 }
Michal Krold55de652006-04-18 10:30:29 +0000507
Brian Paule71e4c92006-11-02 16:09:10 +0000508 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
Michal Krol1d7f7192005-03-25 12:12:50 +0000509
Brian Paulbdb251b2006-11-03 17:29:31 +0000510 if (transpose) {
511 GLfloat *trans, *pt;
512 const GLfloat *pv;
513 GLint i, j, k;
514
515 trans = (GLfloat *) _mesa_malloc(count * matElements * sizeof(GLfloat));
516 if (!trans) {
517 _mesa_error(ctx, GL_OUT_OF_MEMORY, caller);
518 return;
Brian Paule71e4c92006-11-02 16:09:10 +0000519 }
Brian Paulbdb251b2006-11-03 17:29:31 +0000520
521 pt = trans;
522 pv = values;
523 for (i = 0; i < count; i++) {
524 /* transpose from pv matrix into pt matrix */
525 for (j = 0; j < cols; j++) {
526 for (k = 0; k < rows; k++) {
527 /* XXX verify this */
528 pt[j * rows + k] = pv[k * cols + j];
529 }
530 }
531 pt += matElements;
532 pv += matElements;
Brian Paule71e4c92006-11-02 16:09:10 +0000533 }
Brian Paulbdb251b2006-11-03 17:29:31 +0000534
535 if (!(**pro).WriteUniform(pro, location, count, trans, matrixType))
536 _mesa_error(ctx, GL_INVALID_OPERATION, caller);
537 _mesa_free(trans);
Brian Paule71e4c92006-11-02 16:09:10 +0000538 }
Brian Paulbdb251b2006-11-03 17:29:31 +0000539 else {
540 if (!(**pro).WriteUniform(pro, location, count, values, matrixType))
541 _mesa_error(ctx, GL_INVALID_OPERATION, caller);
542 }
543}
544
545
546GLvoid GLAPIENTRY
547_mesa_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose,
548 const GLfloat * value)
549{
550 uniform_matrix(2, 2, "glUniformMatrix2fvARB", GL_FLOAT_MAT2,
551 location, count, transpose, value);
Michal Krolc1fe4692004-10-27 17:09:10 +0000552}
553
Michal Krol9ac96052006-02-27 14:41:41 +0000554GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000555_mesa_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose,
556 const GLfloat * value)
Michal Krol1d7f7192005-03-25 12:12:50 +0000557{
Brian Paulbdb251b2006-11-03 17:29:31 +0000558 uniform_matrix(3, 3, "glUniformMatrix3fvARB", GL_FLOAT_MAT3,
559 location, count, transpose, value);
Michal Krolc1fe4692004-10-27 17:09:10 +0000560}
561
Michal Krol9ac96052006-02-27 14:41:41 +0000562GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000563_mesa_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose,
564 const GLfloat * value)
Michal Krol1d7f7192005-03-25 12:12:50 +0000565{
Brian Paulbdb251b2006-11-03 17:29:31 +0000566 uniform_matrix(4, 4, "glUniformMatrix4fvARB", GL_FLOAT_MAT4,
567 location, count, transpose, value);
Michal Krol1d7f7192005-03-25 12:12:50 +0000568}
569
570static GLboolean
Brian Paule71e4c92006-11-02 16:09:10 +0000571_mesa_get_object_parameter(GLhandleARB obj, GLenum pname, GLvoid * params,
572 GLboolean * integral, GLint * size)
Michal Krol1d7f7192005-03-25 12:12:50 +0000573{
Brian Paule71e4c92006-11-02 16:09:10 +0000574 GET_CURRENT_CONTEXT(ctx);
575 GLint *ipar = (GLint *) params;
Michal Krol1d7f7192005-03-25 12:12:50 +0000576
Brian Paule71e4c92006-11-02 16:09:10 +0000577 /* set default values */
Brian Paulbdb251b2006-11-03 17:29:31 +0000578 *integral = GL_TRUE; /* indicates param type, TRUE: GLint, FALSE: GLfloat */
579 *size = 1; /* param array size */
Michal Krol1d7f7192005-03-25 12:12:50 +0000580
Brian Paule71e4c92006-11-02 16:09:10 +0000581 switch (pname) {
582 case GL_OBJECT_TYPE_ARB:
583 case GL_OBJECT_DELETE_STATUS_ARB:
584 case GL_OBJECT_INFO_LOG_LENGTH_ARB:
585 {
586 GET_GENERIC(gen, obj, "glGetObjectParameterivARB");
Michal Krol9ac96052006-02-27 14:41:41 +0000587
Brian Paule71e4c92006-11-02 16:09:10 +0000588 if (gen == NULL)
589 return GL_FALSE;
Michal Krol9ac96052006-02-27 14:41:41 +0000590
Brian Paule71e4c92006-11-02 16:09:10 +0000591 switch (pname) {
592 case GL_OBJECT_TYPE_ARB:
593 *ipar = (**gen).GetType(gen);
594 break;
595 case GL_OBJECT_DELETE_STATUS_ARB:
596 *ipar = (**gen).GetDeleteStatus(gen);
597 break;
Michal Krola1a02e62006-05-16 09:40:30 +0000598 case GL_OBJECT_INFO_LOG_LENGTH_ARB:
Brian Paule71e4c92006-11-02 16:09:10 +0000599 *ipar = (**gen).GetInfoLogLength(gen);
Michal Krola1a02e62006-05-16 09:40:30 +0000600 break;
Brian Paule71e4c92006-11-02 16:09:10 +0000601 }
Michal Krol9ac96052006-02-27 14:41:41 +0000602
Brian Paule71e4c92006-11-02 16:09:10 +0000603 RELEASE_GENERIC(gen);
604 }
605 break;
606 case GL_OBJECT_SUBTYPE_ARB:
607 case GL_OBJECT_COMPILE_STATUS_ARB:
608 case GL_OBJECT_SHADER_SOURCE_LENGTH_ARB:
609 {
610 GET_SHADER(sha, obj, "glGetObjectParameterivARB");
Michal Krol9ac96052006-02-27 14:41:41 +0000611
Brian Paule71e4c92006-11-02 16:09:10 +0000612 if (sha == NULL)
613 return GL_FALSE;
Michal Krol9ac96052006-02-27 14:41:41 +0000614
Brian Paule71e4c92006-11-02 16:09:10 +0000615 switch (pname) {
616 case GL_OBJECT_SUBTYPE_ARB:
617 *ipar = (**sha).GetSubType(sha);
618 break;
619 case GL_OBJECT_COMPILE_STATUS_ARB:
620 *ipar = (**sha).GetCompileStatus(sha);
621 break;
622 case GL_OBJECT_SHADER_SOURCE_LENGTH_ARB:
623 {
624 const GLcharARB *src = (**sha).GetSource(sha);
Brian Paule71e4c92006-11-02 16:09:10 +0000625 if (src == NULL)
626 *ipar = 0;
627 else
628 *ipar = _mesa_strlen(src) + 1;
629 }
630 break;
631 }
Michal Krol9ac96052006-02-27 14:41:41 +0000632
Brian Paule71e4c92006-11-02 16:09:10 +0000633 RELEASE_SHADER(sha);
634 }
635 break;
636 case GL_OBJECT_LINK_STATUS_ARB:
637 case GL_OBJECT_VALIDATE_STATUS_ARB:
638 case GL_OBJECT_ATTACHED_OBJECTS_ARB:
639 case GL_OBJECT_ACTIVE_UNIFORMS_ARB:
640 case GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB:
641 {
642 GET_PROGRAM(pro, obj, "glGetObjectParameterivARB");
Michal Krol9ac96052006-02-27 14:41:41 +0000643
Brian Paule71e4c92006-11-02 16:09:10 +0000644 if (pro == NULL)
645 return GL_FALSE;
Michal Krol9ac96052006-02-27 14:41:41 +0000646
Brian Paule71e4c92006-11-02 16:09:10 +0000647 switch (pname) {
648 case GL_OBJECT_LINK_STATUS_ARB:
649 *ipar = (**pro).GetLinkStatus(pro);
650 break;
651 case GL_OBJECT_VALIDATE_STATUS_ARB:
652 *ipar = (**pro).GetValidateStatus(pro);
653 break;
Michal Krola1a02e62006-05-16 09:40:30 +0000654 case GL_OBJECT_ATTACHED_OBJECTS_ARB:
Brian Paule71e4c92006-11-02 16:09:10 +0000655 *ipar =
656 (**pro)._container.
657 GetAttachedCount((struct gl2_container_intf **) (pro));
Michal Krola1a02e62006-05-16 09:40:30 +0000658 break;
Brian Paule71e4c92006-11-02 16:09:10 +0000659 case GL_OBJECT_ACTIVE_UNIFORMS_ARB:
660 *ipar = (**pro).GetActiveUniformCount(pro);
661 break;
662 case GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB:
663 *ipar = (**pro).GetActiveUniformMaxLength(pro);
664 break;
665 case GL_OBJECT_ACTIVE_ATTRIBUTES_ARB:
666 *ipar = (**pro).GetActiveAttribCount(pro);
667 break;
668 case GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB:
669 *ipar = (**pro).GetActiveAttribMaxLength(pro);
670 break;
671 }
Michal Krol9ac96052006-02-27 14:41:41 +0000672
Brian Paule71e4c92006-11-02 16:09:10 +0000673 RELEASE_PROGRAM(pro);
674 }
675 break;
676 default:
677 _mesa_error(ctx, GL_INVALID_ENUM, "glGetObjectParameterivARB");
678 return GL_FALSE;
679 }
Michal Krol1d7f7192005-03-25 12:12:50 +0000680
Brian Paule71e4c92006-11-02 16:09:10 +0000681 return GL_TRUE;
Michal Krol1d7f7192005-03-25 12:12:50 +0000682}
683
Michal Krol9ac96052006-02-27 14:41:41 +0000684GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000685_mesa_GetObjectParameterfvARB(GLhandleARB obj, GLenum pname, GLfloat * params)
Michal Krol1d7f7192005-03-25 12:12:50 +0000686{
Brian Paule71e4c92006-11-02 16:09:10 +0000687 GET_CURRENT_CONTEXT(ctx);
688 GLboolean integral;
689 GLint size;
Michal Krol1d7f7192005-03-25 12:12:50 +0000690
Brian Paule71e4c92006-11-02 16:09:10 +0000691 if (params == NULL) {
692 _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectParameterfvARB");
693 return;
694 }
Michal Krold55de652006-04-18 10:30:29 +0000695
Brian Paule71e4c92006-11-02 16:09:10 +0000696 assert(sizeof(GLfloat) == sizeof(GLint));
Michal Krol1d7f7192005-03-25 12:12:50 +0000697
Brian Paulbdb251b2006-11-03 17:29:31 +0000698 if (_mesa_get_object_parameter(obj, pname, (GLvoid *) params,
699 &integral, &size)) {
Brian Paule71e4c92006-11-02 16:09:10 +0000700 if (integral) {
701 GLint i;
Brian Paule71e4c92006-11-02 16:09:10 +0000702 for (i = 0; i < size; i++)
703 params[i] = (GLfloat) ((GLint *) params)[i];
704 }
Brian Paulbdb251b2006-11-03 17:29:31 +0000705 }
Michal Krolc1fe4692004-10-27 17:09:10 +0000706}
707
Michal Krol9ac96052006-02-27 14:41:41 +0000708GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000709_mesa_GetObjectParameterivARB(GLhandleARB obj, GLenum pname, GLint * params)
Michal Krol1d7f7192005-03-25 12:12:50 +0000710{
Brian Paule71e4c92006-11-02 16:09:10 +0000711 GET_CURRENT_CONTEXT(ctx);
712 GLboolean integral;
713 GLint size;
Michal Krol1d7f7192005-03-25 12:12:50 +0000714
Brian Paule71e4c92006-11-02 16:09:10 +0000715 if (params == NULL) {
716 _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectParameterivARB");
717 return;
718 }
Michal Krold55de652006-04-18 10:30:29 +0000719
Brian Paule71e4c92006-11-02 16:09:10 +0000720 assert(sizeof(GLfloat) == sizeof(GLint));
Michal Krol1d7f7192005-03-25 12:12:50 +0000721
Brian Paulbdb251b2006-11-03 17:29:31 +0000722 if (_mesa_get_object_parameter(obj, pname, (GLvoid *) params,
723 &integral, &size)) {
Brian Paule71e4c92006-11-02 16:09:10 +0000724 if (!integral) {
725 GLint i;
Brian Paule71e4c92006-11-02 16:09:10 +0000726 for (i = 0; i < size; i++)
727 params[i] = (GLint) ((GLfloat *) params)[i];
728 }
Brian Paulbdb251b2006-11-03 17:29:31 +0000729 }
Michal Krolc1fe4692004-10-27 17:09:10 +0000730}
731
Brian Paul93269622006-04-14 03:43:39 +0000732
733/**
734 * Copy string from <src> to <dst>, up to maxLength characters, returning
735 * length of <dst> in <length>.
736 * \param src the strings source
737 * \param maxLength max chars to copy
738 * \param length returns numberof chars copied
739 * \param dst the string destination
740 */
Michal Krol9ac96052006-02-27 14:41:41 +0000741static GLvoid
Brian Paule71e4c92006-11-02 16:09:10 +0000742copy_string(const GLcharARB * src, GLsizei maxLength, GLsizei * length,
743 GLcharARB * dst)
Michal Krol1d7f7192005-03-25 12:12:50 +0000744{
Brian Paule71e4c92006-11-02 16:09:10 +0000745 GLsizei len;
746 for (len = 0; len < maxLength - 1 && src && src[len]; len++)
747 dst[len] = src[len];
748 if (maxLength > 0)
749 dst[len] = 0;
750 if (length)
751 *length = len;
Michal Krolc1fe4692004-10-27 17:09:10 +0000752}
753
Brian Paul93269622006-04-14 03:43:39 +0000754
Michal Krol9ac96052006-02-27 14:41:41 +0000755GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000756_mesa_GetInfoLogARB(GLhandleARB obj, GLsizei maxLength, GLsizei * length,
757 GLcharARB * infoLog)
Michal Krol1d7f7192005-03-25 12:12:50 +0000758{
Brian Paule71e4c92006-11-02 16:09:10 +0000759 GET_CURRENT_CONTEXT(ctx);
760 GET_GENERIC(gen, obj, "glGetInfoLogARB");
Michal Krol1d7f7192005-03-25 12:12:50 +0000761
Brian Paule71e4c92006-11-02 16:09:10 +0000762 if (gen == NULL)
763 return;
Michal Krold55de652006-04-18 10:30:29 +0000764
Brian Paule71e4c92006-11-02 16:09:10 +0000765 if (infoLog == NULL)
766 _mesa_error(ctx, GL_INVALID_VALUE, "glGetInfoLogARB");
Michal Krola1a02e62006-05-16 09:40:30 +0000767 else {
Brian Paule71e4c92006-11-02 16:09:10 +0000768 GLsizei actualsize = (**gen).GetInfoLogLength(gen);
Michal Krola1a02e62006-05-16 09:40:30 +0000769 if (actualsize > maxLength)
770 actualsize = maxLength;
Brian Paule71e4c92006-11-02 16:09:10 +0000771 (**gen).GetInfoLog(gen, actualsize, infoLog);
Michal Krola1a02e62006-05-16 09:40:30 +0000772 if (length != NULL)
773 *length = (actualsize > 0) ? actualsize - 1 : 0;
774 }
Brian Paule71e4c92006-11-02 16:09:10 +0000775 RELEASE_GENERIC(gen);
Michal Krol1d7f7192005-03-25 12:12:50 +0000776}
777
Michal Krol9ac96052006-02-27 14:41:41 +0000778GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000779_mesa_GetAttachedObjectsARB(GLhandleARB containerObj, GLsizei maxCount,
780 GLsizei * count, GLhandleARB * obj)
Michal Krol1d7f7192005-03-25 12:12:50 +0000781{
Brian Paule71e4c92006-11-02 16:09:10 +0000782 GET_CURRENT_CONTEXT(ctx);
783 GET_CONTAINER(con, containerObj, "glGetAttachedObjectsARB");
Michal Krol1d7f7192005-03-25 12:12:50 +0000784
Brian Paule71e4c92006-11-02 16:09:10 +0000785 if (con == NULL)
786 return;
Michal Krold55de652006-04-18 10:30:29 +0000787
Brian Paule71e4c92006-11-02 16:09:10 +0000788 if (obj == NULL)
789 _mesa_error(ctx, GL_INVALID_VALUE, "glGetAttachedObjectsARB");
790 else {
791 GLsizei cnt, i;
Michal Krold55de652006-04-18 10:30:29 +0000792
Brian Paule71e4c92006-11-02 16:09:10 +0000793 cnt = (**con).GetAttachedCount(con);
794 if (cnt > maxCount)
795 cnt = maxCount;
796 if (count != NULL)
797 *count = cnt;
Michal Krol9ac96052006-02-27 14:41:41 +0000798
Brian Paule71e4c92006-11-02 16:09:10 +0000799 for (i = 0; i < cnt; i++) {
800 struct gl2_generic_intf **x = (**con).GetAttached(con, i);
801 obj[i] = (**x).GetName(x);
802 RELEASE_GENERIC(x);
803 }
804 }
805 RELEASE_CONTAINER(con);
Michal Krol9ac96052006-02-27 14:41:41 +0000806}
Michal Krolc1fe4692004-10-27 17:09:10 +0000807
808GLint GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000809_mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB * name)
Michal Krol1d7f7192005-03-25 12:12:50 +0000810{
Brian Paule71e4c92006-11-02 16:09:10 +0000811 GET_CURRENT_CONTEXT(ctx);
812 GLint loc = -1;
813 GET_LINKED_PROGRAM(pro, programObj, "glGetUniformLocationARB");
Michal Krol1d7f7192005-03-25 12:12:50 +0000814
Brian Paul7e6701c2006-11-03 21:51:58 +0000815 if (!pro)
Brian Paule71e4c92006-11-02 16:09:10 +0000816 return -1;
Michal Krold55de652006-04-18 10:30:29 +0000817
Brian Paule71e4c92006-11-02 16:09:10 +0000818 if (name == NULL)
819 _mesa_error(ctx, GL_INVALID_VALUE, "glGetUniformLocationARB");
820 else {
821 if (!IS_NAME_WITH_GL_PREFIX(name))
822 loc = (**pro).GetUniformLocation(pro, name);
823 }
824 RELEASE_PROGRAM(pro);
825 return loc;
Michal Krolc1fe4692004-10-27 17:09:10 +0000826}
827
Michal Krol9ac96052006-02-27 14:41:41 +0000828GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000829_mesa_GetActiveUniformARB(GLhandleARB programObj, GLuint index,
830 GLsizei maxLength, GLsizei * length, GLint * size,
831 GLenum * type, GLcharARB * name)
Michal Krol1d7f7192005-03-25 12:12:50 +0000832{
Brian Paule71e4c92006-11-02 16:09:10 +0000833 GET_CURRENT_CONTEXT(ctx);
834 GET_PROGRAM(pro, programObj, "glGetActiveUniformARB");
Michal Krol1d7f7192005-03-25 12:12:50 +0000835
Brian Paule71e4c92006-11-02 16:09:10 +0000836 if (pro == NULL)
837 return;
Michal Krold55de652006-04-18 10:30:29 +0000838
Brian Paule71e4c92006-11-02 16:09:10 +0000839 if (size == NULL || type == NULL || name == NULL)
840 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformARB");
841 else {
842 if (index < (**pro).GetActiveUniformCount(pro))
843 (**pro).GetActiveUniform(pro, index, maxLength, length, size, type,
844 name);
845 else
846 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformARB");
847 }
848 RELEASE_PROGRAM(pro);
Michal Krolc1fe4692004-10-27 17:09:10 +0000849}
850
Michal Krol9ac96052006-02-27 14:41:41 +0000851GLvoid GLAPIENTRY
Brian Paulbdb251b2006-11-03 17:29:31 +0000852_mesa_GetUniformfvARB(GLhandleARB programObj, GLint location, GLfloat * params)
Michal Krol1d7f7192005-03-25 12:12:50 +0000853{
Brian Paule71e4c92006-11-02 16:09:10 +0000854 GET_CURRENT_CONTEXT(ctx);
855 GET_LINKED_PROGRAM(pro, programObj, "glGetUniformfvARB");
Michal Krol1d7f7192005-03-25 12:12:50 +0000856
Brian Paul7e6701c2006-11-03 21:51:58 +0000857 if (!pro)
858 return;
859
860 if (!(**pro).ReadUniform(pro, location, 1, params, GL_FLOAT))
861 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfvARB");
862
863 RELEASE_PROGRAM(pro);
Michal Krolc1fe4692004-10-27 17:09:10 +0000864}
865
Michal Krol9ac96052006-02-27 14:41:41 +0000866GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000867_mesa_GetUniformivARB(GLhandleARB programObj, GLint location, GLint * params)
Michal Krol1d7f7192005-03-25 12:12:50 +0000868{
Brian Paule71e4c92006-11-02 16:09:10 +0000869 GET_CURRENT_CONTEXT(ctx);
870 GET_LINKED_PROGRAM(pro, programObj, "glGetUniformivARB");
Michal Krol1d7f7192005-03-25 12:12:50 +0000871
Brian Paul7e6701c2006-11-03 21:51:58 +0000872 if (!pro)
873 return;
874
875 if (!(**pro).ReadUniform(pro, location, 1, params, GL_INT))
876 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformivARB");
877 RELEASE_PROGRAM(pro);
Michal Krolc1fe4692004-10-27 17:09:10 +0000878}
879
Michal Krol9ac96052006-02-27 14:41:41 +0000880GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000881_mesa_GetShaderSourceARB(GLhandleARB obj, GLsizei maxLength, GLsizei * length,
882 GLcharARB * source)
Michal Krol1d7f7192005-03-25 12:12:50 +0000883{
Brian Paule71e4c92006-11-02 16:09:10 +0000884 GET_CURRENT_CONTEXT(ctx);
885 GET_SHADER(sha, obj, "glGetShaderSourceARB");
Michal Krol1d7f7192005-03-25 12:12:50 +0000886
Brian Paule71e4c92006-11-02 16:09:10 +0000887 if (sha == NULL)
888 return;
Michal Krold55de652006-04-18 10:30:29 +0000889
Brian Paule71e4c92006-11-02 16:09:10 +0000890 if (source == NULL)
891 _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderSourceARB");
892 else
893 copy_string((**sha).GetSource(sha), maxLength, length, source);
894 RELEASE_SHADER(sha);
Michal Krolc1fe4692004-10-27 17:09:10 +0000895}
896
897/* GL_ARB_vertex_shader */
898
Michal Krol9ac96052006-02-27 14:41:41 +0000899GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000900_mesa_BindAttribLocationARB(GLhandleARB programObj, GLuint index,
901 const GLcharARB * name)
Michal Krol1d7f7192005-03-25 12:12:50 +0000902{
Brian Paule71e4c92006-11-02 16:09:10 +0000903 GET_CURRENT_CONTEXT(ctx);
904 GET_PROGRAM(pro, programObj, "glBindAttribLocationARB");
Michal Krol1d7f7192005-03-25 12:12:50 +0000905
Brian Paule71e4c92006-11-02 16:09:10 +0000906 if (pro == NULL)
907 return;
Michal Krold55de652006-04-18 10:30:29 +0000908
Brian Paule71e4c92006-11-02 16:09:10 +0000909 if (name == NULL || index >= MAX_VERTEX_ATTRIBS)
910 _mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocationARB");
911 else if (IS_NAME_WITH_GL_PREFIX(name))
912 _mesa_error(ctx, GL_INVALID_OPERATION, "glBindAttribLocationARB");
913 else
914 (**pro).OverrideAttribBinding(pro, index, name);
915 RELEASE_PROGRAM(pro);
Michal Krolc1fe4692004-10-27 17:09:10 +0000916}
917
Michal Krol9ac96052006-02-27 14:41:41 +0000918GLvoid GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000919_mesa_GetActiveAttribARB(GLhandleARB programObj, GLuint index,
920 GLsizei maxLength, GLsizei * length, GLint * size,
921 GLenum * type, GLcharARB * name)
Michal Krol1d7f7192005-03-25 12:12:50 +0000922{
Brian Paule71e4c92006-11-02 16:09:10 +0000923 GET_CURRENT_CONTEXT(ctx);
924 GET_PROGRAM(pro, programObj, "glGetActiveAttribARB");
Michal Krol1d7f7192005-03-25 12:12:50 +0000925
Brian Paule71e4c92006-11-02 16:09:10 +0000926 if (pro == NULL)
927 return;
Michal Krold55de652006-04-18 10:30:29 +0000928
Brian Paule71e4c92006-11-02 16:09:10 +0000929 if (name == NULL || index >= (**pro).GetActiveAttribCount(pro))
930 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttribARB");
931 else
932 (**pro).GetActiveAttrib(pro, index, maxLength, length, size, type,
933 name);
934 RELEASE_PROGRAM(pro);
Michal Krolc1fe4692004-10-27 17:09:10 +0000935}
936
937GLint GLAPIENTRY
Brian Paule71e4c92006-11-02 16:09:10 +0000938_mesa_GetAttribLocationARB(GLhandleARB programObj, const GLcharARB * name)
Michal Krol1d7f7192005-03-25 12:12:50 +0000939{
Brian Paule71e4c92006-11-02 16:09:10 +0000940 GET_CURRENT_CONTEXT(ctx);
941 GLint loc = -1;
942 GET_LINKED_PROGRAM(pro, programObj, "glGetAttribLocationARB");
Michal Krol1d7f7192005-03-25 12:12:50 +0000943
Brian Paul7e6701c2006-11-03 21:51:58 +0000944 if (!pro)
Brian Paule71e4c92006-11-02 16:09:10 +0000945 return -1;
Michal Krold55de652006-04-18 10:30:29 +0000946
Brian Paule71e4c92006-11-02 16:09:10 +0000947 if (name == NULL)
948 _mesa_error(ctx, GL_INVALID_VALUE, "glGetAttribLocationARB");
949 else if (!IS_NAME_WITH_GL_PREFIX(name))
950 loc = (**pro).GetAttribLocation(pro, name);
951 RELEASE_PROGRAM(pro);
952 return loc;
Michal Krolc1fe4692004-10-27 17:09:10 +0000953}
954
Brian Paulf961d392006-11-02 16:11:31 +0000955
956/**
957 ** OpenGL 2.0 functions which basically wrap the ARB_shader functions
958 **/
959
960void GLAPIENTRY
961_mesa_AttachShader(GLuint program, GLuint shader)
962{
963 _mesa_AttachObjectARB(program, shader);
964}
965
966
967GLuint GLAPIENTRY
968_mesa_CreateShader(GLenum type)
969{
970 return (GLuint) _mesa_CreateShaderObjectARB(type);
971}
972
973GLuint GLAPIENTRY
974_mesa_CreateProgram(void)
975{
976 return (GLuint) _mesa_CreateProgramObjectARB();
977}
978
979void GLAPIENTRY
980_mesa_DeleteProgram(GLuint program)
981{
982 _mesa_DeleteObjectARB(program);
983}
984
985
986void GLAPIENTRY
987_mesa_DeleteShader(GLuint shader)
988{
989 _mesa_DeleteObjectARB(shader);
990}
991
992void GLAPIENTRY
993_mesa_DetachShader(GLuint program, GLuint shader)
994{
995 _mesa_DetachObjectARB(program, shader);
996}
997
998void GLAPIENTRY
999_mesa_GetAttachedShaders(GLuint program, GLsizei maxCount,
1000 GLsizei *count, GLuint *obj)
1001{
1002 _mesa_GetAttachedObjectsARB(program, maxCount, count, obj);
1003}
1004
1005void GLAPIENTRY
1006_mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params)
1007{
Brian Paul3bef6002006-11-03 22:15:43 +00001008 GET_CURRENT_CONTEXT(ctx);
1009 GET_PROGRAM(pro, program, "glGetProgramiv");
1010
1011 if (!pro)
1012 return;
1013
1014 switch (pname) {
1015 case GL_DELETE_STATUS:
Brian Paul7c279f42006-11-15 21:35:06 +00001016 *params = (**pro)._container._generic.GetDeleteStatus((struct gl2_generic_intf **) pro);
Brian Paul3bef6002006-11-03 22:15:43 +00001017 break;
1018 case GL_LINK_STATUS:
1019 *params = (**pro).GetLinkStatus(pro);
1020 break;
1021 case GL_VALIDATE_STATUS:
1022 *params = (**pro).GetValidateStatus(pro);
1023 break;
1024 case GL_INFO_LOG_LENGTH:
Brian Paul7c279f42006-11-15 21:35:06 +00001025 *params = (**pro)._container._generic.GetInfoLogLength( (struct gl2_generic_intf **) pro );
Brian Paul3bef6002006-11-03 22:15:43 +00001026 break;
1027 case GL_ATTACHED_SHADERS:
Brian Paul7c279f42006-11-15 21:35:06 +00001028 *params = (**pro)._container.GetAttachedCount( (struct gl2_container_intf **) pro );
Brian Paul3bef6002006-11-03 22:15:43 +00001029 break;
1030 case GL_ACTIVE_ATTRIBUTES:
1031 *params = (**pro).GetActiveAttribCount(pro);
1032 break;
1033 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
1034 *params = (**pro).GetActiveAttribMaxLength(pro);
1035 break;
1036 case GL_ACTIVE_UNIFORMS:
1037 *params = (**pro).GetActiveUniformCount(pro);
1038 break;
1039 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
1040 *params = (**pro).GetActiveUniformMaxLength(pro);
1041 break;
1042 default:
1043 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname)");
1044 return;
1045 }
Brian Paulf961d392006-11-02 16:11:31 +00001046}
1047
1048void GLAPIENTRY
1049_mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize,
1050 GLsizei *length, GLchar *infoLog)
1051{
1052 _mesa_GetInfoLogARB(program, bufSize, length, infoLog);
1053}
1054
1055void GLAPIENTRY
1056_mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params)
1057{
Brian Pauld2f80772006-11-03 22:23:47 +00001058 GET_CURRENT_CONTEXT(ctx);
1059 GET_SHADER(sh, shader, "glGetShaderiv");
1060
1061 if (!sh)
1062 return;
1063
1064 switch (pname) {
1065 case GL_SHADER_TYPE:
1066 *params = (**sh).GetSubType(sh);
1067 break;
1068 case GL_DELETE_STATUS:
Brian Paul7c279f42006-11-15 21:35:06 +00001069 *params = (**sh)._generic.GetDeleteStatus((struct gl2_generic_intf **) sh);
Brian Pauld2f80772006-11-03 22:23:47 +00001070 break;
1071 case GL_COMPILE_STATUS:
1072 *params = (**sh).GetCompileStatus(sh);
1073 break;
1074 case GL_INFO_LOG_LENGTH:
Brian Paul7c279f42006-11-15 21:35:06 +00001075 *params = (**sh)._generic.GetInfoLogLength((struct gl2_generic_intf **)sh);
Brian Pauld2f80772006-11-03 22:23:47 +00001076 break;
1077 case GL_SHADER_SOURCE_LENGTH:
1078 {
1079 const GLchar *src = (**sh).GetSource(sh);
1080 *params = src ? (_mesa_strlen(src) + 1) : 0;
1081 }
1082 break;
1083 default:
1084 _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)");
1085 return;
1086 }
Brian Paulf961d392006-11-02 16:11:31 +00001087}
1088
1089void GLAPIENTRY
1090_mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize,
1091 GLsizei *length, GLchar *infoLog)
1092{
1093 _mesa_GetInfoLogARB(shader, bufSize, length, infoLog);
1094}
1095
1096GLboolean GLAPIENTRY
Brian Paul12fe1b32006-11-02 16:21:04 +00001097_mesa_IsProgram(GLuint program)
Brian Paulf961d392006-11-02 16:11:31 +00001098{
1099 GET_CURRENT_CONTEXT(ctx);
Brian Paulc9365b72006-11-03 23:32:30 +00001100 GET_PROGRAM(pro, program, "glIsProgram");
1101 if (pro) {
1102 RELEASE_PROGRAM(pro);
1103 return GL_TRUE;
1104 }
1105 else {
1106 return GL_FALSE;
1107 }
Brian Paulf961d392006-11-02 16:11:31 +00001108}
1109
1110GLboolean GLAPIENTRY
1111_mesa_IsShader(GLuint shader)
1112{
1113 GET_CURRENT_CONTEXT(ctx);
Brian Paulc9365b72006-11-03 23:32:30 +00001114 GET_SHADER(sh, shader, "glIsProgram");
1115 if (sh) {
1116 RELEASE_SHADER(sh);
1117 return GL_TRUE;
1118 }
1119 else {
1120 return GL_FALSE;
1121 }
Brian Paulf961d392006-11-02 16:11:31 +00001122}
1123
1124
Brian Paulbdb251b2006-11-03 17:29:31 +00001125/**
1126 ** 2.1 functions
1127 **/
1128
1129void GLAPIENTRY
1130_mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
1131 const GLfloat *value)
1132{
1133 uniform_matrix(2, 3, "glUniformMatrix2x3fv", GL_FLOAT_MAT2x3,
1134 location, count, transpose, value);
1135}
1136
1137void GLAPIENTRY
1138_mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
1139 const GLfloat *value)
1140{
1141 uniform_matrix(3, 2, "glUniformMatrix3x2fv", GL_FLOAT_MAT3x2,
1142 location, count, transpose, value);
1143}
1144
1145void GLAPIENTRY
1146_mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
1147 const GLfloat *value)
1148{
1149 uniform_matrix(2, 4, "glUniformMatrix2x4fv", GL_FLOAT_MAT2x4,
1150 location, count, transpose, value);
1151}
1152
1153void GLAPIENTRY
1154_mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
1155 const GLfloat *value)
1156{
1157 uniform_matrix(4, 2, "glUniformMatrix4x2fv", GL_FLOAT_MAT4x2,
1158 location, count, transpose, value);
1159}
1160
1161void GLAPIENTRY
1162_mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
1163 const GLfloat *value)
1164{
1165 uniform_matrix(3, 4, "glUniformMatrix3x4fv", GL_FLOAT_MAT3x4,
1166 location, count, transpose, value);
1167}
1168
1169void GLAPIENTRY
1170_mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
1171 const GLfloat *value)
1172{
1173 uniform_matrix(4, 3, "glUniformMatrix4x3fv", GL_FLOAT_MAT4x3,
1174 location, count, transpose, value);
1175}
1176
1177
1178
1179
1180
Michal Krol365582d2006-08-01 20:07:31 +00001181#endif
1182
Michal Krol9ac96052006-02-27 14:41:41 +00001183GLvoid
Brian Paule71e4c92006-11-02 16:09:10 +00001184_mesa_init_shaderobjects(GLcontext * ctx)
Michal Krol1d7f7192005-03-25 12:12:50 +00001185{
Brian Paule71e4c92006-11-02 16:09:10 +00001186 ctx->ShaderObjects.CurrentProgram = NULL;
1187 ctx->ShaderObjects._FragmentShaderPresent = GL_FALSE;
1188 ctx->ShaderObjects._VertexShaderPresent = GL_FALSE;
Michal Krol1d7f7192005-03-25 12:12:50 +00001189
Brian Paule71e4c92006-11-02 16:09:10 +00001190 _mesa_init_shaderobjects_3dlabs(ctx);
Michal Krolc1fe4692004-10-27 17:09:10 +00001191}