From: Brian Paul Date: Wed, 28 Jan 2009 17:31:05 +0000 (-0700) Subject: mesa: implement texture swizzling in swrast X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=54c62ba5c36f3e2b279151f5df851d2ceee15319;p=mesa.git mesa: implement texture swizzling in swrast And enable GL_EXT_texture_swizzle for software drivers. --- 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 @@ -32,6 +32,35 @@ #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; 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" @@ -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 ); 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