summaryrefslogtreecommitdiffstats
path: root/src/mesa/main/bufferobj.c
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2004-03-13 18:21:40 +0000
committerBrian Paul <[email protected]>2004-03-13 18:21:40 +0000
commit7a6b71ef2944bae1718e8167b2faaceb8422071c (patch)
tree3fb3435f3728f09486d455f6060f06dd42fe0e80 /src/mesa/main/bufferobj.c
parent5498e8b9f34718aba506421988116ccb1e5e3de7 (diff)
Implementation of GL_EXT_pixel_buffer_object extension.
Note: extension may not be finalized yet - subject to change! Note: implementation not fully suitable for h/w implementation yet.
Diffstat (limited to 'src/mesa/main/bufferobj.c')
-rw-r--r--src/mesa/main/bufferobj.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c
index 882f24526c7..1f9b988d334 100644
--- a/src/mesa/main/bufferobj.c
+++ b/src/mesa/main/bufferobj.c
@@ -33,6 +33,7 @@
#include "glheader.h"
#include "hash.h"
#include "imports.h"
+#include "image.h"
#include "context.h"
#include "bufferobj.h"
@@ -60,6 +61,12 @@ buffer_object_get_target( GLcontext *ctx, GLenum target, const char * str )
case GL_ELEMENT_ARRAY_BUFFER_ARB:
bufObj = ctx->Array.ElementArrayBufferObj;
break;
+ case GL_PIXEL_PACK_BUFFER_EXT:
+ bufObj = ctx->Pack.BufferObj;
+ break;
+ case GL_PIXEL_UNPACK_BUFFER_EXT:
+ bufObj = ctx->Unpack.BufferObj;
+ break;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "gl%s(target)", str);
return NULL;
@@ -358,6 +365,59 @@ _mesa_init_buffer_objects( GLcontext *ctx )
}
+/**
+ * When we're about to read pixel data out of a PBO (via glDrawPixels,
+ * glTexImage, etc) or write data into a PBO (via glReadPixels,
+ * glGetTexImage, etc) we call this function to check that we're not
+ * going to read out of bounds.
+ *
+ * \param ctx the rendering context
+ * \param width width of image to read/write
+ * \param height height of image to read/write
+ * \param depth depth of image to read/write
+ * \param format format of image to read/write
+ * \param type datatype of image to read/write
+ * \param ptr the user-provided pointer/offset
+ * \return GL_TRUE if the PBO access is OK, GL_FALSE if the access would
+ * go out of bounds.
+ */
+GLboolean
+_mesa_validate_pbo_access(const struct gl_pixelstore_attrib *pack,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type, const GLvoid *ptr)
+{
+ GLvoid *start, *end;
+
+ ASSERT(pack->BufferObj->Name != 0);
+
+ if (pack->BufferObj->Size == 0)
+ /* no buffer! */
+ return GL_FALSE;
+
+ /* get address of first pixel we'll read */
+ start = _mesa_image_address(pack, ptr, width, height,
+ format, type, 0, 0, 0);
+
+ /* get address just past the last pixel we'll read */
+ end = _mesa_image_address(pack, ptr, width, height,
+ format, type, depth-1, height-1, width);
+
+
+ if ((const GLubyte *) start > (const GLubyte *) pack->BufferObj->Size) {
+ /* This will catch negative values / wrap-around */
+ return GL_FALSE;
+ }
+ if ((const GLubyte *) end > (const GLubyte *) pack->BufferObj->Size) {
+ /* Image read goes beyond end of buffer */
+ return GL_FALSE;
+ }
+
+ /* OK! */
+ return GL_TRUE;
+}
+
+
+
/**********************************************************************/
/* API Functions */
@@ -407,6 +467,15 @@ _mesa_BindBufferARB(GLenum target, GLuint buffer)
case GL_ELEMENT_ARRAY_BUFFER_ARB:
ctx->Array.ElementArrayBufferObj = newBufObj;
break;
+ case GL_PIXEL_PACK_BUFFER_EXT:
+ ctx->Pack.BufferObj = newBufObj;
+ break;
+ case GL_PIXEL_UNPACK_BUFFER_EXT:
+ ctx->Unpack.BufferObj = newBufObj;
+ break;
+ default:
+ _mesa_problem(ctx, "Bad target in _mesa_BindBufferARB");
+ return;
}
/* Pass BindBuffer call to device driver */
@@ -504,6 +573,13 @@ _mesa_DeleteBuffersARB(GLsizei n, const GLuint *ids)
_mesa_BindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, 0 );
}
+ if (ctx->Pack.BufferObj == bufObj) {
+ _mesa_BindBufferARB( GL_PIXEL_PACK_BUFFER_EXT, 0 );
+ }
+ if (ctx->Unpack.BufferObj == bufObj) {
+ _mesa_BindBufferARB( GL_PIXEL_UNPACK_BUFFER_EXT, 0 );
+ }
+
/* decrement refcount and delete if <= 0 */
bufObj->DeletePending = GL_TRUE;
bufObj->RefCount--;