Merge branch 'gallium-polygon-stipple'
[mesa.git] / src / mesa / swrast / s_readpix.c
index 5e6356c0d549e14b62915a69c8a419e0f2c89c3a..66ca39293a61ba8bcd22cb93aac8da5efddc316d 100644 (file)
@@ -24,7 +24,6 @@
 
 
 #include "main/glheader.h"
-#include "main/bufferobj.h"
 #include "main/colormac.h"
 #include "main/feedback.h"
 #include "main/formats.h"
@@ -32,6 +31,7 @@
 #include "main/imports.h"
 #include "main/macros.h"
 #include "main/pack.h"
+#include "main/pbo.h"
 #include "main/state.h"
 
 #include "s_context.h"
@@ -191,7 +191,13 @@ fast_read_rgba_pixels( struct gl_context *ctx,
    if (!rb)
       return GL_FALSE;
 
-   ASSERT(rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB ||
+   ASSERT(rb->_BaseFormat == GL_RGBA ||
+         rb->_BaseFormat == GL_RGB ||
+         rb->_BaseFormat == GL_RG ||
+         rb->_BaseFormat == GL_RED ||
+         rb->_BaseFormat == GL_LUMINANCE ||
+         rb->_BaseFormat == GL_INTENSITY ||
+         rb->_BaseFormat == GL_LUMINANCE_ALPHA ||
          rb->_BaseFormat == GL_ALPHA);
 
    /* clipping should have already been done */
@@ -312,12 +318,12 @@ read_rgba_pixels( struct gl_context *ctx,
    if (!rb)
       return;
 
-   if (type == GL_FLOAT && ((ctx->Color.ClampReadColor == GL_TRUE) ||
-                            (ctx->Color.ClampReadColor == GL_FIXED_ONLY_ARB &&
-                             rb->DataType != GL_FLOAT)))
+   if ((ctx->Color._ClampReadColor == GL_TRUE || type != GL_FLOAT) &&
+       !_mesa_is_integer_format(format)) {
       transferOps |= IMAGE_CLAMP_BIT;
+   }
 
-   /* Try optimized path first */
+   /* Try the optimized path first. */
    if (fast_read_rgba_pixels(ctx, x, y, width, height,
                              format, type, pixels, packing, transferOps)) {
       return; /* done! */
@@ -341,9 +347,9 @@ read_rgba_pixels( struct gl_context *ctx,
          _swrast_read_rgba_span(ctx, rb, width, x, y, GL_FLOAT, rgba);
 
          /* apply fudge factor for shallow color buffers */
-         if (fb->Visual.redBits < 8 ||
-             fb->Visual.greenBits < 8 ||
-             fb->Visual.blueBits < 8) {
+         if ((fb->Visual.redBits < 8 && fb->Visual.redBits != 0) ||
+             (fb->Visual.greenBits < 8 && fb->Visual.greenBits != 0) ||
+            (fb->Visual.blueBits < 8 && fb->Visual.blueBits != 0)) {
             adjust_colors(fb, width, rgba);
          }
 
@@ -440,7 +446,7 @@ read_depth_stencil_pixels(struct gl_context *ctx,
             GLfloat depthVals[MAX_WIDTH];
             _swrast_read_depth_span_float(ctx, depthRb, width, x, y + i,
                                           depthVals);
-            _mesa_pack_depth_stencil_span(ctx, width, depthStencilDst,
+            _mesa_pack_depth_stencil_span(ctx, width, type, depthStencilDst,
                                           depthVals, stencilVals, packing);
          }
       }
@@ -476,49 +482,33 @@ _swrast_ReadPixels( struct gl_context *ctx,
       _swrast_validate_derived( ctx );
 
    /* Do all needed clipping here, so that we can forget about it later */
-   if (!_mesa_clip_readpixels(ctx, &x, &y, &width, &height, &clippedPacking)) {
-      /* The ReadPixels region is totally outside the window bounds */
-      swrast_render_finish(ctx);
-      return;
-   }
-
-   pixels = _mesa_map_pbo_dest(ctx, &clippedPacking, pixels);
-   if (!pixels)
-      return;
-  
-   switch (format) {
-      case GL_STENCIL_INDEX:
-        read_stencil_pixels(ctx, x, y, width, height, type, pixels,
+   if (_mesa_clip_readpixels(ctx, &x, &y, &width, &height, &clippedPacking)) {
+
+      pixels = _mesa_map_pbo_dest(ctx, &clippedPacking, pixels);
+
+      if (pixels) {
+         switch (format) {
+         case GL_STENCIL_INDEX:
+            read_stencil_pixels(ctx, x, y, width, height, type, pixels,
+                                &clippedPacking);
+            break;
+         case GL_DEPTH_COMPONENT:
+            read_depth_pixels(ctx, x, y, width, height, type, pixels,
+                              &clippedPacking);
+            break;
+         case GL_DEPTH_STENCIL_EXT:
+            read_depth_stencil_pixels(ctx, x, y, width, height, type, pixels,
+                                      &clippedPacking);
+            break;
+         default:
+            /* all other formats should be color formats */
+            read_rgba_pixels(ctx, x, y, width, height, format, type, pixels,
                              &clippedPacking);
-         break;
-      case GL_DEPTH_COMPONENT:
-        read_depth_pixels(ctx, x, y, width, height, type, pixels,
-                           &clippedPacking);
-        break;
-      case GL_RED:
-      case GL_GREEN:
-      case GL_BLUE:
-      case GL_ALPHA:
-      case GL_RGB:
-      case GL_LUMINANCE:
-      case GL_LUMINANCE_ALPHA:
-      case GL_RGBA:
-      case GL_BGR:
-      case GL_BGRA:
-      case GL_ABGR_EXT:
-         read_rgba_pixels(ctx, x, y, width, height,
-                          format, type, pixels, &clippedPacking);
-        break;
-      case GL_DEPTH_STENCIL_EXT:
-         read_depth_stencil_pixels(ctx, x, y, width, height,
-                                   type, pixels, &clippedPacking);
-         break;
-      default:
-        _mesa_problem(ctx, "unexpected format 0x%x in _swrast_ReadPixels", format);
-         /* don't return yet, clean-up */
+         }
+
+         _mesa_unmap_pbo_dest(ctx, &clippedPacking);
+      }
    }
 
    swrast_render_finish(ctx);
-
-   _mesa_unmap_pbo_dest(ctx, &clippedPacking);
 }