Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5564 | serge | 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 OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
||
20 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
||
21 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
||
22 | * OTHER DEALINGS IN THE SOFTWARE. |
||
23 | */ |
||
24 | |||
25 | |||
26 | /** |
||
27 | * \file texstorage.c |
||
28 | * GL_ARB_texture_storage functions |
||
29 | */ |
||
30 | |||
31 | |||
32 | |||
33 | #include "glheader.h" |
||
34 | #include "context.h" |
||
35 | #include "enums.h" |
||
36 | #include "imports.h" |
||
37 | #include "macros.h" |
||
38 | #include "teximage.h" |
||
39 | #include "texobj.h" |
||
40 | #include "mipmap.h" |
||
41 | #include "texstorage.h" |
||
42 | #include "textureview.h" |
||
43 | #include "mtypes.h" |
||
44 | #include "glformats.h" |
||
45 | #include "hash.h" |
||
46 | |||
47 | |||
48 | /** |
||
49 | * Check if the given texture target is a legal texture object target |
||
50 | * for a glTexStorage() command. |
||
51 | * This is a bit different than legal_teximage_target() when it comes |
||
52 | * to cube maps. |
||
53 | */ |
||
54 | static GLboolean |
||
55 | legal_texobj_target(struct gl_context *ctx, GLuint dims, GLenum target) |
||
56 | { |
||
57 | if (_mesa_is_gles3(ctx) |
||
58 | && target != GL_TEXTURE_2D |
||
59 | && target != GL_TEXTURE_CUBE_MAP |
||
60 | && target != GL_TEXTURE_3D |
||
61 | && target != GL_TEXTURE_2D_ARRAY) |
||
62 | return GL_FALSE; |
||
63 | |||
64 | switch (dims) { |
||
65 | case 1: |
||
66 | switch (target) { |
||
67 | case GL_TEXTURE_1D: |
||
68 | case GL_PROXY_TEXTURE_1D: |
||
69 | return GL_TRUE; |
||
70 | default: |
||
71 | return GL_FALSE; |
||
72 | } |
||
73 | case 2: |
||
74 | switch (target) { |
||
75 | case GL_TEXTURE_2D: |
||
76 | case GL_PROXY_TEXTURE_2D: |
||
77 | return GL_TRUE; |
||
78 | case GL_TEXTURE_CUBE_MAP: |
||
79 | case GL_PROXY_TEXTURE_CUBE_MAP: |
||
80 | return ctx->Extensions.ARB_texture_cube_map; |
||
81 | case GL_TEXTURE_RECTANGLE: |
||
82 | case GL_PROXY_TEXTURE_RECTANGLE: |
||
83 | return ctx->Extensions.NV_texture_rectangle; |
||
84 | case GL_TEXTURE_1D_ARRAY: |
||
85 | case GL_PROXY_TEXTURE_1D_ARRAY: |
||
86 | return ctx->Extensions.EXT_texture_array; |
||
87 | default: |
||
88 | return GL_FALSE; |
||
89 | } |
||
90 | case 3: |
||
91 | switch (target) { |
||
92 | case GL_TEXTURE_3D: |
||
93 | case GL_PROXY_TEXTURE_3D: |
||
94 | return GL_TRUE; |
||
95 | case GL_TEXTURE_2D_ARRAY: |
||
96 | case GL_PROXY_TEXTURE_2D_ARRAY: |
||
97 | return ctx->Extensions.EXT_texture_array; |
||
98 | case GL_TEXTURE_CUBE_MAP_ARRAY: |
||
99 | case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: |
||
100 | return ctx->Extensions.ARB_texture_cube_map_array; |
||
101 | default: |
||
102 | return GL_FALSE; |
||
103 | } |
||
104 | default: |
||
105 | _mesa_problem(ctx, "invalid dims=%u in legal_texobj_target()", dims); |
||
106 | return GL_FALSE; |
||
107 | } |
||
108 | } |
||
109 | |||
110 | |||
111 | /** Helper to get a particular texture image in a texture object */ |
||
112 | static struct gl_texture_image * |
||
113 | get_tex_image(struct gl_context *ctx, |
||
114 | struct gl_texture_object *texObj, |
||
115 | GLuint face, GLuint level) |
||
116 | { |
||
117 | const GLenum faceTarget = |
||
118 | (texObj->Target == GL_TEXTURE_CUBE_MAP || |
||
119 | texObj->Target == GL_PROXY_TEXTURE_CUBE_MAP) |
||
120 | ? GL_TEXTURE_CUBE_MAP_POSITIVE_X + face : texObj->Target; |
||
121 | return _mesa_get_tex_image(ctx, texObj, faceTarget, level); |
||
122 | } |
||
123 | |||
124 | |||
125 | |||
126 | static GLboolean |
||
127 | initialize_texture_fields(struct gl_context *ctx, |
||
128 | struct gl_texture_object *texObj, |
||
129 | GLint levels, |
||
130 | GLsizei width, GLsizei height, GLsizei depth, |
||
131 | GLenum internalFormat, mesa_format texFormat) |
||
132 | { |
||
133 | const GLenum target = texObj->Target; |
||
134 | const GLuint numFaces = _mesa_num_tex_faces(target); |
||
135 | GLint level, levelWidth = width, levelHeight = height, levelDepth = depth; |
||
136 | GLuint face; |
||
137 | |||
138 | /* Set up all the texture object's gl_texture_images */ |
||
139 | for (level = 0; level < levels; level++) { |
||
140 | for (face = 0; face < numFaces; face++) { |
||
141 | struct gl_texture_image *texImage = |
||
142 | get_tex_image(ctx, texObj, face, level); |
||
143 | |||
144 | if (!texImage) { |
||
145 | _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage"); |
||
146 | return GL_FALSE; |
||
147 | } |
||
148 | |||
149 | _mesa_init_teximage_fields(ctx, texImage, |
||
150 | levelWidth, levelHeight, levelDepth, |
||
151 | 0, internalFormat, texFormat); |
||
152 | } |
||
153 | |||
154 | _mesa_next_mipmap_level_size(target, 0, levelWidth, levelHeight, levelDepth, |
||
155 | &levelWidth, &levelHeight, &levelDepth); |
||
156 | } |
||
157 | return GL_TRUE; |
||
158 | } |
||
159 | |||
160 | |||
161 | /** |
||
162 | * Clear all fields of texture object to zeros. Used for proxy texture tests |
||
163 | * and to clean up when a texture memory allocation fails. |
||
164 | */ |
||
165 | static void |
||
166 | clear_texture_fields(struct gl_context *ctx, |
||
167 | struct gl_texture_object *texObj) |
||
168 | { |
||
169 | const GLenum target = texObj->Target; |
||
170 | const GLuint numFaces = _mesa_num_tex_faces(target); |
||
171 | GLint level; |
||
172 | GLuint face; |
||
173 | |||
174 | for (level = 0; level < ARRAY_SIZE(texObj->Image[0]); level++) { |
||
175 | for (face = 0; face < numFaces; face++) { |
||
176 | struct gl_texture_image *texImage = |
||
177 | get_tex_image(ctx, texObj, face, level); |
||
178 | |||
179 | if (!texImage) { |
||
180 | _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage"); |
||
181 | return; |
||
182 | } |
||
183 | |||
184 | _mesa_init_teximage_fields(ctx, texImage, |
||
185 | 0, 0, 0, 0, /* w, h, d, border */ |
||
186 | GL_NONE, MESA_FORMAT_NONE); |
||
187 | } |
||
188 | } |
||
189 | } |
||
190 | |||
191 | |||
192 | GLboolean |
||
193 | _mesa_is_legal_tex_storage_format(struct gl_context *ctx, GLenum internalformat) |
||
194 | { |
||
195 | /* check internal format - note that only sized formats are allowed */ |
||
196 | switch (internalformat) { |
||
197 | case GL_ALPHA: |
||
198 | case GL_LUMINANCE: |
||
199 | case GL_LUMINANCE_ALPHA: |
||
200 | case GL_INTENSITY: |
||
201 | case GL_RED: |
||
202 | case GL_RG: |
||
203 | case GL_RGB: |
||
204 | case GL_RGBA: |
||
205 | case GL_BGRA: |
||
206 | case GL_DEPTH_COMPONENT: |
||
207 | case GL_DEPTH_STENCIL: |
||
208 | case GL_COMPRESSED_ALPHA: |
||
209 | case GL_COMPRESSED_LUMINANCE_ALPHA: |
||
210 | case GL_COMPRESSED_LUMINANCE: |
||
211 | case GL_COMPRESSED_INTENSITY: |
||
212 | case GL_COMPRESSED_RGB: |
||
213 | case GL_COMPRESSED_RGBA: |
||
214 | case GL_COMPRESSED_SRGB: |
||
215 | case GL_COMPRESSED_SRGB_ALPHA: |
||
216 | case GL_COMPRESSED_SLUMINANCE: |
||
217 | case GL_COMPRESSED_SLUMINANCE_ALPHA: |
||
218 | case GL_RED_INTEGER: |
||
219 | case GL_GREEN_INTEGER: |
||
220 | case GL_BLUE_INTEGER: |
||
221 | case GL_ALPHA_INTEGER: |
||
222 | case GL_RGB_INTEGER: |
||
223 | case GL_RGBA_INTEGER: |
||
224 | case GL_BGR_INTEGER: |
||
225 | case GL_BGRA_INTEGER: |
||
226 | case GL_LUMINANCE_INTEGER_EXT: |
||
227 | case GL_LUMINANCE_ALPHA_INTEGER_EXT: |
||
228 | /* these unsized formats are illegal */ |
||
229 | return GL_FALSE; |
||
230 | default: |
||
231 | return _mesa_base_tex_format(ctx, internalformat) > 0; |
||
232 | } |
||
233 | } |
||
234 | |||
235 | /** |
||
236 | * Default ctx->Driver.AllocTextureStorage() handler. |
||
237 | * |
||
238 | * The driver can override this with a more specific implementation if it |
||
239 | * desires, but this can be used to get the texture images allocated using the |
||
240 | * usual texture image handling code. The immutability of |
||
241 | * GL_ARB_texture_storage texture layouts is handled by texObj->Immutable |
||
242 | * checks at glTexImage* time. |
||
243 | */ |
||
244 | GLboolean |
||
245 | _mesa_AllocTextureStorage_sw(struct gl_context *ctx, |
||
246 | struct gl_texture_object *texObj, |
||
247 | GLsizei levels, GLsizei width, |
||
248 | GLsizei height, GLsizei depth) |
||
249 | { |
||
250 | const int numFaces = _mesa_num_tex_faces(texObj->Target); |
||
251 | int face; |
||
252 | int level; |
||
253 | |||
254 | (void) width; |
||
255 | (void) height; |
||
256 | (void) depth; |
||
257 | |||
258 | for (face = 0; face < numFaces; face++) { |
||
259 | for (level = 0; level < levels; level++) { |
||
260 | struct gl_texture_image *const texImage = texObj->Image[face][level]; |
||
261 | if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) |
||
262 | return GL_FALSE; |
||
263 | } |
||
264 | } |
||
265 | |||
266 | return GL_TRUE; |
||
267 | } |
||
268 | |||
269 | |||
270 | /** |
||
271 | * Do error checking for calls to glTexStorage1/2/3D(). |
||
272 | * If an error is found, record it with _mesa_error(), unless the target |
||
273 | * is a proxy texture. |
||
274 | * \return GL_TRUE if any error, GL_FALSE otherwise. |
||
275 | */ |
||
276 | static GLboolean |
||
277 | tex_storage_error_check(struct gl_context *ctx, |
||
278 | struct gl_texture_object *texObj, |
||
279 | GLuint dims, GLenum target, |
||
280 | GLsizei levels, GLenum internalformat, |
||
281 | GLsizei width, GLsizei height, GLsizei depth, |
||
282 | bool dsa) |
||
283 | { |
||
284 | const char* suffix = dsa ? "ture" : ""; |
||
285 | |||
286 | /* Legal format checking has been moved to texstorage and texturestorage in |
||
287 | * order to allow meta functions to use legacy formats. */ |
||
288 | |||
289 | /* size check */ |
||
290 | if (width < 1 || height < 1 || depth < 1) { |
||
291 | _mesa_error(ctx, GL_INVALID_VALUE, |
||
292 | "glTex%sStorage%uD(width, height or depth < 1)", |
||
293 | suffix, dims); |
||
294 | return GL_TRUE; |
||
295 | } |
||
296 | |||
297 | /* From section 3.8.6, page 146 of OpenGL ES 3.0 spec: |
||
298 | * |
||
299 | * "The ETC2/EAC texture compression algorithm supports only |
||
300 | * two-dimensional images. If internalformat is an ETC2/EAC format, |
||
301 | * CompressedTexImage3D will generate an INVALID_OPERATION error if |
||
302 | * target is not TEXTURE_2D_ARRAY." |
||
303 | * |
||
304 | * This should also be applicable for glTexStorage3D(). |
||
305 | */ |
||
306 | if (_mesa_is_compressed_format(ctx, internalformat) |
||
307 | && !_mesa_target_can_be_compressed(ctx, target, internalformat)) { |
||
308 | _mesa_error(ctx, _mesa_is_desktop_gl(ctx)? |
||
309 | GL_INVALID_ENUM : GL_INVALID_OPERATION, |
||
310 | "glTex%sStorage%dD(internalformat = %s)", suffix, dims, |
||
311 | _mesa_lookup_enum_by_nr(internalformat)); |
||
312 | } |
||
313 | |||
314 | /* levels check */ |
||
315 | if (levels < 1) { |
||
316 | _mesa_error(ctx, GL_INVALID_VALUE, "glTex%sStorage%uD(levels < 1)", |
||
317 | suffix, dims); |
||
318 | return GL_TRUE; |
||
319 | } |
||
320 | |||
321 | /* check levels against maximum (note different error than above) */ |
||
322 | if (levels > (GLint) _mesa_max_texture_levels(ctx, target)) { |
||
323 | _mesa_error(ctx, GL_INVALID_OPERATION, |
||
324 | "glTex%sStorage%uD(levels too large)", |
||
325 | suffix, dims); |
||
326 | return GL_TRUE; |
||
327 | } |
||
328 | |||
329 | /* check levels against width/height/depth */ |
||
330 | if (levels > _mesa_get_tex_max_num_levels(target, width, height, depth)) { |
||
331 | _mesa_error(ctx, GL_INVALID_OPERATION, |
||
332 | "glTex%sStorage%uD(too many levels" |
||
333 | " for max texture dimension)", |
||
334 | suffix, dims); |
||
335 | return GL_TRUE; |
||
336 | } |
||
337 | |||
338 | /* non-default texture object check */ |
||
339 | if (!_mesa_is_proxy_texture(target) && (!texObj || (texObj->Name == 0))) { |
||
340 | _mesa_error(ctx, GL_INVALID_OPERATION, |
||
341 | "glTex%sStorage%uD(texture object 0)", |
||
342 | suffix, dims); |
||
343 | return GL_TRUE; |
||
344 | } |
||
345 | |||
346 | /* Check if texObj->Immutable is set */ |
||
347 | if (!_mesa_is_proxy_texture(target) && texObj->Immutable) { |
||
348 | _mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sStorage%uD(immutable)", |
||
349 | suffix, dims); |
||
350 | return GL_TRUE; |
||
351 | } |
||
352 | |||
353 | /* additional checks for depth textures */ |
||
354 | if (!_mesa_legal_texture_base_format_for_target(ctx, target, internalformat, |
||
355 | dims, dsa ? |
||
356 | "glTextureStorage" : |
||
357 | "glTexStorage")) |
||
358 | return GL_TRUE; |
||
359 | |||
360 | return GL_FALSE; |
||
361 | } |
||
362 | |||
363 | |||
364 | /** |
||
365 | * Helper that does the storage allocation for _mesa_TexStorage1/2/3D() |
||
366 | * and _mesa_TextureStorage1/2/3D(). |
||
367 | */ |
||
368 | void |
||
369 | _mesa_texture_storage(struct gl_context *ctx, GLuint dims, |
||
370 | struct gl_texture_object *texObj, |
||
371 | GLenum target, GLsizei levels, |
||
372 | GLenum internalformat, GLsizei width, |
||
373 | GLsizei height, GLsizei depth, bool dsa) |
||
374 | { |
||
375 | GLboolean sizeOK, dimensionsOK; |
||
376 | mesa_format texFormat; |
||
377 | const char* suffix = dsa ? "ture" : ""; |
||
378 | |||
379 | assert(texObj); |
||
380 | |||
381 | if (tex_storage_error_check(ctx, texObj, dims, target, levels, |
||
382 | internalformat, width, height, depth, dsa)) { |
||
383 | return; /* error was recorded */ |
||
384 | } |
||
385 | |||
386 | |||
387 | texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0, |
||
388 | internalformat, GL_NONE, GL_NONE); |
||
389 | assert(texFormat != MESA_FORMAT_NONE); |
||
390 | |||
391 | /* check that width, height, depth are legal for the mipmap level */ |
||
392 | dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, 0, |
||
393 | width, height, depth, 0); |
||
394 | |||
395 | sizeOK = ctx->Driver.TestProxyTexImage(ctx, target, 0, texFormat, |
||
396 | width, height, depth, 0); |
||
397 | |||
398 | if (_mesa_is_proxy_texture(target)) { |
||
399 | if (dimensionsOK && sizeOK) { |
||
400 | initialize_texture_fields(ctx, texObj, levels, width, height, depth, |
||
401 | internalformat, texFormat); |
||
402 | } |
||
403 | else { |
||
404 | /* clear all image fields for [levels] */ |
||
405 | clear_texture_fields(ctx, texObj); |
||
406 | } |
||
407 | } |
||
408 | else { |
||
409 | if (!dimensionsOK) { |
||
410 | _mesa_error(ctx, GL_INVALID_VALUE, |
||
411 | "glTex%sStorage%uD(invalid width, height or depth)", |
||
412 | suffix, dims); |
||
413 | return; |
||
414 | } |
||
415 | |||
416 | if (!sizeOK) { |
||
417 | _mesa_error(ctx, GL_OUT_OF_MEMORY, |
||
418 | "glTex%sStorage%uD(texture too large)", |
||
419 | suffix, dims); |
||
420 | } |
||
421 | |||
422 | assert(levels > 0); |
||
423 | assert(width > 0); |
||
424 | assert(height > 0); |
||
425 | assert(depth > 0); |
||
426 | |||
427 | if (!initialize_texture_fields(ctx, texObj, levels, width, height, depth, |
||
428 | internalformat, texFormat)) { |
||
429 | return; |
||
430 | } |
||
431 | |||
432 | /* Do actual texture memory allocation */ |
||
433 | if (!ctx->Driver.AllocTextureStorage(ctx, texObj, levels, |
||
434 | width, height, depth)) { |
||
435 | /* Reset the texture images' info to zeros. |
||
436 | * Strictly speaking, we probably don't have to do this since |
||
437 | * generating GL_OUT_OF_MEMORY can leave things in an undefined |
||
438 | * state but this puts things in a consistent state. |
||
439 | */ |
||
440 | clear_texture_fields(ctx, texObj); |
||
441 | _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTex%sStorage%uD", |
||
442 | suffix, dims); |
||
443 | return; |
||
444 | } |
||
445 | |||
446 | _mesa_set_texture_view_state(ctx, texObj, target, levels); |
||
447 | |||
448 | } |
||
449 | } |
||
450 | |||
451 | /** |
||
452 | * Helper used by _mesa_TexStorage1/2/3D(). |
||
453 | */ |
||
454 | static void |
||
455 | texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, |
||
456 | GLsizei width, GLsizei height, GLsizei depth) |
||
457 | { |
||
458 | struct gl_texture_object *texObj; |
||
459 | GET_CURRENT_CONTEXT(ctx); |
||
460 | |||
461 | /* target check */ |
||
462 | /* This is done here so that _mesa_texture_storage can receive unsized |
||
463 | * formats. */ |
||
464 | if (!legal_texobj_target(ctx, dims, target)) { |
||
465 | _mesa_error(ctx, GL_INVALID_ENUM, |
||
466 | "glTexStorage%uD(illegal target=%s)", |
||
467 | dims, _mesa_lookup_enum_by_nr(target)); |
||
468 | return; |
||
469 | } |
||
470 | |||
471 | if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) |
||
472 | _mesa_debug(ctx, "glTexStorage%uD %s %d %s %d %d %d\n", |
||
473 | dims, |
||
474 | _mesa_lookup_enum_by_nr(target), levels, |
||
475 | _mesa_lookup_enum_by_nr(internalformat), |
||
476 | width, height, depth); |
||
477 | /* Check the format to make sure it is sized. */ |
||
478 | if (!_mesa_is_legal_tex_storage_format(ctx, internalformat)) { |
||
479 | _mesa_error(ctx, GL_INVALID_ENUM, |
||
480 | "glTexStorage%uD(internalformat = %s)", dims, |
||
481 | _mesa_lookup_enum_by_nr(internalformat)); |
||
482 | return; |
||
483 | } |
||
484 | |||
485 | texObj = _mesa_get_current_tex_object(ctx, target); |
||
486 | if (!texObj) |
||
487 | return; |
||
488 | |||
489 | _mesa_texture_storage(ctx, dims, texObj, target, levels, |
||
490 | internalformat, width, height, depth, false); |
||
491 | } |
||
492 | |||
493 | /** |
||
494 | * Helper used by _mesa_TextureStorage1/2/3D(). |
||
495 | */ |
||
496 | static void |
||
497 | texturestorage(GLuint dims, GLuint texture, GLsizei levels, |
||
498 | GLenum internalformat, GLsizei width, GLsizei height, |
||
499 | GLsizei depth) |
||
500 | { |
||
501 | struct gl_texture_object *texObj; |
||
502 | GET_CURRENT_CONTEXT(ctx); |
||
503 | |||
504 | if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) |
||
505 | _mesa_debug(ctx, "glTextureStorage%uD %d %d %s %d %d %d\n", |
||
506 | dims, texture, levels, |
||
507 | _mesa_lookup_enum_by_nr(internalformat), |
||
508 | width, height, depth); |
||
509 | |||
510 | if (!ctx->Extensions.ARB_direct_state_access) { |
||
511 | _mesa_error(ctx, GL_INVALID_OPERATION, |
||
512 | "glTextureStorage%uD(GL_ARB_direct_state_access " |
||
513 | "is not supported)", dims); |
||
514 | return; |
||
515 | } |
||
516 | |||
517 | /* Check the format to make sure it is sized. */ |
||
518 | if (!_mesa_is_legal_tex_storage_format(ctx, internalformat)) { |
||
519 | _mesa_error(ctx, GL_INVALID_ENUM, |
||
520 | "glTextureStorage%uD(internalformat = %s)", dims, |
||
521 | _mesa_lookup_enum_by_nr(internalformat)); |
||
522 | return; |
||
523 | } |
||
524 | |||
525 | /* Get the texture object by Name. */ |
||
526 | texObj = _mesa_lookup_texture(ctx, texture); |
||
527 | if (!texObj) { |
||
528 | _mesa_error(ctx, GL_INVALID_OPERATION, |
||
529 | "glTextureStorage%uD(texture = %d)", dims, texture); |
||
530 | return; |
||
531 | } |
||
532 | |||
533 | /* target check */ |
||
534 | /* This is done here so that _mesa_texture_storage can receive unsized |
||
535 | * formats. */ |
||
536 | if (!legal_texobj_target(ctx, dims, texObj->Target)) { |
||
537 | _mesa_error(ctx, GL_INVALID_ENUM, |
||
538 | "glTextureStorage%uD(illegal target=%s)", |
||
539 | dims, _mesa_lookup_enum_by_nr(texObj->Target)); |
||
540 | return; |
||
541 | } |
||
542 | |||
543 | _mesa_texture_storage(ctx, dims, texObj, texObj->Target, |
||
544 | levels, internalformat, width, height, depth, true); |
||
545 | } |
||
546 | |||
547 | void GLAPIENTRY |
||
548 | _mesa_TexStorage1D(GLenum target, GLsizei levels, GLenum internalformat, |
||
549 | GLsizei width) |
||
550 | { |
||
551 | texstorage(1, target, levels, internalformat, width, 1, 1); |
||
552 | } |
||
553 | |||
554 | |||
555 | void GLAPIENTRY |
||
556 | _mesa_TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, |
||
557 | GLsizei width, GLsizei height) |
||
558 | { |
||
559 | texstorage(2, target, levels, internalformat, width, height, 1); |
||
560 | } |
||
561 | |||
562 | |||
563 | void GLAPIENTRY |
||
564 | _mesa_TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, |
||
565 | GLsizei width, GLsizei height, GLsizei depth) |
||
566 | { |
||
567 | texstorage(3, target, levels, internalformat, width, height, depth); |
||
568 | } |
||
569 | |||
570 | void GLAPIENTRY |
||
571 | _mesa_TextureStorage1D(GLuint texture, GLsizei levels, GLenum internalformat, |
||
572 | GLsizei width) |
||
573 | { |
||
574 | texturestorage(1, texture, levels, internalformat, width, 1, 1); |
||
575 | } |
||
576 | |||
577 | |||
578 | void GLAPIENTRY |
||
579 | _mesa_TextureStorage2D(GLuint texture, GLsizei levels, |
||
580 | GLenum internalformat, |
||
581 | GLsizei width, GLsizei height) |
||
582 | { |
||
583 | texturestorage(2, texture, levels, internalformat, width, height, 1); |
||
584 | } |
||
585 | |||
586 | void GLAPIENTRY |
||
587 | _mesa_TextureStorage3D(GLuint texture, GLsizei levels, GLenum internalformat, |
||
588 | GLsizei width, GLsizei height, GLsizei depth) |
||
589 | { |
||
590 | texturestorage(3, texture, levels, internalformat, width, height, depth); |
||
591 | } |
||
592 | |||
593 | |||
594 | /* |
||
595 | * Note: we don't support GL_EXT_direct_state_access and the spec says |
||
596 | * we don't need the following functions. However, glew checks for the |
||
597 | * presence of all six functions and will say that GL_ARB_texture_storage |
||
598 | * is not supported if these functions are missing. |
||
599 | */ |
||
600 | |||
601 | |||
602 | void GLAPIENTRY |
||
603 | _mesa_TextureStorage1DEXT(GLuint texture, GLenum target, GLsizei levels, |
||
604 | GLenum internalformat, |
||
605 | GLsizei width) |
||
606 | { |
||
607 | GET_CURRENT_CONTEXT(ctx); |
||
608 | |||
609 | (void) texture; |
||
610 | (void) target; |
||
611 | (void) levels; |
||
612 | (void) internalformat; |
||
613 | (void) width; |
||
614 | |||
615 | _mesa_error(ctx, GL_INVALID_OPERATION, |
||
616 | "glTextureStorage1DEXT not supported"); |
||
617 | } |
||
618 | |||
619 | |||
620 | void GLAPIENTRY |
||
621 | _mesa_TextureStorage2DEXT(GLuint texture, GLenum target, GLsizei levels, |
||
622 | GLenum internalformat, |
||
623 | GLsizei width, GLsizei height) |
||
624 | { |
||
625 | GET_CURRENT_CONTEXT(ctx); |
||
626 | |||
627 | (void) texture; |
||
628 | (void) target; |
||
629 | (void) levels; |
||
630 | (void) internalformat; |
||
631 | (void) width; |
||
632 | (void) height; |
||
633 | |||
634 | _mesa_error(ctx, GL_INVALID_OPERATION, |
||
635 | "glTextureStorage2DEXT not supported"); |
||
636 | } |
||
637 | |||
638 | |||
639 | |||
640 | void GLAPIENTRY |
||
641 | _mesa_TextureStorage3DEXT(GLuint texture, GLenum target, GLsizei levels, |
||
642 | GLenum internalformat, |
||
643 | GLsizei width, GLsizei height, GLsizei depth) |
||
644 | { |
||
645 | GET_CURRENT_CONTEXT(ctx); |
||
646 | |||
647 | (void) texture; |
||
648 | (void) target; |
||
649 | (void) levels; |
||
650 | (void) internalformat; |
||
651 | (void) width; |
||
652 | (void) height; |
||
653 | (void) depth; |
||
654 | |||
655 | _mesa_error(ctx, GL_INVALID_OPERATION, |
||
656 | "glTextureStorage3DEXT not supported"); |
||
657 | }>>>>>>>>>>>> |