blob: 5142c2a4a5988a696d4ed96e0ac863f0f03b6887 [file] [log] [blame]
Michal Krol2861e732004-03-29 11:09:34 +00001/*
2 * Mesa 3-D graphics library
Brian Paulebcedd22006-10-29 18:33:14 +00003 * Version: 6.5.2
Michal Krol2861e732004-03-29 11:09:34 +00004 *
Brian Paul8a979462006-04-20 15:06:40 +00005 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
Michal Krol2861e732004-03-29 11:09:34 +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 nvprogram.c
27 * NVIDIA vertex/fragment program state management functions.
28 * \author Brian Paul
29 */
30
31/*
32 * Regarding GL_NV_fragment/vertex_program, GL_NV_vertex_program1_1, etc:
33 *
34 * Portions of this software may use or implement intellectual
35 * property owned and licensed by NVIDIA Corporation. NVIDIA disclaims
36 * any and all warranties with respect to such intellectual property,
37 * including any use thereof or modifications thereto.
38 */
39
Brian Paulbbd28712008-09-18 12:26:54 -060040#include "main/glheader.h"
41#include "main/context.h"
42#include "main/hash.h"
43#include "main/imports.h"
44#include "main/macros.h"
45#include "program.h"
Brian57d95312006-12-14 15:03:04 -070046#include "prog_parameter.h"
47#include "prog_instruction.h"
Brian62324382006-12-14 15:54:01 -070048#include "nvfragparse.h"
Michal Krol2861e732004-03-29 11:09:34 +000049#include "nvvertparse.h"
Michal Krol2861e732004-03-29 11:09:34 +000050#include "nvprogram.h"
Michal Krol2861e732004-03-29 11:09:34 +000051
52
53
54/**
55 * Execute a vertex state program.
56 * \note Called from the GL API dispatcher.
57 */
58void GLAPIENTRY
59_mesa_ExecuteProgramNV(GLenum target, GLuint id, const GLfloat *params)
60{
Brian Paul122629f2006-07-20 16:49:57 +000061 struct gl_vertex_program *vprog;
Michal Krol2861e732004-03-29 11:09:34 +000062 GET_CURRENT_CONTEXT(ctx);
63 ASSERT_OUTSIDE_BEGIN_END(ctx);
64
65 if (target != GL_VERTEX_STATE_PROGRAM_NV) {
66 _mesa_error(ctx, GL_INVALID_ENUM, "glExecuteProgramNV");
67 return;
68 }
69
70 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
71
Brian Paul4d12a052006-08-23 23:10:14 +000072 vprog = (struct gl_vertex_program *) _mesa_lookup_program(ctx, id);
Michal Krol2861e732004-03-29 11:09:34 +000073
74 if (!vprog || vprog->Base.Target != GL_VERTEX_STATE_PROGRAM_NV) {
75 _mesa_error(ctx, GL_INVALID_OPERATION, "glExecuteProgramNV");
76 return;
77 }
78
Brian740a8b02007-02-22 16:00:54 -070079 _mesa_problem(ctx, "glExecuteProgramNV() not supported");
Michal Krol2861e732004-03-29 11:09:34 +000080}
81
82
83/**
84 * Determine if a set of programs is resident in hardware.
85 * \note Not compiled into display lists.
86 * \note Called from the GL API dispatcher.
87 */
Brian Paul81968ec2006-10-10 22:45:50 +000088GLboolean GLAPIENTRY
89_mesa_AreProgramsResidentNV(GLsizei n, const GLuint *ids,
90 GLboolean *residences)
Michal Krol2861e732004-03-29 11:09:34 +000091{
92 GLint i, j;
93 GLboolean allResident = GL_TRUE;
94 GET_CURRENT_CONTEXT(ctx);
95 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
96
97 if (n < 0) {
98 _mesa_error(ctx, GL_INVALID_VALUE, "glAreProgramsResidentNV(n)");
99 return GL_FALSE;
100 }
101
102 for (i = 0; i < n; i++) {
Brian Paul122629f2006-07-20 16:49:57 +0000103 const struct gl_program *prog;
Michal Krol2861e732004-03-29 11:09:34 +0000104 if (ids[i] == 0) {
105 _mesa_error(ctx, GL_INVALID_VALUE, "glAreProgramsResidentNV");
106 return GL_FALSE;
107 }
Brian Paul4d12a052006-08-23 23:10:14 +0000108 prog = _mesa_lookup_program(ctx, ids[i]);
Michal Krol2861e732004-03-29 11:09:34 +0000109 if (!prog) {
110 _mesa_error(ctx, GL_INVALID_VALUE, "glAreProgramsResidentNV");
111 return GL_FALSE;
112 }
113 if (prog->Resident) {
114 if (!allResident)
115 residences[i] = GL_TRUE;
116 }
117 else {
118 if (allResident) {
119 allResident = GL_FALSE;
120 for (j = 0; j < i; j++)
121 residences[j] = GL_TRUE;
122 }
123 residences[i] = GL_FALSE;
124 }
125 }
126
127 return allResident;
128}
129
130
131/**
132 * Request that a set of programs be resident in hardware.
133 * \note Called from the GL API dispatcher.
134 */
135void GLAPIENTRY
136_mesa_RequestResidentProgramsNV(GLsizei n, const GLuint *ids)
137{
138 GLint i;
139 GET_CURRENT_CONTEXT(ctx);
140 ASSERT_OUTSIDE_BEGIN_END(ctx);
141
142 if (n < 0) {
143 _mesa_error(ctx, GL_INVALID_VALUE, "glRequestResidentProgramsNV(n)");
144 return;
145 }
146
147 /* just error checking for now */
148 for (i = 0; i < n; i++) {
Brian Paul122629f2006-07-20 16:49:57 +0000149 struct gl_program *prog;
Michal Krol2861e732004-03-29 11:09:34 +0000150
151 if (ids[i] == 0) {
152 _mesa_error(ctx, GL_INVALID_VALUE, "glRequestResidentProgramsNV(id)");
153 return;
154 }
155
Brian Paul4d12a052006-08-23 23:10:14 +0000156 prog = _mesa_lookup_program(ctx, ids[i]);
Michal Krol2861e732004-03-29 11:09:34 +0000157 if (!prog) {
158 _mesa_error(ctx, GL_INVALID_VALUE, "glRequestResidentProgramsNV(id)");
159 return;
160 }
161
Brian Paul9ca83922004-10-02 15:16:59 +0000162 /* XXX this is really a hardware thing we should hook out */
Michal Krol2861e732004-03-29 11:09:34 +0000163 prog->Resident = GL_TRUE;
164 }
165}
166
167
168/**
169 * Get a program parameter register.
170 * \note Not compiled into display lists.
171 * \note Called from the GL API dispatcher.
172 */
173void GLAPIENTRY
174_mesa_GetProgramParameterfvNV(GLenum target, GLuint index,
175 GLenum pname, GLfloat *params)
176{
177 GET_CURRENT_CONTEXT(ctx);
178 ASSERT_OUTSIDE_BEGIN_END(ctx);
179
180 if (target == GL_VERTEX_PROGRAM_NV) {
181 if (pname == GL_PROGRAM_PARAMETER_NV) {
182 if (index < MAX_NV_VERTEX_PROGRAM_PARAMS) {
183 COPY_4V(params, ctx->VertexProgram.Parameters[index]);
184 }
185 else {
186 _mesa_error(ctx, GL_INVALID_VALUE,
187 "glGetProgramParameterfvNV(index)");
188 return;
189 }
190 }
191 else {
192 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramParameterfvNV(pname)");
193 return;
194 }
195 }
196 else {
197 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramParameterfvNV(target)");
198 return;
199 }
200}
201
202
203/**
204 * Get a program parameter register.
205 * \note Not compiled into display lists.
206 * \note Called from the GL API dispatcher.
207 */
208void GLAPIENTRY
209_mesa_GetProgramParameterdvNV(GLenum target, GLuint index,
210 GLenum pname, GLdouble *params)
211{
212 GET_CURRENT_CONTEXT(ctx);
213 ASSERT_OUTSIDE_BEGIN_END(ctx);
214
215 if (target == GL_VERTEX_PROGRAM_NV) {
216 if (pname == GL_PROGRAM_PARAMETER_NV) {
217 if (index < MAX_NV_VERTEX_PROGRAM_PARAMS) {
218 COPY_4V(params, ctx->VertexProgram.Parameters[index]);
219 }
220 else {
221 _mesa_error(ctx, GL_INVALID_VALUE,
222 "glGetProgramParameterdvNV(index)");
223 return;
224 }
225 }
226 else {
227 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramParameterdvNV(pname)");
228 return;
229 }
230 }
231 else {
232 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramParameterdvNV(target)");
233 return;
234 }
235}
236
237
238/**
239 * Get a program attribute.
240 * \note Not compiled into display lists.
241 * \note Called from the GL API dispatcher.
242 */
243void GLAPIENTRY
244_mesa_GetProgramivNV(GLuint id, GLenum pname, GLint *params)
245{
Brian Paul122629f2006-07-20 16:49:57 +0000246 struct gl_program *prog;
Michal Krol2861e732004-03-29 11:09:34 +0000247 GET_CURRENT_CONTEXT(ctx);
248
Brian Paul548be382009-03-11 20:08:37 -0600249 ASSERT_OUTSIDE_BEGIN_END(ctx);
Michal Krol2861e732004-03-29 11:09:34 +0000250
Brian Paul4d12a052006-08-23 23:10:14 +0000251 prog = _mesa_lookup_program(ctx, id);
Michal Krol2861e732004-03-29 11:09:34 +0000252 if (!prog) {
253 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramivNV");
254 return;
255 }
256
257 switch (pname) {
258 case GL_PROGRAM_TARGET_NV:
259 *params = prog->Target;
260 return;
261 case GL_PROGRAM_LENGTH_NV:
Karl Schultz6258b762005-05-05 21:08:07 +0000262 *params = prog->String ?(GLint)_mesa_strlen((char *) prog->String) : 0;
Michal Krol2861e732004-03-29 11:09:34 +0000263 return;
264 case GL_PROGRAM_RESIDENT_NV:
265 *params = prog->Resident;
266 return;
267 default:
268 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivNV(pname)");
269 return;
270 }
271}
272
273
274/**
275 * Get the program source code.
276 * \note Not compiled into display lists.
277 * \note Called from the GL API dispatcher.
278 */
279void GLAPIENTRY
280_mesa_GetProgramStringNV(GLuint id, GLenum pname, GLubyte *program)
281{
Brian Paul122629f2006-07-20 16:49:57 +0000282 struct gl_program *prog;
Michal Krol2861e732004-03-29 11:09:34 +0000283 GET_CURRENT_CONTEXT(ctx);
284
Brian Paul548be382009-03-11 20:08:37 -0600285 ASSERT_OUTSIDE_BEGIN_END(ctx);
Michal Krol2861e732004-03-29 11:09:34 +0000286
287 if (pname != GL_PROGRAM_STRING_NV) {
288 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringNV(pname)");
289 return;
290 }
291
Brian Paul4d12a052006-08-23 23:10:14 +0000292 prog = _mesa_lookup_program(ctx, id);
Michal Krol2861e732004-03-29 11:09:34 +0000293 if (!prog) {
294 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramStringNV");
295 return;
296 }
297
298 if (prog->String) {
299 MEMCPY(program, prog->String, _mesa_strlen((char *) prog->String));
300 }
301 else {
302 program[0] = 0;
303 }
304}
305
306
307/**
308 * Get matrix tracking information.
309 * \note Not compiled into display lists.
310 * \note Called from the GL API dispatcher.
311 */
312void GLAPIENTRY
313_mesa_GetTrackMatrixivNV(GLenum target, GLuint address,
314 GLenum pname, GLint *params)
315{
316 GET_CURRENT_CONTEXT(ctx);
317 ASSERT_OUTSIDE_BEGIN_END(ctx);
318
319 if (target == GL_VERTEX_PROGRAM_NV
320 && ctx->Extensions.NV_vertex_program) {
321 GLuint i;
322
323 if ((address & 0x3) || address >= MAX_NV_VERTEX_PROGRAM_PARAMS) {
324 _mesa_error(ctx, GL_INVALID_VALUE, "glGetTrackMatrixivNV(address)");
325 return;
326 }
327
328 i = address / 4;
329
330 switch (pname) {
331 case GL_TRACK_MATRIX_NV:
332 params[0] = (GLint) ctx->VertexProgram.TrackMatrix[i];
333 return;
334 case GL_TRACK_MATRIX_TRANSFORM_NV:
335 params[0] = (GLint) ctx->VertexProgram.TrackMatrixTransform[i];
336 return;
337 default:
338 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTrackMatrixivNV");
339 return;
340 }
341 }
342 else {
343 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTrackMatrixivNV");
344 return;
345 }
346}
347
348
349/**
350 * Get a vertex (or vertex array) attribute.
351 * \note Not compiled into display lists.
352 * \note Called from the GL API dispatcher.
353 */
354void GLAPIENTRY
355_mesa_GetVertexAttribdvNV(GLuint index, GLenum pname, GLdouble *params)
356{
357 GET_CURRENT_CONTEXT(ctx);
358 ASSERT_OUTSIDE_BEGIN_END(ctx);
359
Brian Paul120584a2006-11-04 17:31:45 +0000360 if (index >= MAX_NV_VERTEX_PROGRAM_INPUTS) {
Michal Krol2861e732004-03-29 11:09:34 +0000361 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribdvNV(index)");
362 return;
363 }
364
365 switch (pname) {
366 case GL_ATTRIB_ARRAY_SIZE_NV:
Ian Romanickee34e6e2006-06-12 16:26:29 +0000367 params[0] = ctx->Array.ArrayObj->VertexAttrib[index].Size;
Michal Krol2861e732004-03-29 11:09:34 +0000368 break;
369 case GL_ATTRIB_ARRAY_STRIDE_NV:
Ian Romanickee34e6e2006-06-12 16:26:29 +0000370 params[0] = ctx->Array.ArrayObj->VertexAttrib[index].Stride;
Michal Krol2861e732004-03-29 11:09:34 +0000371 break;
372 case GL_ATTRIB_ARRAY_TYPE_NV:
Ian Romanickee34e6e2006-06-12 16:26:29 +0000373 params[0] = ctx->Array.ArrayObj->VertexAttrib[index].Type;
Michal Krol2861e732004-03-29 11:09:34 +0000374 break;
375 case GL_CURRENT_ATTRIB_NV:
Brian Paul120584a2006-11-04 17:31:45 +0000376 if (index == 0) {
377 _mesa_error(ctx, GL_INVALID_OPERATION,
378 "glGetVertexAttribdvNV(index == 0)");
379 return;
380 }
Michal Krol2861e732004-03-29 11:09:34 +0000381 FLUSH_CURRENT(ctx, 0);
382 COPY_4V(params, ctx->Current.Attrib[index]);
383 break;
384 default:
385 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribdvNV");
386 return;
387 }
388}
389
390/**
391 * Get a vertex (or vertex array) attribute.
392 * \note Not compiled into display lists.
393 * \note Called from the GL API dispatcher.
394 */
395void GLAPIENTRY
396_mesa_GetVertexAttribfvNV(GLuint index, GLenum pname, GLfloat *params)
397{
398 GET_CURRENT_CONTEXT(ctx);
399 ASSERT_OUTSIDE_BEGIN_END(ctx);
400
Brian Paul120584a2006-11-04 17:31:45 +0000401 if (index >= MAX_NV_VERTEX_PROGRAM_INPUTS) {
Michal Krol2861e732004-03-29 11:09:34 +0000402 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribdvNV(index)");
403 return;
404 }
405
406 switch (pname) {
407 case GL_ATTRIB_ARRAY_SIZE_NV:
Ian Romanickee34e6e2006-06-12 16:26:29 +0000408 params[0] = (GLfloat) ctx->Array.ArrayObj->VertexAttrib[index].Size;
Michal Krol2861e732004-03-29 11:09:34 +0000409 break;
410 case GL_ATTRIB_ARRAY_STRIDE_NV:
Ian Romanickee34e6e2006-06-12 16:26:29 +0000411 params[0] = (GLfloat) ctx->Array.ArrayObj->VertexAttrib[index].Stride;
Michal Krol2861e732004-03-29 11:09:34 +0000412 break;
413 case GL_ATTRIB_ARRAY_TYPE_NV:
Ian Romanickee34e6e2006-06-12 16:26:29 +0000414 params[0] = (GLfloat) ctx->Array.ArrayObj->VertexAttrib[index].Type;
Michal Krol2861e732004-03-29 11:09:34 +0000415 break;
416 case GL_CURRENT_ATTRIB_NV:
Brian Paul120584a2006-11-04 17:31:45 +0000417 if (index == 0) {
418 _mesa_error(ctx, GL_INVALID_OPERATION,
419 "glGetVertexAttribfvNV(index == 0)");
420 return;
421 }
Michal Krol2861e732004-03-29 11:09:34 +0000422 FLUSH_CURRENT(ctx, 0);
423 COPY_4V(params, ctx->Current.Attrib[index]);
424 break;
425 default:
426 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribdvNV");
427 return;
428 }
429}
430
431/**
432 * Get a vertex (or vertex array) attribute.
433 * \note Not compiled into display lists.
434 * \note Called from the GL API dispatcher.
435 */
436void GLAPIENTRY
437_mesa_GetVertexAttribivNV(GLuint index, GLenum pname, GLint *params)
438{
439 GET_CURRENT_CONTEXT(ctx);
440 ASSERT_OUTSIDE_BEGIN_END(ctx);
441
Brian Paul120584a2006-11-04 17:31:45 +0000442 if (index >= MAX_NV_VERTEX_PROGRAM_INPUTS) {
Michal Krol2861e732004-03-29 11:09:34 +0000443 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribdvNV(index)");
444 return;
445 }
446
447 switch (pname) {
448 case GL_ATTRIB_ARRAY_SIZE_NV:
Ian Romanickee34e6e2006-06-12 16:26:29 +0000449 params[0] = ctx->Array.ArrayObj->VertexAttrib[index].Size;
Michal Krol2861e732004-03-29 11:09:34 +0000450 break;
451 case GL_ATTRIB_ARRAY_STRIDE_NV:
Ian Romanickee34e6e2006-06-12 16:26:29 +0000452 params[0] = ctx->Array.ArrayObj->VertexAttrib[index].Stride;
Michal Krol2861e732004-03-29 11:09:34 +0000453 break;
454 case GL_ATTRIB_ARRAY_TYPE_NV:
Ian Romanickee34e6e2006-06-12 16:26:29 +0000455 params[0] = ctx->Array.ArrayObj->VertexAttrib[index].Type;
Michal Krol2861e732004-03-29 11:09:34 +0000456 break;
457 case GL_CURRENT_ATTRIB_NV:
Brian Paul120584a2006-11-04 17:31:45 +0000458 if (index == 0) {
459 _mesa_error(ctx, GL_INVALID_OPERATION,
460 "glGetVertexAttribivNV(index == 0)");
461 return;
462 }
Michal Krol2861e732004-03-29 11:09:34 +0000463 FLUSH_CURRENT(ctx, 0);
464 params[0] = (GLint) ctx->Current.Attrib[index][0];
465 params[1] = (GLint) ctx->Current.Attrib[index][1];
466 params[2] = (GLint) ctx->Current.Attrib[index][2];
467 params[3] = (GLint) ctx->Current.Attrib[index][3];
468 break;
469 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB:
Ian Romanickee34e6e2006-06-12 16:26:29 +0000470 params[0] = ctx->Array.ArrayObj->VertexAttrib[index].BufferObj->Name;
Michal Krol2861e732004-03-29 11:09:34 +0000471 break;
472 default:
473 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribdvNV");
474 return;
475 }
476}
477
478
479/**
480 * Get a vertex array attribute pointer.
481 * \note Not compiled into display lists.
482 * \note Called from the GL API dispatcher.
483 */
484void GLAPIENTRY
485_mesa_GetVertexAttribPointervNV(GLuint index, GLenum pname, GLvoid **pointer)
486{
487 GET_CURRENT_CONTEXT(ctx);
488 ASSERT_OUTSIDE_BEGIN_END(ctx);
489
490 if (index >= MAX_NV_VERTEX_PROGRAM_INPUTS) {
491 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerNV(index)");
492 return;
493 }
494
495 if (pname != GL_ATTRIB_ARRAY_POINTER_NV) {
496 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerNV(pname)");
497 return;
498 }
499
Ian Romanickee34e6e2006-06-12 16:26:29 +0000500 *pointer = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[index].Ptr;
Michal Krol2861e732004-03-29 11:09:34 +0000501}
502
503
504
505/**
506 * Load/parse/compile a program.
507 * \note Called from the GL API dispatcher.
508 */
509void GLAPIENTRY
510_mesa_LoadProgramNV(GLenum target, GLuint id, GLsizei len,
511 const GLubyte *program)
512{
Brian Paul122629f2006-07-20 16:49:57 +0000513 struct gl_program *prog;
Michal Krol2861e732004-03-29 11:09:34 +0000514 GET_CURRENT_CONTEXT(ctx);
515 ASSERT_OUTSIDE_BEGIN_END(ctx);
516
517 if (id == 0) {
518 _mesa_error(ctx, GL_INVALID_VALUE, "glLoadProgramNV(id)");
519 return;
520 }
521
Brian Paul8a979462006-04-20 15:06:40 +0000522 if (len < 0) {
523 _mesa_error(ctx, GL_INVALID_VALUE, "glLoadProgramNV(len)");
524 return;
525 }
526
Michal Krol2861e732004-03-29 11:09:34 +0000527 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
528
Brian Paul4d12a052006-08-23 23:10:14 +0000529 prog = _mesa_lookup_program(ctx, id);
Michal Krol2861e732004-03-29 11:09:34 +0000530
531 if (prog && prog->Target != 0 && prog->Target != target) {
532 _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(target)");
533 return;
534 }
535
536 if ((target == GL_VERTEX_PROGRAM_NV ||
537 target == GL_VERTEX_STATE_PROGRAM_NV)
538 && ctx->Extensions.NV_vertex_program) {
Brian Paul122629f2006-07-20 16:49:57 +0000539 struct gl_vertex_program *vprog = (struct gl_vertex_program *) prog;
Brian Paul9ca83922004-10-02 15:16:59 +0000540 if (!vprog || prog == &_mesa_DummyProgram) {
Brian Paul122629f2006-07-20 16:49:57 +0000541 vprog = (struct gl_vertex_program *)
Brian Paul05907862004-06-20 20:57:22 +0000542 ctx->Driver.NewProgram(ctx, target, id);
Michal Krol2861e732004-03-29 11:09:34 +0000543 if (!vprog) {
544 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
545 return;
546 }
Michal Krol2861e732004-03-29 11:09:34 +0000547 _mesa_HashInsert(ctx->Shared->Programs, id, vprog);
548 }
549 _mesa_parse_nv_vertex_program(ctx, target, program, len, vprog);
550 }
551 else if (target == GL_FRAGMENT_PROGRAM_NV
552 && ctx->Extensions.NV_fragment_program) {
Brian Paul122629f2006-07-20 16:49:57 +0000553 struct gl_fragment_program *fprog = (struct gl_fragment_program *) prog;
Brian Paul9ca83922004-10-02 15:16:59 +0000554 if (!fprog || prog == &_mesa_DummyProgram) {
Brian Paul122629f2006-07-20 16:49:57 +0000555 fprog = (struct gl_fragment_program *)
Brian Paul05907862004-06-20 20:57:22 +0000556 ctx->Driver.NewProgram(ctx, target, id);
Michal Krol2861e732004-03-29 11:09:34 +0000557 if (!fprog) {
558 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
559 return;
560 }
Michal Krol2861e732004-03-29 11:09:34 +0000561 _mesa_HashInsert(ctx->Shared->Programs, id, fprog);
562 }
563 _mesa_parse_nv_fragment_program(ctx, target, program, len, fprog);
564 }
565 else {
566 _mesa_error(ctx, GL_INVALID_ENUM, "glLoadProgramNV(target)");
567 }
568}
569
570
571
572/**
Michal Krol2861e732004-03-29 11:09:34 +0000573 * Set a sequence of program parameter registers.
574 * \note Called from the GL API dispatcher.
575 */
576void GLAPIENTRY
577_mesa_ProgramParameters4dvNV(GLenum target, GLuint index,
578 GLuint num, const GLdouble *params)
579{
580 GET_CURRENT_CONTEXT(ctx);
581 ASSERT_OUTSIDE_BEGIN_END(ctx);
582
583 if (target == GL_VERTEX_PROGRAM_NV && ctx->Extensions.NV_vertex_program) {
584 GLuint i;
585 if (index + num > MAX_NV_VERTEX_PROGRAM_PARAMS) {
586 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramParameters4dvNV");
587 return;
588 }
589 for (i = 0; i < num; i++) {
590 ctx->VertexProgram.Parameters[index + i][0] = (GLfloat) params[0];
591 ctx->VertexProgram.Parameters[index + i][1] = (GLfloat) params[1];
592 ctx->VertexProgram.Parameters[index + i][2] = (GLfloat) params[2];
593 ctx->VertexProgram.Parameters[index + i][3] = (GLfloat) params[3];
594 params += 4;
595 };
596 }
597 else {
598 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameters4dvNV");
599 return;
600 }
601}
602
603
604/**
605 * Set a sequence of program parameter registers.
606 * \note Called from the GL API dispatcher.
607 */
608void GLAPIENTRY
609_mesa_ProgramParameters4fvNV(GLenum target, GLuint index,
610 GLuint num, const GLfloat *params)
611{
612 GET_CURRENT_CONTEXT(ctx);
613 ASSERT_OUTSIDE_BEGIN_END(ctx);
614
615 if (target == GL_VERTEX_PROGRAM_NV && ctx->Extensions.NV_vertex_program) {
616 GLuint i;
617 if (index + num > MAX_NV_VERTEX_PROGRAM_PARAMS) {
618 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramParameters4fvNV");
619 return;
620 }
621 for (i = 0; i < num; i++) {
622 COPY_4V(ctx->VertexProgram.Parameters[index + i], params);
623 params += 4;
Ian Romanickdaea7172006-08-15 16:26:34 +0000624 }
Michal Krol2861e732004-03-29 11:09:34 +0000625 }
626 else {
627 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameters4fvNV");
628 return;
629 }
630}
631
632
633
634/**
635 * Setup tracking of matrices into program parameter registers.
636 * \note Called from the GL API dispatcher.
637 */
638void GLAPIENTRY
639_mesa_TrackMatrixNV(GLenum target, GLuint address,
640 GLenum matrix, GLenum transform)
641{
642 GET_CURRENT_CONTEXT(ctx);
643 ASSERT_OUTSIDE_BEGIN_END(ctx);
644
645 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
646
647 if (target == GL_VERTEX_PROGRAM_NV && ctx->Extensions.NV_vertex_program) {
648 if (address & 0x3) {
649 /* addr must be multiple of four */
650 _mesa_error(ctx, GL_INVALID_VALUE, "glTrackMatrixNV(address)");
651 return;
652 }
653
654 switch (matrix) {
655 case GL_NONE:
656 case GL_MODELVIEW:
657 case GL_PROJECTION:
658 case GL_TEXTURE:
659 case GL_COLOR:
660 case GL_MODELVIEW_PROJECTION_NV:
661 case GL_MATRIX0_NV:
662 case GL_MATRIX1_NV:
663 case GL_MATRIX2_NV:
664 case GL_MATRIX3_NV:
665 case GL_MATRIX4_NV:
666 case GL_MATRIX5_NV:
667 case GL_MATRIX6_NV:
668 case GL_MATRIX7_NV:
669 /* OK, fallthrough */
670 break;
671 default:
672 _mesa_error(ctx, GL_INVALID_ENUM, "glTrackMatrixNV(matrix)");
673 return;
674 }
675
676 switch (transform) {
677 case GL_IDENTITY_NV:
678 case GL_INVERSE_NV:
679 case GL_TRANSPOSE_NV:
680 case GL_INVERSE_TRANSPOSE_NV:
681 /* OK, fallthrough */
682 break;
683 default:
684 _mesa_error(ctx, GL_INVALID_ENUM, "glTrackMatrixNV(transform)");
685 return;
686 }
687
688 ctx->VertexProgram.TrackMatrix[address / 4] = matrix;
689 ctx->VertexProgram.TrackMatrixTransform[address / 4] = transform;
690 }
691 else {
692 _mesa_error(ctx, GL_INVALID_ENUM, "glTrackMatrixNV(target)");
693 return;
694 }
695}
696
697
698void GLAPIENTRY
699_mesa_ProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte *name,
700 GLfloat x, GLfloat y, GLfloat z, GLfloat w)
701{
Brian Paul122629f2006-07-20 16:49:57 +0000702 struct gl_program *prog;
703 struct gl_fragment_program *fragProg;
Michal Krol2861e732004-03-29 11:09:34 +0000704 GLfloat *v;
705
706 GET_CURRENT_CONTEXT(ctx);
707 ASSERT_OUTSIDE_BEGIN_END(ctx);
708
Brian Paul64e331e2009-04-21 15:56:45 -0600709 FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
Michal Krol2861e732004-03-29 11:09:34 +0000710
Brian Paul4d12a052006-08-23 23:10:14 +0000711 prog = _mesa_lookup_program(ctx, id);
Michal Krol2861e732004-03-29 11:09:34 +0000712 if (!prog || prog->Target != GL_FRAGMENT_PROGRAM_NV) {
713 _mesa_error(ctx, GL_INVALID_OPERATION, "glProgramNamedParameterNV");
714 return;
715 }
716
717 if (len <= 0) {
Brian Paul9ca83922004-10-02 15:16:59 +0000718 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramNamedParameterNV(len)");
Michal Krol2861e732004-03-29 11:09:34 +0000719 return;
720 }
721
Brian Paul122629f2006-07-20 16:49:57 +0000722 fragProg = (struct gl_fragment_program *) prog;
Brian Paulde997602005-11-12 17:53:14 +0000723 v = _mesa_lookup_parameter_value(fragProg->Base.Parameters, len,
724 (char *) name);
Michal Krol2861e732004-03-29 11:09:34 +0000725 if (v) {
726 v[0] = x;
727 v[1] = y;
728 v[2] = z;
729 v[3] = w;
730 return;
731 }
732
Brian Paul9ca83922004-10-02 15:16:59 +0000733 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramNamedParameterNV(name)");
Michal Krol2861e732004-03-29 11:09:34 +0000734}
735
736
737void GLAPIENTRY
738_mesa_ProgramNamedParameter4fvNV(GLuint id, GLsizei len, const GLubyte *name,
739 const float v[])
740{
741 _mesa_ProgramNamedParameter4fNV(id, len, name, v[0], v[1], v[2], v[3]);
742}
743
744
745void GLAPIENTRY
746_mesa_ProgramNamedParameter4dNV(GLuint id, GLsizei len, const GLubyte *name,
747 GLdouble x, GLdouble y, GLdouble z, GLdouble w)
748{
749 _mesa_ProgramNamedParameter4fNV(id, len, name, (GLfloat)x, (GLfloat)y,
750 (GLfloat)z, (GLfloat)w);
751}
752
753
754void GLAPIENTRY
755_mesa_ProgramNamedParameter4dvNV(GLuint id, GLsizei len, const GLubyte *name,
756 const double v[])
757{
758 _mesa_ProgramNamedParameter4fNV(id, len, name,
759 (GLfloat)v[0], (GLfloat)v[1],
760 (GLfloat)v[2], (GLfloat)v[3]);
761}
762
763
764void GLAPIENTRY
765_mesa_GetProgramNamedParameterfvNV(GLuint id, GLsizei len, const GLubyte *name,
766 GLfloat *params)
767{
Brian Paul122629f2006-07-20 16:49:57 +0000768 struct gl_program *prog;
769 struct gl_fragment_program *fragProg;
Michal Krol2861e732004-03-29 11:09:34 +0000770 const GLfloat *v;
771
772 GET_CURRENT_CONTEXT(ctx);
773
Brian Paul548be382009-03-11 20:08:37 -0600774 ASSERT_OUTSIDE_BEGIN_END(ctx);
Michal Krol2861e732004-03-29 11:09:34 +0000775
Brian Paul4d12a052006-08-23 23:10:14 +0000776 prog = _mesa_lookup_program(ctx, id);
Michal Krol2861e732004-03-29 11:09:34 +0000777 if (!prog || prog->Target != GL_FRAGMENT_PROGRAM_NV) {
778 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramNamedParameterNV");
779 return;
780 }
781
782 if (len <= 0) {
783 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramNamedParameterNV");
784 return;
785 }
786
Brian Paul122629f2006-07-20 16:49:57 +0000787 fragProg = (struct gl_fragment_program *) prog;
Brian Paulde997602005-11-12 17:53:14 +0000788 v = _mesa_lookup_parameter_value(fragProg->Base.Parameters,
789 len, (char *) name);
Michal Krol2861e732004-03-29 11:09:34 +0000790 if (v) {
791 params[0] = v[0];
792 params[1] = v[1];
793 params[2] = v[2];
794 params[3] = v[3];
795 return;
796 }
797
798 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramNamedParameterNV");
799}
800
801
802void GLAPIENTRY
803_mesa_GetProgramNamedParameterdvNV(GLuint id, GLsizei len, const GLubyte *name,
804 GLdouble *params)
805{
806 GLfloat floatParams[4];
807 _mesa_GetProgramNamedParameterfvNV(id, len, name, floatParams);
808 COPY_4V(params, floatParams);
809}