<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Mar 5, 2015 at 12:20 AM, Eduardo Lima Mitev <span dir="ltr"><<a href="mailto:elima@igalia.com" target="_blank">elima@igalia.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Internal PBO functions such as _mesa_map_validate_pbo_source() and<br>
_mesa_validate_pbo_compressed_teximage() perform validation and buffer mapping<br>
within the same call.<br>
<br>
This patch takes out the validation into separate functions to allow reuse<br>
of functionality by other code (i.e, gl(Compressed)Tex(Sub)Image).<br>
---<br>
 src/mesa/main/pbo.c | 117 ++++++++++++++++++++++++++++++++++++++--------------<br>
 src/mesa/main/pbo.h |  14 +++++++<br>
 2 files changed, 100 insertions(+), 31 deletions(-)<br>
<br>
diff --git a/src/mesa/main/pbo.c b/src/mesa/main/pbo.c<br>
index 259f763..5ae248c 100644<br>
--- a/src/mesa/main/pbo.c<br>
+++ b/src/mesa/main/pbo.c<br>
@@ -164,23 +164,18 @@ _mesa_map_pbo_source(struct gl_context *ctx,<br>
    return buf;<br>
 }<br>
<br>
-<br>
 /**<br>
- * Combine PBO-read validation and mapping.<br>
+ * Perform PBO validation for read operations with uncompressed textures.<br>
  * If any GL errors are detected, they'll be recorded and NULL returned.<br>
  * \sa _mesa_validate_pbo_access<br>
- * \sa _mesa_map_pbo_source<br>
- * A call to this function should have a matching call to<br>
- * _mesa_unmap_pbo_source().<br>
  */<br>
-const GLvoid *<br>
-_mesa_map_validate_pbo_source(struct gl_context *ctx,<br>
-                              GLuint dimensions,<br>
-                              const struct gl_pixelstore_attrib *unpack,<br>
-                              GLsizei width, GLsizei height, GLsizei depth,<br>
-                              GLenum format, GLenum type,<br>
-                              GLsizei clientMemSize,<br>
-                              const GLvoid *ptr, const char *where)<br>
+bool<br>
+_mesa_validate_pbo_source(struct gl_context *ctx, GLuint dimensions,<br>
+                          const struct gl_pixelstore_attrib *unpack,<br>
+                          GLsizei width, GLsizei height, GLsizei depth,<br>
+                          GLenum format, GLenum type,<br>
+                          GLsizei clientMemSize,<br>
+                          const GLvoid *ptr, const char *where)<br>
 {<br>
    assert(dimensions == 1 || dimensions == 2 || dimensions == 3);<br>
<br>
@@ -188,26 +183,87 @@ _mesa_map_validate_pbo_source(struct gl_context *ctx,<br>
                                   format, type, clientMemSize, ptr)) {<br>
       if (_mesa_is_bufferobj(unpack->BufferObj)) {<br>
          _mesa_error(ctx, GL_INVALID_OPERATION,<br>
-                     "%s(out of bounds PBO access)", where);<br></blockquote><div>Changing the error to "%s%uD, where, dimensions" is not ideal because the other function that calls _mesa_map_validate_pbo_source is _mesa_PolygonStipple, and printing "glPolygonStipple2D" doesn't make sense because the name of the function is "glPolygonStipple."<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+                     "%s%uD(out of bounds PBO access)",<br>
+                     where, dimensions);<br>
       } else {<br>
          _mesa_error(ctx, GL_INVALID_OPERATION,<br></blockquote><div>Why did you remove "bufSize (%d) is too small"?  If we are going to remove that, maybe we should remove the if, then, else block because the error messages are pretty much the same.  I recommend keeping the original error messages for both and moving the "%sD" up to the calling functions (for example, texture_error_check).   <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
-                     "%s(out of bounds access: bufSize (%d) is too small)",<br>
-                     where, clientMemSize);<br>
+                     "%s%uD(out of bounds access)",<br>
+                     where, dimensions);<br>
       }<br>
-      return NULL;<br>
+      return false;<br>
    }<br>
<br>
    if (!_mesa_is_bufferobj(unpack->BufferObj)) {<br>
       /* non-PBO access: no further validation to be done */<br>
-      return ptr;<br>
+      return true;<br>
    }<br>
