summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/glide/fxtris.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/glide/fxtris.c')
-rw-r--r--src/mesa/drivers/glide/fxtris.c99
1 files changed, 93 insertions, 6 deletions
diff --git a/src/mesa/drivers/glide/fxtris.c b/src/mesa/drivers/glide/fxtris.c
index 56563fc4123..cfd643e8e2f 100644
--- a/src/mesa/drivers/glide/fxtris.c
+++ b/src/mesa/drivers/glide/fxtris.c
@@ -35,6 +35,7 @@
#include "mtypes.h"
#include "macros.h"
#include "colormac.h"
+#include "nvfragprog.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
@@ -44,6 +45,9 @@
#include "fxdrv.h"
+GLboolean fxMultipass_ColorSum (GLcontext *ctx, GLuint pass);
+
+
/*
* Subpixel offsets to adjust Mesa's (true) window coordinates to
* Glide coordinates. We need these to ensure precise rasterization.
@@ -147,6 +151,10 @@ fx_translate_vertex( GLcontext *ctx, const GrVertex *src, SWvertex *dst)
dst->color[2] = src->pargb[0];
dst->color[3] = src->pargb[3];
+ dst->specular[0] = src->pspec[2];
+ dst->specular[1] = src->pspec[1];
+ dst->specular[2] = src->pspec[0];
+
dst->texcoord[ts0][0] = fxMesa->inv_s0scale * src->tmuvtx[0].sow * w;
dst->texcoord[ts0][1] = fxMesa->inv_t0scale * src->tmuvtx[0].tow * w;
@@ -377,7 +385,7 @@ static struct {
#define DO_FULL_QUAD 1
#define HAVE_RGBA 1
-#define HAVE_SPEC 0
+#define HAVE_SPEC 1 /* [dBorca] investigate overhead !!! */
#define HAVE_HW_FLATSHADE 0
#define HAVE_BACK_COLORS 0
#define VERTEX GrVertex
@@ -400,6 +408,7 @@ typedef union { GLfloat f; GLuint u; } fu_type;
#define AREA_IS_CCW( a ) (a < 0)
#endif
+
#define VERT_SET_RGBA( dst, f ) \
do { \
UNCLAMPED_FLOAT_TO_UBYTE(dst->pargb[2], f[0]);\
@@ -414,15 +423,31 @@ do { \
#define VERT_SAVE_RGBA( idx ) \
*(GLuint *)&color[idx] = *(GLuint *)&v[idx]->pargb
-
#define VERT_RESTORE_RGBA( idx ) \
*(GLuint *)&v[idx]->pargb = *(GLuint *)&color[idx]
+#define VERT_SET_SPEC( dst, f ) \
+do { \
+ UNCLAMPED_FLOAT_TO_UBYTE(dst->pspec[2], f[0]);\
+ UNCLAMPED_FLOAT_TO_UBYTE(dst->pspec[1], f[1]);\
+ UNCLAMPED_FLOAT_TO_UBYTE(dst->pspec[0], f[2]);\
+} while (0)
+
+#define VERT_COPY_SPEC( v0, v1 ) \
+ *(GLuint *)&v0->pspec = *(GLuint *)&v1->pspec
+
+#define VERT_SAVE_SPEC( idx ) \
+ *(GLuint *)&spec[idx] = *(GLuint *)&v[idx]->pspec
+
+#define VERT_RESTORE_SPEC( idx ) \
+ *(GLuint *)&v[idx]->pspec = *(GLuint *)&spec[idx]
+
+
#define LOCAL_VARS(n) \
fxMesaContext fxMesa = FX_CONTEXT(ctx); \
- GLubyte color[n][4]; \
- (void) color;
+ GLubyte color[n][4], spec[n][4]; \
+ (void) color; (void) spec;
@@ -1318,13 +1343,13 @@ void fxCheckIsInHardware( GLcontext *ctx )
tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple;
tnl->Driver.Render.BuildVertices = fxBuildVertices;
- tnl->Driver.Render.Multipass = 0;
fxChooseVertexState(ctx);
fxDDChooseRenderState(ctx);
if (fxMesa->verbose) {
fprintf(stderr, "Voodoo ! leave SW 0x%08x %s\n", oldfallback, getFallbackString(oldfallback));
}
}
+ tnl->Driver.Render.Multipass = (HAVE_SPEC && NEED_SECONDARY_COLOR(ctx)) ? fxMultipass_ColorSum : NULL;
}
}
@@ -1348,12 +1373,74 @@ void fxDDInitTriFuncs( GLcontext *ctx )
tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple;
tnl->Driver.Render.BuildVertices = fxBuildVertices;
- tnl->Driver.Render.Multipass = 0;
+ tnl->Driver.Render.Multipass = NULL;
(void) fx_print_vertex;
}
+/* [dBorca] Hack alert:
+ * does this approach work with multitex?
+ */
+GLboolean fxMultipass_ColorSum (GLcontext *ctx, GLuint pass)
+{
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+
+ static int t0 = 0;
+ static int t1 = 0;
+
+ switch (pass) {
+ case 1: /* first pass: the TEXTURED triangles are drawn */
+ /* save per-pass data */
+ fxMesa->restoreUnitsState = fxMesa->unitsState;
+ /* turn off texturing */
+ t0 = ctx->Texture.Unit[0]._ReallyEnabled;
+ t1 = ctx->Texture.Unit[1]._ReallyEnabled;
+ ctx->Texture.Unit[0]._ReallyEnabled = 0;
+ ctx->Texture.Unit[1]._ReallyEnabled = 0;
+ /* SUM the colors */
+ fxDDBlendEquation(ctx, GL_FUNC_ADD_EXT);
+ fxDDBlendFuncSeparate(ctx, GL_ONE, GL_ONE, GL_ZERO, GL_ONE);
+ fxDDEnable(ctx, GL_BLEND, GL_TRUE);
+ /* make sure we draw only where we want to */
+ if (ctx->Depth.Mask) {
+ switch (ctx->Depth.Func) {
+ case GL_NEVER:
+ case GL_ALWAYS:
+ break;
+ default:
+ fxDDDepthFunc( ctx, GL_EQUAL );
+ break;
+ }
+ fxDDDepthMask( ctx, GL_FALSE );
+ }
+ /* switch to secondary colors */
+ grVertexLayout(GR_PARAM_PARGB, GR_VERTEX_PSPEC_OFFSET << 2, GR_PARAM_ENABLE);
+ /* don't advertise new state */
+ fxMesa->new_state = 0;
+ break;
+ case 2: /* 2nd pass (last): the secondary color is summed over texture */
+ /* restore original state */
+ fxMesa->unitsState = fxMesa->restoreUnitsState;
+ /* restore texturing */
+ ctx->Texture.Unit[0]._ReallyEnabled = t0;
+ ctx->Texture.Unit[1]._ReallyEnabled = t1;
+ /* revert to primary colors */
+ grVertexLayout(GR_PARAM_PARGB, GR_VERTEX_PARGB_OFFSET << 2, GR_PARAM_ENABLE);
+ break;
+ default:
+ assert(0); /* NOTREACHED */
+ }
+
+ /* update HW state */
+ fxSetupBlend(ctx);
+ fxSetupDepthTest(ctx);
+ fxSetupTexture(ctx);
+
+ return (pass == 1);
+}
+
+
#else