add a number of PBO validate/map/unmap functions
authorBrian Paul <brian.paul@tungstengraphics.com>
Fri, 21 Mar 2008 19:43:07 +0000 (13:43 -0600)
committerBrian Paul <brian.paul@tungstengraphics.com>
Fri, 21 Mar 2008 19:43:07 +0000 (13:43 -0600)
Helper functions for (some) drivers, including swrast.
cherry-picked from Mesa/master

src/mesa/main/bufferobj.c
src/mesa/main/bufferobj.h
src/mesa/swrast/s_bitmap.c
src/mesa/swrast/s_drawpix.c
src/mesa/swrast/s_readpix.c

index 009055a6ab6cba19851b32c212b46e40fe5e9479..71e571353f27b8ebc9ff2d7b6e65f305975c1ab4 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5.1
+ * Version:  7.1
  *
- * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -469,6 +469,189 @@ _mesa_validate_pbo_access(GLuint dimensions,
 }
 
 
+/**
+ * If the source of glBitmap data is a PBO, check that we won't read out
+ * of buffer bounds, then map the buffer.
+ * If not sourcing from a PBO, just return the bitmap pointer.
+ * This is a helper function for (some) drivers.
+ * Return NULL if error.
+ * If non-null return, must call validate_and_map_bitmap_pbo() when done.
+ */
+const GLubyte *
+_mesa_validate_and_map_bitmap_pbo(GLcontext *ctx,
+                                  GLsizei width, GLsizei height,
+                                  const struct gl_pixelstore_attrib *unpack,
+                                  const GLubyte *bitmap)
+{
+   const GLubyte *buf;
+
+   if (unpack->BufferObj->Name) {
+      /* unpack from PBO */
+      if (!_mesa_validate_pbo_access(2, unpack, width, height, 1,
+                                     GL_COLOR_INDEX, GL_BITMAP,
+                                     (GLvoid *) bitmap)) {
+         _mesa_error(ctx, GL_INVALID_OPERATION,"glBitmap(invalid PBO access)");
+         return NULL;
+      }
+
+      if (unpack->BufferObj->Pointer) {
+         /* buffer is already mapped - that's an error */
+         _mesa_error(ctx, GL_INVALID_OPERATION, "glBitmap(PBO is mapped)");
+         return NULL;
+      }
+
+      buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+                                              GL_READ_ONLY_ARB,
+                                              unpack->BufferObj);
+      if (!buf)
+         return NULL;
+
+      buf = ADD_POINTERS(buf, bitmap);
+   }
+   else {
+      /* unpack from normal memory */
+      buf = bitmap;
+   }
+
+   return buf;
+}
+
+
+/**
+ * Counterpart to validate_and_map_bitmap_pbo()
+ * This is a helper function for (some) drivers.
+ */
+void
+_mesa_unmap_bitmap_pbo(GLcontext *ctx,
+                       const struct gl_pixelstore_attrib *unpack)
+{
+   if (unpack->BufferObj->Name) {
+      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+                              unpack->BufferObj);
+   }
+}
+
+
+/**
+ * \sa _mesa_validate_and_map_bitmap_pbo
+ */
+const GLvoid *
+_mesa_validate_and_map_drawpix_pbo(GLcontext *ctx,
+                                   GLsizei width, GLsizei height,
+                                   GLenum format, GLenum type,
+                                   const struct gl_pixelstore_attrib *unpack,
+                                   const GLvoid *pixels)
+{
+   const GLvoid *buf;
+
+   if (unpack->BufferObj->Name) {
+      /* unpack from PBO */
+
+      if (!_mesa_validate_pbo_access(2, unpack, width, height, 1,
+                                     format, type, pixels)) {
+         _mesa_error(ctx, GL_INVALID_OPERATION,
+                     "glDrawPixels(invalid PBO access)");
+         return NULL;
+      }
+
+      if (unpack->BufferObj->Pointer) {
+         /* buffer is already mapped - that's an error */
+         _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels(PBO is mapped)");
+         return NULL;
+      }
+
+      buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+                                              GL_READ_ONLY_ARB,
+                                              unpack->BufferObj);
+      if (!buf)
+         return NULL;
+
+      buf = ADD_POINTERS(buf, pixels);
+   }
+   else {
+      /* unpack from normal memory */
+      buf = pixels;
+   }
+
+   return buf;
+}
+
+
+/**
+ * \sa _mesa_unmap_bitmap_pbo
+ */
+void
+_mesa_unmap_drapix_pbo(GLcontext *ctx,
+                       const struct gl_pixelstore_attrib *unpack)
+{
+   if (unpack->BufferObj->Name) {
+      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+                              unpack->BufferObj);
+   }
+}
+
+
+/**
+ * When doing glReadPixels into a PBO, this function will check for errors
+ * and map the buffer.
+ * Call _mesa_unmap_readpix_pbo() when finished
+ * \return NULL if error
+ */
+void *
+_mesa_validate_and_map_readpix_pbo(GLcontext *ctx,
+                                   GLint x, GLint y,
+                                   GLsizei width, GLsizei height,
+                                   GLenum format, GLenum type,
+                                   const struct gl_pixelstore_attrib *pack,
+                                   GLvoid *dest)
+{
+   void *buf;
+
+   if (pack->BufferObj->Name) {
+      /* pack into PBO */
+      if (!_mesa_validate_pbo_access(2, pack, width, height, 1,
+                                     format, type, dest)) {
+         _mesa_error(ctx, GL_INVALID_OPERATION,
+                     "glReadPixels(invalid PBO access)");
+         return NULL;
+      }
+
+      if (pack->BufferObj->Pointer) {
+         /* buffer is already mapped - that's an error */
+         _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(PBO is mapped)");
+         return NULL;
+      }
+
+      buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
+                                              GL_WRITE_ONLY_ARB,
+                                              pack->BufferObj);
+      if (!buf)
+         return NULL;
+
+      buf = ADD_POINTERS(buf, dest);
+   }
+   else {
+      /* pack to normal memory */
+      buf = dest;
+   }
+
+   return buf;
+}
+
+
+/**
+ * Counterpart to validate_and_map_readpix_pbo()
+ */
+void
+_mesa_unmap_readpix_pbo(GLcontext *ctx,
+                        const struct gl_pixelstore_attrib *pack)
+{
+   if (pack->BufferObj->Name) {
+      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, pack->BufferObj);
+   }
+}
+
+
 /**
  * Return the gl_buffer_object for the given ID.
  * Always return NULL for ID 0.
index f54f9e9ff00c1b228819eb8d8131fdcdac376af5..efb3b4711e1bd6373a8ccbdb15b96b408a37d92c 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.3
+ * Version:  7.1
  *
- * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -86,6 +86,41 @@ _mesa_validate_pbo_access(GLuint dimensions,
                           GLsizei width, GLsizei height, GLsizei depth,
                           GLenum format, GLenum type, const GLvoid *ptr);
 
+extern const GLubyte *
+_mesa_validate_and_map_bitmap_pbo(GLcontext *ctx,
+                                  GLsizei width, GLsizei height,
+                                  const struct gl_pixelstore_attrib *unpack,
+                                  const GLubyte *bitmap);
+
+extern void
+_mesa_unmap_bitmap_pbo(GLcontext *ctx,
+                       const struct gl_pixelstore_attrib *unpack);
+
+extern const GLvoid *
+_mesa_validate_and_map_drawpix_pbo(GLcontext *ctx,
+                                   GLsizei width, GLsizei height,
+                                   GLenum format, GLenum type,
+                                   const struct gl_pixelstore_attrib *unpack,
+                                   const GLvoid *pixels);
+
+extern void
+_mesa_unmap_drapix_pbo(GLcontext *ctx,
+                       const struct gl_pixelstore_attrib *unpack);
+
+
+extern void *
+_mesa_validate_and_map_readpix_pbo(GLcontext *ctx,
+                                   GLint x, GLint y,
+                                   GLsizei width, GLsizei height,
+                                   GLenum format, GLenum type,
+                                   const struct gl_pixelstore_attrib *pack,
+                                   GLvoid *dest);
+
+extern void
+_mesa_unmap_readpix_pbo(GLcontext *ctx,
+                        const struct gl_pixelstore_attrib *pack);
+
+
 extern void
 _mesa_unbind_buffer_object( GLcontext *ctx, struct gl_buffer_object *bufObj );
 
index 1e7f6c18e6a2df7d7c8248019be0635e6a26e0cf..17f639fd5578ee3c0c93008fa5c5d53970942f15 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5.2
+ * Version:  7.1
  *
- * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -57,24 +57,10 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
 
    ASSERT(ctx->RenderMode == GL_RENDER);
 
-   if (unpack->BufferObj->Name) {
-      /* unpack from PBO */
-      GLubyte *buf;
-      if (!_mesa_validate_pbo_access(2, unpack, width, height, 1,
-                                     GL_COLOR_INDEX, GL_BITMAP,
-                                     (GLvoid *) bitmap)) {
-         _mesa_error(ctx, GL_INVALID_OPERATION,"glBitmap(invalid PBO access)");
-         return;
-      }
-      buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
-                                              GL_READ_ONLY_ARB,
-                                              unpack->BufferObj);
-      if (!buf) {
-         /* buffer is already mapped - that's an error */
-         _mesa_error(ctx, GL_INVALID_OPERATION, "glBitmap(PBO is mapped)");
-         return;
-      }
-      bitmap = ADD_POINTERS(buf, bitmap);
+   bitmap = _mesa_validate_and_map_bitmap_pbo(ctx, width, height,
+                                              unpack, bitmap);
+   if (!bitmap) {
+      return NULL;
    }
 
    RENDER_START(swrast,ctx);
