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