1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Mesa 3-D graphics library 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5bf215546Sopenharmony_ci * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 6bf215546Sopenharmony_ci * 7bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 8bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 9bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 10bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 12bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included 15bf215546Sopenharmony_ci * in all copies or substantial portions of the Software. 16bf215546Sopenharmony_ci * 17bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21bf215546Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22bf215546Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23bf215546Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 24bf215546Sopenharmony_ci */ 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ci/** 28bf215546Sopenharmony_ci * \file teximage.c 29bf215546Sopenharmony_ci * Texture image-related functions. 30bf215546Sopenharmony_ci */ 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ci#include <stdbool.h> 33bf215546Sopenharmony_ci#include "glheader.h" 34bf215546Sopenharmony_ci#include "bufferobj.h" 35bf215546Sopenharmony_ci#include "context.h" 36bf215546Sopenharmony_ci#include "enums.h" 37bf215546Sopenharmony_ci#include "fbobject.h" 38bf215546Sopenharmony_ci#include "framebuffer.h" 39bf215546Sopenharmony_ci#include "hash.h" 40bf215546Sopenharmony_ci#include "image.h" 41bf215546Sopenharmony_ci 42bf215546Sopenharmony_ci#include "macros.h" 43bf215546Sopenharmony_ci#include "mipmap.h" 44bf215546Sopenharmony_ci#include "multisample.h" 45bf215546Sopenharmony_ci#include "pixel.h" 46bf215546Sopenharmony_ci#include "pixelstore.h" 47bf215546Sopenharmony_ci#include "state.h" 48bf215546Sopenharmony_ci#include "texcompress.h" 49bf215546Sopenharmony_ci#include "texcompress_cpal.h" 50bf215546Sopenharmony_ci#include "teximage.h" 51bf215546Sopenharmony_ci#include "texobj.h" 52bf215546Sopenharmony_ci#include "texstate.h" 53bf215546Sopenharmony_ci#include "texstorage.h" 54bf215546Sopenharmony_ci#include "textureview.h" 55bf215546Sopenharmony_ci#include "mtypes.h" 56bf215546Sopenharmony_ci#include "glformats.h" 57bf215546Sopenharmony_ci#include "texstore.h" 58bf215546Sopenharmony_ci#include "pbo.h" 59bf215546Sopenharmony_ci#include "api_exec_decl.h" 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_ci#include "util/u_memory.h" 62bf215546Sopenharmony_ci 63bf215546Sopenharmony_ci#include "state_tracker/st_cb_texture.h" 64bf215546Sopenharmony_ci#include "state_tracker/st_context.h" 65bf215546Sopenharmony_ci#include "state_tracker/st_format.h" 66bf215546Sopenharmony_ci#include "state_tracker/st_gen_mipmap.h" 67bf215546Sopenharmony_ci#include "state_tracker/st_cb_eglimage.h" 68bf215546Sopenharmony_ci#include "state_tracker/st_sampler_view.h" 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_ci/** 71bf215546Sopenharmony_ci * Returns a corresponding internal floating point format for a given base 72bf215546Sopenharmony_ci * format as specifed by OES_texture_float. In case of GL_FLOAT, the internal 73bf215546Sopenharmony_ci * format needs to be a 32 bit component and in case of GL_HALF_FLOAT_OES it 74bf215546Sopenharmony_ci * needs to be a 16 bit component. 75bf215546Sopenharmony_ci * 76bf215546Sopenharmony_ci * For example, given base format GL_RGBA, type GL_FLOAT return GL_RGBA32F_ARB. 77bf215546Sopenharmony_ci */ 78bf215546Sopenharmony_cistatic GLenum 79bf215546Sopenharmony_ciadjust_for_oes_float_texture(const struct gl_context *ctx, 80bf215546Sopenharmony_ci GLenum format, GLenum type) 81bf215546Sopenharmony_ci{ 82bf215546Sopenharmony_ci switch (type) { 83bf215546Sopenharmony_ci case GL_FLOAT: 84bf215546Sopenharmony_ci if (ctx->Extensions.OES_texture_float) { 85bf215546Sopenharmony_ci switch (format) { 86bf215546Sopenharmony_ci case GL_RGBA: 87bf215546Sopenharmony_ci return GL_RGBA32F; 88bf215546Sopenharmony_ci case GL_RGB: 89bf215546Sopenharmony_ci return GL_RGB32F; 90bf215546Sopenharmony_ci case GL_ALPHA: 91bf215546Sopenharmony_ci return GL_ALPHA32F_ARB; 92bf215546Sopenharmony_ci case GL_LUMINANCE: 93bf215546Sopenharmony_ci return GL_LUMINANCE32F_ARB; 94bf215546Sopenharmony_ci case GL_LUMINANCE_ALPHA: 95bf215546Sopenharmony_ci return GL_LUMINANCE_ALPHA32F_ARB; 96bf215546Sopenharmony_ci default: 97bf215546Sopenharmony_ci break; 98bf215546Sopenharmony_ci } 99bf215546Sopenharmony_ci } 100bf215546Sopenharmony_ci break; 101bf215546Sopenharmony_ci 102bf215546Sopenharmony_ci case GL_HALF_FLOAT_OES: 103bf215546Sopenharmony_ci if (ctx->Extensions.OES_texture_half_float) { 104bf215546Sopenharmony_ci switch (format) { 105bf215546Sopenharmony_ci case GL_RGBA: 106bf215546Sopenharmony_ci return GL_RGBA16F; 107bf215546Sopenharmony_ci case GL_RGB: 108bf215546Sopenharmony_ci return GL_RGB16F; 109bf215546Sopenharmony_ci case GL_ALPHA: 110bf215546Sopenharmony_ci return GL_ALPHA16F_ARB; 111bf215546Sopenharmony_ci case GL_LUMINANCE: 112bf215546Sopenharmony_ci return GL_LUMINANCE16F_ARB; 113bf215546Sopenharmony_ci case GL_LUMINANCE_ALPHA: 114bf215546Sopenharmony_ci return GL_LUMINANCE_ALPHA16F_ARB; 115bf215546Sopenharmony_ci default: 116bf215546Sopenharmony_ci break; 117bf215546Sopenharmony_ci } 118bf215546Sopenharmony_ci } 119bf215546Sopenharmony_ci break; 120bf215546Sopenharmony_ci 121bf215546Sopenharmony_ci default: 122bf215546Sopenharmony_ci break; 123bf215546Sopenharmony_ci } 124bf215546Sopenharmony_ci 125bf215546Sopenharmony_ci return format; 126bf215546Sopenharmony_ci} 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_ci/** 129bf215546Sopenharmony_ci * Returns a corresponding base format for a given internal floating point 130bf215546Sopenharmony_ci * format as specifed by OES_texture_float. 131bf215546Sopenharmony_ci */ 132bf215546Sopenharmony_cistatic GLenum 133bf215546Sopenharmony_cioes_float_internal_format(const struct gl_context *ctx, 134bf215546Sopenharmony_ci GLenum format, GLenum type) 135bf215546Sopenharmony_ci{ 136bf215546Sopenharmony_ci switch (type) { 137bf215546Sopenharmony_ci case GL_FLOAT: 138bf215546Sopenharmony_ci if (ctx->Extensions.OES_texture_float) { 139bf215546Sopenharmony_ci switch (format) { 140bf215546Sopenharmony_ci case GL_RGBA32F: 141bf215546Sopenharmony_ci return GL_RGBA; 142bf215546Sopenharmony_ci case GL_RGB32F: 143bf215546Sopenharmony_ci return GL_RGB; 144bf215546Sopenharmony_ci case GL_ALPHA32F_ARB: 145bf215546Sopenharmony_ci return GL_ALPHA; 146bf215546Sopenharmony_ci case GL_LUMINANCE32F_ARB: 147bf215546Sopenharmony_ci return GL_LUMINANCE; 148bf215546Sopenharmony_ci case GL_LUMINANCE_ALPHA32F_ARB: 149bf215546Sopenharmony_ci return GL_LUMINANCE_ALPHA; 150bf215546Sopenharmony_ci default: 151bf215546Sopenharmony_ci break; 152bf215546Sopenharmony_ci } 153bf215546Sopenharmony_ci } 154bf215546Sopenharmony_ci break; 155bf215546Sopenharmony_ci 156bf215546Sopenharmony_ci case GL_HALF_FLOAT_OES: 157bf215546Sopenharmony_ci if (ctx->Extensions.OES_texture_half_float) { 158bf215546Sopenharmony_ci switch (format) { 159bf215546Sopenharmony_ci case GL_RGBA16F: 160bf215546Sopenharmony_ci return GL_RGBA; 161bf215546Sopenharmony_ci case GL_RGB16F: 162bf215546Sopenharmony_ci return GL_RGB; 163bf215546Sopenharmony_ci case GL_ALPHA16F_ARB: 164bf215546Sopenharmony_ci return GL_ALPHA; 165bf215546Sopenharmony_ci case GL_LUMINANCE16F_ARB: 166bf215546Sopenharmony_ci return GL_LUMINANCE; 167bf215546Sopenharmony_ci case GL_LUMINANCE_ALPHA16F_ARB: 168bf215546Sopenharmony_ci return GL_LUMINANCE_ALPHA; 169bf215546Sopenharmony_ci default: 170bf215546Sopenharmony_ci break; 171bf215546Sopenharmony_ci } 172bf215546Sopenharmony_ci } 173bf215546Sopenharmony_ci break; 174bf215546Sopenharmony_ci } 175bf215546Sopenharmony_ci return format; 176bf215546Sopenharmony_ci} 177bf215546Sopenharmony_ci 178bf215546Sopenharmony_ci 179bf215546Sopenharmony_ci/** 180bf215546Sopenharmony_ci * Install gl_texture_image in a gl_texture_object according to the target 181bf215546Sopenharmony_ci * and level parameters. 182bf215546Sopenharmony_ci * 183bf215546Sopenharmony_ci * \param tObj texture object. 184bf215546Sopenharmony_ci * \param target texture target. 185bf215546Sopenharmony_ci * \param level image level. 186bf215546Sopenharmony_ci * \param texImage texture image. 187bf215546Sopenharmony_ci */ 188bf215546Sopenharmony_cistatic void 189bf215546Sopenharmony_ciset_tex_image(struct gl_texture_object *tObj, 190bf215546Sopenharmony_ci GLenum target, GLint level, 191bf215546Sopenharmony_ci struct gl_texture_image *texImage) 192bf215546Sopenharmony_ci{ 193bf215546Sopenharmony_ci const GLuint face = _mesa_tex_target_to_face(target); 194bf215546Sopenharmony_ci 195bf215546Sopenharmony_ci assert(tObj); 196bf215546Sopenharmony_ci assert(texImage); 197bf215546Sopenharmony_ci if (target == GL_TEXTURE_RECTANGLE_NV || target == GL_TEXTURE_EXTERNAL_OES) 198bf215546Sopenharmony_ci assert(level == 0); 199bf215546Sopenharmony_ci 200bf215546Sopenharmony_ci tObj->Image[face][level] = texImage; 201bf215546Sopenharmony_ci 202bf215546Sopenharmony_ci /* Set the 'back' pointer */ 203bf215546Sopenharmony_ci texImage->TexObject = tObj; 204bf215546Sopenharmony_ci texImage->Level = level; 205bf215546Sopenharmony_ci texImage->Face = face; 206bf215546Sopenharmony_ci} 207bf215546Sopenharmony_ci 208bf215546Sopenharmony_ci 209bf215546Sopenharmony_ci/** 210bf215546Sopenharmony_ci * Free a gl_texture_image and associated data. 211bf215546Sopenharmony_ci * This function is a fallback. 212bf215546Sopenharmony_ci * 213bf215546Sopenharmony_ci * \param texImage texture image. 214bf215546Sopenharmony_ci * 215bf215546Sopenharmony_ci * Free the texture image structure and the associated image data. 216bf215546Sopenharmony_ci */ 217bf215546Sopenharmony_civoid 218bf215546Sopenharmony_ci_mesa_delete_texture_image(struct gl_context *ctx, 219bf215546Sopenharmony_ci struct gl_texture_image *texImage) 220bf215546Sopenharmony_ci{ 221bf215546Sopenharmony_ci /* Free texImage->Data and/or any other driver-specific texture 222bf215546Sopenharmony_ci * image storage. 223bf215546Sopenharmony_ci */ 224bf215546Sopenharmony_ci st_FreeTextureImageBuffer( ctx, texImage ); 225bf215546Sopenharmony_ci FREE(texImage); 226bf215546Sopenharmony_ci} 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci 229bf215546Sopenharmony_ci/** 230bf215546Sopenharmony_ci * Test if a target is a proxy target. 231bf215546Sopenharmony_ci * 232bf215546Sopenharmony_ci * \param target texture target. 233bf215546Sopenharmony_ci * 234bf215546Sopenharmony_ci * \return GL_TRUE if the target is a proxy target, GL_FALSE otherwise. 235bf215546Sopenharmony_ci */ 236bf215546Sopenharmony_ciGLboolean 237bf215546Sopenharmony_ci_mesa_is_proxy_texture(GLenum target) 238bf215546Sopenharmony_ci{ 239bf215546Sopenharmony_ci unsigned i; 240bf215546Sopenharmony_ci static const GLenum targets[] = { 241bf215546Sopenharmony_ci GL_PROXY_TEXTURE_1D, 242bf215546Sopenharmony_ci GL_PROXY_TEXTURE_2D, 243bf215546Sopenharmony_ci GL_PROXY_TEXTURE_3D, 244bf215546Sopenharmony_ci GL_PROXY_TEXTURE_CUBE_MAP, 245bf215546Sopenharmony_ci GL_PROXY_TEXTURE_RECTANGLE, 246bf215546Sopenharmony_ci GL_PROXY_TEXTURE_1D_ARRAY, 247bf215546Sopenharmony_ci GL_PROXY_TEXTURE_2D_ARRAY, 248bf215546Sopenharmony_ci GL_PROXY_TEXTURE_CUBE_MAP_ARRAY, 249bf215546Sopenharmony_ci GL_PROXY_TEXTURE_2D_MULTISAMPLE, 250bf215546Sopenharmony_ci GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 251bf215546Sopenharmony_ci }; 252bf215546Sopenharmony_ci /* 253bf215546Sopenharmony_ci * NUM_TEXTURE_TARGETS should match number of terms above, except there's no 254bf215546Sopenharmony_ci * proxy for GL_TEXTURE_BUFFER and GL_TEXTURE_EXTERNAL_OES. 255bf215546Sopenharmony_ci */ 256bf215546Sopenharmony_ci STATIC_ASSERT(NUM_TEXTURE_TARGETS == ARRAY_SIZE(targets) + 2); 257bf215546Sopenharmony_ci 258bf215546Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(targets); ++i) 259bf215546Sopenharmony_ci if (target == targets[i]) 260bf215546Sopenharmony_ci return GL_TRUE; 261bf215546Sopenharmony_ci return GL_FALSE; 262bf215546Sopenharmony_ci} 263bf215546Sopenharmony_ci 264bf215546Sopenharmony_ci 265bf215546Sopenharmony_ci/** 266bf215546Sopenharmony_ci * Test if a target is an array target. 267bf215546Sopenharmony_ci * 268bf215546Sopenharmony_ci * \param target texture target. 269bf215546Sopenharmony_ci * 270bf215546Sopenharmony_ci * \return true if the target is an array target, false otherwise. 271bf215546Sopenharmony_ci */ 272bf215546Sopenharmony_cibool 273bf215546Sopenharmony_ci_mesa_is_array_texture(GLenum target) 274bf215546Sopenharmony_ci{ 275bf215546Sopenharmony_ci switch (target) { 276bf215546Sopenharmony_ci case GL_TEXTURE_1D_ARRAY: 277bf215546Sopenharmony_ci case GL_TEXTURE_2D_ARRAY: 278bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_ARRAY: 279bf215546Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 280bf215546Sopenharmony_ci return true; 281bf215546Sopenharmony_ci default: 282bf215546Sopenharmony_ci return false; 283bf215546Sopenharmony_ci }; 284bf215546Sopenharmony_ci} 285bf215546Sopenharmony_ci 286bf215546Sopenharmony_ci/** 287bf215546Sopenharmony_ci * Test if a target is a cube map. 288bf215546Sopenharmony_ci * 289bf215546Sopenharmony_ci * \param target texture target. 290bf215546Sopenharmony_ci * 291bf215546Sopenharmony_ci * \return true if the target is a cube map, false otherwise. 292bf215546Sopenharmony_ci */ 293bf215546Sopenharmony_cibool 294bf215546Sopenharmony_ci_mesa_is_cube_map_texture(GLenum target) 295bf215546Sopenharmony_ci{ 296bf215546Sopenharmony_ci switch(target) { 297bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP: 298bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_ARRAY: 299bf215546Sopenharmony_ci return true; 300bf215546Sopenharmony_ci default: 301bf215546Sopenharmony_ci return false; 302bf215546Sopenharmony_ci } 303bf215546Sopenharmony_ci} 304bf215546Sopenharmony_ci 305bf215546Sopenharmony_ci/** 306bf215546Sopenharmony_ci * Return the proxy target which corresponds to the given texture target 307bf215546Sopenharmony_ci */ 308bf215546Sopenharmony_cistatic GLenum 309bf215546Sopenharmony_ciproxy_target(GLenum target) 310bf215546Sopenharmony_ci{ 311bf215546Sopenharmony_ci switch (target) { 312bf215546Sopenharmony_ci case GL_TEXTURE_1D: 313bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_1D: 314bf215546Sopenharmony_ci return GL_PROXY_TEXTURE_1D; 315bf215546Sopenharmony_ci case GL_TEXTURE_2D: 316bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D: 317bf215546Sopenharmony_ci return GL_PROXY_TEXTURE_2D; 318bf215546Sopenharmony_ci case GL_TEXTURE_3D: 319bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_3D: 320bf215546Sopenharmony_ci return GL_PROXY_TEXTURE_3D; 321bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 322bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 323bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 324bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 325bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 326bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 327bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP: 328bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_CUBE_MAP: 329bf215546Sopenharmony_ci return GL_PROXY_TEXTURE_CUBE_MAP; 330bf215546Sopenharmony_ci case GL_TEXTURE_RECTANGLE_NV: 331bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_RECTANGLE_NV: 332bf215546Sopenharmony_ci return GL_PROXY_TEXTURE_RECTANGLE_NV; 333bf215546Sopenharmony_ci case GL_TEXTURE_1D_ARRAY_EXT: 334bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 335bf215546Sopenharmony_ci return GL_PROXY_TEXTURE_1D_ARRAY_EXT; 336bf215546Sopenharmony_ci case GL_TEXTURE_2D_ARRAY_EXT: 337bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 338bf215546Sopenharmony_ci return GL_PROXY_TEXTURE_2D_ARRAY_EXT; 339bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_ARRAY: 340bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 341bf215546Sopenharmony_ci return GL_PROXY_TEXTURE_CUBE_MAP_ARRAY; 342bf215546Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE: 343bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 344bf215546Sopenharmony_ci return GL_PROXY_TEXTURE_2D_MULTISAMPLE; 345bf215546Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 346bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 347bf215546Sopenharmony_ci return GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY; 348bf215546Sopenharmony_ci default: 349bf215546Sopenharmony_ci _mesa_problem(NULL, "unexpected target in proxy_target()"); 350bf215546Sopenharmony_ci return 0; 351bf215546Sopenharmony_ci } 352bf215546Sopenharmony_ci} 353bf215546Sopenharmony_ci 354bf215546Sopenharmony_ci 355bf215546Sopenharmony_ci 356bf215546Sopenharmony_ci 357bf215546Sopenharmony_ci/** 358bf215546Sopenharmony_ci * Get a texture image pointer from a texture object, given a texture 359bf215546Sopenharmony_ci * target and mipmap level. The target and level parameters should 360bf215546Sopenharmony_ci * have already been error-checked. 361bf215546Sopenharmony_ci * 362bf215546Sopenharmony_ci * \param texObj texture unit. 363bf215546Sopenharmony_ci * \param target texture target. 364bf215546Sopenharmony_ci * \param level image level. 365bf215546Sopenharmony_ci * 366bf215546Sopenharmony_ci * \return pointer to the texture image structure, or NULL on failure. 367bf215546Sopenharmony_ci */ 368bf215546Sopenharmony_cistruct gl_texture_image * 369bf215546Sopenharmony_ci_mesa_select_tex_image(const struct gl_texture_object *texObj, 370bf215546Sopenharmony_ci GLenum target, GLint level) 371bf215546Sopenharmony_ci{ 372bf215546Sopenharmony_ci const GLuint face = _mesa_tex_target_to_face(target); 373bf215546Sopenharmony_ci 374bf215546Sopenharmony_ci assert(texObj); 375bf215546Sopenharmony_ci assert(level >= 0); 376bf215546Sopenharmony_ci assert(level < MAX_TEXTURE_LEVELS); 377bf215546Sopenharmony_ci 378bf215546Sopenharmony_ci return texObj->Image[face][level]; 379bf215546Sopenharmony_ci} 380bf215546Sopenharmony_ci 381bf215546Sopenharmony_ci 382bf215546Sopenharmony_ci/** 383bf215546Sopenharmony_ci * Like _mesa_select_tex_image() but if the image doesn't exist, allocate 384bf215546Sopenharmony_ci * it and install it. Only return NULL if passed a bad parameter or run 385bf215546Sopenharmony_ci * out of memory. 386bf215546Sopenharmony_ci */ 387bf215546Sopenharmony_cistruct gl_texture_image * 388bf215546Sopenharmony_ci_mesa_get_tex_image(struct gl_context *ctx, struct gl_texture_object *texObj, 389bf215546Sopenharmony_ci GLenum target, GLint level) 390bf215546Sopenharmony_ci{ 391bf215546Sopenharmony_ci struct gl_texture_image *texImage; 392bf215546Sopenharmony_ci 393bf215546Sopenharmony_ci if (!texObj) 394bf215546Sopenharmony_ci return NULL; 395bf215546Sopenharmony_ci 396bf215546Sopenharmony_ci texImage = _mesa_select_tex_image(texObj, target, level); 397bf215546Sopenharmony_ci if (!texImage) { 398bf215546Sopenharmony_ci texImage = CALLOC_STRUCT(gl_texture_image); 399bf215546Sopenharmony_ci if (!texImage) { 400bf215546Sopenharmony_ci _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture image allocation"); 401bf215546Sopenharmony_ci return NULL; 402bf215546Sopenharmony_ci } 403bf215546Sopenharmony_ci 404bf215546Sopenharmony_ci set_tex_image(texObj, target, level, texImage); 405bf215546Sopenharmony_ci } 406bf215546Sopenharmony_ci 407bf215546Sopenharmony_ci return texImage; 408bf215546Sopenharmony_ci} 409bf215546Sopenharmony_ci 410bf215546Sopenharmony_ci 411bf215546Sopenharmony_ci/** 412bf215546Sopenharmony_ci * Return pointer to the specified proxy texture image. 413bf215546Sopenharmony_ci * Note that proxy textures are per-context, not per-texture unit. 414bf215546Sopenharmony_ci * \return pointer to texture image or NULL if invalid target, invalid 415bf215546Sopenharmony_ci * level, or out of memory. 416bf215546Sopenharmony_ci */ 417bf215546Sopenharmony_cistatic struct gl_texture_image * 418bf215546Sopenharmony_ciget_proxy_tex_image(struct gl_context *ctx, GLenum target, GLint level) 419bf215546Sopenharmony_ci{ 420bf215546Sopenharmony_ci struct gl_texture_image *texImage; 421bf215546Sopenharmony_ci GLuint texIndex; 422bf215546Sopenharmony_ci 423bf215546Sopenharmony_ci if (level < 0) 424bf215546Sopenharmony_ci return NULL; 425bf215546Sopenharmony_ci 426bf215546Sopenharmony_ci switch (target) { 427bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_1D: 428bf215546Sopenharmony_ci texIndex = TEXTURE_1D_INDEX; 429bf215546Sopenharmony_ci break; 430bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D: 431bf215546Sopenharmony_ci texIndex = TEXTURE_2D_INDEX; 432bf215546Sopenharmony_ci break; 433bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_3D: 434bf215546Sopenharmony_ci texIndex = TEXTURE_3D_INDEX; 435bf215546Sopenharmony_ci break; 436bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_CUBE_MAP: 437bf215546Sopenharmony_ci texIndex = TEXTURE_CUBE_INDEX; 438bf215546Sopenharmony_ci break; 439bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_RECTANGLE_NV: 440bf215546Sopenharmony_ci if (level > 0) 441bf215546Sopenharmony_ci return NULL; 442bf215546Sopenharmony_ci texIndex = TEXTURE_RECT_INDEX; 443bf215546Sopenharmony_ci break; 444bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 445bf215546Sopenharmony_ci texIndex = TEXTURE_1D_ARRAY_INDEX; 446bf215546Sopenharmony_ci break; 447bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 448bf215546Sopenharmony_ci texIndex = TEXTURE_2D_ARRAY_INDEX; 449bf215546Sopenharmony_ci break; 450bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 451bf215546Sopenharmony_ci texIndex = TEXTURE_CUBE_ARRAY_INDEX; 452bf215546Sopenharmony_ci break; 453bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 454bf215546Sopenharmony_ci texIndex = TEXTURE_2D_MULTISAMPLE_INDEX; 455bf215546Sopenharmony_ci break; 456bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 457bf215546Sopenharmony_ci texIndex = TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX; 458bf215546Sopenharmony_ci break; 459bf215546Sopenharmony_ci default: 460bf215546Sopenharmony_ci return NULL; 461bf215546Sopenharmony_ci } 462bf215546Sopenharmony_ci 463bf215546Sopenharmony_ci texImage = ctx->Texture.ProxyTex[texIndex]->Image[0][level]; 464bf215546Sopenharmony_ci if (!texImage) { 465bf215546Sopenharmony_ci texImage = CALLOC_STRUCT(gl_texture_image); 466bf215546Sopenharmony_ci if (!texImage) { 467bf215546Sopenharmony_ci _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); 468bf215546Sopenharmony_ci return NULL; 469bf215546Sopenharmony_ci } 470bf215546Sopenharmony_ci ctx->Texture.ProxyTex[texIndex]->Image[0][level] = texImage; 471bf215546Sopenharmony_ci /* Set the 'back' pointer */ 472bf215546Sopenharmony_ci texImage->TexObject = ctx->Texture.ProxyTex[texIndex]; 473bf215546Sopenharmony_ci } 474bf215546Sopenharmony_ci return texImage; 475bf215546Sopenharmony_ci} 476bf215546Sopenharmony_ci 477bf215546Sopenharmony_ci 478bf215546Sopenharmony_ci/** 479bf215546Sopenharmony_ci * Get the maximum number of allowed mipmap levels. 480bf215546Sopenharmony_ci * 481bf215546Sopenharmony_ci * \param ctx GL context. 482bf215546Sopenharmony_ci * \param target texture target. 483bf215546Sopenharmony_ci * 484bf215546Sopenharmony_ci * \return the maximum number of allowed mipmap levels for the given 485bf215546Sopenharmony_ci * texture target, or zero if passed a bad target. 486bf215546Sopenharmony_ci * 487bf215546Sopenharmony_ci * \sa gl_constants. 488bf215546Sopenharmony_ci */ 489bf215546Sopenharmony_ciGLint 490bf215546Sopenharmony_ci_mesa_max_texture_levels(const struct gl_context *ctx, GLenum target) 491bf215546Sopenharmony_ci{ 492bf215546Sopenharmony_ci switch (target) { 493bf215546Sopenharmony_ci case GL_TEXTURE_1D: 494bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_1D: 495bf215546Sopenharmony_ci case GL_TEXTURE_2D: 496bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D: 497bf215546Sopenharmony_ci return ffs(util_next_power_of_two(ctx->Const.MaxTextureSize)); 498bf215546Sopenharmony_ci case GL_TEXTURE_3D: 499bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_3D: 500bf215546Sopenharmony_ci return !(ctx->API == API_OPENGLES2 && !ctx->Extensions.OES_texture_3D) 501bf215546Sopenharmony_ci ? ctx->Const.Max3DTextureLevels : 0; 502bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP: 503bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 504bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 505bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 506bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 507bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 508bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 509bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_CUBE_MAP: 510bf215546Sopenharmony_ci return ctx->Const.MaxCubeTextureLevels; 511bf215546Sopenharmony_ci case GL_TEXTURE_RECTANGLE_NV: 512bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_RECTANGLE_NV: 513bf215546Sopenharmony_ci return ctx->Extensions.NV_texture_rectangle ? 1 : 0; 514bf215546Sopenharmony_ci case GL_TEXTURE_1D_ARRAY_EXT: 515bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 516bf215546Sopenharmony_ci case GL_TEXTURE_2D_ARRAY_EXT: 517bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 518bf215546Sopenharmony_ci return ctx->Extensions.EXT_texture_array 519bf215546Sopenharmony_ci ? ffs(util_next_power_of_two(ctx->Const.MaxTextureSize)) : 0; 520bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_ARRAY: 521bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 522bf215546Sopenharmony_ci return _mesa_has_texture_cube_map_array(ctx) 523bf215546Sopenharmony_ci ? ctx->Const.MaxCubeTextureLevels : 0; 524bf215546Sopenharmony_ci case GL_TEXTURE_BUFFER: 525bf215546Sopenharmony_ci return (_mesa_has_ARB_texture_buffer_object(ctx) || 526bf215546Sopenharmony_ci _mesa_has_OES_texture_buffer(ctx)) ? 1 : 0; 527bf215546Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE: 528bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 529bf215546Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 530bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 531bf215546Sopenharmony_ci return (_mesa_is_desktop_gl(ctx) || _mesa_is_gles31(ctx)) 532bf215546Sopenharmony_ci && ctx->Extensions.ARB_texture_multisample 533bf215546Sopenharmony_ci ? 1 : 0; 534bf215546Sopenharmony_ci case GL_TEXTURE_EXTERNAL_OES: 535bf215546Sopenharmony_ci return _mesa_has_OES_EGL_image_external(ctx) ? 1 : 0; 536bf215546Sopenharmony_ci default: 537bf215546Sopenharmony_ci return 0; /* bad target */ 538bf215546Sopenharmony_ci } 539bf215546Sopenharmony_ci} 540bf215546Sopenharmony_ci 541bf215546Sopenharmony_ci 542bf215546Sopenharmony_ci/** 543bf215546Sopenharmony_ci * Return number of dimensions per mipmap level for the given texture target. 544bf215546Sopenharmony_ci */ 545bf215546Sopenharmony_ciGLint 546bf215546Sopenharmony_ci_mesa_get_texture_dimensions(GLenum target) 547bf215546Sopenharmony_ci{ 548bf215546Sopenharmony_ci switch (target) { 549bf215546Sopenharmony_ci case GL_TEXTURE_1D: 550bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_1D: 551bf215546Sopenharmony_ci return 1; 552bf215546Sopenharmony_ci case GL_TEXTURE_2D: 553bf215546Sopenharmony_ci case GL_TEXTURE_RECTANGLE: 554bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP: 555bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D: 556bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_RECTANGLE: 557bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_CUBE_MAP: 558bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 559bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 560bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 561bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 562bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 563bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 564bf215546Sopenharmony_ci case GL_TEXTURE_1D_ARRAY: 565bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_1D_ARRAY: 566bf215546Sopenharmony_ci case GL_TEXTURE_EXTERNAL_OES: 567bf215546Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE: 568bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 569bf215546Sopenharmony_ci return 2; 570bf215546Sopenharmony_ci case GL_TEXTURE_3D: 571bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_3D: 572bf215546Sopenharmony_ci case GL_TEXTURE_2D_ARRAY: 573bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D_ARRAY: 574bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_ARRAY: 575bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 576bf215546Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 577bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 578bf215546Sopenharmony_ci return 3; 579bf215546Sopenharmony_ci case GL_TEXTURE_BUFFER: 580bf215546Sopenharmony_ci FALLTHROUGH; 581bf215546Sopenharmony_ci default: 582bf215546Sopenharmony_ci _mesa_problem(NULL, "invalid target 0x%x in get_texture_dimensions()", 583bf215546Sopenharmony_ci target); 584bf215546Sopenharmony_ci return 2; 585bf215546Sopenharmony_ci } 586bf215546Sopenharmony_ci} 587bf215546Sopenharmony_ci 588bf215546Sopenharmony_ci 589bf215546Sopenharmony_ci/** 590bf215546Sopenharmony_ci * Check if a texture target can have more than one layer. 591bf215546Sopenharmony_ci */ 592bf215546Sopenharmony_ciGLboolean 593bf215546Sopenharmony_ci_mesa_tex_target_is_layered(GLenum target) 594bf215546Sopenharmony_ci{ 595bf215546Sopenharmony_ci switch (target) { 596bf215546Sopenharmony_ci case GL_TEXTURE_1D: 597bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_1D: 598bf215546Sopenharmony_ci case GL_TEXTURE_2D: 599bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D: 600bf215546Sopenharmony_ci case GL_TEXTURE_RECTANGLE: 601bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_RECTANGLE: 602bf215546Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE: 603bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 604bf215546Sopenharmony_ci case GL_TEXTURE_BUFFER: 605bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 606bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 607bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 608bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 609bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 610bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 611bf215546Sopenharmony_ci case GL_TEXTURE_EXTERNAL_OES: 612bf215546Sopenharmony_ci return GL_FALSE; 613bf215546Sopenharmony_ci 614bf215546Sopenharmony_ci case GL_TEXTURE_3D: 615bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_3D: 616bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP: 617bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_CUBE_MAP: 618bf215546Sopenharmony_ci case GL_TEXTURE_1D_ARRAY: 619bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_1D_ARRAY: 620bf215546Sopenharmony_ci case GL_TEXTURE_2D_ARRAY: 621bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D_ARRAY: 622bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_ARRAY: 623bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 624bf215546Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 625bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 626bf215546Sopenharmony_ci return GL_TRUE; 627bf215546Sopenharmony_ci 628bf215546Sopenharmony_ci default: 629bf215546Sopenharmony_ci assert(!"Invalid texture target."); 630bf215546Sopenharmony_ci return GL_FALSE; 631bf215546Sopenharmony_ci } 632bf215546Sopenharmony_ci} 633bf215546Sopenharmony_ci 634bf215546Sopenharmony_ci 635bf215546Sopenharmony_ci/** 636bf215546Sopenharmony_ci * Return the number of layers present in the given level of an array, 637bf215546Sopenharmony_ci * cubemap or 3D texture. If the texture is not layered return zero. 638bf215546Sopenharmony_ci */ 639bf215546Sopenharmony_ciGLuint 640bf215546Sopenharmony_ci_mesa_get_texture_layers(const struct gl_texture_object *texObj, GLint level) 641bf215546Sopenharmony_ci{ 642bf215546Sopenharmony_ci assert(level >= 0 && level < MAX_TEXTURE_LEVELS); 643bf215546Sopenharmony_ci 644bf215546Sopenharmony_ci switch (texObj->Target) { 645bf215546Sopenharmony_ci case GL_TEXTURE_1D: 646bf215546Sopenharmony_ci case GL_TEXTURE_2D: 647bf215546Sopenharmony_ci case GL_TEXTURE_RECTANGLE: 648bf215546Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE: 649bf215546Sopenharmony_ci case GL_TEXTURE_BUFFER: 650bf215546Sopenharmony_ci case GL_TEXTURE_EXTERNAL_OES: 651bf215546Sopenharmony_ci return 0; 652bf215546Sopenharmony_ci 653bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP: 654bf215546Sopenharmony_ci return 6; 655bf215546Sopenharmony_ci 656bf215546Sopenharmony_ci case GL_TEXTURE_1D_ARRAY: { 657bf215546Sopenharmony_ci struct gl_texture_image *img = texObj->Image[0][level]; 658bf215546Sopenharmony_ci return img ? img->Height : 0; 659bf215546Sopenharmony_ci } 660bf215546Sopenharmony_ci 661bf215546Sopenharmony_ci case GL_TEXTURE_3D: 662bf215546Sopenharmony_ci case GL_TEXTURE_2D_ARRAY: 663bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_ARRAY: 664bf215546Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: { 665bf215546Sopenharmony_ci struct gl_texture_image *img = texObj->Image[0][level]; 666bf215546Sopenharmony_ci return img ? img->Depth : 0; 667bf215546Sopenharmony_ci } 668bf215546Sopenharmony_ci 669bf215546Sopenharmony_ci default: 670bf215546Sopenharmony_ci assert(!"Invalid texture target."); 671bf215546Sopenharmony_ci return 0; 672bf215546Sopenharmony_ci } 673bf215546Sopenharmony_ci} 674bf215546Sopenharmony_ci 675bf215546Sopenharmony_ci 676bf215546Sopenharmony_ci/** 677bf215546Sopenharmony_ci * Return the maximum number of mipmap levels for the given target 678bf215546Sopenharmony_ci * and the dimensions. 679bf215546Sopenharmony_ci * The dimensions are expected not to include the border. 680bf215546Sopenharmony_ci */ 681bf215546Sopenharmony_ciGLsizei 682bf215546Sopenharmony_ci_mesa_get_tex_max_num_levels(GLenum target, GLsizei width, GLsizei height, 683bf215546Sopenharmony_ci GLsizei depth) 684bf215546Sopenharmony_ci{ 685bf215546Sopenharmony_ci GLsizei size; 686bf215546Sopenharmony_ci 687bf215546Sopenharmony_ci switch (target) { 688bf215546Sopenharmony_ci case GL_TEXTURE_1D: 689bf215546Sopenharmony_ci case GL_TEXTURE_1D_ARRAY: 690bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_1D: 691bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_1D_ARRAY: 692bf215546Sopenharmony_ci size = width; 693bf215546Sopenharmony_ci break; 694bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP: 695bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_ARRAY: 696bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_CUBE_MAP: 697bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 698bf215546Sopenharmony_ci size = width; 699bf215546Sopenharmony_ci break; 700bf215546Sopenharmony_ci case GL_TEXTURE_2D: 701bf215546Sopenharmony_ci case GL_TEXTURE_2D_ARRAY: 702bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D: 703bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D_ARRAY: 704bf215546Sopenharmony_ci size = MAX2(width, height); 705bf215546Sopenharmony_ci break; 706bf215546Sopenharmony_ci case GL_TEXTURE_3D: 707bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_3D: 708bf215546Sopenharmony_ci size = MAX3(width, height, depth); 709bf215546Sopenharmony_ci break; 710bf215546Sopenharmony_ci case GL_TEXTURE_RECTANGLE: 711bf215546Sopenharmony_ci case GL_TEXTURE_EXTERNAL_OES: 712bf215546Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE: 713bf215546Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 714bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_RECTANGLE: 715bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 716bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 717bf215546Sopenharmony_ci return 1; 718bf215546Sopenharmony_ci default: 719bf215546Sopenharmony_ci assert(0); 720bf215546Sopenharmony_ci return 1; 721bf215546Sopenharmony_ci } 722bf215546Sopenharmony_ci 723bf215546Sopenharmony_ci return util_logbase2(size) + 1; 724bf215546Sopenharmony_ci} 725bf215546Sopenharmony_ci 726bf215546Sopenharmony_ci 727bf215546Sopenharmony_ci#if 000 /* not used anymore */ 728bf215546Sopenharmony_ci/* 729bf215546Sopenharmony_ci * glTexImage[123]D can accept a NULL image pointer. In this case we 730bf215546Sopenharmony_ci * create a texture image with unspecified image contents per the OpenGL 731bf215546Sopenharmony_ci * spec. 732bf215546Sopenharmony_ci */ 733bf215546Sopenharmony_cistatic GLubyte * 734bf215546Sopenharmony_cimake_null_texture(GLint width, GLint height, GLint depth, GLenum format) 735bf215546Sopenharmony_ci{ 736bf215546Sopenharmony_ci const GLint components = _mesa_components_in_format(format); 737bf215546Sopenharmony_ci const GLint numPixels = width * height * depth; 738bf215546Sopenharmony_ci GLubyte *data = (GLubyte *) malloc(numPixels * components * sizeof(GLubyte)); 739bf215546Sopenharmony_ci 740bf215546Sopenharmony_ci#ifdef DEBUG 741bf215546Sopenharmony_ci /* 742bf215546Sopenharmony_ci * Let's see if anyone finds this. If glTexImage2D() is called with 743bf215546Sopenharmony_ci * a NULL image pointer then load the texture image with something 744bf215546Sopenharmony_ci * interesting instead of leaving it indeterminate. 745bf215546Sopenharmony_ci */ 746bf215546Sopenharmony_ci if (data) { 747bf215546Sopenharmony_ci static const char message[8][32] = { 748bf215546Sopenharmony_ci " X X XXXXX XXX X ", 749bf215546Sopenharmony_ci " XX XX X X X X X ", 750bf215546Sopenharmony_ci " X X X X X X X ", 751bf215546Sopenharmony_ci " X X XXXX XXX XXXXX ", 752bf215546Sopenharmony_ci " X X X X X X ", 753bf215546Sopenharmony_ci " X X X X X X X ", 754bf215546Sopenharmony_ci " X X XXXXX XXX X X ", 755bf215546Sopenharmony_ci " " 756bf215546Sopenharmony_ci }; 757bf215546Sopenharmony_ci 758bf215546Sopenharmony_ci GLubyte *imgPtr = data; 759bf215546Sopenharmony_ci GLint h, i, j, k; 760bf215546Sopenharmony_ci for (h = 0; h < depth; h++) { 761bf215546Sopenharmony_ci for (i = 0; i < height; i++) { 762bf215546Sopenharmony_ci GLint srcRow = 7 - (i % 8); 763bf215546Sopenharmony_ci for (j = 0; j < width; j++) { 764bf215546Sopenharmony_ci GLint srcCol = j % 32; 765bf215546Sopenharmony_ci GLubyte texel = (message[srcRow][srcCol]=='X') ? 255 : 70; 766bf215546Sopenharmony_ci for (k = 0; k < components; k++) { 767bf215546Sopenharmony_ci *imgPtr++ = texel; 768bf215546Sopenharmony_ci } 769bf215546Sopenharmony_ci } 770bf215546Sopenharmony_ci } 771bf215546Sopenharmony_ci } 772bf215546Sopenharmony_ci } 773bf215546Sopenharmony_ci#endif 774bf215546Sopenharmony_ci 775bf215546Sopenharmony_ci return data; 776bf215546Sopenharmony_ci} 777bf215546Sopenharmony_ci#endif 778bf215546Sopenharmony_ci 779bf215546Sopenharmony_ci 780bf215546Sopenharmony_ci 781bf215546Sopenharmony_ci/** 782bf215546Sopenharmony_ci * Set the size and format-related fields of a gl_texture_image struct 783bf215546Sopenharmony_ci * to zero. This is used when a proxy texture test fails. 784bf215546Sopenharmony_ci */ 785bf215546Sopenharmony_cistatic void 786bf215546Sopenharmony_ciclear_teximage_fields(struct gl_texture_image *img) 787bf215546Sopenharmony_ci{ 788bf215546Sopenharmony_ci assert(img); 789bf215546Sopenharmony_ci img->_BaseFormat = 0; 790bf215546Sopenharmony_ci img->InternalFormat = 0; 791bf215546Sopenharmony_ci img->Border = 0; 792bf215546Sopenharmony_ci img->Width = 0; 793bf215546Sopenharmony_ci img->Height = 0; 794bf215546Sopenharmony_ci img->Depth = 0; 795bf215546Sopenharmony_ci img->Width2 = 0; 796bf215546Sopenharmony_ci img->Height2 = 0; 797bf215546Sopenharmony_ci img->Depth2 = 0; 798bf215546Sopenharmony_ci img->WidthLog2 = 0; 799bf215546Sopenharmony_ci img->HeightLog2 = 0; 800bf215546Sopenharmony_ci img->DepthLog2 = 0; 801bf215546Sopenharmony_ci img->TexFormat = MESA_FORMAT_NONE; 802bf215546Sopenharmony_ci img->NumSamples = 0; 803bf215546Sopenharmony_ci img->FixedSampleLocations = GL_TRUE; 804bf215546Sopenharmony_ci} 805bf215546Sopenharmony_ci 806bf215546Sopenharmony_ci 807bf215546Sopenharmony_ci/** 808bf215546Sopenharmony_ci * Initialize basic fields of the gl_texture_image struct. 809bf215546Sopenharmony_ci * 810bf215546Sopenharmony_ci * \param ctx GL context. 811bf215546Sopenharmony_ci * \param img texture image structure to be initialized. 812bf215546Sopenharmony_ci * \param width image width. 813bf215546Sopenharmony_ci * \param height image height. 814bf215546Sopenharmony_ci * \param depth image depth. 815bf215546Sopenharmony_ci * \param border image border. 816bf215546Sopenharmony_ci * \param internalFormat internal format. 817bf215546Sopenharmony_ci * \param format the actual hardware format (one of MESA_FORMAT_*) 818bf215546Sopenharmony_ci * \param numSamples number of samples per texel, or zero for non-MS. 819bf215546Sopenharmony_ci * \param fixedSampleLocations are sample locations fixed? 820bf215546Sopenharmony_ci * 821bf215546Sopenharmony_ci * Fills in the fields of \p img with the given information. 822bf215546Sopenharmony_ci * Note: width, height and depth include the border. 823bf215546Sopenharmony_ci */ 824bf215546Sopenharmony_civoid 825bf215546Sopenharmony_ci_mesa_init_teximage_fields_ms(struct gl_context *ctx, 826bf215546Sopenharmony_ci struct gl_texture_image *img, 827bf215546Sopenharmony_ci GLsizei width, GLsizei height, GLsizei depth, 828bf215546Sopenharmony_ci GLint border, GLenum internalFormat, 829bf215546Sopenharmony_ci mesa_format format, 830bf215546Sopenharmony_ci GLuint numSamples, GLboolean fixedSampleLocations) 831bf215546Sopenharmony_ci{ 832bf215546Sopenharmony_ci const GLint base_format =_mesa_base_tex_format(ctx, internalFormat); 833bf215546Sopenharmony_ci GLenum target; 834bf215546Sopenharmony_ci assert(img); 835bf215546Sopenharmony_ci assert(width >= 0); 836bf215546Sopenharmony_ci assert(height >= 0); 837bf215546Sopenharmony_ci assert(depth >= 0); 838bf215546Sopenharmony_ci 839bf215546Sopenharmony_ci target = img->TexObject->Target; 840bf215546Sopenharmony_ci assert(base_format != -1); 841bf215546Sopenharmony_ci img->_BaseFormat = (GLenum16)base_format; 842bf215546Sopenharmony_ci img->InternalFormat = internalFormat; 843bf215546Sopenharmony_ci img->Border = border; 844bf215546Sopenharmony_ci img->Width = width; 845bf215546Sopenharmony_ci img->Height = height; 846bf215546Sopenharmony_ci img->Depth = depth; 847bf215546Sopenharmony_ci 848bf215546Sopenharmony_ci img->Width2 = width - 2 * border; /* == 1 << img->WidthLog2; */ 849bf215546Sopenharmony_ci img->WidthLog2 = util_logbase2(img->Width2); 850bf215546Sopenharmony_ci 851bf215546Sopenharmony_ci switch(target) { 852bf215546Sopenharmony_ci case GL_TEXTURE_1D: 853bf215546Sopenharmony_ci case GL_TEXTURE_BUFFER: 854bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_1D: 855bf215546Sopenharmony_ci if (height == 0) 856bf215546Sopenharmony_ci img->Height2 = 0; 857bf215546Sopenharmony_ci else 858bf215546Sopenharmony_ci img->Height2 = 1; 859bf215546Sopenharmony_ci img->HeightLog2 = 0; 860bf215546Sopenharmony_ci if (depth == 0) 861bf215546Sopenharmony_ci img->Depth2 = 0; 862bf215546Sopenharmony_ci else 863bf215546Sopenharmony_ci img->Depth2 = 1; 864bf215546Sopenharmony_ci img->DepthLog2 = 0; 865bf215546Sopenharmony_ci break; 866bf215546Sopenharmony_ci case GL_TEXTURE_1D_ARRAY: 867bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_1D_ARRAY: 868bf215546Sopenharmony_ci img->Height2 = height; /* no border */ 869bf215546Sopenharmony_ci img->HeightLog2 = 0; /* not used */ 870bf215546Sopenharmony_ci if (depth == 0) 871bf215546Sopenharmony_ci img->Depth2 = 0; 872bf215546Sopenharmony_ci else 873bf215546Sopenharmony_ci img->Depth2 = 1; 874bf215546Sopenharmony_ci img->DepthLog2 = 0; 875bf215546Sopenharmony_ci break; 876bf215546Sopenharmony_ci case GL_TEXTURE_2D: 877bf215546Sopenharmony_ci case GL_TEXTURE_RECTANGLE: 878bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP: 879bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 880bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 881bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 882bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 883bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 884bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 885bf215546Sopenharmony_ci case GL_TEXTURE_EXTERNAL_OES: 886bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D: 887bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_RECTANGLE: 888bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_CUBE_MAP: 889bf215546Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE: 890bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 891bf215546Sopenharmony_ci img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */ 892bf215546Sopenharmony_ci img->HeightLog2 = util_logbase2(img->Height2); 893bf215546Sopenharmony_ci if (depth == 0) 894bf215546Sopenharmony_ci img->Depth2 = 0; 895bf215546Sopenharmony_ci else 896bf215546Sopenharmony_ci img->Depth2 = 1; 897bf215546Sopenharmony_ci img->DepthLog2 = 0; 898bf215546Sopenharmony_ci break; 899bf215546Sopenharmony_ci case GL_TEXTURE_2D_ARRAY: 900bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D_ARRAY: 901bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_ARRAY: 902bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 903bf215546Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 904bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 905bf215546Sopenharmony_ci img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */ 906bf215546Sopenharmony_ci img->HeightLog2 = util_logbase2(img->Height2); 907bf215546Sopenharmony_ci img->Depth2 = depth; /* no border */ 908bf215546Sopenharmony_ci img->DepthLog2 = 0; /* not used */ 909bf215546Sopenharmony_ci break; 910bf215546Sopenharmony_ci case GL_TEXTURE_3D: 911bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_3D: 912bf215546Sopenharmony_ci img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */ 913bf215546Sopenharmony_ci img->HeightLog2 = util_logbase2(img->Height2); 914bf215546Sopenharmony_ci img->Depth2 = depth - 2 * border; /* == 1 << img->DepthLog2; */ 915bf215546Sopenharmony_ci img->DepthLog2 = util_logbase2(img->Depth2); 916bf215546Sopenharmony_ci break; 917bf215546Sopenharmony_ci default: 918bf215546Sopenharmony_ci _mesa_problem(NULL, "invalid target 0x%x in _mesa_init_teximage_fields()", 919bf215546Sopenharmony_ci target); 920bf215546Sopenharmony_ci } 921bf215546Sopenharmony_ci 922bf215546Sopenharmony_ci img->MaxNumLevels = 923bf215546Sopenharmony_ci _mesa_get_tex_max_num_levels(target, 924bf215546Sopenharmony_ci img->Width2, img->Height2, img->Depth2); 925bf215546Sopenharmony_ci img->TexFormat = format; 926bf215546Sopenharmony_ci img->NumSamples = numSamples; 927bf215546Sopenharmony_ci img->FixedSampleLocations = fixedSampleLocations; 928bf215546Sopenharmony_ci} 929bf215546Sopenharmony_ci 930bf215546Sopenharmony_ci 931bf215546Sopenharmony_civoid 932bf215546Sopenharmony_ci_mesa_init_teximage_fields(struct gl_context *ctx, 933bf215546Sopenharmony_ci struct gl_texture_image *img, 934bf215546Sopenharmony_ci GLsizei width, GLsizei height, GLsizei depth, 935bf215546Sopenharmony_ci GLint border, GLenum internalFormat, 936bf215546Sopenharmony_ci mesa_format format) 937bf215546Sopenharmony_ci{ 938bf215546Sopenharmony_ci _mesa_init_teximage_fields_ms(ctx, img, width, height, depth, border, 939bf215546Sopenharmony_ci internalFormat, format, 0, GL_TRUE); 940bf215546Sopenharmony_ci} 941bf215546Sopenharmony_ci 942bf215546Sopenharmony_ci 943bf215546Sopenharmony_ci/** 944bf215546Sopenharmony_ci * Free and clear fields of the gl_texture_image struct. 945bf215546Sopenharmony_ci * 946bf215546Sopenharmony_ci * \param ctx GL context. 947bf215546Sopenharmony_ci * \param texImage texture image structure to be cleared. 948bf215546Sopenharmony_ci * 949bf215546Sopenharmony_ci * After the call, \p texImage will have no data associated with it. Its 950bf215546Sopenharmony_ci * fields are cleared so that its parent object will test incomplete. 951bf215546Sopenharmony_ci */ 952bf215546Sopenharmony_civoid 953bf215546Sopenharmony_ci_mesa_clear_texture_image(struct gl_context *ctx, 954bf215546Sopenharmony_ci struct gl_texture_image *texImage) 955bf215546Sopenharmony_ci{ 956bf215546Sopenharmony_ci st_FreeTextureImageBuffer(ctx, texImage); 957bf215546Sopenharmony_ci clear_teximage_fields(texImage); 958bf215546Sopenharmony_ci} 959bf215546Sopenharmony_ci 960bf215546Sopenharmony_ci 961bf215546Sopenharmony_ci/** 962bf215546Sopenharmony_ci * Check the width, height, depth and border of a texture image are legal. 963bf215546Sopenharmony_ci * Used by all the glTexImage, glCompressedTexImage and glCopyTexImage 964bf215546Sopenharmony_ci * functions. 965bf215546Sopenharmony_ci * The target and level parameters will have already been validated. 966bf215546Sopenharmony_ci * \return GL_TRUE if size is OK, GL_FALSE otherwise. 967bf215546Sopenharmony_ci */ 968bf215546Sopenharmony_ciGLboolean 969bf215546Sopenharmony_ci_mesa_legal_texture_dimensions(struct gl_context *ctx, GLenum target, 970bf215546Sopenharmony_ci GLint level, GLint width, GLint height, 971bf215546Sopenharmony_ci GLint depth, GLint border) 972bf215546Sopenharmony_ci{ 973bf215546Sopenharmony_ci GLint maxSize; 974bf215546Sopenharmony_ci 975bf215546Sopenharmony_ci switch (target) { 976bf215546Sopenharmony_ci case GL_TEXTURE_1D: 977bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_1D: 978bf215546Sopenharmony_ci maxSize = ctx->Const.MaxTextureSize >> level; 979bf215546Sopenharmony_ci if (width < 2 * border || width > 2 * border + maxSize) 980bf215546Sopenharmony_ci return GL_FALSE; 981bf215546Sopenharmony_ci if (!ctx->Extensions.ARB_texture_non_power_of_two) { 982bf215546Sopenharmony_ci if (width > 0 && !util_is_power_of_two_nonzero(width - 2 * border)) 983bf215546Sopenharmony_ci return GL_FALSE; 984bf215546Sopenharmony_ci } 985bf215546Sopenharmony_ci return GL_TRUE; 986bf215546Sopenharmony_ci 987bf215546Sopenharmony_ci case GL_TEXTURE_2D: 988bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D: 989bf215546Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE: 990bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 991bf215546Sopenharmony_ci maxSize = ctx->Const.MaxTextureSize >> level; 992bf215546Sopenharmony_ci if (width < 2 * border || width > 2 * border + maxSize) 993bf215546Sopenharmony_ci return GL_FALSE; 994bf215546Sopenharmony_ci if (height < 2 * border || height > 2 * border + maxSize) 995bf215546Sopenharmony_ci return GL_FALSE; 996bf215546Sopenharmony_ci if (!ctx->Extensions.ARB_texture_non_power_of_two) { 997bf215546Sopenharmony_ci if (width > 0 && !util_is_power_of_two_nonzero(width - 2 * border)) 998bf215546Sopenharmony_ci return GL_FALSE; 999bf215546Sopenharmony_ci if (height > 0 && !util_is_power_of_two_nonzero(height - 2 * border)) 1000bf215546Sopenharmony_ci return GL_FALSE; 1001bf215546Sopenharmony_ci } 1002bf215546Sopenharmony_ci return GL_TRUE; 1003bf215546Sopenharmony_ci 1004bf215546Sopenharmony_ci case GL_TEXTURE_3D: 1005bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_3D: 1006bf215546Sopenharmony_ci maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1); 1007bf215546Sopenharmony_ci maxSize >>= level; 1008bf215546Sopenharmony_ci if (width < 2 * border || width > 2 * border + maxSize) 1009bf215546Sopenharmony_ci return GL_FALSE; 1010bf215546Sopenharmony_ci if (height < 2 * border || height > 2 * border + maxSize) 1011bf215546Sopenharmony_ci return GL_FALSE; 1012bf215546Sopenharmony_ci if (depth < 2 * border || depth > 2 * border + maxSize) 1013bf215546Sopenharmony_ci return GL_FALSE; 1014bf215546Sopenharmony_ci if (!ctx->Extensions.ARB_texture_non_power_of_two) { 1015bf215546Sopenharmony_ci if (width > 0 && !util_is_power_of_two_nonzero(width - 2 * border)) 1016bf215546Sopenharmony_ci return GL_FALSE; 1017bf215546Sopenharmony_ci if (height > 0 && !util_is_power_of_two_nonzero(height - 2 * border)) 1018bf215546Sopenharmony_ci return GL_FALSE; 1019bf215546Sopenharmony_ci if (depth > 0 && !util_is_power_of_two_nonzero(depth - 2 * border)) 1020bf215546Sopenharmony_ci return GL_FALSE; 1021bf215546Sopenharmony_ci } 1022bf215546Sopenharmony_ci return GL_TRUE; 1023bf215546Sopenharmony_ci 1024bf215546Sopenharmony_ci case GL_TEXTURE_RECTANGLE_NV: 1025bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_RECTANGLE_NV: 1026bf215546Sopenharmony_ci if (level != 0) 1027bf215546Sopenharmony_ci return GL_FALSE; 1028bf215546Sopenharmony_ci maxSize = ctx->Const.MaxTextureRectSize; 1029bf215546Sopenharmony_ci if (width < 0 || width > maxSize) 1030bf215546Sopenharmony_ci return GL_FALSE; 1031bf215546Sopenharmony_ci if (height < 0 || height > maxSize) 1032bf215546Sopenharmony_ci return GL_FALSE; 1033bf215546Sopenharmony_ci return GL_TRUE; 1034bf215546Sopenharmony_ci 1035bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP: 1036bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1037bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1038bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1039bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1040bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1041bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1042bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_CUBE_MAP: 1043bf215546Sopenharmony_ci maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1); 1044bf215546Sopenharmony_ci maxSize >>= level; 1045bf215546Sopenharmony_ci if (width != height) 1046bf215546Sopenharmony_ci return GL_FALSE; 1047bf215546Sopenharmony_ci if (width < 2 * border || width > 2 * border + maxSize) 1048bf215546Sopenharmony_ci return GL_FALSE; 1049bf215546Sopenharmony_ci if (height < 2 * border || height > 2 * border + maxSize) 1050bf215546Sopenharmony_ci return GL_FALSE; 1051bf215546Sopenharmony_ci if (!ctx->Extensions.ARB_texture_non_power_of_two) { 1052bf215546Sopenharmony_ci if (width > 0 && !util_is_power_of_two_nonzero(width - 2 * border)) 1053bf215546Sopenharmony_ci return GL_FALSE; 1054bf215546Sopenharmony_ci if (height > 0 && !util_is_power_of_two_nonzero(height - 2 * border)) 1055bf215546Sopenharmony_ci return GL_FALSE; 1056bf215546Sopenharmony_ci } 1057bf215546Sopenharmony_ci return GL_TRUE; 1058bf215546Sopenharmony_ci 1059bf215546Sopenharmony_ci case GL_TEXTURE_1D_ARRAY_EXT: 1060bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 1061bf215546Sopenharmony_ci maxSize = ctx->Const.MaxTextureSize >> level; 1062bf215546Sopenharmony_ci if (width < 2 * border || width > 2 * border + maxSize) 1063bf215546Sopenharmony_ci return GL_FALSE; 1064bf215546Sopenharmony_ci if (height < 0 || height > ctx->Const.MaxArrayTextureLayers) 1065bf215546Sopenharmony_ci return GL_FALSE; 1066bf215546Sopenharmony_ci if (!ctx->Extensions.ARB_texture_non_power_of_two) { 1067bf215546Sopenharmony_ci if (width > 0 && !util_is_power_of_two_nonzero(width - 2 * border)) 1068bf215546Sopenharmony_ci return GL_FALSE; 1069bf215546Sopenharmony_ci } 1070bf215546Sopenharmony_ci return GL_TRUE; 1071bf215546Sopenharmony_ci 1072bf215546Sopenharmony_ci case GL_TEXTURE_2D_ARRAY_EXT: 1073bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 1074bf215546Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 1075bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 1076bf215546Sopenharmony_ci maxSize = ctx->Const.MaxTextureSize >> level; 1077bf215546Sopenharmony_ci if (width < 2 * border || width > 2 * border + maxSize) 1078bf215546Sopenharmony_ci return GL_FALSE; 1079bf215546Sopenharmony_ci if (height < 2 * border || height > 2 * border + maxSize) 1080bf215546Sopenharmony_ci return GL_FALSE; 1081bf215546Sopenharmony_ci if (depth < 0 || depth > ctx->Const.MaxArrayTextureLayers) 1082bf215546Sopenharmony_ci return GL_FALSE; 1083bf215546Sopenharmony_ci if (!ctx->Extensions.ARB_texture_non_power_of_two) { 1084bf215546Sopenharmony_ci if (width > 0 && !util_is_power_of_two_nonzero(width - 2 * border)) 1085bf215546Sopenharmony_ci return GL_FALSE; 1086bf215546Sopenharmony_ci if (height > 0 && !util_is_power_of_two_nonzero(height - 2 * border)) 1087bf215546Sopenharmony_ci return GL_FALSE; 1088bf215546Sopenharmony_ci } 1089bf215546Sopenharmony_ci return GL_TRUE; 1090bf215546Sopenharmony_ci 1091bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_ARRAY: 1092bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 1093bf215546Sopenharmony_ci maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1); 1094bf215546Sopenharmony_ci if (width < 2 * border || width > 2 * border + maxSize) 1095bf215546Sopenharmony_ci return GL_FALSE; 1096bf215546Sopenharmony_ci if (height < 2 * border || height > 2 * border + maxSize) 1097bf215546Sopenharmony_ci return GL_FALSE; 1098bf215546Sopenharmony_ci if (depth < 0 || depth > ctx->Const.MaxArrayTextureLayers || depth % 6) 1099bf215546Sopenharmony_ci return GL_FALSE; 1100bf215546Sopenharmony_ci if (width != height) 1101bf215546Sopenharmony_ci return GL_FALSE; 1102bf215546Sopenharmony_ci if (level >= ctx->Const.MaxCubeTextureLevels) 1103bf215546Sopenharmony_ci return GL_FALSE; 1104bf215546Sopenharmony_ci if (!ctx->Extensions.ARB_texture_non_power_of_two) { 1105bf215546Sopenharmony_ci if (width > 0 && !util_is_power_of_two_nonzero(width - 2 * border)) 1106bf215546Sopenharmony_ci return GL_FALSE; 1107bf215546Sopenharmony_ci if (height > 0 && !util_is_power_of_two_nonzero(height - 2 * border)) 1108bf215546Sopenharmony_ci return GL_FALSE; 1109bf215546Sopenharmony_ci } 1110bf215546Sopenharmony_ci return GL_TRUE; 1111bf215546Sopenharmony_ci default: 1112bf215546Sopenharmony_ci _mesa_problem(ctx, "Invalid target in _mesa_legal_texture_dimensions()"); 1113bf215546Sopenharmony_ci return GL_FALSE; 1114bf215546Sopenharmony_ci } 1115bf215546Sopenharmony_ci} 1116bf215546Sopenharmony_ci 1117bf215546Sopenharmony_cistatic bool 1118bf215546Sopenharmony_cierror_check_subtexture_negative_dimensions(struct gl_context *ctx, 1119bf215546Sopenharmony_ci GLuint dims, 1120bf215546Sopenharmony_ci GLsizei subWidth, 1121bf215546Sopenharmony_ci GLsizei subHeight, 1122bf215546Sopenharmony_ci GLsizei subDepth, 1123bf215546Sopenharmony_ci const char *func) 1124bf215546Sopenharmony_ci{ 1125bf215546Sopenharmony_ci /* Check size */ 1126bf215546Sopenharmony_ci if (subWidth < 0) { 1127bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, "%s(width=%d)", func, subWidth); 1128bf215546Sopenharmony_ci return true; 1129bf215546Sopenharmony_ci } 1130bf215546Sopenharmony_ci 1131bf215546Sopenharmony_ci if (dims > 1 && subHeight < 0) { 1132bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, "%s(height=%d)", func, subHeight); 1133bf215546Sopenharmony_ci return true; 1134bf215546Sopenharmony_ci } 1135bf215546Sopenharmony_ci 1136bf215546Sopenharmony_ci if (dims > 2 && subDepth < 0) { 1137bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, "%s(depth=%d)", func, subDepth); 1138bf215546Sopenharmony_ci return true; 1139bf215546Sopenharmony_ci } 1140bf215546Sopenharmony_ci 1141bf215546Sopenharmony_ci return false; 1142bf215546Sopenharmony_ci} 1143bf215546Sopenharmony_ci 1144bf215546Sopenharmony_ci/** 1145bf215546Sopenharmony_ci * Do error checking of xoffset, yoffset, zoffset, width, height and depth 1146bf215546Sopenharmony_ci * for glTexSubImage, glCopyTexSubImage and glCompressedTexSubImage. 1147bf215546Sopenharmony_ci * \param destImage the destination texture image. 1148bf215546Sopenharmony_ci * \return GL_TRUE if error found, GL_FALSE otherwise. 1149bf215546Sopenharmony_ci */ 1150bf215546Sopenharmony_cistatic GLboolean 1151bf215546Sopenharmony_cierror_check_subtexture_dimensions(struct gl_context *ctx, GLuint dims, 1152bf215546Sopenharmony_ci const struct gl_texture_image *destImage, 1153bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, GLint zoffset, 1154bf215546Sopenharmony_ci GLsizei subWidth, GLsizei subHeight, 1155bf215546Sopenharmony_ci GLsizei subDepth, const char *func) 1156bf215546Sopenharmony_ci{ 1157bf215546Sopenharmony_ci const GLenum target = destImage->TexObject->Target; 1158bf215546Sopenharmony_ci GLuint bw, bh, bd; 1159bf215546Sopenharmony_ci 1160bf215546Sopenharmony_ci /* check xoffset and width */ 1161bf215546Sopenharmony_ci if (xoffset < - (GLint) destImage->Border) { 1162bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, "%s(xoffset)", func); 1163bf215546Sopenharmony_ci return GL_TRUE; 1164bf215546Sopenharmony_ci } 1165bf215546Sopenharmony_ci 1166bf215546Sopenharmony_ci if (xoffset + subWidth > (GLint) destImage->Width) { 1167bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, "%s(xoffset %d + width %d > %u)", func, 1168bf215546Sopenharmony_ci xoffset, subWidth, destImage->Width); 1169bf215546Sopenharmony_ci return GL_TRUE; 1170bf215546Sopenharmony_ci } 1171bf215546Sopenharmony_ci 1172bf215546Sopenharmony_ci /* check yoffset and height */ 1173bf215546Sopenharmony_ci if (dims > 1) { 1174bf215546Sopenharmony_ci GLint yBorder = (target == GL_TEXTURE_1D_ARRAY) ? 0 : destImage->Border; 1175bf215546Sopenharmony_ci if (yoffset < -yBorder) { 1176bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, "%s(yoffset)", func); 1177bf215546Sopenharmony_ci return GL_TRUE; 1178bf215546Sopenharmony_ci } 1179bf215546Sopenharmony_ci if (yoffset + subHeight > (GLint) destImage->Height) { 1180bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, "%s(yoffset %d + height %d > %u)", 1181bf215546Sopenharmony_ci func, yoffset, subHeight, destImage->Height); 1182bf215546Sopenharmony_ci return GL_TRUE; 1183bf215546Sopenharmony_ci } 1184bf215546Sopenharmony_ci } 1185bf215546Sopenharmony_ci 1186bf215546Sopenharmony_ci /* check zoffset and depth */ 1187bf215546Sopenharmony_ci if (dims > 2) { 1188bf215546Sopenharmony_ci GLint depth; 1189bf215546Sopenharmony_ci GLint zBorder = (target == GL_TEXTURE_2D_ARRAY || 1190bf215546Sopenharmony_ci target == GL_TEXTURE_CUBE_MAP_ARRAY) ? 1191bf215546Sopenharmony_ci 0 : destImage->Border; 1192bf215546Sopenharmony_ci 1193bf215546Sopenharmony_ci if (zoffset < -zBorder) { 1194bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, "%s(zoffset)", func); 1195bf215546Sopenharmony_ci return GL_TRUE; 1196bf215546Sopenharmony_ci } 1197bf215546Sopenharmony_ci 1198bf215546Sopenharmony_ci depth = (GLint) destImage->Depth; 1199bf215546Sopenharmony_ci if (target == GL_TEXTURE_CUBE_MAP) 1200bf215546Sopenharmony_ci depth = 6; 1201bf215546Sopenharmony_ci if (zoffset + subDepth > depth) { 1202bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, "%s(zoffset %d + depth %d > %u)", 1203bf215546Sopenharmony_ci func, zoffset, subDepth, depth); 1204bf215546Sopenharmony_ci return GL_TRUE; 1205bf215546Sopenharmony_ci } 1206bf215546Sopenharmony_ci } 1207bf215546Sopenharmony_ci 1208bf215546Sopenharmony_ci /* 1209bf215546Sopenharmony_ci * The OpenGL spec (and GL_ARB_texture_compression) says only whole 1210bf215546Sopenharmony_ci * compressed texture images can be updated. But, that restriction may be 1211bf215546Sopenharmony_ci * relaxed for particular compressed formats. At this time, all the 1212bf215546Sopenharmony_ci * compressed formats supported by Mesa allow sub-textures to be updated 1213bf215546Sopenharmony_ci * along compressed block boundaries. 1214bf215546Sopenharmony_ci */ 1215bf215546Sopenharmony_ci _mesa_get_format_block_size_3d(destImage->TexFormat, &bw, &bh, &bd); 1216bf215546Sopenharmony_ci 1217bf215546Sopenharmony_ci if (bw != 1 || bh != 1 || bd != 1) { 1218bf215546Sopenharmony_ci /* offset must be multiple of block size */ 1219bf215546Sopenharmony_ci if ((xoffset % bw != 0) || (yoffset % bh != 0) || (zoffset % bd != 0)) { 1220bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 1221bf215546Sopenharmony_ci "%s(xoffset = %d, yoffset = %d, zoffset = %d)", 1222bf215546Sopenharmony_ci func, xoffset, yoffset, zoffset); 1223bf215546Sopenharmony_ci return GL_TRUE; 1224bf215546Sopenharmony_ci } 1225bf215546Sopenharmony_ci 1226bf215546Sopenharmony_ci /* The size must be a multiple of bw x bh, or we must be using a 1227bf215546Sopenharmony_ci * offset+size that exactly hits the edge of the image. This 1228bf215546Sopenharmony_ci * is important for small mipmap levels (1x1, 2x1, etc) and for 1229bf215546Sopenharmony_ci * NPOT textures. 1230bf215546Sopenharmony_ci */ 1231bf215546Sopenharmony_ci if ((subWidth % bw != 0) && 1232bf215546Sopenharmony_ci (xoffset + subWidth != (GLint) destImage->Width)) { 1233bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 1234bf215546Sopenharmony_ci "%s(width = %d)", func, subWidth); 1235bf215546Sopenharmony_ci return GL_TRUE; 1236bf215546Sopenharmony_ci } 1237bf215546Sopenharmony_ci 1238bf215546Sopenharmony_ci if ((subHeight % bh != 0) && 1239bf215546Sopenharmony_ci (yoffset + subHeight != (GLint) destImage->Height)) { 1240bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 1241bf215546Sopenharmony_ci "%s(height = %d)", func, subHeight); 1242bf215546Sopenharmony_ci return GL_TRUE; 1243bf215546Sopenharmony_ci } 1244bf215546Sopenharmony_ci 1245bf215546Sopenharmony_ci if ((subDepth % bd != 0) && 1246bf215546Sopenharmony_ci (zoffset + subDepth != (GLint) destImage->Depth)) { 1247bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 1248bf215546Sopenharmony_ci "%s(depth = %d)", func, subDepth); 1249bf215546Sopenharmony_ci return GL_TRUE; 1250bf215546Sopenharmony_ci } 1251bf215546Sopenharmony_ci } 1252bf215546Sopenharmony_ci 1253bf215546Sopenharmony_ci return GL_FALSE; 1254bf215546Sopenharmony_ci} 1255bf215546Sopenharmony_ci 1256bf215546Sopenharmony_ci 1257bf215546Sopenharmony_ci 1258bf215546Sopenharmony_ci 1259bf215546Sopenharmony_ci/** 1260bf215546Sopenharmony_ci * This is the fallback for Driver.TestProxyTexImage() for doing device- 1261bf215546Sopenharmony_ci * specific texture image size checks. 1262bf215546Sopenharmony_ci * 1263bf215546Sopenharmony_ci * A hardware driver might override this function if, for example, the 1264bf215546Sopenharmony_ci * max 3D texture size is 512x512x64 (i.e. not a cube). 1265bf215546Sopenharmony_ci * 1266bf215546Sopenharmony_ci * Note that width, height, depth == 0 is not an error. However, a 1267bf215546Sopenharmony_ci * texture with zero width/height/depth will be considered "incomplete" 1268bf215546Sopenharmony_ci * and texturing will effectively be disabled. 1269bf215546Sopenharmony_ci * 1270bf215546Sopenharmony_ci * \param target any texture target/type 1271bf215546Sopenharmony_ci * \param numLevels number of mipmap levels in the texture or 0 if not known 1272bf215546Sopenharmony_ci * \param level as passed to glTexImage 1273bf215546Sopenharmony_ci * \param format the MESA_FORMAT_x for the tex image 1274bf215546Sopenharmony_ci * \param numSamples number of samples per texel 1275bf215546Sopenharmony_ci * \param width as passed to glTexImage 1276bf215546Sopenharmony_ci * \param height as passed to glTexImage 1277bf215546Sopenharmony_ci * \param depth as passed to glTexImage 1278bf215546Sopenharmony_ci * \return GL_TRUE if the image is acceptable, GL_FALSE if not acceptable. 1279bf215546Sopenharmony_ci */ 1280bf215546Sopenharmony_ciGLboolean 1281bf215546Sopenharmony_ci_mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, 1282bf215546Sopenharmony_ci GLuint numLevels, ASSERTED GLint level, 1283bf215546Sopenharmony_ci mesa_format format, GLuint numSamples, 1284bf215546Sopenharmony_ci GLint width, GLint height, GLint depth) 1285bf215546Sopenharmony_ci{ 1286bf215546Sopenharmony_ci uint64_t bytes, mbytes; 1287bf215546Sopenharmony_ci 1288bf215546Sopenharmony_ci if (numLevels > 0) { 1289bf215546Sopenharmony_ci /* Compute total memory for a whole mipmap. This is the path 1290bf215546Sopenharmony_ci * taken for glTexStorage(GL_PROXY_TEXTURE_x). 1291bf215546Sopenharmony_ci */ 1292bf215546Sopenharmony_ci unsigned l; 1293bf215546Sopenharmony_ci 1294bf215546Sopenharmony_ci assert(level == 0); 1295bf215546Sopenharmony_ci 1296bf215546Sopenharmony_ci bytes = 0; 1297bf215546Sopenharmony_ci 1298bf215546Sopenharmony_ci for (l = 0; l < numLevels; l++) { 1299bf215546Sopenharmony_ci GLint nextWidth, nextHeight, nextDepth; 1300bf215546Sopenharmony_ci 1301bf215546Sopenharmony_ci bytes += _mesa_format_image_size64(format, width, height, depth); 1302bf215546Sopenharmony_ci 1303bf215546Sopenharmony_ci if (_mesa_next_mipmap_level_size(target, 0, width, height, depth, 1304bf215546Sopenharmony_ci &nextWidth, &nextHeight, 1305bf215546Sopenharmony_ci &nextDepth)) { 1306bf215546Sopenharmony_ci width = nextWidth; 1307bf215546Sopenharmony_ci height = nextHeight; 1308bf215546Sopenharmony_ci depth = nextDepth; 1309bf215546Sopenharmony_ci } else { 1310bf215546Sopenharmony_ci break; 1311bf215546Sopenharmony_ci } 1312bf215546Sopenharmony_ci } 1313bf215546Sopenharmony_ci } else { 1314bf215546Sopenharmony_ci /* We just compute the size of one mipmap level. This is the path 1315bf215546Sopenharmony_ci * taken for glTexImage(GL_PROXY_TEXTURE_x). 1316bf215546Sopenharmony_ci */ 1317bf215546Sopenharmony_ci bytes = _mesa_format_image_size64(format, width, height, depth); 1318bf215546Sopenharmony_ci } 1319bf215546Sopenharmony_ci 1320bf215546Sopenharmony_ci bytes *= _mesa_num_tex_faces(target); 1321bf215546Sopenharmony_ci bytes *= MAX2(1, numSamples); 1322bf215546Sopenharmony_ci 1323bf215546Sopenharmony_ci mbytes = bytes / (1024 * 1024); /* convert to MB */ 1324bf215546Sopenharmony_ci 1325bf215546Sopenharmony_ci /* We just check if the image size is less than MaxTextureMbytes. 1326bf215546Sopenharmony_ci * Some drivers may do more specific checks. 1327bf215546Sopenharmony_ci */ 1328bf215546Sopenharmony_ci return mbytes <= (uint64_t) ctx->Const.MaxTextureMbytes; 1329bf215546Sopenharmony_ci} 1330bf215546Sopenharmony_ci 1331bf215546Sopenharmony_ci 1332bf215546Sopenharmony_ci/** 1333bf215546Sopenharmony_ci * Return true if the format is only valid for glCompressedTexImage. 1334bf215546Sopenharmony_ci */ 1335bf215546Sopenharmony_cistatic bool 1336bf215546Sopenharmony_cicompressedteximage_only_format(GLenum format) 1337bf215546Sopenharmony_ci{ 1338bf215546Sopenharmony_ci switch (format) { 1339bf215546Sopenharmony_ci case GL_PALETTE4_RGB8_OES: 1340bf215546Sopenharmony_ci case GL_PALETTE4_RGBA8_OES: 1341bf215546Sopenharmony_ci case GL_PALETTE4_R5_G6_B5_OES: 1342bf215546Sopenharmony_ci case GL_PALETTE4_RGBA4_OES: 1343bf215546Sopenharmony_ci case GL_PALETTE4_RGB5_A1_OES: 1344bf215546Sopenharmony_ci case GL_PALETTE8_RGB8_OES: 1345bf215546Sopenharmony_ci case GL_PALETTE8_RGBA8_OES: 1346bf215546Sopenharmony_ci case GL_PALETTE8_R5_G6_B5_OES: 1347bf215546Sopenharmony_ci case GL_PALETTE8_RGBA4_OES: 1348bf215546Sopenharmony_ci case GL_PALETTE8_RGB5_A1_OES: 1349bf215546Sopenharmony_ci case GL_ATC_RGB_AMD: 1350bf215546Sopenharmony_ci case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD: 1351bf215546Sopenharmony_ci case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: 1352bf215546Sopenharmony_ci return true; 1353bf215546Sopenharmony_ci default: 1354bf215546Sopenharmony_ci return false; 1355bf215546Sopenharmony_ci } 1356bf215546Sopenharmony_ci} 1357bf215546Sopenharmony_ci 1358bf215546Sopenharmony_ci/** 1359bf215546Sopenharmony_ci * Return true if the format doesn't support online compression. 1360bf215546Sopenharmony_ci */ 1361bf215546Sopenharmony_cibool 1362bf215546Sopenharmony_ci_mesa_format_no_online_compression(GLenum format) 1363bf215546Sopenharmony_ci{ 1364bf215546Sopenharmony_ci return _mesa_is_astc_format(format) || 1365bf215546Sopenharmony_ci _mesa_is_etc2_format(format) || 1366bf215546Sopenharmony_ci compressedteximage_only_format(format); 1367bf215546Sopenharmony_ci} 1368bf215546Sopenharmony_ci 1369bf215546Sopenharmony_ci/* Writes to an GL error pointer if non-null and returns whether or not the 1370bf215546Sopenharmony_ci * error is GL_NO_ERROR */ 1371bf215546Sopenharmony_cistatic bool 1372bf215546Sopenharmony_ciwrite_error(GLenum *err_ptr, GLenum error) 1373bf215546Sopenharmony_ci{ 1374bf215546Sopenharmony_ci if (err_ptr) 1375bf215546Sopenharmony_ci *err_ptr = error; 1376bf215546Sopenharmony_ci 1377bf215546Sopenharmony_ci return error == GL_NO_ERROR; 1378bf215546Sopenharmony_ci} 1379bf215546Sopenharmony_ci 1380bf215546Sopenharmony_ci/** 1381bf215546Sopenharmony_ci * Helper function to determine whether a target and specific compression 1382bf215546Sopenharmony_ci * format are supported. The error parameter returns GL_NO_ERROR if the 1383bf215546Sopenharmony_ci * target can be compressed. Otherwise it returns either GL_INVALID_OPERATION 1384bf215546Sopenharmony_ci * or GL_INVALID_ENUM, whichever is more appropriate. 1385bf215546Sopenharmony_ci */ 1386bf215546Sopenharmony_ciGLboolean 1387bf215546Sopenharmony_ci_mesa_target_can_be_compressed(const struct gl_context *ctx, GLenum target, 1388bf215546Sopenharmony_ci GLenum intFormat, GLenum *error) 1389bf215546Sopenharmony_ci{ 1390bf215546Sopenharmony_ci GLboolean target_can_be_compresed = GL_FALSE; 1391bf215546Sopenharmony_ci mesa_format format = _mesa_glenum_to_compressed_format(intFormat); 1392bf215546Sopenharmony_ci enum mesa_format_layout layout = _mesa_get_format_layout(format); 1393bf215546Sopenharmony_ci 1394bf215546Sopenharmony_ci switch (target) { 1395bf215546Sopenharmony_ci case GL_TEXTURE_2D: 1396bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D: 1397bf215546Sopenharmony_ci target_can_be_compresed = GL_TRUE; /* true for any compressed format so far */ 1398bf215546Sopenharmony_ci break; 1399bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_CUBE_MAP: 1400bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP: 1401bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1402bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1403bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1404bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1405bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1406bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1407bf215546Sopenharmony_ci target_can_be_compresed = GL_TRUE; 1408bf215546Sopenharmony_ci break; 1409bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 1410bf215546Sopenharmony_ci case GL_TEXTURE_2D_ARRAY_EXT: 1411bf215546Sopenharmony_ci target_can_be_compresed = ctx->Extensions.EXT_texture_array; 1412bf215546Sopenharmony_ci break; 1413bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 1414bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_ARRAY: 1415bf215546Sopenharmony_ci /* From the KHR_texture_compression_astc_hdr spec: 1416bf215546Sopenharmony_ci * 1417bf215546Sopenharmony_ci * Add a second new column "3D Tex." which is empty for all non-ASTC 1418bf215546Sopenharmony_ci * formats. If only the LDR profile is supported by the 1419bf215546Sopenharmony_ci * implementation, this column is also empty for all ASTC formats. If 1420bf215546Sopenharmony_ci * both the LDR and HDR profiles are supported only, this column is 1421bf215546Sopenharmony_ci * checked for all ASTC formats. 1422bf215546Sopenharmony_ci * 1423bf215546Sopenharmony_ci * Add a third new column "Cube Map Array Tex." which is empty for all 1424bf215546Sopenharmony_ci * non-ASTC formats, and checked for all ASTC formats. 1425bf215546Sopenharmony_ci * 1426bf215546Sopenharmony_ci * and, 1427bf215546Sopenharmony_ci * 1428bf215546Sopenharmony_ci * 'An INVALID_OPERATION error is generated by CompressedTexImage3D 1429bf215546Sopenharmony_ci * if <internalformat> is TEXTURE_CUBE_MAP_ARRAY and the 1430bf215546Sopenharmony_ci * "Cube Map Array" column of table 8.19 is *not* checked, or if 1431bf215546Sopenharmony_ci * <internalformat> is TEXTURE_3D and the "3D Tex." column of table 1432bf215546Sopenharmony_ci * 8.19 is *not* checked' 1433bf215546Sopenharmony_ci * 1434bf215546Sopenharmony_ci * The instances of <internalformat> above should say <target>. 1435bf215546Sopenharmony_ci * 1436bf215546Sopenharmony_ci * ETC2/EAC formats are the only alternative in GLES and thus such errors 1437bf215546Sopenharmony_ci * have already been handled by normal ETC2/EAC behavior. 1438bf215546Sopenharmony_ci */ 1439bf215546Sopenharmony_ci 1440bf215546Sopenharmony_ci /* From section 3.8.6, page 146 of OpenGL ES 3.0 spec: 1441bf215546Sopenharmony_ci * 1442bf215546Sopenharmony_ci * "The ETC2/EAC texture compression algorithm supports only 1443bf215546Sopenharmony_ci * two-dimensional images. If internalformat is an ETC2/EAC format, 1444bf215546Sopenharmony_ci * glCompressedTexImage3D will generate an INVALID_OPERATION error if 1445bf215546Sopenharmony_ci * target is not TEXTURE_2D_ARRAY." 1446bf215546Sopenharmony_ci * 1447bf215546Sopenharmony_ci * This should also be applicable for glTexStorage3D(). Other available 1448bf215546Sopenharmony_ci * targets for these functions are: TEXTURE_3D and TEXTURE_CUBE_MAP_ARRAY. 1449bf215546Sopenharmony_ci * 1450bf215546Sopenharmony_ci * Section 8.7, page 179 of OpenGL ES 3.2 adds: 1451bf215546Sopenharmony_ci * 1452bf215546Sopenharmony_ci * An INVALID_OPERATION error is generated by CompressedTexImage3D 1453bf215546Sopenharmony_ci * if internalformat is one of the the formats in table 8.17 and target is 1454bf215546Sopenharmony_ci * not TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP_ARRAY or TEXTURE_3D. 1455bf215546Sopenharmony_ci * 1456bf215546Sopenharmony_ci * An INVALID_OPERATION error is generated by CompressedTexImage3D 1457bf215546Sopenharmony_ci * if internalformat is TEXTURE_CUBE_MAP_ARRAY and the “Cube Map 1458bf215546Sopenharmony_ci * Array” column of table 8.17 is not checked, or if internalformat 1459bf215546Sopenharmony_ci * is TEXTURE_- 3D and the “3D Tex.” column of table 8.17 is not 1460bf215546Sopenharmony_ci * checked. 1461bf215546Sopenharmony_ci * 1462bf215546Sopenharmony_ci * The instances of <internalformat> above should say <target>. 1463bf215546Sopenharmony_ci * 1464bf215546Sopenharmony_ci * Such table 8.17 has checked "Cube Map Array" column for all the 1465bf215546Sopenharmony_ci * cases. So in practice, TEXTURE_CUBE_MAP_ARRAY is now valid for OpenGL ES 3.2 1466bf215546Sopenharmony_ci */ 1467bf215546Sopenharmony_ci if (layout == MESA_FORMAT_LAYOUT_ETC2 && _mesa_is_gles3(ctx) && 1468bf215546Sopenharmony_ci !_mesa_is_gles32(ctx)) 1469bf215546Sopenharmony_ci return write_error(error, GL_INVALID_OPERATION); 1470bf215546Sopenharmony_ci target_can_be_compresed = _mesa_has_texture_cube_map_array(ctx); 1471bf215546Sopenharmony_ci break; 1472bf215546Sopenharmony_ci case GL_TEXTURE_3D: 1473bf215546Sopenharmony_ci switch (layout) { 1474bf215546Sopenharmony_ci case MESA_FORMAT_LAYOUT_ETC2: 1475bf215546Sopenharmony_ci /* See ETC2/EAC comment in case GL_TEXTURE_CUBE_MAP_ARRAY. */ 1476bf215546Sopenharmony_ci if (_mesa_is_gles3(ctx)) 1477bf215546Sopenharmony_ci return write_error(error, GL_INVALID_OPERATION); 1478bf215546Sopenharmony_ci break; 1479bf215546Sopenharmony_ci case MESA_FORMAT_LAYOUT_BPTC: 1480bf215546Sopenharmony_ci target_can_be_compresed = ctx->Extensions.ARB_texture_compression_bptc; 1481bf215546Sopenharmony_ci break; 1482bf215546Sopenharmony_ci case MESA_FORMAT_LAYOUT_ASTC: 1483bf215546Sopenharmony_ci target_can_be_compresed = 1484bf215546Sopenharmony_ci ctx->Extensions.KHR_texture_compression_astc_hdr || 1485bf215546Sopenharmony_ci ctx->Extensions.KHR_texture_compression_astc_sliced_3d; 1486bf215546Sopenharmony_ci 1487bf215546Sopenharmony_ci /* Throw an INVALID_OPERATION error if the target is TEXTURE_3D and 1488bf215546Sopenharmony_ci * neither of the above extensions are supported. See comment in 1489bf215546Sopenharmony_ci * switch case GL_TEXTURE_CUBE_MAP_ARRAY for more info. 1490bf215546Sopenharmony_ci */ 1491bf215546Sopenharmony_ci if (!target_can_be_compresed) 1492bf215546Sopenharmony_ci return write_error(error, GL_INVALID_OPERATION); 1493bf215546Sopenharmony_ci break; 1494bf215546Sopenharmony_ci default: 1495bf215546Sopenharmony_ci break; 1496bf215546Sopenharmony_ci } 1497bf215546Sopenharmony_ci FALLTHROUGH; 1498bf215546Sopenharmony_ci default: 1499bf215546Sopenharmony_ci break; 1500bf215546Sopenharmony_ci } 1501bf215546Sopenharmony_ci return write_error(error, 1502bf215546Sopenharmony_ci target_can_be_compresed ? GL_NO_ERROR : GL_INVALID_ENUM); 1503bf215546Sopenharmony_ci} 1504bf215546Sopenharmony_ci 1505bf215546Sopenharmony_ci 1506bf215546Sopenharmony_ci/** 1507bf215546Sopenharmony_ci * Check if the given texture target value is legal for a 1508bf215546Sopenharmony_ci * glTexImage1/2/3D call. 1509bf215546Sopenharmony_ci */ 1510bf215546Sopenharmony_cistatic GLboolean 1511bf215546Sopenharmony_cilegal_teximage_target(struct gl_context *ctx, GLuint dims, GLenum target) 1512bf215546Sopenharmony_ci{ 1513bf215546Sopenharmony_ci switch (dims) { 1514bf215546Sopenharmony_ci case 1: 1515bf215546Sopenharmony_ci switch (target) { 1516bf215546Sopenharmony_ci case GL_TEXTURE_1D: 1517bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_1D: 1518bf215546Sopenharmony_ci return _mesa_is_desktop_gl(ctx); 1519bf215546Sopenharmony_ci default: 1520bf215546Sopenharmony_ci return GL_FALSE; 1521bf215546Sopenharmony_ci } 1522bf215546Sopenharmony_ci case 2: 1523bf215546Sopenharmony_ci switch (target) { 1524bf215546Sopenharmony_ci case GL_TEXTURE_2D: 1525bf215546Sopenharmony_ci return GL_TRUE; 1526bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D: 1527bf215546Sopenharmony_ci return _mesa_is_desktop_gl(ctx); 1528bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_CUBE_MAP: 1529bf215546Sopenharmony_ci return _mesa_is_desktop_gl(ctx); 1530bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1531bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1532bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1533bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1534bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1535bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1536bf215546Sopenharmony_ci return GL_TRUE; 1537bf215546Sopenharmony_ci case GL_TEXTURE_RECTANGLE_NV: 1538bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_RECTANGLE_NV: 1539bf215546Sopenharmony_ci return _mesa_is_desktop_gl(ctx) 1540bf215546Sopenharmony_ci && ctx->Extensions.NV_texture_rectangle; 1541bf215546Sopenharmony_ci case GL_TEXTURE_1D_ARRAY_EXT: 1542bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 1543bf215546Sopenharmony_ci return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array; 1544bf215546Sopenharmony_ci default: 1545bf215546Sopenharmony_ci return GL_FALSE; 1546bf215546Sopenharmony_ci } 1547bf215546Sopenharmony_ci case 3: 1548bf215546Sopenharmony_ci switch (target) { 1549bf215546Sopenharmony_ci case GL_TEXTURE_3D: 1550bf215546Sopenharmony_ci return GL_TRUE; 1551bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_3D: 1552bf215546Sopenharmony_ci return _mesa_is_desktop_gl(ctx); 1553bf215546Sopenharmony_ci case GL_TEXTURE_2D_ARRAY_EXT: 1554bf215546Sopenharmony_ci return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array) 1555bf215546Sopenharmony_ci || _mesa_is_gles3(ctx); 1556bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 1557bf215546Sopenharmony_ci return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array; 1558bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_ARRAY: 1559bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 1560bf215546Sopenharmony_ci return _mesa_has_texture_cube_map_array(ctx); 1561bf215546Sopenharmony_ci default: 1562bf215546Sopenharmony_ci return GL_FALSE; 1563bf215546Sopenharmony_ci } 1564bf215546Sopenharmony_ci default: 1565bf215546Sopenharmony_ci _mesa_problem(ctx, "invalid dims=%u in legal_teximage_target()", dims); 1566bf215546Sopenharmony_ci return GL_FALSE; 1567bf215546Sopenharmony_ci } 1568bf215546Sopenharmony_ci} 1569bf215546Sopenharmony_ci 1570bf215546Sopenharmony_ci 1571bf215546Sopenharmony_ci/** 1572bf215546Sopenharmony_ci * Check if the given texture target value is legal for a 1573bf215546Sopenharmony_ci * glTexSubImage, glCopyTexSubImage or glCopyTexImage call. 1574bf215546Sopenharmony_ci * The difference compared to legal_teximage_target() above is that 1575bf215546Sopenharmony_ci * proxy targets are not supported. 1576bf215546Sopenharmony_ci */ 1577bf215546Sopenharmony_cistatic GLboolean 1578bf215546Sopenharmony_cilegal_texsubimage_target(struct gl_context *ctx, GLuint dims, GLenum target, 1579bf215546Sopenharmony_ci bool dsa) 1580bf215546Sopenharmony_ci{ 1581bf215546Sopenharmony_ci switch (dims) { 1582bf215546Sopenharmony_ci case 1: 1583bf215546Sopenharmony_ci return _mesa_is_desktop_gl(ctx) && target == GL_TEXTURE_1D; 1584bf215546Sopenharmony_ci case 2: 1585bf215546Sopenharmony_ci switch (target) { 1586bf215546Sopenharmony_ci case GL_TEXTURE_2D: 1587bf215546Sopenharmony_ci return GL_TRUE; 1588bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1589bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1590bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1591bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1592bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1593bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1594bf215546Sopenharmony_ci return GL_TRUE; 1595bf215546Sopenharmony_ci case GL_TEXTURE_RECTANGLE_NV: 1596bf215546Sopenharmony_ci return _mesa_is_desktop_gl(ctx) 1597bf215546Sopenharmony_ci && ctx->Extensions.NV_texture_rectangle; 1598bf215546Sopenharmony_ci case GL_TEXTURE_1D_ARRAY_EXT: 1599bf215546Sopenharmony_ci return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array; 1600bf215546Sopenharmony_ci default: 1601bf215546Sopenharmony_ci return GL_FALSE; 1602bf215546Sopenharmony_ci } 1603bf215546Sopenharmony_ci case 3: 1604bf215546Sopenharmony_ci switch (target) { 1605bf215546Sopenharmony_ci case GL_TEXTURE_3D: 1606bf215546Sopenharmony_ci return GL_TRUE; 1607bf215546Sopenharmony_ci case GL_TEXTURE_2D_ARRAY_EXT: 1608bf215546Sopenharmony_ci return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array) 1609bf215546Sopenharmony_ci || _mesa_is_gles3(ctx); 1610bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_ARRAY: 1611bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 1612bf215546Sopenharmony_ci return _mesa_has_texture_cube_map_array(ctx); 1613bf215546Sopenharmony_ci 1614bf215546Sopenharmony_ci /* Table 8.15 of the OpenGL 4.5 core profile spec 1615bf215546Sopenharmony_ci * (20141030) says that TEXTURE_CUBE_MAP is valid for TextureSubImage3D 1616bf215546Sopenharmony_ci * and CopyTextureSubImage3D. 1617bf215546Sopenharmony_ci */ 1618bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP: 1619bf215546Sopenharmony_ci return dsa; 1620bf215546Sopenharmony_ci default: 1621bf215546Sopenharmony_ci return GL_FALSE; 1622bf215546Sopenharmony_ci } 1623bf215546Sopenharmony_ci default: 1624bf215546Sopenharmony_ci _mesa_problem(ctx, "invalid dims=%u in legal_texsubimage_target()", 1625bf215546Sopenharmony_ci dims); 1626bf215546Sopenharmony_ci return GL_FALSE; 1627bf215546Sopenharmony_ci } 1628bf215546Sopenharmony_ci} 1629bf215546Sopenharmony_ci 1630bf215546Sopenharmony_ci 1631bf215546Sopenharmony_ci/** 1632bf215546Sopenharmony_ci * Helper function to determine if a texture object is mutable (in terms 1633bf215546Sopenharmony_ci * of GL_ARB_texture_storage/GL_ARB_bindless_texture). 1634bf215546Sopenharmony_ci */ 1635bf215546Sopenharmony_cistatic GLboolean 1636bf215546Sopenharmony_cimutable_tex_object(struct gl_texture_object *texObj) 1637bf215546Sopenharmony_ci{ 1638bf215546Sopenharmony_ci if (!texObj) 1639bf215546Sopenharmony_ci return GL_FALSE; 1640bf215546Sopenharmony_ci 1641bf215546Sopenharmony_ci if (texObj->HandleAllocated) { 1642bf215546Sopenharmony_ci /* The ARB_bindless_texture spec says: 1643bf215546Sopenharmony_ci * 1644bf215546Sopenharmony_ci * "The error INVALID_OPERATION is generated by TexImage*, CopyTexImage*, 1645bf215546Sopenharmony_ci * CompressedTexImage*, TexBuffer*, TexParameter*, as well as other 1646bf215546Sopenharmony_ci * functions defined in terms of these, if the texture object to be 1647bf215546Sopenharmony_ci * modified is referenced by one or more texture or image handles." 1648bf215546Sopenharmony_ci */ 1649bf215546Sopenharmony_ci return GL_FALSE; 1650bf215546Sopenharmony_ci } 1651bf215546Sopenharmony_ci 1652bf215546Sopenharmony_ci return !texObj->Immutable; 1653bf215546Sopenharmony_ci} 1654bf215546Sopenharmony_ci 1655bf215546Sopenharmony_ci 1656bf215546Sopenharmony_ci/** 1657bf215546Sopenharmony_ci * Return expected size of a compressed texture. 1658bf215546Sopenharmony_ci */ 1659bf215546Sopenharmony_cistatic GLuint 1660bf215546Sopenharmony_cicompressed_tex_size(GLsizei width, GLsizei height, GLsizei depth, 1661bf215546Sopenharmony_ci GLenum glformat) 1662bf215546Sopenharmony_ci{ 1663bf215546Sopenharmony_ci mesa_format mesaFormat = _mesa_glenum_to_compressed_format(glformat); 1664bf215546Sopenharmony_ci return _mesa_format_image_size(mesaFormat, width, height, depth); 1665bf215546Sopenharmony_ci} 1666bf215546Sopenharmony_ci 1667bf215546Sopenharmony_ci/** 1668bf215546Sopenharmony_ci * Verify that a texture format is valid with a particular target 1669bf215546Sopenharmony_ci * 1670bf215546Sopenharmony_ci * In particular, textures with base format of \c GL_DEPTH_COMPONENT or 1671bf215546Sopenharmony_ci * \c GL_DEPTH_STENCIL are only valid with certain, context dependent texture 1672bf215546Sopenharmony_ci * targets. 1673bf215546Sopenharmony_ci * 1674bf215546Sopenharmony_ci * \param ctx GL context 1675bf215546Sopenharmony_ci * \param target Texture target 1676bf215546Sopenharmony_ci * \param internalFormat Internal format of the texture image 1677bf215546Sopenharmony_ci * 1678bf215546Sopenharmony_ci * \returns true if the combination is legal, false otherwise. 1679bf215546Sopenharmony_ci */ 1680bf215546Sopenharmony_cibool 1681bf215546Sopenharmony_ci_mesa_legal_texture_base_format_for_target(struct gl_context *ctx, 1682bf215546Sopenharmony_ci GLenum target, GLenum internalFormat) 1683bf215546Sopenharmony_ci{ 1684bf215546Sopenharmony_ci if (_mesa_base_tex_format(ctx, internalFormat) == GL_DEPTH_COMPONENT 1685bf215546Sopenharmony_ci || _mesa_base_tex_format(ctx, internalFormat) == GL_DEPTH_STENCIL 1686bf215546Sopenharmony_ci || _mesa_base_tex_format(ctx, internalFormat) == GL_STENCIL_INDEX) { 1687bf215546Sopenharmony_ci /* Section 3.8.3 (Texture Image Specification) of the OpenGL 3.3 Core 1688bf215546Sopenharmony_ci * Profile spec says: 1689bf215546Sopenharmony_ci * 1690bf215546Sopenharmony_ci * "Textures with a base internal format of DEPTH_COMPONENT or 1691bf215546Sopenharmony_ci * DEPTH_STENCIL are supported by texture image specification 1692bf215546Sopenharmony_ci * commands only if target is TEXTURE_1D, TEXTURE_2D, 1693bf215546Sopenharmony_ci * TEXTURE_1D_ARRAY, TEXTURE_2D_ARRAY, TEXTURE_RECTANGLE, 1694bf215546Sopenharmony_ci * TEXTURE_CUBE_MAP, PROXY_TEXTURE_1D, PROXY_TEXTURE_2D, 1695bf215546Sopenharmony_ci * PROXY_TEXTURE_1D_ARRAY, PROXY_TEXTURE_2D_ARRAY, 1696bf215546Sopenharmony_ci * PROXY_TEXTURE_RECTANGLE, or PROXY_TEXTURE_CUBE_MAP. Using these 1697bf215546Sopenharmony_ci * formats in conjunction with any other target will result in an 1698bf215546Sopenharmony_ci * INVALID_OPERATION error." 1699bf215546Sopenharmony_ci * 1700bf215546Sopenharmony_ci * Cubemaps are only supported with desktop OpenGL version >= 3.0, 1701bf215546Sopenharmony_ci * EXT_gpu_shader4, or, on OpenGL ES 2.0+, OES_depth_texture_cube_map. 1702bf215546Sopenharmony_ci */ 1703bf215546Sopenharmony_ci if (target != GL_TEXTURE_1D && 1704bf215546Sopenharmony_ci target != GL_PROXY_TEXTURE_1D && 1705bf215546Sopenharmony_ci target != GL_TEXTURE_2D && 1706bf215546Sopenharmony_ci target != GL_PROXY_TEXTURE_2D && 1707bf215546Sopenharmony_ci target != GL_TEXTURE_1D_ARRAY && 1708bf215546Sopenharmony_ci target != GL_PROXY_TEXTURE_1D_ARRAY && 1709bf215546Sopenharmony_ci target != GL_TEXTURE_2D_ARRAY && 1710bf215546Sopenharmony_ci target != GL_PROXY_TEXTURE_2D_ARRAY && 1711bf215546Sopenharmony_ci target != GL_TEXTURE_RECTANGLE_ARB && 1712bf215546Sopenharmony_ci target != GL_PROXY_TEXTURE_RECTANGLE_ARB && 1713bf215546Sopenharmony_ci !((_mesa_is_cube_face(target) || 1714bf215546Sopenharmony_ci target == GL_TEXTURE_CUBE_MAP || 1715bf215546Sopenharmony_ci target == GL_PROXY_TEXTURE_CUBE_MAP) && 1716bf215546Sopenharmony_ci (ctx->Version >= 30 || ctx->Extensions.EXT_gpu_shader4 1717bf215546Sopenharmony_ci || (ctx->API == API_OPENGLES2 && ctx->Extensions.OES_depth_texture_cube_map))) && 1718bf215546Sopenharmony_ci !((target == GL_TEXTURE_CUBE_MAP_ARRAY || 1719bf215546Sopenharmony_ci target == GL_PROXY_TEXTURE_CUBE_MAP_ARRAY) && 1720bf215546Sopenharmony_ci _mesa_has_texture_cube_map_array(ctx))) { 1721bf215546Sopenharmony_ci return false; 1722bf215546Sopenharmony_ci } 1723bf215546Sopenharmony_ci } 1724bf215546Sopenharmony_ci 1725bf215546Sopenharmony_ci return true; 1726bf215546Sopenharmony_ci} 1727bf215546Sopenharmony_ci 1728bf215546Sopenharmony_cistatic bool 1729bf215546Sopenharmony_citexture_formats_agree(GLenum internalFormat, 1730bf215546Sopenharmony_ci GLenum format) 1731bf215546Sopenharmony_ci{ 1732bf215546Sopenharmony_ci GLboolean colorFormat; 1733bf215546Sopenharmony_ci GLboolean is_format_depth_or_depthstencil; 1734bf215546Sopenharmony_ci GLboolean is_internalFormat_depth_or_depthstencil; 1735bf215546Sopenharmony_ci 1736bf215546Sopenharmony_ci /* Even though there are no color-index textures, we still have to support 1737bf215546Sopenharmony_ci * uploading color-index data and remapping it to RGB via the 1738bf215546Sopenharmony_ci * GL_PIXEL_MAP_I_TO_[RGBA] tables. 1739bf215546Sopenharmony_ci */ 1740bf215546Sopenharmony_ci const GLboolean indexFormat = (format == GL_COLOR_INDEX); 1741bf215546Sopenharmony_ci 1742bf215546Sopenharmony_ci is_internalFormat_depth_or_depthstencil = 1743bf215546Sopenharmony_ci _mesa_is_depth_format(internalFormat) || 1744bf215546Sopenharmony_ci _mesa_is_depthstencil_format(internalFormat); 1745bf215546Sopenharmony_ci 1746bf215546Sopenharmony_ci is_format_depth_or_depthstencil = 1747bf215546Sopenharmony_ci _mesa_is_depth_format(format) || 1748bf215546Sopenharmony_ci _mesa_is_depthstencil_format(format); 1749bf215546Sopenharmony_ci 1750bf215546Sopenharmony_ci colorFormat = _mesa_is_color_format(format); 1751bf215546Sopenharmony_ci 1752bf215546Sopenharmony_ci if (_mesa_is_color_format(internalFormat) && !colorFormat && !indexFormat) 1753bf215546Sopenharmony_ci return false; 1754bf215546Sopenharmony_ci 1755bf215546Sopenharmony_ci if (is_internalFormat_depth_or_depthstencil != 1756bf215546Sopenharmony_ci is_format_depth_or_depthstencil) 1757bf215546Sopenharmony_ci return false; 1758bf215546Sopenharmony_ci 1759bf215546Sopenharmony_ci if (_mesa_is_ycbcr_format(internalFormat) != _mesa_is_ycbcr_format(format)) 1760bf215546Sopenharmony_ci return false; 1761bf215546Sopenharmony_ci 1762bf215546Sopenharmony_ci return true; 1763bf215546Sopenharmony_ci} 1764bf215546Sopenharmony_ci 1765bf215546Sopenharmony_ci/** 1766bf215546Sopenharmony_ci * Test the combination of format, type and internal format arguments of 1767bf215546Sopenharmony_ci * different texture operations on GLES. 1768bf215546Sopenharmony_ci * 1769bf215546Sopenharmony_ci * \param ctx GL context. 1770bf215546Sopenharmony_ci * \param format pixel data format given by the user. 1771bf215546Sopenharmony_ci * \param type pixel data type given by the user. 1772bf215546Sopenharmony_ci * \param internalFormat internal format given by the user. 1773bf215546Sopenharmony_ci * \param callerName name of the caller function to print in the error message 1774bf215546Sopenharmony_ci * 1775bf215546Sopenharmony_ci * \return true if a error is found, false otherwise 1776bf215546Sopenharmony_ci * 1777bf215546Sopenharmony_ci * Currently, it is used by texture_error_check() and texsubimage_error_check(). 1778bf215546Sopenharmony_ci */ 1779bf215546Sopenharmony_cistatic bool 1780bf215546Sopenharmony_citexture_format_error_check_gles(struct gl_context *ctx, GLenum format, 1781bf215546Sopenharmony_ci GLenum type, GLenum internalFormat, const char *callerName) 1782bf215546Sopenharmony_ci{ 1783bf215546Sopenharmony_ci GLenum err = _mesa_gles_error_check_format_and_type(ctx, format, type, 1784bf215546Sopenharmony_ci internalFormat); 1785bf215546Sopenharmony_ci if (err != GL_NO_ERROR) { 1786bf215546Sopenharmony_ci _mesa_error(ctx, err, 1787bf215546Sopenharmony_ci "%s(format = %s, type = %s, internalformat = %s)", 1788bf215546Sopenharmony_ci callerName, _mesa_enum_to_string(format), 1789bf215546Sopenharmony_ci _mesa_enum_to_string(type), 1790bf215546Sopenharmony_ci _mesa_enum_to_string(internalFormat)); 1791bf215546Sopenharmony_ci return true; 1792bf215546Sopenharmony_ci } 1793bf215546Sopenharmony_ci 1794bf215546Sopenharmony_ci return false; 1795bf215546Sopenharmony_ci} 1796bf215546Sopenharmony_ci 1797bf215546Sopenharmony_ci/** 1798bf215546Sopenharmony_ci * Test the glTexImage[123]D() parameters for errors. 1799bf215546Sopenharmony_ci * 1800bf215546Sopenharmony_ci * \param ctx GL context. 1801bf215546Sopenharmony_ci * \param dimensions texture image dimensions (must be 1, 2 or 3). 1802bf215546Sopenharmony_ci * \param target texture target given by the user (already validated). 1803bf215546Sopenharmony_ci * \param level image level given by the user. 1804bf215546Sopenharmony_ci * \param internalFormat internal format given by the user. 1805bf215546Sopenharmony_ci * \param format pixel data format given by the user. 1806bf215546Sopenharmony_ci * \param type pixel data type given by the user. 1807bf215546Sopenharmony_ci * \param width image width given by the user. 1808bf215546Sopenharmony_ci * \param height image height given by the user. 1809bf215546Sopenharmony_ci * \param depth image depth given by the user. 1810bf215546Sopenharmony_ci * \param border image border given by the user. 1811bf215546Sopenharmony_ci * 1812bf215546Sopenharmony_ci * \return GL_TRUE if a error is found, GL_FALSE otherwise 1813bf215546Sopenharmony_ci * 1814bf215546Sopenharmony_ci * Verifies each of the parameters against the constants specified in 1815bf215546Sopenharmony_ci * __struct gl_contextRec::Const and the supported extensions, and according 1816bf215546Sopenharmony_ci * to the OpenGL specification. 1817bf215546Sopenharmony_ci * Note that we don't fully error-check the width, height, depth values 1818bf215546Sopenharmony_ci * here. That's done in _mesa_legal_texture_dimensions() which is used 1819bf215546Sopenharmony_ci * by several other GL entrypoints. Plus, texture dims have a special 1820bf215546Sopenharmony_ci * interaction with proxy textures. 1821bf215546Sopenharmony_ci */ 1822bf215546Sopenharmony_cistatic GLboolean 1823bf215546Sopenharmony_citexture_error_check( struct gl_context *ctx, 1824bf215546Sopenharmony_ci GLuint dimensions, GLenum target, 1825bf215546Sopenharmony_ci struct gl_texture_object* texObj, 1826bf215546Sopenharmony_ci GLint level, GLint internalFormat, 1827bf215546Sopenharmony_ci GLenum format, GLenum type, 1828bf215546Sopenharmony_ci GLint width, GLint height, 1829bf215546Sopenharmony_ci GLint depth, GLint border, 1830bf215546Sopenharmony_ci const GLvoid *pixels ) 1831bf215546Sopenharmony_ci{ 1832bf215546Sopenharmony_ci GLenum err; 1833bf215546Sopenharmony_ci 1834bf215546Sopenharmony_ci /* Note: for proxy textures, some error conditions immediately generate 1835bf215546Sopenharmony_ci * a GL error in the usual way. But others do not generate a GL error. 1836bf215546Sopenharmony_ci * Instead, they cause the width, height, depth, format fields of the 1837bf215546Sopenharmony_ci * texture image to be zeroed-out. The GL spec seems to indicate that the 1838bf215546Sopenharmony_ci * zero-out behaviour is only used in cases related to memory allocation. 1839bf215546Sopenharmony_ci */ 1840bf215546Sopenharmony_ci 1841bf215546Sopenharmony_ci /* level check */ 1842bf215546Sopenharmony_ci if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) { 1843bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, 1844bf215546Sopenharmony_ci "glTexImage%dD(level=%d)", dimensions, level); 1845bf215546Sopenharmony_ci return GL_TRUE; 1846bf215546Sopenharmony_ci } 1847bf215546Sopenharmony_ci 1848bf215546Sopenharmony_ci /* Check border */ 1849bf215546Sopenharmony_ci if (border < 0 || border > 1 || 1850bf215546Sopenharmony_ci ((ctx->API != API_OPENGL_COMPAT || 1851bf215546Sopenharmony_ci target == GL_TEXTURE_RECTANGLE_NV || 1852bf215546Sopenharmony_ci target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) { 1853bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, 1854bf215546Sopenharmony_ci "glTexImage%dD(border=%d)", dimensions, border); 1855bf215546Sopenharmony_ci return GL_TRUE; 1856bf215546Sopenharmony_ci } 1857bf215546Sopenharmony_ci 1858bf215546Sopenharmony_ci if (width < 0 || height < 0 || depth < 0) { 1859bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, 1860bf215546Sopenharmony_ci "glTexImage%dD(width, height or depth < 0)", dimensions); 1861bf215546Sopenharmony_ci return GL_TRUE; 1862bf215546Sopenharmony_ci } 1863bf215546Sopenharmony_ci 1864bf215546Sopenharmony_ci /* Check incoming image format and type */ 1865bf215546Sopenharmony_ci err = _mesa_error_check_format_and_type(ctx, format, type); 1866bf215546Sopenharmony_ci if (err != GL_NO_ERROR) { 1867bf215546Sopenharmony_ci /* Prior to OpenGL-ES 2.0, an INVALID_VALUE is expected instead of 1868bf215546Sopenharmony_ci * INVALID_ENUM. From page 73 OpenGL ES 1.1 spec: 1869bf215546Sopenharmony_ci * 1870bf215546Sopenharmony_ci * "Specifying a value for internalformat that is not one of the 1871bf215546Sopenharmony_ci * above (acceptable) values generates the error INVALID VALUE." 1872bf215546Sopenharmony_ci */ 1873bf215546Sopenharmony_ci if (err == GL_INVALID_ENUM && _mesa_is_gles(ctx) && ctx->Version < 20) 1874bf215546Sopenharmony_ci err = GL_INVALID_VALUE; 1875bf215546Sopenharmony_ci 1876bf215546Sopenharmony_ci _mesa_error(ctx, err, 1877bf215546Sopenharmony_ci "glTexImage%dD(incompatible format = %s, type = %s)", 1878bf215546Sopenharmony_ci dimensions, _mesa_enum_to_string(format), 1879bf215546Sopenharmony_ci _mesa_enum_to_string(type)); 1880bf215546Sopenharmony_ci return GL_TRUE; 1881bf215546Sopenharmony_ci } 1882bf215546Sopenharmony_ci 1883bf215546Sopenharmony_ci /* Check internalFormat */ 1884bf215546Sopenharmony_ci if (_mesa_base_tex_format(ctx, internalFormat) < 0) { 1885bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, 1886bf215546Sopenharmony_ci "glTexImage%dD(internalFormat=%s)", 1887bf215546Sopenharmony_ci dimensions, _mesa_enum_to_string(internalFormat)); 1888bf215546Sopenharmony_ci return GL_TRUE; 1889bf215546Sopenharmony_ci } 1890bf215546Sopenharmony_ci 1891bf215546Sopenharmony_ci /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the 1892bf215546Sopenharmony_ci * combinations of format, internalFormat, and type that can be used. 1893bf215546Sopenharmony_ci * Formats and types that require additional extensions (e.g., GL_FLOAT 1894bf215546Sopenharmony_ci * requires GL_OES_texture_float) are filtered elsewhere. 1895bf215546Sopenharmony_ci */ 1896bf215546Sopenharmony_ci char bufCallerName[20]; 1897bf215546Sopenharmony_ci snprintf(bufCallerName, 20, "glTexImage%dD", dimensions); 1898bf215546Sopenharmony_ci if (_mesa_is_gles(ctx) && 1899bf215546Sopenharmony_ci texture_format_error_check_gles(ctx, format, type, 1900bf215546Sopenharmony_ci internalFormat, bufCallerName)) { 1901bf215546Sopenharmony_ci return GL_TRUE; 1902bf215546Sopenharmony_ci } 1903bf215546Sopenharmony_ci 1904bf215546Sopenharmony_ci /* validate the bound PBO, if any */ 1905bf215546Sopenharmony_ci if (!_mesa_validate_pbo_source(ctx, dimensions, &ctx->Unpack, 1906bf215546Sopenharmony_ci width, height, depth, format, type, 1907bf215546Sopenharmony_ci INT_MAX, pixels, "glTexImage")) { 1908bf215546Sopenharmony_ci return GL_TRUE; 1909bf215546Sopenharmony_ci } 1910bf215546Sopenharmony_ci 1911bf215546Sopenharmony_ci /* make sure internal format and format basically agree */ 1912bf215546Sopenharmony_ci if (!texture_formats_agree(internalFormat, format)) { 1913bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 1914bf215546Sopenharmony_ci "glTexImage%dD(incompatible internalFormat = %s, format = %s)", 1915bf215546Sopenharmony_ci dimensions, _mesa_enum_to_string(internalFormat), 1916bf215546Sopenharmony_ci _mesa_enum_to_string(format)); 1917bf215546Sopenharmony_ci return GL_TRUE; 1918bf215546Sopenharmony_ci } 1919bf215546Sopenharmony_ci 1920bf215546Sopenharmony_ci /* additional checks for ycbcr textures */ 1921bf215546Sopenharmony_ci if (internalFormat == GL_YCBCR_MESA) { 1922bf215546Sopenharmony_ci assert(ctx->Extensions.MESA_ycbcr_texture); 1923bf215546Sopenharmony_ci if (type != GL_UNSIGNED_SHORT_8_8_MESA && 1924bf215546Sopenharmony_ci type != GL_UNSIGNED_SHORT_8_8_REV_MESA) { 1925bf215546Sopenharmony_ci char message[100]; 1926bf215546Sopenharmony_ci snprintf(message, sizeof(message), 1927bf215546Sopenharmony_ci "glTexImage%dD(format/type YCBCR mismatch)", 1928bf215546Sopenharmony_ci dimensions); 1929bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, "%s", message); 1930bf215546Sopenharmony_ci return GL_TRUE; /* error */ 1931bf215546Sopenharmony_ci } 1932bf215546Sopenharmony_ci if (target != GL_TEXTURE_2D && 1933bf215546Sopenharmony_ci target != GL_PROXY_TEXTURE_2D && 1934bf215546Sopenharmony_ci target != GL_TEXTURE_RECTANGLE_NV && 1935bf215546Sopenharmony_ci target != GL_PROXY_TEXTURE_RECTANGLE_NV) { 1936bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, 1937bf215546Sopenharmony_ci "glTexImage%dD(bad target for YCbCr texture)", 1938bf215546Sopenharmony_ci dimensions); 1939bf215546Sopenharmony_ci return GL_TRUE; 1940bf215546Sopenharmony_ci } 1941bf215546Sopenharmony_ci if (border != 0) { 1942bf215546Sopenharmony_ci char message[100]; 1943bf215546Sopenharmony_ci snprintf(message, sizeof(message), 1944bf215546Sopenharmony_ci "glTexImage%dD(format=GL_YCBCR_MESA and border=%d)", 1945bf215546Sopenharmony_ci dimensions, border); 1946bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, "%s", message); 1947bf215546Sopenharmony_ci return GL_TRUE; 1948bf215546Sopenharmony_ci } 1949bf215546Sopenharmony_ci } 1950bf215546Sopenharmony_ci 1951bf215546Sopenharmony_ci /* additional checks for depth textures */ 1952bf215546Sopenharmony_ci if (!_mesa_legal_texture_base_format_for_target(ctx, target, internalFormat)) { 1953bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 1954bf215546Sopenharmony_ci "glTexImage%dD(bad target for texture)", dimensions); 1955bf215546Sopenharmony_ci return GL_TRUE; 1956bf215546Sopenharmony_ci } 1957bf215546Sopenharmony_ci 1958bf215546Sopenharmony_ci /* additional checks for compressed textures */ 1959bf215546Sopenharmony_ci if (_mesa_is_compressed_format(ctx, internalFormat)) { 1960bf215546Sopenharmony_ci GLenum err; 1961bf215546Sopenharmony_ci if (!_mesa_target_can_be_compressed(ctx, target, internalFormat, &err)) { 1962bf215546Sopenharmony_ci _mesa_error(ctx, err, 1963bf215546Sopenharmony_ci "glTexImage%dD(target can't be compressed)", dimensions); 1964bf215546Sopenharmony_ci return GL_TRUE; 1965bf215546Sopenharmony_ci } 1966bf215546Sopenharmony_ci if (_mesa_format_no_online_compression(internalFormat)) { 1967bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 1968bf215546Sopenharmony_ci "glTexImage%dD(no compression for format)", dimensions); 1969bf215546Sopenharmony_ci return GL_TRUE; 1970bf215546Sopenharmony_ci } 1971bf215546Sopenharmony_ci if (border != 0) { 1972bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 1973bf215546Sopenharmony_ci "glTexImage%dD(border!=0)", dimensions); 1974bf215546Sopenharmony_ci return GL_TRUE; 1975bf215546Sopenharmony_ci } 1976bf215546Sopenharmony_ci } 1977bf215546Sopenharmony_ci 1978bf215546Sopenharmony_ci /* additional checks for integer textures */ 1979bf215546Sopenharmony_ci if ((ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) && 1980bf215546Sopenharmony_ci (_mesa_is_enum_format_integer(format) != 1981bf215546Sopenharmony_ci _mesa_is_enum_format_integer(internalFormat))) { 1982bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 1983bf215546Sopenharmony_ci "glTexImage%dD(integer/non-integer format mismatch)", 1984bf215546Sopenharmony_ci dimensions); 1985bf215546Sopenharmony_ci return GL_TRUE; 1986bf215546Sopenharmony_ci } 1987bf215546Sopenharmony_ci 1988bf215546Sopenharmony_ci if (!mutable_tex_object(texObj)) { 1989bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 1990bf215546Sopenharmony_ci "glTexImage%dD(immutable texture)", dimensions); 1991bf215546Sopenharmony_ci return GL_TRUE; 1992bf215546Sopenharmony_ci } 1993bf215546Sopenharmony_ci 1994bf215546Sopenharmony_ci /* if we get here, the parameters are OK */ 1995bf215546Sopenharmony_ci return GL_FALSE; 1996bf215546Sopenharmony_ci} 1997bf215546Sopenharmony_ci 1998bf215546Sopenharmony_ci 1999bf215546Sopenharmony_ci/** 2000bf215546Sopenharmony_ci * Error checking for glCompressedTexImage[123]D(). 2001bf215546Sopenharmony_ci * Note that the width, height and depth values are not fully error checked 2002bf215546Sopenharmony_ci * here. 2003bf215546Sopenharmony_ci * \return GL_TRUE if a error is found, GL_FALSE otherwise 2004bf215546Sopenharmony_ci */ 2005bf215546Sopenharmony_cistatic GLenum 2006bf215546Sopenharmony_cicompressed_texture_error_check(struct gl_context *ctx, GLint dimensions, 2007bf215546Sopenharmony_ci GLenum target, struct gl_texture_object* texObj, 2008bf215546Sopenharmony_ci GLint level, GLenum internalFormat, GLsizei width, 2009bf215546Sopenharmony_ci GLsizei height, GLsizei depth, GLint border, 2010bf215546Sopenharmony_ci GLsizei imageSize, const GLvoid *data) 2011bf215546Sopenharmony_ci{ 2012bf215546Sopenharmony_ci const GLint maxLevels = _mesa_max_texture_levels(ctx, target); 2013bf215546Sopenharmony_ci GLint expectedSize; 2014bf215546Sopenharmony_ci GLenum error = GL_NO_ERROR; 2015bf215546Sopenharmony_ci char *reason = ""; /* no error */ 2016bf215546Sopenharmony_ci 2017bf215546Sopenharmony_ci if (!_mesa_target_can_be_compressed(ctx, target, internalFormat, &error)) { 2018bf215546Sopenharmony_ci reason = "target"; 2019bf215546Sopenharmony_ci goto error; 2020bf215546Sopenharmony_ci } 2021bf215546Sopenharmony_ci 2022bf215546Sopenharmony_ci /* This will detect any invalid internalFormat value */ 2023bf215546Sopenharmony_ci if (!_mesa_is_compressed_format(ctx, internalFormat)) { 2024bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, 2025bf215546Sopenharmony_ci "glCompressedTexImage%dD(internalFormat=%s)", 2026bf215546Sopenharmony_ci dimensions, _mesa_enum_to_string(internalFormat)); 2027bf215546Sopenharmony_ci return GL_TRUE; 2028bf215546Sopenharmony_ci } 2029bf215546Sopenharmony_ci 2030bf215546Sopenharmony_ci /* validate the bound PBO, if any */ 2031bf215546Sopenharmony_ci if (!_mesa_validate_pbo_source_compressed(ctx, dimensions, &ctx->Unpack, 2032bf215546Sopenharmony_ci imageSize, data, 2033bf215546Sopenharmony_ci "glCompressedTexImage")) { 2034bf215546Sopenharmony_ci return GL_TRUE; 2035bf215546Sopenharmony_ci } 2036bf215546Sopenharmony_ci 2037bf215546Sopenharmony_ci switch (internalFormat) { 2038bf215546Sopenharmony_ci case GL_PALETTE4_RGB8_OES: 2039bf215546Sopenharmony_ci case GL_PALETTE4_RGBA8_OES: 2040bf215546Sopenharmony_ci case GL_PALETTE4_R5_G6_B5_OES: 2041bf215546Sopenharmony_ci case GL_PALETTE4_RGBA4_OES: 2042bf215546Sopenharmony_ci case GL_PALETTE4_RGB5_A1_OES: 2043bf215546Sopenharmony_ci case GL_PALETTE8_RGB8_OES: 2044bf215546Sopenharmony_ci case GL_PALETTE8_RGBA8_OES: 2045bf215546Sopenharmony_ci case GL_PALETTE8_R5_G6_B5_OES: 2046bf215546Sopenharmony_ci case GL_PALETTE8_RGBA4_OES: 2047bf215546Sopenharmony_ci case GL_PALETTE8_RGB5_A1_OES: 2048bf215546Sopenharmony_ci /* check level (note that level should be zero or less!) */ 2049bf215546Sopenharmony_ci if (level > 0 || level < -maxLevels) { 2050bf215546Sopenharmony_ci reason = "level"; 2051bf215546Sopenharmony_ci error = GL_INVALID_VALUE; 2052bf215546Sopenharmony_ci goto error; 2053bf215546Sopenharmony_ci } 2054bf215546Sopenharmony_ci 2055bf215546Sopenharmony_ci if (dimensions != 2) { 2056bf215546Sopenharmony_ci reason = "compressed paletted textures must be 2D"; 2057bf215546Sopenharmony_ci error = GL_INVALID_OPERATION; 2058bf215546Sopenharmony_ci goto error; 2059bf215546Sopenharmony_ci } 2060bf215546Sopenharmony_ci 2061bf215546Sopenharmony_ci /* Figure out the expected texture size (in bytes). This will be 2062bf215546Sopenharmony_ci * checked against the actual size later. 2063bf215546Sopenharmony_ci */ 2064bf215546Sopenharmony_ci expectedSize = _mesa_cpal_compressed_size(level, internalFormat, 2065bf215546Sopenharmony_ci width, height); 2066bf215546Sopenharmony_ci 2067bf215546Sopenharmony_ci /* This is for the benefit of the TestProxyTexImage below. It expects 2068bf215546Sopenharmony_ci * level to be non-negative. OES_compressed_paletted_texture uses a 2069bf215546Sopenharmony_ci * weird mechanism where the level specified to glCompressedTexImage2D 2070bf215546Sopenharmony_ci * is -(n-1) number of levels in the texture, and the data specifies the 2071bf215546Sopenharmony_ci * complete mipmap stack. This is done to ensure the palette is the 2072bf215546Sopenharmony_ci * same for all levels. 2073bf215546Sopenharmony_ci */ 2074bf215546Sopenharmony_ci level = -level; 2075bf215546Sopenharmony_ci break; 2076bf215546Sopenharmony_ci 2077bf215546Sopenharmony_ci default: 2078bf215546Sopenharmony_ci /* check level */ 2079bf215546Sopenharmony_ci if (level < 0 || level >= maxLevels) { 2080bf215546Sopenharmony_ci reason = "level"; 2081bf215546Sopenharmony_ci error = GL_INVALID_VALUE; 2082bf215546Sopenharmony_ci goto error; 2083bf215546Sopenharmony_ci } 2084bf215546Sopenharmony_ci 2085bf215546Sopenharmony_ci /* Figure out the expected texture size (in bytes). This will be 2086bf215546Sopenharmony_ci * checked against the actual size later. 2087bf215546Sopenharmony_ci */ 2088bf215546Sopenharmony_ci expectedSize = compressed_tex_size(width, height, depth, internalFormat); 2089bf215546Sopenharmony_ci break; 2090bf215546Sopenharmony_ci } 2091bf215546Sopenharmony_ci 2092bf215546Sopenharmony_ci /* This should really never fail */ 2093bf215546Sopenharmony_ci if (_mesa_base_tex_format(ctx, internalFormat) < 0) { 2094bf215546Sopenharmony_ci reason = "internalFormat"; 2095bf215546Sopenharmony_ci error = GL_INVALID_ENUM; 2096bf215546Sopenharmony_ci goto error; 2097bf215546Sopenharmony_ci } 2098bf215546Sopenharmony_ci 2099bf215546Sopenharmony_ci /* No compressed formats support borders at this time */ 2100bf215546Sopenharmony_ci if (border != 0) { 2101bf215546Sopenharmony_ci reason = "border != 0"; 2102bf215546Sopenharmony_ci error = _mesa_is_desktop_gl(ctx) ? GL_INVALID_OPERATION : GL_INVALID_VALUE; 2103bf215546Sopenharmony_ci goto error; 2104bf215546Sopenharmony_ci } 2105bf215546Sopenharmony_ci 2106bf215546Sopenharmony_ci /* Check for invalid pixel storage modes */ 2107bf215546Sopenharmony_ci if (!_mesa_compressed_pixel_storage_error_check(ctx, dimensions, 2108bf215546Sopenharmony_ci &ctx->Unpack, 2109bf215546Sopenharmony_ci "glCompressedTexImage")) { 2110bf215546Sopenharmony_ci return GL_FALSE; 2111bf215546Sopenharmony_ci } 2112bf215546Sopenharmony_ci 2113bf215546Sopenharmony_ci /* check image size in bytes */ 2114bf215546Sopenharmony_ci if (expectedSize != imageSize) { 2115bf215546Sopenharmony_ci /* Per GL_ARB_texture_compression: GL_INVALID_VALUE is generated [...] 2116bf215546Sopenharmony_ci * if <imageSize> is not consistent with the format, dimensions, and 2117bf215546Sopenharmony_ci * contents of the specified image. 2118bf215546Sopenharmony_ci */ 2119bf215546Sopenharmony_ci reason = "imageSize inconsistent with width/height/format"; 2120bf215546Sopenharmony_ci error = GL_INVALID_VALUE; 2121bf215546Sopenharmony_ci goto error; 2122bf215546Sopenharmony_ci } 2123bf215546Sopenharmony_ci 2124bf215546Sopenharmony_ci if (!mutable_tex_object(texObj)) { 2125bf215546Sopenharmony_ci reason = "immutable texture"; 2126bf215546Sopenharmony_ci error = GL_INVALID_OPERATION; 2127bf215546Sopenharmony_ci goto error; 2128bf215546Sopenharmony_ci } 2129bf215546Sopenharmony_ci 2130bf215546Sopenharmony_ci return GL_FALSE; 2131bf215546Sopenharmony_ci 2132bf215546Sopenharmony_cierror: 2133bf215546Sopenharmony_ci /* Note: not all error paths exit through here. */ 2134bf215546Sopenharmony_ci _mesa_error(ctx, error, "glCompressedTexImage%dD(%s)", 2135bf215546Sopenharmony_ci dimensions, reason); 2136bf215546Sopenharmony_ci return GL_TRUE; 2137bf215546Sopenharmony_ci} 2138bf215546Sopenharmony_ci 2139bf215546Sopenharmony_ci 2140bf215546Sopenharmony_ci 2141bf215546Sopenharmony_ci/** 2142bf215546Sopenharmony_ci * Test glTexSubImage[123]D() parameters for errors. 2143bf215546Sopenharmony_ci * 2144bf215546Sopenharmony_ci * \param ctx GL context. 2145bf215546Sopenharmony_ci * \param dimensions texture image dimensions (must be 1, 2 or 3). 2146bf215546Sopenharmony_ci * \param target texture target given by the user (already validated) 2147bf215546Sopenharmony_ci * \param level image level given by the user. 2148bf215546Sopenharmony_ci * \param xoffset sub-image x offset given by the user. 2149bf215546Sopenharmony_ci * \param yoffset sub-image y offset given by the user. 2150bf215546Sopenharmony_ci * \param zoffset sub-image z offset given by the user. 2151bf215546Sopenharmony_ci * \param format pixel data format given by the user. 2152bf215546Sopenharmony_ci * \param type pixel data type given by the user. 2153bf215546Sopenharmony_ci * \param width image width given by the user. 2154bf215546Sopenharmony_ci * \param height image height given by the user. 2155bf215546Sopenharmony_ci * \param depth image depth given by the user. 2156bf215546Sopenharmony_ci * 2157bf215546Sopenharmony_ci * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. 2158bf215546Sopenharmony_ci * 2159bf215546Sopenharmony_ci * Verifies each of the parameters against the constants specified in 2160bf215546Sopenharmony_ci * __struct gl_contextRec::Const and the supported extensions, and according 2161bf215546Sopenharmony_ci * to the OpenGL specification. 2162bf215546Sopenharmony_ci */ 2163bf215546Sopenharmony_cistatic GLboolean 2164bf215546Sopenharmony_citexsubimage_error_check(struct gl_context *ctx, GLuint dimensions, 2165bf215546Sopenharmony_ci struct gl_texture_object *texObj, 2166bf215546Sopenharmony_ci GLenum target, GLint level, 2167bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, GLint zoffset, 2168bf215546Sopenharmony_ci GLint width, GLint height, GLint depth, 2169bf215546Sopenharmony_ci GLenum format, GLenum type, const GLvoid *pixels, 2170bf215546Sopenharmony_ci const char *callerName) 2171bf215546Sopenharmony_ci{ 2172bf215546Sopenharmony_ci struct gl_texture_image *texImage; 2173bf215546Sopenharmony_ci GLenum err; 2174bf215546Sopenharmony_ci 2175bf215546Sopenharmony_ci if (!texObj) { 2176bf215546Sopenharmony_ci /* must be out of memory */ 2177bf215546Sopenharmony_ci _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s()", callerName); 2178bf215546Sopenharmony_ci return GL_TRUE; 2179bf215546Sopenharmony_ci } 2180bf215546Sopenharmony_ci 2181bf215546Sopenharmony_ci /* level check */ 2182bf215546Sopenharmony_ci if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) { 2183bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, "%s(level=%d)", callerName, level); 2184bf215546Sopenharmony_ci return GL_TRUE; 2185bf215546Sopenharmony_ci } 2186bf215546Sopenharmony_ci 2187bf215546Sopenharmony_ci if (error_check_subtexture_negative_dimensions(ctx, dimensions, 2188bf215546Sopenharmony_ci width, height, depth, 2189bf215546Sopenharmony_ci callerName)) { 2190bf215546Sopenharmony_ci return GL_TRUE; 2191bf215546Sopenharmony_ci } 2192bf215546Sopenharmony_ci 2193bf215546Sopenharmony_ci texImage = _mesa_select_tex_image(texObj, target, level); 2194bf215546Sopenharmony_ci if (!texImage) { 2195bf215546Sopenharmony_ci /* non-existant texture level */ 2196bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid texture level %d)", 2197bf215546Sopenharmony_ci callerName, level); 2198bf215546Sopenharmony_ci return GL_TRUE; 2199bf215546Sopenharmony_ci } 2200bf215546Sopenharmony_ci 2201bf215546Sopenharmony_ci err = _mesa_error_check_format_and_type(ctx, format, type); 2202bf215546Sopenharmony_ci if (err != GL_NO_ERROR) { 2203bf215546Sopenharmony_ci _mesa_error(ctx, err, 2204bf215546Sopenharmony_ci "%s(incompatible format = %s, type = %s)", 2205bf215546Sopenharmony_ci callerName, _mesa_enum_to_string(format), 2206bf215546Sopenharmony_ci _mesa_enum_to_string(type)); 2207bf215546Sopenharmony_ci return GL_TRUE; 2208bf215546Sopenharmony_ci } 2209bf215546Sopenharmony_ci 2210bf215546Sopenharmony_ci if (!texture_formats_agree(texImage->InternalFormat, format)) { 2211bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 2212bf215546Sopenharmony_ci "%s(incompatible internalFormat = %s, format = %s)", 2213bf215546Sopenharmony_ci callerName, 2214bf215546Sopenharmony_ci _mesa_enum_to_string(texImage->InternalFormat), 2215bf215546Sopenharmony_ci _mesa_enum_to_string(format)); 2216bf215546Sopenharmony_ci return GL_TRUE; 2217bf215546Sopenharmony_ci } 2218bf215546Sopenharmony_ci 2219bf215546Sopenharmony_ci GLenum internalFormat = _mesa_is_gles(ctx) ? 2220bf215546Sopenharmony_ci oes_float_internal_format(ctx, texImage->InternalFormat, type) : 2221bf215546Sopenharmony_ci texImage->InternalFormat; 2222bf215546Sopenharmony_ci 2223bf215546Sopenharmony_ci /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the 2224bf215546Sopenharmony_ci * combinations of format, internalFormat, and type that can be used. 2225bf215546Sopenharmony_ci * Formats and types that require additional extensions (e.g., GL_FLOAT 2226bf215546Sopenharmony_ci * requires GL_OES_texture_float) are filtered elsewhere. 2227bf215546Sopenharmony_ci */ 2228bf215546Sopenharmony_ci if (_mesa_is_gles(ctx) && 2229bf215546Sopenharmony_ci texture_format_error_check_gles(ctx, format, type, 2230bf215546Sopenharmony_ci internalFormat, callerName)) { 2231bf215546Sopenharmony_ci return GL_TRUE; 2232bf215546Sopenharmony_ci } 2233bf215546Sopenharmony_ci 2234bf215546Sopenharmony_ci /* validate the bound PBO, if any */ 2235bf215546Sopenharmony_ci if (!_mesa_validate_pbo_source(ctx, dimensions, &ctx->Unpack, 2236bf215546Sopenharmony_ci width, height, depth, format, type, 2237bf215546Sopenharmony_ci INT_MAX, pixels, callerName)) { 2238bf215546Sopenharmony_ci return GL_TRUE; 2239bf215546Sopenharmony_ci } 2240bf215546Sopenharmony_ci 2241bf215546Sopenharmony_ci if (error_check_subtexture_dimensions(ctx, dimensions, 2242bf215546Sopenharmony_ci texImage, xoffset, yoffset, zoffset, 2243bf215546Sopenharmony_ci width, height, depth, callerName)) { 2244bf215546Sopenharmony_ci return GL_TRUE; 2245bf215546Sopenharmony_ci } 2246bf215546Sopenharmony_ci 2247bf215546Sopenharmony_ci if (_mesa_is_format_compressed(texImage->TexFormat)) { 2248bf215546Sopenharmony_ci if (_mesa_format_no_online_compression(texImage->InternalFormat)) { 2249bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 2250bf215546Sopenharmony_ci "%s(no compression for format)", callerName); 2251bf215546Sopenharmony_ci return GL_TRUE; 2252bf215546Sopenharmony_ci } 2253bf215546Sopenharmony_ci } 2254bf215546Sopenharmony_ci 2255bf215546Sopenharmony_ci if (ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) { 2256bf215546Sopenharmony_ci /* both source and dest must be integer-valued, or neither */ 2257bf215546Sopenharmony_ci if (_mesa_is_format_integer_color(texImage->TexFormat) != 2258bf215546Sopenharmony_ci _mesa_is_enum_format_integer(format)) { 2259bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 2260bf215546Sopenharmony_ci "%s(integer/non-integer format mismatch)", callerName); 2261bf215546Sopenharmony_ci return GL_TRUE; 2262bf215546Sopenharmony_ci } 2263bf215546Sopenharmony_ci } 2264bf215546Sopenharmony_ci 2265bf215546Sopenharmony_ci return GL_FALSE; 2266bf215546Sopenharmony_ci} 2267bf215546Sopenharmony_ci 2268bf215546Sopenharmony_ci 2269bf215546Sopenharmony_ci/** 2270bf215546Sopenharmony_ci * Test glCopyTexImage[12]D() parameters for errors. 2271bf215546Sopenharmony_ci * 2272bf215546Sopenharmony_ci * \param ctx GL context. 2273bf215546Sopenharmony_ci * \param dimensions texture image dimensions (must be 1, 2 or 3). 2274bf215546Sopenharmony_ci * \param target texture target given by the user. 2275bf215546Sopenharmony_ci * \param level image level given by the user. 2276bf215546Sopenharmony_ci * \param internalFormat internal format given by the user. 2277bf215546Sopenharmony_ci * \param width image width given by the user. 2278bf215546Sopenharmony_ci * \param height image height given by the user. 2279bf215546Sopenharmony_ci * \param border texture border. 2280bf215546Sopenharmony_ci * 2281bf215546Sopenharmony_ci * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. 2282bf215546Sopenharmony_ci * 2283bf215546Sopenharmony_ci * Verifies each of the parameters against the constants specified in 2284bf215546Sopenharmony_ci * __struct gl_contextRec::Const and the supported extensions, and according 2285bf215546Sopenharmony_ci * to the OpenGL specification. 2286bf215546Sopenharmony_ci */ 2287bf215546Sopenharmony_cistatic GLboolean 2288bf215546Sopenharmony_cicopytexture_error_check( struct gl_context *ctx, GLuint dimensions, 2289bf215546Sopenharmony_ci GLenum target, struct gl_texture_object* texObj, 2290bf215546Sopenharmony_ci GLint level, GLint internalFormat, GLint border ) 2291bf215546Sopenharmony_ci{ 2292bf215546Sopenharmony_ci GLint baseFormat; 2293bf215546Sopenharmony_ci GLint rb_base_format; 2294bf215546Sopenharmony_ci struct gl_renderbuffer *rb; 2295bf215546Sopenharmony_ci GLenum rb_internal_format; 2296bf215546Sopenharmony_ci 2297bf215546Sopenharmony_ci /* level check */ 2298bf215546Sopenharmony_ci if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) { 2299bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, 2300bf215546Sopenharmony_ci "glCopyTexImage%dD(level=%d)", dimensions, level); 2301bf215546Sopenharmony_ci return GL_TRUE; 2302bf215546Sopenharmony_ci } 2303bf215546Sopenharmony_ci 2304bf215546Sopenharmony_ci /* Check that the source buffer is complete */ 2305bf215546Sopenharmony_ci if (_mesa_is_user_fbo(ctx->ReadBuffer)) { 2306bf215546Sopenharmony_ci if (ctx->ReadBuffer->_Status == 0) { 2307bf215546Sopenharmony_ci _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer); 2308bf215546Sopenharmony_ci } 2309bf215546Sopenharmony_ci if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 2310bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, 2311bf215546Sopenharmony_ci "glCopyTexImage%dD(invalid readbuffer)", dimensions); 2312bf215546Sopenharmony_ci return GL_TRUE; 2313bf215546Sopenharmony_ci } 2314bf215546Sopenharmony_ci 2315bf215546Sopenharmony_ci if (ctx->ReadBuffer->Visual.samples > 0) { 2316bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 2317bf215546Sopenharmony_ci "glCopyTexImage%dD(multisample FBO)", dimensions); 2318bf215546Sopenharmony_ci return GL_TRUE; 2319bf215546Sopenharmony_ci } 2320bf215546Sopenharmony_ci } 2321bf215546Sopenharmony_ci 2322bf215546Sopenharmony_ci /* Check border */ 2323bf215546Sopenharmony_ci if (border < 0 || border > 1 || 2324bf215546Sopenharmony_ci ((ctx->API != API_OPENGL_COMPAT || 2325bf215546Sopenharmony_ci target == GL_TEXTURE_RECTANGLE_NV || 2326bf215546Sopenharmony_ci target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) { 2327bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, 2328bf215546Sopenharmony_ci "glCopyTexImage%dD(border=%d)", dimensions, border); 2329bf215546Sopenharmony_ci return GL_TRUE; 2330bf215546Sopenharmony_ci } 2331bf215546Sopenharmony_ci 2332bf215546Sopenharmony_ci /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the 2333bf215546Sopenharmony_ci * internalFormat. 2334bf215546Sopenharmony_ci */ 2335bf215546Sopenharmony_ci if (_mesa_is_gles(ctx) && !_mesa_is_gles3(ctx)) { 2336bf215546Sopenharmony_ci switch (internalFormat) { 2337bf215546Sopenharmony_ci case GL_ALPHA: 2338bf215546Sopenharmony_ci case GL_RGB: 2339bf215546Sopenharmony_ci case GL_RGBA: 2340bf215546Sopenharmony_ci case GL_LUMINANCE: 2341bf215546Sopenharmony_ci case GL_LUMINANCE_ALPHA: 2342bf215546Sopenharmony_ci 2343bf215546Sopenharmony_ci /* Added by GL_OES_required_internalformat (always enabled) in table 3.4.y.*/ 2344bf215546Sopenharmony_ci case GL_ALPHA8: 2345bf215546Sopenharmony_ci case GL_LUMINANCE8: 2346bf215546Sopenharmony_ci case GL_LUMINANCE8_ALPHA8: 2347bf215546Sopenharmony_ci case GL_LUMINANCE4_ALPHA4: 2348bf215546Sopenharmony_ci case GL_RGB565: 2349bf215546Sopenharmony_ci case GL_RGB8: 2350bf215546Sopenharmony_ci case GL_RGBA4: 2351bf215546Sopenharmony_ci case GL_RGB5_A1: 2352bf215546Sopenharmony_ci case GL_RGBA8: 2353bf215546Sopenharmony_ci case GL_DEPTH_COMPONENT16: 2354bf215546Sopenharmony_ci case GL_DEPTH_COMPONENT24: 2355bf215546Sopenharmony_ci case GL_DEPTH_COMPONENT32: 2356bf215546Sopenharmony_ci case GL_DEPTH24_STENCIL8: 2357bf215546Sopenharmony_ci case GL_RGB10: 2358bf215546Sopenharmony_ci case GL_RGB10_A2: 2359bf215546Sopenharmony_ci break; 2360bf215546Sopenharmony_ci 2361bf215546Sopenharmony_ci default: 2362bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, 2363bf215546Sopenharmony_ci "glCopyTexImage%dD(internalFormat=%s)", dimensions, 2364bf215546Sopenharmony_ci _mesa_enum_to_string(internalFormat)); 2365bf215546Sopenharmony_ci return GL_TRUE; 2366bf215546Sopenharmony_ci } 2367bf215546Sopenharmony_ci } else { 2368bf215546Sopenharmony_ci /* 2369bf215546Sopenharmony_ci * Section 8.6 (Alternate Texture Image Specification Commands) of the 2370bf215546Sopenharmony_ci * OpenGL 4.5 (Compatibility Profile) spec says: 2371bf215546Sopenharmony_ci * 2372bf215546Sopenharmony_ci * "Parameters level, internalformat, and border are specified using 2373bf215546Sopenharmony_ci * the same values, with the same meanings, as the corresponding 2374bf215546Sopenharmony_ci * arguments of TexImage2D, except that internalformat may not be 2375bf215546Sopenharmony_ci * specified as 1, 2, 3, or 4." 2376bf215546Sopenharmony_ci */ 2377bf215546Sopenharmony_ci if (internalFormat >= 1 && internalFormat <= 4) { 2378bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, 2379bf215546Sopenharmony_ci "glCopyTexImage%dD(internalFormat=%d)", dimensions, 2380bf215546Sopenharmony_ci internalFormat); 2381bf215546Sopenharmony_ci return GL_TRUE; 2382bf215546Sopenharmony_ci } 2383bf215546Sopenharmony_ci } 2384bf215546Sopenharmony_ci 2385bf215546Sopenharmony_ci baseFormat = _mesa_base_tex_format(ctx, internalFormat); 2386bf215546Sopenharmony_ci if (baseFormat < 0) { 2387bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, 2388bf215546Sopenharmony_ci "glCopyTexImage%dD(internalFormat=%s)", dimensions, 2389bf215546Sopenharmony_ci _mesa_enum_to_string(internalFormat)); 2390bf215546Sopenharmony_ci return GL_TRUE; 2391bf215546Sopenharmony_ci } 2392bf215546Sopenharmony_ci 2393bf215546Sopenharmony_ci rb = _mesa_get_read_renderbuffer_for_format(ctx, internalFormat); 2394bf215546Sopenharmony_ci if (rb == NULL) { 2395bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 2396bf215546Sopenharmony_ci "glCopyTexImage%dD(read buffer)", dimensions); 2397bf215546Sopenharmony_ci return GL_TRUE; 2398bf215546Sopenharmony_ci } 2399bf215546Sopenharmony_ci 2400bf215546Sopenharmony_ci rb_internal_format = rb->InternalFormat; 2401bf215546Sopenharmony_ci rb_base_format = _mesa_base_tex_format(ctx, rb->InternalFormat); 2402bf215546Sopenharmony_ci if (_mesa_is_color_format(internalFormat)) { 2403bf215546Sopenharmony_ci if (rb_base_format < 0) { 2404bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, 2405bf215546Sopenharmony_ci "glCopyTexImage%dD(internalFormat=%s)", dimensions, 2406bf215546Sopenharmony_ci _mesa_enum_to_string(internalFormat)); 2407bf215546Sopenharmony_ci return GL_TRUE; 2408bf215546Sopenharmony_ci } 2409bf215546Sopenharmony_ci } 2410bf215546Sopenharmony_ci 2411bf215546Sopenharmony_ci if (_mesa_is_gles(ctx)) { 2412bf215546Sopenharmony_ci bool valid = true; 2413bf215546Sopenharmony_ci if (_mesa_components_in_format(baseFormat) > 2414bf215546Sopenharmony_ci _mesa_components_in_format(rb_base_format)) { 2415bf215546Sopenharmony_ci valid = false; 2416bf215546Sopenharmony_ci } 2417bf215546Sopenharmony_ci if (baseFormat == GL_DEPTH_COMPONENT || 2418bf215546Sopenharmony_ci baseFormat == GL_DEPTH_STENCIL || 2419bf215546Sopenharmony_ci baseFormat == GL_STENCIL_INDEX || 2420bf215546Sopenharmony_ci rb_base_format == GL_DEPTH_COMPONENT || 2421bf215546Sopenharmony_ci rb_base_format == GL_DEPTH_STENCIL || 2422bf215546Sopenharmony_ci rb_base_format == GL_STENCIL_INDEX || 2423bf215546Sopenharmony_ci ((baseFormat == GL_LUMINANCE_ALPHA || 2424bf215546Sopenharmony_ci baseFormat == GL_ALPHA) && 2425bf215546Sopenharmony_ci rb_base_format != GL_RGBA) || 2426bf215546Sopenharmony_ci internalFormat == GL_RGB9_E5) { 2427bf215546Sopenharmony_ci valid = false; 2428bf215546Sopenharmony_ci } 2429bf215546Sopenharmony_ci if (internalFormat == GL_RGB9_E5) { 2430bf215546Sopenharmony_ci valid = false; 2431bf215546Sopenharmony_ci } 2432bf215546Sopenharmony_ci if (!valid) { 2433bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 2434bf215546Sopenharmony_ci "glCopyTexImage%dD(internalFormat=%s)", dimensions, 2435bf215546Sopenharmony_ci _mesa_enum_to_string(internalFormat)); 2436bf215546Sopenharmony_ci return GL_TRUE; 2437bf215546Sopenharmony_ci } 2438bf215546Sopenharmony_ci } 2439bf215546Sopenharmony_ci 2440bf215546Sopenharmony_ci if (_mesa_is_gles3(ctx)) { 2441bf215546Sopenharmony_ci bool rb_is_srgb = (ctx->Extensions.EXT_sRGB && 2442bf215546Sopenharmony_ci _mesa_is_format_srgb(rb->Format)); 2443bf215546Sopenharmony_ci bool dst_is_srgb = false; 2444bf215546Sopenharmony_ci 2445bf215546Sopenharmony_ci if (_mesa_get_linear_internalformat(internalFormat) != internalFormat) { 2446bf215546Sopenharmony_ci dst_is_srgb = true; 2447bf215546Sopenharmony_ci } 2448bf215546Sopenharmony_ci 2449bf215546Sopenharmony_ci if (rb_is_srgb != dst_is_srgb) { 2450bf215546Sopenharmony_ci /* Page 137 (page 149 of the PDF) in section 3.8.5 of the 2451bf215546Sopenharmony_ci * OpenGLES 3.0.0 spec says: 2452bf215546Sopenharmony_ci * 2453bf215546Sopenharmony_ci * "The error INVALID_OPERATION is also generated if the 2454bf215546Sopenharmony_ci * value of FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING for the 2455bf215546Sopenharmony_ci * framebuffer attachment corresponding to the read buffer 2456bf215546Sopenharmony_ci * is LINEAR (see section 6.1.13) and internalformat is 2457bf215546Sopenharmony_ci * one of the sRGB formats described in section 3.8.16, or 2458bf215546Sopenharmony_ci * if the value of FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING is 2459bf215546Sopenharmony_ci * SRGB and internalformat is not one of the sRGB formats." 2460bf215546Sopenharmony_ci */ 2461bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 2462bf215546Sopenharmony_ci "glCopyTexImage%dD(srgb usage mismatch)", dimensions); 2463bf215546Sopenharmony_ci return GL_TRUE; 2464bf215546Sopenharmony_ci } 2465bf215546Sopenharmony_ci 2466bf215546Sopenharmony_ci /* Page 139, Table 3.15 of OpenGL ES 3.0 spec does not define ReadPixels 2467bf215546Sopenharmony_ci * types for SNORM formats. Also, conversion to SNORM formats is not 2468bf215546Sopenharmony_ci * allowed by Table 3.2 on Page 110. 2469bf215546Sopenharmony_ci */ 2470bf215546Sopenharmony_ci if (!_mesa_has_EXT_render_snorm(ctx) && 2471bf215546Sopenharmony_ci _mesa_is_enum_format_snorm(internalFormat)) { 2472bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 2473bf215546Sopenharmony_ci "glCopyTexImage%dD(internalFormat=%s)", dimensions, 2474bf215546Sopenharmony_ci _mesa_enum_to_string(internalFormat)); 2475bf215546Sopenharmony_ci return GL_TRUE; 2476bf215546Sopenharmony_ci } 2477bf215546Sopenharmony_ci } 2478bf215546Sopenharmony_ci 2479bf215546Sopenharmony_ci if (!_mesa_source_buffer_exists(ctx, baseFormat)) { 2480bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 2481bf215546Sopenharmony_ci "glCopyTexImage%dD(missing readbuffer)", dimensions); 2482bf215546Sopenharmony_ci return GL_TRUE; 2483bf215546Sopenharmony_ci } 2484bf215546Sopenharmony_ci 2485bf215546Sopenharmony_ci /* From the EXT_texture_integer spec: 2486bf215546Sopenharmony_ci * 2487bf215546Sopenharmony_ci * "INVALID_OPERATION is generated by CopyTexImage* and CopyTexSubImage* 2488bf215546Sopenharmony_ci * if the texture internalformat is an integer format and the read color 2489bf215546Sopenharmony_ci * buffer is not an integer format, or if the internalformat is not an 2490bf215546Sopenharmony_ci * integer format and the read color buffer is an integer format." 2491bf215546Sopenharmony_ci */ 2492bf215546Sopenharmony_ci if (_mesa_is_color_format(internalFormat)) { 2493bf215546Sopenharmony_ci bool is_int = _mesa_is_enum_format_integer(internalFormat); 2494bf215546Sopenharmony_ci bool is_rbint = _mesa_is_enum_format_integer(rb_internal_format); 2495bf215546Sopenharmony_ci bool is_unorm = _mesa_is_enum_format_unorm(internalFormat); 2496bf215546Sopenharmony_ci bool is_rbunorm = _mesa_is_enum_format_unorm(rb_internal_format); 2497bf215546Sopenharmony_ci if (is_int || is_rbint) { 2498bf215546Sopenharmony_ci if (is_int != is_rbint) { 2499bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 2500bf215546Sopenharmony_ci "glCopyTexImage%dD(integer vs non-integer)", dimensions); 2501bf215546Sopenharmony_ci return GL_TRUE; 2502bf215546Sopenharmony_ci } else if (_mesa_is_gles(ctx) && 2503bf215546Sopenharmony_ci _mesa_is_enum_format_unsigned_int(internalFormat) != 2504bf215546Sopenharmony_ci _mesa_is_enum_format_unsigned_int(rb_internal_format)) { 2505bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 2506bf215546Sopenharmony_ci "glCopyTexImage%dD(signed vs unsigned integer)", 2507bf215546Sopenharmony_ci dimensions); 2508bf215546Sopenharmony_ci return GL_TRUE; 2509bf215546Sopenharmony_ci } 2510bf215546Sopenharmony_ci } 2511bf215546Sopenharmony_ci 2512bf215546Sopenharmony_ci /* From page 138 of OpenGL ES 3.0 spec: 2513bf215546Sopenharmony_ci * "The error INVALID_OPERATION is generated if floating-point RGBA 2514bf215546Sopenharmony_ci * data is required; if signed integer RGBA data is required and the 2515bf215546Sopenharmony_ci * format of the current color buffer is not signed integer; if 2516bf215546Sopenharmony_ci * unsigned integer RGBA data is required and the format of the 2517bf215546Sopenharmony_ci * current color buffer is not unsigned integer; or if fixed-point 2518bf215546Sopenharmony_ci * RGBA data is required and the format of the current color buffer 2519bf215546Sopenharmony_ci * is not fixed-point. 2520bf215546Sopenharmony_ci */ 2521bf215546Sopenharmony_ci if (_mesa_is_gles(ctx) && is_unorm != is_rbunorm) 2522bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 2523bf215546Sopenharmony_ci "glCopyTexImage%dD(unorm vs non-unorm)", dimensions); 2524bf215546Sopenharmony_ci } 2525bf215546Sopenharmony_ci 2526bf215546Sopenharmony_ci if (_mesa_is_compressed_format(ctx, internalFormat)) { 2527bf215546Sopenharmony_ci GLenum err; 2528bf215546Sopenharmony_ci if (!_mesa_target_can_be_compressed(ctx, target, internalFormat, &err)) { 2529bf215546Sopenharmony_ci _mesa_error(ctx, err, 2530bf215546Sopenharmony_ci "glCopyTexImage%dD(target can't be compressed)", dimensions); 2531bf215546Sopenharmony_ci return GL_TRUE; 2532bf215546Sopenharmony_ci } 2533bf215546Sopenharmony_ci if (_mesa_format_no_online_compression(internalFormat)) { 2534bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 2535bf215546Sopenharmony_ci "glCopyTexImage%dD(no compression for format)", dimensions); 2536bf215546Sopenharmony_ci return GL_TRUE; 2537bf215546Sopenharmony_ci } 2538bf215546Sopenharmony_ci if (border != 0) { 2539bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 2540bf215546Sopenharmony_ci "glCopyTexImage%dD(border!=0)", dimensions); 2541bf215546Sopenharmony_ci return GL_TRUE; 2542bf215546Sopenharmony_ci } 2543bf215546Sopenharmony_ci } 2544bf215546Sopenharmony_ci 2545bf215546Sopenharmony_ci if (!mutable_tex_object(texObj)) { 2546bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 2547bf215546Sopenharmony_ci "glCopyTexImage%dD(immutable texture)", dimensions); 2548bf215546Sopenharmony_ci return GL_TRUE; 2549bf215546Sopenharmony_ci } 2550bf215546Sopenharmony_ci 2551bf215546Sopenharmony_ci /* if we get here, the parameters are OK */ 2552bf215546Sopenharmony_ci return GL_FALSE; 2553bf215546Sopenharmony_ci} 2554bf215546Sopenharmony_ci 2555bf215546Sopenharmony_ci 2556bf215546Sopenharmony_ci/** 2557bf215546Sopenharmony_ci * Test glCopyTexSubImage[12]D() parameters for errors. 2558bf215546Sopenharmony_ci * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. 2559bf215546Sopenharmony_ci */ 2560bf215546Sopenharmony_cistatic GLboolean 2561bf215546Sopenharmony_cicopytexsubimage_error_check(struct gl_context *ctx, GLuint dimensions, 2562bf215546Sopenharmony_ci const struct gl_texture_object *texObj, 2563bf215546Sopenharmony_ci GLenum target, GLint level, 2564bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, GLint zoffset, 2565bf215546Sopenharmony_ci GLint width, GLint height, const char *caller) 2566bf215546Sopenharmony_ci{ 2567bf215546Sopenharmony_ci assert(texObj); 2568bf215546Sopenharmony_ci 2569bf215546Sopenharmony_ci struct gl_texture_image *texImage; 2570bf215546Sopenharmony_ci 2571bf215546Sopenharmony_ci /* Check that the source buffer is complete */ 2572bf215546Sopenharmony_ci if (_mesa_is_user_fbo(ctx->ReadBuffer)) { 2573bf215546Sopenharmony_ci if (ctx->ReadBuffer->_Status == 0) { 2574bf215546Sopenharmony_ci _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer); 2575bf215546Sopenharmony_ci } 2576bf215546Sopenharmony_ci if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 2577bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, 2578bf215546Sopenharmony_ci "%s(invalid readbuffer)", caller); 2579bf215546Sopenharmony_ci return GL_TRUE; 2580bf215546Sopenharmony_ci } 2581bf215546Sopenharmony_ci 2582bf215546Sopenharmony_ci if (ctx->ReadBuffer->Visual.samples > 0) { 2583bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 2584bf215546Sopenharmony_ci "%s(multisample FBO)", caller); 2585bf215546Sopenharmony_ci return GL_TRUE; 2586bf215546Sopenharmony_ci } 2587bf215546Sopenharmony_ci } 2588bf215546Sopenharmony_ci 2589bf215546Sopenharmony_ci /* Check level */ 2590bf215546Sopenharmony_ci if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) { 2591bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, "%s(level=%d)", caller, level); 2592bf215546Sopenharmony_ci return GL_TRUE; 2593bf215546Sopenharmony_ci } 2594bf215546Sopenharmony_ci 2595bf215546Sopenharmony_ci texImage = _mesa_select_tex_image(texObj, target, level); 2596bf215546Sopenharmony_ci if (!texImage) { 2597bf215546Sopenharmony_ci /* destination image does not exist */ 2598bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 2599bf215546Sopenharmony_ci "%s(invalid texture level %d)", caller, level); 2600bf215546Sopenharmony_ci return GL_TRUE; 2601bf215546Sopenharmony_ci } 2602bf215546Sopenharmony_ci 2603bf215546Sopenharmony_ci if (error_check_subtexture_negative_dimensions(ctx, dimensions, 2604bf215546Sopenharmony_ci width, height, 1, caller)) { 2605bf215546Sopenharmony_ci return GL_TRUE; 2606bf215546Sopenharmony_ci } 2607bf215546Sopenharmony_ci 2608bf215546Sopenharmony_ci if (error_check_subtexture_dimensions(ctx, dimensions, texImage, 2609bf215546Sopenharmony_ci xoffset, yoffset, zoffset, 2610bf215546Sopenharmony_ci width, height, 1, caller)) { 2611bf215546Sopenharmony_ci return GL_TRUE; 2612bf215546Sopenharmony_ci } 2613bf215546Sopenharmony_ci 2614bf215546Sopenharmony_ci if (_mesa_is_format_compressed(texImage->TexFormat)) { 2615bf215546Sopenharmony_ci if (_mesa_format_no_online_compression(texImage->InternalFormat)) { 2616bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 2617bf215546Sopenharmony_ci "%s(no compression for format)", caller); 2618bf215546Sopenharmony_ci return GL_TRUE; 2619bf215546Sopenharmony_ci } 2620bf215546Sopenharmony_ci } 2621bf215546Sopenharmony_ci 2622bf215546Sopenharmony_ci if (texImage->InternalFormat == GL_YCBCR_MESA) { 2623bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, "%s()", caller); 2624bf215546Sopenharmony_ci return GL_TRUE; 2625bf215546Sopenharmony_ci } 2626bf215546Sopenharmony_ci 2627bf215546Sopenharmony_ci /* From OpenGL ES 3.2 spec, section 8.6: 2628bf215546Sopenharmony_ci * 2629bf215546Sopenharmony_ci * "An INVALID_OPERATION error is generated by CopyTexSubImage3D, 2630bf215546Sopenharmony_ci * CopyTexImage2D, or CopyTexSubImage2D if the internalformat of the 2631bf215546Sopenharmony_ci * texture image being (re)specified is RGB9_E5" 2632bf215546Sopenharmony_ci */ 2633bf215546Sopenharmony_ci if (texImage->InternalFormat == GL_RGB9_E5 && 2634bf215546Sopenharmony_ci !_mesa_is_desktop_gl(ctx)) { 2635bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 2636bf215546Sopenharmony_ci "%s(invalid internal format %s)", caller, 2637bf215546Sopenharmony_ci _mesa_enum_to_string(texImage->InternalFormat)); 2638bf215546Sopenharmony_ci return GL_TRUE; 2639bf215546Sopenharmony_ci } 2640bf215546Sopenharmony_ci 2641bf215546Sopenharmony_ci if (!_mesa_source_buffer_exists(ctx, texImage->_BaseFormat)) { 2642bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 2643bf215546Sopenharmony_ci "%s(missing readbuffer, format=%s)", caller, 2644bf215546Sopenharmony_ci _mesa_enum_to_string(texImage->_BaseFormat)); 2645bf215546Sopenharmony_ci return GL_TRUE; 2646bf215546Sopenharmony_ci } 2647bf215546Sopenharmony_ci 2648bf215546Sopenharmony_ci /* From the EXT_texture_integer spec: 2649bf215546Sopenharmony_ci * 2650bf215546Sopenharmony_ci * "INVALID_OPERATION is generated by CopyTexImage* and 2651bf215546Sopenharmony_ci * CopyTexSubImage* if the texture internalformat is an integer format 2652bf215546Sopenharmony_ci * and the read color buffer is not an integer format, or if the 2653bf215546Sopenharmony_ci * internalformat is not an integer format and the read color buffer 2654bf215546Sopenharmony_ci * is an integer format." 2655bf215546Sopenharmony_ci */ 2656bf215546Sopenharmony_ci if (_mesa_is_color_format(texImage->InternalFormat)) { 2657bf215546Sopenharmony_ci struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer; 2658bf215546Sopenharmony_ci 2659bf215546Sopenharmony_ci if (_mesa_is_format_integer_color(rb->Format) != 2660bf215546Sopenharmony_ci _mesa_is_format_integer_color(texImage->TexFormat)) { 2661bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 2662bf215546Sopenharmony_ci "%s(integer vs non-integer)", caller); 2663bf215546Sopenharmony_ci return GL_TRUE; 2664bf215546Sopenharmony_ci } 2665bf215546Sopenharmony_ci } 2666bf215546Sopenharmony_ci 2667bf215546Sopenharmony_ci /* In the ES 3.2 specification's Table 8.13 (Valid CopyTexImage source 2668bf215546Sopenharmony_ci * framebuffer/destination texture base internal format combinations), 2669bf215546Sopenharmony_ci * all the entries for stencil are left blank (unsupported). 2670bf215546Sopenharmony_ci */ 2671bf215546Sopenharmony_ci if (_mesa_is_gles(ctx) && _mesa_is_stencil_format(texImage->_BaseFormat)) { 2672bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, "%s(stencil disallowed)", caller); 2673bf215546Sopenharmony_ci return GL_TRUE; 2674bf215546Sopenharmony_ci } 2675bf215546Sopenharmony_ci 2676bf215546Sopenharmony_ci /* if we get here, the parameters are OK */ 2677bf215546Sopenharmony_ci return GL_FALSE; 2678bf215546Sopenharmony_ci} 2679bf215546Sopenharmony_ci 2680bf215546Sopenharmony_ci 2681bf215546Sopenharmony_ci/** Callback info for walking over FBO hash table */ 2682bf215546Sopenharmony_cistruct cb_info 2683bf215546Sopenharmony_ci{ 2684bf215546Sopenharmony_ci struct gl_context *ctx; 2685bf215546Sopenharmony_ci struct gl_texture_object *texObj; 2686bf215546Sopenharmony_ci GLuint level, face; 2687bf215546Sopenharmony_ci}; 2688bf215546Sopenharmony_ci 2689bf215546Sopenharmony_ci 2690bf215546Sopenharmony_ci/** 2691bf215546Sopenharmony_ci * Check render to texture callback. Called from _mesa_HashWalk(). 2692bf215546Sopenharmony_ci */ 2693bf215546Sopenharmony_cistatic void 2694bf215546Sopenharmony_cicheck_rtt_cb(void *data, void *userData) 2695bf215546Sopenharmony_ci{ 2696bf215546Sopenharmony_ci struct gl_framebuffer *fb = (struct gl_framebuffer *) data; 2697bf215546Sopenharmony_ci const struct cb_info *info = (struct cb_info *) userData; 2698bf215546Sopenharmony_ci struct gl_context *ctx = info->ctx; 2699bf215546Sopenharmony_ci const struct gl_texture_object *texObj = info->texObj; 2700bf215546Sopenharmony_ci const GLuint level = info->level, face = info->face; 2701bf215546Sopenharmony_ci 2702bf215546Sopenharmony_ci /* If this is a user-created FBO */ 2703bf215546Sopenharmony_ci if (_mesa_is_user_fbo(fb)) { 2704bf215546Sopenharmony_ci GLuint i; 2705bf215546Sopenharmony_ci /* check if any of the FBO's attachments point to 'texObj' */ 2706bf215546Sopenharmony_ci for (i = 0; i < BUFFER_COUNT; i++) { 2707bf215546Sopenharmony_ci struct gl_renderbuffer_attachment *att = fb->Attachment + i; 2708bf215546Sopenharmony_ci if (att->Type == GL_TEXTURE && 2709bf215546Sopenharmony_ci att->Texture == texObj && 2710bf215546Sopenharmony_ci att->TextureLevel == level && 2711bf215546Sopenharmony_ci att->CubeMapFace == face) { 2712bf215546Sopenharmony_ci _mesa_update_texture_renderbuffer(ctx, fb, att); 2713bf215546Sopenharmony_ci assert(att->Renderbuffer->TexImage); 2714bf215546Sopenharmony_ci /* Mark fb status as indeterminate to force re-validation */ 2715bf215546Sopenharmony_ci fb->_Status = 0; 2716bf215546Sopenharmony_ci 2717bf215546Sopenharmony_ci /* Make sure that the revalidation actually happens if this is 2718bf215546Sopenharmony_ci * being done to currently-bound buffers. 2719bf215546Sopenharmony_ci */ 2720bf215546Sopenharmony_ci if (fb == ctx->DrawBuffer || fb == ctx->ReadBuffer) 2721bf215546Sopenharmony_ci ctx->NewState |= _NEW_BUFFERS; 2722bf215546Sopenharmony_ci } 2723bf215546Sopenharmony_ci } 2724bf215546Sopenharmony_ci } 2725bf215546Sopenharmony_ci} 2726bf215546Sopenharmony_ci 2727bf215546Sopenharmony_ci 2728bf215546Sopenharmony_ci/** 2729bf215546Sopenharmony_ci * When a texture image is specified we have to check if it's bound to 2730bf215546Sopenharmony_ci * any framebuffer objects (render to texture) in order to detect changes 2731bf215546Sopenharmony_ci * in size or format since that effects FBO completeness. 2732bf215546Sopenharmony_ci * Any FBOs rendering into the texture must be re-validated. 2733bf215546Sopenharmony_ci */ 2734bf215546Sopenharmony_civoid 2735bf215546Sopenharmony_ci_mesa_update_fbo_texture(struct gl_context *ctx, 2736bf215546Sopenharmony_ci struct gl_texture_object *texObj, 2737bf215546Sopenharmony_ci GLuint face, GLuint level) 2738bf215546Sopenharmony_ci{ 2739bf215546Sopenharmony_ci /* Only check this texture if it's been marked as RenderToTexture */ 2740bf215546Sopenharmony_ci if (texObj->_RenderToTexture) { 2741bf215546Sopenharmony_ci struct cb_info info; 2742bf215546Sopenharmony_ci info.ctx = ctx; 2743bf215546Sopenharmony_ci info.texObj = texObj; 2744bf215546Sopenharmony_ci info.level = level; 2745bf215546Sopenharmony_ci info.face = face; 2746bf215546Sopenharmony_ci _mesa_HashWalk(ctx->Shared->FrameBuffers, check_rtt_cb, &info); 2747bf215546Sopenharmony_ci } 2748bf215546Sopenharmony_ci} 2749bf215546Sopenharmony_ci 2750bf215546Sopenharmony_ci 2751bf215546Sopenharmony_ci/** 2752bf215546Sopenharmony_ci * If the texture object's GenerateMipmap flag is set and we've 2753bf215546Sopenharmony_ci * changed the texture base level image, regenerate the rest of the 2754bf215546Sopenharmony_ci * mipmap levels now. 2755bf215546Sopenharmony_ci */ 2756bf215546Sopenharmony_cistatic inline void 2757bf215546Sopenharmony_cicheck_gen_mipmap(struct gl_context *ctx, GLenum target, 2758bf215546Sopenharmony_ci struct gl_texture_object *texObj, GLint level) 2759bf215546Sopenharmony_ci{ 2760bf215546Sopenharmony_ci if (texObj->Attrib.GenerateMipmap && 2761bf215546Sopenharmony_ci level == texObj->Attrib.BaseLevel && 2762bf215546Sopenharmony_ci level < texObj->Attrib.MaxLevel) { 2763bf215546Sopenharmony_ci st_generate_mipmap(ctx, target, texObj); 2764bf215546Sopenharmony_ci } 2765bf215546Sopenharmony_ci} 2766bf215546Sopenharmony_ci 2767bf215546Sopenharmony_ci 2768bf215546Sopenharmony_ci/** Debug helper: override the user-requested internal format */ 2769bf215546Sopenharmony_cistatic GLenum 2770bf215546Sopenharmony_cioverride_internal_format(GLenum internalFormat, UNUSED GLint width, 2771bf215546Sopenharmony_ci UNUSED GLint height) 2772bf215546Sopenharmony_ci{ 2773bf215546Sopenharmony_ci#if 0 2774bf215546Sopenharmony_ci if (internalFormat == GL_RGBA16F_ARB || 2775bf215546Sopenharmony_ci internalFormat == GL_RGBA32F_ARB) { 2776bf215546Sopenharmony_ci printf("Convert rgba float tex to int %d x %d\n", width, height); 2777bf215546Sopenharmony_ci return GL_RGBA; 2778bf215546Sopenharmony_ci } 2779bf215546Sopenharmony_ci else if (internalFormat == GL_RGB16F_ARB || 2780bf215546Sopenharmony_ci internalFormat == GL_RGB32F_ARB) { 2781bf215546Sopenharmony_ci printf("Convert rgb float tex to int %d x %d\n", width, height); 2782bf215546Sopenharmony_ci return GL_RGB; 2783bf215546Sopenharmony_ci } 2784bf215546Sopenharmony_ci else if (internalFormat == GL_LUMINANCE_ALPHA16F_ARB || 2785bf215546Sopenharmony_ci internalFormat == GL_LUMINANCE_ALPHA32F_ARB) { 2786bf215546Sopenharmony_ci printf("Convert luminance float tex to int %d x %d\n", width, height); 2787bf215546Sopenharmony_ci return GL_LUMINANCE_ALPHA; 2788bf215546Sopenharmony_ci } 2789bf215546Sopenharmony_ci else if (internalFormat == GL_LUMINANCE16F_ARB || 2790bf215546Sopenharmony_ci internalFormat == GL_LUMINANCE32F_ARB) { 2791bf215546Sopenharmony_ci printf("Convert luminance float tex to int %d x %d\n", width, height); 2792bf215546Sopenharmony_ci return GL_LUMINANCE; 2793bf215546Sopenharmony_ci } 2794bf215546Sopenharmony_ci else if (internalFormat == GL_ALPHA16F_ARB || 2795bf215546Sopenharmony_ci internalFormat == GL_ALPHA32F_ARB) { 2796bf215546Sopenharmony_ci printf("Convert luminance float tex to int %d x %d\n", width, height); 2797bf215546Sopenharmony_ci return GL_ALPHA; 2798bf215546Sopenharmony_ci } 2799bf215546Sopenharmony_ci /* 2800bf215546Sopenharmony_ci else if (internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) { 2801bf215546Sopenharmony_ci internalFormat = GL_RGBA; 2802bf215546Sopenharmony_ci } 2803bf215546Sopenharmony_ci */ 2804bf215546Sopenharmony_ci else { 2805bf215546Sopenharmony_ci return internalFormat; 2806bf215546Sopenharmony_ci } 2807bf215546Sopenharmony_ci#else 2808bf215546Sopenharmony_ci return internalFormat; 2809bf215546Sopenharmony_ci#endif 2810bf215546Sopenharmony_ci} 2811bf215546Sopenharmony_ci 2812bf215546Sopenharmony_ci 2813bf215546Sopenharmony_ci/** 2814bf215546Sopenharmony_ci * Choose the actual hardware format for a texture image. 2815bf215546Sopenharmony_ci * Try to use the same format as the previous image level when possible. 2816bf215546Sopenharmony_ci * Otherwise, ask the driver for the best format. 2817bf215546Sopenharmony_ci * It's important to try to choose a consistant format for all levels 2818bf215546Sopenharmony_ci * for efficient texture memory layout/allocation. In particular, this 2819bf215546Sopenharmony_ci * comes up during automatic mipmap generation. 2820bf215546Sopenharmony_ci */ 2821bf215546Sopenharmony_cimesa_format 2822bf215546Sopenharmony_ci_mesa_choose_texture_format(struct gl_context *ctx, 2823bf215546Sopenharmony_ci struct gl_texture_object *texObj, 2824bf215546Sopenharmony_ci GLenum target, GLint level, 2825bf215546Sopenharmony_ci GLenum internalFormat, GLenum format, GLenum type) 2826bf215546Sopenharmony_ci{ 2827bf215546Sopenharmony_ci mesa_format f = MESA_FORMAT_NONE; 2828bf215546Sopenharmony_ci 2829bf215546Sopenharmony_ci /* see if we've already chosen a format for the previous level */ 2830bf215546Sopenharmony_ci if (level > 0) { 2831bf215546Sopenharmony_ci struct gl_texture_image *prevImage = 2832bf215546Sopenharmony_ci _mesa_select_tex_image(texObj, target, level - 1); 2833bf215546Sopenharmony_ci /* See if the prev level is defined and has an internal format which 2834bf215546Sopenharmony_ci * matches the new internal format. 2835bf215546Sopenharmony_ci */ 2836bf215546Sopenharmony_ci if (prevImage && 2837bf215546Sopenharmony_ci prevImage->Width > 0 && 2838bf215546Sopenharmony_ci prevImage->InternalFormat == internalFormat) { 2839bf215546Sopenharmony_ci /* use the same format */ 2840bf215546Sopenharmony_ci assert(prevImage->TexFormat != MESA_FORMAT_NONE); 2841bf215546Sopenharmony_ci return prevImage->TexFormat; 2842bf215546Sopenharmony_ci } 2843bf215546Sopenharmony_ci } 2844bf215546Sopenharmony_ci 2845bf215546Sopenharmony_ci f = st_ChooseTextureFormat(ctx, target, internalFormat, 2846bf215546Sopenharmony_ci format, type); 2847bf215546Sopenharmony_ci assert(f != MESA_FORMAT_NONE); 2848bf215546Sopenharmony_ci return f; 2849bf215546Sopenharmony_ci} 2850bf215546Sopenharmony_ci 2851bf215546Sopenharmony_ci 2852bf215546Sopenharmony_ci/** 2853bf215546Sopenharmony_ci * Adjust pixel unpack params and image dimensions to strip off the 2854bf215546Sopenharmony_ci * one-pixel texture border. 2855bf215546Sopenharmony_ci * 2856bf215546Sopenharmony_ci * Gallium and intel don't support texture borders. They've seldem been used 2857bf215546Sopenharmony_ci * and seldom been implemented correctly anyway. 2858bf215546Sopenharmony_ci * 2859bf215546Sopenharmony_ci * \param unpackNew returns the new pixel unpack parameters 2860bf215546Sopenharmony_ci */ 2861bf215546Sopenharmony_cistatic void 2862bf215546Sopenharmony_cistrip_texture_border(GLenum target, 2863bf215546Sopenharmony_ci GLint *width, GLint *height, GLint *depth, 2864bf215546Sopenharmony_ci const struct gl_pixelstore_attrib *unpack, 2865bf215546Sopenharmony_ci struct gl_pixelstore_attrib *unpackNew) 2866bf215546Sopenharmony_ci{ 2867bf215546Sopenharmony_ci assert(width); 2868bf215546Sopenharmony_ci assert(height); 2869bf215546Sopenharmony_ci assert(depth); 2870bf215546Sopenharmony_ci 2871bf215546Sopenharmony_ci *unpackNew = *unpack; 2872bf215546Sopenharmony_ci 2873bf215546Sopenharmony_ci if (unpackNew->RowLength == 0) 2874bf215546Sopenharmony_ci unpackNew->RowLength = *width; 2875bf215546Sopenharmony_ci 2876bf215546Sopenharmony_ci if (unpackNew->ImageHeight == 0) 2877bf215546Sopenharmony_ci unpackNew->ImageHeight = *height; 2878bf215546Sopenharmony_ci 2879bf215546Sopenharmony_ci assert(*width >= 3); 2880bf215546Sopenharmony_ci unpackNew->SkipPixels++; /* skip the border */ 2881bf215546Sopenharmony_ci *width = *width - 2; /* reduce the width by two border pixels */ 2882bf215546Sopenharmony_ci 2883bf215546Sopenharmony_ci /* The min height of a texture with a border is 3 */ 2884bf215546Sopenharmony_ci if (*height >= 3 && target != GL_TEXTURE_1D_ARRAY) { 2885bf215546Sopenharmony_ci unpackNew->SkipRows++; /* skip the border */ 2886bf215546Sopenharmony_ci *height = *height - 2; /* reduce the height by two border pixels */ 2887bf215546Sopenharmony_ci } 2888bf215546Sopenharmony_ci 2889bf215546Sopenharmony_ci if (*depth >= 3 && 2890bf215546Sopenharmony_ci target != GL_TEXTURE_2D_ARRAY && 2891bf215546Sopenharmony_ci target != GL_TEXTURE_CUBE_MAP_ARRAY) { 2892bf215546Sopenharmony_ci unpackNew->SkipImages++; /* skip the border */ 2893bf215546Sopenharmony_ci *depth = *depth - 2; /* reduce the depth by two border pixels */ 2894bf215546Sopenharmony_ci } 2895bf215546Sopenharmony_ci} 2896bf215546Sopenharmony_ci 2897bf215546Sopenharmony_cistatic struct gl_texture_object * 2898bf215546Sopenharmony_cilookup_texture_ext_dsa(struct gl_context *ctx, GLenum target, GLuint texture, 2899bf215546Sopenharmony_ci const char *caller) 2900bf215546Sopenharmony_ci{ 2901bf215546Sopenharmony_ci GLenum boundTarget; 2902bf215546Sopenharmony_ci switch (target) { 2903bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 2904bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 2905bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 2906bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 2907bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 2908bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 2909bf215546Sopenharmony_ci boundTarget = GL_TEXTURE_CUBE_MAP; 2910bf215546Sopenharmony_ci break; 2911bf215546Sopenharmony_ci default: 2912bf215546Sopenharmony_ci boundTarget = target; 2913bf215546Sopenharmony_ci break; 2914bf215546Sopenharmony_ci } 2915bf215546Sopenharmony_ci 2916bf215546Sopenharmony_ci int targetIndex = _mesa_tex_target_to_index(ctx, boundTarget); 2917bf215546Sopenharmony_ci if (targetIndex < 0) { 2918bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, "%s(target = %s)", caller, 2919bf215546Sopenharmony_ci _mesa_enum_to_string(target)); 2920bf215546Sopenharmony_ci return NULL; 2921bf215546Sopenharmony_ci } 2922bf215546Sopenharmony_ci assert(targetIndex < NUM_TEXTURE_TARGETS); 2923bf215546Sopenharmony_ci 2924bf215546Sopenharmony_ci struct gl_texture_object *texObj; 2925bf215546Sopenharmony_ci if (texture == 0) { 2926bf215546Sopenharmony_ci /* Use a default texture object */ 2927bf215546Sopenharmony_ci texObj = ctx->Shared->DefaultTex[targetIndex]; 2928bf215546Sopenharmony_ci assert(texObj); 2929bf215546Sopenharmony_ci } else { 2930bf215546Sopenharmony_ci bool isGenName; 2931bf215546Sopenharmony_ci texObj = _mesa_lookup_texture(ctx, texture); 2932bf215546Sopenharmony_ci isGenName = texObj != NULL; 2933bf215546Sopenharmony_ci if (!texObj && ctx->API == API_OPENGL_CORE) { 2934bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-gen name)", caller); 2935bf215546Sopenharmony_ci return NULL; 2936bf215546Sopenharmony_ci } 2937bf215546Sopenharmony_ci 2938bf215546Sopenharmony_ci if (!texObj) { 2939bf215546Sopenharmony_ci texObj = _mesa_new_texture_object(ctx, texture, boundTarget); 2940bf215546Sopenharmony_ci if (!texObj) { 2941bf215546Sopenharmony_ci _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller); 2942bf215546Sopenharmony_ci return NULL; 2943bf215546Sopenharmony_ci } 2944bf215546Sopenharmony_ci 2945bf215546Sopenharmony_ci /* insert into hash table */ 2946bf215546Sopenharmony_ci _mesa_HashInsert(ctx->Shared->TexObjects, texObj->Name, texObj, isGenName); 2947bf215546Sopenharmony_ci } 2948bf215546Sopenharmony_ci 2949bf215546Sopenharmony_ci if (texObj->Target != boundTarget) { 2950bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, "%s(%s != %s)", 2951bf215546Sopenharmony_ci caller, _mesa_enum_to_string(texObj->Target), 2952bf215546Sopenharmony_ci _mesa_enum_to_string(target)); 2953bf215546Sopenharmony_ci return NULL; 2954bf215546Sopenharmony_ci } 2955bf215546Sopenharmony_ci } 2956bf215546Sopenharmony_ci 2957bf215546Sopenharmony_ci return texObj; 2958bf215546Sopenharmony_ci} 2959bf215546Sopenharmony_ci 2960bf215546Sopenharmony_ci/** 2961bf215546Sopenharmony_ci * Common code to implement all the glTexImage1D/2D/3D functions, 2962bf215546Sopenharmony_ci * glCompressedTexImage1D/2D/3D and glTextureImage1D/2D/3DEXT 2963bf215546Sopenharmony_ci * \param compressed only GL_TRUE for glCompressedTexImage1D/2D/3D calls. 2964bf215546Sopenharmony_ci * \param format the user's image format (only used if !compressed) 2965bf215546Sopenharmony_ci * \param type the user's image type (only used if !compressed) 2966bf215546Sopenharmony_ci * \param imageSize only used for glCompressedTexImage1D/2D/3D calls. 2967bf215546Sopenharmony_ci */ 2968bf215546Sopenharmony_cistatic ALWAYS_INLINE void 2969bf215546Sopenharmony_citeximage(struct gl_context *ctx, GLboolean compressed, GLuint dims, 2970bf215546Sopenharmony_ci struct gl_texture_object *texObj, 2971bf215546Sopenharmony_ci GLenum target, GLint level, GLint internalFormat, 2972bf215546Sopenharmony_ci GLsizei width, GLsizei height, GLsizei depth, 2973bf215546Sopenharmony_ci GLint border, GLenum format, GLenum type, 2974bf215546Sopenharmony_ci GLsizei imageSize, const GLvoid *pixels, bool no_error) 2975bf215546Sopenharmony_ci{ 2976bf215546Sopenharmony_ci const char *func = compressed ? "glCompressedTexImage" : "glTexImage"; 2977bf215546Sopenharmony_ci struct gl_pixelstore_attrib unpack_no_border; 2978bf215546Sopenharmony_ci const struct gl_pixelstore_attrib *unpack = &ctx->Unpack; 2979bf215546Sopenharmony_ci mesa_format texFormat; 2980bf215546Sopenharmony_ci bool dimensionsOK = true, sizeOK = true; 2981bf215546Sopenharmony_ci 2982bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, 0, 0); 2983bf215546Sopenharmony_ci 2984bf215546Sopenharmony_ci if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) { 2985bf215546Sopenharmony_ci if (compressed) 2986bf215546Sopenharmony_ci _mesa_debug(ctx, 2987bf215546Sopenharmony_ci "glCompressedTexImage%uD %s %d %s %d %d %d %d %p\n", 2988bf215546Sopenharmony_ci dims, 2989bf215546Sopenharmony_ci _mesa_enum_to_string(target), level, 2990bf215546Sopenharmony_ci _mesa_enum_to_string(internalFormat), 2991bf215546Sopenharmony_ci width, height, depth, border, pixels); 2992bf215546Sopenharmony_ci else 2993bf215546Sopenharmony_ci _mesa_debug(ctx, 2994bf215546Sopenharmony_ci "glTexImage%uD %s %d %s %d %d %d %d %s %s %p\n", 2995bf215546Sopenharmony_ci dims, 2996bf215546Sopenharmony_ci _mesa_enum_to_string(target), level, 2997bf215546Sopenharmony_ci _mesa_enum_to_string(internalFormat), 2998bf215546Sopenharmony_ci width, height, depth, border, 2999bf215546Sopenharmony_ci _mesa_enum_to_string(format), 3000bf215546Sopenharmony_ci _mesa_enum_to_string(type), pixels); 3001bf215546Sopenharmony_ci } 3002bf215546Sopenharmony_ci 3003bf215546Sopenharmony_ci internalFormat = override_internal_format(internalFormat, width, height); 3004bf215546Sopenharmony_ci 3005bf215546Sopenharmony_ci if (!no_error && 3006bf215546Sopenharmony_ci /* target error checking */ 3007bf215546Sopenharmony_ci !legal_teximage_target(ctx, dims, target)) { 3008bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, "%s%uD(target=%s)", 3009bf215546Sopenharmony_ci func, dims, _mesa_enum_to_string(target)); 3010bf215546Sopenharmony_ci return; 3011bf215546Sopenharmony_ci } 3012bf215546Sopenharmony_ci 3013bf215546Sopenharmony_ci if (!texObj) 3014bf215546Sopenharmony_ci texObj = _mesa_get_current_tex_object(ctx, target); 3015bf215546Sopenharmony_ci 3016bf215546Sopenharmony_ci if (!no_error) { 3017bf215546Sopenharmony_ci /* general error checking */ 3018bf215546Sopenharmony_ci if (compressed) { 3019bf215546Sopenharmony_ci if (compressed_texture_error_check(ctx, dims, target, texObj, 3020bf215546Sopenharmony_ci level, internalFormat, 3021bf215546Sopenharmony_ci width, height, depth, 3022bf215546Sopenharmony_ci border, imageSize, pixels)) 3023bf215546Sopenharmony_ci return; 3024bf215546Sopenharmony_ci } else { 3025bf215546Sopenharmony_ci if (texture_error_check(ctx, dims, target, texObj, level, internalFormat, 3026bf215546Sopenharmony_ci format, type, width, height, depth, border, 3027bf215546Sopenharmony_ci pixels)) 3028bf215546Sopenharmony_ci return; 3029bf215546Sopenharmony_ci } 3030bf215546Sopenharmony_ci } 3031bf215546Sopenharmony_ci assert(texObj); 3032bf215546Sopenharmony_ci 3033bf215546Sopenharmony_ci /* Here we convert a cpal compressed image into a regular glTexImage2D 3034bf215546Sopenharmony_ci * call by decompressing the texture. If we really want to support cpal 3035bf215546Sopenharmony_ci * textures in any driver this would have to be changed. 3036bf215546Sopenharmony_ci */ 3037bf215546Sopenharmony_ci if (ctx->API == API_OPENGLES && compressed && dims == 2) { 3038bf215546Sopenharmony_ci switch (internalFormat) { 3039bf215546Sopenharmony_ci case GL_PALETTE4_RGB8_OES: 3040bf215546Sopenharmony_ci case GL_PALETTE4_RGBA8_OES: 3041bf215546Sopenharmony_ci case GL_PALETTE4_R5_G6_B5_OES: 3042bf215546Sopenharmony_ci case GL_PALETTE4_RGBA4_OES: 3043bf215546Sopenharmony_ci case GL_PALETTE4_RGB5_A1_OES: 3044bf215546Sopenharmony_ci case GL_PALETTE8_RGB8_OES: 3045bf215546Sopenharmony_ci case GL_PALETTE8_RGBA8_OES: 3046bf215546Sopenharmony_ci case GL_PALETTE8_R5_G6_B5_OES: 3047bf215546Sopenharmony_ci case GL_PALETTE8_RGBA4_OES: 3048bf215546Sopenharmony_ci case GL_PALETTE8_RGB5_A1_OES: 3049bf215546Sopenharmony_ci _mesa_cpal_compressed_teximage2d(target, level, internalFormat, 3050bf215546Sopenharmony_ci width, height, imageSize, pixels); 3051bf215546Sopenharmony_ci return; 3052bf215546Sopenharmony_ci } 3053bf215546Sopenharmony_ci } 3054bf215546Sopenharmony_ci 3055bf215546Sopenharmony_ci if (compressed) { 3056bf215546Sopenharmony_ci /* For glCompressedTexImage() the driver has no choice about the 3057bf215546Sopenharmony_ci * texture format since we'll never transcode the user's compressed 3058bf215546Sopenharmony_ci * image data. The internalFormat was error checked earlier. 3059bf215546Sopenharmony_ci */ 3060bf215546Sopenharmony_ci texFormat = _mesa_glenum_to_compressed_format(internalFormat); 3061bf215546Sopenharmony_ci } 3062bf215546Sopenharmony_ci else { 3063bf215546Sopenharmony_ci /* In case of HALF_FLOAT_OES or FLOAT_OES, find corresponding sized 3064bf215546Sopenharmony_ci * internal floating point format for the given base format. 3065bf215546Sopenharmony_ci */ 3066bf215546Sopenharmony_ci if (_mesa_is_gles(ctx) && format == internalFormat) { 3067bf215546Sopenharmony_ci if (type == GL_FLOAT) { 3068bf215546Sopenharmony_ci texObj->_IsFloat = GL_TRUE; 3069bf215546Sopenharmony_ci } else if (type == GL_HALF_FLOAT_OES || type == GL_HALF_FLOAT) { 3070bf215546Sopenharmony_ci texObj->_IsHalfFloat = GL_TRUE; 3071bf215546Sopenharmony_ci } 3072bf215546Sopenharmony_ci 3073bf215546Sopenharmony_ci internalFormat = adjust_for_oes_float_texture(ctx, format, type); 3074bf215546Sopenharmony_ci } 3075bf215546Sopenharmony_ci 3076bf215546Sopenharmony_ci texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, 3077bf215546Sopenharmony_ci internalFormat, format, type); 3078bf215546Sopenharmony_ci } 3079bf215546Sopenharmony_ci 3080bf215546Sopenharmony_ci assert(texFormat != MESA_FORMAT_NONE); 3081bf215546Sopenharmony_ci 3082bf215546Sopenharmony_ci if (!no_error) { 3083bf215546Sopenharmony_ci /* check that width, height, depth are legal for the mipmap level */ 3084bf215546Sopenharmony_ci dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, level, width, 3085bf215546Sopenharmony_ci height, depth, border); 3086bf215546Sopenharmony_ci 3087bf215546Sopenharmony_ci /* check that the texture won't take too much memory, etc */ 3088bf215546Sopenharmony_ci sizeOK = st_TestProxyTexImage(ctx, proxy_target(target), 3089bf215546Sopenharmony_ci 0, level, texFormat, 1, 3090bf215546Sopenharmony_ci width, height, depth); 3091bf215546Sopenharmony_ci } 3092bf215546Sopenharmony_ci 3093bf215546Sopenharmony_ci if (_mesa_is_proxy_texture(target)) { 3094bf215546Sopenharmony_ci /* Proxy texture: just clear or set state depending on error checking */ 3095bf215546Sopenharmony_ci struct gl_texture_image *texImage = 3096bf215546Sopenharmony_ci get_proxy_tex_image(ctx, target, level); 3097bf215546Sopenharmony_ci 3098bf215546Sopenharmony_ci if (!texImage) 3099bf215546Sopenharmony_ci return; /* GL_OUT_OF_MEMORY already recorded */ 3100bf215546Sopenharmony_ci 3101bf215546Sopenharmony_ci if (dimensionsOK && sizeOK) { 3102bf215546Sopenharmony_ci _mesa_init_teximage_fields(ctx, texImage, width, height, depth, 3103bf215546Sopenharmony_ci border, internalFormat, texFormat); 3104bf215546Sopenharmony_ci } 3105bf215546Sopenharmony_ci else { 3106bf215546Sopenharmony_ci clear_teximage_fields(texImage); 3107bf215546Sopenharmony_ci } 3108bf215546Sopenharmony_ci } 3109bf215546Sopenharmony_ci else { 3110bf215546Sopenharmony_ci /* non-proxy target */ 3111bf215546Sopenharmony_ci const GLuint face = _mesa_tex_target_to_face(target); 3112bf215546Sopenharmony_ci struct gl_texture_image *texImage; 3113bf215546Sopenharmony_ci 3114bf215546Sopenharmony_ci if (!dimensionsOK) { 3115bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, 3116bf215546Sopenharmony_ci "%s%uD(invalid width=%d or height=%d or depth=%d)", 3117bf215546Sopenharmony_ci func, dims, width, height, depth); 3118bf215546Sopenharmony_ci return; 3119bf215546Sopenharmony_ci } 3120bf215546Sopenharmony_ci 3121bf215546Sopenharmony_ci if (!sizeOK) { 3122bf215546Sopenharmony_ci _mesa_error(ctx, GL_OUT_OF_MEMORY, 3123bf215546Sopenharmony_ci "%s%uD(image too large: %d x %d x %d, %s format)", 3124bf215546Sopenharmony_ci func, dims, width, height, depth, 3125bf215546Sopenharmony_ci _mesa_enum_to_string(internalFormat)); 3126bf215546Sopenharmony_ci return; 3127bf215546Sopenharmony_ci } 3128bf215546Sopenharmony_ci 3129bf215546Sopenharmony_ci /* Allow a hardware driver to just strip out the border, to provide 3130bf215546Sopenharmony_ci * reliable but slightly incorrect hardware rendering instead of 3131bf215546Sopenharmony_ci * rarely-tested software fallback rendering. 3132bf215546Sopenharmony_ci */ 3133bf215546Sopenharmony_ci if (border) { 3134bf215546Sopenharmony_ci strip_texture_border(target, &width, &height, &depth, unpack, 3135bf215546Sopenharmony_ci &unpack_no_border); 3136bf215546Sopenharmony_ci border = 0; 3137bf215546Sopenharmony_ci unpack = &unpack_no_border; 3138bf215546Sopenharmony_ci } 3139bf215546Sopenharmony_ci 3140bf215546Sopenharmony_ci _mesa_update_pixel(ctx); 3141bf215546Sopenharmony_ci 3142bf215546Sopenharmony_ci _mesa_lock_texture(ctx, texObj); 3143bf215546Sopenharmony_ci { 3144bf215546Sopenharmony_ci texObj->External = GL_FALSE; 3145bf215546Sopenharmony_ci 3146bf215546Sopenharmony_ci texImage = _mesa_get_tex_image(ctx, texObj, target, level); 3147bf215546Sopenharmony_ci 3148bf215546Sopenharmony_ci if (!texImage) { 3149bf215546Sopenharmony_ci _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s%uD", func, dims); 3150bf215546Sopenharmony_ci } 3151bf215546Sopenharmony_ci else { 3152bf215546Sopenharmony_ci st_FreeTextureImageBuffer(ctx, texImage); 3153bf215546Sopenharmony_ci 3154bf215546Sopenharmony_ci _mesa_init_teximage_fields(ctx, texImage, 3155bf215546Sopenharmony_ci width, height, depth, 3156bf215546Sopenharmony_ci border, internalFormat, texFormat); 3157bf215546Sopenharmony_ci 3158bf215546Sopenharmony_ci /* Give the texture to the driver. <pixels> may be null. */ 3159bf215546Sopenharmony_ci if (width > 0 && height > 0 && depth > 0) { 3160bf215546Sopenharmony_ci if (compressed) { 3161bf215546Sopenharmony_ci st_CompressedTexImage(ctx, dims, texImage, 3162bf215546Sopenharmony_ci imageSize, pixels); 3163bf215546Sopenharmony_ci } 3164bf215546Sopenharmony_ci else { 3165bf215546Sopenharmony_ci st_TexImage(ctx, dims, texImage, format, 3166bf215546Sopenharmony_ci type, pixels, unpack); 3167bf215546Sopenharmony_ci } 3168bf215546Sopenharmony_ci } 3169bf215546Sopenharmony_ci 3170bf215546Sopenharmony_ci check_gen_mipmap(ctx, target, texObj, level); 3171bf215546Sopenharmony_ci 3172bf215546Sopenharmony_ci _mesa_update_fbo_texture(ctx, texObj, face, level); 3173bf215546Sopenharmony_ci 3174bf215546Sopenharmony_ci _mesa_dirty_texobj(ctx, texObj); 3175bf215546Sopenharmony_ci } 3176bf215546Sopenharmony_ci } 3177bf215546Sopenharmony_ci _mesa_unlock_texture(ctx, texObj); 3178bf215546Sopenharmony_ci } 3179bf215546Sopenharmony_ci} 3180bf215546Sopenharmony_ci 3181bf215546Sopenharmony_ci 3182bf215546Sopenharmony_ci/* This is a wrapper around teximage() so that we can force the KHR_no_error 3183bf215546Sopenharmony_ci * logic to be inlined without inlining the function into all the callers. 3184bf215546Sopenharmony_ci */ 3185bf215546Sopenharmony_cistatic void 3186bf215546Sopenharmony_citeximage_err(struct gl_context *ctx, GLboolean compressed, GLuint dims, 3187bf215546Sopenharmony_ci GLenum target, GLint level, GLint internalFormat, 3188bf215546Sopenharmony_ci GLsizei width, GLsizei height, GLsizei depth, 3189bf215546Sopenharmony_ci GLint border, GLenum format, GLenum type, 3190bf215546Sopenharmony_ci GLsizei imageSize, const GLvoid *pixels) 3191bf215546Sopenharmony_ci{ 3192bf215546Sopenharmony_ci teximage(ctx, compressed, dims, NULL, target, level, internalFormat, width, height, 3193bf215546Sopenharmony_ci depth, border, format, type, imageSize, pixels, false); 3194bf215546Sopenharmony_ci} 3195bf215546Sopenharmony_ci 3196bf215546Sopenharmony_ci 3197bf215546Sopenharmony_cistatic void 3198bf215546Sopenharmony_citeximage_no_error(struct gl_context *ctx, GLboolean compressed, GLuint dims, 3199bf215546Sopenharmony_ci GLenum target, GLint level, GLint internalFormat, 3200bf215546Sopenharmony_ci GLsizei width, GLsizei height, GLsizei depth, 3201bf215546Sopenharmony_ci GLint border, GLenum format, GLenum type, 3202bf215546Sopenharmony_ci GLsizei imageSize, const GLvoid *pixels) 3203bf215546Sopenharmony_ci{ 3204bf215546Sopenharmony_ci teximage(ctx, compressed, dims, NULL, target, level, internalFormat, width, height, 3205bf215546Sopenharmony_ci depth, border, format, type, imageSize, pixels, true); 3206bf215546Sopenharmony_ci} 3207bf215546Sopenharmony_ci 3208bf215546Sopenharmony_ci 3209bf215546Sopenharmony_ci/* 3210bf215546Sopenharmony_ci * Called from the API. Note that width includes the border. 3211bf215546Sopenharmony_ci */ 3212bf215546Sopenharmony_civoid GLAPIENTRY 3213bf215546Sopenharmony_ci_mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, 3214bf215546Sopenharmony_ci GLsizei width, GLint border, GLenum format, 3215bf215546Sopenharmony_ci GLenum type, const GLvoid *pixels ) 3216bf215546Sopenharmony_ci{ 3217bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 3218bf215546Sopenharmony_ci teximage_err(ctx, GL_FALSE, 1, target, level, internalFormat, width, 1, 1, 3219bf215546Sopenharmony_ci border, format, type, 0, pixels); 3220bf215546Sopenharmony_ci} 3221bf215546Sopenharmony_ci 3222bf215546Sopenharmony_civoid GLAPIENTRY 3223bf215546Sopenharmony_ci_mesa_TextureImage1DEXT(GLuint texture, GLenum target, GLint level, 3224bf215546Sopenharmony_ci GLint internalFormat, GLsizei width, GLint border, 3225bf215546Sopenharmony_ci GLenum format, GLenum type, const GLvoid *pixels ) 3226bf215546Sopenharmony_ci{ 3227bf215546Sopenharmony_ci struct gl_texture_object* texObj; 3228bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 3229bf215546Sopenharmony_ci 3230bf215546Sopenharmony_ci texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, 3231bf215546Sopenharmony_ci "glTextureImage1DEXT"); 3232bf215546Sopenharmony_ci if (!texObj) 3233bf215546Sopenharmony_ci return; 3234bf215546Sopenharmony_ci teximage(ctx, GL_FALSE, 1, texObj, target, level, internalFormat, 3235bf215546Sopenharmony_ci width, 1, 1, border, format, type, 0, pixels, false); 3236bf215546Sopenharmony_ci} 3237bf215546Sopenharmony_ci 3238bf215546Sopenharmony_civoid GLAPIENTRY 3239bf215546Sopenharmony_ci_mesa_MultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level, 3240bf215546Sopenharmony_ci GLint internalFormat, GLsizei width, GLint border, 3241bf215546Sopenharmony_ci GLenum format, GLenum type, const GLvoid *pixels ) 3242bf215546Sopenharmony_ci{ 3243bf215546Sopenharmony_ci struct gl_texture_object* texObj; 3244bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 3245bf215546Sopenharmony_ci 3246bf215546Sopenharmony_ci texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, 3247bf215546Sopenharmony_ci texunit - GL_TEXTURE0, 3248bf215546Sopenharmony_ci true, 3249bf215546Sopenharmony_ci "glMultiTexImage1DEXT"); 3250bf215546Sopenharmony_ci if (!texObj) 3251bf215546Sopenharmony_ci return; 3252bf215546Sopenharmony_ci teximage(ctx, GL_FALSE, 1, texObj, target, level, internalFormat, width, 1, 1, 3253bf215546Sopenharmony_ci border, format, type, 0, pixels, false); 3254bf215546Sopenharmony_ci} 3255bf215546Sopenharmony_ci 3256bf215546Sopenharmony_civoid GLAPIENTRY 3257bf215546Sopenharmony_ci_mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, 3258bf215546Sopenharmony_ci GLsizei width, GLsizei height, GLint border, 3259bf215546Sopenharmony_ci GLenum format, GLenum type, 3260bf215546Sopenharmony_ci const GLvoid *pixels ) 3261bf215546Sopenharmony_ci{ 3262bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 3263bf215546Sopenharmony_ci teximage_err(ctx, GL_FALSE, 2, target, level, internalFormat, width, height, 1, 3264bf215546Sopenharmony_ci border, format, type, 0, pixels); 3265bf215546Sopenharmony_ci} 3266bf215546Sopenharmony_ci 3267bf215546Sopenharmony_civoid GLAPIENTRY 3268bf215546Sopenharmony_ci_mesa_TextureImage2DEXT(GLuint texture, GLenum target, GLint level, 3269bf215546Sopenharmony_ci GLint internalFormat, GLsizei width, GLsizei height, 3270bf215546Sopenharmony_ci GLint border, 3271bf215546Sopenharmony_ci GLenum format, GLenum type, const GLvoid *pixels ) 3272bf215546Sopenharmony_ci{ 3273bf215546Sopenharmony_ci struct gl_texture_object* texObj; 3274bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 3275bf215546Sopenharmony_ci 3276bf215546Sopenharmony_ci texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, 3277bf215546Sopenharmony_ci "glTextureImage2DEXT"); 3278bf215546Sopenharmony_ci if (!texObj) 3279bf215546Sopenharmony_ci return; 3280bf215546Sopenharmony_ci teximage(ctx, GL_FALSE, 2, texObj, target, level, internalFormat, 3281bf215546Sopenharmony_ci width, height, 1, border, format, type, 0, pixels, false); 3282bf215546Sopenharmony_ci} 3283bf215546Sopenharmony_ci 3284bf215546Sopenharmony_civoid GLAPIENTRY 3285bf215546Sopenharmony_ci_mesa_MultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level, 3286bf215546Sopenharmony_ci GLint internalFormat, GLsizei width, GLsizei height, 3287bf215546Sopenharmony_ci GLint border, 3288bf215546Sopenharmony_ci GLenum format, GLenum type, const GLvoid *pixels ) 3289bf215546Sopenharmony_ci{ 3290bf215546Sopenharmony_ci struct gl_texture_object* texObj; 3291bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 3292bf215546Sopenharmony_ci 3293bf215546Sopenharmony_ci texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, 3294bf215546Sopenharmony_ci texunit - GL_TEXTURE0, 3295bf215546Sopenharmony_ci true, 3296bf215546Sopenharmony_ci "glMultiTexImage2DEXT"); 3297bf215546Sopenharmony_ci if (!texObj) 3298bf215546Sopenharmony_ci return; 3299bf215546Sopenharmony_ci teximage(ctx, GL_FALSE, 2, texObj, target, level, internalFormat, width, height, 1, 3300bf215546Sopenharmony_ci border, format, type, 0, pixels, false); 3301bf215546Sopenharmony_ci} 3302bf215546Sopenharmony_ci 3303bf215546Sopenharmony_ci/* 3304bf215546Sopenharmony_ci * Called by the API or display list executor. 3305bf215546Sopenharmony_ci * Note that width and height include the border. 3306bf215546Sopenharmony_ci */ 3307bf215546Sopenharmony_civoid GLAPIENTRY 3308bf215546Sopenharmony_ci_mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat, 3309bf215546Sopenharmony_ci GLsizei width, GLsizei height, GLsizei depth, 3310bf215546Sopenharmony_ci GLint border, GLenum format, GLenum type, 3311bf215546Sopenharmony_ci const GLvoid *pixels ) 3312bf215546Sopenharmony_ci{ 3313bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 3314bf215546Sopenharmony_ci teximage_err(ctx, GL_FALSE, 3, target, level, internalFormat, 3315bf215546Sopenharmony_ci width, height, depth, border, format, type, 0, pixels); 3316bf215546Sopenharmony_ci} 3317bf215546Sopenharmony_ci 3318bf215546Sopenharmony_civoid GLAPIENTRY 3319bf215546Sopenharmony_ci_mesa_TextureImage3DEXT(GLuint texture, GLenum target, GLint level, 3320bf215546Sopenharmony_ci GLint internalFormat, GLsizei width, GLsizei height, 3321bf215546Sopenharmony_ci GLsizei depth, GLint border, 3322bf215546Sopenharmony_ci GLenum format, GLenum type, const GLvoid *pixels ) 3323bf215546Sopenharmony_ci{ 3324bf215546Sopenharmony_ci struct gl_texture_object* texObj; 3325bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 3326bf215546Sopenharmony_ci 3327bf215546Sopenharmony_ci texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, 3328bf215546Sopenharmony_ci "glTextureImage3DEXT"); 3329bf215546Sopenharmony_ci if (!texObj) 3330bf215546Sopenharmony_ci return; 3331bf215546Sopenharmony_ci teximage(ctx, GL_FALSE, 3, texObj, target, level, internalFormat, 3332bf215546Sopenharmony_ci width, height, depth, border, format, type, 0, pixels, false); 3333bf215546Sopenharmony_ci} 3334bf215546Sopenharmony_ci 3335bf215546Sopenharmony_ci 3336bf215546Sopenharmony_civoid GLAPIENTRY 3337bf215546Sopenharmony_ci_mesa_MultiTexImage3DEXT(GLenum texunit, GLenum target, GLint level, 3338bf215546Sopenharmony_ci GLint internalFormat, GLsizei width, GLsizei height, 3339bf215546Sopenharmony_ci GLsizei depth, GLint border, GLenum format, GLenum type, 3340bf215546Sopenharmony_ci const GLvoid *pixels ) 3341bf215546Sopenharmony_ci{ 3342bf215546Sopenharmony_ci struct gl_texture_object* texObj; 3343bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 3344bf215546Sopenharmony_ci 3345bf215546Sopenharmony_ci texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, 3346bf215546Sopenharmony_ci texunit - GL_TEXTURE0, 3347bf215546Sopenharmony_ci true, 3348bf215546Sopenharmony_ci "glMultiTexImage3DEXT"); 3349bf215546Sopenharmony_ci if (!texObj) 3350bf215546Sopenharmony_ci return; 3351bf215546Sopenharmony_ci teximage(ctx, GL_FALSE, 3, texObj, target, level, internalFormat, 3352bf215546Sopenharmony_ci width, height, depth, border, format, type, 0, pixels, false); 3353bf215546Sopenharmony_ci} 3354bf215546Sopenharmony_ci 3355bf215546Sopenharmony_ci 3356bf215546Sopenharmony_civoid GLAPIENTRY 3357bf215546Sopenharmony_ci_mesa_TexImage1D_no_error(GLenum target, GLint level, GLint internalFormat, 3358bf215546Sopenharmony_ci GLsizei width, GLint border, GLenum format, 3359bf215546Sopenharmony_ci GLenum type, const GLvoid *pixels) 3360bf215546Sopenharmony_ci{ 3361bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 3362bf215546Sopenharmony_ci teximage_no_error(ctx, GL_FALSE, 1, target, level, internalFormat, width, 1, 3363bf215546Sopenharmony_ci 1, border, format, type, 0, pixels); 3364bf215546Sopenharmony_ci} 3365bf215546Sopenharmony_ci 3366bf215546Sopenharmony_ci 3367bf215546Sopenharmony_civoid GLAPIENTRY 3368bf215546Sopenharmony_ci_mesa_TexImage2D_no_error(GLenum target, GLint level, GLint internalFormat, 3369bf215546Sopenharmony_ci GLsizei width, GLsizei height, GLint border, 3370bf215546Sopenharmony_ci GLenum format, GLenum type, const GLvoid *pixels) 3371bf215546Sopenharmony_ci{ 3372bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 3373bf215546Sopenharmony_ci teximage_no_error(ctx, GL_FALSE, 2, target, level, internalFormat, width, 3374bf215546Sopenharmony_ci height, 1, border, format, type, 0, pixels); 3375bf215546Sopenharmony_ci} 3376bf215546Sopenharmony_ci 3377bf215546Sopenharmony_ci 3378bf215546Sopenharmony_civoid GLAPIENTRY 3379bf215546Sopenharmony_ci_mesa_TexImage3D_no_error(GLenum target, GLint level, GLint internalFormat, 3380bf215546Sopenharmony_ci GLsizei width, GLsizei height, GLsizei depth, 3381bf215546Sopenharmony_ci GLint border, GLenum format, GLenum type, 3382bf215546Sopenharmony_ci const GLvoid *pixels ) 3383bf215546Sopenharmony_ci{ 3384bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 3385bf215546Sopenharmony_ci teximage_no_error(ctx, GL_FALSE, 3, target, level, internalFormat, 3386bf215546Sopenharmony_ci width, height, depth, border, format, type, 0, pixels); 3387bf215546Sopenharmony_ci} 3388bf215546Sopenharmony_ci 3389bf215546Sopenharmony_ci/* 3390bf215546Sopenharmony_ci * Helper used by __mesa_EGLImageTargetTexture2DOES and 3391bf215546Sopenharmony_ci * _mesa_EGLImageTargetTexStorageEXT. 3392bf215546Sopenharmony_ci */ 3393bf215546Sopenharmony_cistatic void 3394bf215546Sopenharmony_ciegl_image_target_texture(struct gl_context *ctx, 3395bf215546Sopenharmony_ci struct gl_texture_object *texObj, GLenum target, 3396bf215546Sopenharmony_ci GLeglImageOES image, bool tex_storage, 3397bf215546Sopenharmony_ci const char *caller) 3398bf215546Sopenharmony_ci{ 3399bf215546Sopenharmony_ci struct gl_texture_image *texImage; 3400bf215546Sopenharmony_ci bool valid_target; 3401bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, 0, 0); 3402bf215546Sopenharmony_ci 3403bf215546Sopenharmony_ci switch (target) { 3404bf215546Sopenharmony_ci case GL_TEXTURE_2D: 3405bf215546Sopenharmony_ci valid_target = _mesa_has_OES_EGL_image(ctx) || 3406bf215546Sopenharmony_ci (tex_storage && _mesa_has_EXT_EGL_image_storage(ctx)); 3407bf215546Sopenharmony_ci break; 3408bf215546Sopenharmony_ci case GL_TEXTURE_EXTERNAL_OES: 3409bf215546Sopenharmony_ci valid_target = _mesa_has_OES_EGL_image_external(ctx); 3410bf215546Sopenharmony_ci break; 3411bf215546Sopenharmony_ci default: 3412bf215546Sopenharmony_ci valid_target = false; 3413bf215546Sopenharmony_ci break; 3414bf215546Sopenharmony_ci } 3415bf215546Sopenharmony_ci 3416bf215546Sopenharmony_ci if (!valid_target) { 3417bf215546Sopenharmony_ci _mesa_error(ctx, tex_storage ? GL_INVALID_OPERATION : GL_INVALID_ENUM, "%s(target=%d)", caller, target); 3418bf215546Sopenharmony_ci return; 3419bf215546Sopenharmony_ci } 3420bf215546Sopenharmony_ci 3421bf215546Sopenharmony_ci if (!texObj) 3422bf215546Sopenharmony_ci texObj = _mesa_get_current_tex_object(ctx, target); 3423bf215546Sopenharmony_ci if (!texObj) 3424bf215546Sopenharmony_ci return; 3425bf215546Sopenharmony_ci 3426bf215546Sopenharmony_ci if (!image || (ctx->Driver.ValidateEGLImage && 3427bf215546Sopenharmony_ci !ctx->Driver.ValidateEGLImage(ctx, image))) { 3428bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, "%s(image=%p)", caller, image); 3429bf215546Sopenharmony_ci return; 3430bf215546Sopenharmony_ci } 3431bf215546Sopenharmony_ci 3432bf215546Sopenharmony_ci _mesa_lock_texture(ctx, texObj); 3433bf215546Sopenharmony_ci 3434bf215546Sopenharmony_ci if (texObj->Immutable) { 3435bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, "%s(texture is immutable)", caller); 3436bf215546Sopenharmony_ci _mesa_unlock_texture(ctx, texObj); 3437bf215546Sopenharmony_ci return; 3438bf215546Sopenharmony_ci } 3439bf215546Sopenharmony_ci 3440bf215546Sopenharmony_ci texImage = _mesa_get_tex_image(ctx, texObj, target, 0); 3441bf215546Sopenharmony_ci if (!texImage) { 3442bf215546Sopenharmony_ci _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller); 3443bf215546Sopenharmony_ci } else { 3444bf215546Sopenharmony_ci st_FreeTextureImageBuffer(ctx, texImage); 3445bf215546Sopenharmony_ci 3446bf215546Sopenharmony_ci texObj->External = GL_TRUE; 3447bf215546Sopenharmony_ci 3448bf215546Sopenharmony_ci if (tex_storage) { 3449bf215546Sopenharmony_ci st_egl_image_target_tex_storage(ctx, target, texObj, texImage, 3450bf215546Sopenharmony_ci image); 3451bf215546Sopenharmony_ci } else { 3452bf215546Sopenharmony_ci st_egl_image_target_texture_2d(ctx, target, texObj, texImage, 3453bf215546Sopenharmony_ci image); 3454bf215546Sopenharmony_ci } 3455bf215546Sopenharmony_ci 3456bf215546Sopenharmony_ci _mesa_dirty_texobj(ctx, texObj); 3457bf215546Sopenharmony_ci } 3458bf215546Sopenharmony_ci 3459bf215546Sopenharmony_ci if (tex_storage) 3460bf215546Sopenharmony_ci _mesa_set_texture_view_state(ctx, texObj, target, 1); 3461bf215546Sopenharmony_ci 3462bf215546Sopenharmony_ci _mesa_update_fbo_texture(ctx, texObj, 0, 0); 3463bf215546Sopenharmony_ci 3464bf215546Sopenharmony_ci _mesa_unlock_texture(ctx, texObj); 3465bf215546Sopenharmony_ci} 3466bf215546Sopenharmony_ci 3467bf215546Sopenharmony_civoid GLAPIENTRY 3468bf215546Sopenharmony_ci_mesa_EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image) 3469bf215546Sopenharmony_ci{ 3470bf215546Sopenharmony_ci const char *func = "glEGLImageTargetTexture2D"; 3471bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 3472bf215546Sopenharmony_ci 3473bf215546Sopenharmony_ci egl_image_target_texture(ctx, NULL, target, image, false, func); 3474bf215546Sopenharmony_ci} 3475bf215546Sopenharmony_ci 3476bf215546Sopenharmony_cistatic void 3477bf215546Sopenharmony_ciegl_image_target_texture_storage(struct gl_context *ctx, 3478bf215546Sopenharmony_ci struct gl_texture_object *texObj, GLenum target, 3479bf215546Sopenharmony_ci GLeglImageOES image, const GLint *attrib_list, 3480bf215546Sopenharmony_ci const char *caller) 3481bf215546Sopenharmony_ci{ 3482bf215546Sopenharmony_ci /* 3483bf215546Sopenharmony_ci * EXT_EGL_image_storage: 3484bf215546Sopenharmony_ci * 3485bf215546Sopenharmony_ci * "<attrib_list> must be NULL or a pointer to the value GL_NONE." 3486bf215546Sopenharmony_ci */ 3487bf215546Sopenharmony_ci if (attrib_list && attrib_list[0] != GL_NONE) { 3488bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, "%s(image=%p)", caller, image); 3489bf215546Sopenharmony_ci return; 3490bf215546Sopenharmony_ci } 3491bf215546Sopenharmony_ci 3492bf215546Sopenharmony_ci egl_image_target_texture(ctx, texObj, target, image, true, caller); 3493bf215546Sopenharmony_ci} 3494bf215546Sopenharmony_ci 3495bf215546Sopenharmony_ci 3496bf215546Sopenharmony_civoid GLAPIENTRY 3497bf215546Sopenharmony_ci_mesa_EGLImageTargetTexStorageEXT(GLenum target, GLeglImageOES image, 3498bf215546Sopenharmony_ci const GLint *attrib_list) 3499bf215546Sopenharmony_ci{ 3500bf215546Sopenharmony_ci const char *func = "glEGLImageTargetTexStorageEXT"; 3501bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 3502bf215546Sopenharmony_ci 3503bf215546Sopenharmony_ci egl_image_target_texture_storage(ctx, NULL, target, image, attrib_list, 3504bf215546Sopenharmony_ci func); 3505bf215546Sopenharmony_ci} 3506bf215546Sopenharmony_ci 3507bf215546Sopenharmony_civoid GLAPIENTRY 3508bf215546Sopenharmony_ci_mesa_EGLImageTargetTextureStorageEXT(GLuint texture, GLeglImageOES image, 3509bf215546Sopenharmony_ci const GLint *attrib_list) 3510bf215546Sopenharmony_ci{ 3511bf215546Sopenharmony_ci struct gl_texture_object *texObj; 3512bf215546Sopenharmony_ci const char *func = "glEGLImageTargetTextureStorageEXT"; 3513bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 3514bf215546Sopenharmony_ci 3515bf215546Sopenharmony_ci if (!(_mesa_is_desktop_gl(ctx) && ctx->Version >= 45) && 3516bf215546Sopenharmony_ci !_mesa_has_ARB_direct_state_access(ctx) && 3517bf215546Sopenharmony_ci !_mesa_has_EXT_direct_state_access(ctx)) { 3518bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, "direct access not supported"); 3519bf215546Sopenharmony_ci return; 3520bf215546Sopenharmony_ci } 3521bf215546Sopenharmony_ci 3522bf215546Sopenharmony_ci texObj = _mesa_lookup_texture_err(ctx, texture, func); 3523bf215546Sopenharmony_ci if (!texObj) 3524bf215546Sopenharmony_ci return; 3525bf215546Sopenharmony_ci 3526bf215546Sopenharmony_ci egl_image_target_texture_storage(ctx, texObj, texObj->Target, image, 3527bf215546Sopenharmony_ci attrib_list, func); 3528bf215546Sopenharmony_ci} 3529bf215546Sopenharmony_ci 3530bf215546Sopenharmony_ci/** 3531bf215546Sopenharmony_ci * Helper that implements the glTexSubImage1/2/3D() 3532bf215546Sopenharmony_ci * and glTextureSubImage1/2/3D() functions. 3533bf215546Sopenharmony_ci */ 3534bf215546Sopenharmony_cistatic void 3535bf215546Sopenharmony_citexture_sub_image(struct gl_context *ctx, GLuint dims, 3536bf215546Sopenharmony_ci struct gl_texture_object *texObj, 3537bf215546Sopenharmony_ci struct gl_texture_image *texImage, 3538bf215546Sopenharmony_ci GLenum target, GLint level, 3539bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, GLint zoffset, 3540bf215546Sopenharmony_ci GLsizei width, GLsizei height, GLsizei depth, 3541bf215546Sopenharmony_ci GLenum format, GLenum type, const GLvoid *pixels) 3542bf215546Sopenharmony_ci{ 3543bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, 0, 0); 3544bf215546Sopenharmony_ci 3545bf215546Sopenharmony_ci _mesa_update_pixel(ctx); 3546bf215546Sopenharmony_ci 3547bf215546Sopenharmony_ci _mesa_lock_texture(ctx, texObj); 3548bf215546Sopenharmony_ci { 3549bf215546Sopenharmony_ci if (width > 0 && height > 0 && depth > 0) { 3550bf215546Sopenharmony_ci /* If we have a border, offset=-1 is legal. Bias by border width. */ 3551bf215546Sopenharmony_ci switch (dims) { 3552bf215546Sopenharmony_ci case 3: 3553bf215546Sopenharmony_ci if (target != GL_TEXTURE_2D_ARRAY) 3554bf215546Sopenharmony_ci zoffset += texImage->Border; 3555bf215546Sopenharmony_ci FALLTHROUGH; 3556bf215546Sopenharmony_ci case 2: 3557bf215546Sopenharmony_ci if (target != GL_TEXTURE_1D_ARRAY) 3558bf215546Sopenharmony_ci yoffset += texImage->Border; 3559bf215546Sopenharmony_ci FALLTHROUGH; 3560bf215546Sopenharmony_ci case 1: 3561bf215546Sopenharmony_ci xoffset += texImage->Border; 3562bf215546Sopenharmony_ci } 3563bf215546Sopenharmony_ci 3564bf215546Sopenharmony_ci st_TexSubImage(ctx, dims, texImage, 3565bf215546Sopenharmony_ci xoffset, yoffset, zoffset, 3566bf215546Sopenharmony_ci width, height, depth, 3567bf215546Sopenharmony_ci format, type, pixels, &ctx->Unpack); 3568bf215546Sopenharmony_ci 3569bf215546Sopenharmony_ci check_gen_mipmap(ctx, target, texObj, level); 3570bf215546Sopenharmony_ci 3571bf215546Sopenharmony_ci /* NOTE: Don't signal _NEW_TEXTURE_OBJECT since we've only changed 3572bf215546Sopenharmony_ci * the texel data, not the texture format, size, etc. 3573bf215546Sopenharmony_ci */ 3574bf215546Sopenharmony_ci } 3575bf215546Sopenharmony_ci } 3576bf215546Sopenharmony_ci _mesa_unlock_texture(ctx, texObj); 3577bf215546Sopenharmony_ci} 3578bf215546Sopenharmony_ci 3579bf215546Sopenharmony_ci/** 3580bf215546Sopenharmony_ci * Implement all the glTexSubImage1/2/3D() functions. 3581bf215546Sopenharmony_ci * Must split this out this way because of GL_TEXTURE_CUBE_MAP. 3582bf215546Sopenharmony_ci */ 3583bf215546Sopenharmony_cistatic void 3584bf215546Sopenharmony_citexsubimage_err(struct gl_context *ctx, GLuint dims, GLenum target, GLint level, 3585bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, GLint zoffset, 3586bf215546Sopenharmony_ci GLsizei width, GLsizei height, GLsizei depth, 3587bf215546Sopenharmony_ci GLenum format, GLenum type, const GLvoid *pixels, 3588bf215546Sopenharmony_ci const char *callerName) 3589bf215546Sopenharmony_ci{ 3590bf215546Sopenharmony_ci struct gl_texture_object *texObj; 3591bf215546Sopenharmony_ci struct gl_texture_image *texImage; 3592bf215546Sopenharmony_ci 3593bf215546Sopenharmony_ci /* check target (proxies not allowed) */ 3594bf215546Sopenharmony_ci if (!legal_texsubimage_target(ctx, dims, target, false)) { 3595bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage%uD(target=%s)", 3596bf215546Sopenharmony_ci dims, _mesa_enum_to_string(target)); 3597bf215546Sopenharmony_ci return; 3598bf215546Sopenharmony_ci } 3599bf215546Sopenharmony_ci 3600bf215546Sopenharmony_ci texObj = _mesa_get_current_tex_object(ctx, target); 3601bf215546Sopenharmony_ci if (!texObj) 3602bf215546Sopenharmony_ci return; 3603bf215546Sopenharmony_ci 3604bf215546Sopenharmony_ci if (texsubimage_error_check(ctx, dims, texObj, target, level, 3605bf215546Sopenharmony_ci xoffset, yoffset, zoffset, 3606bf215546Sopenharmony_ci width, height, depth, format, type, 3607bf215546Sopenharmony_ci pixels, callerName)) { 3608bf215546Sopenharmony_ci return; /* error was detected */ 3609bf215546Sopenharmony_ci } 3610bf215546Sopenharmony_ci 3611bf215546Sopenharmony_ci texImage = _mesa_select_tex_image(texObj, target, level); 3612bf215546Sopenharmony_ci /* texsubimage_error_check ensures that texImage is not NULL */ 3613bf215546Sopenharmony_ci 3614bf215546Sopenharmony_ci if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 3615bf215546Sopenharmony_ci _mesa_debug(ctx, "glTexSubImage%uD %s %d %d %d %d %d %d %d %s %s %p\n", 3616bf215546Sopenharmony_ci dims, 3617bf215546Sopenharmony_ci _mesa_enum_to_string(target), level, 3618bf215546Sopenharmony_ci xoffset, yoffset, zoffset, width, height, depth, 3619bf215546Sopenharmony_ci _mesa_enum_to_string(format), 3620bf215546Sopenharmony_ci _mesa_enum_to_string(type), pixels); 3621bf215546Sopenharmony_ci 3622bf215546Sopenharmony_ci texture_sub_image(ctx, dims, texObj, texImage, target, level, 3623bf215546Sopenharmony_ci xoffset, yoffset, zoffset, width, height, depth, 3624bf215546Sopenharmony_ci format, type, pixels); 3625bf215546Sopenharmony_ci} 3626bf215546Sopenharmony_ci 3627bf215546Sopenharmony_ci 3628bf215546Sopenharmony_cistatic void 3629bf215546Sopenharmony_citexsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level, 3630bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, GLint zoffset, 3631bf215546Sopenharmony_ci GLsizei width, GLsizei height, GLsizei depth, 3632bf215546Sopenharmony_ci GLenum format, GLenum type, const GLvoid *pixels) 3633bf215546Sopenharmony_ci{ 3634bf215546Sopenharmony_ci struct gl_texture_object *texObj; 3635bf215546Sopenharmony_ci struct gl_texture_image *texImage; 3636bf215546Sopenharmony_ci 3637bf215546Sopenharmony_ci texObj = _mesa_get_current_tex_object(ctx, target); 3638bf215546Sopenharmony_ci texImage = _mesa_select_tex_image(texObj, target, level); 3639bf215546Sopenharmony_ci 3640bf215546Sopenharmony_ci texture_sub_image(ctx, dims, texObj, texImage, target, level, 3641bf215546Sopenharmony_ci xoffset, yoffset, zoffset, width, height, depth, 3642bf215546Sopenharmony_ci format, type, pixels); 3643bf215546Sopenharmony_ci} 3644bf215546Sopenharmony_ci 3645bf215546Sopenharmony_ci 3646bf215546Sopenharmony_ci/** 3647bf215546Sopenharmony_ci * Implement all the glTextureSubImage1/2/3D() functions. 3648bf215546Sopenharmony_ci * Must split this out this way because of GL_TEXTURE_CUBE_MAP. 3649bf215546Sopenharmony_ci */ 3650bf215546Sopenharmony_cistatic ALWAYS_INLINE void 3651bf215546Sopenharmony_citexturesubimage(struct gl_context *ctx, GLuint dims, 3652bf215546Sopenharmony_ci GLuint texture, GLenum target, GLint level, 3653bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, GLint zoffset, 3654bf215546Sopenharmony_ci GLsizei width, GLsizei height, GLsizei depth, 3655bf215546Sopenharmony_ci GLenum format, GLenum type, const GLvoid *pixels, 3656bf215546Sopenharmony_ci const char *callerName, bool no_error, bool ext_dsa) 3657bf215546Sopenharmony_ci{ 3658bf215546Sopenharmony_ci struct gl_texture_object *texObj; 3659bf215546Sopenharmony_ci struct gl_texture_image *texImage; 3660bf215546Sopenharmony_ci int i; 3661bf215546Sopenharmony_ci 3662bf215546Sopenharmony_ci if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 3663bf215546Sopenharmony_ci _mesa_debug(ctx, 3664bf215546Sopenharmony_ci "glTextureSubImage%uD %d %d %d %d %d %d %d %d %s %s %p\n", 3665bf215546Sopenharmony_ci dims, texture, level, 3666bf215546Sopenharmony_ci xoffset, yoffset, zoffset, width, height, depth, 3667bf215546Sopenharmony_ci _mesa_enum_to_string(format), 3668bf215546Sopenharmony_ci _mesa_enum_to_string(type), pixels); 3669bf215546Sopenharmony_ci 3670bf215546Sopenharmony_ci /* Get the texture object by Name. */ 3671bf215546Sopenharmony_ci if (!no_error) { 3672bf215546Sopenharmony_ci if (!ext_dsa) { 3673bf215546Sopenharmony_ci texObj = _mesa_lookup_texture_err(ctx, texture, callerName); 3674bf215546Sopenharmony_ci } else { 3675bf215546Sopenharmony_ci texObj = lookup_texture_ext_dsa(ctx, target, texture, callerName); 3676bf215546Sopenharmony_ci } 3677bf215546Sopenharmony_ci if (!texObj) 3678bf215546Sopenharmony_ci return; 3679bf215546Sopenharmony_ci } else { 3680bf215546Sopenharmony_ci texObj = _mesa_lookup_texture(ctx, texture); 3681bf215546Sopenharmony_ci } 3682bf215546Sopenharmony_ci 3683bf215546Sopenharmony_ci if (!no_error) { 3684bf215546Sopenharmony_ci /* check target (proxies not allowed) */ 3685bf215546Sopenharmony_ci if (!legal_texsubimage_target(ctx, dims, texObj->Target, true)) { 3686bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, "%s(target=%s)", 3687bf215546Sopenharmony_ci callerName, _mesa_enum_to_string(texObj->Target)); 3688bf215546Sopenharmony_ci return; 3689bf215546Sopenharmony_ci } 3690bf215546Sopenharmony_ci 3691bf215546Sopenharmony_ci if (texsubimage_error_check(ctx, dims, texObj, texObj->Target, level, 3692bf215546Sopenharmony_ci xoffset, yoffset, zoffset, 3693bf215546Sopenharmony_ci width, height, depth, format, type, 3694bf215546Sopenharmony_ci pixels, callerName)) { 3695bf215546Sopenharmony_ci return; /* error was detected */ 3696bf215546Sopenharmony_ci } 3697bf215546Sopenharmony_ci } 3698bf215546Sopenharmony_ci 3699bf215546Sopenharmony_ci /* Must handle special case GL_TEXTURE_CUBE_MAP. */ 3700bf215546Sopenharmony_ci if (texObj->Target == GL_TEXTURE_CUBE_MAP) { 3701bf215546Sopenharmony_ci GLint imageStride; 3702bf215546Sopenharmony_ci 3703bf215546Sopenharmony_ci /* 3704bf215546Sopenharmony_ci * What do we do if the user created a texture with the following code 3705bf215546Sopenharmony_ci * and then called this function with its handle? 3706bf215546Sopenharmony_ci * 3707bf215546Sopenharmony_ci * GLuint tex; 3708bf215546Sopenharmony_ci * glCreateTextures(GL_TEXTURE_CUBE_MAP, 1, &tex); 3709bf215546Sopenharmony_ci * glBindTexture(GL_TEXTURE_CUBE_MAP, tex); 3710bf215546Sopenharmony_ci * glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, ...); 3711bf215546Sopenharmony_ci * glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, ...); 3712bf215546Sopenharmony_ci * glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, ...); 3713bf215546Sopenharmony_ci * // Note: GL_TEXTURE_CUBE_MAP_NEGATIVE_Y not set, or given the 3714bf215546Sopenharmony_ci * // wrong format, or given the wrong size, etc. 3715bf215546Sopenharmony_ci * glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, ...); 3716bf215546Sopenharmony_ci * glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, ...); 3717bf215546Sopenharmony_ci * 3718bf215546Sopenharmony_ci * A bug has been filed against the spec for this case. In the 3719bf215546Sopenharmony_ci * meantime, we will check for cube completeness. 3720bf215546Sopenharmony_ci * 3721bf215546Sopenharmony_ci * According to Section 8.17 Texture Completeness in the OpenGL 4.5 3722bf215546Sopenharmony_ci * Core Profile spec (30.10.2014): 3723bf215546Sopenharmony_ci * "[A] cube map texture is cube complete if the 3724bf215546Sopenharmony_ci * following conditions all hold true: The [base level] texture 3725bf215546Sopenharmony_ci * images of each of the six cube map faces have identical, positive, 3726bf215546Sopenharmony_ci * and square dimensions. The [base level] images were each specified 3727bf215546Sopenharmony_ci * with the same internal format." 3728bf215546Sopenharmony_ci * 3729bf215546Sopenharmony_ci * It seems reasonable to check for cube completeness of an arbitrary 3730bf215546Sopenharmony_ci * level here so that the image data has a consistent format and size. 3731bf215546Sopenharmony_ci */ 3732bf215546Sopenharmony_ci if (!no_error && !_mesa_cube_level_complete(texObj, level)) { 3733bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 3734bf215546Sopenharmony_ci "glTextureSubImage%uD(cube map incomplete)", 3735bf215546Sopenharmony_ci dims); 3736bf215546Sopenharmony_ci return; 3737bf215546Sopenharmony_ci } 3738bf215546Sopenharmony_ci 3739bf215546Sopenharmony_ci imageStride = _mesa_image_image_stride(&ctx->Unpack, width, height, 3740bf215546Sopenharmony_ci format, type); 3741bf215546Sopenharmony_ci /* Copy in each face. */ 3742bf215546Sopenharmony_ci for (i = zoffset; i < zoffset + depth; ++i) { 3743bf215546Sopenharmony_ci texImage = texObj->Image[i][level]; 3744bf215546Sopenharmony_ci assert(texImage); 3745bf215546Sopenharmony_ci 3746bf215546Sopenharmony_ci texture_sub_image(ctx, 3, texObj, texImage, texObj->Target, 3747bf215546Sopenharmony_ci level, xoffset, yoffset, 0, 3748bf215546Sopenharmony_ci width, height, 1, format, 3749bf215546Sopenharmony_ci type, pixels); 3750bf215546Sopenharmony_ci pixels = (GLubyte *) pixels + imageStride; 3751bf215546Sopenharmony_ci } 3752bf215546Sopenharmony_ci } 3753bf215546Sopenharmony_ci else { 3754bf215546Sopenharmony_ci texImage = _mesa_select_tex_image(texObj, texObj->Target, level); 3755bf215546Sopenharmony_ci assert(texImage); 3756bf215546Sopenharmony_ci 3757bf215546Sopenharmony_ci texture_sub_image(ctx, dims, texObj, texImage, texObj->Target, 3758bf215546Sopenharmony_ci level, xoffset, yoffset, zoffset, 3759bf215546Sopenharmony_ci width, height, depth, format, 3760bf215546Sopenharmony_ci type, pixels); 3761bf215546Sopenharmony_ci } 3762bf215546Sopenharmony_ci} 3763bf215546Sopenharmony_ci 3764bf215546Sopenharmony_ci 3765bf215546Sopenharmony_cistatic void 3766bf215546Sopenharmony_citexturesubimage_error(struct gl_context *ctx, GLuint dims, 3767bf215546Sopenharmony_ci GLuint texture, GLenum target, GLint level, 3768bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, GLint zoffset, 3769bf215546Sopenharmony_ci GLsizei width, GLsizei height, GLsizei depth, 3770bf215546Sopenharmony_ci GLenum format, GLenum type, const GLvoid *pixels, 3771bf215546Sopenharmony_ci const char *callerName, bool ext_dsa) 3772bf215546Sopenharmony_ci{ 3773bf215546Sopenharmony_ci texturesubimage(ctx, dims, texture, target, level, xoffset, yoffset, 3774bf215546Sopenharmony_ci zoffset, width, height, depth, format, type, pixels, 3775bf215546Sopenharmony_ci callerName, false, ext_dsa); 3776bf215546Sopenharmony_ci} 3777bf215546Sopenharmony_ci 3778bf215546Sopenharmony_ci 3779bf215546Sopenharmony_cistatic void 3780bf215546Sopenharmony_citexturesubimage_no_error(struct gl_context *ctx, GLuint dims, 3781bf215546Sopenharmony_ci GLuint texture, GLenum target, GLint level, 3782bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, GLint zoffset, 3783bf215546Sopenharmony_ci GLsizei width, GLsizei height, GLsizei depth, 3784bf215546Sopenharmony_ci GLenum format, GLenum type, const GLvoid *pixels, 3785bf215546Sopenharmony_ci const char *callerName, bool ext_dsa) 3786bf215546Sopenharmony_ci{ 3787bf215546Sopenharmony_ci texturesubimage(ctx, dims, texture, target, level, xoffset, yoffset, 3788bf215546Sopenharmony_ci zoffset, width, height, depth, format, type, pixels, 3789bf215546Sopenharmony_ci callerName, true, ext_dsa); 3790bf215546Sopenharmony_ci} 3791bf215546Sopenharmony_ci 3792bf215546Sopenharmony_ci 3793bf215546Sopenharmony_civoid GLAPIENTRY 3794bf215546Sopenharmony_ci_mesa_TexSubImage1D_no_error(GLenum target, GLint level, 3795bf215546Sopenharmony_ci GLint xoffset, GLsizei width, 3796bf215546Sopenharmony_ci GLenum format, GLenum type, 3797bf215546Sopenharmony_ci const GLvoid *pixels) 3798bf215546Sopenharmony_ci{ 3799bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 3800bf215546Sopenharmony_ci texsubimage(ctx, 1, target, level, 3801bf215546Sopenharmony_ci xoffset, 0, 0, 3802bf215546Sopenharmony_ci width, 1, 1, 3803bf215546Sopenharmony_ci format, type, pixels); 3804bf215546Sopenharmony_ci} 3805bf215546Sopenharmony_ci 3806bf215546Sopenharmony_ci 3807bf215546Sopenharmony_civoid GLAPIENTRY 3808bf215546Sopenharmony_ci_mesa_TexSubImage1D( GLenum target, GLint level, 3809bf215546Sopenharmony_ci GLint xoffset, GLsizei width, 3810bf215546Sopenharmony_ci GLenum format, GLenum type, 3811bf215546Sopenharmony_ci const GLvoid *pixels ) 3812bf215546Sopenharmony_ci{ 3813bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 3814bf215546Sopenharmony_ci texsubimage_err(ctx, 1, target, level, 3815bf215546Sopenharmony_ci xoffset, 0, 0, 3816bf215546Sopenharmony_ci width, 1, 1, 3817bf215546Sopenharmony_ci format, type, pixels, "glTexSubImage1D"); 3818bf215546Sopenharmony_ci} 3819bf215546Sopenharmony_ci 3820bf215546Sopenharmony_ci 3821bf215546Sopenharmony_civoid GLAPIENTRY 3822bf215546Sopenharmony_ci_mesa_TexSubImage2D_no_error(GLenum target, GLint level, 3823bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, 3824bf215546Sopenharmony_ci GLsizei width, GLsizei height, 3825bf215546Sopenharmony_ci GLenum format, GLenum type, 3826bf215546Sopenharmony_ci const GLvoid *pixels) 3827bf215546Sopenharmony_ci{ 3828bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 3829bf215546Sopenharmony_ci texsubimage(ctx, 2, target, level, 3830bf215546Sopenharmony_ci xoffset, yoffset, 0, 3831bf215546Sopenharmony_ci width, height, 1, 3832bf215546Sopenharmony_ci format, type, pixels); 3833bf215546Sopenharmony_ci} 3834bf215546Sopenharmony_ci 3835bf215546Sopenharmony_ci 3836bf215546Sopenharmony_civoid GLAPIENTRY 3837bf215546Sopenharmony_ci_mesa_TexSubImage2D( GLenum target, GLint level, 3838bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, 3839bf215546Sopenharmony_ci GLsizei width, GLsizei height, 3840bf215546Sopenharmony_ci GLenum format, GLenum type, 3841bf215546Sopenharmony_ci const GLvoid *pixels ) 3842bf215546Sopenharmony_ci{ 3843bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 3844bf215546Sopenharmony_ci texsubimage_err(ctx, 2, target, level, 3845bf215546Sopenharmony_ci xoffset, yoffset, 0, 3846bf215546Sopenharmony_ci width, height, 1, 3847bf215546Sopenharmony_ci format, type, pixels, "glTexSubImage2D"); 3848bf215546Sopenharmony_ci} 3849bf215546Sopenharmony_ci 3850bf215546Sopenharmony_ci 3851bf215546Sopenharmony_civoid GLAPIENTRY 3852bf215546Sopenharmony_ci_mesa_TexSubImage3D_no_error(GLenum target, GLint level, 3853bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, GLint zoffset, 3854bf215546Sopenharmony_ci GLsizei width, GLsizei height, GLsizei depth, 3855bf215546Sopenharmony_ci GLenum format, GLenum type, 3856bf215546Sopenharmony_ci const GLvoid *pixels) 3857bf215546Sopenharmony_ci{ 3858bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 3859bf215546Sopenharmony_ci texsubimage(ctx, 3, target, level, 3860bf215546Sopenharmony_ci xoffset, yoffset, zoffset, 3861bf215546Sopenharmony_ci width, height, depth, 3862bf215546Sopenharmony_ci format, type, pixels); 3863bf215546Sopenharmony_ci} 3864bf215546Sopenharmony_ci 3865bf215546Sopenharmony_ci 3866bf215546Sopenharmony_civoid GLAPIENTRY 3867bf215546Sopenharmony_ci_mesa_TexSubImage3D( GLenum target, GLint level, 3868bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, GLint zoffset, 3869bf215546Sopenharmony_ci GLsizei width, GLsizei height, GLsizei depth, 3870bf215546Sopenharmony_ci GLenum format, GLenum type, 3871bf215546Sopenharmony_ci const GLvoid *pixels ) 3872bf215546Sopenharmony_ci{ 3873bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 3874bf215546Sopenharmony_ci texsubimage_err(ctx, 3, target, level, 3875bf215546Sopenharmony_ci xoffset, yoffset, zoffset, 3876bf215546Sopenharmony_ci width, height, depth, 3877bf215546Sopenharmony_ci format, type, pixels, "glTexSubImage3D"); 3878bf215546Sopenharmony_ci} 3879bf215546Sopenharmony_ci 3880bf215546Sopenharmony_ci 3881bf215546Sopenharmony_civoid GLAPIENTRY 3882bf215546Sopenharmony_ci_mesa_TextureSubImage1D_no_error(GLuint texture, GLint level, GLint xoffset, 3883bf215546Sopenharmony_ci GLsizei width, GLenum format, GLenum type, 3884bf215546Sopenharmony_ci const GLvoid *pixels) 3885bf215546Sopenharmony_ci{ 3886bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 3887bf215546Sopenharmony_ci texturesubimage_no_error(ctx, 1, texture, 0, level, xoffset, 0, 0, width, 3888bf215546Sopenharmony_ci 1, 1, format, type, pixels, "glTextureSubImage1D", 3889bf215546Sopenharmony_ci false); 3890bf215546Sopenharmony_ci} 3891bf215546Sopenharmony_ci 3892bf215546Sopenharmony_ci 3893bf215546Sopenharmony_civoid GLAPIENTRY 3894bf215546Sopenharmony_ci_mesa_TextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, 3895bf215546Sopenharmony_ci GLint xoffset, GLsizei width, 3896bf215546Sopenharmony_ci GLenum format, GLenum type, 3897bf215546Sopenharmony_ci const GLvoid *pixels) 3898bf215546Sopenharmony_ci{ 3899bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 3900bf215546Sopenharmony_ci texturesubimage_error(ctx, 1, texture, target, level, xoffset, 0, 0, width, 1, 3901bf215546Sopenharmony_ci 1, format, type, pixels, "glTextureSubImage1DEXT", 3902bf215546Sopenharmony_ci false); 3903bf215546Sopenharmony_ci} 3904bf215546Sopenharmony_ci 3905bf215546Sopenharmony_ci 3906bf215546Sopenharmony_civoid GLAPIENTRY 3907bf215546Sopenharmony_ci_mesa_MultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, 3908bf215546Sopenharmony_ci GLint xoffset, GLsizei width, 3909bf215546Sopenharmony_ci GLenum format, GLenum type, 3910bf215546Sopenharmony_ci const GLvoid *pixels) 3911bf215546Sopenharmony_ci{ 3912bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 3913bf215546Sopenharmony_ci struct gl_texture_object *texObj; 3914bf215546Sopenharmony_ci struct gl_texture_image *texImage; 3915bf215546Sopenharmony_ci 3916bf215546Sopenharmony_ci texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, 3917bf215546Sopenharmony_ci texunit - GL_TEXTURE0, 3918bf215546Sopenharmony_ci false, 3919bf215546Sopenharmony_ci "glMultiTexImage1DEXT"); 3920bf215546Sopenharmony_ci texImage = _mesa_select_tex_image(texObj, target, level); 3921bf215546Sopenharmony_ci 3922bf215546Sopenharmony_ci texture_sub_image(ctx, 1, texObj, texImage, target, level, 3923bf215546Sopenharmony_ci xoffset, 0, 0, width, 1, 1, 3924bf215546Sopenharmony_ci format, type, pixels); 3925bf215546Sopenharmony_ci} 3926bf215546Sopenharmony_ci 3927bf215546Sopenharmony_ci 3928bf215546Sopenharmony_civoid GLAPIENTRY 3929bf215546Sopenharmony_ci_mesa_TextureSubImage1D(GLuint texture, GLint level, 3930bf215546Sopenharmony_ci GLint xoffset, GLsizei width, 3931bf215546Sopenharmony_ci GLenum format, GLenum type, 3932bf215546Sopenharmony_ci const GLvoid *pixels) 3933bf215546Sopenharmony_ci{ 3934bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 3935bf215546Sopenharmony_ci texturesubimage_error(ctx, 1, texture, 0, level, xoffset, 0, 0, width, 1, 3936bf215546Sopenharmony_ci 1, format, type, pixels, "glTextureSubImage1D", 3937bf215546Sopenharmony_ci false); 3938bf215546Sopenharmony_ci} 3939bf215546Sopenharmony_ci 3940bf215546Sopenharmony_ci 3941bf215546Sopenharmony_civoid GLAPIENTRY 3942bf215546Sopenharmony_ci_mesa_TextureSubImage2D_no_error(GLuint texture, GLint level, GLint xoffset, 3943bf215546Sopenharmony_ci GLint yoffset, GLsizei width, GLsizei height, 3944bf215546Sopenharmony_ci GLenum format, GLenum type, 3945bf215546Sopenharmony_ci const GLvoid *pixels) 3946bf215546Sopenharmony_ci{ 3947bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 3948bf215546Sopenharmony_ci texturesubimage_no_error(ctx, 2, texture, 0, level, xoffset, yoffset, 0, 3949bf215546Sopenharmony_ci width, height, 1, format, type, pixels, 3950bf215546Sopenharmony_ci "glTextureSubImage2D", false); 3951bf215546Sopenharmony_ci} 3952bf215546Sopenharmony_ci 3953bf215546Sopenharmony_ci 3954bf215546Sopenharmony_civoid GLAPIENTRY 3955bf215546Sopenharmony_ci_mesa_TextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, 3956bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, GLsizei width, 3957bf215546Sopenharmony_ci GLsizei height, GLenum format, GLenum type, 3958bf215546Sopenharmony_ci const GLvoid *pixels) 3959bf215546Sopenharmony_ci{ 3960bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 3961bf215546Sopenharmony_ci texturesubimage_error(ctx, 2, texture, target, level, xoffset, yoffset, 0, 3962bf215546Sopenharmony_ci width, height, 1, format, type, pixels, 3963bf215546Sopenharmony_ci "glTextureSubImage2DEXT", true); 3964bf215546Sopenharmony_ci} 3965bf215546Sopenharmony_ci 3966bf215546Sopenharmony_ci 3967bf215546Sopenharmony_civoid GLAPIENTRY 3968bf215546Sopenharmony_ci_mesa_MultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, 3969bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, GLsizei width, 3970bf215546Sopenharmony_ci GLsizei height, GLenum format, GLenum type, 3971bf215546Sopenharmony_ci const GLvoid *pixels) 3972bf215546Sopenharmony_ci{ 3973bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 3974bf215546Sopenharmony_ci struct gl_texture_object *texObj; 3975bf215546Sopenharmony_ci struct gl_texture_image *texImage; 3976bf215546Sopenharmony_ci 3977bf215546Sopenharmony_ci texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, 3978bf215546Sopenharmony_ci texunit - GL_TEXTURE0, 3979bf215546Sopenharmony_ci false, 3980bf215546Sopenharmony_ci "glMultiTexImage2DEXT"); 3981bf215546Sopenharmony_ci texImage = _mesa_select_tex_image(texObj, target, level); 3982bf215546Sopenharmony_ci 3983bf215546Sopenharmony_ci texture_sub_image(ctx, 2, texObj, texImage, target, level, 3984bf215546Sopenharmony_ci xoffset, yoffset, 0, width, height, 1, 3985bf215546Sopenharmony_ci format, type, pixels); 3986bf215546Sopenharmony_ci} 3987bf215546Sopenharmony_ci 3988bf215546Sopenharmony_ci 3989bf215546Sopenharmony_civoid GLAPIENTRY 3990bf215546Sopenharmony_ci_mesa_TextureSubImage2D(GLuint texture, GLint level, 3991bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, 3992bf215546Sopenharmony_ci GLsizei width, GLsizei height, 3993bf215546Sopenharmony_ci GLenum format, GLenum type, 3994bf215546Sopenharmony_ci const GLvoid *pixels) 3995bf215546Sopenharmony_ci{ 3996bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 3997bf215546Sopenharmony_ci texturesubimage_error(ctx, 2, texture, 0, level, xoffset, yoffset, 0, 3998bf215546Sopenharmony_ci width, height, 1, format, type, pixels, 3999bf215546Sopenharmony_ci "glTextureSubImage2D", false); 4000bf215546Sopenharmony_ci} 4001bf215546Sopenharmony_ci 4002bf215546Sopenharmony_ci 4003bf215546Sopenharmony_civoid GLAPIENTRY 4004bf215546Sopenharmony_ci_mesa_TextureSubImage3D_no_error(GLuint texture, GLint level, GLint xoffset, 4005bf215546Sopenharmony_ci GLint yoffset, GLint zoffset, GLsizei width, 4006bf215546Sopenharmony_ci GLsizei height, GLsizei depth, GLenum format, 4007bf215546Sopenharmony_ci GLenum type, const GLvoid *pixels) 4008bf215546Sopenharmony_ci{ 4009bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 4010bf215546Sopenharmony_ci texturesubimage_no_error(ctx, 3, texture, 0, level, xoffset, yoffset, 4011bf215546Sopenharmony_ci zoffset, width, height, depth, format, type, 4012bf215546Sopenharmony_ci pixels, "glTextureSubImage3D", false); 4013bf215546Sopenharmony_ci} 4014bf215546Sopenharmony_ci 4015bf215546Sopenharmony_ci 4016bf215546Sopenharmony_civoid GLAPIENTRY 4017bf215546Sopenharmony_ci_mesa_TextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, 4018bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, GLint zoffset, 4019bf215546Sopenharmony_ci GLsizei width, GLsizei height, GLsizei depth, 4020bf215546Sopenharmony_ci GLenum format, GLenum type, const GLvoid *pixels) 4021bf215546Sopenharmony_ci{ 4022bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 4023bf215546Sopenharmony_ci texturesubimage_error(ctx, 3, texture, target, level, xoffset, yoffset, 4024bf215546Sopenharmony_ci zoffset, width, height, depth, format, type, 4025bf215546Sopenharmony_ci pixels, "glTextureSubImage3DEXT", true); 4026bf215546Sopenharmony_ci} 4027bf215546Sopenharmony_ci 4028bf215546Sopenharmony_ci 4029bf215546Sopenharmony_civoid GLAPIENTRY 4030bf215546Sopenharmony_ci_mesa_MultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, 4031bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, GLint zoffset, 4032bf215546Sopenharmony_ci GLsizei width, GLsizei height, GLsizei depth, 4033bf215546Sopenharmony_ci GLenum format, GLenum type, const GLvoid *pixels) 4034bf215546Sopenharmony_ci{ 4035bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 4036bf215546Sopenharmony_ci struct gl_texture_object *texObj; 4037bf215546Sopenharmony_ci struct gl_texture_image *texImage; 4038bf215546Sopenharmony_ci 4039bf215546Sopenharmony_ci texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, 4040bf215546Sopenharmony_ci texunit - GL_TEXTURE0, 4041bf215546Sopenharmony_ci false, 4042bf215546Sopenharmony_ci "glMultiTexImage3DEXT"); 4043bf215546Sopenharmony_ci texImage = _mesa_select_tex_image(texObj, target, level); 4044bf215546Sopenharmony_ci 4045bf215546Sopenharmony_ci texture_sub_image(ctx, 3, texObj, texImage, target, level, 4046bf215546Sopenharmony_ci xoffset, yoffset, zoffset, width, height, depth, 4047bf215546Sopenharmony_ci format, type, pixels); 4048bf215546Sopenharmony_ci} 4049bf215546Sopenharmony_ci 4050bf215546Sopenharmony_ci 4051bf215546Sopenharmony_civoid GLAPIENTRY 4052bf215546Sopenharmony_ci_mesa_TextureSubImage3D(GLuint texture, GLint level, 4053bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, GLint zoffset, 4054bf215546Sopenharmony_ci GLsizei width, GLsizei height, GLsizei depth, 4055bf215546Sopenharmony_ci GLenum format, GLenum type, 4056bf215546Sopenharmony_ci const GLvoid *pixels) 4057bf215546Sopenharmony_ci{ 4058bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 4059bf215546Sopenharmony_ci texturesubimage_error(ctx, 3, texture, 0, level, xoffset, yoffset, zoffset, 4060bf215546Sopenharmony_ci width, height, depth, format, type, pixels, 4061bf215546Sopenharmony_ci "glTextureSubImage3D", false); 4062bf215546Sopenharmony_ci} 4063bf215546Sopenharmony_ci 4064bf215546Sopenharmony_ci 4065bf215546Sopenharmony_ci/** 4066bf215546Sopenharmony_ci * For glCopyTexSubImage, return the source renderbuffer to copy texel data 4067bf215546Sopenharmony_ci * from. This depends on whether the texture contains color or depth values. 4068bf215546Sopenharmony_ci */ 4069bf215546Sopenharmony_cistatic struct gl_renderbuffer * 4070bf215546Sopenharmony_ciget_copy_tex_image_source(struct gl_context *ctx, mesa_format texFormat) 4071bf215546Sopenharmony_ci{ 4072bf215546Sopenharmony_ci if (_mesa_get_format_bits(texFormat, GL_DEPTH_BITS) > 0) { 4073bf215546Sopenharmony_ci /* reading from depth/stencil buffer */ 4074bf215546Sopenharmony_ci return ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; 4075bf215546Sopenharmony_ci } else if (_mesa_get_format_bits(texFormat, GL_STENCIL_BITS) > 0) { 4076bf215546Sopenharmony_ci return ctx->ReadBuffer->Attachment[BUFFER_STENCIL].Renderbuffer; 4077bf215546Sopenharmony_ci } else { 4078bf215546Sopenharmony_ci /* copying from color buffer */ 4079bf215546Sopenharmony_ci return ctx->ReadBuffer->_ColorReadBuffer; 4080bf215546Sopenharmony_ci } 4081bf215546Sopenharmony_ci} 4082bf215546Sopenharmony_ci 4083bf215546Sopenharmony_ci 4084bf215546Sopenharmony_cistatic void 4085bf215546Sopenharmony_cicopytexsubimage_by_slice(struct gl_context *ctx, 4086bf215546Sopenharmony_ci struct gl_texture_image *texImage, 4087bf215546Sopenharmony_ci GLuint dims, 4088bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, GLint zoffset, 4089bf215546Sopenharmony_ci struct gl_renderbuffer *rb, 4090bf215546Sopenharmony_ci GLint x, GLint y, 4091bf215546Sopenharmony_ci GLsizei width, GLsizei height) 4092bf215546Sopenharmony_ci{ 4093bf215546Sopenharmony_ci if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) { 4094bf215546Sopenharmony_ci int slice; 4095bf215546Sopenharmony_ci 4096bf215546Sopenharmony_ci /* For 1D arrays, we copy each scanline of the source rectangle into the 4097bf215546Sopenharmony_ci * next array slice. 4098bf215546Sopenharmony_ci */ 4099bf215546Sopenharmony_ci assert(zoffset == 0); 4100bf215546Sopenharmony_ci 4101bf215546Sopenharmony_ci for (slice = 0; slice < height; slice++) { 4102bf215546Sopenharmony_ci assert(yoffset + slice < texImage->Height); 4103bf215546Sopenharmony_ci st_CopyTexSubImage(ctx, 2, texImage, 4104bf215546Sopenharmony_ci xoffset, 0, yoffset + slice, 4105bf215546Sopenharmony_ci rb, x, y + slice, width, 1); 4106bf215546Sopenharmony_ci } 4107bf215546Sopenharmony_ci } else { 4108bf215546Sopenharmony_ci st_CopyTexSubImage(ctx, dims, texImage, 4109bf215546Sopenharmony_ci xoffset, yoffset, zoffset, 4110bf215546Sopenharmony_ci rb, x, y, width, height); 4111bf215546Sopenharmony_ci } 4112bf215546Sopenharmony_ci} 4113bf215546Sopenharmony_ci 4114bf215546Sopenharmony_ci 4115bf215546Sopenharmony_cistatic GLboolean 4116bf215546Sopenharmony_ciformats_differ_in_component_sizes(mesa_format f1, mesa_format f2) 4117bf215546Sopenharmony_ci{ 4118bf215546Sopenharmony_ci GLint f1_r_bits = _mesa_get_format_bits(f1, GL_RED_BITS); 4119bf215546Sopenharmony_ci GLint f1_g_bits = _mesa_get_format_bits(f1, GL_GREEN_BITS); 4120bf215546Sopenharmony_ci GLint f1_b_bits = _mesa_get_format_bits(f1, GL_BLUE_BITS); 4121bf215546Sopenharmony_ci GLint f1_a_bits = _mesa_get_format_bits(f1, GL_ALPHA_BITS); 4122bf215546Sopenharmony_ci 4123bf215546Sopenharmony_ci GLint f2_r_bits = _mesa_get_format_bits(f2, GL_RED_BITS); 4124bf215546Sopenharmony_ci GLint f2_g_bits = _mesa_get_format_bits(f2, GL_GREEN_BITS); 4125bf215546Sopenharmony_ci GLint f2_b_bits = _mesa_get_format_bits(f2, GL_BLUE_BITS); 4126bf215546Sopenharmony_ci GLint f2_a_bits = _mesa_get_format_bits(f2, GL_ALPHA_BITS); 4127bf215546Sopenharmony_ci 4128bf215546Sopenharmony_ci if ((f1_r_bits && f2_r_bits && f1_r_bits != f2_r_bits) 4129bf215546Sopenharmony_ci || (f1_g_bits && f2_g_bits && f1_g_bits != f2_g_bits) 4130bf215546Sopenharmony_ci || (f1_b_bits && f2_b_bits && f1_b_bits != f2_b_bits) 4131bf215546Sopenharmony_ci || (f1_a_bits && f2_a_bits && f1_a_bits != f2_a_bits)) 4132bf215546Sopenharmony_ci return GL_TRUE; 4133bf215546Sopenharmony_ci 4134bf215546Sopenharmony_ci return GL_FALSE; 4135bf215546Sopenharmony_ci} 4136bf215546Sopenharmony_ci 4137bf215546Sopenharmony_ci 4138bf215546Sopenharmony_ci/** 4139bf215546Sopenharmony_ci * Check if the given texture format and size arguments match those 4140bf215546Sopenharmony_ci * of the texture image. 4141bf215546Sopenharmony_ci * \param return true if arguments match, false otherwise. 4142bf215546Sopenharmony_ci */ 4143bf215546Sopenharmony_cistatic bool 4144bf215546Sopenharmony_cican_avoid_reallocation(const struct gl_texture_image *texImage, 4145bf215546Sopenharmony_ci GLenum internalFormat, 4146bf215546Sopenharmony_ci mesa_format texFormat, GLsizei width, 4147bf215546Sopenharmony_ci GLsizei height, GLint border) 4148bf215546Sopenharmony_ci{ 4149bf215546Sopenharmony_ci if (texImage->InternalFormat != internalFormat) 4150bf215546Sopenharmony_ci return false; 4151bf215546Sopenharmony_ci if (texImage->TexFormat != texFormat) 4152bf215546Sopenharmony_ci return false; 4153bf215546Sopenharmony_ci if (texImage->Border != border) 4154bf215546Sopenharmony_ci return false; 4155bf215546Sopenharmony_ci if (texImage->Width2 != width) 4156bf215546Sopenharmony_ci return false; 4157bf215546Sopenharmony_ci if (texImage->Height2 != height) 4158bf215546Sopenharmony_ci return false; 4159bf215546Sopenharmony_ci return true; 4160bf215546Sopenharmony_ci} 4161bf215546Sopenharmony_ci 4162bf215546Sopenharmony_ci 4163bf215546Sopenharmony_ci/** 4164bf215546Sopenharmony_ci * Implementation for glCopyTex(ture)SubImage1/2/3D() functions. 4165bf215546Sopenharmony_ci */ 4166bf215546Sopenharmony_cistatic void 4167bf215546Sopenharmony_cicopy_texture_sub_image(struct gl_context *ctx, GLuint dims, 4168bf215546Sopenharmony_ci struct gl_texture_object *texObj, 4169bf215546Sopenharmony_ci GLenum target, GLint level, 4170bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, GLint zoffset, 4171bf215546Sopenharmony_ci GLint x, GLint y, GLsizei width, GLsizei height) 4172bf215546Sopenharmony_ci{ 4173bf215546Sopenharmony_ci struct gl_texture_image *texImage; 4174bf215546Sopenharmony_ci 4175bf215546Sopenharmony_ci _mesa_lock_texture(ctx, texObj); 4176bf215546Sopenharmony_ci 4177bf215546Sopenharmony_ci texImage = _mesa_select_tex_image(texObj, target, level); 4178bf215546Sopenharmony_ci 4179bf215546Sopenharmony_ci /* If we have a border, offset=-1 is legal. Bias by border width. */ 4180bf215546Sopenharmony_ci switch (dims) { 4181bf215546Sopenharmony_ci case 3: 4182bf215546Sopenharmony_ci if (target != GL_TEXTURE_2D_ARRAY) 4183bf215546Sopenharmony_ci zoffset += texImage->Border; 4184bf215546Sopenharmony_ci FALLTHROUGH; 4185bf215546Sopenharmony_ci case 2: 4186bf215546Sopenharmony_ci if (target != GL_TEXTURE_1D_ARRAY) 4187bf215546Sopenharmony_ci yoffset += texImage->Border; 4188bf215546Sopenharmony_ci FALLTHROUGH; 4189bf215546Sopenharmony_ci case 1: 4190bf215546Sopenharmony_ci xoffset += texImage->Border; 4191bf215546Sopenharmony_ci } 4192bf215546Sopenharmony_ci 4193bf215546Sopenharmony_ci if (ctx->Const.NoClippingOnCopyTex || 4194bf215546Sopenharmony_ci _mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y, 4195bf215546Sopenharmony_ci &width, &height)) { 4196bf215546Sopenharmony_ci struct gl_renderbuffer *srcRb = 4197bf215546Sopenharmony_ci get_copy_tex_image_source(ctx, texImage->TexFormat); 4198bf215546Sopenharmony_ci 4199bf215546Sopenharmony_ci copytexsubimage_by_slice(ctx, texImage, dims, xoffset, yoffset, zoffset, 4200bf215546Sopenharmony_ci srcRb, x, y, width, height); 4201bf215546Sopenharmony_ci 4202bf215546Sopenharmony_ci check_gen_mipmap(ctx, target, texObj, level); 4203bf215546Sopenharmony_ci 4204bf215546Sopenharmony_ci /* NOTE: Don't signal _NEW_TEXTURE_OBJECT since we've only changed 4205bf215546Sopenharmony_ci * the texel data, not the texture format, size, etc. 4206bf215546Sopenharmony_ci */ 4207bf215546Sopenharmony_ci } 4208bf215546Sopenharmony_ci 4209bf215546Sopenharmony_ci _mesa_unlock_texture(ctx, texObj); 4210bf215546Sopenharmony_ci} 4211bf215546Sopenharmony_ci 4212bf215546Sopenharmony_ci 4213bf215546Sopenharmony_cistatic void 4214bf215546Sopenharmony_cicopy_texture_sub_image_err(struct gl_context *ctx, GLuint dims, 4215bf215546Sopenharmony_ci struct gl_texture_object *texObj, 4216bf215546Sopenharmony_ci GLenum target, GLint level, 4217bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, GLint zoffset, 4218bf215546Sopenharmony_ci GLint x, GLint y, GLsizei width, GLsizei height, 4219bf215546Sopenharmony_ci const char *caller) 4220bf215546Sopenharmony_ci{ 4221bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, 0, 0); 4222bf215546Sopenharmony_ci 4223bf215546Sopenharmony_ci if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 4224bf215546Sopenharmony_ci _mesa_debug(ctx, "%s %s %d %d %d %d %d %d %d %d\n", caller, 4225bf215546Sopenharmony_ci _mesa_enum_to_string(target), 4226bf215546Sopenharmony_ci level, xoffset, yoffset, zoffset, x, y, width, height); 4227bf215546Sopenharmony_ci 4228bf215546Sopenharmony_ci _mesa_update_pixel(ctx); 4229bf215546Sopenharmony_ci 4230bf215546Sopenharmony_ci if (ctx->NewState & _NEW_BUFFERS) 4231bf215546Sopenharmony_ci _mesa_update_state(ctx); 4232bf215546Sopenharmony_ci 4233bf215546Sopenharmony_ci if (copytexsubimage_error_check(ctx, dims, texObj, target, level, 4234bf215546Sopenharmony_ci xoffset, yoffset, zoffset, 4235bf215546Sopenharmony_ci width, height, caller)) { 4236bf215546Sopenharmony_ci return; 4237bf215546Sopenharmony_ci } 4238bf215546Sopenharmony_ci 4239bf215546Sopenharmony_ci copy_texture_sub_image(ctx, dims, texObj, target, level, xoffset, yoffset, 4240bf215546Sopenharmony_ci zoffset, x, y, width, height); 4241bf215546Sopenharmony_ci} 4242bf215546Sopenharmony_ci 4243bf215546Sopenharmony_ci 4244bf215546Sopenharmony_cistatic void 4245bf215546Sopenharmony_cicopy_texture_sub_image_no_error(struct gl_context *ctx, GLuint dims, 4246bf215546Sopenharmony_ci struct gl_texture_object *texObj, 4247bf215546Sopenharmony_ci GLenum target, GLint level, 4248bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, GLint zoffset, 4249bf215546Sopenharmony_ci GLint x, GLint y, GLsizei width, GLsizei height) 4250bf215546Sopenharmony_ci{ 4251bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, 0, 0); 4252bf215546Sopenharmony_ci 4253bf215546Sopenharmony_ci _mesa_update_pixel(ctx); 4254bf215546Sopenharmony_ci 4255bf215546Sopenharmony_ci if (ctx->NewState & _NEW_BUFFERS) 4256bf215546Sopenharmony_ci _mesa_update_state(ctx); 4257bf215546Sopenharmony_ci 4258bf215546Sopenharmony_ci copy_texture_sub_image(ctx, dims, texObj, target, level, xoffset, yoffset, 4259bf215546Sopenharmony_ci zoffset, x, y, width, height); 4260bf215546Sopenharmony_ci} 4261bf215546Sopenharmony_ci 4262bf215546Sopenharmony_ci 4263bf215546Sopenharmony_ci/** 4264bf215546Sopenharmony_ci * Implement the glCopyTexImage1/2D() functions. 4265bf215546Sopenharmony_ci */ 4266bf215546Sopenharmony_cistatic ALWAYS_INLINE void 4267bf215546Sopenharmony_cicopyteximage(struct gl_context *ctx, GLuint dims, struct gl_texture_object *texObj, 4268bf215546Sopenharmony_ci GLenum target, GLint level, GLenum internalFormat, 4269bf215546Sopenharmony_ci GLint x, GLint y, GLsizei width, GLsizei height, GLint border, 4270bf215546Sopenharmony_ci bool no_error) 4271bf215546Sopenharmony_ci{ 4272bf215546Sopenharmony_ci struct gl_texture_image *texImage; 4273bf215546Sopenharmony_ci mesa_format texFormat; 4274bf215546Sopenharmony_ci 4275bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, 0, 0); 4276bf215546Sopenharmony_ci 4277bf215546Sopenharmony_ci if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 4278bf215546Sopenharmony_ci _mesa_debug(ctx, "glCopyTexImage%uD %s %d %s %d %d %d %d %d\n", 4279bf215546Sopenharmony_ci dims, 4280bf215546Sopenharmony_ci _mesa_enum_to_string(target), level, 4281bf215546Sopenharmony_ci _mesa_enum_to_string(internalFormat), 4282bf215546Sopenharmony_ci x, y, width, height, border); 4283bf215546Sopenharmony_ci 4284bf215546Sopenharmony_ci _mesa_update_pixel(ctx); 4285bf215546Sopenharmony_ci 4286bf215546Sopenharmony_ci if (ctx->NewState & _NEW_BUFFERS) 4287bf215546Sopenharmony_ci _mesa_update_state(ctx); 4288bf215546Sopenharmony_ci 4289bf215546Sopenharmony_ci /* check target */ 4290bf215546Sopenharmony_ci if (!no_error && !legal_texsubimage_target(ctx, dims, target, false)) { 4291bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage%uD(target=%s)", 4292bf215546Sopenharmony_ci dims, _mesa_enum_to_string(target)); 4293bf215546Sopenharmony_ci return; 4294bf215546Sopenharmony_ci } 4295bf215546Sopenharmony_ci 4296bf215546Sopenharmony_ci if (!texObj) 4297bf215546Sopenharmony_ci texObj = _mesa_get_current_tex_object(ctx, target); 4298bf215546Sopenharmony_ci 4299bf215546Sopenharmony_ci if (!no_error) { 4300bf215546Sopenharmony_ci if (copytexture_error_check(ctx, dims, target, texObj, level, 4301bf215546Sopenharmony_ci internalFormat, border)) 4302bf215546Sopenharmony_ci return; 4303bf215546Sopenharmony_ci 4304bf215546Sopenharmony_ci if (!_mesa_legal_texture_dimensions(ctx, target, level, width, height, 4305bf215546Sopenharmony_ci 1, border)) { 4306bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, 4307bf215546Sopenharmony_ci "glCopyTexImage%uD(invalid width=%d or height=%d)", 4308bf215546Sopenharmony_ci dims, width, height); 4309bf215546Sopenharmony_ci return; 4310bf215546Sopenharmony_ci } 4311bf215546Sopenharmony_ci } 4312bf215546Sopenharmony_ci 4313bf215546Sopenharmony_ci assert(texObj); 4314bf215546Sopenharmony_ci 4315bf215546Sopenharmony_ci texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, 4316bf215546Sopenharmony_ci internalFormat, GL_NONE, GL_NONE); 4317bf215546Sopenharmony_ci 4318bf215546Sopenharmony_ci /* First check if reallocating the texture buffer can be avoided. 4319bf215546Sopenharmony_ci * Without the realloc the copy can be 20x faster. 4320bf215546Sopenharmony_ci */ 4321bf215546Sopenharmony_ci _mesa_lock_texture(ctx, texObj); 4322bf215546Sopenharmony_ci { 4323bf215546Sopenharmony_ci texImage = _mesa_select_tex_image(texObj, target, level); 4324bf215546Sopenharmony_ci if (texImage && can_avoid_reallocation(texImage, internalFormat, texFormat, 4325bf215546Sopenharmony_ci width, height, border)) { 4326bf215546Sopenharmony_ci _mesa_unlock_texture(ctx, texObj); 4327bf215546Sopenharmony_ci if (no_error) { 4328bf215546Sopenharmony_ci copy_texture_sub_image_no_error(ctx, dims, texObj, target, level, 0, 4329bf215546Sopenharmony_ci 0, 0, x, y, width, height); 4330bf215546Sopenharmony_ci } else { 4331bf215546Sopenharmony_ci copy_texture_sub_image_err(ctx, dims, texObj, target, level, 0, 0, 4332bf215546Sopenharmony_ci 0, x, y, width, height,"CopyTexImage"); 4333bf215546Sopenharmony_ci } 4334bf215546Sopenharmony_ci return; 4335bf215546Sopenharmony_ci } 4336bf215546Sopenharmony_ci } 4337bf215546Sopenharmony_ci _mesa_unlock_texture(ctx, texObj); 4338bf215546Sopenharmony_ci _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_LOW, "glCopyTexImage " 4339bf215546Sopenharmony_ci "can't avoid reallocating texture storage\n"); 4340bf215546Sopenharmony_ci 4341bf215546Sopenharmony_ci if (!no_error && _mesa_is_gles3(ctx)) { 4342bf215546Sopenharmony_ci struct gl_renderbuffer *rb = 4343bf215546Sopenharmony_ci _mesa_get_read_renderbuffer_for_format(ctx, internalFormat); 4344bf215546Sopenharmony_ci 4345bf215546Sopenharmony_ci if (_mesa_is_enum_format_unsized(internalFormat)) { 4346bf215546Sopenharmony_ci /* Conversion from GL_RGB10_A2 source buffer format is not allowed in 4347bf215546Sopenharmony_ci * OpenGL ES 3.0. Khronos bug# 9807. 4348bf215546Sopenharmony_ci */ 4349bf215546Sopenharmony_ci if (rb->InternalFormat == GL_RGB10_A2) { 4350bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 4351bf215546Sopenharmony_ci "glCopyTexImage%uD(Reading from GL_RGB10_A2 buffer" 4352bf215546Sopenharmony_ci " and writing to unsized internal format)", dims); 4353bf215546Sopenharmony_ci return; 4354bf215546Sopenharmony_ci } 4355bf215546Sopenharmony_ci } 4356bf215546Sopenharmony_ci /* From Page 139 of OpenGL ES 3.0 spec: 4357bf215546Sopenharmony_ci * "If internalformat is sized, the internal format of the new texel 4358bf215546Sopenharmony_ci * array is internalformat, and this is also the new texel array’s 4359bf215546Sopenharmony_ci * effective internal format. If the component sizes of internalformat 4360bf215546Sopenharmony_ci * do not exactly match the corresponding component sizes of the source 4361bf215546Sopenharmony_ci * buffer’s effective internal format, described below, an 4362bf215546Sopenharmony_ci * INVALID_OPERATION error is generated. If internalformat is unsized, 4363bf215546Sopenharmony_ci * the internal format of the new texel array is the effective internal 4364bf215546Sopenharmony_ci * format of the source buffer, and this is also the new texel array’s 4365bf215546Sopenharmony_ci * effective internal format. 4366bf215546Sopenharmony_ci */ 4367bf215546Sopenharmony_ci else if (formats_differ_in_component_sizes (texFormat, rb->Format)) { 4368bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 4369bf215546Sopenharmony_ci "glCopyTexImage%uD(component size changed in" 4370bf215546Sopenharmony_ci " internal format)", dims); 4371bf215546Sopenharmony_ci return; 4372bf215546Sopenharmony_ci } 4373bf215546Sopenharmony_ci } 4374bf215546Sopenharmony_ci 4375bf215546Sopenharmony_ci assert(texFormat != MESA_FORMAT_NONE); 4376bf215546Sopenharmony_ci 4377bf215546Sopenharmony_ci if (!st_TestProxyTexImage(ctx, proxy_target(target), 4378bf215546Sopenharmony_ci 0, level, texFormat, 1, 4379bf215546Sopenharmony_ci width, height, 1)) { 4380bf215546Sopenharmony_ci _mesa_error(ctx, GL_OUT_OF_MEMORY, 4381bf215546Sopenharmony_ci "glCopyTexImage%uD(image too large)", dims); 4382bf215546Sopenharmony_ci return; 4383bf215546Sopenharmony_ci } 4384bf215546Sopenharmony_ci 4385bf215546Sopenharmony_ci if (border) { 4386bf215546Sopenharmony_ci x += border; 4387bf215546Sopenharmony_ci width -= border * 2; 4388bf215546Sopenharmony_ci if (dims == 2) { 4389bf215546Sopenharmony_ci y += border; 4390bf215546Sopenharmony_ci height -= border * 2; 4391bf215546Sopenharmony_ci } 4392bf215546Sopenharmony_ci border = 0; 4393bf215546Sopenharmony_ci } 4394bf215546Sopenharmony_ci 4395bf215546Sopenharmony_ci _mesa_lock_texture(ctx, texObj); 4396bf215546Sopenharmony_ci { 4397bf215546Sopenharmony_ci texObj->External = GL_FALSE; 4398bf215546Sopenharmony_ci texImage = _mesa_get_tex_image(ctx, texObj, target, level); 4399bf215546Sopenharmony_ci 4400bf215546Sopenharmony_ci if (!texImage) { 4401bf215546Sopenharmony_ci _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims); 4402bf215546Sopenharmony_ci } 4403bf215546Sopenharmony_ci else { 4404bf215546Sopenharmony_ci GLint srcX = x, srcY = y, dstX = 0, dstY = 0, dstZ = 0; 4405bf215546Sopenharmony_ci const GLuint face = _mesa_tex_target_to_face(target); 4406bf215546Sopenharmony_ci 4407bf215546Sopenharmony_ci /* Free old texture image */ 4408bf215546Sopenharmony_ci st_FreeTextureImageBuffer(ctx, texImage); 4409bf215546Sopenharmony_ci 4410bf215546Sopenharmony_ci _mesa_init_teximage_fields(ctx, texImage, width, height, 1, 4411bf215546Sopenharmony_ci border, internalFormat, texFormat); 4412bf215546Sopenharmony_ci 4413bf215546Sopenharmony_ci if (width && height) { 4414bf215546Sopenharmony_ci /* Allocate texture memory (no pixel data yet) */ 4415bf215546Sopenharmony_ci st_AllocTextureImageBuffer(ctx, texImage); 4416bf215546Sopenharmony_ci 4417bf215546Sopenharmony_ci if (ctx->Const.NoClippingOnCopyTex || 4418bf215546Sopenharmony_ci _mesa_clip_copytexsubimage(ctx, &dstX, &dstY, &srcX, &srcY, 4419bf215546Sopenharmony_ci &width, &height)) { 4420bf215546Sopenharmony_ci struct gl_renderbuffer *srcRb = 4421bf215546Sopenharmony_ci get_copy_tex_image_source(ctx, texImage->TexFormat); 4422bf215546Sopenharmony_ci 4423bf215546Sopenharmony_ci copytexsubimage_by_slice(ctx, texImage, dims, 4424bf215546Sopenharmony_ci dstX, dstY, dstZ, 4425bf215546Sopenharmony_ci srcRb, srcX, srcY, width, height); 4426bf215546Sopenharmony_ci } 4427bf215546Sopenharmony_ci 4428bf215546Sopenharmony_ci check_gen_mipmap(ctx, target, texObj, level); 4429bf215546Sopenharmony_ci } 4430bf215546Sopenharmony_ci 4431bf215546Sopenharmony_ci _mesa_update_fbo_texture(ctx, texObj, face, level); 4432bf215546Sopenharmony_ci 4433bf215546Sopenharmony_ci _mesa_dirty_texobj(ctx, texObj); 4434bf215546Sopenharmony_ci } 4435bf215546Sopenharmony_ci } 4436bf215546Sopenharmony_ci _mesa_unlock_texture(ctx, texObj); 4437bf215546Sopenharmony_ci} 4438bf215546Sopenharmony_ci 4439bf215546Sopenharmony_ci 4440bf215546Sopenharmony_cistatic void 4441bf215546Sopenharmony_cicopyteximage_err(struct gl_context *ctx, GLuint dims, 4442bf215546Sopenharmony_ci GLenum target, 4443bf215546Sopenharmony_ci GLint level, GLenum internalFormat, GLint x, GLint y, 4444bf215546Sopenharmony_ci GLsizei width, GLsizei height, GLint border) 4445bf215546Sopenharmony_ci{ 4446bf215546Sopenharmony_ci copyteximage(ctx, dims, NULL, target, level, internalFormat, x, y, width, height, 4447bf215546Sopenharmony_ci border, false); 4448bf215546Sopenharmony_ci} 4449bf215546Sopenharmony_ci 4450bf215546Sopenharmony_ci 4451bf215546Sopenharmony_cistatic void 4452bf215546Sopenharmony_cicopyteximage_no_error(struct gl_context *ctx, GLuint dims, GLenum target, 4453bf215546Sopenharmony_ci GLint level, GLenum internalFormat, GLint x, GLint y, 4454bf215546Sopenharmony_ci GLsizei width, GLsizei height, GLint border) 4455bf215546Sopenharmony_ci{ 4456bf215546Sopenharmony_ci copyteximage(ctx, dims, NULL, target, level, internalFormat, x, y, width, height, 4457bf215546Sopenharmony_ci border, true); 4458bf215546Sopenharmony_ci} 4459bf215546Sopenharmony_ci 4460bf215546Sopenharmony_ci 4461bf215546Sopenharmony_civoid GLAPIENTRY 4462bf215546Sopenharmony_ci_mesa_CopyTexImage1D( GLenum target, GLint level, 4463bf215546Sopenharmony_ci GLenum internalFormat, 4464bf215546Sopenharmony_ci GLint x, GLint y, 4465bf215546Sopenharmony_ci GLsizei width, GLint border ) 4466bf215546Sopenharmony_ci{ 4467bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 4468bf215546Sopenharmony_ci copyteximage_err(ctx, 1, target, level, internalFormat, x, y, width, 1, 4469bf215546Sopenharmony_ci border); 4470bf215546Sopenharmony_ci} 4471bf215546Sopenharmony_ci 4472bf215546Sopenharmony_ci 4473bf215546Sopenharmony_civoid GLAPIENTRY 4474bf215546Sopenharmony_ci_mesa_CopyTextureImage1DEXT( GLuint texture, GLenum target, GLint level, 4475bf215546Sopenharmony_ci GLenum internalFormat, 4476bf215546Sopenharmony_ci GLint x, GLint y, 4477bf215546Sopenharmony_ci GLsizei width, GLint border ) 4478bf215546Sopenharmony_ci{ 4479bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 4480bf215546Sopenharmony_ci struct gl_texture_object* texObj = 4481bf215546Sopenharmony_ci _mesa_lookup_or_create_texture(ctx, target, texture, false, true, 4482bf215546Sopenharmony_ci "glCopyTextureImage1DEXT"); 4483bf215546Sopenharmony_ci if (!texObj) 4484bf215546Sopenharmony_ci return; 4485bf215546Sopenharmony_ci copyteximage(ctx, 1, texObj, target, level, internalFormat, x, y, width, 1, 4486bf215546Sopenharmony_ci border, false); 4487bf215546Sopenharmony_ci} 4488bf215546Sopenharmony_ci 4489bf215546Sopenharmony_ci 4490bf215546Sopenharmony_civoid GLAPIENTRY 4491bf215546Sopenharmony_ci_mesa_CopyMultiTexImage1DEXT( GLenum texunit, GLenum target, GLint level, 4492bf215546Sopenharmony_ci GLenum internalFormat, 4493bf215546Sopenharmony_ci GLint x, GLint y, 4494bf215546Sopenharmony_ci GLsizei width, GLint border ) 4495bf215546Sopenharmony_ci{ 4496bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 4497bf215546Sopenharmony_ci struct gl_texture_object* texObj = 4498bf215546Sopenharmony_ci _mesa_get_texobj_by_target_and_texunit(ctx, target, 4499bf215546Sopenharmony_ci texunit - GL_TEXTURE0, 4500bf215546Sopenharmony_ci false, 4501bf215546Sopenharmony_ci "glCopyMultiTexImage1DEXT"); 4502bf215546Sopenharmony_ci if (!texObj) 4503bf215546Sopenharmony_ci return; 4504bf215546Sopenharmony_ci copyteximage(ctx, 1, texObj, target, level, internalFormat, x, y, width, 1, 4505bf215546Sopenharmony_ci border, false); 4506bf215546Sopenharmony_ci} 4507bf215546Sopenharmony_ci 4508bf215546Sopenharmony_ci 4509bf215546Sopenharmony_civoid GLAPIENTRY 4510bf215546Sopenharmony_ci_mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, 4511bf215546Sopenharmony_ci GLint x, GLint y, GLsizei width, GLsizei height, 4512bf215546Sopenharmony_ci GLint border ) 4513bf215546Sopenharmony_ci{ 4514bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 4515bf215546Sopenharmony_ci copyteximage_err(ctx, 2, target, level, internalFormat, 4516bf215546Sopenharmony_ci x, y, width, height, border); 4517bf215546Sopenharmony_ci} 4518bf215546Sopenharmony_ci 4519bf215546Sopenharmony_ci 4520bf215546Sopenharmony_civoid GLAPIENTRY 4521bf215546Sopenharmony_ci_mesa_CopyTextureImage2DEXT( GLuint texture, GLenum target, GLint level, 4522bf215546Sopenharmony_ci GLenum internalFormat, 4523bf215546Sopenharmony_ci GLint x, GLint y, 4524bf215546Sopenharmony_ci GLsizei width, GLsizei height, 4525bf215546Sopenharmony_ci GLint border ) 4526bf215546Sopenharmony_ci{ 4527bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 4528bf215546Sopenharmony_ci struct gl_texture_object* texObj = 4529bf215546Sopenharmony_ci _mesa_lookup_or_create_texture(ctx, target, texture, false, true, 4530bf215546Sopenharmony_ci "glCopyTextureImage2DEXT"); 4531bf215546Sopenharmony_ci if (!texObj) 4532bf215546Sopenharmony_ci return; 4533bf215546Sopenharmony_ci copyteximage(ctx, 2, texObj, target, level, internalFormat, x, y, width, height, 4534bf215546Sopenharmony_ci border, false); 4535bf215546Sopenharmony_ci} 4536bf215546Sopenharmony_ci 4537bf215546Sopenharmony_ci 4538bf215546Sopenharmony_civoid GLAPIENTRY 4539bf215546Sopenharmony_ci_mesa_CopyMultiTexImage2DEXT( GLenum texunit, GLenum target, GLint level, 4540bf215546Sopenharmony_ci GLenum internalFormat, 4541bf215546Sopenharmony_ci GLint x, GLint y, 4542bf215546Sopenharmony_ci GLsizei width, GLsizei height, GLint border ) 4543bf215546Sopenharmony_ci{ 4544bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 4545bf215546Sopenharmony_ci struct gl_texture_object* texObj = 4546bf215546Sopenharmony_ci _mesa_get_texobj_by_target_and_texunit(ctx, target, 4547bf215546Sopenharmony_ci texunit - GL_TEXTURE0, 4548bf215546Sopenharmony_ci false, 4549bf215546Sopenharmony_ci "glCopyMultiTexImage2DEXT"); 4550bf215546Sopenharmony_ci if (!texObj) 4551bf215546Sopenharmony_ci return; 4552bf215546Sopenharmony_ci copyteximage(ctx, 2, texObj, target, level, internalFormat, x, y, width, height, 4553bf215546Sopenharmony_ci border, false); 4554bf215546Sopenharmony_ci} 4555bf215546Sopenharmony_ci 4556bf215546Sopenharmony_ci 4557bf215546Sopenharmony_civoid GLAPIENTRY 4558bf215546Sopenharmony_ci_mesa_CopyTexImage1D_no_error(GLenum target, GLint level, GLenum internalFormat, 4559bf215546Sopenharmony_ci GLint x, GLint y, GLsizei width, GLint border) 4560bf215546Sopenharmony_ci{ 4561bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 4562bf215546Sopenharmony_ci copyteximage_no_error(ctx, 1, target, level, internalFormat, x, y, width, 1, 4563bf215546Sopenharmony_ci border); 4564bf215546Sopenharmony_ci} 4565bf215546Sopenharmony_ci 4566bf215546Sopenharmony_ci 4567bf215546Sopenharmony_civoid GLAPIENTRY 4568bf215546Sopenharmony_ci_mesa_CopyTexImage2D_no_error(GLenum target, GLint level, GLenum internalFormat, 4569bf215546Sopenharmony_ci GLint x, GLint y, GLsizei width, GLsizei height, 4570bf215546Sopenharmony_ci GLint border) 4571bf215546Sopenharmony_ci{ 4572bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 4573bf215546Sopenharmony_ci copyteximage_no_error(ctx, 2, target, level, internalFormat, 4574bf215546Sopenharmony_ci x, y, width, height, border); 4575bf215546Sopenharmony_ci} 4576bf215546Sopenharmony_ci 4577bf215546Sopenharmony_ci 4578bf215546Sopenharmony_civoid GLAPIENTRY 4579bf215546Sopenharmony_ci_mesa_CopyTexSubImage1D(GLenum target, GLint level, 4580bf215546Sopenharmony_ci GLint xoffset, GLint x, GLint y, GLsizei width) 4581bf215546Sopenharmony_ci{ 4582bf215546Sopenharmony_ci struct gl_texture_object* texObj; 4583bf215546Sopenharmony_ci const char *self = "glCopyTexSubImage1D"; 4584bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 4585bf215546Sopenharmony_ci 4586bf215546Sopenharmony_ci /* Check target (proxies not allowed). Target must be checked prior to 4587bf215546Sopenharmony_ci * calling _mesa_get_current_tex_object. 4588bf215546Sopenharmony_ci */ 4589bf215546Sopenharmony_ci if (!legal_texsubimage_target(ctx, 1, target, false)) { 4590bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", self, 4591bf215546Sopenharmony_ci _mesa_enum_to_string(target)); 4592bf215546Sopenharmony_ci return; 4593bf215546Sopenharmony_ci } 4594bf215546Sopenharmony_ci 4595bf215546Sopenharmony_ci texObj = _mesa_get_current_tex_object(ctx, target); 4596bf215546Sopenharmony_ci if (!texObj) 4597bf215546Sopenharmony_ci return; 4598bf215546Sopenharmony_ci 4599bf215546Sopenharmony_ci copy_texture_sub_image_err(ctx, 1, texObj, target, level, xoffset, 0, 0, 4600bf215546Sopenharmony_ci x, y, width, 1, self); 4601bf215546Sopenharmony_ci} 4602bf215546Sopenharmony_ci 4603bf215546Sopenharmony_ci 4604bf215546Sopenharmony_civoid GLAPIENTRY 4605bf215546Sopenharmony_ci_mesa_CopyTexSubImage2D(GLenum target, GLint level, 4606bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, 4607bf215546Sopenharmony_ci GLint x, GLint y, GLsizei width, GLsizei height) 4608bf215546Sopenharmony_ci{ 4609bf215546Sopenharmony_ci struct gl_texture_object* texObj; 4610bf215546Sopenharmony_ci const char *self = "glCopyTexSubImage2D"; 4611bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 4612bf215546Sopenharmony_ci 4613bf215546Sopenharmony_ci /* Check target (proxies not allowed). Target must be checked prior to 4614bf215546Sopenharmony_ci * calling _mesa_get_current_tex_object. 4615bf215546Sopenharmony_ci */ 4616bf215546Sopenharmony_ci if (!legal_texsubimage_target(ctx, 2, target, false)) { 4617bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", self, 4618bf215546Sopenharmony_ci _mesa_enum_to_string(target)); 4619bf215546Sopenharmony_ci return; 4620bf215546Sopenharmony_ci } 4621bf215546Sopenharmony_ci 4622bf215546Sopenharmony_ci texObj = _mesa_get_current_tex_object(ctx, target); 4623bf215546Sopenharmony_ci if (!texObj) 4624bf215546Sopenharmony_ci return; 4625bf215546Sopenharmony_ci 4626bf215546Sopenharmony_ci copy_texture_sub_image_err(ctx, 2, texObj, target, level, xoffset, yoffset, 4627bf215546Sopenharmony_ci 0, x, y, width, height, self); 4628bf215546Sopenharmony_ci} 4629bf215546Sopenharmony_ci 4630bf215546Sopenharmony_ci 4631bf215546Sopenharmony_civoid GLAPIENTRY 4632bf215546Sopenharmony_ci_mesa_CopyTexSubImage3D(GLenum target, GLint level, 4633bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, GLint zoffset, 4634bf215546Sopenharmony_ci GLint x, GLint y, GLsizei width, GLsizei height) 4635bf215546Sopenharmony_ci{ 4636bf215546Sopenharmony_ci struct gl_texture_object* texObj; 4637bf215546Sopenharmony_ci const char *self = "glCopyTexSubImage3D"; 4638bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 4639bf215546Sopenharmony_ci 4640bf215546Sopenharmony_ci /* Check target (proxies not allowed). Target must be checked prior to 4641bf215546Sopenharmony_ci * calling _mesa_get_current_tex_object. 4642bf215546Sopenharmony_ci */ 4643bf215546Sopenharmony_ci if (!legal_texsubimage_target(ctx, 3, target, false)) { 4644bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", self, 4645bf215546Sopenharmony_ci _mesa_enum_to_string(target)); 4646bf215546Sopenharmony_ci return; 4647bf215546Sopenharmony_ci } 4648bf215546Sopenharmony_ci 4649bf215546Sopenharmony_ci texObj = _mesa_get_current_tex_object(ctx, target); 4650bf215546Sopenharmony_ci if (!texObj) 4651bf215546Sopenharmony_ci return; 4652bf215546Sopenharmony_ci 4653bf215546Sopenharmony_ci copy_texture_sub_image_err(ctx, 3, texObj, target, level, xoffset, yoffset, 4654bf215546Sopenharmony_ci zoffset, x, y, width, height, self); 4655bf215546Sopenharmony_ci} 4656bf215546Sopenharmony_ci 4657bf215546Sopenharmony_ci 4658bf215546Sopenharmony_civoid GLAPIENTRY 4659bf215546Sopenharmony_ci_mesa_CopyTextureSubImage1D(GLuint texture, GLint level, 4660bf215546Sopenharmony_ci GLint xoffset, GLint x, GLint y, GLsizei width) 4661bf215546Sopenharmony_ci{ 4662bf215546Sopenharmony_ci struct gl_texture_object* texObj; 4663bf215546Sopenharmony_ci const char *self = "glCopyTextureSubImage1D"; 4664bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 4665bf215546Sopenharmony_ci 4666bf215546Sopenharmony_ci texObj = _mesa_lookup_texture_err(ctx, texture, self); 4667bf215546Sopenharmony_ci if (!texObj) 4668bf215546Sopenharmony_ci return; 4669bf215546Sopenharmony_ci 4670bf215546Sopenharmony_ci /* Check target (proxies not allowed). */ 4671bf215546Sopenharmony_ci if (!legal_texsubimage_target(ctx, 1, texObj->Target, true)) { 4672bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", self, 4673bf215546Sopenharmony_ci _mesa_enum_to_string(texObj->Target)); 4674bf215546Sopenharmony_ci return; 4675bf215546Sopenharmony_ci } 4676bf215546Sopenharmony_ci 4677bf215546Sopenharmony_ci copy_texture_sub_image_err(ctx, 1, texObj, texObj->Target, level, xoffset, 0, 4678bf215546Sopenharmony_ci 0, x, y, width, 1, self); 4679bf215546Sopenharmony_ci} 4680bf215546Sopenharmony_ci 4681bf215546Sopenharmony_ci 4682bf215546Sopenharmony_civoid GLAPIENTRY 4683bf215546Sopenharmony_ci_mesa_CopyTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, 4684bf215546Sopenharmony_ci GLint xoffset, GLint x, GLint y, GLsizei width) 4685bf215546Sopenharmony_ci{ 4686bf215546Sopenharmony_ci struct gl_texture_object* texObj; 4687bf215546Sopenharmony_ci const char *self = "glCopyTextureSubImage1DEXT"; 4688bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 4689bf215546Sopenharmony_ci 4690bf215546Sopenharmony_ci texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, 4691bf215546Sopenharmony_ci self); 4692bf215546Sopenharmony_ci if (!texObj) 4693bf215546Sopenharmony_ci return; 4694bf215546Sopenharmony_ci 4695bf215546Sopenharmony_ci /* Check target (proxies not allowed). */ 4696bf215546Sopenharmony_ci if (!legal_texsubimage_target(ctx, 1, texObj->Target, true)) { 4697bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", self, 4698bf215546Sopenharmony_ci _mesa_enum_to_string(texObj->Target)); 4699bf215546Sopenharmony_ci return; 4700bf215546Sopenharmony_ci } 4701bf215546Sopenharmony_ci 4702bf215546Sopenharmony_ci copy_texture_sub_image_err(ctx, 1, texObj, texObj->Target, level, xoffset, 0, 4703bf215546Sopenharmony_ci 0, x, y, width, 1, self); 4704bf215546Sopenharmony_ci} 4705bf215546Sopenharmony_ci 4706bf215546Sopenharmony_ci 4707bf215546Sopenharmony_civoid GLAPIENTRY 4708bf215546Sopenharmony_ci_mesa_CopyMultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, 4709bf215546Sopenharmony_ci GLint xoffset, GLint x, GLint y, GLsizei width) 4710bf215546Sopenharmony_ci{ 4711bf215546Sopenharmony_ci struct gl_texture_object* texObj; 4712bf215546Sopenharmony_ci const char *self = "glCopyMultiTexSubImage1DEXT"; 4713bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 4714bf215546Sopenharmony_ci 4715bf215546Sopenharmony_ci texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, 4716bf215546Sopenharmony_ci texunit - GL_TEXTURE0, 4717bf215546Sopenharmony_ci false, self); 4718bf215546Sopenharmony_ci if (!texObj) 4719bf215546Sopenharmony_ci return; 4720bf215546Sopenharmony_ci 4721bf215546Sopenharmony_ci copy_texture_sub_image_err(ctx, 1, texObj, texObj->Target, level, xoffset, 0, 4722bf215546Sopenharmony_ci 0, x, y, width, 1, self); 4723bf215546Sopenharmony_ci} 4724bf215546Sopenharmony_ci 4725bf215546Sopenharmony_ci 4726bf215546Sopenharmony_civoid GLAPIENTRY 4727bf215546Sopenharmony_ci_mesa_CopyTextureSubImage2D(GLuint texture, GLint level, 4728bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, 4729bf215546Sopenharmony_ci GLint x, GLint y, GLsizei width, GLsizei height) 4730bf215546Sopenharmony_ci{ 4731bf215546Sopenharmony_ci struct gl_texture_object* texObj; 4732bf215546Sopenharmony_ci const char *self = "glCopyTextureSubImage2D"; 4733bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 4734bf215546Sopenharmony_ci 4735bf215546Sopenharmony_ci texObj = _mesa_lookup_texture_err(ctx, texture, self); 4736bf215546Sopenharmony_ci if (!texObj) 4737bf215546Sopenharmony_ci return; 4738bf215546Sopenharmony_ci 4739bf215546Sopenharmony_ci /* Check target (proxies not allowed). */ 4740bf215546Sopenharmony_ci if (!legal_texsubimage_target(ctx, 2, texObj->Target, true)) { 4741bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", self, 4742bf215546Sopenharmony_ci _mesa_enum_to_string(texObj->Target)); 4743bf215546Sopenharmony_ci return; 4744bf215546Sopenharmony_ci } 4745bf215546Sopenharmony_ci 4746bf215546Sopenharmony_ci copy_texture_sub_image_err(ctx, 2, texObj, texObj->Target, level, xoffset, 4747bf215546Sopenharmony_ci yoffset, 0, x, y, width, height, self); 4748bf215546Sopenharmony_ci} 4749bf215546Sopenharmony_ci 4750bf215546Sopenharmony_ci 4751bf215546Sopenharmony_civoid GLAPIENTRY 4752bf215546Sopenharmony_ci_mesa_CopyTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, 4753bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, 4754bf215546Sopenharmony_ci GLint x, GLint y, GLsizei width, GLsizei height) 4755bf215546Sopenharmony_ci{ 4756bf215546Sopenharmony_ci struct gl_texture_object* texObj; 4757bf215546Sopenharmony_ci const char *self = "glCopyTextureSubImage2DEXT"; 4758bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 4759bf215546Sopenharmony_ci 4760bf215546Sopenharmony_ci texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, self); 4761bf215546Sopenharmony_ci if (!texObj) 4762bf215546Sopenharmony_ci return; 4763bf215546Sopenharmony_ci 4764bf215546Sopenharmony_ci /* Check target (proxies not allowed). */ 4765bf215546Sopenharmony_ci if (!legal_texsubimage_target(ctx, 2, texObj->Target, true)) { 4766bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", self, 4767bf215546Sopenharmony_ci _mesa_enum_to_string(texObj->Target)); 4768bf215546Sopenharmony_ci return; 4769bf215546Sopenharmony_ci } 4770bf215546Sopenharmony_ci 4771bf215546Sopenharmony_ci copy_texture_sub_image_err(ctx, 2, texObj, texObj->Target, level, xoffset, 4772bf215546Sopenharmony_ci yoffset, 0, x, y, width, height, self); 4773bf215546Sopenharmony_ci} 4774bf215546Sopenharmony_ci 4775bf215546Sopenharmony_ci 4776bf215546Sopenharmony_civoid GLAPIENTRY 4777bf215546Sopenharmony_ci_mesa_CopyMultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, 4778bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, 4779bf215546Sopenharmony_ci GLint x, GLint y, GLsizei width, GLsizei height) 4780bf215546Sopenharmony_ci{ 4781bf215546Sopenharmony_ci struct gl_texture_object* texObj; 4782bf215546Sopenharmony_ci const char *self = "glCopyMultiTexSubImage2DEXT"; 4783bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 4784bf215546Sopenharmony_ci 4785bf215546Sopenharmony_ci texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, 4786bf215546Sopenharmony_ci texunit - GL_TEXTURE0, 4787bf215546Sopenharmony_ci false, self); 4788bf215546Sopenharmony_ci if (!texObj) 4789bf215546Sopenharmony_ci return; 4790bf215546Sopenharmony_ci 4791bf215546Sopenharmony_ci copy_texture_sub_image_err(ctx, 2, texObj, texObj->Target, level, xoffset, 4792bf215546Sopenharmony_ci yoffset, 0, x, y, width, height, self); 4793bf215546Sopenharmony_ci} 4794bf215546Sopenharmony_ci 4795bf215546Sopenharmony_civoid GLAPIENTRY 4796bf215546Sopenharmony_ci_mesa_CopyTextureSubImage3D(GLuint texture, GLint level, 4797bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, GLint zoffset, 4798bf215546Sopenharmony_ci GLint x, GLint y, GLsizei width, GLsizei height) 4799bf215546Sopenharmony_ci{ 4800bf215546Sopenharmony_ci struct gl_texture_object* texObj; 4801bf215546Sopenharmony_ci const char *self = "glCopyTextureSubImage3D"; 4802bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 4803bf215546Sopenharmony_ci 4804bf215546Sopenharmony_ci texObj = _mesa_lookup_texture_err(ctx, texture, self); 4805bf215546Sopenharmony_ci if (!texObj) 4806bf215546Sopenharmony_ci return; 4807bf215546Sopenharmony_ci 4808bf215546Sopenharmony_ci /* Check target (proxies not allowed). */ 4809bf215546Sopenharmony_ci if (!legal_texsubimage_target(ctx, 3, texObj->Target, true)) { 4810bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", self, 4811bf215546Sopenharmony_ci _mesa_enum_to_string(texObj->Target)); 4812bf215546Sopenharmony_ci return; 4813bf215546Sopenharmony_ci } 4814bf215546Sopenharmony_ci 4815bf215546Sopenharmony_ci if (texObj->Target == GL_TEXTURE_CUBE_MAP) { 4816bf215546Sopenharmony_ci /* Act like CopyTexSubImage2D */ 4817bf215546Sopenharmony_ci copy_texture_sub_image_err(ctx, 2, texObj, 4818bf215546Sopenharmony_ci GL_TEXTURE_CUBE_MAP_POSITIVE_X + zoffset, 4819bf215546Sopenharmony_ci level, xoffset, yoffset, 0, x, y, width, height, 4820bf215546Sopenharmony_ci self); 4821bf215546Sopenharmony_ci } 4822bf215546Sopenharmony_ci else 4823bf215546Sopenharmony_ci copy_texture_sub_image_err(ctx, 3, texObj, texObj->Target, level, xoffset, 4824bf215546Sopenharmony_ci yoffset, zoffset, x, y, width, height, self); 4825bf215546Sopenharmony_ci} 4826bf215546Sopenharmony_ci 4827bf215546Sopenharmony_ci 4828bf215546Sopenharmony_civoid GLAPIENTRY 4829bf215546Sopenharmony_ci_mesa_CopyTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, 4830bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, GLint zoffset, 4831bf215546Sopenharmony_ci GLint x, GLint y, GLsizei width, GLsizei height) 4832bf215546Sopenharmony_ci{ 4833bf215546Sopenharmony_ci struct gl_texture_object* texObj; 4834bf215546Sopenharmony_ci const char *self = "glCopyTextureSubImage3D"; 4835bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 4836bf215546Sopenharmony_ci 4837bf215546Sopenharmony_ci texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, self); 4838bf215546Sopenharmony_ci if (!texObj) 4839bf215546Sopenharmony_ci return; 4840bf215546Sopenharmony_ci 4841bf215546Sopenharmony_ci /* Check target (proxies not allowed). */ 4842bf215546Sopenharmony_ci if (!legal_texsubimage_target(ctx, 3, texObj->Target, true)) { 4843bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", self, 4844bf215546Sopenharmony_ci _mesa_enum_to_string(texObj->Target)); 4845bf215546Sopenharmony_ci return; 4846bf215546Sopenharmony_ci } 4847bf215546Sopenharmony_ci 4848bf215546Sopenharmony_ci if (texObj->Target == GL_TEXTURE_CUBE_MAP) { 4849bf215546Sopenharmony_ci /* Act like CopyTexSubImage2D */ 4850bf215546Sopenharmony_ci copy_texture_sub_image_err(ctx, 2, texObj, 4851bf215546Sopenharmony_ci GL_TEXTURE_CUBE_MAP_POSITIVE_X + zoffset, 4852bf215546Sopenharmony_ci level, xoffset, yoffset, 0, x, y, width, height, 4853bf215546Sopenharmony_ci self); 4854bf215546Sopenharmony_ci } 4855bf215546Sopenharmony_ci else 4856bf215546Sopenharmony_ci copy_texture_sub_image_err(ctx, 3, texObj, texObj->Target, level, xoffset, 4857bf215546Sopenharmony_ci yoffset, zoffset, x, y, width, height, self); 4858bf215546Sopenharmony_ci} 4859bf215546Sopenharmony_ci 4860bf215546Sopenharmony_ci 4861bf215546Sopenharmony_civoid GLAPIENTRY 4862bf215546Sopenharmony_ci_mesa_CopyMultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, 4863bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, GLint zoffset, 4864bf215546Sopenharmony_ci GLint x, GLint y, GLsizei width, GLsizei height) 4865bf215546Sopenharmony_ci{ 4866bf215546Sopenharmony_ci struct gl_texture_object* texObj; 4867bf215546Sopenharmony_ci const char *self = "glCopyMultiTexSubImage3D"; 4868bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 4869bf215546Sopenharmony_ci 4870bf215546Sopenharmony_ci texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, 4871bf215546Sopenharmony_ci texunit - GL_TEXTURE0, 4872bf215546Sopenharmony_ci false, self); 4873bf215546Sopenharmony_ci if (!texObj) 4874bf215546Sopenharmony_ci return; 4875bf215546Sopenharmony_ci 4876bf215546Sopenharmony_ci if (texObj->Target == GL_TEXTURE_CUBE_MAP) { 4877bf215546Sopenharmony_ci /* Act like CopyTexSubImage2D */ 4878bf215546Sopenharmony_ci copy_texture_sub_image_err(ctx, 2, texObj, 4879bf215546Sopenharmony_ci GL_TEXTURE_CUBE_MAP_POSITIVE_X + zoffset, 4880bf215546Sopenharmony_ci level, xoffset, yoffset, 0, x, y, width, height, 4881bf215546Sopenharmony_ci self); 4882bf215546Sopenharmony_ci } 4883bf215546Sopenharmony_ci else 4884bf215546Sopenharmony_ci copy_texture_sub_image_err(ctx, 3, texObj, texObj->Target, level, xoffset, 4885bf215546Sopenharmony_ci yoffset, zoffset, x, y, width, height, self); 4886bf215546Sopenharmony_ci} 4887bf215546Sopenharmony_ci 4888bf215546Sopenharmony_ci 4889bf215546Sopenharmony_civoid GLAPIENTRY 4890bf215546Sopenharmony_ci_mesa_CopyTexSubImage1D_no_error(GLenum target, GLint level, GLint xoffset, 4891bf215546Sopenharmony_ci GLint x, GLint y, GLsizei width) 4892bf215546Sopenharmony_ci{ 4893bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 4894bf215546Sopenharmony_ci 4895bf215546Sopenharmony_ci struct gl_texture_object* texObj = _mesa_get_current_tex_object(ctx, target); 4896bf215546Sopenharmony_ci copy_texture_sub_image_no_error(ctx, 1, texObj, target, level, xoffset, 0, 0, 4897bf215546Sopenharmony_ci x, y, width, 1); 4898bf215546Sopenharmony_ci} 4899bf215546Sopenharmony_ci 4900bf215546Sopenharmony_ci 4901bf215546Sopenharmony_civoid GLAPIENTRY 4902bf215546Sopenharmony_ci_mesa_CopyTexSubImage2D_no_error(GLenum target, GLint level, GLint xoffset, 4903bf215546Sopenharmony_ci GLint yoffset, GLint x, GLint y, GLsizei width, 4904bf215546Sopenharmony_ci GLsizei height) 4905bf215546Sopenharmony_ci{ 4906bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 4907bf215546Sopenharmony_ci 4908bf215546Sopenharmony_ci struct gl_texture_object* texObj = _mesa_get_current_tex_object(ctx, target); 4909bf215546Sopenharmony_ci copy_texture_sub_image_no_error(ctx, 2, texObj, target, level, xoffset, 4910bf215546Sopenharmony_ci yoffset, 0, x, y, width, height); 4911bf215546Sopenharmony_ci} 4912bf215546Sopenharmony_ci 4913bf215546Sopenharmony_ci 4914bf215546Sopenharmony_civoid GLAPIENTRY 4915bf215546Sopenharmony_ci_mesa_CopyTexSubImage3D_no_error(GLenum target, GLint level, GLint xoffset, 4916bf215546Sopenharmony_ci GLint yoffset, GLint zoffset, GLint x, GLint y, 4917bf215546Sopenharmony_ci GLsizei width, GLsizei height) 4918bf215546Sopenharmony_ci{ 4919bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 4920bf215546Sopenharmony_ci 4921bf215546Sopenharmony_ci struct gl_texture_object* texObj = _mesa_get_current_tex_object(ctx, target); 4922bf215546Sopenharmony_ci copy_texture_sub_image_no_error(ctx, 3, texObj, target, level, xoffset, 4923bf215546Sopenharmony_ci yoffset, zoffset, x, y, width, height); 4924bf215546Sopenharmony_ci} 4925bf215546Sopenharmony_ci 4926bf215546Sopenharmony_ci 4927bf215546Sopenharmony_civoid GLAPIENTRY 4928bf215546Sopenharmony_ci_mesa_CopyTextureSubImage1D_no_error(GLuint texture, GLint level, GLint xoffset, 4929bf215546Sopenharmony_ci GLint x, GLint y, GLsizei width) 4930bf215546Sopenharmony_ci{ 4931bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 4932bf215546Sopenharmony_ci 4933bf215546Sopenharmony_ci struct gl_texture_object* texObj = _mesa_lookup_texture(ctx, texture); 4934bf215546Sopenharmony_ci copy_texture_sub_image_no_error(ctx, 1, texObj, texObj->Target, level, 4935bf215546Sopenharmony_ci xoffset, 0, 0, x, y, width, 1); 4936bf215546Sopenharmony_ci} 4937bf215546Sopenharmony_ci 4938bf215546Sopenharmony_ci 4939bf215546Sopenharmony_civoid GLAPIENTRY 4940bf215546Sopenharmony_ci_mesa_CopyTextureSubImage2D_no_error(GLuint texture, GLint level, GLint xoffset, 4941bf215546Sopenharmony_ci GLint yoffset, GLint x, GLint y, 4942bf215546Sopenharmony_ci GLsizei width, GLsizei height) 4943bf215546Sopenharmony_ci{ 4944bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 4945bf215546Sopenharmony_ci 4946bf215546Sopenharmony_ci struct gl_texture_object* texObj = _mesa_lookup_texture(ctx, texture); 4947bf215546Sopenharmony_ci copy_texture_sub_image_no_error(ctx, 2, texObj, texObj->Target, level, 4948bf215546Sopenharmony_ci xoffset, yoffset, 0, x, y, width, height); 4949bf215546Sopenharmony_ci} 4950bf215546Sopenharmony_ci 4951bf215546Sopenharmony_ci 4952bf215546Sopenharmony_civoid GLAPIENTRY 4953bf215546Sopenharmony_ci_mesa_CopyTextureSubImage3D_no_error(GLuint texture, GLint level, GLint xoffset, 4954bf215546Sopenharmony_ci GLint yoffset, GLint zoffset, GLint x, 4955bf215546Sopenharmony_ci GLint y, GLsizei width, GLsizei height) 4956bf215546Sopenharmony_ci{ 4957bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 4958bf215546Sopenharmony_ci 4959bf215546Sopenharmony_ci struct gl_texture_object* texObj = _mesa_lookup_texture(ctx, texture); 4960bf215546Sopenharmony_ci if (texObj->Target == GL_TEXTURE_CUBE_MAP) { 4961bf215546Sopenharmony_ci /* Act like CopyTexSubImage2D */ 4962bf215546Sopenharmony_ci copy_texture_sub_image_no_error(ctx, 2, texObj, 4963bf215546Sopenharmony_ci GL_TEXTURE_CUBE_MAP_POSITIVE_X + zoffset, 4964bf215546Sopenharmony_ci level, xoffset, yoffset, 0, x, y, width, 4965bf215546Sopenharmony_ci height); 4966bf215546Sopenharmony_ci } 4967bf215546Sopenharmony_ci else 4968bf215546Sopenharmony_ci copy_texture_sub_image_no_error(ctx, 3, texObj, texObj->Target, level, 4969bf215546Sopenharmony_ci xoffset, yoffset, zoffset, x, y, width, 4970bf215546Sopenharmony_ci height); 4971bf215546Sopenharmony_ci} 4972bf215546Sopenharmony_ci 4973bf215546Sopenharmony_ci 4974bf215546Sopenharmony_cistatic bool 4975bf215546Sopenharmony_cicheck_clear_tex_image(struct gl_context *ctx, 4976bf215546Sopenharmony_ci const char *function, 4977bf215546Sopenharmony_ci struct gl_texture_image *texImage, 4978bf215546Sopenharmony_ci GLenum format, GLenum type, 4979bf215546Sopenharmony_ci const void *data, 4980bf215546Sopenharmony_ci GLubyte *clearValue) 4981bf215546Sopenharmony_ci{ 4982bf215546Sopenharmony_ci struct gl_texture_object *texObj = texImage->TexObject; 4983bf215546Sopenharmony_ci static const GLubyte zeroData[MAX_PIXEL_BYTES]; 4984bf215546Sopenharmony_ci GLenum internalFormat = texImage->InternalFormat; 4985bf215546Sopenharmony_ci GLenum err; 4986bf215546Sopenharmony_ci 4987bf215546Sopenharmony_ci if (texObj->Target == GL_TEXTURE_BUFFER) { 4988bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 4989bf215546Sopenharmony_ci "%s(buffer texture)", function); 4990bf215546Sopenharmony_ci return false; 4991bf215546Sopenharmony_ci } 4992bf215546Sopenharmony_ci 4993bf215546Sopenharmony_ci if (_mesa_is_compressed_format(ctx, internalFormat)) { 4994bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 4995bf215546Sopenharmony_ci "%s(compressed texture)", function); 4996bf215546Sopenharmony_ci return false; 4997bf215546Sopenharmony_ci } 4998bf215546Sopenharmony_ci 4999bf215546Sopenharmony_ci err = _mesa_error_check_format_and_type(ctx, format, type); 5000bf215546Sopenharmony_ci if (err != GL_NO_ERROR) { 5001bf215546Sopenharmony_ci _mesa_error(ctx, err, 5002bf215546Sopenharmony_ci "%s(incompatible format = %s, type = %s)", 5003bf215546Sopenharmony_ci function, 5004bf215546Sopenharmony_ci _mesa_enum_to_string(format), 5005bf215546Sopenharmony_ci _mesa_enum_to_string(type)); 5006bf215546Sopenharmony_ci return false; 5007bf215546Sopenharmony_ci } 5008bf215546Sopenharmony_ci 5009bf215546Sopenharmony_ci /* make sure internal format and format basically agree */ 5010bf215546Sopenharmony_ci if (!texture_formats_agree(internalFormat, format)) { 5011bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 5012bf215546Sopenharmony_ci "%s(incompatible internalFormat = %s, format = %s)", 5013bf215546Sopenharmony_ci function, 5014bf215546Sopenharmony_ci _mesa_enum_to_string(internalFormat), 5015bf215546Sopenharmony_ci _mesa_enum_to_string(format)); 5016bf215546Sopenharmony_ci return false; 5017bf215546Sopenharmony_ci } 5018bf215546Sopenharmony_ci 5019bf215546Sopenharmony_ci if (ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) { 5020bf215546Sopenharmony_ci /* both source and dest must be integer-valued, or neither */ 5021bf215546Sopenharmony_ci if (_mesa_is_format_integer_color(texImage->TexFormat) != 5022bf215546Sopenharmony_ci _mesa_is_enum_format_integer(format)) { 5023bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 5024bf215546Sopenharmony_ci "%s(integer/non-integer format mismatch)", 5025bf215546Sopenharmony_ci function); 5026bf215546Sopenharmony_ci return false; 5027bf215546Sopenharmony_ci } 5028bf215546Sopenharmony_ci } 5029bf215546Sopenharmony_ci 5030bf215546Sopenharmony_ci if (!_mesa_texstore(ctx, 5031bf215546Sopenharmony_ci 1, /* dims */ 5032bf215546Sopenharmony_ci texImage->_BaseFormat, 5033bf215546Sopenharmony_ci texImage->TexFormat, 5034bf215546Sopenharmony_ci 0, /* dstRowStride */ 5035bf215546Sopenharmony_ci &clearValue, 5036bf215546Sopenharmony_ci 1, 1, 1, /* srcWidth/Height/Depth */ 5037bf215546Sopenharmony_ci format, type, 5038bf215546Sopenharmony_ci data ? data : zeroData, 5039bf215546Sopenharmony_ci &ctx->DefaultPacking)) { 5040bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid format)", function); 5041bf215546Sopenharmony_ci return false; 5042bf215546Sopenharmony_ci } 5043bf215546Sopenharmony_ci 5044bf215546Sopenharmony_ci return true; 5045bf215546Sopenharmony_ci} 5046bf215546Sopenharmony_ci 5047bf215546Sopenharmony_ci 5048bf215546Sopenharmony_cistatic struct gl_texture_object * 5049bf215546Sopenharmony_ciget_tex_obj_for_clear(struct gl_context *ctx, 5050bf215546Sopenharmony_ci const char *function, 5051bf215546Sopenharmony_ci GLuint texture) 5052bf215546Sopenharmony_ci{ 5053bf215546Sopenharmony_ci struct gl_texture_object *texObj; 5054bf215546Sopenharmony_ci 5055bf215546Sopenharmony_ci texObj = _mesa_lookup_texture_err(ctx, texture, function); 5056bf215546Sopenharmony_ci if (!texObj) 5057bf215546Sopenharmony_ci return NULL; 5058bf215546Sopenharmony_ci 5059bf215546Sopenharmony_ci if (texObj->Target == 0) { 5060bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unbound tex)", function); 5061bf215546Sopenharmony_ci return NULL; 5062bf215546Sopenharmony_ci } 5063bf215546Sopenharmony_ci 5064bf215546Sopenharmony_ci return texObj; 5065bf215546Sopenharmony_ci} 5066bf215546Sopenharmony_ci 5067bf215546Sopenharmony_ci 5068bf215546Sopenharmony_ci/** 5069bf215546Sopenharmony_ci * For clearing cube textures, the zoffset and depth parameters indicate 5070bf215546Sopenharmony_ci * which cube map faces are to be cleared. This is the one case where we 5071bf215546Sopenharmony_ci * need to be concerned with multiple gl_texture_images. This function 5072bf215546Sopenharmony_ci * returns the array of texture images to clear for cube maps, or one 5073bf215546Sopenharmony_ci * texture image otherwise. 5074bf215546Sopenharmony_ci * \return number of texture images, 0 for error, 6 for cube, 1 otherwise. 5075bf215546Sopenharmony_ci */ 5076bf215546Sopenharmony_cistatic int 5077bf215546Sopenharmony_ciget_tex_images_for_clear(struct gl_context *ctx, 5078bf215546Sopenharmony_ci const char *function, 5079bf215546Sopenharmony_ci struct gl_texture_object *texObj, 5080bf215546Sopenharmony_ci GLint level, 5081bf215546Sopenharmony_ci struct gl_texture_image **texImages) 5082bf215546Sopenharmony_ci{ 5083bf215546Sopenharmony_ci GLenum target; 5084bf215546Sopenharmony_ci int numFaces, i; 5085bf215546Sopenharmony_ci 5086bf215546Sopenharmony_ci if (level < 0 || level >= MAX_TEXTURE_LEVELS) { 5087bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid level)", function); 5088bf215546Sopenharmony_ci return 0; 5089bf215546Sopenharmony_ci } 5090bf215546Sopenharmony_ci 5091bf215546Sopenharmony_ci if (texObj->Target == GL_TEXTURE_CUBE_MAP) { 5092bf215546Sopenharmony_ci target = GL_TEXTURE_CUBE_MAP_POSITIVE_X; 5093bf215546Sopenharmony_ci numFaces = MAX_FACES; 5094bf215546Sopenharmony_ci } 5095bf215546Sopenharmony_ci else { 5096bf215546Sopenharmony_ci target = texObj->Target; 5097bf215546Sopenharmony_ci numFaces = 1; 5098bf215546Sopenharmony_ci } 5099bf215546Sopenharmony_ci 5100bf215546Sopenharmony_ci for (i = 0; i < numFaces; i++) { 5101bf215546Sopenharmony_ci texImages[i] = _mesa_select_tex_image(texObj, target + i, level); 5102bf215546Sopenharmony_ci if (texImages[i] == NULL) { 5103bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid level)", function); 5104bf215546Sopenharmony_ci return 0; 5105bf215546Sopenharmony_ci } 5106bf215546Sopenharmony_ci } 5107bf215546Sopenharmony_ci 5108bf215546Sopenharmony_ci return numFaces; 5109bf215546Sopenharmony_ci} 5110bf215546Sopenharmony_ci 5111bf215546Sopenharmony_ci 5112bf215546Sopenharmony_civoid GLAPIENTRY 5113bf215546Sopenharmony_ci_mesa_ClearTexSubImage(GLuint texture, GLint level, 5114bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, GLint zoffset, 5115bf215546Sopenharmony_ci GLsizei width, GLsizei height, GLsizei depth, 5116bf215546Sopenharmony_ci GLenum format, GLenum type, const void *data) 5117bf215546Sopenharmony_ci{ 5118bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 5119bf215546Sopenharmony_ci struct gl_texture_object *texObj; 5120bf215546Sopenharmony_ci struct gl_texture_image *texImages[MAX_FACES]; 5121bf215546Sopenharmony_ci GLubyte clearValue[MAX_FACES][MAX_PIXEL_BYTES]; 5122bf215546Sopenharmony_ci int i, numImages; 5123bf215546Sopenharmony_ci int minDepth, maxDepth; 5124bf215546Sopenharmony_ci 5125bf215546Sopenharmony_ci texObj = get_tex_obj_for_clear(ctx, "glClearTexSubImage", texture); 5126bf215546Sopenharmony_ci 5127bf215546Sopenharmony_ci if (texObj == NULL) 5128bf215546Sopenharmony_ci return; 5129bf215546Sopenharmony_ci 5130bf215546Sopenharmony_ci _mesa_lock_texture(ctx, texObj); 5131bf215546Sopenharmony_ci 5132bf215546Sopenharmony_ci numImages = get_tex_images_for_clear(ctx, "glClearTexSubImage", 5133bf215546Sopenharmony_ci texObj, level, texImages); 5134bf215546Sopenharmony_ci if (numImages == 0) 5135bf215546Sopenharmony_ci goto out; 5136bf215546Sopenharmony_ci 5137bf215546Sopenharmony_ci if (numImages == 1) { 5138bf215546Sopenharmony_ci minDepth = -(int) texImages[0]->Border; 5139bf215546Sopenharmony_ci maxDepth = texImages[0]->Depth; 5140bf215546Sopenharmony_ci } else { 5141bf215546Sopenharmony_ci assert(numImages == MAX_FACES); 5142bf215546Sopenharmony_ci minDepth = 0; 5143bf215546Sopenharmony_ci maxDepth = numImages; 5144bf215546Sopenharmony_ci } 5145bf215546Sopenharmony_ci 5146bf215546Sopenharmony_ci if (xoffset < -(GLint) texImages[0]->Border || 5147bf215546Sopenharmony_ci yoffset < -(GLint) texImages[0]->Border || 5148bf215546Sopenharmony_ci zoffset < minDepth || 5149bf215546Sopenharmony_ci width < 0 || 5150bf215546Sopenharmony_ci height < 0 || 5151bf215546Sopenharmony_ci depth < 0 || 5152bf215546Sopenharmony_ci xoffset + width > texImages[0]->Width || 5153bf215546Sopenharmony_ci yoffset + height > texImages[0]->Height || 5154bf215546Sopenharmony_ci zoffset + depth > maxDepth) { 5155bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 5156bf215546Sopenharmony_ci "glClearSubTexImage(invalid dimensions)"); 5157bf215546Sopenharmony_ci goto out; 5158bf215546Sopenharmony_ci } 5159bf215546Sopenharmony_ci 5160bf215546Sopenharmony_ci if (numImages == 1) { 5161bf215546Sopenharmony_ci if (check_clear_tex_image(ctx, "glClearTexSubImage", texImages[0], 5162bf215546Sopenharmony_ci format, type, data, clearValue[0])) { 5163bf215546Sopenharmony_ci st_ClearTexSubImage(ctx, 5164bf215546Sopenharmony_ci texImages[0], 5165bf215546Sopenharmony_ci xoffset, yoffset, zoffset, 5166bf215546Sopenharmony_ci width, height, depth, 5167bf215546Sopenharmony_ci data ? clearValue[0] : NULL); 5168bf215546Sopenharmony_ci } 5169bf215546Sopenharmony_ci } else { 5170bf215546Sopenharmony_ci /* loop over cube face images */ 5171bf215546Sopenharmony_ci for (i = zoffset; i < zoffset + depth; i++) { 5172bf215546Sopenharmony_ci assert(i < MAX_FACES); 5173bf215546Sopenharmony_ci if (!check_clear_tex_image(ctx, "glClearTexSubImage", texImages[i], 5174bf215546Sopenharmony_ci format, type, data, clearValue[i])) 5175bf215546Sopenharmony_ci goto out; 5176bf215546Sopenharmony_ci } 5177bf215546Sopenharmony_ci for (i = zoffset; i < zoffset + depth; i++) { 5178bf215546Sopenharmony_ci st_ClearTexSubImage(ctx, 5179bf215546Sopenharmony_ci texImages[i], 5180bf215546Sopenharmony_ci xoffset, yoffset, 0, 5181bf215546Sopenharmony_ci width, height, 1, 5182bf215546Sopenharmony_ci data ? clearValue[i] : NULL); 5183bf215546Sopenharmony_ci } 5184bf215546Sopenharmony_ci } 5185bf215546Sopenharmony_ci 5186bf215546Sopenharmony_ci out: 5187bf215546Sopenharmony_ci _mesa_unlock_texture(ctx, texObj); 5188bf215546Sopenharmony_ci} 5189bf215546Sopenharmony_ci 5190bf215546Sopenharmony_ci 5191bf215546Sopenharmony_civoid GLAPIENTRY 5192bf215546Sopenharmony_ci_mesa_ClearTexImage( GLuint texture, GLint level, 5193bf215546Sopenharmony_ci GLenum format, GLenum type, const void *data ) 5194bf215546Sopenharmony_ci{ 5195bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 5196bf215546Sopenharmony_ci struct gl_texture_object *texObj; 5197bf215546Sopenharmony_ci struct gl_texture_image *texImages[MAX_FACES]; 5198bf215546Sopenharmony_ci GLubyte clearValue[MAX_FACES][MAX_PIXEL_BYTES]; 5199bf215546Sopenharmony_ci int i, numImages; 5200bf215546Sopenharmony_ci 5201bf215546Sopenharmony_ci texObj = get_tex_obj_for_clear(ctx, "glClearTexImage", texture); 5202bf215546Sopenharmony_ci 5203bf215546Sopenharmony_ci if (texObj == NULL) 5204bf215546Sopenharmony_ci return; 5205bf215546Sopenharmony_ci 5206bf215546Sopenharmony_ci _mesa_lock_texture(ctx, texObj); 5207bf215546Sopenharmony_ci 5208bf215546Sopenharmony_ci numImages = get_tex_images_for_clear(ctx, "glClearTexImage", 5209bf215546Sopenharmony_ci texObj, level, texImages); 5210bf215546Sopenharmony_ci 5211bf215546Sopenharmony_ci for (i = 0; i < numImages; i++) { 5212bf215546Sopenharmony_ci if (!check_clear_tex_image(ctx, "glClearTexImage", texImages[i], format, 5213bf215546Sopenharmony_ci type, data, clearValue[i])) 5214bf215546Sopenharmony_ci goto out; 5215bf215546Sopenharmony_ci } 5216bf215546Sopenharmony_ci 5217bf215546Sopenharmony_ci for (i = 0; i < numImages; i++) { 5218bf215546Sopenharmony_ci st_ClearTexSubImage(ctx, texImages[i], 5219bf215546Sopenharmony_ci -(GLint) texImages[i]->Border, /* xoffset */ 5220bf215546Sopenharmony_ci -(GLint) texImages[i]->Border, /* yoffset */ 5221bf215546Sopenharmony_ci -(GLint) texImages[i]->Border, /* zoffset */ 5222bf215546Sopenharmony_ci texImages[i]->Width, 5223bf215546Sopenharmony_ci texImages[i]->Height, 5224bf215546Sopenharmony_ci texImages[i]->Depth, 5225bf215546Sopenharmony_ci data ? clearValue[i] : NULL); 5226bf215546Sopenharmony_ci } 5227bf215546Sopenharmony_ci 5228bf215546Sopenharmony_ciout: 5229bf215546Sopenharmony_ci _mesa_unlock_texture(ctx, texObj); 5230bf215546Sopenharmony_ci} 5231bf215546Sopenharmony_ci 5232bf215546Sopenharmony_ci 5233bf215546Sopenharmony_ci 5234bf215546Sopenharmony_ci 5235bf215546Sopenharmony_ci/**********************************************************************/ 5236bf215546Sopenharmony_ci/****** Compressed Textures ******/ 5237bf215546Sopenharmony_ci/**********************************************************************/ 5238bf215546Sopenharmony_ci 5239bf215546Sopenharmony_ci 5240bf215546Sopenharmony_ci/** 5241bf215546Sopenharmony_ci * Target checking for glCompressedTexSubImage[123]D(). 5242bf215546Sopenharmony_ci * \return GL_TRUE if error, GL_FALSE if no error 5243bf215546Sopenharmony_ci * Must come before other error checking so that the texture object can 5244bf215546Sopenharmony_ci * be correctly retrieved using _mesa_get_current_tex_object. 5245bf215546Sopenharmony_ci */ 5246bf215546Sopenharmony_cistatic GLboolean 5247bf215546Sopenharmony_cicompressed_subtexture_target_check(struct gl_context *ctx, GLenum target, 5248bf215546Sopenharmony_ci GLint dims, GLenum intFormat, bool dsa, 5249bf215546Sopenharmony_ci const char *caller) 5250bf215546Sopenharmony_ci{ 5251bf215546Sopenharmony_ci GLboolean targetOK; 5252bf215546Sopenharmony_ci mesa_format format; 5253bf215546Sopenharmony_ci enum mesa_format_layout layout; 5254bf215546Sopenharmony_ci 5255bf215546Sopenharmony_ci if (dsa && target == GL_TEXTURE_RECTANGLE) { 5256bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", caller, 5257bf215546Sopenharmony_ci _mesa_enum_to_string(target)); 5258bf215546Sopenharmony_ci return GL_TRUE; 5259bf215546Sopenharmony_ci } 5260bf215546Sopenharmony_ci 5261bf215546Sopenharmony_ci switch (dims) { 5262bf215546Sopenharmony_ci case 2: 5263bf215546Sopenharmony_ci switch (target) { 5264bf215546Sopenharmony_ci case GL_TEXTURE_2D: 5265bf215546Sopenharmony_ci targetOK = GL_TRUE; 5266bf215546Sopenharmony_ci break; 5267bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 5268bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 5269bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 5270bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 5271bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 5272bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 5273bf215546Sopenharmony_ci targetOK = GL_TRUE; 5274bf215546Sopenharmony_ci break; 5275bf215546Sopenharmony_ci default: 5276bf215546Sopenharmony_ci targetOK = GL_FALSE; 5277bf215546Sopenharmony_ci break; 5278bf215546Sopenharmony_ci } 5279bf215546Sopenharmony_ci break; 5280bf215546Sopenharmony_ci case 3: 5281bf215546Sopenharmony_ci switch (target) { 5282bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP: 5283bf215546Sopenharmony_ci targetOK = dsa; 5284bf215546Sopenharmony_ci break; 5285bf215546Sopenharmony_ci case GL_TEXTURE_2D_ARRAY: 5286bf215546Sopenharmony_ci targetOK = _mesa_is_gles3(ctx) || 5287bf215546Sopenharmony_ci (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array); 5288bf215546Sopenharmony_ci break; 5289bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_ARRAY: 5290bf215546Sopenharmony_ci targetOK = _mesa_has_texture_cube_map_array(ctx); 5291bf215546Sopenharmony_ci break; 5292bf215546Sopenharmony_ci case GL_TEXTURE_3D: 5293bf215546Sopenharmony_ci targetOK = GL_TRUE; 5294bf215546Sopenharmony_ci /* 5295bf215546Sopenharmony_ci * OpenGL 4.5 spec (30.10.2014) says in Section 8.7 Compressed Texture 5296bf215546Sopenharmony_ci * Images: 5297bf215546Sopenharmony_ci * "An INVALID_OPERATION error is generated by 5298bf215546Sopenharmony_ci * CompressedTex*SubImage3D if the internal format of the texture 5299bf215546Sopenharmony_ci * is one of the EAC, ETC2, or RGTC formats and either border is 5300bf215546Sopenharmony_ci * non-zero, or the effective target for the texture is not 5301bf215546Sopenharmony_ci * TEXTURE_2D_ARRAY." 5302bf215546Sopenharmony_ci * 5303bf215546Sopenharmony_ci * NOTE: that's probably a spec error. It should probably say 5304bf215546Sopenharmony_ci * "... or the effective target for the texture is not 5305bf215546Sopenharmony_ci * TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP, nor 5306bf215546Sopenharmony_ci * GL_TEXTURE_CUBE_MAP_ARRAY." 5307bf215546Sopenharmony_ci * since those targets are 2D images and they support all compression 5308bf215546Sopenharmony_ci * formats. 5309bf215546Sopenharmony_ci * 5310bf215546Sopenharmony_ci * Instead of listing all these, just list those which are allowed, 5311bf215546Sopenharmony_ci * which is (at this time) only bptc. Otherwise we'd say s3tc (and 5312bf215546Sopenharmony_ci * more) are valid here, which they are not, but of course not 5313bf215546Sopenharmony_ci * mentioned by core spec. 5314bf215546Sopenharmony_ci * 5315bf215546Sopenharmony_ci * Also, from GL_KHR_texture_compression_astc_{hdr,ldr}: 5316bf215546Sopenharmony_ci * 5317bf215546Sopenharmony_ci * "Add a second new column "3D Tex." which is empty for all non-ASTC 5318bf215546Sopenharmony_ci * formats. If only the LDR profile is supported by the implementation, 5319bf215546Sopenharmony_ci * this column is also empty for all ASTC formats. If both the LDR and HDR 5320bf215546Sopenharmony_ci * profiles are supported, this column is checked for all ASTC formats." 5321bf215546Sopenharmony_ci * 5322bf215546Sopenharmony_ci * "An INVALID_OPERATION error is generated by CompressedTexSubImage3D if 5323bf215546Sopenharmony_ci * <format> is one of the formats in table 8.19 and <target> is not 5324bf215546Sopenharmony_ci * TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP_ARRAY, or TEXTURE_3D. 5325bf215546Sopenharmony_ci * 5326bf215546Sopenharmony_ci * An INVALID_OPERATION error is generated by CompressedTexSubImage3D if 5327bf215546Sopenharmony_ci * <format> is TEXTURE_CUBE_MAP_ARRAY and the "Cube Map Array" column of 5328bf215546Sopenharmony_ci * table 8.19 is *not* checked, or if <format> is TEXTURE_3D and the "3D 5329bf215546Sopenharmony_ci * Tex." column of table 8.19 is *not* checked" 5330bf215546Sopenharmony_ci * 5331bf215546Sopenharmony_ci * And from GL_KHR_texture_compression_astc_sliced_3d: 5332bf215546Sopenharmony_ci * 5333bf215546Sopenharmony_ci * "Modify the "3D Tex." column to be checked for all ASTC formats." 5334bf215546Sopenharmony_ci */ 5335bf215546Sopenharmony_ci format = _mesa_glenum_to_compressed_format(intFormat); 5336bf215546Sopenharmony_ci layout = _mesa_get_format_layout(format); 5337bf215546Sopenharmony_ci switch (layout) { 5338bf215546Sopenharmony_ci case MESA_FORMAT_LAYOUT_BPTC: 5339bf215546Sopenharmony_ci /* valid format */ 5340bf215546Sopenharmony_ci break; 5341bf215546Sopenharmony_ci case MESA_FORMAT_LAYOUT_ASTC: 5342bf215546Sopenharmony_ci targetOK = 5343bf215546Sopenharmony_ci ctx->Extensions.KHR_texture_compression_astc_hdr || 5344bf215546Sopenharmony_ci ctx->Extensions.KHR_texture_compression_astc_sliced_3d; 5345bf215546Sopenharmony_ci break; 5346bf215546Sopenharmony_ci default: 5347bf215546Sopenharmony_ci /* invalid format */ 5348bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 5349bf215546Sopenharmony_ci "%s(invalid target %s for format %s)", caller, 5350bf215546Sopenharmony_ci _mesa_enum_to_string(target), 5351bf215546Sopenharmony_ci _mesa_enum_to_string(intFormat)); 5352bf215546Sopenharmony_ci return GL_TRUE; 5353bf215546Sopenharmony_ci } 5354bf215546Sopenharmony_ci break; 5355bf215546Sopenharmony_ci default: 5356bf215546Sopenharmony_ci targetOK = GL_FALSE; 5357bf215546Sopenharmony_ci } 5358bf215546Sopenharmony_ci 5359bf215546Sopenharmony_ci break; 5360bf215546Sopenharmony_ci default: 5361bf215546Sopenharmony_ci assert(dims == 1); 5362bf215546Sopenharmony_ci /* no 1D compressed textures at this time */ 5363bf215546Sopenharmony_ci targetOK = GL_FALSE; 5364bf215546Sopenharmony_ci break; 5365bf215546Sopenharmony_ci } 5366bf215546Sopenharmony_ci 5367bf215546Sopenharmony_ci if (!targetOK) { 5368bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", caller, 5369bf215546Sopenharmony_ci _mesa_enum_to_string(target)); 5370bf215546Sopenharmony_ci return GL_TRUE; 5371bf215546Sopenharmony_ci } 5372bf215546Sopenharmony_ci 5373bf215546Sopenharmony_ci return GL_FALSE; 5374bf215546Sopenharmony_ci} 5375bf215546Sopenharmony_ci 5376bf215546Sopenharmony_ci/** 5377bf215546Sopenharmony_ci * Error checking for glCompressedTexSubImage[123]D(). 5378bf215546Sopenharmony_ci * \return GL_TRUE if error, GL_FALSE if no error 5379bf215546Sopenharmony_ci */ 5380bf215546Sopenharmony_cistatic GLboolean 5381bf215546Sopenharmony_cicompressed_subtexture_error_check(struct gl_context *ctx, GLint dims, 5382bf215546Sopenharmony_ci const struct gl_texture_object *texObj, 5383bf215546Sopenharmony_ci GLenum target, GLint level, 5384bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, GLint zoffset, 5385bf215546Sopenharmony_ci GLsizei width, GLsizei height, GLsizei depth, 5386bf215546Sopenharmony_ci GLenum format, GLsizei imageSize, 5387bf215546Sopenharmony_ci const GLvoid *data, const char *callerName) 5388bf215546Sopenharmony_ci{ 5389bf215546Sopenharmony_ci struct gl_texture_image *texImage; 5390bf215546Sopenharmony_ci GLint expectedSize; 5391bf215546Sopenharmony_ci 5392bf215546Sopenharmony_ci GLenum is_generic_compressed_token = 5393bf215546Sopenharmony_ci _mesa_generic_compressed_format_to_uncompressed_format(format) != 5394bf215546Sopenharmony_ci format; 5395bf215546Sopenharmony_ci 5396bf215546Sopenharmony_ci /* OpenGL 4.6 and OpenGL ES 3.2 spec: 5397bf215546Sopenharmony_ci * 5398bf215546Sopenharmony_ci * "An INVALID_OPERATION error is generated if format does not match the 5399bf215546Sopenharmony_ci * internal format of the texture image being modified, since these commands do 5400bf215546Sopenharmony_ci * not provide for image format conversion." 5401bf215546Sopenharmony_ci * 5402bf215546Sopenharmony_ci * Desktop spec has an additional rule for GL_INVALID_ENUM: 5403bf215546Sopenharmony_ci * 5404bf215546Sopenharmony_ci * "An INVALID_ENUM error is generated if format is one of the generic 5405bf215546Sopenharmony_ci * compressed internal formats." 5406bf215546Sopenharmony_ci */ 5407bf215546Sopenharmony_ci /* this will catch any invalid compressed format token */ 5408bf215546Sopenharmony_ci if (!_mesa_is_compressed_format(ctx, format)) { 5409bf215546Sopenharmony_ci GLenum error = _mesa_is_desktop_gl(ctx) && is_generic_compressed_token ? 5410bf215546Sopenharmony_ci GL_INVALID_ENUM : GL_INVALID_OPERATION; 5411bf215546Sopenharmony_ci _mesa_error(ctx, error, "%s(format)", callerName); 5412bf215546Sopenharmony_ci return GL_TRUE; 5413bf215546Sopenharmony_ci } 5414bf215546Sopenharmony_ci 5415bf215546Sopenharmony_ci if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) { 5416bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, "%s(level=%d)", callerName, level); 5417bf215546Sopenharmony_ci return GL_TRUE; 5418bf215546Sopenharmony_ci } 5419bf215546Sopenharmony_ci 5420bf215546Sopenharmony_ci /* validate the bound PBO, if any */ 5421bf215546Sopenharmony_ci if (!_mesa_validate_pbo_source_compressed(ctx, dims, &ctx->Unpack, 5422bf215546Sopenharmony_ci imageSize, data, callerName)) { 5423bf215546Sopenharmony_ci return GL_TRUE; 5424bf215546Sopenharmony_ci } 5425bf215546Sopenharmony_ci 5426bf215546Sopenharmony_ci /* Check for invalid pixel storage modes */ 5427bf215546Sopenharmony_ci if (!_mesa_compressed_pixel_storage_error_check(ctx, dims, 5428bf215546Sopenharmony_ci &ctx->Unpack, callerName)) { 5429bf215546Sopenharmony_ci return GL_TRUE; 5430bf215546Sopenharmony_ci } 5431bf215546Sopenharmony_ci 5432bf215546Sopenharmony_ci expectedSize = compressed_tex_size(width, height, depth, format); 5433bf215546Sopenharmony_ci if (expectedSize != imageSize) { 5434bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d)", callerName, imageSize); 5435bf215546Sopenharmony_ci return GL_TRUE; 5436bf215546Sopenharmony_ci } 5437bf215546Sopenharmony_ci 5438bf215546Sopenharmony_ci texImage = _mesa_select_tex_image(texObj, target, level); 5439bf215546Sopenharmony_ci if (!texImage) { 5440bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid texture level %d)", 5441bf215546Sopenharmony_ci callerName, level); 5442bf215546Sopenharmony_ci return GL_TRUE; 5443bf215546Sopenharmony_ci } 5444bf215546Sopenharmony_ci 5445bf215546Sopenharmony_ci if ((GLint) format != texImage->InternalFormat) { 5446bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, "%s(format=%s)", 5447bf215546Sopenharmony_ci callerName, _mesa_enum_to_string(format)); 5448bf215546Sopenharmony_ci return GL_TRUE; 5449bf215546Sopenharmony_ci } 5450bf215546Sopenharmony_ci 5451bf215546Sopenharmony_ci if (compressedteximage_only_format(format)) { 5452bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, "%s(format=%s cannot be updated)", 5453bf215546Sopenharmony_ci callerName, _mesa_enum_to_string(format)); 5454bf215546Sopenharmony_ci return GL_TRUE; 5455bf215546Sopenharmony_ci } 5456bf215546Sopenharmony_ci 5457bf215546Sopenharmony_ci if (error_check_subtexture_negative_dimensions(ctx, dims, width, height, 5458bf215546Sopenharmony_ci depth, callerName)) { 5459bf215546Sopenharmony_ci return GL_TRUE; 5460bf215546Sopenharmony_ci } 5461bf215546Sopenharmony_ci 5462bf215546Sopenharmony_ci if (error_check_subtexture_dimensions(ctx, dims, texImage, xoffset, yoffset, 5463bf215546Sopenharmony_ci zoffset, width, height, depth, 5464bf215546Sopenharmony_ci callerName)) { 5465bf215546Sopenharmony_ci return GL_TRUE; 5466bf215546Sopenharmony_ci } 5467bf215546Sopenharmony_ci 5468bf215546Sopenharmony_ci return GL_FALSE; 5469bf215546Sopenharmony_ci} 5470bf215546Sopenharmony_ci 5471bf215546Sopenharmony_ci 5472bf215546Sopenharmony_civoid GLAPIENTRY 5473bf215546Sopenharmony_ci_mesa_CompressedTexImage1D(GLenum target, GLint level, 5474bf215546Sopenharmony_ci GLenum internalFormat, GLsizei width, 5475bf215546Sopenharmony_ci GLint border, GLsizei imageSize, 5476bf215546Sopenharmony_ci const GLvoid *data) 5477bf215546Sopenharmony_ci{ 5478bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 5479bf215546Sopenharmony_ci teximage_err(ctx, GL_TRUE, 1, target, level, internalFormat, 5480bf215546Sopenharmony_ci width, 1, 1, border, GL_NONE, GL_NONE, imageSize, data); 5481bf215546Sopenharmony_ci} 5482bf215546Sopenharmony_ci 5483bf215546Sopenharmony_ci 5484bf215546Sopenharmony_civoid GLAPIENTRY 5485bf215546Sopenharmony_ci_mesa_CompressedTextureImage1DEXT(GLuint texture, GLenum target, GLint level, 5486bf215546Sopenharmony_ci GLenum internalFormat, GLsizei width, 5487bf215546Sopenharmony_ci GLint border, GLsizei imageSize, 5488bf215546Sopenharmony_ci const GLvoid *pixels) 5489bf215546Sopenharmony_ci{ 5490bf215546Sopenharmony_ci struct gl_texture_object* texObj; 5491bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 5492bf215546Sopenharmony_ci 5493bf215546Sopenharmony_ci texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, 5494bf215546Sopenharmony_ci "glCompressedTextureImage1DEXT"); 5495bf215546Sopenharmony_ci if (!texObj) 5496bf215546Sopenharmony_ci return; 5497bf215546Sopenharmony_ci teximage(ctx, GL_TRUE, 1, texObj, target, level, internalFormat, 5498bf215546Sopenharmony_ci width, 1, 1, border, GL_NONE, GL_NONE, imageSize, pixels, false); 5499bf215546Sopenharmony_ci} 5500bf215546Sopenharmony_ci 5501bf215546Sopenharmony_ci 5502bf215546Sopenharmony_civoid GLAPIENTRY 5503bf215546Sopenharmony_ci_mesa_CompressedMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level, 5504bf215546Sopenharmony_ci GLenum internalFormat, GLsizei width, 5505bf215546Sopenharmony_ci GLint border, GLsizei imageSize, 5506bf215546Sopenharmony_ci const GLvoid *pixels) 5507bf215546Sopenharmony_ci{ 5508bf215546Sopenharmony_ci struct gl_texture_object* texObj; 5509bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 5510bf215546Sopenharmony_ci 5511bf215546Sopenharmony_ci texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, 5512bf215546Sopenharmony_ci texunit - GL_TEXTURE0, 5513bf215546Sopenharmony_ci true, 5514bf215546Sopenharmony_ci "glCompressedMultiTexImage1DEXT"); 5515bf215546Sopenharmony_ci if (!texObj) 5516bf215546Sopenharmony_ci return; 5517bf215546Sopenharmony_ci teximage(ctx, GL_TRUE, 1, texObj, target, level, internalFormat, 5518bf215546Sopenharmony_ci width, 1, 1, border, GL_NONE, GL_NONE, imageSize, pixels, false); 5519bf215546Sopenharmony_ci} 5520bf215546Sopenharmony_ci 5521bf215546Sopenharmony_ci 5522bf215546Sopenharmony_civoid GLAPIENTRY 5523bf215546Sopenharmony_ci_mesa_CompressedTexImage2D(GLenum target, GLint level, 5524bf215546Sopenharmony_ci GLenum internalFormat, GLsizei width, 5525bf215546Sopenharmony_ci GLsizei height, GLint border, GLsizei imageSize, 5526bf215546Sopenharmony_ci const GLvoid *data) 5527bf215546Sopenharmony_ci{ 5528bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 5529bf215546Sopenharmony_ci teximage_err(ctx, GL_TRUE, 2, target, level, internalFormat, 5530bf215546Sopenharmony_ci width, height, 1, border, GL_NONE, GL_NONE, imageSize, data); 5531bf215546Sopenharmony_ci} 5532bf215546Sopenharmony_ci 5533bf215546Sopenharmony_ci 5534bf215546Sopenharmony_civoid GLAPIENTRY 5535bf215546Sopenharmony_ci_mesa_CompressedTextureImage2DEXT(GLuint texture, GLenum target, GLint level, 5536bf215546Sopenharmony_ci GLenum internalFormat, GLsizei width, 5537bf215546Sopenharmony_ci GLsizei height, GLint border, GLsizei imageSize, 5538bf215546Sopenharmony_ci const GLvoid *pixels) 5539bf215546Sopenharmony_ci{ 5540bf215546Sopenharmony_ci struct gl_texture_object* texObj; 5541bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 5542bf215546Sopenharmony_ci 5543bf215546Sopenharmony_ci texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, 5544bf215546Sopenharmony_ci "glCompressedTextureImage2DEXT"); 5545bf215546Sopenharmony_ci if (!texObj) 5546bf215546Sopenharmony_ci return; 5547bf215546Sopenharmony_ci teximage(ctx, GL_TRUE, 2, texObj, target, level, internalFormat, 5548bf215546Sopenharmony_ci width, height, 1, border, GL_NONE, GL_NONE, imageSize, pixels, false); 5549bf215546Sopenharmony_ci} 5550bf215546Sopenharmony_ci 5551bf215546Sopenharmony_ci 5552bf215546Sopenharmony_civoid GLAPIENTRY 5553bf215546Sopenharmony_ci_mesa_CompressedMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level, 5554bf215546Sopenharmony_ci GLenum internalFormat, GLsizei width, 5555bf215546Sopenharmony_ci GLsizei height, GLint border, GLsizei imageSize, 5556bf215546Sopenharmony_ci const GLvoid *pixels) 5557bf215546Sopenharmony_ci{ 5558bf215546Sopenharmony_ci struct gl_texture_object* texObj; 5559bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 5560bf215546Sopenharmony_ci 5561bf215546Sopenharmony_ci texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, 5562bf215546Sopenharmony_ci texunit - GL_TEXTURE0, 5563bf215546Sopenharmony_ci true, 5564bf215546Sopenharmony_ci "glCompressedMultiTexImage2DEXT"); 5565bf215546Sopenharmony_ci if (!texObj) 5566bf215546Sopenharmony_ci return; 5567bf215546Sopenharmony_ci teximage(ctx, GL_TRUE, 2, texObj, target, level, internalFormat, 5568bf215546Sopenharmony_ci width, height, 1, border, GL_NONE, GL_NONE, imageSize, pixels, false); 5569bf215546Sopenharmony_ci} 5570bf215546Sopenharmony_ci 5571bf215546Sopenharmony_ci 5572bf215546Sopenharmony_civoid GLAPIENTRY 5573bf215546Sopenharmony_ci_mesa_CompressedTexImage3D(GLenum target, GLint level, 5574bf215546Sopenharmony_ci GLenum internalFormat, GLsizei width, 5575bf215546Sopenharmony_ci GLsizei height, GLsizei depth, GLint border, 5576bf215546Sopenharmony_ci GLsizei imageSize, const GLvoid *data) 5577bf215546Sopenharmony_ci{ 5578bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 5579bf215546Sopenharmony_ci teximage_err(ctx, GL_TRUE, 3, target, level, internalFormat, width, height, 5580bf215546Sopenharmony_ci depth, border, GL_NONE, GL_NONE, imageSize, data); 5581bf215546Sopenharmony_ci} 5582bf215546Sopenharmony_ci 5583bf215546Sopenharmony_ci 5584bf215546Sopenharmony_civoid GLAPIENTRY 5585bf215546Sopenharmony_ci_mesa_CompressedTextureImage3DEXT(GLuint texture, GLenum target, GLint level, 5586bf215546Sopenharmony_ci GLenum internalFormat, GLsizei width, 5587bf215546Sopenharmony_ci GLsizei height, GLsizei depth, GLint border, 5588bf215546Sopenharmony_ci GLsizei imageSize, const GLvoid *pixels) 5589bf215546Sopenharmony_ci{ 5590bf215546Sopenharmony_ci struct gl_texture_object* texObj; 5591bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 5592bf215546Sopenharmony_ci 5593bf215546Sopenharmony_ci texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, 5594bf215546Sopenharmony_ci "glCompressedTextureImage3DEXT"); 5595bf215546Sopenharmony_ci if (!texObj) 5596bf215546Sopenharmony_ci return; 5597bf215546Sopenharmony_ci teximage(ctx, GL_TRUE, 3, texObj, target, level, internalFormat, 5598bf215546Sopenharmony_ci width, height, depth, border, GL_NONE, GL_NONE, imageSize, pixels, false); 5599bf215546Sopenharmony_ci} 5600bf215546Sopenharmony_ci 5601bf215546Sopenharmony_ci 5602bf215546Sopenharmony_civoid GLAPIENTRY 5603bf215546Sopenharmony_ci_mesa_CompressedMultiTexImage3DEXT(GLenum texunit, GLenum target, GLint level, 5604bf215546Sopenharmony_ci GLenum internalFormat, GLsizei width, 5605bf215546Sopenharmony_ci GLsizei height, GLsizei depth, GLint border, 5606bf215546Sopenharmony_ci GLsizei imageSize, const GLvoid *pixels) 5607bf215546Sopenharmony_ci{ 5608bf215546Sopenharmony_ci struct gl_texture_object* texObj; 5609bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 5610bf215546Sopenharmony_ci 5611bf215546Sopenharmony_ci texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, 5612bf215546Sopenharmony_ci texunit - GL_TEXTURE0, 5613bf215546Sopenharmony_ci true, 5614bf215546Sopenharmony_ci "glCompressedMultiTexImage3DEXT"); 5615bf215546Sopenharmony_ci if (!texObj) 5616bf215546Sopenharmony_ci return; 5617bf215546Sopenharmony_ci teximage(ctx, GL_TRUE, 3, texObj, target, level, internalFormat, 5618bf215546Sopenharmony_ci width, height, depth, border, GL_NONE, GL_NONE, imageSize, pixels, false); 5619bf215546Sopenharmony_ci} 5620bf215546Sopenharmony_ci 5621bf215546Sopenharmony_ci 5622bf215546Sopenharmony_civoid GLAPIENTRY 5623bf215546Sopenharmony_ci_mesa_CompressedTexImage1D_no_error(GLenum target, GLint level, 5624bf215546Sopenharmony_ci GLenum internalFormat, GLsizei width, 5625bf215546Sopenharmony_ci GLint border, GLsizei imageSize, 5626bf215546Sopenharmony_ci const GLvoid *data) 5627bf215546Sopenharmony_ci{ 5628bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 5629bf215546Sopenharmony_ci teximage_no_error(ctx, GL_TRUE, 1, target, level, internalFormat, width, 1, 5630bf215546Sopenharmony_ci 1, border, GL_NONE, GL_NONE, imageSize, data); 5631bf215546Sopenharmony_ci} 5632bf215546Sopenharmony_ci 5633bf215546Sopenharmony_ci 5634bf215546Sopenharmony_civoid GLAPIENTRY 5635bf215546Sopenharmony_ci_mesa_CompressedTexImage2D_no_error(GLenum target, GLint level, 5636bf215546Sopenharmony_ci GLenum internalFormat, GLsizei width, 5637bf215546Sopenharmony_ci GLsizei height, GLint border, 5638bf215546Sopenharmony_ci GLsizei imageSize, const GLvoid *data) 5639bf215546Sopenharmony_ci{ 5640bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 5641bf215546Sopenharmony_ci teximage_no_error(ctx, GL_TRUE, 2, target, level, internalFormat, width, 5642bf215546Sopenharmony_ci height, 1, border, GL_NONE, GL_NONE, imageSize, data); 5643bf215546Sopenharmony_ci} 5644bf215546Sopenharmony_ci 5645bf215546Sopenharmony_ci 5646bf215546Sopenharmony_civoid GLAPIENTRY 5647bf215546Sopenharmony_ci_mesa_CompressedTexImage3D_no_error(GLenum target, GLint level, 5648bf215546Sopenharmony_ci GLenum internalFormat, GLsizei width, 5649bf215546Sopenharmony_ci GLsizei height, GLsizei depth, GLint border, 5650bf215546Sopenharmony_ci GLsizei imageSize, const GLvoid *data) 5651bf215546Sopenharmony_ci{ 5652bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 5653bf215546Sopenharmony_ci teximage_no_error(ctx, GL_TRUE, 3, target, level, internalFormat, width, 5654bf215546Sopenharmony_ci height, depth, border, GL_NONE, GL_NONE, imageSize, data); 5655bf215546Sopenharmony_ci} 5656bf215546Sopenharmony_ci 5657bf215546Sopenharmony_ci 5658bf215546Sopenharmony_ci/** 5659bf215546Sopenharmony_ci * Common helper for glCompressedTexSubImage1/2/3D() and 5660bf215546Sopenharmony_ci * glCompressedTextureSubImage1/2/3D(). 5661bf215546Sopenharmony_ci */ 5662bf215546Sopenharmony_cistatic void 5663bf215546Sopenharmony_cicompressed_texture_sub_image(struct gl_context *ctx, GLuint dims, 5664bf215546Sopenharmony_ci struct gl_texture_object *texObj, 5665bf215546Sopenharmony_ci struct gl_texture_image *texImage, 5666bf215546Sopenharmony_ci GLenum target, GLint level, GLint xoffset, 5667bf215546Sopenharmony_ci GLint yoffset, GLint zoffset, GLsizei width, 5668bf215546Sopenharmony_ci GLsizei height, GLsizei depth, GLenum format, 5669bf215546Sopenharmony_ci GLsizei imageSize, const GLvoid *data) 5670bf215546Sopenharmony_ci{ 5671bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, 0, 0); 5672bf215546Sopenharmony_ci 5673bf215546Sopenharmony_ci _mesa_lock_texture(ctx, texObj); 5674bf215546Sopenharmony_ci { 5675bf215546Sopenharmony_ci if (width > 0 && height > 0 && depth > 0) { 5676bf215546Sopenharmony_ci st_CompressedTexSubImage(ctx, dims, texImage, 5677bf215546Sopenharmony_ci xoffset, yoffset, zoffset, 5678bf215546Sopenharmony_ci width, height, depth, 5679bf215546Sopenharmony_ci format, imageSize, data); 5680bf215546Sopenharmony_ci 5681bf215546Sopenharmony_ci check_gen_mipmap(ctx, target, texObj, level); 5682bf215546Sopenharmony_ci 5683bf215546Sopenharmony_ci /* NOTE: Don't signal _NEW_TEXTURE_OBJECT since we've only changed 5684bf215546Sopenharmony_ci * the texel data, not the texture format, size, etc. 5685bf215546Sopenharmony_ci */ 5686bf215546Sopenharmony_ci } 5687bf215546Sopenharmony_ci } 5688bf215546Sopenharmony_ci _mesa_unlock_texture(ctx, texObj); 5689bf215546Sopenharmony_ci} 5690bf215546Sopenharmony_ci 5691bf215546Sopenharmony_ci 5692bf215546Sopenharmony_cienum tex_mode { 5693bf215546Sopenharmony_ci /* Use bound texture to current unit */ 5694bf215546Sopenharmony_ci TEX_MODE_CURRENT_NO_ERROR = 0, 5695bf215546Sopenharmony_ci TEX_MODE_CURRENT_ERROR, 5696bf215546Sopenharmony_ci /* Use the specified texture name */ 5697bf215546Sopenharmony_ci TEX_MODE_DSA_NO_ERROR, 5698bf215546Sopenharmony_ci TEX_MODE_DSA_ERROR, 5699bf215546Sopenharmony_ci /* Use the specified texture name + target */ 5700bf215546Sopenharmony_ci TEX_MODE_EXT_DSA_TEXTURE, 5701bf215546Sopenharmony_ci /* Use the specified texture unit + target */ 5702bf215546Sopenharmony_ci TEX_MODE_EXT_DSA_TEXUNIT, 5703bf215546Sopenharmony_ci}; 5704bf215546Sopenharmony_ci 5705bf215546Sopenharmony_ci 5706bf215546Sopenharmony_cistatic void 5707bf215546Sopenharmony_cicompressed_tex_sub_image(unsigned dim, GLenum target, GLuint textureOrIndex, 5708bf215546Sopenharmony_ci GLint level, GLint xoffset, GLint yoffset, 5709bf215546Sopenharmony_ci GLint zoffset, GLsizei width, GLsizei height, 5710bf215546Sopenharmony_ci GLsizei depth, GLenum format, GLsizei imageSize, 5711bf215546Sopenharmony_ci const GLvoid *data, enum tex_mode mode, 5712bf215546Sopenharmony_ci const char *caller) 5713bf215546Sopenharmony_ci{ 5714bf215546Sopenharmony_ci struct gl_texture_object *texObj = NULL; 5715bf215546Sopenharmony_ci struct gl_texture_image *texImage; 5716bf215546Sopenharmony_ci bool no_error = false; 5717bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 5718bf215546Sopenharmony_ci 5719bf215546Sopenharmony_ci switch (mode) { 5720bf215546Sopenharmony_ci case TEX_MODE_DSA_ERROR: 5721bf215546Sopenharmony_ci assert(target == 0); 5722bf215546Sopenharmony_ci texObj = _mesa_lookup_texture_err(ctx, textureOrIndex, caller); 5723bf215546Sopenharmony_ci if (texObj) 5724bf215546Sopenharmony_ci target = texObj->Target; 5725bf215546Sopenharmony_ci break; 5726bf215546Sopenharmony_ci case TEX_MODE_DSA_NO_ERROR: 5727bf215546Sopenharmony_ci assert(target == 0); 5728bf215546Sopenharmony_ci texObj = _mesa_lookup_texture(ctx, textureOrIndex); 5729bf215546Sopenharmony_ci if (texObj) 5730bf215546Sopenharmony_ci target = texObj->Target; 5731bf215546Sopenharmony_ci no_error = true; 5732bf215546Sopenharmony_ci break; 5733bf215546Sopenharmony_ci case TEX_MODE_EXT_DSA_TEXTURE: 5734bf215546Sopenharmony_ci texObj = _mesa_lookup_or_create_texture(ctx, target, textureOrIndex, 5735bf215546Sopenharmony_ci false, true, caller); 5736bf215546Sopenharmony_ci break; 5737bf215546Sopenharmony_ci case TEX_MODE_EXT_DSA_TEXUNIT: 5738bf215546Sopenharmony_ci texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, 5739bf215546Sopenharmony_ci textureOrIndex, 5740bf215546Sopenharmony_ci false, 5741bf215546Sopenharmony_ci caller); 5742bf215546Sopenharmony_ci break; 5743bf215546Sopenharmony_ci case TEX_MODE_CURRENT_NO_ERROR: 5744bf215546Sopenharmony_ci no_error = true; 5745bf215546Sopenharmony_ci FALLTHROUGH; 5746bf215546Sopenharmony_ci case TEX_MODE_CURRENT_ERROR: 5747bf215546Sopenharmony_ci default: 5748bf215546Sopenharmony_ci assert(textureOrIndex == 0); 5749bf215546Sopenharmony_ci break; 5750bf215546Sopenharmony_ci } 5751bf215546Sopenharmony_ci 5752bf215546Sopenharmony_ci if (!no_error && 5753bf215546Sopenharmony_ci compressed_subtexture_target_check(ctx, target, dim, format, 5754bf215546Sopenharmony_ci mode == TEX_MODE_DSA_ERROR, 5755bf215546Sopenharmony_ci caller)) { 5756bf215546Sopenharmony_ci return; 5757bf215546Sopenharmony_ci } 5758bf215546Sopenharmony_ci 5759bf215546Sopenharmony_ci if (mode == TEX_MODE_CURRENT_NO_ERROR || 5760bf215546Sopenharmony_ci mode == TEX_MODE_CURRENT_ERROR) { 5761bf215546Sopenharmony_ci texObj = _mesa_get_current_tex_object(ctx, target); 5762bf215546Sopenharmony_ci } 5763bf215546Sopenharmony_ci 5764bf215546Sopenharmony_ci if (!texObj) 5765bf215546Sopenharmony_ci return; 5766bf215546Sopenharmony_ci 5767bf215546Sopenharmony_ci if (!no_error && 5768bf215546Sopenharmony_ci compressed_subtexture_error_check(ctx, dim, texObj, target, level, 5769bf215546Sopenharmony_ci xoffset, yoffset, zoffset, width, 5770bf215546Sopenharmony_ci height, depth, format, 5771bf215546Sopenharmony_ci imageSize, data, caller)) { 5772bf215546Sopenharmony_ci return; 5773bf215546Sopenharmony_ci } 5774bf215546Sopenharmony_ci 5775bf215546Sopenharmony_ci /* Must handle special case GL_TEXTURE_CUBE_MAP. */ 5776bf215546Sopenharmony_ci if (dim == 3 && 5777bf215546Sopenharmony_ci (mode == TEX_MODE_DSA_ERROR || mode == TEX_MODE_DSA_NO_ERROR) && 5778bf215546Sopenharmony_ci texObj->Target == GL_TEXTURE_CUBE_MAP) { 5779bf215546Sopenharmony_ci const char *pixels = data; 5780bf215546Sopenharmony_ci GLint image_stride; 5781bf215546Sopenharmony_ci 5782bf215546Sopenharmony_ci /* Make sure the texture object is a proper cube. 5783bf215546Sopenharmony_ci * (See texturesubimage in teximage.c for details on why this check is 5784bf215546Sopenharmony_ci * performed.) 5785bf215546Sopenharmony_ci */ 5786bf215546Sopenharmony_ci if (!no_error && !_mesa_cube_level_complete(texObj, level)) { 5787bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 5788bf215546Sopenharmony_ci "glCompressedTextureSubImage3D(cube map incomplete)"); 5789bf215546Sopenharmony_ci return; 5790bf215546Sopenharmony_ci } 5791bf215546Sopenharmony_ci 5792bf215546Sopenharmony_ci /* Copy in each face. */ 5793bf215546Sopenharmony_ci for (int i = zoffset; i < zoffset + depth; ++i) { 5794bf215546Sopenharmony_ci texImage = texObj->Image[i][level]; 5795bf215546Sopenharmony_ci assert(texImage); 5796bf215546Sopenharmony_ci 5797bf215546Sopenharmony_ci compressed_texture_sub_image(ctx, 3, texObj, texImage, 5798bf215546Sopenharmony_ci texObj->Target, level, xoffset, yoffset, 5799bf215546Sopenharmony_ci 0, width, height, 1, format, 5800bf215546Sopenharmony_ci imageSize, pixels); 5801bf215546Sopenharmony_ci 5802bf215546Sopenharmony_ci /* Compressed images don't have a client format */ 5803bf215546Sopenharmony_ci image_stride = _mesa_format_image_size(texImage->TexFormat, 5804bf215546Sopenharmony_ci texImage->Width, 5805bf215546Sopenharmony_ci texImage->Height, 1); 5806bf215546Sopenharmony_ci 5807bf215546Sopenharmony_ci pixels += image_stride; 5808bf215546Sopenharmony_ci imageSize -= image_stride; 5809bf215546Sopenharmony_ci } 5810bf215546Sopenharmony_ci } else { 5811bf215546Sopenharmony_ci texImage = _mesa_select_tex_image(texObj, target, level); 5812bf215546Sopenharmony_ci assert(texImage); 5813bf215546Sopenharmony_ci 5814bf215546Sopenharmony_ci compressed_texture_sub_image(ctx, dim, texObj, texImage, target, level, 5815bf215546Sopenharmony_ci xoffset, yoffset, zoffset, width, height, 5816bf215546Sopenharmony_ci depth, format, imageSize, data); 5817bf215546Sopenharmony_ci } 5818bf215546Sopenharmony_ci} 5819bf215546Sopenharmony_ci 5820bf215546Sopenharmony_ci 5821bf215546Sopenharmony_civoid GLAPIENTRY 5822bf215546Sopenharmony_ci_mesa_CompressedTexSubImage1D_no_error(GLenum target, GLint level, 5823bf215546Sopenharmony_ci GLint xoffset, GLsizei width, 5824bf215546Sopenharmony_ci GLenum format, GLsizei imageSize, 5825bf215546Sopenharmony_ci const GLvoid *data) 5826bf215546Sopenharmony_ci{ 5827bf215546Sopenharmony_ci compressed_tex_sub_image(1, target, 0, 5828bf215546Sopenharmony_ci level, xoffset, 0, 0, width, 5829bf215546Sopenharmony_ci 1, 1, format, imageSize, data, 5830bf215546Sopenharmony_ci TEX_MODE_CURRENT_NO_ERROR, 5831bf215546Sopenharmony_ci "glCompressedTexSubImage1D"); 5832bf215546Sopenharmony_ci} 5833bf215546Sopenharmony_ci 5834bf215546Sopenharmony_ci 5835bf215546Sopenharmony_civoid GLAPIENTRY 5836bf215546Sopenharmony_ci_mesa_CompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, 5837bf215546Sopenharmony_ci GLsizei width, GLenum format, 5838bf215546Sopenharmony_ci GLsizei imageSize, const GLvoid *data) 5839bf215546Sopenharmony_ci{ 5840bf215546Sopenharmony_ci compressed_tex_sub_image(1, target, 0, 5841bf215546Sopenharmony_ci level, xoffset, 0, 0, width, 5842bf215546Sopenharmony_ci 1, 1, format, imageSize, data, 5843bf215546Sopenharmony_ci TEX_MODE_CURRENT_ERROR, 5844bf215546Sopenharmony_ci "glCompressedTexSubImage1D"); 5845bf215546Sopenharmony_ci} 5846bf215546Sopenharmony_ci 5847bf215546Sopenharmony_ci 5848bf215546Sopenharmony_civoid GLAPIENTRY 5849bf215546Sopenharmony_ci_mesa_CompressedTextureSubImage1D_no_error(GLuint texture, GLint level, 5850bf215546Sopenharmony_ci GLint xoffset, GLsizei width, 5851bf215546Sopenharmony_ci GLenum format, GLsizei imageSize, 5852bf215546Sopenharmony_ci const GLvoid *data) 5853bf215546Sopenharmony_ci{ 5854bf215546Sopenharmony_ci compressed_tex_sub_image(1, 0, texture, 5855bf215546Sopenharmony_ci level, xoffset, 0, 0, 5856bf215546Sopenharmony_ci width, 1, 1, format, imageSize, data, 5857bf215546Sopenharmony_ci TEX_MODE_DSA_NO_ERROR, 5858bf215546Sopenharmony_ci "glCompressedTextureSubImage1D"); 5859bf215546Sopenharmony_ci} 5860bf215546Sopenharmony_ci 5861bf215546Sopenharmony_ci 5862bf215546Sopenharmony_civoid GLAPIENTRY 5863bf215546Sopenharmony_ci_mesa_CompressedTextureSubImage1D(GLuint texture, GLint level, GLint xoffset, 5864bf215546Sopenharmony_ci GLsizei width, GLenum format, 5865bf215546Sopenharmony_ci GLsizei imageSize, const GLvoid *data) 5866bf215546Sopenharmony_ci{ 5867bf215546Sopenharmony_ci compressed_tex_sub_image(1, 0, texture, 5868bf215546Sopenharmony_ci level, xoffset, 0, 0, 5869bf215546Sopenharmony_ci width, 1, 1, format, imageSize, data, 5870bf215546Sopenharmony_ci TEX_MODE_DSA_ERROR, 5871bf215546Sopenharmony_ci "glCompressedTextureSubImage1D"); 5872bf215546Sopenharmony_ci} 5873bf215546Sopenharmony_ci 5874bf215546Sopenharmony_ci 5875bf215546Sopenharmony_civoid GLAPIENTRY 5876bf215546Sopenharmony_ci_mesa_CompressedTextureSubImage1DEXT(GLuint texture, GLenum target, 5877bf215546Sopenharmony_ci GLint level, GLint xoffset, 5878bf215546Sopenharmony_ci GLsizei width, GLenum format, 5879bf215546Sopenharmony_ci GLsizei imageSize, const GLvoid *data) 5880bf215546Sopenharmony_ci{ 5881bf215546Sopenharmony_ci compressed_tex_sub_image(1, target, texture, level, xoffset, 0, 5882bf215546Sopenharmony_ci 0, width, 1, 1, format, imageSize, 5883bf215546Sopenharmony_ci data, 5884bf215546Sopenharmony_ci TEX_MODE_EXT_DSA_TEXTURE, 5885bf215546Sopenharmony_ci "glCompressedTextureSubImage1DEXT"); 5886bf215546Sopenharmony_ci} 5887bf215546Sopenharmony_ci 5888bf215546Sopenharmony_ci 5889bf215546Sopenharmony_civoid GLAPIENTRY 5890bf215546Sopenharmony_ci_mesa_CompressedMultiTexSubImage1DEXT(GLenum texunit, GLenum target, 5891bf215546Sopenharmony_ci GLint level, GLint xoffset, 5892bf215546Sopenharmony_ci GLsizei width, GLenum format, 5893bf215546Sopenharmony_ci GLsizei imageSize, const GLvoid *data) 5894bf215546Sopenharmony_ci{ 5895bf215546Sopenharmony_ci compressed_tex_sub_image(1, target, texunit - GL_TEXTURE0, level, 5896bf215546Sopenharmony_ci xoffset, 0, 0, width, 1, 1, format, imageSize, 5897bf215546Sopenharmony_ci data, 5898bf215546Sopenharmony_ci TEX_MODE_EXT_DSA_TEXUNIT, 5899bf215546Sopenharmony_ci "glCompressedMultiTexSubImage1DEXT"); 5900bf215546Sopenharmony_ci} 5901bf215546Sopenharmony_ci 5902bf215546Sopenharmony_ci 5903bf215546Sopenharmony_civoid GLAPIENTRY 5904bf215546Sopenharmony_ci_mesa_CompressedTexSubImage2D_no_error(GLenum target, GLint level, 5905bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, 5906bf215546Sopenharmony_ci GLsizei width, GLsizei height, 5907bf215546Sopenharmony_ci GLenum format, GLsizei imageSize, 5908bf215546Sopenharmony_ci const GLvoid *data) 5909bf215546Sopenharmony_ci{ 5910bf215546Sopenharmony_ci compressed_tex_sub_image(2, target, 0, level, 5911bf215546Sopenharmony_ci xoffset, yoffset, 0, 5912bf215546Sopenharmony_ci width, height, 1, format, imageSize, data, 5913bf215546Sopenharmony_ci TEX_MODE_CURRENT_NO_ERROR, 5914bf215546Sopenharmony_ci "glCompressedTexSubImage2D"); 5915bf215546Sopenharmony_ci} 5916bf215546Sopenharmony_ci 5917bf215546Sopenharmony_ci 5918bf215546Sopenharmony_civoid GLAPIENTRY 5919bf215546Sopenharmony_ci_mesa_CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, 5920bf215546Sopenharmony_ci GLint yoffset, GLsizei width, GLsizei height, 5921bf215546Sopenharmony_ci GLenum format, GLsizei imageSize, 5922bf215546Sopenharmony_ci const GLvoid *data) 5923bf215546Sopenharmony_ci{ 5924bf215546Sopenharmony_ci compressed_tex_sub_image(2, target, 0, level, 5925bf215546Sopenharmony_ci xoffset, yoffset, 0, 5926bf215546Sopenharmony_ci width, height, 1, format, imageSize, data, 5927bf215546Sopenharmony_ci TEX_MODE_CURRENT_ERROR, 5928bf215546Sopenharmony_ci "glCompressedTexSubImage2D"); 5929bf215546Sopenharmony_ci} 5930bf215546Sopenharmony_ci 5931bf215546Sopenharmony_ci 5932bf215546Sopenharmony_civoid GLAPIENTRY 5933bf215546Sopenharmony_ci_mesa_CompressedTextureSubImage2DEXT(GLuint texture, GLenum target, 5934bf215546Sopenharmony_ci GLint level, GLint xoffset, 5935bf215546Sopenharmony_ci GLint yoffset, GLsizei width, 5936bf215546Sopenharmony_ci GLsizei height, GLenum format, 5937bf215546Sopenharmony_ci GLsizei imageSize, const GLvoid *data) 5938bf215546Sopenharmony_ci{ 5939bf215546Sopenharmony_ci compressed_tex_sub_image(2, target, texture, level, xoffset, 5940bf215546Sopenharmony_ci yoffset, 0, width, height, 1, format, 5941bf215546Sopenharmony_ci imageSize, data, 5942bf215546Sopenharmony_ci TEX_MODE_EXT_DSA_TEXTURE, 5943bf215546Sopenharmony_ci "glCompressedTextureSubImage2DEXT"); 5944bf215546Sopenharmony_ci} 5945bf215546Sopenharmony_ci 5946bf215546Sopenharmony_ci 5947bf215546Sopenharmony_civoid GLAPIENTRY 5948bf215546Sopenharmony_ci_mesa_CompressedMultiTexSubImage2DEXT(GLenum texunit, GLenum target, 5949bf215546Sopenharmony_ci GLint level, GLint xoffset, GLint yoffset, 5950bf215546Sopenharmony_ci GLsizei width, GLsizei height, GLenum format, 5951bf215546Sopenharmony_ci GLsizei imageSize, const GLvoid *data) 5952bf215546Sopenharmony_ci{ 5953bf215546Sopenharmony_ci compressed_tex_sub_image(2, target, texunit - GL_TEXTURE0, level, 5954bf215546Sopenharmony_ci xoffset, yoffset, 0, width, height, 1, format, 5955bf215546Sopenharmony_ci imageSize, data, 5956bf215546Sopenharmony_ci TEX_MODE_EXT_DSA_TEXUNIT, 5957bf215546Sopenharmony_ci "glCompressedMultiTexSubImage2DEXT"); 5958bf215546Sopenharmony_ci} 5959bf215546Sopenharmony_ci 5960bf215546Sopenharmony_ci 5961bf215546Sopenharmony_civoid GLAPIENTRY 5962bf215546Sopenharmony_ci_mesa_CompressedTextureSubImage2D_no_error(GLuint texture, GLint level, 5963bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, 5964bf215546Sopenharmony_ci GLsizei width, GLsizei height, 5965bf215546Sopenharmony_ci GLenum format, GLsizei imageSize, 5966bf215546Sopenharmony_ci const GLvoid *data) 5967bf215546Sopenharmony_ci{ 5968bf215546Sopenharmony_ci compressed_tex_sub_image(2, 0, texture, level, xoffset, yoffset, 0, 5969bf215546Sopenharmony_ci width, height, 1, format, imageSize, data, 5970bf215546Sopenharmony_ci TEX_MODE_DSA_NO_ERROR, 5971bf215546Sopenharmony_ci "glCompressedTextureSubImage2D"); 5972bf215546Sopenharmony_ci} 5973bf215546Sopenharmony_ci 5974bf215546Sopenharmony_ci 5975bf215546Sopenharmony_civoid GLAPIENTRY 5976bf215546Sopenharmony_ci_mesa_CompressedTextureSubImage2D(GLuint texture, GLint level, GLint xoffset, 5977bf215546Sopenharmony_ci GLint yoffset, 5978bf215546Sopenharmony_ci GLsizei width, GLsizei height, 5979bf215546Sopenharmony_ci GLenum format, GLsizei imageSize, 5980bf215546Sopenharmony_ci const GLvoid *data) 5981bf215546Sopenharmony_ci{ 5982bf215546Sopenharmony_ci compressed_tex_sub_image(2, 0, texture, level, xoffset, yoffset, 0, 5983bf215546Sopenharmony_ci width, height, 1, format, imageSize, data, 5984bf215546Sopenharmony_ci TEX_MODE_DSA_ERROR, 5985bf215546Sopenharmony_ci "glCompressedTextureSubImage2D"); 5986bf215546Sopenharmony_ci} 5987bf215546Sopenharmony_ci 5988bf215546Sopenharmony_civoid GLAPIENTRY 5989bf215546Sopenharmony_ci_mesa_CompressedTexSubImage3D_no_error(GLenum target, GLint level, 5990bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, 5991bf215546Sopenharmony_ci GLint zoffset, GLsizei width, 5992bf215546Sopenharmony_ci GLsizei height, GLsizei depth, 5993bf215546Sopenharmony_ci GLenum format, GLsizei imageSize, 5994bf215546Sopenharmony_ci const GLvoid *data) 5995bf215546Sopenharmony_ci{ 5996bf215546Sopenharmony_ci compressed_tex_sub_image(3, target, 0, level, xoffset, yoffset, 5997bf215546Sopenharmony_ci zoffset, width, height, depth, format, 5998bf215546Sopenharmony_ci imageSize, data, 5999bf215546Sopenharmony_ci TEX_MODE_CURRENT_NO_ERROR, 6000bf215546Sopenharmony_ci "glCompressedTexSubImage3D"); 6001bf215546Sopenharmony_ci} 6002bf215546Sopenharmony_ci 6003bf215546Sopenharmony_civoid GLAPIENTRY 6004bf215546Sopenharmony_ci_mesa_CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, 6005bf215546Sopenharmony_ci GLint yoffset, GLint zoffset, GLsizei width, 6006bf215546Sopenharmony_ci GLsizei height, GLsizei depth, GLenum format, 6007bf215546Sopenharmony_ci GLsizei imageSize, const GLvoid *data) 6008bf215546Sopenharmony_ci{ 6009bf215546Sopenharmony_ci compressed_tex_sub_image(3, target, 0, level, xoffset, yoffset, 6010bf215546Sopenharmony_ci zoffset, width, height, depth, format, 6011bf215546Sopenharmony_ci imageSize, data, 6012bf215546Sopenharmony_ci TEX_MODE_CURRENT_ERROR, 6013bf215546Sopenharmony_ci "glCompressedTexSubImage3D"); 6014bf215546Sopenharmony_ci} 6015bf215546Sopenharmony_ci 6016bf215546Sopenharmony_civoid GLAPIENTRY 6017bf215546Sopenharmony_ci_mesa_CompressedTextureSubImage3D_no_error(GLuint texture, GLint level, 6018bf215546Sopenharmony_ci GLint xoffset, GLint yoffset, 6019bf215546Sopenharmony_ci GLint zoffset, GLsizei width, 6020bf215546Sopenharmony_ci GLsizei height, GLsizei depth, 6021bf215546Sopenharmony_ci GLenum format, GLsizei imageSize, 6022bf215546Sopenharmony_ci const GLvoid *data) 6023bf215546Sopenharmony_ci{ 6024bf215546Sopenharmony_ci compressed_tex_sub_image(3, 0, texture, level, xoffset, yoffset, 6025bf215546Sopenharmony_ci zoffset, width, height, depth, format, 6026bf215546Sopenharmony_ci imageSize, data, 6027bf215546Sopenharmony_ci TEX_MODE_DSA_NO_ERROR, 6028bf215546Sopenharmony_ci "glCompressedTextureSubImage3D"); 6029bf215546Sopenharmony_ci} 6030bf215546Sopenharmony_ci 6031bf215546Sopenharmony_civoid GLAPIENTRY 6032bf215546Sopenharmony_ci_mesa_CompressedTextureSubImage3D(GLuint texture, GLint level, GLint xoffset, 6033bf215546Sopenharmony_ci GLint yoffset, GLint zoffset, GLsizei width, 6034bf215546Sopenharmony_ci GLsizei height, GLsizei depth, 6035bf215546Sopenharmony_ci GLenum format, GLsizei imageSize, 6036bf215546Sopenharmony_ci const GLvoid *data) 6037bf215546Sopenharmony_ci{ 6038bf215546Sopenharmony_ci compressed_tex_sub_image(3, 0, texture, level, xoffset, yoffset, 6039bf215546Sopenharmony_ci zoffset, width, height, depth, format, 6040bf215546Sopenharmony_ci imageSize, data, 6041bf215546Sopenharmony_ci TEX_MODE_DSA_ERROR, 6042bf215546Sopenharmony_ci "glCompressedTextureSubImage3D"); 6043bf215546Sopenharmony_ci} 6044bf215546Sopenharmony_ci 6045bf215546Sopenharmony_ci 6046bf215546Sopenharmony_civoid GLAPIENTRY 6047bf215546Sopenharmony_ci_mesa_CompressedTextureSubImage3DEXT(GLuint texture, GLenum target, 6048bf215546Sopenharmony_ci GLint level, GLint xoffset, 6049bf215546Sopenharmony_ci GLint yoffset, GLint zoffset, 6050bf215546Sopenharmony_ci GLsizei width, GLsizei height, 6051bf215546Sopenharmony_ci GLsizei depth, GLenum format, 6052bf215546Sopenharmony_ci GLsizei imageSize, const GLvoid *data) 6053bf215546Sopenharmony_ci{ 6054bf215546Sopenharmony_ci compressed_tex_sub_image(3, target, texture, level, xoffset, yoffset, 6055bf215546Sopenharmony_ci zoffset, width, height, depth, format, 6056bf215546Sopenharmony_ci imageSize, data, 6057bf215546Sopenharmony_ci TEX_MODE_EXT_DSA_TEXTURE, 6058bf215546Sopenharmony_ci "glCompressedTextureSubImage3DEXT"); 6059bf215546Sopenharmony_ci} 6060bf215546Sopenharmony_ci 6061bf215546Sopenharmony_ci 6062bf215546Sopenharmony_civoid GLAPIENTRY 6063bf215546Sopenharmony_ci_mesa_CompressedMultiTexSubImage3DEXT(GLenum texunit, GLenum target, 6064bf215546Sopenharmony_ci GLint level, GLint xoffset, GLint yoffset, 6065bf215546Sopenharmony_ci GLint zoffset, GLsizei width, GLsizei height, 6066bf215546Sopenharmony_ci GLsizei depth, GLenum format, 6067bf215546Sopenharmony_ci GLsizei imageSize, const GLvoid *data) 6068bf215546Sopenharmony_ci{ 6069bf215546Sopenharmony_ci compressed_tex_sub_image(3, target, texunit - GL_TEXTURE0, level, 6070bf215546Sopenharmony_ci xoffset, yoffset, zoffset, width, height, depth, 6071bf215546Sopenharmony_ci format, imageSize, data, 6072bf215546Sopenharmony_ci TEX_MODE_EXT_DSA_TEXUNIT, 6073bf215546Sopenharmony_ci "glCompressedMultiTexSubImage3DEXT"); 6074bf215546Sopenharmony_ci} 6075bf215546Sopenharmony_ci 6076bf215546Sopenharmony_ci 6077bf215546Sopenharmony_cimesa_format 6078bf215546Sopenharmony_ci_mesa_get_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat) 6079bf215546Sopenharmony_ci{ 6080bf215546Sopenharmony_ci if (ctx->API == API_OPENGL_COMPAT) { 6081bf215546Sopenharmony_ci switch (internalFormat) { 6082bf215546Sopenharmony_ci case GL_ALPHA8: 6083bf215546Sopenharmony_ci return MESA_FORMAT_A_UNORM8; 6084bf215546Sopenharmony_ci case GL_ALPHA16: 6085bf215546Sopenharmony_ci return MESA_FORMAT_A_UNORM16; 6086bf215546Sopenharmony_ci case GL_ALPHA16F_ARB: 6087bf215546Sopenharmony_ci return MESA_FORMAT_A_FLOAT16; 6088bf215546Sopenharmony_ci case GL_ALPHA32F_ARB: 6089bf215546Sopenharmony_ci return MESA_FORMAT_A_FLOAT32; 6090bf215546Sopenharmony_ci case GL_ALPHA8I_EXT: 6091bf215546Sopenharmony_ci return MESA_FORMAT_A_SINT8; 6092bf215546Sopenharmony_ci case GL_ALPHA16I_EXT: 6093bf215546Sopenharmony_ci return MESA_FORMAT_A_SINT16; 6094bf215546Sopenharmony_ci case GL_ALPHA32I_EXT: 6095bf215546Sopenharmony_ci return MESA_FORMAT_A_SINT32; 6096bf215546Sopenharmony_ci case GL_ALPHA8UI_EXT: 6097bf215546Sopenharmony_ci return MESA_FORMAT_A_UINT8; 6098bf215546Sopenharmony_ci case GL_ALPHA16UI_EXT: 6099bf215546Sopenharmony_ci return MESA_FORMAT_A_UINT16; 6100bf215546Sopenharmony_ci case GL_ALPHA32UI_EXT: 6101bf215546Sopenharmony_ci return MESA_FORMAT_A_UINT32; 6102bf215546Sopenharmony_ci case GL_LUMINANCE8: 6103bf215546Sopenharmony_ci return MESA_FORMAT_L_UNORM8; 6104bf215546Sopenharmony_ci case GL_LUMINANCE16: 6105bf215546Sopenharmony_ci return MESA_FORMAT_L_UNORM16; 6106bf215546Sopenharmony_ci case GL_LUMINANCE16F_ARB: 6107bf215546Sopenharmony_ci return MESA_FORMAT_L_FLOAT16; 6108bf215546Sopenharmony_ci case GL_LUMINANCE32F_ARB: 6109bf215546Sopenharmony_ci return MESA_FORMAT_L_FLOAT32; 6110bf215546Sopenharmony_ci case GL_LUMINANCE8I_EXT: 6111bf215546Sopenharmony_ci return MESA_FORMAT_L_SINT8; 6112bf215546Sopenharmony_ci case GL_LUMINANCE16I_EXT: 6113bf215546Sopenharmony_ci return MESA_FORMAT_L_SINT16; 6114bf215546Sopenharmony_ci case GL_LUMINANCE32I_EXT: 6115bf215546Sopenharmony_ci return MESA_FORMAT_L_SINT32; 6116bf215546Sopenharmony_ci case GL_LUMINANCE8UI_EXT: 6117bf215546Sopenharmony_ci return MESA_FORMAT_L_UINT8; 6118bf215546Sopenharmony_ci case GL_LUMINANCE16UI_EXT: 6119bf215546Sopenharmony_ci return MESA_FORMAT_L_UINT16; 6120bf215546Sopenharmony_ci case GL_LUMINANCE32UI_EXT: 6121bf215546Sopenharmony_ci return MESA_FORMAT_L_UINT32; 6122bf215546Sopenharmony_ci case GL_LUMINANCE8_ALPHA8: 6123bf215546Sopenharmony_ci return MESA_FORMAT_LA_UNORM8; 6124bf215546Sopenharmony_ci case GL_LUMINANCE16_ALPHA16: 6125bf215546Sopenharmony_ci return MESA_FORMAT_LA_UNORM16; 6126bf215546Sopenharmony_ci case GL_LUMINANCE_ALPHA16F_ARB: 6127bf215546Sopenharmony_ci return MESA_FORMAT_LA_FLOAT16; 6128bf215546Sopenharmony_ci case GL_LUMINANCE_ALPHA32F_ARB: 6129bf215546Sopenharmony_ci return MESA_FORMAT_LA_FLOAT32; 6130bf215546Sopenharmony_ci case GL_LUMINANCE_ALPHA8I_EXT: 6131bf215546Sopenharmony_ci return MESA_FORMAT_LA_SINT8; 6132bf215546Sopenharmony_ci case GL_LUMINANCE_ALPHA16I_EXT: 6133bf215546Sopenharmony_ci return MESA_FORMAT_LA_SINT16; 6134bf215546Sopenharmony_ci case GL_LUMINANCE_ALPHA32I_EXT: 6135bf215546Sopenharmony_ci return MESA_FORMAT_LA_SINT32; 6136bf215546Sopenharmony_ci case GL_LUMINANCE_ALPHA8UI_EXT: 6137bf215546Sopenharmony_ci return MESA_FORMAT_LA_UINT8; 6138bf215546Sopenharmony_ci case GL_LUMINANCE_ALPHA16UI_EXT: 6139bf215546Sopenharmony_ci return MESA_FORMAT_LA_UINT16; 6140bf215546Sopenharmony_ci case GL_LUMINANCE_ALPHA32UI_EXT: 6141bf215546Sopenharmony_ci return MESA_FORMAT_LA_UINT32; 6142bf215546Sopenharmony_ci case GL_INTENSITY8: 6143bf215546Sopenharmony_ci return MESA_FORMAT_I_UNORM8; 6144bf215546Sopenharmony_ci case GL_INTENSITY16: 6145bf215546Sopenharmony_ci return MESA_FORMAT_I_UNORM16; 6146bf215546Sopenharmony_ci case GL_INTENSITY16F_ARB: 6147bf215546Sopenharmony_ci return MESA_FORMAT_I_FLOAT16; 6148bf215546Sopenharmony_ci case GL_INTENSITY32F_ARB: 6149bf215546Sopenharmony_ci return MESA_FORMAT_I_FLOAT32; 6150bf215546Sopenharmony_ci case GL_INTENSITY8I_EXT: 6151bf215546Sopenharmony_ci return MESA_FORMAT_I_SINT8; 6152bf215546Sopenharmony_ci case GL_INTENSITY16I_EXT: 6153bf215546Sopenharmony_ci return MESA_FORMAT_I_SINT16; 6154bf215546Sopenharmony_ci case GL_INTENSITY32I_EXT: 6155bf215546Sopenharmony_ci return MESA_FORMAT_I_SINT32; 6156bf215546Sopenharmony_ci case GL_INTENSITY8UI_EXT: 6157bf215546Sopenharmony_ci return MESA_FORMAT_I_UINT8; 6158bf215546Sopenharmony_ci case GL_INTENSITY16UI_EXT: 6159bf215546Sopenharmony_ci return MESA_FORMAT_I_UINT16; 6160bf215546Sopenharmony_ci case GL_INTENSITY32UI_EXT: 6161bf215546Sopenharmony_ci return MESA_FORMAT_I_UINT32; 6162bf215546Sopenharmony_ci default: 6163bf215546Sopenharmony_ci break; 6164bf215546Sopenharmony_ci } 6165bf215546Sopenharmony_ci } 6166bf215546Sopenharmony_ci 6167bf215546Sopenharmony_ci if (_mesa_has_ARB_texture_buffer_object_rgb32(ctx) || 6168bf215546Sopenharmony_ci _mesa_has_OES_texture_buffer(ctx)) { 6169bf215546Sopenharmony_ci switch (internalFormat) { 6170bf215546Sopenharmony_ci case GL_RGB32F: 6171bf215546Sopenharmony_ci return MESA_FORMAT_RGB_FLOAT32; 6172bf215546Sopenharmony_ci case GL_RGB32UI: 6173bf215546Sopenharmony_ci return MESA_FORMAT_RGB_UINT32; 6174bf215546Sopenharmony_ci case GL_RGB32I: 6175bf215546Sopenharmony_ci return MESA_FORMAT_RGB_SINT32; 6176bf215546Sopenharmony_ci default: 6177bf215546Sopenharmony_ci break; 6178bf215546Sopenharmony_ci } 6179bf215546Sopenharmony_ci } 6180bf215546Sopenharmony_ci 6181bf215546Sopenharmony_ci switch (internalFormat) { 6182bf215546Sopenharmony_ci case GL_RGBA8: 6183bf215546Sopenharmony_ci return MESA_FORMAT_R8G8B8A8_UNORM; 6184bf215546Sopenharmony_ci case GL_RGBA16: 6185bf215546Sopenharmony_ci if (_mesa_is_gles(ctx) && !_mesa_has_EXT_texture_norm16(ctx)) 6186bf215546Sopenharmony_ci return MESA_FORMAT_NONE; 6187bf215546Sopenharmony_ci return MESA_FORMAT_RGBA_UNORM16; 6188bf215546Sopenharmony_ci case GL_RGBA16F_ARB: 6189bf215546Sopenharmony_ci return MESA_FORMAT_RGBA_FLOAT16; 6190bf215546Sopenharmony_ci case GL_RGBA32F_ARB: 6191bf215546Sopenharmony_ci return MESA_FORMAT_RGBA_FLOAT32; 6192bf215546Sopenharmony_ci case GL_RGBA8I_EXT: 6193bf215546Sopenharmony_ci return MESA_FORMAT_RGBA_SINT8; 6194bf215546Sopenharmony_ci case GL_RGBA16I_EXT: 6195bf215546Sopenharmony_ci return MESA_FORMAT_RGBA_SINT16; 6196bf215546Sopenharmony_ci case GL_RGBA32I_EXT: 6197bf215546Sopenharmony_ci return MESA_FORMAT_RGBA_SINT32; 6198bf215546Sopenharmony_ci case GL_RGBA8UI_EXT: 6199bf215546Sopenharmony_ci return MESA_FORMAT_RGBA_UINT8; 6200bf215546Sopenharmony_ci case GL_RGBA16UI_EXT: 6201bf215546Sopenharmony_ci return MESA_FORMAT_RGBA_UINT16; 6202bf215546Sopenharmony_ci case GL_RGBA32UI_EXT: 6203bf215546Sopenharmony_ci return MESA_FORMAT_RGBA_UINT32; 6204bf215546Sopenharmony_ci 6205bf215546Sopenharmony_ci case GL_RG8: 6206bf215546Sopenharmony_ci return MESA_FORMAT_RG_UNORM8; 6207bf215546Sopenharmony_ci case GL_RG16: 6208bf215546Sopenharmony_ci if (_mesa_is_gles(ctx) && !_mesa_has_EXT_texture_norm16(ctx)) 6209bf215546Sopenharmony_ci return MESA_FORMAT_NONE; 6210bf215546Sopenharmony_ci return MESA_FORMAT_RG_UNORM16; 6211bf215546Sopenharmony_ci case GL_RG16F: 6212bf215546Sopenharmony_ci return MESA_FORMAT_RG_FLOAT16; 6213bf215546Sopenharmony_ci case GL_RG32F: 6214bf215546Sopenharmony_ci return MESA_FORMAT_RG_FLOAT32; 6215bf215546Sopenharmony_ci case GL_RG8I: 6216bf215546Sopenharmony_ci return MESA_FORMAT_RG_SINT8; 6217bf215546Sopenharmony_ci case GL_RG16I: 6218bf215546Sopenharmony_ci return MESA_FORMAT_RG_SINT16; 6219bf215546Sopenharmony_ci case GL_RG32I: 6220bf215546Sopenharmony_ci return MESA_FORMAT_RG_SINT32; 6221bf215546Sopenharmony_ci case GL_RG8UI: 6222bf215546Sopenharmony_ci return MESA_FORMAT_RG_UINT8; 6223bf215546Sopenharmony_ci case GL_RG16UI: 6224bf215546Sopenharmony_ci return MESA_FORMAT_RG_UINT16; 6225bf215546Sopenharmony_ci case GL_RG32UI: 6226bf215546Sopenharmony_ci return MESA_FORMAT_RG_UINT32; 6227bf215546Sopenharmony_ci 6228bf215546Sopenharmony_ci case GL_R8: 6229bf215546Sopenharmony_ci return MESA_FORMAT_R_UNORM8; 6230bf215546Sopenharmony_ci case GL_R16: 6231bf215546Sopenharmony_ci if (_mesa_is_gles(ctx) && !_mesa_has_EXT_texture_norm16(ctx)) 6232bf215546Sopenharmony_ci return MESA_FORMAT_NONE; 6233bf215546Sopenharmony_ci return MESA_FORMAT_R_UNORM16; 6234bf215546Sopenharmony_ci case GL_R16F: 6235bf215546Sopenharmony_ci return MESA_FORMAT_R_FLOAT16; 6236bf215546Sopenharmony_ci case GL_R32F: 6237bf215546Sopenharmony_ci return MESA_FORMAT_R_FLOAT32; 6238bf215546Sopenharmony_ci case GL_R8I: 6239bf215546Sopenharmony_ci return MESA_FORMAT_R_SINT8; 6240bf215546Sopenharmony_ci case GL_R16I: 6241bf215546Sopenharmony_ci return MESA_FORMAT_R_SINT16; 6242bf215546Sopenharmony_ci case GL_R32I: 6243bf215546Sopenharmony_ci return MESA_FORMAT_R_SINT32; 6244bf215546Sopenharmony_ci case GL_R8UI: 6245bf215546Sopenharmony_ci return MESA_FORMAT_R_UINT8; 6246bf215546Sopenharmony_ci case GL_R16UI: 6247bf215546Sopenharmony_ci return MESA_FORMAT_R_UINT16; 6248bf215546Sopenharmony_ci case GL_R32UI: 6249bf215546Sopenharmony_ci return MESA_FORMAT_R_UINT32; 6250bf215546Sopenharmony_ci 6251bf215546Sopenharmony_ci default: 6252bf215546Sopenharmony_ci return MESA_FORMAT_NONE; 6253bf215546Sopenharmony_ci } 6254bf215546Sopenharmony_ci} 6255bf215546Sopenharmony_ci 6256bf215546Sopenharmony_ci 6257bf215546Sopenharmony_cimesa_format 6258bf215546Sopenharmony_ci_mesa_validate_texbuffer_format(const struct gl_context *ctx, 6259bf215546Sopenharmony_ci GLenum internalFormat) 6260bf215546Sopenharmony_ci{ 6261bf215546Sopenharmony_ci mesa_format format = _mesa_get_texbuffer_format(ctx, internalFormat); 6262bf215546Sopenharmony_ci GLenum datatype; 6263bf215546Sopenharmony_ci 6264bf215546Sopenharmony_ci if (format == MESA_FORMAT_NONE) 6265bf215546Sopenharmony_ci return MESA_FORMAT_NONE; 6266bf215546Sopenharmony_ci 6267bf215546Sopenharmony_ci datatype = _mesa_get_format_datatype(format); 6268bf215546Sopenharmony_ci 6269bf215546Sopenharmony_ci /* The GL_ARB_texture_buffer_object spec says: 6270bf215546Sopenharmony_ci * 6271bf215546Sopenharmony_ci * "If ARB_texture_float is not supported, references to the 6272bf215546Sopenharmony_ci * floating-point internal formats provided by that extension should be 6273bf215546Sopenharmony_ci * removed, and such formats may not be passed to TexBufferARB." 6274bf215546Sopenharmony_ci * 6275bf215546Sopenharmony_ci * As a result, GL_HALF_FLOAT internal format depends on both 6276bf215546Sopenharmony_ci * GL_ARB_texture_float and GL_ARB_half_float_pixel. 6277bf215546Sopenharmony_ci */ 6278bf215546Sopenharmony_ci if ((datatype == GL_FLOAT || datatype == GL_HALF_FLOAT) && 6279bf215546Sopenharmony_ci !ctx->Extensions.ARB_texture_float) 6280bf215546Sopenharmony_ci return MESA_FORMAT_NONE; 6281bf215546Sopenharmony_ci 6282bf215546Sopenharmony_ci if (!ctx->Extensions.ARB_texture_rg) { 6283bf215546Sopenharmony_ci GLenum base_format = _mesa_get_format_base_format(format); 6284bf215546Sopenharmony_ci if (base_format == GL_R || base_format == GL_RG) 6285bf215546Sopenharmony_ci return MESA_FORMAT_NONE; 6286bf215546Sopenharmony_ci } 6287bf215546Sopenharmony_ci 6288bf215546Sopenharmony_ci if (!ctx->Extensions.ARB_texture_buffer_object_rgb32) { 6289bf215546Sopenharmony_ci GLenum base_format = _mesa_get_format_base_format(format); 6290bf215546Sopenharmony_ci if (base_format == GL_RGB) 6291bf215546Sopenharmony_ci return MESA_FORMAT_NONE; 6292bf215546Sopenharmony_ci } 6293bf215546Sopenharmony_ci return format; 6294bf215546Sopenharmony_ci} 6295bf215546Sopenharmony_ci 6296bf215546Sopenharmony_ci 6297bf215546Sopenharmony_ci/** 6298bf215546Sopenharmony_ci * Do work common to glTexBuffer, glTexBufferRange, glTextureBuffer 6299bf215546Sopenharmony_ci * and glTextureBufferRange, including some error checking. 6300bf215546Sopenharmony_ci */ 6301bf215546Sopenharmony_cistatic void 6302bf215546Sopenharmony_citexture_buffer_range(struct gl_context *ctx, 6303bf215546Sopenharmony_ci struct gl_texture_object *texObj, 6304bf215546Sopenharmony_ci GLenum internalFormat, 6305bf215546Sopenharmony_ci struct gl_buffer_object *bufObj, 6306bf215546Sopenharmony_ci GLintptr offset, GLsizeiptr size, 6307bf215546Sopenharmony_ci const char *caller) 6308bf215546Sopenharmony_ci{ 6309bf215546Sopenharmony_ci GLintptr oldOffset = texObj->BufferOffset; 6310bf215546Sopenharmony_ci GLsizeiptr oldSize = texObj->BufferSize; 6311bf215546Sopenharmony_ci mesa_format format; 6312bf215546Sopenharmony_ci mesa_format old_format; 6313bf215546Sopenharmony_ci 6314bf215546Sopenharmony_ci /* NOTE: ARB_texture_buffer_object might not be supported in 6315bf215546Sopenharmony_ci * the compatibility profile. 6316bf215546Sopenharmony_ci */ 6317bf215546Sopenharmony_ci if (!_mesa_has_ARB_texture_buffer_object(ctx) && 6318bf215546Sopenharmony_ci !_mesa_has_OES_texture_buffer(ctx)) { 6319bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 6320bf215546Sopenharmony_ci "%s(ARB_texture_buffer_object is not" 6321bf215546Sopenharmony_ci " implemented for the compatibility profile)", caller); 6322bf215546Sopenharmony_ci return; 6323bf215546Sopenharmony_ci } 6324bf215546Sopenharmony_ci 6325bf215546Sopenharmony_ci if (texObj->HandleAllocated) { 6326bf215546Sopenharmony_ci /* The ARB_bindless_texture spec says: 6327bf215546Sopenharmony_ci * 6328bf215546Sopenharmony_ci * "The error INVALID_OPERATION is generated by TexImage*, CopyTexImage*, 6329bf215546Sopenharmony_ci * CompressedTexImage*, TexBuffer*, TexParameter*, as well as other 6330bf215546Sopenharmony_ci * functions defined in terms of these, if the texture object to be 6331bf215546Sopenharmony_ci * modified is referenced by one or more texture or image handles." 6332bf215546Sopenharmony_ci */ 6333bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, "%s(immutable texture)", caller); 6334bf215546Sopenharmony_ci return; 6335bf215546Sopenharmony_ci } 6336bf215546Sopenharmony_ci 6337bf215546Sopenharmony_ci format = _mesa_validate_texbuffer_format(ctx, internalFormat); 6338bf215546Sopenharmony_ci if (format == MESA_FORMAT_NONE) { 6339bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, "%s(internalFormat %s)", 6340bf215546Sopenharmony_ci caller, _mesa_enum_to_string(internalFormat)); 6341bf215546Sopenharmony_ci return; 6342bf215546Sopenharmony_ci } 6343bf215546Sopenharmony_ci 6344bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, 0, GL_TEXTURE_BIT); 6345bf215546Sopenharmony_ci 6346bf215546Sopenharmony_ci _mesa_lock_texture(ctx, texObj); 6347bf215546Sopenharmony_ci { 6348bf215546Sopenharmony_ci _mesa_reference_buffer_object_shared(ctx, &texObj->BufferObject, bufObj); 6349bf215546Sopenharmony_ci texObj->BufferObjectFormat = internalFormat; 6350bf215546Sopenharmony_ci old_format = texObj->_BufferObjectFormat; 6351bf215546Sopenharmony_ci texObj->_BufferObjectFormat = format; 6352bf215546Sopenharmony_ci texObj->BufferOffset = offset; 6353bf215546Sopenharmony_ci texObj->BufferSize = size; 6354bf215546Sopenharmony_ci } 6355bf215546Sopenharmony_ci _mesa_unlock_texture(ctx, texObj); 6356bf215546Sopenharmony_ci 6357bf215546Sopenharmony_ci if (old_format != format) { 6358bf215546Sopenharmony_ci st_texture_release_all_sampler_views(st_context(ctx), texObj); 6359bf215546Sopenharmony_ci } else { 6360bf215546Sopenharmony_ci if (offset != oldOffset) { 6361bf215546Sopenharmony_ci st_texture_release_all_sampler_views(st_context(ctx), texObj); 6362bf215546Sopenharmony_ci } 6363bf215546Sopenharmony_ci if (size != oldSize) { 6364bf215546Sopenharmony_ci st_texture_release_all_sampler_views(st_context(ctx), texObj); 6365bf215546Sopenharmony_ci } 6366bf215546Sopenharmony_ci } 6367bf215546Sopenharmony_ci 6368bf215546Sopenharmony_ci ctx->NewDriverState |= ST_NEW_SAMPLER_VIEWS; 6369bf215546Sopenharmony_ci 6370bf215546Sopenharmony_ci if (bufObj) { 6371bf215546Sopenharmony_ci bufObj->UsageHistory |= USAGE_TEXTURE_BUFFER; 6372bf215546Sopenharmony_ci } 6373bf215546Sopenharmony_ci} 6374bf215546Sopenharmony_ci 6375bf215546Sopenharmony_ci 6376bf215546Sopenharmony_ci/** 6377bf215546Sopenharmony_ci * Make sure the texture buffer target is GL_TEXTURE_BUFFER. 6378bf215546Sopenharmony_ci * Return true if it is, and return false if it is not 6379bf215546Sopenharmony_ci * (and throw INVALID ENUM as dictated in the OpenGL 4.5 6380bf215546Sopenharmony_ci * core spec, 02.02.2015, PDF page 245). 6381bf215546Sopenharmony_ci */ 6382bf215546Sopenharmony_cistatic bool 6383bf215546Sopenharmony_cicheck_texture_buffer_target(struct gl_context *ctx, GLenum target, 6384bf215546Sopenharmony_ci const char *caller, bool dsa) 6385bf215546Sopenharmony_ci{ 6386bf215546Sopenharmony_ci if (target != GL_TEXTURE_BUFFER_ARB) { 6387bf215546Sopenharmony_ci _mesa_error(ctx, dsa ? GL_INVALID_OPERATION : GL_INVALID_ENUM, 6388bf215546Sopenharmony_ci "%s(texture target is not GL_TEXTURE_BUFFER)", caller); 6389bf215546Sopenharmony_ci return false; 6390bf215546Sopenharmony_ci } 6391bf215546Sopenharmony_ci else 6392bf215546Sopenharmony_ci return true; 6393bf215546Sopenharmony_ci} 6394bf215546Sopenharmony_ci 6395bf215546Sopenharmony_ci/** 6396bf215546Sopenharmony_ci * Check for errors related to the texture buffer range. 6397bf215546Sopenharmony_ci * Return false if errors are found, true if none are found. 6398bf215546Sopenharmony_ci */ 6399bf215546Sopenharmony_cistatic bool 6400bf215546Sopenharmony_cicheck_texture_buffer_range(struct gl_context *ctx, 6401bf215546Sopenharmony_ci struct gl_buffer_object *bufObj, 6402bf215546Sopenharmony_ci GLintptr offset, GLsizeiptr size, 6403bf215546Sopenharmony_ci const char *caller) 6404bf215546Sopenharmony_ci{ 6405bf215546Sopenharmony_ci /* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer 6406bf215546Sopenharmony_ci * Textures (PDF page 245): 6407bf215546Sopenharmony_ci * "An INVALID_VALUE error is generated if offset is negative, if 6408bf215546Sopenharmony_ci * size is less than or equal to zero, or if offset + size is greater 6409bf215546Sopenharmony_ci * than the value of BUFFER_SIZE for the buffer bound to target." 6410bf215546Sopenharmony_ci */ 6411bf215546Sopenharmony_ci if (offset < 0) { 6412bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, "%s(offset=%d < 0)", caller, 6413bf215546Sopenharmony_ci (int) offset); 6414bf215546Sopenharmony_ci return false; 6415bf215546Sopenharmony_ci } 6416bf215546Sopenharmony_ci 6417bf215546Sopenharmony_ci if (size <= 0) { 6418bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d <= 0)", caller, 6419bf215546Sopenharmony_ci (int) size); 6420bf215546Sopenharmony_ci return false; 6421bf215546Sopenharmony_ci } 6422bf215546Sopenharmony_ci 6423bf215546Sopenharmony_ci if (offset + size > bufObj->Size) { 6424bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, 6425bf215546Sopenharmony_ci "%s(offset=%d + size=%d > buffer_size=%d)", caller, 6426bf215546Sopenharmony_ci (int) offset, (int) size, (int) bufObj->Size); 6427bf215546Sopenharmony_ci return false; 6428bf215546Sopenharmony_ci } 6429bf215546Sopenharmony_ci 6430bf215546Sopenharmony_ci /* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer 6431bf215546Sopenharmony_ci * Textures (PDF page 245): 6432bf215546Sopenharmony_ci * "An INVALID_VALUE error is generated if offset is not an integer 6433bf215546Sopenharmony_ci * multiple of the value of TEXTURE_BUFFER_OFFSET_ALIGNMENT." 6434bf215546Sopenharmony_ci */ 6435bf215546Sopenharmony_ci if (offset % ctx->Const.TextureBufferOffsetAlignment) { 6436bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, 6437bf215546Sopenharmony_ci "%s(invalid offset alignment)", caller); 6438bf215546Sopenharmony_ci return false; 6439bf215546Sopenharmony_ci } 6440bf215546Sopenharmony_ci 6441bf215546Sopenharmony_ci return true; 6442bf215546Sopenharmony_ci} 6443bf215546Sopenharmony_ci 6444bf215546Sopenharmony_ci 6445bf215546Sopenharmony_ci/** GL_ARB_texture_buffer_object */ 6446bf215546Sopenharmony_civoid GLAPIENTRY 6447bf215546Sopenharmony_ci_mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer) 6448bf215546Sopenharmony_ci{ 6449bf215546Sopenharmony_ci struct gl_texture_object *texObj; 6450bf215546Sopenharmony_ci struct gl_buffer_object *bufObj; 6451bf215546Sopenharmony_ci 6452bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 6453bf215546Sopenharmony_ci 6454bf215546Sopenharmony_ci /* Need to catch a bad target before it gets to 6455bf215546Sopenharmony_ci * _mesa_get_current_tex_object. 6456bf215546Sopenharmony_ci */ 6457bf215546Sopenharmony_ci if (!check_texture_buffer_target(ctx, target, "glTexBuffer", false)) 6458bf215546Sopenharmony_ci return; 6459bf215546Sopenharmony_ci 6460bf215546Sopenharmony_ci if (buffer) { 6461bf215546Sopenharmony_ci bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glTexBuffer"); 6462bf215546Sopenharmony_ci if (!bufObj) 6463bf215546Sopenharmony_ci return; 6464bf215546Sopenharmony_ci } else 6465bf215546Sopenharmony_ci bufObj = NULL; 6466bf215546Sopenharmony_ci 6467bf215546Sopenharmony_ci texObj = _mesa_get_current_tex_object(ctx, target); 6468bf215546Sopenharmony_ci if (!texObj) 6469bf215546Sopenharmony_ci return; 6470bf215546Sopenharmony_ci 6471bf215546Sopenharmony_ci texture_buffer_range(ctx, texObj, internalFormat, bufObj, 0, 6472bf215546Sopenharmony_ci buffer ? -1 : 0, "glTexBuffer"); 6473bf215546Sopenharmony_ci} 6474bf215546Sopenharmony_ci 6475bf215546Sopenharmony_ci 6476bf215546Sopenharmony_ci/** GL_ARB_texture_buffer_range */ 6477bf215546Sopenharmony_civoid GLAPIENTRY 6478bf215546Sopenharmony_ci_mesa_TexBufferRange(GLenum target, GLenum internalFormat, GLuint buffer, 6479bf215546Sopenharmony_ci GLintptr offset, GLsizeiptr size) 6480bf215546Sopenharmony_ci{ 6481bf215546Sopenharmony_ci struct gl_texture_object *texObj; 6482bf215546Sopenharmony_ci struct gl_buffer_object *bufObj; 6483bf215546Sopenharmony_ci 6484bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 6485bf215546Sopenharmony_ci 6486bf215546Sopenharmony_ci /* Need to catch a bad target before it gets to 6487bf215546Sopenharmony_ci * _mesa_get_current_tex_object. 6488bf215546Sopenharmony_ci */ 6489bf215546Sopenharmony_ci if (!check_texture_buffer_target(ctx, target, "glTexBufferRange", false)) 6490bf215546Sopenharmony_ci return; 6491bf215546Sopenharmony_ci 6492bf215546Sopenharmony_ci if (buffer) { 6493bf215546Sopenharmony_ci bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glTexBufferRange"); 6494bf215546Sopenharmony_ci if (!bufObj) 6495bf215546Sopenharmony_ci return; 6496bf215546Sopenharmony_ci 6497bf215546Sopenharmony_ci if (!check_texture_buffer_range(ctx, bufObj, offset, size, 6498bf215546Sopenharmony_ci "glTexBufferRange")) 6499bf215546Sopenharmony_ci return; 6500bf215546Sopenharmony_ci 6501bf215546Sopenharmony_ci } else { 6502bf215546Sopenharmony_ci /* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer 6503bf215546Sopenharmony_ci * Textures (PDF page 254): 6504bf215546Sopenharmony_ci * "If buffer is zero, then any buffer object attached to the buffer 6505bf215546Sopenharmony_ci * texture is detached, the values offset and size are ignored and 6506bf215546Sopenharmony_ci * the state for offset and size for the buffer texture are reset to 6507bf215546Sopenharmony_ci * zero." 6508bf215546Sopenharmony_ci */ 6509bf215546Sopenharmony_ci offset = 0; 6510bf215546Sopenharmony_ci size = 0; 6511bf215546Sopenharmony_ci bufObj = NULL; 6512bf215546Sopenharmony_ci } 6513bf215546Sopenharmony_ci 6514bf215546Sopenharmony_ci texObj = _mesa_get_current_tex_object(ctx, target); 6515bf215546Sopenharmony_ci if (!texObj) 6516bf215546Sopenharmony_ci return; 6517bf215546Sopenharmony_ci 6518bf215546Sopenharmony_ci texture_buffer_range(ctx, texObj, internalFormat, bufObj, 6519bf215546Sopenharmony_ci offset, size, "glTexBufferRange"); 6520bf215546Sopenharmony_ci} 6521bf215546Sopenharmony_ci 6522bf215546Sopenharmony_ci 6523bf215546Sopenharmony_ci/** GL_ARB_texture_buffer_range + GL_EXT_direct_state_access */ 6524bf215546Sopenharmony_civoid GLAPIENTRY 6525bf215546Sopenharmony_ci_mesa_TextureBufferRangeEXT(GLuint texture, GLenum target, GLenum internalFormat, 6526bf215546Sopenharmony_ci GLuint buffer, GLintptr offset, GLsizeiptr size) 6527bf215546Sopenharmony_ci{ 6528bf215546Sopenharmony_ci struct gl_texture_object *texObj; 6529bf215546Sopenharmony_ci struct gl_buffer_object *bufObj; 6530bf215546Sopenharmony_ci 6531bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 6532bf215546Sopenharmony_ci 6533bf215546Sopenharmony_ci texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, 6534bf215546Sopenharmony_ci "glTextureBufferRangeEXT"); 6535bf215546Sopenharmony_ci if (!texObj) 6536bf215546Sopenharmony_ci return; 6537bf215546Sopenharmony_ci 6538bf215546Sopenharmony_ci if (!check_texture_buffer_target(ctx, target, "glTextureBufferRangeEXT", true)) 6539bf215546Sopenharmony_ci return; 6540bf215546Sopenharmony_ci 6541bf215546Sopenharmony_ci if (buffer) { 6542bf215546Sopenharmony_ci bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glTextureBufferRangeEXT"); 6543bf215546Sopenharmony_ci if (!bufObj) 6544bf215546Sopenharmony_ci return; 6545bf215546Sopenharmony_ci 6546bf215546Sopenharmony_ci if (!check_texture_buffer_range(ctx, bufObj, offset, size, 6547bf215546Sopenharmony_ci "glTextureBufferRangeEXT")) 6548bf215546Sopenharmony_ci return; 6549bf215546Sopenharmony_ci 6550bf215546Sopenharmony_ci } else { 6551bf215546Sopenharmony_ci /* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer 6552bf215546Sopenharmony_ci * Textures (PDF page 254): 6553bf215546Sopenharmony_ci * "If buffer is zero, then any buffer object attached to the buffer 6554bf215546Sopenharmony_ci * texture is detached, the values offset and size are ignored and 6555bf215546Sopenharmony_ci * the state for offset and size for the buffer texture are reset to 6556bf215546Sopenharmony_ci * zero." 6557bf215546Sopenharmony_ci */ 6558bf215546Sopenharmony_ci offset = 0; 6559bf215546Sopenharmony_ci size = 0; 6560bf215546Sopenharmony_ci bufObj = NULL; 6561bf215546Sopenharmony_ci } 6562bf215546Sopenharmony_ci 6563bf215546Sopenharmony_ci texture_buffer_range(ctx, texObj, internalFormat, bufObj, 6564bf215546Sopenharmony_ci offset, size, "glTextureBufferRangeEXT"); 6565bf215546Sopenharmony_ci} 6566bf215546Sopenharmony_ci 6567bf215546Sopenharmony_ci 6568bf215546Sopenharmony_civoid GLAPIENTRY 6569bf215546Sopenharmony_ci_mesa_TextureBuffer(GLuint texture, GLenum internalFormat, GLuint buffer) 6570bf215546Sopenharmony_ci{ 6571bf215546Sopenharmony_ci struct gl_texture_object *texObj; 6572bf215546Sopenharmony_ci struct gl_buffer_object *bufObj; 6573bf215546Sopenharmony_ci 6574bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 6575bf215546Sopenharmony_ci 6576bf215546Sopenharmony_ci if (buffer) { 6577bf215546Sopenharmony_ci bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glTextureBuffer"); 6578bf215546Sopenharmony_ci if (!bufObj) 6579bf215546Sopenharmony_ci return; 6580bf215546Sopenharmony_ci } else 6581bf215546Sopenharmony_ci bufObj = NULL; 6582bf215546Sopenharmony_ci 6583bf215546Sopenharmony_ci /* Get the texture object by Name. */ 6584bf215546Sopenharmony_ci texObj = _mesa_lookup_texture_err(ctx, texture, "glTextureBuffer"); 6585bf215546Sopenharmony_ci if (!texObj) 6586bf215546Sopenharmony_ci return; 6587bf215546Sopenharmony_ci 6588bf215546Sopenharmony_ci if (!check_texture_buffer_target(ctx, texObj->Target, "glTextureBuffer", true)) 6589bf215546Sopenharmony_ci return; 6590bf215546Sopenharmony_ci 6591bf215546Sopenharmony_ci texture_buffer_range(ctx, texObj, internalFormat, 6592bf215546Sopenharmony_ci bufObj, 0, buffer ? -1 : 0, "glTextureBuffer"); 6593bf215546Sopenharmony_ci} 6594bf215546Sopenharmony_ci 6595bf215546Sopenharmony_civoid GLAPIENTRY 6596bf215546Sopenharmony_ci_mesa_TextureBufferEXT(GLuint texture, GLenum target, 6597bf215546Sopenharmony_ci GLenum internalFormat, GLuint buffer) 6598bf215546Sopenharmony_ci{ 6599bf215546Sopenharmony_ci struct gl_texture_object *texObj; 6600bf215546Sopenharmony_ci struct gl_buffer_object *bufObj; 6601bf215546Sopenharmony_ci 6602bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 6603bf215546Sopenharmony_ci 6604bf215546Sopenharmony_ci if (buffer) { 6605bf215546Sopenharmony_ci bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glTextureBuffer"); 6606bf215546Sopenharmony_ci if (!bufObj) 6607bf215546Sopenharmony_ci return; 6608bf215546Sopenharmony_ci } else 6609bf215546Sopenharmony_ci bufObj = NULL; 6610bf215546Sopenharmony_ci 6611bf215546Sopenharmony_ci /* Get the texture object by Name. */ 6612bf215546Sopenharmony_ci texObj = _mesa_lookup_or_create_texture(ctx, target, texture, 6613bf215546Sopenharmony_ci false, true, 6614bf215546Sopenharmony_ci "glTextureBufferEXT"); 6615bf215546Sopenharmony_ci 6616bf215546Sopenharmony_ci if (!texObj || 6617bf215546Sopenharmony_ci !check_texture_buffer_target(ctx, texObj->Target, "glTextureBufferEXT", true)) 6618bf215546Sopenharmony_ci return; 6619bf215546Sopenharmony_ci 6620bf215546Sopenharmony_ci texture_buffer_range(ctx, texObj, internalFormat, 6621bf215546Sopenharmony_ci bufObj, 0, buffer ? -1 : 0, "glTextureBufferEXT"); 6622bf215546Sopenharmony_ci} 6623bf215546Sopenharmony_ci 6624bf215546Sopenharmony_civoid GLAPIENTRY 6625bf215546Sopenharmony_ci_mesa_MultiTexBufferEXT(GLenum texunit, GLenum target, 6626bf215546Sopenharmony_ci GLenum internalFormat, GLuint buffer) 6627bf215546Sopenharmony_ci{ 6628bf215546Sopenharmony_ci struct gl_texture_object *texObj; 6629bf215546Sopenharmony_ci struct gl_buffer_object *bufObj; 6630bf215546Sopenharmony_ci 6631bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 6632bf215546Sopenharmony_ci 6633bf215546Sopenharmony_ci if (buffer) { 6634bf215546Sopenharmony_ci bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glMultiTexBufferEXT"); 6635bf215546Sopenharmony_ci if (!bufObj) 6636bf215546Sopenharmony_ci return; 6637bf215546Sopenharmony_ci } else 6638bf215546Sopenharmony_ci bufObj = NULL; 6639bf215546Sopenharmony_ci 6640bf215546Sopenharmony_ci /* Get the texture object */ 6641bf215546Sopenharmony_ci texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, 6642bf215546Sopenharmony_ci texunit - GL_TEXTURE0, 6643bf215546Sopenharmony_ci true, 6644bf215546Sopenharmony_ci "glMultiTexBufferEXT"); 6645bf215546Sopenharmony_ci 6646bf215546Sopenharmony_ci if (!texObj || 6647bf215546Sopenharmony_ci !check_texture_buffer_target(ctx, texObj->Target, "glMultiTexBufferEXT", false)) 6648bf215546Sopenharmony_ci return; 6649bf215546Sopenharmony_ci 6650bf215546Sopenharmony_ci texture_buffer_range(ctx, texObj, internalFormat, 6651bf215546Sopenharmony_ci bufObj, 0, buffer ? -1 : 0, "glMultiTexBufferEXT"); 6652bf215546Sopenharmony_ci} 6653bf215546Sopenharmony_ci 6654bf215546Sopenharmony_civoid GLAPIENTRY 6655bf215546Sopenharmony_ci_mesa_TextureBufferRange(GLuint texture, GLenum internalFormat, GLuint buffer, 6656bf215546Sopenharmony_ci GLintptr offset, GLsizeiptr size) 6657bf215546Sopenharmony_ci{ 6658bf215546Sopenharmony_ci struct gl_texture_object *texObj; 6659bf215546Sopenharmony_ci struct gl_buffer_object *bufObj; 6660bf215546Sopenharmony_ci 6661bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 6662bf215546Sopenharmony_ci 6663bf215546Sopenharmony_ci if (buffer) { 6664bf215546Sopenharmony_ci bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, 6665bf215546Sopenharmony_ci "glTextureBufferRange"); 6666bf215546Sopenharmony_ci if (!bufObj) 6667bf215546Sopenharmony_ci return; 6668bf215546Sopenharmony_ci 6669bf215546Sopenharmony_ci if (!check_texture_buffer_range(ctx, bufObj, offset, size, 6670bf215546Sopenharmony_ci "glTextureBufferRange")) 6671bf215546Sopenharmony_ci return; 6672bf215546Sopenharmony_ci 6673bf215546Sopenharmony_ci } else { 6674bf215546Sopenharmony_ci /* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer 6675bf215546Sopenharmony_ci * Textures (PDF page 254): 6676bf215546Sopenharmony_ci * "If buffer is zero, then any buffer object attached to the buffer 6677bf215546Sopenharmony_ci * texture is detached, the values offset and size are ignored and 6678bf215546Sopenharmony_ci * the state for offset and size for the buffer texture are reset to 6679bf215546Sopenharmony_ci * zero." 6680bf215546Sopenharmony_ci */ 6681bf215546Sopenharmony_ci offset = 0; 6682bf215546Sopenharmony_ci size = 0; 6683bf215546Sopenharmony_ci bufObj = NULL; 6684bf215546Sopenharmony_ci } 6685bf215546Sopenharmony_ci 6686bf215546Sopenharmony_ci /* Get the texture object by Name. */ 6687bf215546Sopenharmony_ci texObj = _mesa_lookup_texture_err(ctx, texture, "glTextureBufferRange"); 6688bf215546Sopenharmony_ci if (!texObj) 6689bf215546Sopenharmony_ci return; 6690bf215546Sopenharmony_ci 6691bf215546Sopenharmony_ci if (!check_texture_buffer_target(ctx, texObj->Target, 6692bf215546Sopenharmony_ci "glTextureBufferRange", true)) 6693bf215546Sopenharmony_ci return; 6694bf215546Sopenharmony_ci 6695bf215546Sopenharmony_ci texture_buffer_range(ctx, texObj, internalFormat, 6696bf215546Sopenharmony_ci bufObj, offset, size, "glTextureBufferRange"); 6697bf215546Sopenharmony_ci} 6698bf215546Sopenharmony_ci 6699bf215546Sopenharmony_ciGLboolean 6700bf215546Sopenharmony_ci_mesa_is_renderable_texture_format(const struct gl_context *ctx, 6701bf215546Sopenharmony_ci GLenum internalformat) 6702bf215546Sopenharmony_ci{ 6703bf215546Sopenharmony_ci /* Everything that is allowed for renderbuffers, 6704bf215546Sopenharmony_ci * except for a base format of GL_STENCIL_INDEX, unless supported. 6705bf215546Sopenharmony_ci */ 6706bf215546Sopenharmony_ci GLenum baseFormat = _mesa_base_fbo_format(ctx, internalformat); 6707bf215546Sopenharmony_ci if (ctx->Extensions.ARB_texture_stencil8) 6708bf215546Sopenharmony_ci return baseFormat != 0; 6709bf215546Sopenharmony_ci else 6710bf215546Sopenharmony_ci return baseFormat != 0 && baseFormat != GL_STENCIL_INDEX; 6711bf215546Sopenharmony_ci} 6712bf215546Sopenharmony_ci 6713bf215546Sopenharmony_ci 6714bf215546Sopenharmony_ci/** GL_ARB_texture_multisample */ 6715bf215546Sopenharmony_cistatic GLboolean 6716bf215546Sopenharmony_cicheck_multisample_target(GLuint dims, GLenum target, bool dsa) 6717bf215546Sopenharmony_ci{ 6718bf215546Sopenharmony_ci switch(target) { 6719bf215546Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE: 6720bf215546Sopenharmony_ci return dims == 2; 6721bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 6722bf215546Sopenharmony_ci return dims == 2 && !dsa; 6723bf215546Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 6724bf215546Sopenharmony_ci return dims == 3; 6725bf215546Sopenharmony_ci case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 6726bf215546Sopenharmony_ci return dims == 3 && !dsa; 6727bf215546Sopenharmony_ci default: 6728bf215546Sopenharmony_ci return GL_FALSE; 6729bf215546Sopenharmony_ci } 6730bf215546Sopenharmony_ci} 6731bf215546Sopenharmony_ci 6732bf215546Sopenharmony_ci 6733bf215546Sopenharmony_cistatic void 6734bf215546Sopenharmony_citexture_image_multisample(struct gl_context *ctx, GLuint dims, 6735bf215546Sopenharmony_ci struct gl_texture_object *texObj, 6736bf215546Sopenharmony_ci struct gl_memory_object *memObj, 6737bf215546Sopenharmony_ci GLenum target, GLsizei samples, 6738bf215546Sopenharmony_ci GLint internalformat, GLsizei width, 6739bf215546Sopenharmony_ci GLsizei height, GLsizei depth, 6740bf215546Sopenharmony_ci GLboolean fixedsamplelocations, 6741bf215546Sopenharmony_ci GLboolean immutable, GLuint64 offset, 6742bf215546Sopenharmony_ci const char *func) 6743bf215546Sopenharmony_ci{ 6744bf215546Sopenharmony_ci struct gl_texture_image *texImage; 6745bf215546Sopenharmony_ci GLboolean sizeOK, dimensionsOK, samplesOK; 6746bf215546Sopenharmony_ci mesa_format texFormat; 6747bf215546Sopenharmony_ci GLenum sample_count_error; 6748bf215546Sopenharmony_ci bool dsa = strstr(func, "ture") ? true : false; 6749bf215546Sopenharmony_ci 6750bf215546Sopenharmony_ci if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) { 6751bf215546Sopenharmony_ci _mesa_debug(ctx, "%s(target=%s, samples=%d, internalformat=%s)\n", func, 6752bf215546Sopenharmony_ci _mesa_enum_to_string(target), samples, _mesa_enum_to_string(internalformat)); 6753bf215546Sopenharmony_ci } 6754bf215546Sopenharmony_ci 6755bf215546Sopenharmony_ci if (!((ctx->Extensions.ARB_texture_multisample 6756bf215546Sopenharmony_ci && _mesa_is_desktop_gl(ctx))) && !_mesa_is_gles31(ctx)) { 6757bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func); 6758bf215546Sopenharmony_ci return; 6759bf215546Sopenharmony_ci } 6760bf215546Sopenharmony_ci 6761bf215546Sopenharmony_ci if (samples < 1) { 6762bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, "%s(samples < 1)", func); 6763bf215546Sopenharmony_ci return; 6764bf215546Sopenharmony_ci } 6765bf215546Sopenharmony_ci 6766bf215546Sopenharmony_ci if (!check_multisample_target(dims, target, dsa)) { 6767bf215546Sopenharmony_ci GLenum err = dsa ? GL_INVALID_OPERATION : GL_INVALID_ENUM; 6768bf215546Sopenharmony_ci _mesa_error(ctx, err, "%s(target=%s)", func, 6769bf215546Sopenharmony_ci _mesa_enum_to_string(target)); 6770bf215546Sopenharmony_ci return; 6771bf215546Sopenharmony_ci } 6772bf215546Sopenharmony_ci 6773bf215546Sopenharmony_ci /* check that the specified internalformat is color/depth/stencil-renderable; 6774bf215546Sopenharmony_ci * refer GL3.1 spec 4.4.4 6775bf215546Sopenharmony_ci */ 6776bf215546Sopenharmony_ci 6777bf215546Sopenharmony_ci if (immutable && !_mesa_is_legal_tex_storage_format(ctx, internalformat)) { 6778bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, 6779bf215546Sopenharmony_ci "%s(internalformat=%s not legal for immutable-format)", 6780bf215546Sopenharmony_ci func, _mesa_enum_to_string(internalformat)); 6781bf215546Sopenharmony_ci return; 6782bf215546Sopenharmony_ci } 6783bf215546Sopenharmony_ci 6784bf215546Sopenharmony_ci if (!_mesa_is_renderable_texture_format(ctx, internalformat)) { 6785bf215546Sopenharmony_ci /* Page 172 of OpenGL ES 3.1 spec says: 6786bf215546Sopenharmony_ci * "An INVALID_ENUM error is generated if sizedinternalformat is not 6787bf215546Sopenharmony_ci * color-renderable, depth-renderable, or stencil-renderable (as 6788bf215546Sopenharmony_ci * defined in section 9.4). 6789bf215546Sopenharmony_ci * 6790bf215546Sopenharmony_ci * (Same error is also defined for desktop OpenGL for multisample 6791bf215546Sopenharmony_ci * teximage/texstorage functions.) 6792bf215546Sopenharmony_ci */ 6793bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, "%s(internalformat=%s)", func, 6794bf215546Sopenharmony_ci _mesa_enum_to_string(internalformat)); 6795bf215546Sopenharmony_ci return; 6796bf215546Sopenharmony_ci } 6797bf215546Sopenharmony_ci 6798bf215546Sopenharmony_ci sample_count_error = _mesa_check_sample_count(ctx, target, 6799bf215546Sopenharmony_ci internalformat, samples, samples); 6800bf215546Sopenharmony_ci samplesOK = sample_count_error == GL_NO_ERROR; 6801bf215546Sopenharmony_ci 6802bf215546Sopenharmony_ci /* Page 254 of OpenGL 4.4 spec says: 6803bf215546Sopenharmony_ci * "Proxy arrays for two-dimensional multisample and two-dimensional 6804bf215546Sopenharmony_ci * multisample array textures are operated on in the same way when 6805bf215546Sopenharmony_ci * TexImage2DMultisample is called with target specified as 6806bf215546Sopenharmony_ci * PROXY_TEXTURE_2D_MULTISAMPLE, or TexImage3DMultisample is called 6807bf215546Sopenharmony_ci * with target specified as PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY. 6808bf215546Sopenharmony_ci * However, if samples is not supported, then no error is generated. 6809bf215546Sopenharmony_ci */ 6810bf215546Sopenharmony_ci if (!samplesOK && !_mesa_is_proxy_texture(target)) { 6811bf215546Sopenharmony_ci _mesa_error(ctx, sample_count_error, "%s(samples=%d)", func, samples); 6812bf215546Sopenharmony_ci return; 6813bf215546Sopenharmony_ci } 6814bf215546Sopenharmony_ci 6815bf215546Sopenharmony_ci if (!texObj) { 6816bf215546Sopenharmony_ci texObj = _mesa_get_current_tex_object(ctx, target); 6817bf215546Sopenharmony_ci if (!texObj) 6818bf215546Sopenharmony_ci return; 6819bf215546Sopenharmony_ci } 6820bf215546Sopenharmony_ci 6821bf215546Sopenharmony_ci if (immutable && texObj->Name == 0) { 6822bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 6823bf215546Sopenharmony_ci "%s(texture object 0)", 6824bf215546Sopenharmony_ci func); 6825bf215546Sopenharmony_ci return; 6826bf215546Sopenharmony_ci } 6827bf215546Sopenharmony_ci 6828bf215546Sopenharmony_ci texImage = _mesa_get_tex_image(ctx, texObj, 0, 0); 6829bf215546Sopenharmony_ci 6830bf215546Sopenharmony_ci if (texImage == NULL) { 6831bf215546Sopenharmony_ci _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s()", func); 6832bf215546Sopenharmony_ci return; 6833bf215546Sopenharmony_ci } 6834bf215546Sopenharmony_ci 6835bf215546Sopenharmony_ci texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0, 6836bf215546Sopenharmony_ci internalformat, GL_NONE, GL_NONE); 6837bf215546Sopenharmony_ci assert(texFormat != MESA_FORMAT_NONE); 6838bf215546Sopenharmony_ci 6839bf215546Sopenharmony_ci dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, 0, 6840bf215546Sopenharmony_ci width, height, depth, 0); 6841bf215546Sopenharmony_ci 6842bf215546Sopenharmony_ci sizeOK = st_TestProxyTexImage(ctx, target, 0, 0, texFormat, 6843bf215546Sopenharmony_ci samples, width, height, depth); 6844bf215546Sopenharmony_ci 6845bf215546Sopenharmony_ci if (_mesa_is_proxy_texture(target)) { 6846bf215546Sopenharmony_ci if (samplesOK && dimensionsOK && sizeOK) { 6847bf215546Sopenharmony_ci _mesa_init_teximage_fields_ms(ctx, texImage, width, height, depth, 0, 6848bf215546Sopenharmony_ci internalformat, texFormat, 6849bf215546Sopenharmony_ci samples, fixedsamplelocations); 6850bf215546Sopenharmony_ci } 6851bf215546Sopenharmony_ci else { 6852bf215546Sopenharmony_ci /* clear all image fields */ 6853bf215546Sopenharmony_ci clear_teximage_fields(texImage); 6854bf215546Sopenharmony_ci } 6855bf215546Sopenharmony_ci } 6856bf215546Sopenharmony_ci else { 6857bf215546Sopenharmony_ci if (!dimensionsOK) { 6858bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, 6859bf215546Sopenharmony_ci "%s(invalid width=%d or height=%d)", func, width, height); 6860bf215546Sopenharmony_ci return; 6861bf215546Sopenharmony_ci } 6862bf215546Sopenharmony_ci 6863bf215546Sopenharmony_ci if (!sizeOK) { 6864bf215546Sopenharmony_ci _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(texture too large)", func); 6865bf215546Sopenharmony_ci return; 6866bf215546Sopenharmony_ci } 6867bf215546Sopenharmony_ci 6868bf215546Sopenharmony_ci /* Check if texObj->Immutable is set */ 6869bf215546Sopenharmony_ci if (texObj->Immutable) { 6870bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, "%s(immutable)", func); 6871bf215546Sopenharmony_ci return; 6872bf215546Sopenharmony_ci } 6873bf215546Sopenharmony_ci 6874bf215546Sopenharmony_ci if (texObj->IsSparse && 6875bf215546Sopenharmony_ci _mesa_sparse_texture_error_check(ctx, dims, texObj, texFormat, target, 0, 6876bf215546Sopenharmony_ci width, height, depth, func)) 6877bf215546Sopenharmony_ci return; /* error was recorded */ 6878bf215546Sopenharmony_ci 6879bf215546Sopenharmony_ci st_FreeTextureImageBuffer(ctx, texImage); 6880bf215546Sopenharmony_ci 6881bf215546Sopenharmony_ci _mesa_init_teximage_fields_ms(ctx, texImage, width, height, depth, 0, 6882bf215546Sopenharmony_ci internalformat, texFormat, 6883bf215546Sopenharmony_ci samples, fixedsamplelocations); 6884bf215546Sopenharmony_ci 6885bf215546Sopenharmony_ci if (width > 0 && height > 0 && depth > 0) { 6886bf215546Sopenharmony_ci if (memObj) { 6887bf215546Sopenharmony_ci if (!st_SetTextureStorageForMemoryObject(ctx, texObj, 6888bf215546Sopenharmony_ci memObj, 1, width, 6889bf215546Sopenharmony_ci height, depth, 6890bf215546Sopenharmony_ci offset)) { 6891bf215546Sopenharmony_ci 6892bf215546Sopenharmony_ci _mesa_init_teximage_fields(ctx, texImage, 0, 0, 0, 0, 6893bf215546Sopenharmony_ci internalformat, texFormat); 6894bf215546Sopenharmony_ci } 6895bf215546Sopenharmony_ci } else { 6896bf215546Sopenharmony_ci if (!st_AllocTextureStorage(ctx, texObj, 1, 6897bf215546Sopenharmony_ci width, height, depth)) { 6898bf215546Sopenharmony_ci /* tidy up the texture image state. strictly speaking, 6899bf215546Sopenharmony_ci * we're allowed to just leave this in whatever state we 6900bf215546Sopenharmony_ci * like, but being tidy is good. 6901bf215546Sopenharmony_ci */ 6902bf215546Sopenharmony_ci _mesa_init_teximage_fields(ctx, texImage, 0, 0, 0, 0, 6903bf215546Sopenharmony_ci internalformat, texFormat); 6904bf215546Sopenharmony_ci } 6905bf215546Sopenharmony_ci } 6906bf215546Sopenharmony_ci } 6907bf215546Sopenharmony_ci 6908bf215546Sopenharmony_ci texObj->External = GL_FALSE; 6909bf215546Sopenharmony_ci texObj->Immutable |= immutable; 6910bf215546Sopenharmony_ci 6911bf215546Sopenharmony_ci if (immutable) { 6912bf215546Sopenharmony_ci _mesa_set_texture_view_state(ctx, texObj, target, 1); 6913bf215546Sopenharmony_ci } 6914bf215546Sopenharmony_ci 6915bf215546Sopenharmony_ci _mesa_update_fbo_texture(ctx, texObj, 0, 0); 6916bf215546Sopenharmony_ci } 6917bf215546Sopenharmony_ci} 6918bf215546Sopenharmony_ci 6919bf215546Sopenharmony_ci 6920bf215546Sopenharmony_civoid GLAPIENTRY 6921bf215546Sopenharmony_ci_mesa_TexImage2DMultisample(GLenum target, GLsizei samples, 6922bf215546Sopenharmony_ci GLenum internalformat, GLsizei width, 6923bf215546Sopenharmony_ci GLsizei height, GLboolean fixedsamplelocations) 6924bf215546Sopenharmony_ci{ 6925bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 6926bf215546Sopenharmony_ci 6927bf215546Sopenharmony_ci texture_image_multisample(ctx, 2, NULL, NULL, target, samples, 6928bf215546Sopenharmony_ci internalformat, width, height, 1, 6929bf215546Sopenharmony_ci fixedsamplelocations, GL_FALSE, 0, 6930bf215546Sopenharmony_ci "glTexImage2DMultisample"); 6931bf215546Sopenharmony_ci} 6932bf215546Sopenharmony_ci 6933bf215546Sopenharmony_ci 6934bf215546Sopenharmony_civoid GLAPIENTRY 6935bf215546Sopenharmony_ci_mesa_TexImage3DMultisample(GLenum target, GLsizei samples, 6936bf215546Sopenharmony_ci GLenum internalformat, GLsizei width, 6937bf215546Sopenharmony_ci GLsizei height, GLsizei depth, 6938bf215546Sopenharmony_ci GLboolean fixedsamplelocations) 6939bf215546Sopenharmony_ci{ 6940bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 6941bf215546Sopenharmony_ci 6942bf215546Sopenharmony_ci texture_image_multisample(ctx, 3, NULL, NULL, target, samples, 6943bf215546Sopenharmony_ci internalformat, width, height, depth, 6944bf215546Sopenharmony_ci fixedsamplelocations, GL_FALSE, 0, 6945bf215546Sopenharmony_ci "glTexImage3DMultisample"); 6946bf215546Sopenharmony_ci} 6947bf215546Sopenharmony_ci 6948bf215546Sopenharmony_cistatic bool 6949bf215546Sopenharmony_civalid_texstorage_ms_parameters(GLsizei width, GLsizei height, GLsizei depth, 6950bf215546Sopenharmony_ci unsigned dims) 6951bf215546Sopenharmony_ci{ 6952bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 6953bf215546Sopenharmony_ci 6954bf215546Sopenharmony_ci if (!_mesa_valid_tex_storage_dim(width, height, depth)) { 6955bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, 6956bf215546Sopenharmony_ci "glTexStorage%uDMultisample(width=%d,height=%d,depth=%d)", 6957bf215546Sopenharmony_ci dims, width, height, depth); 6958bf215546Sopenharmony_ci return false; 6959bf215546Sopenharmony_ci } 6960bf215546Sopenharmony_ci return true; 6961bf215546Sopenharmony_ci} 6962bf215546Sopenharmony_ci 6963bf215546Sopenharmony_civoid GLAPIENTRY 6964bf215546Sopenharmony_ci_mesa_TexStorage2DMultisample(GLenum target, GLsizei samples, 6965bf215546Sopenharmony_ci GLenum internalformat, GLsizei width, 6966bf215546Sopenharmony_ci GLsizei height, GLboolean fixedsamplelocations) 6967bf215546Sopenharmony_ci{ 6968bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 6969bf215546Sopenharmony_ci 6970bf215546Sopenharmony_ci if (!valid_texstorage_ms_parameters(width, height, 1, 2)) 6971bf215546Sopenharmony_ci return; 6972bf215546Sopenharmony_ci 6973bf215546Sopenharmony_ci texture_image_multisample(ctx, 2, NULL, NULL, target, samples, 6974bf215546Sopenharmony_ci internalformat, width, height, 1, 6975bf215546Sopenharmony_ci fixedsamplelocations, GL_TRUE, 0, 6976bf215546Sopenharmony_ci "glTexStorage2DMultisample"); 6977bf215546Sopenharmony_ci} 6978bf215546Sopenharmony_ci 6979bf215546Sopenharmony_civoid GLAPIENTRY 6980bf215546Sopenharmony_ci_mesa_TexStorage3DMultisample(GLenum target, GLsizei samples, 6981bf215546Sopenharmony_ci GLenum internalformat, GLsizei width, 6982bf215546Sopenharmony_ci GLsizei height, GLsizei depth, 6983bf215546Sopenharmony_ci GLboolean fixedsamplelocations) 6984bf215546Sopenharmony_ci{ 6985bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 6986bf215546Sopenharmony_ci 6987bf215546Sopenharmony_ci if (!valid_texstorage_ms_parameters(width, height, depth, 3)) 6988bf215546Sopenharmony_ci return; 6989bf215546Sopenharmony_ci 6990bf215546Sopenharmony_ci texture_image_multisample(ctx, 3, NULL, NULL, target, samples, 6991bf215546Sopenharmony_ci internalformat, width, height, depth, 6992bf215546Sopenharmony_ci fixedsamplelocations, GL_TRUE, 0, 6993bf215546Sopenharmony_ci "glTexStorage3DMultisample"); 6994bf215546Sopenharmony_ci} 6995bf215546Sopenharmony_ci 6996bf215546Sopenharmony_civoid GLAPIENTRY 6997bf215546Sopenharmony_ci_mesa_TextureStorage2DMultisample(GLuint texture, GLsizei samples, 6998bf215546Sopenharmony_ci GLenum internalformat, GLsizei width, 6999bf215546Sopenharmony_ci GLsizei height, 7000bf215546Sopenharmony_ci GLboolean fixedsamplelocations) 7001bf215546Sopenharmony_ci{ 7002bf215546Sopenharmony_ci struct gl_texture_object *texObj; 7003bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 7004bf215546Sopenharmony_ci 7005bf215546Sopenharmony_ci texObj = _mesa_lookup_texture_err(ctx, texture, 7006bf215546Sopenharmony_ci "glTextureStorage2DMultisample"); 7007bf215546Sopenharmony_ci if (!texObj) 7008bf215546Sopenharmony_ci return; 7009bf215546Sopenharmony_ci 7010bf215546Sopenharmony_ci if (!valid_texstorage_ms_parameters(width, height, 1, 2)) 7011bf215546Sopenharmony_ci return; 7012bf215546Sopenharmony_ci 7013bf215546Sopenharmony_ci texture_image_multisample(ctx, 2, texObj, NULL, texObj->Target, 7014bf215546Sopenharmony_ci samples, internalformat, width, height, 1, 7015bf215546Sopenharmony_ci fixedsamplelocations, GL_TRUE, 0, 7016bf215546Sopenharmony_ci "glTextureStorage2DMultisample"); 7017bf215546Sopenharmony_ci} 7018bf215546Sopenharmony_ci 7019bf215546Sopenharmony_civoid GLAPIENTRY 7020bf215546Sopenharmony_ci_mesa_TextureStorage3DMultisample(GLuint texture, GLsizei samples, 7021bf215546Sopenharmony_ci GLenum internalformat, GLsizei width, 7022bf215546Sopenharmony_ci GLsizei height, GLsizei depth, 7023bf215546Sopenharmony_ci GLboolean fixedsamplelocations) 7024bf215546Sopenharmony_ci{ 7025bf215546Sopenharmony_ci struct gl_texture_object *texObj; 7026bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 7027bf215546Sopenharmony_ci 7028bf215546Sopenharmony_ci /* Get the texture object by Name. */ 7029bf215546Sopenharmony_ci texObj = _mesa_lookup_texture_err(ctx, texture, 7030bf215546Sopenharmony_ci "glTextureStorage3DMultisample"); 7031bf215546Sopenharmony_ci if (!texObj) 7032bf215546Sopenharmony_ci return; 7033bf215546Sopenharmony_ci 7034bf215546Sopenharmony_ci if (!valid_texstorage_ms_parameters(width, height, depth, 3)) 7035bf215546Sopenharmony_ci return; 7036bf215546Sopenharmony_ci 7037bf215546Sopenharmony_ci texture_image_multisample(ctx, 3, texObj, NULL, texObj->Target, samples, 7038bf215546Sopenharmony_ci internalformat, width, height, depth, 7039bf215546Sopenharmony_ci fixedsamplelocations, GL_TRUE, 0, 7040bf215546Sopenharmony_ci "glTextureStorage3DMultisample"); 7041bf215546Sopenharmony_ci} 7042bf215546Sopenharmony_ci 7043bf215546Sopenharmony_civoid GLAPIENTRY 7044bf215546Sopenharmony_ci_mesa_TextureStorage2DMultisampleEXT(GLuint texture, GLenum target, GLsizei samples, 7045bf215546Sopenharmony_ci GLenum internalformat, GLsizei width, 7046bf215546Sopenharmony_ci GLsizei height, 7047bf215546Sopenharmony_ci GLboolean fixedsamplelocations) 7048bf215546Sopenharmony_ci{ 7049bf215546Sopenharmony_ci struct gl_texture_object *texObj; 7050bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 7051bf215546Sopenharmony_ci 7052bf215546Sopenharmony_ci texObj = lookup_texture_ext_dsa(ctx, target, texture, 7053bf215546Sopenharmony_ci "glTextureStorage2DMultisampleEXT"); 7054bf215546Sopenharmony_ci if (!texObj) 7055bf215546Sopenharmony_ci return; 7056bf215546Sopenharmony_ci 7057bf215546Sopenharmony_ci if (!valid_texstorage_ms_parameters(width, height, 1, 2)) 7058bf215546Sopenharmony_ci return; 7059bf215546Sopenharmony_ci 7060bf215546Sopenharmony_ci texture_image_multisample(ctx, 2, texObj, NULL, texObj->Target, 7061bf215546Sopenharmony_ci samples, internalformat, width, height, 1, 7062bf215546Sopenharmony_ci fixedsamplelocations, GL_TRUE, 0, 7063bf215546Sopenharmony_ci "glTextureStorage2DMultisampleEXT"); 7064bf215546Sopenharmony_ci} 7065bf215546Sopenharmony_ci 7066bf215546Sopenharmony_civoid GLAPIENTRY 7067bf215546Sopenharmony_ci_mesa_TextureStorage3DMultisampleEXT(GLuint texture, GLenum target, GLsizei samples, 7068bf215546Sopenharmony_ci GLenum internalformat, GLsizei width, 7069bf215546Sopenharmony_ci GLsizei height, GLsizei depth, 7070bf215546Sopenharmony_ci GLboolean fixedsamplelocations) 7071bf215546Sopenharmony_ci{ 7072bf215546Sopenharmony_ci struct gl_texture_object *texObj; 7073bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 7074bf215546Sopenharmony_ci 7075bf215546Sopenharmony_ci texObj = lookup_texture_ext_dsa(ctx, target, texture, 7076bf215546Sopenharmony_ci "glTextureStorage3DMultisampleEXT"); 7077bf215546Sopenharmony_ci if (!texObj) 7078bf215546Sopenharmony_ci return; 7079bf215546Sopenharmony_ci 7080bf215546Sopenharmony_ci if (!valid_texstorage_ms_parameters(width, height, depth, 3)) 7081bf215546Sopenharmony_ci return; 7082bf215546Sopenharmony_ci 7083bf215546Sopenharmony_ci texture_image_multisample(ctx, 3, texObj, NULL, texObj->Target, samples, 7084bf215546Sopenharmony_ci internalformat, width, height, depth, 7085bf215546Sopenharmony_ci fixedsamplelocations, GL_TRUE, 0, 7086bf215546Sopenharmony_ci "glTextureStorage3DMultisampleEXT"); 7087bf215546Sopenharmony_ci} 7088bf215546Sopenharmony_ci 7089bf215546Sopenharmony_civoid 7090bf215546Sopenharmony_ci_mesa_texture_storage_ms_memory(struct gl_context *ctx, GLuint dims, 7091bf215546Sopenharmony_ci struct gl_texture_object *texObj, 7092bf215546Sopenharmony_ci struct gl_memory_object *memObj, 7093bf215546Sopenharmony_ci GLenum target, GLsizei samples, 7094bf215546Sopenharmony_ci GLenum internalFormat, GLsizei width, 7095bf215546Sopenharmony_ci GLsizei height, GLsizei depth, 7096bf215546Sopenharmony_ci GLboolean fixedSampleLocations, 7097bf215546Sopenharmony_ci GLuint64 offset, const char* func) 7098bf215546Sopenharmony_ci{ 7099bf215546Sopenharmony_ci assert(memObj); 7100bf215546Sopenharmony_ci 7101bf215546Sopenharmony_ci texture_image_multisample(ctx, dims, texObj, memObj, target, samples, 7102bf215546Sopenharmony_ci internalFormat, width, height, depth, 7103bf215546Sopenharmony_ci fixedSampleLocations, GL_TRUE, offset, 7104bf215546Sopenharmony_ci func); 7105bf215546Sopenharmony_ci} 7106