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