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