2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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.
26 #include "main/glheader.h"
27 #include "main/context.h"
28 #include "main/macros.h"
29 #include "nvfragparse.h"
30 #include "nvvertparse.h"
32 #include "prog_debug.h"
33 #include "prog_parameter.h"
34 #include "prog_instruction.h"
39 * Functions for the experimental GL_MESA_program_debug extension.
45 glProgramCallbackMESA(GLenum target
, GLprogramcallbackMESA callback
,
48 _mesa_ProgramCallbackMESA(target
, callback
, data
);
53 _mesa_ProgramCallbackMESA(GLenum target
, GLprogramcallbackMESA callback
,
56 GET_CURRENT_CONTEXT(ctx
);
59 case GL_FRAGMENT_PROGRAM_ARB
:
60 if (!ctx
->Extensions
.ARB_fragment_program
) {
61 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramCallbackMESA(target)");
64 ctx
->FragmentProgram
.Callback
= callback
;
65 ctx
->FragmentProgram
.CallbackData
= data
;
67 case GL_FRAGMENT_PROGRAM_NV
:
68 if (!ctx
->Extensions
.NV_fragment_program
) {
69 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramCallbackMESA(target)");
72 ctx
->FragmentProgram
.Callback
= callback
;
73 ctx
->FragmentProgram
.CallbackData
= data
;
75 case GL_VERTEX_PROGRAM_ARB
: /* == GL_VERTEX_PROGRAM_NV */
76 if (!ctx
->Extensions
.ARB_vertex_program
&&
77 !ctx
->Extensions
.NV_vertex_program
) {
78 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramCallbackMESA(target)");
81 ctx
->VertexProgram
.Callback
= callback
;
82 ctx
->VertexProgram
.CallbackData
= data
;
85 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramCallbackMESA(target)");
93 glGetProgramRegisterfvMESA(GLenum target
,
94 GLsizei len
, const GLubyte
*registerName
,
97 _mesa_GetProgramRegisterfvMESA(target
, len
, registerName
, v
);
102 _mesa_GetProgramRegisterfvMESA(GLenum target
,
103 GLsizei len
, const GLubyte
*registerName
,
107 GET_CURRENT_CONTEXT(ctx
);
109 /* We _should_ be inside glBegin/glEnd */
111 if (ctx
->Driver
.CurrentExecPrimitive
== PRIM_OUTSIDE_BEGIN_END
) {
112 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetProgramRegisterfvMESA");
117 /* make null-terminated copy of registerName */
118 len
= MIN2((unsigned int) len
, sizeof(reg
) - 1);
119 _mesa_memcpy(reg
, registerName
, len
);
123 case GL_VERTEX_PROGRAM_ARB
: /* == GL_VERTEX_PROGRAM_NV */
124 if (!ctx
->Extensions
.ARB_vertex_program
&&
125 !ctx
->Extensions
.NV_vertex_program
) {
126 _mesa_error(ctx
, GL_INVALID_ENUM
,
127 "glGetProgramRegisterfvMESA(target)");
130 if (!ctx
->VertexProgram
._Enabled
) {
131 _mesa_error(ctx
, GL_INVALID_OPERATION
,
132 "glGetProgramRegisterfvMESA");
135 /* GL_NV_vertex_program */
138 GLint i
= _mesa_atoi(reg
+ 1);
139 if (i
>= (GLint
)ctx
->Const
.VertexProgram
.MaxTemps
) {
140 _mesa_error(ctx
, GL_INVALID_VALUE
,
141 "glGetProgramRegisterfvMESA(registerName)");
144 ctx
->Driver
.GetProgramRegister(ctx
, PROGRAM_TEMPORARY
, i
, v
);
146 else if (reg
[0] == 'v' && reg
[1] == '[') {
147 /* Vertex Input attribute */
149 for (i
= 0; i
< ctx
->Const
.VertexProgram
.MaxAttribs
; i
++) {
150 const char *name
= _mesa_nv_vertex_input_register_name(i
);
152 _mesa_sprintf(number
, "%d", i
);
153 if (_mesa_strncmp(reg
+ 2, name
, 4) == 0 ||
154 _mesa_strncmp(reg
+ 2, number
, _mesa_strlen(number
)) == 0) {
155 ctx
->Driver
.GetProgramRegister(ctx
, PROGRAM_INPUT
, i
, v
);
159 _mesa_error(ctx
, GL_INVALID_VALUE
,
160 "glGetProgramRegisterfvMESA(registerName)");
163 else if (reg
[0] == 'o' && reg
[1] == '[') {
164 /* Vertex output attribute */
166 /* GL_ARB_vertex_program */
167 else if (_mesa_strncmp(reg
, "vertex.", 7) == 0) {
171 _mesa_error(ctx
, GL_INVALID_VALUE
,
172 "glGetProgramRegisterfvMESA(registerName)");
176 case GL_FRAGMENT_PROGRAM_ARB
:
177 if (!ctx
->Extensions
.ARB_fragment_program
) {
178 _mesa_error(ctx
, GL_INVALID_ENUM
,
179 "glGetProgramRegisterfvMESA(target)");
182 if (!ctx
->FragmentProgram
._Enabled
) {
183 _mesa_error(ctx
, GL_INVALID_OPERATION
,
184 "glGetProgramRegisterfvMESA");
189 case GL_FRAGMENT_PROGRAM_NV
:
190 if (!ctx
->Extensions
.NV_fragment_program
) {
191 _mesa_error(ctx
, GL_INVALID_ENUM
,
192 "glGetProgramRegisterfvMESA(target)");
195 if (!ctx
->FragmentProgram
._Enabled
) {
196 _mesa_error(ctx
, GL_INVALID_OPERATION
,
197 "glGetProgramRegisterfvMESA");
202 GLint i
= _mesa_atoi(reg
+ 1);
203 if (i
>= (GLint
)ctx
->Const
.FragmentProgram
.MaxTemps
) {
204 _mesa_error(ctx
, GL_INVALID_VALUE
,
205 "glGetProgramRegisterfvMESA(registerName)");
208 ctx
->Driver
.GetProgramRegister(ctx
, PROGRAM_TEMPORARY
,
211 else if (reg
[0] == 'f' && reg
[1] == '[') {
212 /* Fragment input attribute */
214 for (i
= 0; i
< ctx
->Const
.FragmentProgram
.MaxAttribs
; i
++) {
215 const char *name
= _mesa_nv_fragment_input_register_name(i
);
216 if (_mesa_strncmp(reg
+ 2, name
, 4) == 0) {
217 ctx
->Driver
.GetProgramRegister(ctx
, PROGRAM_INPUT
, i
, v
);
221 _mesa_error(ctx
, GL_INVALID_VALUE
,
222 "glGetProgramRegisterfvMESA(registerName)");
225 else if (_mesa_strcmp(reg
, "o[COLR]") == 0) {
226 /* Fragment output color */
227 ctx
->Driver
.GetProgramRegister(ctx
, PROGRAM_OUTPUT
,
228 FRAG_RESULT_COLR
, v
);
230 else if (_mesa_strcmp(reg
, "o[COLH]") == 0) {
231 /* Fragment output color */
232 ctx
->Driver
.GetProgramRegister(ctx
, PROGRAM_OUTPUT
,
233 FRAG_RESULT_COLH
, v
);
235 else if (_mesa_strcmp(reg
, "o[DEPR]") == 0) {
236 /* Fragment output depth */
237 ctx
->Driver
.GetProgramRegister(ctx
, PROGRAM_OUTPUT
,
238 FRAG_RESULT_DEPR
, v
);
241 /* try user-defined identifiers */
242 const GLfloat
*value
= _mesa_lookup_parameter_value(
243 ctx
->FragmentProgram
.Current
->Base
.Parameters
, -1, reg
);
248 _mesa_error(ctx
, GL_INVALID_VALUE
,
249 "glGetProgramRegisterfvMESA(registerName)");
255 _mesa_error(ctx
, GL_INVALID_ENUM
,
256 "glGetProgramRegisterfvMESA(target)");