fix GL_CURRENT_VERTEX_ATTRIB_ARB queries
[mesa.git] / src / mesa / main / arbprogram.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 5.1
4 *
5 * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /**
26 * \file arbprogram.c
27 * \brief ARB_vertex/fragment_program state management functions.
28 * \author Brian Paul
29 */
30
31
32 #include "glheader.h"
33 #include "arbprogram.h"
34 #include "context.h"
35 #include "hash.h"
36 #include "imports.h"
37 #include "macros.h"
38 #include "mtypes.h"
39 #include "nvprogram.h"
40 #include "nvfragprog.h"
41 #include "nvvertprog.h"
42
43
44 /* XXX temporary */
45 static void
46 _mesa_parse_arb_vertex_program(GLcontext *ctx, GLenum target,
47 const GLubyte *string, GLsizei len,
48 struct vertex_program *prog)
49 {
50 }
51
52
53 static void
54 _mesa_parse_arb_fragment_program(GLcontext *ctx, GLenum target,
55 const GLubyte *string, GLsizei len,
56 struct fragment_program *prog)
57 {
58 }
59
60
61
62 void
63 _mesa_EnableVertexAttribArrayARB(GLuint index)
64 {
65 GET_CURRENT_CONTEXT(ctx);
66 ASSERT_OUTSIDE_BEGIN_END(ctx);
67
68 if (index >= ctx->Const.MaxVertexProgramAttribs) {
69 _mesa_error(ctx, GL_INVALID_VALUE,
70 "glEnableVertexAttribArrayARB(index)");
71 return;
72 }
73
74 ctx->Array.VertexAttrib[index].Enabled = GL_TRUE;
75 ctx->Array._Enabled |= _NEW_ARRAY_ATTRIB(index);
76 ctx->Array.NewState |= _NEW_ARRAY_ATTRIB(index);
77 }
78
79
80 void
81 _mesa_DisableVertexAttribArrayARB(GLuint index)
82 {
83 GET_CURRENT_CONTEXT(ctx);
84 ASSERT_OUTSIDE_BEGIN_END(ctx);
85
86 if (index >= ctx->Const.MaxVertexProgramAttribs) {
87 _mesa_error(ctx, GL_INVALID_VALUE,
88 "glEnableVertexAttribArrayARB(index)");
89 return;
90 }
91
92 ctx->Array.VertexAttrib[index].Enabled = GL_FALSE;
93 ctx->Array._Enabled &= ~_NEW_ARRAY_ATTRIB(index);
94 ctx->Array.NewState |= _NEW_ARRAY_ATTRIB(index);
95 }
96
97
98 void
99 _mesa_GetVertexAttribdvARB(GLuint index, GLenum pname, GLdouble *params)
100 {
101 GLfloat fparams[4];
102 GET_CURRENT_CONTEXT(ctx);
103 ASSERT_OUTSIDE_BEGIN_END(ctx);
104
105 _mesa_GetVertexAttribfvARB(index, pname, fparams);
106 if (ctx->ErrorValue == GL_NO_ERROR) {
107 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
108 COPY_4V(params, fparams);
109 }
110 else {
111 params[0] = fparams[0];
112 }
113 }
114 }
115
116
117 void
118 _mesa_GetVertexAttribfvARB(GLuint index, GLenum pname, GLfloat *params)
119 {
120 GET_CURRENT_CONTEXT(ctx);
121 ASSERT_OUTSIDE_BEGIN_END(ctx);
122
123 if (index == 0 || index >= VERT_ATTRIB_MAX) {
124 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribfvARB(index)");
125 return;
126 }
127
128 switch (pname) {
129 case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB:
130 params[0] = ctx->Array.VertexAttrib[index].Enabled;
131 break;
132 case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB:
133 params[0] = ctx->Array.VertexAttrib[index].Size;
134 break;
135 case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB:
136 params[0] = ctx->Array.VertexAttrib[index].Stride;
137 break;
138 case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB:
139 params[0] = ctx->Array.VertexAttrib[index].Type;
140 break;
141 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB:
142 params[0] = ctx->Array.VertexAttrib[index].Normalized;
143 break;
144 case GL_CURRENT_VERTEX_ATTRIB_ARB:
145 FLUSH_CURRENT(ctx, 0);
146 COPY_4V(params, ctx->Current.Attrib[index]);
147 break;
148 default:
149 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribfvARB(pname)");
150 return;
151 }
152 }
153
154
155 void
156 _mesa_GetVertexAttribivARB(GLuint index, GLenum pname, GLint *params)
157 {
158 GLfloat fparams[4];
159 GET_CURRENT_CONTEXT(ctx);
160 ASSERT_OUTSIDE_BEGIN_END(ctx);
161
162 _mesa_GetVertexAttribfvARB(index, pname, fparams);
163 if (ctx->ErrorValue == GL_NO_ERROR) {
164 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
165 COPY_4V(params, fparams); /* float to int */
166 }
167 else {
168 params[0] = fparams[0];
169 }
170 }
171 }
172
173
174 void
175 _mesa_GetVertexAttribPointervARB(GLuint index, GLenum pname, GLvoid **pointer)
176 {
177 GET_CURRENT_CONTEXT(ctx);
178 ASSERT_OUTSIDE_BEGIN_END(ctx);
179
180 if (index >= ctx->Const.MaxVertexProgramAttribs) {
181 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerARB(index)");
182 return;
183 }
184
185 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) {
186 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerARB(pname)");
187 return;
188 }
189
190 *pointer = ctx->Array.VertexAttrib[index].Ptr;;
191 }
192
193
194 void
195 _mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
196 const GLvoid *string)
197 {
198 GET_CURRENT_CONTEXT(ctx);
199 ASSERT_OUTSIDE_BEGIN_END(ctx);
200
201 if (target == GL_VERTEX_PROGRAM_ARB
202 && ctx->Extensions.ARB_vertex_program) {
203 struct vertex_program *prog = ctx->VertexProgram.Current;
204 if (format != GL_PROGRAM_FORMAT_ASCII_ARB) {
205 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(format)");
206 return;
207 }
208 _mesa_parse_arb_vertex_program(ctx, target, string, len, prog);
209 }
210 else if (target == GL_FRAGMENT_PROGRAM_ARB
211 && ctx->Extensions.ARB_fragment_program) {
212 struct fragment_program *prog = ctx->FragmentProgram.Current;
213 if (format != GL_PROGRAM_FORMAT_ASCII_ARB) {
214 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(format)");
215 return;
216 }
217 _mesa_parse_arb_fragment_program(ctx, target, string, len, prog);
218 }
219 else {
220 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(target)");
221 }
222 }
223
224
225 void
226 _mesa_ProgramEnvParameter4dARB(GLenum target, GLuint index,
227 GLdouble x, GLdouble y, GLdouble z, GLdouble w)
228 {
229 _mesa_ProgramEnvParameter4fARB(target, index, x, y, z, w);
230 }
231
232
233 void
234 _mesa_ProgramEnvParameter4dvARB(GLenum target, GLuint index,
235 const GLdouble *params)
236 {
237 _mesa_ProgramEnvParameter4fARB(target, index, params[0], params[1],
238 params[2], params[3]);
239 }
240
241
242 void
243 _mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index,
244 GLfloat x, GLfloat y, GLfloat z, GLfloat w)
245 {
246 GET_CURRENT_CONTEXT(ctx);
247 ASSERT_OUTSIDE_BEGIN_END(ctx);
248
249 if (target == GL_FRAGMENT_PROGRAM_ARB
250 && ctx->Extensions.ARB_fragment_program) {
251 if (index >= ctx->Const.MaxFragmentProgramEnvParams) {
252 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
253 return;
254 }
255 index += FP_PROG_REG_START;
256 ASSIGN_4V(ctx->FragmentProgram.Machine.Registers[index], x, y, z, w);
257 }
258 if (target == GL_VERTEX_PROGRAM_ARB
259 && ctx->Extensions.ARB_vertex_program) {
260 if (index >= ctx->Const.MaxVertexProgramEnvParams) {
261 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
262 return;
263 }
264 index += VP_PROG_REG_START;
265 ASSIGN_4V(ctx->VertexProgram.Machine.Registers[index], x, y, z, w);
266 }
267 else {
268 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameter(target)");
269 return;
270 }
271 }
272
273
274 void
275 _mesa_ProgramEnvParameter4fvARB(GLenum target, GLuint index,
276 const GLfloat *params)
277 {
278 _mesa_ProgramEnvParameter4fARB(target, index, params[0], params[1],
279 params[2], params[3]);
280 }
281
282
283 void
284 _mesa_GetProgramEnvParameterdvARB(GLenum target, GLuint index,
285 GLdouble *params)
286 {
287 GET_CURRENT_CONTEXT(ctx);
288 GLfloat fparams[4];
289
290 _mesa_GetProgramEnvParameterfvARB(target, index, fparams);
291 if (ctx->ErrorValue == GL_NO_ERROR) {
292 params[0] = fparams[0];
293 params[1] = fparams[1];
294 params[2] = fparams[2];
295 params[3] = fparams[3];
296 }
297 }
298
299
300 void
301 _mesa_GetProgramEnvParameterfvARB(GLenum target, GLuint index,
302 GLfloat *params)
303 {
304 GET_CURRENT_CONTEXT(ctx);
305 ASSERT_OUTSIDE_BEGIN_END(ctx);
306
307 if (target == GL_FRAGMENT_PROGRAM_ARB
308 && ctx->Extensions.ARB_fragment_program) {
309 if (index >= ctx->Const.MaxFragmentProgramEnvParams) {
310 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
311 return;
312 }
313 index += FP_PROG_REG_START;
314 COPY_4V(params, ctx->FragmentProgram.Machine.Registers[index]);
315 }
316 if (target == GL_VERTEX_PROGRAM_ARB
317 && ctx->Extensions.ARB_vertex_program) {
318 if (index >= ctx->Const.MaxVertexProgramEnvParams) {
319 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
320 return;
321 }
322 index += VP_PROG_REG_START;
323 COPY_4V(params, ctx->VertexProgram.Machine.Registers[index]);
324 }
325 else {
326 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramEnvParameter(target)");
327 return;
328 }
329 }
330
331
332 /**
333 * Note, this function is also used by the GL_NV_fragment_program extension.
334 */
335 void
336 _mesa_ProgramLocalParameter4fARB(GLenum target, GLuint index,
337 GLfloat x, GLfloat y, GLfloat z, GLfloat w)
338 {
339 GET_CURRENT_CONTEXT(ctx);
340 struct program *prog;
341 ASSERT_OUTSIDE_BEGIN_END(ctx);
342
343 if ((target == GL_FRAGMENT_PROGRAM_NV
344 && ctx->Extensions.NV_fragment_program) ||
345 (target == GL_FRAGMENT_PROGRAM_ARB
346 && ctx->Extensions.ARB_fragment_program)) {
347 if (index >= ctx->Const.MaxFragmentProgramLocalParams) {
348 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
349 return;
350 }
351 prog = &(ctx->FragmentProgram.Current->Base);
352 }
353 else if (target == GL_VERTEX_PROGRAM_ARB
354 && ctx->Extensions.ARB_vertex_program) {
355 if (index >= ctx->Const.MaxVertexProgramLocalParams) {
356 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
357 return;
358 }
359 prog = &(ctx->VertexProgram.Current->Base);
360 }
361 else {
362 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameterARB");
363 return;
364 }
365
366 ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS);
367 prog->LocalParams[index][0] = x;
368 prog->LocalParams[index][1] = y;
369 prog->LocalParams[index][2] = z;
370 prog->LocalParams[index][3] = w;
371 }
372
373
374 /**
375 * Note, this function is also used by the GL_NV_fragment_program extension.
376 */
377 void
378 _mesa_ProgramLocalParameter4fvARB(GLenum target, GLuint index,
379 const GLfloat *params)
380 {
381 _mesa_ProgramLocalParameter4fARB(target, index, params[0], params[1],
382 params[2], params[3]);
383 }
384
385
386 /**
387 * Note, this function is also used by the GL_NV_fragment_program extension.
388 */
389 void
390 _mesa_ProgramLocalParameter4dARB(GLenum target, GLuint index,
391 GLdouble x, GLdouble y,
392 GLdouble z, GLdouble w)
393 {
394 _mesa_ProgramLocalParameter4fARB(target, index, (GLfloat) x, (GLfloat) y,
395 (GLfloat) z, (GLfloat) w);
396 }
397
398
399 /**
400 * Note, this function is also used by the GL_NV_fragment_program extension.
401 */
402 void
403 _mesa_ProgramLocalParameter4dvARB(GLenum target, GLuint index,
404 const GLdouble *params)
405 {
406 _mesa_ProgramLocalParameter4fARB(target, index,
407 (GLfloat) params[0], (GLfloat) params[1],
408 (GLfloat) params[2], (GLfloat) params[3]);
409 }
410
411
412 /**
413 * Note, this function is also used by the GL_NV_fragment_program extension.
414 */
415 void
416 _mesa_GetProgramLocalParameterfvARB(GLenum target, GLuint index,
417 GLfloat *params)
418 {
419 const struct program *prog;
420 GLuint maxParams;
421 GET_CURRENT_CONTEXT(ctx);
422 ASSERT_OUTSIDE_BEGIN_END(ctx);
423
424 if (target == GL_VERTEX_PROGRAM_ARB
425 && ctx->Extensions.ARB_vertex_program) {
426 prog = &(ctx->VertexProgram.Current->Base);
427 maxParams = ctx->Const.MaxVertexProgramLocalParams;
428 }
429 else if (target == GL_FRAGMENT_PROGRAM_ARB
430 && ctx->Extensions.ARB_fragment_program) {
431 prog = &(ctx->FragmentProgram.Current->Base);
432 maxParams = ctx->Const.MaxFragmentProgramLocalParams;
433 }
434 else if (target == GL_FRAGMENT_PROGRAM_NV
435 && ctx->Extensions.NV_fragment_program) {
436 prog = &(ctx->FragmentProgram.Current->Base);
437 maxParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
438 }
439 else {
440 _mesa_error(ctx, GL_INVALID_ENUM,
441 "glGetProgramLocalParameterARB(target)");
442 return;
443 }
444
445 if (index >= maxParams) {
446 _mesa_error(ctx, GL_INVALID_VALUE,
447 "glGetProgramLocalParameterARB(index)");
448 return;
449 }
450
451 ASSERT(prog);
452 ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS);
453 COPY_4V(params, prog->LocalParams[index]);
454 }
455
456
457 /**
458 * Note, this function is also used by the GL_NV_fragment_program extension.
459 */
460 void
461 _mesa_GetProgramLocalParameterdvARB(GLenum target, GLuint index,
462 GLdouble *params)
463 {
464 GET_CURRENT_CONTEXT(ctx);
465 GLfloat floatParams[4];
466 _mesa_GetProgramLocalParameterfvARB(target, index, floatParams);
467 if (ctx->ErrorValue == GL_NO_ERROR) {
468 COPY_4V(params, floatParams);
469 }
470 }
471
472
473 void
474 _mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params)
475 {
476 struct program *prog;
477 GET_CURRENT_CONTEXT(ctx);
478 ASSERT_OUTSIDE_BEGIN_END(ctx);
479
480 if (target == GL_VERTEX_PROGRAM_ARB
481 && ctx->Extensions.ARB_vertex_program) {
482 prog = &(ctx->VertexProgram.Current->Base);
483 }
484 else if (target == GL_FRAGMENT_PROGRAM_ARB
485 && ctx->Extensions.ARB_vertex_program) {
486 prog = &(ctx->FragmentProgram.Current->Base);
487 }
488 else {
489 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
490 return;
491 }
492
493 ASSERT(prog);
494
495 switch (pname) {
496 case GL_PROGRAM_LENGTH_ARB:
497 *params = prog->String ? _mesa_strlen((char *) prog->String) : 0;
498 break;
499 case GL_PROGRAM_FORMAT_ARB:
500 *params = prog->Format;
501 break;
502 case GL_PROGRAM_BINDING_ARB:
503 *params = prog->Id;
504 break;
505 case GL_PROGRAM_INSTRUCTIONS_ARB:
506 *params = prog->NumInstructions;
507 break;
508 case GL_MAX_PROGRAM_INSTRUCTIONS_ARB:
509 if (target == GL_VERTEX_PROGRAM_ARB)
510 *params = ctx->Const.MaxVertexProgramInstructions;
511 else
512 *params = ctx->Const.MaxFragmentProgramInstructions;
513 break;
514 case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
515 *params = prog->NumInstructions;
516 break;
517 case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
518 if (target == GL_VERTEX_PROGRAM_ARB)
519 *params = ctx->Const.MaxVertexProgramInstructions;
520 else
521 *params = ctx->Const.MaxFragmentProgramInstructions;
522 break;
523 case GL_PROGRAM_TEMPORARIES_ARB:
524 *params = prog->NumTemporaries;
525 break;
526 case GL_MAX_PROGRAM_TEMPORARIES_ARB:
527 if (target == GL_VERTEX_PROGRAM_ARB)
528 *params = ctx->Const.MaxVertexProgramTemps;
529 else
530 *params = ctx->Const.MaxFragmentProgramTemps;
531 break;
532 case GL_PROGRAM_NATIVE_TEMPORARIES_ARB:
533 /* XXX same as GL_PROGRAM_TEMPORARIES_ARB? */
534 *params = prog->NumTemporaries;
535 break;
536 case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB:
537 /* XXX same as GL_MAX_PROGRAM_TEMPORARIES_ARB? */
538 if (target == GL_VERTEX_PROGRAM_ARB)
539 *params = ctx->Const.MaxVertexProgramTemps;
540 else
541 *params = ctx->Const.MaxFragmentProgramTemps;
542 break;
543 case GL_PROGRAM_PARAMETERS_ARB:
544 *params = prog->NumParameters;
545 break;
546 case GL_MAX_PROGRAM_PARAMETERS_ARB:
547 if (target == GL_VERTEX_PROGRAM_ARB)
548 *params = ctx->Const.MaxVertexProgramLocalParams;
549 else
550 *params = ctx->Const.MaxFragmentProgramLocalParams;
551 break;
552 case GL_PROGRAM_NATIVE_PARAMETERS_ARB:
553 /* XXX same as GL_MAX_PROGRAM_PARAMETERS_ARB? */
554 *params = prog->NumParameters;
555 break;
556 case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB:
557 /* XXX same as GL_MAX_PROGRAM_PARAMETERS_ARB? */
558 if (target == GL_VERTEX_PROGRAM_ARB)
559 *params = ctx->Const.MaxVertexProgramLocalParams;
560 else
561 *params = ctx->Const.MaxFragmentProgramLocalParams;
562 break;
563 case GL_PROGRAM_ATTRIBS_ARB:
564 *params = prog->NumAttributes;
565 break;
566 case GL_MAX_PROGRAM_ATTRIBS_ARB:
567 if (target == GL_VERTEX_PROGRAM_ARB)
568 *params = ctx->Const.MaxVertexProgramAttribs;
569 else
570 *params = ctx->Const.MaxFragmentProgramAttribs;
571 break;
572 case GL_PROGRAM_NATIVE_ATTRIBS_ARB:
573 /* XXX same as GL_PROGRAM_ATTRIBS_ARB? */
574 *params = prog->NumAttributes;
575 break;
576 case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB:
577 /* XXX same as GL_MAX_PROGRAM_ATTRIBS_ARB? */
578 if (target == GL_VERTEX_PROGRAM_ARB)
579 *params = ctx->Const.MaxVertexProgramAttribs;
580 else
581 *params = ctx->Const.MaxFragmentProgramAttribs;
582 break;
583 case GL_PROGRAM_ADDRESS_REGISTERS_ARB:
584 *params = prog->NumAddressRegs;
585 break;
586 case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB:
587 if (target == GL_VERTEX_PROGRAM_ARB)
588 *params = ctx->Const.MaxVertexProgramAddressRegs;
589 else
590 *params = ctx->Const.MaxFragmentProgramAddressRegs;
591 break;
592 case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
593 /* XXX same as GL_PROGRAM_ADDRESS_REGISTERS_ARB? */
594 *params = prog->NumAddressRegs;
595 break;
596 case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
597 /* XXX same as GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB? */
598 if (target == GL_VERTEX_PROGRAM_ARB)
599 *params = ctx->Const.MaxVertexProgramAddressRegs;
600 else
601 *params = ctx->Const.MaxFragmentProgramAddressRegs;
602 break;
603 case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB:
604 if (target == GL_VERTEX_PROGRAM_ARB)
605 *params = ctx->Const.MaxVertexProgramLocalParams;
606 else
607 *params = ctx->Const.MaxFragmentProgramLocalParams;
608 break;
609 case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB:
610 if (target == GL_VERTEX_PROGRAM_ARB)
611 *params = ctx->Const.MaxVertexProgramEnvParams;
612 else
613 *params = ctx->Const.MaxFragmentProgramEnvParams;
614 break;
615 case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB:
616 /* XXX ok? */
617 *params = GL_TRUE;
618 break;
619
620 /*
621 * The following apply to fragment programs only.
622 */
623 case GL_PROGRAM_ALU_INSTRUCTIONS_ARB:
624 case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
625 if (target != GL_FRAGMENT_PROGRAM_ARB) {
626 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
627 return;
628 }
629 *params = ctx->FragmentProgram.Current->NumAluInstructions;
630 break;
631 case GL_PROGRAM_TEX_INSTRUCTIONS_ARB:
632 case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
633 if (target != GL_FRAGMENT_PROGRAM_ARB) {
634 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
635 return;
636 }
637 *params = ctx->FragmentProgram.Current->NumTexInstructions;
638 break;
639 case GL_PROGRAM_TEX_INDIRECTIONS_ARB:
640 case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
641 if (target != GL_FRAGMENT_PROGRAM_ARB) {
642 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
643 return;
644 }
645 *params = ctx->FragmentProgram.Current->NumTexIndirections;
646 break;
647 case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB:
648 case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
649 if (target != GL_FRAGMENT_PROGRAM_ARB) {
650 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
651 return;
652 }
653 *params = ctx->Const.MaxFragmentProgramAluInstructions;
654 break;
655 case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB:
656 case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
657 if (target != GL_FRAGMENT_PROGRAM_ARB) {
658 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
659 return;
660 }
661 *params = ctx->Const.MaxFragmentProgramTexInstructions;
662 break;
663 case GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB:
664 case GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
665 if (target != GL_FRAGMENT_PROGRAM_ARB) {
666 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
667 return;
668 }
669 *params = ctx->Const.MaxFragmentProgramTexIndirections;
670 break;
671 default:
672 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(pname)");
673 return;
674 }
675 }
676
677
678 void
679 _mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string)
680 {
681 struct program *prog;
682 GET_CURRENT_CONTEXT(ctx);
683 ASSERT_OUTSIDE_BEGIN_END(ctx);
684
685 if (target == GL_VERTEX_PROGRAM_ARB) {
686 prog = &(ctx->VertexProgram.Current->Base);
687 }
688 else if (target == GL_FRAGMENT_PROGRAM_ARB) {
689 prog = &(ctx->FragmentProgram.Current->Base);
690 }
691 else {
692 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(target)");
693 return;
694 }
695
696 ASSERT(prog);
697
698 if (pname != GL_PROGRAM_STRING_ARB) {
699 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(pname)");
700 return;
701 }
702
703 MEMCPY(string, prog->String, _mesa_strlen((char *) prog->String));
704 }