mesa: handle glDrawPixels images which are larger than max rect texture size
authorBrian Paul <brianp@vmware.com>
Wed, 12 Aug 2009 01:30:05 +0000 (19:30 -0600)
committerBrian Paul <brianp@vmware.com>
Wed, 12 Aug 2009 02:34:22 +0000 (20:34 -0600)
src/mesa/drivers/common/meta.c

index 79e93d648b7443a18709de0bc2de41749b80c213..a8db686573f022de2de1e889f3646a04da90b9f4 100644 (file)
@@ -1047,6 +1047,42 @@ _mesa_meta_copy_pixels(GLcontext *ctx, GLint srcX, GLint srcY,
 
 
 
+/**
+ * When the glDrawPixels() image size is greater than the max rectangle
+ * texture size we use this function to break the glDrawPixels() image
+ * into tiles which fit into the max texture size.
+ */
+static void
+tiled_draw_pixels(GLcontext *ctx,
+                  GLint x, GLint y, GLsizei width, GLsizei height,
+                  GLenum format, GLenum type,
+                  const struct gl_pixelstore_attrib *unpack,
+                  const GLvoid *pixels)
+{
+   const GLint maxSize = ctx->Const.MaxTextureRectSize;
+   struct gl_pixelstore_attrib tileUnpack = *unpack;
+   GLint i, j;
+
+   for (i = 0; i < width; i += maxSize) {
+      const GLint tileWidth = MIN2(maxSize, width - i);
+      const GLint tileX = (GLint) (x + i * ctx->Pixel.ZoomX);
+
+      tileUnpack.SkipPixels = unpack->SkipPixels + i;
+
+      for (j = 0; j < height; j += maxSize) {
+         const GLint tileHeight = MIN2(maxSize, height - j);
+         const GLint tileY = (GLint) (y + j * ctx->Pixel.ZoomY);
+
+         tileUnpack.SkipRows = unpack->SkipRows + j;
+
+         _mesa_meta_draw_pixels(ctx, tileX, tileY,
+                                tileWidth, tileHeight,
+                                format, type, &tileUnpack, pixels);
+      }
+   }
+}
+
+
 /**
  * Meta implementation of ctx->Driver.DrawPixels() in terms
  * of texture mapping and polygon rendering.
@@ -1075,9 +1111,7 @@ _mesa_meta_draw_pixels(GLcontext *ctx,
     */
    fallback = GL_FALSE;
    if (ctx->_ImageTransferState ||
-       ctx->Fog.Enabled ||
-       width > ctx->Const.MaxTextureRectSize ||
-       height > ctx->Const.MaxTextureRectSize) {
+       ctx->Fog.Enabled) {
       fallback = GL_TRUE;
    }
 
@@ -1094,6 +1128,16 @@ _mesa_meta_draw_pixels(GLcontext *ctx,
       return;
    }
 
+   /*
+    * Check image size against max texture size, draw as tiles if needed.
+    */
+   if (width > ctx->Const.MaxTextureRectSize ||
+       height > ctx->Const.MaxTextureRectSize) {
+      tiled_draw_pixels(ctx, x, y, width, height,
+                        format, type, unpack, pixels);
+      return;
+   }
+
    /* Most GL state applies to glDrawPixels, but a there's a few things
     * we need to override:
     */