Brian Paul | a8fcb79 | 2011-10-31 10:52:56 -0600 | [diff] [blame] | 1 | /* |
| 2 | * Mesa 3-D graphics library |
| 3 | * |
| 4 | * Copyright (C) 2011 VMware, Inc. All Rights Reserved. |
| 5 | * |
| 6 | * Permission is hereby granted, free of charge, to any person obtaining a |
| 7 | * copy of this software and associated documentation files (the "Software"), |
| 8 | * to deal in the Software without restriction, including without limitation |
| 9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| 10 | * and/or sell copies of the Software, and to permit persons to whom the |
| 11 | * Software is furnished to do so, subject to the following conditions: |
| 12 | * |
| 13 | * The above copyright notice and this permission notice shall be included |
| 14 | * in all copies or substantial portions of the Software. |
| 15 | * |
| 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| 17 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| 19 | * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN |
| 20 | * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
| 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| 22 | */ |
| 23 | |
| 24 | |
| 25 | /** |
| 26 | * \file texstorage.c |
| 27 | * GL_ARB_texture_storage functions |
| 28 | */ |
| 29 | |
| 30 | |
| 31 | |
| 32 | #include "glheader.h" |
| 33 | #include "context.h" |
| 34 | #include "enums.h" |
| 35 | #include "imports.h" |
| 36 | #include "macros.h" |
| 37 | #include "mfeatures.h" |
| 38 | #include "teximage.h" |
Brian Paul | 46751ed | 2012-08-21 20:22:27 -0600 | [diff] [blame] | 39 | #include "texobj.h" |
Brian Paul | a8fcb79 | 2011-10-31 10:52:56 -0600 | [diff] [blame] | 40 | #include "texstorage.h" |
| 41 | #include "mtypes.h" |
| 42 | |
| 43 | |
| 44 | |
| 45 | /** |
| 46 | * Check if the given texture target is a legal texture object target |
| 47 | * for a glTexStorage() command. |
| 48 | * This is a bit different than legal_teximage_target() when it comes |
| 49 | * to cube maps. |
| 50 | */ |
| 51 | static GLboolean |
| 52 | legal_texobj_target(struct gl_context *ctx, GLuint dims, GLenum target) |
| 53 | { |
| 54 | switch (dims) { |
| 55 | case 1: |
| 56 | switch (target) { |
| 57 | case GL_TEXTURE_1D: |
| 58 | case GL_PROXY_TEXTURE_1D: |
| 59 | return GL_TRUE; |
| 60 | default: |
| 61 | return GL_FALSE; |
| 62 | } |
| 63 | case 2: |
| 64 | switch (target) { |
| 65 | case GL_TEXTURE_2D: |
| 66 | case GL_PROXY_TEXTURE_2D: |
| 67 | return GL_TRUE; |
| 68 | case GL_TEXTURE_CUBE_MAP: |
| 69 | case GL_PROXY_TEXTURE_CUBE_MAP: |
| 70 | return ctx->Extensions.ARB_texture_cube_map; |
| 71 | case GL_TEXTURE_RECTANGLE: |
| 72 | case GL_PROXY_TEXTURE_RECTANGLE: |
| 73 | return ctx->Extensions.NV_texture_rectangle; |
| 74 | case GL_TEXTURE_1D_ARRAY: |
| 75 | case GL_PROXY_TEXTURE_1D_ARRAY: |
| 76 | return (ctx->Extensions.MESA_texture_array || |
| 77 | ctx->Extensions.EXT_texture_array); |
| 78 | default: |
| 79 | return GL_FALSE; |
| 80 | } |
| 81 | case 3: |
| 82 | switch (target) { |
| 83 | case GL_TEXTURE_3D: |
| 84 | case GL_PROXY_TEXTURE_3D: |
| 85 | return GL_TRUE; |
| 86 | case GL_TEXTURE_2D_ARRAY: |
| 87 | case GL_PROXY_TEXTURE_2D_ARRAY: |
| 88 | return (ctx->Extensions.MESA_texture_array || |
| 89 | ctx->Extensions.EXT_texture_array); |
Dave Airlie | e0e7e29 | 2012-11-03 20:41:08 +1000 | [diff] [blame] | 90 | case GL_TEXTURE_CUBE_MAP_ARRAY: |
| 91 | case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: |
| 92 | return ctx->Extensions.ARB_texture_cube_map_array; |
Brian Paul | a8fcb79 | 2011-10-31 10:52:56 -0600 | [diff] [blame] | 93 | default: |
| 94 | return GL_FALSE; |
| 95 | } |
| 96 | default: |
| 97 | _mesa_problem(ctx, "invalid dims=%u in legal_texobj_target()", dims); |
| 98 | return GL_FALSE; |
| 99 | } |
| 100 | } |
| 101 | |
| 102 | |
| 103 | /** |
| 104 | * Compute the size of the next mipmap level. |
| 105 | */ |
| 106 | static void |
| 107 | next_mipmap_level_size(GLenum target, |
| 108 | GLint *width, GLint *height, GLint *depth) |
| 109 | { |
| 110 | if (*width > 1) { |
| 111 | *width /= 2; |
| 112 | } |
| 113 | |
| 114 | if ((*height > 1) && (target != GL_TEXTURE_1D_ARRAY)) { |
| 115 | *height /= 2; |
| 116 | } |
| 117 | |
| 118 | if ((*depth > 1) && (target != GL_TEXTURE_2D_ARRAY)) { |
| 119 | *depth /= 2; |
| 120 | } |
| 121 | } |
| 122 | |
| 123 | |
Brian Paul | ff24ed0 | 2012-09-15 10:30:20 -0600 | [diff] [blame] | 124 | /** Helper to get a particular texture image in a texture object */ |
| 125 | static struct gl_texture_image * |
| 126 | get_tex_image(struct gl_context *ctx, |
| 127 | struct gl_texture_object *texObj, |
| 128 | GLuint face, GLuint level) |
| 129 | { |
| 130 | const GLenum faceTarget = |
| 131 | (texObj->Target == GL_TEXTURE_CUBE_MAP || |
| 132 | texObj->Target == GL_PROXY_TEXTURE_CUBE_MAP) |
| 133 | ? GL_TEXTURE_CUBE_MAP_POSITIVE_X + face : texObj->Target; |
| 134 | return _mesa_get_tex_image(ctx, texObj, faceTarget, level); |
| 135 | } |
| 136 | |
| 137 | |
| 138 | |
| 139 | static GLboolean |
| 140 | initialize_texture_fields(struct gl_context *ctx, |
| 141 | struct gl_texture_object *texObj, |
| 142 | GLint levels, |
| 143 | GLsizei width, GLsizei height, GLsizei depth, |
| 144 | GLenum internalFormat, gl_format texFormat) |
Brian Paul | a8fcb79 | 2011-10-31 10:52:56 -0600 | [diff] [blame] | 145 | { |
| 146 | const GLenum target = texObj->Target; |
Brian Paul | 46751ed | 2012-08-21 20:22:27 -0600 | [diff] [blame] | 147 | const GLuint numFaces = _mesa_num_tex_faces(target); |
Brian Paul | a8fcb79 | 2011-10-31 10:52:56 -0600 | [diff] [blame] | 148 | GLint level, levelWidth = width, levelHeight = height, levelDepth = depth; |
| 149 | GLuint face; |
| 150 | |
Brian Paul | a8fcb79 | 2011-10-31 10:52:56 -0600 | [diff] [blame] | 151 | /* Set up all the texture object's gl_texture_images */ |
| 152 | for (level = 0; level < levels; level++) { |
| 153 | for (face = 0; face < numFaces; face++) { |
Brian Paul | a8fcb79 | 2011-10-31 10:52:56 -0600 | [diff] [blame] | 154 | struct gl_texture_image *texImage = |
Brian Paul | ff24ed0 | 2012-09-15 10:30:20 -0600 | [diff] [blame] | 155 | get_tex_image(ctx, texObj, face, level); |
Brian Paul | a8fcb79 | 2011-10-31 10:52:56 -0600 | [diff] [blame] | 156 | |
| 157 | if (!texImage) { |
Brian Paul | ff24ed0 | 2012-09-15 10:30:20 -0600 | [diff] [blame] | 158 | _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage"); |
| 159 | return GL_FALSE; |
Brian Paul | a8fcb79 | 2011-10-31 10:52:56 -0600 | [diff] [blame] | 160 | } |
| 161 | |
Brian Paul | 892a254 | 2012-01-03 17:48:12 -0700 | [diff] [blame] | 162 | _mesa_init_teximage_fields(ctx, texImage, |
Brian Paul | a8fcb79 | 2011-10-31 10:52:56 -0600 | [diff] [blame] | 163 | levelWidth, levelHeight, levelDepth, |
| 164 | 0, internalFormat, texFormat); |
| 165 | } |
| 166 | |
| 167 | next_mipmap_level_size(target, &levelWidth, &levelHeight, &levelDepth); |
| 168 | } |
Brian Paul | ff24ed0 | 2012-09-15 10:30:20 -0600 | [diff] [blame] | 169 | return GL_TRUE; |
Brian Paul | a8fcb79 | 2011-10-31 10:52:56 -0600 | [diff] [blame] | 170 | } |
| 171 | |
| 172 | |
| 173 | /** |
| 174 | * Clear all fields of texture object to zeros. Used for proxy texture tests. |
Brian Paul | ff24ed0 | 2012-09-15 10:30:20 -0600 | [diff] [blame] | 175 | * Used for proxy texture tests (and to clean up when a texture memory |
| 176 | * allocation fails). |
Brian Paul | a8fcb79 | 2011-10-31 10:52:56 -0600 | [diff] [blame] | 177 | */ |
| 178 | static void |
Brian Paul | ff24ed0 | 2012-09-15 10:30:20 -0600 | [diff] [blame] | 179 | clear_texture_fields(struct gl_context *ctx, |
| 180 | struct gl_texture_object *texObj) |
Brian Paul | a8fcb79 | 2011-10-31 10:52:56 -0600 | [diff] [blame] | 181 | { |
| 182 | const GLenum target = texObj->Target; |
Brian Paul | 46751ed | 2012-08-21 20:22:27 -0600 | [diff] [blame] | 183 | const GLuint numFaces = _mesa_num_tex_faces(target); |
Brian Paul | a8fcb79 | 2011-10-31 10:52:56 -0600 | [diff] [blame] | 184 | GLint level; |
| 185 | GLuint face; |
| 186 | |
| 187 | for (level = 0; level < Elements(texObj->Image[0]); level++) { |
| 188 | for (face = 0; face < numFaces; face++) { |
Brian Paul | a8fcb79 | 2011-10-31 10:52:56 -0600 | [diff] [blame] | 189 | struct gl_texture_image *texImage = |
Brian Paul | ff24ed0 | 2012-09-15 10:30:20 -0600 | [diff] [blame] | 190 | get_tex_image(ctx, texObj, face, level); |
Brian Paul | a8fcb79 | 2011-10-31 10:52:56 -0600 | [diff] [blame] | 191 | |
| 192 | if (!texImage) { |
Brian Paul | ff24ed0 | 2012-09-15 10:30:20 -0600 | [diff] [blame] | 193 | _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage"); |
Brian Paul | a8fcb79 | 2011-10-31 10:52:56 -0600 | [diff] [blame] | 194 | return; |
| 195 | } |
| 196 | |
Brian Paul | 892a254 | 2012-01-03 17:48:12 -0700 | [diff] [blame] | 197 | _mesa_init_teximage_fields(ctx, texImage, |
Brian Paul | ff24ed0 | 2012-09-15 10:30:20 -0600 | [diff] [blame] | 198 | 0, 0, 0, 0, /* w, h, d, border */ |
| 199 | GL_NONE, MESA_FORMAT_NONE); |
Brian Paul | a8fcb79 | 2011-10-31 10:52:56 -0600 | [diff] [blame] | 200 | } |
| 201 | } |
| 202 | } |
| 203 | |
| 204 | |
| 205 | /** |
| 206 | * Do error checking for calls to glTexStorage1/2/3D(). |
| 207 | * If an error is found, record it with _mesa_error(), unless the target |
| 208 | * is a proxy texture. |
| 209 | * \return GL_TRUE if any error, GL_FALSE otherwise. |
| 210 | */ |
| 211 | static GLboolean |
| 212 | tex_storage_error_check(struct gl_context *ctx, GLuint dims, GLenum target, |
| 213 | GLsizei levels, GLenum internalformat, |
| 214 | GLsizei width, GLsizei height, GLsizei depth) |
| 215 | { |
Brian Paul | a8fcb79 | 2011-10-31 10:52:56 -0600 | [diff] [blame] | 216 | struct gl_texture_object *texObj; |
Brian Paul | 2e4fc54 | 2012-09-08 09:27:46 -0600 | [diff] [blame] | 217 | GLboolean legalFormat; |
| 218 | |
| 219 | /* check internal format - note that only sized formats are allowed */ |
| 220 | switch (internalformat) { |
| 221 | case GL_ALPHA: |
| 222 | case GL_LUMINANCE: |
| 223 | case GL_LUMINANCE_ALPHA: |
| 224 | case GL_INTENSITY: |
| 225 | case GL_RED: |
| 226 | case GL_RG: |
| 227 | case GL_RGB: |
| 228 | case GL_RGBA: |
| 229 | case GL_BGRA: |
| 230 | case GL_DEPTH_COMPONENT: |
| 231 | case GL_DEPTH_STENCIL: |
| 232 | case GL_COMPRESSED_ALPHA: |
| 233 | case GL_COMPRESSED_LUMINANCE_ALPHA: |
| 234 | case GL_COMPRESSED_LUMINANCE: |
| 235 | case GL_COMPRESSED_INTENSITY: |
| 236 | case GL_COMPRESSED_RGB: |
| 237 | case GL_COMPRESSED_RGBA: |
| 238 | case GL_COMPRESSED_SRGB: |
| 239 | case GL_COMPRESSED_SRGB_ALPHA: |
| 240 | case GL_COMPRESSED_SLUMINANCE: |
| 241 | case GL_COMPRESSED_SLUMINANCE_ALPHA: |
| 242 | case GL_RED_INTEGER: |
| 243 | case GL_GREEN_INTEGER: |
| 244 | case GL_BLUE_INTEGER: |
| 245 | case GL_ALPHA_INTEGER: |
| 246 | case GL_RGB_INTEGER: |
| 247 | case GL_RGBA_INTEGER: |
| 248 | case GL_BGR_INTEGER: |
| 249 | case GL_BGRA_INTEGER: |
| 250 | case GL_LUMINANCE_INTEGER_EXT: |
| 251 | case GL_LUMINANCE_ALPHA_INTEGER_EXT: |
| 252 | /* these unsized formats are illegal */ |
| 253 | legalFormat = GL_FALSE; |
| 254 | break; |
| 255 | default: |
| 256 | legalFormat = _mesa_base_tex_format(ctx, internalformat) > 0; |
| 257 | } |
| 258 | |
| 259 | if (!legalFormat) { |
| 260 | _mesa_error(ctx, GL_INVALID_ENUM, |
| 261 | "glTexStorage%uD(internalformat = %s)", dims, |
| 262 | _mesa_lookup_enum_by_nr(internalformat)); |
| 263 | return GL_TRUE; |
| 264 | } |
Brian Paul | a8fcb79 | 2011-10-31 10:52:56 -0600 | [diff] [blame] | 265 | |
| 266 | /* size check */ |
| 267 | if (width < 1 || height < 1 || depth < 1) { |
Brian Paul | 35c75f6 | 2012-09-08 09:33:13 -0600 | [diff] [blame] | 268 | _mesa_error(ctx, GL_INVALID_VALUE, |
| 269 | "glTexStorage%uD(width, height or depth < 1)", dims); |
Brian Paul | a8fcb79 | 2011-10-31 10:52:56 -0600 | [diff] [blame] | 270 | return GL_TRUE; |
| 271 | } |
| 272 | |
Brian Paul | a8fcb79 | 2011-10-31 10:52:56 -0600 | [diff] [blame] | 273 | /* target check */ |
| 274 | if (!legal_texobj_target(ctx, dims, target)) { |
| 275 | _mesa_error(ctx, GL_INVALID_ENUM, |
| 276 | "glTexStorage%uD(illegal target=%s)", |
| 277 | dims, _mesa_lookup_enum_by_nr(target)); |
| 278 | return GL_TRUE; |
| 279 | } |
| 280 | |
Brian Paul | 7dc76e9 | 2012-09-15 10:30:20 -0600 | [diff] [blame] | 281 | /* levels check */ |
| 282 | if (levels < 1) { |
| 283 | _mesa_error(ctx, GL_INVALID_VALUE, "glTexStorage%uD(levels < 1)", |
| 284 | dims); |
| 285 | return GL_TRUE; |
| 286 | } |
| 287 | |
| 288 | /* check levels against maximum (note different error than above) */ |
Brian Paul | db0136a | 2012-10-27 08:58:19 -0600 | [diff] [blame] | 289 | if (levels > (GLint) _mesa_max_texture_levels(ctx, target)) { |
Brian Paul | 35c75f6 | 2012-09-08 09:33:13 -0600 | [diff] [blame] | 290 | _mesa_error(ctx, GL_INVALID_OPERATION, |
| 291 | "glTexStorage%uD(levels too large)", dims); |
Brian Paul | a8fcb79 | 2011-10-31 10:52:56 -0600 | [diff] [blame] | 292 | return GL_TRUE; |
| 293 | } |
| 294 | |
| 295 | /* check levels against width/height/depth */ |
Marek Olšák | 985f2ae | 2012-11-11 15:25:55 +0100 | [diff] [blame] | 296 | if (levels > _mesa_get_tex_max_num_levels(target, width, height, depth)) { |
Brian Paul | 35c75f6 | 2012-09-08 09:33:13 -0600 | [diff] [blame] | 297 | _mesa_error(ctx, GL_INVALID_OPERATION, |
| 298 | "glTexStorage%uD(too many levels for max texture dimension)", |
| 299 | dims); |
Brian Paul | a8fcb79 | 2011-10-31 10:52:56 -0600 | [diff] [blame] | 300 | return GL_TRUE; |
| 301 | } |
| 302 | |
| 303 | /* non-default texture object check */ |
| 304 | texObj = _mesa_get_current_tex_object(ctx, target); |
Brian Paul | 35c75f6 | 2012-09-08 09:33:13 -0600 | [diff] [blame] | 305 | if (!texObj || (texObj->Name == 0)) { |
| 306 | _mesa_error(ctx, GL_INVALID_OPERATION, |
| 307 | "glTexStorage%uD(texture object 0)", dims); |
Brian Paul | a8fcb79 | 2011-10-31 10:52:56 -0600 | [diff] [blame] | 308 | return GL_TRUE; |
| 309 | } |
| 310 | |
| 311 | /* Check if texObj->Immutable is set */ |
| 312 | if (texObj->Immutable) { |
Brian Paul | 35c75f6 | 2012-09-08 09:33:13 -0600 | [diff] [blame] | 313 | _mesa_error(ctx, GL_INVALID_OPERATION, "glTexStorage%uD(immutable)", |
| 314 | dims); |
Brian Paul | a8fcb79 | 2011-10-31 10:52:56 -0600 | [diff] [blame] | 315 | return GL_TRUE; |
| 316 | } |
| 317 | |
| 318 | return GL_FALSE; |
| 319 | } |
| 320 | |
| 321 | |
| 322 | /** |
| 323 | * Helper used by _mesa_TexStorage1/2/3D(). |
| 324 | */ |
| 325 | static void |
| 326 | texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, |
| 327 | GLsizei width, GLsizei height, GLsizei depth) |
| 328 | { |
| 329 | struct gl_texture_object *texObj; |
Brian Paul | ff24ed0 | 2012-09-15 10:30:20 -0600 | [diff] [blame] | 330 | GLboolean sizeOK, dimensionsOK; |
Brian Paul | e6eaa85 | 2012-09-15 10:30:20 -0600 | [diff] [blame] | 331 | gl_format texFormat; |
Brian Paul | a8fcb79 | 2011-10-31 10:52:56 -0600 | [diff] [blame] | 332 | |
| 333 | GET_CURRENT_CONTEXT(ctx); |
| 334 | |
Brian Paul | 35c75f6 | 2012-09-08 09:33:13 -0600 | [diff] [blame] | 335 | if (tex_storage_error_check(ctx, dims, target, levels, |
| 336 | internalformat, width, height, depth)) { |
| 337 | return; /* error was recorded */ |
| 338 | } |
| 339 | |
Brian Paul | e6eaa85 | 2012-09-15 10:30:20 -0600 | [diff] [blame] | 340 | texObj = _mesa_get_current_tex_object(ctx, target); |
| 341 | assert(texObj); |
| 342 | |
| 343 | texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0, |
| 344 | internalformat, GL_NONE, GL_NONE); |
| 345 | assert(texFormat != MESA_FORMAT_NONE); |
| 346 | |
Brian Paul | ff24ed0 | 2012-09-15 10:30:20 -0600 | [diff] [blame] | 347 | /* check that width, height, depth are legal for the mipmap level */ |
| 348 | dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, 0, |
| 349 | width, height, depth, 0); |
| 350 | |
Brian Paul | e6eaa85 | 2012-09-15 10:30:20 -0600 | [diff] [blame] | 351 | sizeOK = ctx->Driver.TestProxyTexImage(ctx, target, 0, texFormat, |
Brian Paul | 35c75f6 | 2012-09-08 09:33:13 -0600 | [diff] [blame] | 352 | width, height, depth, 0); |
| 353 | |
Brian Paul | ff24ed0 | 2012-09-15 10:30:20 -0600 | [diff] [blame] | 354 | if (_mesa_is_proxy_texture(texObj->Target)) { |
| 355 | if (dimensionsOK && sizeOK) { |
| 356 | initialize_texture_fields(ctx, texObj, levels, width, height, depth, |
| 357 | internalformat, texFormat); |
Brian Paul | 35c75f6 | 2012-09-08 09:33:13 -0600 | [diff] [blame] | 358 | } |
| 359 | else { |
Brian Paul | ff24ed0 | 2012-09-15 10:30:20 -0600 | [diff] [blame] | 360 | /* clear all image fields for [levels] */ |
| 361 | clear_texture_fields(ctx, texObj); |
Brian Paul | 35c75f6 | 2012-09-08 09:33:13 -0600 | [diff] [blame] | 362 | } |
| 363 | } |
| 364 | else { |
Brian Paul | ff24ed0 | 2012-09-15 10:30:20 -0600 | [diff] [blame] | 365 | if (!dimensionsOK) { |
| 366 | _mesa_error(ctx, GL_INVALID_VALUE, |
| 367 | "glTexStorage%uD(invalid width, height or depth)", dims); |
| 368 | return; |
| 369 | } |
| 370 | |
| 371 | if (!sizeOK) { |
| 372 | _mesa_error(ctx, GL_OUT_OF_MEMORY, |
| 373 | "glTexStorage%uD(texture too large)", dims); |
| 374 | } |
| 375 | |
| 376 | assert(levels > 0); |
| 377 | assert(width > 0); |
| 378 | assert(height > 0); |
| 379 | assert(depth > 0); |
| 380 | |
| 381 | if (!initialize_texture_fields(ctx, texObj, levels, width, height, depth, |
| 382 | internalformat, texFormat)) { |
| 383 | return; |
| 384 | } |
| 385 | |
| 386 | /* Do actual texture memory allocation */ |
| 387 | if (!ctx->Driver.AllocTextureStorage(ctx, texObj, levels, |
| 388 | width, height, depth)) { |
| 389 | /* Reset the texture images' info to zeros. |
| 390 | * Strictly speaking, we probably don't have to do this since |
| 391 | * generating GL_OUT_OF_MEMORY can leave things in an undefined |
| 392 | * state but this puts things in a consistent state. |
| 393 | */ |
| 394 | clear_texture_fields(ctx, texObj); |
| 395 | _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage%uD", dims); |
| 396 | return; |
| 397 | } |
| 398 | |
| 399 | texObj->Immutable = GL_TRUE; |
Brian Paul | a8fcb79 | 2011-10-31 10:52:56 -0600 | [diff] [blame] | 400 | } |
Brian Paul | a8fcb79 | 2011-10-31 10:52:56 -0600 | [diff] [blame] | 401 | } |
| 402 | |
| 403 | |
| 404 | void GLAPIENTRY |
| 405 | _mesa_TexStorage1D(GLenum target, GLsizei levels, GLenum internalformat, |
| 406 | GLsizei width) |
| 407 | { |
| 408 | texstorage(1, target, levels, internalformat, width, 1, 1); |
| 409 | } |
| 410 | |
| 411 | |
| 412 | void GLAPIENTRY |
| 413 | _mesa_TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, |
| 414 | GLsizei width, GLsizei height) |
| 415 | { |
| 416 | texstorage(2, target, levels, internalformat, width, height, 1); |
| 417 | } |
| 418 | |
| 419 | |
| 420 | void GLAPIENTRY |
| 421 | _mesa_TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, |
| 422 | GLsizei width, GLsizei height, GLsizei depth) |
| 423 | { |
| 424 | texstorage(3, target, levels, internalformat, width, height, depth); |
| 425 | } |
| 426 | |
| 427 | |
| 428 | |
| 429 | /* |
| 430 | * Note: we don't support GL_EXT_direct_state_access and the spec says |
| 431 | * we don't need the following functions. However, glew checks for the |
| 432 | * presence of all six functions and will say that GL_ARB_texture_storage |
| 433 | * is not supported if these functions are missing. |
| 434 | */ |
| 435 | |
| 436 | |
| 437 | void GLAPIENTRY |
| 438 | _mesa_TextureStorage1DEXT(GLuint texture, GLenum target, GLsizei levels, |
| 439 | GLenum internalformat, |
| 440 | GLsizei width) |
| 441 | { |
| 442 | /* no-op */ |
| 443 | } |
| 444 | |
| 445 | |
| 446 | void GLAPIENTRY |
| 447 | _mesa_TextureStorage2DEXT(GLuint texture, GLenum target, GLsizei levels, |
| 448 | GLenum internalformat, |
| 449 | GLsizei width, GLsizei height) |
| 450 | { |
| 451 | /* no-op */ |
| 452 | } |
| 453 | |
| 454 | |
| 455 | |
| 456 | void GLAPIENTRY |
| 457 | _mesa_TextureStorage3DEXT(GLuint texture, GLenum target, GLsizei levels, |
| 458 | GLenum internalformat, |
| 459 | GLsizei width, GLsizei height, GLsizei depth) |
| 460 | { |
| 461 | /* no-op */ |
| 462 | } |