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