Softpipe currently does not saturate colors after add/subtract
blending. This violates the OpenGL specification leading to incorrect
rendering in some cases.
This patch fixes this in the obvious way.

Note that saturation should also happen after the fragment shader, but
I haven't checked whether softpipe does that correctly.

diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c
b/src/gallium/drivers/softpipe/sp_quad_blend.c
index e134e44..5a46a5b 100644
--- a/src/gallium/drivers/softpipe/sp_quad_blend.c
+++ b/src/gallium/drivers/softpipe/sp_quad_blend.c
@@ -72,6 +72,22 @@ do { \
    R[3] = A[3] - B[3]; \
 } while (0)

+#define VEC4_ADD_SAT(R, A, B) \
+do { \
+   R[0] = A[0] + B[0]; if(R[0] > 1.0f) R[0] = 1.0f; \
+   R[1] = A[1] + B[1]; if(R[1] > 1.0f) R[1] = 1.0f; \
+   R[2] = A[2] + B[2]; if(R[2] > 1.0f) R[2] = 1.0f; \
+   R[3] = A[3] + B[3]; if(R[3] > 1.0f) R[3] = 1.0f; \
+} while (0)
+
+#define VEC4_SUB_SAT(R, A, B) \
+do { \
+   R[0] = A[0] - B[0]; if(R[0] < 0.0f) R[0] = 0.0f; \
+   R[1] = A[1] - B[1]; if(R[1] < 0.0f) R[1] = 0.0f;\
+   R[2] = A[2] - B[2]; if(R[2] < 0.0f) R[2] = 0.0f; \
+   R[3] = A[3] - B[3]; if(R[3] < 0.0f) R[3] = 0.0f; \
+} while (0)
+
 #define VEC4_MUL(R, A, B) \
 do { \
    R[0] = A[0] * B[0]; \
@@ -676,19 +692,19 @@ blend_quad(struct quad_stage *qs, struct
quad_header *quad)
        */
       switch (softpipe->blend->rgb_func) {
       case PIPE_BLEND_ADD:
-         VEC4_ADD(quadColor[0], source[0], dest[0]); /* R */
-         VEC4_ADD(quadColor[1], source[1], dest[1]); /* G */
-         VEC4_ADD(quadColor[2], source[2], dest[2]); /* B */
+         VEC4_ADD_SAT(quadColor[0], source[0], dest[0]); /* R */
+         VEC4_ADD_SAT(quadColor[1], source[1], dest[1]); /* G */
+         VEC4_ADD_SAT(quadColor[2], source[2], dest[2]); /* B */
          break;
       case PIPE_BLEND_SUBTRACT:
-         VEC4_SUB(quadColor[0], source[0], dest[0]); /* R */
-         VEC4_SUB(quadColor[1], source[1], dest[1]); /* G */
-         VEC4_SUB(quadColor[2], source[2], dest[2]); /* B */
+         VEC4_SUB_SAT(quadColor[0], source[0], dest[0]); /* R */
+         VEC4_SUB_SAT(quadColor[1], source[1], dest[1]); /* G */
+         VEC4_SUB_SAT(quadColor[2], source[2], dest[2]); /* B */
          break;
       case PIPE_BLEND_REVERSE_SUBTRACT:
-         VEC4_SUB(quadColor[0], dest[0], source[0]); /* R */
-         VEC4_SUB(quadColor[1], dest[1], source[1]); /* G */
-         VEC4_SUB(quadColor[2], dest[2], source[2]); /* B */
+         VEC4_SUB_SAT(quadColor[0], dest[0], source[0]); /* R */
+         VEC4_SUB_SAT(quadColor[1], dest[1], source[1]); /* G */
+         VEC4_SUB_SAT(quadColor[2], dest[2], source[2]); /* B */
          break;
       case PIPE_BLEND_MIN:
          VEC4_MIN(quadColor[0], source[0], dest[0]); /* R */
@@ -709,13 +725,13 @@ blend_quad(struct quad_stage *qs, struct
quad_header *quad)
        */
       switch (softpipe->blend->alpha_func) {
       case PIPE_BLEND_ADD:
-         VEC4_ADD(quadColor[3], source[3], dest[3]); /* A */
+         VEC4_ADD_SAT(quadColor[3], source[3], dest[3]); /* A */
          break;
       case PIPE_BLEND_SUBTRACT:
-         VEC4_SUB(quadColor[3], source[3], dest[3]); /* A */
+         VEC4_SUB_SAT(quadColor[3], source[3], dest[3]); /* A */
          break;
       case PIPE_BLEND_REVERSE_SUBTRACT:
-         VEC4_SUB(quadColor[3], dest[3], source[3]); /* A */
+         VEC4_SUB_SAT(quadColor[3], dest[3], source[3]); /* A */
          break;
       case PIPE_BLEND_MIN:
          VEC4_MIN(quadColor[3], source[3], dest[3]); /* A */

------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge  
This is your chance to win up to $100,000 in prizes! For a limited time, 
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize  
details at: http://p.sf.net/sfu/Challenge
_______________________________________________
Mesa3d-dev mailing list
Mesa3d-dev@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev

Reply via email to