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