[Mesa-dev] [PATCH 7/8] mesa: implement GL_ARB_robustness functions

nobled nobled at dreamwidth.org
Tue Apr 19 19:30:53 PDT 2011


As long as GLX_ARB_create_context_robustness isn't
implemented yet, these function calls are all that's
needed to implement the spec.

The function pointers just need to be hooked up
to the GLAPI dispatch table and such.
---
 src/mesa/main/colortab.c    |   13 ++++-
 src/mesa/main/convolve.c    |   27 ++++++++++--
 src/mesa/main/eval.c        |   90 +++++++++++++++++++++++++++++++++++++-
 src/mesa/main/get.h         |    4 ++
 src/mesa/main/getstring.c   |   17 +++++++
 src/mesa/main/histogram.c   |   22 ++++++++-
 src/mesa/main/pixel.c       |   34 +++++++++++---
 src/mesa/main/polygon.c     |   11 ++++-
 src/mesa/main/polygon.h     |    3 +
 src/mesa/main/readpix.c     |   16 +++++--
 src/mesa/main/readpix.h     |    4 ++
 src/mesa/main/texgetimage.c |   25 ++++++++--
 src/mesa/main/texgetimage.h |    7 +++-
 src/mesa/main/uniforms.c    |  101 +++++++++++++++++++++++++++++++++++++------
 src/mesa/main/uniforms.h    |   17 +++++++-
 15 files changed, 345 insertions(+), 46 deletions(-)

