blob: e3e5396bb17bdf31841a71e7f20461a90f26994e [file] [log] [blame]
Brian383ecc02007-02-09 15:39:32 -07001/*
2 * Mesa 3-D graphics library
3 * Version: 6.5.3
4 *
5 * Copyright (C) 1999-2007 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#include "glheader.h"
27#include "context.h"
28#include "macros.h"
29#include "nvfragparse.h"
30#include "nvvertparse.h"
31#include "program.h"
32#include "prog_debug.h"
33#include "prog_parameter.h"
34#include "prog_instruction.h"
35
36
37
38/**
39 * Functions for the experimental GL_MESA_program_debug extension.
40 */
41
42
43/* XXX temporary */
44GLAPI void GLAPIENTRY
45glProgramCallbackMESA(GLenum target, GLprogramcallbackMESA callback,
46 GLvoid *data)
47{
48 _mesa_ProgramCallbackMESA(target, callback, data);
49}
50
51
52void
53_mesa_ProgramCallbackMESA(GLenum target, GLprogramcallbackMESA callback,
54 GLvoid *data)
55{
56 GET_CURRENT_CONTEXT(ctx);
57
58 switch (target) {
59 case GL_FRAGMENT_PROGRAM_ARB:
60 if (!ctx->Extensions.ARB_fragment_program) {
61 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramCallbackMESA(target)");
62 return;
63 }
64 ctx->FragmentProgram.Callback = callback;
65 ctx->FragmentProgram.CallbackData = data;
66 break;
67 case GL_FRAGMENT_PROGRAM_NV:
68 if (!ctx->Extensions.NV_fragment_program) {
69 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramCallbackMESA(target)");
70 return;
71 }
72 ctx->FragmentProgram.Callback = callback;
73 ctx->FragmentProgram.CallbackData = data;
74 break;
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)");
79 return;
80 }
81 ctx->VertexProgram.Callback = callback;
82 ctx->VertexProgram.CallbackData = data;
83 break;
84 default:
85 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramCallbackMESA(target)");
86 return;
87 }
88}
89
90
91/* XXX temporary */
92GLAPI void GLAPIENTRY
93glGetProgramRegisterfvMESA(GLenum target,
94 GLsizei len, const GLubyte *registerName,
95 GLfloat *v)
96{
97 _mesa_GetProgramRegisterfvMESA(target, len, registerName, v);
98}
99
100
101void
102_mesa_GetProgramRegisterfvMESA(GLenum target,
103 GLsizei len, const GLubyte *registerName,
104 GLfloat *v)
105{
106 char reg[1000];
107 GET_CURRENT_CONTEXT(ctx);
108
109 /* We _should_ be inside glBegin/glEnd */
110#if 0
111 if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) {
112 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramRegisterfvMESA");
113 return;
114 }
115#endif
116
117 /* make null-terminated copy of registerName */
118 len = MIN2((unsigned int) len, sizeof(reg) - 1);
119 _mesa_memcpy(reg, registerName, len);
120 reg[len] = 0;
121
122 switch (target) {
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)");
128 return;
129 }
130 if (!ctx->VertexProgram._Enabled) {
131 _mesa_error(ctx, GL_INVALID_OPERATION,
132 "glGetProgramRegisterfvMESA");
133 return;
134 }
135 /* GL_NV_vertex_program */
136 if (reg[0] == 'R') {
137 /* Temp register */
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)");
142 return;
143 }
144#if 0 /* FIX ME */
145 ctx->Driver.GetVertexProgramRegister(ctx, PROGRAM_TEMPORARY, i, v);
146#endif
147 }
148 else if (reg[0] == 'v' && reg[1] == '[') {
149 /* Vertex Input attribute */
150 GLuint i;
151 for (i = 0; i < ctx->Const.VertexProgram.MaxAttribs; i++) {
152 const char *name = _mesa_nv_vertex_input_register_name(i);
153 char number[10];
154 _mesa_sprintf(number, "%d", i);
155 if (_mesa_strncmp(reg + 2, name, 4) == 0 ||
156 _mesa_strncmp(reg + 2, number, _mesa_strlen(number)) == 0) {
157#if 0 /* FIX ME */
158 ctx->Driver.GetVertexProgramRegister(ctx, PROGRAM_INPUT,
159 i, v);
160#endif
161 return;
162 }
163 }
164 _mesa_error(ctx, GL_INVALID_VALUE,
165 "glGetProgramRegisterfvMESA(registerName)");
166 return;
167 }
168 else if (reg[0] == 'o' && reg[1] == '[') {
169 /* Vertex output attribute */
170 }
171 /* GL_ARB_vertex_program */
172 else if (_mesa_strncmp(reg, "vertex.", 7) == 0) {
173
174 }
175 else {
176 _mesa_error(ctx, GL_INVALID_VALUE,
177 "glGetProgramRegisterfvMESA(registerName)");
178 return;
179 }
180 break;
181 case GL_FRAGMENT_PROGRAM_ARB:
182 if (!ctx->Extensions.ARB_fragment_program) {
183 _mesa_error(ctx, GL_INVALID_ENUM,
184 "glGetProgramRegisterfvMESA(target)");
185 return;
186 }
187 if (!ctx->FragmentProgram._Enabled) {
188 _mesa_error(ctx, GL_INVALID_OPERATION,
189 "glGetProgramRegisterfvMESA");
190 return;
191 }
192 /* XXX to do */
193 break;
194 case GL_FRAGMENT_PROGRAM_NV:
195 if (!ctx->Extensions.NV_fragment_program) {
196 _mesa_error(ctx, GL_INVALID_ENUM,
197 "glGetProgramRegisterfvMESA(target)");
198 return;
199 }
200 if (!ctx->FragmentProgram._Enabled) {
201 _mesa_error(ctx, GL_INVALID_OPERATION,
202 "glGetProgramRegisterfvMESA");
203 return;
204 }
205 if (reg[0] == 'R') {
206 /* Temp register */
207 GLint i = _mesa_atoi(reg + 1);
208 if (i >= (GLint)ctx->Const.FragmentProgram.MaxTemps) {
209 _mesa_error(ctx, GL_INVALID_VALUE,
210 "glGetProgramRegisterfvMESA(registerName)");
211 return;
212 }
213 ctx->Driver.GetFragmentProgramRegister(ctx, PROGRAM_TEMPORARY,
214 i, v);
215 }
216 else if (reg[0] == 'f' && reg[1] == '[') {
217 /* Fragment input attribute */
218 GLuint i;
219 for (i = 0; i < ctx->Const.FragmentProgram.MaxAttribs; i++) {
220 const char *name = _mesa_nv_fragment_input_register_name(i);
221 if (_mesa_strncmp(reg + 2, name, 4) == 0) {
222 ctx->Driver.GetFragmentProgramRegister(ctx,
223 PROGRAM_INPUT, i, v);
224 return;
225 }
226 }
227 _mesa_error(ctx, GL_INVALID_VALUE,
228 "glGetProgramRegisterfvMESA(registerName)");
229 return;
230 }
231 else if (_mesa_strcmp(reg, "o[COLR]") == 0) {
232 /* Fragment output color */
233 ctx->Driver.GetFragmentProgramRegister(ctx, PROGRAM_OUTPUT,
234 FRAG_RESULT_COLR, v);
235 }
236 else if (_mesa_strcmp(reg, "o[COLH]") == 0) {
237 /* Fragment output color */
238 ctx->Driver.GetFragmentProgramRegister(ctx, PROGRAM_OUTPUT,
239 FRAG_RESULT_COLH, v);
240 }
241 else if (_mesa_strcmp(reg, "o[DEPR]") == 0) {
242 /* Fragment output depth */
243 ctx->Driver.GetFragmentProgramRegister(ctx, PROGRAM_OUTPUT,
244 FRAG_RESULT_DEPR, v);
245 }
246 else {
247 /* try user-defined identifiers */
248 const GLfloat *value = _mesa_lookup_parameter_value(
249 ctx->FragmentProgram.Current->Base.Parameters, -1, reg);
250 if (value) {
251 COPY_4V(v, value);
252 }
253 else {
254 _mesa_error(ctx, GL_INVALID_VALUE,
255 "glGetProgramRegisterfvMESA(registerName)");
256 return;
257 }
258 }
259 break;
260 default:
261 _mesa_error(ctx, GL_INVALID_ENUM,
262 "glGetProgramRegisterfvMESA(target)");
263 return;
264 }
265}