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