glBindProgramARB dispatches to glBindProgramNV (remove _mesa_BindProgramARB).
[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 COPY_4V(params, ctx->Current.Attrib[index]);
146 break;
147 default:
148 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribfvARB(pname)");
149 return;
150 }
151 }
152
153
154 void
155 _mesa_GetVertexAttribivARB(GLuint index, GLenum pname, GLint *params)
156 {
157 GLfloat fparams[4];
158 GET_CURRENT_CONTEXT(ctx);
159 ASSERT_OUTSIDE_BEGIN_END(ctx);
160
161 _mesa_GetVertexAttribfvARB(index, pname, fparams);
162 if (ctx->ErrorValue == GL_NO_ERROR) {
163 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
164 COPY_4V(params, fparams); /* float to int */
165 }
166 else {
167 params[0] = fparams[0];
168 }
169 }
170 }
171
172
173 void
174 _mesa_GetVertexAttribPointervARB(GLuint index, GLenum pname, GLvoid **pointer)
175 {
176 GET_CURRENT_CONTEXT(ctx);
177 ASSERT_OUTSIDE_BEGIN_END(ctx);
178
179 if (index >= ctx->Const.MaxVertexProgramAttribs) {
180 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerARB(index)");
181 return;
182 }
183
184 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) {
185 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerARB(pname)");
186 return;
187 }
188
189 *pointer = ctx->Array.VertexAttrib[index].Ptr;;
190 }
191
192
193 void
194 _mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
195 const GLvoid *string)
196 {
197 GET_CURRENT_CONTEXT(ctx);
198 ASSERT_OUTSIDE_BEGIN_END(ctx);
199
200 if (target == GL_VERTEX_PROGRAM_ARB
201 && ctx->Extensions.ARB_vertex_program) {
202 struct vertex_program *prog = ctx->VertexProgram.Current;
203 if (format != GL_PROGRAM_FORMAT_ASCII_ARB) {
204 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(format)");
205 return;
206 }
207 _mesa_parse_arb_vertex_program(ctx, target, string, len, prog);
208 }
209 else if (target == GL_FRAGMENT_PROGRAM_ARB
210 && ctx->Extensions.ARB_fragment_program) {
211 struct fragment_program *prog = ctx->FragmentProgram.Current;
212 if (format != GL_PROGRAM_FORMAT_ASCII_ARB) {
213 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(format)");
214 return;
215 }
216 _mesa_parse_arb_fragment_program(ctx, target, string, len, prog);
217 }
218 else {
219 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(target)");
220 }
221 }
222
223
224 void
225 _mesa_ProgramEnvParameter4dARB(GLenum target, GLuint index,
226 GLdouble x, GLdouble y, GLdouble z, GLdouble w)
227 {
228 _mesa_ProgramEnvParameter4fARB(target, index, x, y, z, w);
229 }
230
231
232 void
233 _mesa_ProgramEnvParameter4dvARB(GLenum target, GLuint index,
234 const GLdouble *params)
235 {
236 _mesa_ProgramEnvParameter4fARB(target, index, params[0], params[1],
237 params[2], params[3]);
238 }
239
240
241 void
242 _mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index,
243 GLfloat x, GLfloat y, GLfloat z, GLfloat w)
244 {
245 GET_CURRENT_CONTEXT(ctx);
246 ASSERT_OUTSIDE_BEGIN_END(ctx);
247
248 if (target == GL_FRAGMENT_PROGRAM_ARB
249 && ctx->Extensions.ARB_fragment_program) {
250 if (index >= ctx->Const.MaxFragmentProgramEnvParams) {
251 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
252 return;
253 }
254 index += FP_PROG_REG_START;
255 ASSIGN_4V(ctx->FragmentProgram.Machine.Registers[index], x, y, z, w);
256 }
257 if (target == GL_VERTEX_PROGRAM_ARB
258 && ctx->Extensions.ARB_vertex_program) {
259 if (index >= ctx->Const.MaxVertexProgramEnvParams) {
260 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
261 return;
262 }
263 index += VP_PROG_REG_START;
264 ASSIGN_4V(ctx->VertexProgram.Machine.Registers[index], x, y, z, w);
265 }
266 else {
267 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameter(target)");
268 return;
269 }
270 }
271
272
273 void
274 _mesa_ProgramEnvParameter4fvARB(GLenum target, GLuint index,
275 const GLfloat *params)
276 {
277 _mesa_ProgramEnvParameter4fARB(target, index, params[0], params[1],
278 params[2], params[3]);
279 }
280
281
282 void
283 _mesa_GetProgramEnvParameterdvARB(GLenum target, GLuint index,
284 GLdouble *params)
285 {
286 GET_CURRENT_CONTEXT(ctx);
287 GLfloat fparams[4];
288
289 _mesa_GetProgramEnvParameterfvARB(target, index, fparams);
290 if (ctx->ErrorValue == GL_NO_ERROR) {
291 params[0] = fparams[0];
292 params[1] = fparams[1];
293 params[2] = fparams[2];
294 params[3] = fparams[3];
295 }
296 }
297
298
299 void
300 _mesa_GetProgramEnvParameterfvARB(GLenum target, GLuint index,
301 GLfloat *params)
302 {
303 GET_CURRENT_CONTEXT(ctx);
304 ASSERT_OUTSIDE_BEGIN_END(ctx);
305
306 if (target == GL_FRAGMENT_PROGRAM_ARB
307 && ctx->Extensions.ARB_fragment_program) {
308 if (index >= ctx->Const.MaxFragmentProgramEnvParams) {
309 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
310 return;
311 }
312 index += FP_PROG_REG_START;
313 COPY_4V(params, ctx->FragmentProgram.Machine.Registers[index]);
314 }
315 if (target == GL_VERTEX_PROGRAM_ARB
316 && ctx->Extensions.ARB_vertex_program) {
317 if (index >= ctx->Const.MaxVertexProgramEnvParams) {
318 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
319 return;
320 }
321 index += VP_PROG_REG_START;
322 COPY_4V(params, ctx->VertexProgram.Machine.Registers[index]);
323 }
324 else {
325 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramEnvParameter(target)");
326 return;
327 }
328 }
329
330
331 /**
332 * Note, this function is also used by the GL_NV_fragment_program extension.
333 */
334 void
335 _mesa_ProgramLocalParameter4fARB(GLenum target, GLuint index,
336 GLfloat x, GLfloat y, GLfloat z, GLfloat w)
337 {
338 GET_CURRENT_CONTEXT(ctx);
339 struct program *prog;
340 ASSERT_OUTSIDE_BEGIN_END(ctx);
341
342 if ((target == GL_FRAGMENT_PROGRAM_NV
343 && ctx->Extensions.NV_fragment_program) ||
344 (target == GL_FRAGMENT_PROGRAM_ARB
345 && ctx->Extensions.ARB_fragment_program)) {
346 if (index >= ctx->Const.MaxFragmentProgramLocalParams) {
347 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
348 return;
349 }
350 prog = &(ctx->FragmentProgram.Current->Base);
351 }
352 else if (target == GL_VERTEX_PROGRAM_ARB
353 && ctx->Extensions.ARB_vertex_program) {
354 if (index >= ctx->Const.MaxVertexProgramLocalParams) {
355 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
356 return;
357 }
358 prog = &(ctx->VertexProgram.Current->Base);
359 }
360 else {
361 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameterARB");
362 return;
363 }
364
365 ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS);
366 prog->LocalParams[index][0] = x;
367 prog->LocalParams[index][1] = y;
368 prog->LocalParams[index][2] = z;
369 prog->LocalParams[index][3] = w;
370 }
371
372
373 /**
374 * Note, this function is also used by the GL_NV_fragment_program extension.
375 */
376 void
377 _mesa_ProgramLocalParameter4fvARB(GLenum target, GLuint index,
378 const GLfloat *params)
379 {
380 _mesa_ProgramLocalParameter4fARB(target, index, params[0], params[1],
381 params[2], params[3]);
382 }
383
384
385 /**
386 * Note, this function is also used by the GL_NV_fragment_program extension.
387 */
388 void
389 _mesa_ProgramLocalParameter4dARB(GLenum target, GLuint index,
390 GLdouble x, GLdouble y,
391 GLdouble z, GLdouble w)
392 {
393 _mesa_ProgramLocalParameter4fARB(target, index, (GLfloat) x, (GLfloat) y,
394 (GLfloat) z, (GLfloat) w);
395 }
396
397
398 /**
399 * Note, this function is also used by the GL_NV_fragment_program extension.
400 */
401 void
402 _mesa_ProgramLocalParameter4dvARB(GLenum target, GLuint index,
403 const GLdouble *params)
404 {
405 _mesa_ProgramLocalParameter4fARB(target, index,
406 (GLfloat) params[0], (GLfloat) params[1],
407 (GLfloat) params[2], (GLfloat) params[3]);
408 }
409
410
411 /**
412 * Note, this function is also used by the GL_NV_fragment_program extension.
413 */
414 void
415 _mesa_GetProgramLocalParameterfvARB(GLenum target, GLuint index,
416 GLfloat *params)
417 {
418 const struct program *prog;
419 GLuint maxParams;
420 GET_CURRENT_CONTEXT(ctx);
421 ASSERT_OUTSIDE_BEGIN_END(ctx);
422
423 if (target == GL_VERTEX_PROGRAM_ARB
424 && ctx->Extensions.ARB_vertex_program) {
425 prog = &(ctx->VertexProgram.Current->Base);
426 maxParams = ctx->Const.MaxVertexProgramLocalParams;
427 }
428 else if (target == GL_FRAGMENT_PROGRAM_ARB
429 && ctx->Extensions.ARB_fragment_program) {
430 prog = &(ctx->FragmentProgram.Current->Base);
431 maxParams = ctx->Const.MaxFragmentProgramLocalParams;
432 }
433 else if (target == GL_FRAGMENT_PROGRAM_NV
434 && ctx->Extensions.NV_fragment_program) {
435 prog = &(ctx->FragmentProgram.Current->Base);
436 maxParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
437 }
438 else {
439 _mesa_error(ctx, GL_INVALID_ENUM,
440 "glGetProgramLocalParameterARB(target)");
441 return;
442 }
443
444 if (index >= maxParams) {
445 _mesa_error(ctx, GL_INVALID_VALUE,
446 "glGetProgramLocalParameterARB(index)");
447 return;
448 }
449
450 ASSERT(prog);
451 ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS);
452 COPY_4V(params, prog->LocalParams[index]);
453 }
454
455
456 /**
457 * Note, this function is also used by the GL_NV_fragment_program extension.
458 */
459 void
460 _mesa_GetProgramLocalParameterdvARB(GLenum target, GLuint index,
461 GLdouble *params)
462 {
463 GET_CURRENT_CONTEXT(ctx);
464 GLfloat floatParams[4];
465 _mesa_GetProgramLocalParameterfvARB(target, index, floatParams);
466 if (ctx->ErrorValue == GL_NO_ERROR) {
467 COPY_4V(params, floatParams);
468 }
469 }
470
471
472 void
473 _mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params)
474 {
475 struct program *prog;
476 GET_CURRENT_CONTEXT(ctx);
477 ASSERT_OUTSIDE_BEGIN_END(ctx);
478
479 if (target == GL_VERTEX_PROGRAM_ARB
480 && ctx->Extensions.ARB_vertex_program) {
481 prog = &(ctx->VertexProgram.Current->Base);
482 }
483 else if (target == GL_FRAGMENT_PROGRAM_ARB
484 && ctx->Extensions.ARB_vertex_program) {
485 prog = &(ctx->FragmentProgram.Current->Base);
486 }
487 else {
488 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
489 return;
490 }
491
492 ASSERT(prog);
493
494 switch (pname) {
495 case GL_PROGRAM_LENGTH_ARB:
496 *params = prog->String ? _mesa_strlen((char *) prog->String) : 0;
497 break;
498 case GL_PROGRAM_FORMAT_ARB:
499 *params = prog->Format;
500 break;
501 case GL_PROGRAM_BINDING_ARB:
502 *params = prog->Id;
503 break;
504 case GL_PROGRAM_INSTRUCTIONS_ARB:
505 *params = prog->NumInstructions;
506 break;
507 case GL_MAX_PROGRAM_INSTRUCTIONS_ARB:
508 if (target == GL_VERTEX_PROGRAM_ARB)
509 *params = ctx->Const.MaxVertexProgramInstructions;
510 else
511 *params = ctx->Const.MaxFragmentProgramInstructions;
512 break;
513 case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
514 *params = prog->NumInstructions;
515 break;
516 case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
517 if (target == GL_VERTEX_PROGRAM_ARB)
518 *params = ctx->Const.MaxVertexProgramInstructions;
519 else
520 *params = ctx->Const.MaxFragmentProgramInstructions;
521 break;
522 case GL_PROGRAM_TEMPORARIES_ARB:
523 *params = prog->NumTemporaries;
524 break;
525 case GL_MAX_PROGRAM_TEMPORARIES_ARB:
526 if (target == GL_VERTEX_PROGRAM_ARB)
527 *params = ctx->Const.MaxVertexProgramTemps;
528 else
529 *params = ctx->Const.MaxFragmentProgramTemps;
530 break;
531 case GL_PROGRAM_NATIVE_TEMPORARIES_ARB:
532 /* XXX same as GL_PROGRAM_TEMPORARIES_ARB? */
533 *params = prog->NumTemporaries;
534 break;
535 case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB:
536 /* XXX same as GL_MAX_PROGRAM_TEMPORARIES_ARB? */
537 if (target == GL_VERTEX_PROGRAM_ARB)
538 *params = ctx->Const.MaxVertexProgramTemps;
539 else
540 *params = ctx->Const.MaxFragmentProgramTemps;
541 break;
542 case GL_PROGRAM_PARAMETERS_ARB:
543 *params = prog->NumParameters;
544 break;
545 case GL_MAX_PROGRAM_PARAMETERS_ARB:
546 if (target == GL_VERTEX_PROGRAM_ARB)
547 *params = ctx->Const.MaxVertexProgramLocalParams;
548 else
549 *params = ctx->Const.MaxFragmentProgramLocalParams;
550 break;
551 case GL_PROGRAM_NATIVE_PARAMETERS_ARB:
552 /* XXX same as GL_MAX_PROGRAM_PARAMETERS_ARB? */
553 *params = prog->NumParameters;
554 break;
555 case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB:
556 /* XXX same as GL_MAX_PROGRAM_PARAMETERS_ARB? */
557 if (target == GL_VERTEX_PROGRAM_ARB)
558 *params = ctx->Const.MaxVertexProgramLocalParams;
559 else
560 *params = ctx->Const.MaxFragmentProgramLocalParams;
561 break;
562 case GL_PROGRAM_ATTRIBS_ARB:
563 *params = prog->NumAttributes;
564 break;
565 case GL_MAX_PROGRAM_ATTRIBS_ARB:
566 if (target == GL_VERTEX_PROGRAM_ARB)
567 *params = ctx->Const.MaxVertexProgramAttribs;
568 else
569 *params = ctx->Const.MaxFragmentProgramAttribs;
570 break;
571 case GL_PROGRAM_NATIVE_ATTRIBS_ARB:
572 /* XXX same as GL_PROGRAM_ATTRIBS_ARB? */
573 *params = prog->NumAttributes;
574 break;
575 case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB:
576 /* XXX same as GL_MAX_PROGRAM_ATTRIBS_ARB? */
577 if (target == GL_VERTEX_PROGRAM_ARB)
578 *params = ctx->Const.MaxVertexProgramAttribs;
579 else
580 *params = ctx->Const.MaxFragmentProgramAttribs;
581 break;
582 case GL_PROGRAM_ADDRESS_REGISTERS_ARB:
583 *params = prog->NumAddressRegs;
584 break;
585 case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB:
586 if (target == GL_VERTEX_PROGRAM_ARB)
587 *params = ctx->Const.MaxVertexProgramAddressRegs;
588 else
589 *params = ctx->Const.MaxFragmentProgramAddressRegs;
590 break;
591 case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
592 /* XXX same as GL_PROGRAM_ADDRESS_REGISTERS_ARB? */
593 *params = prog->NumAddressRegs;
594 break;
595 case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
596 /* XXX same as GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB? */
597 if (target == GL_VERTEX_PROGRAM_ARB)
598 *params = ctx->Const.MaxVertexProgramAddressRegs;
599 else
600 *params = ctx->Const.MaxFragmentProgramAddressRegs;
601 break;
602 case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB:
603 if (target == GL_VERTEX_PROGRAM_ARB)
604 *params = ctx->Const.MaxVertexProgramLocalParams;
605 else
606 *params = ctx->Const.MaxFragmentProgramLocalParams;
607 break;
608 case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB:
609 if (target == GL_VERTEX_PROGRAM_ARB)
610 *params = ctx->Const.MaxVertexProgramEnvParams;
611 else
612 *params = ctx->Const.MaxFragmentProgramEnvParams;
613 break;
614 case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB:
615 /* XXX ok? */
616 *params = GL_TRUE;
617 break;
618
619 /*
620 * The following apply to fragment programs only.
621 */
622 case GL_PROGRAM_ALU_INSTRUCTIONS_ARB:
623 case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
624 if (target != GL_FRAGMENT_PROGRAM_ARB) {
625 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
626 return;
627 }
628 *params = ctx->FragmentProgram.Current->NumAluInstructions;
629 break;
630 case GL_PROGRAM_TEX_INSTRUCTIONS_ARB:
631 case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
632 if (target != GL_FRAGMENT_PROGRAM_ARB) {
633 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
634 return;
635 }
636 *params = ctx->FragmentProgram.Current->NumTexInstructions;
637 break;
638 case GL_PROGRAM_TEX_INDIRECTIONS_ARB:
639 case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
640 if (target != GL_FRAGMENT_PROGRAM_ARB) {
641 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
642 return;
643 }
644 *params = ctx->FragmentProgram.Current->NumTexIndirections;
645 break;
646 case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB:
647 case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
648 if (target != GL_FRAGMENT_PROGRAM_ARB) {
649 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
650 return;
651 }
652 *params = ctx->Const.MaxFragmentProgramAluInstructions;
653 break;
654 case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB:
655 case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
656 if (target != GL_FRAGMENT_PROGRAM_ARB) {
657 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
658 return;
659 }
660 *params = ctx->Const.MaxFragmentProgramTexInstructions;
661 break;
662 case GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB:
663 case GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
664 if (target != GL_FRAGMENT_PROGRAM_ARB) {
665 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
666 return;
667 }
668 *params = ctx->Const.MaxFragmentProgramTexIndirections;
669 break;
670 default:
671 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(pname)");
672 return;
673 }
674 }
675
676
677 void
678 _mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string)
679 {
680 struct program *prog;
681 GET_CURRENT_CONTEXT(ctx);
682 ASSERT_OUTSIDE_BEGIN_END(ctx);
683
684 if (target == GL_VERTEX_PROGRAM_ARB) {
685 prog = &(ctx->VertexProgram.Current->Base);
686 }
687 else if (target == GL_FRAGMENT_PROGRAM_ARB) {
688 prog = &(ctx->FragmentProgram.Current->Base);
689 }
690 else {
691 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(target)");
692 return;
693 }
694
695 ASSERT(prog);
696
697 if (pname != GL_PROGRAM_STRING_ARB) {
698 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(pname)");
699 return;
700 }
701
702 MEMCPY(string, prog->String, _mesa_strlen((char *) prog->String));
703 }