1848b8605Smrg/* 2848b8605Smrg * Mesa 3-D graphics library 3848b8605Smrg * 4848b8605Smrg * Copyright (C) 2011 VMware, Inc. All Rights Reserved. 5848b8605Smrg * 6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 7848b8605Smrg * copy of this software and associated documentation files (the "Software"), 8848b8605Smrg * to deal in the Software without restriction, including without limitation 9848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the 11848b8605Smrg * Software is furnished to do so, subject to the following conditions: 12848b8605Smrg * 13848b8605Smrg * The above copyright notice and this permission notice shall be included 14848b8605Smrg * in all copies or substantial portions of the Software. 15848b8605Smrg * 16848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20848b8605Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21848b8605Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22848b8605Smrg * OTHER DEALINGS IN THE SOFTWARE. 23848b8605Smrg */ 24848b8605Smrg 25848b8605Smrg 26848b8605Smrg/** 27848b8605Smrg * \file samplerobj.c 28848b8605Smrg * \brief Functions for the GL_ARB_sampler_objects extension. 29848b8605Smrg * \author Brian Paul 30848b8605Smrg */ 31848b8605Smrg 32848b8605Smrg 33848b8605Smrg#include "main/glheader.h" 34848b8605Smrg#include "main/context.h" 35848b8605Smrg#include "main/enums.h" 36848b8605Smrg#include "main/hash.h" 37848b8605Smrg#include "main/macros.h" 38848b8605Smrg#include "main/mtypes.h" 39848b8605Smrg#include "main/samplerobj.h" 40b8e80941Smrg#include "main/texturebindless.h" 41848b8605Smrg 42848b8605Smrg 43848b8605Smrgstruct gl_sampler_object * 44848b8605Smrg_mesa_lookup_samplerobj(struct gl_context *ctx, GLuint name) 45848b8605Smrg{ 46848b8605Smrg if (name == 0) 47848b8605Smrg return NULL; 48848b8605Smrg else 49848b8605Smrg return (struct gl_sampler_object *) 50848b8605Smrg _mesa_HashLookup(ctx->Shared->SamplerObjects, name); 51848b8605Smrg} 52848b8605Smrg 53848b8605Smrgstatic inline struct gl_sampler_object * 54848b8605Smrglookup_samplerobj_locked(struct gl_context *ctx, GLuint name) 55848b8605Smrg{ 56848b8605Smrg return (struct gl_sampler_object *) 57848b8605Smrg _mesa_HashLookupLocked(ctx->Shared->SamplerObjects, name); 58848b8605Smrg} 59848b8605Smrg 60b8e80941Smrgstatic void 61b8e80941Smrgdelete_sampler_object(struct gl_context *ctx, 62b8e80941Smrg struct gl_sampler_object *sampObj) 63b8e80941Smrg{ 64b8e80941Smrg _mesa_delete_sampler_handles(ctx, sampObj); 65b8e80941Smrg simple_mtx_destroy(&sampObj->Mutex); 66b8e80941Smrg free(sampObj->Label); 67b8e80941Smrg free(sampObj); 68b8e80941Smrg} 69848b8605Smrg 70848b8605Smrg/** 71848b8605Smrg * Handle reference counting. 72848b8605Smrg */ 73848b8605Smrgvoid 74848b8605Smrg_mesa_reference_sampler_object_(struct gl_context *ctx, 75848b8605Smrg struct gl_sampler_object **ptr, 76848b8605Smrg struct gl_sampler_object *samp) 77848b8605Smrg{ 78848b8605Smrg assert(*ptr != samp); /* The inline wrapper should prevent no-op calls */ 79848b8605Smrg 80848b8605Smrg if (*ptr) { 81848b8605Smrg /* Unreference the old sampler */ 82848b8605Smrg GLboolean deleteFlag = GL_FALSE; 83848b8605Smrg struct gl_sampler_object *oldSamp = *ptr; 84848b8605Smrg 85b8e80941Smrg simple_mtx_lock(&oldSamp->Mutex); 86b8e80941Smrg assert(oldSamp->RefCount > 0); 87848b8605Smrg oldSamp->RefCount--; 88848b8605Smrg deleteFlag = (oldSamp->RefCount == 0); 89b8e80941Smrg simple_mtx_unlock(&oldSamp->Mutex); 90848b8605Smrg 91b8e80941Smrg if (deleteFlag) 92b8e80941Smrg delete_sampler_object(ctx, oldSamp); 93848b8605Smrg 94848b8605Smrg *ptr = NULL; 95848b8605Smrg } 96b8e80941Smrg assert(!*ptr); 97848b8605Smrg 98848b8605Smrg if (samp) { 99848b8605Smrg /* reference new sampler */ 100b8e80941Smrg simple_mtx_lock(&samp->Mutex); 101b8e80941Smrg assert(samp->RefCount > 0); 102b8e80941Smrg 103b8e80941Smrg samp->RefCount++; 104b8e80941Smrg *ptr = samp; 105b8e80941Smrg simple_mtx_unlock(&samp->Mutex); 106848b8605Smrg } 107848b8605Smrg} 108848b8605Smrg 109848b8605Smrg 110848b8605Smrg/** 111848b8605Smrg * Initialize the fields of the given sampler object. 112848b8605Smrg */ 113848b8605Smrgstatic void 114848b8605Smrg_mesa_init_sampler_object(struct gl_sampler_object *sampObj, GLuint name) 115848b8605Smrg{ 116b8e80941Smrg simple_mtx_init(&sampObj->Mutex, mtx_plain); 117848b8605Smrg sampObj->Name = name; 118848b8605Smrg sampObj->RefCount = 1; 119848b8605Smrg sampObj->WrapS = GL_REPEAT; 120848b8605Smrg sampObj->WrapT = GL_REPEAT; 121848b8605Smrg sampObj->WrapR = GL_REPEAT; 122848b8605Smrg sampObj->MinFilter = GL_NEAREST_MIPMAP_LINEAR; 123848b8605Smrg sampObj->MagFilter = GL_LINEAR; 124848b8605Smrg sampObj->BorderColor.f[0] = 0.0; 125848b8605Smrg sampObj->BorderColor.f[1] = 0.0; 126848b8605Smrg sampObj->BorderColor.f[2] = 0.0; 127848b8605Smrg sampObj->BorderColor.f[3] = 0.0; 128848b8605Smrg sampObj->MinLod = -1000.0F; 129848b8605Smrg sampObj->MaxLod = 1000.0F; 130848b8605Smrg sampObj->LodBias = 0.0F; 131848b8605Smrg sampObj->MaxAnisotropy = 1.0F; 132848b8605Smrg sampObj->CompareMode = GL_NONE; 133848b8605Smrg sampObj->CompareFunc = GL_LEQUAL; 134848b8605Smrg sampObj->sRGBDecode = GL_DECODE_EXT; 135848b8605Smrg sampObj->CubeMapSeamless = GL_FALSE; 136b8e80941Smrg sampObj->HandleAllocated = GL_FALSE; 137b8e80941Smrg 138b8e80941Smrg /* GL_ARB_bindless_texture */ 139b8e80941Smrg _mesa_init_sampler_handles(sampObj); 140848b8605Smrg} 141848b8605Smrg 142848b8605Smrg/** 143848b8605Smrg * Fallback for ctx->Driver.NewSamplerObject(); 144848b8605Smrg */ 145848b8605Smrgstruct gl_sampler_object * 146848b8605Smrg_mesa_new_sampler_object(struct gl_context *ctx, GLuint name) 147848b8605Smrg{ 148848b8605Smrg struct gl_sampler_object *sampObj = CALLOC_STRUCT(gl_sampler_object); 149848b8605Smrg if (sampObj) { 150848b8605Smrg _mesa_init_sampler_object(sampObj, name); 151848b8605Smrg } 152848b8605Smrg return sampObj; 153848b8605Smrg} 154848b8605Smrg 155848b8605Smrgstatic void 156b8e80941Smrgcreate_samplers(struct gl_context *ctx, GLsizei count, GLuint *samplers, 157b8e80941Smrg const char *caller) 158848b8605Smrg{ 159b8e80941Smrg GLuint first; 160b8e80941Smrg GLint i; 161848b8605Smrg 162b8e80941Smrg if (!samplers) 163b8e80941Smrg return; 164848b8605Smrg 165b8e80941Smrg _mesa_HashLockMutex(ctx->Shared->SamplerObjects); 166b8e80941Smrg 167b8e80941Smrg first = _mesa_HashFindFreeKeyBlock(ctx->Shared->SamplerObjects, count); 168b8e80941Smrg 169b8e80941Smrg /* Insert the ID and pointer to new sampler object into hash table */ 170b8e80941Smrg for (i = 0; i < count; i++) { 171b8e80941Smrg struct gl_sampler_object *sampObj; 172b8e80941Smrg GLuint name = first + i; 173b8e80941Smrg 174b8e80941Smrg sampObj = ctx->Driver.NewSamplerObject(ctx, name); 175b8e80941Smrg if (!sampObj) { 176b8e80941Smrg _mesa_HashUnlockMutex(ctx->Shared->SamplerObjects); 177b8e80941Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller); 178b8e80941Smrg return; 179b8e80941Smrg } 180b8e80941Smrg 181b8e80941Smrg _mesa_HashInsertLocked(ctx->Shared->SamplerObjects, name, sampObj); 182b8e80941Smrg samplers[i] = name; 183b8e80941Smrg } 184b8e80941Smrg 185b8e80941Smrg _mesa_HashUnlockMutex(ctx->Shared->SamplerObjects); 186b8e80941Smrg} 187b8e80941Smrg 188b8e80941Smrgstatic void 189b8e80941Smrgcreate_samplers_err(struct gl_context *ctx, GLsizei count, GLuint *samplers, 190b8e80941Smrg const char *caller) 191848b8605Smrg{ 192848b8605Smrg 193848b8605Smrg if (MESA_VERBOSE & VERBOSE_API) 194b8e80941Smrg _mesa_debug(ctx, "%s(%d)\n", caller, count); 195848b8605Smrg 196848b8605Smrg if (count < 0) { 197b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, "%s(n<0)", caller); 198848b8605Smrg return; 199848b8605Smrg } 200848b8605Smrg 201b8e80941Smrg create_samplers(ctx, count, samplers, caller); 202b8e80941Smrg} 203848b8605Smrg 204b8e80941Smrgvoid GLAPIENTRY 205b8e80941Smrg_mesa_GenSamplers_no_error(GLsizei count, GLuint *samplers) 206b8e80941Smrg{ 207b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 208b8e80941Smrg create_samplers(ctx, count, samplers, "glGenSamplers"); 209b8e80941Smrg} 210848b8605Smrg 211b8e80941Smrgvoid GLAPIENTRY 212b8e80941Smrg_mesa_GenSamplers(GLsizei count, GLuint *samplers) 213b8e80941Smrg{ 214b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 215b8e80941Smrg create_samplers_err(ctx, count, samplers, "glGenSamplers"); 216848b8605Smrg} 217848b8605Smrg 218b8e80941Smrgvoid GLAPIENTRY 219b8e80941Smrg_mesa_CreateSamplers_no_error(GLsizei count, GLuint *samplers) 220b8e80941Smrg{ 221b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 222b8e80941Smrg create_samplers(ctx, count, samplers, "glCreateSamplers"); 223b8e80941Smrg} 224848b8605Smrg 225848b8605Smrgvoid GLAPIENTRY 226b8e80941Smrg_mesa_CreateSamplers(GLsizei count, GLuint *samplers) 227848b8605Smrg{ 228848b8605Smrg GET_CURRENT_CONTEXT(ctx); 229b8e80941Smrg create_samplers_err(ctx, count, samplers, "glCreateSamplers"); 230b8e80941Smrg} 231848b8605Smrg 232848b8605Smrg 233b8e80941Smrgstatic void 234b8e80941Smrgdelete_samplers(struct gl_context *ctx, GLsizei count, const GLuint *samplers) 235b8e80941Smrg{ 236b8e80941Smrg FLUSH_VERTICES(ctx, 0); 237848b8605Smrg 238b8e80941Smrg _mesa_HashLockMutex(ctx->Shared->SamplerObjects); 239848b8605Smrg 240b8e80941Smrg for (GLsizei i = 0; i < count; i++) { 241848b8605Smrg if (samplers[i]) { 242848b8605Smrg GLuint j; 243848b8605Smrg struct gl_sampler_object *sampObj = 244b8e80941Smrg lookup_samplerobj_locked(ctx, samplers[i]); 245848b8605Smrg 246848b8605Smrg if (sampObj) { 247848b8605Smrg /* If the sampler is currently bound, unbind it. */ 248848b8605Smrg for (j = 0; j < ctx->Const.MaxCombinedTextureImageUnits; j++) { 249848b8605Smrg if (ctx->Texture.Unit[j].Sampler == sampObj) { 250b8e80941Smrg FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT); 251848b8605Smrg _mesa_reference_sampler_object(ctx, &ctx->Texture.Unit[j].Sampler, NULL); 252848b8605Smrg } 253848b8605Smrg } 254848b8605Smrg 255848b8605Smrg /* The ID is immediately freed for re-use */ 256b8e80941Smrg _mesa_HashRemoveLocked(ctx->Shared->SamplerObjects, samplers[i]); 257848b8605Smrg /* But the object exists until its reference count goes to zero */ 258848b8605Smrg _mesa_reference_sampler_object(ctx, &sampObj, NULL); 259848b8605Smrg } 260848b8605Smrg } 261848b8605Smrg } 262848b8605Smrg 263b8e80941Smrg _mesa_HashUnlockMutex(ctx->Shared->SamplerObjects); 264848b8605Smrg} 265848b8605Smrg 266848b8605Smrg 267b8e80941Smrgvoid GLAPIENTRY 268b8e80941Smrg_mesa_DeleteSamplers_no_error(GLsizei count, const GLuint *samplers) 269848b8605Smrg{ 270848b8605Smrg GET_CURRENT_CONTEXT(ctx); 271b8e80941Smrg delete_samplers(ctx, count, samplers); 272b8e80941Smrg} 273848b8605Smrg 274848b8605Smrg 275b8e80941Smrgvoid GLAPIENTRY 276b8e80941Smrg_mesa_DeleteSamplers(GLsizei count, const GLuint *samplers) 277b8e80941Smrg{ 278b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 279848b8605Smrg 280b8e80941Smrg if (count < 0) { 281b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteSamplers(count)"); 282b8e80941Smrg return; 283b8e80941Smrg } 284848b8605Smrg 285b8e80941Smrg delete_samplers(ctx, count, samplers); 286848b8605Smrg} 287848b8605Smrg 288848b8605Smrg 289b8e80941SmrgGLboolean GLAPIENTRY 290b8e80941Smrg_mesa_IsSampler(GLuint sampler) 291848b8605Smrg{ 292848b8605Smrg GET_CURRENT_CONTEXT(ctx); 293848b8605Smrg 294b8e80941Smrg ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); 295b8e80941Smrg 296b8e80941Smrg return _mesa_lookup_samplerobj(ctx, sampler) != NULL; 297b8e80941Smrg} 298b8e80941Smrg 299b8e80941Smrgvoid 300b8e80941Smrg_mesa_bind_sampler(struct gl_context *ctx, GLuint unit, 301b8e80941Smrg struct gl_sampler_object *sampObj) 302b8e80941Smrg{ 303b8e80941Smrg if (ctx->Texture.Unit[unit].Sampler != sampObj) { 304b8e80941Smrg FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT); 305848b8605Smrg } 306848b8605Smrg 307b8e80941Smrg _mesa_reference_sampler_object(ctx, &ctx->Texture.Unit[unit].Sampler, 308b8e80941Smrg sampObj); 309b8e80941Smrg} 310b8e80941Smrg 311b8e80941Smrgstatic ALWAYS_INLINE void 312b8e80941Smrgbind_sampler(struct gl_context *ctx, GLuint unit, GLuint sampler, bool no_error) 313b8e80941Smrg{ 314b8e80941Smrg struct gl_sampler_object *sampObj; 315b8e80941Smrg 316848b8605Smrg if (sampler == 0) { 317848b8605Smrg /* Use the default sampler object, the one contained in the texture 318848b8605Smrg * object. 319848b8605Smrg */ 320848b8605Smrg sampObj = NULL; 321b8e80941Smrg } else { 322848b8605Smrg /* user-defined sampler object */ 323848b8605Smrg sampObj = _mesa_lookup_samplerobj(ctx, sampler); 324b8e80941Smrg if (!no_error && !sampObj) { 325848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "glBindSampler(sampler)"); 326848b8605Smrg return; 327848b8605Smrg } 328848b8605Smrg } 329848b8605Smrg 330848b8605Smrg /* bind new sampler */ 331b8e80941Smrg _mesa_bind_sampler(ctx, unit, sampObj); 332848b8605Smrg} 333848b8605Smrg 334b8e80941Smrgvoid GLAPIENTRY 335b8e80941Smrg_mesa_BindSampler_no_error(GLuint unit, GLuint sampler) 336b8e80941Smrg{ 337b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 338b8e80941Smrg bind_sampler(ctx, unit, sampler, true); 339b8e80941Smrg} 340848b8605Smrg 341848b8605Smrgvoid GLAPIENTRY 342b8e80941Smrg_mesa_BindSampler(GLuint unit, GLuint sampler) 343848b8605Smrg{ 344848b8605Smrg GET_CURRENT_CONTEXT(ctx); 345848b8605Smrg 346b8e80941Smrg if (unit >= ctx->Const.MaxCombinedTextureImageUnits) { 347b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glBindSampler(unit %u)", unit); 348848b8605Smrg return; 349848b8605Smrg } 350848b8605Smrg 351b8e80941Smrg bind_sampler(ctx, unit, sampler, false); 352b8e80941Smrg} 353b8e80941Smrg 354b8e80941Smrg 355b8e80941Smrgstatic ALWAYS_INLINE void 356b8e80941Smrgbind_samplers(struct gl_context *ctx, GLuint first, GLsizei count, 357b8e80941Smrg const GLuint *samplers, bool no_error) 358b8e80941Smrg{ 359b8e80941Smrg GLsizei i; 360b8e80941Smrg 361848b8605Smrg FLUSH_VERTICES(ctx, 0); 362848b8605Smrg 363848b8605Smrg if (samplers) { 364848b8605Smrg /* Note that the error semantics for multi-bind commands differ from 365848b8605Smrg * those of other GL commands. 366848b8605Smrg * 367848b8605Smrg * The Issues section in the ARB_multi_bind spec says: 368848b8605Smrg * 369848b8605Smrg * "(11) Typically, OpenGL specifies that if an error is generated by 370848b8605Smrg * a command, that command has no effect. This is somewhat 371848b8605Smrg * unfortunate for multi-bind commands, because it would require 372848b8605Smrg * a first pass to scan the entire list of bound objects for 373848b8605Smrg * errors and then a second pass to actually perform the 374848b8605Smrg * bindings. Should we have different error semantics? 375848b8605Smrg * 376848b8605Smrg * RESOLVED: Yes. In this specification, when the parameters for 377848b8605Smrg * one of the <count> binding points are invalid, that binding 378848b8605Smrg * point is not updated and an error will be generated. However, 379848b8605Smrg * other binding points in the same command will be updated if 380848b8605Smrg * their parameters are valid and no other error occurs." 381848b8605Smrg */ 382848b8605Smrg 383b8e80941Smrg _mesa_HashLockMutex(ctx->Shared->SamplerObjects); 384848b8605Smrg 385848b8605Smrg for (i = 0; i < count; i++) { 386848b8605Smrg const GLuint unit = first + i; 387848b8605Smrg struct gl_sampler_object * const currentSampler = 388848b8605Smrg ctx->Texture.Unit[unit].Sampler; 389848b8605Smrg struct gl_sampler_object *sampObj; 390848b8605Smrg 391848b8605Smrg if (samplers[i] != 0) { 392848b8605Smrg if (currentSampler && currentSampler->Name == samplers[i]) 393848b8605Smrg sampObj = currentSampler; 394848b8605Smrg else 395848b8605Smrg sampObj = lookup_samplerobj_locked(ctx, samplers[i]); 396848b8605Smrg 397848b8605Smrg /* The ARB_multi_bind spec says: 398848b8605Smrg * 399848b8605Smrg * "An INVALID_OPERATION error is generated if any value 400848b8605Smrg * in <samplers> is not zero or the name of an existing 401848b8605Smrg * sampler object (per binding)." 402848b8605Smrg */ 403b8e80941Smrg if (!no_error && !sampObj) { 404848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 405848b8605Smrg "glBindSamplers(samplers[%d]=%u is not zero or " 406848b8605Smrg "the name of an existing sampler object)", 407848b8605Smrg i, samplers[i]); 408848b8605Smrg continue; 409848b8605Smrg } 410848b8605Smrg } else { 411848b8605Smrg sampObj = NULL; 412848b8605Smrg } 413848b8605Smrg 414848b8605Smrg /* Bind the new sampler */ 415848b8605Smrg if (sampObj != currentSampler) { 416848b8605Smrg _mesa_reference_sampler_object(ctx, 417848b8605Smrg &ctx->Texture.Unit[unit].Sampler, 418848b8605Smrg sampObj); 419b8e80941Smrg ctx->NewState |= _NEW_TEXTURE_OBJECT; 420848b8605Smrg } 421848b8605Smrg } 422848b8605Smrg 423b8e80941Smrg _mesa_HashUnlockMutex(ctx->Shared->SamplerObjects); 424848b8605Smrg } else { 425848b8605Smrg /* Unbind all samplers in the range <first> through <first>+<count>-1 */ 426848b8605Smrg for (i = 0; i < count; i++) { 427848b8605Smrg const GLuint unit = first + i; 428848b8605Smrg 429848b8605Smrg if (ctx->Texture.Unit[unit].Sampler) { 430848b8605Smrg _mesa_reference_sampler_object(ctx, 431848b8605Smrg &ctx->Texture.Unit[unit].Sampler, 432848b8605Smrg NULL); 433b8e80941Smrg ctx->NewState |= _NEW_TEXTURE_OBJECT; 434848b8605Smrg } 435848b8605Smrg } 436848b8605Smrg } 437848b8605Smrg} 438848b8605Smrg 439848b8605Smrg 440b8e80941Smrgvoid GLAPIENTRY 441b8e80941Smrg_mesa_BindSamplers_no_error(GLuint first, GLsizei count, const GLuint *samplers) 442b8e80941Smrg{ 443b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 444b8e80941Smrg bind_samplers(ctx, first, count, samplers, true); 445b8e80941Smrg} 446b8e80941Smrg 447b8e80941Smrg 448b8e80941Smrgvoid GLAPIENTRY 449b8e80941Smrg_mesa_BindSamplers(GLuint first, GLsizei count, const GLuint *samplers) 450b8e80941Smrg{ 451b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 452b8e80941Smrg 453b8e80941Smrg /* The ARB_multi_bind spec says: 454b8e80941Smrg * 455b8e80941Smrg * "An INVALID_OPERATION error is generated if <first> + <count> is 456b8e80941Smrg * greater than the number of texture image units supported by 457b8e80941Smrg * the implementation." 458b8e80941Smrg */ 459b8e80941Smrg if (first + count > ctx->Const.MaxCombinedTextureImageUnits) { 460b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 461b8e80941Smrg "glBindSamplers(first=%u + count=%d > the value of " 462b8e80941Smrg "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS=%u)", 463b8e80941Smrg first, count, ctx->Const.MaxCombinedTextureImageUnits); 464b8e80941Smrg return; 465b8e80941Smrg } 466b8e80941Smrg 467b8e80941Smrg bind_samplers(ctx, first, count, samplers, false); 468b8e80941Smrg} 469b8e80941Smrg 470b8e80941Smrg 471848b8605Smrg/** 472848b8605Smrg * Check if a coordinate wrap mode is legal. 473848b8605Smrg * \return GL_TRUE if legal, GL_FALSE otherwise 474848b8605Smrg */ 475848b8605Smrgstatic GLboolean 476848b8605Smrgvalidate_texture_wrap_mode(struct gl_context *ctx, GLenum wrap) 477848b8605Smrg{ 478848b8605Smrg const struct gl_extensions * const e = &ctx->Extensions; 479848b8605Smrg 480848b8605Smrg switch (wrap) { 481848b8605Smrg case GL_CLAMP: 482848b8605Smrg case GL_CLAMP_TO_EDGE: 483848b8605Smrg case GL_REPEAT: 484848b8605Smrg case GL_MIRRORED_REPEAT: 485848b8605Smrg return GL_TRUE; 486848b8605Smrg case GL_CLAMP_TO_BORDER: 487848b8605Smrg return e->ARB_texture_border_clamp; 488848b8605Smrg case GL_MIRROR_CLAMP_EXT: 489848b8605Smrg return e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp; 490848b8605Smrg case GL_MIRROR_CLAMP_TO_EDGE_EXT: 491848b8605Smrg return e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp || e->ARB_texture_mirror_clamp_to_edge; 492848b8605Smrg case GL_MIRROR_CLAMP_TO_BORDER_EXT: 493848b8605Smrg return e->EXT_texture_mirror_clamp; 494848b8605Smrg default: 495848b8605Smrg return GL_FALSE; 496848b8605Smrg } 497848b8605Smrg} 498848b8605Smrg 499848b8605Smrg 500848b8605Smrg/** 501848b8605Smrg * This is called just prior to changing any sampler object state. 502848b8605Smrg */ 503848b8605Smrgstatic inline void 504848b8605Smrgflush(struct gl_context *ctx) 505848b8605Smrg{ 506b8e80941Smrg FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT); 507848b8605Smrg} 508848b8605Smrg 509b8e80941Smrgvoid 510b8e80941Smrg_mesa_set_sampler_wrap(struct gl_context *ctx, struct gl_sampler_object *samp, 511b8e80941Smrg GLenum s, GLenum t, GLenum r) 512b8e80941Smrg{ 513b8e80941Smrg assert(validate_texture_wrap_mode(ctx, s)); 514b8e80941Smrg assert(validate_texture_wrap_mode(ctx, t)); 515b8e80941Smrg assert(validate_texture_wrap_mode(ctx, r)); 516b8e80941Smrg 517b8e80941Smrg if (samp->WrapS == s && samp->WrapT == t && samp->WrapR == r) 518b8e80941Smrg return; 519b8e80941Smrg 520b8e80941Smrg flush(ctx); 521b8e80941Smrg samp->WrapS = s; 522b8e80941Smrg samp->WrapT = t; 523b8e80941Smrg samp->WrapR = r; 524b8e80941Smrg} 525848b8605Smrg 526848b8605Smrg#define INVALID_PARAM 0x100 527848b8605Smrg#define INVALID_PNAME 0x101 528848b8605Smrg#define INVALID_VALUE 0x102 529848b8605Smrg 530848b8605Smrgstatic GLuint 531848b8605Smrgset_sampler_wrap_s(struct gl_context *ctx, struct gl_sampler_object *samp, 532848b8605Smrg GLint param) 533848b8605Smrg{ 534848b8605Smrg if (samp->WrapS == param) 535848b8605Smrg return GL_FALSE; 536848b8605Smrg if (validate_texture_wrap_mode(ctx, param)) { 537848b8605Smrg flush(ctx); 538848b8605Smrg samp->WrapS = param; 539848b8605Smrg return GL_TRUE; 540848b8605Smrg } 541848b8605Smrg return INVALID_PARAM; 542848b8605Smrg} 543848b8605Smrg 544848b8605Smrg 545848b8605Smrgstatic GLuint 546848b8605Smrgset_sampler_wrap_t(struct gl_context *ctx, struct gl_sampler_object *samp, 547848b8605Smrg GLint param) 548848b8605Smrg{ 549848b8605Smrg if (samp->WrapT == param) 550848b8605Smrg return GL_FALSE; 551848b8605Smrg if (validate_texture_wrap_mode(ctx, param)) { 552848b8605Smrg flush(ctx); 553848b8605Smrg samp->WrapT = param; 554848b8605Smrg return GL_TRUE; 555848b8605Smrg } 556848b8605Smrg return INVALID_PARAM; 557848b8605Smrg} 558848b8605Smrg 559848b8605Smrg 560848b8605Smrgstatic GLuint 561848b8605Smrgset_sampler_wrap_r(struct gl_context *ctx, struct gl_sampler_object *samp, 562848b8605Smrg GLint param) 563848b8605Smrg{ 564848b8605Smrg if (samp->WrapR == param) 565848b8605Smrg return GL_FALSE; 566848b8605Smrg if (validate_texture_wrap_mode(ctx, param)) { 567848b8605Smrg flush(ctx); 568848b8605Smrg samp->WrapR = param; 569848b8605Smrg return GL_TRUE; 570848b8605Smrg } 571848b8605Smrg return INVALID_PARAM; 572848b8605Smrg} 573848b8605Smrg 574b8e80941Smrgvoid 575b8e80941Smrg_mesa_set_sampler_filters(struct gl_context *ctx, 576b8e80941Smrg struct gl_sampler_object *samp, 577b8e80941Smrg GLenum min_filter, GLenum mag_filter) 578b8e80941Smrg{ 579b8e80941Smrg assert(min_filter == GL_NEAREST || 580b8e80941Smrg min_filter == GL_LINEAR || 581b8e80941Smrg min_filter == GL_NEAREST_MIPMAP_NEAREST || 582b8e80941Smrg min_filter == GL_LINEAR_MIPMAP_NEAREST || 583b8e80941Smrg min_filter == GL_NEAREST_MIPMAP_LINEAR || 584b8e80941Smrg min_filter == GL_LINEAR_MIPMAP_LINEAR); 585b8e80941Smrg assert(mag_filter == GL_NEAREST || 586b8e80941Smrg mag_filter == GL_LINEAR); 587b8e80941Smrg 588b8e80941Smrg if (samp->MinFilter == min_filter && samp->MagFilter == mag_filter) 589b8e80941Smrg return; 590b8e80941Smrg 591b8e80941Smrg flush(ctx); 592b8e80941Smrg samp->MinFilter = min_filter; 593b8e80941Smrg samp->MagFilter = mag_filter; 594b8e80941Smrg} 595848b8605Smrg 596848b8605Smrgstatic GLuint 597848b8605Smrgset_sampler_min_filter(struct gl_context *ctx, struct gl_sampler_object *samp, 598848b8605Smrg GLint param) 599848b8605Smrg{ 600848b8605Smrg if (samp->MinFilter == param) 601848b8605Smrg return GL_FALSE; 602848b8605Smrg 603848b8605Smrg switch (param) { 604848b8605Smrg case GL_NEAREST: 605848b8605Smrg case GL_LINEAR: 606848b8605Smrg case GL_NEAREST_MIPMAP_NEAREST: 607848b8605Smrg case GL_LINEAR_MIPMAP_NEAREST: 608848b8605Smrg case GL_NEAREST_MIPMAP_LINEAR: 609848b8605Smrg case GL_LINEAR_MIPMAP_LINEAR: 610848b8605Smrg flush(ctx); 611848b8605Smrg samp->MinFilter = param; 612848b8605Smrg return GL_TRUE; 613848b8605Smrg default: 614848b8605Smrg return INVALID_PARAM; 615848b8605Smrg } 616848b8605Smrg} 617848b8605Smrg 618848b8605Smrg 619848b8605Smrgstatic GLuint 620848b8605Smrgset_sampler_mag_filter(struct gl_context *ctx, struct gl_sampler_object *samp, 621848b8605Smrg GLint param) 622848b8605Smrg{ 623848b8605Smrg if (samp->MagFilter == param) 624848b8605Smrg return GL_FALSE; 625848b8605Smrg 626848b8605Smrg switch (param) { 627848b8605Smrg case GL_NEAREST: 628848b8605Smrg case GL_LINEAR: 629848b8605Smrg flush(ctx); 630848b8605Smrg samp->MagFilter = param; 631848b8605Smrg return GL_TRUE; 632848b8605Smrg default: 633848b8605Smrg return INVALID_PARAM; 634848b8605Smrg } 635848b8605Smrg} 636848b8605Smrg 637848b8605Smrg 638848b8605Smrgstatic GLuint 639848b8605Smrgset_sampler_lod_bias(struct gl_context *ctx, struct gl_sampler_object *samp, 640848b8605Smrg GLfloat param) 641848b8605Smrg{ 642848b8605Smrg if (samp->LodBias == param) 643848b8605Smrg return GL_FALSE; 644848b8605Smrg 645848b8605Smrg flush(ctx); 646848b8605Smrg samp->LodBias = param; 647848b8605Smrg return GL_TRUE; 648848b8605Smrg} 649848b8605Smrg 650848b8605Smrg 651848b8605Smrgstatic GLuint 652848b8605Smrgset_sampler_border_colorf(struct gl_context *ctx, 653848b8605Smrg struct gl_sampler_object *samp, 654848b8605Smrg const GLfloat params[4]) 655848b8605Smrg{ 656848b8605Smrg flush(ctx); 657848b8605Smrg samp->BorderColor.f[RCOMP] = params[0]; 658848b8605Smrg samp->BorderColor.f[GCOMP] = params[1]; 659848b8605Smrg samp->BorderColor.f[BCOMP] = params[2]; 660848b8605Smrg samp->BorderColor.f[ACOMP] = params[3]; 661848b8605Smrg return GL_TRUE; 662848b8605Smrg} 663848b8605Smrg 664848b8605Smrg 665848b8605Smrgstatic GLuint 666848b8605Smrgset_sampler_border_colori(struct gl_context *ctx, 667848b8605Smrg struct gl_sampler_object *samp, 668848b8605Smrg const GLint params[4]) 669848b8605Smrg{ 670848b8605Smrg flush(ctx); 671848b8605Smrg samp->BorderColor.i[RCOMP] = params[0]; 672848b8605Smrg samp->BorderColor.i[GCOMP] = params[1]; 673848b8605Smrg samp->BorderColor.i[BCOMP] = params[2]; 674848b8605Smrg samp->BorderColor.i[ACOMP] = params[3]; 675848b8605Smrg return GL_TRUE; 676848b8605Smrg} 677848b8605Smrg 678848b8605Smrg 679848b8605Smrgstatic GLuint 680848b8605Smrgset_sampler_border_colorui(struct gl_context *ctx, 681848b8605Smrg struct gl_sampler_object *samp, 682848b8605Smrg const GLuint params[4]) 683848b8605Smrg{ 684848b8605Smrg flush(ctx); 685848b8605Smrg samp->BorderColor.ui[RCOMP] = params[0]; 686848b8605Smrg samp->BorderColor.ui[GCOMP] = params[1]; 687848b8605Smrg samp->BorderColor.ui[BCOMP] = params[2]; 688848b8605Smrg samp->BorderColor.ui[ACOMP] = params[3]; 689848b8605Smrg return GL_TRUE; 690848b8605Smrg} 691848b8605Smrg 692848b8605Smrg 693848b8605Smrgstatic GLuint 694848b8605Smrgset_sampler_min_lod(struct gl_context *ctx, struct gl_sampler_object *samp, 695848b8605Smrg GLfloat param) 696848b8605Smrg{ 697848b8605Smrg if (samp->MinLod == param) 698848b8605Smrg return GL_FALSE; 699848b8605Smrg 700848b8605Smrg flush(ctx); 701848b8605Smrg samp->MinLod = param; 702848b8605Smrg return GL_TRUE; 703848b8605Smrg} 704848b8605Smrg 705848b8605Smrg 706848b8605Smrgstatic GLuint 707848b8605Smrgset_sampler_max_lod(struct gl_context *ctx, struct gl_sampler_object *samp, 708848b8605Smrg GLfloat param) 709848b8605Smrg{ 710848b8605Smrg if (samp->MaxLod == param) 711848b8605Smrg return GL_FALSE; 712848b8605Smrg 713848b8605Smrg flush(ctx); 714848b8605Smrg samp->MaxLod = param; 715848b8605Smrg return GL_TRUE; 716848b8605Smrg} 717848b8605Smrg 718848b8605Smrg 719848b8605Smrgstatic GLuint 720848b8605Smrgset_sampler_compare_mode(struct gl_context *ctx, 721848b8605Smrg struct gl_sampler_object *samp, GLint param) 722848b8605Smrg{ 723b8e80941Smrg /* If GL_ARB_shadow is not supported, don't report an error. The 724b8e80941Smrg * sampler object extension spec isn't clear on this extension interaction. 725b8e80941Smrg * Silences errors with Wine on older GPUs such as R200. 726b8e80941Smrg */ 727848b8605Smrg if (!ctx->Extensions.ARB_shadow) 728b8e80941Smrg return GL_FALSE; 729848b8605Smrg 730848b8605Smrg if (samp->CompareMode == param) 731848b8605Smrg return GL_FALSE; 732848b8605Smrg 733848b8605Smrg if (param == GL_NONE || 734848b8605Smrg param == GL_COMPARE_R_TO_TEXTURE_ARB) { 735848b8605Smrg flush(ctx); 736848b8605Smrg samp->CompareMode = param; 737848b8605Smrg return GL_TRUE; 738848b8605Smrg } 739848b8605Smrg 740848b8605Smrg return INVALID_PARAM; 741848b8605Smrg} 742848b8605Smrg 743848b8605Smrg 744848b8605Smrgstatic GLuint 745848b8605Smrgset_sampler_compare_func(struct gl_context *ctx, 746848b8605Smrg struct gl_sampler_object *samp, GLint param) 747848b8605Smrg{ 748b8e80941Smrg /* If GL_ARB_shadow is not supported, don't report an error. The 749b8e80941Smrg * sampler object extension spec isn't clear on this extension interaction. 750b8e80941Smrg * Silences errors with Wine on older GPUs such as R200. 751b8e80941Smrg */ 752848b8605Smrg if (!ctx->Extensions.ARB_shadow) 753b8e80941Smrg return GL_FALSE; 754848b8605Smrg 755848b8605Smrg if (samp->CompareFunc == param) 756848b8605Smrg return GL_FALSE; 757848b8605Smrg 758848b8605Smrg switch (param) { 759848b8605Smrg case GL_LEQUAL: 760848b8605Smrg case GL_GEQUAL: 761848b8605Smrg case GL_EQUAL: 762848b8605Smrg case GL_NOTEQUAL: 763848b8605Smrg case GL_LESS: 764848b8605Smrg case GL_GREATER: 765848b8605Smrg case GL_ALWAYS: 766848b8605Smrg case GL_NEVER: 767848b8605Smrg flush(ctx); 768848b8605Smrg samp->CompareFunc = param; 769848b8605Smrg return GL_TRUE; 770848b8605Smrg default: 771848b8605Smrg return INVALID_PARAM; 772848b8605Smrg } 773848b8605Smrg} 774848b8605Smrg 775848b8605Smrg 776848b8605Smrgstatic GLuint 777848b8605Smrgset_sampler_max_anisotropy(struct gl_context *ctx, 778848b8605Smrg struct gl_sampler_object *samp, GLfloat param) 779848b8605Smrg{ 780848b8605Smrg if (!ctx->Extensions.EXT_texture_filter_anisotropic) 781848b8605Smrg return INVALID_PNAME; 782848b8605Smrg 783848b8605Smrg if (samp->MaxAnisotropy == param) 784848b8605Smrg return GL_FALSE; 785848b8605Smrg 786b8e80941Smrg if (param < 1.0F) 787848b8605Smrg return INVALID_VALUE; 788848b8605Smrg 789848b8605Smrg flush(ctx); 790848b8605Smrg /* clamp to max, that's what NVIDIA does */ 791848b8605Smrg samp->MaxAnisotropy = MIN2(param, ctx->Const.MaxTextureMaxAnisotropy); 792848b8605Smrg return GL_TRUE; 793848b8605Smrg} 794848b8605Smrg 795848b8605Smrg 796848b8605Smrgstatic GLuint 797848b8605Smrgset_sampler_cube_map_seamless(struct gl_context *ctx, 798848b8605Smrg struct gl_sampler_object *samp, GLboolean param) 799848b8605Smrg{ 800848b8605Smrg if (!_mesa_is_desktop_gl(ctx) 801848b8605Smrg || !ctx->Extensions.AMD_seamless_cubemap_per_texture) 802848b8605Smrg return INVALID_PNAME; 803848b8605Smrg 804848b8605Smrg if (samp->CubeMapSeamless == param) 805848b8605Smrg return GL_FALSE; 806848b8605Smrg 807848b8605Smrg if (param != GL_TRUE && param != GL_FALSE) 808848b8605Smrg return INVALID_VALUE; 809848b8605Smrg 810848b8605Smrg flush(ctx); 811848b8605Smrg samp->CubeMapSeamless = param; 812848b8605Smrg return GL_TRUE; 813848b8605Smrg} 814848b8605Smrg 815b8e80941Smrgvoid 816b8e80941Smrg_mesa_set_sampler_srgb_decode(struct gl_context *ctx, 817b8e80941Smrg struct gl_sampler_object *samp, GLenum param) 818b8e80941Smrg{ 819b8e80941Smrg assert(param == GL_DECODE_EXT || param == GL_SKIP_DECODE_EXT); 820b8e80941Smrg 821b8e80941Smrg flush(ctx); 822b8e80941Smrg samp->sRGBDecode = param; 823b8e80941Smrg} 824b8e80941Smrg 825848b8605Smrgstatic GLuint 826848b8605Smrgset_sampler_srgb_decode(struct gl_context *ctx, 827848b8605Smrg struct gl_sampler_object *samp, GLenum param) 828848b8605Smrg{ 829848b8605Smrg if (!ctx->Extensions.EXT_texture_sRGB_decode) 830848b8605Smrg return INVALID_PNAME; 831848b8605Smrg 832848b8605Smrg if (samp->sRGBDecode == param) 833848b8605Smrg return GL_FALSE; 834848b8605Smrg 835b8e80941Smrg /* The EXT_texture_sRGB_decode spec says: 836b8e80941Smrg * 837b8e80941Smrg * "INVALID_ENUM is generated if the <pname> parameter of 838b8e80941Smrg * TexParameter[i,f,Ii,Iui][v][EXT], 839b8e80941Smrg * MultiTexParameter[i,f,Ii,Iui][v]EXT, 840b8e80941Smrg * TextureParameter[i,f,Ii,Iui][v]EXT, SamplerParameter[i,f,Ii,Iui][v] 841b8e80941Smrg * is TEXTURE_SRGB_DECODE_EXT when the <param> parameter is not one of 842b8e80941Smrg * DECODE_EXT or SKIP_DECODE_EXT. 843b8e80941Smrg * 844b8e80941Smrg * Returning INVALID_PARAM makes that happen. 845b8e80941Smrg */ 846848b8605Smrg if (param != GL_DECODE_EXT && param != GL_SKIP_DECODE_EXT) 847b8e80941Smrg return INVALID_PARAM; 848848b8605Smrg 849848b8605Smrg flush(ctx); 850848b8605Smrg samp->sRGBDecode = param; 851848b8605Smrg return GL_TRUE; 852848b8605Smrg} 853848b8605Smrg 854b8e80941Smrgstatic struct gl_sampler_object * 855b8e80941Smrgsampler_parameter_error_check(struct gl_context *ctx, GLuint sampler, 856b8e80941Smrg bool get, const char *name) 857b8e80941Smrg{ 858b8e80941Smrg struct gl_sampler_object *sampObj; 859b8e80941Smrg 860b8e80941Smrg sampObj = _mesa_lookup_samplerobj(ctx, sampler); 861b8e80941Smrg if (!sampObj) { 862b8e80941Smrg /* OpenGL 4.5 spec, section "8.2 Sampler Objects", page 176 of the PDF 863b8e80941Smrg * states: 864b8e80941Smrg * 865b8e80941Smrg * "An INVALID_OPERATION error is generated if sampler is not the name 866b8e80941Smrg * of a sampler object previously returned from a call to 867b8e80941Smrg * GenSamplers." 868b8e80941Smrg */ 869b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid sampler)", name); 870b8e80941Smrg return NULL; 871b8e80941Smrg } 872b8e80941Smrg 873b8e80941Smrg if (!get && sampObj->HandleAllocated) { 874b8e80941Smrg /* The ARB_bindless_texture spec says: 875b8e80941Smrg * 876b8e80941Smrg * "The error INVALID_OPERATION is generated by SamplerParameter* if 877b8e80941Smrg * <sampler> identifies a sampler object referenced by one or more 878b8e80941Smrg * texture handles." 879b8e80941Smrg */ 880b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s(immutable sampler)", name); 881b8e80941Smrg return NULL; 882b8e80941Smrg } 883b8e80941Smrg 884b8e80941Smrg return sampObj; 885b8e80941Smrg} 886b8e80941Smrg 887848b8605Smrgvoid GLAPIENTRY 888848b8605Smrg_mesa_SamplerParameteri(GLuint sampler, GLenum pname, GLint param) 889848b8605Smrg{ 890848b8605Smrg struct gl_sampler_object *sampObj; 891848b8605Smrg GLuint res; 892848b8605Smrg GET_CURRENT_CONTEXT(ctx); 893848b8605Smrg 894b8e80941Smrg sampObj = sampler_parameter_error_check(ctx, sampler, false, 895b8e80941Smrg "glSamplerParameteri"); 896b8e80941Smrg if (!sampObj) 897848b8605Smrg return; 898848b8605Smrg 899848b8605Smrg switch (pname) { 900848b8605Smrg case GL_TEXTURE_WRAP_S: 901848b8605Smrg res = set_sampler_wrap_s(ctx, sampObj, param); 902848b8605Smrg break; 903848b8605Smrg case GL_TEXTURE_WRAP_T: 904848b8605Smrg res = set_sampler_wrap_t(ctx, sampObj, param); 905848b8605Smrg break; 906848b8605Smrg case GL_TEXTURE_WRAP_R: 907848b8605Smrg res = set_sampler_wrap_r(ctx, sampObj, param); 908848b8605Smrg break; 909848b8605Smrg case GL_TEXTURE_MIN_FILTER: 910848b8605Smrg res = set_sampler_min_filter(ctx, sampObj, param); 911848b8605Smrg break; 912848b8605Smrg case GL_TEXTURE_MAG_FILTER: 913848b8605Smrg res = set_sampler_mag_filter(ctx, sampObj, param); 914848b8605Smrg break; 915848b8605Smrg case GL_TEXTURE_MIN_LOD: 916848b8605Smrg res = set_sampler_min_lod(ctx, sampObj, (GLfloat) param); 917848b8605Smrg break; 918848b8605Smrg case GL_TEXTURE_MAX_LOD: 919848b8605Smrg res = set_sampler_max_lod(ctx, sampObj, (GLfloat) param); 920848b8605Smrg break; 921848b8605Smrg case GL_TEXTURE_LOD_BIAS: 922848b8605Smrg res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) param); 923848b8605Smrg break; 924848b8605Smrg case GL_TEXTURE_COMPARE_MODE: 925848b8605Smrg res = set_sampler_compare_mode(ctx, sampObj, param); 926848b8605Smrg break; 927848b8605Smrg case GL_TEXTURE_COMPARE_FUNC: 928848b8605Smrg res = set_sampler_compare_func(ctx, sampObj, param); 929848b8605Smrg break; 930848b8605Smrg case GL_TEXTURE_MAX_ANISOTROPY_EXT: 931848b8605Smrg res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) param); 932848b8605Smrg break; 933848b8605Smrg case GL_TEXTURE_CUBE_MAP_SEAMLESS: 934848b8605Smrg res = set_sampler_cube_map_seamless(ctx, sampObj, param); 935848b8605Smrg break; 936848b8605Smrg case GL_TEXTURE_SRGB_DECODE_EXT: 937848b8605Smrg res = set_sampler_srgb_decode(ctx, sampObj, param); 938848b8605Smrg break; 939848b8605Smrg case GL_TEXTURE_BORDER_COLOR: 940848b8605Smrg /* fall-through */ 941848b8605Smrg default: 942848b8605Smrg res = INVALID_PNAME; 943848b8605Smrg } 944848b8605Smrg 945848b8605Smrg switch (res) { 946848b8605Smrg case GL_FALSE: 947848b8605Smrg /* no change */ 948848b8605Smrg break; 949848b8605Smrg case GL_TRUE: 950848b8605Smrg /* state change - we do nothing special at this time */ 951848b8605Smrg break; 952848b8605Smrg case INVALID_PNAME: 953848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteri(pname=%s)\n", 954b8e80941Smrg _mesa_enum_to_string(pname)); 955848b8605Smrg break; 956848b8605Smrg case INVALID_PARAM: 957848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteri(param=%d)\n", 958848b8605Smrg param); 959848b8605Smrg break; 960848b8605Smrg case INVALID_VALUE: 961848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameteri(param=%d)\n", 962848b8605Smrg param); 963848b8605Smrg break; 964848b8605Smrg default: 965848b8605Smrg ; 966848b8605Smrg } 967848b8605Smrg} 968848b8605Smrg 969848b8605Smrg 970848b8605Smrgvoid GLAPIENTRY 971848b8605Smrg_mesa_SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) 972848b8605Smrg{ 973848b8605Smrg struct gl_sampler_object *sampObj; 974848b8605Smrg GLuint res; 975848b8605Smrg GET_CURRENT_CONTEXT(ctx); 976848b8605Smrg 977b8e80941Smrg sampObj = sampler_parameter_error_check(ctx, sampler, false, 978b8e80941Smrg "glSamplerParameterf"); 979b8e80941Smrg if (!sampObj) 980848b8605Smrg return; 981848b8605Smrg 982848b8605Smrg switch (pname) { 983848b8605Smrg case GL_TEXTURE_WRAP_S: 984848b8605Smrg res = set_sampler_wrap_s(ctx, sampObj, (GLint) param); 985848b8605Smrg break; 986848b8605Smrg case GL_TEXTURE_WRAP_T: 987848b8605Smrg res = set_sampler_wrap_t(ctx, sampObj, (GLint) param); 988848b8605Smrg break; 989848b8605Smrg case GL_TEXTURE_WRAP_R: 990848b8605Smrg res = set_sampler_wrap_r(ctx, sampObj, (GLint) param); 991848b8605Smrg break; 992848b8605Smrg case GL_TEXTURE_MIN_FILTER: 993848b8605Smrg res = set_sampler_min_filter(ctx, sampObj, (GLint) param); 994848b8605Smrg break; 995848b8605Smrg case GL_TEXTURE_MAG_FILTER: 996848b8605Smrg res = set_sampler_mag_filter(ctx, sampObj, (GLint) param); 997848b8605Smrg break; 998848b8605Smrg case GL_TEXTURE_MIN_LOD: 999848b8605Smrg res = set_sampler_min_lod(ctx, sampObj, param); 1000848b8605Smrg break; 1001848b8605Smrg case GL_TEXTURE_MAX_LOD: 1002848b8605Smrg res = set_sampler_max_lod(ctx, sampObj, param); 1003848b8605Smrg break; 1004848b8605Smrg case GL_TEXTURE_LOD_BIAS: 1005848b8605Smrg res = set_sampler_lod_bias(ctx, sampObj, param); 1006848b8605Smrg break; 1007848b8605Smrg case GL_TEXTURE_COMPARE_MODE: 1008848b8605Smrg res = set_sampler_compare_mode(ctx, sampObj, (GLint) param); 1009848b8605Smrg break; 1010848b8605Smrg case GL_TEXTURE_COMPARE_FUNC: 1011848b8605Smrg res = set_sampler_compare_func(ctx, sampObj, (GLint) param); 1012848b8605Smrg break; 1013848b8605Smrg case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1014848b8605Smrg res = set_sampler_max_anisotropy(ctx, sampObj, param); 1015848b8605Smrg break; 1016848b8605Smrg case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1017848b8605Smrg res = set_sampler_cube_map_seamless(ctx, sampObj, (GLboolean) param); 1018848b8605Smrg break; 1019848b8605Smrg case GL_TEXTURE_SRGB_DECODE_EXT: 1020848b8605Smrg res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) param); 1021848b8605Smrg break; 1022848b8605Smrg case GL_TEXTURE_BORDER_COLOR: 1023848b8605Smrg /* fall-through */ 1024848b8605Smrg default: 1025848b8605Smrg res = INVALID_PNAME; 1026848b8605Smrg } 1027848b8605Smrg 1028848b8605Smrg switch (res) { 1029848b8605Smrg case GL_FALSE: 1030848b8605Smrg /* no change */ 1031848b8605Smrg break; 1032848b8605Smrg case GL_TRUE: 1033848b8605Smrg /* state change - we do nothing special at this time */ 1034848b8605Smrg break; 1035848b8605Smrg case INVALID_PNAME: 1036848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterf(pname=%s)\n", 1037b8e80941Smrg _mesa_enum_to_string(pname)); 1038848b8605Smrg break; 1039848b8605Smrg case INVALID_PARAM: 1040848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterf(param=%f)\n", 1041848b8605Smrg param); 1042848b8605Smrg break; 1043848b8605Smrg case INVALID_VALUE: 1044848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterf(param=%f)\n", 1045848b8605Smrg param); 1046848b8605Smrg break; 1047848b8605Smrg default: 1048848b8605Smrg ; 1049848b8605Smrg } 1050848b8605Smrg} 1051848b8605Smrg 1052848b8605Smrgvoid GLAPIENTRY 1053848b8605Smrg_mesa_SamplerParameteriv(GLuint sampler, GLenum pname, const GLint *params) 1054848b8605Smrg{ 1055848b8605Smrg struct gl_sampler_object *sampObj; 1056848b8605Smrg GLuint res; 1057848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1058848b8605Smrg 1059b8e80941Smrg sampObj = sampler_parameter_error_check(ctx, sampler, false, 1060b8e80941Smrg "glSamplerParameteriv"); 1061b8e80941Smrg if (!sampObj) 1062848b8605Smrg return; 1063848b8605Smrg 1064848b8605Smrg switch (pname) { 1065848b8605Smrg case GL_TEXTURE_WRAP_S: 1066848b8605Smrg res = set_sampler_wrap_s(ctx, sampObj, params[0]); 1067848b8605Smrg break; 1068848b8605Smrg case GL_TEXTURE_WRAP_T: 1069848b8605Smrg res = set_sampler_wrap_t(ctx, sampObj, params[0]); 1070848b8605Smrg break; 1071848b8605Smrg case GL_TEXTURE_WRAP_R: 1072848b8605Smrg res = set_sampler_wrap_r(ctx, sampObj, params[0]); 1073848b8605Smrg break; 1074848b8605Smrg case GL_TEXTURE_MIN_FILTER: 1075848b8605Smrg res = set_sampler_min_filter(ctx, sampObj, params[0]); 1076848b8605Smrg break; 1077848b8605Smrg case GL_TEXTURE_MAG_FILTER: 1078848b8605Smrg res = set_sampler_mag_filter(ctx, sampObj, params[0]); 1079848b8605Smrg break; 1080848b8605Smrg case GL_TEXTURE_MIN_LOD: 1081848b8605Smrg res = set_sampler_min_lod(ctx, sampObj, (GLfloat) params[0]); 1082848b8605Smrg break; 1083848b8605Smrg case GL_TEXTURE_MAX_LOD: 1084848b8605Smrg res = set_sampler_max_lod(ctx, sampObj, (GLfloat) params[0]); 1085848b8605Smrg break; 1086848b8605Smrg case GL_TEXTURE_LOD_BIAS: 1087848b8605Smrg res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) params[0]); 1088848b8605Smrg break; 1089848b8605Smrg case GL_TEXTURE_COMPARE_MODE: 1090848b8605Smrg res = set_sampler_compare_mode(ctx, sampObj, params[0]); 1091848b8605Smrg break; 1092848b8605Smrg case GL_TEXTURE_COMPARE_FUNC: 1093848b8605Smrg res = set_sampler_compare_func(ctx, sampObj, params[0]); 1094848b8605Smrg break; 1095848b8605Smrg case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1096848b8605Smrg res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) params[0]); 1097848b8605Smrg break; 1098848b8605Smrg case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1099848b8605Smrg res = set_sampler_cube_map_seamless(ctx, sampObj, params[0]); 1100848b8605Smrg break; 1101848b8605Smrg case GL_TEXTURE_SRGB_DECODE_EXT: 1102848b8605Smrg res = set_sampler_srgb_decode(ctx, sampObj, params[0]); 1103848b8605Smrg break; 1104848b8605Smrg case GL_TEXTURE_BORDER_COLOR: 1105848b8605Smrg { 1106848b8605Smrg GLfloat c[4]; 1107848b8605Smrg c[0] = INT_TO_FLOAT(params[0]); 1108848b8605Smrg c[1] = INT_TO_FLOAT(params[1]); 1109848b8605Smrg c[2] = INT_TO_FLOAT(params[2]); 1110848b8605Smrg c[3] = INT_TO_FLOAT(params[3]); 1111848b8605Smrg res = set_sampler_border_colorf(ctx, sampObj, c); 1112848b8605Smrg } 1113848b8605Smrg break; 1114848b8605Smrg default: 1115848b8605Smrg res = INVALID_PNAME; 1116848b8605Smrg } 1117848b8605Smrg 1118848b8605Smrg switch (res) { 1119848b8605Smrg case GL_FALSE: 1120848b8605Smrg /* no change */ 1121848b8605Smrg break; 1122848b8605Smrg case GL_TRUE: 1123848b8605Smrg /* state change - we do nothing special at this time */ 1124848b8605Smrg break; 1125848b8605Smrg case INVALID_PNAME: 1126848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteriv(pname=%s)\n", 1127b8e80941Smrg _mesa_enum_to_string(pname)); 1128848b8605Smrg break; 1129848b8605Smrg case INVALID_PARAM: 1130848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteriv(param=%d)\n", 1131848b8605Smrg params[0]); 1132848b8605Smrg break; 1133848b8605Smrg case INVALID_VALUE: 1134848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameteriv(param=%d)\n", 1135848b8605Smrg params[0]); 1136848b8605Smrg break; 1137848b8605Smrg default: 1138848b8605Smrg ; 1139848b8605Smrg } 1140848b8605Smrg} 1141848b8605Smrg 1142848b8605Smrgvoid GLAPIENTRY 1143848b8605Smrg_mesa_SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *params) 1144848b8605Smrg{ 1145848b8605Smrg struct gl_sampler_object *sampObj; 1146848b8605Smrg GLuint res; 1147848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1148848b8605Smrg 1149b8e80941Smrg sampObj = sampler_parameter_error_check(ctx, sampler, false, 1150b8e80941Smrg "glSamplerParameterfv"); 1151b8e80941Smrg if (!sampObj) 1152848b8605Smrg return; 1153848b8605Smrg 1154848b8605Smrg switch (pname) { 1155848b8605Smrg case GL_TEXTURE_WRAP_S: 1156848b8605Smrg res = set_sampler_wrap_s(ctx, sampObj, (GLint) params[0]); 1157848b8605Smrg break; 1158848b8605Smrg case GL_TEXTURE_WRAP_T: 1159848b8605Smrg res = set_sampler_wrap_t(ctx, sampObj, (GLint) params[0]); 1160848b8605Smrg break; 1161848b8605Smrg case GL_TEXTURE_WRAP_R: 1162848b8605Smrg res = set_sampler_wrap_r(ctx, sampObj, (GLint) params[0]); 1163848b8605Smrg break; 1164848b8605Smrg case GL_TEXTURE_MIN_FILTER: 1165848b8605Smrg res = set_sampler_min_filter(ctx, sampObj, (GLint) params[0]); 1166848b8605Smrg break; 1167848b8605Smrg case GL_TEXTURE_MAG_FILTER: 1168848b8605Smrg res = set_sampler_mag_filter(ctx, sampObj, (GLint) params[0]); 1169848b8605Smrg break; 1170848b8605Smrg case GL_TEXTURE_MIN_LOD: 1171848b8605Smrg res = set_sampler_min_lod(ctx, sampObj, params[0]); 1172848b8605Smrg break; 1173848b8605Smrg case GL_TEXTURE_MAX_LOD: 1174848b8605Smrg res = set_sampler_max_lod(ctx, sampObj, params[0]); 1175848b8605Smrg break; 1176848b8605Smrg case GL_TEXTURE_LOD_BIAS: 1177848b8605Smrg res = set_sampler_lod_bias(ctx, sampObj, params[0]); 1178848b8605Smrg break; 1179848b8605Smrg case GL_TEXTURE_COMPARE_MODE: 1180848b8605Smrg res = set_sampler_compare_mode(ctx, sampObj, (GLint) params[0]); 1181848b8605Smrg break; 1182848b8605Smrg case GL_TEXTURE_COMPARE_FUNC: 1183848b8605Smrg res = set_sampler_compare_func(ctx, sampObj, (GLint) params[0]); 1184848b8605Smrg break; 1185848b8605Smrg case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1186848b8605Smrg res = set_sampler_max_anisotropy(ctx, sampObj, params[0]); 1187848b8605Smrg break; 1188848b8605Smrg case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1189848b8605Smrg res = set_sampler_cube_map_seamless(ctx, sampObj, (GLboolean) params[0]); 1190848b8605Smrg break; 1191848b8605Smrg case GL_TEXTURE_SRGB_DECODE_EXT: 1192848b8605Smrg res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) params[0]); 1193848b8605Smrg break; 1194848b8605Smrg case GL_TEXTURE_BORDER_COLOR: 1195848b8605Smrg res = set_sampler_border_colorf(ctx, sampObj, params); 1196848b8605Smrg break; 1197848b8605Smrg default: 1198848b8605Smrg res = INVALID_PNAME; 1199848b8605Smrg } 1200848b8605Smrg 1201848b8605Smrg switch (res) { 1202848b8605Smrg case GL_FALSE: 1203848b8605Smrg /* no change */ 1204848b8605Smrg break; 1205848b8605Smrg case GL_TRUE: 1206848b8605Smrg /* state change - we do nothing special at this time */ 1207848b8605Smrg break; 1208848b8605Smrg case INVALID_PNAME: 1209848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterfv(pname=%s)\n", 1210b8e80941Smrg _mesa_enum_to_string(pname)); 1211848b8605Smrg break; 1212848b8605Smrg case INVALID_PARAM: 1213848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterfv(param=%f)\n", 1214848b8605Smrg params[0]); 1215848b8605Smrg break; 1216848b8605Smrg case INVALID_VALUE: 1217848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterfv(param=%f)\n", 1218848b8605Smrg params[0]); 1219848b8605Smrg break; 1220848b8605Smrg default: 1221848b8605Smrg ; 1222848b8605Smrg } 1223848b8605Smrg} 1224848b8605Smrg 1225848b8605Smrgvoid GLAPIENTRY 1226848b8605Smrg_mesa_SamplerParameterIiv(GLuint sampler, GLenum pname, const GLint *params) 1227848b8605Smrg{ 1228848b8605Smrg struct gl_sampler_object *sampObj; 1229848b8605Smrg GLuint res; 1230848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1231848b8605Smrg 1232b8e80941Smrg sampObj = sampler_parameter_error_check(ctx, sampler, false, 1233b8e80941Smrg "glSamplerParameterIiv"); 1234b8e80941Smrg if (!sampObj) 1235848b8605Smrg return; 1236848b8605Smrg 1237848b8605Smrg switch (pname) { 1238848b8605Smrg case GL_TEXTURE_WRAP_S: 1239848b8605Smrg res = set_sampler_wrap_s(ctx, sampObj, params[0]); 1240848b8605Smrg break; 1241848b8605Smrg case GL_TEXTURE_WRAP_T: 1242848b8605Smrg res = set_sampler_wrap_t(ctx, sampObj, params[0]); 1243848b8605Smrg break; 1244848b8605Smrg case GL_TEXTURE_WRAP_R: 1245848b8605Smrg res = set_sampler_wrap_r(ctx, sampObj, params[0]); 1246848b8605Smrg break; 1247848b8605Smrg case GL_TEXTURE_MIN_FILTER: 1248848b8605Smrg res = set_sampler_min_filter(ctx, sampObj, params[0]); 1249848b8605Smrg break; 1250848b8605Smrg case GL_TEXTURE_MAG_FILTER: 1251848b8605Smrg res = set_sampler_mag_filter(ctx, sampObj, params[0]); 1252848b8605Smrg break; 1253848b8605Smrg case GL_TEXTURE_MIN_LOD: 1254848b8605Smrg res = set_sampler_min_lod(ctx, sampObj, (GLfloat) params[0]); 1255848b8605Smrg break; 1256848b8605Smrg case GL_TEXTURE_MAX_LOD: 1257848b8605Smrg res = set_sampler_max_lod(ctx, sampObj, (GLfloat) params[0]); 1258848b8605Smrg break; 1259848b8605Smrg case GL_TEXTURE_LOD_BIAS: 1260848b8605Smrg res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) params[0]); 1261848b8605Smrg break; 1262848b8605Smrg case GL_TEXTURE_COMPARE_MODE: 1263848b8605Smrg res = set_sampler_compare_mode(ctx, sampObj, params[0]); 1264848b8605Smrg break; 1265848b8605Smrg case GL_TEXTURE_COMPARE_FUNC: 1266848b8605Smrg res = set_sampler_compare_func(ctx, sampObj, params[0]); 1267848b8605Smrg break; 1268848b8605Smrg case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1269848b8605Smrg res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) params[0]); 1270848b8605Smrg break; 1271848b8605Smrg case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1272848b8605Smrg res = set_sampler_cube_map_seamless(ctx, sampObj, params[0]); 1273848b8605Smrg break; 1274848b8605Smrg case GL_TEXTURE_SRGB_DECODE_EXT: 1275848b8605Smrg res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) params[0]); 1276848b8605Smrg break; 1277848b8605Smrg case GL_TEXTURE_BORDER_COLOR: 1278848b8605Smrg res = set_sampler_border_colori(ctx, sampObj, params); 1279848b8605Smrg break; 1280848b8605Smrg default: 1281848b8605Smrg res = INVALID_PNAME; 1282848b8605Smrg } 1283848b8605Smrg 1284848b8605Smrg switch (res) { 1285848b8605Smrg case GL_FALSE: 1286848b8605Smrg /* no change */ 1287848b8605Smrg break; 1288848b8605Smrg case GL_TRUE: 1289848b8605Smrg /* state change - we do nothing special at this time */ 1290848b8605Smrg break; 1291848b8605Smrg case INVALID_PNAME: 1292848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIiv(pname=%s)\n", 1293b8e80941Smrg _mesa_enum_to_string(pname)); 1294848b8605Smrg break; 1295848b8605Smrg case INVALID_PARAM: 1296848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIiv(param=%d)\n", 1297848b8605Smrg params[0]); 1298848b8605Smrg break; 1299848b8605Smrg case INVALID_VALUE: 1300848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIiv(param=%d)\n", 1301848b8605Smrg params[0]); 1302848b8605Smrg break; 1303848b8605Smrg default: 1304848b8605Smrg ; 1305848b8605Smrg } 1306848b8605Smrg} 1307848b8605Smrg 1308848b8605Smrg 1309848b8605Smrgvoid GLAPIENTRY 1310848b8605Smrg_mesa_SamplerParameterIuiv(GLuint sampler, GLenum pname, const GLuint *params) 1311848b8605Smrg{ 1312848b8605Smrg struct gl_sampler_object *sampObj; 1313848b8605Smrg GLuint res; 1314848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1315848b8605Smrg 1316b8e80941Smrg sampObj = sampler_parameter_error_check(ctx, sampler, false, 1317b8e80941Smrg "glSamplerParameterIuiv"); 1318b8e80941Smrg if (!sampObj) 1319848b8605Smrg return; 1320848b8605Smrg 1321848b8605Smrg switch (pname) { 1322848b8605Smrg case GL_TEXTURE_WRAP_S: 1323848b8605Smrg res = set_sampler_wrap_s(ctx, sampObj, params[0]); 1324848b8605Smrg break; 1325848b8605Smrg case GL_TEXTURE_WRAP_T: 1326848b8605Smrg res = set_sampler_wrap_t(ctx, sampObj, params[0]); 1327848b8605Smrg break; 1328848b8605Smrg case GL_TEXTURE_WRAP_R: 1329848b8605Smrg res = set_sampler_wrap_r(ctx, sampObj, params[0]); 1330848b8605Smrg break; 1331848b8605Smrg case GL_TEXTURE_MIN_FILTER: 1332848b8605Smrg res = set_sampler_min_filter(ctx, sampObj, params[0]); 1333848b8605Smrg break; 1334848b8605Smrg case GL_TEXTURE_MAG_FILTER: 1335848b8605Smrg res = set_sampler_mag_filter(ctx, sampObj, params[0]); 1336848b8605Smrg break; 1337848b8605Smrg case GL_TEXTURE_MIN_LOD: 1338848b8605Smrg res = set_sampler_min_lod(ctx, sampObj, (GLfloat) params[0]); 1339848b8605Smrg break; 1340848b8605Smrg case GL_TEXTURE_MAX_LOD: 1341848b8605Smrg res = set_sampler_max_lod(ctx, sampObj, (GLfloat) params[0]); 1342848b8605Smrg break; 1343848b8605Smrg case GL_TEXTURE_LOD_BIAS: 1344848b8605Smrg res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) params[0]); 1345848b8605Smrg break; 1346848b8605Smrg case GL_TEXTURE_COMPARE_MODE: 1347848b8605Smrg res = set_sampler_compare_mode(ctx, sampObj, params[0]); 1348848b8605Smrg break; 1349848b8605Smrg case GL_TEXTURE_COMPARE_FUNC: 1350848b8605Smrg res = set_sampler_compare_func(ctx, sampObj, params[0]); 1351848b8605Smrg break; 1352848b8605Smrg case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1353848b8605Smrg res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) params[0]); 1354848b8605Smrg break; 1355848b8605Smrg case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1356848b8605Smrg res = set_sampler_cube_map_seamless(ctx, sampObj, params[0]); 1357848b8605Smrg break; 1358848b8605Smrg case GL_TEXTURE_SRGB_DECODE_EXT: 1359848b8605Smrg res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) params[0]); 1360848b8605Smrg break; 1361848b8605Smrg case GL_TEXTURE_BORDER_COLOR: 1362848b8605Smrg res = set_sampler_border_colorui(ctx, sampObj, params); 1363848b8605Smrg break; 1364848b8605Smrg default: 1365848b8605Smrg res = INVALID_PNAME; 1366848b8605Smrg } 1367848b8605Smrg 1368848b8605Smrg switch (res) { 1369848b8605Smrg case GL_FALSE: 1370848b8605Smrg /* no change */ 1371848b8605Smrg break; 1372848b8605Smrg case GL_TRUE: 1373848b8605Smrg /* state change - we do nothing special at this time */ 1374848b8605Smrg break; 1375848b8605Smrg case INVALID_PNAME: 1376848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIuiv(pname=%s)\n", 1377b8e80941Smrg _mesa_enum_to_string(pname)); 1378848b8605Smrg break; 1379848b8605Smrg case INVALID_PARAM: 1380848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIuiv(param=%u)\n", 1381848b8605Smrg params[0]); 1382848b8605Smrg break; 1383848b8605Smrg case INVALID_VALUE: 1384848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIuiv(param=%u)\n", 1385848b8605Smrg params[0]); 1386848b8605Smrg break; 1387848b8605Smrg default: 1388848b8605Smrg ; 1389848b8605Smrg } 1390848b8605Smrg} 1391848b8605Smrg 1392848b8605Smrg 1393848b8605Smrgvoid GLAPIENTRY 1394848b8605Smrg_mesa_GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params) 1395848b8605Smrg{ 1396848b8605Smrg struct gl_sampler_object *sampObj; 1397848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1398848b8605Smrg 1399b8e80941Smrg sampObj = sampler_parameter_error_check(ctx, sampler, true, 1400b8e80941Smrg "glGetSamplerParameteriv"); 1401b8e80941Smrg if (!sampObj) 1402848b8605Smrg return; 1403848b8605Smrg 1404848b8605Smrg switch (pname) { 1405848b8605Smrg case GL_TEXTURE_WRAP_S: 1406848b8605Smrg *params = sampObj->WrapS; 1407848b8605Smrg break; 1408848b8605Smrg case GL_TEXTURE_WRAP_T: 1409848b8605Smrg *params = sampObj->WrapT; 1410848b8605Smrg break; 1411848b8605Smrg case GL_TEXTURE_WRAP_R: 1412848b8605Smrg *params = sampObj->WrapR; 1413848b8605Smrg break; 1414848b8605Smrg case GL_TEXTURE_MIN_FILTER: 1415848b8605Smrg *params = sampObj->MinFilter; 1416848b8605Smrg break; 1417848b8605Smrg case GL_TEXTURE_MAG_FILTER: 1418848b8605Smrg *params = sampObj->MagFilter; 1419848b8605Smrg break; 1420848b8605Smrg case GL_TEXTURE_MIN_LOD: 1421b8e80941Smrg /* GL spec 'Data Conversions' section specifies that floating-point 1422b8e80941Smrg * value in integer Get function is rounded to nearest integer 1423b8e80941Smrg */ 1424b8e80941Smrg *params = IROUND(sampObj->MinLod); 1425848b8605Smrg break; 1426848b8605Smrg case GL_TEXTURE_MAX_LOD: 1427b8e80941Smrg /* GL spec 'Data Conversions' section specifies that floating-point 1428b8e80941Smrg * value in integer Get function is rounded to nearest integer 1429b8e80941Smrg */ 1430b8e80941Smrg *params = IROUND(sampObj->MaxLod); 1431848b8605Smrg break; 1432848b8605Smrg case GL_TEXTURE_LOD_BIAS: 1433b8e80941Smrg /* GL spec 'Data Conversions' section specifies that floating-point 1434b8e80941Smrg * value in integer Get function is rounded to nearest integer 1435b8e80941Smrg */ 1436b8e80941Smrg *params = IROUND(sampObj->LodBias); 1437848b8605Smrg break; 1438848b8605Smrg case GL_TEXTURE_COMPARE_MODE: 1439848b8605Smrg *params = sampObj->CompareMode; 1440848b8605Smrg break; 1441848b8605Smrg case GL_TEXTURE_COMPARE_FUNC: 1442848b8605Smrg *params = sampObj->CompareFunc; 1443848b8605Smrg break; 1444848b8605Smrg case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1445b8e80941Smrg /* GL spec 'Data Conversions' section specifies that floating-point 1446b8e80941Smrg * value in integer Get function is rounded to nearest integer 1447b8e80941Smrg */ 1448b8e80941Smrg *params = IROUND(sampObj->MaxAnisotropy); 1449848b8605Smrg break; 1450848b8605Smrg case GL_TEXTURE_BORDER_COLOR: 1451848b8605Smrg params[0] = FLOAT_TO_INT(sampObj->BorderColor.f[0]); 1452848b8605Smrg params[1] = FLOAT_TO_INT(sampObj->BorderColor.f[1]); 1453848b8605Smrg params[2] = FLOAT_TO_INT(sampObj->BorderColor.f[2]); 1454848b8605Smrg params[3] = FLOAT_TO_INT(sampObj->BorderColor.f[3]); 1455848b8605Smrg break; 1456848b8605Smrg case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1457848b8605Smrg if (!ctx->Extensions.AMD_seamless_cubemap_per_texture) 1458848b8605Smrg goto invalid_pname; 1459848b8605Smrg *params = sampObj->CubeMapSeamless; 1460848b8605Smrg break; 1461848b8605Smrg case GL_TEXTURE_SRGB_DECODE_EXT: 1462848b8605Smrg if (!ctx->Extensions.EXT_texture_sRGB_decode) 1463848b8605Smrg goto invalid_pname; 1464848b8605Smrg *params = (GLenum) sampObj->sRGBDecode; 1465848b8605Smrg break; 1466848b8605Smrg default: 1467848b8605Smrg goto invalid_pname; 1468848b8605Smrg } 1469848b8605Smrg return; 1470848b8605Smrg 1471848b8605Smrginvalid_pname: 1472848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameteriv(pname=%s)", 1473b8e80941Smrg _mesa_enum_to_string(pname)); 1474848b8605Smrg} 1475848b8605Smrg 1476848b8605Smrg 1477848b8605Smrgvoid GLAPIENTRY 1478848b8605Smrg_mesa_GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params) 1479848b8605Smrg{ 1480848b8605Smrg struct gl_sampler_object *sampObj; 1481848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1482848b8605Smrg 1483b8e80941Smrg sampObj = sampler_parameter_error_check(ctx, sampler, true, 1484b8e80941Smrg "glGetSamplerParameterfv"); 1485b8e80941Smrg if (!sampObj) 1486848b8605Smrg return; 1487848b8605Smrg 1488848b8605Smrg switch (pname) { 1489848b8605Smrg case GL_TEXTURE_WRAP_S: 1490848b8605Smrg *params = (GLfloat) sampObj->WrapS; 1491848b8605Smrg break; 1492848b8605Smrg case GL_TEXTURE_WRAP_T: 1493848b8605Smrg *params = (GLfloat) sampObj->WrapT; 1494848b8605Smrg break; 1495848b8605Smrg case GL_TEXTURE_WRAP_R: 1496848b8605Smrg *params = (GLfloat) sampObj->WrapR; 1497848b8605Smrg break; 1498848b8605Smrg case GL_TEXTURE_MIN_FILTER: 1499848b8605Smrg *params = (GLfloat) sampObj->MinFilter; 1500848b8605Smrg break; 1501848b8605Smrg case GL_TEXTURE_MAG_FILTER: 1502848b8605Smrg *params = (GLfloat) sampObj->MagFilter; 1503848b8605Smrg break; 1504848b8605Smrg case GL_TEXTURE_MIN_LOD: 1505848b8605Smrg *params = sampObj->MinLod; 1506848b8605Smrg break; 1507848b8605Smrg case GL_TEXTURE_MAX_LOD: 1508848b8605Smrg *params = sampObj->MaxLod; 1509848b8605Smrg break; 1510848b8605Smrg case GL_TEXTURE_LOD_BIAS: 1511848b8605Smrg *params = sampObj->LodBias; 1512848b8605Smrg break; 1513848b8605Smrg case GL_TEXTURE_COMPARE_MODE: 1514848b8605Smrg *params = (GLfloat) sampObj->CompareMode; 1515848b8605Smrg break; 1516848b8605Smrg case GL_TEXTURE_COMPARE_FUNC: 1517848b8605Smrg *params = (GLfloat) sampObj->CompareFunc; 1518848b8605Smrg break; 1519848b8605Smrg case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1520848b8605Smrg *params = sampObj->MaxAnisotropy; 1521848b8605Smrg break; 1522848b8605Smrg case GL_TEXTURE_BORDER_COLOR: 1523848b8605Smrg params[0] = sampObj->BorderColor.f[0]; 1524848b8605Smrg params[1] = sampObj->BorderColor.f[1]; 1525848b8605Smrg params[2] = sampObj->BorderColor.f[2]; 1526848b8605Smrg params[3] = sampObj->BorderColor.f[3]; 1527848b8605Smrg break; 1528848b8605Smrg case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1529848b8605Smrg if (!ctx->Extensions.AMD_seamless_cubemap_per_texture) 1530848b8605Smrg goto invalid_pname; 1531848b8605Smrg *params = (GLfloat) sampObj->CubeMapSeamless; 1532848b8605Smrg break; 1533848b8605Smrg case GL_TEXTURE_SRGB_DECODE_EXT: 1534848b8605Smrg if (!ctx->Extensions.EXT_texture_sRGB_decode) 1535848b8605Smrg goto invalid_pname; 1536848b8605Smrg *params = (GLfloat) sampObj->sRGBDecode; 1537848b8605Smrg break; 1538848b8605Smrg default: 1539848b8605Smrg goto invalid_pname; 1540848b8605Smrg } 1541848b8605Smrg return; 1542848b8605Smrg 1543848b8605Smrginvalid_pname: 1544848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameterfv(pname=%s)", 1545b8e80941Smrg _mesa_enum_to_string(pname)); 1546848b8605Smrg} 1547848b8605Smrg 1548848b8605Smrg 1549848b8605Smrgvoid GLAPIENTRY 1550848b8605Smrg_mesa_GetSamplerParameterIiv(GLuint sampler, GLenum pname, GLint *params) 1551848b8605Smrg{ 1552848b8605Smrg struct gl_sampler_object *sampObj; 1553848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1554848b8605Smrg 1555b8e80941Smrg sampObj = sampler_parameter_error_check(ctx, sampler, true, 1556b8e80941Smrg "glGetSamplerParameterIiv"); 1557b8e80941Smrg if (!sampObj) 1558848b8605Smrg return; 1559848b8605Smrg 1560848b8605Smrg switch (pname) { 1561848b8605Smrg case GL_TEXTURE_WRAP_S: 1562848b8605Smrg *params = sampObj->WrapS; 1563848b8605Smrg break; 1564848b8605Smrg case GL_TEXTURE_WRAP_T: 1565848b8605Smrg *params = sampObj->WrapT; 1566848b8605Smrg break; 1567848b8605Smrg case GL_TEXTURE_WRAP_R: 1568848b8605Smrg *params = sampObj->WrapR; 1569848b8605Smrg break; 1570848b8605Smrg case GL_TEXTURE_MIN_FILTER: 1571848b8605Smrg *params = sampObj->MinFilter; 1572848b8605Smrg break; 1573848b8605Smrg case GL_TEXTURE_MAG_FILTER: 1574848b8605Smrg *params = sampObj->MagFilter; 1575848b8605Smrg break; 1576848b8605Smrg case GL_TEXTURE_MIN_LOD: 1577848b8605Smrg *params = (GLint) sampObj->MinLod; 1578848b8605Smrg break; 1579848b8605Smrg case GL_TEXTURE_MAX_LOD: 1580848b8605Smrg *params = (GLint) sampObj->MaxLod; 1581848b8605Smrg break; 1582848b8605Smrg case GL_TEXTURE_LOD_BIAS: 1583848b8605Smrg *params = (GLint) sampObj->LodBias; 1584848b8605Smrg break; 1585848b8605Smrg case GL_TEXTURE_COMPARE_MODE: 1586848b8605Smrg *params = sampObj->CompareMode; 1587848b8605Smrg break; 1588848b8605Smrg case GL_TEXTURE_COMPARE_FUNC: 1589848b8605Smrg *params = sampObj->CompareFunc; 1590848b8605Smrg break; 1591848b8605Smrg case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1592848b8605Smrg *params = (GLint) sampObj->MaxAnisotropy; 1593848b8605Smrg break; 1594848b8605Smrg case GL_TEXTURE_BORDER_COLOR: 1595848b8605Smrg params[0] = sampObj->BorderColor.i[0]; 1596848b8605Smrg params[1] = sampObj->BorderColor.i[1]; 1597848b8605Smrg params[2] = sampObj->BorderColor.i[2]; 1598848b8605Smrg params[3] = sampObj->BorderColor.i[3]; 1599848b8605Smrg break; 1600848b8605Smrg case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1601848b8605Smrg if (!ctx->Extensions.AMD_seamless_cubemap_per_texture) 1602848b8605Smrg goto invalid_pname; 1603848b8605Smrg *params = sampObj->CubeMapSeamless; 1604848b8605Smrg break; 1605848b8605Smrg case GL_TEXTURE_SRGB_DECODE_EXT: 1606848b8605Smrg if (!ctx->Extensions.EXT_texture_sRGB_decode) 1607848b8605Smrg goto invalid_pname; 1608848b8605Smrg *params = (GLenum) sampObj->sRGBDecode; 1609848b8605Smrg break; 1610848b8605Smrg default: 1611848b8605Smrg goto invalid_pname; 1612848b8605Smrg } 1613848b8605Smrg return; 1614848b8605Smrg 1615848b8605Smrginvalid_pname: 1616848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameterIiv(pname=%s)", 1617b8e80941Smrg _mesa_enum_to_string(pname)); 1618848b8605Smrg} 1619848b8605Smrg 1620848b8605Smrg 1621848b8605Smrgvoid GLAPIENTRY 1622848b8605Smrg_mesa_GetSamplerParameterIuiv(GLuint sampler, GLenum pname, GLuint *params) 1623848b8605Smrg{ 1624848b8605Smrg struct gl_sampler_object *sampObj; 1625848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1626848b8605Smrg 1627b8e80941Smrg sampObj = sampler_parameter_error_check(ctx, sampler, true, 1628b8e80941Smrg "glGetSamplerParameterIuiv"); 1629b8e80941Smrg if (!sampObj) 1630848b8605Smrg return; 1631848b8605Smrg 1632848b8605Smrg switch (pname) { 1633848b8605Smrg case GL_TEXTURE_WRAP_S: 1634848b8605Smrg *params = sampObj->WrapS; 1635848b8605Smrg break; 1636848b8605Smrg case GL_TEXTURE_WRAP_T: 1637848b8605Smrg *params = sampObj->WrapT; 1638848b8605Smrg break; 1639848b8605Smrg case GL_TEXTURE_WRAP_R: 1640848b8605Smrg *params = sampObj->WrapR; 1641848b8605Smrg break; 1642848b8605Smrg case GL_TEXTURE_MIN_FILTER: 1643848b8605Smrg *params = sampObj->MinFilter; 1644848b8605Smrg break; 1645848b8605Smrg case GL_TEXTURE_MAG_FILTER: 1646848b8605Smrg *params = sampObj->MagFilter; 1647848b8605Smrg break; 1648848b8605Smrg case GL_TEXTURE_MIN_LOD: 1649848b8605Smrg *params = (GLuint) sampObj->MinLod; 1650848b8605Smrg break; 1651848b8605Smrg case GL_TEXTURE_MAX_LOD: 1652848b8605Smrg *params = (GLuint) sampObj->MaxLod; 1653848b8605Smrg break; 1654848b8605Smrg case GL_TEXTURE_LOD_BIAS: 1655848b8605Smrg *params = (GLuint) sampObj->LodBias; 1656848b8605Smrg break; 1657848b8605Smrg case GL_TEXTURE_COMPARE_MODE: 1658848b8605Smrg *params = sampObj->CompareMode; 1659848b8605Smrg break; 1660848b8605Smrg case GL_TEXTURE_COMPARE_FUNC: 1661848b8605Smrg *params = sampObj->CompareFunc; 1662848b8605Smrg break; 1663848b8605Smrg case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1664848b8605Smrg *params = (GLuint) sampObj->MaxAnisotropy; 1665848b8605Smrg break; 1666848b8605Smrg case GL_TEXTURE_BORDER_COLOR: 1667848b8605Smrg params[0] = sampObj->BorderColor.ui[0]; 1668848b8605Smrg params[1] = sampObj->BorderColor.ui[1]; 1669848b8605Smrg params[2] = sampObj->BorderColor.ui[2]; 1670848b8605Smrg params[3] = sampObj->BorderColor.ui[3]; 1671848b8605Smrg break; 1672848b8605Smrg case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1673848b8605Smrg if (!ctx->Extensions.AMD_seamless_cubemap_per_texture) 1674848b8605Smrg goto invalid_pname; 1675848b8605Smrg *params = sampObj->CubeMapSeamless; 1676848b8605Smrg break; 1677848b8605Smrg case GL_TEXTURE_SRGB_DECODE_EXT: 1678848b8605Smrg if (!ctx->Extensions.EXT_texture_sRGB_decode) 1679848b8605Smrg goto invalid_pname; 1680848b8605Smrg *params = (GLenum) sampObj->sRGBDecode; 1681848b8605Smrg break; 1682848b8605Smrg default: 1683848b8605Smrg goto invalid_pname; 1684848b8605Smrg } 1685848b8605Smrg return; 1686848b8605Smrg 1687848b8605Smrginvalid_pname: 1688848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameterIuiv(pname=%s)", 1689b8e80941Smrg _mesa_enum_to_string(pname)); 1690848b8605Smrg} 1691848b8605Smrg 1692848b8605Smrg 1693848b8605Smrgvoid 1694848b8605Smrg_mesa_init_sampler_object_functions(struct dd_function_table *driver) 1695848b8605Smrg{ 1696848b8605Smrg driver->NewSamplerObject = _mesa_new_sampler_object; 1697848b8605Smrg} 1698