<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Jun 13, 2014 at 5:59 PM, Neil Roberts <span dir="ltr"><<a href="mailto:neil@linux.intel.com" target="_blank">neil@linux.intel.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This adds the driver entry point for glClearTexSubImage and fills in the<br>
_mesa_ClearTexImage and _mesa_ClearTexSubImage functions that call it.<br>
---<br>
 src/mesa/main/dd.h       |  14 +++<br>
 src/mesa/main/teximage.c | 241 ++++++++++++++++++++++++++++++++++++++++++++++-<br>
 src/mesa/main/teximage.h |  12 +++<br>
 3 files changed, 266 insertions(+), 1 deletion(-)<br>
<br>
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h<br>
index 633ea2c..8976535 100644<br>
--- a/src/mesa/main/dd.h<br>
+++ b/src/mesa/main/dd.h<br>
@@ -239,6 +239,20 @@ struct dd_function_table {<br>
                         struct gl_texture_image *texImage );<br>
<br>
    /**<br>
+    * Called by glClearTex[Sub]Image<br>
+    *<br>
+    * Clears a rectangular region of the image to a given value. The<br>
+    * clearValue argument is either NULL or points to a single texel to use as<br>
+    * the clear value in the same internal format as the texture image. If it<br>
+    * is NULL then the texture should be cleared to zeroes.<br>
+    */<br>
+   void (*ClearTexSubImage)(struct gl_context *ctx,<br>
+                            struct gl_texture_image *texImage,<br>
+                            GLint xoffset, GLint yoffset, GLint zoffset,<br>
+                            GLsizei width, GLsizei height, GLsizei depth,<br>
+                            const GLvoid *clearValue);<br>
+<br>
+   /**<br>
     * Called by glCopyTex[Sub]Image[123]D().<br>
     *<br>
     * This function should copy a rectangular region in the rb to a single<br>
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c<br>
index a893c70..d5baac8 100644<br>
--- a/src/mesa/main/teximage.c<br>
+++ b/src/mesa/main/teximage.c<br>
@@ -51,6 +51,7 @@<br>
 #include "textureview.h"<br>
 #include "mtypes.h"<br>
 #include "glformats.h"<br>
+#include "texstore.h"<br>
<br>
<br>
 /**<br>
@@ -3848,20 +3849,259 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level,<br>
                    x, y, width, height);<br>
 }<br>
<br>
+static bool<br>
+clear_tex_image(struct gl_context *ctx,<br>
+                const char *function,<br>
+                struct gl_texture_image *texImage, GLint level,<br>
+                GLint xoffset, GLint yoffset, GLint zoffset,<br>
+                GLsizei width, GLsizei height, GLsizei depth,<br>
+                GLenum format, GLenum type,<br>
+                const void *data)<br>
+{<br>
+   struct gl_texture_object *texObj = texImage->TexObject;<br>
+   static const GLubyte zeroData[MAX_PIXEL_BYTES];<br>
+   GLubyte clearValue[MAX_PIXEL_BYTES];<br>
+   GLubyte *clearValuePtr = clearValue;<br>
+   GLenum internalFormat = texImage->InternalFormat;<br>
+   GLenum err;<br>
+<br>
+   if (texObj->Target == GL_TEXTURE_BUFFER) {<br>
+      _mesa_error(ctx, GL_INVALID_OPERATION,<br>
+                  "%s(buffer texture)", function);<br>
+      return false;<br>
+   }<br>
+<br>
+   if (_mesa_is_compressed_format(ctx, internalFormat)) {<br>
+      _mesa_error(ctx, GL_INVALID_OPERATION,<br>
+                  "%s(compressed texture)", function);<br>
+      return false;<br>
+   }<br>
+<br>
+   err = _mesa_error_check_format_and_type(ctx, format, type);<br>
+   if (err != GL_NO_ERROR) {<br>
+      _mesa_error(ctx, err,<br>
+                  "%s(incompatible format = %s, type = %s)",<br>
+                  function,<br>
+                  _mesa_lookup_enum_by_nr(format),<br>
+                  _mesa_lookup_enum_by_nr(type));<br>
+      return false;<br>
+   }<br>
+<br>
+   /* make sure internal format and format basically agree */<br>
+   if (!texture_formats_agree(internalFormat, format)) {<br>
+      _mesa_error(ctx, GL_INVALID_OPERATION,<br>
+                  "%s(incompatible internalFormat = %s, format = %s)",<br>
+                  function,<br>
+                  _mesa_lookup_enum_by_nr(internalFormat),<br>
+                  _mesa_lookup_enum_by_nr(format));<br>
+      return false;<br>
+   }<br>
+<br>
+   if (ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) {<br>
+      /* both source and dest must be integer-valued, or neither */<br>
+      if (_mesa_is_format_integer_color(texImage->TexFormat) !=<br>
+          _mesa_is_enum_format_integer(format)) {<br>
+         _mesa_error(ctx, GL_INVALID_OPERATION,<br>
+                     "%s(integer/non-integer format mismatch)",<br>
+                     function);<br>
+         return false;<br>
+      }<br>
+   }<br>
+<br>
+   if (!_mesa_texstore(ctx,<br>
+                       1, /* dims */<br>
+                       texImage->_BaseFormat,<br>
+                       texImage->TexFormat,<br>
+                       0, /* dstRowStride */<br>
+                       &clearValuePtr,<br>
+                       1, 1, 1, /* srcWidth/Height/Depth */<br>
+                       format, type,<br>
+                       data ? data : zeroData,<br>
+                       &ctx->DefaultPacking)) {<br>
+      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid format)", function);<br>
+      return false;<br>
+   }<br>
+<br>
+   ctx->Driver.ClearTexSubImage(ctx,<br>
+                                texImage,<br>
+                                xoffset, yoffset, zoffset,<br>
+                                width, height, depth,<br>
+                                data ? clearValue : NULL);<br>
+<br>
+   return true;<br>
+}<br>
+<br>
+static struct gl_texture_object *<br>
+get_tex_obj_for_clear(struct gl_context *ctx,<br>
+                      const char *function,<br>
+                      GLuint texture)<br>
+{<br>
+   struct gl_texture_object *texObj;<br>
+<br>
+   if (texture == 0) {<br>
+      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(zero texture)", function);<br>
+      return NULL;<br>
+   }<br>
+<br>
+   texObj = _mesa_lookup_texture(ctx, texture);<br>
+<br>
+   if (texObj == NULL) {<br>
+      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-gen name)", function);<br>
+      return NULL;<br>
+   }<br>
+<br>
+   if (texObj->Target == 0) {<br>
+      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unbound tex)", function);<br>
+      return NULL;<br>
+   }<br>
+<br>
+   return texObj;<br>
+}<br>
+<br>
+static int<br>
+get_tex_images_for_clear(struct gl_context *ctx,<br>
+                         const char *function,<br>
+                         struct gl_texture_object *texObj,<br>
+                         GLint level,<br>
+                         struct gl_texture_image **texImages)<br>
+{<br>
+   GLenum target;<br>
+   int i;<br>
+<br>
+   if (level < 0 || level >= MAX_TEXTURE_LEVELS) {<br>
+      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid level)", function);<br>
+      return 0;<br>
+   }<br>
+<br>
+   if (texObj->Target == GL_TEXTURE_CUBE_MAP) {<br>
+      for (i = 0; i < MAX_FACES; i++) {<br>
+         target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;<br>
+<br>
+         texImages[i] = _mesa_select_tex_image(ctx, texObj, target, level);<br>
+         if (texImages[i] == NULL) {<br>
+            _mesa_error(ctx, GL_INVALID_OPERATION,<br>
+                        "%s(invalid level)", function);<br>
+            return 0;<br>
+         }<br>
+      }<br>
+<br>
+      return MAX_FACES;<br>
+   }<br>
+<br>
+   texImages[0] = _mesa_select_tex_image(ctx, texObj, texObj->Target, level);<br></blockquote><div><br></div><div>Do you want this inside an else block?<br><br></div><div>Other than that, looks good to me.<br></div><div>
--Jason Ekstrand<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
+   if (texImages[0] == NULL) {<br>
+      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid level)", function);<br>
+      return 0;<br>
+   }<br>
+<br>
+   return 1;<br>
+}<br>
+<br>
 void GLAPIENTRY<br>
 _mesa_ClearTexSubImage( GLuint texture, GLint level,<br>
                         GLint xoffset, GLint yoffset, GLint zoffset,<br>
                         GLsizei width, GLsizei height, GLsizei depth,<br>
                         GLenum format, GLenum type, const void *data )<br>
 {<br>
+   GET_CURRENT_CONTEXT(ctx);<br>
+   struct gl_texture_object *texObj;<br>
+   struct gl_texture_image *texImages[MAX_FACES];<br>
+   int i, numImages;<br>
+   int minDepth, maxDepth;<br>
+   bool res;<br>
<br>
+   texObj = get_tex_obj_for_clear(ctx, "glClearTexSubImage", texture);<br>
+<br>
+   if (texObj == NULL)<br>
+      return;<br>
+<br>
+   _mesa_lock_texture(ctx, texObj);<br>
+<br>
+   numImages = get_tex_images_for_clear(ctx, "glClearTexSubImage",<br>
+                                        texObj, level, texImages);<br>
+   if (numImages == 0)<br>
+      goto out;<br>
+<br>
+   if (numImages == 1) {<br>
+      minDepth = -(int) texImages[0]->Border;<br>
+      maxDepth = texImages[0]->Depth;<br>
+   } else {<br>
+      minDepth = 0;<br>
+      maxDepth = numImages;<br>
+   }<br>
+<br>
+   if (xoffset < -(GLint) texImages[0]->Border ||<br>
+       yoffset < -(GLint) texImages[0]->Border ||<br>
+       zoffset < minDepth ||<br>
+       width < 0 ||<br>
+       height < 0 ||<br>
+       depth < 0 ||<br>
+       xoffset + width > texImages[0]->Width ||<br>
+       yoffset + height > texImages[0]->Height ||<br>
+       zoffset + depth > maxDepth) {<br>
+      _mesa_error(ctx, GL_INVALID_OPERATION,<br>
+                  "glClearSubTexImage(invalid dimensions)");<br>
+      goto out;<br>
+   }<br>
+<br>
+   if (numImages == 1) {<br>
+      clear_tex_image(ctx, "glClearTexSubImage",<br>
+                      texImages[0], level,<br>
+                      xoffset, yoffset, zoffset,<br>
+                      width, height, depth,<br>
+                      format, type, data);<br>
+   } else {<br>
+      for (i = zoffset; i < zoffset + depth; i++) {<br>
+         res = clear_tex_image(ctx, "glClearTexSubImage",<br>
+                               texImages[i], level,<br>
+                               xoffset, yoffset, 0,<br>
+                               width, height, 1,<br>
+                               format, type, data);<br>
+         if (!res)<br>
+            break;<br>
+      }<br>
+   }<br>
+<br>
+ out:<br>
+   _mesa_unlock_texture(ctx, texObj);<br>
 }<br>
