Signed-off-by: Ilia Mirkin <imir...@alum.mit.edu> --- I believe I've addressed all the comments from Brian and Ian. If you still see something you mentioned before, please assume incompetence rather than malice :)
I'm happy to get rid of the border stuff and just stuck a assert(border == 0) in there. Like I said -- I'm really unsure as to what these things are. But if I do leave it in, I think that using Width is correct, at least in the comments, Width is listed as 2^logwidth + 2*border, so the clear will go from -border to 2^logwidth + border. src/mesa/main/dd.h | 14 +++++ src/mesa/main/teximage.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 163 insertions(+), 1 deletion(-) diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index 9715241..f05d62c 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -275,6 +275,20 @@ struct dd_function_table { GLint level, mesa_format format, GLint width, GLint height, GLint depth, GLint border); + + + /** + * Called by glClearTexImage and glClearTexSubImage. Should clear the + * specified area with the specified texel, provided in the TexFormat of + * the texImage. + */ + void (*ClearTexSubImage)(struct gl_context *ctx, + struct gl_texture_image *texImage, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + const GLubyte *clearValue, + GLsizeiptr clearValueSize); + /*@}*/ diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 2e671b0..65f0684 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -48,6 +48,7 @@ #include "texobj.h" #include "texstate.h" #include "texstorage.h" +#include "texstore.h" #include "textureview.h" #include "mtypes.h" #include "glformats.h" @@ -3794,22 +3795,169 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level, x, y, width, height); } +static struct gl_texture_image * +get_tex_image(struct gl_context *ctx, const char *function, + GLuint texture, GLint level, GLint zoffset) +{ + GLenum target = 0; + struct gl_texture_object *texObj = _mesa_lookup_texture(ctx, texture); + struct gl_texture_image *texImage; + + if (!texture || !texObj) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid texture)", function); + return NULL; + } + + switch (texObj->Target) { + case GL_TEXTURE_BUFFER: + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(texture can't be buffer)", function); + return NULL; + case GL_TEXTURE_CUBE_MAP_ARB: + case GL_TEXTURE_CUBE_MAP_ARRAY: + target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + zoffset; + break; + default: + break; + } + + texImage = _mesa_select_tex_image(ctx, texObj, target, level); + if (!texImage) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(missing image)", function); + return NULL; + } + + return texImage; +} + +static void +clear_tex_sub_image(struct gl_context *ctx, const char *function, + struct gl_texture_image *texImage, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const void *data) +{ + GLenum ret; + GLubyte clearValue[MAX_PIXEL_BYTES]; + GLubyte *clearValuePtr = clearValue; + GLsizeiptr clearValueSize; + + if (!texImage) + return; + + ret = _mesa_error_check_format_and_type(ctx, format, type); + if (ret != GL_NO_ERROR) { + _mesa_error(ctx, ret, "%s(invalid format, type)", function); + return; + } + + if (_mesa_is_compressed_format(ctx, texImage->InternalFormat)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(compressed format)", function); + return; + } + + if (texImage->_BaseFormat == GL_DEPTH_COMPONENT) { + if (format != GL_DEPTH_COMPONENT) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid format)", function); + return; + } + } else if (texImage->_BaseFormat == GL_DEPTH_STENCIL) { + if (format != GL_DEPTH_STENCIL) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid format)", function); + return; + } + } else if (texImage->_BaseFormat == GL_STENCIL_INDEX) { + if (format != GL_STENCIL_INDEX) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid format)", function); + return; + } + } else { + assert(_mesa_is_color_format(texImage->_BaseFormat)); + if (format == GL_DEPTH_COMPONENT || + format == GL_DEPTH_STENCIL || + format == GL_STENCIL_INDEX) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid format)", function); + return; + } + } + + if (_mesa_is_format_integer_color(texImage->TexFormat) != + _mesa_is_enum_format_or_type_integer(format, type)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid format)", function); + return; + } + + if (xoffset < -texImage->Border || + xoffset + width > texImage->Width - texImage->Border || + yoffset < -texImage->Border || + yoffset + height > texImage->Height - texImage->Border || + zoffset < -texImage->Border || + zoffset + depth > texImage->Depth - texImage->Border) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid bounds)", function); + } + + switch (texImage->TexObject->Target) { + case GL_TEXTURE_1D: + case GL_TEXTURE_1D_ARRAY: + if (width == 0) + return; + break; + default: + if (width == 0 && height == 0) + return; + break; + } + + clearValueSize = _mesa_get_format_bytes(texImage->TexFormat); + if (!data) { + memset(clearValue, 0, clearValueSize); + } else if (!_mesa_texstore(ctx, 1, texImage->_BaseFormat, + texImage->TexFormat, + 0, &clearValuePtr, 1, 1, 1, + format, type, data, &ctx->Unpack)) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", function); + return; + } + + ctx->Driver.ClearTexSubImage(ctx, texImage, xoffset, yoffset, zoffset, + width, height, depth, + clearValue, clearValueSize); +} + void GLAPIENTRY _mesa_ClearTexSubImage( GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data ) { + GET_CURRENT_CONTEXT(ctx); + struct gl_texture_image *texImage = + get_tex_image(ctx, "glClearTexSubImage", texture, level, zoffset); + clear_tex_sub_image(ctx, "glClearTexSubImage", texImage, + xoffset, yoffset, zoffset, + width, height, depth, format, type, data); } void GLAPIENTRY _mesa_ClearTexImage( GLuint texture, GLint level, GLenum format, GLenum type, const void *data ) { + GET_CURRENT_CONTEXT(ctx); -} + struct gl_texture_image *texImage = + get_tex_image(ctx, "glClearTexImage", texture, level, 0); + if (!texImage) + return; + /* XXX figure out which dimensions the texImage has, and pass in 0's for + * the border. + */ + clear_tex_sub_image(ctx, "glClearTexImage", texImage, + -texImage->Border, -texImage->Border, -texImage->Border, + texImage->Width, texImage->Height, texImage->Depth, + format, type, data); +} -- 1.8.3.2 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev