1848b8605Smrg/* 2848b8605Smrg * Copyright © 2012 Intel Corporation 3848b8605Smrg * 4848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5848b8605Smrg * copy of this software and associated documentation files (the "Software"), 6848b8605Smrg * to deal in the Software without restriction, including without limitation 7848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the 9848b8605Smrg * Software is furnished to do so, subject to the following conditions: 10848b8605Smrg * 11848b8605Smrg * The above copyright notice and this permission notice (including the next 12848b8605Smrg * paragraph) shall be included in all copies or substantial portions of the 13848b8605Smrg * Software. 14848b8605Smrg * 15848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16848b8605Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19848b8605Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20848b8605Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21848b8605Smrg * DEALINGS IN THE SOFTWARE. 22848b8605Smrg */ 23848b8605Smrg 24848b8605Smrg#include "mtypes.h" 25848b8605Smrg#include "context.h" 26848b8605Smrg#include "glformats.h" 27848b8605Smrg#include "macros.h" 28848b8605Smrg#include "enums.h" 29848b8605Smrg#include "fbobject.h" 30848b8605Smrg#include "formatquery.h" 31b8e80941Smrg#include "teximage.h" 32b8e80941Smrg#include "texparam.h" 33b8e80941Smrg#include "texobj.h" 34b8e80941Smrg#include "get.h" 35b8e80941Smrg#include "genmipmap.h" 36b8e80941Smrg#include "shaderimage.h" 37b8e80941Smrg#include "texcompress.h" 38b8e80941Smrg#include "textureview.h" 39848b8605Smrg 40b8e80941Smrgstatic bool 41b8e80941Smrg_is_renderable(struct gl_context *ctx, GLenum internalformat) 42848b8605Smrg{ 43b8e80941Smrg /* Section 4.4.4 on page 212 of the GLES 3.0.4 spec says: 44b8e80941Smrg * 45b8e80941Smrg * "An internal format is color-renderable if it is one of the 46b8e80941Smrg * formats from table 3.13 noted as color-renderable or if it 47b8e80941Smrg * is unsized format RGBA or RGB." 48b8e80941Smrg * 49b8e80941Smrg * Therefore, we must accept GL_RGB and GL_RGBA here. 50b8e80941Smrg */ 51b8e80941Smrg if (internalformat != GL_RGB && internalformat != GL_RGBA && 52b8e80941Smrg _mesa_base_fbo_format(ctx, internalformat) == 0) 53b8e80941Smrg return false; 54848b8605Smrg 55b8e80941Smrg return true; 56848b8605Smrg} 57848b8605Smrg 58b8e80941Smrg/* Handles the cases where either ARB_internalformat_query or 59b8e80941Smrg * ARB_internalformat_query2 have to return an error. 60b8e80941Smrg */ 61b8e80941Smrgstatic bool 62b8e80941Smrg_legal_parameters(struct gl_context *ctx, GLenum target, GLenum internalformat, 63b8e80941Smrg GLenum pname, GLsizei bufSize, GLint *params) 64848b8605Smrg 65848b8605Smrg{ 66b8e80941Smrg bool query2 = _mesa_has_ARB_internalformat_query2(ctx); 67848b8605Smrg 68b8e80941Smrg /* The ARB_internalformat_query2 spec says: 69848b8605Smrg * 70b8e80941Smrg * "The INVALID_ENUM error is generated if the <target> parameter to 71b8e80941Smrg * GetInternalformati*v is not one of the targets listed in Table 6.xx. 72848b8605Smrg */ 73b8e80941Smrg switch(target){ 74b8e80941Smrg case GL_TEXTURE_1D: 75b8e80941Smrg case GL_TEXTURE_1D_ARRAY: 76b8e80941Smrg case GL_TEXTURE_2D: 77b8e80941Smrg case GL_TEXTURE_2D_ARRAY: 78b8e80941Smrg case GL_TEXTURE_3D: 79b8e80941Smrg case GL_TEXTURE_CUBE_MAP: 80b8e80941Smrg case GL_TEXTURE_CUBE_MAP_ARRAY: 81b8e80941Smrg case GL_TEXTURE_RECTANGLE: 82b8e80941Smrg case GL_TEXTURE_BUFFER: 83b8e80941Smrg if (!query2) { 84b8e80941Smrg /* The ARB_internalformat_query spec says: 85b8e80941Smrg * 86b8e80941Smrg * "If the <target> parameter to GetInternalformativ is not one of 87b8e80941Smrg * TEXTURE_2D_MULTISAMPLE, TEXTURE_2D_MULTISAMPLE_ARRAY 88b8e80941Smrg * or RENDERBUFFER then an INVALID_ENUM error is generated. 89b8e80941Smrg */ 90b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, 91b8e80941Smrg "glGetInternalformativ(target=%s)", 92b8e80941Smrg _mesa_enum_to_string(target)); 93b8e80941Smrg 94b8e80941Smrg return false; 95b8e80941Smrg } 96b8e80941Smrg break; 97b8e80941Smrg 98848b8605Smrg case GL_RENDERBUFFER: 99848b8605Smrg break; 100848b8605Smrg 101848b8605Smrg case GL_TEXTURE_2D_MULTISAMPLE: 102848b8605Smrg case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 103b8e80941Smrg /* The non-existence of ARB_texture_multisample is treated in 104b8e80941Smrg * ARB_internalformat_query implementation like an error. 105b8e80941Smrg */ 106b8e80941Smrg if (!query2 && 107b8e80941Smrg !(_mesa_has_ARB_texture_multisample(ctx) || _mesa_is_gles31(ctx))) { 108b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, 109b8e80941Smrg "glGetInternalformativ(target=%s)", 110b8e80941Smrg _mesa_enum_to_string(target)); 111b8e80941Smrg 112b8e80941Smrg return false; 113b8e80941Smrg } 114b8e80941Smrg break; 115848b8605Smrg 116848b8605Smrg default: 117848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, 118848b8605Smrg "glGetInternalformativ(target=%s)", 119b8e80941Smrg _mesa_enum_to_string(target)); 120b8e80941Smrg return false; 121848b8605Smrg } 122848b8605Smrg 123b8e80941Smrg 124b8e80941Smrg /* The ARB_internalformat_query2 spec says: 125848b8605Smrg * 126b8e80941Smrg * "The INVALID_ENUM error is generated if the <pname> parameter is 127b8e80941Smrg * not one of the listed possibilities. 128848b8605Smrg */ 129b8e80941Smrg switch(pname){ 130b8e80941Smrg case GL_SAMPLES: 131b8e80941Smrg case GL_NUM_SAMPLE_COUNTS: 132b8e80941Smrg break; 133b8e80941Smrg 134b8e80941Smrg case GL_SRGB_DECODE_ARB: 135b8e80941Smrg /* The ARB_internalformat_query2 spec says: 136b8e80941Smrg * 137b8e80941Smrg * "If ARB_texture_sRGB_decode or EXT_texture_sRGB_decode or 138b8e80941Smrg * equivalent functionality is not supported, queries for the 139b8e80941Smrg * SRGB_DECODE_ARB <pname> set the INVALID_ENUM error. 140b8e80941Smrg */ 141b8e80941Smrg if (!_mesa_has_EXT_texture_sRGB_decode(ctx)) { 142b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, 143b8e80941Smrg "glGetInternalformativ(pname=%s)", 144b8e80941Smrg _mesa_enum_to_string(pname)); 145b8e80941Smrg return false; 146b8e80941Smrg } 147b8e80941Smrg /* fallthrough */ 148b8e80941Smrg case GL_INTERNALFORMAT_SUPPORTED: 149b8e80941Smrg case GL_INTERNALFORMAT_PREFERRED: 150b8e80941Smrg case GL_INTERNALFORMAT_RED_SIZE: 151b8e80941Smrg case GL_INTERNALFORMAT_GREEN_SIZE: 152b8e80941Smrg case GL_INTERNALFORMAT_BLUE_SIZE: 153b8e80941Smrg case GL_INTERNALFORMAT_ALPHA_SIZE: 154b8e80941Smrg case GL_INTERNALFORMAT_DEPTH_SIZE: 155b8e80941Smrg case GL_INTERNALFORMAT_STENCIL_SIZE: 156b8e80941Smrg case GL_INTERNALFORMAT_SHARED_SIZE: 157b8e80941Smrg case GL_INTERNALFORMAT_RED_TYPE: 158b8e80941Smrg case GL_INTERNALFORMAT_GREEN_TYPE: 159b8e80941Smrg case GL_INTERNALFORMAT_BLUE_TYPE: 160b8e80941Smrg case GL_INTERNALFORMAT_ALPHA_TYPE: 161b8e80941Smrg case GL_INTERNALFORMAT_DEPTH_TYPE: 162b8e80941Smrg case GL_INTERNALFORMAT_STENCIL_TYPE: 163b8e80941Smrg case GL_MAX_WIDTH: 164b8e80941Smrg case GL_MAX_HEIGHT: 165b8e80941Smrg case GL_MAX_DEPTH: 166b8e80941Smrg case GL_MAX_LAYERS: 167b8e80941Smrg case GL_MAX_COMBINED_DIMENSIONS: 168b8e80941Smrg case GL_COLOR_COMPONENTS: 169b8e80941Smrg case GL_DEPTH_COMPONENTS: 170b8e80941Smrg case GL_STENCIL_COMPONENTS: 171b8e80941Smrg case GL_COLOR_RENDERABLE: 172b8e80941Smrg case GL_DEPTH_RENDERABLE: 173b8e80941Smrg case GL_STENCIL_RENDERABLE: 174b8e80941Smrg case GL_FRAMEBUFFER_RENDERABLE: 175b8e80941Smrg case GL_FRAMEBUFFER_RENDERABLE_LAYERED: 176b8e80941Smrg case GL_FRAMEBUFFER_BLEND: 177b8e80941Smrg case GL_READ_PIXELS: 178b8e80941Smrg case GL_READ_PIXELS_FORMAT: 179b8e80941Smrg case GL_READ_PIXELS_TYPE: 180b8e80941Smrg case GL_TEXTURE_IMAGE_FORMAT: 181b8e80941Smrg case GL_TEXTURE_IMAGE_TYPE: 182b8e80941Smrg case GL_GET_TEXTURE_IMAGE_FORMAT: 183b8e80941Smrg case GL_GET_TEXTURE_IMAGE_TYPE: 184b8e80941Smrg case GL_MIPMAP: 185b8e80941Smrg case GL_MANUAL_GENERATE_MIPMAP: 186b8e80941Smrg case GL_AUTO_GENERATE_MIPMAP: 187b8e80941Smrg case GL_COLOR_ENCODING: 188b8e80941Smrg case GL_SRGB_READ: 189b8e80941Smrg case GL_SRGB_WRITE: 190b8e80941Smrg case GL_FILTER: 191b8e80941Smrg case GL_VERTEX_TEXTURE: 192b8e80941Smrg case GL_TESS_CONTROL_TEXTURE: 193b8e80941Smrg case GL_TESS_EVALUATION_TEXTURE: 194b8e80941Smrg case GL_GEOMETRY_TEXTURE: 195b8e80941Smrg case GL_FRAGMENT_TEXTURE: 196b8e80941Smrg case GL_COMPUTE_TEXTURE: 197b8e80941Smrg case GL_TEXTURE_SHADOW: 198b8e80941Smrg case GL_TEXTURE_GATHER: 199b8e80941Smrg case GL_TEXTURE_GATHER_SHADOW: 200b8e80941Smrg case GL_SHADER_IMAGE_LOAD: 201b8e80941Smrg case GL_SHADER_IMAGE_STORE: 202b8e80941Smrg case GL_SHADER_IMAGE_ATOMIC: 203b8e80941Smrg case GL_IMAGE_TEXEL_SIZE: 204b8e80941Smrg case GL_IMAGE_COMPATIBILITY_CLASS: 205b8e80941Smrg case GL_IMAGE_PIXEL_FORMAT: 206b8e80941Smrg case GL_IMAGE_PIXEL_TYPE: 207b8e80941Smrg case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE: 208b8e80941Smrg case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST: 209b8e80941Smrg case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST: 210b8e80941Smrg case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE: 211b8e80941Smrg case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE: 212b8e80941Smrg case GL_TEXTURE_COMPRESSED: 213b8e80941Smrg case GL_TEXTURE_COMPRESSED_BLOCK_WIDTH: 214b8e80941Smrg case GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT: 215b8e80941Smrg case GL_TEXTURE_COMPRESSED_BLOCK_SIZE: 216b8e80941Smrg case GL_CLEAR_BUFFER: 217b8e80941Smrg case GL_TEXTURE_VIEW: 218b8e80941Smrg case GL_VIEW_COMPATIBILITY_CLASS: 219b8e80941Smrg case GL_NUM_TILING_TYPES_EXT: 220b8e80941Smrg case GL_TILING_TYPES_EXT: 221b8e80941Smrg /* The ARB_internalformat_query spec says: 222b8e80941Smrg * 223b8e80941Smrg * "If the <pname> parameter to GetInternalformativ is not SAMPLES 224b8e80941Smrg * or NUM_SAMPLE_COUNTS, then an INVALID_ENUM error is generated." 225b8e80941Smrg */ 226b8e80941Smrg if (!query2) { 227b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, 228b8e80941Smrg "glGetInternalformativ(pname=%s)", 229b8e80941Smrg _mesa_enum_to_string(pname)); 230b8e80941Smrg 231b8e80941Smrg return false; 232b8e80941Smrg } 233b8e80941Smrg break; 234b8e80941Smrg 235b8e80941Smrg default: 236848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, 237b8e80941Smrg "glGetInternalformativ(pname=%s)", 238b8e80941Smrg _mesa_enum_to_string(pname)); 239b8e80941Smrg return false; 240848b8605Smrg } 241848b8605Smrg 242848b8605Smrg /* The ARB_internalformat_query spec says: 243848b8605Smrg * 244848b8605Smrg * "If the <bufSize> parameter to GetInternalformativ is negative, then 245848b8605Smrg * an INVALID_VALUE error is generated." 246b8e80941Smrg * 247b8e80941Smrg * Nothing is said in ARB_internalformat_query2 but we assume the same. 248848b8605Smrg */ 249848b8605Smrg if (bufSize < 0) { 250848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, 251848b8605Smrg "glGetInternalformativ(target=%s)", 252b8e80941Smrg _mesa_enum_to_string(target)); 253b8e80941Smrg return false; 254b8e80941Smrg } 255b8e80941Smrg 256b8e80941Smrg /* The ARB_internalformat_query spec says: 257b8e80941Smrg * 258b8e80941Smrg * "If the <internalformat> parameter to GetInternalformativ is not 259b8e80941Smrg * color-, depth- or stencil-renderable, then an INVALID_ENUM error is 260b8e80941Smrg * generated." 261b8e80941Smrg */ 262b8e80941Smrg if (!query2 && !_is_renderable(ctx, internalformat)) { 263b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, 264b8e80941Smrg "glGetInternalformativ(internalformat=%s)", 265b8e80941Smrg _mesa_enum_to_string(internalformat)); 266b8e80941Smrg return false; 267b8e80941Smrg } 268b8e80941Smrg 269b8e80941Smrg return true; 270b8e80941Smrg} 271b8e80941Smrg 272b8e80941Smrg/* Sets the appropriate "unsupported" response as defined by the 273b8e80941Smrg * ARB_internalformat_query2 spec for each each <pname>. 274b8e80941Smrg */ 275b8e80941Smrgstatic void 276b8e80941Smrg_set_default_response(GLenum pname, GLint buffer[16]) 277b8e80941Smrg{ 278b8e80941Smrg /* The ARB_internalformat_query2 defines which is the reponse best 279b8e80941Smrg * representing "not supported" or "not applicable" for each <pname>. 280b8e80941Smrg * 281b8e80941Smrg * " In general: 282b8e80941Smrg * - size- or count-based queries will return zero, 283b8e80941Smrg * - support-, format- or type-based queries will return NONE, 284b8e80941Smrg * - boolean-based queries will return FALSE, and 285b8e80941Smrg * - list-based queries return no entries." 286b8e80941Smrg */ 287b8e80941Smrg switch(pname) { 288b8e80941Smrg case GL_SAMPLES: 289b8e80941Smrg case GL_TILING_TYPES_EXT: 290b8e80941Smrg break; 291b8e80941Smrg 292b8e80941Smrg case GL_MAX_COMBINED_DIMENSIONS: 293b8e80941Smrg /* This value can be a 64-bit value. As the default is the 32-bit query, 294b8e80941Smrg * we pack 2 32-bit integers. So we need to clean both */ 295b8e80941Smrg buffer[0] = 0; 296b8e80941Smrg buffer[1] = 0; 297b8e80941Smrg break; 298b8e80941Smrg 299b8e80941Smrg case GL_NUM_SAMPLE_COUNTS: 300b8e80941Smrg case GL_INTERNALFORMAT_RED_SIZE: 301b8e80941Smrg case GL_INTERNALFORMAT_GREEN_SIZE: 302b8e80941Smrg case GL_INTERNALFORMAT_BLUE_SIZE: 303b8e80941Smrg case GL_INTERNALFORMAT_ALPHA_SIZE: 304b8e80941Smrg case GL_INTERNALFORMAT_DEPTH_SIZE: 305b8e80941Smrg case GL_INTERNALFORMAT_STENCIL_SIZE: 306b8e80941Smrg case GL_INTERNALFORMAT_SHARED_SIZE: 307b8e80941Smrg case GL_MAX_WIDTH: 308b8e80941Smrg case GL_MAX_HEIGHT: 309b8e80941Smrg case GL_MAX_DEPTH: 310b8e80941Smrg case GL_MAX_LAYERS: 311b8e80941Smrg case GL_IMAGE_TEXEL_SIZE: 312b8e80941Smrg case GL_TEXTURE_COMPRESSED_BLOCK_WIDTH: 313b8e80941Smrg case GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT: 314b8e80941Smrg case GL_TEXTURE_COMPRESSED_BLOCK_SIZE: 315b8e80941Smrg case GL_NUM_TILING_TYPES_EXT: 316b8e80941Smrg buffer[0] = 0; 317b8e80941Smrg break; 318b8e80941Smrg 319b8e80941Smrg case GL_INTERNALFORMAT_PREFERRED: 320b8e80941Smrg case GL_INTERNALFORMAT_RED_TYPE: 321b8e80941Smrg case GL_INTERNALFORMAT_GREEN_TYPE: 322b8e80941Smrg case GL_INTERNALFORMAT_BLUE_TYPE: 323b8e80941Smrg case GL_INTERNALFORMAT_ALPHA_TYPE: 324b8e80941Smrg case GL_INTERNALFORMAT_DEPTH_TYPE: 325b8e80941Smrg case GL_INTERNALFORMAT_STENCIL_TYPE: 326b8e80941Smrg case GL_FRAMEBUFFER_RENDERABLE: 327b8e80941Smrg case GL_FRAMEBUFFER_RENDERABLE_LAYERED: 328b8e80941Smrg case GL_FRAMEBUFFER_BLEND: 329b8e80941Smrg case GL_READ_PIXELS: 330b8e80941Smrg case GL_READ_PIXELS_FORMAT: 331b8e80941Smrg case GL_READ_PIXELS_TYPE: 332b8e80941Smrg case GL_TEXTURE_IMAGE_FORMAT: 333b8e80941Smrg case GL_TEXTURE_IMAGE_TYPE: 334b8e80941Smrg case GL_GET_TEXTURE_IMAGE_FORMAT: 335b8e80941Smrg case GL_GET_TEXTURE_IMAGE_TYPE: 336b8e80941Smrg case GL_MANUAL_GENERATE_MIPMAP: 337b8e80941Smrg case GL_AUTO_GENERATE_MIPMAP: 338b8e80941Smrg case GL_COLOR_ENCODING: 339b8e80941Smrg case GL_SRGB_READ: 340b8e80941Smrg case GL_SRGB_WRITE: 341b8e80941Smrg case GL_SRGB_DECODE_ARB: 342b8e80941Smrg case GL_FILTER: 343b8e80941Smrg case GL_VERTEX_TEXTURE: 344b8e80941Smrg case GL_TESS_CONTROL_TEXTURE: 345b8e80941Smrg case GL_TESS_EVALUATION_TEXTURE: 346b8e80941Smrg case GL_GEOMETRY_TEXTURE: 347b8e80941Smrg case GL_FRAGMENT_TEXTURE: 348b8e80941Smrg case GL_COMPUTE_TEXTURE: 349b8e80941Smrg case GL_TEXTURE_SHADOW: 350b8e80941Smrg case GL_TEXTURE_GATHER: 351b8e80941Smrg case GL_TEXTURE_GATHER_SHADOW: 352b8e80941Smrg case GL_SHADER_IMAGE_LOAD: 353b8e80941Smrg case GL_SHADER_IMAGE_STORE: 354b8e80941Smrg case GL_SHADER_IMAGE_ATOMIC: 355b8e80941Smrg case GL_IMAGE_COMPATIBILITY_CLASS: 356b8e80941Smrg case GL_IMAGE_PIXEL_FORMAT: 357b8e80941Smrg case GL_IMAGE_PIXEL_TYPE: 358b8e80941Smrg case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE: 359b8e80941Smrg case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST: 360b8e80941Smrg case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST: 361b8e80941Smrg case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE: 362b8e80941Smrg case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE: 363b8e80941Smrg case GL_CLEAR_BUFFER: 364b8e80941Smrg case GL_TEXTURE_VIEW: 365b8e80941Smrg case GL_VIEW_COMPATIBILITY_CLASS: 366b8e80941Smrg buffer[0] = GL_NONE; 367b8e80941Smrg break; 368b8e80941Smrg 369b8e80941Smrg case GL_INTERNALFORMAT_SUPPORTED: 370b8e80941Smrg case GL_COLOR_COMPONENTS: 371b8e80941Smrg case GL_DEPTH_COMPONENTS: 372b8e80941Smrg case GL_STENCIL_COMPONENTS: 373b8e80941Smrg case GL_COLOR_RENDERABLE: 374b8e80941Smrg case GL_DEPTH_RENDERABLE: 375b8e80941Smrg case GL_STENCIL_RENDERABLE: 376b8e80941Smrg case GL_MIPMAP: 377b8e80941Smrg case GL_TEXTURE_COMPRESSED: 378b8e80941Smrg buffer[0] = GL_FALSE; 379b8e80941Smrg break; 380b8e80941Smrg 381b8e80941Smrg default: 382b8e80941Smrg unreachable("invalid 'pname'"); 383b8e80941Smrg } 384b8e80941Smrg} 385b8e80941Smrg 386b8e80941Smrgstatic bool 387b8e80941Smrg_is_target_supported(struct gl_context *ctx, GLenum target) 388b8e80941Smrg{ 389b8e80941Smrg /* The ARB_internalformat_query2 spec says: 390b8e80941Smrg * 391b8e80941Smrg * "if a particular type of <target> is not supported by the 392b8e80941Smrg * implementation the "unsupported" answer should be given. 393b8e80941Smrg * This is not an error." 394b8e80941Smrg * 395b8e80941Smrg * Note that legality of targets has already been verified. 396b8e80941Smrg */ 397b8e80941Smrg switch(target){ 398b8e80941Smrg case GL_TEXTURE_1D: 399b8e80941Smrg case GL_TEXTURE_2D: 400b8e80941Smrg case GL_TEXTURE_3D: 401b8e80941Smrg break; 402b8e80941Smrg 403b8e80941Smrg case GL_TEXTURE_1D_ARRAY: 404b8e80941Smrg if (!_mesa_has_EXT_texture_array(ctx)) 405b8e80941Smrg return false; 406b8e80941Smrg break; 407b8e80941Smrg 408b8e80941Smrg case GL_TEXTURE_2D_ARRAY: 409b8e80941Smrg if (!_mesa_has_EXT_texture_array(ctx)) 410b8e80941Smrg return false; 411b8e80941Smrg break; 412b8e80941Smrg 413b8e80941Smrg case GL_TEXTURE_CUBE_MAP: 414b8e80941Smrg if (ctx->API != API_OPENGL_CORE && !_mesa_has_ARB_texture_cube_map(ctx)) 415b8e80941Smrg return false; 416b8e80941Smrg break; 417b8e80941Smrg 418b8e80941Smrg case GL_TEXTURE_CUBE_MAP_ARRAY: 419b8e80941Smrg if (!_mesa_has_ARB_texture_cube_map_array(ctx)) 420b8e80941Smrg return false; 421b8e80941Smrg break; 422b8e80941Smrg 423b8e80941Smrg case GL_TEXTURE_RECTANGLE: 424b8e80941Smrg if (!_mesa_has_ARB_texture_rectangle(ctx)) 425b8e80941Smrg return false; 426b8e80941Smrg break; 427b8e80941Smrg 428b8e80941Smrg case GL_TEXTURE_BUFFER: 429b8e80941Smrg if (!_mesa_has_ARB_texture_buffer_object(ctx)) 430b8e80941Smrg return false; 431b8e80941Smrg break; 432b8e80941Smrg 433b8e80941Smrg case GL_RENDERBUFFER: 434b8e80941Smrg if (!(_mesa_has_ARB_framebuffer_object(ctx) || 435b8e80941Smrg _mesa_is_gles3(ctx))) 436b8e80941Smrg return false; 437b8e80941Smrg break; 438b8e80941Smrg 439b8e80941Smrg case GL_TEXTURE_2D_MULTISAMPLE: 440b8e80941Smrg case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 441b8e80941Smrg if (!(_mesa_has_ARB_texture_multisample(ctx) || 442b8e80941Smrg _mesa_is_gles31(ctx))) 443b8e80941Smrg return false; 444b8e80941Smrg break; 445b8e80941Smrg 446b8e80941Smrg default: 447b8e80941Smrg unreachable("invalid target"); 448b8e80941Smrg } 449b8e80941Smrg 450b8e80941Smrg return true; 451b8e80941Smrg} 452b8e80941Smrg 453b8e80941Smrgstatic bool 454b8e80941Smrg_is_resource_supported(struct gl_context *ctx, GLenum target, 455b8e80941Smrg GLenum internalformat, GLenum pname) 456b8e80941Smrg{ 457b8e80941Smrg /* From the ARB_internalformat_query2 spec: 458b8e80941Smrg * 459b8e80941Smrg * In the following descriptions, the term /resource/ is used to generically 460b8e80941Smrg * refer to an object of the appropriate type that has been created with 461b8e80941Smrg * <internalformat> and <target>. If the particular <target> and 462b8e80941Smrg * <internalformat> combination do not make sense, ... the "unsupported" 463b8e80941Smrg * answer should be given. This is not an error. 464b8e80941Smrg */ 465b8e80941Smrg 466b8e80941Smrg /* In the ARB_internalformat_query2 spec wording, some <pnames> do not care 467b8e80941Smrg * about the /resource/ being supported or not, we return 'true' for those. 468b8e80941Smrg */ 469b8e80941Smrg switch (pname) { 470b8e80941Smrg case GL_INTERNALFORMAT_SUPPORTED: 471b8e80941Smrg case GL_INTERNALFORMAT_PREFERRED: 472b8e80941Smrg case GL_COLOR_COMPONENTS: 473b8e80941Smrg case GL_DEPTH_COMPONENTS: 474b8e80941Smrg case GL_STENCIL_COMPONENTS: 475b8e80941Smrg case GL_COLOR_RENDERABLE: 476b8e80941Smrg case GL_DEPTH_RENDERABLE: 477b8e80941Smrg case GL_STENCIL_RENDERABLE: 478b8e80941Smrg return true; 479b8e80941Smrg default: 480b8e80941Smrg break; 481b8e80941Smrg } 482b8e80941Smrg 483b8e80941Smrg switch(target){ 484b8e80941Smrg case GL_TEXTURE_1D: 485b8e80941Smrg case GL_TEXTURE_1D_ARRAY: 486b8e80941Smrg case GL_TEXTURE_2D: 487b8e80941Smrg case GL_TEXTURE_2D_ARRAY: 488b8e80941Smrg case GL_TEXTURE_3D: 489b8e80941Smrg case GL_TEXTURE_CUBE_MAP: 490b8e80941Smrg case GL_TEXTURE_CUBE_MAP_ARRAY: 491b8e80941Smrg case GL_TEXTURE_RECTANGLE: 492b8e80941Smrg /* Based on what Mesa does for glTexImage1D/2D/3D and 493b8e80941Smrg * glCompressedTexImage1D/2D/3D functions. 494b8e80941Smrg */ 495b8e80941Smrg if (_mesa_base_tex_format(ctx, internalformat) < 0) 496b8e80941Smrg return false; 497b8e80941Smrg 498b8e80941Smrg /* additional checks for depth textures */ 499b8e80941Smrg if (!_mesa_legal_texture_base_format_for_target(ctx, target, internalformat)) 500b8e80941Smrg return false; 501b8e80941Smrg 502b8e80941Smrg /* additional checks for compressed textures */ 503b8e80941Smrg if (_mesa_is_compressed_format(ctx, internalformat) && 504b8e80941Smrg !_mesa_target_can_be_compressed(ctx, target, internalformat, NULL)) 505b8e80941Smrg return false; 506b8e80941Smrg 507b8e80941Smrg break; 508b8e80941Smrg case GL_TEXTURE_2D_MULTISAMPLE: 509b8e80941Smrg case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 510b8e80941Smrg /* Based on what Mesa does for glTexImage2D/3DMultisample, 511b8e80941Smrg * glTexStorage2D/3DMultisample and 512b8e80941Smrg * glTextureStorage2D/3DMultisample functions. 513b8e80941Smrg */ 514b8e80941Smrg if (!_mesa_is_renderable_texture_format(ctx, internalformat)) 515b8e80941Smrg return false; 516b8e80941Smrg 517b8e80941Smrg break; 518b8e80941Smrg case GL_TEXTURE_BUFFER: 519b8e80941Smrg /* Based on what Mesa does for the glTexBuffer function. */ 520b8e80941Smrg if (_mesa_validate_texbuffer_format(ctx, internalformat) == 521b8e80941Smrg MESA_FORMAT_NONE) 522b8e80941Smrg return false; 523b8e80941Smrg 524b8e80941Smrg break; 525b8e80941Smrg case GL_RENDERBUFFER: 526b8e80941Smrg /* Based on what Mesa does for glRenderbufferStorage(Multisample) and 527b8e80941Smrg * glNamedRenderbufferStorage functions. 528b8e80941Smrg */ 529b8e80941Smrg if (!_mesa_base_fbo_format(ctx, internalformat)) 530b8e80941Smrg return false; 531b8e80941Smrg 532b8e80941Smrg break; 533b8e80941Smrg default: 534b8e80941Smrg unreachable("bad target"); 535b8e80941Smrg } 536b8e80941Smrg 537b8e80941Smrg return true; 538b8e80941Smrg} 539b8e80941Smrg 540b8e80941Smrgstatic bool 541b8e80941Smrg_is_internalformat_supported(struct gl_context *ctx, GLenum target, 542b8e80941Smrg GLenum internalformat) 543b8e80941Smrg{ 544b8e80941Smrg /* From the ARB_internalformat_query2 specification: 545b8e80941Smrg * 546b8e80941Smrg * "- INTERNALFORMAT_SUPPORTED: If <internalformat> is an internal format 547b8e80941Smrg * that is supported by the implementation in at least some subset of 548b8e80941Smrg * possible operations, TRUE is written to <params>. If <internalformat> 549b8e80941Smrg * if not a valid token for any internal format usage, FALSE is returned. 550b8e80941Smrg * 551b8e80941Smrg * <internalformats> that must be supported (in GL 4.2 or later) include 552b8e80941Smrg * the following: 553b8e80941Smrg * - "sized internal formats" from Table 3.12, 3.13, and 3.15, 554b8e80941Smrg * - any specific "compressed internal format" from Table 3.14, 555b8e80941Smrg * - any "image unit format" from Table 3.21. 556b8e80941Smrg * - any generic "compressed internal format" from Table 3.14, if the 557b8e80941Smrg * implementation accepts it for any texture specification commands, and 558b8e80941Smrg * - unsized or base internal format, if the implementation accepts 559b8e80941Smrg * it for texture or image specification. 560b8e80941Smrg * 561b8e80941Smrg * But also: 562b8e80941Smrg * "If the particualar <target> and <internalformat> combination do not make 563b8e80941Smrg * sense, or if a particular type of <target> is not supported by the 564b8e80941Smrg * implementation the "unsupported" answer should be given. This is not an 565b8e80941Smrg * error. 566b8e80941Smrg */ 567b8e80941Smrg GLint buffer[1]; 568b8e80941Smrg 569b8e80941Smrg if (target == GL_RENDERBUFFER) { 570b8e80941Smrg if (_mesa_base_fbo_format(ctx, internalformat) == 0) { 571b8e80941Smrg return false; 572b8e80941Smrg } 573b8e80941Smrg } else if (target == GL_TEXTURE_BUFFER) { 574b8e80941Smrg if (_mesa_validate_texbuffer_format(ctx, internalformat) == 575b8e80941Smrg MESA_FORMAT_NONE) { 576b8e80941Smrg return false; 577b8e80941Smrg } 578b8e80941Smrg } else { 579b8e80941Smrg if (_mesa_base_tex_format(ctx, internalformat) < 0) { 580b8e80941Smrg return false; 581b8e80941Smrg } 582b8e80941Smrg } 583b8e80941Smrg 584b8e80941Smrg /* Let the driver have the final word */ 585b8e80941Smrg ctx->Driver.QueryInternalFormat(ctx, target, internalformat, 586b8e80941Smrg GL_INTERNALFORMAT_SUPPORTED, buffer); 587b8e80941Smrg 588b8e80941Smrg return (buffer[0] == GL_TRUE); 589b8e80941Smrg} 590b8e80941Smrg 591b8e80941Smrgstatic bool 592b8e80941Smrg_legal_target_for_framebuffer_texture_layer(struct gl_context *ctx, 593b8e80941Smrg GLenum target) 594b8e80941Smrg{ 595b8e80941Smrg switch (target) { 596b8e80941Smrg case GL_TEXTURE_3D: 597b8e80941Smrg case GL_TEXTURE_1D_ARRAY: 598b8e80941Smrg case GL_TEXTURE_2D_ARRAY: 599b8e80941Smrg case GL_TEXTURE_CUBE_MAP_ARRAY: 600b8e80941Smrg case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 601b8e80941Smrg case GL_TEXTURE_CUBE_MAP: 602b8e80941Smrg return true; 603b8e80941Smrg default: 604b8e80941Smrg return false; 605b8e80941Smrg } 606b8e80941Smrg} 607b8e80941Smrg 608b8e80941Smrgstatic GLenum 609b8e80941Smrg_mesa_generic_type_for_internal_format(GLenum internalFormat) 610b8e80941Smrg{ 611b8e80941Smrg if (_mesa_is_enum_format_unsigned_int(internalFormat)) 612b8e80941Smrg return GL_UNSIGNED_BYTE; 613b8e80941Smrg else if (_mesa_is_enum_format_signed_int(internalFormat)) 614b8e80941Smrg return GL_BYTE; 615b8e80941Smrg else 616b8e80941Smrg return GL_FLOAT; 617b8e80941Smrg} 618b8e80941Smrg 619b8e80941Smrg/* default implementation of QueryInternalFormat driverfunc, for 620b8e80941Smrg * drivers not implementing ARB_internalformat_query2. 621b8e80941Smrg */ 622b8e80941Smrgvoid 623b8e80941Smrg_mesa_query_internal_format_default(struct gl_context *ctx, GLenum target, 624b8e80941Smrg GLenum internalFormat, GLenum pname, 625b8e80941Smrg GLint *params) 626b8e80941Smrg{ 627b8e80941Smrg (void) target; 628b8e80941Smrg 629b8e80941Smrg switch (pname) { 630b8e80941Smrg case GL_SAMPLES: 631b8e80941Smrg case GL_NUM_SAMPLE_COUNTS: 632b8e80941Smrg params[0] = 1; 633b8e80941Smrg break; 634b8e80941Smrg 635b8e80941Smrg case GL_INTERNALFORMAT_SUPPORTED: 636b8e80941Smrg params[0] = GL_TRUE; 637b8e80941Smrg break; 638b8e80941Smrg 639b8e80941Smrg case GL_INTERNALFORMAT_PREFERRED: 640b8e80941Smrg params[0] = internalFormat; 641b8e80941Smrg break; 642b8e80941Smrg 643b8e80941Smrg case GL_READ_PIXELS_FORMAT: { 644b8e80941Smrg GLenum base_format = _mesa_base_tex_format(ctx, internalFormat); 645b8e80941Smrg switch (base_format) { 646b8e80941Smrg case GL_STENCIL_INDEX: 647b8e80941Smrg case GL_DEPTH_COMPONENT: 648b8e80941Smrg case GL_DEPTH_STENCIL: 649b8e80941Smrg case GL_RED: 650b8e80941Smrg case GL_RGB: 651b8e80941Smrg case GL_BGR: 652b8e80941Smrg case GL_RGBA: 653b8e80941Smrg case GL_BGRA: 654b8e80941Smrg params[0] = base_format; 655b8e80941Smrg break; 656b8e80941Smrg default: 657b8e80941Smrg params[0] = GL_NONE; 658b8e80941Smrg break; 659b8e80941Smrg } 660b8e80941Smrg break; 661b8e80941Smrg } 662b8e80941Smrg 663b8e80941Smrg case GL_READ_PIXELS_TYPE: 664b8e80941Smrg case GL_TEXTURE_IMAGE_TYPE: 665b8e80941Smrg case GL_GET_TEXTURE_IMAGE_TYPE: { 666b8e80941Smrg GLenum base_format = _mesa_base_tex_format(ctx, internalFormat); 667b8e80941Smrg if (base_format > 0) 668b8e80941Smrg params[0] = _mesa_generic_type_for_internal_format(internalFormat); 669b8e80941Smrg else 670b8e80941Smrg params[0] = GL_NONE; 671b8e80941Smrg break; 672b8e80941Smrg } 673b8e80941Smrg 674b8e80941Smrg case GL_TEXTURE_IMAGE_FORMAT: 675b8e80941Smrg case GL_GET_TEXTURE_IMAGE_FORMAT: { 676b8e80941Smrg GLenum format = GL_NONE; 677b8e80941Smrg GLenum base_format = _mesa_base_tex_format(ctx, internalFormat); 678b8e80941Smrg if (base_format > 0) { 679b8e80941Smrg if (_mesa_is_enum_format_integer(internalFormat)) 680b8e80941Smrg format = _mesa_base_format_to_integer_format(base_format); 681b8e80941Smrg else 682b8e80941Smrg format = base_format; 683b8e80941Smrg } 684b8e80941Smrg 685b8e80941Smrg params[0] = format; 686b8e80941Smrg break; 687b8e80941Smrg } 688b8e80941Smrg 689b8e80941Smrg case GL_MANUAL_GENERATE_MIPMAP: 690b8e80941Smrg case GL_AUTO_GENERATE_MIPMAP: 691b8e80941Smrg case GL_SRGB_READ: 692b8e80941Smrg case GL_SRGB_WRITE: 693b8e80941Smrg case GL_SRGB_DECODE_ARB: 694b8e80941Smrg case GL_VERTEX_TEXTURE: 695b8e80941Smrg case GL_TESS_CONTROL_TEXTURE: 696b8e80941Smrg case GL_TESS_EVALUATION_TEXTURE: 697b8e80941Smrg case GL_GEOMETRY_TEXTURE: 698b8e80941Smrg case GL_FRAGMENT_TEXTURE: 699b8e80941Smrg case GL_COMPUTE_TEXTURE: 700b8e80941Smrg case GL_SHADER_IMAGE_LOAD: 701b8e80941Smrg case GL_SHADER_IMAGE_STORE: 702b8e80941Smrg case GL_SHADER_IMAGE_ATOMIC: 703b8e80941Smrg case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST: 704b8e80941Smrg case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST: 705b8e80941Smrg case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE: 706b8e80941Smrg case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE: 707b8e80941Smrg case GL_CLEAR_BUFFER: 708b8e80941Smrg case GL_TEXTURE_VIEW: 709b8e80941Smrg case GL_TEXTURE_SHADOW: 710b8e80941Smrg case GL_TEXTURE_GATHER: 711b8e80941Smrg case GL_TEXTURE_GATHER_SHADOW: 712b8e80941Smrg case GL_FRAMEBUFFER_RENDERABLE: 713b8e80941Smrg case GL_FRAMEBUFFER_RENDERABLE_LAYERED: 714b8e80941Smrg case GL_FRAMEBUFFER_BLEND: 715b8e80941Smrg case GL_FILTER: 716b8e80941Smrg /* 717b8e80941Smrg * TODO seems a tad optimistic just saying yes to everything here. 718b8e80941Smrg * Even for combinations which make no sense... 719b8e80941Smrg * And things like TESS_CONTROL_TEXTURE should definitely default to 720b8e80941Smrg * NONE if the driver doesn't even support tessellation... 721b8e80941Smrg */ 722b8e80941Smrg params[0] = GL_FULL_SUPPORT; 723b8e80941Smrg break; 724b8e80941Smrg case GL_NUM_TILING_TYPES_EXT: 725b8e80941Smrg params[0] = 2; 726b8e80941Smrg break; 727b8e80941Smrg case GL_TILING_TYPES_EXT: 728b8e80941Smrg params[0] = GL_OPTIMAL_TILING_EXT; 729b8e80941Smrg params[1] = GL_LINEAR_TILING_EXT; 730b8e80941Smrg break; 731b8e80941Smrg 732b8e80941Smrg default: 733b8e80941Smrg _set_default_response(pname, params); 734b8e80941Smrg break; 735b8e80941Smrg } 736b8e80941Smrg} 737b8e80941Smrg 738b8e80941Smrg/* 739b8e80941Smrg * For MAX_WIDTH/MAX_HEIGHT/MAX_DEPTH it returns the equivalent GetInteger 740b8e80941Smrg * pname for a Getinternalformat pname/target combination. target/pname 741b8e80941Smrg * combinations that would return 0 due dimension number or unsupported status 742b8e80941Smrg * should be already filtered out 743b8e80941Smrg * 744b8e80941Smrg * Note that this means that the returned value would be independent of the 745b8e80941Smrg * internalformat. This possibility is already mentioned at the Issue 7 of the 746b8e80941Smrg * arb_internalformat_query2 spec. 747b8e80941Smrg */ 748b8e80941Smrgstatic GLenum 749b8e80941Smrg_equivalent_size_pname(GLenum target, 750b8e80941Smrg GLenum pname) 751b8e80941Smrg{ 752b8e80941Smrg switch (target) { 753b8e80941Smrg case GL_TEXTURE_1D: 754b8e80941Smrg case GL_TEXTURE_2D: 755b8e80941Smrg case GL_TEXTURE_2D_MULTISAMPLE: 756b8e80941Smrg return GL_MAX_TEXTURE_SIZE; 757b8e80941Smrg case GL_TEXTURE_3D: 758b8e80941Smrg return GL_MAX_3D_TEXTURE_SIZE; 759b8e80941Smrg case GL_TEXTURE_CUBE_MAP: 760b8e80941Smrg return GL_MAX_CUBE_MAP_TEXTURE_SIZE; 761b8e80941Smrg case GL_TEXTURE_RECTANGLE: 762b8e80941Smrg return GL_MAX_RECTANGLE_TEXTURE_SIZE; 763b8e80941Smrg case GL_RENDERBUFFER: 764b8e80941Smrg return GL_MAX_RENDERBUFFER_SIZE; 765b8e80941Smrg case GL_TEXTURE_1D_ARRAY: 766b8e80941Smrg if (pname == GL_MAX_HEIGHT) 767b8e80941Smrg return GL_MAX_ARRAY_TEXTURE_LAYERS; 768b8e80941Smrg else 769b8e80941Smrg return GL_MAX_TEXTURE_SIZE; 770b8e80941Smrg case GL_TEXTURE_2D_ARRAY: 771b8e80941Smrg case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 772b8e80941Smrg if (pname == GL_MAX_DEPTH) 773b8e80941Smrg return GL_MAX_ARRAY_TEXTURE_LAYERS; 774b8e80941Smrg else 775b8e80941Smrg return GL_MAX_TEXTURE_SIZE; 776b8e80941Smrg case GL_TEXTURE_CUBE_MAP_ARRAY: 777b8e80941Smrg if (pname == GL_MAX_DEPTH) 778b8e80941Smrg return GL_MAX_ARRAY_TEXTURE_LAYERS; 779b8e80941Smrg else 780b8e80941Smrg return GL_MAX_CUBE_MAP_TEXTURE_SIZE; 781b8e80941Smrg case GL_TEXTURE_BUFFER: 782b8e80941Smrg return GL_MAX_TEXTURE_BUFFER_SIZE; 783b8e80941Smrg default: 784b8e80941Smrg return 0; 785b8e80941Smrg } 786b8e80941Smrg} 787b8e80941Smrg 788b8e80941Smrg/* 789b8e80941Smrg * Returns the dimensions associated to a target. GL_TEXTURE_BUFFER and 790b8e80941Smrg * GL_RENDERBUFFER have associated a dimension, but they are not textures 791b8e80941Smrg * per-se, so we can't just call _mesa_get_texture_dimension directly. 792b8e80941Smrg */ 793b8e80941Smrgstatic GLint 794b8e80941Smrg_get_target_dimensions(GLenum target) 795b8e80941Smrg{ 796b8e80941Smrg switch(target) { 797b8e80941Smrg case GL_TEXTURE_BUFFER: 798b8e80941Smrg return 1; 799b8e80941Smrg case GL_RENDERBUFFER: 800b8e80941Smrg return 2; 801b8e80941Smrg default: 802b8e80941Smrg return _mesa_get_texture_dimensions(target); 803b8e80941Smrg } 804b8e80941Smrg} 805b8e80941Smrg 806b8e80941Smrg/* 807b8e80941Smrg * Returns the minimum amount of dimensions associated to a pname. So for 808b8e80941Smrg * example, if querying GL_MAX_HEIGHT, it is assumed that your target would 809b8e80941Smrg * have as minimum 2 dimensions. 810b8e80941Smrg * 811b8e80941Smrg * Useful to handle sentences like this from query2 spec: 812b8e80941Smrg * 813b8e80941Smrg * "MAX_HEIGHT: 814b8e80941Smrg * <skip> 815b8e80941Smrg * If the resource does not have at least two dimensions 816b8e80941Smrg * <skip>." 817b8e80941Smrg */ 818b8e80941Smrgstatic GLint 819b8e80941Smrg_get_min_dimensions(GLenum pname) 820b8e80941Smrg{ 821b8e80941Smrg switch(pname) { 822b8e80941Smrg case GL_MAX_WIDTH: 823b8e80941Smrg return 1; 824b8e80941Smrg case GL_MAX_HEIGHT: 825b8e80941Smrg return 2; 826b8e80941Smrg case GL_MAX_DEPTH: 827b8e80941Smrg return 3; 828b8e80941Smrg default: 829b8e80941Smrg return 0; 830b8e80941Smrg } 831b8e80941Smrg} 832b8e80941Smrg 833b8e80941Smrg/* 834b8e80941Smrg * Similar to teximage.c:check_multisample_target, but independent of the 835b8e80941Smrg * dimensions. 836b8e80941Smrg */ 837b8e80941Smrgstatic bool 838b8e80941Smrg_is_multisample_target(GLenum target) 839b8e80941Smrg{ 840b8e80941Smrg switch(target) { 841b8e80941Smrg case GL_TEXTURE_2D_MULTISAMPLE: 842b8e80941Smrg case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 843b8e80941Smrg return true; 844b8e80941Smrg default: 845b8e80941Smrg return false; 846b8e80941Smrg } 847b8e80941Smrg 848b8e80941Smrg} 849b8e80941Smrg 850b8e80941Smrgvoid GLAPIENTRY 851b8e80941Smrg_mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, 852b8e80941Smrg GLsizei bufSize, GLint *params) 853b8e80941Smrg{ 854b8e80941Smrg GLint buffer[16]; 855b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 856b8e80941Smrg 857b8e80941Smrg ASSERT_OUTSIDE_BEGIN_END(ctx); 858b8e80941Smrg 859b8e80941Smrg /* ARB_internalformat_query is also mandatory for ARB_internalformat_query2 */ 860b8e80941Smrg if (!(_mesa_has_ARB_internalformat_query(ctx) || 861b8e80941Smrg _mesa_is_gles3(ctx))) { 862b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInternalformativ"); 863848b8605Smrg return; 864848b8605Smrg } 865848b8605Smrg 866b8e80941Smrg assert(ctx->Driver.QueryInternalFormat != NULL); 867b8e80941Smrg 868b8e80941Smrg if (!_legal_parameters(ctx, target, internalformat, pname, bufSize, params)) 869b8e80941Smrg return; 870b8e80941Smrg 871b8e80941Smrg /* initialize the contents of the temporary buffer */ 872b8e80941Smrg memcpy(buffer, params, MIN2(bufSize, 16) * sizeof(GLint)); 873b8e80941Smrg 874b8e80941Smrg /* Use the 'unsupported' response defined by the spec for every pname 875b8e80941Smrg * as the default answer. 876b8e80941Smrg */ 877b8e80941Smrg _set_default_response(pname, buffer); 878b8e80941Smrg 879b8e80941Smrg if (!_is_target_supported(ctx, target) || 880b8e80941Smrg !_is_internalformat_supported(ctx, target, internalformat) || 881b8e80941Smrg !_is_resource_supported(ctx, target, internalformat, pname)) 882b8e80941Smrg goto end; 883b8e80941Smrg 884848b8605Smrg switch (pname) { 885848b8605Smrg case GL_SAMPLES: 886b8e80941Smrg /* fall-through */ 887b8e80941Smrg case GL_NUM_SAMPLE_COUNTS: 888b8e80941Smrg /* The ARB_internalformat_query2 sets the response as 'unsupported' for 889b8e80941Smrg * SAMPLES and NUM_SAMPLE_COUNTS: 890b8e80941Smrg * 891b8e80941Smrg * "If <internalformat> is not color-renderable, depth-renderable, or 892b8e80941Smrg * stencil-renderable (as defined in section 4.4.4), or if <target> 893b8e80941Smrg * does not support multiple samples (ie other than 894b8e80941Smrg * TEXTURE_2D_MULTISAMPLE, TEXTURE_2D_MULTISAMPLE_ARRAY, 895b8e80941Smrg * or RENDERBUFFER)." 896b8e80941Smrg */ 897b8e80941Smrg if ((target != GL_RENDERBUFFER && 898b8e80941Smrg target != GL_TEXTURE_2D_MULTISAMPLE && 899b8e80941Smrg target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY) || 900b8e80941Smrg !_is_renderable(ctx, internalformat)) 901b8e80941Smrg goto end; 902b8e80941Smrg 903b8e80941Smrg /* The GL ES 3.0 specification, section 6.1.15 page 236 says: 904b8e80941Smrg * 905b8e80941Smrg * "Since multisampling is not supported for signed and unsigned 906b8e80941Smrg * integer internal formats, the value of NUM_SAMPLE_COUNTS will be 907b8e80941Smrg * zero for such formats. 908b8e80941Smrg * 909b8e80941Smrg * Since OpenGL ES 3.1 adds support for multisampled integer formats, we 910b8e80941Smrg * have to check the version for 30 exactly. 911b8e80941Smrg */ 912b8e80941Smrg if (pname == GL_NUM_SAMPLE_COUNTS && ctx->API == API_OPENGLES2 && 913b8e80941Smrg ctx->Version == 30 && _mesa_is_enum_format_integer(internalformat)) { 914b8e80941Smrg goto end; 915b8e80941Smrg } 916b8e80941Smrg 917b8e80941Smrg ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 918b8e80941Smrg buffer); 919b8e80941Smrg break; 920b8e80941Smrg 921b8e80941Smrg case GL_INTERNALFORMAT_SUPPORTED: 922b8e80941Smrg /* Having a supported <internalformat> is implemented as a prerequisite 923b8e80941Smrg * for all the <pnames>. Thus, if we reach this point, the internalformat is 924b8e80941Smrg * supported. 925b8e80941Smrg */ 926b8e80941Smrg buffer[0] = GL_TRUE; 927b8e80941Smrg break; 928b8e80941Smrg 929b8e80941Smrg case GL_INTERNALFORMAT_PREFERRED: 930b8e80941Smrg /* The ARB_internalformat_query2 spec says: 931b8e80941Smrg * 932b8e80941Smrg * "- INTERNALFORMAT_PREFERRED: The implementation-preferred internal 933b8e80941Smrg * format for representing resources of the specified <internalformat> is 934b8e80941Smrg * returned in <params>. 935b8e80941Smrg * 936b8e80941Smrg * Therefore, we let the driver answer. Note that if we reach this 937b8e80941Smrg * point, it means that the internalformat is supported, so the driver 938b8e80941Smrg * is called just to try to get a preferred format. If not supported, 939b8e80941Smrg * GL_NONE was already returned and the driver is not called. 940b8e80941Smrg */ 941b8e80941Smrg ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 942b8e80941Smrg buffer); 943b8e80941Smrg break; 944b8e80941Smrg 945b8e80941Smrg case GL_INTERNALFORMAT_RED_SIZE: 946b8e80941Smrg case GL_INTERNALFORMAT_GREEN_SIZE: 947b8e80941Smrg case GL_INTERNALFORMAT_BLUE_SIZE: 948b8e80941Smrg case GL_INTERNALFORMAT_ALPHA_SIZE: 949b8e80941Smrg case GL_INTERNALFORMAT_DEPTH_SIZE: 950b8e80941Smrg case GL_INTERNALFORMAT_STENCIL_SIZE: 951b8e80941Smrg case GL_INTERNALFORMAT_SHARED_SIZE: 952b8e80941Smrg case GL_INTERNALFORMAT_RED_TYPE: 953b8e80941Smrg case GL_INTERNALFORMAT_GREEN_TYPE: 954b8e80941Smrg case GL_INTERNALFORMAT_BLUE_TYPE: 955b8e80941Smrg case GL_INTERNALFORMAT_ALPHA_TYPE: 956b8e80941Smrg case GL_INTERNALFORMAT_DEPTH_TYPE: 957b8e80941Smrg case GL_INTERNALFORMAT_STENCIL_TYPE: { 958b8e80941Smrg GLint baseformat; 959b8e80941Smrg mesa_format texformat; 960b8e80941Smrg 961b8e80941Smrg if (target != GL_RENDERBUFFER) { 962b8e80941Smrg baseformat = _mesa_base_tex_format(ctx, internalformat); 963b8e80941Smrg } else { 964b8e80941Smrg baseformat = _mesa_base_fbo_format(ctx, internalformat); 965b8e80941Smrg } 966b8e80941Smrg 967b8e80941Smrg /* Let the driver choose the texture format. 968b8e80941Smrg * 969b8e80941Smrg * Disclaimer: I am considering that drivers use for renderbuffers the 970b8e80941Smrg * same format-choice logic as for textures. 971b8e80941Smrg */ 972b8e80941Smrg texformat = ctx->Driver.ChooseTextureFormat(ctx, target, internalformat, 973b8e80941Smrg GL_NONE /*format */, GL_NONE /* type */); 974b8e80941Smrg 975b8e80941Smrg if (texformat == MESA_FORMAT_NONE || baseformat <= 0) 976b8e80941Smrg goto end; 977b8e80941Smrg 978b8e80941Smrg /* Implementation based on what Mesa does for glGetTexLevelParameteriv 979b8e80941Smrg * and glGetRenderbufferParameteriv functions. 980b8e80941Smrg */ 981b8e80941Smrg if (pname == GL_INTERNALFORMAT_SHARED_SIZE) { 982b8e80941Smrg if (texformat == MESA_FORMAT_R9G9B9E5_FLOAT) { 983b8e80941Smrg buffer[0] = 5; 984b8e80941Smrg } 985b8e80941Smrg goto end; 986b8e80941Smrg } 987b8e80941Smrg 988b8e80941Smrg if (!_mesa_base_format_has_channel(baseformat, pname)) 989b8e80941Smrg goto end; 990b8e80941Smrg 991b8e80941Smrg switch (pname) { 992b8e80941Smrg case GL_INTERNALFORMAT_DEPTH_SIZE: 993b8e80941Smrg if (ctx->API != API_OPENGL_CORE && 994b8e80941Smrg !_mesa_has_ARB_depth_texture(ctx) && 995b8e80941Smrg target != GL_RENDERBUFFER && 996b8e80941Smrg target != GL_TEXTURE_BUFFER) 997b8e80941Smrg goto end; 998b8e80941Smrg /* fallthrough */ 999b8e80941Smrg case GL_INTERNALFORMAT_RED_SIZE: 1000b8e80941Smrg case GL_INTERNALFORMAT_GREEN_SIZE: 1001b8e80941Smrg case GL_INTERNALFORMAT_BLUE_SIZE: 1002b8e80941Smrg case GL_INTERNALFORMAT_ALPHA_SIZE: 1003b8e80941Smrg case GL_INTERNALFORMAT_STENCIL_SIZE: 1004b8e80941Smrg buffer[0] = _mesa_get_format_bits(texformat, pname); 1005b8e80941Smrg break; 1006b8e80941Smrg 1007b8e80941Smrg case GL_INTERNALFORMAT_DEPTH_TYPE: 1008b8e80941Smrg if (!_mesa_has_ARB_texture_float(ctx)) 1009b8e80941Smrg goto end; 1010b8e80941Smrg /* fallthrough */ 1011b8e80941Smrg case GL_INTERNALFORMAT_RED_TYPE: 1012b8e80941Smrg case GL_INTERNALFORMAT_GREEN_TYPE: 1013b8e80941Smrg case GL_INTERNALFORMAT_BLUE_TYPE: 1014b8e80941Smrg case GL_INTERNALFORMAT_ALPHA_TYPE: 1015b8e80941Smrg case GL_INTERNALFORMAT_STENCIL_TYPE: 1016b8e80941Smrg buffer[0] = _mesa_get_format_datatype(texformat); 1017b8e80941Smrg break; 1018b8e80941Smrg 1019b8e80941Smrg default: 1020b8e80941Smrg break; 1021b8e80941Smrg 1022b8e80941Smrg } 1023848b8605Smrg break; 1024b8e80941Smrg } 1025b8e80941Smrg 1026b8e80941Smrg /* For WIDTH/HEIGHT/DEPTH/LAYERS there is no reason to think that the 1027b8e80941Smrg * returned values should be different to the values returned by 1028b8e80941Smrg * GetInteger with MAX_TEXTURE_SIZE, MAX_3D_TEXTURE_SIZE, etc.*/ 1029b8e80941Smrg case GL_MAX_WIDTH: 1030b8e80941Smrg case GL_MAX_HEIGHT: 1031b8e80941Smrg case GL_MAX_DEPTH: { 1032b8e80941Smrg GLenum get_pname; 1033b8e80941Smrg GLint dimensions; 1034b8e80941Smrg GLint min_dimensions; 1035b8e80941Smrg 1036b8e80941Smrg /* From query2:MAX_HEIGHT spec (as example): 1037848b8605Smrg * 1038b8e80941Smrg * "If the resource does not have at least two dimensions, or if the 1039b8e80941Smrg * resource is unsupported, zero is returned." 1040b8e80941Smrg */ 1041b8e80941Smrg dimensions = _get_target_dimensions(target); 1042b8e80941Smrg min_dimensions = _get_min_dimensions(pname); 1043b8e80941Smrg if (dimensions < min_dimensions) 1044b8e80941Smrg goto end; 1045b8e80941Smrg 1046b8e80941Smrg get_pname = _equivalent_size_pname(target, pname); 1047b8e80941Smrg if (get_pname == 0) 1048b8e80941Smrg goto end; 1049b8e80941Smrg 1050b8e80941Smrg _mesa_GetIntegerv(get_pname, buffer); 1051b8e80941Smrg break; 1052b8e80941Smrg } 1053b8e80941Smrg 1054b8e80941Smrg case GL_MAX_LAYERS: 1055b8e80941Smrg if (!_mesa_has_EXT_texture_array(ctx)) 1056b8e80941Smrg goto end; 1057b8e80941Smrg 1058b8e80941Smrg if (!_mesa_is_array_texture(target)) 1059b8e80941Smrg goto end; 1060b8e80941Smrg 1061b8e80941Smrg _mesa_GetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, buffer); 1062b8e80941Smrg break; 1063b8e80941Smrg 1064b8e80941Smrg case GL_MAX_COMBINED_DIMENSIONS:{ 1065b8e80941Smrg GLint64 combined_value = 1; 1066b8e80941Smrg GLenum max_dimensions_pnames[] = { 1067b8e80941Smrg GL_MAX_WIDTH, 1068b8e80941Smrg GL_MAX_HEIGHT, 1069b8e80941Smrg GL_MAX_DEPTH, 1070b8e80941Smrg GL_SAMPLES 1071b8e80941Smrg }; 1072b8e80941Smrg unsigned i; 1073b8e80941Smrg GLint current_value; 1074b8e80941Smrg 1075b8e80941Smrg /* Combining the dimensions. Note that for array targets, this would 1076b8e80941Smrg * automatically include the value of MAX_LAYERS, as that value is 1077b8e80941Smrg * returned as MAX_HEIGHT or MAX_DEPTH */ 1078b8e80941Smrg for (i = 0; i < 4; i++) { 1079b8e80941Smrg if (max_dimensions_pnames[i] == GL_SAMPLES && 1080b8e80941Smrg !_is_multisample_target(target)) 1081b8e80941Smrg continue; 1082b8e80941Smrg 1083b8e80941Smrg _mesa_GetInternalformativ(target, internalformat, 1084b8e80941Smrg max_dimensions_pnames[i], 1085b8e80941Smrg 1, ¤t_value); 1086b8e80941Smrg 1087b8e80941Smrg if (current_value != 0) 1088b8e80941Smrg combined_value *= current_value; 1089b8e80941Smrg } 1090b8e80941Smrg 1091b8e80941Smrg if (_mesa_is_cube_map_texture(target)) 1092b8e80941Smrg combined_value *= 6; 1093b8e80941Smrg 1094b8e80941Smrg /* We pack the 64-bit value on two 32-bit values. Calling the 32-bit 1095b8e80941Smrg * query, this would work as far as the value can be hold on a 32-bit 1096b8e80941Smrg * signed integer. For the 64-bit query, the wrapper around the 32-bit 1097b8e80941Smrg * query will unpack the value */ 1098b8e80941Smrg memcpy(buffer, &combined_value, sizeof(GLint64)); 1099b8e80941Smrg break; 1100b8e80941Smrg } 1101b8e80941Smrg 1102b8e80941Smrg case GL_COLOR_COMPONENTS: 1103b8e80941Smrg /* The ARB_internalformat_query2 spec says: 1104b8e80941Smrg * 1105b8e80941Smrg * "- COLOR_COMPONENTS: If the internal format contains any color 1106b8e80941Smrg * components (R, G, B, or A), TRUE is returned in <params>. 1107b8e80941Smrg * If the internal format is unsupported or contains no color 1108b8e80941Smrg * components, FALSE is returned." 1109b8e80941Smrg */ 1110b8e80941Smrg if (_mesa_is_color_format(internalformat)) 1111b8e80941Smrg buffer[0] = GL_TRUE; 1112b8e80941Smrg break; 1113b8e80941Smrg 1114b8e80941Smrg case GL_DEPTH_COMPONENTS: 1115b8e80941Smrg /* The ARB_internalformat_query2 spec says: 1116b8e80941Smrg * 1117b8e80941Smrg * "- DEPTH_COMPONENTS: If the internal format contains a depth 1118b8e80941Smrg * component (D), TRUE is returned in <params>. If the internal format 1119b8e80941Smrg * is unsupported or contains no depth component, FALSE is returned." 1120b8e80941Smrg */ 1121b8e80941Smrg if (_mesa_is_depth_format(internalformat) || 1122b8e80941Smrg _mesa_is_depthstencil_format(internalformat)) 1123b8e80941Smrg buffer[0] = GL_TRUE; 1124b8e80941Smrg break; 1125b8e80941Smrg 1126b8e80941Smrg case GL_STENCIL_COMPONENTS: 1127b8e80941Smrg /* The ARB_internalformat_query2 spec says: 1128848b8605Smrg * 1129b8e80941Smrg * "- STENCIL_COMPONENTS: If the internal format contains a stencil 1130b8e80941Smrg * component (S), TRUE is returned in <params>. If the internal format 1131b8e80941Smrg * is unsupported or contains no stencil component, FALSE is returned. 1132b8e80941Smrg */ 1133b8e80941Smrg if (_mesa_is_stencil_format(internalformat) || 1134b8e80941Smrg _mesa_is_depthstencil_format(internalformat)) 1135b8e80941Smrg buffer[0] = GL_TRUE; 1136b8e80941Smrg break; 1137b8e80941Smrg 1138b8e80941Smrg case GL_COLOR_RENDERABLE: 1139b8e80941Smrg case GL_DEPTH_RENDERABLE: 1140b8e80941Smrg case GL_STENCIL_RENDERABLE: 1141b8e80941Smrg if (!_is_renderable(ctx, internalformat)) 1142b8e80941Smrg goto end; 1143b8e80941Smrg 1144b8e80941Smrg if (pname == GL_COLOR_RENDERABLE) { 1145b8e80941Smrg if (!_mesa_is_color_format(internalformat)) 1146b8e80941Smrg goto end; 1147b8e80941Smrg } else { 1148b8e80941Smrg GLenum baseFormat = _mesa_base_fbo_format(ctx, internalformat); 1149b8e80941Smrg if (baseFormat != GL_DEPTH_STENCIL && 1150b8e80941Smrg ((pname == GL_DEPTH_RENDERABLE && baseFormat != GL_DEPTH_COMPONENT) || 1151b8e80941Smrg (pname == GL_STENCIL_RENDERABLE && baseFormat != GL_STENCIL_INDEX))) 1152b8e80941Smrg goto end; 1153b8e80941Smrg } 1154b8e80941Smrg 1155b8e80941Smrg buffer[0] = GL_TRUE; 1156b8e80941Smrg break; 1157b8e80941Smrg 1158b8e80941Smrg case GL_FRAMEBUFFER_RENDERABLE_LAYERED: 1159b8e80941Smrg if (!_mesa_has_EXT_texture_array(ctx) || 1160b8e80941Smrg _legal_target_for_framebuffer_texture_layer(ctx, target)) 1161b8e80941Smrg goto end; 1162b8e80941Smrg /* fallthrough */ 1163b8e80941Smrg case GL_FRAMEBUFFER_RENDERABLE: 1164b8e80941Smrg case GL_FRAMEBUFFER_BLEND: 1165b8e80941Smrg if (!_mesa_has_ARB_framebuffer_object(ctx)) 1166b8e80941Smrg goto end; 1167b8e80941Smrg 1168b8e80941Smrg if (target == GL_TEXTURE_BUFFER || 1169b8e80941Smrg !_is_renderable(ctx, internalformat)) 1170b8e80941Smrg goto end; 1171b8e80941Smrg 1172b8e80941Smrg ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 1173b8e80941Smrg buffer); 1174b8e80941Smrg break; 1175b8e80941Smrg 1176b8e80941Smrg case GL_READ_PIXELS: 1177b8e80941Smrg case GL_READ_PIXELS_FORMAT: 1178b8e80941Smrg case GL_READ_PIXELS_TYPE: 1179b8e80941Smrg ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 1180b8e80941Smrg buffer); 1181b8e80941Smrg break; 1182b8e80941Smrg 1183b8e80941Smrg case GL_TEXTURE_IMAGE_FORMAT: 1184b8e80941Smrg case GL_GET_TEXTURE_IMAGE_FORMAT: 1185b8e80941Smrg case GL_TEXTURE_IMAGE_TYPE: 1186b8e80941Smrg case GL_GET_TEXTURE_IMAGE_TYPE: 1187b8e80941Smrg ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 1188b8e80941Smrg buffer); 1189b8e80941Smrg break; 1190b8e80941Smrg 1191b8e80941Smrg case GL_MIPMAP: 1192b8e80941Smrg case GL_MANUAL_GENERATE_MIPMAP: 1193b8e80941Smrg case GL_AUTO_GENERATE_MIPMAP: 1194b8e80941Smrg if (!_mesa_is_valid_generate_texture_mipmap_target(ctx, target) || 1195b8e80941Smrg !_mesa_is_valid_generate_texture_mipmap_internalformat(ctx, 1196b8e80941Smrg internalformat)) { 1197b8e80941Smrg goto end; 1198b8e80941Smrg } 1199b8e80941Smrg 1200b8e80941Smrg if (pname == GL_MIPMAP) { 1201b8e80941Smrg buffer[0] = GL_TRUE; 1202b8e80941Smrg goto end; 1203b8e80941Smrg } 1204b8e80941Smrg else if (pname == GL_MANUAL_GENERATE_MIPMAP) { 1205b8e80941Smrg if (!_mesa_has_ARB_framebuffer_object(ctx)) 1206b8e80941Smrg goto end; 1207b8e80941Smrg } 1208b8e80941Smrg else { 1209b8e80941Smrg /* From ARB_internalformat_query2: 1210b8e80941Smrg * "Dependencies on OpenGL 3.2 (Core Profile) 1211b8e80941Smrg * In core profiles for OpenGL 3.2 and later versions, queries 1212b8e80941Smrg * for the AUTO_GENERATE_MIPMAP <pname> return the appropriate 1213b8e80941Smrg * unsupported response." 1214b8e80941Smrg */ 1215b8e80941Smrg if (_mesa_is_desktop_gl(ctx) && ctx->Version >= 32) 1216b8e80941Smrg goto end; 1217b8e80941Smrg } 1218b8e80941Smrg 1219b8e80941Smrg ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 1220b8e80941Smrg buffer); 1221b8e80941Smrg break; 1222b8e80941Smrg 1223b8e80941Smrg case GL_COLOR_ENCODING: 1224b8e80941Smrg if (!_mesa_is_color_format(internalformat)) 1225b8e80941Smrg goto end; 1226b8e80941Smrg 1227b8e80941Smrg if (_mesa_is_srgb_format(internalformat)) 1228b8e80941Smrg buffer[0] = GL_SRGB; 1229b8e80941Smrg else 1230b8e80941Smrg buffer[0] = GL_LINEAR; 1231b8e80941Smrg break; 1232b8e80941Smrg 1233b8e80941Smrg case GL_SRGB_READ: 1234b8e80941Smrg if (!_mesa_has_EXT_texture_sRGB(ctx) || 1235b8e80941Smrg !_mesa_is_srgb_format(internalformat)) { 1236b8e80941Smrg goto end; 1237b8e80941Smrg } 1238b8e80941Smrg 1239b8e80941Smrg ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 1240b8e80941Smrg buffer); 1241b8e80941Smrg break; 1242b8e80941Smrg 1243b8e80941Smrg case GL_SRGB_WRITE: 1244b8e80941Smrg if (!ctx->Extensions.EXT_sRGB || 1245b8e80941Smrg !_mesa_is_color_format(internalformat)) { 1246b8e80941Smrg goto end; 1247b8e80941Smrg } 1248b8e80941Smrg 1249b8e80941Smrg ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 1250b8e80941Smrg buffer); 1251b8e80941Smrg break; 1252b8e80941Smrg 1253b8e80941Smrg case GL_SRGB_DECODE_ARB: 1254b8e80941Smrg /* Presence of EXT_texture_sRGB_decode was already verified */ 1255b8e80941Smrg if (!_mesa_has_EXT_texture_sRGB(ctx) || 1256b8e80941Smrg target == GL_RENDERBUFFER || 1257b8e80941Smrg !_mesa_is_srgb_format(internalformat)) { 1258b8e80941Smrg goto end; 1259b8e80941Smrg } 1260b8e80941Smrg 1261b8e80941Smrg ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 1262b8e80941Smrg buffer); 1263b8e80941Smrg break; 1264b8e80941Smrg 1265b8e80941Smrg case GL_FILTER: 1266b8e80941Smrg /* If it doesn't allow to set sampler parameters then it would not allow 1267b8e80941Smrg * to set a filter different to GL_NEAREST. In practice, this method 1268b8e80941Smrg * only filters out MULTISAMPLE/MULTISAMPLE_ARRAY */ 1269b8e80941Smrg if (!_mesa_target_allows_setting_sampler_parameters(target)) 1270b8e80941Smrg goto end; 1271b8e80941Smrg 1272b8e80941Smrg if (_mesa_is_enum_format_integer(internalformat)) 1273b8e80941Smrg goto end; 1274b8e80941Smrg 1275b8e80941Smrg if (target == GL_TEXTURE_BUFFER) 1276b8e80941Smrg goto end; 1277b8e80941Smrg 1278b8e80941Smrg /* At this point we know that multi-texel filtering is supported. We 1279b8e80941Smrg * need to call the driver to know if it is CAVEAT_SUPPORT or 1280b8e80941Smrg * FULL_SUPPORT. 1281b8e80941Smrg */ 1282b8e80941Smrg ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 1283b8e80941Smrg buffer); 1284b8e80941Smrg break; 1285b8e80941Smrg 1286b8e80941Smrg case GL_VERTEX_TEXTURE: 1287b8e80941Smrg case GL_TESS_CONTROL_TEXTURE: 1288b8e80941Smrg case GL_TESS_EVALUATION_TEXTURE: 1289b8e80941Smrg case GL_GEOMETRY_TEXTURE: 1290b8e80941Smrg case GL_FRAGMENT_TEXTURE: 1291b8e80941Smrg case GL_COMPUTE_TEXTURE: 1292b8e80941Smrg if (target == GL_RENDERBUFFER) 1293b8e80941Smrg goto end; 1294b8e80941Smrg 1295b8e80941Smrg if ((pname == GL_TESS_CONTROL_TEXTURE || 1296b8e80941Smrg pname == GL_TESS_EVALUATION_TEXTURE) && 1297b8e80941Smrg !_mesa_has_tessellation(ctx)) 1298b8e80941Smrg goto end; 1299b8e80941Smrg 1300b8e80941Smrg if (pname == GL_GEOMETRY_TEXTURE && !_mesa_has_geometry_shaders(ctx)) 1301b8e80941Smrg goto end; 1302b8e80941Smrg 1303b8e80941Smrg if (pname == GL_COMPUTE_TEXTURE && !_mesa_has_compute_shaders(ctx)) 1304b8e80941Smrg goto end; 1305b8e80941Smrg 1306b8e80941Smrg ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 1307b8e80941Smrg buffer); 1308b8e80941Smrg break; 1309b8e80941Smrg 1310b8e80941Smrg case GL_TEXTURE_GATHER: 1311b8e80941Smrg case GL_TEXTURE_GATHER_SHADOW: 1312b8e80941Smrg if (!_mesa_has_ARB_texture_gather(ctx)) 1313b8e80941Smrg goto end; 1314b8e80941Smrg 1315b8e80941Smrg /* fallthrough */ 1316b8e80941Smrg case GL_TEXTURE_SHADOW: 1317b8e80941Smrg /* Only depth or depth-stencil image formats make sense in shadow 1318b8e80941Smrg samplers */ 1319b8e80941Smrg if (pname != GL_TEXTURE_GATHER && 1320b8e80941Smrg !_mesa_is_depth_format(internalformat) && 1321b8e80941Smrg !_mesa_is_depthstencil_format(internalformat)) 1322b8e80941Smrg goto end; 1323b8e80941Smrg 1324b8e80941Smrg /* Validate the target for shadow and gather operations */ 1325b8e80941Smrg switch (target) { 1326b8e80941Smrg case GL_TEXTURE_2D: 1327b8e80941Smrg case GL_TEXTURE_2D_ARRAY: 1328b8e80941Smrg case GL_TEXTURE_CUBE_MAP: 1329b8e80941Smrg case GL_TEXTURE_CUBE_MAP_ARRAY: 1330b8e80941Smrg case GL_TEXTURE_RECTANGLE: 1331b8e80941Smrg break; 1332b8e80941Smrg 1333b8e80941Smrg case GL_TEXTURE_1D: 1334b8e80941Smrg case GL_TEXTURE_1D_ARRAY: 1335b8e80941Smrg /* 1D and 1DArray textures are not admitted in gather operations */ 1336b8e80941Smrg if (pname != GL_TEXTURE_SHADOW) 1337b8e80941Smrg goto end; 1338b8e80941Smrg break; 1339b8e80941Smrg 1340b8e80941Smrg default: 1341b8e80941Smrg goto end; 1342b8e80941Smrg } 1343b8e80941Smrg 1344b8e80941Smrg ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 1345b8e80941Smrg buffer); 1346b8e80941Smrg break; 1347b8e80941Smrg 1348b8e80941Smrg case GL_SHADER_IMAGE_LOAD: 1349b8e80941Smrg case GL_SHADER_IMAGE_STORE: 1350b8e80941Smrg if (!_mesa_has_ARB_shader_image_load_store(ctx)) 1351b8e80941Smrg goto end; 1352b8e80941Smrg 1353b8e80941Smrg /* We call to _mesa_is_shader_image_format_supported 1354b8e80941Smrg * using "internalformat" as parameter, because the 1355b8e80941Smrg * the ARB_internalformat_query2 spec says: 1356b8e80941Smrg * "In this case the <internalformat> is the value of the <format> 1357b8e80941Smrg * parameter that is passed to BindImageTexture." 1358b8e80941Smrg */ 1359b8e80941Smrg if (target == GL_RENDERBUFFER || 1360b8e80941Smrg !_mesa_is_shader_image_format_supported(ctx, internalformat)) 1361b8e80941Smrg goto end; 1362b8e80941Smrg 1363b8e80941Smrg ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 1364b8e80941Smrg buffer); 1365b8e80941Smrg break; 1366b8e80941Smrg 1367b8e80941Smrg case GL_SHADER_IMAGE_ATOMIC: 1368b8e80941Smrg if (!_mesa_has_ARB_shader_image_load_store(ctx)) 1369b8e80941Smrg goto end; 1370b8e80941Smrg 1371b8e80941Smrg ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 1372b8e80941Smrg buffer); 1373b8e80941Smrg break; 1374b8e80941Smrg 1375b8e80941Smrg case GL_IMAGE_TEXEL_SIZE: { 1376b8e80941Smrg mesa_format image_format; 1377b8e80941Smrg 1378b8e80941Smrg if (!_mesa_has_ARB_shader_image_load_store(ctx) || 1379b8e80941Smrg target == GL_RENDERBUFFER) 1380b8e80941Smrg goto end; 1381b8e80941Smrg 1382b8e80941Smrg image_format = _mesa_get_shader_image_format(internalformat); 1383b8e80941Smrg if (image_format == MESA_FORMAT_NONE) 1384b8e80941Smrg goto end; 1385b8e80941Smrg 1386b8e80941Smrg /* We return bits */ 1387b8e80941Smrg buffer[0] = (_mesa_get_format_bytes(image_format) * 8); 1388b8e80941Smrg break; 1389b8e80941Smrg } 1390b8e80941Smrg 1391b8e80941Smrg case GL_IMAGE_COMPATIBILITY_CLASS: 1392b8e80941Smrg if (!_mesa_has_ARB_shader_image_load_store(ctx) || 1393b8e80941Smrg target == GL_RENDERBUFFER) 1394b8e80941Smrg goto end; 1395b8e80941Smrg 1396b8e80941Smrg buffer[0] = _mesa_get_image_format_class(internalformat); 1397b8e80941Smrg break; 1398b8e80941Smrg 1399b8e80941Smrg case GL_IMAGE_PIXEL_FORMAT: { 1400b8e80941Smrg GLint base_format; 1401b8e80941Smrg 1402b8e80941Smrg if (!_mesa_has_ARB_shader_image_load_store(ctx) || 1403b8e80941Smrg target == GL_RENDERBUFFER || 1404b8e80941Smrg !_mesa_is_shader_image_format_supported(ctx, internalformat)) 1405b8e80941Smrg goto end; 1406b8e80941Smrg 1407b8e80941Smrg base_format = _mesa_base_tex_format(ctx, internalformat); 1408b8e80941Smrg if (base_format == -1) 1409b8e80941Smrg goto end; 1410b8e80941Smrg 1411b8e80941Smrg if (_mesa_is_enum_format_integer(internalformat)) 1412b8e80941Smrg buffer[0] = _mesa_base_format_to_integer_format(base_format); 1413b8e80941Smrg else 1414b8e80941Smrg buffer[0] = base_format; 1415b8e80941Smrg break; 1416b8e80941Smrg } 1417b8e80941Smrg 1418b8e80941Smrg case GL_IMAGE_PIXEL_TYPE: { 1419b8e80941Smrg mesa_format image_format; 1420b8e80941Smrg GLenum datatype; 1421b8e80941Smrg GLuint comps; 1422b8e80941Smrg 1423b8e80941Smrg if (!_mesa_has_ARB_shader_image_load_store(ctx) || 1424b8e80941Smrg target == GL_RENDERBUFFER) 1425b8e80941Smrg goto end; 1426b8e80941Smrg 1427b8e80941Smrg image_format = _mesa_get_shader_image_format(internalformat); 1428b8e80941Smrg if (image_format == MESA_FORMAT_NONE) 1429b8e80941Smrg goto end; 1430b8e80941Smrg 1431b8e80941Smrg _mesa_uncompressed_format_to_type_and_comps(image_format, &datatype, 1432b8e80941Smrg &comps); 1433b8e80941Smrg if (!datatype) 1434b8e80941Smrg goto end; 1435b8e80941Smrg 1436b8e80941Smrg buffer[0] = datatype; 1437b8e80941Smrg break; 1438b8e80941Smrg } 1439b8e80941Smrg 1440b8e80941Smrg case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE: { 1441b8e80941Smrg if (!_mesa_has_ARB_shader_image_load_store(ctx)) 1442b8e80941Smrg goto end; 1443b8e80941Smrg 1444b8e80941Smrg /* As pointed by the spec quote below, this pname query should return 1445b8e80941Smrg * the same value that GetTexParameter. So if the target is not valid 1446b8e80941Smrg * for GetTexParameter we return the unsupported value. The check below 1447b8e80941Smrg * is the same target check used by GetTexParameter. 1448848b8605Smrg */ 1449b8e80941Smrg int targetIndex = _mesa_tex_target_to_index(ctx, target); 1450b8e80941Smrg if (targetIndex < 0 || targetIndex == TEXTURE_BUFFER_INDEX) 1451b8e80941Smrg goto end; 1452848b8605Smrg 1453b8e80941Smrg /* From spec: "Equivalent to calling GetTexParameter with <value> set 1454b8e80941Smrg * to IMAGE_FORMAT_COMPATIBILITY_TYPE." 1455b8e80941Smrg * 1456b8e80941Smrg * GetTexParameter just returns 1457b8e80941Smrg * tex_obj->ImageFormatCompatibilityType. We create a fake tex_obj 1458b8e80941Smrg * just with the purpose of getting the value. 1459848b8605Smrg */ 1460b8e80941Smrg struct gl_texture_object *tex_obj = _mesa_new_texture_object(ctx, 0, target); 1461b8e80941Smrg buffer[0] = tex_obj->ImageFormatCompatibilityType; 1462b8e80941Smrg _mesa_delete_texture_object(ctx, tex_obj); 1463b8e80941Smrg 1464b8e80941Smrg break; 1465b8e80941Smrg } 1466b8e80941Smrg 1467b8e80941Smrg case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST: 1468b8e80941Smrg case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST: 1469b8e80941Smrg case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE: 1470b8e80941Smrg case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE: 1471b8e80941Smrg if (target == GL_RENDERBUFFER) 1472b8e80941Smrg goto end; 1473b8e80941Smrg 1474b8e80941Smrg if (!_mesa_is_depthstencil_format(internalformat)) { 1475b8e80941Smrg if (((pname == GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST || 1476b8e80941Smrg pname == GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE) && 1477b8e80941Smrg !_mesa_is_depth_format(internalformat)) || 1478b8e80941Smrg ((pname == GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST || 1479b8e80941Smrg pname == GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE) && 1480b8e80941Smrg !_mesa_is_stencil_format(internalformat))) 1481b8e80941Smrg goto end; 1482b8e80941Smrg } 1483b8e80941Smrg 1484b8e80941Smrg ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 1485b8e80941Smrg buffer); 1486b8e80941Smrg break; 1487b8e80941Smrg 1488b8e80941Smrg case GL_TEXTURE_COMPRESSED: 1489b8e80941Smrg buffer[0] = _mesa_is_compressed_format(ctx, internalformat); 1490b8e80941Smrg break; 1491b8e80941Smrg 1492b8e80941Smrg case GL_TEXTURE_COMPRESSED_BLOCK_WIDTH: 1493b8e80941Smrg case GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT: 1494b8e80941Smrg case GL_TEXTURE_COMPRESSED_BLOCK_SIZE: { 1495b8e80941Smrg mesa_format mesaformat; 1496b8e80941Smrg GLint block_size; 1497b8e80941Smrg 1498b8e80941Smrg mesaformat = _mesa_glenum_to_compressed_format(internalformat); 1499b8e80941Smrg if (mesaformat == MESA_FORMAT_NONE) 1500b8e80941Smrg goto end; 1501b8e80941Smrg 1502b8e80941Smrg block_size = _mesa_get_format_bytes(mesaformat); 1503b8e80941Smrg assert(block_size > 0); 1504b8e80941Smrg 1505b8e80941Smrg if (pname == GL_TEXTURE_COMPRESSED_BLOCK_SIZE) { 1506b8e80941Smrg buffer[0] = block_size; 1507b8e80941Smrg } else { 1508b8e80941Smrg GLuint bwidth, bheight; 1509b8e80941Smrg 1510b8e80941Smrg /* Returns the width and height in pixels. We return bytes */ 1511b8e80941Smrg _mesa_get_format_block_size(mesaformat, &bwidth, &bheight); 1512b8e80941Smrg assert(bwidth > 0 && bheight > 0); 1513b8e80941Smrg 1514b8e80941Smrg if (pname == GL_TEXTURE_COMPRESSED_BLOCK_WIDTH) 1515b8e80941Smrg buffer[0] = block_size / bheight; 1516b8e80941Smrg else 1517b8e80941Smrg buffer[0] = block_size / bwidth; 1518b8e80941Smrg } 1519848b8605Smrg break; 1520848b8605Smrg } 1521b8e80941Smrg 1522b8e80941Smrg case GL_CLEAR_BUFFER: 1523b8e80941Smrg if (target != GL_TEXTURE_BUFFER) 1524b8e80941Smrg goto end; 1525b8e80941Smrg 1526b8e80941Smrg ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 1527b8e80941Smrg buffer); 1528b8e80941Smrg break; 1529b8e80941Smrg 1530b8e80941Smrg case GL_TEXTURE_VIEW: 1531b8e80941Smrg case GL_VIEW_COMPATIBILITY_CLASS: 1532b8e80941Smrg if (!_mesa_has_ARB_texture_view(ctx) || 1533b8e80941Smrg target == GL_TEXTURE_BUFFER || 1534b8e80941Smrg target == GL_RENDERBUFFER) 1535b8e80941Smrg goto end; 1536b8e80941Smrg 1537b8e80941Smrg if (pname == GL_TEXTURE_VIEW) { 1538b8e80941Smrg ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 1539b8e80941Smrg buffer); 1540b8e80941Smrg } else { 1541b8e80941Smrg GLenum view_class = _mesa_texture_view_lookup_view_class(ctx, 1542b8e80941Smrg internalformat); 1543b8e80941Smrg if (view_class == GL_FALSE) 1544b8e80941Smrg goto end; 1545b8e80941Smrg 1546b8e80941Smrg buffer[0] = view_class; 1547b8e80941Smrg } 1548b8e80941Smrg break; 1549b8e80941Smrg 1550b8e80941Smrg case GL_NUM_TILING_TYPES_EXT: 1551b8e80941Smrg case GL_TILING_TYPES_EXT: 1552b8e80941Smrg ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 1553b8e80941Smrg buffer); 1554b8e80941Smrg break; 1555b8e80941Smrg 1556848b8605Smrg default: 1557b8e80941Smrg unreachable("bad param"); 1558848b8605Smrg } 1559848b8605Smrg 1560b8e80941Smrg end: 1561848b8605Smrg if (bufSize != 0 && params == NULL) { 1562848b8605Smrg /* Emit a warning to aid application debugging, but go ahead and do the 1563848b8605Smrg * memcpy (and probably crash) anyway. 1564848b8605Smrg */ 1565848b8605Smrg _mesa_warning(ctx, 1566848b8605Smrg "glGetInternalformativ(bufSize = %d, but params = NULL)", 1567848b8605Smrg bufSize); 1568848b8605Smrg } 1569848b8605Smrg 1570848b8605Smrg /* Copy the data from the temporary buffer to the buffer supplied by the 1571848b8605Smrg * application. Clamp the size of the copy to the size supplied by the 1572848b8605Smrg * application. 1573848b8605Smrg */ 1574b8e80941Smrg memcpy(params, buffer, MIN2(bufSize, 16) * sizeof(GLint)); 1575848b8605Smrg 1576848b8605Smrg return; 1577848b8605Smrg} 1578b8e80941Smrg 1579b8e80941Smrgvoid GLAPIENTRY 1580b8e80941Smrg_mesa_GetInternalformati64v(GLenum target, GLenum internalformat, 1581b8e80941Smrg GLenum pname, GLsizei bufSize, GLint64 *params) 1582b8e80941Smrg{ 1583b8e80941Smrg GLint params32[16]; 1584b8e80941Smrg unsigned i; 1585b8e80941Smrg GLsizei realSize = MIN2(bufSize, 16); 1586b8e80941Smrg GLsizei callSize; 1587b8e80941Smrg 1588b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 1589b8e80941Smrg 1590b8e80941Smrg ASSERT_OUTSIDE_BEGIN_END(ctx); 1591b8e80941Smrg 1592b8e80941Smrg if (!_mesa_has_ARB_internalformat_query2(ctx)) { 1593b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInternalformati64v"); 1594b8e80941Smrg return; 1595b8e80941Smrg } 1596b8e80941Smrg 1597b8e80941Smrg /* For SAMPLES there are cases where params needs to remain unmodified. As 1598b8e80941Smrg * no pname can return a negative value, we fill params32 with negative 1599b8e80941Smrg * values as reference values, that can be used to know what copy-back to 1600b8e80941Smrg * params */ 1601b8e80941Smrg for (i = 0; i < realSize; i++) 1602b8e80941Smrg params32[i] = -1; 1603b8e80941Smrg 1604b8e80941Smrg /* For GL_MAX_COMBINED_DIMENSIONS we need to get back 2 32-bit integers, 1605b8e80941Smrg * and at the same time we only need 2. So for that pname, we call the 1606b8e80941Smrg * 32-bit query with bufSize 2, except on the case of bufSize 0, that is 1607b8e80941Smrg * basically like asking to not get the value, but that is a caller 1608b8e80941Smrg * problem. */ 1609b8e80941Smrg if (pname == GL_MAX_COMBINED_DIMENSIONS && bufSize > 0) 1610b8e80941Smrg callSize = 2; 1611b8e80941Smrg else 1612b8e80941Smrg callSize = bufSize; 1613b8e80941Smrg 1614b8e80941Smrg _mesa_GetInternalformativ(target, internalformat, pname, callSize, params32); 1615b8e80941Smrg 1616b8e80941Smrg if (pname == GL_MAX_COMBINED_DIMENSIONS) { 1617b8e80941Smrg memcpy(params, params32, sizeof(GLint64)); 1618b8e80941Smrg } else { 1619b8e80941Smrg for (i = 0; i < realSize; i++) { 1620b8e80941Smrg /* We only copy back the values that changed */ 1621b8e80941Smrg if (params32[i] < 0) 1622b8e80941Smrg break; 1623b8e80941Smrg params[i] = (GLint64) params32[i]; 1624b8e80941Smrg } 1625b8e80941Smrg } 1626b8e80941Smrg} 1627