summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2009-01-28 10:31:05 -0700
committerBrian Paul <[email protected]>2009-01-28 10:31:05 -0700
commit54c62ba5c36f3e2b279151f5df851d2ceee15319 (patch)
tree8ecbcfc4b129957f263e22aaacf48c2936b65757
parent4a89e51c5f88b57040b361b62e80a57c8248ba4b (diff)
mesa: implement texture swizzling in swrast
And enable GL_EXT_texture_swizzle for software drivers.
-rw-r--r--src/mesa/main/extensions.c1
-rw-r--r--src/mesa/swrast/s_fragprog.c39
-rw-r--r--src/mesa/swrast/s_texcombine.c39
-rw-r--r--src/mesa/swrast/s_triangle.c2
4 files changed, 73 insertions, 8 deletions
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index 053f3697d70..86144c42ad8 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -274,6 +274,7 @@ _mesa_enable_sw_extensions(GLcontext *ctx)
#if FEATURE_EXT_texture_sRGB
ctx->Extensions.EXT_texture_sRGB = GL_TRUE;
#endif
+ ctx->Extensions.EXT_texture_swizzle = GL_TRUE;
ctx->Extensions.EXT_vertex_array_bgra = GL_TRUE;
ctx->Extensions.IBM_multimode_draw_arrays = GL_TRUE;
ctx->Extensions.MESA_pack_invert = GL_TRUE;
diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c
index 45ba91ff86d..58ef91ec010 100644
--- a/src/mesa/swrast/s_fragprog.c
+++ b/src/mesa/swrast/s_fragprog.c
@@ -33,6 +33,35 @@
/**
+ * Apply texture object's swizzle (X/Y/Z/W/0/1) to incoming 'texel'
+ * and return results in 'colorOut'.
+ */
+static INLINE void
+swizzle_texel(const GLchan texel[4], GLfloat colorOut[4], GLuint swizzle)
+{
+ if (swizzle == SWIZZLE_NOOP) {
+ colorOut[0] = CHAN_TO_FLOAT(texel[0]);
+ colorOut[1] = CHAN_TO_FLOAT(texel[1]);
+ colorOut[2] = CHAN_TO_FLOAT(texel[2]);
+ colorOut[3] = CHAN_TO_FLOAT(texel[3]);
+ }
+ else {
+ GLfloat vector[6];
+ vector[SWIZZLE_X] = CHAN_TO_FLOAT(texel[0]);
+ vector[SWIZZLE_Y] = CHAN_TO_FLOAT(texel[1]);
+ vector[SWIZZLE_Z] = CHAN_TO_FLOAT(texel[2]);
+ vector[SWIZZLE_W] = CHAN_TO_FLOAT(texel[3]);
+ vector[SWIZZLE_ZERO] = 0.0F;
+ vector[SWIZZLE_ONE] = 1.0F;
+ colorOut[0] = vector[GET_SWZ(swizzle, 0)];
+ colorOut[1] = vector[GET_SWZ(swizzle, 1)];
+ colorOut[2] = vector[GET_SWZ(swizzle, 2)];
+ colorOut[3] = vector[GET_SWZ(swizzle, 3)];
+ }
+}
+
+
+/**
* Fetch a texel with given lod.
* Called via machine->FetchTexelLod()
*/
@@ -52,10 +81,7 @@ fetch_texel_lod( GLcontext *ctx, const GLfloat texcoord[4], GLfloat lambda,
swrast->TextureSample[unit](ctx, texObj, 1,
(const GLfloat (*)[4]) texcoord,
&lambda, &rgba);
- color[0] = CHAN_TO_FLOAT(rgba[0]);
- color[1] = CHAN_TO_FLOAT(rgba[1]);
- color[2] = CHAN_TO_FLOAT(rgba[2]);
- color[3] = CHAN_TO_FLOAT(rgba[3]);
+ swizzle_texel(rgba, color, texObj->_Swizzle);
}
else {
color[0] = color[1] = color[2] = color[3] = 0.0F;
@@ -97,10 +123,7 @@ fetch_texel_deriv( GLcontext *ctx, const GLfloat texcoord[4],
swrast->TextureSample[unit](ctx, texObj, 1,
(const GLfloat (*)[4]) texcoord,
&lambda, &rgba);
- color[0] = CHAN_TO_FLOAT(rgba[0]);
- color[1] = CHAN_TO_FLOAT(rgba[1]);
- color[2] = CHAN_TO_FLOAT(rgba[2]);
- color[3] = CHAN_TO_FLOAT(rgba[3]);
+ swizzle_texel(rgba, color, texObj->_Swizzle);
}
else {
color[0] = color[1] = color[2] = color[3] = 0.0F;
diff --git a/src/mesa/swrast/s_texcombine.c b/src/mesa/swrast/s_texcombine.c
index df6efad66c1..1b8775bf300 100644
--- a/src/mesa/swrast/s_texcombine.c
+++ b/src/mesa/swrast/s_texcombine.c
@@ -31,6 +31,7 @@
#include "main/imports.h"
#include "main/macros.h"
#include "main/pixel.h"
+#include "shader/prog_instruction.h"
#include "s_context.h"
#include "s_texcombine.h"
@@ -816,6 +817,36 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n,
/**
+ * Apply X/Y/Z/W/0/1 swizzle to an array of colors/texels.
+ * See GL_EXT_texture_swizzle.
+ */
+static void
+swizzle_texels(GLuint swizzle, GLuint count, GLchan (*texels)[4])
+{
+ const GLuint swzR = GET_SWZ(swizzle, 0);
+ const GLuint swzG = GET_SWZ(swizzle, 1);
+ const GLuint swzB = GET_SWZ(swizzle, 2);
+ const GLuint swzA = GET_SWZ(swizzle, 3);
+ GLchan vector[6];
+ GLuint i;
+
+ vector[SWIZZLE_ZERO] = 0;
+ vector[SWIZZLE_ONE] = CHAN_MAX;
+
+ for (i = 0; i < count; i++) {
+ vector[SWIZZLE_X] = texels[i][0];
+ vector[SWIZZLE_Y] = texels[i][1];
+ vector[SWIZZLE_Z] = texels[i][2];
+ vector[SWIZZLE_W] = texels[i][3];
+ texels[i][RCOMP] = vector[swzR];
+ texels[i][GCOMP] = vector[swzG];
+ texels[i][BCOMP] = vector[swzB];
+ texels[i][ACOMP] = vector[swzA];
+ }
+}
+
+
+/**
* Apply a conventional OpenGL texture env mode (REPLACE, ADD, BLEND,
* MODULATE, or DECAL) to an array of fragments.
* Input: textureUnit - pointer to texture unit to apply
@@ -1241,9 +1272,15 @@ _swrast_texture_span( GLcontext *ctx, SWspan *span )
_mesa_lookup_rgba_float(&texUnit->ColorTable, span->end, texels);
#endif
}
+
+ /* GL_EXT_texture_swizzle */
+ if (curObj->_Swizzle != SWIZZLE_NOOP) {
+ swizzle_texels(curObj->_Swizzle, span->end, texels);
+ }
}
}
+
/*
* OK, now apply the texture (aka texture combine/blend).
* We modify the span->color.rgba values.
@@ -1262,6 +1299,8 @@ _swrast_texture_span( GLcontext *ctx, SWspan *span )
const GLchan (*texels)[4] = (const GLchan (*)[4])
(swrast->TexelBuffer + unit *
(span->end * 4 * sizeof(GLchan)));
+
+
texture_apply( ctx, texUnit, span->end,
(CONST GLchan (*)[4]) primary_rgba, texels,
span->array->rgba );
diff --git a/src/mesa/swrast/s_triangle.c b/src/mesa/swrast/s_triangle.c
index 5d232487f30..063130714c0 100644
--- a/src/mesa/swrast/s_triangle.c
+++ b/src/mesa/swrast/s_triangle.c
@@ -35,6 +35,7 @@
#include "main/imports.h"
#include "main/macros.h"
#include "main/texformat.h"
+#include "shader/prog_instruction.h"
#include "s_aatriangle.h"
#include "s_context.h"
@@ -1063,6 +1064,7 @@ _swrast_choose_triangle( GLcontext *ctx )
&& ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT
&& texObj2D->WrapS == GL_REPEAT
&& texObj2D->WrapT == GL_REPEAT
+ && texObj2D->_Swizzle == SWIZZLE_NOOP
&& texImg->_IsPowerOfTwo
&& texImg->Border == 0
&& texImg->Width == texImg->RowStride