test version of startmenu root with big icons
[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 >= VERT_ATTRIB_MAX) {
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 COPY_4V(params, ctx->Current.Attrib[index]);
134 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 }
140 params[0] = (GLfloat) ctx->Array.VertexAttrib[index].BufferObj->Name;
141 default:
142 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribfvARB(pname)");
143 return;
144 }
145 }
146
147
148 void GLAPIENTRY
149 _mesa_GetVertexAttribivARB(GLuint index, GLenum pname, GLint *params)
150 {
151 GLfloat fparams[4];
152 GET_CURRENT_CONTEXT(ctx);
153 ASSERT_OUTSIDE_BEGIN_END(ctx);
154
155 _mesa_GetVertexAttribfvARB(index, pname, fparams);
156 if (ctx->ErrorValue == GL_NO_ERROR) {
157 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
158 COPY_4V_CAST(params, fparams, GLint); /* float to int */
159 }
160 else {
161 params[0] = (GLint) fparams[0];
162 }
163 }
164 }
165
166
167 void GLAPIENTRY
168 _mesa_GetVertexAttribPointervARB(GLuint index, GLenum pname, GLvoid **pointer)
169 {
170 GET_CURRENT_CONTEXT(ctx);
171 ASSERT_OUTSIDE_BEGIN_END(ctx);
172
173 if (index >= ctx->Const.MaxVertexProgramAttribs) {
174 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerARB(index)");
175 return;
176 }
177
178 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) {
179 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerARB(pname)");
180 return;
181 }
182
183 *pointer = (GLvoid *) ctx->Array.VertexAttrib[index].Ptr;;
184 }
185
186
187 void GLAPIENTRY
188 _mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
189 const GLvoid *string)
190 {
191 GET_CURRENT_CONTEXT(ctx);
192 ASSERT_OUTSIDE_BEGIN_END(ctx);
193
194 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
195
196 if (target == GL_VERTEX_PROGRAM_ARB
197 && ctx->Extensions.ARB_vertex_program) {
198 struct vertex_program *prog = ctx->VertexProgram.Current;
199 if (format != GL_PROGRAM_FORMAT_ASCII_ARB) {
200 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(format)");
201 return;
202 }
203 _mesa_parse_arb_vertex_program(ctx, target, (const GLubyte *) string,
204 len, prog);
205
206 if (ctx->Driver.ProgramStringNotify)
207 ctx->Driver.ProgramStringNotify( ctx, target, &prog->Base );
208 }
209 else if (target == GL_FRAGMENT_PROGRAM_ARB
210 && ctx->Extensions.ARB_fragment_program) {
211 struct fragment_program *prog = ctx->FragmentProgram.Current;
212 if (format != GL_PROGRAM_FORMAT_ASCII_ARB) {
213 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(format)");
214 return;
215 }
216 _mesa_parse_arb_fragment_program(ctx, target, (const GLubyte *) string,
217 len, prog);
218
219 if (ctx->Driver.ProgramStringNotify)
220 ctx->Driver.ProgramStringNotify( ctx, target, &prog->Base );
221 }
222 else {
223 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(target)");
224 return;
225 }
226 }
227
228
229 void GLAPIENTRY
230 _mesa_ProgramEnvParameter4dARB(GLenum target, GLuint index,
231 GLdouble x, GLdouble y, GLdouble z, GLdouble w)
232 {
233 _mesa_ProgramEnvParameter4fARB(target, index, (GLfloat) x, (GLfloat) y,
234 (GLfloat) z, (GLfloat) w);
235 }
236
237
238 void GLAPIENTRY
239 _mesa_ProgramEnvParameter4dvARB(GLenum target, GLuint index,
240 const GLdouble *params)
241 {
242 _mesa_ProgramEnvParameter4fARB(target, index, (GLfloat) params[0],
243 (GLfloat) params[1], (GLfloat) params[2],
244 (GLfloat) params[3]);
245 }
246
247
248 void GLAPIENTRY
249 _mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index,
250 GLfloat x, GLfloat y, GLfloat z, GLfloat w)
251 {
252 GET_CURRENT_CONTEXT(ctx);
253 ASSERT_OUTSIDE_BEGIN_END(ctx);
254
255 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
256
257 if (target == GL_FRAGMENT_PROGRAM_ARB
258 && ctx->Extensions.ARB_fragment_program) {
259 if (index >= ctx->Const.MaxFragmentProgramEnvParams) {
260 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
261 return;
262 }
263 ASSIGN_4V(ctx->FragmentProgram.Parameters[index], x, y, z, w);
264 }
265 if (target == GL_VERTEX_PROGRAM_ARB
266 && ctx->Extensions.ARB_vertex_program) {
267 if (index >= ctx->Const.MaxVertexProgramEnvParams) {
268 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
269 return;
270 }
271 ASSIGN_4V(ctx->VertexProgram.Parameters[index], x, y, z, w);
272 }
273 else {
274 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameter(target)");
275 return;
276 }
277 }
278
279
280 void GLAPIENTRY
281 _mesa_ProgramEnvParameter4fvARB(GLenum target, GLuint index,
282 const GLfloat *params)
283 {
284 _mesa_ProgramEnvParameter4fARB(target, index, params[0], params[1],
285 params[2], params[3]);
286 }
287
288
289 void GLAPIENTRY
290 _mesa_GetProgramEnvParameterdvARB(GLenum target, GLuint index,
291 GLdouble *params)
292 {
293 GET_CURRENT_CONTEXT(ctx);
294 GLfloat fparams[4];
295
296 _mesa_GetProgramEnvParameterfvARB(target, index, fparams);
297 if (ctx->ErrorValue == GL_NO_ERROR) {
298 params[0] = fparams[0];
299 params[1] = fparams[1];
300 params[2] = fparams[2];
301 params[3] = fparams[3];
302 }
303 }
304
305
306 void GLAPIENTRY
307 _mesa_GetProgramEnvParameterfvARB(GLenum target, GLuint index,
308 GLfloat *params)
309 {
310 GET_CURRENT_CONTEXT(ctx);
311
312 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
313
314 if (!ctx->_CurrentProgram)
315 ASSERT_OUTSIDE_BEGIN_END(ctx);
316
317 if (target == GL_FRAGMENT_PROGRAM_ARB
318 && ctx->Extensions.ARB_fragment_program) {
319 if (index >= ctx->Const.MaxFragmentProgramEnvParams) {
320 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
321 return;
322 }
323 COPY_4V(params, ctx->FragmentProgram.Parameters[index]);
324 }
325 if (target == GL_VERTEX_PROGRAM_ARB
326 && ctx->Extensions.ARB_vertex_program) {
327 if (index >= ctx->Const.MaxVertexProgramEnvParams) {
328 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
329 return;
330 }
331 COPY_4V(params, ctx->VertexProgram.Parameters[index]);
332 }
333 else {
334 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramEnvParameter(target)");
335 return;
336 }
337 }
338
339
340 /**
341 * Note, this function is also used by the GL_NV_fragment_program extension.
342 */
343 void GLAPIENTRY
344 _mesa_ProgramLocalParameter4fARB(GLenum target, GLuint index,
345 GLfloat x, GLfloat y, GLfloat z, GLfloat w)
346 {
347 GET_CURRENT_CONTEXT(ctx);
348 struct program *prog;
349 ASSERT_OUTSIDE_BEGIN_END(ctx);
350
351 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
352
353 if ((target == GL_FRAGMENT_PROGRAM_NV
354 && ctx->Extensions.NV_fragment_program) ||
355 (target == GL_FRAGMENT_PROGRAM_ARB
356 && ctx->Extensions.ARB_fragment_program)) {
357 if (index >= ctx->Const.MaxFragmentProgramLocalParams) {
358 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
359 return;
360 }
361 prog = &(ctx->FragmentProgram.Current->Base);
362 }
363 else if (target == GL_VERTEX_PROGRAM_ARB
364 && ctx->Extensions.ARB_vertex_program) {
365 if (index >= ctx->Const.MaxVertexProgramLocalParams) {
366 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
367 return;
368 }
369 prog = &(ctx->VertexProgram.Current->Base);
370 }
371 else {
372 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameterARB");
373 return;
374 }
375
376 ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS);
377 prog->LocalParams[index][0] = x;
378 prog->LocalParams[index][1] = y;
379 prog->LocalParams[index][2] = z;
380 prog->LocalParams[index][3] = w;
381 }
382
383
384 /**
385 * Note, this function is also used by the GL_NV_fragment_program extension.
386 */
387 void GLAPIENTRY
388 _mesa_ProgramLocalParameter4fvARB(GLenum target, GLuint index,
389 const GLfloat *params)
390 {
391 _mesa_ProgramLocalParameter4fARB(target, index, params[0], params[1],
392 params[2], params[3]);
393 }
394
395
396 /**
397 * Note, this function is also used by the GL_NV_fragment_program extension.
398 */
399 void GLAPIENTRY
400 _mesa_ProgramLocalParameter4dARB(GLenum target, GLuint index,
401 GLdouble x, GLdouble y,
402 GLdouble z, GLdouble w)
403 {
404 _mesa_ProgramLocalParameter4fARB(target, index, (GLfloat) x, (GLfloat) y,
405 (GLfloat) z, (GLfloat) w);
406 }
407
408
409 /**
410 * Note, this function is also used by the GL_NV_fragment_program extension.
411 */
412 void GLAPIENTRY
413 _mesa_ProgramLocalParameter4dvARB(GLenum target, GLuint index,
414 const GLdouble *params)
415 {
416 _mesa_ProgramLocalParameter4fARB(target, index,
417 (GLfloat) params[0], (GLfloat) params[1],
418 (GLfloat) params[2], (GLfloat) params[3]);
419 }
420
421
422 /**
423 * Note, this function is also used by the GL_NV_fragment_program extension.
424 */
425 void GLAPIENTRY
426 _mesa_GetProgramLocalParameterfvARB(GLenum target, GLuint index,
427 GLfloat *params)
428 {
429 const struct program *prog;
430 GLuint maxParams;
431 GET_CURRENT_CONTEXT(ctx);
432 ASSERT_OUTSIDE_BEGIN_END(ctx);
433
434 if (target == GL_VERTEX_PROGRAM_ARB
435 && ctx->Extensions.ARB_vertex_program) {
436 prog = &(ctx->VertexProgram.Current->Base);
437 maxParams = ctx->Const.MaxVertexProgramLocalParams;
438 }
439 else if (target == GL_FRAGMENT_PROGRAM_ARB
440 && ctx->Extensions.ARB_fragment_program) {
441 prog = &(ctx->FragmentProgram.Current->Base);
442 maxParams = ctx->Const.MaxFragmentProgramLocalParams;
443 }
444 else if (target == GL_FRAGMENT_PROGRAM_NV
445 && ctx->Extensions.NV_fragment_program) {
446 prog = &(ctx->FragmentProgram.Current->Base);
447 maxParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
448 }
449 else {
450 _mesa_error(ctx, GL_INVALID_ENUM,
451 "glGetProgramLocalParameterARB(target)");
452 return;
453 }
454
455 if (index >= maxParams) {
456 _mesa_error(ctx, GL_INVALID_VALUE,
457 "glGetProgramLocalParameterARB(index)");
458 return;
459 }
460
461 ASSERT(prog);
462 ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS);
463 COPY_4V(params, prog->LocalParams[index]);
464 }
465
466
467 /**
468 * Note, this function is also used by the GL_NV_fragment_program extension.
469 */
470 void GLAPIENTRY
471 _mesa_GetProgramLocalParameterdvARB(GLenum target, GLuint index,
472 GLdouble *params)
473 {
474 GET_CURRENT_CONTEXT(ctx);
475 GLfloat floatParams[4];
476 _mesa_GetProgramLocalParameterfvARB(target, index, floatParams);
477 if (ctx->ErrorValue == GL_NO_ERROR) {
478 COPY_4V(params, floatParams);
479 }
480 }
481
482
483 void GLAPIENTRY
484 _mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params)
485 {
486 struct program *prog;
487 GET_CURRENT_CONTEXT(ctx);
488
489 if (!ctx->_CurrentProgram)
490 ASSERT_OUTSIDE_BEGIN_END(ctx);
491
492 if (target == GL_VERTEX_PROGRAM_ARB
493 && ctx->Extensions.ARB_vertex_program) {
494 prog = &(ctx->VertexProgram.Current->Base);
495 }
496 else if (target == GL_FRAGMENT_PROGRAM_ARB
497 && ctx->Extensions.ARB_fragment_program) {
498 prog = &(ctx->FragmentProgram.Current->Base);
499 }
500 else {
501 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
502 return;
503 }
504
505 ASSERT(prog);
506
507 switch (pname) {
508 case GL_PROGRAM_LENGTH_ARB:
509 *params = prog->String ? _mesa_strlen((char *) prog->String) : 0;
510 break;
511 case GL_PROGRAM_FORMAT_ARB:
512 *params = prog->Format;
513 break;
514 case GL_PROGRAM_BINDING_ARB:
515 *params = prog->Id;
516 break;
517 case GL_PROGRAM_INSTRUCTIONS_ARB:
518 *params = prog->NumInstructions;
519 break;
520 case GL_MAX_PROGRAM_INSTRUCTIONS_ARB:
521 if (target == GL_VERTEX_PROGRAM_ARB)
522 *params = ctx->Const.MaxVertexProgramInstructions;
523 else
524 *params = ctx->Const.MaxFragmentProgramInstructions;
525 break;
526 case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
527 *params = prog->NumInstructions;
528 break;
529 case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
530 if (target == GL_VERTEX_PROGRAM_ARB)
531 *params = ctx->Const.MaxVertexProgramInstructions;
532 else
533 *params = ctx->Const.MaxFragmentProgramInstructions;
534 break;
535 case GL_PROGRAM_TEMPORARIES_ARB:
536 *params = prog->NumTemporaries;
537 break;
538 case GL_MAX_PROGRAM_TEMPORARIES_ARB:
539 if (target == GL_VERTEX_PROGRAM_ARB)
540 *params = ctx->Const.MaxVertexProgramTemps;
541 else
542 *params = ctx->Const.MaxFragmentProgramTemps;
543 break;
544 case GL_PROGRAM_NATIVE_TEMPORARIES_ARB:
545 /* XXX same as GL_PROGRAM_TEMPORARIES_ARB? */
546 *params = prog->NumTemporaries;
547 break;
548 case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB:
549 /* XXX same as GL_MAX_PROGRAM_TEMPORARIES_ARB? */
550 if (target == GL_VERTEX_PROGRAM_ARB)
551 *params = ctx->Const.MaxVertexProgramTemps;
552 else
553 *params = ctx->Const.MaxFragmentProgramTemps;
554 break;
555 case GL_PROGRAM_PARAMETERS_ARB:
556 *params = prog->NumParameters;
557 break;
558 case GL_MAX_PROGRAM_PARAMETERS_ARB:
559 if (target == GL_VERTEX_PROGRAM_ARB)
560 *params = ctx->Const.MaxVertexProgramLocalParams;
561 else
562 *params = ctx->Const.MaxFragmentProgramLocalParams;
563 break;
564 case GL_PROGRAM_NATIVE_PARAMETERS_ARB:
565 /* XXX same as GL_MAX_PROGRAM_PARAMETERS_ARB? */
566 *params = prog->NumParameters;
567 break;
568 case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB:
569 /* XXX same as GL_MAX_PROGRAM_PARAMETERS_ARB? */
570 if (target == GL_VERTEX_PROGRAM_ARB)
571 *params = ctx->Const.MaxVertexProgramLocalParams;
572 else
573 *params = ctx->Const.MaxFragmentProgramLocalParams;
574 break;
575 case GL_PROGRAM_ATTRIBS_ARB:
576 *params = prog->NumAttributes;
577 break;
578 case GL_MAX_PROGRAM_ATTRIBS_ARB:
579 if (target == GL_VERTEX_PROGRAM_ARB)
580 *params = ctx->Const.MaxVertexProgramAttribs;
581 else
582 *params = ctx->Const.MaxFragmentProgramAttribs;
583 break;
584 case GL_PROGRAM_NATIVE_ATTRIBS_ARB:
585 /* XXX same as GL_PROGRAM_ATTRIBS_ARB? */
586 *params = prog->NumAttributes;
587 break;
588 case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB:
589 /* XXX same as GL_MAX_PROGRAM_ATTRIBS_ARB? */
590 if (target == GL_VERTEX_PROGRAM_ARB)
591 *params = ctx->Const.MaxVertexProgramAttribs;
592 else
593 *params = ctx->Const.MaxFragmentProgramAttribs;
594 break;
595 case GL_PROGRAM_ADDRESS_REGISTERS_ARB:
596 *params = prog->NumAddressRegs;
597 break;
598 case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB:
599 if (target == GL_VERTEX_PROGRAM_ARB)
600 *params = ctx->Const.MaxVertexProgramAddressRegs;
601 else
602 *params = ctx->Const.MaxFragmentProgramAddressRegs;
603 break;
604 case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
605 /* XXX same as GL_PROGRAM_ADDRESS_REGISTERS_ARB? */
606 *params = prog->NumAddressRegs;
607 break;
608 case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
609 /* XXX same as GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB? */
610 if (target == GL_VERTEX_PROGRAM_ARB)
611 *params = ctx->Const.MaxVertexProgramAddressRegs;
612 else
613 *params = ctx->Const.MaxFragmentProgramAddressRegs;
614 break;
615 case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB:
616 if (target == GL_VERTEX_PROGRAM_ARB)
617 *params = ctx->Const.MaxVertexProgramLocalParams;
618 else
619 *params = ctx->Const.MaxFragmentProgramLocalParams;
620 break;
621 case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB:
622 if (target == GL_VERTEX_PROGRAM_ARB)
623 *params = ctx->Const.MaxVertexProgramEnvParams;
624 else
625 *params = ctx->Const.MaxFragmentProgramEnvParams;
626 break;
627 case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB:
628 if (ctx->Driver.IsProgramNative)
629 *params = ctx->Driver.IsProgramNative( ctx, target, prog );
630 else
631 *params = GL_TRUE;
632 break;
633
634 /*
635 * The following apply to fragment programs only.
636 */
637 case GL_PROGRAM_ALU_INSTRUCTIONS_ARB:
638 case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
639 if (target != GL_FRAGMENT_PROGRAM_ARB) {
640 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
641 return;
642 }
643 *params = ctx->FragmentProgram.Current->NumAluInstructions;
644 break;
645 case GL_PROGRAM_TEX_INSTRUCTIONS_ARB:
646 case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
647 if (target != GL_FRAGMENT_PROGRAM_ARB) {
648 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
649 return;
650 }
651 *params = ctx->FragmentProgram.Current->NumTexInstructions;
652 break;
653 case GL_PROGRAM_TEX_INDIRECTIONS_ARB:
654 case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
655 if (target != GL_FRAGMENT_PROGRAM_ARB) {
656 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
657 return;
658 }
659 *params = ctx->FragmentProgram.Current->NumTexIndirections;
660 break;
661 case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB:
662 case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
663 if (target != GL_FRAGMENT_PROGRAM_ARB) {
664 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
665 return;
666 }
667 *params = ctx->Const.MaxFragmentProgramAluInstructions;
668 break;
669 case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB:
670 case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
671 if (target != GL_FRAGMENT_PROGRAM_ARB) {
672 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
673 return;
674 }
675 *params = ctx->Const.MaxFragmentProgramTexInstructions;
676 break;
677 case GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB:
678 case GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
679 if (target != GL_FRAGMENT_PROGRAM_ARB) {
680 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
681 return;
682 }
683 *params = ctx->Const.MaxFragmentProgramTexIndirections;
684 break;
685 default:
686 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(pname)");
687 return;
688 }
689 }
690
691
692 void GLAPIENTRY
693 _mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string)
694 {
695 struct program *prog;
696 GET_CURRENT_CONTEXT(ctx);
697
698 if (!ctx->_CurrentProgram)
699 ASSERT_OUTSIDE_BEGIN_END(ctx);
700
701 if (target == GL_VERTEX_PROGRAM_ARB) {
702 prog = &(ctx->VertexProgram.Current->Base);
703 }
704 else if (target == GL_FRAGMENT_PROGRAM_ARB) {
705 prog = &(ctx->FragmentProgram.Current->Base);
706 }
707 else {
708 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(target)");
709 return;
710 }
711
712 ASSERT(prog);
713
714 if (pname != GL_PROGRAM_STRING_ARB) {
715 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(pname)");
716 return;
717 }
718
719 MEMCPY(string, prog->String, _mesa_strlen((char *) prog->String));
720 }
721