X-Git-Url: https://git.libre-soc.org/?p=mesa.git;a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fteximage.c;h=bea5c9ae356440091eb0dd15ad8b446a257c86b7;hp=d45854bd17f2bdfabfe898e495dd79f49fa52e4b;hb=a0d667036d8c8b77fa62f74263583b07909f8637;hpb=0d356cf4781bece0dc9a7b84b4b38c45cb2e4eaa diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index d45854bd17f..bea5c9ae356 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -176,7 +176,7 @@ oes_float_internal_format(const struct gl_context *ctx, /** * Install gl_texture_image in a gl_texture_object according to the target * and level parameters. - * + * * \param tObj texture object. * \param target texture target. * \param level image level. @@ -423,23 +423,15 @@ get_proxy_tex_image(struct gl_context *ctx, GLenum target, GLint level) switch (target) { case GL_PROXY_TEXTURE_1D: - if (level >= ctx->Const.MaxTextureLevels) - return NULL; texIndex = TEXTURE_1D_INDEX; break; case GL_PROXY_TEXTURE_2D: - if (level >= ctx->Const.MaxTextureLevels) - return NULL; texIndex = TEXTURE_2D_INDEX; break; case GL_PROXY_TEXTURE_3D: - if (level >= ctx->Const.Max3DTextureLevels) - return NULL; texIndex = TEXTURE_3D_INDEX; break; case GL_PROXY_TEXTURE_CUBE_MAP: - if (level >= ctx->Const.MaxCubeTextureLevels) - return NULL; texIndex = TEXTURE_CUBE_INDEX; break; case GL_PROXY_TEXTURE_RECTANGLE_NV: @@ -448,28 +440,18 @@ get_proxy_tex_image(struct gl_context *ctx, GLenum target, GLint level) texIndex = TEXTURE_RECT_INDEX; break; case GL_PROXY_TEXTURE_1D_ARRAY_EXT: - if (level >= ctx->Const.MaxTextureLevels) - return NULL; texIndex = TEXTURE_1D_ARRAY_INDEX; break; case GL_PROXY_TEXTURE_2D_ARRAY_EXT: - if (level >= ctx->Const.MaxTextureLevels) - return NULL; texIndex = TEXTURE_2D_ARRAY_INDEX; break; case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: - if (level >= ctx->Const.MaxCubeTextureLevels) - return NULL; texIndex = TEXTURE_CUBE_ARRAY_INDEX; break; case GL_PROXY_TEXTURE_2D_MULTISAMPLE: - if (level > 0) - return 0; texIndex = TEXTURE_2D_MULTISAMPLE_INDEX; break; case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: - if (level > 0) - return 0; texIndex = TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX; break; default: @@ -503,14 +485,14 @@ get_proxy_tex_image(struct gl_context *ctx, GLenum target, GLint level) * \sa gl_constants. */ GLint -_mesa_max_texture_levels(struct gl_context *ctx, GLenum target) +_mesa_max_texture_levels(const struct gl_context *ctx, GLenum target) { switch (target) { case GL_TEXTURE_1D: case GL_PROXY_TEXTURE_1D: case GL_TEXTURE_2D: case GL_PROXY_TEXTURE_2D: - return ctx->Const.MaxTextureLevels; + return ffs(util_next_power_of_two(ctx->Const.MaxTextureSize)); case GL_TEXTURE_3D: case GL_PROXY_TEXTURE_3D: return ctx->Const.Max3DTextureLevels; @@ -532,7 +514,7 @@ _mesa_max_texture_levels(struct gl_context *ctx, GLenum target) case GL_TEXTURE_2D_ARRAY_EXT: case GL_PROXY_TEXTURE_2D_ARRAY_EXT: return ctx->Extensions.EXT_texture_array - ? ctx->Const.MaxTextureLevels : 0; + ? ffs(util_next_power_of_two(ctx->Const.MaxTextureSize)) : 0; case GL_TEXTURE_CUBE_MAP_ARRAY: case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: return _mesa_has_texture_cube_map_array(ctx) @@ -548,7 +530,7 @@ _mesa_max_texture_levels(struct gl_context *ctx, GLenum target) && ctx->Extensions.ARB_texture_multisample ? 1 : 0; case GL_TEXTURE_EXTERNAL_OES: - /* fall-through */ + return _mesa_has_OES_EGL_image_external(ctx) ? 1 : 0; default: return 0; /* bad target */ } @@ -991,8 +973,7 @@ _mesa_legal_texture_dimensions(struct gl_context *ctx, GLenum target, switch (target) { case GL_TEXTURE_1D: case GL_PROXY_TEXTURE_1D: - maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); /* level zero size */ - maxSize >>= level; /* level size */ + maxSize = ctx->Const.MaxTextureSize >> level; if (width < 2 * border || width > 2 * border + maxSize) return GL_FALSE; if (!ctx->Extensions.ARB_texture_non_power_of_two) { @@ -1005,8 +986,7 @@ _mesa_legal_texture_dimensions(struct gl_context *ctx, GLenum target, case GL_PROXY_TEXTURE_2D: case GL_TEXTURE_2D_MULTISAMPLE: case GL_PROXY_TEXTURE_2D_MULTISAMPLE: - maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); - maxSize >>= level; + maxSize = ctx->Const.MaxTextureSize >> level; if (width < 2 * border || width > 2 * border + maxSize) return GL_FALSE; if (height < 2 * border || height > 2 * border + maxSize) @@ -1076,8 +1056,7 @@ _mesa_legal_texture_dimensions(struct gl_context *ctx, GLenum target, case GL_TEXTURE_1D_ARRAY_EXT: case GL_PROXY_TEXTURE_1D_ARRAY_EXT: - maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); - maxSize >>= level; + maxSize = ctx->Const.MaxTextureSize >> level; if (width < 2 * border || width > 2 * border + maxSize) return GL_FALSE; if (height < 0 || height > ctx->Const.MaxArrayTextureLayers) @@ -1092,8 +1071,7 @@ _mesa_legal_texture_dimensions(struct gl_context *ctx, GLenum target, case GL_PROXY_TEXTURE_2D_ARRAY_EXT: case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: - maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); - maxSize >>= level; + maxSize = ctx->Const.MaxTextureSize >> level; if (width < 2 * border || width > 2 * border + maxSize) return GL_FALSE; if (height < 2 * border || height > 2 * border + maxSize) @@ -1299,7 +1277,7 @@ error_check_subtexture_dimensions(struct gl_context *ctx, GLuint dims, */ GLboolean _mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, - GLuint numLevels, MAYBE_UNUSED GLint level, + GLuint numLevels, ASSERTED GLint level, mesa_format format, GLuint numSamples, GLint width, GLint height, GLint depth) { @@ -1366,6 +1344,9 @@ compressedteximage_only_format(GLenum format) case GL_PALETTE8_R5_G6_B5_OES: case GL_PALETTE8_RGBA4_OES: case GL_PALETTE8_RGB5_A1_OES: + case GL_ATC_RGB_AMD: + case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD: + case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: return true; default: return false; @@ -1650,9 +1631,8 @@ legal_texsubimage_target(struct gl_context *ctx, GLuint dims, GLenum target, * of GL_ARB_texture_storage/GL_ARB_bindless_texture). */ static GLboolean -mutable_tex_object(struct gl_context *ctx, GLenum target) +mutable_tex_object(struct gl_texture_object *texObj) { - struct gl_texture_object *texObj = _mesa_get_current_tex_object(ctx, target); if (!texObj) return GL_FALSE; @@ -1798,8 +1778,8 @@ static bool texture_format_error_check_gles(struct gl_context *ctx, GLenum format, GLenum type, GLenum internalFormat, const char *callerName) { - GLenum err = _mesa_es3_error_check_format_and_type(ctx, format, type, - internalFormat); + GLenum err = _mesa_gles_error_check_format_and_type(ctx, format, type, + internalFormat); if (err != GL_NO_ERROR) { _mesa_error(ctx, err, "%s(format = %s, type = %s, internalformat = %s)", @@ -1840,6 +1820,7 @@ texture_format_error_check_gles(struct gl_context *ctx, GLenum format, static GLboolean texture_error_check( struct gl_context *ctx, GLuint dimensions, GLenum target, + struct gl_texture_object* texObj, GLint level, GLint internalFormat, GLenum format, GLenum type, GLint width, GLint height, @@ -2002,7 +1983,7 @@ texture_error_check( struct gl_context *ctx, return GL_TRUE; } - if (!mutable_tex_object(ctx, target)) { + if (!mutable_tex_object(texObj)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glTexImage%dD(immutable texture)", dimensions); return GL_TRUE; @@ -2021,8 +2002,8 @@ texture_error_check( struct gl_context *ctx, */ static GLenum compressed_texture_error_check(struct gl_context *ctx, GLint dimensions, - GLenum target, GLint level, - GLenum internalFormat, GLsizei width, + GLenum target, struct gl_texture_object* texObj, + GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data) { @@ -2138,7 +2119,7 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions, goto error; } - if (!mutable_tex_object(ctx, target)) { + if (!mutable_tex_object(texObj)) { reason = "immutable texture"; error = GL_INVALID_OPERATION; goto error; @@ -2224,6 +2205,15 @@ texsubimage_error_check(struct gl_context *ctx, GLuint dimensions, return GL_TRUE; } + if (!texture_formats_agree(texImage->InternalFormat, format)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(incompatible internalFormat = %s, format = %s)", + callerName, + _mesa_enum_to_string(texImage->InternalFormat), + _mesa_enum_to_string(format)); + return GL_TRUE; + } + GLenum internalFormat = _mesa_is_gles(ctx) ? oes_float_internal_format(ctx, texImage->InternalFormat, type) : texImage->InternalFormat; @@ -2294,8 +2284,8 @@ texsubimage_error_check(struct gl_context *ctx, GLuint dimensions, */ static GLboolean copytexture_error_check( struct gl_context *ctx, GLuint dimensions, - GLenum target, GLint level, GLint internalFormat, - GLint border ) + GLenum target, struct gl_texture_object* texObj, + GLint level, GLint internalFormat, GLint border ) { GLint baseFormat; GLint rb_base_format; @@ -2407,8 +2397,8 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions, if (_mesa_is_gles(ctx)) { bool valid = true; - if (_mesa_base_format_component_count(baseFormat) > - _mesa_base_format_component_count(rb_base_format)) { + if (_mesa_components_in_format(baseFormat) > + _mesa_components_in_format(rb_base_format)) { valid = false; } if (baseFormat == GL_DEPTH_COMPONENT || @@ -2435,14 +2425,10 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions, } if (_mesa_is_gles3(ctx)) { - bool rb_is_srgb = false; + bool rb_is_srgb = (ctx->Extensions.EXT_sRGB && + _mesa_is_format_srgb(rb->Format)); bool dst_is_srgb = false; - if (ctx->Extensions.EXT_framebuffer_sRGB && - _mesa_get_format_color_encoding(rb->Format) == GL_SRGB) { - rb_is_srgb = true; - } - if (_mesa_get_linear_internalformat(internalFormat) != internalFormat) { dst_is_srgb = true; } @@ -2543,7 +2529,7 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions, } } - if (!mutable_tex_object(ctx, target)) { + if (!mutable_tex_object(texObj)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexImage%dD(immutable texture)", dimensions); return GL_TRUE; @@ -2896,10 +2882,70 @@ strip_texture_border(GLenum target, } } +static struct gl_texture_object * +lookup_texture_ext_dsa(struct gl_context *ctx, GLenum target, GLuint texture, + const char *caller) +{ + GLenum boundTarget; + switch (target) { + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + boundTarget = GL_TEXTURE_CUBE_MAP; + break; + default: + boundTarget = target; + break; + } + + int targetIndex = _mesa_tex_target_to_index(ctx, boundTarget); + if (targetIndex < 0) { + _mesa_error(ctx, GL_INVALID_ENUM, "%s(target = %s)", caller, + _mesa_enum_to_string(target)); + return NULL; + } + assert(targetIndex < NUM_TEXTURE_TARGETS); + + struct gl_texture_object *texObj; + if (texture == 0) { + /* Use a default texture object */ + texObj = ctx->Shared->DefaultTex[targetIndex]; + assert(texObj); + } else { + texObj = _mesa_lookup_texture(ctx, texture); + if (!texObj && ctx->API == API_OPENGL_CORE) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-gen name)", caller); + return NULL; + } + + if (!texObj) { + texObj = ctx->Driver.NewTextureObject(ctx, texture, boundTarget); + if (!texObj) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller); + return NULL; + } + + /* insert into hash table */ + _mesa_HashInsert(ctx->Shared->TexObjects, texObj->Name, texObj); + } + + if (texObj->Target != boundTarget) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(%s != %s)", + caller, _mesa_enum_to_string(texObj->Target), + _mesa_enum_to_string(target)); + return NULL; + } + } + + return texObj; +} /** - * Common code to implement all the glTexImage1D/2D/3D functions - * as well as glCompressedTexImage1D/2D/3D. + * Common code to implement all the glTexImage1D/2D/3D functions, + * glCompressedTexImage1D/2D/3D and glTextureImage1D/2D/3DEXT * \param compressed only GL_TRUE for glCompressedTexImage1D/2D/3D calls. * \param format the user's image format (only used if !compressed) * \param type the user's image type (only used if !compressed) @@ -2907,6 +2953,7 @@ strip_texture_border(GLenum target, */ static ALWAYS_INLINE void teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims, + struct gl_texture_object *texObj, GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, @@ -2915,7 +2962,6 @@ teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims, const char *func = compressed ? "glCompressedTexImage" : "glTexImage"; struct gl_pixelstore_attrib unpack_no_border; const struct gl_pixelstore_attrib *unpack = &ctx->Unpack; - struct gl_texture_object *texObj; mesa_format texFormat; bool dimensionsOK = true, sizeOK = true; @@ -2942,28 +2988,33 @@ teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims, internalFormat = override_internal_format(internalFormat, width, height); - if (!no_error) { - /* target error checking */ - if (!legal_teximage_target(ctx, dims, target)) { - _mesa_error(ctx, GL_INVALID_ENUM, "%s%uD(target=%s)", - func, dims, _mesa_enum_to_string(target)); - return; - } + if (!no_error && + /* target error checking */ + !legal_teximage_target(ctx, dims, target)) { + _mesa_error(ctx, GL_INVALID_ENUM, "%s%uD(target=%s)", + func, dims, _mesa_enum_to_string(target)); + return; + } + + if (!texObj) + texObj = _mesa_get_current_tex_object(ctx, target); + if (!no_error) { /* general error checking */ if (compressed) { - if (compressed_texture_error_check(ctx, dims, target, level, - internalFormat, + if (compressed_texture_error_check(ctx, dims, target, texObj, + level, internalFormat, width, height, depth, border, imageSize, pixels)) return; } else { - if (texture_error_check(ctx, dims, target, level, internalFormat, + if (texture_error_check(ctx, dims, target, texObj, level, internalFormat, format, type, width, height, depth, border, pixels)) return; } } + assert(texObj); /* Here we convert a cpal compressed image into a regular glTexImage2D * call by decompressing the texture. If we really want to support cpal @@ -2987,9 +3038,6 @@ teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims, } } - texObj = _mesa_get_current_tex_object(ctx, target); - assert(texObj); - if (compressed) { /* For glCompressedTexImage() the driver has no choice about the * texture format since we'll never transcode the user's compressed @@ -3126,7 +3174,7 @@ teximage_err(struct gl_context *ctx, GLboolean compressed, GLuint dims, GLint border, GLenum format, GLenum type, GLsizei imageSize, const GLvoid *pixels) { - teximage(ctx, compressed, dims, target, level, internalFormat, width, height, + teximage(ctx, compressed, dims, NULL, target, level, internalFormat, width, height, depth, border, format, type, imageSize, pixels, false); } @@ -3138,7 +3186,7 @@ teximage_no_error(struct gl_context *ctx, GLboolean compressed, GLuint dims, GLint border, GLenum format, GLenum type, GLsizei imageSize, const GLvoid *pixels) { - teximage(ctx, compressed, dims, target, level, internalFormat, width, height, + teximage(ctx, compressed, dims, NULL, target, level, internalFormat, width, height, depth, border, format, type, imageSize, pixels, true); } @@ -3156,6 +3204,39 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, border, format, type, 0, pixels); } +void GLAPIENTRY +_mesa_TextureImage1DEXT(GLuint texture, GLenum target, GLint level, + GLint internalFormat, GLsizei width, GLint border, + GLenum format, GLenum type, const GLvoid *pixels ) +{ + struct gl_texture_object* texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, + "glTextureImage1DEXT"); + if (!texObj) + return; + teximage(ctx, GL_FALSE, 1, texObj, target, level, internalFormat, + width, 1, 1, border, format, type, 0, pixels, false); +} + +void GLAPIENTRY +_mesa_MultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level, + GLint internalFormat, GLsizei width, GLint border, + GLenum format, GLenum type, const GLvoid *pixels ) +{ + struct gl_texture_object* texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + texunit - GL_TEXTURE0, + true, + "glMultiTexImage1DEXT"); + if (!texObj) + return; + teximage(ctx, GL_FALSE, 1, texObj, target, level, internalFormat, width, 1, 1, + border, format, type, 0, pixels, false); +} void GLAPIENTRY _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, @@ -3168,6 +3249,41 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, border, format, type, 0, pixels); } +void GLAPIENTRY +_mesa_TextureImage2DEXT(GLuint texture, GLenum target, GLint level, + GLint internalFormat, GLsizei width, GLsizei height, + GLint border, + GLenum format, GLenum type, const GLvoid *pixels ) +{ + struct gl_texture_object* texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, + "glTextureImage2DEXT"); + if (!texObj) + return; + teximage(ctx, GL_FALSE, 2, texObj, target, level, internalFormat, + width, height, 1, border, format, type, 0, pixels, false); +} + +void GLAPIENTRY +_mesa_MultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level, + GLint internalFormat, GLsizei width, GLsizei height, + GLint border, + GLenum format, GLenum type, const GLvoid *pixels ) +{ + struct gl_texture_object* texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + texunit - GL_TEXTURE0, + true, + "glMultiTexImage2DEXT"); + if (!texObj) + return; + teximage(ctx, GL_FALSE, 2, texObj, target, level, internalFormat, width, height, 1, + border, format, type, 0, pixels, false); +} /* * Called by the API or display list executor. @@ -3184,6 +3300,43 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat, width, height, depth, border, format, type, 0, pixels); } +void GLAPIENTRY +_mesa_TextureImage3DEXT(GLuint texture, GLenum target, GLint level, + GLint internalFormat, GLsizei width, GLsizei height, + GLsizei depth, GLint border, + GLenum format, GLenum type, const GLvoid *pixels ) +{ + struct gl_texture_object* texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, + "glTextureImage3DEXT"); + if (!texObj) + return; + teximage(ctx, GL_FALSE, 3, texObj, target, level, internalFormat, + width, height, depth, border, format, type, 0, pixels, false); +} + + +void GLAPIENTRY +_mesa_MultiTexImage3DEXT(GLenum texunit, GLenum target, GLint level, + GLint internalFormat, GLsizei width, GLsizei height, + GLsizei depth, GLint border, GLenum format, GLenum type, + const GLvoid *pixels ) +{ + struct gl_texture_object* texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + texunit - GL_TEXTURE0, + true, + "glMultiTexImage3DEXT"); + if (!texObj) + return; + teximage(ctx, GL_FALSE, 3, texObj, target, level, internalFormat, + width, height, depth, border, format, type, 0, pixels, false); +} + void GLAPIENTRY _mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalFormat, @@ -3294,7 +3447,6 @@ _mesa_EGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image) _mesa_unlock_texture(ctx, texObj); } - /** * Helper that implements the glTexSubImage1/2/3D() * and glTextureSubImage1/2/3D() functions. @@ -3418,11 +3570,11 @@ texsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level, */ static ALWAYS_INLINE void texturesubimage(struct gl_context *ctx, GLuint dims, - GLuint texture, GLint level, + GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels, - const char *callerName, bool no_error) + const char *callerName, bool no_error, bool ext_dsa) { struct gl_texture_object *texObj; struct gl_texture_image *texImage; @@ -3438,7 +3590,11 @@ texturesubimage(struct gl_context *ctx, GLuint dims, /* Get the texture object by Name. */ if (!no_error) { - texObj = _mesa_lookup_texture_err(ctx, texture, callerName); + if (!ext_dsa) { + texObj = _mesa_lookup_texture_err(ctx, texture, callerName); + } else { + texObj = lookup_texture_ext_dsa(ctx, target, texture, callerName); + } if (!texObj) return; } else { @@ -3529,29 +3685,29 @@ texturesubimage(struct gl_context *ctx, GLuint dims, static void texturesubimage_error(struct gl_context *ctx, GLuint dims, - GLuint texture, GLint level, + GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels, - const char *callerName) + const char *callerName, bool ext_dsa) { - texturesubimage(ctx, dims, texture, level, xoffset, yoffset, zoffset, - width, height, depth, format, type, pixels, callerName, - false); + texturesubimage(ctx, dims, texture, target, level, xoffset, yoffset, + zoffset, width, height, depth, format, type, pixels, + callerName, false, ext_dsa); } static void texturesubimage_no_error(struct gl_context *ctx, GLuint dims, - GLuint texture, GLint level, + GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels, - const char *callerName) + const char *callerName, bool ext_dsa) { - texturesubimage(ctx, dims, texture, level, xoffset, yoffset, zoffset, - width, height, depth, format, type, pixels, callerName, - true); + texturesubimage(ctx, dims, texture, target, level, xoffset, yoffset, + zoffset, width, height, depth, format, type, pixels, + callerName, true, ext_dsa); } @@ -3649,8 +3805,44 @@ _mesa_TextureSubImage1D_no_error(GLuint texture, GLint level, GLint xoffset, const GLvoid *pixels) { GET_CURRENT_CONTEXT(ctx); - texturesubimage_no_error(ctx, 1, texture, level, xoffset, 0, 0, width, 1, 1, - format, type, pixels, "glTextureSubImage1D"); + texturesubimage_no_error(ctx, 1, texture, 0, level, xoffset, 0, 0, width, + 1, 1, format, type, pixels, "glTextureSubImage1D", + false); +} + + +void GLAPIENTRY +_mesa_TextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLsizei width, + GLenum format, GLenum type, + const GLvoid *pixels) +{ + GET_CURRENT_CONTEXT(ctx); + texturesubimage_error(ctx, 1, texture, target, level, xoffset, 0, 0, width, 1, + 1, format, type, pixels, "glTextureSubImage1DEXT", + false); +} + + +void GLAPIENTRY +_mesa_MultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, + GLint xoffset, GLsizei width, + GLenum format, GLenum type, + const GLvoid *pixels) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + texunit - GL_TEXTURE0, + false, + "glMultiTexImage1DEXT"); + texImage = _mesa_select_tex_image(texObj, target, level); + + texture_sub_image(ctx, 1, texObj, texImage, target, level, + xoffset, 0, 0, width, 1, 1, + format, type, pixels); } @@ -3661,8 +3853,9 @@ _mesa_TextureSubImage1D(GLuint texture, GLint level, const GLvoid *pixels) { GET_CURRENT_CONTEXT(ctx); - texturesubimage_error(ctx, 1, texture, level, xoffset, 0, 0, width, 1, 1, - format, type, pixels, "glTextureSubImage1D"); + texturesubimage_error(ctx, 1, texture, 0, level, xoffset, 0, 0, width, 1, + 1, format, type, pixels, "glTextureSubImage1D", + false); } @@ -3673,9 +3866,44 @@ _mesa_TextureSubImage2D_no_error(GLuint texture, GLint level, GLint xoffset, const GLvoid *pixels) { GET_CURRENT_CONTEXT(ctx); - texturesubimage_no_error(ctx, 2, texture, level, xoffset, yoffset, 0, width, - height, 1, format, type, pixels, - "glTextureSubImage2D"); + texturesubimage_no_error(ctx, 2, texture, 0, level, xoffset, yoffset, 0, + width, height, 1, format, type, pixels, + "glTextureSubImage2D", false); +} + + +void GLAPIENTRY +_mesa_TextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, GLenum type, + const GLvoid *pixels) +{ + GET_CURRENT_CONTEXT(ctx); + texturesubimage_error(ctx, 2, texture, target, level, xoffset, yoffset, 0, + width, height, 1, format, type, pixels, + "glTextureSubImage2DEXT", true); +} + + +void GLAPIENTRY +_mesa_MultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, GLenum type, + const GLvoid *pixels) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + texunit - GL_TEXTURE0, + false, + "glMultiTexImage2DEXT"); + texImage = _mesa_select_tex_image(texObj, target, level); + + texture_sub_image(ctx, 2, texObj, texImage, target, level, + xoffset, yoffset, 0, width, height, 1, + format, type, pixels); } @@ -3687,9 +3915,9 @@ _mesa_TextureSubImage2D(GLuint texture, GLint level, const GLvoid *pixels) { GET_CURRENT_CONTEXT(ctx); - texturesubimage_error(ctx, 2, texture, level, xoffset, yoffset, 0, width, - height, 1, format, type, pixels, - "glTextureSubImage2D"); + texturesubimage_error(ctx, 2, texture, 0, level, xoffset, yoffset, 0, + width, height, 1, format, type, pixels, + "glTextureSubImage2D", false); } @@ -3700,9 +3928,44 @@ _mesa_TextureSubImage3D_no_error(GLuint texture, GLint level, GLint xoffset, GLenum type, const GLvoid *pixels) { GET_CURRENT_CONTEXT(ctx); - texturesubimage_no_error(ctx, 3, texture, level, xoffset, yoffset, zoffset, - width, height, depth, format, type, pixels, - "glTextureSubImage3D"); + texturesubimage_no_error(ctx, 3, texture, 0, level, xoffset, yoffset, + zoffset, width, height, depth, format, type, + pixels, "glTextureSubImage3D", false); +} + + +void GLAPIENTRY +_mesa_TextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const GLvoid *pixels) +{ + GET_CURRENT_CONTEXT(ctx); + texturesubimage_error(ctx, 3, texture, target, level, xoffset, yoffset, + zoffset, width, height, depth, format, type, + pixels, "glTextureSubImage3DEXT", true); +} + + +void GLAPIENTRY +_mesa_MultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const GLvoid *pixels) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + texunit - GL_TEXTURE0, + false, + "glMultiTexImage3DEXT"); + texImage = _mesa_select_tex_image(texObj, target, level); + + texture_sub_image(ctx, 3, texObj, texImage, target, level, + xoffset, yoffset, zoffset, width, height, depth, + format, type, pixels); } @@ -3714,9 +3977,9 @@ _mesa_TextureSubImage3D(GLuint texture, GLint level, const GLvoid *pixels) { GET_CURRENT_CONTEXT(ctx); - texturesubimage_error(ctx, 3, texture, level, xoffset, yoffset, zoffset, + texturesubimage_error(ctx, 3, texture, 0, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels, - "glTextureSubImage3D"); + "glTextureSubImage3D", false); } @@ -3917,13 +4180,12 @@ copy_texture_sub_image_no_error(struct gl_context *ctx, GLuint dims, * Implement the glCopyTexImage1/2D() functions. */ static ALWAYS_INLINE void -copyteximage(struct gl_context *ctx, GLuint dims, +copyteximage(struct gl_context *ctx, GLuint dims, struct gl_texture_object *texObj, GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border, bool no_error) { struct gl_texture_image *texImage; - struct gl_texture_object *texObj; mesa_format texFormat; FLUSH_VERTICES(ctx, 0); @@ -3939,8 +4201,8 @@ copyteximage(struct gl_context *ctx, GLuint dims, _mesa_update_state(ctx); if (!no_error) { - if (copytexture_error_check(ctx, dims, target, level, internalFormat, - border)) + if (copytexture_error_check(ctx, dims, target, texObj, level, + internalFormat, border)) return; if (!_mesa_legal_texture_dimensions(ctx, target, level, width, height, @@ -3952,7 +4214,6 @@ copyteximage(struct gl_context *ctx, GLuint dims, } } - texObj = _mesa_get_current_tex_object(ctx, target); assert(texObj); texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, @@ -4079,11 +4340,13 @@ copyteximage(struct gl_context *ctx, GLuint dims, static void -copyteximage_err(struct gl_context *ctx, GLuint dims, GLenum target, +copyteximage_err(struct gl_context *ctx, GLuint dims, + GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { - copyteximage(ctx, dims, target, level, internalFormat, x, y, width, height, + struct gl_texture_object* texObj = _mesa_get_current_tex_object(ctx, target); + copyteximage(ctx, dims, texObj, target, level, internalFormat, x, y, width, height, border, false); } @@ -4093,7 +4356,8 @@ copyteximage_no_error(struct gl_context *ctx, GLuint dims, GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { - copyteximage(ctx, dims, target, level, internalFormat, x, y, width, height, + struct gl_texture_object* texObj = _mesa_get_current_tex_object(ctx, target); + copyteximage(ctx, dims, texObj, target, level, internalFormat, x, y, width, height, border, true); } @@ -4110,6 +4374,42 @@ _mesa_CopyTexImage1D( GLenum target, GLint level, } +void GLAPIENTRY +_mesa_CopyTextureImage1DEXT( GLuint texture, GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, + GLsizei width, GLint border ) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_texture_object* texObj = + _mesa_lookup_or_create_texture(ctx, target, texture, false, true, + "glCopyTextureImage1DEXT"); + if (!texObj) + return; + copyteximage(ctx, 1, texObj, target, level, internalFormat, x, y, width, 1, + border, false); +} + + +void GLAPIENTRY +_mesa_CopyMultiTexImage1DEXT( GLenum texunit, GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, + GLsizei width, GLint border ) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_texture_object* texObj = + _mesa_get_texobj_by_target_and_texunit(ctx, target, + texunit - GL_TEXTURE0, + false, + "glCopyMultiTexImage1DEXT"); + if (!texObj) + return; + copyteximage(ctx, 1, texObj, target, level, internalFormat, x, y, width, 1, + border, false); +} + + void GLAPIENTRY _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, @@ -4121,6 +4421,43 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, } +void GLAPIENTRY +_mesa_CopyTextureImage2DEXT( GLuint texture, GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLint border ) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_texture_object* texObj = + _mesa_lookup_or_create_texture(ctx, target, texture, false, true, + "glCopyTextureImage2DEXT"); + if (!texObj) + return; + copyteximage(ctx, 2, texObj, target, level, internalFormat, x, y, width, height, + border, false); +} + + +void GLAPIENTRY +_mesa_CopyMultiTexImage2DEXT( GLenum texunit, GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, + GLsizei width, GLsizei height, GLint border ) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_texture_object* texObj = + _mesa_get_texobj_by_target_and_texunit(ctx, target, + texunit - GL_TEXTURE0, + false, + "glCopyMultiTexImage2DEXT"); + if (!texObj) + return; + copyteximage(ctx, 2, texObj, target, level, internalFormat, x, y, width, height, + border, false); +} + + void GLAPIENTRY _mesa_CopyTexImage1D_no_error(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border) @@ -4247,54 +4584,203 @@ _mesa_CopyTextureSubImage1D(GLuint texture, GLint level, void GLAPIENTRY -_mesa_CopyTextureSubImage2D(GLuint texture, GLint level, - GLint xoffset, GLint yoffset, - GLint x, GLint y, GLsizei width, GLsizei height) +_mesa_CopyTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint x, GLint y, GLsizei width) { struct gl_texture_object* texObj; - const char *self = "glCopyTextureSubImage2D"; + const char *self = "glCopyTextureSubImage1DEXT"; GET_CURRENT_CONTEXT(ctx); - texObj = _mesa_lookup_texture_err(ctx, texture, self); + texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, + self); if (!texObj) return; /* Check target (proxies not allowed). */ - if (!legal_texsubimage_target(ctx, 2, texObj->Target, true)) { + if (!legal_texsubimage_target(ctx, 1, texObj->Target, true)) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", self, _mesa_enum_to_string(texObj->Target)); return; } - copy_texture_sub_image_err(ctx, 2, texObj, texObj->Target, level, xoffset, - yoffset, 0, x, y, width, height, self); + copy_texture_sub_image_err(ctx, 1, texObj, texObj->Target, level, xoffset, 0, + 0, x, y, width, 1, self); } void GLAPIENTRY -_mesa_CopyTextureSubImage3D(GLuint texture, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLint x, GLint y, GLsizei width, GLsizei height) +_mesa_CopyMultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, + GLint xoffset, GLint x, GLint y, GLsizei width) { struct gl_texture_object* texObj; - const char *self = "glCopyTextureSubImage3D"; + const char *self = "glCopyMultiTexSubImage1DEXT"; GET_CURRENT_CONTEXT(ctx); - texObj = _mesa_lookup_texture_err(ctx, texture, self); + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + texunit - GL_TEXTURE0, + false, self); if (!texObj) return; - /* Check target (proxies not allowed). */ - if (!legal_texsubimage_target(ctx, 3, texObj->Target, true)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", self, - _mesa_enum_to_string(texObj->Target)); - return; - } + copy_texture_sub_image_err(ctx, 1, texObj, texObj->Target, level, xoffset, 0, + 0, x, y, width, 1, self); +} - if (texObj->Target == GL_TEXTURE_CUBE_MAP) { - /* Act like CopyTexSubImage2D */ - copy_texture_sub_image_err(ctx, 2, texObj, - GL_TEXTURE_CUBE_MAP_POSITIVE_X + zoffset, + +void GLAPIENTRY +_mesa_CopyTextureSubImage2D(GLuint texture, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, GLsizei width, GLsizei height) +{ + struct gl_texture_object* texObj; + const char *self = "glCopyTextureSubImage2D"; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_texture_err(ctx, texture, self); + if (!texObj) + return; + + /* Check target (proxies not allowed). */ + if (!legal_texsubimage_target(ctx, 2, texObj->Target, true)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", self, + _mesa_enum_to_string(texObj->Target)); + return; + } + + copy_texture_sub_image_err(ctx, 2, texObj, texObj->Target, level, xoffset, + yoffset, 0, x, y, width, height, self); +} + + +void GLAPIENTRY +_mesa_CopyTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, GLsizei width, GLsizei height) +{ + struct gl_texture_object* texObj; + const char *self = "glCopyTextureSubImage2DEXT"; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, self); + if (!texObj) + return; + + /* Check target (proxies not allowed). */ + if (!legal_texsubimage_target(ctx, 2, texObj->Target, true)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", self, + _mesa_enum_to_string(texObj->Target)); + return; + } + + copy_texture_sub_image_err(ctx, 2, texObj, texObj->Target, level, xoffset, + yoffset, 0, x, y, width, height, self); +} + + +void GLAPIENTRY +_mesa_CopyMultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, GLsizei width, GLsizei height) +{ + struct gl_texture_object* texObj; + const char *self = "glCopyMultiTexSubImage2DEXT"; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + texunit - GL_TEXTURE0, + false, self); + if (!texObj) + return; + + copy_texture_sub_image_err(ctx, 2, texObj, texObj->Target, level, xoffset, + yoffset, 0, x, y, width, height, self); +} + +void GLAPIENTRY +_mesa_CopyTextureSubImage3D(GLuint texture, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, GLsizei width, GLsizei height) +{ + struct gl_texture_object* texObj; + const char *self = "glCopyTextureSubImage3D"; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_texture_err(ctx, texture, self); + if (!texObj) + return; + + /* Check target (proxies not allowed). */ + if (!legal_texsubimage_target(ctx, 3, texObj->Target, true)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", self, + _mesa_enum_to_string(texObj->Target)); + return; + } + + if (texObj->Target == GL_TEXTURE_CUBE_MAP) { + /* Act like CopyTexSubImage2D */ + copy_texture_sub_image_err(ctx, 2, texObj, + GL_TEXTURE_CUBE_MAP_POSITIVE_X + zoffset, + level, xoffset, yoffset, 0, x, y, width, height, + self); + } + else + copy_texture_sub_image_err(ctx, 3, texObj, texObj->Target, level, xoffset, + yoffset, zoffset, x, y, width, height, self); +} + + +void GLAPIENTRY +_mesa_CopyTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, GLsizei width, GLsizei height) +{ + struct gl_texture_object* texObj; + const char *self = "glCopyTextureSubImage3D"; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, self); + if (!texObj) + return; + + /* Check target (proxies not allowed). */ + if (!legal_texsubimage_target(ctx, 3, texObj->Target, true)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", self, + _mesa_enum_to_string(texObj->Target)); + return; + } + + if (texObj->Target == GL_TEXTURE_CUBE_MAP) { + /* Act like CopyTexSubImage2D */ + copy_texture_sub_image_err(ctx, 2, texObj, + GL_TEXTURE_CUBE_MAP_POSITIVE_X + zoffset, + level, xoffset, yoffset, 0, x, y, width, height, + self); + } + else + copy_texture_sub_image_err(ctx, 3, texObj, texObj->Target, level, xoffset, + yoffset, zoffset, x, y, width, height, self); +} + + +void GLAPIENTRY +_mesa_CopyMultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, GLsizei width, GLsizei height) +{ + struct gl_texture_object* texObj; + const char *self = "glCopyMultiTexSubImage3D"; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + texunit - GL_TEXTURE0, + false, self); + if (!texObj) + return; + + if (texObj->Target == GL_TEXTURE_CUBE_MAP) { + /* Act like CopyTexSubImage2D */ + copy_texture_sub_image_err(ctx, 2, texObj, + GL_TEXTURE_CUBE_MAP_POSITIVE_X + zoffset, level, xoffset, yoffset, 0, x, y, width, height, self); } @@ -4882,6 +5368,44 @@ _mesa_CompressedTexImage1D(GLenum target, GLint level, } +void GLAPIENTRY +_mesa_CompressedTextureImage1DEXT(GLuint texture, GLenum target, GLint level, + GLenum internalFormat, GLsizei width, + GLint border, GLsizei imageSize, + const GLvoid *pixels) +{ + struct gl_texture_object* texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, + "glCompressedTextureImage1DEXT"); + if (!texObj) + return; + teximage(ctx, GL_TRUE, 1, texObj, target, level, internalFormat, + width, 1, 1, border, GL_NONE, GL_NONE, imageSize, pixels, false); +} + + +void GLAPIENTRY +_mesa_CompressedMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level, + GLenum internalFormat, GLsizei width, + GLint border, GLsizei imageSize, + const GLvoid *pixels) +{ + struct gl_texture_object* texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + texunit - GL_TEXTURE0, + true, + "glCompressedMultiTexImage1DEXT"); + if (!texObj) + return; + teximage(ctx, GL_TRUE, 1, texObj, target, level, internalFormat, + width, 1, 1, border, GL_NONE, GL_NONE, imageSize, pixels, false); +} + + void GLAPIENTRY _mesa_CompressedTexImage2D(GLenum target, GLint level, GLenum internalFormat, GLsizei width, @@ -4894,6 +5418,44 @@ _mesa_CompressedTexImage2D(GLenum target, GLint level, } +void GLAPIENTRY +_mesa_CompressedTextureImage2DEXT(GLuint texture, GLenum target, GLint level, + GLenum internalFormat, GLsizei width, + GLsizei height, GLint border, GLsizei imageSize, + const GLvoid *pixels) +{ + struct gl_texture_object* texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, + "glCompressedTextureImage2DEXT"); + if (!texObj) + return; + teximage(ctx, GL_TRUE, 2, texObj, target, level, internalFormat, + width, height, 1, border, GL_NONE, GL_NONE, imageSize, pixels, false); +} + + +void GLAPIENTRY +_mesa_CompressedMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level, + GLenum internalFormat, GLsizei width, + GLsizei height, GLint border, GLsizei imageSize, + const GLvoid *pixels) +{ + struct gl_texture_object* texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + texunit - GL_TEXTURE0, + true, + "glCompressedMultiTexImage2DEXT"); + if (!texObj) + return; + teximage(ctx, GL_TRUE, 2, texObj, target, level, internalFormat, + width, height, 1, border, GL_NONE, GL_NONE, imageSize, pixels, false); +} + + void GLAPIENTRY _mesa_CompressedTexImage3D(GLenum target, GLint level, GLenum internalFormat, GLsizei width, @@ -4906,6 +5468,44 @@ _mesa_CompressedTexImage3D(GLenum target, GLint level, } +void GLAPIENTRY +_mesa_CompressedTextureImage3DEXT(GLuint texture, GLenum target, GLint level, + GLenum internalFormat, GLsizei width, + GLsizei height, GLsizei depth, GLint border, + GLsizei imageSize, const GLvoid *pixels) +{ + struct gl_texture_object* texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, + "glCompressedTextureImage3DEXT"); + if (!texObj) + return; + teximage(ctx, GL_TRUE, 3, texObj, target, level, internalFormat, + width, height, depth, border, GL_NONE, GL_NONE, imageSize, pixels, false); +} + + +void GLAPIENTRY +_mesa_CompressedMultiTexImage3DEXT(GLenum texunit, GLenum target, GLint level, + GLenum internalFormat, GLsizei width, + GLsizei height, GLsizei depth, GLint border, + GLsizei imageSize, const GLvoid *pixels) +{ + struct gl_texture_object* texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + texunit - GL_TEXTURE0, + true, + "glCompressedMultiTexImage3DEXT"); + if (!texObj) + return; + teximage(ctx, GL_TRUE, 3, texObj, target, level, internalFormat, + width, height, depth, border, GL_NONE, GL_NONE, imageSize, pixels, false); +} + + void GLAPIENTRY _mesa_CompressedTexImage1D_no_error(GLenum target, GLint level, GLenum internalFormat, GLsizei width, @@ -4976,43 +5576,80 @@ compressed_texture_sub_image(struct gl_context *ctx, GLuint dims, } -static ALWAYS_INLINE void -compressed_tex_sub_image(unsigned dim, GLenum target, GLuint texture, +enum tex_mode { + /* Use bound texture to current unit */ + TEX_MODE_CURRENT_NO_ERROR = 0, + TEX_MODE_CURRENT_ERROR, + /* Use the specified texture name */ + TEX_MODE_DSA_NO_ERROR, + TEX_MODE_DSA_ERROR, + /* Use the specified texture name + target */ + TEX_MODE_EXT_DSA_TEXTURE, + /* Use the specified texture unit + target */ + TEX_MODE_EXT_DSA_TEXUNIT, +}; + + +static void +compressed_tex_sub_image(unsigned dim, GLenum target, GLuint textureOrIndex, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, - const GLvoid *data, bool dsa, bool no_error, + const GLvoid *data, enum tex_mode mode, const char *caller) { struct gl_texture_object *texObj = NULL; struct gl_texture_image *texImage; - + bool no_error = false; GET_CURRENT_CONTEXT(ctx); - if (dsa) { - if (no_error) { - texObj = _mesa_lookup_texture(ctx, texture); - } else { - texObj = _mesa_lookup_texture_err(ctx, texture, caller); - if (!texObj) - return; - } - - target = texObj->Target; + switch (mode) { + case TEX_MODE_DSA_ERROR: + assert(target == 0); + texObj = _mesa_lookup_texture_err(ctx, textureOrIndex, caller); + if (texObj) + target = texObj->Target; + break; + case TEX_MODE_DSA_NO_ERROR: + assert(target == 0); + texObj = _mesa_lookup_texture(ctx, textureOrIndex); + if (texObj) + target = texObj->Target; + no_error = true; + break; + case TEX_MODE_EXT_DSA_TEXTURE: + texObj = _mesa_lookup_or_create_texture(ctx, target, textureOrIndex, + false, true, caller); + break; + case TEX_MODE_EXT_DSA_TEXUNIT: + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + textureOrIndex, + false, + caller); + break; + case TEX_MODE_CURRENT_NO_ERROR: + no_error = true; + case TEX_MODE_CURRENT_ERROR: + default: + assert(textureOrIndex == 0); + break; } if (!no_error && - compressed_subtexture_target_check(ctx, target, dim, format, dsa, + compressed_subtexture_target_check(ctx, target, dim, format, + mode == TEX_MODE_DSA_ERROR, caller)) { return; } - if (!dsa) { + if (mode == TEX_MODE_CURRENT_NO_ERROR || + mode == TEX_MODE_CURRENT_ERROR) { texObj = _mesa_get_current_tex_object(ctx, target); - if (!no_error && !texObj) - return; } + if (!texObj) + return; + if (!no_error && compressed_subtexture_error_check(ctx, dim, texObj, target, level, xoffset, yoffset, zoffset, width, @@ -5022,7 +5659,9 @@ compressed_tex_sub_image(unsigned dim, GLenum target, GLuint texture, } /* Must handle special case GL_TEXTURE_CUBE_MAP. */ - if (dim == 3 && dsa && texObj->Target == GL_TEXTURE_CUBE_MAP) { + if (dim == 3 && + (mode == TEX_MODE_DSA_ERROR || mode == TEX_MODE_DSA_NO_ERROR) && + texObj->Target == GL_TEXTURE_CUBE_MAP) { const char *pixels = data; GLint image_stride; @@ -5064,31 +5703,6 @@ compressed_tex_sub_image(unsigned dim, GLenum target, GLuint texture, } } -static void -compressed_tex_sub_image_error(unsigned dim, GLenum target, GLuint texture, - GLint level, GLint xoffset, GLint yoffset, - GLint zoffset, GLsizei width, GLsizei height, - GLsizei depth, GLenum format, GLsizei imageSize, - const GLvoid *data, bool dsa, - const char *caller) -{ - compressed_tex_sub_image(dim, target, texture, level, xoffset, yoffset, - zoffset, width, height, depth, format, imageSize, - data, dsa, false, caller); -} - -static void -compressed_tex_sub_image_no_error(unsigned dim, GLenum target, GLuint texture, - GLint level, GLint xoffset, GLint yoffset, - GLint zoffset, GLsizei width, GLsizei height, - GLsizei depth, GLenum format, GLsizei imageSize, - const GLvoid *data, bool dsa, - const char *caller) -{ - compressed_tex_sub_image(dim, target, texture, level, xoffset, yoffset, - zoffset, width, height, depth, format, imageSize, - data, dsa, true, caller); -} void GLAPIENTRY _mesa_CompressedTexSubImage1D_no_error(GLenum target, GLint level, @@ -5096,9 +5710,11 @@ _mesa_CompressedTexSubImage1D_no_error(GLenum target, GLint level, GLenum format, GLsizei imageSize, const GLvoid *data) { - compressed_tex_sub_image_no_error(1, target, 0, level, xoffset, 0, 0, width, - 1, 1, format, imageSize, data, false, - "glCompressedTexSubImage1D"); + compressed_tex_sub_image(1, target, 0, + level, xoffset, 0, 0, width, + 1, 1, format, imageSize, data, + TEX_MODE_CURRENT_NO_ERROR, + "glCompressedTexSubImage1D"); } @@ -5107,9 +5723,11 @@ _mesa_CompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data) { - compressed_tex_sub_image_error(1, target, 0, level, xoffset, 0, 0, width, 1, - 1, format, imageSize, data, false, - "glCompressedTexSubImage1D"); + compressed_tex_sub_image(1, target, 0, + level, xoffset, 0, 0, width, + 1, 1, format, imageSize, data, + TEX_MODE_CURRENT_ERROR, + "glCompressedTexSubImage1D"); } @@ -5119,9 +5737,11 @@ _mesa_CompressedTextureSubImage1D_no_error(GLuint texture, GLint level, GLenum format, GLsizei imageSize, const GLvoid *data) { - compressed_tex_sub_image_no_error(1, 0, texture, level, xoffset, 0, 0, width, - 1, 1, format, imageSize, data, true, - "glCompressedTextureSubImage1D"); + compressed_tex_sub_image(1, 0, texture, + level, xoffset, 0, 0, + width, 1, 1, format, imageSize, data, + TEX_MODE_DSA_NO_ERROR, + "glCompressedTextureSubImage1D"); } @@ -5130,11 +5750,42 @@ _mesa_CompressedTextureSubImage1D(GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data) { - compressed_tex_sub_image_error(1, 0, texture, level, xoffset, 0, 0, width, - 1, 1, format, imageSize, data, true, - "glCompressedTextureSubImage1D"); + compressed_tex_sub_image(1, 0, texture, + level, xoffset, 0, 0, + width, 1, 1, format, imageSize, data, + TEX_MODE_DSA_ERROR, + "glCompressedTextureSubImage1D"); +} + + +void GLAPIENTRY +_mesa_CompressedTextureSubImage1DEXT(GLuint texture, GLenum target, + GLint level, GLint xoffset, + GLsizei width, GLenum format, + GLsizei imageSize, const GLvoid *data) +{ + compressed_tex_sub_image(1, target, texture, level, xoffset, 0, + 0, width, 1, 1, format, imageSize, + data, + TEX_MODE_EXT_DSA_TEXTURE, + "glCompressedTextureSubImage1DEXT"); +} + + +void GLAPIENTRY +_mesa_CompressedMultiTexSubImage1DEXT(GLenum texunit, GLenum target, + GLint level, GLint xoffset, + GLsizei width, GLenum format, + GLsizei imageSize, const GLvoid *data) +{ + compressed_tex_sub_image(1, target, texunit - GL_TEXTURE0, level, + xoffset, 0, 0, width, 1, 1, format, imageSize, + data, + TEX_MODE_EXT_DSA_TEXUNIT, + "glCompressedMultiTexSubImage1DEXT"); } + void GLAPIENTRY _mesa_CompressedTexSubImage2D_no_error(GLenum target, GLint level, GLint xoffset, GLint yoffset, @@ -5142,9 +5793,11 @@ _mesa_CompressedTexSubImage2D_no_error(GLenum target, GLint level, GLenum format, GLsizei imageSize, const GLvoid *data) { - compressed_tex_sub_image_no_error(2, target, 0, level, xoffset, yoffset, 0, - width, height, 1, format, imageSize, data, - false, "glCompressedTexSubImage2D"); + compressed_tex_sub_image(2, target, 0, level, + xoffset, yoffset, 0, + width, height, 1, format, imageSize, data, + TEX_MODE_CURRENT_NO_ERROR, + "glCompressedTexSubImage2D"); } @@ -5154,9 +5807,40 @@ _mesa_CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLenum format, GLsizei imageSize, const GLvoid *data) { - compressed_tex_sub_image_error(2, target, 0, level, xoffset, yoffset, 0, - width, height, 1, format, imageSize, data, - false, "glCompressedTexSubImage2D"); + compressed_tex_sub_image(2, target, 0, level, + xoffset, yoffset, 0, + width, height, 1, format, imageSize, data, + TEX_MODE_CURRENT_ERROR, + "glCompressedTexSubImage2D"); +} + + +void GLAPIENTRY +_mesa_CompressedTextureSubImage2DEXT(GLuint texture, GLenum target, + GLint level, GLint xoffset, + GLint yoffset, GLsizei width, + GLsizei height, GLenum format, + GLsizei imageSize, const GLvoid *data) +{ + compressed_tex_sub_image(2, target, texture, level, xoffset, + yoffset, 0, width, height, 1, format, + imageSize, data, + TEX_MODE_EXT_DSA_TEXTURE, + "glCompressedTextureSubImage2DEXT"); +} + + +void GLAPIENTRY +_mesa_CompressedMultiTexSubImage2DEXT(GLenum texunit, GLenum target, + GLint level, GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLenum format, + GLsizei imageSize, const GLvoid *data) +{ + compressed_tex_sub_image(2, target, texunit - GL_TEXTURE0, level, + xoffset, yoffset, 0, width, height, 1, format, + imageSize, data, + TEX_MODE_EXT_DSA_TEXUNIT, + "glCompressedMultiTexSubImage2DEXT"); } @@ -5167,9 +5851,10 @@ _mesa_CompressedTextureSubImage2D_no_error(GLuint texture, GLint level, GLenum format, GLsizei imageSize, const GLvoid *data) { - compressed_tex_sub_image_no_error(2, 0, texture, level, xoffset, yoffset, 0, - width, height, 1, format, imageSize, data, - true, "glCompressedTextureSubImage2D"); + compressed_tex_sub_image(2, 0, texture, level, xoffset, yoffset, 0, + width, height, 1, format, imageSize, data, + TEX_MODE_DSA_NO_ERROR, + "glCompressedTextureSubImage2D"); } @@ -5180,9 +5865,10 @@ _mesa_CompressedTextureSubImage2D(GLuint texture, GLint level, GLint xoffset, GLenum format, GLsizei imageSize, const GLvoid *data) { - compressed_tex_sub_image_error(2, 0, texture, level, xoffset, yoffset, 0, - width, height, 1, format, imageSize, data, - true, "glCompressedTextureSubImage2D"); + compressed_tex_sub_image(2, 0, texture, level, xoffset, yoffset, 0, + width, height, 1, format, imageSize, data, + TEX_MODE_DSA_ERROR, + "glCompressedTextureSubImage2D"); } void GLAPIENTRY @@ -5193,10 +5879,11 @@ _mesa_CompressedTexSubImage3D_no_error(GLenum target, GLint level, GLenum format, GLsizei imageSize, const GLvoid *data) { - compressed_tex_sub_image_no_error(3, target, 0, level, xoffset, yoffset, - zoffset, width, height, depth, format, - imageSize, data, false, - "glCompressedTexSubImage3D"); + compressed_tex_sub_image(3, target, 0, level, xoffset, yoffset, + zoffset, width, height, depth, format, + imageSize, data, + TEX_MODE_CURRENT_NO_ERROR, + "glCompressedTexSubImage3D"); } void GLAPIENTRY @@ -5205,10 +5892,11 @@ _mesa_CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data) { - compressed_tex_sub_image_error(3, target, 0, level, xoffset, yoffset, - zoffset, width, height, depth, format, - imageSize, data, false, - "glCompressedTexSubImage3D"); + compressed_tex_sub_image(3, target, 0, level, xoffset, yoffset, + zoffset, width, height, depth, format, + imageSize, data, + TEX_MODE_CURRENT_ERROR, + "glCompressedTexSubImage3D"); } void GLAPIENTRY @@ -5219,10 +5907,11 @@ _mesa_CompressedTextureSubImage3D_no_error(GLuint texture, GLint level, GLenum format, GLsizei imageSize, const GLvoid *data) { - compressed_tex_sub_image_no_error(3, 0, texture, level, xoffset, yoffset, - zoffset, width, height, depth, format, - imageSize, data, true, - "glCompressedTextureSubImage3D"); + compressed_tex_sub_image(3, 0, texture, level, xoffset, yoffset, + zoffset, width, height, depth, format, + imageSize, data, + TEX_MODE_DSA_NO_ERROR, + "glCompressedTextureSubImage3D"); } void GLAPIENTRY @@ -5232,12 +5921,45 @@ _mesa_CompressedTextureSubImage3D(GLuint texture, GLint level, GLint xoffset, GLenum format, GLsizei imageSize, const GLvoid *data) { - compressed_tex_sub_image_error(3, 0, texture, level, xoffset, yoffset, - zoffset, width, height, depth, format, - imageSize, data, true, - "glCompressedTextureSubImage3D"); + compressed_tex_sub_image(3, 0, texture, level, xoffset, yoffset, + zoffset, width, height, depth, format, + imageSize, data, + TEX_MODE_DSA_ERROR, + "glCompressedTextureSubImage3D"); +} + + +void GLAPIENTRY +_mesa_CompressedTextureSubImage3DEXT(GLuint texture, GLenum target, + GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, + GLsizei depth, GLenum format, + GLsizei imageSize, const GLvoid *data) +{ + compressed_tex_sub_image(3, target, texture, level, xoffset, yoffset, + zoffset, width, height, depth, format, + imageSize, data, + TEX_MODE_EXT_DSA_TEXTURE, + "glCompressedTextureSubImage3DEXT"); +} + + +void GLAPIENTRY +_mesa_CompressedMultiTexSubImage3DEXT(GLenum texunit, GLenum target, + GLint level, GLint xoffset, GLint yoffset, + GLint zoffset, GLsizei width, GLsizei height, + GLsizei depth, GLenum format, + GLsizei imageSize, const GLvoid *data) +{ + compressed_tex_sub_image(3, target, texunit - GL_TEXTURE0, level, + xoffset, yoffset, zoffset, width, height, depth, + format, imageSize, data, + TEX_MODE_EXT_DSA_TEXUNIT, + "glCompressedMultiTexSubImage3DEXT"); } + mesa_format _mesa_get_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat) { @@ -5284,9 +6006,9 @@ _mesa_get_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat) case GL_LUMINANCE32UI_EXT: return MESA_FORMAT_L_UINT32; case GL_LUMINANCE8_ALPHA8: - return MESA_FORMAT_L8A8_UNORM; + return MESA_FORMAT_LA_UNORM8; case GL_LUMINANCE16_ALPHA16: - return MESA_FORMAT_L16A16_UNORM; + return MESA_FORMAT_LA_UNORM16; case GL_LUMINANCE_ALPHA16F_ARB: return MESA_FORMAT_LA_FLOAT16; case GL_LUMINANCE_ALPHA32F_ARB: @@ -5367,11 +6089,11 @@ _mesa_get_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat) return MESA_FORMAT_RGBA_UINT32; case GL_RG8: - return MESA_FORMAT_R8G8_UNORM; + return MESA_FORMAT_RG_UNORM8; case GL_RG16: if (_mesa_is_gles(ctx) && !_mesa_has_EXT_texture_norm16(ctx)) return MESA_FORMAT_NONE; - return MESA_FORMAT_R16G16_UNORM; + return MESA_FORMAT_RG_UNORM16; case GL_RG16F: return MESA_FORMAT_RG_FLOAT16; case GL_RG32F: @@ -5679,6 +6401,52 @@ _mesa_TexBufferRange(GLenum target, GLenum internalFormat, GLuint buffer, offset, size, "glTexBufferRange"); } + +/** GL_ARB_texture_buffer_range + GL_EXT_direct_state_access */ +void GLAPIENTRY +_mesa_TextureBufferRangeEXT(GLuint texture, GLenum target, GLenum internalFormat, + GLuint buffer, GLintptr offset, GLsizeiptr size) +{ + struct gl_texture_object *texObj; + struct gl_buffer_object *bufObj; + + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, + "glTextureBufferRangeEXT"); + if (!texObj) + return; + + if (!check_texture_buffer_target(ctx, target, "glTextureBufferRangeEXT")) + return; + + if (buffer) { + bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glTextureBufferRangeEXT"); + if (!bufObj) + return; + + if (!check_texture_buffer_range(ctx, bufObj, offset, size, + "glTextureBufferRangeEXT")) + return; + + } else { + /* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer + * Textures (PDF page 254): + * "If buffer is zero, then any buffer object attached to the buffer + * texture is detached, the values offset and size are ignored and + * the state for offset and size for the buffer texture are reset to + * zero." + */ + offset = 0; + size = 0; + bufObj = NULL; + } + + texture_buffer_range(ctx, texObj, internalFormat, bufObj, + offset, size, "glTextureBufferRangeEXT"); +} + + void GLAPIENTRY _mesa_TextureBuffer(GLuint texture, GLenum internalFormat, GLuint buffer) { @@ -5706,6 +6474,65 @@ _mesa_TextureBuffer(GLuint texture, GLenum internalFormat, GLuint buffer) bufObj, 0, buffer ? -1 : 0, "glTextureBuffer"); } +void GLAPIENTRY +_mesa_TextureBufferEXT(GLuint texture, GLenum target, + GLenum internalFormat, GLuint buffer) +{ + struct gl_texture_object *texObj; + struct gl_buffer_object *bufObj; + + GET_CURRENT_CONTEXT(ctx); + + if (buffer) { + bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glTextureBuffer"); + if (!bufObj) + return; + } else + bufObj = NULL; + + /* Get the texture object by Name. */ + texObj = _mesa_lookup_or_create_texture(ctx, target, texture, + false, true, + "glTextureBufferEXT"); + + if (!texObj || + !check_texture_buffer_target(ctx, texObj->Target, "glTextureBufferEXT")) + return; + + texture_buffer_range(ctx, texObj, internalFormat, + bufObj, 0, buffer ? -1 : 0, "glTextureBufferEXT"); +} + +void GLAPIENTRY +_mesa_MultiTexBufferEXT(GLenum texunit, GLenum target, + GLenum internalFormat, GLuint buffer) +{ + struct gl_texture_object *texObj; + struct gl_buffer_object *bufObj; + + GET_CURRENT_CONTEXT(ctx); + + if (buffer) { + bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glMultiTexBufferEXT"); + if (!bufObj) + return; + } else + bufObj = NULL; + + /* Get the texture object */ + texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, + texunit - GL_TEXTURE0, + true, + "glMultiTexBufferEXT"); + + if (!texObj || + !check_texture_buffer_target(ctx, texObj->Target, "glMultiTexBufferEXT")) + return; + + texture_buffer_range(ctx, texObj, internalFormat, + bufObj, 0, buffer ? -1 : 0, "glMultiTexBufferEXT"); +} + void GLAPIENTRY _mesa_TextureBufferRange(GLuint texture, GLenum internalFormat, GLuint buffer, GLintptr offset, GLsizeiptr size)