1 /* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 2011 VMware, Inc. All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included 14 * in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 20 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 */ 23 24 25 /** 26 * \file samplerobj.c 27 * \brief Functions for the GL_ARB_sampler_objects extension. 28 * \author Brian Paul 29 */ 30 31 32 #include "main/glheader.h" 33 #include "main/context.h" 34 #include "main/dispatch.h" 35 #include "main/enums.h" 36 #include "main/hash.h" 37 #include "main/macros.h" 38 #include "main/mfeatures.h" 39 #include "main/mtypes.h" 40 #include "main/samplerobj.h" 41 42 43 static struct gl_sampler_object * 44 _mesa_lookup_samplerobj(struct gl_context *ctx, GLuint name) 45 { 46 if (name == 0) 47 return NULL; 48 else 49 return (struct gl_sampler_object *) 50 _mesa_HashLookup(ctx->Shared->SamplerObjects, name); 51 } 52 53 54 /** 55 * Handle reference counting. 56 */ 57 void 58 _mesa_reference_sampler_object_(struct gl_context *ctx, 59 struct gl_sampler_object **ptr, 60 struct gl_sampler_object *samp) 61 { 62 assert(*ptr != samp); /* The inline wrapper should prevent no-op calls */ 63 64 if (*ptr) { 65 /* Unreference the old sampler */ 66 GLboolean deleteFlag = GL_FALSE; 67 struct gl_sampler_object *oldSamp = *ptr; 68 69 /*_glthread_LOCK_MUTEX(oldSamp->Mutex);*/ 70 ASSERT(oldSamp->RefCount > 0); 71 oldSamp->RefCount--; 72 #if 0 73 printf("SamplerObj %p %d DECR to %d\n", 74 (void *) oldSamp, oldSamp->Name, oldSamp->RefCount); 75 #endif 76 deleteFlag = (oldSamp->RefCount == 0); 77 /*_glthread_UNLOCK_MUTEX(oldSamp->Mutex);*/ 78 79 if (deleteFlag) { 80 ASSERT(ctx->Driver.DeleteSamplerObject); 81 ctx->Driver.DeleteSamplerObject(ctx, oldSamp); 82 } 83 84 *ptr = NULL; 85 } 86 ASSERT(!*ptr); 87 88 if (samp) { 89 /* reference new sampler */ 90 /*_glthread_LOCK_MUTEX(samp->Mutex);*/ 91 if (samp->RefCount == 0) { 92 /* this sampler's being deleted (look just above) */ 93 /* Not sure this can every really happen. Warn if it does. */ 94 _mesa_problem(NULL, "referencing deleted sampler object"); 95 *ptr = NULL; 96 } 97 else { 98 samp->RefCount++; 99 #if 0 100 printf("SamplerObj %p %d INCR to %d\n", 101 (void *) samp, samp->Name, samp->RefCount); 102 #endif 103 *ptr = samp; 104 } 105 /*_glthread_UNLOCK_MUTEX(samp->Mutex);*/ 106 } 107 } 108 109 110 /** 111 * Initialize the fields of the given sampler object. 112 */ 113 void 114 _mesa_init_sampler_object(struct gl_sampler_object *sampObj, GLuint name) 115 { 116 sampObj->Name = name; 117 sampObj->RefCount = 1; 118 sampObj->WrapS = GL_REPEAT; 119 sampObj->WrapT = GL_REPEAT; 120 sampObj->WrapR = GL_REPEAT; 121 sampObj->MinFilter = GL_NEAREST_MIPMAP_LINEAR; 122 sampObj->MagFilter = GL_LINEAR; 123 sampObj->BorderColor.f[0] = 0.0; 124 sampObj->BorderColor.f[1] = 0.0; 125 sampObj->BorderColor.f[2] = 0.0; 126 sampObj->BorderColor.f[3] = 0.0; 127 sampObj->MinLod = -1000.0F; 128 sampObj->MaxLod = 1000.0F; 129 sampObj->LodBias = 0.0F; 130 sampObj->MaxAnisotropy = 1.0F; 131 sampObj->CompareMode = GL_NONE; 132 sampObj->CompareFunc = GL_LEQUAL; 133 sampObj->sRGBDecode = GL_DECODE_EXT; 134 sampObj->CubeMapSeamless = GL_FALSE; 135 } 136 137 /** 138 * Fallback for ctx->Driver.NewSamplerObject(); 139 */ 140 struct gl_sampler_object * 141 _mesa_new_sampler_object(struct gl_context *ctx, GLuint name) 142 { 143 struct gl_sampler_object *sampObj = CALLOC_STRUCT(gl_sampler_object); 144 if (sampObj) { 145 _mesa_init_sampler_object(sampObj, name); 146 } 147 return sampObj; 148 } 149 150 151 /** 152 * Fallback for ctx->Driver.DeleteSamplerObject(); 153 */ 154 void 155 _mesa_delete_sampler_object(struct gl_context *ctx, 156 struct gl_sampler_object *sampObj) 157 { 158 FREE(sampObj); 159 } 160 161 162 void GLAPIENTRY 163 _mesa_GenSamplers(GLsizei count, GLuint *samplers) 164 { 165 GET_CURRENT_CONTEXT(ctx); 166 GLuint first; 167 GLint i; 168 169 ASSERT_OUTSIDE_BEGIN_END(ctx); 170 171 if (MESA_VERBOSE & VERBOSE_API) 172 _mesa_debug(ctx, "glGenSamplers(%d)\n", count); 173 174 if (count < 0) { 175 _mesa_error(ctx, GL_INVALID_VALUE, "glGenSamplers"); 176 return; 177 } 178 179 if (!samplers) 180 return; 181 182 first = _mesa_HashFindFreeKeyBlock(ctx->Shared->SamplerObjects, count); 183 184 /* Insert the ID and pointer to new sampler object into hash table */ 185 for (i = 0; i < count; i++) { 186 struct gl_sampler_object *sampObj = 187 ctx->Driver.NewSamplerObject(ctx, first + i); 188 _mesa_HashInsert(ctx->Shared->SamplerObjects, first + i, sampObj); 189 samplers[i] = first + i; 190 } 191 } 192 193 194 void GLAPIENTRY 195 _mesa_DeleteSamplers(GLsizei count, const GLuint *samplers) 196 { 197 GET_CURRENT_CONTEXT(ctx); 198 GLsizei i; 199 200 ASSERT_OUTSIDE_BEGIN_END(ctx); 201 FLUSH_VERTICES(ctx, 0); 202 203 if (count < 0) { 204 _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteSamplers(count)"); 205 return; 206 } 207 208 _glthread_LOCK_MUTEX(ctx->Shared->Mutex); 209 210 for (i = 0; i < count; i++) { 211 if (samplers[i]) { 212 struct gl_sampler_object *sampObj = 213 _mesa_lookup_samplerobj(ctx, samplers[i]); 214 if (sampObj) { 215 /* The ID is immediately freed for re-use */ 216 _mesa_HashRemove(ctx->Shared->SamplerObjects, samplers[i]); 217 /* But the object exists until its reference count goes to zero */ 218 _mesa_reference_sampler_object(ctx, &sampObj, NULL); 219 } 220 } 221 } 222 223 _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); 224 } 225 226 227 static GLboolean GLAPIENTRY 228 _mesa_IsSampler(GLuint sampler) 229 { 230 struct gl_sampler_object *sampObj; 231 GET_CURRENT_CONTEXT(ctx); 232 233 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); 234 235 if (sampler == 0) 236 return GL_FALSE; 237 238 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 239 240 return sampObj != NULL; 241 } 242 243 244 void GLAPIENTRY 245 _mesa_BindSampler(GLuint unit, GLuint sampler) 246 { 247 struct gl_sampler_object *sampObj; 248 GET_CURRENT_CONTEXT(ctx); 249 250 if (unit >= ctx->Const.MaxCombinedTextureImageUnits) { 251 _mesa_error(ctx, GL_INVALID_VALUE, "glBindSampler(unit %u)", unit); 252 return; 253 } 254 255 if (sampler == 0) { 256 /* Use the default sampler object, the one contained in the texture 257 * object. 258 */ 259 sampObj = NULL; 260 } 261 else { 262 /* user-defined sampler object */ 263 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 264 if (!sampObj) { 265 _mesa_error(ctx, GL_INVALID_OPERATION, "glBindSampler(sampler)"); 266 return; 267 } 268 } 269 270 if (ctx->Texture.Unit[unit].Sampler != sampObj) { 271 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 272 } 273 274 /* bind new sampler */ 275 _mesa_reference_sampler_object(ctx, &ctx->Texture.Unit[unit].Sampler, 276 sampObj); 277 } 278 279 280 /** 281 * Check if a coordinate wrap mode is legal. 282 * \return GL_TRUE if legal, GL_FALSE otherwise 283 */ 284 static GLboolean 285 validate_texture_wrap_mode(struct gl_context *ctx, GLenum wrap) 286 { 287 const struct gl_extensions * const e = &ctx->Extensions; 288 289 switch (wrap) { 290 case GL_CLAMP: 291 case GL_CLAMP_TO_EDGE: 292 case GL_REPEAT: 293 case GL_MIRRORED_REPEAT: 294 return GL_TRUE; 295 case GL_CLAMP_TO_BORDER: 296 return e->ARB_texture_border_clamp; 297 case GL_MIRROR_CLAMP_EXT: 298 return e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp; 299 case GL_MIRROR_CLAMP_TO_EDGE_EXT: 300 return e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp; 301 case GL_MIRROR_CLAMP_TO_BORDER_EXT: 302 return e->EXT_texture_mirror_clamp; 303 default: 304 return GL_FALSE; 305 } 306 } 307 308 309 /** 310 * This is called just prior to changing any sampler object state. 311 */ 312 static inline void 313 flush(struct gl_context *ctx) 314 { 315 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 316 } 317 318 319 #define INVALID_PARAM 0x100 320 #define INVALID_PNAME 0x101 321 #define INVALID_VALUE 0x102 322 323 static GLuint 324 set_sampler_wrap_s(struct gl_context *ctx, struct gl_sampler_object *samp, 325 GLint param) 326 { 327 if (samp->WrapS == param) 328 return GL_FALSE; 329 if (validate_texture_wrap_mode(ctx, param)) { 330 flush(ctx); 331 samp->WrapS = param; 332 return GL_TRUE; 333 } 334 return INVALID_PARAM; 335 } 336 337 338 static GLuint 339 set_sampler_wrap_t(struct gl_context *ctx, struct gl_sampler_object *samp, 340 GLint param) 341 { 342 if (samp->WrapT == param) 343 return GL_FALSE; 344 if (validate_texture_wrap_mode(ctx, param)) { 345 flush(ctx); 346 samp->WrapT = param; 347 return GL_TRUE; 348 } 349 return INVALID_PARAM; 350 } 351 352 353 static GLuint 354 set_sampler_wrap_r(struct gl_context *ctx, struct gl_sampler_object *samp, 355 GLint param) 356 { 357 if (samp->WrapR == param) 358 return GL_FALSE; 359 if (validate_texture_wrap_mode(ctx, param)) { 360 flush(ctx); 361 samp->WrapR = param; 362 return GL_TRUE; 363 } 364 return INVALID_PARAM; 365 } 366 367 368 static GLuint 369 set_sampler_min_filter(struct gl_context *ctx, struct gl_sampler_object *samp, 370 GLint param) 371 { 372 if (samp->MinFilter == param) 373 return GL_FALSE; 374 375 switch (param) { 376 case GL_NEAREST: 377 case GL_LINEAR: 378 case GL_NEAREST_MIPMAP_NEAREST: 379 case GL_LINEAR_MIPMAP_NEAREST: 380 case GL_NEAREST_MIPMAP_LINEAR: 381 case GL_LINEAR_MIPMAP_LINEAR: 382 flush(ctx); 383 samp->MinFilter = param; 384 return GL_TRUE; 385 default: 386 return INVALID_PARAM; 387 } 388 } 389 390 391 static GLuint 392 set_sampler_mag_filter(struct gl_context *ctx, struct gl_sampler_object *samp, 393 GLint param) 394 { 395 if (samp->MagFilter == param) 396 return GL_FALSE; 397 398 switch (param) { 399 case GL_NEAREST: 400 case GL_LINEAR: 401 flush(ctx); 402 samp->MagFilter = param; 403 return GL_TRUE; 404 default: 405 return INVALID_PARAM; 406 } 407 } 408 409 410 static GLuint 411 set_sampler_lod_bias(struct gl_context *ctx, struct gl_sampler_object *samp, 412 GLfloat param) 413 { 414 if (samp->LodBias == param) 415 return GL_FALSE; 416 417 flush(ctx); 418 samp->LodBias = param; 419 return GL_TRUE; 420 } 421 422 423 static GLuint 424 set_sampler_border_colorf(struct gl_context *ctx, 425 struct gl_sampler_object *samp, 426 const GLfloat params[4]) 427 { 428 flush(ctx); 429 samp->BorderColor.f[RCOMP] = params[0]; 430 samp->BorderColor.f[GCOMP] = params[1]; 431 samp->BorderColor.f[BCOMP] = params[2]; 432 samp->BorderColor.f[ACOMP] = params[3]; 433 return GL_TRUE; 434 } 435 436 437 static GLuint 438 set_sampler_border_colori(struct gl_context *ctx, 439 struct gl_sampler_object *samp, 440 const GLint params[4]) 441 { 442 flush(ctx); 443 samp->BorderColor.i[RCOMP] = params[0]; 444 samp->BorderColor.i[GCOMP] = params[1]; 445 samp->BorderColor.i[BCOMP] = params[2]; 446 samp->BorderColor.i[ACOMP] = params[3]; 447 return GL_TRUE; 448 } 449 450 451 static GLuint 452 set_sampler_border_colorui(struct gl_context *ctx, 453 struct gl_sampler_object *samp, 454 const GLuint params[4]) 455 { 456 flush(ctx); 457 samp->BorderColor.ui[RCOMP] = params[0]; 458 samp->BorderColor.ui[GCOMP] = params[1]; 459 samp->BorderColor.ui[BCOMP] = params[2]; 460 samp->BorderColor.ui[ACOMP] = params[3]; 461 return GL_TRUE; 462 } 463 464 465 static GLuint 466 set_sampler_min_lod(struct gl_context *ctx, struct gl_sampler_object *samp, 467 GLfloat param) 468 { 469 if (samp->MinLod == param) 470 return GL_FALSE; 471 472 flush(ctx); 473 samp->MinLod = param; 474 return GL_TRUE; 475 } 476 477 478 static GLuint 479 set_sampler_max_lod(struct gl_context *ctx, struct gl_sampler_object *samp, 480 GLfloat param) 481 { 482 if (samp->MaxLod == param) 483 return GL_FALSE; 484 485 flush(ctx); 486 samp->MaxLod = param; 487 return GL_TRUE; 488 } 489 490 491 static GLuint 492 set_sampler_compare_mode(struct gl_context *ctx, 493 struct gl_sampler_object *samp, GLint param) 494 { 495 if (!ctx->Extensions.ARB_shadow) 496 return INVALID_PNAME; 497 498 if (samp->CompareMode == param) 499 return GL_FALSE; 500 501 if (param == GL_NONE || 502 param == GL_COMPARE_R_TO_TEXTURE_ARB) { 503 flush(ctx); 504 samp->CompareMode = param; 505 return GL_TRUE; 506 } 507 508 return INVALID_PARAM; 509 } 510 511 512 static GLuint 513 set_sampler_compare_func(struct gl_context *ctx, 514 struct gl_sampler_object *samp, GLint param) 515 { 516 if (!ctx->Extensions.ARB_shadow) 517 return INVALID_PNAME; 518 519 if (samp->CompareFunc == param) 520 return GL_FALSE; 521 522 switch (param) { 523 case GL_LEQUAL: 524 case GL_GEQUAL: 525 flush(ctx); 526 samp->CompareFunc = param; 527 return GL_TRUE; 528 case GL_EQUAL: 529 case GL_NOTEQUAL: 530 case GL_LESS: 531 case GL_GREATER: 532 case GL_ALWAYS: 533 case GL_NEVER: 534 if (ctx->Extensions.EXT_shadow_funcs) { 535 flush(ctx); 536 samp->CompareFunc = param; 537 return GL_TRUE; 538 } 539 /* fall-through */ 540 default: 541 return INVALID_PARAM; 542 } 543 } 544 545 546 static GLuint 547 set_sampler_max_anisotropy(struct gl_context *ctx, 548 struct gl_sampler_object *samp, GLfloat param) 549 { 550 if (!ctx->Extensions.EXT_texture_filter_anisotropic) 551 return INVALID_PNAME; 552 553 if (samp->MaxAnisotropy == param) 554 return GL_FALSE; 555 556 if (param < 1.0) 557 return INVALID_VALUE; 558 559 flush(ctx); 560 /* clamp to max, that's what NVIDIA does */ 561 samp->MaxAnisotropy = MIN2(param, ctx->Const.MaxTextureMaxAnisotropy); 562 return GL_TRUE; 563 } 564 565 566 static GLuint 567 set_sampler_cube_map_seamless(struct gl_context *ctx, 568 struct gl_sampler_object *samp, GLboolean param) 569 { 570 if (!ctx->Extensions.AMD_seamless_cubemap_per_texture) 571 return INVALID_PNAME; 572 573 if (samp->CubeMapSeamless == param) 574 return GL_FALSE; 575 576 if (param != GL_TRUE && param != GL_FALSE) 577 return INVALID_VALUE; 578 579 flush(ctx); 580 samp->CubeMapSeamless = param; 581 return GL_TRUE; 582 } 583 584 static GLuint 585 set_sampler_srgb_decode(struct gl_context *ctx, 586 struct gl_sampler_object *samp, GLenum param) 587 { 588 if (!ctx->Extensions.EXT_texture_sRGB_decode) 589 return INVALID_PNAME; 590 591 if (samp->sRGBDecode == param) 592 return GL_FALSE; 593 594 if (param != GL_DECODE_EXT && param != GL_SKIP_DECODE_EXT) 595 return INVALID_VALUE; 596 597 flush(ctx); 598 samp->sRGBDecode = param; 599 return GL_TRUE; 600 } 601 602 void GLAPIENTRY 603 _mesa_SamplerParameteri(GLuint sampler, GLenum pname, GLint param) 604 { 605 struct gl_sampler_object *sampObj; 606 GLuint res; 607 GET_CURRENT_CONTEXT(ctx); 608 609 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 610 if (!sampObj) { 611 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameteri(sampler %u)", 612 sampler); 613 return; 614 } 615 616 switch (pname) { 617 case GL_TEXTURE_WRAP_S: 618 res = set_sampler_wrap_s(ctx, sampObj, param); 619 break; 620 case GL_TEXTURE_WRAP_T: 621 res = set_sampler_wrap_t(ctx, sampObj, param); 622 break; 623 case GL_TEXTURE_WRAP_R: 624 res = set_sampler_wrap_r(ctx, sampObj, param); 625 break; 626 case GL_TEXTURE_MIN_FILTER: 627 res = set_sampler_min_filter(ctx, sampObj, param); 628 break; 629 case GL_TEXTURE_MAG_FILTER: 630 res = set_sampler_mag_filter(ctx, sampObj, param); 631 break; 632 case GL_TEXTURE_MIN_LOD: 633 res = set_sampler_min_lod(ctx, sampObj, (GLfloat) param); 634 break; 635 case GL_TEXTURE_MAX_LOD: 636 res = set_sampler_max_lod(ctx, sampObj, (GLfloat) param); 637 break; 638 case GL_TEXTURE_LOD_BIAS: 639 res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) param); 640 break; 641 case GL_TEXTURE_COMPARE_MODE: 642 res = set_sampler_compare_mode(ctx, sampObj, param); 643 break; 644 case GL_TEXTURE_COMPARE_FUNC: 645 res = set_sampler_compare_func(ctx, sampObj, param); 646 break; 647 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 648 res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) param); 649 break; 650 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 651 res = set_sampler_cube_map_seamless(ctx, sampObj, param); 652 break; 653 case GL_TEXTURE_SRGB_DECODE_EXT: 654 res = set_sampler_srgb_decode(ctx, sampObj, param); 655 break; 656 case GL_TEXTURE_BORDER_COLOR: 657 /* fall-through */ 658 default: 659 res = INVALID_PNAME; 660 } 661 662 switch (res) { 663 case GL_FALSE: 664 /* no change */ 665 break; 666 case GL_TRUE: 667 /* state change - we do nothing special at this time */ 668 break; 669 case INVALID_PNAME: 670 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteri(pname=%s)\n", 671 _mesa_lookup_enum_by_nr(pname)); 672 break; 673 case INVALID_PARAM: 674 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteri(param=%d)\n", 675 param); 676 break; 677 case INVALID_VALUE: 678 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameteri(param=%d)\n", 679 param); 680 break; 681 default: 682 ; 683 } 684 } 685 686 687 static void GLAPIENTRY 688 _mesa_SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) 689 { 690 struct gl_sampler_object *sampObj; 691 GLuint res; 692 GET_CURRENT_CONTEXT(ctx); 693 694 ASSERT_OUTSIDE_BEGIN_END(ctx); 695 696 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 697 if (!sampObj) { 698 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterf(sampler %u)", 699 sampler); 700 return; 701 } 702 703 switch (pname) { 704 case GL_TEXTURE_WRAP_S: 705 res = set_sampler_wrap_s(ctx, sampObj, (GLint) param); 706 break; 707 case GL_TEXTURE_WRAP_T: 708 res = set_sampler_wrap_t(ctx, sampObj, (GLint) param); 709 break; 710 case GL_TEXTURE_WRAP_R: 711 res = set_sampler_wrap_r(ctx, sampObj, (GLint) param); 712 break; 713 case GL_TEXTURE_MIN_FILTER: 714 res = set_sampler_min_filter(ctx, sampObj, (GLint) param); 715 break; 716 case GL_TEXTURE_MAG_FILTER: 717 res = set_sampler_mag_filter(ctx, sampObj, (GLint) param); 718 break; 719 case GL_TEXTURE_MIN_LOD: 720 res = set_sampler_min_lod(ctx, sampObj, param); 721 break; 722 case GL_TEXTURE_MAX_LOD: 723 res = set_sampler_max_lod(ctx, sampObj, param); 724 break; 725 case GL_TEXTURE_LOD_BIAS: 726 res = set_sampler_lod_bias(ctx, sampObj, param); 727 break; 728 case GL_TEXTURE_COMPARE_MODE: 729 res = set_sampler_compare_mode(ctx, sampObj, (GLint) param); 730 break; 731 case GL_TEXTURE_COMPARE_FUNC: 732 res = set_sampler_compare_func(ctx, sampObj, (GLint) param); 733 break; 734 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 735 res = set_sampler_max_anisotropy(ctx, sampObj, param); 736 break; 737 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 738 res = set_sampler_cube_map_seamless(ctx, sampObj, (GLboolean) param); 739 break; 740 case GL_TEXTURE_SRGB_DECODE_EXT: 741 res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) param); 742 break; 743 case GL_TEXTURE_BORDER_COLOR: 744 /* fall-through */ 745 default: 746 res = INVALID_PNAME; 747 } 748 749 switch (res) { 750 case GL_FALSE: 751 /* no change */ 752 break; 753 case GL_TRUE: 754 /* state change - we do nothing special at this time */ 755 break; 756 case INVALID_PNAME: 757 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterf(pname=%s)\n", 758 _mesa_lookup_enum_by_nr(pname)); 759 break; 760 case INVALID_PARAM: 761 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterf(param=%f)\n", 762 param); 763 break; 764 case INVALID_VALUE: 765 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterf(param=%f)\n", 766 param); 767 break; 768 default: 769 ; 770 } 771 } 772 773 static void GLAPIENTRY 774 _mesa_SamplerParameteriv(GLuint sampler, GLenum pname, const GLint *params) 775 { 776 struct gl_sampler_object *sampObj; 777 GLuint res; 778 GET_CURRENT_CONTEXT(ctx); 779 780 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 781 if (!sampObj) { 782 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameteriv(sampler %u)", 783 sampler); 784 return; 785 } 786 787 switch (pname) { 788 case GL_TEXTURE_WRAP_S: 789 res = set_sampler_wrap_s(ctx, sampObj, params[0]); 790 break; 791 case GL_TEXTURE_WRAP_T: 792 res = set_sampler_wrap_t(ctx, sampObj, params[0]); 793 break; 794 case GL_TEXTURE_WRAP_R: 795 res = set_sampler_wrap_r(ctx, sampObj, params[0]); 796 break; 797 case GL_TEXTURE_MIN_FILTER: 798 res = set_sampler_min_filter(ctx, sampObj, params[0]); 799 break; 800 case GL_TEXTURE_MAG_FILTER: 801 res = set_sampler_mag_filter(ctx, sampObj, params[0]); 802 break; 803 case GL_TEXTURE_MIN_LOD: 804 res = set_sampler_min_lod(ctx, sampObj, (GLfloat) params[0]); 805 break; 806 case GL_TEXTURE_MAX_LOD: 807 res = set_sampler_max_lod(ctx, sampObj, (GLfloat) params[0]); 808 break; 809 case GL_TEXTURE_LOD_BIAS: 810 res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) params[0]); 811 break; 812 case GL_TEXTURE_COMPARE_MODE: 813 res = set_sampler_compare_mode(ctx, sampObj, params[0]); 814 break; 815 case GL_TEXTURE_COMPARE_FUNC: 816 res = set_sampler_compare_func(ctx, sampObj, params[0]); 817 break; 818 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 819 res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) params[0]); 820 break; 821 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 822 res = set_sampler_cube_map_seamless(ctx, sampObj, params[0]); 823 break; 824 case GL_TEXTURE_SRGB_DECODE_EXT: 825 res = set_sampler_srgb_decode(ctx, sampObj, params[0]); 826 break; 827 case GL_TEXTURE_BORDER_COLOR: 828 { 829 GLfloat c[4]; 830 c[0] = INT_TO_FLOAT(params[0]); 831 c[1] = INT_TO_FLOAT(params[1]); 832 c[2] = INT_TO_FLOAT(params[2]); 833 c[3] = INT_TO_FLOAT(params[3]); 834 res = set_sampler_border_colorf(ctx, sampObj, c); 835 } 836 break; 837 default: 838 res = INVALID_PNAME; 839 } 840 841 switch (res) { 842 case GL_FALSE: 843 /* no change */ 844 break; 845 case GL_TRUE: 846 /* state change - we do nothing special at this time */ 847 break; 848 case INVALID_PNAME: 849 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteriv(pname=%s)\n", 850 _mesa_lookup_enum_by_nr(pname)); 851 break; 852 case INVALID_PARAM: 853 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteriv(param=%d)\n", 854 params[0]); 855 break; 856 case INVALID_VALUE: 857 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameteriv(param=%d)\n", 858 params[0]); 859 break; 860 default: 861 ; 862 } 863 } 864 865 static void GLAPIENTRY 866 _mesa_SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *params) 867 { 868 struct gl_sampler_object *sampObj; 869 GLuint res; 870 GET_CURRENT_CONTEXT(ctx); 871 872 ASSERT_OUTSIDE_BEGIN_END(ctx); 873 874 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 875 if (!sampObj) { 876 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterfv(sampler %u)", 877 sampler); 878 return; 879 } 880 881 switch (pname) { 882 case GL_TEXTURE_WRAP_S: 883 res = set_sampler_wrap_s(ctx, sampObj, (GLint) params[0]); 884 break; 885 case GL_TEXTURE_WRAP_T: 886 res = set_sampler_wrap_t(ctx, sampObj, (GLint) params[0]); 887 break; 888 case GL_TEXTURE_WRAP_R: 889 res = set_sampler_wrap_r(ctx, sampObj, (GLint) params[0]); 890 break; 891 case GL_TEXTURE_MIN_FILTER: 892 res = set_sampler_min_filter(ctx, sampObj, (GLint) params[0]); 893 break; 894 case GL_TEXTURE_MAG_FILTER: 895 res = set_sampler_mag_filter(ctx, sampObj, (GLint) params[0]); 896 break; 897 case GL_TEXTURE_MIN_LOD: 898 res = set_sampler_min_lod(ctx, sampObj, params[0]); 899 break; 900 case GL_TEXTURE_MAX_LOD: 901 res = set_sampler_max_lod(ctx, sampObj, params[0]); 902 break; 903 case GL_TEXTURE_LOD_BIAS: 904 res = set_sampler_lod_bias(ctx, sampObj, params[0]); 905 break; 906 case GL_TEXTURE_COMPARE_MODE: 907 res = set_sampler_compare_mode(ctx, sampObj, (GLint) params[0]); 908 break; 909 case GL_TEXTURE_COMPARE_FUNC: 910 res = set_sampler_compare_func(ctx, sampObj, (GLint) params[0]); 911 break; 912 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 913 res = set_sampler_max_anisotropy(ctx, sampObj, params[0]); 914 break; 915 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 916 res = set_sampler_cube_map_seamless(ctx, sampObj, (GLboolean) params[0]); 917 break; 918 case GL_TEXTURE_SRGB_DECODE_EXT: 919 res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) params[0]); 920 break; 921 case GL_TEXTURE_BORDER_COLOR: 922 res = set_sampler_border_colorf(ctx, sampObj, params); 923 break; 924 default: 925 res = INVALID_PNAME; 926 } 927 928 switch (res) { 929 case GL_FALSE: 930 /* no change */ 931 break; 932 case GL_TRUE: 933 /* state change - we do nothing special at this time */ 934 break; 935 case INVALID_PNAME: 936 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterfv(pname=%s)\n", 937 _mesa_lookup_enum_by_nr(pname)); 938 break; 939 case INVALID_PARAM: 940 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterfv(param=%f)\n", 941 params[0]); 942 break; 943 case INVALID_VALUE: 944 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterfv(param=%f)\n", 945 params[0]); 946 break; 947 default: 948 ; 949 } 950 } 951 952 static void GLAPIENTRY 953 _mesa_SamplerParameterIiv(GLuint sampler, GLenum pname, const GLint *params) 954 { 955 struct gl_sampler_object *sampObj; 956 GLuint res; 957 GET_CURRENT_CONTEXT(ctx); 958 959 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 960 if (!sampObj) { 961 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIiv(sampler %u)", 962 sampler); 963 return; 964 } 965 966 switch (pname) { 967 case GL_TEXTURE_WRAP_S: 968 res = set_sampler_wrap_s(ctx, sampObj, params[0]); 969 break; 970 case GL_TEXTURE_WRAP_T: 971 res = set_sampler_wrap_t(ctx, sampObj, params[0]); 972 break; 973 case GL_TEXTURE_WRAP_R: 974 res = set_sampler_wrap_r(ctx, sampObj, params[0]); 975 break; 976 case GL_TEXTURE_MIN_FILTER: 977 res = set_sampler_min_filter(ctx, sampObj, params[0]); 978 break; 979 case GL_TEXTURE_MAG_FILTER: 980 res = set_sampler_mag_filter(ctx, sampObj, params[0]); 981 break; 982 case GL_TEXTURE_MIN_LOD: 983 res = set_sampler_min_lod(ctx, sampObj, (GLfloat) params[0]); 984 break; 985 case GL_TEXTURE_MAX_LOD: 986 res = set_sampler_max_lod(ctx, sampObj, (GLfloat) params[0]); 987 break; 988 case GL_TEXTURE_LOD_BIAS: 989 res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) params[0]); 990 break; 991 case GL_TEXTURE_COMPARE_MODE: 992 res = set_sampler_compare_mode(ctx, sampObj, params[0]); 993 break; 994 case GL_TEXTURE_COMPARE_FUNC: 995 res = set_sampler_compare_func(ctx, sampObj, params[0]); 996 break; 997 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 998 res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) params[0]); 999 break; 1000 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1001 res = set_sampler_cube_map_seamless(ctx, sampObj, params[0]); 1002 break; 1003 case GL_TEXTURE_SRGB_DECODE_EXT: 1004 res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) params[0]); 1005 break; 1006 case GL_TEXTURE_BORDER_COLOR: 1007 res = set_sampler_border_colori(ctx, sampObj, params); 1008 break; 1009 default: 1010 res = INVALID_PNAME; 1011 } 1012 1013 switch (res) { 1014 case GL_FALSE: 1015 /* no change */ 1016 break; 1017 case GL_TRUE: 1018 /* state change - we do nothing special at this time */ 1019 break; 1020 case INVALID_PNAME: 1021 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIiv(pname=%s)\n", 1022 _mesa_lookup_enum_by_nr(pname)); 1023 break; 1024 case INVALID_PARAM: 1025 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIiv(param=%d)\n", 1026 params[0]); 1027 break; 1028 case INVALID_VALUE: 1029 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIiv(param=%d)\n", 1030 params[0]); 1031 break; 1032 default: 1033 ; 1034 } 1035 } 1036 1037 1038 static void GLAPIENTRY 1039 _mesa_SamplerParameterIuiv(GLuint sampler, GLenum pname, const GLuint *params) 1040 { 1041 struct gl_sampler_object *sampObj; 1042 GLuint res; 1043 GET_CURRENT_CONTEXT(ctx); 1044 1045 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 1046 if (!sampObj) { 1047 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIuiv(sampler %u)", 1048 sampler); 1049 return; 1050 } 1051 1052 switch (pname) { 1053 case GL_TEXTURE_WRAP_S: 1054 res = set_sampler_wrap_s(ctx, sampObj, params[0]); 1055 break; 1056 case GL_TEXTURE_WRAP_T: 1057 res = set_sampler_wrap_t(ctx, sampObj, params[0]); 1058 break; 1059 case GL_TEXTURE_WRAP_R: 1060 res = set_sampler_wrap_r(ctx, sampObj, params[0]); 1061 break; 1062 case GL_TEXTURE_MIN_FILTER: 1063 res = set_sampler_min_filter(ctx, sampObj, params[0]); 1064 break; 1065 case GL_TEXTURE_MAG_FILTER: 1066 res = set_sampler_mag_filter(ctx, sampObj, params[0]); 1067 break; 1068 case GL_TEXTURE_MIN_LOD: 1069 res = set_sampler_min_lod(ctx, sampObj, (GLfloat) params[0]); 1070 break; 1071 case GL_TEXTURE_MAX_LOD: 1072 res = set_sampler_max_lod(ctx, sampObj, (GLfloat) params[0]); 1073 break; 1074 case GL_TEXTURE_LOD_BIAS: 1075 res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) params[0]); 1076 break; 1077 case GL_TEXTURE_COMPARE_MODE: 1078 res = set_sampler_compare_mode(ctx, sampObj, params[0]); 1079 break; 1080 case GL_TEXTURE_COMPARE_FUNC: 1081 res = set_sampler_compare_func(ctx, sampObj, params[0]); 1082 break; 1083 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1084 res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) params[0]); 1085 break; 1086 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1087 res = set_sampler_cube_map_seamless(ctx, sampObj, params[0]); 1088 break; 1089 case GL_TEXTURE_SRGB_DECODE_EXT: 1090 res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) params[0]); 1091 break; 1092 case GL_TEXTURE_BORDER_COLOR: 1093 res = set_sampler_border_colorui(ctx, sampObj, params); 1094 break; 1095 default: 1096 res = INVALID_PNAME; 1097 } 1098 1099 switch (res) { 1100 case GL_FALSE: 1101 /* no change */ 1102 break; 1103 case GL_TRUE: 1104 /* state change - we do nothing special at this time */ 1105 break; 1106 case INVALID_PNAME: 1107 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIuiv(pname=%s)\n", 1108 _mesa_lookup_enum_by_nr(pname)); 1109 break; 1110 case INVALID_PARAM: 1111 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIuiv(param=%u)\n", 1112 params[0]); 1113 break; 1114 case INVALID_VALUE: 1115 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIuiv(param=%u)\n", 1116 params[0]); 1117 break; 1118 default: 1119 ; 1120 } 1121 } 1122 1123 1124 static void GLAPIENTRY 1125 _mesa_GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params) 1126 { 1127 struct gl_sampler_object *sampObj; 1128 GET_CURRENT_CONTEXT(ctx); 1129 1130 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 1131 if (!sampObj) { 1132 _mesa_error(ctx, GL_INVALID_VALUE, "glGetSamplerParameteriv(sampler %u)", 1133 sampler); 1134 return; 1135 } 1136 1137 switch (pname) { 1138 case GL_TEXTURE_WRAP_S: 1139 *params = sampObj->WrapS; 1140 break; 1141 case GL_TEXTURE_WRAP_T: 1142 *params = sampObj->WrapT; 1143 break; 1144 case GL_TEXTURE_WRAP_R: 1145 *params = sampObj->WrapR; 1146 break; 1147 case GL_TEXTURE_MIN_FILTER: 1148 *params = sampObj->MinFilter; 1149 break; 1150 case GL_TEXTURE_MAG_FILTER: 1151 *params = sampObj->MagFilter; 1152 break; 1153 case GL_TEXTURE_MIN_LOD: 1154 *params = (GLint) sampObj->MinLod; 1155 break; 1156 case GL_TEXTURE_MAX_LOD: 1157 *params = (GLint) sampObj->MaxLod; 1158 break; 1159 case GL_TEXTURE_LOD_BIAS: 1160 *params = (GLint) sampObj->LodBias; 1161 break; 1162 case GL_TEXTURE_COMPARE_MODE: 1163 if (!ctx->Extensions.ARB_shadow) 1164 goto invalid_pname; 1165 *params = sampObj->CompareMode; 1166 break; 1167 case GL_TEXTURE_COMPARE_FUNC: 1168 if (!ctx->Extensions.ARB_shadow) 1169 goto invalid_pname; 1170 *params = sampObj->CompareFunc; 1171 break; 1172 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1173 *params = (GLint) sampObj->MaxAnisotropy; 1174 break; 1175 case GL_TEXTURE_BORDER_COLOR: 1176 params[0] = FLOAT_TO_INT(sampObj->BorderColor.f[0]); 1177 params[1] = FLOAT_TO_INT(sampObj->BorderColor.f[1]); 1178 params[2] = FLOAT_TO_INT(sampObj->BorderColor.f[2]); 1179 params[3] = FLOAT_TO_INT(sampObj->BorderColor.f[3]); 1180 break; 1181 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1182 if (!ctx->Extensions.AMD_seamless_cubemap_per_texture) 1183 goto invalid_pname; 1184 *params = sampObj->CubeMapSeamless; 1185 break; 1186 case GL_TEXTURE_SRGB_DECODE_EXT: 1187 if (!ctx->Extensions.EXT_texture_sRGB_decode) 1188 goto invalid_pname; 1189 *params = (GLenum) sampObj->sRGBDecode; 1190 break; 1191 default: 1192 goto invalid_pname; 1193 } 1194 return; 1195 1196 invalid_pname: 1197 _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameteriv(pname=%s)", 1198 _mesa_lookup_enum_by_nr(pname)); 1199 } 1200 1201 1202 static void GLAPIENTRY 1203 _mesa_GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params) 1204 { 1205 struct gl_sampler_object *sampObj; 1206 GET_CURRENT_CONTEXT(ctx); 1207 1208 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 1209 if (!sampObj) { 1210 _mesa_error(ctx, GL_INVALID_VALUE, "glGetSamplerParameterfv(sampler %u)", 1211 sampler); 1212 return; 1213 } 1214 1215 switch (pname) { 1216 case GL_TEXTURE_WRAP_S: 1217 *params = (GLfloat) sampObj->WrapS; 1218 break; 1219 case GL_TEXTURE_WRAP_T: 1220 *params = (GLfloat) sampObj->WrapT; 1221 break; 1222 case GL_TEXTURE_WRAP_R: 1223 *params = (GLfloat) sampObj->WrapR; 1224 break; 1225 case GL_TEXTURE_MIN_FILTER: 1226 *params = (GLfloat) sampObj->MinFilter; 1227 break; 1228 case GL_TEXTURE_MAG_FILTER: 1229 *params = (GLfloat) sampObj->MagFilter; 1230 break; 1231 case GL_TEXTURE_MIN_LOD: 1232 *params = sampObj->MinLod; 1233 break; 1234 case GL_TEXTURE_MAX_LOD: 1235 *params = sampObj->MaxLod; 1236 break; 1237 case GL_TEXTURE_LOD_BIAS: 1238 *params = sampObj->LodBias; 1239 break; 1240 case GL_TEXTURE_COMPARE_MODE: 1241 if (!ctx->Extensions.ARB_shadow) 1242 goto invalid_pname; 1243 *params = (GLfloat) sampObj->CompareMode; 1244 break; 1245 case GL_TEXTURE_COMPARE_FUNC: 1246 if (!ctx->Extensions.ARB_shadow) 1247 goto invalid_pname; 1248 *params = (GLfloat) sampObj->CompareFunc; 1249 break; 1250 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1251 *params = sampObj->MaxAnisotropy; 1252 break; 1253 case GL_TEXTURE_BORDER_COLOR: 1254 params[0] = sampObj->BorderColor.f[0]; 1255 params[1] = sampObj->BorderColor.f[1]; 1256 params[2] = sampObj->BorderColor.f[2]; 1257 params[3] = sampObj->BorderColor.f[3]; 1258 break; 1259 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1260 if (!ctx->Extensions.AMD_seamless_cubemap_per_texture) 1261 goto invalid_pname; 1262 *params = (GLfloat) sampObj->CubeMapSeamless; 1263 break; 1264 case GL_TEXTURE_SRGB_DECODE_EXT: 1265 if (!ctx->Extensions.EXT_texture_sRGB_decode) 1266 goto invalid_pname; 1267 *params = (GLfloat) sampObj->sRGBDecode; 1268 break; 1269 default: 1270 goto invalid_pname; 1271 } 1272 return; 1273 1274 invalid_pname: 1275 _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameterfv(pname=%s)", 1276 _mesa_lookup_enum_by_nr(pname)); 1277 } 1278 1279 1280 static void GLAPIENTRY 1281 _mesa_GetSamplerParameterIiv(GLuint sampler, GLenum pname, GLint *params) 1282 { 1283 struct gl_sampler_object *sampObj; 1284 GET_CURRENT_CONTEXT(ctx); 1285 1286 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 1287 if (!sampObj) { 1288 _mesa_error(ctx, GL_INVALID_VALUE, 1289 "glGetSamplerParameterIiv(sampler %u)", 1290 sampler); 1291 return; 1292 } 1293 1294 switch (pname) { 1295 case GL_TEXTURE_WRAP_S: 1296 *params = sampObj->WrapS; 1297 break; 1298 case GL_TEXTURE_WRAP_T: 1299 *params = sampObj->WrapT; 1300 break; 1301 case GL_TEXTURE_WRAP_R: 1302 *params = sampObj->WrapR; 1303 break; 1304 case GL_TEXTURE_MIN_FILTER: 1305 *params = sampObj->MinFilter; 1306 break; 1307 case GL_TEXTURE_MAG_FILTER: 1308 *params = sampObj->MagFilter; 1309 break; 1310 case GL_TEXTURE_MIN_LOD: 1311 *params = (GLint) sampObj->MinLod; 1312 break; 1313 case GL_TEXTURE_MAX_LOD: 1314 *params = (GLint) sampObj->MaxLod; 1315 break; 1316 case GL_TEXTURE_LOD_BIAS: 1317 *params = (GLint) sampObj->LodBias; 1318 break; 1319 case GL_TEXTURE_COMPARE_MODE: 1320 if (!ctx->Extensions.ARB_shadow) 1321 goto invalid_pname; 1322 *params = sampObj->CompareMode; 1323 break; 1324 case GL_TEXTURE_COMPARE_FUNC: 1325 if (!ctx->Extensions.ARB_shadow) 1326 goto invalid_pname; 1327 *params = sampObj->CompareFunc; 1328 break; 1329 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1330 *params = (GLint) sampObj->MaxAnisotropy; 1331 break; 1332 case GL_TEXTURE_BORDER_COLOR: 1333 params[0] = sampObj->BorderColor.i[0]; 1334 params[1] = sampObj->BorderColor.i[1]; 1335 params[2] = sampObj->BorderColor.i[2]; 1336 params[3] = sampObj->BorderColor.i[3]; 1337 break; 1338 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1339 if (!ctx->Extensions.AMD_seamless_cubemap_per_texture) 1340 goto invalid_pname; 1341 *params = sampObj->CubeMapSeamless; 1342 break; 1343 case GL_TEXTURE_SRGB_DECODE_EXT: 1344 if (!ctx->Extensions.EXT_texture_sRGB_decode) 1345 goto invalid_pname; 1346 *params = (GLenum) sampObj->sRGBDecode; 1347 break; 1348 default: 1349 goto invalid_pname; 1350 } 1351 return; 1352 1353 invalid_pname: 1354 _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameterIiv(pname=%s)", 1355 _mesa_lookup_enum_by_nr(pname)); 1356 } 1357 1358 1359 static void GLAPIENTRY 1360 _mesa_GetSamplerParameterIuiv(GLuint sampler, GLenum pname, GLuint *params) 1361 { 1362 struct gl_sampler_object *sampObj; 1363 GET_CURRENT_CONTEXT(ctx); 1364 1365 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 1366 if (!sampObj) { 1367 _mesa_error(ctx, GL_INVALID_VALUE, 1368 "glGetSamplerParameterIuiv(sampler %u)", 1369 sampler); 1370 return; 1371 } 1372 1373 switch (pname) { 1374 case GL_TEXTURE_WRAP_S: 1375 *params = sampObj->WrapS; 1376 break; 1377 case GL_TEXTURE_WRAP_T: 1378 *params = sampObj->WrapT; 1379 break; 1380 case GL_TEXTURE_WRAP_R: 1381 *params = sampObj->WrapR; 1382 break; 1383 case GL_TEXTURE_MIN_FILTER: 1384 *params = sampObj->MinFilter; 1385 break; 1386 case GL_TEXTURE_MAG_FILTER: 1387 *params = sampObj->MagFilter; 1388 break; 1389 case GL_TEXTURE_MIN_LOD: 1390 *params = (GLuint) sampObj->MinLod; 1391 break; 1392 case GL_TEXTURE_MAX_LOD: 1393 *params = (GLuint) sampObj->MaxLod; 1394 break; 1395 case GL_TEXTURE_LOD_BIAS: 1396 *params = (GLuint) sampObj->LodBias; 1397 break; 1398 case GL_TEXTURE_COMPARE_MODE: 1399 if (!ctx->Extensions.ARB_shadow) 1400 goto invalid_pname; 1401 *params = sampObj->CompareMode; 1402 break; 1403 case GL_TEXTURE_COMPARE_FUNC: 1404 if (!ctx->Extensions.ARB_shadow) 1405 goto invalid_pname; 1406 *params = sampObj->CompareFunc; 1407 break; 1408 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1409 *params = (GLuint) sampObj->MaxAnisotropy; 1410 break; 1411 case GL_TEXTURE_BORDER_COLOR: 1412 params[0] = sampObj->BorderColor.ui[0]; 1413 params[1] = sampObj->BorderColor.ui[1]; 1414 params[2] = sampObj->BorderColor.ui[2]; 1415 params[3] = sampObj->BorderColor.ui[3]; 1416 break; 1417 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1418 if (!ctx->Extensions.AMD_seamless_cubemap_per_texture) 1419 goto invalid_pname; 1420 *params = sampObj->CubeMapSeamless; 1421 break; 1422 case GL_TEXTURE_SRGB_DECODE_EXT: 1423 if (!ctx->Extensions.EXT_texture_sRGB_decode) 1424 goto invalid_pname; 1425 *params = (GLenum) sampObj->sRGBDecode; 1426 break; 1427 default: 1428 goto invalid_pname; 1429 } 1430 return; 1431 1432 invalid_pname: 1433 _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameterIuiv(pname=%s)", 1434 _mesa_lookup_enum_by_nr(pname)); 1435 } 1436 1437 1438 void 1439 _mesa_init_sampler_object_functions(struct dd_function_table *driver) 1440 { 1441 driver->NewSamplerObject = _mesa_new_sampler_object; 1442 driver->DeleteSamplerObject = _mesa_delete_sampler_object; 1443 } 1444 1445 1446 void 1447 _mesa_init_sampler_object_dispatch(struct _glapi_table *disp) 1448 { 1449 SET_GenSamplers(disp, _mesa_GenSamplers); 1450 SET_DeleteSamplers(disp, _mesa_DeleteSamplers); 1451 SET_IsSampler(disp, _mesa_IsSampler); 1452 SET_BindSampler(disp, _mesa_BindSampler); 1453 SET_SamplerParameteri(disp, _mesa_SamplerParameteri); 1454 SET_SamplerParameterf(disp, _mesa_SamplerParameterf); 1455 SET_SamplerParameteriv(disp, _mesa_SamplerParameteriv); 1456 SET_SamplerParameterfv(disp, _mesa_SamplerParameterfv); 1457 SET_SamplerParameterIiv(disp, _mesa_SamplerParameterIiv); 1458 SET_SamplerParameterIuiv(disp, _mesa_SamplerParameterIuiv); 1459 SET_GetSamplerParameteriv(disp, _mesa_GetSamplerParameteriv); 1460 SET_GetSamplerParameterfv(disp, _mesa_GetSamplerParameterfv); 1461 SET_GetSamplerParameterIiv(disp, _mesa_GetSamplerParameterIiv); 1462 SET_GetSamplerParameterIuiv(disp, _mesa_GetSamplerParameterIuiv); 1463 } 1464