[Mesa-dev] [PATCH 2/4] mesa/main: add generic bits of ARB_clear_texture impl
Ilia Mirkin
imirkin at alum.mit.edu
Thu Mar 6 22:41:16 PST 2014
Signed-off-by: Ilia Mirkin <imirkin at 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
More information about the mesa-dev
mailing list