1848b8605Smrg/* 2848b8605Smrg * Mesa 3-D graphics library 3848b8605Smrg * 4848b8605Smrg * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5848b8605Smrg * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 6848b8605Smrg * 7848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 8848b8605Smrg * copy of this software and associated documentation files (the "Software"), 9848b8605Smrg * to deal in the Software without restriction, including without limitation 10848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the 12848b8605Smrg * Software is furnished to do so, subject to the following conditions: 13848b8605Smrg * 14848b8605Smrg * The above copyright notice and this permission notice shall be included 15848b8605Smrg * in all copies or substantial portions of the Software. 16848b8605Smrg * 17848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21848b8605Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22848b8605Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23848b8605Smrg * OTHER DEALINGS IN THE SOFTWARE. 24848b8605Smrg */ 25848b8605Smrg 26848b8605Smrg/** 27848b8605Smrg * \file texparam.c 28848b8605Smrg * 29848b8605Smrg * glTexParameter-related functions 30848b8605Smrg */ 31848b8605Smrg 32848b8605Smrg#include <stdbool.h> 33848b8605Smrg#include "main/glheader.h" 34848b8605Smrg#include "main/blend.h" 35848b8605Smrg#include "main/context.h" 36848b8605Smrg#include "main/enums.h" 37848b8605Smrg#include "main/formats.h" 38848b8605Smrg#include "main/glformats.h" 39848b8605Smrg#include "main/macros.h" 40848b8605Smrg#include "main/mtypes.h" 41848b8605Smrg#include "main/state.h" 42848b8605Smrg#include "main/texcompress.h" 43848b8605Smrg#include "main/texobj.h" 44848b8605Smrg#include "main/texparam.h" 45848b8605Smrg#include "main/teximage.h" 46848b8605Smrg#include "main/texstate.h" 47848b8605Smrg#include "program/prog_instruction.h" 48848b8605Smrg 49848b8605Smrg 50848b8605Smrg/** 51848b8605Smrg * Check if a coordinate wrap mode is supported for the texture target. 52848b8605Smrg * \return GL_TRUE if legal, GL_FALSE otherwise 53848b8605Smrg */ 54848b8605Smrgstatic GLboolean 55848b8605Smrgvalidate_texture_wrap_mode(struct gl_context * ctx, GLenum target, GLenum wrap) 56848b8605Smrg{ 57848b8605Smrg const struct gl_extensions * const e = & ctx->Extensions; 58848b8605Smrg const bool is_desktop_gl = _mesa_is_desktop_gl(ctx); 59848b8605Smrg bool supported; 60848b8605Smrg 61848b8605Smrg switch (wrap) { 62848b8605Smrg case GL_CLAMP: 63848b8605Smrg /* GL_CLAMP was removed in the core profile, and it has never existed in 64848b8605Smrg * OpenGL ES. 65848b8605Smrg */ 66848b8605Smrg supported = (ctx->API == API_OPENGL_COMPAT) 67848b8605Smrg && (target != GL_TEXTURE_EXTERNAL_OES); 68848b8605Smrg break; 69848b8605Smrg 70848b8605Smrg case GL_CLAMP_TO_EDGE: 71848b8605Smrg supported = true; 72848b8605Smrg break; 73848b8605Smrg 74848b8605Smrg case GL_CLAMP_TO_BORDER: 75b8e80941Smrg supported = ctx->API != API_OPENGLES && e->ARB_texture_border_clamp 76848b8605Smrg && (target != GL_TEXTURE_EXTERNAL_OES); 77848b8605Smrg break; 78848b8605Smrg 79848b8605Smrg case GL_REPEAT: 80848b8605Smrg case GL_MIRRORED_REPEAT: 81848b8605Smrg supported = (target != GL_TEXTURE_RECTANGLE_NV) 82848b8605Smrg && (target != GL_TEXTURE_EXTERNAL_OES); 83848b8605Smrg break; 84848b8605Smrg 85848b8605Smrg case GL_MIRROR_CLAMP_EXT: 86848b8605Smrg supported = is_desktop_gl 87848b8605Smrg && (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp) 88848b8605Smrg && (target != GL_TEXTURE_RECTANGLE_NV) 89848b8605Smrg && (target != GL_TEXTURE_EXTERNAL_OES); 90848b8605Smrg break; 91848b8605Smrg 92848b8605Smrg case GL_MIRROR_CLAMP_TO_EDGE_EXT: 93848b8605Smrg supported = is_desktop_gl 94848b8605Smrg && (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp || e->ARB_texture_mirror_clamp_to_edge) 95848b8605Smrg && (target != GL_TEXTURE_RECTANGLE_NV) 96848b8605Smrg && (target != GL_TEXTURE_EXTERNAL_OES); 97848b8605Smrg break; 98848b8605Smrg 99848b8605Smrg case GL_MIRROR_CLAMP_TO_BORDER_EXT: 100848b8605Smrg supported = is_desktop_gl && e->EXT_texture_mirror_clamp 101848b8605Smrg && (target != GL_TEXTURE_RECTANGLE_NV) 102848b8605Smrg && (target != GL_TEXTURE_EXTERNAL_OES); 103848b8605Smrg break; 104848b8605Smrg 105848b8605Smrg default: 106848b8605Smrg supported = false; 107848b8605Smrg break; 108848b8605Smrg } 109848b8605Smrg 110848b8605Smrg if (!supported) 111848b8605Smrg _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)", wrap ); 112848b8605Smrg 113848b8605Smrg return supported; 114848b8605Smrg} 115848b8605Smrg 116848b8605Smrg 117848b8605Smrg/** 118848b8605Smrg * Get current texture object for given target. 119848b8605Smrg * Return NULL if any error (and record the error). 120848b8605Smrg * Note that this is different from _mesa_get_current_tex_object() in that 121848b8605Smrg * proxy targets are not accepted. 122848b8605Smrg * Only the glGetTexLevelParameter() functions accept proxy targets. 123848b8605Smrg */ 124848b8605Smrgstatic struct gl_texture_object * 125b8e80941Smrgget_texobj_by_target(struct gl_context *ctx, GLenum target, GLboolean get) 126848b8605Smrg{ 127848b8605Smrg struct gl_texture_unit *texUnit; 128848b8605Smrg int targetIndex; 129848b8605Smrg 130848b8605Smrg if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) { 131848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 132848b8605Smrg "gl%sTexParameter(current unit)", get ? "Get" : ""); 133848b8605Smrg return NULL; 134848b8605Smrg } 135848b8605Smrg 136848b8605Smrg texUnit = _mesa_get_current_tex_unit(ctx); 137848b8605Smrg 138848b8605Smrg targetIndex = _mesa_tex_target_to_index(ctx, target); 139848b8605Smrg if (targetIndex < 0 || targetIndex == TEXTURE_BUFFER_INDEX) { 140848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, 141848b8605Smrg "gl%sTexParameter(target)", get ? "Get" : ""); 142848b8605Smrg return NULL; 143848b8605Smrg } 144848b8605Smrg assert(targetIndex < NUM_TEXTURE_TARGETS); 145848b8605Smrg 146848b8605Smrg return texUnit->CurrentTex[targetIndex]; 147848b8605Smrg} 148848b8605Smrg 149b8e80941Smrg/** 150b8e80941Smrg * Get current texture object for given name. 151b8e80941Smrg * Return NULL if any error (and record the error). 152b8e80941Smrg * Note that proxy targets are not accepted. 153b8e80941Smrg * Only the glGetTexLevelParameter() functions accept proxy targets. 154b8e80941Smrg */ 155b8e80941Smrgstatic struct gl_texture_object * 156b8e80941Smrgget_texobj_by_name(struct gl_context *ctx, GLuint texture, const char *name) 157b8e80941Smrg{ 158b8e80941Smrg struct gl_texture_object *texObj; 159b8e80941Smrg 160b8e80941Smrg texObj = _mesa_lookup_texture_err(ctx, texture, name); 161b8e80941Smrg if (!texObj) 162b8e80941Smrg return NULL; 163b8e80941Smrg 164b8e80941Smrg switch (texObj->Target) { 165b8e80941Smrg case GL_TEXTURE_1D: 166b8e80941Smrg case GL_TEXTURE_1D_ARRAY: 167b8e80941Smrg case GL_TEXTURE_2D: 168b8e80941Smrg case GL_TEXTURE_2D_ARRAY: 169b8e80941Smrg case GL_TEXTURE_2D_MULTISAMPLE: 170b8e80941Smrg case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 171b8e80941Smrg case GL_TEXTURE_3D: 172b8e80941Smrg case GL_TEXTURE_CUBE_MAP: 173b8e80941Smrg case GL_TEXTURE_CUBE_MAP_ARRAY: 174b8e80941Smrg case GL_TEXTURE_RECTANGLE: 175b8e80941Smrg return texObj; 176b8e80941Smrg default: 177b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s(target)", name); 178b8e80941Smrg return NULL; 179b8e80941Smrg } 180b8e80941Smrg 181b8e80941Smrg} 182b8e80941Smrg 183848b8605Smrg 184848b8605Smrg/** 185848b8605Smrg * Convert GL_RED/GREEN/BLUE/ALPHA/ZERO/ONE to SWIZZLE_X/Y/Z/W/ZERO/ONE. 186848b8605Smrg * \return -1 if error. 187848b8605Smrg */ 188848b8605Smrgstatic GLint 189848b8605Smrgcomp_to_swizzle(GLenum comp) 190848b8605Smrg{ 191848b8605Smrg switch (comp) { 192848b8605Smrg case GL_RED: 193848b8605Smrg return SWIZZLE_X; 194848b8605Smrg case GL_GREEN: 195848b8605Smrg return SWIZZLE_Y; 196848b8605Smrg case GL_BLUE: 197848b8605Smrg return SWIZZLE_Z; 198848b8605Smrg case GL_ALPHA: 199848b8605Smrg return SWIZZLE_W; 200848b8605Smrg case GL_ZERO: 201848b8605Smrg return SWIZZLE_ZERO; 202848b8605Smrg case GL_ONE: 203848b8605Smrg return SWIZZLE_ONE; 204848b8605Smrg default: 205848b8605Smrg return -1; 206848b8605Smrg } 207848b8605Smrg} 208848b8605Smrg 209848b8605Smrg 210848b8605Smrgstatic void 211b8e80941Smrgset_swizzle_component(GLushort *swizzle, GLuint comp, GLuint swz) 212848b8605Smrg{ 213b8e80941Smrg assert(comp < 4); 214b8e80941Smrg assert(swz <= SWIZZLE_NIL); 215848b8605Smrg { 216848b8605Smrg GLuint mask = 0x7 << (3 * comp); 217848b8605Smrg GLuint s = (*swizzle & ~mask) | (swz << (3 * comp)); 218848b8605Smrg *swizzle = s; 219848b8605Smrg } 220848b8605Smrg} 221848b8605Smrg 222848b8605Smrg 223848b8605Smrg/** 224848b8605Smrg * This is called just prior to changing any texture object state which 225b8e80941Smrg * will not affect texture completeness. 226848b8605Smrg */ 227848b8605Smrgstatic inline void 228848b8605Smrgflush(struct gl_context *ctx) 229848b8605Smrg{ 230b8e80941Smrg FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT); 231848b8605Smrg} 232848b8605Smrg 233848b8605Smrg 234848b8605Smrg/** 235848b8605Smrg * This is called just prior to changing any texture object state which 236b8e80941Smrg * could affect texture completeness (texture base level, max level). 237b8e80941Smrg * Any pending rendering will be flushed out, we'll set the _NEW_TEXTURE_OBJECT 238848b8605Smrg * state flag and then mark the texture object as 'incomplete' so that any 239848b8605Smrg * per-texture derived state gets recomputed. 240848b8605Smrg */ 241848b8605Smrgstatic inline void 242848b8605Smrgincomplete(struct gl_context *ctx, struct gl_texture_object *texObj) 243848b8605Smrg{ 244b8e80941Smrg FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT); 245848b8605Smrg _mesa_dirty_texobj(ctx, texObj); 246848b8605Smrg} 247848b8605Smrg 248848b8605Smrg 249b8e80941SmrgGLboolean 250b8e80941Smrg_mesa_target_allows_setting_sampler_parameters(GLenum target) 251848b8605Smrg{ 252848b8605Smrg switch (target) { 253848b8605Smrg case GL_TEXTURE_2D_MULTISAMPLE: 254848b8605Smrg case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 255848b8605Smrg return GL_FALSE; 256848b8605Smrg 257848b8605Smrg default: 258848b8605Smrg return GL_TRUE; 259848b8605Smrg } 260848b8605Smrg} 261848b8605Smrg 262848b8605Smrg 263848b8605Smrg/** 264848b8605Smrg * Set an integer-valued texture parameter 265848b8605Smrg * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise 266848b8605Smrg */ 267848b8605Smrgstatic GLboolean 268848b8605Smrgset_tex_parameteri(struct gl_context *ctx, 269848b8605Smrg struct gl_texture_object *texObj, 270b8e80941Smrg GLenum pname, const GLint *params, bool dsa) 271848b8605Smrg{ 272b8e80941Smrg const char *suffix = dsa ? "ture" : ""; 273b8e80941Smrg 274b8e80941Smrg if (texObj->HandleAllocated) { 275b8e80941Smrg /* The ARB_bindless_texture spec says: 276b8e80941Smrg * 277b8e80941Smrg * "The error INVALID_OPERATION is generated by TexImage*, CopyTexImage*, 278b8e80941Smrg * CompressedTexImage*, TexBuffer*, TexParameter*, as well as other 279b8e80941Smrg * functions defined in terms of these, if the texture object to be 280b8e80941Smrg * modified is referenced by one or more texture or image handles." 281b8e80941Smrg */ 282b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 283b8e80941Smrg "glTex%sParameter(immutable texture)", suffix); 284b8e80941Smrg return GL_FALSE; 285b8e80941Smrg } 286b8e80941Smrg 287848b8605Smrg switch (pname) { 288848b8605Smrg case GL_TEXTURE_MIN_FILTER: 289b8e80941Smrg if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) 290b8e80941Smrg goto invalid_enum; 291848b8605Smrg 292848b8605Smrg if (texObj->Sampler.MinFilter == params[0]) 293848b8605Smrg return GL_FALSE; 294848b8605Smrg switch (params[0]) { 295848b8605Smrg case GL_NEAREST: 296848b8605Smrg case GL_LINEAR: 297848b8605Smrg flush(ctx); 298848b8605Smrg texObj->Sampler.MinFilter = params[0]; 299848b8605Smrg return GL_TRUE; 300848b8605Smrg case GL_NEAREST_MIPMAP_NEAREST: 301848b8605Smrg case GL_LINEAR_MIPMAP_NEAREST: 302848b8605Smrg case GL_NEAREST_MIPMAP_LINEAR: 303848b8605Smrg case GL_LINEAR_MIPMAP_LINEAR: 304848b8605Smrg if (texObj->Target != GL_TEXTURE_RECTANGLE_NV && 305848b8605Smrg texObj->Target != GL_TEXTURE_EXTERNAL_OES) { 306848b8605Smrg flush(ctx); 307848b8605Smrg texObj->Sampler.MinFilter = params[0]; 308848b8605Smrg return GL_TRUE; 309848b8605Smrg } 310848b8605Smrg /* fall-through */ 311848b8605Smrg default: 312848b8605Smrg goto invalid_param; 313848b8605Smrg } 314848b8605Smrg return GL_FALSE; 315848b8605Smrg 316848b8605Smrg case GL_TEXTURE_MAG_FILTER: 317b8e80941Smrg if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) 318b8e80941Smrg goto invalid_enum; 319848b8605Smrg 320848b8605Smrg if (texObj->Sampler.MagFilter == params[0]) 321848b8605Smrg return GL_FALSE; 322848b8605Smrg switch (params[0]) { 323848b8605Smrg case GL_NEAREST: 324848b8605Smrg case GL_LINEAR: 325848b8605Smrg flush(ctx); /* does not effect completeness */ 326848b8605Smrg texObj->Sampler.MagFilter = params[0]; 327848b8605Smrg return GL_TRUE; 328848b8605Smrg default: 329848b8605Smrg goto invalid_param; 330848b8605Smrg } 331848b8605Smrg return GL_FALSE; 332848b8605Smrg 333848b8605Smrg case GL_TEXTURE_WRAP_S: 334b8e80941Smrg if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) 335b8e80941Smrg goto invalid_enum; 336848b8605Smrg 337848b8605Smrg if (texObj->Sampler.WrapS == params[0]) 338848b8605Smrg return GL_FALSE; 339848b8605Smrg if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) { 340848b8605Smrg flush(ctx); 341848b8605Smrg texObj->Sampler.WrapS = params[0]; 342848b8605Smrg return GL_TRUE; 343848b8605Smrg } 344848b8605Smrg return GL_FALSE; 345848b8605Smrg 346848b8605Smrg case GL_TEXTURE_WRAP_T: 347b8e80941Smrg if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) 348b8e80941Smrg goto invalid_enum; 349848b8605Smrg 350848b8605Smrg if (texObj->Sampler.WrapT == params[0]) 351848b8605Smrg return GL_FALSE; 352848b8605Smrg if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) { 353848b8605Smrg flush(ctx); 354848b8605Smrg texObj->Sampler.WrapT = params[0]; 355848b8605Smrg return GL_TRUE; 356848b8605Smrg } 357848b8605Smrg return GL_FALSE; 358848b8605Smrg 359848b8605Smrg case GL_TEXTURE_WRAP_R: 360b8e80941Smrg if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) 361b8e80941Smrg goto invalid_enum; 362848b8605Smrg 363848b8605Smrg if (texObj->Sampler.WrapR == params[0]) 364848b8605Smrg return GL_FALSE; 365848b8605Smrg if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) { 366848b8605Smrg flush(ctx); 367848b8605Smrg texObj->Sampler.WrapR = params[0]; 368848b8605Smrg return GL_TRUE; 369848b8605Smrg } 370848b8605Smrg return GL_FALSE; 371848b8605Smrg 372848b8605Smrg case GL_TEXTURE_BASE_LEVEL: 373848b8605Smrg if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 374848b8605Smrg goto invalid_pname; 375848b8605Smrg 376848b8605Smrg if (texObj->BaseLevel == params[0]) 377848b8605Smrg return GL_FALSE; 378848b8605Smrg 379b8e80941Smrg /* Section 8.10 (Texture Parameters) of the OpenGL 4.5 Core Profile spec 380b8e80941Smrg * says: 381b8e80941Smrg * 382b8e80941Smrg * An INVALID_OPERATION error is generated if the effective target is 383b8e80941Smrg * TEXTURE_2D_MULTISAMPLE, TEXTURE_2D_MULTISAMPLE_ARRAY, or 384b8e80941Smrg * TEXTURE_RECTANGLE, and pname TEXTURE_BASE_LEVEL is set to a value 385b8e80941Smrg * other than zero. 386b8e80941Smrg * 387b8e80941Smrg * Note that section 3.8.8 (Texture Parameters) of the OpenGL 3.3 Core 388b8e80941Smrg * Profile spec said: 389b8e80941Smrg * 390b8e80941Smrg * The error INVALID_VALUE is generated if TEXTURE_BASE_LEVEL is set 391b8e80941Smrg * to any value other than zero. 392b8e80941Smrg * 393b8e80941Smrg * We take the 4.5 language as a correction to 3.3, and we implement 394b8e80941Smrg * that on all GL versions. 395b8e80941Smrg */ 396848b8605Smrg if ((texObj->Target == GL_TEXTURE_2D_MULTISAMPLE || 397b8e80941Smrg texObj->Target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY || 398b8e80941Smrg texObj->Target == GL_TEXTURE_RECTANGLE) && params[0] != 0) 399848b8605Smrg goto invalid_operation; 400848b8605Smrg 401b8e80941Smrg if (params[0] < 0) { 402848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, 403b8e80941Smrg "glTex%sParameter(param=%d)", suffix, params[0]); 404848b8605Smrg return GL_FALSE; 405848b8605Smrg } 406848b8605Smrg incomplete(ctx, texObj); 407848b8605Smrg 408848b8605Smrg /** See note about ARB_texture_storage below */ 409848b8605Smrg if (texObj->Immutable) 410848b8605Smrg texObj->BaseLevel = MIN2(texObj->ImmutableLevels - 1, params[0]); 411848b8605Smrg else 412848b8605Smrg texObj->BaseLevel = params[0]; 413848b8605Smrg 414848b8605Smrg return GL_TRUE; 415848b8605Smrg 416848b8605Smrg case GL_TEXTURE_MAX_LEVEL: 417848b8605Smrg if (texObj->MaxLevel == params[0]) 418848b8605Smrg return GL_FALSE; 419848b8605Smrg 420848b8605Smrg if (params[0] < 0 || 421848b8605Smrg (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] > 0)) { 422848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, 423b8e80941Smrg "glTex%sParameter(param=%d)", suffix, 424b8e80941Smrg params[0]); 425848b8605Smrg return GL_FALSE; 426848b8605Smrg } 427848b8605Smrg incomplete(ctx, texObj); 428848b8605Smrg 429848b8605Smrg /** From ARB_texture_storage: 430848b8605Smrg * However, if TEXTURE_IMMUTABLE_FORMAT is TRUE, then level_base is 431848b8605Smrg * clamped to the range [0, <levels> - 1] and level_max is then clamped to 432848b8605Smrg * the range [level_base, <levels> - 1], where <levels> is the parameter 433848b8605Smrg * passed the call to TexStorage* for the texture object. 434848b8605Smrg */ 435848b8605Smrg if (texObj->Immutable) 436848b8605Smrg texObj->MaxLevel = CLAMP(params[0], texObj->BaseLevel, 437848b8605Smrg texObj->ImmutableLevels - 1); 438848b8605Smrg else 439848b8605Smrg texObj->MaxLevel = params[0]; 440848b8605Smrg 441848b8605Smrg return GL_TRUE; 442848b8605Smrg 443848b8605Smrg case GL_GENERATE_MIPMAP_SGIS: 444848b8605Smrg if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES) 445848b8605Smrg goto invalid_pname; 446848b8605Smrg 447848b8605Smrg if (params[0] && texObj->Target == GL_TEXTURE_EXTERNAL_OES) 448848b8605Smrg goto invalid_param; 449848b8605Smrg if (texObj->GenerateMipmap != params[0]) { 450848b8605Smrg /* no flush() */ 451848b8605Smrg texObj->GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE; 452848b8605Smrg return GL_TRUE; 453848b8605Smrg } 454848b8605Smrg return GL_FALSE; 455848b8605Smrg 456848b8605Smrg case GL_TEXTURE_COMPARE_MODE_ARB: 457848b8605Smrg if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_shadow) 458848b8605Smrg || _mesa_is_gles3(ctx)) { 459848b8605Smrg 460b8e80941Smrg if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) 461b8e80941Smrg goto invalid_enum; 462848b8605Smrg 463848b8605Smrg if (texObj->Sampler.CompareMode == params[0]) 464848b8605Smrg return GL_FALSE; 465848b8605Smrg if (params[0] == GL_NONE || 466848b8605Smrg params[0] == GL_COMPARE_R_TO_TEXTURE_ARB) { 467848b8605Smrg flush(ctx); 468848b8605Smrg texObj->Sampler.CompareMode = params[0]; 469848b8605Smrg return GL_TRUE; 470848b8605Smrg } 471848b8605Smrg goto invalid_param; 472848b8605Smrg } 473848b8605Smrg goto invalid_pname; 474848b8605Smrg 475848b8605Smrg case GL_TEXTURE_COMPARE_FUNC_ARB: 476848b8605Smrg if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_shadow) 477848b8605Smrg || _mesa_is_gles3(ctx)) { 478848b8605Smrg 479b8e80941Smrg if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) 480b8e80941Smrg goto invalid_enum; 481848b8605Smrg 482848b8605Smrg if (texObj->Sampler.CompareFunc == params[0]) 483848b8605Smrg return GL_FALSE; 484848b8605Smrg switch (params[0]) { 485848b8605Smrg case GL_LEQUAL: 486848b8605Smrg case GL_GEQUAL: 487848b8605Smrg case GL_EQUAL: 488848b8605Smrg case GL_NOTEQUAL: 489848b8605Smrg case GL_LESS: 490848b8605Smrg case GL_GREATER: 491848b8605Smrg case GL_ALWAYS: 492848b8605Smrg case GL_NEVER: 493848b8605Smrg flush(ctx); 494848b8605Smrg texObj->Sampler.CompareFunc = params[0]; 495848b8605Smrg return GL_TRUE; 496848b8605Smrg default: 497848b8605Smrg goto invalid_param; 498848b8605Smrg } 499848b8605Smrg } 500848b8605Smrg goto invalid_pname; 501848b8605Smrg 502848b8605Smrg case GL_DEPTH_TEXTURE_MODE_ARB: 503848b8605Smrg /* GL_DEPTH_TEXTURE_MODE_ARB is removed in core-profile and it has never 504848b8605Smrg * existed in OpenGL ES. 505848b8605Smrg */ 506848b8605Smrg if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.ARB_depth_texture) { 507848b8605Smrg if (texObj->DepthMode == params[0]) 508848b8605Smrg return GL_FALSE; 509848b8605Smrg if (params[0] == GL_LUMINANCE || 510848b8605Smrg params[0] == GL_INTENSITY || 511848b8605Smrg params[0] == GL_ALPHA || 512848b8605Smrg (ctx->Extensions.ARB_texture_rg && params[0] == GL_RED)) { 513848b8605Smrg flush(ctx); 514848b8605Smrg texObj->DepthMode = params[0]; 515848b8605Smrg return GL_TRUE; 516848b8605Smrg } 517848b8605Smrg goto invalid_param; 518848b8605Smrg } 519848b8605Smrg goto invalid_pname; 520848b8605Smrg 521848b8605Smrg case GL_DEPTH_STENCIL_TEXTURE_MODE: 522b8e80941Smrg if (_mesa_has_ARB_stencil_texturing(ctx) || _mesa_is_gles31(ctx)) { 523848b8605Smrg bool stencil = params[0] == GL_STENCIL_INDEX; 524848b8605Smrg if (!stencil && params[0] != GL_DEPTH_COMPONENT) 525848b8605Smrg goto invalid_param; 526848b8605Smrg 527848b8605Smrg if (texObj->StencilSampling == stencil) 528848b8605Smrg return GL_FALSE; 529848b8605Smrg 530848b8605Smrg texObj->StencilSampling = stencil; 531848b8605Smrg return GL_TRUE; 532848b8605Smrg } 533848b8605Smrg goto invalid_pname; 534848b8605Smrg 535848b8605Smrg case GL_TEXTURE_CROP_RECT_OES: 536848b8605Smrg if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture) 537848b8605Smrg goto invalid_pname; 538848b8605Smrg 539848b8605Smrg texObj->CropRect[0] = params[0]; 540848b8605Smrg texObj->CropRect[1] = params[1]; 541848b8605Smrg texObj->CropRect[2] = params[2]; 542848b8605Smrg texObj->CropRect[3] = params[3]; 543848b8605Smrg return GL_TRUE; 544848b8605Smrg 545848b8605Smrg case GL_TEXTURE_SWIZZLE_R_EXT: 546848b8605Smrg case GL_TEXTURE_SWIZZLE_G_EXT: 547848b8605Smrg case GL_TEXTURE_SWIZZLE_B_EXT: 548848b8605Smrg case GL_TEXTURE_SWIZZLE_A_EXT: 549848b8605Smrg if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_swizzle) 550848b8605Smrg || _mesa_is_gles3(ctx)) { 551848b8605Smrg const GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT; 552848b8605Smrg const GLint swz = comp_to_swizzle(params[0]); 553848b8605Smrg if (swz < 0) { 554848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, 555b8e80941Smrg "glTex%sParameter(swizzle 0x%x)", suffix, params[0]); 556848b8605Smrg return GL_FALSE; 557848b8605Smrg } 558b8e80941Smrg assert(comp < 4); 559848b8605Smrg 560848b8605Smrg flush(ctx); 561848b8605Smrg texObj->Swizzle[comp] = params[0]; 562848b8605Smrg set_swizzle_component(&texObj->_Swizzle, comp, swz); 563848b8605Smrg return GL_TRUE; 564848b8605Smrg } 565848b8605Smrg goto invalid_pname; 566848b8605Smrg 567848b8605Smrg case GL_TEXTURE_SWIZZLE_RGBA_EXT: 568848b8605Smrg if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_swizzle) 569848b8605Smrg || _mesa_is_gles3(ctx)) { 570848b8605Smrg GLuint comp; 571848b8605Smrg flush(ctx); 572848b8605Smrg for (comp = 0; comp < 4; comp++) { 573848b8605Smrg const GLint swz = comp_to_swizzle(params[comp]); 574848b8605Smrg if (swz >= 0) { 575848b8605Smrg texObj->Swizzle[comp] = params[comp]; 576848b8605Smrg set_swizzle_component(&texObj->_Swizzle, comp, swz); 577848b8605Smrg } 578848b8605Smrg else { 579848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, 580b8e80941Smrg "glTex%sParameter(swizzle 0x%x)", 581b8e80941Smrg suffix, params[comp]); 582848b8605Smrg return GL_FALSE; 583848b8605Smrg } 584848b8605Smrg } 585848b8605Smrg return GL_TRUE; 586848b8605Smrg } 587848b8605Smrg goto invalid_pname; 588848b8605Smrg 589848b8605Smrg case GL_TEXTURE_SRGB_DECODE_EXT: 590b8e80941Smrg if (ctx->Extensions.EXT_texture_sRGB_decode) { 591848b8605Smrg GLenum decode = params[0]; 592848b8605Smrg 593b8e80941Smrg if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) 594b8e80941Smrg goto invalid_enum; 595848b8605Smrg 596848b8605Smrg if (decode == GL_DECODE_EXT || decode == GL_SKIP_DECODE_EXT) { 597848b8605Smrg if (texObj->Sampler.sRGBDecode != decode) { 598848b8605Smrg flush(ctx); 599848b8605Smrg texObj->Sampler.sRGBDecode = decode; 600848b8605Smrg } 601848b8605Smrg return GL_TRUE; 602848b8605Smrg } 603848b8605Smrg } 604848b8605Smrg goto invalid_pname; 605848b8605Smrg 606848b8605Smrg case GL_TEXTURE_CUBE_MAP_SEAMLESS: 607848b8605Smrg if (_mesa_is_desktop_gl(ctx) 608848b8605Smrg && ctx->Extensions.AMD_seamless_cubemap_per_texture) { 609848b8605Smrg GLenum param = params[0]; 610848b8605Smrg 611b8e80941Smrg if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) 612b8e80941Smrg goto invalid_enum; 613848b8605Smrg 614848b8605Smrg if (param != GL_TRUE && param != GL_FALSE) { 615848b8605Smrg goto invalid_param; 616848b8605Smrg } 617848b8605Smrg if (param != texObj->Sampler.CubeMapSeamless) { 618848b8605Smrg flush(ctx); 619848b8605Smrg texObj->Sampler.CubeMapSeamless = param; 620848b8605Smrg } 621848b8605Smrg return GL_TRUE; 622848b8605Smrg } 623848b8605Smrg goto invalid_pname; 624848b8605Smrg 625b8e80941Smrg case GL_TEXTURE_TILING_EXT: 626b8e80941Smrg if (ctx->Extensions.EXT_memory_object) { 627b8e80941Smrg texObj->TextureTiling = params[0]; 628b8e80941Smrg 629b8e80941Smrg return GL_TRUE; 630b8e80941Smrg } 631b8e80941Smrg goto invalid_pname; 632b8e80941Smrg 633848b8605Smrg default: 634848b8605Smrg goto invalid_pname; 635848b8605Smrg } 636848b8605Smrg 637848b8605Smrginvalid_pname: 638b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)", 639b8e80941Smrg suffix, _mesa_enum_to_string(pname)); 640848b8605Smrg return GL_FALSE; 641848b8605Smrg 642848b8605Smrginvalid_param: 643b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(param=%s)", 644b8e80941Smrg suffix, _mesa_enum_to_string(params[0])); 645848b8605Smrg return GL_FALSE; 646848b8605Smrg 647848b8605Smrginvalid_operation: 648b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sParameter(pname=%s)", 649b8e80941Smrg suffix, _mesa_enum_to_string(pname)); 650b8e80941Smrg return GL_FALSE; 651b8e80941Smrg 652b8e80941Smrginvalid_enum: 653b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)", 654b8e80941Smrg suffix, _mesa_enum_to_string(pname)); 655848b8605Smrg return GL_FALSE; 656848b8605Smrg} 657848b8605Smrg 658848b8605Smrg 659848b8605Smrg/** 660848b8605Smrg * Set a float-valued texture parameter 661848b8605Smrg * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise 662848b8605Smrg */ 663848b8605Smrgstatic GLboolean 664848b8605Smrgset_tex_parameterf(struct gl_context *ctx, 665848b8605Smrg struct gl_texture_object *texObj, 666b8e80941Smrg GLenum pname, const GLfloat *params, bool dsa) 667848b8605Smrg{ 668b8e80941Smrg const char *suffix = dsa ? "ture" : ""; 669b8e80941Smrg 670b8e80941Smrg if (texObj->HandleAllocated) { 671b8e80941Smrg /* The ARB_bindless_texture spec says: 672b8e80941Smrg * 673b8e80941Smrg * "The error INVALID_OPERATION is generated by TexImage*, CopyTexImage*, 674b8e80941Smrg * CompressedTexImage*, TexBuffer*, TexParameter*, as well as other 675b8e80941Smrg * functions defined in terms of these, if the texture object to be 676b8e80941Smrg * modified is referenced by one or more texture or image handles." 677b8e80941Smrg */ 678b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 679b8e80941Smrg "glTex%sParameter(immutable texture)", suffix); 680b8e80941Smrg return GL_FALSE; 681b8e80941Smrg } 682b8e80941Smrg 683848b8605Smrg switch (pname) { 684848b8605Smrg case GL_TEXTURE_MIN_LOD: 685848b8605Smrg if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 686848b8605Smrg goto invalid_pname; 687848b8605Smrg 688b8e80941Smrg if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) 689b8e80941Smrg goto invalid_enum; 690848b8605Smrg 691848b8605Smrg if (texObj->Sampler.MinLod == params[0]) 692848b8605Smrg return GL_FALSE; 693848b8605Smrg flush(ctx); 694848b8605Smrg texObj->Sampler.MinLod = params[0]; 695848b8605Smrg return GL_TRUE; 696848b8605Smrg 697848b8605Smrg case GL_TEXTURE_MAX_LOD: 698848b8605Smrg if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 699848b8605Smrg goto invalid_pname; 700848b8605Smrg 701b8e80941Smrg if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) 702b8e80941Smrg goto invalid_enum; 703848b8605Smrg 704848b8605Smrg if (texObj->Sampler.MaxLod == params[0]) 705848b8605Smrg return GL_FALSE; 706848b8605Smrg flush(ctx); 707848b8605Smrg texObj->Sampler.MaxLod = params[0]; 708848b8605Smrg return GL_TRUE; 709848b8605Smrg 710848b8605Smrg case GL_TEXTURE_PRIORITY: 711848b8605Smrg if (ctx->API != API_OPENGL_COMPAT) 712848b8605Smrg goto invalid_pname; 713848b8605Smrg 714848b8605Smrg flush(ctx); 715848b8605Smrg texObj->Priority = CLAMP(params[0], 0.0F, 1.0F); 716848b8605Smrg return GL_TRUE; 717848b8605Smrg 718848b8605Smrg case GL_TEXTURE_MAX_ANISOTROPY_EXT: 719848b8605Smrg if (ctx->Extensions.EXT_texture_filter_anisotropic) { 720b8e80941Smrg if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) 721b8e80941Smrg goto invalid_enum; 722848b8605Smrg 723848b8605Smrg if (texObj->Sampler.MaxAnisotropy == params[0]) 724848b8605Smrg return GL_FALSE; 725b8e80941Smrg if (params[0] < 1.0F) { 726b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glTex%sParameter(param)", 727b8e80941Smrg suffix); 728848b8605Smrg return GL_FALSE; 729848b8605Smrg } 730848b8605Smrg flush(ctx); 731848b8605Smrg /* clamp to max, that's what NVIDIA does */ 732848b8605Smrg texObj->Sampler.MaxAnisotropy = MIN2(params[0], 733848b8605Smrg ctx->Const.MaxTextureMaxAnisotropy); 734848b8605Smrg return GL_TRUE; 735848b8605Smrg } 736848b8605Smrg else { 737848b8605Smrg static GLuint count = 0; 738848b8605Smrg if (count++ < 10) 739848b8605Smrg goto invalid_pname; 740848b8605Smrg } 741848b8605Smrg return GL_FALSE; 742848b8605Smrg 743848b8605Smrg case GL_TEXTURE_LOD_BIAS: 744848b8605Smrg /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias. */ 745848b8605Smrg if (_mesa_is_gles(ctx)) 746848b8605Smrg goto invalid_pname; 747848b8605Smrg 748b8e80941Smrg if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) 749b8e80941Smrg goto invalid_enum; 750848b8605Smrg 751848b8605Smrg if (texObj->Sampler.LodBias != params[0]) { 752848b8605Smrg flush(ctx); 753848b8605Smrg texObj->Sampler.LodBias = params[0]; 754848b8605Smrg return GL_TRUE; 755848b8605Smrg } 756848b8605Smrg break; 757848b8605Smrg 758848b8605Smrg case GL_TEXTURE_BORDER_COLOR: 759b8e80941Smrg /* Border color exists in desktop OpenGL since 1.0 for GL_CLAMP. In 760b8e80941Smrg * OpenGL ES 2.0+, it only exists in when GL_OES_texture_border_clamp is 761b8e80941Smrg * enabled. It is never available in OpenGL ES 1.x. 762b8e80941Smrg * 763b8e80941Smrg * FIXME: Every driver that supports GLES2 has this extension. Elide 764b8e80941Smrg * the check? 765b8e80941Smrg */ 766b8e80941Smrg if (ctx->API == API_OPENGLES || 767b8e80941Smrg (ctx->API == API_OPENGLES2 && 768b8e80941Smrg !ctx->Extensions.ARB_texture_border_clamp)) 769848b8605Smrg goto invalid_pname; 770848b8605Smrg 771b8e80941Smrg if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) 772b8e80941Smrg goto invalid_enum; 773848b8605Smrg 774848b8605Smrg flush(ctx); 775848b8605Smrg /* ARB_texture_float disables clamping */ 776848b8605Smrg if (ctx->Extensions.ARB_texture_float) { 777848b8605Smrg texObj->Sampler.BorderColor.f[RCOMP] = params[0]; 778848b8605Smrg texObj->Sampler.BorderColor.f[GCOMP] = params[1]; 779848b8605Smrg texObj->Sampler.BorderColor.f[BCOMP] = params[2]; 780848b8605Smrg texObj->Sampler.BorderColor.f[ACOMP] = params[3]; 781848b8605Smrg } else { 782848b8605Smrg texObj->Sampler.BorderColor.f[RCOMP] = CLAMP(params[0], 0.0F, 1.0F); 783848b8605Smrg texObj->Sampler.BorderColor.f[GCOMP] = CLAMP(params[1], 0.0F, 1.0F); 784848b8605Smrg texObj->Sampler.BorderColor.f[BCOMP] = CLAMP(params[2], 0.0F, 1.0F); 785848b8605Smrg texObj->Sampler.BorderColor.f[ACOMP] = CLAMP(params[3], 0.0F, 1.0F); 786848b8605Smrg } 787848b8605Smrg return GL_TRUE; 788848b8605Smrg 789b8e80941Smrg case GL_TEXTURE_TILING_EXT: 790b8e80941Smrg if (ctx->Extensions.EXT_memory_object) { 791b8e80941Smrg texObj->TextureTiling = params[0]; 792b8e80941Smrg return GL_TRUE; 793b8e80941Smrg } 794b8e80941Smrg goto invalid_pname; 795b8e80941Smrg 796848b8605Smrg default: 797848b8605Smrg goto invalid_pname; 798848b8605Smrg } 799848b8605Smrg return GL_FALSE; 800848b8605Smrg 801848b8605Smrginvalid_pname: 802b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)", 803b8e80941Smrg suffix, _mesa_enum_to_string(pname)); 804848b8605Smrg return GL_FALSE; 805848b8605Smrg 806b8e80941Smrginvalid_enum: 807b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)", 808b8e80941Smrg suffix, _mesa_enum_to_string(pname)); 809848b8605Smrg return GL_FALSE; 810848b8605Smrg} 811848b8605Smrg 812848b8605Smrg 813b8e80941Smrgvoid 814b8e80941Smrg_mesa_texture_parameterf(struct gl_context *ctx, 815b8e80941Smrg struct gl_texture_object *texObj, 816b8e80941Smrg GLenum pname, GLfloat param, bool dsa) 817848b8605Smrg{ 818848b8605Smrg GLboolean need_update; 819848b8605Smrg 820848b8605Smrg switch (pname) { 821848b8605Smrg case GL_TEXTURE_MIN_FILTER: 822848b8605Smrg case GL_TEXTURE_MAG_FILTER: 823848b8605Smrg case GL_TEXTURE_WRAP_S: 824848b8605Smrg case GL_TEXTURE_WRAP_T: 825848b8605Smrg case GL_TEXTURE_WRAP_R: 826848b8605Smrg case GL_TEXTURE_BASE_LEVEL: 827848b8605Smrg case GL_TEXTURE_MAX_LEVEL: 828848b8605Smrg case GL_GENERATE_MIPMAP_SGIS: 829848b8605Smrg case GL_TEXTURE_COMPARE_MODE_ARB: 830848b8605Smrg case GL_TEXTURE_COMPARE_FUNC_ARB: 831848b8605Smrg case GL_DEPTH_TEXTURE_MODE_ARB: 832848b8605Smrg case GL_DEPTH_STENCIL_TEXTURE_MODE: 833848b8605Smrg case GL_TEXTURE_SRGB_DECODE_EXT: 834848b8605Smrg case GL_TEXTURE_CUBE_MAP_SEAMLESS: 835848b8605Smrg case GL_TEXTURE_SWIZZLE_R_EXT: 836848b8605Smrg case GL_TEXTURE_SWIZZLE_G_EXT: 837848b8605Smrg case GL_TEXTURE_SWIZZLE_B_EXT: 838848b8605Smrg case GL_TEXTURE_SWIZZLE_A_EXT: 839848b8605Smrg { 840848b8605Smrg GLint p[4]; 841848b8605Smrg p[0] = (param > 0) ? 842848b8605Smrg ((param > INT_MAX) ? INT_MAX : (GLint) (param + 0.5)) : 843848b8605Smrg ((param < INT_MIN) ? INT_MIN : (GLint) (param - 0.5)); 844848b8605Smrg 845848b8605Smrg p[1] = p[2] = p[3] = 0; 846b8e80941Smrg need_update = set_tex_parameteri(ctx, texObj, pname, p, dsa); 847848b8605Smrg } 848848b8605Smrg break; 849b8e80941Smrg case GL_TEXTURE_BORDER_COLOR: 850b8e80941Smrg case GL_TEXTURE_SWIZZLE_RGBA: 851b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameterf(non-scalar pname)", 852b8e80941Smrg dsa ? "ture" : ""); 853b8e80941Smrg return; 854848b8605Smrg default: 855848b8605Smrg { 856848b8605Smrg /* this will generate an error if pname is illegal */ 857848b8605Smrg GLfloat p[4]; 858848b8605Smrg p[0] = param; 859848b8605Smrg p[1] = p[2] = p[3] = 0.0F; 860b8e80941Smrg need_update = set_tex_parameterf(ctx, texObj, pname, p, dsa); 861848b8605Smrg } 862848b8605Smrg } 863848b8605Smrg 864848b8605Smrg if (ctx->Driver.TexParameter && need_update) { 865b8e80941Smrg ctx->Driver.TexParameter(ctx, texObj, pname); 866848b8605Smrg } 867848b8605Smrg} 868848b8605Smrg 869848b8605Smrg 870b8e80941Smrgvoid 871b8e80941Smrg_mesa_texture_parameterfv(struct gl_context *ctx, 872b8e80941Smrg struct gl_texture_object *texObj, 873b8e80941Smrg GLenum pname, const GLfloat *params, bool dsa) 874848b8605Smrg{ 875848b8605Smrg GLboolean need_update; 876848b8605Smrg switch (pname) { 877848b8605Smrg case GL_TEXTURE_MIN_FILTER: 878848b8605Smrg case GL_TEXTURE_MAG_FILTER: 879848b8605Smrg case GL_TEXTURE_WRAP_S: 880848b8605Smrg case GL_TEXTURE_WRAP_T: 881848b8605Smrg case GL_TEXTURE_WRAP_R: 882848b8605Smrg case GL_TEXTURE_BASE_LEVEL: 883848b8605Smrg case GL_TEXTURE_MAX_LEVEL: 884848b8605Smrg case GL_GENERATE_MIPMAP_SGIS: 885848b8605Smrg case GL_TEXTURE_COMPARE_MODE_ARB: 886848b8605Smrg case GL_TEXTURE_COMPARE_FUNC_ARB: 887848b8605Smrg case GL_DEPTH_TEXTURE_MODE_ARB: 888848b8605Smrg case GL_DEPTH_STENCIL_TEXTURE_MODE: 889848b8605Smrg case GL_TEXTURE_SRGB_DECODE_EXT: 890848b8605Smrg case GL_TEXTURE_CUBE_MAP_SEAMLESS: 891848b8605Smrg { 892848b8605Smrg /* convert float param to int */ 893848b8605Smrg GLint p[4]; 894848b8605Smrg p[0] = (GLint) params[0]; 895848b8605Smrg p[1] = p[2] = p[3] = 0; 896b8e80941Smrg need_update = set_tex_parameteri(ctx, texObj, pname, p, dsa); 897848b8605Smrg } 898848b8605Smrg break; 899848b8605Smrg case GL_TEXTURE_CROP_RECT_OES: 900848b8605Smrg { 901848b8605Smrg /* convert float params to int */ 902848b8605Smrg GLint iparams[4]; 903848b8605Smrg iparams[0] = (GLint) params[0]; 904848b8605Smrg iparams[1] = (GLint) params[1]; 905848b8605Smrg iparams[2] = (GLint) params[2]; 906848b8605Smrg iparams[3] = (GLint) params[3]; 907b8e80941Smrg need_update = set_tex_parameteri(ctx, texObj, pname, iparams, dsa); 908848b8605Smrg } 909848b8605Smrg break; 910848b8605Smrg case GL_TEXTURE_SWIZZLE_R_EXT: 911848b8605Smrg case GL_TEXTURE_SWIZZLE_G_EXT: 912848b8605Smrg case GL_TEXTURE_SWIZZLE_B_EXT: 913848b8605Smrg case GL_TEXTURE_SWIZZLE_A_EXT: 914848b8605Smrg case GL_TEXTURE_SWIZZLE_RGBA_EXT: 915848b8605Smrg { 916848b8605Smrg GLint p[4] = {0, 0, 0, 0}; 917848b8605Smrg p[0] = (GLint) params[0]; 918848b8605Smrg if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT) { 919848b8605Smrg p[1] = (GLint) params[1]; 920848b8605Smrg p[2] = (GLint) params[2]; 921848b8605Smrg p[3] = (GLint) params[3]; 922848b8605Smrg } 923b8e80941Smrg need_update = set_tex_parameteri(ctx, texObj, pname, p, dsa); 924848b8605Smrg } 925848b8605Smrg break; 926848b8605Smrg default: 927848b8605Smrg /* this will generate an error if pname is illegal */ 928b8e80941Smrg need_update = set_tex_parameterf(ctx, texObj, pname, params, dsa); 929848b8605Smrg } 930848b8605Smrg 931848b8605Smrg if (ctx->Driver.TexParameter && need_update) { 932b8e80941Smrg ctx->Driver.TexParameter(ctx, texObj, pname); 933848b8605Smrg } 934848b8605Smrg} 935848b8605Smrg 936848b8605Smrg 937b8e80941Smrgvoid 938b8e80941Smrg_mesa_texture_parameteri(struct gl_context *ctx, 939b8e80941Smrg struct gl_texture_object *texObj, 940b8e80941Smrg GLenum pname, GLint param, bool dsa) 941848b8605Smrg{ 942848b8605Smrg GLboolean need_update; 943848b8605Smrg switch (pname) { 944848b8605Smrg case GL_TEXTURE_MIN_LOD: 945848b8605Smrg case GL_TEXTURE_MAX_LOD: 946848b8605Smrg case GL_TEXTURE_PRIORITY: 947848b8605Smrg case GL_TEXTURE_MAX_ANISOTROPY_EXT: 948848b8605Smrg case GL_TEXTURE_LOD_BIAS: 949848b8605Smrg case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB: 950848b8605Smrg { 951848b8605Smrg GLfloat fparam[4]; 952848b8605Smrg fparam[0] = (GLfloat) param; 953848b8605Smrg fparam[1] = fparam[2] = fparam[3] = 0.0F; 954848b8605Smrg /* convert int param to float */ 955b8e80941Smrg need_update = set_tex_parameterf(ctx, texObj, pname, fparam, dsa); 956848b8605Smrg } 957848b8605Smrg break; 958b8e80941Smrg case GL_TEXTURE_BORDER_COLOR: 959b8e80941Smrg case GL_TEXTURE_SWIZZLE_RGBA: 960b8e80941Smrg { 961b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, 962b8e80941Smrg "glTex%sParameteri(non-scalar pname)", 963b8e80941Smrg dsa ? "ture" : ""); 964b8e80941Smrg return; 965b8e80941Smrg } 966848b8605Smrg default: 967848b8605Smrg /* this will generate an error if pname is illegal */ 968848b8605Smrg { 969848b8605Smrg GLint iparam[4]; 970848b8605Smrg iparam[0] = param; 971848b8605Smrg iparam[1] = iparam[2] = iparam[3] = 0; 972b8e80941Smrg need_update = set_tex_parameteri(ctx, texObj, pname, iparam, dsa); 973848b8605Smrg } 974848b8605Smrg } 975848b8605Smrg 976848b8605Smrg if (ctx->Driver.TexParameter && need_update) { 977b8e80941Smrg ctx->Driver.TexParameter(ctx, texObj, pname); 978848b8605Smrg } 979848b8605Smrg} 980848b8605Smrg 981848b8605Smrg 982b8e80941Smrgvoid 983b8e80941Smrg_mesa_texture_parameteriv(struct gl_context *ctx, 984b8e80941Smrg struct gl_texture_object *texObj, 985b8e80941Smrg GLenum pname, const GLint *params, bool dsa) 986848b8605Smrg{ 987848b8605Smrg GLboolean need_update; 988848b8605Smrg 989848b8605Smrg switch (pname) { 990848b8605Smrg case GL_TEXTURE_BORDER_COLOR: 991848b8605Smrg { 992848b8605Smrg /* convert int params to float */ 993848b8605Smrg GLfloat fparams[4]; 994848b8605Smrg fparams[0] = INT_TO_FLOAT(params[0]); 995848b8605Smrg fparams[1] = INT_TO_FLOAT(params[1]); 996848b8605Smrg fparams[2] = INT_TO_FLOAT(params[2]); 997848b8605Smrg fparams[3] = INT_TO_FLOAT(params[3]); 998b8e80941Smrg need_update = set_tex_parameterf(ctx, texObj, pname, fparams, dsa); 999848b8605Smrg } 1000848b8605Smrg break; 1001848b8605Smrg case GL_TEXTURE_MIN_LOD: 1002848b8605Smrg case GL_TEXTURE_MAX_LOD: 1003848b8605Smrg case GL_TEXTURE_PRIORITY: 1004848b8605Smrg case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1005848b8605Smrg case GL_TEXTURE_LOD_BIAS: 1006848b8605Smrg case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB: 1007848b8605Smrg { 1008848b8605Smrg /* convert int param to float */ 1009848b8605Smrg GLfloat fparams[4]; 1010848b8605Smrg fparams[0] = (GLfloat) params[0]; 1011848b8605Smrg fparams[1] = fparams[2] = fparams[3] = 0.0F; 1012b8e80941Smrg need_update = set_tex_parameterf(ctx, texObj, pname, fparams, dsa); 1013848b8605Smrg } 1014848b8605Smrg break; 1015848b8605Smrg default: 1016848b8605Smrg /* this will generate an error if pname is illegal */ 1017b8e80941Smrg need_update = set_tex_parameteri(ctx, texObj, pname, params, dsa); 1018848b8605Smrg } 1019848b8605Smrg 1020848b8605Smrg if (ctx->Driver.TexParameter && need_update) { 1021b8e80941Smrg ctx->Driver.TexParameter(ctx, texObj, pname); 1022b8e80941Smrg } 1023b8e80941Smrg} 1024b8e80941Smrg 1025b8e80941Smrgvoid 1026b8e80941Smrg_mesa_texture_parameterIiv(struct gl_context *ctx, 1027b8e80941Smrg struct gl_texture_object *texObj, 1028b8e80941Smrg GLenum pname, const GLint *params, bool dsa) 1029b8e80941Smrg{ 1030b8e80941Smrg switch (pname) { 1031b8e80941Smrg case GL_TEXTURE_BORDER_COLOR: 1032b8e80941Smrg if (texObj->HandleAllocated) { 1033b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 1034b8e80941Smrg "glTextureParameterIiv(immutable texture)"); 1035b8e80941Smrg return; 1036b8e80941Smrg } 1037b8e80941Smrg 1038b8e80941Smrg if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) { 1039b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glTextureParameterIiv(texture)"); 1040b8e80941Smrg return; 1041b8e80941Smrg } 1042b8e80941Smrg FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT); 1043b8e80941Smrg /* set the integer-valued border color */ 1044b8e80941Smrg COPY_4V(texObj->Sampler.BorderColor.i, params); 1045b8e80941Smrg break; 1046b8e80941Smrg default: 1047b8e80941Smrg _mesa_texture_parameteriv(ctx, texObj, pname, params, dsa); 1048b8e80941Smrg break; 1049b8e80941Smrg } 1050b8e80941Smrg /* XXX no driver hook for TexParameterIiv() yet */ 1051b8e80941Smrg} 1052b8e80941Smrg 1053b8e80941Smrgvoid 1054b8e80941Smrg_mesa_texture_parameterIuiv(struct gl_context *ctx, 1055b8e80941Smrg struct gl_texture_object *texObj, 1056b8e80941Smrg GLenum pname, const GLuint *params, bool dsa) 1057b8e80941Smrg{ 1058b8e80941Smrg switch (pname) { 1059b8e80941Smrg case GL_TEXTURE_BORDER_COLOR: 1060b8e80941Smrg if (texObj->HandleAllocated) { 1061b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 1062b8e80941Smrg "glTextureParameterIuiv(immutable texture)"); 1063b8e80941Smrg return; 1064848b8605Smrg } 1065b8e80941Smrg 1066b8e80941Smrg if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) { 1067b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glTextureParameterIuiv(texture)"); 1068b8e80941Smrg return; 1069b8e80941Smrg } 1070b8e80941Smrg FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT); 1071b8e80941Smrg /* set the unsigned integer-valued border color */ 1072b8e80941Smrg COPY_4V(texObj->Sampler.BorderColor.ui, params); 1073b8e80941Smrg break; 1074b8e80941Smrg default: 1075b8e80941Smrg _mesa_texture_parameteriv(ctx, texObj, pname, (const GLint *) params, 1076b8e80941Smrg dsa); 1077b8e80941Smrg break; 1078848b8605Smrg } 1079b8e80941Smrg /* XXX no driver hook for TexParameterIuiv() yet */ 1080848b8605Smrg} 1081848b8605Smrg 1082b8e80941Smrgvoid GLAPIENTRY 1083b8e80941Smrg_mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param) 1084b8e80941Smrg{ 1085b8e80941Smrg struct gl_texture_object *texObj; 1086b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 1087b8e80941Smrg 1088b8e80941Smrg texObj = get_texobj_by_target(ctx, target, GL_FALSE); 1089b8e80941Smrg if (!texObj) 1090b8e80941Smrg return; 1091b8e80941Smrg 1092b8e80941Smrg _mesa_texture_parameterf(ctx, texObj, pname, param, false); 1093b8e80941Smrg} 1094b8e80941Smrg 1095b8e80941Smrgvoid GLAPIENTRY 1096b8e80941Smrg_mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params) 1097b8e80941Smrg{ 1098b8e80941Smrg struct gl_texture_object *texObj; 1099b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 1100b8e80941Smrg 1101b8e80941Smrg texObj = get_texobj_by_target(ctx, target, GL_FALSE); 1102b8e80941Smrg if (!texObj) 1103b8e80941Smrg return; 1104b8e80941Smrg 1105b8e80941Smrg _mesa_texture_parameterfv(ctx, texObj, pname, params, false); 1106b8e80941Smrg} 1107b8e80941Smrg 1108b8e80941Smrgvoid GLAPIENTRY 1109b8e80941Smrg_mesa_TexParameteri(GLenum target, GLenum pname, GLint param) 1110b8e80941Smrg{ 1111b8e80941Smrg struct gl_texture_object *texObj; 1112b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 1113b8e80941Smrg 1114b8e80941Smrg texObj = get_texobj_by_target(ctx, target, GL_FALSE); 1115b8e80941Smrg if (!texObj) 1116b8e80941Smrg return; 1117b8e80941Smrg 1118b8e80941Smrg _mesa_texture_parameteri(ctx, texObj, pname, param, false); 1119b8e80941Smrg} 1120b8e80941Smrg 1121b8e80941Smrgvoid GLAPIENTRY 1122b8e80941Smrg_mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params) 1123b8e80941Smrg{ 1124b8e80941Smrg struct gl_texture_object *texObj; 1125b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 1126b8e80941Smrg 1127b8e80941Smrg texObj = get_texobj_by_target(ctx, target, GL_FALSE); 1128b8e80941Smrg if (!texObj) 1129b8e80941Smrg return; 1130b8e80941Smrg 1131b8e80941Smrg _mesa_texture_parameteriv(ctx, texObj, pname, params, false); 1132b8e80941Smrg} 1133848b8605Smrg 1134848b8605Smrg/** 1135848b8605Smrg * Set tex parameter to integer value(s). Primarily intended to set 1136848b8605Smrg * integer-valued texture border color (for integer-valued textures). 1137848b8605Smrg * New in GL 3.0. 1138848b8605Smrg */ 1139848b8605Smrgvoid GLAPIENTRY 1140848b8605Smrg_mesa_TexParameterIiv(GLenum target, GLenum pname, const GLint *params) 1141848b8605Smrg{ 1142848b8605Smrg struct gl_texture_object *texObj; 1143848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1144848b8605Smrg 1145b8e80941Smrg texObj = get_texobj_by_target(ctx, target, GL_FALSE); 1146848b8605Smrg if (!texObj) 1147848b8605Smrg return; 1148848b8605Smrg 1149b8e80941Smrg _mesa_texture_parameterIiv(ctx, texObj, pname, params, false); 1150848b8605Smrg} 1151848b8605Smrg 1152848b8605Smrg/** 1153848b8605Smrg * Set tex parameter to unsigned integer value(s). Primarily intended to set 1154848b8605Smrg * uint-valued texture border color (for integer-valued textures). 1155848b8605Smrg * New in GL 3.0 1156848b8605Smrg */ 1157848b8605Smrgvoid GLAPIENTRY 1158848b8605Smrg_mesa_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params) 1159848b8605Smrg{ 1160848b8605Smrg struct gl_texture_object *texObj; 1161848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1162848b8605Smrg 1163b8e80941Smrg texObj = get_texobj_by_target(ctx, target, GL_FALSE); 1164848b8605Smrg if (!texObj) 1165848b8605Smrg return; 1166848b8605Smrg 1167b8e80941Smrg _mesa_texture_parameterIuiv(ctx, texObj, pname, params, false); 1168848b8605Smrg} 1169848b8605Smrg 1170848b8605Smrg 1171b8e80941Smrgvoid GLAPIENTRY 1172b8e80941Smrg_mesa_TextureParameterfv(GLuint texture, GLenum pname, const GLfloat *params) 1173b8e80941Smrg{ 1174b8e80941Smrg struct gl_texture_object *texObj; 1175b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 1176b8e80941Smrg 1177b8e80941Smrg texObj = get_texobj_by_name(ctx, texture, "glTextureParameterfv"); 1178b8e80941Smrg if (!texObj) 1179b8e80941Smrg return; 1180b8e80941Smrg 1181b8e80941Smrg _mesa_texture_parameterfv(ctx, texObj, pname, params, true); 1182b8e80941Smrg} 1183b8e80941Smrg 1184b8e80941Smrgvoid GLAPIENTRY 1185b8e80941Smrg_mesa_TextureParameterf(GLuint texture, GLenum pname, GLfloat param) 1186848b8605Smrg{ 1187b8e80941Smrg struct gl_texture_object *texObj; 1188b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 1189b8e80941Smrg 1190b8e80941Smrg texObj = get_texobj_by_name(ctx, texture, "glTextureParameterf"); 1191b8e80941Smrg if (!texObj) 1192b8e80941Smrg return; 1193b8e80941Smrg 1194b8e80941Smrg _mesa_texture_parameterf(ctx, texObj, pname, param, true); 1195b8e80941Smrg} 1196b8e80941Smrg 1197b8e80941Smrgvoid GLAPIENTRY 1198b8e80941Smrg_mesa_TextureParameteri(GLuint texture, GLenum pname, GLint param) 1199b8e80941Smrg{ 1200b8e80941Smrg struct gl_texture_object *texObj; 1201b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 1202b8e80941Smrg 1203b8e80941Smrg texObj = get_texobj_by_name(ctx, texture, "glTextureParameteri"); 1204b8e80941Smrg if (!texObj) 1205b8e80941Smrg return; 1206b8e80941Smrg 1207b8e80941Smrg _mesa_texture_parameteri(ctx, texObj, pname, param, true); 1208b8e80941Smrg} 1209b8e80941Smrg 1210b8e80941Smrgvoid GLAPIENTRY 1211b8e80941Smrg_mesa_TextureParameteriv(GLuint texture, GLenum pname, 1212b8e80941Smrg const GLint *params) 1213b8e80941Smrg{ 1214b8e80941Smrg struct gl_texture_object *texObj; 1215b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 1216b8e80941Smrg 1217b8e80941Smrg texObj = get_texobj_by_name(ctx, texture, "glTextureParameteriv"); 1218b8e80941Smrg if (!texObj) 1219b8e80941Smrg return; 1220b8e80941Smrg 1221b8e80941Smrg _mesa_texture_parameteriv(ctx, texObj, pname, params, true); 1222b8e80941Smrg} 1223b8e80941Smrg 1224b8e80941Smrg 1225b8e80941Smrgvoid GLAPIENTRY 1226b8e80941Smrg_mesa_TextureParameterIiv(GLuint texture, GLenum pname, const GLint *params) 1227b8e80941Smrg{ 1228b8e80941Smrg struct gl_texture_object *texObj; 1229b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 1230b8e80941Smrg 1231b8e80941Smrg texObj = get_texobj_by_name(ctx, texture, "glTextureParameterIiv"); 1232b8e80941Smrg if (!texObj) 1233b8e80941Smrg return; 1234b8e80941Smrg 1235b8e80941Smrg _mesa_texture_parameterIiv(ctx, texObj, pname, params, true); 1236b8e80941Smrg} 1237b8e80941Smrg 1238b8e80941Smrgvoid GLAPIENTRY 1239b8e80941Smrg_mesa_TextureParameterIuiv(GLuint texture, GLenum pname, const GLuint *params) 1240b8e80941Smrg{ 1241b8e80941Smrg struct gl_texture_object *texObj; 1242b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 1243b8e80941Smrg 1244b8e80941Smrg texObj = get_texobj_by_name(ctx, texture, "glTextureParameterIuiv"); 1245b8e80941Smrg if (!texObj) 1246b8e80941Smrg return; 1247b8e80941Smrg 1248b8e80941Smrg _mesa_texture_parameterIuiv(ctx, texObj, pname, params, true); 1249b8e80941Smrg} 1250b8e80941Smrg 1251b8e80941SmrgGLboolean 1252b8e80941Smrg_mesa_legal_get_tex_level_parameter_target(struct gl_context *ctx, GLenum target, 1253b8e80941Smrg bool dsa) 1254b8e80941Smrg{ 1255b8e80941Smrg /* Common targets for desktop GL and GLES 3.1. */ 1256848b8605Smrg switch (target) { 1257848b8605Smrg case GL_TEXTURE_2D: 1258848b8605Smrg case GL_TEXTURE_3D: 1259848b8605Smrg return GL_TRUE; 1260848b8605Smrg case GL_TEXTURE_2D_ARRAY_EXT: 1261848b8605Smrg return ctx->Extensions.EXT_texture_array; 1262b8e80941Smrg case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1263b8e80941Smrg case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1264b8e80941Smrg case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1265b8e80941Smrg case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1266b8e80941Smrg case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1267b8e80941Smrg case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1268b8e80941Smrg return ctx->Extensions.ARB_texture_cube_map; 1269b8e80941Smrg case GL_TEXTURE_2D_MULTISAMPLE: 1270b8e80941Smrg case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 1271b8e80941Smrg return ctx->Extensions.ARB_texture_multisample; 1272848b8605Smrg case GL_TEXTURE_BUFFER: 1273848b8605Smrg /* GetTexLevelParameter accepts GL_TEXTURE_BUFFER in GL 3.1+ contexts, 1274848b8605Smrg * but not in earlier versions that expose ARB_texture_buffer_object. 1275848b8605Smrg * 1276848b8605Smrg * From the ARB_texture_buffer_object spec: 1277848b8605Smrg * "(7) Do buffer textures support texture parameters (TexParameter) or 1278848b8605Smrg * queries (GetTexParameter, GetTexLevelParameter, GetTexImage)? 1279848b8605Smrg * 1280848b8605Smrg * RESOLVED: No. [...] Note that the spec edits above don't add 1281848b8605Smrg * explicit error language for any of these cases. That is because 1282848b8605Smrg * each of the functions enumerate the set of valid <target> 1283848b8605Smrg * parameters. Not editing the spec to allow TEXTURE_BUFFER_ARB in 1284848b8605Smrg * these cases means that target is not legal, and an INVALID_ENUM 1285848b8605Smrg * error should be generated." 1286848b8605Smrg * 1287848b8605Smrg * From the OpenGL 3.1 spec: 1288848b8605Smrg * "target may also be TEXTURE_BUFFER, indicating the texture buffer." 1289848b8605Smrg */ 1290b8e80941Smrg return (_mesa_is_desktop_gl(ctx) && ctx->Version >= 31) || 1291b8e80941Smrg _mesa_has_OES_texture_buffer(ctx); 1292b8e80941Smrg case GL_TEXTURE_CUBE_MAP_ARRAY: 1293b8e80941Smrg return _mesa_has_texture_cube_map_array(ctx); 1294b8e80941Smrg } 1295b8e80941Smrg 1296b8e80941Smrg if (!_mesa_is_desktop_gl(ctx)) 1297b8e80941Smrg return GL_FALSE; 1298b8e80941Smrg 1299b8e80941Smrg /* Rest of the desktop GL targets. */ 1300b8e80941Smrg switch (target) { 1301b8e80941Smrg case GL_TEXTURE_1D: 1302b8e80941Smrg case GL_PROXY_TEXTURE_1D: 1303b8e80941Smrg case GL_PROXY_TEXTURE_2D: 1304b8e80941Smrg case GL_PROXY_TEXTURE_3D: 1305b8e80941Smrg return GL_TRUE; 1306b8e80941Smrg case GL_PROXY_TEXTURE_CUBE_MAP: 1307b8e80941Smrg return ctx->Extensions.ARB_texture_cube_map; 1308b8e80941Smrg case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 1309b8e80941Smrg return ctx->Extensions.ARB_texture_cube_map_array; 1310b8e80941Smrg case GL_TEXTURE_RECTANGLE_NV: 1311b8e80941Smrg case GL_PROXY_TEXTURE_RECTANGLE_NV: 1312b8e80941Smrg return ctx->Extensions.NV_texture_rectangle; 1313b8e80941Smrg case GL_TEXTURE_1D_ARRAY_EXT: 1314b8e80941Smrg case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 1315b8e80941Smrg case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 1316b8e80941Smrg return ctx->Extensions.EXT_texture_array; 1317848b8605Smrg case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 1318848b8605Smrg case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 1319848b8605Smrg return ctx->Extensions.ARB_texture_multisample; 1320b8e80941Smrg 1321b8e80941Smrg /* This is a valid target for dsa, but the OpenGL 4.5 core spec 1322b8e80941Smrg * (30.10.2014) Section 8.11 Texture Queries says: 1323b8e80941Smrg * "For GetTextureLevelParameter* only, texture may also be a cube 1324b8e80941Smrg * map texture object. In this case the query is always performed 1325b8e80941Smrg * for face zero (the TEXTURE_CUBE_MAP_POSITIVE_X face), since there 1326b8e80941Smrg * is no way to specify another face." 1327b8e80941Smrg */ 1328b8e80941Smrg case GL_TEXTURE_CUBE_MAP: 1329b8e80941Smrg return dsa; 1330848b8605Smrg default: 1331848b8605Smrg return GL_FALSE; 1332848b8605Smrg } 1333848b8605Smrg} 1334848b8605Smrg 1335848b8605Smrg 1336848b8605Smrgstatic void 1337848b8605Smrgget_tex_level_parameter_image(struct gl_context *ctx, 1338848b8605Smrg const struct gl_texture_object *texObj, 1339848b8605Smrg GLenum target, GLint level, 1340b8e80941Smrg GLenum pname, GLint *params, 1341b8e80941Smrg bool dsa) 1342848b8605Smrg{ 1343848b8605Smrg const struct gl_texture_image *img = NULL; 1344848b8605Smrg struct gl_texture_image dummy_image; 1345848b8605Smrg mesa_format texFormat; 1346b8e80941Smrg const char *suffix = dsa ? "ture" : ""; 1347848b8605Smrg 1348b8e80941Smrg img = _mesa_select_tex_image(texObj, target, level); 1349848b8605Smrg if (!img || img->TexFormat == MESA_FORMAT_NONE) { 1350848b8605Smrg /* In case of undefined texture image return the default values. 1351848b8605Smrg * 1352848b8605Smrg * From OpenGL 4.0 spec, page 398: 1353848b8605Smrg * "The initial internal format of a texel array is RGBA 1354848b8605Smrg * instead of 1. TEXTURE_COMPONENTS is deprecated; always 1355848b8605Smrg * use TEXTURE_INTERNAL_FORMAT." 1356848b8605Smrg */ 1357848b8605Smrg memset(&dummy_image, 0, sizeof(dummy_image)); 1358848b8605Smrg dummy_image.TexFormat = MESA_FORMAT_NONE; 1359848b8605Smrg dummy_image.InternalFormat = GL_RGBA; 1360848b8605Smrg dummy_image._BaseFormat = GL_NONE; 1361b8e80941Smrg dummy_image.FixedSampleLocations = GL_TRUE; 1362848b8605Smrg 1363848b8605Smrg img = &dummy_image; 1364848b8605Smrg } 1365848b8605Smrg 1366848b8605Smrg texFormat = img->TexFormat; 1367848b8605Smrg 1368848b8605Smrg switch (pname) { 1369848b8605Smrg case GL_TEXTURE_WIDTH: 1370848b8605Smrg *params = img->Width; 1371848b8605Smrg break; 1372848b8605Smrg case GL_TEXTURE_HEIGHT: 1373848b8605Smrg *params = img->Height; 1374848b8605Smrg break; 1375848b8605Smrg case GL_TEXTURE_DEPTH: 1376848b8605Smrg *params = img->Depth; 1377848b8605Smrg break; 1378848b8605Smrg case GL_TEXTURE_INTERNAL_FORMAT: 1379848b8605Smrg if (_mesa_is_format_compressed(texFormat)) { 1380848b8605Smrg /* need to return the actual compressed format */ 1381848b8605Smrg *params = _mesa_compressed_format_to_glenum(ctx, texFormat); 1382848b8605Smrg } 1383848b8605Smrg else { 1384848b8605Smrg /* If the true internal format is not compressed but the user 1385848b8605Smrg * requested a generic compressed format, we have to return the 1386848b8605Smrg * generic base format that matches. 1387848b8605Smrg * 1388848b8605Smrg * From page 119 (page 129 of the PDF) of the OpenGL 1.3 spec: 1389848b8605Smrg * 1390848b8605Smrg * "If no specific compressed format is available, 1391848b8605Smrg * internalformat is instead replaced by the corresponding base 1392848b8605Smrg * internal format." 1393848b8605Smrg * 1394848b8605Smrg * Otherwise just return the user's requested internal format 1395848b8605Smrg */ 1396848b8605Smrg const GLenum f = 1397848b8605Smrg _mesa_gl_compressed_format_base_format(img->InternalFormat); 1398848b8605Smrg 1399848b8605Smrg *params = (f != 0) ? f : img->InternalFormat; 1400848b8605Smrg } 1401848b8605Smrg break; 1402848b8605Smrg case GL_TEXTURE_BORDER: 1403848b8605Smrg if (ctx->API != API_OPENGL_COMPAT) 1404848b8605Smrg goto invalid_pname; 1405848b8605Smrg *params = img->Border; 1406848b8605Smrg break; 1407848b8605Smrg case GL_TEXTURE_RED_SIZE: 1408848b8605Smrg case GL_TEXTURE_GREEN_SIZE: 1409848b8605Smrg case GL_TEXTURE_BLUE_SIZE: 1410848b8605Smrg case GL_TEXTURE_ALPHA_SIZE: 1411848b8605Smrg if (_mesa_base_format_has_channel(img->_BaseFormat, pname)) 1412848b8605Smrg *params = _mesa_get_format_bits(texFormat, pname); 1413848b8605Smrg else 1414848b8605Smrg *params = 0; 1415848b8605Smrg break; 1416848b8605Smrg case GL_TEXTURE_INTENSITY_SIZE: 1417848b8605Smrg case GL_TEXTURE_LUMINANCE_SIZE: 1418848b8605Smrg if (ctx->API != API_OPENGL_COMPAT) 1419848b8605Smrg goto invalid_pname; 1420848b8605Smrg if (_mesa_base_format_has_channel(img->_BaseFormat, pname)) { 1421848b8605Smrg *params = _mesa_get_format_bits(texFormat, pname); 1422848b8605Smrg if (*params == 0) { 1423848b8605Smrg /* intensity or luminance is probably stored as RGB[A] */ 1424848b8605Smrg *params = MIN2(_mesa_get_format_bits(texFormat, 1425848b8605Smrg GL_TEXTURE_RED_SIZE), 1426848b8605Smrg _mesa_get_format_bits(texFormat, 1427848b8605Smrg GL_TEXTURE_GREEN_SIZE)); 1428848b8605Smrg } 1429b8e80941Smrg if (*params == 0 && pname == GL_TEXTURE_INTENSITY_SIZE) { 1430b8e80941Smrg /* Gallium may store intensity as LA */ 1431b8e80941Smrg *params = _mesa_get_format_bits(texFormat, 1432b8e80941Smrg GL_TEXTURE_ALPHA_SIZE); 1433b8e80941Smrg } 1434848b8605Smrg } 1435848b8605Smrg else { 1436848b8605Smrg *params = 0; 1437848b8605Smrg } 1438848b8605Smrg break; 1439848b8605Smrg case GL_TEXTURE_DEPTH_SIZE_ARB: 1440848b8605Smrg if (!ctx->Extensions.ARB_depth_texture) 1441848b8605Smrg goto invalid_pname; 1442848b8605Smrg *params = _mesa_get_format_bits(texFormat, pname); 1443848b8605Smrg break; 1444848b8605Smrg case GL_TEXTURE_STENCIL_SIZE: 1445848b8605Smrg *params = _mesa_get_format_bits(texFormat, pname); 1446848b8605Smrg break; 1447848b8605Smrg case GL_TEXTURE_SHARED_SIZE: 1448848b8605Smrg if (ctx->Version < 30 && 1449848b8605Smrg !ctx->Extensions.EXT_texture_shared_exponent) 1450848b8605Smrg goto invalid_pname; 1451848b8605Smrg *params = texFormat == MESA_FORMAT_R9G9B9E5_FLOAT ? 5 : 0; 1452848b8605Smrg break; 1453848b8605Smrg 1454848b8605Smrg /* GL_ARB_texture_compression */ 1455848b8605Smrg case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: 1456b8e80941Smrg if (_mesa_is_format_compressed(texFormat) && 1457848b8605Smrg !_mesa_is_proxy_texture(target)) { 1458848b8605Smrg *params = _mesa_format_image_size(texFormat, img->Width, 1459848b8605Smrg img->Height, img->Depth); 1460b8e80941Smrg } else { 1461b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 1462b8e80941Smrg "glGetTex%sLevelParameter[if]v(pname=%s)", suffix, 1463b8e80941Smrg _mesa_enum_to_string(pname)); 1464b8e80941Smrg } 1465848b8605Smrg break; 1466848b8605Smrg case GL_TEXTURE_COMPRESSED: 1467848b8605Smrg *params = (GLint) _mesa_is_format_compressed(texFormat); 1468848b8605Smrg break; 1469848b8605Smrg 1470848b8605Smrg /* GL_ARB_texture_float */ 1471848b8605Smrg case GL_TEXTURE_LUMINANCE_TYPE_ARB: 1472848b8605Smrg case GL_TEXTURE_INTENSITY_TYPE_ARB: 1473848b8605Smrg if (ctx->API != API_OPENGL_COMPAT) 1474848b8605Smrg goto invalid_pname; 1475848b8605Smrg /* FALLTHROUGH */ 1476848b8605Smrg case GL_TEXTURE_RED_TYPE_ARB: 1477848b8605Smrg case GL_TEXTURE_GREEN_TYPE_ARB: 1478848b8605Smrg case GL_TEXTURE_BLUE_TYPE_ARB: 1479848b8605Smrg case GL_TEXTURE_ALPHA_TYPE_ARB: 1480848b8605Smrg case GL_TEXTURE_DEPTH_TYPE_ARB: 1481848b8605Smrg if (!ctx->Extensions.ARB_texture_float) 1482848b8605Smrg goto invalid_pname; 1483848b8605Smrg if (_mesa_base_format_has_channel(img->_BaseFormat, pname)) 1484848b8605Smrg *params = _mesa_get_format_datatype(texFormat); 1485848b8605Smrg else 1486848b8605Smrg *params = GL_NONE; 1487848b8605Smrg break; 1488848b8605Smrg 1489848b8605Smrg /* GL_ARB_texture_multisample */ 1490848b8605Smrg case GL_TEXTURE_SAMPLES: 1491848b8605Smrg if (!ctx->Extensions.ARB_texture_multisample) 1492848b8605Smrg goto invalid_pname; 1493848b8605Smrg *params = img->NumSamples; 1494848b8605Smrg break; 1495848b8605Smrg 1496848b8605Smrg case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS: 1497848b8605Smrg if (!ctx->Extensions.ARB_texture_multisample) 1498848b8605Smrg goto invalid_pname; 1499848b8605Smrg *params = img->FixedSampleLocations; 1500848b8605Smrg break; 1501848b8605Smrg 1502b8e80941Smrg /* There is never a buffer data store here, but these pnames still have 1503b8e80941Smrg * to work. 1504b8e80941Smrg */ 1505b8e80941Smrg 1506b8e80941Smrg /* GL_ARB_texture_buffer_object */ 1507b8e80941Smrg case GL_TEXTURE_BUFFER_DATA_STORE_BINDING: 1508b8e80941Smrg if (!ctx->Extensions.ARB_texture_buffer_object) 1509b8e80941Smrg goto invalid_pname; 1510b8e80941Smrg *params = 0; 1511b8e80941Smrg break; 1512b8e80941Smrg 1513b8e80941Smrg /* GL_ARB_texture_buffer_range */ 1514b8e80941Smrg case GL_TEXTURE_BUFFER_OFFSET: 1515b8e80941Smrg if (!ctx->Extensions.ARB_texture_buffer_range) 1516b8e80941Smrg goto invalid_pname; 1517b8e80941Smrg *params = 0; 1518b8e80941Smrg break; 1519b8e80941Smrg case GL_TEXTURE_BUFFER_SIZE: 1520b8e80941Smrg if (!ctx->Extensions.ARB_texture_buffer_range) 1521b8e80941Smrg goto invalid_pname; 1522b8e80941Smrg *params = 0; 1523b8e80941Smrg break; 1524b8e80941Smrg 1525848b8605Smrg default: 1526848b8605Smrg goto invalid_pname; 1527848b8605Smrg } 1528848b8605Smrg 1529848b8605Smrg /* no error if we get here */ 1530848b8605Smrg return; 1531848b8605Smrg 1532848b8605Smrginvalid_pname: 1533848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, 1534b8e80941Smrg "glGetTex%sLevelParameter[if]v(pname=%s)", suffix, 1535b8e80941Smrg _mesa_enum_to_string(pname)); 1536848b8605Smrg} 1537848b8605Smrg 1538848b8605Smrg 1539b8e80941Smrg/** 1540b8e80941Smrg * Handle a glGetTexLevelParamteriv() call for a texture buffer. 1541b8e80941Smrg */ 1542848b8605Smrgstatic void 1543848b8605Smrgget_tex_level_parameter_buffer(struct gl_context *ctx, 1544848b8605Smrg const struct gl_texture_object *texObj, 1545b8e80941Smrg GLenum pname, GLint *params, bool dsa) 1546848b8605Smrg{ 1547848b8605Smrg const struct gl_buffer_object *bo = texObj->BufferObject; 1548848b8605Smrg mesa_format texFormat = texObj->_BufferObjectFormat; 1549b8e80941Smrg int bytes = MAX2(1, _mesa_get_format_bytes(texFormat)); 1550848b8605Smrg GLenum internalFormat = texObj->BufferObjectFormat; 1551848b8605Smrg GLenum baseFormat = _mesa_get_format_base_format(texFormat); 1552b8e80941Smrg const char *suffix = dsa ? "ture" : ""; 1553b8e80941Smrg 1554b8e80941Smrg assert(texObj->Target == GL_TEXTURE_BUFFER); 1555848b8605Smrg 1556848b8605Smrg if (!bo) { 1557848b8605Smrg /* undefined texture buffer object */ 1558b8e80941Smrg switch (pname) { 1559b8e80941Smrg case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS: 1560b8e80941Smrg *params = GL_TRUE; 1561b8e80941Smrg break; 1562b8e80941Smrg case GL_TEXTURE_INTERNAL_FORMAT: 1563b8e80941Smrg *params = internalFormat; 1564b8e80941Smrg break; 1565b8e80941Smrg default: 1566b8e80941Smrg *params = 0; 1567b8e80941Smrg break; 1568b8e80941Smrg } 1569848b8605Smrg return; 1570848b8605Smrg } 1571848b8605Smrg 1572848b8605Smrg switch (pname) { 1573848b8605Smrg case GL_TEXTURE_BUFFER_DATA_STORE_BINDING: 1574848b8605Smrg *params = bo->Name; 1575848b8605Smrg break; 1576848b8605Smrg case GL_TEXTURE_WIDTH: 1577b8e80941Smrg *params = ((texObj->BufferSize == -1) ? bo->Size : texObj->BufferSize) 1578b8e80941Smrg / bytes; 1579848b8605Smrg break; 1580848b8605Smrg case GL_TEXTURE_HEIGHT: 1581848b8605Smrg case GL_TEXTURE_DEPTH: 1582b8e80941Smrg *params = 1; 1583b8e80941Smrg break; 1584848b8605Smrg case GL_TEXTURE_BORDER: 1585848b8605Smrg case GL_TEXTURE_SHARED_SIZE: 1586848b8605Smrg case GL_TEXTURE_COMPRESSED: 1587848b8605Smrg *params = 0; 1588848b8605Smrg break; 1589848b8605Smrg case GL_TEXTURE_INTERNAL_FORMAT: 1590848b8605Smrg *params = internalFormat; 1591848b8605Smrg break; 1592848b8605Smrg case GL_TEXTURE_RED_SIZE: 1593848b8605Smrg case GL_TEXTURE_GREEN_SIZE: 1594848b8605Smrg case GL_TEXTURE_BLUE_SIZE: 1595848b8605Smrg case GL_TEXTURE_ALPHA_SIZE: 1596848b8605Smrg if (_mesa_base_format_has_channel(baseFormat, pname)) 1597848b8605Smrg *params = _mesa_get_format_bits(texFormat, pname); 1598848b8605Smrg else 1599848b8605Smrg *params = 0; 1600848b8605Smrg break; 1601848b8605Smrg case GL_TEXTURE_INTENSITY_SIZE: 1602848b8605Smrg case GL_TEXTURE_LUMINANCE_SIZE: 1603848b8605Smrg if (_mesa_base_format_has_channel(baseFormat, pname)) { 1604848b8605Smrg *params = _mesa_get_format_bits(texFormat, pname); 1605848b8605Smrg if (*params == 0) { 1606848b8605Smrg /* intensity or luminance is probably stored as RGB[A] */ 1607848b8605Smrg *params = MIN2(_mesa_get_format_bits(texFormat, 1608848b8605Smrg GL_TEXTURE_RED_SIZE), 1609848b8605Smrg _mesa_get_format_bits(texFormat, 1610848b8605Smrg GL_TEXTURE_GREEN_SIZE)); 1611848b8605Smrg } 1612848b8605Smrg } else { 1613848b8605Smrg *params = 0; 1614848b8605Smrg } 1615848b8605Smrg break; 1616848b8605Smrg case GL_TEXTURE_DEPTH_SIZE_ARB: 1617848b8605Smrg case GL_TEXTURE_STENCIL_SIZE_EXT: 1618848b8605Smrg *params = _mesa_get_format_bits(texFormat, pname); 1619848b8605Smrg break; 1620848b8605Smrg 1621848b8605Smrg /* GL_ARB_texture_buffer_range */ 1622848b8605Smrg case GL_TEXTURE_BUFFER_OFFSET: 1623848b8605Smrg if (!ctx->Extensions.ARB_texture_buffer_range) 1624848b8605Smrg goto invalid_pname; 1625848b8605Smrg *params = texObj->BufferOffset; 1626848b8605Smrg break; 1627848b8605Smrg case GL_TEXTURE_BUFFER_SIZE: 1628848b8605Smrg if (!ctx->Extensions.ARB_texture_buffer_range) 1629848b8605Smrg goto invalid_pname; 1630848b8605Smrg *params = (texObj->BufferSize == -1) ? bo->Size : texObj->BufferSize; 1631848b8605Smrg break; 1632848b8605Smrg 1633b8e80941Smrg /* GL_ARB_texture_multisample */ 1634b8e80941Smrg case GL_TEXTURE_SAMPLES: 1635b8e80941Smrg if (!ctx->Extensions.ARB_texture_multisample) 1636b8e80941Smrg goto invalid_pname; 1637b8e80941Smrg *params = 0; 1638b8e80941Smrg break; 1639b8e80941Smrg 1640b8e80941Smrg case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS: 1641b8e80941Smrg if (!ctx->Extensions.ARB_texture_multisample) 1642b8e80941Smrg goto invalid_pname; 1643b8e80941Smrg *params = GL_TRUE; 1644b8e80941Smrg break; 1645b8e80941Smrg 1646848b8605Smrg /* GL_ARB_texture_compression */ 1647848b8605Smrg case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: 1648848b8605Smrg /* Always illegal for GL_TEXTURE_BUFFER */ 1649848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 1650b8e80941Smrg "glGetTex%sLevelParameter[if]v(pname=%s)", suffix, 1651b8e80941Smrg _mesa_enum_to_string(pname)); 1652848b8605Smrg break; 1653848b8605Smrg 1654848b8605Smrg /* GL_ARB_texture_float */ 1655848b8605Smrg case GL_TEXTURE_RED_TYPE_ARB: 1656848b8605Smrg case GL_TEXTURE_GREEN_TYPE_ARB: 1657848b8605Smrg case GL_TEXTURE_BLUE_TYPE_ARB: 1658848b8605Smrg case GL_TEXTURE_ALPHA_TYPE_ARB: 1659848b8605Smrg case GL_TEXTURE_LUMINANCE_TYPE_ARB: 1660848b8605Smrg case GL_TEXTURE_INTENSITY_TYPE_ARB: 1661848b8605Smrg case GL_TEXTURE_DEPTH_TYPE_ARB: 1662848b8605Smrg if (!ctx->Extensions.ARB_texture_float) 1663848b8605Smrg goto invalid_pname; 1664848b8605Smrg if (_mesa_base_format_has_channel(baseFormat, pname)) 1665848b8605Smrg *params = _mesa_get_format_datatype(texFormat); 1666848b8605Smrg else 1667848b8605Smrg *params = GL_NONE; 1668848b8605Smrg break; 1669848b8605Smrg 1670848b8605Smrg default: 1671848b8605Smrg goto invalid_pname; 1672848b8605Smrg } 1673848b8605Smrg 1674848b8605Smrg /* no error if we get here */ 1675848b8605Smrg return; 1676848b8605Smrg 1677848b8605Smrginvalid_pname: 1678848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, 1679b8e80941Smrg "glGetTex%sLevelParameter[if]v(pname=%s)", suffix, 1680b8e80941Smrg _mesa_enum_to_string(pname)); 1681b8e80941Smrg} 1682b8e80941Smrg 1683b8e80941Smrgstatic bool 1684b8e80941Smrgvalid_tex_level_parameteriv_target(struct gl_context *ctx, GLenum target, 1685b8e80941Smrg bool dsa) 1686b8e80941Smrg{ 1687b8e80941Smrg const char *suffix = dsa ? "ture" : ""; 1688b8e80941Smrg if (!_mesa_legal_get_tex_level_parameter_target(ctx, target, dsa)) { 1689b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, 1690b8e80941Smrg "glGetTex%sLevelParameter[if]v(target=%s)", suffix, 1691b8e80941Smrg _mesa_enum_to_string(target)); 1692b8e80941Smrg return false; 1693b8e80941Smrg } 1694b8e80941Smrg return true; 1695848b8605Smrg} 1696848b8605Smrg 1697b8e80941Smrg/** 1698b8e80941Smrg * This isn't exposed to the rest of the driver because it is a part of the 1699b8e80941Smrg * OpenGL API that is rarely used. 1700b8e80941Smrg */ 1701b8e80941Smrgstatic void 1702b8e80941Smrgget_tex_level_parameteriv(struct gl_context *ctx, 1703b8e80941Smrg struct gl_texture_object *texObj, 1704b8e80941Smrg GLenum target, GLint level, 1705b8e80941Smrg GLenum pname, GLint *params, 1706b8e80941Smrg bool dsa) 1707b8e80941Smrg{ 1708b8e80941Smrg GLint maxLevels; 1709b8e80941Smrg const char *suffix = dsa ? "ture" : ""; 1710b8e80941Smrg 1711b8e80941Smrg /* Check for errors */ 1712b8e80941Smrg if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) { 1713b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 1714b8e80941Smrg "glGetTex%sLevelParameter[if]v(" 1715b8e80941Smrg "current unit >= max combined texture units)", suffix); 1716b8e80941Smrg return; 1717b8e80941Smrg } 1718b8e80941Smrg 1719b8e80941Smrg maxLevels = _mesa_max_texture_levels(ctx, target); 1720b8e80941Smrg assert(maxLevels != 0); 1721b8e80941Smrg 1722b8e80941Smrg if (level < 0 || level >= maxLevels) { 1723b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, 1724b8e80941Smrg "glGetTex%sLevelParameter[if]v(level out of range)", suffix); 1725b8e80941Smrg return; 1726b8e80941Smrg } 1727b8e80941Smrg 1728b8e80941Smrg /* Get the level parameter */ 1729b8e80941Smrg if (target == GL_TEXTURE_BUFFER) { 1730b8e80941Smrg get_tex_level_parameter_buffer(ctx, texObj, pname, params, dsa); 1731b8e80941Smrg } 1732b8e80941Smrg else { 1733b8e80941Smrg get_tex_level_parameter_image(ctx, texObj, target, 1734b8e80941Smrg level, pname, params, dsa); 1735b8e80941Smrg } 1736b8e80941Smrg} 1737848b8605Smrg 1738848b8605Smrgvoid GLAPIENTRY 1739848b8605Smrg_mesa_GetTexLevelParameterfv( GLenum target, GLint level, 1740848b8605Smrg GLenum pname, GLfloat *params ) 1741848b8605Smrg{ 1742b8e80941Smrg struct gl_texture_object *texObj; 1743848b8605Smrg GLint iparam; 1744b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 1745b8e80941Smrg 1746b8e80941Smrg if (!valid_tex_level_parameteriv_target(ctx, target, false)) 1747b8e80941Smrg return; 1748b8e80941Smrg 1749b8e80941Smrg texObj = _mesa_get_current_tex_object(ctx, target); 1750b8e80941Smrg if (!texObj) 1751b8e80941Smrg return; 1752b8e80941Smrg 1753b8e80941Smrg get_tex_level_parameteriv(ctx, texObj, target, level, 1754b8e80941Smrg pname, &iparam, false); 1755b8e80941Smrg 1756848b8605Smrg *params = (GLfloat) iparam; 1757848b8605Smrg} 1758848b8605Smrg 1759848b8605Smrgvoid GLAPIENTRY 1760848b8605Smrg_mesa_GetTexLevelParameteriv( GLenum target, GLint level, 1761848b8605Smrg GLenum pname, GLint *params ) 1762848b8605Smrg{ 1763848b8605Smrg struct gl_texture_object *texObj; 1764848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1765848b8605Smrg 1766b8e80941Smrg if (!valid_tex_level_parameteriv_target(ctx, target, false)) 1767848b8605Smrg return; 1768848b8605Smrg 1769b8e80941Smrg texObj = _mesa_get_current_tex_object(ctx, target); 1770b8e80941Smrg if (!texObj) 1771848b8605Smrg return; 1772848b8605Smrg 1773b8e80941Smrg get_tex_level_parameteriv(ctx, texObj, target, level, 1774b8e80941Smrg pname, params, false); 1775b8e80941Smrg} 1776848b8605Smrg 1777b8e80941Smrgvoid GLAPIENTRY 1778b8e80941Smrg_mesa_GetTextureLevelParameterfv(GLuint texture, GLint level, 1779b8e80941Smrg GLenum pname, GLfloat *params) 1780b8e80941Smrg{ 1781b8e80941Smrg struct gl_texture_object *texObj; 1782b8e80941Smrg GLint iparam; 1783b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 1784b8e80941Smrg 1785b8e80941Smrg texObj = _mesa_lookup_texture_err(ctx, texture, 1786b8e80941Smrg "glGetTextureLevelParameterfv"); 1787b8e80941Smrg if (!texObj) 1788848b8605Smrg return; 1789848b8605Smrg 1790b8e80941Smrg if (!valid_tex_level_parameteriv_target(ctx, texObj->Target, true)) 1791b8e80941Smrg return; 1792848b8605Smrg 1793b8e80941Smrg get_tex_level_parameteriv(ctx, texObj, texObj->Target, level, 1794b8e80941Smrg pname, &iparam, true); 1795848b8605Smrg 1796b8e80941Smrg *params = (GLfloat) iparam; 1797b8e80941Smrg} 1798848b8605Smrg 1799848b8605Smrgvoid GLAPIENTRY 1800b8e80941Smrg_mesa_GetTextureLevelParameteriv(GLuint texture, GLint level, 1801b8e80941Smrg GLenum pname, GLint *params) 1802848b8605Smrg{ 1803b8e80941Smrg struct gl_texture_object *texObj; 1804848b8605Smrg GET_CURRENT_CONTEXT(ctx); 1805848b8605Smrg 1806b8e80941Smrg texObj = _mesa_lookup_texture_err(ctx, texture, 1807b8e80941Smrg "glGetTextureLevelParameteriv"); 1808b8e80941Smrg if (!texObj) 1809b8e80941Smrg return; 1810b8e80941Smrg 1811b8e80941Smrg if (!valid_tex_level_parameteriv_target(ctx, texObj->Target, true)) 1812848b8605Smrg return; 1813848b8605Smrg 1814b8e80941Smrg get_tex_level_parameteriv(ctx, texObj, texObj->Target, level, 1815b8e80941Smrg pname, params, true); 1816b8e80941Smrg} 1817b8e80941Smrg 1818b8e80941Smrg/** 1819b8e80941Smrg * This isn't exposed to the rest of the driver because it is a part of the 1820b8e80941Smrg * OpenGL API that is rarely used. 1821b8e80941Smrg */ 1822b8e80941Smrgstatic void 1823b8e80941Smrgget_tex_parameterfv(struct gl_context *ctx, 1824b8e80941Smrg struct gl_texture_object *obj, 1825b8e80941Smrg GLenum pname, GLfloat *params, bool dsa) 1826b8e80941Smrg{ 1827848b8605Smrg _mesa_lock_context_textures(ctx); 1828848b8605Smrg switch (pname) { 1829848b8605Smrg case GL_TEXTURE_MAG_FILTER: 1830848b8605Smrg *params = ENUM_TO_FLOAT(obj->Sampler.MagFilter); 1831848b8605Smrg break; 1832848b8605Smrg case GL_TEXTURE_MIN_FILTER: 1833848b8605Smrg *params = ENUM_TO_FLOAT(obj->Sampler.MinFilter); 1834848b8605Smrg break; 1835848b8605Smrg case GL_TEXTURE_WRAP_S: 1836848b8605Smrg *params = ENUM_TO_FLOAT(obj->Sampler.WrapS); 1837848b8605Smrg break; 1838848b8605Smrg case GL_TEXTURE_WRAP_T: 1839848b8605Smrg *params = ENUM_TO_FLOAT(obj->Sampler.WrapT); 1840848b8605Smrg break; 1841848b8605Smrg case GL_TEXTURE_WRAP_R: 1842848b8605Smrg *params = ENUM_TO_FLOAT(obj->Sampler.WrapR); 1843848b8605Smrg break; 1844848b8605Smrg case GL_TEXTURE_BORDER_COLOR: 1845b8e80941Smrg if (ctx->API == API_OPENGLES || 1846b8e80941Smrg !ctx->Extensions.ARB_texture_border_clamp) 1847848b8605Smrg goto invalid_pname; 1848848b8605Smrg 1849848b8605Smrg if (ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP)) 1850848b8605Smrg _mesa_update_state_locked(ctx); 1851b8e80941Smrg if (_mesa_get_clamp_fragment_color(ctx, ctx->DrawBuffer)) { 1852848b8605Smrg params[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F); 1853848b8605Smrg params[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F); 1854848b8605Smrg params[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F); 1855848b8605Smrg params[3] = CLAMP(obj->Sampler.BorderColor.f[3], 0.0F, 1.0F); 1856848b8605Smrg } 1857848b8605Smrg else { 1858848b8605Smrg params[0] = obj->Sampler.BorderColor.f[0]; 1859848b8605Smrg params[1] = obj->Sampler.BorderColor.f[1]; 1860848b8605Smrg params[2] = obj->Sampler.BorderColor.f[2]; 1861848b8605Smrg params[3] = obj->Sampler.BorderColor.f[3]; 1862848b8605Smrg } 1863848b8605Smrg break; 1864848b8605Smrg case GL_TEXTURE_RESIDENT: 1865848b8605Smrg if (ctx->API != API_OPENGL_COMPAT) 1866848b8605Smrg goto invalid_pname; 1867848b8605Smrg 1868848b8605Smrg *params = 1.0F; 1869848b8605Smrg break; 1870848b8605Smrg case GL_TEXTURE_PRIORITY: 1871848b8605Smrg if (ctx->API != API_OPENGL_COMPAT) 1872848b8605Smrg goto invalid_pname; 1873848b8605Smrg 1874848b8605Smrg *params = obj->Priority; 1875848b8605Smrg break; 1876848b8605Smrg case GL_TEXTURE_MIN_LOD: 1877848b8605Smrg if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 1878848b8605Smrg goto invalid_pname; 1879848b8605Smrg 1880848b8605Smrg *params = obj->Sampler.MinLod; 1881848b8605Smrg break; 1882848b8605Smrg case GL_TEXTURE_MAX_LOD: 1883848b8605Smrg if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 1884848b8605Smrg goto invalid_pname; 1885848b8605Smrg 1886848b8605Smrg *params = obj->Sampler.MaxLod; 1887848b8605Smrg break; 1888848b8605Smrg case GL_TEXTURE_BASE_LEVEL: 1889848b8605Smrg if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 1890848b8605Smrg goto invalid_pname; 1891848b8605Smrg 1892848b8605Smrg *params = (GLfloat) obj->BaseLevel; 1893848b8605Smrg break; 1894848b8605Smrg case GL_TEXTURE_MAX_LEVEL: 1895848b8605Smrg *params = (GLfloat) obj->MaxLevel; 1896848b8605Smrg break; 1897848b8605Smrg case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1898848b8605Smrg if (!ctx->Extensions.EXT_texture_filter_anisotropic) 1899848b8605Smrg goto invalid_pname; 1900848b8605Smrg *params = obj->Sampler.MaxAnisotropy; 1901848b8605Smrg break; 1902848b8605Smrg case GL_GENERATE_MIPMAP_SGIS: 1903848b8605Smrg if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES) 1904848b8605Smrg goto invalid_pname; 1905848b8605Smrg 1906848b8605Smrg *params = (GLfloat) obj->GenerateMipmap; 1907848b8605Smrg break; 1908848b8605Smrg case GL_TEXTURE_COMPARE_MODE_ARB: 1909848b8605Smrg if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow) 1910848b8605Smrg && !_mesa_is_gles3(ctx)) 1911848b8605Smrg goto invalid_pname; 1912848b8605Smrg *params = (GLfloat) obj->Sampler.CompareMode; 1913848b8605Smrg break; 1914848b8605Smrg case GL_TEXTURE_COMPARE_FUNC_ARB: 1915848b8605Smrg if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow) 1916848b8605Smrg && !_mesa_is_gles3(ctx)) 1917848b8605Smrg goto invalid_pname; 1918848b8605Smrg *params = (GLfloat) obj->Sampler.CompareFunc; 1919848b8605Smrg break; 1920848b8605Smrg case GL_DEPTH_TEXTURE_MODE_ARB: 1921848b8605Smrg /* GL_DEPTH_TEXTURE_MODE_ARB is removed in core-profile and it has 1922848b8605Smrg * never existed in OpenGL ES. 1923848b8605Smrg */ 1924848b8605Smrg if (ctx->API != API_OPENGL_COMPAT || !ctx->Extensions.ARB_depth_texture) 1925848b8605Smrg goto invalid_pname; 1926848b8605Smrg *params = (GLfloat) obj->DepthMode; 1927848b8605Smrg break; 1928848b8605Smrg case GL_DEPTH_STENCIL_TEXTURE_MODE: 1929b8e80941Smrg if (!_mesa_has_ARB_stencil_texturing(ctx) && !_mesa_is_gles31(ctx)) 1930848b8605Smrg goto invalid_pname; 1931848b8605Smrg *params = (GLfloat) 1932848b8605Smrg (obj->StencilSampling ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT); 1933848b8605Smrg break; 1934848b8605Smrg case GL_TEXTURE_LOD_BIAS: 1935848b8605Smrg if (_mesa_is_gles(ctx)) 1936848b8605Smrg goto invalid_pname; 1937848b8605Smrg 1938848b8605Smrg *params = obj->Sampler.LodBias; 1939848b8605Smrg break; 1940848b8605Smrg case GL_TEXTURE_CROP_RECT_OES: 1941848b8605Smrg if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture) 1942848b8605Smrg goto invalid_pname; 1943848b8605Smrg 1944848b8605Smrg params[0] = (GLfloat) obj->CropRect[0]; 1945848b8605Smrg params[1] = (GLfloat) obj->CropRect[1]; 1946848b8605Smrg params[2] = (GLfloat) obj->CropRect[2]; 1947848b8605Smrg params[3] = (GLfloat) obj->CropRect[3]; 1948848b8605Smrg break; 1949848b8605Smrg 1950848b8605Smrg case GL_TEXTURE_SWIZZLE_R_EXT: 1951848b8605Smrg case GL_TEXTURE_SWIZZLE_G_EXT: 1952848b8605Smrg case GL_TEXTURE_SWIZZLE_B_EXT: 1953848b8605Smrg case GL_TEXTURE_SWIZZLE_A_EXT: 1954848b8605Smrg if ((!_mesa_is_desktop_gl(ctx) 1955848b8605Smrg || !ctx->Extensions.EXT_texture_swizzle) 1956848b8605Smrg && !_mesa_is_gles3(ctx)) 1957848b8605Smrg goto invalid_pname; 1958848b8605Smrg *params = (GLfloat) obj->Swizzle[pname - GL_TEXTURE_SWIZZLE_R_EXT]; 1959848b8605Smrg break; 1960848b8605Smrg 1961848b8605Smrg case GL_TEXTURE_SWIZZLE_RGBA_EXT: 1962848b8605Smrg if ((!_mesa_is_desktop_gl(ctx) 1963848b8605Smrg || !ctx->Extensions.EXT_texture_swizzle) 1964848b8605Smrg && !_mesa_is_gles3(ctx)) { 1965848b8605Smrg goto invalid_pname; 1966848b8605Smrg } 1967848b8605Smrg else { 1968848b8605Smrg GLuint comp; 1969848b8605Smrg for (comp = 0; comp < 4; comp++) { 1970848b8605Smrg params[comp] = (GLfloat) obj->Swizzle[comp]; 1971848b8605Smrg } 1972848b8605Smrg } 1973848b8605Smrg break; 1974848b8605Smrg 1975848b8605Smrg case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1976848b8605Smrg if (!_mesa_is_desktop_gl(ctx) 1977848b8605Smrg || !ctx->Extensions.AMD_seamless_cubemap_per_texture) 1978848b8605Smrg goto invalid_pname; 1979848b8605Smrg *params = (GLfloat) obj->Sampler.CubeMapSeamless; 1980848b8605Smrg break; 1981848b8605Smrg 1982848b8605Smrg case GL_TEXTURE_IMMUTABLE_FORMAT: 1983848b8605Smrg *params = (GLfloat) obj->Immutable; 1984848b8605Smrg break; 1985848b8605Smrg 1986848b8605Smrg case GL_TEXTURE_IMMUTABLE_LEVELS: 1987b8e80941Smrg if (_mesa_is_gles3(ctx) || _mesa_has_texture_view(ctx)) 1988848b8605Smrg *params = (GLfloat) obj->ImmutableLevels; 1989848b8605Smrg else 1990848b8605Smrg goto invalid_pname; 1991848b8605Smrg break; 1992848b8605Smrg 1993848b8605Smrg case GL_TEXTURE_VIEW_MIN_LEVEL: 1994b8e80941Smrg if (!_mesa_has_texture_view(ctx)) 1995848b8605Smrg goto invalid_pname; 1996848b8605Smrg *params = (GLfloat) obj->MinLevel; 1997848b8605Smrg break; 1998848b8605Smrg 1999848b8605Smrg case GL_TEXTURE_VIEW_NUM_LEVELS: 2000b8e80941Smrg if (!_mesa_has_texture_view(ctx)) 2001848b8605Smrg goto invalid_pname; 2002848b8605Smrg *params = (GLfloat) obj->NumLevels; 2003848b8605Smrg break; 2004848b8605Smrg 2005848b8605Smrg case GL_TEXTURE_VIEW_MIN_LAYER: 2006b8e80941Smrg if (!_mesa_has_texture_view(ctx)) 2007848b8605Smrg goto invalid_pname; 2008848b8605Smrg *params = (GLfloat) obj->MinLayer; 2009848b8605Smrg break; 2010848b8605Smrg 2011848b8605Smrg case GL_TEXTURE_VIEW_NUM_LAYERS: 2012b8e80941Smrg if (!_mesa_has_texture_view(ctx)) 2013848b8605Smrg goto invalid_pname; 2014848b8605Smrg *params = (GLfloat) obj->NumLayers; 2015848b8605Smrg break; 2016848b8605Smrg 2017848b8605Smrg case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: 2018848b8605Smrg if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external) 2019848b8605Smrg goto invalid_pname; 2020848b8605Smrg *params = (GLfloat) obj->RequiredTextureImageUnits; 2021848b8605Smrg break; 2022848b8605Smrg 2023848b8605Smrg case GL_TEXTURE_SRGB_DECODE_EXT: 2024848b8605Smrg if (!ctx->Extensions.EXT_texture_sRGB_decode) 2025848b8605Smrg goto invalid_pname; 2026848b8605Smrg *params = (GLfloat) obj->Sampler.sRGBDecode; 2027848b8605Smrg break; 2028848b8605Smrg 2029b8e80941Smrg case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE: 2030b8e80941Smrg if (!ctx->Extensions.ARB_shader_image_load_store) 2031b8e80941Smrg goto invalid_pname; 2032b8e80941Smrg *params = (GLfloat) obj->ImageFormatCompatibilityType; 2033b8e80941Smrg break; 2034b8e80941Smrg 2035b8e80941Smrg case GL_TEXTURE_TARGET: 2036b8e80941Smrg if (ctx->API != API_OPENGL_CORE) 2037b8e80941Smrg goto invalid_pname; 2038b8e80941Smrg *params = ENUM_TO_FLOAT(obj->Target); 2039b8e80941Smrg break; 2040b8e80941Smrg 2041b8e80941Smrg case GL_TEXTURE_TILING_EXT: 2042b8e80941Smrg if (!ctx->Extensions.EXT_memory_object) 2043b8e80941Smrg goto invalid_pname; 2044b8e80941Smrg *params = ENUM_TO_FLOAT(obj->TextureTiling); 2045b8e80941Smrg break; 2046b8e80941Smrg 2047848b8605Smrg default: 2048848b8605Smrg goto invalid_pname; 2049848b8605Smrg } 2050848b8605Smrg 2051848b8605Smrg /* no error if we get here */ 2052848b8605Smrg _mesa_unlock_context_textures(ctx); 2053848b8605Smrg return; 2054848b8605Smrg 2055848b8605Smrginvalid_pname: 2056848b8605Smrg _mesa_unlock_context_textures(ctx); 2057b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glGetTex%sParameterfv(pname=0x%x)", 2058b8e80941Smrg dsa ? "ture" : "", pname); 2059848b8605Smrg} 2060848b8605Smrg 2061848b8605Smrg 2062b8e80941Smrgstatic void 2063b8e80941Smrgget_tex_parameteriv(struct gl_context *ctx, 2064b8e80941Smrg struct gl_texture_object *obj, 2065b8e80941Smrg GLenum pname, GLint *params, bool dsa) 2066848b8605Smrg{ 2067848b8605Smrg _mesa_lock_texture(ctx, obj); 2068848b8605Smrg switch (pname) { 2069848b8605Smrg case GL_TEXTURE_MAG_FILTER: 2070848b8605Smrg *params = (GLint) obj->Sampler.MagFilter; 2071848b8605Smrg break; 2072848b8605Smrg case GL_TEXTURE_MIN_FILTER: 2073848b8605Smrg *params = (GLint) obj->Sampler.MinFilter; 2074848b8605Smrg break; 2075848b8605Smrg case GL_TEXTURE_WRAP_S: 2076848b8605Smrg *params = (GLint) obj->Sampler.WrapS; 2077848b8605Smrg break; 2078848b8605Smrg case GL_TEXTURE_WRAP_T: 2079848b8605Smrg *params = (GLint) obj->Sampler.WrapT; 2080848b8605Smrg break; 2081848b8605Smrg case GL_TEXTURE_WRAP_R: 2082848b8605Smrg *params = (GLint) obj->Sampler.WrapR; 2083848b8605Smrg break; 2084848b8605Smrg case GL_TEXTURE_BORDER_COLOR: 2085b8e80941Smrg if (ctx->API == API_OPENGLES || 2086b8e80941Smrg !ctx->Extensions.ARB_texture_border_clamp) 2087848b8605Smrg goto invalid_pname; 2088848b8605Smrg 2089848b8605Smrg { 2090848b8605Smrg GLfloat b[4]; 2091848b8605Smrg b[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F); 2092848b8605Smrg b[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F); 2093848b8605Smrg b[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F); 2094848b8605Smrg b[3] = CLAMP(obj->Sampler.BorderColor.f[3], 0.0F, 1.0F); 2095848b8605Smrg params[0] = FLOAT_TO_INT(b[0]); 2096848b8605Smrg params[1] = FLOAT_TO_INT(b[1]); 2097848b8605Smrg params[2] = FLOAT_TO_INT(b[2]); 2098848b8605Smrg params[3] = FLOAT_TO_INT(b[3]); 2099848b8605Smrg } 2100848b8605Smrg break; 2101848b8605Smrg case GL_TEXTURE_RESIDENT: 2102848b8605Smrg if (ctx->API != API_OPENGL_COMPAT) 2103848b8605Smrg goto invalid_pname; 2104848b8605Smrg 2105848b8605Smrg *params = 1; 2106848b8605Smrg break; 2107848b8605Smrg case GL_TEXTURE_PRIORITY: 2108848b8605Smrg if (ctx->API != API_OPENGL_COMPAT) 2109848b8605Smrg goto invalid_pname; 2110848b8605Smrg 2111848b8605Smrg *params = FLOAT_TO_INT(obj->Priority); 2112848b8605Smrg break; 2113848b8605Smrg case GL_TEXTURE_MIN_LOD: 2114848b8605Smrg if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 2115848b8605Smrg goto invalid_pname; 2116b8e80941Smrg /* GL spec 'Data Conversions' section specifies that floating-point 2117b8e80941Smrg * value in integer Get function is rounded to nearest integer 2118b8e80941Smrg */ 2119b8e80941Smrg *params = IROUND(obj->Sampler.MinLod); 2120848b8605Smrg break; 2121848b8605Smrg case GL_TEXTURE_MAX_LOD: 2122848b8605Smrg if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 2123848b8605Smrg goto invalid_pname; 2124b8e80941Smrg /* GL spec 'Data Conversions' section specifies that floating-point 2125b8e80941Smrg * value in integer Get function is rounded to nearest integer 2126b8e80941Smrg */ 2127b8e80941Smrg *params = IROUND(obj->Sampler.MaxLod); 2128848b8605Smrg break; 2129848b8605Smrg case GL_TEXTURE_BASE_LEVEL: 2130848b8605Smrg if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 2131848b8605Smrg goto invalid_pname; 2132848b8605Smrg 2133848b8605Smrg *params = obj->BaseLevel; 2134848b8605Smrg break; 2135848b8605Smrg case GL_TEXTURE_MAX_LEVEL: 2136848b8605Smrg *params = obj->MaxLevel; 2137848b8605Smrg break; 2138848b8605Smrg case GL_TEXTURE_MAX_ANISOTROPY_EXT: 2139848b8605Smrg if (!ctx->Extensions.EXT_texture_filter_anisotropic) 2140848b8605Smrg goto invalid_pname; 2141b8e80941Smrg /* GL spec 'Data Conversions' section specifies that floating-point 2142b8e80941Smrg * value in integer Get function is rounded to nearest integer 2143b8e80941Smrg */ 2144b8e80941Smrg *params = IROUND(obj->Sampler.MaxAnisotropy); 2145848b8605Smrg break; 2146848b8605Smrg case GL_GENERATE_MIPMAP_SGIS: 2147848b8605Smrg if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES) 2148848b8605Smrg goto invalid_pname; 2149848b8605Smrg 2150848b8605Smrg *params = (GLint) obj->GenerateMipmap; 2151848b8605Smrg break; 2152848b8605Smrg case GL_TEXTURE_COMPARE_MODE_ARB: 2153848b8605Smrg if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow) 2154848b8605Smrg && !_mesa_is_gles3(ctx)) 2155848b8605Smrg goto invalid_pname; 2156848b8605Smrg *params = (GLint) obj->Sampler.CompareMode; 2157848b8605Smrg break; 2158848b8605Smrg case GL_TEXTURE_COMPARE_FUNC_ARB: 2159848b8605Smrg if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow) 2160848b8605Smrg && !_mesa_is_gles3(ctx)) 2161848b8605Smrg goto invalid_pname; 2162848b8605Smrg *params = (GLint) obj->Sampler.CompareFunc; 2163848b8605Smrg break; 2164848b8605Smrg case GL_DEPTH_TEXTURE_MODE_ARB: 2165848b8605Smrg if (ctx->API != API_OPENGL_COMPAT || !ctx->Extensions.ARB_depth_texture) 2166848b8605Smrg goto invalid_pname; 2167848b8605Smrg *params = (GLint) obj->DepthMode; 2168848b8605Smrg break; 2169848b8605Smrg case GL_DEPTH_STENCIL_TEXTURE_MODE: 2170b8e80941Smrg if (!_mesa_has_ARB_stencil_texturing(ctx) && !_mesa_is_gles31(ctx)) 2171848b8605Smrg goto invalid_pname; 2172848b8605Smrg *params = (GLint) 2173848b8605Smrg (obj->StencilSampling ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT); 2174848b8605Smrg break; 2175848b8605Smrg case GL_TEXTURE_LOD_BIAS: 2176848b8605Smrg if (_mesa_is_gles(ctx)) 2177848b8605Smrg goto invalid_pname; 2178848b8605Smrg 2179848b8605Smrg /* GL spec 'Data Conversions' section specifies that floating-point 2180848b8605Smrg * value in integer Get function is rounded to nearest integer 2181848b8605Smrg */ 2182848b8605Smrg *params = IROUND(obj->Sampler.LodBias); 2183848b8605Smrg break; 2184848b8605Smrg case GL_TEXTURE_CROP_RECT_OES: 2185848b8605Smrg if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture) 2186848b8605Smrg goto invalid_pname; 2187848b8605Smrg 2188848b8605Smrg params[0] = obj->CropRect[0]; 2189848b8605Smrg params[1] = obj->CropRect[1]; 2190848b8605Smrg params[2] = obj->CropRect[2]; 2191848b8605Smrg params[3] = obj->CropRect[3]; 2192848b8605Smrg break; 2193848b8605Smrg case GL_TEXTURE_SWIZZLE_R_EXT: 2194848b8605Smrg case GL_TEXTURE_SWIZZLE_G_EXT: 2195848b8605Smrg case GL_TEXTURE_SWIZZLE_B_EXT: 2196848b8605Smrg case GL_TEXTURE_SWIZZLE_A_EXT: 2197848b8605Smrg if ((!_mesa_is_desktop_gl(ctx) 2198848b8605Smrg || !ctx->Extensions.EXT_texture_swizzle) 2199848b8605Smrg && !_mesa_is_gles3(ctx)) 2200848b8605Smrg goto invalid_pname; 2201848b8605Smrg *params = obj->Swizzle[pname - GL_TEXTURE_SWIZZLE_R_EXT]; 2202848b8605Smrg break; 2203848b8605Smrg 2204848b8605Smrg case GL_TEXTURE_SWIZZLE_RGBA_EXT: 2205848b8605Smrg if ((!_mesa_is_desktop_gl(ctx) 2206848b8605Smrg || !ctx->Extensions.EXT_texture_swizzle) 2207848b8605Smrg && !_mesa_is_gles3(ctx)) 2208848b8605Smrg goto invalid_pname; 2209848b8605Smrg COPY_4V(params, obj->Swizzle); 2210848b8605Smrg break; 2211848b8605Smrg 2212848b8605Smrg case GL_TEXTURE_CUBE_MAP_SEAMLESS: 2213848b8605Smrg if (!_mesa_is_desktop_gl(ctx) 2214848b8605Smrg || !ctx->Extensions.AMD_seamless_cubemap_per_texture) 2215848b8605Smrg goto invalid_pname; 2216848b8605Smrg *params = (GLint) obj->Sampler.CubeMapSeamless; 2217848b8605Smrg break; 2218848b8605Smrg 2219848b8605Smrg case GL_TEXTURE_IMMUTABLE_FORMAT: 2220848b8605Smrg *params = (GLint) obj->Immutable; 2221848b8605Smrg break; 2222848b8605Smrg 2223848b8605Smrg case GL_TEXTURE_IMMUTABLE_LEVELS: 2224848b8605Smrg if (_mesa_is_gles3(ctx) || 2225848b8605Smrg (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_view)) 2226848b8605Smrg *params = obj->ImmutableLevels; 2227848b8605Smrg else 2228848b8605Smrg goto invalid_pname; 2229848b8605Smrg break; 2230848b8605Smrg 2231848b8605Smrg case GL_TEXTURE_VIEW_MIN_LEVEL: 2232848b8605Smrg if (!ctx->Extensions.ARB_texture_view) 2233848b8605Smrg goto invalid_pname; 2234848b8605Smrg *params = (GLint) obj->MinLevel; 2235848b8605Smrg break; 2236848b8605Smrg 2237848b8605Smrg case GL_TEXTURE_VIEW_NUM_LEVELS: 2238848b8605Smrg if (!ctx->Extensions.ARB_texture_view) 2239848b8605Smrg goto invalid_pname; 2240848b8605Smrg *params = (GLint) obj->NumLevels; 2241848b8605Smrg break; 2242848b8605Smrg 2243848b8605Smrg case GL_TEXTURE_VIEW_MIN_LAYER: 2244848b8605Smrg if (!ctx->Extensions.ARB_texture_view) 2245848b8605Smrg goto invalid_pname; 2246848b8605Smrg *params = (GLint) obj->MinLayer; 2247848b8605Smrg break; 2248848b8605Smrg 2249848b8605Smrg case GL_TEXTURE_VIEW_NUM_LAYERS: 2250848b8605Smrg if (!ctx->Extensions.ARB_texture_view) 2251848b8605Smrg goto invalid_pname; 2252848b8605Smrg *params = (GLint) obj->NumLayers; 2253848b8605Smrg break; 2254848b8605Smrg 2255848b8605Smrg case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: 2256848b8605Smrg if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external) 2257848b8605Smrg goto invalid_pname; 2258848b8605Smrg *params = obj->RequiredTextureImageUnits; 2259848b8605Smrg break; 2260848b8605Smrg 2261848b8605Smrg case GL_TEXTURE_SRGB_DECODE_EXT: 2262848b8605Smrg if (!ctx->Extensions.EXT_texture_sRGB_decode) 2263848b8605Smrg goto invalid_pname; 2264848b8605Smrg *params = obj->Sampler.sRGBDecode; 2265848b8605Smrg break; 2266848b8605Smrg 2267848b8605Smrg case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE: 2268848b8605Smrg if (!ctx->Extensions.ARB_shader_image_load_store) 2269848b8605Smrg goto invalid_pname; 2270848b8605Smrg *params = obj->ImageFormatCompatibilityType; 2271848b8605Smrg break; 2272848b8605Smrg 2273b8e80941Smrg case GL_TEXTURE_TARGET: 2274b8e80941Smrg if (ctx->API != API_OPENGL_CORE) 2275b8e80941Smrg goto invalid_pname; 2276b8e80941Smrg *params = (GLint) obj->Target; 2277b8e80941Smrg break; 2278b8e80941Smrg 2279b8e80941Smrg case GL_TEXTURE_TILING_EXT: 2280b8e80941Smrg if (!ctx->Extensions.EXT_memory_object) 2281b8e80941Smrg goto invalid_pname; 2282b8e80941Smrg *params = (GLint) obj->TextureTiling; 2283b8e80941Smrg break; 2284b8e80941Smrg 2285848b8605Smrg default: 2286848b8605Smrg goto invalid_pname; 2287848b8605Smrg } 2288848b8605Smrg 2289848b8605Smrg /* no error if we get here */ 2290848b8605Smrg _mesa_unlock_texture(ctx, obj); 2291848b8605Smrg return; 2292848b8605Smrg 2293848b8605Smrginvalid_pname: 2294848b8605Smrg _mesa_unlock_texture(ctx, obj); 2295b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glGetTex%sParameteriv(pname=0x%x)", 2296b8e80941Smrg dsa ? "ture" : "", pname); 2297b8e80941Smrg} 2298b8e80941Smrg 2299b8e80941Smrgstatic void 2300b8e80941Smrgget_tex_parameterIiv(struct gl_context *ctx, 2301b8e80941Smrg struct gl_texture_object *obj, 2302b8e80941Smrg GLenum pname, GLint *params, bool dsa) 2303b8e80941Smrg{ 2304b8e80941Smrg switch (pname) { 2305b8e80941Smrg case GL_TEXTURE_BORDER_COLOR: 2306b8e80941Smrg COPY_4V(params, obj->Sampler.BorderColor.i); 2307b8e80941Smrg break; 2308b8e80941Smrg default: 2309b8e80941Smrg get_tex_parameteriv(ctx, obj, pname, params, dsa); 2310b8e80941Smrg } 2311b8e80941Smrg} 2312b8e80941Smrg 2313b8e80941Smrgvoid GLAPIENTRY 2314b8e80941Smrg_mesa_GetTexParameterfv(GLenum target, GLenum pname, GLfloat *params) 2315b8e80941Smrg{ 2316b8e80941Smrg struct gl_texture_object *obj; 2317b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 2318b8e80941Smrg 2319b8e80941Smrg obj = get_texobj_by_target(ctx, target, GL_TRUE); 2320b8e80941Smrg if (!obj) 2321b8e80941Smrg return; 2322b8e80941Smrg 2323b8e80941Smrg get_tex_parameterfv(ctx, obj, pname, params, false); 2324848b8605Smrg} 2325848b8605Smrg 2326b8e80941Smrgvoid GLAPIENTRY 2327b8e80941Smrg_mesa_GetTexParameteriv(GLenum target, GLenum pname, GLint *params) 2328b8e80941Smrg{ 2329b8e80941Smrg struct gl_texture_object *obj; 2330b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 2331b8e80941Smrg 2332b8e80941Smrg obj = get_texobj_by_target(ctx, target, GL_TRUE); 2333b8e80941Smrg if (!obj) 2334b8e80941Smrg return; 2335b8e80941Smrg 2336b8e80941Smrg get_tex_parameteriv(ctx, obj, pname, params, false); 2337b8e80941Smrg} 2338848b8605Smrg 2339848b8605Smrg/** New in GL 3.0 */ 2340848b8605Smrgvoid GLAPIENTRY 2341848b8605Smrg_mesa_GetTexParameterIiv(GLenum target, GLenum pname, GLint *params) 2342848b8605Smrg{ 2343848b8605Smrg struct gl_texture_object *texObj; 2344848b8605Smrg GET_CURRENT_CONTEXT(ctx); 2345848b8605Smrg 2346b8e80941Smrg texObj = get_texobj_by_target(ctx, target, GL_TRUE); 2347848b8605Smrg if (!texObj) 2348848b8605Smrg return; 2349848b8605Smrg 2350b8e80941Smrg get_tex_parameterIiv(ctx, texObj, pname, params, false); 2351848b8605Smrg} 2352848b8605Smrg 2353848b8605Smrg 2354848b8605Smrg/** New in GL 3.0 */ 2355848b8605Smrgvoid GLAPIENTRY 2356848b8605Smrg_mesa_GetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params) 2357848b8605Smrg{ 2358848b8605Smrg struct gl_texture_object *texObj; 2359848b8605Smrg GET_CURRENT_CONTEXT(ctx); 2360848b8605Smrg 2361b8e80941Smrg texObj = get_texobj_by_target(ctx, target, GL_TRUE); 2362848b8605Smrg if (!texObj) 2363848b8605Smrg return; 2364848b8605Smrg 2365b8e80941Smrg get_tex_parameterIiv(ctx, texObj, pname, (GLint *) params, false); 2366b8e80941Smrg} 2367b8e80941Smrg 2368b8e80941Smrg 2369b8e80941Smrgvoid GLAPIENTRY 2370b8e80941Smrg_mesa_GetTextureParameterfv(GLuint texture, GLenum pname, GLfloat *params) 2371b8e80941Smrg{ 2372b8e80941Smrg struct gl_texture_object *obj; 2373b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 2374b8e80941Smrg 2375b8e80941Smrg obj = get_texobj_by_name(ctx, texture, "glGetTextureParameterfv"); 2376b8e80941Smrg if (!obj) 2377b8e80941Smrg return; 2378b8e80941Smrg 2379b8e80941Smrg get_tex_parameterfv(ctx, obj, pname, params, true); 2380b8e80941Smrg} 2381b8e80941Smrg 2382b8e80941Smrgvoid GLAPIENTRY 2383b8e80941Smrg_mesa_GetTextureParameteriv(GLuint texture, GLenum pname, GLint *params) 2384b8e80941Smrg{ 2385b8e80941Smrg struct gl_texture_object *obj; 2386b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 2387b8e80941Smrg 2388b8e80941Smrg obj = get_texobj_by_name(ctx, texture, "glGetTextureParameteriv"); 2389b8e80941Smrg if (!obj) 2390b8e80941Smrg return; 2391b8e80941Smrg 2392b8e80941Smrg get_tex_parameteriv(ctx, obj, pname, params, true); 2393b8e80941Smrg} 2394b8e80941Smrg 2395b8e80941Smrgvoid GLAPIENTRY 2396b8e80941Smrg_mesa_GetTextureParameterIiv(GLuint texture, GLenum pname, GLint *params) 2397b8e80941Smrg{ 2398b8e80941Smrg struct gl_texture_object *texObj; 2399b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 2400b8e80941Smrg 2401b8e80941Smrg texObj = get_texobj_by_name(ctx, texture, "glGetTextureParameterIiv"); 2402b8e80941Smrg if (!texObj) 2403b8e80941Smrg return; 2404b8e80941Smrg 2405b8e80941Smrg get_tex_parameterIiv(ctx, texObj, pname, params, true); 2406b8e80941Smrg} 2407b8e80941Smrg 2408b8e80941Smrg 2409b8e80941Smrgvoid GLAPIENTRY 2410b8e80941Smrg_mesa_GetTextureParameterIuiv(GLuint texture, GLenum pname, GLuint *params) 2411b8e80941Smrg{ 2412b8e80941Smrg struct gl_texture_object *texObj; 2413b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 2414b8e80941Smrg 2415b8e80941Smrg texObj = get_texobj_by_name(ctx, texture, "glGetTextureParameterIuiv"); 2416b8e80941Smrg if (!texObj) 2417b8e80941Smrg return; 2418b8e80941Smrg 2419b8e80941Smrg get_tex_parameterIiv(ctx, texObj, pname, (GLint *) params, true); 2420848b8605Smrg} 2421