st/mesa: Validate the state in st_readpixels.
[mesa.git] / src / mesa / state_tracker / st_cb_readpixels.c
index ccf1a0b5634b9f9fa4f908f064bd9eb3dc46cc55..f0a02ab7664216593ae1bfa08c2eed362d5cab0c 100644 (file)
 
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
-#include "pipe/p_inlines.h"
+#include "util/u_inlines.h"
 #include "util/u_tile.h"
 
+#include "st_debug.h"
 #include "st_context.h"
-#include "st_cb_bitmap.h"
+#include "st_atom.h"
 #include "st_cb_readpixels.h"
 #include "st_cb_fbo.h"
-#include "st_format.h"
 #include "st_public.h"
 #include "st_texture.h"
 #include "st_inlines.h"
@@ -102,14 +102,14 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
       }
 
       /* get stencil (and Z) values */
-      switch (pt->format) {
+      switch (pt->texture->format) {
       case PIPE_FORMAT_S8_UNORM:
          {
             const ubyte *src = stmap + srcY * pt->stride;
             memcpy(sValues, src, width);
          }
          break;
-      case PIPE_FORMAT_S8Z24_UNORM:
+      case PIPE_FORMAT_Z24S8_UNORM:
          if (format == GL_DEPTH_STENCIL) {
             const uint *src = (uint *) (stmap + srcY * pt->stride);
             const GLfloat scale = 1.0f / (0xffffff);
@@ -127,7 +127,7 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
             }
          }
          break;
-      case PIPE_FORMAT_Z24S8_UNORM:
+      case PIPE_FORMAT_S8Z24_UNORM:
          if (format == GL_DEPTH_STENCIL) {
             const uint *src = (uint *) (stmap + srcY * pt->stride);
             const GLfloat scale = 1.0f / (0xffffff);
@@ -215,15 +215,15 @@ st_fast_readpixels(GLcontext *ctx, struct st_renderbuffer *strb,
    if (ctx->_ImageTransferState)
       return GL_FALSE;
 
-   if (strb->format == PIPE_FORMAT_A8R8G8B8_UNORM &&
+   if (strb->format == PIPE_FORMAT_B8G8R8A8_UNORM &&
        format == GL_RGBA && type == GL_UNSIGNED_BYTE) {
       combo = A8R8G8B8_UNORM_TO_RGBA_UBYTE;
    }
-   else if (strb->format == PIPE_FORMAT_A8R8G8B8_UNORM &&
+   else if (strb->format == PIPE_FORMAT_B8G8R8A8_UNORM &&
             format == GL_RGB && type == GL_UNSIGNED_BYTE) {
       combo = A8R8G8B8_UNORM_TO_RGB_UBYTE;
    }
-   else if (strb->format == PIPE_FORMAT_A8R8G8B8_UNORM &&
+   else if (strb->format == PIPE_FORMAT_B8G8R8A8_UNORM &&
             format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8_REV) {
       combo = A8R8G8B8_UNORM_TO_BGRA_UINT;
    }
@@ -242,7 +242,8 @@ st_fast_readpixels(GLcontext *ctx, struct st_renderbuffer *strb,
       GLint row, col, dy, dstStride;
 
       if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
-         y = strb->texture->height[0] - y - height;
+         /* convert GL Y to Gallium Y */
+         y = strb->texture->height0 - y - height;
       }
 
       trans = st_cond_flush_get_tex_transfer(st_context(ctx), strb->texture,
@@ -259,11 +260,16 @@ st_fast_readpixels(GLcontext *ctx, struct st_renderbuffer *strb,
          return GL_FALSE;
       }
 
+      /* We always write to the user/dest buffer from low addr to high addr
+       * but the read order depends on renderbuffer orientation
+       */
       if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
+         /* read source rows from bottom to top */
          y = height - 1;
          dy = -1;
       }
       else {
+         /* read source rows from top to bottom */
          y = 0;
          dy = 1;
       }
@@ -347,13 +353,15 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
    /* XXX convolution not done yet */
    assert((transferOps & IMAGE_CONVOLUTION_BIT) == 0);
 
+   st_validate_state(ctx->st);
+
    /* 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 transfer is totally outside the window bounds */
       return;
    }
 
-   dest = _mesa_map_readpix_pbo(ctx, &clippedPacking, dest);
+   dest = _mesa_map_pbo_dest(ctx, &clippedPacking, dest);
    if (!dest)
       return;
 
@@ -380,7 +388,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
    if (st_fast_readpixels(ctx, strb, x, y, width, height,
                           format, type, pack, dest)) {
       /* success! */
-      _mesa_unmap_readpix_pbo(ctx, &clippedPacking);
+      _mesa_unmap_pbo_dest(ctx, &clippedPacking);
       return;
    }
 
@@ -397,6 +405,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
    }
 
    if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
+      /* convert GL Y to Gallium Y */
       y = strb->Base.Height - y - height;
    }
 
@@ -416,6 +425,9 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
       yStep = 1;
    }
 
+   if (ST_DEBUG & DEBUG_FALLBACK)
+      debug_printf("%s: fallback processing\n", __FUNCTION__);
+
    /*
     * Copy pixels from pipe_transfer to user memory
     */
@@ -427,8 +439,8 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
       const GLint dstStride = _mesa_image_row_stride(&clippedPacking, width,
                                                      format, type);
 
-      if (trans->format == PIPE_FORMAT_S8Z24_UNORM ||
-          trans->format == PIPE_FORMAT_X8Z24_UNORM) {
+      if (trans->texture->format == PIPE_FORMAT_Z24S8_UNORM ||
+          trans->texture->format == PIPE_FORMAT_Z24X8_UNORM) {
          if (format == GL_DEPTH_COMPONENT) {
             for (i = 0; i < height; i++) {
                GLuint ztemp[MAX_WIDTH];
@@ -459,8 +471,8 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
             }
          }
       }
-      else if (trans->format == PIPE_FORMAT_Z24S8_UNORM ||
-               trans->format == PIPE_FORMAT_Z24X8_UNORM) {
+      else if (trans->texture->format == PIPE_FORMAT_S8Z24_UNORM ||
+               trans->texture->format == PIPE_FORMAT_X8Z24_UNORM) {
          if (format == GL_DEPTH_COMPONENT) {
             for (i = 0; i < height; i++) {
                GLuint ztemp[MAX_WIDTH];
@@ -486,7 +498,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
             }
          }
       }
-      else if (trans->format == PIPE_FORMAT_Z16_UNORM) {
+      else if (trans->texture->format == PIPE_FORMAT_Z16_UNORM) {
          for (i = 0; i < height; i++) {
             GLushort ztemp[MAX_WIDTH];
             GLfloat zfloat[MAX_WIDTH];
@@ -501,7 +513,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
             dst += dstStride;
          }
       }
-      else if (trans->format == PIPE_FORMAT_Z32_UNORM) {
+      else if (trans->texture->format == PIPE_FORMAT_Z32_UNORM) {
          for (i = 0; i < height; i++) {
             GLuint ztemp[MAX_WIDTH];
             GLfloat zfloat[MAX_WIDTH];
@@ -534,7 +546,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
 
    screen->tex_transfer_destroy(trans);
 
-   _mesa_unmap_readpix_pbo(ctx, &clippedPacking);
+   _mesa_unmap_pbo_dest(ctx, &clippedPacking);
 }