fix some glBindProgramNV/ARB details
[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 * \brief ARB_vertex/fragment_program state management functions.
28 * \author Brian Paul
29 */
30
31
32 #include "glheader.h"
33 #include "context.h"
34 #include "hash.h"
35 #include "imports.h"
36 #include "macros.h"
37 #include "mtypes.h"
38 #include "nvprogram.h"
39 #include "arbprogram.h"
40
41
42 /* XXX temporary */
43 static void
44 _mesa_parse_arb_vertex_program(GLcontext *ctx, GLenum target,
45 const GLubyte *string, GLsizei len,
46 struct vertex_program *prog)
47 {
48 }
49
50
51 static void
52 _mesa_parse_arb_fragment_program(GLcontext *ctx, GLenum target,
53 const GLubyte *string, GLsizei len,
54 struct fragment_program *prog)
55 {
56 }
57
58
59
60 void
61 _mesa_VertexAttrib1sARB(GLuint index, GLshort x)
62 {
63 }
64
65 void
66 _mesa_VertexAttrib1fARB(GLuint index, GLfloat x)
67 {
68 }
69
70 void
71 _mesa_VertexAttrib1dARB(GLuint index, GLdouble x)
72 {
73 }
74
75 void
76 _mesa_VertexAttrib2sARB(GLuint index, GLshort x, GLshort y)
77 {
78 }
79
80 void
81 _mesa_VertexAttrib2fARB(GLuint index, GLfloat x, GLfloat y)
82 {
83 }
84
85 void
86 _mesa_VertexAttrib2dARB(GLuint index, GLdouble x, GLdouble y)
87 {
88 }
89
90 void
91 _mesa_VertexAttrib3sARB(GLuint index, GLshort x, GLshort y, GLshort z)
92 {
93 }
94
95 void
96 _mesa_VertexAttrib3fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z)
97 {
98 }
99
100 void
101 _mesa_VertexAttrib3dARB(GLuint index, GLdouble x, GLdouble y, GLdouble z)
102 {
103 }
104
105 void
106 _mesa_VertexAttrib4sARB(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w)
107 {
108 }
109
110 void
111 _mesa_VertexAttrib4fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
112 {
113 }
114
115 void
116 _mesa_VertexAttrib4dARB(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
117 {
118 }
119
120 void
121 _mesa_VertexAttrib4NubARB(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w)
122 {
123 }
124
125 void
126 _mesa_VertexAttrib1svARB(GLuint index, const GLshort *v)
127 {
128 }
129
130 void
131 _mesa_VertexAttrib1fvARB(GLuint index, const GLfloat *v)
132 {
133 }
134
135 void
136 _mesa_VertexAttrib1dvARB(GLuint index, const GLdouble *v)
137 {
138 }
139
140 void
141 _mesa_VertexAttrib2svARB(GLuint index, const GLshort *v)
142 {
143 }
144
145 void
146 _mesa_VertexAttrib2fvARB(GLuint index, const GLfloat *v)
147 {
148 }
149
150 void
151 _mesa_VertexAttrib2dvARB(GLuint index, const GLdouble *v)
152 {
153 }
154
155 void
156 _mesa_VertexAttrib3svARB(GLuint index, const GLshort *v)
157 {
158 }
159
160 void
161 _mesa_VertexAttrib3fvARB(GLuint index, const GLfloat *v)
162 {
163 }
164
165 void
166 _mesa_VertexAttrib3dvARB(GLuint index, const GLdouble *v)
167 {
168 }
169
170 void
171 _mesa_VertexAttrib4bvARB(GLuint index, const GLbyte *v)
172 {
173 }
174
175 void
176 _mesa_VertexAttrib4svARB(GLuint index, const GLshort *v)
177 {
178 }
179
180 void
181 _mesa_VertexAttrib4ivARB(GLuint index, const GLint *v)
182 {
183 }
184
185 void
186 _mesa_VertexAttrib4ubvARB(GLuint index, const GLubyte *v)
187 {
188 }
189
190 void
191 _mesa_VertexAttrib4usvARB(GLuint index, const GLushort *v)
192 {
193 }
194
195 void
196 _mesa_VertexAttrib4uivARB(GLuint index, const GLuint *v)
197 {
198 }
199
200 void
201 _mesa_VertexAttrib4fvARB(GLuint index, const GLfloat *v)
202 {
203 }
204
205 void
206 _mesa_VertexAttrib4dvARB(GLuint index, const GLdouble *v)
207 {
208 }
209
210 void
211 _mesa_VertexAttrib4NbvARB(GLuint index, const GLbyte *v)
212 {
213 }
214
215 void
216 _mesa_VertexAttrib4NsvARB(GLuint index, const GLshort *v)
217 {
218 }
219
220 void
221 _mesa_VertexAttrib4NivARB(GLuint index, const GLint *v)
222 {
223 }
224
225 void
226 _mesa_VertexAttrib4NubvARB(GLuint index, const GLubyte *v)
227 {
228 }
229
230 void
231 _mesa_VertexAttrib4NusvARB(GLuint index, const GLushort *v)
232 {
233 }
234
235 void
236 _mesa_VertexAttrib4NuivARB(GLuint index, const GLuint *v)
237 {
238 }
239
240
241 void
242 _mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type,
243 GLboolean normalized, GLsizei stride,
244 const GLvoid *pointer)
245 {
246 }
247
248
249 void
250 _mesa_EnableVertexAttribArrayARB(GLuint index)
251 {
252 GET_CURRENT_CONTEXT(ctx);
253 ASSERT_OUTSIDE_BEGIN_END(ctx);
254
255 if (index >= ctx->Const.MaxVertexProgramAttribs) {
256 _mesa_error(ctx, GL_INVALID_VALUE,
257 "glEnableVertexAttribArrayARB(index)");
258 return;
259 }
260
261 ctx->Array.VertexAttrib[index].Enabled = GL_TRUE;
262 ctx->Array._Enabled |= _NEW_ARRAY_ATTRIB(index);
263 ctx->Array.NewState |= _NEW_ARRAY_ATTRIB(index);
264 }
265
266
267 void
268 _mesa_DisableVertexAttribArrayARB(GLuint index)
269 {
270 GET_CURRENT_CONTEXT(ctx);
271 ASSERT_OUTSIDE_BEGIN_END(ctx);
272
273 if (index >= ctx->Const.MaxVertexProgramAttribs) {
274 _mesa_error(ctx, GL_INVALID_VALUE,
275 "glEnableVertexAttribArrayARB(index)");
276 return;
277 }
278
279 ctx->Array.VertexAttrib[index].Enabled = GL_FALSE;
280 ctx->Array._Enabled &= ~_NEW_ARRAY_ATTRIB(index);
281 ctx->Array.NewState &= ~_NEW_ARRAY_ATTRIB(index);
282 }
283
284
285 void
286 _mesa_GetVertexAttribdvARB(GLuint index, GLenum pname, GLdouble *params)
287 {
288 GLfloat fparams[4];
289 GET_CURRENT_CONTEXT(ctx);
290 ASSERT_OUTSIDE_BEGIN_END(ctx);
291
292 _mesa_GetVertexAttribfvARB(index, pname, fparams);
293 if (ctx->ErrorValue == GL_NO_ERROR) {
294 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
295 COPY_4V(params, fparams);
296 }
297 else {
298 params[0] = fparams[0];
299 }
300 }
301 }
302
303
304 void
305 _mesa_GetVertexAttribfvARB(GLuint index, GLenum pname, GLfloat *params)
306 {
307 GET_CURRENT_CONTEXT(ctx);
308 ASSERT_OUTSIDE_BEGIN_END(ctx);
309
310 if (index == 0 || index >= VERT_ATTRIB_MAX) {
311 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribfvARB(index)");
312 return;
313 }
314
315 switch (pname) {
316 case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB:
317 params[0] = ctx->Array.VertexAttrib[index].Enabled;
318 break;
319 case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB:
320 params[0] = ctx->Array.VertexAttrib[index].Size;
321 break;
322 case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB:
323 params[0] = ctx->Array.VertexAttrib[index].Stride;
324 break;
325 case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB:
326 params[0] = ctx->Array.VertexAttrib[index].Type;
327 break;
328 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB:
329 params[0] = ctx->Array.VertexAttrib[index].Normalized;
330 break;
331 case GL_CURRENT_VERTEX_ATTRIB_ARB:
332 COPY_4V(params, ctx->Current.Attrib[index]);
333 break;
334 default:
335 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribfvARB(pname)");
336 return;
337 }
338 }
339
340
341 void
342 _mesa_GetVertexAttribivARB(GLuint index, GLenum pname, GLint *params)
343 {
344 GLfloat fparams[4];
345 GET_CURRENT_CONTEXT(ctx);
346 ASSERT_OUTSIDE_BEGIN_END(ctx);
347
348 _mesa_GetVertexAttribfvARB(index, pname, fparams);
349 if (ctx->ErrorValue == GL_NO_ERROR) {
350 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
351 COPY_4V(params, fparams); /* float to int */
352 }
353 else {
354 params[0] = fparams[0];
355 }
356 }
357 }
358
359
360 void
361 _mesa_GetVertexAttribPointervARB(GLuint index, GLenum pname, GLvoid **pointer)
362 {
363 GET_CURRENT_CONTEXT(ctx);
364 ASSERT_OUTSIDE_BEGIN_END(ctx);
365
366 if (index >= ctx->Const.MaxVertexProgramAttribs) {
367 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerARB(index)");
368 return;
369 }
370
371 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) {
372 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerARB(pname)");
373 return;
374 }
375
376 *pointer = ctx->Array.VertexAttrib[index].Ptr;;
377 }
378
379
380 void
381 _mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
382 const GLvoid *string)
383 {
384 GET_CURRENT_CONTEXT(ctx);
385 ASSERT_OUTSIDE_BEGIN_END(ctx);
386
387 if (target == GL_VERTEX_PROGRAM_ARB
388 && ctx->Extensions.ARB_vertex_program) {
389 struct vertex_program *prog = ctx->VertexProgram.Current;
390 if (format != GL_PROGRAM_FORMAT_ASCII_ARB) {
391 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(format)");
392 return;
393 }
394 _mesa_parse_arb_vertex_program(ctx, target, string, len, prog);
395 }
396 else if (target == GL_FRAGMENT_PROGRAM_ARB
397 && ctx->Extensions.ARB_fragment_program) {
398 struct fragment_program *prog = ctx->FragmentProgram.Current;
399 if (format != GL_PROGRAM_FORMAT_ASCII_ARB) {
400 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(format)");
401 return;
402 }
403 _mesa_parse_arb_fragment_program(ctx, target, string, len, prog);
404 }
405 else {
406 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(target)");
407 }
408 }
409
410
411 void
412 _mesa_BindProgramARB(GLenum target, GLuint program)
413 {
414 struct program *prog;
415 GET_CURRENT_CONTEXT(ctx);
416 ASSERT_OUTSIDE_BEGIN_END(ctx);
417
418 if (target == GL_VERTEX_PROGRAM_ARB
419 && ctx->Extensions.ARB_vertex_program) {
420 if (ctx->VertexProgram.Current &&
421 ctx->VertexProgram.Current->Base.Id == program)
422 return;
423 /* decrement refcount on previously bound vertex program */
424 if (ctx->VertexProgram.Current) {
425 ctx->VertexProgram.Current->Base.RefCount--;
426 /* and delete if refcount goes below one */
427 if (ctx->VertexProgram.Current->Base.RefCount <= 0) {
428 _mesa_delete_program(ctx, &(ctx->VertexProgram.Current->Base));
429 _mesa_HashRemove(ctx->Shared->Programs, program);
430 }
431 }
432 }
433 else if (target == GL_FRAGMENT_PROGRAM_ARB
434 && ctx->Extensions.ARB_fragment_program) {
435 if (ctx->FragmentProgram.Current &&
436 ctx->FragmentProgram.Current->Base.Id == program)
437 return;
438 /* decrement refcount on previously bound fragment program */
439 if (ctx->FragmentProgram.Current) {
440 ctx->FragmentProgram.Current->Base.RefCount--;
441 /* and delete if refcount goes below one */
442 if (ctx->FragmentProgram.Current->Base.RefCount <= 0) {
443 _mesa_delete_program(ctx, &(ctx->FragmentProgram.Current->Base));
444 _mesa_HashRemove(ctx->Shared->Programs, program);
445 }
446 }
447 }
448 else {
449 _mesa_error(ctx, GL_INVALID_ENUM, "glBindProgramARB(target)");
450 return;
451 }
452
453 /* NOTE: binding to a non-existant program is not an error.
454 * That's supposed to be caught in glBegin.
455 * NOTE: program number 0 is legal here.
456 */
457 if (program == 0) {
458 /* default program */
459 if (target == GL_VERTEX_PROGRAM_ARB)
460 prog = ctx->Shared->DefaultVertexProgram;
461 else
462 prog = ctx->Shared->DefaultFragmentProgram;
463 }
464 else {
465 prog = (struct program *) _mesa_HashLookup(ctx->Shared->Programs, program);
466 if (prog) {
467 if (prog->Target == 0) {
468 /* prog was allocated with glGenProgramsARB */
469 prog->Target = target;
470 }
471 else if (prog->Target != target) {
472 _mesa_error(ctx, GL_INVALID_OPERATION,
473 "glBindProgramARB(target mismatch)");
474 return;
475 }
476 }
477 else {
478 /* allocate a new program now */
479 prog = _mesa_alloc_program(ctx, target, program);
480 if (!prog) {
481 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindProgramARB");
482 return;
483 }
484 prog->Id = program;
485 prog->Target = target;
486 prog->Resident = GL_TRUE;
487 prog->RefCount = 1;
488 _mesa_HashInsert(ctx->Shared->Programs, program, prog);
489 }
490 }
491
492 /* bind now */
493 if (target == GL_VERTEX_PROGRAM_ARB) {
494 ctx->VertexProgram.Current = (struct vertex_program *) prog;
495 }
496 else {
497 ASSERT(target == GL_FRAGMENT_PROGRAM_ARB);
498 ctx->FragmentProgram.Current = (struct fragment_program *) prog;
499 }
500
501 if (prog)
502 prog->RefCount++;
503 }
504
505
506 void
507 _mesa_DeleteProgramsARB(GLsizei n, const GLuint *programs)
508 {
509 _mesa_DeleteProgramsNV(n, programs);
510 }
511
512
513 void
514 _mesa_GenProgramsARB(GLsizei n, GLuint *programs)
515 {
516 _mesa_GenProgramsNV(n, programs);
517 }
518
519
520 GLboolean
521 _mesa_IsProgramARB(GLuint program)
522 {
523 return _mesa_IsProgramNV(program);
524 }
525
526
527 void
528 _mesa_ProgramEnvParameter4dARB(GLenum target, GLuint index,
529 GLdouble x, GLdouble y, GLdouble z, GLdouble w)
530 {
531 _mesa_ProgramEnvParameter4fARB(target, index, x, y, z, w);
532 }
533
534
535 void
536 _mesa_ProgramEnvParameter4dvARB(GLenum target, GLuint index,
537 const GLdouble *params)
538 {
539 _mesa_ProgramEnvParameter4fARB(target, index, params[0], params[1],
540 params[2], params[3]);
541 }
542
543
544 void
545 _mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index,
546 GLfloat x, GLfloat y, GLfloat z, GLfloat w)
547 {
548 GET_CURRENT_CONTEXT(ctx);
549 ASSERT_OUTSIDE_BEGIN_END(ctx);
550
551 if (target == GL_FRAGMENT_PROGRAM_ARB
552 && ctx->Extensions.ARB_fragment_program) {
553 if (index >= ctx->Const.MaxFragmentProgramEnvParams) {
554 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
555 return;
556 }
557 index += MAX_NV_FRAGMENT_PROGRAM_TEMPS; /* XXX fix */
558 ASSIGN_4V(ctx->FragmentProgram.Machine.Registers[index], x, y, z, w);
559 }
560 if (target == GL_VERTEX_PROGRAM_ARB
561 && ctx->Extensions.ARB_vertex_program) {
562 if (index >= ctx->Const.MaxVertexProgramEnvParams) {
563 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
564 return;
565 }
566 index += MAX_NV_VERTEX_PROGRAM_TEMPS; /* XXX fix */
567 ASSIGN_4V(ctx->VertexProgram.Machine.Registers[index], x, y, z, w);
568 }
569 else {
570 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameter(target)");
571 return;
572 }
573 }
574
575
576 void
577 _mesa_ProgramEnvParameter4fvARB(GLenum target, GLuint index,
578 const GLfloat *params)
579 {
580 _mesa_ProgramEnvParameter4fARB(target, index, params[0], params[1],
581 params[2], params[3]);
582 }
583
584
585 void
586 _mesa_GetProgramEnvParameterdvARB(GLenum target, GLuint index,
587 GLdouble *params)
588 {
589 GET_CURRENT_CONTEXT(ctx);
590 GLfloat fparams[4];
591
592 _mesa_GetProgramEnvParameterfvARB(target, index, fparams);
593 if (ctx->ErrorValue == GL_NO_ERROR) {
594 params[0] = fparams[0];
595 params[1] = fparams[1];
596 params[2] = fparams[2];
597 params[3] = fparams[3];
598 }
599 }
600
601
602 void
603 _mesa_GetProgramEnvParameterfvARB(GLenum target, GLuint index,
604 GLfloat *params)
605 {
606 GET_CURRENT_CONTEXT(ctx);
607 ASSERT_OUTSIDE_BEGIN_END(ctx);
608
609 if (target == GL_FRAGMENT_PROGRAM_ARB
610 && ctx->Extensions.ARB_fragment_program) {
611 if (index >= ctx->Const.MaxFragmentProgramEnvParams) {
612 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
613 return;
614 }
615 index += MAX_NV_FRAGMENT_PROGRAM_TEMPS; /* XXX fix */
616 COPY_4V(params, ctx->FragmentProgram.Machine.Registers[index]);
617 }
618 if (target == GL_VERTEX_PROGRAM_ARB
619 && ctx->Extensions.ARB_vertex_program) {
620 if (index >= ctx->Const.MaxVertexProgramEnvParams) {
621 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
622 return;
623 }
624 index += MAX_NV_VERTEX_PROGRAM_TEMPS; /* XXX fix */
625 COPY_4V(params, ctx->VertexProgram.Machine.Registers[index]);
626 }
627 else {
628 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramEnvParameter(target)");
629 return;
630 }
631 }
632
633
634 /**
635 * Note, this function is also used by the GL_NV_fragment_program extension.
636 */
637 void
638 _mesa_ProgramLocalParameter4fARB(GLenum target, GLuint index,
639 GLfloat x, GLfloat y, GLfloat z, GLfloat w)
640 {
641 GET_CURRENT_CONTEXT(ctx);
642 ASSERT_OUTSIDE_BEGIN_END(ctx);
643
644 if ((target == GL_FRAGMENT_PROGRAM_NV
645 && ctx->Extensions.NV_fragment_program) ||
646 (target == GL_FRAGMENT_PROGRAM_ARB
647 && ctx->Extensions.ARB_fragment_program)) {
648 struct fragment_program *fprog = ctx->FragmentProgram.Current;
649 if (!fprog) {
650 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameterARB");
651 return;
652 }
653 if (index >= ctx->Const.MaxFragmentProgramLocalParams) {
654 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
655 return;
656 }
657 fprog->Base.LocalParams[index][0] = x;
658 fprog->Base.LocalParams[index][1] = y;
659 fprog->Base.LocalParams[index][2] = z;
660 fprog->Base.LocalParams[index][3] = w;
661 }
662 else if (target == GL_VERTEX_PROGRAM_ARB
663 && ctx->Extensions.ARB_vertex_program) {
664 struct vertex_program *vprog = ctx->VertexProgram.Current;
665 if (!vprog) {
666 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameterARB");
667 return;
668 }
669 if (index >= ctx->Const.MaxVertexProgramLocalParams) {
670 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
671 return;
672 }
673 vprog->Base.LocalParams[index][0] = x;
674 vprog->Base.LocalParams[index][1] = y;
675 vprog->Base.LocalParams[index][2] = z;
676 vprog->Base.LocalParams[index][3] = w;
677 }
678 else {
679 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameterARB");
680 return;
681 }
682 }
683
684
685 /**
686 * Note, this function is also used by the GL_NV_fragment_program extension.
687 */
688 void
689 _mesa_ProgramLocalParameter4fvARB(GLenum target, GLuint index,
690 const GLfloat *params)
691 {
692 _mesa_ProgramLocalParameter4fARB(target, index, params[0], params[1],
693 params[2], params[3]);
694 }
695
696
697 /**
698 * Note, this function is also used by the GL_NV_fragment_program extension.
699 */
700 void
701 _mesa_ProgramLocalParameter4dARB(GLenum target, GLuint index,
702 GLdouble x, GLdouble y,
703 GLdouble z, GLdouble w)
704 {
705 _mesa_ProgramLocalParameter4fARB(target, index, (GLfloat) x, (GLfloat) y,
706 (GLfloat) z, (GLfloat) w);
707 }
708
709
710 /**
711 * Note, this function is also used by the GL_NV_fragment_program extension.
712 */
713 void
714 _mesa_ProgramLocalParameter4dvARB(GLenum target, GLuint index,
715 const GLdouble *params)
716 {
717 _mesa_ProgramLocalParameter4fARB(target, index,
718 (GLfloat) params[0], (GLfloat) params[1],
719 (GLfloat) params[2], (GLfloat) params[3]);
720 }
721
722
723 /**
724 * Note, this function is also used by the GL_NV_fragment_program extension.
725 */
726 void
727 _mesa_GetProgramLocalParameterfvARB(GLenum target, GLuint index,
728 GLfloat *params)
729 {
730 const struct program *prog;
731 GLuint maxParams;
732 GET_CURRENT_CONTEXT(ctx);
733 ASSERT_OUTSIDE_BEGIN_END(ctx);
734
735 if (target == GL_VERTEX_PROGRAM_ARB
736 && ctx->Extensions.ARB_vertex_program) {
737 prog = &(ctx->VertexProgram.Current->Base);
738 maxParams = ctx->Const.MaxVertexProgramLocalParams;
739 }
740 else if (target == GL_FRAGMENT_PROGRAM_ARB
741 && ctx->Extensions.ARB_fragment_program) {
742 prog = &(ctx->FragmentProgram.Current->Base);
743 maxParams = ctx->Const.MaxFragmentProgramLocalParams;
744 }
745 else if (target == GL_FRAGMENT_PROGRAM_NV
746 && ctx->Extensions.NV_fragment_program) {
747 prog = &(ctx->FragmentProgram.Current->Base);
748 maxParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
749 }
750 else {
751 _mesa_error(ctx, GL_INVALID_ENUM,
752 "glGetProgramLocalParameterARB(target)");
753 return;
754 }
755
756 if (index >= maxParams) {
757 _mesa_error(ctx, GL_INVALID_VALUE,
758 "glGetProgramLocalParameterARB(index)");
759 return;
760 }
761
762 ASSERT(prog);
763 COPY_4V(params, prog->LocalParams[index]);
764 }
765
766
767 /**
768 * Note, this function is also used by the GL_NV_fragment_program extension.
769 */
770 void
771 _mesa_GetProgramLocalParameterdvARB(GLenum target, GLuint index,
772 GLdouble *params)
773 {
774 GET_CURRENT_CONTEXT(ctx);
775 GLfloat floatParams[4];
776 _mesa_GetProgramLocalParameterfvARB(target, index, floatParams);
777 if (ctx->ErrorValue == GL_NO_ERROR) {
778 COPY_4V(params, floatParams);
779 }
780 }
781
782
783 void
784 _mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params)
785 {
786 struct program *prog;
787 GET_CURRENT_CONTEXT(ctx);
788 ASSERT_OUTSIDE_BEGIN_END(ctx);
789
790 if (target == GL_VERTEX_PROGRAM_ARB
791 && ctx->Extensions.ARB_vertex_program) {
792 prog = &(ctx->VertexProgram.Current->Base);
793 }
794 else if (target == GL_FRAGMENT_PROGRAM_ARB
795 && ctx->Extensions.ARB_vertex_program) {
796 prog = &(ctx->FragmentProgram.Current->Base);
797 }
798 else {
799 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
800 return;
801 }
802
803 ASSERT(prog);
804
805 switch (pname) {
806 case GL_PROGRAM_LENGTH_ARB:
807 *params = prog->String ? _mesa_strlen((char *) prog->String) : 0;
808 break;
809 case GL_PROGRAM_FORMAT_ARB:
810 *params = prog->Format;
811 break;
812 case GL_PROGRAM_BINDING_ARB:
813 *params = prog->Id;
814 break;
815 case GL_PROGRAM_INSTRUCTIONS_ARB:
816 *params = prog->NumInstructions;
817 break;
818 case GL_MAX_PROGRAM_INSTRUCTIONS_ARB:
819 if (target == GL_VERTEX_PROGRAM_ARB)
820 *params = ctx->Const.MaxVertexProgramInstructions;
821 else
822 *params = ctx->Const.MaxFragmentProgramInstructions;
823 break;
824 case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
825 *params = prog->NumInstructions;
826 break;
827 case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
828 if (target == GL_VERTEX_PROGRAM_ARB)
829 *params = ctx->Const.MaxVertexProgramInstructions;
830 else
831 *params = ctx->Const.MaxFragmentProgramInstructions;
832 break;
833 case GL_PROGRAM_TEMPORARIES_ARB:
834 *params = prog->NumTemporaries;
835 break;
836 case GL_MAX_PROGRAM_TEMPORARIES_ARB:
837 if (target == GL_VERTEX_PROGRAM_ARB)
838 *params = ctx->Const.MaxVertexProgramTemps;
839 else
840 *params = ctx->Const.MaxFragmentProgramTemps;
841 break;
842 case GL_PROGRAM_NATIVE_TEMPORARIES_ARB:
843 /* XXX same as GL_PROGRAM_TEMPORARIES_ARB? */
844 *params = prog->NumTemporaries;
845 break;
846 case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB:
847 /* XXX same as GL_MAX_PROGRAM_TEMPORARIES_ARB? */
848 if (target == GL_VERTEX_PROGRAM_ARB)
849 *params = ctx->Const.MaxVertexProgramTemps;
850 else
851 *params = ctx->Const.MaxFragmentProgramTemps;
852 break;
853 case GL_PROGRAM_PARAMETERS_ARB:
854 *params = prog->NumParameters;
855 break;
856 case GL_MAX_PROGRAM_PARAMETERS_ARB:
857 if (target == GL_VERTEX_PROGRAM_ARB)
858 *params = ctx->Const.MaxVertexProgramLocalParams;
859 else
860 *params = ctx->Const.MaxFragmentProgramLocalParams;
861 break;
862 case GL_PROGRAM_NATIVE_PARAMETERS_ARB:
863 /* XXX same as GL_MAX_PROGRAM_PARAMETERS_ARB? */
864 *params = prog->NumParameters;
865 break;
866 case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB:
867 /* XXX same as GL_MAX_PROGRAM_PARAMETERS_ARB? */
868 if (target == GL_VERTEX_PROGRAM_ARB)
869 *params = ctx->Const.MaxVertexProgramLocalParams;
870 else
871 *params = ctx->Const.MaxFragmentProgramLocalParams;
872 break;
873 case GL_PROGRAM_ATTRIBS_ARB:
874 *params = prog->NumAttributes;
875 break;
876 case GL_MAX_PROGRAM_ATTRIBS_ARB:
877 if (target == GL_VERTEX_PROGRAM_ARB)
878 *params = ctx->Const.MaxVertexProgramAttribs;
879 else
880 *params = ctx->Const.MaxFragmentProgramAttribs;
881 break;
882 case GL_PROGRAM_NATIVE_ATTRIBS_ARB:
883 /* XXX same as GL_PROGRAM_ATTRIBS_ARB? */
884 *params = prog->NumAttributes;
885 break;
886 case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB:
887 /* XXX same as GL_MAX_PROGRAM_ATTRIBS_ARB? */
888 if (target == GL_VERTEX_PROGRAM_ARB)
889 *params = ctx->Const.MaxVertexProgramAttribs;
890 else
891 *params = ctx->Const.MaxFragmentProgramAttribs;
892 break;
893 case GL_PROGRAM_ADDRESS_REGISTERS_ARB:
894 *params = prog->NumAddressRegs;
895 break;
896 case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB:
897 if (target == GL_VERTEX_PROGRAM_ARB)
898 *params = ctx->Const.MaxVertexProgramAddressRegs;
899 else
900 *params = ctx->Const.MaxFragmentProgramAddressRegs;
901 break;
902 case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
903 /* XXX same as GL_PROGRAM_ADDRESS_REGISTERS_ARB? */
904 *params = prog->NumAddressRegs;
905 break;
906 case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
907 /* XXX same as GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB? */
908 if (target == GL_VERTEX_PROGRAM_ARB)
909 *params = ctx->Const.MaxVertexProgramAddressRegs;
910 else
911 *params = ctx->Const.MaxFragmentProgramAddressRegs;
912 break;
913 case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB:
914 if (target == GL_VERTEX_PROGRAM_ARB)
915 *params = ctx->Const.MaxVertexProgramLocalParams;
916 else
917 *params = ctx->Const.MaxFragmentProgramLocalParams;
918 break;
919 case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB:
920 if (target == GL_VERTEX_PROGRAM_ARB)
921 *params = ctx->Const.MaxVertexProgramEnvParams;
922 else
923 *params = ctx->Const.MaxFragmentProgramEnvParams;
924 break;
925 case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB:
926 /* XXX ok? */
927 *params = GL_TRUE;
928 break;
929
930 /*
931 * The following apply to fragment programs only.
932 */
933 case GL_PROGRAM_ALU_INSTRUCTIONS_ARB:
934 case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
935 if (target != GL_FRAGMENT_PROGRAM_ARB) {
936 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
937 return;
938 }
939 *params = ctx->FragmentProgram.Current->NumAluInstructions;
940 break;
941 case GL_PROGRAM_TEX_INSTRUCTIONS_ARB:
942 case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
943 if (target != GL_FRAGMENT_PROGRAM_ARB) {
944 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
945 return;
946 }
947 *params = ctx->FragmentProgram.Current->NumTexInstructions;
948 break;
949 case GL_PROGRAM_TEX_INDIRECTIONS_ARB:
950 case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
951 if (target != GL_FRAGMENT_PROGRAM_ARB) {
952 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
953 return;
954 }
955 *params = ctx->FragmentProgram.Current->NumTexIndirections;
956 break;
957 case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB:
958 case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
959 if (target != GL_FRAGMENT_PROGRAM_ARB) {
960 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
961 return;
962 }
963 *params = ctx->Const.MaxFragmentProgramAluInstructions;
964 break;
965 case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB:
966 case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
967 if (target != GL_FRAGMENT_PROGRAM_ARB) {
968 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
969 return;
970 }
971 *params = ctx->Const.MaxFragmentProgramTexInstructions;
972 break;
973 case GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB:
974 case GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
975 if (target != GL_FRAGMENT_PROGRAM_ARB) {
976 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
977 return;
978 }
979 *params = ctx->Const.MaxFragmentProgramTexIndirections;
980 break;
981 default:
982 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(pname)");
983 return;
984 }
985 }
986
987
988 void
989 _mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string)
990 {
991 struct program *prog;
992 GET_CURRENT_CONTEXT(ctx);
993 ASSERT_OUTSIDE_BEGIN_END(ctx);
994
995 if (target == GL_VERTEX_PROGRAM_ARB) {
996 prog = &(ctx->VertexProgram.Current->Base);
997 }
998 else if (target == GL_FRAGMENT_PROGRAM_ARB) {
999 prog = &(ctx->FragmentProgram.Current->Base);
1000 }
1001 else {
1002 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(target)");
1003 return;
1004 }
1005
1006 ASSERT(prog);
1007
1008 if (pname != GL_PROGRAM_STRING_ARB) {
1009 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(pname)");
1010 return;
1011 }
1012
1013 MEMCPY(string, prog->String, _mesa_strlen((char *) prog->String));
1014 }