blob: 89f2d20cc9a39980214d64bc15b9e8b64aafc584 [file] [log] [blame]
Michal Krol157ec8b2004-03-10 18:02:01 +00001/*
2 * Mesa 3-D graphics library
Brian Paul05051032005-11-01 04:36:33 +00003 * Version: 6.5
Michal Krol157ec8b2004-03-10 18:02:01 +00004 *
Michal Krolbb38cad2006-04-11 11:41:11 +00005 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
Michal Krol157ec8b2004-03-10 18:02:01 +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 arbprogram.c
27 * ARB_vertex/fragment_program state management functions.
28 * \author Brian Paul
29 */
30
31
32#include "glheader.h"
33#include "arbprogram.h"
Brian Paul8c41a142005-11-19 15:36:28 +000034#include "arbprogparse.h"
Michal Krol157ec8b2004-03-10 18:02:01 +000035#include "context.h"
36#include "imports.h"
37#include "macros.h"
38#include "mtypes.h"
Michal Krol157ec8b2004-03-10 18:02:01 +000039
40
41void GLAPIENTRY
42_mesa_EnableVertexAttribArrayARB(GLuint index)
43{
44 GET_CURRENT_CONTEXT(ctx);
45 ASSERT_OUTSIDE_BEGIN_END(ctx);
46
Brian Paul05051032005-11-01 04:36:33 +000047 if (index >= ctx->Const.VertexProgram.MaxAttribs) {
Michal Krol157ec8b2004-03-10 18:02:01 +000048 _mesa_error(ctx, GL_INVALID_VALUE,
49 "glEnableVertexAttribArrayARB(index)");
50 return;
51 }
52
53 FLUSH_VERTICES(ctx, _NEW_ARRAY);
Ian Romanickee34e6e2006-06-12 16:26:29 +000054 ctx->Array.ArrayObj->VertexAttrib[index].Enabled = GL_TRUE;
55 ctx->Array.ArrayObj->_Enabled |= _NEW_ARRAY_ATTRIB(index);
Michal Krol157ec8b2004-03-10 18:02:01 +000056 ctx->Array.NewState |= _NEW_ARRAY_ATTRIB(index);
57}
58
59
60void GLAPIENTRY
61_mesa_DisableVertexAttribArrayARB(GLuint index)
62{
63 GET_CURRENT_CONTEXT(ctx);
64 ASSERT_OUTSIDE_BEGIN_END(ctx);
65
Brian Paul05051032005-11-01 04:36:33 +000066 if (index >= ctx->Const.VertexProgram.MaxAttribs) {
Michal Krol157ec8b2004-03-10 18:02:01 +000067 _mesa_error(ctx, GL_INVALID_VALUE,
68 "glEnableVertexAttribArrayARB(index)");
69 return;
70 }
71
72 FLUSH_VERTICES(ctx, _NEW_ARRAY);
Ian Romanickee34e6e2006-06-12 16:26:29 +000073 ctx->Array.ArrayObj->VertexAttrib[index].Enabled = GL_FALSE;
74 ctx->Array.ArrayObj->_Enabled &= ~_NEW_ARRAY_ATTRIB(index);
Michal Krol157ec8b2004-03-10 18:02:01 +000075 ctx->Array.NewState |= _NEW_ARRAY_ATTRIB(index);
76}
77
78
79void GLAPIENTRY
80_mesa_GetVertexAttribdvARB(GLuint index, GLenum pname, GLdouble *params)
81{
82 GLfloat fparams[4];
83 GET_CURRENT_CONTEXT(ctx);
84 ASSERT_OUTSIDE_BEGIN_END(ctx);
85
86 _mesa_GetVertexAttribfvARB(index, pname, fparams);
87 if (ctx->ErrorValue == GL_NO_ERROR) {
88 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
89 COPY_4V(params, fparams);
90 }
91 else {
92 params[0] = fparams[0];
93 }
94 }
95}
96
97
98void GLAPIENTRY
99_mesa_GetVertexAttribfvARB(GLuint index, GLenum pname, GLfloat *params)
100{
101 GET_CURRENT_CONTEXT(ctx);
102 ASSERT_OUTSIDE_BEGIN_END(ctx);
103
Brian Paulbe76b7f2004-10-04 14:40:05 +0000104 if (index == 0 || index >= MAX_VERTEX_PROGRAM_ATTRIBS) {
Michal Krol157ec8b2004-03-10 18:02:01 +0000105 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribfvARB(index)");
106 return;
107 }
108
109 switch (pname) {
110 case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB:
Ian Romanickee34e6e2006-06-12 16:26:29 +0000111 params[0] = (GLfloat) ctx->Array.ArrayObj->VertexAttrib[index].Enabled;
Michal Krol157ec8b2004-03-10 18:02:01 +0000112 break;
113 case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB:
Ian Romanickee34e6e2006-06-12 16:26:29 +0000114 params[0] = (GLfloat) ctx->Array.ArrayObj->VertexAttrib[index].Size;
Michal Krol157ec8b2004-03-10 18:02:01 +0000115 break;
116 case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB:
Ian Romanickee34e6e2006-06-12 16:26:29 +0000117 params[0] = (GLfloat) ctx->Array.ArrayObj->VertexAttrib[index].Stride;
Michal Krol157ec8b2004-03-10 18:02:01 +0000118 break;
119 case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB:
Ian Romanickee34e6e2006-06-12 16:26:29 +0000120 params[0] = (GLfloat) ctx->Array.ArrayObj->VertexAttrib[index].Type;
Michal Krol157ec8b2004-03-10 18:02:01 +0000121 break;
122 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB:
Ian Romanickee34e6e2006-06-12 16:26:29 +0000123 params[0] = ctx->Array.ArrayObj->VertexAttrib[index].Normalized;
Michal Krol157ec8b2004-03-10 18:02:01 +0000124 break;
125 case GL_CURRENT_VERTEX_ATTRIB_ARB:
Michal Krolbb38cad2006-04-11 11:41:11 +0000126 FLUSH_CURRENT(ctx, 0);
127 COPY_4V(params, ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + index]);
Michal Krol157ec8b2004-03-10 18:02:01 +0000128 break;
129 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB:
130 if (!ctx->Extensions.ARB_vertex_buffer_object) {
131 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribfvARB(pname)");
132 return;
133 }
Ian Romanickee34e6e2006-06-12 16:26:29 +0000134 params[0] = (GLfloat) ctx->Array.ArrayObj->VertexAttrib[index].BufferObj->Name;
Tilman Sauerbeck6be81272006-05-30 16:57:52 +0000135 break;
Michal Krol157ec8b2004-03-10 18:02:01 +0000136 default:
137 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribfvARB(pname)");
138 return;
139 }
140}
141
142
143void GLAPIENTRY
144_mesa_GetVertexAttribivARB(GLuint index, GLenum pname, GLint *params)
145{
146 GLfloat fparams[4];
147 GET_CURRENT_CONTEXT(ctx);
148 ASSERT_OUTSIDE_BEGIN_END(ctx);
149
150 _mesa_GetVertexAttribfvARB(index, pname, fparams);
151 if (ctx->ErrorValue == GL_NO_ERROR) {
152 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
153 COPY_4V_CAST(params, fparams, GLint); /* float to int */
154 }
155 else {
156 params[0] = (GLint) fparams[0];
157 }
158 }
159}
160
161
162void GLAPIENTRY
163_mesa_GetVertexAttribPointervARB(GLuint index, GLenum pname, GLvoid **pointer)
164{
165 GET_CURRENT_CONTEXT(ctx);
166 ASSERT_OUTSIDE_BEGIN_END(ctx);
167
Brian Paul05051032005-11-01 04:36:33 +0000168 if (index >= ctx->Const.VertexProgram.MaxAttribs) {
Michal Krol157ec8b2004-03-10 18:02:01 +0000169 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerARB(index)");
170 return;
171 }
172
173 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) {
174 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerARB(pname)");
175 return;
176 }
177
Ian Romanickee34e6e2006-06-12 16:26:29 +0000178 *pointer = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[index].Ptr;
Michal Krol157ec8b2004-03-10 18:02:01 +0000179}
180
181
182void GLAPIENTRY
183_mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
184 const GLvoid *string)
185{
186 GET_CURRENT_CONTEXT(ctx);
187 ASSERT_OUTSIDE_BEGIN_END(ctx);
188
189 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
190
Brian Paul8c41a142005-11-19 15:36:28 +0000191 if (format != GL_PROGRAM_FORMAT_ASCII_ARB) {
192 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(format)");
193 return;
194 }
195
Michal Krol157ec8b2004-03-10 18:02:01 +0000196 if (target == GL_VERTEX_PROGRAM_ARB
197 && ctx->Extensions.ARB_vertex_program) {
Brian Paul122629f2006-07-20 16:49:57 +0000198 struct gl_vertex_program *prog = ctx->VertexProgram.Current;
Brian Paul8c41a142005-11-19 15:36:28 +0000199 _mesa_parse_arb_vertex_program(ctx, target, string, len, prog);
Michal Krol157ec8b2004-03-10 18:02:01 +0000200
201 if (ctx->Driver.ProgramStringNotify)
202 ctx->Driver.ProgramStringNotify( ctx, target, &prog->Base );
203 }
204 else if (target == GL_FRAGMENT_PROGRAM_ARB
205 && ctx->Extensions.ARB_fragment_program) {
Brian Paul122629f2006-07-20 16:49:57 +0000206 struct gl_fragment_program *prog = ctx->FragmentProgram.Current;
Brian Paul8c41a142005-11-19 15:36:28 +0000207 _mesa_parse_arb_fragment_program(ctx, target, string, len, prog);
Michal Krol157ec8b2004-03-10 18:02:01 +0000208
209 if (ctx->Driver.ProgramStringNotify)
210 ctx->Driver.ProgramStringNotify( ctx, target, &prog->Base );
211 }
212 else {
213 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(target)");
214 return;
215 }
216}
217
218
219void GLAPIENTRY
220_mesa_ProgramEnvParameter4dARB(GLenum target, GLuint index,
221 GLdouble x, GLdouble y, GLdouble z, GLdouble w)
222{
223 _mesa_ProgramEnvParameter4fARB(target, index, (GLfloat) x, (GLfloat) y,
224 (GLfloat) z, (GLfloat) w);
225}
226
227
228void GLAPIENTRY
229_mesa_ProgramEnvParameter4dvARB(GLenum target, GLuint index,
230 const GLdouble *params)
231{
232 _mesa_ProgramEnvParameter4fARB(target, index, (GLfloat) params[0],
233 (GLfloat) params[1], (GLfloat) params[2],
234 (GLfloat) params[3]);
235}
236
237
238void GLAPIENTRY
239_mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index,
240 GLfloat x, GLfloat y, GLfloat z, GLfloat w)
241{
242 GET_CURRENT_CONTEXT(ctx);
243 ASSERT_OUTSIDE_BEGIN_END(ctx);
244
245 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
246
247 if (target == GL_FRAGMENT_PROGRAM_ARB
248 && ctx->Extensions.ARB_fragment_program) {
Brian Paul05051032005-11-01 04:36:33 +0000249 if (index >= ctx->Const.FragmentProgram.MaxEnvParams) {
Michal Krol157ec8b2004-03-10 18:02:01 +0000250 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
251 return;
252 }
253 ASSIGN_4V(ctx->FragmentProgram.Parameters[index], x, y, z, w);
254 }
Brian Paul83c74b72004-10-16 00:29:03 +0000255 else if (target == GL_VERTEX_PROGRAM_ARB
Michal Krol157ec8b2004-03-10 18:02:01 +0000256 && ctx->Extensions.ARB_vertex_program) {
Brian Paul05051032005-11-01 04:36:33 +0000257 if (index >= ctx->Const.VertexProgram.MaxEnvParams) {
Michal Krol157ec8b2004-03-10 18:02:01 +0000258 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
259 return;
260 }
261 ASSIGN_4V(ctx->VertexProgram.Parameters[index], x, y, z, w);
262 }
263 else {
264 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameter(target)");
265 return;
266 }
267}
268
269
270void GLAPIENTRY
271_mesa_ProgramEnvParameter4fvARB(GLenum target, GLuint index,
272 const GLfloat *params)
273{
274 _mesa_ProgramEnvParameter4fARB(target, index, params[0], params[1],
275 params[2], params[3]);
276}
277
278
279void GLAPIENTRY
Ian Romanick8c41c752006-08-15 16:47:34 +0000280_mesa_ProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count,
281 const GLfloat *params)
282{
283 GET_CURRENT_CONTEXT(ctx);
284 unsigned i;
285 GLfloat * dest;
286 ASSERT_OUTSIDE_BEGIN_END(ctx);
287
288 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
289
290 if (count <= 0) {
291 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameters4fv(count)");
292 }
293
294 if (target == GL_FRAGMENT_PROGRAM_ARB
295 && ctx->Extensions.ARB_fragment_program) {
296 if ((index + count) > ctx->Const.FragmentProgram.MaxEnvParams) {
297 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameters4fv(index + count)");
298 return;
299 }
300 dest = ctx->FragmentProgram.Parameters[index];
301 }
302 else if (target == GL_VERTEX_PROGRAM_ARB
303 && ctx->Extensions.ARB_vertex_program) {
304 if ((index + count) > ctx->Const.VertexProgram.MaxEnvParams) {
305 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameters4fv(index + count)");
306 return;
307 }
308 dest = ctx->VertexProgram.Parameters[index];
309 }
310 else {
311 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameters4fv(target)");
312 return;
313 }
314
315 for ( i = 0 ; i < count ; i++ ) {
316 COPY_4V(dest, params);
317 params += 4;
318 dest += 4;
319 }
320}
321
322
323void GLAPIENTRY
Michal Krol157ec8b2004-03-10 18:02:01 +0000324_mesa_GetProgramEnvParameterdvARB(GLenum target, GLuint index,
325 GLdouble *params)
326{
327 GET_CURRENT_CONTEXT(ctx);
328 GLfloat fparams[4];
329
330 _mesa_GetProgramEnvParameterfvARB(target, index, fparams);
331 if (ctx->ErrorValue == GL_NO_ERROR) {
332 params[0] = fparams[0];
333 params[1] = fparams[1];
334 params[2] = fparams[2];
335 params[3] = fparams[3];
336 }
337}
338
339
340void GLAPIENTRY
341_mesa_GetProgramEnvParameterfvARB(GLenum target, GLuint index,
342 GLfloat *params)
343{
344 GET_CURRENT_CONTEXT(ctx);
345
346 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
347
348 if (!ctx->_CurrentProgram)
349 ASSERT_OUTSIDE_BEGIN_END(ctx);
350
351 if (target == GL_FRAGMENT_PROGRAM_ARB
352 && ctx->Extensions.ARB_fragment_program) {
Brian Paul05051032005-11-01 04:36:33 +0000353 if (index >= ctx->Const.FragmentProgram.MaxEnvParams) {
Michal Krol157ec8b2004-03-10 18:02:01 +0000354 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
355 return;
356 }
357 COPY_4V(params, ctx->FragmentProgram.Parameters[index]);
358 }
Brian Paul83c74b72004-10-16 00:29:03 +0000359 else if (target == GL_VERTEX_PROGRAM_ARB
Michal Krol157ec8b2004-03-10 18:02:01 +0000360 && ctx->Extensions.ARB_vertex_program) {
Brian Paul05051032005-11-01 04:36:33 +0000361 if (index >= ctx->Const.VertexProgram.MaxEnvParams) {
Michal Krol157ec8b2004-03-10 18:02:01 +0000362 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
363 return;
364 }
365 COPY_4V(params, ctx->VertexProgram.Parameters[index]);
366 }
367 else {
368 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramEnvParameter(target)");
369 return;
370 }
371}
372
373
374/**
375 * Note, this function is also used by the GL_NV_fragment_program extension.
376 */
377void GLAPIENTRY
378_mesa_ProgramLocalParameter4fARB(GLenum target, GLuint index,
379 GLfloat x, GLfloat y, GLfloat z, GLfloat w)
380{
381 GET_CURRENT_CONTEXT(ctx);
Brian Paul122629f2006-07-20 16:49:57 +0000382 struct gl_program *prog;
Michal Krol157ec8b2004-03-10 18:02:01 +0000383 ASSERT_OUTSIDE_BEGIN_END(ctx);
384
385 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
386
387 if ((target == GL_FRAGMENT_PROGRAM_NV
388 && ctx->Extensions.NV_fragment_program) ||
389 (target == GL_FRAGMENT_PROGRAM_ARB
390 && ctx->Extensions.ARB_fragment_program)) {
Brian Paul05051032005-11-01 04:36:33 +0000391 if (index >= ctx->Const.FragmentProgram.MaxLocalParams) {
Michal Krol157ec8b2004-03-10 18:02:01 +0000392 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
393 return;
394 }
395 prog = &(ctx->FragmentProgram.Current->Base);
396 }
397 else if (target == GL_VERTEX_PROGRAM_ARB
398 && ctx->Extensions.ARB_vertex_program) {
Brian Paul05051032005-11-01 04:36:33 +0000399 if (index >= ctx->Const.VertexProgram.MaxLocalParams) {
Michal Krol157ec8b2004-03-10 18:02:01 +0000400 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
401 return;
402 }
403 prog = &(ctx->VertexProgram.Current->Base);
404 }
405 else {
406 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameterARB");
407 return;
408 }
409
410 ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS);
411 prog->LocalParams[index][0] = x;
412 prog->LocalParams[index][1] = y;
413 prog->LocalParams[index][2] = z;
414 prog->LocalParams[index][3] = w;
415}
416
417
418/**
419 * Note, this function is also used by the GL_NV_fragment_program extension.
420 */
421void GLAPIENTRY
422_mesa_ProgramLocalParameter4fvARB(GLenum target, GLuint index,
423 const GLfloat *params)
424{
425 _mesa_ProgramLocalParameter4fARB(target, index, params[0], params[1],
426 params[2], params[3]);
427}
428
429
Ian Romanick8c41c752006-08-15 16:47:34 +0000430void GLAPIENTRY
431_mesa_ProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count,
432 const GLfloat *params)
433{
434 GET_CURRENT_CONTEXT(ctx);
435 struct gl_program *prog;
436 unsigned i;
437 ASSERT_OUTSIDE_BEGIN_END(ctx);
438
439 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
440
441 if (count <= 0) {
442 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameters4fv(count)");
443 }
444
445 if (target == GL_FRAGMENT_PROGRAM_ARB
446 && ctx->Extensions.ARB_fragment_program) {
447 if ((index + count) > ctx->Const.FragmentProgram.MaxLocalParams) {
448 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameters4fvEXT(index + count)");
449 return;
450 }
451 prog = &(ctx->FragmentProgram.Current->Base);
452 }
453 else if (target == GL_VERTEX_PROGRAM_ARB
454 && ctx->Extensions.ARB_vertex_program) {
455 if ((index + count) > ctx->Const.VertexProgram.MaxLocalParams) {
456 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameters4fvEXT(index + count)");
457 return;
458 }
459 prog = &(ctx->VertexProgram.Current->Base);
460 }
461 else {
462 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameters4fvEXT(target)");
463 return;
464 }
465
466 for (i = 0; i < count; i++) {
467 ASSERT((index + i) < MAX_PROGRAM_LOCAL_PARAMS);
468 COPY_4V(prog->LocalParams[index + i], params);
469 params += 4;
470 }
471}
472
473
Michal Krol157ec8b2004-03-10 18:02:01 +0000474/**
475 * Note, this function is also used by the GL_NV_fragment_program extension.
476 */
477void GLAPIENTRY
478_mesa_ProgramLocalParameter4dARB(GLenum target, GLuint index,
479 GLdouble x, GLdouble y,
480 GLdouble z, GLdouble w)
481{
482 _mesa_ProgramLocalParameter4fARB(target, index, (GLfloat) x, (GLfloat) y,
483 (GLfloat) z, (GLfloat) w);
484}
485
486
487/**
488 * Note, this function is also used by the GL_NV_fragment_program extension.
489 */
490void GLAPIENTRY
491_mesa_ProgramLocalParameter4dvARB(GLenum target, GLuint index,
492 const GLdouble *params)
493{
494 _mesa_ProgramLocalParameter4fARB(target, index,
495 (GLfloat) params[0], (GLfloat) params[1],
496 (GLfloat) params[2], (GLfloat) params[3]);
497}
498
499
500/**
501 * Note, this function is also used by the GL_NV_fragment_program extension.
502 */
503void GLAPIENTRY
504_mesa_GetProgramLocalParameterfvARB(GLenum target, GLuint index,
505 GLfloat *params)
506{
Brian Paul122629f2006-07-20 16:49:57 +0000507 const struct gl_program *prog;
Michal Krol157ec8b2004-03-10 18:02:01 +0000508 GLuint maxParams;
509 GET_CURRENT_CONTEXT(ctx);
510 ASSERT_OUTSIDE_BEGIN_END(ctx);
511
512 if (target == GL_VERTEX_PROGRAM_ARB
513 && ctx->Extensions.ARB_vertex_program) {
514 prog = &(ctx->VertexProgram.Current->Base);
Brian Paul05051032005-11-01 04:36:33 +0000515 maxParams = ctx->Const.VertexProgram.MaxLocalParams;
Michal Krol157ec8b2004-03-10 18:02:01 +0000516 }
517 else if (target == GL_FRAGMENT_PROGRAM_ARB
518 && ctx->Extensions.ARB_fragment_program) {
519 prog = &(ctx->FragmentProgram.Current->Base);
Brian Paul05051032005-11-01 04:36:33 +0000520 maxParams = ctx->Const.FragmentProgram.MaxLocalParams;
Michal Krol157ec8b2004-03-10 18:02:01 +0000521 }
522 else if (target == GL_FRAGMENT_PROGRAM_NV
523 && ctx->Extensions.NV_fragment_program) {
524 prog = &(ctx->FragmentProgram.Current->Base);
525 maxParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
526 }
527 else {
528 _mesa_error(ctx, GL_INVALID_ENUM,
529 "glGetProgramLocalParameterARB(target)");
530 return;
531 }
532
533 if (index >= maxParams) {
534 _mesa_error(ctx, GL_INVALID_VALUE,
535 "glGetProgramLocalParameterARB(index)");
536 return;
537 }
538
539 ASSERT(prog);
540 ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS);
541 COPY_4V(params, prog->LocalParams[index]);
542}
543
544
545/**
546 * Note, this function is also used by the GL_NV_fragment_program extension.
547 */
548void GLAPIENTRY
549_mesa_GetProgramLocalParameterdvARB(GLenum target, GLuint index,
550 GLdouble *params)
551{
552 GET_CURRENT_CONTEXT(ctx);
553 GLfloat floatParams[4];
554 _mesa_GetProgramLocalParameterfvARB(target, index, floatParams);
555 if (ctx->ErrorValue == GL_NO_ERROR) {
556 COPY_4V(params, floatParams);
557 }
558}
559
560
561void GLAPIENTRY
562_mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params)
563{
Brian Paul05051032005-11-01 04:36:33 +0000564 const struct gl_program_constants *limits;
Brian Paul122629f2006-07-20 16:49:57 +0000565 struct gl_program *prog;
Michal Krol157ec8b2004-03-10 18:02:01 +0000566 GET_CURRENT_CONTEXT(ctx);
567
568 if (!ctx->_CurrentProgram)
569 ASSERT_OUTSIDE_BEGIN_END(ctx);
570
571 if (target == GL_VERTEX_PROGRAM_ARB
572 && ctx->Extensions.ARB_vertex_program) {
573 prog = &(ctx->VertexProgram.Current->Base);
Brian Paul05051032005-11-01 04:36:33 +0000574 limits = &ctx->Const.VertexProgram;
Michal Krol157ec8b2004-03-10 18:02:01 +0000575 }
576 else if (target == GL_FRAGMENT_PROGRAM_ARB
577 && ctx->Extensions.ARB_fragment_program) {
578 prog = &(ctx->FragmentProgram.Current->Base);
Brian Paul05051032005-11-01 04:36:33 +0000579 limits = &ctx->Const.FragmentProgram;
Michal Krol157ec8b2004-03-10 18:02:01 +0000580 }
581 else {
582 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
583 return;
584 }
585
586 ASSERT(prog);
Brian Paul05051032005-11-01 04:36:33 +0000587 ASSERT(limits);
Michal Krol157ec8b2004-03-10 18:02:01 +0000588
Brian Paul05051032005-11-01 04:36:33 +0000589 /* Queries supported for both vertex and fragment programs */
Michal Krol157ec8b2004-03-10 18:02:01 +0000590 switch (pname) {
591 case GL_PROGRAM_LENGTH_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000592 *params
593 = prog->String ? (GLint) _mesa_strlen((char *) prog->String) : 0;
594 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000595 case GL_PROGRAM_FORMAT_ARB:
596 *params = prog->Format;
Brian Paul05051032005-11-01 04:36:33 +0000597 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000598 case GL_PROGRAM_BINDING_ARB:
599 *params = prog->Id;
Brian Paul05051032005-11-01 04:36:33 +0000600 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000601 case GL_PROGRAM_INSTRUCTIONS_ARB:
602 *params = prog->NumInstructions;
Brian Paul05051032005-11-01 04:36:33 +0000603 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000604 case GL_MAX_PROGRAM_INSTRUCTIONS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000605 *params = limits->MaxInstructions;
606 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000607 case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000608 *params = prog->NumNativeInstructions;
609 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000610 case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000611 *params = limits->MaxNativeInstructions;
612 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000613 case GL_PROGRAM_TEMPORARIES_ARB:
614 *params = prog->NumTemporaries;
Brian Paul05051032005-11-01 04:36:33 +0000615 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000616 case GL_MAX_PROGRAM_TEMPORARIES_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000617 *params = limits->MaxTemps;
618 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000619 case GL_PROGRAM_NATIVE_TEMPORARIES_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000620 *params = prog->NumNativeTemporaries;
621 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000622 case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000623 *params = limits->MaxNativeTemps;
624 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000625 case GL_PROGRAM_PARAMETERS_ARB:
626 *params = prog->NumParameters;
Brian Paul05051032005-11-01 04:36:33 +0000627 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000628 case GL_MAX_PROGRAM_PARAMETERS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000629 *params = limits->MaxParameters;
630 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000631 case GL_PROGRAM_NATIVE_PARAMETERS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000632 *params = prog->NumNativeParameters;
633 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000634 case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000635 *params = limits->MaxNativeParameters;
636 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000637 case GL_PROGRAM_ATTRIBS_ARB:
638 *params = prog->NumAttributes;
Brian Paul05051032005-11-01 04:36:33 +0000639 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000640 case GL_MAX_PROGRAM_ATTRIBS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000641 *params = limits->MaxAttribs;
642 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000643 case GL_PROGRAM_NATIVE_ATTRIBS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000644 *params = prog->NumNativeAttributes;
645 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000646 case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000647 *params = limits->MaxNativeAttribs;
648 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000649 case GL_PROGRAM_ADDRESS_REGISTERS_ARB:
650 *params = prog->NumAddressRegs;
Brian Paul05051032005-11-01 04:36:33 +0000651 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000652 case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000653 *params = limits->MaxAddressRegs;
654 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000655 case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000656 *params = prog->NumNativeAddressRegs;
657 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000658 case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000659 *params = limits->MaxNativeAddressRegs;
660 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000661 case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000662 *params = limits->MaxLocalParams;
663 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000664 case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000665 *params = limits->MaxEnvParams;
666 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000667 case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000668 /*
669 * XXX we may not really need a driver callback here.
670 * If the number of native instructions, registers, etc. used
671 * are all below the maximums, we could return true.
672 * The spec says that even if this query returns true, there's
673 * no guarantee that the program will run in hardware.
674 */
Michal Krol157ec8b2004-03-10 18:02:01 +0000675 if (ctx->Driver.IsProgramNative)
676 *params = ctx->Driver.IsProgramNative( ctx, target, prog );
677 else
678 *params = GL_TRUE;
Michal Krol157ec8b2004-03-10 18:02:01 +0000679 return;
Brian Paul05051032005-11-01 04:36:33 +0000680 default:
681 /* continue with fragment-program only queries below */
682 break;
683 }
684
685 /*
686 * The following apply to fragment programs only (at this time)
687 */
688 if (target == GL_FRAGMENT_PROGRAM_ARB) {
Brian Paul122629f2006-07-20 16:49:57 +0000689 const struct gl_fragment_program *fp = ctx->FragmentProgram.Current;
Brian Paul05051032005-11-01 04:36:33 +0000690 switch (pname) {
691 case GL_PROGRAM_ALU_INSTRUCTIONS_ARB:
692 *params = fp->NumNativeAluInstructions;
693 return;
694 case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
695 *params = fp->NumAluInstructions;
696 return;
697 case GL_PROGRAM_TEX_INSTRUCTIONS_ARB:
698 *params = fp->NumTexInstructions;
699 return;
700 case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
701 *params = fp->NumNativeTexInstructions;
702 return;
703 case GL_PROGRAM_TEX_INDIRECTIONS_ARB:
704 *params = fp->NumTexIndirections;
705 return;
706 case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
707 *params = fp->NumNativeTexIndirections;
708 return;
709 case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB:
710 *params = limits->MaxAluInstructions;
711 return;
712 case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
713 *params = limits->MaxNativeAluInstructions;
714 return;
715 case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB:
716 *params = limits->MaxTexInstructions;
717 return;
718 case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
719 *params = limits->MaxNativeTexInstructions;
720 return;
721 case GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB:
722 *params = limits->MaxTexIndirections;
723 return;
724 case GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
725 *params = limits->MaxNativeTexIndirections;
726 return;
727 default:
728 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(pname)");
729 return;
730 }
Michal Krol157ec8b2004-03-10 18:02:01 +0000731 }
732}
733
734
735void GLAPIENTRY
736_mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string)
737{
Brian Paul122629f2006-07-20 16:49:57 +0000738 const struct gl_program *prog;
Michal Krol157ec8b2004-03-10 18:02:01 +0000739 GET_CURRENT_CONTEXT(ctx);
740
741 if (!ctx->_CurrentProgram)
742 ASSERT_OUTSIDE_BEGIN_END(ctx);
743
744 if (target == GL_VERTEX_PROGRAM_ARB) {
745 prog = &(ctx->VertexProgram.Current->Base);
746 }
747 else if (target == GL_FRAGMENT_PROGRAM_ARB) {
748 prog = &(ctx->FragmentProgram.Current->Base);
749 }
750 else {
751 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(target)");
752 return;
753 }
754
755 ASSERT(prog);
756
757 if (pname != GL_PROGRAM_STRING_ARB) {
758 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(pname)");
759 return;
760 }
761
Brian Paul05051032005-11-01 04:36:33 +0000762 _mesa_memcpy(string, prog->String, _mesa_strlen((char *) prog->String));
Michal Krol157ec8b2004-03-10 18:02:01 +0000763}