diff options
Diffstat (limited to 'xc/lib/GL/mesa/src/drv/tdfx')
33 files changed, 5786 insertions, 6794 deletions
diff --git a/xc/lib/GL/mesa/src/drv/tdfx/Imakefile b/xc/lib/GL/mesa/src/drv/tdfx/Imakefile index abb22e61a..7405bc18d 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/Imakefile +++ b/xc/lib/GL/mesa/src/drv/tdfx/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/drv/tdfx/Imakefile,v 1.28 2001/08/18 02:51:06 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/drv/tdfx/Imakefile,v 1.25.2.1 2001/06/01 07:42:23 alanh Exp $ #include <Threads.tmpl> @@ -22,13 +22,15 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/drv/tdfx/Imakefile,v 1.28 2001/08/18 02:51:06 #ifdef i386Architecture #include "../../X86/Imakefile.inc" #endif +#ifdef SparcArchitecture +#include "../../SPARC/Imakefile.inc" +#endif DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES) $(MESA_ASM_DEFINES) INCLUDES = $(X_INCLUDES) $(MESA_INCLUDES) $(DRI_INCLUDES) \ -I$(GLIDE3INCDIR) - DRIOBJS = $(GLXLIBSRC)/mesa/dri/dri_mesa.o \ - $(GLXLIBSRC)/dri/dri_tmm.o + DRIOBJS = $(GLXLIBSRC)/dri/dri_util.o DRMOBJS = $(GLXLIBSRC)/dri/drm/xf86drm.o \ $(GLXLIBSRC)/dri/drm/xf86drmHash.o \ diff --git a/xc/lib/GL/mesa/src/drv/tdfx/Imakefile.inc b/xc/lib/GL/mesa/src/drv/tdfx/Imakefile.inc index 0b7080a49..c3e85ff4a 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/Imakefile.inc +++ b/xc/lib/GL/mesa/src/drv/tdfx/Imakefile.inc @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/drv/tdfx/Imakefile.inc,v 1.3 2001/08/18 02:51:06 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/drv/tdfx/Imakefile.inc,v 1.1 2001/03/23 19:18:44 dawes Exp $ #ifndef MesaDrvSrcDir #define MesaDrvSrcDir $(GLXLIBSRC)/mesa/src/drv @@ -16,26 +16,28 @@ ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL #endif #if BuildXF86DRI - DRI_DEFINES = GlxDefines - DRI_INCLUDES = -I$(GLXLIBSRC)/dri -I$(GLXLIBSRC)/glx \ - -I$(INCLUDESRC) -I$(INCLUDESRC)/GL \ - -I$(GLXLIBSRC)/mesa/dri \ + DRI_DEFINES = GlxDefines -DX_BYTE_ORDER=ByteOrder + DRI_INCLUDES = -I$(GLXLIBSRC)/dri \ + -I$(GLXLIBSRC)/glx \ + -I$(INCLUDESRC) \ + -I$(INCLUDESRC)/GL \ -I$(SERVERSRC)/GL/dri \ -I$(XF86OSSRC) \ -I$(XF86DRIVERSRC)/tdfx \ - -I$(GLXLIBSRC)/dri/drm + -I$(XF86COMSRC) \ + -I$(GLXLIBSRC)/dri/drm \ + -I$(GLXLIBSRC)/include #endif -MESA_INCLUDES = -I$(MESASRCDIR)/src -I$(MESADRVSRCDIR)/common \ +MESA_INCLUDES = -I$(MESASRCDIR)/src \ + -I$(MESADRVSRCDIR)/common \ -I$(MESADRVSRCDIR)/tdfx X_INCLUDES = -I$(XINCLUDESRC) -I$(EXTINCSRC) TDFXSRCS = $(MESADRVTDFXBUILDDIR)tdfx_context.c \ $(MESADRVTDFXBUILDDIR)tdfx_dd.c \ - $(MESADRVTDFXBUILDDIR)tdfx_pixels.c \ - $(MESADRVTDFXBUILDDIR)tdfx_fastpath.c \ $(MESADRVTDFXBUILDDIR)tdfx_lock.c \ - $(MESADRVTDFXBUILDDIR)tdfx_pipeline.c \ + $(MESADRVTDFXBUILDDIR)tdfx_pixels.c \ $(MESADRVTDFXBUILDDIR)tdfx_render.c \ $(MESADRVTDFXBUILDDIR)tdfx_screen.c \ $(MESADRVTDFXBUILDDIR)tdfx_span.c \ @@ -44,16 +46,12 @@ MESA_INCLUDES = -I$(MESASRCDIR)/src -I$(MESADRVSRCDIR)/common \ $(MESADRVTDFXBUILDDIR)tdfx_texman.c \ $(MESADRVTDFXBUILDDIR)tdfx_texstate.c \ $(MESADRVTDFXBUILDDIR)tdfx_tris.c \ - $(MESADRVTDFXBUILDDIR)tdfx_vb.c \ - $(MESADRVTDFXBUILDDIR)tdfx_wrapper.c \ - $(MESADRVTDFXBUILDDIR)tdfx_xmesa.c + $(MESADRVTDFXBUILDDIR)tdfx_vb.c TDFXOBJS = $(MESADRVTDFXBUILDDIR)tdfx_context.o \ $(MESADRVTDFXBUILDDIR)tdfx_dd.o \ - $(MESADRVTDFXBUILDDIR)tdfx_pixels.o \ - $(MESADRVTDFXBUILDDIR)tdfx_fastpath.o \ $(MESADRVTDFXBUILDDIR)tdfx_lock.o \ - $(MESADRVTDFXBUILDDIR)tdfx_pipeline.o \ + $(MESADRVTDFXBUILDDIR)tdfx_pixels.o \ $(MESADRVTDFXBUILDDIR)tdfx_render.o \ $(MESADRVTDFXBUILDDIR)tdfx_screen.o \ $(MESADRVTDFXBUILDDIR)tdfx_span.o \ @@ -62,16 +60,12 @@ MESA_INCLUDES = -I$(MESASRCDIR)/src -I$(MESADRVSRCDIR)/common \ $(MESADRVTDFXBUILDDIR)tdfx_texman.o \ $(MESADRVTDFXBUILDDIR)tdfx_texstate.o \ $(MESADRVTDFXBUILDDIR)tdfx_tris.o \ - $(MESADRVTDFXBUILDDIR)tdfx_vb.o \ - $(MESADRVTDFXBUILDDIR)tdfx_wrapper.o \ - $(MESADRVTDFXBUILDDIR)tdfx_xmesa.o + $(MESADRVTDFXBUILDDIR)tdfx_vb.o TDFXUOBJS = $(MESADRVTDFXBUILDDIR)unshared/tdfx_context.o \ $(MESADRVTDFXBUILDDIR)unshared/tdfx_dd.o \ - $(MESADRVTDFXBUILDDIR)unshared/tdfx_pixels.o \ - $(MESADRVTDFXBUILDDIR)unshared/tdfx_fastpath.o \ $(MESADRVTDFXBUILDDIR)unshared/tdfx_lock.o \ - $(MESADRVTDFXBUILDDIR)unshared/tdfx_pipeline.o \ + $(MESADRVTDFXBUILDDIR)unshared/tdfx_pixels.o \ $(MESADRVTDFXBUILDDIR)unshared/tdfx_render.o \ $(MESADRVTDFXBUILDDIR)unshared/tdfx_screen.o \ $(MESADRVTDFXBUILDDIR)unshared/tdfx_span.o \ @@ -80,16 +74,12 @@ MESA_INCLUDES = -I$(MESASRCDIR)/src -I$(MESADRVSRCDIR)/common \ $(MESADRVTDFXBUILDDIR)unshared/tdfx_texman.o \ $(MESADRVTDFXBUILDDIR)unshared/tdfx_texstate.o \ $(MESADRVTDFXBUILDDIR)unshared/tdfx_tris.o \ - $(MESADRVTDFXBUILDDIR)unshared/tdfx_vb.o \ - $(MESADRVTDFXBUILDDIR)unshared/tdfx_wrapper.o \ - $(MESADRVTDFXBUILDDIR)unshared/tdfx_xmesa.o + $(MESADRVTDFXBUILDDIR)unshared/tdfx_vb.o TDFXDOBJS = $(MESADRVTDFXBUILDDIR)debugger/tdfx_context.o \ $(MESADRVTDFXBUILDDIR)debugger/tdfx_dd.o \ - $(MESADRVTDFXBUILDDIR)debugger/tdfx_pixels.o \ - $(MESADRVTDFXBUILDDIR)debugger/tdfx_fastpath.o \ $(MESADRVTDFXBUILDDIR)debugger/tdfx_lock.o \ - $(MESADRVTDFXBUILDDIR)debugger/tdfx_pipeline.o \ + $(MESADRVTDFXBUILDDIR)debugger/tdfx_pixels.o \ $(MESADRVTDFXBUILDDIR)debugger/tdfx_render.o \ $(MESADRVTDFXBUILDDIR)debugger/tdfx_screen.o \ $(MESADRVTDFXBUILDDIR)debugger/tdfx_span.o \ @@ -98,16 +88,12 @@ MESA_INCLUDES = -I$(MESASRCDIR)/src -I$(MESADRVSRCDIR)/common \ $(MESADRVTDFXBUILDDIR)debugger/tdfx_texman.o \ $(MESADRVTDFXBUILDDIR)debugger/tdfx_texstate.o \ $(MESADRVTDFXBUILDDIR)debugger/tdfx_tris.o \ - $(MESADRVTDFXBUILDDIR)debugger/tdfx_vb.o \ - $(MESADRVTDFXBUILDDIR)debugger/tdfx_wrapper.o \ - $(MESADRVTDFXBUILDDIR)debugger/tdfx_xmesa.o + $(MESADRVTDFXBUILDDIR)debugger/tdfx_vb.o TDFXPOBJS = $(MESADRVTDFXBUILDDIR)profiled/tdfx_context.o \ $(MESADRVTDFXBUILDDIR)profiled/tdfx_dd.o \ - $(MESADRVTDFXBUILDDIR)profiled/tdfx_pixels.o \ - $(MESADRVTDFXBUILDDIR)profiled/tdfx_fastpath.o \ $(MESADRVTDFXBUILDDIR)profiled/tdfx_lock.o \ - $(MESADRVTDFXBUILDDIR)profiled/tdfx_pipeline.o \ + $(MESADRVTDFXBUILDDIR)profiled/tdfx_pixels.o \ $(MESADRVTDFXBUILDDIR)profiled/tdfx_render.o \ $(MESADRVTDFXBUILDDIR)profiled/tdfx_screen.o \ $(MESADRVTDFXBUILDDIR)profiled/tdfx_span.o \ @@ -116,17 +102,13 @@ MESA_INCLUDES = -I$(MESASRCDIR)/src -I$(MESADRVSRCDIR)/common \ $(MESADRVTDFXBUILDDIR)profiled/tdfx_texman.o \ $(MESADRVTDFXBUILDDIR)profiled/tdfx_texstate.o \ $(MESADRVTDFXBUILDDIR)profiled/tdfx_tris.o \ - $(MESADRVTDFXBUILDDIR)profiled/tdfx_vb.o \ - $(MESADRVTDFXBUILDDIR)profiled/tdfx_wrapper.o \ - $(MESADRVTDFXBUILDDIR)profiled/tdfx_xmesa.o + $(MESADRVTDFXBUILDDIR)profiled/tdfx_vb.o #ifdef NeedToLinkMesaSrc LinkSourceFile(tdfx_context.c, $(MESADRVSRCDIR)/tdfx) LinkSourceFile(tdfx_dd.c, $(MESADRVSRCDIR)/tdfx) -LinkSourceFile(tdfx_pixels.c, $(MESADRVSRCDIR)/tdfx) -LinkSourceFile(tdfx_fastpath.c, $(MESADRVSRCDIR)/tdfx) LinkSourceFile(tdfx_lock.c, $(MESADRVSRCDIR)/tdfx) -LinkSourceFile(tdfx_pipeline.c, $(MESADRVSRCDIR)/tdfx) +LinkSourceFile(tdfx_pixels.c, $(MESADRVSRCDIR)/tdfx) LinkSourceFile(tdfx_render.c, $(MESADRVSRCDIR)/tdfx) LinkSourceFile(tdfx_screen.c, $(MESADRVSRCDIR)/tdfx) LinkSourceFile(tdfx_span.c, $(MESADRVSRCDIR)/tdfx) @@ -136,7 +118,4 @@ LinkSourceFile(tdfx_texman.c, $(MESADRVSRCDIR)/tdfx) LinkSourceFile(tdfx_texstate.c, $(MESADRVSRCDIR)/tdfx) LinkSourceFile(tdfx_tris.c, $(MESADRVSRCDIR)/tdfx) LinkSourceFile(tdfx_vb.c, $(MESADRVSRCDIR)/tdfx) -LinkSourceFile(tdfx_wrapper.c, $(MESADRVSRCDIR)/tdfx) -LinkSourceFile(tdfx_xmesa.c, $(MESADRVSRCDIR)/tdfx) #endif - diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.c index fa532ba36..faf4972d0 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.c @@ -36,30 +36,23 @@ */ #include <dlfcn.h> -#include "dri_glide.h" #include "tdfx_context.h" #include "tdfx_dd.h" #include "tdfx_state.h" #include "tdfx_vb.h" +#include "tdfx_tris.h" #include "tdfx_render.h" -#include "tdfx_pipeline.h" #include "tdfx_span.h" -#include "tdfx_tex.h" #include "tdfx_texman.h" #include "extensions.h" -#ifndef TDFX_DEBUG -int TDFX_DEBUG = (0 -/* | DEBUG_ALWAYS_SYNC */ -/* | DEBUG_VERBOSE_API */ -/* | DEBUG_VERBOSE_MSG */ -/* | DEBUG_VERBOSE_LRU */ -/* | DEBUG_VERBOSE_DRI */ -/* | DEBUG_VERBOSE_IOCTL */ -/* | DEBUG_VERBOSE_2D */ -/* | DEBUG_VERBOSE_TEXTURE */ - ); -#endif + +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "array_cache/acache.h" + +#include "tnl/tnl.h" +#include "tnl/t_pipeline.h" #if 0 @@ -79,27 +72,25 @@ static void tdfxDDInitExtensions( GLcontext *ctx ) { tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - gl_extensions_disable( ctx, "GL_EXT_blend_logic_op" ); - gl_extensions_disable( ctx, "GL_EXT_blend_minmax" ); - gl_extensions_disable( ctx, "GL_EXT_blend_subtract" ); - gl_extensions_disable( ctx, "GL_EXT_blend_color" ); - gl_extensions_disable( ctx, "GL_EXT_blend_func_separate" ); - gl_extensions_disable( ctx, "GL_EXT_point_parameters" ); - gl_extensions_disable( ctx, "GL_EXT_shared_texture_palette" ); - gl_extensions_disable( ctx, "GL_INGR_blend_func_separate" ); - gl_extensions_enable( ctx, "GL_HP_occlusion_test" ); - - if ( fxMesa->numTMUs == 1 ) { - gl_extensions_disable( ctx, "GL_EXT_texture_env_add" ); - gl_extensions_disable( ctx, "GL_ARB_multitexture" ); + _mesa_enable_extension( ctx, "GL_HP_occlusion_test" ); + _mesa_enable_extension( ctx, "GL_EXT_paletted_texture" ); + _mesa_enable_extension( ctx, "GL_EXT_texture_lod_bias" ); + + if ( fxMesa->haveTwoTMUs ) { + _mesa_enable_extension( ctx, "GL_EXT_texture_env_add" ); + _mesa_enable_extension( ctx, "GL_ARB_multitexture" ); } if ( TDFX_IS_NAPALM( fxMesa ) ) { - gl_extensions_enable( ctx, "GL_EXT_texture_env_combine" ); +#if 0 + _mesa_enable_extension( ctx, "GL_ARB_texture_compression" ); + _mesa_enable_extension( ctx, "GL_3DFX_texture_compression_FXT1" ); +#endif + _mesa_enable_extension( ctx, "GL_EXT_texture_env_combine" ); } if (fxMesa->haveHwStencil) { - gl_extensions_enable( ctx, "GL_EXT_stencil_wrap" ); + _mesa_enable_extension( ctx, "GL_EXT_stencil_wrap" ); } /* Example of hooking in an extension function. @@ -124,22 +115,46 @@ static void tdfxDDInitExtensions( GLcontext *ctx ) -GLboolean tdfxCreateContext( Display *dpy, GLvisual *mesaVis, - __DRIcontextPrivate *driContextPriv ) +static const struct gl_pipeline_stage *tdfx_pipeline[] = { + &_tnl_vertex_transform_stage, + &_tnl_normal_transform_stage, + &_tnl_lighting_stage, /* REMOVE: fog coord stage */ + &_tnl_texgen_stage, + &_tnl_texture_transform_stage, + /* REMOVE: point attenuation stage */ + &_tnl_render_stage, + 0, +}; + + +GLboolean tdfxCreateContext( Display *dpy, const __GLcontextModes *mesaVis, + __DRIcontextPrivate *driContextPriv, + void *sharedContextPrivate ) { tdfxContextPtr fxMesa; - GLcontext *ctx = driContextPriv->mesaContext; + GLcontext *ctx, *shareCtx; __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; tdfxScreenPrivate *fxScreen = (tdfxScreenPrivate *) sPriv->private; TDFXSAREAPriv *saPriv = (TDFXSAREAPriv *) ((char *) sPriv->pSAREA + - fxScreen->sarea_priv_offset); + sizeof(XF86DRISAREARec)); - fxMesa = (tdfxContextPtr) MALLOC( sizeof(tdfxContextRec) ); - if ( !fxMesa ) { + /* Allocate tdfx context */ + fxMesa = (tdfxContextPtr) CALLOC( sizeof(tdfxContextRec) ); + if (!fxMesa) + return GL_FALSE; + + /* Allocate the Mesa context */ + if (sharedContextPrivate) + shareCtx = ((tdfxContextPtr) sharedContextPrivate)->glCtx; + else + shareCtx = NULL; + fxMesa->glCtx = _mesa_create_context(mesaVis, shareCtx, fxMesa, GL_TRUE); + if (!fxMesa->glCtx) { + FREE(fxMesa); return GL_FALSE; } - BZERO(fxMesa, sizeof(tdfxContextRec)); + driContextPriv->driverPrivate = fxMesa; /* Mirror some important DRI state */ @@ -152,25 +167,19 @@ GLboolean tdfxCreateContext( Display *dpy, GLvisual *mesaVis, fxMesa->fxScreen = fxScreen; fxMesa->sarea = saPriv; - - fxMesa->haveHwStencil = ( TDFX_IS_NAPALM( fxMesa ) && - mesaVis->StencilBits && - mesaVis->DepthBits == 24 ); + mesaVis->stencilBits && + mesaVis->depthBits == 24 ); fxMesa->screen_width = fxScreen->width; fxMesa->screen_height = fxScreen->height; + fxMesa->new_gl_state = ~0; fxMesa->new_state = ~0; fxMesa->dirty = ~0; - fxMesa->vertexFormat = 0; - - fxMesa->glCtx = driContextPriv->mesaContext; - fxMesa->glVis = mesaVis; - - /* NOTE: This MUST be called before any Glide functions are called! */ - if (!tdfxInitGlide(fxMesa)) { + /* NOTE: This must be here before any Glide calls! */ + if (!tdfxInitGlide( fxMesa )) { FREE(fxMesa); return GL_FALSE; } @@ -196,10 +205,16 @@ GLboolean tdfxCreateContext( Display *dpy, GLvisual *mesaVis, fxMesa->Glide.Initialized = GL_FALSE; fxMesa->Glide.Board = 0; - if ( getenv( "FX_EMULATE_SINGLE_TMU" ) || TDFX_IS_BANSHEE( fxMesa ) ) { - fxMesa->numTMUs = 1; - } else { - fxMesa->numTMUs = 2; + + if (getenv("FX_EMULATE_SINGLE_TMU")) { + fxMesa->haveTwoTMUs = GL_FALSE; + } + else { + if ( TDFX_IS_BANSHEE( fxMesa ) ) { + fxMesa->haveTwoTMUs = GL_FALSE; + } else { + fxMesa->haveTwoTMUs = GL_TRUE; + } } fxMesa->stats.swapBuffer = 0; @@ -209,61 +224,58 @@ GLboolean tdfxCreateContext( Display *dpy, GLvisual *mesaVis, fxMesa->tmuSrc = TDFX_TMU_NONE; + ctx = fxMesa->glCtx; if ( TDFX_IS_NAPALM( fxMesa ) ) { ctx->Const.MaxTextureLevels = 12; - ctx->Const.MaxTextureSize = 2048; ctx->Const.NumCompressedTextureFormats = 1; } else { ctx->Const.MaxTextureLevels = 9; - ctx->Const.MaxTextureSize = 256; ctx->Const.NumCompressedTextureFormats = 0; } ctx->Const.MaxTextureUnits = TDFX_IS_BANSHEE( fxMesa ) ? 1 : 2; - ctx->NewState |= NEW_DRVSTATE1; - - ctx->DriverCtx = (void *) fxMesa; - - tdfxDDInitExtensions( ctx ); - - tdfxDDInitDriverFuncs( ctx ); - tdfxDDInitStateFuncs( ctx ); - tdfxDDInitRenderFuncs( ctx ); - tdfxDDInitSpanFuncs( ctx ); - tdfxDDInitTextureFuncs( ctx ); - - ctx->Driver.TriangleCaps = (DD_TRI_CULL | - DD_TRI_LIGHT_TWOSIDE | - DD_TRI_STIPPLE | - DD_TRI_OFFSET); + /* No wide points. + */ + ctx->Const.MinPointSize = 1.0; + ctx->Const.MinPointSizeAA = 1.0; + ctx->Const.MaxPointSize = 1.0; + ctx->Const.MaxPointSizeAA = 1.0; - if ( ctx->VB ) - tdfxDDRegisterVB( ctx->VB ); + /* Disable wide lines as we can't antialias them correctly in + * hardware. + */ + ctx->Const.MinLineWidth = 1.0; + ctx->Const.MinLineWidthAA = 1.0; + ctx->Const.MaxLineWidth = 1.0; + ctx->Const.MaxLineWidthAA = 1.0; + ctx->Const.LineWidthGranularity = 1.0; - if ( ctx->NrPipelineStages ) - ctx->NrPipelineStages = - tdfxDDRegisterPipelineStages( ctx->PipelineStage, - ctx->PipelineStage, - ctx->NrPipelineStages ); + /* Initialize the software rasterizer and helper modules. + */ + _swrast_CreateContext( ctx ); + _ac_CreateContext( ctx ); + _tnl_CreateContext( ctx ); + _swsetup_CreateContext( ctx ); - /* Run the config file */ - gl_context_initialize( ctx ); + /* Install the customized pipeline: + */ + _tnl_destroy_pipeline( ctx ); + _tnl_install_pipeline( ctx, tdfx_pipeline ); -#if 0 - /* HACK: Allocate buffer for vertex data. + /* Configure swrast to match hardware characteristics: */ - if ( fxMesa->buffer ) { - ALIGN_FREE( fxMesa->buffer ); - } - fxMesa->buffer = ALIGN_MALLOC( 2048, 32 ); - fxMesa->buffer_total = 2048; - fxMesa->buffer_used = 0; -#endif + _swrast_allow_pixel_fog( ctx, GL_TRUE ); + _swrast_allow_vertex_fog( ctx, GL_FALSE ); + tdfxDDInitExtensions( ctx ); + tdfxDDInitDriverFuncs( ctx ); + tdfxDDInitStateFuncs( ctx ); + tdfxDDInitRenderFuncs( ctx ); + tdfxDDInitSpanFuncs( ctx ); + tdfxDDInitTriFuncs( ctx ); + tdfxInitVB( ctx ); tdfxInitState( fxMesa ); - driContextPriv->driverPrivate = (void *) fxMesa; - return GL_TRUE; } @@ -284,26 +296,40 @@ static GLboolean tdfxInitVertexFormats( tdfxContextPtr fxMesa ) } } - /* Single textured vertex format - 32 bytes. + /* Tiny vertex format - 16 bytes. */ fxMesa->Glide.grReset( GR_VERTEX_PARAMETER ); + fxMesa->Glide.grCoordinateSpace( GR_WINDOW_COORDS ); + fxMesa->Glide.grVertexLayout( GR_PARAM_XY, TDFX_XY_OFFSET, GR_PARAM_ENABLE ); + fxMesa->Glide.grVertexLayout( GR_PARAM_Z, TDFX_Z_OFFSET, GR_PARAM_ENABLE ); + fxMesa->Glide.grVertexLayout( GR_PARAM_PARGB, TDFX_Q_OFFSET, GR_PARAM_ENABLE ); + fxMesa->Glide.grGlideGetVertexLayout( fxMesa->layout[TDFX_LAYOUT_TINY] ); + /* Non textured vertex format - 24 bytes (Need w for table fog) + */ + fxMesa->Glide.grReset( GR_VERTEX_PARAMETER ); fxMesa->Glide.grCoordinateSpace( GR_WINDOW_COORDS ); fxMesa->Glide.grVertexLayout( GR_PARAM_XY, TDFX_XY_OFFSET, GR_PARAM_ENABLE ); fxMesa->Glide.grVertexLayout( GR_PARAM_Z, TDFX_Z_OFFSET, GR_PARAM_ENABLE ); fxMesa->Glide.grVertexLayout( GR_PARAM_Q, TDFX_Q_OFFSET, GR_PARAM_ENABLE ); fxMesa->Glide.grVertexLayout( GR_PARAM_PARGB, TDFX_ARGB_OFFSET, GR_PARAM_ENABLE ); - fxMesa->Glide.grVertexLayout( GR_PARAM_ST0, TDFX_ST0_OFFSET, GR_PARAM_ENABLE ); -#if 0 - fxMesa->Glide.grVertexLayout( GR_PARAM_FOG_EXT, TDFX_FOG_OFFSET, GR_PARAM_ENABLE ); -#endif + fxMesa->Glide.grGlideGetVertexLayout( fxMesa->layout[TDFX_LAYOUT_NOTEX] ); + /* Single textured vertex format - 32 bytes. + */ + fxMesa->Glide.grReset( GR_VERTEX_PARAMETER ); + fxMesa->Glide.grCoordinateSpace( GR_WINDOW_COORDS ); + fxMesa->Glide.grVertexLayout( GR_PARAM_XY, TDFX_XY_OFFSET, GR_PARAM_ENABLE ); + fxMesa->Glide.grVertexLayout( GR_PARAM_Z, TDFX_Z_OFFSET, GR_PARAM_ENABLE ); + fxMesa->Glide.grVertexLayout( GR_PARAM_Q, TDFX_Q_OFFSET, GR_PARAM_ENABLE ); + fxMesa->Glide.grVertexLayout( GR_PARAM_PARGB, TDFX_ARGB_OFFSET, GR_PARAM_ENABLE ); + fxMesa->Glide.grVertexLayout( GR_PARAM_ST0, TDFX_ST0_OFFSET, GR_PARAM_ENABLE ); + /*grVertexLayout( GR_PARAM_FOG_EXT, TDFX_FOG_OFFSET, GR_PARAM_ENABLE );*/ fxMesa->Glide.grGlideGetVertexLayout( fxMesa->layout[TDFX_LAYOUT_SINGLE] ); /* Multitextured vertex format - 40 bytes. */ fxMesa->Glide.grReset( GR_VERTEX_PARAMETER ); - fxMesa->Glide.grCoordinateSpace( GR_WINDOW_COORDS ); fxMesa->Glide.grVertexLayout( GR_PARAM_XY, TDFX_XY_OFFSET, GR_PARAM_ENABLE ); fxMesa->Glide.grVertexLayout( GR_PARAM_Z, TDFX_Z_OFFSET, GR_PARAM_ENABLE ); @@ -311,29 +337,22 @@ static GLboolean tdfxInitVertexFormats( tdfxContextPtr fxMesa ) fxMesa->Glide.grVertexLayout( GR_PARAM_PARGB, TDFX_ARGB_OFFSET, GR_PARAM_ENABLE ); fxMesa->Glide.grVertexLayout( GR_PARAM_ST0, TDFX_ST0_OFFSET, GR_PARAM_ENABLE ); fxMesa->Glide.grVertexLayout( GR_PARAM_ST1, TDFX_ST1_OFFSET, GR_PARAM_ENABLE ); -#if 0 - fxMesa->Glide.grVertexLayout( GR_PARAM_FOG_EXT, TDFX_FOG_OFFSET, GR_PARAM_ENABLE ); -#endif - + /*fxMesa->Glide.grVertexLayout( GR_PARAM_FOG_EXT, TDFX_FOG_OFFSET, GR_PARAM_ENABLE );*/ fxMesa->Glide.grGlideGetVertexLayout( fxMesa->layout[TDFX_LAYOUT_MULTI] ); /* Projected texture vertex format - 48 bytes. */ fxMesa->Glide.grReset( GR_VERTEX_PARAMETER ); - fxMesa->Glide.grCoordinateSpace( GR_WINDOW_COORDS ); fxMesa->Glide.grVertexLayout( GR_PARAM_XY, TDFX_XY_OFFSET, GR_PARAM_ENABLE ); fxMesa->Glide.grVertexLayout( GR_PARAM_Z, TDFX_Z_OFFSET, GR_PARAM_ENABLE ); fxMesa->Glide.grVertexLayout( GR_PARAM_Q, TDFX_Q_OFFSET, GR_PARAM_ENABLE ); fxMesa->Glide.grVertexLayout( GR_PARAM_PARGB, TDFX_ARGB_OFFSET, GR_PARAM_ENABLE ); fxMesa->Glide.grVertexLayout( GR_PARAM_ST0, TDFX_ST0_OFFSET, GR_PARAM_ENABLE ); - fxMesa->Glide.grVertexLayout( GR_PARAM_ST1, TDFX_ST1_OFFSET, GR_PARAM_ENABLE ); fxMesa->Glide.grVertexLayout( GR_PARAM_Q0, TDFX_Q0_OFFSET, GR_PARAM_ENABLE ); + fxMesa->Glide.grVertexLayout( GR_PARAM_ST1, TDFX_ST1_OFFSET, GR_PARAM_ENABLE ); fxMesa->Glide.grVertexLayout( GR_PARAM_Q1, TDFX_Q1_OFFSET, GR_PARAM_ENABLE ); -#if 0 - fxMesa->Glide.grVertexLayout( GR_PARAM_FOG_EXT, TDFX_FOG_OFFSET, GR_PARAM_ENABLE ); -#endif - + /*fxMesa->Glide.grVertexLayout( GR_PARAM_FOG_EXT, TDFX_FOG_OFFSET, GR_PARAM_ENABLE );*/ fxMesa->Glide.grGlideGetVertexLayout( fxMesa->layout[TDFX_LAYOUT_PROJECT] ); UNLOCK_HARDWARE( fxMesa ); @@ -345,8 +364,8 @@ static GLboolean tdfxInitVertexFormats( tdfxContextPtr fxMesa ) /* * Initialize the state in an tdfxContextPtr struct. */ -GLboolean tdfxInitContext( __DRIdrawablePrivate *driDrawPriv, - tdfxContextPtr fxMesa ) +static GLboolean +tdfxInitContext( __DRIdrawablePrivate *driDrawPriv, tdfxContextPtr fxMesa ) { /* KW: Would be nice to make one of these a member of the other. */ @@ -397,7 +416,7 @@ GLboolean tdfxInitContext( __DRIdrawablePrivate *driDrawPriv, LOCK_HARDWARE( fxMesa ); - if ( fxMesa->glVis->DepthBits > 0 ) { + if ( fxMesa->glCtx->Visual.depthBits > 0 ) { fxMesa->Glide.grDepthBufferMode(GR_DEPTHBUFFER_ZBUFFER); } else { fxMesa->Glide.grDepthBufferMode(GR_DEPTHBUFFER_DISABLE); @@ -444,6 +463,14 @@ GLboolean tdfxInitContext( __DRIdrawablePrivate *driDrawPriv, UNLOCK_HARDWARE( fxMesa ); + { + const char *debug = getenv("LIBGL_DEBUG"); + if (debug && strstr(debug, "fallbacks")) { + fxMesa->debugFallbacks = GL_TRUE; + } + } + + fxMesa->numClipRects = 0; fxMesa->pClipRects = NULL; fxMesa->scissoredClipRects = GL_FALSE; @@ -454,37 +481,223 @@ GLboolean tdfxInitContext( __DRIdrawablePrivate *driDrawPriv, } -void tdfxDestroyContext( tdfxContextPtr fxMesa ) +void +tdfxDestroyContext( __DRIcontextPrivate *driContextPriv ) { + tdfxContextPtr fxMesa = (tdfxContextPtr) driContextPriv->driverPrivate; + if ( TDFX_DEBUG & DEBUG_VERBOSE_DRI ) { fprintf( stderr, "%s( %p )\n", __FUNCTION__, fxMesa ); } if ( fxMesa ) { - GLcontext *ctx = fxMesa->glCtx; - struct gl_texture_object *tObj; - - if ( ctx->Shared->RefCount == 1 && fxMesa->driDrawable ) { + if (fxMesa->glCtx->Shared->RefCount == 1 && fxMesa->driDrawable) { /* This share group is about to go away, free our private * texture object data. */ - LOCK_HARDWARE( fxMesa ); - for ( tObj = ctx->Shared->TexObjectList ; tObj ; tObj = tObj->Next ) { - tdfxTMFreeTextureLocked( fxMesa, tObj ); + struct gl_texture_object *tObj; + tObj = fxMesa->glCtx->Shared->TexObjectList; + while (tObj) { + tdfxTMFreeTexture(fxMesa, tObj); + tObj = tObj->Next; } - UNLOCK_HARDWARE( fxMesa ); } - tdfxTMClose( fxMesa ); /* free texture memory */ - FREE( fxMesa ); + tdfxTMClose(fxMesa); /* free texture memory */ + + _swsetup_DestroyContext( fxMesa->glCtx ); + _tnl_DestroyContext( fxMesa->glCtx ); + _ac_DestroyContext( fxMesa->glCtx ); + _swrast_DestroyContext( fxMesa->glCtx ); + + tdfxFreeVB( fxMesa->glCtx ); + + /* Free Mesa context */ + fxMesa->glCtx->DriverCtx = NULL; + _mesa_destroy_context(fxMesa->glCtx); + + /* free the tdfx context */ + XFree( fxMesa ); + } +} + + +GLboolean +tdfxUnbindContext( __DRIcontextPrivate *driContextPriv ) +{ + GET_CURRENT_CONTEXT(ctx); + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + + if ( TDFX_DEBUG & DEBUG_VERBOSE_DRI ) { + fprintf( stderr, "%s( %p )\n", __FUNCTION__, driContextPriv ); + } + + if ( driContextPriv && (tdfxContextPtr) driContextPriv == fxMesa ) { + LOCK_HARDWARE(fxMesa); + fxMesa->Glide.grGlideGetState(fxMesa->Glide.State); + UNLOCK_HARDWARE(fxMesa); + } + return GL_TRUE; +} + + +GLboolean +tdfxMakeCurrent( __DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv ) +{ + if ( TDFX_DEBUG & DEBUG_VERBOSE_DRI ) { + fprintf( stderr, "%s( %p )\n", __FUNCTION__, driContextPriv ); + } + + if ( driContextPriv ) { + tdfxContextPtr newFx = (tdfxContextPtr) driContextPriv->driverPrivate; + GLcontext *newCtx = newFx->glCtx; + GET_CURRENT_CONTEXT(curCtx); + + if ( newFx->driDrawable != driDrawPriv ) { + newFx->driDrawable = driDrawPriv; + newFx->dirty = ~0; + } + else if (curCtx == newCtx) { + /* same drawable, same context -> no-op */ + /* Need to call _mesa_make_current2() in order to make sure API + * dispatch is set correctly. + */ + _mesa_make_current2( newCtx, + (GLframebuffer *) driDrawPriv->driverPrivate, + (GLframebuffer *) driReadPriv->driverPrivate ); + return GL_TRUE; + } + + if ( !newFx->Glide.Initialized ) { + if ( !tdfxInitContext( driDrawPriv, newFx ) ) + return GL_FALSE; + + LOCK_HARDWARE( newFx ); + + /* FIXME: Force loading of window information */ + newFx->width = 0; + tdfxUpdateClipping(newCtx); + tdfxUploadClipping(newFx); + + UNLOCK_HARDWARE( newFx ); + } else { + LOCK_HARDWARE( newFx ); + + newFx->Glide.grSstSelect( newFx->Glide.Board ); + newFx->Glide.grGlideSetState( newFx->Glide.State ); + + tdfxUpdateClipping(newCtx); + tdfxUploadClipping(newFx); + + UNLOCK_HARDWARE( newFx ); + } + + _mesa_make_current2( newCtx, + (GLframebuffer *) driDrawPriv->driverPrivate, + (GLframebuffer *) driReadPriv->driverPrivate ); + + if ( !newCtx->Viewport.Width ) { + _mesa_set_viewport( newCtx, 0, 0, driDrawPriv->w, driDrawPriv->h ); + } + } else { + _mesa_make_current( 0, 0 ); } -#if 0 - glx_fini_prof(); -#endif + return GL_TRUE; } +/* + * Enable this to trace calls to various Glide functions. + */ +/*#define DEBUG_TRAP*/ +#ifdef DEBUG_TRAP +static void (*real_grDrawTriangle)( const void *a, const void *b, const void *c ); +static void (*real_grDrawPoint)( const void *a ); +static void (*real_grDrawVertexArray)(FxU32 mode, FxU32 Count, void *pointers); +static void (*real_grDrawVertexArrayContiguous)(FxU32 mode, FxU32 Count, + void *pointers, FxU32 stride); +static void (*real_grClipWindow)( FxU32 minx, FxU32 miny, FxU32 maxx, FxU32 maxy ); + +static void (*real_grVertexLayout)(FxU32 param, FxI32 offset, FxU32 mode); +static void (*real_grGlideGetVertexLayout)( void *layout ); +static void (*real_grGlideSetVertexLayout)( const void *layout ); + +static void (*real_grTexDownloadMipMapLevel)( GrChipID_t tmu, + FxU32 startAddress, + GrLOD_t thisLod, + GrLOD_t largeLod, + GrAspectRatio_t aspectRatio, + GrTextureFormat_t format, + FxU32 evenOdd, + void *data ); + + +static void debug_grDrawTriangle( const void *a, const void *b, const void *c ) +{ + printf("%s\n", __FUNCTION__); + (*real_grDrawTriangle)(a, b, c); +} + +static void debug_grDrawPoint( const void *a ) +{ + const float *f = (const float *) a; + printf("%s %g %g\n", __FUNCTION__, f[0], f[1]); + (*real_grDrawPoint)(a); +} + +static void debug_grDrawVertexArray(FxU32 mode, FxU32 Count, void *pointers) +{ + printf("%s count=%d\n", __FUNCTION__, (int) Count); + (*real_grDrawVertexArray)(mode, Count, pointers); +} + +static void debug_grDrawVertexArrayContiguous(FxU32 mode, FxU32 Count, + void *pointers, FxU32 stride) +{ + printf("%s mode=0x%x count=%d\n", __FUNCTION__, (int) mode, (int) Count); + (*real_grDrawVertexArrayContiguous)(mode, Count, pointers, stride); +} + +static void debug_grClipWindow( FxU32 minx, FxU32 miny, FxU32 maxx, FxU32 maxy ) +{ + printf("%s %d,%d .. %d,%d\n", __FUNCTION__, + (int) minx, (int) miny, (int) maxx, (int) maxy); + (*real_grClipWindow)(minx, miny, maxx, maxy); +} + +static void debug_grVertexLayout(FxU32 param, FxI32 offset, FxU32 mode) +{ + (*real_grVertexLayout)(param, offset, mode); +} + +static void debug_grGlideGetVertexLayout( void *layout ) +{ + (*real_grGlideGetVertexLayout)(layout); +} + +static void debug_grGlideSetVertexLayout( const void *layout ) +{ + (*real_grGlideSetVertexLayout)(layout); +} + +static void debug_grTexDownloadMipMapLevel( GrChipID_t tmu, + FxU32 startAddress, + GrLOD_t thisLod, + GrLOD_t largeLod, + GrAspectRatio_t aspectRatio, + GrTextureFormat_t format, + FxU32 evenOdd, + void *data ) +{ + (*real_grTexDownloadMipMapLevel)(tmu, startAddress, thisLod, largeLod, + aspectRatio, format, evenOdd, data); +} + +#endif + /* * Examine the context's deviceID to determine what kind of 3dfx hardware @@ -513,10 +726,8 @@ GLboolean tdfxInitGlide(tdfxContextPtr tmesa) break; default: { - char err[1000]; - sprintf(err, "unrecognized 3dfx deviceID: 0x%x", + __driUtilMessage("unrecognized 3dfx deviceID: 0x%x", tmesa->fxScreen->deviceID); - __driMesaMessage(err); } return GL_FALSE; } @@ -528,13 +739,10 @@ GLboolean tdfxInitGlide(tdfxContextPtr tmesa) */ libHandle = dlopen(defaultGlide, RTLD_NOW); if (!libHandle) { - char err[1000]; - sprintf(err, + __driUtilMessage( "can't find Glide library, dlopen(%s) and dlopen(%s) both failed.", libName, defaultGlide); - __driMesaMessage(err); - sprintf(err, "dlerror() message: %s", dlerror()); - __driMesaMessage(err); + __driUtilMessage("dlerror() message: %s", dlerror()); return GL_FALSE; } libName = defaultGlide; @@ -550,10 +758,8 @@ GLboolean tdfxInitGlide(tdfxContextPtr tmesa) #define GET_FUNCTION(PTR, NAME) \ tmesa->Glide.PTR = dlsym(libHandle, NAME); \ if (!tmesa->Glide.PTR) { \ - char err[1000]; \ - sprintf(err, "couldn't find Glide function %s in %s.", \ + __driUtilMessage("couldn't find Glide function %s in %s.", \ NAME, libName); \ - __driMesaMessage(err); \ } GET_FUNCTION(grDrawPoint, "grDrawPoint"); @@ -609,10 +815,10 @@ GLboolean tdfxInitGlide(tdfxContextPtr tmesa) GET_FUNCTION(grDisable, "grDisable"); GET_FUNCTION(grCoordinateSpace, "grCoordinateSpace"); GET_FUNCTION(grDepthRange, "grDepthRange"); -#if defined(__linux__) || defined(__FreeBSD__) +#ifdef __linux__ GET_FUNCTION(grStippleMode, "grStippleMode"); GET_FUNCTION(grStipplePattern, "grStipplePattern"); -#endif /* __linux__ || __FreeBSD__ */ +#endif /* __linux__ */ GET_FUNCTION(grViewport, "grViewport"); GET_FUNCTION(grTexCalcMemRequired, "grTexCalcMemRequired"); GET_FUNCTION(grTexTextureMemRequired, "grTexTextureMemRequired"); @@ -685,5 +891,35 @@ GLboolean tdfxInitGlide(tdfxContextPtr tmesa) tmesa->Glide.txImgDequantizeFXT1 = dlsym(libHandle, "_txImgDequantizeFXT1"); tmesa->Glide.txErrorSetCallback = dlsym(libHandle, "txErrorSetCallback"); +#ifdef DEBUG_TRAP + /* wrap the drawing functions so we can trap them */ + real_grDrawTriangle = tmesa->Glide.grDrawTriangle; + tmesa->Glide.grDrawTriangle = debug_grDrawTriangle; + + real_grDrawPoint = tmesa->Glide.grDrawPoint; + tmesa->Glide.grDrawPoint = debug_grDrawPoint; + + real_grDrawVertexArray = tmesa->Glide.grDrawVertexArray; + tmesa->Glide.grDrawVertexArray = debug_grDrawVertexArray; + + real_grDrawVertexArrayContiguous = tmesa->Glide.grDrawVertexArrayContiguous; + tmesa->Glide.grDrawVertexArrayContiguous = debug_grDrawVertexArrayContiguous; + + real_grClipWindow = tmesa->Glide.grClipWindow; + tmesa->Glide.grClipWindow = debug_grClipWindow; + + real_grVertexLayout = tmesa->Glide.grVertexLayout; + tmesa->Glide.grVertexLayout = debug_grVertexLayout; + + real_grGlideGetVertexLayout = tmesa->Glide.grGlideGetVertexLayout; + tmesa->Glide.grGlideGetVertexLayout = debug_grGlideGetVertexLayout; + + real_grGlideSetVertexLayout = tmesa->Glide.grGlideSetVertexLayout; + tmesa->Glide.grGlideSetVertexLayout = debug_grGlideSetVertexLayout; + + real_grTexDownloadMipMapLevel = tmesa->Glide.grTexDownloadMipMapLevel; + tmesa->Glide.grTexDownloadMipMapLevel = debug_grTexDownloadMipMapLevel; + +#endif return GL_TRUE; } diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.h b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.h index 39069f061..baee1125c 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.h +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.h @@ -40,10 +40,7 @@ #ifdef GLX_DIRECT_RENDERING #include <sys/time.h> -#include "dri_tmm.h" -#include "dri_mesaint.h" -#include "dri_mesa.h" -#include "dri_xmesaapi.h" +#include "dri_util.h" #ifdef XFree86Server #include "GL/xf86glx.h" #else @@ -52,35 +49,21 @@ #if defined(__linux__) #include <signal.h> #endif + +#include "glide.h" +#include "g3ext.h" + #include "clip.h" #include "context.h" - #include "macros.h" #include "matrix.h" #include "mem.h" -#include "texture.h" -#include "types.h" -#include "vb.h" -#include "vbrender.h" -#include "xform.h" +#include "mtypes.h" -#include "tdfx_wrapper.h" #include "tdfx_screen.h" -#include "tdfx_lock.h" -/* Mergable items first - */ -#define SETUP_RGBA 0x1 -#define SETUP_TMU0 0x2 -#define SETUP_TMU1 0x4 -#define SETUP_XY 0x8 -#define SETUP_Z 0x10 -#define SETUP_W 0x20 - -#define MAX_MERGABLE 0x8 - #define TDFX_TMU0 GR_TMU0 #define TDFX_TMU1 GR_TMU1 @@ -129,7 +112,6 @@ #define TDFX_UPLOAD_CULL 0x00004000 #define TDFX_UPLOAD_VERTEX_LAYOUT 0x00008000 #define TDFX_UPLOAD_COLOR_MASK 0x00010000 -#define TDFX_UPLOAD_CONSTANT_COLOR 0x00020000 #define TDFX_UPLOAD_DITHER 0x00040000 #define TDFX_UPLOAD_STENCIL 0x00080000 @@ -143,27 +125,28 @@ #define TDFX_UPLOAD_STIPPLE 0x04000000 -/* Flags for software fallback cases - */ -#define TDFX_FALLBACK_TEXTURE 0x0001 -#define TDFX_FALLBACK_BUFFER 0x0002 +/* Flags for software fallback cases */ +/* See correponding strings in tdfx_tris.c */ +#define TDFX_FALLBACK_TEXTURE_1D_3D 0x0001 +#define TDFX_FALLBACK_DRAW_BUFFER 0x0002 #define TDFX_FALLBACK_SPECULAR 0x0004 #define TDFX_FALLBACK_STENCIL 0x0008 #define TDFX_FALLBACK_RENDER_MODE 0x0010 -#define TDFX_FALLBACK_MULTIDRAW 0x0020 -#define TDFX_FALLBACK_LOGICOP 0x0040 -#define TDFX_FALLBACK_WIDE_AA_LINE 0x0080 -#define TDFX_FALLBACK_TEXTURE_ENV 0x0100 -#define TDFX_FALLBACK_TEXTURE_BORDER 0x0200 -#define TDFX_FALLBACK_COLORMASK 0x0400 -#define TDFX_FALLBACK_BLEND 0x0800 +#define TDFX_FALLBACK_LOGICOP 0x0020 +#define TDFX_FALLBACK_TEXTURE_ENV 0x0040 +#define TDFX_FALLBACK_TEXTURE_BORDER 0x0080 +#define TDFX_FALLBACK_COLORMASK 0x0100 +#define TDFX_FALLBACK_BLEND 0x0200 +#define TDFX_FALLBACK_LINE_STIPPLE 0x0400 /* Different Glide vertex layouts */ -#define TDFX_LAYOUT_SINGLE 0 -#define TDFX_LAYOUT_MULTI 1 -#define TDFX_LAYOUT_PROJECT 2 -#define TDFX_NUM_LAYOUTS 3 +#define TDFX_LAYOUT_TINY 0 +#define TDFX_LAYOUT_NOTEX 1 +#define TDFX_LAYOUT_SINGLE 2 +#define TDFX_LAYOUT_MULTI 3 +#define TDFX_LAYOUT_PROJECT 4 +#define TDFX_NUM_LAYOUTS 5 #define TDFX_XY_OFFSET 0 #define TDFX_Z_OFFSET 8 @@ -260,18 +243,15 @@ (((GLuint) (G) & 0xF8) << 2) | \ (((GLuint) (R) & 0xF8) >> 3)) -typedef void (*tdfxRenderEltsFunc)( struct vertex_buffer * ); - /* Used in calls to grColorMaskv()... */ extern const GLboolean false4[4]; extern const GLboolean true4[4]; -typedef void (*tdfx_interp_func)( GLfloat t, - GLfloat *result, - const GLfloat *in, - const GLfloat *out ); +typedef struct tdfx_context tdfxContextRec; +typedef struct tdfx_context *tdfxContextPtr; + typedef struct { volatile int fifoPtr; @@ -279,7 +259,9 @@ typedef struct { volatile int fifoOwner; volatile int ctxOwner; volatile int texOwner; -} TDFXSAREAPriv; +} +TDFXSAREAPriv; + typedef struct { GLuint swapBuffer; @@ -289,75 +271,122 @@ typedef struct { GLuint texSwaps; } tdfxStats; + + /* * Memory range from startAddr to endAddr-1 */ typedef struct mem_range { struct mem_range *next; FxU32 startAddr, endAddr; -} tdfxMemRange; +} +tdfxMemRange; -typedef struct { - GLvoid *data; - GLsizei width, height; - FxU32 size; -} tdfxTexRawData; typedef struct { - tdfxTexRawData original; /* Mesa-formatted texture image */ - tdfxTexRawData rescaled; /* Only needed if aspect ratio > 8:1 */ - - GLvoid *data; /* Final version of texture image */ - FxU32 size; /* image size in bytes */ - - GrTextureFormat_t glideFormat; /* Glide image format */ - GLint wScale, hScale; /* Broken hardware... */ -} tdfxTexImage, *tdfxTexImagePtr; + GLsizei width, height; /* image size */ + GLint wScale, hScale; /* scale factors */ + GrTextureFormat_t glideFormat; /* Glide image format */ +} +tdfxMipMapLevel; #define TDFX_NUM_TMU 2 -typedef struct { +typedef struct tdfxTexInfo_t +{ GLboolean isInTM; GLboolean reloadImages; /* if true, resend images to Glide */ GLuint lastTimeUsed; FxU32 whichTMU; GrTexInfo info; - tdfxTexImage image[MAX_TEXTURE_LEVELS]; - tdfxMemRange *range[TDFX_NUM_TMU]; + GrAspectRatio_t aspectRatio; + tdfxMemRange *tm[TDFX_NUM_TMU]; GLint minLevel, maxLevel; - GrMipMapMode_t mmMode; - GrAspectRatio_t aspectRatio; - FxBool LODblend; GrTextureFilterMode_t minFilt; GrTextureFilterMode_t magFilt; GrTextureClampMode_t sClamp; GrTextureClampMode_t tClamp; + FxBool LODblend; + GrMipMapMode_t mmMode; - GLfloat sScale, tScale; /* texcoord scale factor */ + GLfloat sScale, tScale; /* texcoord scale factor */ GuTexPalette palette; -} tdfxTexObj, *tdfxTexObjPtr; +} +tdfxTexInfo; + + +#define TDFX_TEXTURE_DATA(mesaObj) ((tdfxTexInfo *)((mesaObj)->DriverData)) + +#define TDFX_TEXIMAGE_DATA(mesaImg) ((tdfxMipMapLevel *)((mesaImg)->DriverData)) -#define TDFX_TEXTURE_DATA(tObj) ((tdfxTexObjPtr)((tObj)->DriverData)) -/* This is state which may be shared by several tdfx contexts. +/* + * This is state which may be shared by several tdfx contexts. * It hangs off of Mesa's gl_shared_state object (ctx->Shared->DriverData). */ -typedef struct tdfx_shared_state { +struct tdfxSharedState { GLboolean umaTexMemory; - GLuint totalTexMem[TDFX_NUM_TMU]; /* constant */ - GLuint freeTexMem[TDFX_NUM_TMU]; /* changes as we go */ - tdfxMemRange *rangePool; - tdfxMemRange *freeRanges[TDFX_NUM_TMU]; -} tdfxSharedState, *tdfxSharedStatePtr; + GLuint totalTexMem[TDFX_NUM_TMU]; /* constant */ + GLuint freeTexMem[TDFX_NUM_TMU]; /* changes as we go */ + tdfxMemRange *tmPool; + tdfxMemRange *tmFree[TDFX_NUM_TMU]; +}; +/* ================================================================ + * The vertex structures. + */ +typedef struct { + GLubyte blue; + GLubyte green; + GLubyte red; + GLubyte alpha; +} tdfx_color_t; + +typedef struct { + GLfloat x, y, z; /* Coordinates in screen space */ + GLfloat rhw; /* Reciprocal homogeneous w */ + tdfx_color_t color; /* Diffuse color */ + GLuint pad; + GLfloat tu0, tv0; /* Texture 0 coordinates */ + GLfloat tu1, tv1; /* Texture 1 coordinates */ +} tdfx_vertex; + +typedef struct { + GLfloat x, y, z; /* Coordinates in screen space */ + GLfloat rhw; /* Reciprocal homogeneous w */ + tdfx_color_t color; /* Diffuse color */ + GLuint pad; + GLfloat tu0, tv0; /* Texture 0 coordinates */ + GLfloat tu1, tv1; /* Texture 1 coordinates */ + GLfloat tq0, tq1; /* Texture 0/1 q coords */ +} tdfx_ptex_vertex; + +typedef struct { + GLfloat x, y, z; /* Coordinates in screen space */ + tdfx_color_t color; /* Diffuse color */ +} tdfx_tiny_vertex; + +/* The size of this union is not of relevence: + */ +union tdfx_vertex_t { + tdfx_vertex v; + tdfx_tiny_vertex tv; + tdfx_ptex_vertex pv; + GLfloat f[16]; + GLuint ui[16]; + GLubyte ub4[16][4]; +}; + +typedef union tdfx_vertex_t tdfxVertex, *tdfxVertexPtr; + /* ================================================================ * @@ -512,11 +541,6 @@ struct tdfx_depth { FxBool Mask; /* Write enable flag */ }; -#ifndef GR_STIPPLE_PATTERN -#error You MUST upgrade your Glide3 libraries and headers. -#error Get the latest from http://dri.sourceforge.net/res.phtml -#endif - struct tdfx_stipple { GrStippleMode_t Mode; /* Stipple enable/disable */ FxU32 Pattern; /* 8x4 Stipple Pattern */ @@ -650,10 +674,10 @@ struct tdfx_glide { void (*grDisable)( GrEnableMode_t mode ); void (*grCoordinateSpace)( GrCoordinateSpaceMode_t mode ); void (*grDepthRange)( FxFloat n, FxFloat f ); -#if defined(__linux__) || defined (__FreeBSD__) +#ifdef __linux__ void (*grStippleMode)( GrStippleMode_t mode ); void (*grStipplePattern)( GrStipplePattern_t mode ); -#endif /* __linux__ || __FreeBSD__ */ +#endif /* __linux__ */ void (*grViewport)( FxI32 x, FxI32 y, FxI32 width, FxI32 height ); FxU32 (*grTexCalcMemRequired)(GrLOD_t lodmin, GrLOD_t lodmax, GrAspectRatio_t aspect, GrTextureFormat_t fmt); @@ -799,13 +823,17 @@ struct tdfx_glide { void (*txErrorSetCallback)( void *fnc ); }; +typedef void (*tdfx_tri_func)( tdfxContextPtr, tdfxVertex *, tdfxVertex *, + tdfxVertex * ); +typedef void (*tdfx_line_func)( tdfxContextPtr, tdfxVertex *, tdfxVertex * ); +typedef void (*tdfx_point_func)( tdfxContextPtr, tdfxVertex * ); struct tdfx_context { /* Set once and never changed: */ GLcontext *glCtx; /* The core Mesa context */ - GLvisual *glVis; /* Describes the color buffer */ + GLuint new_gl_state; GLuint new_state; GLuint dirty; @@ -843,37 +871,51 @@ struct tdfx_context { struct tdfx_glide Glide; + + /* Temporaries for translating away float colors: + */ + struct gl_client_array UbyteColor; + + /* Fallback rasterization functions + */ + tdfx_point_func draw_point; + tdfx_line_func draw_line; + tdfx_tri_func draw_triangle; + + /* Variable-size Glide vertex formats */ - GLuint vertsize; /* bytes per vertex */ GLuint vertexFormat; /* the current format */ + GLuint vertex_stride_shift; void *layout[TDFX_NUM_LAYOUTS]; - - GLuint tmu_source[TDFX_NUM_TMU]; - GLuint tex_dest[MAX_TEXTURE_UNITS]; - GLuint numTMUs; - + char *verts; /* tdfxVertices, arbitarily packed */ + + GLfloat hw_viewport[16]; + GLuint SetupIndex; - GLuint SetupDone; + GLuint SetupNewInputs; GLuint RenderIndex; - - GLuint IndirectTriangles; GLuint Fallback; + GLenum render_primitive; /* what GL thinks */ + GLenum raster_primitive; /* what the hardware thinks */ GLfloat sScale0, tScale0; GLfloat sScale1, tScale1; - GLuint using_fast_path, passes, multipass; GLuint texBindNumber; GLint tmuSrc; int screen_width; int screen_height; + GLboolean haveTwoTMUs; /* True if we have 2 tmu's */ GLboolean haveHwStencil; + GLboolean haveHwStipple; GLint maxPendingSwapBuffers; + char rendererString[100]; + /* stuff added for DRI */ __DRIscreenPrivate *driScreen; __DRIcontextPrivate *driContext; @@ -897,39 +939,41 @@ struct tdfx_context { XF86DRIClipRectPtr pClipRects; GLboolean scissoredClipRects; /* if true, pClipRects is private storage */ - GuTexPalette glbPalette; /* global texture palette */ - tdfx_interp_func interp; - - points_func PointsFunc; - line_func LineFunc; - triangle_func TriangleFunc; - quad_func QuadFunc; - render_func *RenderVBRawTab; - tdfxRenderEltsFunc RenderElementsRaw; - - tdfxStats stats; - /* HACK: Let's get some buffering of vertices happening... - */ - GLuint *buffer; - GLuint buffer_total; - GLuint buffer_used; + GLboolean debugFallbacks; }; #define TDFX_CONTEXT(ctx) ((tdfxContextPtr)((ctx)->DriverCtx)) -extern GLboolean tdfxCreateContext( Display *dpy, GLvisual *mesaVis, - __DRIcontextPrivate *driContextPriv ); -extern void tdfxDestroyContext( tdfxContextPtr fxMesa ); +extern GLboolean +tdfxCreateContext( Display *dpy, + const __GLcontextModes *mesaVis, + __DRIcontextPrivate *driContextPriv, + void *sharedContextPrivate ); + +extern void +tdfxDestroyContext( __DRIcontextPrivate *driContextPriv ); + +extern GLboolean +tdfxUnbindContext( __DRIcontextPrivate *driContextPriv ); + +extern GLboolean +tdfxMakeCurrent( __DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv ); + +extern GLboolean +tdfxInitGlide( tdfxContextPtr tmesa ); -extern GLboolean tdfxInitContext( __DRIdrawablePrivate *driDrawPriv, - tdfxContextPtr fxMesa ); +extern void +FX_grColorMaskv(GLcontext *ctx, const GLboolean rgba[4]); -extern GLboolean tdfxInitGlide(tdfxContextPtr tmesa); +extern void +FX_grColorMaskv_NoLock(GLcontext *ctx, const GLboolean rgba[4]); /* Color packing utilities @@ -981,7 +1025,6 @@ extern int TDFX_DEBUG; #define DEBUG_VERBOSE_DRI 0x10 #define DEBUG_VERBOSE_IOCTL 0x20 #define DEBUG_VERBOSE_2D 0x40 -#define DEBUG_VERBOSE_TEXTURE 0x80 #endif /* GLX_DIRECT_RENDERING */ diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_dd.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_dd.c index b783b1ea9..451dcd8c2 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_dd.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_dd.c @@ -23,7 +23,7 @@ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_dd.c,v 1.5 2001/08/18 02:51:06 dawes Exp $ */ +/* $XFree86$ */ /* * Original rewrite: @@ -37,17 +37,18 @@ #include "tdfx_context.h" #include "tdfx_dd.h" +#include "tdfx_lock.h" #include "tdfx_vb.h" -#include "tdfx_pipeline.h" #include "tdfx_pixels.h" #include "enums.h" -#include "pb.h" -#if defined(USE_X86_ASM) || defined(USE_3DNOW_ASM) || defined(USE_KATMAI_ASM) +#include "swrast/swrast.h" +#if defined(USE_X86_ASM) #include "X86/common_x86_asm.h" #endif -#define TDFX_DATE "20010501" + +#define TDFX_DATE "20010624" /* These are used in calls to FX_grColorMaskv() */ @@ -65,42 +66,48 @@ static const GLubyte *tdfxDDGetString( GLcontext *ctx, GLenum name ) tdfxContextPtr fxMesa = (tdfxContextPtr) ctx->DriverCtx; switch ( name ) { - case GL_VENDOR: - return (GLubyte *)"VA Linux Systems, Inc."; + case GL_RENDERER: + { + /* The renderer string must be per-context state to handle + * multihead correctly. + */ + char *buffer = fxMesa->rendererString; + char hardware[100]; - case GL_RENDERER: { - static char buffer[128]; - char hardware[128]; + LOCK_HARDWARE(fxMesa); + strcpy( hardware, fxMesa->Glide.grGetString(GR_HARDWARE) ); + UNLOCK_HARDWARE(fxMesa); - strcpy( hardware, FX_grGetString( fxMesa, GR_HARDWARE ) ); + strcpy( buffer, "Mesa DRI " ); + strcat( buffer, TDFX_DATE ); + strcat( buffer, " " ); if ( strcmp( hardware, "Voodoo3 (tm)" ) == 0 ) { - strcpy( hardware, "Voodoo3" ); + strcat( buffer, "Voodoo3" ); } else if ( strcmp( hardware, "Voodoo Banshee (tm)" ) == 0 ) { - strcpy( hardware, "VoodooBanshee" ); + strcat( buffer, "VoodooBanshee" ); } else if ( strcmp( hardware, "Voodoo4 (tm)" ) == 0 ) { - strcpy( hardware, "Voodoo4" ); + strcat( buffer, "Voodoo4" ); } else if ( strcmp( hardware, "Voodoo5 (tm)" ) == 0 ) { - strcpy( hardware, "Voodoo5" ); + strcat( buffer, "Voodoo5" ); } else { - /* Unexpected result: replace spaces with hyphens */ + /* unexpected result: replace spaces with hyphens */ int i; - for ( i = 0 ; hardware[i] ; i++ ) { + for ( i = 0 ; hardware[i] && i < 60 ; i++ ) { if ( hardware[i] == ' ' || hardware[i] == '\t' ) hardware[i] = '-'; } + strcat( buffer, hardware ); } - /* Now make the GL_RENDERER string */ - sprintf( buffer, "Mesa DRI %s " TDFX_DATE, hardware ); /* Append any CPU-specific information. */ #ifdef USE_X86_ASM - if ( gl_x86_cpu_features ) { + if ( _mesa_x86_cpu_features ) { strncat( buffer, " x86", 4 ); } #endif @@ -114,41 +121,35 @@ static const GLubyte *tdfxDDGetString( GLcontext *ctx, GLenum name ) strncat( buffer, "/3DNow!", 7 ); } #endif -#ifdef USE_KATMAI_ASM +#ifdef USE_SSE_ASM if ( cpu_has_xmm ) { strncat( buffer, "/SSE", 4 ); } #endif - return (GLubyte *)buffer; + return (const GLubyte *) buffer; } - + case GL_VENDOR: + return "VA Linux Systems, Inc."; default: return NULL; } } -/* Return buffer size information. +/* Return uptodate buffer size information. */ static void tdfxDDGetBufferSize( GLcontext *ctx, GLuint *width, GLuint *height ) { tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + LOCK_HARDWARE( fxMesa ); *width = fxMesa->width; *height = fxMesa->height; + UNLOCK_HARDWARE( fxMesa ); } -static GLint tdfxDDGetParameteri( const GLcontext *ctx, GLint param ) -{ - switch ( param ) { - case DD_HAVE_HARDWARE_FOG: - return 1; - default: - return 0; - } -} /* * Return the current value of the occlusion test flag and @@ -240,10 +241,10 @@ static GLboolean tdfxDDGetIntegerv( GLcontext *ctx, GLenum pname, #define VISUAL_EQUALS_RGBA(vis, r, g, b, a) \ - ((vis->RedBits == r) && \ - (vis->GreenBits == g) && \ - (vis->BlueBits == b) && \ - (vis->AlphaBits == a)) + ((vis.redBits == r) && \ + (vis.greenBits == g) && \ + (vis.blueBits == b) && \ + (vis.alphaBits == a)) void tdfxDDInitDriverFuncs( GLcontext *ctx ) { @@ -254,48 +255,74 @@ void tdfxDDInitDriverFuncs( GLcontext *ctx ) ctx->Driver.GetString = tdfxDDGetString; ctx->Driver.GetBufferSize = tdfxDDGetBufferSize; ctx->Driver.Error = NULL; - ctx->Driver.GetParameteri = tdfxDDGetParameteri; + /* Pixel path fallbacks. + */ + ctx->Driver.Accum = _swrast_Accum; + ctx->Driver.Bitmap = _swrast_Bitmap; + ctx->Driver.CopyPixels = _swrast_CopyPixels; + ctx->Driver.DrawPixels = _swrast_DrawPixels; + ctx->Driver.ReadPixels = _swrast_ReadPixels; + ctx->Driver.ResizeBuffersMESA = _swrast_alloc_buffers; + + /* Accelerated paths + */ if ( VISUAL_EQUALS_RGBA(ctx->Visual, 8, 8, 8, 8) ) { ctx->Driver.DrawPixels = tdfx_drawpixels_R8G8B8A8; ctx->Driver.ReadPixels = tdfx_readpixels_R8G8B8A8; - ctx->Driver.CopyPixels = NULL; - ctx->Driver.Bitmap = NULL; } else if ( VISUAL_EQUALS_RGBA(ctx->Visual, 5, 6, 5, 0) ) { - ctx->Driver.DrawPixels = NULL; ctx->Driver.ReadPixels = tdfx_readpixels_R5G6B5; - ctx->Driver.CopyPixels = NULL; - ctx->Driver.Bitmap = NULL; - } - else - { - ctx->Driver.DrawPixels = NULL; - ctx->Driver.ReadPixels = NULL; - ctx->Driver.CopyPixels = NULL; - ctx->Driver.Bitmap = NULL; } - ctx->Driver.RegisterVB = tdfxDDRegisterVB; - ctx->Driver.UnregisterVB = tdfxDDUnregisterVB; - ctx->Driver.ResetVB = NULL; - ctx->Driver.ResetCvaVB = NULL; - - if ( !getenv( "TDFX_NO_FAST" ) ) { - ctx->Driver.BuildPrecalcPipeline = tdfxDDBuildPrecalcPipeline; - } else { - ctx->Driver.BuildPrecalcPipeline = NULL; - } - ctx->Driver.BuildEltPipeline = NULL; - - ctx->Driver.OptimizeImmediatePipeline = NULL; - ctx->Driver.OptimizePrecalcPipeline = NULL; - ctx->Driver.GetBooleanv = tdfxDDGetBooleanv; ctx->Driver.GetDoublev = tdfxDDGetDoublev; ctx->Driver.GetFloatv = tdfxDDGetFloatv; ctx->Driver.GetIntegerv = tdfxDDGetIntegerv; ctx->Driver.GetPointerv = NULL; } + + +/* + * These are here for lack of a better place. + */ + +void +FX_grColorMaskv(GLcontext *ctx, const GLboolean rgba[4]) +{ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + LOCK_HARDWARE(fxMesa); + if (ctx->Visual.redBits == 8) { + /* 32bpp mode */ + ASSERT( fxMesa->Glide.grColorMaskExt ); + fxMesa->Glide.grColorMaskExt(rgba[RCOMP], rgba[GCOMP], + rgba[BCOMP], rgba[ACOMP]); + } + else { + /* 16 bpp mode */ + /* we never have an alpha buffer */ + fxMesa->Glide.grColorMask(rgba[RCOMP] || rgba[GCOMP] || rgba[BCOMP], + GL_FALSE); + } + UNLOCK_HARDWARE(fxMesa); +} + +void +FX_grColorMaskv_NoLock(GLcontext *ctx, const GLboolean rgba[4]) +{ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + if (ctx->Visual.redBits == 8) { + /* 32bpp mode */ + ASSERT( fxMesa->Glide.grColorMaskExt ); + fxMesa->Glide.grColorMaskExt(rgba[RCOMP], rgba[GCOMP], + rgba[BCOMP], rgba[ACOMP]); + } + else { + /* 16 bpp mode */ + /* we never have an alpha buffer */ + fxMesa->Glide.grColorMask(rgba[RCOMP] || rgba[GCOMP] || rgba[BCOMP], + GL_FALSE); + } +} diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_fastpath.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_fastpath.c deleted file mode 100644 index d448ad581..000000000 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_fastpath.c +++ /dev/null @@ -1,594 +0,0 @@ -/* -*- 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/tdfx/tdfx_fastpath.c,v 1.2 2001/08/18 02:51:06 dawes Exp $ */ - -/* - * Original rewrite: - * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 - * - * Authors: - * Gareth Hughes <gareth@valinux.com> - * Keith Whitwell <keithw@valinux.com> - * - */ - -#include "types.h" -#include "enums.h" -#include "cva.h" -#include "vertices.h" -#include "mmath.h" - -#include "tdfx_context.h" -#include "tdfx_state.h" -#include "tdfx_vb.h" -#include "tdfx_tris.h" -#include "tdfx_pipeline.h" - - -struct tdfx_fast_tab { - void (*build_vertices)( struct vertex_buffer *VB, GLuint do_cliptest ); - void (*interp)( GLfloat t, GLfloat *O, const GLfloat *I, const GLfloat *J ); - void (*project_vertices)( struct vertex_buffer *VB ); - void (*project_clipped_vertices)( struct vertex_buffer *VB ); -}; - - -#define POINT(x) tdfx_draw_point( fxMesa, &vert[x], psize ) -#define LINE(x,y) tdfx_draw_line( fxMesa, &vert[x], &vert[y], lwidth ) -#define TRI(x,y,z) fxMesa->Glide.grDrawTriangle( &vert[x], &vert[y], &vert[z] ); - - -#define INDIRECT_TRI(x,y,z) \ -do { \ - out[next_elt + 0] = &vert[x]; \ - out[next_elt + 1] = &vert[y]; \ - out[next_elt + 2] = &vert[z]; \ - next_elt += 3; \ -} while (0) - - - -/* Direct, and no clipping required. The clip funcs have not been - * written yet, so this is only useful for the fast path. - */ -#define RENDER_POINTS( start, count ) \ -do { \ - GLuint e; \ - for ( e = start ; e < count ; e++ ) \ - POINT( elt[e] ); \ -} while (0) - -#define RENDER_LINE( i1, i ) \ -do { \ - GLuint e1 = elt[i1], e = elt[i]; \ - LINE( e1, e ); \ -} while (0) - -#define RENDER_TRI( i2, i1, i, pv, parity ) \ -do { \ - GLuint e2 = elt[i2], e1 = elt[i1], e = elt[i]; \ - if ( parity ) { \ - GLuint tmp = e2; e2 = e1; e1 = tmp; \ - } \ - TRI( e2, e1, e ); \ -} while (0) - -#define RENDER_QUAD( i3, i2, i1, i, pv ) \ -do { \ - GLuint e3 = elt[i3], e2 = elt[i2], e1 = elt[i1], e = elt[i]; \ - TRI( e3, e2, e ); \ - TRI( e2, e1, e ); \ -} while (0) - -#define LOCAL_VARS \ - tdfxVertexPtr vert = TDFX_DRIVER_DATA(VB)->verts; \ - const GLuint *elt = VB->EltPtr->data; \ - GLcontext *ctx = VB->ctx; \ - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); \ - const GLfloat lwidth = ctx->Line.Width; \ - const GLfloat psize = ctx->Point.Size; \ - (void) lwidth; (void) psize; (void) vert; (void) fxMesa; - -#define TAG(x) tdfx_##x##_smooth_direct -#include "render_tmp.h" - - - -/* Indirect, and no clipping required. The clip funcs have not been - * written yet, so this is only useful for the fast path. - */ -#define RENDER_POINTS( start, count ) \ -do { \ - GLuint e; \ - for ( e = start ; e < count ; e++ ) \ - POINT( elt[e] ); \ -} while (0) - -#define RENDER_LINE( i1, i ) \ -do { \ - GLuint e1 = elt[i1], e = elt[i]; \ - LINE( e1, e ); \ -} while (0) - -#define RENDER_TRI( i2, i1, i, pv, parity ) \ -do { \ - GLuint e2 = elt[i2], e1 = elt[i1], e = elt[i]; \ - if ( parity ) { \ - GLuint tmp = e2; e2 = e1; e1 = tmp; \ - } \ - INDIRECT_TRI( e2, e1, e ); \ -} while (0) - -#define RENDER_QUAD( i3, i2, i1, i, pv ) \ -do { \ - GLuint e3 = elt[i3], e2 = elt[i2], e1 = elt[i1], e = elt[i]; \ - TRI( e3, e2, e ); \ - TRI( e2, e1, e ); \ -} while (0) - -#define LOCAL_VARS \ - tdfxVertexBufferPtr fxVB = TDFX_DRIVER_DATA(VB); \ - tdfxVertexPtr vert = fxVB->verts; \ - GLuint next_elt = fxVB->last_elt; \ - tdfxVertexPtr *out = fxVB->elts; \ - const GLuint *elt = VB->EltPtr->data; \ - GLcontext *ctx = VB->ctx; \ - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); \ - const GLfloat lwidth = ctx->Line.Width; \ - const GLfloat psize = ctx->Point.Size; \ - (void) lwidth; (void) psize; (void) vert; (void) out; (void) fxMesa; - -#define POSTFIX \ - fxVB->last_elt = next_elt; - -#define TAG(x) tdfx_##x##_smooth_indirect -#include "render_tmp.h" - - - -#define NEGATIVE(f) (f < 0) -#define DIFFERENT_SIGNS(a,b) ((a*b) < 0) -#define LINTERP(T, A, B) ((A) + (T) * ((B) - (A))) - -#define INTERP_RGBA( t, out, a, b ) \ -do { \ - int i; \ - for ( i = 0 ; i < 4 ; i++ ) { \ - GLfloat fa = UBYTE_COLOR_TO_FLOAT_COLOR( a[i] ); \ - GLfloat fb = UBYTE_COLOR_TO_FLOAT_COLOR( b[i] ); \ - GLfloat fo = LINTERP( t, fa, fb ); \ - FLOAT_COLOR_TO_UBYTE_COLOR( out[i], fo ); \ - } \ -} while (0) - -#define CLIP( SGN, V, PLANE ) \ -do { \ - if ( mask & PLANE ) { \ - GLuint *indata = inlist[in]; \ - GLuint *outdata = inlist[in ^= 1]; \ - GLuint nr = n; \ - GLfloat *J = verts[indata[nr-1]].f; \ - GLfloat dpJ = (SGN J[V]) + J[3]; \ - \ - inlist[0] = vlist1; \ - for ( i = n = 0 ; i < nr ; i++ ) { \ - GLuint elt_i = indata[i]; \ - GLfloat *I = verts[elt_i].f; \ - GLfloat dpI = (SGN I[V]) + I[3]; \ - \ - if ( DIFFERENT_SIGNS( dpI, dpJ ) ) { \ - GLfloat *O = verts[next_vert].f; \ - GLfloat t, *in, *out; \ - \ - if ( NEGATIVE( dpI ) ) { \ - t = dpI / (dpI - dpJ); \ - in = I; \ - out = J; \ - } else { \ - t = dpJ / (dpJ - dpI); \ - in = J; \ - out = I; \ - } \ - \ - interp( t, O, in, out ); \ - \ - clipmask[next_vert] = 0; \ - outdata[n++] = next_vert++; \ - } \ - \ - clipmask[elt_i] |= PLANE; /* don't set up */ \ - \ - if ( !NEGATIVE( dpI ) ) { \ - outdata[n++] = elt_i; \ - clipmask[elt_i] &= ~PLANE; /* set up after all */ \ - } \ - \ - J = I; \ - dpJ = dpI; \ - } \ - \ - if ( n < 3 ) return; \ - } \ -} while (0) - -#define LINE_CLIP( x, y, z, w, PLANE ) \ -do { \ - if ( mask & PLANE ) { \ - GLfloat dpI = DOT4V( I, x, y, z, w ); \ - GLfloat dpJ = DOT4V( J, x, y, z, w ); \ - \ - if ( DIFFERENT_SIGNS( dpI, dpJ ) ) { \ - GLfloat *O = verts[next_vert].f; \ - GLfloat t = dpI / (dpI - dpJ); \ - \ - interp( t, O, I, J ); \ - \ - clipmask[next_vert] = 0; \ - \ - if ( NEGATIVE( dpI ) ) { \ - clipmask[elts[0]] |= PLANE; \ - I = O; \ - elts[0] = next_vert++; \ - } else { \ - clipmask[elts[1]] |= PLANE; \ - J = O; \ - elts[1] = next_vert++; \ - } \ - } else if ( NEGATIVE( dpI ) ) { \ - return; \ - } \ - } \ -} while (0) - - -static __inline void tdfx_tri_clip( GLuint **p_elts, - tdfxVertex *verts, - GLubyte *clipmask, - GLuint *p_next_vert, - GLubyte mask, - tdfx_interp_func interp ) -{ - GLuint *elts = *p_elts; - GLuint next_vert = *p_next_vert; - GLuint in = 0; - GLuint n = 3; - GLuint vlist1[VB_MAX_CLIPPED_VERTS]; - GLuint vlist2[VB_MAX_CLIPPED_VERTS]; - GLuint *inlist[2]; - GLuint *out; - GLuint i; - - inlist[0] = elts; - inlist[1] = vlist2; - - CLIP( -, 0, CLIP_RIGHT_BIT ); - CLIP( +, 0, CLIP_LEFT_BIT ); - CLIP( -, 1, CLIP_TOP_BIT ); - CLIP( +, 1, CLIP_BOTTOM_BIT ); - CLIP( -, 2, CLIP_FAR_BIT ); - CLIP( +, 2, CLIP_NEAR_BIT ); - - /* Convert the planar polygon to a list of triangles */ - out = inlist[in]; - - for ( i = 2 ; i < n ; i++ ) { - elts[0] = out[0]; - elts[1] = out[i-1]; - elts[2] = out[i]; - elts += 3; - } - - *p_next_vert = next_vert; - *p_elts = elts; -} - - -static __inline void tdfx_line_clip( GLuint **p_elts, - tdfxVertex *verts, - GLubyte *clipmask, - GLuint *p_next_vert, - GLubyte mask, - tdfx_interp_func interp ) -{ - GLuint *elts = *p_elts; - GLfloat *I = verts[elts[0]].f; - GLfloat *J = verts[elts[1]].f; - GLuint next_vert = *p_next_vert; - - LINE_CLIP( 1, 0, 0, -1, CLIP_LEFT_BIT ); - LINE_CLIP( -1, 0, 0, 1, CLIP_RIGHT_BIT ); - LINE_CLIP( 0, 1, 0, -1, CLIP_TOP_BIT ); - LINE_CLIP( 0, -1, 0, 1, CLIP_BOTTOM_BIT ); - LINE_CLIP( 0, 0, 1, -1, CLIP_FAR_BIT ); - LINE_CLIP( 0, 0, -1, 1, CLIP_NEAR_BIT ); - - *p_next_vert = next_vert; - *p_elts += 2; -} - - -#define CLIP_POINT( e ) \ -do { \ - if ( mask[e] ) *out++ = e; \ -} while (0) - -#define CLIP_LINE( e1, e0 ) \ -do { \ - GLubyte ormask = mask[e0] | mask[e1]; \ - out[0] = e1; \ - out[1] = e0; \ - out += 2; \ - if ( ormask ) { \ - out-=2; \ - if ( !(mask[e0] & mask[e1]) ) { \ - tdfx_line_clip( &out, verts, mask, \ - &next_vert, ormask, interp ); \ - } \ - } \ -} while (0) - -#define CLIP_TRIANGLE( e2, e1, e0 ) \ -do { \ - GLubyte ormask; \ - out[0] = e2; \ - out[1] = e1; \ - out[2] = e0; \ - out += 3; \ - ormask = mask[e2] | mask[e1] | mask[e0]; \ - if ( ormask ) { \ - out -= 3; \ - if ( !(mask[e2] & mask[e1] & mask[e0]) ) { \ - tdfx_tri_clip( &out, verts, mask, \ - &next_vert, ormask, interp ); \ - } \ - } \ -} while (0) - - - -/* Build a table of functions to clip each primitive type. These - * produce a list of elements in the appropriate 'reduced' primitive, - * ie (points, lines, triangles) containing all the clipped and - * unclipped primitives from the original list. - */ -#define LOCAL_VARS \ - tdfxContextPtr fxMesa = TDFX_CONTEXT(VB->ctx); \ - tdfxVertexBufferPtr fxVB = TDFX_DRIVER_DATA(VB); \ - GLuint *elt = VB->EltPtr->data; \ - tdfxVertexPtr verts = fxVB->verts; \ - GLuint next_vert = fxVB->last_vert; \ - GLuint *out = fxVB->clipped_elements.data; \ - GLubyte *mask = VB->ClipMask; \ - tdfx_interp_func interp = fxMesa->interp; \ - (void) interp; (void) verts; - -#define POSTFIX \ - fxVB->clipped_elements.count = out - fxVB->clipped_elements.data; \ - fxVB->last_vert = next_vert; - - -#define INIT( x ) - -#define RENDER_POINTS( start, count ) \ -do { \ - GLuint i; \ - for ( i = start ; i < count ; i++ ) \ - CLIP_POINT( elt[i] ); \ -} while (0) - -#define RENDER_LINE( i1, i0 ) \ -do { \ - CLIP_LINE( elt[i1], elt[i0] ); \ -} while (0) - -#define RENDER_TRI( i2, i1, i0, pv, parity ) \ -do { \ - GLuint e2 = elt[i2], e1 = elt[i1], e0 = elt[i0]; \ - if ( parity ) e2 = elt[i1], e1 = elt[i2]; \ - CLIP_TRIANGLE( e2, e1, e0 ); \ -} while (0) - -#define RENDER_QUAD( i3, i2, i1, i0, pv ) \ -do { \ - CLIP_TRIANGLE( elt[i3], elt[i2], elt[i0] ); \ - CLIP_TRIANGLE( elt[i2], elt[i1], elt[i0] ); \ -} while (0) - -#define TAG(x) tdfx_##x##_clip_elt -#include "render_tmp.h" - - - - -/* Pack rgba and/or texture into the remaining half of a 32 byte vertex. - */ -#define CLIP_UBYTE_COLOR 4 -#define CLIP_UBYTE_B 0 -#define CLIP_UBYTE_G 1 -#define CLIP_UBYTE_R 2 -#define CLIP_UBYTE_A 3 -#define CLIP_S0 6 -#define CLIP_T0 7 -#define CLIP_S1 8 -#define CLIP_T1 9 - -#define TYPE (0) -#define TAG(x) x -#include "tdfx_fasttmp.h" - -#define TYPE (TDFX_RGBA_BIT) -#define TAG(x) x##_RGBA -#include "tdfx_fasttmp.h" - -#define TYPE (TDFX_TEX0_BIT) -#define TAG(x) x##_TEX0 -#include "tdfx_fasttmp.h" - -#define TYPE (TDFX_RGBA_BIT | TDFX_TEX0_BIT) -#define TAG(x) x##_RGBA_TEX0 -#include "tdfx_fasttmp.h" - -#define TYPE (TDFX_RGBA_BIT | TDFX_TEX0_BIT | TDFX_TEX1_BIT) -#define TAG(x) x##_RGBA_TEX0_TEX1 -#include "tdfx_fasttmp.h" - -/* This one *could* get away with sneaking TEX1 into the color and - * specular slots, thus fitting inside a cache line. Would be even - * better to switch to a smaller vertex. - */ -#define TYPE (TDFX_TEX0_BIT | TDFX_TEX1_BIT) -#define TAG(x) x##_TEX0_TEX1 -#include "tdfx_fasttmp.h" - - - -/* Render elements directly from original list of vertices. - */ -static void tdfx_render_elements_direct( struct vertex_buffer *VB ) -{ - GLcontext *ctx = VB->ctx; - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - GLenum prim = ctx->CVA.elt_mode; - GLuint nr = VB->EltPtr->count; - render_func func = tdfx_render_tab_smooth_direct[prim]; - GLuint p = 0; - - if ( fxMesa->new_state ) - tdfxDDUpdateHwState( ctx ); - - BEGIN_CLIP_LOOP( fxMesa ); - do { - func( VB, 0, nr, 0 ); - } while ( ctx->Driver.MultipassFunc && - ctx->Driver.MultipassFunc( VB, ++p ) ); - END_CLIP_LOOP( fxMesa ); -} - -/* Render elements indirectly from original list of vertices. - */ -#if 0 -static void tdfx_render_elements_indirect( struct vertex_buffer *VB ) -{ - GLcontext *ctx = VB->ctx; - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - tdfxVertexBufferPtr fxVB = TDFX_DRIVER_DATA(VB); - GLenum prim = ctx->CVA.elt_mode; - GLuint nr = VB->EltPtr->count; - render_func func = tdfx_render_tab_smooth_indirect[prim]; - GLuint p = 0; - - if ( fxMesa->new_state ) - tdfxDDUpdateHwState( ctx ); - - do { - func( VB, 0, nr, 0 ); - } while ( ctx->Driver.MultipassFunc && - ctx->Driver.MultipassFunc( VB, ++p ) ); - - BEGIN_CLIP_LOOP( fxMesa ); - fxMesa->Glide.grDrawVertexArray( GR_TRIANGLES, fxVB->last_elt, fxVB->elts ); - END_CLIP_LOOP( fxMesa ); - - fxVB->last_elt = 0; -} -#endif - -/* Very sparsely popluated array - fix the indices. - */ -static struct tdfx_fast_tab fxFastTab[0x80]; - -void tdfxDDFastPathInit( void ) -{ - tdfx_render_init_clip_elt(); - tdfx_render_init_smooth_direct(); - tdfx_render_init_smooth_indirect(); - - tdfx_init_fastpath( &fxFastTab[0] ); - tdfx_init_fastpath_RGBA( &fxFastTab[TDFX_RGBA_BIT] ); - tdfx_init_fastpath_TEX0( &fxFastTab[TDFX_TEX0_BIT] ); - tdfx_init_fastpath_RGBA_TEX0( &fxFastTab[TDFX_RGBA_BIT|TDFX_TEX0_BIT] ); - tdfx_init_fastpath_TEX0_TEX1( &fxFastTab[TDFX_TEX0_BIT|TDFX_TEX1_BIT] ); - tdfx_init_fastpath_RGBA_TEX0_TEX1( &fxFastTab[TDFX_RGBA_BIT|TDFX_TEX0_BIT| - TDFX_TEX1_BIT] ); -} - - -#define VALID_SETUP (TDFX_RGBA_BIT | TDFX_TEX0_BIT | TDFX_TEX1_BIT) - - -void tdfxDDFastPath( struct vertex_buffer *VB ) -{ - GLcontext *ctx = VB->ctx; - GLenum prim = ctx->CVA.elt_mode; - tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); - tdfxVertexBufferPtr fxVB = TDFX_DRIVER_DATA(VB); - struct tdfx_fast_tab *tab = &fxFastTab[fxMesa->SetupIndex & VALID_SETUP]; - - if ( fxMesa->new_state ) { - tdfxDDUpdateHwState( ctx ); - } - else if ( fxMesa->dirty & TDFX_UPLOAD_VERTEX_LAYOUT ) { - /* After extensive debugging I discovered that the vertex layout - * may need to be updated at this point. Not sure how this works - * in the other drivers. -BP - */ - LOCK_HARDWARE( fxMesa ); - fxMesa->Glide.grGlideSetVertexLayout( fxMesa->layout[fxMesa->vertexFormat] ); - fxMesa->dirty &= ~TDFX_UPLOAD_VERTEX_LAYOUT; - UNLOCK_HARDWARE( fxMesa ); - } - - gl_prepare_arrays_cva( VB ); /* still need this */ - - /* Reserve enough space for the pathological case */ - if ( VB->EltPtr->count * 12 > fxVB->size ) - tdfxDDResizeVB( VB, VB->EltPtr->count * 12 ); - - tab->build_vertices( VB, 1 ); /* object->clip space */ - - if ( VB->ClipOrMask ) { - if ( !VB->ClipAndMask ) { - render_func *clip = tdfx_render_tab_clip_elt; - - fxMesa->interp = tab->interp; - - clip[prim]( VB, 0, VB->EltPtr->count, 0 ); /* build new elts */ - - ctx->CVA.elt_mode = gl_reduce_prim[prim]; - VB->EltPtr = &(fxVB->clipped_elements); - - tab->project_clipped_vertices( VB ); /* clip->device space */ - tdfx_render_elements_direct( VB ); /* render using new list */ - } - } else { - tab->project_vertices( VB ); /* clip->device space */ - tdfx_render_elements_direct( VB ); /* render using orig list */ - } - - /* This indicates that there is no cached data to reuse */ - VB->pipeline->data_valid = 0; - VB->pipeline->new_state = 0; -} diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_fasttmp.h b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_fasttmp.h deleted file mode 100644 index ab97a3895..000000000 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_fasttmp.h +++ /dev/null @@ -1,293 +0,0 @@ -/* -*- 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/tdfx/tdfx_fasttmp.h,v 1.1 2001/03/21 16:14:28 dawes Exp $ */ - -/* - * Original rewrite: - * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 - * - * Authors: - * Gareth Hughes <gareth@valinux.com> - * Keith Whitwell <keithw@valinux.com> - * - */ - -/* The first part of setup is applied to all vertices, clipped or - * unclipped. This data will be used for clipping, and then all - * vertices with a zero clipmask will be projected to device space. - * - * This could be split into several loops, but - it seems that the - * large stride of the fxVertices makes cache issues the big - * performance factor, and that multiple loops mean multiple cache - * misses.... - */ - -static void TAG(tdfx_setup_full)( struct vertex_buffer *VB, - GLuint do_cliptest ) -{ - tdfxVertexBufferPtr fxVB = TDFX_DRIVER_DATA(VB); - GLcontext *ctx = VB->ctx; - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - const GLfloat * const m = ctx->ModelProjectMatrix.m; - GLuint start = VB->CopyStart; - GLuint count = VB->Count; - - if (0) fprintf(stderr, "%s\n", __FUNCTION__); - - gl_xform_points3_v16_general( TDFX_DRIVER_DATA(VB)->verts[start].f, - m, - VB->ObjPtr->start, - VB->ObjPtr->stride, - count - start ); - - if ( do_cliptest ) { - VB->ClipAndMask = ~0; - VB->ClipOrMask = 0; - gl_cliptest_points4_v16( fxVB->verts[start].f, - fxVB->verts[count].f, - &(VB->ClipOrMask), - &(VB->ClipAndMask), - VB->ClipMask + start ); - } - - /* These branches are all resolved at compile time. Hopefully all - * the pointers are valid addresses even when not enabled. - */ - if ( TYPE ) { - GLubyte *color = VB->ColorPtr->start; - GLfloat *tex0_data = VB->TexCoordPtr[fxMesa->tmu_source[0]]->start; - GLfloat *tex1_data = VB->TexCoordPtr[fxMesa->tmu_source[1]]->start; - - const GLuint color_stride = VB->ColorPtr->stride; - const GLuint tex0_stride = VB->TexCoordPtr[fxMesa->tmu_source[0]]->stride; - const GLuint tex1_stride = VB->TexCoordPtr[fxMesa->tmu_source[1]]->stride; - - GLfloat *f = fxVB->verts[start].f; - GLfloat *end = f + (16 * (count - start)); - - while ( f != end ) { - if ( TYPE & TDFX_RGBA_BIT ) { -#if defined(USE_X86_ASM) - __asm__ ( - "movl (%%edx),%%eax \n" - "bswap %%eax \n" - "rorl $8,%%eax \n" - "movl %%eax,16(%%edi) \n" - : - : "d" (color), "D" (f) - : "%eax" ); -#else - GLubyte *col = color; - GLubyte *b = (GLubyte *)&f[CLIP_UBYTE_COLOR]; - b[CLIP_UBYTE_B] = col[2]; - b[CLIP_UBYTE_G] = col[1]; - b[CLIP_UBYTE_R] = col[0]; - b[CLIP_UBYTE_A] = col[3]; -#endif - } - if (TYPE & TDFX_TEX0_BIT) { -#if defined (USE_X86_ASM) - __asm__ ( - "movl (%%ecx), %%eax \n" - "movl %%eax, 24(%%edi) \n" - "movl 4(%%ecx), %%eax \n" - "movl %%eax, 28(%%edi)" - : - : "c" (tex0_data), "D" (f) - : "%eax"); -#else - *(unsigned int *)(f+CLIP_S0) = *(unsigned int *)tex0_data; - *(unsigned int *)(f+CLIP_T0) = *(unsigned int *)(tex0_data+1); -#endif - } - if (TYPE & TDFX_TEX1_BIT) { - /* Hits a second cache line. - */ -#if defined (USE_X86_ASM) - __asm__ ( - "movl (%%esi), %%eax \n" - "movl %%eax, 32(%%edi) \n" - "movl 4(%%esi), %%eax \n" - "movl %%eax, 36(%%edi)" - : - : "S" (tex1_data), "D" (f) - : "%eax"); -#else - *(unsigned int *)(f+CLIP_S1) = *(unsigned int *)tex1_data; - *(unsigned int *)(f+CLIP_T1) = *(unsigned int *)(tex1_data+1); -#endif - } - if ( TYPE & TDFX_RGBA_BIT ) color += color_stride; - if ( TYPE & TDFX_TEX0_BIT ) STRIDE_F( tex0_data, tex0_stride ); - if ( TYPE & TDFX_TEX1_BIT ) STRIDE_F( tex1_data, tex1_stride ); - f += 16; - } - } - - fxVB->clipped_elements.count = start; - fxVB->last_vert = count; -} - - -/* Changed to just put the interp func instead of the whole clip - * routine into the header. Less code and better chance of doing some - * of this stuff in assembly. - */ -static void TAG(tdfx_interp_vert)( GLfloat t, - GLfloat *O, - const GLfloat *I, - const GLfloat *J ) -{ - O[0] = LINTERP( t, I[0], J[0] ); - O[1] = LINTERP( t, I[1], J[1] ); - O[2] = LINTERP( t, I[2], J[2] ); - O[3] = LINTERP( t, I[3], J[3] ); - - if ( TYPE & TDFX_RGBA_BIT ) { - INTERP_RGBA( t, - ((GLubyte *)&(O[4])), - ((GLubyte *)&(I[4])), - ((GLubyte *)&(J[4])) ); - } - - if ( TYPE & TDFX_TEX0_BIT ) { - O[6] = LINTERP( t, I[6], J[6] ); - O[7] = LINTERP( t, I[7], J[7] ); - } - - if ( TYPE & TDFX_TEX1_BIT ) { - O[8] = LINTERP( t, I[8], J[8] ); - O[9] = LINTERP( t, I[9], J[9] ); - } -} - - - -static void TAG(tdfx_project_vertices)( struct vertex_buffer *VB ) -{ - GLcontext *ctx = VB->ctx; - GLmatrix *mat = &ctx->Viewport.WindowMap; - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - tdfxVertexBufferPtr fxVB = TDFX_DRIVER_DATA(VB); - GLfloat *first = fxVB->verts[VB->CopyStart].f; - GLfloat *last = fxVB->verts[fxVB->last_vert].f; - GLfloat m[16]; - GLfloat *f; - - m[MAT_SX] = mat->m[MAT_SX]; - m[MAT_TX] = mat->m[MAT_TX] + fxMesa->x_offset + TRI_X_OFFSET; - m[MAT_SY] = mat->m[MAT_SY]; - m[MAT_TY] = mat->m[MAT_TY] + fxMesa->y_delta + TRI_Y_OFFSET; - m[MAT_SZ] = mat->m[MAT_SZ]; - m[MAT_TZ] = mat->m[MAT_TZ]; - - gl_project_v16( first, last, m, 16 * 4 ); - - /* V3 at least requires texcoords to be multiplied by 1/w: - */ - if ( TYPE & (TDFX_TEX0_BIT|TDFX_TEX1_BIT) ) { - - const GLfloat sScale0 = fxMesa->sScale0; - const GLfloat tScale0 = fxMesa->tScale0; - const GLfloat sScale1 = fxMesa->sScale1; - const GLfloat tScale1 = fxMesa->tScale1; - - - for ( f = first ; f != last ; f += 16) { - const GLfloat oow = f[3]; - - if (TYPE & TDFX_TEX0_BIT) { - f[CLIP_S0] *= sScale0 * oow; - f[CLIP_T0] *= tScale0 * oow; - } - - if (TYPE & TDFX_TEX1_BIT) { - f[CLIP_S1] *= sScale1 * oow; - f[CLIP_T1] *= tScale1 * oow; - } - } - } -} - -static void TAG(tdfx_project_clipped_vertices)( struct vertex_buffer *VB ) -{ - GLfloat *f; - - GLcontext *ctx = VB->ctx; - GLmatrix *mat = &ctx->Viewport.WindowMap; - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - tdfxVertexBufferPtr fxVB = TDFX_DRIVER_DATA(VB); - GLfloat *first = fxVB->verts[VB->CopyStart].f; - GLfloat *last = fxVB->verts[fxVB->last_vert].f; - const GLubyte *mask = VB->ClipMask + VB->CopyStart; - GLfloat m[16]; - - m[MAT_SX] = mat->m[MAT_SX]; - m[MAT_TX] = mat->m[MAT_TX] + fxMesa->x_offset + TRI_X_OFFSET; - m[MAT_SY] = mat->m[MAT_SY]; - m[MAT_TY] = mat->m[MAT_TY] + fxMesa->y_delta + TRI_Y_OFFSET; - m[MAT_SZ] = mat->m[MAT_SZ]; - m[MAT_TZ] = mat->m[MAT_TZ]; - - gl_project_clipped_v16( first, last, m, 16 * 4, mask ); - - /* V3 at least requires texcoords to be multiplied by 1/w: - */ - if ( TYPE & (TDFX_TEX0_BIT|TDFX_TEX1_BIT) ) { - - const GLfloat sScale0 = fxMesa->sScale0; - const GLfloat tScale0 = fxMesa->tScale0; - const GLfloat sScale1 = fxMesa->sScale1; - const GLfloat tScale1 = fxMesa->tScale1; - - for ( f = first ; f != last ; f += 16, mask++) { - if (!*mask) { - const GLfloat oow = f[3]; - if (TYPE & TDFX_TEX0_BIT) { - f[CLIP_S0] *= sScale0 * oow; - f[CLIP_T0] *= tScale0 * oow; - } - - if (TYPE & TDFX_TEX1_BIT) { - f[CLIP_S1] *= sScale1 * oow; - f[CLIP_T1] *= tScale1 * oow; - } - } - } - } -} - -static void TAG(tdfx_init_fastpath)( struct tdfx_fast_tab *tab ) -{ - tab->build_vertices = TAG(tdfx_setup_full); - tab->interp = TAG(tdfx_interp_vert); - tab->project_vertices = TAG(tdfx_project_vertices); - tab->project_clipped_vertices = TAG(tdfx_project_clipped_vertices); -} - -#undef TYPE -#undef TAG -#undef SIZE diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_lock.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_lock.c index 729349a24..40f097476 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_lock.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_lock.c @@ -34,11 +34,10 @@ * */ -#include "dri_glide.h" - #include "tdfx_context.h" #include "tdfx_lock.h" #include "tdfx_state.h" +#include "tdfx_render.h" #include "tdfx_texman.h" #include "tdfx_tris.h" @@ -51,15 +50,14 @@ void tdfxGetLock( tdfxContextPtr fxMesa ) TDFXSAREAPriv *saPriv = (TDFXSAREAPriv *) (((char *) sPriv->pSAREA) + fxMesa->fxScreen->sarea_priv_offset); int stamp = dPriv->lastStamp; - int one_rect = (fxMesa->numClipRects <= 1); drmGetLock( fxMesa->driFd, fxMesa->hHWContext, 0 ); /* This macro will update dPriv's cliprects if needed */ - XMESA_VALIDATE_DRAWABLE_INFO( cPriv->display, sPriv, dPriv ); + DRI_VALIDATE_DRAWABLE_INFO( cPriv->display, sPriv, dPriv ); if ( saPriv->fifoOwner != fxMesa->hHWContext ) { - fxMesa->Glide.grDRIImportFifo( saPriv->fifoPtr, saPriv->fifoRead ); + fxMesa->Glide.grDRIImportFifo( saPriv->fifoPtr, saPriv->fifoRead ); } if ( saPriv->ctxOwner != fxMesa->hHWContext ) { @@ -69,11 +67,11 @@ void tdfxGetLock( tdfxContextPtr fxMesa ) * that state onto the hardware when you set the state. */ void *state; - FxI32 size; - fxMesa->Glide.grGet( GR_GLIDE_STATE_SIZE, 4, &size ); - state = malloc( size ); - FX_grGlideGetState_NoLock( state ); - FX_grGlideSetState_NoLock( state ); + FxI32 stateSize; + fxMesa->Glide.grGet(GR_GLIDE_STATE_SIZE, 4, &stateSize); + state = malloc(stateSize); + fxMesa->Glide.grGlideGetState( state ); + fxMesa->Glide.grGlideSetState( state ); free( state ); } @@ -88,11 +86,5 @@ void tdfxGetLock( tdfxContextPtr fxMesa ) tdfxUploadClipping(fxMesa); } - /* Detect if we have swapped between 1 and >1 cliprects, and change - * triangle funcs if necessary. - */ - if (one_rect != (fxMesa->numClipRects <= 1)) - tdfxDDToggleTriCliprects( fxMesa->glCtx ); - DEBUG_LOCK(); } diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_lock.h b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_lock.h index 8f258f57b..249384f81 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_lock.h +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_lock.h @@ -23,7 +23,7 @@ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_lock.h,v 1.2 2001/08/18 02:51:06 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_lock.h,v 1.1 2001/03/21 16:14:28 dawes Exp $ */ /* * Original rewrite: diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_pipeline.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_pipeline.c deleted file mode 100644 index 370ed51f2..000000000 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_pipeline.c +++ /dev/null @@ -1,177 +0,0 @@ -/* -*- 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/tdfx/tdfx_pipeline.c,v 1.1 2001/03/21 16:14:28 dawes Exp $ */ - -/* - * Original rewrite: - * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 - * - * Authors: - * Gareth Hughes <gareth@valinux.com> - * Keith Whitwell <keithw@valinux.com> - * - */ - -#include "tdfx_context.h" -#include "tdfx_pipeline.h" -#include "tdfx_vb.h" -#include "tdfx_tris.h" - -#include "vbindirect.h" - -static struct gl_pipeline_stage tdfx_fast_stage = { - "TDFX Fast Path", - (PIPE_OP_VERT_XFORM | - PIPE_OP_RAST_SETUP_0 | - PIPE_OP_RAST_SETUP_1 | - PIPE_OP_RENDER), - PIPE_PRECALC, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - tdfxDDFastPath -}; - -#define ILLEGAL_ENABLES (TEXTURE0_3D | \ - TEXTURE1_3D | \ - ENABLE_TEXMAT0 | \ - ENABLE_TEXMAT1 | \ - ENABLE_TEXGEN0 | \ - ENABLE_TEXGEN1 | \ - ENABLE_USERCLIP | \ - ENABLE_LIGHT | \ - ENABLE_FOG) - -/* Build the PRECALC pipeline with our stage, if possible. Otherwise, - * return GL_FALSE. - */ -GLboolean tdfxDDBuildPrecalcPipeline( GLcontext *ctx ) -{ - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - struct gl_pipeline *pipe = &ctx->CVA.pre; - - if ( (fxMesa->RenderIndex & ~TDFX_CLIPRECT_BIT) == 0 && - (ctx->Enabled & ILLEGAL_ENABLES) == 0 && -#ifdef VAO - (ctx->Array.Current->Flags & (VERT_OBJ_234 | -#else - (ctx->Array.Flags & (VERT_OBJ_234 | -#endif - VERT_TEX0_4 | - VERT_TEX1_4 | - VERT_ELT)) == (VERT_OBJ_23 | VERT_ELT) ) - { - pipe->stages[0] = &tdfx_fast_stage; - pipe->stages[1] = 0; - pipe->new_inputs = ctx->RenderFlags & VERT_DATA; - pipe->ops = pipe->stages[0]->ops; - - fxMesa->using_fast_path = GL_TRUE; - return GL_TRUE; - } - - if ( fxMesa->using_fast_path ) { - fxMesa->using_fast_path = GL_FALSE; - - ctx->CVA.VB->ClipOrMask = 0; - ctx->CVA.VB->ClipAndMask = CLIP_ALL_BITS; -#ifdef VAO - ctx->Array.NewArrayState |= ctx->Array.Current->Summary; -#else - ctx->Array.NewArrayState |= ctx->Array.Summary; -#endif - } - - return GL_FALSE; -} - - -static void tdfxDDCheckRasterSetup( GLcontext *ctx, - struct gl_pipeline_stage *d ) -{ - d->type = PIPE_IMMEDIATE | PIPE_PRECALC; - d->inputs = ctx->RenderFlags; - - d->outputs = VERT_SETUP_FULL; - - if ( ctx->IndirectTriangles & DD_SW_SETUP ) - d->type = PIPE_IMMEDIATE; -} - - -static void tdfxDDRenderElements(struct vertex_buffer *VB) -{ - if (VB->ClipOrMask) { - gl_render_elts( VB ); - } else { - GLcontext *ctx = VB->ctx; - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - fxMesa->RenderElementsRaw( VB ); - } -} - - -/* Register the pipeline with our stages included */ -GLuint tdfxDDRegisterPipelineStages( struct gl_pipeline_stage *out, - const struct gl_pipeline_stage *in, - GLuint nr ) -{ - int i, o; - - for ( i = o = 0 ; i < nr ; i++ ) { - switch ( in[i].ops ) { - - case PIPE_OP_RAST_SETUP_0: - out[o] = in[i]; - out[o].cva_state_change = (NEW_LIGHTING | - NEW_TEXTURING | - NEW_RASTER_OPS); - out[o].state_change = ~0; - out[o].check = tdfxDDCheckPartialRasterSetup; - out[o].run = tdfxDDPartialRasterSetup; - o++; - break; - - case PIPE_OP_RAST_SETUP_0 | PIPE_OP_RAST_SETUP_1: - out[o] = in[i]; - out[o].check = tdfxDDCheckRasterSetup; - out[o].run = tdfxDDDoRasterSetup; - o++; - break; - - case PIPE_OP_RENDER: - out[o] = in[i]; - if (in[i].type == PIPE_PRECALC) - out[o].run = tdfxDDRenderElements; - o++; - break; - - default: - out[o++] = in[i]; - break; - } - } - - return o; -} diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_pixels.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_pixels.c index 9be3edf44..dc9b01e0f 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_pixels.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_pixels.c @@ -23,7 +23,7 @@ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_pixels.c,v 1.3 2001/08/18 02:51:06 dawes Exp $ */ +/* $XFree86$ */ /* * Original rewrite: @@ -38,13 +38,56 @@ #include "tdfx_context.h" #include "tdfx_dd.h" +#include "tdfx_lock.h" #include "tdfx_vb.h" -#include "tdfx_pipeline.h" #include "tdfx_pixels.h" #include "tdfx_render.h" +#include "swrast/swrast.h" + #include "image.h" + +#define FX_grLfbWriteRegion(fxMesa,dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data) \ + do { \ + LOCK_HARDWARE(fxMesa); \ + fxMesa->Glide.grLfbWriteRegion(dst_buffer,dst_x,dst_y,src_format,src_width,src_height,FXFALSE,src_stride,src_data); \ + UNLOCK_HARDWARE(fxMesa); \ + } while(0) + + +#define FX_grLfbReadRegion(fxMesa,src_buffer,src_x,src_y,src_width,src_height,dst_stride,dst_data) \ + do { \ + LOCK_HARDWARE(fxMesa); \ + fxMesa->Glide.grLfbReadRegion(src_buffer,src_x,src_y,src_width,src_height,dst_stride,dst_data); \ + UNLOCK_HARDWARE(fxMesa); \ + } while (0); + + +static FxBool +FX_grLfbLock(tdfxContextPtr fxMesa, GrLock_t type, GrBuffer_t buffer, + GrLfbWriteMode_t writeMode, GrOriginLocation_t origin, + FxBool pixelPipeline, GrLfbInfo_t * info) +{ + FxBool result; + + LOCK_HARDWARE(fxMesa); + result = fxMesa->Glide.grLfbLock(type, buffer, writeMode, origin, pixelPipeline, info); + UNLOCK_HARDWARE(fxMesa); + return result; +} + + + +#define FX_grLfbUnlock(fxMesa, t, b) \ + do { \ + LOCK_HARDWARE(fxMesa); \ + fxMesa->Glide.grLfbUnlock(t, b); \ + UNLOCK_HARDWARE(fxMesa); \ + } while (0) + + + #if 0 /* test if window coord (px,py) is visible */ static GLboolean @@ -432,25 +475,26 @@ tdfx_bitmap_R8G8B8A8(GLcontext * ctx, GLint px, GLint py, } #endif -GLboolean +void tdfx_readpixels_R5G6B5(GLcontext * ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, const struct gl_pixelstore_attrib *packing, GLvoid * dstImage) { - if (!(format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5)) { - return GL_FALSE; /* format/type not recognised */ - } - - if (ctx->Pixel.ScaleOrBiasRGBA || ctx->Pixel.MapColorFlag) { - return GL_FALSE; /* can't do this */ + if (format != GL_RGB || + type != GL_UNSIGNED_SHORT_5_6_5 || + (ctx->_ImageTransferState & (IMAGE_SCALE_BIAS_BIT| + IMAGE_MAP_COLOR_BIT))) + { + _swrast_ReadPixels( ctx, x, y, width, height, format, type, packing, + dstImage ); + return; } { tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); GrLfbInfo_t info; - GLboolean result = GL_FALSE; const GLint winX = fxMesa->x_offset; const GLint winY = fxMesa->y_offset + fxMesa->height - 1; @@ -460,9 +504,9 @@ tdfx_readpixels_R5G6B5(GLcontext * ctx, GLint x, GLint y, LOCK_HARDWARE( fxMesa ); info.size = sizeof(info); if (fxMesa->Glide.grLfbLock(GR_LFB_READ_ONLY, - fxMesa->ReadBuffer, - GR_LFBWRITEMODE_ANY, - GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { + fxMesa->ReadBuffer, + GR_LFBWRITEMODE_ANY, + GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { const GLint srcStride = (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) ? (fxMesa->screen_width) : (info.strideInBytes / 2); const GLushort *src = (const GLushort *) info.lfbPtr @@ -472,45 +516,43 @@ tdfx_readpixels_R5G6B5(GLcontext * ctx, GLint x, GLint y, const GLint dstStride = _mesa_image_row_stride(packing, width, format, type); - if (format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5) { - /* directly memcpy 5R6G5B pixels into client's buffer */ - const GLint widthInBytes = width * 2; - GLint row; - for (row = 0; row < height; row++) { - MEMCPY(dst, src, widthInBytes); - dst += dstStride; - src -= srcStride; - } - result = GL_TRUE; + /* directly memcpy 5R6G5B pixels into client's buffer */ + const GLint widthInBytes = width * 2; + GLint row; + for (row = 0; row < height; row++) { + MEMCPY(dst, src, widthInBytes); + dst += dstStride; + src -= srcStride; } fxMesa->Glide.grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->ReadBuffer); } UNLOCK_HARDWARE( fxMesa ); - return result; + return; } } -GLboolean +void tdfx_readpixels_R8G8B8A8(GLcontext * ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, const struct gl_pixelstore_attrib *packing, GLvoid * dstImage) { - if (!(format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8) && - !(format == GL_BGRA && type == GL_UNSIGNED_BYTE)) { - return GL_FALSE; /* format/type not optimised */ + if ((!(format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8) && + !(format == GL_BGRA && type == GL_UNSIGNED_BYTE)) || + (ctx->_ImageTransferState & (IMAGE_SCALE_BIAS_BIT| + IMAGE_MAP_COLOR_BIT))) + { + _swrast_ReadPixels( ctx, x, y, width, height, format, type, packing, + dstImage ); + return; } - if (ctx->Pixel.ScaleOrBiasRGBA || ctx->Pixel.MapColorFlag) { - return GL_FALSE; /* can't do this */ - } { tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); GrLfbInfo_t info; - GLboolean result = GL_FALSE; const GLint winX = fxMesa->x_offset; const GLint winY = fxMesa->y_offset + fxMesa->height - 1; @@ -520,9 +562,9 @@ tdfx_readpixels_R8G8B8A8(GLcontext * ctx, GLint x, GLint y, LOCK_HARDWARE(fxMesa); info.size = sizeof(info); if (fxMesa->Glide.grLfbLock(GR_LFB_READ_ONLY, - fxMesa->ReadBuffer, - GR_LFBWRITEMODE_ANY, - GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) + fxMesa->ReadBuffer, + GR_LFBWRITEMODE_ANY, + GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { const GLint srcStride = (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) ? (fxMesa->screen_width) : (info.strideInBytes / 4); @@ -534,46 +576,53 @@ tdfx_readpixels_R8G8B8A8(GLcontext * ctx, GLint x, GLint y, dstImage, width, height, format, type, 0, 0, 0); const GLint widthInBytes = width * 4; - if ((format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8) || - (format == GL_BGRA && type == GL_UNSIGNED_BYTE)) { + { GLint row; for (row = 0; row < height; row++) { MEMCPY(dst, src, widthInBytes); dst += dstStride; src -= srcStride; } - result = GL_TRUE; } fxMesa->Glide.grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->ReadBuffer); } UNLOCK_HARDWARE(fxMesa); - return result; } } -GLboolean +void tdfx_drawpixels_R8G8B8A8(GLcontext * ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, const struct gl_pixelstore_attrib *unpack, const GLvoid * pixels) { - if (!(format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8) && - !(format == GL_BGRA && type == GL_UNSIGNED_BYTE)) { - return GL_FALSE; /* format/type not optimised */ - } - - if (ctx->Pixel.ZoomX!=1.0F || ctx->Pixel.ZoomY!=1.0F) { - return GL_FALSE; /* can't scale pixels */ - } - - if (ctx->Pixel.ScaleOrBiasRGBA || ctx->Pixel.MapColorFlag) { - return GL_FALSE; /* can't do this */ - } + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - if (ctx->RasterMask & (~BLEND_BIT)) { - return GL_FALSE; /* can't do any raster ops, except blend */ + if ((!(format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8) && + !(format == GL_BGRA && type == GL_UNSIGNED_BYTE)) || + ctx->Pixel.ZoomX != 1.0F || + ctx->Pixel.ZoomY != 1.0F || + (ctx->_ImageTransferState & (IMAGE_SCALE_BIAS_BIT| + IMAGE_MAP_COLOR_BIT)) || + ctx->Color.AlphaEnabled || + ctx->Depth.Test || + ctx->Fog.Enabled || + ctx->Scissor.Enabled || + ctx->Stencil.Enabled || + !ctx->Color.ColorMask[0] || + !ctx->Color.ColorMask[1] || + !ctx->Color.ColorMask[2] || + !ctx->Color.ColorMask[3] || + ctx->Color.ColorLogicOpEnabled || + ctx->Texture._ReallyEnabled || + ctx->Depth.OcclusionTest || + fxMesa->Fallback) + { + _swrast_DrawPixels( ctx, x, y, width, height, format, type, + unpack, pixels ); + return; } { @@ -590,7 +639,7 @@ tdfx_drawpixels_R8G8B8A8(GLcontext * ctx, GLint x, GLint y, LOCK_HARDWARE(fxMesa); /* make sure hardware has latest blend funcs */ - if (ctx->RasterMask & BLEND_BIT) { + if (ctx->Color.BlendEnabled) { fxMesa->dirty |= TDFX_UPLOAD_BLEND_FUNC; tdfxEmitHwStateLocked( fxMesa ); } @@ -599,15 +648,17 @@ tdfx_drawpixels_R8G8B8A8(GLcontext * ctx, GLint x, GLint y, if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) { if (!inClipRects_Region(fxMesa, scrX, scrY, width, height)) { UNLOCK_HARDWARE(fxMesa); - return GL_FALSE; + _swrast_DrawPixels( ctx, x, y, width, height, format, type, + unpack, pixels ); + return; } } info.size = sizeof(info); if (fxMesa->Glide.grLfbLock(GR_LFB_WRITE_ONLY, - fxMesa->DrawBuffer, - GR_LFBWRITEMODE_8888, - GR_ORIGIN_UPPER_LEFT, FXTRUE, &info)) + fxMesa->DrawBuffer, + GR_LFBWRITEMODE_8888, + GR_ORIGIN_UPPER_LEFT, FXTRUE, &info)) { const GLint dstStride = (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) ? (fxMesa->screen_width * 4) : (info.strideInBytes); @@ -633,6 +684,5 @@ tdfx_drawpixels_R8G8B8A8(GLcontext * ctx, GLint x, GLint y, fxMesa->Glide.grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->DrawBuffer); } UNLOCK_HARDWARE(fxMesa); - return result; } } diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_pixels.h b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_pixels.h index bb409d6fa..d565ca496 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_pixels.h +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_pixels.h @@ -43,33 +43,33 @@ #include "context.h" -extern GLboolean +extern void tdfx_bitmap_R5G6B5( GLcontext *ctx, GLint px, GLint py, GLsizei width, GLsizei height, const struct gl_pixelstore_attrib *unpack, const GLubyte *bitmap ); -extern GLboolean +extern void tdfx_bitmap_R8G8B8A8( GLcontext *ctx, GLint px, GLint py, GLsizei width, GLsizei height, const struct gl_pixelstore_attrib *unpack, const GLubyte *bitmap ); -extern GLboolean +extern void tdfx_readpixels_R5G6B5( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, const struct gl_pixelstore_attrib *packing, GLvoid *dstImage ); -extern GLboolean +extern void tdfx_readpixels_R8G8B8A8( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, const struct gl_pixelstore_attrib *packing, GLvoid *dstImage ); -extern GLboolean +extern void tdfx_drawpixels_R8G8B8A8( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_render.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_render.c index d97549f0a..e3afab10d 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_render.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_render.c @@ -35,91 +35,22 @@ * */ -#include "dri_glide.h" #include "tdfx_context.h" #include "tdfx_render.h" #include "tdfx_state.h" #include "tdfx_texman.h" +#include "swrast/swrast.h" /* Clear the color and/or depth buffers. */ -static GLbitfield tdfxDDClear( GLcontext *ctx, - GLbitfield mask, GLboolean all, - GLint x, GLint y, GLint width, GLint height ) +static void tdfxDDClear( GLcontext *ctx, + GLbitfield mask, GLboolean all, + GLint x, GLint y, GLint width, GLint height ) { tdfxContextPtr fxMesa = (tdfxContextPtr) ctx->DriverCtx; - const GLuint stencil_size = fxMesa->haveHwStencil ? fxMesa->glVis->StencilBits : 0; - GLbitfield softwareMask = 0; - -#if 0 - GLuint flags; - - FLUSH_BATCH( fxMesa ); - - if ( mask & DD_FRONT_LEFT_BIT ) { - flags |= TDFX_FRONT; - mask &= ~DD_FRONT_LEFT_BIT; - } - - if ( mask & DD_BACK_LEFT_BIT ) { - flags |= TDFX_BACK; - mask &= ~DD_BACK_LEFT_BIT; - } - - if ( (mask & DD_DEPTH_BIT) && ctx->Depth.Mask ) { - flags |= TDFX_DEPTH; - mask &= ~DD_DEPTH_BIT; - } - - if ( (mask & DD_STENCIL_BIT) && fxMesa->haveHwStencil ) { - clear.flags |= TDFX_STENCIL; - mask &= ~DD_STENCIL_BIT; - } - - if ( !flags ) - return mask; - - LOCK_HARDWARE( fxMesa ); - - - if ( flags & TDFX_FRONT ) { - - } - - if ( flags & TDFX_BACK ) { - - } - - if ( flags & TDFX_DEPTH ) { - - } - - if ( flags & TDFX_STENCIL ) { - fxMesa->Glide.grStencilMask( fxMesa->Stencil.WriteMask ); - /* set stencil ref value = desired clear value */ - fxMesa->Glide.grStencilFunc( GR_CMP_ALWAYS, fxMesa->Stencil.Clear, 0xff ); - fxMesa->Glide.grStencilOp( GR_STENCILOP_REPLACE, - GR_STENCILOP_REPLACE, - GR_STENCILOP_REPLACE ); - fxMesa->Glide.grEnable( GR_STENCIL_MODE_EXT ); - - if ( ctx->Stencil.Enabled ) { - fxMesa->Glide.grStencilOp( fxMesa->Stencil.FailFunc, - fxMesa->Stencil.ZFailFunc, - fxMesa->Stencil.ZPassFunc ); - fxMesa->Glide.grStencilMask( fxMesa->Stencil.WriteMask ); - fxMesa->Glide.grStencilFunc( fxMesa->Stencil.Function, - fxMesa->Stencil.RefValue, - fxMesa->Stencil.ValueMask ); - fxMesa->Glide.grEnable_NoLock( GR_STENCIL_MODE_EXT ); - } else { - fxMesa->Glide.grDisable( GR_STENCIL_MODE_EXT ); - } - - } - UNLOCK_HARDWARE( fxMesa ); - -#else + GLbitfield softwareMask = mask & (DD_ACCUM_BIT); + const GLuint stencil_size = + fxMesa->haveHwStencil ? fxMesa->glCtx->Visual.stencilBits : 0; if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) { fprintf( stderr, "%s( %d, %d, %d, %d )\n", @@ -133,10 +64,7 @@ static GLbitfield tdfxDDClear( GLcontext *ctx, } /* we can't clear accum buffers */ - if (mask & DD_ACCUM_BIT) { - mask &= ~(DD_ACCUM_BIT); - softwareMask |= DD_ACCUM_BIT; - } + mask &= ~(DD_ACCUM_BIT); if (mask & DD_STENCIL_BIT) { if (!fxMesa->haveHwStencil || ctx->Stencil.WriteMask != 0xff) { @@ -147,10 +75,10 @@ static GLbitfield tdfxDDClear( GLcontext *ctx, } } - if (fxMesa->glVis->RedBits != 8) { + if (fxMesa->glCtx->Visual.redBits != 8) { /* can only do color masking if running in 24/32bpp on Napalm */ - if ((ctx->Color.ColorMask[RCOMP] != ctx->Color.ColorMask[GCOMP]) || - (ctx->Color.ColorMask[GCOMP] != ctx->Color.ColorMask[BCOMP])) { + if (ctx->Color.ColorMask[RCOMP] != ctx->Color.ColorMask[GCOMP] || + ctx->Color.ColorMask[GCOMP] != ctx->Color.ColorMask[BCOMP]) { softwareMask |= (mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT)); mask &= ~(DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT); } @@ -166,7 +94,8 @@ static GLbitfield tdfxDDClear( GLcontext *ctx, if (mask & DD_STENCIL_BIT) { fxMesa->Glide.grStencilMask(/*ctx->Stencil.WriteMask*/ 0xff); /* set stencil ref value = desired clear value */ - fxMesa->Glide.grStencilFunc(GR_CMP_ALWAYS, ctx->Stencil.Clear, 0xff); + fxMesa->Glide.grStencilFunc(GR_CMP_ALWAYS, + ctx->Stencil.Clear, 0xff); fxMesa->Glide.grStencilOp(GR_STENCILOP_REPLACE, GR_STENCILOP_REPLACE, GR_STENCILOP_REPLACE); fxMesa->Glide.grEnable(GR_STENCIL_MODE_EXT); @@ -178,7 +107,8 @@ static GLbitfield tdfxDDClear( GLcontext *ctx, } /* - * FIXME: This is just plain ugly... + * This may be ugly, but it's needed in order to work around a number + * of Glide bugs. */ BEGIN_CLIP_LOOP(fxMesa); { @@ -277,8 +207,7 @@ static GLbitfield tdfxDDClear( GLcontext *ctx, case DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT: /* front and back */ fxMesa->Glide.grDepthMask(FXFALSE); - fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER); - FX_grColorMaskv_NoLock(ctx, true4); + fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER); if (stencil_size > 0) fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor, fxMesa->Color.ClearAlpha, @@ -288,7 +217,7 @@ static GLbitfield tdfxDDClear( GLcontext *ctx, fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor, fxMesa->Color.ClearAlpha, fxMesa->Depth.Clear); - fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER); + fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER); if (stencil_size > 0) fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor, fxMesa->Color.ClearAlpha, @@ -306,7 +235,6 @@ static GLbitfield tdfxDDClear( GLcontext *ctx, /* clear front */ fxMesa->Glide.grDepthMask(FXFALSE); fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER); - FX_grColorMaskv_NoLock(ctx, true4); if (stencil_size > 0) fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor, fxMesa->Color.ClearAlpha, @@ -319,7 +247,7 @@ static GLbitfield tdfxDDClear( GLcontext *ctx, /* clear back and depth */ fxMesa->Glide.grDepthMask(FXTRUE); fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER); - if (stencil_size > 0) + if (stencil_size > 0) fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor, fxMesa->Color.ClearAlpha, fxMesa->Depth.Clear, @@ -381,8 +309,8 @@ static GLbitfield tdfxDDClear( GLcontext *ctx, fxMesa->dirty |= TDFX_UPLOAD_STENCIL; } -#endif - return softwareMask; + if (softwareMask) + _swrast_Clear( ctx, softwareMask, all, x, y, width, height ); } @@ -410,7 +338,7 @@ static void tdfxDDFlush( GLcontext *ctx ) } - +#if 0 static const char *texSource(int k) { switch (k) { @@ -454,7 +382,9 @@ static const char *texSource(int k) return ""; } } +#endif +#if 0 static const char *texMode(int k) { switch (k) { @@ -472,11 +402,14 @@ static const char *texMode(int k) return ""; } } +#endif +#if 0 static const char *texInvert(int k) { return k ? "FXTRUE" : "FXFALSE"; } +#endif static void uploadTextureEnv( tdfxContextPtr fxMesa ) { @@ -530,7 +463,7 @@ static void uploadTextureEnv( tdfxContextPtr fxMesa ) fxMesa->TexCombineExt[unit].Alpha.Shift, fxMesa->TexCombineExt[unit].Alpha.Invert); fxMesa->Glide.grConstantColorValueExt(TDFX_TMU0 + unit, - fxMesa->TexCombineExt[unit].EnvColor); + fxMesa->TexCombineExt[unit].EnvColor); } } else { @@ -598,13 +531,16 @@ static void uploadTextureImages( tdfxContextPtr fxMesa ) { GLcontext *ctx = fxMesa->glCtx; int unit; - for ( unit = 0 ; unit < TDFX_NUM_TMU ; unit++ ) { - if ( ctx->Texture.Unit[unit].ReallyEnabled == TEXTURE0_2D ) { - struct gl_texture_object *tObj = ctx->Texture.Unit[unit].CurrentD[2]; - tdfxTexObjPtr t = TDFX_TEXTURE_DATA(tObj); - if ( t && t->reloadImages ) { - tdfxTMDownloadTextureLocked( fxMesa, tObj ); - t->reloadImages = GL_FALSE; + for (unit = 0; unit < TDFX_NUM_TMU; unit++) { + if (ctx->Texture.Unit[unit]._ReallyEnabled == TEXTURE0_2D) { + struct gl_texture_object *tObj = ctx->Texture.Unit[unit].Current2D; + tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj); + if (ti && ti->reloadImages && ti->whichTMU != TDFX_TMU_NONE) { + /* + printf("download texture image on unit %d\n", unit); + */ + tdfxTMDownloadTexture(fxMesa, tObj); + ti->reloadImages = GL_FALSE; } } } @@ -631,9 +567,9 @@ void tdfxUploadClipping( tdfxContextPtr fxMesa ) } else if (fxMesa->numClipRects == 1) { fxMesa->Glide.grClipWindow(fxMesa->pClipRects[0].x1, - fxMesa->screen_height - fxMesa->pClipRects[0].y2, - fxMesa->pClipRects[0].x2, - fxMesa->screen_height - fxMesa->pClipRects[0].y1); + fxMesa->screen_height - fxMesa->pClipRects[0].y2, + fxMesa->pClipRects[0].x2, + fxMesa->screen_height - fxMesa->pClipRects[0].y1); } /* else, we'll do a cliprect loop around all drawing */ @@ -650,23 +586,23 @@ void tdfxEmitHwStateLocked( tdfxContextPtr fxMesa ) if ( fxMesa->dirty & TDFX_UPLOAD_COLOR_COMBINE ) { if (TDFX_IS_NAPALM(fxMesa)) { fxMesa->Glide.grColorCombineExt(fxMesa->ColorCombineExt.SourceA, - fxMesa->ColorCombineExt.ModeA, - fxMesa->ColorCombineExt.SourceB, - fxMesa->ColorCombineExt.ModeB, - fxMesa->ColorCombineExt.SourceC, - fxMesa->ColorCombineExt.InvertC, - fxMesa->ColorCombineExt.SourceD, - fxMesa->ColorCombineExt.InvertD, - fxMesa->ColorCombineExt.Shift, - fxMesa->ColorCombineExt.Invert); + fxMesa->ColorCombineExt.ModeA, + fxMesa->ColorCombineExt.SourceB, + fxMesa->ColorCombineExt.ModeB, + fxMesa->ColorCombineExt.SourceC, + fxMesa->ColorCombineExt.InvertC, + fxMesa->ColorCombineExt.SourceD, + fxMesa->ColorCombineExt.InvertD, + fxMesa->ColorCombineExt.Shift, + fxMesa->ColorCombineExt.Invert); } else { /* Voodoo 3 */ - fxMesa->Glide.grColorCombine(fxMesa->ColorCombine.Function, - fxMesa->ColorCombine.Factor, - fxMesa->ColorCombine.Local, - fxMesa->ColorCombine.Other, - fxMesa->ColorCombine.Invert); + fxMesa->Glide.grColorCombine( fxMesa->ColorCombine.Function, + fxMesa->ColorCombine.Factor, + fxMesa->ColorCombine.Local, + fxMesa->ColorCombine.Other, + fxMesa->ColorCombine.Invert ); } fxMesa->dirty &= ~TDFX_UPLOAD_COLOR_COMBINE; } @@ -699,13 +635,11 @@ void tdfxEmitHwStateLocked( tdfxContextPtr fxMesa ) fxMesa->dirty &= ~TDFX_UPLOAD_RENDER_BUFFER; } -#if defined(__linux__) || defined(__FreeBSD__) if ( fxMesa->dirty & TDFX_UPLOAD_STIPPLE) { fxMesa->Glide.grStipplePattern( fxMesa->Stipple.Pattern ); fxMesa->Glide.grStippleMode( fxMesa->Stipple.Mode ); fxMesa->dirty &= ~TDFX_UPLOAD_STIPPLE; } -#endif /* __linux__ || __FreeBSD__ */ if ( fxMesa->dirty & TDFX_UPLOAD_ALPHA_TEST ) { fxMesa->Glide.grAlphaTestFunction( fxMesa->Color.AlphaFunc ); @@ -779,7 +713,7 @@ void tdfxEmitHwStateLocked( tdfxContextPtr fxMesa ) if ( fxMesa->dirty & TDFX_UPLOAD_COLOR_MASK ) { if ( fxMesa->Glide.grColorMaskExt - && fxMesa->glCtx->Visual->RedBits == 8) { + && fxMesa->glCtx->Visual.redBits == 8) { fxMesa->Glide.grColorMaskExt( fxMesa->Color.ColorMask[RCOMP], fxMesa->Color.ColorMask[GCOMP], fxMesa->Color.ColorMask[BCOMP], @@ -793,10 +727,10 @@ void tdfxEmitHwStateLocked( tdfxContextPtr fxMesa ) fxMesa->dirty &= ~TDFX_UPLOAD_COLOR_MASK; } - if ( fxMesa->dirty & TDFX_UPLOAD_CONSTANT_COLOR ) { - fxMesa->Glide.grConstantColorValue( fxMesa->Color.MonoColor ); - fxMesa->dirty &= ~TDFX_UPLOAD_CONSTANT_COLOR; - } +/* if ( fxMesa->dirty & TDFX_UPLOAD_CONSTANT_COLOR ) { */ +/* grConstantColorValue( fxMesa->Color.MonoColor ); */ +/* fxMesa->dirty &= ~TDFX_UPLOAD_CONSTANT_COLOR; */ +/* } */ if ( fxMesa->dirty & TDFX_UPLOAD_LINE ) { if (fxMesa->glCtx->Line.SmoothFlag && fxMesa->glCtx->Line.Width == 1.0) diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_screen.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_screen.c index 5d47e948a..61a3b4dea 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_screen.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_screen.c @@ -23,7 +23,7 @@ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_screen.c,v 1.2 2001/08/18 02:51:07 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_screen.c,v 1.1 2001/03/21 16:14:28 dawes Exp $ */ /* * Original rewrite: @@ -38,9 +38,9 @@ #include "tdfx_dri.h" #include "tdfx_context.h" +#include "tdfx_lock.h" #include "tdfx_vb.h" #include "tdfx_tris.h" -#include "tdfx_pipeline.h" #ifdef DEBUG_LOCKING @@ -48,8 +48,22 @@ char *prevLockFile = 0; int prevLockLine = 0; #endif +#ifndef TDFX_DEBUG +int TDFX_DEBUG = (0 +/* | DEBUG_ALWAYS_SYNC */ +/* | DEBUG_VERBOSE_API */ +/* | DEBUG_VERBOSE_MSG */ +/* | DEBUG_VERBOSE_LRU */ +/* | DEBUG_VERBOSE_DRI */ +/* | DEBUG_VERBOSE_IOCTL */ +/* | DEBUG_VERBOSE_2D */ + ); +#endif + + -GLboolean tdfxCreateScreen( __DRIscreenPrivate *sPriv ) +static GLboolean +tdfxCreateScreen( __DRIscreenPrivate *sPriv ) { tdfxScreenPrivate *fxScreen; TDFXDRIPtr fxDRIPriv = (TDFXDRIPtr) sPriv->pDevPriv; @@ -84,17 +98,12 @@ GLboolean tdfxCreateScreen( __DRIscreenPrivate *sPriv ) return GL_FALSE; } - tdfxDDSetupInit(); - tdfxDDTriangleFuncsInit(); - tdfxDDFastPathInit(); - - /*** - tdfxDDGlideExtensionsInit(); - **/ return GL_TRUE; } -void tdfxDestroyScreen( __DRIscreenPrivate *sPriv ) + +static void +tdfxDestroyScreen( __DRIscreenPrivate *sPriv ) { tdfxScreenPrivate *fxScreen = (tdfxScreenPrivate *) sPriv->private; @@ -105,3 +114,258 @@ void tdfxDestroyScreen( __DRIscreenPrivate *sPriv ) sPriv->private = NULL; } } + + +static GLboolean +tdfxInitDriver( __DRIscreenPrivate *sPriv ) +{ + int major, minor, patch; + + if ( TDFX_DEBUG & DEBUG_VERBOSE_DRI ) { + fprintf( stderr, "%s( %p )\n", __FUNCTION__, sPriv ); + } + + /* Check the DRI version */ + if ( XF86DRIQueryVersion( sPriv->display, &major, &minor, &patch ) ) { + if ( major != 4 || + minor < 0 ) { + __driUtilMessage( + "3dfx DRI driver expected DRI version 4.0.x " + "but got version %d.%d.%d", + major, minor, patch ); + return GL_FALSE; + } + } + + /* Check that the DDX driver version is compatible */ + if ( sPriv->ddxMajor != 1 || + sPriv->ddxMinor < 0 ) { + __driUtilMessage( + "3dfx DRI driver expected DDX driver version 1.0.x " + "but got version %d.%d.%d", + sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch ); + return GL_FALSE; + } + + /* Check that the DRM driver version is compatible */ + if ( sPriv->drmMajor != 1 || + sPriv->drmMinor < 0 ) { + __driUtilMessage( + "3dfx DRI driver expected DRM driver version 1.0.x " + "but got version %d.%d.%d", + sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch ); + return GL_FALSE; + } + + if ( !tdfxCreateScreen( sPriv ) ) { + tdfxDestroyScreen( sPriv ); + return GL_FALSE; + } + + return GL_TRUE; +} + + +static GLboolean +tdfxCreateBuffer( Display *dpy, + __DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + const __GLcontextModes *mesaVis, + GLboolean isPixmap ) +{ + if (isPixmap) { + return GL_FALSE; /* not implemented */ + } + else { + driDrawPriv->driverPrivate = (void *) + _mesa_create_framebuffer( mesaVis, + GL_FALSE, /* software depth buffer? */ + mesaVis->stencilBits > 0, + mesaVis->accumRedBits > 0, + GL_FALSE /* software alpha channel? */ ); + return (driDrawPriv->driverPrivate != NULL); + } +} + + +static void +tdfxDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) +{ + _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); +} + + +static void +tdfxSwapBuffers(Display *dpy, void *drawablePrivate) +{ + __DRIdrawablePrivate *driDrawPriv = (__DRIdrawablePrivate*) drawablePrivate; + GET_CURRENT_CONTEXT(ctx); + tdfxContextPtr fxMesa = 0; + GLframebuffer *mesaBuffer; + + if ( TDFX_DEBUG & DEBUG_VERBOSE_DRI ) { + fprintf( stderr, "%s( %p )\n", __FUNCTION__, driDrawPriv ); + } + + mesaBuffer = (GLframebuffer *) driDrawPriv->driverPrivate; + if ( !mesaBuffer->Visual.doubleBufferMode ) + return; /* can't swap a single-buffered window */ + + /* If the current context's drawable matches the given drawable + * we have to do a glFinish (per the GLX spec). + */ + if ( ctx ) { + __DRIdrawablePrivate *curDrawPriv; + fxMesa = TDFX_CONTEXT(ctx); + curDrawPriv = fxMesa->driContext->driDrawablePriv; + + if ( curDrawPriv == driDrawPriv ) { + /* swapping window bound to current context, flush first */ + _mesa_swapbuffers( ctx ); + LOCK_HARDWARE( fxMesa ); + } + else { + /* find the fxMesa context previously bound to the window */ + fxMesa = (tdfxContextPtr) driDrawPriv->driContextPriv->driverPrivate; + if (!fxMesa) + return; + LOCK_HARDWARE( fxMesa ); + fxMesa->Glide.grSstSelect( fxMesa->Glide.Board ); + printf("SwapBuf SetState 1\n"); + fxMesa->Glide.grGlideSetState(fxMesa->Glide.State ); + } + } + +#ifdef STATS + { + int stalls; + static int prevStalls = 0; + + stalls = fxMesa->Glide.grFifoGetStalls(); + + fprintf( stderr, "%s:\n", __FUNCTION__ ); + if ( stalls != prevStalls ) { + fprintf( stderr, " %d stalls occurred\n", + stalls - prevStalls ); + prevStalls = stalls; + } + if ( fxMesa && fxMesa->texSwaps ) { + fprintf( stderr, " %d texture swaps occurred\n", + fxMesa->texSwaps ); + fxMesa->texSwaps = 0; + } + } +#endif + + if (fxMesa->scissoredClipRects) { + /* restore clip rects without scissor box */ + fxMesa->Glide.grDRIPosition( driDrawPriv->x, driDrawPriv->y, + driDrawPriv->w, driDrawPriv->h, + driDrawPriv->numClipRects, + driDrawPriv->pClipRects ); + } + + fxMesa->Glide.grDRIBufferSwap( fxMesa->Glide.SwapInterval ); + + if (fxMesa->scissoredClipRects) { + /* restore clip rects WITH scissor box */ + fxMesa->Glide.grDRIPosition( driDrawPriv->x, driDrawPriv->y, + driDrawPriv->w, driDrawPriv->h, + fxMesa->numClipRects, fxMesa->pClipRects ); + } + + +#if 0 + { + FxI32 result; + do { + FxI32 result; + fxMesa->Glide.grGet(GR_PENDING_BUFFERSWAPS, 4, &result); + } while ( result > fxMesa->maxPendingSwapBuffers ); + } +#endif + + fxMesa->stats.swapBuffer++; + + if (ctx) { + if (ctx->DriverCtx != fxMesa) { + fxMesa = TDFX_CONTEXT(ctx); + fxMesa->Glide.grSstSelect( fxMesa->Glide.Board ); + printf("SwapBuf SetState 2\n"); + fxMesa->Glide.grGlideSetState(fxMesa->Glide.State ); + } + UNLOCK_HARDWARE( fxMesa ); + } +} + + + +/* This function is called by libGL.so as soon as libGL.so is loaded. + * This is where we'd register new extension functions with the dispatcher. + */ +void __driRegisterExtensions( void ) +{ +#if 0 + /* Example. Also look in tdfx_dd.c for more details. */ + { + const int _gloffset_FooBarEXT = 555; /* just an example number! */ + if ( _glapi_add_entrypoint( "glFooBarEXT", _gloffset_FooBarEXT ) ) { + void *f = glXGetProcAddressARB( "glFooBarEXT" ); + assert( f ); + } + } +#endif +} + +static GLboolean +tdfxOpenFullScreen(__DRIcontextPrivate *driContextPriv) +{ + fprintf(stderr,"***** XMesaOpenFullScreen *****\n"); +#if 0 /* When new glide3 calls exist */ + return((GLboolean)grDRISetupFullScreen(GL_TRUE)); +#else + return GL_TRUE; +#endif +} + + +static GLboolean +tdfxCloseFullScreen(__DRIcontextPrivate *driContextPriv) +{ + fprintf(stderr,"***** XMesaCloseFullScreen *****\n"); +#if 0 /* When new glide3 calls exist */ + return((GLboolean)grDRISetupFullScreen(GL_FALSE)); +#else + return GL_TRUE; +#endif +} + + + +static struct __DriverAPIRec tdfxAPI = { + tdfxInitDriver, + tdfxDestroyScreen, + tdfxCreateContext, + tdfxDestroyContext, + tdfxCreateBuffer, + tdfxDestroyBuffer, + tdfxSwapBuffers, + tdfxMakeCurrent, + tdfxUnbindContext, + tdfxOpenFullScreen, + tdfxCloseFullScreen +}; + + +/* + * This is the bootstrap function for the driver. + * The __driCreateScreen name is the symbol that libGL.so fetches. + * Return: pointer to a __DRIscreenPrivate. + */ +void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, + int numConfigs, __GLXvisualConfig *config) +{ + __DRIscreenPrivate *psp; + psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &tdfxAPI); + return (void *) psp; +} diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_screen.h b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_screen.h index 9c41933d8..2391417e9 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_screen.h +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_screen.h @@ -39,8 +39,6 @@ #ifdef GLX_DIRECT_RENDERING -#include "dri_mesaint.h" - typedef struct { drmHandle handle; drmSize size; @@ -71,8 +69,5 @@ typedef struct { } tdfxScreenPrivate; -extern GLboolean tdfxCreateScreen( __DRIscreenPrivate *driScrnPriv ); -extern void tdfxDestroyScreen( __DRIscreenPrivate *driScrnPriv ); - #endif #endif diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_span.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_span.c index 06bd0022f..6b9a49b57 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_span.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_span.c @@ -23,7 +23,7 @@ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_span.c,v 1.3 2001/08/18 02:51:07 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_span.c,v 1.1 2001/03/21 16:14:28 dawes Exp $ */ /* * Original rewrite: @@ -37,8 +37,10 @@ */ #include "tdfx_context.h" +#include "tdfx_lock.h" #include "tdfx_span.h" #include "tdfx_render.h" +#include "swrast/swrast.h" #define DBG 0 @@ -58,8 +60,6 @@ (void) buf; (void) p; -#define INIT_MONO_PIXEL( p ) p = fxMesa->Color.MonoColor; - #define CLIPPIXEL( _x, _y ) ( _x >= minx && _x < maxx && \ _y >= miny && _y < maxy ) @@ -83,8 +83,9 @@ UNLOCK_HARDWARE( fxMesa ); \ LOCK_HARDWARE( fxMesa ); \ info.size = sizeof(GrLfbInfo_t); \ - if ( fxMesa->Glide.grLfbLock( GR_LFB_WRITE_ONLY, fxMesa->DrawBuffer, \ - LFB_MODE, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info ) ) \ + if ( fxMesa->Glide.grLfbLock( GR_LFB_WRITE_ONLY, \ + fxMesa->DrawBuffer, LFB_MODE, \ + GR_ORIGIN_UPPER_LEFT, FXFALSE, &info ) ) \ { #define HW_WRITE_UNLOCK() \ @@ -100,7 +101,7 @@ LOCK_HARDWARE( fxMesa ); \ info.size = sizeof(GrLfbInfo_t); \ if ( fxMesa->Glide.grLfbLock( GR_LFB_READ_ONLY, fxMesa->ReadBuffer, \ - LFB_MODE, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info ) ) \ + LFB_MODE, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info ) ) \ { #define HW_READ_UNLOCK() \ @@ -140,6 +141,11 @@ /* 16 bit, RGB565 color spanline and pixel functions */ \ +#undef INIT_MONO_PIXEL +#define INIT_MONO_PIXEL(p, color) \ + p = TDFXPACKCOLOR565( color[0], color[1], color[2] ) + + #define WRITE_RGBA( _x, _y, r, g, b, a ) \ *(GLushort *)(buf + _x*2 + _y*pitch) = ((((int)r & 0xf8) << 8) | \ (((int)g & 0xfc) << 3) | \ @@ -195,6 +201,10 @@ /* 24 bit, RGB888 color spanline and pixel functions */ +#undef INIT_MONO_PIXEL +#define INIT_MONO_PIXEL(p, color) \ + p = TDFXPACKCOLOR888( color[0], color[1], color[2] ) + #define WRITE_RGBA( _x, _y, r, g, b, a ) \ *(GLuint *)(buf + _x*3 + _y*pitch) = ((b << 0) | \ (g << 8) | \ @@ -223,6 +233,10 @@ do { \ /* 32 bit, ARGB8888 color spanline and pixel functions */ +#undef INIT_MONO_PIXEL +#define INIT_MONO_PIXEL(p, color) \ + p = TDFXPACKCOLOR8888( color[0], color[1], color[2], color[3] ) + #define WRITE_RGBA( _x, _y, r, g, b, a ) \ *(GLuint *)(buf + _x*4 + _y*pitch) = ((b << 0) | \ (g << 8) | \ @@ -557,10 +571,6 @@ GetFbParams(tdfxContextPtr fxMesa, * it's better in the macro or in the call. * * Recall that x and y are screen coordinates. - * - * Note: ANSI C doesn't allow conditional expressions or cast expressions - * as lvalues. Some of these macros violate that. - * */ #define GET_FB_DATA(ReadParamsp, type, x, y) \ (((x) < (ReadParamsp)->firstWrappedX) \ @@ -592,8 +602,8 @@ tdfxDDWriteDepthSpan(GLcontext * ctx, { tdfxContextPtr fxMesa = (tdfxContextPtr) ctx->DriverCtx; GLint bottom = fxMesa->y_offset + fxMesa->height - 1; - GLuint depth_size = fxMesa->glVis->DepthBits; - GLuint stencil_size = fxMesa->glVis->StencilBits; + GLuint depth_size = fxMesa->glCtx->Visual.depthBits; + GLuint stencil_size = fxMesa->glCtx->Visual.stencilBits; GrLfbInfo_t info; GLubyte visMask[MAX_WIDTH]; @@ -828,7 +838,7 @@ tdfxDDReadDepthSpan(GLcontext * ctx, tdfxContextPtr fxMesa = (tdfxContextPtr) ctx->DriverCtx; GLint bottom = fxMesa->height + fxMesa->y_offset - 1; GLuint i; - GLuint depth_size = fxMesa->glVis->DepthBits; + GLuint depth_size = fxMesa->glCtx->Visual.depthBits; GrLfbInfo_t info; if (MESA_VERBOSE & VERBOSE_DRIVER) { @@ -883,7 +893,7 @@ tdfxDDReadDepthSpan(GLcontext * ctx, LFBParameters ReadParams; GrLfbInfo_t backBufferInfo; int wrappedPartStart; - GLuint stencil_size = fxMesa->glVis->StencilBits; + GLuint stencil_size = fxMesa->glCtx->Visual.stencilBits; GetBackBufferInfo(fxMesa, &backBufferInfo); /* * Note that the _LOCK macro adds a curly brace, @@ -934,8 +944,8 @@ tdfxDDWriteDepthPixels(GLcontext * ctx, GLuint i; GLushort d16; GLuint d32; - GLuint depth_size = fxMesa->glVis->DepthBits; - GLuint stencil_size = fxMesa->glVis->StencilBits; + GLuint depth_size = fxMesa->glCtx->Visual.depthBits; + GLuint stencil_size = fxMesa->glCtx->Visual.stencilBits; GrLfbInfo_t info; int xpos; int ypos; @@ -1013,7 +1023,7 @@ tdfxDDReadDepthPixels(GLcontext * ctx, GLuint n, tdfxContextPtr fxMesa = (tdfxContextPtr) ctx->DriverCtx; GLint bottom = fxMesa->height + fxMesa->y_offset - 1; GLuint i; - GLuint depth_size = fxMesa->glVis->DepthBits; + GLuint depth_size = fxMesa->glCtx->Visual.depthBits; GLushort d16; int xpos; int ypos; @@ -1058,7 +1068,7 @@ tdfxDDReadDepthPixels(GLcontext * ctx, GLuint n, * and the UNLOCK macro removes it. */ READ_FB_SPAN_LOCK(fxMesa, info, GR_BUFFER_AUXBUFFER); - stencil_size = fxMesa->glVis->StencilBits; + stencil_size = fxMesa->glCtx->Visual.stencilBits; { LFBParameters ReadParams; GetFbParams(fxMesa, &info, &backBufferInfo, @@ -1270,47 +1280,96 @@ read_stencil_pixels(GLcontext * ctx, GLuint n, const GLint x[], } #define VISUAL_EQUALS_RGBA(vis, r, g, b, a) \ - ((vis->RedBits == r) && \ - (vis->GreenBits == g) && \ - (vis->BlueBits == b) && \ - (vis->AlphaBits == a)) + ((vis.redBits == r) && \ + (vis.greenBits == g) && \ + (vis.blueBits == b) && \ + (vis.alphaBits == a)) + + + + +/**********************************************************************/ +/* Locking for swrast */ +/**********************************************************************/ + + +static void tdfxSpanRenderStart( GLcontext *ctx ) +{ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + LOCK_HARDWARE(fxMesa); +} + +static void tdfxSpanRenderFinish( GLcontext *ctx ) +{ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + _swrast_flush( ctx ); + UNLOCK_HARDWARE(fxMesa); +} + +/* Set the buffer used for reading */ +static void tdfxDDSetReadBuffer( GLcontext *ctx, + GLframebuffer *buffer, GLenum mode ) +{ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + (void) buffer; + + switch ( mode ) { + case GL_FRONT_LEFT: + fxMesa->ReadBuffer = GR_BUFFER_FRONTBUFFER; + break; + + case GL_BACK_LEFT: + fxMesa->ReadBuffer = GR_BUFFER_BACKBUFFER; + break; + + default: + break; + } +} + +/**********************************************************************/ +/* Initialize swrast device driver */ +/**********************************************************************/ void tdfxDDInitSpanFuncs( GLcontext *ctx ) { tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx ); + + swdd->SetReadBuffer = tdfxDDSetReadBuffer; if ( VISUAL_EQUALS_RGBA(ctx->Visual, 5, 6, 5, 0) ) { /* 16bpp mode */ - ctx->Driver.WriteRGBASpan = tdfxWriteRGBASpan_RGB565; - ctx->Driver.WriteRGBSpan = tdfxWriteRGBSpan_RGB565; - ctx->Driver.WriteMonoRGBASpan = tdfxWriteMonoRGBASpan_RGB565; - ctx->Driver.WriteRGBAPixels = tdfxWriteRGBAPixels_RGB565; - ctx->Driver.WriteMonoRGBAPixels = tdfxWriteMonoRGBAPixels_RGB565; - ctx->Driver.ReadRGBASpan = tdfxReadRGBASpan_RGB565; - ctx->Driver.ReadRGBAPixels = tdfxReadRGBAPixels_RGB565; + swdd->WriteRGBASpan = tdfxWriteRGBASpan_RGB565; + swdd->WriteRGBSpan = tdfxWriteRGBSpan_RGB565; + swdd->WriteMonoRGBASpan = tdfxWriteMonoRGBASpan_RGB565; + swdd->WriteRGBAPixels = tdfxWriteRGBAPixels_RGB565; + swdd->WriteMonoRGBAPixels = tdfxWriteMonoRGBAPixels_RGB565; + swdd->ReadRGBASpan = tdfxReadRGBASpan_RGB565; + swdd->ReadRGBAPixels = tdfxReadRGBAPixels_RGB565; } else if ( VISUAL_EQUALS_RGBA(ctx->Visual, 8, 8, 8, 0) ) { /* 24bpp mode */ - ctx->Driver.WriteRGBASpan = tdfxWriteRGBASpan_RGB888; - ctx->Driver.WriteRGBSpan = tdfxWriteRGBSpan_RGB888; - ctx->Driver.WriteMonoRGBASpan = tdfxWriteMonoRGBASpan_RGB888; - ctx->Driver.WriteRGBAPixels = tdfxWriteRGBAPixels_RGB888; - ctx->Driver.WriteMonoRGBAPixels = tdfxWriteMonoRGBAPixels_RGB888; - ctx->Driver.ReadRGBASpan = tdfxReadRGBASpan_RGB888; - ctx->Driver.ReadRGBAPixels = tdfxReadRGBAPixels_RGB888; + swdd->WriteRGBASpan = tdfxWriteRGBASpan_RGB888; + swdd->WriteRGBSpan = tdfxWriteRGBSpan_RGB888; + swdd->WriteMonoRGBASpan = tdfxWriteMonoRGBASpan_RGB888; + swdd->WriteRGBAPixels = tdfxWriteRGBAPixels_RGB888; + swdd->WriteMonoRGBAPixels = tdfxWriteMonoRGBAPixels_RGB888; + swdd->ReadRGBASpan = tdfxReadRGBASpan_RGB888; + swdd->ReadRGBAPixels = tdfxReadRGBAPixels_RGB888; } else if ( VISUAL_EQUALS_RGBA(ctx->Visual, 8, 8, 8, 8) ) { /* 32bpp mode */ - ctx->Driver.WriteRGBASpan = tdfxWriteRGBASpan_ARGB8888; - ctx->Driver.WriteRGBSpan = tdfxWriteRGBSpan_ARGB8888; - ctx->Driver.WriteMonoRGBASpan = tdfxWriteMonoRGBASpan_ARGB8888; - ctx->Driver.WriteRGBAPixels = tdfxWriteRGBAPixels_ARGB8888; - ctx->Driver.WriteMonoRGBAPixels = tdfxWriteMonoRGBAPixels_ARGB8888; - ctx->Driver.ReadRGBAPixels = tdfxReadRGBAPixels_ARGB8888; - ctx->Driver.ReadRGBASpan = tdfxReadRGBASpan_ARGB8888; + swdd->WriteRGBASpan = tdfxWriteRGBASpan_ARGB8888; + swdd->WriteRGBSpan = tdfxWriteRGBSpan_ARGB8888; + swdd->WriteMonoRGBASpan = tdfxWriteMonoRGBASpan_ARGB8888; + swdd->WriteRGBAPixels = tdfxWriteRGBAPixels_ARGB8888; + swdd->WriteMonoRGBAPixels = tdfxWriteMonoRGBAPixels_ARGB8888; + swdd->ReadRGBAPixels = tdfxReadRGBAPixels_ARGB8888; + swdd->ReadRGBASpan = tdfxReadRGBASpan_ARGB8888; } else { @@ -1318,22 +1377,25 @@ void tdfxDDInitSpanFuncs( GLcontext *ctx ) } if ( fxMesa->haveHwStencil ) { - ctx->Driver.WriteStencilSpan = write_stencil_span; - ctx->Driver.ReadStencilSpan = read_stencil_span; - ctx->Driver.WriteStencilPixels = write_stencil_pixels; - ctx->Driver.ReadStencilPixels = read_stencil_pixels; + swdd->WriteStencilSpan = write_stencil_span; + swdd->ReadStencilSpan = read_stencil_span; + swdd->WriteStencilPixels = write_stencil_pixels; + swdd->ReadStencilPixels = read_stencil_pixels; } - ctx->Driver.WriteDepthSpan = tdfxDDWriteDepthSpan; - ctx->Driver.WriteDepthPixels = tdfxDDWriteDepthPixels; - ctx->Driver.ReadDepthSpan = tdfxDDReadDepthSpan; - ctx->Driver.ReadDepthPixels = tdfxDDReadDepthPixels; - - ctx->Driver.WriteCI8Span = NULL; - ctx->Driver.WriteCI32Span = NULL; - ctx->Driver.WriteMonoCISpan = NULL; - ctx->Driver.WriteCI32Pixels = NULL; - ctx->Driver.WriteMonoCIPixels = NULL; - ctx->Driver.ReadCI32Span = NULL; - ctx->Driver.ReadCI32Pixels = NULL; + swdd->WriteDepthSpan = tdfxDDWriteDepthSpan; + swdd->WriteDepthPixels = tdfxDDWriteDepthPixels; + swdd->ReadDepthSpan = tdfxDDReadDepthSpan; + swdd->ReadDepthPixels = tdfxDDReadDepthPixels; + + swdd->WriteCI8Span = NULL; + swdd->WriteCI32Span = NULL; + swdd->WriteMonoCISpan = NULL; + swdd->WriteCI32Pixels = NULL; + swdd->WriteMonoCIPixels = NULL; + swdd->ReadCI32Span = NULL; + swdd->ReadCI32Pixels = NULL; + + swdd->SpanRenderStart = tdfxSpanRenderStart; + swdd->SpanRenderFinish = tdfxSpanRenderFinish; } diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.c index 7485f6ea1..cd321720b 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.c @@ -32,19 +32,26 @@ * Authors: * Gareth Hughes <gareth@valinux.com> * Brian Paul <brianp@valinux.com> + * Keith Whitwell <keithw@valinux.com> (port to 3.5) * */ -#include "types.h" -#include "pb.h" +#include "mtypes.h" +#include "texformat.h" +#include "texstore.h" -#include "dri_glide.h" +#include "swrast/swrast.h" +#include "array_cache/acache.h" +#include "tnl/tnl.h" +#include "tnl/t_pipeline.h" +#include "swrast_setup/swrast_setup.h" #include "tdfx_context.h" #include "tdfx_state.h" #include "tdfx_vb.h" #include "tdfx_tex.h" #include "tdfx_texman.h" +#include "tdfx_texstate.h" #include "tdfx_tris.h" #include "tdfx_render.h" @@ -60,7 +67,6 @@ static void tdfxUpdateAlphaMode( GLcontext *ctx ) GrCmpFnc_t func; GrAlphaBlendFnc_t srcRGB, dstRGB, srcA, dstA; GrAlpha_t ref = ctx->Color.AlphaRef; - const int hasAlpha = ctx->Visual->AlphaBits > 0; if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) { fprintf( stderr, "%s()\n", __FUNCTION__ ); @@ -120,13 +126,13 @@ static void tdfxUpdateAlphaMode( GLcontext *ctx ) srcRGB = GR_BLEND_ONE_MINUS_SRC_ALPHA; break; case GL_DST_ALPHA: - srcRGB = hasAlpha ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE; + srcRGB = GR_BLEND_DST_ALPHA; break; case GL_ONE_MINUS_DST_ALPHA: - srcRGB = hasAlpha ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO; + srcRGB = GR_BLEND_ONE_MINUS_DST_ALPHA; break; case GL_SRC_ALPHA_SATURATE: - srcRGB = hasAlpha ? GR_BLEND_ALPHA_SATURATE : GR_BLEND_ZERO; + srcRGB = GR_BLEND_ALPHA_SATURATE; break; default: srcRGB = GR_BLEND_ONE; @@ -139,23 +145,23 @@ static void tdfxUpdateAlphaMode( GLcontext *ctx ) case GL_ONE: srcA = GR_BLEND_ONE; break; - case GL_DST_COLOR: /* Napalm only */ - srcA = hasAlpha ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE; + case GL_DST_COLOR: + srcA = GR_BLEND_DST_ALPHA; /* Napalm only */ break; - case GL_ONE_MINUS_DST_COLOR: /* Napalm only */ - srcA = hasAlpha ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO; + case GL_ONE_MINUS_DST_COLOR: + srcA = GR_BLEND_ONE_MINUS_DST_ALPHA; /* Napalm only */ break; - case GL_SRC_ALPHA: /* Napalm only */ - srcA = GR_BLEND_SRC_ALPHA; + case GL_SRC_ALPHA: + srcA = GR_BLEND_SRC_ALPHA; /* Napalm only */ break; - case GL_ONE_MINUS_SRC_ALPHA: /* Napalm only */ - srcA = GR_BLEND_ONE_MINUS_SRC_ALPHA; + case GL_ONE_MINUS_SRC_ALPHA: + srcA = GR_BLEND_ONE_MINUS_SRC_ALPHA; /* Napalm only */ break; - case GL_DST_ALPHA: /* Napalm only */ - srcA = hasAlpha ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE; + case GL_DST_ALPHA: + srcA = GR_BLEND_DST_ALPHA; /* Napalm only */ break; - case GL_ONE_MINUS_DST_ALPHA: /* Napalm only */ - srcA = hasAlpha ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO; + case GL_ONE_MINUS_DST_ALPHA: + srcA = GR_BLEND_ONE_MINUS_DST_ALPHA; /* Napalm only */ break; case GL_SRC_ALPHA_SATURATE: srcA = GR_BLEND_ONE; @@ -184,10 +190,10 @@ static void tdfxUpdateAlphaMode( GLcontext *ctx ) dstRGB = GR_BLEND_ONE_MINUS_SRC_ALPHA; break; case GL_DST_ALPHA: - dstRGB = hasAlpha ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE; + dstRGB = GR_BLEND_DST_ALPHA; break; case GL_ONE_MINUS_DST_ALPHA: - dstRGB = hasAlpha ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO; + dstRGB = GR_BLEND_ONE_MINUS_DST_ALPHA; break; default: dstRGB = GR_BLEND_ZERO; @@ -200,23 +206,23 @@ static void tdfxUpdateAlphaMode( GLcontext *ctx ) case GL_ONE: dstA = GR_BLEND_ONE; break; - case GL_SRC_COLOR: /* Napalm only */ - dstA = GR_BLEND_SRC_ALPHA; + case GL_SRC_COLOR: + dstA = GR_BLEND_SRC_ALPHA; /* Napalm only */ break; - case GL_ONE_MINUS_SRC_COLOR: /* Napalm only */ - dstA = GR_BLEND_ONE_MINUS_SRC_ALPHA; + case GL_ONE_MINUS_SRC_COLOR: + dstA = GR_BLEND_ONE_MINUS_SRC_ALPHA; /* Napalm only */ break; - case GL_SRC_ALPHA: /* Napalm only */ - dstA = GR_BLEND_SRC_ALPHA; + case GL_SRC_ALPHA: + dstA = GR_BLEND_SRC_ALPHA; /* Napalm only */ break; - case GL_ONE_MINUS_SRC_ALPHA: /* Napalm only */ - dstA = GR_BLEND_ONE_MINUS_SRC_ALPHA; + case GL_ONE_MINUS_SRC_ALPHA: + dstA = GR_BLEND_ONE_MINUS_SRC_ALPHA; /* Napalm only */ break; - case GL_DST_ALPHA: /* Napalm only */ - dstA = hasAlpha ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE; + case GL_DST_ALPHA: + dstA = GR_BLEND_DST_ALPHA; /* Napalm only */ break; - case GL_ONE_MINUS_DST_ALPHA: /* Napalm only */ - dstA = hasAlpha ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO; + case GL_ONE_MINUS_DST_ALPHA: + dstA = GR_BLEND_ONE_MINUS_DST_ALPHA; /* Napalm only */ break; default: dstA = GR_BLEND_ZERO; @@ -251,7 +257,7 @@ static void tdfxUpdateAlphaMode( GLcontext *ctx ) } } -static void tdfxDDAlphaFunc( GLcontext *ctx, GLenum func, GLclampf ref ) +static void tdfxDDAlphaFunc( GLcontext *ctx, GLenum func, GLchan ref ) { tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); @@ -265,11 +271,6 @@ static void tdfxDDBlendEquation( GLcontext *ctx, GLenum mode ) FLUSH_BATCH( fxMesa ); fxMesa->new_state |= TDFX_NEW_ALPHA; - - if (ctx->Color.ColorLogicOpEnabled && ctx->Color.LogicOp != GL_COPY) - fxMesa->Fallback |= TDFX_FALLBACK_LOGICOP; - else - fxMesa->Fallback &= ~TDFX_FALLBACK_LOGICOP; } static void tdfxDDBlendFunc( GLcontext *ctx, GLenum sfactor, GLenum dfactor ) @@ -300,7 +301,7 @@ static void tdfxDDBlendFuncSeparate( GLcontext *ctx, * Stipple */ -static void tdfxUpdateStipple( GLcontext *ctx ) +void tdfxUpdateStipple( GLcontext *ctx ) { tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); GrStippleMode_t mode = GR_STIPPLE_DISABLE; @@ -333,9 +334,9 @@ static void tdfxUpdateZMode( GLcontext *ctx ) FxI32 bias; FxBool mask; - if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) { + if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) fprintf( stderr, "%s()\n", __FUNCTION__ ); - } + bias = (FxI32) (ctx->Polygon.OffsetUnits * TDFX_DEPTH_BIAS_SCALE); @@ -381,7 +382,7 @@ static void tdfxUpdateZMode( GLcontext *ctx ) mask = FXFALSE; /* zbuffer is not touched */ } - fxMesa->Depth.Clear = (FxU32) (((1 << fxMesa->glVis->DepthBits) - 1) + fxMesa->Depth.Clear = (FxU32) (((1 << fxMesa->glCtx->Visual.depthBits) - 1) * ctx->Depth.Clear); if ( fxMesa->Depth.Bias != bias ) { @@ -451,7 +452,7 @@ static GrStencil_t convertGLStencilOp( GLenum op ) case GL_DECR_WRAP_EXT: return GR_STENCILOP_DECR_WRAP; default: - gl_problem( NULL, "bad stencil op in convertGLStencilOp" ); + _mesa_problem( NULL, "bad stencil op in convertGLStencilOp" ); } return GR_STENCILOP_KEEP; /* never get, silence compiler warning */ } @@ -547,14 +548,14 @@ static void tdfxUpdateFogAttrib( GLcontext *ctx ) { switch( ctx->Fog.Mode ) { case GL_EXP: - fxMesa->Glide.guFogGenerateExp(fxMesa->Fog.Table, ctx->Fog.Density); + fxMesa->Glide.guFogGenerateExp( fxMesa->Fog.Table, ctx->Fog.Density ); break; case GL_EXP2: - fxMesa->Glide.guFogGenerateExp2(fxMesa->Fog.Table, ctx->Fog.Density); + fxMesa->Glide.guFogGenerateExp2( fxMesa->Fog.Table, ctx->Fog.Density); break; case GL_LINEAR: - fxMesa->Glide.guFogGenerateLinear(fxMesa->Fog.Table, - ctx->Fog.Start, ctx->Fog.End); + fxMesa->Glide.guFogGenerateLinear( fxMesa->Fog.Table, + ctx->Fog.Start, ctx->Fog.End ); break; } @@ -619,6 +620,7 @@ void tdfxUpdateClipping( GLcontext *ctx ) fxMesa->height = dPriv->h; fxMesa->y_delta = fxMesa->screen_height - fxMesa->y_offset - fxMesa->height; + tdfxUpdateViewport( ctx ); } if (fxMesa->scissoredClipRects && fxMesa->pClipRects) { @@ -678,18 +680,15 @@ void tdfxUpdateClipping( GLcontext *ctx ) * Culling */ -static void tdfxUpdateCull( GLcontext *ctx ) +void tdfxUpdateCull( GLcontext *ctx ) { tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); GrCullMode_t mode = GR_CULL_DISABLE; - if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) { - fprintf( stderr, "%s()\n", __FUNCTION__ ); - } - - if ( ctx->Polygon.CullFlag && - (ctx->PB->primitive == GL_POLYGON || - ctx->PB->primitive == GL_BITMAP) ) { + /* KW: don't need to check raster_primitive here as we don't + * attempt to draw lines or points with triangles. + */ + if ( ctx->Polygon.CullFlag ) { switch ( ctx->Polygon.CullFaceMode ) { case GL_FRONT: if ( ctx->Polygon.FrontFace == GL_CCW ) { @@ -708,8 +707,11 @@ static void tdfxUpdateCull( GLcontext *ctx ) break; case GL_FRONT_AND_BACK: + /* Handled as a fallback on triangles in tdfx_tris.c */ + return; + default: - mode = GR_CULL_DISABLE; + ASSERT(0); break; } } @@ -762,32 +764,13 @@ static void tdfxDDLineWidth( GLcontext *ctx, GLfloat width ) } - /* ============================================================= * Color Attributes */ -static void tdfxDDLogicOp( GLcontext *ctx, GLenum opcode ) -{ - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - - if (ctx->Color.ColorLogicOpEnabled) - { - FLUSH_BATCH( fxMesa ); - - if (opcode == GL_COPY) - fxMesa->Fallback &= ~TDFX_FALLBACK_LOGICOP; - else - fxMesa->Fallback |= TDFX_FALLBACK_LOGICOP; - } - else - fxMesa->Fallback &= ~TDFX_FALLBACK_LOGICOP; -} - - -static GLboolean tdfxDDColorMask( GLcontext *ctx, - GLboolean r, GLboolean g, - GLboolean b, GLboolean a ) +static void tdfxDDColorMask( GLcontext *ctx, + GLboolean r, GLboolean g, + GLboolean b, GLboolean a ) { tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); @@ -803,48 +786,22 @@ static GLboolean tdfxDDColorMask( GLcontext *ctx, fxMesa->Color.ColorMask[ACOMP] = a; fxMesa->dirty |= TDFX_UPLOAD_COLOR_MASK; - if (ctx->Visual->RedBits < 8) { + if (ctx->Visual.redBits < 8) { /* Can't do RGB colormasking in 16bpp mode. */ /* We can completely ignore the alpha mask. */ - if (r != g || g != b) { - fxMesa->Fallback |= TDFX_FALLBACK_COLORMASK; - } - else { - fxMesa->Fallback &= ~TDFX_FALLBACK_COLORMASK; - } + FALLBACK( fxMesa, TDFX_FALLBACK_COLORMASK, (r != g || g != b) ); } } - - return GL_FALSE; /* This forces the software paths to do colormasking. */ - /* This function will return void when we use Mesa 3.5 */ } -static void tdfxDDColor( GLcontext *ctx, - GLubyte r, GLubyte g, GLubyte b, GLubyte a ) -{ - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - GrColor_t color; - - FLUSH_BATCH( fxMesa ); - - color = tdfxPackColor( fxMesa->fxScreen->cpp, r, g, b, a ); - - if ( fxMesa->Color.MonoColor != color ) { - fxMesa->Color.MonoColor = color; - fxMesa->dirty |= TDFX_UPLOAD_CONSTANT_COLOR; - } -} static void tdfxDDClearColor( GLcontext *ctx, - GLubyte red, GLubyte green, - GLubyte blue, GLubyte alpha ) + const GLchan color[4] ) { tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - FLUSH_BATCH( fxMesa ); - - fxMesa->Color.ClearColor = TDFXPACKCOLOR888( red, green, blue ); - fxMesa->Color.ClearAlpha = alpha; + fxMesa->Color.ClearColor = TDFXPACKCOLOR888( color[0], color[1], color[2] ); + fxMesa->Color.ClearAlpha = color[3]; } @@ -858,14 +815,9 @@ static void tdfxDDLightModelfv( GLcontext *ctx, GLenum pname, tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); if ( pname == GL_LIGHT_MODEL_COLOR_CONTROL ) { - FLUSH_BATCH( fxMesa ); - - fxMesa->Fallback &= ~TDFX_FALLBACK_SPECULAR; - - if ( ctx->Light.Enabled && - ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ) { - fxMesa->Fallback |= TDFX_FALLBACK_SPECULAR; - } + FALLBACK( fxMesa, TDFX_FALLBACK_SPECULAR, + (ctx->Light.Enabled && + ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR )); } } @@ -906,12 +858,20 @@ static void tdfxUpdateRenderAttrib( GLcontext *ctx ) * Viewport */ -static void tdfxUpdateViewport( GLcontext *ctx ) +void tdfxUpdateViewport( GLcontext *ctx ) { - /* XXX: Implement this when we're doing clip coordinates */ - if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) { - fprintf( stderr, "%s()\n", __FUNCTION__ ); - } + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + const GLfloat *v = ctx->Viewport._WindowMap.m; + GLfloat *m = fxMesa->hw_viewport; + + m[MAT_SX] = v[MAT_SX]; + m[MAT_TX] = v[MAT_TX] + fxMesa->x_offset + TRI_X_OFFSET; + m[MAT_SY] = v[MAT_SY]; + m[MAT_TY] = v[MAT_TY] + fxMesa->y_delta + TRI_Y_OFFSET; + m[MAT_SZ] = v[MAT_SZ]; + m[MAT_TZ] = v[MAT_TZ]; + + fxMesa->SetupNewInputs |= VERT_CLIP; } @@ -924,7 +884,7 @@ static void tdfxDDViewport( GLcontext *ctx, GLint x, GLint y, } -static void tdfxDDNearFar( GLcontext *ctx, GLfloat nearVal, GLfloat farVal ) +static void tdfxDDDepthRange( GLcontext *ctx, GLclampd nearVal, GLclampd farVal ) { tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); FLUSH_BATCH( fxMesa ); @@ -949,11 +909,9 @@ static void tdfxDDEnable( GLcontext *ctx, GLenum cap, GLboolean state ) case GL_BLEND: FLUSH_BATCH( fxMesa ); fxMesa->new_state |= TDFX_NEW_ALPHA; - - if (ctx->Color.ColorLogicOpEnabled && ctx->Color.LogicOp != GL_COPY) - fxMesa->Fallback |= TDFX_FALLBACK_LOGICOP; - else - fxMesa->Fallback &= ~TDFX_FALLBACK_LOGICOP; + FALLBACK( fxMesa, TDFX_FALLBACK_LOGICOP, + (ctx->Color.ColorLogicOpEnabled && + ctx->Color.LogicOp != GL_COPY)); break; case GL_CULL_FACE: @@ -982,12 +940,15 @@ static void tdfxDDEnable( GLcontext *ctx, GLenum cap, GLboolean state ) break; case GL_COLOR_LOGIC_OP: - FLUSH_BATCH( fxMesa ); - if ( state && ctx->Color.LogicOp != GL_COPY ) { - fxMesa->Fallback |= TDFX_FALLBACK_LOGICOP; - } else { - fxMesa->Fallback &= ~TDFX_FALLBACK_LOGICOP; - } + FALLBACK( fxMesa, TDFX_FALLBACK_LOGICOP, + (ctx->Color.ColorLogicOpEnabled && + ctx->Color.LogicOp != GL_COPY)); + break; + + case GL_LIGHTING: + FALLBACK( fxMesa, TDFX_FALLBACK_SPECULAR, + (ctx->Light.Enabled && + ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR )); break; case GL_LINE_SMOOTH: @@ -995,6 +956,10 @@ static void tdfxDDEnable( GLcontext *ctx, GLenum cap, GLboolean state ) fxMesa->new_state |= TDFX_NEW_LINE; break; + case GL_LINE_STIPPLE: + FALLBACK(fxMesa, TDFX_FALLBACK_LINE_STIPPLE, state); + break; + case GL_POLYGON_STIPPLE: FLUSH_BATCH(fxMesa); fxMesa->new_state |= TDFX_NEW_STIPPLE; @@ -1007,20 +972,13 @@ static void tdfxDDEnable( GLcontext *ctx, GLenum cap, GLboolean state ) case GL_STENCIL_TEST: FLUSH_BATCH( fxMesa ); - if (fxMesa->haveHwStencil) - fxMesa->new_state |= TDFX_NEW_STENCIL; - else if (state) - fxMesa->Fallback |= TDFX_FALLBACK_STENCIL; - else - fxMesa->Fallback &= ~TDFX_FALLBACK_STENCIL; + FALLBACK( fxMesa, TDFX_FALLBACK_STENCIL, state && !fxMesa->haveHwStencil); break; case GL_TEXTURE_1D: case GL_TEXTURE_3D: - if (state) - fxMesa->Fallback |= TDFX_FALLBACK_TEXTURE; - else - fxMesa->Fallback &= ~TDFX_FALLBACK_TEXTURE; + FLUSH_BATCH( fxMesa ); + FALLBACK( fxMesa, TDFX_FALLBACK_TEXTURE_1D_3D, state); /* wrong */ fxMesa->new_state |= TDFX_NEW_TEXTURE; break; @@ -1048,56 +1006,31 @@ static GLboolean tdfxDDSetDrawBuffer( GLcontext *ctx, GLenum mode ) FLUSH_BATCH( fxMesa ); - fxMesa->Fallback &= ~TDFX_FALLBACK_BUFFER; - - switch ( mode ) { + switch( mode) { case GL_FRONT_LEFT: fxMesa->DrawBuffer = GR_BUFFER_FRONTBUFFER; fxMesa->new_state |= TDFX_NEW_RENDER; + FALLBACK( fxMesa, TDFX_FALLBACK_DRAW_BUFFER, GL_FALSE ); return GL_TRUE; case GL_BACK_LEFT: fxMesa->DrawBuffer = GR_BUFFER_BACKBUFFER; fxMesa->new_state |= TDFX_NEW_RENDER; + FALLBACK( fxMesa, TDFX_FALLBACK_DRAW_BUFFER, GL_FALSE ); return GL_TRUE; case GL_NONE: FX_grColorMaskv( ctx, false4 ); + FALLBACK( fxMesa, TDFX_FALLBACK_DRAW_BUFFER, GL_FALSE ); return GL_TRUE; default: - fxMesa->Fallback |= TDFX_FALLBACK_BUFFER; + FALLBACK( fxMesa, TDFX_FALLBACK_DRAW_BUFFER, GL_TRUE ); return GL_FALSE; } } -/* Set the buffer used for reading */ -/* XXX support for separate read/draw buffers hasn't been tested */ -static void tdfxDDSetReadBuffer( GLcontext *ctx, - GLframebuffer *buffer, GLenum mode ) -{ - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - (void) buffer; - - FLUSH_BATCH( fxMesa ); - - fxMesa->Fallback &= ~TDFX_FALLBACK_BUFFER; - - switch ( mode ) { - case GL_FRONT_LEFT: - fxMesa->ReadBuffer = GR_BUFFER_FRONTBUFFER; - break; - - case GL_BACK_LEFT: - fxMesa->ReadBuffer = GR_BUFFER_BACKBUFFER; - break; - - default: - fxMesa->Fallback |= TDFX_FALLBACK_BUFFER; - break; - } -} /* ============================================================= * Polygon stipple @@ -1109,12 +1042,30 @@ static void tdfxDDPolygonStipple( GLcontext *ctx, const GLubyte *mask ) const GLubyte *m = mask; GLubyte q[4]; int i,j,k; - int active = (ctx->Polygon.StippleFlag && ctx->PB->primitive == GL_POLYGON); + GLboolean allBitsSet; + +/* int active = (ctx->Polygon.StippleFlag && */ +/* fxMesa->reduced_prim == GL_TRIANGLES); */ FLUSH_BATCH(fxMesa); + fxMesa->Stipple.Pattern = 0xffffffff; + fxMesa->dirty |= TDFX_UPLOAD_STIPPLE; + fxMesa->new_state |= TDFX_NEW_STIPPLE; - if (active) { - ctx->Driver.TriangleCaps |= DD_TRI_STIPPLE; + /* Check if the stipple pattern is fully opaque. If so, use software + * rendering. This basically a trick to make sure the OpenGL conformance + * test passes. + */ + allBitsSet = GL_TRUE; + for (i = 0; i < 32; i++) { + if (((GLuint *) mask)[i] != 0xffffffff) { + allBitsSet = GL_FALSE; + break; + } + } + if (allBitsSet) { + fxMesa->haveHwStipple = GL_FALSE; + return; } q[0] = mask[0]; @@ -1126,43 +1077,24 @@ static void tdfxDDPolygonStipple( GLcontext *ctx, const GLubyte *mask ) for (j = 0 ; j < 4; j++) for (i = 0 ; i < 4 ; i++,m++) { if (*m != q[j]) { - ctx->Driver.TriangleCaps &= ~DD_TRI_STIPPLE; - fxMesa->Stipple.Pattern = 0xffffffff; /* ensure all pixels on */ + fxMesa->haveHwStipple = GL_FALSE; return; } } - /* We can do it, so flag an upload of the stipple pattern */ + fxMesa->haveHwStipple = GL_TRUE; fxMesa->Stipple.Pattern = ( (q[0] << 0) | (q[1] << 8) | (q[2] << 16) | (q[3] << 24) ); - fxMesa->dirty |= TDFX_UPLOAD_STIPPLE; } -/* Always called between RenderStart and RenderFinish --> We already - * hold the lock. - */ -static void tdfxDDReducedPrimitiveChange( GLcontext *ctx, GLenum prim ) -{ - tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); - - FLUSH_BATCH( fxMesa ); - tdfxUpdateCull(ctx); - if ( fxMesa->dirty & TDFX_UPLOAD_CULL ) { - fxMesa->Glide.grCullMode( fxMesa->CullMode ); - fxMesa->dirty &= ~TDFX_UPLOAD_CULL; - } -#if defined(__linux__) || defined(__FreeBSD__) - tdfxUpdateStipple(ctx); - if ( fxMesa->dirty & TDFX_UPLOAD_STIPPLE ) { - fxMesa->Glide.grStipplePattern ( fxMesa->Stipple.Pattern ); - fxMesa->Glide.grStippleMode ( fxMesa->Stipple.Mode ); - fxMesa->dirty &= ~TDFX_UPLOAD_STIPPLE; - } -#endif /* __linux__ || __FreeBSD__ */ +static void tdfxDDRenderMode( GLcontext *ctx, GLenum mode ) +{ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + FALLBACK( fxMesa, TDFX_FALLBACK_RENDER_MODE, (mode != GL_RENDER) ); } @@ -1266,65 +1198,13 @@ void tdfxDDUpdateHwState( GLcontext *ctx ) } -static void tdfxDDRenderStart( GLcontext *ctx ) -{ - tdfxDDUpdateHwState( ctx ); - LOCK_HARDWARE( TDFX_CONTEXT(ctx) ); -} - -static void tdfxDDRenderFinish( GLcontext *ctx ) -{ - UNLOCK_HARDWARE( TDFX_CONTEXT(ctx) ); -} - -#define INTERESTED (~(NEW_MODELVIEW | \ - NEW_PROJECTION | \ - NEW_TEXTURE_MATRIX | \ - NEW_USER_CLIP | \ - NEW_CLIENT_STATE | \ - NEW_TEXTURE_ENABLE)) - -static void tdfxDDUpdateState( GLcontext *ctx ) +static void tdfxDDInvalidateState( GLcontext *ctx, GLuint new_state ) { - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - - if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) { - fprintf( stderr, "%s()\n", __FUNCTION__ ); - } - - /* Have to do this here to detect texture, line fallbacks in time: - */ - if ( fxMesa->new_state & (TDFX_NEW_TEXTURE | TDFX_NEW_LINE) ) - tdfxDDUpdateHwState( ctx ); - - if ( ctx->NewState & INTERESTED ) { - tdfxDDChooseRenderState( ctx ); - } - - /* The choise of vertex setup function only depends on whether fog - * and/or texturing is enabled. - */ - if ( ctx->NewState & (NEW_FOG | NEW_TEXTURE_ENABLE | NEW_TEXTURING)) { - tdfxDDChooseRasterSetupFunc( ctx ); - } - - if ( 0 ) - fprintf( stderr, "fallback %x indirect %x\n", - fxMesa->Fallback, fxMesa->IndirectTriangles ); - - if ( fxMesa->Fallback ) { - ctx->IndirectTriangles |= ctx->TriangleCaps; - } - else { - ctx->IndirectTriangles &= ~DD_SW_RASTERIZE; - ctx->IndirectTriangles |= fxMesa->IndirectTriangles; - - ctx->Driver.PointsFunc = fxMesa->PointsFunc; - ctx->Driver.LineFunc = fxMesa->LineFunc; - ctx->Driver.TriangleFunc = fxMesa->TriangleFunc; - ctx->Driver.QuadFunc = fxMesa->QuadFunc; - ctx->Driver.RenderVBRawTab = fxMesa->RenderVBRawTab; - } + _swrast_InvalidateState( ctx, new_state ); + _swsetup_InvalidateState( ctx, new_state ); + _ac_InvalidateState( ctx, new_state ); + _tnl_InvalidateState( ctx, new_state ); + TDFX_CONTEXT(ctx)->new_gl_state |= new_state; } @@ -1405,7 +1285,7 @@ void tdfxInitState( tdfxContextPtr fxMesa ) fxMesa->TexState.Enabled = 0; } - if ( ctx->Visual->DBflag) { + if ( ctx->Visual.doubleBufferMode) { fxMesa->DrawBuffer = GR_BUFFER_BACKBUFFER; fxMesa->ReadBuffer = GR_BUFFER_BACKBUFFER; } else { @@ -1430,7 +1310,7 @@ void tdfxInitState( tdfxContextPtr fxMesa ) fxMesa->Color.Dither = GR_DITHER_2x2; - if ( fxMesa->glVis->DepthBits > 0 ) { + if ( fxMesa->glCtx->Visual.depthBits > 0 ) { fxMesa->Depth.Mode = GR_DEPTHBUFFER_ZBUFFER; } else { fxMesa->Depth.Mode = GR_DEPTHBUFFER_DISABLE; @@ -1486,31 +1366,18 @@ void tdfxDDInitStateFuncs( GLcontext *ctx ) { tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - ctx->Driver.UpdateState = tdfxDDUpdateState; + ctx->Driver.UpdateState = tdfxDDInvalidateState; + + /* State notification callbacks: + */ ctx->Driver.ClearIndex = NULL; ctx->Driver.ClearColor = tdfxDDClearColor; - ctx->Driver.Index = NULL; - ctx->Driver.Color = tdfxDDColor; ctx->Driver.SetDrawBuffer = tdfxDDSetDrawBuffer; - ctx->Driver.SetReadBuffer = tdfxDDSetReadBuffer; ctx->Driver.IndexMask = NULL; ctx->Driver.ColorMask = tdfxDDColorMask; - ctx->Driver.NearFar = tdfxDDNearFar; - - ctx->Driver.RenderStart = tdfxDDRenderStart; - ctx->Driver.RenderFinish = tdfxDDRenderFinish; - ctx->Driver.RasterSetup = NULL; - - ctx->Driver.RenderVBClippedTab = NULL; - ctx->Driver.RenderVBCulledTab = NULL; - ctx->Driver.RenderVBRawTab = NULL; - - ctx->Driver.ReducedPrimitiveChange = tdfxDDReducedPrimitiveChange; - ctx->Driver.MultipassFunc = NULL; - ctx->Driver.AlphaFunc = tdfxDDAlphaFunc; ctx->Driver.BlendEquation = tdfxDDBlendEquation; ctx->Driver.BlendFunc = tdfxDDBlendFunc; @@ -1521,7 +1388,7 @@ void tdfxDDInitStateFuncs( GLcontext *ctx ) ctx->Driver.FrontFace = tdfxDDFrontFace; ctx->Driver.DepthFunc = tdfxDDDepthFunc; ctx->Driver.DepthMask = tdfxDDDepthMask; - ctx->Driver.DepthRange = NULL; + ctx->Driver.DepthRange = tdfxDDDepthRange; ctx->Driver.Enable = tdfxDDEnable; ctx->Driver.Fogfv = tdfxDDFogfv; ctx->Driver.Hint = NULL; @@ -1529,14 +1396,37 @@ void tdfxDDInitStateFuncs( GLcontext *ctx ) ctx->Driver.LightModelfv = tdfxDDLightModelfv; ctx->Driver.LineStipple = NULL; ctx->Driver.LineWidth = tdfxDDLineWidth; - ctx->Driver.LogicOpcode = tdfxDDLogicOp; -#if 0 - ctx->Driver.PolygonMode = NULL; -#endif ctx->Driver.PolygonStipple = tdfxDDPolygonStipple; + ctx->Driver.RenderMode = tdfxDDRenderMode; ctx->Driver.Scissor = tdfxDDScissor; ctx->Driver.ShadeModel = tdfxDDShadeModel; + ctx->Driver.BindTexture = tdfxDDBindTexture; + ctx->Driver.DeleteTexture = tdfxDDDeleteTexture; + ctx->Driver.TexEnv = tdfxDDTexEnv; + ctx->Driver.TexParameter = tdfxDDTexParameter; + ctx->Driver.ChooseTextureFormat = tdfxDDChooseTextureFormat; + ctx->Driver.TexImage2D = tdfxDDTexImage2D; + ctx->Driver.TexSubImage2D = tdfxDDTexSubImage2D; + /* + ctx->Driver.TexImage2D = _mesa_store_teximage2d; + ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d; + */ + + ctx->Driver.TexImage1D = _mesa_store_teximage1d; + ctx->Driver.TexImage3D = _mesa_store_teximage3d; + ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d; + ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d; + ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d; + ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d; + ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d; + ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d; + ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d; + ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage; + +/* ctx->Driver.GetTexImage = tdfxDDGetTexImage; */ + ctx->Driver.UpdateTexturePalette = tdfxDDTexturePalette; + if ( fxMesa->haveHwStencil ) { ctx->Driver.StencilFunc = tdfxDDStencilFunc; ctx->Driver.StencilMask = tdfxDDStencilMask; @@ -1548,4 +1438,12 @@ void tdfxDDInitStateFuncs( GLcontext *ctx ) } ctx->Driver.Viewport = tdfxDDViewport; + + + /* Swrast hooks for imaging extensions: + */ + ctx->Driver.CopyColorTable = _swrast_CopyColorTable; + ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable; + ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; + ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; } diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.h b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.h index d2ad058d2..e4fdcb44f 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.h +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.h @@ -51,5 +51,14 @@ extern void tdfxInitState( tdfxContextPtr fxMesa ); extern void tdfxUpdateClipping( GLcontext *ctx ); + +extern void tdfxFallback( GLcontext *ctx, GLuint bit, GLboolean mode ); +#define FALLBACK( rmesa, bit, mode ) tdfxFallback( rmesa->glCtx, bit, mode ) + +extern void tdfxUpdateCull( GLcontext *ctx ); +extern void tdfxUpdateStipple( GLcontext *ctx ); +extern void tdfxUpdateViewport( GLcontext *ctx ); + + #endif #endif diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.c index 3b9a40d3f..e204498ea 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.c @@ -23,7 +23,7 @@ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.c,v 1.3 2001/08/18 02:51:07 dawes Exp $ */ +/* $XFree86$ */ /* * Original rewrite: @@ -35,37 +35,42 @@ * */ +#include "image.h" +#include "texutil.h" +#include "texformat.h" +#include "teximage.h" +#include "texstore.h" #include "tdfx_context.h" #include "tdfx_tex.h" #include "tdfx_texman.h" -#include "enums.h" -#include "image.h" -#include "texutil.h" - -#define TX_DITHER_NONE 0x00000000 -static int logbase2( int n ) +static int +logbase2(int n) { - GLint i = 1; - GLint log2 = 0; - - if ( n < 0 ) - return -1; - - while ( n > i ) { - i *= 2; - log2++; - } - if ( i != n ) { - return -1; - } else { - return log2; - } + GLint i = 1; + GLint log2 = 0; + + if (n < 0) { + return -1; + } + + while (n > i) { + i *= 2; + log2++; + } + if (i != n) { + return -1; + } + else { + return log2; + } } -/* Compute various texture image parameters. + +/* + * Compute various texture image parameters. * Input: w, h - source texture width and height * Output: lodlevel - Glide lod level token for the larger texture dimension * aspectratio - Glide aspect ratio token @@ -82,282 +87,524 @@ static int logbase2( int n ) * 32 64 GR_LOD_LOG2_64 (=6) GR_ASPECT_LOG2_1x2 (=-1) * 32 32 GR_LOD_LOG2_32 (=5) GR_ASPECT_LOG2_1x1 (=0) */ -static void tdfxTexGetInfo( const GLcontext *ctx, int w, int h, - GrLOD_t *lodlevel, GrAspectRatio_t *aspectratio, - float *sscale, float *tscale, - int *wscale, int *hscale ) +static void +tdfxTexGetInfo(const GLcontext *ctx, int w, int h, + GrLOD_t *lodlevel, GrAspectRatio_t *aspectratio, + float *sscale, float *tscale, + int *wscale, int *hscale) { - int logw, logh, ar, lod, ws, hs; - float s, t; + int logw, logh, ar, lod, ws, hs; + float s, t; + + ASSERT(w >= 1); + ASSERT(h >= 1); + + logw = logbase2(w); + logh = logbase2(h); + ar = logw - logh; /* aspect ratio = difference in log dimensions */ + + /* Hardware only allows a maximum aspect ratio of 8x1, so handle + |ar| > 3 by scaling the image and using an 8x1 aspect ratio */ + if (ar >= 0) { + ASSERT(width >= height); + lod = logw; + s = 256.0; + ws = 1; + if (ar <= GR_ASPECT_LOG2_8x1) { + t = 256 >> ar; + hs = 1; + } + else { + /* have to stretch image height */ + t = 32.0; + hs = 1 << (ar - 3); + } + } + else { + ASSERT(width < height); + lod = logh; + t = 256.0; + hs = 1; + if (ar >= GR_ASPECT_LOG2_1x8) { + s = 256 >> -ar; + ws = 1; + } + else { + /* have to stretch image width */ + s = 32.0; + ws = 1 << (-ar - 3); + } + } + + if (ar < GR_ASPECT_LOG2_1x8) + ar = GR_ASPECT_LOG2_1x8; + else if (ar > GR_ASPECT_LOG2_8x1) + ar = GR_ASPECT_LOG2_8x1; + + if (lodlevel) + *lodlevel = (GrLOD_t) lod; + if (aspectratio) + *aspectratio = (GrAspectRatio_t) ar; + if (sscale) + *sscale = s; + if (tscale) + *tscale = t; + if (wscale) + *wscale = ws; + if (hscale) + *hscale = hs; +} - ASSERT( w >= 1 ); - ASSERT( h >= 1 ); - logw = logbase2( w ); - logh = logbase2( h ); - ar = logw - logh; /* aspect ratio = difference in log dimensions */ +/* + * We need to call this when a texture object's minification filter + * or texture image sizes change. + */ +static void RevalidateTexture(GLcontext *ctx, struct gl_texture_object *tObj) +{ + tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj); + GLint minl, maxl; + + if (!ti) + return; + + minl = maxl = tObj->BaseLevel; + + if (tObj->Image[minl]) { + maxl = MIN2(tObj->MaxLevel, tObj->Image[minl]->MaxLog2); + + /* compute largeLodLog2, aspect ratio and texcoord scale factors */ + tdfxTexGetInfo(ctx, tObj->Image[minl]->Width, tObj->Image[minl]->Height, + &ti->info.largeLodLog2, + &ti->info.aspectRatioLog2, + &(ti->sScale), &(ti->tScale), NULL, NULL); + } + + if (tObj->Image[maxl] && (tObj->MinFilter != GL_NEAREST) && (tObj->MinFilter != GL_LINEAR)) { + /* mipmapping: need to compute smallLodLog2 */ + tdfxTexGetInfo(ctx, tObj->Image[maxl]->Width, + tObj->Image[maxl]->Height, + &ti->info.smallLodLog2, NULL, + NULL, NULL, NULL, NULL); + } + else { + /* not mipmapping: smallLodLog2 = largeLodLog2 */ + ti->info.smallLodLog2 = ti->info.largeLodLog2; + maxl = minl; + } + + ti->minLevel = minl; + ti->maxLevel = maxl; + ti->info.data = NULL; +} - /* Hardware only allows a maximum aspect ratio of 8x1, so handle - * |ar| > 3 by scaling the image and using an 8x1 aspect ratio. - */ - if ( ar >= 0 ) { - ASSERT( w >= h ); - lod = logw; - s = 256.0; - ws = 1; - if ( ar <= GR_ASPECT_LOG2_8x1 ) { - t = 256 >> ar; - hs = 1; - } else { - /* have to stretch image height */ - t = 32.0; - hs = 1 << (ar - 3); - } - } else { - ASSERT( w < h ); - lod = logh; - t = 256.0; - hs = 1; - if ( ar >= GR_ASPECT_LOG2_1x8 ) { - s = 256 >> -ar; - ws = 1; - } else { - /* have to stretch image width */ - s = 32.0; - ws = 1 << (-ar - 3); - } - } - if ( ar < GR_ASPECT_LOG2_1x8 ) { - ar = GR_ASPECT_LOG2_1x8; - } else if ( ar > GR_ASPECT_LOG2_8x1 ) { - ar = GR_ASPECT_LOG2_8x1; - } +static tdfxTexInfo * +fxAllocTexObjData(tdfxContextPtr fxMesa) +{ + tdfxTexInfo *ti; + + if (!(ti = CALLOC(sizeof(tdfxTexInfo)))) { + _mesa_problem(NULL, "tdfx driver: out of memory"); + return NULL; + } + + ti->isInTM = GL_FALSE; + + ti->whichTMU = TDFX_TMU_NONE; + + ti->tm[TDFX_TMU0] = NULL; + ti->tm[TDFX_TMU1] = NULL; + + ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED; + ti->magFilt = GR_TEXTUREFILTER_BILINEAR; + + ti->sClamp = GR_TEXTURECLAMP_WRAP; + ti->tClamp = GR_TEXTURECLAMP_WRAP; - if ( lodlevel ) - *lodlevel = (GrLOD_t)lod; - if ( aspectratio ) - *aspectratio = (GrAspectRatio_t)ar; - if ( sscale ) - *sscale = s; - if ( tscale ) - *tscale = t; - if ( wscale ) - *wscale = ws; - if ( hscale ) - *hscale = hs; + ti->mmMode = GR_MIPMAP_NEAREST; + ti->LODblend = FXFALSE; + + return ti; } -/* We need to call this when a texture object's minification filter - * or texture image sizes change. +/* + * Called via glBindTexture. */ -static void tdfxRevalidateTexture( GLcontext *ctx, - struct gl_texture_object *tObj ) -{ - tdfxTexObjPtr t = TDFX_TEXTURE_DATA(tObj); - GLint minl, maxl; - if ( !t ) - return; +void +tdfxDDBindTexture(GLcontext * ctx, GLenum target, + struct gl_texture_object *tObj) +{ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + tdfxTexInfo *ti; - minl = maxl = tObj->BaseLevel; + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxDDTexBind(%d,%p)\n", tObj->Name, + tObj->DriverData); + } - if ( tObj->Image[minl] ) { - maxl = MIN2( tObj->MaxLevel, tObj->Image[minl]->MaxLog2 ); + if (target != GL_TEXTURE_2D) + return; - /* Compute largeLodLog2, aspect ratio and texcoord scale factors. - */ - tdfxTexGetInfo( ctx, - tObj->Image[minl]->Width, tObj->Image[minl]->Height, - &t->info.largeLodLog2, &t->info.aspectRatioLog2, - &t->sScale, &t->tScale, NULL, NULL ); - } + if (!tObj->DriverData) { + tObj->DriverData = fxAllocTexObjData(fxMesa); + } - if ( tObj->Image[maxl] && - tObj->MinFilter != GL_NEAREST && - tObj->MinFilter != GL_LINEAR ) { - /* Mipmapping: need to compute smallLodLog2 */ - tdfxTexGetInfo( ctx, - tObj->Image[maxl]->Width, tObj->Image[maxl]->Height, - &t->info.smallLodLog2, - NULL, NULL, NULL, NULL, NULL ); - } else { - /* Not mipmapping: smallLodLog2 = largeLodLog2 */ - t->info.smallLodLog2 = t->info.largeLodLog2; - } + ti = TDFX_TEXTURE_DATA(tObj); + ti->lastTimeUsed = fxMesa->texBindNumber++; - t->minLevel = minl; - t->maxLevel = maxl; - t->info.data = NULL; + fxMesa->new_state |= TDFX_NEW_TEXTURE; } -static tdfxTexObjPtr tdfxAllocTexObj( tdfxContextPtr fxMesa ) +/* + * Called via glTexEnv. + */ +void +tdfxDDTexEnv(GLcontext * ctx, GLenum target, GLenum pname, + const GLfloat * param) { - tdfxTexObjPtr t; - int i; + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + + if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) { + if (param) + fprintf(stderr, "fxmesa: texenv(%x,%x)\n", pname, + (GLint) (*param)); + else + fprintf(stderr, "fxmesa: texenv(%x)\n", pname); + } + + /* XXX this is a bit of a hack to force the Glide texture + * state to be updated. + */ + fxMesa->TexState.EnvMode[ctx->Texture.CurrentUnit] = 0; + + fxMesa->new_state |= TDFX_NEW_TEXTURE; +} - t = CALLOC( sizeof(tdfxTexObj) ); - if ( !t ) { - gl_problem( NULL, "tdfx driver: out of memory" ); - return NULL; - } - t->isInTM = GL_FALSE; +/* + * Called via glTexParameter. + */ +void +tdfxDDTexParameter(GLcontext * ctx, GLenum target, + struct gl_texture_object *tObj, + GLenum pname, const GLfloat * params) +{ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + GLenum param = (GLenum) (GLint) params[0]; + tdfxTexInfo *ti; + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxDDTexParam(%d,%p,%x,%x)\n", tObj->Name, + tObj->DriverData, pname, param); + } + + if (target != GL_TEXTURE_2D) + return; + + if (!tObj->DriverData) + tObj->DriverData = fxAllocTexObjData(fxMesa); + + ti = TDFX_TEXTURE_DATA(tObj); + + switch (pname) { + case GL_TEXTURE_MIN_FILTER: + switch (param) { + case GL_NEAREST: + ti->mmMode = GR_MIPMAP_DISABLE; + ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED; + ti->LODblend = FXFALSE; + break; + case GL_LINEAR: + ti->mmMode = GR_MIPMAP_DISABLE; + ti->minFilt = GR_TEXTUREFILTER_BILINEAR; + ti->LODblend = FXFALSE; + break; + case GL_NEAREST_MIPMAP_LINEAR: + if (TDFX_IS_NAPALM(fxMesa)) { + if (fxMesa->haveTwoTMUs) { + ti->mmMode = GR_MIPMAP_NEAREST; + ti->LODblend = FXTRUE; + } + else { + ti->mmMode = GR_MIPMAP_NEAREST_DITHER; + ti->LODblend = FXFALSE; + } + ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED; + break; + } + /* XXX Voodoo3/Banshee mipmap blending seems to produce + * incorrectly filtered colors for the smallest mipmap levels. + * To work-around we fall-through here and use a different filter. + */ + case GL_NEAREST_MIPMAP_NEAREST: + ti->mmMode = GR_MIPMAP_NEAREST; + ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED; + ti->LODblend = FXFALSE; + break; + case GL_LINEAR_MIPMAP_LINEAR: + if (TDFX_IS_NAPALM(fxMesa)) { + if (fxMesa->haveTwoTMUs) { + ti->mmMode = GR_MIPMAP_NEAREST; + ti->LODblend = FXTRUE; + } + else { + ti->mmMode = GR_MIPMAP_NEAREST_DITHER; + ti->LODblend = FXFALSE; + } + ti->minFilt = GR_TEXTUREFILTER_BILINEAR; + break; + } + /* XXX Voodoo3/Banshee mipmap blending seems to produce + * incorrectly filtered colors for the smallest mipmap levels. + * To work-around we fall-through here and use a different filter. + */ + case GL_LINEAR_MIPMAP_NEAREST: + ti->mmMode = GR_MIPMAP_NEAREST; + ti->minFilt = GR_TEXTUREFILTER_BILINEAR; + ti->LODblend = FXFALSE; + break; + default: + break; + } + RevalidateTexture(ctx, tObj); + fxMesa->new_state |= TDFX_NEW_TEXTURE; + break; + + case GL_TEXTURE_MAG_FILTER: + switch (param) { + case GL_NEAREST: + ti->magFilt = GR_TEXTUREFILTER_POINT_SAMPLED; + break; + case GL_LINEAR: + ti->magFilt = GR_TEXTUREFILTER_BILINEAR; + break; + default: + break; + } + fxMesa->new_state |= TDFX_NEW_TEXTURE; + break; + + case GL_TEXTURE_WRAP_S: + switch (param) { + case GL_CLAMP: + ti->sClamp = GR_TEXTURECLAMP_CLAMP; + break; + case GL_REPEAT: + ti->sClamp = GR_TEXTURECLAMP_WRAP; + break; + default: + break; + } + fxMesa->new_state |= TDFX_NEW_TEXTURE; + break; + + case GL_TEXTURE_WRAP_T: + switch (param) { + case GL_CLAMP: + ti->tClamp = GR_TEXTURECLAMP_CLAMP; + break; + case GL_REPEAT: + ti->tClamp = GR_TEXTURECLAMP_WRAP; + break; + default: + break; + } + fxMesa->new_state |= TDFX_NEW_TEXTURE; + break; + + case GL_TEXTURE_BORDER_COLOR: + /* TO DO */ + break; + case GL_TEXTURE_MIN_LOD: + /* TO DO */ + break; + case GL_TEXTURE_MAX_LOD: + /* TO DO */ + break; + case GL_TEXTURE_BASE_LEVEL: + RevalidateTexture(ctx, tObj); + break; + case GL_TEXTURE_MAX_LEVEL: + RevalidateTexture(ctx, tObj); + break; + + default: + break; + } +} - t->whichTMU = TDFX_TMU_NONE; - t->range[TDFX_TMU0] = NULL; - t->range[TDFX_TMU1] = NULL; +/* + * Called via glDeleteTextures to delete a texture object. + * Here, we delete the Glide data associated with the texture. + */ +void +tdfxDDDeleteTexture(GLcontext * ctx, struct gl_texture_object *tObj) +{ + if (ctx && ctx->DriverCtx) { + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + tdfxTMFreeTexture(fxMesa, tObj); + fxMesa->new_state |= TDFX_NEW_TEXTURE; + } +} - t->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED; - t->magFilt = GR_TEXTUREFILTER_BILINEAR; - t->sClamp = GR_TEXTURECLAMP_WRAP; - t->tClamp = GR_TEXTURECLAMP_WRAP; +/* + * Return true if texture is resident, false otherwise. + */ +GLboolean +tdfxDDIsTextureResident(GLcontext *ctx, struct gl_texture_object *tObj) +{ + tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj); + return (GLboolean) (ti && ti->isInTM); +} - t->mmMode = GR_MIPMAP_NEAREST; - t->LODblend = FXFALSE; - for ( i = 0 ; i < MAX_TEXTURE_LEVELS ; i++ ) { - t->image[i].original.data = NULL; - t->image[i].rescaled.data = NULL; - } - return t; +/* + * Convert a gl_color_table texture palette to Glide's format. + */ +static void +convertPalette(FxU32 data[256], const struct gl_color_table *table) +{ + const GLubyte *tableUB = (const GLubyte *) table->Table; + GLint width = table->Size; + FxU32 r, g, b, a; + GLint i; + + ASSERT(table->TableType == GL_UNSIGNED_BYTE); + + switch (table->Format) { + case GL_INTENSITY: + for (i = 0; i < width; i++) { + r = tableUB[i]; + g = tableUB[i]; + b = tableUB[i]; + a = tableUB[i]; + data[i] = (a << 24) | (r << 16) | (g << 8) | b; + } + break; + case GL_LUMINANCE: + for (i = 0; i < width; i++) { + r = tableUB[i]; + g = tableUB[i]; + b = tableUB[i]; + a = 255; + data[i] = (a << 24) | (r << 16) | (g << 8) | b; + } + break; + case GL_ALPHA: + for (i = 0; i < width; i++) { + r = g = b = 255; + a = tableUB[i]; + data[i] = (a << 24) | (r << 16) | (g << 8) | b; + } + break; + case GL_LUMINANCE_ALPHA: + for (i = 0; i < width; i++) { + r = g = b = tableUB[i * 2 + 0]; + a = tableUB[i * 2 + 1]; + data[i] = (a << 24) | (r << 16) | (g << 8) | b; + } + break; + case GL_RGB: + for (i = 0; i < width; i++) { + r = tableUB[i * 3 + 0]; + g = tableUB[i * 3 + 1]; + b = tableUB[i * 3 + 2]; + a = 255; + data[i] = (a << 24) | (r << 16) | (g << 8) | b; + } + break; + case GL_RGBA: + for (i = 0; i < width; i++) { + r = tableUB[i * 4 + 0]; + g = tableUB[i * 4 + 1]; + b = tableUB[i * 4 + 2]; + a = tableUB[i * 4 + 3]; + data[i] = (a << 24) | (r << 16) | (g << 8) | b; + } + break; + } } -/* Given an OpenGL internal texture format, return the corresponding - * Glide internal texture format and MesaIntTexFormat. - * If allow32bpp is true, we'll return 32-bit texel formats when - * appropriate. - */ -static GrTextureFormat_t -tdfxTexGetFormat( tdfxContextPtr fxMesa, struct gl_texture_image *texImage, - GLenum format, GLenum type ) + +void +tdfxDDTexturePalette(GLcontext * ctx, struct gl_texture_object *tObj) { - const GLboolean allow32bpp = TDFX_IS_NAPALM(fxMesa); - const GLboolean is32bpp = ( fxMesa->fxScreen->cpp == 4 ); - const struct gl_texture_format *texFormat; - GrTextureFormat_t ret; - - if ( 0 ) - fprintf( stderr, "internal=%s format=%s type=%s\n", - texImage->IntFormat == 3 ? "GL_RGB (3)" : - texImage->IntFormat == 4 ? "GL_RGBA (4)" : - gl_lookup_enum_by_nr( texImage->IntFormat ), - gl_lookup_enum_by_nr( format ), - gl_lookup_enum_by_nr( type ) ); - -#define SET_FORMAT( gr, gl ) \ - do { \ - ret = (gr); \ - texFormat = &(gl); \ - } while (0) - -#define SET_FORMAT_32BPP( gr32, gl32, gr16, gl16 ) \ - do { \ - if ( allow32bpp ) { \ - ret = (gr32); \ - texFormat = &(gl32); \ - } else { \ - ret = (gr16); \ - texFormat = &(gl16); \ - } \ - } while (0) - - switch ( texImage->IntFormat ) { - /* GH: Bias towards GL_RGB, GL_RGBA texture formats. This has - * got to be better than sticking them way down the end of this - * huge list. - */ - case GL_RGBA: - case 4: - if ( format == GL_BGRA ) { - if ( type == GL_UNSIGNED_INT_8_8_8_8_REV && allow32bpp ) { - SET_FORMAT( GR_TEXFMT_ARGB_8888, _mesa_texformat_argb8888 ); - break; - } else if ( type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) { - SET_FORMAT( GR_TEXFMT_ARGB_4444, _mesa_texformat_argb4444 ); - break; - } else if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) { - SET_FORMAT( GR_TEXFMT_ARGB_1555, _mesa_texformat_argb1555 ); - break; - } - } - if ( allow32bpp && is32bpp ) { - SET_FORMAT( GR_TEXFMT_ARGB_8888, _mesa_texformat_argb8888 ); - } else { - SET_FORMAT( GR_TEXFMT_ARGB_4444, _mesa_texformat_argb4444 ); - } - break; + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + + if (tObj) { + /* per-texture palette */ + tdfxTexInfo *ti; + + /* This might be a proxy texture. */ + if (!tObj->Palette.Table) + return; + + if (!tObj->DriverData) + tObj->DriverData = fxAllocTexObjData(fxMesa); + ti = TDFX_TEXTURE_DATA(tObj); + convertPalette(ti->palette.data, &tObj->Palette); + /*tdfxTexInvalidate(ctx, tObj);*/ + } + else { + /* global texture palette */ + convertPalette(fxMesa->glbPalette.data, &ctx->Texture.Palette); + } + fxMesa->new_state |= TDFX_NEW_TEXTURE; /* XXX too heavy-handed */ +} - case GL_RGB: - case 3: - if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) { - SET_FORMAT( GR_TEXFMT_RGB_565, _mesa_texformat_rgb565 ); - break; - } - if ( allow32bpp && is32bpp ) { - SET_FORMAT( GR_TEXFMT_ARGB_8888, _mesa_texformat_argb8888 ); - } else { - SET_FORMAT( GR_TEXFMT_RGB_565, _mesa_texformat_rgb565 ); - } - break; - /* GH: Okay, keep checking as normal. Still test for GL_RGB, - * GL_RGBA formats first. - */ - case GL_RGBA8: - case GL_RGB10_A2: - case GL_RGBA12: - case GL_RGBA16: - SET_FORMAT_32BPP( GR_TEXFMT_ARGB_8888, _mesa_texformat_argb8888, - GR_TEXFMT_ARGB_4444, _mesa_texformat_argb4444 ); - break; +/**********************************************************************/ +/**** NEW TEXTURE IMAGE FUNCTIONS ****/ +/**********************************************************************/ - case GL_RGBA4: - case GL_RGBA2: - SET_FORMAT( GR_TEXFMT_ARGB_4444, _mesa_texformat_argb4444 ); - break; +static FxBool TexusFatalError = FXFALSE; +static FxBool TexusError = FXFALSE; - case GL_RGB5_A1: - SET_FORMAT( GR_TEXFMT_ARGB_1555, _mesa_texformat_argb1555 ); - break; +#define TX_DITHER_NONE 0x00000000 - case GL_RGB8: - case GL_RGB10: - case GL_RGB12: - case GL_RGB16: - SET_FORMAT_32BPP( GR_TEXFMT_ARGB_8888, _mesa_texformat_argb8888, - GR_TEXFMT_RGB_565, _mesa_texformat_rgb565 ); - break; +#if 000 +static void +fxTexusError(const char *string, FxBool fatal) +{ + _mesa_problem(NULL, string); + /* + * Just propagate the fatal value up. + */ + TexusError = FXTRUE; + TexusFatalError = fatal; +} +#endif - case GL_RGB5: - case GL_RGB4: - case GL_R3_G3_B2: - SET_FORMAT( GR_TEXFMT_RGB_565, _mesa_texformat_rgb565 ); - break; +const struct gl_texture_format * +tdfxDDChooseTextureFormat( GLcontext *ctx, GLint internalFormat, + GLenum srcFormat, GLenum srcType ) +{ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + const GLboolean allow32bpt = TDFX_IS_NAPALM(fxMesa); + + switch (internalFormat) { case GL_ALPHA: case GL_ALPHA4: case GL_ALPHA8: case GL_ALPHA12: case GL_ALPHA16: - SET_FORMAT( GR_TEXFMT_ALPHA_8, _mesa_texformat_a8 ); - break; - + return &_mesa_texformat_a8; case 1: case GL_LUMINANCE: case GL_LUMINANCE4: case GL_LUMINANCE8: case GL_LUMINANCE12: case GL_LUMINANCE16: - SET_FORMAT( GR_TEXFMT_INTENSITY_8, _mesa_texformat_l8 ); - break; - + return &_mesa_texformat_l8; case 2: case GL_LUMINANCE_ALPHA: case GL_LUMINANCE4_ALPHA4: @@ -366,17 +613,39 @@ tdfxTexGetFormat( tdfxContextPtr fxMesa, struct gl_texture_image *texImage, case GL_LUMINANCE12_ALPHA4: case GL_LUMINANCE12_ALPHA12: case GL_LUMINANCE16_ALPHA16: - SET_FORMAT( GR_TEXFMT_ALPHA_INTENSITY_88, _mesa_texformat_al88 ); - break; - + return &_mesa_texformat_al88; case GL_INTENSITY: case GL_INTENSITY4: case GL_INTENSITY8: case GL_INTENSITY12: case GL_INTENSITY16: - SET_FORMAT( GR_TEXFMT_ALPHA_8, _mesa_texformat_i8 ); + return &_mesa_texformat_i8; + case GL_R3_G3_B2: + case GL_RGB4: + case GL_RGB5: + return &_mesa_texformat_rgb565; + case 3: + case GL_RGB: + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + return (allow32bpt) ? &_mesa_texformat_argb8888 + : &_mesa_texformat_rgb565; break; - + case GL_RGBA2: + case GL_RGBA4: + return &_mesa_texformat_argb4444; + case 4: + case GL_RGBA: + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + return allow32bpt ? &_mesa_texformat_argb8888 + : &_mesa_texformat_argb4444; + case GL_RGB5_A1: + return &_mesa_texformat_argb1555; case GL_COLOR_INDEX: case GL_COLOR_INDEX1_EXT: case GL_COLOR_INDEX2_EXT: @@ -384,677 +653,821 @@ tdfxTexGetFormat( tdfxContextPtr fxMesa, struct gl_texture_image *texImage, case GL_COLOR_INDEX8_EXT: case GL_COLOR_INDEX12_EXT: case GL_COLOR_INDEX16_EXT: - SET_FORMAT( GR_TEXFMT_P_8, _mesa_texformat_ci8 ); - break; - + return &_mesa_texformat_ci8; default: - fprintf( stderr, "bad texture format in fxTexGetFormat() %d", - texImage->IntFormat ); - return -1; + _mesa_problem(ctx, "unexpected format in tdfxDDChooseTextureFormat"); + return NULL; } - - texImage->TexFormat = texFormat; - - return ret; } -static GLboolean -tdfxDDTexImage2D( GLcontext *ctx, GLenum target, GLint level, - GLenum format, GLenum type, const GLvoid *pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage, - GLboolean *retainInternalCopy ) +/* + * Return the Glide format for the given mesa texture format. + */ +static GrTextureFormat_t +fxGlideFormat(GLint mesaFormat) { - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - const struct gl_texture_format *texFormat; - GrTextureFormat_t glideFormat; - tdfxTexObjPtr t; - tdfxTexImagePtr image; - GLint dstWidth, dstHeight, wScale, hScale; - GLint size; - void *data; - - if ( 0 ) { - printf("TexImage id=%d int 0x%x format 0x%x type 0x%x %dx%d\n", - texObj->Name, texImage->IntFormat, format, type, - texImage->Width, texImage->Height); - } - - if ( target != GL_TEXTURE_2D || texImage->Border > 0 ) - return GL_FALSE; - - if ( !texObj->DriverData ) - texObj->DriverData = tdfxAllocTexObj( fxMesa ); - - t = TDFX_TEXTURE_DATA(texObj); - image = &t->image[level]; - - /* Determine the appropriate GL internal texel format, Mesa internal - * texel format, and texelSize (bytes) given the user's internal - * texture format hint. - */ - glideFormat = tdfxTexGetFormat( fxMesa, texImage, format, type ); - - /* Get the destination internal format. - */ - texFormat = texImage->TexFormat; - - /* Determine width and height scale factors for texture. Remember, - * Glide is limited to 8:1 aspect ratios. - */ - tdfxTexGetInfo( ctx, - texImage->Width, texImage->Height, - NULL, NULL, NULL, NULL, - &wScale, &hScale ); - dstWidth = texImage->Width * wScale; - dstHeight = texImage->Height * hScale; - - /* Allocate new storage for texture image, if needed. This - * conditional wants to set uncompressedImage to point to the - * uncompressed image, and mml->data to the texture data. If the - * image is uncompressed, these are identical. If the image is not - * compressed, these are different. - */ - if ( !image->original.data || image->glideFormat != glideFormat || - image->original.width != texImage->Width || - image->original.height != texImage->Height ) - { - if ( image->original.data ) { - FREE( image->original.data ); - image->original.data = NULL; - } - if ( image->rescaled.data ) { - FREE( image->rescaled.data ); - image->rescaled.data = NULL; - } - - size = texImage->Width * texImage->Height * texFormat->TexelBytes; - image->original.data = (void *) MALLOC( size ); - if ( !image->original.data ) - return GL_FALSE; - - image->original.width = texImage->Width; - image->original.height = texImage->Height; - image->original.size = size; - - image->glideFormat = glideFormat; - image->wScale = wScale; - image->hScale = hScale; - - t->info.format = glideFormat; - tdfxTMMoveOutTM( fxMesa, texObj ); - } - - /* Store the texture image into the 'original' space. - */ - if ( !_mesa_convert_texsubimage2d( texFormat->IntFormat, - 0, 0, texImage->Width, - texImage->Height, texImage->Width, - format, type, packing, pixels, - image->original.data ) ) { - return GL_FALSE; - } - - data = image->original.data; - size = image->original.size; - - /* GH: Sigh... - */ - if ( wScale > 1 || hScale > 1 ) { - if ( image->rescaled.data ) { - FREE( image->rescaled.data ); - image->rescaled.data = NULL; - } - - size = dstWidth * dstHeight * texFormat->TexelBytes; - image->rescaled.data = (void *) MALLOC( size ); - if ( !image->rescaled.data ) - return GL_FALSE; - - image->rescaled.width = dstWidth; - image->rescaled.height = dstHeight; - image->rescaled.size = size; - - _mesa_rescale_teximage2d( texFormat->TexelBytes, - texImage->Width, texImage->Height, - dstWidth, dstHeight, - image->original.data, image->rescaled.data ); - - data = image->rescaled.data; + switch (mesaFormat) { + case MESA_FORMAT_I8: + return GR_TEXFMT_ALPHA_8; + case MESA_FORMAT_A8: + return GR_TEXFMT_ALPHA_8; + case MESA_FORMAT_L8: + return GR_TEXFMT_INTENSITY_8; + case MESA_FORMAT_CI8: + return GR_TEXFMT_P_8; + case MESA_FORMAT_AL88: + return GR_TEXFMT_ALPHA_INTENSITY_88; + case MESA_FORMAT_RGB565: + return GR_TEXFMT_RGB_565; + case MESA_FORMAT_ARGB4444: + return GR_TEXFMT_ARGB_4444; + case MESA_FORMAT_ARGB1555: + return GR_TEXFMT_ARGB_1555; + case MESA_FORMAT_ARGB8888: + return GR_TEXFMT_ARGB_8888; + default: + _mesa_problem(NULL, "Unexpected format in fxGlideFormat"); + return 0; } +} - image->data = data; - image->size = size; - - tdfxRevalidateTexture( ctx, texObj ); - t->reloadImages = GL_TRUE; - fxMesa->new_state |= TDFX_NEW_TEXTURE; +/* Texel-fetch functions for software texturing and glGetTexImage(). + * We should have been able to use some "standard" fetch functions (which + * may get defined in texutil.c) but we have to account for scaled texture + * images on tdfx hardware (the 8:1 aspect ratio limit). + * Hence, we need special functions here. + */ - *retainInternalCopy = GL_FALSE; - return GL_TRUE; +static void +fetch_intensity8(const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLvoid * texelOut) +{ + GLchan *rgba = (GLchan *) texelOut; + const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage); + const GLubyte *texel; + + i = i * mml->wScale; + j = j * mml->hScale; + + texel = ((GLubyte *) texImage->Data) + j * mml->width + i; + rgba[RCOMP] = *texel; + rgba[GCOMP] = *texel; + rgba[BCOMP] = *texel; + rgba[ACOMP] = *texel; } -static GLboolean -tdfxDDTexSubImage2D( GLcontext *ctx, GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLenum format, GLenum type, const GLvoid *pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage ) +static void +fetch_luminance8(const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLvoid * texelOut) { - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - tdfxTexObjPtr t = TDFX_TEXTURE_DATA(texObj); - tdfxTexImagePtr image; - - if ( target != GL_TEXTURE_2D ) - return GL_FALSE; - - if ( !t ) - return GL_FALSE; - - if ( 0 ) { - fprintf( stderr, "TexSubImage id=%d lvl=%d int=0x%x format=0x%x type=0x%x x=%d y=%d w=%d h=%d fullW=%d fullH=%d\n", - texObj->Name, level, texImage->IntFormat, format, type, - xoffset, yoffset, width, height, - texImage->Width, texImage->Height ); - } - - image = &t->image[level]; - - /* Must have an existing texture image! - */ - assert( image->original.data ); - - if ( !_mesa_convert_texsubimage2d( texImage->TexFormat->IntFormat, - xoffset, yoffset, width, height, - texImage->Width, - format, type, packing, - pixels, image->original.data ) ) { - return GL_FALSE; - } - - /* Rescale the original image again if we have to. - */ - if ( image->wScale > 1 || image->hScale > 1 ) { - assert( image->rescaled.data ); - _mesa_rescale_teximage2d( texImage->TexFormat->TexelBytes, - image->original.width, image->original.height, - image->rescaled.width, image->rescaled.height, - image->original.data, image->rescaled.data ); - } - - t->reloadImages = GL_TRUE; /* signal the image needs to be reloaded */ - fxMesa->new_state |= TDFX_NEW_TEXTURE; /* XXX this might be a bit much */ - - return GL_TRUE; + GLchan *rgba = (GLchan *) texelOut; + const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage); + const GLubyte *texel; + + i = i * mml->wScale; + j = j * mml->hScale; + + texel = ((GLubyte *) texImage->Data) + j * mml->width + i; + rgba[RCOMP] = *texel; + rgba[GCOMP] = *texel; + rgba[BCOMP] = *texel; + rgba[ACOMP] = 255; } +static void +fetch_alpha8(const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLvoid * texelOut) +{ + GLchan *rgba = (GLchan *) texelOut; + const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage); + const GLubyte *texel; + + i = i * mml->wScale; + j = j * mml->hScale; + i = i * mml->width / texImage->Width; + j = j * mml->height / texImage->Height; + + texel = ((GLubyte *) texImage->Data) + j * mml->width + i; + rgba[RCOMP] = 255; + rgba[GCOMP] = 255; + rgba[BCOMP] = 255; + rgba[ACOMP] = *texel; +} -/* ================================================================ - * - */ -static void tdfxDDTexEnv( GLcontext *ctx, GLenum target, - GLenum pname, const GLfloat *param ) +static void +fetch_index8(const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLvoid * texelOut) { - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage); + (void) mml; + /* XXX todo */ +} - if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) { - if ( param ) { - fprintf( stderr, __FUNCTION__"( %x, %x )\n", pname, (GLint)(*param) ); - } else { - fprintf( stderr, __FUNCTION__"( %x )\n", pname ); - } - } - fxMesa->new_state |= TDFX_NEW_TEXTURE; +static void +fetch_luminance8_alpha8(const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLvoid * texelOut) +{ + GLchan *rgba = (GLchan *) texelOut; + const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage); + const GLubyte *texel; + + i = i * mml->wScale; + j = j * mml->hScale; + + texel = ((GLubyte *) texImage->Data) + (j * mml->width + i) * 2; + rgba[RCOMP] = texel[0]; + rgba[GCOMP] = texel[0]; + rgba[BCOMP] = texel[0]; + rgba[ACOMP] = texel[1]; } -static void tdfxDDTexParameter( GLcontext *ctx, GLenum target, - struct gl_texture_object *tObj, - GLenum pname, const GLfloat *params ) -{ - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - GLenum param = (GLenum) (GLint) params[0]; - tdfxTexObjPtr t; - if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) { - fprintf( stderr, __FUNCTION__ "( %d, %p, %x, %x )\n", - tObj->Name, tObj->DriverData, pname, param ); - } +static void +fetch_r5g6b5(const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLvoid * texelOut) +{ + GLchan *rgba = (GLchan *) texelOut; + const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage); + const GLushort *texel; + + i = i * mml->wScale; + j = j * mml->hScale; + + texel = ((GLushort *) texImage->Data) + j * mml->width + i; + rgba[RCOMP] = (((*texel) >> 11) & 0x1f) * 255 / 31; + rgba[GCOMP] = (((*texel) >> 5) & 0x3f) * 255 / 63; + rgba[BCOMP] = (((*texel) >> 0) & 0x1f) * 255 / 31; + rgba[ACOMP] = 255; +} - if ( target != GL_TEXTURE_2D ) - return; - - if ( !tObj->DriverData ) - tObj->DriverData = tdfxAllocTexObj( fxMesa ); - - t = TDFX_TEXTURE_DATA(tObj); - - switch ( pname ) { - case GL_TEXTURE_MIN_FILTER: - switch ( param ) { - case GL_NEAREST: - t->mmMode = GR_MIPMAP_DISABLE; - t->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED; - t->LODblend = FXFALSE; - break; - - case GL_LINEAR: - t->mmMode = GR_MIPMAP_DISABLE; - t->minFilt = GR_TEXTUREFILTER_BILINEAR; - t->LODblend = FXFALSE; - break; - - case GL_NEAREST_MIPMAP_LINEAR: - if ( TDFX_IS_NAPALM(fxMesa) ) { - if ( fxMesa->numTMUs > 1 ) { - t->mmMode = GR_MIPMAP_NEAREST; - t->LODblend = FXTRUE; - } else { - t->mmMode = GR_MIPMAP_NEAREST_DITHER; - t->LODblend = FXFALSE; - } - t->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED; - break; - } - /* XXX Voodoo3/Banshee mipmap blending seems to produce - * incorrectly filtered colors for the smallest mipmap levels. - * To work-around we fall-through here and use a different filter. - */ - case GL_NEAREST_MIPMAP_NEAREST: - t->mmMode = GR_MIPMAP_NEAREST; - t->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED; - t->LODblend = FXFALSE; - break; - - case GL_LINEAR_MIPMAP_LINEAR: - if ( TDFX_IS_NAPALM(fxMesa) ) { - if ( fxMesa->numTMUs > 1 ) { - t->mmMode = GR_MIPMAP_NEAREST; - t->LODblend = FXTRUE; - } else { - t->mmMode = GR_MIPMAP_NEAREST_DITHER; - t->LODblend = FXFALSE; - } - t->minFilt = GR_TEXTUREFILTER_BILINEAR; - break; - } - /* XXX Voodoo3/Banshee mipmap blending seems to produce - * incorrectly filtered colors for the smallest mipmap levels. - * To work-around we fall-through here and use a different filter. - */ - case GL_LINEAR_MIPMAP_NEAREST: - t->mmMode = GR_MIPMAP_NEAREST; - t->minFilt = GR_TEXTUREFILTER_BILINEAR; - t->LODblend = FXFALSE; - break; - default: - break; - } - tdfxRevalidateTexture( ctx, tObj ); - fxMesa->new_state |= TDFX_NEW_TEXTURE; - break; - case GL_TEXTURE_MAG_FILTER: - switch ( param ) { - case GL_NEAREST: - t->magFilt = GR_TEXTUREFILTER_POINT_SAMPLED; - break; - case GL_LINEAR: - t->magFilt = GR_TEXTUREFILTER_BILINEAR; - break; - default: - break; - } - fxMesa->new_state |= TDFX_NEW_TEXTURE; - break; +static void +fetch_r4g4b4a4(const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLvoid * texelOut) +{ + GLchan *rgba = (GLchan *) texelOut; + const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage); + const GLushort *texel; + + i = i * mml->wScale; + j = j * mml->hScale; + + texel = ((GLushort *) texImage->Data) + j * mml->width + i; + rgba[RCOMP] = (((*texel) >> 12) & 0xf) * 255 / 15; + rgba[GCOMP] = (((*texel) >> 8) & 0xf) * 255 / 15; + rgba[BCOMP] = (((*texel) >> 4) & 0xf) * 255 / 15; + rgba[ACOMP] = (((*texel) >> 0) & 0xf) * 255 / 15; +} - case GL_TEXTURE_WRAP_S: - switch ( param ) { - case GL_CLAMP: - t->sClamp = GR_TEXTURECLAMP_CLAMP; - break; - case GL_REPEAT: - t->sClamp = GR_TEXTURECLAMP_WRAP; - break; - default: - break; - } - fxMesa->new_state |= TDFX_NEW_TEXTURE; - break; - case GL_TEXTURE_WRAP_T: - switch ( param ) { - case GL_CLAMP: - t->tClamp = GR_TEXTURECLAMP_CLAMP; - break; - case GL_REPEAT: - t->tClamp = GR_TEXTURECLAMP_WRAP; - break; - default: - break; - } - fxMesa->new_state |= TDFX_NEW_TEXTURE; - break; +static void +fetch_r5g5b5a1(const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLvoid * texelOut) +{ + GLchan *rgba = (GLchan *) texelOut; + const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage); + const GLushort *texel; + + i = i * mml->wScale; + j = j * mml->hScale; + + texel = ((GLushort *) texImage->Data) + j * mml->width + i; + rgba[RCOMP] = (((*texel) >> 11) & 0x1f) * 255 / 31; + rgba[GCOMP] = (((*texel) >> 6) & 0x1f) * 255 / 31; + rgba[BCOMP] = (((*texel) >> 1) & 0x1f) * 255 / 31; + rgba[ACOMP] = (((*texel) >> 0) & 0x01) * 255; +} - case GL_TEXTURE_BASE_LEVEL: - tdfxRevalidateTexture( ctx, tObj ); - break; - case GL_TEXTURE_MAX_LEVEL: - tdfxRevalidateTexture( ctx, tObj ); - break; +static void +fetch_a8r8g8b8(const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLvoid * texelOut) +{ + GLchan *rgba = (GLchan *) texelOut; + const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage); + const GLuint *texel; + + i = i * mml->wScale; + j = j * mml->hScale; + + texel = ((GLuint *) texImage->Data) + j * mml->width + i; + rgba[RCOMP] = (((*texel) >> 16) & 0xff); + rgba[GCOMP] = (((*texel) >> 8) & 0xff); + rgba[BCOMP] = (((*texel) ) & 0xff); + rgba[ACOMP] = (((*texel) >> 24) & 0xff); +} - case GL_TEXTURE_BORDER_COLOR: - /* TO DO */ - break; - case GL_TEXTURE_MIN_LOD: - /* TO DO */ - break; - case GL_TEXTURE_MAX_LOD: - /* TO DO */ - break; +static FetchTexelFunc +fxFetchFunction(GLint mesaFormat) +{ + switch (mesaFormat) { + case MESA_FORMAT_I8: + return fetch_intensity8; + case MESA_FORMAT_A8: + return fetch_alpha8; + case MESA_FORMAT_L8: + return fetch_luminance8; + case MESA_FORMAT_CI8: + return fetch_index8; + case MESA_FORMAT_AL88: + return fetch_luminance8_alpha8; + case MESA_FORMAT_RGB565: + return fetch_r5g6b5; + case MESA_FORMAT_ARGB4444: + return fetch_r4g4b4a4; + case MESA_FORMAT_ARGB1555: + return fetch_r5g5b5a1; + case MESA_FORMAT_ARGB8888: + return fetch_a8r8g8b8; default: - break; + _mesa_problem(NULL, "Unexpected format in fxFetchFunction"); + printf("%d\n", mesaFormat); + return NULL; } } -static void tdfxDDBindTexture( GLcontext *ctx, GLenum target, - struct gl_texture_object *tObj ) -{ - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - tdfxTexObjPtr t; - - if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) { - fprintf( stderr, __FUNCTION__ "( %d, %p )\n", - tObj->Name, tObj->DriverData ); - } - - if ( target != GL_TEXTURE_2D ) - return; - if ( !tObj->DriverData ) - tObj->DriverData = tdfxAllocTexObj( fxMesa ); - - t = TDFX_TEXTURE_DATA(tObj); - t->lastTimeUsed = fxMesa->texBindNumber++; - - fxMesa->new_state |= TDFX_NEW_TEXTURE; -} - -static void tdfxDDDeleteTexture( GLcontext *ctx, - struct gl_texture_object *tObj ) +void +tdfxDDTexImage2D(GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, GLint width, GLint height, GLint border, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) { - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - - if ( fxMesa->driDrawable ) { - LOCK_HARDWARE( fxMesa ); - tdfxTMFreeTextureLocked( fxMesa, tObj ); - UNLOCK_HARDWARE( fxMesa ); - } + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + tdfxTexInfo *ti; + tdfxMipMapLevel *mml; + GLint texelBytes; + + /* + printf("TexImage id=%d int 0x%x format 0x%x type 0x%x %dx%d\n", + texObj->Name, texImage->IntFormat, format, type, + texImage->Width, texImage->Height); + */ - fxMesa->new_state |= TDFX_NEW_TEXTURE; + ti = TDFX_TEXTURE_DATA(texObj); + if (!ti) { + texObj->DriverData = fxAllocTexObjData(fxMesa); + if (!texObj->DriverData) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + return; + } + ti = TDFX_TEXTURE_DATA(texObj); + } + + mml = TDFX_TEXIMAGE_DATA(texImage); + if (!mml) { + texImage->DriverData = CALLOC(sizeof(tdfxMipMapLevel)); + if (!texImage->DriverData) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + return; + } + mml = TDFX_TEXIMAGE_DATA(texImage); + } + + /* Determine width and height scale factors for texture. + * Remember, Glide is limited to 8:1 aspect ratios. + */ + tdfxTexGetInfo(ctx, + texImage->Width, texImage->Height, + NULL, /* lod level */ + NULL, /* aspect ratio */ + NULL, NULL, /* sscale, tscale */ + &mml->wScale, &mml->hScale); + + /* rescaled size: */ + mml->width = width * mml->wScale; + mml->height = height * mml->hScale; + + + /* choose the texture format */ + assert(ctx->Driver.ChooseTextureFormat); + texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, + internalFormat, format, type); + assert(texImage->TexFormat); + mml->glideFormat = fxGlideFormat(texImage->TexFormat->MesaFormat); + ti->info.format = mml->glideFormat; + texImage->FetchTexel = fxFetchFunction(texImage->TexFormat->MesaFormat); + texelBytes = texImage->TexFormat->TexelBytes; + + if (mml->width != width || mml->height != height) { + /* rescale the image to overcome 1:8 aspect limitation */ + GLvoid *tempImage; + tempImage = MALLOC(width * height * texelBytes); + if (!tempImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + return; + } + /* unpack image, apply transfer ops and store in tempImage */ + _mesa_transfer_teximage(ctx, 2, texImage->Format, + texImage->TexFormat, + tempImage, + width, height, 1, 0, 0, 0, + width * texelBytes, + 0, /* dstImageStride */ + format, type, pixels, packing); + assert(!texImage->Data); + texImage->Data = MALLOC(mml->width * mml->height * texelBytes); + if (!texImage->Data) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + FREE(tempImage); + return; + } + _mesa_rescale_teximage2d(texelBytes, + mml->width * texelBytes, /* dst stride */ + width, height, + mml->width, mml->height, + tempImage /*src*/, texImage->Data /*dst*/ ); + FREE(tempImage); + } + else { + /* no rescaling needed */ + assert(!texImage->Data); + texImage->Data = MALLOC(mml->width * mml->height * texelBytes); + if (!texImage->Data) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + return; + } + /* unpack image, apply transfer ops and store in texImage->Data */ + _mesa_transfer_teximage(ctx, 2, texImage->Format, + texImage->TexFormat, texImage->Data, + width, height, 1, 0, 0, 0, + texImage->Width * texelBytes, + 0, /* dstImageStride */ + format, type, pixels, packing); + } + + RevalidateTexture(ctx, texObj); + + ti->reloadImages = GL_TRUE; + fxMesa->new_state |= TDFX_NEW_TEXTURE; } -static GLboolean tdfxDDIsTextureResident( GLcontext *ctx, - struct gl_texture_object *tObj ) -{ - tdfxTexObjPtr t = TDFX_TEXTURE_DATA(tObj); - return ( t && t->isInTM ); +void +tdfxDDTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + tdfxTexInfo *ti; + tdfxMipMapLevel *mml; + GLint texelBytes; + + if (!texObj->DriverData) { + _mesa_problem(ctx, "problem in fxDDTexSubImage2D"); + return; + } + + ti = TDFX_TEXTURE_DATA(texObj); + assert(ti); + mml = TDFX_TEXIMAGE_DATA(texImage); + assert(mml); + + assert(texImage->Data); /* must have an existing texture image! */ + assert(texImage->Format); + + texelBytes = texImage->TexFormat->TexelBytes; + + if (mml->wScale != 1 || mml->hScale != 1) { + /* need to rescale subimage to match mipmap level's rescale factors */ + const GLint newWidth = width * mml->wScale; + const GLint newHeight = height * mml->hScale; + GLvoid *scaledImage, *tempImage; + GLubyte *destAddr; + tempImage = MALLOC(width * height * texelBytes); + if (!tempImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D"); + return; + } + + _mesa_transfer_teximage(ctx, 2, texImage->Format,/* Tex int format */ + texImage->TexFormat, /* dest format */ + (GLubyte *) tempImage, /* dest */ + width, height, 1, /* subimage size */ + 0, 0, 0, /* subimage pos */ + width * texelBytes, /* dest row stride */ + 0, /* dst image stride */ + format, type, pixels, packing); + + /* now rescale */ + scaledImage = MALLOC(newWidth * newHeight * texelBytes); + if (!scaledImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D"); + FREE(tempImage); + return; + } + + /* compute address of dest subimage within the overal tex image */ + destAddr = (GLubyte *) texImage->Data + + (yoffset * mml->hScale * mml->width + + xoffset * mml->wScale) * texelBytes; + + _mesa_rescale_teximage2d(texelBytes, + mml->width * texelBytes, /* dst stride */ + width, height, + newWidth, newHeight, + tempImage, destAddr); + + FREE(tempImage); + FREE(scaledImage); + } + else { + /* no rescaling needed */ + _mesa_transfer_teximage(ctx, 2, texImage->Format, /* Tex int format */ + texImage->TexFormat, /* dest format */ + (GLubyte *) texImage->Data,/* dest */ + width, height, 1, /* subimage size */ + xoffset, yoffset, 0, /* subimage pos */ + mml->width * texelBytes, /* dest row stride */ + 0, /* dst image stride */ + format, type, pixels, packing); + } + + ti->reloadImages = GL_TRUE; /* signal the image needs to be reloaded */ + fxMesa->new_state |= TDFX_NEW_TEXTURE; /* XXX this might be a bit much */ } -/* Convert a gl_color_table texture palette to Glide's format. - */ -static void -tdfxConvertPalette( FxU32 data[256], const struct gl_color_table *table ) -{ - const GLubyte *tableUB = (const GLubyte *) table->Table; - GLint width = table->Size; - FxU32 r, g, b, a; - GLint i; - ASSERT( table->TableType == GL_UNSIGNED_BYTE ); +/**********************************************************************/ +/**** COMPRESSED TEXTURE IMAGE FUNCTIONS ****/ +/**********************************************************************/ - switch ( table->Format ) { - case GL_RGBA: - for ( i = 0 ; i < width ; i++ ) { - r = tableUB[i * 4 + 0]; - g = tableUB[i * 4 + 1]; - b = tableUB[i * 4 + 2]; - a = tableUB[i * 4 + 3]; - data[i] = PACK_COLOR_8888( a, r, g, b ); - } - break; - case GL_RGB: - for ( i = 0 ; i < width ; i++ ) { - r = tableUB[i * 3 + 0]; - g = tableUB[i * 3 + 1]; - b = tableUB[i * 3 + 2]; - a = 255; - data[i] = PACK_COLOR_8888( a, r, g, b ); - } - break; - case GL_LUMINANCE: - for ( i = 0 ; i < width ; i++ ) { - r = tableUB[i]; - g = tableUB[i]; - b = tableUB[i]; - a = 255; - data[i] = PACK_COLOR_8888( a, r, g, b ); - } - break; - case GL_ALPHA: - for ( i = 0 ; i < width ; i++ ) { - r = g = b = 255; - a = tableUB[i]; - data[i] = PACK_COLOR_8888( a, r, g, b ); - } - break; - case GL_LUMINANCE_ALPHA: - for ( i = 0 ; i < width ; i++ ) { - r = g = b = tableUB[i * 2 + 0]; - a = tableUB[i * 2 + 1]; - data[i] = PACK_COLOR_8888( a, r, g, b ); - } - break; - case GL_INTENSITY: - for ( i = 0 ; i < width ; i++ ) { - r = tableUB[i]; - g = tableUB[i]; - b = tableUB[i]; - a = tableUB[i]; - data[i] = PACK_COLOR_8888( a, r, g, b ); - } - break; - } +#if 0000 +GLboolean +tdfxDDCompressedTexImage2D( GLcontext *ctx, GLenum target, + GLint level, GLsizei imageSize, + const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + GLboolean *retainInternalCopy) +{ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + const GLboolean allow32bpt = TDFX_IS_NAPALM(fxMesa); + GrTextureFormat_t gldformat; + tdfxTexInfo *ti; + tdfxMipMapLevel *mml; + GLint dstWidth, dstHeight, wScale, hScale, texelSize; + MesaIntTexFormat intFormat; + GLboolean isCompressedFormat; + GLsizei texSize; + + if (target != GL_TEXTURE_2D || texImage->Border > 0) + return GL_FALSE; + + if (!texObj->DriverData) + texObj->DriverData = fxAllocTexObjData(fxMesa); + + ti = TDFX_TEXTURE_DATA(texObj); + mml = &ti->mipmapLevel[level]; + + isCompressedFormat = tdfxDDIsCompressedGlideFormatMacro(texImage->IntFormat); + if (!isCompressedFormat) { + _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage2D(format)"); + return GL_FALSE; + } + /* Determine the apporpriate GL internal texel format, Mesa internal + * texel format, and texelSize (bytes) given the user's internal + * texture format hint. + */ + tdfxTexGetFormat(texImage->IntFormat, allow32bpt, + &gldformat, &intFormat, &texelSize); + + /* Determine width and height scale factors for texture. + * Remember, Glide is limited to 8:1 aspect ratios. + */ + tdfxTexGetInfo(ctx, + texImage->Width, texImage->Height, + NULL, /* lod level */ + NULL, /* aspect ratio */ + NULL, NULL, /* sscale, tscale */ + &wScale, &hScale); + dstWidth = texImage->Width * wScale; + dstHeight = texImage->Height * hScale; + /* housekeeping */ + _mesa_set_teximage_component_sizes(intFormat, texImage); + + texSize = tdfxDDCompressedImageSize(ctx, + texImage->IntFormat, + 2, + texImage->Width, + texImage->Height, + 1); + if (texSize != imageSize) { + _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexImage2D(texSize)"); + return GL_FALSE; + } + + /* allocate new storage for texture image, if needed */ + if (!mml->data || mml->glideFormat != gldformat || + mml->width != dstWidth || mml->height != dstHeight || + texSize != mml->dataSize) { + if (mml->data) { + FREE(mml->data); + } + mml->data = MALLOC(texSize); + if (!mml->data) { + return GL_FALSE; + } + mml->texelSize = texelSize; + mml->glideFormat = gldformat; + mml->width = dstWidth; + mml->height = dstHeight; + tdfxTMMoveOutTM(fxMesa, texObj); + /*tdfxTexInvalidate(ctx, texObj);*/ + } + + /* save the texture data */ + MEMCPY(mml->data, data, imageSize); + + RevalidateTexture(ctx, texObj); + + ti->reloadImages = GL_TRUE; + fxMesa->new_state |= TDFX_NEW_TEXTURE; + + *retainInternalCopy = GL_FALSE; + return GL_TRUE; } -static void -tdfxDDTexturePalette( GLcontext *ctx, struct gl_texture_object *tObj ) +GLboolean +tdfxDDCompressedTexSubImage2D( GLcontext *ctx, GLenum target, + GLint level, GLint xoffset, + GLint yoffset, GLsizei width, + GLint height, GLenum format, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) { - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - tdfxTexObjPtr t; - - if ( tObj ) { - /* Per-texture palette */ - if ( !tObj->DriverData ) - tObj->DriverData = tdfxAllocTexObj(fxMesa); - - t = TDFX_TEXTURE_DATA(tObj); - tdfxConvertPalette( t->palette.data, &tObj->Palette ); - /*tdfxTexInvalidate( ctx, tObj );*/ - } else { - /* Global texture palette */ - tdfxConvertPalette( fxMesa->glbPalette.data, &ctx->Texture.Palette ); - } - - fxMesa->new_state |= TDFX_NEW_TEXTURE; /* XXX too heavy-handed */ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + tdfxTexInfo *ti; + tdfxMipMapLevel *mml; + + /* + * We punt if we are not replacing the entire image. This + * is allowed by the spec. + */ + if ((xoffset != 0) && (yoffset != 0) + && (width != texImage->Width) + && (height != texImage->Height)) { + return GL_FALSE; + } + + ti = TDFX_TEXTURE_DATA(texObj); + mml = &ti->mipmapLevel[level]; + if (imageSize != mml->dataSize) { + return GL_FALSE; + } + MEMCPY(data, mml->data, imageSize); + + ti->reloadImages = GL_TRUE; + fxMesa->new_state |= TDFX_NEW_TEXTURE; + + return GL_TRUE; } +#endif - -/**********************************************************************/ -/**** NEW TEXTURE IMAGE FUNCTIONS ****/ -/**********************************************************************/ - - - -#if 0 +#if 0 static void PrintTexture(int w, int h, int c, const GLubyte * data) { - int i, j; - for (i = 0; i < h; i++) { - for (j = 0; j < w; j++) { - if (c == 2) - printf("%02x %02x ", data[0], data[1]); - else if (c == 3) - printf("%02x %02x %02x ", data[0], data[1], data[2]); - data += c; - } - printf("\n"); - } + int i, j; + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++) { + if (c == 2) + printf("%02x %02x ", data[0], data[1]); + else if (c == 3) + printf("%02x %02x %02x ", data[0], data[1], data[2]); + data += c; + } + printf("\n"); + } } #endif -static GLboolean -tdfxDDTestProxyTexImage( GLcontext *ctx, GLenum target, - GLint level, GLint internalFormat, - GLenum format, GLenum type, - GLint width, GLint height, - GLint depth, GLint border ) +GLboolean +tdfxDDTestProxyTexImage(GLcontext *ctx, GLenum target, + GLint level, GLint internalFormat, + GLenum format, GLenum type, + GLint width, GLint height, + GLint depth, GLint border) { - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - struct gl_shared_state *ss = fxMesa->glCtx->Shared; - tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ss->DriverData; - - switch (target) { - case GL_PROXY_TEXTURE_1D: - return GL_TRUE; /* software rendering */ - case GL_PROXY_TEXTURE_2D: - { - struct gl_texture_object *tObj; - tdfxTexObjPtr t; - int memNeeded; - - tObj = ctx->Texture.Proxy2D; - if (!tObj->DriverData) - tObj->DriverData = tdfxAllocTexObj(fxMesa); - t = TDFX_TEXTURE_DATA(tObj); - - /* assign the parameters to test against */ - tObj->Image[level]->Width = width; - tObj->Image[level]->Height = height; - tObj->Image[level]->Border = border; - tObj->Image[level]->IntFormat = internalFormat; - if (level == 0) { - /* don't use mipmap levels > 0 */ - tObj->MinFilter = tObj->MagFilter = GL_NEAREST; - } - else { - /* test with all mipmap levels */ - tObj->MinFilter = GL_LINEAR_MIPMAP_LINEAR; - tObj->MagFilter = GL_NEAREST; - } - tdfxRevalidateTexture(ctx, tObj); - - /* - printf("small lodlog2 0x%x\n", t->info.smallLodLog2); - printf("large lodlog2 0x%x\n", t->info.largeLodLog2); - printf("aspect ratio 0x%x\n", t->info.aspectRatioLog2); - printf("glide format 0x%x\n", t->info.format); - printf("data %p\n", t->info.data); - printf("lodblend %d\n", (int) t->LODblend); - */ - - /* determine where texture will reside */ - if (t->LODblend && !tss->umaTexMemory) { - /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */ - memNeeded = fxMesa->Glide.grTexTextureMemRequired( - GR_MIPMAPLEVELMASK_BOTH, &(t->info)); - } - else { - /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */ - memNeeded = fxMesa->Glide.grTexTextureMemRequired( - GR_MIPMAPLEVELMASK_BOTH, &(t->info)); - } - /* - printf("Proxy test %d > %d\n", memNeeded, tss->totalTexMem[0]); - */ - if (memNeeded > tss->totalTexMem[0]) - return GL_FALSE; - else - return GL_TRUE; - } - case GL_PROXY_TEXTURE_3D: - return GL_TRUE; /* software rendering */ - default: - return GL_TRUE; /* never happens, silence compiler */ - } + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; + struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; + + switch (target) { + case GL_PROXY_TEXTURE_1D: + return GL_TRUE; /* software rendering */ + case GL_PROXY_TEXTURE_2D: + { + struct gl_texture_object *tObj; + tdfxTexInfo *ti; + int memNeeded; + + tObj = ctx->Texture.Proxy2D; + if (!tObj->DriverData) + tObj->DriverData = fxAllocTexObjData(fxMesa); + ti = TDFX_TEXTURE_DATA(tObj); + + /* assign the parameters to test against */ + tObj->Image[level]->Width = width; + tObj->Image[level]->Height = height; + tObj->Image[level]->Border = border; +#if 0 + tObj->Image[level]->IntFormat = internalFormat; +#endif + if (level == 0) { + /* don't use mipmap levels > 0 */ + tObj->MinFilter = tObj->MagFilter = GL_NEAREST; + } + else { + /* test with all mipmap levels */ + tObj->MinFilter = GL_LINEAR_MIPMAP_LINEAR; + tObj->MagFilter = GL_NEAREST; + } + RevalidateTexture(ctx, tObj); + + /* + printf("small lodlog2 0x%x\n", ti->info.smallLodLog2); + printf("large lodlog2 0x%x\n", ti->info.largeLodLog2); + printf("aspect ratio 0x%x\n", ti->info.aspectRatioLog2); + printf("glide format 0x%x\n", ti->info.format); + printf("data %p\n", ti->info.data); + printf("lodblend %d\n", (int) ti->LODblend); + */ + + /* determine where texture will reside */ + if (ti->LODblend && !shared->umaTexMemory) { + /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */ + memNeeded = fxMesa->Glide.grTexTextureMemRequired( + GR_MIPMAPLEVELMASK_BOTH, &(ti->info)); + } + else { + /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */ + memNeeded = fxMesa->Glide.grTexTextureMemRequired( + GR_MIPMAPLEVELMASK_BOTH, &(ti->info)); + } + /* + printf("Proxy test %d > %d\n", memNeeded, shared->totalTexMem[0]); + */ + if (memNeeded > shared->totalTexMem[0]) + return GL_FALSE; + else + return GL_TRUE; + } + case GL_PROXY_TEXTURE_3D: + return GL_TRUE; /* software rendering */ + default: + return GL_TRUE; /* never happens, silence compiler */ + } } -/* Return a texture image to Mesa. This is either to satisfy - * a glGetTexImage() call or to prepare for software texturing. +#if 000 +/* + * This is called from _mesa_GetCompressedTexImage. We just + * copy out the compressed data. */ -static GLvoid * -tdfxDDGetTexImage( GLcontext *ctx, GLenum target, GLint level, - const struct gl_texture_object *texObj, - GLenum *formatOut, GLenum *typeOut, - GLboolean *freeImageOut ) +void +tdfxDDGetCompressedTexImage( GLcontext *ctx, GLenum target, + GLint lod, void *image, + const struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) { - const struct gl_texture_image *texImage = texObj->Image[level]; - const struct gl_texture_format *texFormat = texImage->TexFormat; - tdfxTexObjPtr t = TDFX_TEXTURE_DATA(texObj); - tdfxTexImagePtr image; - GLubyte *data; + tdfxTexInfo *ti; + tdfxMipMapLevel *mml; - if ( target != GL_TEXTURE_2D ) - return NULL; - if ( !t ) - return NULL; + if (target != GL_TEXTURE_2D) + return; - image = &t->image[level]; - if ( !image->original.data ) - return NULL; + if (!texObj->DriverData) + return; - data = (GLubyte *) MALLOC( texImage->Width * texImage->Height * 4 ); - if ( !data ) - return NULL; + ti = TDFX_TEXTURE_DATA(texObj); + mml = &ti->mipmapLevel[lod]; + if (mml->data) { + MEMCPY(image, mml->data, mml->dataSize); + } +} +#endif - _mesa_unconvert_teximage2d( texFormat->IntFormat, texImage->Format, - texImage->Width, texImage->Height, - image->original.data, data ); +/* + * Calculate a specific texture format given a generic + * texture format. + */ +GLint +tdfxDDSpecificCompressedTexFormat(GLcontext *ctx, + GLint internalFormat, + GLint numDimensions) +{ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + + if (numDimensions != 2) { + return internalFormat; + } + /* + * If we don't have pointers to the functions, then + * we drop back to uncompressed format. The logic + * in Mesa proper handles this for us. + * + * This is just to ease the transition to a Glide with + * the texus2 library. + */ + if (!fxMesa->Glide.txImgQuantize || !fxMesa->Glide.txImgDequantizeFXT1) { + return internalFormat; + } + switch (internalFormat) { + case GL_COMPRESSED_RGB_ARB: + return GL_COMPRESSED_RGB_FXT1_3DFX; + case GL_COMPRESSED_RGBA_ARB: + return GL_COMPRESSED_RGBA_FXT1_3DFX; + } + return internalFormat; +} - *formatOut = texImage->Format; - *typeOut = GL_UNSIGNED_BYTE; - *freeImageOut = GL_TRUE; +/* + * Calculate a specific texture format given a generic + * texture format. + */ +GLint +tdfxDDBaseCompressedTexFormat(GLcontext *ctx, + GLint internalFormat) +{ + switch (internalFormat) { + case GL_COMPRESSED_RGB_FXT1_3DFX: + return GL_RGB; + case GL_COMPRESSED_RGBA_FXT1_3DFX: + return GL_RGBA; + } + return -1; +} - return data; +/* + * Tell us if an image is compressed. The real work is done + * in a macro, but we need to have a function to create a + * function pointer. + */ +GLboolean +tdfxDDIsCompressedFormat(GLcontext *ctx, GLint internalFormat) +{ + return tdfxDDIsCompressedFormatMacro(internalFormat); } -void tdfxDDInitTextureFuncs( GLcontext *ctx ) +/* + * Calculate the image size of a compressed texture. + * + * The current compressed format, the FXT1 family, all + * map 8x32 texel blocks into 128 bits. + * + * We return 0 if we can't calculate the size. + * + * Glide would report this out to us, but we don't have + * exactly the right parameters. + */ +GLsizei +tdfxDDCompressedImageSize(GLcontext *ctx, + GLenum intFormat, + GLuint numDimensions, + GLuint width, + GLuint height, + GLuint depth) { - ctx->Driver.TexImage2D = tdfxDDTexImage2D; - ctx->Driver.TexSubImage2D = tdfxDDTexSubImage2D; - ctx->Driver.GetTexImage = tdfxDDGetTexImage; - ctx->Driver.TexEnv = tdfxDDTexEnv; - ctx->Driver.TexParameter = tdfxDDTexParameter; - ctx->Driver.BindTexture = tdfxDDBindTexture; - ctx->Driver.DeleteTexture = tdfxDDDeleteTexture; - ctx->Driver.IsTextureResident = tdfxDDIsTextureResident; - ctx->Driver.UpdateTexturePalette = tdfxDDTexturePalette; + if (numDimensions != 2) { + return 0; + } + switch (intFormat) { + case GL_COMPRESSED_RGB_FXT1_3DFX: + case GL_COMPRESSED_RGBA_FXT1_3DFX: + /* + * Round height and width to multiples of 4 and 8, + * divide the resulting product by 32 to get the number + * of blocks, and multiply by 32 = 128/8 to get the. + * number of bytes required. That is to say, just + * return the product. Remember that we are returning + * bytes, not texels, so we have shrunk the texture + * by a factor of the texel size. + */ + width = (width + 0x7) &~ 0x7; + height = (height + 0x3) &~ 0x3; + return width * height; + } + return 0; } diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.h b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.h index 3de4285a9..f6fcb6d3a 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.h +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.h @@ -23,7 +23,7 @@ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.h,v 1.1 2001/03/21 16:14:28 dawes Exp $ */ +/* $XFree86$ */ /* * Original rewrite: @@ -35,12 +35,131 @@ * */ -#ifndef __TDFX_TEX_H__ -#define __TDFX_TEX_H__ +#ifndef _TDFX_TEX_H_ +#define _TDFX_TEX_H_ -extern void tdfxUpdateTextureState( GLcontext *ctx ); -extern void tdfxUpdateTextureBinding( GLcontext *ctx ); -extern void tdfxDDInitTextureFuncs( GLcontext *ctx ); +#include "texutil.h" + + +#define tdfxDDIsCompressedFormatMacro(internalFormat) \ + (((internalFormat) == GL_COMPRESSED_RGB_FXT1_3DFX) || \ + ((internalFormat) == GL_COMPRESSED_RGBA_FXT1_3DFX)) +#define tdfxDDIsCompressedGlideFormatMacro(internalFormat) \ + ((internalFormat) == GR_TEXFMT_ARGB_CMP_FXT1) + + + +extern void +tdfxTexValidate(GLcontext * ctx, struct gl_texture_object *tObj); + +extern void +tdfxDDBindTexture(GLcontext * ctx, GLenum target, + struct gl_texture_object *tObj); + +extern void +tdfxDDDeleteTexture(GLcontext * ctx, struct gl_texture_object *tObj); + +extern GLboolean +tdfxDDIsTextureResident(GLcontext *ctx, struct gl_texture_object *tObj); + +extern void +tdfxDDTexturePalette(GLcontext * ctx, struct gl_texture_object *tObj); + +#if 000 /* DEAD? */ +extern void +fxDDTexUseGlobalPalette(GLcontext * ctx, GLboolean state); +#endif + +extern void +tdfxDDTexEnv(GLcontext * ctx, GLenum target, GLenum pname, + const GLfloat * param); + +extern void +tdfxDDTexParameter(GLcontext * ctx, GLenum target, + struct gl_texture_object *tObj, + GLenum pname, const GLfloat * params); + +extern const struct gl_texture_format * +tdfxDDChooseTextureFormat( GLcontext *ctx, GLint internalFormat, + GLenum srcFormat, GLenum srcType ); + +extern void +tdfxDDTexImage2D(GLcontext * ctx, GLenum target, GLint level, + GLint internalFormat, GLint width, GLint height, + GLint border, + GLenum format, GLenum type, const GLvoid * pixels, + const struct gl_pixelstore_attrib * packing, + struct gl_texture_object * texObj, + struct gl_texture_image * texImage); + +extern void +tdfxDDTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ); + +#if 000 +extern GLboolean +tdfxDDCompressedTexImage2D( GLcontext *ctx, GLenum target, + GLint level, GLsizei imageSize, + const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + GLboolean *retainInternalCopy); + +extern GLboolean +tdfxDDCompressedTexSubImage2D( GLcontext *ctx, GLenum target, + GLint level, GLint xoffset, + GLint yoffset, GLsizei width, + GLint height, GLenum format, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ); +#endif + +extern GLboolean +tdfxDDTestProxyTexImage(GLcontext *ctx, GLenum target, + GLint level, GLint internalFormat, + GLenum format, GLenum type, + GLint width, GLint height, + GLint depth, GLint border); + +extern GLvoid * +tdfxDDGetTexImage(GLcontext * ctx, GLenum target, GLint level, + const struct gl_texture_object *texObj, + GLenum * formatOut, GLenum * typeOut, + GLboolean * freeImageOut); + +extern void +tdfxDDGetCompressedTexImage( GLcontext *ctx, GLenum target, + GLint lod, void *image, + const struct gl_texture_object *texObj, + struct gl_texture_image *texImage ); + +extern GLint +tdfxDDSpecificCompressedTexFormat(GLcontext *ctx, + GLint internalFormat, + GLint numDimensions); + +extern GLint +tdfxDDBaseCompressedTexFormat(GLcontext *ctx, + GLint internalFormat); + +extern GLboolean +tdfxDDIsCompressedFormat(GLcontext *ctx, GLint internalFormat); + +extern GLsizei +tdfxDDCompressedImageSize(GLcontext *ctx, + GLenum intFormat, + GLuint numDimensions, + GLuint width, + GLuint height, + GLuint depth); + #endif diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.c index 273fd3169..6fc3484a3 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.c @@ -23,7 +23,7 @@ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.c,v 1.4 2001/08/18 02:51:07 dawes Exp $ */ +/* $XFree86$ */ /* * Original rewrite: @@ -39,871 +39,934 @@ #include "tdfx_tex.h" #include "tdfx_texman.h" -#define BAD_ADDRESS ((FxU32) -1) -/* Verify the consistancy of the texture memory manager. +#define BAD_ADDRESS ((FxU32) -1) + + +#if 0 /* DEBUG use */ +/* + * Verify the consistancy of the texture memory manager. * This involves: * Traversing all texture objects and computing total memory used. * Traverse the free block list and computing total memory free. * Compare the total free and total used amounts to the total memory size. * Make various assertions about the results. */ -static void tdfxTMVerifyFreeList( tdfxContextPtr fxMesa, FxU32 unit ) +static void +VerifyFreeList(tdfxContextPtr fxMesa, FxU32 tmu) { - struct gl_shared_state *ss = fxMesa->glCtx->Shared; - struct gl_texture_object *texObj; - tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ss->DriverData; - tdfxMemRange *block; - int prevStart = -1, prevEnd = -1; - int totalFree = 0; - int numObj = 0, numRes = 0; - int totalUsed = 0; - - for ( block = tss->freeRanges[unit] ; block ; block = block->next ) { - assert( block->endAddr > 0 ); - assert( block->startAddr <= tss->totalTexMem[unit] ); - assert( block->endAddr <= tss->totalTexMem[unit] ); - assert( (int) block->startAddr > prevStart ); - assert( (int) block->startAddr >= prevEnd ); - prevStart = (int) block->startAddr; - prevEnd = (int) block->endAddr; - totalFree += (block->endAddr - block->startAddr); - } - assert( totalFree == tss->freeTexMem[unit] ); - - for ( texObj = ss->TexObjectList ; texObj ; texObj = texObj->Next ) { - tdfxTexObjPtr t = TDFX_TEXTURE_DATA(texObj); - numObj++; - if ( t ) { - if ( t->isInTM ) { - numRes++; - assert( t->range[0] ); - if ( t->range[unit] ) - totalUsed += (t->range[unit]->endAddr - t->range[unit]->startAddr); - } else { - assert(!t->range[0]); - } - } - } - - fprintf( stderr, - "totalFree: %d totalUsed: %d totalMem: %d #objs=%d #res=%d\n", - tss->freeTexMem[unit], totalUsed, tss->totalTexMem[unit], - numObj, numRes ); - - assert( totalUsed + totalFree == tss->totalTexMem[unit] ); + struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; + struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; + tdfxMemRange *block; + int prevStart = -1, prevEnd = -1; + int totalFree = 0; + int numObj = 0, numRes = 0; + int totalUsed = 0; + + for (block = shared->tmFree[tmu]; block; block = block->next) { + assert( block->endAddr > 0 ); + assert( block->startAddr <= shared->totalTexMem[tmu] ); + assert( block->endAddr <= shared->totalTexMem[tmu] ); + assert( (int) block->startAddr > prevStart ); + assert( (int) block->startAddr >= prevEnd ); + prevStart = (int) block->startAddr; + prevEnd = (int) block->endAddr; + totalFree += (block->endAddr - block->startAddr); + } + assert(totalFree == shared->freeTexMem[tmu]); + + { + struct gl_texture_object *obj; + for (obj = mesaShared->TexObjectList; obj; obj = obj->Next) { + tdfxTexInfo *ti = TDFX_TEXTURE_DATA(obj); + numObj++; + if (ti) { + if (ti->isInTM) { + numRes++; + assert(ti->tm[0]); + if (ti->tm[tmu]) + totalUsed += (ti->tm[tmu]->endAddr - ti->tm[tmu]->startAddr); + } + else { + assert(!ti->tm[0]); + } + } + } + } + + printf("totalFree: %d totalUsed: %d totalMem: %d #objs=%d #res=%d\n", + shared->freeTexMem[tmu], totalUsed, shared->totalTexMem[tmu], + numObj, numRes); + + assert(totalUsed + totalFree == shared->totalTexMem[tmu]); } -static void tdfxTMDumpTexMem( tdfxContextPtr fxMesa ) -{ - struct gl_shared_state *ss = fxMesa->glCtx->Shared; - tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ss->DriverData; - struct gl_texture_object *texObj; - tdfxMemRange *r; - FxU32 prev; - - printf( "DUMP Objects:\n" ); - for ( texObj = ss->TexObjectList ; texObj ; texObj = texObj->Next ) { - tdfxTexObjPtr t = TDFX_TEXTURE_DATA(texObj); - - if ( t && t->isInTM ) { - printf( "Obj %8p: %4d info = %p\n", texObj, texObj->Name, t ); - - printf( " isInTM=%d whichTMU=%ld lastTimeUsed=%d\n", - t->isInTM, t->whichTMU, t->lastTimeUsed ); - printf( " tm[0] = %p", t->range[0] ); - assert( t->range[0] ); - if ( t->range[0] ) { - printf( " tm startAddr = %ld endAddr = %ld", - t->range[0]->startAddr, - t->range[0]->endAddr ); - } - printf( "\n" ); - printf( " tm[1] = %p", t->range[1] ); - if ( t->range[1] ) { - printf( " tm startAddr = %ld endAddr = %ld", - t->range[1]->startAddr, - t->range[1]->endAddr ); - } - printf( "\n" ); - } - } - - tdfxTMVerifyFreeList( fxMesa, 0 ); - tdfxTMVerifyFreeList( fxMesa, 1 ); - printf( "Free memory unit 0: %d bytes\n", tss->freeTexMem[0] ); - prev = 0; - for ( r = tss->freeRanges[0] ; r ; r = r->next ) { - printf( "%8p: start %8ld end %8ld size %8ld gap %8ld\n", - r, r->startAddr, r->endAddr, r->endAddr - r->startAddr, - r->startAddr - prev ); - prev = r->endAddr; - } +static void +dump_texmem(tdfxContextPtr fxMesa) +{ + struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; + struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; + struct gl_texture_object *oldestObj, *obj, *lowestPriorityObj; + tdfxMemRange *r; + FxU32 prev; + + printf("DUMP Objects:\n"); + for (obj = mesaShared->TexObjectList; obj; obj = obj->Next) { + tdfxTexInfo *info = TDFX_TEXTURE_DATA(obj); + + if (info && info->isInTM) { + printf("Obj %8p: %4d info = %p\n", obj, obj->Name, info); + + printf(" isInTM=%d whichTMU=%d lastTimeUsed=%d\n", + info->isInTM, info->whichTMU, info->lastTimeUsed); + printf(" tm[0] = %p", info->tm[0]); + assert(info->tm[0]); + if (info->tm[0]) { + printf(" tm startAddr = %d endAddr = %d", + info->tm[0]->startAddr, + info->tm[0]->endAddr); + } + printf("\n"); + printf(" tm[1] = %p", info->tm[1]); + if (info->tm[1]) { + printf(" tm startAddr = %d endAddr = %d", + info->tm[1]->startAddr, + info->tm[1]->endAddr); + } + printf("\n"); + } + } + + VerifyFreeList(fxMesa, 0); + VerifyFreeList(fxMesa, 1); + + printf("Free memory unit 0: %d bytes\n", shared->freeTexMem[0]); + prev = 0; + for (r = shared->tmFree[0]; r; r = r->next) { + printf("%8p: start %8d end %8d size %8d gap %8d\n", r, r->startAddr, r->endAddr, r->endAddr - r->startAddr, r->startAddr - prev); + prev = r->endAddr; + } + + printf("Free memory unit 1: %d bytes\n", shared->freeTexMem[1]); + prev = 0; + for (r = shared->tmFree[1]; r; r = r->next) { + printf("%8p: start %8d end %8d size %8d gap %8d\n", r, r->startAddr, r->endAddr, r->endAddr - r->startAddr, r->startAddr - prev); + prev = r->endAddr; + } - printf( "Free memory unit 1: %d bytes\n", tss->freeTexMem[1] ); - prev = 0; - for ( r = tss->freeRanges[1] ; r ; r = r->next ) { - printf( "%8p: start %8ld end %8ld size %8ld gap %8ld\n", - r, r->startAddr, r->endAddr, r->endAddr - r->startAddr, - r->startAddr - prev ); - prev = r->endAddr; - } } +#endif + #ifdef TEXSANITY -static void fubar( void ) +static void +fubar(void) { - /* GH: What am I meant to do??? */ } -/* Sanity Check +/* + * Sanity Check */ -static void sanity( tdfxContextPtr fxMesa ) +static void +sanity(tdfxContextPtr fxMesa) { - tdfxMemRange *tmp, *prev, *pos; - - prev = 0; - tmp = fxMesa->freeRanges[0]; - while ( tmp ) { - if ( !tmp->startAddr && !tmp->endAddr ) { - fprintf( stderr, "Textures fubar\n" ); - fubar(); - } - if ( tmp->startAddr >= tmp->endAddr ) { - fprintf( stderr, "Node fubar\n" ); - fubar(); - } - if ( prev && ( prev->startAddr >= tmp->startAddr || - prev->endAddr > tmp->startAddr ) ) { - fprintf( stderr, "Sorting fubar\n" ); - fubar(); - } - prev = tmp; - tmp = tmp->next; - } - - prev = 0; - tmp = fxMesa->freeRanges[1]; - while ( tmp ) { - if ( !tmp->startAddr && !tmp->endAddr ) { - fprintf( stderr, "Textures fubar\n" ); - fubar(); - } - if ( tmp->startAddr >= tmp->endAddr ) { - fprintf( stderr, "Node fubar\n" ); - fubar(); - } - if ( prev && ( prev->startAddr >= tmp->startAddr || - prev->endAddr > tmp->startAddr ) ) { - fprintf( stderr, "Sorting fubar\n" ); - fubar(); - } - prev = tmp; - tmp = tmp->next; - } + tdfxMemRange *tmp, *prev, *pos; + + prev = 0; + tmp = fxMesa->tmFree[0]; + while (tmp) { + if (!tmp->startAddr && !tmp->endAddr) { + fprintf(stderr, "Textures fubar\n"); + fubar(); + } + if (tmp->startAddr >= tmp->endAddr) { + fprintf(stderr, "Node fubar\n"); + fubar(); + } + if (prev && (prev->startAddr >= tmp->startAddr || + prev->endAddr > tmp->startAddr)) { + fprintf(stderr, "Sorting fubar\n"); + fubar(); + } + prev = tmp; + tmp = tmp->next; + } + prev = 0; + tmp = fxMesa->tmFree[1]; + while (tmp) { + if (!tmp->startAddr && !tmp->endAddr) { + fprintf(stderr, "Textures fubar\n"); + fubar(); + } + if (tmp->startAddr >= tmp->endAddr) { + fprintf(stderr, "Node fubar\n"); + fubar(); + } + if (prev && (prev->startAddr >= tmp->startAddr || + prev->endAddr > tmp->startAddr)) { + fprintf(stderr, "Sorting fubar\n"); + fubar(); + } + prev = tmp; + tmp = tmp->next; + } } #endif -/* Allocate and initialize a new MemRange struct. Try to allocate it - * from the pool of free MemRange nodes rather than malloc. - */ -static tdfxMemRange * -tdfxTMNewRangeNode( tdfxContextPtr fxMesa, FxU32 start, FxU32 end ) -{ - struct gl_shared_state *ss = fxMesa->glCtx->Shared; - tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ss->DriverData; - tdfxMemRange *range; - - _glthread_LOCK_MUTEX( ss->Mutex ); - if ( tss && tss->rangePool ) { - range = tss->rangePool; - tss->rangePool = tss->rangePool->next; - } else { - range = MALLOC( sizeof(tdfxMemRange) ); - } - _glthread_UNLOCK_MUTEX( ss->Mutex ); - if ( !range ) { - if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE ) - fprintf( stderr, __FUNCTION__ ": out of memory!\n" ); - return NULL; - } - range->startAddr = start; - range->endAddr = end; - range->next = NULL; - return range; +/* + * Allocate and initialize a new MemRange struct. + * Try to allocate it from the pool of free MemRange nodes rather than malloc. + */ +static tdfxMemRange * +NewRangeNode(tdfxContextPtr fxMesa, FxU32 start, FxU32 end) +{ + struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; + struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; + tdfxMemRange *result; + + _glthread_LOCK_MUTEX(mesaShared->Mutex); + if (shared && shared->tmPool) { + result = shared->tmPool; + shared->tmPool = shared->tmPool->next; + } + else { + result = MALLOC(sizeof(tdfxMemRange)); + + } + _glthread_UNLOCK_MUTEX(mesaShared->Mutex); + + if (!result) { + /*fprintf(stderr, "fxDriver: out of memory!\n");*/ + return NULL; + } + + result->startAddr = start; + result->endAddr = end; + result->next = NULL; + + return result; } -/* Initialize texture memory. We take care of one or both TMU's here. +/* + * Initialize texture memory. + * We take care of one or both TMU's here. */ -void tdfxTMInit( tdfxContextPtr fxMesa ) +void +tdfxTMInit(tdfxContextPtr fxMesa) { - GLcontext *ctx = fxMesa->glCtx; - - if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE ) - fprintf( stderr, __FUNCTION__ "\n" ); - - if ( !ctx->Shared->DriverData ) { - const char *extensions; - tdfxSharedStatePtr tss = CALLOC_STRUCT( tdfx_shared_state ); - - if ( !tss ) - return; - - LOCK_HARDWARE( fxMesa ); - - extensions = fxMesa->Glide.grGetString( GR_EXTENSION ); - - if ( strstr( extensions, " TEXUMA " ) ) { - FxU32 start, end; - - tss->umaTexMemory = GL_TRUE; - - fxMesa->Glide.grEnable( GR_TEXTURE_UMA_EXT ); - - start = fxMesa->Glide.grTexMinAddress( 0 ); - end = fxMesa->Glide.grTexMaxAddress( 0 ); - - if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE ) - fprintf( stderr, " UMA tex memory: %d\n", (int)(end - start) ); - - tss->totalTexMem[0] = end - start; - tss->totalTexMem[1] = 0; - tss->freeTexMem[0] = end - start; - tss->freeTexMem[1] = 0; - tss->freeRanges[0] = tdfxTMNewRangeNode( fxMesa, start, end ); - tss->freeRanges[1] = NULL; - } else { - int unit; - - tss->umaTexMemory = GL_FALSE; - - for ( unit = 0 ; unit < fxMesa->numTMUs ; unit++ ) { - FxU32 start, end; - - start = fxMesa->Glide.grTexMinAddress( unit ); - end = fxMesa->Glide.grTexMaxAddress( unit ); - - tss->totalTexMem[unit] = end - start; - tss->freeTexMem[unit] = end - start; - tss->freeRanges[unit] = tdfxTMNewRangeNode( fxMesa, start, end ); - - if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE ) - fprintf( stderr, " Split tex memory: %d\n", - (int)(end - start) ); - } - } - - UNLOCK_HARDWARE( fxMesa ); - - tss->rangePool = NULL; - ctx->Shared->DriverData = tss; - - if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE ) - fprintf( stderr, " init UMA: %d\n", tss->umaTexMemory ); - } + if (!fxMesa->glCtx->Shared->DriverData) { + const char *extensions; + struct tdfxSharedState *shared = CALLOC_STRUCT(tdfxSharedState); + if (!shared) + return; + + LOCK_HARDWARE(fxMesa); + extensions = fxMesa->Glide.grGetString(GR_EXTENSION); + UNLOCK_HARDWARE(fxMesa); + if (strstr(extensions, "TEXUMA")) { + FxU32 start, end; + shared->umaTexMemory = GL_TRUE; + LOCK_HARDWARE(fxMesa); + fxMesa->Glide.grEnable(GR_TEXTURE_UMA_EXT); + start = fxMesa->Glide.grTexMinAddress(0); + end = fxMesa->Glide.grTexMaxAddress(0); + UNLOCK_HARDWARE(fxMesa); + shared->totalTexMem[0] = end - start; + shared->totalTexMem[1] = 0; + shared->freeTexMem[0] = end - start; + shared->freeTexMem[1] = 0; + shared->tmFree[0] = NewRangeNode(fxMesa, start, end); + shared->tmFree[1] = NULL; + /*printf("UMA tex memory: %d\n", (int) (end - start));*/ + } + else { + const int numTMUs = fxMesa->haveTwoTMUs ? 2 : 1; + int tmu; + shared->umaTexMemory = GL_FALSE; + LOCK_HARDWARE(fxMesa); + for (tmu = 0; tmu < numTMUs; tmu++) { + FxU32 start = fxMesa->Glide.grTexMinAddress(tmu); + FxU32 end = fxMesa->Glide.grTexMaxAddress(tmu); + shared->totalTexMem[tmu] = end - start; + shared->freeTexMem[tmu] = end - start; + shared->tmFree[tmu] = NewRangeNode(fxMesa, start, end); + /*printf("Split tex memory: %d\n", (int) (end - start));*/ + } + UNLOCK_HARDWARE(fxMesa); + } + + shared->tmPool = NULL; + fxMesa->glCtx->Shared->DriverData = shared; + /*printf("Texture memory init UMA: %d\n", shared->umaTexMemory);*/ + } } -/* Clean-up texture memory before destroying context. +/* + * Clean-up texture memory before destroying context. */ -void tdfxTMClose( tdfxContextPtr fxMesa ) +void +tdfxTMClose(tdfxContextPtr fxMesa) { - GLcontext *ctx = fxMesa->glCtx; - - if ( ctx->Shared->RefCount == 1 && fxMesa->driDrawable ) { - /* RefCount will soon go to zero, free our 3dfx stuff */ - tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ctx->Shared->DriverData; - int unit; - tdfxMemRange *tmp, *next; - - /* Deallocate the pool of free tdfxMemRange nodes */ - tmp = tss->rangePool; - while ( tmp ) { - next = tmp->next; - FREE( tmp ); - tmp = next; - } - - /* Delete the texture memory block tdfxMemRange nodes */ - for ( unit = 0 ; unit < fxMesa->numTMUs ; unit++ ) { - tmp = tss->freeRanges[unit]; - while ( tmp ) { - next = tmp->next; - FREE( tmp ); - tmp = next; - } - } - - FREE( tss ); - ctx->Shared->DriverData = NULL; - } + if (fxMesa->glCtx->Shared->RefCount == 1 && fxMesa->driDrawable) { + /* refcount will soon go to zero, free our 3dfx stuff */ + struct tdfxSharedState *shared = (struct tdfxSharedState *) fxMesa->glCtx->Shared->DriverData; + + const int numTMUs = fxMesa->haveTwoTMUs ? 2 : 1; + int tmu; + tdfxMemRange *tmp, *next; + + /* Deallocate the pool of free tdfxMemRange nodes */ + tmp = shared->tmPool; + while (tmp) { + next = tmp->next; + FREE(tmp); + tmp = next; + } + + /* Delete the texture memory block tdfxMemRange nodes */ + for (tmu = 0; tmu < numTMUs; tmu++) { + tmp = shared->tmFree[tmu]; + while (tmp) { + next = tmp->next; + FREE(tmp); + tmp = next; + } + } + + FREE(shared); + fxMesa->glCtx->Shared->DriverData = NULL; + } } -/* Delete a tdfxMemRange struct. +/* + * Delete a tdfxMemRange struct. * We keep a linked list of free/available tdfxMemRange structs to * avoid extra malloc/free calls. */ -#define DELETE_RANGE_NODE( tss, range ) \ -do { \ - (range)->next = (tss)->rangePool; \ - (tss)->rangePool = (range); \ -} while (0) +#if 0 +static void +DeleteRangeNode_NoLock(struct TdfxSharedState *shared, tdfxMemRange *range) +{ + /* insert at head of list */ + range->next = shared->tmPool; + shared->tmPool = range; +} +#endif + +#define DELETE_RANGE_NODE(shared, range) \ + (range)->next = (shared)->tmPool; \ + (shared)->tmPool = (range) + -/* When we've run out of texture memory we have to throw out an + +/* + * When we've run out of texture memory we have to throw out an * existing texture to make room for the new one. This function * determins the texture to throw out. */ static struct gl_texture_object * -tdfxTMFindOldestObject( tdfxContextPtr fxMesa, FxU32 unit ) +FindOldestObject(tdfxContextPtr fxMesa, FxU32 tmu) { - struct gl_shared_state *ss = fxMesa->glCtx->Shared; - const GLuint bindNumber = fxMesa->texBindNumber; - struct gl_texture_object *oldestObj, *texObj, *lowestPriorityObj; - GLfloat lowestPriority; - GLuint oldestAge; - - if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE ) - fprintf( stderr, __FUNCTION__ "\n" ); - - oldestObj = NULL; - oldestAge = 0; - - lowestPriority = 1.0F; - lowestPriorityObj = NULL; - - for ( texObj = ss->TexObjectList ; texObj ; texObj = texObj->Next ) { - tdfxTexObjPtr t = TDFX_TEXTURE_DATA(texObj); - - if ( t && t->isInTM && - ( ( t->whichTMU == unit ) || - ( t->whichTMU == TDFX_TMU_BOTH ) || - ( t->whichTMU == TDFX_TMU_SPLIT ) ) ) { - GLuint age, lastTime; - - assert( t->range[0] ); - lastTime = t->lastTimeUsed; - - if ( lastTime > bindNumber ) { - /* TODO: check wrap around */ - age = bindNumber + (UINT_MAX - lastTime + 1); - } else { - age = bindNumber - lastTime; - } - if ( age >= oldestAge ) { - oldestAge = age; - oldestObj = texObj; - } + const GLuint bindnumber = fxMesa->texBindNumber; + struct gl_texture_object *oldestObj, *obj, *lowestPriorityObj; + GLfloat lowestPriority; + GLuint oldestAge; + + oldestObj = NULL; + oldestAge = 0; + + lowestPriority = 1.0F; + lowestPriorityObj = NULL; + + for (obj = fxMesa->glCtx->Shared->TexObjectList; obj; obj = obj->Next) { + tdfxTexInfo *info = TDFX_TEXTURE_DATA(obj); + + if (info && info->isInTM && + ((info->whichTMU == tmu) || (info->whichTMU == TDFX_TMU_BOTH) || + (info->whichTMU == TDFX_TMU_SPLIT))) { + GLuint age, lasttime; + + assert(info->tm[0]); + lasttime = info->lastTimeUsed; + + if (lasttime > bindnumber) + age = bindnumber + (UINT_MAX - lasttime + 1); /* TO DO: check wrap around */ + else + age = bindnumber - lasttime; + + if (age >= oldestAge) { + oldestAge = age; + oldestObj = obj; + } + + /* examine priority */ + if (obj->Priority < lowestPriority) { + lowestPriority = obj->Priority; + lowestPriorityObj = obj; + } + } + } + + if (lowestPriority < 1.0) { + ASSERT(lowestPriorityObj); + /* + printf("discard %d pri=%f\n", lowestPriorityObj->Name, lowestPriority); + */ + return lowestPriorityObj; + } + else { + /* + printf("discard %d age=%d\n", oldestObj->Name, oldestAge); + */ + return oldestObj; + } +} - /* examine priority */ - if ( texObj->Priority < lowestPriority ) { - lowestPriority = texObj->Priority; - lowestPriorityObj = texObj; - } - } - } - if ( lowestPriority < 1.0 ) { - ASSERT( lowestPriorityObj ); - if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE ) - fprintf( stderr, "discard %d pri=%f\n", - lowestPriorityObj->Name, lowestPriority ); - return lowestPriorityObj; - } else { - if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE ) - fprintf( stderr, "discard %d age=%d\n", - oldestObj->Name, oldestAge ); - return oldestObj; - } +#if 0 +static void +FlushTexMemory(tdfxContextPtr fxMesa) +{ + struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; + struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; + struct gl_texture_object *obj; + + for (obj = mesaShared->TexObjectList; obj; obj = obj->Next) { + if (obj->RefCount < 2) { + /* don't flush currently bound textures */ + tdfxTMMoveOutTM_NoLock(fxMesa, obj); + } + } } +#endif -/* Find the address (offset?) at which we can store a new texture. - * <unit> is the texture unit. +/* + * Find the address (offset?) at which we can store a new texture. + * <tmu> is the texture unit. * <size> is the texture size in bytes. */ -static FxU32 tdfxTMFindStartAddr( tdfxContextPtr fxMesa, - FxU32 unit, FxU32 size ) +static FxU32 +FindStartAddr(tdfxContextPtr fxMesa, FxU32 tmu, FxU32 size) { - struct gl_shared_state *ss = fxMesa->glCtx->Shared; - tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ss->DriverData; - struct gl_texture_object *texObj; - tdfxMemRange *prev, *block; - FxU32 result; - - if ( tss->umaTexMemory ) { - assert( unit == TDFX_TMU0 ); - } - - _glthread_LOCK_MUTEX( ss->Mutex ); - while ( 1 ) { - prev = NULL; - block = tss->freeRanges[unit]; - - while ( block ) { - if ( block->endAddr - block->startAddr >= size ) { - /* The texture will fit here */ - result = block->startAddr; - block->startAddr += size; - if ( block->startAddr == block->endAddr ) { - /* Remove this node since it's empty */ - if ( prev ) { - prev->next = block->next; - } else { - tss->freeRanges[unit] = block->next; - } - DELETE_RANGE_NODE( tss, block ); - } - tss->freeTexMem[unit] -= size; - _glthread_UNLOCK_MUTEX( ss->Mutex ); - return result; - } - prev = block; - block = block->next; - } - - /* We failed to find a block large enough to accomodate <size> bytes. - * Find the oldest texObject and free it. - */ - texObj = tdfxTMFindOldestObject( fxMesa, unit ); - if ( texObj ) { - tdfxTMMoveOutTMLocked( fxMesa, texObj ); - fxMesa->stats.texSwaps++; - } else { - gl_problem( NULL, "tdfx driver: extreme texmem fragmentation" ); - _glthread_UNLOCK_MUTEX( ss->Mutex ); - return BAD_ADDRESS; - } - } + struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; + struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; + tdfxMemRange *prev, *block; + FxU32 result; +#if 0 + int discardedCount = 0; +#define MAX_DISCARDS 10 +#endif - /* never get here, but play it safe */ - _glthread_UNLOCK_MUTEX( ss->Mutex ); - return BAD_ADDRESS; + if (shared->umaTexMemory) { + assert(tmu == TDFX_TMU0); + } + + _glthread_LOCK_MUTEX(mesaShared->Mutex); + while (1) { + prev = NULL; + block = shared->tmFree[tmu]; + while (block) { + if (block->endAddr - block->startAddr >= size) { + /* The texture will fit here */ + result = block->startAddr; + block->startAddr += size; + if (block->startAddr == block->endAddr) { + /* Remove this node since it's empty */ + if (prev) { + prev->next = block->next; + } + else { + shared->tmFree[tmu] = block->next; + } + DELETE_RANGE_NODE(shared, block); + } + shared->freeTexMem[tmu] -= size; + _glthread_UNLOCK_MUTEX(mesaShared->Mutex); + return result; + } + prev = block; + block = block->next; + } + /* We failed to find a block large enough to accomodate <size> bytes. + * Find the oldest texObject and free it. + */ +#if 0 + discardedCount++; + if (discardedCount > MAX_DISCARDS + 1) { + _mesa_problem(NULL, "tdfx driver: extreme texmem fragmentation"); + _glthread_UNLOCK_MUTEX(mesaShared->Mutex); + return BAD_ADDRESS; + } + else if (discardedCount > MAX_DISCARDS) { + /* texture memory is probably really fragmented, flush it */ + FlushTexMemory(fxMesa); + } + else +#endif + { + struct gl_texture_object *obj = FindOldestObject(fxMesa, tmu); + if (obj) { + tdfxTMMoveOutTM_NoLock(fxMesa, obj); + fxMesa->stats.texSwaps++; + } + else { + _mesa_problem(NULL, "tdfx driver: extreme texmem fragmentation"); + _glthread_UNLOCK_MUTEX(mesaShared->Mutex); + return BAD_ADDRESS; + } + } + } + + /* never get here, but play it safe */ + _glthread_UNLOCK_MUTEX(mesaShared->Mutex); + return BAD_ADDRESS; } -/* Remove the given tdfxMemRange node from hardware texture memory. +/* + * Remove the given tdfxMemRange node from hardware texture memory. */ -static void tdfxTMRemoveRangeLocked( tdfxContextPtr fxMesa, - FxU32 unit, tdfxMemRange *range ) +static void +RemoveRange_NoLock(tdfxContextPtr fxMesa, FxU32 tmu, tdfxMemRange *range) { - struct gl_shared_state *ss = fxMesa->glCtx->Shared; - tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ss->DriverData; - tdfxMemRange *block, *prev; - - if ( tss->umaTexMemory ) { - assert( unit == TDFX_TMU0 ); - } - - if ( !range ) - return; + struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; + struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; + tdfxMemRange *block, *prev; + + if (shared->umaTexMemory) { + assert(tmu == TDFX_TMU0); + } + + if (!range) + return; + + if (range->startAddr == range->endAddr) { + DELETE_RANGE_NODE(shared, range); + return; + } + shared->freeTexMem[tmu] += range->endAddr - range->startAddr; + + /* find position in linked list to insert this tdfxMemRange node */ + prev = NULL; + block = shared->tmFree[tmu]; + while (block) { + assert(range->startAddr != block->startAddr); + if (range->startAddr > block->startAddr) { + prev = block; + block = block->next; + } + else { + break; + } + } + + /* Insert the free block, combine with adjacent blocks when possible */ + range->next = block; + if (block) { + if (range->endAddr == block->startAddr) { + /* Combine */ + block->startAddr = range->startAddr; + DELETE_RANGE_NODE(shared, range); + range = block; + } + } + if (prev) { + if (prev->endAddr == range->startAddr) { + /* Combine */ + prev->endAddr = range->endAddr; + prev->next = range->next; + DELETE_RANGE_NODE(shared, range); + } + else { + prev->next = range; + } + } + else { + shared->tmFree[tmu] = range; + } +} - if ( range->startAddr == range->endAddr ) { - DELETE_RANGE_NODE( tss, range ); - return; - } - tss->freeTexMem[unit] += range->endAddr - range->startAddr; - - /* find position in linked list to insert this tdfxMemRange node */ - prev = NULL; - block = tss->freeRanges[unit]; - while ( block ) { - assert( range->startAddr != block->startAddr ); - if ( range->startAddr > block->startAddr ) { - prev = block; - block = block->next; - } else { - break; - } - } - /* Insert the free block, combine with adjacent blocks when possible */ - range->next = block; - if ( block ) { - if ( range->endAddr == block->startAddr ) { - /* Combine */ - block->startAddr = range->startAddr; - DELETE_RANGE_NODE( tss, range ); - range = block; - } - } - if ( prev ) { - if ( prev->endAddr == range->startAddr ) { - /* Combine */ - prev->endAddr = range->endAddr; - prev->next = range->next; - DELETE_RANGE_NODE( tss, range ); - } else { - prev->next = range; - } - } else { - tss->freeRanges[unit] = range; - } +#if 0 /* NOT USED */ +static void +RemoveRange(tdfxContextPtr fxMesa, FxU32 tmu, tdfxMemRange *range) +{ + struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; + _glthread_LOCK_MUTEX(mesaShared->Mutex); + RemoveRange_NoLock(fxMesa, tmu, range); + _glthread_UNLOCK_MUTEX(mesaShared->Mutex); } +#endif -/* Allocate space for a texture image. +/* + * Allocate space for a texture image. * <tmu> is the texture unit * <texmemsize> is the number of bytes to allocate */ static tdfxMemRange * -tdfxTMAllocTexMem( tdfxContextPtr fxMesa, FxU32 unit, FxU32 size ) +AllocTexMem(tdfxContextPtr fxMesa, FxU32 tmu, FxU32 texmemsize) { - tdfxMemRange *range = NULL; - FxU32 start; - - start = tdfxTMFindStartAddr( fxMesa, unit, size ); - - if ( start != BAD_ADDRESS ) { - range = tdfxTMNewRangeNode( fxMesa, start, start + size ); - } else { - fprintf( stderr, - "tdfxTMAllocTexMem returned NULL! unit=%ld size=%ld\n", - unit, size ); - } - return range; + FxU32 startAddr; + startAddr = FindStartAddr(fxMesa, tmu, texmemsize); + if (startAddr == BAD_ADDRESS) { + char err[100]; + sprintf(err, "AllocTexMem returned NULL! tmu=%d texmemsize=%d\n", + (int) tmu, (int) texmemsize); + _mesa_problem(fxMesa->glCtx, err); + return NULL; + } + else { + tdfxMemRange *range; + range = NewRangeNode(fxMesa, startAddr, startAddr + texmemsize); + return range; + } } -/* Download (copy) the given texture data (all mipmap levels) into the - * Voodoo's texture memory. The texture memory must have already been - * allocated. +/* + * Download (copy) the given texture data (all mipmap levels) into the + * Voodoo's texture memory. + * The texture memory must have already been allocated. */ -void tdfxTMDownloadTextureLocked( tdfxContextPtr fxMesa, - struct gl_texture_object *tObj ) +void +tdfxTMDownloadTexture(tdfxContextPtr fxMesa, struct gl_texture_object *tObj) { - tdfxTexObjPtr t = TDFX_TEXTURE_DATA(tObj); - FxU32 targetTMU; - GLint l; - - assert( tObj ); - assert( t ); - - targetTMU = t->whichTMU; - - switch ( targetTMU ) { - case TDFX_TMU0: - case TDFX_TMU1: - if ( t->range[targetTMU] ) { - for ( l = t->minLevel ; l <= t->maxLevel && t->image[l].data ; l++ ) { - GrLOD_t glideLod = t->info.largeLodLog2 - l + tObj->BaseLevel; - - fxMesa->Glide.grTexDownloadMipMapLevel( targetTMU, - t->range[targetTMU]->startAddr, - glideLod, - t->info.largeLodLog2, - t->info.aspectRatioLog2, - t->info.format, - GR_MIPMAPLEVELMASK_BOTH, - t->image[l].data ); - } - } - break; - - case TDFX_TMU_SPLIT: - if ( t->range[TDFX_TMU0] && t->range[TDFX_TMU1] ) { - for ( l = t->minLevel ; l <= t->maxLevel && t->image[l].data ; l++ ) { - GrLOD_t glideLod = t->info.largeLodLog2 - l + tObj->BaseLevel; - - fxMesa->Glide.grTexDownloadMipMapLevel( GR_TMU0, - t->range[TDFX_TMU0]->startAddr, - glideLod, - t->info.largeLodLog2, - t->info.aspectRatioLog2, - t->info.format, - GR_MIPMAPLEVELMASK_ODD, - t->image[l].data ); - - fxMesa->Glide.grTexDownloadMipMapLevel( GR_TMU1, - t->range[TDFX_TMU1]->startAddr, - glideLod, - t->info.largeLodLog2, - t->info.aspectRatioLog2, - t->info.format, - GR_MIPMAPLEVELMASK_EVEN, - t->image[l].data ); - } - } - break; - - case TDFX_TMU_BOTH: - if ( t->range[TDFX_TMU0] && t->range[TDFX_TMU1] ) { - for ( l = t->minLevel ; l <= t->maxLevel && t->image[l].data ; l++ ) { - GrLOD_t glideLod = t->info.largeLodLog2 - l + tObj->BaseLevel; - - fxMesa->Glide.grTexDownloadMipMapLevel( GR_TMU0, - t->range[TDFX_TMU0]->startAddr, - glideLod, - t->info.largeLodLog2, - t->info.aspectRatioLog2, - t->info.format, - GR_MIPMAPLEVELMASK_BOTH, - t->image[l].data ); - - fxMesa->Glide.grTexDownloadMipMapLevel( GR_TMU1, - t->range[TDFX_TMU1]->startAddr, - glideLod, - t->info.largeLodLog2, - t->info.aspectRatioLog2, - t->info.format, - GR_MIPMAPLEVELMASK_BOTH, - t->image[l].data ); - } - } - break; - - default: - gl_problem( NULL, "error in tdfxTMDownloadTexture: bad unit" ); - return; - } + tdfxTexInfo *ti; + GLint l; + FxU32 targetTMU; + + assert(tObj); + ti = TDFX_TEXTURE_DATA(tObj); + assert(ti); + targetTMU = ti->whichTMU; + + switch (targetTMU) { + case TDFX_TMU0: + case TDFX_TMU1: + if (ti->tm[targetTMU]) { + for (l = ti->minLevel; l <= ti->maxLevel + && tObj->Image[l]->Data; l++) { + GrLOD_t glideLod = ti->info.largeLodLog2 - l + tObj->BaseLevel; + fxMesa->Glide.grTexDownloadMipMapLevel(targetTMU, + ti->tm[targetTMU]->startAddr, + glideLod, + ti->info.largeLodLog2, + ti->info.aspectRatioLog2, + ti->info.format, + GR_MIPMAPLEVELMASK_BOTH, + tObj->Image[l]->Data); + } + } + break; + case TDFX_TMU_SPLIT: + if (ti->tm[TDFX_TMU0] && ti->tm[TDFX_TMU1]) { + for (l = ti->minLevel; l <= ti->maxLevel + && tObj->Image[l]->Data; l++) { + GrLOD_t glideLod = ti->info.largeLodLog2 - l + tObj->BaseLevel; + fxMesa->Glide.grTexDownloadMipMapLevel(GR_TMU0, + ti->tm[TDFX_TMU0]->startAddr, + glideLod, + ti->info.largeLodLog2, + ti->info.aspectRatioLog2, + ti->info.format, + GR_MIPMAPLEVELMASK_ODD, + tObj->Image[l]->Data); + + fxMesa->Glide.grTexDownloadMipMapLevel(GR_TMU1, + ti->tm[TDFX_TMU1]->startAddr, + glideLod, + ti->info.largeLodLog2, + ti->info.aspectRatioLog2, + ti->info.format, + GR_MIPMAPLEVELMASK_EVEN, + tObj->Image[l]->Data); + } + } + break; + case TDFX_TMU_BOTH: + if (ti->tm[TDFX_TMU0] && ti->tm[TDFX_TMU1]) { + for (l = ti->minLevel; l <= ti->maxLevel + && tObj->Image[l]->Data; l++) { + GrLOD_t glideLod = ti->info.largeLodLog2 - l + tObj->BaseLevel; + fxMesa->Glide.grTexDownloadMipMapLevel(GR_TMU0, + ti->tm[TDFX_TMU0]->startAddr, + glideLod, + ti->info.largeLodLog2, + ti->info.aspectRatioLog2, + ti->info.format, + GR_MIPMAPLEVELMASK_BOTH, + tObj->Image[l]->Data); + + fxMesa->Glide.grTexDownloadMipMapLevel(GR_TMU1, + ti->tm[TDFX_TMU1]->startAddr, + glideLod, + ti->info.largeLodLog2, + ti->info.aspectRatioLog2, + ti->info.format, + GR_MIPMAPLEVELMASK_BOTH, + tObj->Image[l]->Data); + } + } + break; + default: + _mesa_problem(NULL, "error in tdfxTMDownloadTexture: bad tmu"); + return; + } } -void tdfxTMReloadMipMapLevelLocked( GLcontext *ctx, - struct gl_texture_object *tObj, - GLint level ) +void +tdfxTMReloadMipMapLevel(GLcontext *ctx, struct gl_texture_object *tObj, + GLint level) { - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - tdfxTexObjPtr t = TDFX_TEXTURE_DATA(tObj); - GrLOD_t glideLod; - FxU32 unit; - - ASSERT( t->isInTM ); - - unit = t->whichTMU; - glideLod = t->info.largeLodLog2 - level + tObj->BaseLevel; - - switch ( unit ) { - case TDFX_TMU0: - case TDFX_TMU1: - fxMesa->Glide.grTexDownloadMipMapLevel( unit, - t->range[unit]->startAddr, - glideLod, - t->info.largeLodLog2, - t->info.aspectRatioLog2, - t->info.format, - GR_MIPMAPLEVELMASK_BOTH, - t->image[level].data ); - break; - - case TDFX_TMU_SPLIT: - fxMesa->Glide.grTexDownloadMipMapLevel( GR_TMU0, - t->range[GR_TMU0]->startAddr, - glideLod, - t->info.largeLodLog2, - t->info.aspectRatioLog2, - t->info.format, - GR_MIPMAPLEVELMASK_ODD, - t->image[level].data ); - - fxMesa->Glide.grTexDownloadMipMapLevel( GR_TMU1, - t->range[GR_TMU1]->startAddr, - glideLod, - t->info.largeLodLog2, - t->info.aspectRatioLog2, - t->info.format, - GR_MIPMAPLEVELMASK_EVEN, - t->image[level].data ); - break; - - case TDFX_TMU_BOTH: - fxMesa->Glide.grTexDownloadMipMapLevel( GR_TMU0, - t->range[GR_TMU0]->startAddr, - glideLod, - t->info.largeLodLog2, - t->info.aspectRatioLog2, - t->info.format, - GR_MIPMAPLEVELMASK_BOTH, - t->image[level].data ); - - fxMesa->Glide.grTexDownloadMipMapLevel( GR_TMU1, - t->range[GR_TMU1]->startAddr, - glideLod, - t->info.largeLodLog2, - t->info.aspectRatioLog2, - t->info.format, - GR_MIPMAPLEVELMASK_BOTH, - t->image[level].data ); - break; - - default: - gl_problem( ctx, "error in tdfxTMReloadMipMapLevel(): wrong unit" ); - break; - } + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj); + GrLOD_t glideLod; + FxU32 tmu; + + tmu = ti->whichTMU; + glideLod = ti->info.largeLodLog2 - level + tObj->BaseLevel; + ASSERT(ti->isInTM); + + LOCK_HARDWARE(fxMesa); + + switch (tmu) { + case TDFX_TMU0: + case TDFX_TMU1: + fxMesa->Glide.grTexDownloadMipMapLevel(tmu, + ti->tm[tmu]->startAddr, + glideLod, + ti->info.largeLodLog2, + ti->info.aspectRatioLog2, + ti->info.format, + GR_MIPMAPLEVELMASK_BOTH, + tObj->Image[level]->Data); + break; + case TDFX_TMU_SPLIT: + fxMesa->Glide.grTexDownloadMipMapLevel(GR_TMU0, + ti->tm[GR_TMU0]->startAddr, + glideLod, + ti->info.largeLodLog2, + ti->info.aspectRatioLog2, + ti->info.format, + GR_MIPMAPLEVELMASK_ODD, + tObj->Image[level]->Data); + + fxMesa->Glide.grTexDownloadMipMapLevel(GR_TMU1, + ti->tm[GR_TMU1]->startAddr, + glideLod, + ti->info.largeLodLog2, + ti->info.aspectRatioLog2, + ti->info.format, + GR_MIPMAPLEVELMASK_EVEN, + tObj->Image[level]->Data); + break; + case TDFX_TMU_BOTH: + fxMesa->Glide.grTexDownloadMipMapLevel(GR_TMU0, + ti->tm[GR_TMU0]->startAddr, + glideLod, + ti->info.largeLodLog2, + ti->info.aspectRatioLog2, + ti->info.format, + GR_MIPMAPLEVELMASK_BOTH, + tObj->Image[level]->Data); + + fxMesa->Glide.grTexDownloadMipMapLevel(GR_TMU1, + ti->tm[GR_TMU1]->startAddr, + glideLod, + ti->info.largeLodLog2, + ti->info.aspectRatioLog2, + ti->info.format, + GR_MIPMAPLEVELMASK_BOTH, + tObj->Image[level]->Data); + break; + + default: + _mesa_problem(ctx, "error in tdfxTMReloadMipMapLevel(): wrong tmu"); + break; + } + UNLOCK_HARDWARE(fxMesa); } -/* Allocate space for the given texture in texture memory then +/* + * Allocate space for the given texture in texture memory then * download (copy) it into that space. */ -void tdfxTMMoveInTMLocked( tdfxContextPtr fxMesa, - struct gl_texture_object *tObj, FxU32 targetTMU ) +void +tdfxTMMoveInTM_NoLock( tdfxContextPtr fxMesa, struct gl_texture_object *tObj, + FxU32 targetTMU ) { - tdfxTexObjPtr t = TDFX_TEXTURE_DATA(tObj); - FxU32 size; - - fxMesa->stats.reqTexUpload++; - - if ( t->isInTM ) { - if ( t->whichTMU == targetTMU ) - return; - - if ( targetTMU == TDFX_TMU_SPLIT || t->whichTMU == TDFX_TMU_SPLIT ) { - tdfxTMMoveOutTMLocked( fxMesa, tObj ); - } else { - if ( t->whichTMU == TDFX_TMU_BOTH ) - return; - targetTMU = TDFX_TMU_BOTH; - } - } - - t->whichTMU = targetTMU; - - switch ( targetTMU ) { - case TDFX_TMU0: - case TDFX_TMU1: - size = fxMesa->Glide.grTexTextureMemRequired( GR_MIPMAPLEVELMASK_BOTH, &t->info ); - t->range[targetTMU] = tdfxTMAllocTexMem(fxMesa, targetTMU, size); - break; - - case TDFX_TMU_SPLIT: - size = fxMesa->Glide.grTexTextureMemRequired( GR_MIPMAPLEVELMASK_ODD, &t->info ); - t->range[TDFX_TMU0] = tdfxTMAllocTexMem( fxMesa, TDFX_TMU0, size ); - if ( t->range[TDFX_TMU0] ) - fxMesa->stats.memTexUpload += size; - - size = fxMesa->Glide.grTexTextureMemRequired( GR_MIPMAPLEVELMASK_EVEN, &t->info ); - t->range[TDFX_TMU1] = tdfxTMAllocTexMem( fxMesa, TDFX_TMU1, size ); - break; - - case TDFX_TMU_BOTH: - size = fxMesa->Glide.grTexTextureMemRequired( GR_MIPMAPLEVELMASK_BOTH, &t->info ); - t->range[TDFX_TMU0] = tdfxTMAllocTexMem( fxMesa, TDFX_TMU0, size ); - if ( t->range[TDFX_TMU0] ) - fxMesa->stats.memTexUpload += size; - - size = fxMesa->Glide.grTexTextureMemRequired( GR_MIPMAPLEVELMASK_BOTH, &t->info ); - t->range[TDFX_TMU1] = tdfxTMAllocTexMem( fxMesa, TDFX_TMU1, size ); - break; - - default: - gl_problem( NULL, "error in tdfxTMMoveInTM() -> bad unit (%d)" ); - return; - } - - t->reloadImages = GL_TRUE; - t->isInTM = GL_TRUE; - - fxMesa->stats.texUpload++; + tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj); + FxU32 texmemsize; + + fxMesa->stats.reqTexUpload++; + + if (ti->isInTM) { + if (ti->whichTMU == targetTMU) + return; + if (targetTMU == TDFX_TMU_SPLIT || ti->whichTMU == TDFX_TMU_SPLIT) { + tdfxTMMoveOutTM_NoLock(fxMesa, tObj); + } + else { + if (ti->whichTMU == TDFX_TMU_BOTH) + return; + targetTMU = TDFX_TMU_BOTH; + } + } + + ti->whichTMU = targetTMU; + + switch (targetTMU) { + case TDFX_TMU0: + case TDFX_TMU1: + texmemsize = fxMesa->Glide.grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, + &(ti->info)); + ti->tm[targetTMU] = AllocTexMem(fxMesa, targetTMU, texmemsize); + break; + case TDFX_TMU_SPLIT: + texmemsize = fxMesa->Glide.grTexTextureMemRequired(GR_MIPMAPLEVELMASK_ODD, + &(ti->info)); + ti->tm[TDFX_TMU0] = AllocTexMem(fxMesa, TDFX_TMU0, texmemsize); + if (ti->tm[TDFX_TMU0]) + fxMesa->stats.memTexUpload += texmemsize; + + texmemsize = fxMesa->Glide.grTexTextureMemRequired(GR_MIPMAPLEVELMASK_EVEN, + &(ti->info)); + ti->tm[TDFX_TMU1] = AllocTexMem(fxMesa, TDFX_TMU1, texmemsize); + break; + case TDFX_TMU_BOTH: + texmemsize = fxMesa->Glide.grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, + &(ti->info)); + ti->tm[TDFX_TMU0] = AllocTexMem(fxMesa, TDFX_TMU0, texmemsize); + if (ti->tm[TDFX_TMU0]) + fxMesa->stats.memTexUpload += texmemsize; + + texmemsize = fxMesa->Glide.grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, + &(ti->info)); + ti->tm[TDFX_TMU1] = AllocTexMem(fxMesa, TDFX_TMU1, texmemsize); + break; + default: + _mesa_problem(NULL, "error in tdfxTMMoveInTM() -> bad tmu (%d)"); + return; + } + + ti->reloadImages = GL_TRUE; + ti->isInTM = GL_TRUE; + + fxMesa->stats.texUpload++; } -/* Move the given texture out of hardware texture memory. +/* + * Move the given texture out of hardware texture memory. * This deallocates the texture's memory space. */ -void tdfxTMMoveOutTMLocked( tdfxContextPtr fxMesa, - struct gl_texture_object *tObj ) +void +tdfxTMMoveOutTM_NoLock( tdfxContextPtr fxMesa, struct gl_texture_object *tObj ) { - struct gl_shared_state *ss = fxMesa->glCtx->Shared; - tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ss->DriverData; - tdfxTexObjPtr t = TDFX_TEXTURE_DATA(tObj); - - if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE ) { - fprintf( stderr, __FUNCTION__ "( %p (%d) )\n", tObj, tObj->Name ); - tdfxTMVerifyFreeList( fxMesa, 0 ); - tdfxTMVerifyFreeList( fxMesa, 1 ); - } - - if ( !t || !t->isInTM ) - return; - - switch ( t->whichTMU ) { - case TDFX_TMU0: - case TDFX_TMU1: - tdfxTMRemoveRangeLocked( fxMesa, t->whichTMU, t->range[t->whichTMU] ); - break; - - case TDFX_TMU_SPLIT: - case TDFX_TMU_BOTH: - assert( !tss->umaTexMemory ); - tdfxTMRemoveRangeLocked( fxMesa, TDFX_TMU0, t->range[TDFX_TMU0] ); - tdfxTMRemoveRangeLocked( fxMesa, TDFX_TMU1, t->range[TDFX_TMU1] ); - break; - - default: - gl_problem( NULL, "tdfx driver: bad unit in tdfxTMMOveOutTM()" ); - return; - } - - t->isInTM = GL_FALSE; - t->range[0] = NULL; - t->range[1] = NULL; - t->whichTMU = TDFX_TMU_NONE; - - if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE ) { - tdfxTMVerifyFreeList( fxMesa, 0 ); - tdfxTMVerifyFreeList( fxMesa, 1 ); - } + struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; + struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; + tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj); + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxTMMoveOutTM(%p (%d))\n", tObj, tObj->Name); + } + + /* + VerifyFreeList(fxMesa, 0); + VerifyFreeList(fxMesa, 1); + */ + + if (!ti || !ti->isInTM) + return; + + switch (ti->whichTMU) { + case TDFX_TMU0: + case TDFX_TMU1: + RemoveRange_NoLock(fxMesa, ti->whichTMU, ti->tm[ti->whichTMU]); + break; + case TDFX_TMU_SPLIT: + case TDFX_TMU_BOTH: + assert(!shared->umaTexMemory); + RemoveRange_NoLock(fxMesa, TDFX_TMU0, ti->tm[TDFX_TMU0]); + RemoveRange_NoLock(fxMesa, TDFX_TMU1, ti->tm[TDFX_TMU1]); + break; + default: + _mesa_problem(NULL, "tdfx driver: bad tmu in tdfxTMMOveOutTM()"); + return; + } + + ti->isInTM = GL_FALSE; + ti->tm[0] = NULL; + ti->tm[1] = NULL; + ti->whichTMU = TDFX_TMU_NONE; + + /* + VerifyFreeList(fxMesa, 0); + VerifyFreeList(fxMesa, 1); + */ } -void tdfxTMFreeTextureLocked( tdfxContextPtr fxMesa, - struct gl_texture_object *tObj ) +/* + * Called via glDeleteTexture to delete a texture object. + */ +void +tdfxTMFreeTexture(tdfxContextPtr fxMesa, struct gl_texture_object *tObj) { - tdfxTexObjPtr t = TDFX_TEXTURE_DATA(tObj); - - if ( t ) { - int i; - tdfxTMMoveOutTMLocked( fxMesa, tObj ); - for ( i = 0 ; i < MAX_TEXTURE_LEVELS ; i++ ) { - if ( t->image[i].original.data ) FREE( t->image[i].original.data ); - if ( t->image[i].rescaled.data ) FREE( t->image[i].rescaled.data ); - } - FREE( t ); - tObj->DriverData = NULL; - } - - if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE ) { - tdfxTMVerifyFreeList( fxMesa, 0 ); - tdfxTMVerifyFreeList( fxMesa, 1 ); - } + tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj); + if (ti) { + tdfxTMMoveOutTM(fxMesa, tObj); + FREE(ti); + tObj->DriverData = NULL; + } + /* + VerifyFreeList(fxMesa, 0); + VerifyFreeList(fxMesa, 1); + */ } -/* After a context switch this function will be called to restore + +/* + * After a context switch this function will be called to restore * texture memory for the new context. */ -void tdfxTMRestoreTexturesLocked( tdfxContextPtr fxMesa ) +void tdfxTMRestoreTextures_NoLock( tdfxContextPtr fxMesa ) { GLcontext *ctx = fxMesa->glCtx; struct gl_texture_object *tObj; int i; for ( tObj = ctx->Shared->TexObjectList ; tObj ; tObj = tObj->Next ) { - tdfxTexObjPtr t = TDFX_TEXTURE_DATA( tObj ); - if ( t && t->isInTM ) { + tdfxTexInfo *ti = TDFX_TEXTURE_DATA( tObj ); + if ( ti && ti->isInTM ) { for ( i = 0 ; i < MAX_TEXTURE_UNITS ; i++ ) { - if ( ctx->Texture.Unit[i].Current == tObj ) { - tdfxTMDownloadTextureLocked( fxMesa, tObj ); + if ( ctx->Texture.Unit[i]._Current == tObj ) { + tdfxTMDownloadTexture( fxMesa, tObj ); break; } } if ( i == MAX_TEXTURE_UNITS ) { - tdfxTMMoveOutTMLocked( fxMesa, tObj ); + tdfxTMMoveOutTM_NoLock( fxMesa, tObj ); } } } - - if ( TDFX_DEBUG & DEBUG_VERBOSE_TEXTURE ) { - tdfxTMVerifyFreeList( fxMesa, 0 ); - tdfxTMVerifyFreeList( fxMesa, 1 ); - } + /* + VerifyFreeList(fxMesa, 0); + VerifyFreeList(fxMesa, 1); + */ } diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.h b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.h index 485d8cf3b..1965aaa84 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.h +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.h @@ -23,7 +23,7 @@ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.h,v 1.1 2001/03/21 16:14:28 dawes Exp $ */ +/* $XFree86$ */ /* * Original rewrite: @@ -38,39 +38,47 @@ #ifndef __TDFX_TEXMAN_H__ #define __TDFX_TEXMAN_H__ + #include "tdfx_lock.h" + extern void tdfxTMInit( tdfxContextPtr fxMesa ); + extern void tdfxTMClose( tdfxContextPtr fxMesa ); -extern void tdfxTMDownloadTextureLocked( tdfxContextPtr fxMesa, - struct gl_texture_object *tObj ); -extern void tdfxTMReloadMipMapLevelLocked( GLcontext *ctx, - struct gl_texture_object *tObj, - GLint level ); -extern void tdfxTMMoveInTMLocked( tdfxContextPtr fxMesa, - struct gl_texture_object *tObj, - FxU32 targetTMU ); -extern void tdfxTMMoveOutTMLocked( tdfxContextPtr fxMesa, - struct gl_texture_object *tObj ); -extern void tdfxTMRestoreTexturesLocked( tdfxContextPtr fxMesa ); - -extern void tdfxTMFreeTextureLocked( tdfxContextPtr fxMesa, - struct gl_texture_object *tObj ); - - -#define tdfxTMMoveInTM( fxMesa, tObj, targetTMU ) \ -do { \ - LOCK_HARDWARE( fxMesa ); \ - tdfxTMMoveInTMLocked( fxMesa, tObj, targetTMU ); \ - UNLOCK_HARDWARE( fxMesa ); \ -} while (0) - -#define tdfxTMMoveOutTM( fxMesa, tObj ) \ -do { \ - LOCK_HARDWARE( fxMesa ); \ - tdfxTMMoveOutTMLocked( fxMesa, tObj ); \ - UNLOCK_HARDWARE( fxMesa ); \ -} while (0) +extern void tdfxTMDownloadTexture(tdfxContextPtr fxMesa, + struct gl_texture_object *tObj); + +extern void tdfxTMReloadMipMapLevel( GLcontext *ctx, + struct gl_texture_object *tObj, + GLint level ); + +extern void tdfxTMMoveInTM_NoLock( tdfxContextPtr fxMesa, + struct gl_texture_object *tObj, + FxU32 targetTMU ); + +extern void tdfxTMMoveOutTM_NoLock( tdfxContextPtr fxMesa, + struct gl_texture_object *tObj ); + +extern void tdfxTMFreeTexture( tdfxContextPtr fxMesa, + struct gl_texture_object *tObj ); + +extern void tdfxTMRestoreTextures_NoLock( tdfxContextPtr fxMesa ); + + +#define tdfxTMMoveInTM( fxMesa, tObj, targetTMU ) \ + do { \ + LOCK_HARDWARE( fxMesa ); \ + tdfxTMMoveInTM_NoLock( fxMesa, tObj, targetTMU ); \ + UNLOCK_HARDWARE( fxMesa ); \ + } while (0) + +#define tdfxTMMoveOutTM( fxMesa, tObj ) \ + do { \ + LOCK_HARDWARE( fxMesa ); \ + tdfxTMMoveOutTM_NoLock( fxMesa, tObj ); \ + UNLOCK_HARDWARE( fxMesa ); \ + } while (0) + #endif diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texstate.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texstate.c index a32dd431d..ccffeff5e 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texstate.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texstate.c @@ -23,7 +23,7 @@ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_texstate.c,v 1.1 2001/03/21 16:14:28 dawes Exp $ */ +/* $XFree86$ */ /* * Original rewrite: @@ -38,6 +38,7 @@ #include "tdfx_state.h" #include "tdfx_tex.h" #include "tdfx_texman.h" +#include "tdfx_texstate.h" /* ============================================================= @@ -656,7 +657,7 @@ SetupTexEnvNapalm(GLcontext *ctx, GLboolean useIteratedRGBA, texUnit->CombineOperandA[1], incomingAlpha); TEXENV_SETUP_MODE_A(Bmode_A, - texUnit->CombineOperandA[0]); + texUnit->CombineOperandA[1]); C_A = D_A = GR_CMBX_ZERO; Cinv_A = FXTRUE; Dinv_A = Ginv_A = FXFALSE; @@ -751,7 +752,7 @@ SetupTexEnvNapalm(GLcontext *ctx, GLboolean useIteratedRGBA, texUnit->CombineOperandA[2], incomingAlpha); Cinv_A = FXFALSE; - D_A = GR_CMBX_ZERO; + D_A = GR_CMBX_B; Dinv_A = Ginv_A = FXFALSE; break; default: @@ -798,7 +799,7 @@ SetupTexEnvNapalm(GLcontext *ctx, GLboolean useIteratedRGBA, break; default: - gl_problem(ctx, "Bad envMode in SetupTexEnvNapalm"); + _mesa_problem(ctx, "Bad envMode in SetupTexEnvNapalm"); } fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_ENV; @@ -1008,7 +1009,7 @@ SetupSingleTexEnvVoodoo3(GLcontext *ctx, int unit, break; default: - gl_problem(NULL, "bad texture env mode in SetupSingleTexEnvVoodoo3"); + _mesa_problem(NULL, "bad texture env mode in SetupSingleTexEnvVoodoo3"); } if (colorComb.Function != fxMesa->ColorCombine.Function || @@ -1250,7 +1251,7 @@ SetupDoubleTexEnvVoodoo3(GLcontext *ctx, int tmu0, fxMesa->AlphaCombine.Invert = FXFALSE; } else { - /*gl_problem(ctx, "Unexpected dual texture mode encountered\n");*/ + /*_mesa_problem(ctx, "Unexpected dual texture mode encountered\n");*/ return GL_FALSE; } @@ -1269,105 +1270,105 @@ SetupDoubleTexEnvVoodoo3(GLcontext *ctx, int tmu0, static void setupSingleTMU(tdfxContextPtr fxMesa, struct gl_texture_object *tObj) { + struct tdfxSharedState *shared = (struct tdfxSharedState *) fxMesa->glCtx->Shared->DriverData; + tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj); const GLcontext *ctx = fxMesa->glCtx; - tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ctx->Shared->DriverData; - tdfxTexObjPtr t = TDFX_TEXTURE_DATA(tObj); /* Make sure we're not loaded incorrectly */ - if (t->isInTM && !tss->umaTexMemory) { + if (ti->isInTM && !shared->umaTexMemory) { /* if doing filtering between mipmap levels, alternate mipmap levels * must be in alternate TMUs. */ - if (t->LODblend) { - if (t->whichTMU != TDFX_TMU_SPLIT) - tdfxTMMoveOutTMLocked(fxMesa, tObj); + if (ti->LODblend) { + if (ti->whichTMU != TDFX_TMU_SPLIT) + tdfxTMMoveOutTM_NoLock(fxMesa, tObj); } else { - if (t->whichTMU == TDFX_TMU_SPLIT) - tdfxTMMoveOutTMLocked(fxMesa, tObj); + if (ti->whichTMU == TDFX_TMU_SPLIT) + tdfxTMMoveOutTM_NoLock(fxMesa, tObj); } } /* Make sure we're loaded correctly */ - if (!t->isInTM) { + if (!ti->isInTM) { /* Have to download the texture */ - if (tss->umaTexMemory) { - tdfxTMMoveInTMLocked(fxMesa, tObj, TDFX_TMU0); + if (shared->umaTexMemory) { + tdfxTMMoveInTM_NoLock(fxMesa, tObj, TDFX_TMU0); } else { /* Voodoo3 (split texture memory) */ - if (t->LODblend) { - tdfxTMMoveInTMLocked(fxMesa, tObj, TDFX_TMU_SPLIT); + if (ti->LODblend) { + tdfxTMMoveInTM_NoLock(fxMesa, tObj, TDFX_TMU_SPLIT); } else { #if 0 /* XXX putting textures into the second memory bank when the * first bank is full is not working at this time. */ - if (fxMesa->numTMUs > 1) { - GLint memReq = - grTexTextureMemRequired( GR_MIPMAPLEVELMASK_BOTH, &t->info ); - if (tss->freeTexMem[TDFX_TMU0] > memReq) { - tdfxTMMoveInTMLocked(fxMesa, tObj, TDFX_TMU0); + if (fxMesa->haveTwoTMUs) { + GLint memReq = fxMesa->Glide.grTexTextureMemRequired( + GR_MIPMAPLEVELMASK_BOTH, &(ti->info)); + if (shared->freeTexMem[TDFX_TMU0] > memReq) { + tdfxTMMoveInTM_NoLock(fxMesa, tObj, TDFX_TMU0); } else { - tdfxTMMoveInTMLocked(fxMesa, tObj, TDFX_TMU1); + tdfxTMMoveInTM_NoLock(fxMesa, tObj, TDFX_TMU1); } } else #endif { - tdfxTMMoveInTMLocked( fxMesa, tObj, TDFX_TMU0 ); + tdfxTMMoveInTM_NoLock(fxMesa, tObj, TDFX_TMU0); } } } } - if (t->LODblend && t->whichTMU == TDFX_TMU_SPLIT) { + if (ti->LODblend && ti->whichTMU == TDFX_TMU_SPLIT) { /* mipmap levels split between texture banks */ GLint u; - if (t->info.format == GR_TEXFMT_P_8 && !ctx->Texture.SharedPalette) { + if (ti->info.format == GR_TEXFMT_P_8 && !ctx->Texture.SharedPalette) { fxMesa->TexPalette.Type = GR_TEXTABLE_PALETTE_6666_EXT; - fxMesa->TexPalette.Data = &(t->palette); + fxMesa->TexPalette.Data = &(ti->palette); fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PALETTE; } for (u = 0; u < 2; u++) { - fxMesa->TexParams[u].sClamp = t->sClamp; - fxMesa->TexParams[u].tClamp = t->tClamp; - fxMesa->TexParams[u].minFilt = t->minFilt; - fxMesa->TexParams[u].magFilt = t->magFilt; - fxMesa->TexParams[u].mmMode = t->mmMode; - fxMesa->TexParams[u].LODblend = t->LODblend; + fxMesa->TexParams[u].sClamp = ti->sClamp; + fxMesa->TexParams[u].tClamp = ti->tClamp; + fxMesa->TexParams[u].minFilt = ti->minFilt; + fxMesa->TexParams[u].magFilt = ti->magFilt; + fxMesa->TexParams[u].mmMode = ti->mmMode; + fxMesa->TexParams[u].LODblend = ti->LODblend; fxMesa->TexParams[u].LodBias = ctx->Texture.Unit[u].LodBias; } fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PARAMS; - fxMesa->TexSource[0].StartAddress = t->range[TDFX_TMU0]->startAddr; + fxMesa->TexSource[0].StartAddress = ti->tm[TDFX_TMU0]->startAddr; fxMesa->TexSource[0].EvenOdd = GR_MIPMAPLEVELMASK_ODD; - fxMesa->TexSource[0].Info = &(t->info); - fxMesa->TexSource[1].StartAddress = t->range[TDFX_TMU1]->startAddr; + fxMesa->TexSource[0].Info = &(ti->info); + fxMesa->TexSource[1].StartAddress = ti->tm[TDFX_TMU1]->startAddr; fxMesa->TexSource[1].EvenOdd = GR_MIPMAPLEVELMASK_EVEN; - fxMesa->TexSource[1].Info = &(t->info); + fxMesa->TexSource[1].Info = &(ti->info); fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_SOURCE; } else { FxU32 tmu; - if (t->whichTMU == TDFX_TMU_BOTH) + if (ti->whichTMU == TDFX_TMU_BOTH) tmu = TDFX_TMU0; else - tmu = t->whichTMU; + tmu = ti->whichTMU; - if (tss->umaTexMemory) { - assert(t->whichTMU == TDFX_TMU0); + if (shared->umaTexMemory) { + assert(ti->whichTMU == TDFX_TMU0); assert(tmu == TDFX_TMU0); } - if (t->info.format == GR_TEXFMT_P_8 && !ctx->Texture.SharedPalette) { + if (ti->info.format == GR_TEXFMT_P_8 && !ctx->Texture.SharedPalette) { fxMesa->TexPalette.Type = GR_TEXTABLE_PALETTE_6666_EXT; - fxMesa->TexPalette.Data = &(t->palette); + fxMesa->TexPalette.Data = &(ti->palette); fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PALETTE; } @@ -1376,18 +1377,18 @@ setupSingleTMU(tdfxContextPtr fxMesa, struct gl_texture_object *tObj) * texture memory, so perhaps it's not a good idea. */ - if (fxMesa->TexParams[tmu].sClamp != t->sClamp || - fxMesa->TexParams[tmu].tClamp != t->tClamp || - fxMesa->TexParams[tmu].minFilt != t->minFilt || - fxMesa->TexParams[tmu].magFilt != t->magFilt || - fxMesa->TexParams[tmu].mmMode != t->mmMode || + if (fxMesa->TexParams[tmu].sClamp != ti->sClamp || + fxMesa->TexParams[tmu].tClamp != ti->tClamp || + fxMesa->TexParams[tmu].minFilt != ti->minFilt || + fxMesa->TexParams[tmu].magFilt != ti->magFilt || + fxMesa->TexParams[tmu].mmMode != ti->mmMode || fxMesa->TexParams[tmu].LODblend != FXFALSE || fxMesa->TexParams[tmu].LodBias != ctx->Texture.Unit[tmu].LodBias) { - fxMesa->TexParams[tmu].sClamp = t->sClamp; - fxMesa->TexParams[tmu].tClamp = t->tClamp; - fxMesa->TexParams[tmu].minFilt = t->minFilt; - fxMesa->TexParams[tmu].magFilt = t->magFilt; - fxMesa->TexParams[tmu].mmMode = t->mmMode; + fxMesa->TexParams[tmu].sClamp = ti->sClamp; + fxMesa->TexParams[tmu].tClamp = ti->tClamp; + fxMesa->TexParams[tmu].minFilt = ti->minFilt; + fxMesa->TexParams[tmu].magFilt = ti->magFilt; + fxMesa->TexParams[tmu].mmMode = ti->mmMode; fxMesa->TexParams[tmu].LODblend = FXFALSE; fxMesa->TexParams[tmu].LodBias = ctx->Texture.Unit[tmu].LodBias; fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PARAMS; @@ -1396,16 +1397,16 @@ setupSingleTMU(tdfxContextPtr fxMesa, struct gl_texture_object *tObj) /* Glide texture source info */ fxMesa->TexSource[0].Info = NULL; fxMesa->TexSource[1].Info = NULL; - if (t->range[tmu]) { - fxMesa->TexSource[tmu].StartAddress = t->range[tmu]->startAddr; + if (ti->tm[tmu]) { + fxMesa->TexSource[tmu].StartAddress = ti->tm[tmu]->startAddr; fxMesa->TexSource[tmu].EvenOdd = GR_MIPMAPLEVELMASK_BOTH; - fxMesa->TexSource[tmu].Info = &(t->info); + fxMesa->TexSource[tmu].Info = &(ti->info); fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_SOURCE; } } - fxMesa->sScale0 = t->sScale; - fxMesa->tScale0 = t->tScale; + fxMesa->sScale0 = ti->sScale; + fxMesa->tScale0 = ti->tScale; } static void @@ -1419,12 +1420,12 @@ selectSingleTMUSrc(tdfxContextPtr fxMesa, GLint tmu, FxBool LODblend) fxMesa->TexCombine[0].InvertRGB = FXFALSE; fxMesa->TexCombine[0].InvertAlpha = FXFALSE; - if ( fxMesa->numTMUs > 1 ) { - const struct gl_shared_state *ss = fxMesa->glCtx->Shared; - const tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ss->DriverData; + if (fxMesa->haveTwoTMUs) { + const struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; + const struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; int tmu; - if (tss->umaTexMemory) + if (shared->umaTexMemory) tmu = GR_TMU0; else tmu = GR_TMU1; @@ -1446,7 +1447,7 @@ selectSingleTMUSrc(tdfxContextPtr fxMesa, GLint tmu, FxBool LODblend) fxMesa->TexCombine[0].FactorAlpha = GR_COMBINE_FACTOR_NONE; fxMesa->TexCombine[0].InvertRGB = FXFALSE; fxMesa->TexCombine[0].InvertAlpha = FXFALSE; - if ( fxMesa->numTMUs > 1 ) { + if (fxMesa->haveTwoTMUs) { fxMesa->TexCombine[1].FunctionRGB = GR_COMBINE_FUNCTION_ZERO; fxMesa->TexCombine[1].FactorRGB = GR_COMBINE_FACTOR_NONE; fxMesa->TexCombine[1].FunctionAlpha = GR_COMBINE_FUNCTION_ZERO; @@ -1480,19 +1481,19 @@ selectSingleTMUSrc(tdfxContextPtr fxMesa, GLint tmu, FxBool LODblend) static void print_state(tdfxContextPtr fxMesa) { GLcontext *ctx = fxMesa->glCtx; - struct gl_texture_object *tObj0 = ctx->Texture.Unit[0].CurrentD[2]; - struct gl_texture_object *tObj1 = ctx->Texture.Unit[1].CurrentD[2]; + struct gl_texture_object *tObj0 = ctx->Texture.Unit[0].Current2D; + struct gl_texture_object *tObj1 = ctx->Texture.Unit[1].Current2D; GLenum base0 = tObj0->Image[tObj0->BaseLevel] ? tObj0->Image[tObj0->BaseLevel]->Format : 99; GLenum base1 = tObj1->Image[tObj1->BaseLevel] ? tObj1->Image[tObj1->BaseLevel]->Format : 99; - printf("Unit 0: Enabled: GL=%d Gr=%d\n", ctx->Texture.Unit[0].ReallyEnabled, + printf("Unit 0: Enabled: GL=%d Gr=%d\n", ctx->Texture.Unit[0]._ReallyEnabled, fxMesa->TexState.Enabled); printf(" EnvMode: GL=0x%x Gr=0x%x\n", ctx->Texture.Unit[0].EnvMode, fxMesa->TexState.EnvMode[0]); printf(" BaseFmt: GL=0x%x Gr=0x%x\n", base0, fxMesa->TexState.TexFormat[0]); - printf("Unit 1: Enabled: GL=%d Gr=%d\n", ctx->Texture.Unit[1].ReallyEnabled, + printf("Unit 1: Enabled: GL=%d Gr=%d\n", ctx->Texture.Unit[1]._ReallyEnabled, fxMesa->TexState.Enabled); printf(" EnvMode: GL=0x%x Gr:0x%x\n", ctx->Texture.Unit[1].EnvMode, fxMesa->TexState.EnvMode[1]); @@ -1510,48 +1511,39 @@ static void print_state(tdfxContextPtr fxMesa) static void setupTextureSingleTMU(GLcontext * ctx, GLuint unit) { tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - tdfxTexObjPtr t; + tdfxTexInfo *ti; struct gl_texture_object *tObj; int tmu; GLenum envMode, baseFormat; - tObj = ctx->Texture.Unit[unit].CurrentD[2]; - - if (!tObj->Image[tObj->BaseLevel]) { - fprintf(stderr, "tObj->Image[BaseLevel] is nil, how did this happen?!?\n"); - return; - } - + tObj = ctx->Texture.Unit[unit].Current2D; if (tObj->Image[tObj->BaseLevel]->Border > 0) { - fxMesa->Fallback |= TDFX_FALLBACK_TEXTURE_BORDER; + FALLBACK(fxMesa, TDFX_FALLBACK_TEXTURE_BORDER, GL_TRUE); return; } setupSingleTMU(fxMesa, tObj); - t = TDFX_TEXTURE_DATA(tObj); - if (t->whichTMU == TDFX_TMU_BOTH) + ti = TDFX_TEXTURE_DATA(tObj); + if (ti->whichTMU == TDFX_TMU_BOTH) tmu = TDFX_TMU0; else - tmu = t->whichTMU; + tmu = ti->whichTMU; if (fxMesa->tmuSrc != tmu) { - selectSingleTMUSrc(fxMesa, tmu, t->LODblend); + selectSingleTMUSrc(fxMesa, tmu, ti->LODblend); } - if (t->reloadImages) + if (ti->reloadImages) fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_IMAGES; - /* Some texture environments not supported */ - fxMesa->Fallback &= ~TDFX_FALLBACK_TEXTURE_ENV; - /* Check if we really need to update the texenv state */ envMode = ctx->Texture.Unit[unit].EnvMode; baseFormat = tObj->Image[tObj->BaseLevel]->Format; if (TDFX_IS_NAPALM(fxMesa)) { /* see if we really need to update the unit */ - if (fxMesa->TexState.Enabled != ctx->Texture.ReallyEnabled || + if (fxMesa->TexState.Enabled != ctx->Texture._ReallyEnabled || envMode != fxMesa->TexState.EnvMode[0] || envMode == GL_COMBINE_EXT || baseFormat != fxMesa->TexState.TexFormat[0]) { @@ -1560,7 +1552,7 @@ static void setupTextureSingleTMU(GLcontext * ctx, GLuint unit) &ctx->Texture.Unit[unit], baseFormat, &fxMesa->TexCombineExt[0])) { /* software fallback */ - fxMesa->Fallback |= TDFX_FALLBACK_TEXTURE_ENV; + FALLBACK(fxMesa, TDFX_FALLBACK_TEXTURE_ENV, GL_TRUE); } /* disable other unit */ otherEnv = &fxMesa->TexCombineExt[1]; @@ -1585,7 +1577,7 @@ static void setupTextureSingleTMU(GLcontext * ctx, GLuint unit) otherEnv->Alpha.Shift = 0; otherEnv->Alpha.Invert = FXFALSE; - fxMesa->TexState.Enabled = ctx->Texture.ReallyEnabled; + fxMesa->TexState.Enabled = ctx->Texture._ReallyEnabled; fxMesa->TexState.EnvMode[0] = envMode; fxMesa->TexState.TexFormat[0] = baseFormat; fxMesa->TexState.EnvMode[1] = 0; @@ -1596,15 +1588,15 @@ static void setupTextureSingleTMU(GLcontext * ctx, GLuint unit) /* Voodoo3 */ /* see if we really need to update the unit */ - if (fxMesa->TexState.Enabled != ctx->Texture.ReallyEnabled || + if (fxMesa->TexState.Enabled != ctx->Texture._ReallyEnabled || envMode != fxMesa->TexState.EnvMode[0] || envMode == GL_COMBINE_EXT || baseFormat != fxMesa->TexState.TexFormat[0]) { if (!SetupSingleTexEnvVoodoo3(ctx, tmu, envMode, baseFormat)) { /* software fallback */ - fxMesa->Fallback |= TDFX_FALLBACK_TEXTURE_ENV; + FALLBACK(fxMesa, TDFX_FALLBACK_TEXTURE_ENV, GL_TRUE); } - fxMesa->TexState.Enabled = ctx->Texture.ReallyEnabled; + fxMesa->TexState.Enabled = ctx->Texture._ReallyEnabled; fxMesa->TexState.EnvMode[0] = envMode; fxMesa->TexState.TexFormat[0] = baseFormat; fxMesa->TexState.EnvMode[1] = 0; @@ -1626,35 +1618,35 @@ setupDoubleTMU(tdfxContextPtr fxMesa, #define T0_IN_TMU1 0x10 #define T1_IN_TMU1 0x20 - const struct gl_shared_state *ss = fxMesa->glCtx->Shared; - const tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ss->DriverData; + const struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; + const struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; const GLcontext *ctx = fxMesa->glCtx; - tdfxTexObjPtr t0 = TDFX_TEXTURE_DATA(tObj0); - tdfxTexObjPtr t1 = TDFX_TEXTURE_DATA(tObj1); + tdfxTexInfo *ti0 = TDFX_TEXTURE_DATA(tObj0); + tdfxTexInfo *ti1 = TDFX_TEXTURE_DATA(tObj1); GLuint tstate = 0; int tmu0 = 0, tmu1 = 1; - if (tss->umaTexMemory) { - if (!t0->isInTM) { - tdfxTMMoveInTMLocked(fxMesa, tObj0, TDFX_TMU0); - assert(t0->isInTM); + if (shared->umaTexMemory) { + if (!ti0->isInTM) { + tdfxTMMoveInTM_NoLock(fxMesa, tObj0, TDFX_TMU0); + assert(ti0->isInTM); } - if (!t1->isInTM) { - tdfxTMMoveInTMLocked(fxMesa, tObj1, TDFX_TMU0); - assert(t1->isInTM); + if (!ti1->isInTM) { + tdfxTMMoveInTM_NoLock(fxMesa, tObj1, TDFX_TMU0); + assert(ti1->isInTM); } } else { /* We shouldn't need to do this. There is something wrong with multitexturing when the TMUs are swapped. So, we're forcing them to always be loaded correctly. !!! */ - if (t0->whichTMU == TDFX_TMU1) - tdfxTMMoveOutTMLocked(fxMesa, tObj0); - if (t1->whichTMU == TDFX_TMU0) - tdfxTMMoveOutTMLocked(fxMesa, tObj1); + if (ti0->whichTMU == TDFX_TMU1) + tdfxTMMoveOutTM_NoLock(fxMesa, tObj0); + if (ti1->whichTMU == TDFX_TMU0) + tdfxTMMoveOutTM_NoLock(fxMesa, tObj1); - if (t0->isInTM) { - switch (t0->whichTMU) { + if (ti0->isInTM) { + switch (ti0->whichTMU) { case TDFX_TMU0: tstate |= T0_IN_TMU0; break; @@ -1672,8 +1664,8 @@ setupDoubleTMU(tdfxContextPtr fxMesa, else tstate |= T0_NOT_IN_TMU; - if (t1->isInTM) { - switch (t1->whichTMU) { + if (ti1->isInTM) { + switch (ti1->whichTMU) { case TDFX_TMU0: tstate |= T1_IN_TMU0; break; @@ -1696,7 +1688,7 @@ setupDoubleTMU(tdfxContextPtr fxMesa, if (!(((tstate & T0_IN_TMU0) && (tstate & T1_IN_TMU1)) || ((tstate & T0_IN_TMU1) && (tstate & T1_IN_TMU0)))) { if (tObj0 == tObj1) { - tdfxTMMoveInTMLocked(fxMesa, tObj1, TDFX_TMU_BOTH); + tdfxTMMoveInTM_NoLock(fxMesa, tObj1, TDFX_TMU_BOTH); } else { /* Find the minimal way to correct the situation */ @@ -1704,10 +1696,10 @@ setupDoubleTMU(tdfxContextPtr fxMesa, /* We have one in the standard order, setup the other */ if (tstate & T0_IN_TMU0) { /* T0 is in TMU0, put T1 in TMU1 */ - tdfxTMMoveInTMLocked(fxMesa, tObj1, TDFX_TMU1); + tdfxTMMoveInTM_NoLock(fxMesa, tObj1, TDFX_TMU1); } else { - tdfxTMMoveInTMLocked(fxMesa, tObj0, TDFX_TMU0); + tdfxTMMoveInTM_NoLock(fxMesa, tObj0, TDFX_TMU0); } /* tmu0 and tmu1 are setup */ } @@ -1715,36 +1707,36 @@ setupDoubleTMU(tdfxContextPtr fxMesa, /* we have one in the reverse order, setup the other */ if (tstate & T1_IN_TMU0) { /* T1 is in TMU0, put T0 in TMU1 */ - tdfxTMMoveInTMLocked(fxMesa, tObj0, TDFX_TMU1); + tdfxTMMoveInTM_NoLock(fxMesa, tObj0, TDFX_TMU1); } else { - tdfxTMMoveInTMLocked(fxMesa, tObj1, TDFX_TMU0); + tdfxTMMoveInTM_NoLock(fxMesa, tObj1, TDFX_TMU0); } tmu0 = 1; tmu1 = 0; } else { /* Nothing is loaded */ - tdfxTMMoveInTMLocked(fxMesa, tObj0, TDFX_TMU0); - tdfxTMMoveInTMLocked(fxMesa, tObj1, TDFX_TMU1); + tdfxTMMoveInTM_NoLock(fxMesa, tObj0, TDFX_TMU0); + tdfxTMMoveInTM_NoLock(fxMesa, tObj1, TDFX_TMU1); /* tmu0 and tmu1 are setup */ } } } } - t0->lastTimeUsed = fxMesa->texBindNumber; - t1->lastTimeUsed = fxMesa->texBindNumber; + ti0->lastTimeUsed = fxMesa->texBindNumber; + ti1->lastTimeUsed = fxMesa->texBindNumber; if (!ctx->Texture.SharedPalette) { - if (t0->info.format == GR_TEXFMT_P_8) { + if (ti0->info.format == GR_TEXFMT_P_8) { fxMesa->TexPalette.Type = GR_TEXTABLE_PALETTE_6666_EXT; - fxMesa->TexPalette.Data = &(t0->palette); + fxMesa->TexPalette.Data = &(ti0->palette); fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PALETTE; } - else if (t1->info.format == GR_TEXFMT_P_8) { + else if (ti1->info.format == GR_TEXFMT_P_8) { fxMesa->TexPalette.Type = GR_TEXTABLE_PALETTE_6666_EXT; - fxMesa->TexPalette.Data = &(t1->palette); + fxMesa->TexPalette.Data = &(ti1->palette); fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PALETTE; } else { @@ -1755,25 +1747,25 @@ setupDoubleTMU(tdfxContextPtr fxMesa, /* * Setup Unit 0 */ - assert(t0->isInTM); - assert(t0->range[tmu0]); - fxMesa->TexSource[tmu0].StartAddress = t0->range[tmu0]->startAddr; + assert(ti0->isInTM); + assert(ti0->tm[tmu0]); + fxMesa->TexSource[tmu0].StartAddress = ti0->tm[tmu0]->startAddr; fxMesa->TexSource[tmu0].EvenOdd = GR_MIPMAPLEVELMASK_BOTH; - fxMesa->TexSource[tmu0].Info = &(t0->info); + fxMesa->TexSource[tmu0].Info = &(ti0->info); fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_SOURCE; - if (fxMesa->TexParams[tmu0].sClamp != t0->sClamp || - fxMesa->TexParams[tmu0].tClamp != t0->tClamp || - fxMesa->TexParams[tmu0].minFilt != t0->minFilt || - fxMesa->TexParams[tmu0].magFilt != t0->magFilt || - fxMesa->TexParams[tmu0].mmMode != t0->mmMode || + if (fxMesa->TexParams[tmu0].sClamp != ti0->sClamp || + fxMesa->TexParams[tmu0].tClamp != ti0->tClamp || + fxMesa->TexParams[tmu0].minFilt != ti0->minFilt || + fxMesa->TexParams[tmu0].magFilt != ti0->magFilt || + fxMesa->TexParams[tmu0].mmMode != ti0->mmMode || fxMesa->TexParams[tmu0].LODblend != FXFALSE || fxMesa->TexParams[tmu0].LodBias != ctx->Texture.Unit[tmu0].LodBias) { - fxMesa->TexParams[tmu0].sClamp = t0->sClamp; - fxMesa->TexParams[tmu0].tClamp = t0->tClamp; - fxMesa->TexParams[tmu0].minFilt = t0->minFilt; - fxMesa->TexParams[tmu0].magFilt = t0->magFilt; - fxMesa->TexParams[tmu0].mmMode = t0->mmMode; + fxMesa->TexParams[tmu0].sClamp = ti0->sClamp; + fxMesa->TexParams[tmu0].tClamp = ti0->tClamp; + fxMesa->TexParams[tmu0].minFilt = ti0->minFilt; + fxMesa->TexParams[tmu0].magFilt = ti0->magFilt; + fxMesa->TexParams[tmu0].mmMode = ti0->mmMode; fxMesa->TexParams[tmu0].LODblend = FXFALSE; fxMesa->TexParams[tmu0].LodBias = ctx->Texture.Unit[tmu0].LodBias; fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PARAMS; @@ -1782,42 +1774,42 @@ setupDoubleTMU(tdfxContextPtr fxMesa, /* * Setup Unit 1 */ - if (tss->umaTexMemory) { - ASSERT(t1->isInTM); - ASSERT(t1->range[0]); - fxMesa->TexSource[tmu1].StartAddress = t1->range[0]->startAddr; + if (shared->umaTexMemory) { + ASSERT(ti1->isInTM); + ASSERT(ti1->tm[0]); + fxMesa->TexSource[tmu1].StartAddress = ti1->tm[0]->startAddr; fxMesa->TexSource[tmu1].EvenOdd = GR_MIPMAPLEVELMASK_BOTH; - fxMesa->TexSource[tmu1].Info = &(t1->info); + fxMesa->TexSource[tmu1].Info = &(ti1->info); } else { - ASSERT(t1->isInTM); - ASSERT(t1->range[tmu1]); - fxMesa->TexSource[tmu1].StartAddress = t1->range[tmu1]->startAddr; + ASSERT(ti1->isInTM); + ASSERT(ti1->tm[tmu1]); + fxMesa->TexSource[tmu1].StartAddress = ti1->tm[tmu1]->startAddr; fxMesa->TexSource[tmu1].EvenOdd = GR_MIPMAPLEVELMASK_BOTH; - fxMesa->TexSource[tmu1].Info = &(t1->info); + fxMesa->TexSource[tmu1].Info = &(ti1->info); } - if (fxMesa->TexParams[tmu1].sClamp != t1->sClamp || - fxMesa->TexParams[tmu1].tClamp != t1->tClamp || - fxMesa->TexParams[tmu1].minFilt != t1->minFilt || - fxMesa->TexParams[tmu1].magFilt != t1->magFilt || - fxMesa->TexParams[tmu1].mmMode != t1->mmMode || + if (fxMesa->TexParams[tmu1].sClamp != ti1->sClamp || + fxMesa->TexParams[tmu1].tClamp != ti1->tClamp || + fxMesa->TexParams[tmu1].minFilt != ti1->minFilt || + fxMesa->TexParams[tmu1].magFilt != ti1->magFilt || + fxMesa->TexParams[tmu1].mmMode != ti1->mmMode || fxMesa->TexParams[tmu1].LODblend != FXFALSE || fxMesa->TexParams[tmu1].LodBias != ctx->Texture.Unit[tmu1].LodBias) { - fxMesa->TexParams[tmu1].sClamp = t1->sClamp; - fxMesa->TexParams[tmu1].tClamp = t1->tClamp; - fxMesa->TexParams[tmu1].minFilt = t1->minFilt; - fxMesa->TexParams[tmu1].magFilt = t1->magFilt; - fxMesa->TexParams[tmu1].mmMode = t1->mmMode; + fxMesa->TexParams[tmu1].sClamp = ti1->sClamp; + fxMesa->TexParams[tmu1].tClamp = ti1->tClamp; + fxMesa->TexParams[tmu1].minFilt = ti1->minFilt; + fxMesa->TexParams[tmu1].magFilt = ti1->magFilt; + fxMesa->TexParams[tmu1].mmMode = ti1->mmMode; fxMesa->TexParams[tmu1].LODblend = FXFALSE; fxMesa->TexParams[tmu1].LodBias = ctx->Texture.Unit[tmu1].LodBias; fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PARAMS; } - fxMesa->sScale0 = t0->sScale; - fxMesa->tScale0 = t0->tScale; - fxMesa->sScale1 = t1->sScale; - fxMesa->tScale1 = t1->tScale; + fxMesa->sScale0 = ti0->sScale; + fxMesa->tScale0 = ti0->tScale; + fxMesa->sScale1 = ti1->sScale; + fxMesa->tScale1 = ti1->tScale; #undef T0_NOT_IN_TMU #undef T1_NOT_IN_TMU @@ -1830,30 +1822,27 @@ setupDoubleTMU(tdfxContextPtr fxMesa, static void setupTextureDoubleTMU(GLcontext * ctx) { tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - struct gl_texture_object *tObj0 = ctx->Texture.Unit[0].CurrentD[2]; - struct gl_texture_object *tObj1 = ctx->Texture.Unit[1].CurrentD[2]; - tdfxTexObjPtr t0 = TDFX_TEXTURE_DATA(tObj0); - tdfxTexObjPtr t1 = TDFX_TEXTURE_DATA(tObj1); + struct gl_texture_object *tObj0 = ctx->Texture.Unit[0].Current2D; + struct gl_texture_object *tObj1 = ctx->Texture.Unit[1].Current2D; + tdfxTexInfo *ti0 = TDFX_TEXTURE_DATA(tObj0); + tdfxTexInfo *ti1 = TDFX_TEXTURE_DATA(tObj1); struct gl_texture_image *baseImage0 = tObj0->Image[tObj0->BaseLevel]; struct gl_texture_image *baseImage1 = tObj1->Image[tObj1->BaseLevel]; const GLenum envMode0 = ctx->Texture.Unit[0].EnvMode; const GLenum envMode1 = ctx->Texture.Unit[1].EnvMode; - if (baseImage0->Border > 0 || baseImage1->Border >0) { - fxMesa->Fallback |= TDFX_FALLBACK_TEXTURE_BORDER; + if (baseImage0->Border > 0 || baseImage1->Border > 0) { + FALLBACK(fxMesa, TDFX_FALLBACK_TEXTURE_BORDER, GL_TRUE); return; } setupDoubleTMU(fxMesa, tObj0, tObj1); - if (t0->reloadImages || t1->reloadImages) + if (ti0->reloadImages || ti1->reloadImages) fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_IMAGES; fxMesa->tmuSrc = TDFX_TMU_BOTH; - /* Some texture environments not supported */ - fxMesa->Fallback &= ~TDFX_FALLBACK_TEXTURE_ENV; - if (TDFX_IS_NAPALM(fxMesa)) { /* Remember, Glide has its texture units numbered in backward * order compared to OpenGL. @@ -1861,7 +1850,7 @@ static void setupTextureDoubleTMU(GLcontext * ctx) GLboolean hw1 = GL_TRUE, hw2 = GL_TRUE; /* check if we really need to update glide unit 1 */ - if (fxMesa->TexState.Enabled != ctx->Texture.ReallyEnabled || + if (fxMesa->TexState.Enabled != ctx->Texture._ReallyEnabled || envMode0 != fxMesa->TexState.EnvMode[1] || envMode0 == GL_COMBINE_EXT || baseImage0->Format != fxMesa->TexState.TexFormat[1] || @@ -1873,7 +1862,7 @@ static void setupTextureDoubleTMU(GLcontext * ctx) } /* check if we really need to update glide unit 0 */ - if (fxMesa->TexState.Enabled != ctx->Texture.ReallyEnabled || + if (fxMesa->TexState.Enabled != ctx->Texture._ReallyEnabled || envMode1 != fxMesa->TexState.EnvMode[0] || envMode1 == GL_COMBINE_EXT || baseImage1->Format != fxMesa->TexState.TexFormat[0] || @@ -1884,21 +1873,21 @@ static void setupTextureDoubleTMU(GLcontext * ctx) fxMesa->TexState.TexFormat[0] = baseImage1->Format; } - fxMesa->TexState.Enabled = ctx->Texture.ReallyEnabled; + fxMesa->TexState.Enabled = ctx->Texture._ReallyEnabled; if (!hw1 || !hw2) { - fxMesa->Fallback |= TDFX_FALLBACK_TEXTURE_ENV; + FALLBACK(fxMesa, TDFX_FALLBACK_TEXTURE_ENV, GL_TRUE); } } else { int unit0, unit1; - if ((t0->whichTMU == TDFX_TMU1) || (t1->whichTMU == TDFX_TMU0)) + if ((ti0->whichTMU == TDFX_TMU1) || (ti1->whichTMU == TDFX_TMU0)) unit0 = 1; else unit0 = 0; unit1 = 1 - unit0; - if (fxMesa->TexState.Enabled != ctx->Texture.ReallyEnabled || + if (fxMesa->TexState.Enabled != ctx->Texture._ReallyEnabled || envMode0 != fxMesa->TexState.EnvMode[unit0] || envMode0 == GL_COMBINE_EXT || envMode1 != fxMesa->TexState.EnvMode[unit1] || @@ -1910,47 +1899,50 @@ static void setupTextureDoubleTMU(GLcontext * ctx) if (!SetupDoubleTexEnvVoodoo3(ctx, unit0, ctx->Texture.Unit[0].EnvMode, baseImage0->Format, ctx->Texture.Unit[1].EnvMode, baseImage1->Format)) { - fxMesa->Fallback |= TDFX_FALLBACK_TEXTURE_ENV; + FALLBACK(fxMesa, TDFX_FALLBACK_TEXTURE_ENV, GL_TRUE); } fxMesa->TexState.EnvMode[unit0] = envMode0; fxMesa->TexState.TexFormat[unit0] = baseImage0->Format; fxMesa->TexState.EnvMode[unit1] = envMode1; fxMesa->TexState.TexFormat[unit1] = baseImage1->Format; - fxMesa->TexState.Enabled = ctx->Texture.ReallyEnabled; + fxMesa->TexState.Enabled = ctx->Texture._ReallyEnabled; } } } -void tdfxUpdateTextureState( GLcontext *ctx ) +void +tdfxUpdateTextureState( GLcontext *ctx ) { tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - GLuint enabled = ctx->Texture.ReallyEnabled; + GLuint tex2Denabled = ctx->Texture._ReallyEnabled; - if ( fxMesa->numTMUs == 1 ) - enabled &= TEXTURE0_2D; + if (!fxMesa->haveTwoTMUs) + tex2Denabled &= TEXTURE0_2D; - switch ( enabled ) { + FALLBACK(fxMesa, TDFX_FALLBACK_TEXTURE_BORDER, GL_FALSE); + FALLBACK(fxMesa, TDFX_FALLBACK_TEXTURE_ENV, GL_FALSE); + + switch (tex2Denabled) { case TEXTURE0_2D: LOCK_HARDWARE( fxMesa ); /* XXX remove locking eventually */ - setupTextureSingleTMU( ctx, 0 ); + setupTextureSingleTMU(ctx, 0); UNLOCK_HARDWARE( fxMesa ); break; case TEXTURE1_2D: LOCK_HARDWARE( fxMesa ); - setupTextureSingleTMU( ctx, 1 ); + setupTextureSingleTMU(ctx, 1); UNLOCK_HARDWARE( fxMesa ); break; - case TEXTURE0_2D | TEXTURE1_2D: + case (TEXTURE0_2D | TEXTURE1_2D): LOCK_HARDWARE( fxMesa ); - setupTextureDoubleTMU( ctx ); + setupTextureDoubleTMU(ctx); UNLOCK_HARDWARE( fxMesa ); break; - default: - /* Disable hardware texturing */ - if ( TDFX_IS_NAPALM( fxMesa ) ) { + /* disable hardware texturing */ + if (TDFX_IS_NAPALM(fxMesa)) { fxMesa->ColorCombineExt.SourceA = GR_CMBX_ITRGB; fxMesa->ColorCombineExt.ModeA = GR_FUNC_MODE_X; fxMesa->ColorCombineExt.SourceB = GR_CMBX_ZERO; @@ -1971,8 +1963,9 @@ void tdfxUpdateTextureState( GLcontext *ctx ) fxMesa->AlphaCombineExt.InvertD = FXFALSE; fxMesa->AlphaCombineExt.Shift = 0; fxMesa->AlphaCombineExt.Invert = FXFALSE; - } else { - /* Voodoo 3 */ + } + else { + /* Voodoo 3*/ fxMesa->ColorCombine.Function = GR_COMBINE_FUNCTION_LOCAL; fxMesa->ColorCombine.Factor = GR_COMBINE_FACTOR_NONE; fxMesa->ColorCombine.Local = GR_COMBINE_LOCAL_ITERATED; @@ -1995,103 +1988,106 @@ void tdfxUpdateTextureState( GLcontext *ctx ) } -/* This is a special case of texture state update. + +/* + * This is a special case of texture state update. * It's used when we've simply bound a new texture to a texture * unit and the new texture has the exact same attributes as the * previously bound texture. * This is very common in Quake3. */ -void tdfxUpdateTextureBinding( GLcontext *ctx ) +void +tdfxUpdateTextureBinding( GLcontext *ctx ) { tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - const struct gl_shared_state *ss = fxMesa->glCtx->Shared; - const tdfxSharedStatePtr tss = (tdfxSharedStatePtr)ss->DriverData; - struct gl_texture_object *tObj0 = ctx->Texture.Unit[0].CurrentD[2]; - struct gl_texture_object *tObj1 = ctx->Texture.Unit[1].CurrentD[2]; - tdfxTexObjPtr t0 = TDFX_TEXTURE_DATA(tObj0); - tdfxTexObjPtr t1 = TDFX_TEXTURE_DATA(tObj1); - - if ( t0 ) { - fxMesa->sScale0 = t0->sScale; - fxMesa->tScale0 = t0->tScale; - if ( t0->info.format == GR_TEXFMT_P_8 ) { + struct gl_texture_object *tObj0 = ctx->Texture.Unit[0].Current2D; + struct gl_texture_object *tObj1 = ctx->Texture.Unit[1].Current2D; + tdfxTexInfo *ti0 = TDFX_TEXTURE_DATA(tObj0); + tdfxTexInfo *ti1 = TDFX_TEXTURE_DATA(tObj1); + + const struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; + const struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; + + if (ti0) { + fxMesa->sScale0 = ti0->sScale; + fxMesa->tScale0 = ti0->tScale; + if (ti0->info.format == GR_TEXFMT_P_8) { fxMesa->TexPalette.Type = GR_TEXTABLE_PALETTE_6666_EXT; - fxMesa->TexPalette.Data = &t0->palette; + fxMesa->TexPalette.Data = &(ti0->palette); fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PALETTE; - } else if ( t1 && t1->info.format == GR_TEXFMT_P_8 ) { + } + else if (ti1 && ti1->info.format == GR_TEXFMT_P_8) { fxMesa->TexPalette.Type = GR_TEXTABLE_PALETTE_6666_EXT; - fxMesa->TexPalette.Data = &t1->palette; + fxMesa->TexPalette.Data = &(ti1->palette); fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PALETTE; } } - if ( t1 ) { - fxMesa->sScale1 = t1->sScale; - fxMesa->tScale1 = t1->tScale; + if (ti1) { + fxMesa->sScale1 = ti1->sScale; + fxMesa->tScale1 = ti1->tScale; } - switch ( ctx->Texture.ReallyEnabled ) { - case TEXTURE0_2D: - if ( tss->umaTexMemory ) { - fxMesa->TexSource[0].StartAddress = t0->range[0]->startAddr; + if (ctx->Texture._ReallyEnabled == TEXTURE0_2D) { + if (shared->umaTexMemory) { + fxMesa->TexSource[0].StartAddress = ti0->tm[0]->startAddr; fxMesa->TexSource[0].EvenOdd = GR_MIPMAPLEVELMASK_BOTH; - fxMesa->TexSource[0].Info = &(t0->info); - } else { - if ( t0->LODblend && t0->whichTMU == TDFX_TMU_SPLIT ) { - fxMesa->TexSource[0].StartAddress = t0->range[TDFX_TMU0]->startAddr; + fxMesa->TexSource[0].Info = &(ti0->info); + } + else { + if (ti0->LODblend && ti0->whichTMU == TDFX_TMU_SPLIT) { + fxMesa->TexSource[0].StartAddress = ti0->tm[TDFX_TMU0]->startAddr; fxMesa->TexSource[0].EvenOdd = GR_MIPMAPLEVELMASK_ODD; - fxMesa->TexSource[0].Info = &t0->info; - fxMesa->TexSource[1].StartAddress = t0->range[TDFX_TMU1]->startAddr; + fxMesa->TexSource[0].Info = &(ti0->info); + fxMesa->TexSource[1].StartAddress = ti0->tm[TDFX_TMU1]->startAddr; fxMesa->TexSource[1].EvenOdd = GR_MIPMAPLEVELMASK_EVEN; - fxMesa->TexSource[1].Info = &t0->info; - } else { - FxU32 unit; - if ( t0->whichTMU == TDFX_TMU_BOTH ) { - unit = TDFX_TMU0; - } else { - unit = t0->whichTMU; - } + fxMesa->TexSource[1].Info = &(ti0->info); + } + else { + FxU32 tmu; + if (ti0->whichTMU == TDFX_TMU_BOTH) + tmu = TDFX_TMU0; + else + tmu = ti0->whichTMU; fxMesa->TexSource[0].Info = NULL; fxMesa->TexSource[1].Info = NULL; - if ( t0->range[unit] ) { - fxMesa->TexSource[unit].StartAddress = t0->range[unit]->startAddr; - fxMesa->TexSource[unit].EvenOdd = GR_MIPMAPLEVELMASK_BOTH; - fxMesa->TexSource[unit].Info = &t0->info; + if (ti0->tm[tmu]) { + fxMesa->TexSource[tmu].StartAddress = ti0->tm[tmu]->startAddr; + fxMesa->TexSource[tmu].EvenOdd = GR_MIPMAPLEVELMASK_BOTH; + fxMesa->TexSource[tmu].Info = &(ti0->info); } } } - break; - - case TEXTURE1_2D: - if ( tss->umaTexMemory ) { - fxMesa->TexSource[0].StartAddress = t1->range[0]->startAddr; + } + else if (ctx->Texture._ReallyEnabled == TEXTURE1_2D) { + if (shared->umaTexMemory) { + fxMesa->TexSource[0].StartAddress = ti1->tm[0]->startAddr; fxMesa->TexSource[0].EvenOdd = GR_MIPMAPLEVELMASK_BOTH; - fxMesa->TexSource[0].Info = &t1->info; + fxMesa->TexSource[0].Info = &(ti1->info); } - break; - - case TEXTURE0_2D | TEXTURE1_2D: - if ( tss->umaTexMemory ) { + } + else if (ctx->Texture._ReallyEnabled == (TEXTURE0_2D | TEXTURE1_2D)) { + if (shared->umaTexMemory) { const FxU32 tmu0 = 0, tmu1 = 1; - fxMesa->TexSource[tmu0].StartAddress = t0->range[0]->startAddr; + fxMesa->TexSource[tmu0].StartAddress = ti0->tm[0]->startAddr; fxMesa->TexSource[tmu0].EvenOdd = GR_MIPMAPLEVELMASK_BOTH; - fxMesa->TexSource[tmu0].Info = &t0->info; + fxMesa->TexSource[tmu0].Info = &(ti0->info); - fxMesa->TexSource[tmu1].StartAddress = t1->range[0]->startAddr; + fxMesa->TexSource[tmu1].StartAddress = ti1->tm[0]->startAddr; fxMesa->TexSource[tmu1].EvenOdd = GR_MIPMAPLEVELMASK_BOTH; - fxMesa->TexSource[tmu1].Info = &t1->info; + fxMesa->TexSource[tmu1].Info = &(ti1->info); } else { const FxU32 tmu0 = 0, tmu1 = 1; - fxMesa->TexSource[tmu0].StartAddress = t0->range[tmu0]->startAddr; + fxMesa->TexSource[tmu0].StartAddress = ti0->tm[tmu0]->startAddr; fxMesa->TexSource[tmu0].EvenOdd = GR_MIPMAPLEVELMASK_BOTH; - fxMesa->TexSource[tmu0].Info = &t0->info; + fxMesa->TexSource[tmu0].Info = &(ti0->info); - fxMesa->TexSource[tmu1].StartAddress = t1->range[tmu1]->startAddr; + fxMesa->TexSource[tmu1].StartAddress = ti1->tm[tmu1]->startAddr; fxMesa->TexSource[tmu1].EvenOdd = GR_MIPMAPLEVELMASK_BOTH; - fxMesa->TexSource[tmu1].Info = &t1->info; + fxMesa->TexSource[tmu1].Info = &(ti1->info); } - break; } + fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_SOURCE; } diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_pipeline.h b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texstate.h index 2f199a007..0c0d4adcb 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_pipeline.h +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texstate.h @@ -23,7 +23,7 @@ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_pipeline.h,v 1.1 2001/03/21 16:14:28 dawes Exp $ */ +/* $XFree86$ */ /* * Original rewrite: @@ -31,24 +31,14 @@ * * Authors: * Gareth Hughes <gareth@valinux.com> - * Keith Whitwell <keithw@valinux.com> + * Brian Paul <brianp@valinux.com> * */ -#ifndef __TDFX_PIPELINE_H__ -#define __TDFX_PIPELINE_H__ +#ifndef __TDFX_TEXSTATE_H__ +#define __TDFX_TEXSTATE_H__ -#ifdef GLX_DIRECT_RENDERING +extern void tdfxUpdateTextureState( GLcontext *ctx ); +extern void tdfxUpdateTextureBinding( GLcontext *ctx ); -#include "context.h" - -extern GLboolean tdfxDDBuildPrecalcPipeline( GLcontext *ctx ); -extern GLuint tdfxDDRegisterPipelineStages( struct gl_pipeline_stage *out, - const struct gl_pipeline_stage *in, - GLuint nr ); - -extern void tdfxDDFastPathInit( void ); -extern void tdfxDDFastPath( struct vertex_buffer *VB ); - -#endif #endif diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tris.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tris.c index 2afe815b2..2a8270dbd 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tris.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tris.c @@ -23,493 +23,1262 @@ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_tris.c,v 1.2 2001/08/18 02:51:07 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfxtris.c,v 1.5 2000/09/24 13:51:04 alanh Exp $ */ -/* - * Original rewrite: - * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 - * - * Authors: - * Gareth Hughes <gareth@valinux.com> - * Brian Paul <brianp@valinux.com> - * Keith Whitwell <keithw@valinux.com> - * +/* Authors: + * Keith Whitwell <keithw@valinux.com> */ -#include "tdfx_context.h" +#include <stdio.h> +#include <math.h> + +#include "glheader.h" +#include "mtypes.h" +#include "macros.h" +#include "colormac.h" + +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "swrast_setup/ss_context.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" + #include "tdfx_tris.h" +#include "tdfx_state.h" +#include "tdfx_vb.h" +#include "tdfx_lock.h" +#include "tdfx_render.h" + + +static void tdfxRasterPrimitive( GLcontext *ctx, GLenum prim ); +static void tdfxRenderPrimitive( 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_triangle( fxMesa, a, b, c ); \ + else \ + fxMesa->Glide.grDrawTriangle( a, b, c ); \ +} while (0) \ + +#define QUAD( a, b, c, d ) \ +do { \ + if (DO_FALLBACK) { \ + fxMesa->draw_triangle( fxMesa, a, b, d ); \ + fxMesa->draw_triangle( fxMesa, b, c, d ); \ + } else { \ + fxMesa->Glide.grDrawTriangle( a, b, d ); \ + fxMesa->Glide.grDrawTriangle( b, c, d ); \ + } \ +} while (0) -#include "pipeline.h" -#include "vbindirect.h" +#define LINE( v0, v1 ) \ +do { \ + if (DO_FALLBACK) \ + fxMesa->draw_line( fxMesa, v0, v1 ); \ + else { \ + v0->v.x += LINE_X_OFFSET - TRI_X_OFFSET; \ + v0->v.y += LINE_Y_OFFSET - TRI_Y_OFFSET; \ + v1->v.x += LINE_X_OFFSET - TRI_X_OFFSET; \ + v1->v.y += LINE_Y_OFFSET - TRI_Y_OFFSET; \ + fxMesa->Glide.grDrawLine( v0, v1 ); \ + v0->v.x -= LINE_X_OFFSET - TRI_X_OFFSET; \ + v0->v.y -= LINE_Y_OFFSET - TRI_Y_OFFSET; \ + v1->v.x -= LINE_X_OFFSET - TRI_X_OFFSET; \ + v1->v.y -= LINE_Y_OFFSET - TRI_Y_OFFSET; \ + } \ +} while (0) + +#define POINT( v0 ) \ +do { \ + if (DO_FALLBACK) \ + fxMesa->draw_point( fxMesa, v0 ); \ + else { \ + v0->v.x += PNT_X_OFFSET - TRI_X_OFFSET; \ + v0->v.y += PNT_Y_OFFSET - TRI_Y_OFFSET; \ + fxMesa->Glide.grDrawPoint( v0 ); \ + v0->v.x -= PNT_X_OFFSET - TRI_X_OFFSET; \ + v0->v.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 +tdfx_translate_vertex( GLcontext *ctx, const tdfxVertex *src, SWvertex *dst) +{ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + + if (fxMesa->vertexFormat == TDFX_LAYOUT_TINY) { + dst->win[0] = src->tv.x - fxMesa->x_offset; + dst->win[1] = src->tv.y - (fxMesa->screen_height - fxMesa->height - fxMesa->y_offset); + dst->win[2] = src->tv.z; + dst->win[3] = 1.0; + + dst->color[0] = src->tv.color.red; + dst->color[1] = src->tv.color.green; + dst->color[2] = src->tv.color.blue; + dst->color[3] = src->tv.color.alpha; + } + else { + GLfloat w = 1.0 / src->v.rhw; + + dst->win[0] = src->v.x - fxMesa->x_offset; + dst->win[1] = fxMesa->screen_height - fxMesa->y_offset - src->v.y; + dst->win[2] = src->v.z; + dst->win[3] = src->v.rhw; + + dst->color[0] = src->v.color.red; + dst->color[1] = src->v.color.green; + dst->color[2] = src->v.color.blue; + dst->color[3] = src->v.color.alpha; + + if (fxMesa->vertexFormat == TDFX_LAYOUT_PROJECT) { + dst->texcoord[0][0] = fxMesa->sScale0 * w * src->pv.tu0; + dst->texcoord[0][1] = fxMesa->tScale0 * w * src->pv.tv0; + dst->texcoord[0][3] = w * src->pv.tq0; + + if (fxMesa->SetupIndex & TDFX_TEX1_BIT) { + dst->texcoord[1][0] = fxMesa->sScale1 * w * src->pv.tu1; + dst->texcoord[1][1] = fxMesa->tScale1 * w * src->pv.tv1; + dst->texcoord[1][3] = w * src->pv.tq1; + } + } else if (fxMesa->SetupIndex & TDFX_TEX0_BIT) { + dst->texcoord[0][0] = fxMesa->sScale0 * w * src->v.tu0; + dst->texcoord[0][1] = fxMesa->tScale0 * w * src->v.tv0; + dst->texcoord[0][3] = 1.0; + + if (fxMesa->SetupIndex & TDFX_TEX1_BIT) { + dst->texcoord[1][0] = fxMesa->sScale1 * w * src->v.tu1; + dst->texcoord[1][1] = fxMesa->tScale1 * w * src->v.tv1; + dst->texcoord[1][3] = 1.0; + } + } + } + + dst->pointSize = ctx->Point._Size; +} + + +static void +tdfx_fallback_tri( tdfxContextPtr fxMesa, + tdfxVertex *v0, + tdfxVertex *v1, + tdfxVertex *v2 ) +{ + GLcontext *ctx = fxMesa->glCtx; + SWvertex v[3]; + tdfx_translate_vertex( ctx, v0, &v[0] ); + tdfx_translate_vertex( ctx, v1, &v[1] ); + tdfx_translate_vertex( ctx, v2, &v[2] ); + _swrast_Triangle( ctx, &v[0], &v[1], &v[2] ); +} + + +static void +tdfx_fallback_line( tdfxContextPtr fxMesa, + tdfxVertex *v0, + tdfxVertex *v1 ) +{ + GLcontext *ctx = fxMesa->glCtx; + SWvertex v[2]; + tdfx_translate_vertex( ctx, v0, &v[0] ); + tdfx_translate_vertex( ctx, v1, &v[1] ); + _swrast_Line( ctx, &v[0], &v[1] ); +} + + +static void +tdfx_fallback_point( tdfxContextPtr fxMesa, + tdfxVertex *v0 ) +{ + GLcontext *ctx = fxMesa->glCtx; + SWvertex v[1]; + tdfx_translate_vertex( ctx, v0, &v[0] ); + _swrast_Point( ctx, &v[0] ); +} + +/*********************************************************************** + * Functions to draw basic primitives * + ***********************************************************************/ + +static void tdfx_print_vertex( GLcontext *ctx, const tdfxVertex *v ) +{ + tdfxContextPtr imesa = TDFX_CONTEXT( ctx ); + + fprintf(stderr, "vertex at %p\n", v); + + if (imesa->vertexFormat == TDFX_LAYOUT_TINY) { + fprintf(stderr, "x %f y %f z %f\n", v->v.x, v->v.y, v->v.z); + fprintf(stderr, "r %d g %d b %d a %d\n", + v->tv.color.red, + v->tv.color.green, + v->tv.color.blue, + v->tv.color.alpha); + } + else { + fprintf(stderr, "x %f y %f z %f oow %f\n", + v->v.x, v->v.y, v->v.z, v->v.rhw); + fprintf(stderr, "r %d g %d b %d a %d\n", + v->v.color.red, + v->v.color.green, + v->v.color.blue, + v->v.color.alpha); + } + + fprintf(stderr, "\n"); +} + +#define DO_FALLBACK 0 + +/* 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 tdfx_draw_quad( tdfxContextPtr fxMesa, + tdfxVertexPtr v0, + tdfxVertexPtr v1, + tdfxVertexPtr v2, + tdfxVertexPtr v3 ) +{ +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + BEGIN_CLIP_LOOP_LOCKED(fxMesa) { + QUAD( v0, v1, v2, v3 ); + } END_CLIP_LOOP_LOCKED(fxMesa); +} + +static void tdfx_draw_triangle( tdfxContextPtr fxMesa, + tdfxVertexPtr v0, + tdfxVertexPtr v1, + tdfxVertexPtr v2 ) +{ +/* fprintf(stderr, "%s\n", __FUNCTION__); */ +/* tdfx_print_vertex( fxMesa->glCtx, v0 ); */ +/* tdfx_print_vertex( fxMesa->glCtx, v1 ); */ +/* tdfx_print_vertex( fxMesa->glCtx, v2 ); */ + BEGIN_CLIP_LOOP_LOCKED(fxMesa) { + TRI( v0, v1, v2 ); + } END_CLIP_LOOP_LOCKED(fxMesa); +} + +static void tdfx_draw_line( tdfxContextPtr fxMesa, + tdfxVertexPtr v0, + tdfxVertexPtr v1 ) +{ + /* No support for wide lines (avoid wide/aa line fallback). + */ + BEGIN_CLIP_LOOP_LOCKED(fxMesa) { + LINE(v0, v1); + } END_CLIP_LOOP_LOCKED(fxMesa); +} + +static void tdfx_draw_point( tdfxContextPtr fxMesa, + tdfxVertexPtr v0 ) +{ + /* No support for wide points. + */ + BEGIN_CLIP_LOOP_LOCKED(fxMesa) { + POINT( v0 ); + } END_CLIP_LOOP_LOCKED(fxMesa); +} + +#undef DO_FALLBACK + + +#define TDFX_UNFILLED_BIT 0x1 +#define TDFX_OFFSET_BIT 0x2 +#define TDFX_TWOSIDE_BIT 0x4 +#define TDFX_FLAT_BIT 0x8 +#define TDFX_FALLBACK_BIT 0x10 +#define TDFX_MAX_TRIFUNC 0x20 static struct { - points_func points; - line_func line; + points_func points; + line_func line; triangle_func triangle; quad_func quad; - render_func *render_tab; } rast_tab[TDFX_MAX_TRIFUNC]; -#define TDFX_COLOR( to, from ) \ - do { \ - (to)[0] = (from)[2]; \ - (to)[1] = (from)[1]; \ - (to)[2] = (from)[0]; \ - (to)[3] = (from)[3]; \ - } while (0) - +#define DO_FALLBACK (IND & TDFX_FALLBACK_BIT) +#define DO_OFFSET (IND & TDFX_OFFSET_BIT) +#define DO_UNFILLED (IND & TDFX_UNFILLED_BIT) +#define DO_TWOSIDE (IND & TDFX_TWOSIDE_BIT) +#define DO_FLAT (IND & TDFX_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 tdfxVertex +#define TAB rast_tab + +#define TDFX_COLOR( dst, src ) \ +do { \ + dst[0] = src[2]; \ + dst[1] = src[1]; \ + dst[2] = src[0]; \ + dst[3] = src[3]; \ +} while (0) -static void tdfxPrintRenderState( const char *msg, GLuint state ) -{ - fprintf( stderr, "%s: (0x%x) %s%s%s%s\n", - msg, state, - (state & TDFX_FLAT_BIT) ? "flat, " : "", - (state & TDFX_OFFSET_BIT) ? "offset, " : "", - (state & TDFX_TWOSIDE_BIT) ? "twoside, " : "", - (state & TDFX_CLIPRECT_BIT) ? "cliprects, " : ""); -} +#define DEPTH_SCALE 1.0 +#define UNFILLED_TRI unfilled_tri +#define UNFILLED_QUAD unfilled_quad +#define VERT_X(_v) _v->v.x +#define VERT_Y(_v) _v->v.y +#define VERT_Z(_v) _v->v.z +#define AREA_IS_CCW( a ) (a < 0) +#define GET_VERTEX(e) (fxMesa->verts + (e<<fxMesa->vertex_stride_shift)) + +#define VERT_SET_RGBA( v, c ) TDFX_COLOR( v->ub4[coloroffset], c ) +#define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset] +#define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[coloroffset] +#define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx] + +#define LOCAL_VARS(n) \ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); \ + GLuint coloroffset = (fxMesa->vertexFormat == \ + TDFX_LAYOUT_TINY) ? 3 : 4; \ + GLuint color[n]; \ + (void) color; (void)coloroffset + + + +/*********************************************************************** + * Functions to draw basic unfilled primitives * + ***********************************************************************/ + +#define RASTERIZE(x) if (fxMesa->raster_primitive != x) \ + tdfxRasterPrimitive( ctx, x ) +#define RENDER_PRIMITIVE fxMesa->render_primitive +#define IND TDFX_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 "tdfx_tritmp.h" - -#define IND (TDFX_FLAT_BIT) -#define TAG(x) x##_flat -#include "tdfx_tritmp.h" +#include "tnl_dd/t_dd_tritmp.h" #define IND (TDFX_OFFSET_BIT) #define TAG(x) x##_offset -#include "tdfx_tritmp.h" - -#define IND (TDFX_OFFSET_BIT | TDFX_FLAT_BIT) -#define TAG(x) x##_offset_flat -#include "tdfx_tritmp.h" +#include "tnl_dd/t_dd_tritmp.h" #define IND (TDFX_TWOSIDE_BIT) #define TAG(x) x##_twoside -#include "tdfx_tritmp.h" +#include "tnl_dd/t_dd_tritmp.h" -#define IND (TDFX_TWOSIDE_BIT | TDFX_FLAT_BIT) -#define TAG(x) x##_twoside_flat -#include "tdfx_tritmp.h" - -#define IND (TDFX_TWOSIDE_BIT | TDFX_OFFSET_BIT) +#define IND (TDFX_TWOSIDE_BIT|TDFX_OFFSET_BIT) #define TAG(x) x##_twoside_offset -#include "tdfx_tritmp.h" +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (TDFX_UNFILLED_BIT) +#define TAG(x) x##_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (TDFX_OFFSET_BIT|TDFX_UNFILLED_BIT) +#define TAG(x) x##_offset_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (TDFX_TWOSIDE_BIT|TDFX_UNFILLED_BIT) +#define TAG(x) x##_twoside_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (TDFX_TWOSIDE_BIT|TDFX_OFFSET_BIT|TDFX_UNFILLED_BIT) +#define TAG(x) x##_twoside_offset_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (TDFX_FALLBACK_BIT) +#define TAG(x) x##_fallback +#include "tnl_dd/t_dd_tritmp.h" -#define IND (TDFX_TWOSIDE_BIT | TDFX_OFFSET_BIT | TDFX_FLAT_BIT) +#define IND (TDFX_OFFSET_BIT|TDFX_FALLBACK_BIT) +#define TAG(x) x##_offset_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (TDFX_TWOSIDE_BIT|TDFX_FALLBACK_BIT) +#define TAG(x) x##_twoside_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (TDFX_TWOSIDE_BIT|TDFX_OFFSET_BIT|TDFX_FALLBACK_BIT) +#define TAG(x) x##_twoside_offset_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (TDFX_UNFILLED_BIT|TDFX_FALLBACK_BIT) +#define TAG(x) x##_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (TDFX_OFFSET_BIT|TDFX_UNFILLED_BIT|TDFX_FALLBACK_BIT) +#define TAG(x) x##_offset_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (TDFX_TWOSIDE_BIT|TDFX_UNFILLED_BIT|TDFX_FALLBACK_BIT) +#define TAG(x) x##_twoside_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (TDFX_TWOSIDE_BIT|TDFX_OFFSET_BIT|TDFX_UNFILLED_BIT| \ + TDFX_FALLBACK_BIT) +#define TAG(x) x##_twoside_offset_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + + +/* Tdfx doesn't support provoking-vertex flat-shading? + */ +#define IND (TDFX_FLAT_BIT) +#define TAG(x) x##_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (TDFX_OFFSET_BIT|TDFX_FLAT_BIT) +#define TAG(x) x##_offset_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (TDFX_TWOSIDE_BIT|TDFX_FLAT_BIT) +#define TAG(x) x##_twoside_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (TDFX_TWOSIDE_BIT|TDFX_OFFSET_BIT|TDFX_FLAT_BIT) #define TAG(x) x##_twoside_offset_flat -#include "tdfx_tritmp.h" +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (TDFX_UNFILLED_BIT|TDFX_FLAT_BIT) +#define TAG(x) x##_unfilled_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (TDFX_OFFSET_BIT|TDFX_UNFILLED_BIT|TDFX_FLAT_BIT) +#define TAG(x) x##_offset_unfilled_flat +#include "tnl_dd/t_dd_tritmp.h" -#define IND (TDFX_CLIPRECT_BIT) -#define TAG(x) x##_cliprect -#include "tdfx_tritmp.h" +#define IND (TDFX_TWOSIDE_BIT|TDFX_UNFILLED_BIT|TDFX_FLAT_BIT) +#define TAG(x) x##_twoside_unfilled_flat +#include "tnl_dd/t_dd_tritmp.h" -#define IND (TDFX_FLAT_BIT | TDFX_CLIPRECT_BIT) -#define TAG(x) x##_flat_cliprect -#include "tdfx_tritmp.h" +#define IND (TDFX_TWOSIDE_BIT|TDFX_OFFSET_BIT|TDFX_UNFILLED_BIT|TDFX_FLAT_BIT) +#define TAG(x) x##_twoside_offset_unfilled_flat +#include "tnl_dd/t_dd_tritmp.h" -#define IND (TDFX_OFFSET_BIT | TDFX_CLIPRECT_BIT) -#define TAG(x) x##_offset_cliprect -#include "tdfx_tritmp.h" +#define IND (TDFX_FALLBACK_BIT|TDFX_FLAT_BIT) +#define TAG(x) x##_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" -#define IND (TDFX_OFFSET_BIT | TDFX_FLAT_BIT | TDFX_CLIPRECT_BIT) -#define TAG(x) x##_offset_flat_cliprect -#include "tdfx_tritmp.h" +#define IND (TDFX_OFFSET_BIT|TDFX_FALLBACK_BIT|TDFX_FLAT_BIT) +#define TAG(x) x##_offset_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (TDFX_TWOSIDE_BIT|TDFX_FALLBACK_BIT|TDFX_FLAT_BIT) +#define TAG(x) x##_twoside_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (TDFX_TWOSIDE_BIT|TDFX_OFFSET_BIT|TDFX_FALLBACK_BIT|TDFX_FLAT_BIT) +#define TAG(x) x##_twoside_offset_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (TDFX_UNFILLED_BIT|TDFX_FALLBACK_BIT|TDFX_FLAT_BIT) +#define TAG(x) x##_unfilled_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (TDFX_OFFSET_BIT|TDFX_UNFILLED_BIT|TDFX_FALLBACK_BIT|TDFX_FLAT_BIT) +#define TAG(x) x##_offset_unfilled_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (TDFX_TWOSIDE_BIT|TDFX_UNFILLED_BIT|TDFX_FALLBACK_BIT|TDFX_FLAT_BIT) +#define TAG(x) x##_twoside_unfilled_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (TDFX_TWOSIDE_BIT|TDFX_OFFSET_BIT|TDFX_UNFILLED_BIT| \ + TDFX_FALLBACK_BIT|TDFX_FLAT_BIT) +#define TAG(x) x##_twoside_offset_unfilled_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" + + +static void init_rast_tab( void ) +{ + init(); + init_offset(); + init_twoside(); + init_twoside_offset(); + init_unfilled(); + init_offset_unfilled(); + init_twoside_unfilled(); + init_twoside_offset_unfilled(); + init_fallback(); + init_offset_fallback(); + init_twoside_fallback(); + init_twoside_offset_fallback(); + init_unfilled_fallback(); + init_offset_unfilled_fallback(); + init_twoside_unfilled_fallback(); + init_twoside_offset_unfilled_fallback(); + + 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(); +} -#define IND (TDFX_TWOSIDE_BIT | TDFX_CLIPRECT_BIT) -#define TAG(x) x##_twoside_cliprect -#include "tdfx_tritmp.h" -#define IND (TDFX_TWOSIDE_BIT | TDFX_FLAT_BIT | TDFX_CLIPRECT_BIT) -#define TAG(x) x##_twoside_flat_cliprect -#include "tdfx_tritmp.h" +/**********************************************************************/ +/* Render whole begin/end objects */ +/**********************************************************************/ -#define IND (TDFX_TWOSIDE_BIT | TDFX_OFFSET_BIT | TDFX_CLIPRECT_BIT) -#define TAG(x) x##_twoside_offset_cliprect -#include "tdfx_tritmp.h" -#define IND (TDFX_TWOSIDE_BIT | TDFX_OFFSET_BIT | TDFX_FLAT_BIT | TDFX_CLIPRECT_BIT) -#define TAG(x) x##_twoside_offset_flat_cliprect -#include "tdfx_tritmp.h" +/* Accelerate vertex buffer rendering when renderindex == 0 and + * there is no clipping. + */ -static void tdfx_render_vb_points( struct vertex_buffer *VB, +static void tdfx_render_vb_points( GLcontext *ctx, GLuint start, GLuint count, - GLuint parity ) + GLuint flags ) { - GLcontext *ctx = VB->ctx; tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - tdfxVertexPtr fxVB = TDFX_DRIVER_DATA(VB)->verts; + GLuint shift = fxMesa->vertex_stride_shift; + char *fxVB = fxMesa->verts + (start << shift); + int stride = 1<<shift; + char *tmp; GLint i; - (void) parity; + (void) flags; + /* Adjust point coords */ - for (i = start; i < count; i++) { - fxVB[i].v.x += PNT_X_OFFSET - TRI_X_OFFSET; - fxVB[i].v.y += PNT_Y_OFFSET - TRI_Y_OFFSET; + for (i = start, tmp = fxVB; i < count; i++, tmp += stride) { + ((tdfxVertexPtr)tmp)->v.x += PNT_X_OFFSET - TRI_X_OFFSET; + ((tdfxVertexPtr)tmp)->v.y += PNT_Y_OFFSET - TRI_Y_OFFSET; } + fxMesa->Glide.grDrawVertexArrayContiguous( GR_POINTS, count-start, - fxVB+start, sizeof(*fxVB)); + fxVB, stride); /* restore point coords */ - for (i = start; i < count; i++) { - fxVB[i].v.x -= PNT_X_OFFSET - TRI_X_OFFSET; - fxVB[i].v.y -= PNT_Y_OFFSET - TRI_Y_OFFSET; + for (i = start, tmp = fxVB; i < count; i++, tmp += stride) { + ((tdfxVertexPtr)tmp)->v.x -= PNT_X_OFFSET - TRI_X_OFFSET; + ((tdfxVertexPtr)tmp)->v.y -= PNT_Y_OFFSET - TRI_Y_OFFSET; } } -static void tdfx_render_vb_line_strip( struct vertex_buffer *VB, +static void tdfx_render_vb_line_strip( GLcontext *ctx, GLuint start, GLuint count, - GLuint parity ) + GLuint flags ) { - tdfxContextPtr fxMesa = TDFX_CONTEXT(VB->ctx); - tdfxVertexPtr fxVB = TDFX_DRIVER_DATA(VB)->verts; + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + GLuint shift = fxMesa->vertex_stride_shift; + char *fxVB = fxMesa->verts + (start << shift); + int stride = 1<<shift; + char *tmp; GLint i; - (void) parity; + (void) flags; + /* adjust line coords */ - for (i = start; i < count; i++) { - fxVB[i].v.x += LINE_X_OFFSET - TRI_X_OFFSET; - fxVB[i].v.y += LINE_Y_OFFSET - TRI_Y_OFFSET; + for (i = start, tmp = fxVB; i < count; i++, tmp += stride) { + ((tdfxVertexPtr)tmp)->v.x += LINE_X_OFFSET - TRI_X_OFFSET; + ((tdfxVertexPtr)tmp)->v.y += LINE_Y_OFFSET - TRI_Y_OFFSET; } + fxMesa->Glide.grDrawVertexArrayContiguous( GR_LINE_STRIP, count-start, - fxVB+start, sizeof(*fxVB)); + fxVB, 1<<shift); + + /* restore line coords */ + for (i = start, tmp = fxVB; i < count; i++, tmp += stride) { + ((tdfxVertexPtr)tmp)->v.x -= LINE_X_OFFSET - TRI_X_OFFSET; + ((tdfxVertexPtr)tmp)->v.y -= LINE_Y_OFFSET - TRI_Y_OFFSET; + } +} + +static void tdfx_render_vb_line_loop( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + GLuint shift = fxMesa->vertex_stride_shift; + char *fxVB = fxMesa->verts + (start << shift); + int stride = 1<<shift; + char *tmp, *tmp2 = fxVB; + GLint i; + GLint j = start; + (void) flags; + + if (!(flags & PRIM_BEGIN)) { + fxVB += (1 << shift); + j++; + } + + /* adjust line coords */ + for (i = start, tmp = tmp2; i < count; i++, tmp += stride) { + ((tdfxVertexPtr)tmp)->v.x += LINE_X_OFFSET - TRI_X_OFFSET; + ((tdfxVertexPtr)tmp)->v.y += LINE_Y_OFFSET - TRI_Y_OFFSET; + } + + fxMesa->Glide.grDrawVertexArrayContiguous( GR_LINE_STRIP, count-j, + fxVB, 1<<shift); + + if (flags & PRIM_END) + fxMesa->Glide.grDrawLine( fxMesa->verts + ((count - 1)<<shift), + fxMesa->verts + (start<<shift) ); + /* restore line coords */ - for (i = start; i < count; i++) { - fxVB[i].v.x -= LINE_X_OFFSET - TRI_X_OFFSET; - fxVB[i].v.y -= LINE_Y_OFFSET - TRI_Y_OFFSET; + for (i = start, tmp = tmp2; i < count; i++, tmp += stride) { + ((tdfxVertexPtr)tmp)->v.x -= LINE_X_OFFSET - TRI_X_OFFSET; + ((tdfxVertexPtr)tmp)->v.y -= LINE_Y_OFFSET - TRI_Y_OFFSET; } } -static void tdfx_render_vb_lines( struct vertex_buffer *VB, +static void tdfx_render_vb_lines( GLcontext *ctx, GLuint start, GLuint count, - GLuint parity ) + GLuint flags ) { - tdfxContextPtr fxMesa = TDFX_CONTEXT(VB->ctx); - tdfxVertexPtr fxVB = TDFX_DRIVER_DATA(VB)->verts; + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + GLuint shift = fxMesa->vertex_stride_shift; + char *fxVB = fxMesa->verts + (start << shift); + int stride = 1<<shift; + char *tmp; GLint i; - (void) parity; + (void) flags; + /* adjust line coords */ - for (i = start; i < count; i++) { - fxVB[i].v.x += LINE_X_OFFSET - TRI_X_OFFSET; - fxVB[i].v.y += LINE_Y_OFFSET - TRI_Y_OFFSET; + for (i = start, tmp = fxVB; i < count; i++, tmp += stride) { + ((tdfxVertexPtr)tmp)->v.x += LINE_X_OFFSET - TRI_X_OFFSET; + ((tdfxVertexPtr)tmp)->v.y += LINE_Y_OFFSET - TRI_Y_OFFSET; } + fxMesa->Glide.grDrawVertexArrayContiguous( GR_LINES, count-start, - fxVB+start, sizeof(*fxVB)); + fxVB, 1<<shift); + /* restore line coords */ - for (i = start; i < count; i++) { - fxVB[i].v.x -= LINE_X_OFFSET - TRI_X_OFFSET; - fxVB[i].v.y -= LINE_Y_OFFSET - TRI_Y_OFFSET; + for (i = start, tmp = fxVB; i < count; i++, tmp += stride) { + ((tdfxVertexPtr)tmp)->v.x -= LINE_X_OFFSET - TRI_X_OFFSET; + ((tdfxVertexPtr)tmp)->v.y -= LINE_Y_OFFSET - TRI_Y_OFFSET; } } -static void tdfx_render_vb_triangles( struct vertex_buffer *VB, +static void tdfx_render_vb_triangles( GLcontext *ctx, GLuint start, GLuint count, - GLuint parity ) + GLuint flags ) { - tdfxContextPtr fxMesa = TDFX_CONTEXT(VB->ctx); - tdfxVertexPtr fxVB = TDFX_DRIVER_DATA(VB)->verts; + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + GLuint shift = fxMesa->vertex_stride_shift; + char *fxVB = fxMesa->verts + (start << shift); + (void) flags; + fxMesa->Glide.grDrawVertexArrayContiguous( GR_TRIANGLES, count-start, - fxVB+start, sizeof(*fxVB)); - (void) parity; + fxVB, 1<<shift); } -static void tdfx_render_vb_tri_strip( struct vertex_buffer *VB, +static void tdfx_render_vb_tri_strip( GLcontext *ctx, GLuint start, GLuint count, - GLuint parity ) + GLuint flags ) { - tdfxContextPtr fxMesa = TDFX_CONTEXT(VB->ctx); - tdfxVertexPtr fxVB = TDFX_DRIVER_DATA(VB)->verts; - fxMesa->Glide.grDrawVertexArrayContiguous( GR_TRIANGLE_STRIP, count-start, - fxVB+start, sizeof(*fxVB)); - (void) parity; + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + GLuint shift = fxMesa->vertex_stride_shift; + char *fxVB = fxMesa->verts + (start << shift); + int mode; + (void) flags; + +/* fprintf(stderr, "%s/%d\n", __FUNCTION__, 1<<shift); */ +/* if(!prevLockLine) abort(); */ + + if (flags & PRIM_PARITY) + mode = GR_TRIANGLE_STRIP_CONTINUE; + else + mode = GR_TRIANGLE_STRIP; + + fxMesa->Glide.grDrawVertexArrayContiguous( mode, count-start, + fxVB, 1<<shift); } -static void tdfx_render_vb_tri_fan( struct vertex_buffer *VB, +static void tdfx_render_vb_tri_fan( GLcontext *ctx, GLuint start, GLuint count, - GLuint parity ) + GLuint flags ) { - tdfxContextPtr fxMesa = TDFX_CONTEXT(VB->ctx); - tdfxVertexPtr fxVB = TDFX_DRIVER_DATA(VB)->verts; + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + GLuint shift = fxMesa->vertex_stride_shift; + char *fxVB = fxMesa->verts + (start << shift); + (void) flags; + fxMesa->Glide.grDrawVertexArrayContiguous( GR_TRIANGLE_FAN, count-start, - fxVB+start, sizeof(*fxVB) ); - (void) parity; + fxVB, 1<<shift ); } +static void tdfx_render_vb_quads( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + GLuint shift = fxMesa->vertex_stride_shift; + char *fxVB = fxMesa->verts; + GLuint i; + (void) flags; + + for (i = start ; i < count-3 ; i += 4 ) { +#define VERT(x) (fxVB + ((x)<<shift)) + fxMesa->Glide.grDrawTriangle( VERT(i), VERT(i+1), VERT(i+3) ); + fxMesa->Glide.grDrawTriangle( VERT(i+1), VERT(i+2), VERT(i+3) ); +#undef VERT + } +} + +static void tdfx_render_vb_quad_strip( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + GLuint shift = fxMesa->vertex_stride_shift; + char *fxVB = fxMesa->verts + (start << shift); + (void) flags; + + count -= (count-start)&1; + + fxMesa->Glide.grDrawVertexArrayContiguous( GR_TRIANGLE_STRIP, + count-start, fxVB, 1<<shift); +} -static void tdfx_render_vb_poly( struct vertex_buffer *VB, +static void tdfx_render_vb_poly( GLcontext *ctx, GLuint start, GLuint count, - GLuint parity ) + GLuint flags ) { - tdfxContextPtr fxMesa = TDFX_CONTEXT(VB->ctx); - tdfxVertexPtr fxVB = TDFX_DRIVER_DATA(VB)->verts; + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + GLuint shift = fxMesa->vertex_stride_shift; + char *fxVB = fxMesa->verts + (start << shift); + (void) flags; + fxMesa->Glide.grDrawVertexArrayContiguous( GR_POLYGON, count-start, - fxVB+start, sizeof(*fxVB)); - (void) parity; + fxVB, 1<<shift); } +static void tdfx_render_vb_noop( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + (void) (ctx && start && count && flags); +} -#define RENDER_POINTS( start, count ) \ -do { \ - int i; \ - for (i = start ; i < count ; i++) { \ - v[elt[i]].v.x += PNT_X_OFFSET - TRI_X_OFFSET; \ - v[elt[i]].v.y += PNT_Y_OFFSET - TRI_Y_OFFSET; \ - fxMesa->Glide.grDrawPoint(&v[elt[i]]); \ - v[elt[i]].v.x -= PNT_X_OFFSET - TRI_X_OFFSET; \ - v[elt[i]].v.y -= PNT_Y_OFFSET - TRI_Y_OFFSET; \ - } \ -} while (0) +static void (*tdfx_render_tab_verts[GL_POLYGON+2])(GLcontext *, + GLuint, + GLuint, + GLuint) = +{ + tdfx_render_vb_points, + tdfx_render_vb_lines, + tdfx_render_vb_line_loop, + tdfx_render_vb_line_strip, + tdfx_render_vb_triangles, + tdfx_render_vb_tri_strip, + tdfx_render_vb_tri_fan, + tdfx_render_vb_quads, + tdfx_render_vb_quad_strip, + tdfx_render_vb_poly, + tdfx_render_vb_noop, +}; -#define RENDER_LINE( i0, i1 ) \ -do { \ - v[elt[i0]].v.x += LINE_X_OFFSET - TRI_X_OFFSET; \ - v[elt[i0]].v.y += LINE_Y_OFFSET - TRI_Y_OFFSET; \ - v[elt[i1]].v.x += LINE_X_OFFSET - TRI_X_OFFSET; \ - v[elt[i1]].v.y += LINE_Y_OFFSET - TRI_Y_OFFSET; \ - fxMesa->Glide.grDrawLine( &v[elt[i0]], &v[elt[i1]] );\ - v[elt[i0]].v.x -= LINE_X_OFFSET - TRI_X_OFFSET; \ - v[elt[i0]].v.y -= LINE_Y_OFFSET - TRI_Y_OFFSET; \ - v[elt[i1]].v.x -= LINE_X_OFFSET - TRI_X_OFFSET; \ - v[elt[i1]].v.y -= LINE_Y_OFFSET - TRI_Y_OFFSET; \ -} while (0) -#define RENDER_TRI( i2, i1, i, pv, parity ) \ -do { \ - if (parity) fxMesa->Glide.grDrawTriangle( &v[elt[i1]], &v[elt[i2]], &v[elt[i]] ); \ - else fxMesa->Glide.grDrawTriangle( &v[elt[i2]], &v[elt[i1]], &v[elt[i]] ); \ -} while (0) +/**********************************************************************/ +/* Render whole (indexed) begin/end objects */ +/**********************************************************************/ -#define RENDER_QUAD( i3, i2, i1, i, pv ) \ -do { \ - fxMesa->Glide.grDrawTriangle( &v[elt[i3]], &v[elt[i2]], &v[elt[i]] ); \ - fxMesa->Glide.grDrawTriangle( &v[elt[i2]], &v[elt[i1]], &v[elt[i]] ); \ -} while (0) +#define VERT(x) (tdfxVertex *)(vertptr + ((x)<<vertshift)) + +#define RENDER_POINTS( start, count ) \ + for ( ; start < count ; start++) \ + fxMesa->Glide.grDrawPoint( VERT(ELT(start)) ); + +#define RENDER_LINE( v0, v1 ) \ + fxMesa->Glide.grDrawLine( VERT(v0), VERT(v1) ) + +#define RENDER_TRI( v0, v1, v2 ) \ + fxMesa->Glide.grDrawTriangle( VERT(v0), VERT(v1), VERT(v2) ) + +#define RENDER_QUAD( v0, v1, v2, v3 ) \ + tdfx_draw_quad( fxMesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) ) + +#define INIT(x) tdfxRenderPrimitive( ctx, x ) -#define LOCAL_VARS \ - GLcontext *ctx = VB->ctx; \ - tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); \ - const GLuint *elt = VB->EltPtr->data; \ - tdfxVertexPtr v = TDFX_DRIVER_DATA(VB)->verts; \ - (void) v; (void) ctx; +#undef LOCAL_VARS +#define LOCAL_VARS \ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); \ + GLubyte *vertptr = (GLubyte *)fxMesa->verts; \ + const GLuint vertshift = fxMesa->vertex_stride_shift; \ + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \ + (void) elt; +#define RESET_STIPPLE +#define RESET_OCCLUSION +#define PRESERVE_VB_DEFS + +/* Elts, no clipping. + */ +#undef ELT +#undef TAG #define TAG(x) tdfx_##x##_elts -#include "render_tmp.h" +#define ELT(x) elt[x] +#include "tnl_dd/t_dd_rendertmp.h" -static void tdfxDDRenderEltsRaw( struct vertex_buffer *VB ) -{ - GLcontext *ctx = VB->ctx; - tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); - struct vertex_buffer *OldVB = ctx->VB; - GLenum prim = ctx->CVA.elt_mode; - GLuint nr = VB->EltPtr->count; - render_func func = tdfx_render_tab_elts[prim]; - GLuint p = 0; - ctx->VB = VB; - ctx->Driver.RenderStart( ctx ); +/**********************************************************************/ +/* Render clipped primitives */ +/**********************************************************************/ - BEGIN_CLIP_LOOP_LOCKED( fxMesa ); - do { - func( VB, 0, nr, 0 ); - } while ( ctx->Driver.MultipassFunc && - ctx->Driver.MultipassFunc( VB, ++p ) ); - END_CLIP_LOOP_LOCKED( fxMesa ); - ctx->Driver.RenderFinish( ctx ); - ctx->VB = OldVB; -} +static void tdfxRenderClippedPoly( GLcontext *ctx, const GLuint *elts, + GLuint n ) +{ + tdfxContextPtr fxMesa = TDFX_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; + } + + /* Restore the render primitive + */ + if (prim != GL_POLYGON) + tnl->Driver.Render.PrimitiveNotify( ctx, prim ); +} -void tdfxDDTriangleFuncsInit( void ) +static void tdfxRenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj ) { - init(); - init_flat(); - init_offset(); - init_offset_flat(); - init_twoside(); - init_twoside_flat(); - init_twoside_offset(); - init_twoside_offset_flat(); + TNLcontext *tnl = TNL_CONTEXT(ctx); + tnl->Driver.Render.Line( ctx, ii, jj ); +} - init_cliprect(); - init_flat_cliprect(); - init_offset_cliprect(); - init_offset_flat_cliprect(); - init_twoside_cliprect(); - init_twoside_flat_cliprect(); - init_twoside_offset_cliprect(); - init_twoside_offset_flat_cliprect(); - - rast_tab[0].render_tab[GL_POINTS] = tdfx_render_vb_points; - rast_tab[0].render_tab[GL_LINE_STRIP] = tdfx_render_vb_line_strip; - rast_tab[0].render_tab[GL_LINES] = tdfx_render_vb_lines; - rast_tab[0].render_tab[GL_TRIANGLES] = tdfx_render_vb_triangles; - rast_tab[0].render_tab[GL_TRIANGLE_STRIP] = tdfx_render_vb_tri_strip; - rast_tab[0].render_tab[GL_TRIANGLE_FAN] = tdfx_render_vb_tri_fan; - rast_tab[0].render_tab[GL_POLYGON] = tdfx_render_vb_poly; - - tdfx_render_init_elts(); -} - - -#define ALL_FALLBACK (DD_SELECT | DD_FEEDBACK) -#define POINT_FALLBACK (ALL_FALLBACK | DD_POINT_SMOOTH | DD_POINT_ATTEN) -#define LINE_FALLBACK (ALL_FALLBACK | DD_LINE_STIPPLE) -#define TRI_FALLBACK (ALL_FALLBACK | DD_TRI_SMOOTH | DD_TRI_UNFILLED) -#define ANY_FALLBACK (POINT_FALLBACK | LINE_FALLBACK | TRI_FALLBACK | DD_TRI_STIPPLE | DD_LINE_SMOOTH | DD_LINE_WIDTH | DD_POINT_SIZE ) -#define ANY_RENDER_FLAGS (DD_FLATSHADE | DD_TRI_LIGHT_TWOSIDE | DD_TRI_OFFSET) - -/* 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. - */ -void tdfxDDChooseRenderState( GLcontext *ctx ) +static void tdfxFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, + GLuint n ) { tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); - GLuint flags = ctx->TriangleCaps; - CARD32 index = 0; - fxMesa->RenderElementsRaw = tdfxDDRenderEltsRaw; + GLubyte *vertptr = (GLubyte *)fxMesa->verts; + const GLuint vertshift = fxMesa->vertex_stride_shift; + const GLuint *start = (const GLuint *)VERT(elts[0]); + int i; - if ( fxMesa->Fallback ) { - fxMesa->RenderElementsRaw = gl_render_elts; - fxMesa->RenderIndex = TDFX_FALLBACK_BIT; - return; + for (i = 2 ; i < n ; i++) { + fxMesa->Glide.grDrawTriangle( start, VERT(elts[i-1]), VERT(elts[i]) ); } +} + +/**********************************************************************/ +/* Choose render functions */ +/**********************************************************************/ - if ( flags & ANY_RENDER_FLAGS ) { - if ( flags & DD_FLATSHADE ) index |= TDFX_FLAT_BIT; - if ( flags & DD_TRI_LIGHT_TWOSIDE ) index |= TDFX_TWOSIDE_BIT; - if ( flags & DD_TRI_OFFSET ) index |= TDFX_OFFSET_BIT; - fxMesa->RenderElementsRaw = gl_render_elts; + +#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) + + +/* All state referenced below: + */ +#define _TDFX_NEW_RENDERSTATE (_DD_NEW_POINT_SMOOTH | \ + _DD_NEW_LINE_STIPPLE | \ + _DD_NEW_TRI_SMOOTH | \ + _DD_NEW_FLATSHADE | \ + _DD_NEW_TRI_UNFILLED | \ + _DD_NEW_TRI_LIGHT_TWOSIDE | \ + _DD_NEW_TRI_OFFSET | \ + _DD_NEW_TRI_STIPPLE | \ + _NEW_POLYGONSTIPPLE) + + +static void tdfxChooseRenderState(GLcontext *ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + GLuint flags = ctx->_TriangleCaps; + GLuint index = 0; + + if (0) { + fxMesa->draw_point = tdfx_draw_point; + fxMesa->draw_line = tdfx_draw_line; + fxMesa->draw_triangle = tdfx_draw_triangle; + index |= TDFX_FALLBACK_BIT; } - if ( fxMesa->numClipRects > 1 ) - index |= TDFX_CLIPRECT_BIT; - - fxMesa->PointsFunc = rast_tab[index].points; - fxMesa->LineFunc = rast_tab[index].line; - fxMesa->TriangleFunc = rast_tab[index].triangle; - fxMesa->QuadFunc = rast_tab[index].quad; - fxMesa->RenderVBRawTab = rast_tab[index].render_tab; - fxMesa->RenderIndex = index; - fxMesa->IndirectTriangles = 0; - - if ( flags & ANY_FALLBACK ) { - if ( flags & POINT_FALLBACK ) { - fxMesa->PointsFunc = 0; - fxMesa->RenderVBRawTab = 0; - fxMesa->IndirectTriangles |= DD_POINT_SW_RASTERIZE; - fxMesa->RenderIndex |= TDFX_FALLBACK_BIT; + if (flags & (ANY_FALLBACK_FLAGS|ANY_RASTER_FLAGS)) { + if (flags & ANY_RASTER_FLAGS) { + if (flags & DD_TRI_LIGHT_TWOSIDE) index |= TDFX_TWOSIDE_BIT; + if (flags & DD_TRI_OFFSET) index |= TDFX_OFFSET_BIT; + if (flags & DD_TRI_UNFILLED) index |= TDFX_UNFILLED_BIT; + if (flags & DD_FLATSHADE) index |= TDFX_FLAT_BIT; } - if ( flags & LINE_FALLBACK ) { - fxMesa->LineFunc = 0; - fxMesa->RenderVBRawTab = 0; - fxMesa->IndirectTriangles |= DD_LINE_SW_RASTERIZE; - fxMesa->RenderIndex |= TDFX_FALLBACK_BIT; + fxMesa->draw_point = tdfx_draw_point; + fxMesa->draw_line = tdfx_draw_line; + fxMesa->draw_triangle = tdfx_draw_triangle; + + /* Hook in fallbacks for specific primitives. + * + * DD_TRI_UNFILLED is here because the unfilled_tri functions use + * fxMesa->draw_tri *always*, and thus can't use the multipass + * approach to cliprects. + * + */ + if (flags & (POINT_FALLBACK| + LINE_FALLBACK| + TRI_FALLBACK| + DD_TRI_STIPPLE| + DD_TRI_UNFILLED)) + { + if (flags & POINT_FALLBACK) + fxMesa->draw_point = tdfx_fallback_point; + + if (flags & LINE_FALLBACK) + fxMesa->draw_line = tdfx_fallback_line; + + if (flags & TRI_FALLBACK) + fxMesa->draw_triangle = tdfx_fallback_tri; + + if ((flags & DD_TRI_STIPPLE) && !fxMesa->haveHwStipple) + fxMesa->draw_triangle = tdfx_fallback_tri; + + index |= TDFX_FALLBACK_BIT; } + } - if ( flags & TRI_FALLBACK ) { - fxMesa->TriangleFunc = 0; - fxMesa->QuadFunc = 0; - fxMesa->RenderVBRawTab = 0; - fxMesa->IndirectTriangles |= (DD_TRI_SW_RASTERIZE | - DD_QUAD_SW_RASTERIZE); - fxMesa->RenderIndex |= TDFX_FALLBACK_BIT; + if (fxMesa->RenderIndex != index) { + fxMesa->RenderIndex = index; + + tnl->Driver.Render.Points = rast_tab[index].points; + tnl->Driver.Render.Line = 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 = tdfx_render_tab_verts; + tnl->Driver.Render.PrimTabElts = tdfx_render_tab_elts; + tnl->Driver.Render.ClippedLine = line; /* from tritmp.h */ + tnl->Driver.Render.ClippedPolygon = tdfxFastRenderClippedPoly; + } else { + tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; + tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; + tnl->Driver.Render.ClippedLine = tdfxRenderClippedLine; + tnl->Driver.Render.ClippedPolygon = tdfxRenderClippedPoly; } + } +} - /* Special case: wide, AA lines must be done in software */ - if (flags & DD_LINE_SMOOTH) { - if (ctx->Line.Width != 1.0) { - fxMesa->RenderVBRawTab = 0; - fxMesa->LineFunc = 0; - fxMesa->IndirectTriangles |= DD_LINE_SW_RASTERIZE; - fxMesa->RenderIndex |= TDFX_FALLBACK_BIT; - } - } +/**********************************************************************/ +/* Use multipass rendering for cliprects */ +/**********************************************************************/ - /* Special case: we can do polygon stipples, but otherwise */ - if ((flags & DD_TRI_STIPPLE) && - (ctx->IndirectTriangles & DD_TRI_STIPPLE)) { - fxMesa->TriangleFunc = 0; - fxMesa->QuadFunc = 0; - fxMesa->RenderVBRawTab = 0; - fxMesa->IndirectTriangles |= (DD_TRI_SW_RASTERIZE | - DD_QUAD_SW_RASTERIZE); - fxMesa->RenderIndex |= TDFX_FALLBACK_BIT; - } - if (flags & (DD_LINE_WIDTH | DD_POINT_SIZE)) - fxMesa->RenderVBRawTab = 0; - fxMesa->RenderElementsRaw = gl_render_elts; +/* TODO: Benchmark this. + * TODO: Use single back-buffer cliprect where possible. + * NOTE: <pass> starts at 1, not zero! + */ +static GLboolean multipass_cliprect( GLcontext *ctx, GLuint pass ) +{ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + if (pass >= fxMesa->numClipRects) + return GL_FALSE; + else { + fxMesa->Glide.grClipWindow(fxMesa->pClipRects[pass].x1, + fxMesa->screen_height - fxMesa->pClipRects[pass].y2, + fxMesa->pClipRects[pass].x2, + fxMesa->screen_height - fxMesa->pClipRects[pass].y1); + + return GL_TRUE; + } +} + + +/**********************************************************************/ +/* Runtime render state and callbacks */ +/**********************************************************************/ + +static void tdfxRunPipeline( GLcontext *ctx ) +{ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + + if (fxMesa->new_state) { + tdfxDDUpdateHwState( ctx ); + } + + if (!fxMesa->Fallback && fxMesa->new_gl_state) { + if (fxMesa->new_gl_state & _TDFX_NEW_RASTERSETUP) + tdfxChooseVertexState( ctx ); + + if (fxMesa->new_gl_state & _TDFX_NEW_RENDERSTATE) + tdfxChooseRenderState( ctx ); + + fxMesa->new_gl_state = 0; } + _tnl_run_pipeline( ctx ); +} + + +static void tdfxRenderStart( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + + tdfxCheckTexSizes( ctx ); - if ( 0 ) { - gl_print_tri_caps( "tricaps", ctx->TriangleCaps ); - tdfxPrintRenderState( "tdfx render state", fxMesa->RenderIndex ); + LOCK_HARDWARE(fxMesa); + + /* Make sure vertex format changes get uploaded before we start + * sending triangles. + */ + if (fxMesa->dirty) { + tdfxEmitHwStateLocked( fxMesa ); + } + + if (fxMesa->numClipRects && !(fxMesa->RenderIndex & TDFX_FALLBACK_BIT)) { + fxMesa->Glide.grClipWindow(fxMesa->pClipRects[0].x1, + fxMesa->screen_height - fxMesa->pClipRects[0].y2, + fxMesa->pClipRects[0].x2, + fxMesa->screen_height - fxMesa->pClipRects[0].y1); + if (fxMesa->numClipRects > 1) + tnl->Driver.Render.Multipass = multipass_cliprect; + else + tnl->Driver.Render.Multipass = NULL; } + else + tnl->Driver.Render.Multipass = NULL; } -void tdfxDDToggleTriCliprects( GLcontext *ctx ) +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 +}; + + + +/* Always called between RenderStart and RenderFinish --> We already + * hold the lock. + */ +static void tdfxRasterPrimitive( GLcontext *ctx, GLenum prim ) { tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); - int oldidx = fxMesa->RenderIndex; - int newidx; - if (fxMesa->Fallback) + FLUSH_BATCH( fxMesa ); + + fxMesa->raster_primitive = prim; + + tdfxUpdateCull(ctx); + if ( fxMesa->dirty & TDFX_UPLOAD_CULL ) { + fxMesa->Glide.grCullMode( fxMesa->CullMode ); + fxMesa->dirty &= ~TDFX_UPLOAD_CULL; + } + + tdfxUpdateStipple(ctx); + if ( fxMesa->dirty & TDFX_UPLOAD_STIPPLE ) { + fxMesa->Glide.grStipplePattern ( fxMesa->Stipple.Pattern ); + fxMesa->Glide.grStippleMode ( fxMesa->Stipple.Mode ); + fxMesa->dirty &= ~TDFX_UPLOAD_STIPPLE; + } +} + + + +/* Determine the rasterized primitive when not drawing unfilled + * polygons. + * + * Used only for the default render stage which always decomposes + * primitives to trianges/lines/points. For the accelerated stage, + * which renders strips as strips, the equivalent calculations are + * performed in tdfx_render.c. + */ +static void tdfxRenderPrimitive( GLcontext *ctx, GLenum prim ) +{ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + GLuint rprim = reduced_prim[prim]; + + fxMesa->render_primitive = prim; + + if (rprim == GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED)) return; + + if (fxMesa->raster_primitive != rprim) { + tdfxRasterPrimitive( ctx, rprim ); + } +} + +static void tdfxRenderFinish( GLcontext *ctx ) +{ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + + if (fxMesa->RenderIndex & TDFX_FALLBACK_BIT) + _swrast_flush( ctx ); + + UNLOCK_HARDWARE(fxMesa); +} - if (fxMesa->numClipRects > 1) - newidx = (fxMesa->RenderIndex |= TDFX_CLIPRECT_BIT); - else - newidx = (fxMesa->RenderIndex &= ~TDFX_CLIPRECT_BIT); - if (ctx->Driver.TriangleFunc == rast_tab[oldidx].triangle) - ctx->Driver.TriangleFunc = rast_tab[newidx].triangle; - if (ctx->Driver.QuadFunc == rast_tab[oldidx].quad) - ctx->Driver.QuadFunc = rast_tab[newidx].quad; +/* + * These functions are used when we're software rendering, and + * lock/unlock the hardware (for span reading/writing). + */ +static void tdfxSwSetupStart( GLcontext *ctx ) +{ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + LOCK_HARDWARE(fxMesa); +} + +static void tdfxSwSetupFinish( GLcontext *ctx ) +{ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + UNLOCK_HARDWARE(fxMesa); +} - if (ctx->Driver.LineFunc == rast_tab[oldidx].line) - ctx->Driver.LineFunc = rast_tab[newidx].line; - if (ctx->Driver.PointsFunc == rast_tab[oldidx].points) - ctx->Driver.PointsFunc = rast_tab[newidx].points; +/**********************************************************************/ +/* Manage total rasterization fallbacks */ +/**********************************************************************/ - if (ctx->Driver.RenderVBRawTab == rast_tab[oldidx].render_tab) - ctx->Driver.RenderVBRawTab = rast_tab[newidx].render_tab; +static char *fallbackStrings[] = { + "1D/3D Texture map", + "glDrawBuffer(GL_FRONT_AND_BACK)", + "Separate specular color", + "glEnable/Disable(GL_STENCIL_TEST)", + "glRenderMode(selection or feedback)", + "glLogicOp()", + "Texture env mode", + "Texture border", + "glColorMask", + "blend mode", + "line stipple" +}; - if (ctx->TriangleFunc == rast_tab[oldidx].triangle) - ctx->TriangleFunc = rast_tab[newidx].triangle; - if (ctx->QuadFunc == rast_tab[oldidx].quad) - ctx->QuadFunc = rast_tab[newidx].quad; +static char *getFallbackString(GLuint bit) +{ + int i = 0; + while (bit > 1) { + i++; + bit >>= 1; + } + return fallbackStrings[i]; +} - fxMesa->PointsFunc = rast_tab[newidx].points; - fxMesa->LineFunc = rast_tab[newidx].line; - fxMesa->TriangleFunc = rast_tab[newidx].triangle; - fxMesa->QuadFunc = rast_tab[newidx].quad; - fxMesa->RenderVBRawTab = rast_tab[newidx].render_tab; - if (newidx == 0 && - (ctx->IndirectTriangles & (DD_LINE_WIDTH|DD_POINT_SIZE)) == 0) - fxMesa->RenderElementsRaw = tdfxDDRenderEltsRaw; - else - fxMesa->RenderElementsRaw = gl_render_elts; +void tdfxFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + GLuint oldfallback = fxMesa->Fallback; + + if (mode) { + fxMesa->Fallback |= bit; + if (oldfallback == 0) { + /*printf("Go to software rendering, bit = 0x%x\n", bit);*/ + FLUSH_BATCH(fxMesa); + _swsetup_Wakeup( ctx ); + fxMesa->RenderIndex = ~0; + if (fxMesa->debugFallbacks) { + fprintf(stderr, "Tdfx begin software fallback: 0x%x %s\n", + bit, getFallbackString(bit)); + } + } + } + else { + fxMesa->Fallback &= ~bit; + if (oldfallback == bit) { + /*printf("Go to hardware rendering, bit = 0x%x\n", bit);*/ + _swrast_flush( ctx ); + tnl->Driver.Render.Start = tdfxRenderStart; + tnl->Driver.Render.PrimitiveNotify = tdfxRenderPrimitive; + tnl->Driver.Render.Finish = tdfxRenderFinish; + tnl->Driver.Render.BuildVertices = tdfxBuildVertices; + fxMesa->new_gl_state |= (_TDFX_NEW_RENDERSTATE| + _TDFX_NEW_RASTERSETUP); + if (fxMesa->debugFallbacks) { + fprintf(stderr, "Tdfx end software fallback: 0x%x %s\n", + bit, getFallbackString(bit)); + } + } + } +} + + +void tdfxDDInitTriFuncs( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + SScontext *swsetup = SWSETUP_CONTEXT(ctx); + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + static int firsttime = 1; + + if (firsttime) { + init_rast_tab(); + firsttime = 0; + } + + fxMesa->RenderIndex = ~0; + + tnl->Driver.RunPipeline = tdfxRunPipeline; + tnl->Driver.Render.Start = tdfxRenderStart; + tnl->Driver.Render.Finish = tdfxRenderFinish; + tnl->Driver.Render.PrimitiveNotify = tdfxRenderPrimitive; + tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple; + tnl->Driver.Render.BuildVertices = tdfxBuildVertices; + tnl->Driver.Render.Multipass = NULL; + + + swsetup->Driver.Start = tdfxSwSetupStart; + swsetup->Driver.Finish = tdfxSwSetupFinish; - if (0) - tdfxPrintRenderState( "toggle tdfx render state", fxMesa->RenderIndex ); + (void) tdfx_print_vertex; } diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tris.h b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tris.h index 4ef310b3a..04a3be507 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tris.h +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tris.h @@ -23,154 +23,21 @@ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_tris.h,v 1.2 2001/08/18 02:51:07 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_tris.h,v 1.1 2001/03/21 16:14:28 dawes Exp $ */ /* - * Original rewrite: - * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 - * * Authors: - * Gareth Hughes <gareth@valinux.com> - * Brian Paul <brianp@valinux.com> * Keith Whitwell <keithw@valinux.com> * */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810tris.h,v 1.8 2000/12/04 19:21:43 dawes Exp $ */ -#ifndef __TDFX_TRIS_H__ -#define __TDFX_TRIS_H__ - -#ifdef GLX_DIRECT_RENDERING - -#include "tdfx_vb.h" -#include "tdfx_render.h" - -extern void tdfxDDChooseRenderState( GLcontext *ctx ); -extern void tdfxDDTriangleFuncsInit( void ); - - -#define TDFX_FLAT_BIT 0x01 -#define TDFX_OFFSET_BIT 0x02 -#define TDFX_TWOSIDE_BIT 0x04 -#define TDFX_CLIPRECT_BIT 0x10 -#define TDFX_FALLBACK_BIT 0x20 -#define TDFX_MAX_TRIFUNC 0x40 - - -static __inline void tdfx_draw_triangle( tdfxContextPtr fxMesa, - tdfxVertex *v0, - tdfxVertex *v1, - tdfxVertex *v2 ) -{ - fxMesa->Glide.grDrawTriangle( v0, v1, v2 ); -} - - -static __inline void tdfx_draw_point( tdfxContextPtr fxMesa, - tdfxVertex *tmp, float sz ) -{ - if ( sz <= 1.0 ) { - /* Save and restore original x,y rather than copying whole - * vertex. - */ - GLfloat x = tmp->v.x, y = tmp->v.y; - tmp->v.x += PNT_X_OFFSET - TRI_X_OFFSET; - tmp->v.y += PNT_Y_OFFSET - TRI_Y_OFFSET; - fxMesa->Glide.grDrawPoint( tmp ); - tmp->v.x = x; - tmp->v.y = y; - } - else { - const GLfloat xLeft = tmp->v.x - 0.5 * sz - TRI_X_OFFSET + PNT_X_OFFSET; - const GLfloat xRight = tmp->v.x + 0.5 * sz - TRI_X_OFFSET + PNT_X_OFFSET; - const GLfloat yBot = tmp->v.y - 0.5 * sz - TRI_Y_OFFSET + PNT_Y_OFFSET; - const GLfloat yTop = tmp->v.y + 0.5 * sz - TRI_Y_OFFSET + PNT_Y_OFFSET; - tdfxVertex verts[4]; - - verts[0] = *tmp; - verts[1] = *tmp; - verts[2] = *tmp; - verts[3] = *tmp; - - verts[0].v.x = xLeft; - verts[0].v.y = yBot; - - verts[1].v.x = xRight; - verts[1].v.y = yBot; - - verts[2].v.x = xRight; - verts[2].v.y = yTop; - - verts[3].v.x = xLeft; - verts[3].v.y = yTop; - - fxMesa->Glide.grDrawVertexArrayContiguous( GR_TRIANGLE_FAN, 4, verts, - sizeof(tdfxVertex) ); - } -} - - -static __inline void tdfx_draw_line( tdfxContextPtr fxMesa, - tdfxVertex *tmp0, - tdfxVertex *tmp1, - float width ) -{ - if ( width <= 1.0 ) - { - /* Faster to save and restore 4 dwords than to copy 32 dwords. - */ - GLfloat x0 = tmp0->v.x, y0 = tmp0->v.y; - GLfloat x1 = tmp1->v.x, y1 = tmp1->v.y; - tmp0->v.x += LINE_X_OFFSET - TRI_X_OFFSET; - tmp0->v.y += LINE_Y_OFFSET - TRI_Y_OFFSET; - tmp1->v.x += LINE_X_OFFSET - TRI_X_OFFSET; - tmp1->v.y += LINE_Y_OFFSET - TRI_Y_OFFSET; - fxMesa->Glide.grDrawLine(tmp0, tmp1); - tmp0->v.x = x0; - tmp0->v.y = y0; - tmp1->v.x = x1; - tmp1->v.y = y1; - } - else - { - tdfxVertex verts[4]; - float dx, dy, ix, iy; - - dx = tmp0->v.x - tmp1->v.x; - dy = tmp0->v.y - tmp1->v.y; - - if (dx * dx > dy * dy) { - iy = width * .5; - ix = 0; - } else { - iy = 0; - ix = width * .5; - } - - verts[0] = *tmp0; - verts[1] = *tmp0; - verts[2] = *tmp1; - verts[3] = *tmp1; - - verts[0].v.x = tmp0->v.x - ix; - verts[0].v.y = tmp0->v.y - iy; - - verts[1].v.x = tmp0->v.x + ix; - verts[1].v.y = tmp0->v.y + iy; - - verts[2].v.x = tmp1->v.x + ix; - verts[2].v.y = tmp1->v.y + iy; - - verts[3].v.x = tmp1->v.x - ix; - verts[3].v.y = tmp1->v.y - iy; - - fxMesa->Glide.grDrawVertexArrayContiguous( GR_TRIANGLE_FAN, 4, verts, - sizeof(tdfxVertex) ); - } -} +#ifndef TDFX_TRIS_INC +#define TDFX_TRIS_INC -void tdfxDDToggleTriCliprects( GLcontext *ctx ); +#include "mtypes.h" +extern void tdfxDDInitTriFuncs( GLcontext *ctx ); -#endif /* GLX_DIRECT_RENDERING */ -#endif /* __TDFX_TRIS_H__ */ +#endif diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tritmp.h b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tritmp.h deleted file mode 100644 index 04d01e7f2..000000000 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tritmp.h +++ /dev/null @@ -1,415 +0,0 @@ -/* -*- 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/tdfx/tdfx_tritmp.h,v 1.2 2001/08/18 02:51:07 dawes Exp $ */ - -/* - * Original rewrite: - * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 - * - * Authors: - * Gareth Hughes <gareth@valinux.com> - * Keith Whitwell <keithw@valinux.com> - * - */ - -static __inline void TAG(triangle)( GLcontext *ctx, - GLuint e0, GLuint e1, GLuint e2, - GLuint pv ) -{ - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - struct vertex_buffer *VB = ctx->VB; - tdfxVertexPtr fxverts = TDFX_DRIVER_DATA(VB)->verts; - tdfxVertex *v[3]; - -#if (IND & TDFX_OFFSET_BIT) - GLfloat offset; - GLfloat z[3]; -#endif - -#if (IND & (TDFX_TWOSIDE_BIT | TDFX_FLAT_BIT)) - GLuint c[3]; -#endif - - v[0] = &fxverts[e0]; - v[1] = &fxverts[e1]; - v[2] = &fxverts[e2]; - -#if (IND & (TDFX_TWOSIDE_BIT | TDFX_FLAT_BIT)) - c[0] = v[0]->ui[4]; - c[1] = v[1]->ui[4]; - c[2] = v[2]->ui[4]; -#endif - - -#if (IND & (TDFX_TWOSIDE_BIT | TDFX_OFFSET_BIT)) - { - GLfloat ex = v[0]->v.x - v[2]->v.x; - GLfloat ey = v[0]->v.y - v[2]->v.y; - GLfloat fx = v[1]->v.x - v[2]->v.x; - GLfloat fy = v[1]->v.y - v[2]->v.y; - GLfloat cc = ex*fy - ey*fx; - -#if (IND & TDFX_TWOSIDE_BIT) - { - GLuint facing = ( cc < 0.0 ) ^ ctx->Polygon.FrontBit; - GLubyte (*vbcolor)[4] = VB->Color[facing]->data; - if (IND & TDFX_FLAT_BIT) { - TDFX_COLOR( (char *)&v[0]->ui[4], vbcolor[pv] ); - v[2]->ui[4] = v[1]->ui[4] = v[0]->ui[4]; - } else { - TDFX_COLOR( (char *)&v[0]->ui[4], vbcolor[e0] ); - TDFX_COLOR( (char *)&v[1]->ui[4], vbcolor[e1] ); - TDFX_COLOR( (char *)&v[2]->ui[4], vbcolor[e2] ); - } - } -#endif - -#if (IND & TDFX_OFFSET_BIT) - { - offset = ctx->Polygon.OffsetUnits; - z[0] = v[0]->v.z; - z[1] = v[1]->v.z; - z[2] = v[2]->v.z; - if (cc * cc > 1e-16) { - GLfloat ez = z[0] - z[2]; - GLfloat fz = z[1] - z[2]; - GLfloat a = ey*fz - ez*fy; - GLfloat b = ez*fx - ex*fz; - GLfloat ic = 1.0 / cc; - GLfloat ac = a * ic; - GLfloat bc = b * ic; - if ( ac < 0.0f ) ac = -ac; - if ( bc < 0.0f ) bc = -bc; - offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor; - - } - v[0]->v.z += offset; - v[1]->v.z += offset; - v[2]->v.z += offset; - } -#endif - } -#elif (IND & TDFX_FLAT_BIT) - { - GLuint color = fxverts[pv].ui[4]; - v[0]->ui[4] = color; - v[1]->ui[4] = color; - v[2]->ui[4] = color; - } -#endif - -#if (IND & TDFX_CLIPRECT_BIT) - BEGIN_CLIP_LOOP_LOCKED( fxMesa ); - fxMesa->Glide.grDrawTriangle( v[0], v[1], v[2] ); - END_CLIP_LOOP_LOCKED( fxMesa ); -#else - fxMesa->Glide.grDrawTriangle( v[0], v[1], v[2] ); -#endif - -#if (IND & TDFX_OFFSET_BIT) - v[0]->v.z = z[0]; - v[1]->v.z = z[1]; - v[2]->v.z = z[2]; -#endif - -#if (IND & (TDFX_FLAT_BIT | TDFX_TWOSIDE_BIT)) - v[0]->ui[4] = c[0]; - v[1]->ui[4] = c[1]; - v[2]->ui[4] = c[2]; -#endif - -} - - - -static __inline void TAG(quad)( GLcontext *ctx, GLuint e0, - GLuint e1, GLuint e2, GLuint e3, - GLuint pv ) -{ - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - struct vertex_buffer *VB = ctx->VB; - tdfxVertexPtr fxverts = TDFX_DRIVER_DATA(VB)->verts; - tdfxVertex *v[4]; - -#if (IND & TDFX_OFFSET_BIT) - GLfloat offset; - GLfloat z[4]; -#endif - -#if (IND & (TDFX_TWOSIDE_BIT | TDFX_FLAT_BIT)) - GLuint c[4]; -#endif - - v[0] = &fxverts[e0]; - v[1] = &fxverts[e1]; - v[2] = &fxverts[e2]; - v[3] = &fxverts[e3]; - - -/* fprintf(stderr, "%s\n", __FUNCTION__); */ - -#if (IND & (TDFX_TWOSIDE_BIT | TDFX_FLAT_BIT)) - c[0] = v[0]->ui[4]; - c[1] = v[1]->ui[4]; - c[2] = v[2]->ui[4]; - c[3] = v[3]->ui[4]; -#endif - - -#if (IND & (TDFX_TWOSIDE_BIT | TDFX_OFFSET_BIT)) - { - GLfloat ex = v[0]->v.x - v[2]->v.x; - GLfloat ey = v[0]->v.y - v[2]->v.y; - GLfloat fx = v[1]->v.x - v[2]->v.x; - GLfloat fy = v[1]->v.y - v[2]->v.y; - GLfloat cc = ex*fy - ey*fx; - -#if (IND & TDFX_TWOSIDE_BIT) - { - GLuint facing = ( cc < 0.0 ) ^ ctx->Polygon.FrontBit; - GLubyte (*vbcolor)[4] = VB->Color[facing]->data; - if (IND & TDFX_FLAT_BIT) { - TDFX_COLOR( (char *)&v[0]->ui[4], vbcolor[pv] ); - v[3]->ui[4] = v[2]->ui[4] = v[1]->ui[4] = v[0]->ui[4]; - } else { - TDFX_COLOR( (char *)&v[0]->ui[4], vbcolor[e0] ); - TDFX_COLOR( (char *)&v[1]->ui[4], vbcolor[e1] ); - TDFX_COLOR( (char *)&v[2]->ui[4], vbcolor[e2] ); - TDFX_COLOR( (char *)&v[3]->ui[4], vbcolor[e3] ); - } - } -#endif - -#if (IND & TDFX_OFFSET_BIT) - { - offset = ctx->Polygon.OffsetUnits; - z[0] = v[0]->v.z; - z[1] = v[1]->v.z; - z[2] = v[2]->v.z; - z[3] = v[3]->v.z; - if (cc * cc > 1e-16) { - GLfloat ez = z[0] - z[2]; - GLfloat fz = z[1] - z[2]; - GLfloat a = ey*fz - ez*fy; - GLfloat b = ez*fx - ex*fz; - GLfloat ic = 1.0 / cc; - GLfloat ac = a * ic; - GLfloat bc = b * ic; - if ( ac < 0.0f ) ac = -ac; - if ( bc < 0.0f ) bc = -bc; - offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor; - - } - v[0]->v.z += offset; - v[1]->v.z += offset; - v[2]->v.z += offset; - v[3]->v.z += offset; - } -#endif - } -#elif (IND & TDFX_FLAT_BIT) - { - GLuint color = fxverts[pv].ui[4]; - v[0]->ui[4] = color; - v[1]->ui[4] = color; - v[2]->ui[4] = color; - v[3]->ui[4] = color; - } -#endif - -/* Marginally faster to call grDrawTriangle twice - * than calling grDrawVertexArray. - */ -#if (IND & TDFX_CLIPRECT_BIT) - BEGIN_CLIP_LOOP_LOCKED( fxMesa ); -/* grDrawVertexArray( GR_TRIANGLE_FAN, 4, v ); */ - fxMesa->Glide.grDrawTriangle( v[0], v[1], v[3] ); - fxMesa->Glide.grDrawTriangle( v[1], v[2], v[3] ); - END_CLIP_LOOP_LOCKED( fxMesa ); -#else -/* grDrawVertexArray( GR_TRIANGLE_FAN, 4, v ); */ - fxMesa->Glide.grDrawTriangle( v[0], v[1], v[3] ); - fxMesa->Glide.grDrawTriangle( v[1], v[2], v[3] ); -#endif - -#if (IND & TDFX_OFFSET_BIT) - v[0]->v.z = z[0]; - v[1]->v.z = z[1]; - v[2]->v.z = z[2]; - v[3]->v.z = z[3]; -#endif - -#if (IND & (TDFX_FLAT_BIT | TDFX_TWOSIDE_BIT)) - v[0]->ui[4] = c[0]; - v[1]->ui[4] = c[1]; - v[2]->ui[4] = c[2]; - v[3]->ui[4] = c[3]; -#endif -} - - - - - -static __inline void TAG(line)( GLcontext *ctx, GLuint v0, GLuint v1, - GLuint pv ) -{ - tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); - tdfxVertexPtr fxVB = TDFX_DRIVER_DATA(ctx->VB)->verts; - float width = ctx->Line.Width; - GLfloat z0, z1; - GLuint c0, c1; - tdfxVertex *vert0 = &fxVB[v0]; - tdfxVertex *vert1 = &fxVB[v1]; - - if ( IND & TDFX_TWOSIDE_BIT ) { - GLubyte (*vbcolor)[4] = ctx->VB->ColorPtr->data; - - if ( IND & TDFX_FLAT_BIT ) { - TDFX_COLOR( (char *)&vert0->v.color,vbcolor[pv] ); - *(int *)&vert1->v.color = *(int *)&vert0->v.color; - } else { - TDFX_COLOR( (char *)&vert0->v.color,vbcolor[v0] ); - TDFX_COLOR( (char *)&vert1->v.color,vbcolor[v1] ); - } - } else if ( IND & TDFX_FLAT_BIT ) { - c0 = *(GLuint *) &(vert0->v.color); - c1 = *(GLuint *) &(vert1->v.color); - *(int *)&vert0->v.color = - *(int *)&vert1->v.color = *(int *)&fxVB[pv].v.color; - } - - if ( IND & TDFX_OFFSET_BIT ) { - GLfloat offset = ctx->LineZoffset; - z0 = vert0->v.z; - z1 = vert1->v.z; - vert0->v.z += offset; - vert1->v.z += offset; - } - - if (IND & TDFX_CLIPRECT_BIT) { - BEGIN_CLIP_LOOP_LOCKED( fxMesa ); - tdfx_draw_line( fxMesa, &fxVB[v0], &fxVB[v1], width ); - END_CLIP_LOOP_LOCKED( fxMesa ); - } else - tdfx_draw_line( fxMesa, &fxVB[v0], &fxVB[v1], width ); - - if ( IND & TDFX_OFFSET_BIT ) { - vert0->v.z = z0; - vert1->v.z = z1; - } - - if ( (IND & TDFX_FLAT_BIT) && !(IND & TDFX_TWOSIDE_BIT) ) { - *(GLuint *) &(vert0->v.color) = c0; - *(GLuint *) &(vert1->v.color) = c1; - } -} - - -static __inline void TAG(points)( GLcontext *ctx, GLuint first, GLuint last ) -{ - tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); - struct vertex_buffer *VB = ctx->VB; - tdfxVertexPtr fxVB = TDFX_DRIVER_DATA(VB)->verts; - GLfloat sz = ctx->Point.Size; - int i; - - for ( i = first ; i < last ; i++ ) { - if ( VB->ClipMask[i] == 0 ) { - if ( IND & (TDFX_TWOSIDE_BIT|TDFX_OFFSET_BIT) ) - { - tdfxVertex tmp0 = fxVB[i]; - - if ( IND & TDFX_TWOSIDE_BIT ) { - GLubyte (*vbcolor)[4] = VB->ColorPtr->data; - TDFX_COLOR( (char *)&tmp0.v.color, vbcolor[i] ); - } - - if ( IND & TDFX_OFFSET_BIT ) { - GLfloat offset = ctx->PointZoffset; - tmp0.v.z += offset; - } - - if (IND & TDFX_CLIPRECT_BIT) { - BEGIN_CLIP_LOOP_LOCKED( fxMesa ); - tdfx_draw_point( fxMesa, &tmp0, sz ); - END_CLIP_LOOP_LOCKED( fxMesa ); - } else - tdfx_draw_point( fxMesa, &tmp0, sz ); - } - else if (IND & TDFX_CLIPRECT_BIT) - { - BEGIN_CLIP_LOOP_LOCKED( fxMesa ); - tdfx_draw_point( fxMesa, &fxVB[i], sz ); - END_CLIP_LOOP_LOCKED( fxMesa ); - } - else - tdfx_draw_point( fxMesa, &fxVB[i], sz ); - } - } -} - - - - -/* Accelerate unclipped VB rendering when fxMesa->renderIndex != 0 - * - * The versions for renderIndex == 0 are further optimized and appear - * in tdfx_tris.c - */ -#if (TYPE == 0) -#define RENDER_POINTS( start, count ) TAG(points)( ctx, start, count ) -#define RENDER_LINE( i1, i ) TAG(line)( ctx, i1, i, i ) -#define RENDER_TRI( i2, i1, i, pv, parity ) \ - do { \ - if (parity) TAG(triangle)( ctx, i1, i2, i, pv ); \ - else TAG(triangle)( ctx, i2, i1, i, pv ); \ - } while (0) -#define RENDER_QUAD( i3, i2, i1, i, pv ) TAG(quad)( ctx, i3, i2, i1, i, pv ) -#define LOCAL_VARS GLcontext *ctx = VB->ctx; -#define PRESERVE_TAG -#include "render_tmp.h" -#endif - - - -static void TAG(init)( void ) -{ - rast_tab[IND].triangle = TAG(triangle); - rast_tab[IND].quad = TAG(quad); - rast_tab[IND].line = TAG(line); - rast_tab[IND].points = TAG(points); -#if (TYPE == 0) - rast_tab[IND].render_tab = TAG(render_tab); -#else - rast_tab[IND].render_tab = 0; -#endif - TAG(render_init)(); -} - - -#undef IND -#undef TAG diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_vb.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_vb.c index a6c27612e..e6054f1ee 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_vb.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_vb.c @@ -1,8 +1,6 @@ -/* -*- mode: c; c-basic-offset: 3 -*- - * - * Copyright 2000 VA Linux Systems Inc., Fremont, California. - * - * 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"), @@ -11,488 +9,356 @@ * 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 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, + * 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/tdfx/tdfx_vb.c,v 1.1 2001/03/21 16:14:28 dawes Exp $ */ - -/* - * Original rewrite: - * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 + * 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. * - * Authors: - * Gareth Hughes <gareth@valinux.com> - * Brian Paul <brianp@valinux.com> - * Keith Whitwell <keithw@valinux.com> * */ - -#include "tdfx_context.h" -#include "tdfx_vb.h" - -#include "stages.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" -#define COORD \ -do { \ - v->v.x = winCoord[0] + xoffset; \ - v->v.y = winCoord[1] + yoffset; \ - v->v.z = winCoord[2]; \ - v->v.rhw = w; \ -} while (0) - - -/* The assembly is slower... - */ -#if 0 && defined(USE_X86_ASM) -#define COL \ -do { \ - __asm__ ( \ - "movl (%%edx),%%eax \n" \ - "bswap %%eax \n" \ - "rorl $8,%%eax \n" \ - "movl %%eax,16(%%edi) \n" \ - : \ - : "d" (color), "D" (v) \ - : "%eax" ); \ -} while (0) -#else -#define COL \ -do { \ - v->v.color.blue = color[2]; \ - v->v.color.green = color[1]; \ - v->v.color.red = color[0]; \ - v->v.color.alpha = color[3]; \ -} while (0) -#endif - - -#define TEX0 \ -do { \ - v->v.tu0 = tc0[i][0] * sScale0 * w; \ - v->v.tv0 = tc0[i][1] * tScale0 * w; \ -} while (0) - -#define TEX1 \ -do { \ - v->v.tu1 = tc1[i][0] * sScale1 * w; \ - v->v.tv1 = tc1[i][1] * tScale1 * w; \ -} while (0) - - -#define TEX0_4 \ - if ( VB->TexCoordPtr[0]->size == 4 ) { \ - GLfloat (*tc)[4] = VB->TexCoordPtr[0]->data; \ - winCoord = VB->Win.data[start]; \ - v = &(TDFX_DRIVER_DATA(VB)->verts[start]); \ - for ( i = start ; i < end ; i++, v++, winCoord+=4 ) { \ - v->v.tq0 = tc[i][3] * winCoord[3]; \ - } \ - } - -#define TEX1_4 \ - if ( VB->TexCoordPtr[1]->size == 4 ) { \ - GLfloat (*tc)[4] = VB->TexCoordPtr[1]->data; \ - winCoord = VB->Win.data[start]; \ - v = &(TDFX_DRIVER_DATA(VB)->verts[start]); \ - for ( i = start ; i < end ; i++, v++, winCoord+=4 ) { \ - v->v.tq1 = tc[i][3] * winCoord[3]; \ - } \ - } - +#include "tdfx_context.h" +#include "tdfx_vb.h" +#include "tdfx_tris.h" +#include "tdfx_state.h" +#include "tdfx_render.h" -#define FOG - - -#define NOP - - - -#define SETUPFUNC(name,win,col,tex0,tex1,tex0_4,tex1_4,fog) \ -static void name( struct vertex_buffer *VB, GLuint start, GLuint end ) \ -{ \ - tdfxContextPtr fxMesa = TDFX_CONTEXT(VB->ctx); \ - tdfxVertexPtr v; \ - const GLfloat *winCoord; \ - GLfloat (*tc0)[4]; \ - GLfloat (*tc1)[4]; \ - const GLfloat xoffset = fxMesa->x_offset + TRI_X_OFFSET; \ - const GLfloat yoffset = fxMesa->y_delta + TRI_Y_OFFSET; \ - const GLfloat sScale0 = fxMesa->sScale0; \ - const GLfloat tScale0 = fxMesa->tScale0; \ - const GLfloat sScale1 = fxMesa->sScale1; \ - const GLfloat tScale1 = fxMesa->tScale1; \ - const GLubyte *color; \ - int i; \ - \ - (void) xoffset; (void) yoffset; \ - (void) sScale0; (void) tScale0; \ - (void) sScale1; (void) tScale1; \ - \ - if (0) fprintf(stderr, "%s\n", __FUNCTION__); \ - gl_import_client_data( VB, VB->ctx->RenderFlags, \ - (VB->ClipOrMask \ - ? VEC_WRITABLE|VEC_GOOD_STRIDE \ - : VEC_GOOD_STRIDE)); \ - \ - tc0 = VB->TexCoordPtr[fxMesa->tmu_source[0]]->data; \ - tc1 = VB->TexCoordPtr[fxMesa->tmu_source[1]]->data; \ - color = VB->Color[0]->data[start]; \ - winCoord = VB->Win.data[start]; \ - \ - v = &(TDFX_DRIVER_DATA(VB)->verts[start]); \ - \ - if ( VB->ClipOrMask == 0 ) { \ - for ( i = start ; i < end ; i++, v++, color+=4, winCoord+=4 ) { \ - const GLfloat w = winCoord[3]; \ - (void) w; \ - win; \ - col; \ - fog; \ - tex0; \ - tex1; \ - } \ - } else { \ - for ( i = start ; i < end ; i++, v++, color+=4, winCoord+=4 ) { \ - if ( VB->ClipMask[i] == 0 ) { \ - const GLfloat w = winCoord[3]; \ - (void) w; \ - win; \ - fog; \ - tex0; \ - tex1; \ - } \ - col; \ - } \ - } \ - tex0_4; \ - tex1_4; \ +static void copy_pv_rgba4( GLcontext *ctx, GLuint edst, GLuint esrc ) +{ + tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); + GLubyte *tdfxverts = (GLubyte *)fxMesa->verts; + GLuint shift = fxMesa->vertex_stride_shift; + tdfxVertex *dst = (tdfxVertex *)(tdfxverts + (edst << shift)); + tdfxVertex *src = (tdfxVertex *)(tdfxverts + (esrc << shift)); + dst->ui[4] = src->ui[4]; } - -SETUPFUNC(rs_wt0, COORD, NOP, TEX0, NOP, TEX0_4, NOP, NOP) -SETUPFUNC(rs_wt0t1, COORD, NOP, TEX0, TEX1, TEX0_4, TEX1_4, NOP) -SETUPFUNC(rs_wft0, COORD, NOP, TEX0, NOP, TEX0_4, NOP, FOG) -SETUPFUNC(rs_wft0t1, COORD, NOP, TEX0, TEX1, TEX0_4, TEX1_4, FOG) -SETUPFUNC(rs_wg, COORD, COL, NOP, NOP, NOP, NOP, NOP) -SETUPFUNC(rs_wgt0, COORD, COL, TEX0, NOP, TEX0_4, NOP, NOP) -SETUPFUNC(rs_wgt0t1, COORD, COL, TEX0, TEX1, TEX0_4, TEX1_4, NOP) -SETUPFUNC(rs_wgf, COORD, COL, NOP, NOP, NOP, NOP, FOG) -SETUPFUNC(rs_wgft0, COORD, COL, TEX0, NOP, TEX0_4, NOP, FOG) -SETUPFUNC(rs_wgft0t1, COORD, COL, TEX0, TEX1, TEX0_4, TEX1_4, FOG) - -SETUPFUNC(rs_t0, NOP, NOP, TEX0, NOP, TEX0_4, NOP, NOP) -SETUPFUNC(rs_t0t1, NOP, NOP, TEX0, TEX1, TEX0_4, TEX1_4, NOP) -SETUPFUNC(rs_f, NOP, NOP, NOP, NOP, NOP, NOP, FOG) -SETUPFUNC(rs_ft0, NOP, NOP, TEX0, NOP, TEX0_4, NOP, FOG) -SETUPFUNC(rs_ft0t1, NOP, NOP, TEX0, TEX1, TEX0_4, TEX1_4, FOG) -SETUPFUNC(rs_g, NOP, COL, NOP, NOP, NOP, NOP, NOP) -SETUPFUNC(rs_gt0, NOP, COL, TEX0, NOP, TEX0_4, NOP, NOP) -SETUPFUNC(rs_gt0t1, NOP, COL, TEX0, TEX1, TEX0_4, TEX1_4, NOP) -SETUPFUNC(rs_gf, NOP, COL, NOP, NOP, NOP, NOP, FOG) -SETUPFUNC(rs_gft0, NOP, COL, TEX0, NOP, TEX0_4, NOP, FOG) -SETUPFUNC(rs_gft0t1, NOP, COL, TEX0, TEX1, TEX0_4, TEX1_4, FOG) - - - -static void rs_invalid( struct vertex_buffer *VB, GLuint start, GLuint end ) +static void copy_pv_rgba3( GLcontext *ctx, GLuint edst, GLuint esrc ) { - fprintf( stderr, "tdfxRasterSetup(): invalid setup function\n" ); + tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); + GLubyte *tdfxverts = (GLubyte *)fxMesa->verts; + GLuint shift = fxMesa->vertex_stride_shift; + tdfxVertex *dst = (tdfxVertex *)(tdfxverts + (edst << shift)); + tdfxVertex *src = (tdfxVertex *)(tdfxverts + (esrc << shift)); + dst->ui[3] = src->ui[3]; } -typedef void (*setupFunc)( struct vertex_buffer *, GLuint, GLuint ); +typedef void (*emit_func)( GLcontext *, GLuint, GLuint, void *, GLuint ); -static setupFunc setup_func[0x40]; +static struct { + emit_func emit; + interp_func interp; + copy_pv_func copy_pv; + GLboolean (*check_tex_sizes)( GLcontext *ctx ); + GLuint vertex_size; + GLuint vertex_stride_shift; + GLuint vertex_format; +} setup_tab[TDFX_MAX_SETUP]; -void tdfxDDSetupInit( void ) +static void import_float_colors( GLcontext *ctx ) { - int i; - - for (i = 0; i < Elements(setup_func); i++) - setup_func[i] = rs_invalid; - - /* Functions to build vertices from scratch */ - setup_func[TDFX_WIN_BIT|TDFX_TEX0_BIT] = rs_wt0; - setup_func[TDFX_WIN_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT] = rs_wt0t1; - setup_func[TDFX_WIN_BIT|TDFX_FOG_BIT|TDFX_TEX0_BIT] = rs_wft0; - setup_func[TDFX_WIN_BIT|TDFX_FOG_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT] = rs_wft0t1; - setup_func[TDFX_WIN_BIT|TDFX_RGBA_BIT] = rs_wg; - setup_func[TDFX_WIN_BIT|TDFX_RGBA_BIT|TDFX_TEX0_BIT] = rs_wgt0; - setup_func[TDFX_WIN_BIT|TDFX_RGBA_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT] = rs_wgt0t1; - setup_func[TDFX_WIN_BIT|TDFX_RGBA_BIT|TDFX_FOG_BIT] = rs_wgf; - setup_func[TDFX_WIN_BIT|TDFX_RGBA_BIT|TDFX_FOG_BIT|TDFX_TEX0_BIT] = rs_wgft0; - setup_func[TDFX_WIN_BIT|TDFX_RGBA_BIT|TDFX_FOG_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT] = rs_wgft0t1; - - /* Repair functions */ - setup_func[TDFX_TEX0_BIT] = rs_t0; - setup_func[TDFX_TEX0_BIT|TDFX_TEX1_BIT] = rs_t0t1; - setup_func[TDFX_FOG_BIT] = rs_f; - setup_func[TDFX_FOG_BIT|TDFX_TEX0_BIT] = rs_ft0; - setup_func[TDFX_FOG_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT] = rs_ft0t1; - setup_func[TDFX_RGBA_BIT] = rs_g; - setup_func[TDFX_RGBA_BIT|TDFX_TEX0_BIT] = rs_gt0; - setup_func[TDFX_RGBA_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT] = rs_gt0t1; - setup_func[TDFX_RGBA_BIT|TDFX_FOG_BIT] = rs_gf; - setup_func[TDFX_RGBA_BIT|TDFX_FOG_BIT|TDFX_TEX0_BIT] = rs_gft0; - setup_func[TDFX_RGBA_BIT|TDFX_FOG_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT] = rs_gft0t1; -} - + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + struct gl_client_array *from = VB->ColorPtr[0]; + struct gl_client_array *to = &TDFX_CONTEXT(ctx)->UbyteColor; + GLuint count = VB->Count; + + if (!to->Ptr) { + to->Ptr = ALIGN_MALLOC( VB->Size * 4 * sizeof(GLubyte), 32 ); + to->Type = GL_UNSIGNED_BYTE; + } -void tdfxPrintSetupFlags( char *msg, GLuint flags ) -{ - fprintf( stderr, "%s: 0x%x %s%s%s%s%s\n", - msg, - (int)flags, - (flags & TDFX_WIN_BIT) ? " xyzw," : "", - (flags & TDFX_RGBA_BIT) ? " rgba," : "", - (flags & TDFX_FOG_BIT) ? " fog," : "", - (flags & TDFX_TEX0_BIT) ? " tex-0," : "", - (flags & TDFX_TEX1_BIT) ? " tex-1," : "" ); + /* 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; } -/* ================================================================ - * Raster Setup - */ +#define GET_COLOR(ptr, idx) (((GLchan (*)[4])((ptr)->Ptr))[idx]) + -void tdfxDDChooseRasterSetupFunc( GLcontext *ctx ) +static void interp_extras( GLcontext *ctx, + GLfloat t, + GLuint dst, GLuint out, GLuint in, + GLboolean force_boundary ) { - tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); - int index = TDFX_WIN_BIT | TDFX_RGBA_BIT; - int vertexFormat = fxMesa->vertexFormat; - - fxMesa->vertsize = 8; - fxMesa->tmu_source[0] = 0; - fxMesa->tmu_source[1] = 1; - fxMesa->tex_dest[0] = TDFX_TEX0_BIT; - fxMesa->tex_dest[1] = TDFX_TEX1_BIT; - fxMesa->vertexFormat = TDFX_LAYOUT_SINGLE; - - if ( ctx->Texture.ReallyEnabled & ENABLE_TEX0 ) { - index |= TDFX_TEX0_BIT; - } + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - if ( ctx->Texture.ReallyEnabled & ENABLE_TEX1 ) { - if ( ctx->Texture.ReallyEnabled & ENABLE_TEX0 ) { - fxMesa->vertexFormat = TDFX_LAYOUT_MULTI; - fxMesa->vertsize = 10; - index |= TDFX_TEX1_BIT; - } else { - /* Just a funny way of doing single texturing. - */ - fxMesa->tmu_source[0] = 1; - fxMesa->tex_dest[1] = TDFX_TEX0_BIT; - index |= TDFX_TEX0_BIT; - } + /*fprintf(stderr, "%s\n", __FUNCTION__);*/ + + if (VB->ColorPtr[1]) { + INTERP_4CHAN( t, + GET_COLOR(VB->ColorPtr[1], dst), + GET_COLOR(VB->ColorPtr[1], out), + GET_COLOR(VB->ColorPtr[1], in) ); } - if (ctx->Texture.ReallyEnabled & (ENABLE_TEX0 | ENABLE_TEX1)) { - if ((ctx->VB->TexCoordPtr[0] && ctx->VB->TexCoordPtr[0]->size == 4) || - (ctx->VB->TexCoordPtr[1] && ctx->VB->TexCoordPtr[1]->size == 4)) { - fxMesa->vertexFormat = TDFX_LAYOUT_PROJECT; - } + if (VB->EdgeFlag) { + VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary; } - if ( ctx->Fog.Enabled ) - index |= TDFX_FOG_BIT; + setup_tab[TDFX_CONTEXT(ctx)->SetupIndex].interp(ctx, t, dst, out, in, + force_boundary); +} - fxMesa->SetupIndex = index; - ctx->Driver.RasterSetup = setup_func[index]; +static void copy_pv_extras( GLcontext *ctx, GLuint dst, GLuint src ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - if ( fxMesa->vertexFormat != vertexFormat ) { - fxMesa->dirty |= TDFX_UPLOAD_VERTEX_LAYOUT; + if (VB->ColorPtr[1]) { + COPY_CHAN4( GET_COLOR(VB->ColorPtr[1], dst), + GET_COLOR(VB->ColorPtr[1], src) ); } - if (0) { - tdfxPrintSetupFlags( "full setup function", index ); - fprintf(stderr, "full setup function %p\n", ctx->Driver.RasterSetup); - } + setup_tab[TDFX_CONTEXT(ctx)->SetupIndex].copy_pv(ctx, dst, src); } -/* Check to see if vertices need repairing. - */ -void tdfxDDCheckPartialRasterSetup( GLcontext *ctx, - struct gl_pipeline_stage *d ) -{ - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - int tmp = fxMesa->SetupDone; - - d->type = 0; - fxMesa->SetupDone = 0; /* cleared if we return */ - if ( (ctx->Array.Summary & VERT_OBJ_ANY) == 0 ) - return; - if ( ctx->IndirectTriangles ) - return; - fxMesa->SetupDone = tmp; -} +#define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT) +#define TAG(x) x##_wg +#include "tdfx_vbtmp.h" -/* Repair existing precalculated vertices with new data. +/* Special for tdfx: fog requires w */ -void tdfxDDPartialRasterSetup( struct vertex_buffer *VB ) -{ - tdfxContextPtr fxMesa = TDFX_CONTEXT( VB->ctx ); - GLuint new = VB->pipeline->new_outputs; - GLuint available = VB->pipeline->outputs; - GLuint index = 0; - - if ( new & VERT_WIN ) { - new = available; - index |= TDFX_WIN_BIT | TDFX_FOG_BIT; - } +#define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT) +#define TAG(x) x##_wg_fog +#include "tdfx_vbtmp.h" - if ( new & VERT_RGBA ) - index |= TDFX_RGBA_BIT; +#define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT) +#define TAG(x) x##_wgt0 +#include "tdfx_vbtmp.h" - if ( new & VERT_TEX0_ANY ) - index |= TDFX_TEX0_BIT; +#define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT) +#define TAG(x) x##_wgt0t1 +#include "tdfx_vbtmp.h" - if ( new & VERT_TEX1_ANY ) - index |= fxMesa->tex_dest[1]; +#define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_PTEX_BIT) +#define TAG(x) x##_wgpt0 +#include "tdfx_vbtmp.h" - if ( new & VERT_FOG_COORD ) - index |= TDFX_FOG_BIT; +#define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT|\ + TDFX_PTEX_BIT) +#define TAG(x) x##_wgpt0t1 +#include "tdfx_vbtmp.h" - fxMesa->SetupDone &= ~index; - index &= fxMesa->SetupIndex; - fxMesa->SetupDone |= index; +#define IND (TDFX_RGBA_BIT) +#define TAG(x) x##_g +#include "tdfx_vbtmp.h" - if ( 0 ) - tdfxPrintSetupFlags( "partial setup function", index ); +#define IND (TDFX_TEX0_BIT) +#define TAG(x) x##_t0 +#include "tdfx_vbtmp.h" - if ( index ) - setup_func[index]( VB, VB->Start, VB->Count ); -} +#define IND (TDFX_TEX0_BIT|TDFX_TEX1_BIT) +#define TAG(x) x##_t0t1 +#include "tdfx_vbtmp.h" -void tdfxDDDoRasterSetup( struct vertex_buffer *VB ) -{ - GLcontext *ctx = VB->ctx; +#define IND (TDFX_RGBA_BIT|TDFX_TEX0_BIT) +#define TAG(x) x##_gt0 +#include "tdfx_vbtmp.h" - if ( VB->Type == VB_CVA_PRECALC ) { - tdfxDDPartialRasterSetup( VB ); - } else if ( ctx->Driver.RasterSetup ) { - ctx->Driver.RasterSetup( VB, VB->CopyStart, VB->Count ); - } -} +#define IND (TDFX_RGBA_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT) +#define TAG(x) x##_gt0t1 +#include "tdfx_vbtmp.h" -/* ================================================================ - * Device-specific Vertex Buffers - */ -void tdfxDDResizeVB( struct vertex_buffer *VB, GLuint size ) +static void init_setup_tab( void ) { - tdfxVertexBufferPtr fxVB = TDFX_DRIVER_DATA(VB); + init_wg(); + init_wg_fog(); + init_wgt0(); + init_wgt0t1(); + init_wgpt0(); + init_wgpt0t1(); + + init_g(); + init_t0(); + init_t0t1(); + init_gt0(); + init_gt0t1(); +} - while ( fxVB->size < size ) - fxVB->size *= 2; - ALIGN_FREE( fxVB->vert_store ); - fxVB->vert_store = ALIGN_MALLOC( sizeof(tdfxVertex) * fxVB->size, 32 ); - if ( !fxVB->vert_store ) { - fprintf( stderr, "Cannot allocate vertex store! Exiting...\n" ); - exit( 1 ); - } +void tdfxPrintSetupFlags(char *msg, GLuint flags ) +{ + fprintf(stderr, "%s(%x): %s%s%s%s%s\n", + msg, + (int)flags, + (flags & TDFX_XYZ_BIT) ? " xyz," : "", + (flags & TDFX_W_BIT) ? " w," : "", + (flags & TDFX_RGBA_BIT) ? " rgba," : "", + (flags & TDFX_TEX0_BIT) ? " tex-0," : "", + (flags & TDFX_TEX1_BIT) ? " tex-1," : ""); +} - fxVB->verts = (tdfxVertexPtr)fxVB->vert_store; - gl_vector1ui_free( &fxVB->clipped_elements ); - gl_vector1ui_alloc( &fxVB->clipped_elements, - VEC_WRITABLE, fxVB->size, 32 ); - if ( !fxVB->clipped_elements.start ) { - fprintf( stderr, "Cannot allocate clipped elements! Exiting...\n" ); - exit( 1 ); - } - ALIGN_FREE( VB->ClipMask ); - VB->ClipMask = (GLubyte *)ALIGN_MALLOC( sizeof(GLubyte) * fxVB->size, 32 ); - if ( !VB->ClipMask ) { - fprintf( stderr, "Cannot allocate clipmask! Exiting...\n" ); - exit( 1 ); +void tdfxCheckTexSizes( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); + + if (!setup_tab[fxMesa->SetupIndex].check_tex_sizes(ctx)) { + GLuint ind = fxMesa->SetupIndex |= (TDFX_PTEX_BIT|TDFX_RGBA_BIT); + + /* Tdfx handles projective textures nicely; just have to change + * up to the new vertex format. + */ + if (setup_tab[ind].vertex_format != fxMesa->vertexFormat) { + FLUSH_BATCH(fxMesa); + fxMesa->dirty |= TDFX_UPLOAD_VERTEX_LAYOUT; + fxMesa->vertexFormat = setup_tab[ind].vertex_format; + fxMesa->vertex_stride_shift = setup_tab[ind].vertex_stride_shift; + + /* This is required as we have just changed the vertex + * format, so the interp and copy routines must also change. + * In the unfilled and twosided cases we are using the + * swrast_setup 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; + tnl->Driver.Render.CopyPV = setup_tab[fxMesa->SetupIndex].copy_pv; + } + } } } -void tdfxDDResizeElts( struct vertex_buffer *VB, GLuint size ) + +void tdfxBuildVertices( GLcontext *ctx, GLuint start, GLuint count, + GLuint newinputs ) { -#if 0 - tdfxVertexBufferPtr fxVB = TDFX_DRIVER_DATA(VB); + tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); + char *v = (fxMesa->verts + (start<<fxMesa->vertex_stride_shift)); + GLuint stride = 1<<fxMesa->vertex_stride_shift; - FREE(fxVB->elts); + newinputs |= fxMesa->SetupNewInputs; + fxMesa->SetupNewInputs = 0; - while (fxVB->elt_size < size) - fxVB->elt_size *= 2; + if (!newinputs) + return; - FREE(fxVB->elts); - fxVB->elts = MALLOC( sizeof(tdfxVertex *) * fxVB->elt_size ); - if ( !fxVB->elts ) { - fprintf( stderr, "Cannot allocate vertex indirection! Exiting...\n" ); - exit( 1 ); - } -#endif -} + if (newinputs & VERT_CLIP) { + setup_tab[fxMesa->SetupIndex].emit( ctx, start, count, v, stride ); + } else { + GLuint ind = 0; -void tdfxDDRegisterVB( struct vertex_buffer *VB ) -{ - tdfxVertexBufferPtr fxVB; + if (newinputs & VERT_RGBA) + ind |= TDFX_RGBA_BIT; + + if (newinputs & VERT_TEX0) + ind |= TDFX_TEX0_BIT; - fxVB = (tdfxVertexBufferPtr) CALLOC( sizeof(*fxVB) ); + if (newinputs & VERT_TEX1) + ind |= TDFX_TEX0_BIT|TDFX_TEX1_BIT; - fxVB->elt_size = fxVB->size = VB->Size * 2; - fxVB->vert_store = ALIGN_MALLOC( sizeof(tdfxVertex) * fxVB->size, 32 ); - if ( !fxVB->vert_store ) { - fprintf( stderr, "Cannot allocate vertex store! Exiting...\n" ); - exit( 1 ); + if (fxMesa->SetupIndex & TDFX_PTEX_BIT) + ind = ~0; + + ind &= fxMesa->SetupIndex; + + if (ind) { + setup_tab[ind].emit( ctx, start, count, v, stride ); + } } +} - fxVB->verts = (tdfxVertexPtr)fxVB->vert_store; -#if 0 - fxVB->elts = MALLOC( sizeof(tdfxVertex *) * fxVB->elt_size ); - if ( !fxVB->elts ) { - fprintf( stderr, "Cannot allocate vertex indirection! Exiting...\n" ); - exit( 1 ); +void tdfxChooseVertexState( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); + GLuint ind = TDFX_XYZ_BIT|TDFX_RGBA_BIT; + + if (ctx->Texture._ReallyEnabled & 0xf0) + ind |= TDFX_W_BIT|TDFX_TEX1_BIT|TDFX_TEX0_BIT; + else if (ctx->Texture._ReallyEnabled & 0xf) + ind |= TDFX_W_BIT|TDFX_TEX0_BIT; + else if (ctx->Fog.Enabled) + ind |= TDFX_W_BIT; + + 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 = setup_tab[ind].copy_pv; } -#endif - gl_vector1ui_alloc( &fxVB->clipped_elements, - VEC_WRITABLE, fxVB->size, 32 ); - if ( !fxVB->clipped_elements.start ) { - fprintf( stderr, "Cannot allocate clipped elements! Exiting...\n" ); - exit( 1 ); + if (setup_tab[ind].vertex_format != fxMesa->vertexFormat) { + FLUSH_BATCH(fxMesa); + fxMesa->dirty |= TDFX_UPLOAD_VERTEX_LAYOUT; + fxMesa->vertexFormat = setup_tab[ind].vertex_format; + fxMesa->vertex_stride_shift = setup_tab[ind].vertex_stride_shift; } +} + - ALIGN_FREE( VB->ClipMask ); - VB->ClipMask = (GLubyte *)ALIGN_MALLOC( sizeof(GLubyte) * fxVB->size, 32 ); - if ( !VB->ClipMask ) { - fprintf( stderr, "Cannot allocate clipmask! Exiting...\n" ); - exit( 1 ); +void tdfxInitVB( GLcontext *ctx ) +{ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + GLuint size = TNL_CONTEXT(ctx)->vb.Size; + static int firsttime = 1; + if (firsttime) { + init_setup_tab(); + firsttime = 0; } - VB->driver_data = fxVB; + fxMesa->verts = (char *)ALIGN_MALLOC(size * sizeof(tdfxVertex), 32); + fxMesa->vertexFormat = setup_tab[TDFX_XYZ_BIT|TDFX_RGBA_BIT].vertex_format; + fxMesa->vertex_stride_shift = setup_tab[(TDFX_XYZ_BIT| + TDFX_RGBA_BIT)].vertex_stride_shift; + fxMesa->SetupIndex = TDFX_XYZ_BIT|TDFX_RGBA_BIT; } -void tdfxDDUnregisterVB( struct vertex_buffer *VB ) + +void tdfxFreeVB( GLcontext *ctx ) { - tdfxVertexBufferPtr fxVB = TDFX_DRIVER_DATA(VB); - - if ( fxVB ) { - if ( fxVB->vert_store ) ALIGN_FREE( fxVB->vert_store ); - if ( fxVB->elts ) ALIGN_FREE( fxVB->elts ); - gl_vector1ui_free( &fxVB->clipped_elements ); - FREE( fxVB ); - VB->driver_data = NULL; + tdfxContextPtr fxMesa = TDFX_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/xc/lib/GL/mesa/src/drv/tdfx/tdfx_vb.h b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_vb.h index 29d426add..8bea7f0df 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_vb.h +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_vb.h @@ -1,8 +1,6 @@ -/* -*- mode: c; c-basic-offset: 3 -*- - * - * Copyright 2000 VA Linux Systems Inc., Fremont, California. - * - * All Rights Reserved. +/* + * GLX Hardware Device Driver for Intel tdfx + * 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"), @@ -11,117 +9,60 @@ * 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 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, + * 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/tdfx/tdfx_vb.h,v 1.1 2001/03/21 16:14:28 dawes Exp $ */ - -/* - * Original rewrite: - * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 + * 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. * - * Authors: - * Gareth Hughes <gareth@valinux.com> - * Brian Paul <brianp@valinux.com> - * Keith Whitwell <keithw@valinux.com> * */ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfxvb.h,v 1.3 2000/08/28 02:43:12 tsi Exp $ */ -#ifndef __TDFX_VB_H__ -#define __TDFX_VB_H__ - -#ifdef GLX_DIRECT_RENDERING - -#include "types.h" -#include "vb.h" - -/* - * Color type for the vertex data - */ -typedef struct { - GLubyte blue; - GLubyte green; - GLubyte red; - GLubyte alpha; -} tdfx_color_t; - - -/* The vertex structure. The final tu1/tv1 values only used in - * multitexture modes, and tq0/tq1 in projected texture modes. - */ -typedef struct { - GLfloat x, y, z; /* Coordinates in screen space */ - GLfloat rhw; /* Reciprocal homogeneous w */ - tdfx_color_t color; /* Diffuse color */ - GLuint padding; /* ... */ - GLfloat tu0, tv0; /* Texture 0 coordinates */ - GLfloat tu1, tv1; /* Texture 1 coordinates */ - GLfloat tq0, tq1; /* Projected texture coordinates */ -} tdfx_vertex; - - -/* The fastpath code still expects a 16-float stride vertex. - */ -union tdfx_vertex_t { - tdfx_vertex v; - GLfloat f[16]; - GLuint ui[16]; -}; - -typedef union tdfx_vertex_t tdfxVertex; -typedef union tdfx_vertex_t *tdfxVertexPtr; - -/* Vertex buffer for use when on the fast path */ -struct tdfx_vertex_buffer { - tdfxVertexPtr verts; - GLvector1ui clipped_elements; - GLuint size; - int last_vert; - void *vert_store; +#ifndef TDFXVB_INC +#define TDFXVB_INC - tdfxVertexPtr *elts; - GLuint elt_size; - GLuint last_elt; -}; +#include "mtypes.h" -typedef struct tdfx_vertex_buffer *tdfxVertexBufferPtr; +#include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "math/m_xform.h" -#define TDFX_DRIVER_DATA(vb) ((tdfxVertexBufferPtr)((vb)->driver_data)) +#define TDFX_XYZ_BIT 0x1 +#define TDFX_W_BIT 0x2 +#define TDFX_RGBA_BIT 0x4 +#define TDFX_TEX1_BIT 0x8 +#define TDFX_TEX0_BIT 0x10 +#define TDFX_PTEX_BIT 0x20 +#define TDFX_MAX_SETUP 0x40 +#define _TDFX_NEW_RASTERSETUP (_NEW_TEXTURE | \ + _DD_NEW_SEPARATE_SPECULAR | \ + _DD_NEW_TRI_UNFILLED | \ + _DD_NEW_TRI_LIGHT_TWOSIDE | \ + _NEW_FOG) -#define TDFX_WIN_BIT 0x01 -#define TDFX_RGBA_BIT 0x02 -#define TDFX_FOG_BIT 0x04 -#define TDFX_SPEC_BIT 0x08 -#define TDFX_TEX0_BIT 0x10 -#define TDFX_TEX1_BIT 0x20 +extern void tdfxValidateBuildProjVerts(GLcontext *ctx, + GLuint start, GLuint count, + GLuint newinputs ); -extern void tdfxDDSetupInit( void ); +extern void tdfxPrintSetupFlags(char *msg, GLuint flags ); -extern void tdfxDDChooseRasterSetupFunc( GLcontext *ctx ); -extern void tdfxPrintSetupFlags( char *msg, GLuint flags ); +extern void tdfxInitVB( GLcontext *ctx ); -extern void tdfxDDCheckPartialRasterSetup( GLcontext *ctx, - struct gl_pipeline_stage *s ); -extern void tdfxDDPartialRasterSetup( struct vertex_buffer *VB ); -extern void tdfxDDDoRasterSetup( struct vertex_buffer *VB ); +extern void tdfxFreeVB( GLcontext *ctx ); -extern void tdfxDDResizeVB( struct vertex_buffer *VB, GLuint size ); -extern void tdfxDDResizeElts( struct vertex_buffer *VB, GLuint size ); -extern void tdfxDDRegisterVB( struct vertex_buffer *VB ); -extern void tdfxDDUnregisterVB( struct vertex_buffer *VB ); +extern void tdfxCheckTexSizes( GLcontext *ctx ); +extern void tdfxChooseVertexState( GLcontext *ctx ); -#endif /* GLX_DIRECT_RENDERING */ +extern void tdfxBuildVertices( GLcontext *ctx, GLuint start, GLuint count, + GLuint newinputs ); -#endif /* __TDFX_VB_H__ */ +#endif diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_vbtmp.h b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_vbtmp.h new file mode 100644 index 000000000..558f38666 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_vbtmp.h @@ -0,0 +1,442 @@ + +#if (IND & (TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT)) + +static void TAG(emit)( GLcontext *ctx, + GLuint start, GLuint end, + void *dest, + GLuint stride ) +{ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + 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; + tdfxVertex *v = (tdfxVertex *)dest; + GLfloat u0scale,v0scale,u1scale,v1scale; + const GLubyte *mask = VB->ClipMask; + const GLfloat *s = fxMesa->hw_viewport; + int i; + +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + ASSERT(stride > 16); + + + if (IND & TDFX_TEX0_BIT) { + tc0_stride = VB->TexCoordPtr[0]->stride; + tc0 = VB->TexCoordPtr[0]->data; + u0scale = fxMesa->sScale0; + v0scale = fxMesa->tScale0; + if (IND & TDFX_PTEX_BIT) + tc0_size = VB->TexCoordPtr[0]->size; + } + + if (IND & TDFX_TEX1_BIT) { + tc1 = VB->TexCoordPtr[1]->data; + tc1_stride = VB->TexCoordPtr[1]->stride; + u1scale = fxMesa->sScale1; + v1scale = fxMesa->tScale1; + if (IND & TDFX_PTEX_BIT) + tc1_size = VB->TexCoordPtr[1]->size; + } + + if (IND & TDFX_RGBA_BIT) { + if (VB->ColorPtr[0]->Type != GL_UNSIGNED_BYTE) + import_float_colors( ctx ); + col = VB->ColorPtr[0]->Ptr; + col_stride = VB->ColorPtr[0]->StrideB; + } + + if (VB->importable_data) { + /* May have nonstandard strides: + */ + if (start) { + proj = (GLfloat (*)[4])((GLubyte *)proj + start * proj_stride); + if (IND & TDFX_TEX0_BIT) + tc0 = (GLfloat (*)[4])((GLubyte *)tc0 + start * tc0_stride); + if (IND & TDFX_TEX1_BIT) + tc1 = (GLfloat (*)[4])((GLubyte *)tc1 + start * tc1_stride); + if (IND & TDFX_RGBA_BIT) + STRIDE_4UB(col, start * col_stride); + } + + for (i=start; i < end; i++, v = (tdfxVertex *)((GLubyte *)v + stride)) { + if (IND & TDFX_XYZ_BIT) { + if (mask[i] == 0) { + /* unclipped */ + v->v.x = s[0] * proj[0][0] + s[12]; + v->v.y = s[5] * proj[0][1] + s[13]; + v->v.z = s[10] * proj[0][2] + s[14]; + v->v.rhw = proj[0][3]; + } else { + /* clipped */ + v->v.rhw = 1.0; + } + proj = (GLfloat (*)[4])((GLubyte *)proj + proj_stride); + } + if (IND & TDFX_RGBA_BIT) { +#if 0 + *(GLuint *)&v->v.color = *(GLuint *)col; +#else + GLubyte *b = (GLubyte *) &v->v.color; + b[0] = col[0][2]; + b[1] = col[0][1]; + b[2] = col[0][0]; + b[3] = col[0][3]; + +#endif + STRIDE_4UB(col, col_stride); + } + if (IND & TDFX_TEX0_BIT) { + GLfloat w = v->v.rhw; + if (IND & TDFX_PTEX_BIT) { + v->pv.tu0 = tc0[0][0] * u0scale * w; + v->pv.tv0 = tc0[0][1] * v0scale * w; + v->pv.tq0 = w; + if (tc0_size == 4) + v->pv.tq0 = tc0[0][3] * w; + } + else { + v->v.tu0 = tc0[0][0] * u0scale * w; + v->v.tv0 = tc0[0][1] * v0scale * w; + } + tc0 = (GLfloat (*)[4])((GLubyte *)tc0 + tc0_stride); + } + if (IND & TDFX_TEX1_BIT) { + GLfloat w = v->v.rhw; + if (IND & TDFX_PTEX_BIT) { + v->pv.tu1 = tc1[0][0] * u1scale * w; + v->pv.tv1 = tc1[0][1] * v1scale * w; + v->pv.tq1 = w; + if (tc1_size == 4) + v->pv.tq1 = tc1[0][3] * w; + } + else { + v->v.tu1 = tc1[0][0] * u1scale * w; + v->v.tv1 = tc1[0][1] * v1scale * w; + } + tc1 = (GLfloat (*)[4])((GLubyte *)tc1 + tc1_stride); + } + } + } + else { + for (i=start; i < end; i++, v = (tdfxVertex *)((GLubyte *)v + stride)) { + if (IND & TDFX_XYZ_BIT) { + if (mask[i] == 0) { + v->v.x = s[0] * proj[i][0] + s[12]; + v->v.y = s[5] * proj[i][1] + s[13]; + v->v.z = s[10] * proj[i][2] + s[14]; + v->v.rhw = proj[i][3]; + } else { + v->v.rhw = 1.0; + } + } + if (IND & TDFX_RGBA_BIT) { +#if 0 + *(GLuint *)&v->v.color = *(GLuint *)&col[i]; +#else + GLubyte *b = (GLubyte *) &v->v.color; + b[0] = col[i][2]; + b[1] = col[i][1]; + b[2] = col[i][0]; + b[3] = col[i][3]; + +#endif + } + if (IND & TDFX_TEX0_BIT) { + GLfloat w = v->v.rhw; + if (IND & TDFX_PTEX_BIT) { + v->pv.tu0 = tc0[i][0] * u0scale * w; + v->pv.tv0 = tc0[i][1] * v0scale * w; + v->pv.tq0 = w; + if (tc0_size == 4) + v->pv.tq0 = tc0[i][3] * w; + } + else { + v->v.tu0 = tc0[i][0] * u0scale * w; + v->v.tv0 = tc0[i][1] * v0scale * w; + } + } + if (IND & TDFX_TEX1_BIT) { + GLfloat w = v->v.rhw; + if (IND & TDFX_PTEX_BIT) { + v->pv.tu1 = tc1[i][0] * u1scale * w; + v->pv.tv1 = tc1[i][1] * v1scale * w; + v->pv.tq1 = w; + if (tc1_size == 4) + v->pv.tq1 = tc1[i][3] * w; + } + else { + v->v.tu1 = tc1[i][0] * u1scale * w; + v->v.tv1 = tc1[i][1] * v1scale * w; + } + } + } + } +} +#else +#if (IND & TDFX_XYZ_BIT) +static void TAG(emit)( GLcontext *ctx, GLuint start, GLuint end, + void *dest, GLuint stride ) +{ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLubyte (*col)[4]; + GLuint col_stride; + GLfloat (*proj)[4] = VB->ProjectedClipPtr->data; + GLuint proj_stride = VB->ProjectedClipPtr->stride; + GLfloat *v = (GLfloat *)dest; + const GLubyte *mask = VB->ClipMask; + const GLfloat *s = fxMesa->hw_viewport; + int i; + +/* fprintf(stderr, "%s %d..%d dest %p stride %d\n", __FUNCTION__, */ +/* start, end, dest, stride); */ + + ASSERT(fxMesa->SetupIndex == (TDFX_XYZ_BIT|TDFX_RGBA_BIT)); + ASSERT(stride == 16); + + if (VB->ColorPtr[0]->Type != GL_UNSIGNED_BYTE) + import_float_colors( ctx ); + + col = (GLubyte (*)[4])VB->ColorPtr[0]->Ptr; + col_stride = VB->ColorPtr[0]->StrideB; + ASSERT(VB->ColorPtr[0]->Type == GL_UNSIGNED_BYTE); + + /* Pack what's left into a 4-dword vertex. Color is in a different + * place, and there is no 'w' coordinate. + */ + if (VB->importable_data) { + if (start) { + proj = (GLfloat (*)[4])((GLubyte *)proj + start * proj_stride); + STRIDE_4UB(col, start * col_stride); + } + + for (i=start; i < end; i++, v+=4) { + if (mask[i] == 0) { + v[0] = s[0] * proj[0][0] + s[12]; + v[1] = s[5] * proj[0][1] + s[13]; + v[2] = s[10] * proj[0][2] + s[14]; + } + proj = (GLfloat (*)[4])((GLubyte *)proj + proj_stride); + { + GLubyte *b = (GLubyte *)&v[3]; + b[0] = col[0][2]; + b[1] = col[0][1]; + b[2] = col[0][0]; + b[3] = col[0][3]; + STRIDE_4UB(col, col_stride); + } + } + } + else { + for (i=start; i < end; i++, v+=4) { + if (mask[i] == 0) { + v[0] = s[0] * proj[i][0] + s[12]; + v[1] = s[5] * proj[i][1] + s[13]; + v[2] = s[10] * proj[i][2] + s[14]; + } + { + GLubyte *b = (GLubyte *)&v[3]; + b[0] = col[i][2]; + b[1] = col[i][1]; + b[2] = col[i][0]; + b[3] = col[i][3]; + } + } + } +} +#else +static void TAG(emit)( GLcontext *ctx, GLuint start, GLuint end, + void *dest, GLuint stride ) +{ + tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLubyte (*col)[4]; + GLuint col_stride; + GLfloat *v = (GLfloat *)dest; + int i; + + if (VB->ColorPtr[0]->Type != GL_UNSIGNED_BYTE) + import_float_colors( ctx ); + + col = VB->ColorPtr[0]->Ptr; + col_stride = VB->ColorPtr[0]->StrideB; + + if (start) + STRIDE_4UB(col, col_stride * start); + + /* Need to figure out where color is: + */ + if (fxMesa->SetupIndex & TDFX_W_BIT ) + v += 4; + else + v += 3; + + for (i=start; i < end; i++, STRIDE_F(v, stride)) { + GLubyte *b = (GLubyte *)v; + b[0] = col[0][2]; + b[1] = col[0][1]; + b[2] = col[0][0]; + b[3] = col[0][3]; + STRIDE_4UB( col, col_stride ); + } +} +#endif +#endif + +#if (IND & TDFX_XYZ_BIT) && (IND & TDFX_RGBA_BIT) + +static GLboolean TAG(check_tex_sizes)( GLcontext *ctx ) +{ +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + + if (IND & TDFX_PTEX_BIT) + return GL_TRUE; + + if (IND & TDFX_TEX0_BIT) { + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + + if (IND & TDFX_TEX1_BIT) { + 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 ) +{ + tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + const GLuint shift = fxMesa->vertex_stride_shift; + const GLfloat *dstclip = VB->ClipPtr->data[edst]; + const GLfloat oow = (dstclip[3] == 0.0F) ? 1.0F : (1.0F / dstclip[3]); + const GLfloat *s = fxMesa->hw_viewport; + GLubyte *tdfxverts = (GLubyte *)fxMesa->verts; + tdfxVertex *dst = (tdfxVertex *) (tdfxverts + (edst << shift)); + const tdfxVertex *out = (const tdfxVertex *) (tdfxverts + (eout << shift)); + const tdfxVertex *in = (const tdfxVertex *) (tdfxverts + (ein << shift)); + const GLfloat wout = 1.0F / out->v.rhw; + const GLfloat win = 1.0F / in->v.rhw; + + dst->v.x = s[0] * dstclip[0] * oow + s[12]; + dst->v.y = s[5] * dstclip[1] * oow + s[13]; + dst->v.z = s[10] * dstclip[2] * oow + s[14]; + + if (IND & (TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT)) { + dst->v.rhw = oow; + + INTERP_UB( t, dst->ub4[4][0], out->ub4[4][0], in->ub4[4][0] ); + INTERP_UB( t, dst->ub4[4][1], out->ub4[4][1], in->ub4[4][1] ); + INTERP_UB( t, dst->ub4[4][2], out->ub4[4][2], in->ub4[4][2] ); + INTERP_UB( t, dst->ub4[4][3], out->ub4[4][3], in->ub4[4][3] ); + + if (IND & TDFX_TEX0_BIT) { + if (IND & TDFX_PTEX_BIT) { + INTERP_F( t, dst->pv.tu0, out->pv.tu0 * wout, in->pv.tu0 * win ); + INTERP_F( t, dst->pv.tv0, out->pv.tv0 * wout, in->pv.tv0 * win ); + INTERP_F( t, dst->pv.tq0, out->pv.tq0 * wout, in->pv.tq0 * win ); + dst->pv.tu0 *= oow; + dst->pv.tv0 *= oow; + dst->pv.tq0 *= oow; + } else { + INTERP_F( t, dst->v.tu0, out->v.tu0 * wout, in->v.tu0 * win ); + INTERP_F( t, dst->v.tv0, out->v.tv0 * wout, in->v.tv0 * win ); + dst->v.tu0 *= oow; + dst->v.tv0 *= oow; + } + } + if (IND & TDFX_TEX1_BIT) { + if (IND & TDFX_PTEX_BIT) { + INTERP_F( t, dst->pv.tu1, out->pv.tu1 * wout, in->pv.tu1 * win ); + INTERP_F( t, dst->pv.tv1, out->pv.tv1 * wout, in->pv.tv1 * win ); + INTERP_F( t, dst->pv.tq1, out->pv.tq1 * wout, in->pv.tq1 * win ); + dst->pv.tu1 *= oow; + dst->pv.tv1 *= oow; + dst->pv.tq1 *= oow; + } else { + INTERP_F( t, dst->v.tu1, out->v.tu1 * wout, in->v.tu1 * win ); + INTERP_F( t, dst->v.tv1, out->v.tv1 * wout, in->v.tv1 * win ); + dst->v.tu1 *= oow; + dst->v.tv1 *= oow; + } + } + } else { + /* 4-dword vertex. Color is in v[3] and there is no oow coordinate. + */ + INTERP_UB( t, dst->ub4[3][0], out->ub4[3][0], in->ub4[3][0] ); + INTERP_UB( t, dst->ub4[3][1], out->ub4[3][1], in->ub4[3][1] ); + INTERP_UB( t, dst->ub4[3][2], out->ub4[3][2], in->ub4[3][2] ); + INTERP_UB( t, dst->ub4[3][3], out->ub4[3][3], in->ub4[3][3] ); + } +} +#endif + + +static void TAG(init)( void ) +{ +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + + setup_tab[IND].emit = TAG(emit); + +#if ((IND & TDFX_XYZ_BIT) && (IND & TDFX_RGBA_BIT)) + setup_tab[IND].check_tex_sizes = TAG(check_tex_sizes); + setup_tab[IND].interp = TAG(interp); + + if (IND & (TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT)) + setup_tab[IND].copy_pv = copy_pv_rgba4; + else + setup_tab[IND].copy_pv = copy_pv_rgba3; + + + if (IND & TDFX_TEX1_BIT) { + if (IND & TDFX_PTEX_BIT) { + setup_tab[IND].vertex_format = TDFX_LAYOUT_PROJECT; + setup_tab[IND].vertex_size = 12; + setup_tab[IND].vertex_stride_shift = 6; + } + else { + setup_tab[IND].vertex_format = TDFX_LAYOUT_MULTI; + setup_tab[IND].vertex_size = 10; + setup_tab[IND].vertex_stride_shift = 6; + } + } + else if (IND & TDFX_TEX0_BIT) { + if (IND & TDFX_PTEX_BIT) { + setup_tab[IND].vertex_format = TDFX_LAYOUT_PROJECT; + setup_tab[IND].vertex_size = 12; + setup_tab[IND].vertex_stride_shift = 6; + } else { + setup_tab[IND].vertex_format = TDFX_LAYOUT_SINGLE; + setup_tab[IND].vertex_size = 8; + setup_tab[IND].vertex_stride_shift = 5; + } + } + else if (IND & TDFX_W_BIT) { + setup_tab[IND].vertex_format = TDFX_LAYOUT_NOTEX; + setup_tab[IND].vertex_size = 6; + setup_tab[IND].vertex_stride_shift = 5; + } else { + setup_tab[IND].vertex_format = TDFX_LAYOUT_TINY; + setup_tab[IND].vertex_size = 4; + setup_tab[IND].vertex_stride_shift = 4; + } +#endif +} + + +#undef IND +#undef TAG diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_wrapper.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_wrapper.c deleted file mode 100644 index 70641eb9a..000000000 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_wrapper.c +++ /dev/null @@ -1,392 +0,0 @@ -/* -*- 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/tdfx/tdfx_wrapper.c,v 1.2 2001/08/18 02:51:07 dawes Exp $ */ - -/* - * Original rewrite: - * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 - * - * Authors: - * Gareth Hughes <gareth@valinux.com> - * Brian Paul <brianp@valinux.com> - * - */ - -#include <stdlib.h> -#include <string.h> - -#include "tdfx_context.h" - - -FxI32 -FX_grGetInteger_NoLock(tdfxContextPtr fxMesa, FxU32 pname) -{ - switch (pname) { - case FX_FOG_TABLE_ENTRIES: - case FX_GLIDE_STATE_SIZE: - case FX_LFB_PIXEL_PIPE: - case FX_PENDING_BUFFERSWAPS: - case FX_TEXTURE_ALIGN: - case GR_STATS_PIXELS_DEPTHFUNC_FAIL: - case GR_STATS_PIXELS_IN: - case GR_STATS_PIXELS_OUT: - { - FxI32 result; - FxU32 grname = pname; - fxMesa->Glide.grGet(grname, 4, &result); - return result; - } - case FX_ZDEPTH_MAX: - { - FxI32 zvals[2]; - fxMesa->Glide.grGet(GR_ZDEPTH_MIN_MAX, 8, zvals); - return zvals[0]; - } - default: - if (MESA_VERBOSE & VERBOSE_DRIVER) { - fprintf(stderr, "Wrong parameter in FX_grGetInteger!\n"); - } - } - - return 0; -} - - -FxI32 -FX_grGetInteger(tdfxContextPtr fxMesa, FxU32 pname) -{ - int result; - LOCK_HARDWARE(fxMesa); - result = FX_grGetInteger_NoLock(fxMesa, pname); - UNLOCK_HARDWARE(fxMesa); - return result; -} - - -const char * -FX_grGetString(tdfxContextPtr fxMesa, FxU32 pname) -{ - const char *s; - LOCK_HARDWARE(fxMesa); - s = fxMesa->Glide.grGetString(pname); - UNLOCK_HARDWARE(fxMesa); - return s; -} - - - -/* Wrapper for grColorMask() and grColorMaskExt(). - */ -void -FX_grColorMask(GLcontext *ctx, GLboolean r, GLboolean g, - GLboolean b, GLboolean a) -{ - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - LOCK_HARDWARE(fxMesa); - if (ctx->Visual->RedBits == 8) { - /* 32bpp mode */ - ASSERT( fxMesa->Glide.grColorMaskExt ); - fxMesa->Glide.grColorMaskExt(r, g, b, a); - } - else { - /* 16 bpp mode */ - /* we never have an alpha buffer */ - fxMesa->Glide.grColorMask(r || g || b, GL_FALSE); - } - UNLOCK_HARDWARE(fxMesa); -} - - -void -FX_grColorMask_NoLock(GLcontext *ctx, GLboolean r, GLboolean g, - GLboolean b, GLboolean a) -{ - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - if (ctx->Visual->RedBits == 8) { - /* 32bpp mode */ - ASSERT( fxMesa->Glide.grColorMaskExt ); - fxMesa->Glide.grColorMaskExt(r, g, b, a); - } - else { - /* 16 bpp mode */ - /* we never have an alpha buffer */ - fxMesa->Glide.grColorMask(r || g || b, GL_FALSE); - } -} - - -/* As above, but pass the mask as an array - */ -void -FX_grColorMaskv(GLcontext *ctx, const GLboolean rgba[4]) -{ - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - LOCK_HARDWARE(fxMesa); - if (ctx->Visual->RedBits == 8) { - /* 32bpp mode */ - ASSERT( fxMesa->Glide.grColorMaskExt ); - fxMesa->Glide.grColorMaskExt(rgba[RCOMP], rgba[GCOMP], - rgba[BCOMP], rgba[ACOMP]); - } - else { - /* 16 bpp mode */ - /* we never have an alpha buffer */ - fxMesa->Glide.grColorMask(rgba[RCOMP] || rgba[GCOMP] || rgba[BCOMP], GL_FALSE); - } - UNLOCK_HARDWARE(fxMesa); -} - -void -FX_grColorMaskv_NoLock(GLcontext *ctx, const GLboolean rgba[4]) -{ - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - if (ctx->Visual->RedBits == 8) { - /* 32bpp mode */ - ASSERT( fxMesa->Glide.grColorMaskExt ); - fxMesa->Glide.grColorMaskExt(rgba[RCOMP], rgba[GCOMP], - rgba[BCOMP], rgba[ACOMP]); - } - else { - /* 16 bpp mode */ - /* we never have an alpha buffer */ - fxMesa->Glide.grColorMask(rgba[RCOMP] || rgba[GCOMP] || rgba[BCOMP], GL_FALSE); - } -} - - - -FxBool -FX_grLfbLock(tdfxContextPtr fxMesa, GrLock_t type, GrBuffer_t buffer, - GrLfbWriteMode_t writeMode, GrOriginLocation_t origin, - FxBool pixelPipeline, GrLfbInfo_t * info) -{ - FxBool result; - - LOCK_HARDWARE(fxMesa); - result = fxMesa->Glide.grLfbLock(type, buffer, writeMode, - origin, pixelPipeline, info); - UNLOCK_HARDWARE(fxMesa); - return result; -} - -FxU32 -FX_grTexTextureMemRequired(tdfxContextPtr fxMesa, FxU32 evenOdd, GrTexInfo * info) -{ - FxU32 result; - - LOCK_HARDWARE(fxMesa); - result = fxMesa->Glide.grTexTextureMemRequired(evenOdd, info); - UNLOCK_HARDWARE(fxMesa); - return result; -} - -FxU32 -FX_grTexMinAddress(tdfxContextPtr fxMesa, GrChipID_t tmu) -{ - FxU32 result; - - LOCK_HARDWARE(fxMesa); - result = fxMesa->Glide.grTexMinAddress(tmu); - UNLOCK_HARDWARE(fxMesa); - return result; -} - -extern FxU32 -FX_grTexMaxAddress(tdfxContextPtr fxMesa, GrChipID_t tmu) -{ - FxU32 result; - - LOCK_HARDWARE(fxMesa); - result = fxMesa->Glide.grTexMaxAddress(tmu); - UNLOCK_HARDWARE(fxMesa); - return result; -} - - -int -FX_getFogTableSize(tdfxContextPtr fxMesa) -{ - int result; - LOCK_HARDWARE(fxMesa); - fxMesa->Glide.grGet(GR_FOG_TABLE_ENTRIES, sizeof(int), (void *) &result); - UNLOCK_HARDWARE(fxMesa); - return result; -} - -int -FX_getGrStateSize(tdfxContextPtr fxMesa) -{ - int result; - LOCK_HARDWARE(fxMesa); - fxMesa->Glide.grGet(GR_GLIDE_STATE_SIZE, sizeof(int), (void *) &result); - UNLOCK_HARDWARE(fxMesa); - return result; -} - -void -FX_grAADrawLine(tdfxContextPtr fxMesa, GrVertex * a, GrVertex * b) -{ - /* ToDo */ - BEGIN_CLIP_LOOP(fxMesa); - fxMesa->Glide.grDrawLine(a, b); - END_CLIP_LOOP(fxMesa); -} - -void -FX_grAADrawPoint(tdfxContextPtr fxMesa, GrVertex * a) -{ - BEGIN_CLIP_LOOP(fxMesa); - fxMesa->Glide.grDrawPoint(a); - END_CLIP_LOOP(fxMesa); -} - -void -FX_grDrawPolygonVertexList(tdfxContextPtr fxMesa, int n, GrVertex * verts) -{ - BEGIN_CLIP_LOOP(fxMesa); - fxMesa->Glide.grDrawVertexArrayContiguous(GR_POLYGON, n, verts, sizeof(GrVertex)); - END_CLIP_LOOP(fxMesa); -} - -#if TDFX_USE_PARGB -void -FX_setupGrVertexLayout(tdfxContextPtr fxMesa) -{ - LOCK_HARDWARE(fxMesa); - fxMesa->Glide.grReset(GR_VERTEX_PARAMETER); - - fxMesa->Glide.grCoordinateSpace(GR_WINDOW_COORDS); - fxMesa->Glide.grVertexLayout(GR_PARAM_XY, GR_VERTEX_X_OFFSET << 2, GR_PARAM_ENABLE); - fxMesa->Glide.grVertexLayout(GR_PARAM_PARGB, GR_VERTEX_PARGB_OFFSET << 2, GR_PARAM_ENABLE); - fxMesa->Glide.grVertexLayout(GR_PARAM_Q, GR_VERTEX_OOW_OFFSET << 2, GR_PARAM_ENABLE); - fxMesa->Glide.grVertexLayout(GR_PARAM_Z, GR_VERTEX_OOZ_OFFSET << 2, GR_PARAM_ENABLE); - fxMesa->Glide.grVertexLayout(GR_PARAM_ST0, GR_VERTEX_SOW_TMU0_OFFSET << 2, GR_PARAM_ENABLE); - fxMesa->Glide.grVertexLayout(GR_PARAM_Q0, GR_VERTEX_OOW_TMU0_OFFSET << 2, GR_PARAM_DISABLE); - fxMesa->Glide.grVertexLayout(GR_PARAM_ST1, GR_VERTEX_SOW_TMU1_OFFSET << 2, GR_PARAM_DISABLE); - fxMesa->Glide.grVertexLayout(GR_PARAM_Q1, GR_VERTEX_OOW_TMU1_OFFSET << 2, GR_PARAM_DISABLE); - UNLOCK_HARDWARE(fxMesa); -} -#else /* TDFX_USE_PARGB */ -void -FX_setupGrVertexLayout(tdfxContextPtr fxMesa) -{ - LOCK_HARDWARE(fxMesa); - fxMesa->Glide.grReset(GR_VERTEX_PARAMETER); - - fxMesa->Glide.grCoordinateSpace(GR_WINDOW_COORDS); - fxMesa->Glide.grVertexLayout(GR_PARAM_XY, GR_VERTEX_X_OFFSET << 2, GR_PARAM_ENABLE); - fxMesa->Glide.grVertexLayout(GR_PARAM_RGB, GR_VERTEX_R_OFFSET << 2, GR_PARAM_ENABLE); - fxMesa->Glide.grVertexLayout(GR_PARAM_A, GR_VERTEX_A_OFFSET << 2, GR_PARAM_ENABLE); - fxMesa->Glide.grVertexLayout(GR_PARAM_Q, GR_VERTEX_OOW_OFFSET << 2, GR_PARAM_ENABLE); - fxMesa->Glide.grVertexLayout(GR_PARAM_Z, GR_VERTEX_OOZ_OFFSET << 2, GR_PARAM_ENABLE); - fxMesa->Glide.grVertexLayout(GR_PARAM_ST0, GR_VERTEX_SOW_TMU0_OFFSET << 2, GR_PARAM_ENABLE); - fxMesa->Glide.grVertexLayout(GR_PARAM_Q0, GR_VERTEX_OOW_TMU0_OFFSET << 2, GR_PARAM_DISABLE); - fxMesa->Glide.grVertexLayout(GR_PARAM_ST1, GR_VERTEX_SOW_TMU1_OFFSET << 2, GR_PARAM_DISABLE); - fxMesa->Glide.grVertexLayout(GR_PARAM_Q1, GR_VERTEX_OOW_TMU1_OFFSET << 2, GR_PARAM_DISABLE); - UNLOCK_HARDWARE(fxMesa); -} -#endif /* TDFX_USE_PARGB */ - -void -FX_grHints_NoLock(tdfxContextPtr fxMesa, GrHint_t hintType, FxU32 hintMask) -{ - switch (hintType) { - case GR_HINT_STWHINT: - { - if (hintMask & GR_STWHINT_W_DIFF_TMU0) - fxMesa->Glide.grVertexLayout(GR_PARAM_Q0, - GR_VERTEX_OOW_TMU0_OFFSET << 2, - GR_PARAM_ENABLE); - else - fxMesa->Glide.grVertexLayout(GR_PARAM_Q0, - GR_VERTEX_OOW_TMU0_OFFSET << 2, - GR_PARAM_DISABLE); - - if (hintMask & GR_STWHINT_ST_DIFF_TMU1) - fxMesa->Glide.grVertexLayout(GR_PARAM_ST1, - GR_VERTEX_SOW_TMU1_OFFSET << 2, - GR_PARAM_ENABLE); - else - fxMesa->Glide.grVertexLayout(GR_PARAM_ST1, - GR_VERTEX_SOW_TMU1_OFFSET << 2, - GR_PARAM_DISABLE); - - if (hintMask & GR_STWHINT_W_DIFF_TMU1) - fxMesa->Glide.grVertexLayout(GR_PARAM_Q1, - GR_VERTEX_OOW_TMU1_OFFSET << 2, - GR_PARAM_ENABLE); - else - fxMesa->Glide.grVertexLayout(GR_PARAM_Q1, - GR_VERTEX_OOW_TMU1_OFFSET << 2, - GR_PARAM_DISABLE); - - } - } -} - -void -FX_grHints(tdfxContextPtr fxMesa, GrHint_t hintType, FxU32 hintMask) -{ - LOCK_HARDWARE(fxMesa); - FX_grHints_NoLock(fxMesa, hintType, hintMask); - UNLOCK_HARDWARE(fxMesa); -} - -/* It appears to me that this function is needed either way. */ -FX_GrContext_t -FX_grSstWinOpen(tdfxContextPtr fxMesa, - FxU32 hWnd, - GrScreenResolution_t screen_resolution, - GrScreenRefresh_t refresh_rate, - GrColorFormat_t color_format, - GrOriginLocation_t origin_location, - int nColBuffers, int nAuxBuffers) -{ - FX_GrContext_t i; - LOCK_HARDWARE(fxMesa); - i = fxMesa->Glide.grSstWinOpen(hWnd, - screen_resolution, - refresh_rate, - color_format, origin_location, - nColBuffers, nAuxBuffers); - - /* - fprintf(stderr, - "grSstWinOpen( win %d res %d ref %d fmt %d\n" - " org %d ncol %d naux %d )\n" - " ==> %d\n", - hWnd, - screen_resolution, - refresh_rate, - color_format, - origin_location, - nColBuffers, - nAuxBuffers, - i); - */ - UNLOCK_HARDWARE(fxMesa); - return i; -} diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_wrapper.h b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_wrapper.h deleted file mode 100644 index 9bb819c96..000000000 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_wrapper.h +++ /dev/null @@ -1,673 +0,0 @@ -/* - * 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. - * - * - * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the - * terms stated above. - * - * Thank you for your contribution, David! - * - * Please make note of the above copyright/license statement. If you - * contributed code or bug fixes to this code under the previous (GNU - * Library) license and object to the new license, your code will be - * removed at your request. Please see the Mesa docs/COPYRIGHT file - * for more information. - * - * Additional Mesa/3Dfx driver developers: - * Daryll Strauss <daryll@precisioninsight.com> - * Keith Whitwell <keith@precisioninsight.com> - * - * See fxapi.h for more revision/author details. - */ -/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_wrapper.h,v 1.3 2001/08/18 11:55:48 tsi Exp $ */ - -#ifndef __FX_GLIDE_WARPER__ -#define __FX_GLIDE_WARPER__ - -#include "glide.h" -#include "g3ext.h" - -typedef struct tdfx_context tdfxContextRec; -typedef struct tdfx_context *tdfxContextPtr; - -/* - * General context: - */ -typedef GrContext_t FX_GrContext_t; - -#define FX_FOG_TABLE_ENTRIES GR_FOG_TABLE_ENTRIES -#define FX_GLIDE_STATE_SIZE GR_GLIDE_STATE_SIZE -#define FX_LFB_PIXEL_PIPE GR_LFB_PIXEL_PIPE -#define FX_PENDING_BUFFERSWAPS GR_PENDING_BUFFERSWAPS -#define FX_TEXTURE_ALIGN GR_TEXTURE_ALIGN - -#define FX_ZDEPTH_MAX 0x100 - - -#define GR_ASPECT_1x1 GR_ASPECT_LOG2_1x1 -#define GR_ASPECT_2x1 GR_ASPECT_LOG2_2x1 -#define GR_ASPECT_4x1 GR_ASPECT_LOG2_4x1 -#define GR_ASPECT_8x1 GR_ASPECT_LOG2_8x1 -#define GR_ASPECT_1x2 GR_ASPECT_LOG2_1x2 -#define GR_ASPECT_1x4 GR_ASPECT_LOG2_1x4 -#define GR_ASPECT_1x8 GR_ASPECT_LOG2_1x8 - -#define GR_LOD_256 GR_LOD_LOG2_256 -#define GR_LOD_128 GR_LOD_LOG2_128 -#define GR_LOD_64 GR_LOD_LOG2_64 -#define GR_LOD_32 GR_LOD_LOG2_32 -#define GR_LOD_16 GR_LOD_LOG2_16 -#define GR_LOD_8 GR_LOD_LOG2_8 -#define GR_LOD_4 GR_LOD_LOG2_4 -#define GR_LOD_2 GR_LOD_LOG2_2 -#define GR_LOD_1 GR_LOD_LOG2_1 - -#define GR_FOG_WITH_TABLE GR_FOG_WITH_TABLE_ON_Q - - -typedef FxU32 GrHint_t; -#define GR_HINTTYPE_MIN 0 -#define GR_HINT_STWHINT 0 - -typedef FxU32 GrSTWHint_t; -#define GR_STWHINT_W_DIFF_FBI FXBIT(0) -#define GR_STWHINT_W_DIFF_TMU0 FXBIT(1) -#define GR_STWHINT_ST_DIFF_TMU0 FXBIT(2) -#define GR_STWHINT_W_DIFF_TMU1 FXBIT(3) -#define GR_STWHINT_ST_DIFF_TMU1 FXBIT(4) -#define GR_STWHINT_W_DIFF_TMU2 FXBIT(5) -#define GR_STWHINT_ST_DIFF_TMU2 FXBIT(6) - -#define GR_CONTROL_ACTIVATE 1 -#define GR_CONTROL_DEACTIVATE 0 - -#define GrState void - -/* -** move the vertex layout defintion to application -*/ -typedef struct -{ - GLfloat sow; /* s texture ordinate (s over w) */ - GLfloat tow; /* t texture ordinate (t over w) */ - GLfloat oow; /* 1/w (used mipmapping - really 0xfff/w) */ -} -GrTmuVertex; - - -#if FX_USE_PARGB - -/* standard vertex, packed argb, double texture, 12 dwords */ -typedef struct -{ - GLfloat x, y; /* X and Y in screen space */ - GLfloat ooz; /* 65535/Z (used for Z-buffering) */ - GLfloat oow; /* 1/W (used for W-buffering, texturing) */ - FxU32 argb; /* R, G, B, A [0..255.0] */ - GrTmuVertex tmuvtx[GLIDE_NUM_TMU]; - GLfloat z; /* Z is ignored */ -} -GrVertex; - -/* optimised vertex, packed argb, single texture, 8 dwords = 1 cacheline */ -typedef struct -{ - GLfloat x, y; /* X and Y in screen space */ - GLfloat ooz; /* 65535/Z (used for Z-buffering) */ - GLfloat oow; /* 1/W (used for W-buffering, texturing) */ - FxU32 argb; /* R, G, B, A [0..255.0] */ - GrTmuVertex tmuvtx; /* only 1 TMU used to keep vertex size down */ -} -GrVertex_Fast; - -/* following offsets work for both vertex layouts */ -#define GR_VERTEX_X_OFFSET 0 -#define GR_VERTEX_Y_OFFSET 1 -#define GR_VERTEX_OOZ_OFFSET 2 -#define GR_VERTEX_OOW_OFFSET 3 -#define GR_VERTEX_PARGB_OFFSET 4 -#define GR_VERTEX_SOW_TMU0_OFFSET 5 -#define GR_VERTEX_TOW_TMU0_OFFSET 6 -#define GR_VERTEX_OOW_TMU0_OFFSET 7 -#define GR_VERTEX_SOW_TMU1_OFFSET 8 -#define GR_VERTEX_TOW_TMU1_OFFSET 9 -#define GR_VERTEX_OOW_TMU1_OFFSET 10 -#define GR_VERTEX_Z_OFFSET 11 - -#if GLIDE_ENDIAN == GLIDE_ENDIAN_BIG -#define GET_PA(v) ((FxU8*)(v))[GR_VERTEX_PARGB_OFFSET*4+3] -#define GET_PR(v) ((FxU8*)(v))[GR_VERTEX_PARGB_OFFSET*4+2] -#define GET_PG(v) ((FxU8*)(v))[GR_VERTEX_PARGB_OFFSET*4+1] -#define GET_PB(v) ((FxU8*)(v))[GR_VERTEX_PARGB_OFFSET*4+0] -#else -#define GET_PA(v) ((FxU8*)(v))[GR_VERTEX_PARGB_OFFSET*4+0] -#define GET_PR(v) ((FxU8*)(v))[GR_VERTEX_PARGB_OFFSET*4+1] -#define GET_PG(v) ((FxU8*)(v))[GR_VERTEX_PARGB_OFFSET*4+2] -#define GET_PB(v) ((FxU8*)(v))[GR_VERTEX_PARGB_OFFSET*4+3] -#endif - -#define GET_PARGB(v) ((FxU32*)(v))[GR_VERTEX_PARGB_OFFSET] -#define PACK_4F_ARGB(dest, a, r, g, b) { \ - const GLuint cr = (int)r; \ - const GLuint cg = (int)g; \ - const GLuint ca = (int)a; \ - const GLuint cb = (int)b; \ - dest = ca << 24 | cr << 16 | cg << 8 | cb; \ -} - -#else /* FX_USE_PARGB */ - -typedef struct -{ - float x, y, z; /* X, Y, and Z of scrn space -- Z is ignored */ - float r, g, b; /* R, G, B, ([0..255.0]) */ - float ooz; /* 65535/Z (used for Z-buffering) */ - float a; /* Alpha [0..255.0] */ - float oow; /* 1/W (used for W-buffering, texturing) */ - GrTmuVertex tmuvtx[GLIDE_NUM_TMU]; -} -GrVertex; - -#define GR_VERTEX_X_OFFSET 0 -#define GR_VERTEX_Y_OFFSET 1 -#define GR_VERTEX_Z_OFFSET 2 -#define GR_VERTEX_R_OFFSET 3 -#define GR_VERTEX_G_OFFSET 4 -#define GR_VERTEX_B_OFFSET 5 -#define GR_VERTEX_OOZ_OFFSET 6 -#define GR_VERTEX_A_OFFSET 7 -#define GR_VERTEX_OOW_OFFSET 8 -#define GR_VERTEX_SOW_TMU0_OFFSET 9 -#define GR_VERTEX_TOW_TMU0_OFFSET 10 -#define GR_VERTEX_OOW_TMU0_OFFSET 11 -#define GR_VERTEX_SOW_TMU1_OFFSET 12 -#define GR_VERTEX_TOW_TMU1_OFFSET 13 -#define GR_VERTEX_OOW_TMU1_OFFSET 14 -#endif /* FX_USE_PARGB */ - - - -extern FxI32 FX_grGetInteger_NoLock(tdfxContextPtr fxMesa, FxU32 pname); - -extern FxI32 FX_grGetInteger(tdfxContextPtr fxMesa, FxU32 pname); - -extern const char *FX_grGetString(tdfxContextPtr fxMesa, FxU32 pname); - - -#define FX_grTexDownloadTable(fxMesa, type, data) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grTexDownloadTable(type,data); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0); - -#define FX_grTexDownloadTable_NoLock(type, data) \ - fxMesa->Glide.grTexDownloadTable(type, data) - - -#define FX_grFlush(fxMesa) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grFlush(); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grFinish(fxMesa) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMes->Glide.grFinish(); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - - -#define FX_grLfbWriteRegion(fxMesa,dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grLfbWriteRegion(dst_buffer,dst_x,dst_y,src_format,src_width,src_height,FXFALSE,src_stride,src_data); \ - UNLOCK_HARDWARE(fxMesa); \ - } while(0) - - -#define FX_grLfbReadRegion(fxMesa,src_buffer,src_x,src_y,src_width,src_height,dst_stride,dst_data) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grLfbReadRegion(src_buffer,src_x,src_y,src_width,src_height,dst_stride,dst_data); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0); - - -#define FX_grDrawTriangle_NoLock(a,b,c) fxMesa->Glide.grDrawTriangle(a,b,c) -#define FX_grDrawTriangle(fxMesa, a,b,c) \ - do { \ - BEGIN_CLIP_LOOP(fxMesa); \ - FX_grDrawTriangle_NoLock(a,b,c); \ - END_CLIP_LOOP(fxMesa); \ - } while (0) - - - -extern void FX_grHints_NoLock(tdfxContextPtr fxMesa, GrHint_t hintType, FxU32 hintMask); -extern void FX_grHints(tdfxContextPtr fxMesa, GrHint_t hintType, FxU32 hintMask); - - -extern void FX_grAADrawLine(tdfxContextPtr fxMesa, GrVertex * a, GrVertex * b); - -extern void FX_grAADrawPoint(tdfxContextPtr fxMesa, GrVertex * a); - - -extern void FX_setupGrVertexLayout(tdfxContextPtr fxMesa); - - -extern FX_GrContext_t FX_grSstWinOpen(tdfxContextPtr fxMesa, - FxU32 hWnd, - GrScreenResolution_t screen_resolution, - GrScreenRefresh_t refresh_rate, - GrColorFormat_t color_format, - GrOriginLocation_t origin_location, - int nColBuffers, int nAuxBuffers); - - -#define FX_grDrawLine_NoLock(v1, v2) fxMesa->Glide.grDrawLine(v1, v2) -#define FX_grDrawLine(fxMesa, v1, v2) \ - do { \ - BEGIN_CLIP_LOOP(fxMesa); \ - FX_grDrawLine_NoLock(v1, v2); \ - END_CLIP_LOOP(fxMesa); \ - } while (0) - -#define FX_grDrawPoint_NoLock(p) fxMesa->Glide.grDrawPoint(p) -#define FX_grDrawPoint(fxMesa, p) \ - do { \ - BEGIN_CLIP_LOOP(fxMesa); \ - FX_grDrawPoint_NoLock(p); \ - END_CLIP_LOOP(fxMesa); \ - } while (0) - -extern void FX_grDrawPolygonVertexList(tdfxContextPtr fxMesa, - int n, GrVertex * v); - -#define FX_grDitherMode(fxMesa, m) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grDitherMode(m); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grRenderBuffer(fxMesa, b) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grRenderBuffer(b); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grRenderBuffer_NoLock(b) fxMesa->Glide.grRenderBuffer(b) - -#define FX_grBufferClear(fxMesa, c, a, d) \ - do { \ - BEGIN_CLIP_LOOP(fxMesa); \ - fxMesa->Glide.grBufferClear(c, a, d); \ - END_CLIP_LOOP(fxMesa); \ - } while (0) - -#define FX_grBufferClear_NoLock(c, a, d) fxMesa->Glide.grBufferClear(c, a, d) - - -#define FX_grBufferClearExt_NoLock(c, a, d, s) fxMesa->Glide.grBufferClearExt(c, a, d, s) - -#define FX_grBufferClearExt(fxMesa, c, a, d, s) \ - do { \ - BEGIN_CLIP_LOOP(fxMesa); \ - fxMesa->Glide.grBufferClearExt(c, a, d, s); \ - END_CLIP_LOOP(fxMesa); \ - } while (0) - -#define FX_grEnable(fxMesa, m) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grEnable(m); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grEnable_NoLock(m) fxMesa->Glide.grEnable(m) - -#define FX_grDisable(fxMesa, m) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grDisable(m); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grDisable_NoLock(m) fxMesa->Glide.grDisable(m) - - -#define FX_grStencilFunc(fxMesa, fnc, ref, mask) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grStencilFunc((fnc), (ref), (mask)); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grStencilFunc_NoLock(f, r, m) fxMesa->grStencilFunc(f, r, m) - -#define FX_grStencilMask(fxMesa, write_mask) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grStencilMask(write_mask); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grStencilMask_NoLock(m) fxMesa->Glide.grStencilMask(m) - -#define FX_grStencilOp(fxMesa, stencil_fail, depth_fail, depth_pass) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grStencilOp((stencil_fail), (depth_fail), (depth_pass));\ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grStencilOp_NoLock(sf, df, dp) fxMesa->Glide.grStencilOp(sf, df, dp) - -#define FX_grDepthMask(fxMesa, m) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grDepthMask(m); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grDepthMask_NoLock(m) fxMesa->Glide.grDepthMask(m) - - -extern void FX_grColorMask(GLcontext *ctx, GLboolean r, GLboolean g, - GLboolean b, GLboolean a); - -extern void FX_grColorMask_NoLock(GLcontext *ctx, GLboolean r, GLboolean g, - GLboolean b, GLboolean a); - -extern void FX_grColorMaskv(GLcontext *ctx, const GLboolean rgba[4]); - -extern void FX_grColorMaskv_NoLock(GLcontext *ctx, const GLboolean rgba[4]); - - -extern FxBool FX_grLfbLock(tdfxContextPtr fxMesa, - GrLock_t type, GrBuffer_t buffer, - GrLfbWriteMode_t writeMode, - GrOriginLocation_t origin, FxBool pixelPipeline, - GrLfbInfo_t * info); - -#define FX_grLfbUnlock(fxMesa, t, b) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grLfbUnlock(t, b); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grConstantColorValue(fxMesa, v) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grConstantColorValue(v); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grConstantColorValue_NoLock fxMesa->Glide.grConstantColorValue - -#define FX_grAADrawTriangle(fxMesa, a, b, c, ab, bc, ca) \ - do { \ - BEGIN_CLIP_LOOP(fxMesa); \ - fxMesa->Glide.grAADrawTriangle(a, b, c, ab, bc, ca); \ - END_CLIP_LOOP(fxMesa); \ - } while (0) - -#define FX_grAlphaBlendFunction(rs, rd, as, ad) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grAlphaBlendFunction(rs, rd, as, ad); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grAlphaCombine(func, fact, loc, oth, inv) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grAlphaCombine(func, fact, loc, oth, inv); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grAlphaCombine_NoLock fxMesa->Glide.grAlphaCombine - -#define FX_grAlphaTestFunction(fxMesa, f) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grAlphaTestFunction(f); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grAlphaTestReferenceValue(fxMesa, v) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grAlphaTestReferenceValue(v); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grClipWindow(fxMesa, minx, miny, maxx, maxy) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grClipWindow(minx, miny, maxx, maxy); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grClipWindow_NoLock fxMesa->Glide.grClipWindow - -#define FX_grColorCombine(fxMesa, func, fact, loc, oth, inv) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grColorCombine(func, fact, loc, oth, inv); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grColorCombine_NoLock fxMesa->Glide.grColorCombine - -#define FX_grCullMode(fxMesa, m) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grCullMode(m); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grDepthBiasLevel(fxMesa, lev) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grDepthBiasLevel(lev); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grDepthBufferFunction(fxMesa, func) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grDepthBufferFunction(func); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grFogColorValue(fxMesa, c) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grFogColorValue(c); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grFogMode(fxMesa, m) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grFogMode(m); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grFogTable(fxMesa, t)\ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grFogTable(t);\ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grTexClampMode(fxMesa, t, sc, tc) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grTexClampMode(t, sc, tc); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grTexClampMode_NoLock fxMesa->Glide.grTexClampMode - -#define FX_grTexCombine(fxMesa, t, rfunc, rfact, afunc, afact, rinv, ainv)\ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grTexCombine(t, rfunc, rfact, afunc, afact, rinv, ainv);\ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grTexCombine_NoLock fxMesa->Glide.grTexCombine - -#define FX_grTexDownloadMipMapLevel(fxMesa, t, sa, tlod, llod, ar, f, eo, d)\ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grTexDownloadMipMapLevel(t, sa, tlod, llod, ar, f, eo, d);\ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grTexDownloadMipMapLevelPartial(fxMesa, t, sa, tlod, llod, ar, f, eo, d, s, e); \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grTexDownloadMipMapLevelPartial(t, sa, tlod, llod, ar, f, eo, d, s, e); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grTexFilterMode(fxMesa, t, minf, magf) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grTexFilterMode(t, minf, magf); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grTexFilterMode_NoLock fxMesa->Glide.grTexFilterMode - -extern FxU32 FX_grTexMinAddress(tdfxContextPtr fxMesa, GrChipID_t tmu); -extern FxU32 FX_grTexMaxAddress(tdfxContextPtr fxMesa, GrChipID_t tmu); - -#define FX_grTexMipMapMode(t, m, lod) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grTexMipMapMode(t, m, lod);\ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grTexMipMapMode_NoLock fxMesa->Glide.grTexMipMapMode - -#define FX_grTexSource(t, sa, eo, i) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grTexSource(t, sa, eo, i);\ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grTexSource_NoLock fxMesa->Glide.grTexSource - -extern FxU32 FX_grTexTextureMemRequired(tdfxContextPtr fxMesa, - FxU32 evenOdd, GrTexInfo * info); - -#define FX_grTexTextureMemRequired_NoLock fxMesa->Glide.grTexTextureMemRequired - -#define FX_grGlideGetState(fxMesa, s) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grGlideGetState(s); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) -#define FX_grGlideGetState_NoLock(s) fxMesa->Glide.grGlideGetState(s); - -#define FX_grDRIBufferSwap(fxMesa, i) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grDRIBufferSwap(i); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grSstSelect(fxMesa, b) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grSstSelect(b); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grSstSelect_NoLock fxMesa->Glide.grSstSelect - -#define FX_grGlideSetState(fxMesa, s) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grGlideSetState(s); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) -#define FX_grGlideSetState_NoLock(s) fxMesa->Glide.grGlideSetState(s); - -#define FX_grDepthBufferMode(fxMesa, m) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grDepthBufferMode(m); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grLfbWriteColorFormat(fxMesa, f) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grLfbWriteColorFormat(f); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grDrawVertexArray(fxMesa, m, c, p) \ - do { \ - BEGIN_CLIP_LOOP(fxMesa); \ - fxMesa->Glide.grDrawVertexArray(m, c, p); \ - END_CLIP_LOOP(fxMesa); \ - } while (0) - -#define FX_grGlideShutdown(fxMesa) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grGlideShutdown(); \ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grTexLodBiasValue_NoLock(t, v) fxMesa->Glide.grTexLodBiasValue(t, v) - -#define FX_grTexLodBiasValue(t, v) \ - do { \ - LOCK_HARDWARE(fxMesa); \ - fxMesa->Glide.grTexLodBiasValue(t, v);\ - UNLOCK_HARDWARE(fxMesa); \ - } while (0) - -#define FX_grGlideInit_NoLock fxMesa->Glide.grGlideInit -#define FX_grSstWinOpen_NoLock fxMesa->Glide.grSstWinOpen - -extern int FX_getFogTableSize(tdfxContextPtr fxMesa); - -extern int FX_getGrStateSize(tdfxContextPtr fxMesa); - -#endif /* __FX_GLIDE_WARPER__ */ diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c deleted file mode 100644 index 9fb4a8321..000000000 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c +++ /dev/null @@ -1,429 +0,0 @@ -/* -*- 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/tdfx/tdfx_xmesa.c,v 1.13 2001/08/18 02:51:07 dawes Exp $ */ - -/* - * Original rewrite: - * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 - * - * Authors: - * Gareth Hughes <gareth@valinux.com> - * Brian Paul <brianp@valinux.com> - * - */ - -#ifdef GLX_DIRECT_RENDERING - -#include <X11/Xlibint.h> - -#include "context.h" -#include "matrix.h" -#include "mmath.h" -#include "vbxform.h" - -#include "dri_glide.h" - -#include "tdfx_context.h" -#include "tdfx_render.h" -#include "tdfx_state.h" -#include "tdfx_texman.h" - - -GLboolean -XMesaInitDriver( __DRIscreenPrivate *sPriv ) -{ - int major, minor, patch; - char msg[1024]; - - if ( TDFX_DEBUG & DEBUG_VERBOSE_DRI ) { - fprintf( stderr, "%s( %p )\n", __FUNCTION__, sPriv ); - } - - /* Check the DRI version */ - if ( XF86DRIQueryVersion( sPriv->display, &major, &minor, &patch ) ) { - if ( major != 4 || - minor < 0 ) { - sprintf( msg, - "3dfx DRI driver expected DRI version 4.0.x " - "but got version %d.%d.%d", - major, minor, patch ); - __driMesaMessage( msg ); - return GL_FALSE; - } - } - - /* Check that the DDX driver version is compatible */ - if ( sPriv->ddxMajor != 1 || - sPriv->ddxMinor < 0 ) { - sprintf( msg, - "3dfx DRI driver expected DDX driver version 1.0.x " - "but got version %d.%d.%d", - sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch ); - __driMesaMessage( msg ); - return GL_FALSE; - } - - /* Check that the DRM driver version is compatible */ - if ( sPriv->drmMajor != 1 || - sPriv->drmMinor < 0 ) { - sprintf( msg, - "3dfx DRI driver expected DRM driver version 1.0.x " - "but got version %d.%d.%d", - sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch ); - __driMesaMessage( msg ); - return GL_FALSE; - } - - if ( !tdfxCreateScreen( sPriv ) ) { - tdfxDestroyScreen( sPriv ); - return GL_FALSE; - } - - return GL_TRUE; -} - - -void -XMesaResetDriver( __DRIscreenPrivate *sPriv ) -{ - if ( TDFX_DEBUG & DEBUG_VERBOSE_DRI ) { - fprintf( stderr, "%s( %p )\n", __FUNCTION__, sPriv ); - } - - tdfxDestroyScreen( sPriv ); -} - - -GLvisual * -XMesaCreateVisual( Display * dpy, - __DRIscreenPrivate *driScrnPriv, - const XVisualInfo *visinfo, - const __GLXvisualConfig *config ) -{ - /* Drivers may change the args to _mesa_create_visual() in order to - * setup special visuals. - */ - return _mesa_create_visual( config->rgba, - config->doubleBuffer, - config->stereo, - _mesa_bitcount( visinfo->red_mask ), - _mesa_bitcount( visinfo->green_mask ), - _mesa_bitcount( visinfo->blue_mask ), - config->alphaSize, - 0, /* index bits */ - config->depthSize, - config->stencilSize, - config->accumRedSize, - config->accumGreenSize, - config->accumBlueSize, - config->accumAlphaSize, - 0 /* num samples */ ); -} - - -GLboolean -XMesaCreateContext( Display *dpy, GLvisual *mesaVis, - __DRIcontextPrivate *driContextPriv ) -{ - if ( TDFX_DEBUG & DEBUG_VERBOSE_DRI ) { - fprintf( stderr, "%s( %p )\n", __FUNCTION__, driContextPriv ); - } - - return tdfxCreateContext( dpy, mesaVis, driContextPriv ); -} - - -void -XMesaDestroyContext( __DRIcontextPrivate *driContextPriv ) -{ - tdfxContextPtr fxMesa; - - if ( TDFX_DEBUG & DEBUG_VERBOSE_DRI ) { - fprintf( stderr, "%s( %p )\n", __FUNCTION__, driContextPriv ); - } - - fxMesa = (tdfxContextPtr) driContextPriv->driverPrivate; - tdfxDestroyContext( fxMesa ); - driContextPriv->driverPrivate = NULL; -} - - -GLframebuffer * -XMesaCreateWindowBuffer( Display *dpy, - __DRIscreenPrivate *driScrnPriv, - __DRIdrawablePrivate *driDrawPriv, - GLvisual *mesaVis ) -{ - return gl_create_framebuffer( mesaVis, - GL_FALSE, /* software depth buffer? */ - mesaVis->StencilBits > 0, - mesaVis->AccumRedBits > 0, - GL_FALSE /* software alpha channel? */ ); -} - - -GLframebuffer * -XMesaCreatePixmapBuffer( Display *dpy, - __DRIscreenPrivate *driScrnPriv, - __DRIdrawablePrivate *driDrawPriv, - GLvisual *mesaVis ) -{ -#if 0 - /* Different drivers may have different combinations of hardware and - * software ancillary buffers. - */ - return gl_create_framebuffer( mesaVis, - GL_FALSE, /* software depth buffer? */ - mesaVis->StencilBits > 0, - mesaVis->AccumRedBits > 0, - mesaVis->AlphaBits > 0 ); -#else - return NULL; /* not implemented yet */ -#endif -} - -void -XMesaSwapBuffers( __DRIdrawablePrivate *driDrawPriv ) -{ - GET_CURRENT_CONTEXT(ctx); - tdfxContextPtr fxMesa = 0; - - if ( TDFX_DEBUG & DEBUG_VERBOSE_DRI ) { - fprintf( stderr, "%s( %p )\n", __FUNCTION__, driDrawPriv ); - } - - if ( !driDrawPriv->mesaBuffer->Visual->DBflag ) - return; /* can't swap a single-buffered window */ - - /* If the current context's drawable matches the given drawable - * we have to do a glFinish (per the GLX spec). - */ - if ( ctx ) { - __DRIdrawablePrivate *curDrawPriv; - fxMesa = TDFX_CONTEXT(ctx); - curDrawPriv = fxMesa->driContext->driDrawablePriv; - - if ( curDrawPriv == driDrawPriv ) { - /* swapping window bound to current context, flush first */ - FLUSH_VB( ctx, "swap buffers" ); - LOCK_HARDWARE( fxMesa ); - } - else { - /* find the fxMesa context previously bound to the window */ - fxMesa = (tdfxContextPtr) driDrawPriv->driContextPriv->driverPrivate; - if (!fxMesa) - return; - LOCK_HARDWARE( fxMesa ); - fxMesa->Glide.grSstSelect( fxMesa->Glide.Board ); - fxMesa->Glide.grGlideSetState( (GrState *) fxMesa->Glide.State ); - } - } - -#ifdef STATS - { - int stalls; - static int prevStalls = 0; - - stalls = fxMesa->Glide.grFifoGetStalls(); - - fprintf( stderr, "%s:\n", __FUNCTION__ ); - if ( stalls != prevStalls ) { - fprintf( stderr, " %d stalls occurred\n", - stalls - prevStalls ); - prevStalls = stalls; - } - if ( fxMesa && fxMesa->texSwaps ) { - fprintf( stderr, " %d texture swaps occurred\n", - fxMesa->texSwaps ); - fxMesa->texSwaps = 0; - } - } -#endif - - if (fxMesa->scissoredClipRects) { - /* restore clip rects without scissor box */ - fxMesa->Glide.grDRIPosition( driDrawPriv->x, driDrawPriv->y, - driDrawPriv->w, driDrawPriv->h, - driDrawPriv->numClipRects, - driDrawPriv->pClipRects ); - } - - fxMesa->Glide.grDRIBufferSwap( fxMesa->Glide.SwapInterval ); - - if (fxMesa->scissoredClipRects) { - /* restore clip rects WITH scissor box */ - fxMesa->Glide.grDRIPosition( driDrawPriv->x, driDrawPriv->y, - driDrawPriv->w, driDrawPriv->h, - fxMesa->numClipRects, fxMesa->pClipRects ); - } - - -#if 0 - { - FxI32 result; - do { - result = FX_grGetInteger( FX_PENDING_BUFFERSWAPS ); - } while ( result > fxMesa->maxPendingSwapBuffers ); - } -#endif - - fxMesa->stats.swapBuffer++; - - if (ctx) { - if (ctx->DriverCtx != fxMesa) { - fxMesa = TDFX_CONTEXT(ctx); - fxMesa->Glide.grSstSelect( fxMesa->Glide.Board ); - fxMesa->Glide.grGlideSetState( (GrState *) fxMesa->Glide.State ); - } - UNLOCK_HARDWARE( fxMesa ); - } -} - - -GLboolean -XMesaUnbindContext( __DRIcontextPrivate *driContextPriv ) -{ - GET_CURRENT_CONTEXT(ctx); - - if ( TDFX_DEBUG & DEBUG_VERBOSE_DRI ) { - fprintf( stderr, "%s( %p )\n", __FUNCTION__, driContextPriv ); - } - - if ( driContextPriv && driContextPriv->mesaContext == ctx ) { - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - FX_grGlideGetState( fxMesa, (GrState *) fxMesa->Glide.State ); - } - return GL_TRUE; -} - - -GLboolean -XMesaMakeCurrent( __DRIcontextPrivate *driContextPriv, - __DRIdrawablePrivate *driDrawPriv, - __DRIdrawablePrivate *driReadPriv ) -{ - if ( TDFX_DEBUG & DEBUG_VERBOSE_DRI ) { - fprintf( stderr, "%s( %p )\n", __FUNCTION__, driContextPriv ); - } - - if ( driContextPriv ) { - tdfxContextPtr fxMesa = (tdfxContextPtr) driContextPriv->driverPrivate; - GLcontext *ctx = fxMesa->glCtx; - - if ( fxMesa->driDrawable != driDrawPriv ) { - fxMesa->driDrawable = driDrawPriv; - fxMesa->dirty = ~0; - } - - if ( !fxMesa->Glide.Initialized ) { - if ( !tdfxInitContext( driDrawPriv, fxMesa ) ) - return GL_FALSE; - - LOCK_HARDWARE( fxMesa ); - - /* FIXME: Force loading of window information */ - fxMesa->width = 0; - tdfxUpdateClipping(ctx); - tdfxUploadClipping(fxMesa); - - UNLOCK_HARDWARE( fxMesa ); - } else { - LOCK_HARDWARE( fxMesa ); - - fxMesa->Glide.grSstSelect( fxMesa->Glide.Board ); - fxMesa->Glide.grGlideSetState( fxMesa->Glide.State ); - - tdfxUpdateClipping(ctx); - tdfxUploadClipping(fxMesa); - - UNLOCK_HARDWARE( fxMesa ); - } - - assert( ctx == driContextPriv->mesaContext ); - - gl_make_current2( ctx, driDrawPriv->mesaBuffer, - driReadPriv->mesaBuffer ); - - if ( !ctx->Viewport.Width ) { - gl_Viewport( ctx, 0, 0, driDrawPriv->w, driDrawPriv->h ); - } - } else { - gl_make_current( 0, 0 ); - } - - return GL_TRUE; -} - - -GLboolean -XMesaOpenFullScreen(__DRIcontextPrivate *driContextPriv) -{ - if ( 0 ) - fprintf( stderr, "***** XMesaOpenFullScreen *****\n" ); -#if 0 /* When new glide3 calls exist */ - return (GLboolean)grDRISetupFullScreen( GL_TRUE ); -#else - return GL_TRUE; -#endif -} - - -GLboolean -XMesaCloseFullScreen(__DRIcontextPrivate *driContextPriv) -{ - if ( 0 ) - fprintf( stderr, "***** XMesaCloseFullScreen *****\n" ); -#if 0 /* When new glide3 calls exist */ - return (GLboolean)grDRISetupFullScreen( GL_FALSE ); -#else - return GL_TRUE; -#endif -} - - -/* Silence compiler warnings. - */ -extern void __driRegisterExtensions( void ); - -/* This function is called by libGL.so as soon as libGL.so is loaded. - * This is where we'd register new extension functions with the dispatcher. - */ -void __driRegisterExtensions( void ) -{ -#if 0 - /* Example. Also look in tdfx_dd.c for more details. */ - { - const int _gloffset_FooBarEXT = 555; /* just an example number! */ - if ( _glapi_add_entrypoint( "glFooBarEXT", _gloffset_FooBarEXT ) ) { - void *f = glXGetProcAddressARB( "glFooBarEXT" ); - assert( f ); - } - } -#endif -} - - -#endif |