* OTHER DEALINGS IN THE SOFTWARE.
*/
-
/**
* \file texstorage.c
* GL_ARB_texture_storage functions
*/
-
-
#include "glheader.h"
#include "context.h"
#include "enums.h"
/** Helper to get a particular texture image in a texture object */
static struct gl_texture_image *
-get_tex_image(struct gl_context *ctx,
+get_tex_image(struct gl_context *ctx,
struct gl_texture_object *texObj,
GLuint face, GLuint level)
{
0, internalFormat, texFormat);
}
- _mesa_next_mipmap_level_size(target, 0, levelWidth, levelHeight, levelDepth,
+ _mesa_next_mipmap_level_size(target, 0,
+ levelWidth, levelHeight, levelDepth,
&levelWidth, &levelHeight, &levelDepth);
}
return GL_TRUE;
return;
}
- _mesa_init_teximage_fields(ctx, texImage,
- 0, 0, 0, 0, /* w, h, d, border */
- GL_NONE, MESA_FORMAT_NONE);
+ _mesa_clear_texture_image(ctx, texImage);
}
}
}
+/**
+ * Update/re-validate framebuffer object.
+ */
+static void
+update_fbo_texture(struct gl_context *ctx, struct gl_texture_object *texObj)
+{
+ const unsigned numFaces = _mesa_num_tex_faces(texObj->Target);
+ for (int level = 0; level < ARRAY_SIZE(texObj->Image[0]); level++) {
+ for (unsigned face = 0; face < numFaces; face++)
+ _mesa_update_fbo_texture(ctx, texObj, face, level);
+ }
+}
+
+
GLboolean
-_mesa_is_legal_tex_storage_format(struct gl_context *ctx, GLenum internalformat)
+_mesa_is_legal_tex_storage_format(const struct gl_context *ctx,
+ GLenum internalformat)
{
/* check internal format - note that only sized formats are allowed */
switch (internalformat) {
}
}
+
/**
* Default ctx->Driver.AllocTextureStorage() handler.
*
* order to allow meta functions to use legacy formats. */
/* size check */
- if (width < 1 || height < 1 || depth < 1) {
+ if (!_mesa_valid_tex_storage_dim(width, height, depth)) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glTex%sStorage%uD(width, height or depth < 1)",
suffix, dims);
return GL_TRUE;
- }
-
- /* From section 3.8.6, page 146 of OpenGL ES 3.0 spec:
- *
- * "The ETC2/EAC texture compression algorithm supports only
- * two-dimensional images. If internalformat is an ETC2/EAC format,
- * CompressedTexImage3D will generate an INVALID_OPERATION error if
- * target is not TEXTURE_2D_ARRAY."
- *
- * This should also be applicable for glTexStorage3D().
- */
- if (_mesa_is_compressed_format(ctx, internalformat)
- && !_mesa_target_can_be_compressed(ctx, target, internalformat)) {
- _mesa_error(ctx, _mesa_is_desktop_gl(ctx)?
- GL_INVALID_ENUM : GL_INVALID_OPERATION,
+ }
+
+ if (_mesa_is_compressed_format(ctx, internalformat)) {
+ GLenum err;
+ if (!_mesa_target_can_be_compressed(ctx, target, internalformat, &err)) {
+ _mesa_error(ctx, err,
"glTex%sStorage%dD(internalformat = %s)", suffix, dims,
- _mesa_lookup_enum_by_nr(internalformat));
- return GL_TRUE;
+ _mesa_enum_to_string(internalformat));
+ return GL_TRUE;
+ }
}
/* levels check */
_mesa_error(ctx, GL_INVALID_VALUE, "glTex%sStorage%uD(levels < 1)",
suffix, dims);
return GL_TRUE;
- }
+ }
/* check levels against maximum (note different error than above) */
if (levels > (GLint) _mesa_max_texture_levels(ctx, target)) {
}
/* additional checks for depth textures */
- if (!_mesa_legal_texture_base_format_for_target(ctx, target, internalformat,
- dims, dsa ?
- "glTextureStorage" :
- "glTexStorage"))
+ if (!_mesa_legal_texture_base_format_for_target(ctx, target, internalformat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sStorage%uD(bad target for texture)",
+ suffix, dims);
return GL_TRUE;
+ }
return GL_FALSE;
}
return; /* error was recorded */
}
-
texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0,
internalformat, GL_NONE, GL_NONE);
assert(texFormat != MESA_FORMAT_NONE);
dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, 0,
width, height, depth, 0);
- sizeOK = ctx->Driver.TestProxyTexImage(ctx, target, 0, texFormat,
- width, height, depth, 0);
+ sizeOK = ctx->Driver.TestProxyTexImage(ctx, target, levels, 0, texFormat,
+ 1, width, height, depth);
if (_mesa_is_proxy_texture(target)) {
if (dimensionsOK && sizeOK) {
_mesa_set_texture_view_state(ctx, texObj, target, levels);
+ update_fbo_texture(ctx, texObj);
}
}
+
/**
* Helper used by _mesa_TexStorage1/2/3D().
*/
struct gl_texture_object *texObj;
GET_CURRENT_CONTEXT(ctx);
- /* target check */
- /* This is done here so that _mesa_texture_storage can receive unsized
- * formats. */
+ /* Check target. This is done here so that _mesa_texture_storage
+ * can receive unsized formats.
+ */
if (!legal_texobj_target(ctx, dims, target)) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glTexStorage%uD(illegal target=%s)",
- dims, _mesa_lookup_enum_by_nr(target));
+ dims, _mesa_enum_to_string(target));
return;
}
if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
_mesa_debug(ctx, "glTexStorage%uD %s %d %s %d %d %d\n",
dims,
- _mesa_lookup_enum_by_nr(target), levels,
- _mesa_lookup_enum_by_nr(internalformat),
+ _mesa_enum_to_string(target), levels,
+ _mesa_enum_to_string(internalformat),
width, height, depth);
+
/* Check the format to make sure it is sized. */
if (!_mesa_is_legal_tex_storage_format(ctx, internalformat)) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glTexStorage%uD(internalformat = %s)", dims,
- _mesa_lookup_enum_by_nr(internalformat));
+ _mesa_enum_to_string(internalformat));
return;
}
internalformat, width, height, depth, false);
}
+
/**
* Helper used by _mesa_TextureStorage1/2/3D().
*/
if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
_mesa_debug(ctx, "glTextureStorage%uD %d %d %s %d %d %d\n",
dims, texture, levels,
- _mesa_lookup_enum_by_nr(internalformat),
+ _mesa_enum_to_string(internalformat),
width, height, depth);
/* Check the format to make sure it is sized. */
if (!_mesa_is_legal_tex_storage_format(ctx, internalformat)) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glTextureStorage%uD(internalformat = %s)", dims,
- _mesa_lookup_enum_by_nr(internalformat));
+ _mesa_enum_to_string(internalformat));
return;
}
return;
}
- /* target check */
- /* This is done here so that _mesa_texture_storage can receive unsized
- * formats. */
+ /* Check target. This is done here so that _mesa_texture_storage
+ * can receive unsized formats.
+ */
if (!legal_texobj_target(ctx, dims, texObj->Target)) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glTextureStorage%uD(illegal target=%s)",
- dims, _mesa_lookup_enum_by_nr(texObj->Target));
+ dims, _mesa_enum_to_string(texObj->Target));
return;
}
levels, internalformat, width, height, depth, true);
}
+
void GLAPIENTRY
_mesa_TexStorage1D(GLenum target, GLsizei levels, GLenum internalformat,
GLsizei width)
texstorage(3, target, levels, internalformat, width, height, depth);
}
+
void GLAPIENTRY
_mesa_TextureStorage1D(GLuint texture, GLsizei levels, GLenum internalformat,
GLsizei width)
texturestorage(2, texture, levels, internalformat, width, height, 1);
}
+
void GLAPIENTRY
_mesa_TextureStorage3D(GLuint texture, GLsizei levels, GLenum internalformat,
GLsizei width, GLsizei height, GLsizei depth)
}
-
void GLAPIENTRY
_mesa_TextureStorage3DEXT(GLuint texture, GLenum target, GLsizei levels,
GLenum internalformat,