blob: e1b2a94c8aabeac46a109c7bc1b196e0e298e790 [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 Paulbe76b7f2004-10-04 14:40:05 +0000105 if (index == 0 || 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:
Michal Krolbb38cad2006-04-11 11:41:11 +0000127 FLUSH_CURRENT(ctx, 0);
128 COPY_4V(params, ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + index]);
Michal Krol157ec8b2004-03-10 18:02:01 +0000129 break;
130 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB:
131 if (!ctx->Extensions.ARB_vertex_buffer_object) {
132 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribfvARB(pname)");
133 return;
134 }
Ian Romanickee34e6e2006-06-12 16:26:29 +0000135 params[0] = (GLfloat) ctx->Array.ArrayObj->VertexAttrib[index].BufferObj->Name;
Tilman Sauerbeck6be81272006-05-30 16:57:52 +0000136 break;
Michal Krol157ec8b2004-03-10 18:02:01 +0000137 default:
138 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribfvARB(pname)");
139 return;
140 }
141}
142
143
144void GLAPIENTRY
145_mesa_GetVertexAttribivARB(GLuint index, GLenum pname, GLint *params)
146{
147 GLfloat fparams[4];
148 GET_CURRENT_CONTEXT(ctx);
149 ASSERT_OUTSIDE_BEGIN_END(ctx);
150
151 _mesa_GetVertexAttribfvARB(index, pname, fparams);
152 if (ctx->ErrorValue == GL_NO_ERROR) {
153 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
154 COPY_4V_CAST(params, fparams, GLint); /* float to int */
155 }
156 else {
157 params[0] = (GLint) fparams[0];
158 }
159 }
160}
161
162
163void GLAPIENTRY
164_mesa_GetVertexAttribPointervARB(GLuint index, GLenum pname, GLvoid **pointer)
165{
166 GET_CURRENT_CONTEXT(ctx);
167 ASSERT_OUTSIDE_BEGIN_END(ctx);
168
Brian Paul05051032005-11-01 04:36:33 +0000169 if (index >= ctx->Const.VertexProgram.MaxAttribs) {
Michal Krol157ec8b2004-03-10 18:02:01 +0000170 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerARB(index)");
171 return;
172 }
173
174 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) {
175 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerARB(pname)");
176 return;
177 }
178
Ian Romanickee34e6e2006-06-12 16:26:29 +0000179 *pointer = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[index].Ptr;
Michal Krol157ec8b2004-03-10 18:02:01 +0000180}
181
182
Brian Paulf49c0d02006-11-02 16:20:29 +0000183/**
184 * Determine if id names a vertex or fragment program.
185 * \note Not compiled into display lists.
186 * \note Called from both glIsProgramNV and glIsProgramARB.
187 * \param id is the program identifier
188 * \return GL_TRUE if id is a program, else GL_FALSE.
189 */
190GLboolean GLAPIENTRY
191_mesa_IsProgramARB(GLuint id)
192{
193 GET_CURRENT_CONTEXT(ctx);
194 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
195
196 if (id == 0)
197 return GL_FALSE;
198
199 if (_mesa_lookup_program(ctx, id))
200 return GL_TRUE;
201 else
202 return GL_FALSE;
203}
204
205
Michal Krol157ec8b2004-03-10 18:02:01 +0000206void GLAPIENTRY
207_mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
208 const GLvoid *string)
209{
210 GET_CURRENT_CONTEXT(ctx);
211 ASSERT_OUTSIDE_BEGIN_END(ctx);
212
213 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
214
Brian Paul8c41a142005-11-19 15:36:28 +0000215 if (format != GL_PROGRAM_FORMAT_ASCII_ARB) {
216 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(format)");
217 return;
218 }
219
Michal Krol157ec8b2004-03-10 18:02:01 +0000220 if (target == GL_VERTEX_PROGRAM_ARB
221 && ctx->Extensions.ARB_vertex_program) {
Brian Paul122629f2006-07-20 16:49:57 +0000222 struct gl_vertex_program *prog = ctx->VertexProgram.Current;
Brian Paul8c41a142005-11-19 15:36:28 +0000223 _mesa_parse_arb_vertex_program(ctx, target, string, len, prog);
Michal Krol157ec8b2004-03-10 18:02:01 +0000224
225 if (ctx->Driver.ProgramStringNotify)
226 ctx->Driver.ProgramStringNotify( ctx, target, &prog->Base );
227 }
228 else if (target == GL_FRAGMENT_PROGRAM_ARB
229 && ctx->Extensions.ARB_fragment_program) {
Brian Paul122629f2006-07-20 16:49:57 +0000230 struct gl_fragment_program *prog = ctx->FragmentProgram.Current;
Brian Paul8c41a142005-11-19 15:36:28 +0000231 _mesa_parse_arb_fragment_program(ctx, target, string, len, prog);
Michal Krol157ec8b2004-03-10 18:02:01 +0000232
233 if (ctx->Driver.ProgramStringNotify)
234 ctx->Driver.ProgramStringNotify( ctx, target, &prog->Base );
235 }
236 else {
237 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(target)");
238 return;
239 }
240}
241
242
243void GLAPIENTRY
244_mesa_ProgramEnvParameter4dARB(GLenum target, GLuint index,
245 GLdouble x, GLdouble y, GLdouble z, GLdouble w)
246{
247 _mesa_ProgramEnvParameter4fARB(target, index, (GLfloat) x, (GLfloat) y,
248 (GLfloat) z, (GLfloat) w);
249}
250
251
252void GLAPIENTRY
253_mesa_ProgramEnvParameter4dvARB(GLenum target, GLuint index,
254 const GLdouble *params)
255{
256 _mesa_ProgramEnvParameter4fARB(target, index, (GLfloat) params[0],
257 (GLfloat) params[1], (GLfloat) params[2],
258 (GLfloat) params[3]);
259}
260
261
262void GLAPIENTRY
263_mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index,
264 GLfloat x, GLfloat y, GLfloat z, GLfloat w)
265{
266 GET_CURRENT_CONTEXT(ctx);
267 ASSERT_OUTSIDE_BEGIN_END(ctx);
268
269 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
270
271 if (target == GL_FRAGMENT_PROGRAM_ARB
272 && ctx->Extensions.ARB_fragment_program) {
Brian Paul05051032005-11-01 04:36:33 +0000273 if (index >= ctx->Const.FragmentProgram.MaxEnvParams) {
Michal Krol157ec8b2004-03-10 18:02:01 +0000274 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
275 return;
276 }
277 ASSIGN_4V(ctx->FragmentProgram.Parameters[index], x, y, z, w);
278 }
Brian Paul83c74b72004-10-16 00:29:03 +0000279 else if (target == GL_VERTEX_PROGRAM_ARB
Michal Krol157ec8b2004-03-10 18:02:01 +0000280 && ctx->Extensions.ARB_vertex_program) {
Brian Paul05051032005-11-01 04:36:33 +0000281 if (index >= ctx->Const.VertexProgram.MaxEnvParams) {
Michal Krol157ec8b2004-03-10 18:02:01 +0000282 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
283 return;
284 }
285 ASSIGN_4V(ctx->VertexProgram.Parameters[index], x, y, z, w);
286 }
287 else {
288 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameter(target)");
289 return;
290 }
291}
292
293
294void GLAPIENTRY
295_mesa_ProgramEnvParameter4fvARB(GLenum target, GLuint index,
296 const GLfloat *params)
297{
298 _mesa_ProgramEnvParameter4fARB(target, index, params[0], params[1],
299 params[2], params[3]);
300}
301
302
303void GLAPIENTRY
Ian Romanick8c41c752006-08-15 16:47:34 +0000304_mesa_ProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count,
305 const GLfloat *params)
306{
307 GET_CURRENT_CONTEXT(ctx);
308 unsigned i;
309 GLfloat * dest;
310 ASSERT_OUTSIDE_BEGIN_END(ctx);
311
312 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
313
314 if (count <= 0) {
315 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameters4fv(count)");
316 }
317
318 if (target == GL_FRAGMENT_PROGRAM_ARB
319 && ctx->Extensions.ARB_fragment_program) {
320 if ((index + count) > ctx->Const.FragmentProgram.MaxEnvParams) {
321 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameters4fv(index + count)");
322 return;
323 }
324 dest = ctx->FragmentProgram.Parameters[index];
325 }
326 else if (target == GL_VERTEX_PROGRAM_ARB
327 && ctx->Extensions.ARB_vertex_program) {
328 if ((index + count) > ctx->Const.VertexProgram.MaxEnvParams) {
329 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameters4fv(index + count)");
330 return;
331 }
332 dest = ctx->VertexProgram.Parameters[index];
333 }
334 else {
335 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameters4fv(target)");
336 return;
337 }
338
339 for ( i = 0 ; i < count ; i++ ) {
340 COPY_4V(dest, params);
341 params += 4;
342 dest += 4;
343 }
344}
345
346
347void GLAPIENTRY
Michal Krol157ec8b2004-03-10 18:02:01 +0000348_mesa_GetProgramEnvParameterdvARB(GLenum target, GLuint index,
349 GLdouble *params)
350{
351 GET_CURRENT_CONTEXT(ctx);
352 GLfloat fparams[4];
353
354 _mesa_GetProgramEnvParameterfvARB(target, index, fparams);
355 if (ctx->ErrorValue == GL_NO_ERROR) {
356 params[0] = fparams[0];
357 params[1] = fparams[1];
358 params[2] = fparams[2];
359 params[3] = fparams[3];
360 }
361}
362
363
364void GLAPIENTRY
365_mesa_GetProgramEnvParameterfvARB(GLenum target, GLuint index,
366 GLfloat *params)
367{
368 GET_CURRENT_CONTEXT(ctx);
369
370 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
371
372 if (!ctx->_CurrentProgram)
373 ASSERT_OUTSIDE_BEGIN_END(ctx);
374
375 if (target == GL_FRAGMENT_PROGRAM_ARB
376 && ctx->Extensions.ARB_fragment_program) {
Brian Paul05051032005-11-01 04:36:33 +0000377 if (index >= ctx->Const.FragmentProgram.MaxEnvParams) {
Michal Krol157ec8b2004-03-10 18:02:01 +0000378 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
379 return;
380 }
381 COPY_4V(params, ctx->FragmentProgram.Parameters[index]);
382 }
Brian Paul83c74b72004-10-16 00:29:03 +0000383 else if (target == GL_VERTEX_PROGRAM_ARB
Michal Krol157ec8b2004-03-10 18:02:01 +0000384 && ctx->Extensions.ARB_vertex_program) {
Brian Paul05051032005-11-01 04:36:33 +0000385 if (index >= ctx->Const.VertexProgram.MaxEnvParams) {
Michal Krol157ec8b2004-03-10 18:02:01 +0000386 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
387 return;
388 }
389 COPY_4V(params, ctx->VertexProgram.Parameters[index]);
390 }
391 else {
392 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramEnvParameter(target)");
393 return;
394 }
395}
396
397
398/**
399 * Note, this function is also used by the GL_NV_fragment_program extension.
400 */
401void GLAPIENTRY
402_mesa_ProgramLocalParameter4fARB(GLenum target, GLuint index,
403 GLfloat x, GLfloat y, GLfloat z, GLfloat w)
404{
405 GET_CURRENT_CONTEXT(ctx);
Brian Paul122629f2006-07-20 16:49:57 +0000406 struct gl_program *prog;
Michal Krol157ec8b2004-03-10 18:02:01 +0000407 ASSERT_OUTSIDE_BEGIN_END(ctx);
408
409 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
410
411 if ((target == GL_FRAGMENT_PROGRAM_NV
412 && ctx->Extensions.NV_fragment_program) ||
413 (target == GL_FRAGMENT_PROGRAM_ARB
414 && ctx->Extensions.ARB_fragment_program)) {
Brian Paul05051032005-11-01 04:36:33 +0000415 if (index >= ctx->Const.FragmentProgram.MaxLocalParams) {
Michal Krol157ec8b2004-03-10 18:02:01 +0000416 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
417 return;
418 }
419 prog = &(ctx->FragmentProgram.Current->Base);
420 }
421 else if (target == GL_VERTEX_PROGRAM_ARB
422 && ctx->Extensions.ARB_vertex_program) {
Brian Paul05051032005-11-01 04:36:33 +0000423 if (index >= ctx->Const.VertexProgram.MaxLocalParams) {
Michal Krol157ec8b2004-03-10 18:02:01 +0000424 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
425 return;
426 }
427 prog = &(ctx->VertexProgram.Current->Base);
428 }
429 else {
430 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameterARB");
431 return;
432 }
433
434 ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS);
435 prog->LocalParams[index][0] = x;
436 prog->LocalParams[index][1] = y;
437 prog->LocalParams[index][2] = z;
438 prog->LocalParams[index][3] = w;
439}
440
441
442/**
443 * Note, this function is also used by the GL_NV_fragment_program extension.
444 */
445void GLAPIENTRY
446_mesa_ProgramLocalParameter4fvARB(GLenum target, GLuint index,
447 const GLfloat *params)
448{
449 _mesa_ProgramLocalParameter4fARB(target, index, params[0], params[1],
450 params[2], params[3]);
451}
452
453
Ian Romanick8c41c752006-08-15 16:47:34 +0000454void GLAPIENTRY
455_mesa_ProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count,
456 const GLfloat *params)
457{
458 GET_CURRENT_CONTEXT(ctx);
459 struct gl_program *prog;
460 unsigned i;
461 ASSERT_OUTSIDE_BEGIN_END(ctx);
462
463 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
464
465 if (count <= 0) {
466 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameters4fv(count)");
467 }
468
469 if (target == GL_FRAGMENT_PROGRAM_ARB
470 && ctx->Extensions.ARB_fragment_program) {
471 if ((index + count) > ctx->Const.FragmentProgram.MaxLocalParams) {
472 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameters4fvEXT(index + count)");
473 return;
474 }
475 prog = &(ctx->FragmentProgram.Current->Base);
476 }
477 else if (target == GL_VERTEX_PROGRAM_ARB
478 && ctx->Extensions.ARB_vertex_program) {
479 if ((index + count) > ctx->Const.VertexProgram.MaxLocalParams) {
480 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameters4fvEXT(index + count)");
481 return;
482 }
483 prog = &(ctx->VertexProgram.Current->Base);
484 }
485 else {
486 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameters4fvEXT(target)");
487 return;
488 }
489
490 for (i = 0; i < count; i++) {
491 ASSERT((index + i) < MAX_PROGRAM_LOCAL_PARAMS);
492 COPY_4V(prog->LocalParams[index + i], params);
493 params += 4;
494 }
495}
496
497
Michal Krol157ec8b2004-03-10 18:02:01 +0000498/**
499 * Note, this function is also used by the GL_NV_fragment_program extension.
500 */
501void GLAPIENTRY
502_mesa_ProgramLocalParameter4dARB(GLenum target, GLuint index,
503 GLdouble x, GLdouble y,
504 GLdouble z, GLdouble w)
505{
506 _mesa_ProgramLocalParameter4fARB(target, index, (GLfloat) x, (GLfloat) y,
507 (GLfloat) z, (GLfloat) w);
508}
509
510
511/**
512 * Note, this function is also used by the GL_NV_fragment_program extension.
513 */
514void GLAPIENTRY
515_mesa_ProgramLocalParameter4dvARB(GLenum target, GLuint index,
516 const GLdouble *params)
517{
518 _mesa_ProgramLocalParameter4fARB(target, index,
519 (GLfloat) params[0], (GLfloat) params[1],
520 (GLfloat) params[2], (GLfloat) params[3]);
521}
522
523
524/**
525 * Note, this function is also used by the GL_NV_fragment_program extension.
526 */
527void GLAPIENTRY
528_mesa_GetProgramLocalParameterfvARB(GLenum target, GLuint index,
529 GLfloat *params)
530{
Brian Paul122629f2006-07-20 16:49:57 +0000531 const struct gl_program *prog;
Michal Krol157ec8b2004-03-10 18:02:01 +0000532 GLuint maxParams;
533 GET_CURRENT_CONTEXT(ctx);
534 ASSERT_OUTSIDE_BEGIN_END(ctx);
535
536 if (target == GL_VERTEX_PROGRAM_ARB
537 && ctx->Extensions.ARB_vertex_program) {
538 prog = &(ctx->VertexProgram.Current->Base);
Brian Paul05051032005-11-01 04:36:33 +0000539 maxParams = ctx->Const.VertexProgram.MaxLocalParams;
Michal Krol157ec8b2004-03-10 18:02:01 +0000540 }
541 else if (target == GL_FRAGMENT_PROGRAM_ARB
542 && ctx->Extensions.ARB_fragment_program) {
543 prog = &(ctx->FragmentProgram.Current->Base);
Brian Paul05051032005-11-01 04:36:33 +0000544 maxParams = ctx->Const.FragmentProgram.MaxLocalParams;
Michal Krol157ec8b2004-03-10 18:02:01 +0000545 }
546 else if (target == GL_FRAGMENT_PROGRAM_NV
547 && ctx->Extensions.NV_fragment_program) {
548 prog = &(ctx->FragmentProgram.Current->Base);
549 maxParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
550 }
551 else {
552 _mesa_error(ctx, GL_INVALID_ENUM,
553 "glGetProgramLocalParameterARB(target)");
554 return;
555 }
556
557 if (index >= maxParams) {
558 _mesa_error(ctx, GL_INVALID_VALUE,
559 "glGetProgramLocalParameterARB(index)");
560 return;
561 }
562
563 ASSERT(prog);
564 ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS);
565 COPY_4V(params, prog->LocalParams[index]);
566}
567
568
569/**
570 * Note, this function is also used by the GL_NV_fragment_program extension.
571 */
572void GLAPIENTRY
573_mesa_GetProgramLocalParameterdvARB(GLenum target, GLuint index,
574 GLdouble *params)
575{
576 GET_CURRENT_CONTEXT(ctx);
577 GLfloat floatParams[4];
578 _mesa_GetProgramLocalParameterfvARB(target, index, floatParams);
579 if (ctx->ErrorValue == GL_NO_ERROR) {
580 COPY_4V(params, floatParams);
581 }
582}
583
584
585void GLAPIENTRY
586_mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params)
587{
Brian Paul05051032005-11-01 04:36:33 +0000588 const struct gl_program_constants *limits;
Brian Paul122629f2006-07-20 16:49:57 +0000589 struct gl_program *prog;
Michal Krol157ec8b2004-03-10 18:02:01 +0000590 GET_CURRENT_CONTEXT(ctx);
591
592 if (!ctx->_CurrentProgram)
593 ASSERT_OUTSIDE_BEGIN_END(ctx);
594
595 if (target == GL_VERTEX_PROGRAM_ARB
596 && ctx->Extensions.ARB_vertex_program) {
597 prog = &(ctx->VertexProgram.Current->Base);
Brian Paul05051032005-11-01 04:36:33 +0000598 limits = &ctx->Const.VertexProgram;
Michal Krol157ec8b2004-03-10 18:02:01 +0000599 }
600 else if (target == GL_FRAGMENT_PROGRAM_ARB
601 && ctx->Extensions.ARB_fragment_program) {
602 prog = &(ctx->FragmentProgram.Current->Base);
Brian Paul05051032005-11-01 04:36:33 +0000603 limits = &ctx->Const.FragmentProgram;
Michal Krol157ec8b2004-03-10 18:02:01 +0000604 }
605 else {
606 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
607 return;
608 }
609
610 ASSERT(prog);
Brian Paul05051032005-11-01 04:36:33 +0000611 ASSERT(limits);
Michal Krol157ec8b2004-03-10 18:02:01 +0000612
Brian Paul05051032005-11-01 04:36:33 +0000613 /* Queries supported for both vertex and fragment programs */
Michal Krol157ec8b2004-03-10 18:02:01 +0000614 switch (pname) {
615 case GL_PROGRAM_LENGTH_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000616 *params
617 = prog->String ? (GLint) _mesa_strlen((char *) prog->String) : 0;
618 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000619 case GL_PROGRAM_FORMAT_ARB:
620 *params = prog->Format;
Brian Paul05051032005-11-01 04:36:33 +0000621 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000622 case GL_PROGRAM_BINDING_ARB:
623 *params = prog->Id;
Brian Paul05051032005-11-01 04:36:33 +0000624 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000625 case GL_PROGRAM_INSTRUCTIONS_ARB:
626 *params = prog->NumInstructions;
Brian Paul05051032005-11-01 04:36:33 +0000627 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000628 case GL_MAX_PROGRAM_INSTRUCTIONS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000629 *params = limits->MaxInstructions;
630 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000631 case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000632 *params = prog->NumNativeInstructions;
633 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000634 case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000635 *params = limits->MaxNativeInstructions;
636 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000637 case GL_PROGRAM_TEMPORARIES_ARB:
638 *params = prog->NumTemporaries;
Brian Paul05051032005-11-01 04:36:33 +0000639 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000640 case GL_MAX_PROGRAM_TEMPORARIES_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000641 *params = limits->MaxTemps;
642 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000643 case GL_PROGRAM_NATIVE_TEMPORARIES_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000644 *params = prog->NumNativeTemporaries;
645 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000646 case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000647 *params = limits->MaxNativeTemps;
648 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000649 case GL_PROGRAM_PARAMETERS_ARB:
650 *params = prog->NumParameters;
Brian Paul05051032005-11-01 04:36:33 +0000651 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000652 case GL_MAX_PROGRAM_PARAMETERS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000653 *params = limits->MaxParameters;
654 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000655 case GL_PROGRAM_NATIVE_PARAMETERS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000656 *params = prog->NumNativeParameters;
657 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000658 case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000659 *params = limits->MaxNativeParameters;
660 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000661 case GL_PROGRAM_ATTRIBS_ARB:
662 *params = prog->NumAttributes;
Brian Paul05051032005-11-01 04:36:33 +0000663 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000664 case GL_MAX_PROGRAM_ATTRIBS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000665 *params = limits->MaxAttribs;
666 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000667 case GL_PROGRAM_NATIVE_ATTRIBS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000668 *params = prog->NumNativeAttributes;
669 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000670 case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000671 *params = limits->MaxNativeAttribs;
672 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000673 case GL_PROGRAM_ADDRESS_REGISTERS_ARB:
674 *params = prog->NumAddressRegs;
Brian Paul05051032005-11-01 04:36:33 +0000675 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000676 case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000677 *params = limits->MaxAddressRegs;
678 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000679 case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000680 *params = prog->NumNativeAddressRegs;
681 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000682 case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000683 *params = limits->MaxNativeAddressRegs;
684 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000685 case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000686 *params = limits->MaxLocalParams;
687 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000688 case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000689 *params = limits->MaxEnvParams;
690 return;
Michal Krol157ec8b2004-03-10 18:02:01 +0000691 case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB:
Brian Paul05051032005-11-01 04:36:33 +0000692 /*
693 * XXX we may not really need a driver callback here.
694 * If the number of native instructions, registers, etc. used
695 * are all below the maximums, we could return true.
696 * The spec says that even if this query returns true, there's
697 * no guarantee that the program will run in hardware.
698 */
Michal Krol157ec8b2004-03-10 18:02:01 +0000699 if (ctx->Driver.IsProgramNative)
700 *params = ctx->Driver.IsProgramNative( ctx, target, prog );
701 else
702 *params = GL_TRUE;
Michal Krol157ec8b2004-03-10 18:02:01 +0000703 return;
Brian Paul05051032005-11-01 04:36:33 +0000704 default:
705 /* continue with fragment-program only queries below */
706 break;
707 }
708
709 /*
710 * The following apply to fragment programs only (at this time)
711 */
712 if (target == GL_FRAGMENT_PROGRAM_ARB) {
Brian Paul122629f2006-07-20 16:49:57 +0000713 const struct gl_fragment_program *fp = ctx->FragmentProgram.Current;
Brian Paul05051032005-11-01 04:36:33 +0000714 switch (pname) {
715 case GL_PROGRAM_ALU_INSTRUCTIONS_ARB:
716 *params = fp->NumNativeAluInstructions;
717 return;
718 case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
719 *params = fp->NumAluInstructions;
720 return;
721 case GL_PROGRAM_TEX_INSTRUCTIONS_ARB:
722 *params = fp->NumTexInstructions;
723 return;
724 case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
725 *params = fp->NumNativeTexInstructions;
726 return;
727 case GL_PROGRAM_TEX_INDIRECTIONS_ARB:
728 *params = fp->NumTexIndirections;
729 return;
730 case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
731 *params = fp->NumNativeTexIndirections;
732 return;
733 case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB:
734 *params = limits->MaxAluInstructions;
735 return;
736 case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
737 *params = limits->MaxNativeAluInstructions;
738 return;
739 case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB:
740 *params = limits->MaxTexInstructions;
741 return;
742 case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
743 *params = limits->MaxNativeTexInstructions;
744 return;
745 case GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB:
746 *params = limits->MaxTexIndirections;
747 return;
748 case GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
749 *params = limits->MaxNativeTexIndirections;
750 return;
751 default:
752 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(pname)");
753 return;
754 }
Michal Krol157ec8b2004-03-10 18:02:01 +0000755 }
756}
757
758
759void GLAPIENTRY
760_mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string)
761{
Brian Paul122629f2006-07-20 16:49:57 +0000762 const struct gl_program *prog;
Michal Krol157ec8b2004-03-10 18:02:01 +0000763 GET_CURRENT_CONTEXT(ctx);
764
765 if (!ctx->_CurrentProgram)
766 ASSERT_OUTSIDE_BEGIN_END(ctx);
767
768 if (target == GL_VERTEX_PROGRAM_ARB) {
769 prog = &(ctx->VertexProgram.Current->Base);
770 }
771 else if (target == GL_FRAGMENT_PROGRAM_ARB) {
772 prog = &(ctx->FragmentProgram.Current->Base);
773 }
774 else {
775 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(target)");
776 return;
777 }
778
779 ASSERT(prog);
780
781 if (pname != GL_PROGRAM_STRING_ARB) {
782 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(pname)");
783 return;
784 }
785
Brian Paul05051032005-11-01 04:36:33 +0000786 _mesa_memcpy(string, prog->String, _mesa_strlen((char *) prog->String));
Michal Krol157ec8b2004-03-10 18:02:01 +0000787}