arbprogram.c revision b0b9b798ac0620aeba15143f84c1d1ef2ddd44db
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 * \brief ARB_vertex/fragment_program state management functions. 28 * \author Brian Paul 29 */ 30 31 32#include "glheader.h" 33#include "arbprogram.h" 34#include "context.h" 35#include "hash.h" 36#include "imports.h" 37#include "macros.h" 38#include "mtypes.h" 39#include "nvprogram.h" 40#include "nvfragprog.h" 41#include "nvvertprog.h" 42 43 44/* XXX temporary */ 45static void 46_mesa_parse_arb_vertex_program(GLcontext *ctx, GLenum target, 47 const GLubyte *string, GLsizei len, 48 struct vertex_program *prog) 49{ 50} 51 52 53static void 54_mesa_parse_arb_fragment_program(GLcontext *ctx, GLenum target, 55 const GLubyte *string, GLsizei len, 56 struct fragment_program *prog) 57{ 58} 59 60 61 62void 63_mesa_VertexAttrib1sARB(GLuint index, GLshort x) 64{ 65} 66 67void 68_mesa_VertexAttrib1fARB(GLuint index, GLfloat x) 69{ 70} 71 72void 73_mesa_VertexAttrib1dARB(GLuint index, GLdouble x) 74{ 75} 76 77void 78_mesa_VertexAttrib2sARB(GLuint index, GLshort x, GLshort y) 79{ 80} 81 82void 83_mesa_VertexAttrib2fARB(GLuint index, GLfloat x, GLfloat y) 84{ 85} 86 87void 88_mesa_VertexAttrib2dARB(GLuint index, GLdouble x, GLdouble y) 89{ 90} 91 92void 93_mesa_VertexAttrib3sARB(GLuint index, GLshort x, GLshort y, GLshort z) 94{ 95} 96 97void 98_mesa_VertexAttrib3fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z) 99{ 100} 101 102void 103_mesa_VertexAttrib3dARB(GLuint index, GLdouble x, GLdouble y, GLdouble z) 104{ 105} 106 107void 108_mesa_VertexAttrib4sARB(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w) 109{ 110} 111 112void 113_mesa_VertexAttrib4fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) 114{ 115} 116 117void 118_mesa_VertexAttrib4dARB(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) 119{ 120} 121 122void 123_mesa_VertexAttrib4NubARB(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w) 124{ 125} 126 127void 128_mesa_VertexAttrib1svARB(GLuint index, const GLshort *v) 129{ 130} 131 132void 133_mesa_VertexAttrib1fvARB(GLuint index, const GLfloat *v) 134{ 135} 136 137void 138_mesa_VertexAttrib1dvARB(GLuint index, const GLdouble *v) 139{ 140} 141 142void 143_mesa_VertexAttrib2svARB(GLuint index, const GLshort *v) 144{ 145} 146 147void 148_mesa_VertexAttrib2fvARB(GLuint index, const GLfloat *v) 149{ 150} 151 152void 153_mesa_VertexAttrib2dvARB(GLuint index, const GLdouble *v) 154{ 155} 156 157void 158_mesa_VertexAttrib3svARB(GLuint index, const GLshort *v) 159{ 160} 161 162void 163_mesa_VertexAttrib3fvARB(GLuint index, const GLfloat *v) 164{ 165} 166 167void 168_mesa_VertexAttrib3dvARB(GLuint index, const GLdouble *v) 169{ 170} 171 172void 173_mesa_VertexAttrib4bvARB(GLuint index, const GLbyte *v) 174{ 175} 176 177void 178_mesa_VertexAttrib4svARB(GLuint index, const GLshort *v) 179{ 180} 181 182void 183_mesa_VertexAttrib4ivARB(GLuint index, const GLint *v) 184{ 185} 186 187void 188_mesa_VertexAttrib4ubvARB(GLuint index, const GLubyte *v) 189{ 190} 191 192void 193_mesa_VertexAttrib4usvARB(GLuint index, const GLushort *v) 194{ 195} 196 197void 198_mesa_VertexAttrib4uivARB(GLuint index, const GLuint *v) 199{ 200} 201 202void 203_mesa_VertexAttrib4fvARB(GLuint index, const GLfloat *v) 204{ 205} 206 207void 208_mesa_VertexAttrib4dvARB(GLuint index, const GLdouble *v) 209{ 210} 211 212void 213_mesa_VertexAttrib4NbvARB(GLuint index, const GLbyte *v) 214{ 215} 216 217void 218_mesa_VertexAttrib4NsvARB(GLuint index, const GLshort *v) 219{ 220} 221 222void 223_mesa_VertexAttrib4NivARB(GLuint index, const GLint *v) 224{ 225} 226 227void 228_mesa_VertexAttrib4NubvARB(GLuint index, const GLubyte *v) 229{ 230} 231 232void 233_mesa_VertexAttrib4NusvARB(GLuint index, const GLushort *v) 234{ 235} 236 237void 238_mesa_VertexAttrib4NuivARB(GLuint index, const GLuint *v) 239{ 240} 241 242 243void 244_mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type, 245 GLboolean normalized, GLsizei stride, 246 const GLvoid *pointer) 247{ 248} 249 250 251void 252_mesa_EnableVertexAttribArrayARB(GLuint index) 253{ 254 GET_CURRENT_CONTEXT(ctx); 255 ASSERT_OUTSIDE_BEGIN_END(ctx); 256 257 if (index >= ctx->Const.MaxVertexProgramAttribs) { 258 _mesa_error(ctx, GL_INVALID_VALUE, 259 "glEnableVertexAttribArrayARB(index)"); 260 return; 261 } 262 263 ctx->Array.VertexAttrib[index].Enabled = GL_TRUE; 264 ctx->Array._Enabled |= _NEW_ARRAY_ATTRIB(index); 265 ctx->Array.NewState |= _NEW_ARRAY_ATTRIB(index); 266} 267 268 269void 270_mesa_DisableVertexAttribArrayARB(GLuint index) 271{ 272 GET_CURRENT_CONTEXT(ctx); 273 ASSERT_OUTSIDE_BEGIN_END(ctx); 274 275 if (index >= ctx->Const.MaxVertexProgramAttribs) { 276 _mesa_error(ctx, GL_INVALID_VALUE, 277 "glEnableVertexAttribArrayARB(index)"); 278 return; 279 } 280 281 ctx->Array.VertexAttrib[index].Enabled = GL_FALSE; 282 ctx->Array._Enabled &= ~_NEW_ARRAY_ATTRIB(index); 283 ctx->Array.NewState &= ~_NEW_ARRAY_ATTRIB(index); 284} 285 286 287void 288_mesa_GetVertexAttribdvARB(GLuint index, GLenum pname, GLdouble *params) 289{ 290 GLfloat fparams[4]; 291 GET_CURRENT_CONTEXT(ctx); 292 ASSERT_OUTSIDE_BEGIN_END(ctx); 293 294 _mesa_GetVertexAttribfvARB(index, pname, fparams); 295 if (ctx->ErrorValue == GL_NO_ERROR) { 296 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { 297 COPY_4V(params, fparams); 298 } 299 else { 300 params[0] = fparams[0]; 301 } 302 } 303} 304 305 306void 307_mesa_GetVertexAttribfvARB(GLuint index, GLenum pname, GLfloat *params) 308{ 309 GET_CURRENT_CONTEXT(ctx); 310 ASSERT_OUTSIDE_BEGIN_END(ctx); 311 312 if (index == 0 || index >= VERT_ATTRIB_MAX) { 313 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribfvARB(index)"); 314 return; 315 } 316 317 switch (pname) { 318 case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB: 319 params[0] = ctx->Array.VertexAttrib[index].Enabled; 320 break; 321 case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB: 322 params[0] = ctx->Array.VertexAttrib[index].Size; 323 break; 324 case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB: 325 params[0] = ctx->Array.VertexAttrib[index].Stride; 326 break; 327 case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB: 328 params[0] = ctx->Array.VertexAttrib[index].Type; 329 break; 330 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB: 331 params[0] = ctx->Array.VertexAttrib[index].Normalized; 332 break; 333 case GL_CURRENT_VERTEX_ATTRIB_ARB: 334 COPY_4V(params, ctx->Current.Attrib[index]); 335 break; 336 default: 337 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribfvARB(pname)"); 338 return; 339 } 340} 341 342 343void 344_mesa_GetVertexAttribivARB(GLuint index, GLenum pname, GLint *params) 345{ 346 GLfloat fparams[4]; 347 GET_CURRENT_CONTEXT(ctx); 348 ASSERT_OUTSIDE_BEGIN_END(ctx); 349 350 _mesa_GetVertexAttribfvARB(index, pname, fparams); 351 if (ctx->ErrorValue == GL_NO_ERROR) { 352 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { 353 COPY_4V(params, fparams); /* float to int */ 354 } 355 else { 356 params[0] = fparams[0]; 357 } 358 } 359} 360 361 362void 363_mesa_GetVertexAttribPointervARB(GLuint index, GLenum pname, GLvoid **pointer) 364{ 365 GET_CURRENT_CONTEXT(ctx); 366 ASSERT_OUTSIDE_BEGIN_END(ctx); 367 368 if (index >= ctx->Const.MaxVertexProgramAttribs) { 369 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerARB(index)"); 370 return; 371 } 372 373 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) { 374 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerARB(pname)"); 375 return; 376 } 377 378 *pointer = ctx->Array.VertexAttrib[index].Ptr;; 379} 380 381 382void 383_mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len, 384 const GLvoid *string) 385{ 386 GET_CURRENT_CONTEXT(ctx); 387 ASSERT_OUTSIDE_BEGIN_END(ctx); 388 389 if (target == GL_VERTEX_PROGRAM_ARB 390 && ctx->Extensions.ARB_vertex_program) { 391 struct vertex_program *prog = ctx->VertexProgram.Current; 392 if (format != GL_PROGRAM_FORMAT_ASCII_ARB) { 393 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(format)"); 394 return; 395 } 396 _mesa_parse_arb_vertex_program(ctx, target, string, len, prog); 397 } 398 else if (target == GL_FRAGMENT_PROGRAM_ARB 399 && ctx->Extensions.ARB_fragment_program) { 400 struct fragment_program *prog = ctx->FragmentProgram.Current; 401 if (format != GL_PROGRAM_FORMAT_ASCII_ARB) { 402 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(format)"); 403 return; 404 } 405 _mesa_parse_arb_fragment_program(ctx, target, string, len, prog); 406 } 407 else { 408 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(target)"); 409 } 410} 411 412 413void 414_mesa_BindProgramARB(GLenum target, GLuint program) 415{ 416 struct program *prog; 417 GET_CURRENT_CONTEXT(ctx); 418 ASSERT_OUTSIDE_BEGIN_END(ctx); 419 420 if (target == GL_VERTEX_PROGRAM_ARB 421 && ctx->Extensions.ARB_vertex_program) { 422 if (ctx->VertexProgram.Current && 423 ctx->VertexProgram.Current->Base.Id == program) 424 return; 425 /* decrement refcount on previously bound vertex program */ 426 if (ctx->VertexProgram.Current) { 427 ctx->VertexProgram.Current->Base.RefCount--; 428 /* and delete if refcount goes below one */ 429 if (ctx->VertexProgram.Current->Base.RefCount <= 0) { 430 _mesa_delete_program(ctx, &(ctx->VertexProgram.Current->Base)); 431 _mesa_HashRemove(ctx->Shared->Programs, program); 432 } 433 } 434 } 435 else if (target == GL_FRAGMENT_PROGRAM_ARB 436 && ctx->Extensions.ARB_fragment_program) { 437 if (ctx->FragmentProgram.Current && 438 ctx->FragmentProgram.Current->Base.Id == program) 439 return; 440 /* decrement refcount on previously bound fragment program */ 441 if (ctx->FragmentProgram.Current) { 442 ctx->FragmentProgram.Current->Base.RefCount--; 443 /* and delete if refcount goes below one */ 444 if (ctx->FragmentProgram.Current->Base.RefCount <= 0) { 445 _mesa_delete_program(ctx, &(ctx->FragmentProgram.Current->Base)); 446 _mesa_HashRemove(ctx->Shared->Programs, program); 447 } 448 } 449 } 450 else { 451 _mesa_error(ctx, GL_INVALID_ENUM, "glBindProgramARB(target)"); 452 return; 453 } 454 455 /* NOTE: binding to a non-existant program is not an error. 456 * That's supposed to be caught in glBegin. 457 * NOTE: program number 0 is legal here. 458 */ 459 if (program == 0) { 460 /* default program */ 461 if (target == GL_VERTEX_PROGRAM_ARB) 462 prog = ctx->Shared->DefaultVertexProgram; 463 else 464 prog = ctx->Shared->DefaultFragmentProgram; 465 } 466 else { 467 prog = (struct program *) _mesa_HashLookup(ctx->Shared->Programs, program); 468 if (prog) { 469 if (prog->Target == 0) { 470 /* prog was allocated with glGenProgramsARB */ 471 prog->Target = target; 472 } 473 else if (prog->Target != target) { 474 _mesa_error(ctx, GL_INVALID_OPERATION, 475 "glBindProgramARB(target mismatch)"); 476 return; 477 } 478 } 479 else { 480 /* allocate a new program now */ 481 prog = _mesa_alloc_program(ctx, target, program); 482 if (!prog) { 483 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindProgramARB"); 484 return; 485 } 486 prog->Id = program; 487 prog->Target = target; 488 prog->Resident = GL_TRUE; 489 prog->RefCount = 1; 490 _mesa_HashInsert(ctx->Shared->Programs, program, prog); 491 } 492 } 493 494 /* bind now */ 495 if (target == GL_VERTEX_PROGRAM_ARB) { 496 ctx->VertexProgram.Current = (struct vertex_program *) prog; 497 } 498 else { 499 ASSERT(target == GL_FRAGMENT_PROGRAM_ARB); 500 ctx->FragmentProgram.Current = (struct fragment_program *) prog; 501 } 502 503 if (prog) 504 prog->RefCount++; 505} 506 507 508void 509_mesa_ProgramEnvParameter4dARB(GLenum target, GLuint index, 510 GLdouble x, GLdouble y, GLdouble z, GLdouble w) 511{ 512 _mesa_ProgramEnvParameter4fARB(target, index, x, y, z, w); 513} 514 515 516void 517_mesa_ProgramEnvParameter4dvARB(GLenum target, GLuint index, 518 const GLdouble *params) 519{ 520 _mesa_ProgramEnvParameter4fARB(target, index, params[0], params[1], 521 params[2], params[3]); 522} 523 524 525void 526_mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index, 527 GLfloat x, GLfloat y, GLfloat z, GLfloat w) 528{ 529 GET_CURRENT_CONTEXT(ctx); 530 ASSERT_OUTSIDE_BEGIN_END(ctx); 531 532 if (target == GL_FRAGMENT_PROGRAM_ARB 533 && ctx->Extensions.ARB_fragment_program) { 534 if (index >= ctx->Const.MaxFragmentProgramEnvParams) { 535 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)"); 536 return; 537 } 538 index += FP_PROG_REG_START; 539 ASSIGN_4V(ctx->FragmentProgram.Machine.Registers[index], x, y, z, w); 540 } 541 if (target == GL_VERTEX_PROGRAM_ARB 542 && ctx->Extensions.ARB_vertex_program) { 543 if (index >= ctx->Const.MaxVertexProgramEnvParams) { 544 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)"); 545 return; 546 } 547 index += VP_PROG_REG_START; 548 ASSIGN_4V(ctx->VertexProgram.Machine.Registers[index], x, y, z, w); 549 } 550 else { 551 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameter(target)"); 552 return; 553 } 554} 555 556 557void 558_mesa_ProgramEnvParameter4fvARB(GLenum target, GLuint index, 559 const GLfloat *params) 560{ 561 _mesa_ProgramEnvParameter4fARB(target, index, params[0], params[1], 562 params[2], params[3]); 563} 564 565 566void 567_mesa_GetProgramEnvParameterdvARB(GLenum target, GLuint index, 568 GLdouble *params) 569{ 570 GET_CURRENT_CONTEXT(ctx); 571 GLfloat fparams[4]; 572 573 _mesa_GetProgramEnvParameterfvARB(target, index, fparams); 574 if (ctx->ErrorValue == GL_NO_ERROR) { 575 params[0] = fparams[0]; 576 params[1] = fparams[1]; 577 params[2] = fparams[2]; 578 params[3] = fparams[3]; 579 } 580} 581 582 583void 584_mesa_GetProgramEnvParameterfvARB(GLenum target, GLuint index, 585 GLfloat *params) 586{ 587 GET_CURRENT_CONTEXT(ctx); 588 ASSERT_OUTSIDE_BEGIN_END(ctx); 589 590 if (target == GL_FRAGMENT_PROGRAM_ARB 591 && ctx->Extensions.ARB_fragment_program) { 592 if (index >= ctx->Const.MaxFragmentProgramEnvParams) { 593 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)"); 594 return; 595 } 596 index += FP_PROG_REG_START; 597 COPY_4V(params, ctx->FragmentProgram.Machine.Registers[index]); 598 } 599 if (target == GL_VERTEX_PROGRAM_ARB 600 && ctx->Extensions.ARB_vertex_program) { 601 if (index >= ctx->Const.MaxVertexProgramEnvParams) { 602 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)"); 603 return; 604 } 605 index += VP_PROG_REG_START; 606 COPY_4V(params, ctx->VertexProgram.Machine.Registers[index]); 607 } 608 else { 609 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramEnvParameter(target)"); 610 return; 611 } 612} 613 614 615/** 616 * Note, this function is also used by the GL_NV_fragment_program extension. 617 */ 618void 619_mesa_ProgramLocalParameter4fARB(GLenum target, GLuint index, 620 GLfloat x, GLfloat y, GLfloat z, GLfloat w) 621{ 622 GET_CURRENT_CONTEXT(ctx); 623 struct program *prog; 624 ASSERT_OUTSIDE_BEGIN_END(ctx); 625 626 if ((target == GL_FRAGMENT_PROGRAM_NV 627 && ctx->Extensions.NV_fragment_program) || 628 (target == GL_FRAGMENT_PROGRAM_ARB 629 && ctx->Extensions.ARB_fragment_program)) { 630 if (index >= ctx->Const.MaxFragmentProgramLocalParams) { 631 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB"); 632 return; 633 } 634 prog = &(ctx->FragmentProgram.Current->Base); 635 } 636 else if (target == GL_VERTEX_PROGRAM_ARB 637 && ctx->Extensions.ARB_vertex_program) { 638 if (index >= ctx->Const.MaxVertexProgramLocalParams) { 639 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB"); 640 return; 641 } 642 prog = &(ctx->VertexProgram.Current->Base); 643 } 644 else { 645 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameterARB"); 646 return; 647 } 648 649 ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS); 650 prog->LocalParams[index][0] = x; 651 prog->LocalParams[index][1] = y; 652 prog->LocalParams[index][2] = z; 653 prog->LocalParams[index][3] = w; 654} 655 656 657/** 658 * Note, this function is also used by the GL_NV_fragment_program extension. 659 */ 660void 661_mesa_ProgramLocalParameter4fvARB(GLenum target, GLuint index, 662 const GLfloat *params) 663{ 664 _mesa_ProgramLocalParameter4fARB(target, index, params[0], params[1], 665 params[2], params[3]); 666} 667 668 669/** 670 * Note, this function is also used by the GL_NV_fragment_program extension. 671 */ 672void 673_mesa_ProgramLocalParameter4dARB(GLenum target, GLuint index, 674 GLdouble x, GLdouble y, 675 GLdouble z, GLdouble w) 676{ 677 _mesa_ProgramLocalParameter4fARB(target, index, (GLfloat) x, (GLfloat) y, 678 (GLfloat) z, (GLfloat) w); 679} 680 681 682/** 683 * Note, this function is also used by the GL_NV_fragment_program extension. 684 */ 685void 686_mesa_ProgramLocalParameter4dvARB(GLenum target, GLuint index, 687 const GLdouble *params) 688{ 689 _mesa_ProgramLocalParameter4fARB(target, index, 690 (GLfloat) params[0], (GLfloat) params[1], 691 (GLfloat) params[2], (GLfloat) params[3]); 692} 693 694 695/** 696 * Note, this function is also used by the GL_NV_fragment_program extension. 697 */ 698void 699_mesa_GetProgramLocalParameterfvARB(GLenum target, GLuint index, 700 GLfloat *params) 701{ 702 const struct program *prog; 703 GLuint maxParams; 704 GET_CURRENT_CONTEXT(ctx); 705 ASSERT_OUTSIDE_BEGIN_END(ctx); 706 707 if (target == GL_VERTEX_PROGRAM_ARB 708 && ctx->Extensions.ARB_vertex_program) { 709 prog = &(ctx->VertexProgram.Current->Base); 710 maxParams = ctx->Const.MaxVertexProgramLocalParams; 711 } 712 else if (target == GL_FRAGMENT_PROGRAM_ARB 713 && ctx->Extensions.ARB_fragment_program) { 714 prog = &(ctx->FragmentProgram.Current->Base); 715 maxParams = ctx->Const.MaxFragmentProgramLocalParams; 716 } 717 else if (target == GL_FRAGMENT_PROGRAM_NV 718 && ctx->Extensions.NV_fragment_program) { 719 prog = &(ctx->FragmentProgram.Current->Base); 720 maxParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS; 721 } 722 else { 723 _mesa_error(ctx, GL_INVALID_ENUM, 724 "glGetProgramLocalParameterARB(target)"); 725 return; 726 } 727 728 if (index >= maxParams) { 729 _mesa_error(ctx, GL_INVALID_VALUE, 730 "glGetProgramLocalParameterARB(index)"); 731 return; 732 } 733 734 ASSERT(prog); 735 ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS); 736 COPY_4V(params, prog->LocalParams[index]); 737} 738 739 740/** 741 * Note, this function is also used by the GL_NV_fragment_program extension. 742 */ 743void 744_mesa_GetProgramLocalParameterdvARB(GLenum target, GLuint index, 745 GLdouble *params) 746{ 747 GET_CURRENT_CONTEXT(ctx); 748 GLfloat floatParams[4]; 749 _mesa_GetProgramLocalParameterfvARB(target, index, floatParams); 750 if (ctx->ErrorValue == GL_NO_ERROR) { 751 COPY_4V(params, floatParams); 752 } 753} 754 755 756void 757_mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params) 758{ 759 struct program *prog; 760 GET_CURRENT_CONTEXT(ctx); 761 ASSERT_OUTSIDE_BEGIN_END(ctx); 762 763 if (target == GL_VERTEX_PROGRAM_ARB 764 && ctx->Extensions.ARB_vertex_program) { 765 prog = &(ctx->VertexProgram.Current->Base); 766 } 767 else if (target == GL_FRAGMENT_PROGRAM_ARB 768 && ctx->Extensions.ARB_vertex_program) { 769 prog = &(ctx->FragmentProgram.Current->Base); 770 } 771 else { 772 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)"); 773 return; 774 } 775 776 ASSERT(prog); 777 778 switch (pname) { 779 case GL_PROGRAM_LENGTH_ARB: 780 *params = prog->String ? _mesa_strlen((char *) prog->String) : 0; 781 break; 782 case GL_PROGRAM_FORMAT_ARB: 783 *params = prog->Format; 784 break; 785 case GL_PROGRAM_BINDING_ARB: 786 *params = prog->Id; 787 break; 788 case GL_PROGRAM_INSTRUCTIONS_ARB: 789 *params = prog->NumInstructions; 790 break; 791 case GL_MAX_PROGRAM_INSTRUCTIONS_ARB: 792 if (target == GL_VERTEX_PROGRAM_ARB) 793 *params = ctx->Const.MaxVertexProgramInstructions; 794 else 795 *params = ctx->Const.MaxFragmentProgramInstructions; 796 break; 797 case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB: 798 *params = prog->NumInstructions; 799 break; 800 case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB: 801 if (target == GL_VERTEX_PROGRAM_ARB) 802 *params = ctx->Const.MaxVertexProgramInstructions; 803 else 804 *params = ctx->Const.MaxFragmentProgramInstructions; 805 break; 806 case GL_PROGRAM_TEMPORARIES_ARB: 807 *params = prog->NumTemporaries; 808 break; 809 case GL_MAX_PROGRAM_TEMPORARIES_ARB: 810 if (target == GL_VERTEX_PROGRAM_ARB) 811 *params = ctx->Const.MaxVertexProgramTemps; 812 else 813 *params = ctx->Const.MaxFragmentProgramTemps; 814 break; 815 case GL_PROGRAM_NATIVE_TEMPORARIES_ARB: 816 /* XXX same as GL_PROGRAM_TEMPORARIES_ARB? */ 817 *params = prog->NumTemporaries; 818 break; 819 case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB: 820 /* XXX same as GL_MAX_PROGRAM_TEMPORARIES_ARB? */ 821 if (target == GL_VERTEX_PROGRAM_ARB) 822 *params = ctx->Const.MaxVertexProgramTemps; 823 else 824 *params = ctx->Const.MaxFragmentProgramTemps; 825 break; 826 case GL_PROGRAM_PARAMETERS_ARB: 827 *params = prog->NumParameters; 828 break; 829 case GL_MAX_PROGRAM_PARAMETERS_ARB: 830 if (target == GL_VERTEX_PROGRAM_ARB) 831 *params = ctx->Const.MaxVertexProgramLocalParams; 832 else 833 *params = ctx->Const.MaxFragmentProgramLocalParams; 834 break; 835 case GL_PROGRAM_NATIVE_PARAMETERS_ARB: 836 /* XXX same as GL_MAX_PROGRAM_PARAMETERS_ARB? */ 837 *params = prog->NumParameters; 838 break; 839 case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB: 840 /* XXX same as GL_MAX_PROGRAM_PARAMETERS_ARB? */ 841 if (target == GL_VERTEX_PROGRAM_ARB) 842 *params = ctx->Const.MaxVertexProgramLocalParams; 843 else 844 *params = ctx->Const.MaxFragmentProgramLocalParams; 845 break; 846 case GL_PROGRAM_ATTRIBS_ARB: 847 *params = prog->NumAttributes; 848 break; 849 case GL_MAX_PROGRAM_ATTRIBS_ARB: 850 if (target == GL_VERTEX_PROGRAM_ARB) 851 *params = ctx->Const.MaxVertexProgramAttribs; 852 else 853 *params = ctx->Const.MaxFragmentProgramAttribs; 854 break; 855 case GL_PROGRAM_NATIVE_ATTRIBS_ARB: 856 /* XXX same as GL_PROGRAM_ATTRIBS_ARB? */ 857 *params = prog->NumAttributes; 858 break; 859 case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB: 860 /* XXX same as GL_MAX_PROGRAM_ATTRIBS_ARB? */ 861 if (target == GL_VERTEX_PROGRAM_ARB) 862 *params = ctx->Const.MaxVertexProgramAttribs; 863 else 864 *params = ctx->Const.MaxFragmentProgramAttribs; 865 break; 866 case GL_PROGRAM_ADDRESS_REGISTERS_ARB: 867 *params = prog->NumAddressRegs; 868 break; 869 case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB: 870 if (target == GL_VERTEX_PROGRAM_ARB) 871 *params = ctx->Const.MaxVertexProgramAddressRegs; 872 else 873 *params = ctx->Const.MaxFragmentProgramAddressRegs; 874 break; 875 case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB: 876 /* XXX same as GL_PROGRAM_ADDRESS_REGISTERS_ARB? */ 877 *params = prog->NumAddressRegs; 878 break; 879 case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB: 880 /* XXX same as GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB? */ 881 if (target == GL_VERTEX_PROGRAM_ARB) 882 *params = ctx->Const.MaxVertexProgramAddressRegs; 883 else 884 *params = ctx->Const.MaxFragmentProgramAddressRegs; 885 break; 886 case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB: 887 if (target == GL_VERTEX_PROGRAM_ARB) 888 *params = ctx->Const.MaxVertexProgramLocalParams; 889 else 890 *params = ctx->Const.MaxFragmentProgramLocalParams; 891 break; 892 case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB: 893 if (target == GL_VERTEX_PROGRAM_ARB) 894 *params = ctx->Const.MaxVertexProgramEnvParams; 895 else 896 *params = ctx->Const.MaxFragmentProgramEnvParams; 897 break; 898 case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB: 899 /* XXX ok? */ 900 *params = GL_TRUE; 901 break; 902 903 /* 904 * The following apply to fragment programs only. 905 */ 906 case GL_PROGRAM_ALU_INSTRUCTIONS_ARB: 907 case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB: 908 if (target != GL_FRAGMENT_PROGRAM_ARB) { 909 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)"); 910 return; 911 } 912 *params = ctx->FragmentProgram.Current->NumAluInstructions; 913 break; 914 case GL_PROGRAM_TEX_INSTRUCTIONS_ARB: 915 case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB: 916 if (target != GL_FRAGMENT_PROGRAM_ARB) { 917 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)"); 918 return; 919 } 920 *params = ctx->FragmentProgram.Current->NumTexInstructions; 921 break; 922 case GL_PROGRAM_TEX_INDIRECTIONS_ARB: 923 case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB: 924 if (target != GL_FRAGMENT_PROGRAM_ARB) { 925 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)"); 926 return; 927 } 928 *params = ctx->FragmentProgram.Current->NumTexIndirections; 929 break; 930 case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB: 931 case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB: 932 if (target != GL_FRAGMENT_PROGRAM_ARB) { 933 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)"); 934 return; 935 } 936 *params = ctx->Const.MaxFragmentProgramAluInstructions; 937 break; 938 case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB: 939 case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB: 940 if (target != GL_FRAGMENT_PROGRAM_ARB) { 941 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)"); 942 return; 943 } 944 *params = ctx->Const.MaxFragmentProgramTexInstructions; 945 break; 946 case GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB: 947 case GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB: 948 if (target != GL_FRAGMENT_PROGRAM_ARB) { 949 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)"); 950 return; 951 } 952 *params = ctx->Const.MaxFragmentProgramTexIndirections; 953 break; 954 default: 955 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(pname)"); 956 return; 957 } 958} 959 960 961void 962_mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string) 963{ 964 struct program *prog; 965 GET_CURRENT_CONTEXT(ctx); 966 ASSERT_OUTSIDE_BEGIN_END(ctx); 967 968 if (target == GL_VERTEX_PROGRAM_ARB) { 969 prog = &(ctx->VertexProgram.Current->Base); 970 } 971 else if (target == GL_FRAGMENT_PROGRAM_ARB) { 972 prog = &(ctx->FragmentProgram.Current->Base); 973 } 974 else { 975 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(target)"); 976 return; 977 } 978 979 ASSERT(prog); 980 981 if (pname != GL_PROGRAM_STRING_ARB) { 982 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(pname)"); 983 return; 984 } 985 986 MEMCPY(string, prog->String, _mesa_strlen((char *) prog->String)); 987} 988