blob: baba887912cd5caf9bb7eee3eba669111165f30d [file] [log] [blame]
Michal Krol157ec8b2004-03-10 18:02:01 +00001/*
2 * Mesa 3-D graphics library
Brian Paulf49c0d02006-11-02 16:20:29 +00003 * Version: 6.5.2
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"
Brian Paulf49c0d02006-11-02 16:20:29 +000039#include "program.h"
Michal Krol157ec8b2004-03-10 18:02:01 +000040
41
42void GLAPIENTRY
43_mesa_EnableVertexAttribArrayARB(GLuint index)
44{
45 GET_CURRENT_CONTEXT(ctx);
46 ASSERT_OUTSIDE_BEGIN_END(ctx);
47
Brian Paul05051032005-11-01 04:36:33 +000048 if (index >= ctx->Const.VertexProgram.MaxAttribs) {
Michal Krol157ec8b2004-03-10 18:02:01 +000049 _mesa_error(ctx, GL_INVALID_VALUE,
50 "glEnableVertexAttribArrayARB(index)");
51 return;
52 }
53
54 FLUSH_VERTICES(ctx, _NEW_ARRAY);
Ian Romanickee34e6e2006-06-12 16:26:29 +000055 ctx->Array.ArrayObj->VertexAttrib[index].Enabled = GL_TRUE;
56 ctx->Array.ArrayObj->_Enabled |= _NEW_ARRAY_ATTRIB(index);
Michal Krol157ec8b2004-03-10 18:02:01 +000057 ctx->Array.NewState |= _NEW_ARRAY_ATTRIB(index);
58}
59
60
61void GLAPIENTRY
62_mesa_DisableVertexAttribArrayARB(GLuint index)
63{
64 GET_CURRENT_CONTEXT(ctx);
65 ASSERT_OUTSIDE_BEGIN_END(ctx);
66
Brian Paul05051032005-11-01 04:36:33 +000067 if (index >= ctx->Const.VertexProgram.MaxAttribs) {
Michal Krol157ec8b2004-03-10 18:02:01 +000068 _mesa_error(ctx, GL_INVALID_VALUE,
69 "glEnableVertexAttribArrayARB(index)");
70 return;
71 }
72
73 FLUSH_VERTICES(ctx, _NEW_ARRAY);
Ian Romanickee34e6e2006-06-12 16:26:29 +000074 ctx->Array.ArrayObj->VertexAttrib[index].Enabled = GL_FALSE;
75 ctx->Array.ArrayObj->_Enabled &= ~_NEW_ARRAY_ATTRIB(index);
Michal Krol157ec8b2004-03-10 18:02:01 +000076 ctx->Array.NewState |= _NEW_ARRAY_ATTRIB(index);
77}
78
79
80void GLAPIENTRY
81_mesa_GetVertexAttribdvARB(GLuint index, GLenum pname, GLdouble *params)
82{
83 GLfloat fparams[4];
84 GET_CURRENT_CONTEXT(ctx);
85 ASSERT_OUTSIDE_BEGIN_END(ctx);
86
87 _mesa_GetVertexAttribfvARB(index, pname, fparams);
88 if (ctx->ErrorValue == GL_NO_ERROR) {
89 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
90 COPY_4V(params, fparams);
91 }
92 else {
93 params[0] = fparams[0];
94 }
95 }
96}
97
98
99void GLAPIENTRY
100_mesa_GetVertexAttribfvARB(GLuint index, GLenum pname, GLfloat *params)
101{
102 GET_CURRENT_CONTEXT(ctx);
103 ASSERT_OUTSIDE_BEGIN_END(ctx);
104
Brian Paul590b5572006-11-04 17:28:38 +0000105 if (index >= MAX_VERTEX_PROGRAM_ATTRIBS) {
Michal Krol157ec8b2004-03-10 18:02:01 +0000106 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribfvARB(index)");
107 return;
108 }
109
110 switch (pname) {
111 case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB:
Ian Romanickee34e6e2006-06-12 16:26:29 +0000112 params[0] = (GLfloat) ctx->Array.ArrayObj->VertexAttrib[index].Enabled;
Michal Krol157ec8b2004-03-10 18:02:01 +0000113 break;
114 case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB:
Ian Romanickee34e6e2006-06-12 16:26:29 +0000115 params[0] = (GLfloat) ctx->Array.ArrayObj->VertexAttrib[index].Size;
Michal Krol157ec8b2004-03-10 18:02:01 +0000116 break;
117 case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB:
Ian Romanickee34e6e2006-06-12 16:26:29 +0000118 params[0] = (GLfloat) ctx->Array.ArrayObj->VertexAttrib[index].Stride;
Michal Krol157ec8b2004-03-10 18:02:01 +0000119 break;
120 case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB:
Ian Romanickee34e6e2006-06-12 16:26:29 +0000121 params[0] = (GLfloat) ctx->Array.ArrayObj->VertexAttrib[index].Type;
Michal Krol157ec8b2004-03-10 18:02:01 +0000122 break;
123 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB:
Ian Romanickee34e6e2006-06-12 16:26:29 +0000124 params[0] = ctx->Array.ArrayObj->VertexAttrib[index].Normalized;
Michal Krol157ec8b2004-03-10 18:02:01 +0000125 break;
126 case GL_CURRENT_VERTEX_ATTRIB_ARB:
Brian Paul590b5572006-11-04 17:28:38 +0000127 if (index == 0) {
128 _mesa_error(ctx, GL_INVALID_OPERATION,
129 "glGetVertexAttribfvARB(pname)");
130 return;
131 }
Michal Krolbb38cad2006-04-11 11:41:11 +0000132 FLUSH_CURRENT(ctx, 0);
133 COPY_4V(params, ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + index]);
Michal Krol157ec8b2004-03-10 18:02:01 +0000134 break;
135 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB:
136 if (!ctx->Extensions.ARB_vertex_buffer_object) {
137 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribfvARB(pname)");
138 return;
139 }
Ian Romanickee34e6e2006-06-12 16:26:29 +0000140 params[0] = (GLfloat) ctx->Array.ArrayObj->VertexAttrib[index].BufferObj->Name;
Tilman Sauerbeck6be81272006-05-30 16:57:52 +0000141 break;
Michal Krol157ec8b2004-03-10 18:02:01 +0000142 default:
143 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribfvARB(pname)");
144 return;
145 }
146}
147
148
149void GLAPIENTRY
150_mesa_GetVertexAttribivARB(GLuint index, GLenum pname, GLint *params)
151{
152 GLfloat fparams[4];
153 GET_CURRENT_CONTEXT(ctx);
154 ASSERT_OUTSIDE_BEGIN_END(ctx);
155
156 _mesa_GetVertexAttribfvARB(index, pname, fparams);
157 if (ctx->ErrorValue == GL_NO_ERROR) {
158 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
159 COPY_4V_CAST(params, fparams, GLint); /* float to int */
160 }
161 else {
162 params[0] = (GLint) fparams[0];
163 }
164 }
165}
166
167
168void GLAPIENTRY
169_mesa_GetVertexAttribPointervARB(GLuint index, GLenum pname, GLvoid **pointer)
170{
171 GET_CURRENT_CONTEXT(ctx);
172 ASSERT_OUTSIDE_BEGIN_END(ctx);
173
Brian Paul05051032005-11-01 04:36:33 +0000174 if (index >= ctx->Const.VertexProgram.MaxAttribs) {
Michal Krol157ec8b2004-03-10 18:02:01 +0000175 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerARB(index)");
176 return;
177 }
178
179 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) {
180 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerARB(pname)");
181 return;
182 }
183
Ian Romanickee34e6e2006-06-12 16:26:29 +0000184 *pointer = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[index].Ptr;
Michal Krol157ec8b2004-03-10 18:02:01 +0000185}
186
187
Brian Paulf49c0d02006-11-02 16:20:29 +0000188/**
189 * Determine if id names a vertex or fragment program.
190 * \note Not compiled into display lists.
191 * \note Called from both glIsProgramNV and glIsProgramARB.
192 * \param id is the program identifier
193 * \return GL_TRUE if id is a program, else GL_FALSE.
194 */
195GLboolean GLAPIENTRY
196_mesa_IsProgramARB(GLuint id)
197{
198 GET_CURRENT_CONTEXT(ctx);
199 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
200
201 if (id == 0)
202 return GL_FALSE;
203
204 if (_mesa_lookup_program(ctx, id))
205 return GL_TRUE;
206 else
207 return GL_FALSE;
208}
209
210
Michal Krol157ec8b2004-03-10 18:02:01 +0000211void GLAPIENTRY
212_mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
213 const GLvoid *string)
214{
215 GET_CURRENT_CONTEXT(ctx);
216 ASSERT_OUTSIDE_BEGIN_END(ctx);
217
218 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
219
Brian Paul8c41a142005-11-19 15:36:28 +0000220 if (format != GL_PROGRAM_FORMAT_ASCII_ARB) {
221 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(format)");
222 return;
223 }
224
Michal Krol157ec8b2004-03-10 18:02:01 +0000225 if (target == GL_VERTEX_PROGRAM_ARB
226 && ctx->Extensions.ARB_vertex_program) {
Brian Paul122629f2006-07-20 16:49:57 +0000227 struct gl_vertex_program *prog = ctx->VertexProgram.Current;
Brian Paul8c41a142005-11-19 15:36:28 +0000228 _mesa_parse_arb_vertex_program(ctx, target, string, len, prog);
Michal Krol157ec8b2004-03-10 18:02:01 +0000229
230 if (ctx->Driver.ProgramStringNotify)
231 ctx->Driver.ProgramStringNotify( ctx, target, &prog->Base );
232 }
233 else if (target == GL_FRAGMENT_PROGRAM_ARB
234 && ctx->Extensions.ARB_fragment_program) {
Brian Paul122629f2006-07-20 16:49:57 +0000235 struct gl_fragment_program *prog = ctx->FragmentProgram.Current;
Brian Paul8c41a142005-11-19 15:36:28 +0000236 _mesa_parse_arb_fragment_program(ctx, target, string, len, prog);
Michal Krol157ec8b2004-03-10 18:02:01 +0000237
238 if (ctx->Driver.ProgramStringNotify)
239 ctx->Driver.ProgramStringNotify( ctx, target, &prog->Base );
240 }
241 else {
242 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(target)");
243 return;
244 }
245}
246
247
248void GLAPIENTRY
249_mesa_ProgramEnvParameter4dARB(GLenum target, GLuint index,
250 GLdouble x, GLdouble y, GLdouble z, GLdouble w)
251{
252 _mesa_ProgramEnvParameter4fARB(target, index, (GLfloat) x, (GLfloat) y,
253 (GLfloat) z, (GLfloat) w);
254}
255
256
257void GLAPIENTRY
258_mesa_ProgramEnvParameter4dvARB(GLenum target, GLuint index,
259 const GLdouble *params)
260{
261 _mesa_ProgramEnvParameter4fARB(target, index, (GLfloat) params[0],
262 (GLfloat) params[1], (GLfloat) params[2],
263 (GLfloat) params[3]);
264}
265
266
267void GLAPIENTRY
268_mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index,
269 GLfloat x, GLfloat y, GLfloat z, GLfloat w)
270{
271 GET_CURRENT_CONTEXT(ctx);
272 ASSERT_OUTSIDE_BEGIN_END(ctx);
273
274 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
275
276 if (target == GL_FRAGMENT_PROGRAM_ARB
277 && ctx->Extensions.ARB_fragment_program) {
Brian Paul05051032005-11-01 04:36:33 +0000278 if (index >= ctx->Const.FragmentProgram.MaxEnvParams) {
Michal Krol157ec8b2004-03-10 18:02:01 +0000279 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
280 return;
281 }
282 ASSIGN_4V(ctx->FragmentProgram.Parameters[index], x, y, z, w);
283 }
Brian Paul83c74b72004-10-16 00:29:03 +0000284 else if (target == GL_VERTEX_PROGRAM_ARB
Michal Krol157ec8b2004-03-10 18:02:01 +0000285 && ctx->Extensions.ARB_vertex_program) {
Brian Paul05051032005-11-01 04:36:33 +0000286 if (index >= ctx->Const.VertexProgram.MaxEnvParams) {
Michal Krol157ec8b2004-03-10 18:02:01 +0000287 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
288 return;
289 }
290 ASSIGN_4V(ctx->VertexProgram.Parameters[index], x, y, z, w);
291 }
292 else {
293 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameter(target)");
294 return;
295 }
296}
297
298
299void GLAPIENTRY
300_mesa_ProgramEnvParameter4fvARB(GLenum target, GLuint index,
301 const GLfloat *params)
302{
303 _mesa_ProgramEnvParameter4fARB(target, index, params[0], params[1],
304 params[2], params[3]);
305}
306
307
308void GLAPIENTRY
Ian Romanick8c41c752006-08-15 16:47:34 +0000309_mesa_ProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count,
310 const GLfloat *params)
311{
312 GET_CURRENT_CONTEXT(ctx);
313 unsigned i;
314 GLfloat * dest;
315 ASSERT_OUTSIDE_BEGIN_END(ctx);
316
317 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
318
319 if (count <= 0) {
320 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameters4fv(count)");
321 }
322
323 if (target == GL_FRAGMENT_PROGRAM_ARB
324 && ctx->Extensions.ARB_fragment_program) {
325 if ((index + count) > ctx->Const.FragmentProgram.MaxEnvParams) {
326 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameters4fv(index + count)");
327 return;
328 }
329 dest = ctx->FragmentProgram.Parameters[index];
330 }
331 else if (target == GL_VERTEX_PROGRAM_ARB
332 && ctx->Extensions.ARB_vertex_program) {
333 if ((index + count) > ctx->Const.VertexProgram.MaxEnvParams) {
334 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameters4fv(index + count)");
335 return;
336 }
337 dest = ctx->VertexProgram.Parameters[index];
338 }
339 else {
340 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameters4fv(target)");
341 return;
342 }
343
344 for ( i = 0 ; i < count ; i++ ) {
345 COPY_4V(dest, params);
346 params += 4;
347 dest += 4;
348 }
349}
350
351
352void GLAPIENTRY
Michal Krol157ec8b2004-03-10 18:02:01 +0000353_mesa_GetProgramEnvParameterdvARB(GLenum target, GLuint index,
354 GLdouble *params)
355{
356 GET_CURRENT_CONTEXT(ctx);
357 GLfloat fparams[4];
358
359 _mesa_GetProgramEnvParameterfvARB(target, index, fparams);
360 if (ctx->ErrorValue == GL_NO_ERROR) {
361 params[0] = fparams[0];
362 params[1] = fparams[1];
363 params[2] = fparams[2];
364 params[3] = fparams[3];
365 }
366}
367
368
369void GLAPIENTRY
370_mesa_GetProgramEnvParameterfvARB(GLenum target, GLuint index,
371 GLfloat *params)
372{
373 GET_CURRENT_CONTEXT(ctx);
374
375 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
376
377 if (!ctx->_CurrentProgram)
378 ASSERT_OUTSIDE_BEGIN_END(ctx);
379
380 if (target == GL_FRAGMENT_PROGRAM_ARB
381 && ctx->Extensions.ARB_fragment_program) {
Brian Paul05051032005-11-01 04:36:33 +0000382 if (index >= ctx->Const.FragmentProgram.MaxEnvParams) {
Michal Krol157ec8b2004-03-10 18:02:01 +0000383 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
384 return;
385 }
386 COPY_4V(params, ctx->FragmentProgram.Parameters[index]);
387 }
Brian Paul83c74b72004-10-16 00:29:03 +0000388 else if (target == GL_VERTEX_PROGRAM_ARB
Michal Krol157ec8b2004-03-10 18:02:01 +0000389 && ctx->Extensions.ARB_vertex_program) {
Brian Paul05051032005-11-01 04:36:33 +0000390 if (index >= ctx->Const.VertexProgram.MaxEnvParams) {
Michal Krol157ec8b2004-03-10 18:02:01 +0000391 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
392 return;
393 }
394 COPY_4V(params, ctx->VertexProgram.Parameters[index]);
395 }
396 else {
397 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramEnvParameter(target)");
398 return;
399 }
400}
401
402
403/**
404 * Note, this function is also used by the GL_NV_fragment_program extension.
405 */
406void GLAPIENTRY
407_mesa_ProgramLocalParameter4fARB(GLenum target, GLuint index,
408 GLfloat x, GLfloat y, GLfloat z, GLfloat w)
409{
410 GET_CURRENT_CONTEXT(ctx);
Brian Paul122629f2006-07-20 16:49:57 +0000411 struct gl_program *prog;
Michal Krol157ec8b2004-03-10 18:02:01 +0000412 ASSERT_OUTSIDE_BEGIN_END(ctx);
413
414 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
415
416 if ((target == GL_FRAGMENT_PROGRAM_NV
417 && ctx->Extensions.NV_fragment_program) ||
418 (target == GL_FRAGMENT_PROGRAM_ARB
419 && ctx->Extensions.ARB_fragment_program)) {
Brian Paul05051032005-11-01 04:36:33 +0000420 if (index >= ctx->Const.FragmentProgram.MaxLocalParams) {
Michal Krol157ec8b2004-03-10 18:02:01 +0000421 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
422 return;
423 }
424 prog = &(ctx->FragmentProgram.Current->Base);
425 }
426 else if (target == GL_VERTEX_PROGRAM_ARB
427 && ctx->Extensions.ARB_vertex_program) {
Brian Paul05051032005-11-01 04:36:33 +0000428 if (index >= ctx->Const.VertexProgram.MaxLocalParams) {
Michal Krol157ec8b2004-03-10 18:02:01 +0000429 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
430 return;
431 }
432 prog = &(ctx->VertexProgram.Current->Base);
433 }
434 else {
435 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameterARB");
436 return;
437 }
438
439 ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS);
440 prog->LocalParams[index][0] = x;
441 prog->LocalParams[index][1] = y;
442 prog->LocalParams[index][2] = z;
443 prog->LocalParams[index][3] = w;
444}
445
446
447/**
448 * Note, this function is also used by the GL_NV_fragment_program extension.
449 */
450void GLAPIENTRY
451_mesa_ProgramLocalParameter4fvARB(GLenum target, GLuint index,
452 const GLfloat *params)
453{
454 _mesa_ProgramLocalParameter4fARB(target, index, params[0], params[1],
455 params[2], params[3]);
456}
457
458
Ian Romanick8c41c752006-08-15 16:47:34 +0000459void GLAPIENTRY
460_mesa_ProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count,
461 const GLfloat *params)
462{
463 GET_CURRENT_CONTEXT(ctx);
464 struct gl_program *prog;
465 unsigned i;
466 ASSERT_OUTSIDE_BEGIN_END(ctx);
467
468 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
469
470 if (count <= 0) {
471 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameters4fv(count)");
472 }
473
474 if (target == GL_FRAGMENT_PROGRAM_ARB
475 && ctx->Extensions.ARB_fragment_program) {
476 if ((index + count) > ctx->Const.FragmentProgram.MaxLocalParams) {
477 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameters4fvEXT(index + count)");
478 return;
479 }
480 prog = &(ctx->FragmentProgram.Current->Base);
481 }
482 else if (target == GL_VERTEX_PROGRAM_ARB
483 && ctx->Extensions.ARB_vertex_program) {
484 if ((index + count) > ctx->Const.VertexProgram.MaxLocalParams) {
485 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameters4fvEXT(index + count)");
486 return;
487 }
488 prog = &(ctx->VertexProgram.Current->Base);
489 }
490 else {
491 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameters4fvEXT(target)");
492 return;
493 }
494
495 for (i = 0; i < count; i++) {
496 ASSERT((index + i) < MAX_PROGRAM_LOCAL_PARAMS);
497 COPY_4V(prog->LocalParams[index + i], params);
498 params += 4;
499 }
500}
501
502
Michal Krol157ec8b2004-03-10 18:02:01 +0000503/**
504 * Note, this function is also used by the GL_NV_fragment_program extension.
505 */
506void GLAPIENTRY
507_mesa_ProgramLocalParameter4dARB(GLenum target, GLuint index,
508 GLdouble x, GLdouble y,
509 GLdouble z, GLdouble w)
510{
511 _mesa_ProgramLocalParameter4fARB(target, index, (GLfloat) x, (GLfloat) y,
512 (GLfloat) z, (GLfloat) w);
513}
514
515
516/**
517 * Note, this function is also used by the GL_NV_fragment_program extension.
518 */
519void GLAPIENTRY
520_mesa_ProgramLocalParameter4dvARB(GLenum target, GLuint index,
521 const GLdouble *params)
522{
523 _mesa_ProgramLocalParameter4fARB(target, index,
524 (GLfloat) params[0], (GLfloat) params[1],
525 (GLfloat) params[2], (GLfloat) params[3]);
526}
527
528
529/**
530 * Note, this function is also used by the GL_NV_fragment_program extension.
531 */
532void GLAPIENTRY
533_mesa_GetProgramLocalParameterfvARB(GLenum target, GLuint index,
534 GLfloat *params)
535{
Brian Paul122629f2006-07-20 16:49:57 +0000536 const struct gl_program *prog;
Michal Krol157ec8b2004-03-10 18:02:01 +0000537 GLuint maxParams;
538 GET_CURRENT_CONTEXT(ctx);
539 ASSERT_OUTSIDE_BEGIN_END(ctx);
540
541 if (target == GL_VERTEX_PROGRAM_ARB
542 && ctx->Extensions.ARB_vertex_program) {
543 prog = &(ctx->VertexProgram.Current->Base);
Brian Paul05051032005-11-01 04:36:33 +0000544 maxParams = ctx->Const.VertexProgram.MaxLocalParams;
Michal Krol157ec8b2004-03-10 18:02:01 +0000545 }
546 else if (target == GL_FRAGMENT_PROGRAM_ARB
547 && ctx->Extensions.ARB_fragment_program) {
548 prog = &(ctx->FragmentProgram.Current->Base);
Brian Paul05051032005-11-01 04:36:33 +0000549 maxParams = ctx->Const.FragmentProgram.MaxLocalParams;
Michal Krol157ec8b2004-03-10 18:02:01 +0000550 }
551 else if (target == GL_FRAGMENT_PROGRAM_NV
552 && ctx->Extensions.NV_fragment_program) {
553 prog = &(ctx->FragmentProgram.Current->Base);
554 maxParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
555 }
556 else {
557 _mesa_error(ctx, GL_INVALID_ENUM,
558 "glGetProgramLocalParameterARB(target)");
559 return;
560 }
561
562 if (index >= maxParams) {
563 _mesa_error(ctx, GL_INVALID_VALUE,
564 "glGetProgramLocalParameterARB(index)");
565 return;
566 }
567
568 ASSERT(prog);
569 ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS);
570 COPY_4V(params, prog->LocalParams[index]);
571}
572
573
574/**
575 * Note, this function is also used by the GL_NV_fragment_program extension.
576 */
577void GLAPIENTRY
578_mesa_GetProgramLocalParameterdvARB(GLenum target, GLuint index,
579 GLdouble *params)
580{
581 GET_CURRENT_CONTEXT(ctx);
582 GLfloat floatParams[4];
583 _mesa_GetProgramLocalParameterfvARB(target, index, floatParams);
584 if (ctx->ErrorValue == GL_NO_ERROR) {
585 COPY_4V(params, floatParams);
586 }
587}
588
589
590void GLAPIENTRY
591_mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params)
592{
Brian Paul05051032005-11-01 04:36:33 +0000593 const struct gl_program_constants *limits;
Brian Paul122629f2006-07-20 16:49:57 +0000594 struct gl_program *prog;
Michal Krol157ec8b2004-03-10 18:02:01 +0000595 GET_CURRENT_CONTEXT(ctx);
596
597 if (!ctx->_CurrentProgram)
598 ASSERT_OUTSIDE_BEGIN_END(ctx);
599
600 if (target == GL_VERTEX_PROGRAM_ARB
601 && ctx->Extensions.ARB_vertex_program) {
602 prog = &(ctx->VertexProgram.Current->Base);
Brian Paul05051032005-11-01 04:36:33 +0000603 limits = &ctx->Const.VertexProgram;
Michal Krol157ec8b2004-03-10 18:02:01 +0000604 }
605 else if (target == GL_FRAGMENT_PROGRAM_ARB
606 && ctx->Extensions.ARB_fragment_program) {
607 prog = &(ctx->FragmentProgram.Current->Base);
Brian Paul05051032005-11-01 04:36:33 +0000608 limits = &ctx->Const.FragmentProgram;
Michal Krol157ec8b2004-03-10 18:02:01 +0000609 }
610 else {
611 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
612 return;
613 }
614
615 ASSERT(prog);
Brian Paul05051032005-11-01 04:36:33 +0000616 ASSERT(limits);
Michal Krol157ec8b2004-03-10 18:02:01 +0000617
Brian Paul05051032005-11-01 04:36:33 +0000618 /* Queries supported for both vertex and fragment programs */
Michal Krol157ec8b2004-03-10 18:02:01 +0000619 switch (pname) {
620 case GL_PROGRAM_LENGTH_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000621 *params
622 = prog->String ? (GLint) _mesa_strlen((char *) prog->String) : 0;
623 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000624 case GL_PROGRAM_FORMAT_ARB:
625 *params = prog->Format;
Brian Paul05051032005-11-01 04:36:33 +0000626 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000627 case GL_PROGRAM_BINDING_ARB:
628 *params = prog->Id;
Brian Paul05051032005-11-01 04:36:33 +0000629 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000630 case GL_PROGRAM_INSTRUCTIONS_ARB:
631 *params = prog->NumInstructions;
Brian Paul05051032005-11-01 04:36:33 +0000632 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000633 case GL_MAX_PROGRAM_INSTRUCTIONS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000634 *params = limits->MaxInstructions;
635 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000636 case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000637 *params = prog->NumNativeInstructions;
638 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000639 case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000640 *params = limits->MaxNativeInstructions;
641 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000642 case GL_PROGRAM_TEMPORARIES_ARB:
643 *params = prog->NumTemporaries;
Brian Paul05051032005-11-01 04:36:33 +0000644 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000645 case GL_MAX_PROGRAM_TEMPORARIES_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000646 *params = limits->MaxTemps;
647 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000648 case GL_PROGRAM_NATIVE_TEMPORARIES_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000649 *params = prog->NumNativeTemporaries;
650 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000651 case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000652 *params = limits->MaxNativeTemps;
653 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000654 case GL_PROGRAM_PARAMETERS_ARB:
655 *params = prog->NumParameters;
Brian Paul05051032005-11-01 04:36:33 +0000656 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000657 case GL_MAX_PROGRAM_PARAMETERS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000658 *params = limits->MaxParameters;
659 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000660 case GL_PROGRAM_NATIVE_PARAMETERS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000661 *params = prog->NumNativeParameters;
662 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000663 case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000664 *params = limits->MaxNativeParameters;
665 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000666 case GL_PROGRAM_ATTRIBS_ARB:
667 *params = prog->NumAttributes;
Brian Paul05051032005-11-01 04:36:33 +0000668 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000669 case GL_MAX_PROGRAM_ATTRIBS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000670 *params = limits->MaxAttribs;
671 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000672 case GL_PROGRAM_NATIVE_ATTRIBS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000673 *params = prog->NumNativeAttributes;
674 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000675 case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000676 *params = limits->MaxNativeAttribs;
677 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000678 case GL_PROGRAM_ADDRESS_REGISTERS_ARB:
679 *params = prog->NumAddressRegs;
Brian Paul05051032005-11-01 04:36:33 +0000680 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000681 case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000682 *params = limits->MaxAddressRegs;
683 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000684 case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000685 *params = prog->NumNativeAddressRegs;
686 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000687 case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000688 *params = limits->MaxNativeAddressRegs;
689 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000690 case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000691 *params = limits->MaxLocalParams;
692 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000693 case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000694 *params = limits->MaxEnvParams;
695 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000696 case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000697 /*
698 * XXX we may not really need a driver callback here.
699 * If the number of native instructions, registers, etc. used
700 * are all below the maximums, we could return true.
701 * The spec says that even if this query returns true, there's
702 * no guarantee that the program will run in hardware.
703 */
Michal Krol157ec8b2004-03-10 18:02:01 +0000704 if (ctx->Driver.IsProgramNative)
705 *params = ctx->Driver.IsProgramNative( ctx, target, prog );
706 else
707 *params = GL_TRUE;
Michal Krol157ec8b2004-03-10 18:02:01 +0000708 return;
Brian Paul05051032005-11-01 04:36:33 +0000709 default:
710 /* continue with fragment-program only queries below */
711 break;
712 }
713
714 /*
715 * The following apply to fragment programs only (at this time)
716 */
717 if (target == GL_FRAGMENT_PROGRAM_ARB) {
Brian Paul122629f2006-07-20 16:49:57 +0000718 const struct gl_fragment_program *fp = ctx->FragmentProgram.Current;
Brian Paul05051032005-11-01 04:36:33 +0000719 switch (pname) {
720 case GL_PROGRAM_ALU_INSTRUCTIONS_ARB:
721 *params = fp->NumNativeAluInstructions;
722 return;
723 case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
724 *params = fp->NumAluInstructions;
725 return;
726 case GL_PROGRAM_TEX_INSTRUCTIONS_ARB:
727 *params = fp->NumTexInstructions;
728 return;
729 case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
730 *params = fp->NumNativeTexInstructions;
731 return;
732 case GL_PROGRAM_TEX_INDIRECTIONS_ARB:
733 *params = fp->NumTexIndirections;
734 return;
735 case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
736 *params = fp->NumNativeTexIndirections;
737 return;
738 case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB:
739 *params = limits->MaxAluInstructions;
740 return;
741 case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
742 *params = limits->MaxNativeAluInstructions;
743 return;
744 case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB:
745 *params = limits->MaxTexInstructions;
746 return;
747 case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
748 *params = limits->MaxNativeTexInstructions;
749 return;
750 case GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB:
751 *params = limits->MaxTexIndirections;
752 return;
753 case GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
754 *params = limits->MaxNativeTexIndirections;
755 return;
756 default:
757 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(pname)");
758 return;
759 }
Michal Krol157ec8b2004-03-10 18:02:01 +0000760 }
761}
762
763
764void GLAPIENTRY
765_mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string)
766{
Brian Paul122629f2006-07-20 16:49:57 +0000767 const struct gl_program *prog;
Michal Krol157ec8b2004-03-10 18:02:01 +0000768 GET_CURRENT_CONTEXT(ctx);
769
770 if (!ctx->_CurrentProgram)
771 ASSERT_OUTSIDE_BEGIN_END(ctx);
772
773 if (target == GL_VERTEX_PROGRAM_ARB) {
774 prog = &(ctx->VertexProgram.Current->Base);
775 }
776 else if (target == GL_FRAGMENT_PROGRAM_ARB) {
777 prog = &(ctx->FragmentProgram.Current->Base);
778 }
779 else {
780 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(target)");
781 return;
782 }
783
784 ASSERT(prog);
785
786 if (pname != GL_PROGRAM_STRING_ARB) {
787 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(pname)");
788 return;
789 }
790
Brian Paul05051032005-11-01 04:36:33 +0000791 _mesa_memcpy(string, prog->String, _mesa_strlen((char *) prog->String));
Michal Krol157ec8b2004-03-10 18:02:01 +0000792}