Added arbprogram.c to Makefiles.
[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 }
467 if (!prog && program > 0){
468 /* allocate new program */
469 prog = _mesa_alloc_program(ctx, target, program);
470 if (!prog) {
471 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindProgramARB");
472 return;
473 }
474 prog->Id = program;
475 prog->Target = target;
476 prog->Resident = GL_TRUE;
477 prog->RefCount = 1;
478 _mesa_HashInsert(ctx->Shared->Programs, program, prog);
479 }
480
481 /* bind now */
482 if (target == GL_VERTEX_PROGRAM_ARB) {
483 ctx->VertexProgram.Current = (struct vertex_program *) prog;
484 }
485 else {
486 ASSERT(target == GL_FRAGMENT_PROGRAM_ARB);
487 ctx->FragmentProgram.Current = (struct fragment_program *) prog;
488 }
489
490 if (prog)
491 prog->RefCount++;
492 }
493
494
495 void
496 _mesa_DeleteProgramsARB(GLsizei n, const GLuint *programs)
497 {
498 _mesa_DeleteProgramsNV(n, programs);
499 }
500
501
502 void
503 _mesa_GenProgramsARB(GLsizei n, GLuint *programs)
504 {
505 _mesa_GenProgramsNV(n, programs);
506 }
507
508
509 GLboolean
510 _mesa_IsProgramARB(GLuint program)
511 {
512 return _mesa_IsProgramNV(program);
513 }
514
515
516 void
517 _mesa_ProgramEnvParameter4dARB(GLenum target, GLuint index,
518 GLdouble x, GLdouble y, GLdouble z, GLdouble w)
519 {
520 _mesa_ProgramEnvParameter4fARB(target, index, x, y, z, w);
521 }
522
523
524 void
525 _mesa_ProgramEnvParameter4dvARB(GLenum target, GLuint index,
526 const GLdouble *params)
527 {
528 _mesa_ProgramEnvParameter4fARB(target, index, params[0], params[1],
529 params[2], params[3]);
530 }
531
532
533 void
534 _mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index,
535 GLfloat x, GLfloat y, GLfloat z, GLfloat w)
536 {
537 GET_CURRENT_CONTEXT(ctx);
538 ASSERT_OUTSIDE_BEGIN_END(ctx);
539
540 if (target == GL_FRAGMENT_PROGRAM_ARB
541 && ctx->Extensions.ARB_fragment_program) {
542 if (index >= ctx->Const.MaxFragmentProgramEnvParams) {
543 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
544 return;
545 }
546 index += MAX_NV_FRAGMENT_PROGRAM_TEMPS; /* XXX fix */
547 ASSIGN_4V(ctx->FragmentProgram.Machine.Registers[index], x, y, z, w);
548 }
549 if (target == GL_VERTEX_PROGRAM_ARB
550 && ctx->Extensions.ARB_vertex_program) {
551 if (index >= ctx->Const.MaxVertexProgramEnvParams) {
552 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
553 return;
554 }
555 index += MAX_NV_VERTEX_PROGRAM_TEMPS; /* XXX fix */
556 ASSIGN_4V(ctx->VertexProgram.Machine.Registers[index], x, y, z, w);
557 }
558 else {
559 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameter(target)");
560 return;
561 }
562 }
563
564
565 void
566 _mesa_ProgramEnvParameter4fvARB(GLenum target, GLuint index,
567 const GLfloat *params)
568 {
569 _mesa_ProgramEnvParameter4fARB(target, index, params[0], params[1],
570 params[2], params[3]);
571 }
572
573
574 void
575 _mesa_GetProgramEnvParameterdvARB(GLenum target, GLuint index,
576 GLdouble *params)
577 {
578 GET_CURRENT_CONTEXT(ctx);
579 GLfloat fparams[4];
580
581 _mesa_GetProgramEnvParameterfvARB(target, index, fparams);
582 if (ctx->ErrorValue == GL_NO_ERROR) {
583 params[0] = fparams[0];
584 params[1] = fparams[1];
585 params[2] = fparams[2];
586 params[3] = fparams[3];
587 }
588 }
589
590
591 void
592 _mesa_GetProgramEnvParameterfvARB(GLenum target, GLuint index,
593 GLfloat *params)
594 {
595 GET_CURRENT_CONTEXT(ctx);
596 ASSERT_OUTSIDE_BEGIN_END(ctx);
597
598 if (target == GL_FRAGMENT_PROGRAM_ARB
599 && ctx->Extensions.ARB_fragment_program) {
600 if (index >= ctx->Const.MaxFragmentProgramEnvParams) {
601 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
602 return;
603 }
604 index += MAX_NV_FRAGMENT_PROGRAM_TEMPS; /* XXX fix */
605 COPY_4V(params, ctx->FragmentProgram.Machine.Registers[index]);
606 }
607 if (target == GL_VERTEX_PROGRAM_ARB
608 && ctx->Extensions.ARB_vertex_program) {
609 if (index >= ctx->Const.MaxVertexProgramEnvParams) {
610 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
611 return;
612 }
613 index += MAX_NV_VERTEX_PROGRAM_TEMPS; /* XXX fix */
614 COPY_4V(params, ctx->VertexProgram.Machine.Registers[index]);
615 }
616 else {
617 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramEnvParameter(target)");
618 return;
619 }
620 }
621
622
623 /**
624 * Note, this function is also used by the GL_NV_fragment_program extension.
625 */
626 void
627 _mesa_ProgramLocalParameter4fARB(GLenum target, GLuint index,
628 GLfloat x, GLfloat y, GLfloat z, GLfloat w)
629 {
630 GET_CURRENT_CONTEXT(ctx);
631 ASSERT_OUTSIDE_BEGIN_END(ctx);
632
633 if ((target == GL_FRAGMENT_PROGRAM_NV
634 && ctx->Extensions.NV_fragment_program) ||
635 (target == GL_FRAGMENT_PROGRAM_ARB
636 && ctx->Extensions.ARB_fragment_program)) {
637 struct fragment_program *fprog = ctx->FragmentProgram.Current;
638 if (!fprog) {
639 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameterARB");
640 return;
641 }
642 if (index >= ctx->Const.MaxFragmentProgramLocalParams) {
643 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
644 return;
645 }
646 fprog->Base.LocalParams[index][0] = x;
647 fprog->Base.LocalParams[index][1] = y;
648 fprog->Base.LocalParams[index][2] = z;
649 fprog->Base.LocalParams[index][3] = w;
650 }
651 else if (target == GL_VERTEX_PROGRAM_ARB
652 && ctx->Extensions.ARB_vertex_program) {
653 struct vertex_program *vprog = ctx->VertexProgram.Current;
654 if (!vprog) {
655 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameterARB");
656 return;
657 }
658 if (index >= ctx->Const.MaxVertexProgramLocalParams) {
659 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
660 return;
661 }
662 vprog->Base.LocalParams[index][0] = x;
663 vprog->Base.LocalParams[index][1] = y;
664 vprog->Base.LocalParams[index][2] = z;
665 vprog->Base.LocalParams[index][3] = w;
666 }
667 else {
668 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameterARB");
669 return;
670 }
671 }
672
673
674 /**
675 * Note, this function is also used by the GL_NV_fragment_program extension.
676 */
677 void
678 _mesa_ProgramLocalParameter4fvARB(GLenum target, GLuint index,
679 const GLfloat *params)
680 {
681 _mesa_ProgramLocalParameter4fARB(target, index, params[0], params[1],
682 params[2], params[3]);
683 }
684
685
686 /**
687 * Note, this function is also used by the GL_NV_fragment_program extension.
688 */
689 void
690 _mesa_ProgramLocalParameter4dARB(GLenum target, GLuint index,
691 GLdouble x, GLdouble y,
692 GLdouble z, GLdouble w)
693 {
694 _mesa_ProgramLocalParameter4fARB(target, index, (GLfloat) x, (GLfloat) y,
695 (GLfloat) z, (GLfloat) w);
696 }
697
698
699 /**
700 * Note, this function is also used by the GL_NV_fragment_program extension.
701 */
702 void
703 _mesa_ProgramLocalParameter4dvARB(GLenum target, GLuint index,
704 const GLdouble *params)
705 {
706 _mesa_ProgramLocalParameter4fARB(target, index,
707 (GLfloat) params[0], (GLfloat) params[1],
708 (GLfloat) params[2], (GLfloat) params[3]);
709 }
710
711
712 /**
713 * Note, this function is also used by the GL_NV_fragment_program extension.
714 */
715 void
716 _mesa_GetProgramLocalParameterfvARB(GLenum target, GLuint index,
717 GLfloat *params)
718 {
719 const struct program *prog;
720 GLuint maxParams;
721 GET_CURRENT_CONTEXT(ctx);
722 ASSERT_OUTSIDE_BEGIN_END(ctx);
723
724 if (target == GL_VERTEX_PROGRAM_ARB
725 && ctx->Extensions.ARB_vertex_program) {
726 prog = &(ctx->VertexProgram.Current->Base);
727 maxParams = ctx->Const.MaxVertexProgramLocalParams;
728 }
729 else if (target == GL_FRAGMENT_PROGRAM_ARB
730 && ctx->Extensions.ARB_fragment_program) {
731 prog = &(ctx->FragmentProgram.Current->Base);
732 maxParams = ctx->Const.MaxFragmentProgramLocalParams;
733 }
734 else if (target == GL_FRAGMENT_PROGRAM_NV
735 && ctx->Extensions.NV_fragment_program) {
736 prog = &(ctx->FragmentProgram.Current->Base);
737 maxParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
738 }
739 else {
740 _mesa_error(ctx, GL_INVALID_ENUM,
741 "glGetProgramLocalParameterARB(target)");
742 return;
743 }
744
745 if (index >= maxParams) {
746 _mesa_error(ctx, GL_INVALID_VALUE,
747 "glGetProgramLocalParameterARB(index)");
748 return;
749 }
750
751 ASSERT(prog);
752 COPY_4V(params, prog->LocalParams[index]);
753 }
754
755
756 /**
757 * Note, this function is also used by the GL_NV_fragment_program extension.
758 */
759 void
760 _mesa_GetProgramLocalParameterdvARB(GLenum target, GLuint index,
761 GLdouble *params)
762 {
763 GET_CURRENT_CONTEXT(ctx);
764 GLfloat floatParams[4];
765 _mesa_GetProgramLocalParameterfvARB(target, index, floatParams);
766 if (ctx->ErrorValue == GL_NO_ERROR) {
767 COPY_4V(params, floatParams);
768 }
769 }
770
771
772 void
773 _mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params)
774 {
775 struct program *prog;
776 GET_CURRENT_CONTEXT(ctx);
777 ASSERT_OUTSIDE_BEGIN_END(ctx);
778
779 if (target == GL_VERTEX_PROGRAM_ARB
780 && ctx->Extensions.ARB_vertex_program) {
781 prog = &(ctx->VertexProgram.Current->Base);
782 }
783 else if (target == GL_FRAGMENT_PROGRAM_ARB
784 && ctx->Extensions.ARB_vertex_program) {
785 prog = &(ctx->FragmentProgram.Current->Base);
786 }
787 else {
788 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
789 return;
790 }
791
792 ASSERT(prog);
793
794 switch (pname) {
795 case GL_PROGRAM_LENGTH_ARB:
796 *params = prog->String ? _mesa_strlen((char *) prog->String) : 0;
797 break;
798 case GL_PROGRAM_FORMAT_ARB:
799 *params = prog->Format;
800 break;
801 case GL_PROGRAM_BINDING_ARB:
802 *params = prog->Id;
803 break;
804 case GL_PROGRAM_INSTRUCTIONS_ARB:
805 *params = prog->NumInstructions;
806 break;
807 case GL_MAX_PROGRAM_INSTRUCTIONS_ARB:
808 if (target == GL_VERTEX_PROGRAM_ARB)
809 *params = ctx->Const.MaxVertexProgramInstructions;
810 else
811 *params = ctx->Const.MaxFragmentProgramInstructions;
812 break;
813 case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
814 *params = prog->NumInstructions;
815 break;
816 case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
817 if (target == GL_VERTEX_PROGRAM_ARB)
818 *params = ctx->Const.MaxVertexProgramInstructions;
819 else
820 *params = ctx->Const.MaxFragmentProgramInstructions;
821 break;
822 case GL_PROGRAM_TEMPORARIES_ARB:
823 *params = prog->NumTemporaries;
824 break;
825 case GL_MAX_PROGRAM_TEMPORARIES_ARB:
826 if (target == GL_VERTEX_PROGRAM_ARB)
827 *params = ctx->Const.MaxVertexProgramTemps;
828 else
829 *params = ctx->Const.MaxFragmentProgramTemps;
830 break;
831 case GL_PROGRAM_NATIVE_TEMPORARIES_ARB:
832 /* XXX same as GL_PROGRAM_TEMPORARIES_ARB? */
833 *params = prog->NumTemporaries;
834 break;
835 case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB:
836 /* XXX same as 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_PARAMETERS_ARB:
843 *params = prog->NumParameters;
844 break;
845 case GL_MAX_PROGRAM_PARAMETERS_ARB:
846 if (target == GL_VERTEX_PROGRAM_ARB)
847 *params = ctx->Const.MaxVertexProgramLocalParams;
848 else
849 *params = ctx->Const.MaxFragmentProgramLocalParams;
850 break;
851 case GL_PROGRAM_NATIVE_PARAMETERS_ARB:
852 /* XXX same as GL_MAX_PROGRAM_PARAMETERS_ARB? */
853 *params = prog->NumParameters;
854 break;
855 case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB:
856 /* XXX same as 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_ATTRIBS_ARB:
863 *params = prog->NumAttributes;
864 break;
865 case GL_MAX_PROGRAM_ATTRIBS_ARB:
866 if (target == GL_VERTEX_PROGRAM_ARB)
867 *params = ctx->Const.MaxVertexProgramAttribs;
868 else
869 *params = ctx->Const.MaxFragmentProgramAttribs;
870 break;
871 case GL_PROGRAM_NATIVE_ATTRIBS_ARB:
872 /* XXX same as GL_PROGRAM_ATTRIBS_ARB? */
873 *params = prog->NumAttributes;
874 break;
875 case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB:
876 /* XXX same as 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_ADDRESS_REGISTERS_ARB:
883 *params = prog->NumAddressRegs;
884 break;
885 case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB:
886 if (target == GL_VERTEX_PROGRAM_ARB)
887 *params = ctx->Const.MaxVertexProgramAddressRegs;
888 else
889 *params = ctx->Const.MaxFragmentProgramAddressRegs;
890 break;
891 case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
892 /* XXX same as GL_PROGRAM_ADDRESS_REGISTERS_ARB? */
893 *params = prog->NumAddressRegs;
894 break;
895 case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
896 /* XXX same as 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_MAX_PROGRAM_LOCAL_PARAMETERS_ARB:
903 if (target == GL_VERTEX_PROGRAM_ARB)
904 *params = ctx->Const.MaxVertexProgramLocalParams;
905 else
906 *params = ctx->Const.MaxFragmentProgramLocalParams;
907 break;
908 case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB:
909 if (target == GL_VERTEX_PROGRAM_ARB)
910 *params = ctx->Const.MaxVertexProgramEnvParams;
911 else
912 *params = ctx->Const.MaxFragmentProgramEnvParams;
913 break;
914 case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB:
915 /* XXX ok? */
916 *params = GL_TRUE;
917 break;
918
919 /*
920 * The following apply to fragment programs only.
921 */
922 case GL_PROGRAM_ALU_INSTRUCTIONS_ARB:
923 case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
924 if (target != GL_FRAGMENT_PROGRAM_ARB) {
925 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
926 return;
927 }
928 *params = ctx->FragmentProgram.Current->NumAluInstructions;
929 break;
930 case GL_PROGRAM_TEX_INSTRUCTIONS_ARB:
931 case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
932 if (target != GL_FRAGMENT_PROGRAM_ARB) {
933 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
934 return;
935 }
936 *params = ctx->FragmentProgram.Current->NumTexInstructions;
937 break;
938 case GL_PROGRAM_TEX_INDIRECTIONS_ARB:
939 case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
940 if (target != GL_FRAGMENT_PROGRAM_ARB) {
941 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
942 return;
943 }
944 *params = ctx->FragmentProgram.Current->NumTexIndirections;
945 break;
946 case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB:
947 case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
948 if (target != GL_FRAGMENT_PROGRAM_ARB) {
949 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
950 return;
951 }
952 *params = ctx->Const.MaxFragmentProgramAluInstructions;
953 break;
954 case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB:
955 case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
956 if (target != GL_FRAGMENT_PROGRAM_ARB) {
957 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
958 return;
959 }
960 *params = ctx->Const.MaxFragmentProgramTexInstructions;
961 break;
962 case GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB:
963 case GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
964 if (target != GL_FRAGMENT_PROGRAM_ARB) {
965 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
966 return;
967 }
968 *params = ctx->Const.MaxFragmentProgramTexIndirections;
969 break;
970 default:
971 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(pname)");
972 return;
973 }
974 }
975
976
977 void
978 _mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string)
979 {
980 struct program *prog;
981 GET_CURRENT_CONTEXT(ctx);
982 ASSERT_OUTSIDE_BEGIN_END(ctx);
983
984 if (target == GL_VERTEX_PROGRAM_ARB) {
985 prog = &(ctx->VertexProgram.Current->Base);
986 }
987 else if (target == GL_FRAGMENT_PROGRAM_ARB) {
988 prog = &(ctx->FragmentProgram.Current->Base);
989 }
990 else {
991 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(target)");
992 return;
993 }
994
995 ASSERT(prog);
996
997 if (pname != GL_PROGRAM_STRING_ARB) {
998 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(pname)");
999 return;
1000 }
1001
1002 MEMCPY(string, prog->String, _mesa_strlen((char *) prog->String));
1003 }