diff --git a/src/mesa/main/colortab.c b/src/mesa/main/colortab.c
index 5414acc..e3a77d8 100644
--- a/src/mesa/main/colortab.c
+++ b/src/mesa/main/colortab.c
@@ -509,8 +509,8 @@ _mesa_CopyColorSubTable(GLenum target, GLsizei start,


 static void GLAPIENTRY
-_mesa_GetColorTable( GLenum target, GLenum format,
-                     GLenum type, GLvoid *data )
+_mesa_GetnColorTableARB( GLenum target, GLenum format, GLenum type,
+                         GLsizei bufSize, GLvoid *data )
 {
    GET_CURRENT_CONTEXT(ctx);
    struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
@@ -614,7 +614,7 @@ _mesa_GetColorTable( GLenum target, GLenum format,

    data = _mesa_map_validate_pbo_dest(ctx,
                                       1, &ctx->Pack, table->Size, 1, 1,
-                                      format, type, INT_MAX, data,
+                                      format, type, bufSize, data,
                                       "glGetColorTable");
    if (!data)
       return;
@@ -630,6 +630,13 @@ _mesa_GetColorTable( GLenum target, GLenum format,
 }


+static void GLAPIENTRY
+_mesa_GetColorTable( GLenum target, GLenum format,
+                     GLenum type, GLvoid *data )
+{
+   _mesa_GetnColorTableARB(target, format, type, INT_MAX, data);
+}
+

 static void GLAPIENTRY
 _mesa_ColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params)
diff --git a/src/mesa/main/convolve.c b/src/mesa/main/convolve.c
index 5d286eb..d5b3d5b 100644
--- a/src/mesa/main/convolve.c
+++ b/src/mesa/main/convolve.c
@@ -115,8 +115,8 @@ _mesa_CopyConvolutionFilter2D(GLenum target,
GLenum internalFormat, GLint x, GLi


 static void GLAPIENTRY
-_mesa_GetConvolutionFilter(GLenum target, GLenum format, GLenum type,
-                           GLvoid *image)
+_mesa_GetnConvolutionFilterARB(GLenum target, GLenum format, GLenum type,
+                               GLsizei bufSize, GLvoid *image)
 {
    GET_CURRENT_CONTEXT(ctx);

@@ -125,6 +125,14 @@ _mesa_GetConvolutionFilter(GLenum target, GLenum
format, GLenum type,


 static void GLAPIENTRY
+_mesa_GetConvolutionFilter(GLenum target, GLenum format, GLenum type,
+                           GLvoid *image)
+{
+   _mesa_GetnConvolutionFilterARB(target, format, type, INT_MAX, image);
+}
+
+
+static void GLAPIENTRY
 _mesa_GetConvolutionParameterfv(GLenum target, GLenum pname, GLfloat *params)
 {
    GET_CURRENT_CONTEXT(ctx);
@@ -143,8 +151,10 @@ _mesa_GetConvolutionParameteriv(GLenum target,
GLenum pname, GLint *params)


 static void GLAPIENTRY
-_mesa_GetSeparableFilter(GLenum target, GLenum format, GLenum type,
-                         GLvoid *row, GLvoid *column, GLvoid *span)
+_mesa_GetnSeparableFilterARB(GLenum target, GLenum format, GLenum type,
+                             GLsizei rowBufSize, GLvoid *row,
+                             GLsizei columnBufSize,  GLvoid *column,
+                             GLvoid *span)
 {
    GET_CURRENT_CONTEXT(ctx);

@@ -153,6 +163,15 @@ _mesa_GetSeparableFilter(GLenum target, GLenum
format, GLenum type,


 static void GLAPIENTRY
+_mesa_GetSeparableFilter(GLenum target, GLenum format, GLenum type,
+                         GLvoid *row, GLvoid *column, GLvoid *span)
+{
+   _mesa_GetnSeparableFilterARB(target, format, type, INT_MAX, row,
+                                INT_MAX, column, span);
+}
+
+
+static void GLAPIENTRY
 _mesa_SeparableFilter2D(GLenum target, GLenum internalFormat, GLsizei
width, GLsizei height, GLenum format, GLenum type, const GLvoid *row,
const GLvoid *column)
 {
    GET_CURRENT_CONTEXT(ctx);
diff --git a/src/mesa/main/eval.c b/src/mesa/main/eval.c
index 9ab5507..9eb4f67 100644
--- a/src/mesa/main/eval.c
+++ b/src/mesa/main/eval.c
@@ -545,7 +545,7 @@ _mesa_Map2d( GLenum target,


 static void GLAPIENTRY
-_mesa_GetMapdv( GLenum target, GLenum query, GLdouble *v )
+_mesa_GetnMapdvARB( GLenum target, GLenum query, GLsizei bufSize, GLdouble *v )
 {
    GET_CURRENT_CONTEXT(ctx);
    struct gl_1d_map *map1d;
@@ -553,6 +553,7 @@ _mesa_GetMapdv( GLenum target, GLenum query, GLdouble *v )
    GLint i, n;
    GLfloat *data;
    GLuint comps;
+   GLsizei numBytes;

    ASSERT_OUTSIDE_BEGIN_END(ctx);

@@ -577,6 +578,9 @@ _mesa_GetMapdv( GLenum target, GLenum query, GLdouble *v )
             n = map2d->Uorder * map2d->Vorder * comps;
          }
 	 if (data) {
+            numBytes = n * sizeof *v;
+            if (bufSize < numBytes)
+               goto overflow;
 	    for (i=0;i<n;i++) {
 	       v[i] = data[i];
 	    }
@@ -584,19 +588,31 @@ _mesa_GetMapdv( GLenum target, GLenum query, GLdouble *v )
          break;
       case GL_ORDER:
          if (map1d) {
+            numBytes = 1 * sizeof *v;
+            if (bufSize < numBytes)
+               goto overflow;
             v[0] = (GLdouble) map1d->Order;
          }
          else {
+            numBytes = 2 * sizeof *v;
+            if (bufSize < numBytes)
+               goto overflow;
             v[0] = (GLdouble) map2d->Uorder;
             v[1] = (GLdouble) map2d->Vorder;
          }
          break;
       case GL_DOMAIN:
          if (map1d) {
+            numBytes = 2 * sizeof *v;
+            if (bufSize < numBytes)
+              goto overflow;
             v[0] = (GLdouble) map1d->u1;
             v[1] = (GLdouble) map1d->u2;
          }
          else {
+            numBytes = 4 * sizeof *v;
+            if (bufSize < numBytes)
+               goto overflow;
             v[0] = (GLdouble) map2d->u1;
             v[1] = (GLdouble) map2d->u2;
             v[2] = (GLdouble) map2d->v1;
@@ -606,11 +622,22 @@ _mesa_GetMapdv( GLenum target, GLenum query, GLdouble *v )
       default:
          _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapdv(query)" );
    }
+   return;
+
+overflow:
+   _mesa_error( ctx, GL_INVALID_OPERATION,
+               "glGetnMapdvARB(out of bounds: bufSize is %d,"
+               " but %d bytes are required)", bufSize, numBytes );
 }

+static void GLAPIENTRY
+_mesa_GetMapdv( GLenum target, GLenum query, GLdouble *v )
+{
+   _mesa_GetnMapdvARB(target, query, INT_MAX, v);
+}

 static void GLAPIENTRY
-_mesa_GetMapfv( GLenum target, GLenum query, GLfloat *v )
+_mesa_GetnMapfvARB( GLenum target, GLenum query, GLsizei bufSize, GLfloat *v )
 {
    GET_CURRENT_CONTEXT(ctx);
    struct gl_1d_map *map1d;
@@ -618,6 +645,7 @@ _mesa_GetMapfv( GLenum target, GLenum query, GLfloat *v )
    GLint i, n;
    GLfloat *data;
    GLuint comps;
+   GLsizei numBytes;

    ASSERT_OUTSIDE_BEGIN_END(ctx);

@@ -642,6 +670,9 @@ _mesa_GetMapfv( GLenum target, GLenum query, GLfloat *v )
             n = map2d->Uorder * map2d->Vorder * comps;
          }
 	 if (data) {
+            numBytes = n * sizeof *v;
+            if (bufSize < numBytes)
+               goto overflow;
 	    for (i=0;i<n;i++) {
 	       v[i] = data[i];
 	    }
@@ -649,19 +680,31 @@ _mesa_GetMapfv( GLenum target, GLenum query, GLfloat *v )
          break;
       case GL_ORDER:
          if (map1d) {
+            numBytes = 1 * sizeof *v;
+            if (bufSize < numBytes)
+               goto overflow;
             v[0] = (GLfloat) map1d->Order;
          }
          else {
+            numBytes = 2 * sizeof *v;
+            if (bufSize < numBytes)
+               goto overflow;
             v[0] = (GLfloat) map2d->Uorder;
             v[1] = (GLfloat) map2d->Vorder;
          }
          break;
       case GL_DOMAIN:
          if (map1d) {
+            numBytes = 2 * sizeof *v;
+            if (bufSize < numBytes)
+               goto overflow;
             v[0] = map1d->u1;
             v[1] = map1d->u2;
          }
          else {
+            numBytes = 4 * sizeof *v;
+            if (bufSize < numBytes)
+               goto overflow;
             v[0] = map2d->u1;
             v[1] = map2d->u2;
             v[2] = map2d->v1;
@@ -671,11 +714,24 @@ _mesa_GetMapfv( GLenum target, GLenum query, GLfloat *v )
       default:
          _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapfv(query)" );
    }
+   return;
+
+overflow:
+   _mesa_error( ctx, GL_INVALID_OPERATION,
+               "glGetnMapfvARB(out of bounds: bufSize is %d,"
+               " but %d bytes are required)", bufSize, numBytes );
 }


 static void GLAPIENTRY
-_mesa_GetMapiv( GLenum target, GLenum query, GLint *v )
+_mesa_GetMapfv( GLenum target, GLenum query, GLfloat *v )
+{
+   _mesa_GetnMapfvARB(target, query, INT_MAX, v);
+}
+
+
+static void GLAPIENTRY
+_mesa_GetnMapivARB( GLenum target, GLenum query, GLsizei bufSize, GLint *v )
 {
    GET_CURRENT_CONTEXT(ctx);
    struct gl_1d_map *map1d;
@@ -683,6 +739,7 @@ _mesa_GetMapiv( GLenum target, GLenum query, GLint *v )
    GLuint i, n;
    GLfloat *data;
    GLuint comps;
+   GLsizei numBytes;

    ASSERT_OUTSIDE_BEGIN_END(ctx);

@@ -707,6 +764,9 @@ _mesa_GetMapiv( GLenum target, GLenum query, GLint *v )
             n = map2d->Uorder * map2d->Vorder * comps;
          }
 	 if (data) {
+            numBytes = n * sizeof *v;
+            if (bufSize < numBytes)
+               goto overflow;
 	    for (i=0;i<n;i++) {
 	       v[i] = IROUND(data[i]);
 	    }
@@ -714,19 +774,31 @@ _mesa_GetMapiv( GLenum target, GLenum query, GLint *v )
          break;
       case GL_ORDER:
          if (map1d) {
+            numBytes = 1 * sizeof *v;
+            if (bufSize < numBytes)
+               goto overflow;
             v[0] = map1d->Order;
          }
          else {
+            numBytes = 2 * sizeof *v;
+            if (bufSize < numBytes)
+               goto overflow;
             v[0] = map2d->Uorder;
             v[1] = map2d->Vorder;
          }
          break;
       case GL_DOMAIN:
          if (map1d) {
+            numBytes = 2 * sizeof *v;
+            if (bufSize < numBytes)
+               goto overflow;
             v[0] = IROUND(map1d->u1);
             v[1] = IROUND(map1d->u2);
          }
          else {
+            numBytes = 4 * sizeof *v;
+            if (bufSize < numBytes)
+               goto overflow;
             v[0] = IROUND(map2d->u1);
             v[1] = IROUND(map2d->u2);
             v[2] = IROUND(map2d->v1);
@@ -736,9 +808,21 @@ _mesa_GetMapiv( GLenum target, GLenum query, GLint *v )
       default:
          _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapiv(query)" );
    }
+   return;
+
+overflow:
+   _mesa_error( ctx, GL_INVALID_OPERATION,
+               "glGetnMapivARB(out of bounds: bufSize is %d,"
+               " but %d bytes are required)", bufSize, numBytes );
 }


+static void GLAPIENTRY
+_mesa_GetMapiv( GLenum target, GLenum query, GLint *v )
+{
+   _mesa_GetnMapivARB(target, query, INT_MAX, v);
+}
+

 static void GLAPIENTRY
 _mesa_MapGrid1f( GLint un, GLfloat u1, GLfloat u2 )
diff --git a/src/mesa/main/get.h b/src/mesa/main/get.h
index 99a004b..9422efe 100644
--- a/src/mesa/main/get.h
+++ b/src/mesa/main/get.h
@@ -74,4 +74,8 @@ _mesa_GetStringi(GLenum name, GLuint index);
 extern GLenum GLAPIENTRY
 _mesa_GetError( void );

+/* GL_ARB_robustness */
+extern GLenum GLAPIENTRY
+_mesa_GetGraphicsResetStatusARB( void );
+
 #endif
diff --git a/src/mesa/main/getstring.c b/src/mesa/main/getstring.c
index f8866f6..c381fb2 100644
--- a/src/mesa/main/getstring.c
+++ b/src/mesa/main/getstring.c
@@ -251,3 +251,20 @@ _mesa_GetError( void )
    ctx->ErrorDebugCount = 0;
    return e;
 }
+
+/**
+ * Returns an error code specified by GL_ARB_robustness, or GL_NO_ERROR.
+ * \return current context status
+ */
+GLenum GLAPIENTRY
+_mesa_GetGraphicsResetStatusARB( void )
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLenum status = ctx->ResetStatus;
+
+   if (MESA_VERBOSE & VERBOSE_API)
+      _mesa_debug(ctx, "glGetGraphicsResetStatusARB"
+                       "(always returns GL_NO_ERROR)\n");
+
+   return status;
+}
diff --git a/src/mesa/main/histogram.c b/src/mesa/main/histogram.c
index 75bb925..bc5576d 100644
--- a/src/mesa/main/histogram.c
+++ b/src/mesa/main/histogram.c
@@ -44,7 +44,8 @@ static void GLAPIENTRY _mesa_ResetMinmax(GLenum target);


 static void GLAPIENTRY
-_mesa_GetMinmax(GLenum target, GLboolean reset, GLenum format, GLenum
type, GLvoid *values)
+_mesa_GetnMinmaxARB(GLenum target, GLboolean reset, GLenum format,
+                    GLenum type, GLsizei bufSize, GLvoid *values)
 {
    GET_CURRENT_CONTEXT(ctx);

@@ -53,7 +54,16 @@ _mesa_GetMinmax(GLenum target, GLboolean reset,
GLenum format, GLenum type, GLvo


 static void GLAPIENTRY
-_mesa_GetHistogram(GLenum target, GLboolean reset, GLenum format,
GLenum type, GLvoid *values)
+_mesa_GetMinmax(GLenum target, GLboolean reset, GLenum format, GLenum type,
+                GLvoid *values)
+{
+   _mesa_GetnMinmaxARB(target, reset, format, type, INT_MAX, values);
+}
+
+
+static void GLAPIENTRY
+_mesa_GetnHistogramARB(GLenum target, GLboolean reset, GLenum format,
+                       GLenum type, GLsizei bufSize, GLvoid *values)
 {
    GET_CURRENT_CONTEXT(ctx);

@@ -62,6 +72,14 @@ _mesa_GetHistogram(GLenum target, GLboolean reset,
GLenum format, GLenum type, G


 static void GLAPIENTRY
+_mesa_GetHistogram(GLenum target, GLboolean reset, GLenum format, GLenum type,
+                   GLvoid *values)
+{
+   _mesa_GetnHistogramARB(target, reset, format, type, INT_MAX, values);
+}
+
+
+static void GLAPIENTRY
 _mesa_GetHistogramParameterfv(GLenum target, GLenum pname, GLfloat *params)
 {
    GET_CURRENT_CONTEXT(ctx);
diff --git a/src/mesa/main/pixel.c b/src/mesa/main/pixel.c
index 62dd13e..724b998 100644
--- a/src/mesa/main/pixel.c
+++ b/src/mesa/main/pixel.c
@@ -334,10 +334,10 @@ _mesa_PixelMapusv(GLenum map, GLsizei mapsize,
const GLushort *values )


 static void GLAPIENTRY
-_mesa_GetPixelMapfv( GLenum map, GLfloat *values )
+_mesa_GetnPixelMapfvARB( GLenum map, GLsizei bufSize, GLfloat *values )
 {
    GET_CURRENT_CONTEXT(ctx);
-   GLuint mapsize, i;
+   GLint mapsize, i;
    const struct gl_pixelmap *pm;

    ASSERT_OUTSIDE_BEGIN_END(ctx);
@@ -351,7 +351,7 @@ _mesa_GetPixelMapfv( GLenum map, GLfloat *values )
    mapsize = pm->Size;

    if (!validate_pbo_access(ctx, &ctx->Pack, mapsize, GL_INTENSITY,
-                            GL_FLOAT, INT_MAX, values)) {
+                            GL_FLOAT, bufSize, values)) {
       return;
    }

@@ -379,7 +379,13 @@ _mesa_GetPixelMapfv( GLenum map, GLfloat *values )


 static void GLAPIENTRY
-_mesa_GetPixelMapuiv( GLenum map, GLuint *values )
+_mesa_GetPixelMapfv( GLenum map, GLfloat *values )
+{
+   _mesa_GetnPixelMapfvARB(map, INT_MAX, values);
+}
+
+static void GLAPIENTRY
+_mesa_GetnPixelMapuivARB( GLenum map, GLsizei bufSize, GLuint *values )
 {
    GET_CURRENT_CONTEXT(ctx);
    GLint mapsize, i;
@@ -392,10 +398,11 @@ _mesa_GetPixelMapuiv( GLenum map, GLuint *values )
       _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapuiv(map)");
       return;
    }
+
    mapsize = pm->Size;

    if (!validate_pbo_access(ctx, &ctx->Pack, mapsize, GL_INTENSITY,
-                            GL_UNSIGNED_INT, INT_MAX, values)) {
+                            GL_UNSIGNED_INT, bufSize, values)) {
       return;
    }

@@ -423,7 +430,13 @@ _mesa_GetPixelMapuiv( GLenum map, GLuint *values )


 static void GLAPIENTRY
-_mesa_GetPixelMapusv( GLenum map, GLushort *values )
+_mesa_GetPixelMapuiv( GLenum map, GLuint *values )
+{
+   _mesa_GetnPixelMapuivARB(map, INT_MAX, values);
+}
+
+static void GLAPIENTRY
+_mesa_GetnPixelMapusvARB( GLenum map, GLsizei bufSize, GLushort *values )
 {
    GET_CURRENT_CONTEXT(ctx);
    GLint mapsize, i;
@@ -436,10 +449,11 @@ _mesa_GetPixelMapusv( GLenum map, GLushort *values )
       _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapusv(map)");
       return;
    }
+
    mapsize = pm->Size;

    if (!validate_pbo_access(ctx, &ctx->Pack, mapsize, GL_INTENSITY,
-                            GL_UNSIGNED_SHORT, INT_MAX, values)) {
+                            GL_UNSIGNED_SHORT, bufSize, values)) {
       return;
    }

@@ -474,6 +488,12 @@ _mesa_GetPixelMapusv( GLenum map, GLushort *values )
 }


+static void GLAPIENTRY
+_mesa_GetPixelMapusv( GLenum map, GLushort *values )
+{
+   _mesa_GetnPixelMapusvARB(map, INT_MAX, values);
+}
+

 /**********************************************************************/
 /*****                       glPixelTransfer                      *****/
diff --git a/src/mesa/main/polygon.c b/src/mesa/main/polygon.c
index c985235..addca02 100644
--- a/src/mesa/main/polygon.c
+++ b/src/mesa/main/polygon.c
@@ -232,7 +232,7 @@ _mesa_PolygonStipple( const GLubyte *pattern )
  * Called by glPolygonStipple.
  */
 void GLAPIENTRY
-_mesa_GetPolygonStipple( GLubyte *dest )
+_mesa_GetnPolygonStippleARB( GLsizei bufSize, GLubyte *dest )
 {
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END(ctx);
@@ -243,7 +243,7 @@ _mesa_GetPolygonStipple( GLubyte *dest )
    dest = _mesa_map_validate_pbo_dest(ctx, 2,
                                       &ctx->Pack, 32, 32, 1,
                                       GL_COLOR_INDEX, GL_BITMAP,
-                                      INT_MAX, dest, "glGetPolygonStipple");
+                                      bufSize, dest, "glGetPolygonStipple");
    if (!dest)
       return;

@@ -254,6 +254,13 @@ _mesa_GetPolygonStipple( GLubyte *dest )


 void GLAPIENTRY
+_mesa_GetPolygonStipple( GLubyte *dest )
+{
+   _mesa_GetnPolygonStippleARB(INT_MAX, dest);
+}
+
+
+void GLAPIENTRY
 _mesa_PolygonOffset( GLfloat factor, GLfloat units )
 {
    GET_CURRENT_CONTEXT(ctx);
diff --git a/src/mesa/main/polygon.h b/src/mesa/main/polygon.h
index 13f7c91..71d6490 100644
--- a/src/mesa/main/polygon.h
+++ b/src/mesa/main/polygon.h
@@ -61,6 +61,9 @@ _mesa_PolygonStipple( const GLubyte *mask );
 extern void GLAPIENTRY
 _mesa_GetPolygonStipple( GLubyte *mask );

+extern void GLAPIENTRY
+_mesa_GetnPolygonStippleARB( GLsizei bufSize, GLubyte *dest );
+
 extern void
 _mesa_init_polygon( struct gl_context * ctx );

diff --git a/src/mesa/main/readpix.c b/src/mesa/main/readpix.c
index 465be9f..0331a8c 100644
--- a/src/mesa/main/readpix.c
+++ b/src/mesa/main/readpix.c
@@ -167,8 +167,9 @@ _mesa_error_check_format_type(struct gl_context
*ctx, GLenum format,


 void GLAPIENTRY
-_mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,
-		  GLenum format, GLenum type, GLvoid *pixels )
+_mesa_ReadnPixelsARB( GLint x, GLint y, GLsizei width, GLsizei height,
+		      GLenum format, GLenum type, GLsizei bufSize,
+                      GLvoid *pixels )
 {
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
@@ -225,14 +226,14 @@ _mesa_ReadPixels( GLint x, GLint y, GLsizei
width, GLsizei height,
       return; /* nothing to do */

    if (!_mesa_validate_pbo_access(2, &ctx->Pack, width, height, 1,
-                                  format, type, INT_MAX, pixels)) {
+                                  format, type, bufSize, pixels)) {
       if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
          _mesa_error(ctx, GL_INVALID_OPERATION,
                      "glReadPixels(out of bounds PBO access)");
       } else {
          _mesa_error(ctx, GL_INVALID_OPERATION,
                      "glReadnPixelsARB(out of bounds access:"
-                     " bufSize (%d) is too small)", INT_MAX);
+                     " bufSize (%d) is too small)", bufSize);
       }
       return;
    }
@@ -247,3 +248,10 @@ _mesa_ReadPixels( GLint x, GLint y, GLsizei
width, GLsizei height,
    ctx->Driver.ReadPixels(ctx, x, y, width, height,
 			  format, type, &ctx->Pack, pixels);
 }
+
+void GLAPIENTRY
+_mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,
+		  GLenum format, GLenum type, GLvoid *pixels )
+{
+   _mesa_ReadnPixelsARB(x, y, width, height, format, type, INT_MAX, pixels);
+}
diff --git a/src/mesa/main/readpix.h b/src/mesa/main/readpix.h
index fd25e70..f6bb3d6 100644
--- a/src/mesa/main/readpix.h
+++ b/src/mesa/main/readpix.h
@@ -39,5 +39,9 @@ extern void GLAPIENTRY
 _mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,
                   GLenum format, GLenum type, GLvoid *pixels );

+extern void GLAPIENTRY
+_mesa_ReadnPixelsARB( GLint x, GLint y, GLsizei width, GLsizei height,
+		      GLenum format, GLenum type, GLsizei bufSize,
+                      GLvoid *pixels );

 #endif
diff --git a/src/mesa/main/texgetimage.c b/src/mesa/main/texgetimage.c
index 581d7fd..467baa2 100644
--- a/src/mesa/main/texgetimage.c
+++ b/src/mesa/main/texgetimage.c
@@ -767,11 +767,12 @@ getteximage_error_check(struct gl_context *ctx,
GLenum target, GLint level,
  * \param level image level.
  * \param format pixel data format for returned image.
  * \param type pixel data type for returned image.
+ * \param bufSize size of the pixels data buffer.
  * \param pixels returned pixel data.
  */
 void GLAPIENTRY
-_mesa_GetTexImage( GLenum target, GLint level, GLenum format,
-                   GLenum type, GLvoid *pixels )
+_mesa_GetnTexImageARB( GLenum target, GLint level, GLenum format,
+                       GLenum type, GLsizei bufSize, GLvoid *pixels )
 {
    struct gl_texture_object *texObj;
    struct gl_texture_image *texImage;
@@ -779,7 +780,7 @@ _mesa_GetTexImage( GLenum target, GLint level,
GLenum format,
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);

    if (getteximage_error_check(ctx, target, level, format, type,
-                               INT_MAX, pixels)) {
+                               bufSize, pixels)) {
       return;
    }

@@ -809,6 +810,13 @@ _mesa_GetTexImage( GLenum target, GLint level,
GLenum format,
 }


+void GLAPIENTRY
+_mesa_GetTexImage( GLenum target, GLint level, GLenum format,
+                   GLenum type, GLvoid *pixels )
+{
+   _mesa_GetnTexImageARB(target, level, format, type, INT_MAX, pixels);
+}
+

 /**
  * Do error checking for a glGetCompressedTexImage() call.
@@ -897,14 +905,15 @@ getcompressedteximage_error_check(struct
gl_context *ctx, GLenum target,


 void GLAPIENTRY
-_mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img)
+_mesa_GetnCompressedTexImageARB(GLenum target, GLint level, GLsizei bufSize,
+                                GLvoid *img)
 {
    struct gl_texture_object *texObj;
    struct gl_texture_image *texImage;
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);

-   if (getcompressedteximage_error_check(ctx, target, level, INT_MAX, img)) {
+   if (getcompressedteximage_error_check(ctx, target, level, bufSize, img)) {
       return;
    }

@@ -931,3 +940,9 @@ _mesa_GetCompressedTexImageARB(GLenum target,
GLint level, GLvoid *img)
    }
    _mesa_unlock_texture(ctx, texObj);
 }
+
+void GLAPIENTRY
+_mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img)
+{
+   _mesa_GetnCompressedTexImageARB(target, level, INT_MAX, img);
+}
diff --git a/src/mesa/main/texgetimage.h b/src/mesa/main/texgetimage.h
index ef420dd..8612705 100644
--- a/src/mesa/main/texgetimage.h
+++ b/src/mesa/main/texgetimage.h
@@ -51,10 +51,15 @@ _mesa_get_compressed_teximage(struct gl_context
*ctx, GLenum target, GLint level
 extern void GLAPIENTRY
 _mesa_GetTexImage( GLenum target, GLint level,
                    GLenum format, GLenum type, GLvoid *pixels );
-
+extern void GLAPIENTRY
+_mesa_GetnTexImageARB( GLenum target, GLint level, GLenum format,
+                       GLenum type, GLsizei bufSize, GLvoid *pixels );

 extern void GLAPIENTRY
 _mesa_GetCompressedTexImageARB(GLenum target, GLint lod, GLvoid *img);

+extern void GLAPIENTRY
+_mesa_GetnCompressedTexImageARB(GLenum target, GLint level, GLsizei bufSize,
+                                GLvoid *img);

 #endif /* TEXGETIMAGE_H */
diff --git a/src/mesa/main/uniforms.c b/src/mesa/main/uniforms.c
index f984ce3..1ad5e0a 100644
--- a/src/mesa/main/uniforms.c
+++ b/src/mesa/main/uniforms.c
@@ -412,11 +412,10 @@ split_location_offset(GLint *location, GLint *offset)
  */
 static void
 _mesa_get_uniformfv(struct gl_context *ctx, GLuint program, GLint location,
-                    GLfloat *params)
+                    GLsizei bufSize, GLfloat *params)
 {
    struct gl_program *prog;
-   GLint paramPos;
-   GLint offset;
+   GLint paramPos, offset;

    split_location_offset(&location, &offset);

@@ -426,9 +425,18 @@ _mesa_get_uniformfv(struct gl_context *ctx,
GLuint program, GLint location,
       const struct gl_program_parameter *p =
          &prog->Parameters->Parameters[paramPos];
       GLint rows, cols, i, j, k;
+      GLsizei numBytes;

       get_uniform_rows_cols(p, &rows, &cols);

+      numBytes = rows * cols * sizeof *params;
+      if (bufSize < numBytes) {
+         _mesa_error( ctx, GL_INVALID_OPERATION,
+                     "glGetnUniformfvARB(out of bounds: bufSize is %d,"
+                     " but %d bytes are required)", bufSize, numBytes );
+         return;
+      }
+
       k = 0;
       for (i = 0; i < rows; i++) {
 	 const int base = paramPos + offset + i;
@@ -447,11 +455,10 @@ _mesa_get_uniformfv(struct gl_context *ctx,
GLuint program, GLint location,
  */
 static void
 _mesa_get_uniformiv(struct gl_context *ctx, GLuint program, GLint location,
-                    GLint *params)
+                    GLsizei bufSize, GLint *params)
 {
    struct gl_program *prog;
-   GLint paramPos;
-   GLint offset;
+   GLint paramPos, offset;

    split_location_offset(&location, &offset);

@@ -461,9 +468,18 @@ _mesa_get_uniformiv(struct gl_context *ctx,
GLuint program, GLint location,
       const struct gl_program_parameter *p =
          &prog->Parameters->Parameters[paramPos];
       GLint rows, cols, i, j, k;
+      GLsizei numBytes;

       get_uniform_rows_cols(p, &rows, &cols);

+      numBytes = rows * cols * sizeof *params;
+      if (bufSize < numBytes) {
+         _mesa_error( ctx, GL_INVALID_OPERATION,
+                     "glGetnUniformivARB(out of bounds: bufSize is %d,"
+                     " but %d bytes are required)", bufSize, numBytes );
+         return;
+      }
+
       k = 0;
       for (i = 0; i < rows; i++) {
 	 const int base = paramPos + offset + i;
@@ -483,11 +499,10 @@ _mesa_get_uniformiv(struct gl_context *ctx,
GLuint program, GLint location,
  */
 static void
 _mesa_get_uniformuiv(struct gl_context *ctx, GLuint program, GLint location,
-                     GLuint *params)
+                     GLsizei bufSize, GLuint *params)
 {
    struct gl_program *prog;
-   GLint paramPos;
-   GLint offset;
+   GLint paramPos, offset;

    split_location_offset(&location, &offset);

@@ -497,9 +512,18 @@ _mesa_get_uniformuiv(struct gl_context *ctx,
GLuint program, GLint location,
       const struct gl_program_parameter *p =
          &prog->Parameters->Parameters[paramPos];
       GLint rows, cols, i, j, k;
+      GLsizei numBytes;

       get_uniform_rows_cols(p, &rows, &cols);

+      numBytes = rows * cols * sizeof *params;
+      if (bufSize < numBytes) {
+         _mesa_error( ctx, GL_INVALID_OPERATION,
+                     "glGetnUniformuivARB(out of bounds: bufSize is %d,"
+                     " but %d bytes are required)", bufSize, numBytes );
+         return;
+      }
+
       k = 0;
       for (i = 0; i < rows; i++) {
 	 const int base = paramPos + offset + i;
@@ -513,6 +537,19 @@ _mesa_get_uniformuiv(struct gl_context *ctx,
GLuint program, GLint location,


 /**
+ * Called via glGetUniformdv().
+ * New in GL_ARB_gpu_shader_fp64, OpenGL 4.0
+ */
+static void
+_mesa_get_uniformdv(struct gl_context *ctx, GLuint program, GLint location,
+                    GLsizei bufSize, GLdouble *params)
+{
+   _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformdvARB"
+               "(GL_ARB_gpu_shader_fp64 not implemented)");
+}
+
+
+/**
  * Called via glGetUniformLocation().
  *
  * The return value will encode two values, the uniform location and an
@@ -1350,29 +1387,65 @@ _mesa_UniformMatrix4x3fv(GLint location,
GLsizei count, GLboolean transpose,


 void GLAPIENTRY
-_mesa_GetUniformfvARB(GLhandleARB program, GLint location, GLfloat *params)
+_mesa_GetnUniformfvARB(GLhandleARB program, GLint location,
+                       GLsizei bufSize, GLfloat *params)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_get_uniformfv(ctx, program, location, params);
+   _mesa_get_uniformfv(ctx, program, location, bufSize, params);
+}
+
+void GLAPIENTRY
+_mesa_GetUniformfvARB(GLhandleARB program, GLint location, GLfloat *params)
+{
+   _mesa_GetnUniformfvARB(program, location, INT_MAX, params);
 }


 void GLAPIENTRY
-_mesa_GetUniformivARB(GLhandleARB program, GLint location, GLint *params)
+_mesa_GetnUniformivARB(GLhandleARB program, GLint location,
+                       GLsizei bufSize, GLint *params)
 {
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_get_uniformiv(ctx, program, location, params);
+   _mesa_get_uniformiv(ctx, program, location, bufSize, params);
+}
+
+void GLAPIENTRY
+_mesa_GetUniformivARB(GLhandleARB program, GLint location, GLint *params)
+{
+   _mesa_GetnUniformivARB(program, location, INT_MAX, params);
 }


 /* GL3 */
 void GLAPIENTRY
+_mesa_GetnUniformuivARB(GLhandleARB program, GLint location,
+                        GLsizei bufSize, GLuint *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_get_uniformuiv(ctx, program, location, bufSize, params);
+}
+
+void GLAPIENTRY
 _mesa_GetUniformuiv(GLhandleARB program, GLint location, GLuint *params)
 {
+   _mesa_GetnUniformuivARB(program, location, INT_MAX, params);
+}
+
+
+/* GL4 */
+void GLAPIENTRY
+_mesa_GetnUniformdvARB(GLhandleARB program, GLint location,
+                        GLsizei bufSize, GLdouble *params)
+{
    GET_CURRENT_CONTEXT(ctx);
-   _mesa_get_uniformuiv(ctx, program, location, params);
+   _mesa_get_uniformdv(ctx, program, location, bufSize, params);
 }

+void GLAPIENTRY
+_mesa_GetUniformdv(GLhandleARB program, GLint location, GLdouble *params)
+{
+   _mesa_GetnUniformdvARB(program, location, INT_MAX, params);
+}


 GLint GLAPIENTRY
diff --git a/src/mesa/main/uniforms.h b/src/mesa/main/uniforms.h
index 54abb08..b024cb3 100644
--- a/src/mesa/main/uniforms.h
+++ b/src/mesa/main/uniforms.h
@@ -146,10 +146,25 @@ extern void GLAPIENTRY
 _mesa_GetUniformfvARB(GLhandleARB, GLint, GLfloat *);

 extern void GLAPIENTRY
+_mesa_GetnUniformfvARB(GLhandleARB, GLint, GLsizei, GLfloat *);
+
+extern void GLAPIENTRY
 _mesa_GetUniformivARB(GLhandleARB, GLint, GLint *);

 extern void GLAPIENTRY
-_mesa_GetUniformuiv(GLhandleARB program, GLint location, GLuint *params);
+_mesa_GetnUniformivARB(GLhandleARB, GLint, GLsizei, GLint *);
+
+extern void GLAPIENTRY
+_mesa_GetUniformuiv(GLhandleARB, GLint, GLuint *);
+
+extern void GLAPIENTRY
+_mesa_GetnUniformuivARB(GLhandleARB, GLint, GLsizei, GLuint *);
+
+extern void GLAPIENTRY
+_mesa_GetUniformdv(GLhandleARB, GLint, GLdouble *);
+
+extern void GLAPIENTRY
+_mesa_GetnUniformdvARB(GLhandleARB, GLint, GLsizei, GLdouble *);

 extern GLint GLAPIENTRY
 _mesa_GetUniformLocationARB(GLhandleARB, const GLcharARB *);
-- 
1.7.0.4


More information about the mesa-dev mailing list