<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>