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