move mesa32 over to new dir
[reactos.git] / reactos / lib / mesa32 / src / shader / arbprogram.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 5.1
4 *
5 * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /**
26 * \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"
34 #include "arbfragparse.h"
35 #include "arbvertparse.h"
36 #include "context.h"
37 #include "imports.h"
38 #include "macros.h"
39 #include "mtypes.h"
40 #include "nvprogram.h"
41 #include "nvfragparse.h"
42 #include "nvfragprog.h"
43 #include "nvvertparse.h"
44 #include "nvvertprog.h"
45
46
47 void GLAPIENTRY
48 _mesa_EnableVertexAttribArrayARB(GLuint index)
49 {
50 GET_CURRENT_CONTEXT(ctx);
51 ASSERT_OUTSIDE_BEGIN_END(ctx);
52
53 if (index >= ctx->Const.MaxVertexProgramAttribs) {
54 _mesa_error(ctx, GL_INVALID_VALUE,
55 "glEnableVertexAttribArrayARB(index)");
56 return;
57 }
58
59 FLUSH_VERTICES(ctx, _NEW_ARRAY);
60 ctx->Array.VertexAttrib[index].Enabled = GL_TRUE;
61 ctx->Array._Enabled |= _NEW_ARRAY_ATTRIB(index);
62 ctx->Array.NewState |= _NEW_ARRAY_ATTRIB(index);
63 }
64
65
66 void GLAPIENTRY
67 _mesa_DisableVertexAttribArrayARB(GLuint index)
68 {
69 GET_CURRENT_CONTEXT(ctx);
70 ASSERT_OUTSIDE_BEGIN_END(ctx);
71
72 if (index >= ctx->Const.MaxVertexProgramAttribs) {
73 _mesa_error(ctx, GL_INVALID_VALUE,
74 "glEnableVertexAttribArrayARB(index)");
75 return;
76 }
77
78 FLUSH_VERTICES(ctx, _NEW_ARRAY);
79 ctx->Array.VertexAttrib[index].Enabled = GL_FALSE;
80 ctx->Array._Enabled &= ~_NEW_ARRAY_ATTRIB(index);
81 ctx->Array.NewState |= _NEW_ARRAY_ATTRIB(index);
82 }
83
84
85 void GLAPIENTRY
86 _mesa_GetVertexAttribdvARB(GLuint index, GLenum pname, GLdouble *params)
87 {
88 GLfloat fparams[4];
89 GET_CURRENT_CONTEXT(ctx);
90 ASSERT_OUTSIDE_BEGIN_END(ctx);
91
92 _mesa_GetVertexAttribfvARB(index, pname, fparams);
93 if (ctx->ErrorValue == GL_NO_ERROR) {
94 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
95 COPY_4V(params, fparams);
96 }
97 else {
98 params[0] = fparams[0];
99 }
100 }
101 }
102
103
104 void GLAPIENTRY
105 _mesa_GetVertexAttribfvARB(GLuint index, GLenum pname, GLfloat *params)
106 {
107 GET_CURRENT_CONTEXT(ctx);
108 ASSERT_OUTSIDE_BEGIN_END(ctx);
109
110 if (index == 0 || index >= MAX_VERTEX_PROGRAM_ATTRIBS) {
111 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribfvARB(index)");
112 return;
113 }
114
115 switch (pname) {
116 case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB:
117 params[0] = (GLfloat) ctx->Array.VertexAttrib[index].Enabled;
118 break;
119 case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB:
120 params[0] = (GLfloat) ctx->Array.VertexAttrib[index].Size;
121 break;
122 case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB:
123 params[0] = (GLfloat) ctx->Array.VertexAttrib[index].Stride;
124 break;
125 case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB:
126 params[0] = (GLfloat) ctx->Array.VertexAttrib[index].Type;
127 break;
128 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB:
129 params[0] = ctx->Array.VertexAttrib[index].Normalized;
130 break;
131 case GL_CURRENT_VERTEX_ATTRIB_ARB:
132 FLUSH_CURRENT(ctx, 0);
133 /* XXX should read:
134 COPY_4V(params, ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + index]);
135 */
136 COPY_4V(params, ctx->Current.Attrib[index]);
137 break;
138 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB:
139 if (!ctx->Extensions.ARB_vertex_buffer_object) {
140 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribfvARB(pname)");
141 return;
142 }
143 params[0] = (GLfloat) ctx->Array.VertexAttrib[index].BufferObj->Name;
144 default:
145 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribfvARB(pname)");
146 return;
147 }
148 }
149
150
151 void GLAPIENTRY
152 _mesa_GetVertexAttribivARB(GLuint index, GLenum pname, GLint *params)
153 {
154 GLfloat fparams[4];
155 GET_CURRENT_CONTEXT(ctx);
156 ASSERT_OUTSIDE_BEGIN_END(ctx);
157
158 _mesa_GetVertexAttribfvARB(index, pname, fparams);
159 if (ctx->ErrorValue == GL_NO_ERROR) {
160 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
161 COPY_4V_CAST(params, fparams, GLint); /* float to int */
162 }
163 else {
164 params[0] = (GLint) fparams[0];
165 }
166 }
167 }
168
169
170 void GLAPIENTRY
171 _mesa_GetVertexAttribPointervARB(GLuint index, GLenum pname, GLvoid **pointer)
172 {
173 GET_CURRENT_CONTEXT(ctx);
174 ASSERT_OUTSIDE_BEGIN_END(ctx);
175
176 if (index >= ctx->Const.MaxVertexProgramAttribs) {
177 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerARB(index)");
178 return;
179 }
180
181 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) {
182 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerARB(pname)");
183 return;
184 }
185
186 *pointer = (GLvoid *) ctx->Array.VertexAttrib[index].Ptr;;
187 }
188
189
190 void GLAPIENTRY
191 _mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
192 const GLvoid *string)
193 {
194 GET_CURRENT_CONTEXT(ctx);
195 ASSERT_OUTSIDE_BEGIN_END(ctx);
196
197 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
198
199 if (target == GL_VERTEX_PROGRAM_ARB
200 && ctx->Extensions.ARB_vertex_program) {
201 struct vertex_program *prog = ctx->VertexProgram.Current;
202 if (format != GL_PROGRAM_FORMAT_ASCII_ARB) {
203 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(format)");
204 return;
205 }
206 _mesa_parse_arb_vertex_program(ctx, target, (const GLubyte *) string,
207 len, prog);
208
209 if (ctx->Driver.ProgramStringNotify)
210 ctx->Driver.ProgramStringNotify( ctx, target, &prog->Base );
211 }
212 else if (target == GL_FRAGMENT_PROGRAM_ARB
213 && ctx->Extensions.ARB_fragment_program) {
214 struct fragment_program *prog = ctx->FragmentProgram.Current;
215 if (format != GL_PROGRAM_FORMAT_ASCII_ARB) {
216 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(format)");
217 return;
218 }
219 _mesa_parse_arb_fragment_program(ctx, target, (const GLubyte *) string,
220 len, prog);
221
222 if (ctx->Driver.ProgramStringNotify)
223 ctx->Driver.ProgramStringNotify( ctx, target, &prog->Base );
224 }
225 else {
226 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(target)");
227 return;
228 }
229 }
230
231
232 void GLAPIENTRY
233 _mesa_ProgramEnvParameter4dARB(GLenum target, GLuint index,
234 GLdouble x, GLdouble y, GLdouble z, GLdouble w)
235 {
236 _mesa_ProgramEnvParameter4fARB(target, index, (GLfloat) x, (GLfloat) y,
237 (GLfloat) z, (GLfloat) w);
238 }
239
240
241 void GLAPIENTRY
242 _mesa_ProgramEnvParameter4dvARB(GLenum target, GLuint index,
243 const GLdouble *params)
244 {
245 _mesa_ProgramEnvParameter4fARB(target, index, (GLfloat) params[0],
246 (GLfloat) params[1], (GLfloat) params[2],
247 (GLfloat) params[3]);
248 }
249
250
251 void GLAPIENTRY
252 _mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index,
253 GLfloat x, GLfloat y, GLfloat z, GLfloat w)
254 {
255 GET_CURRENT_CONTEXT(ctx);
256 ASSERT_OUTSIDE_BEGIN_END(ctx);
257
258 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
259
260 if (target == GL_FRAGMENT_PROGRAM_ARB
261 && ctx->Extensions.ARB_fragment_program) {
262 if (index >= ctx->Const.MaxFragmentProgramEnvParams) {
263 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
264 return;
265 }
266 ASSIGN_4V(ctx->FragmentProgram.Parameters[index], x, y, z, w);
267 }
268 else if (target == GL_VERTEX_PROGRAM_ARB
269 && ctx->Extensions.ARB_vertex_program) {
270 if (index >= ctx->Const.MaxVertexProgramEnvParams) {
271 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
272 return;
273 }
274 ASSIGN_4V(ctx->VertexProgram.Parameters[index], x, y, z, w);
275 }
276 else {
277 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameter(target)");
278 return;
279 }
280 }
281
282
283 void GLAPIENTRY
284 _mesa_ProgramEnvParameter4fvARB(GLenum target, GLuint index,
285 const GLfloat *params)
286 {
287 _mesa_ProgramEnvParameter4fARB(target, index, params[0], params[1],
288 params[2], params[3]);
289 }
290
291
292 void GLAPIENTRY
293 _mesa_GetProgramEnvParameterdvARB(GLenum target, GLuint index,
294 GLdouble *params)
295 {
296 GET_CURRENT_CONTEXT(ctx);
297 GLfloat fparams[4];
298
299 _mesa_GetProgramEnvParameterfvARB(target, index, fparams);
300 if (ctx->ErrorValue == GL_NO_ERROR) {
301 params[0] = fparams[0];
302 params[1] = fparams[1];
303 params[2] = fparams[2];
304 params[3] = fparams[3];
305 }
306 }
307
308
309 void GLAPIENTRY
310 _mesa_GetProgramEnvParameterfvARB(GLenum target, GLuint index,
311 GLfloat *params)
312 {
313 GET_CURRENT_CONTEXT(ctx);
314
315 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
316
317 if (!ctx->_CurrentProgram)
318 ASSERT_OUTSIDE_BEGIN_END(ctx);
319
320 if (target == GL_FRAGMENT_PROGRAM_ARB
321 && ctx->Extensions.ARB_fragment_program) {
322 if (index >= ctx->Const.MaxFragmentProgramEnvParams) {
323 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
324 return;
325 }
326 COPY_4V(params, ctx->FragmentProgram.Parameters[index]);
327 }
328 else if (target == GL_VERTEX_PROGRAM_ARB
329 && ctx->Extensions.ARB_vertex_program) {
330 if (index >= ctx->Const.MaxVertexProgramEnvParams) {
331 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
332 return;
333 }
334 COPY_4V(params, ctx->VertexProgram.Parameters[index]);
335 }
336 else {
337 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramEnvParameter(target)");
338 return;
339 }
340 }
341
342
343 /**
344 * Note, this function is also used by the GL_NV_fragment_program extension.
345 */
346 void GLAPIENTRY
347 _mesa_ProgramLocalParameter4fARB(GLenum target, GLuint index,
348 GLfloat x, GLfloat y, GLfloat z, GLfloat w)
349 {
350 GET_CURRENT_CONTEXT(ctx);
351 struct program *prog;
352 ASSERT_OUTSIDE_BEGIN_END(ctx);
353
354 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
355
356 if ((target == GL_FRAGMENT_PROGRAM_NV
357 && ctx->Extensions.NV_fragment_program) ||
358 (target == GL_FRAGMENT_PROGRAM_ARB
359 && ctx->Extensions.ARB_fragment_program)) {
360 if (index >= ctx->Const.MaxFragmentProgramLocalParams) {
361 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
362 return;
363 }
364 prog = &(ctx->FragmentProgram.Current->Base);
365 }
366 else if (target == GL_VERTEX_PROGRAM_ARB
367 && ctx->Extensions.ARB_vertex_program) {
368 if (index >= ctx->Const.MaxVertexProgramLocalParams) {
369 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
370 return;
371 }
372 prog = &(ctx->VertexProgram.Current->Base);
373 }
374 else {
375 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameterARB");
376 return;
377 }
378
379 ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS);
380 prog->LocalParams[index][0] = x;
381 prog->LocalParams[index][1] = y;
382 prog->LocalParams[index][2] = z;
383 prog->LocalParams[index][3] = w;
384 }
385
386
387 /**
388 * Note, this function is also used by the GL_NV_fragment_program extension.
389 */
390 void GLAPIENTRY
391 _mesa_ProgramLocalParameter4fvARB(GLenum target, GLuint index,
392 const GLfloat *params)
393 {
394 _mesa_ProgramLocalParameter4fARB(target, index, params[0], params[1],
395 params[2], params[3]);
396 }
397
398
399 /**
400 * Note, this function is also used by the GL_NV_fragment_program extension.
401 */
402 void GLAPIENTRY
403 _mesa_ProgramLocalParameter4dARB(GLenum target, GLuint index,
404 GLdouble x, GLdouble y,
405 GLdouble z, GLdouble w)
406 {
407 _mesa_ProgramLocalParameter4fARB(target, index, (GLfloat) x, (GLfloat) y,
408 (GLfloat) z, (GLfloat) w);
409 }
410
411
412 /**
413 * Note, this function is also used by the GL_NV_fragment_program extension.
414 */
415 void GLAPIENTRY
416 _mesa_ProgramLocalParameter4dvARB(GLenum target, GLuint index,
417 const GLdouble *params)
418 {
419 _mesa_ProgramLocalParameter4fARB(target, index,
420 (GLfloat) params[0], (GLfloat) params[1],
421 (GLfloat) params[2], (GLfloat) params[3]);
422 }
423
424
425 /**
426 * Note, this function is also used by the GL_NV_fragment_program extension.
427 */
428 void GLAPIENTRY
429 _mesa_GetProgramLocalParameterfvARB(GLenum target, GLuint index,
430 GLfloat *params)
431 {
432 const struct program *prog;
433 GLuint maxParams;
434 GET_CURRENT_CONTEXT(ctx);
435 ASSERT_OUTSIDE_BEGIN_END(ctx);
436
437 if (target == GL_VERTEX_PROGRAM_ARB
438 && ctx->Extensions.ARB_vertex_program) {
439 prog = &(ctx->VertexProgram.Current->Base);
440 maxParams = ctx->Const.MaxVertexProgramLocalParams;
441 }
442 else if (target == GL_FRAGMENT_PROGRAM_ARB
443 && ctx->Extensions.ARB_fragment_program) {
444 prog = &(ctx->FragmentProgram.Current->Base);
445 maxParams = ctx->Const.MaxFragmentProgramLocalParams;
446 }
447 else if (target == GL_FRAGMENT_PROGRAM_NV
448 && ctx->Extensions.NV_fragment_program) {
449 prog = &(ctx->FragmentProgram.Current->Base);
450 maxParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
451 }
452 else {
453 _mesa_error(ctx, GL_INVALID_ENUM,
454 "glGetProgramLocalParameterARB(target)");
455 return;
456 }
457
458 if (index >= maxParams) {
459 _mesa_error(ctx, GL_INVALID_VALUE,
460 "glGetProgramLocalParameterARB(index)");
461 return;
462 }
463
464 ASSERT(prog);
465 ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS);
466 COPY_4V(params, prog->LocalParams[index]);
467 }
468
469
470 /**
471 * Note, this function is also used by the GL_NV_fragment_program extension.
472 */
473 void GLAPIENTRY
474 _mesa_GetProgramLocalParameterdvARB(GLenum target, GLuint index,
475 GLdouble *params)
476 {
477 GET_CURRENT_CONTEXT(ctx);
478 GLfloat floatParams[4];
479 _mesa_GetProgramLocalParameterfvARB(target, index, floatParams);
480 if (ctx->ErrorValue == GL_NO_ERROR) {
481 COPY_4V(params, floatParams);
482 }
483 }
484
485
486 void GLAPIENTRY
487 _mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params)
488 {
489 struct program *prog;
490 GET_CURRENT_CONTEXT(ctx);
491
492 if (!ctx->_CurrentProgram)
493 ASSERT_OUTSIDE_BEGIN_END(ctx);
494
495 if (target == GL_VERTEX_PROGRAM_ARB
496 && ctx->Extensions.ARB_vertex_program) {
497 prog = &(ctx->VertexProgram.Current->Base);
498 }
499 else if (target == GL_FRAGMENT_PROGRAM_ARB
500 && ctx->Extensions.ARB_fragment_program) {
501 prog = &(ctx->FragmentProgram.Current->Base);
502 }
503 else {
504 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
505 return;
506 }
507
508 ASSERT(prog);
509
510 switch (pname) {
511 case GL_PROGRAM_LENGTH_ARB:
512 *params = prog->String ? (GLint)_mesa_strlen((char *) prog->String) : 0;
513 break;
514 case GL_PROGRAM_FORMAT_ARB:
515 *params = prog->Format;
516 break;
517 case GL_PROGRAM_BINDING_ARB:
518 *params = prog->Id;
519 break;
520 case GL_PROGRAM_INSTRUCTIONS_ARB:
521 *params = prog->NumInstructions;
522 break;
523 case GL_MAX_PROGRAM_INSTRUCTIONS_ARB:
524 if (target == GL_VERTEX_PROGRAM_ARB)
525 *params = ctx->Const.MaxVertexProgramInstructions;
526 else
527 *params = ctx->Const.MaxFragmentProgramInstructions;
528 break;
529 case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
530 *params = prog->NumInstructions;
531 break;
532 case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
533 if (target == GL_VERTEX_PROGRAM_ARB)
534 *params = ctx->Const.MaxVertexProgramInstructions;
535 else
536 *params = ctx->Const.MaxFragmentProgramInstructions;
537 break;
538 case GL_PROGRAM_TEMPORARIES_ARB:
539 *params = prog->NumTemporaries;
540 break;
541 case GL_MAX_PROGRAM_TEMPORARIES_ARB:
542 if (target == GL_VERTEX_PROGRAM_ARB)
543 *params = ctx->Const.MaxVertexProgramTemps;
544 else
545 *params = ctx->Const.MaxFragmentProgramTemps;
546 break;
547 case GL_PROGRAM_NATIVE_TEMPORARIES_ARB:
548 /* XXX same as GL_PROGRAM_TEMPORARIES_ARB? */
549 *params = prog->NumTemporaries;
550 break;
551 case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB:
552 /* XXX same as GL_MAX_PROGRAM_TEMPORARIES_ARB? */
553 if (target == GL_VERTEX_PROGRAM_ARB)
554 *params = ctx->Const.MaxVertexProgramTemps;
555 else
556 *params = ctx->Const.MaxFragmentProgramTemps;
557 break;
558 case GL_PROGRAM_PARAMETERS_ARB:
559 *params = prog->NumParameters;
560 break;
561 case GL_MAX_PROGRAM_PARAMETERS_ARB:
562 if (target == GL_VERTEX_PROGRAM_ARB)
563 *params = ctx->Const.MaxVertexProgramLocalParams;
564 else
565 *params = ctx->Const.MaxFragmentProgramLocalParams;
566 break;
567 case GL_PROGRAM_NATIVE_PARAMETERS_ARB:
568 /* XXX same as GL_MAX_PROGRAM_PARAMETERS_ARB? */
569 *params = prog->NumParameters;
570 break;
571 case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB:
572 /* XXX same as GL_MAX_PROGRAM_PARAMETERS_ARB? */
573 if (target == GL_VERTEX_PROGRAM_ARB)
574 *params = ctx->Const.MaxVertexProgramLocalParams;
575 else
576 *params = ctx->Const.MaxFragmentProgramLocalParams;
577 break;
578 case GL_PROGRAM_ATTRIBS_ARB:
579 *params = prog->NumAttributes;
580 break;
581 case GL_MAX_PROGRAM_ATTRIBS_ARB:
582 if (target == GL_VERTEX_PROGRAM_ARB)
583 *params = ctx->Const.MaxVertexProgramAttribs;
584 else
585 *params = ctx->Const.MaxFragmentProgramAttribs;
586 break;
587 case GL_PROGRAM_NATIVE_ATTRIBS_ARB:
588 /* XXX same as GL_PROGRAM_ATTRIBS_ARB? */
589 *params = prog->NumAttributes;
590 break;
591 case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB:
592 /* XXX same as GL_MAX_PROGRAM_ATTRIBS_ARB? */
593 if (target == GL_VERTEX_PROGRAM_ARB)
594 *params = ctx->Const.MaxVertexProgramAttribs;
595 else
596 *params = ctx->Const.MaxFragmentProgramAttribs;
597 break;
598 case GL_PROGRAM_ADDRESS_REGISTERS_ARB:
599 *params = prog->NumAddressRegs;
600 break;
601 case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB:
602 if (target == GL_VERTEX_PROGRAM_ARB)
603 *params = ctx->Const.MaxVertexProgramAddressRegs;
604 else
605 *params = ctx->Const.MaxFragmentProgramAddressRegs;
606 break;
607 case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
608 /* XXX same as GL_PROGRAM_ADDRESS_REGISTERS_ARB? */
609 *params = prog->NumAddressRegs;
610 break;
611 case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
612 /* XXX same as GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB? */
613 if (target == GL_VERTEX_PROGRAM_ARB)
614 *params = ctx->Const.MaxVertexProgramAddressRegs;
615 else
616 *params = ctx->Const.MaxFragmentProgramAddressRegs;
617 break;
618 case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB:
619 if (target == GL_VERTEX_PROGRAM_ARB)
620 *params = ctx->Const.MaxVertexProgramLocalParams;
621 else
622 *params = ctx->Const.MaxFragmentProgramLocalParams;
623 break;
624 case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB:
625 if (target == GL_VERTEX_PROGRAM_ARB)
626 *params = ctx->Const.MaxVertexProgramEnvParams;
627 else
628 *params = ctx->Const.MaxFragmentProgramEnvParams;
629 break;
630 case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB:
631 if (ctx->Driver.IsProgramNative)
632 *params = ctx->Driver.IsProgramNative( ctx, target, prog );
633 else
634 *params = GL_TRUE;
635 break;
636
637 /*
638 * The following apply to fragment programs only.
639 */
640 case GL_PROGRAM_ALU_INSTRUCTIONS_ARB:
641 case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
642 if (target != GL_FRAGMENT_PROGRAM_ARB) {
643 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
644 return;
645 }
646 *params = ctx->FragmentProgram.Current->NumAluInstructions;
647 break;
648 case GL_PROGRAM_TEX_INSTRUCTIONS_ARB:
649 case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
650 if (target != GL_FRAGMENT_PROGRAM_ARB) {
651 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
652 return;
653 }
654 *params = ctx->FragmentProgram.Current->NumTexInstructions;
655 break;
656 case GL_PROGRAM_TEX_INDIRECTIONS_ARB:
657 case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
658 if (target != GL_FRAGMENT_PROGRAM_ARB) {
659 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
660 return;
661 }
662 *params = ctx->FragmentProgram.Current->NumTexIndirections;
663 break;
664 case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB:
665 case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
666 if (target != GL_FRAGMENT_PROGRAM_ARB) {
667 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
668 return;
669 }
670 *params = ctx->Const.MaxFragmentProgramAluInstructions;
671 break;
672 case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB:
673 case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
674 if (target != GL_FRAGMENT_PROGRAM_ARB) {
675 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
676 return;
677 }
678 *params = ctx->Const.MaxFragmentProgramTexInstructions;
679 break;
680 case GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB:
681 case GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
682 if (target != GL_FRAGMENT_PROGRAM_ARB) {
683 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
684 return;
685 }
686 *params = ctx->Const.MaxFragmentProgramTexIndirections;
687 break;
688 default:
689 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(pname)");
690 return;
691 }
692 }
693
694
695 void GLAPIENTRY
696 _mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string)
697 {
698 struct program *prog;
699 GET_CURRENT_CONTEXT(ctx);
700
701 if (!ctx->_CurrentProgram)
702 ASSERT_OUTSIDE_BEGIN_END(ctx);
703
704 if (target == GL_VERTEX_PROGRAM_ARB) {
705 prog = &(ctx->VertexProgram.Current->Base);
706 }
707 else if (target == GL_FRAGMENT_PROGRAM_ARB) {
708 prog = &(ctx->FragmentProgram.Current->Base);
709 }
710 else {
711 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(target)");
712 return;
713 }
714
715 ASSERT(prog);
716
717 if (pname != GL_PROGRAM_STRING_ARB) {
718 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(pname)");
719 return;
720 }
721
722 MEMCPY(string, prog->String, _mesa_strlen((char *) prog->String));
723 }
724