[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