mesa: Separate PBO validation checks from buffer mapping, to allow reuse
authorEduardo Lima Mitev <elima@igalia.com>
Thu, 12 Mar 2015 07:14:03 +0000 (08:14 +0100)
committerEduardo Lima Mitev <elima@igalia.com>
Fri, 13 Mar 2015 15:40:20 +0000 (16:40 +0100)
Internal PBO functions such as _mesa_map_validate_pbo_source() and
_mesa_validate_pbo_compressed_teximage() perform validation and buffer mapping
within the same call.

This patch takes out the validation into separate functions to allow reuse
of functionality by other code (i.e, gl(Compressed)Tex(Sub)Image).

Reviewed-by: Laura Ekstrand <laura@jlekstrand.net>
src/mesa/main/pbo.c
src/mesa/main/pbo.h

index 259f763208ef65be57834bb4af0e37c388f71420..0c16025320136b33680acba733a4e5301799f84f 100644 (file)
@@ -164,23 +164,18 @@ _mesa_map_pbo_source(struct gl_context *ctx,
    return buf;
 }
 
-
 /**
- * Combine PBO-read validation and mapping.
- * If any GL errors are detected, they'll be recorded and NULL returned.
+ * Perform PBO validation for read operations with uncompressed textures.
+ * If any GL errors are detected, false is returned, otherwise returns true.
  * \sa _mesa_validate_pbo_access
- * \sa _mesa_map_pbo_source
- * A call to this function should have a matching call to
- * _mesa_unmap_pbo_source().
  */
-const GLvoid *
-_mesa_map_validate_pbo_source(struct gl_context *ctx,
-                              GLuint dimensions,
-                              const struct gl_pixelstore_attrib *unpack,
-                              GLsizei width, GLsizei height, GLsizei depth,
-                              GLenum format, GLenum type,
-                              GLsizei clientMemSize,
-                              const GLvoid *ptr, const char *where)
+bool
+_mesa_validate_pbo_source(struct gl_context *ctx, GLuint dimensions,
+                          const struct gl_pixelstore_attrib *unpack,
+                          GLsizei width, GLsizei height, GLsizei depth,
+                          GLenum format, GLenum type,
+                          GLsizei clientMemSize,
+                          const GLvoid *ptr, const char *where)
 {
    assert(dimensions == 1 || dimensions == 2 || dimensions == 3);
 
@@ -188,24 +183,85 @@ _mesa_map_validate_pbo_source(struct gl_context *ctx,
                                   format, type, clientMemSize, ptr)) {
       if (_mesa_is_bufferobj(unpack->BufferObj)) {
          _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "%s(out of bounds PBO access)", where);
+                     "%s(out of bounds PBO access)",
+                     where);
       } else {
          _mesa_error(ctx, GL_INVALID_OPERATION,
                      "%s(out of bounds access: bufSize (%d) is too small)",
                      where, clientMemSize);
       }
