blob: 9cc5488b2b12b9894f0656c60e1fcec8f6d2ce83 [file] [log] [blame]
Michal Krol157ec8b2004-03-10 18:02:01 +00001/*
2 * Mesa 3-D graphics library
Brian Paul05051032005-11-01 04:36:33 +00003 * Version: 6.5
Michal Krol157ec8b2004-03-10 18:02:01 +00004 *
Michal Krolbb38cad2006-04-11 11:41:11 +00005 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
Michal Krol157ec8b2004-03-10 18:02:01 +00006 *
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 * ARB_vertex/fragment_program state management functions.
28 * \author Brian Paul
29 */
30
31
32#include "glheader.h"
33#include "arbprogram.h"
Brian Paul8c41a142005-11-19 15:36:28 +000034#include "arbprogparse.h"
Michal Krol157ec8b2004-03-10 18:02:01 +000035#include "context.h"
36#include "imports.h"
37#include "macros.h"
38#include "mtypes.h"
Michal Krol157ec8b2004-03-10 18:02:01 +000039
40
41void GLAPIENTRY
42_mesa_EnableVertexAttribArrayARB(GLuint index)
43{
44 GET_CURRENT_CONTEXT(ctx);
45 ASSERT_OUTSIDE_BEGIN_END(ctx);
46
Brian Paul05051032005-11-01 04:36:33 +000047 if (index >= ctx->Const.VertexProgram.MaxAttribs) {
Michal Krol157ec8b2004-03-10 18:02:01 +000048 _mesa_error(ctx, GL_INVALID_VALUE,
49 "glEnableVertexAttribArrayARB(index)");
50 return;
51 }
52
53 FLUSH_VERTICES(ctx, _NEW_ARRAY);
54 ctx->Array.VertexAttrib[index].Enabled = GL_TRUE;
55 ctx->Array._Enabled |= _NEW_ARRAY_ATTRIB(index);
56 ctx->Array.NewState |= _NEW_ARRAY_ATTRIB(index);
57}
58
59
60void GLAPIENTRY
61_mesa_DisableVertexAttribArrayARB(GLuint index)
62{
63 GET_CURRENT_CONTEXT(ctx);
64 ASSERT_OUTSIDE_BEGIN_END(ctx);
65
Brian Paul05051032005-11-01 04:36:33 +000066 if (index >= ctx->Const.VertexProgram.MaxAttribs) {
Michal Krol157ec8b2004-03-10 18:02:01 +000067 _mesa_error(ctx, GL_INVALID_VALUE,
68 "glEnableVertexAttribArrayARB(index)");
69 return;
70 }
71
72 FLUSH_VERTICES(ctx, _NEW_ARRAY);
73 ctx->Array.VertexAttrib[index].Enabled = GL_FALSE;
74 ctx->Array._Enabled &= ~_NEW_ARRAY_ATTRIB(index);
75 ctx->Array.NewState |= _NEW_ARRAY_ATTRIB(index);
76}
77
78
79void GLAPIENTRY
80_mesa_GetVertexAttribdvARB(GLuint index, GLenum pname, GLdouble *params)
81{
82 GLfloat fparams[4];
83 GET_CURRENT_CONTEXT(ctx);
84 ASSERT_OUTSIDE_BEGIN_END(ctx);
85
86 _mesa_GetVertexAttribfvARB(index, pname, fparams);
87 if (ctx->ErrorValue == GL_NO_ERROR) {
88 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
89 COPY_4V(params, fparams);
90 }
91 else {
92 params[0] = fparams[0];
93 }
94 }
95}
96
97
98void GLAPIENTRY
99_mesa_GetVertexAttribfvARB(GLuint index, GLenum pname, GLfloat *params)
100{
101 GET_CURRENT_CONTEXT(ctx);
102 ASSERT_OUTSIDE_BEGIN_END(ctx);
103
Brian Paulbe76b7f2004-10-04 14:40:05 +0000104 if (index == 0 || index >= MAX_VERTEX_PROGRAM_ATTRIBS) {
Michal Krol157ec8b2004-03-10 18:02:01 +0000105 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribfvARB(index)");
106 return;
107 }
108
109 switch (pname) {
110 case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB:
111 params[0] = (GLfloat) ctx->Array.VertexAttrib[index].Enabled;
112 break;
113 case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB:
114 params[0] = (GLfloat) ctx->Array.VertexAttrib[index].Size;
115 break;
116 case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB:
117 params[0] = (GLfloat) ctx->Array.VertexAttrib[index].Stride;
118 break;
119 case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB:
120 params[0] = (GLfloat) ctx->Array.VertexAttrib[index].Type;
121 break;
122 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB:
123 params[0] = ctx->Array.VertexAttrib[index].Normalized;
124 break;
125 case GL_CURRENT_VERTEX_ATTRIB_ARB:
Michal Krolbb38cad2006-04-11 11:41:11 +0000126 FLUSH_CURRENT(ctx, 0);
127 COPY_4V(params, ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + index]);
Michal Krol157ec8b2004-03-10 18:02:01 +0000128 break;
129 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB:
130 if (!ctx->Extensions.ARB_vertex_buffer_object) {
131 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribfvARB(pname)");
132 return;
133 }
134 params[0] = (GLfloat) ctx->Array.VertexAttrib[index].BufferObj->Name;
135 default:
136 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribfvARB(pname)");
137 return;
138 }
139}
140
141
142void GLAPIENTRY
143_mesa_GetVertexAttribivARB(GLuint index, GLenum pname, GLint *params)
144{
145 GLfloat fparams[4];
146 GET_CURRENT_CONTEXT(ctx);
147 ASSERT_OUTSIDE_BEGIN_END(ctx);
148
149 _mesa_GetVertexAttribfvARB(index, pname, fparams);
150 if (ctx->ErrorValue == GL_NO_ERROR) {
151 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
152 COPY_4V_CAST(params, fparams, GLint); /* float to int */
153 }
154 else {
155 params[0] = (GLint) fparams[0];
156 }
157 }
158}
159
160
161void GLAPIENTRY
162_mesa_GetVertexAttribPointervARB(GLuint index, GLenum pname, GLvoid **pointer)
163{
164 GET_CURRENT_CONTEXT(ctx);
165 ASSERT_OUTSIDE_BEGIN_END(ctx);
166
Brian Paul05051032005-11-01 04:36:33 +0000167 if (index >= ctx->Const.VertexProgram.MaxAttribs) {
Michal Krol157ec8b2004-03-10 18:02:01 +0000168 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerARB(index)");
169 return;
170 }
171
172 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) {
173 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerARB(pname)");
174 return;
175 }
176
177 *pointer = (GLvoid *) ctx->Array.VertexAttrib[index].Ptr;;
178}
179
180
181void GLAPIENTRY
182_mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
183 const GLvoid *string)
184{
185 GET_CURRENT_CONTEXT(ctx);
186 ASSERT_OUTSIDE_BEGIN_END(ctx);
187
188 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
189
Brian Paul8c41a142005-11-19 15:36:28 +0000190 if (format != GL_PROGRAM_FORMAT_ASCII_ARB) {
191 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(format)");
192 return;
193 }
194
Michal Krol157ec8b2004-03-10 18:02:01 +0000195 if (target == GL_VERTEX_PROGRAM_ARB
196 && ctx->Extensions.ARB_vertex_program) {
197 struct vertex_program *prog = ctx->VertexProgram.Current;
Brian Paul8c41a142005-11-19 15:36:28 +0000198 _mesa_parse_arb_vertex_program(ctx, target, string, len, prog);
Michal Krol157ec8b2004-03-10 18:02:01 +0000199
200 if (ctx->Driver.ProgramStringNotify)
201 ctx->Driver.ProgramStringNotify( ctx, target, &prog->Base );
202 }
203 else if (target == GL_FRAGMENT_PROGRAM_ARB
204 && ctx->Extensions.ARB_fragment_program) {
205 struct fragment_program *prog = ctx->FragmentProgram.Current;
Brian Paul8c41a142005-11-19 15:36:28 +0000206 _mesa_parse_arb_fragment_program(ctx, target, string, len, prog);
Michal Krol157ec8b2004-03-10 18:02:01 +0000207
208 if (ctx->Driver.ProgramStringNotify)
209 ctx->Driver.ProgramStringNotify( ctx, target, &prog->Base );
210 }
211 else {
212 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(target)");
213 return;
214 }
215}
216
217
218void GLAPIENTRY
219_mesa_ProgramEnvParameter4dARB(GLenum target, GLuint index,
220 GLdouble x, GLdouble y, GLdouble z, GLdouble w)
221{
222 _mesa_ProgramEnvParameter4fARB(target, index, (GLfloat) x, (GLfloat) y,
223 (GLfloat) z, (GLfloat) w);
224}
225
226
227void GLAPIENTRY
228_mesa_ProgramEnvParameter4dvARB(GLenum target, GLuint index,
229 const GLdouble *params)
230{
231 _mesa_ProgramEnvParameter4fARB(target, index, (GLfloat) params[0],
232 (GLfloat) params[1], (GLfloat) params[2],
233 (GLfloat) params[3]);
234}
235
236
237void GLAPIENTRY
238_mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index,
239 GLfloat x, GLfloat y, GLfloat z, GLfloat w)
240{
241 GET_CURRENT_CONTEXT(ctx);
242 ASSERT_OUTSIDE_BEGIN_END(ctx);
243
244 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
245
246 if (target == GL_FRAGMENT_PROGRAM_ARB
247 && ctx->Extensions.ARB_fragment_program) {
Brian Paul05051032005-11-01 04:36:33 +0000248 if (index >= ctx->Const.FragmentProgram.MaxEnvParams) {
Michal Krol157ec8b2004-03-10 18:02:01 +0000249 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
250 return;
251 }
252 ASSIGN_4V(ctx->FragmentProgram.Parameters[index], x, y, z, w);
253 }
Brian Paul83c74b72004-10-16 00:29:03 +0000254 else if (target == GL_VERTEX_PROGRAM_ARB
Michal Krol157ec8b2004-03-10 18:02:01 +0000255 && ctx->Extensions.ARB_vertex_program) {
Brian Paul05051032005-11-01 04:36:33 +0000256 if (index >= ctx->Const.VertexProgram.MaxEnvParams) {
Michal Krol157ec8b2004-03-10 18:02:01 +0000257 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
258 return;
259 }
260 ASSIGN_4V(ctx->VertexProgram.Parameters[index], x, y, z, w);
261 }
262 else {
263 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameter(target)");
264 return;
265 }
266}
267
268
269void GLAPIENTRY
270_mesa_ProgramEnvParameter4fvARB(GLenum target, GLuint index,
271 const GLfloat *params)
272{
273 _mesa_ProgramEnvParameter4fARB(target, index, params[0], params[1],
274 params[2], params[3]);
275}
276
277
278void GLAPIENTRY
279_mesa_GetProgramEnvParameterdvARB(GLenum target, GLuint index,
280 GLdouble *params)
281{
282 GET_CURRENT_CONTEXT(ctx);
283 GLfloat fparams[4];
284
285 _mesa_GetProgramEnvParameterfvARB(target, index, fparams);
286 if (ctx->ErrorValue == GL_NO_ERROR) {
287 params[0] = fparams[0];
288 params[1] = fparams[1];
289 params[2] = fparams[2];
290 params[3] = fparams[3];
291 }
292}
293
294
295void GLAPIENTRY
296_mesa_GetProgramEnvParameterfvARB(GLenum target, GLuint index,
297 GLfloat *params)
298{
299 GET_CURRENT_CONTEXT(ctx);
300
301 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
302
303 if (!ctx->_CurrentProgram)
304 ASSERT_OUTSIDE_BEGIN_END(ctx);
305
306 if (target == GL_FRAGMENT_PROGRAM_ARB
307 && ctx->Extensions.ARB_fragment_program) {
Brian Paul05051032005-11-01 04:36:33 +0000308 if (index >= ctx->Const.FragmentProgram.MaxEnvParams) {
Michal Krol157ec8b2004-03-10 18:02:01 +0000309 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
310 return;
311 }
312 COPY_4V(params, ctx->FragmentProgram.Parameters[index]);
313 }
Brian Paul83c74b72004-10-16 00:29:03 +0000314 else if (target == GL_VERTEX_PROGRAM_ARB
Michal Krol157ec8b2004-03-10 18:02:01 +0000315 && ctx->Extensions.ARB_vertex_program) {
Brian Paul05051032005-11-01 04:36:33 +0000316 if (index >= ctx->Const.VertexProgram.MaxEnvParams) {
Michal Krol157ec8b2004-03-10 18:02:01 +0000317 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
318 return;
319 }
320 COPY_4V(params, ctx->VertexProgram.Parameters[index]);
321 }
322 else {
323 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramEnvParameter(target)");
324 return;
325 }
326}
327
328
329/**
330 * Note, this function is also used by the GL_NV_fragment_program extension.
331 */
332void GLAPIENTRY
333_mesa_ProgramLocalParameter4fARB(GLenum target, GLuint index,
334 GLfloat x, GLfloat y, GLfloat z, GLfloat w)
335{
336 GET_CURRENT_CONTEXT(ctx);
337 struct program *prog;
338 ASSERT_OUTSIDE_BEGIN_END(ctx);
339
340 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
341
342 if ((target == GL_FRAGMENT_PROGRAM_NV
343 && ctx->Extensions.NV_fragment_program) ||
344 (target == GL_FRAGMENT_PROGRAM_ARB
345 && ctx->Extensions.ARB_fragment_program)) {
Brian Paul05051032005-11-01 04:36:33 +0000346 if (index >= ctx->Const.FragmentProgram.MaxLocalParams) {
Michal Krol157ec8b2004-03-10 18:02:01 +0000347 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
348 return;
349 }
350 prog = &(ctx->FragmentProgram.Current->Base);
351 }
352 else if (target == GL_VERTEX_PROGRAM_ARB
353 && ctx->Extensions.ARB_vertex_program) {
Brian Paul05051032005-11-01 04:36:33 +0000354 if (index >= ctx->Const.VertexProgram.MaxLocalParams) {
Michal Krol157ec8b2004-03-10 18:02:01 +0000355 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
356 return;
357 }
358 prog = &(ctx->VertexProgram.Current->Base);
359 }
360 else {
361 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameterARB");
362 return;
363 }
364
365 ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS);
366 prog->LocalParams[index][0] = x;
367 prog->LocalParams[index][1] = y;
368 prog->LocalParams[index][2] = z;
369 prog->LocalParams[index][3] = w;
370}
371
372
373/**
374 * Note, this function is also used by the GL_NV_fragment_program extension.
375 */
376void GLAPIENTRY
377_mesa_ProgramLocalParameter4fvARB(GLenum target, GLuint index,
378 const GLfloat *params)
379{
380 _mesa_ProgramLocalParameter4fARB(target, index, params[0], params[1],
381 params[2], params[3]);
382}
383
384
385/**
386 * Note, this function is also used by the GL_NV_fragment_program extension.
387 */
388void GLAPIENTRY
389_mesa_ProgramLocalParameter4dARB(GLenum target, GLuint index,
390 GLdouble x, GLdouble y,
391 GLdouble z, GLdouble w)
392{
393 _mesa_ProgramLocalParameter4fARB(target, index, (GLfloat) x, (GLfloat) y,
394 (GLfloat) z, (GLfloat) w);
395}
396
397
398/**
399 * Note, this function is also used by the GL_NV_fragment_program extension.
400 */
401void GLAPIENTRY
402_mesa_ProgramLocalParameter4dvARB(GLenum target, GLuint index,
403 const GLdouble *params)
404{
405 _mesa_ProgramLocalParameter4fARB(target, index,
406 (GLfloat) params[0], (GLfloat) params[1],
407 (GLfloat) params[2], (GLfloat) params[3]);
408}
409
410
411/**
412 * Note, this function is also used by the GL_NV_fragment_program extension.
413 */
414void GLAPIENTRY
415_mesa_GetProgramLocalParameterfvARB(GLenum target, GLuint index,
416 GLfloat *params)
417{
418 const struct program *prog;
419 GLuint maxParams;
420 GET_CURRENT_CONTEXT(ctx);
421 ASSERT_OUTSIDE_BEGIN_END(ctx);
422
423 if (target == GL_VERTEX_PROGRAM_ARB
424 && ctx->Extensions.ARB_vertex_program) {
425 prog = &(ctx->VertexProgram.Current->Base);
Brian Paul05051032005-11-01 04:36:33 +0000426 maxParams = ctx->Const.VertexProgram.MaxLocalParams;
Michal Krol157ec8b2004-03-10 18:02:01 +0000427 }
428 else if (target == GL_FRAGMENT_PROGRAM_ARB
429 && ctx->Extensions.ARB_fragment_program) {
430 prog = &(ctx->FragmentProgram.Current->Base);
Brian Paul05051032005-11-01 04:36:33 +0000431 maxParams = ctx->Const.FragmentProgram.MaxLocalParams;
Michal Krol157ec8b2004-03-10 18:02:01 +0000432 }
433 else if (target == GL_FRAGMENT_PROGRAM_NV
434 && ctx->Extensions.NV_fragment_program) {
435 prog = &(ctx->FragmentProgram.Current->Base);
436 maxParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
437 }
438 else {
439 _mesa_error(ctx, GL_INVALID_ENUM,
440 "glGetProgramLocalParameterARB(target)");
441 return;
442 }
443
444 if (index >= maxParams) {
445 _mesa_error(ctx, GL_INVALID_VALUE,
446 "glGetProgramLocalParameterARB(index)");
447 return;
448 }
449
450 ASSERT(prog);
451 ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS);
452 COPY_4V(params, prog->LocalParams[index]);
453}
454
455
456/**
457 * Note, this function is also used by the GL_NV_fragment_program extension.
458 */
459void GLAPIENTRY
460_mesa_GetProgramLocalParameterdvARB(GLenum target, GLuint index,
461 GLdouble *params)
462{
463 GET_CURRENT_CONTEXT(ctx);
464 GLfloat floatParams[4];
465 _mesa_GetProgramLocalParameterfvARB(target, index, floatParams);
466 if (ctx->ErrorValue == GL_NO_ERROR) {
467 COPY_4V(params, floatParams);
468 }
469}
470
471
472void GLAPIENTRY
473_mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params)
474{
Brian Paul05051032005-11-01 04:36:33 +0000475 const struct gl_program_constants *limits;
Michal Krol157ec8b2004-03-10 18:02:01 +0000476 struct program *prog;
477 GET_CURRENT_CONTEXT(ctx);
478
479 if (!ctx->_CurrentProgram)
480 ASSERT_OUTSIDE_BEGIN_END(ctx);
481
482 if (target == GL_VERTEX_PROGRAM_ARB
483 && ctx->Extensions.ARB_vertex_program) {
484 prog = &(ctx->VertexProgram.Current->Base);
Brian Paul05051032005-11-01 04:36:33 +0000485 limits = &ctx->Const.VertexProgram;
Michal Krol157ec8b2004-03-10 18:02:01 +0000486 }
487 else if (target == GL_FRAGMENT_PROGRAM_ARB
488 && ctx->Extensions.ARB_fragment_program) {
489 prog = &(ctx->FragmentProgram.Current->Base);
Brian Paul05051032005-11-01 04:36:33 +0000490 limits = &ctx->Const.FragmentProgram;
Michal Krol157ec8b2004-03-10 18:02:01 +0000491 }
492 else {
493 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
494 return;
495 }
496
497 ASSERT(prog);
Brian Paul05051032005-11-01 04:36:33 +0000498 ASSERT(limits);
Michal Krol157ec8b2004-03-10 18:02:01 +0000499
Brian Paul05051032005-11-01 04:36:33 +0000500 /* Queries supported for both vertex and fragment programs */
Michal Krol157ec8b2004-03-10 18:02:01 +0000501 switch (pname) {
502 case GL_PROGRAM_LENGTH_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000503 *params
504 = prog->String ? (GLint) _mesa_strlen((char *) prog->String) : 0;
505 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000506 case GL_PROGRAM_FORMAT_ARB:
507 *params = prog->Format;
Brian Paul05051032005-11-01 04:36:33 +0000508 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000509 case GL_PROGRAM_BINDING_ARB:
510 *params = prog->Id;
Brian Paul05051032005-11-01 04:36:33 +0000511 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000512 case GL_PROGRAM_INSTRUCTIONS_ARB:
513 *params = prog->NumInstructions;
Brian Paul05051032005-11-01 04:36:33 +0000514 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000515 case GL_MAX_PROGRAM_INSTRUCTIONS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000516 *params = limits->MaxInstructions;
517 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000518 case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000519 *params = prog->NumNativeInstructions;
520 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000521 case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000522 *params = limits->MaxNativeInstructions;
523 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000524 case GL_PROGRAM_TEMPORARIES_ARB:
525 *params = prog->NumTemporaries;
Brian Paul05051032005-11-01 04:36:33 +0000526 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000527 case GL_MAX_PROGRAM_TEMPORARIES_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000528 *params = limits->MaxTemps;
529 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000530 case GL_PROGRAM_NATIVE_TEMPORARIES_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000531 *params = prog->NumNativeTemporaries;
532 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000533 case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000534 *params = limits->MaxNativeTemps;
535 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000536 case GL_PROGRAM_PARAMETERS_ARB:
537 *params = prog->NumParameters;
Brian Paul05051032005-11-01 04:36:33 +0000538 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000539 case GL_MAX_PROGRAM_PARAMETERS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000540 *params = limits->MaxParameters;
541 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000542 case GL_PROGRAM_NATIVE_PARAMETERS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000543 *params = prog->NumNativeParameters;
544 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000545 case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000546 *params = limits->MaxNativeParameters;
547 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000548 case GL_PROGRAM_ATTRIBS_ARB:
549 *params = prog->NumAttributes;
Brian Paul05051032005-11-01 04:36:33 +0000550 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000551 case GL_MAX_PROGRAM_ATTRIBS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000552 *params = limits->MaxAttribs;
553 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000554 case GL_PROGRAM_NATIVE_ATTRIBS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000555 *params = prog->NumNativeAttributes;
556 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000557 case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000558 *params = limits->MaxNativeAttribs;
559 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000560 case GL_PROGRAM_ADDRESS_REGISTERS_ARB:
561 *params = prog->NumAddressRegs;
Brian Paul05051032005-11-01 04:36:33 +0000562 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000563 case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000564 *params = limits->MaxAddressRegs;
565 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000566 case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000567 *params = prog->NumNativeAddressRegs;
568 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000569 case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000570 *params = limits->MaxNativeAddressRegs;
571 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000572 case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000573 *params = limits->MaxLocalParams;
574 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000575 case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000576 *params = limits->MaxEnvParams;
577 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000578 case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000579 /*
580 * XXX we may not really need a driver callback here.
581 * If the number of native instructions, registers, etc. used
582 * are all below the maximums, we could return true.
583 * The spec says that even if this query returns true, there's
584 * no guarantee that the program will run in hardware.
585 */
Michal Krol157ec8b2004-03-10 18:02:01 +0000586 if (ctx->Driver.IsProgramNative)
587 *params = ctx->Driver.IsProgramNative( ctx, target, prog );
588 else
589 *params = GL_TRUE;
Michal Krol157ec8b2004-03-10 18:02:01 +0000590 return;
Brian Paul05051032005-11-01 04:36:33 +0000591 default:
592 /* continue with fragment-program only queries below */
593 break;
594 }
595
596 /*
597 * The following apply to fragment programs only (at this time)
598 */
599 if (target == GL_FRAGMENT_PROGRAM_ARB) {
600 const struct fragment_program *fp = ctx->FragmentProgram.Current;
601 switch (pname) {
602 case GL_PROGRAM_ALU_INSTRUCTIONS_ARB:
603 *params = fp->NumNativeAluInstructions;
604 return;
605 case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
606 *params = fp->NumAluInstructions;
607 return;
608 case GL_PROGRAM_TEX_INSTRUCTIONS_ARB:
609 *params = fp->NumTexInstructions;
610 return;
611 case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
612 *params = fp->NumNativeTexInstructions;
613 return;
614 case GL_PROGRAM_TEX_INDIRECTIONS_ARB:
615 *params = fp->NumTexIndirections;
616 return;
617 case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
618 *params = fp->NumNativeTexIndirections;
619 return;
620 case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB:
621 *params = limits->MaxAluInstructions;
622 return;
623 case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
624 *params = limits->MaxNativeAluInstructions;
625 return;
626 case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB:
627 *params = limits->MaxTexInstructions;
628 return;
629 case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
630 *params = limits->MaxNativeTexInstructions;
631 return;
632 case GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB:
633 *params = limits->MaxTexIndirections;
634 return;
635 case GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
636 *params = limits->MaxNativeTexIndirections;
637 return;
638 default:
639 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(pname)");
640 return;
641 }
Michal Krol157ec8b2004-03-10 18:02:01 +0000642 }
643}
644
645
646void GLAPIENTRY
647_mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string)
648{
Brian Paul05051032005-11-01 04:36:33 +0000649 const struct program *prog;
Michal Krol157ec8b2004-03-10 18:02:01 +0000650 GET_CURRENT_CONTEXT(ctx);
651
652 if (!ctx->_CurrentProgram)
653 ASSERT_OUTSIDE_BEGIN_END(ctx);
654
655 if (target == GL_VERTEX_PROGRAM_ARB) {
656 prog = &(ctx->VertexProgram.Current->Base);
657 }
658 else if (target == GL_FRAGMENT_PROGRAM_ARB) {
659 prog = &(ctx->FragmentProgram.Current->Base);
660 }
661 else {
662 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(target)");
663 return;
664 }
665
666 ASSERT(prog);
667
668 if (pname != GL_PROGRAM_STRING_ARB) {
669 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(pname)");
670 return;
671 }
672
Brian Paul05051032005-11-01 04:36:33 +0000673 _mesa_memcpy(string, prog->String, _mesa_strlen((char *) prog->String));
Michal Krol157ec8b2004-03-10 18:02:01 +0000674}