remove temporary prototypes
[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 /*
48 * Init context's program state
49 */
50 void
51 _mesa_init_program(GLcontext *ctx)
52 {
53 GLuint i;
54
55 ctx->Program.ErrorPos = -1;
56 ctx->Program.ErrorString = _mesa_strdup("");
57
58 #if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program
59 ctx->VertexProgram.Enabled = GL_FALSE;
60 ctx->VertexProgram.PointSizeEnabled = GL_FALSE;
61 ctx->VertexProgram.TwoSideEnabled = GL_FALSE;
62 ctx->VertexProgram.Current = NULL;
63 ctx->VertexProgram.Current = (struct vertex_program *) ctx->Shared->DefaultVertexProgram;
64 assert(ctx->VertexProgram.Current);
65 ctx->VertexProgram.Current->Base.RefCount++;
66 for (i = 0; i < VP_NUM_PROG_REGS / 4; i++) {
67 ctx->VertexProgram.TrackMatrix[i] = GL_NONE;
68 ctx->VertexProgram.TrackMatrixTransform[i] = GL_IDENTITY_NV;
69 }
70 #endif
71
72 #if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program
73 ctx->FragmentProgram.Enabled = GL_FALSE;
74 ctx->FragmentProgram.Current = (struct fragment_program *) ctx->Shared->DefaultFragmentProgram;
75 assert(ctx->FragmentProgram.Current);
76 ctx->FragmentProgram.Current->Base.RefCount++;
77 #endif
78 }
79
80
81 void
82 _mesa_EnableVertexAttribArrayARB(GLuint index)
83 {
84 GET_CURRENT_CONTEXT(ctx);
85 ASSERT_OUTSIDE_BEGIN_END(ctx);
86
87 if (index >= ctx->Const.MaxVertexProgramAttribs) {
88 _mesa_error(ctx, GL_INVALID_VALUE,
89 "glEnableVertexAttribArrayARB(index)");
90 return;
91 }
92
93 ctx->Array.VertexAttrib[index].Enabled = GL_TRUE;
94 ctx->Array._Enabled |= _NEW_ARRAY_ATTRIB(index);
95 ctx->Array.NewState |= _NEW_ARRAY_ATTRIB(index);
96 }
97
98
99 void
100 _mesa_DisableVertexAttribArrayARB(GLuint index)
101 {
102 GET_CURRENT_CONTEXT(ctx);
103 ASSERT_OUTSIDE_BEGIN_END(ctx);
104
105 if (index >= ctx->Const.MaxVertexProgramAttribs) {
106 _mesa_error(ctx, GL_INVALID_VALUE,
107 "glEnableVertexAttribArrayARB(index)");
108 return;
109 }
110
111 ctx->Array.VertexAttrib[index].Enabled = GL_FALSE;
112 ctx->Array._Enabled &= ~_NEW_ARRAY_ATTRIB(index);
113 ctx->Array.NewState |= _NEW_ARRAY_ATTRIB(index);
114 }
115
116
117 void
118 _mesa_GetVertexAttribdvARB(GLuint index, GLenum pname, GLdouble *params)
119 {
120 GLfloat fparams[4];
121 GET_CURRENT_CONTEXT(ctx);
122 ASSERT_OUTSIDE_BEGIN_END(ctx);
123
124 _mesa_GetVertexAttribfvARB(index, pname, fparams);
125 if (ctx->ErrorValue == GL_NO_ERROR) {
126 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
127 COPY_4V(params, fparams);
128 }
129 else {
130 params[0] = fparams[0];
131 }
132 }
133 }
134
135
136 void
137 _mesa_GetVertexAttribfvARB(GLuint index, GLenum pname, GLfloat *params)
138 {
139 GET_CURRENT_CONTEXT(ctx);
140 ASSERT_OUTSIDE_BEGIN_END(ctx);
141
142 if (index == 0 || index >= VERT_ATTRIB_MAX) {
143 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribfvARB(index)");
144 return;
145 }
146
147 switch (pname) {
148 case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB:
149 params[0] = ctx->Array.VertexAttrib[index].Enabled;
150 break;
151 case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB:
152 params[0] = ctx->Array.VertexAttrib[index].Size;
153 break;
154 case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB:
155 params[0] = ctx->Array.VertexAttrib[index].Stride;
156 break;
157 case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB:
158 params[0] = ctx->Array.VertexAttrib[index].Type;
159 break;
160 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB:
161 params[0] = ctx->Array.VertexAttrib[index].Normalized;
162 break;
163 case GL_CURRENT_VERTEX_ATTRIB_ARB:
164 FLUSH_CURRENT(ctx, 0);
165 COPY_4V(params, ctx->Current.Attrib[index]);
166 break;
167 default:
168 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribfvARB(pname)");
169 return;
170 }
171 }
172
173
174 void
175 _mesa_GetVertexAttribivARB(GLuint index, GLenum pname, GLint *params)
176 {
177 GLfloat fparams[4];
178 GET_CURRENT_CONTEXT(ctx);
179 ASSERT_OUTSIDE_BEGIN_END(ctx);
180
181 _mesa_GetVertexAttribfvARB(index, pname, fparams);
182 if (ctx->ErrorValue == GL_NO_ERROR) {
183 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
184 COPY_4V(params, fparams); /* float to int */
185 }
186 else {
187 params[0] = fparams[0];
188 }
189 }
190 }
191
192
193 void
194 _mesa_GetVertexAttribPointervARB(GLuint index, GLenum pname, GLvoid **pointer)
195 {
196 GET_CURRENT_CONTEXT(ctx);
197 ASSERT_OUTSIDE_BEGIN_END(ctx);
198
199 if (index >= ctx->Const.MaxVertexProgramAttribs) {
200 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerARB(index)");
201 return;
202 }
203
204 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) {
205 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerARB(pname)");
206 return;
207 }
208
209 *pointer = ctx->Array.VertexAttrib[index].Ptr;;
210 }
211
212
213 void
214 _mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
215 const GLvoid *string)
216 {
217 GET_CURRENT_CONTEXT(ctx);
218 ASSERT_OUTSIDE_BEGIN_END(ctx);
219
220 if (target == GL_VERTEX_PROGRAM_ARB
221 && ctx->Extensions.ARB_vertex_program) {
222 struct vertex_program *prog = ctx->VertexProgram.Current;
223 if (format != GL_PROGRAM_FORMAT_ASCII_ARB) {
224 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(format)");
225 return;
226 }
227 _mesa_parse_arb_vertex_program(ctx, target, string, len, prog);
228 }
229 else if (target == GL_FRAGMENT_PROGRAM_ARB
230 && ctx->Extensions.ARB_fragment_program) {
231 struct fragment_program *prog = ctx->FragmentProgram.Current;
232 if (format != GL_PROGRAM_FORMAT_ASCII_ARB) {
233 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(format)");
234 return;
235 }
236 _mesa_parse_arb_fragment_program(ctx, target, string, len, prog);
237 }
238 else {
239 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(target)");
240 }
241 }
242
243
244 void
245 _mesa_ProgramEnvParameter4dARB(GLenum target, GLuint index,
246 GLdouble x, GLdouble y, GLdouble z, GLdouble w)
247 {
248 _mesa_ProgramEnvParameter4fARB(target, index, x, y, z, w);
249 }
250
251
252 void
253 _mesa_ProgramEnvParameter4dvARB(GLenum target, GLuint index,
254 const GLdouble *params)
255 {
256 _mesa_ProgramEnvParameter4fARB(target, index, params[0], params[1],
257 params[2], params[3]);
258 }
259
260
261 void
262 _mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index,
263 GLfloat x, GLfloat y, GLfloat z, GLfloat w)
264 {
265 GET_CURRENT_CONTEXT(ctx);
266 ASSERT_OUTSIDE_BEGIN_END(ctx);
267
268 if (target == GL_FRAGMENT_PROGRAM_ARB
269 && ctx->Extensions.ARB_fragment_program) {
270 if (index >= ctx->Const.MaxFragmentProgramEnvParams) {
271 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
272 return;
273 }
274 index += FP_PROG_REG_START;
275 ASSIGN_4V(ctx->FragmentProgram.Machine.Registers[index], x, y, z, w);
276 }
277 if (target == GL_VERTEX_PROGRAM_ARB
278 && ctx->Extensions.ARB_vertex_program) {
279 if (index >= ctx->Const.MaxVertexProgramEnvParams) {
280 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
281 return;
282 }
283 index += VP_PROG_REG_START;
284 ASSIGN_4V(ctx->VertexProgram.Machine.Registers[index], x, y, z, w);
285 }
286 else {
287 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameter(target)");
288 return;
289 }
290 }
291
292
293 void
294 _mesa_ProgramEnvParameter4fvARB(GLenum target, GLuint index,
295 const GLfloat *params)
296 {
297 _mesa_ProgramEnvParameter4fARB(target, index, params[0], params[1],
298 params[2], params[3]);
299 }
300
301
302 void
303 _mesa_GetProgramEnvParameterdvARB(GLenum target, GLuint index,
304 GLdouble *params)
305 {
306 GET_CURRENT_CONTEXT(ctx);
307 GLfloat fparams[4];
308
309 _mesa_GetProgramEnvParameterfvARB(target, index, fparams);
310 if (ctx->ErrorValue == GL_NO_ERROR) {
311 params[0] = fparams[0];
312 params[1] = fparams[1];
313 params[2] = fparams[2];
314 params[3] = fparams[3];
315 }
316 }
317
318
319 void
320 _mesa_GetProgramEnvParameterfvARB(GLenum target, GLuint index,
321 GLfloat *params)
322 {
323 GET_CURRENT_CONTEXT(ctx);
324
325 if (!ctx->_CurrentProgram)
326 ASSERT_OUTSIDE_BEGIN_END(ctx);
327
328 if (target == GL_FRAGMENT_PROGRAM_ARB
329 && ctx->Extensions.ARB_fragment_program) {
330 if (index >= ctx->Const.MaxFragmentProgramEnvParams) {
331 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
332 return;
333 }
334 index += FP_PROG_REG_START;
335 COPY_4V(params, ctx->FragmentProgram.Machine.Registers[index]);
336 }
337 if (target == GL_VERTEX_PROGRAM_ARB
338 && ctx->Extensions.ARB_vertex_program) {
339 if (index >= ctx->Const.MaxVertexProgramEnvParams) {
340 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
341 return;
342 }
343 index += VP_PROG_REG_START;
344 COPY_4V(params, ctx->VertexProgram.Machine.Registers[index]);
345 }
346 else {
347 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramEnvParameter(target)");
348 return;
349 }
350 }
351
352
353 /**
354 * Note, this function is also used by the GL_NV_fragment_program extension.
355 */
356 void
357 _mesa_ProgramLocalParameter4fARB(GLenum target, GLuint index,
358 GLfloat x, GLfloat y, GLfloat z, GLfloat w)
359 {
360 GET_CURRENT_CONTEXT(ctx);
361 struct program *prog;
362 ASSERT_OUTSIDE_BEGIN_END(ctx);
363
364 if ((target == GL_FRAGMENT_PROGRAM_NV
365 && ctx->Extensions.NV_fragment_program) ||
366 (target == GL_FRAGMENT_PROGRAM_ARB
367 && ctx->Extensions.ARB_fragment_program)) {
368 if (index >= ctx->Const.MaxFragmentProgramLocalParams) {
369 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
370 return;
371 }
372 prog = &(ctx->FragmentProgram.Current->Base);
373 }
374 else if (target == GL_VERTEX_PROGRAM_ARB
375 && ctx->Extensions.ARB_vertex_program) {
376 if (index >= ctx->Const.MaxVertexProgramLocalParams) {
377 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
378 return;
379 }
380 prog = &(ctx->VertexProgram.Current->Base);
381 }
382 else {
383 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameterARB");
384 return;
385 }
386
387 ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS);
388 prog->LocalParams[index][0] = x;
389 prog->LocalParams[index][1] = y;
390 prog->LocalParams[index][2] = z;
391 prog->LocalParams[index][3] = w;
392 }
393
394
395 /**
396 * Note, this function is also used by the GL_NV_fragment_program extension.
397 */
398 void
399 _mesa_ProgramLocalParameter4fvARB(GLenum target, GLuint index,
400 const GLfloat *params)
401 {
402 _mesa_ProgramLocalParameter4fARB(target, index, params[0], params[1],
403 params[2], params[3]);
404 }
405
406
407 /**
408 * Note, this function is also used by the GL_NV_fragment_program extension.
409 */
410 void
411 _mesa_ProgramLocalParameter4dARB(GLenum target, GLuint index,
412 GLdouble x, GLdouble y,
413 GLdouble z, GLdouble w)
414 {
415 _mesa_ProgramLocalParameter4fARB(target, index, (GLfloat) x, (GLfloat) y,
416 (GLfloat) z, (GLfloat) w);
417 }
418
419
420 /**
421 * Note, this function is also used by the GL_NV_fragment_program extension.
422 */
423 void
424 _mesa_ProgramLocalParameter4dvARB(GLenum target, GLuint index,
425 const GLdouble *params)
426 {
427 _mesa_ProgramLocalParameter4fARB(target, index,
428 (GLfloat) params[0], (GLfloat) params[1],
429 (GLfloat) params[2], (GLfloat) params[3]);
430 }
431
432
433 /**
434 * Note, this function is also used by the GL_NV_fragment_program extension.
435 */
436 void
437 _mesa_GetProgramLocalParameterfvARB(GLenum target, GLuint index,
438 GLfloat *params)
439 {
440 const struct program *prog;
441 GLuint maxParams;
442 GET_CURRENT_CONTEXT(ctx);
443 ASSERT_OUTSIDE_BEGIN_END(ctx);
444
445 if (target == GL_VERTEX_PROGRAM_ARB
446 && ctx->Extensions.ARB_vertex_program) {
447 prog = &(ctx->VertexProgram.Current->Base);
448 maxParams = ctx->Const.MaxVertexProgramLocalParams;
449 }
450 else if (target == GL_FRAGMENT_PROGRAM_ARB
451 && ctx->Extensions.ARB_fragment_program) {
452 prog = &(ctx->FragmentProgram.Current->Base);
453 maxParams = ctx->Const.MaxFragmentProgramLocalParams;
454 }
455 else if (target == GL_FRAGMENT_PROGRAM_NV
456 && ctx->Extensions.NV_fragment_program) {
457 prog = &(ctx->FragmentProgram.Current->Base);
458 maxParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
459 }
460 else {
461 _mesa_error(ctx, GL_INVALID_ENUM,
462 "glGetProgramLocalParameterARB(target)");
463 return;
464 }
465
466 if (index >= maxParams) {
467 _mesa_error(ctx, GL_INVALID_VALUE,
468 "glGetProgramLocalParameterARB(index)");
469 return;
470 }
471
472 ASSERT(prog);
473 ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS);
474 COPY_4V(params, prog->LocalParams[index]);
475 }
476
477
478 /**
479 * Note, this function is also used by the GL_NV_fragment_program extension.
480 */
481 void
482 _mesa_GetProgramLocalParameterdvARB(GLenum target, GLuint index,
483 GLdouble *params)
484 {
485 GET_CURRENT_CONTEXT(ctx);
486 GLfloat floatParams[4];
487 _mesa_GetProgramLocalParameterfvARB(target, index, floatParams);
488 if (ctx->ErrorValue == GL_NO_ERROR) {
489 COPY_4V(params, floatParams);
490 }
491 }
492
493
494 void
495 _mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params)
496 {
497 struct program *prog;
498 GET_CURRENT_CONTEXT(ctx);
499
500 if (!ctx->_CurrentProgram)
501 ASSERT_OUTSIDE_BEGIN_END(ctx);
502
503 if (target == GL_VERTEX_PROGRAM_ARB
504 && ctx->Extensions.ARB_vertex_program) {
505 prog = &(ctx->VertexProgram.Current->Base);
506 }
507 else if (target == GL_FRAGMENT_PROGRAM_ARB
508 && ctx->Extensions.ARB_fragment_program) {
509 prog = &(ctx->FragmentProgram.Current->Base);
510 }
511 else {
512 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
513 return;
514 }
515
516 ASSERT(prog);
517
518 switch (pname) {
519 case GL_PROGRAM_LENGTH_ARB:
520 *params = prog->String ? _mesa_strlen((char *) prog->String) : 0;
521 break;
522 case GL_PROGRAM_FORMAT_ARB:
523 *params = prog->Format;
524 break;
525 case GL_PROGRAM_BINDING_ARB:
526 *params = prog->Id;
527 break;
528 case GL_PROGRAM_INSTRUCTIONS_ARB:
529 *params = prog->NumInstructions;
530 break;
531 case GL_MAX_PROGRAM_INSTRUCTIONS_ARB:
532 if (target == GL_VERTEX_PROGRAM_ARB)
533 *params = ctx->Const.MaxVertexProgramInstructions;
534 else
535 *params = ctx->Const.MaxFragmentProgramInstructions;
536 break;
537 case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
538 *params = prog->NumInstructions;
539 break;
540 case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
541 if (target == GL_VERTEX_PROGRAM_ARB)
542 *params = ctx->Const.MaxVertexProgramInstructions;
543 else
544 *params = ctx->Const.MaxFragmentProgramInstructions;
545 break;
546 case GL_PROGRAM_TEMPORARIES_ARB:
547 *params = prog->NumTemporaries;
548 break;
549 case GL_MAX_PROGRAM_TEMPORARIES_ARB:
550 if (target == GL_VERTEX_PROGRAM_ARB)
551 *params = ctx->Const.MaxVertexProgramTemps;
552 else
553 *params = ctx->Const.MaxFragmentProgramTemps;
554 break;
555 case GL_PROGRAM_NATIVE_TEMPORARIES_ARB:
556 /* XXX same as GL_PROGRAM_TEMPORARIES_ARB? */
557 *params = prog->NumTemporaries;
558 break;
559 case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB:
560 /* XXX same as GL_MAX_PROGRAM_TEMPORARIES_ARB? */
561 if (target == GL_VERTEX_PROGRAM_ARB)
562 *params = ctx->Const.MaxVertexProgramTemps;
563 else
564 *params = ctx->Const.MaxFragmentProgramTemps;
565 break;
566 case GL_PROGRAM_PARAMETERS_ARB:
567 *params = prog->NumParameters;
568 break;
569 case GL_MAX_PROGRAM_PARAMETERS_ARB:
570 if (target == GL_VERTEX_PROGRAM_ARB)
571 *params = ctx->Const.MaxVertexProgramLocalParams;
572 else
573 *params = ctx->Const.MaxFragmentProgramLocalParams;
574 break;
575 case GL_PROGRAM_NATIVE_PARAMETERS_ARB:
576 /* XXX same as GL_MAX_PROGRAM_PARAMETERS_ARB? */
577 *params = prog->NumParameters;
578 break;
579 case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB:
580 /* XXX same as GL_MAX_PROGRAM_PARAMETERS_ARB? */
581 if (target == GL_VERTEX_PROGRAM_ARB)
582 *params = ctx->Const.MaxVertexProgramLocalParams;
583 else
584 *params = ctx->Const.MaxFragmentProgramLocalParams;
585 break;
586 case GL_PROGRAM_ATTRIBS_ARB:
587 *params = prog->NumAttributes;
588 break;
589 case GL_MAX_PROGRAM_ATTRIBS_ARB:
590 if (target == GL_VERTEX_PROGRAM_ARB)
591 *params = ctx->Const.MaxVertexProgramAttribs;
592 else
593 *params = ctx->Const.MaxFragmentProgramAttribs;
594 break;
595 case GL_PROGRAM_NATIVE_ATTRIBS_ARB:
596 /* XXX same as GL_PROGRAM_ATTRIBS_ARB? */
597 *params = prog->NumAttributes;
598 break;
599 case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB:
600 /* XXX same as GL_MAX_PROGRAM_ATTRIBS_ARB? */
601 if (target == GL_VERTEX_PROGRAM_ARB)
602 *params = ctx->Const.MaxVertexProgramAttribs;
603 else
604 *params = ctx->Const.MaxFragmentProgramAttribs;
605 break;
606 case GL_PROGRAM_ADDRESS_REGISTERS_ARB:
607 *params = prog->NumAddressRegs;
608 break;
609 case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB:
610 if (target == GL_VERTEX_PROGRAM_ARB)
611 *params = ctx->Const.MaxVertexProgramAddressRegs;
612 else
613 *params = ctx->Const.MaxFragmentProgramAddressRegs;
614 break;
615 case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
616 /* XXX same as GL_PROGRAM_ADDRESS_REGISTERS_ARB? */
617 *params = prog->NumAddressRegs;
618 break;
619 case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
620 /* XXX same as GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB? */
621 if (target == GL_VERTEX_PROGRAM_ARB)
622 *params = ctx->Const.MaxVertexProgramAddressRegs;
623 else
624 *params = ctx->Const.MaxFragmentProgramAddressRegs;
625 break;
626 case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB:
627 if (target == GL_VERTEX_PROGRAM_ARB)
628 *params = ctx->Const.MaxVertexProgramLocalParams;
629 else
630 *params = ctx->Const.MaxFragmentProgramLocalParams;
631 break;
632 case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB:
633 if (target == GL_VERTEX_PROGRAM_ARB)
634 *params = ctx->Const.MaxVertexProgramEnvParams;
635 else
636 *params = ctx->Const.MaxFragmentProgramEnvParams;
637 break;
638 case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB:
639 /* XXX ok? */
640 *params = GL_TRUE;
641 break;
642
643 /*
644 * The following apply to fragment programs only.
645 */
646 case GL_PROGRAM_ALU_INSTRUCTIONS_ARB:
647 case GL_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->FragmentProgram.Current->NumAluInstructions;
653 break;
654 case GL_PROGRAM_TEX_INSTRUCTIONS_ARB:
655 case GL_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->FragmentProgram.Current->NumTexInstructions;
661 break;
662 case GL_PROGRAM_TEX_INDIRECTIONS_ARB:
663 case GL_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->FragmentProgram.Current->NumTexIndirections;
669 break;
670 case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB:
671 case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
672 if (target != GL_FRAGMENT_PROGRAM_ARB) {
673 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
674 return;
675 }
676 *params = ctx->Const.MaxFragmentProgramAluInstructions;
677 break;
678 case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB:
679 case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
680 if (target != GL_FRAGMENT_PROGRAM_ARB) {
681 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
682 return;
683 }
684 *params = ctx->Const.MaxFragmentProgramTexInstructions;
685 break;
686 case GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB:
687 case GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
688 if (target != GL_FRAGMENT_PROGRAM_ARB) {
689 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
690 return;
691 }
692 *params = ctx->Const.MaxFragmentProgramTexIndirections;
693 break;
694 default:
695 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(pname)");
696 return;
697 }
698 }
699
700
701 void
702 _mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string)
703 {
704 struct program *prog;
705 GET_CURRENT_CONTEXT(ctx);
706
707 if (!ctx->_CurrentProgram)
708 ASSERT_OUTSIDE_BEGIN_END(ctx);
709
710 if (target == GL_VERTEX_PROGRAM_ARB) {
711 prog = &(ctx->VertexProgram.Current->Base);
712 }
713 else if (target == GL_FRAGMENT_PROGRAM_ARB) {
714 prog = &(ctx->FragmentProgram.Current->Base);
715 }
716 else {
717 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(target)");
718 return;
719 }
720
721 ASSERT(prog);
722
723 if (pname != GL_PROGRAM_STRING_ARB) {
724 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(pname)");
725 return;
726 }
727
728 MEMCPY(string, prog->String, _mesa_strlen((char *) prog->String));
729 }
730
731
732
733 /* XXX temporary */
734 void
735 glProgramCallbackMESA(GLenum target, GLprogramcallbackMESA callback,
736 GLvoid *data)
737 {
738 _mesa_ProgramCallbackMESA(target, callback, data);
739 }
740
741
742 void
743 _mesa_ProgramCallbackMESA(GLenum target, GLprogramcallbackMESA callback,
744 GLvoid *data)
745 {
746 GET_CURRENT_CONTEXT(ctx);
747
748 switch (target) {
749 case GL_FRAGMENT_PROGRAM_ARB:
750 if (!ctx->Extensions.ARB_fragment_program) {
751 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramCallbackMESA(target)");
752 return;
753 }
754 ctx->FragmentProgram.Callback = callback;
755 ctx->FragmentProgram.CallbackData = data;
756 break;
757 case GL_FRAGMENT_PROGRAM_NV:
758 if (!ctx->Extensions.NV_fragment_program) {
759 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramCallbackMESA(target)");
760 return;
761 }
762 ctx->FragmentProgram.Callback = callback;
763 ctx->FragmentProgram.CallbackData = data;
764 break;
765 case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */
766 if (!ctx->Extensions.ARB_vertex_program &&
767 !ctx->Extensions.NV_vertex_program) {
768 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramCallbackMESA(target)");
769 return;
770 }
771 ctx->VertexProgram.Callback = callback;
772 ctx->VertexProgram.CallbackData = data;
773 break;
774 default:
775 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramCallbackMESA(target)");
776 return;
777 }
778 }
779
780
781 /* XXX temporary */
782 void
783 glGetProgramRegisterfvMESA(GLenum target,
784 GLsizei len, const GLubyte *registerName,
785 GLfloat *v)
786 {
787 _mesa_GetProgramRegisterfvMESA(target, len, registerName, v);
788 }
789
790
791 void
792 _mesa_GetProgramRegisterfvMESA(GLenum target,
793 GLsizei len, const GLubyte *registerName,
794 GLfloat *v)
795 {
796 char reg[1000];
797 GET_CURRENT_CONTEXT(ctx);
798
799 /* We _should_ be inside glBegin/glEnd */
800 #if 0
801 if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) {
802 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramRegisterfvMESA");
803 return;
804 }
805 #endif
806
807 /* make null-terminated copy of registerName */
808 _mesa_memcpy(reg, registerName, len);
809 reg[len] = 0;
810
811 switch (target) {
812 case GL_VERTEX_PROGRAM_NV:
813 if (!ctx->Extensions.ARB_vertex_program &&
814 !ctx->Extensions.NV_vertex_program) {
815 _mesa_error(ctx, GL_INVALID_ENUM,
816 "glGetProgramRegisterfvMESA(target)");
817 return;
818 }
819 if (!ctx->VertexProgram.Enabled) {
820 _mesa_error(ctx, GL_INVALID_OPERATION,
821 "glGetProgramRegisterfvMESA");
822 return;
823 }
824 /* GL_NV_vertex_program */
825 if (reg[0] == 'R') {
826 /* Temp register */
827 GLint i = _mesa_atoi(reg + 1);
828 if (i >= ctx->Const.MaxVertexProgramTemps) {
829 _mesa_error(ctx, GL_INVALID_VALUE,
830 "glGetProgramRegisterfvMESA(registerName)");
831 return;
832 }
833 COPY_4V(v, ctx->VertexProgram.Machine.Registers
834 [VP_TEMP_REG_START + i]);
835 }
836 else if (reg[0] == 'v' && reg[1] == '[') {
837 /* Vertex Input attribute */
838 GLint i;
839 for (i = 0; i < ctx->Const.MaxVertexProgramAttribs; i++) {
840 const char *name = _mesa_nv_vertex_input_register_name(i);
841 char number[10];
842 sprintf(number, "%d", i);
843 if (_mesa_strncmp(reg + 2, name, 4) == 0 ||
844 _mesa_strncmp(reg + 2, number, _mesa_strlen(number)) == 0) {
845 COPY_4V(v, ctx->VertexProgram.Machine.Registers
846 [VP_INPUT_REG_START + i]);
847 return;
848 }
849 }
850 _mesa_error(ctx, GL_INVALID_VALUE,
851 "glGetProgramRegisterfvMESA(registerName)");
852 return;
853 }
854 else if (reg[0] == 'o' && reg[1] == '[') {
855 /* Vertex output attribute */
856 }
857 /* GL_ARB_vertex_program */
858 else if (_mesa_strncmp(reg, "vertex.", 7) == 0) {
859
860 }
861 else {
862 _mesa_error(ctx, GL_INVALID_VALUE,
863 "glGetProgramRegisterfvMESA(registerName)");
864 return;
865 }
866 break;
867 case GL_FRAGMENT_PROGRAM_ARB:
868 if (!ctx->Extensions.ARB_fragment_program) {
869 _mesa_error(ctx, GL_INVALID_ENUM,
870 "glGetProgramRegisterfvMESA(target)");
871 return;
872 }
873 if (!ctx->FragmentProgram.Enabled) {
874 _mesa_error(ctx, GL_INVALID_OPERATION,
875 "glGetProgramRegisterfvMESA");
876 return;
877 }
878 /* XXX to do */
879 break;
880 case GL_FRAGMENT_PROGRAM_NV:
881 if (!ctx->Extensions.NV_fragment_program) {
882 _mesa_error(ctx, GL_INVALID_ENUM,
883 "glGetProgramRegisterfvMESA(target)");
884 return;
885 }
886 if (!ctx->FragmentProgram.Enabled) {
887 _mesa_error(ctx, GL_INVALID_OPERATION,
888 "glGetProgramRegisterfvMESA");
889 return;
890 }
891 if (reg[0] == 'R') {
892 /* Temp register */
893 GLint i = _mesa_atoi(reg + 1);
894 if (i >= ctx->Const.MaxFragmentProgramTemps) {
895 _mesa_error(ctx, GL_INVALID_VALUE,
896 "glGetProgramRegisterfvMESA(registerName)");
897 return;
898 }
899 COPY_4V(v,
900 ctx->FragmentProgram.Machine.Registers[FP_TEMP_REG_START + i]);
901 }
902 else if (reg[0] == 'f' && reg[1] == '[') {
903 /* Fragment input attribute */
904 GLint i;
905 for (i = 0; i < ctx->Const.MaxFragmentProgramAttribs; i++) {
906 const char *name = _mesa_nv_fragment_input_register_name(i);
907 if (_mesa_strncmp(reg + 2, name, 4) == 0) {
908 COPY_4V(v, ctx->FragmentProgram.Machine.Registers
909 [FP_INPUT_REG_START + i]);
910 return;
911 }
912 }
913 _mesa_error(ctx, GL_INVALID_VALUE,
914 "glGetProgramRegisterfvMESA(registerName)");
915 return;
916 }
917 else if (_mesa_strcmp(reg, "o[COLR]") == 0) {
918 /* Fragment output color */
919 COPY_4V(v, ctx->FragmentProgram.Machine.Registers
920 [FP_OUTPUT_REG_START + FRAG_OUTPUT_COLR]);
921 }
922 else if (_mesa_strcmp(reg, "o[COLH]") == 0) {
923 /* Fragment output color */
924 COPY_4V(v, ctx->FragmentProgram.Machine.Registers
925 [FP_OUTPUT_REG_START + FRAG_OUTPUT_COLH]);
926 }
927 else if (_mesa_strcmp(reg, "o[DEPR]") == 0) {
928 /* Fragment output depth */
929 COPY_4V(v, ctx->FragmentProgram.Machine.Registers
930 [FP_OUTPUT_REG_START + FRAG_OUTPUT_DEPR]);
931 }
932 else {
933 _mesa_error(ctx, GL_INVALID_VALUE,
934 "glGetProgramRegisterfvMESA(registerName)");
935 return;
936 }
937 break;
938 default:
939 _mesa_error(ctx, GL_INVALID_ENUM,
940 "glGetProgramRegisterfvMESA(target)");
941 return;
942 }
943
944 }