samplerobj.c revision 4cf5c85ec70abb736e9c135e77c221b177d85d12
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 75static void 76delete_sampler_object(struct gl_context *ctx, 77 struct gl_sampler_object *sampObj) 78{ 79 mtx_destroy(&sampObj->Mutex); 80 free(sampObj->Label); 81 free(sampObj); 82} 83 84/** 85 * Handle reference counting. 86 */ 87void 88_mesa_reference_sampler_object_(struct gl_context *ctx, 89 struct gl_sampler_object **ptr, 90 struct gl_sampler_object *samp) 91{ 92 assert(*ptr != samp); /* The inline wrapper should prevent no-op calls */ 93 94 if (*ptr) { 95 /* Unreference the old sampler */ 96 GLboolean deleteFlag = GL_FALSE; 97 struct gl_sampler_object *oldSamp = *ptr; 98 99 mtx_lock(&oldSamp->Mutex); 100 assert(oldSamp->RefCount > 0); 101 oldSamp->RefCount--; 102 deleteFlag = (oldSamp->RefCount == 0); 103 mtx_unlock(&oldSamp->Mutex); 104 105 if (deleteFlag) 106 delete_sampler_object(ctx, oldSamp); 107 108 *ptr = NULL; 109 } 110 assert(!*ptr); 111 112 if (samp) { 113 /* reference new sampler */ 114 mtx_lock(&samp->Mutex); 115 if (samp->RefCount == 0) { 116 /* this sampler's being deleted (look just above) */ 117 /* Not sure this can every really happen. Warn if it does. */ 118 _mesa_problem(NULL, "referencing deleted sampler object"); 119 *ptr = NULL; 120 } 121 else { 122 samp->RefCount++; 123 *ptr = samp; 124 } 125 mtx_unlock(&samp->Mutex); 126 } 127} 128 129 130/** 131 * Initialize the fields of the given sampler object. 132 */ 133static void 134_mesa_init_sampler_object(struct gl_sampler_object *sampObj, GLuint name) 135{ 136 mtx_init(&sampObj->Mutex, mtx_plain); 137 sampObj->Name = name; 138 sampObj->RefCount = 1; 139 sampObj->WrapS = GL_REPEAT; 140 sampObj->WrapT = GL_REPEAT; 141 sampObj->WrapR = GL_REPEAT; 142 sampObj->MinFilter = GL_NEAREST_MIPMAP_LINEAR; 143 sampObj->MagFilter = GL_LINEAR; 144 sampObj->BorderColor.f[0] = 0.0; 145 sampObj->BorderColor.f[1] = 0.0; 146 sampObj->BorderColor.f[2] = 0.0; 147 sampObj->BorderColor.f[3] = 0.0; 148 sampObj->MinLod = -1000.0F; 149 sampObj->MaxLod = 1000.0F; 150 sampObj->LodBias = 0.0F; 151 sampObj->MaxAnisotropy = 1.0F; 152 sampObj->CompareMode = GL_NONE; 153 sampObj->CompareFunc = GL_LEQUAL; 154 sampObj->sRGBDecode = GL_DECODE_EXT; 155 sampObj->CubeMapSeamless = GL_FALSE; 156} 157 158/** 159 * Fallback for ctx->Driver.NewSamplerObject(); 160 */ 161struct gl_sampler_object * 162_mesa_new_sampler_object(struct gl_context *ctx, GLuint name) 163{ 164 struct gl_sampler_object *sampObj = CALLOC_STRUCT(gl_sampler_object); 165 if (sampObj) { 166 _mesa_init_sampler_object(sampObj, name); 167 } 168 return sampObj; 169} 170 171static void 172create_samplers(struct gl_context *ctx, GLsizei count, GLuint *samplers, 173 const char *caller) 174{ 175 GLuint first; 176 GLint i; 177 178 if (MESA_VERBOSE & VERBOSE_API) 179 _mesa_debug(ctx, "%s(%d)\n", caller, count); 180 181 if (count < 0) { 182 _mesa_error(ctx, GL_INVALID_VALUE, "%s(n<0)", caller); 183 return; 184 } 185 186 if (!samplers) 187 return; 188 189 first = _mesa_HashFindFreeKeyBlock(ctx->Shared->SamplerObjects, count); 190 191 /* Insert the ID and pointer to new sampler object into hash table */ 192 for (i = 0; i < count; i++) { 193 struct gl_sampler_object *sampObj = 194 ctx->Driver.NewSamplerObject(ctx, first + i); 195 _mesa_HashInsert(ctx->Shared->SamplerObjects, first + i, sampObj); 196 samplers[i] = first + i; 197 } 198} 199 200void GLAPIENTRY 201_mesa_GenSamplers(GLsizei count, GLuint *samplers) 202{ 203 GET_CURRENT_CONTEXT(ctx); 204 create_samplers(ctx, count, samplers, "glGenSamplers"); 205} 206 207void GLAPIENTRY 208_mesa_CreateSamplers(GLsizei count, GLuint *samplers) 209{ 210 GET_CURRENT_CONTEXT(ctx); 211 create_samplers(ctx, count, samplers, "glCreateSamplers"); 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 447void 448_mesa_set_sampler_wrap(struct gl_context *ctx, struct gl_sampler_object *samp, 449 GLenum s, GLenum t, GLenum r) 450{ 451 assert(validate_texture_wrap_mode(ctx, s)); 452 assert(validate_texture_wrap_mode(ctx, t)); 453 assert(validate_texture_wrap_mode(ctx, r)); 454 455 if (samp->WrapS == s && samp->WrapT == t && samp->WrapR == r) 456 return; 457 458 flush(ctx); 459 samp->WrapS = s; 460 samp->WrapT = t; 461 samp->WrapR = r; 462} 463 464#define INVALID_PARAM 0x100 465#define INVALID_PNAME 0x101 466#define INVALID_VALUE 0x102 467 468static GLuint 469set_sampler_wrap_s(struct gl_context *ctx, struct gl_sampler_object *samp, 470 GLint param) 471{ 472 if (samp->WrapS == param) 473 return GL_FALSE; 474 if (validate_texture_wrap_mode(ctx, param)) { 475 flush(ctx); 476 samp->WrapS = param; 477 return GL_TRUE; 478 } 479 return INVALID_PARAM; 480} 481 482 483static GLuint 484set_sampler_wrap_t(struct gl_context *ctx, struct gl_sampler_object *samp, 485 GLint param) 486{ 487 if (samp->WrapT == param) 488 return GL_FALSE; 489 if (validate_texture_wrap_mode(ctx, param)) { 490 flush(ctx); 491 samp->WrapT = param; 492 return GL_TRUE; 493 } 494 return INVALID_PARAM; 495} 496 497 498static GLuint 499set_sampler_wrap_r(struct gl_context *ctx, struct gl_sampler_object *samp, 500 GLint param) 501{ 502 if (samp->WrapR == param) 503 return GL_FALSE; 504 if (validate_texture_wrap_mode(ctx, param)) { 505 flush(ctx); 506 samp->WrapR = param; 507 return GL_TRUE; 508 } 509 return INVALID_PARAM; 510} 511 512void 513_mesa_set_sampler_filters(struct gl_context *ctx, 514 struct gl_sampler_object *samp, 515 GLenum min_filter, GLenum mag_filter) 516{ 517 assert(min_filter == GL_NEAREST || 518 min_filter == GL_LINEAR || 519 min_filter == GL_NEAREST_MIPMAP_NEAREST || 520 min_filter == GL_LINEAR_MIPMAP_NEAREST || 521 min_filter == GL_NEAREST_MIPMAP_LINEAR || 522 min_filter == GL_LINEAR_MIPMAP_LINEAR); 523 assert(mag_filter == GL_NEAREST || 524 mag_filter == GL_LINEAR); 525 526 if (samp->MinFilter == min_filter && samp->MagFilter == mag_filter) 527 return; 528 529 flush(ctx); 530 samp->MinFilter = min_filter; 531 samp->MagFilter = mag_filter; 532} 533 534static GLuint 535set_sampler_min_filter(struct gl_context *ctx, struct gl_sampler_object *samp, 536 GLint param) 537{ 538 if (samp->MinFilter == param) 539 return GL_FALSE; 540 541 switch (param) { 542 case GL_NEAREST: 543 case GL_LINEAR: 544 case GL_NEAREST_MIPMAP_NEAREST: 545 case GL_LINEAR_MIPMAP_NEAREST: 546 case GL_NEAREST_MIPMAP_LINEAR: 547 case GL_LINEAR_MIPMAP_LINEAR: 548 flush(ctx); 549 samp->MinFilter = param; 550 return GL_TRUE; 551 default: 552 return INVALID_PARAM; 553 } 554} 555 556 557static GLuint 558set_sampler_mag_filter(struct gl_context *ctx, struct gl_sampler_object *samp, 559 GLint param) 560{ 561 if (samp->MagFilter == param) 562 return GL_FALSE; 563 564 switch (param) { 565 case GL_NEAREST: 566 case GL_LINEAR: 567 flush(ctx); 568 samp->MagFilter = param; 569 return GL_TRUE; 570 default: 571 return INVALID_PARAM; 572 } 573} 574 575 576static GLuint 577set_sampler_lod_bias(struct gl_context *ctx, struct gl_sampler_object *samp, 578 GLfloat param) 579{ 580 if (samp->LodBias == param) 581 return GL_FALSE; 582 583 flush(ctx); 584 samp->LodBias = param; 585 return GL_TRUE; 586} 587 588 589static GLuint 590set_sampler_border_colorf(struct gl_context *ctx, 591 struct gl_sampler_object *samp, 592 const GLfloat params[4]) 593{ 594 flush(ctx); 595 samp->BorderColor.f[RCOMP] = params[0]; 596 samp->BorderColor.f[GCOMP] = params[1]; 597 samp->BorderColor.f[BCOMP] = params[2]; 598 samp->BorderColor.f[ACOMP] = params[3]; 599 return GL_TRUE; 600} 601 602 603static GLuint 604set_sampler_border_colori(struct gl_context *ctx, 605 struct gl_sampler_object *samp, 606 const GLint params[4]) 607{ 608 flush(ctx); 609 samp->BorderColor.i[RCOMP] = params[0]; 610 samp->BorderColor.i[GCOMP] = params[1]; 611 samp->BorderColor.i[BCOMP] = params[2]; 612 samp->BorderColor.i[ACOMP] = params[3]; 613 return GL_TRUE; 614} 615 616 617static GLuint 618set_sampler_border_colorui(struct gl_context *ctx, 619 struct gl_sampler_object *samp, 620 const GLuint params[4]) 621{ 622 flush(ctx); 623 samp->BorderColor.ui[RCOMP] = params[0]; 624 samp->BorderColor.ui[GCOMP] = params[1]; 625 samp->BorderColor.ui[BCOMP] = params[2]; 626 samp->BorderColor.ui[ACOMP] = params[3]; 627 return GL_TRUE; 628} 629 630 631static GLuint 632set_sampler_min_lod(struct gl_context *ctx, struct gl_sampler_object *samp, 633 GLfloat param) 634{ 635 if (samp->MinLod == param) 636 return GL_FALSE; 637 638 flush(ctx); 639 samp->MinLod = param; 640 return GL_TRUE; 641} 642 643 644static GLuint 645set_sampler_max_lod(struct gl_context *ctx, struct gl_sampler_object *samp, 646 GLfloat param) 647{ 648 if (samp->MaxLod == param) 649 return GL_FALSE; 650 651 flush(ctx); 652 samp->MaxLod = param; 653 return GL_TRUE; 654} 655 656 657static GLuint 658set_sampler_compare_mode(struct gl_context *ctx, 659 struct gl_sampler_object *samp, GLint param) 660{ 661 /* If GL_ARB_shadow is not supported, don't report an error. The 662 * sampler object extension spec isn't clear on this extension interaction. 663 * Silences errors with Wine on older GPUs such as R200. 664 */ 665 if (!ctx->Extensions.ARB_shadow) 666 return GL_FALSE; 667 668 if (samp->CompareMode == param) 669 return GL_FALSE; 670 671 if (param == GL_NONE || 672 param == GL_COMPARE_R_TO_TEXTURE_ARB) { 673 flush(ctx); 674 samp->CompareMode = param; 675 return GL_TRUE; 676 } 677 678 return INVALID_PARAM; 679} 680 681 682static GLuint 683set_sampler_compare_func(struct gl_context *ctx, 684 struct gl_sampler_object *samp, GLint param) 685{ 686 /* If GL_ARB_shadow is not supported, don't report an error. The 687 * sampler object extension spec isn't clear on this extension interaction. 688 * Silences errors with Wine on older GPUs such as R200. 689 */ 690 if (!ctx->Extensions.ARB_shadow) 691 return GL_FALSE; 692 693 if (samp->CompareFunc == param) 694 return GL_FALSE; 695 696 switch (param) { 697 case GL_LEQUAL: 698 case GL_GEQUAL: 699 case GL_EQUAL: 700 case GL_NOTEQUAL: 701 case GL_LESS: 702 case GL_GREATER: 703 case GL_ALWAYS: 704 case GL_NEVER: 705 flush(ctx); 706 samp->CompareFunc = param; 707 return GL_TRUE; 708 default: 709 return INVALID_PARAM; 710 } 711} 712 713 714static GLuint 715set_sampler_max_anisotropy(struct gl_context *ctx, 716 struct gl_sampler_object *samp, GLfloat param) 717{ 718 if (!ctx->Extensions.EXT_texture_filter_anisotropic) 719 return INVALID_PNAME; 720 721 if (samp->MaxAnisotropy == param) 722 return GL_FALSE; 723 724 if (param < 1.0F) 725 return INVALID_VALUE; 726 727 flush(ctx); 728 /* clamp to max, that's what NVIDIA does */ 729 samp->MaxAnisotropy = MIN2(param, ctx->Const.MaxTextureMaxAnisotropy); 730 return GL_TRUE; 731} 732 733 734static GLuint 735set_sampler_cube_map_seamless(struct gl_context *ctx, 736 struct gl_sampler_object *samp, GLboolean param) 737{ 738 if (!_mesa_is_desktop_gl(ctx) 739 || !ctx->Extensions.AMD_seamless_cubemap_per_texture) 740 return INVALID_PNAME; 741 742 if (samp->CubeMapSeamless == param) 743 return GL_FALSE; 744 745 if (param != GL_TRUE && param != GL_FALSE) 746 return INVALID_VALUE; 747 748 flush(ctx); 749 samp->CubeMapSeamless = param; 750 return GL_TRUE; 751} 752 753void 754_mesa_set_sampler_srgb_decode(struct gl_context *ctx, 755 struct gl_sampler_object *samp, GLenum param) 756{ 757 assert(param == GL_DECODE_EXT || param == GL_SKIP_DECODE_EXT); 758 759 flush(ctx); 760 samp->sRGBDecode = param; 761} 762 763static GLuint 764set_sampler_srgb_decode(struct gl_context *ctx, 765 struct gl_sampler_object *samp, GLenum param) 766{ 767 if (!ctx->Extensions.EXT_texture_sRGB_decode) 768 return INVALID_PNAME; 769 770 if (samp->sRGBDecode == param) 771 return GL_FALSE; 772 773 if (param != GL_DECODE_EXT && param != GL_SKIP_DECODE_EXT) 774 return INVALID_VALUE; 775 776 flush(ctx); 777 samp->sRGBDecode = param; 778 return GL_TRUE; 779} 780 781void GLAPIENTRY 782_mesa_SamplerParameteri(GLuint sampler, GLenum pname, GLint param) 783{ 784 struct gl_sampler_object *sampObj; 785 GLuint res; 786 GET_CURRENT_CONTEXT(ctx); 787 788 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 789 if (!sampObj) { 790 /* '3.8.2 Sampler Objects' section of the GL-ES 3.0 specification states: 791 * 792 * "An INVALID_OPERATION error is generated if sampler is not the name 793 * of a sampler object previously returned from a call to GenSamplers." 794 * 795 * In desktop GL, an GL_INVALID_VALUE is returned instead. 796 */ 797 _mesa_error(ctx, (_mesa_is_gles(ctx) ? 798 GL_INVALID_OPERATION : GL_INVALID_VALUE), 799 "glSamplerParameteri(sampler %u)", sampler); 800 return; 801 } 802 803 switch (pname) { 804 case GL_TEXTURE_WRAP_S: 805 res = set_sampler_wrap_s(ctx, sampObj, param); 806 break; 807 case GL_TEXTURE_WRAP_T: 808 res = set_sampler_wrap_t(ctx, sampObj, param); 809 break; 810 case GL_TEXTURE_WRAP_R: 811 res = set_sampler_wrap_r(ctx, sampObj, param); 812 break; 813 case GL_TEXTURE_MIN_FILTER: 814 res = set_sampler_min_filter(ctx, sampObj, param); 815 break; 816 case GL_TEXTURE_MAG_FILTER: 817 res = set_sampler_mag_filter(ctx, sampObj, param); 818 break; 819 case GL_TEXTURE_MIN_LOD: 820 res = set_sampler_min_lod(ctx, sampObj, (GLfloat) param); 821 break; 822 case GL_TEXTURE_MAX_LOD: 823 res = set_sampler_max_lod(ctx, sampObj, (GLfloat) param); 824 break; 825 case GL_TEXTURE_LOD_BIAS: 826 res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) param); 827 break; 828 case GL_TEXTURE_COMPARE_MODE: 829 res = set_sampler_compare_mode(ctx, sampObj, param); 830 break; 831 case GL_TEXTURE_COMPARE_FUNC: 832 res = set_sampler_compare_func(ctx, sampObj, param); 833 break; 834 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 835 res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) param); 836 break; 837 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 838 res = set_sampler_cube_map_seamless(ctx, sampObj, param); 839 break; 840 case GL_TEXTURE_SRGB_DECODE_EXT: 841 res = set_sampler_srgb_decode(ctx, sampObj, param); 842 break; 843 case GL_TEXTURE_BORDER_COLOR: 844 /* fall-through */ 845 default: 846 res = INVALID_PNAME; 847 } 848 849 switch (res) { 850 case GL_FALSE: 851 /* no change */ 852 break; 853 case GL_TRUE: 854 /* state change - we do nothing special at this time */ 855 break; 856 case INVALID_PNAME: 857 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteri(pname=%s)\n", 858 _mesa_enum_to_string(pname)); 859 break; 860 case INVALID_PARAM: 861 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteri(param=%d)\n", 862 param); 863 break; 864 case INVALID_VALUE: 865 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameteri(param=%d)\n", 866 param); 867 break; 868 default: 869 ; 870 } 871} 872 873 874void GLAPIENTRY 875_mesa_SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) 876{ 877 struct gl_sampler_object *sampObj; 878 GLuint res; 879 GET_CURRENT_CONTEXT(ctx); 880 881 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 882 if (!sampObj) { 883 /* '3.8.2 Sampler Objects' section of the GL-ES 3.0 specification states: 884 * 885 * "An INVALID_OPERATION error is generated if sampler is not the name 886 * of a sampler object previously returned from a call to GenSamplers." 887 * 888 * In desktop GL, an GL_INVALID_VALUE is returned instead. 889 */ 890 _mesa_error(ctx, (_mesa_is_gles(ctx) ? 891 GL_INVALID_OPERATION : GL_INVALID_VALUE), 892 "glSamplerParameterf(sampler %u)", sampler); 893 return; 894 } 895 896 switch (pname) { 897 case GL_TEXTURE_WRAP_S: 898 res = set_sampler_wrap_s(ctx, sampObj, (GLint) param); 899 break; 900 case GL_TEXTURE_WRAP_T: 901 res = set_sampler_wrap_t(ctx, sampObj, (GLint) param); 902 break; 903 case GL_TEXTURE_WRAP_R: 904 res = set_sampler_wrap_r(ctx, sampObj, (GLint) param); 905 break; 906 case GL_TEXTURE_MIN_FILTER: 907 res = set_sampler_min_filter(ctx, sampObj, (GLint) param); 908 break; 909 case GL_TEXTURE_MAG_FILTER: 910 res = set_sampler_mag_filter(ctx, sampObj, (GLint) param); 911 break; 912 case GL_TEXTURE_MIN_LOD: 913 res = set_sampler_min_lod(ctx, sampObj, param); 914 break; 915 case GL_TEXTURE_MAX_LOD: 916 res = set_sampler_max_lod(ctx, sampObj, param); 917 break; 918 case GL_TEXTURE_LOD_BIAS: 919 res = set_sampler_lod_bias(ctx, sampObj, param); 920 break; 921 case GL_TEXTURE_COMPARE_MODE: 922 res = set_sampler_compare_mode(ctx, sampObj, (GLint) param); 923 break; 924 case GL_TEXTURE_COMPARE_FUNC: 925 res = set_sampler_compare_func(ctx, sampObj, (GLint) param); 926 break; 927 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 928 res = set_sampler_max_anisotropy(ctx, sampObj, param); 929 break; 930 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 931 res = set_sampler_cube_map_seamless(ctx, sampObj, (GLboolean) param); 932 break; 933 case GL_TEXTURE_SRGB_DECODE_EXT: 934 res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) param); 935 break; 936 case GL_TEXTURE_BORDER_COLOR: 937 /* fall-through */ 938 default: 939 res = INVALID_PNAME; 940 } 941 942 switch (res) { 943 case GL_FALSE: 944 /* no change */ 945 break; 946 case GL_TRUE: 947 /* state change - we do nothing special at this time */ 948 break; 949 case INVALID_PNAME: 950 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterf(pname=%s)\n", 951 _mesa_enum_to_string(pname)); 952 break; 953 case INVALID_PARAM: 954 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterf(param=%f)\n", 955 param); 956 break; 957 case INVALID_VALUE: 958 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterf(param=%f)\n", 959 param); 960 break; 961 default: 962 ; 963 } 964} 965 966void GLAPIENTRY 967_mesa_SamplerParameteriv(GLuint sampler, GLenum pname, const GLint *params) 968{ 969 struct gl_sampler_object *sampObj; 970 GLuint res; 971 GET_CURRENT_CONTEXT(ctx); 972 973 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 974 if (!sampObj) { 975 /* '3.8.2 Sampler Objects' section of the GL-ES 3.0 specification states: 976 * 977 * "An INVALID_OPERATION error is generated if sampler is not the name 978 * of a sampler object previously returned from a call to GenSamplers." 979 * 980 * In desktop GL, an GL_INVALID_VALUE is returned instead. 981 */ 982 _mesa_error(ctx, (_mesa_is_gles(ctx) ? 983 GL_INVALID_OPERATION : GL_INVALID_VALUE), 984 "glSamplerParameteriv(sampler %u)", sampler); 985 return; 986 } 987 988 switch (pname) { 989 case GL_TEXTURE_WRAP_S: 990 res = set_sampler_wrap_s(ctx, sampObj, params[0]); 991 break; 992 case GL_TEXTURE_WRAP_T: 993 res = set_sampler_wrap_t(ctx, sampObj, params[0]); 994 break; 995 case GL_TEXTURE_WRAP_R: 996 res = set_sampler_wrap_r(ctx, sampObj, params[0]); 997 break; 998 case GL_TEXTURE_MIN_FILTER: 999 res = set_sampler_min_filter(ctx, sampObj, params[0]); 1000 break; 1001 case GL_TEXTURE_MAG_FILTER: 1002 res = set_sampler_mag_filter(ctx, sampObj, params[0]); 1003 break; 1004 case GL_TEXTURE_MIN_LOD: 1005 res = set_sampler_min_lod(ctx, sampObj, (GLfloat) params[0]); 1006 break; 1007 case GL_TEXTURE_MAX_LOD: 1008 res = set_sampler_max_lod(ctx, sampObj, (GLfloat) params[0]); 1009 break; 1010 case GL_TEXTURE_LOD_BIAS: 1011 res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) params[0]); 1012 break; 1013 case GL_TEXTURE_COMPARE_MODE: 1014 res = set_sampler_compare_mode(ctx, sampObj, params[0]); 1015 break; 1016 case GL_TEXTURE_COMPARE_FUNC: 1017 res = set_sampler_compare_func(ctx, sampObj, params[0]); 1018 break; 1019 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1020 res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) params[0]); 1021 break; 1022 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1023 res = set_sampler_cube_map_seamless(ctx, sampObj, params[0]); 1024 break; 1025 case GL_TEXTURE_SRGB_DECODE_EXT: 1026 res = set_sampler_srgb_decode(ctx, sampObj, params[0]); 1027 break; 1028 case GL_TEXTURE_BORDER_COLOR: 1029 { 1030 GLfloat c[4]; 1031 c[0] = INT_TO_FLOAT(params[0]); 1032 c[1] = INT_TO_FLOAT(params[1]); 1033 c[2] = INT_TO_FLOAT(params[2]); 1034 c[3] = INT_TO_FLOAT(params[3]); 1035 res = set_sampler_border_colorf(ctx, sampObj, c); 1036 } 1037 break; 1038 default: 1039 res = INVALID_PNAME; 1040 } 1041 1042 switch (res) { 1043 case GL_FALSE: 1044 /* no change */ 1045 break; 1046 case GL_TRUE: 1047 /* state change - we do nothing special at this time */ 1048 break; 1049 case INVALID_PNAME: 1050 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteriv(pname=%s)\n", 1051 _mesa_enum_to_string(pname)); 1052 break; 1053 case INVALID_PARAM: 1054 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteriv(param=%d)\n", 1055 params[0]); 1056 break; 1057 case INVALID_VALUE: 1058 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameteriv(param=%d)\n", 1059 params[0]); 1060 break; 1061 default: 1062 ; 1063 } 1064} 1065 1066void GLAPIENTRY 1067_mesa_SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *params) 1068{ 1069 struct gl_sampler_object *sampObj; 1070 GLuint res; 1071 GET_CURRENT_CONTEXT(ctx); 1072 1073 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 1074 if (!sampObj) { 1075 /* '3.8.2 Sampler Objects' section of the GL-ES 3.0 specification states: 1076 * 1077 * "An INVALID_OPERATION error is generated if sampler is not the name 1078 * of a sampler object previously returned from a call to GenSamplers." 1079 * 1080 * In desktop GL, an GL_INVALID_VALUE is returned instead. 1081 */ 1082 _mesa_error(ctx, (_mesa_is_gles(ctx) ? 1083 GL_INVALID_OPERATION : GL_INVALID_VALUE), 1084 "glSamplerParameterfv(sampler %u)", sampler); 1085 return; 1086 } 1087 1088 switch (pname) { 1089 case GL_TEXTURE_WRAP_S: 1090 res = set_sampler_wrap_s(ctx, sampObj, (GLint) params[0]); 1091 break; 1092 case GL_TEXTURE_WRAP_T: 1093 res = set_sampler_wrap_t(ctx, sampObj, (GLint) params[0]); 1094 break; 1095 case GL_TEXTURE_WRAP_R: 1096 res = set_sampler_wrap_r(ctx, sampObj, (GLint) params[0]); 1097 break; 1098 case GL_TEXTURE_MIN_FILTER: 1099 res = set_sampler_min_filter(ctx, sampObj, (GLint) params[0]); 1100 break; 1101 case GL_TEXTURE_MAG_FILTER: 1102 res = set_sampler_mag_filter(ctx, sampObj, (GLint) params[0]); 1103 break; 1104 case GL_TEXTURE_MIN_LOD: 1105 res = set_sampler_min_lod(ctx, sampObj, params[0]); 1106 break; 1107 case GL_TEXTURE_MAX_LOD: 1108 res = set_sampler_max_lod(ctx, sampObj, params[0]); 1109 break; 1110 case GL_TEXTURE_LOD_BIAS: 1111 res = set_sampler_lod_bias(ctx, sampObj, params[0]); 1112 break; 1113 case GL_TEXTURE_COMPARE_MODE: 1114 res = set_sampler_compare_mode(ctx, sampObj, (GLint) params[0]); 1115 break; 1116 case GL_TEXTURE_COMPARE_FUNC: 1117 res = set_sampler_compare_func(ctx, sampObj, (GLint) params[0]); 1118 break; 1119 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1120 res = set_sampler_max_anisotropy(ctx, sampObj, params[0]); 1121 break; 1122 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1123 res = set_sampler_cube_map_seamless(ctx, sampObj, (GLboolean) params[0]); 1124 break; 1125 case GL_TEXTURE_SRGB_DECODE_EXT: 1126 res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) params[0]); 1127 break; 1128 case GL_TEXTURE_BORDER_COLOR: 1129 res = set_sampler_border_colorf(ctx, sampObj, params); 1130 break; 1131 default: 1132 res = INVALID_PNAME; 1133 } 1134 1135 switch (res) { 1136 case GL_FALSE: 1137 /* no change */ 1138 break; 1139 case GL_TRUE: 1140 /* state change - we do nothing special at this time */ 1141 break; 1142 case INVALID_PNAME: 1143 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterfv(pname=%s)\n", 1144 _mesa_enum_to_string(pname)); 1145 break; 1146 case INVALID_PARAM: 1147 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterfv(param=%f)\n", 1148 params[0]); 1149 break; 1150 case INVALID_VALUE: 1151 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterfv(param=%f)\n", 1152 params[0]); 1153 break; 1154 default: 1155 ; 1156 } 1157} 1158 1159void GLAPIENTRY 1160_mesa_SamplerParameterIiv(GLuint sampler, GLenum pname, const GLint *params) 1161{ 1162 struct gl_sampler_object *sampObj; 1163 GLuint res; 1164 GET_CURRENT_CONTEXT(ctx); 1165 1166 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 1167 if (!sampObj) { 1168 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIiv(sampler %u)", 1169 sampler); 1170 return; 1171 } 1172 1173 switch (pname) { 1174 case GL_TEXTURE_WRAP_S: 1175 res = set_sampler_wrap_s(ctx, sampObj, params[0]); 1176 break; 1177 case GL_TEXTURE_WRAP_T: 1178 res = set_sampler_wrap_t(ctx, sampObj, params[0]); 1179 break; 1180 case GL_TEXTURE_WRAP_R: 1181 res = set_sampler_wrap_r(ctx, sampObj, params[0]); 1182 break; 1183 case GL_TEXTURE_MIN_FILTER: 1184 res = set_sampler_min_filter(ctx, sampObj, params[0]); 1185 break; 1186 case GL_TEXTURE_MAG_FILTER: 1187 res = set_sampler_mag_filter(ctx, sampObj, params[0]); 1188 break; 1189 case GL_TEXTURE_MIN_LOD: 1190 res = set_sampler_min_lod(ctx, sampObj, (GLfloat) params[0]); 1191 break; 1192 case GL_TEXTURE_MAX_LOD: 1193 res = set_sampler_max_lod(ctx, sampObj, (GLfloat) params[0]); 1194 break; 1195 case GL_TEXTURE_LOD_BIAS: 1196 res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) params[0]); 1197 break; 1198 case GL_TEXTURE_COMPARE_MODE: 1199 res = set_sampler_compare_mode(ctx, sampObj, params[0]); 1200 break; 1201 case GL_TEXTURE_COMPARE_FUNC: 1202 res = set_sampler_compare_func(ctx, sampObj, params[0]); 1203 break; 1204 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1205 res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) params[0]); 1206 break; 1207 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1208 res = set_sampler_cube_map_seamless(ctx, sampObj, params[0]); 1209 break; 1210 case GL_TEXTURE_SRGB_DECODE_EXT: 1211 res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) params[0]); 1212 break; 1213 case GL_TEXTURE_BORDER_COLOR: 1214 res = set_sampler_border_colori(ctx, sampObj, params); 1215 break; 1216 default: 1217 res = INVALID_PNAME; 1218 } 1219 1220 switch (res) { 1221 case GL_FALSE: 1222 /* no change */ 1223 break; 1224 case GL_TRUE: 1225 /* state change - we do nothing special at this time */ 1226 break; 1227 case INVALID_PNAME: 1228 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIiv(pname=%s)\n", 1229 _mesa_enum_to_string(pname)); 1230 break; 1231 case INVALID_PARAM: 1232 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIiv(param=%d)\n", 1233 params[0]); 1234 break; 1235 case INVALID_VALUE: 1236 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIiv(param=%d)\n", 1237 params[0]); 1238 break; 1239 default: 1240 ; 1241 } 1242} 1243 1244 1245void GLAPIENTRY 1246_mesa_SamplerParameterIuiv(GLuint sampler, GLenum pname, const GLuint *params) 1247{ 1248 struct gl_sampler_object *sampObj; 1249 GLuint res; 1250 GET_CURRENT_CONTEXT(ctx); 1251 1252 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 1253 if (!sampObj) { 1254 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIuiv(sampler %u)", 1255 sampler); 1256 return; 1257 } 1258 1259 switch (pname) { 1260 case GL_TEXTURE_WRAP_S: 1261 res = set_sampler_wrap_s(ctx, sampObj, params[0]); 1262 break; 1263 case GL_TEXTURE_WRAP_T: 1264 res = set_sampler_wrap_t(ctx, sampObj, params[0]); 1265 break; 1266 case GL_TEXTURE_WRAP_R: 1267 res = set_sampler_wrap_r(ctx, sampObj, params[0]); 1268 break; 1269 case GL_TEXTURE_MIN_FILTER: 1270 res = set_sampler_min_filter(ctx, sampObj, params[0]); 1271 break; 1272 case GL_TEXTURE_MAG_FILTER: 1273 res = set_sampler_mag_filter(ctx, sampObj, params[0]); 1274 break; 1275 case GL_TEXTURE_MIN_LOD: 1276 res = set_sampler_min_lod(ctx, sampObj, (GLfloat) params[0]); 1277 break; 1278 case GL_TEXTURE_MAX_LOD: 1279 res = set_sampler_max_lod(ctx, sampObj, (GLfloat) params[0]); 1280 break; 1281 case GL_TEXTURE_LOD_BIAS: 1282 res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) params[0]); 1283 break; 1284 case GL_TEXTURE_COMPARE_MODE: 1285 res = set_sampler_compare_mode(ctx, sampObj, params[0]); 1286 break; 1287 case GL_TEXTURE_COMPARE_FUNC: 1288 res = set_sampler_compare_func(ctx, sampObj, params[0]); 1289 break; 1290 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1291 res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) params[0]); 1292 break; 1293 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1294 res = set_sampler_cube_map_seamless(ctx, sampObj, params[0]); 1295 break; 1296 case GL_TEXTURE_SRGB_DECODE_EXT: 1297 res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) params[0]); 1298 break; 1299 case GL_TEXTURE_BORDER_COLOR: 1300 res = set_sampler_border_colorui(ctx, sampObj, params); 1301 break; 1302 default: 1303 res = INVALID_PNAME; 1304 } 1305 1306 switch (res) { 1307 case GL_FALSE: 1308 /* no change */ 1309 break; 1310 case GL_TRUE: 1311 /* state change - we do nothing special at this time */ 1312 break; 1313 case INVALID_PNAME: 1314 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIuiv(pname=%s)\n", 1315 _mesa_enum_to_string(pname)); 1316 break; 1317 case INVALID_PARAM: 1318 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIuiv(param=%u)\n", 1319 params[0]); 1320 break; 1321 case INVALID_VALUE: 1322 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIuiv(param=%u)\n", 1323 params[0]); 1324 break; 1325 default: 1326 ; 1327 } 1328} 1329 1330 1331void GLAPIENTRY 1332_mesa_GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params) 1333{ 1334 struct gl_sampler_object *sampObj; 1335 GET_CURRENT_CONTEXT(ctx); 1336 1337 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 1338 if (!sampObj) { 1339 /* '3.8.2 Sampler Objects' section of the GL-ES 3.0 specification states: 1340 * 1341 * "An INVALID_OPERATION error is generated if sampler is not the name 1342 * of a sampler object previously returned from a call to GenSamplers." 1343 * 1344 * In desktop GL, an GL_INVALID_VALUE is returned instead. 1345 */ 1346 _mesa_error(ctx, (_mesa_is_gles(ctx) ? 1347 GL_INVALID_OPERATION : GL_INVALID_VALUE), 1348 "glGetSamplerParameteriv(sampler %u)", sampler); 1349 return; 1350 } 1351 1352 switch (pname) { 1353 case GL_TEXTURE_WRAP_S: 1354 *params = sampObj->WrapS; 1355 break; 1356 case GL_TEXTURE_WRAP_T: 1357 *params = sampObj->WrapT; 1358 break; 1359 case GL_TEXTURE_WRAP_R: 1360 *params = sampObj->WrapR; 1361 break; 1362 case GL_TEXTURE_MIN_FILTER: 1363 *params = sampObj->MinFilter; 1364 break; 1365 case GL_TEXTURE_MAG_FILTER: 1366 *params = sampObj->MagFilter; 1367 break; 1368 case GL_TEXTURE_MIN_LOD: 1369 /* GL spec 'Data Conversions' section specifies that floating-point 1370 * value in integer Get function is rounded to nearest integer 1371 */ 1372 *params = IROUND(sampObj->MinLod); 1373 break; 1374 case GL_TEXTURE_MAX_LOD: 1375 /* GL spec 'Data Conversions' section specifies that floating-point 1376 * value in integer Get function is rounded to nearest integer 1377 */ 1378 *params = IROUND(sampObj->MaxLod); 1379 break; 1380 case GL_TEXTURE_LOD_BIAS: 1381 /* GL spec 'Data Conversions' section specifies that floating-point 1382 * value in integer Get function is rounded to nearest integer 1383 */ 1384 *params = IROUND(sampObj->LodBias); 1385 break; 1386 case GL_TEXTURE_COMPARE_MODE: 1387 *params = sampObj->CompareMode; 1388 break; 1389 case GL_TEXTURE_COMPARE_FUNC: 1390 *params = sampObj->CompareFunc; 1391 break; 1392 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1393 /* GL spec 'Data Conversions' section specifies that floating-point 1394 * value in integer Get function is rounded to nearest integer 1395 */ 1396 *params = IROUND(sampObj->MaxAnisotropy); 1397 break; 1398 case GL_TEXTURE_BORDER_COLOR: 1399 params[0] = FLOAT_TO_INT(sampObj->BorderColor.f[0]); 1400 params[1] = FLOAT_TO_INT(sampObj->BorderColor.f[1]); 1401 params[2] = FLOAT_TO_INT(sampObj->BorderColor.f[2]); 1402 params[3] = FLOAT_TO_INT(sampObj->BorderColor.f[3]); 1403 break; 1404 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1405 if (!ctx->Extensions.AMD_seamless_cubemap_per_texture) 1406 goto invalid_pname; 1407 *params = sampObj->CubeMapSeamless; 1408 break; 1409 case GL_TEXTURE_SRGB_DECODE_EXT: 1410 if (!ctx->Extensions.EXT_texture_sRGB_decode) 1411 goto invalid_pname; 1412 *params = (GLenum) sampObj->sRGBDecode; 1413 break; 1414 default: 1415 goto invalid_pname; 1416 } 1417 return; 1418 1419invalid_pname: 1420 _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameteriv(pname=%s)", 1421 _mesa_enum_to_string(pname)); 1422} 1423 1424 1425void GLAPIENTRY 1426_mesa_GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params) 1427{ 1428 struct gl_sampler_object *sampObj; 1429 GET_CURRENT_CONTEXT(ctx); 1430 1431 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 1432 if (!sampObj) { 1433 /* '3.8.2 Sampler Objects' section of the GL-ES 3.0 specification states: 1434 * 1435 * "An INVALID_OPERATION error is generated if sampler is not the name 1436 * of a sampler object previously returned from a call to GenSamplers." 1437 * 1438 * In desktop GL, an GL_INVALID_VALUE is returned instead. 1439 */ 1440 _mesa_error(ctx, (_mesa_is_gles(ctx) ? 1441 GL_INVALID_OPERATION : GL_INVALID_VALUE), 1442 "glGetSamplerParameterfv(sampler %u)", sampler); 1443 return; 1444 } 1445 1446 switch (pname) { 1447 case GL_TEXTURE_WRAP_S: 1448 *params = (GLfloat) sampObj->WrapS; 1449 break; 1450 case GL_TEXTURE_WRAP_T: 1451 *params = (GLfloat) sampObj->WrapT; 1452 break; 1453 case GL_TEXTURE_WRAP_R: 1454 *params = (GLfloat) sampObj->WrapR; 1455 break; 1456 case GL_TEXTURE_MIN_FILTER: 1457 *params = (GLfloat) sampObj->MinFilter; 1458 break; 1459 case GL_TEXTURE_MAG_FILTER: 1460 *params = (GLfloat) sampObj->MagFilter; 1461 break; 1462 case GL_TEXTURE_MIN_LOD: 1463 *params = sampObj->MinLod; 1464 break; 1465 case GL_TEXTURE_MAX_LOD: 1466 *params = sampObj->MaxLod; 1467 break; 1468 case GL_TEXTURE_LOD_BIAS: 1469 *params = sampObj->LodBias; 1470 break; 1471 case GL_TEXTURE_COMPARE_MODE: 1472 *params = (GLfloat) sampObj->CompareMode; 1473 break; 1474 case GL_TEXTURE_COMPARE_FUNC: 1475 *params = (GLfloat) sampObj->CompareFunc; 1476 break; 1477 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1478 *params = sampObj->MaxAnisotropy; 1479 break; 1480 case GL_TEXTURE_BORDER_COLOR: 1481 params[0] = sampObj->BorderColor.f[0]; 1482 params[1] = sampObj->BorderColor.f[1]; 1483 params[2] = sampObj->BorderColor.f[2]; 1484 params[3] = sampObj->BorderColor.f[3]; 1485 break; 1486 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1487 if (!ctx->Extensions.AMD_seamless_cubemap_per_texture) 1488 goto invalid_pname; 1489 *params = (GLfloat) sampObj->CubeMapSeamless; 1490 break; 1491 case GL_TEXTURE_SRGB_DECODE_EXT: 1492 if (!ctx->Extensions.EXT_texture_sRGB_decode) 1493 goto invalid_pname; 1494 *params = (GLfloat) sampObj->sRGBDecode; 1495 break; 1496 default: 1497 goto invalid_pname; 1498 } 1499 return; 1500 1501invalid_pname: 1502 _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameterfv(pname=%s)", 1503 _mesa_enum_to_string(pname)); 1504} 1505 1506 1507void GLAPIENTRY 1508_mesa_GetSamplerParameterIiv(GLuint sampler, GLenum pname, GLint *params) 1509{ 1510 struct gl_sampler_object *sampObj; 1511 GET_CURRENT_CONTEXT(ctx); 1512 1513 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 1514 if (!sampObj) { 1515 _mesa_error(ctx, GL_INVALID_VALUE, 1516 "glGetSamplerParameterIiv(sampler %u)", 1517 sampler); 1518 return; 1519 } 1520 1521 switch (pname) { 1522 case GL_TEXTURE_WRAP_S: 1523 *params = sampObj->WrapS; 1524 break; 1525 case GL_TEXTURE_WRAP_T: 1526 *params = sampObj->WrapT; 1527 break; 1528 case GL_TEXTURE_WRAP_R: 1529 *params = sampObj->WrapR; 1530 break; 1531 case GL_TEXTURE_MIN_FILTER: 1532 *params = sampObj->MinFilter; 1533 break; 1534 case GL_TEXTURE_MAG_FILTER: 1535 *params = sampObj->MagFilter; 1536 break; 1537 case GL_TEXTURE_MIN_LOD: 1538 *params = (GLint) sampObj->MinLod; 1539 break; 1540 case GL_TEXTURE_MAX_LOD: 1541 *params = (GLint) sampObj->MaxLod; 1542 break; 1543 case GL_TEXTURE_LOD_BIAS: 1544 *params = (GLint) sampObj->LodBias; 1545 break; 1546 case GL_TEXTURE_COMPARE_MODE: 1547 *params = sampObj->CompareMode; 1548 break; 1549 case GL_TEXTURE_COMPARE_FUNC: 1550 *params = sampObj->CompareFunc; 1551 break; 1552 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1553 *params = (GLint) sampObj->MaxAnisotropy; 1554 break; 1555 case GL_TEXTURE_BORDER_COLOR: 1556 params[0] = sampObj->BorderColor.i[0]; 1557 params[1] = sampObj->BorderColor.i[1]; 1558 params[2] = sampObj->BorderColor.i[2]; 1559 params[3] = sampObj->BorderColor.i[3]; 1560 break; 1561 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1562 if (!ctx->Extensions.AMD_seamless_cubemap_per_texture) 1563 goto invalid_pname; 1564 *params = sampObj->CubeMapSeamless; 1565 break; 1566 case GL_TEXTURE_SRGB_DECODE_EXT: 1567 if (!ctx->Extensions.EXT_texture_sRGB_decode) 1568 goto invalid_pname; 1569 *params = (GLenum) sampObj->sRGBDecode; 1570 break; 1571 default: 1572 goto invalid_pname; 1573 } 1574 return; 1575 1576invalid_pname: 1577 _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameterIiv(pname=%s)", 1578 _mesa_enum_to_string(pname)); 1579} 1580 1581 1582void GLAPIENTRY 1583_mesa_GetSamplerParameterIuiv(GLuint sampler, GLenum pname, GLuint *params) 1584{ 1585 struct gl_sampler_object *sampObj; 1586 GET_CURRENT_CONTEXT(ctx); 1587 1588 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 1589 if (!sampObj) { 1590 _mesa_error(ctx, GL_INVALID_VALUE, 1591 "glGetSamplerParameterIuiv(sampler %u)", 1592 sampler); 1593 return; 1594 } 1595 1596 switch (pname) { 1597 case GL_TEXTURE_WRAP_S: 1598 *params = sampObj->WrapS; 1599 break; 1600 case GL_TEXTURE_WRAP_T: 1601 *params = sampObj->WrapT; 1602 break; 1603 case GL_TEXTURE_WRAP_R: 1604 *params = sampObj->WrapR; 1605 break; 1606 case GL_TEXTURE_MIN_FILTER: 1607 *params = sampObj->MinFilter; 1608 break; 1609 case GL_TEXTURE_MAG_FILTER: 1610 *params = sampObj->MagFilter; 1611 break; 1612 case GL_TEXTURE_MIN_LOD: 1613 *params = (GLuint) sampObj->MinLod; 1614 break; 1615 case GL_TEXTURE_MAX_LOD: 1616 *params = (GLuint) sampObj->MaxLod; 1617 break; 1618 case GL_TEXTURE_LOD_BIAS: 1619 *params = (GLuint) sampObj->LodBias; 1620 break; 1621 case GL_TEXTURE_COMPARE_MODE: 1622 *params = sampObj->CompareMode; 1623 break; 1624 case GL_TEXTURE_COMPARE_FUNC: 1625 *params = sampObj->CompareFunc; 1626 break; 1627 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1628 *params = (GLuint) sampObj->MaxAnisotropy; 1629 break; 1630 case GL_TEXTURE_BORDER_COLOR: 1631 params[0] = sampObj->BorderColor.ui[0]; 1632 params[1] = sampObj->BorderColor.ui[1]; 1633 params[2] = sampObj->BorderColor.ui[2]; 1634 params[3] = sampObj->BorderColor.ui[3]; 1635 break; 1636 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1637 if (!ctx->Extensions.AMD_seamless_cubemap_per_texture) 1638 goto invalid_pname; 1639 *params = sampObj->CubeMapSeamless; 1640 break; 1641 case GL_TEXTURE_SRGB_DECODE_EXT: 1642 if (!ctx->Extensions.EXT_texture_sRGB_decode) 1643 goto invalid_pname; 1644 *params = (GLenum) sampObj->sRGBDecode; 1645 break; 1646 default: 1647 goto invalid_pname; 1648 } 1649 return; 1650 1651invalid_pname: 1652 _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameterIuiv(pname=%s)", 1653 _mesa_enum_to_string(pname)); 1654} 1655 1656 1657void 1658_mesa_init_sampler_object_functions(struct dd_function_table *driver) 1659{ 1660 driver->NewSamplerObject = _mesa_new_sampler_object; 1661} 1662