@@ -150,11 +136,7 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
 
    RENDER_FINISH(swrast,ctx);
 
-   if (unpack->BufferObj->Name) {
-      /* done with PBO so unmap it now */
-      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
-                              unpack->BufferObj);
-   }
+   _mesa_unmap_bitmap_pbo(ctx, unpack);
 }
 
 
index 0cf425e1c62a588e270b4cdede692661678512ef..2cf3501274ffcd679f23f57720d378f2fa2bf4e2 100644 (file)
@@ -812,7 +812,6 @@ draw_depth_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
 }
 
 
-
 /**
  * Execute software-based glDrawPixels.
  * By time we get here, all error checking will have been done.
@@ -835,25 +834,10 @@ _swrast_DrawPixels( GLcontext *ctx,
    if (swrast->NewState)
       _swrast_validate_derived( ctx );
 
-   if (unpack->BufferObj->Name) {
-      /* unpack from PBO */
-      GLubyte *buf;
-      if (!_mesa_validate_pbo_access(2, unpack, width, height, 1,
-                                     format, type, pixels)) {
-         _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glDrawPixels(invalid PBO access)");
-         goto end;
-      }
-      buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
-                                              GL_READ_ONLY_ARB,
-                                              unpack->BufferObj);
-      if (!buf) {
-         /* buffer is already mapped - that's an error */
-         _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels(PBO is mapped)");
-         goto end;
-      }
-      pixels = ADD_POINTERS(buf, pixels);
-   }
+   pixels = _mesa_validate_and_map_drawpix_pbo(ctx, x, y, width, height,
+                                               format, type, unpack, pixels);
+   if (!pixels)
+      return;
 
    switch (format) {
    case GL_STENCIL_INDEX:
@@ -894,11 +878,7 @@ end:
 
    RENDER_FINISH(swrast,ctx);
 
-   if (unpack->BufferObj->Name) {
-      /* done with PBO so unmap it now */
-      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
-                              unpack->BufferObj);
-   }
+   _mesa_unmap_drapix_pbo(ctx, unpack);
 }
 
 
