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