20118d45a1fb4a6039792c0ebaec5cfa1a484b30
[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 ASSERT_OUTSIDE_BEGIN_END(ctx);
308
309 if (target == GL_FRAGMENT_PROGRAM_ARB
310 && ctx->Extensions.ARB_fragment_program) {
311 if (index >= ctx->Const.MaxFragmentProgramEnvParams) {
312 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
313 return;
314 }
315 index += FP_PROG_REG_START;
316 COPY_4V(params, ctx->FragmentProgram.Machine.Registers[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 index += VP_PROG_REG_START;
325 COPY_4V(params, ctx->VertexProgram.Machine.Registers[index]);
326 }
327 else {
328 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramEnvParameter(target)");
329 return;
330 }
331 }
332
333
334 /**
335 * Note, this function is also used by the GL_NV_fragment_program extension.
336 */
337 void
338 _mesa_ProgramLocalParameter4fARB(GLenum target, GLuint index,
339 GLfloat x, GLfloat y, GLfloat z, GLfloat w)
340 {
341 GET_CURRENT_CONTEXT(ctx);
342 struct program *prog;
343 ASSERT_OUTSIDE_BEGIN_END(ctx);
344
345 if ((target == GL_FRAGMENT_PROGRAM_NV
346 && ctx->Extensions.NV_fragment_program) ||
347 (target == GL_FRAGMENT_PROGRAM_ARB
348 && ctx->Extensions.ARB_fragment_program)) {
349 if (index >= ctx->Const.MaxFragmentProgramLocalParams) {
350 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
351 return;
352 }
353 prog = &(ctx->FragmentProgram.Current->Base);
354 }
355 else if (target == GL_VERTEX_PROGRAM_ARB
356 && ctx->Extensions.ARB_vertex_program) {
357 if (index >= ctx->Const.MaxVertexProgramLocalParams) {
358 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
359 return;
360 }
361 prog = &(ctx->VertexProgram.Current->Base);
362 }
363 else {
364 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameterARB");
365 return;
366 }
367
368 ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS);
369 prog->LocalParams[index][0] = x;
370 prog->LocalParams[index][1] = y;
371 prog->LocalParams[index][2] = z;
372 prog->LocalParams[index][3] = w;
373 }
374
375
376 /**
377 * Note, this function is also used by the GL_NV_fragment_program extension.
378 */
379 void
380 _mesa_ProgramLocalParameter4fvARB(GLenum target, GLuint index,
381 const GLfloat *params)
382 {
383 _mesa_ProgramLocalParameter4fARB(target, index, params[0], params[1],
384 params[2], params[3]);
385 }
386
387
388 /**
389 * Note, this function is also used by the GL_NV_fragment_program extension.
390 */
391 void
392 _mesa_ProgramLocalParameter4dARB(GLenum target, GLuint index,
393 GLdouble x, GLdouble y,
394 GLdouble z, GLdouble w)
395 {
396 _mesa_ProgramLocalParameter4fARB(target, index, (GLfloat) x, (GLfloat) y,
397 (GLfloat) z, (GLfloat) w);
398 }
399
400
401 /**
402 * Note, this function is also used by the GL_NV_fragment_program extension.
403 */
404 void
405 _mesa_ProgramLocalParameter4dvARB(GLenum target, GLuint index,
406 const GLdouble *params)
407 {
408 _mesa_ProgramLocalParameter4fARB(target, index,
409 (GLfloat) params[0], (GLfloat) params[1],
410 (GLfloat) params[2], (GLfloat) params[3]);
411 }
412
413
414 /**
415 * Note, this function is also used by the GL_NV_fragment_program extension.
416 */
417 void
418 _mesa_GetProgramLocalParameterfvARB(GLenum target, GLuint index,
419 GLfloat *params)
420 {
421 const struct program *prog;
422 GLuint maxParams;
423 GET_CURRENT_CONTEXT(ctx);
424 ASSERT_OUTSIDE_BEGIN_END(ctx);
425
426 if (target == GL_VERTEX_PROGRAM_ARB
427 && ctx->Extensions.ARB_vertex_program) {
428 prog = &(ctx->VertexProgram.Current->Base);
429 maxParams = ctx->Const.MaxVertexProgramLocalParams;
430 }
431 else if (target == GL_FRAGMENT_PROGRAM_ARB
432 && ctx->Extensions.ARB_fragment_program) {
433 prog = &(ctx->FragmentProgram.Current->Base);
434 maxParams = ctx->Const.MaxFragmentProgramLocalParams;
435 }
436 else if (target == GL_FRAGMENT_PROGRAM_NV
437 && ctx->Extensions.NV_fragment_program) {
438 prog = &(ctx->FragmentProgram.Current->Base);
439 maxParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
440 }
441 else {
442 _mesa_error(ctx, GL_INVALID_ENUM,
443 "glGetProgramLocalParameterARB(target)");
444 return;
445 }
446
447 if (index >= maxParams) {
448 _mesa_error(ctx, GL_INVALID_VALUE,
449 "glGetProgramLocalParameterARB(index)");
450 return;
451 }
452
453 ASSERT(prog);
454 ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS);
455 COPY_4V(params, prog->LocalParams[index]);
456 }
457
458
459 /**
460 * Note, this function is also used by the GL_NV_fragment_program extension.
461 */
462 void
463 _mesa_GetProgramLocalParameterdvARB(GLenum target, GLuint index,
464 GLdouble *params)
465 {
466 GET_CURRENT_CONTEXT(ctx);
467 GLfloat floatParams[4];
468 _mesa_GetProgramLocalParameterfvARB(target, index, floatParams);
469 if (ctx->ErrorValue == GL_NO_ERROR) {
470 COPY_4V(params, floatParams);
471 }
472 }
473
474
475 void
476 _mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params)
477 {
478 struct program *prog;
479 GET_CURRENT_CONTEXT(ctx);
480 ASSERT_OUTSIDE_BEGIN_END(ctx);
481
482 if (target == GL_VERTEX_PROGRAM_ARB
483 && ctx->Extensions.ARB_vertex_program) {
484 prog = &(ctx->VertexProgram.Current->Base);
485 }
486 else if (target == GL_FRAGMENT_PROGRAM_ARB
487 && ctx->Extensions.ARB_fragment_program) {
488 prog = &(ctx->FragmentProgram.Current->Base);
489 }
490 else {
491 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
492 return;
493 }
494
495 ASSERT(prog);
496
497 switch (pname) {
498 case GL_PROGRAM_LENGTH_ARB:
499 *params = prog->String ? _mesa_strlen((char *) prog->String) : 0;
500 break;
501 case GL_PROGRAM_FORMAT_ARB:
502 *params = prog->Format;
503 break;
504 case GL_PROGRAM_BINDING_ARB:
505 *params = prog->Id;
506 break;
507 case GL_PROGRAM_INSTRUCTIONS_ARB:
508 *params = prog->NumInstructions;
509 break;
510 case GL_MAX_PROGRAM_INSTRUCTIONS_ARB:
511 if (target == GL_VERTEX_PROGRAM_ARB)
512 *params = ctx->Const.MaxVertexProgramInstructions;
513 else
514 *params = ctx->Const.MaxFragmentProgramInstructions;
515 break;
516 case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
517 *params = prog->NumInstructions;
518 break;
519 case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
520 if (target == GL_VERTEX_PROGRAM_ARB)
521 *params = ctx->Const.MaxVertexProgramInstructions;
522 else
523 *params = ctx->Const.MaxFragmentProgramInstructions;
524 break;
525 case GL_PROGRAM_TEMPORARIES_ARB:
526 *params = prog->NumTemporaries;
527 break;
528 case GL_MAX_PROGRAM_TEMPORARIES_ARB:
529 if (target == GL_VERTEX_PROGRAM_ARB)
530 *params = ctx->Const.MaxVertexProgramTemps;
531 else
532 *params = ctx->Const.MaxFragmentProgramTemps;
533 break;
534 case GL_PROGRAM_NATIVE_TEMPORARIES_ARB:
535 /* XXX same as GL_PROGRAM_TEMPORARIES_ARB? */
536 *params = prog->NumTemporaries;
537 break;
538 case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB:
539 /* XXX same as GL_MAX_PROGRAM_TEMPORARIES_ARB? */
540 if (target == GL_VERTEX_PROGRAM_ARB)
541 *params = ctx->Const.MaxVertexProgramTemps;
542 else
543 *params = ctx->Const.MaxFragmentProgramTemps;
544 break;
545 case GL_PROGRAM_PARAMETERS_ARB:
546 *params = prog->NumParameters;
547 break;
548 case GL_MAX_PROGRAM_PARAMETERS_ARB:
549 if (target == GL_VERTEX_PROGRAM_ARB)
550 *params = ctx->Const.MaxVertexProgramLocalParams;
551 else
552 *params = ctx->Const.MaxFragmentProgramLocalParams;
553 break;
554 case GL_PROGRAM_NATIVE_PARAMETERS_ARB:
555 /* XXX same as GL_MAX_PROGRAM_PARAMETERS_ARB? */
556 *params = prog->NumParameters;
557 break;
558 case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB:
559 /* XXX same as GL_MAX_PROGRAM_PARAMETERS_ARB? */
560 if (target == GL_VERTEX_PROGRAM_ARB)
561 *params = ctx->Const.MaxVertexProgramLocalParams;
562 else
563 *params = ctx->Const.MaxFragmentProgramLocalParams;
564 break;
565 case GL_PROGRAM_ATTRIBS_ARB:
566 *params = prog->NumAttributes;
567 break;
568 case GL_MAX_PROGRAM_ATTRIBS_ARB:
569 if (target == GL_VERTEX_PROGRAM_ARB)
570 *params = ctx->Const.MaxVertexProgramAttribs;
571 else
572 *params = ctx->Const.MaxFragmentProgramAttribs;
573 break;
574 case GL_PROGRAM_NATIVE_ATTRIBS_ARB:
575 /* XXX same as GL_PROGRAM_ATTRIBS_ARB? */
576 *params = prog->NumAttributes;
577 break;
578 case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB:
579 /* XXX same as GL_MAX_PROGRAM_ATTRIBS_ARB? */
580 if (target == GL_VERTEX_PROGRAM_ARB)
581 *params = ctx->Const.MaxVertexProgramAttribs;
582 else
583 *params = ctx->Const.MaxFragmentProgramAttribs;
584 break;
585 case GL_PROGRAM_ADDRESS_REGISTERS_ARB:
586 *params = prog->NumAddressRegs;
587 break;
588 case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB:
589 if (target == GL_VERTEX_PROGRAM_ARB)
590 *params = ctx->Const.MaxVertexProgramAddressRegs;
591 else
592 *params = ctx->Const.MaxFragmentProgramAddressRegs;
593 break;
594 case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
595 /* XXX same as GL_PROGRAM_ADDRESS_REGISTERS_ARB? */
596 *params = prog->NumAddressRegs;
597 break;
598 case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
599 /* XXX same as GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB? */
600 if (target == GL_VERTEX_PROGRAM_ARB)
601 *params = ctx->Const.MaxVertexProgramAddressRegs;
602 else
603 *params = ctx->Const.MaxFragmentProgramAddressRegs;
604 break;
605 case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB:
606 if (target == GL_VERTEX_PROGRAM_ARB)
607 *params = ctx->Const.MaxVertexProgramLocalParams;
608 else
609 *params = ctx->Const.MaxFragmentProgramLocalParams;
610 break;
611 case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB:
612 if (target == GL_VERTEX_PROGRAM_ARB)
613 *params = ctx->Const.MaxVertexProgramEnvParams;
614 else
615 *params = ctx->Const.MaxFragmentProgramEnvParams;
616 break;
617 case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB:
618 /* XXX ok? */
619 *params = GL_TRUE;
620 break;
621
622 /*
623 * The following apply to fragment programs only.
624 */
625 case GL_PROGRAM_ALU_INSTRUCTIONS_ARB:
626 case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
627 if (target != GL_FRAGMENT_PROGRAM_ARB) {
628 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
629 return;
630 }
631 *params = ctx->FragmentProgram.Current->NumAluInstructions;
632 break;
633 case GL_PROGRAM_TEX_INSTRUCTIONS_ARB:
634 case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
635 if (target != GL_FRAGMENT_PROGRAM_ARB) {
636 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
637 return;
638 }
639 *params = ctx->FragmentProgram.Current->NumTexInstructions;
640 break;
641 case GL_PROGRAM_TEX_INDIRECTIONS_ARB:
642 case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
643 if (target != GL_FRAGMENT_PROGRAM_ARB) {
644 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
645 return;
646 }
647 *params = ctx->FragmentProgram.Current->NumTexIndirections;
648 break;
649 case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB:
650 case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
651 if (target != GL_FRAGMENT_PROGRAM_ARB) {
652 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
653 return;
654 }
655 *params = ctx->Const.MaxFragmentProgramAluInstructions;
656 break;
657 case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB:
658 case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
659 if (target != GL_FRAGMENT_PROGRAM_ARB) {
660 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
661 return;
662 }
663 *params = ctx->Const.MaxFragmentProgramTexInstructions;
664 break;
665 case GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB:
666 case GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
667 if (target != GL_FRAGMENT_PROGRAM_ARB) {
668 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
669 return;
670 }
671 *params = ctx->Const.MaxFragmentProgramTexIndirections;
672 break;
673 default:
674 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(pname)");
675 return;
676 }
677 }
678
679
680 void
681 _mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string)
682 {
683 struct program *prog;
684 GET_CURRENT_CONTEXT(ctx);
685 ASSERT_OUTSIDE_BEGIN_END(ctx);
686
687 if (target == GL_VERTEX_PROGRAM_ARB) {
688 prog = &(ctx->VertexProgram.Current->Base);
689 }
690 else if (target == GL_FRAGMENT_PROGRAM_ARB) {
691 prog = &(ctx->FragmentProgram.Current->Base);
692 }
693 else {
694 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(target)");
695 return;
696 }
697
698 ASSERT(prog);
699
700 if (pname != GL_PROGRAM_STRING_ARB) {
701 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(pname)");
702 return;
703 }
704
705 MEMCPY(string, prog->String, _mesa_strlen((char *) prog->String));
706 }
707
708
709
710 /* XXX temporary */
711 void
712 glProgramCallbackMESA(GLenum target, GLprogramcallbackMESA callback,
713 GLvoid *data)
714 {
715 _mesa_ProgramCallbackMESA(target, callback, data);
716 }
717
718
719 void
720 _mesa_ProgramCallbackMESA(GLenum target, GLprogramcallbackMESA callback,
721 GLvoid *data)
722 {
723 GET_CURRENT_CONTEXT(ctx);
724
725 switch (target) {
726 case GL_FRAGMENT_PROGRAM_ARB:
727 if (!ctx->Extensions.ARB_fragment_program) {
728 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramCallbackMESA(target)");
729 return;
730 }
731 ctx->FragmentProgram.Callback = callback;
732 ctx->FragmentProgram.CallbackData = data;
733 break;
734 case GL_FRAGMENT_PROGRAM_NV:
735 if (!ctx->Extensions.NV_fragment_program) {
736 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramCallbackMESA(target)");
737 return;
738 }
739 ctx->FragmentProgram.Callback = callback;
740 ctx->FragmentProgram.CallbackData = data;
741 break;
742 case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */
743 if (!ctx->Extensions.ARB_vertex_program &&
744 !ctx->Extensions.ARB_vertex_program) {
745 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramCallbackMESA(target)");
746 return;
747 }
748 ctx->VertexProgram.Callback = callback;
749 ctx->VertexProgram.CallbackData = data;
750 break;
751 default:
752 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramCallbackMESA(target)");
753 return;
754 }
755 }
756
757
758 /* XXX temporary */
759 void
760 glGetProgramRegisterfvMESA(GLenum target,
761 GLsizei len, const GLubyte *registerName,
762 GLfloat *v)
763 {
764 _mesa_GetProgramRegisterfvMESA(target, len, registerName, v);
765 }
766
767
768 void
769 _mesa_GetProgramRegisterfvMESA(GLenum target,
770 GLsizei len, const GLubyte *registerName,
771 GLfloat *v)
772 {
773 char reg[1000];
774 GET_CURRENT_CONTEXT(ctx);
775
776 /* We _should_ be inside glBegin/glEnd */
777 #if 0
778 if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) {
779 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramRegisterfvMESA");
780 return;
781 }
782 #endif
783
784 /* make null-terminated copy of registerName */
785 _mesa_memcpy(reg, registerName, len);
786 reg[len] = 0;
787
788 switch (target) {
789 case GL_VERTEX_PROGRAM_NV:
790 if (!ctx->Extensions.ARB_vertex_program &&
791 !ctx->Extensions.NV_vertex_program) {
792 _mesa_error(ctx, GL_INVALID_ENUM,
793 "glGetProgramRegisterfvMESA(target)");
794 return;
795 }
796 if (!ctx->VertexProgram.Enabled) {
797 _mesa_error(ctx, GL_INVALID_OPERATION,
798 "glGetProgramRegisterfvMESA");
799 return;
800 }
801 /* GL_NV_vertex_program */
802 if (reg[0] == 'R') {
803 /* Temp register */
804 GLint i = _mesa_atoi(reg + 1);
805 if (i >= ctx->Const.MaxVertexProgramTemps) {
806 _mesa_error(ctx, GL_INVALID_VALUE,
807 "glGetProgramRegisterfvMESA(registerName)");
808 return;
809 }
810 COPY_4V(v, ctx->VertexProgram.Machine.Registers
811 [VP_TEMP_REG_START + i]);
812 }
813 else if (reg[0] == 'v' && reg[1] == '[') {
814 /* Vertex Input attribute */
815 GLint i;
816 for (i = 0; i < ctx->Const.MaxVertexProgramAttribs; i++) {
817 const char *name = _mesa_nv_vertex_input_register_name(i);
818 if (_mesa_strncmp(reg + 2, name, 4) == 0) {
819 COPY_4V(v, ctx->VertexProgram.Machine.Registers
820 [VP_INPUT_REG_START + i]);
821 return;
822 }
823 }
824 _mesa_error(ctx, GL_INVALID_VALUE,
825 "glGetProgramRegisterfvMESA(registerName)");
826 return;
827 }
828 else if (reg[0] == 'o' && reg[1] == '[') {
829 /* Vertex output attribute */
830 }
831 /* GL_ARB_vertex_program */
832 else if (_mesa_strncmp(reg, "vertex.", 7) == 0) {
833
834 }
835 else {
836 _mesa_error(ctx, GL_INVALID_VALUE,
837 "glGetProgramRegisterfvMESA(registerName)");
838 return;
839 }
840 break;
841 case GL_FRAGMENT_PROGRAM_ARB:
842 if (!ctx->Extensions.ARB_fragment_program) {
843 _mesa_error(ctx, GL_INVALID_ENUM,
844 "glGetProgramRegisterfvMESA(target)");
845 return;
846 }
847 if (!ctx->FragmentProgram.Enabled) {
848 _mesa_error(ctx, GL_INVALID_OPERATION,
849 "glGetProgramRegisterfvMESA");
850 return;
851 }
852 /* XXX to do */
853 break;
854 case GL_FRAGMENT_PROGRAM_NV:
855 if (!ctx->Extensions.NV_fragment_program) {
856 _mesa_error(ctx, GL_INVALID_ENUM,
857 "glGetProgramRegisterfvMESA(target)");
858 return;
859 }
860 if (!ctx->FragmentProgram.Enabled) {
861 _mesa_error(ctx, GL_INVALID_OPERATION,
862 "glGetProgramRegisterfvMESA");
863 return;
864 }
865 if (reg[0] == 'R') {
866 /* Temp register */
867 GLint i = _mesa_atoi(reg + 1);
868 if (i >= ctx->Const.MaxFragmentProgramTemps) {
869 _mesa_error(ctx, GL_INVALID_VALUE,
870 "glGetProgramRegisterfvMESA(registerName)");
871 return;
872 }
873 COPY_4V(v,
874 ctx->FragmentProgram.Machine.Registers[FP_TEMP_REG_START + i]);
875 }
876 else if (reg[0] == 'f' && reg[1] == '[') {
877 /* Fragment input attribute */
878 GLint i;
879 for (i = 0; i < ctx->Const.MaxFragmentProgramAttribs; i++) {
880 const char *name = _mesa_nv_fragment_input_register_name(i);
881 if (_mesa_strncmp(reg + 2, name, 4) == 0) {
882 COPY_4V(v, ctx->FragmentProgram.Machine.Registers
883 [FP_INPUT_REG_START + i]);
884 return;
885 }
886 }
887 _mesa_error(ctx, GL_INVALID_VALUE,
888 "glGetProgramRegisterfvMESA(registerName)");
889 return;
890 }
891 else if (_mesa_strcmp(reg, "o[COLR]") == 0) {
892 /* Fragment output color */
893 COPY_4V(v, ctx->FragmentProgram.Machine.Registers
894 [FP_OUTPUT_REG_START + FRAG_OUTPUT_COLR]);
895 }
896 else if (_mesa_strcmp(reg, "o[COLH]") == 0) {
897 /* Fragment output color */
898 COPY_4V(v, ctx->FragmentProgram.Machine.Registers
899 [FP_OUTPUT_REG_START + FRAG_OUTPUT_COLH]);
900 }
901 else if (_mesa_strcmp(reg, "o[DEPR]") == 0) {
902 /* Fragment output depth */
903 COPY_4V(v, ctx->FragmentProgram.Machine.Registers
904 [FP_OUTPUT_REG_START + FRAG_OUTPUT_DEPR]);
905 }
906 else {
907 _mesa_error(ctx, GL_INVALID_VALUE,
908 "glGetProgramRegisterfvMESA(registerName)");
909 return;
910 }
911 break;
912 default:
913 _mesa_error(ctx, GL_INVALID_ENUM,
914 "glGetProgramRegisterfvMESA(target)");
915 return;
916 }
917
918 }