mesa: implement texture swizzling in swrast
authorBrian Paul <brianp@vmware.com>
Wed, 28 Jan 2009 17:31:05 +0000 (10:31 -0700)
committerBrian Paul <brianp@vmware.com>
Wed, 28 Jan 2009 17:31:05 +0000 (10:31 -0700)
And enable GL_EXT_texture_swizzle for software drivers.

src/mesa/main/extensions.c
src/mesa/swrast/s_fragprog.c
src/mesa/swrast/s_texcombine.c
src/mesa/swrast/s_triangle.c

index 053f3697d70e4b8f58d97d24fbfe8a26f4a2adb7..86144c42ad8d1d032e3a5d8833e62248fb4da8f3 100644 (file)
@@ -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;
index 45ba91ff86d4dd584788f4e8d2a5469b85a1505e..58ef91ec010a35b5c81698069cdff29055892cf1 100644 (file)
 #include "s_span.h"
 
 
+/**
+ * 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;
index df6efad66c18cf8765cbf8ff430f0c9eb620647f..1b8775bf3008fe1f5fde1b99017ecfa50f5b5474 100644 (file)
@@ -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"
@@ -815,6 +816,36 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n,
 #undef PROD
 
 
+/**
+ * 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.
@@ -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 );
index 5d232487f30e9d6e1728242eee2976a3a231ea45..063130714c0688eb77a0b43a9a901771a90217c1 100644 (file)
@@ -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