samplerobj.c revision adb4b31bc33fda284319819877312f9e8631b657
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 273void 274_mesa_bind_sampler(struct gl_context *ctx, GLuint unit, 275 struct gl_sampler_object *sampObj) 276{ 277 if (ctx->Texture.Unit[unit].Sampler != sampObj) { 278 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 279 } 280 281 _mesa_reference_sampler_object(ctx, &ctx->Texture.Unit[unit].Sampler, 282 sampObj); 283} 284 285void GLAPIENTRY 286_mesa_BindSampler(GLuint unit, GLuint sampler) 287{ 288 struct gl_sampler_object *sampObj; 289 GET_CURRENT_CONTEXT(ctx); 290 291 if (unit >= ctx->Const.MaxCombinedTextureImageUnits) { 292 _mesa_error(ctx, GL_INVALID_VALUE, "glBindSampler(unit %u)", unit); 293 return; 294 } 295 296 if (sampler == 0) { 297 /* Use the default sampler object, the one contained in the texture 298 * object. 299 */ 300 sampObj = NULL; 301 } 302 else { 303 /* user-defined sampler object */ 304 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 305 if (!sampObj) { 306 _mesa_error(ctx, GL_INVALID_OPERATION, "glBindSampler(sampler)"); 307 return; 308 } 309 } 310 311 /* bind new sampler */ 312 _mesa_bind_sampler(ctx, unit, sampObj); 313} 314 315 316void GLAPIENTRY 317_mesa_BindSamplers(GLuint first, GLsizei count, const GLuint *samplers) 318{ 319 GET_CURRENT_CONTEXT(ctx); 320 GLint i; 321 322 /* The ARB_multi_bind spec says: 323 * 324 * "An INVALID_OPERATION error is generated if <first> + <count> is 325 * greater than the number of texture image units supported by 326 * the implementation." 327 */ 328 if (first + count > ctx->Const.MaxCombinedTextureImageUnits) { 329 _mesa_error(ctx, GL_INVALID_OPERATION, 330 "glBindSamplers(first=%u + count=%d > the value of " 331 "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS=%u)", 332 first, count, ctx->Const.MaxCombinedTextureImageUnits); 333 return; 334 } 335 336 FLUSH_VERTICES(ctx, 0); 337 338 if (samplers) { 339 /* Note that the error semantics for multi-bind commands differ from 340 * those of other GL commands. 341 * 342 * The Issues section in the ARB_multi_bind spec says: 343 * 344 * "(11) Typically, OpenGL specifies that if an error is generated by 345 * a command, that command has no effect. This is somewhat 346 * unfortunate for multi-bind commands, because it would require 347 * a first pass to scan the entire list of bound objects for 348 * errors and then a second pass to actually perform the 349 * bindings. Should we have different error semantics? 350 * 351 * RESOLVED: Yes. In this specification, when the parameters for 352 * one of the <count> binding points are invalid, that binding 353 * point is not updated and an error will be generated. However, 354 * other binding points in the same command will be updated if 355 * their parameters are valid and no other error occurs." 356 */ 357 358 begin_samplerobj_lookups(ctx); 359 360 for (i = 0; i < count; i++) { 361 const GLuint unit = first + i; 362 struct gl_sampler_object * const currentSampler = 363 ctx->Texture.Unit[unit].Sampler; 364 struct gl_sampler_object *sampObj; 365 366 if (samplers[i] != 0) { 367 if (currentSampler && currentSampler->Name == samplers[i]) 368 sampObj = currentSampler; 369 else 370 sampObj = lookup_samplerobj_locked(ctx, samplers[i]); 371 372 /* The ARB_multi_bind spec says: 373 * 374 * "An INVALID_OPERATION error is generated if any value 375 * in <samplers> is not zero or the name of an existing 376 * sampler object (per binding)." 377 */ 378 if (!sampObj) { 379 _mesa_error(ctx, GL_INVALID_OPERATION, 380 "glBindSamplers(samplers[%d]=%u is not zero or " 381 "the name of an existing sampler object)", 382 i, samplers[i]); 383 continue; 384 } 385 } else { 386 sampObj = NULL; 387 } 388 389 /* Bind the new sampler */ 390 if (sampObj != currentSampler) { 391 _mesa_reference_sampler_object(ctx, 392 &ctx->Texture.Unit[unit].Sampler, 393 sampObj); 394 ctx->NewState |= _NEW_TEXTURE; 395 } 396 } 397 398 end_samplerobj_lookups(ctx); 399 } else { 400 /* Unbind all samplers in the range <first> through <first>+<count>-1 */ 401 for (i = 0; i < count; i++) { 402 const GLuint unit = first + i; 403 404 if (ctx->Texture.Unit[unit].Sampler) { 405 _mesa_reference_sampler_object(ctx, 406 &ctx->Texture.Unit[unit].Sampler, 407 NULL); 408 ctx->NewState |= _NEW_TEXTURE; 409 } 410 } 411 } 412} 413 414 415/** 416 * Check if a coordinate wrap mode is legal. 417 * \return GL_TRUE if legal, GL_FALSE otherwise 418 */ 419static GLboolean 420validate_texture_wrap_mode(struct gl_context *ctx, GLenum wrap) 421{ 422 const struct gl_extensions * const e = &ctx->Extensions; 423 424 switch (wrap) { 425 case GL_CLAMP: 426 case GL_CLAMP_TO_EDGE: 427 case GL_REPEAT: 428 case GL_MIRRORED_REPEAT: 429 return GL_TRUE; 430 case GL_CLAMP_TO_BORDER: 431 return e->ARB_texture_border_clamp; 432 case GL_MIRROR_CLAMP_EXT: 433 return e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp; 434 case GL_MIRROR_CLAMP_TO_EDGE_EXT: 435 return e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp || e->ARB_texture_mirror_clamp_to_edge; 436 case GL_MIRROR_CLAMP_TO_BORDER_EXT: 437 return e->EXT_texture_mirror_clamp; 438 default: 439 return GL_FALSE; 440 } 441} 442 443 444/** 445 * This is called just prior to changing any sampler object state. 446 */ 447static inline void 448flush(struct gl_context *ctx) 449{ 450 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 451} 452 453void 454_mesa_set_sampler_wrap(struct gl_context *ctx, struct gl_sampler_object *samp, 455 GLenum s, GLenum t, GLenum r) 456{ 457 assert(validate_texture_wrap_mode(ctx, s)); 458 assert(validate_texture_wrap_mode(ctx, t)); 459 assert(validate_texture_wrap_mode(ctx, r)); 460 461 if (samp->WrapS == s && samp->WrapT == t && samp->WrapR == r) 462 return; 463 464 flush(ctx); 465 samp->WrapS = s; 466 samp->WrapT = t; 467 samp->WrapR = r; 468} 469 470#define INVALID_PARAM 0x100 471#define INVALID_PNAME 0x101 472#define INVALID_VALUE 0x102 473 474static GLuint 475set_sampler_wrap_s(struct gl_context *ctx, struct gl_sampler_object *samp, 476 GLint param) 477{ 478 if (samp->WrapS == param) 479 return GL_FALSE; 480 if (validate_texture_wrap_mode(ctx, param)) { 481 flush(ctx); 482 samp->WrapS = param; 483 return GL_TRUE; 484 } 485 return INVALID_PARAM; 486} 487 488 489static GLuint 490set_sampler_wrap_t(struct gl_context *ctx, struct gl_sampler_object *samp, 491 GLint param) 492{ 493 if (samp->WrapT == param) 494 return GL_FALSE; 495 if (validate_texture_wrap_mode(ctx, param)) { 496 flush(ctx); 497 samp->WrapT = param; 498 return GL_TRUE; 499 } 500 return INVALID_PARAM; 501} 502 503 504static GLuint 505set_sampler_wrap_r(struct gl_context *ctx, struct gl_sampler_object *samp, 506 GLint param) 507{ 508 if (samp->WrapR == param) 509 return GL_FALSE; 510 if (validate_texture_wrap_mode(ctx, param)) { 511 flush(ctx); 512 samp->WrapR = param; 513 return GL_TRUE; 514 } 515 return INVALID_PARAM; 516} 517 518void 519_mesa_set_sampler_filters(struct gl_context *ctx, 520 struct gl_sampler_object *samp, 521 GLenum min_filter, GLenum mag_filter) 522{ 523 assert(min_filter == GL_NEAREST || 524 min_filter == GL_LINEAR || 525 min_filter == GL_NEAREST_MIPMAP_NEAREST || 526 min_filter == GL_LINEAR_MIPMAP_NEAREST || 527 min_filter == GL_NEAREST_MIPMAP_LINEAR || 528 min_filter == GL_LINEAR_MIPMAP_LINEAR); 529 assert(mag_filter == GL_NEAREST || 530 mag_filter == GL_LINEAR); 531 532 if (samp->MinFilter == min_filter && samp->MagFilter == mag_filter) 533 return; 534 535 flush(ctx); 536 samp->MinFilter = min_filter; 537 samp->MagFilter = mag_filter; 538} 539 540static GLuint 541set_sampler_min_filter(struct gl_context *ctx, struct gl_sampler_object *samp, 542 GLint param) 543{ 544 if (samp->MinFilter == param) 545 return GL_FALSE; 546 547 switch (param) { 548 case GL_NEAREST: 549 case GL_LINEAR: 550 case GL_NEAREST_MIPMAP_NEAREST: 551 case GL_LINEAR_MIPMAP_NEAREST: 552 case GL_NEAREST_MIPMAP_LINEAR: 553 case GL_LINEAR_MIPMAP_LINEAR: 554 flush(ctx); 555 samp->MinFilter = param; 556 return GL_TRUE; 557 default: 558 return INVALID_PARAM; 559 } 560} 561 562 563static GLuint 564set_sampler_mag_filter(struct gl_context *ctx, struct gl_sampler_object *samp, 565 GLint param) 566{ 567 if (samp->MagFilter == param) 568 return GL_FALSE; 569 570 switch (param) { 571 case GL_NEAREST: 572 case GL_LINEAR: 573 flush(ctx); 574 samp->MagFilter = param; 575 return GL_TRUE; 576 default: 577 return INVALID_PARAM; 578 } 579} 580 581 582static GLuint 583set_sampler_lod_bias(struct gl_context *ctx, struct gl_sampler_object *samp, 584 GLfloat param) 585{ 586 if (samp->LodBias == param) 587 return GL_FALSE; 588 589 flush(ctx); 590 samp->LodBias = param; 591 return GL_TRUE; 592} 593 594 595static GLuint 596set_sampler_border_colorf(struct gl_context *ctx, 597 struct gl_sampler_object *samp, 598 const GLfloat params[4]) 599{ 600 flush(ctx); 601 samp->BorderColor.f[RCOMP] = params[0]; 602 samp->BorderColor.f[GCOMP] = params[1]; 603 samp->BorderColor.f[BCOMP] = params[2]; 604 samp->BorderColor.f[ACOMP] = params[3]; 605 return GL_TRUE; 606} 607 608 609static GLuint 610set_sampler_border_colori(struct gl_context *ctx, 611 struct gl_sampler_object *samp, 612 const GLint params[4]) 613{ 614 flush(ctx); 615 samp->BorderColor.i[RCOMP] = params[0]; 616 samp->BorderColor.i[GCOMP] = params[1]; 617 samp->BorderColor.i[BCOMP] = params[2]; 618 samp->BorderColor.i[ACOMP] = params[3]; 619 return GL_TRUE; 620} 621 622 623static GLuint 624set_sampler_border_colorui(struct gl_context *ctx, 625 struct gl_sampler_object *samp, 626 const GLuint params[4]) 627{ 628 flush(ctx); 629 samp->BorderColor.ui[RCOMP] = params[0]; 630 samp->BorderColor.ui[GCOMP] = params[1]; 631 samp->BorderColor.ui[BCOMP] = params[2]; 632 samp->BorderColor.ui[ACOMP] = params[3]; 633 return GL_TRUE; 634} 635 636 637static GLuint 638set_sampler_min_lod(struct gl_context *ctx, struct gl_sampler_object *samp, 639 GLfloat param) 640{ 641 if (samp->MinLod == param) 642 return GL_FALSE; 643 644 flush(ctx); 645 samp->MinLod = param; 646 return GL_TRUE; 647} 648 649 650static GLuint 651set_sampler_max_lod(struct gl_context *ctx, struct gl_sampler_object *samp, 652 GLfloat param) 653{ 654 if (samp->MaxLod == param) 655 return GL_FALSE; 656 657 flush(ctx); 658 samp->MaxLod = param; 659 return GL_TRUE; 660} 661 662 663static GLuint 664set_sampler_compare_mode(struct gl_context *ctx, 665 struct gl_sampler_object *samp, GLint param) 666{ 667 /* If GL_ARB_shadow is not supported, don't report an error. The 668 * sampler object extension spec isn't clear on this extension interaction. 669 * Silences errors with Wine on older GPUs such as R200. 670 */ 671 if (!ctx->Extensions.ARB_shadow) 672 return GL_FALSE; 673 674 if (samp->CompareMode == param) 675 return GL_FALSE; 676 677 if (param == GL_NONE || 678 param == GL_COMPARE_R_TO_TEXTURE_ARB) { 679 flush(ctx); 680 samp->CompareMode = param; 681 return GL_TRUE; 682 } 683 684 return INVALID_PARAM; 685} 686 687 688static GLuint 689set_sampler_compare_func(struct gl_context *ctx, 690 struct gl_sampler_object *samp, GLint param) 691{ 692 /* If GL_ARB_shadow is not supported, don't report an error. The 693 * sampler object extension spec isn't clear on this extension interaction. 694 * Silences errors with Wine on older GPUs such as R200. 695 */ 696 if (!ctx->Extensions.ARB_shadow) 697 return GL_FALSE; 698 699 if (samp->CompareFunc == param) 700 return GL_FALSE; 701 702 switch (param) { 703 case GL_LEQUAL: 704 case GL_GEQUAL: 705 case GL_EQUAL: 706 case GL_NOTEQUAL: 707 case GL_LESS: 708 case GL_GREATER: 709 case GL_ALWAYS: 710 case GL_NEVER: 711 flush(ctx); 712 samp->CompareFunc = param; 713 return GL_TRUE; 714 default: 715 return INVALID_PARAM; 716 } 717} 718 719 720static GLuint 721set_sampler_max_anisotropy(struct gl_context *ctx, 722 struct gl_sampler_object *samp, GLfloat param) 723{ 724 if (!ctx->Extensions.EXT_texture_filter_anisotropic) 725 return INVALID_PNAME; 726 727 if (samp->MaxAnisotropy == param) 728 return GL_FALSE; 729 730 if (param < 1.0F) 731 return INVALID_VALUE; 732 733 flush(ctx); 734 /* clamp to max, that's what NVIDIA does */ 735 samp->MaxAnisotropy = MIN2(param, ctx->Const.MaxTextureMaxAnisotropy); 736 return GL_TRUE; 737} 738 739 740static GLuint 741set_sampler_cube_map_seamless(struct gl_context *ctx, 742 struct gl_sampler_object *samp, GLboolean param) 743{ 744 if (!_mesa_is_desktop_gl(ctx) 745 || !ctx->Extensions.AMD_seamless_cubemap_per_texture) 746 return INVALID_PNAME; 747 748 if (samp->CubeMapSeamless == param) 749 return GL_FALSE; 750 751 if (param != GL_TRUE && param != GL_FALSE) 752 return INVALID_VALUE; 753 754 flush(ctx); 755 samp->CubeMapSeamless = param; 756 return GL_TRUE; 757} 758 759void 760_mesa_set_sampler_srgb_decode(struct gl_context *ctx, 761 struct gl_sampler_object *samp, GLenum param) 762{ 763 assert(param == GL_DECODE_EXT || param == GL_SKIP_DECODE_EXT); 764 765 flush(ctx); 766 samp->sRGBDecode = param; 767} 768 769static GLuint 770set_sampler_srgb_decode(struct gl_context *ctx, 771 struct gl_sampler_object *samp, GLenum param) 772{ 773 if (!ctx->Extensions.EXT_texture_sRGB_decode) 774 return INVALID_PNAME; 775 776 if (samp->sRGBDecode == param) 777 return GL_FALSE; 778 779 if (param != GL_DECODE_EXT && param != GL_SKIP_DECODE_EXT) 780 return INVALID_VALUE; 781 782 flush(ctx); 783 samp->sRGBDecode = param; 784 return GL_TRUE; 785} 786 787void GLAPIENTRY 788_mesa_SamplerParameteri(GLuint sampler, GLenum pname, GLint param) 789{ 790 struct gl_sampler_object *sampObj; 791 GLuint res; 792 GET_CURRENT_CONTEXT(ctx); 793 794 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 795 if (!sampObj) { 796 /* '3.8.2 Sampler Objects' section of the GL-ES 3.0 specification states: 797 * 798 * "An INVALID_OPERATION error is generated if sampler is not the name 799 * of a sampler object previously returned from a call to GenSamplers." 800 * 801 * In desktop GL, an GL_INVALID_VALUE is returned instead. 802 */ 803 _mesa_error(ctx, (_mesa_is_gles(ctx) ? 804 GL_INVALID_OPERATION : GL_INVALID_VALUE), 805 "glSamplerParameteri(sampler %u)", sampler); 806 return; 807 } 808 809 switch (pname) { 810 case GL_TEXTURE_WRAP_S: 811 res = set_sampler_wrap_s(ctx, sampObj, param); 812 break; 813 case GL_TEXTURE_WRAP_T: 814 res = set_sampler_wrap_t(ctx, sampObj, param); 815 break; 816 case GL_TEXTURE_WRAP_R: 817 res = set_sampler_wrap_r(ctx, sampObj, param); 818 break; 819 case GL_TEXTURE_MIN_FILTER: 820 res = set_sampler_min_filter(ctx, sampObj, param); 821 break; 822 case GL_TEXTURE_MAG_FILTER: 823 res = set_sampler_mag_filter(ctx, sampObj, param); 824 break; 825 case GL_TEXTURE_MIN_LOD: 826 res = set_sampler_min_lod(ctx, sampObj, (GLfloat) param); 827 break; 828 case GL_TEXTURE_MAX_LOD: 829 res = set_sampler_max_lod(ctx, sampObj, (GLfloat) param); 830 break; 831 case GL_TEXTURE_LOD_BIAS: 832 res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) param); 833 break; 834 case GL_TEXTURE_COMPARE_MODE: 835 res = set_sampler_compare_mode(ctx, sampObj, param); 836 break; 837 case GL_TEXTURE_COMPARE_FUNC: 838 res = set_sampler_compare_func(ctx, sampObj, param); 839 break; 840 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 841 res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) param); 842 break; 843 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 844 res = set_sampler_cube_map_seamless(ctx, sampObj, param); 845 break; 846 case GL_TEXTURE_SRGB_DECODE_EXT: 847 res = set_sampler_srgb_decode(ctx, sampObj, param); 848 break; 849 case GL_TEXTURE_BORDER_COLOR: 850 /* fall-through */ 851 default: 852 res = INVALID_PNAME; 853 } 854 855 switch (res) { 856 case GL_FALSE: 857 /* no change */ 858 break; 859 case GL_TRUE: 860 /* state change - we do nothing special at this time */ 861 break; 862 case INVALID_PNAME: 863 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteri(pname=%s)\n", 864 _mesa_enum_to_string(pname)); 865 break; 866 case INVALID_PARAM: 867 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteri(param=%d)\n", 868 param); 869 break; 870 case INVALID_VALUE: 871 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameteri(param=%d)\n", 872 param); 873 break; 874 default: 875 ; 876 } 877} 878 879 880void GLAPIENTRY 881_mesa_SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) 882{ 883 struct gl_sampler_object *sampObj; 884 GLuint res; 885 GET_CURRENT_CONTEXT(ctx); 886 887 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 888 if (!sampObj) { 889 /* '3.8.2 Sampler Objects' section of the GL-ES 3.0 specification states: 890 * 891 * "An INVALID_OPERATION error is generated if sampler is not the name 892 * of a sampler object previously returned from a call to GenSamplers." 893 * 894 * In desktop GL, an GL_INVALID_VALUE is returned instead. 895 */ 896 _mesa_error(ctx, (_mesa_is_gles(ctx) ? 897 GL_INVALID_OPERATION : GL_INVALID_VALUE), 898 "glSamplerParameterf(sampler %u)", sampler); 899 return; 900 } 901 902 switch (pname) { 903 case GL_TEXTURE_WRAP_S: 904 res = set_sampler_wrap_s(ctx, sampObj, (GLint) param); 905 break; 906 case GL_TEXTURE_WRAP_T: 907 res = set_sampler_wrap_t(ctx, sampObj, (GLint) param); 908 break; 909 case GL_TEXTURE_WRAP_R: 910 res = set_sampler_wrap_r(ctx, sampObj, (GLint) param); 911 break; 912 case GL_TEXTURE_MIN_FILTER: 913 res = set_sampler_min_filter(ctx, sampObj, (GLint) param); 914 break; 915 case GL_TEXTURE_MAG_FILTER: 916 res = set_sampler_mag_filter(ctx, sampObj, (GLint) param); 917 break; 918 case GL_TEXTURE_MIN_LOD: 919 res = set_sampler_min_lod(ctx, sampObj, param); 920 break; 921 case GL_TEXTURE_MAX_LOD: 922 res = set_sampler_max_lod(ctx, sampObj, param); 923 break; 924 case GL_TEXTURE_LOD_BIAS: 925 res = set_sampler_lod_bias(ctx, sampObj, param); 926 break; 927 case GL_TEXTURE_COMPARE_MODE: 928 res = set_sampler_compare_mode(ctx, sampObj, (GLint) param); 929 break; 930 case GL_TEXTURE_COMPARE_FUNC: 931 res = set_sampler_compare_func(ctx, sampObj, (GLint) param); 932 break; 933 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 934 res = set_sampler_max_anisotropy(ctx, sampObj, param); 935 break; 936 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 937 res = set_sampler_cube_map_seamless(ctx, sampObj, (GLboolean) param); 938 break; 939 case GL_TEXTURE_SRGB_DECODE_EXT: 940 res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) param); 941 break; 942 case GL_TEXTURE_BORDER_COLOR: 943 /* fall-through */ 944 default: 945 res = INVALID_PNAME; 946 } 947 948 switch (res) { 949 case GL_FALSE: 950 /* no change */ 951 break; 952 case GL_TRUE: 953 /* state change - we do nothing special at this time */ 954 break; 955 case INVALID_PNAME: 956 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterf(pname=%s)\n", 957 _mesa_enum_to_string(pname)); 958 break; 959 case INVALID_PARAM: 960 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterf(param=%f)\n", 961 param); 962 break; 963 case INVALID_VALUE: 964 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterf(param=%f)\n", 965 param); 966 break; 967 default: 968 ; 969 } 970} 971 972void GLAPIENTRY 973_mesa_SamplerParameteriv(GLuint sampler, GLenum pname, const GLint *params) 974{ 975 struct gl_sampler_object *sampObj; 976 GLuint res; 977 GET_CURRENT_CONTEXT(ctx); 978 979 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 980 if (!sampObj) { 981 /* '3.8.2 Sampler Objects' section of the GL-ES 3.0 specification states: 982 * 983 * "An INVALID_OPERATION error is generated if sampler is not the name 984 * of a sampler object previously returned from a call to GenSamplers." 985 * 986 * In desktop GL, an GL_INVALID_VALUE is returned instead. 987 */ 988 _mesa_error(ctx, (_mesa_is_gles(ctx) ? 989 GL_INVALID_OPERATION : GL_INVALID_VALUE), 990 "glSamplerParameteriv(sampler %u)", sampler); 991 return; 992 } 993 994 switch (pname) { 995 case GL_TEXTURE_WRAP_S: 996 res = set_sampler_wrap_s(ctx, sampObj, params[0]); 997 break; 998 case GL_TEXTURE_WRAP_T: 999 res = set_sampler_wrap_t(ctx, sampObj, params[0]); 1000 break; 1001 case GL_TEXTURE_WRAP_R: 1002 res = set_sampler_wrap_r(ctx, sampObj, params[0]); 1003 break; 1004 case GL_TEXTURE_MIN_FILTER: 1005 res = set_sampler_min_filter(ctx, sampObj, params[0]); 1006 break; 1007 case GL_TEXTURE_MAG_FILTER: 1008 res = set_sampler_mag_filter(ctx, sampObj, params[0]); 1009 break; 1010 case GL_TEXTURE_MIN_LOD: 1011 res = set_sampler_min_lod(ctx, sampObj, (GLfloat) params[0]); 1012 break; 1013 case GL_TEXTURE_MAX_LOD: 1014 res = set_sampler_max_lod(ctx, sampObj, (GLfloat) params[0]); 1015 break; 1016 case GL_TEXTURE_LOD_BIAS: 1017 res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) params[0]); 1018 break; 1019 case GL_TEXTURE_COMPARE_MODE: 1020 res = set_sampler_compare_mode(ctx, sampObj, params[0]); 1021 break; 1022 case GL_TEXTURE_COMPARE_FUNC: 1023 res = set_sampler_compare_func(ctx, sampObj, params[0]); 1024 break; 1025 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1026 res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) params[0]); 1027 break; 1028 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1029 res = set_sampler_cube_map_seamless(ctx, sampObj, params[0]); 1030 break; 1031 case GL_TEXTURE_SRGB_DECODE_EXT: 1032 res = set_sampler_srgb_decode(ctx, sampObj, params[0]); 1033 break; 1034 case GL_TEXTURE_BORDER_COLOR: 1035 { 1036 GLfloat c[4]; 1037 c[0] = INT_TO_FLOAT(params[0]); 1038 c[1] = INT_TO_FLOAT(params[1]); 1039 c[2] = INT_TO_FLOAT(params[2]); 1040 c[3] = INT_TO_FLOAT(params[3]); 1041 res = set_sampler_border_colorf(ctx, sampObj, c); 1042 } 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, "glSamplerParameteriv(pname=%s)\n", 1057 _mesa_enum_to_string(pname)); 1058 break; 1059 case INVALID_PARAM: 1060 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteriv(param=%d)\n", 1061 params[0]); 1062 break; 1063 case INVALID_VALUE: 1064 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameteriv(param=%d)\n", 1065 params[0]); 1066 break; 1067 default: 1068 ; 1069 } 1070} 1071 1072void GLAPIENTRY 1073_mesa_SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *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 /* '3.8.2 Sampler Objects' section of the GL-ES 3.0 specification states: 1082 * 1083 * "An INVALID_OPERATION error is generated if sampler is not the name 1084 * of a sampler object previously returned from a call to GenSamplers." 1085 * 1086 * In desktop GL, an GL_INVALID_VALUE is returned instead. 1087 */ 1088 _mesa_error(ctx, (_mesa_is_gles(ctx) ? 1089 GL_INVALID_OPERATION : GL_INVALID_VALUE), 1090 "glSamplerParameterfv(sampler %u)", sampler); 1091 return; 1092 } 1093 1094 switch (pname) { 1095 case GL_TEXTURE_WRAP_S: 1096 res = set_sampler_wrap_s(ctx, sampObj, (GLint) params[0]); 1097 break; 1098 case GL_TEXTURE_WRAP_T: 1099 res = set_sampler_wrap_t(ctx, sampObj, (GLint) params[0]); 1100 break; 1101 case GL_TEXTURE_WRAP_R: 1102 res = set_sampler_wrap_r(ctx, sampObj, (GLint) params[0]); 1103 break; 1104 case GL_TEXTURE_MIN_FILTER: 1105 res = set_sampler_min_filter(ctx, sampObj, (GLint) params[0]); 1106 break; 1107 case GL_TEXTURE_MAG_FILTER: 1108 res = set_sampler_mag_filter(ctx, sampObj, (GLint) params[0]); 1109 break; 1110 case GL_TEXTURE_MIN_LOD: 1111 res = set_sampler_min_lod(ctx, sampObj, params[0]); 1112 break; 1113 case GL_TEXTURE_MAX_LOD: 1114 res = set_sampler_max_lod(ctx, sampObj, params[0]); 1115 break; 1116 case GL_TEXTURE_LOD_BIAS: 1117 res = set_sampler_lod_bias(ctx, sampObj, params[0]); 1118 break; 1119 case GL_TEXTURE_COMPARE_MODE: 1120 res = set_sampler_compare_mode(ctx, sampObj, (GLint) params[0]); 1121 break; 1122 case GL_TEXTURE_COMPARE_FUNC: 1123 res = set_sampler_compare_func(ctx, sampObj, (GLint) params[0]); 1124 break; 1125 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1126 res = set_sampler_max_anisotropy(ctx, sampObj, params[0]); 1127 break; 1128 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1129 res = set_sampler_cube_map_seamless(ctx, sampObj, (GLboolean) params[0]); 1130 break; 1131 case GL_TEXTURE_SRGB_DECODE_EXT: 1132 res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) params[0]); 1133 break; 1134 case GL_TEXTURE_BORDER_COLOR: 1135 res = set_sampler_border_colorf(ctx, sampObj, params); 1136 break; 1137 default: 1138 res = INVALID_PNAME; 1139 } 1140 1141 switch (res) { 1142 case GL_FALSE: 1143 /* no change */ 1144 break; 1145 case GL_TRUE: 1146 /* state change - we do nothing special at this time */ 1147 break; 1148 case INVALID_PNAME: 1149 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterfv(pname=%s)\n", 1150 _mesa_enum_to_string(pname)); 1151 break; 1152 case INVALID_PARAM: 1153 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterfv(param=%f)\n", 1154 params[0]); 1155 break; 1156 case INVALID_VALUE: 1157 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterfv(param=%f)\n", 1158 params[0]); 1159 break; 1160 default: 1161 ; 1162 } 1163} 1164 1165void GLAPIENTRY 1166_mesa_SamplerParameterIiv(GLuint sampler, GLenum pname, const GLint *params) 1167{ 1168 struct gl_sampler_object *sampObj; 1169 GLuint res; 1170 GET_CURRENT_CONTEXT(ctx); 1171 1172 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 1173 if (!sampObj) { 1174 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIiv(sampler %u)", 1175 sampler); 1176 return; 1177 } 1178 1179 switch (pname) { 1180 case GL_TEXTURE_WRAP_S: 1181 res = set_sampler_wrap_s(ctx, sampObj, params[0]); 1182 break; 1183 case GL_TEXTURE_WRAP_T: 1184 res = set_sampler_wrap_t(ctx, sampObj, params[0]); 1185 break; 1186 case GL_TEXTURE_WRAP_R: 1187 res = set_sampler_wrap_r(ctx, sampObj, params[0]); 1188 break; 1189 case GL_TEXTURE_MIN_FILTER: 1190 res = set_sampler_min_filter(ctx, sampObj, params[0]); 1191 break; 1192 case GL_TEXTURE_MAG_FILTER: 1193 res = set_sampler_mag_filter(ctx, sampObj, params[0]); 1194 break; 1195 case GL_TEXTURE_MIN_LOD: 1196 res = set_sampler_min_lod(ctx, sampObj, (GLfloat) params[0]); 1197 break; 1198 case GL_TEXTURE_MAX_LOD: 1199 res = set_sampler_max_lod(ctx, sampObj, (GLfloat) params[0]); 1200 break; 1201 case GL_TEXTURE_LOD_BIAS: 1202 res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) params[0]); 1203 break; 1204 case GL_TEXTURE_COMPARE_MODE: 1205 res = set_sampler_compare_mode(ctx, sampObj, params[0]); 1206 break; 1207 case GL_TEXTURE_COMPARE_FUNC: 1208 res = set_sampler_compare_func(ctx, sampObj, params[0]); 1209 break; 1210 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1211 res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) params[0]); 1212 break; 1213 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1214 res = set_sampler_cube_map_seamless(ctx, sampObj, params[0]); 1215 break; 1216 case GL_TEXTURE_SRGB_DECODE_EXT: 1217 res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) params[0]); 1218 break; 1219 case GL_TEXTURE_BORDER_COLOR: 1220 res = set_sampler_border_colori(ctx, sampObj, params); 1221 break; 1222 default: 1223 res = INVALID_PNAME; 1224 } 1225 1226 switch (res) { 1227 case GL_FALSE: 1228 /* no change */ 1229 break; 1230 case GL_TRUE: 1231 /* state change - we do nothing special at this time */ 1232 break; 1233 case INVALID_PNAME: 1234 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIiv(pname=%s)\n", 1235 _mesa_enum_to_string(pname)); 1236 break; 1237 case INVALID_PARAM: 1238 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIiv(param=%d)\n", 1239 params[0]); 1240 break; 1241 case INVALID_VALUE: 1242 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIiv(param=%d)\n", 1243 params[0]); 1244 break; 1245 default: 1246 ; 1247 } 1248} 1249 1250 1251void GLAPIENTRY 1252_mesa_SamplerParameterIuiv(GLuint sampler, GLenum pname, const GLuint *params) 1253{ 1254 struct gl_sampler_object *sampObj; 1255 GLuint res; 1256 GET_CURRENT_CONTEXT(ctx); 1257 1258 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 1259 if (!sampObj) { 1260 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIuiv(sampler %u)", 1261 sampler); 1262 return; 1263 } 1264 1265 switch (pname) { 1266 case GL_TEXTURE_WRAP_S: 1267 res = set_sampler_wrap_s(ctx, sampObj, params[0]); 1268 break; 1269 case GL_TEXTURE_WRAP_T: 1270 res = set_sampler_wrap_t(ctx, sampObj, params[0]); 1271 break; 1272 case GL_TEXTURE_WRAP_R: 1273 res = set_sampler_wrap_r(ctx, sampObj, params[0]); 1274 break; 1275 case GL_TEXTURE_MIN_FILTER: 1276 res = set_sampler_min_filter(ctx, sampObj, params[0]); 1277 break; 1278 case GL_TEXTURE_MAG_FILTER: 1279 res = set_sampler_mag_filter(ctx, sampObj, params[0]); 1280 break; 1281 case GL_TEXTURE_MIN_LOD: 1282 res = set_sampler_min_lod(ctx, sampObj, (GLfloat) params[0]); 1283 break; 1284 case GL_TEXTURE_MAX_LOD: 1285 res = set_sampler_max_lod(ctx, sampObj, (GLfloat) params[0]); 1286 break; 1287 case GL_TEXTURE_LOD_BIAS: 1288 res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) params[0]); 1289 break; 1290 case GL_TEXTURE_COMPARE_MODE: 1291 res = set_sampler_compare_mode(ctx, sampObj, params[0]); 1292 break; 1293 case GL_TEXTURE_COMPARE_FUNC: 1294 res = set_sampler_compare_func(ctx, sampObj, params[0]); 1295 break; 1296 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1297 res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) params[0]); 1298 break; 1299 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1300 res = set_sampler_cube_map_seamless(ctx, sampObj, params[0]); 1301 break; 1302 case GL_TEXTURE_SRGB_DECODE_EXT: 1303 res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) params[0]); 1304 break; 1305 case GL_TEXTURE_BORDER_COLOR: 1306 res = set_sampler_border_colorui(ctx, sampObj, params); 1307 break; 1308 default: 1309 res = INVALID_PNAME; 1310 } 1311 1312 switch (res) { 1313 case GL_FALSE: 1314 /* no change */ 1315 break; 1316 case GL_TRUE: 1317 /* state change - we do nothing special at this time */ 1318 break; 1319 case INVALID_PNAME: 1320 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIuiv(pname=%s)\n", 1321 _mesa_enum_to_string(pname)); 1322 break; 1323 case INVALID_PARAM: 1324 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIuiv(param=%u)\n", 1325 params[0]); 1326 break; 1327 case INVALID_VALUE: 1328 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIuiv(param=%u)\n", 1329 params[0]); 1330 break; 1331 default: 1332 ; 1333 } 1334} 1335 1336 1337void GLAPIENTRY 1338_mesa_GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params) 1339{ 1340 struct gl_sampler_object *sampObj; 1341 GET_CURRENT_CONTEXT(ctx); 1342 1343 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 1344 if (!sampObj) { 1345 /* '3.8.2 Sampler Objects' section of the GL-ES 3.0 specification states: 1346 * 1347 * "An INVALID_OPERATION error is generated if sampler is not the name 1348 * of a sampler object previously returned from a call to GenSamplers." 1349 * 1350 * In desktop GL, an GL_INVALID_VALUE is returned instead. 1351 */ 1352 _mesa_error(ctx, (_mesa_is_gles(ctx) ? 1353 GL_INVALID_OPERATION : GL_INVALID_VALUE), 1354 "glGetSamplerParameteriv(sampler %u)", sampler); 1355 return; 1356 } 1357 1358 switch (pname) { 1359 case GL_TEXTURE_WRAP_S: 1360 *params = sampObj->WrapS; 1361 break; 1362 case GL_TEXTURE_WRAP_T: 1363 *params = sampObj->WrapT; 1364 break; 1365 case GL_TEXTURE_WRAP_R: 1366 *params = sampObj->WrapR; 1367 break; 1368 case GL_TEXTURE_MIN_FILTER: 1369 *params = sampObj->MinFilter; 1370 break; 1371 case GL_TEXTURE_MAG_FILTER: 1372 *params = sampObj->MagFilter; 1373 break; 1374 case GL_TEXTURE_MIN_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->MinLod); 1379 break; 1380 case GL_TEXTURE_MAX_LOD: 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->MaxLod); 1385 break; 1386 case GL_TEXTURE_LOD_BIAS: 1387 /* GL spec 'Data Conversions' section specifies that floating-point 1388 * value in integer Get function is rounded to nearest integer 1389 */ 1390 *params = IROUND(sampObj->LodBias); 1391 break; 1392 case GL_TEXTURE_COMPARE_MODE: 1393 *params = sampObj->CompareMode; 1394 break; 1395 case GL_TEXTURE_COMPARE_FUNC: 1396 *params = sampObj->CompareFunc; 1397 break; 1398 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1399 /* GL spec 'Data Conversions' section specifies that floating-point 1400 * value in integer Get function is rounded to nearest integer 1401 */ 1402 *params = IROUND(sampObj->MaxAnisotropy); 1403 break; 1404 case GL_TEXTURE_BORDER_COLOR: 1405 params[0] = FLOAT_TO_INT(sampObj->BorderColor.f[0]); 1406 params[1] = FLOAT_TO_INT(sampObj->BorderColor.f[1]); 1407 params[2] = FLOAT_TO_INT(sampObj->BorderColor.f[2]); 1408 params[3] = FLOAT_TO_INT(sampObj->BorderColor.f[3]); 1409 break; 1410 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1411 if (!ctx->Extensions.AMD_seamless_cubemap_per_texture) 1412 goto invalid_pname; 1413 *params = sampObj->CubeMapSeamless; 1414 break; 1415 case GL_TEXTURE_SRGB_DECODE_EXT: 1416 if (!ctx->Extensions.EXT_texture_sRGB_decode) 1417 goto invalid_pname; 1418 *params = (GLenum) sampObj->sRGBDecode; 1419 break; 1420 default: 1421 goto invalid_pname; 1422 } 1423 return; 1424 1425invalid_pname: 1426 _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameteriv(pname=%s)", 1427 _mesa_enum_to_string(pname)); 1428} 1429 1430 1431void GLAPIENTRY 1432_mesa_GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params) 1433{ 1434 struct gl_sampler_object *sampObj; 1435 GET_CURRENT_CONTEXT(ctx); 1436 1437 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 1438 if (!sampObj) { 1439 /* '3.8.2 Sampler Objects' section of the GL-ES 3.0 specification states: 1440 * 1441 * "An INVALID_OPERATION error is generated if sampler is not the name 1442 * of a sampler object previously returned from a call to GenSamplers." 1443 * 1444 * In desktop GL, an GL_INVALID_VALUE is returned instead. 1445 */ 1446 _mesa_error(ctx, (_mesa_is_gles(ctx) ? 1447 GL_INVALID_OPERATION : GL_INVALID_VALUE), 1448 "glGetSamplerParameterfv(sampler %u)", sampler); 1449 return; 1450 } 1451 1452 switch (pname) { 1453 case GL_TEXTURE_WRAP_S: 1454 *params = (GLfloat) sampObj->WrapS; 1455 break; 1456 case GL_TEXTURE_WRAP_T: 1457 *params = (GLfloat) sampObj->WrapT; 1458 break; 1459 case GL_TEXTURE_WRAP_R: 1460 *params = (GLfloat) sampObj->WrapR; 1461 break; 1462 case GL_TEXTURE_MIN_FILTER: 1463 *params = (GLfloat) sampObj->MinFilter; 1464 break; 1465 case GL_TEXTURE_MAG_FILTER: 1466 *params = (GLfloat) sampObj->MagFilter; 1467 break; 1468 case GL_TEXTURE_MIN_LOD: 1469 *params = sampObj->MinLod; 1470 break; 1471 case GL_TEXTURE_MAX_LOD: 1472 *params = sampObj->MaxLod; 1473 break; 1474 case GL_TEXTURE_LOD_BIAS: 1475 *params = sampObj->LodBias; 1476 break; 1477 case GL_TEXTURE_COMPARE_MODE: 1478 *params = (GLfloat) sampObj->CompareMode; 1479 break; 1480 case GL_TEXTURE_COMPARE_FUNC: 1481 *params = (GLfloat) sampObj->CompareFunc; 1482 break; 1483 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1484 *params = sampObj->MaxAnisotropy; 1485 break; 1486 case GL_TEXTURE_BORDER_COLOR: 1487 params[0] = sampObj->BorderColor.f[0]; 1488 params[1] = sampObj->BorderColor.f[1]; 1489 params[2] = sampObj->BorderColor.f[2]; 1490 params[3] = sampObj->BorderColor.f[3]; 1491 break; 1492 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1493 if (!ctx->Extensions.AMD_seamless_cubemap_per_texture) 1494 goto invalid_pname; 1495 *params = (GLfloat) sampObj->CubeMapSeamless; 1496 break; 1497 case GL_TEXTURE_SRGB_DECODE_EXT: 1498 if (!ctx->Extensions.EXT_texture_sRGB_decode) 1499 goto invalid_pname; 1500 *params = (GLfloat) sampObj->sRGBDecode; 1501 break; 1502 default: 1503 goto invalid_pname; 1504 } 1505 return; 1506 1507invalid_pname: 1508 _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameterfv(pname=%s)", 1509 _mesa_enum_to_string(pname)); 1510} 1511 1512 1513void GLAPIENTRY 1514_mesa_GetSamplerParameterIiv(GLuint sampler, GLenum pname, GLint *params) 1515{ 1516 struct gl_sampler_object *sampObj; 1517 GET_CURRENT_CONTEXT(ctx); 1518 1519 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 1520 if (!sampObj) { 1521 _mesa_error(ctx, GL_INVALID_VALUE, 1522 "glGetSamplerParameterIiv(sampler %u)", 1523 sampler); 1524 return; 1525 } 1526 1527 switch (pname) { 1528 case GL_TEXTURE_WRAP_S: 1529 *params = sampObj->WrapS; 1530 break; 1531 case GL_TEXTURE_WRAP_T: 1532 *params = sampObj->WrapT; 1533 break; 1534 case GL_TEXTURE_WRAP_R: 1535 *params = sampObj->WrapR; 1536 break; 1537 case GL_TEXTURE_MIN_FILTER: 1538 *params = sampObj->MinFilter; 1539 break; 1540 case GL_TEXTURE_MAG_FILTER: 1541 *params = sampObj->MagFilter; 1542 break; 1543 case GL_TEXTURE_MIN_LOD: 1544 *params = (GLint) sampObj->MinLod; 1545 break; 1546 case GL_TEXTURE_MAX_LOD: 1547 *params = (GLint) sampObj->MaxLod; 1548 break; 1549 case GL_TEXTURE_LOD_BIAS: 1550 *params = (GLint) sampObj->LodBias; 1551 break; 1552 case GL_TEXTURE_COMPARE_MODE: 1553 *params = sampObj->CompareMode; 1554 break; 1555 case GL_TEXTURE_COMPARE_FUNC: 1556 *params = sampObj->CompareFunc; 1557 break; 1558 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1559 *params = (GLint) sampObj->MaxAnisotropy; 1560 break; 1561 case GL_TEXTURE_BORDER_COLOR: 1562 params[0] = sampObj->BorderColor.i[0]; 1563 params[1] = sampObj->BorderColor.i[1]; 1564 params[2] = sampObj->BorderColor.i[2]; 1565 params[3] = sampObj->BorderColor.i[3]; 1566 break; 1567 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1568 if (!ctx->Extensions.AMD_seamless_cubemap_per_texture) 1569 goto invalid_pname; 1570 *params = sampObj->CubeMapSeamless; 1571 break; 1572 case GL_TEXTURE_SRGB_DECODE_EXT: 1573 if (!ctx->Extensions.EXT_texture_sRGB_decode) 1574 goto invalid_pname; 1575 *params = (GLenum) sampObj->sRGBDecode; 1576 break; 1577 default: 1578 goto invalid_pname; 1579 } 1580 return; 1581 1582invalid_pname: 1583 _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameterIiv(pname=%s)", 1584 _mesa_enum_to_string(pname)); 1585} 1586 1587 1588void GLAPIENTRY 1589_mesa_GetSamplerParameterIuiv(GLuint sampler, GLenum pname, GLuint *params) 1590{ 1591 struct gl_sampler_object *sampObj; 1592 GET_CURRENT_CONTEXT(ctx); 1593 1594 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 1595 if (!sampObj) { 1596 _mesa_error(ctx, GL_INVALID_VALUE, 1597 "glGetSamplerParameterIuiv(sampler %u)", 1598 sampler); 1599 return; 1600 } 1601 1602 switch (pname) { 1603 case GL_TEXTURE_WRAP_S: 1604 *params = sampObj->WrapS; 1605 break; 1606 case GL_TEXTURE_WRAP_T: 1607 *params = sampObj->WrapT; 1608 break; 1609 case GL_TEXTURE_WRAP_R: 1610 *params = sampObj->WrapR; 1611 break; 1612 case GL_TEXTURE_MIN_FILTER: 1613 *params = sampObj->MinFilter; 1614 break; 1615 case GL_TEXTURE_MAG_FILTER: 1616 *params = sampObj->MagFilter; 1617 break; 1618 case GL_TEXTURE_MIN_LOD: 1619 *params = (GLuint) sampObj->MinLod; 1620 break; 1621 case GL_TEXTURE_MAX_LOD: 1622 *params = (GLuint) sampObj->MaxLod; 1623 break; 1624 case GL_TEXTURE_LOD_BIAS: 1625 *params = (GLuint) sampObj->LodBias; 1626 break; 1627 case GL_TEXTURE_COMPARE_MODE: 1628 *params = sampObj->CompareMode; 1629 break; 1630 case GL_TEXTURE_COMPARE_FUNC: 1631 *params = sampObj->CompareFunc; 1632 break; 1633 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1634 *params = (GLuint) sampObj->MaxAnisotropy; 1635 break; 1636 case GL_TEXTURE_BORDER_COLOR: 1637 params[0] = sampObj->BorderColor.ui[0]; 1638 params[1] = sampObj->BorderColor.ui[1]; 1639 params[2] = sampObj->BorderColor.ui[2]; 1640 params[3] = sampObj->BorderColor.ui[3]; 1641 break; 1642 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1643 if (!ctx->Extensions.AMD_seamless_cubemap_per_texture) 1644 goto invalid_pname; 1645 *params = sampObj->CubeMapSeamless; 1646 break; 1647 case GL_TEXTURE_SRGB_DECODE_EXT: 1648 if (!ctx->Extensions.EXT_texture_sRGB_decode) 1649 goto invalid_pname; 1650 *params = (GLenum) sampObj->sRGBDecode; 1651 break; 1652 default: 1653 goto invalid_pname; 1654 } 1655 return; 1656 1657invalid_pname: 1658 _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameterIuiv(pname=%s)", 1659 _mesa_enum_to_string(pname)); 1660} 1661 1662 1663void 1664_mesa_init_sampler_object_functions(struct dd_function_table *driver) 1665{ 1666 driver->NewSamplerObject = _mesa_new_sampler_object; 1667} 1668