[Mesa-dev] [PATCH] mesa/readpix: clamp SNORM properly (v2)

Dave Airlie airlied at gmail.com
Sun Jun 5 19:40:47 UTC 2016


From: Dave Airlie <airlied at redhat.com>

The clamping code always clamps to 0..1, which for SNORM is
incorrect. This adds a bit to say that clamping is for
an snorm and to use the correct range.

This fixes a number of SNORM cases in:
GL33-CTS.texture_size_promotion.functional

v2: handle the case where the format is an array format.
don't test for snorm in readpixels, readpixels always does
[0..1] according to spec.

Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 src/mesa/main/pack.c          |  4 +++-
 src/mesa/main/pixeltransfer.c | 10 ++++++----
 src/mesa/main/pixeltransfer.h |  1 +
 src/mesa/main/readpix.c       |  4 +++-
 src/mesa/main/texgetimage.c   |  4 +++-
 src/mesa/main/texstore.c      | 10 +++++++++-
 src/mesa/swrast/s_copypix.c   |  4 +++-
 src/mesa/swrast/s_drawpix.c   |  2 +-
 8 files changed, 29 insertions(+), 10 deletions(-)

diff --git a/src/mesa/main/pack.c b/src/mesa/main/pack.c
index 89faf51..f810929 100644
--- a/src/mesa/main/pack.c
+++ b/src/mesa/main/pack.c
@@ -1607,7 +1607,9 @@ _mesa_unpack_color_index_to_rgba_float(struct gl_context *ctx, GLuint dims,
        * with color indexes.
        */
       transferOps &= ~(IMAGE_SCALE_BIAS_BIT | IMAGE_MAP_COLOR_BIT);
-      _mesa_apply_rgba_transfer_ops(ctx, transferOps, count, (float (*)[4])dstPtr);
+      _mesa_apply_rgba_transfer_ops(ctx, transferOps,
+                                    false,
+                                    count, (float (*)[4])dstPtr);
 
       dstPtr += srcHeight * srcWidth * 4;
    }
diff --git a/src/mesa/main/pixeltransfer.c b/src/mesa/main/pixeltransfer.c
index 22eac00..93ab8ad 100644
--- a/src/mesa/main/pixeltransfer.c
+++ b/src/mesa/main/pixeltransfer.c
@@ -162,6 +162,7 @@ _mesa_scale_and_bias_depth_uint(const struct gl_context *ctx, GLuint n,
  */
 void
 _mesa_apply_rgba_transfer_ops(struct gl_context *ctx, GLbitfield transferOps,
+                              bool clamp_snorm,
                               GLuint n, GLfloat rgba[][4])
 {
    /* scale & bias */
@@ -180,11 +181,12 @@ _mesa_apply_rgba_transfer_ops(struct gl_context *ctx, GLbitfield transferOps,
    /* clamping to [0,1] */
    if (transferOps & IMAGE_CLAMP_BIT) {
       GLuint i;
+      GLfloat lower_val = clamp_snorm ? -1.0F : 0.0F;
       for (i = 0; i < n; i++) {
-         rgba[i][RCOMP] = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F);
-         rgba[i][GCOMP] = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F);
-         rgba[i][BCOMP] = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F);
-         rgba[i][ACOMP] = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F);
+         rgba[i][RCOMP] = CLAMP(rgba[i][RCOMP], lower_val, 1.0F);
+         rgba[i][GCOMP] = CLAMP(rgba[i][GCOMP], lower_val, 1.0F);
+         rgba[i][BCOMP] = CLAMP(rgba[i][BCOMP], lower_val, 1.0F);
+         rgba[i][ACOMP] = CLAMP(rgba[i][ACOMP], lower_val, 1.0F);
       }
    }
 }
