<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Mar 10, 2015 at 11:34 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"><span class="">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>
</span> src/mesa/main/pbo.c | 119 ++++++++++++++++++++++++++++++++++++++--------------<br>
 src/mesa/main/pbo.h |  14 +++++++<br>
 2 files changed, 101 insertions(+), 32 deletions(-)<br>
<br>
diff --git a/src/mesa/main/pbo.c b/src/mesa/main/pbo.c<br>
index 259f763..46121a2 100644<br>
<div><div class="h5">--- 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></div></div></blockquote><div>Maybe say something like "If there are errors, return false, else return true"?  This is important because in other parts of the driver (like main/teximage.c), error checking functions return GL_TRUE if an error is found and GL_FALSE if one isn't found.  (Confusing, I know :< ) <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5">
  * \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>
</div></div>@@ -188,24 +183,85 @@ _mesa_map_validate_pbo_source(struct gl_context *ctx,<br>
<span class="">                                   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>
</span>-      } else {<br>
-         _mesa_error(ctx, GL_INVALID_OPERATION,<br></blockquote><div>You changed the order of the conditions from the original version.  In the original, if (_mesa_is_bufferobj), then say "out of bounds PBO access."  If (!_mesa_is_bufferobj), say "out of bounds access: bufSize is too small."  You have them switched around here. <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span class="">                      "%s(out of bounds access: bufSize (%d) is too small)",<br>
</span>                      where, clientMemSize);<br>
+      } else {<br>
+         _mesa_error(ctx, GL_INVALID_OPERATION,<br>
+                     "%s(out of bounds access)",<br>
+                     where);<br>
<span class="">       }<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>
</span>-      return NULL;<br>
+      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(PBO is mapped)",<br>
+                  where);<br>
<span class="">+      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></span></blockquote><div>Same here as above.  Say something about the return value (true or false). <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">
+ */<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>
</span>+      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid PBO access)",<br>
+                  where);<br>
<span class="">+      return false;<br>
+   }<br>
+<br>
</span>+   if (_mesa_check_disallowed_mapping(unpack->BufferObj)) {<br>
<span class="">+      /* buffer is already mapped - that's an error */<br>
</span>+      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(PBO is mapped)",<br>
+                  where);<br>
<div class="HOEnZb"><div class="h5">+      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>
</div></div><span class="im HOEnZb">    ptr = _mesa_map_pbo_source(ctx, unpack, ptr);<br>
</span><div class="HOEnZb"><div class="h5">@@ -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>
--<br>
2.1.3<br>
<br>
</div></div></blockquote></div><br></div></div>