<br>
 void GLAPIENTRY<br>
 _mesa_ClearTexImage( GLuint texture, GLint level,<br>
                      GLenum format, GLenum type, const void *data )<br>
 {<br>
+   GET_CURRENT_CONTEXT(ctx);<br>
+   struct gl_texture_object *texObj;<br>
+   struct gl_texture_image *texImages[MAX_FACES];<br>
+   int i, numImages;<br>
+   bool res;<br>
+<br>
+   texObj = get_tex_obj_for_clear(ctx, "glClearTexImage", texture);<br>
<br>
+   if (texObj == NULL)<br>
+      return;<br>
+<br>
+   _mesa_lock_texture(ctx, texObj);<br>
+<br>
+   numImages = get_tex_images_for_clear(ctx, "glClearTexImage",<br>
+                                        texObj, level, texImages);<br>
+<br>
+   for (i = 0; i < numImages; i++) {<br>
+      res = clear_tex_image(ctx, "glClearTexImage",<br>
+                            texImages[i], level,<br>
+                            -(GLint) texImages[i]->Border, /* xoffset */<br>
+                            -(GLint) texImages[i]->Border, /* yoffset */<br>
+                            -(GLint) texImages[i]->Border, /* zoffset */<br>
+                            texImages[i]->Width,<br>
+                            texImages[i]->Height,<br>
+                            texImages[i]->Depth,<br>
+                            format, type, data);<br>
+      if (!res)<br>
+         break;<br>
+   }<br>
+<br>
+   _mesa_unlock_texture(ctx, texObj);<br>
 }<br>