<br>
    if (_mesa_check_disallowed_mapping(unpack->BufferObj)) {<br>
       /* buffer is already mapped - that's an error */<br>
-      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(PBO is mapped)", where);<br>
+      _mesa_error(ctx, GL_INVALID_OPERATION, "%s%uD(PBO is mapped)",<br>
+                  where, dimensions);<br>
+      return false;<br>
+   }<br>
+<br>
+   return true;<br>
+}<br>
+<br>
+/**<br>
+ * Perform PBO validation for read operations with compressed textures.<br>
+ * If any GL errors are detected, they'll be recorded and NULL returned.<br>
+ */<br>
+bool<br>
+_mesa_validate_pbo_source_compressed(struct gl_context *ctx, GLuint dimensions,<br>
+                                     const struct gl_pixelstore_attrib *unpack,<br>
+                                     GLsizei imageSize, const GLvoid *pixels,<br>
+                                     const char *where)<br>
+{<br>
+   if (!_mesa_is_bufferobj(unpack->BufferObj)) {<br>
+      /* not using a PBO */<br>
+      return true;<br>
+   }<br>
+<br>
+   if ((const GLubyte *) pixels + imageSize ><br>
+       ((const GLubyte *) 0) + unpack->BufferObj->Size) {<br>
+      /* out of bounds read! */<br>
+      _mesa_error(ctx, GL_INVALID_OPERATION, "%s%uD(invalid PBO access)",<br>
+                  where, dimensions);<br></blockquote><div>This should be return false. <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
       return NULL;<br>
    }<br>
<br>
+   if (_mesa_check_disallowed_mapping(unpack->BufferObj)) {<br>
+      /* buffer is already mapped - that's an error */<br>
+      _mesa_error(ctx, GL_INVALID_OPERATION, "%s%uD(PBO is mapped)",<br>
+                  where, dimensions);<br>
+      return false;<br>
+   }<br>
+<br>
+   return true;<br>
+}<br>
+<br>
+/**<br>
+ * Perform PBO-read mapping.<br>
+ * If any GL errors are detected, they'll be recorded and NULL returned.<br>
+ * \sa _mesa_validate_pbo_source<br>
+ * \sa _mesa_map_pbo_source<br>
+ * A call to this function should have a matching call to<br>
+ * _mesa_unmap_pbo_source().<br>
+ */<br>
+const GLvoid *<br>
+_mesa_map_validate_pbo_source(struct gl_context *ctx,<br>
+                              GLuint dimensions,<br>
+                              const struct gl_pixelstore_attrib *unpack,<br>
+                              GLsizei width, GLsizei height, GLsizei depth,<br>
+                              GLenum format, GLenum type,<br>
+                              GLsizei clientMemSize,<br>
+                              const GLvoid *ptr, const char *where)<br>
+{<br>
+   if (!_mesa_validate_pbo_source(ctx, dimensions, unpack,<br>
+                                  width, height, depth, format, type,<br>
+                                  clientMemSize, ptr, where)) {<br>
+     return NULL;<br>
+   }<br>
+<br>
    ptr = _mesa_map_pbo_source(ctx, unpack, ptr);<br>
    return ptr;<br>
 }<br>
@@ -381,28 +437,27 @@ _mesa_validate_pbo_compressed_teximage(struct gl_context *ctx,<br>
 {<br>
    GLubyte *buf;<br>
<br>
+   if (!_mesa_validate_pbo_source_compressed(ctx, dimensions, packing,<br>
+                                             imageSize, pixels, funcName)) {<br>
+     /* error is already set during validation */<br>
+      return NULL;<br>
+   }<br>
+<br>
    if (!_mesa_is_bufferobj(packing->BufferObj)) {<br>
       /* not using a PBO - return pointer unchanged */<br>
       return pixels;<br>
    }<br>
-   if ((const GLubyte *) pixels + imageSize ><br>
-       ((const GLubyte *) 0) + packing->BufferObj->Size) {<br>
-      /* out of bounds read! */<br>
-      _mesa_error(ctx, GL_INVALID_OPERATION, "%s%uD(invalid PBO access)",<br>
-                  funcName, dimensions);<br>
-      return NULL;<br>
-   }<br>
<br>
    buf = (GLubyte*) ctx->Driver.MapBufferRange(ctx, 0,<br>
                                               packing->BufferObj->Size,<br>
                                               GL_MAP_READ_BIT,<br>
                                               packing->BufferObj,<br>
                                                MAP_INTERNAL);<br>
-   if (!buf) {<br>
-      _mesa_error(ctx, GL_INVALID_OPERATION, "%s%uD(PBO is mapped)", funcName,<br>
-                  dimensions);<br>
-      return NULL;<br>
-   }<br>
+<br>
+   /* Validation above already checked that PBO is not mapped, so buffer<br>
+    * should not be null.<br>
+    */<br>
+   assert(buf);<br>
<br>
    return ADD_POINTERS(buf, pixels);<br>
 }<br>
diff --git a/src/mesa/main/pbo.h b/src/mesa/main/pbo.h<br>
index 9851ef1..b3f24e6 100644<br>
--- a/src/mesa/main/pbo.h<br>
+++ b/src/mesa/main/pbo.h<br>
@@ -92,4 +92,18 @@ _mesa_unmap_teximage_pbo(struct gl_context *ctx,<br>
                          const struct gl_pixelstore_attrib *unpack);<br>
<br>
<br>
+extern bool<br>
+_mesa_validate_pbo_source(struct gl_context *ctx, GLuint dimensions,<br>
+                          const struct gl_pixelstore_attrib *unpack,<br>
+                          GLsizei width, GLsizei height, GLsizei depth,<br>
+                          GLenum format, GLenum type,<br>
+                          GLsizei clientMemSize,<br>
+                          const GLvoid *ptr, const char *where);<br>
+<br>
+extern bool<br>
+_mesa_validate_pbo_source_compressed(struct gl_context *ctx, GLuint dimensions,<br>
+                                     const struct gl_pixelstore_attrib *unpack,<br>
+                                     GLsizei imageSize, const GLvoid *ptr,<br>
+                                     const char *where);<br>
+<br>
 #endif<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.1.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>