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