aboutsummaryrefslogtreecommitdiffstats
path: root/src/mesa/swrast/s_blend.c
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2006-09-25 23:57:39 +0000
committerBrian Paul <[email protected]>2006-09-25 23:57:39 +0000
commita50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4 (patch)
treeb1e19031a7563c7da67386584a7e42a4603c4ba1 /src/mesa/swrast/s_blend.c
parentdf8632ebd87219c809810d993f56fef1e6853a25 (diff)
Initial work for supporting different renderbuffer color depths at runtime.
Diffstat (limited to 'src/mesa/swrast/s_blend.c')
-rw-r--r--src/mesa/swrast/s_blend.c708
1 files changed, 566 insertions, 142 deletions
diff --git a/src/mesa/swrast/s_blend.c b/src/mesa/swrast/s_blend.c
index 91ec513d5bc..4e6c3d909f4 100644
--- a/src/mesa/swrast/s_blend.c
+++ b/src/mesa/swrast/s_blend.c
@@ -51,18 +51,18 @@
#endif
-/*
+/**
* Special case for glBlendFunc(GL_ZERO, GL_ONE)
*/
static void _BLENDAPI
-blend_noop( GLcontext *ctx, GLuint n, const GLubyte mask[],
- GLchan rgba[][4], CONST GLchan dest[][4] )
+blend_noop_ubyte(GLcontext *ctx, GLuint n, const GLubyte mask[],
+ GLchan rgba[][4], CONST GLchan dest[][4], GLenum chanType)
{
GLuint i;
- ASSERT(ctx->Color.BlendEquationRGB==GL_FUNC_ADD);
- ASSERT(ctx->Color.BlendEquationA==GL_FUNC_ADD);
- ASSERT(ctx->Color.BlendSrcRGB==GL_ZERO);
- ASSERT(ctx->Color.BlendDstRGB==GL_ONE);
+ ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD);
+ ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD);
+ ASSERT(ctx->Color.BlendSrcRGB == GL_ZERO);
+ ASSERT(ctx->Color.BlendDstRGB == GL_ONE);
(void) ctx;
for (i = 0; i < n; i++) {
@@ -73,17 +73,17 @@ blend_noop( GLcontext *ctx, GLuint n, const GLubyte mask[],
}
-/*
+/**
* Special case for glBlendFunc(GL_ONE, GL_ZERO)
*/
static void _BLENDAPI
-blend_replace( GLcontext *ctx, GLuint n, const GLubyte mask[],
- GLchan rgba[][4], CONST GLchan dest[][4] )
+blend_replace(GLcontext *ctx, GLuint n, const GLubyte mask[],
+ GLchan rgba[][4], CONST GLchan dest[][4], GLenum chanType)
{
- ASSERT(ctx->Color.BlendEquationRGB==GL_FUNC_ADD);
- ASSERT(ctx->Color.BlendEquationA==GL_FUNC_ADD);
- ASSERT(ctx->Color.BlendSrcRGB==GL_ONE);
- ASSERT(ctx->Color.BlendDstRGB==GL_ZERO);
+ ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD);
+ ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD);
+ ASSERT(ctx->Color.BlendSrcRGB == GL_ONE);
+ ASSERT(ctx->Color.BlendDstRGB == GL_ZERO);
(void) ctx;
(void) n;
(void) mask;
@@ -92,18 +92,21 @@ blend_replace( GLcontext *ctx, GLuint n, const GLubyte mask[],
}
-/*
+/**
* Common transparency blending mode.
*/
static void _BLENDAPI
-blend_transparency( GLcontext *ctx, GLuint n, const GLubyte mask[],
- GLchan rgba[][4], CONST GLchan dest[][4] )
+blend_transparency_ubyte(GLcontext *ctx, GLuint n, const GLubyte mask[],
+ GLchan rgba[][4], CONST GLchan dest[][4],
+ GLenum chanType)
{
GLuint i;
- ASSERT(ctx->Color.BlendEquationRGB==GL_FUNC_ADD);
- ASSERT(ctx->Color.BlendEquationA==GL_FUNC_ADD);
- ASSERT(ctx->Color.BlendSrcRGB==GL_SRC_ALPHA);
- ASSERT(ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA);
+ ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD);
+ ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD);
+ ASSERT(ctx->Color.BlendSrcRGB == GL_SRC_ALPHA);
+ ASSERT(ctx->Color.BlendSrcA == GL_SRC_ALPHA);
+ ASSERT(ctx->Color.BlendDstRGB == GL_ONE_MINUS_SRC_ALPHA);
+ ASSERT(ctx->Color.BlendDstA == GL_ONE_MINUS_SRC_ALPHA);
(void) ctx;
for (i=0;i<n;i++) {
@@ -180,18 +183,18 @@ blend_transparency( GLcontext *ctx, GLuint n, const GLubyte mask[],
-/*
+/**
* Add src and dest.
*/
static void _BLENDAPI
-blend_add( GLcontext *ctx, GLuint n, const GLubyte mask[],
- GLchan rgba[][4], CONST GLchan dest[][4] )
+blend_add_ubyte(GLcontext *ctx, GLuint n, const GLubyte mask[],
+ GLchan rgba[][4], CONST GLchan dest[][4], GLenum chanType)
{
GLuint i;
- ASSERT(ctx->Color.BlendEquationRGB==GL_FUNC_ADD);
- ASSERT(ctx->Color.BlendEquationA==GL_FUNC_ADD);
- ASSERT(ctx->Color.BlendSrcRGB==GL_ONE);
- ASSERT(ctx->Color.BlendDstRGB==GL_ONE);
+ ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD);
+ ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD);
+ ASSERT(ctx->Color.BlendSrcRGB == GL_ONE);
+ ASSERT(ctx->Color.BlendDstRGB == GL_ONE);
(void) ctx;
for (i=0;i<n;i++) {
@@ -219,16 +222,16 @@ blend_add( GLcontext *ctx, GLuint n, const GLubyte mask[],
-/*
+/**
* Blend min function (for GL_EXT_blend_minmax)
*/
static void _BLENDAPI
-blend_min( GLcontext *ctx, GLuint n, const GLubyte mask[],
- GLchan rgba[][4], CONST GLchan dest[][4] )
+blend_min_ubyte(GLcontext *ctx, GLuint n, const GLubyte mask[],
+ GLchan rgba[][4], CONST GLchan dest[][4], GLenum chanType)
{
GLuint i;
- ASSERT(ctx->Color.BlendEquationRGB==GL_MIN);
- ASSERT(ctx->Color.BlendEquationA==GL_MIN);
+ ASSERT(ctx->Color.BlendEquationRGB == GL_MIN);
+ ASSERT(ctx->Color.BlendEquationA == GL_MIN);
(void) ctx;
for (i=0;i<n;i++) {
@@ -248,16 +251,16 @@ blend_min( GLcontext *ctx, GLuint n, const GLubyte mask[],
-/*
+/**
* Blend max function (for GL_EXT_blend_minmax)
*/
static void _BLENDAPI
-blend_max( GLcontext *ctx, GLuint n, const GLubyte mask[],
- GLchan rgba[][4], CONST GLchan dest[][4] )
+blend_max_ubyte(GLcontext *ctx, GLuint n, const GLubyte mask[],
+ GLchan rgba[][4], CONST GLchan dest[][4], GLenum chanType)
{
GLuint i;
- ASSERT(ctx->Color.BlendEquationRGB==GL_MAX);
- ASSERT(ctx->Color.BlendEquationA==GL_MAX);
+ ASSERT(ctx->Color.BlendEquationRGB == GL_MAX);
+ ASSERT(ctx->Color.BlendEquationA == GL_MAX);
(void) ctx;
for (i=0;i<n;i++) {
@@ -277,12 +280,12 @@ blend_max( GLcontext *ctx, GLuint n, const GLubyte mask[],
-/*
+/**
* Modulate: result = src * dest
*/
static void _BLENDAPI
-blend_modulate( GLcontext *ctx, GLuint n, const GLubyte mask[],
- GLchan rgba[][4], CONST GLchan dest[][4] )
+blend_modulate_ubyte(GLcontext *ctx, GLuint n, const GLubyte mask[],
+ GLchan rgba[][4], CONST GLchan dest[][4], GLenum chanType)
{
GLuint i;
(void) ctx;
@@ -318,17 +321,435 @@ blend_modulate( GLcontext *ctx, GLuint n, const GLubyte mask[],
}
-
-/*
- * General case blend pixels.
- * Input: n - number of pixels
- * mask - the usual write mask
- * In/Out: rgba - the incoming and modified pixels
- * Input: dest - the pixels from the dest color buffer
+#if 0
+/**
+ * Do any blending operation, using floating point.
+ * \param n number of pixels
+ * \param mask fragment writemask array
+ * \param src array of incoming (and modified) pixels
+ * \param dst array of pixels from the dest color buffer
*/
+static void
+blend_general_float(GLcontext *ctx, GLuint n, const GLubyte mask[],
+ GLvoid *src, const GLvoid *dst, GLenum chanType)
+{
+ GLfloat (*rgba)[4] = (GLfloat (*)[4]) src;
+ const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst;
+ GLuint i;
+
+ for (i = 0; i < n; i++) {
+ if (mask[i]) {
+ /* Incoming/source Color */
+ const GLfloat Rs = rgba[i][RCOMP];
+ const GLfloat Gs = rgba[i][GCOMP];
+ const GLfloat Bs = rgba[i][BCOMP];
+ const GLfloat As = rgba[i][ACOMP];
+
+ /* Frame buffer/dest color */
+ const GLfloat Rd = dest[i][RCOMP];
+ const GLfloat Gd = dest[i][GCOMP];
+ const GLfloat Bd = dest[i][BCOMP];
+ const GLfloat Ad = dest[i][ACOMP];
+
+ GLfloat sR, sG, sB, sA; /* Source factor */
+ GLfloat dR, dG, dB, dA; /* Dest factor */
+ GLfloat r, g, b, a; /* result color */
+
+ /* XXX for the case of constant blend terms we could init
+ * the sX and dX variables just once before the loop.
+ */
+
+ /* Source RGB factor */
+ switch (ctx->Color.BlendSrcRGB) {
+ case GL_ZERO:
+ sR = sG = sB = 0.0F;
+ break;
+ case GL_ONE:
+ sR = sG = sB = 1.0F;
+ break;
+ case GL_DST_COLOR:
+ sR = Rd;
+ sG = Gd;
+ sB = Bd;
+ break;
+ case GL_ONE_MINUS_DST_COLOR:
+ sR = 1.0F - Rd;
+ sG = 1.0F - Gd;
+ sB = 1.0F - Bd;
+ break;
+ case GL_SRC_ALPHA:
+ sR = sG = sB = As;
+ break;
+ case GL_ONE_MINUS_SRC_ALPHA:
+ sR = sG = sB = 1.0F - As;
+ break;
+ case GL_DST_ALPHA:
+ sR = sG = sB = Ad;
+ break;
+ case GL_ONE_MINUS_DST_ALPHA:
+ sR = sG = sB = 1.0F - Ad;
+ break;
+ case GL_SRC_ALPHA_SATURATE:
+ if (As < 1.0F - Ad) {
+ sR = sG = sB = As;
+ }
+ else {
+ sR = sG = sB = 1.0F - Ad;
+ }
+ break;
+ case GL_CONSTANT_COLOR:
+ sR = ctx->Color.BlendColor[0];
+ sG = ctx->Color.BlendColor[1];
+ sB = ctx->Color.BlendColor[2];
+ break;
+ case GL_ONE_MINUS_CONSTANT_COLOR:
+ sR = 1.0F - ctx->Color.BlendColor[0];
+ sG = 1.0F - ctx->Color.BlendColor[1];
+ sB = 1.0F - ctx->Color.BlendColor[2];
+ break;
+ case GL_CONSTANT_ALPHA:
+ sR = sG = sB = ctx->Color.BlendColor[3];
+ break;
+ case GL_ONE_MINUS_CONSTANT_ALPHA:
+ sR = sG = sB = 1.0F - ctx->Color.BlendColor[3];
+ break;
+ case GL_SRC_COLOR: /* GL_NV_blend_square */
+ sR = Rs;
+ sG = Gs;
+ sB = Bs;
+ break;
+ case GL_ONE_MINUS_SRC_COLOR: /* GL_NV_blend_square */
+ sR = 1.0F - Rs;
+ sG = 1.0F - Gs;
+ sB = 1.0F - Bs;
+ break;
+ default:
+ /* this should never happen */
+ _mesa_problem(ctx, "Bad blend source RGB factor in blend_general_float");
+ return;
+ }
+
+ /* Source Alpha factor */
+ switch (ctx->Color.BlendSrcA) {
+ case GL_ZERO:
+ sA = 0.0F;
+ break;
+ case GL_ONE:
+ sA = 1.0F;
+ break;
+ case GL_DST_COLOR:
+ sA = Ad;
+ break;
+ case GL_ONE_MINUS_DST_COLOR:
+ sA = 1.0F - Ad;
+ break;
+ case GL_SRC_ALPHA:
+ sA = As;
+ break;
+ case GL_ONE_MINUS_SRC_ALPHA:
+ sA = 1.0F - As;
+ break;
+ case GL_DST_ALPHA:
+ sA = Ad;
+ break;
+ case GL_ONE_MINUS_DST_ALPHA:
+ sA = 1.0F - Ad;
+ break;
+ case GL_SRC_ALPHA_SATURATE:
+ sA = 1.0;
+ break;
+ case GL_CONSTANT_COLOR:
+ sA = ctx->Color.BlendColor[3];
+ break;
+ case GL_ONE_MINUS_CONSTANT_COLOR:
+ sA = 1.0F - ctx->Color.BlendColor[3];
+ break;
+ case GL_CONSTANT_ALPHA:
+ sA = ctx->Color.BlendColor[3];
+ break;
+ case GL_ONE_MINUS_CONSTANT_ALPHA:
+ sA = 1.0F - ctx->Color.BlendColor[3];
+ break;
+ case GL_SRC_COLOR: /* GL_NV_blend_square */
+ sA = As;
+ break;
+ case GL_ONE_MINUS_SRC_COLOR: /* GL_NV_blend_square */
+ sA = 1.0F - As;
+ break;
+ default:
+ /* this should never happen */
+ sA = 0.0F;
+ _mesa_problem(ctx, "Bad blend source A factor in blend_general_float");
+ return;
+ }
+
+ /* Dest RGB factor */
+ switch (ctx->Color.BlendDstRGB) {
+ case GL_ZERO:
+ dR = dG = dB = 0.0F;
+ break;
+ case GL_ONE:
+ dR = dG = dB = 1.0F;
+ break;
+ case GL_SRC_COLOR:
+ dR = Rs;
+ dG = Gs;
+ dB = Bs;
+ break;
+ case GL_ONE_MINUS_SRC_COLOR:
+ dR = 1.0F - Rs;
+ dG = 1.0F - Gs;
+ dB = 1.0F - Bs;
+ break;
+ case GL_SRC_ALPHA:
+ dR = dG = dB = As;
+ break;
+ case GL_ONE_MINUS_SRC_ALPHA:
+ dR = dG = dB = 1.0F - As;
+ break;
+ case GL_DST_ALPHA:
+ dR = dG = dB = Ad;
+ break;
+ case GL_ONE_MINUS_DST_ALPHA:
+ dR = dG = dB = 1.0F - Ad;
+ break;
+ case GL_CONSTANT_COLOR:
+ dR = ctx->Color.BlendColor[0];
+ dG = ctx->Color.BlendColor[1];
+ dB = ctx->Color.BlendColor[2];
+ break;
+ case GL_ONE_MINUS_CONSTANT_COLOR:
+ dR = 1.0F - ctx->Color.BlendColor[0];
+ dG = 1.0F - ctx->Color.BlendColor[1];
+ dB = 1.0F - ctx->Color.BlendColor[2];
+ break;
+ case GL_CONSTANT_ALPHA:
+ dR = dG = dB = ctx->Color.BlendColor[3];
+ break;
+ case GL_ONE_MINUS_CONSTANT_ALPHA:
+ dR = dG = dB = 1.0F - ctx->Color.BlendColor[3];
+ break;
+ case GL_DST_COLOR: /* GL_NV_blend_square */
+ dR = Rd;
+ dG = Gd;
+ dB = Bd;
+ break;
+ case GL_ONE_MINUS_DST_COLOR: /* GL_NV_blend_square */
+ dR = 1.0F - Rd;
+ dG = 1.0F - Gd;
+ dB = 1.0F - Bd;
+ break;
+ default:
+ /* this should never happen */
+ dR = dG = dB = 0.0F;
+ _mesa_problem(ctx, "Bad blend dest RGB factor in blend_general_float");
+ return;
+ }
+
+ /* Dest Alpha factor */
+ switch (ctx->Color.BlendDstA) {
+ case GL_ZERO:
+ dA = 0.0F;
+ break;
+ case GL_ONE:
+ dA = 1.0F;
+ break;
+ case GL_SRC_COLOR:
+ dA = As;
+ break;
+ case GL_ONE_MINUS_SRC_COLOR:
+ dA = 1.0F - As;
+ break;
+ case GL_SRC_ALPHA:
+ dA = As;
+ break;
+ case GL_ONE_MINUS_SRC_ALPHA:
+ dA = 1.0F - As;
+ break;
+ case GL_DST_ALPHA:
+ dA = Ad;
+ break;
+ case GL_ONE_MINUS_DST_ALPHA:
+ dA = 1.0F - Ad;
+ break;
+ case GL_CONSTANT_COLOR:
+ dA = ctx->Color.BlendColor[3];
+ break;
+ case GL_ONE_MINUS_CONSTANT_COLOR:
+ dA = 1.0F - ctx->Color.BlendColor[3];
+ break;
+ case GL_CONSTANT_ALPHA:
+ dA = ctx->Color.BlendColor[3];
+ break;
+ case GL_ONE_MINUS_CONSTANT_ALPHA:
+ dA = 1.0F - ctx->Color.BlendColor[3];
+ break;
+ case GL_DST_COLOR: /* GL_NV_blend_square */
+ dA = Ad;
+ break;
+ case GL_ONE_MINUS_DST_COLOR: /* GL_NV_blend_square */
+ dA = 1.0F - Ad;
+ break;
+ default:
+ /* this should never happen */
+ dA = 0.0F;
+ _mesa_problem(ctx, "Bad blend dest A factor in blend_general_float");
+ return;
+ }
+
+ /* compute the blended RGB */
+ switch (ctx->Color.BlendEquationRGB) {
+ case GL_FUNC_ADD:
+ r = Rs * sR + Rd * dR;
+ g = Gs * sG + Gd * dG;
+ b = Bs * sB + Bd * dB;
+ a = As * sA + Ad * dA;
+ break;
+ case GL_FUNC_SUBTRACT:
+ r = Rs * sR - Rd * dR;
+ g = Gs * sG - Gd * dG;
+ b = Bs * sB - Bd * dB;
+ a = As * sA - Ad * dA;
+ break;
+ case GL_FUNC_REVERSE_SUBTRACT:
+ r = Rd * dR - Rs * sR;
+ g = Gd * dG - Gs * sG;
+ b = Bd * dB - Bs * sB;
+ a = Ad * dA - As * sA;
+ break;
+ case GL_MIN:
+ r = MIN2( Rd, Rs );
+ g = MIN2( Gd, Gs );
+ b = MIN2( Bd, Bs );
+ break;
+ case GL_MAX:
+ r = MAX2( Rd, Rs );
+ g = MAX2( Gd, Gs );
+ b = MAX2( Bd, Bs );
+ break;
+ default:
+ /* should never get here */
+ r = g = b = 0.0F; /* silence uninitialized var warning */
+ _mesa_problem(ctx, "unexpected BlendEquation in blend_general()");
+ return;
+ }
+
+ /* compute the blended alpha */
+ switch (ctx->Color.BlendEquationA) {
+ case GL_FUNC_ADD:
+ a = As * sA + Ad * dA;
+ break;
+ case GL_FUNC_SUBTRACT:
+ a = As * sA - Ad * dA;
+ break;
+ case GL_FUNC_REVERSE_SUBTRACT:
+ a = Ad * dA - As * sA;
+ break;
+ case GL_MIN:
+ a = MIN2( Ad, As );
+ break;
+ case GL_MAX:
+ a = MAX2( Ad, As );
+ break;
+ default:
+ /* should never get here */
+ a = 0.0F; /* silence uninitialized var warning */
+ _mesa_problem(ctx, "unexpected BlendEquation in blend_general()");
+ return;
+ }
+
+ /* final clamping */
+#if 0
+ rgba[i][RCOMP] = MAX2( r, 0.0F );
+ rgba[i][GCOMP] = MAX2( g, 0.0F );
+ rgba[i][BCOMP] = MAX2( b, 0.0F );
+ rgba[i][ACOMP] = CLAMP( a, 0.0F, CHAN_MAXF );
+#else
+ ASSIGN_4V(rgba[i], r, g, b, a);
+#endif
+ }
+ }
+}
+#endif
+
+
+#if 0 /* not ready yet */
+static void
+blend_general2(GLcontext *ctx, GLuint n, const GLubyte mask[],
+ void *src, const void *dst, GLenum chanType)
+{
+ GLfloat rgbaF[MAX_WIDTH][4], destF[MAX_WIDTH][4];
+
+ if (chanType == GL_UNSIGNED_BYTE) {
+ GLubyte (*rgba)[4] = (GLubyte (*)[4]) src;
+ const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst;
+ GLuint i;
+ /* convert ubytes to floats */
+ for (i = 0; i < n; i++) {
+ if (mask[i]) {
+ rgbaF[i][RCOMP] = UBYTE_TO_FLOAT(rgba[i][RCOMP]);
+ rgbaF[i][GCOMP] = UBYTE_TO_FLOAT(rgba[i][GCOMP]);
+ rgbaF[i][BCOMP] = UBYTE_TO_FLOAT(rgba[i][BCOMP]);
+ rgbaF[i][ACOMP] = UBYTE_TO_FLOAT(rgba[i][ACOMP]);
+ destF[i][RCOMP] = UBYTE_TO_FLOAT(dest[i][RCOMP]);
+ destF[i][GCOMP] = UBYTE_TO_FLOAT(dest[i][GCOMP]);
+ destF[i][BCOMP] = UBYTE_TO_FLOAT(dest[i][BCOMP]);
+ destF[i][ACOMP] = UBYTE_TO_FLOAT(dest[i][ACOMP]);
+ }
+ }
+ /* do blend */
+ blend_general_float(ctx, n, mask, rgbaF, destF, chanType);
+ /* convert back to ubytes */
+ for (i = 0; i < n; i++) {
+ if (mask[i]) {
+ UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][RCOMP], rgbaF[i][RCOMP]);
+ UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][GCOMP], rgbaF[i][GCOMP]);
+ UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][BCOMP], rgbaF[i][BCOMP]);
+ UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][ACOMP], rgbaF[i][ACOMP]);
+ }
+ }
+ }
+ else if (chanType == GL_UNSIGNED_SHORT) {
+ GLushort (*rgba)[4] = (GLushort (*)[4]) src;
+ const GLushort (*dest)[4] = (const GLushort (*)[4]) dst;
+ GLuint i;
+ /* convert ushorts to floats */
+ for (i = 0; i < n; i++) {
+ if (mask[i]) {
+ rgbaF[i][RCOMP] = USHORT_TO_FLOAT(rgba[i][RCOMP]);
+ rgbaF[i][GCOMP] = USHORT_TO_FLOAT(rgba[i][GCOMP]);
+ rgbaF[i][BCOMP] = USHORT_TO_FLOAT(rgba[i][BCOMP]);
+ rgbaF[i][ACOMP] = USHORT_TO_FLOAT(rgba[i][ACOMP]);
+ destF[i][RCOMP] = USHORT_TO_FLOAT(dest[i][RCOMP]);
+ destF[i][GCOMP] = USHORT_TO_FLOAT(dest[i][GCOMP]);
+ destF[i][BCOMP] = USHORT_TO_FLOAT(dest[i][BCOMP]);
+ destF[i][ACOMP] = USHORT_TO_FLOAT(dest[i][ACOMP]);
+ }
+ }
+ /* do blend */
+ blend_general_float(ctx, n, mask, rgbaF, destF, chanType);
+ /* convert back to ushorts */
+ for (i = 0; i < n; i++) {
+ if (mask[i]) {
+ UNCLAMPED_FLOAT_TO_USHORT(rgba[i][RCOMP], rgbaF[i][RCOMP]);
+ UNCLAMPED_FLOAT_TO_USHORT(rgba[i][GCOMP], rgbaF[i][GCOMP]);
+ UNCLAMPED_FLOAT_TO_USHORT(rgba[i][BCOMP], rgbaF[i][BCOMP]);
+ UNCLAMPED_FLOAT_TO_USHORT(rgba[i][ACOMP], rgbaF[i][ACOMP]);
+ }
+ }
+ }
+ else {
+ blend_general_float(ctx, n, mask, (GLfloat (*)[4]) rgbaF,
+ (const GLfloat (*)[4]) destF, chanType);
+ }
+}
+#endif
+
+
static void _BLENDAPI
-blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[],
- GLchan rgba[][4], CONST GLchan dest[][4] )
+blend_general(GLcontext *ctx, GLuint n, const GLubyte mask[],
+ GLchan rgba[][4], CONST GLchan dest[][4],
+ GLenum chanType)
{
const GLfloat rscale = 1.0F / CHAN_MAXF;
const GLfloat gscale = 1.0F / CHAN_MAXF;
@@ -441,7 +862,7 @@ blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[],
break;
default:
/* this should never happen */
- _mesa_problem(ctx, "Bad blend source RGB factor in do_blend");
+ _mesa_problem(ctx, "Bad blend source RGB factor in blend_general");
return;
}
@@ -466,7 +887,7 @@ blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[],
sA = 1.0F - (GLfloat) As * ascale;
break;
case GL_DST_ALPHA:
- sA =(GLfloat) Ad * ascale;
+ sA = (GLfloat) Ad * ascale;
break;
case GL_ONE_MINUS_DST_ALPHA:
sA = 1.0F - (GLfloat) Ad * ascale;
@@ -495,7 +916,8 @@ blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[],
default:
/* this should never happen */
sA = 0.0F;
- _mesa_problem(ctx, "Bad blend source A factor in do_blend");
+ _mesa_problem(ctx, "Bad blend source A factor in blend_general");
+ return;
}
/* Dest RGB factor */
@@ -557,7 +979,8 @@ blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[],
default:
/* this should never happen */
dR = dG = dB = 0.0F;
- _mesa_problem(ctx, "Bad blend dest RGB factor in do_blend");
+ _mesa_problem(ctx, "Bad blend dest RGB factor in blend_general");
+ return;
}
/* Dest Alpha factor */
@@ -607,7 +1030,7 @@ blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[],
default:
/* this should never happen */
dA = 0.0F;
- _mesa_problem(ctx, "Bad blend dest A factor in do_blend");
+ _mesa_problem(ctx, "Bad blend dest A factor in blend_general");
return;
}
@@ -633,59 +1056,63 @@ blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[],
/* compute blended color */
#if CHAN_TYPE == GL_FLOAT
- if (ctx->Color.BlendEquationRGB==GL_FUNC_ADD) {
+ switch (ctx->Color.BlendEquationRGB) {
+ case GL_FUNC_ADD:
r = Rs * sR + Rd * dR;
g = Gs * sG + Gd * dG;
b = Bs * sB + Bd * dB;
a = As * sA + Ad * dA;
- }
- else if (ctx->Color.BlendEquationRGB==GL_FUNC_SUBTRACT) {
+ break;
+ case GL_FUNC_SUBTRACT:
r = Rs * sR - Rd * dR;
g = Gs * sG - Gd * dG;
b = Bs * sB - Bd * dB;
a = As * sA - Ad * dA;
- }
- else if (ctx->Color.BlendEquationRGB==GL_FUNC_REVERSE_SUBTRACT) {
+ break;
+ case GL_FUNC_REVERSE_SUBTRACT:
r = Rd * dR - Rs * sR;
g = Gd * dG - Gs * sG;
b = Bd * dB - Bs * sB;
a = Ad * dA - As * sA;
- }
- else if (ctx->Color.BlendEquationRGB==GL_MIN) {
+ break;
+ case GL_MIN:
r = MIN2( Rd, Rs );
g = MIN2( Gd, Gs );
b = MIN2( Bd, Bs );
- }
- else if (ctx->Color.BlendEquationRGB==GL_MAX) {
+ break;
+ case GL_MAX:
r = MAX2( Rd, Rs );
g = MAX2( Gd, Gs );
b = MAX2( Bd, Bs );
- }
- else {
+ break;
+ default:
/* should never get here */
r = g = b = 0.0F; /* silence uninitialized var warning */
_mesa_problem(ctx, "unexpected BlendEquation in blend_general()");
+ return;
}
- if (ctx->Color.BlendEquationA==GL_FUNC_ADD) {
+ switch (ctx->Color.BlendEquationA) {
+ case GL_FUNC_ADD:
a = As * sA + Ad * dA;
- }
- else if (ctx->Color.BlendEquationA==GL_FUNC_SUBTRACT) {
+ break;
+ case GL_FUNC_SUBTRACT:
a = As * sA - Ad * dA;
- }
- else if (ctx->Color.BlendEquationA==GL_FUNC_REVERSE_SUBTRACT) {
+ break;
+ case GL_FUNC_REVERSE_SUBTRACT:
a = Ad * dA - As * sA;
- }
- else if (ctx->Color.BlendEquationA==GL_MIN) {
+ break;
+ case GL_MIN:
a = MIN2( Ad, As );
- }
- else if (ctx->Color.BlendEquationA==GL_MAX) {
+ break;
+ case GL_MAX:
a = MAX2( Ad, As );
- }
- else {
+ break;
+ default:
/* should never get here */
a = 0.0F; /* silence uninitialized var warning */
_mesa_problem(ctx, "unexpected BlendEquation in blend_general()");
+ return;
}
/* final clamping */
@@ -694,56 +1121,60 @@ blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[],
rgba[i][BCOMP] = MAX2( b, 0.0F );
rgba[i][ACOMP] = CLAMP( a, 0.0F, CHAN_MAXF );
#else
- if (ctx->Color.BlendEquationRGB==GL_FUNC_ADD) {
+ switch (ctx->Color.BlendEquationRGB) {
+ case GL_FUNC_ADD:
r = Rs * sR + Rd * dR + 0.5F;
g = Gs * sG + Gd * dG + 0.5F;
b = Bs * sB + Bd * dB + 0.5F;
- }
- else if (ctx->Color.BlendEquationRGB==GL_FUNC_SUBTRACT) {
+ break;
+ case GL_FUNC_SUBTRACT:
r = Rs * sR - Rd * dR + 0.5F;
g = Gs * sG - Gd * dG + 0.5F;
b = Bs * sB - Bd * dB + 0.5F;
- }
- else if (ctx->Color.BlendEquationRGB==GL_FUNC_REVERSE_SUBTRACT) {
+ break;
+ case GL_FUNC_REVERSE_SUBTRACT:
r = Rd * dR - Rs * sR + 0.5F;
g = Gd * dG - Gs * sG + 0.5F;
b = Bd * dB - Bs * sB + 0.5F;
- }
- else if (ctx->Color.BlendEquationRGB==GL_MIN) {
+ break;
+ case GL_MIN:
r = MIN2( Rd, Rs );
g = MIN2( Gd, Gs );
b = MIN2( Bd, Bs );
- }
- else if (ctx->Color.BlendEquationRGB==GL_MAX) {
+ break;
+ case GL_MAX:
r = MAX2( Rd, Rs );
g = MAX2( Gd, Gs );
b = MAX2( Bd, Bs );
- }
- else {
+ break;
+ default:
/* should never get here */
r = g = b = 0.0F; /* silence uninitialized var warning */
_mesa_problem(ctx, "unexpected BlendEquation in blend_general()");
+ return;
}
- if (ctx->Color.BlendEquationA==GL_FUNC_ADD) {
+ switch (ctx->Color.BlendEquationA) {
+ case GL_FUNC_ADD:
a = As * sA + Ad * dA + 0.5F;
- }
- else if (ctx->Color.BlendEquationA==GL_FUNC_SUBTRACT) {
+ break;
+ case GL_FUNC_SUBTRACT:
a = As * sA - Ad * dA + 0.5F;
- }
- else if (ctx->Color.BlendEquationA==GL_FUNC_REVERSE_SUBTRACT) {
+ break;
+ case GL_FUNC_REVERSE_SUBTRACT:
a = Ad * dA - As * sA + 0.5F;
- }
- else if (ctx->Color.BlendEquationA==GL_MIN) {
+ break;
+ case GL_MIN:
a = MIN2( Ad, As );
- }
- else if (ctx->Color.BlendEquationA==GL_MAX) {
+ break;
+ case GL_MAX:
a = MAX2( Ad, As );
- }
- else {
+ break;
+ default:
/* should never get here */
a = 0.0F; /* silence uninitialized var warning */
_mesa_problem(ctx, "unexpected BlendEquation in blend_general()");
+ return;
}
/* final clamping */
@@ -757,12 +1188,13 @@ blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[],
}
-/*
+/**
* Analyze current blending parameters to pick fastest blending function.
* Result: the ctx->Color.BlendFunc pointer is updated.
*/
void _swrast_choose_blend_func( GLcontext *ctx )
{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLenum eq = ctx->Color.BlendEquationRGB;
const GLenum srcRGB = ctx->Color.BlendSrcRGB;
const GLenum dstRGB = ctx->Color.BlendDstRGB;
@@ -770,77 +1202,77 @@ void _swrast_choose_blend_func( GLcontext *ctx )
const GLenum dstA = ctx->Color.BlendDstA;
if (ctx->Color.BlendEquationRGB != ctx->Color.BlendEquationA) {
- SWRAST_CONTEXT(ctx)->BlendFunc = blend_general;
+ swrast->BlendFunc = blend_general;
}
- else if (eq==GL_MIN) {
+ else if (eq == GL_MIN) {
/* Note: GL_MIN ignores the blending weight factors */
#if defined(USE_MMX_ASM)
if ( cpu_has_mmx ) {
- SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_min;
+ swrast->BlendFunc = _mesa_mmx_blend_min;
}
else
#endif
- SWRAST_CONTEXT(ctx)->BlendFunc = blend_min;
+ swrast->BlendFunc = blend_min_ubyte;
}
- else if (eq==GL_MAX) {
+ else if (eq == GL_MAX) {
/* Note: GL_MAX ignores the blending weight factors */
#if defined(USE_MMX_ASM)
if ( cpu_has_mmx ) {
- SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_max;
+ swrast->BlendFunc = _mesa_mmx_blend_max;
}
else
#endif
- SWRAST_CONTEXT(ctx)->BlendFunc = blend_max;
+ swrast->BlendFunc = blend_max_ubyte;
}
else if (srcRGB != srcA || dstRGB != dstA) {
- SWRAST_CONTEXT(ctx)->BlendFunc = blend_general;
+ swrast->BlendFunc = blend_general;
}
- else if (eq==GL_FUNC_ADD && srcRGB==GL_SRC_ALPHA
- && dstRGB==GL_ONE_MINUS_SRC_ALPHA) {
+ else if (eq == GL_FUNC_ADD && srcRGB == GL_SRC_ALPHA
+ && dstRGB == GL_ONE_MINUS_SRC_ALPHA) {
#if defined(USE_MMX_ASM)
if ( cpu_has_mmx ) {
- SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_transparency;
+ swrast->BlendFunc = _mesa_mmx_blend_transparency;
}
else
#endif
- SWRAST_CONTEXT(ctx)->BlendFunc = blend_transparency;
+ swrast->BlendFunc = blend_transparency_ubyte;
}
- else if (eq==GL_FUNC_ADD && srcRGB==GL_ONE && dstRGB==GL_ONE) {
+ else if (eq == GL_FUNC_ADD && srcRGB == GL_ONE && dstRGB == GL_ONE) {
#if defined(USE_MMX_ASM)
if ( cpu_has_mmx ) {
- SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_add;
+ swrast->BlendFunc = _mesa_mmx_blend_add;
}
else
#endif
- SWRAST_CONTEXT(ctx)->BlendFunc = blend_add;
+ swrast->BlendFunc = blend_add_ubyte;
}
- else if (((eq==GL_FUNC_ADD || eq==GL_FUNC_REVERSE_SUBTRACT)
- && (srcRGB==GL_ZERO && dstRGB==GL_SRC_COLOR))
+ else if (((eq == GL_FUNC_ADD || eq == GL_FUNC_REVERSE_SUBTRACT)
+ && (srcRGB == GL_ZERO && dstRGB == GL_SRC_COLOR))
||
- ((eq==GL_FUNC_ADD || eq==GL_FUNC_SUBTRACT)
- && (srcRGB==GL_DST_COLOR && dstRGB==GL_ZERO))) {
+ ((eq == GL_FUNC_ADD || eq == GL_FUNC_SUBTRACT)
+ && (srcRGB == GL_DST_COLOR && dstRGB == GL_ZERO))) {
#if defined(USE_MMX_ASM)
if ( cpu_has_mmx ) {
- SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_modulate;
+ swrast->BlendFunc = _mesa_mmx_blend_modulate;
}
else
#endif
- SWRAST_CONTEXT(ctx)->BlendFunc = blend_modulate;
+ swrast->BlendFunc = blend_modulate_ubyte;
}
- else if (eq==GL_FUNC_ADD && srcRGB == GL_ZERO && dstRGB == GL_ONE) {
- SWRAST_CONTEXT(ctx)->BlendFunc = blend_noop;
+ else if (eq == GL_FUNC_ADD && srcRGB == GL_ZERO && dstRGB == GL_ONE) {
+ swrast->BlendFunc = blend_noop_ubyte;
}
- else if (eq==GL_FUNC_ADD && srcRGB == GL_ONE && dstRGB == GL_ZERO) {
- SWRAST_CONTEXT(ctx)->BlendFunc = blend_replace;
+ else if (eq == GL_FUNC_ADD && srcRGB == GL_ONE && dstRGB == GL_ZERO) {
+ swrast->BlendFunc = blend_replace;
}
else {
- SWRAST_CONTEXT(ctx)->BlendFunc = blend_general;
+ swrast->BlendFunc = blend_general;
}
}
-/*
+/**
* Apply the blending operator to a span of pixels.
* We can handle horizontal runs of pixels (spans) or arrays of x/y
* pixel coordinates.
@@ -849,25 +1281,17 @@ void
_swrast_blend_span(GLcontext *ctx, struct gl_renderbuffer *rb,
struct sw_span *span)
{
- GLchan framebuffer[MAX_WIDTH][4];
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ void *rbPixels;
ASSERT(span->end <= MAX_WIDTH);
ASSERT(span->arrayMask & SPAN_RGBA);
+ ASSERT(rb->DataType == span->array->ChanType);
ASSERT(!ctx->Color._LogicOpEnabled);
- /* Read span of current frame buffer pixels */
- if (span->arrayMask & SPAN_XY) {
- /* array of x/y pixel coords */
- _swrast_get_values(ctx, rb, span->end, span->array->x, span->array->y,
- framebuffer, 4 * sizeof(GLchan));
- }
- else {
- /* horizontal run of pixels */
- _swrast_read_rgba_span(ctx, rb, span->end, span->x, span->y,
- framebuffer);
- }
+ rbPixels = _swrast_get_dest_rgba(ctx, rb, span);
- SWRAST_CONTEXT(ctx)->BlendFunc( ctx, span->end, span->array->mask,
- span->array->rgba,
- (const GLchan (*)[4]) framebuffer );
+ swrast->BlendFunc(ctx, span->end, span->array->mask,
+ span->array->rgba, (const GLchan (*)[4]) rbPixels,
+ span->array->ChanType);
}