-      return NULL;
+      return false;
    }
 
    if (!_mesa_is_bufferobj(unpack->BufferObj)) {
       /* non-PBO access: no further validation to be done */
-      return ptr;
+      return true;
    }
 
    if (_mesa_check_disallowed_mapping(unpack->BufferObj)) {
       /* buffer is already mapped - that's an error */
-      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(PBO is mapped)", where);
-      return NULL;
+      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(PBO is mapped)",
+                  where);
+      return false;
+   }
+
+   return true;
+}
+
+/**
+ * Perform PBO validation for read operations with compressed textures.
+ * If any GL errors are detected, false is returned, otherwise returns true.
+ */
+bool
+_mesa_validate_pbo_source_compressed(struct gl_context *ctx, GLuint dimensions,
+                                     const struct gl_pixelstore_attrib *unpack,
+                                     GLsizei imageSize, const GLvoid *pixels,
+                                     const char *where)
+{
+   if (!_mesa_is_bufferobj(unpack->BufferObj)) {
+      /* not using a PBO */
+      return true;
+   }
+
+   if ((const GLubyte *) pixels + imageSize >
+       ((const GLubyte *) 0) + unpack->BufferObj->Size) {
+      /* out of bounds read! */
+      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid PBO access)",
+                  where);
+      return false;
+   }
+
+   if (_mesa_check_disallowed_mapping(unpack->BufferObj)) {
+      /* buffer is already mapped - that's an error */
+      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(PBO is mapped)",
+                  where);
+      return false;
+   }
+
+   return true;
+}
+
+/**
+ * Perform PBO-read mapping.
+ * If any GL errors are detected, they'll be recorded and NULL returned.
+ * \sa _mesa_validate_pbo_source
+ * \sa _mesa_map_pbo_source
+ * A call to this function should have a matching call to
+ * _mesa_unmap_pbo_source().
+ */
+const GLvoid *
+_mesa_map_validate_pbo_source(struct gl_context *ctx,
+                              GLuint dimensions,
+                              const struct gl_pixelstore_attrib *unpack,
+                              GLsizei width, GLsizei height, GLsizei depth,
+                              GLenum format, GLenum type,
+                              GLsizei clientMemSize,
+                              const GLvoid *ptr, const char *where)
+{
+   if (!_mesa_validate_pbo_source(ctx, dimensions, unpack,
+                                  width, height, depth, format, type,
+                                  clientMemSize, ptr, where)) {
+     return NULL;
    }
 
    ptr = _mesa_map_pbo_source(ctx, unpack, ptr);
@@ -381,28 +437,27 @@ _mesa_validate_pbo_compressed_teximage(struct gl_context *ctx,
 {
    GLubyte *buf;
 
+   if (!_mesa_validate_pbo_source_compressed(ctx, dimensions, packing,
+                                             imageSize, pixels, funcName)) {
+     /* error is already set during validation */
+      return NULL;
+   }
+
    if (!_mesa_is_bufferobj(packing->BufferObj)) {
       /* not using a PBO - return pointer unchanged */
       return pixels;
    }
-   if ((const GLubyte *) pixels + imageSize >
-       ((const GLubyte *) 0) + packing->BufferObj->Size) {
-      /* out of bounds read! */
-      _mesa_error(ctx, GL_INVALID_OPERATION, "%s%uD(invalid PBO access)",
-                  funcName, dimensions);
-      return NULL;
-   }
 
    buf = (GLubyte*) ctx->Driver.MapBufferRange(ctx, 0,
                                               packing->BufferObj->Size,
                                               GL_MAP_READ_BIT,
                                               packing->BufferObj,
                                                MAP_INTERNAL);
-   if (!buf) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "%s%uD(PBO is mapped)", funcName,
-                  dimensions);
-      return NULL;
-   }
+
+   /* Validation above already checked that PBO is not mapped, so buffer
+    * should not be null.
+    */
+   assert(buf);
 
    return ADD_POINTERS(buf, pixels);
 }
index 9851ef1a172fedc62b5ab9627fddf4ad86c48d91..b3f24e62bd2ab5a126c62c01a08464113a42e1f0 100644 (file)
@@ -92,4 +92,18 @@ _mesa_unmap_teximage_pbo(struct gl_context *ctx,
                          const struct gl_pixelstore_attrib *unpack);
 
 
+extern bool
+_mesa_validate_pbo_source(struct gl_context *ctx, GLuint dimensions,
+                          const struct gl_pixelstore_attrib *unpack,
+                          GLsizei width, GLsizei height, GLsizei depth,
+                          GLenum format, GLenum type,
+                          GLsizei clientMemSize,
+                          const GLvoid *ptr, const char *where);
+
+extern bool
+_mesa_validate_pbo_source_compressed(struct gl_context *ctx, GLuint dimensions,
+                                     const struct gl_pixelstore_attrib *unpack,
+                                     GLsizei imageSize, const GLvoid *ptr,
+                                     const char *where);
+
 #endif