diff options
author | Keith Whitwell <keith@tungstengraphics.com> | 2001-07-12 22:09:21 +0000 |
---|---|---|
committer | Keith Whitwell <keith@tungstengraphics.com> | 2001-07-12 22:09:21 +0000 |
commit | 1182ffeec39bf419928ba862c225e80a439fee7a (patch) | |
tree | af9e3f9019e3c59cb73d770eb60e94c5c77bdd25 /src | |
parent | fae7b778b81b686ef419f971064b5fe12fb4ead3 (diff) |
Rename some of the tnl->Driver.* functions to tnl->Driver.Render.*, to make it
clear that these are owned by t_vb_render.c.
Make swrast_setup opaque - it now hooks itself directly into
tnl->Driver.Render.*. Add a _swsetup_Wakeup() call that does this.
Update X11 (tested), osmesa and FX drivers for this change.
FX compiles but is probably broken as the changes there are large. It was the
only remaining driver that used the internal _swsetup_ functions for
interp and copy_pv. This usage has been replaced with code from the DRI
tdfx driver.
Diffstat (limited to 'src')
24 files changed, 1809 insertions, 1750 deletions
diff --git a/src/mesa/Makefile.X11 b/src/mesa/Makefile.X11 index 255ab695f4..28980575a5 100644 --- a/src/mesa/Makefile.X11 +++ b/src/mesa/Makefile.X11 @@ -1,4 +1,4 @@ -# $Id: Makefile.X11,v 1.55 2001/06/27 12:52:12 keithw Exp $ +# $Id: Makefile.X11,v 1.56 2001/07/12 22:09:21 keithw Exp $ # Mesa 3-D graphics library # Version: 3.5 @@ -21,6 +21,9 @@ LIBDIR = ../lib CORE_SOURCES = \ + swrast_setup/ss_context.c \ + swrast_setup/ss_triangle.c \ + swrast_setup/ss_vb.c \ api_arrayelt.c \ api_loopback.c \ api_noop.c \ @@ -118,10 +121,6 @@ CORE_SOURCES = \ swrast/s_texstore.c \ swrast/s_triangle.c \ swrast/s_zoom.c \ - swrast_setup/ss_context.c \ - swrast_setup/ss_triangle.c \ - swrast_setup/ss_vb.c \ - swrast_setup/ss_interp.c \ tnl/t_array_api.c \ tnl/t_array_import.c \ tnl/t_context.c \ diff --git a/src/mesa/drivers/glide/fxdd.c b/src/mesa/drivers/glide/fxdd.c index 117e9d7dea..e645f65be6 100644 --- a/src/mesa/drivers/glide/fxdd.c +++ b/src/mesa/drivers/glide/fxdd.c @@ -674,11 +674,6 @@ fxDDInitFxMesaContext(fxMesaContext fxMesa) if (getenv("FX_EMULATE_SINGLE_TMU")) fxMesa->haveTwoTMUs = GL_FALSE; - fxMesa->emulateTwoTMUs = fxMesa->haveTwoTMUs; - - if (!getenv("FX_DONT_FAKE_MULTITEX")) - fxMesa->emulateTwoTMUs = GL_TRUE; - if (getenv("FX_GLIDE_SWAPINTERVAL")) fxMesa->swapInterval = atoi(getenv("FX_GLIDE_SWAPINTERVAL")); else @@ -754,7 +749,7 @@ fxDDInitFxMesaContext(fxMesaContext fxMesa) fxMesa->textureAlign = FX_grGetInteger(FX_TEXTURE_ALIGN); fxMesa->glCtx->Const.MaxTextureLevels = 9; - fxMesa->glCtx->Const.MaxTextureUnits = fxMesa->emulateTwoTMUs ? 2 : 1; + fxMesa->glCtx->Const.MaxTextureUnits = fxMesa->haveTwoTMUs ? 2 : 1; fxMesa->new_state = _NEW_ALL; /* Initialize the software rasterizer and helper modules. @@ -783,10 +778,6 @@ fxDDInitFxMesaContext(fxMesaContext fxMesa) fxDDInitExtensions(fxMesa->glCtx); -#ifdef FXVTXFMT - fxDDInitVtxfmt(fxMesa->glCtx); -#endif - FX_grGlideGetState((GrState *) fxMesa->state); /* Run the config file */ @@ -830,7 +821,7 @@ fxDDInitExtensions(GLcontext * ctx) if (fxMesa->haveTwoTMUs) _mesa_enable_extension(ctx, "GL_EXT_texture_env_add"); - if (fxMesa->emulateTwoTMUs) + if (fxMesa->haveTwoTMUs) _mesa_enable_extension(ctx, "GL_ARB_multitexture"); } @@ -843,8 +834,8 @@ fxDDInitExtensions(GLcontext * ctx) * * Performs similar work to fxDDChooseRenderState() - should be merged. */ -static GLboolean -fxIsInHardware(GLcontext * ctx) +GLboolean +fx_check_IsInHardware(GLcontext * ctx) { fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; @@ -868,7 +859,7 @@ fxIsInHardware(GLcontext * ctx) } /* Unsupported texture/multitexture cases */ - if (fxMesa->emulateTwoTMUs) { + if (fxMesa->haveTwoTMUs) { if (ctx->Texture._ReallyEnabled & (TEXTURE0_3D | TEXTURE1_3D)) return GL_FALSE; /* can't do 3D textures */ if (ctx->Texture._ReallyEnabled & (TEXTURE0_1D | TEXTURE1_1D)) @@ -939,6 +930,9 @@ fxIsInHardware(GLcontext * ctx) return GL_TRUE; } + + + static void update_texture_scales(GLcontext * ctx) { @@ -980,79 +974,34 @@ fxDDUpdateDDPointers(GLcontext * ctx, GLuint new_state) if (new_state & (_FX_NEW_IS_IN_HARDWARE | _FX_NEW_RENDERSTATE | - _FX_NEW_SETUP_FUNCTION | _NEW_TEXTURE)) { + _FX_NEW_SETUP_FUNCTION | + _NEW_TEXTURE)) { if (new_state & _FX_NEW_IS_IN_HARDWARE) - fxMesa->is_in_hardware = fxIsInHardware(ctx); + fxCheckIsInHardware(ctx); if (fxMesa->new_state) fxSetupFXUnits(ctx); - if (new_state & _FX_NEW_RENDERSTATE) - fxDDChooseRenderState(ctx); + if (fxMesa->is_in_hardware) { + if (new_state & _FX_NEW_RENDERSTATE) + fxDDChooseRenderState(ctx); - if (new_state & _FX_NEW_SETUP_FUNCTION) - tnl->Driver.BuildProjectedVertices = fx_validate_BuildProjVerts; + if (new_state & _FX_NEW_SETUP_FUNCTION) + fxDDChooseSetupState(ctx); + } if (new_state & _NEW_TEXTURE) update_texture_scales(ctx); - - } - -#ifdef FXVTXFMT - if (fxMesa->allow_vfmt) { - if (new_state & _NEW_LIGHT) - fx_update_lighting(ctx); - - if (new_state & _FX_NEW_VTXFMT) - fxDDCheckVtxfmt(ctx); - } -#endif -} - -static void -fxDDRenderPrimitive(GLcontext * ctx, GLenum mode) -{ - fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; - - if (!fxMesa->is_in_hardware) { - _swsetup_RenderPrimitive(ctx, mode); - } - else { - fxMesa->render_prim = mode; } } -static void -fxDDRenderStart(GLcontext * ctx) -{ - fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; - - _swsetup_RenderStart(ctx); - - if (fxMesa->new_state) { - fxSetupFXUnits(ctx); - } -} - -static void -fxDDRenderFinish(GLcontext * ctx) -{ - fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; - - if (!fxMesa->is_in_hardware) { - _swsetup_RenderFinish(ctx); - } -} - void fxSetupDDPointers(GLcontext * ctx) { - TNLcontext *tnl = TNL_CONTEXT(ctx); - if (MESA_VERBOSE & VERBOSE_DRIVER) { fprintf(stderr, "fxmesa: fxSetupDDPointers()\n"); } @@ -1106,16 +1055,6 @@ fxSetupDDPointers(GLcontext * ctx) ctx->Driver.ShadeModel = fxDDShadeModel; ctx->Driver.Enable = fxDDEnable; - tnl->Driver.RunPipeline = _tnl_run_pipeline; - tnl->Driver.RenderStart = fxDDRenderStart; - tnl->Driver.RenderFinish = fxDDRenderFinish; - tnl->Driver.ResetLineStipple = _swrast_ResetLineStipple; - tnl->Driver.RenderPrimitive = fxDDRenderPrimitive; - tnl->Driver.RenderInterp = _swsetup_RenderInterp; - tnl->Driver.RenderCopyPV = _swsetup_RenderCopyPV; - tnl->Driver.RenderClippedLine = _swsetup_RenderClippedLine; - tnl->Driver.RenderClippedPolygon = _swsetup_RenderClippedPolygon; - fxSetupDDSpanPointers(ctx); fxDDUpdateDDPointers(ctx, ~0); } diff --git a/src/mesa/drivers/glide/fxdrv.h b/src/mesa/drivers/glide/fxdrv.h index 0d4c7a45bd..09674680c9 100644 --- a/src/mesa/drivers/glide/fxdrv.h +++ b/src/mesa/drivers/glide/fxdrv.h @@ -94,37 +94,6 @@ extern float gl_ubyte_to_float_255_color_tab[256]; -/* Should have size == 16 * sizeof(float). - */ -typedef union -{ - GrVertex v; - GLfloat f[16]; - GLuint ui[16]; -} -fxVertex; - -/* Used in the fxvtxfmt t&l engine. - */ -typedef struct -{ - GrVertex v; - GLfloat clip[4]; - GLfloat texcoord[2][2]; - GLubyte mask; - GLfloat normal[3]; /* for replay & fallback */ -} -fxClipVertex; - - - -typedef void (*vfmt_project_func) (GLcontext * ctx, fxClipVertex * v); -typedef void (*vfmt_interpolate_func) (GLfloat t, - fxClipVertex * O, - const fxClipVertex * I, - const fxClipVertex * J); - - #if defined(FXMESA_USE_ARGB) #define FXCOLOR4( c ) ( \ @@ -147,14 +116,15 @@ typedef void (*vfmt_interpolate_func) (GLfloat t, -/* fastpath/vtxfmt flags first +/* fastpath flags first */ #define SETUP_TMU0 0x1 #define SETUP_TMU1 0x2 #define SETUP_RGBA 0x4 #define SETUP_SNAP 0x8 #define SETUP_XYZW 0x10 -#define MAX_SETUP 0x20 +#define SETUP_PTEX 0x20 +#define MAX_SETUP 0x40 #define FX_NUM_TMU 2 @@ -356,6 +326,7 @@ tfxUnitsState; _DD_NEW_POINT_SIZE | \ _NEW_LINE) + /* Covers the state referenced by fxDDChooseSetupFunction. */ #define _FX_NEW_SETUP_FUNCTION (_NEW_LIGHT| \ @@ -364,18 +335,6 @@ tfxUnitsState; _NEW_COLOR) \ -/* Covers the state referenced in fxDDCheckVtxfmt. - */ -#define _FX_NEW_VTXFMT (_NEW_TEXTURE | \ - _NEW_TEXTURE_MATRIX | \ - _NEW_TRANSFORM | \ - _NEW_LIGHT | \ - _NEW_PROJECTION | \ - _NEW_MODELVIEW | \ - _TNL_NEW_NEED_EYE_COORDS | \ - _FX_NEW_RENDERSTATE) - - /* These lookup table are used to extract RGB values in [0,255] from * 16-bit pixel values. */ @@ -384,11 +343,9 @@ extern GLubyte FX_PixelToG[0x10000]; extern GLubyte FX_PixelToB[0x10000]; -typedef void (*fx_tri_func) (GLcontext *, const fxVertex *, - const fxVertex *, const fxVertex *); -typedef void (*fx_line_func) (GLcontext *, const fxVertex *, - const fxVertex *); -typedef void (*fx_point_func) (GLcontext *, const fxVertex *); +typedef void (*fx_tri_func) (fxMesaContext, GrVertex *, GrVertex *, GrVertex *); +typedef void (*fx_line_func) (fxMesaContext, GrVertex *, GrVertex *); +typedef void (*fx_point_func) (fxMesaContext, GrVertex *); struct tfxMesaContext { @@ -434,19 +391,18 @@ struct tfxMesaContext /* Vertex building and storage: */ GLuint tmu_source[FX_NUM_TMU]; - GLuint tex_dest[MAX_TEXTURE_UNITS]; - GLuint setupindex; - GLuint setup_gone; /* for multipass */ + GLuint SetupIndex; GLuint stw_hint_state; /* for grHints */ - fxVertex *verts; + GrVertex *verts; GLboolean snapVertices; /* needed for older Voodoo hardware */ + struct gl_client_array UbyteColor; /* Rasterization: */ GLuint render_index; - GLuint passes, multipass; GLuint is_in_hardware; - GLenum render_prim; + GLenum render_primitive; + GLenum raster_primitive; /* Current rasterization functions */ @@ -454,15 +410,6 @@ struct tfxMesaContext fx_line_func draw_line; fx_tri_func draw_tri; - /* System to turn culling on/off for tris/lines/points. - */ - fx_point_func initial_point; - fx_line_func initial_line; - fx_tri_func initial_tri; - - fx_point_func subsequent_point; - fx_line_func subsequent_line; - fx_tri_func subsequent_tri; /* Keep texture scales somewhere handy: */ @@ -485,7 +432,6 @@ struct tfxMesaContext GLboolean verbose; GLboolean haveTwoTMUs; /* True if we really have 2 tmu's */ - GLboolean emulateTwoTMUs; /* True if we present 2 tmu's to mesa. */ GLboolean haveAlphaBuffer; GLboolean haveZBuffer; GLboolean haveDoubleBuffer; @@ -502,37 +448,8 @@ struct tfxMesaContext int clipMaxX; int clipMinY; int clipMaxY; - - /* fxvtxfmt - */ - GLboolean allow_vfmt; - GLvertexformat vtxfmt; - fxClipVertex current; - fxClipVertex *vert; /* points into verts[] */ - void (*fire_on_vertex) (GLcontext *); - void (*fire_on_end) (GLcontext *); - void (*fire_on_fallback) (GLcontext *); - - vfmt_project_func project_vertex; - vfmt_interpolate_func interpolate_vertices; - - int vtxfmt_fallback_count; - int vtxfmt_installed; - void (*old_begin) (GLenum); - GLenum prim; - - GLuint accel_light; - GLfloat basecolor[4]; - - - /* Projected vertices, fastpath data: - */ - GLvector1ui clipped_elements; - fxVertex *last_vert; - GLuint size; }; -typedef void (*tfxSetupFunc) (GLcontext * ctx, GLuint, GLuint); extern GrHwConfiguration glbHWConfig; extern int glbCurrentBoard; @@ -540,17 +457,20 @@ extern int glbCurrentBoard; extern void fxSetupFXUnits(GLcontext *); extern void fxSetupDDPointers(GLcontext *); -/* fxvsetup: +/* fxvb.c: */ -extern void fxDDSetupInit(void); extern void fxAllocVB(GLcontext * ctx); extern void fxFreeVB(GLcontext * ctx); -extern void fxPrintSetupFlags(const char *msg, GLuint flags); -extern void fx_BuildProjVerts(GLcontext * ctx, - GLuint start, GLuint count, GLuint newinputs); -extern void fx_validate_BuildProjVerts(GLcontext * ctx, - GLuint start, GLuint count, - GLuint newinputs); +extern void fxPrintSetupFlags(char *msg, GLuint flags ); +extern void fxCheckTexSizes( GLcontext *ctx ); +extern void fxBuildVertices( GLcontext *ctx, GLuint start, GLuint count, + GLuint newinputs ); +extern void fxChooseVertexState( GLcontext *ctx ); + + + + + /* fxtrifuncs: */ @@ -655,14 +575,4 @@ extern void fxTMMoveInTM_NoLock(fxMesaContext fxMesa, extern void fxInitPixelTables(fxMesaContext fxMesa, GLboolean bgrOrder); -/* fxvtxfmt: - */ -extern void fxDDCheckVtxfmt(GLcontext * ctx); -extern void fx_update_lighting(GLcontext * ctx); -extern void fxDDInitVtxfmt(GLcontext * ctx); - -/* fxsimplerender - */ -extern const struct gl_pipeline_stage fx_render_stage; - #endif diff --git a/src/mesa/drivers/glide/fxsetup.c b/src/mesa/drivers/glide/fxsetup.c index 2e33bd47e3..ca79cc4e19 100644 --- a/src/mesa/drivers/glide/fxsetup.c +++ b/src/mesa/drivers/glide/fxsetup.c @@ -55,8 +55,6 @@ #include "enums.h" #include "tnl/t_context.h" -/*static GLboolean fxMultipassTexture(GLcontext *, GLuint);*/ - static void fxTexValidate(GLcontext * ctx, struct gl_texture_object *tObj) { @@ -531,23 +529,8 @@ fxSetupTextureSingleTMU_NoLock(GLcontext * ctx, GLuint textureset) localc, GR_COMBINE_OTHER_TEXTURE, FXFALSE); break; case GL_BLEND: -#if 0 - FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER, - GR_COMBINE_FACTOR_LOCAL, - locala, GR_COMBINE_OTHER_TEXTURE, FXFALSE); - if (ifmt == GL_ALPHA) - FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL, - GR_COMBINE_FACTOR_NONE, - localc, GR_COMBINE_OTHER_NONE, FXFALSE); - else - FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, - GR_COMBINE_FACTOR_LOCAL, - localc, GR_COMBINE_OTHER_TEXTURE, FXTRUE); - ctx->Driver.MultipassFunc = fxMultipassBlend; -#else if (MESA_VERBOSE & VERBOSE_DRIVER) fprintf(stderr, "fx Driver: GL_BLEND not yet supported\n"); -#endif break; case GL_REPLACE: if ((ifmt == GL_RGB) || (ifmt == GL_LUMINANCE)) @@ -1037,7 +1020,7 @@ fxSetupTexture_NoLock(GLcontext * ctx) */ tex2Denabled = (ctx->Texture._ReallyEnabled & TEXTURE0_2D); - if (fxMesa->emulateTwoTMUs) + if (fxMesa->haveTwoTMUs) tex2Denabled |= (ctx->Texture._ReallyEnabled & TEXTURE1_2D); switch (tex2Denabled) { @@ -1055,7 +1038,6 @@ fxSetupTexture_NoLock(GLcontext * ctx) fprintf(stderr, "fxmesa: enabling fake multitexture\n"); fxSetupTextureSingleTMU_NoLock(ctx, 0); - /*ctx->Driver.MultipassFunc = fxMultipassTexture;*/ } break; default: @@ -1547,7 +1529,8 @@ fxSetupCull(GLcontext * ctx) else FX_CONTEXT(ctx)->cullMode = GR_CULL_DISABLE; - FX_grCullMode(FX_CONTEXT(ctx)->cullMode); + if (FX_CONTEXT(ctx)->raster_primitive == GL_TRIANGLES) + FX_grCullMode(FX_CONTEXT(ctx)->cullMode); } @@ -1616,129 +1599,7 @@ fxDDEnable(GLcontext * ctx, GLenum cap, GLboolean state) } } -#if 0 -/* - Multipass to do GL_BLEND texture functions - Cf*(1-Ct) has already been written to the buffer during the first pass - Cc*Ct gets written during the second pass (in this function) - Everything gets reset in the third call (in this function) -*/ -static GLboolean -fxMultipassBlend(struct vertex_buffer *VB, GLuint pass) -{ - GLcontext *ctx = VB->ctx; - fxMesaContext fxMesa = FX_CONTEXT(ctx); - - switch (pass) { - case 1: - /* Add Cc*Ct */ - fxMesa->restoreUnitsState = fxMesa->unitsState; - if (ctx->Depth.Mask) { - /* We don't want to check or change the depth buffers */ - switch (ctx->Depth.Func) { - case GL_NEVER: - case GL_ALWAYS: - break; - default: - fxDDDepthFunc(ctx, GL_EQUAL); - break; - } - fxDDDepthMask(ctx, FALSE); - } - /* Enable Cc*Ct mode */ - /* XXX Set the Constant Color ? */ - fxDDEnable(ctx, GL_BLEND, GL_TRUE); - fxDDBlendFunc(ctx, XXX, XXX); - fxSetupTextureSingleTMU(ctx, XXX); - fxSetupBlend(ctx); - fxSetupDepthTest(ctx); - break; - - case 2: - /* Reset everything back to normal */ - fxMesa->unitsState = fxMesa->restoreUnitsState; - fxMesa->setup_gone |= XXX; - fxSetupTextureSingleTMU(ctx, XXX); - fxSetupBlend(ctx); - fxSetupDepthTest(ctx); - break; - } - - return pass == 1; -} -#endif -/************************************************************************/ -/******************** Fake Multitexture Support *************************/ -/************************************************************************/ - -/* Its considered cheeky to try to fake ARB multitexture by doing - * multipass rendering, because it is not possible to emulate the full - * spec in this way. The fact is that the voodoo 2 supports only a - * subset of the possible multitexturing modes, and it is possible to - * support almost the same subset using multipass blending on the - * voodoo 1. In all other cases for both voodoo 1 and 2, we fall back - * to software rendering, satisfying the spec if not the user. - */ -static GLboolean -fxMultipassTexture(GLcontext * ctx, GLuint pass) -{ - fxMesaContext fxMesa = FX_CONTEXT(ctx); - TNLcontext *tnl = TNL_CONTEXT(ctx); - fxVertex *v = fxMesa->verts; - fxVertex *last = fxMesa->verts + tnl->vb.Count; - - switch (pass) { - case 1: - if (MESA_VERBOSE & - (VERBOSE_DRIVER | VERBOSE_PIPELINE | VERBOSE_TEXTURE)) - fprintf(stderr, "fxmesa: Second texture pass\n"); - - for (; v != last; v++) { - v->f[S0COORD] = v->f[S1COORD]; - v->f[T0COORD] = v->f[T1COORD]; - } - - fxMesa->restoreUnitsState = fxMesa->unitsState; - fxMesa->tmu_source[0] = 1; - - 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); - } - - if (ctx->Texture.Unit[1].EnvMode == GL_MODULATE) { - fxDDEnable(ctx, GL_BLEND, GL_TRUE); - fxDDBlendFunc(ctx, GL_DST_COLOR, GL_ZERO); - } - - fxSetupTextureSingleTMU(ctx, 1); - fxSetupBlend(ctx); - fxSetupDepthTest(ctx); - break; - - case 2: - /* Restore original state. - */ - fxMesa->tmu_source[0] = 0; - fxMesa->unitsState = fxMesa->restoreUnitsState; - fxMesa->setup_gone |= SETUP_TMU0; - fxSetupTextureSingleTMU(ctx, 0); - fxSetupBlend(ctx); - fxSetupDepthTest(ctx); - break; - } - - return pass == 1; -} /************************************************************************/ @@ -1809,9 +1670,6 @@ fxSetupFXUnits(GLcontext * ctx) if (newstate & FX_NEW_CULL) fxSetupCull(ctx); - fxMesa->draw_point = fxMesa->initial_point; - fxMesa->draw_line = fxMesa->initial_line; - fxMesa->draw_tri = fxMesa->initial_tri; fxMesa->new_state = 0; } } diff --git a/src/mesa/drivers/glide/fxtris.c b/src/mesa/drivers/glide/fxtris.c index 829aabe749..5129a94476 100644 --- a/src/mesa/drivers/glide/fxtris.c +++ b/src/mesa/drivers/glide/fxtris.c @@ -1,641 +1,824 @@ +/* -*- mode: c; c-basic-offset: 3 -*- + * + * Copyright 2000 VA Linux Systems Inc., Fremont, California. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * VA LINUX SYSTEMS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +/* $XFree86: xc/lib/GL/mesa/src/drv/fx/fxtris.c,v 1.5 2000/09/24 13:51:04 alanh Exp $ */ +/* Authors: + * Keith Whitwell <keithw@valinux.com> + */ -#ifdef HAVE_CONFIG_H -#include "conf.h" -#endif +#include <stdio.h> +#include <math.h> -#if defined(FX) +#include "glheader.h" +#include "mtypes.h" +#include "macros.h" +#include "colormac.h" -#include "mmath.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" - #include "tnl/t_context.h" #include "tnl/t_pipeline.h" #include "fxdrv.h" -#include "fxglidew.h" - - - - - - -static void -fx_draw_point(GLcontext * ctx, const fxVertex * v) +/* + * Subpixel offsets to adjust Mesa's (true) window coordinates to + * Glide coordinates. We need these to ensure precise rasterization. + * Otherwise, we'll fail a bunch of conformance tests. + */ +#define TRI_X_OFFSET ( 0.0F) +#define TRI_Y_OFFSET ( 0.0F) +#define LINE_X_OFFSET ( 0.0F) +#define LINE_Y_OFFSET ( 0.125F) +#define PNT_X_OFFSET ( 0.375F) +#define PNT_Y_OFFSET ( 0.375F) + +static void fxRasterPrimitive( GLcontext *ctx, GLenum prim ); +static void fxRenderPrimitive( GLcontext *ctx, GLenum prim ); + +/*********************************************************************** + * Macros for t_dd_tritmp.h to draw basic primitives * + ***********************************************************************/ + +#define TRI( a, b, c ) \ +do { \ + if (DO_FALLBACK) \ + fxMesa->draw_tri( fxMesa, a, b, c ); \ + else \ + grDrawTriangle( a, b, c ); \ +} while (0) \ + +#define QUAD( a, b, c, d ) \ +do { \ + if (DO_FALLBACK) { \ + fxMesa->draw_tri( fxMesa, a, b, d ); \ + fxMesa->draw_tri( fxMesa, b, c, d ); \ + } else { \ + grDrawTriangle( a, b, d ); \ + grDrawTriangle( b, c, d ); \ + } \ +} while (0) + +#define LINE( v0, v1 ) \ +do { \ + if (DO_FALLBACK) \ + fxMesa->draw_line( fxMesa, v0, v1 ); \ + else { \ + v0->x += LINE_X_OFFSET - TRI_X_OFFSET; \ + v0->y += LINE_Y_OFFSET - TRI_Y_OFFSET; \ + v1->x += LINE_X_OFFSET - TRI_X_OFFSET; \ + v1->y += LINE_Y_OFFSET - TRI_Y_OFFSET; \ + grDrawLine( v0, v1 ); \ + v0->x -= LINE_X_OFFSET - TRI_X_OFFSET; \ + v0->y -= LINE_Y_OFFSET - TRI_Y_OFFSET; \ + v1->x -= LINE_X_OFFSET - TRI_X_OFFSET; \ + v1->y -= LINE_Y_OFFSET - TRI_Y_OFFSET; \ + } \ +} while (0) + +#define POINT( v0 ) \ +do { \ + if (DO_FALLBACK) \ + fxMesa->draw_point( fxMesa, v0 ); \ + else { \ + v0->x += PNT_X_OFFSET - TRI_X_OFFSET; \ + v0->y += PNT_Y_OFFSET - TRI_Y_OFFSET; \ + grDrawPoint( v0 ); \ + v0->x -= PNT_X_OFFSET - TRI_X_OFFSET; \ + v0->y -= PNT_Y_OFFSET - TRI_Y_OFFSET; \ + } \ +} while (0) + + +/*********************************************************************** + * Fallback to swrast for basic primitives * + ***********************************************************************/ + +/* Build an SWvertex from a hardware vertex. + * + * This code is hit only when a mix of accelerated and unaccelerated + * primitives are being drawn, and only for the unaccelerated + * primitives. + */ +static void +fx_translate_vertex( GLcontext *ctx, const GrVertex *src, SWvertex *dst) { - GLfloat sz = ctx->Point._Size; - - if (sz <= 1.0) { - grDrawPoint(&(v->v)); - } - else { - GrVertex verts[4]; - - sz *= .5; + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GLuint ts0 = fxMesa->tmu_source[0]; + GLuint ts1 = fxMesa->tmu_source[1]; + GLfloat w = 1.0 / src->oow; - verts[0] = v->v; - verts[1] = v->v; - verts[2] = v->v; - verts[3] = v->v; + dst->win[0] = src->x; + dst->win[1] = src->y; + dst->win[2] = src->ooz; + dst->win[3] = src->oow; - verts[0].x = v->v.x - sz; - verts[0].y = v->v.y - sz; + dst->color[0] = (GLubyte) src->r; + dst->color[1] = (GLubyte) src->g; + dst->color[2] = (GLubyte) src->b; + dst->color[3] = (GLubyte) src->a; - verts[1].x = v->v.x + sz; - verts[1].y = v->v.y - sz; + dst->texcoord[ts0][0] = fxMesa->inv_s0scale * src->tmuvtx[0].sow * w; + dst->texcoord[ts0][1] = fxMesa->inv_t0scale * src->tmuvtx[0].tow * w; - verts[2].x = v->v.x + sz; - verts[2].y = v->v.y + sz; + if (fxMesa->stw_hint_state & GR_STWHINT_W_DIFF_TMU0) + dst->texcoord[ts0][3] = src->tmuvtx[0].oow * w; + else + dst->texcoord[ts0][3] = 1.0; - verts[3].x = v->v.x - sz; - verts[3].y = v->v.y + sz; + if (fxMesa->SetupIndex & SETUP_TMU1) { + dst->texcoord[ts1][0] = fxMesa->inv_s1scale * src->tmuvtx[1].sow * w; + dst->texcoord[ts1][1] = fxMesa->inv_t1scale * src->tmuvtx[1].tow * w; - grDrawTriangle(&verts[0], &verts[1], &verts[3]); - grDrawTriangle(&verts[1], &verts[2], &verts[3]); + if (fxMesa->stw_hint_state & GR_STWHINT_W_DIFF_TMU1) + dst->texcoord[ts1][3] = src->tmuvtx[1].oow * w; + else + dst->texcoord[ts1][3] = 1.0; } + + dst->pointSize = ctx->Point._Size; } -static void -fx_draw_line(GLcontext * ctx, const fxVertex * v0, const fxVertex * v1) +static void +fx_fallback_tri( fxMesaContext fxMesa, + GrVertex *v0, + GrVertex *v1, + GrVertex *v2 ) { - float width = ctx->Line.Width; - - if (width <= 1.0) { - grDrawLine(&(v0->v), &(v1->v)); - } - else { - GrVertex verts[4]; - float dx, dy, ix, iy; - - dx = v0->v.x - v1->v.x; - dy = v0->v.y - v1->v.y; - - if (dx * dx > dy * dy) { - iy = width * .5; - ix = 0; - } - else { - iy = 0; - ix = width * .5; - } - - - verts[0] = v0->v; - verts[0].x -= ix; - verts[0].y -= iy; + GLcontext *ctx = fxMesa->glCtx; + SWvertex v[3]; + fx_translate_vertex( ctx, v0, &v[0] ); + fx_translate_vertex( ctx, v1, &v[1] ); + fx_translate_vertex( ctx, v2, &v[2] ); + _swrast_Triangle( ctx, &v[0], &v[1], &v[2] ); +} - verts[1] = v0->v; - verts[1].x += ix; - verts[1].y += iy; - verts[2] = v1->v; - verts[2].x += ix; - verts[2].y += iy; +static void +fx_fallback_line( fxMesaContext fxMesa, + GrVertex *v0, + GrVertex *v1 ) +{ + GLcontext *ctx = fxMesa->glCtx; + SWvertex v[2]; + fx_translate_vertex( ctx, v0, &v[0] ); + fx_translate_vertex( ctx, v1, &v[1] ); + _swrast_Line( ctx, &v[0], &v[1] ); +} - verts[3] = v1->v; - verts[3].x -= ix; - verts[3].y -= iy; - grDrawTriangle(&verts[0], &verts[1], &verts[3]); - grDrawTriangle(&verts[1], &verts[2], &verts[3]); - } +static void +fx_fallback_point( fxMesaContext fxMesa, + GrVertex *v0 ) +{ + GLcontext *ctx = fxMesa->glCtx; + SWvertex v[1]; + fx_translate_vertex( ctx, v0, &v[0] ); + _swrast_Point( ctx, &v[0] ); } -static void -fx_draw_tri(GLcontext * ctx, const fxVertex * v0, const fxVertex * v1, - const fxVertex * v2) +/*********************************************************************** + * Functions to draw basic primitives * + ***********************************************************************/ + +static void fx_print_vertex( GLcontext *ctx, const GrVertex *v ) { - grDrawTriangle(&(v0->v), &(v1->v), &(v2->v)); + fprintf(stderr, "vertex at %p\n", v); + + fprintf(stderr, "x %f y %f z %f oow %f\n", + v->x, v->y, v->ooz, v->oow); + fprintf(stderr, "r %f g %f b %f a %f\n", + v->r, + v->g, + v->b, + v->a); + + fprintf(stderr, "\n"); } +#define DO_FALLBACK 0 - -#define FX_COLOR(vert, c) { \ - GLfloat *col = c; \ - UNCLAMPED_FLOAT_TO_UBYTE(vert->v.r, col[0]); \ - UNCLAMPED_FLOAT_TO_UBYTE(vert->v.g, col[1]); \ - UNCLAMPED_FLOAT_TO_UBYTE(vert->v.b, col[2]); \ - UNCLAMPED_FLOAT_TO_UBYTE(vert->v.a, col[3]); \ +/* Need to do clip loop at each triangle when mixing swrast and hw + * rendering. These functions are only used when mixed-mode rendering + * is occurring. + */ +static void fx_draw_quad( fxMesaContext fxMesa, + GrVertex *v0, + GrVertex *v1, + GrVertex *v2, + GrVertex *v3 ) +{ + QUAD( v0, v1, v2, v3 ); } -#define FX_COPY_COLOR( dst, src ) { \ - dst->v.r = src->v.r; \ - dst->v.g = src->v.g; \ - dst->v.b = src->v.b; \ - dst->v.a = src->v.a; \ +static void fx_draw_triangle( fxMesaContext fxMesa, + GrVertex *v0, + GrVertex *v1, + GrVertex *v2 ) +{ + TRI( v0, v1, v2 ); } +static void fx_draw_line( fxMesaContext fxMesa, + GrVertex *v0, + GrVertex *v1 ) +{ + /* No support for wide lines (avoid wide/aa line fallback). + */ + LINE(v0, v1); +} - -#define FX_FLAT_BIT 0x01 -#define FX_OFFSET_BIT 0x02 -#define FX_TWOSIDE_BIT 0x04 -#define FX_UNFILLED_BIT 0x10 -#define FX_FALLBACK_BIT 0x20 -#define FX_MAX_TRIFUNC 0x40 - -static struct +static void fx_draw_point( fxMesaContext fxMesa, + GrVertex *v0 ) { - points_func points; - line_func line; - triangle_func triangle; - quad_func quad; + /* No support for wide points. + */ + POINT( v0 ); } -rast_tab[FX_MAX_TRIFUNC]; +#undef DO_FALLBACK + + +#define FX_UNFILLED_BIT 0x1 +#define FX_OFFSET_BIT 0x2 +#define FX_TWOSIDE_BIT 0x4 +#define FX_FLAT_BIT 0x8 +#define FX_FALLBACK_BIT 0x10 +#define FX_MAX_TRIFUNC 0x20 + +static struct { + points_func points; + line_func line; + triangle_func triangle; + quad_func quad; +} rast_tab[FX_MAX_TRIFUNC]; + +#define DO_FALLBACK (IND & FX_FALLBACK_BIT) +#define DO_OFFSET (IND & FX_OFFSET_BIT) +#define DO_UNFILLED (IND & FX_UNFILLED_BIT) +#define DO_TWOSIDE (IND & FX_TWOSIDE_BIT) +#define DO_FLAT (IND & FX_FLAT_BIT) +#define DO_TRI 1 +#define DO_QUAD 1 +#define DO_LINE 1 +#define DO_POINTS 1 +#define DO_FULL_QUAD 1 + +#define HAVE_RGBA 1 +#define HAVE_SPEC 0 +#define HAVE_HW_FLATSHADE 0 +#define HAVE_BACK_COLORS 0 +#define VERTEX GrVertex +#define TAB rast_tab + +#define DEPTH_SCALE 1.0 +#define UNFILLED_TRI unfilled_tri +#define UNFILLED_QUAD unfilled_quad +#define VERT_X(_v) _v->x +#define VERT_Y(_v) _v->y +#define VERT_Z(_v) _v->ooz +#define AREA_IS_CCW( a ) (a < 0) +#define GET_VERTEX(e) (fxMesa->verts + e) + +#define VERT_SET_RGBA( dst, f ) \ +do { \ + dst->r = CLAMP( f[0], 0, 1 ) * 255.0; \ + dst->g = CLAMP( f[1], 0, 1 ) * 255.0; \ + dst->b = CLAMP( f[2], 0, 1 ) * 255.0; \ + dst->a = CLAMP( f[3], 0, 1 ) * 255.0; \ +} while (0) + +#define VERT_COPY_RGBA( v0, v1 ) \ +do { \ + v0->r = v1->r; \ + v0->g = v1->g; \ + v0->b = v1->b; \ + v0->a = v1->a; \ +} while (0) + +#define VERT_SAVE_RGBA( idx ) \ +do { \ + color[idx][0] = v[idx]->r; \ + color[idx][1] = v[idx]->g; \ + color[idx][1] = v[idx]->b; \ + color[idx][3] = v[idx]->a; \ +} while (0) + + +#define VERT_RESTORE_RGBA( idx ) \ +do { \ + v[idx]->r = color[idx][0]; \ + v[idx]->g = color[idx][1]; \ + v[idx]->b = color[idx][2]; \ + v[idx]->a = color[idx][3]; \ +} while (0) + + +#define LOCAL_VARS(n) \ + fxMesaContext fxMesa = FX_CONTEXT(ctx); \ + GLfloat color[n][4]; \ + (void) color; + + + +/*********************************************************************** + * Functions to draw basic unfilled primitives * + ***********************************************************************/ + +#define RASTERIZE(x) if (fxMesa->raster_primitive != x) \ + fxRasterPrimitive( ctx, x ) +#define RENDER_PRIMITIVE fxMesa->render_primitive +#define IND FX_FALLBACK_BIT +#define TAG(x) x +#include "tnl_dd/t_dd_unfilled.h" +#undef IND + +/*********************************************************************** + * Functions to draw GL primitives * + ***********************************************************************/ #define IND (0) #define TAG(x) x -#include "fxtritmp.h" - -#define IND (FX_FLAT_BIT) -#define TAG(x) x##_flat -#include "fxtritmp.h" +#include "tnl_dd/t_dd_tritmp.h" #define IND (FX_OFFSET_BIT) #define TAG(x) x##_offset -#include "fxtritmp.h" - -#define IND (FX_OFFSET_BIT | FX_FLAT_BIT) -#define TAG(x) x##_offset_flat -#include "fxtritmp.h" +#include "tnl_dd/t_dd_tritmp.h" #define IND (FX_TWOSIDE_BIT) #define TAG(x) x##_twoside -#include "fxtritmp.h" - -#define IND (FX_TWOSIDE_BIT | FX_FLAT_BIT) -#define TAG(x) x##_twoside_flat -#include "fxtritmp.h" +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT) +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT) #define TAG(x) x##_twoside_offset -#include "fxtritmp.h" +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_FLAT_BIT) -#define TAG(x) x##_twoside_offset_flat -#include "fxtritmp.h" +#define IND (FX_UNFILLED_BIT) +#define TAG(x) x##_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT) +#define TAG(x) x##_offset_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT) +#define TAG(x) x##_twoside_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT) +#define TAG(x) x##_twoside_offset_unfilled +#include "tnl_dd/t_dd_tritmp.h" #define IND (FX_FALLBACK_BIT) #define TAG(x) x##_fallback -#include "fxtritmp.h" - -#define IND (FX_FLAT_BIT | FX_FALLBACK_BIT) -#define TAG(x) x##_flat_fallback -#include "fxtritmp.h" +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_OFFSET_BIT | FX_FALLBACK_BIT) +#define IND (FX_OFFSET_BIT|FX_FALLBACK_BIT) #define TAG(x) x##_offset_fallback -#include "fxtritmp.h" +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_OFFSET_BIT | FX_FLAT_BIT | FX_FALLBACK_BIT) -#define TAG(x) x##_offset_flat_fallback -#include "fxtritmp.h" - -#define IND (FX_TWOSIDE_BIT | FX_FALLBACK_BIT) +#define IND (FX_TWOSIDE_BIT|FX_FALLBACK_BIT) #define TAG(x) x##_twoside_fallback -#include "fxtritmp.h" - -#define IND (FX_TWOSIDE_BIT | FX_FLAT_BIT | FX_FALLBACK_BIT) -#define TAG(x) x##_twoside_flat_fallback -#include "fxtritmp.h" +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_FALLBACK_BIT) +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_FALLBACK_BIT) #define TAG(x) x##_twoside_offset_fallback -#include "fxtritmp.h" +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_FLAT_BIT | FX_FALLBACK_BIT) -#define TAG(x) x##_twoside_offset_flat_fallback -#include "fxtritmp.h" +#define IND (FX_UNFILLED_BIT|FX_FALLBACK_BIT) +#define TAG(x) x##_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_UNFILLED_BIT) -#define TAG(x) x##_unfilled -#include "fxtritmp.h" +#define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT) +#define TAG(x) x##_offset_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_FLAT_BIT | FX_UNFILLED_BIT) -#define TAG(x) x##_flat_unfilled -#include "fxtritmp.h" +#define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT) +#define TAG(x) x##_twoside_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_OFFSET_BIT | FX_UNFILLED_BIT) -#define TAG(x) x##_offset_unfilled -#include "fxtritmp.h" +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT| \ + FX_FALLBACK_BIT) +#define TAG(x) x##_twoside_offset_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_OFFSET_BIT | FX_FLAT_BIT | FX_UNFILLED_BIT) -#define TAG(x) x##_offset_flat_unfilled -#include "fxtritmp.h" -#define IND (FX_TWOSIDE_BIT | FX_UNFILLED_BIT) -#define TAG(x) x##_twoside_unfilled -#include "fxtritmp.h" +/* Fx doesn't support provoking-vertex flat-shading? + */ +#define IND (FX_FLAT_BIT) +#define TAG(x) x##_flat +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_TWOSIDE_BIT | FX_FLAT_BIT | FX_UNFILLED_BIT) -#define TAG(x) x##_twoside_flat_unfilled -#include "fxtritmp.h" +#define IND (FX_OFFSET_BIT|FX_FLAT_BIT) +#define TAG(x) x##_offset_flat +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_UNFILLED_BIT) -#define TAG(x) x##_twoside_offset_unfilled -#include "fxtritmp.h" +#define IND (FX_TWOSIDE_BIT|FX_FLAT_BIT) +#define TAG(x) x##_twoside_flat +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_FLAT_BIT | FX_UNFILLED_BIT) -#define TAG(x) x##_twoside_offset_flat_unfilled -#include "fxtritmp.h" +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_FLAT_BIT) +#define TAG(x) x##_twoside_offset_flat +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_FALLBACK_BIT | FX_UNFILLED_BIT) -#define TAG(x) x##_fallback_unfilled -#include "fxtritmp.h" +#define IND (FX_UNFILLED_BIT|FX_FLAT_BIT) +#define TAG(x) x##_unfilled_flat +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_FLAT_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT) -#define TAG(x) x##_flat_fallback_unfilled -#include "fxtritmp.h" +#define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FLAT_BIT) +#define TAG(x) x##_offset_unfilled_flat +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_OFFSET_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT) -#define TAG(x) x##_offset_fallback_unfilled -#include "fxtritmp.h" +#define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_FLAT_BIT) +#define TAG(x) x##_twoside_unfilled_flat +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_OFFSET_BIT | FX_FLAT_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT) -#define TAG(x) x##_offset_flat_fallback_unfilled -#include "fxtritmp.h" +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FLAT_BIT) +#define TAG(x) x##_twoside_offset_unfilled_flat +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_TWOSIDE_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT) -#define TAG(x) x##_twoside_fallback_unfilled -#include "fxtritmp.h" +#define IND (FX_FALLBACK_BIT|FX_FLAT_BIT) +#define TAG(x) x##_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_TWOSIDE_BIT | FX_FLAT_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT) -#define TAG(x) x##_twoside_flat_fallback_unfilled -#include "fxtritmp.h" +#define IND (FX_OFFSET_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT) +#define TAG(x) x##_offset_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT) -#define TAG(x) x##_twoside_offset_fallback_unfilled -#include "fxtritmp.h" +#define IND (FX_TWOSIDE_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT) +#define TAG(x) x##_twoside_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" -#define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_FLAT_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT) -#define TAG(x) x##_twoside_offset_flat_fallback_unfilled -#include "fxtritmp.h" +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT) +#define TAG(x) x##_twoside_offset_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" +#define IND (FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT) +#define TAG(x) x##_unfilled_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" +#define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT) +#define TAG(x) x##_offset_unfilled_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" +#define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT) +#define TAG(x) x##_twoside_unfilled_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT| \ + FX_FALLBACK_BIT|FX_FLAT_BIT) +#define TAG(x) x##_twoside_offset_unfilled_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" -void -fxDDTrifuncInit(void) +static void init_rast_tab( void ) { init(); - init_flat(); init_offset(); - init_offset_flat(); init_twoside(); - init_twoside_flat(); init_twoside_offset(); - init_twoside_offset_flat(); + init_unfilled(); + init_offset_unfilled(); + init_twoside_unfilled(); + init_twoside_offset_unfilled(); init_fallback(); - init_flat_fallback(); init_offset_fallback(); - init_offset_flat_fallback(); init_twoside_fallback(); - init_twoside_flat_fallback(); init_twoside_offset_fallback(); - init_twoside_offset_flat_fallback(); + init_unfilled_fallback(); + init_offset_unfilled_fallback(); + init_twoside_unfilled_fallback(); + init_twoside_offset_unfilled_fallback(); - init_unfilled(); - init_flat_unfilled(); - init_offset_unfilled(); - init_offset_flat_unfilled(); - init_twoside_unfilled(); - init_twoside_flat_unfilled(); - init_twoside_offset_unfilled(); - init_twoside_offset_flat_unfilled(); - init_fallback_unfilled(); - init_flat_fallback_unfilled(); - init_offset_fallback_unfilled(); - init_offset_flat_fallback_unfilled(); - init_twoside_fallback_unfilled(); - init_twoside_flat_fallback_unfilled(); - init_twoside_offset_fallback_unfilled(); - init_twoside_offset_flat_fallback_unfilled(); + init_flat(); + init_offset_flat(); + init_twoside_flat(); + init_twoside_offset_flat(); + init_unfilled_flat(); + init_offset_unfilled_flat(); + init_twoside_unfilled_flat(); + init_twoside_offset_unfilled_flat(); + init_fallback_flat(); + init_offset_fallback_flat(); + init_twoside_fallback_flat(); + init_twoside_offset_fallback_flat(); + init_unfilled_fallback_flat(); + init_offset_unfilled_fallback_flat(); + init_twoside_unfilled_fallback_flat(); + init_twoside_offset_unfilled_fallback_flat(); } -/* Build an SWvertex from a GrVertex. This is workable because in - * states where the GrVertex is insufficent (eg separate-specular), - * the driver initiates a total fallback, and builds SWvertices - * directly -- it recognizes that it will never have use for the - * GrVertex. - * - * This code is hit only when a mix of accelerated and unaccelerated - * primitives are being drawn, and only for the unaccelerated - * primitives. - */ -static void -fx_translate_vertex(GLcontext * ctx, const fxVertex * src, SWvertex * dst) -{ - fxMesaContext fxMesa = FX_CONTEXT(ctx); - GLuint ts0 = fxMesa->tmu_source[0]; - GLuint ts1 = fxMesa->tmu_source[1]; - GLfloat w = 1.0 / src->v.oow; - - dst->win[0] = src->v.x; - dst->win[1] = src->v.y; - dst->win[2] = src->v.ooz; - dst->win[3] = src->v.oow; - - dst->color[0] = (GLubyte) src->v.r; - dst->color[1] = (GLubyte) src->v.g; - dst->color[2] = (GLubyte) src->v.b; - dst->color[3] = (GLubyte) src->v.a; - - dst->texcoord[ts0][0] = fxMesa->inv_s0scale * src->v.tmuvtx[0].sow * w; - dst->texcoord[ts0][1] = fxMesa->inv_t0scale * src->v.tmuvtx[0].tow * w; - if (fxMesa->stw_hint_state & GR_STWHINT_W_DIFF_TMU0) - dst->texcoord[ts0][3] = src->v.tmuvtx[0].oow * w; - else - dst->texcoord[ts0][3] = 1.0; +/**********************************************************************/ +/* Render whole (indexed) begin/end objects */ +/**********************************************************************/ - dst->texcoord[ts1][0] = fxMesa->inv_s1scale * src->v.tmuvtx[1].sow * w; - dst->texcoord[ts1][1] = fxMesa->inv_t1scale * src->v.tmuvtx[1].tow * w; - if (fxMesa->stw_hint_state & GR_STWHINT_W_DIFF_TMU1) - dst->texcoord[ts1][3] = src->v.tmuvtx[1].oow * w; - else - dst->texcoord[ts1][3] = 1.0; -} +#define VERT(x) (vertptr + x) +#define RENDER_POINTS( start, count ) \ + for ( ; start < count ; start++) \ + grDrawPoint( VERT(ELT(start)) ); -static void -fx_fallback_tri(GLcontext * ctx, - const fxVertex * v0, const fxVertex * v1, const fxVertex * v2) -{ - SWvertex v[3]; - fx_translate_vertex(ctx, v0, &v[0]); - fx_translate_vertex(ctx, v1, &v[1]); - fx_translate_vertex(ctx, v2, &v[2]); - _swrast_Triangle(ctx, &v[0], &v[1], &v[2]); -} +#define RENDER_LINE( v0, v1 ) \ + grDrawLine( VERT(v0), VERT(v1) ) +#define RENDER_TRI( v0, v1, v2 ) \ + grDrawTriangle( VERT(v0), VERT(v1), VERT(v2) ) -static void -fx_fallback_line(GLcontext * ctx, const fxVertex * v0, const fxVertex * v1) -{ - SWvertex v[2]; - fx_translate_vertex(ctx, v0, &v[0]); - fx_translate_vertex(ctx, v1, &v[1]); - _swrast_Line(ctx, &v[0], &v[1]); -} +#define RENDER_QUAD( v0, v1, v2, v3 ) \ + fx_draw_quad( fxMesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) ) +#define INIT(x) fxRenderPrimitive( ctx, x ) -static void -fx_fallback_point(GLcontext * ctx, const fxVertex * v0) -{ - SWvertex v[1]; - fx_translate_vertex(ctx, v0, &v[0]); - _swrast_Point(ctx, &v[0]); -} +#undef LOCAL_VARS +#define LOCAL_VARS \ + fxMesaContext fxMesa = FX_CONTEXT(ctx); \ + GrVertex *vertptr = fxMesa->verts; \ + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \ + (void) elt; +#define RESET_STIPPLE +#define RESET_OCCLUSION +#define PRESERVE_VB_DEFS -/* System to turn culling off for rasterized lines and points, and - * back on for rasterized triangles. +/* Elts, no clipping. */ -static void -fx_cull_draw_tri(GLcontext * ctx, - const fxVertex * v0, const fxVertex * v1, - const fxVertex * v2) -{ - fxMesaContext fxMesa = FX_CONTEXT(ctx); - - FX_grCullMode(fxMesa->cullMode); - - fxMesa->draw_line = fxMesa->initial_line; - fxMesa->draw_point = fxMesa->initial_point; - fxMesa->draw_tri = fxMesa->subsequent_tri; - - fxMesa->draw_tri(ctx, v0, v1, v2); -} +#undef ELT +#undef TAG +#define TAG(x) fx_##x##_elts +#define ELT(x) elt[x] +#include "tnl_dd/t_dd_rendertmp.h" +/* Verts, no clipping. + */ +#undef ELT +#undef TAG +#define TAG(x) fx_##x##_verts +#define ELT(x) x +#include "tnl_dd/t_dd_rendertmp.h" -static void -fx_cull_draw_line(GLcontext * ctx, const fxVertex * v0, const fxVertex * v1) -{ - fxMesaContext fxMesa = FX_CONTEXT(ctx); - FX_grCullMode(GR_CULL_DISABLE); - fxMesa->draw_point = fxMesa->initial_point; - fxMesa->draw_tri = fxMesa->initial_tri; - fxMesa->draw_line = fxMesa->subsequent_line; +/**********************************************************************/ +/* Render clipped primitives */ +/**********************************************************************/ - fxMesa->draw_line(ctx, v0, v1); -} -static void -fx_cull_draw_point(GLcontext * ctx, const fxVertex * v0) +static void fxRenderClippedPoly( GLcontext *ctx, const GLuint *elts, + GLuint n ) { fxMesaContext fxMesa = FX_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint prim = fxMesa->render_primitive; + + /* Render the new vertices as an unclipped polygon. + */ + { + GLuint *tmp = VB->Elts; + VB->Elts = (GLuint *)elts; + tnl->Driver.Render.PrimTabElts[GL_POLYGON]( ctx, 0, n, + PRIM_BEGIN|PRIM_END ); + VB->Elts = tmp; + } - FX_grCullMode(GR_CULL_DISABLE); - - fxMesa->draw_line = fxMesa->initial_line; - fxMesa->draw_tri = fxMesa->initial_tri; - fxMesa->draw_point = fxMesa->subsequent_point; - - fxMesa->draw_point(ctx, v0); + /* Restore the render primitive + */ + if (prim != GL_POLYGON) + tnl->Driver.Render.PrimitiveNotify( ctx, prim ); } -static void -fx_null_tri(GLcontext * ctx, - const fxVertex * v0, const fxVertex * v1, const fxVertex * v2) +static void fxFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, + GLuint n ) { - (void) v0; - (void) v1; - (void) v2; + fxMesaContext fxMesa = FX_CONTEXT( ctx ); + GrVertex *vertptr = fxMesa->verts; + const GrVertex *start = VERT(elts[0]); + int i; + + for (i = 2 ; i < n ; i++) { + grDrawTriangle( start, VERT(elts[i-1]), VERT(elts[i]) ); + } } +/**********************************************************************/ +/* Choose render functions */ +/**********************************************************************/ +#define POINT_FALLBACK (DD_POINT_SMOOTH) +#define LINE_FALLBACK (DD_LINE_STIPPLE) +#define TRI_FALLBACK (DD_TRI_SMOOTH) +#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK|DD_TRI_STIPPLE) +#define ANY_RASTER_FLAGS (DD_FLATSHADE|DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET| \ + DD_TRI_UNFILLED) -/**********************************************************************/ -/* Render whole begin/end objects */ -/**********************************************************************/ -/* Vertices, no clipping. - */ -#define RENDER_POINTS( start, count ) \ - for ( ; start < count ; start++) \ - grDrawPoint( &v[ELT(start)].v ); +static void fxChooseRenderState(GLcontext *ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GLuint flags = ctx->_TriangleCaps; + GLuint index = 0; -#define RENDER_LINE( i1, i ) \ - grDrawLine( &v[i1].v, &v[i].v ) +/* fprintf(stderr, "%s\n", __FUNCTION__); */ -#define RENDER_TRI( i2, i1, i ) \ - grDrawTriangle( &v[i2].v, &v[i1].v, &v[i].v ) + if (flags & (ANY_FALLBACK_FLAGS|ANY_RASTER_FLAGS)) { + if (flags & ANY_RASTER_FLAGS) { + if (flags & DD_TRI_LIGHT_TWOSIDE) index |= FX_TWOSIDE_BIT; + if (flags & DD_TRI_OFFSET) index |= FX_OFFSET_BIT; + if (flags & DD_TRI_UNFILLED) index |= FX_UNFILLED_BIT; + if (flags & DD_FLATSHADE) index |= FX_FLAT_BIT; + } -#define RENDER_QUAD( i3, i2, i1, i ) \ - grDrawTriangle( &v[i3].v, &v[i2].v, &v[i].v ); \ - grDrawTriangle( &v[i2].v, &v[i1].v, &v[i].v ) + fxMesa->draw_point = fx_draw_point; + fxMesa->draw_line = fx_draw_line; + fxMesa->draw_tri = fx_draw_triangle; -#define TAG(x) fx_##x##_verts -#define LOCAL_VARS \ - fxVertex *v = FX_CONTEXT(ctx)->verts; \ - const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \ - (void) elt; + /* Hook in fallbacks for specific primitives. + * + * + */ + if (flags & (POINT_FALLBACK| + LINE_FALLBACK| + TRI_FALLBACK)) + { + if (flags & POINT_FALLBACK) + fxMesa->draw_point = fx_fallback_point; -/* Verts, no clipping. - */ -#define ELT(x) x -#define RESET_STIPPLE -#define RESET_OCCLUSION -#define PRESERVE_VB_DEFS -#include "tnl/t_vb_rendertmp.h" + if (flags & LINE_FALLBACK) + fxMesa->draw_line = fx_fallback_line; + if (flags & TRI_FALLBACK) + fxMesa->draw_tri = fx_fallback_tri; -/* Elts, no clipping. - */ -#undef ELT -#undef TAG -#define TAG(x) fx_##x##_elts -#define ELT(x) elt[x] -#include "tnl/t_vb_rendertmp.h" + index |= FX_FALLBACK_BIT; + } + } + tnl->Driver.Render.Points = rast_tab[index].points; + tnl->Driver.Render.Line = rast_tab[index].line; + tnl->Driver.Render.ClippedLine = rast_tab[index].line; + tnl->Driver.Render.Triangle = rast_tab[index].triangle; + tnl->Driver.Render.Quad = rast_tab[index].quad; + + if (index == 0) { + tnl->Driver.Render.PrimTabVerts = fx_render_tab_verts; + tnl->Driver.Render.PrimTabElts = fx_render_tab_elts; + tnl->Driver.Render.ClippedPolygon = fxFastRenderClippedPoly; + } else { + tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; + tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; + tnl->Driver.Render.ClippedPolygon = fxRenderClippedPoly; + } +} /**********************************************************************/ -/* Choose render functions */ +/* Runtime render state and callbacks */ /**********************************************************************/ +static GLenum reduced_prim[GL_POLYGON+1] = { + GL_POINTS, + GL_LINES, + GL_LINES, + GL_LINES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES +}; -#define POINT_FALLBACK (DD_POINT_SMOOTH ) -#define LINE_FALLBACK (DD_LINE_STIPPLE) -#define TRI_FALLBACK (DD_TRI_SMOOTH | DD_TRI_STIPPLE ) -#define ANY_FALLBACK (POINT_FALLBACK | LINE_FALLBACK | TRI_FALLBACK) +/* Always called between RenderStart and RenderFinish --> We already + * hold the lock. + */ +static void fxRasterPrimitive( GLcontext *ctx, GLenum prim ) +{ + fxMesaContext fxMesa = FX_CONTEXT( ctx ); -#define ANY_RENDER_FLAGS (DD_FLATSHADE | \ - DD_TRI_LIGHT_TWOSIDE | \ - DD_TRI_OFFSET | \ - DD_TRI_UNFILLED) + fxMesa->raster_primitive = prim; + if (prim == GL_TRIANGLES) + grCullMode( fxMesa->cullMode ); + else + grCullMode( GR_CULL_DISABLE ); +} -/* Setup the Point, Line, Triangle and Quad functions based on the - * current rendering state. Wherever possible, use the hardware to - * render the primitive. Otherwise, fallback to software rendering. +/* Determine the rasterized primitive when not drawing unfilled + * polygons. */ -void -fxDDChooseRenderState(GLcontext * ctx) +static void fxRenderPrimitive( GLcontext *ctx, GLenum prim ) { - TNLcontext *tnl = TNL_CONTEXT(ctx); fxMesaContext fxMesa = FX_CONTEXT(ctx); - GLuint flags = ctx->_TriangleCaps; - GLuint index = 0; + GLuint rprim = reduced_prim[prim]; - if (!fxMesa->is_in_hardware) { - /* Build software vertices directly. No acceleration is - * possible. GrVertices may be insufficient for this mode. - */ - tnl->Driver.PointsFunc = _swsetup_Points; - tnl->Driver.LineFunc = _swsetup_Line; - tnl->Driver.TriangleFunc = _swsetup_Triangle; - tnl->Driver.QuadFunc = _swsetup_Quad; - tnl->Driver.RenderTabVerts = _tnl_render_tab_verts; - tnl->Driver.RenderTabElts = _tnl_render_tab_elts; - - fxMesa->render_index = FX_FALLBACK_BIT; - return; - } + fxMesa->render_primitive = prim; - if (flags & ANY_RENDER_FLAGS) { - if (flags & DD_FLATSHADE) - index |= FX_FLAT_BIT; - if (flags & DD_TRI_LIGHT_TWOSIDE) - index |= FX_TWOSIDE_BIT; - if (flags & DD_TRI_OFFSET) - index |= FX_OFFSET_BIT; - if (flags & DD_TRI_UNFILLED) - index |= FX_UNFILLED_BIT; + if (rprim == GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED)) + return; + + if (fxMesa->raster_primitive != rprim) { + fxRasterPrimitive( ctx, rprim ); } +} - if (flags & (ANY_FALLBACK | - DD_LINE_WIDTH | DD_POINT_SIZE | DD_TRI_CULL_FRONT_BACK)) { - - /* Hook in fallbacks for specific primitives. - - * Set up a system to turn culling on/off for wide points and - * lines. Alternately: figure out what tris to send so that - * culling isn't a problem. - * - * This replaces the ReducedPrimitiveChange mechanism. - */ - index |= FX_FALLBACK_BIT; - fxMesa->initial_point = fx_cull_draw_point; - fxMesa->initial_line = fx_cull_draw_line; - fxMesa->initial_tri = fx_cull_draw_tri; - - fxMesa->subsequent_point = fx_draw_point; - fxMesa->subsequent_line = fx_draw_line; - fxMesa->subsequent_tri = fx_draw_tri; - - if (flags & POINT_FALLBACK) - fxMesa->initial_point = fx_fallback_point; - - if (flags & LINE_FALLBACK) - fxMesa->initial_line = fx_fallback_line; - if ((flags & DD_LINE_SMOOTH) && ctx->Line.Width != 1.0) - fxMesa->initial_line = fx_fallback_line; - if (flags & TRI_FALLBACK) - fxMesa->initial_tri = fx_fallback_tri; +/**********************************************************************/ +/* Manage total rasterization fallbacks */ +/**********************************************************************/ - if (flags & DD_TRI_CULL_FRONT_BACK) - fxMesa->initial_tri = fx_null_tri; - fxMesa->draw_point = fxMesa->initial_point; - fxMesa->draw_line = fxMesa->initial_line; - fxMesa->draw_tri = fxMesa->initial_tri; - } - else if (fxMesa->render_index & FX_FALLBACK_BIT) { - FX_grCullMode(fxMesa->cullMode); - } +void fxCheckIsInHardware( GLcontext *ctx ) +{ + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint oldfallback = !fxMesa->is_in_hardware; + GLuint newfallback; - tnl->Driver.PointsFunc = rast_tab[index].points; - tnl->Driver.LineFunc = rast_tab[index].line; - tnl->Driver.TriangleFunc = rast_tab[index].triangle; - tnl->Driver.QuadFunc = rast_tab[index].quad; - fxMesa->render_index = index; + fxMesa->is_in_hardware = check_IsInHardware( ctx ); + newfallback = !fxMesa->is_in_hardware; - if (fxMesa->render_index == 0) { - tnl->Driver.RenderTabVerts = fx_render_tab_verts; - tnl->Driver.RenderTabElts = fx_render_tab_elts; + if (newfallback) { + if (oldfallback == 0) { + _swsetup_Wakeup( ctx ); + } } else { - tnl->Driver.RenderTabVerts = _tnl_render_tab_verts; - tnl->Driver.RenderTabElts = _tnl_render_tab_elts; + if (oldfallback) { + _swrast_flush( ctx ); + tnl->Driver.Render.Start = fxCheckTexSizes; + tnl->Driver.Render.Finish = _swrast_flush; + tnl->Driver.Render.PrimitiveNotify = fxRenderPrimitive; + tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; + tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine; + tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; + tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; + tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple; + tnl->Driver.Render.BuildVertices = fxBuildVertices; + tnl->Driver.Render.Multipass = 0; + fxDDChooseSetupState(ctx); + fxDDChooseRenderState(ctx); + } } } +void fxDDInitTriFuncs( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + fxMesaContext fxMesa = FX_CONTEXT(ctx); + static int firsttime = 1; + if (firsttime) { + init_rast_tab(); + firsttime = 0; + } - -#else - - -/* - * Need this to provide at least one external definition. - */ - -extern int gl_fx_dummy_function_trifuncs(void); -int -gl_fx_dummy_function_trifuncs(void) -{ - return 0; + tnl->Driver.Render.Start = fxCheckTexSizes; + tnl->Driver.Render.Finish = _swrast_flush; + tnl->Driver.Render.PrimitiveNotify = fxRenderPrimitive; + tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; + tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine; + tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; + tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; + tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple; + tnl->Driver.Render.BuildVertices = fxBuildVertices; + tnl->Driver.Render.Multipass = 0; + + (void) fx_print_vertex; } - -#endif /* FX */ diff --git a/src/mesa/drivers/glide/fxvb.c b/src/mesa/drivers/glide/fxvb.c index e38d3c3cdd..9468d83e3b 100644 --- a/src/mesa/drivers/glide/fxvb.c +++ b/src/mesa/drivers/glide/fxvb.c @@ -1,9 +1,6 @@ - /* - * Mesa 3-D graphics library - * Version: 3.3 - * - * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. + * GLX Hardware Device Driver for Intel i810 + * Copyright (C) 1999 Keith Whitwell * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -18,400 +15,379 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the - * terms stated above. * - * Author: - * Keith Whitwell <keith@precisioninsight.com> */ - - -/* fxvsetup.c - 3Dfx VooDoo vertices setup functions */ - - -#ifdef HAVE_CONFIG_H -#include "conf.h" -#endif - -#if defined(FX) - -#include "fxdrv.h" +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfxvb.c,v 1.7 2000/11/08 05:02:43 dawes Exp $ */ + +#include "glheader.h" +#include "mtypes.h" +#include "mem.h" +#include "macros.h" +#include "colormac.h" #include "mmath.h" + +#include "math/m_translate.h" #include "swrast_setup/swrast_setup.h" +#include "tnl/tnl.h" #include "tnl/t_context.h" -#include "tnl/t_pipeline.h" + +#include "fxdrv.h" -void -fxPrintSetupFlags(const char *msg, GLuint flags) +static void copy_pv( GLcontext *ctx, GLuint edst, GLuint esrc ) { - fprintf(stderr, "%s: %d %s%s%s%s%s\n", - msg, - flags, - (flags & SETUP_XYZW) ? " xyzw," : "", - (flags & SETUP_SNAP) ? " snap," : "", - (flags & SETUP_RGBA) ? " rgba," : "", - (flags & SETUP_TMU0) ? " tmu0," : "", - (flags & SETUP_TMU1) ? " tmu1," : ""); + fxMesaContext fxMesa = FX_CONTEXT( ctx ); + GrVertex *dst = fxMesa->verts + edst; + GrVertex *src = fxMesa->verts + esrc; + + dst->r = src->r; + dst->g = src->g; + dst->b = src->b; + dst->a = src->a; } -static void -project_texcoords(fxVertex * v, - struct vertex_buffer *VB, - GLuint tmu_nr, GLuint tc_nr, GLuint start, GLuint count) +typedef void (*emit_func)( GLcontext *, GLuint, GLuint, void * ); + +static struct { + emit_func emit; + interp_func interp; + GLboolean (*check_tex_sizes)( GLcontext *ctx ); + GLuint vertex_format; +} setup_tab[MAX_SETUP]; + + +static void import_float_colors( GLcontext *ctx ) { - GrTmuVertex *tmu = &(v->v.tmuvtx[tmu_nr]); - GLvector4f *vec = VB->TexCoordPtr[tc_nr]; + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + struct gl_client_array *from = VB->ColorPtr[0]; + struct gl_client_array *to = &FX_CONTEXT(ctx)->UbyteColor; + GLuint count = VB->Count; - GLuint i; - GLuint stride = vec->stride; - GLfloat *data = VEC_ELT(vec, GLfloat, start); + if (!to->Ptr) { + to->Ptr = ALIGN_MALLOC( VB->Size * 4 * sizeof(GLubyte), 32 ); + to->Type = GL_UNSIGNED_BYTE; + } - for (i = start; i < count; i++, STRIDE_F(data, stride), v++) { - tmu->oow = v->v.oow * data[3]; - tmu = (GrTmuVertex *) ((char *) tmu + sizeof(fxVertex)); + /* No need to transform the same value 3000 times. + */ + if (!from->StrideB) { + to->StrideB = 0; + count = 1; } + else + to->StrideB = 4 * sizeof(GLubyte); + + _math_trans_4ub( (GLubyte (*)[4]) to->Ptr, + from->Ptr, + from->StrideB, + from->Type, + from->Size, + 0, + count); + + VB->ColorPtr[0] = to; } -static void -copy_w(fxVertex * v, - struct vertex_buffer *VB, GLuint tmu_nr, GLuint start, GLuint count) -{ - GrTmuVertex *tmu = &(v->v.tmuvtx[tmu_nr]); - GLuint i; +#define GET_COLOR(ptr, idx) (((GLfloat (*)[4])((ptr)->Ptr))[idx]) - for (i = start; i < count; i++, v++) { - tmu->oow = v->v.oow; - tmu = (GrTmuVertex *) ((char *) tmu + sizeof(fxVertex)); - } -} -/* need to compute W values for fogging purposes - */ -static void -fx_fake_fog_w(GLcontext * ctx, - fxVertex * verts, - struct vertex_buffer *VB, GLuint start, GLuint end) +static void interp_extras( GLcontext *ctx, + GLfloat t, + GLuint dst, GLuint out, GLuint in, + GLboolean force_boundary ) { - const GLfloat m10 = ctx->ProjectionMatrix.m[10]; - const GLfloat m14 = ctx->ProjectionMatrix.m[14]; - GLfloat(*clip)[4] = VB->ClipPtr->data; - GLubyte *clipmask = VB->ClipMask; - GLuint i; - - for (i = start; i < end; i++) { - if (clipmask[i] == 0) { - verts[i].v.oow = -m10 / (clip[i][2] - m14); /* -1/zEye */ + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + + /*fprintf(stderr, "%s\n", __FUNCTION__);*/ + + if (VB->ColorPtr[1]) { + INTERP_4F( t, + GET_COLOR(VB->ColorPtr[1], dst), + GET_COLOR(VB->ColorPtr[1], out), + GET_COLOR(VB->ColorPtr[1], in) ); + + if (VB->SecondaryColorPtr[1]) { + INTERP_3F( t, + GET_COLOR(VB->SecondaryColorPtr[1], dst), + GET_COLOR(VB->SecondaryColorPtr[1], out), + GET_COLOR(VB->SecondaryColorPtr[1], in) ); } } -} + if (VB->EdgeFlag) { + VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary; + } + setup_tab[FX_CONTEXT(ctx)->SetupIndex].interp(ctx, t, dst, out, in, + force_boundary); +} -static tfxSetupFunc setupfuncs[MAX_SETUP]; +static void copy_pv_extras( GLcontext *ctx, GLuint dst, GLuint src ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + if (VB->ColorPtr[1]) { + COPY_4FV( GET_COLOR(VB->ColorPtr[1], dst), + GET_COLOR(VB->ColorPtr[1], src) ); -#define IND (SETUP_XYZW) -#define INPUTS (VERT_CLIP) -#define NAME fxsetupXYZW -#include "fxvbtmp.h" + if (VB->SecondaryColorPtr[1]) { + COPY_4FV( GET_COLOR(VB->SecondaryColorPtr[1], dst), + GET_COLOR(VB->SecondaryColorPtr[1], src) ); + } + } -#define IND (SETUP_XYZW|SETUP_RGBA) -#define INPUTS (VERT_CLIP|VERT_RGBA) -#define NAME fxsetupXYZWRGBA -#include "fxvbtmp.h" + copy_pv(ctx, dst, src); +} -#define IND (SETUP_XYZW|SETUP_TMU0) -#define INPUTS (VERT_CLIP|VERT_TEX_ANY) -#define NAME fxsetupXYZWT0 -#include "fxvbtmp.h" -#define IND (SETUP_XYZW|SETUP_TMU1) -#define INPUTS (VERT_CLIP|VERT_TEX_ANY) -#define NAME fxsetupXYZWT1 +#define IND (SETUP_XYZW|SETUP_RGBA) +#define TAG(x) x##_wg #include "fxvbtmp.h" -#define IND (SETUP_XYZW|SETUP_TMU1|SETUP_TMU0) -#define INPUTS (VERT_CLIP|VERT_TEX_ANY) -#define NAME fxsetupXYZWT0T1 +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0) +#define TAG(x) x##_wgt0 #include "fxvbtmp.h" -#define IND (SETUP_XYZW|SETUP_TMU0|SETUP_RGBA) -#define INPUTS (VERT_CLIP|VERT_RGBA|VERT_TEX_ANY) -#define NAME fxsetupXYZWRGBAT0 +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_TMU1) +#define TAG(x) x##_wgt0t1 #include "fxvbtmp.h" -#define IND (SETUP_XYZW|SETUP_TMU1|SETUP_RGBA) -#define INPUTS (VERT_CLIP|VERT_RGBA|VERT_TEX_ANY) -#define NAME fxsetupXYZWRGBAT1 +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_PTEX) +#define TAG(x) x##_wgpt0 #include "fxvbtmp.h" -#define IND (SETUP_XYZW|SETUP_TMU1|SETUP_TMU0|SETUP_RGBA) -#define INPUTS (VERT_CLIP|VERT_RGBA|VERT_TEX_ANY) -#define NAME fxsetupXYZWRGBAT0T1 +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_TMU1|\ + SETUP_PTEX) +#define TAG(x) x##_wgpt0t1 #include "fxvbtmp.h" -#define IND (SETUP_XYZW|SETUP_SNAP) -#define INPUTS (VERT_CLIP) -#define NAME fxsetupXYZW_SNAP -#include "fxvbtmp.h" - +/* Snapping for voodoo-1 + */ #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA) -#define INPUTS (VERT_CLIP|VERT_RGBA) -#define NAME fxsetupXYZW_SNAP_RGBA -#include "fxvbtmp.h" - -#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_TMU0) -#define INPUTS (VERT_CLIP|VERT_TEX_ANY) -#define NAME fxsetupXYZW_SNAP_T0 +#define TAG(x) x##_wsg #include "fxvbtmp.h" -#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_TMU1) -#define INPUTS (VERT_CLIP|VERT_TEX_ANY) -#define NAME fxsetupXYZW_SNAP_T1 +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0) +#define TAG(x) x##_wsgt0 #include "fxvbtmp.h" -#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_TMU1|SETUP_TMU0) -#define INPUTS (VERT_CLIP|VERT_TEX_ANY) -#define NAME fxsetupXYZW_SNAP_T0T1 +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\ + SETUP_TMU1) +#define TAG(x) x##_wsgt0t1 #include "fxvbtmp.h" -#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_TMU0|SETUP_RGBA) -#define INPUTS (VERT_CLIP|VERT_RGBA|VERT_TEX_ANY) -#define NAME fxsetupXYZW_SNAP_RGBAT0 +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\ + SETUP_PTEX) +#define TAG(x) x##_wsgpt0 #include "fxvbtmp.h" -#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_TMU1|SETUP_RGBA) -#define INPUTS (VERT_CLIP|VERT_RGBA|VERT_TEX_ANY) -#define NAME fxsetupXYZW_SNAP_RGBAT1 +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\ + SETUP_TMU1|SETUP_PTEX) +#define TAG(x) x##_wsgpt0t1 #include "fxvbtmp.h" -#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_TMU1|SETUP_TMU0|SETUP_RGBA) -#define INPUTS (VERT_CLIP|VERT_RGBA|VERT_TEX_ANY) -#define NAME fxsetupXYZW_SNAP_RGBAT0T1 -#include "fxvbtmp.h" - - +/* Vertex repair (multipass rendering) + */ #define IND (SETUP_RGBA) -#define INPUTS (VERT_RGBA) -#define NAME fxsetupRGBA +#define TAG(x) x##_g #include "fxvbtmp.h" #define IND (SETUP_TMU0) -#define INPUTS (VERT_TEX_ANY) -#define NAME fxsetupT0 -#include "fxvbtmp.h" - -#define IND (SETUP_TMU1) -#define INPUTS (VERT_TEX_ANY) -#define NAME fxsetupT1 +#define TAG(x) x##_t0 #include "fxvbtmp.h" -#define IND (SETUP_TMU1|SETUP_TMU0) -#define INPUTS (VERT_TEX_ANY) -#define NAME fxsetupT0T1 +#define IND (SETUP_TMU0|SETUP_TMU1) +#define TAG(x) x##_t0t1 #include "fxvbtmp.h" -#define IND (SETUP_TMU0|SETUP_RGBA) -#define INPUTS (VERT_RGBA|VERT_TEX_ANY) -#define NAME fxsetupRGBAT0 +#define IND (SETUP_RGBA|SETUP_TMU0) +#define TAG(x) x##_gt0 #include "fxvbtmp.h" -#define IND (SETUP_TMU1|SETUP_RGBA) -#define INPUTS (VERT_RGBA|VERT_TEX_ANY) -#define NAME fxsetupRGBAT1 +#define IND (SETUP_RGBA|SETUP_TMU0|SETUP_TMU1) +#define TAG(x) x##_gt0t1 #include "fxvbtmp.h" -#define IND (SETUP_TMU1|SETUP_TMU0|SETUP_RGBA) -#define INPUTS (VERT_RGBA|VERT_TEX_ANY) -#define NAME fxsetupRGBAT0T1 -#include "fxvbtmp.h" -static void -fxsetup_invalid(GLcontext * ctx, GLuint start, GLuint end) +static void init_setup_tab( void ) { - fprintf(stderr, "fxMesa: invalid setup function\n"); - (void) (ctx && start && end); + init_wg(); + init_wgt0(); + init_wgt0t1(); + init_wgpt0(); + init_wgpt0t1(); + + init_wsg(); + init_wsgt0(); + init_wsgt0t1(); + init_wsgpt0(); + init_wsgpt0t1(); + + init_g(); + init_t0(); + init_t0t1(); + init_gt0(); + init_gt0t1(); } -void -fxDDSetupInit(void) +void fxPrintSetupFlags(char *msg, GLuint flags ) { - GLuint i; - for (i = 0; i < Elements(setupfuncs); i++) - setupfuncs[i] = fxsetup_invalid; - - setupfuncs[SETUP_XYZW] = fxsetupXYZW; - setupfuncs[SETUP_XYZW | SETUP_RGBA] = fxsetupXYZWRGBA; - setupfuncs[SETUP_XYZW | SETUP_TMU0] = fxsetupXYZWT0; - setupfuncs[SETUP_XYZW | SETUP_TMU1] = fxsetupXYZWT1; - setupfuncs[SETUP_XYZW | SETUP_TMU0 | SETUP_RGBA] = fxsetupXYZWRGBAT0; - setupfuncs[SETUP_XYZW | SETUP_TMU1 | SETUP_RGBA] = fxsetupXYZWRGBAT1; - setupfuncs[SETUP_XYZW | SETUP_TMU1 | SETUP_TMU0] = fxsetupXYZWT0T1; - setupfuncs[SETUP_XYZW | SETUP_TMU1 | SETUP_TMU0 | SETUP_RGBA] = - fxsetupXYZWRGBAT0T1; - - setupfuncs[SETUP_XYZW | SETUP_SNAP] = fxsetupXYZW_SNAP; - setupfuncs[SETUP_XYZW | SETUP_SNAP | SETUP_RGBA] = fxsetupXYZW_SNAP_RGBA; - setupfuncs[SETUP_XYZW | SETUP_SNAP | SETUP_TMU0] = fxsetupXYZW_SNAP_T0; - setupfuncs[SETUP_XYZW | SETUP_SNAP | SETUP_TMU1] = fxsetupXYZW_SNAP_T1; - setupfuncs[SETUP_XYZW | SETUP_SNAP | SETUP_TMU0 | SETUP_RGBA] = - fxsetupXYZW_SNAP_RGBAT0; - setupfuncs[SETUP_XYZW | SETUP_SNAP | SETUP_TMU1 | SETUP_RGBA] = - fxsetupXYZW_SNAP_RGBAT1; - setupfuncs[SETUP_XYZW | SETUP_SNAP | SETUP_TMU1 | SETUP_TMU0] = - fxsetupXYZW_SNAP_T0T1; - setupfuncs[SETUP_XYZW | SETUP_SNAP | SETUP_TMU1 | SETUP_TMU0 | SETUP_RGBA] - = fxsetupXYZW_SNAP_RGBAT0T1; - - setupfuncs[SETUP_RGBA] = fxsetupRGBA; - setupfuncs[SETUP_TMU0] = fxsetupT0; - setupfuncs[SETUP_TMU1] = fxsetupT1; - setupfuncs[SETUP_TMU1 | SETUP_TMU0] = fxsetupT0T1; - setupfuncs[SETUP_TMU0 | SETUP_RGBA] = fxsetupRGBAT0; - setupfuncs[SETUP_TMU1 | SETUP_RGBA] = fxsetupRGBAT1; - setupfuncs[SETUP_TMU1 | SETUP_TMU0 | SETUP_RGBA] = fxsetupRGBAT0T1; + fprintf(stderr, "%s(%x): %s%s%s%s\n", + msg, + (int)flags, + (flags & SETUP_XYZW) ? " xyzw," : "", + (flags & SETUP_SNAP) ? " snap," : "", + (flags & SETUP_RGBA) ? " rgba," : "", + (flags & SETUP_TMU0) ? " tex-0," : "", + (flags & SETUP_TMU1) ? " tex-1," : ""); } -void -fx_validate_BuildProjVerts(GLcontext * ctx, GLuint start, GLuint count, - GLuint newinputs) +void fxCheckTexSizes( GLcontext *ctx ) { TNLcontext *tnl = TNL_CONTEXT(ctx); - fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; - - if (!fxMesa->is_in_hardware) - tnl->Driver.BuildProjectedVertices = _swsetup_BuildProjectedVertices; - else { - GLuint setupindex = SETUP_XYZW; + fxMesaContext fxMesa = FX_CONTEXT( ctx ); - if (fxMesa->snapVertices) - setupindex |= SETUP_SNAP; + if (!setup_tab[fxMesa->SetupIndex].check_tex_sizes(ctx)) { + GLuint ind = fxMesa->SetupIndex |= (SETUP_PTEX|SETUP_RGBA); - fxMesa->tmu_source[0] = 0; - fxMesa->tmu_source[1] = 1; - fxMesa->tex_dest[0] = SETUP_TMU0; - fxMesa->tex_dest[1] = SETUP_TMU1; - - /* For flat and two-side-lit triangles, colors will always be added - * to vertices in the triangle functions. Vertices will *always* - * have rbga values, but only sometimes will they come from here. + /* Tdfx handles projective textures nicely; just have to change + * up to the new vertex format. */ - if ((ctx->_TriangleCaps & (DD_FLATSHADE | DD_TRI_LIGHT_TWOSIDE)) == 0) - setupindex |= SETUP_RGBA; - - if (ctx->Texture._ReallyEnabled & TEXTURE0_2D) - setupindex |= SETUP_TMU0; - - if (ctx->Texture._ReallyEnabled & TEXTURE1_2D) { - if ((ctx->Texture._ReallyEnabled & TEXTURE0_2D) == 0) { - fxMesa->tmu_source[0] = 1; - fxMesa->tex_dest[0] = SETUP_TMU1; - fxMesa->tmu_source[1] = 0; - fxMesa->tex_dest[1] = SETUP_TMU0; - setupindex |= SETUP_TMU0; - } - else { - setupindex |= SETUP_TMU1; + if (setup_tab[ind].vertex_format != fxMesa->stw_hint_state) { + + fxMesa->stw_hint_state = setup_tab[ind].vertex_format; + FX_grHints(GR_HINT_STWHINT, fxMesa->stw_hint_state); + + /* This is required as we have just changed the vertex + * format, so the interp routines must also change. + * In the unfilled and twosided cases we are using the + * Extras ones anyway, so leave them in place. + */ + if (!(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) { + tnl->Driver.Render.Interp = setup_tab[fxMesa->SetupIndex].interp; } } - - if (MESA_VERBOSE & (VERBOSE_DRIVER | VERBOSE_PIPELINE | VERBOSE_STATE)) - fxPrintSetupFlags("fxmesa: vertex setup function", setupindex); - - fxMesa->setupindex = setupindex; - tnl->Driver.BuildProjectedVertices = fx_BuildProjVerts; } - tnl->Driver.BuildProjectedVertices(ctx, start, count, newinputs); } -void -fx_BuildProjVerts(GLcontext * ctx, GLuint start, GLuint count, - GLuint newinputs) +void fxBuildVertices( GLcontext *ctx, GLuint start, GLuint count, + GLuint newinputs ) { - fxMesaContext fxMesa = FX_CONTEXT(ctx); - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + fxMesaContext fxMesa = FX_CONTEXT( ctx ); + GrVertex *v = (fxMesa->verts + start); - if (newinputs == ~0) { - /* build interpolated vertices */ - setupfuncs[fxMesa->setupindex] (ctx, start, count); - } - else { - GLuint ind = fxMesa->setup_gone; - fxMesa->setup_gone = 0; - - if (newinputs & VERT_CLIP) - ind = fxMesa->setupindex; /* clipmask has potentially changed */ - else { - if (newinputs & VERT_TEX0) - ind |= fxMesa->tex_dest[0]; + if (!newinputs) + return; - if (newinputs & VERT_TEX1) - ind |= fxMesa->tex_dest[1]; + if (newinputs & VERT_CLIP) { + setup_tab[fxMesa->SetupIndex].emit( ctx, start, count, v ); + } else { + GLuint ind = 0; - if (newinputs & VERT_RGBA) - ind |= SETUP_RGBA; + if (newinputs & VERT_RGBA) + ind |= SETUP_RGBA; + + if (newinputs & VERT_TEX0) + ind |= SETUP_TMU0; - ind &= fxMesa->setupindex; - } + if (newinputs & VERT_TEX1) + ind |= SETUP_TMU0|SETUP_TMU1; - if (ind) { - if (fxMesa->new_state) - fxSetupFXUnits(ctx); /* why? */ + if (fxMesa->SetupIndex & SETUP_PTEX) + ind = ~0; - if (VB->importable_data & newinputs) - VB->import_data(ctx, VB->importable_data & newinputs, - VEC_BAD_STRIDE); + ind &= fxMesa->SetupIndex; - setupfuncs[ind] (ctx, start, count); + if (ind) { + setup_tab[ind].emit( ctx, start, count, v ); } } } -void -fxAllocVB(GLcontext * ctx) + +void fxChooseVertexState( GLcontext *ctx ) { - fxMesaContext fxMesa = FX_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); - fxMesa->verts = ALIGN_MALLOC(tnl->vb.Size * sizeof(fxMesa->verts[0]), 32); -} + fxMesaContext fxMesa = FX_CONTEXT( ctx ); + GLuint ind = SETUP_XYZW|SETUP_RGBA; -void -fxFreeVB(GLcontext * ctx) -{ - fxMesaContext fxMesa = FX_CONTEXT(ctx); - if (fxMesa->verts) - ALIGN_FREE(fxMesa->verts); - fxMesa->verts = 0; -} + if (fxMesa->snapVertices) + ind |= SETUP_SNAP; + + fxMesa->tmu_source[0] = 0; + fxMesa->tmu_source[1] = 1; + if (ctx->Texture._ReallyEnabled & 0xf0) { + if (ctx->Texture._ReallyEnabled & 0xf) { + ind |= SETUP_TMU1|SETUP_TMU0; + } + else { + fxMesa->tmu_source[0] = 1; + fxMesa->tmu_source[1] = 0; + ind |= SETUP_TMU0; + } + } + else if (ctx->Texture._ReallyEnabled & 0xf) { + ind |= SETUP_TMU0; + } + + fxMesa->SetupIndex = ind; + + if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) { + tnl->Driver.Render.Interp = interp_extras; + tnl->Driver.Render.CopyPV = copy_pv_extras; + } else { + tnl->Driver.Render.Interp = setup_tab[ind].interp; + tnl->Driver.Render.CopyPV = copy_pv; + } -#else + if (setup_tab[ind].vertex_format != fxMesa->stw_hint_state) { + fxMesa->stw_hint_state = setup_tab[ind].vertex_format; + FX_grHints(GR_HINT_STWHINT, fxMesa->stw_hint_state); + } +} -/* - * Need this to provide at least one external definition. - */ -extern int gl_fx_dummy_function_vsetup(void); -int -gl_fx_dummy_function_vsetup(void) +void fxAllocVB( GLcontext *ctx ) { - return 0; + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GLuint size = TNL_CONTEXT(ctx)->vb.Size; + static int firsttime = 1; + if (firsttime) { + init_setup_tab(); + firsttime = 0; + } + + fxMesa->verts = (GrVertex *)ALIGN_MALLOC(size * sizeof(GrVertex), 32); + fxMesa->SetupIndex = SETUP_XYZW|SETUP_RGBA; } -#endif /* FX */ + +void fxFreeVB( GLcontext *ctx ) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + if (fxMesa->verts) { + ALIGN_FREE(fxMesa->verts); + fxMesa->verts = 0; + } + + if (fxMesa->UbyteColor.Ptr) { + ALIGN_FREE(fxMesa->UbyteColor.Ptr); + fxMesa->UbyteColor.Ptr = 0; + } +} diff --git a/src/mesa/drivers/glide/fxvbtmp.h b/src/mesa/drivers/glide/fxvbtmp.h index 24d5b521a0..570e7adf16 100644 --- a/src/mesa/drivers/glide/fxvbtmp.h +++ b/src/mesa/drivers/glide/fxvbtmp.h @@ -1,181 +1,277 @@ -/* - * Mesa 3-D graphics library - * Version: 3.3 - * - * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Author: - * Keith Whitwell <keith@precisioninsight.com> - */ - - -static void -NAME(GLcontext * ctx, GLuint start, GLuint end) +static void TAG(emit)( GLcontext *ctx, + GLuint start, GLuint end, + void *dest ) { - fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; - fxVertex *verts = fxMesa->verts; + fxMesaContext fxMesa = FX_CONTEXT(ctx); struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; GLuint tmu0_source = fxMesa->tmu_source[0]; GLuint tmu1_source = fxMesa->tmu_source[1]; - GLfloat (*tmu0_data)[4]; - GLfloat (*tmu1_data)[4]; - GLfloat (*color)[4]; - GLfloat (*proj)[4] = VB->ProjectedClipPtr->data; - fxVertex *v = &verts[start]; - GLfloat sscale0 = fxMesa->s0scale; - GLfloat tscale0 = fxMesa->t0scale; - GLfloat sscale1 = fxMesa->s1scale; - GLfloat tscale1 = fxMesa->t1scale; - GLubyte *clipmask = VB->ClipMask; - GLuint i; + GLfloat (*tc0)[4], (*tc1)[4]; + GLubyte (*col)[4]; + GLuint tc0_stride, tc1_stride, col_stride; + GLuint tc0_size, tc1_size; + GLfloat (*proj)[4] = VB->ProjectedClipPtr->data; + GLuint proj_stride = VB->ProjectedClipPtr->stride; + GrVertex *v = (GrVertex *)dest; + GLfloat u0scale,v0scale,u1scale,v1scale; const GLfloat *const s = ctx->Viewport._WindowMap.m; + int i; - if (IND & SETUP_TMU0) - tmu0_data = VB->TexCoordPtr[tmu0_source]->data; - if (IND & SETUP_TMU1) - tmu1_data = VB->TexCoordPtr[tmu1_source]->data; + if (IND & SETUP_TMU0) { + tc0_stride = VB->TexCoordPtr[tmu0_source]->stride; + tc0 = VB->TexCoordPtr[tmu0_source]->data; + u0scale = fxMesa->s0scale; + v0scale = fxMesa->t0scale; + if (IND & SETUP_PTEX) + tc0_size = VB->TexCoordPtr[tmu0_source]->size; + } + + if (IND & SETUP_TMU1) { + tc1 = VB->TexCoordPtr[tmu1_source]->data; + tc1_stride = VB->TexCoordPtr[tmu1_source]->stride; + u1scale = fxMesa->s1scale; /* wrong if tmu1_source == 0, possible? */ + v1scale = fxMesa->t1scale; + if (IND & SETUP_PTEX) + tc1_size = VB->TexCoordPtr[tmu1_source]->size; + } + + if (IND & SETUP_RGBA) { + if (VB->ColorPtr[0]->Type != GL_UNSIGNED_BYTE) + import_float_colors( ctx ); + col = VB->ColorPtr[0]->Ptr; + col_stride = VB->ColorPtr[0]->StrideB; + } - if (IND & SETUP_RGBA) - color = VB->ColorPtr[0]->Ptr; + if (start) { + proj = (GLfloat (*)[4])((GLubyte *)proj + start * proj_stride); + if (IND & SETUP_TMU0) + tc0 = (GLfloat (*)[4])((GLubyte *)tc0 + start * tc0_stride); + if (IND & SETUP_TMU1) + tc1 = (GLfloat (*)[4])((GLubyte *)tc1 + start * tc1_stride); + if (IND & SETUP_RGBA) + STRIDE_4UB(col, start * col_stride); + } - if (VB->ClipOrMask) { - for (i = start; i < end; i++, v++) { - if (!clipmask[i]) { - if (IND & SETUP_XYZW) { - v->v.x = s[0] * proj[i][0] + s[12]; - v->v.y = s[5] * proj[i][1] + s[13]; - v->v.ooz = s[10] * proj[i][2] + s[14]; - v->v.oow = proj[i][3]; + for (i=start; i < end; i++, v++) { + if (IND & SETUP_XYZW) { + /* unclipped */ + v->x = s[0] * proj[0][0] + s[12]; + v->y = s[5] * proj[0][1] + s[13]; + v->ooz = s[10] * proj[0][2] + s[14]; + v->oow = proj[0][3]; - if (IND & SETUP_SNAP) { + if (IND & SETUP_SNAP) { #if defined(USE_IEEE) - const float snapper = (3L << 18); - v->v.x += snapper; - v->v.x -= snapper; - v->v.y += snapper; - v->v.y -= snapper; + const float snapper = (3L << 18); + v->x += snapper; + v->x -= snapper; + v->y += snapper; + v->y -= snapper; #else - v->v.x = ((int) (v->v.x * 16.0f)) * (1.0f / 16.0f); - v->v.y = ((int) (v->v.y * 16.0f)) * (1.0f / 16.0f); + v->x = ((int) (v->x * 16.0f)) * (1.0f / 16.0f); + v->y = ((int) (v->y * 16.0f)) * (1.0f / 16.0f); #endif - } - } - if (IND & SETUP_RGBA) { - UNCLAMPED_FLOAT_TO_UBYTE(v->v.r, color[i][0]); - UNCLAMPED_FLOAT_TO_UBYTE(v->v.g, color[i][1]); - UNCLAMPED_FLOAT_TO_UBYTE(v->v.b, color[i][2]); - UNCLAMPED_FLOAT_TO_UBYTE(v->v.a, color[i][3]); - } - if (IND & SETUP_TMU0) { - v->v.tmuvtx[0].sow = sscale0 * tmu0_data[i][0] * v->v.oow; - v->v.tmuvtx[0].tow = tscale0 * tmu0_data[i][1] * v->v.oow; - } - if (IND & SETUP_TMU1) { - v->v.tmuvtx[1].sow = sscale1 * tmu1_data[i][0] * v->v.oow; - v->v.tmuvtx[1].tow = tscale1 * tmu1_data[i][1] * v->v.oow; - } } + + proj = (GLfloat (*)[4])((GLubyte *)proj + proj_stride); } + if (IND & SETUP_RGBA) { + v->r = (GLfloat) col[0][0]; + v->g = (GLfloat) col[0][1]; + v->b = (GLfloat) col[0][2]; + v->a = (GLfloat) col[0][3]; + STRIDE_4UB(col, col_stride); + } + if (IND & SETUP_TMU0) { + GLfloat w = v->oow; + if (IND & SETUP_PTEX) { + v->tmuvtx[0].sow = tc0[0][0] * u0scale * w; + v->tmuvtx[0].tow = tc0[0][1] * v0scale * w; + v->tmuvtx[0].oow = w; + if (tc0_size == 4) + v->tmuvtx[0].oow = tc0[0][3] * w; + } + else { + v->tmuvtx[0].sow = tc0[0][0] * u0scale * w; + v->tmuvtx[0].tow = tc0[0][1] * v0scale * w; + } + tc0 = (GLfloat (*)[4])((GLubyte *)tc0 + tc0_stride); + } + if (IND & SETUP_TMU1) { + GLfloat w = v->oow; + if (IND & SETUP_PTEX) { + v->tmuvtx[1].sow = tc1[0][0] * u1scale * w; + v->tmuvtx[1].tow = tc1[0][1] * v1scale * w; + v->tmuvtx[1].oow = w; + if (tc1_size == 4) + v->tmuvtx[1].oow = tc1[0][3] * w; + } + else { + v->tmuvtx[1].sow = tc1[0][0] * u1scale * w; + v->tmuvtx[1].tow = tc1[0][1] * v1scale * w; + } + tc1 = (GLfloat (*)[4])((GLubyte *)tc1 + tc1_stride); + } } - else { - for (i = start; i < end; i++, v++) { - if (IND & SETUP_XYZW) { - v->v.x = s[0] * proj[i][0] + s[12]; - v->v.y = s[5] * proj[i][1] + s[13]; - v->v.ooz = s[10] * proj[i][2] + s[14]; - v->v.oow = proj[i][3]; - - if (IND & SETUP_SNAP) { +} + +#if (IND & SETUP_XYZW) && (IND & SETUP_RGBA) + +static GLboolean TAG(check_tex_sizes)( GLcontext *ctx ) +{ +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + + if (IND & SETUP_PTEX) + return GL_TRUE; + + if (IND & SETUP_TMU0) { + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + + if (IND & SETUP_TMU1) { + if (VB->TexCoordPtr[0] == 0) + VB->TexCoordPtr[0] = VB->TexCoordPtr[1]; + + if (VB->TexCoordPtr[1]->size == 4) + return GL_FALSE; + } + + if (VB->TexCoordPtr[0]->size == 4) + return GL_FALSE; + } + + return GL_TRUE; +} + +static void TAG(interp)( GLcontext *ctx, + GLfloat t, + GLuint edst, GLuint eout, GLuint ein, + GLboolean force_boundary ) +{ + fxMesaContext fxMesa = FX_CONTEXT( ctx ); + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + const GLfloat *dstclip = VB->ClipPtr->data[edst]; + const GLfloat oow = (dstclip[3] == 0.0F) ? 1.0F : (1.0F / dstclip[3]); + const GLfloat *const s = ctx->Viewport._WindowMap.m; + GrVertex *fxverts = fxMesa->verts; + GrVertex *dst = (GrVertex *) (fxverts + edst); + const GrVertex *out = (const GrVertex *) (fxverts + eout); + const GrVertex *in = (const GrVertex *) (fxverts + ein); + const GLfloat wout = 1.0F / out->oow; + const GLfloat win = 1.0F / in->oow; + + dst->x = s[0] * dstclip[0] * oow + s[12]; + dst->y = s[5] * dstclip[1] * oow + s[13]; + dst->z = s[10] * dstclip[2] * oow + s[14]; + dst->oow = oow; + + if (IND & SETUP_SNAP) { #if defined(USE_IEEE) - const float snapper = (3L << 18); - v->v.x += snapper; - v->v.x -= snapper; - v->v.y += snapper; - v->v.y -= snapper; + const float snapper = (3L << 18); + dst->x += snapper; + dst->x -= snapper; + dst->y += snapper; + dst->y -= snapper; #else - v->v.x = ((int) (v->v.x * 16.0f)) * (1.0f / 16.0f); - v->v.y = ((int) (v->v.y * 16.0f)) * (1.0f / 16.0f); + dst->x = ((int) (dst->x * 16.0f)) * (1.0f / 16.0f); + dst->y = ((int) (dst->y * 16.0f)) * (1.0f / 16.0f); #endif - } - } - if (IND & SETUP_RGBA) { - UNCLAMPED_FLOAT_TO_UBYTE(v->v.r, color[i][0]); - UNCLAMPED_FLOAT_TO_UBYTE(v->v.g, color[i][1]); - UNCLAMPED_FLOAT_TO_UBYTE(v->v.b, color[i][2]); - UNCLAMPED_FLOAT_TO_UBYTE(v->v.a, color[i][3]); - } - if (IND & SETUP_TMU0) { - v->v.tmuvtx[0].sow = sscale0 * tmu0_data[i][0] * v->v.oow; - v->v.tmuvtx[0].tow = tscale0 * tmu0_data[i][1] * v->v.oow; - } - if (IND & SETUP_TMU1) { - v->v.tmuvtx[1].sow = sscale1 * tmu1_data[i][0] * v->v.oow; - v->v.tmuvtx[1].tow = tscale1 * tmu1_data[i][1] * v->v.oow; - } - } } - if ((IND & SETUP_XYZW) && - ctx->ProjectionMatrix.m[15] != 0.0F && ctx->Fog.Enabled) { - fx_fake_fog_w(ctx, v, VB, start, end); - } + + INTERP_F( t, dst->r, out->r, in->r ); + INTERP_F( t, dst->g, out->g, in->g ); + INTERP_F( t, dst->b, out->b, in->b ); + INTERP_F( t, dst->a, out->a, in->a ); - /* Check for and enable projective texturing in each texture unit. - */ - if (IND & (SETUP_TMU0 | SETUP_TMU1)) { - GLuint tmu0_sz = 2; - GLuint tmu1_sz = 2; - GLuint hs = fxMesa->stw_hint_state & ~(GR_STWHINT_W_DIFF_TMU0 | - GR_STWHINT_W_DIFF_TMU1); - - if (VB->TexCoordPtr[tmu0_source]) - tmu0_sz = VB->TexCoordPtr[tmu0_source]->size; - - if (VB->TexCoordPtr[tmu1_source]) - tmu1_sz = VB->TexCoordPtr[tmu1_source]->size; - - if (tmu0_sz == 4) { - project_texcoords(v, VB, 0, tmu0_source, start, end); - if (tmu1_sz == 4) - project_texcoords(v, VB, 1, tmu1_source, start, end); - else - copy_w(v, VB, 1, start, end); - hs |= (GR_STWHINT_W_DIFF_TMU0 | GR_STWHINT_W_DIFF_TMU1); - } - else if (tmu1_sz == 4) { - project_texcoords(v, VB, 1, tmu1_source, start, end); - hs |= GR_STWHINT_W_DIFF_TMU1; + if (IND & SETUP_TMU0) { + if (IND & SETUP_PTEX) { + INTERP_F( t, + dst->tmuvtx[0].sow, + out->tmuvtx[0].sow * wout, + in->tmuvtx[0].sow * win ); + INTERP_F( t, + dst->tmuvtx[0].tow, + out->tmuvtx[0].tow * wout, + in->tmuvtx[0].tow * win ); + INTERP_F( t, + dst->tmuvtx[0].oow, + out->tmuvtx[0].oow * wout, + in->tmuvtx[0].oow * win ); + + dst->tmuvtx[0].sow *= oow; + dst->tmuvtx[0].tow *= oow; + dst->tmuvtx[0].oow *= oow; + } else { + INTERP_F( t, + dst->tmuvtx[0].sow, + out->tmuvtx[0].sow * wout, + in->tmuvtx[0].sow * win ); + INTERP_F( t, + dst->tmuvtx[0].tow, + out->tmuvtx[0].tow * wout, + in->tmuvtx[0].tow * win ); + + dst->tmuvtx[0].sow *= oow; + dst->tmuvtx[0].tow *= oow; } + } + + if (IND & SETUP_TMU1) { + if (IND & SETUP_PTEX) { + INTERP_F( t, + dst->tmuvtx[1].sow, + out->tmuvtx[1].sow * wout, + in->tmuvtx[1].sow * win ); + INTERP_F( t, + dst->tmuvtx[1].tow, + out->tmuvtx[1].tow * wout, + in->tmuvtx[1].tow * win ); + INTERP_F( t, + dst->tmuvtx[1].oow, + out->tmuvtx[1].oow * wout, + in->tmuvtx[1].oow * win ); + + dst->tmuvtx[1].sow *= oow; + dst->tmuvtx[1].tow *= oow; + dst->tmuvtx[1].oow *= oow; + } else { + INTERP_F( t, + dst->tmuvtx[1].sow, + out->tmuvtx[1].sow * wout, + in->tmuvtx[1].sow * win ); + INTERP_F( t, + dst->tmuvtx[1].tow, + out->tmuvtx[1].tow * wout, + in->tmuvtx[1].tow * win ); - if (hs != fxMesa->stw_hint_state) { - fxMesa->stw_hint_state = hs; - FX_grHints(GR_HINT_STWHINT, hs); + dst->tmuvtx[1].sow *= oow; + dst->tmuvtx[1].tow *= oow; } } } +#endif + +static void TAG(init)( void ) +{ + setup_tab[IND].emit = TAG(emit); + +#if ((IND & SETUP_XYZW) && (IND & SETUP_RGBA)) + setup_tab[IND].check_tex_sizes = TAG(check_tex_sizes); + setup_tab[IND].interp = TAG(interp); + if (IND & SETUP_PTEX) { + setup_tab[IND].vertex_format = (GR_STWHINT_W_DIFF_TMU0 | + GR_STWHINT_W_DIFF_TMU1); + } + else { + setup_tab[IND].vertex_format = 0; + } +#endif +} #undef IND -#undef NAME -#undef INPUTS +#undef TAG diff --git a/src/mesa/drivers/osmesa/osmesa.c b/src/mesa/drivers/osmesa/osmesa.c index 85679d6a92..a0f2823f1d 100644 --- a/src/mesa/drivers/osmesa/osmesa.c +++ b/src/mesa/drivers/osmesa/osmesa.c @@ -1,4 +1,4 @@ -/* $Id: osmesa.c,v 1.60 2001/07/05 15:12:13 brianp Exp $ */ +/* $Id: osmesa.c,v 1.61 2001/07/12 22:09:21 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -346,6 +346,7 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits, _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); + _swsetup_Wakeup( ctx ); osmesa_register_swrast_functions( ctx ); } } @@ -2072,20 +2073,6 @@ static void osmesa_update_state( GLcontext *ctx, GLuint new_state ) swdd->SetReadBuffer = set_read_buffer; tnl->Driver.RunPipeline = _tnl_run_pipeline; - tnl->Driver.RenderStart = _swsetup_RenderStart; - tnl->Driver.RenderFinish = _swsetup_RenderFinish; - tnl->Driver.BuildProjectedVertices = _swsetup_BuildProjectedVertices; - tnl->Driver.RenderPrimitive = _swsetup_RenderPrimitive; - tnl->Driver.PointsFunc = _swsetup_Points; - tnl->Driver.LineFunc = _swsetup_Line; - tnl->Driver.TriangleFunc = _swsetup_Triangle; - tnl->Driver.QuadFunc = _swsetup_Quad; - tnl->Driver.ResetLineStipple = _swrast_ResetLineStipple; - tnl->Driver.RenderInterp = _swsetup_RenderInterp; - tnl->Driver.RenderCopyPV = _swsetup_RenderCopyPV; - tnl->Driver.RenderClippedLine = _swsetup_RenderClippedLine; - tnl->Driver.RenderClippedPolygon = _swsetup_RenderClippedPolygon; - _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); diff --git a/src/mesa/drivers/x11/xm_dd.c b/src/mesa/drivers/x11/xm_dd.c index dbb01f343e..768aa2f56b 100644 --- a/src/mesa/drivers/x11/xm_dd.c +++ b/src/mesa/drivers/x11/xm_dd.c @@ -1,4 +1,4 @@ -/* $Id: xm_dd.c,v 1.24 2001/05/10 12:22:32 keithw Exp $ */ +/* $Id: xm_dd.c,v 1.25 2001/07/12 22:09:21 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -992,19 +992,10 @@ void xmesa_init_pointers( GLcontext *ctx ) */ tnl = TNL_CONTEXT(ctx); tnl->Driver.RunPipeline = _tnl_run_pipeline; - tnl->Driver.RenderStart = _swsetup_RenderStart; - tnl->Driver.RenderFinish = _swsetup_RenderFinish; - tnl->Driver.BuildProjectedVertices = _swsetup_BuildProjectedVertices; - tnl->Driver.RenderPrimitive = _swsetup_RenderPrimitive; - tnl->Driver.PointsFunc = _swsetup_Points; - tnl->Driver.LineFunc = _swsetup_Line; - tnl->Driver.TriangleFunc = _swsetup_Triangle; - tnl->Driver.QuadFunc = _swsetup_Quad; - tnl->Driver.ResetLineStipple = _swrast_ResetLineStipple; - tnl->Driver.RenderInterp = _swsetup_RenderInterp; - tnl->Driver.RenderCopyPV = _swsetup_RenderCopyPV; - tnl->Driver.RenderClippedLine = _swsetup_RenderClippedLine; - tnl->Driver.RenderClippedPolygon = _swsetup_RenderClippedPolygon; + + /* Install swsetup for tnl->Driver.Render.*: + */ + _swsetup_Wakeup(ctx); (void) DitherValues; /* silenced unused var warning */ } diff --git a/src/mesa/main/Makefile.X11 b/src/mesa/main/Makefile.X11 index 255ab695f4..28980575a5 100644 --- a/src/mesa/main/Makefile.X11 +++ b/src/mesa/main/Makefile.X11 @@ -1,4 +1,4 @@ -# $Id: Makefile.X11,v 1.55 2001/06/27 12:52:12 keithw Exp $ +# $Id: Makefile.X11,v 1.56 2001/07/12 22:09:21 keithw Exp $ # Mesa 3-D graphics library # Version: 3.5 @@ -21,6 +21,9 @@ LIBDIR = ../lib CORE_SOURCES = \ + swrast_setup/ss_context.c \ + swrast_setup/ss_triangle.c \ + swrast_setup/ss_vb.c \ api_arrayelt.c \ api_loopback.c \ api_noop.c \ @@ -118,10 +121,6 @@ CORE_SOURCES = \ swrast/s_texstore.c \ swrast/s_triangle.c \ swrast/s_zoom.c \ - swrast_setup/ss_context.c \ - swrast_setup/ss_triangle.c \ - swrast_setup/ss_vb.c \ - swrast_setup/ss_interp.c \ tnl/t_array_api.c \ tnl/t_array_import.c \ tnl/t_context.c \ diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c index 69e0660970..354d809e08 100644 --- a/src/mesa/swrast/s_context.c +++ b/src/mesa/swrast/s_context.c @@ -1,4 +1,4 @@ -/* $Id: s_context.c,v 1.21 2001/05/17 09:32:17 keithw Exp $ */ +/* $Id: s_context.c,v 1.22 2001/07/12 22:09:21 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -529,7 +529,7 @@ _swrast_GetDeviceDriverReference( GLcontext *ctx ) return &swrast->Driver; } -#define SWRAST_DEBUG_VERTICES 0 +#define SWRAST_DEBUG_VERTICES 1 void _swrast_print_vertex( GLcontext *ctx, const SWvertex *v ) @@ -540,6 +540,8 @@ _swrast_print_vertex( GLcontext *ctx, const SWvertex *v ) fprintf(stderr, "win %f %f %f %f\n", v->win[0], v->win[1], v->win[2], v->win[3]); + return; + for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) fprintf(stderr, "texcoord[%d] %f %f %f %f\n", i, v->texcoord[i][0], v->texcoord[i][1], diff --git a/src/mesa/swrast_setup/NOTES b/src/mesa/swrast_setup/NOTES index 4445b332d9..c6cb4ab348 100644 --- a/src/mesa/swrast_setup/NOTES +++ b/src/mesa/swrast_setup/NOTES @@ -6,10 +6,8 @@ swrast vertices from the t&l vertex_buffer structs, and to use them to perform triangle setup functions not implemented in the software rasterizer. -The module provides a RasterSetup function to plug into the t&l driver -interface. This hook had previously been used for hardware -rasterizers, with the software rasterizer taking its data directly -from the vertex buffer. +The module implements a full set of functions to plug into the +t_vb_render.c driver interface (tnl->Driver.Render.*). There are strong advantages to decoupling the software rasterizer from the t&l module, primarily allowing hardware drivers better control @@ -18,63 +16,50 @@ rasterizer in the t&l module, allowing the two modules to evolve independently and allowing either to be substituted with equivalent functionality from another codebase. -This module provides helpers for triangle/quad setup for offset, -unfilled and twoside-lit triangles. The software rasterizer doesn't -handle these primitives directly. +This module implements triangle/quad setup for offset, unfilled and +twoside-lit triangles. The software rasterizer doesn't handle these +primitives directly. -Hardware rasterization drivers probably have little use for this -module. Rather, they might provide a layer that translates their -native (hardware) vertices to swrast vertices before calling into the -swrast module for fallbacks. +Hardware rasterization drivers typically use this module in situations +where no hardware rasterization is possible, ie during total +fallbacks. STATE -This module associates an array of SWvertex structs with each VB. -Thus there are: - - GLboolean _swsetup_RegisterVB( struct vertex_buffer *VB ); - void _swsetup_UnregisterVB( struct vertex_buffer *VB ); - -Which must be called to create and destroy internal vertex storage for -this module. - -To create and destroy the module itself: +To create and destroy the module: GLboolean _swsetup_CreateContext( GLcontext *ctx ); void _swsetup_DestroyContext( GLcontext *ctx ); -Like the software rasterizer, this module tracks state changes -internally and maintains a set of entry points which will always -reflect the current state. For this to work, the driver must call: - - void _swsetup_InvalidateState( GLcontext *ctx, GLuint new_state ); +The module is not active by default, and must be installed by calling +_swrast_Wakeup(). This function installs internal swrast_setup +functions into all the tnl->Driver.Render driver hooks, thus taking +over the task of rasterization entirely: -SERVICES + void _swrast_Wakeup( GLcontext *ctx ); -The module provides the following entrypoints: + +This module tracks state changes internally and maintains derived +values based on the current state. For this to work, the driver +ensure the following funciton is called whenever the state changes and +the swsetup module is 'awake': - void _swrast_RasterSetup( struct vertex_buffer *VB, - GLuint start, GLuint end ); - -Build SWvertices for <VB> between indices start and end. - - void _swsetup_Quad( GLcontext *ctx, GLuint v0, GLuint v1, - GLuint v2, GLuint v3, GLuint pv ); - - void _swsetup_Triangle( GLcontext *ctx, GLuint v0, GLuint v1, - GLuint v2, GLuint pv ); + void _swsetup_InvalidateState( GLcontext *ctx, GLuint new_state ); - void _swsetup_Line( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv ); +There is no explicit call to put the swsetup module to sleep. Simply +install other function pointers into all the tnl->Driver.Render.* +hooks, and (optionally) cease calling _swsetup_InvalidateState(). +DRIVER INTERFACE - void _swsetup_Points( GLcontext *ctx, GLuint first, GLuint last ); +The module offers a minimal driver interface: -Draw quad, triangle, line, points. Note that these are in the format -expected by core mesa. The Quad and Triangle functions handle -unfilled, offset, twoside-lit and flat-shaded primitives correctly. + void (*Start)( GLcontext *ctx ); + void (*Finish)( GLcontext *ctx ); + +These are called before and after the completion of all swrast drawing +activity. As swrast doesn't call callbacks during triangle, line or +point rasterization, these are necessary to provide locking hooks for +some drivers. They may otherwise be left null. -These functions can thus be plugged into the ctx->Driver struct and -left permanently in place, providing the InvalidateState() routine is -correctly called on state changes. -
\ No newline at end of file diff --git a/src/mesa/swrast_setup/ss_context.c b/src/mesa/swrast_setup/ss_context.c index def9e4f43c..2e92342e07 100644 --- a/src/mesa/swrast_setup/ss_context.c +++ b/src/mesa/swrast_setup/ss_context.c @@ -1,4 +1,4 @@ -/* $Id: ss_context.c,v 1.13 2001/03/12 00:48:43 gareth Exp $ */ +/* $Id: ss_context.c,v 1.14 2001/07/12 22:09:21 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -32,12 +32,14 @@ #include "ss_context.h" #include "ss_triangle.h" #include "ss_vb.h" -#include "ss_interp.h" #include "swrast_setup.h" +#include "tnl/tnl.h" #include "tnl/t_context.h" +#include "tnl/t_pipeline.h" #define _SWSETUP_NEW_VERTS (_NEW_RENDERMODE| \ + _NEW_POLYGON| \ _NEW_LIGHT| \ _NEW_TEXTURE| \ _NEW_COLOR| \ @@ -47,47 +49,6 @@ #define _SWSETUP_NEW_RENDERINDEX (_NEW_POLYGON|_NEW_LIGHT) -/* Dispatch from these fixed entrypoints to the state-dependent - * functions. - * - * The design of swsetup suggests that we could really program - * ctx->Driver.TriangleFunc directly from _swsetup_RenderStart, and - * avoid this second level of indirection. However, this is more - * convient for fallback cases in hardware rasterization drivers. - */ -void -_swsetup_Quad( GLcontext *ctx, GLuint v0, GLuint v1, - GLuint v2, GLuint v3 ) -{ - SWSETUP_CONTEXT(ctx)->Quad( ctx, v0, v1, v2, v3 ); -} - -void -_swsetup_Triangle( GLcontext *ctx, GLuint v0, GLuint v1, - GLuint v2 ) -{ - SWSETUP_CONTEXT(ctx)->Triangle( ctx, v0, v1, v2 ); -} - -void -_swsetup_Line( GLcontext *ctx, GLuint v0, GLuint v1 ) -{ - SWSETUP_CONTEXT(ctx)->Line( ctx, v0, v1 ); -} - -void -_swsetup_Points( GLcontext *ctx, GLuint first, GLuint last ) -{ - SWSETUP_CONTEXT(ctx)->Points( ctx, first, last ); -} - -void -_swsetup_BuildProjectedVertices( GLcontext *ctx, GLuint start, GLuint end, - GLuint new_inputs ) -{ - SWSETUP_CONTEXT(ctx)->BuildProjVerts( ctx, start, end, new_inputs ); -} - GLboolean _swsetup_CreateContext( GLcontext *ctx ) @@ -98,7 +59,8 @@ _swsetup_CreateContext( GLcontext *ctx ) if (!swsetup) return GL_FALSE; - swsetup->verts = (SWvertex *) ALIGN_MALLOC( sizeof(SWvertex) * tnl->vb.Size, 32); + swsetup->verts = (SWvertex *) ALIGN_MALLOC( sizeof(SWvertex) * tnl->vb.Size, + 32); if (!swsetup->verts) { FREE(swsetup); return GL_FALSE; @@ -108,7 +70,6 @@ _swsetup_CreateContext( GLcontext *ctx ) swsetup->NewState = ~0; _swsetup_vb_init( ctx ); - _swsetup_interp_init( ctx ); _swsetup_trifuncs_init( ctx ); return GL_TRUE; @@ -126,17 +87,16 @@ _swsetup_DestroyContext( GLcontext *ctx ) } } -void +static void _swsetup_RenderPrimitive( GLcontext *ctx, GLenum mode ) { SWSETUP_CONTEXT(ctx)->render_prim = mode; } -void +static void _swsetup_RenderStart( GLcontext *ctx ) { SScontext *swsetup = SWSETUP_CONTEXT(ctx); - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; GLuint new_state = swsetup->NewState; if (new_state & _SWSETUP_NEW_RENDERINDEX) { @@ -149,16 +109,19 @@ _swsetup_RenderStart( GLcontext *ctx ) swsetup->NewState = 0; - if (VB->ClipMask && VB->importable_data) - VB->import_data( ctx, - VB->importable_data, - VEC_NOT_WRITEABLE|VEC_BAD_STRIDE); + if (swsetup->Driver.Start) + swsetup->Driver.Start( ctx ); } -void +static void _swsetup_RenderFinish( GLcontext *ctx ) { + SScontext *swsetup = SWSETUP_CONTEXT(ctx); + _swrast_flush( ctx ); + + if (swsetup->Driver.Finish) + swsetup->Driver.Finish( ctx ); } void @@ -166,23 +129,29 @@ _swsetup_InvalidateState( GLcontext *ctx, GLuint new_state ) { SScontext *swsetup = SWSETUP_CONTEXT(ctx); swsetup->NewState |= new_state; - - if (new_state & _SWSETUP_NEW_INTERP) { - swsetup->RenderInterp = _swsetup_validate_interp; - swsetup->RenderCopyPV = _swsetup_validate_copypv; - } } -void -_swsetup_RenderInterp( GLcontext *ctx, GLfloat t, - GLuint dst, GLuint out, GLuint in, - GLboolean force_boundary ) -{ - SWSETUP_CONTEXT(ctx)->RenderInterp( ctx, t, dst, out, in, force_boundary ); -} void -_swsetup_RenderCopyPV( GLcontext *ctx, GLuint dst, GLuint src ) +_swsetup_Wakeup( GLcontext *ctx ) { - SWSETUP_CONTEXT(ctx)->RenderCopyPV( ctx, dst, src ); + TNLcontext *tnl = TNL_CONTEXT(ctx); + tnl->Driver.Render.Start = _swsetup_RenderStart; + tnl->Driver.Render.Finish = _swsetup_RenderFinish; + tnl->Driver.Render.PrimitiveNotify = _swsetup_RenderPrimitive; + /* interp */ + /* copypv */ + tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; /* new */ + tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine; /* new */ + /* points */ + /* line */ + /* triangle */ + /* quad */ + tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; + tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; + tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple; + /* buildvertices */ + tnl->Driver.Render.Multipass = 0; + _tnl_need_projected_coords( ctx, GL_TRUE ); + _swsetup_InvalidateState( ctx, ~0 ); } diff --git a/src/mesa/swrast_setup/ss_context.h b/src/mesa/swrast_setup/ss_context.h index 895fb1b03e..f477f850cd 100644 --- a/src/mesa/swrast_setup/ss_context.h +++ b/src/mesa/swrast_setup/ss_context.h @@ -1,4 +1,4 @@ -/* $Id: ss_context.h,v 1.7 2001/03/12 00:48:43 gareth Exp $ */ +/* $Id: ss_context.h,v 1.8 2001/07/12 22:09:21 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -36,35 +36,14 @@ typedef struct { GLuint NewState; - GLuint StateChanges; - - /* Function hooks, trigger lazy state updates. - */ - void (*InvalidateState)( GLcontext *ctx, GLuint new_state ); - - void (*BuildProjVerts)( GLcontext *ctx, - GLuint start, GLuint end, GLuint new_inputs ); - - void (*Quad)( GLcontext *ctx, GLuint v0, GLuint v1, - GLuint v2, GLuint v3 ); - - void (*Triangle)( GLcontext *ctx, GLuint v0, GLuint v1, - GLuint v2 ); - - void (*Line)( GLcontext *ctx, GLuint v0, GLuint v1 ); - - void (*Points)( GLcontext *ctx, GLuint first, GLuint last ); - - void (*RenderCopyPV)( GLcontext *ctx, GLuint dst, GLuint src ); - - void (*RenderInterp)( GLcontext *ctx, GLfloat t, - GLuint dst, GLuint out, GLuint in, - GLboolean force_boundary ); - - SWvertex *verts; GLenum render_prim; + GLuint SetupIndex; + struct { + void (*Start)( GLcontext * ); + void (*Finish)( GLcontext * ); + } Driver; } SScontext; #define SWSETUP_CONTEXT(ctx) ((SScontext *)ctx->swsetup_context) diff --git a/src/mesa/swrast_setup/ss_triangle.c b/src/mesa/swrast_setup/ss_triangle.c index a12429e26d..7b2d638213 100644 --- a/src/mesa/swrast_setup/ss_triangle.c +++ b/src/mesa/swrast_setup/ss_triangle.c @@ -1,4 +1,4 @@ -/* $Id: ss_triangle.c,v 1.13 2001/04/28 08:39:18 keithw Exp $ */ +/* $Id: ss_triangle.c,v 1.14 2001/07/12 22:09:21 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -262,7 +262,7 @@ static void swsetup_line( GLcontext *ctx, GLuint v0, GLuint v1 ) void _swsetup_choose_trifuncs( GLcontext *ctx ) { - SScontext *swsetup = SWSETUP_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); GLuint ind = 0; if (ctx->Polygon._OffsetAny) @@ -277,8 +277,8 @@ void _swsetup_choose_trifuncs( GLcontext *ctx ) if (ctx->Visual.rgbMode) ind |= SS_RGBA_BIT; - swsetup->Triangle = tri_tab[ind]; - swsetup->Quad = quad_tab[ind]; - swsetup->Line = swsetup_line; - swsetup->Points = swsetup_points; + tnl->Driver.Render.Triangle = tri_tab[ind]; + tnl->Driver.Render.Quad = quad_tab[ind]; + tnl->Driver.Render.Line = swsetup_line; + tnl->Driver.Render.Points = swsetup_points; } diff --git a/src/mesa/swrast_setup/ss_tritmp.h b/src/mesa/swrast_setup/ss_tritmp.h index 0db792ba2b..49e92acf1c 100644 --- a/src/mesa/swrast_setup/ss_tritmp.h +++ b/src/mesa/swrast_setup/ss_tritmp.h @@ -1,4 +1,4 @@ -/* $Id: ss_tritmp.h,v 1.12 2001/04/28 08:39:18 keithw Exp $ */ +/* $Id: ss_tritmp.h,v 1.13 2001/07/12 22:09:21 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -62,13 +62,15 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 ) if (IND & SS_TWOSIDE_BIT) { if (IND & SS_RGBA_BIT) { GLfloat (*vbcolor)[4] = (GLfloat (*)[4])VB->ColorPtr[1]->Ptr; - GLfloat (*vbspec)[4] = (GLfloat (*)[4])VB->SecondaryColorPtr[1]->Ptr; SS_COLOR(v[0]->color, vbcolor[e0]); SS_COLOR(v[1]->color, vbcolor[e1]); SS_COLOR(v[2]->color, vbcolor[e2]); - SS_SPEC(v[0]->specular, vbspec[e0]); - SS_SPEC(v[1]->specular, vbspec[e1]); - SS_SPEC(v[2]->specular, vbspec[e2]); + if (VB->SecondaryColorPtr[1]) { + GLfloat (*vbspec)[4] = (GLfloat (*)[4])VB->SecondaryColorPtr[1]->Ptr; + SS_SPEC(v[0]->specular, vbspec[e0]); + SS_SPEC(v[1]->specular, vbspec[e1]); + SS_SPEC(v[2]->specular, vbspec[e2]); + } } else { GLuint *vbindex = VB->IndexPtr[1]->data; SS_IND(v[0]->index, vbindex[e0]); @@ -135,13 +137,15 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 ) if (facing == 1) { if (IND & SS_RGBA_BIT) { GLfloat (*vbcolor)[4] = (GLfloat (*)[4])VB->ColorPtr[0]->Ptr; - GLfloat (*vbspec)[4] = (GLfloat (*)[4])VB->SecondaryColorPtr[0]->Ptr; SS_COLOR(v[0]->color, vbcolor[e0]); SS_COLOR(v[1]->color, vbcolor[e1]); SS_COLOR(v[2]->color, vbcolor[e2]); - SS_SPEC(v[0]->specular, vbspec[e0]); - SS_SPEC(v[1]->specular, vbspec[e1]); - SS_SPEC(v[2]->specular, vbspec[e2]); + if (VB->SecondaryColorPtr[0]) { + GLfloat (*vbspec)[4] = (GLfloat (*)[4])VB->SecondaryColorPtr[0]->Ptr; + SS_SPEC(v[0]->specular, vbspec[e0]); + SS_SPEC(v[1]->specular, vbspec[e1]); + SS_SPEC(v[2]->specular, vbspec[e2]); + } } else { GLuint *vbindex = VB->IndexPtr[0]->data; SS_IND(v[0]->index, vbindex[e0]); diff --git a/src/mesa/swrast_setup/ss_vb.c b/src/mesa/swrast_setup/ss_vb.c index f9d1d01997..7afb646769 100644 --- a/src/mesa/swrast_setup/ss_vb.c +++ b/src/mesa/swrast_setup/ss_vb.c @@ -1,4 +1,4 @@ -/* $Id: ss_vb.c,v 1.12 2001/03/29 21:16:26 keithw Exp $ */ +/* $Id: ss_vb.c,v 1.13 2001/07/12 22:09:21 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -46,8 +46,6 @@ * in this module, but not the rest of the swrast module. */ -typedef void (*SetupFunc)( GLcontext *ctx, - GLuint start, GLuint end, GLuint newinputs ); #define COLOR 0x1 #define INDEX 0x2 @@ -58,7 +56,9 @@ typedef void (*SetupFunc)( GLcontext *ctx, #define POINT 0x40 #define MAX_SETUPFUNC 0x80 -static SetupFunc setup_func[MAX_SETUPFUNC]; +static setup_func setup_tab[MAX_SETUPFUNC]; +static interp_func interp_tab[MAX_SETUPFUNC]; +static copy_pv_func copy_pv_tab[MAX_SETUPFUNC]; #define IND (0) @@ -165,84 +165,150 @@ static SetupFunc setup_func[MAX_SETUPFUNC]; #define TAG(x) x##_index #include "ss_vbtmp.h" -#define IND (INDEX|TEX0) -#define TAG(x) x##_index_tex0 -#include "ss_vbtmp.h" - #define IND (INDEX|FOG) #define TAG(x) x##_index_fog #include "ss_vbtmp.h" -#define IND (INDEX|TEX0|FOG) -#define TAG(x) x##_index_tex0_fog -#include "ss_vbtmp.h" - #define IND (INDEX|POINT) #define TAG(x) x##_index_point #include "ss_vbtmp.h" -#define IND (INDEX|TEX0|POINT) -#define TAG(x) x##_index_tex0_point -#include "ss_vbtmp.h" - #define IND (INDEX|FOG|POINT) #define TAG(x) x##_index_fog_point #include "ss_vbtmp.h" -#define IND (INDEX|TEX0|FOG|POINT) -#define TAG(x) x##_index_tex0_fog_point -#include "ss_vbtmp.h" + +/*********************************************************************** + * Additional setup and interp for back color and edgeflag. + ***********************************************************************/ + +#define GET_COLOR(ptr, idx) (((GLfloat (*)[4])((ptr)->Ptr))[idx]) + +static void interp_extras( GLcontext *ctx, + GLfloat t, + GLuint dst, GLuint out, GLuint in, + GLboolean force_boundary ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + + if (VB->ColorPtr[1]) { + INTERP_4F( t, + GET_COLOR(VB->ColorPtr[1], dst), + GET_COLOR(VB->ColorPtr[1], out), + GET_COLOR(VB->ColorPtr[1], in) ); + + if (VB->SecondaryColorPtr[1]) { + INTERP_3F( t, + GET_COLOR(VB->SecondaryColorPtr[1], dst), + GET_COLOR(VB->SecondaryColorPtr[1], out), + GET_COLOR(VB->SecondaryColorPtr[1], in) ); + } + } + else if (VB->IndexPtr[1]) { + VB->IndexPtr[1]->data[dst] = (GLuint) (GLint) + LINTERP( t, + (GLfloat) VB->IndexPtr[1]->data[out], + (GLfloat) VB->IndexPtr[1]->data[in] ); + } + + if (VB->EdgeFlag) { + VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary; + } + + interp_tab[SWSETUP_CONTEXT(ctx)->SetupIndex](ctx, t, dst, out, in, + force_boundary); +} + +static void copy_pv_extras( GLcontext *ctx, GLuint dst, GLuint src ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + + if (VB->ColorPtr[1]) { + COPY_4FV( GET_COLOR(VB->ColorPtr[1], dst), + GET_COLOR(VB->ColorPtr[1], src) ); + + if (VB->SecondaryColorPtr[1]) { + COPY_4FV( GET_COLOR(VB->SecondaryColorPtr[1], dst), + GET_COLOR(VB->SecondaryColorPtr[1], src) ); + } + } + else if (VB->IndexPtr[1]) { + VB->IndexPtr[1]->data[dst] = VB->IndexPtr[1]->data[src]; + } + + copy_pv_tab[SWSETUP_CONTEXT(ctx)->SetupIndex](ctx, dst, src); +} + +/*********************************************************************** + * Initialization + ***********************************************************************/ + + + static void -rs_invalid( GLcontext *ctx, GLuint start, GLuint end, GLuint newinputs ) +emit_invalid( GLcontext *ctx, GLuint start, GLuint end, GLuint newinputs ) { fprintf(stderr, "swrast_setup: invalid setup function\n"); (void) (ctx && start && end && newinputs); } -void -_swsetup_vb_init( GLcontext *ctx ) +static void +interp_invalid( GLcontext *ctx, GLfloat t, + GLuint edst, GLuint eout, GLuint ein, + GLboolean force_boundary ) +{ + fprintf(stderr, "swrast_setup: invalid interp function\n"); + (void) (ctx && t && edst && eout && ein && force_boundary); +} + +static void +copy_pv_invalid( GLcontext *ctx, GLuint edst, GLuint esrc ) +{ + fprintf(stderr, "swrast_setup: invalid copy_pv function\n"); + (void) (ctx && edst && esrc ); +} + +static void init_standard( void ) { GLuint i; - (void) ctx; - for (i = 0 ; i < Elements(setup_func) ; i++) - setup_func[i] = rs_invalid; - - setup_func[0] = rs_none; - setup_func[COLOR] = rs_color; - setup_func[COLOR|SPEC] = rs_color_spec; - setup_func[COLOR|FOG] = rs_color_fog; - setup_func[COLOR|SPEC|FOG] = rs_color_spec_fog; - setup_func[COLOR|TEX0] = rs_color_tex0; - setup_func[COLOR|TEX0|SPEC] = rs_color_tex0_spec; - setup_func[COLOR|TEX0|FOG] = rs_color_tex0_fog; - setup_func[COLOR|TEX0|SPEC|FOG] = rs_color_tex0_spec_fog; - setup_func[COLOR|MULTITEX] = rs_color_multitex; - setup_func[COLOR|MULTITEX|SPEC] = rs_color_multitex_spec; - setup_func[COLOR|MULTITEX|FOG] = rs_color_multitex_fog; - setup_func[COLOR|MULTITEX|SPEC|FOG] = rs_color_multitex_spec_fog; - setup_func[COLOR|POINT] = rs_color_point; - setup_func[COLOR|SPEC|POINT] = rs_color_spec_point; - setup_func[COLOR|FOG|POINT] = rs_color_fog_point; - setup_func[COLOR|SPEC|FOG|POINT] = rs_color_spec_fog_point; - setup_func[COLOR|TEX0|POINT] = rs_color_tex0_point; - setup_func[COLOR|TEX0|SPEC|POINT] = rs_color_tex0_spec_point; - setup_func[COLOR|TEX0|FOG|POINT] = rs_color_tex0_fog_point; - setup_func[COLOR|TEX0|SPEC|FOG|POINT] = rs_color_tex0_spec_fog_point; - setup_func[COLOR|MULTITEX|POINT] = rs_color_multitex_point; - setup_func[COLOR|MULTITEX|SPEC|POINT] = rs_color_multitex_spec_point; - setup_func[COLOR|MULTITEX|FOG|POINT] = rs_color_multitex_fog_point; - setup_func[COLOR|MULTITEX|SPEC|FOG|POINT] = rs_color_multitex_spec_fog_point; - setup_func[INDEX] = rs_index; - setup_func[INDEX|TEX0] = rs_index_tex0; - setup_func[INDEX|FOG] = rs_index_fog; - setup_func[INDEX|TEX0|FOG] = rs_index_tex0_fog; - setup_func[INDEX|POINT] = rs_index_point; - setup_func[INDEX|TEX0|POINT] = rs_index_tex0_point; - setup_func[INDEX|FOG|POINT] = rs_index_fog_point; - setup_func[INDEX|TEX0|FOG|POINT] = rs_index_tex0_fog_point; + for (i = 0 ; i < Elements(setup_tab) ; i++) { + setup_tab[i] = emit_invalid; + interp_tab[i] = interp_invalid; + copy_pv_tab[i] = copy_pv_invalid; + } + + init_none(); + init_color(); + init_color_spec(); + init_color_fog(); + init_color_spec_fog(); + init_color_tex0(); + init_color_tex0_spec(); + init_color_tex0_fog(); + init_color_tex0_spec_fog(); + init_color_multitex(); + init_color_multitex_spec(); + init_color_multitex_fog(); + init_color_multitex_spec_fog(); + init_color_point(); + init_color_spec_point(); + init_color_fog_point(); + init_color_spec_fog_point(); + init_color_tex0_point(); + init_color_tex0_spec_point(); + init_color_tex0_fog_point(); + init_color_tex0_spec_fog_point(); + init_color_multitex_point(); + init_color_multitex_spec_point(); + init_color_multitex_fog_point(); + init_color_multitex_spec_fog_point(); + init_index(); + init_index_fog(); + init_index_point(); + init_index_fog_point(); } static void printSetupFlags(char *msg, GLuint flags ) @@ -260,10 +326,12 @@ static void printSetupFlags(char *msg, GLuint flags ) } + void _swsetup_choose_rastersetup_func(GLcontext *ctx) { SScontext *swsetup = SWSETUP_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); int funcindex = 0; if (ctx->RenderMode == GL_RENDER) { @@ -275,8 +343,7 @@ _swsetup_choose_rastersetup_func(GLcontext *ctx) else if (ctx->Texture._ReallyEnabled & 0xf) funcindex |= TEX0; - if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR || - ctx->Fog.ColorSumEnabled) + if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) funcindex |= SPEC; } else { @@ -293,12 +360,33 @@ _swsetup_choose_rastersetup_func(GLcontext *ctx) if (ctx->Visual.rgbMode) funcindex = (COLOR | TEX0); /* is feedback color subject to fogging? */ else - funcindex = (INDEX | TEX0); + funcindex = INDEX; } else funcindex = 0; + + swsetup->SetupIndex = funcindex; + tnl->Driver.Render.BuildVertices = setup_tab[funcindex]; - if (0) printSetupFlags("software setup func", funcindex); - swsetup->BuildProjVerts = setup_func[funcindex]; - ASSERT(setup_func[funcindex] != rs_invalid); + if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) { + tnl->Driver.Render.Interp = interp_extras; + tnl->Driver.Render.CopyPV = copy_pv_extras; + } + else { + tnl->Driver.Render.Interp = interp_tab[funcindex]; + tnl->Driver.Render.CopyPV = copy_pv_tab[funcindex]; + } + + ASSERT(tnl->Driver.Render.BuildVertices); + ASSERT(tnl->Driver.Render.BuildVertices != emit_invalid); +} + + +void +_swsetup_vb_init( GLcontext *ctx ) +{ + (void) ctx; + init_standard(); + (void) printSetupFlags; } + diff --git a/src/mesa/swrast_setup/ss_vbtmp.h b/src/mesa/swrast_setup/ss_vbtmp.h index 9ef51a3c20..4a83cf2301 100644 --- a/src/mesa/swrast_setup/ss_vbtmp.h +++ b/src/mesa/swrast_setup/ss_vbtmp.h @@ -1,4 +1,4 @@ -/* $Id: ss_vbtmp.h,v 1.15 2001/04/30 09:04:00 keithw Exp $ */ +/* $Id: ss_vbtmp.h,v 1.16 2001/07/12 22:09:21 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -28,19 +28,23 @@ */ -static void TAG(rs)(GLcontext *ctx, GLuint start, GLuint end, GLuint newinputs ) +static void TAG(emit)(GLcontext *ctx, GLuint start, GLuint end, + GLuint newinputs ) { TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; SWvertex *v; - GLfloat (*proj)[4]; /* projected clip coordinates */ - GLfloat (*tc[MAX_TEXTURE_UNITS])[4]; - GLfloat (*color)[4]; - GLfloat (*spec)[4]; + GLfloat *proj; /* projected clip coordinates */ + GLfloat *tc[MAX_TEXTURE_UNITS]; + GLfloat *color; + GLfloat *spec; GLuint *index; GLfloat *fog; GLfloat *pointSize; GLuint tsz[MAX_TEXTURE_UNITS]; + GLuint tstride[MAX_TEXTURE_UNITS]; + GLuint proj_stride, color_stride, spec_stride, index_stride; + GLuint fog_stride, pointSize_stride; GLuint i; GLfloat *m = ctx->Viewport._WindowMap.m; const GLfloat sx = m[0]; @@ -51,94 +55,200 @@ static void TAG(rs)(GLcontext *ctx, GLuint start, GLuint end, GLuint newinputs ) const GLfloat tz = m[14]; GLuint maxtex = 0; - /* Only the most basic optimization for cva: - */ - if (!newinputs) - return; - - /* TODO: Get import_client_data to pad vectors out to 4 cleanly. - * - * NOTE: This has the effect of converting any remaining ubyte - * colors to floats... As they're already there 90% of the - * time, this isn't a bad thing. - */ - if (VB->importable_data) - VB->import_data( ctx, VB->importable_data & newinputs, - (VB->ClipOrMask - ? VEC_NOT_WRITEABLE|VEC_BAD_STRIDE - : VEC_BAD_STRIDE)); - if (IND & TEX0) { - tc[0] = VB->TexCoordPtr[0]->data; + tc[0] = (GLfloat *)VB->TexCoordPtr[0]->data; tsz[0] = VB->TexCoordPtr[0]->size; + tstride[0] = VB->TexCoordPtr[0]->stride; } if (IND & MULTITEX) { for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) { if (VB->TexCoordPtr[i]) { maxtex = i+1; - tc[i] = VB->TexCoordPtr[i]->data; + tc[i] = (GLfloat *)VB->TexCoordPtr[i]->data; tsz[i] = VB->TexCoordPtr[i]->size; + tstride[i] = VB->TexCoordPtr[i]->stride; } else tc[i] = 0; } } - /* Tie up some dangling pointers for flat/twoside code in ss_tritmp.h - */ - if ((ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) == 0) { - VB->SecondaryColorPtr[0] = VB->ColorPtr[0]; - VB->SecondaryColorPtr[1] = VB->ColorPtr[1]; - } - + proj = VB->ProjectedClipPtr->data[0]; + proj_stride = VB->ProjectedClipPtr->stride; - proj = VB->ProjectedClipPtr->data; - if (IND & FOG) + if (IND & FOG) { fog = VB->FogCoordPtr->data; - if (IND & COLOR) - color = (GLfloat (*)[4])VB->ColorPtr[0]->Ptr; - if (IND & SPEC) - spec = (GLfloat (*)[4])VB->SecondaryColorPtr[0]->Ptr; - if (IND & INDEX) + fog_stride = VB->FogCoordPtr->stride; + } + if (IND & COLOR) { + color = VB->ColorPtr[0]->Ptr; + color_stride = VB->ColorPtr[0]->StrideB; + } + if (IND & SPEC) { + spec = VB->SecondaryColorPtr[0]->Ptr; + spec_stride = VB->SecondaryColorPtr[0]->StrideB; + } + if (IND & INDEX) { index = VB->IndexPtr[0]->data; - if (IND & POINT) + index_stride = VB->IndexPtr[0]->stride; + } + if (IND & POINT) { pointSize = VB->PointSizePtr->data; + pointSize_stride = VB->PointSizePtr->stride; + } v = &(SWSETUP_CONTEXT(ctx)->verts[start]); for (i=start; i < end; i++, v++) { if (VB->ClipMask[i] == 0) { - v->win[0] = sx * proj[i][0] + tx; - v->win[1] = sy * proj[i][1] + ty; - v->win[2] = sz * proj[i][2] + tz; - v->win[3] = proj[i][3]; - - if (IND & TEX0) - COPY_CLEAN_4V( v->texcoord[0], tsz[0], tc[0][i] ); - - if (IND & MULTITEX) { - GLuint u; - for (u = 0 ; u < maxtex ; u++) - if (tc[u]) - COPY_CLEAN_4V( v->texcoord[u], tsz[u], tc[u][i] ); - } + v->win[0] = sx * proj[0] + tx; + v->win[1] = sy * proj[1] + ty; + v->win[2] = sz * proj[2] + tz; + v->win[3] = proj[3]; + } + STRIDE_F(proj, proj_stride); + + if (IND & TEX0) { + COPY_CLEAN_4V( v->texcoord[0], tsz[0], tc[0] ); + STRIDE_F(tc[0], tstride[0]); + } + + if (IND & MULTITEX) { + GLuint u; + for (u = 0 ; u < maxtex ; u++) + if (tc[u]) { + COPY_CLEAN_4V( v->texcoord[u], tsz[u], tc[u] ); + STRIDE_F(tc[u], tstride[u]); + } + } - if (IND & COLOR) - UNCLAMPED_FLOAT_TO_RGBA_CHAN(v->color, color[i]); + if (IND & COLOR) { + UNCLAMPED_FLOAT_TO_RGBA_CHAN(v->color, color); + STRIDE_F(color, color_stride); +/* COPY_CHAN4(v->color, color); */ +/* STRIDE_CHAN(color, color_stride); */ + } - if (IND & SPEC) - UNCLAMPED_FLOAT_TO_RGBA_CHAN(v->specular, spec[i]); + if (IND & SPEC) { + UNCLAMPED_FLOAT_TO_RGB_CHAN(v->specular, spec); + STRIDE_F(spec, spec_stride); +/* COPY_CHAN4(v->specular, spec); */ +/* STRIDE_CHAN(spec, spec_stride); */ + } - if (IND & FOG) - v->fog = fog[i]; + if (IND & FOG) { + v->fog = fog[0]; + STRIDE_F(fog, fog_stride); + } - if (IND & INDEX) - v->index = index[i]; + if (IND & INDEX) { + v->index = index[0]; + STRIDE_UI(index, index_stride); + } - if (IND & POINT) - v->pointSize = pointSize[i]; + if (IND & POINT) { + v->pointSize = pointSize[0]; + STRIDE_F(pointSize, pointSize_stride); } + + } +} + + + +static void TAG(interp)( GLcontext *ctx, + GLfloat t, + GLuint edst, GLuint eout, GLuint ein, + GLboolean force_boundary ) +{ + SScontext *swsetup = SWSETUP_CONTEXT(ctx); + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLfloat *m = ctx->Viewport._WindowMap.m; + GLfloat *clip = VB->ClipPtr->data[edst]; + + SWvertex *dst = &swsetup->verts[edst]; + SWvertex *in = &swsetup->verts[ein]; + SWvertex *out = &swsetup->verts[eout]; + + /* Avoid division by zero by rearranging order of clip planes? + */ + if (clip[3] != 0.0) { + GLfloat oow = 1.0F / clip[3]; + dst->win[0] = m[0] * clip[0] * oow + m[12]; + dst->win[1] = m[5] * clip[1] * oow + m[13]; + dst->win[2] = m[10] * clip[2] * oow + m[14]; + dst->win[3] = oow; } + +/* fprintf(stderr, "%s edst %d win %f %f %f %f\n", */ +/* __FUNCTION__, edst, */ +/* dst->win[0], dst->win[1], dst->win[2], dst->win[3]); */ + + if (IND & TEX0) { + INTERP_4F( t, dst->texcoord[0], out->texcoord[0], in->texcoord[0] ); + } + + if (IND & MULTITEX) { + GLuint u; + GLuint maxtex = ctx->Const.MaxTextureUnits; + for (u = 0 ; u < maxtex ; u++) + if (VB->TexCoordPtr[u]) { + INTERP_4F( t, dst->texcoord[u], out->texcoord[u], in->texcoord[u] ); + } + } + + if (IND & COLOR) { + INTERP_CHAN( t, dst->color[0], out->color[0], in->color[0] ); + INTERP_CHAN( t, dst->color[1], out->color[1], in->color[1] ); + INTERP_CHAN( t, dst->color[2], out->color[2], in->color[2] ); + INTERP_CHAN( t, dst->color[3], out->color[3], in->color[3] ); + } + + if (IND & SPEC) { + INTERP_CHAN( t, dst->specular[0], out->specular[0], in->specular[0] ); + INTERP_CHAN( t, dst->specular[1], out->specular[1], in->specular[1] ); + INTERP_CHAN( t, dst->specular[2], out->specular[2], in->specular[2] ); + } + + if (IND & FOG) { + INTERP_F( t, dst->fog, out->fog, in->fog ); + } + + if (IND & INDEX) { + INTERP_UI( t, dst->index, out->index, in->index ); + } + + if (IND & POINT) { + INTERP_F( t, dst->pointSize, out->pointSize, in->pointSize ); + } +} + + +static void TAG(copy_pv)( GLcontext *ctx, GLuint edst, GLuint esrc ) +{ + SScontext *swsetup = SWSETUP_CONTEXT(ctx); + SWvertex *dst = &swsetup->verts[edst]; + SWvertex *src = &swsetup->verts[esrc]; + + if (IND & COLOR) { + COPY_CHAN4( dst->color, src->color ); + } + + if (IND & SPEC) { + COPY_3V( dst->specular, src->specular ); + } + + if (IND & INDEX) { + dst->index = src->index; + } +} + + +static void TAG(init)( void ) +{ + setup_tab[IND] = TAG(emit); + interp_tab[IND] = TAG(interp); + copy_pv_tab[IND] = TAG(copy_pv); } #undef TAG diff --git a/src/mesa/swrast_setup/swrast_setup.h b/src/mesa/swrast_setup/swrast_setup.h index bec8d90c1f..1a4b036442 100644 --- a/src/mesa/swrast_setup/swrast_setup.h +++ b/src/mesa/swrast_setup/swrast_setup.h @@ -1,4 +1,4 @@ -/* $Id: swrast_setup.h,v 1.8 2001/03/12 00:48:43 gareth Exp $ */ +/* $Id: swrast_setup.h,v 1.9 2001/07/12 22:09:21 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -30,6 +30,10 @@ /* Public interface to the swrast_setup module. This module provides * an implementation of the driver interface to t_vb_render.c, and uses * the software rasterizer (swrast) to perform actual rasterization. + * + * The internals of the implementation are private, but can be hooked + * into tnl at any time (except between RenderStart/RenderEnd) by + * calling _swsetup_Wakeup(). */ #ifndef SWRAST_SETUP_H @@ -45,48 +49,6 @@ extern void _swsetup_InvalidateState( GLcontext *ctx, GLuint new_state ); extern void -_swsetup_BuildProjectedVertices( GLcontext *ctx, - GLuint start, - GLuint end, - GLuint new_inputs ); - -extern void -_swsetup_Quad( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3 ); - -extern void -_swsetup_Triangle( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2 ); - -extern void -_swsetup_Line( GLcontext *ctx, GLuint v0, GLuint v1 ); - -extern void -_swsetup_Points( GLcontext *ctx, GLuint first, GLuint last ); - -extern void -_swsetup_RenderPrimitive( GLcontext *ctx, GLenum mode ); - -extern void -_swsetup_RenderStart( GLcontext *ctx ); - -extern void -_swsetup_RenderFinish( GLcontext *ctx ); - -extern void -_swsetup_RenderProjectInterpVerts( GLcontext *ctx ); - -extern void -_swsetup_RenderInterp( GLcontext *ctx, GLfloat t, - GLuint dst, GLuint out, GLuint in, - GLboolean force_boundary ); -extern void -_swsetup_RenderCopyPV( GLcontext *ctx, GLuint dst, GLuint src ); - -extern void -_swsetup_RenderClippedPolygon( GLcontext *ctx, const GLuint *elts, GLuint n ); - -extern void -_swsetup_RenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj ); - - +_swsetup_Wakeup( GLcontext *ctx ); #endif diff --git a/src/mesa/tnl/t_context.c b/src/mesa/tnl/t_context.c index 0acb9f9db2..76f4180b65 100644 --- a/src/mesa/tnl/t_context.c +++ b/src/mesa/tnl/t_context.c @@ -1,4 +1,4 @@ -/* $Id: t_context.c,v 1.20 2001/06/28 17:34:14 keithw Exp $ */ +/* $Id: t_context.c,v 1.21 2001/07/12 22:09:21 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -123,8 +123,8 @@ _tnl_CreateContext( GLcontext *ctx ) ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN; - tnl->Driver.RenderTabElts = _tnl_render_tab_elts; - tnl->Driver.RenderTabVerts = _tnl_render_tab_verts; + tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; + tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; return GL_TRUE; diff --git a/src/mesa/tnl/t_context.h b/src/mesa/tnl/t_context.h index a7ecb346b7..7142f31616 100644 --- a/src/mesa/tnl/t_context.h +++ b/src/mesa/tnl/t_context.h @@ -1,4 +1,4 @@ -/* $Id: t_context.h,v 1.29 2001/06/28 17:34:14 keithw Exp $ */ +/* $Id: t_context.h,v 1.30 2001/07/12 22:09:22 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -376,6 +376,9 @@ typedef void (*interp_func)( GLcontext *ctx, GLfloat t, GLuint dst, GLuint out, GLuint in, GLboolean force_boundary ); typedef void (*copy_pv_func)( GLcontext *ctx, GLuint dst, GLuint src ); +typedef void (*setup_func)( GLcontext *ctx, + GLuint start, GLuint end, + GLuint new_inputs); struct tnl_device_driver { @@ -390,87 +393,86 @@ struct tnl_device_driver { */ /*** - *** Rendering + *** Rendering -- These functions called only from t_vb_render.c ***/ - - void (*RenderStart)(GLcontext *ctx); - void (*RenderFinish)(GLcontext *ctx); - /* Called before and after all rendering operations, including DrawPixels, - * ReadPixels, Bitmap, span functions, and CopyTexImage, etc commands. - * These are a suitable place for grabbing/releasing hardware locks. - */ - - void (*RenderPrimitive)(GLcontext *ctx, GLenum mode); - /* Called between RednerStart() and RenderFinish() to indicate the - * type of primitive we're about to draw. Mode will be one of the - * modes accepted by glBegin(). - */ - - interp_func RenderInterp; - /* The interp function is called by the clipping routines when we need - * to generate an interpolated vertex. All pertinant vertex ancilliary - * data should be computed by interpolating between the 'in' and 'out' - * vertices. - */ - - copy_pv_func RenderCopyPV; - /* The copy function is used to make a copy of a vertex. All pertinant - * vertex attributes should be copied. - */ - - void (*RenderClippedPolygon)( GLcontext *ctx, const GLuint *elts, GLuint n ); - /* Render a polygon with <n> vertices whose indexes are in the <elts> - * array. - */ - - void (*RenderClippedLine)( GLcontext *ctx, GLuint v0, GLuint v1 ); - /* Render a line between the two vertices given by indexes v0 and v1. */ - - points_func PointsFunc; /* must now respect vb->elts */ - line_func LineFunc; - triangle_func TriangleFunc; - quad_func QuadFunc; - /* These functions are called in order to render points, lines, - * triangles and quads. These are only called via the T&L module. - */ - - render_func *RenderTabVerts; - render_func *RenderTabElts; - /* Render whole unclipped primitives (points, lines, linestrips, - * lineloops, etc). The tables are indexed by the GL enum of the - * primitive to be rendered. RenderTabVerts is used for non-indexed - * arrays of vertices. RenderTabElts is used for indexed arrays of - * vertices. - */ - - void (*ResetLineStipple)( GLcontext *ctx ); - /* Reset the hardware's line stipple counter. - */ - - void (*BuildProjectedVertices)( GLcontext *ctx, - GLuint start, GLuint end, - GLuint new_inputs); - /* This function is called whenever new vertices are required for - * rendering. The vertices in question are those n such that start - * <= n < end. The new_inputs parameter indicates those fields of - * the vertex which need to be updated, if only a partial repair of - * the vertex is required. - * - * This function is called only from _tnl_render_stage in tnl/t_render.c. - */ - - - GLboolean (*MultipassFunc)( GLcontext *ctx, GLuint passno ); - /* Driver may request additional render passes by returning GL_TRUE - * when this function is called. This function will be called - * after the first pass, and passes will be made until the function - * returns GL_FALSE. If no function is registered, only one pass - * is made. - * - * This function will be first invoked with passno == 1. - */ + struct { + void (*Start)(GLcontext *ctx); + void (*Finish)(GLcontext *ctx); + /* Called before and after all rendering operations, including DrawPixels, + * ReadPixels, Bitmap, span functions, and CopyTexImage, etc commands. + * These are a suitable place for grabbing/releasing hardware locks. + */ + + void (*PrimitiveNotify)(GLcontext *ctx, GLenum mode); + /* Called between RenderStart() and RenderFinish() to indicate the + * type of primitive we're about to draw. Mode will be one of the + * modes accepted by glBegin(). + */ + + interp_func Interp; + /* The interp function is called by the clipping routines when we need + * to generate an interpolated vertex. All pertinant vertex ancilliary + * data should be computed by interpolating between the 'in' and 'out' + * vertices. + */ + + copy_pv_func CopyPV; + /* The copy function is used to make a copy of a vertex. All pertinant + * vertex attributes should be copied. + */ + + void (*ClippedPolygon)( GLcontext *ctx, const GLuint *elts, GLuint n ); + /* Render a polygon with <n> vertices whose indexes are in the <elts> + * array. + */ + + void (*ClippedLine)( GLcontext *ctx, GLuint v0, GLuint v1 ); + /* Render a line between the two vertices given by indexes v0 and v1. */ + + points_func Points; /* must now respect vb->elts */ + line_func Line; + triangle_func Triangle; + quad_func Quad; + /* These functions are called in order to render points, lines, + * triangles and quads. These are only called via the T&L module. + */ + + render_func *PrimTabVerts; + render_func *PrimTabElts; + /* Render whole unclipped primitives (points, lines, linestrips, + * lineloops, etc). The tables are indexed by the GL enum of the + * primitive to be rendered. RenderTabVerts is used for non-indexed + * arrays of vertices. RenderTabElts is used for indexed arrays of + * vertices. + */ + + void (*ResetLineStipple)( GLcontext *ctx ); + /* Reset the hardware's line stipple counter. + */ + + setup_func BuildVertices; + /* This function is called whenever new vertices are required for + * rendering. The vertices in question are those n such that start + * <= n < end. The new_inputs parameter indicates those fields of + * the vertex which need to be updated, if only a partial repair of + * the vertex is required. + * + * This function is called only from _tnl_render_stage in tnl/t_render.c. + */ + + + GLboolean (*Multipass)( GLcontext *ctx, GLuint passno ); + /* Driver may request additional render passes by returning GL_TRUE + * when this function is called. This function will be called + * after the first pass, and passes will be made until the function + * returns GL_FALSE. If no function is registered, only one pass + * is made. + * + * This function will be first invoked with passno == 1. + */ + } Render; }; - + typedef struct { diff --git a/src/mesa/tnl/t_pipeline.h b/src/mesa/tnl/t_pipeline.h index 60b349d0e0..cb057df810 100644 --- a/src/mesa/tnl/t_pipeline.h +++ b/src/mesa/tnl/t_pipeline.h @@ -1,4 +1,4 @@ -/* $Id: t_pipeline.h,v 1.7 2001/03/12 00:48:43 gareth Exp $ */ +/* $Id: t_pipeline.h,v 1.8 2001/07/12 22:09:22 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -66,4 +66,10 @@ extern const struct gl_pipeline_stage *_tnl_default_pipeline[]; extern render_func _tnl_render_tab_elts[]; extern render_func _tnl_render_tab_verts[]; +extern void _tnl_RenderClippedPolygon( GLcontext *ctx, + const GLuint *elts, GLuint n ); + +extern void _tnl_RenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj ); + + #endif diff --git a/src/mesa/tnl/t_vb_cliptmp.h b/src/mesa/tnl/t_vb_cliptmp.h index 90b9b82f53..8a26ad2de7 100644 --- a/src/mesa/tnl/t_vb_cliptmp.h +++ b/src/mesa/tnl/t_vb_cliptmp.h @@ -1,4 +1,4 @@ -/* $Id: t_vb_cliptmp.h,v 1.12 2001/05/09 12:25:40 keithw Exp $ */ +/* $Id: t_vb_cliptmp.h,v 1.13 2001/07/12 22:09:22 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -124,7 +124,7 @@ static __inline void TAG(clip_line)( GLcontext *ctx, { TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; - interp_func interp = tnl->Driver.RenderInterp; + interp_func interp = tnl->Driver.Render.Interp; GLfloat (*coord)[4] = VB->ClipPtr->data; GLuint ii = i, jj = j, p; @@ -152,9 +152,9 @@ static __inline void TAG(clip_line)( GLcontext *ctx, } if ((ctx->_TriangleCaps & DD_FLATSHADE) && j != jj) - tnl->Driver.RenderCopyPV( ctx, jj, j ); + tnl->Driver.Render.CopyPV( ctx, jj, j ); - tnl->Driver.RenderClippedLine( ctx, ii, jj ); + tnl->Driver.Render.ClippedLine( ctx, ii, jj ); } @@ -166,7 +166,7 @@ static __inline void TAG(clip_tri)( GLcontext *ctx, { TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; - interp_func interp = tnl->Driver.RenderInterp; + interp_func interp = tnl->Driver.Render.Interp; GLfloat (*coord)[4] = VB->ClipPtr->data; GLuint pv = v2; GLuint vlist[2][MAX_CLIPPED_VERTICES]; @@ -203,11 +203,11 @@ static __inline void TAG(clip_tri)( GLcontext *ctx, if (ctx->_TriangleCaps & DD_FLATSHADE) { if (pv != inlist[0]) { ASSERT( inlist[0] >= VB->FirstClipped ); - tnl->Driver.RenderCopyPV( ctx, inlist[0], pv ); + tnl->Driver.Render.CopyPV( ctx, inlist[0], pv ); } } - tnl->Driver.RenderClippedPolygon( ctx, inlist, n ); + tnl->Driver.Render.ClippedPolygon( ctx, inlist, n ); } @@ -219,7 +219,7 @@ static __inline void TAG(clip_quad)( GLcontext *ctx, { TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; - interp_func interp = tnl->Driver.RenderInterp; + interp_func interp = tnl->Driver.Render.Interp; GLfloat (*coord)[4] = VB->ClipPtr->data; GLuint pv = v3; GLuint vlist[2][MAX_CLIPPED_VERTICES]; @@ -256,11 +256,11 @@ static __inline void TAG(clip_quad)( GLcontext *ctx, if (ctx->_TriangleCaps & DD_FLATSHADE) { if (pv != inlist[0]) { ASSERT( inlist[0] >= VB->FirstClipped ); - tnl->Driver.RenderCopyPV( ctx, inlist[0], pv ); + tnl->Driver.Render.CopyPV( ctx, inlist[0], pv ); } } - tnl->Driver.RenderClippedPolygon( ctx, inlist, n ); + tnl->Driver.Render.ClippedPolygon( ctx, inlist, n ); } #undef W diff --git a/src/mesa/tnl/t_vb_render.c b/src/mesa/tnl/t_vb_render.c index ec3cb02bb6..5ad8c3e5be 100644 --- a/src/mesa/tnl/t_vb_render.c +++ b/src/mesa/tnl/t_vb_render.c @@ -1,4 +1,4 @@ -/* $Id: t_vb_render.c,v 1.21 2001/06/15 15:22:08 brianp Exp $ */ +/* $Id: t_vb_render.c,v 1.22 2001/07/12 22:09:22 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -35,17 +35,8 @@ * This file makes calls to project vertices and to the point, line * and triangle rasterizers via the function pointers: * - * context->Driver.BuildProjectedVertices() + * context->Driver.Render.* * - * context->Driver.PointsFunc() - * context->Driver.LineFunc() - * context->Driver.TriangleFunc() - * context->Driver.QuadFunc() - * - * context->Driver.RenderTabVerts[] - * context->Driver.RenderTabElts[] - * - * None of these may be null. */ @@ -102,7 +93,7 @@ /* Vertices, with the possibility of clipping. */ #define RENDER_POINTS( start, count ) \ - tnl->Driver.PointsFunc( ctx, start, count ) + tnl->Driver.Render.Points( ctx, start, count ) #define RENDER_LINE( v1, v2 ) \ do { \ @@ -142,16 +133,16 @@ do { \ const GLuint * const elt = VB->Elts; \ const GLubyte *mask = VB->ClipMask; \ const GLuint sz = VB->ClipPtr->size; \ - const line_func LineFunc = tnl->Driver.LineFunc; \ - const triangle_func TriangleFunc = tnl->Driver.TriangleFunc; \ - const quad_func QuadFunc = tnl->Driver.QuadFunc; \ + const line_func LineFunc = tnl->Driver.Render.Line; \ + const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; \ + const quad_func QuadFunc = tnl->Driver.Render.Quad; \ const GLboolean stipple = ctx->Line.StippleFlag; \ (void) (LineFunc && TriangleFunc && QuadFunc); \ (void) elt; (void) mask; (void) sz; (void) stipple; #define TAG(x) clip_##x##_verts -#define INIT(x) tnl->Driver.RenderPrimitive( ctx, x ) -#define RESET_STIPPLE if (stipple) tnl->Driver.ResetLineStipple( ctx ) +#define INIT(x) tnl->Driver.Render.PrimitiveNotify( ctx, x ) +#define RESET_STIPPLE if (stipple) tnl->Driver.Render.ResetLineStipple( ctx ) #define RESET_OCCLUSION ctx->OcclusionResult = GL_TRUE #define PRESERVE_VB_DEFS #include "t_vb_rendertmp.h" @@ -174,7 +165,7 @@ static void clip_elt_triangles( GLcontext *ctx, GLuint flags ) { TNLcontext *tnl = TNL_CONTEXT(ctx); - render_func render_tris = tnl->Driver.RenderTabElts[GL_TRIANGLES]; + render_func render_tris = tnl->Driver.Render.PrimTabElts[GL_TRIANGLES]; struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; GLubyte *mask = VB->ClipMask; @@ -182,7 +173,7 @@ static void clip_elt_triangles( GLcontext *ctx, GLuint j; (void) flags; - tnl->Driver.RenderPrimitive( ctx, GL_TRIANGLES ); + tnl->Driver.Render.PrimitiveNotify( ctx, GL_TRIANGLES ); for (j=start; j < last; j+=3 ) { GLubyte c1 = mask[elt[j]]; @@ -214,7 +205,7 @@ static void clip_elt_triangles( GLcontext *ctx, /* Vertices, no clipping. */ #define RENDER_POINTS( start, count ) \ - tnl->Driver.PointsFunc( ctx, start, count ) + tnl->Driver.Render.Points( ctx, start, count ) #define RENDER_LINE( v1, v2 ) \ LineFunc( ctx, v1, v2 ) @@ -231,15 +222,15 @@ static void clip_elt_triangles( GLcontext *ctx, TNLcontext *tnl = TNL_CONTEXT(ctx); \ struct vertex_buffer *VB = &tnl->vb; \ const GLuint * const elt = VB->Elts; \ - const line_func LineFunc = tnl->Driver.LineFunc; \ - const triangle_func TriangleFunc = tnl->Driver.TriangleFunc; \ - const quad_func QuadFunc = tnl->Driver.QuadFunc; \ + const line_func LineFunc = tnl->Driver.Render.Line; \ + const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; \ + const quad_func QuadFunc = tnl->Driver.Render.Quad; \ (void) (LineFunc && TriangleFunc && QuadFunc); \ (void) elt; -#define RESET_STIPPLE tnl->Driver.ResetLineStipple( ctx ) +#define RESET_STIPPLE tnl->Driver.Render.ResetLineStipple( ctx ) #define RESET_OCCLUSION ctx->OcclusionResult = GL_TRUE -#define INIT(x) tnl->Driver.RenderPrimitive( ctx, x ) +#define INIT(x) tnl->Driver.Render.PrimitiveNotify( ctx, x ) #define RENDER_TAB_QUALIFIER #define PRESERVE_VB_DEFS #include "t_vb_rendertmp.h" @@ -253,6 +244,27 @@ static void clip_elt_triangles( GLcontext *ctx, #include "t_vb_rendertmp.h" +/**********************************************************************/ +/* Helper functions for drivers */ +/**********************************************************************/ + +void _tnl_RenderClippedPolygon( GLcontext *ctx, const GLuint *elts, GLuint n ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint *tmp = VB->Elts; + + VB->Elts = (GLuint *)elts; + tnl->Driver.Render.PrimTabElts[GL_POLYGON]( ctx, 0, n, PRIM_BEGIN|PRIM_END ); + VB->Elts = tmp; +} + +void _tnl_RenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + tnl->Driver.Render.Line( ctx, ii, jj ); +} + /**********************************************************************/ @@ -274,31 +286,33 @@ static GLboolean run_render( GLcontext *ctx, * that window coordinates are guarenteed not to change before * rendering. */ - ASSERT(tnl->Driver.RenderStart); + ASSERT(tnl->Driver.Render.Start); - tnl->Driver.RenderStart( ctx ); + tnl->Driver.Render.Start( ctx ); - ASSERT(tnl->Driver.BuildProjectedVertices); - ASSERT(tnl->Driver.RenderPrimitive); - ASSERT(tnl->Driver.PointsFunc); - ASSERT(tnl->Driver.LineFunc); - ASSERT(tnl->Driver.TriangleFunc); - ASSERT(tnl->Driver.QuadFunc); - ASSERT(tnl->Driver.ResetLineStipple); - ASSERT(tnl->Driver.RenderInterp); - ASSERT(tnl->Driver.RenderCopyPV); - ASSERT(tnl->Driver.RenderClippedLine); - ASSERT(tnl->Driver.RenderClippedPolygon); - ASSERT(tnl->Driver.RenderFinish); + ASSERT(tnl->Driver.Render.BuildVertices); + ASSERT(tnl->Driver.Render.PrimitiveNotify); + ASSERT(tnl->Driver.Render.Points); + ASSERT(tnl->Driver.Render.Line); + ASSERT(tnl->Driver.Render.Triangle); + ASSERT(tnl->Driver.Render.Quad); + ASSERT(tnl->Driver.Render.ResetLineStipple); + ASSERT(tnl->Driver.Render.Interp); + ASSERT(tnl->Driver.Render.CopyPV); + ASSERT(tnl->Driver.Render.ClippedLine); + ASSERT(tnl->Driver.Render.ClippedPolygon); + ASSERT(tnl->Driver.Render.Finish); - tnl->Driver.BuildProjectedVertices( ctx, 0, VB->Count, new_inputs ); + tnl->Driver.Render.BuildVertices( ctx, 0, VB->Count, new_inputs ); if (VB->ClipOrMask) { tab = VB->Elts ? clip_render_tab_elts : clip_render_tab_verts; clip_render_tab_elts[GL_TRIANGLES] = clip_elt_triangles; } else { - tab = VB->Elts ? tnl->Driver.RenderTabElts : tnl->Driver.RenderTabVerts; + tab = (VB->Elts ? + tnl->Driver.Render.PrimTabElts : + tnl->Driver.Render.PrimTabVerts); } do @@ -313,11 +327,11 @@ static GLboolean run_render( GLcontext *ctx, if (length) tab[flags & PRIM_MODE_MASK]( ctx, i, i + length, flags ); } - } while (tnl->Driver.MultipassFunc && - tnl->Driver.MultipassFunc( ctx, ++pass )); + } while (tnl->Driver.Render.Multipass && + tnl->Driver.Render.Multipass( ctx, ++pass )); - tnl->Driver.RenderFinish( ctx ); + tnl->Driver.Render.Finish( ctx ); /* _swrast_flush(ctx); */ /* usleep(1000000); */ return GL_FALSE; /* finished the pipe */ |