X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Ftexstorage.c;h=3ace5e8bbcf3bb570a9e993a3e7f67c12e5cc534;hb=e0439f750557bc6880a8a4eccb38256fafd63fae;hp=44b5374fdbd76bb30bb2a0df9c39891ab57dd55e;hpb=a94d78438d35cfde851596dff8461f1e739a0ddc;p=mesa.git diff --git a/src/mesa/main/texstorage.c b/src/mesa/main/texstorage.c index 44b5374fdbd..3ace5e8bbcf 100644 --- a/src/mesa/main/texstorage.c +++ b/src/mesa/main/texstorage.c @@ -41,7 +41,8 @@ #include "texstorage.h" #include "textureview.h" #include "mtypes.h" - +#include "glformats.h" +#include "hash.h" /** @@ -241,10 +242,10 @@ _mesa_is_legal_tex_storage_format(struct gl_context *ctx, GLenum internalformat) * checks at glTexImage* time. */ GLboolean -_mesa_alloc_texture_storage(struct gl_context *ctx, - struct gl_texture_object *texObj, - GLsizei levels, GLsizei width, - GLsizei height, GLsizei depth) +_mesa_AllocTextureStorage_sw(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLsizei levels, GLsizei width, + GLsizei height, GLsizei depth) { const int numFaces = _mesa_num_tex_faces(texObj->Target); int face; @@ -273,74 +274,87 @@ _mesa_alloc_texture_storage(struct gl_context *ctx, * \return GL_TRUE if any error, GL_FALSE otherwise. */ static GLboolean -tex_storage_error_check(struct gl_context *ctx, GLuint dims, GLenum target, +tex_storage_error_check(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, - GLsizei width, GLsizei height, GLsizei depth) + GLsizei width, GLsizei height, GLsizei depth, + bool dsa) { - struct gl_texture_object *texObj; + const char* suffix = dsa ? "ture" : ""; - 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)); - return GL_TRUE; - } + /* Legal format checking has been moved to texstorage and texturestorage in + * order to allow meta functions to use legacy formats. */ /* size check */ if (width < 1 || height < 1 || depth < 1) { _mesa_error(ctx, GL_INVALID_VALUE, - "glTexStorage%uD(width, height or depth < 1)", dims); + "glTex%sStorage%uD(width, height or depth < 1)", + suffix, dims); return GL_TRUE; } - /* target check */ - 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)); - 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, + "glTex%sStorage%dD(internalformat = %s)", suffix, dims, + _mesa_lookup_enum_by_nr(internalformat)); } /* levels check */ if (levels < 1) { - _mesa_error(ctx, GL_INVALID_VALUE, "glTexStorage%uD(levels < 1)", - dims); + _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)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glTexStorage%uD(levels too large)", dims); + "glTex%sStorage%uD(levels too large)", + suffix, dims); return GL_TRUE; } /* check levels against width/height/depth */ if (levels > _mesa_get_tex_max_num_levels(target, width, height, depth)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glTexStorage%uD(too many levels for max texture dimension)", - dims); + "glTex%sStorage%uD(too many levels" + " for max texture dimension)", + suffix, dims); return GL_TRUE; } /* non-default texture object check */ - texObj = _mesa_get_current_tex_object(ctx, target); if (!_mesa_is_proxy_texture(target) && (!texObj || (texObj->Name == 0))) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glTexStorage%uD(texture object 0)", dims); + "glTex%sStorage%uD(texture object 0)", + suffix, dims); return GL_TRUE; } /* Check if texObj->Immutable is set */ if (!_mesa_is_proxy_texture(target) && texObj->Immutable) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glTexStorage%uD(immutable)", - dims); + _mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sStorage%uD(immutable)", + suffix, dims); return GL_TRUE; } /* additional checks for depth textures */ if (!_mesa_legal_texture_base_format_for_target(ctx, target, internalformat, - dims, "glTexStorage")) + dims, dsa ? + "glTextureStorage" : + "glTexStorage")) return GL_TRUE; return GL_FALSE; @@ -348,32 +362,27 @@ tex_storage_error_check(struct gl_context *ctx, GLuint dims, GLenum target, /** - * Helper used by _mesa_TexStorage1/2/3D(). + * Helper that does the storage allocation for _mesa_TexStorage1/2/3D() + * and _mesa_TextureStorage1/2/3D(). */ -static void -texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, - GLsizei width, GLsizei height, GLsizei depth) +void +_mesa_texture_storage(struct gl_context *ctx, GLuint dims, + struct gl_texture_object *texObj, + GLenum target, GLsizei levels, + GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth, bool dsa) { - struct gl_texture_object *texObj; GLboolean sizeOK, dimensionsOK; mesa_format texFormat; + const char* suffix = dsa ? "ture" : ""; - GET_CURRENT_CONTEXT(ctx); - - 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), - width, height, depth); + assert(texObj); - if (tex_storage_error_check(ctx, dims, target, levels, - internalformat, width, height, depth)) { + if (tex_storage_error_check(ctx, texObj, dims, target, levels, + internalformat, width, height, depth, dsa)) { return; /* error was recorded */ } - texObj = _mesa_get_current_tex_object(ctx, target); - assert(texObj); texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0, internalformat, GL_NONE, GL_NONE); @@ -386,7 +395,7 @@ texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, sizeOK = ctx->Driver.TestProxyTexImage(ctx, target, 0, texFormat, width, height, depth, 0); - if (_mesa_is_proxy_texture(texObj->Target)) { + if (_mesa_is_proxy_texture(target)) { if (dimensionsOK && sizeOK) { initialize_texture_fields(ctx, texObj, levels, width, height, depth, internalformat, texFormat); @@ -399,13 +408,15 @@ texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, else { if (!dimensionsOK) { _mesa_error(ctx, GL_INVALID_VALUE, - "glTexStorage%uD(invalid width, height or depth)", dims); + "glTex%sStorage%uD(invalid width, height or depth)", + suffix, dims); return; } if (!sizeOK) { _mesa_error(ctx, GL_OUT_OF_MEMORY, - "glTexStorage%uD(texture too large)", dims); + "glTex%sStorage%uD(texture too large)", + suffix, dims); } assert(levels > 0); @@ -427,7 +438,8 @@ texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, * state but this puts things in a consistent state. */ clear_texture_fields(ctx, texObj); - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage%uD", dims); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTex%sStorage%uD", + suffix, dims); return; } @@ -436,6 +448,94 @@ texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, } } +/** + * Helper used by _mesa_TexStorage1/2/3D(). + */ +static void +texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, + GLsizei width, GLsizei height, GLsizei depth) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + /* target check */ + /* 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)); + 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), + 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)); + return; + } + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + _mesa_texture_storage(ctx, dims, texObj, target, levels, + internalformat, width, height, depth, false); +} + +/** + * Helper used by _mesa_TextureStorage1/2/3D(). + */ +static void +texturestorage(GLuint dims, GLuint texture, GLsizei levels, + GLenum internalformat, GLsizei width, GLsizei height, + GLsizei depth) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + 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), + 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)); + return; + } + + /* Get the texture object by Name. */ + texObj = _mesa_lookup_texture(ctx, texture); + if (!texObj) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTextureStorage%uD(texture = %d)", dims, texture); + return; + } + + /* target check */ + /* 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)); + return; + } + + _mesa_texture_storage(ctx, dims, texObj, texObj->Target, + levels, internalformat, width, height, depth, true); +} void GLAPIENTRY _mesa_TexStorage1D(GLenum target, GLsizei levels, GLenum internalformat, @@ -460,6 +560,28 @@ _mesa_TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, texstorage(3, target, levels, internalformat, width, height, depth); } +void GLAPIENTRY +_mesa_TextureStorage1D(GLuint texture, GLsizei levels, GLenum internalformat, + GLsizei width) +{ + texturestorage(1, texture, levels, internalformat, width, 1, 1); +} + + +void GLAPIENTRY +_mesa_TextureStorage2D(GLuint texture, GLsizei levels, + GLenum internalformat, + GLsizei width, GLsizei height) +{ + texturestorage(2, texture, levels, internalformat, width, height, 1); +} + +void GLAPIENTRY +_mesa_TextureStorage3D(GLuint texture, GLsizei levels, GLenum internalformat, + GLsizei width, GLsizei height, GLsizei depth) +{ + texturestorage(3, texture, levels, internalformat, width, height, depth); +} /*