diff --git a/src/mesa/main/pixeltransfer.h b/src/mesa/main/pixeltransfer.h
index b0a301f..e67ab53 100644
--- a/src/mesa/main/pixeltransfer.h
+++ b/src/mesa/main/pixeltransfer.h
@@ -56,6 +56,7 @@ _mesa_scale_and_bias_depth_uint(const struct gl_context *ctx, GLuint n,
 
 extern void
 _mesa_apply_rgba_transfer_ops(struct gl_context *ctx, GLbitfield transferOps,
+                              bool clamp_snorm,
                               GLuint n, GLfloat rgba[][4]);
 
 extern void
diff --git a/src/mesa/main/readpix.c b/src/mesa/main/readpix.c
index 1cb06c7..9c17a10 100644
--- a/src/mesa/main/readpix.c
+++ b/src/mesa/main/readpix.c
@@ -544,7 +544,9 @@ read_rgba_pixels( struct gl_context *ctx,
 
       /* Handle transfer ops if necessary */
       if (transferOps)
-         _mesa_apply_rgba_transfer_ops(ctx, transferOps, width * height, rgba);
+         _mesa_apply_rgba_transfer_ops(ctx, transferOps,
+                                       false,
+                                       width * height, rgba);
 
       /* If we had to rebase, we have already taken care of that */
       needs_rebase = false;
diff --git a/src/mesa/main/texgetimage.c b/src/mesa/main/texgetimage.c
index fc3cc6b..c501f9e 100644
--- a/src/mesa/main/texgetimage.c
+++ b/src/mesa/main/texgetimage.c
@@ -518,7 +518,9 @@ get_tex_rgba_uncompressed(struct gl_context *ctx, GLuint dimensions,
                               needsRebase ? rebaseSwizzle : NULL);
 
          /* Handle transfer ops now */
-         _mesa_apply_rgba_transfer_ops(ctx, transferOps, width * height, rgba);
+         _mesa_apply_rgba_transfer_ops(ctx, transferOps,
+                                       _mesa_get_format_datatype(texFormat) == GL_SIGNED_NORMALIZED,
+                                       width * height, rgba);
 
          /* If we had to rebase, we have already handled that */
          needsRebase = false;
diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c
index b54e033..bed416a 100644
--- a/src/mesa/main/texstore.c
+++ b/src/mesa/main/texstore.c
@@ -760,6 +760,7 @@ texstore_rgba(TEXSTORE_PARAMS)
        _mesa_texstore_needs_transfer_ops(ctx, baseInternalFormat, dstFormat)) {
       /* Allocate RGBA float image */
       int elementCount = srcWidth * srcHeight * srcDepth;
+      bool is_snorm;
       tempRGBA = malloc(4 * elementCount * sizeof(float));
       if (!tempRGBA) {
          free(tempImage);
@@ -778,8 +779,15 @@ texstore_rgba(TEXSTORE_PARAMS)
          dst += srcHeight * 4 * srcWidth * sizeof(float);
       }
 
+      if (_mesa_format_is_mesa_array_format(srcMesaFormat)) {
+         is_snorm = _mesa_array_format_is_normalized(srcMesaFormat) &&
+            _mesa_array_format_is_signed(srcMesaFormat);
+      } else
+         is_snorm = _mesa_get_format_datatype(srcMesaFormat) == GL_SIGNED_NORMALIZED;
       /* Apply transferOps */
-      _mesa_apply_rgba_transfer_ops(ctx, ctx->_ImageTransferState, elementCount,
+      _mesa_apply_rgba_transfer_ops(ctx, ctx->_ImageTransferState,
+                                    is_snorm,
+                                    elementCount,
                                     (float(*)[4]) tempRGBA);
 
       /* Now we have to adjust our src info for a conversion from
diff --git a/src/mesa/swrast/s_copypix.c b/src/mesa/swrast/s_copypix.c
index 0dbccc0..c3cf7a3 100644
--- a/src/mesa/swrast/s_copypix.c
+++ b/src/mesa/swrast/s_copypix.c
@@ -165,7 +165,9 @@ copy_rgba_pixels(struct gl_context *ctx, GLint srcx, GLint srcy,
       }
 
       if (transferOps) {
-         _mesa_apply_rgba_transfer_ops(ctx, transferOps, width,
+         _mesa_apply_rgba_transfer_ops(ctx, transferOps,
+                                       false,
+                                       width,
                                        (GLfloat (*)[4]) rgba);
       }
 
diff --git a/src/mesa/swrast/s_drawpix.c b/src/mesa/swrast/s_drawpix.c
index f05528d..78d9771 100644
--- a/src/mesa/swrast/s_drawpix.c
+++ b/src/mesa/swrast/s_drawpix.c
@@ -516,7 +516,7 @@ draw_rgba_pixels( struct gl_context *ctx, GLint x, GLint y,
                                  (void*)source, srcMesaFormat, srcStride,
                                  spanWidth, 1, NULL);
             if (transferOps)
-               _mesa_apply_rgba_transfer_ops(ctx, transferOps, spanWidth, (GLfloat (*)[4])rgba);
+               _mesa_apply_rgba_transfer_ops(ctx, transferOps, false, spanWidth, (GLfloat (*)[4])rgba);
 	    /* Set these for each row since the _swrast_write_* functions
 	     * may change them while clipping/rendering.
 	     */
-- 
2.5.5



More information about the mesa-dev mailing list