index fe9a70f4eae03932dc91a58be33e373c479c8f37..f4f882ae8409f9c5e3726c9e28491e3656af6221 100644 (file)
@@ -572,25 +572,11 @@ _swrast_ReadPixels( GLcontext *ctx,
       goto end;
    }
 
-   if (clippedPacking.BufferObj->Name) {
-      /* pack into PBO */
-      GLubyte *buf;
-      if (!_mesa_validate_pbo_access(2, &clippedPacking, width, height, 1,
-                                     format, type, pixels)) {
-         _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glReadPixels(invalid PBO access)");
-         goto end;
-      }
-      buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
-                                              GL_WRITE_ONLY_ARB,
-                                              clippedPacking.BufferObj);
-      if (!buf) {
-         /* buffer is already mapped - that's an error */
-         _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(PBO is mapped)");
-         goto end;
-      }
-      pixels = ADD_POINTERS(buf, pixels);
-   }
+   pixels = _mesa_validate_and_map_readpix_pbo(ctx, x, y, width, height,
+                                               format, type,
+                                               &clippedPacking, pixels);
+   if (!pixels)
+      return;
 
    switch (format) {
       case GL_COLOR_INDEX:
@@ -632,9 +618,5 @@ _swrast_ReadPixels( GLcontext *ctx,
 end:
    RENDER_FINISH(swrast, ctx);
 
-   if (clippedPacking.BufferObj->Name) {
-      /* done with PBO so unmap it now */
-      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
-                              clippedPacking.BufferObj);
-   }
+   _mesa_unmap_readpix_pbo(ctx, &clippedPacking);
 }