st/mesa: Set samplers views' first_level.
[mesa.git] / src / mesa / state_tracker / st_cb_readpixels.c
index 0507be745783be12d689ce7c19eabe5d01876a63..03f58bf0fc4ae3626e39b782c24c94f5446cef05 100644 (file)
 #include "main/context.h"
 #include "main/image.h"
 #include "main/pack.h"
+#include "main/pbo.h"
 
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
+#include "util/u_format.h"
 #include "util/u_inlines.h"
 #include "util/u_tile.h"
 
@@ -329,13 +331,14 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h
    struct st_context *st = st_context(ctx);
    struct pipe_context *pipe = st->pipe;
    GLfloat (*temp)[4];
-   const GLbitfield transferOps = ctx->_ImageTransferState;
+   GLbitfield transferOps = ctx->_ImageTransferState;
    GLsizei i, j;
    GLint yStep, dfStride;
    GLfloat *df;
    struct st_renderbuffer *strb;
    struct gl_pixelstore_attrib clippedPacking = *pack;
    struct pipe_transfer *trans;
+   enum pipe_format pformat;
 
    assert(ctx->ReadBuffer->Width > 0);
 
@@ -388,7 +391,10 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h
       return;
    }
 
-   if (format == GL_RGBA && type == GL_FLOAT) {
+   if(ctx->Color._ClampReadColor)
+      transferOps |= IMAGE_CLAMP_BIT;
+
+   if (format == GL_RGBA && type == GL_FLOAT && !transferOps) {
       /* write tile(row) directly into user's buffer */
       df = (GLfloat *) _mesa_image_address2d(&clippedPacking, dest, width,
                                              height, format, type, 0, 0);
@@ -421,6 +427,9 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h
       yStep = 1;
    }
 
+   /* possibly convert sRGB format to linear RGB format */
+   pformat = util_format_linear(trans->resource->format);
+
    if (ST_DEBUG & DEBUG_FALLBACK)
       debug_printf("%s: fallback processing\n", __FUNCTION__);
 
@@ -435,8 +444,8 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h
       const GLint dstStride = _mesa_image_row_stride(&clippedPacking, width,
                                                      format, type);
 
-      if (trans->resource->format == PIPE_FORMAT_Z24_UNORM_S8_USCALED ||
-          trans->resource->format == PIPE_FORMAT_Z24X8_UNORM) {
+      if (pformat == PIPE_FORMAT_Z24_UNORM_S8_USCALED ||
+          pformat == PIPE_FORMAT_Z24X8_UNORM) {
          if (format == GL_DEPTH_COMPONENT) {
             for (i = 0; i < height; i++) {
                GLuint ztemp[MAX_WIDTH];
@@ -467,8 +476,8 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h
             }
          }
       }
-      else if (trans->resource->format == PIPE_FORMAT_S8_USCALED_Z24_UNORM ||
-               trans->resource->format == PIPE_FORMAT_X8Z24_UNORM) {
+      else if (pformat == PIPE_FORMAT_S8_USCALED_Z24_UNORM ||
+               pformat == PIPE_FORMAT_X8Z24_UNORM) {
          if (format == GL_DEPTH_COMPONENT) {
             for (i = 0; i < height; i++) {
                GLuint ztemp[MAX_WIDTH];
@@ -494,7 +503,7 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h
             }
          }
       }
-      else if (trans->resource->format == PIPE_FORMAT_Z16_UNORM) {
+      else if (pformat == PIPE_FORMAT_Z16_UNORM) {
          for (i = 0; i < height; i++) {
             GLushort ztemp[MAX_WIDTH];
             GLfloat zfloat[MAX_WIDTH];
@@ -509,7 +518,7 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h
             dst += dstStride;
          }
       }
-      else if (trans->resource->format == PIPE_FORMAT_Z32_UNORM) {
+      else if (pformat == PIPE_FORMAT_Z32_UNORM) {
          for (i = 0; i < height; i++) {
             GLuint ztemp[MAX_WIDTH];
             GLfloat zfloat[MAX_WIDTH];
@@ -528,7 +537,8 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h
          /* RGBA format */
          /* Do a row at a time to flip image data vertically */
          for (i = 0; i < height; i++) {
-            pipe_get_tile_rgba(pipe, trans, 0, y, width, 1, df);
+            pipe_get_tile_rgba_format(pipe, trans, 0, y, width, 1,
+                                      pformat, df);
             y += yStep;
             df += dfStride;
             if (!dfStride) {