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