Implementation of GL_EXT_pixel_buffer_object extension.
authorBrian Paul <brian.paul@tungstengraphics.com>
Sat, 13 Mar 2004 18:21:40 +0000 (18:21 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Sat, 13 Mar 2004 18:21:40 +0000 (18:21 +0000)
Note: extension may not be finalized yet - subject to change!
Note: implementation not fully suitable for h/w implementation yet.

22 files changed:
src/mesa/drivers/x11/xm_dd.c
src/mesa/main/attrib.c
src/mesa/main/bufferobj.c
src/mesa/main/bufferobj.h
src/mesa/main/config.h
src/mesa/main/dlist.c
src/mesa/main/drawpix.c
src/mesa/main/extensions.c
src/mesa/main/get.c
src/mesa/main/glheader.h
src/mesa/main/image.c
src/mesa/main/image.h
src/mesa/main/mtypes.h
src/mesa/main/pixel.c
src/mesa/main/texstore.c
src/mesa/swrast/s_bitmap.c
src/mesa/swrast/s_context.c
src/mesa/swrast/s_drawpix.c
src/mesa/swrast/s_imaging.c
src/mesa/swrast/s_readpix.c
src/mesa/swrast/s_texstore.c
src/mesa/swrast/swrast.h

index f54003bc852560047cca1cdf3e52667601be9160..1178b71b74f1aa5c9d5631ae7c216d6a130ec300 100644 (file)
@@ -843,6 +843,12 @@ xmesa_DrawPixels_8R8G8B( GLcontext *ctx,
       int srcX = unpack->SkipPixels;
       int srcY = unpack->SkipRows;
       int rowLength = unpack->RowLength ? unpack->RowLength : width;
+
+      pixels = _swrast_validate_pbo_access(unpack, width, height, 1,
+                                           format, type, (GLvoid *) pixels);
+      if (!pixels)
+         return;
+
       if (_swrast_clip_pixelrect(ctx, &dstX, &dstY, &w, &h, &srcX, &srcY)) {
          /* This is a little tricky since all coordinates up to now have
           * been in the OpenGL bottom-to-top orientation.  X is top-to-bottom
@@ -918,6 +924,12 @@ xmesa_DrawPixels_5R6G5B( GLcontext *ctx,
       int srcX = unpack->SkipPixels;
       int srcY = unpack->SkipRows;
       int rowLength = unpack->RowLength ? unpack->RowLength : width;
+
+      pixels = _swrast_validate_pbo_access(unpack, width, height, 1,
+                                           format, type, (GLvoid *) pixels);
+      if (!pixels)
+         return;
+
       if (_swrast_clip_pixelrect(ctx, &dstX, &dstY, &w, &h, &srcX, &srcY)) {
          /* This is a little tricky since all coordinates up to now have
           * been in the OpenGL bottom-to-top orientation.  X is top-to-bottom
index e3423c74170a6b8f6203f63c5335fa2f4560e6c6..339c40b9bdd5235eae40c21e2fb78b2d383ba4c3 100644 (file)
@@ -28,6 +28,7 @@
 #include "attrib.h"
 #include "blend.h"
 #include "buffers.h"
+#include "bufferobj.h"
 #include "colormac.h"
 #include "colortab.h"
 #include "context.h"
@@ -1191,6 +1192,10 @@ _mesa_PushClientAttrib(GLbitfield mask)
 
    if (mask & GL_CLIENT_PIXEL_STORE_BIT) {
       struct gl_pixelstore_attrib *attr;
+#if FEATURE_EXT_pixel_buffer_object
+      ctx->Pack.BufferObj->RefCount++;
+      ctx->Unpack.BufferObj->RefCount++;
+#endif
       /* packing attribs */
       attr = MALLOC_STRUCT( gl_pixelstore_attrib );
       MEMCPY( attr, &ctx->Pack, sizeof(struct gl_pixelstore_attrib) );
@@ -1244,11 +1249,25 @@ _mesa_PopClientAttrib(void)
    while (attr) {
       switch (attr->kind) {
          case GL_CLIENT_PACK_BIT:
+#if FEATURE_EXT_pixel_buffer_object
+            ctx->Pack.BufferObj->RefCount--;
+            if (ctx->Pack.BufferObj->RefCount <= 0) {
+               _mesa_remove_buffer_object( ctx, ctx->Pack.BufferObj );
+               (*ctx->Driver.DeleteBuffer)( ctx, ctx->Pack.BufferObj );
+            }
+#endif
             MEMCPY( &ctx->Pack, attr->data,
                     sizeof(struct gl_pixelstore_attrib) );
            ctx->NewState |= _NEW_PACKUNPACK;
             break;
          case GL_CLIENT_UNPACK_BIT:
+#if FEATURE_EXT_pixel_buffer_object
+            ctx->Unpack.BufferObj->RefCount--;
+            if (ctx->Unpack.BufferObj->RefCount <= 0) {
+               _mesa_remove_buffer_object( ctx, ctx->Unpack.BufferObj );
+               (*ctx->Driver.DeleteBuffer)( ctx, ctx->Unpack.BufferObj );
+            }
+#endif
             MEMCPY( &ctx->Unpack, attr->data,
                     sizeof(struct gl_pixelstore_attrib) );
            ctx->NewState |= _NEW_PACKUNPACK;
index 882f24526c79170d772b183934ec60e982f7b61d..1f9b988d334e9e6878c4f92655826c4c633e7ef7 100644 (file)
@@ -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--;
index 236545b9abe54b8e7aba6fb644585aa428d21b54..e6bd8b329a7f05e97e829acf1283b836c056bd33 100644 (file)
@@ -1,9 +1,8 @@
-
 /*
  * Mesa 3-D graphics library
- * Version:  5.1
+ * Version:  6.1
  *
- * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2004  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"),
@@ -75,6 +74,11 @@ _mesa_buffer_map( GLcontext *ctx, GLenum target, GLenum access,
                  struct gl_buffer_object * bufObj );
 
 
+extern GLboolean
+_mesa_validate_pbo_access(const struct gl_pixelstore_attrib *pack,
+                          GLsizei width, GLsizei height, GLsizei depth,
+                          GLenum format, GLenum type, const GLvoid *ptr);
+
 
 /*
  * API functions
index 6d8952d9af0205cfd198f657edf23590ed18d918..74ebb469afa6aba22b590dd85ef421c700b3b144 100644 (file)
 #define FEATURE_ARB_vertex_program  _HAVE_FULL_GL
 #define FEATURE_ARB_fragment_program  _HAVE_FULL_GL
 #define FEATURE_ARB_occlusion_query  _HAVE_FULL_GL
+#define FEATURE_EXT_pixel_buffer_object  _HAVE_FULL_GL
 #define FEATURE_MESA_program_debug  _HAVE_FULL_GL
 #define FEATURE_NV_fence  _HAVE_FULL_GL
 #define FEATURE_NV_fragment_program  _HAVE_FULL_GL
index 3c7fe9c47da6bc5baff610d0a63cd7a994b4373f..26bf76a00777bfc1ec3d2b3975e3a5c0ae6049c3 100644 (file)
@@ -618,7 +618,11 @@ static GLuint translate_id( GLsizei n, GLenum type, const GLvoid *list )
 /*****                        Public                              *****/
 /**********************************************************************/
 
-void _mesa_init_lists( void )
+/**
+ * Do one-time initialiazations for display lists.
+ */
+void
+_mesa_init_lists( void )
 {
    static int init_flag = 0;
 
@@ -789,6 +793,32 @@ void _mesa_init_lists( void )
 }
 
 
+
+/**
+ * Wrapper for _mesa_unpack_image() that handles pixel buffer objects.
+ * \todo This won't suffice when the PBO is really in VRAM/GPU memory.
+ */
+static GLvoid *
+unpack_image( GLsizei width, GLsizei height, GLsizei depth,
+              GLenum format, GLenum type, const GLvoid *pixels,
+              const struct gl_pixelstore_attrib *unpack )
+{
+   if (unpack->BufferObj->Name == 0) {
+      /* no PBO */
+      return _mesa_unpack_image(width, height, depth, format, type,
+                                pixels, unpack);
+   }
+   else if (_mesa_validate_pbo_access(unpack, width, height, depth, format,
+                                      type, pixels)) {
+      const GLubyte *src = ADD_POINTERS(unpack->BufferObj->Data, pixels);
+      return _mesa_unpack_image(width, height, depth, format, type,
+                                src, unpack);
+   }
+   /* bad access! */
+   return NULL;
+}
+
+
 /*
  * Allocate space for a display list instruction.
  * \param opcode - type of instruction
@@ -1255,8 +1285,8 @@ static void GLAPIENTRY save_ColorTable( GLenum target, GLenum internalFormat,
                                 format, type, table );
    }
    else {
-      GLvoid *image = _mesa_unpack_image(width, 1, 1, format, type, table,
-                                         &ctx->Unpack);
+      GLvoid *image = unpack_image(width, 1, 1, format, type, table,
+                                   &ctx->Unpack);
       Node *n;
       ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
       n = ALLOC_INSTRUCTION( ctx, OPCODE_COLOR_TABLE, 6 );
@@ -1344,8 +1374,8 @@ static void GLAPIENTRY save_ColorSubTable( GLenum target, GLsizei start, GLsizei
                                 const GLvoid *table)
 {
    GET_CURRENT_CONTEXT(ctx);
-   GLvoid *image = _mesa_unpack_image(count, 1, 1, format, type, table,
-                                      &ctx->Unpack);
+   GLvoid *image = unpack_image(count, 1, 1, format, type, table,
+                                &ctx->Unpack);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
    n = ALLOC_INSTRUCTION( ctx, OPCODE_COLOR_SUB_TABLE, 6 );
@@ -1415,8 +1445,8 @@ save_ConvolutionFilter1D(GLenum target, GLenum internalFormat, GLsizei width,
                          GLenum format, GLenum type, const GLvoid *filter)
 {
    GET_CURRENT_CONTEXT(ctx);
-   GLvoid *image = _mesa_unpack_image(width, 1, 1, format, type, filter,
-                                      &ctx->Unpack);
+   GLvoid *image = unpack_image(width, 1, 1, format, type, filter,
+                                &ctx->Unpack);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
    n = ALLOC_INSTRUCTION( ctx, OPCODE_CONVOLUTION_FILTER_1D, 6 );
@@ -1444,8 +1474,8 @@ save_ConvolutionFilter2D(GLenum target, GLenum internalFormat,
                          GLenum type, const GLvoid *filter)
 {
    GET_CURRENT_CONTEXT(ctx);
-   GLvoid *image = _mesa_unpack_image(width, height, 1, format, type, filter,
-                                      &ctx->Unpack);
+   GLvoid *image = unpack_image(width, height, 1, format, type, filter,
+                                &ctx->Unpack);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
    n = ALLOC_INSTRUCTION( ctx, OPCODE_CONVOLUTION_FILTER_2D, 7 );
@@ -1809,8 +1839,8 @@ static void GLAPIENTRY save_DrawPixels( GLsizei width, GLsizei height,
                              const GLvoid *pixels )
 {
    GET_CURRENT_CONTEXT(ctx);
-   GLvoid *image = _mesa_unpack_image(width, height, 1, format, type,
-                                      pixels, &ctx->Unpack);
+   GLvoid *image = unpack_image(width, height, 1, format, type,
+                                pixels, &ctx->Unpack);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
    n = ALLOC_INSTRUCTION( ctx, OPCODE_DRAW_PIXELS, 5 );
@@ -3365,8 +3395,8 @@ static void GLAPIENTRY save_TexImage1D( GLenum target,
                                border, format, type, pixels );
    }
    else {
-      GLvoid *image = _mesa_unpack_image(width, 1, 1, format, type,
-                                         pixels, &ctx->Unpack);
+      GLvoid *image = unpack_image(width, 1, 1, format, type,
+                                   pixels, &ctx->Unpack);
       Node *n;
       ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
       n = ALLOC_INSTRUCTION( ctx, OPCODE_TEX_IMAGE1D, 8 );
@@ -3404,8 +3434,8 @@ static void GLAPIENTRY save_TexImage2D( GLenum target,
                                height, border, format, type, pixels );
    }
    else {
-      GLvoid *image = _mesa_unpack_image(width, height, 1, format, type,
-                                         pixels, &ctx->Unpack);
+      GLvoid *image = unpack_image(width, height, 1, format, type,
+                                   pixels, &ctx->Unpack);
       Node *n;
       ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
       n = ALLOC_INSTRUCTION( ctx, OPCODE_TEX_IMAGE2D, 9 );
@@ -3446,8 +3476,8 @@ static void GLAPIENTRY save_TexImage3D( GLenum target,
    }
    else {
       Node *n;
-      GLvoid *image = _mesa_unpack_image(width, height, depth, format, type,
-                                         pixels, &ctx->Unpack);
+      GLvoid *image = unpack_image(width, height, depth, format, type,
+                                   pixels, &ctx->Unpack);
       ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
       n = ALLOC_INSTRUCTION( ctx, OPCODE_TEX_IMAGE3D, 10 );
       if (n) {
@@ -3479,8 +3509,8 @@ static void GLAPIENTRY save_TexSubImage1D( GLenum target, GLint level, GLint xof
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   GLvoid *image = _mesa_unpack_image(width, 1, 1, format, type,
-                                      pixels, &ctx->Unpack);
+   GLvoid *image = unpack_image(width, 1, 1, format, type,
+                                pixels, &ctx->Unpack);
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
    n = ALLOC_INSTRUCTION( ctx, OPCODE_TEX_SUB_IMAGE1D, 7 );
    if (n) {
@@ -3510,8 +3540,8 @@ static void GLAPIENTRY save_TexSubImage2D( GLenum target, GLint level,
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   GLvoid *image = _mesa_unpack_image(width, height, 1, format, type,
-                                      pixels, &ctx->Unpack);
+   GLvoid *image = unpack_image(width, height, 1, format, type,
+                                pixels, &ctx->Unpack);
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
    n = ALLOC_INSTRUCTION( ctx, OPCODE_TEX_SUB_IMAGE2D, 9 );
    if (n) {
@@ -3543,8 +3573,8 @@ static void GLAPIENTRY save_TexSubImage3D( GLenum target, GLint level,
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   GLvoid *image = _mesa_unpack_image(width, height, depth, format, type,
-                                      pixels, &ctx->Unpack);
+   GLvoid *image = unpack_image(width, height, depth, format, type,
+                                pixels, &ctx->Unpack);
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
    n = ALLOC_INSTRUCTION( ctx, OPCODE_TEX_SUB_IMAGE3D, 11 );
    if (n) {
@@ -5283,8 +5313,8 @@ execute_list( GLcontext *ctx, GLuint list )
             break;
         case OPCODE_BITMAP:
             {
-               struct gl_pixelstore_attrib save = ctx->Unpack;
-               ctx->Unpack = _mesa_native_packing;
+               const struct gl_pixelstore_attrib save = ctx->Unpack;
+               ctx->Unpack = ctx->DefaultPacking;
                (*ctx->Exec->Bitmap)( (GLsizei) n[1].i, (GLsizei) n[2].i,
                  n[3].f, n[4].f, n[5].f, n[6].f, (const GLubyte *) n[7].data );
                ctx->Unpack = save;  /* restore */
@@ -5354,8 +5384,8 @@ execute_list( GLcontext *ctx, GLuint list )
            break;
          case OPCODE_COLOR_TABLE:
             {
-               struct gl_pixelstore_attrib save = ctx->Unpack;
-               ctx->Unpack = _mesa_native_packing;
+               const struct gl_pixelstore_attrib save = ctx->Unpack;
+               ctx->Unpack = ctx->DefaultPacking;
                (*ctx->Exec->ColorTable)( n[1].e, n[2].e, n[3].i, n[4].e,
                                          n[5].e, n[6].data );
                ctx->Unpack = save;  /* restore */
@@ -5383,8 +5413,8 @@ execute_list( GLcontext *ctx, GLuint list )
             break;
          case OPCODE_COLOR_SUB_TABLE:
             {
-               struct gl_pixelstore_attrib save = ctx->Unpack;
-               ctx->Unpack = _mesa_native_packing;
+               const struct gl_pixelstore_attrib save = ctx->Unpack;
+               ctx->Unpack = ctx->DefaultPacking;
                (*ctx->Exec->ColorSubTable)( n[1].e, n[2].i, n[3].i,
                                             n[4].e, n[5].e, n[6].data );
                ctx->Unpack = save;  /* restore */
@@ -5392,8 +5422,8 @@ execute_list( GLcontext *ctx, GLuint list )
             break;
          case OPCODE_CONVOLUTION_FILTER_1D:
             {
-               struct gl_pixelstore_attrib save = ctx->Unpack;
-               ctx->Unpack = _mesa_native_packing;
+               const struct gl_pixelstore_attrib save = ctx->Unpack;
+               ctx->Unpack = ctx->DefaultPacking;
                (*ctx->Exec->ConvolutionFilter1D)( n[1].e, n[2].i, n[3].i,
                                                   n[4].e, n[5].e, n[6].data );
                ctx->Unpack = save;  /* restore */
@@ -5401,8 +5431,8 @@ execute_list( GLcontext *ctx, GLuint list )
             break;
          case OPCODE_CONVOLUTION_FILTER_2D:
             {
-               struct gl_pixelstore_attrib save = ctx->Unpack;
-               ctx->Unpack = _mesa_native_packing;
+               const struct gl_pixelstore_attrib save = ctx->Unpack;
+               ctx->Unpack = ctx->DefaultPacking;
                (*ctx->Exec->ConvolutionFilter2D)( n[1].e, n[2].i, n[3].i,
                                        n[4].i, n[5].e, n[6].e, n[7].data );
                ctx->Unpack = save;  /* restore */
@@ -5486,8 +5516,8 @@ execute_list( GLcontext *ctx, GLuint list )
            break;
         case OPCODE_DRAW_PIXELS:
             {
-               struct gl_pixelstore_attrib save = ctx->Unpack;
-               ctx->Unpack = _mesa_native_packing;
+               const struct gl_pixelstore_attrib save = ctx->Unpack;
+               ctx->Unpack = ctx->DefaultPacking;
                (*ctx->Exec->DrawPixels)( n[1].i, n[2].i, n[3].e, n[4].e,
                                         n[5].data );
                ctx->Unpack = save;  /* restore */
@@ -5755,8 +5785,8 @@ execute_list( GLcontext *ctx, GLuint list )
             break;
         case OPCODE_TEX_IMAGE1D:
             {
-               struct gl_pixelstore_attrib save = ctx->Unpack;
-               ctx->Unpack = _mesa_native_packing;
+               const struct gl_pixelstore_attrib save = ctx->Unpack;
+               ctx->Unpack = ctx->DefaultPacking;
                (*ctx->Exec->TexImage1D)(
                                         n[1].e, /* target */
                                         n[2].i, /* level */
@@ -5771,8 +5801,8 @@ execute_list( GLcontext *ctx, GLuint list )
            break;
         case OPCODE_TEX_IMAGE2D:
             {
-               struct gl_pixelstore_attrib save = ctx->Unpack;
-               ctx->Unpack = _mesa_native_packing;
+               const struct gl_pixelstore_attrib save = ctx->Unpack;
+               ctx->Unpack = ctx->DefaultPacking;
                (*ctx->Exec->TexImage2D)(
                                         n[1].e, /* target */
                                         n[2].i, /* level */
@@ -5788,8 +5818,8 @@ execute_list( GLcontext *ctx, GLuint list )
            break;
          case OPCODE_TEX_IMAGE3D:
             {
-               struct gl_pixelstore_attrib save = ctx->Unpack;
-               ctx->Unpack = _mesa_native_packing;
+               const struct gl_pixelstore_attrib save = ctx->Unpack;
+               ctx->Unpack = ctx->DefaultPacking;
                (*ctx->Exec->TexImage3D)(
                                         n[1].e, /* target */
                                         n[2].i, /* level */
@@ -5806,8 +5836,8 @@ execute_list( GLcontext *ctx, GLuint list )
             break;
          case OPCODE_TEX_SUB_IMAGE1D:
             {
-               struct gl_pixelstore_attrib save = ctx->Unpack;
-               ctx->Unpack = _mesa_native_packing;
+               const struct gl_pixelstore_attrib save = ctx->Unpack;
+               ctx->Unpack = ctx->DefaultPacking;
                (*ctx->Exec->TexSubImage1D)( n[1].e, n[2].i, n[3].i,
                                            n[4].i, n[5].e,
                                            n[6].e, n[7].data );
@@ -5816,8 +5846,8 @@ execute_list( GLcontext *ctx, GLuint list )
             break;
          case OPCODE_TEX_SUB_IMAGE2D:
             {
-               struct gl_pixelstore_attrib save = ctx->Unpack;
-               ctx->Unpack = _mesa_native_packing;
+               const struct gl_pixelstore_attrib save = ctx->Unpack;
+               ctx->Unpack = ctx->DefaultPacking;
                (*ctx->Exec->TexSubImage2D)( n[1].e, n[2].i, n[3].i,
                                            n[4].i, n[5].e,
                                            n[6].i, n[7].e, n[8].e, n[9].data );
@@ -5826,8 +5856,8 @@ execute_list( GLcontext *ctx, GLuint list )
             break;
          case OPCODE_TEX_SUB_IMAGE3D:
             {
-               struct gl_pixelstore_attrib save = ctx->Unpack;
-               ctx->Unpack = _mesa_native_packing;
+               const struct gl_pixelstore_attrib save = ctx->Unpack;
+               ctx->Unpack = ctx->DefaultPacking;
                (*ctx->Exec->TexSubImage3D)( n[1].e, n[2].i, n[3].i,
                                            n[4].i, n[5].i, n[6].i, n[7].i,
                                            n[8].i, n[9].e, n[10].e,
index 745d7a304d93f2168b77891838da673f0a9c465e..fc7dd32b06bbb5c780e0c2b1ba6c5666d740e567 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.0.1
+ * Version:  6.1
  *
  * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
  *
@@ -32,6 +32,7 @@
 #include "state.h"
 #include "mtypes.h"
 
+
 #if _HAVE_FULL_GL
 
 /*
@@ -58,7 +59,7 @@ _mesa_DrawPixels( GLsizei width, GLsizei height,
 
    if (ctx->RenderMode==GL_RENDER) {
       GLint x, y;
-      if (!pixels || !ctx->Current.RasterPosValid) {
+      if (!ctx->Current.RasterPosValid) {
         return;
       }
 
@@ -93,6 +94,7 @@ _mesa_DrawPixels( GLsizei width, GLsizei height,
    }
 }
 
+
 void GLAPIENTRY
 _mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height,
                   GLenum type )
@@ -148,7 +150,7 @@ _mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height,
    }
 }
 
-#endif
+#endif /* _HAVE_FULL_GL */
 
 
 
@@ -165,11 +167,6 @@ _mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,
       return;
    }
 
-   if (!pixels) {
-      _mesa_error( ctx, GL_INVALID_VALUE, "glReadPixels(pixels)" );
-      return;
-   }
-
    if (ctx->NewState)
       _mesa_update_state(ctx);
 
@@ -179,8 +176,6 @@ _mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,
 
 
 
-
-
 void GLAPIENTRY
 _mesa_Bitmap( GLsizei width, GLsizei height,
               GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove,
@@ -206,18 +201,16 @@ _mesa_Bitmap( GLsizei width, GLsizei height,
    }
 
    if (ctx->RenderMode==GL_RENDER) {
-      if (bitmap) {
-         /* Truncate, to satisfy conformance tests (matches SGI's OpenGL). */
-         GLint x = IFLOOR(ctx->Current.RasterPos[0] - xorig);
-         GLint y = IFLOOR(ctx->Current.RasterPos[1] - yorig);
+      /* Truncate, to satisfy conformance tests (matches SGI's OpenGL). */
+      GLint x = IFLOOR(ctx->Current.RasterPos[0] - xorig);
+      GLint y = IFLOOR(ctx->Current.RasterPos[1] - yorig);
 
-         if (ctx->NewState) {
-            _mesa_update_state(ctx);
-         }
-
-         ctx->OcclusionResult = GL_TRUE;
-        ctx->Driver.Bitmap( ctx, x, y, width, height, &ctx->Unpack, bitmap );
+      if (ctx->NewState) {
+         _mesa_update_state(ctx);
       }
+
+      ctx->OcclusionResult = GL_TRUE;
+      ctx->Driver.Bitmap( ctx, x, y, width, height, &ctx->Unpack, bitmap );
    }
 #if _HAVE_FULL_GL
    else if (ctx->RenderMode==GL_FEEDBACK) {
index 01810b65b2417e64aa5f5317791fc0a61bd6186b..2ae48b4edb0af576827b51da60efcffe2ffd3023 100644 (file)
@@ -83,6 +83,7 @@ static const struct {
    { OFF, "GL_EXT_multi_draw_arrays",          F(EXT_multi_draw_arrays) },
    { ON,  "GL_EXT_packed_pixels",              F(EXT_packed_pixels) },
    { OFF, "GL_EXT_paletted_texture",           F(EXT_paletted_texture) },
+   { OFF, "GL_EXT_pixel_buffer_object",        F(EXT_pixel_buffer_object) },
    { OFF, "GL_EXT_point_parameters",           F(EXT_point_parameters) },
    { ON,  "GL_EXT_polygon_offset",             F(EXT_polygon_offset) },
    { ON,  "GL_EXT_rescale_normal",             F(EXT_rescale_normal) },
@@ -195,6 +196,9 @@ _mesa_enable_sw_extensions(GLcontext *ctx)
    ctx->Extensions.EXT_histogram = GL_TRUE;
    ctx->Extensions.EXT_multi_draw_arrays = GL_TRUE;
    ctx->Extensions.EXT_paletted_texture = GL_TRUE;
+#if FEATURE_EXT_pixel_buffer_object
+   ctx->Extensions.EXT_pixel_buffer_object = GL_TRUE;
+#endif
    ctx->Extensions.EXT_point_parameters = GL_TRUE;
    ctx->Extensions.EXT_shadow_funcs = GL_TRUE;
    ctx->Extensions.EXT_secondary_color = GL_TRUE;
index 723c48ce3c9802a0952033983eabc058e32501fc..fac3f072bc3b3b24c38cd82d17d94b5e26d32802 100644 (file)
@@ -1609,6 +1609,16 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
          *params = INT_TO_BOOL(ctx->Array.ElementArrayBufferObj->Name);
          break;
 #endif
+#if FEATURE_EXT_pixel_buffer_object
+      case GL_PIXEL_PACK_BUFFER_BINDING_EXT:
+         CHECK_EXTENSION_B(EXT_pixel_buffer_object, pname);
+         *params = INT_TO_BOOL(ctx->Pack.BufferObj->Name);
+         break;
+      case GL_PIXEL_UNPACK_BUFFER_BINDING_EXT:
+         CHECK_EXTENSION_B(EXT_pixel_buffer_object, pname);
+         *params = INT_TO_BOOL(ctx->Unpack.BufferObj->Name);
+         break;
+#endif
 
 #if FEATURE_ARB_fragment_program
       case GL_FRAGMENT_PROGRAM_ARB:
@@ -3149,6 +3159,16 @@ _mesa_GetDoublev( GLenum pname, GLdouble *params )
          *params = (GLdouble) ctx->Array.ElementArrayBufferObj->Name;
          break;
 #endif
+#if FEATURE_EXT_pixel_buffer_object
+      case GL_PIXEL_PACK_BUFFER_BINDING_EXT:
+         CHECK_EXTENSION_D(EXT_pixel_buffer_object, pname);
+         *params = (GLdouble) ctx->Pack.BufferObj->Name;
+         break;
+      case GL_PIXEL_UNPACK_BUFFER_BINDING_EXT:
+         CHECK_EXTENSION_D(EXT_pixel_buffer_object, pname);
+         *params = (GLdouble) ctx->Unpack.BufferObj->Name;
+         break;
+#endif
 
 #if FEATURE_ARB_fragment_program
       case GL_FRAGMENT_PROGRAM_ARB:
@@ -4665,6 +4685,16 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )
          *params = (GLfloat) ctx->Array.ElementArrayBufferObj->Name;
          break;
 #endif
+#if FEATURE_EXT_pixel_buffer_object
+      case GL_PIXEL_PACK_BUFFER_BINDING_EXT:
+         CHECK_EXTENSION_F(EXT_pixel_buffer_object, pname);
+         *params = (GLfloat) ctx->Pack.BufferObj->Name;
+         break;
+      case GL_PIXEL_UNPACK_BUFFER_BINDING_EXT:
+         CHECK_EXTENSION_F(EXT_pixel_buffer_object, pname);
+         *params = (GLfloat) ctx->Unpack.BufferObj->Name;
+         break;
+#endif
 
 #if FEATURE_ARB_fragment_program
       case GL_FRAGMENT_PROGRAM_ARB:
@@ -6219,6 +6249,16 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
          *params = (GLint) ctx->Array.ElementArrayBufferObj->Name;
          break;
 #endif
+#if FEATURE_EXT_pixel_buffer_object
+      case GL_PIXEL_PACK_BUFFER_BINDING_EXT:
+         CHECK_EXTENSION_I(EXT_pixel_buffer_object, pname);
+         *params = (GLint) ctx->Pack.BufferObj->Name;
+         break;
+      case GL_PIXEL_UNPACK_BUFFER_BINDING_EXT:
+         CHECK_EXTENSION_I(EXT_pixel_buffer_object, pname);
+         *params = (GLint) ctx->Unpack.BufferObj->Name;
+         break;
+#endif
 
 #if FEATURE_ARB_fragment_program
       case GL_FRAGMENT_PROGRAM_ARB:
index a75c65dd4aa0367dbd88ca4f5bfa6d6241354020..dd4a404fc835f2a6a34464c13feb685b99e4994c 100644 (file)
@@ -211,6 +211,14 @@ typedef struct tagPIXELFORMATDESCRIPTOR PIXELFORMATDESCRIPTOR, *PPIXELFORMATDESC
 #include <GL/internal/glcore.h>
 
 
+/* XXX temporary hack */
+#ifndef GL_PIXEL_PACK_BUFFER_EXT
+#define GL_PIXEL_PACK_BUFFER_EXT                        0x88EB
+#define GL_PIXEL_UNPACK_BUFFER_EXT                      0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING_EXT                0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT              0x88EF
+#endif
+
 
 /* Disable unreachable code warnings for Watcom C++ */
 #ifdef __WATCOMC__
index 5c117f6ce6a9b94bb0788b773e302dff15f44a77..d610865996779fc644827a86565e799392e563f9 100644 (file)
@@ -5,9 +5,9 @@
 
 /*
  * Mesa 3-D graphics library
- * Version:  5.1
+ * Version:  6.1
  *
- * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2004  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"),
@@ -29,6 +29,7 @@
 
 
 #include "glheader.h"
+#include "bufferobj.h"
 #include "colormac.h"
 #include "context.h"
 #include "image.h"
 #define CEILING( A, B )  ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 )
 
 
-/**
- * Image packing parameters for Mesa's internal images.
- * 
- * _mesa_unpack_image() returns image data in this format.  When we execute
- * image commands (glDrawPixels(), glTexImage(), etc) from within display lists
- * we have to be sure to set the current unpacking parameters to these values!
- */
-const struct gl_pixelstore_attrib _mesa_native_packing = {
-   1,            /* Alignment */
-   0,            /* RowLength */
-   0,            /* SkipPixels */
-   0,            /* SkipRows */
-   0,            /* ImageHeight */
-   0,            /* SkipImages */
-   GL_FALSE,     /* SwapBytes */
-   GL_FALSE,     /* LsbFirst */
-   GL_FALSE,     /* ClientStorage */
-   GL_FALSE      /* Invert */
-};
-
-
 /**
  * Flip the 8 bits in each byte of the given array.
  *
@@ -3974,9 +3954,11 @@ _mesa_pack_depth_span( const GLcontext *ctx, GLuint n, GLvoid *dest,
 }
 
 
-/*
- * Unpack image data.  Apply byteswapping, byte flipping (bitmap).
- * Return all image data in a contiguous block.
+/**
+ * Unpack image data.  Apply byte swapping, byte flipping (bitmap).
+ * Return all image data in a contiguous block.  This is used when we
+ * compile glDrawPixels, glTexImage, etc into a display list.  We
+ * need a copy of the data in a standard format.
  */
 void *
 _mesa_unpack_image( GLsizei width, GLsizei height, GLsizei depth,
index b3757a30fdcd1ff4d0353f9879f324c943e29b70..ffe629e103fd6c45dbb2888e0919835b9c2e408a 100644 (file)
@@ -35,9 +35,6 @@
 #include "mtypes.h"
 
 
-extern const struct gl_pixelstore_attrib _mesa_native_packing;
-
-
 extern void
 _mesa_swap2( GLushort *p, GLuint n );
 
index 3ef508b3f83bcd1b92f2e3488f32b7754506dc50..0dcf54baf7230a922715e38c9cf4192daf48f353 100644 (file)
@@ -1319,17 +1319,18 @@ struct gl_attrib_node {
 
 
 /**
- * GL_ARB_vertex_buffer_object buffer object
+ * GL_ARB_vertex/pixel_buffer_object buffer object
  */
 struct gl_buffer_object {
    GLint RefCount;
    GLuint Name;
    GLenum Usage;
    GLenum Access;
-   GLvoid *Pointer;   /**< Only valid while buffer is mapped */
-   GLuint Size;       /**< Size of data array in bytes */
-   GLubyte *Data;     /**< The storage */
-   GLboolean DeletePending;  /**< Deleted by user? */
+   GLvoid *Pointer;          /**< Only valid while buffer is mapped */
+   GLuint Size;              /**< Size of storage in bytes */
+   GLubyte *Data;            /**< Location of storage either in RAM or VRAM. */
+   GLboolean OnCard;         /**< Is buffer in VRAM? (hardware drivers) */
+   GLboolean DeletePending;  /**< Deleted by user but RefCount > 0? */
 };
 
 
@@ -1348,6 +1349,7 @@ struct gl_pixelstore_attrib {
    GLboolean LsbFirst;
    GLboolean ClientStorage; /**< GL_APPLE_client_storage */
    GLboolean Invert;        /**< GL_MESA_pack_invert */
+   struct gl_buffer_object *BufferObj; /**< GL_ARB_pixel_buffer_object */
 };
 
 
@@ -1518,7 +1520,7 @@ enum register_file
    PROGRAM_NAMED_PARAM,
    PROGRAM_STATE_VAR,
    PROGRAM_WRITE_ONLY,
-       PROGRAM_ADDRESS
+   PROGRAM_ADDRESS
 };
 
 
@@ -1852,6 +1854,7 @@ struct gl_extensions
    GLboolean EXT_multi_draw_arrays;
    GLboolean EXT_paletted_texture;
    GLboolean EXT_packed_pixels;
+   GLboolean EXT_pixel_buffer_object;
    GLboolean EXT_point_parameters;
    GLboolean EXT_polygon_offset;
    GLboolean EXT_rescale_normal;
@@ -2264,6 +2267,7 @@ struct __GLcontextRec {
    struct gl_array_attrib      Array;  /**< Vertex arrays */
    struct gl_pixelstore_attrib Pack;   /**< Pixel packing */
    struct gl_pixelstore_attrib Unpack; /**< Pixel unpacking */
+   struct gl_pixelstore_attrib DefaultPacking; /**< Default params */
 
    struct gl_evaluators EvalMap;   /**< All evaluators */
    struct gl_feedback   Feedback;  /**< Feedback */
index 6800170faae4f79ab75f6a8bfdbabfa3be84c222..8e2b55fc34786c0eb0f81e69f82f43096754c33c 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "glheader.h"
 #include "imports.h"
+#include "image.h"
 #include "colormac.h"
 #include "context.h"
 #include "macros.h"
@@ -1682,7 +1683,8 @@ void _mesa_update_pixel( GLcontext *ctx, GLuint new_state )
 /*****                      Initialization                        *****/
 /**********************************************************************/
 
-void _mesa_init_pixel( GLcontext * ctx )
+void
+_mesa_init_pixel( GLcontext * ctx )
 {
    int i;
 
@@ -1774,6 +1776,9 @@ void _mesa_init_pixel( GLcontext * ctx )
    ctx->Pack.LsbFirst = GL_FALSE;
    ctx->Pack.ClientStorage = GL_FALSE;
    ctx->Pack.Invert = GL_FALSE;
+#if FEATURE_EXT_pixel_buffer_object
+   ctx->Pack.BufferObj = ctx->Array.NullBufferObj;
+#endif
    ctx->Unpack.Alignment = 4;
    ctx->Unpack.RowLength = 0;
    ctx->Unpack.ImageHeight = 0;
@@ -1784,6 +1789,29 @@ void _mesa_init_pixel( GLcontext * ctx )
    ctx->Unpack.LsbFirst = GL_FALSE;
    ctx->Unpack.ClientStorage = GL_FALSE;
    ctx->Unpack.Invert = GL_FALSE;
+#if FEATURE_EXT_pixel_buffer_object
+   ctx->Unpack.BufferObj = ctx->Array.NullBufferObj;
+#endif
+
+   /*
+    * _mesa_unpack_image() returns image data in this format.  When we
+    * execute image commands (glDrawPixels(), glTexImage(), etc) from
+    * within display lists we have to be sure to set the current
+    * unpacking parameters to these values!
+    */
+   ctx->DefaultPacking.Alignment = 1;
+   ctx->DefaultPacking.RowLength = 0;
+   ctx->DefaultPacking.SkipPixels = 0;
+   ctx->DefaultPacking.SkipRows = 0;
+   ctx->DefaultPacking.ImageHeight = 0;
+   ctx->DefaultPacking.SkipImages = 0;
+   ctx->DefaultPacking.SwapBytes = GL_FALSE;
+   ctx->DefaultPacking.LsbFirst = GL_FALSE;
+   ctx->DefaultPacking.ClientStorage = GL_FALSE;
+   ctx->DefaultPacking.Invert = GL_FALSE;
+#if FEATURE_EXT_pixel_buffer_object
+   ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj;
+#endif
 
    if (ctx->Visual.doubleBufferMode) {
       ctx->Pixel.ReadBuffer = GL_BACK;
index 315cd6ca2d34168d28cd8535972321a4cb3b4dca..4ed7d38beb9b8aa8e7fef0e7aca5b36b0f9333db 100644 (file)
@@ -52,6 +52,7 @@
 
 
 #include "glheader.h"
+#include "bufferobj.h"
 #include "colormac.h"
 #include "context.h"
 #include "convolve.h"
@@ -391,7 +392,7 @@ transfer_teximage(GLcontext *ctx, GLuint dimensions,
                _mesa_pack_rgba_span_float(ctx, convWidth,
                                           (const GLfloat (*)[4]) srcf,
                                           texDestFormat, CHAN_TYPE,
-                                          dest, &_mesa_native_packing,
+                                          dest, &ctx->DefaultPacking,
                                           transferOps
                                           & IMAGE_POST_CONVOLUTION_BITS);
                srcf += convWidth * 4;
@@ -519,7 +520,7 @@ _mesa_transfer_teximage(GLcontext *ctx, GLuint dimensions,
       srcFormat = baseInternalFormat;
       srcType = CHAN_TYPE;
       srcAddr = tmpImage;
-      srcPacking = &_mesa_native_packing;
+      srcPacking = &ctx->DefaultPacking;
       freeSourceData = GL_TRUE;
       transferOps = 0;  /* image transfer ops were completed */
    }
@@ -611,7 +612,7 @@ _mesa_transfer_teximage(GLcontext *ctx, GLuint dimensions,
       srcFormat = tmpFormat;
       srcType = CHAN_TYPE;
       srcAddr = tmpImage;
-      srcPacking = &_mesa_native_packing;
+      srcPacking = &ctx->DefaultPacking;
       freeSourceData = GL_TRUE;
    }
 
@@ -740,6 +741,58 @@ transfer_compressed_teximage(GLcontext *ctx, GLuint dimensions,
 }
 
 
+/**
+ * Validate acces to a PBO for texture data.
+ *
+ * \todo If the PBO is really resident in VRAM, this won't work; the
+ * device driver should check for that and do the right thing.
+ */
+static const GLvoid *
+validate_pbo_teximage( GLsizei width, GLsizei height, GLsizei depth,
+                       GLenum format, GLenum type, const GLvoid *pixels,
+                       const struct gl_pixelstore_attrib *unpack )
+{
+   if (unpack->BufferObj->Name == 0) {
+      /* no PBO */
+      return pixels;
+   }
+   else if (_mesa_validate_pbo_access(unpack, width, height, depth, format,
+                                      type, pixels)) {
+      return ADD_POINTERS(unpack->BufferObj->Data, pixels);
+   }
+   /* bad access! */
+   return NULL;
+}
+
+
+/**
+ * Validate that unpacking compressed texture image data from a PBO
+ * won't go out of bounds.
+ *
+ * \todo If the PBO is really resident in VRAM, this won't work; the
+ * device driver should check for that and do the right thing.
+ */
+static const GLvoid *
+validate_pbo_compressed_teximage(GLsizei imageSize, const GLvoid *pixels,
+                               const struct gl_pixelstore_attrib *packing)
+{
+   if (packing->BufferObj->Name == 0) {
+      /* not using a PBO - return pointer unchanged */
+      return pixels;
+   }
+   else {
+      /* using a PBO */
+      if ((const GLubyte *) pixels + imageSize >
+          (const GLubyte *) packing->BufferObj->Size) {
+         /* out of bounds read! */
+         return NULL;
+      }
+      /* OK! */
+      return ADD_POINTERS(packing->BufferObj->Data, pixels);
+   }
+}
+
+
 
 /*
  * This is the software fallback for Driver.TexImage1D()
@@ -785,6 +838,7 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
       return;
    }
 
+   pixels = validate_pbo_teximage(width, 1, 1, format, type, pixels, packing);
    if (!pixels)
       return;
 
@@ -862,6 +916,8 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
       return;
    }
 
+   pixels = validate_pbo_teximage(width, height, 1,
+                                  format, type, pixels, packing);
    if (!pixels)
       return;
 
@@ -934,6 +990,8 @@ _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
       return;
    }
 
+   pixels = validate_pbo_teximage(width, height, depth,
+                                  format, type, pixels, packing);
    if (!pixels)
       return;
 
@@ -980,6 +1038,11 @@ _mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
                           struct gl_texture_object *texObj,
                           struct gl_texture_image *texImage)
 {
+   pixels = validate_pbo_teximage(width, 1, 1,
+                                  format, type, pixels, packing);
+   if (!pixels)
+      return;
+
    if (texImage->IsCompressed) {
       GLint dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,
                                                        texImage->Width);
@@ -1029,6 +1092,11 @@ _mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level,
                           struct gl_texture_object *texObj,
                           struct gl_texture_image *texImage)
 {
+   pixels = validate_pbo_teximage(width, height, 1,
+                                  format, type, pixels, packing);
+   if (!pixels)
+      return;
+
    if (texImage->IsCompressed) {
       GLint dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,
                                                        texImage->Width);
@@ -1113,8 +1181,6 @@ _mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
 }
 
 
-
-
 /*
  * Fallback for Driver.CompressedTexImage1D()
  */
@@ -1167,6 +1233,10 @@ _mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
       return;
    }
 
+   data = validate_pbo_compressed_teximage(imageSize, data, &ctx->Unpack);
+   if (!data)
+      return;
+
    /* copy the data */
    ASSERT(texImage->CompressedSize == (GLuint) imageSize);
    MEMCPY(texImage->Data, data, imageSize);
@@ -1231,6 +1301,10 @@ _mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target,
    ASSERT((xoffset & 3) == 0);
    ASSERT((yoffset & 3) == 0);
 
+   data = validate_pbo_compressed_teximage(imageSize, data, &ctx->Unpack);
+   if (!data)
+      return;
+
    srcRowStride = _mesa_compressed_row_stride(texImage->IntFormat, width);
    src = (const GLubyte *) data;
 
index aeacba88eace85bf205c5aab0613bf800b1cf641..6c8f515b626f8644eabfc62b626ded68a0364824 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  5.1
+ * Version:  6.1
  *
- * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2004  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"),
@@ -53,7 +53,14 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
    struct sw_span span;
 
    ASSERT(ctx->RenderMode == GL_RENDER);
-   ASSERT(bitmap);
+
+   bitmap = _swrast_validate_pbo_access(unpack, width, height, 1,
+                                        GL_COLOR_INDEX, GL_BITMAP,
+                                        (GLvoid *) bitmap);
+   if (!bitmap) {
+      /* XXX GL_INVALID_OPERATION? */
+      return;
+   }
 
    RENDER_START(swrast,ctx);
 
index 0a81048e6f598b65e02c67a3a958d34b4986b4b9..be800d4d5944f07e2d53df5ef59bc82c9755e139 100644 (file)
@@ -27,6 +27,7 @@
  */
 
 #include "imports.h"
+#include "bufferobj.h"
 #include "context.h"
 #include "colormac.h"
 #include "mtypes.h"
@@ -731,3 +732,25 @@ _swrast_print_vertex( GLcontext *ctx, const SWvertex *v )
       _mesa_debug(ctx, "\n");
    }
 }
+
+
+/**
+ * Validate access to a PBO to be sure we're not going to read/write
+ * out of buffer bounds.
+ */
+GLvoid *
+_swrast_validate_pbo_access(const struct gl_pixelstore_attrib *pack,
+                            GLsizei width, GLsizei height, GLsizei depth,
+                            GLenum format, GLenum type, GLvoid *ptr)
+{
+   if (pack->BufferObj->Name == 0) {
+      /* no PBO */
+      return ptr;
+   }
+   else if (_mesa_validate_pbo_access(pack, width, height, depth, format,
+                                      type, ptr)) {
+      return ADD_POINTERS(pack->BufferObj->Data, ptr);
+   }
+   /* bad access! */
+   return NULL;
+}
index 5b6f924405752da31d84d92a756b184c4e514678..337b5a5bfd4da1f4ffea95d0590de2ed24bab303 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  5.1
+ * Version:  6.1
  *
- * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2004  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"),
@@ -785,14 +785,14 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
       GLint row;
       GLfloat *dest, *tmpImage;
 
-      tmpImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat));
+      tmpImage = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
       if (!tmpImage) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
          return;
       }
-      convImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat));
+      convImage = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
       if (!convImage) {
-         FREE(tmpImage);
+         _mesa_free(tmpImage);
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
          return;
       }
@@ -816,10 +816,10 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
          ASSERT(ctx->Pixel.Separable2DEnabled);
          _mesa_convolve_sep_image(ctx, &width, &height, tmpImage, convImage);
       }
-      FREE(tmpImage);
+      _mesa_free(tmpImage);
 
       /* continue transfer ops and draw the convolved image */
-      unpack = &_mesa_native_packing;
+      unpack = &ctx->DefaultPacking;
       pixels = convImage;
       format = GL_RGBA;
       type = GL_FLOAT;
@@ -887,7 +887,7 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
    }
 
    if (convImage) {
-      FREE(convImage);
+      _mesa_free(convImage);
    }
 }
 
@@ -910,6 +910,11 @@ _swrast_DrawPixels( GLcontext *ctx,
    if (swrast->NewState)
       _swrast_validate_derived( ctx );
 
+   pixels = _swrast_validate_pbo_access(unpack, width, height, 1,
+                                        format, type, (GLvoid *) pixels);
+   if (!pixels)
+      return;
+
    RENDER_START(swrast,ctx);
 
    switch (format) {
index b9c413687b17197039d5e972372f147602f2adc3..52c809f7a9bc946924a320da4952dcc27b5721ce 100644 (file)
@@ -1,9 +1,8 @@
-
 /*
  * Mesa 3-D graphics library
- * Version:  4.1
+ * Version:  6.1
  *
- * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2004  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"),
@@ -30,6 +29,9 @@
 
 #include "s_context.h"
 #include "s_span.h"
+#include "colortab.h"
+#include "convolve.h"
+
 
 void
 _swrast_CopyColorTable( GLcontext *ctx, 
@@ -50,9 +52,10 @@ _swrast_CopyColorTable( GLcontext *ctx,
    /* Restore reading from draw buffer (the default) */
    _swrast_use_draw_buffer(ctx);
 
-   glColorTable(target, internalformat, width, GL_RGBA, CHAN_TYPE, data);
+   _mesa_ColorTable(target, internalformat, width, GL_RGBA, CHAN_TYPE, data);
 }
 
+
 void
 _swrast_CopyColorSubTable( GLcontext *ctx,GLenum target, GLsizei start,
                           GLint x, GLint y, GLsizei width)
@@ -71,7 +74,7 @@ _swrast_CopyColorSubTable( GLcontext *ctx,GLenum target, GLsizei start,
    /* Restore reading from draw buffer (the default) */
    _swrast_use_draw_buffer(ctx);
 
-   glColorSubTable(target, start, width, GL_RGBA, CHAN_TYPE, data);
+   _mesa_ColorSubTable(target, start, width, GL_RGBA, CHAN_TYPE, data);
 }
 
 
@@ -98,8 +101,8 @@ _swrast_CopyConvolutionFilter1D(GLcontext *ctx, GLenum target,
    _swrast_use_draw_buffer(ctx);
 
    /* store as convolution filter */
-   glConvolutionFilter1D(target, internalFormat, width,
-                        GL_RGBA, CHAN_TYPE, rgba);
+   _mesa_ConvolutionFilter1D(target, internalFormat, width,
+                             GL_RGBA, CHAN_TYPE, rgba);
 }
 
 
@@ -145,10 +148,11 @@ _swrast_CopyConvolutionFilter2D(GLcontext *ctx, GLenum target,
    ctx->Unpack.SkipImages = 0;
    ctx->Unpack.SwapBytes = GL_FALSE;
    ctx->Unpack.LsbFirst = GL_FALSE;
+   ctx->Unpack.BufferObj = ctx->Array.NullBufferObj;
    ctx->NewState |= _NEW_PACKUNPACK;
 
-   glConvolutionFilter2D(target, internalFormat, width, height,
-                        GL_RGBA, CHAN_TYPE, rgba);
+   _mesa_ConvolutionFilter2D(target, internalFormat, width, height,
+                             GL_RGBA, CHAN_TYPE, rgba);
 
    ctx->Unpack = packSave;  /* restore pixel packing params */
    ctx->NewState |= _NEW_PACKUNPACK; 
index 7c2ce364913c660ac05536c92f1e469d5091245e..b5ab06e4ba6e5ec3919c85b17f30ca8b791349a0 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  5.1
+ * Version:  6.1
  *
- * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2004  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"),
@@ -382,14 +382,14 @@ read_rgba_pixels( GLcontext *ctx,
       GLfloat *dest, *src, *tmpImage, *convImage;
       GLint row;
 
-      tmpImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat));
+      tmpImage = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
       if (!tmpImage) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
          return;
       }
-      convImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat));
+      convImage = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
       if (!convImage) {
-         FREE(tmpImage);
+         _mesa_free(tmpImage);
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
          return;
       }
@@ -410,7 +410,7 @@ read_rgba_pixels( GLcontext *ctx,
             _mesa_map_ci_to_rgba_chan(ctx, readWidth, index, rgba);
          }
          _mesa_pack_rgba_span_chan(ctx, readWidth, (const GLchan (*)[4]) rgba,
-                              GL_RGBA, GL_FLOAT, dest, &_mesa_native_packing,
+                              GL_RGBA, GL_FLOAT, dest, &ctx->DefaultPacking,
                               transferOps & IMAGE_PRE_CONVOLUTION_BITS);
          dest += width * 4;
       }
@@ -423,7 +423,7 @@ read_rgba_pixels( GLcontext *ctx,
          ASSERT(ctx->Pixel.Separable2DEnabled);
          _mesa_convolve_sep_image(ctx, &readWidth, &height, tmpImage, convImage);
       }
-      FREE(tmpImage);
+      _mesa_free(tmpImage);
 
       /* finish transfer ops and pack the resulting image */
       src = convImage;
@@ -501,6 +501,14 @@ _swrast_ReadPixels( GLcontext *ctx,
    if (swrast->NewState)
       _swrast_validate_derived( ctx );
 
+   pixels = _swrast_validate_pbo_access(pack, width, height, 1,
+                                        format, type, (GLvoid *) pixels);
+
+   if (!pixels) {
+      _mesa_error( ctx, GL_INVALID_VALUE, "glReadPixels(pixels)" );
+      return;
+   }
+
    RENDER_START(swrast,ctx);
 
    switch (format) {
index edf75f61f5e115b846e0b7f4cde19f95c0e63c3f..fa6b74b7451e87d7560dd3045960cf66b8c387cd 100644 (file)
@@ -1,9 +1,8 @@
-
 /*
  * Mesa 3-D graphics library
- * Version:  5.1
+ * Version:  6.1
  *
- * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2004  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"),
@@ -68,7 +67,7 @@ read_color_image( GLcontext *ctx, GLint x, GLint y,
    GLint stride, i;
    GLchan *image, *dst;
 
-   image = (GLchan *) MALLOC(width * height * 4 * sizeof(GLchan));
+   image = (GLchan *) _mesa_malloc(width * height * 4 * sizeof(GLchan));
    if (!image)
       return NULL;
 
@@ -105,7 +104,7 @@ read_depth_image( GLcontext *ctx, GLint x, GLint y,
    GLfloat *image, *dst;
    GLint i;
 
-   image = (GLfloat *) MALLOC(width * height * sizeof(GLfloat));
+   image = (GLfloat *) _mesa_malloc(width * height * sizeof(GLfloat));
    if (!image)
       return NULL;
 
@@ -171,8 +170,8 @@ _swrast_copy_teximage1d( GLcontext *ctx, GLenum target, GLint level,
       (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat,
                                 width, border,
                                 GL_DEPTH_COMPONENT, GL_FLOAT, image,
-                                &_mesa_native_packing, texObj, texImage);
-      FREE(image);
+                                &ctx->DefaultPacking, texObj, texImage);
+      _mesa_free(image);
    }
    else {
       /* read RGBA image from framebuffer */
@@ -186,8 +185,8 @@ _swrast_copy_teximage1d( GLcontext *ctx, GLenum target, GLint level,
       (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat,
                                 width, border,
                                 GL_RGBA, CHAN_TYPE, image,
-                                &_mesa_native_packing, texObj, texImage);
-      FREE(image);
+                                &ctx->DefaultPacking, texObj, texImage);
+      _mesa_free(image);
    }
 
    /* GL_SGIS_generate_mipmap */
@@ -230,8 +229,8 @@ _swrast_copy_teximage2d( GLcontext *ctx, GLenum target, GLint level,
       (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat,
                                 width, height, border,
                                 GL_DEPTH_COMPONENT, GL_FLOAT, image,
-                                &_mesa_native_packing, texObj, texImage);
-      FREE(image);
+                                &ctx->DefaultPacking, texObj, texImage);
+      _mesa_free(image);
    }
    else {
       /* read RGBA image from framebuffer */
@@ -245,8 +244,8 @@ _swrast_copy_teximage2d( GLcontext *ctx, GLenum target, GLint level,
       (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat,
                                 width, height, border,
                                 GL_RGBA, CHAN_TYPE, image,
-                                &_mesa_native_packing, texObj, texImage);
-      FREE(image);
+                                &ctx->DefaultPacking, texObj, texImage);
+      _mesa_free(image);
    }
 
    /* GL_SGIS_generate_mipmap */
@@ -286,8 +285,8 @@ _swrast_copy_texsubimage1d( GLcontext *ctx, GLenum target, GLint level,
       /* call glTexSubImage1D to redefine the texture */
       (*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width,
                                    GL_DEPTH_COMPONENT, GL_FLOAT, image,
-                                   &_mesa_native_packing, texObj, texImage);
-      FREE(image);
+                                   &ctx->DefaultPacking, texObj, texImage);
+      _mesa_free(image);
    }
    else {
       /* read RGBA image from framebuffer */
@@ -300,8 +299,8 @@ _swrast_copy_texsubimage1d( GLcontext *ctx, GLenum target, GLint level,
       /* now call glTexSubImage1D to do the real work */
       (*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width,
                                    GL_RGBA, CHAN_TYPE, image,
-                                   &_mesa_native_packing, texObj, texImage);
-      FREE(image);
+                                   &ctx->DefaultPacking, texObj, texImage);
+      _mesa_free(image);
    }
 
    /* GL_SGIS_generate_mipmap */
@@ -344,8 +343,8 @@ _swrast_copy_texsubimage2d( GLcontext *ctx,
       (*ctx->Driver.TexSubImage2D)(ctx, target, level,
                                    xoffset, yoffset, width, height,
                                    GL_DEPTH_COMPONENT, GL_FLOAT, image,
-                                   &_mesa_native_packing, texObj, texImage);
-      FREE(image);
+                                   &ctx->DefaultPacking, texObj, texImage);
+      _mesa_free(image);
    }
    else {
       /* read RGBA image from framebuffer */
@@ -359,8 +358,8 @@ _swrast_copy_texsubimage2d( GLcontext *ctx,
       (*ctx->Driver.TexSubImage2D)(ctx, target, level,
                                    xoffset, yoffset, width, height,
                                    GL_RGBA, CHAN_TYPE, image,
-                                   &_mesa_native_packing, texObj, texImage);
-      FREE(image);
+                                   &ctx->DefaultPacking, texObj, texImage);
+      _mesa_free(image);
    }
 
    /* GL_SGIS_generate_mipmap */
@@ -403,8 +402,8 @@ _swrast_copy_texsubimage3d( GLcontext *ctx,
       (*ctx->Driver.TexSubImage3D)(ctx, target, level,
                                    xoffset, yoffset, zoffset, width, height, 1,
                                    GL_DEPTH_COMPONENT, GL_FLOAT, image,
-                                   &_mesa_native_packing, texObj, texImage);
-      FREE(image);
+                                   &ctx->DefaultPacking, texObj, texImage);
+      _mesa_free(image);
    }
    else {
       /* read RGBA image from framebuffer */
@@ -418,8 +417,8 @@ _swrast_copy_texsubimage3d( GLcontext *ctx,
       (*ctx->Driver.TexSubImage3D)(ctx, target, level,
                                    xoffset, yoffset, zoffset, width, height, 1,
                                    GL_RGBA, CHAN_TYPE, image,
-                                   &_mesa_native_packing, texObj, texImage);
-      FREE(image);
+                                   &ctx->DefaultPacking, texObj, texImage);
+      _mesa_free(image);
    }
 
    /* GL_SGIS_generate_mipmap */
index 61cc017b85d9fa5afcd0ba47915efb13ede783a5..e1220cff4e119e514a0c7b0cd0f369eebf05c889 100644 (file)
@@ -197,6 +197,11 @@ extern void
 _swrast_print_vertex( GLcontext *ctx, const SWvertex *v );
 
 
+extern GLvoid *
+_swrast_validate_pbo_access(const struct gl_pixelstore_attrib *pack,
+                            GLsizei width, GLsizei height, GLsizei depth,
+                            GLenum format, GLenum type, GLvoid *ptr);
+
 /*
  * Imaging fallbacks (a better solution should be found, perhaps
  * moving all the imaging fallback code to a new module) 
@@ -252,7 +257,6 @@ _swrast_copy_texsubimage3d(GLcontext *ctx,
                            GLint x, GLint y, GLsizei width, GLsizei height);
 
 
-
 /* The driver interface for the software rasterizer.
  * Unless otherwise noted, all functions are mandatory.  
  */