<br>
<br>
@@ -4624,7 +4864,6 @@ _mesa_TexStorage2DMultisample(GLenum target, GLsizei samples,<br>
                        "glTexStorage2DMultisample");<br>
 }<br>
<br>
-<br>
 void GLAPIENTRY<br>
 _mesa_TexStorage3DMultisample(GLenum target, GLsizei samples,<br>
                               GLenum internalformat, GLsizei width,<br>
diff --git a/src/mesa/main/teximage.h b/src/mesa/main/teximage.h<br>
index 42305f4..984321c 100644<br>
--- a/src/mesa/main/teximage.h<br>
+++ b/src/mesa/main/teximage.h<br>
@@ -336,6 +336,18 @@ _mesa_TexStorage3DMultisample(GLenum target, GLsizei samples,<br>
                               GLsizei height, GLsizei depth,<br>
                               GLboolean fixedsamplelocations);<br>
<br>
+extern void GLAPIENTRY<br>
+_mesa_ClearTexImage(GLuint texture, GLint level,<br>
+                    GLenum format, GLenum type,<br>
+                    const void *data);<br>
+<br>
+extern void GLAPIENTRY<br>
+_mesa_ClearTexSubImage(GLuint texture, GLint level,<br>
+                       GLint xoffset, GLint yoffset, GLint zoffset,<br>
+                       GLsizei width, GLsizei height, GLsizei depth,<br>
+                       GLenum format, GLenum type,<br>
+                       const void *data);<br>
+<br>
 bool<br>
 _mesa_compressed_texture_pixel_storage_error_check(struct gl_context *ctx,<br>
                                              GLint dimensions,<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.9.3<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>