diff options
author | jhartmann <jhartmann> | 2002-05-29 21:21:47 +0000 |
---|---|---|
committer | jhartmann <jhartmann> | 2002-05-29 21:21:47 +0000 |
commit | 63c06df02c54c715eaa77008e35387b4a7e041af (patch) | |
tree | 8e49ae4f48730fc773e38838ff900fc5e11d620c /xc/lib | |
parent | 4b5d3f1f775b6b9100c11017028ad6e2b20f4df3 (diff) |
Import Mesa 4.0 port of I830M/I845G 3D driver funded by 2d3d.
Import Lastest i810 ddx driver changes from XFree86 CVS to support the I845G.
Fixup warnings in I830M kernel driver.
-Jeff
Diffstat (limited to 'xc/lib')
33 files changed, 6673 insertions, 6431 deletions
diff --git a/xc/lib/GL/mesa/src/drv/i830/Imakefile b/xc/lib/GL/mesa/src/drv/i830/Imakefile index 926900c67..fa4474bba 100644 --- a/xc/lib/GL/mesa/src/drv/i830/Imakefile +++ b/xc/lib/GL/mesa/src/drv/i830/Imakefile @@ -33,8 +33,7 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/drv/i830/Imakefile,v 1.2 2002/02/23 00:45:50 DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES) $(MESA_ASM_DEFINES) INCLUDES = $(X_INCLUDES) $(MESA_INCLUDES) $(DRI_INCLUDES) - 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/i830/Imakefile.inc b/xc/lib/GL/mesa/src/drv/i830/Imakefile.inc index 86c425b53..9da00b91a 100644 --- a/xc/lib/GL/mesa/src/drv/i830/Imakefile.inc +++ b/xc/lib/GL/mesa/src/drv/i830/Imakefile.inc @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/drv/i830/Imakefile.inc,v 1.1 2001/10/04 18:28:21 alanh Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/drv/i830/Imakefile.inc,v 1.1 2001/03/23 19:18:40 dawes Exp $ #ifndef MesaDrvSrcDir #define MesaDrvSrcDir $(GLXLIBSRC)/mesa/src/drv @@ -17,84 +17,100 @@ ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL #if BuildXF86DRI DRI_DEFINES = GlxDefines - DRI_INCLUDES = -I$(GLXLIBSRC)/dri -I$(GLXLIBSRC)/glx \ - -I$(INCLUDESRC) -I$(INCLUDESRC)/GL \ - -I$(GLXLIBSRC)/mesa/dri \ + DRI_INCLUDES = -I$(GLXLIBSRC)/dri \ + -I$(GLXLIBSRC)/glx \ + -I$(INCLUDESRC) \ + -I$(INCLUDESRC)/GL \ + -I$(GLXLIBSRC)/dri \ -I$(SERVERSRC)/GL/dri \ -I$(XF86OSSRC) \ -I$(XF86DRIVERSRC)/i810 \ - -I$(GLXLIBSRC)/dri/drm + -I$(GLXLIBSRC)/dri/drm \ + -I$(GLXLIBSRC)/include #endif MESA_INCLUDES = -I$(MESASRCDIR)/src -I$(MESADRVSRCDIR)/common \ -I$(MESADRVSRCDIR)/i830 X_INCLUDES = -I$(XINCLUDESRC) -I$(EXTINCSRC) - I830SRCS = $(MESADRVI830BUILDDIR)i830_xmesa.c \ - $(MESADRVI830BUILDDIR)i830_dd.c \ - $(MESADRVI830BUILDDIR)i830_pipeline.c \ + I830SRCS = $(MESADRVI830BUILDDIR)i830_context.c \ + $(MESADRVI830BUILDDIR)i830_debug.c \ + $(MESADRVI830BUILDDIR)i830_ioctl.c \ + $(MESADRVI830BUILDDIR)i830_render.c \ + $(MESADRVI830BUILDDIR)i830_screen.c \ $(MESADRVI830BUILDDIR)i830_span.c \ $(MESADRVI830BUILDDIR)i830_state.c \ $(MESADRVI830BUILDDIR)i830_tex.c \ + $(MESADRVI830BUILDDIR)i830_texmem.c \ + $(MESADRVI830BUILDDIR)i830_texstate.c \ $(MESADRVI830BUILDDIR)i830_tris.c \ - $(MESADRVI830BUILDDIR)i830_vb.c \ - $(MESADRVI830BUILDDIR)i830_fastpath.c \ - $(MESADRVI830BUILDDIR)i830_ioctl.c + $(MESADRVI830BUILDDIR)i830_vb.c - I830OBJS = $(MESADRVI830BUILDDIR)i830_xmesa.o \ - $(MESADRVI830BUILDDIR)i830_dd.o \ - $(MESADRVI830BUILDDIR)i830_pipeline.o \ + I830OBJS = $(MESADRVI830BUILDDIR)i830_context.o \ + $(MESADRVI830BUILDDIR)i830_debug.o \ + $(MESADRVI830BUILDDIR)i830_ioctl.o \ + $(MESADRVI830BUILDDIR)i830_render.o \ + $(MESADRVI830BUILDDIR)i830_screen.o \ $(MESADRVI830BUILDDIR)i830_span.o \ $(MESADRVI830BUILDDIR)i830_state.o \ $(MESADRVI830BUILDDIR)i830_tex.o \ + $(MESADRVI830BUILDDIR)i830_texmem.o \ + $(MESADRVI830BUILDDIR)i830_texstate.o \ $(MESADRVI830BUILDDIR)i830_tris.o \ - $(MESADRVI830BUILDDIR)i830_vb.o \ - $(MESADRVI830BUILDDIR)i830_fastpath.o \ - $(MESADRVI830BUILDDIR)i830_ioctl.o + $(MESADRVI830BUILDDIR)i830_vb.o - I830UOBJS = $(MESADRVI830BUILDDIR)unshared/i830_xmesa.o \ - $(MESADRVI830BUILDDIR)unshared/i830_dd.o \ - $(MESADRVI830BUILDDIR)unshared/i830_pipeline.o \ + I830UOBJS = $(MESADRVI830BUILDDIR)unshared/i830_context.o \ + $(MESADRVI830BUILDDIR)unshared/i830_debug.o \ + $(MESADRVI830BUILDDIR)unshared/i830_ioctl.o \ + $(MESADRVI830BUILDDIR)unshared/i830_render.o \ + $(MESADRVI830BUILDDIR)unshared/i830_screen.o \ $(MESADRVI830BUILDDIR)unshared/i830_span.o \ $(MESADRVI830BUILDDIR)unshared/i830_state.o \ $(MESADRVI830BUILDDIR)unshared/i830_tex.o \ + $(MESADRVI830BUILDDIR)unshared/i830_texmem.o \ + $(MESADRVI830BUILDDIR)unshared/i830_texstate.o \ $(MESADRVI830BUILDDIR)unshared/i830_tris.o \ - $(MESADRVI830BUILDDIR)unshared/i830_vb.o \ - $(MESADRVI830BUILDDIR)unshared/i830_fastpath.o \ - $(MESADRVI830BUILDDIR)unshared/i830_ioctl.o + $(MESADRVI830BUILDDIR)unshared/i830_vb.o - I830DOBJS = $(MESADRVI830BUILDDIR)unshared/i830_xmesa.o \ - $(MESADRVI830BUILDDIR)unshared/i830_dd.o \ - $(MESADRVI830BUILDDIR)unshared/i830_pipeline.o \ - $(MESADRVI830BUILDDIR)unshared/i830_span.o \ - $(MESADRVI830BUILDDIR)unshared/i830_state.o \ - $(MESADRVI830BUILDDIR)unshared/i830_tex.o \ - $(MESADRVI830BUILDDIR)unshared/i830_tris.o \ - $(MESADRVI830BUILDDIR)unshared/i830_vb.o \ - $(MESADRVI830BUILDDIR)unshared/i830_fastpath.o \ - $(MESADRVI830BUILDDIR)unshared/i830_ioctl.o + I830DOBJS = $(MESADRVI830BUILDDIR)debugger/i830_context.o \ + $(MESADRVI830BUILDDIR)debugger/i830_debug.o \ + $(MESADRVI830BUILDDIR)debugger/i830_ioctl.o \ + $(MESADRVI830BUILDDIR)debugger/i830_render.o \ + $(MESADRVI830BUILDDIR)debugger/i830_screen.o \ + $(MESADRVI830BUILDDIR)debugger/i830_span.o \ + $(MESADRVI830BUILDDIR)debugger/i830_state.o \ + $(MESADRVI830BUILDDIR)debugger/i830_tex.o \ + $(MESADRVI830BUILDDIR)debugger/i830_texmem.o \ + $(MESADRVI830BUILDDIR)debugger/i830_texstate.o \ + $(MESADRVI830BUILDDIR)debugger/i830_tris.o \ + $(MESADRVI830BUILDDIR)debugger/i830_vb.o - I830POBJS = $(MESADRVI830BUILDDIR)unshared/i830_xmesa.o \ - $(MESADRVI830BUILDDIR)unshared/i830_dd.o \ - $(MESADRVI830BUILDDIR)unshared/i830_pipeline.o \ - $(MESADRVI830BUILDDIR)unshared/i830_span.o \ - $(MESADRVI830BUILDDIR)unshared/i830_state.o \ - $(MESADRVI830BUILDDIR)unshared/i830_tex.o \ - $(MESADRVI830BUILDDIR)unshared/i830_tris.o \ - $(MESADRVI830BUILDDIR)unshared/i830_vb.o \ - $(MESADRVI830BUILDDIR)unshared/i830_fastpath.o \ - $(MESADRVI830BUILDDIR)unshared/i830_ioctl.o + I830POBJS = $(MESADRVI830BUILDDIR)profiled/i830_context.o \ + $(MESADRVI830BUILDDIR)profiled/i830_debug.o \ + $(MESADRVI830BUILDDIR)profiled/i830_ioctl.o \ + $(MESADRVI830BUILDDIR)profiled/i830_render.o \ + $(MESADRVI830BUILDDIR)profiled/i830_screen.o \ + $(MESADRVI830BUILDDIR)profiled/i830_span.o \ + $(MESADRVI830BUILDDIR)profiled/i830_state.o \ + $(MESADRVI830BUILDDIR)profiled/i830_tex.o \ + $(MESADRVI830BUILDDIR)profiled/i830_texmem.o \ + $(MESADRVI830BUILDDIR)profiled/i830_texstate.o \ + $(MESADRVI830BUILDDIR)profiled/i830_tris.o \ + $(MESADRVI830BUILDDIR)profiled/i830_vb.o #ifdef NeedToLinkMesaSrc -LinkSourceFile(i830_xmesa.c, $(MESADRVSRCDIR)/i830) -LinkSourceFile(i830_dd.c, $(MESADRVSRCDIR)/i830) -LinkSourceFile(i830_pipeline.c, $(MESADRVSRCDIR)/i830) +LinkSourceFile(i830_context.c, $(MESADRVSRCDIR)/i830) +LinkSourceFile(i830_debug.c, $(MESADRVSRCDIR)/i830) +LinkSourceFile(i830_ioctl.c, $(MESADRVSRCDIR)/i830) +LinkSourceFile(i830_render.c, $(MESADRVSRCDIR)/i830) +LinkSourceFile(i830_screen.c, $(MESADRVSRCDIR)/i830) LinkSourceFile(i830_span.c, $(MESADRVSRCDIR)/i830) LinkSourceFile(i830_state.c, $(MESADRVSRCDIR)/i830) LinkSourceFile(i830_tex.c, $(MESADRVSRCDIR)/i830) +LinkSourceFile(i830_texmem.c, $(MESADRVSRCDIR)/i830) +LinkSourceFile(i830_texstate.c, $(MESADRVSRCDIR)/i830) LinkSourceFile(i830_tris.c, $(MESADRVSRCDIR)/i830) LinkSourceFile(i830_vb.c, $(MESADRVSRCDIR)/i830) -LinkSourceFile(i830_fastpath.c, $(MESADRVSRCDIR)/i830) -LinkSourceFile(i830_ioctl.c, $(MESADRVSRCDIR)/i830) #endif + diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_3d_reg.h b/xc/lib/GL/mesa/src/drv/i830/i830_3d_reg.h index 80721d344..2166a136d 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_3d_reg.h +++ b/xc/lib/GL/mesa/src/drv/i830/i830_3d_reg.h @@ -683,6 +683,11 @@ #define TEXCOORDFMT_4D 2 #define TEXCOORDFMT_1D 3 +/*New stuff picked up along the way */ + +#define MLC_LOD_BIAS_MASK ((1<<7)-1) + + /* STATE3D_VERTEX_TRANSFORM, p207 */ #define STATE3D_VERTEX_TRANS_CMD (CMD_3D|(0x1d<<24)|(0x8b<<16)|0) #define STATE3D_VERTEX_TRANS_MTX_CMD (CMD_3D|(0x1d<<24)|(0x8b<<16)|6) diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_context.c b/xc/lib/GL/mesa/src/drv/i830/i830_context.c new file mode 100644 index 000000000..e425fd949 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/i830/i830_context.c @@ -0,0 +1,474 @@ +/************************************************************************** + * + * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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$ */ + +/* + * Authors: + * Jeff Hartmann <jhartmann@2d3d.com> + * Graeme Fisher <graeme@2d3d.co.za> + * Abraham vd Merwe <abraham@2d3d.co.za> + * + * Heavily Based on I810 driver written by: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#include "glheader.h" +#include "context.h" +#include "matrix.h" +#include "simple_list.h" +#include "extensions.h" +#include "mem.h" + +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/tnl.h" +#include "array_cache/acache.h" + +#include "tnl/t_pipeline.h" + +#include "i830_screen.h" +#include "i830_dri.h" + +#include "i830_state.h" +#include "i830_tex.h" +#include "i830_span.h" +#include "i830_tris.h" +#include "i830_vb.h" +#include "i830_ioctl.h" + +#include <X11/Xlibint.h> +#include <stdio.h> + +/*************************************** + * Mesa's Driver Functions + ***************************************/ + +static const GLubyte *i830DDGetString( GLcontext *ctx, GLenum name ) +{ + switch (name) { + case GL_VENDOR: + return (GLubyte *)"2d3D, Inc"; + case GL_RENDERER: + return (GLubyte *)"Mesa DRI I830 20020528"; + default: + return 0; + } +} + +static void i830BufferSize(GLframebuffer *buffer, + GLuint *width, GLuint *height) +{ + GET_CURRENT_CONTEXT(ctx); + i830ContextPtr imesa = I830_CONTEXT(ctx); + /* Need to lock to make sure the driDrawable is uptodate. This + * information is used to resize Mesa's software buffers, so it has + * to be correct. + */ + LOCK_HARDWARE(imesa); + *width = imesa->driDrawable->w; + *height = imesa->driDrawable->h; + UNLOCK_HARDWARE(imesa); +} + +/* Enable all the extensions we need */ +static void i830InitExtensions( GLcontext *ctx ) +{ + _mesa_enable_imaging_extensions( ctx ); + _mesa_enable_extension( ctx, "GL_ARB_multitexture" ); + _mesa_enable_extension( ctx, "GL_ARB_texture_env_add" ); + _mesa_enable_extension( ctx, "GL_EXT_texture_env_add" ); + _mesa_enable_extension( ctx, "GL_ARB_texture_env_combine" ); + _mesa_enable_extension( ctx, "GL_EXT_texture_env_combine" ); + _mesa_enable_extension( ctx, "GL_EXT_blend_color" ); + _mesa_enable_extension( ctx, "GL_EXT_blend_minmax" ); + _mesa_enable_extension( ctx, "GL_EXT_blend_subtract" ); + _mesa_enable_extension( ctx, "GL_EXT_blend_func_separate" ); + _mesa_enable_extension( ctx, "GL_EXT_texture_lod_bias" ); + + /* Leave this for later */ +#if 0 + _mesa_enable_extension( ctx, "GL_EXT_stencil_wrap" ); +#endif +} + +extern const struct gl_pipeline_stage _i830_render_stage; + +static const struct gl_pipeline_stage *i830_pipeline[] = { + &_tnl_vertex_transform_stage, + &_tnl_normal_transform_stage, + &_tnl_lighting_stage, + &_tnl_fog_coordinate_stage, + &_tnl_texgen_stage, + &_tnl_texture_transform_stage, + /* REMOVE: point attenuation stage */ +#if 1 + &_i830_render_stage, /* ADD: unclipped rastersetup-to-dma */ +#endif + &_tnl_render_stage, + 0, +}; + +GLboolean i830CreateContext( Display *dpy, const __GLcontextModes *mesaVis, + __DRIcontextPrivate *driContextPriv, + void *sharedContextPrivate) +{ + GLcontext *ctx , *shareCtx; + i830ContextPtr imesa; + __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + i830ScreenPrivate *i830Screen = (i830ScreenPrivate *)sPriv->private; + I830SAREAPtr saPriv=(I830SAREAPtr) + (((GLubyte *)sPriv->pSAREA)+i830Screen->sarea_priv_offset); + + /* Allocate i830 context */ + imesa = (i830ContextPtr) CALLOC_STRUCT(i830_context_t); + if (!imesa) return GL_FALSE; + + /* Allocate the Mesa context */ + if (sharedContextPrivate) + shareCtx = ((i830ContextPtr) sharedContextPrivate)->glCtx; + else + shareCtx = NULL; + + imesa->glCtx = _mesa_create_context(mesaVis, shareCtx, imesa, GL_TRUE); + if (!imesa->glCtx) { + FREE(imesa); + return GL_FALSE; + } + driContextPriv->driverPrivate = imesa; + + /* Set the maximum texture size small enough that we can guarentee + * that both texture units can bind a maximal texture and have them + * in memory at once. + */ + ctx = imesa->glCtx; + if (i830Screen->textureSize < 2*1024*1024) { + ctx->Const.MaxTextureLevels = 9; + } else if (i830Screen->textureSize < 8*1024*1024) { + ctx->Const.MaxTextureLevels = 10; + } else { + ctx->Const.MaxTextureLevels = 11; + } + ctx->Const.MaxTextureUnits = 2; + + ctx->Const.MinLineWidth = 1.0; + ctx->Const.MinLineWidthAA = 1.0; + ctx->Const.MaxLineWidth = 3.0; + ctx->Const.MaxLineWidthAA = 3.0; + ctx->Const.LineWidthGranularity = 1.0; + + ctx->Const.MinPointSize = 1.0; + ctx->Const.MinPointSizeAA = 1.0; + ctx->Const.MaxPointSize = 255.0; + ctx->Const.MaxPointSizeAA = 3.0; + ctx->Const.PointSizeGranularity = 1.0; + + ctx->Driver.GetBufferSize = i830BufferSize; + ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; + ctx->Driver.GetString = i830DDGetString; + + /* Who owns who? */ + ctx->DriverCtx = (void *) imesa; + imesa->glCtx = ctx; + + /* Initialize the software rasterizer and helper modules. */ + _swrast_CreateContext( ctx ); + _ac_CreateContext( ctx ); + _tnl_CreateContext( ctx ); + _swsetup_CreateContext( ctx ); + + /* Install the customized pipeline: */ + _tnl_destroy_pipeline( ctx ); + _tnl_install_pipeline( ctx, i830_pipeline ); + + /* Configure swrast to match hardware characteristics: */ + _swrast_allow_pixel_fog( ctx, GL_FALSE ); + _swrast_allow_vertex_fog( ctx, GL_TRUE ); + + /* Dri stuff */ + imesa->display = dpy; + imesa->hHWContext = driContextPriv->hHWContext; + imesa->driFd = sPriv->fd; + imesa->driHwLock = &sPriv->pSAREA->lock; + imesa->vertex_format = 0; + + imesa->hw_stencil = mesaVis->stencilBits && mesaVis->depthBits == 24; + + switch(mesaVis->depthBits) { + case 16: + imesa->depth_scale = 1.0/0xffff; + imesa->depth_clear_mask = ~0; + imesa->ClearDepth = 0xffff; + break; + case 24: + imesa->depth_scale = 1.0/0xffffff; + imesa->depth_clear_mask = 0x00ffffff; + imesa->stencil_clear_mask = 0xff000000; + imesa->ClearDepth = 0x00ffffff; + break; + case 32: /* Not supported */ + default: + break; + } + /* Completely disable stenciling for now, there are some serious issues + * with stencil. + */ +#if 1 + imesa->hw_stencil = 0; +#endif + + imesa->i830Screen = i830Screen; + imesa->driScreen = sPriv; + imesa->sarea = saPriv; + imesa->glBuffer = NULL; + + imesa->texHeap = mmInit( 0, i830Screen->textureSize ); + imesa->RenderIndex = ~0; + imesa->dirty = ~0; + imesa->upload_cliprects = GL_TRUE; + + make_empty_list(&imesa->TexObjList); + make_empty_list(&imesa->SwappedOut); + + imesa->CurrentTexObj[0] = 0; + imesa->CurrentTexObj[1] = 0; + + _math_matrix_ctr (&imesa->ViewportMatrix); + + + i830InitExtensions (ctx); + i830DDInitStateFuncs( ctx ); + i830DDInitTextureFuncs( ctx ); + i830InitTriFuncs (ctx); + i830DDInitSpanFuncs( ctx ); + i830DDInitIoctlFuncs( ctx ); + i830InitVB (ctx); + i830DDInitState (ctx); + + return GL_TRUE; +} + +void i830DestroyContext(__DRIcontextPrivate *driContextPriv) +{ + i830ContextPtr imesa = (i830ContextPtr) driContextPriv->driverPrivate; + + assert(imesa); /* should never be null */ + if (imesa) { + _swsetup_DestroyContext (imesa->glCtx); + _tnl_DestroyContext (imesa->glCtx); + _ac_DestroyContext (imesa->glCtx); + _swrast_DestroyContext (imesa->glCtx); + + i830FreeVB (imesa->glCtx); + + /* free the Mesa context */ + imesa->glCtx->DriverCtx = NULL; + _mesa_destroy_context(imesa->glCtx); + + Xfree (imesa); + } +} + +void i830XMesaSetFrontClipRects( i830ContextPtr imesa ) +{ + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + + imesa->numClipRects = dPriv->numClipRects; + imesa->pClipRects = dPriv->pClipRects; + imesa->drawX = dPriv->x; + imesa->drawY = dPriv->y; + + i830EmitDrawingRectangle( imesa ); + imesa->upload_cliprects = GL_TRUE; +} + +void i830XMesaSetBackClipRects( i830ContextPtr imesa ) +{ + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + + if (dPriv->numBackClipRects == 0) { + imesa->numClipRects = dPriv->numClipRects; + imesa->pClipRects = dPriv->pClipRects; + imesa->drawX = dPriv->x; + imesa->drawY = dPriv->y; + } else { + imesa->numClipRects = dPriv->numBackClipRects; + imesa->pClipRects = dPriv->pBackClipRects; + imesa->drawX = dPriv->backX; + imesa->drawY = dPriv->backY; + } + + i830EmitDrawingRectangle( imesa ); + imesa->upload_cliprects = GL_TRUE; +} + +static void i830XMesaWindowMoved( i830ContextPtr imesa ) +{ + switch (imesa->glCtx->Color.DriverDrawBuffer) { + case GL_FRONT_LEFT: + i830XMesaSetFrontClipRects( imesa ); + break; + case GL_BACK_LEFT: + i830XMesaSetBackClipRects( imesa ); + break; + default: + break; + } +} + +GLboolean i830UnbindContext(__DRIcontextPrivate *driContextPriv) +{ + i830ContextPtr imesa = (i830ContextPtr) driContextPriv->driverPrivate; + if (imesa) { + /* Might want to change this so texblend isn't always updated */ + imesa->dirty = (I830_UPLOAD_CTX | + I830_UPLOAD_BUFFERS | + I830_UPLOAD_TEXBLEND0 | + I830_UPLOAD_TEXBLEND1); + + if (imesa->CurrentTexObj[0]) imesa->dirty |= I830_UPLOAD_TEX0; + if (imesa->CurrentTexObj[1]) imesa->dirty |= I830_UPLOAD_TEX1; + } + return GL_TRUE; +} + +GLboolean i830MakeCurrent(__DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv) +{ + + if (driContextPriv) { + i830ContextPtr imesa = (i830ContextPtr) driContextPriv->driverPrivate; + + _mesa_make_current2(imesa->glCtx, + (GLframebuffer *) driDrawPriv->driverPrivate, + (GLframebuffer *) driReadPriv->driverPrivate); + /* Shouldn't the readbuffer be stored also? */ + imesa->driDrawable = driDrawPriv; + + /* Are these necessary? */ + i830XMesaWindowMoved( imesa ); + if (!imesa->glCtx->Viewport.Width) + _mesa_set_viewport(imesa->glCtx, 0, 0, + driDrawPriv->w, driDrawPriv->h); + } else { + _mesa_make_current(0,0); + } + + return GL_TRUE; +} + +void i830GetLock( i830ContextPtr imesa, GLuint flags ) +{ + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + __DRIscreenPrivate *sPriv = imesa->driScreen; + I830SAREAPtr sarea = imesa->sarea; + int me = imesa->hHWContext; + + drmGetLock(imesa->driFd, imesa->hHWContext, flags); + + /* If the window moved, may need to set a new cliprect now. + * + * NOTE: This releases and regains the hw lock, so all state + * checking must be done *after* this call: + */ + DRI_VALIDATE_DRAWABLE_INFO(imesa->display, sPriv, dPriv); + + /* If we lost context, need to dump all registers to hardware. + * Note that we don't care about 2d contexts, even if they perform + * accelerated commands, so the DRI locking in the X server is even + * more broken than usual. + */ + + if (sarea->ctxOwner != me) { + imesa->upload_cliprects = GL_TRUE; + imesa->dirty |= (I830_UPLOAD_CTX | + I830_UPLOAD_BUFFERS); + + if(imesa->CurrentTexObj[0]) imesa->dirty |= I830_UPLOAD_TEX0; + if(imesa->CurrentTexObj[1]) imesa->dirty |= I830_UPLOAD_TEX1; + if(imesa->TexBlendWordsUsed[0]) imesa->dirty |= I830_UPLOAD_TEXBLEND0; + if(imesa->TexBlendWordsUsed[1]) imesa->dirty |= I830_UPLOAD_TEXBLEND1; + + sarea->ctxOwner = me; + } + + /* Shared texture managment - if another client has played with + * texture space, figure out which if any of our textures have been + * ejected, and update our global LRU. + */ + if (sarea->texAge != imesa->texAge) { + int sz = 1 << (imesa->i830Screen->logTextureGranularity); + int idx, nr = 0; + + /* Have to go right round from the back to ensure stuff ends up + * LRU in our local list... + */ + for (idx = sarea->texList[I830_NR_TEX_REGIONS].prev ; + idx != I830_NR_TEX_REGIONS && nr < I830_NR_TEX_REGIONS ; + idx = sarea->texList[idx].prev, nr++) { + if (sarea->texList[idx].age > imesa->texAge) + i830TexturesGone(imesa, idx * sz, sz, sarea->texList[idx].in_use); + } + + if (nr == I830_NR_TEX_REGIONS) { + i830TexturesGone(imesa, 0, imesa->i830Screen->textureSize, 0); + i830ResetGlobalLRU( imesa ); + } + + imesa->texAge = sarea->texAge; + } + + if (imesa->lastStamp != dPriv->lastStamp) { + i830XMesaWindowMoved( imesa ); + imesa->lastStamp = dPriv->lastStamp; + } + + sarea->last_quiescent = -1; /* just kill it for now */ +} + +void i830SwapBuffers(Display *dpy, void *drawablePrivate) +{ + __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate; + + if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { + i830ContextPtr imesa; + GLcontext *ctx; + imesa = (i830ContextPtr) dPriv->driContextPriv->driverPrivate; + ctx = imesa->glCtx; + if (ctx->Visual.doubleBufferMode) { + _mesa_swapbuffers( ctx ); /* flush pending rendering comands */ + if ( imesa->doPageFlip ) { + i830PageFlip( dPriv ); + } else { + i830CopyBuffer( dPriv ); + } + } + } else { + /* XXX this shouldn't be an error but we can't handle it for now */ + _mesa_problem(NULL, "i830SwapBuffers: drawable has no context!\n"); + } +} diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_context.h b/xc/lib/GL/mesa/src/drv/i830/i830_context.h new file mode 100644 index 000000000..516e0047b --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/i830/i830_context.h @@ -0,0 +1,267 @@ +/* + * GLX Hardware Device Driver for Intel i830 + * 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"), + * 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 + * 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. + * + */ + +/* Adapted for use in the I830M driver: + * Jeff Hartmann <jhartmann@2d3d.com> + */ +/* $XFree86$ */ + +#ifndef I830CONTEXT_INC +#define I830CONTEXT_INC + +typedef struct i830_context_t i830Context; +typedef struct i830_context_t *i830ContextPtr; +typedef struct i830_texture_object_t *i830TextureObjectPtr; + + +#include "mtypes.h" +#include "drm.h" +#include "mm.h" + +#include "i830_screen.h" +#include "i830_tex.h" +#include "i830_drv.h" + +#define TAG(x) i830##x +#include "tnl_dd/t_dd_vertex.h" +#undef TAG + + +typedef void (*i830_tri_func)(i830ContextPtr, i830Vertex *, i830Vertex *, + i830Vertex *); +typedef void (*i830_line_func)(i830ContextPtr, i830Vertex *, i830Vertex *); +typedef void (*i830_point_func)(i830ContextPtr, i830Vertex *); + +#define I830_FALLBACK_TEXTURE 0x1 +#define I830_FALLBACK_DRAW_BUFFER 0x2 +#define I830_FALLBACK_READ_BUFFER 0x4 +#define I830_FALLBACK_COLORMASK 0x8 +#define I830_FALLBACK_SPECULAR 0x20 +#define I830_FALLBACK_LOGICOP 0x40 +#define I830_FALLBACK_RENDERMODE 0x80 +#define I830_FALLBACK_STENCIL 0x100 +#define I830_FALLBACK_BLEND_EQ 0x200 +#define I830_FALLBACK_BLEND_FUNC 0x400 +#define I830_FALLBACK_STIPPLE 0x800 + +struct i830_context_t +{ + GLint refcount; + GLcontext *glCtx; + + /*From I830 stuff*/ + int TextureMode; + GLuint renderindex; + GLuint TexBlendWordsUsed[I830_TEXBLEND_COUNT]; + GLuint TexBlend[I830_TEXBLEND_COUNT][I830_TEXBLEND_SIZE]; + GLuint Init_TexBlend[I830_TEXBLEND_COUNT][I830_TEXBLEND_SIZE]; + GLuint Init_TexBlendWordsUsed[I830_TEXBLEND_COUNT]; + GLuint Init_TexBlendColorPipeNum[I830_TEXBLEND_COUNT]; + GLuint TexBlendColorPipeNum[I830_TEXBLEND_COUNT]; + GLuint Init_BufferSetup[I830_DEST_SETUP_SIZE]; + + GLenum palette_format; + GLuint palette[256]; + + + GLuint Init_Setup[I830_CTX_SETUP_SIZE]; + GLuint vertex_prim; + drmBufPtr vertex_dma_buffer; + + GLboolean mask_red; + GLboolean mask_green; + GLboolean mask_blue; + GLboolean mask_alpha; + + GLboolean clear_red; + GLboolean clear_green; + GLboolean clear_blue; + GLboolean clear_alpha; + + GLfloat depth_scale; + int depth_clear_mask; + int stencil_clear_mask; + int ClearDepth; + int hw_stencil; + + GLuint MonoColor; + + GLuint LastTexEnabled; + GLuint TexEnabledMask; + + /* Textures + */ + i830TextureObjectPtr CurrentTexObj[2]; + struct i830_texture_object_t TexObjList; + struct i830_texture_object_t SwappedOut; + memHeap_t *texHeap; + + /* Bit flag to keep track of fallbacks. + */ + GLuint Fallback; + + /* Temporaries for translating away float colors: + */ + struct gl_client_array UbyteColor; + struct gl_client_array UbyteSecondaryColor; + + /* State for i830vb.c and i830tris.c. + */ + GLuint new_state; /* _NEW_* flags */ + GLuint SetupNewInputs; + GLuint SetupIndex; + GLuint RenderIndex; + GLmatrix ViewportMatrix; + GLenum render_primitive; + GLenum reduced_primitive; + GLuint hw_primitive; + GLuint vertex_format; + char *verts; + + drmBufPtr vertex_buffer; + char *vertex_addr; + GLuint vertex_low; + GLuint vertex_high; + GLuint vertex_last_prim; + + GLboolean upload_cliprects; + + + /* Fallback rasterization functions + */ + i830_point_func draw_point; + i830_line_func draw_line; + i830_tri_func draw_tri; + + /* Hardware state + */ + GLuint dirty; /* I810_UPLOAD_* */ + GLuint Setup[I830_CTX_SETUP_SIZE]; + GLuint BufferSetup[I830_DEST_SETUP_SIZE]; + int vertex_size; + int vertex_stride_shift; + GLint lastStamp; + GLboolean stipple_in_hw; + + GLenum TexEnvImageFmt[2]; + + /* State which can't be computed completely on the fly: + */ + GLuint LcsCullMode; + GLuint LcsLineWidth; + GLuint LcsPointSize; + + /* Funny mesa mirrors + */ + GLuint ClearColor; + + /* DRI stuff + */ + GLuint needClip; + GLframebuffer *glBuffer; + GLboolean doPageFlip; + + /* These refer to the current draw (front vs. back) buffer: + */ + char *drawMap; /* draw buffer address in virtual mem */ + char *readMap; + int drawX; /* origin of drawable in draw buffer */ + int drawY; + GLuint numClipRects; /* cliprects for that buffer */ + XF86DRIClipRectPtr pClipRects; + + int lastSwap; + int texAge; + int ctxAge; + int dirtyAge; + + GLboolean scissor; + XF86DRIClipRectRec draw_rect; + XF86DRIClipRectRec scissor_rect; + + drmContext hHWContext; + drmLock *driHwLock; + int driFd; + Display *display; + + __DRIdrawablePrivate *driDrawable; + __DRIscreenPrivate *driScreen; + i830ScreenPrivate *i830Screen; + I830SAREAPtr sarea; +}; + + +#define I830_TEX_UNIT_ENABLED(unit) (1<<unit) +#define VALID_I830_TEXTURE_OBJECT(tobj) (tobj) + +#define I830_CONTEXT(ctx) ((i830ContextPtr)(ctx->DriverCtx)) +#define I830_DRIVER_DATA(vb) ((i830VertexBufferPtr)((vb)->driver_data)) +#define GET_DISPATCH_AGE(imesa) imesa->sarea->last_dispatch +#define GET_ENQUEUE_AGE(imesa) imesa->sarea->last_enqueue + + +/* Lock the hardware and validate our state. + */ +#define LOCK_HARDWARE( imesa ) \ +do { \ + char __ret=0; \ + DRM_CAS(imesa->driHwLock, imesa->hHWContext, \ + (DRM_LOCK_HELD|imesa->hHWContext), __ret); \ + if (__ret) \ + i830GetLock( imesa, 0 ); \ +}while (0) + + + /* Unlock the hardware using the global current context + */ +#define UNLOCK_HARDWARE(imesa) \ + DRM_UNLOCK(imesa->driFd, imesa->driHwLock, imesa->hHWContext); + + + /* This is the wrong way to do it, I'm sure. Otherwise the drm + * bitches that I've already got the heavyweight lock. At worst, + * this is 3 ioctls. The best solution probably only gets me down + * to 2 ioctls in the worst case. + */ +#define LOCK_HARDWARE_QUIESCENT( imesa ) do { \ + LOCK_HARDWARE( imesa ); \ + i830RegetLockQuiescent( imesa ); \ +} while(0) + + + +extern void i830GetLock(i830ContextPtr imesa, GLuint flags); +extern void i830EmitHwStateLocked(i830ContextPtr imesa); +extern void i830EmitDrawingRectangle(i830ContextPtr imesa); +extern void i830XMesaSetBackClipRects(i830ContextPtr imesa); +extern void i830XMesaSetFrontClipRects(i830ContextPtr imesa); +extern void i830DDExtensionsInit(GLcontext *ctx); +extern void i830DDInitDriverFuncs(GLcontext *ctx); +extern void i830DDUpdateHwState(GLcontext *ctx); + +#define SUBPIXEL_X 0.125 +#define SUBPIXEL_Y 0.125 + +#endif + diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_dd.c b/xc/lib/GL/mesa/src/drv/i830/i830_dd.c deleted file mode 100644 index 7b33694bc..000000000 --- a/xc/lib/GL/mesa/src/drv/i830/i830_dd.c +++ /dev/null @@ -1,159 +0,0 @@ -/************************************************************************** - -Copyright 2001 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 -on the rights to use, copy, modify, merge, publish, distribute, sub -license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL -ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS 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/i830/i830_dd.c,v 1.1 2001/10/04 18:28:21 alanh Exp $ */ - -/* - * Author: - * Jeff Hartmann <jhartmann@valinux.com> - * - * Heavily based on the I810 driver, which was written by: - * Keith Whitwell <keithw@valinux.com> - */ - -#include "types.h" -#include "vbrender.h" - -#include <stdio.h> - -#include "mm.h" -#include "extensions.h" -#include "vb.h" -#include "dd.h" - -#include "i830_drv.h" -#include "i830_ioctl.h" - -extern int xf86VTSema; - - -/*************************************** - * Mesa's Driver Functions - ***************************************/ - - -static const GLubyte *i830DDGetString( GLcontext *ctx, GLenum name ) -{ - switch (name) { - case GL_VENDOR: - return (GLubyte *)"VA Linux Systems"; - case GL_RENDERER: - return (GLubyte *)"Mesa DRI I830 20020221"; - default: - return 0; - } -} - -static GLint i830GetParameteri(const GLcontext *ctx, GLint param) -{ - switch (param) { - case DD_HAVE_HARDWARE_FOG: - return 1; - default: - return 0; - } -} - - - -static void i830BufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height) -{ - GET_CURRENT_CONTEXT(ctx); - i830ContextPtr imesa = I830_CONTEXT(ctx); - - /* Need to lock to make sure the driDrawable is uptodate. This - * information is used to resize Mesa's software buffers, so it has - * to be correct. - */ - LOCK_HARDWARE(imesa); - *width = imesa->driDrawable->w; - *height = imesa->driDrawable->h; - UNLOCK_HARDWARE(imesa); -} - - - - -void i830DDExtensionsInit( GLcontext *ctx ) -{ - gl_extensions_enable( ctx, "GL_EXT_blend_color" ); - gl_extensions_enable( ctx, "GL_EXT_blend_minmax" ); - gl_extensions_enable( ctx, "GL_EXT_blend_subtract" ); - gl_extensions_enable( ctx, "GL_EXT_blend_logic_op" ); - - gl_extensions_enable( ctx, "GL_EXT_blend_func_separate" ); - gl_extensions_enable( ctx, "GL_ARB_texture_env_add" ); - gl_extensions_enable( ctx, "GL_EXT_texture_env_add" ); - gl_extensions_enable( ctx, "GL_EXT_texture_env_combine" ); - -#if 0 - /* These need a little work, the code is there, but some applications - * don't render correctly. - */ - - gl_extensions_enable( ctx, "GL_EXT_shared_texture_palette" ); - gl_extensions_enable( ctx, "GL_EXT_paletted_texture" ); -#else - gl_extensions_disable( ctx, "GL_EXT_shared_texture_palette" ); - gl_extensions_disable( ctx, "GL_EXT_paletted_texture" ); -#endif - - /* This should be easy to add */ - gl_extensions_disable( ctx, "GL_EXT_texture_lod_bias" ); - - /* Planned extensions */ - gl_extensions_disable( ctx, "GL_ARB_texture_compression" ); - gl_extensions_disable( ctx, "GL_ARB_texture_cube_map" ); - - /* we don't support point parameters in hardware yet */ - gl_extensions_disable( ctx, "GL_EXT_point_parameters" ); - - /* The imaging subset of 1.2 isn't supported by any mesa driver. - */ - gl_extensions_disable( ctx, "ARB_imaging" ); - gl_extensions_disable( ctx, "GL_EXT_convolution" ); - gl_extensions_disable( ctx, "GL_MESA_resize_buffers" ); - gl_extensions_disable( ctx, "GL_SGIX_pixel_texture" ); - gl_extensions_disable( ctx, "GL_SGI_color_matrix" ); - gl_extensions_disable( ctx, "GL_SGI_color_table" ); -} - - - - -void i830DDInitDriverFuncs( GLcontext *ctx ) -{ - ctx->Driver.GetBufferSize = i830BufferSize; - ctx->Driver.GetString = i830DDGetString; - ctx->Driver.GetParameteri = i830GetParameteri; - ctx->Driver.RegisterVB = i830DDRegisterVB; - ctx->Driver.UnregisterVB = i830DDUnregisterVB; - ctx->Driver.Clear = i830Clear; - - - ctx->Driver.BuildPrecalcPipeline = i830DDBuildPrecalcPipeline; -} diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_debug.c b/xc/lib/GL/mesa/src/drv/i830/i830_debug.c new file mode 100644 index 000000000..94fc38a90 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/i830/i830_debug.c @@ -0,0 +1,366 @@ +/************************************************************************** + +Copyright 2001 2d3d Inc., Delray Beach, FL + +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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS 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$ */ + +/* + * Author: + * Jeff Hartmann <jhartmann@2d3d.com> + */ +#include <stdio.h> +#include <unistd.h> + +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "enums.h" +#include "dd.h" + +#include "mm.h" + +#include "i830_screen.h" +#include "i830_dri.h" + +#include "i830_context.h" +#include "i830_state.h" +#include "i830_tex.h" +#include "i830_vb.h" +#include "i830_tris.h" +#include "i830_ioctl.h" +#include "i830_debug.h" + +#include "swrast/swrast.h" +#include "array_cache/acache.h" +#include "tnl/tnl.h" +#include "swrast_setup/swrast_setup.h" + +#include "tnl/t_pipeline.h" + + +#define TINY_VERTEX_FORMAT (STATE3D_VERTEX_FORMAT_CMD | \ + VRTX_TEX_COORD_COUNT(0) | \ + VRTX_HAS_DIFFUSE | \ + VRTX_HAS_XYZ) + +#define NOTEX_VERTEX_FORMAT (STATE3D_VERTEX_FORMAT_CMD | \ + VRTX_TEX_COORD_COUNT(0) | \ + VRTX_HAS_DIFFUSE | \ + VRTX_HAS_SPEC | \ + VRTX_HAS_XYZW) + +#define TEX0_VERTEX_FORMAT (STATE3D_VERTEX_FORMAT_CMD | \ + VRTX_TEX_COORD_COUNT(1) | \ + VRTX_HAS_DIFFUSE | \ + VRTX_HAS_SPEC | \ + VRTX_HAS_XYZW) + +#define TEX1_VERTEX_FORMAT (STATE3D_VERTEX_FORMAT_CMD | \ + VRTX_TEX_COORD_COUNT(2) | \ + VRTX_HAS_DIFFUSE | \ + VRTX_HAS_SPEC | \ + VRTX_HAS_XYZW) + +#define PROJ_VF2 (STATE3D_VERTEX_FORMAT_2_CMD | \ + VRTX_TEX_SET_0_FMT(TEXCOORDFMT_3D) | \ + VRTX_TEX_SET_1_FMT(TEXCOORDFMT_3D) | \ + VRTX_TEX_SET_2_FMT(TEXCOORDFMT_3D) | \ + VRTX_TEX_SET_3_FMT(TEXCOORDFMT_3D)) + +#define NON_PROJ_VF2 (STATE3D_VERTEX_FORMAT_2_CMD | \ + VRTX_TEX_SET_0_FMT(TEXCOORDFMT_2D) | \ + VRTX_TEX_SET_1_FMT(TEXCOORDFMT_2D) | \ + VRTX_TEX_SET_2_FMT(TEXCOORDFMT_2D) | \ + VRTX_TEX_SET_3_FMT(TEXCOORDFMT_2D)) + +void i830DumpContextState( i830ContextPtr imesa ) +{ + GLuint *Context = imesa->Setup; + + fprintf(stderr, "%s\n", __FUNCTION__); + fprintf(stderr, "STATE1 : 0x%08x\n", Context[I830_CTXREG_STATE1]); + fprintf(stderr, "STATE2 : 0x%08x\n", Context[I830_CTXREG_STATE2]); + fprintf(stderr, "STATE3 : 0x%08x\n", Context[I830_CTXREG_STATE3]); + fprintf(stderr, "STATE4 : 0x%08x\n", Context[I830_CTXREG_STATE4]); + fprintf(stderr, "STATE5 : 0x%08x\n", Context[I830_CTXREG_STATE5]); + fprintf(stderr, "IALPHAB : 0x%08x\n", Context[I830_CTXREG_IALPHAB]); + fprintf(stderr, "STENCILTST : 0x%08x\n", Context[I830_CTXREG_STENCILTST]); + fprintf(stderr, "ENABLES_1 : 0x%08x\n", Context[I830_CTXREG_ENABLES_1]); + fprintf(stderr, "ENABLES_2 : 0x%08x\n", Context[I830_CTXREG_ENABLES_2]); + fprintf(stderr, "AA : 0x%08x\n", Context[I830_CTXREG_AA]); + fprintf(stderr, "FOGCOLOR : 0x%08x\n", Context[I830_CTXREG_FOGCOLOR]); + fprintf(stderr, "BCOLOR0 : 0x%08x\n", Context[I830_CTXREG_BLENDCOLR0]); + fprintf(stderr, "BCOLOR : 0x%08x\n", Context[I830_CTXREG_BLENDCOLR]); + fprintf(stderr, "VF : 0x%08x\n", Context[I830_CTXREG_VF]); + fprintf(stderr, "VF2 : 0x%08x\n", Context[I830_CTXREG_VF2]); + fprintf(stderr, "MCSB0 : 0x%08x\n", Context[I830_CTXREG_MCSB0]); + fprintf(stderr, "MCSB1 : 0x%08x\n", Context[I830_CTXREG_MCSB1]); +} + +void i830DumpBufferState( i830ContextPtr imesa ) +{ + GLuint *Buffer = imesa->BufferSetup; + + fprintf(stderr, "%s\n", __FUNCTION__); + fprintf(stderr, "CBUFADDR : 0x%08x\n", Buffer[I830_DESTREG_CBUFADDR]); + fprintf(stderr, "DBUFADDR : 0x%08x\n", Buffer[I830_DESTREG_DBUFADDR]); + fprintf(stderr, "DV0 : 0x%08x\n", Buffer[I830_DESTREG_DV0]); + fprintf(stderr, "DV1 : 0x%08x\n", Buffer[I830_DESTREG_DV1]); + fprintf(stderr, "SENABLE : 0x%08x\n", Buffer[I830_DESTREG_SENABLE]); + fprintf(stderr, "SR0 : 0x%08x\n", Buffer[I830_DESTREG_SR0]); + fprintf(stderr, "SR1 : 0x%08x\n", Buffer[I830_DESTREG_SR1]); + fprintf(stderr, "SR2 : 0x%08x\n", Buffer[I830_DESTREG_SR2]); + fprintf(stderr, "DR0 : 0x%08x\n", Buffer[I830_DESTREG_DR0]); + fprintf(stderr, "DR1 : 0x%08x\n", Buffer[I830_DESTREG_DR1]); + fprintf(stderr, "DR2 : 0x%08x\n", Buffer[I830_DESTREG_DR2]); + fprintf(stderr, "DR3 : 0x%08x\n", Buffer[I830_DESTREG_DR3]); + fprintf(stderr, "DR4 : 0x%08x\n", Buffer[I830_DESTREG_DR4]); +} + +void i830DumpTextureState( i830ContextPtr imesa, int unit ) +{ + i830TextureObjectPtr t = imesa->CurrentTexObj[unit]; + + if(t) { + fprintf(stderr, "%s : unit %d\n", __FUNCTION__, unit); + fprintf(stderr, "MI0 : 0x%08x\n", t->Setup[I830_TEXREG_MI0]); + fprintf(stderr, "MI1 : 0x%08x\n", t->Setup[I830_TEXREG_MI1]); + fprintf(stderr, "MI2 : 0x%08x\n", t->Setup[I830_TEXREG_MI2]); + fprintf(stderr, "MI3 : 0x%08x\n", t->Setup[I830_TEXREG_MI3]); + fprintf(stderr, "MI4 : 0x%08x\n", t->Setup[I830_TEXREG_MI4]); + fprintf(stderr, "MI5 : 0x%08x\n", t->Setup[I830_TEXREG_MI5]); + fprintf(stderr, "MF : 0x%08x\n", t->Setup[I830_TEXREG_MF]); + fprintf(stderr, "MLC : 0x%08x\n", t->Setup[I830_TEXREG_MLC]); + fprintf(stderr, "MLL : 0x%08x\n", t->Setup[I830_TEXREG_MLL]); + fprintf(stderr, "MCS : 0x%08x\n", t->Setup[I830_TEXREG_MCS]); + } +} + +void i830DumpTextureBlendState( i830ContextPtr imesa, int unit ) +{ + GLuint *TexBlend = imesa->TexBlend[unit]; + GLuint length = imesa->TexBlendWordsUsed[unit]; + int i; + + fprintf(stderr, "%s : unit %d : length %d\n", __FUNCTION__, unit, length); + for(i = 0; i < length; i++) { + fprintf(stderr, "[%d] : 0x%08x\n", i, TexBlend[i]); + } +} + +void i830VertexSanity( i830ContextPtr imesa, drmI830Vertex vertex ) +{ + I830SAREAPtr sarea = imesa->sarea; + char *prim_name; + int size = 0; + int vfmt_size = 0; + int hw_nr_vertex = 0; + int hw_start_vertex = 0; + + /* Do a bunch of sanity checks on the vertices sent to the hardware */ + + size = vertex.used - 4; + if(imesa->vertex_size && (size % imesa->vertex_size) != 0) { + fprintf(stderr, "\n\nVertex size does not match imesa " + "internal state\n"); + fprintf(stderr, "Buffer size : %d\n", size); + fprintf(stderr, "Vertex size : %d\n", imesa->vertex_size); + } + + /* Check to see if the vertex format is good, and get its size */ + if (sarea->ContextState[I830_CTXREG_VF] == TINY_VERTEX_FORMAT) { + vfmt_size = 16; /* 4 dwords */ + } else if (sarea->ContextState[I830_CTXREG_VF] == + NOTEX_VERTEX_FORMAT) { + vfmt_size = 24; /* 6 dwords */ + } else if (sarea->ContextState[I830_CTXREG_VF] == + TEX0_VERTEX_FORMAT) { + vfmt_size = 32; /* 8 dwords */ + if (sarea->ContextState[I830_CTXREG_VF2] != NON_PROJ_VF2) { + fprintf(stderr, "\n\nTex 0 vertex format, but proj " + "texturing\n"); + } + } else if(sarea->ContextState[I830_CTXREG_VF] == + TEX1_VERTEX_FORMAT) { + if (sarea->ContextState[I830_CTXREG_VF2] == NON_PROJ_VF2) + vfmt_size = 40; /* 10 dwords */ + else + vfmt_size = 48; /* 12 dwords */ + } else { + fprintf(stderr, "\n\nUnknown vertex format : vf : %08x " + "vf2 : %08x\n", + sarea->ContextState[I830_CTXREG_VF], + sarea->ContextState[I830_CTXREG_VF2]); + } + + if(vfmt_size && (size % vfmt_size) != 0) { + fprintf(stderr, "\n\nVertex size does not match hardware " + "internal state\n"); + fprintf(stderr, "Buffer size : %d\n", size); + fprintf(stderr, "Vertex size : %d\n", vfmt_size); + sleep(10); + } + + switch(sarea->vertex_prim) { + case PRIM3D_POINTLIST: + hw_start_vertex = 0; + hw_nr_vertex = 1; + prim_name = "PointList"; + break; + + case PRIM3D_LINELIST: + hw_start_vertex = 0; + hw_nr_vertex = 2; + prim_name = "LineList"; + break; + + case PRIM3D_LINESTRIP: + hw_start_vertex = 2; + hw_nr_vertex = 1; + prim_name = "LineStrip"; + break; + + case PRIM3D_TRILIST: + hw_start_vertex = 0; + hw_nr_vertex = 3; + prim_name = "TriList"; + break; + + case PRIM3D_TRISTRIP: + hw_start_vertex = 3; + hw_nr_vertex = 1; + prim_name = "TriStrip"; + break; + + case PRIM3D_TRIFAN: + hw_start_vertex = 3; + hw_nr_vertex = 1; + prim_name = "TriFan"; + break; + + case PRIM3D_POLY: + hw_start_vertex = 3; + hw_nr_vertex = 1; + prim_name = "Polygons"; + break; + default: + prim_name = "Unknown"; + fprintf(stderr, "\n\nUnknown primitive type : %08x\n", + sarea->vertex_prim); + } + + if (hw_nr_vertex && vfmt_size) { + int temp_size = size - (hw_start_vertex * vfmt_size); + int remaining = (temp_size % (hw_nr_vertex * vfmt_size)); + + if (remaining != 0) { + fprintf(stderr, "\n\nThis buffer contains an improper" + " multiple of vertices for this primitive : %s\n", + prim_name); + fprintf(stderr, "Number of vertices in buffer : %d\n", + size / vfmt_size); + fprintf(stderr, "temp_size : %d\n", temp_size); + fprintf(stderr, "remaining vertices : %d", + remaining / vfmt_size); + sleep(10); + } + } + if (PRINT_VERTEX_INFO) { + fprintf(stderr, "\n\nPrim name (%s), vertices (%d)\n", + prim_name, + size / vfmt_size); + } +} + +void i830EmitHwStateLockedDebug( i830ContextPtr imesa ) +{ + int i; + + if ((imesa->dirty & I830_UPLOAD_TEX0_IMAGE) && imesa->CurrentTexObj[0]) { + i830UploadTexImages(imesa, imesa->CurrentTexObj[0]); + } + + if ((imesa->dirty & I830_UPLOAD_TEX1_IMAGE) && imesa->CurrentTexObj[1]) { + i830UploadTexImages(imesa, imesa->CurrentTexObj[1]); + } + + if (imesa->dirty & I830_UPLOAD_CTX) { + memcpy( imesa->sarea->ContextState, + imesa->Setup, sizeof(imesa->Setup) ); + i830DumpContextState(imesa); + } + + for(i = 0; i < I830_TEXTURE_COUNT; i++) { + if ((imesa->dirty & I830_UPLOAD_TEX_N(i)) && imesa->CurrentTexObj[i]) { + imesa->sarea->dirty |= I830_UPLOAD_TEX_N(i); + memcpy(imesa->sarea->TexState[i], + imesa->CurrentTexObj[i]->Setup, + sizeof(imesa->sarea->TexState[i])); + i830DumpTextureState(imesa, i); + } + } + /* Need to figure out if texturing state, or enable changed. */ + + for(i = 0; i < I830_TEXBLEND_COUNT; i++) { + if (imesa->dirty & I830_UPLOAD_TEXBLEND_N(i)) { + imesa->sarea->dirty |= I830_UPLOAD_TEXBLEND_N(i); + memcpy(imesa->sarea->TexBlendState[i],imesa->TexBlend[i], + imesa->TexBlendWordsUsed[i] * 4); + imesa->sarea->TexBlendStateWordsUsed[i] = + imesa->TexBlendWordsUsed[i]; + i830DumpTextureBlendState(imesa, i); + } + } + + if (imesa->dirty & I830_UPLOAD_BUFFERS) { + memcpy( imesa->sarea->BufferState,imesa->BufferSetup, + sizeof(imesa->BufferSetup) ); + i830DumpBufferState(imesa); + } + + if (imesa->dirty & I830_UPLOAD_TEX_PALETTE_SHARED) { + memcpy( imesa->sarea->Palette[0],imesa->palette, + sizeof(imesa->sarea->Palette[0])); + } else { + i830TextureObjectPtr p; + if (imesa->dirty & I830_UPLOAD_TEX_PALETTE_N(0)) { + p = imesa->CurrentTexObj[0]; + memcpy( imesa->sarea->Palette[0],p->palette, + sizeof(imesa->sarea->Palette[0])); + } + if (imesa->dirty & I830_UPLOAD_TEX_PALETTE_N(1)) { + p = imesa->CurrentTexObj[1]; + memcpy( imesa->sarea->Palette[1], + p->palette, + sizeof(imesa->sarea->Palette[1])); + } + } + imesa->sarea->dirty |= (imesa->dirty & ~(I830_UPLOAD_TEX_MASK | + I830_UPLOAD_TEXBLEND_MASK)); + + imesa->upload_cliprects = GL_TRUE; + imesa->dirty = 0; +} diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_debug.h b/xc/lib/GL/mesa/src/drv/i830/i830_debug.h new file mode 100644 index 000000000..77e7ac213 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/i830/i830_debug.h @@ -0,0 +1,53 @@ +/************************************************************************** + +Copyright 2001 2d3d Inc., Delray Beach, FL + +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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS 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$ */ + +/* + * Author: + * Jeff Hartmann <jhartmann@2d3d.com> + */ + +/* Defines for sanity checking and debug output */ +#ifndef I830DEBUG_INC +#define I830DEBUG_INC + +/* Do sanity checking on vertex buffers */ +#define VERTEX_SANITY 0 +/* Print out information at each vertex buffer dispatch */ +#define PRINT_VERTEX_INFO 0 +/* Dump all emitted state */ +#define OUTPUT_EMITTED_STATE 0 + +void i830DumpContextState( i830ContextPtr imesa ); +void i830DumpBufferState( i830ContextPtr imesa ); +void i830DumpTextureState( i830ContextPtr imesa, int unit ); +void i830DumpTextureBlendState( i830ContextPtr imesa, int unit ); +void i830VertexSanity( i830ContextPtr imesa, drmI830Vertex vertex ); +void i830EmitHwStateLockedDebug( i830ContextPtr imesa ); + +#endif diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_drv.h b/xc/lib/GL/mesa/src/drv/i830/i830_drv.h index 93d574570..fafd9f98c 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_drv.h +++ b/xc/lib/GL/mesa/src/drv/i830/i830_drv.h @@ -25,43 +25,37 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_drv.h,v 1.1 2001/10/04 18:28:21 alanh Exp $ */ +/* $XFree86$ */ /* * Author: - * Jeff Hartmann <jhartmann@valinux.com> + * Jeff Hartmann <jhartmann@2d3d.com> * * Heavily based on the I810 driver, which was written by: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> */ #ifndef __I830_MESA_DRV_H__ #define __I830_MESA_DRV_H__ -#include <X11/Xlibint.h> +#define DEBUGGING 0 -#include "dri_tmm.h" -#include "dri_mesaint.h" -#include "dri_mesa.h" +#define TRACE_IN {\ + if (DEBUGGING) \ + fprintf(stderr,"\nWe are IN function %s on line %d\n",__FUNCTION__,__LINE__);\ +} +#define TRACE_OUT {\ + if (DEBUGGING) \ + fprintf(stderr,"\nWe are OUT OF function %s on line %d\n",__FUNCTION__,__LINE__);\ +} -#include "types.h" -#include "mm.h" -#include "context.h" -#include "mmath.h" -#include "vb.h" - -#include <sys/time.h> - -#include "xf86drm.h" -#include "xf86drmI830.h" -#include "i830_dri.h" + -#include "i830_3d_reg.h" /* To remove all debugging, make sure I830_DEBUG is defined as a * preprocessor symbol, and equal to zero. */ -#define I830_DEBUG 0 +#define I830_DEBUG 0/*DEBUG_VERBOSE_2D|DEBUG_VERBOSE_STATE|DEBUG_VERBOSE_TRACE|DEBUG_VERBOSE_IOCTL|DEBUG_VERBOSE_DRI|DEBUG_VERBOSE_LRU|DEBUG_VALIDATE_RING|DEBUG_VERBOSE_API|DEBUG_VERBOSE_MSG*/ #ifndef I830_DEBUG #warning "Debugging enabled - expect reduced performance" extern int I830_DEBUG; @@ -89,6 +83,7 @@ extern int I830_DEBUG; /* Reasons to fallback on all primitives. (see also * imesa->IndirectTriangles). */ +/* #define I830_FALLBACK_TEXTURE 0x1 #define I830_FALLBACK_DRAW_BUFFER 0x2 #define I830_FALLBACK_READ_BUFFER 0x4 @@ -96,7 +91,7 @@ extern int I830_DEBUG; #define I830_FALLBACK_SPECULAR 0x10 #define I830_FALLBACK_STENCIL 0x20 #define I830_FALLBACK_COLORMASK 0x40 - +*/ /* for i830ctx.new_state - manage GL->driver state changes */ @@ -110,80 +105,14 @@ extern int I830_DEBUG; #define I830_UPDATE_PALETTE 0x2 #define I830_FALLBACK_PALETTE 0x4 -#define I830_SPEC_BIT 0x1 -#define I830_FOG_BIT 0x2 +/*#define I830_SPEC_BIT 0x1 +#define I830_FOG_BIT 0x2*/ #define I830_ALPHA_BIT 0x4 /* GL_BLEND, not used */ -#define I830_TEX0_BIT 0x8 -#define I830_TEX1_BIT 0x10 -#define I830_RGBA_BIT 0x20 +/*#define I830_TEX0_BIT 0x8 +#define I830_TEX1_BIT 0x10*/ +/*#define I830_RGBA_BIT 0x20*/ #define I830_WIN_BIT 0x40 -/* All structures go here */ -typedef struct { - GLubyte blue; - GLubyte green; - GLubyte red; - GLubyte alpha; -} i830_color; - -/* A basic fixed format vertex to kick things off. Move to dynamic - * layouts later on. (see also the i830_full_vertex struct in - * i830_3d_reg.h) - */ -typedef struct { - float x; - float y; - float z; - float oow; - /* float point_width; */ - i830_color color; - i830_color specular; - - float tu0; - float tv0; - /* q only if TEXCOORDTYPE_HOMOGENEOUS (projective) or _VECTOR (cube map)*/ - /* when q is desired, need to change VRTX_TEX_SET_0_FMT(TEXCOORDFMT_2D) - to VRTX_TEX_SET_0_FMT(TEXCOORDFMT_3D); same for other texcoords */ - /* float tq0; */ - - float tu1; - float tv1; - /* float tq1; */ - -#if defined(I830_ENABLE_4_TEXTURES) /* see i830_3d_reg.h */ - float tu2; - float tv2; - /* float tq2; */ - - float tu3; - float tv3; - /* float tq3; */ -#endif /* I830_ENABLE_4_TEXTURES */ -} i830_vertex; - -/* Unfortunately only have assembly for 16-stride vertices. - */ -union i830_vertex_t { - i830_vertex v; - float f[16]; - GLuint ui[16]; -}; - -typedef union i830_vertex_t i830Vertex; -typedef union i830_vertex_t *i830VertexPtr; - -struct i830_vertex_buffer_t { - GLvector1ui clipped_elements; - i830VertexPtr verts; - int last_vert; - GLuint *primitive; - GLuint *next_primitive; - void *vert_store; - GLuint size; -}; - -typedef struct i830_vertex_buffer_t *i830VertexBufferPtr; - /* For shared texture space managment, these texture objects may also * be used as proxies for regions of texture memory containing other @@ -200,85 +129,6 @@ typedef struct i830_vertex_buffer_t *i830VertexBufferPtr; #define TEX_0 1 #define TEX_1 2 -struct i830_texture_object_t { - struct i830_texture_object_t *next, *prev; - - GLuint age; - struct gl_texture_object *globj; - - int Pitch; - int Height; - int texelBytes; - int totalSize; - int bound; - - PMemBlock MemBlock; - char *BufAddr; - - GLuint min_level; - GLuint max_level; - GLuint dirty_images; - - GLenum palette_format; - GLuint palette[256]; - - struct { - const struct gl_texture_image *image; - int offset; /* into BufAddr */ - int height; - int internalFormat; - } image[I830_TEX_MAXLEVELS]; - - /* Support for multitexture. - */ - GLuint current_unit; - GLuint Setup[I830_TEX_SETUP_SIZE]; -}; - -typedef struct { - drmHandle handle; - drmSize size; - char *map; -} i830Region, *i830RegionPtr; - -typedef struct { - i830Region front; - i830Region back; - i830Region depth; - i830Region tex; - - int deviceID; - int width; - int height; - int mem; - - int cpp; /* for front and back buffers */ - int bitsPerPixel; - - int fbFormat; - int fbOffset; - int fbStride; - - int backOffset; - int depthOffset; - - int backPitch; - int backPitchBits; - - int textureOffset; - int textureSize; - int logTextureGranularity; - - __DRIscreenPrivate *driScrnPriv; - drmBufMapPtr bufs; - int use_copy_buf; - unsigned int sarea_priv_offset; -} i830ScreenPrivate; - -typedef struct i830_context_t i830Context; -typedef struct i830_context_t *i830ContextPtr; -typedef struct i830_texture_object_t *i830TextureObjectPtr; - typedef void (*i830_interp_func)( GLfloat t, GLfloat *result, const GLfloat *in, @@ -286,182 +136,8 @@ typedef void (*i830_interp_func)( GLfloat t, -struct i830_context_t { - GLint refcount; - - GLcontext *glCtx; - - i830TextureObjectPtr CurrentTexObj[2]; - - struct i830_texture_object_t TexObjList; - struct i830_texture_object_t SwappedOut; - - int TextureMode; - - /* Hardware state - */ - GLuint Setup[I830_CTX_SETUP_SIZE]; - GLuint BufferSetup[I830_DEST_SETUP_SIZE]; - GLuint TexBlend[I830_TEXBLEND_COUNT][I830_TEXBLEND_SIZE]; - GLuint TexBlendWordsUsed[I830_TEXBLEND_COUNT]; - GLuint TexBlendColorPipeNum[I830_TEXBLEND_COUNT]; - GLuint LastTexEnabled; - GLuint TexEnabledMask; - int vertsize; - - /* Initial GL state, stored here so we can easily access it to draw - * quads to do clears. - */ - GLuint Init_Setup[I830_CTX_SETUP_SIZE]; - GLuint Init_BufferSetup[I830_DEST_SETUP_SIZE]; - GLuint Init_TexBlend[I830_TEXBLEND_COUNT][I830_TEXBLEND_SIZE]; - GLuint Init_TexBlendWordsUsed[I830_TEXBLEND_COUNT]; - GLuint Init_TexBlendColorPipeNum[I830_TEXBLEND_COUNT]; - - /* Support for CVA and the fast paths. - */ - GLuint setupdone; - GLuint setupindex; - GLuint renderindex; - GLuint using_fast_path; - i830_interp_func interp; - - /* Shortcircuit some state changes. - */ - points_func PointsFunc; - line_func LineFunc; - triangle_func TriangleFunc; - quad_func QuadFunc; - - /* Manage our own state */ - GLuint new_state; - - /* Manage hardware state */ - GLuint dirty; - memHeap_t *texHeap; - - /* One of the few bits of hardware state that can't be calculated - * completely on the fly: - */ - GLuint LcsCullMode; - - /* Funny mesa mirrors - */ - GLuint MonoColor; - GLuint ClearColor; - - /* DRI stuff - */ - drmBufPtr vertex_dma_buffer; - GLuint vertex_prim; - - GLframebuffer *glBuffer; - - /* Two flags to keep track of fallbacks. - */ - GLuint IndirectTriangles; - GLuint Fallback; - - - GLuint needClip; - - /* These refer to the current draw (front vs. back) buffer: - */ - char *drawMap; /* draw buffer address in virtual mem */ - char *readMap; - int drawX; /* origin of drawable in draw buffer */ - int drawY; - GLuint numClipRects; /* cliprects for that buffer */ - XF86DRIClipRectPtr pClipRects; - - int lastSwap; - int secondLastSwap; - int texAge; - int ctxAge; - int dirtyAge; - int any_contend; /* throttle me harder */ - - XF86DRIClipRectRec draw_rect; - - drmContext hHWContext; - drmLock *driHwLock; - int driFd; - Display *display; - - int hw_stencil; - - GLfloat depth_scale; - int depth_clear_mask; - int stencil_clear_mask; - int ClearDepth; - - GLboolean mask_red; - GLboolean mask_green; - GLboolean mask_blue; - GLboolean mask_alpha; - - GLubyte clear_red; - GLubyte clear_green; - GLubyte clear_blue; - GLubyte clear_alpha; - - GLenum palette_format; - GLuint palette[256]; - - __DRIdrawablePrivate *driDrawable; - __DRIscreenPrivate *driScreen; - i830ScreenPrivate *i830Screen; - I830SAREAPtr sarea; -}; - -extern void i830GetLock(i830ContextPtr imesa, GLuint flags); -extern void i830EmitHwStateLocked(i830ContextPtr imesa); -extern void i830EmitScissorValues(i830ContextPtr imesa, int box_nr, - int emit); -extern void i830EmitDrawingRectangle(i830ContextPtr imesa); -extern void i830XMesaSetBackClipRects(i830ContextPtr imesa); -extern void i830XMesaSetFrontClipRects(i830ContextPtr imesa); -extern void i830DestroyTexObj(i830ContextPtr imesa, - i830TextureObjectPtr t); -extern int i830UploadTexImages(i830ContextPtr imesa, - i830TextureObjectPtr t); -extern void i830ResetGlobalLRU(i830ContextPtr imesa); -extern void i830TexturesGone(i830ContextPtr imesa, - GLuint start, GLuint end, GLuint in_use); -extern void i830PrintLocalLRU(i830ContextPtr imesa); -extern void i830PrintGlobalLRU(i830ContextPtr imesa); -extern void i830ChooseRasterSetupFunc(GLcontext *ctx); -extern void i830PrintSetupFlags(char *msg, GLuint flags); -extern void i830UpdateTextureState(GLcontext *ctx); - - - -extern void i830DDFastPath(struct vertex_buffer *VB); -extern void i830DDFastPathInit(void); -extern void i830DDExtensionsInit(GLcontext *ctx); -extern void i830DDInitDriverFuncs(GLcontext *ctx); -extern void i830DDInitSpanFuncs(GLcontext *ctx); -extern void i830DDUpdateHwState(GLcontext *ctx); -extern void i830DDUpdateState(GLcontext *ctx); -extern void i830DDInitState(i830ContextPtr imesa); -extern void i830DDInitStateFuncs(GLcontext *ctx); -extern void i830DDInitTextureFuncs(GLcontext *ctx); -extern void i830DDDoRasterSetup(struct vertex_buffer *VB); -extern void i830DDPartialRasterSetup(struct vertex_buffer *VB); -extern void i830DDCheckPartialRasterSetup(GLcontext *ctx, - struct gl_pipeline_stage *d); -extern void i830DDViewport(GLcontext *ctx, GLint x, GLint y, - GLsizei width, GLsizei height); -extern void i830DDDepthRange(GLcontext *ctx, GLclampd nearval, - GLclampd farval); -extern void i830DDUnregisterVB(struct vertex_buffer *VB); -extern void i830DDRegisterVB(struct vertex_buffer *VB); -extern void i830DDResizeVB(struct vertex_buffer *VB, GLuint size); -extern void i830DDSetupInit(void); -extern GLboolean i830DDBuildPrecalcPipeline(GLcontext *ctx); -extern GLuint i830DDRegisterPipelineStages(struct gl_pipeline_stage *out, - const struct gl_pipeline_stage *in, - GLuint nr); + + #define I830_TEX_UNIT_ENABLED(unit) (1<<unit) #define VALID_I830_TEXTURE_OBJECT(tobj) (tobj) @@ -471,33 +147,4 @@ extern GLuint i830DDRegisterPipelineStages(struct gl_pipeline_stage *out, #define GET_DISPATCH_AGE(imesa) imesa->sarea->last_dispatch #define GET_ENQUEUE_AGE(imesa) imesa->sarea->last_enqueue -/* Lock the hardware and validate our state. - */ -#define LOCK_HARDWARE( imesa ) \ - do { \ - char __ret=0; \ - DRM_CAS(imesa->driHwLock, imesa->hHWContext, \ - (DRM_LOCK_HELD|imesa->hHWContext), __ret); \ - if (__ret) \ - i830GetLock( imesa, 0 ); \ - } while (0) - - - -/* Unlock the hardware using the global current context - */ -#define UNLOCK_HARDWARE(imesa) \ - DRM_UNLOCK(imesa->driFd, imesa->driHwLock, imesa->hHWContext); - - -/* This is the wrong way to do it, I'm sure. Otherwise the drm - * bitches that I've already got the heavyweight lock. At worst, - * this is 3 ioctls. The best solution probably only gets me down - * to 2 ioctls in the worst case. - */ -#define LOCK_HARDWARE_QUIESCENT( imesa ) do { \ - LOCK_HARDWARE( imesa ); \ - i830RegetLockQuiescent( imesa ); \ -} while(0) - #endif /* __I830_MESA_DRV_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_fastpath.c b/xc/lib/GL/mesa/src/drv/i830/i830_fastpath.c deleted file mode 100644 index 462ad006f..000000000 --- a/xc/lib/GL/mesa/src/drv/i830/i830_fastpath.c +++ /dev/null @@ -1,535 +0,0 @@ -/************************************************************************** - -Copyright 2001 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 -on the rights to use, copy, modify, merge, publish, distribute, sub -license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL -ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS 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/i830/i830_fastpath.c,v 1.1 2001/10/04 18:28:21 alanh Exp $ */ - -/* - * Author: - * Jeff Hartmann <jhartmann@valinux.com> - * - * Heavily based on the I810 driver, which was written by: - * Keith Whitwell <keithw@valinux.com> - */ - -#include <stdio.h> - -#include "types.h" -#include "enums.h" -#include "cva.h" -#include "vertices.h" - -/* #include "mmath.h" */ - -#include "i830_drv.h" -#include "i830_tris.h" - - -extern void gl_fast_copy_vb( struct vertex_buffer *VB ); - -struct i830_fast_tab { - void (*build_vertices)( struct vertex_buffer *VB, GLuint do_cliptest ); - void (*interp)( GLfloat t, GLfloat *O, const GLfloat *I, const GLfloat *J ); -}; - - - - -#define POINT(x) i830_draw_point(imesa, &ivert[x], psize) -#define LINE(x,y) i830_draw_line(imesa, &ivert[x], &ivert[y] ) -#define TRI(x,y,z) i830_draw_triangle(imesa, &ivert[x], &ivert[y], &ivert[z]) - - - - -/* Direct, and no clipping required. I haven't written the clip funcs - * 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 \ - i830VertexPtr ivert = I830_DRIVER_DATA(VB)->verts; \ - const GLuint *elt = VB->EltPtr->data; \ - GLcontext *ctx = VB->ctx; \ - i830ContextPtr imesa = I830_CONTEXT(ctx); \ - const GLfloat psize = ctx->Point.Size; \ - (void)psize; (void) ivert; - - -#define TAG(x) x##_i830_smooth_indirect -#include "render_tmp.h" - - - -static void i830_render_elements_direct( struct vertex_buffer *VB ) -{ - GLcontext *ctx = VB->ctx; - i830ContextPtr imesa = I830_CONTEXT( ctx ); - GLenum prim = ctx->CVA.elt_mode; - GLuint nr = VB->EltPtr->count; - render_func func = render_tab_i830_smooth_indirect[prim]; - GLuint p = 0; - - if (imesa->new_state) - i830DDUpdateHwState( ctx ); - - do { - func( VB, 0, nr, 0 ); - } while (ctx->Driver.MultipassFunc && - ctx->Driver.MultipassFunc( VB, ++p )); -} - - - -#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) { \ - 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); \ - } \ -} - - -#define CLIP(SGN,V,PLANE) \ -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; \ -} - -#define LINE_CLIP(x,y,z,w,PLANE) \ -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; \ -} - - -static __inline void i830_tri_clip( GLuint **p_elts, - i830Vertex *verts, - GLubyte *clipmask, - GLuint *p_next_vert, - GLubyte mask, - i830_interp_func interp ) -{ - GLuint *elts = *p_elts; - GLuint next_vert = *p_next_vert; - GLuint vlist1[VB_MAX_CLIPPED_VERTS]; - GLuint vlist2[VB_MAX_CLIPPED_VERTS]; - GLuint *inlist[2]; - GLuint *out; - GLuint in = 0; - GLuint n = 3; - 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 i830_line_clip( GLuint **p_elts, - i830Vertex *verts, - GLubyte *clipmask, - GLuint *p_next_vert, - GLubyte mask, - i830_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 ) \ - if (mask[e]) \ - *out++ = e - -#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])) { \ - i830_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])) { \ - i830_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 \ - i830ContextPtr imesa = I830_CONTEXT( VB->ctx ); \ - GLuint *elt = VB->EltPtr->data; \ - i830Vertex *verts = I830_DRIVER_DATA(VB)->verts; \ - GLuint next_vert = I830_DRIVER_DATA(VB)->last_vert; \ - GLuint *out = I830_DRIVER_DATA(VB)->clipped_elements.data; \ - GLubyte *mask = VB->ClipMask; \ - i830_interp_func interp = imesa->interp; \ - (void) interp; (void) verts; - -#define POSTFIX \ - I830_DRIVER_DATA(VB)->clipped_elements.count = \ - out - I830_DRIVER_DATA(VB)->clipped_elements.data; \ - I830_DRIVER_DATA(VB)->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) \ - CLIP_LINE(elt[i1], elt[i0]) - -#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 ) \ - CLIP_TRIANGLE(elt[i3], elt[i2], elt[i0]); \ - CLIP_TRIANGLE(elt[i2], elt[i1], elt[i0]) - -#define TAG(x) i830_clip_##x##_elt -#include "render_tmp.h" - - - -static void i830_project_vertices( struct vertex_buffer *VB ) -{ - i830VertexBufferPtr i830VB = I830_DRIVER_DATA(VB); - GLcontext *ctx = VB->ctx; - i830ContextPtr imesa = I830_CONTEXT(ctx); - GLmatrix *mat = &ctx->Viewport.WindowMap; - GLfloat m[16]; - - m[MAT_SX] = mat->m[MAT_SX]; - m[MAT_TX] = mat->m[MAT_TX] - .5; - m[MAT_SY] = (- mat->m[MAT_SY]); - m[MAT_TY] = (- mat->m[MAT_TY]) + I830_CONTEXT(ctx)->driDrawable->h - .5; - m[MAT_SZ] = mat->m[MAT_SZ] * imesa->depth_scale; - m[MAT_TZ] = mat->m[MAT_TZ] * imesa->depth_scale; - - gl_project_v16( i830VB->verts[VB->CopyStart].f, - i830VB->verts[i830VB->last_vert].f, - m, - 16 * 4 ); -} - -static void i830_project_clipped_vertices( struct vertex_buffer *VB ) -{ - i830VertexBufferPtr i830VB = I830_DRIVER_DATA(VB); - GLcontext *ctx = VB->ctx; - i830ContextPtr imesa = I830_CONTEXT(ctx); - GLmatrix *mat = &ctx->Viewport.WindowMap; - GLfloat m[16]; - - m[MAT_SX] = mat->m[MAT_SX]; - m[MAT_TX] = mat->m[MAT_TX] - .5; - m[MAT_SY] = (- mat->m[MAT_SY]); - m[MAT_TY] = (- mat->m[MAT_TY]) + I830_CONTEXT(ctx)->driDrawable->h - .5; - m[MAT_SZ] = mat->m[MAT_SZ] * imesa->depth_scale; - m[MAT_TZ] = mat->m[MAT_TZ] * imesa->depth_scale; - - gl_project_clipped_v16( i830VB->verts[VB->CopyStart].f, - i830VB->verts[i830VB->last_vert].f, - m, - 16 * 4, - VB->ClipMask + VB->CopyStart ); -} - - -/* 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 "i830_fasttmp.h" - -#define TYPE (I830_RGBA_BIT) -#define TAG(x) x##_RGBA -#include "i830_fasttmp.h" - -#define TYPE (I830_TEX0_BIT) -#define TAG(x) x##_TEX0 -#include "i830_fasttmp.h" - -#define TYPE (I830_RGBA_BIT|I830_TEX0_BIT) -#define TAG(x) x##_RGBA_TEX0 -#include "i830_fasttmp.h" - -#define TYPE (I830_RGBA_BIT|I830_TEX0_BIT|I830_TEX1_BIT) -#define TAG(x) x##_RGBA_TEX0_TEX1 -#include "i830_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 (I830_TEX0_BIT|I830_TEX1_BIT) -#define TAG(x) x##_TEX0_TEX1 -#include "i830_fasttmp.h" - - -/* Very sparsely popluated array - fix the indices. - */ -static struct i830_fast_tab i830FastTab[0x80]; - -void i830DDFastPathInit( void ) -{ - i830_clip_render_init_elt(); - render_init_i830_smooth_indirect(); - - i830_init_fastpath( &i830FastTab[0] ); - i830_init_fastpath_RGBA( &i830FastTab[I830_RGBA_BIT] ); - i830_init_fastpath_TEX0( &i830FastTab[I830_TEX0_BIT] ); - i830_init_fastpath_RGBA_TEX0( &i830FastTab[I830_RGBA_BIT|I830_TEX0_BIT] ); - i830_init_fastpath_TEX0_TEX1( &i830FastTab[I830_TEX0_BIT|I830_TEX1_BIT] ); - i830_init_fastpath_RGBA_TEX0_TEX1( &i830FastTab[I830_RGBA_BIT|I830_TEX0_BIT| - I830_TEX1_BIT] ); -} - -#define VALID_SETUP (I830_RGBA_BIT|I830_TEX0_BIT|I830_TEX1_BIT) - - -void i830DDFastPath( struct vertex_buffer *VB ) -{ - GLcontext *ctx = VB->ctx; - GLenum prim = ctx->CVA.elt_mode; - i830ContextPtr imesa = I830_CONTEXT( ctx ); - struct i830_fast_tab *tab = &i830FastTab[imesa->setupindex & VALID_SETUP]; - GLuint do_cliptest = 1; - - gl_prepare_arrays_cva( VB ); /* still need this */ - - /* Reserve enough space for the pathological case. - */ - if (VB->EltPtr->count * 12 > I830_DRIVER_DATA(VB)->size) { - i830DDResizeVB( VB, VB->EltPtr->count * 12 ); - do_cliptest = 1; - } - - tab->build_vertices( VB, do_cliptest ); /* object->clip space */ - - if (imesa->new_state) - i830DDUpdateHwState( ctx ); - - if (VB->ClipOrMask) { - if (!VB->ClipAndMask) { - render_func *clip = i830_clip_render_tab_elt; - - imesa->interp = tab->interp; - - clip[prim]( VB, 0, VB->EltPtr->count, 0 ); /* build new elts */ - - ctx->CVA.elt_mode = gl_reduce_prim[prim]; - VB->EltPtr = &(I830_DRIVER_DATA(VB)->clipped_elements); - - i830_project_clipped_vertices( VB ); /* clip->device space */ - i830_render_elements_direct( VB ); /* render using new list */ - } - } else { - i830_project_vertices( VB ); /* clip->device space */ - i830_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/i830/i830_fasttmp.h b/xc/lib/GL/mesa/src/drv/i830/i830_fasttmp.h deleted file mode 100644 index 78ea7698f..000000000 --- a/xc/lib/GL/mesa/src/drv/i830/i830_fasttmp.h +++ /dev/null @@ -1,156 +0,0 @@ -/************************************************************************** - -Copyright 2001 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 -on the rights to use, copy, modify, merge, publish, distribute, sub -license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL -ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS 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/i830/i830_fasttmp.h,v 1.1 2001/10/04 18:28:21 alanh Exp $ */ - -/* - * Author: - * Jeff Hartmann <jhartmann@valinux.com> - * - * Heavily based on the I810 driver, which was written by: - * Keith Whitwell <keithw@valinux.com> - */ - - - -/* The first part of setup is applied to all vertices, clipped or - * unclipped. This data w!ill 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(i830_setup_full)( struct vertex_buffer *VB, GLuint do_cliptest ) -{ - GLcontext *ctx = VB->ctx; - const GLfloat * const m = ctx->ModelProjectMatrix.m; - GLuint start = VB->CopyStart; - GLuint count = VB->Count; - GLuint i; - - gl_xform_points3_v16_general(I830_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(I830_DRIVER_DATA(VB)->verts[start].f, - I830_DRIVER_DATA(VB)->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[0]->start; - GLfloat *tex1_data = VB->TexCoordPtr[1]->start; - - GLuint color_stride = VB->ColorPtr->stride; - GLuint tex0_stride = VB->TexCoordPtr[0]->stride; - GLuint tex1_stride = VB->TexCoordPtr[1]->stride; - - GLfloat *f = I830_DRIVER_DATA(VB)->verts[start].f; - - for (i = start ; i < count ; i++, f += 16) { - if (TYPE & I830_RGBA_BIT) { - GLubyte *b = (GLubyte *)&f[CLIP_UBYTE_COLOR]; - GLubyte *col = color; color += color_stride; - b[CLIP_UBYTE_R] = col[0]; - b[CLIP_UBYTE_G] = col[1]; - b[CLIP_UBYTE_B] = col[2]; - b[CLIP_UBYTE_A] = col[3]; - } - if (TYPE & I830_TEX0_BIT) { - f[CLIP_S0] = tex0_data[0]; - f[CLIP_T0] = tex0_data[1]; - STRIDE_F(tex0_data, tex0_stride); - } - if (TYPE & I830_TEX1_BIT) { - f[CLIP_S1] = tex1_data[0]; - f[CLIP_T1] = tex1_data[1]; - STRIDE_F(tex1_data, tex1_stride); - } - } - } - - I830_DRIVER_DATA(VB)->clipped_elements.count = start; - I830_DRIVER_DATA(VB)->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(i830_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 & I830_RGBA_BIT) { - INTERP_RGBA(t, - ((GLubyte *)&(O[4])), - ((GLubyte *)&(I[4])), - ((GLubyte *)&(J[4]))); - } - - if (TYPE & I830_TEX0_BIT) { - O[6] = LINTERP(t, I[6], J[6]); - O[7] = LINTERP(t, I[7], J[7]); - } - - if (TYPE & I830_TEX1_BIT) { - O[8] = LINTERP(t, I[8], J[8]); - O[9] = LINTERP(t, I[9], J[9]); - } -} - - -static void TAG(i830_init_fastpath)( struct i830_fast_tab *tab ) -{ - tab->interp = TAG(i830_interp_vert); - tab->build_vertices = TAG(i830_setup_full); -} - -#undef TYPE -#undef TAG -#undef SIZE diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_ioctl.c b/xc/lib/GL/mesa/src/drv/i830/i830_ioctl.c index 44b3f15c7..493e495c8 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_ioctl.c +++ b/xc/lib/GL/mesa/src/drv/i830/i830_ioctl.c @@ -1,3 +1,4 @@ + /************************************************************************** Copyright 2001 VA Linux Systems Inc., Fremont, California. @@ -25,74 +26,78 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_ioctl.c,v 1.1 2001/10/04 18:28:21 alanh Exp $ */ +/* $XFree86$ */ /* * Author: - * Jeff Hartmann <jhartmann@valinux.com> + * Jeff Hartmann <jhartmann@2d3d.com> + * Graeme Fisher <graeme@2d3d.co.za> + * Abraham vd Merwe <abraham@2d3d.co.za> * * Heavily based on the I810 driver, which was written by: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> */ #include <stdio.h> #include <unistd.h> -#include "types.h" -#include "pb.h" +#include "glheader.h" +#include "mtypes.h" +#include "macros.h" #include "dd.h" +#include "swrast/swrast.h" #include "mm.h" -#include "i830_drv.h" + +#include "i830_screen.h" +#include "i830_dri.h" + +#include "i830_context.h" #include "i830_ioctl.h" +#include "i830_state.h" +#include "i830_debug.h" #include "drm.h" -#include <sys/ioctl.h> -drmBufPtr i830_get_buffer_ioctl( i830ContextPtr imesa ) + +static drmBufPtr i830_get_buffer_ioctl( i830ContextPtr imesa ) { - drm_i830_dma_t dma; + drmI830DMA dma; drmBufPtr buf; - int retcode; - - if (I830_DEBUG&DEBUG_VERBOSE_IOCTL) - fprintf(stderr, "Getting dma buffer\n"); - + int retcode,i = 0; while (1) { - retcode = ioctl(imesa->driFd, DRM_IOCTL_I830_GETBUF, &dma); - - if (dma.granted == 1 && retcode == 0) - break; - - if (I830_DEBUG&DEBUG_VERBOSE_IOCTL) - fprintf(stderr, "Retcode : %d, granted : %d\n", retcode, dma.granted); - - ioctl(imesa->driFd, DRM_IOCTL_I830_FLUSH); + retcode = drmCommandWriteRead(imesa->driFd, + DRM_I830_GETBUF, + &dma, + sizeof(drmI830DMA)); + if (dma.granted == 1 && retcode == 0) + break; + + if (++i > 1000) { + retcode = drmCommandNone(imesa->driFd, DRM_I830_FLUSH); + i = 0; + } } - - if (I830_DEBUG&DEBUG_VERBOSE_IOCTL) - fprintf(stderr, - "imesa->i830Screen->bufs->list : %p, " - "dma.request_idx : %d\n", - imesa->i830Screen->bufs->list, dma.request_idx); + if (0) + fprintf(stderr,"\nimesa->i830Screen->bufs->list: %p\n + dma.request_idx: %d\n",imesa->i830Screen->bufs->list, + dma.request_idx); buf = &(imesa->i830Screen->bufs->list[dma.request_idx]); buf->idx = dma.request_idx; - buf->used = 4; /* leave room for instruction header */ + buf->used = 0; buf->total = dma.request_size; + buf->address = (drmAddress)dma.virtual; - if(imesa->i830Screen->use_copy_buf != 1) - buf->address = (drmAddress)dma.virtual; return buf; } - static void i830ClearDrawQuad(i830ContextPtr imesa, float left, float right, float bottom, float top, GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) { - GLuint *vb = i830AllocDwordsInlineLocked( imesa, 32 ); + GLuint *vb = i830AllocDmaLowLocked( imesa, 128 ); i830Vertex tmp; int i; @@ -102,7 +107,7 @@ static void i830ClearDrawQuad(i830ContextPtr imesa, float left, tmp.v.x = left; tmp.v.y = bottom; tmp.v.z = 1.0; - tmp.v.oow = 1.0; + tmp.v.w = 1.0; tmp.v.color.red = red; tmp.v.color.green = green; tmp.v.color.blue = blue; @@ -111,8 +116,8 @@ static void i830ClearDrawQuad(i830ContextPtr imesa, float left, tmp.v.specular.green = 0; tmp.v.specular.blue = 0; tmp.v.specular.alpha = 0; - tmp.v.tu0 = 0.0f; - tmp.v.tv0 = 0.0f; + tmp.v.u0 = 0.0f; + tmp.v.v0 = 0.0f; for (i = 0 ; i < 8 ; i++) vb[i] = tmp.ui[i]; @@ -180,8 +185,8 @@ static void i830ClearWithTris(GLcontext *ctx, GLbitfield mask, imesa->BufferSetup, sizeof(imesa->BufferSetup) ); - old_vertex_prim = imesa->vertex_prim; - imesa->vertex_prim = PRIM3D_TRIFAN; + old_vertex_prim = imesa->hw_primitive; + imesa->hw_primitive = PRIM3D_TRIFAN; if(mask & DD_FRONT_LEFT_BIT) { GLuint tmp = sarea->ContextState[I830_CTXREG_ENABLES_2]; @@ -242,7 +247,7 @@ static void i830ClearWithTris(GLcontext *ctx, GLbitfield mask, i830ClearDrawQuad(imesa, (float)x0, (float)x1, (float)y0, (float)y1, imesa->clear_red, imesa->clear_green, imesa->clear_blue, imesa->clear_alpha); - i830FlushVerticesLocked(imesa); + i830FlushPrimsLocked( imesa ); } if(mask & DD_BACK_LEFT_BIT) { @@ -305,7 +310,7 @@ static void i830ClearWithTris(GLcontext *ctx, GLbitfield mask, i830ClearDrawQuad(imesa, (float)x0, (float)x1, (float)y0, (float)y1, imesa->clear_red, imesa->clear_green, imesa->clear_blue, imesa->clear_alpha); - i830FlushVerticesLocked(imesa); + i830FlushPrimsLocked( imesa ); } if(mask & DD_STENCIL_BIT) { @@ -387,7 +392,7 @@ static void i830ClearWithTris(GLcontext *ctx, GLbitfield mask, i830ClearDrawQuad(imesa, (float)x0, (float)x1, (float)y0, (float)y1, 255, 255, 255, 255); - i830FlushVerticesLocked(imesa); + i830FlushPrimsLocked( imesa ); } UNLOCK_HARDWARE(imesa); @@ -396,32 +401,35 @@ static void i830ClearWithTris(GLcontext *ctx, GLbitfield mask, I830_UPLOAD_BUFFERS | I830_UPLOAD_TEXBLEND0); - imesa->vertex_prim = old_vertex_prim; + imesa->hw_primitive = old_vertex_prim; } -GLbitfield i830Clear( GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint cx, GLint cy, GLint cw, GLint ch ) +static void i830Clear(GLcontext *ctx, GLbitfield mask, GLboolean all, + GLint cx1, GLint cy1, GLint cw, GLint ch) { i830ContextPtr imesa = I830_CONTEXT( ctx ); __DRIdrawablePrivate *dPriv = imesa->driDrawable; const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); - drm_i830_clear_t clear; + drmI830Clear clear; GLbitfield tri_mask = 0; int i; - - FLUSH_BATCH( imesa ); + GLint cx, cy; /* flip top to bottom */ - cy = dPriv->h-cy-ch; - cx += imesa->drawX; + cy = dPriv->h-cy1-ch; + cx = cx1 + imesa->drawX; cy += imesa->drawY; + if(0) fprintf(stderr, "\nClearColor : 0x%08x\n", imesa->ClearColor); + clear.flags = 0; clear.clear_color = imesa->ClearColor; clear.clear_depth = 0; clear.clear_colormask = 0; clear.clear_depthmask = 0; + I830_FIREVERTICES( imesa ); + if (mask & DD_FRONT_LEFT_BIT) { if(colorMask == ~0) { clear.flags |= I830_FRONT; @@ -453,86 +461,89 @@ GLbitfield i830Clear( GLcontext *ctx, GLbitfield mask, GLboolean all, } else { clear.flags |= I830_DEPTH; clear.clear_depthmask |= imesa->stencil_clear_mask; - clear.clear_depth |= ((ctx->Stencil.Clear<<24) & - imesa->stencil_clear_mask); + clear.clear_depth |= imesa->stencil_clear_mask; } mask &= ~DD_STENCIL_BIT; } /* First check for clears that need to happen with triangles */ - if(tri_mask) { i830ClearWithTris(ctx, tri_mask, all, cx, cy, cw, ch); + } else { + mask |= tri_mask; } - if (!clear.flags) - return mask; - - LOCK_HARDWARE( imesa ); + if (clear.flags) { + LOCK_HARDWARE( imesa ); - if (I830_DEBUG&DEBUG_VERBOSE_IOCTL) - fprintf(stderr, "Clear, bufs %x nbox %d\n", - (int)clear.flags, (int)imesa->numClipRects); - - for (i = 0 ; i < imesa->numClipRects ; ) - { - int nr = MIN2(i + I830_NR_SAREA_CLIPRECTS, imesa->numClipRects); - XF86DRIClipRectRec *box = imesa->pClipRects; - drm_clip_rect_t *b = (drm_clip_rect_t *)imesa->sarea->boxes; - int n = 0; - - if (!all) { - for ( ; i < nr ; i++) { - GLint x = box[i].x1; - GLint y = box[i].y1; - GLint w = box[i].x2 - x; - GLint h = box[i].y2 - y; - - if (x < cx) w -= cx - x, x = cx; - if (y < cy) h -= cy - y, y = cy; - if (x + w > cx + cw) w = cx + cw - x; - if (y + h > cy + ch) h = cy + ch - y; - if (w <= 0) continue; - if (h <= 0) continue; - - b->x1 = x; - b->y1 = y; - b->x2 = x + w; - b->y2 = y + h; - b++; - n++; - } - } else { - for ( ; i < nr ; i++) { - *b++ = *(drm_clip_rect_t *)&box[i]; - n++; + for (i = 0 ; i < imesa->numClipRects ; ) + { + int nr = MIN2(i + I830_NR_SAREA_CLIPRECTS, imesa->numClipRects); + XF86DRIClipRectRec *box = imesa->pClipRects; + drm_clip_rect_t *b = (drm_clip_rect_t *)imesa->sarea->boxes; + int n = 0; + + if (!all) { + for ( ; i < nr ; i++) { + GLint x = box[i].x1; + GLint y = box[i].y1; + GLint w = box[i].x2 - x; + GLint h = box[i].y2 - y; + + if (x < cx) w -= cx - x, x = cx; + if (y < cy) h -= cy - y, y = cy; + if (x + w > cx + cw) w = cx + cw - x; + if (y + h > cy + ch) h = cy + ch - y; + if (w <= 0) continue; + if (h <= 0) continue; + + b->x1 = x; + b->y1 = y; + b->x2 = x + w; + b->y2 = y + h; + b++; + n++; + } + } else { + for ( ; i < nr ; i++) { + *b++ = *(drm_clip_rect_t *)&box[i]; + n++; + } } + + imesa->sarea->nbox = n; + drmCommandWrite(imesa->driFd, DRM_I830_CLEAR, + &clear, sizeof(drmI830Clear)); } - imesa->sarea->nbox = n; - ioctl(imesa->driFd, DRM_IOCTL_I830_CLEAR, &clear); + UNLOCK_HARDWARE( imesa ); + imesa->upload_cliprects = GL_TRUE; } - UNLOCK_HARDWARE( imesa ); - imesa->dirty |= I830_UPLOAD_CLIPRECTS; - - return mask; + if (mask) + _swrast_Clear( ctx, mask, all, cx1, cy1, cw, ch ); } + + /* * Copy the back buffer to the front buffer. */ -void i830SwapBuffers( i830ContextPtr imesa ) +void i830CopyBuffer( const __DRIdrawablePrivate *dPriv ) { - __DRIdrawablePrivate *dPriv = imesa->driDrawable; + i830ContextPtr imesa; XF86DRIClipRectPtr pbox; - int nbox; - int i; - int tmp; + int nbox, i, tmp; + + assert(dPriv); + assert(dPriv->driContextPriv); + assert(dPriv->driContextPriv->driverPrivate); - FLUSH_BATCH( imesa ); + imesa = (i830ContextPtr) dPriv->driContextPriv->driverPrivate; + + I830_FIREVERTICES( imesa ); LOCK_HARDWARE( imesa ); - + pbox = dPriv->pClipRects; nbox = dPriv->numClipRects; @@ -545,117 +556,76 @@ void i830SwapBuffers( i830ContextPtr imesa ) for ( ; i < nr ; i++) *b++ = pbox[i]; - - ioctl(imesa->driFd, DRM_IOCTL_I830_SWAP); + drmCommandNone(imesa->driFd, DRM_I830_SWAP); } tmp = GET_ENQUEUE_AGE(imesa); UNLOCK_HARDWARE( imesa ); - if (GET_DISPATCH_AGE(imesa) < imesa->lastSwap) + /* multiarb will suck the life out of the server without this throttle: + */ + if (GET_DISPATCH_AGE(imesa) < imesa->lastSwap) { i830WaitAge(imesa, imesa->lastSwap); + } imesa->lastSwap = tmp; - imesa->dirty |= I830_UPLOAD_CLIPRECTS; + imesa->upload_cliprects = GL_TRUE; } - - - - +/* + * XXX implement when full-screen extension is done. + */ +void i830PageFlip( const __DRIdrawablePrivate *dPriv ) +{ + return; +} /* This waits for *everybody* to finish rendering -- overkill. */ -void i830DmaFinish( i830ContextPtr imesa ) +void i830DmaFinish( i830ContextPtr imesa ) { - FLUSH_BATCH( imesa ); - - - if (1 || imesa->sarea->last_quiescent != imesa->sarea->last_enqueue) { - - if (I830_DEBUG&DEBUG_VERBOSE_IOCTL) - fprintf(stderr, "i830DmaFinish\n"); - - LOCK_HARDWARE( imesa ); - i830RegetLockQuiescent( imesa ); - UNLOCK_HARDWARE( imesa ); - imesa->sarea->last_quiescent = imesa->sarea->last_enqueue; - } + I830_FIREVERTICES( imesa ); + LOCK_HARDWARE( imesa ); + i830RegetLockQuiescent( imesa ); + UNLOCK_HARDWARE( imesa ); } - -void i830RegetLockQuiescent( i830ContextPtr imesa ) +void i830RegetLockQuiescent( i830ContextPtr imesa ) { - if (1 || imesa->sarea->last_quiescent != imesa->sarea->last_enqueue) { - if (I830_DEBUG&DEBUG_VERBOSE_IOCTL) - fprintf(stderr, "i830RegetLockQuiescent\n"); - - drmUnlock(imesa->driFd, imesa->hHWContext); - i830GetLock( imesa, DRM_LOCK_QUIESCENT ); - imesa->sarea->last_quiescent = imesa->sarea->last_enqueue; - } + drmUnlock(imesa->driFd, imesa->hHWContext); + i830GetLock( imesa, DRM_LOCK_QUIESCENT ); } -void i830WaitAgeLocked( i830ContextPtr imesa, int age ) +void i830WaitAgeLocked( i830ContextPtr imesa, int age ) { - int i = 0; - - - while (++i < 500000 && GET_DISPATCH_AGE(imesa) < age) { - ioctl(imesa->driFd, DRM_IOCTL_I830_GETAGE); - } - - if (GET_DISPATCH_AGE(imesa) < age) { - if (0) - fprintf(stderr, "wait locked %d %d\n", age, GET_DISPATCH_AGE(imesa)); - ioctl(imesa->driFd, DRM_IOCTL_I830_FLUSH); + int i = 0, j; + while (++i < 5000) { + drmCommandNone(imesa->driFd, DRM_I830_GETAGE); + if (GET_DISPATCH_AGE(imesa) >= age) return; + for (j = 0 ; j < 1000 ; j++); } + drmCommandNone(imesa->driFd, DRM_I830_FLUSH); } - void i830WaitAge( i830ContextPtr imesa, int age ) { - int i = 0; - - while (++i < 500000 && GET_DISPATCH_AGE(imesa) < age) { - ioctl(imesa->driFd, DRM_IOCTL_I830_GETAGE); + int i = 0, j; + while (++i < 5000) { + drmCommandNone(imesa->driFd, DRM_I830_GETAGE); + if (GET_DISPATCH_AGE(imesa) >= age) return; + for (j = 0 ; j < 1000 ; j++); } - if (GET_DISPATCH_AGE(imesa) >= age) - return; - i = 0; - while (++i < 1000 && GET_DISPATCH_AGE(imesa) < age) { - ioctl(imesa->driFd, DRM_IOCTL_I830_GETAGE); + while (++i < 1000) { + drmCommandNone(imesa->driFd, DRM_I830_GETAGE); + if (GET_DISPATCH_AGE(imesa) >= age) return; usleep(1000); } - - /* To be effective at letting other clients at the hardware, - * particularly the X server which regularly needs quiescence to - * touch the framebuffer, we really need to sleep *beyond* the - * point where our last buffer clears the hardware. - */ - if (imesa->any_contend) { - usleep(3000); - } - - imesa->any_contend = 0; - - if (GET_DISPATCH_AGE(imesa) < age) { - LOCK_HARDWARE(imesa); - if (GET_DISPATCH_AGE(imesa) < age) - ioctl(imesa->driFd, DRM_IOCTL_I830_FLUSH); - UNLOCK_HARDWARE(imesa); - } -} - -void i830FlushVertices( i830ContextPtr imesa ) -{ - if (!imesa->vertex_dma_buffer) return; - LOCK_HARDWARE( imesa ); - i830FlushVerticesLocked( imesa ); - UNLOCK_HARDWARE( imesa ); + LOCK_HARDWARE(imesa); + drmCommandNone(imesa->driFd, DRM_I830_FLUSH); + UNLOCK_HARDWARE(imesa); } static void age_imesa( i830ContextPtr imesa, int age ) @@ -664,139 +634,140 @@ static void age_imesa( i830ContextPtr imesa, int age ) if (imesa->CurrentTexObj[1]) imesa->CurrentTexObj[1]->age = age; } -void i830FlushVerticesLocked( i830ContextPtr imesa ) +void i830FlushPrimsLocked( i830ContextPtr imesa ) { - drm_clip_rect_t *pbox = (drm_clip_rect_t *)imesa->pClipRects; + XF86DRIClipRectPtr pbox = (XF86DRIClipRectPtr)imesa->pClipRects; int nbox = imesa->numClipRects; - drmBufPtr buffer = imesa->vertex_dma_buffer; - drm_i830_vertex_t vertex; + drmBufPtr buffer = imesa->vertex_buffer; + I830SAREAPtr sarea = imesa->sarea; + drmI830Vertex vertex; int i; - if (I830_DEBUG&DEBUG_VERBOSE_IOCTL) - fprintf(stderr, "i830FlushVerticesLocked, buf->used %d\n", - buffer->used); - - if (!buffer) - return; - - if (imesa->dirty & ~I830_UPLOAD_CLIPRECTS) - i830EmitHwStateLocked( imesa ); - - if (I830_DEBUG&DEBUG_VERBOSE_IOCTL) - fprintf(stderr, "i830FlushVerticesLocked, used %d\n", - buffer->used); - - imesa->vertex_dma_buffer = 0; + if (0) fprintf(stderr, "%s dirty: %08x\n", __FUNCTION__, imesa->dirty); + if (imesa->dirty) +#if OUTPUT_EMITTED_STATE + i830EmitHwStateLockedDebug(imesa); +#else + i830EmitHwStateLocked(imesa); +#endif vertex.idx = buffer->idx; - vertex.used = buffer->used; + vertex.used = imesa->vertex_low; vertex.discard = 0; - + sarea->vertex_prim = imesa->hw_primitive; + + if (0) + fprintf(stderr,"\nVertex idx%d\n" + "\nused %d\n" + "\ndiscard %d\n", + vertex.idx, + vertex.used, + vertex.discard); if (!nbox) vertex.used = 0; + else if (nbox > I830_NR_SAREA_CLIPRECTS) + imesa->upload_cliprects = GL_TRUE; - if (nbox > I830_NR_SAREA_CLIPRECTS) - imesa->dirty |= I830_UPLOAD_CLIPRECTS; - - if(imesa->i830Screen->use_copy_buf == 1 && vertex.used) { - drm_i830_copy_t copy; - - copy.idx = buffer->idx; - copy.used = buffer->used; - copy.address = buffer->address; - ioctl(imesa->driFd, DRM_IOCTL_I830_COPY, ©); - } - - - imesa->sarea->vertex_prim = imesa->vertex_prim; - - if (!nbox || !(imesa->dirty & I830_UPLOAD_CLIPRECTS)) - { - if (nbox == 1) - imesa->sarea->nbox = 0; - else - imesa->sarea->nbox = nbox; - - if (I830_DEBUG&DEBUG_VERBOSE_IOCTL) - fprintf(stderr, "DRM_IOCTL_I830_VERTEX CASE1 nbox %d used %d\n", - nbox, vertex.used); - + if (!nbox || !imesa->upload_cliprects) { + sarea->nbox = nbox == 1 ? 0 : nbox; vertex.discard = 1; - ioctl(imesa->driFd, DRM_IOCTL_I830_VERTEX, &vertex); - age_imesa(imesa, imesa->sarea->last_enqueue); - } - else - { - for (i = 0 ; i < nbox ; ) - { - int nr = MIN2(i + I810_NR_SAREA_CLIPRECTS, nbox); - drm_clip_rect_t *b = (drm_clip_rect_t *)imesa->sarea->boxes; + drmCommandWrite (imesa->driFd, DRM_I830_VERTEX, + &vertex, sizeof(drmI830Vertex)); + age_imesa(imesa, sarea->last_enqueue); + } else { + for (i = 0 ; i < nbox ; ) { + int nr = MIN2(i + I830_NR_SAREA_CLIPRECTS, nbox); + XF86DRIClipRectPtr b = sarea->boxes; - imesa->sarea->nbox = nr - i; + sarea->nbox = nr - i; for ( ; i < nr ; i++, b++) { *b++ = pbox[i]; - if(0) fprintf(stderr, "x1: %d y1: %d x2: %d y2: %d\n", - pbox[i].x1, - pbox[i].y1, - pbox[i].x2, - pbox[i].y2); + if (0) + fprintf(stderr,"\nCo-ordiantes: x1 %d\n" + "y1: %d\n" + "x2: %d\n" + "x3: %d\n", + b->x1, + b->y1, + b->x2, + b->y2); } /* Finished with the buffer? */ - if (nr == nbox) - vertex.discard = 1; + if (nr == nbox) + vertex.discard = 1; + if (0) + fprintf(stderr,"\nWriting vertex info to hardware\n"); + if (0) { + fprintf(stderr,"\nimesa->BufferSetup[I830_DESTREG_DR1] = %x\n", + imesa->BufferSetup[I830_DESTREG_DR1]); + fprintf(stderr,"\nimesa->BufferSetup[I830_DESTREG_DR4] = %x\n", + imesa->BufferSetup[I830_DESTREG_DR4]); + } - if (I830_DEBUG&DEBUG_VERBOSE_IOCTL) - fprintf(stderr, "DRM_IOCTL_I830_VERTEX nbox %d used %d\n", - nbox, vertex.used); + /* Do a bunch of sanity checks on the vertices sent to the hardware */ + if (VERTEX_SANITY) i830VertexSanity(imesa, vertex); - ioctl(imesa->driFd, DRM_IOCTL_I830_VERTEX, &vertex); + drmCommandWrite (imesa->driFd, DRM_I830_VERTEX, + &vertex, sizeof(drmI830Vertex)); age_imesa(imesa, imesa->sarea->last_enqueue); } } + /* Reset imesa vars: + */ + imesa->vertex_buffer = 0; + imesa->vertex_addr = 0; + imesa->vertex_low = 0; + imesa->vertex_high = 0; + imesa->vertex_last_prim = 0; imesa->dirty = 0; - if (I830_DEBUG&DEBUG_VERBOSE_IOCTL) - fprintf(stderr, "finished i830FlushVerticesLocked\n"); + imesa->upload_cliprects = GL_FALSE; } +void i830FlushPrimsGetBuffer( i830ContextPtr imesa ) +{ + LOCK_HARDWARE(imesa); + if (imesa->vertex_buffer) + i830FlushPrimsLocked( imesa ); + imesa->vertex_buffer = i830_get_buffer_ioctl( imesa ); + imesa->vertex_high = imesa->vertex_buffer->total; + imesa->vertex_addr = (char *)imesa->vertex_buffer->address; + imesa->vertex_low = 4; /* leave room for instruction header */ + imesa->vertex_last_prim = imesa->vertex_low; + UNLOCK_HARDWARE(imesa); +} -GLuint *i830AllocDwords( i830ContextPtr imesa, int dwords ) +void i830FlushPrimsGetBufferLocked( i830ContextPtr imesa ) { - GLuint *start; + if (imesa->vertex_buffer) + i830FlushPrimsLocked( imesa ); + imesa->vertex_buffer = i830_get_buffer_ioctl( imesa ); + imesa->vertex_high = imesa->vertex_buffer->total; + imesa->vertex_addr = (char *)imesa->vertex_buffer->address; + imesa->vertex_low = 4; /* leave room for instruction header */ + imesa->vertex_last_prim = imesa->vertex_low; +} - if (!imesa->vertex_dma_buffer) - { - LOCK_HARDWARE(imesa); - imesa->vertex_dma_buffer = i830_get_buffer_ioctl( imesa ); - UNLOCK_HARDWARE(imesa); - } - else if (imesa->vertex_dma_buffer->used + dwords * 4 > - imesa->vertex_dma_buffer->total) - { - LOCK_HARDWARE(imesa); - i830FlushVerticesLocked( imesa ); - imesa->vertex_dma_buffer = i830_get_buffer_ioctl( imesa ); - UNLOCK_HARDWARE(imesa); +void i830FlushPrims( i830ContextPtr imesa ) +{ + if (imesa->vertex_buffer) { + LOCK_HARDWARE( imesa ); + i830FlushPrimsLocked( imesa ); + UNLOCK_HARDWARE( imesa ); } - - start = (GLuint *)((char *)imesa->vertex_dma_buffer->address + - imesa->vertex_dma_buffer->used); - - imesa->vertex_dma_buffer->used += dwords * 4; - return start; } int i830_check_copy(int fd) { - return(ioctl(fd, DRM_IOCTL_I830_DOCOPY)); + return drmCommandNone(fd, DRM_I830_DOCOPY); } static void i830DDFlush( GLcontext *ctx ) { i830ContextPtr imesa = I830_CONTEXT( ctx ); - FLUSH_BATCH( imesa ); + I830_FIREVERTICES( imesa ); } static void i830DDFinish( GLcontext *ctx ) @@ -808,5 +779,7 @@ static void i830DDFinish( GLcontext *ctx ) void i830DDInitIoctlFuncs( GLcontext *ctx ) { ctx->Driver.Flush = i830DDFlush; + ctx->Driver.Clear = i830Clear; ctx->Driver.Finish = i830DDFinish; } + diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_ioctl.h b/xc/lib/GL/mesa/src/drv/i830/i830_ioctl.h index 983ea9840..389143b22 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_ioctl.h +++ b/xc/lib/GL/mesa/src/drv/i830/i830_ioctl.h @@ -1,3 +1,4 @@ + /************************************************************************** Copyright 2001 VA Linux Systems Inc., Fremont, California. @@ -25,104 +26,82 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_ioctl.h,v 1.1 2001/10/04 18:28:21 alanh Exp $ */ +/* $XFree86$ */ /* * Author: - * Jeff Hartmann <jhartmann@valinux.com> + * Jeff Hartmann <jhartmann@2d3d.com> + * Graeme Fisher <graeme@2d3d.co.za> + * Abraham vd Merwe <abraham@2d3d.co.za> * * Heavily based on the I810 driver, which was written by: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> */ +/* $XFree86$ */ + #ifndef I830_IOCTL_H #define I830_IOCTL_H -#include "i830_drv.h" - - -GLuint *i830AllocDwords( i830ContextPtr imesa, int dwords ); - -void i830GetGeneralDmaBufferLocked( i830ContextPtr mmesa ); - -void i830FlushVertices( i830ContextPtr mmesa ); -void i830FlushVerticesLocked( i830ContextPtr mmesa ); +#include "i830_context.h" -void i830FlushGeneralLocked( i830ContextPtr imesa ); +GLuint *i830AllocDwords (i830ContextPtr imesa, int dwords); +void i830EmitPrim( i830ContextPtr imesa ); +void i830FlushPrims( i830ContextPtr mmesa ); +void i830FlushPrimsLocked( i830ContextPtr mmesa ); +void i830FlushPrimsGetBuffer( i830ContextPtr imesa ); +void i830FlushPrimsGetBufferLocked( i830ContextPtr imesa ); void i830WaitAgeLocked( i830ContextPtr imesa, int age ); void i830WaitAge( i830ContextPtr imesa, int age ); - void i830DmaFinish( i830ContextPtr imesa ); - void i830RegetLockQuiescent( i830ContextPtr imesa ); - void i830DDInitIoctlFuncs( GLcontext *ctx ); - -void i830SwapBuffers( i830ContextPtr imesa ); - +void i830CopyBuffer( const __DRIdrawablePrivate *dpriv ); +void i830PageFlip( const __DRIdrawablePrivate *dpriv ); int i830_check_copy(int fd); -GLbitfield i830Clear( GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint cx, GLint cy, GLint cw, GLint ch ); +#define I830_STATECHANGE(imesa, flag) \ +do { \ + if (imesa->vertex_low != imesa->vertex_last_prim) \ + i830FlushPrims(imesa); \ + imesa->dirty |= flag; \ +} while (0) + -#define FLUSH_BATCH(imesa) do { \ - if (I830_DEBUG&DEBUG_VERBOSE_IOCTL) \ - fprintf(stderr, "FLUSH_BATCH in %s\n", __FUNCTION__); \ - if (imesa->vertex_dma_buffer) i830FlushVertices(imesa); \ +#define I830_FIREVERTICES(imesa) \ +do { \ + if (imesa->vertex_buffer) { \ + i830FlushPrims(imesa); \ +} \ } while (0) -extern drmBufPtr i830_get_buffer_ioctl( i830ContextPtr imesa ); -static __inline -GLuint *i830AllocDwordsInline( i830ContextPtr imesa, int dwords ) +static __inline GLuint *i830AllocDmaLow( i830ContextPtr imesa, int bytes ) { - int bytes = dwords * 4; - GLuint *start; - - if (!imesa->vertex_dma_buffer) - { - LOCK_HARDWARE(imesa); - imesa->vertex_dma_buffer = i830_get_buffer_ioctl( imesa ); - UNLOCK_HARDWARE(imesa); - } - else if (imesa->vertex_dma_buffer->used + bytes > - imesa->vertex_dma_buffer->total) + if (imesa->vertex_low + bytes > imesa->vertex_high) { + i830FlushPrimsGetBuffer( imesa ); + } + { - LOCK_HARDWARE(imesa); - i830FlushVerticesLocked( imesa ); - imesa->vertex_dma_buffer = i830_get_buffer_ioctl( imesa ); - UNLOCK_HARDWARE(imesa); + GLuint *start = (GLuint *)(imesa->vertex_addr + imesa->vertex_low); + imesa->vertex_low += bytes; + return start; } - - start = (GLuint *)((char *)imesa->vertex_dma_buffer->address + - imesa->vertex_dma_buffer->used); - - imesa->vertex_dma_buffer->used += bytes; - return start; } -static __inline -GLuint *i830AllocDwordsInlineLocked( i830ContextPtr imesa, int dwords ) +static __inline GLuint *i830AllocDmaLowLocked( i830ContextPtr imesa, + int bytes ) { - int bytes = dwords * 4; - GLuint *start; - - if (!imesa->vertex_dma_buffer) - { - imesa->vertex_dma_buffer = i830_get_buffer_ioctl( imesa ); - } - else if (imesa->vertex_dma_buffer->used + bytes > - imesa->vertex_dma_buffer->total) + if (imesa->vertex_low + bytes > imesa->vertex_high) { + i830FlushPrimsGetBufferLocked( imesa ); + } + { - i830FlushVerticesLocked( imesa ); - imesa->vertex_dma_buffer = i830_get_buffer_ioctl( imesa ); + GLuint *start = (GLuint *)(imesa->vertex_addr + imesa->vertex_low); + imesa->vertex_low += bytes; + return start; } - - start = (GLuint *)((char *)imesa->vertex_dma_buffer->address + - imesa->vertex_dma_buffer->used); - - imesa->vertex_dma_buffer->used += bytes; - return start; } + #endif diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_pipeline.c b/xc/lib/GL/mesa/src/drv/i830/i830_pipeline.c deleted file mode 100644 index 79741cc79..000000000 --- a/xc/lib/GL/mesa/src/drv/i830/i830_pipeline.c +++ /dev/null @@ -1,145 +0,0 @@ -/************************************************************************** - -Copyright 2001 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 -on the rights to use, copy, modify, merge, publish, distribute, sub -license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL -ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS 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/i830/i830_pipeline.c,v 1.1 2001/10/04 18:28:21 alanh Exp $ */ - -/* - * Author: - * Jeff Hartmann <jhartmann@valinux.com> - * - * Heavily based on the I810 driver, which was written by: - * Keith Whitwell <keithw@valinux.com> - */ - -#include <stdio.h> - -#include "types.h" -#include "fog.h" - -#include "i830_drv.h" - -static struct gl_pipeline_stage i830_fast_stage = { - "i830 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, - i830DDFastPath -}; - - -#define ILLEGAL_ENABLES (TEXTURE0_3D| \ - TEXTURE1_3D| \ - ENABLE_TEXMAT0 | \ - ENABLE_TEXMAT1 | \ - ENABLE_TEXGEN0 | \ - ENABLE_TEXGEN1 | \ - ENABLE_USERCLIP | \ - ENABLE_LIGHT | \ - ENABLE_FOG) - - -/* The driver gets first shot at building the pipeline - make some - * quick tests to see if we can use the fast path. - */ -GLboolean i830DDBuildPrecalcPipeline( GLcontext *ctx ) -{ - i830ContextPtr imesa = I830_CONTEXT( ctx ); - struct gl_pipeline *pipe = &ctx->CVA.pre; - - if (imesa->renderindex == 0 && - (ctx->Enabled & ILLEGAL_ENABLES) == 0 && - (ctx->Array.Flags & (VERT_OBJ_234| - VERT_TEX0_4| - VERT_TEX1_4| - VERT_ELT)) == (VERT_OBJ_23|VERT_ELT)) - { - pipe->stages[0] = &i830_fast_stage; - pipe->stages[1] = 0; - pipe->new_inputs = ctx->RenderFlags & VERT_DATA; - pipe->ops = pipe->stages[0]->ops; - imesa->using_fast_path = 1; - return 1; - } - - if (imesa->using_fast_path) - { - imesa->using_fast_path = 0; - ctx->CVA.VB->ClipOrMask = 0; - ctx->CVA.VB->ClipAndMask = CLIP_ALL_BITS; - ctx->Array.NewArrayState |= ctx->Array.Summary; - return 0; - } - - return 0; -} - - - -GLuint i830DDRegisterPipelineStages( struct gl_pipeline_stage *out, - const struct gl_pipeline_stage *in, - GLuint nr ) -{ - GLuint 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 = i830DDCheckPartialRasterSetup; - out[o].run = i830DDPartialRasterSetup; - o++; - break; - - case PIPE_OP_RAST_SETUP_0|PIPE_OP_RAST_SETUP_1: - out[o] = in[i]; - out[o].run = i830DDDoRasterSetup; - o++; - break; - - /* Completely replace Mesa's fog processing to generate fog - * coordinates instead of messing with colors. - */ - case PIPE_OP_FOG: - out[o] = gl_fog_coord_stage; - o++; - break; - - - default: - out[o++] = in[i]; - break; - } - } - - return o; -} - - diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_render.c b/xc/lib/GL/mesa/src/drv/i830/i830_render.c new file mode 100644 index 000000000..15edda3bc --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/i830/i830_render.c @@ -0,0 +1,215 @@ +/* $Id: i830_render.c,v 1.1 2002/05/29 21:21:48 jhartmann Exp $ */ + +/* + * Intel i810 DRI driver for Mesa 3.5 + * + * Copyright (C) 1999-2000 Keith Whitwell 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 KEITH WHITWELL BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Author: + * Keith Whitwell <keith@tungstengraphics.com> + * Adapted for use on the I830: + * Jeff Hartmann <jhartmann@2d3d.com> + */ + + +/* + * Render unclipped vertex buffers by emitting vertices directly to + * dma buffers. Use strip/fan hardware acceleration where possible. + * + */ +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "mem.h" +#include "mtypes.h" +#include "mmath.h" + +#include "tnl/t_context.h" + +#include "i830_screen.h" +#include "i830_dri.h" + +#include "i830_context.h" +#include "i830_tris.h" +#include "i830_state.h" +#include "i830_vb.h" +#include "i830_ioctl.h" + +/* + * Render unclipped vertex buffers by emitting vertices directly to + * dma buffers. Use strip/fan hardware primitives where possible. + * Try to simulate missing primitives with indexed vertices. + */ +#define HAVE_POINTS 0 /* Has it, but can't use because subpixel has to + * be adjusted for points on the I830/I845G + */ +#define HAVE_LINES 1 +#define HAVE_LINE_STRIPS 1 +#define HAVE_TRIANGLES 1 +#define HAVE_TRI_STRIPS 1 +#define HAVE_TRI_STRIP_1 0 /* has it, template can't use it yet */ +#define HAVE_TRI_FANS 1 +#define HAVE_POLYGONS 1 +#define HAVE_QUADS 0 +#define HAVE_QUAD_STRIPS 0 + +#define HAVE_ELTS 0 + +static GLuint hw_prim[GL_POLYGON+1] = { + PRIM3D_POINTLIST, + PRIM3D_LINELIST, + 0, + PRIM3D_LINESTRIP, + PRIM3D_TRILIST, + PRIM3D_TRISTRIP, + PRIM3D_TRIFAN, + 0, + 0, + PRIM3D_POLY +}; + +static const 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 +}; + +/* Fallback to normal rendering. + */ +static void VERT_FALLBACK( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + tnl->Driver.Render.PrimitiveNotify( ctx, flags & PRIM_MODE_MASK ); + tnl->Driver.Render.BuildVertices( ctx, start, count, ~0 ); + tnl->Driver.Render.PrimTabVerts[flags&PRIM_MODE_MASK]( ctx, start, + count, flags ); + I830_CONTEXT(ctx)->SetupNewInputs = VERT_CLIP; +} + + +#define LOCAL_VARS i830ContextPtr imesa = I830_CONTEXT(ctx) +#define INIT( prim ) do { \ + I830_STATECHANGE(imesa, 0); \ + i830RasterPrimitive( ctx, reduced_prim[prim], hw_prim[prim] ); \ +} while (0) + +#define NEW_PRIMITIVE() I830_STATECHANGE( imesa, 0 ) +#define NEW_BUFFER() I830_FIREVERTICES( imesa ) +#define GET_CURRENT_VB_MAX_VERTS() \ + (((int)imesa->vertex_high - (int)imesa->vertex_low) / (imesa->vertex_size*4)) +#define GET_SUBSEQUENT_VB_MAX_VERTS() \ + (I830_DMA_BUF_SZ-4) / (imesa->vertex_size * 4) + +#define EMIT_VERTS( ctx, j, nr ) \ + i830_emit_contiguous_verts(ctx, j, (j)+(nr)) + +#define TAG(x) i830_##x +#include "tnl_dd/t_dd_dmatmp.h" + + +/**********************************************************************/ +/* Render pipeline stage */ +/**********************************************************************/ + + +static GLboolean i830_run_render( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint i, length, flags = 0; + /* Don't handle clipping or indexed vertices. + */ + if (VB->ClipOrMask || imesa->RenderIndex != 0 || VB->Elts) { + return GL_TRUE; + } + + imesa->SetupNewInputs = VERT_CLIP; + + tnl->Driver.Render.Start( ctx ); + + for (i = VB->FirstPrimitive ; !(flags & PRIM_LAST) ; i += length) { + flags = VB->Primitive[i]; + length= VB->PrimitiveLength[i]; + if (length) + i830_render_tab_verts[flags & PRIM_MODE_MASK]( ctx, i, i + length, + flags ); + } + + tnl->Driver.Render.Finish( ctx ); + + return GL_FALSE; /* finished the pipe */ +} + + +static void i830_check_render( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + GLuint inputs = VERT_CLIP|VERT_RGBA; + if (ctx->RenderMode == GL_RENDER) { + if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) + inputs |= VERT_SPEC_RGB; + + if (ctx->Texture.Unit[0]._ReallyEnabled) + inputs |= VERT_TEX(0); + + if (ctx->Texture.Unit[1]._ReallyEnabled) + inputs |= VERT_TEX(1); + + if (ctx->Fog.Enabled) + inputs |= VERT_FOG_COORD; + } + + stage->inputs = inputs; +} + +static void dtr( struct gl_pipeline_stage *stage ) +{ + (void)stage; +} + + +const struct gl_pipeline_stage _i830_render_stage = +{ + "i830 render", + (_DD_NEW_SEPARATE_SPECULAR | + _NEW_TEXTURE| + _NEW_FOG| + _NEW_RENDERMODE), /* re-check (new inputs) */ + 0, /* re-run (always runs) */ + GL_TRUE, /* active */ + 0, 0, /* inputs (set in check_render), outputs */ + 0, 0, /* changed_inputs, private */ + dtr, /* destructor */ + i830_check_render, /* check - initially set to alloc data */ + i830_run_render /* run */ +}; diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_screen.c b/xc/lib/GL/mesa/src/drv/i830/i830_screen.c new file mode 100644 index 000000000..78ea80b06 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/i830/i830_screen.c @@ -0,0 +1,378 @@ +/************************************************************************** + * + * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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$ */ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + * Adapted for use on the I830M: + * Jeff Hartmann <jhartmann@2d3d.com> + */ + + +#include <X11/Xlibint.h> +#include <stdio.h> + + +#include <X11/Xlibint.h> +#include <stdio.h> + +#include "glheader.h" +#include "context.h" +#include "matrix.h" +#include "simple_list.h" + +#include "i830_screen.h" +#include "i830_dri.h" + +#include "i830_state.h" +#include "i830_tex.h" +#include "i830_span.h" +#include "i830_tris.h" +#include "i830_ioctl.h" + +#include "i830_dri.h" + + +static int i830_malloc_proxy_buf(drmBufMapPtr buffers) +{ + char *buffer; + drmBufPtr buf; + int i; + + buffer = Xmalloc(I830_DMA_BUF_SZ); + if(buffer == NULL) return -1; + for(i = 0; i < I830_DMA_BUF_NR; i++) { + buf = &(buffers->list[i]); + buf->address = (drmAddress)buffer; + } + + return 0; +} + +static drmBufMapPtr i830_create_empty_buffers(void) +{ + drmBufMapPtr retval; + + retval = (drmBufMapPtr)Xmalloc(sizeof(drmBufMap)); + if(retval == NULL) return NULL; + memset(retval, 0, sizeof(drmBufMap)); + retval->list = (drmBufPtr)Xmalloc(sizeof(drmBuf) * I830_DMA_BUF_NR); + if(retval->list == NULL) { + Xfree(retval); + return NULL; + } + + memset(retval->list, 0, sizeof(drmBuf) * I830_DMA_BUF_NR); + return retval; +} + +static void i830PrintDRIInfo(i830ScreenPrivate *i830Screen, + __DRIscreenPrivate *sPriv, + I830DRIPtr gDRIPriv) +{ + GLuint size = (gDRIPriv->ringSize + + i830Screen->textureSize + + i830Screen->depth.size + + i830Screen->back.size + + sPriv->fbSize + + I830_DMA_BUF_NR * I830_DMA_BUF_SZ + + 32768 /* Context Memory */ + + 16*4096 /* Ring buffer */ + + 64*1024 /* Scratch buffer */ + + 4096 /* Cursor */); + GLuint size_low = (gDRIPriv->ringSize + + i830Screen->textureSize + + sPriv->fbSize + + I830_DMA_BUF_NR * I830_DMA_BUF_SZ + + 32768 /* Context Memory */ + + 16*4096 /* Ring buffer */ + + 64*1024 /* Scratch buffer */); + + fprintf(stderr, "\nFront size : 0x%x\n", sPriv->fbSize); + fprintf(stderr, "Front offset : 0x%x\n", i830Screen->fbOffset); + fprintf(stderr, "Back size : 0x%x\n", i830Screen->back.size); + fprintf(stderr, "Back offset : 0x%x\n", i830Screen->backOffset); + fprintf(stderr, "Depth size : 0x%x\n", i830Screen->depth.size); + fprintf(stderr, "Depth offset : 0x%x\n", i830Screen->depthOffset); + fprintf(stderr, "Texture size : 0x%x\n", i830Screen->textureSize); + fprintf(stderr, "Texture offset : 0x%x\n", i830Screen->textureOffset); + fprintf(stderr, "Ring offset : 0x%x\n", gDRIPriv->ringOffset); + fprintf(stderr, "Ring size : 0x%x\n", gDRIPriv->ringSize); + fprintf(stderr, "Memory : 0x%x\n", gDRIPriv->mem); + fprintf(stderr, "Used Memory : low(0x%x) high(0x%x)\n", size_low, size); +} + +static GLboolean i830InitDriver(__DRIscreenPrivate *sPriv) +{ + i830ScreenPrivate *i830Screen; + I830DRIPtr gDRIPriv = (I830DRIPtr)sPriv->pDevPriv; + + /* Check the DRI version */ + { + int major, minor, patch; + if (XF86DRIQueryVersion(sPriv->display, &major, &minor, &patch)) { + if (major != 4 || minor < 0) { + __driUtilMessage("i830 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("i830 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 < 2) { + __driUtilMessage("i830 DRI driver expected DRM driver version 1.2.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch); + return GL_FALSE; + } + + /* Allocate the private area */ + i830Screen = (i830ScreenPrivate *)Xmalloc(sizeof(i830ScreenPrivate)); + if (!i830Screen) { + if(DEBUGGING) + fprintf(stderr,"\nERROR! Allocating private area failed\n"); + return GL_FALSE; + } + + i830Screen->driScrnPriv = sPriv; + sPriv->private = (void *)i830Screen; + + i830Screen->deviceID = gDRIPriv->deviceID; + i830Screen->width = gDRIPriv->width; + i830Screen->height = gDRIPriv->height; + i830Screen->mem = gDRIPriv->mem; + i830Screen->cpp = gDRIPriv->cpp; + i830Screen->fbStride = gDRIPriv->fbStride; + i830Screen->fbOffset = gDRIPriv->fbOffset; + + switch (gDRIPriv->bitsPerPixel) { + case 15: i830Screen->fbFormat = DV_PF_555; break; + case 16: i830Screen->fbFormat = DV_PF_565; break; + case 32: i830Screen->fbFormat = DV_PF_8888; break; + } + + i830Screen->backOffset = gDRIPriv->backOffset; + i830Screen->depthOffset = gDRIPriv->depthOffset; + i830Screen->backPitch = gDRIPriv->auxPitch; + i830Screen->backPitchBits = gDRIPriv->auxPitchBits; + i830Screen->textureOffset = gDRIPriv->textureOffset; + i830Screen->textureSize = gDRIPriv->textureSize; + i830Screen->logTextureGranularity = gDRIPriv->logTextureGranularity; + + if (DEBUGGING) + fprintf(stderr, "Tex heap size 0x%x, granularity 0x%x bytes\n", + i830Screen->textureSize, + 1 << i830Screen->logTextureGranularity); + + i830Screen->bufs = i830_create_empty_buffers(); + if(i830Screen->bufs == NULL) { + if (DEBUGGING) + fprintf(stderr,"\nERROR: Failed to create empty buffers in %s \n", + __FUNCTION__); + Xfree(i830Screen); + return GL_FALSE; + } + + /* Check if you need to create a fake buffer */ + if(i830_check_copy(sPriv->fd) == 1) { + i830_malloc_proxy_buf(i830Screen->bufs); + i830Screen->use_copy_buf = 1; + } else { + i830Screen->use_copy_buf = 0; + } + + i830Screen->back.handle = gDRIPriv->backbuffer; + i830Screen->back.size = gDRIPriv->backbufferSize; + + if (drmMap(sPriv->fd, + i830Screen->back.handle, + i830Screen->back.size, + (drmAddress *)&i830Screen->back.map) != 0) { + if (DEBUGGING) + fprintf(stderr, "\nERROR: line %d, Function %s, File %s\n", + __LINE__, __FUNCTION__, __FILE__); + Xfree(i830Screen); + sPriv->private = NULL; + return GL_FALSE; + } + + i830Screen->depth.handle = gDRIPriv->depthbuffer; + i830Screen->depth.size = gDRIPriv->depthbufferSize; + + if (drmMap(sPriv->fd, + i830Screen->depth.handle, + i830Screen->depth.size, + (drmAddress *)&i830Screen->depth.map) != 0) { + if (DEBUGGING) + fprintf(stderr, "\nERROR: line %d, Function %s, File %s\n", + __LINE__, __FUNCTION__, __FILE__); + Xfree(i830Screen); + drmUnmap(i830Screen->back.map, i830Screen->back.size); + sPriv->private = NULL; + return GL_FALSE; + } + + i830Screen->tex.handle = gDRIPriv->textures; + i830Screen->tex.size = gDRIPriv->textureSize; + + if (drmMap(sPriv->fd, + i830Screen->tex.handle, + i830Screen->tex.size, + (drmAddress *)&i830Screen->tex.map) != 0) { + if (DEBUGGING) + fprintf(stderr, "\nERROR: line %d, Function %s, File %s\n", + __LINE__, __FUNCTION__, __FILE__); + Xfree(i830Screen); + drmUnmap(i830Screen->back.map, i830Screen->back.size); + drmUnmap(i830Screen->depth.map, i830Screen->depth.size); + sPriv->private = NULL; + return GL_FALSE; + } + + i830Screen->sarea_priv_offset = gDRIPriv->sarea_priv_offset; + if(0) i830PrintDRIInfo(i830Screen, sPriv, gDRIPriv); + return GL_TRUE; +} + + +static void i830DestroyScreen(__DRIscreenPrivate *sPriv) +{ + i830ScreenPrivate *i830Screen = (i830ScreenPrivate *)sPriv->private; + + /* Need to unmap all the bufs and maps here: + */ + drmUnmap(i830Screen->back.map, i830Screen->back.size); + drmUnmap(i830Screen->depth.map, i830Screen->depth.size); + drmUnmap(i830Screen->tex.map, i830Screen->tex.size); + Xfree(i830Screen); + sPriv->private = NULL; +} + +static GLboolean i830CreateBuffer( Display *dpy, + __DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + const __GLcontextModes *mesaVis, + GLboolean isPixmap ) +{ + if (isPixmap) { + return GL_FALSE; /* not implemented */ + } else { +#if 0 + GLboolean swStencil = (mesaVis->stencilBits > 0 && + mesaVis->depthBits != 24); +#else + GLboolean swStencil = mesaVis->stencilBits > 0; +#endif + driDrawPriv->driverPrivate = (void *) + _mesa_create_framebuffer(mesaVis, + GL_FALSE, /* software depth buffer? */ + swStencil, + mesaVis->accumRedBits > 0, + GL_FALSE /* s/w alpha planes */); + + return (driDrawPriv->driverPrivate != NULL); + } +} + +static void i830DestroyBuffer(__DRIdrawablePrivate *driDrawPriv) +{ + _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); +} + +#if 0 +GLboolean XMesaCloseFullScreen(__DRIcontextPrivate *driContextPriv) +{ + i830ContextPtr imesa = (i830ContextPtr)driContextPriv->driverPrivate; + + if (imesa->currentPage ==1) { + i830PageFlip(imesa); + imesa->currentPage = 0; + } + + imesa->doPageFlip = GL_FALSE; + imesa->Setup[I830_DESTREG_DI0] = imesa->driScreen->front_offset; + + return GL_TRUE; +} + + +GLboolean XMesaOpenFullScreen(__DRIcontextPrivate *driContextPriv) +{ + i830ContextPtr imesa = (i830ContextPtr)driContextPriv->driverPrivate; + + imesa->doPageFlip = 1; + imesa->currentPage = 0; + + return GL_TRUE; +} + +#else + +static GLboolean i830OpenFullScreen (__DRIcontextPrivate *driContextPriv) +{ + return GL_TRUE; +} + +static GLboolean i830CloseFullScreen (__DRIcontextPrivate *driContextPriv) +{ + return GL_TRUE; +} + +#endif + +static struct __DriverAPIRec i830API = { + i830InitDriver, + i830DestroyScreen, + i830CreateContext, + i830DestroyContext, + i830CreateBuffer, + i830DestroyBuffer, + i830SwapBuffers, + i830MakeCurrent, + i830UnbindContext, + i830OpenFullScreen, + i830CloseFullScreen +}; + +/* + * 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, &i830API); + return (void *) psp; +} + diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_screen.h b/xc/lib/GL/mesa/src/drv/i830/i830_screen.h new file mode 100644 index 000000000..ca991c78a --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/i830/i830_screen.h @@ -0,0 +1,115 @@ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +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, sub license, 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 NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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: + * Keith Whitwell <keith@tungstengraphics.com> + * Adapted for use on the I830M: + * Jeff Hartmann <jhartmann@2d3d.com> + */ + +#ifndef _I830_INIT_H_ +#define _I830_INIT_H_ + +#include <sys/time.h> +#include "dri_util.h" + + +/* All structures go here */ +typedef struct +{ + GLubyte blue; + GLubyte green; + GLubyte red; + GLubyte alpha; +}i830_color; + + + +typedef struct { + drmHandle handle; + drmSize size; + char *map; +} i830Region, *i830RegionPtr; + +typedef struct +{ + + i830Region front; + i830Region back; + i830Region depth; + i830Region tex; + + int deviceID; + int width; + int height; + int mem; + + int cpp; /* for front and back buffers */ + int bitsPerPixel; + + int fbFormat; + int fbOffset; + int fbStride; + + int backOffset; + int depthOffset; + + int backPitch; + int backPitchBits; + + int textureOffset; + int textureSize; + int logTextureGranularity; + + __DRIscreenPrivate *driScrnPriv; + drmBufMapPtr bufs; + int use_copy_buf; + unsigned int sarea_priv_offset; +}i830ScreenPrivate; + + +extern GLboolean +i830CreateContext( Display *dpy, const __GLcontextModes *mesaVis, + __DRIcontextPrivate *driContextPriv, + void *sharedContextPrivate ); + +extern void +i830DestroyContext(__DRIcontextPrivate *driContextPriv); + +extern GLboolean +i830UnbindContext(__DRIcontextPrivate *driContextPriv); + +extern GLboolean +i830MakeCurrent(__DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv); + +extern void +i830SwapBuffers(Display *dpy, void *drawablePrivate); + +#endif diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_span.c b/xc/lib/GL/mesa/src/drv/i830/i830_span.c index b52fd7006..035eb3820 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_span.c +++ b/xc/lib/GL/mesa/src/drv/i830/i830_span.c @@ -25,50 +25,57 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_span.c,v 1.1 2001/10/04 18:28:21 alanh Exp $ */ +/* $XFree86$ */ /* * Author: - * Jeff Hartmann <jhartmann@valinux.com> + * Jeff Hartmann <jhartmann@2d3d.com> * * Heavily based on the I810 driver, which was written by: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> */ -#include "types.h" +#include "glheader.h" +#include "macros.h" +#include "mtypes.h" -#include "i830_drv.h" +#include "i830_screen.h" +#include "i830_dri.h" + +#include "i830_span.h" #include "i830_ioctl.h" +#include "swrast/swrast.h" #define DBG 0 -#define LOCAL_VARS \ - __DRIdrawablePrivate *dPriv = imesa->driDrawable; \ - i830ScreenPrivate *i830Screen = imesa->i830Screen; \ +#define LOCAL_VARS \ + __DRIdrawablePrivate *dPriv = imesa->driDrawable; \ + i830ScreenPrivate *i830Screen = imesa->i830Screen; \ GLuint pitch = i830Screen->backPitch * i830Screen->cpp; \ - GLuint height = dPriv->h; \ - char *buf = (char *)(imesa->drawMap + \ - dPriv->x * i830Screen->cpp + \ - dPriv->y * pitch); \ - char *read_buf = (char *)(imesa->readMap + \ - dPriv->x * i830Screen->cpp + \ - dPriv->y * pitch); \ - GLushort p = I830_CONTEXT( ctx )->MonoColor; \ + GLuint height = dPriv->h; \ + char *buf = (char *)(imesa->drawMap + \ + dPriv->x * i830Screen->cpp + \ + dPriv->y * pitch); \ + char *read_buf = (char *)(imesa->readMap + \ + dPriv->x * i830Screen->cpp + \ + dPriv->y * pitch); \ + GLushort p; \ (void) read_buf; (void) buf; (void) p -#define LOCAL_DEPTH_VARS \ - __DRIdrawablePrivate *dPriv = imesa->driDrawable; \ - i830ScreenPrivate *i830Screen = imesa->i830Screen; \ +#define LOCAL_DEPTH_VARS \ + __DRIdrawablePrivate *dPriv = imesa->driDrawable; \ + i830ScreenPrivate *i830Screen = imesa->i830Screen; \ GLuint pitch = i830Screen->backPitch * i830Screen->cpp; \ - GLuint height = dPriv->h; \ - char *buf = (char *)(i830Screen->depth.map + \ - dPriv->x * i830Screen->cpp + \ + GLuint height = dPriv->h; \ + char *buf = (char *)(i830Screen->depth.map + \ + dPriv->x * i830Screen->cpp + \ dPriv->y * pitch) #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS -#define INIT_MONO_PIXEL(p) +#define INIT_MONO_PIXEL(p,color)\ + p = PACK_COLOR_565(color[0],color[1],color[2]) #define CLIPPIXEL(_x,_y) (_x >= minx && _x < maxx && \ _y >= miny && _y < maxy) @@ -86,10 +93,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define Y_FLIP(_y) (height - _y - 1) -#define HW_LOCK() \ +#define HW_LOCK() \ i830ContextPtr imesa = I830_CONTEXT(ctx); \ - FLUSH_BATCH(imesa); \ - i830DmaFinish(imesa); \ + I830_FIREVERTICES(imesa); \ + i830DmaFinish(imesa); \ LOCK_HARDWARE_QUIESCENT(imesa); #define HW_CLIPLOOP() \ @@ -111,8 +118,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. UNLOCK_HARDWARE(imesa); - - /* 16 bit, 565 rgb color spanline and pixel functions */ #define WRITE_RGBA( _x, _y, r, g, b, a ) \ @@ -167,7 +172,6 @@ do { \ #define READ_DEPTH( d, _x, _y ) \ d = *(GLushort *)(buf + _x*2 + _y*pitch); -/* d = 0xffff; */ #define TAG(x) i830##x##_16 #include "depthtmp.h" @@ -188,6 +192,9 @@ do { \ GLuint p = I830_CONTEXT( ctx )->MonoColor; \ (void) read_buf; (void) buf; (void) p +#undef INIT_MONO_PIXEL +#define INIT_MONO_PIXEL(p,color)\ + p = PACK_COLOR_888(color[0],color[1],color[2]) /* 32 bit, 8888 argb color spanline and pixel functions */ @@ -258,76 +265,90 @@ do { \ #define TAG(x) i830##x##_24_8 #include "stenciltmp.h" +static void i830SetReadBuffer(GLcontext *ctx, GLframebuffer *colorBuffer, + GLenum mode) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + if (mode == GL_FRONT_LEFT) { + imesa->readMap = (char*)imesa->driScreen->pFB; + } else if (mode == GL_BACK_LEFT) { + imesa->readMap = imesa->i830Screen->back.map; + } else { + ASSERT(0); + } +} + + void i830DDInitSpanFuncs( GLcontext *ctx ) { i830ContextPtr imesa = I830_CONTEXT(ctx); i830ScreenPrivate *i830Screen = imesa->i830Screen; + struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx); + if (DEBUGGING) + fprintf(stderr,"\nInitialising SPAN funcs\n"); + + swdd->SetReadBuffer = i830SetReadBuffer; + switch (i830Screen->fbFormat) { case DV_PF_555: - ctx->Driver.WriteRGBASpan = i830WriteRGBASpan_555; - ctx->Driver.WriteRGBSpan = i830WriteRGBSpan_555; - ctx->Driver.WriteMonoRGBASpan = i830WriteMonoRGBASpan_555; - ctx->Driver.WriteRGBAPixels = i830WriteRGBAPixels_555; - ctx->Driver.WriteMonoRGBAPixels = i830WriteMonoRGBAPixels_555; - ctx->Driver.ReadRGBASpan = i830ReadRGBASpan_555; - ctx->Driver.ReadRGBAPixels = i830ReadRGBAPixels_555; - - ctx->Driver.ReadDepthSpan = i830ReadDepthSpan_16; - ctx->Driver.WriteDepthSpan = i830WriteDepthSpan_16; - ctx->Driver.ReadDepthPixels = i830ReadDepthPixels_16; - ctx->Driver.WriteDepthPixels = i830WriteDepthPixels_16; + swdd->WriteRGBASpan = i830WriteRGBASpan_555; + swdd->WriteRGBSpan = i830WriteRGBSpan_555; + swdd->WriteMonoRGBASpan = i830WriteMonoRGBASpan_555; + swdd->WriteRGBAPixels = i830WriteRGBAPixels_555; + swdd->WriteMonoRGBAPixels = i830WriteMonoRGBAPixels_555; + swdd->ReadRGBASpan = i830ReadRGBASpan_555; + swdd->ReadRGBAPixels = i830ReadRGBAPixels_555; + + swdd->ReadDepthSpan = i830ReadDepthSpan_16; + swdd->WriteDepthSpan = i830WriteDepthSpan_16; + swdd->ReadDepthPixels = i830ReadDepthPixels_16; + swdd->WriteDepthPixels = i830WriteDepthPixels_16; break; case DV_PF_565: - ctx->Driver.WriteRGBASpan = i830WriteRGBASpan_565; - ctx->Driver.WriteRGBSpan = i830WriteRGBSpan_565; - ctx->Driver.WriteMonoRGBASpan = i830WriteMonoRGBASpan_565; - ctx->Driver.WriteRGBAPixels = i830WriteRGBAPixels_565; - ctx->Driver.WriteMonoRGBAPixels = i830WriteMonoRGBAPixels_565; - ctx->Driver.ReadRGBASpan = i830ReadRGBASpan_565; - ctx->Driver.ReadRGBAPixels = i830ReadRGBAPixels_565; - - ctx->Driver.ReadDepthSpan = i830ReadDepthSpan_16; - ctx->Driver.WriteDepthSpan = i830WriteDepthSpan_16; - ctx->Driver.ReadDepthPixels = i830ReadDepthPixels_16; - ctx->Driver.WriteDepthPixels = i830WriteDepthPixels_16; + swdd->WriteRGBASpan = i830WriteRGBASpan_565; + swdd->WriteRGBSpan = i830WriteRGBSpan_565; + swdd->WriteMonoRGBASpan = i830WriteMonoRGBASpan_565; + swdd->WriteRGBAPixels = i830WriteRGBAPixels_565; + swdd->WriteMonoRGBAPixels = i830WriteMonoRGBAPixels_565; + swdd->ReadRGBASpan = i830ReadRGBASpan_565; + swdd->ReadRGBAPixels = i830ReadRGBAPixels_565; + + swdd->ReadDepthSpan = i830ReadDepthSpan_16; + swdd->WriteDepthSpan = i830WriteDepthSpan_16; + swdd->ReadDepthPixels = i830ReadDepthPixels_16; + swdd->WriteDepthPixels = i830WriteDepthPixels_16; break; case DV_PF_8888: - ctx->Driver.WriteRGBASpan = i830WriteRGBASpan_8888; - ctx->Driver.WriteRGBSpan = i830WriteRGBSpan_8888; - ctx->Driver.WriteMonoRGBASpan = i830WriteMonoRGBASpan_8888; - ctx->Driver.WriteRGBAPixels = i830WriteRGBAPixels_8888; - ctx->Driver.WriteMonoRGBAPixels = i830WriteMonoRGBAPixels_8888; - ctx->Driver.ReadRGBASpan = i830ReadRGBASpan_8888; - ctx->Driver.ReadRGBAPixels = i830ReadRGBAPixels_8888; + swdd->WriteRGBASpan = i830WriteRGBASpan_8888; + swdd->WriteRGBSpan = i830WriteRGBSpan_8888; + swdd->WriteMonoRGBASpan = i830WriteMonoRGBASpan_8888; + swdd->WriteRGBAPixels = i830WriteRGBAPixels_8888; + swdd->WriteMonoRGBAPixels = i830WriteMonoRGBAPixels_8888; + swdd->ReadRGBASpan = i830ReadRGBASpan_8888; + swdd->ReadRGBAPixels = i830ReadRGBAPixels_8888; if(imesa->hw_stencil) { - ctx->Driver.ReadDepthSpan = i830ReadDepthSpan_24_8; - ctx->Driver.WriteDepthSpan = i830WriteDepthSpan_24_8; - ctx->Driver.ReadDepthPixels = i830ReadDepthPixels_24_8; - ctx->Driver.WriteDepthPixels = i830WriteDepthPixels_24_8; - - ctx->Driver.WriteStencilSpan = i830WriteStencilSpan_24_8; - ctx->Driver.ReadStencilSpan = i830ReadStencilSpan_24_8; - ctx->Driver.WriteStencilPixels = i830WriteStencilPixels_24_8; - ctx->Driver.ReadStencilPixels = i830ReadStencilPixels_24_8; + swdd->ReadDepthSpan = i830ReadDepthSpan_24_8; + swdd->WriteDepthSpan = i830WriteDepthSpan_24_8; + swdd->ReadDepthPixels = i830ReadDepthPixels_24_8; + swdd->WriteDepthPixels = i830WriteDepthPixels_24_8; + + swdd->WriteStencilSpan = i830WriteStencilSpan_24_8; + swdd->ReadStencilSpan = i830ReadStencilSpan_24_8; + swdd->WriteStencilPixels = i830WriteStencilPixels_24_8; + swdd->ReadStencilPixels = i830ReadStencilPixels_24_8; } else { - ctx->Driver.ReadDepthSpan = i830ReadDepthSpan_24; - ctx->Driver.WriteDepthSpan = i830WriteDepthSpan_24; - ctx->Driver.ReadDepthPixels = i830ReadDepthPixels_24; - ctx->Driver.WriteDepthPixels = i830WriteDepthPixels_24; + swdd->ReadDepthSpan = i830ReadDepthSpan_24; + swdd->WriteDepthSpan = i830WriteDepthSpan_24; + swdd->ReadDepthPixels = i830ReadDepthPixels_24; + swdd->WriteDepthPixels = i830WriteDepthPixels_24; } break; } - - 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; + if (DEBUGGING) + fprintf(stderr,"\nFinished initialising SPAN funcs\n"); } diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_span.h b/xc/lib/GL/mesa/src/drv/i830/i830_span.h new file mode 100644 index 000000000..295bf2838 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/i830/i830_span.h @@ -0,0 +1,43 @@ +/************************************************************************** + +Copyright 2001 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS 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$ */ + +/* + * Author: + * Jeff Hartmann <jhartmann@2d3d.com> + * + * Heavily based on the I810 driver, which was written by: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#ifndef _I830_SPAN_H +#define _I830_SPAN_H + +extern void i830DDInitSpanFuncs( GLcontext *ctx ); + +#endif diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_state.c b/xc/lib/GL/mesa/src/drv/i830/i830_state.c index 94aa702d4..68ad5de16 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_state.c +++ b/xc/lib/GL/mesa/src/drv/i830/i830_state.c @@ -1,6 +1,6 @@ /************************************************************************** -Copyright 2001 VA Linux Systems Inc., Fremont, California. +Copyright 2001 2d3d Inc., Delray Beach, FL All Rights Reserved. @@ -25,30 +25,42 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_state.c,v 1.1 2001/10/04 18:28:21 alanh Exp $ */ +/* $XFree86$ */ /* * Author: - * Jeff Hartmann <jhartmann@valinux.com> + * Jeff Hartmann <jhartmann@2d3d.com> * * Heavily based on the I810 driver, which was written by: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> */ - #include <stdio.h> -#include "types.h" +#include "glheader.h" +#include "context.h" +#include "macros.h" #include "enums.h" -#include "pb.h" #include "dd.h" #include "mm.h" -#include "i830_drv.h" +#include "i830_screen.h" +#include "i830_dri.h" + +#include "i830_context.h" +#include "i830_state.h" +#include "i830_tex.h" +#include "i830_vb.h" #include "i830_tris.h" #include "i830_ioctl.h" -/* Need to add other formats */ +#include "swrast/swrast.h" +#include "array_cache/acache.h" +#include "tnl/tnl.h" +#include "swrast_setup/swrast_setup.h" + +#include "tnl/t_pipeline.h" + static __inline__ GLuint i830PackColor(GLuint format, GLubyte r, GLubyte g, GLubyte b, GLubyte a) @@ -70,109 +82,72 @@ static __inline__ GLuint i830PackColor(GLuint format, } } -static void i830DDPointSize(GLcontext *ctx, GLfloat size) +static void i830StencilFunc(GLcontext *ctx, GLenum func, GLint ref, + GLuint mask) { i830ContextPtr imesa = I830_CONTEXT(ctx); - GLint point_size = FloatToInt(size); - - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s\n", __FUNCTION__); - - FLUSH_BATCH(imesa); - CLAMP_SELF(point_size, 1, 256); - imesa->dirty |= I830_UPLOAD_CTX; - imesa->Setup[I830_CTXREG_STATE5] &= ~FIXED_POINT_WIDTH_MASK; - imesa->Setup[I830_CTXREG_STATE5] |= (ENABLE_FIXED_POINT_WIDTH | - FIXED_POINT_WIDTH(point_size)); -} - -static void i830DDStencilFunc(GLcontext *ctx, GLenum func, GLint ref, - GLuint mask) -{ - i830ContextPtr imesa = I830_CONTEXT(ctx); - GLuint v_mask, w_mask; int test = 0; + mask = mask & 0xff; if(I830_DEBUG&DEBUG_VERBOSE_TRACE) fprintf(stderr, "%s : func: %s, ref : 0x%x, mask: 0x%x\n", __FUNCTION__, - gl_lookup_enum_by_nr(func), ref, mask); - - FLUSH_BATCH(imesa); - - v_mask = ctx->Stencil.ValueMask & 0xff; - w_mask = ctx->Stencil.WriteMask & 0xff; + _mesa_lookup_enum_by_nr(func), ref, mask); switch(func) { case GL_NEVER: test = COMPAREFUNC_NEVER; break; case GL_LESS: test = COMPAREFUNC_LESS; break; - case GL_EQUAL: test = COMPAREFUNC_EQUAL; break; case GL_LEQUAL: test = COMPAREFUNC_LEQUAL; break; case GL_GREATER: test = COMPAREFUNC_GREATER; break; - case GL_NOTEQUAL: test = COMPAREFUNC_NOTEQUAL; break; case GL_GEQUAL: test = COMPAREFUNC_GEQUAL; break; + case GL_NOTEQUAL: test = COMPAREFUNC_NOTEQUAL; break; + case GL_EQUAL: test = COMPAREFUNC_EQUAL; break; case GL_ALWAYS: test = COMPAREFUNC_ALWAYS; break; - default: break; + default: return; } - imesa->dirty |= I830_UPLOAD_CTX; + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); imesa->Setup[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_MASK; imesa->Setup[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | - ENABLE_STENCIL_WRITE_MASK | - STENCIL_TEST_MASK(v_mask) | - STENCIL_WRITE_MASK(w_mask)); + ENABLE_STENCIL_WRITE_MASK | + STENCIL_TEST_MASK(mask) | + STENCIL_WRITE_MASK(mask)); imesa->Setup[I830_CTXREG_STENCILTST] &= ~(STENCIL_REF_VALUE_MASK | - ENABLE_STENCIL_TEST_FUNC_MASK); + ENABLE_STENCIL_TEST_FUNC_MASK); imesa->Setup[I830_CTXREG_STENCILTST] |= (ENABLE_STENCIL_REF_VALUE | - ENABLE_STENCIL_TEST_FUNC | - STENCIL_REF_VALUE(ref) | - STENCIL_TEST_FUNC(test)); - - if(I830_DEBUG&DEBUG_VERBOSE_STATE) - fprintf(stderr, "%s : state4 : 0x%x, stentst : 0x%x\n", __FUNCTION__, - imesa->Setup[I830_CTXREG_STATE4], - imesa->Setup[I830_CTXREG_STENCILTST]); + ENABLE_STENCIL_TEST_FUNC | + STENCIL_REF_VALUE(ref) | + STENCIL_TEST_FUNC(test)); } -static void i830DDStencilMask(GLcontext *ctx, GLuint mask) +static void i830StencilMask(GLcontext *ctx, GLuint mask) { i830ContextPtr imesa = I830_CONTEXT(ctx); - GLuint v_mask, w_mask; - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) fprintf(stderr, "%s : mask 0x%x\n", __FUNCTION__, mask); - FLUSH_BATCH(imesa); - - v_mask = ctx->Stencil.ValueMask & 0xff; - w_mask = ctx->Stencil.WriteMask & 0xff; - - imesa->dirty |= I830_UPLOAD_CTX; + mask = mask & 0xff; + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); imesa->Setup[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_MASK; imesa->Setup[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | - ENABLE_STENCIL_WRITE_MASK | - STENCIL_TEST_MASK(v_mask) | - STENCIL_WRITE_MASK(w_mask)); - if(I830_DEBUG&DEBUG_VERBOSE_STATE) - fprintf(stderr, "%s : state4 : 0x%x\n", __FUNCTION__, - imesa->Setup[I830_CTXREG_STATE4]); + ENABLE_STENCIL_WRITE_MASK | + STENCIL_TEST_MASK(mask) | + STENCIL_WRITE_MASK(mask)); } -static void i830DDStencilOp(GLcontext *ctx, GLenum fail, GLenum zfail, - GLenum zpass) +static void i830StencilOp(GLcontext *ctx, GLenum fail, GLenum zfail, + GLenum zpass) { i830ContextPtr imesa = I830_CONTEXT(ctx); int fop, dfop, dpop; if(I830_DEBUG&DEBUG_VERBOSE_TRACE) fprintf(stderr, "%s: fail : %s, zfail: %s, zpass : %s\n", __FUNCTION__, - gl_lookup_enum_by_nr(fail), - gl_lookup_enum_by_nr(zfail), - gl_lookup_enum_by_nr(zpass)); - - FLUSH_BATCH(imesa); + _mesa_lookup_enum_by_nr(fail), + _mesa_lookup_enum_by_nr(zfail), + _mesa_lookup_enum_by_nr(zpass)); fop = 0; dfop = 0; dpop = 0; @@ -204,59 +179,39 @@ static void i830DDStencilOp(GLcontext *ctx, GLenum fail, GLenum zfail, default: break; } - imesa->dirty |= I830_UPLOAD_CTX; + + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); imesa->Setup[I830_CTXREG_STENCILTST] &= ~(STENCIL_OPS_MASK); imesa->Setup[I830_CTXREG_STENCILTST] |= (ENABLE_STENCIL_PARMS | - STENCIL_FAIL_OP(fop) | - STENCIL_PASS_DEPTH_FAIL_OP(dfop) | - STENCIL_PASS_DEPTH_PASS_OP(dpop)); + STENCIL_FAIL_OP(fop) | + STENCIL_PASS_DEPTH_FAIL_OP(dfop) | + STENCIL_PASS_DEPTH_PASS_OP(dpop)); if(I830_DEBUG&DEBUG_VERBOSE_STATE) fprintf(stderr, "%s : stentst : 0x%x\n", __FUNCTION__, imesa->Setup[I830_CTXREG_STENCILTST]); - } -static void i830DDAlphaFunc(GLcontext *ctx, GLenum func, GLclampf ref) +static void i830AlphaFunc(GLcontext *ctx, GLenum func, GLchan ref) { i830ContextPtr imesa = I830_CONTEXT(ctx); int test = 0; GLubyte tmp_ref; - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s %s\n", __FUNCTION__, gl_lookup_enum_by_nr(func)); - FLOAT_COLOR_TO_UBYTE_COLOR(tmp_ref, ref); - FLUSH_BATCH(imesa); - switch(func) { - case GL_NEVER: - test = COMPAREFUNC_NEVER; - break; - case GL_LESS: - test = COMPAREFUNC_LESS; - break; - case GL_LEQUAL: - test = COMPAREFUNC_LEQUAL; - break; - case GL_GREATER: - test = COMPAREFUNC_GREATER; - break; - case GL_GEQUAL: - test = COMPAREFUNC_GEQUAL; - break; - case GL_NOTEQUAL: - test = COMPAREFUNC_NOTEQUAL; - break; - case GL_EQUAL: - test = COMPAREFUNC_EQUAL; - break; - case GL_ALWAYS: - test = COMPAREFUNC_ALWAYS; - break; + case GL_NEVER: test = COMPAREFUNC_NEVER; break; + case GL_LESS: test = COMPAREFUNC_LESS; break; + case GL_LEQUAL: test = COMPAREFUNC_LEQUAL; break; + case GL_GREATER: test = COMPAREFUNC_GREATER; break; + case GL_GEQUAL: test = COMPAREFUNC_GEQUAL; break; + case GL_NOTEQUAL: test = COMPAREFUNC_NOTEQUAL; break; + case GL_EQUAL: test = COMPAREFUNC_EQUAL; break; + case GL_ALWAYS: test = COMPAREFUNC_ALWAYS; break; default: return; } - imesa->dirty |= I830_UPLOAD_CTX; + + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); imesa->Setup[I830_CTXREG_STATE2] &= ~ALPHA_TEST_REF_MASK; imesa->Setup[I830_CTXREG_STATE2] |= (ENABLE_ALPHA_TEST_FUNC | ENABLE_ALPHA_REF_VALUE | @@ -274,10 +229,9 @@ static void i830EvalLogicOpBlendState(GLcontext *ctx) { i830ContextPtr imesa = I830_CONTEXT(ctx); - FLUSH_BATCH(imesa); - imesa->dirty |= I830_UPLOAD_CTX; + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); - if(ctx->Color.ColorLogicOpEnabled || ctx->Color.IndexLogicOpEnabled) { + if(ctx->Color.ColorLogicOpEnabled) { imesa->Setup[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND | ENABLE_LOGIC_OP_MASK); imesa->Setup[I830_CTXREG_ENABLES_1] |= (DISABLE_COLOR_BLEND | @@ -305,19 +259,38 @@ static void i830EvalLogicOpBlendState(GLcontext *ctx) } } -static void i830DDBlendEquation(GLcontext *ctx, GLenum mode) +static void i830BlendColor(GLcontext *ctx, const GLfloat color[4]) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + GLubyte r, g, b, a; + + if(I830_DEBUG&DEBUG_VERBOSE_TRACE) + fprintf(stderr, "%s\n", __FUNCTION__); + + FLOAT_COLOR_TO_UBYTE_COLOR(r, color[RCOMP]); + FLOAT_COLOR_TO_UBYTE_COLOR(g, color[GCOMP]); + FLOAT_COLOR_TO_UBYTE_COLOR(b, color[BCOMP]); + FLOAT_COLOR_TO_UBYTE_COLOR(a, color[ACOMP]); + + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_BLENDCOLR] = ((a << 24) | + (r << 16) | + (g << 8) | + b); +} + +static void i830BlendEquation(GLcontext *ctx, GLenum mode) { i830ContextPtr imesa = I830_CONTEXT(ctx); int func = ENABLE_ALPHA_BLENDFUNC; if(I830_DEBUG&DEBUG_VERBOSE_TRACE) fprintf(stderr, "%s %s\n", __FUNCTION__, - gl_lookup_enum_by_nr(mode)); + _mesa_lookup_enum_by_nr(mode)); + /* This will catch a logicop blend equation */ i830EvalLogicOpBlendState(ctx); - FLUSH_BATCH(imesa); - switch(mode) { case GL_FUNC_ADD_EXT: func |= BLENDFUNC_ADD; break; case GL_MIN_EXT: func |= BLENDFUNC_MIN; break; @@ -326,37 +299,89 @@ static void i830DDBlendEquation(GLcontext *ctx, GLenum mode) case GL_FUNC_REVERSE_SUBTRACT_EXT: func |= BLENDFUNC_RVRSE_SUB; break; default: return; } - - imesa->dirty |= I830_UPLOAD_CTX; + + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); imesa->Setup[I830_CTXREG_STATE1] &= ~BLENDFUNC_MASK; imesa->Setup[I830_CTXREG_STATE1] |= func; + if (0) fprintf(stderr, "%s : STATE1 : 0x%08x\n", + __FUNCTION__, + imesa->Setup[I830_CTXREG_STATE1]); } -static void i830DDBlendConstColor(GLcontext *ctx, GLfloat red, - GLfloat green, GLfloat blue, - GLfloat alpha) +static void i830BlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor) { i830ContextPtr imesa = I830_CONTEXT(ctx); - GLubyte r, g, b, a; + int func = (ENABLE_SRC_BLND_FACTOR|ENABLE_DST_BLND_FACTOR); if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s\n", __FUNCTION__); + fprintf(stderr, "%s %s %s\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(sfactor), + _mesa_lookup_enum_by_nr(dfactor)); - FLOAT_COLOR_TO_UBYTE_COLOR(r, red); - FLOAT_COLOR_TO_UBYTE_COLOR(g, green); - FLOAT_COLOR_TO_UBYTE_COLOR(b, blue); - FLOAT_COLOR_TO_UBYTE_COLOR(a, alpha); + switch(sfactor) { + case GL_ZERO: func |= SRC_BLND_FACT(BLENDFACT_ZERO); break; + case GL_SRC_ALPHA: func |= SRC_BLND_FACT(BLENDFACT_SRC_ALPHA); break; + case GL_ONE: func |= SRC_BLND_FACT(BLENDFACT_ONE); break; + case GL_DST_COLOR: func |= SRC_BLND_FACT(BLENDFACT_DST_COLR); break; + case GL_ONE_MINUS_DST_COLOR: + func |= SRC_BLND_FACT(BLENDFACT_INV_DST_COLR); break; + case GL_ONE_MINUS_SRC_ALPHA: + func |= SRC_BLND_FACT(BLENDFACT_INV_SRC_ALPHA); break; + case GL_DST_ALPHA: func |= SRC_BLND_FACT(BLENDFACT_DST_ALPHA); break; + case GL_ONE_MINUS_DST_ALPHA: + func |= SRC_BLND_FACT(BLENDFACT_INV_DST_ALPHA); break; + case GL_SRC_ALPHA_SATURATE: + func |= SRC_BLND_FACT(BLENDFACT_SRC_ALPHA_SATURATE); + break; + case GL_CONSTANT_COLOR_EXT: + func |= SRC_BLND_FACT(BLENDFACT_CONST_COLOR); break; + case GL_ONE_MINUS_CONSTANT_COLOR_EXT: + func |= SRC_BLND_FACT(BLENDFACT_INV_CONST_COLOR); + break; + case GL_CONSTANT_ALPHA_EXT: + func |= SRC_BLND_FACT(BLENDFACT_CONST_ALPHA); break; + case GL_ONE_MINUS_CONSTANT_ALPHA_EXT: + func |= SRC_BLND_FACT(BLENDFACT_INV_CONST_ALPHA); + break; + default: return; + } - imesa->dirty |= I830_UPLOAD_CTX; - imesa->Setup[I830_CTXREG_BLENDCOLR] = ((a << 24) | - (r << 16) | - (g << 8) | - b); + switch(dfactor) { + case GL_SRC_ALPHA: func |= DST_BLND_FACT(BLENDFACT_SRC_ALPHA); break; + case GL_ONE_MINUS_SRC_ALPHA: + func |= DST_BLND_FACT(BLENDFACT_INV_SRC_ALPHA); break; + case GL_ZERO: func |= DST_BLND_FACT(BLENDFACT_ZERO); break; + case GL_ONE: func |= DST_BLND_FACT(BLENDFACT_ONE); break; + case GL_SRC_COLOR: func |= DST_BLND_FACT(BLENDFACT_SRC_COLR); break; + case GL_ONE_MINUS_SRC_COLOR: + func |= DST_BLND_FACT(BLENDFACT_INV_SRC_COLR); break; + case GL_DST_ALPHA: func |= DST_BLND_FACT(BLENDFACT_DST_ALPHA); break; + case GL_ONE_MINUS_DST_ALPHA: + func |= DST_BLND_FACT(BLENDFACT_INV_DST_ALPHA); break; + case GL_CONSTANT_COLOR_EXT: + func |= DST_BLND_FACT(BLENDFACT_CONST_COLOR); break; + case GL_ONE_MINUS_CONSTANT_COLOR_EXT: + func |= DST_BLND_FACT(BLENDFACT_INV_CONST_COLOR); + break; + case GL_CONSTANT_ALPHA_EXT: + func |= DST_BLND_FACT(BLENDFACT_CONST_ALPHA); break; + case GL_ONE_MINUS_CONSTANT_ALPHA_EXT: + func |= DST_BLND_FACT(BLENDFACT_INV_CONST_ALPHA); + break; + default: return; + } + + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_IALPHAB] &= ~SRC_DST_ABLEND_MASK; + imesa->Setup[I830_CTXREG_STATE1] &= ~SRC_DST_BLND_MASK; + imesa->Setup[I830_CTXREG_STATE1] |= func; + /* Insure Independant Alpha Blend is really disabled. */ + i830EvalLogicOpBlendState(ctx); } -static void i830DDBlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, - GLenum dfactorRGB, GLenum sfactorA, - GLenum dfactorA ) +static void i830BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, + GLenum dfactorRGB, GLenum sfactorA, + GLenum dfactorA ) { i830ContextPtr imesa = I830_CONTEXT(ctx); int funcA = (ENABLE_SRC_ABLEND_FACTOR|ENABLE_DST_ABLEND_FACTOR); @@ -365,8 +390,6 @@ static void i830DDBlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, if(I830_DEBUG&DEBUG_VERBOSE_TRACE) fprintf(stderr, "%s\n", __FUNCTION__); - FLUSH_BATCH(imesa); - switch(sfactorA) { case GL_ZERO: funcA |= SRC_ABLEND_FACT(BLENDFACT_ZERO); break; case GL_SRC_ALPHA: funcA |= SRC_ABLEND_FACT(BLENDFACT_SRC_ALPHA); break; @@ -472,91 +495,19 @@ static void i830DDBlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, default: return; } - imesa->dirty |= I830_UPLOAD_CTX; + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); imesa->Setup[I830_CTXREG_IALPHAB] &= ~SRC_DST_ABLEND_MASK; imesa->Setup[I830_CTXREG_IALPHAB] |= funcA; imesa->Setup[I830_CTXREG_STATE1] &= ~SRC_DST_BLND_MASK; imesa->Setup[I830_CTXREG_STATE1] |= funcRGB; - /* Insure Independant Alpha Blend is really enabled if need be */ - i830EvalLogicOpBlendState(ctx); -} - -static void i830DDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor) -{ - i830ContextPtr imesa = I830_CONTEXT(ctx); - int func = (ENABLE_SRC_BLND_FACTOR|ENABLE_DST_BLND_FACTOR); - - FLUSH_BATCH(imesa); - - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s %s %s\n", __FUNCTION__, - gl_lookup_enum_by_nr(sfactor), - gl_lookup_enum_by_nr(dfactor)); - - switch(sfactor) { - case GL_ZERO: func |= SRC_BLND_FACT(BLENDFACT_ZERO); break; - case GL_SRC_ALPHA: func |= SRC_BLND_FACT(BLENDFACT_SRC_ALPHA); break; - case GL_ONE: func |= SRC_BLND_FACT(BLENDFACT_ONE); break; - case GL_DST_COLOR: func |= SRC_BLND_FACT(BLENDFACT_DST_COLR); break; - case GL_ONE_MINUS_DST_COLOR: - func |= SRC_BLND_FACT(BLENDFACT_INV_DST_COLR); break; - case GL_ONE_MINUS_SRC_ALPHA: - func |= SRC_BLND_FACT(BLENDFACT_INV_SRC_ALPHA); break; - case GL_DST_ALPHA: func |= SRC_BLND_FACT(BLENDFACT_DST_ALPHA); break; - case GL_ONE_MINUS_DST_ALPHA: - func |= SRC_BLND_FACT(BLENDFACT_INV_DST_ALPHA); break; - case GL_SRC_ALPHA_SATURATE: - func |= SRC_BLND_FACT(BLENDFACT_SRC_ALPHA_SATURATE); - break; - case GL_CONSTANT_COLOR_EXT: - func |= SRC_BLND_FACT(BLENDFACT_CONST_COLOR); break; - case GL_ONE_MINUS_CONSTANT_COLOR_EXT: - func |= SRC_BLND_FACT(BLENDFACT_INV_CONST_COLOR); - break; - case GL_CONSTANT_ALPHA_EXT: - func |= SRC_BLND_FACT(BLENDFACT_CONST_ALPHA); break; - case GL_ONE_MINUS_CONSTANT_ALPHA_EXT: - func |= SRC_BLND_FACT(BLENDFACT_INV_CONST_ALPHA); - break; - default: return; - } - switch(dfactor) { - case GL_SRC_ALPHA: func |= DST_BLND_FACT(BLENDFACT_SRC_ALPHA); break; - case GL_ONE_MINUS_SRC_ALPHA: - func |= DST_BLND_FACT(BLENDFACT_INV_SRC_ALPHA); break; - case GL_ZERO: func |= DST_BLND_FACT(BLENDFACT_ZERO); break; - case GL_ONE: func |= DST_BLND_FACT(BLENDFACT_ONE); break; - case GL_SRC_COLOR: func |= DST_BLND_FACT(BLENDFACT_SRC_COLR); break; - case GL_ONE_MINUS_SRC_COLOR: - func |= DST_BLND_FACT(BLENDFACT_INV_SRC_COLR); break; - case GL_DST_ALPHA: func |= DST_BLND_FACT(BLENDFACT_DST_ALPHA); break; - case GL_ONE_MINUS_DST_ALPHA: - func |= DST_BLND_FACT(BLENDFACT_INV_DST_ALPHA); break; - case GL_CONSTANT_COLOR_EXT: - func |= DST_BLND_FACT(BLENDFACT_CONST_COLOR); break; - case GL_ONE_MINUS_CONSTANT_COLOR_EXT: - func |= DST_BLND_FACT(BLENDFACT_INV_CONST_COLOR); - break; - case GL_CONSTANT_ALPHA_EXT: - func |= DST_BLND_FACT(BLENDFACT_CONST_ALPHA); break; - case GL_ONE_MINUS_CONSTANT_ALPHA_EXT: - func |= DST_BLND_FACT(BLENDFACT_INV_CONST_ALPHA); - break; - default: return; - } - - imesa->dirty |= I830_UPLOAD_CTX; - imesa->Setup[I830_CTXREG_IALPHAB] &= ~SRC_DST_ABLEND_MASK; - imesa->Setup[I830_CTXREG_STATE1] &= ~SRC_DST_BLND_MASK; - imesa->Setup[I830_CTXREG_STATE1] |= func; - /* Insure Independant Alpha Blend is really disabled if need be */ + /* Insure Independant Alpha Blend is really enabled if + * Blending is already enabled. + */ i830EvalLogicOpBlendState(ctx); - - if(0) fprintf(stderr, "STATE1 : 0x%x\n", imesa->Setup[I830_CTXREG_STATE1]); } -static void i830DDDepthFunc(GLcontext *ctx, GLenum func) +static void i830DepthFunc(GLcontext *ctx, GLenum func) { i830ContextPtr imesa = I830_CONTEXT(ctx); int test = 0; @@ -564,52 +515,33 @@ static void i830DDDepthFunc(GLcontext *ctx, GLenum func) if(I830_DEBUG&DEBUG_VERBOSE_TRACE) fprintf(stderr, "%s\n", __FUNCTION__); - FLUSH_BATCH(imesa); - switch(func) { - case GL_NEVER: - test = COMPAREFUNC_NEVER; - break; - case GL_LESS: - test = COMPAREFUNC_LESS; - break; - case GL_LEQUAL: - test = COMPAREFUNC_LEQUAL; - break; - case GL_GREATER: - test = COMPAREFUNC_GREATER; - break; - case GL_GEQUAL: - test = COMPAREFUNC_GEQUAL; - break; - case GL_NOTEQUAL: - test = COMPAREFUNC_NOTEQUAL; - break; - case GL_EQUAL: - test = COMPAREFUNC_EQUAL; - break; - case GL_ALWAYS: - test = COMPAREFUNC_ALWAYS; - break; + case GL_NEVER: test = COMPAREFUNC_NEVER; break; + case GL_LESS: test = COMPAREFUNC_LESS; break; + case GL_LEQUAL: test = COMPAREFUNC_LEQUAL; break; + case GL_GREATER: test = COMPAREFUNC_GREATER; break; + case GL_GEQUAL: test = COMPAREFUNC_GEQUAL; break; + case GL_NOTEQUAL: test = COMPAREFUNC_NOTEQUAL; break; + case GL_EQUAL: test = COMPAREFUNC_EQUAL; break; + case GL_ALWAYS: test = COMPAREFUNC_ALWAYS; break; default: return; } - imesa->dirty |= I830_UPLOAD_CTX; + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); imesa->Setup[I830_CTXREG_STATE3] &= ~DEPTH_TEST_FUNC_MASK; imesa->Setup[I830_CTXREG_STATE3] |= (ENABLE_DEPTH_TEST_FUNC | DEPTH_TEST_FUNC(test)); } -static void i830DDDepthMask(GLcontext *ctx, GLboolean flag) +static void i830DepthMask(GLcontext *ctx, GLboolean flag) { i830ContextPtr imesa = I830_CONTEXT(ctx); if(I830_DEBUG&DEBUG_VERBOSE_TRACE) fprintf(stderr, "%s flag (%d)\n", __FUNCTION__, flag); - FLUSH_BATCH(imesa); + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); - imesa->dirty |= I830_UPLOAD_CTX; imesa->Setup[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK; if (flag) @@ -618,13 +550,20 @@ static void i830DDDepthMask(GLcontext *ctx, GLboolean flag) imesa->Setup[I830_CTXREG_ENABLES_2] |= DISABLE_DEPTH_WRITE; } +/* The i830 has no stipple hardware */ +static void i830PolygonStipple(GLcontext *ctx, const GLubyte *mask) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + + FALLBACK(imesa, I830_FALLBACK_STIPPLE, ctx->Polygon.StippleFlag); +} + /* ============================================================= * Hardware clipping */ - -static void i830DDScissor( GLcontext *ctx, GLint x, GLint y, - GLsizei w, GLsizei h ) -{ +static void i830Scissor(GLcontext *ctx, GLint x, GLint y, + GLsizei w, GLsizei h) +{ i830ContextPtr imesa = I830_CONTEXT(ctx); int x1 = x; int y1 = imesa->driDrawable->h - (y + h); @@ -640,13 +579,12 @@ static void i830DDScissor( GLcontext *ctx, GLint x, GLint y, if(x2 < 0) x2 = 0; if(y2 < 0) y2 = 0; - FLUSH_BATCH(imesa); - imesa->dirty |= I830_UPLOAD_BUFFERS; + I830_STATECHANGE(imesa, I830_UPLOAD_BUFFERS); imesa->BufferSetup[I830_DESTREG_SR1] = (y1 << 16) | (x1 & 0xffff); imesa->BufferSetup[I830_DESTREG_SR2] = (y2 << 16) | (x2 & 0xffff); } -static void i830DDLogicOp( GLcontext *ctx, GLenum opcode ) +static void i830LogicOp(GLcontext *ctx, GLenum opcode) { i830ContextPtr imesa = I830_CONTEXT(ctx); int tmp = 0; @@ -654,9 +592,6 @@ static void i830DDLogicOp( GLcontext *ctx, GLenum opcode ) if(I830_DEBUG&DEBUG_VERBOSE_TRACE) fprintf(stderr, "%s\n", __FUNCTION__); - - FLUSH_BATCH( imesa ); - switch(opcode) { case GL_CLEAR: tmp = LOGICOP_CLEAR; break; case GL_AND: tmp = LOGICOP_AND; break; @@ -677,106 +612,72 @@ static void i830DDLogicOp( GLcontext *ctx, GLenum opcode ) default: return; } - imesa->dirty |= I830_UPLOAD_CTX; + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); imesa->Setup[I830_CTXREG_STATE4] &= ~LOGICOP_MASK; imesa->Setup[I830_CTXREG_STATE4] |= LOGIC_OP_FUNC(tmp); - if(0) fprintf(stderr, "Logicop : 0x%x, state4 : 0x%x\n", tmp, imesa->Setup[I830_CTXREG_STATE4]); - /* Insure all the enables are correct */ + + /* Make sure all the enables are correct */ i830EvalLogicOpBlendState(ctx); } -static GLboolean i830DDSetDrawBuffer(GLcontext *ctx, GLenum mode ) +/* Fallback to swrast for select and feedback. + */ +static void i830RenderMode( GLcontext *ctx, GLenum mode ) { i830ContextPtr imesa = I830_CONTEXT(ctx); + FALLBACK( imesa, I830_FALLBACK_RENDERMODE, (mode != GL_RENDER) ); +} - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s\n", __FUNCTION__); - - FLUSH_BATCH(imesa); +static GLboolean i830SetDrawBuffer(GLcontext *ctx, GLenum mode ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); - imesa->Fallback &= ~I830_FALLBACK_DRAW_BUFFER; - if(mode == GL_FRONT_LEFT) { - imesa->readMap = (char *)imesa->driScreen->pFB; + I830_FIREVERTICES(imesa); + I830_STATECHANGE(imesa, I830_UPLOAD_BUFFERS); + + imesa->BufferSetup[I830_DESTREG_CBUFADDR] = imesa->i830Screen->fbOffset; + imesa->drawMap = (char *)imesa->driScreen->pFB; - imesa->BufferSetup[I830_DESTREG_CBUFADDR] = - imesa->i830Screen->fbOffset; - imesa->dirty |= I830_UPLOAD_BUFFERS; + imesa->readMap = (char *)imesa->driScreen->pFB; i830XMesaSetFrontClipRects( imesa ); + FALLBACK( imesa, I830_FALLBACK_DRAW_BUFFER, GL_FALSE ); return GL_TRUE; } else if(mode == GL_BACK_LEFT) { - imesa->readMap = imesa->i830Screen->back.map; - imesa->drawMap = (char *)imesa->i830Screen->back.map; - imesa->BufferSetup[I830_DESTREG_CBUFADDR] = - imesa->i830Screen->backOffset; - imesa->dirty |= I830_UPLOAD_BUFFERS; - i830XMesaSetBackClipRects( imesa ); - return GL_TRUE; - } + I830_FIREVERTICES(imesa); + I830_STATECHANGE(imesa, I830_UPLOAD_BUFFERS); - imesa->Fallback |= I830_FALLBACK_DRAW_BUFFER; - return GL_FALSE; -} - -static void i830DDSetReadBuffer(GLcontext *ctx, GLframebuffer *colorBuffer, - GLenum mode ) -{ - i830ContextPtr imesa = I830_CONTEXT(ctx); - - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s\n", __FUNCTION__); + imesa->BufferSetup[I830_DESTREG_CBUFADDR] = + imesa->i830Screen->backOffset; - if(mode == GL_FRONT_LEFT) { - imesa->readMap = (char *)imesa->driScreen->pFB; - imesa->Fallback &= ~I830_FALLBACK_READ_BUFFER; - } else if(mode == GL_BACK_LEFT) { + imesa->drawMap = imesa->i830Screen->back.map; imesa->readMap = imesa->i830Screen->back.map; - imesa->Fallback &= ~I830_FALLBACK_READ_BUFFER; + i830XMesaSetBackClipRects( imesa ); + FALLBACK( imesa, I830_FALLBACK_DRAW_BUFFER, GL_FALSE ); + return GL_TRUE; } else { - imesa->Fallback |= I830_FALLBACK_READ_BUFFER; + FALLBACK( imesa, I830_FALLBACK_DRAW_BUFFER, GL_TRUE ); + return GL_FALSE; } } -static void i830DDSetColor(GLcontext *ctx, - GLubyte r, GLubyte g, - GLubyte b, GLubyte a ) +static void i830ClearColor(GLcontext *ctx, const GLchan color[4]) { i830ContextPtr imesa = I830_CONTEXT(ctx); - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__, - r, g, b, a); + imesa->clear_red = color[RCOMP]; + imesa->clear_green = color[GCOMP]; + imesa->clear_blue = color[BCOMP]; + imesa->clear_alpha = color[ACOMP]; - imesa->MonoColor = i830PackColor( imesa->i830Screen->fbFormat, r, g, b, a ); - if(I830_DEBUG&DEBUG_VERBOSE_STATE) - fprintf(stderr, "[%s] MonoColor = 0x%08x\n", __FUNCTION__, - imesa->MonoColor); + imesa->ClearColor = i830PackColor(imesa->i830Screen->fbFormat, + color[RCOMP], + color[GCOMP], + color[BCOMP], + color[ACOMP] ); } - -static void i830DDClearColor(GLcontext *ctx, - GLubyte r, GLubyte g, - GLubyte b, GLubyte a ) -{ - i830ContextPtr imesa = I830_CONTEXT(ctx); - - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__, - r, g, b, a); - - imesa->clear_red = r; - imesa->clear_green = g; - imesa->clear_blue = b; - imesa->clear_alpha = a; - - imesa->ClearColor = i830PackColor( imesa->i830Screen->fbFormat, r, g, b, a ); - if(I830_DEBUG&DEBUG_VERBOSE_STATE) - fprintf(stderr, "[%s] ClearColor = 0x%08x\n", __FUNCTION__, - imesa->ClearColor); - -} - -static void i830DDCullFaceFrontFace(GLcontext *ctx, GLenum unused) +static void i830CullFaceFrontFace(GLcontext *ctx, GLenum unused) { i830ContextPtr imesa = I830_CONTEXT(ctx); GLuint mode = CULLMODE_BOTH; @@ -784,9 +685,7 @@ static void i830DDCullFaceFrontFace(GLcontext *ctx, GLenum unused) if(I830_DEBUG&DEBUG_VERBOSE_TRACE) fprintf(stderr, "%s\n", __FUNCTION__); - FLUSH_BATCH(imesa); - - if(ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) { + if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) { mode = CULLMODE_CW; if (ctx->Polygon.CullFaceMode == GL_FRONT) @@ -797,64 +696,14 @@ static void i830DDCullFaceFrontFace(GLcontext *ctx, GLenum unused) imesa->LcsCullMode = mode; - if(ctx->Polygon.CullFlag && ctx->PB->primitive == GL_POLYGON) { - imesa->dirty |= I830_UPLOAD_CTX; - imesa->Setup[I830_CTXREG_STATE3] &= ~CULLMODE_MASK; - imesa->Setup[I830_CTXREG_STATE3] |= ENABLE_CULL_MODE | mode; + if (ctx->Polygon.CullFlag) { + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_STATE3] &= ~CULLMODE_MASK; + imesa->Setup[I830_CTXREG_STATE3] |= ENABLE_CULL_MODE | mode; } } -static void i830DDReducedPrimitiveChange( GLcontext *ctx, GLenum prim ) -{ - i830ContextPtr imesa = I830_CONTEXT(ctx); - - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s %s\n", __FUNCTION__, gl_lookup_enum_by_nr(prim)); - - FLUSH_BATCH(imesa); - imesa->dirty |= I830_UPLOAD_CTX; - imesa->Setup[I830_CTXREG_STATE3] &= ~CULLMODE_MASK; - imesa->Setup[I830_CTXREG_AA] &= ~AA_LINE_ENABLE; - imesa->vertex_prim = PRIM3D_TRILIST; - - switch(ctx->PB->primitive) { - case GL_POLYGON: - if (ctx->Polygon.CullFlag) - imesa->Setup[I830_CTXREG_STATE3] |= (ENABLE_CULL_MODE | - imesa->LcsCullMode); - else - imesa->Setup[I830_CTXREG_STATE3] |= (ENABLE_CULL_MODE | - CULLMODE_NONE); - break; - - case GL_LINE: - case GL_LINES: - imesa->vertex_prim = PRIM3D_LINELIST; - - if(ctx->Line.SmoothFlag) - imesa->Setup[I830_CTXREG_AA] |= AA_LINE_ENABLE; - imesa->Setup[I830_CTXREG_STATE3] |= CULLMODE_NONE; - break; - - case GL_POINT: - case GL_POINTS: - imesa->vertex_prim = PRIM3D_POINTLIST; - imesa->Setup[I830_CTXREG_STATE3] |= CULLMODE_NONE; - default: - imesa->Setup[I830_CTXREG_STATE3] |= CULLMODE_NONE; - break; - } - - if(I830_DEBUG&DEBUG_VERBOSE_STATE) - fprintf(stderr, "[%s] AA(0x%08x) STATE3(0x%08x) vertex_prim 0x%x\n", - __FUNCTION__, - imesa->Setup[I830_CTXREG_AA], - imesa->Setup[I830_CTXREG_STATE3], - imesa->vertex_prim); - -} - -static void i830DDLineWidth( GLcontext *ctx, GLfloat widthf ) +static void i830LineWidth( GLcontext *ctx, GLfloat widthf ) { i830ContextPtr imesa = I830_CONTEXT( ctx ); int width; @@ -864,24 +713,36 @@ static void i830DDLineWidth( GLcontext *ctx, GLfloat widthf ) width = FloatToInt(widthf * 2); CLAMP_SELF(width, 1, 15); + + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); imesa->Setup[I830_CTXREG_STATE5] &= ~FIXED_LINE_WIDTH_MASK; imesa->Setup[I830_CTXREG_STATE5] |= (ENABLE_FIXED_LINE_WIDTH | FIXED_LINE_WIDTH(width)); +} - imesa->dirty |= I830_UPLOAD_CTX; +static void i830PointSize(GLcontext *ctx, GLfloat size) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + GLint point_size = FloatToInt(size); + + if(I830_DEBUG&DEBUG_VERBOSE_TRACE) + fprintf(stderr, "%s\n", __FUNCTION__); + + CLAMP_SELF(point_size, 1, 256); + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_STATE5] &= ~FIXED_POINT_WIDTH_MASK; + imesa->Setup[I830_CTXREG_STATE5] |= (ENABLE_FIXED_POINT_WIDTH | + FIXED_POINT_WIDTH(point_size)); } + /* ============================================================= * Color masks */ -/* This only deals with ColorMask for rendering, clears need to update - * a planemask for the clearing blit. This is to be done. - */ - -static GLboolean i830DDColorMask(GLcontext *ctx, - GLboolean r, GLboolean g, - GLboolean b, GLboolean a ) +static void i830ColorMask(GLcontext *ctx, + GLboolean r, GLboolean g, + GLboolean b, GLboolean a) { i830ContextPtr imesa = I830_CONTEXT( ctx ); GLuint tmp = 0; @@ -903,31 +764,29 @@ static GLboolean i830DDColorMask(GLcontext *ctx, ((!a) << WRITEMASK_ALPHA_SHIFT); if(tmp != imesa->Setup[I830_CTXREG_ENABLES_2]) { - FLUSH_BATCH(imesa); + I830_FIREVERTICES(imesa); imesa->dirty |= I830_UPLOAD_CTX; imesa->Setup[I830_CTXREG_ENABLES_2] = tmp; if(I830_DEBUG&DEBUG_VERBOSE_STATE) fprintf(stderr, "[%s] enables 2 = 0x%08x\n", __FUNCTION__, tmp); } - - /* Always return false so s/w fallbacks are correct */ - return GL_FALSE; } -static void i830DDLightModelfv(GLcontext *ctx, GLenum pname, - const GLfloat *param) + +static void i830LightModelfv(GLcontext *ctx, GLenum pname, + const GLfloat *param) { if(I830_DEBUG&DEBUG_VERBOSE_TRACE) fprintf(stderr, "%s\n", __FUNCTION__); if(pname == GL_LIGHT_MODEL_COLOR_CONTROL) { i830ContextPtr imesa = I830_CONTEXT( ctx ); - FLUSH_BATCH(imesa); - imesa->dirty |= I830_UPLOAD_CTX; + + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_SPEC_ADD_MASK; - if(ctx->Texture.ReallyEnabled && + if(ctx->Texture._ReallyEnabled && ctx->Light.Enabled && ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) imesa->Setup[I830_CTXREG_ENABLES_1] |= ENABLE_SPEC_ADD; @@ -937,192 +796,167 @@ static void i830DDLightModelfv(GLcontext *ctx, GLenum pname, if(I830_DEBUG&DEBUG_VERBOSE_STATE) fprintf(stderr, "[%s] Enables_1 = 0x%08x\n", __FUNCTION__, imesa->Setup[I830_CTXREG_ENABLES_1]); + } +} + +/* In Mesa 3.5 we can reliably do native flatshading. + */ +static void i830ShadeModel(GLcontext *ctx, GLenum mode) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + +#define SHADE_MODE_MASK ((1<<10)|(1<<8)|(1<<6)|(1<<4)) + + imesa->Setup[I830_CTXREG_STATE3] &= ~SHADE_MODE_MASK; + + if (mode == GL_FLAT) { + imesa->Setup[I830_CTXREG_STATE3] |= (ALPHA_SHADE_MODE(SHADE_MODE_FLAT) | + FOG_SHADE_MODE(SHADE_MODE_FLAT) | + SPEC_SHADE_MODE(SHADE_MODE_FLAT) | + COLOR_SHADE_MODE(SHADE_MODE_FLAT)); + } else { + imesa->Setup[I830_CTXREG_STATE3] |= (ALPHA_SHADE_MODE(SHADE_MODE_LINEAR) | + FOG_SHADE_MODE(SHADE_MODE_LINEAR) | + SPEC_SHADE_MODE(SHADE_MODE_LINEAR) | + COLOR_SHADE_MODE(SHADE_MODE_LINEAR)); } } /* ============================================================= * Fog */ -static void i830DDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param) +static void i830Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *param) { i830ContextPtr imesa = I830_CONTEXT(ctx); if(I830_DEBUG&DEBUG_VERBOSE_TRACE) fprintf(stderr, "%s\n", __FUNCTION__); - if(pname == GL_FOG_COLOR) { + if (pname == GL_FOG_COLOR) { GLuint color = (((GLubyte)(ctx->Fog.Color[0]*255.0F) << 16) | ((GLubyte)(ctx->Fog.Color[1]*255.0F) << 8) | ((GLubyte)(ctx->Fog.Color[2]*255.0F) << 0)); - imesa->dirty |= I830_UPLOAD_CTX; + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); imesa->Setup[I830_CTXREG_FOGCOLOR] = (STATE3D_FOG_COLOR_CMD | color); - - if(I830_DEBUG&DEBUG_VERBOSE_STATE) - fprintf(stderr, "[%s] FogColor = 0x%08x\n", __FUNCTION__, - imesa->Setup[I830_CTXREG_FOGCOLOR]); - } } - /* ============================================================= */ -static void i830DDEnable(GLcontext *ctx, GLenum cap, GLboolean state) +static void i830Enable(GLcontext *ctx, GLenum cap, GLboolean state) { i830ContextPtr imesa = I830_CONTEXT(ctx); - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s cap(%s) state(%d)\n", __FUNCTION__, - gl_lookup_enum_by_nr(cap), state); - switch(cap) { case GL_LIGHTING: - FLUSH_BATCH(imesa); - imesa->dirty |= I830_UPLOAD_CTX; - imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_SPEC_ADD_MASK; + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_SPEC_ADD_MASK; - if (ctx->Texture.ReallyEnabled && - ctx->Light.Enabled && - ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) - imesa->Setup[I830_CTXREG_ENABLES_1] |= ENABLE_SPEC_ADD; - else - imesa->Setup[I830_CTXREG_ENABLES_1] |= DISABLE_SPEC_ADD; + if (ctx->Texture._ReallyEnabled && + ctx->Light.Enabled && + ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) + imesa->Setup[I830_CTXREG_ENABLES_1] |= ENABLE_SPEC_ADD; + else + imesa->Setup[I830_CTXREG_ENABLES_1] |= DISABLE_SPEC_ADD; + + break; - break; case GL_ALPHA_TEST: - FLUSH_BATCH(imesa); - imesa->dirty |= I830_UPLOAD_CTX; - imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_ALPHA_TEST_MASK; - if(state) - imesa->Setup[I830_CTXREG_ENABLES_1] |= ENABLE_ALPHA_TEST; - else - imesa->Setup[I830_CTXREG_ENABLES_1] |= DISABLE_ALPHA_TEST; - break; + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_ALPHA_TEST_MASK; + if(state) + imesa->Setup[I830_CTXREG_ENABLES_1] |= ENABLE_ALPHA_TEST; + else + imesa->Setup[I830_CTXREG_ENABLES_1] |= DISABLE_ALPHA_TEST; + + break; case GL_BLEND: case GL_COLOR_LOGIC_OP: case GL_INDEX_LOGIC_OP: - i830EvalLogicOpBlendState(ctx); - break; - case GL_DITHER: - { - unsigned int temp; + i830EvalLogicOpBlendState(ctx); + break; - FLUSH_BATCH(imesa); - temp = imesa->Setup[I830_CTXREG_ENABLES_2]; - - temp &= ~ENABLE_DITHER; + case GL_DITHER: + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_ENABLES_2] &= ~ENABLE_DITHER; - if(state) temp |= ENABLE_DITHER; - else temp |= DISABLE_DITHER; - - if(temp != imesa->Setup[I830_CTXREG_ENABLES_2]) { - imesa->dirty |= I830_UPLOAD_CTX; - imesa->Setup[I830_CTXREG_ENABLES_2] = temp; - } - } - break; + if(state) + imesa->Setup[I830_CTXREG_ENABLES_2] |= ENABLE_DITHER; + else + imesa->Setup[I830_CTXREG_ENABLES_2] |= DISABLE_DITHER; + break; case GL_DEPTH_TEST: - FLUSH_BATCH(imesa); - imesa->dirty |= I830_UPLOAD_CTX; - imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK; - - if(state) - imesa->Setup[I830_CTXREG_ENABLES_1] |= ENABLE_DEPTH_TEST; - else - imesa->Setup[I830_CTXREG_ENABLES_1] |= DISABLE_DEPTH_TEST; - break; + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK; - case GL_SCISSOR_TEST: - FLUSH_BATCH(imesa); + if(state) + imesa->Setup[I830_CTXREG_ENABLES_1] |= ENABLE_DEPTH_TEST; + else + imesa->Setup[I830_CTXREG_ENABLES_1] |= DISABLE_DEPTH_TEST; + break; - if(state) - imesa->BufferSetup[I830_DESTREG_SENABLE] = (STATE3D_SCISSOR_ENABLE_CMD | - ENABLE_SCISSOR_RECT); + case GL_SCISSOR_TEST: + I830_STATECHANGE(imesa, I830_UPLOAD_BUFFERS); + + if (state) + imesa->BufferSetup[I830_DESTREG_SENABLE] = + (STATE3D_SCISSOR_ENABLE_CMD | + ENABLE_SCISSOR_RECT); else - imesa->BufferSetup[I830_DESTREG_SENABLE] = (STATE3D_SCISSOR_ENABLE_CMD | - DISABLE_SCISSOR_RECT); - imesa->dirty |= I830_UPLOAD_BUFFERS; - break; + imesa->BufferSetup[I830_DESTREG_SENABLE] = + (STATE3D_SCISSOR_ENABLE_CMD | + DISABLE_SCISSOR_RECT); - case GL_POLYGON_STIPPLE: - if(ctx->PB->primitive == GL_POLYGON) { - FLUSH_BATCH(imesa); - /* Need a fallback here */ - } + imesa->upload_cliprects = GL_TRUE; break; case GL_LINE_SMOOTH: - if (ctx->PB->primitive == GL_LINE) { - FLUSH_BATCH(imesa); - if(0) fprintf(stderr, "Line smooth hit\n"); - imesa->dirty |= I830_UPLOAD_CTX; - imesa->Setup[I830_CTXREG_AA] &= ~AA_LINE_ENABLE; - /* imesa->Setup[I830_CTXREG_LCS] &= ~LCS_LINEWIDTH_0_5; */ - if (state) { - imesa->Setup[I830_CTXREG_AA] |= AA_LINE_ENABLE; - /* imesa->Setup[I830_CTXREG_LCS] |= LCS_LINEWIDTH_0_5; */ - } else { - imesa->Setup[I830_CTXREG_AA] |= AA_LINE_DISABLE; - /* imesa->Setup[I830_CTXREG_LCS] |= LCS_LINEWIDTH_0_5; */ - } - } - break; - - case GL_POINT_SMOOTH: - if (ctx->PB->primitive == GL_POINT) { - FLUSH_BATCH(imesa); - if(0) fprintf(stderr, "Point smooth hit\n"); - } - break; - - case GL_POLYGON_SMOOTH: - if (ctx->PB->primitive == GL_POLYGON) { - FLUSH_BATCH(imesa); - if(0) fprintf(stderr, "Polygon Smooth hit\n"); + if (imesa->reduced_primitive == GL_LINES) { + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + + imesa->Setup[I830_CTXREG_AA] &= ~AA_LINE_ENABLE; + if(state) + imesa->Setup[I830_CTXREG_AA] |= AA_LINE_ENABLE; + else + imesa->Setup[I830_CTXREG_AA] |= AA_LINE_DISABLE; } break; case GL_FOG: - FLUSH_BATCH(imesa); - imesa->dirty |= I830_UPLOAD_CTX; - imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_FOG_MASK; + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_FOG_MASK; + if(state) + imesa->Setup[I830_CTXREG_ENABLES_1] |= I830_ENABLE_FOG; + else + imesa->Setup[I830_CTXREG_ENABLES_1] |= I830_DISABLE_FOG; + break; + + case GL_CULL_FACE: + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_STATE3] &= ~CULLMODE_MASK; if(state) - imesa->Setup[I830_CTXREG_ENABLES_1] |= I830_ENABLE_FOG; + imesa->Setup[I830_CTXREG_STATE3] |= (ENABLE_CULL_MODE | + imesa->LcsCullMode); else - imesa->Setup[I830_CTXREG_ENABLES_1] |= I830_DISABLE_FOG; + imesa->Setup[I830_CTXREG_STATE3] |= (ENABLE_CULL_MODE | + CULLMODE_NONE); break; - case GL_CULL_FACE: - if (ctx->PB->primitive == GL_POLYGON) { - FLUSH_BATCH(imesa); - imesa->dirty |= I830_UPLOAD_CTX; - imesa->Setup[I830_CTXREG_STATE3] &= ~CULLMODE_MASK; - if (state) - imesa->Setup[I830_CTXREG_STATE3] |= (ENABLE_CULL_MODE | - imesa->LcsCullMode); - else - imesa->Setup[I830_CTXREG_STATE3] |= (ENABLE_CULL_MODE | - CULLMODE_NONE); - } - break; - case GL_TEXTURE_1D: - case GL_TEXTURE_3D: - FLUSH_BATCH(imesa); - imesa->new_state |= I830_NEW_TEXTURE; - break; case GL_TEXTURE_2D: - FLUSH_BATCH(imesa); - imesa->new_state |= I830_NEW_TEXTURE; - - imesa->dirty |= I830_UPLOAD_CTX; + if(0) { + if(state) fprintf(stderr, "\n\nTexturing Enabled\n\n"); + else fprintf(stderr, "\n\nTexturing Disabled\n\n"); + } + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_SPEC_ADD_MASK; - if (ctx->Texture.ReallyEnabled && + if (ctx->Texture._ReallyEnabled && ctx->Light.Enabled && ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) imesa->Setup[I830_CTXREG_ENABLES_1] |= ENABLE_SPEC_ADD; @@ -1131,56 +965,29 @@ static void i830DDEnable(GLcontext *ctx, GLenum cap, GLboolean state) break; case GL_STENCIL_TEST: - FLUSH_BATCH(imesa); if(imesa->hw_stencil) { - imesa->dirty |= I830_UPLOAD_CTX; - imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_STENCIL_TEST; - - if(state) { - if(0) fprintf(stderr, "Enabling stencil test\n"); - imesa->Setup[I830_CTXREG_ENABLES_1] |= ENABLE_STENCIL_TEST; - } else { - if(0) fprintf(stderr, "Disabling stencil test\n"); - imesa->Setup[I830_CTXREG_ENABLES_1] |= DISABLE_STENCIL_TEST; - } - - if(I830_DEBUG&DEBUG_VERBOSE_STATE) - fprintf(stderr, "%s : state4 : 0x%x, stentst : 0x%x," - " enables_1 : 0x%x\n", __FUNCTION__, - imesa->Setup[I830_CTXREG_STATE4], - imesa->Setup[I830_CTXREG_STENCILTST], - imesa->Setup[I830_CTXREG_ENABLES_1]); - - } else if (state) { - imesa->Fallback |= I830_FALLBACK_STENCIL; + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_STENCIL_TEST; + + if(state) { + imesa->Setup[I830_CTXREG_ENABLES_1] |= ENABLE_STENCIL_TEST; + } else { + imesa->Setup[I830_CTXREG_ENABLES_1] |= DISABLE_STENCIL_TEST; + } + + if(I830_DEBUG&DEBUG_VERBOSE_STATE) + fprintf(stderr, "%s : state4 : 0x%x, stentst : 0x%x," + " enables_1 : 0x%x\n", __FUNCTION__, + imesa->Setup[I830_CTXREG_STATE4], + imesa->Setup[I830_CTXREG_STENCILTST], + imesa->Setup[I830_CTXREG_ENABLES_1]); } else { - imesa->Fallback &= ~I830_FALLBACK_STENCIL; + FALLBACK( imesa, I830_FALLBACK_STENCIL, state ); } - + break; default: - ; - } -} - - - -/* ============================================================= - */ - - -void i830DDUpdateHwState( GLcontext *ctx ) -{ - i830ContextPtr imesa = I830_CONTEXT(ctx); - - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s\n", __FUNCTION__); - - if(imesa->new_state & I830_NEW_TEXTURE) { - FLUSH_BATCH(imesa); - i830UpdateTextureState( ctx ); + ; } - - imesa->new_state = 0; } @@ -1194,7 +1001,7 @@ void i830EmitDrawingRectangle( i830ContextPtr imesa ) int y1 = y0 + dPriv->h; /* Don't set drawing rectangle */ - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) + if(DEBUGGING) fprintf(stderr, "%s x0(%d) x1(%d) y0(%d) y1(%d)\n", __FUNCTION__, x0, x1, y0, y1); @@ -1215,9 +1022,18 @@ void i830EmitDrawingRectangle( i830ContextPtr imesa ) */ imesa->BufferSetup[I830_DESTREG_DR2] = ((y0<<16) | x0); imesa->BufferSetup[I830_DESTREG_DR3] = (((y1+1)<<16) | (x1+1)); + + + /* Just add in our dirty flag, since we might be called when locked */ + /* Might want to modify how this is done. */ +#if 0 + if (imesa->vertex_low != imesa->vertex_last_prim) + i830FlushPrimsLocked(imesa); +#endif + imesa->dirty |= I830_UPLOAD_BUFFERS; - if(I830_DEBUG&DEBUG_VERBOSE_STATE) + if(0) fprintf(stderr, "[%s] DR2(0x%08x) DR3(0x%08x) DR4(0x%08x)\n", __FUNCTION__, imesa->BufferSetup[I830_DESTREG_DR2], @@ -1225,102 +1041,130 @@ void i830EmitDrawingRectangle( i830ContextPtr imesa ) imesa->BufferSetup[I830_DESTREG_DR4]); } +/* This could be done in hardware, will do once I have the driver + * up and running. + */ +static void i830CalcViewport( GLcontext *ctx ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + const GLfloat *v = ctx->Viewport._WindowMap.m; + GLfloat *m = imesa->ViewportMatrix.m; + /* See also i830_translate_vertex. SUBPIXEL adjustments can be done + * via state vars, too. + */ + m[MAT_SX] = v[MAT_SX]; + m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X; + m[MAT_SY] = - v[MAT_SY]; + m[MAT_TY] = - v[MAT_TY] + imesa->driDrawable->h + SUBPIXEL_Y; + m[MAT_SZ] = v[MAT_SZ] * imesa->depth_scale; + m[MAT_TZ] = v[MAT_TZ] * imesa->depth_scale; +} -static void i830DDPrintDirty( const char *msg, GLuint state ) +static void i830Viewport( GLcontext *ctx, + GLint x, GLint y, + GLsizei width, GLsizei height ) { - fprintf(stderr, "%s (0x%x): %s%s%s%s%s\n", + i830CalcViewport( ctx ); +} + +static void i830DepthRange( GLcontext *ctx, + GLclampd nearval, GLclampd farval ) +{ + i830CalcViewport( ctx ); +} + +void i830PrintDirty( const char *msg, GLuint state ) +{ + fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s\n", msg, (unsigned int) state, - (state & I830_UPLOAD_TEX0_IMAGE) ? "upload-tex0, " : "", - (state & I830_UPLOAD_TEX1_IMAGE) ? "upload-tex1, " : "", + (state & I830_UPLOAD_TEX0) ? "upload-tex0, " : "", + (state & I830_UPLOAD_TEX1) ? "upload-tex1, " : "", (state & I830_UPLOAD_CTX) ? "upload-ctx, " : "", (state & I830_UPLOAD_BUFFERS) ? "upload-bufs, " : "", - (state & I830_UPLOAD_CLIPRECTS) ? "upload-cliprects, " : "" + (state & I830_UPLOAD_TEXBLEND0) ? "upload-blend0, " : "", + (state & I830_UPLOAD_TEXBLEND1) ? "upload-blend1, " : "" ); } - /* Push the state into the sarea and/or texture memory. */ void i830EmitHwStateLocked( i830ContextPtr imesa ) { int i; - if (I830_DEBUG & DEBUG_VERBOSE_API) - i830DDPrintDirty( "\n\n\ni830EmitHwStateLocked", imesa->dirty ); + if (DEBUGGING) + i830PrintDirty( "\n\n\ni830EmitHwStateLocked", imesa->dirty ); - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) + if (DEBUGGING) fprintf(stderr, "%s\n", __FUNCTION__); - if (imesa->dirty & ~I830_UPLOAD_CLIPRECTS) { - if ((imesa->dirty & I830_UPLOAD_TEX0_IMAGE) && imesa->CurrentTexObj[0]) - i830UploadTexImages(imesa, imesa->CurrentTexObj[0]); - - if ((imesa->dirty & I830_UPLOAD_TEX1_IMAGE) && imesa->CurrentTexObj[1]) - i830UploadTexImages(imesa, imesa->CurrentTexObj[1]); - - if (imesa->dirty & I830_UPLOAD_CTX) - memcpy( imesa->sarea->ContextState, - imesa->Setup, - sizeof(imesa->Setup) ); - - for(i = 0; i < I830_TEXTURE_COUNT; i++) { - if ((imesa->dirty & I830_UPLOAD_TEX_N(i)) && imesa->CurrentTexObj[i]) { - imesa->sarea->dirty |= I830_UPLOAD_TEX_N(i); - memcpy(imesa->sarea->TexState[i], - imesa->CurrentTexObj[i]->Setup, - sizeof(imesa->sarea->TexState[i])); - } + if ((imesa->dirty & I830_UPLOAD_TEX0_IMAGE) && imesa->CurrentTexObj[0]) + i830UploadTexImages(imesa, imesa->CurrentTexObj[0]); + if ((imesa->dirty & I830_UPLOAD_TEX1_IMAGE) && imesa->CurrentTexObj[1]) + i830UploadTexImages(imesa, imesa->CurrentTexObj[1]); + if (imesa->dirty & I830_UPLOAD_CTX) { + memcpy( imesa->sarea->ContextState, + imesa->Setup, sizeof(imesa->Setup) ); + } + + for(i = 0; i < I830_TEXTURE_COUNT; i++) { + if ((imesa->dirty & I830_UPLOAD_TEX_N(i)) && imesa->CurrentTexObj[i]) { + imesa->sarea->dirty |= I830_UPLOAD_TEX_N(i); + memcpy(imesa->sarea->TexState[i], + imesa->CurrentTexObj[i]->Setup, + sizeof(imesa->sarea->TexState[i])); + /* Update the LRU usage */ + i830UpdateTexLRU(imesa, imesa->CurrentTexObj[i]); } + } + /* Need to figure out if texturing state, or enable changed. */ - /* Need to figure out if texturing state, or enable changed. */ - - for(i = 0; i < I830_TEXBLEND_COUNT; i++) { - if (imesa->dirty & I830_UPLOAD_TEXBLEND_N(i)) { - imesa->sarea->dirty |= I830_UPLOAD_TEXBLEND_N(i); - memcpy(imesa->sarea->TexBlendState[i], - imesa->TexBlend[i], - imesa->TexBlendWordsUsed[i] * 4); - imesa->sarea->TexBlendStateWordsUsed[i] = - imesa->TexBlendWordsUsed[i]; - } + for(i = 0; i < I830_TEXBLEND_COUNT; i++) { + if (imesa->dirty & I830_UPLOAD_TEXBLEND_N(i)) { + imesa->sarea->dirty |= I830_UPLOAD_TEXBLEND_N(i); + memcpy(imesa->sarea->TexBlendState[i],imesa->TexBlend[i], + imesa->TexBlendWordsUsed[i] * 4); + imesa->sarea->TexBlendStateWordsUsed[i] = + imesa->TexBlendWordsUsed[i]; } + } - if (imesa->dirty & I830_UPLOAD_BUFFERS) - memcpy( imesa->sarea->BufferState, - imesa->BufferSetup, - sizeof(imesa->BufferSetup) ); + if (imesa->dirty & I830_UPLOAD_BUFFERS) { + if (DEBUGGING) + fprintf(stderr,"\nCopying BufferState to shared area\n"); + memcpy( imesa->sarea->BufferState,imesa->BufferSetup, + sizeof(imesa->BufferSetup) ); + } - if (imesa->dirty & I830_UPLOAD_TEX_PALETTE_SHARED) { - memcpy( imesa->sarea->Palette[0], - imesa->palette, - sizeof(imesa->sarea->Palette[0])); - } else { - i830TextureObjectPtr p; - - if (imesa->dirty & I830_UPLOAD_TEX_PALETTE_N(0)) { - p = imesa->CurrentTexObj[0]; - memcpy( imesa->sarea->Palette[0], - p->palette, - sizeof(imesa->sarea->Palette[0])); - } - if (imesa->dirty & I830_UPLOAD_TEX_PALETTE_N(1)) { - p = imesa->CurrentTexObj[1]; - memcpy( imesa->sarea->Palette[1], - p->palette, - sizeof(imesa->sarea->Palette[1])); - } + if (imesa->dirty & I830_UPLOAD_TEX_PALETTE_SHARED) { + memcpy( imesa->sarea->Palette[0],imesa->palette, + sizeof(imesa->sarea->Palette[0])); + } else { + i830TextureObjectPtr p; + if (imesa->dirty & I830_UPLOAD_TEX_PALETTE_N(0)) { + p = imesa->CurrentTexObj[0]; + memcpy( imesa->sarea->Palette[0],p->palette, + sizeof(imesa->sarea->Palette[0])); + } + if (imesa->dirty & I830_UPLOAD_TEX_PALETTE_N(1)) { + p = imesa->CurrentTexObj[1]; + memcpy( imesa->sarea->Palette[1], + p->palette, + sizeof(imesa->sarea->Palette[1])); } - - imesa->sarea->dirty |= (imesa->dirty & - ~(I830_UPLOAD_TEX_MASK | - I830_UPLOAD_TEXBLEND_MASK)); - imesa->dirty &= I830_UPLOAD_CLIPRECTS; } + imesa->sarea->dirty |= (imesa->dirty & ~(I830_UPLOAD_TEX_MASK | + I830_UPLOAD_TEXBLEND_MASK)); + + imesa->upload_cliprects = GL_TRUE; + imesa->dirty = 0; } -void i830DDInitState( i830ContextPtr imesa ) + +void i830DDInitState( GLcontext *ctx ) { + i830ContextPtr imesa = I830_CONTEXT(ctx); i830ScreenPrivate *i830Screen = imesa->i830Screen; int i, j; @@ -1411,11 +1255,15 @@ void i830DDInitState( i830ContextPtr imesa ) memset(imesa->Setup, 0, sizeof(imesa->Setup)); - imesa->Setup[I830_CTXREG_VF] = VRTX_FORMAT_NTEX(1); - + imesa->Setup[I830_CTXREG_VF] = (STATE3D_VERTEX_FORMAT_CMD | + VRTX_TEX_COORD_COUNT(1) | + VRTX_HAS_DIFFUSE | + VRTX_HAS_SPEC | + VRTX_HAS_XYZW); + imesa->vertex_format = 0; imesa->Setup[I830_CTXREG_VF2] = (STATE3D_VERTEX_FORMAT_2_CMD | VRTX_TEX_SET_0_FMT(TEXCOORDFMT_2D) | - VRTX_TEX_SET_1_FMT(TEXCOORDFMT_2D) | + VRTX_TEX_SET_1_FMT(TEXCOORDFMT_2D) | VRTX_TEX_SET_2_FMT(TEXCOORDFMT_2D) | VRTX_TEX_SET_3_FMT(TEXCOORDFMT_2D)); @@ -1457,41 +1305,41 @@ void i830DDInitState( i830ContextPtr imesa ) } imesa->Setup[I830_CTXREG_STATE1] = (STATE3D_MODES_1_CMD | - ENABLE_COLR_BLND_FUNC | - BLENDFUNC_ADD | - ENABLE_SRC_BLND_FACTOR | - SRC_BLND_FACT(BLENDFACT_ONE) | - ENABLE_DST_BLND_FACTOR | - DST_BLND_FACT(BLENDFACT_ZERO) ); + ENABLE_COLR_BLND_FUNC | + BLENDFUNC_ADD | + ENABLE_SRC_BLND_FACTOR | + SRC_BLND_FACT(BLENDFACT_ONE) | + ENABLE_DST_BLND_FACTOR | + DST_BLND_FACT(BLENDFACT_ZERO) ); imesa->Setup[I830_CTXREG_STATE2] = (STATE3D_MODES_2_CMD | - ENABLE_GLOBAL_DEPTH_BIAS | - GLOBAL_DEPTH_BIAS(0) | - ENABLE_ALPHA_TEST_FUNC | - ALPHA_TEST_FUNC(COMPAREFUNC_ALWAYS) | - ALPHA_REF_VALUE(0) ); + ENABLE_GLOBAL_DEPTH_BIAS | + GLOBAL_DEPTH_BIAS(0) | + ENABLE_ALPHA_TEST_FUNC | + ALPHA_TEST_FUNC(COMPAREFUNC_ALWAYS) | + ALPHA_REF_VALUE(0) ); imesa->Setup[I830_CTXREG_STATE3] = (STATE3D_MODES_3_CMD | - ENABLE_DEPTH_TEST_FUNC | - DEPTH_TEST_FUNC(COMPAREFUNC_LESS) | - ENABLE_ALPHA_SHADE_MODE | - ALPHA_SHADE_MODE(SHADE_MODE_LINEAR) | - ENABLE_FOG_SHADE_MODE | - FOG_SHADE_MODE(SHADE_MODE_LINEAR) | - ENABLE_SPEC_SHADE_MODE | - SPEC_SHADE_MODE(SHADE_MODE_LINEAR) | - ENABLE_COLOR_SHADE_MODE | - COLOR_SHADE_MODE(SHADE_MODE_LINEAR) | - ENABLE_CULL_MODE | - CULLMODE_NONE); + ENABLE_DEPTH_TEST_FUNC | + DEPTH_TEST_FUNC(COMPAREFUNC_LESS) | + ENABLE_ALPHA_SHADE_MODE | + ALPHA_SHADE_MODE(SHADE_MODE_LINEAR) | + ENABLE_FOG_SHADE_MODE | + FOG_SHADE_MODE(SHADE_MODE_LINEAR) | + ENABLE_SPEC_SHADE_MODE | + SPEC_SHADE_MODE(SHADE_MODE_LINEAR) | + ENABLE_COLOR_SHADE_MODE | + COLOR_SHADE_MODE(SHADE_MODE_LINEAR) | + ENABLE_CULL_MODE | + CULLMODE_NONE); imesa->Setup[I830_CTXREG_STATE4] = (STATE3D_MODES_4_CMD | - ENABLE_LOGIC_OP_FUNC | - LOGIC_OP_FUNC(LOGICOP_COPY) | - ENABLE_STENCIL_TEST_MASK | - STENCIL_TEST_MASK(0xff) | - ENABLE_STENCIL_WRITE_MASK | - STENCIL_WRITE_MASK(0xff)); + ENABLE_LOGIC_OP_FUNC | + LOGIC_OP_FUNC(LOGICOP_COPY) | + ENABLE_STENCIL_TEST_MASK | + STENCIL_TEST_MASK(0xff) | + ENABLE_STENCIL_WRITE_MASK | + STENCIL_WRITE_MASK(0xff)); imesa->Setup[I830_CTXREG_STENCILTST] = (STATE3D_STENCIL_TEST_CMD | ENABLE_STENCIL_PARMS | @@ -1513,14 +1361,14 @@ void i830DDInitState( i830ContextPtr imesa ) FIXED_POINT_WIDTH(1) ); imesa->Setup[I830_CTXREG_IALPHAB] = (STATE3D_INDPT_ALPHA_BLEND_CMD | - DISABLE_INDPT_ALPHA_BLEND | - ENABLE_ALPHA_BLENDFUNC | - ABLENDFUNC_ADD); + DISABLE_INDPT_ALPHA_BLEND | + ENABLE_ALPHA_BLENDFUNC | + ABLENDFUNC_ADD); imesa->Setup[I830_CTXREG_FOGCOLOR] = (STATE3D_FOG_COLOR_CMD | - FOG_COLOR_RED(0) | - FOG_COLOR_GREEN(0) | - FOG_COLOR_BLUE(0)); + FOG_COLOR_RED(0) | + FOG_COLOR_GREEN(0) | + FOG_COLOR_BLUE(0)); imesa->Setup[I830_CTXREG_BLENDCOLR0] = (STATE3D_CONST_BLEND_COLOR_CMD); @@ -1528,9 +1376,9 @@ void i830DDInitState( i830ContextPtr imesa ) imesa->Setup[I830_CTXREG_MCSB0] = STATE3D_MAP_COORD_SETBIND_CMD; imesa->Setup[I830_CTXREG_MCSB1] = (TEXBIND_SET3(TEXCOORDSRC_VTXSET_3) | - TEXBIND_SET2(TEXCOORDSRC_VTXSET_2) | - TEXBIND_SET1(TEXCOORDSRC_VTXSET_1) | - TEXBIND_SET0(TEXCOORDSRC_VTXSET_0)); + TEXBIND_SET2(TEXCOORDSRC_VTXSET_2) | + TEXBIND_SET1(TEXCOORDSRC_VTXSET_1) | + TEXBIND_SET0(TEXCOORDSRC_VTXSET_0)); imesa->LcsCullMode = CULLMODE_CW; /* GL default */ @@ -1555,21 +1403,21 @@ void i830DDInitState( i830ContextPtr imesa ) case DV_PF_555: case DV_PF_565: imesa->BufferSetup[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ - DSTORG_VERT_BIAS(0x8) | /* .5 */ - i830Screen->fbFormat | - DEPTH_IS_Z | - DEPTH_FRMT_16_FIXED); + DSTORG_VERT_BIAS(0x8) | /* .5 */ + i830Screen->fbFormat | + DEPTH_IS_Z | + DEPTH_FRMT_16_FIXED); break; case DV_PF_8888: imesa->BufferSetup[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ - DSTORG_VERT_BIAS(0x8) | /* .5 */ - i830Screen->fbFormat | - DEPTH_IS_Z | - DEPTH_FRMT_24_FIXED_8_OTHER); + DSTORG_VERT_BIAS(0x8) | /* .5 */ + i830Screen->fbFormat | + DEPTH_IS_Z | + DEPTH_FRMT_24_FIXED_8_OTHER); break; } imesa->BufferSetup[I830_DESTREG_SENABLE] = (STATE3D_SCISSOR_ENABLE_CMD | - DISABLE_SCISSOR_RECT); + DISABLE_SCISSOR_RECT); imesa->BufferSetup[I830_DESTREG_SR0] = STATE3D_SCISSOR_RECT_0_CMD; imesa->BufferSetup[I830_DESTREG_SR1] = 0; imesa->BufferSetup[I830_DESTREG_SR2] = 0; @@ -1590,86 +1438,64 @@ void i830DDInitState( i830ContextPtr imesa ) } -#define INTERESTED (~(NEW_MODELVIEW|NEW_PROJECTION|\ - NEW_TEXTURE_MATRIX|\ - NEW_USER_CLIP|NEW_CLIENT_STATE)) - -void i830DDUpdateState( GLcontext *ctx ) +static void i830InvalidateState( GLcontext *ctx, GLuint new_state ) { - i830ContextPtr imesa = I830_CONTEXT( ctx ); - - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s\n", __FUNCTION__); - - /* Have to do this here to detect texture fallbacks in time */ - if (imesa->new_state & I830_NEW_TEXTURE) - i830DDUpdateHwState( ctx ); - - - if (ctx->NewState & INTERESTED) { - i830DDChooseRenderState(ctx); - i830ChooseRasterSetupFunc(ctx); - } - - if (0) - fprintf(stderr, "IndirectTriangles %x Fallback %x\n", - imesa->IndirectTriangles, imesa->Fallback); - - if (!imesa->Fallback) { - ctx->IndirectTriangles &= ~DD_SW_RASTERIZE; - ctx->IndirectTriangles |= imesa->IndirectTriangles; - - ctx->Driver.PointsFunc=imesa->PointsFunc; - ctx->Driver.LineFunc=imesa->LineFunc; - ctx->Driver.TriangleFunc=imesa->TriangleFunc; - ctx->Driver.QuadFunc=imesa->QuadFunc; - } + _swrast_InvalidateState( ctx, new_state ); + _swsetup_InvalidateState( ctx, new_state ); + _ac_InvalidateState( ctx, new_state ); + _tnl_InvalidateState( ctx, new_state ); + I830_CONTEXT(ctx)->new_state |= new_state; } - void i830DDInitStateFuncs(GLcontext *ctx) { - i830ContextPtr imesa = I830_CONTEXT( ctx ); - - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s\n", __FUNCTION__); - - ctx->Driver.UpdateState = i830DDUpdateState; - ctx->Driver.Enable = i830DDEnable; - ctx->Driver.AlphaFunc = i830DDAlphaFunc; - ctx->Driver.BlendEquation = i830DDBlendEquation; - ctx->Driver.BlendFunc = i830DDBlendFunc; - ctx->Driver.BlendFuncSeparate = i830DDBlendFuncSeparate; - ctx->Driver.BlendConstColor = i830DDBlendConstColor; - ctx->Driver.DepthFunc = i830DDDepthFunc; - ctx->Driver.DepthMask = i830DDDepthMask; - ctx->Driver.Fogfv = i830DDFogfv; - ctx->Driver.Scissor = i830DDScissor; - ctx->Driver.CullFace = i830DDCullFaceFrontFace; - ctx->Driver.FrontFace = i830DDCullFaceFrontFace; - ctx->Driver.ColorMask = i830DDColorMask; - ctx->Driver.ReducedPrimitiveChange = i830DDReducedPrimitiveChange; - ctx->Driver.RenderStart = i830DDUpdateHwState; - ctx->Driver.RenderFinish = 0; - - ctx->Driver.LineStipple = 0; - ctx->Driver.LineWidth = i830DDLineWidth; - ctx->Driver.LogicOpcode = i830DDLogicOp; - ctx->Driver.SetReadBuffer = i830DDSetReadBuffer; - ctx->Driver.SetDrawBuffer = i830DDSetDrawBuffer; - ctx->Driver.Color = i830DDSetColor; - ctx->Driver.ClearColor = i830DDClearColor; - ctx->Driver.Dither = NULL; - ctx->Driver.Index = 0; - ctx->Driver.ClearIndex = 0; - ctx->Driver.IndexMask = 0; + /* Callbacks for internal Mesa events. + */ + ctx->Driver.UpdateState = i830InvalidateState; - if(imesa->hw_stencil) { - ctx->Driver.StencilFunc = i830DDStencilFunc; - ctx->Driver.StencilMask = i830DDStencilMask; - ctx->Driver.StencilOp = i830DDStencilOp; - } + /* API callbacks + */ + ctx->Driver.AlphaFunc = i830AlphaFunc; + ctx->Driver.BlendEquation = i830BlendEquation; + ctx->Driver.BlendFunc = i830BlendFunc; + ctx->Driver.BlendFuncSeparate = i830BlendFuncSeparate; + ctx->Driver.BlendColor = i830BlendColor; + ctx->Driver.ClearColor = i830ClearColor; + ctx->Driver.ColorMask = i830ColorMask; + ctx->Driver.CullFace = i830CullFaceFrontFace; + ctx->Driver.DepthFunc = i830DepthFunc; + ctx->Driver.DepthMask = i830DepthMask; + ctx->Driver.Enable = i830Enable; + ctx->Driver.Fogfv = i830Fogfv; + ctx->Driver.FrontFace = i830CullFaceFrontFace; + ctx->Driver.LineWidth = i830LineWidth; + ctx->Driver.PointSize = i830PointSize; + ctx->Driver.LogicOpcode = i830LogicOp; + ctx->Driver.PolygonStipple = i830PolygonStipple; + ctx->Driver.RenderMode = i830RenderMode; + ctx->Driver.Scissor = i830Scissor; + ctx->Driver.SetDrawBuffer = i830SetDrawBuffer; + ctx->Driver.ShadeModel = i830ShadeModel; + ctx->Driver.DepthRange = i830DepthRange; + ctx->Driver.Viewport = i830Viewport; + ctx->Driver.LightModelfv = i830LightModelfv; + + ctx->Driver.StencilFunc = i830StencilFunc; + ctx->Driver.StencilMask = i830StencilMask; + ctx->Driver.StencilOp = i830StencilOp; + + /* 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.LightModelfv = i830DDLightModelfv; - ctx->Driver.PointSize = i830DDPointSize; + /* 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/i830/i830_state.h b/xc/lib/GL/mesa/src/drv/i830/i830_state.h new file mode 100644 index 000000000..e6141e7a3 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/i830/i830_state.h @@ -0,0 +1,67 @@ +/************************************************************************** + +Copyright 2001 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS 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$ */ + +/* + * Author: + * Jeff Hartmann <jhartmann@2d3d.com> + * + * Heavily based on the I810 driver, which was written by: + * Keith Whitwell <keith@tungstengraphics.com> + */ +#ifndef _I830_STATE_H +#define _I830_STATE_H + +#include "i830_context.h" +/*Maths macros from mmath.h*/ +#define FloatToInt(F) ((int)(F)) + +/* + * * This function/macro is sensitive to precision. Test carefully + * * if you change it. + * */ +#define FLOAT_COLOR_TO_UBYTE_COLOR(b, f) \ + do { \ + union {GLfloat r; GLuint i; } tmp; \ + tmp.r = f; \ + b = ((tmp.i >= IEEE_ONE) \ + ? ((GLint)tmp.i < 0) ? (GLubyte)0 : (GLubyte)255 \ + : (tmp.r = tmp.r*(255.0F/256.0F) + 32768.0F, \ + (GLubyte)tmp.i)); \ + } while (0) + + + +extern void i830DDInitState( GLcontext *ctx ); +extern void i830DDInitStateFuncs( GLcontext *ctx ); + +extern void i830PrintDirty( const char *msg, GLuint state ); + +extern void i830Fallback( i830ContextPtr imesa, GLuint bit, GLboolean mode ); +#define FALLBACK( imesa, bit, mode ) i830Fallback( imesa, bit, mode ) +#endif diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_tex.c b/xc/lib/GL/mesa/src/drv/i830/i830_tex.c index 783e765b1..a4dbc907c 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_tex.c +++ b/xc/lib/GL/mesa/src/drv/i830/i830_tex.c @@ -1,6 +1,6 @@ /************************************************************************** -Copyright 2001 VA Linux Systems Inc., Fremont, California. +Copyright 2001 2d3d Inc., Delray Beach, FL All Rights Reserved. @@ -25,33 +25,48 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_tex.c,v 1.1 2001/10/04 18:28:21 alanh Exp $ */ +/* $XFree86$ */ /* * Author: - * Jeff Hartmann <jhartmann@valinux.com> + * Jeff Hartmann <jhartmann@2d3d.com> * * Heavily based on the I810 driver, which was written by: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keithw@tungstengraphics.com> */ #include <stdlib.h> #include <stdio.h> #include <GL/gl.h> - -#include "types.h" +#include "glheader.h" +#include "mtypes.h" +#include "mem.h" +#include "simple_list.h" #include "enums.h" -#include "pb.h" -#include "dd.h" +#include "texstore.h" +#include "texformat.h" +#include "swrast/swrast.h" #include "mm.h" -#include "enums.h" -#include "i830_drv.h" +#include "i830_screen.h" +#include "i830_dri.h" +#include "i830_context.h" +#include "i830_tex.h" +#include "i830_state.h" #include "i830_ioctl.h" -#include "simple_list.h" -#include "texutil.h" + +/* + * Compute the 'S2.4' lod bias factor from the floating point OpenGL bias. + */ +static GLuint i830ComputeLodBias(GLfloat bias) +{ + int b = (int) (bias * 16.0) + 12; + if(b > 63) b = 63; + else if (b < -64) b = -64; + return (GLuint) (b & MAP_LOD_MASK); +} static void i830SetTexWrapping(i830TextureObjectPtr tex, GLenum swrap, GLenum twrap) @@ -72,7 +87,9 @@ static void i830SetTexWrapping(i830TextureObjectPtr tex, tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_CLAMP_BORDER); break; + default: break; } + switch( twrap ) { case GL_REPEAT: tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP); @@ -84,15 +101,15 @@ static void i830SetTexWrapping(i830TextureObjectPtr tex, tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_CLAMP_BORDER); break; + default: break; } - } static void i830SetTexFilter(i830ContextPtr imesa, i830TextureObjectPtr t, - GLenum minf, GLenum magf) + GLenum minf, GLenum magf, + GLfloat bias) { - GLuint LastLevel; int minFilt = 0, mipFilt = 0, magFilt = 0; if(I830_DEBUG&DEBUG_VERBOSE_TRACE) @@ -110,6 +127,11 @@ static void i830SetTexFilter(i830ContextPtr imesa, case GL_NEAREST_MIPMAP_NEAREST: minFilt = FILTER_NEAREST; mipFilt = MIPFILTER_NEAREST; + + if(magf == GL_LINEAR) { + bias -= 0.5; + } + break; case GL_LINEAR_MIPMAP_NEAREST: minFilt = FILTER_LINEAR; @@ -118,6 +140,11 @@ static void i830SetTexFilter(i830ContextPtr imesa, case GL_NEAREST_MIPMAP_LINEAR: minFilt = FILTER_NEAREST; mipFilt = MIPFILTER_LINEAR; + + if(magf == GL_LINEAR) { + bias -= 0.5; + } + break; case GL_LINEAR_MIPMAP_LINEAR: minFilt = FILTER_LINEAR; @@ -129,10 +156,6 @@ static void i830SetTexFilter(i830ContextPtr imesa, break; } - I830_SET_FIELD(t->Setup[I830_TEXREG_MF], - MIN_FILTER_MASK | MIP_FILTER_MASK, - MIN_FILTER(minFilt) | mipFilt); - switch (magf) { case GL_NEAREST: magFilt = FILTER_NEAREST; @@ -147,39 +170,15 @@ static void i830SetTexFilter(i830ContextPtr imesa, } I830_SET_FIELD(t->Setup[I830_TEXREG_MF], - MAG_FILTER_MASK, MAG_FILTER(magFilt)); - - if (t->globj->MinFilter != GL_NEAREST && - t->globj->MinFilter != GL_LINEAR) { - LastLevel = t->max_level; - } else { - LastLevel = t->min_level; - } - - I830_SET_FIELD(t->Setup[I830_TEXREG_MLL], - LOD_MAX_MASK, - LOD_MAX(t->min_level << 4)); + MIN_FILTER_MASK | MIP_FILTER_MASK, + MIN_FILTER(minFilt) | mipFilt); - I830_SET_FIELD(t->Setup[I830_TEXREG_MLL], - LOD_MIN_MASK, - LOD_MIN(LastLevel)); + I830_SET_FIELD(t->Setup[I830_TEXREG_MF], + MAG_FILTER_MASK, MAG_FILTER(magFilt)); - /* See OpenGL 1.2 specification */ - if (magf == GL_LINEAR && (minf == GL_NEAREST_MIPMAP_NEAREST || - minf == GL_NEAREST_MIPMAP_LINEAR)) - { - /* c = 0.5 */ - I830_SET_FIELD(t->Setup[I830_TEXREG_MLC], - MAP_LOD_MASK, 0x10); - } else { - /* c = 0 */ - I830_SET_FIELD(t->Setup[I830_TEXREG_MLC], - MAP_LOD_MASK, 0x0); - } + t->Setup[I830_TEXREG_MLC] |= i830ComputeLodBias(bias); } - -/* XXX - have to make sure MI0 has length field set to include color */ static void i830SetTexBorderColor(i830TextureObjectPtr t, GLubyte color[4]) { if(I830_DEBUG&DEBUG_VERBOSE_TRACE) @@ -190,2069 +189,350 @@ static void i830SetTexBorderColor(i830TextureObjectPtr t, GLubyte color[4]) } -static void ReplicateMesaTexState(i830ContextPtr imesa, - i830TextureObjectPtr t, - struct gl_texture_object *mesatex) -{ - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s\n", __FUNCTION__); - - i830SetTexWrapping(t,mesatex->WrapS,mesatex->WrapT); - i830SetTexFilter(imesa, t,mesatex->MinFilter,mesatex->MagFilter); - i830SetTexBorderColor(t,mesatex->BorderColor); -} - -/* Utility function to setup the texture palette */ -static void -i830ConvertPalette(GLuint *data, const struct gl_color_table *table) +static void i830TexParameter( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj, + GLenum pname, const GLfloat *params ) { - const GLubyte *tableUB = (const GLubyte *) table->Table; - GLint width = table->Size; - GLuint r, g, b, a; - int i; + i830ContextPtr imesa = I830_CONTEXT(ctx); + i830TextureObjectPtr t = (i830TextureObjectPtr) tObj->DriverData; + GLuint unit = ctx->Texture.CurrentUnit; + if (!t) + return; - ASSERT(table->TableType == GL_UNSIGNED_BYTE); + if ( target != GL_TEXTURE_2D ) + return; - 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] = I830PACKCOLOR4444(r, g, b, a); - } - 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]; - data[i] = I830PACKCOLOR565(r, g, b); - } - break; - case GL_LUMINANCE: - for (i = 0; i < width; i++) { - r = tableUB[i]; - data[i] = (255 << 8) | r; - } - break; - case GL_ALPHA: - for (i = 0; i < width; i++) { - a = tableUB[i]; - data[i] = (a << 8) | 255; - } - break; - case GL_LUMINANCE_ALPHA: - for (i = 0; i < width; i++) { - r = tableUB[i * 2 + 0]; - a = tableUB[i * 2 + 1]; - data[i] = (a << 8) | r; - } - break; - case GL_INTENSITY: - for (i = 0; i < width; i++) { - a = tableUB[i]; - data[i] = (a << 8) | a; + /* Can't do the update now as we don't know whether to flush + * vertices or not. Setting imesa->new_state means that + * i830UpdateTextureState() will be called before any triangles are + * rendered. If a statechange has occurred, it will be detected at + * that point, and buffered vertices flushed. + */ + switch (pname) { + case GL_TEXTURE_MIN_FILTER: + case GL_TEXTURE_MAG_FILTER: + { + GLfloat bias = ctx->Texture.Unit[unit].LodBias; + i830SetTexFilter( imesa, t, tObj->MinFilter, tObj->MagFilter, bias ); } break; - } -} - -static i830TextureObjectPtr i830CreateTexObj(i830ContextPtr imesa, - struct gl_texture_object *tObj) -{ - i830TextureObjectPtr t; - GLuint height, width, pitch, i, textureFormat; - struct gl_texture_image *image; - - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s\n", __FUNCTION__); - - image = tObj->Image[ 0 ]; - if ( !image ) { - fprintf(stderr, "no image at level zero - not creating texobj\n"); - return 0; - } - - t = (i830TextureObjectPtr) calloc(1,sizeof(*t)); - if (!t) { - fprintf(stderr, "failed to allocate memory - not creating texobj\n"); - return 0; - } - switch( image->Format ) { - case GL_RGB: - image->TexFormat = &(_mesa_texformat_rgb565); - t->texelBytes = 2; - textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565; - break; - case GL_RGBA: - image->TexFormat = &(_mesa_texformat_argb4444); - t->texelBytes = 2; - textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB4444; + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + i830SetTexWrapping( t, tObj->WrapS, tObj->WrapT ); break; - case GL_ALPHA: - case GL_LUMINANCE: - case GL_LUMINANCE_ALPHA: - case GL_INTENSITY: - image->TexFormat = &(_mesa_texformat_al88); - t->texelBytes = 2; - textureFormat = MAPSURF_16BIT | MT_16BIT_AY88; + + case GL_TEXTURE_BORDER_COLOR: + i830SetTexBorderColor( t, tObj->BorderColor ); break; - case GL_COLOR_INDEX: - image->TexFormat = &(_mesa_texformat_ci8); - textureFormat = MAPSURF_8BIT_INDEXED; - t->texelBytes = 1; - - switch(tObj->Palette.Format) { - case GL_RGBA: - textureFormat |= MT_8BIT_IDX_ARGB4444; - break; - case GL_RGB: - textureFormat |= MT_8BIT_IDX_RGB565; - break; - case GL_LUMINANCE: - case GL_ALPHA: - case GL_LUMINANCE_ALPHA: - case GL_INTENSITY: - textureFormat |= MT_8BIT_IDX_AY88; break; - } - /* Insure the palette is loaded */ - i830ConvertPalette(t->palette, &tObj->Palette); - t->palette_format = tObj->Palette.Format; + case GL_TEXTURE_BASE_LEVEL: + case GL_TEXTURE_MAX_LEVEL: + case GL_TEXTURE_MIN_LOD: + case GL_TEXTURE_MAX_LOD: + /* This isn't the most efficient solution but there doesn't appear to + * be a nice alternative for Radeon. Since there's no LOD clamping, + * we just have to rely on loading the right subset of mipmap levels + * to simulate a clamped LOD. + */ + i830SwapOutTexObj( imesa, t ); break; - default: - fprintf(stderr, "i830CreateTexObj: bad image->Format\n"); - free( t ); - return 0; - } - - /* Figure out the size now (and count the levels). Upload won't be done - * until later. - */ - width = image->Width * t->texelBytes; - if(width % 4) { - fprintf(stderr, "Pitch is not a multiple of dwords\n"); - } - pitch = width; /* All pitches can be used, since we are not using - * tiled surfaces. - */ - - t->dirty_images = 0; - t->bound = 0; - - for ( height = i = 0 ; i < I830_TEX_MAXLEVELS && tObj->Image[i] ; i++ ) { - t->image[i].image = tObj->Image[i]; - t->image[i].offset = height * pitch; - t->image[i].internalFormat = image->Format; - t->dirty_images |= (1<<i); - height += t->image[i].image->Height; - } - - t->Pitch = pitch; - t->totalSize = height*pitch; - t->max_level = i-1; - t->min_level = 0; - t->globj = tObj; - t->age = 0; - - t->Setup[I830_TEXREG_MI0] = STATE3D_MAP_INFO_COLR_CMD; - - t->Setup[I830_TEXREG_MI1] = MAP_INFO_TEX(0) | - textureFormat | - MAP_INFO_OUTMUX_F0F1F2F3 | - MAP_INFO_VERTLINESTRIDE_0 | - MAP_INFO_VERTLINESTRIDEOFS_0 | - MAP_INFO_FORMAT_2D | - MAP_INFO_USE_FENCE; - - t->Setup[I830_TEXREG_MI2] = (((1 << image->HeightLog2) - 1) << 16) | - ((1 << image->WidthLog2) - 1); - - t->Setup[I830_TEXREG_MI3] = 0; - - t->Setup[I830_TEXREG_MI4] = ((pitch / 4) - 1) << 2; - - t->Setup[I830_TEXREG_MI5] = 0; - - t->Setup[I830_TEXREG_MLC] = STATE3D_MAP_LOD_CNTL_CMD | MAP_UNIT(0) | - ENABLE_TEXLOD_BIAS | - MAP_LOD_BIAS(0); - - t->Setup[I830_TEXREG_MLL] = STATE3D_MAP_LOD_LIMITS_CMD | MAP_UNIT(0) | - ENABLE_MAX_MIP_LVL | - LOD_MAX(t->min_level << 4) | - ENABLE_MIN_MIP_LVL | - LOD_MIN(t->max_level); - - /* I think this is context state, really. - */ - t->Setup[I830_TEXREG_MCS] = STATE3D_MAP_COORD_SET_CMD | MAP_UNIT(0) | - ENABLE_TEXCOORD_PARAMS | - TEXCOORDS_ARE_NORMAL | - TEXCOORDTYPE_CARTESIAN | - ENABLE_ADDR_V_CNTL | - TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP) | - ENABLE_ADDR_U_CNTL | - TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP); - - t->Setup[I830_TEXREG_MF] = STATE3D_MAP_FILTER_CMD | MAP_UNIT(0) | - ENABLE_MIP_MODE_FILTER | - MIPFILTER_NEAREST | - ENABLE_MAG_MODE_FILTER | - MAG_FILTER(FILTER_LINEAR) | - ENABLE_MIN_MODE_FILTER | - MIN_FILTER(FILTER_LINEAR); - - t->current_unit = 0; - - ReplicateMesaTexState(imesa, t,tObj); - tObj->DriverData = t; - /* Forces tex cache flush */ - imesa->dirty |= I830_UPLOAD_CTX; - make_empty_list( t ); - return t; -} - -void i830DestroyTexObj(i830ContextPtr imesa, i830TextureObjectPtr t) -{ - if (!t) return; - - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s\n", __FUNCTION__); - - /* This is sad - need to sync *in case* we upload a texture - * to this newly free memory... - */ - if (t->MemBlock) { - mmFreeMem(t->MemBlock); - t->MemBlock = 0; - - if (t->age > imesa->dirtyAge) - imesa->dirtyAge = t->age; - } - - if (t->globj) - t->globj->DriverData = 0; - - if (t->bound) - imesa->CurrentTexObj[t->bound - 1] = 0; - - remove_from_list(t); - free(t); -} - - -static void i830SwapOutTexObj(i830ContextPtr imesa, i830TextureObjectPtr t) -{ - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (t->MemBlock) { - mmFreeMem(t->MemBlock); - t->MemBlock = 0; - - if (t->age > imesa->dirtyAge) - imesa->dirtyAge = t->age; - } - - t->dirty_images = ~0; - move_to_tail(&(imesa->SwappedOut), t); -} - - - -/* Upload an image from mesa's internal copy. - */ -static void i830UploadTexLevel( i830TextureObjectPtr t, int level ) -{ - const struct gl_texture_image *image = t->image[level].image; - int i,j; - - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (I830_DEBUG & DEBUG_VERBOSE_LRU) - fprintf(stderr, "i830UploadTexLevel %d, BufAddr %p offset %x\n", - level, t->BufAddr, t->image[level].offset); - - switch (t->image[level].internalFormat) { - case GL_RGB: - { - GLushort *dst = (GLushort *)(t->BufAddr + t->image[level].offset); - GLubyte *src = (GLubyte *)image->Data; - - for (j = 0 ; j < image->Height ; j++, dst += (t->Pitch/2)) { - for (i = 0 ; i < image->Width ; i++) { - dst[i] = I830PACKCOLOR565(src[0],src[1],src[2]); - src += 3; - } - } - } - break; - - case GL_RGBA: - { - GLushort *dst = (GLushort *)(t->BufAddr + t->image[level].offset); - GLubyte *src = (GLubyte *)image->Data; - - for (j = 0 ; j < image->Height ; j++, dst += (t->Pitch/2)) { - for (i = 0 ; i < image->Width ; i++) { - dst[i] = I830PACKCOLOR4444(src[0],src[1],src[2],src[3]); - src += 4; - } - } - } - break; - - case GL_INTENSITY: - { - GLushort *dst = (GLushort *)(t->BufAddr + t->image[level].offset); - GLubyte *src = (GLubyte *)image->Data; - int i; - - for (j = 0 ; j < image->Height ; j++, dst += (t->Pitch/2)) { - for (i = 0 ; i < image->Width ; i++) { - dst[i] = (src[0] << 8) | (src[0]); - src ++; - } - } - } - break; - - case GL_LUMINANCE: - { - GLushort *dst = (GLushort *)(t->BufAddr + t->image[level].offset); - GLubyte *src = (GLubyte *)image->Data; - for (j = 0 ; j < image->Height ; j++, dst += (t->Pitch/2)) { - for (i = 0 ; i < image->Width ; i++) { - dst[i] = (255 << 8) | (src[0]); - src ++; - } - } - } - break; - - case GL_LUMINANCE_ALPHA: - { - GLushort *dst = (GLushort *)(t->BufAddr + t->image[level].offset); - GLubyte *src = (GLubyte *)image->Data; - - for (j = 0 ; j < image->Height ; j++, dst += (t->Pitch/2)) { - for (i = 0 ; i < image->Width ; i++) { - dst[i] = (src[1] << 8) | (src[0]); - src += 2; - } - } - } - break; - - case GL_ALPHA: - { - GLushort *dst = (GLushort *)(t->BufAddr + t->image[level].offset); - GLubyte *src = (GLubyte *)image->Data; - - for (j = 0 ; j < image->Height ; j++, dst += (t->Pitch/2)) { - for (i = 0 ; i < image->Width ; i++) { - dst[i] = (src[0] << 8) | 255; - src += 1; - } - } - } - break; - - case GL_COLOR_INDEX: - { - GLubyte *dst = (GLubyte *)(t->BufAddr + t->image[level].offset); - GLubyte *src = (GLubyte *)image->Data; - - for (j = 0 ; j < image->Height ; j++, dst += t->Pitch) { - for (i = 0 ; i < image->Width ; i++) { - dst[i] = src[0]; - src += 1; - } - } - } - break; - default: - fprintf(stderr, "Not supported texture format %s\n", - gl_lookup_enum_by_nr(image->Format)); - } -} - - - -void i830PrintLocalLRU( i830ContextPtr imesa ) -{ - i830TextureObjectPtr t; - int sz = 1 << (imesa->i830Screen->logTextureGranularity); - - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s\n", __FUNCTION__); - - foreach( t, &imesa->TexObjList ) { - if (!t->globj) - fprintf(stderr, "Placeholder %d at %x sz %x\n", - t->MemBlock->ofs / sz, - t->MemBlock->ofs, - t->MemBlock->size); - else - fprintf(stderr, "Texture (bound %d) at %x sz %x\n", - t->bound, - t->MemBlock->ofs, - t->MemBlock->size); - - } -} - -void i830PrintGlobalLRU( i830ContextPtr imesa ) -{ - int i, j; - I830TexRegion *list = imesa->sarea->texList; - - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s\n", __FUNCTION__); - - for (i = 0, j = I830_NR_TEX_REGIONS ; i < I830_NR_TEX_REGIONS ; i++) { - fprintf(stderr, "list[%d] age %d next %d prev %d\n", - j, list[j].age, list[j].next, list[j].prev); - j = list[j].next; - if (j == I830_NR_TEX_REGIONS) break; + return; } - - if (j != I830_NR_TEX_REGIONS) - fprintf(stderr, "Loop detected in global LRU\n"); -} - -void i830ResetGlobalLRU( i830ContextPtr imesa ) -{ - I830TexRegion *list = imesa->sarea->texList; - int sz = 1 << imesa->i830Screen->logTextureGranularity; - int i; - - /* (Re)initialize the global circular LRU list. The last element - * in the array (I830_NR_TEX_REGIONS) is the sentinal. Keeping it - * at the end of the array allows it to be addressed rationally - * when looking up objects at a particular location in texture - * memory. - */ - - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s\n", __FUNCTION__); - - for (i = 0 ; (i+1) * sz <= imesa->i830Screen->textureSize ; i++) { - list[i].prev = i-1; - list[i].next = i+1; - list[i].age = 0; + if (t == imesa->CurrentTexObj[unit]) { + I830_STATECHANGE( imesa, I830_UPLOAD_TEX0 ); } - - i--; - list[0].prev = I830_NR_TEX_REGIONS; - list[i].prev = i-1; - list[i].next = I830_NR_TEX_REGIONS; - list[I830_NR_TEX_REGIONS].prev = i; - list[I830_NR_TEX_REGIONS].next = 0; - imesa->sarea->texAge = 0; } -static void i830UpdateTexLRU( i830ContextPtr imesa, i830TextureObjectPtr t ) -{ - int i; - int logsz = imesa->i830Screen->logTextureGranularity; - int start = t->MemBlock->ofs >> logsz; - int end = (t->MemBlock->ofs + t->MemBlock->size - 1) >> logsz; - I830TexRegion *list = imesa->sarea->texList; - - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s\n", __FUNCTION__); - - imesa->texAge = ++imesa->sarea->texAge; - - /* Update our local LRU - */ - move_to_head( &(imesa->TexObjList), t ); - - /* Update the global LRU - */ - for (i = start ; i <= end ; i++) { - - list[i].in_use = 1; - list[i].age = imesa->texAge; - - /* remove_from_list(i) - */ - list[(unsigned)list[i].next].prev = list[i].prev; - list[(unsigned)list[i].prev].next = list[i].next; - - /* insert_at_head(list, i) - */ - list[i].prev = I830_NR_TEX_REGIONS; - list[i].next = list[I830_NR_TEX_REGIONS].next; - list[(unsigned)list[I830_NR_TEX_REGIONS].next].prev = i; - list[I830_NR_TEX_REGIONS].next = i; - } -} - - -/* Called for every shared texture region which has increased in age - * since we last held the lock. - * - * Figures out which of our textures have been ejected by other clients, - * and pushes a placeholder texture onto the LRU list to represent - * the other client's textures. - */ -void i830TexturesGone( i830ContextPtr imesa, - GLuint offset, - GLuint size, - GLuint in_use ) -{ - i830TextureObjectPtr t, tmp; - - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s\n", __FUNCTION__); - - foreach_s ( t, tmp, &imesa->TexObjList ) { - - if (t->MemBlock->ofs >= offset + size || - t->MemBlock->ofs + t->MemBlock->size <= offset) - continue; - - /* It overlaps - kick it off. Need to hold onto the currently bound - * objects, however. - */ - if (t->bound) - i830SwapOutTexObj( imesa, t ); - else - i830DestroyTexObj( imesa, t ); - } - - - if (in_use) { - t = (i830TextureObjectPtr) calloc(1,sizeof(*t)); - if (!t) return; - - t->MemBlock = mmAllocMem( imesa->texHeap, size, 0, offset); - insert_at_head( &imesa->TexObjList, t ); - } -} - -/* This is called with the lock held. May have to eject our own and/or - * other client's texture objects to make room for the upload. - */ -int i830UploadTexImages( i830ContextPtr imesa, i830TextureObjectPtr t ) +static void i830TexEnv( GLcontext *ctx, GLenum target, + GLenum pname, const GLfloat *param ) { - int i; - int ofs; - - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s\n", __FUNCTION__); + i830ContextPtr imesa = I830_CONTEXT( ctx ); + GLuint unit = ctx->Texture.CurrentUnit; - /* Do we need to eject LRU texture objects? + /* Only one env color. Need a fallback if env colors are different + * and texture setup references env color in both units. */ - if (!t->MemBlock) { - while (1) + switch (pname) { + case GL_TEXTURE_ENV_COLOR: + case GL_TEXTURE_ENV_MODE: + case GL_COMBINE_RGB_EXT: + case GL_COMBINE_ALPHA_EXT: + case GL_SOURCE0_RGB_EXT: + case GL_SOURCE1_RGB_EXT: + case GL_SOURCE2_RGB_EXT: + case GL_SOURCE0_ALPHA_EXT: + case GL_SOURCE1_ALPHA_EXT: + case GL_SOURCE2_ALPHA_EXT: + case GL_OPERAND0_RGB_EXT: + case GL_OPERAND1_RGB_EXT: + case GL_OPERAND2_RGB_EXT: + case GL_OPERAND0_ALPHA_EXT: + case GL_OPERAND1_ALPHA_EXT: + case GL_OPERAND2_ALPHA_EXT: + case GL_RGB_SCALE_EXT: + case GL_ALPHA_SCALE: + imesa->TexEnvImageFmt[unit] = 0; /* force recalc of env state */ + break; + + case GL_TEXTURE_LOD_BIAS_EXT: { - t->MemBlock = mmAllocMem( imesa->texHeap, t->totalSize, 12, 0 ); - if (t->MemBlock) - break; - - if (imesa->TexObjList.prev->bound) { - fprintf(stderr, "Hit bound texture in upload\n"); - i830PrintLocalLRU( imesa ); - return -1; - } - - if (imesa->TexObjList.prev == &(imesa->TexObjList)) { - fprintf(stderr, "Failed to upload texture, sz %d\n", t->totalSize); - mmDumpMemInfo( imesa->texHeap ); - return -1; + struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current; + i830TextureObjectPtr t = (i830TextureObjectPtr) tObj->DriverData; + t->Setup[I830_TEXREG_MLC] &= ~(MLC_LOD_BIAS_MASK); + t->Setup[I830_TEXREG_MLC] |= i830ComputeLodBias(*param); + /* Do a state change */ + if (t == imesa->CurrentTexObj[unit]) { + I830_STATECHANGE( imesa, I830_UPLOAD_TEX_N(unit) ); } - - i830DestroyTexObj( imesa, imesa->TexObjList.prev ); - } - - ofs = t->MemBlock->ofs; - t->Setup[I830_TEXREG_MI3] = imesa->i830Screen->textureOffset + ofs; - t->BufAddr = imesa->i830Screen->tex.map + ofs; - imesa->dirty |= I830_UPLOAD_CTX; - } - - /* Let the world know we've used this memory recently. - */ - i830UpdateTexLRU( imesa, t ); - - if (I830_DEBUG & DEBUG_VERBOSE_LRU) - fprintf(stderr, "dispatch age: %d age freed memory: %d\n", - GET_DISPATCH_AGE(imesa), imesa->dirtyAge); - - if (imesa->dirtyAge >= GET_DISPATCH_AGE(imesa)) - i830WaitAgeLocked( imesa, imesa->dirtyAge ); - - - if (t->dirty_images) { - if (I830_DEBUG & DEBUG_VERBOSE_LRU) - fprintf(stderr, "*"); - - for (i = t->min_level ; i <= t->max_level ; i++) - if (t->dirty_images & (1<<i)) - i830UploadTexLevel( t, i ); - } - - - t->dirty_images = 0; - return 0; -} - -static void i830TexSetUnit( i830TextureObjectPtr t, GLuint unit ) -{ - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s unit(%d)\n", __FUNCTION__, unit); - - /* This will need to be changed when I support more then 2 t units */ - I830_SET_FIELD(t->Setup[I830_TEXREG_MI1], - MAP_INFO_MASK | MAP_INFO_USE_PALETTE_1, - MAP_INFO_TEX(unit) | MAP_INFO_USE_PALETTE_N(unit)); - I830_SET_FIELD(t->Setup[I830_TEXREG_MLC], MAP_UNIT_MASK, MAP_UNIT(unit)); - I830_SET_FIELD(t->Setup[I830_TEXREG_MLL], MAP_UNIT_MASK, MAP_UNIT(unit)); - I830_SET_FIELD(t->Setup[I830_TEXREG_MCS], MAP_UNIT_MASK, MAP_UNIT(unit)); - I830_SET_FIELD(t->Setup[I830_TEXREG_MF], MAP_UNIT_MASK, MAP_UNIT(unit)); - - t->current_unit = unit; -} - -static __inline__ GLuint GetTexelOp(GLint unit) -{ - switch(unit) { - case 0: return TEXBLENDARG_TEXEL0; - case 1: return TEXBLENDARG_TEXEL1; - case 2: return TEXBLENDARG_TEXEL2; - case 3: return TEXBLENDARG_TEXEL3; - default: return TEXBLENDARG_TEXEL0; - } -} - -/* Only 1.2 modes; make another func for combine, combine4, combiners */ -static void i830SetBlend_GL1_2(i830ContextPtr imesa, int curTex, - GLenum envMode, GLenum format) -{ - GLuint texel_op = GetTexelOp(curTex); - - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s %s %s unit (%d) texel_op(0x%x)\n", - __FUNCTION__, - gl_lookup_enum_by_nr(format), - gl_lookup_enum_by_nr(envMode), - curTex, - texel_op); - - switch(envMode) { - case GL_REPLACE: - switch(format) { - case GL_ALPHA: - imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | - TEXPIPE_COLOR | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - DISABLE_TEX_CNTRL_STAGE | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | - TEXPIPE_ALPHA | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_COLOR | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_ALPHA | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - texel_op); - imesa->TexBlendColorPipeNum[curTex] = 0; - imesa->TexBlendWordsUsed[curTex] = 4; - break; - case GL_LUMINANCE: - case GL_RGB: - imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | - TEXPIPE_COLOR | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - DISABLE_TEX_CNTRL_STAGE | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | - TEXPIPE_ALPHA | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_COLOR | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - texel_op); - imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_ALPHA | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlendColorPipeNum[curTex] = 0; - imesa->TexBlendWordsUsed[curTex] = 4; - break; - - case GL_INTENSITY: - case GL_LUMINANCE_ALPHA: - case GL_RGBA: - imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | - TEXPIPE_COLOR | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - DISABLE_TEX_CNTRL_STAGE | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | - TEXPIPE_ALPHA | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_COLOR | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - texel_op); - imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_ALPHA | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - texel_op); - imesa->TexBlendColorPipeNum[curTex] = 0; - imesa->TexBlendWordsUsed[curTex] = 4; - break; - default: - /* Always set to passthru if something is funny */ - imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(0) | - TEXPIPE_COLOR | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - DISABLE_TEX_CNTRL_STAGE | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(0) | - TEXPIPE_ALPHA | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) | - TEXPIPE_COLOR | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) | - TEXPIPE_ALPHA | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlendColorPipeNum[curTex] = 0; - imesa->TexBlendWordsUsed[curTex] = 4; - break; - } - break; - - case GL_MODULATE: - switch(format) { - case GL_ALPHA: - imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | - TEXPIPE_COLOR | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - DISABLE_TEX_CNTRL_STAGE | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | - TEXPIPE_ALPHA | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_MODULATE); - imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_COLOR | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_ALPHA | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - texel_op); - imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_ALPHA | - TEXBLEND_ARG2 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlendColorPipeNum[curTex] = 0; - imesa->TexBlendWordsUsed[curTex] = 5; - break; - - case GL_LUMINANCE: - case GL_RGB: - imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | - TEXPIPE_COLOR | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - DISABLE_TEX_CNTRL_STAGE | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_MODULATE); - imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | - TEXPIPE_ALPHA | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_COLOR | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - texel_op); - imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_COLOR | - TEXBLEND_ARG2 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_ALPHA | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlendColorPipeNum[curTex] = 0; - imesa->TexBlendWordsUsed[curTex] = 5; - break; - - case GL_INTENSITY: - case GL_LUMINANCE_ALPHA: - case GL_RGBA: - imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | - TEXPIPE_COLOR | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - DISABLE_TEX_CNTRL_STAGE | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_MODULATE); - imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | - TEXPIPE_ALPHA | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_MODULATE); - imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_COLOR | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - texel_op); - imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_COLOR | - TEXBLEND_ARG2 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_ALPHA | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - texel_op); - imesa->TexBlend[curTex][5] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_ALPHA | - TEXBLEND_ARG2 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlendColorPipeNum[curTex] = 0; - imesa->TexBlendWordsUsed[curTex] = 6; - break; - default: - /* Always set to passthru if something is funny */ - imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(0) | - TEXPIPE_COLOR | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - DISABLE_TEX_CNTRL_STAGE | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(0) | - TEXPIPE_ALPHA | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) | - TEXPIPE_COLOR | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) | - TEXPIPE_ALPHA | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlendColorPipeNum[curTex] = 0; - imesa->TexBlendWordsUsed[curTex] = 4; - break; - } - break; - - case GL_DECAL: - switch(format) { - case GL_RGB: - imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | - TEXPIPE_COLOR | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - DISABLE_TEX_CNTRL_STAGE | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | - TEXPIPE_ALPHA | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_COLOR | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - texel_op); - imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_ALPHA | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlendColorPipeNum[curTex] = 0; - imesa->TexBlendWordsUsed[curTex] = 4; - break; - - case GL_RGBA: - imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | - TEXPIPE_COLOR | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - DISABLE_TEX_CNTRL_STAGE | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_BLEND); - imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | - TEXPIPE_ALPHA | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_COLOR | - TEXBLEND_ARG0 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_REPLICATE_ALPHA | - texel_op); - imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_COLOR | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - texel_op); - imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_COLOR | - TEXBLEND_ARG2 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlend[curTex][5] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_ALPHA | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlendColorPipeNum[curTex] = 0; - imesa->TexBlendWordsUsed[curTex] = 6; - break; - default: - /* Always set to passthru if something is funny */ - imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(0) | - TEXPIPE_COLOR | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - DISABLE_TEX_CNTRL_STAGE | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(0) | - TEXPIPE_ALPHA | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) | - TEXPIPE_COLOR | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) | - TEXPIPE_ALPHA | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlendColorPipeNum[curTex] = 0; - imesa->TexBlendWordsUsed[curTex] = 4; - break; - } - break; - - case GL_BLEND: - switch(format) { - case GL_ALPHA: - imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | - TEXPIPE_COLOR | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - DISABLE_TEX_CNTRL_STAGE | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | - TEXPIPE_ALPHA | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_MODULATE); - imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_COLOR | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_ALPHA | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - texel_op); - imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_ALPHA | - TEXBLEND_ARG2 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlendColorPipeNum[curTex] = 0; - imesa->TexBlendWordsUsed[curTex] = 5; - break; - - case GL_LUMINANCE: - case GL_RGB: - imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | - TEXPIPE_COLOR | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - DISABLE_TEX_CNTRL_STAGE | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_BLEND); - imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | - TEXPIPE_ALPHA | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_COLOR | - TEXBLEND_ARG0 | - TEXBLENDARG_MODIFY_PARMS | - texel_op); - imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_COLOR | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_FACTOR_N); - imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_COLOR | - TEXBLEND_ARG2 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlend[curTex][5] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_ALPHA | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlendColorPipeNum[curTex] = 0; - imesa->TexBlendWordsUsed[curTex] = 6; - break; - - case GL_INTENSITY: - imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | - TEXPIPE_COLOR | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - DISABLE_TEX_CNTRL_STAGE | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_BLEND); - imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | - TEXPIPE_ALPHA | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_BLEND); - imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_COLOR | - TEXBLEND_ARG0 | - TEXBLENDARG_MODIFY_PARMS | - texel_op); - imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_COLOR | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_FACTOR_N); - imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_COLOR | - TEXBLEND_ARG2 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlend[curTex][5] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_ALPHA | - TEXBLEND_ARG0 | - TEXBLENDARG_MODIFY_PARMS | - texel_op); - imesa->TexBlend[curTex][6] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_ALPHA | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_FACTOR_N); - imesa->TexBlend[curTex][7] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_ALPHA | - TEXBLEND_ARG2 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlendColorPipeNum[curTex] = 0; - imesa->TexBlendWordsUsed[curTex] = 8; - break; - - case GL_LUMINANCE_ALPHA: - case GL_RGBA: - imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | - TEXPIPE_COLOR | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - DISABLE_TEX_CNTRL_STAGE | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_BLEND); - imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | - TEXPIPE_ALPHA | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_MODULATE); - imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_COLOR | - TEXBLEND_ARG0 | - TEXBLENDARG_MODIFY_PARMS | - texel_op); - imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_COLOR | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_FACTOR_N); - imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_COLOR | - TEXBLEND_ARG2 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlend[curTex][5] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_ALPHA | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - texel_op); - imesa->TexBlend[curTex][6] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_ALPHA | - TEXBLEND_ARG2 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlendColorPipeNum[curTex] = 0; - imesa->TexBlendWordsUsed[curTex] = 7; - break; - default: - /* Always set to passthru if something is funny */ - imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(0) | - TEXPIPE_COLOR | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - DISABLE_TEX_CNTRL_STAGE | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(0) | - TEXPIPE_ALPHA | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) | - TEXPIPE_COLOR | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) | - TEXPIPE_ALPHA | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlendColorPipeNum[curTex] = 0; - imesa->TexBlendWordsUsed[curTex] = 4; - break; } break; - case GL_ADD: - switch(format) { - case GL_ALPHA: - imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | - TEXPIPE_COLOR | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - DISABLE_TEX_CNTRL_STAGE | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | - TEXPIPE_ALPHA | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_MODULATE); - imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_COLOR | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_ALPHA | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - texel_op); - imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_ALPHA | - TEXBLEND_ARG2 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlendColorPipeNum[curTex] = 0; - imesa->TexBlendWordsUsed[curTex] = 5; - break; - case GL_LUMINANCE: - case GL_RGB: - imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | - TEXPIPE_COLOR | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - DISABLE_TEX_CNTRL_STAGE | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ADD); - imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | - TEXPIPE_ALPHA | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_COLOR | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - texel_op); - imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_COLOR | - TEXBLEND_ARG2 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_ALPHA | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlendColorPipeNum[curTex] = 0; - imesa->TexBlendWordsUsed[curTex] = 5; - break; - - case GL_INTENSITY: - imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | - TEXPIPE_COLOR | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - DISABLE_TEX_CNTRL_STAGE | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ADD); - imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | - TEXPIPE_ALPHA | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ADD); - imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_COLOR | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - texel_op); - imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_COLOR | - TEXBLEND_ARG2 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_ALPHA | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - texel_op); - imesa->TexBlend[curTex][5] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_ALPHA | - TEXBLEND_ARG2 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlendColorPipeNum[curTex] = 0; - imesa->TexBlendWordsUsed[curTex] = 6; - break; - - case GL_LUMINANCE_ALPHA: - case GL_RGBA: - imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | - TEXPIPE_COLOR | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - DISABLE_TEX_CNTRL_STAGE | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ADD); - imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | - TEXPIPE_ALPHA | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_MODULATE); - imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_COLOR | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - texel_op); - imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_COLOR | - TEXBLEND_ARG2 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_ALPHA | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - texel_op); - imesa->TexBlend[curTex][5] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | - TEXPIPE_ALPHA | - TEXBLEND_ARG2 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlendColorPipeNum[curTex] = 0; - imesa->TexBlendWordsUsed[curTex] = 6; - break; - default: - /* Always set to passthru if something is funny */ - imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(0) | - TEXPIPE_COLOR | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - DISABLE_TEX_CNTRL_STAGE | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(0) | - TEXPIPE_ALPHA | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) | - TEXPIPE_COLOR | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) | - TEXPIPE_ALPHA | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlendColorPipeNum[curTex] = 0; - imesa->TexBlendWordsUsed[curTex] = 4; - break; - } - break; default: - /* Always set to passthru if something is funny */ - imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(0) | - TEXPIPE_COLOR | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - DISABLE_TEX_CNTRL_STAGE | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(0) | - TEXPIPE_ALPHA | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) | - TEXPIPE_COLOR | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) | - TEXPIPE_ALPHA | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlendColorPipeNum[curTex] = 0; - imesa->TexBlendWordsUsed[curTex] = 4; - break; + break; } +} - if (I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s\n", __FUNCTION__); -} - -static void i830SetTexEnvCombine(i830ContextPtr imesa, - struct gl_texture_unit *texUnit, - GLint unit) +static void i830TexImage2D( 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 ) { - GLuint blendop; - GLuint ablendop; - GLuint args_RGB[3]; - GLuint args_A[3]; - GLuint texel_op = GetTexelOp(unit); - int i; - - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s\n", __FUNCTION__); - - switch(texUnit->CombineModeRGB) { - case GL_REPLACE: blendop = TEXBLENDOP_ARG1; break; - case GL_MODULATE: blendop = TEXBLENDOP_MODULATE; break; - case GL_ADD: blendop = TEXBLENDOP_ADD; break; - case GL_ADD_SIGNED_EXT: blendop = TEXBLENDOP_ADDSIGNED; break; - case GL_INTERPOLATE_EXT: blendop = TEXBLENDOP_BLEND; break; - default: return; - } - - switch(texUnit->CombineScaleShiftRGB) { - case 0: blendop |= TEXOP_SCALE_1X; break; - case 1: blendop |= TEXOP_SCALE_2X; break; - case 2: blendop |= TEXOP_SCALE_4X; break; - default: return; - } - - switch(texUnit->CombineModeA) { - case GL_REPLACE: ablendop = TEXBLENDOP_ARG1; break; - case GL_MODULATE: ablendop = TEXBLENDOP_MODULATE; break; - case GL_ADD: ablendop = TEXBLENDOP_ADD; break; - case GL_ADD_SIGNED_EXT: ablendop = TEXBLENDOP_ADDSIGNED; break; - case GL_INTERPOLATE_EXT: ablendop = TEXBLENDOP_BLEND; break; - default: return; - } - - switch(texUnit->CombineScaleShiftA) { - case 0: ablendop |= TEXOP_SCALE_1X; break; - case 1: ablendop |= TEXOP_SCALE_2X; break; - case 2: ablendop |= TEXOP_SCALE_4X; break; - default: return; - } - - /* Handle RGB args */ - for(i = 0; i < 3; i++) { - switch(texUnit->CombineSourceRGB[i]) { - case GL_TEXTURE: args_RGB[i] = texel_op; break; - case GL_CONSTANT_EXT: args_RGB[i] = TEXBLENDARG_FACTOR_N; break; - case GL_PRIMARY_COLOR_EXT: args_RGB[i] = TEXBLENDARG_DIFFUSE; break; - case GL_PREVIOUS_EXT: args_RGB[i] = TEXBLENDARG_CURRENT; break; - default: return; - } - - switch(texUnit->CombineOperandRGB[i]) { - case GL_SRC_COLOR: args_RGB[i] |= 0; break; - case GL_ONE_MINUS_SRC_COLOR: args_RGB[i] |= TEXBLENDARG_INV_ARG; break; - case GL_SRC_ALPHA: args_RGB[i] |= TEXBLENDARG_REPLICATE_ALPHA; break; - case GL_ONE_MINUS_SRC_ALPHA: - args_RGB[i] |= (TEXBLENDARG_REPLICATE_ALPHA | - TEXBLENDARG_INV_ARG); - break; - default: return; - } - } - - /* Handle A args */ - for(i = 0; i < 3; i++) { - switch(texUnit->CombineSourceA[i]) { - case GL_TEXTURE: args_A[i] = texel_op; break; - case GL_CONSTANT_EXT: args_A[i] = TEXBLENDARG_FACTOR_N; break; - case GL_PRIMARY_COLOR_EXT: args_A[i] = TEXBLENDARG_DIFFUSE; break; - case GL_PREVIOUS_EXT: args_A[i] = TEXBLENDARG_CURRENT; break; - default: return; - } - - switch(texUnit->CombineOperandA[i]) { - case GL_SRC_ALPHA: args_A[i] |= 0; break; - case GL_ONE_MINUS_SRC_ALPHA: args_A[i] |= TEXBLENDARG_INV_ARG; break; - default: return; - } - } - - /* Native Arg1 == Arg0 in GL_EXT_texture_env_combine spec */ - /* Native Arg2 == Arg1 in GL_EXT_texture_env_combine spec */ - /* Native Arg0 == Arg2 in GL_EXT_texture_env_combine spec */ - - /* When we render we need to figure out which is the last really enabled - * tex unit, and put last stage on it - */ - - imesa->TexBlendColorPipeNum[unit] = 0; - - /* Build color pipeline */ - - imesa->TexBlend[unit][0] = (STATE3D_MAP_BLEND_OP_CMD(unit) | - TEXPIPE_COLOR | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - DISABLE_TEX_CNTRL_STAGE | - TEXOP_MODIFY_PARMS | - blendop); - imesa->TexBlend[unit][1] = (STATE3D_MAP_BLEND_ARG_CMD(unit) | - TEXPIPE_COLOR | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - args_RGB[0]); - imesa->TexBlend[unit][2] = (STATE3D_MAP_BLEND_ARG_CMD(unit) | - TEXPIPE_COLOR | - TEXBLEND_ARG2 | - TEXBLENDARG_MODIFY_PARMS | - args_RGB[1]); - imesa->TexBlend[unit][3] = (STATE3D_MAP_BLEND_ARG_CMD(unit) | - TEXPIPE_COLOR | - TEXBLEND_ARG0 | - TEXBLENDARG_MODIFY_PARMS | - args_RGB[2]); - - /* Build Alpha pipeline */ - imesa->TexBlend[unit][4] = (STATE3D_MAP_BLEND_OP_CMD(unit) | - TEXPIPE_ALPHA | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - TEXOP_MODIFY_PARMS | - ablendop); - imesa->TexBlend[unit][5] = (STATE3D_MAP_BLEND_ARG_CMD(unit) | - TEXPIPE_ALPHA | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - args_A[0]); - imesa->TexBlend[unit][6] = (STATE3D_MAP_BLEND_ARG_CMD(unit) | - TEXPIPE_ALPHA | - TEXBLEND_ARG2 | - TEXBLENDARG_MODIFY_PARMS | - args_A[1]); - imesa->TexBlend[unit][7] = (STATE3D_MAP_BLEND_ARG_CMD(unit) | - TEXPIPE_ALPHA | - TEXBLEND_ARG0 | - TEXBLENDARG_MODIFY_PARMS | - args_A[2]); - - { - GLubyte r, g, b, a; - GLfloat *fc = texUnit->EnvColor; - - FLOAT_COLOR_TO_UBYTE_COLOR(r, fc[RCOMP]); - FLOAT_COLOR_TO_UBYTE_COLOR(g, fc[GCOMP]); - FLOAT_COLOR_TO_UBYTE_COLOR(b, fc[BCOMP]); - FLOAT_COLOR_TO_UBYTE_COLOR(a, fc[ACOMP]); - - imesa->TexBlend[unit][8] = STATE3D_COLOR_FACTOR_CMD(unit); - imesa->TexBlend[unit][9] = ((a << 24) | - (r << 16) | - (g << 8) | - b); + i830TextureObjectPtr t = (i830TextureObjectPtr) texObj->DriverData; + if (t) { + i830SwapOutTexObj( I830_CONTEXT(ctx), t ); } - imesa->TexBlendWordsUsed[unit] = 10; + _mesa_store_teximage2d( ctx, target, level, internalFormat, + width, height, border, format, type, + pixels, packing, texObj, texImage ); } -static void i830UpdateTexState( GLcontext *ctx, int unit ) +static void i830TexSubImage2D( 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 ) { - i830ContextPtr imesa = I830_CONTEXT(ctx); - struct gl_texture_object *tObj; - i830TextureObjectPtr t; - - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s\n", __FUNCTION__); - - tObj = ctx->Texture.Unit[unit].Current; - - if ( tObj != ctx->Texture.Unit[unit].CurrentD[2] ) - tObj = 0; - - /* XXX grantham - need to change this shift if "TEXTURE" flags change - in mesa/src/types.h */ - if (!(ctx->Texture.ReallyEnabled & (0xf << (4 * unit))) - || !tObj || !tObj->Complete) { - return; - } - - t = tObj->DriverData; - - if (!t) { - t = i830CreateTexObj( imesa, tObj ); - if (!t) return; - } - - i830TexSetUnit( t, unit ); - - if (t->dirty_images) { - if(unit == 0) imesa->dirty |= I830_UPLOAD_TEX0_IMAGE; - if(unit == 1) imesa->dirty |= I830_UPLOAD_TEX1_IMAGE; - } - - if((t->Setup[I830_TEXREG_MI1] & ((1<<26)|(1<<25)|(1<<24))) == - MAPSURF_8BIT_INDEXED) { - /* Texture palette needs updated, need to do this in a smarter - * way, since it will always be loaded each time paletted textures - * are used, and texture state is reeval'ed. - */ - if(0) fprintf(stderr, "\n\n\nUpdating texture palette\n"); - if(!ctx->Texture.SharedPalette) { - imesa->dirty |= I830_UPLOAD_TEX_PALETTE_N(unit); - if(0) fprintf(stderr, "per texobj palette\n"); - } else { - imesa->dirty |= I830_UPLOAD_TEX_PALETTE_SHARED; - if(0) fprintf(stderr, "shared palette\n"); - } + i830TextureObjectPtr t = (i830TextureObjectPtr) texObj->DriverData; + if (t) { + i830SwapOutTexObj( I830_CONTEXT(ctx), t ); } + _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width, + height, format, type, pixels, packing, texObj, + texImage); - imesa->CurrentTexObj[unit] = t; - t->bound = 1; - - imesa->TexEnabledMask |= I830_TEX_UNIT_ENABLED(unit); - /* We only want the last texture unit, so we don't or this flag */ - imesa->LastTexEnabled = I830_TEX_UNIT_ENABLED(unit); - - /* Can't do this, we aren't locked here. Causes bad bad bad things */ -#if 0 - if (t->MemBlock) - i830UpdateTexLRU( imesa, t ); -#endif - } -static void i830UpdateTexBlend(GLcontext *ctx, int unit ) +static void i830BindTexture( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj ) { - i830ContextPtr imesa = I830_CONTEXT(ctx); - struct gl_texture_unit *texUnit; - struct gl_texture_object *texObj; - i830TextureObjectPtr t; - GLuint col; - - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s : unit %d\n", __FUNCTION__, unit); - - texUnit = &ctx->Texture.Unit[unit]; - texObj = ctx->Texture.Unit[unit].Current; - - if (!(ctx->Texture.ReallyEnabled & (0xf << (4 * unit))) - || !texObj || !texObj->Complete) { - return; - } - - t = (i830TextureObjectPtr) texObj->DriverData; - if (!t) { - t = i830CreateTexObj( imesa, texObj ); - if (!t) return; - } - - imesa->TexBlendWordsUsed[unit] = 0; - /* Could handle texenv_combine, register_combiners, combine4, etc */ - if(texUnit->EnvMode == GL_COMBINE_EXT) { - i830SetTexEnvCombine(imesa, - texUnit, - unit); - } else { - if(t->image[0].internalFormat == GL_COLOR_INDEX) { - if(!ctx->Texture.SharedPalette) { - i830SetBlend_GL1_2(imesa, unit, texUnit->EnvMode, - t->palette_format); - } else { - i830SetBlend_GL1_2(imesa, unit, texUnit->EnvMode, - imesa->palette_format); - - } - } else { - i830SetBlend_GL1_2(imesa, unit, texUnit->EnvMode, - t->image[0].internalFormat); + if (target == GL_TEXTURE_2D) { + i830ContextPtr imesa = I830_CONTEXT( ctx ); + i830TextureObjectPtr t = (i830TextureObjectPtr) tObj->DriverData; + + if (!t) { + GLfloat bias = ctx->Texture.Unit[ctx->Texture.CurrentUnit].LodBias; + t = CALLOC_STRUCT(i830_texture_object_t); + + /* Initialize non-image-dependent parts of the state: + */ + t->globj = tObj; + t->Setup[I830_TEXREG_MI0] = STATE3D_MAP_INFO_COLR_CMD; + t->Setup[I830_TEXREG_MI1] = (MAP_INFO_TEX(0) | + MAP_INFO_OUTMUX_F0F1F2F3 | + MAP_INFO_VERTLINESTRIDE_0 | + MAP_INFO_VERTLINESTRIDEOFS_0 | + MAP_INFO_FORMAT_2D | + MAP_INFO_USE_FENCE); + t->Setup[I830_TEXREG_MLC] = (STATE3D_MAP_LOD_CNTL_CMD | + MAP_UNIT(0) | + ENABLE_TEXLOD_BIAS | + MAP_LOD_BIAS(0)); + + t->Setup[I830_TEXREG_MCS] = (STATE3D_MAP_COORD_SET_CMD | + MAP_UNIT(0) | + ENABLE_TEXCOORD_PARAMS | + TEXCOORDS_ARE_NORMAL | + TEXCOORDTYPE_CARTESIAN | + ENABLE_ADDR_V_CNTL | + TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP) | + ENABLE_ADDR_U_CNTL | + TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP)); + + t->Setup[I830_TEXREG_MF] = (STATE3D_MAP_FILTER_CMD | + MAP_UNIT(0) | + ENABLE_MIP_MODE_FILTER | + MIPFILTER_NEAREST | + ENABLE_MAG_MODE_FILTER | + ENABLE_MIN_MODE_FILTER); + + t->dirty_images = ~0; + + tObj->DriverData = t; + make_empty_list( t ); + + i830SetTexWrapping( t, tObj->WrapS, tObj->WrapT ); + i830SetTexFilter( imesa, t, tObj->MinFilter, tObj->MagFilter, bias ); + i830SetTexBorderColor( t, tObj->BorderColor ); } - /* This only needs emitted when neccessary, fix it later */ - - /* add blend color */ - { - GLubyte r, g, b, a; - GLfloat *fc = texUnit->EnvColor; - - FLOAT_COLOR_TO_UBYTE_COLOR(r, fc[RCOMP]); - FLOAT_COLOR_TO_UBYTE_COLOR(g, fc[GCOMP]); - FLOAT_COLOR_TO_UBYTE_COLOR(b, fc[BCOMP]); - FLOAT_COLOR_TO_UBYTE_COLOR(a, fc[ACOMP]); - - col = ((a << 24) | - (r << 16) | - (g << 8) | - b); - } - - { - int i; - - i = imesa->TexBlendWordsUsed[unit]; - imesa->TexBlend[unit][i++] = STATE3D_COLOR_FACTOR_CMD(unit); - imesa->TexBlend[unit][i++] = col; - - imesa->TexBlendWordsUsed[unit] = i; - } - } - if(0) fprintf(stderr, "TexBlendWordsUsed : %d\n", imesa->TexBlendWordsUsed[unit]); -} - -void i830UpdateTextureState( GLcontext *ctx ) -{ - i830ContextPtr imesa = I830_CONTEXT(ctx); - int pipe_num = 0; - - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s\n", __FUNCTION__); - - if(ctx->Texture.ReallyEnabled & ~(TEXTURE0_2D|(TEXTURE0_2D<<4))) { - /* Bits are set for a fallback */ - if(0) fprintf(stderr, "Falling back to software for texturing\n"); - imesa->Fallback |= I830_FALLBACK_TEXTURE; - return; - } - imesa->LastTexEnabled = 0; - imesa->TexEnabledMask = 0; - - if (imesa->CurrentTexObj[0]) imesa->CurrentTexObj[0]->bound = 0; - if (imesa->CurrentTexObj[1]) imesa->CurrentTexObj[1]->bound = 0; - - imesa->CurrentTexObj[0] = 0; - imesa->CurrentTexObj[1] = 0; - - i830UpdateTexState( ctx, 0 ); - i830UpdateTexState( ctx, 1 ); - - i830UpdateTexBlend( ctx, 0 ); - i830UpdateTexBlend( ctx, 1 ); - - /* Need to decide the units to set to diffuse by looking at - * the texture units that actually got enabled */ - if(!(imesa->TexEnabledMask & I830_TEX_UNIT_ENABLED(0))) { - if(0) fprintf(stderr, "Diffuse got turned on\n"); - if(imesa->LastTexEnabled == 0) - imesa->LastTexEnabled = I830_TEX_UNIT_ENABLED(0); - - imesa->TexBlend[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) | - TEXPIPE_COLOR | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - DISABLE_TEX_CNTRL_STAGE | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - imesa->TexBlend[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) | - TEXPIPE_ALPHA | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - imesa->TexBlend[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) | - TEXPIPE_COLOR | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_DIFFUSE); - imesa->TexBlend[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) | - TEXPIPE_ALPHA | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_DIFFUSE); - imesa->TexBlendColorPipeNum[0] = 0; - imesa->TexBlendWordsUsed[0] = 4; - imesa->dirty |= I830_UPLOAD_TEXBLEND_N(0); - } - - switch(imesa->LastTexEnabled) { - case I830_TEX_UNIT_ENABLED(0): - if(0) fprintf(stderr, "Texture unit 0 is the last stage\n"); - pipe_num = imesa->TexBlendColorPipeNum[0]; - imesa->TexBlend[0][pipe_num] |= TEXOP_LAST_STAGE; - break; - case I830_TEX_UNIT_ENABLED(1): - if(0) fprintf(stderr, "Texture unit 1 is the last stage\n"); - pipe_num = imesa->TexBlendColorPipeNum[1]; - imesa->TexBlend[1][pipe_num] |= TEXOP_LAST_STAGE; - break; - default: break; - } - - /* Forces texture cache flush */ - imesa->dirty |= I830_UPLOAD_CTX; - if(imesa->TexEnabledMask & I830_TEX_UNIT_ENABLED(0)) { - if(0) fprintf(stderr, "Enabling Texture unit 0\n"); - imesa->dirty |= (I830_UPLOAD_TEX_N(0) | I830_UPLOAD_TEXBLEND_N(0)); - } - if(imesa->TexEnabledMask & I830_TEX_UNIT_ENABLED(1)) { - if(0) fprintf(stderr, "Enabling Texture unit 1\n"); - imesa->dirty |= (I830_UPLOAD_TEX_N(1) | I830_UPLOAD_TEXBLEND_N(1)); - } -} - - - -/***************************************** - * DRIVER functions - *****************************************/ - -/* TEXTURE_ENV_COLOR should be optimized, so we only flush when the - * color really changes - */ - -static void i830TexEnv( GLcontext *ctx, GLenum target, - GLenum pname, const GLfloat *param ) -{ - i830ContextPtr imesa = I830_CONTEXT( ctx ); - - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s\n", __FUNCTION__); - - /* Always flush texture state or texture_env_combine doesn't work */ - FLUSH_BATCH(imesa); - imesa->new_state |= I830_NEW_TEXTURE; -} - -static void i830TexImage( GLcontext *ctx, - GLenum target, - struct gl_texture_object *tObj, - GLint level, - GLint internalFormat, - const struct gl_texture_image *image ) -{ - i830ContextPtr imesa = I830_CONTEXT( ctx ); - i830TextureObjectPtr t; - - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (target != GL_TEXTURE_2D) - return; - - if (level >= I830_TEX_MAXLEVELS) - return; - - t = (i830TextureObjectPtr) tObj->DriverData; - if (t) { - if (t->bound) FLUSH_BATCH(imesa); - /* if this is the current object, it will force an update */ - i830DestroyTexObj( imesa, t ); - tObj->DriverData = 0; - imesa->new_state |= I830_NEW_TEXTURE; } } -static void i830TexSubImage( GLcontext *ctx, GLenum target, - struct gl_texture_object *tObj, GLint level, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLint internalFormat, - const struct gl_texture_image *image ) +static void i830DeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj ) { - i830ContextPtr imesa = I830_CONTEXT( ctx ); - i830TextureObjectPtr t; - - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s\n", __FUNCTION__); + i830TextureObjectPtr t = (i830TextureObjectPtr)tObj->DriverData; - if ( target != GL_TEXTURE_2D ) - return; - - t = (i830TextureObjectPtr) tObj->DriverData; if (t) { - if (t->bound) FLUSH_BATCH( imesa ); + i830ContextPtr imesa = I830_CONTEXT( ctx ); + if (imesa) + I830_FIREVERTICES( imesa ); i830DestroyTexObj( imesa, t ); tObj->DriverData = 0; - imesa->new_state |= I830_NEW_TEXTURE; } } -static void i830TexParameter( GLcontext *ctx, GLenum target, - struct gl_texture_object *tObj, - GLenum pname, const GLfloat *params ) -{ - i830TextureObjectPtr t = (i830TextureObjectPtr) tObj->DriverData; - i830ContextPtr imesa = I830_CONTEXT( ctx ); - - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (!t || target != GL_TEXTURE_2D) - return; - - switch (pname) { - case GL_TEXTURE_MIN_FILTER: - case GL_TEXTURE_MAG_FILTER: - if (t->bound) FLUSH_BATCH( imesa ); - i830SetTexFilter(imesa, t,tObj->MinFilter,tObj->MagFilter); - break; - - case GL_TEXTURE_WRAP_S: - case GL_TEXTURE_WRAP_T: - if (t->bound) FLUSH_BATCH( imesa ); - i830SetTexWrapping(t,tObj->WrapS,tObj->WrapT); - break; - - case GL_TEXTURE_BORDER_COLOR: - if (t->bound) FLUSH_BATCH( imesa ); - i830SetTexBorderColor(t,tObj->BorderColor); - break; - - default: - return; - } - - imesa->new_state |= I830_NEW_TEXTURE; -} - -static void i830BindTexture( GLcontext *ctx, GLenum target, - struct gl_texture_object *tObj ) +static GLboolean i830IsTextureResident( GLcontext *ctx, + struct gl_texture_object *tObj ) { - i830ContextPtr imesa = I830_CONTEXT( ctx ); - - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s\n", __FUNCTION__); - - FLUSH_BATCH(imesa); - - if (imesa->CurrentTexObj[ctx->Texture.CurrentUnit]) { - imesa->CurrentTexObj[ctx->Texture.CurrentUnit]->bound = 0; - imesa->CurrentTexObj[ctx->Texture.CurrentUnit] = 0; - } - - imesa->new_state |= I830_NEW_TEXTURE; + i830TextureObjectPtr t = (i830TextureObjectPtr)tObj->DriverData; + return t && t->MemBlock; } -static void i830DeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj ) +static const struct gl_texture_format * +i830ChooseTextureFormat( GLcontext *ctx, GLint internalFormat, + GLenum format, GLenum type ) { - i830TextureObjectPtr t = (i830TextureObjectPtr)tObj->DriverData; i830ContextPtr imesa = I830_CONTEXT( ctx ); + const GLboolean do32bpt = ( imesa->i830Screen->cpp == 4 && + imesa->i830Screen->textureSize > 4*1024*1024); - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (t) { + switch ( internalFormat ) { + case 4: + case GL_RGBA: + if ( format == GL_BGRA ) { + if ( type == GL_UNSIGNED_INT_8_8_8_8_REV ) { + return &_mesa_texformat_argb8888; + } + else if ( type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) { + return &_mesa_texformat_argb4444; + } + else if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) { + return &_mesa_texformat_argb1555; + } + } + return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444; - if (t->bound) { - FLUSH_BATCH(imesa); - imesa->CurrentTexObj[t->bound-1] = 0; - imesa->new_state |= I830_NEW_TEXTURE; + case 3: + case GL_RGB: + if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) { + return &_mesa_texformat_rgb565; } + return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565; - i830DestroyTexObj(imesa,t); - tObj->DriverData=0; - } -} + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444; + case GL_RGBA4: + case GL_RGBA2: + return &_mesa_texformat_argb4444; -static GLboolean i830IsTextureResident( GLcontext *ctx, - struct gl_texture_object *t ) -{ - i830TextureObjectPtr mt; + case GL_RGB5_A1: + return &_mesa_texformat_argb1555; -/* LOCK_HARDWARE; */ - mt = (i830TextureObjectPtr)t->DriverData; -/* UNLOCK_HARDWARE; */ + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565; - return mt && mt->MemBlock; -} + case GL_RGB5: + case GL_RGB4: + case GL_R3_G3_B2: + return &_mesa_texformat_rgb565; -static void -i830DDTexturePalette(GLcontext *ctx, struct gl_texture_object *tObj) -{ - i830ContextPtr imesa = I830_CONTEXT(ctx); - i830TextureObjectPtr t; + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + return &_mesa_texformat_al88; - imesa->new_state |= I830_NEW_TEXTURE; + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + return &_mesa_texformat_l8; - if(tObj) { - t = tObj->DriverData; + case 2: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + return &_mesa_texformat_al88; - if(!t) { - /* Will be handled elsewhere */ - return; - } + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + return &_mesa_texformat_i8; - i830ConvertPalette(t->palette, &tObj->Palette); - t->palette_format = tObj->Palette.Format; - } else { - i830ConvertPalette(imesa->palette, &ctx->Texture.Palette); - imesa->palette_format = ctx->Texture.Palette.Format; + default: + fprintf(stderr, "unexpected texture format in %s", __FUNCTION__); + return NULL; } + + return NULL; /* never get here */ } void i830DDInitTextureFuncs( GLcontext *ctx ) { - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s\n", __FUNCTION__); - ctx->Driver.TexEnv = i830TexEnv; - ctx->Driver.TexImage = i830TexImage; - ctx->Driver.TexSubImage = i830TexSubImage; + ctx->Driver.ChooseTextureFormat = i830ChooseTextureFormat; + ctx->Driver.TexImage1D = _mesa_store_teximage1d; + ctx->Driver.TexImage2D = i830TexImage2D; + ctx->Driver.TexImage3D = _mesa_store_teximage3d; + ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d; + ctx->Driver.TexSubImage2D = i830TexSubImage2D; + 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.BindTexture = i830BindTexture; ctx->Driver.DeleteTexture = i830DeleteTexture; ctx->Driver.TexParameter = i830TexParameter; - ctx->Driver.UpdateTexturePalette = i830DDTexturePalette; + ctx->Driver.UpdateTexturePalette = 0; ctx->Driver.IsTextureResident = i830IsTextureResident; + ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage; + + { + GLuint tmp = ctx->Texture.CurrentUnit; + ctx->Texture.CurrentUnit = 0; + i830BindTexture( ctx, GL_TEXTURE_2D, ctx->Texture.Unit[0].Current2D); + ctx->Texture.CurrentUnit = 1; + i830BindTexture( ctx, GL_TEXTURE_2D, ctx->Texture.Unit[1].Current2D); + ctx->Texture.CurrentUnit = tmp; + } } diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_tex.h b/xc/lib/GL/mesa/src/drv/i830/i830_tex.h new file mode 100644 index 000000000..03a898074 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/i830/i830_tex.h @@ -0,0 +1,90 @@ +/* + * 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"), + * 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 + * 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. + * + * Adapted for use in the I830M driver: + * Jeff Hartmann <jhartmann@2d3d.com> + */ + +#ifndef I830TEX_INC +#define I830TEX_INC + +#include "mtypes.h" +#include "mmath.h" +#include "mm.h" +#include "i830_context.h" +#include "i830_3d_reg.h" + +#define I830_TEX_MAXLEVELS 10 + +struct i830_texture_object_t +{ + struct i830_texture_object_t *next, *prev; + GLuint age; + struct gl_texture_object *globj; + int Pitch; + int Height; + int texelBytes; + int totalSize; + int bound; + PMemBlock MemBlock; + char *BufAddr; + GLuint min_level; + GLuint max_level; + GLuint dirty_images; + GLenum palette_format; + GLuint palette[256]; + struct + { + const struct gl_texture_image *image; + int offset; /* into BufAddr */ + int height; + int internalFormat; + }image[I830_TEX_MAXLEVELS]; + + /* Support for multitexture. + * */ + GLuint current_unit; + GLuint Setup[I830_TEX_SETUP_SIZE]; + GLuint dirty; + GLuint firstLevel,lastLevel; +}; + +void i830UpdateTextureState( GLcontext *ctx ); +void i830DDInitTextureFuncs( GLcontext *ctx ); +void i830UpdateTexUnitProj( GLcontext *ctx, GLuint unit, GLboolean state ); + + +void i830DestroyTexObj( i830ContextPtr imesa, i830TextureObjectPtr t ); +void i830SwapOutTexObj( i830ContextPtr imesa, i830TextureObjectPtr t ); +int i830UploadTexImages( i830ContextPtr imesa, i830TextureObjectPtr t ); + +void i830ResetGlobalLRU( i830ContextPtr imesa ); +void i830TexturesGone( i830ContextPtr imesa, + GLuint start, GLuint end, + GLuint in_use ); + +void i830PrintLocalLRU( i830ContextPtr imesa ); +void i830PrintGlobalLRU( i830ContextPtr imesa ); +void i830UpdateTexLRU( i830ContextPtr imesa, i830TextureObjectPtr t ); + + +#endif diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_texmem.c b/xc/lib/GL/mesa/src/drv/i830/i830_texmem.c new file mode 100644 index 000000000..16a5709ed --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/i830/i830_texmem.c @@ -0,0 +1,380 @@ +/************************************************************************** + +Copyright 2001 2d3d Inc., Delray Beach, FL + +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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS 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$ */ + +/* + * Author: + * Jeff Hartmann <jhartmann@2d3d.com> + * + * Heavily based on the I810 driver, which was written by: + * Keith Whitwell <keithw@tungstengraphics.com> + */ + +#include <stdlib.h> +#include <stdio.h> + +#include "glheader.h" +#include "macros.h" +#include "mtypes.h" +#include "simple_list.h" +#include "enums.h" +#include "texformat.h" + +#include "mm.h" + +#include "i830_screen.h" +#include "i830_dri.h" + +#include "i830_context.h" +#include "i830_tex.h" +#include "i830_state.h" +#include "i830_ioctl.h" + + +void i830DestroyTexObj(i830ContextPtr imesa, i830TextureObjectPtr t) +{ + if (!t) return; + + /* This is sad - need to sync *in case* we upload a texture + * to this newly free memory... + */ + if (t->MemBlock) { + mmFreeMem(t->MemBlock); + t->MemBlock = 0; + + if (imesa && t->age > imesa->dirtyAge) + imesa->dirtyAge = t->age; + } + + if (t->globj) + t->globj->DriverData = 0; + + if (imesa) { + if (imesa->CurrentTexObj[0] == t) { + imesa->CurrentTexObj[0] = 0; + imesa->dirty &= ~I830_UPLOAD_TEX0; + } + + if (imesa->CurrentTexObj[1] == t) { + imesa->CurrentTexObj[1] = 0; + imesa->dirty &= ~I830_UPLOAD_TEX1; + } + } + + remove_from_list(t); + free(t); +} + + +void i830SwapOutTexObj(i830ContextPtr imesa, i830TextureObjectPtr t) +{ +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + + if (t->MemBlock) { + mmFreeMem(t->MemBlock); + t->MemBlock = 0; + + if (t->age > imesa->dirtyAge) + imesa->dirtyAge = t->age; + } + + t->dirty_images = ~0; + move_to_tail(&(imesa->SwappedOut), t); +} + + + +/* Upload an image from mesa's internal copy. + */ +static void i830UploadTexLevel( i830TextureObjectPtr t, int level ) +{ + const struct gl_texture_image *image = t->image[level].image; + int i,j; + + if (0) fprintf(stderr, "Uploading level : %d\n", level); + + switch (image->TexFormat->MesaFormat) { + case MESA_FORMAT_I8: + case MESA_FORMAT_L8: + { + GLubyte *dst = (GLubyte *)(t->BufAddr + t->image[level].offset); + GLubyte *src = (GLubyte *)image->Data; + + for (j = 0 ; j < image->Height ; j++, dst += t->Pitch) { + for (i = 0 ; i < image->Width ; i++) { + dst[i] = src[0]; + src++; + } + } + } + break; + + case MESA_FORMAT_AL88: + case MESA_FORMAT_RGB565: + case MESA_FORMAT_ARGB1555: + case MESA_FORMAT_ARGB4444: + { + GLushort *dst = (GLushort *)(t->BufAddr + t->image[level].offset); + GLushort *src = (GLushort *)image->Data; + + for (j = 0 ; j < image->Height ; j++, dst += (t->Pitch/2)) { + for (i = 0 ; i < image->Width ; i++) { + dst[i] = src[0]; + src++; + } + } + } + break; + + case MESA_FORMAT_ARGB8888: + { + GLuint *dst = (GLuint *)(t->BufAddr + t->image[level].offset); + GLuint *src = (GLuint *)image->Data; + + for (j = 0 ; j < image->Height ; j++, dst += (t->Pitch/4)) { + for (i = 0 ; i < image->Width ; i++) { + dst[i] = src[0]; + src++; + } + } + } + break; + + default: + fprintf(stderr, "Not supported texture format %s\n", + _mesa_lookup_enum_by_nr(image->Format)); + } +} + +void i830PrintLocalLRU( i830ContextPtr imesa ) +{ + i830TextureObjectPtr t; + int sz = 1 << (imesa->i830Screen->logTextureGranularity); + + foreach( t, &imesa->TexObjList ) { + if (!t->globj) + fprintf(stderr, "Placeholder %d at %x sz %x\n", + t->MemBlock->ofs / sz, + t->MemBlock->ofs, + t->MemBlock->size); + else + fprintf(stderr, "Texture at %x sz %x\n", + t->MemBlock->ofs, + t->MemBlock->size); + + } +} + +void i830PrintGlobalLRU( i830ContextPtr imesa ) +{ + int i, j; + I830TexRegion *list = imesa->sarea->texList; + + for (i = 0, j = I830_NR_TEX_REGIONS ; i < I830_NR_TEX_REGIONS ; i++) { + fprintf(stderr, "list[%d] age %d next %d prev %d\n", + j, list[j].age, list[j].next, list[j].prev); + j = list[j].next; + if (j == I830_NR_TEX_REGIONS) break; + } + + if (j != I830_NR_TEX_REGIONS) + fprintf(stderr, "Loop detected in global LRU\n"); +} + + +void i830ResetGlobalLRU( i830ContextPtr imesa ) +{ + I830TexRegion *list = imesa->sarea->texList; + int sz = 1 << imesa->i830Screen->logTextureGranularity; + int i; + + /* (Re)initialize the global circular LRU list. The last element + * in the array (I830_NR_TEX_REGIONS) is the sentinal. Keeping it + * at the end of the array allows it to be addressed rationally + * when looking up objects at a particular location in texture + * memory. + */ + for (i = 0 ; (i+1) * sz <= imesa->i830Screen->textureSize ; i++) { + list[i].prev = i-1; + list[i].next = i+1; + list[i].age = 0; + } + + i--; + list[0].prev = I830_NR_TEX_REGIONS; + list[i].prev = i-1; + list[i].next = I830_NR_TEX_REGIONS; + list[I830_NR_TEX_REGIONS].prev = i; + list[I830_NR_TEX_REGIONS].next = 0; + imesa->sarea->texAge = 0; +} + + +void i830UpdateTexLRU( i830ContextPtr imesa, i830TextureObjectPtr t ) +{ + int i; + int logsz = imesa->i830Screen->logTextureGranularity; + int start = t->MemBlock->ofs >> logsz; + int end = (t->MemBlock->ofs + t->MemBlock->size - 1) >> logsz; + I830TexRegion *list = imesa->sarea->texList; + + imesa->texAge = ++imesa->sarea->texAge; + + /* Update our local LRU + */ + move_to_head( &(imesa->TexObjList), t ); + + /* Update the global LRU + */ + for (i = start ; i <= end ; i++) { + + list[i].in_use = 1; + list[i].age = imesa->texAge; + + /* remove_from_list(i) + */ + list[(unsigned)list[i].next].prev = list[i].prev; + list[(unsigned)list[i].prev].next = list[i].next; + + /* insert_at_head(list, i) + */ + list[i].prev = I830_NR_TEX_REGIONS; + list[i].next = list[I830_NR_TEX_REGIONS].next; + list[(unsigned)list[I830_NR_TEX_REGIONS].next].prev = i; + list[I830_NR_TEX_REGIONS].next = i; + } +} + + +/* Called for every shared texture region which has increased in age + * since we last held the lock. + * + * Figures out which of our textures have been ejected by other clients, + * and pushes a placeholder texture onto the LRU list to represent + * the other client's textures. + */ +void i830TexturesGone( i830ContextPtr imesa, + GLuint offset, + GLuint size, + GLuint in_use ) +{ + i830TextureObjectPtr t, tmp; + + if (I830_DEBUG&DEBUG_VERBOSE_TRACE) + fprintf(stderr, "%s\n", __FUNCTION__); + + foreach_s ( t, tmp, &imesa->TexObjList ) { + if (t->MemBlock->ofs >= offset + size || + t->MemBlock->ofs + t->MemBlock->size <= offset) + continue; + + /* It overlaps - kick it off. Need to hold onto the currently bound + * objects, however. + */ + if (t->bound) + i830SwapOutTexObj( imesa, t ); + else + i830DestroyTexObj( imesa, t ); + } + + if (in_use) { + t = (i830TextureObjectPtr) calloc(1,sizeof(*t)); + if (!t) return; + + t->MemBlock = mmAllocMem( imesa->texHeap, size, 0, offset); + insert_at_head( &imesa->TexObjList, t ); + } +} + + +/* This is called with the lock held. May have to eject our own and/or + * other client's texture objects to make room for the upload. + */ + +int i830UploadTexImages( i830ContextPtr imesa, i830TextureObjectPtr t ) +{ + int i; + int ofs; + int numLevels; + + /* Do we need to eject LRU texture objects? + */ + if (!t->MemBlock) { + while (1) + { + t->MemBlock = mmAllocMem( imesa->texHeap, t->totalSize, 12, 0 ); + if (t->MemBlock) + break; + + if (imesa->TexObjList.prev == imesa->CurrentTexObj[0] || + imesa->TexObjList.prev == imesa->CurrentTexObj[1]) { + fprintf(stderr, "Hit bound texture in upload\n"); + i830PrintLocalLRU( imesa ); + return -1; + } + + if (imesa->TexObjList.prev == &(imesa->TexObjList)) { + fprintf(stderr, "Failed to upload texture, sz %d\n", t->totalSize); + mmDumpMemInfo( imesa->texHeap ); + return -1; + } + + i830SwapOutTexObj( imesa, imesa->TexObjList.prev ); + } + + ofs = t->MemBlock->ofs; + t->BufAddr = imesa->i830Screen->tex.map + ofs; + t->Setup[I830_TEXREG_MI3] = imesa->i830Screen->textureOffset + ofs; + + if (t == imesa->CurrentTexObj[0]) + I830_STATECHANGE(imesa, I830_UPLOAD_TEX0); + + if (t == imesa->CurrentTexObj[1]) + I830_STATECHANGE(imesa, I830_UPLOAD_TEX1); +#if 0 + if (t == imesa->CurrentTexObj[2]) + I830_STATECHANGE(imesa, I830_UPLOAD_TEX2); + + if (t == imesa->CurrentTexObj[3]) + I830_STATECHANGE(imesa, I830_UPLOAD_TEX3); +#endif + i830UpdateTexLRU( imesa, t ); + } + + if (imesa->dirtyAge >= GET_DISPATCH_AGE(imesa)) + i830WaitAgeLocked( imesa, imesa->dirtyAge ); + + numLevels = t->lastLevel - t->firstLevel + 1; + for (i = 0 ; i < numLevels ; i++) + if (t->dirty_images & (1<<i)) + i830UploadTexLevel( t, i ); + + t->dirty_images = 0; + + return 0; +} diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_texstate.c b/xc/lib/GL/mesa/src/drv/i830/i830_texstate.c new file mode 100644 index 000000000..0f002cd50 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/i830/i830_texstate.c @@ -0,0 +1,1430 @@ +/************************************************************************** + +Copyright 2001 2d3d Inc., Delray Beach, FL + +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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS 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$ */ + +/* + * Author: + * Jeff Hartmann <jhartmann@2d3d.com> + * + * Heavily based on the I810 driver, which was written by: + * Keith Whitwell <keithw@tungstengraphics.com> + */ +#include <stdlib.h> +#include <stdio.h> + +#include "glheader.h" +#include "macros.h" +#include "mtypes.h" +#include "simple_list.h" +#include "enums.h" +#include "texformat.h" +#include "texstore.h" +#include "texutil.h" + +#include "mm.h" + +#include "i830_screen.h" +#include "i830_dri.h" + +#include "i830_context.h" +#include "i830_tex.h" +#include "i830_state.h" +#include "i830_ioctl.h" + +static void i830SetTexImages( i830ContextPtr imesa, + struct gl_texture_object *tObj ) +{ + GLuint height, width, pitch, i, textureFormat; + i830TextureObjectPtr t = (i830TextureObjectPtr) tObj->DriverData; + const struct gl_texture_image *baseImage = tObj->Image[tObj->BaseLevel]; + GLint firstLevel, lastLevel, numLevels; + GLint log2Width, log2Height; + + switch( baseImage->TexFormat->MesaFormat ) { + case MESA_FORMAT_L8: + t->texelBytes = 1; + textureFormat = MAPSURF_8BIT | MT_8BIT_L8; + break; + + case MESA_FORMAT_I8: + t->texelBytes = 1; + textureFormat = MAPSURF_8BIT | MT_8BIT_I8; + break; + + case MESA_FORMAT_AL88: + t->texelBytes = 2; + textureFormat = MAPSURF_16BIT | MT_16BIT_AY88; + break; + + case MESA_FORMAT_RGB565: + t->texelBytes = 2; + textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565; + break; + + case MESA_FORMAT_ARGB1555: + t->texelBytes = 2; + textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB1555; + break; + + case MESA_FORMAT_ARGB4444: + t->texelBytes = 2; + textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB4444; + break; + + case MESA_FORMAT_ARGB8888: + t->texelBytes = 4; + textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888; + break; + + default: + fprintf(stderr, "%s: bad image format\n", __FUNCTION__); + free( t ); + return; + } + + /* Compute which mipmap levels we really want to send to the hardware. + * This depends on the base image size, GL_TEXTURE_MIN_LOD, + * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL. + * Yes, this looks overly complicated, but it's all needed. + */ + if (tObj->MinFilter == GL_LINEAR || tObj->MinFilter == GL_NEAREST) { + firstLevel = lastLevel = tObj->BaseLevel; + } else { + firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5); + firstLevel = MAX2(firstLevel, tObj->BaseLevel); + lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5); + lastLevel = MAX2(lastLevel, tObj->BaseLevel); + lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2); + lastLevel = MIN2(lastLevel, tObj->MaxLevel); + lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */ + } + + /* save these values */ + t->firstLevel = firstLevel; + t->lastLevel = lastLevel; + + numLevels = lastLevel - firstLevel + 1; + + if (0) fprintf(stderr, + "%s : " + "NumLevels : %d\n" + "firstLevel : %d\n" + "lastLevel : %d\n", + __FUNCTION__, + numLevels, + firstLevel, + lastLevel); + + log2Width = tObj->Image[firstLevel]->WidthLog2; + log2Height = tObj->Image[firstLevel]->HeightLog2; + + /* Figure out the amount of memory required to hold all the mipmap + * levels. Choose the smallest pitch to accomodate the largest + * mipmap: + */ + width = tObj->Image[firstLevel]->Width * t->texelBytes; + + pitch = width; + + /* All images must be loaded at this pitch. Count the number of + * lines required: + */ + for ( height = i = 0 ; i < numLevels ; i++ ) { + t->image[i].image = tObj->Image[firstLevel + i]; + t->image[i].offset = height * pitch; + t->image[i].internalFormat = baseImage->Format; + height += t->image[i].image->Height; + } + + t->Pitch = pitch; + t->totalSize = height*pitch; + t->max_level = i-1; + + t->Setup[I830_TEXREG_MI1] = (MAP_INFO_TEX(0) | + textureFormat | + MAP_INFO_OUTMUX_F0F1F2F3 | + MAP_INFO_VERTLINESTRIDE_0 | + MAP_INFO_VERTLINESTRIDEOFS_0 | + MAP_INFO_FORMAT_2D | + MAP_INFO_USE_FENCE); + t->Setup[I830_TEXREG_MI2] = (((1 << log2Height) - 1) << 16) | + ((1 << log2Width) - 1); + t->Setup[I830_TEXREG_MI4] = ((pitch / 4) - 1) << 2; + + t->Setup[I830_TEXREG_MLL] = (STATE3D_MAP_LOD_LIMITS_CMD | + MAP_UNIT(0) | + ENABLE_MAX_MIP_LVL | + LOD_MAX(0) | + ENABLE_MIN_MIP_LVL | + LOD_MIN(numLevels - 1)); + + t->dirty = I830_UPLOAD_TEX0 | I830_UPLOAD_TEX1; + i830UploadTexImages( imesa, t ); +} + +/* ================================================================ + * Texture combine functions + */ +static __inline__ GLuint GetTexelOp(GLint unit) +{ + switch(unit) { + case 0: return TEXBLENDARG_TEXEL0; + case 1: return TEXBLENDARG_TEXEL1; + case 2: return TEXBLENDARG_TEXEL2; + case 3: return TEXBLENDARG_TEXEL3; + default: return TEXBLENDARG_TEXEL0; + } +} + +static void i830SetBlend_GL1_2(i830ContextPtr imesa, int curTex, + GLenum envMode, GLenum format) +{ + GLuint texel_op = GetTexelOp(curTex); + + if(I830_DEBUG&DEBUG_VERBOSE_TRACE) + fprintf(stderr, "%s %s %s unit (%d) texel_op(0x%x)\n", + __FUNCTION__, + _mesa_lookup_enum_by_nr(format), + _mesa_lookup_enum_by_nr(envMode), + curTex, + texel_op); + + switch(envMode) { + case GL_REPLACE: + switch(format) { + case GL_ALPHA: + imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + imesa->TexBlendColorPipeNum[curTex] = 0; + imesa->TexBlendWordsUsed[curTex] = 4; + break; + case GL_LUMINANCE: + case GL_RGB: + imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlendColorPipeNum[curTex] = 0; + imesa->TexBlendWordsUsed[curTex] = 4; + break; + + case GL_INTENSITY: + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + imesa->TexBlendColorPipeNum[curTex] = 0; + imesa->TexBlendWordsUsed[curTex] = 4; + break; + default: + /* Always set to passthru if something is funny */ + imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlendColorPipeNum[curTex] = 0; + imesa->TexBlendWordsUsed[curTex] = 4; + break; + } + break; + + case GL_MODULATE: + switch(format) { + case GL_ALPHA: + imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_MODULATE); + imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_ALPHA | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlendColorPipeNum[curTex] = 0; + imesa->TexBlendWordsUsed[curTex] = 5; + break; + + case GL_LUMINANCE: + case GL_RGB: + imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_MODULATE); + imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlendColorPipeNum[curTex] = 0; + imesa->TexBlendWordsUsed[curTex] = 5; + break; + + case GL_INTENSITY: + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_MODULATE); + imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_MODULATE); + imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + imesa->TexBlend[curTex][5] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_ALPHA | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlendColorPipeNum[curTex] = 0; + imesa->TexBlendWordsUsed[curTex] = 6; + break; + default: + /* Always set to passthru if something is funny */ + imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlendColorPipeNum[curTex] = 0; + imesa->TexBlendWordsUsed[curTex] = 4; + break; + } + break; + + case GL_DECAL: + switch(format) { + case GL_RGB: + imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlendColorPipeNum[curTex] = 0; + imesa->TexBlendWordsUsed[curTex] = 4; + break; + + case GL_RGBA: + imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_BLEND); + imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG0 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_REPLICATE_ALPHA | + texel_op); + imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlend[curTex][5] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlendColorPipeNum[curTex] = 0; + imesa->TexBlendWordsUsed[curTex] = 6; + break; + default: + /* Always set to passthru if something is funny */ + imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlendColorPipeNum[curTex] = 0; + imesa->TexBlendWordsUsed[curTex] = 4; + break; + } + break; + + case GL_BLEND: + switch(format) { + case GL_ALPHA: + imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_MODULATE); + imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_ALPHA | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlendColorPipeNum[curTex] = 0; + imesa->TexBlendWordsUsed[curTex] = 5; + break; + + case GL_LUMINANCE: + case GL_RGB: + imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_BLEND); + imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG0 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_FACTOR_N); + imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlend[curTex][5] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlendColorPipeNum[curTex] = 0; + imesa->TexBlendWordsUsed[curTex] = 6; + break; + + case GL_INTENSITY: + imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_BLEND); + imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_BLEND); + imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG0 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_FACTOR_N); + imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlend[curTex][5] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_ALPHA | + TEXBLEND_ARG0 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + imesa->TexBlend[curTex][6] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_FACTOR_N); + imesa->TexBlend[curTex][7] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_ALPHA | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlendColorPipeNum[curTex] = 0; + imesa->TexBlendWordsUsed[curTex] = 8; + break; + + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_BLEND); + imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_MODULATE); + imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG0 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_FACTOR_N); + imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlend[curTex][5] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + imesa->TexBlend[curTex][6] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_ALPHA | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlendColorPipeNum[curTex] = 0; + imesa->TexBlendWordsUsed[curTex] = 7; + break; + default: + /* Always set to passthru if something is funny */ + imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlendColorPipeNum[curTex] = 0; + imesa->TexBlendWordsUsed[curTex] = 4; + break; + } + break; + + case GL_ADD: + switch(format) { + case GL_ALPHA: + imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_MODULATE); + imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_ALPHA | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlendColorPipeNum[curTex] = 0; + imesa->TexBlendWordsUsed[curTex] = 5; + break; + case GL_LUMINANCE: + case GL_RGB: + imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ADD); + imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlendColorPipeNum[curTex] = 0; + imesa->TexBlendWordsUsed[curTex] = 5; + break; + + case GL_INTENSITY: + imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ADD); + imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ADD); + imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + imesa->TexBlend[curTex][5] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_ALPHA | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlendColorPipeNum[curTex] = 0; + imesa->TexBlendWordsUsed[curTex] = 6; + break; + + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ADD); + imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_MODULATE); + imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlend[curTex][4] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + imesa->TexBlend[curTex][5] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_ALPHA | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlendColorPipeNum[curTex] = 0; + imesa->TexBlendWordsUsed[curTex] = 6; + break; + default: + /* Always set to passthru if something is funny */ + imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlendColorPipeNum[curTex] = 0; + imesa->TexBlendWordsUsed[curTex] = 4; + break; + } + break; + default: + /* Always set to passthru if something is funny */ + imesa->TexBlend[curTex][0] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[curTex][1] = (STATE3D_MAP_BLEND_OP_CMD(curTex) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[curTex][2] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlend[curTex][3] = (STATE3D_MAP_BLEND_ARG_CMD(curTex) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlendColorPipeNum[curTex] = 0; + imesa->TexBlendWordsUsed[curTex] = 4; + break; + } + + if (I830_DEBUG&DEBUG_VERBOSE_TRACE) + fprintf(stderr, "%s\n", __FUNCTION__); +} + +static void i830SetTexEnvCombine(i830ContextPtr imesa, + const struct gl_texture_unit *texUnit, + GLint unit) +{ + GLuint blendop; + GLuint ablendop; + GLuint args_RGB[3]; + GLuint args_A[3]; + GLuint texel_op = GetTexelOp(unit); + int i; + + if(I830_DEBUG&DEBUG_VERBOSE_TRACE) + fprintf(stderr, "%s\n", __FUNCTION__); + + switch(texUnit->CombineModeRGB) { + case GL_REPLACE: blendop = TEXBLENDOP_ARG1; break; + case GL_MODULATE: blendop = TEXBLENDOP_MODULATE; break; + case GL_ADD: blendop = TEXBLENDOP_ADD; break; + case GL_ADD_SIGNED_ARB: + blendop = TEXBLENDOP_ADDSIGNED; break; + case GL_INTERPOLATE_ARB: + blendop = TEXBLENDOP_BLEND; break; + case GL_SUBTRACT_ARB: blendop = TEXBLENDOP_SUBTRACT; break; + default: return; + } + + switch(texUnit->CombineScaleShiftRGB) { + case 0: blendop |= TEXOP_SCALE_1X; break; + case 1: blendop |= TEXOP_SCALE_2X; break; + case 2: blendop |= TEXOP_SCALE_4X; break; + default: return; + } + + switch(texUnit->CombineModeA) { + case GL_REPLACE: ablendop = TEXBLENDOP_ARG1; break; + case GL_MODULATE: ablendop = TEXBLENDOP_MODULATE; break; + case GL_ADD: ablendop = TEXBLENDOP_ADD; break; + case GL_ADD_SIGNED_ARB: + ablendop = TEXBLENDOP_ADDSIGNED; break; + case GL_INTERPOLATE_ARB: + ablendop = TEXBLENDOP_BLEND; break; + case GL_SUBTRACT_ARB: ablendop = TEXBLENDOP_SUBTRACT; break; + default: return; + } + + switch(texUnit->CombineScaleShiftA) { + case 0: ablendop |= TEXOP_SCALE_1X; break; + case 1: ablendop |= TEXOP_SCALE_2X; break; + case 2: ablendop |= TEXOP_SCALE_4X; break; + default: return; + } + + /* Handle RGB args */ + for(i = 0; i < 3; i++) { + switch(texUnit->CombineSourceRGB[i]) { + case GL_TEXTURE: args_RGB[i] = texel_op; break; + case GL_CONSTANT_ARB: + args_RGB[i] = TEXBLENDARG_FACTOR_N; break; + case GL_PRIMARY_COLOR_ARB: + args_RGB[i] = TEXBLENDARG_DIFFUSE; break; + case GL_PREVIOUS_ARB: + args_RGB[i] = TEXBLENDARG_CURRENT; break; + default: return; + } + + switch(texUnit->CombineOperandRGB[i]) { + case GL_SRC_COLOR: args_RGB[i] |= 0; break; + case GL_ONE_MINUS_SRC_COLOR: args_RGB[i] |= TEXBLENDARG_INV_ARG; break; + case GL_SRC_ALPHA: args_RGB[i] |= TEXBLENDARG_REPLICATE_ALPHA; break; + case GL_ONE_MINUS_SRC_ALPHA: + args_RGB[i] |= (TEXBLENDARG_REPLICATE_ALPHA | + TEXBLENDARG_INV_ARG); + break; + default: return; + } + } + + /* Handle A args */ + for(i = 0; i < 3; i++) { + switch(texUnit->CombineSourceA[i]) { + case GL_TEXTURE: args_A[i] = texel_op; break; + case GL_CONSTANT_ARB: + args_A[i] = TEXBLENDARG_FACTOR_N; break; + case GL_PRIMARY_COLOR_ARB: + args_A[i] = TEXBLENDARG_DIFFUSE; break; + case GL_PREVIOUS_ARB: + args_A[i] = TEXBLENDARG_CURRENT; break; + default: return; + } + + switch(texUnit->CombineOperandA[i]) { + case GL_SRC_ALPHA: args_A[i] |= 0; break; + case GL_ONE_MINUS_SRC_ALPHA: args_A[i] |= TEXBLENDARG_INV_ARG; break; + default: return; + } + } + + /* Native Arg1 == Arg0 in GL_EXT_texture_env_combine spec */ + /* Native Arg2 == Arg1 in GL_EXT_texture_env_combine spec */ + /* Native Arg0 == Arg2 in GL_EXT_texture_env_combine spec */ + + /* When we render we need to figure out which is the last really enabled + * tex unit, and put last stage on it + */ + + imesa->TexBlendColorPipeNum[unit] = 0; + + /* Build color pipeline */ + + imesa->TexBlend[unit][0] = (STATE3D_MAP_BLEND_OP_CMD(unit) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_MODIFY_PARMS | + blendop); + imesa->TexBlend[unit][1] = (STATE3D_MAP_BLEND_ARG_CMD(unit) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + args_RGB[0]); + imesa->TexBlend[unit][2] = (STATE3D_MAP_BLEND_ARG_CMD(unit) | + TEXPIPE_COLOR | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + args_RGB[1]); + imesa->TexBlend[unit][3] = (STATE3D_MAP_BLEND_ARG_CMD(unit) | + TEXPIPE_COLOR | + TEXBLEND_ARG0 | + TEXBLENDARG_MODIFY_PARMS | + args_RGB[2]); + + /* Build Alpha pipeline */ + imesa->TexBlend[unit][4] = (STATE3D_MAP_BLEND_OP_CMD(unit) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_MODIFY_PARMS | + ablendop); + imesa->TexBlend[unit][5] = (STATE3D_MAP_BLEND_ARG_CMD(unit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + args_A[0]); + imesa->TexBlend[unit][6] = (STATE3D_MAP_BLEND_ARG_CMD(unit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + args_A[1]); + imesa->TexBlend[unit][7] = (STATE3D_MAP_BLEND_ARG_CMD(unit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG0 | + TEXBLENDARG_MODIFY_PARMS | + args_A[2]); + + { + GLubyte r, g, b, a; + GLfloat *fc = texUnit->EnvColor; + + FLOAT_COLOR_TO_UBYTE_COLOR(r, fc[RCOMP]); + FLOAT_COLOR_TO_UBYTE_COLOR(g, fc[GCOMP]); + FLOAT_COLOR_TO_UBYTE_COLOR(b, fc[BCOMP]); + FLOAT_COLOR_TO_UBYTE_COLOR(a, fc[ACOMP]); + + imesa->TexBlend[unit][8] = STATE3D_COLOR_FACTOR_CMD(unit); + imesa->TexBlend[unit][9] = ((a << 24) | + (r << 16) | + (g << 8) | + b); + } + imesa->TexBlendWordsUsed[unit] = 10; +} + + + + +static void i830UpdateTexEnv( GLcontext *ctx, GLuint unit ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + const struct gl_texture_object *tObj = texUnit->_Current; + i830TextureObjectPtr t = (i830TextureObjectPtr)tObj->DriverData; + GLuint col; + + imesa->TexBlendWordsUsed[unit] = 0; + + if (0) fprintf(stderr, "i830UpdateTexEnv called : %s\n", + _mesa_lookup_enum_by_nr(texUnit->EnvMode)); + + if(texUnit->EnvMode == GL_COMBINE_ARB) { + i830SetTexEnvCombine(imesa, + texUnit, + unit); + } else { + i830SetBlend_GL1_2(imesa, + unit, + texUnit->EnvMode, + t->image[0].internalFormat); + + /* add blend color */ + { + GLubyte r, g, b, a; + GLfloat *fc = texUnit->EnvColor; + + FLOAT_COLOR_TO_UBYTE_COLOR(r, fc[RCOMP]); + FLOAT_COLOR_TO_UBYTE_COLOR(g, fc[GCOMP]); + FLOAT_COLOR_TO_UBYTE_COLOR(b, fc[BCOMP]); + FLOAT_COLOR_TO_UBYTE_COLOR(a, fc[ACOMP]); + + col = ((a << 24) | + (r << 16) | + (g << 8) | + b); + } + + { + int i; + + i = imesa->TexBlendWordsUsed[unit]; + imesa->TexBlend[unit][i++] = STATE3D_COLOR_FACTOR_CMD(unit); + imesa->TexBlend[unit][i++] = col; + + imesa->TexBlendWordsUsed[unit] = i; + } + } + + I830_STATECHANGE( imesa, I830_UPLOAD_TEXBLEND_N(unit) ); +} + + +static void i830TexSetUnit( i830TextureObjectPtr t, GLuint unit ) +{ + if(I830_DEBUG&DEBUG_VERBOSE_TRACE) + fprintf(stderr, "%s unit(%d)\n", __FUNCTION__, unit); + + /* This will need to be changed when I support more then 2 t units */ + I830_SET_FIELD(t->Setup[I830_TEXREG_MI1], + MAP_INFO_MASK | MAP_INFO_USE_PALETTE_1, + MAP_INFO_TEX(unit) | MAP_INFO_USE_PALETTE_N(unit)); + I830_SET_FIELD(t->Setup[I830_TEXREG_MLC], MAP_UNIT_MASK, MAP_UNIT(unit)); + I830_SET_FIELD(t->Setup[I830_TEXREG_MLL], MAP_UNIT_MASK, MAP_UNIT(unit)); + I830_SET_FIELD(t->Setup[I830_TEXREG_MCS], MAP_UNIT_MASK, MAP_UNIT(unit)); + I830_SET_FIELD(t->Setup[I830_TEXREG_MF], MAP_UNIT_MASK, MAP_UNIT(unit)); + + t->current_unit = unit; +} + +#define TEXCOORDTYPE_MASK (~((1<<13)|(1<<12)|(1<<11))) + +static void i830UpdateTexUnit( GLcontext *ctx, GLuint unit ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + + imesa->TexEnabledMask &= ~(I830_TEX_UNIT_ENABLED(unit)); + + if (texUnit->_ReallyEnabled == TEXTURE0_2D) { + struct gl_texture_object *tObj = texUnit->_Current; + i830TextureObjectPtr t = (i830TextureObjectPtr)tObj->DriverData; + GLuint mcs = t->Setup[I830_TEXREG_MCS] & TEXCOORDTYPE_MASK; + + /* Handle projective texturing */ + if (imesa->vertex_format & (1<<31)) { + mcs |= TEXCOORDTYPE_HOMOGENEOUS; + } else { + mcs |= TEXCOORDTYPE_CARTESIAN; + } + + /* Upload teximages (not pipelined) + */ + if (t->dirty_images) { + I830_FIREVERTICES(imesa); + i830SetTexImages( imesa, tObj ); + if (!t->MemBlock) { + FALLBACK( imesa, I830_FALLBACK_TEXTURE, GL_TRUE ); + return; + } + } + + /* Update state if this is a different texture object to last + * time. + */ + if (imesa->CurrentTexObj[unit] != t || + mcs != t->Setup[I830_TEXREG_MCS]) { + I830_STATECHANGE(imesa, (I830_UPLOAD_TEX0<<unit)); + t->Setup[I830_TEXREG_MCS] = mcs; + imesa->CurrentTexObj[unit] = t; + i830TexSetUnit(t, unit); + } + + /* Update texture environment if texture object image format or + * texture environment state has changed. + */ + if (tObj->Image[tObj->BaseLevel]->Format != + imesa->TexEnvImageFmt[unit]) { + imesa->TexEnvImageFmt[unit] = tObj->Image[tObj->BaseLevel]->Format; + i830UpdateTexEnv( ctx, unit ); + } + imesa->TexEnabledMask |= I830_TEX_UNIT_ENABLED(unit); + } + else if (texUnit->_ReallyEnabled) { + FALLBACK( imesa, I830_FALLBACK_TEXTURE, GL_TRUE ); + } + else if (unit == 0) { + /* This is happening too often. I need to conditionally send diffuse + * state to the card. Perhaps a diffuse dirty flag of some kind. + * Will need to change this logic if more than 2 texture units are + * used. We need to only do this up to the last unit enabled, or unit + * one if nothing is enabled. + */ + imesa->CurrentTexObj[unit] = 0; + imesa->TexEnvImageFmt[unit] = 0; + imesa->dirty &= ~(I830_UPLOAD_TEX_N(unit)); + + imesa->TexBlend[unit][0] = (STATE3D_MAP_BLEND_OP_CMD(unit) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[unit][1] = (STATE3D_MAP_BLEND_OP_CMD(unit) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[unit][2] = (STATE3D_MAP_BLEND_ARG_CMD(unit) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlend[unit][3] = (STATE3D_MAP_BLEND_ARG_CMD(unit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlendColorPipeNum[unit] = 0; + imesa->TexBlendWordsUsed[unit] = 4; + I830_STATECHANGE(imesa, (I830_UPLOAD_TEXBLEND_N(unit))); + } +} + +/* Called from vb code to update projective texturing properly */ +void i830UpdateTexUnitProj( GLcontext *ctx, GLuint unit, GLboolean state ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + + if (texUnit->_ReallyEnabled == TEXTURE0_2D) { + struct gl_texture_object *tObj = texUnit->_Current; + i830TextureObjectPtr t = (i830TextureObjectPtr)tObj->DriverData; + GLuint mcs = t->Setup[I830_TEXREG_MCS] & TEXCOORDTYPE_MASK; + + /* Handle projective texturing */ + if (state) { + mcs |= TEXCOORDTYPE_HOMOGENEOUS; + } else { + mcs |= TEXCOORDTYPE_CARTESIAN; + } + + if (mcs != t->Setup[I830_TEXREG_MCS]) { + I830_STATECHANGE(imesa, (I830_UPLOAD_TEX0<<unit)); + t->Setup[I830_TEXREG_MCS] = mcs; + } + } +} + +/* Only deal with unit 0 and 1 for right now */ +void i830UpdateTextureState( GLcontext *ctx ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + int pipe_num = 0; + + if (0) fprintf(stderr, "%s\n", __FUNCTION__); + FALLBACK( imesa, I830_FALLBACK_TEXTURE, GL_FALSE ); + + i830UpdateTexUnit( ctx, 0 ); + i830UpdateTexUnit( ctx, 1 ); +#if 0 + i830UpdateTexUnit( ctx, 2 ); + i830UpdateTexUnit( ctx, 3 ); +#endif + + /* Make sure last stage is set correctly */ +#if 0 + if(imesa->TexEnabledMask & I830_TEX_UNIT_ENABLED(3)) { + pipe_num = imesa->TexBlendColorPipeNum[3]; + imesa->TexBlend[3][pipe_num] |= TEXOP_LAST_STAGE; + } else if(imesa->TexEnabledMask & I830_TEX_UNIT_ENABLED(2)) { + pipe_num = imesa->TexBlendColorPipeNum[2]; + imesa->TexBlend[2][pipe_num] |= TEXOP_LAST_STAGE; + } else +#endif + if(imesa->TexEnabledMask & I830_TEX_UNIT_ENABLED(1)) { + pipe_num = imesa->TexBlendColorPipeNum[1]; + imesa->TexBlend[1][pipe_num] |= TEXOP_LAST_STAGE; + if (0) fprintf(stderr, "Unit One is last enabled\n"); + } else { + pipe_num = imesa->TexBlendColorPipeNum[0]; + imesa->TexBlend[0][pipe_num] |= TEXOP_LAST_STAGE; + if (0) fprintf(stderr, "Unit Zero is last enabled\n"); + } +} + + + diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_tris.c b/xc/lib/GL/mesa/src/drv/i830/i830_tris.c index d9a547a56..a239fd4f9 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_tris.c +++ b/xc/lib/GL/mesa/src/drv/i830/i830_tris.c @@ -1,3 +1,4 @@ +/* $XFree86$ */ /************************************************************************** Copyright 2001 VA Linux Systems Inc., Fremont, California. @@ -25,159 +26,820 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_tris.c,v 1.1 2001/10/04 18:28:21 alanh Exp $ */ - /* - * Author: - * Jeff Hartmann <jhartmann@valinux.com> - * - * Heavily based on the I810 driver, which was written by: - * Keith Whitwell <keithw@valinux.com> + * Original Authors: + * Keith Whitwell <keith@tungstengraphics.com> + * Adapted for use on the I830M: + * Jeff Hartmann <jhartmann@2d3d.com> */ #include <stdio.h> #include <math.h> -#include "types.h" -#include "vb.h" -#include "pipeline.h" +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "enums.h" +#include "dd.h" -#include "mm.h" +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" + +#include "i830_screen.h" +#include "i830_dri.h" -#include "i830_drv.h" #include "i830_tris.h" +#include "i830_state.h" +#include "i830_vb.h" +#include "i830_ioctl.h" + +static void i830RenderPrimitive( GLcontext *ctx, GLenum prim ); + +/*********************************************************************** + * Emit primitives as inline vertices * + ***********************************************************************/ + +#if defined(USE_X86_ASM) +#define COPY_DWORDS( j, vb, vertsize, v ) \ +do { \ + int __tmp; \ + __asm__ __volatile__( "rep ; movsl" \ + : "=%c" (j), "=D" (vb), "=S" (__tmp) \ + : "0" (vertsize), \ + "D" ((long)vb), \ + "S" ((long)v) ); \ +} while (0) +#else +#define COPY_DWORDS( j, vb, vertsize, v ) \ +do { \ + for ( j = 0 ; j < vertsize ; j++ ) \ + vb[j] = ((GLuint *)v)[j]; \ + vb += vertsize; \ +} while (0) +#endif + +static void __inline__ i830_draw_triangle( i830ContextPtr imesa, + i830VertexPtr v0, + i830VertexPtr v1, + i830VertexPtr v2 ) +{ + GLuint vertsize = imesa->vertex_size; + GLuint *vb = i830AllocDmaLow( imesa, 3 * 4 * vertsize ); + int j; -/* Used in i830tritmp.h - */ -#define I830_COLOR(to, from) { \ - (to)[0] = (from)[2]; \ - (to)[1] = (from)[1]; \ - (to)[2] = (from)[0]; \ - (to)[3] = (from)[3]; \ + COPY_DWORDS( j, vb, vertsize, v0 ); + COPY_DWORDS( j, vb, vertsize, v1 ); + COPY_DWORDS( j, vb, vertsize, v2 ); } -#define I830_COLOR3(to, from) { \ - (to)[0] = (from)[2]; \ - (to)[1] = (from)[1]; \ - (to)[2] = (from)[0]; \ + +static void __inline__ i830_draw_quad( i830ContextPtr imesa, + i830VertexPtr v0, + i830VertexPtr v1, + i830VertexPtr v2, + i830VertexPtr v3 ) +{ + GLuint vertsize = imesa->vertex_size; + GLuint *vb = i830AllocDmaLow( imesa, 6 * 4 * vertsize ); + int j; + + COPY_DWORDS( j, vb, vertsize, v0 ); + COPY_DWORDS( j, vb, vertsize, v1 ); + COPY_DWORDS( j, vb, vertsize, v3 ); + COPY_DWORDS( j, vb, vertsize, v1 ); + COPY_DWORDS( j, vb, vertsize, v2 ); + COPY_DWORDS( j, vb, vertsize, v3 ); } -static triangle_func tri_tab[0x10]; -static quad_func quad_tab[0x10]; -static line_func line_tab[0x10]; -static points_func points_tab[0x10]; -#define IND (0) +static __inline__ void i830_draw_point( i830ContextPtr imesa, + i830VertexPtr tmp ) +{ + GLuint vertsize = imesa->vertex_size; + GLuint *vb = i830AllocDmaLow( imesa, 4 * vertsize ); + int j; + + /* Adjust for sub pixel position */ + *(float *)&vb[0] = tmp->v.x - 0.125; + *(float *)&vb[1] = tmp->v.y - 0.125; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp->ui[j]; +} + + +static __inline__ void i830_draw_line( i830ContextPtr imesa, + i830VertexPtr v0, + i830VertexPtr v1 ) +{ + GLuint vertsize = imesa->vertex_size; + GLuint *vb = i830AllocDmaLow( imesa, 2 * 4 * vertsize ); + int j; + + COPY_DWORDS( j, vb, vertsize, v0 ); + COPY_DWORDS( j, vb, vertsize, v1 ); +} + + + +/*********************************************************************** + * Macros for t_dd_tritmp.h to draw basic primitives * + ***********************************************************************/ + +#define TRI( a, b, c ) \ +do { \ + if (DO_FALLBACK) \ + imesa->draw_tri( imesa, a, b, c ); \ + else \ + i830_draw_triangle( imesa, a, b, c ); \ +} while (0) + +#define QUAD( a, b, c, d ) \ +do { \ + if (DO_FALLBACK) { \ + imesa->draw_tri( imesa, a, b, d ); \ + imesa->draw_tri( imesa, b, c, d ); \ + } else \ + i830_draw_quad( imesa, a, b, c, d ); \ +} while (0) + +#define LINE( v0, v1 ) \ +do { \ + if (DO_FALLBACK) \ + imesa->draw_line( imesa, v0, v1 ); \ + else \ + i830_draw_line( imesa, v0, v1 ); \ +} while (0) + +#define POINT( v0 ) \ +do { \ + if (DO_FALLBACK) \ + imesa->draw_point( imesa, v0 ); \ + else \ + i830_draw_point( imesa, v0 ); \ +} while (0) + + +/*********************************************************************** + * Build render functions from dd templates * + ***********************************************************************/ + +#define I830_OFFSET_BIT 0x01 +#define I830_TWOSIDE_BIT 0x02 +#define I830_UNFILLED_BIT 0x04 +#define I830_FALLBACK_BIT 0x08 +#define I830_MAX_TRIFUNC 0x10 + + +static struct { + points_func points; + line_func line; + triangle_func triangle; + quad_func quad; +} rast_tab[I830_MAX_TRIFUNC]; + + +#define DO_FALLBACK (IND & I830_FALLBACK_BIT) +#define DO_OFFSET (IND & I830_OFFSET_BIT) +#define DO_UNFILLED (IND & I830_UNFILLED_BIT) +#define DO_TWOSIDE (IND & I830_TWOSIDE_BIT) +#define DO_FLAT 0 +#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 1 +#define HAVE_BACK_COLORS 0 +#define HAVE_HW_FLATSHADE 1 +#define VERTEX i830Vertex +#define TAB rast_tab + +/* Only used to pull back colors into vertices (ie, we know color is + * floating point). + */ +#define I830_COLOR( dst, src ) \ +do { \ + dst[0] = src[2]; \ + dst[1] = src[1]; \ + dst[2] = src[0]; \ + dst[3] = src[3]; \ +} while (0) + +#define I830_SPEC( dst, src ) \ +do { \ + dst[0] = src[2]; \ + dst[1] = src[1]; \ + dst[2] = src[0]; \ +} while (0) + + +#define DEPTH_SCALE (imesa->depth_scale) +#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) (imesa->verts + (e<<imesa->vertex_stride_shift)) + +#define VERT_SET_RGBA( v, c ) I830_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 VERT_SET_SPEC( v, c ) if (havespec) I830_SPEC( v->ub4[5], c ) +#define VERT_COPY_SPEC( v0, v1 ) if (havespec) COPY_3V(v0->ub4[5], v1->ub4[5]) +#define VERT_SAVE_SPEC( idx ) if (havespec) spec[idx] = v[idx]->ui[5] +#define VERT_RESTORE_SPEC( idx ) if (havespec) v[idx]->ui[5] = spec[idx] + +#define LOCAL_VARS(n) \ + i830ContextPtr imesa = I830_CONTEXT(ctx); \ + GLuint color[n], spec[n]; \ + GLuint coloroffset = (imesa->vertex_size == 4 ? 3 : 4); \ + GLboolean havespec = (imesa->vertex_size > 4); \ + (void) color; (void) spec; (void) coloroffset; (void) havespec; + + +/*********************************************************************** + * Helpers for rendering unfilled primitives * + ***********************************************************************/ + +static const GLuint hw_prim[GL_POLYGON+1] = { + PRIM3D_POINTLIST, + PRIM3D_LINELIST, + PRIM3D_LINELIST, + PRIM3D_LINELIST, + PRIM3D_TRILIST, + PRIM3D_TRILIST, + PRIM3D_TRILIST, + PRIM3D_TRILIST, + PRIM3D_TRILIST, + PRIM3D_TRILIST +}; + +#define RASTERIZE(x) if (imesa->hw_primitive != hw_prim[x]) \ + i830RasterPrimitive( ctx, x, hw_prim[x] ) +#define RENDER_PRIMITIVE imesa->render_primitive #define TAG(x) x -#include "i830_tritmp.h" +#define IND I830_FALLBACK_BIT +#include "tnl_dd/t_dd_unfilled.h" +#undef IND -#define IND (I830_FLAT_BIT) -#define TAG(x) x##_flat -#include "i830_tritmp.h" +/*********************************************************************** + * Generate GL render functions * + ***********************************************************************/ -#define IND (I830_OFFSET_BIT) -#define TAG(x) x##_offset -#include "i830_tritmp.h" +#define IND (0) +#define TAG(x) x +#include "tnl_dd/t_dd_tritmp.h" -#define IND (I830_OFFSET_BIT|I830_FLAT_BIT) -#define TAG(x) x##_offset_flat -#include "i830_tritmp.h" +#define IND (I830_OFFSET_BIT) +#define TAG(x) x##_offset +#include "tnl_dd/t_dd_tritmp.h" -#define IND (I830_TWOSIDE_BIT) +#define IND (I830_TWOSIDE_BIT) #define TAG(x) x##_twoside -#include "i830_tritmp.h" - -#define IND (I830_TWOSIDE_BIT|I830_FLAT_BIT) -#define TAG(x) x##_twoside_flat -#include "i830_tritmp.h" +#include "tnl_dd/t_dd_tritmp.h" -#define IND (I830_TWOSIDE_BIT|I830_OFFSET_BIT) +#define IND (I830_TWOSIDE_BIT|I830_OFFSET_BIT) #define TAG(x) x##_twoside_offset -#include "i830_tritmp.h" +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I830_UNFILLED_BIT) +#define TAG(x) x##_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I830_OFFSET_BIT|I830_UNFILLED_BIT) +#define TAG(x) x##_offset_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I830_TWOSIDE_BIT|I830_UNFILLED_BIT) +#define TAG(x) x##_twoside_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I830_TWOSIDE_BIT|I830_OFFSET_BIT|I830_UNFILLED_BIT) +#define TAG(x) x##_twoside_offset_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I830_FALLBACK_BIT) +#define TAG(x) x##_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I830_OFFSET_BIT|I830_FALLBACK_BIT) +#define TAG(x) x##_offset_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I830_TWOSIDE_BIT|I830_FALLBACK_BIT) +#define TAG(x) x##_twoside_fallback +#include "tnl_dd/t_dd_tritmp.h" -#define IND (I830_TWOSIDE_BIT|I830_OFFSET_BIT|I830_FLAT_BIT) -#define TAG(x) x##_twoside_offset_flat -#include "i830_tritmp.h" +#define IND (I830_TWOSIDE_BIT|I830_OFFSET_BIT|I830_FALLBACK_BIT) +#define TAG(x) x##_twoside_offset_fallback +#include "tnl_dd/t_dd_tritmp.h" +#define IND (I830_UNFILLED_BIT|I830_FALLBACK_BIT) +#define TAG(x) x##_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" +#define IND (I830_OFFSET_BIT|I830_UNFILLED_BIT|I830_FALLBACK_BIT) +#define TAG(x) x##_offset_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" -void i830DDTrifuncInit() +#define IND (I830_TWOSIDE_BIT|I830_UNFILLED_BIT|I830_FALLBACK_BIT) +#define TAG(x) x##_twoside_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I830_TWOSIDE_BIT|I830_OFFSET_BIT|I830_UNFILLED_BIT| \ + I830_FALLBACK_BIT) +#define TAG(x) x##_twoside_offset_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + + +static void init_rast_tab( void ) { init(); - init_flat(); init_offset(); - init_offset_flat(); init_twoside(); - init_twoside_flat(); init_twoside_offset(); - init_twoside_offset_flat(); -} - - - -#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_UNFILLED | DD_TRI_STIPPLE | DD_TRI_SMOOTH) -#define ANY_FALLBACK (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK|DD_TRI_STIPPLE) -#define ANY_RASTER_FLAGS (DD_FLATSHADE|DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET) - -void i830DDChooseRenderState(GLcontext *ctx) -{ - i830ContextPtr imesa = I830_CONTEXT(ctx); - GLuint flags = ctx->TriangleCaps; - CARD32 index = 0; - - if (imesa->Fallback) { - imesa->renderindex = I830_FALLBACK_BIT; - return; - } - - if (flags & ANY_RASTER_FLAGS) { - if (flags & DD_FLATSHADE) index |= I830_FLAT_BIT; - if (flags & DD_TRI_LIGHT_TWOSIDE) index |= I830_TWOSIDE_BIT; - if (flags & DD_TRI_OFFSET) index |= I830_OFFSET_BIT; - } - - imesa->PointsFunc = points_tab[index]; - imesa->LineFunc = line_tab[index]; - imesa->TriangleFunc = tri_tab[index]; - imesa->QuadFunc = quad_tab[index]; - imesa->renderindex = index; - imesa->IndirectTriangles = 0; - - if (flags & ANY_FALLBACK) { - if (flags & POINT_FALLBACK) { - imesa->renderindex |= I830_FALLBACK_BIT; - imesa->PointsFunc = 0; - imesa->IndirectTriangles |= DD_POINT_SW_RASTERIZE; - } - - if (flags & LINE_FALLBACK) { - imesa->renderindex |= I830_FALLBACK_BIT; - imesa->LineFunc = 0; - imesa->IndirectTriangles |= DD_LINE_SW_RASTERIZE; - } - - if (flags & TRI_FALLBACK) { - imesa->renderindex |= I830_FALLBACK_BIT; - imesa->TriangleFunc = 0; - imesa->QuadFunc = 0; - imesa->IndirectTriangles |= (DD_TRI_SW_RASTERIZE | - DD_QUAD_SW_RASTERIZE); - } - /* Special cases: - */ - if ((flags & DD_TRI_STIPPLE) && - (ctx->IndirectTriangles & DD_TRI_STIPPLE)) { - imesa->renderindex |= I830_FALLBACK_BIT; - imesa->TriangleFunc = 0; - imesa->QuadFunc = 0; - imesa->IndirectTriangles |= (DD_TRI_SW_RASTERIZE | - DD_QUAD_SW_RASTERIZE); - } - } + 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(); +} + + +/*********************************************************************** + * Rasterization fallback helpers * + ***********************************************************************/ + + +/* This code is hit only when a mix of accelerated and unaccelerated + * primitives are being drawn, and only for the unaccelerated + * primitives. + */ +static void +i830_fallback_tri( i830ContextPtr imesa, + i830Vertex *v0, + i830Vertex *v1, + i830Vertex *v2 ) +{ + GLcontext *ctx = imesa->glCtx; + SWvertex v[3]; + + if (DEBUGGING) + fprintf(stderr, "\n%s\n", __FUNCTION__); + + i830_translate_vertex( ctx, v0, &v[0] ); + i830_translate_vertex( ctx, v1, &v[1] ); + i830_translate_vertex( ctx, v2, &v[2] ); + _swrast_Triangle( ctx, &v[0], &v[1], &v[2] ); +} + + +static void +i830_fallback_line( i830ContextPtr imesa, + i830Vertex *v0, + i830Vertex *v1 ) +{ + GLcontext *ctx = imesa->glCtx; + SWvertex v[2]; + + if (DEBUGGING) + fprintf(stderr, "\n%s\n", __FUNCTION__); + + i830_translate_vertex( ctx, v0, &v[0] ); + i830_translate_vertex( ctx, v1, &v[1] ); + _swrast_Line( ctx, &v[0], &v[1] ); } +static void +i830_fallback_point( i830ContextPtr imesa, + i830Vertex *v0 ) +{ + GLcontext *ctx = imesa->glCtx; + SWvertex v[1]; + + if (DEBUGGING) + fprintf(stderr, "\n%s\n", __FUNCTION__); + + i830_translate_vertex( ctx, v0, &v[0] ); + _swrast_Point( ctx, &v[0] ); +} + + + +/**********************************************************************/ +/* Render unclipped begin/end objects */ +/**********************************************************************/ + +#define IND 0 +#define V(x) (i830Vertex *)(vertptr + ((x)<<vertshift)) +#define RENDER_POINTS( start, count ) \ + for ( ; start < count ; start++) POINT( V(ELT(start)) ); +#define RENDER_LINE( v0, v1 ) LINE( V(v0), V(v1) ) +#define RENDER_TRI( v0, v1, v2 ) TRI( V(v0), V(v1), V(v2) ) +#define RENDER_QUAD( v0, v1, v2, v3 ) QUAD( V(v0), V(v1), V(v2), V(v3) ) +#define INIT(x) i830RenderPrimitive( ctx, x ) +#undef LOCAL_VARS +#define LOCAL_VARS \ + i830ContextPtr imesa = I830_CONTEXT(ctx); \ + GLubyte *vertptr = (GLubyte *)imesa->verts; \ + const GLuint vertshift = imesa->vertex_stride_shift; \ + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \ + (void) elt; +#define RESET_STIPPLE +#define RESET_OCCLUSION +#define PRESERVE_VB_DEFS +#define ELT(x) x +#define TAG(x) i830_##x##_verts +#include "tnl/t_vb_rendertmp.h" +#undef ELT +#undef TAG +#define TAG(x) i830_##x##_elts +#define ELT(x) elt[x] +#include "tnl/t_vb_rendertmp.h" + +/**********************************************************************/ +/* Render clipped primitives */ +/**********************************************************************/ + + + +static void i830RenderClippedPoly( GLcontext *ctx, const GLuint *elts, + GLuint n ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLuint prim = imesa->render_primitive; + + if (DEBUGGING) + fprintf(stderr, "\n%s\n", __FUNCTION__); + + /* 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 ); +} + +static void i830RenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + if (DEBUGGING) + fprintf(stderr, "\n%s\n", __FUNCTION__); + tnl->Driver.Render.Line( ctx, ii, jj ); +} + +static void i830FastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, + GLuint n ) +{ + i830ContextPtr imesa = I830_CONTEXT( ctx ); + GLuint vertsize = imesa->vertex_size; + GLuint *vb = i830AllocDmaLow( imesa, (n-2) * 3 * 4 * vertsize ); + GLubyte *vertptr = (GLubyte *)imesa->verts; + const GLuint vertshift = imesa->vertex_stride_shift; + const GLuint *start = (const GLuint *)V(elts[0]); + int i,j; + + if (DEBUGGING) + fprintf(stderr, "\n%s\n", __FUNCTION__); + + for (i = 2 ; i < n ; i++) { + COPY_DWORDS( j, vb, vertsize, start ); + COPY_DWORDS( j, vb, vertsize, V(elts[i-1]) ); + COPY_DWORDS( j, vb, vertsize, V(elts[i]) ); + } +} + +/**********************************************************************/ +/* Choose render functions */ +/**********************************************************************/ + + + +#define _I830_NEW_RENDERSTATE (_DD_NEW_LINE_STIPPLE | \ + _DD_NEW_TRI_UNFILLED | \ + _DD_NEW_TRI_LIGHT_TWOSIDE | \ + _DD_NEW_TRI_OFFSET | \ + _DD_NEW_TRI_STIPPLE | \ + _NEW_POLYGONSTIPPLE) + +#define POINT_FALLBACK (0) +#define LINE_FALLBACK (DD_LINE_STIPPLE) +#define TRI_FALLBACK (DD_TRI_STIPPLE) +#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK|\ + DD_TRI_STIPPLE) +#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED) + +static void i830ChooseRenderState(GLcontext *ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + i830ContextPtr imesa = I830_CONTEXT(ctx); + GLuint flags = ctx->_TriangleCaps; + GLuint index = 0; + if (DEBUGGING) + fprintf(stderr,"\n%s\n",__FUNCTION__); + + if (flags & (ANY_FALLBACK_FLAGS|ANY_RASTER_FLAGS)) { + if (flags & ANY_RASTER_FLAGS) { + if (flags & DD_TRI_LIGHT_TWOSIDE) index |= I830_TWOSIDE_BIT; + if (flags & DD_TRI_OFFSET) index |= I830_OFFSET_BIT; + if (flags & DD_TRI_UNFILLED) index |= I830_UNFILLED_BIT; + } + + imesa->draw_point = i830_draw_point; + imesa->draw_line = i830_draw_line; + imesa->draw_tri = i830_draw_triangle; + + /* Hook in fallbacks for specific primitives. + */ + if (flags & ANY_FALLBACK_FLAGS) + { + if (flags & POINT_FALLBACK) + imesa->draw_point = i830_fallback_point; + + if (flags & LINE_FALLBACK) + imesa->draw_line = i830_fallback_line; + + if (flags & TRI_FALLBACK) + imesa->draw_tri = i830_fallback_tri; + + if (flags & DD_TRI_STIPPLE) + imesa->draw_tri = i830_fallback_tri; + + index |= I830_FALLBACK_BIT; + } + } + + if (imesa->RenderIndex != index) { + imesa->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 = i830_render_tab_verts; + tnl->Driver.Render.PrimTabElts = i830_render_tab_elts; + tnl->Driver.Render.ClippedLine = line; /* from tritmp.h */ + tnl->Driver.Render.ClippedPolygon = i830FastRenderClippedPoly; + } else { + tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; + tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; + tnl->Driver.Render.ClippedLine = i830RenderClippedLine; + tnl->Driver.Render.ClippedPolygon = i830RenderClippedPoly; + } + } +} + +static const 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 +}; + + +/**********************************************************************/ +/* High level hooks for t_vb_render.c */ +/**********************************************************************/ + + + +/* 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 i810render.c. + */ +static void i830RenderPrimitive( GLcontext *ctx, GLenum prim ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + GLuint rprim = reduced_prim[prim]; + + imesa->render_primitive = prim; + + if (rprim == GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED)) + return; + + if (imesa->reduced_primitive != rprim || + hw_prim[prim] != imesa->hw_primitive) { + i830RasterPrimitive( ctx, rprim, hw_prim[prim] ); + } +} + +static void i830RunPipeline( GLcontext *ctx ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + + if (imesa->new_state) { + if (imesa->new_state & _NEW_TEXTURE) + i830UpdateTextureState( ctx ); /* may modify imesa->new_state */ + + if (!imesa->Fallback) { + if (imesa->new_state & _I830_NEW_VERTEX) + i830ChooseVertexState( ctx ); + + if (imesa->new_state & _I830_NEW_RENDERSTATE) + i830ChooseRenderState( ctx ); + } + + imesa->new_state = 0; + } + + _tnl_run_pipeline( ctx ); +} + +static void i830RenderStart( GLcontext *ctx ) +{ + /* Check for projective textureing. Make sure all texcoord + * pointers point to something. (fix in mesa?) + */ + + i830CheckTexSizes( ctx ); +} + +static void i830RenderFinish( GLcontext *ctx ) +{ + if (I830_CONTEXT(ctx)->RenderIndex & I830_FALLBACK_BIT) + _swrast_flush( ctx ); +} + + + + +/* System to flush dma and emit state changes based on the rasterized + * primitive. + */ +void i830RasterPrimitive( GLcontext *ctx, + GLenum rprim, + GLuint hwprim ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + GLuint aa = imesa->Setup[I830_CTXREG_AA]; + + aa &= ~AA_LINE_ENABLE; + + if (0) { + /* Prints reduced prim, and hw prim */ + char *prim_name = "Unknown"; + + switch(hwprim) { + case PRIM3D_POINTLIST: + prim_name = "PointList"; + break; + case PRIM3D_LINELIST: + prim_name = "LineList"; + break; + case PRIM3D_LINESTRIP: + prim_name = "LineStrip"; + break; + case PRIM3D_TRILIST: + prim_name = "TriList"; + break; + case PRIM3D_TRISTRIP: + prim_name = "TriStrip"; + break; + case PRIM3D_TRIFAN: + prim_name = "TriFan"; + break; + case PRIM3D_POLY: + prim_name = "Polygons"; + break; + default: + break; + } + + fprintf(stderr, "%s : rprim(%s), hwprim(%s)\n", + __FUNCTION__, + _mesa_lookup_enum_by_nr(rprim), + prim_name); + } + + switch (rprim) { + case GL_TRIANGLES: + aa |= AA_LINE_DISABLE; + break; + case GL_LINES: + if (ctx->Line.SmoothFlag) { + aa |= AA_LINE_ENABLE; + } else { + aa |= AA_LINE_DISABLE; + } + break; + case GL_POINTS: + aa |= AA_LINE_DISABLE; + break; + default: + return; + } + + imesa->reduced_primitive = rprim; + + if (aa != imesa->Setup[I830_CTXREG_AA]) { + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->hw_primitive = hwprim; + imesa->Setup[I830_CTXREG_AA] = aa; + } + else if (hwprim != imesa->hw_primitive) { + I830_STATECHANGE(imesa, 0); + imesa->hw_primitive = hwprim; + } +} + +/**********************************************************************/ +/* Transition to/from hardware rasterization. */ +/**********************************************************************/ + + +void i830Fallback( i830ContextPtr imesa, GLuint bit, GLboolean mode ) +{ + GLcontext *ctx = imesa->glCtx; + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint oldfallback = imesa->Fallback; + + if (0) fprintf(stderr, "%s old %x bit %x mode %d\n", __FUNCTION__, + imesa->Fallback, bit, mode ); + + if (mode) { + imesa->Fallback |= bit; + if (oldfallback == 0) { + if (0) fprintf(stderr, "ENTER FALLBACK\n"); + I830_FIREVERTICES(imesa); + _swsetup_Wakeup( ctx ); + imesa->RenderIndex = ~0; + } + } + else { + imesa->Fallback &= ~bit; + if (oldfallback == bit) { + if (0) fprintf(stderr, "LEAVE FALLBACK\n"); + _swrast_flush( ctx ); + tnl->Driver.Render.Start = i830RenderStart; + tnl->Driver.Render.PrimitiveNotify = i830RenderPrimitive; + tnl->Driver.Render.Finish = i830RenderFinish; + tnl->Driver.Render.BuildVertices = i830BuildVertices; + imesa->new_state |= (_I830_NEW_RENDERSTATE|_I830_NEW_VERTEX); + } + } +} + + + + +/**********************************************************************/ +/* Initialization. */ +/**********************************************************************/ + + +void i830InitTriFuncs( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + static int firsttime = 1; + + if (firsttime) { + init_rast_tab(); + firsttime = 0; + } + + tnl->Driver.RunPipeline = i830RunPipeline; + tnl->Driver.Render.Start = i830RenderStart; + tnl->Driver.Render.Finish = i830RenderFinish; + tnl->Driver.Render.PrimitiveNotify = i830RenderPrimitive; + tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple; + tnl->Driver.Render.BuildVertices = i830BuildVertices; +} diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_tris.h b/xc/lib/GL/mesa/src/drv/i830/i830_tris.h index e27939cd0..2096f42d5 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_tris.h +++ b/xc/lib/GL/mesa/src/drv/i830/i830_tris.h @@ -1,263 +1,37 @@ -/************************************************************************** - -Copyright 2001 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 -on the rights to use, copy, modify, merge, publish, distribute, sub -license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL -ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS 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/i830/i830_tris.h,v 1.2 2002/01/17 09:50:58 eich Exp $ */ - /* - * Author: - * Jeff Hartmann <jhartmann@valinux.com> + * 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"), + * 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: * - * Heavily based on the I810 driver, which was written by: - * Keith Whitwell <keithw@valinux.com> + * 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 + * 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. + * + * Adapted for use in the I830M: + * Jeff Hartmann <jhartmann@2d3d.com> */ +/* $XFree86$ */ -#ifndef i830_TRIS_INC -#define i830_TRIS_INC - -#include "types.h" +#ifndef I830TRIS_INC +#define I830TRIS_INC -#include "i830_drv.h" -#include "i830_ioctl.h" +#include "mtypes.h" extern void i830PrintRenderState( const char *msg, GLuint state ); -extern void i830DDChooseRenderState(GLcontext *ctx); -extern void i830DDTrifuncInit( void ); - - -#define I830_FLAT_BIT 0x1 -#define I830_OFFSET_BIT 0x2 -#define I830_TWOSIDE_BIT 0x4 -#define I830_FALLBACK_BIT 0x8 - - - - -static void __inline__ i830_draw_triangle( i830ContextPtr imesa, - i830VertexPtr v0, - i830VertexPtr v1, - i830VertexPtr v2 ) -{ - GLuint vertsize = imesa->vertsize; - int j; - GLuint *vb = i830AllocDwordsInline(imesa, 3 * vertsize); - -#if 0 - - if(imesa->vertex_prim != PRIM3D_TRILIST) fprintf(stderr, "Not tris and rendering tris\n"); - - fprintf(stderr, "\n\n\n\nDrawTriangle :\n"); - fprintf(stderr, "v0\n"); - fprintf(stderr, "u: %f\n", v0->f[6]); - fprintf(stderr, "v: %f\n", v0->f[7]); - fprintf(stderr, "v1\n"); - fprintf(stderr, "u: %f\n", v1->f[6]); - fprintf(stderr, "v: %f\n", v1->f[7]); - fprintf(stderr, "v2\n"); - fprintf(stderr, "u: %f\n", v2->f[6]); - fprintf(stderr, "v: %f\n", v2->f[7]); -#endif - -#if 0 - fprintf(stderr, "\n\n\n\nDrawTriangle :\n"); - fprintf(stderr, "v0\n"); - fprintf(stderr, "0x%x\n", v0->ui[0]); - fprintf(stderr, "0x%x\n", v0->ui[1]); - fprintf(stderr, "0x%x\n", v0->ui[2]); - fprintf(stderr, "0x%x\n", v0->ui[3]); - fprintf(stderr, "0x%x\n", v0->ui[4]); - fprintf(stderr, "0x%x\n", v0->ui[5]); - fprintf(stderr, "0x%x\n", v0->ui[6]); - fprintf(stderr, "0x%x\n", v0->ui[7]); - fprintf(stderr, "0x%x\n", v0->ui[8]); - fprintf(stderr, "0x%x\n", v0->ui[9]); - fprintf(stderr, "0x%x\n", v0->ui[10]); - fprintf(stderr, "0x%x\n", v0->ui[11]); - fprintf(stderr, "0x%x\n", v0->ui[12]); - fprintf(stderr, "0x%x\n", v0->ui[13]); - fprintf(stderr, "0x%x\n", v0->ui[14]); - fprintf(stderr, "0x%x\n", v0->ui[15]); - fprintf(stderr, "v1\n"); - fprintf(stderr, "0x%x\n", v1->ui[0]); - fprintf(stderr, "0x%x\n", v1->ui[1]); - fprintf(stderr, "0x%x\n", v1->ui[2]); - fprintf(stderr, "0x%x\n", v1->ui[3]); - fprintf(stderr, "0x%x\n", v1->ui[4]); - fprintf(stderr, "0x%x\n", v1->ui[5]); - fprintf(stderr, "0x%x\n", v1->ui[6]); - fprintf(stderr, "0x%x\n", v1->ui[7]); - fprintf(stderr, "0x%x\n", v1->ui[8]); - fprintf(stderr, "0x%x\n", v1->ui[9]); - fprintf(stderr, "0x%x\n", v1->ui[10]); - fprintf(stderr, "0x%x\n", v1->ui[11]); - fprintf(stderr, "0x%x\n", v1->ui[12]); - fprintf(stderr, "0x%x\n", v1->ui[13]); - fprintf(stderr, "0x%x\n", v1->ui[14]); - fprintf(stderr, "0x%x\n", v1->ui[15]); - fprintf(stderr, "v2\n"); - fprintf(stderr, "0x%x\n", v2->ui[0]); - fprintf(stderr, "0x%x\n", v2->ui[1]); - fprintf(stderr, "0x%x\n", v2->ui[2]); - fprintf(stderr, "0x%x\n", v2->ui[3]); - fprintf(stderr, "0x%x\n", v2->ui[4]); - fprintf(stderr, "0x%x\n", v2->ui[5]); - fprintf(stderr, "0x%x\n", v2->ui[6]); - fprintf(stderr, "0x%x\n", v2->ui[7]); - fprintf(stderr, "0x%x\n", v2->ui[8]); - fprintf(stderr, "0x%x\n", v2->ui[9]); - fprintf(stderr, "0x%x\n", v2->ui[10]); - fprintf(stderr, "0x%x\n", v2->ui[11]); - fprintf(stderr, "0x%x\n", v2->ui[12]); - fprintf(stderr, "0x%x\n", v2->ui[13]); - fprintf(stderr, "0x%x\n", v2->ui[14]); - fprintf(stderr, "0x%x\n", v2->ui[15]); -#endif - -#if defined(USE_X86_ASM) - __asm__ __volatile__( "rep ; movsl" - : "=%c" (j) - : "0" (vertsize), "D" ((long)vb), "S" ((long)v0) - : "memory" ); - __asm__ __volatile__( "rep ; movsl" - : "=%c" (j) - : "0" (vertsize), "S" ((long)v1) - : "memory" ); - __asm__ __volatile__( "rep ; movsl" - : "=%c" (j) - : "0" (vertsize), "S" ((long)v2) - : "memory" ); -#else - - for (j = 0 ; j < vertsize ; j++) - vb[j] = v0->ui[j]; - - vb += vertsize; - for (j = 0 ; j < vertsize ; j++) - vb[j] = v1->ui[j]; - - vb += vertsize; - for (j = 0 ; j < vertsize ; j++) - vb[j] = v2->ui[j]; -#endif -} - -/* We aren't supporting point params, so we are ignoring size */ -static __inline__ void i830_draw_point( i830ContextPtr imesa, - i830VertexPtr tmp, - float sz ) -{ - GLuint vertsize = imesa->vertsize; - int j; - GLuint *vb = i830AllocDwordsInline( imesa, 1 * vertsize ); - -#if 0 - if(imesa->vertex_prim != PRIM3D_POINTLIST) fprintf(stderr, "Not points and rendering points\n"); -#endif - -#if defined(USE_X86_ASM) - __asm__ __volatile__( "rep ; movsl" - : "=%c" (j) - : "0" (vertsize), "D" ((long)vb), "S" ((long)tmp) - : "memory" ); -#else - for (j = 0 ; j < vertsize ; j++) - vb[j] = tmp->ui[j]; - -#endif - -} - -static __inline__ void i830_draw_line( i830ContextPtr imesa, - i830VertexPtr v0, - i830VertexPtr v1 ) -{ - GLuint vertsize = imesa->vertsize; - int j; - GLuint *vb = i830AllocDwordsInline( imesa, 2 * vertsize ); - -#if 0 - if(imesa->vertex_prim != PRIM3D_LINELIST) fprintf(stderr, "Not lines and rendering lines : prim %d\n", imesa->vertex_prim); -#endif - -#if 0 - fprintf(stderr, "\n\n\n\nDrawLine"); - fprintf(stderr, "v0\n"); - fprintf(stderr, "0x%x\n", v0->ui[0]); - fprintf(stderr, "0x%x\n", v0->ui[1]); - fprintf(stderr, "0x%x\n", v0->ui[2]); - fprintf(stderr, "0x%x\n", v0->ui[3]); - fprintf(stderr, "0x%x\n", v0->ui[4]); - fprintf(stderr, "0x%x\n", v0->ui[5]); - fprintf(stderr, "0x%x\n", v0->ui[6]); - fprintf(stderr, "0x%x\n", v0->ui[7]); - fprintf(stderr, "0x%x\n", v0->ui[8]); - fprintf(stderr, "0x%x\n", v0->ui[9]); - fprintf(stderr, "0x%x\n", v0->ui[10]); - fprintf(stderr, "0x%x\n", v0->ui[11]); - fprintf(stderr, "0x%x\n", v0->ui[12]); - fprintf(stderr, "0x%x\n", v0->ui[13]); - fprintf(stderr, "0x%x\n", v0->ui[14]); - fprintf(stderr, "0x%x\n", v0->ui[15]); - fprintf(stderr, "v1\n"); - fprintf(stderr, "0x%x\n", v1->ui[0]); - fprintf(stderr, "0x%x\n", v1->ui[1]); - fprintf(stderr, "0x%x\n", v1->ui[2]); - fprintf(stderr, "0x%x\n", v1->ui[3]); - fprintf(stderr, "0x%x\n", v1->ui[4]); - fprintf(stderr, "0x%x\n", v1->ui[5]); - fprintf(stderr, "0x%x\n", v1->ui[6]); - fprintf(stderr, "0x%x\n", v1->ui[7]); - fprintf(stderr, "0x%x\n", v1->ui[8]); - fprintf(stderr, "0x%x\n", v1->ui[9]); - fprintf(stderr, "0x%x\n", v1->ui[10]); - fprintf(stderr, "0x%x\n", v1->ui[11]); - fprintf(stderr, "0x%x\n", v1->ui[12]); - fprintf(stderr, "0x%x\n", v1->ui[13]); - fprintf(stderr, "0x%x\n", v1->ui[14]); - fprintf(stderr, "0x%x\n", v1->ui[15]); -#endif - -#if defined(USE_X86_ASM) - __asm__ __volatile__( "rep ; movsl" - : "=%c" (j) - : "0" (vertsize), "D" ((long)vb), "S" ((long)v0) - : "memory" ); - __asm__ __volatile__( "rep ; movsl" - : "=%c" (j) - : "0" (vertsize), "S" ((long)v1) - : "memory" ); -#else - for (j = 0 ; j < vertsize ; j++) - vb[j] = v0->ui[j]; - - vb += vertsize; - for (j = 0 ; j < vertsize ; j++) - vb[j] = v1->ui[j]; -#endif -} - +extern void i830InitTriFuncs( GLcontext *ctx ); +extern void i830RasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim ); #endif diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_tritmp.h b/xc/lib/GL/mesa/src/drv/i830/i830_tritmp.h deleted file mode 100644 index b2ab90d36..000000000 --- a/xc/lib/GL/mesa/src/drv/i830/i830_tritmp.h +++ /dev/null @@ -1,276 +0,0 @@ -/************************************************************************** - -Copyright 2001 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 -on the rights to use, copy, modify, merge, publish, distribute, sub -license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL -ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS 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/i830/i830_tritmp.h,v 1.1 2001/10/04 18:28:21 alanh Exp $ */ - -/* - * Author: - * Jeff Hartmann <jhartmann@valinux.com> - * - * Heavily based on the I810 driver, which was written by: - * Keith Whitwell <keithw@valinux.com> - */ - -static __inline void TAG(triangle)(GLcontext *ctx, - GLuint e0, GLuint e1, GLuint e2, - GLuint pv) -{ - i830ContextPtr imesa = I830_CONTEXT(ctx); - struct vertex_buffer *VB = ctx->VB; - i830VertexPtr i830verts = I830_DRIVER_DATA(VB)->verts; - i830Vertex *v[3]; - -#if (IND & I830_OFFSET_BIT) - GLfloat offset; - GLfloat z[3]; -#endif - -#if (IND & (I830_TWOSIDE_BIT | I830_FLAT_BIT)) - GLuint c[3]; - GLuint s[3]; -#endif - - v[0] = &i830verts[e0]; - v[1] = &i830verts[e1]; - v[2] = &i830verts[e2]; - -#if (IND & (I830_TWOSIDE_BIT | I830_FLAT_BIT)) - c[0] = v[0]->ui[4]; - c[1] = v[1]->ui[4]; - c[2] = v[2]->ui[4]; - s[0] = v[0]->ui[5]; - s[1] = v[1]->ui[5]; - s[2] = v[2]->ui[5]; -#endif - - -#if (IND & (I830_TWOSIDE_BIT | I830_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 & I830_TWOSIDE_BIT) - { - GLuint facing = (cc > 0.0) ^ ctx->Polygon.FrontBit; - GLubyte (*vbcolor)[4] = VB->Color[facing]->data; - GLubyte (*vbspec)[4] = VB->Spec[facing]; - if (IND & I830_FLAT_BIT) { - I830_COLOR((char *)&v[0]->ui[4], vbcolor[pv]); - v[2]->ui[4] = v[1]->ui[4] = v[0]->ui[4]; - I830_COLOR3((char *)&v[0]->ui[5], vbspec[pv]); - v[2]->ui[5] = v[1]->ui[5] = v[0]->ui[5]; - } else { - I830_COLOR((char *)&v[0]->ui[4], vbcolor[e0]); - I830_COLOR((char *)&v[1]->ui[4], vbcolor[e1]); - I830_COLOR((char *)&v[2]->ui[4], vbcolor[e2]); - I830_COLOR3((char *)&v[0]->ui[5], vbspec[e0]); - I830_COLOR3((char *)&v[1]->ui[5], vbspec[e1]); - I830_COLOR3((char *)&v[2]->ui[5], vbspec[e2]); - } - } -#endif - -#if (IND & I830_OFFSET_BIT) - { - /*offset = ctx->Polygon.OffsetUnits * 1.0/0x10000;*/ - offset = ctx->Polygon.OffsetUnits * imesa->depth_scale; - 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 & I830_FLAT_BIT) - { - GLuint color = i830verts[pv].ui[4]; - GLuint spec = i830verts[pv].ui[5]; - v[0]->ui[4] = color; - v[1]->ui[4] = color; - v[2]->ui[4] = color; - v[0]->ui[5] = spec; - v[1]->ui[5] = spec; - v[2]->ui[5] = spec; - } -#endif - - i830_draw_triangle( imesa, v[0], v[1], v[2] ); - -#if (IND & I830_OFFSET_BIT) - v[0]->v.z = z[0]; - v[1]->v.z = z[1]; - v[2]->v.z = z[2]; -#endif - -#if (IND & (I830_FLAT_BIT | I830_TWOSIDE_BIT)) - v[0]->ui[4] = c[0]; - v[1]->ui[4] = c[1]; - v[2]->ui[4] = c[2]; - v[0]->ui[5] = s[0]; - v[1]->ui[5] = s[1]; - v[2]->ui[5] = s[2]; -#endif - -} - - - - -static void TAG(quad)( GLcontext *ctx, GLuint v0, - GLuint v1, GLuint v2, GLuint v3, - GLuint pv ) -{ - TAG(triangle)( ctx, v0, v1, v3, pv ); - TAG(triangle)( ctx, v1, v2, v3, pv ); -} - - -static void TAG(line)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv ) -{ - i830ContextPtr imesa = I830_CONTEXT( ctx ); - i830VertexPtr i830VB = I830_DRIVER_DATA(ctx->VB)->verts; - GLfloat z0, z1; - GLuint c0, c1; - GLuint s0, s1; - i830Vertex *vert0 = &i830VB[v0]; - i830Vertex *vert1 = &i830VB[v1]; - - if (IND & I830_TWOSIDE_BIT) { - GLubyte (*vbcolor)[4] = ctx->VB->ColorPtr->data; - GLubyte (*vbspec)[4] = ctx->VB->Specular; - - if (IND & I830_FLAT_BIT) { - I830_COLOR((char *)&vert0->v.color,vbcolor[pv]); - *(int *)&vert1->v.color = *(int *)&vert0->v.color; - I830_COLOR3((char *)&vert0->v.specular, vbspec[pv]); - *(int *)&vert1->v.specular = *(int *)&vert0->v.specular; - } else { - I830_COLOR((char *)&vert0->v.color,vbcolor[v0]); - I830_COLOR((char *)&vert1->v.color,vbcolor[v1]); - I830_COLOR3((char *)&vert0->v.specular, vbspec[v0]); - I830_COLOR3((char *)&vert1->v.specular, vbspec[v1]); - } - } else if (IND & I830_FLAT_BIT) { - c0 = *(GLuint *) &(vert0->v.color); - c1 = *(GLuint *) &(vert1->v.color); - *(int *)&vert0->v.color = - *(int *)&vert1->v.color = *(int *)&i830VB[pv].v.color; - s0 = *(GLuint *) &(vert0->v.specular); - s1 = *(GLuint *) &(vert1->v.specular); - *(int *)&vert0->v.specular = - *(int *)&vert1->v.specular = *(int *)&i830VB[pv].v.specular; - } - - if (IND & I830_OFFSET_BIT) { - /*GLfloat offset = ctx->LineZoffset * (1.0 / 0x10000);*/ - GLfloat offset = ctx->LineZoffset * imesa->depth_scale; - z0 = vert0->v.z; - z1 = vert1->v.z; - vert0->v.z += offset; - vert1->v.z += offset; - } - - i830_draw_line( imesa, &i830VB[v0], &i830VB[v1]); - - if (IND & I830_OFFSET_BIT) { - vert0->v.z = z0; - vert1->v.z = z1; - } - - if ((IND & I830_FLAT_BIT) && !(IND & I830_TWOSIDE_BIT)) { - *(GLuint *) &(vert0->v.color) = c0; - *(GLuint *) &(vert1->v.color) = c1; - *(GLuint *) &(vert0->v.specular) = s0; - *(GLuint *) &(vert1->v.specular) = s1; - } -} - -static void TAG(points)( GLcontext *ctx, GLuint first, GLuint last ) -{ - i830ContextPtr imesa = I830_CONTEXT( ctx ); - struct vertex_buffer *VB = ctx->VB; - i830VertexPtr i830VB = I830_DRIVER_DATA(VB)->verts; - GLfloat sz = ctx->Point.Size * .5; - int i; - - for(i=first;i<last;i++) - if(VB->ClipMask[i]==0) { - if (IND & (I830_TWOSIDE_BIT|I830_OFFSET_BIT)) { - i830Vertex tmp0 = i830VB[i]; - if (IND & I830_TWOSIDE_BIT) { - GLubyte (*vbcolor)[4] = VB->ColorPtr->data; - I830_COLOR((char *)&tmp0.v.color, vbcolor[i]); - } - if (IND & I830_OFFSET_BIT) { - /*GLfloat offset = ctx->PointZoffset * (1.0 / 0x10000);*/ - GLfloat offset = ctx->PointZoffset * imesa->depth_scale; - tmp0.v.z += offset; - } - tmp0.f[0] -= 0.125; - tmp0.f[1] -= 0.125; - i830_draw_point( imesa, &tmp0, sz ); - } else { - i830VB[i].f[0] -= 0.125; - i830VB[i].f[1] -= 0.125; - i830_draw_point( imesa, &i830VB[i], sz ); - i830VB[i].f[0] += 0.125; - i830VB[i].f[1] += 0.125; - } - } -} - - - - -static void TAG(init)( void ) -{ - tri_tab[IND] = TAG(triangle); - quad_tab[IND] = TAG(quad); - line_tab[IND] = TAG(line); - points_tab[IND] = TAG(points); -} - - -#undef IND -#undef TAG diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_vb.c b/xc/lib/GL/mesa/src/drv/i830/i830_vb.c index dad88fa2f..671598b7f 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_vb.c +++ b/xc/lib/GL/mesa/src/drv/i830/i830_vb.c @@ -1,480 +1,592 @@ -/************************************************************************** - -Copyright 2001 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 -on the rights to use, copy, modify, merge, publish, distribute, sub -license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL -ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS 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/i830/i830_vb.c,v 1.1 2001/10/04 18:28:21 alanh Exp $ */ - /* - * Author: - * Jeff Hartmann <jhartmann@valinux.com> + * 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"), + * 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. * - * Heavily based on the I810 driver, which was written by: - * Keith Whitwell <keithw@valinux.com> + * 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 + * 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. + * + * Adapted for use on the I830M: + * Jeff Hartmann <jhartmann@2d3d.com> */ - -#include <stdio.h> -#include <stdlib.h> +/* $XFree86$ */ -#include "i830_drv.h" +#include "glheader.h" +#include "mtypes.h" #include "mem.h" -#include "stages.h" +#include "macros.h" +#include "colormac.h" +#include "mmath.h" -#define TEX0 { \ - v->v.tu0 = tc0[i][0]; \ - v->v.tv0 = tc0[i][1]; \ -} - -#define TEX1 { \ - v->v.tu1 = tc1[i][0]; \ - v->v.tv1 = tc1[i][1]; \ -} +#include "swrast_setup/swrast_setup.h" +#include "tnl/t_context.h" -/* Doesn't seem to work very well (golly). - */ -#define SPC { \ - GLubyte *spec = &(VB->Spec[0][i][0]); \ - v->v.specular.red = spec[0]; \ - v->v.specular.green = spec[1]; \ - v->v.specular.blue = spec[2]; \ -} - -#define FOG { \ - GLubyte *spec = &(VB->Spec[0][i][0]); \ - v->v.specular.alpha = spec[3]; \ -} +#include "i830_screen.h" +#include "i830_dri.h" -#define COL { \ - GLubyte *col = &(VB->Color[0]->data[i][0]); \ - v->v.color.blue = col[2]; \ - v->v.color.green = col[1]; \ - v->v.color.red = col[0]; \ - v->v.color.alpha = col[3]; \ -} +#include "i830_context.h" +#include "i830_vb.h" +#include "i830_ioctl.h" +#include "i830_tris.h" +#include "i830_state.h" +#include "i830_drv.h" -/* The vertex formats we have don't seem to support projective texturing - * in the multitexture case. (Would require another 1/w value for the - * second set of texcoords). - * XXX grantham - i830 does q coordinate, haven't spent time to figure out - * how to implement dynamic HOMOGENOUS coord; plus need to copy tc[i][2] - * for cube maps, not tc[i][3] +#define I830_TEX1_BIT 0x1 +#define I830_TEX0_BIT 0x2 +#define I830_RGBA_BIT 0x4 +#define I830_SPEC_BIT 0x8 +#define I830_FOG_BIT 0x10 +#define I830_XYZW_BIT 0x20 +#define I830_PTEX_BIT 0x40 +#define I830_MAX_SETUP 0x80 + +static struct { + void (*emit)( GLcontext *, GLuint, GLuint, void *, GLuint ); + 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[I830_MAX_SETUP]; + +#define TINY_VERTEX_FORMAT (STATE3D_VERTEX_FORMAT_CMD | \ + VRTX_TEX_COORD_COUNT(0) | \ + VRTX_HAS_DIFFUSE | \ + VRTX_HAS_XYZ) + +#define NOTEX_VERTEX_FORMAT (STATE3D_VERTEX_FORMAT_CMD | \ + VRTX_TEX_COORD_COUNT(0) | \ + VRTX_HAS_DIFFUSE | \ + VRTX_HAS_SPEC | \ + VRTX_HAS_XYZW) + +#define TEX0_VERTEX_FORMAT (STATE3D_VERTEX_FORMAT_CMD | \ + VRTX_TEX_COORD_COUNT(1) | \ + VRTX_HAS_DIFFUSE | \ + VRTX_HAS_SPEC | \ + VRTX_HAS_XYZW) + +#define TEX1_VERTEX_FORMAT (STATE3D_VERTEX_FORMAT_CMD | \ + VRTX_TEX_COORD_COUNT(2) | \ + VRTX_HAS_DIFFUSE | \ + VRTX_HAS_SPEC | \ + VRTX_HAS_XYZW) + + +/* I'm cheating here hardcore : if bit 31 is set I know to emit + * a vf2 state == TEXCOORDFMT_3D. We never mix 2d/3d texcoords, + * so this solution works for now. */ -#define TEX0_4 \ - if (VB->TexCoordPtr[0]->size == 4) \ - { \ - GLfloat (*tc)[4] = VB->TexCoordPtr[0]->data; \ - v = &(I830_DRIVER_DATA(VB)->verts[start]); \ - imesa->setupdone &= ~I830_WIN_BIT; \ - for (i=start; i < end; i++, v++) { \ - float oow = 1.0 / tc[i][3]; \ - v->v.oow *= tc[i][3]; \ - v->v.tu0 *= oow; \ - v->v.tv0 *= oow; \ - } \ - } - -#define COORD \ - GLfloat *win = VB->Win.data[i]; \ - v->v.x = xoffset + win[0]; \ - v->v.y = yoffset - win[1]; \ - v->v.z = depth_scale * win[2]; \ - v->v.oow = win[3]; - - -#define NOP -#define SUBPIXEL_X 0.125 -#define SUBPIXEL_Y 0.125 - -#define SETUPFUNC(name,win,col,tex0,tex1,tex0_4,spec,fog) \ -static void name(struct vertex_buffer *VB, GLuint start, GLuint end) \ -{ \ - i830ContextPtr imesa = I830_CONTEXT( VB->ctx ); \ - __DRIdrawablePrivate *dPriv = imesa->driDrawable; \ - i830VertexPtr v; \ - GLfloat (*tc0)[4]; \ - GLfloat (*tc1)[4]; \ - const GLfloat depth_scale = imesa->depth_scale; \ - const GLfloat xoffset = SUBPIXEL_X; \ - const GLfloat yoffset = dPriv->h + SUBPIXEL_Y; \ - int i; \ - (void) xoffset; \ - (void) yoffset; \ - (void) imesa; \ - (void) depth_scale; \ - \ - \ - gl_import_client_data( VB, VB->ctx->RenderFlags, \ - (VB->ClipOrMask \ - ? VEC_WRITABLE|VEC_GOOD_STRIDE \ - : VEC_GOOD_STRIDE)); \ - \ - tc0 = VB->TexCoordPtr[0]->data; \ - tc1 = VB->TexCoordPtr[1]->data; \ - \ - v = &(I830_DRIVER_DATA(VB)->verts[start]); \ - \ - if (VB->ClipOrMask == 0) \ - for (i=start; i < end; i++, v++) { \ - win; \ - col; \ - spec; \ - fog; \ - tex0; \ - tex1; \ - } \ - else \ - for (i=start; i < end; i++, v++) { \ - if (VB->ClipMask[i] == 0) { \ - win; \ - spec; \ - fog; \ - tex0; \ - tex1; \ - } \ - col; \ - } \ - tex0_4; \ - /* tex1_4; */ \ - /* tex2_4; */ \ - /* tex3_4; */ \ -} - -SETUPFUNC(rs_wt0, COORD,NOP,TEX0,NOP,TEX0_4,NOP,NOP) -SETUPFUNC(rs_wt0t1, COORD,NOP,TEX0,TEX1,TEX0_4,NOP,NOP) -SETUPFUNC(rs_wft0, COORD,NOP,TEX0,NOP,TEX0_4,NOP,FOG) -SETUPFUNC(rs_wft0t1, COORD,NOP,TEX0,TEX1,TEX0_4,NOP,FOG) -SETUPFUNC(rs_wg, COORD,COL,NOP,NOP,NOP,NOP,NOP) -SETUPFUNC(rs_wgs, COORD,COL,NOP,NOP,NOP,SPC,NOP) -SETUPFUNC(rs_wgt0, COORD,COL,TEX0,NOP,TEX0_4,NOP,NOP) -SETUPFUNC(rs_wgt0t1, COORD,COL,TEX0,TEX1,TEX0_4,NOP,NOP) -SETUPFUNC(rs_wgst0, COORD,COL,TEX0,NOP,TEX0_4,SPC,NOP) -SETUPFUNC(rs_wgst0t1, COORD,COL,TEX0,TEX1,TEX0_4,SPC,NOP) -SETUPFUNC(rs_wgf, COORD,COL,NOP,NOP,NOP,NOP,FOG) -SETUPFUNC(rs_wgfs, COORD,COL,NOP,NOP,NOP,SPC,FOG) -SETUPFUNC(rs_wgft0, COORD,COL,TEX0,NOP,TEX0_4,NOP,FOG) -SETUPFUNC(rs_wgft0t1, COORD,COL,TEX0,TEX1,TEX0_4,NOP,FOG) -SETUPFUNC(rs_wgfst0, COORD,COL,TEX0,NOP,TEX0_4,SPC,FOG) -SETUPFUNC(rs_wgfst0t1, COORD,COL,TEX0,TEX1,TEX0_4,SPC,FOG) - -SETUPFUNC(rs_t0, NOP,NOP,TEX0,NOP,TEX0_4,NOP,NOP) -SETUPFUNC(rs_t0t1, NOP,NOP,TEX0,TEX1,TEX0_4,NOP,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,NOP,FOG) -SETUPFUNC(rs_g, NOP,COL,NOP,NOP,NOP,NOP,NOP) -SETUPFUNC(rs_gs, NOP,COL,NOP,NOP,NOP,SPC,NOP) -SETUPFUNC(rs_gt0, NOP,COL,TEX0,NOP,TEX0_4,NOP,NOP) -SETUPFUNC(rs_gt0t1, NOP,COL,TEX0,TEX1,TEX0_4,NOP,NOP) -SETUPFUNC(rs_gst0, NOP,COL,TEX0,NOP,TEX0_4,SPC,NOP) -SETUPFUNC(rs_gst0t1, NOP,COL,TEX0,TEX1,TEX0_4,SPC,NOP) -SETUPFUNC(rs_gf, NOP,COL,NOP,NOP,NOP,NOP,FOG) -SETUPFUNC(rs_gfs, NOP,COL,NOP,NOP,NOP,SPC,FOG) -SETUPFUNC(rs_gft0, NOP,COL,TEX0,NOP,TEX0_4,NOP,FOG) -SETUPFUNC(rs_gft0t1, NOP,COL,TEX0,TEX1,TEX0_4,NOP,FOG) -SETUPFUNC(rs_gfst0, NOP,COL,TEX0,NOP,TEX0_4,SPC,FOG) -SETUPFUNC(rs_gfst0t1, NOP,COL,TEX0,TEX1,TEX0_4,SPC,FOG) - - - -static void rs_invalid(struct vertex_buffer *VB, GLuint start, GLuint end) -{ - - fprintf(stderr, "i830RasterSetup(): invalid setup function\n"); -} +#define PROJ_TEX1_VERTEX_FORMAT ((1<<31) | \ + STATE3D_VERTEX_FORMAT_CMD | \ + VRTX_TEX_COORD_COUNT(2) | \ + VRTX_HAS_DIFFUSE | \ + VRTX_HAS_SPEC | \ + VRTX_HAS_XYZW) + +/* Might want to do these later */ +#define TEX2_VERTEX_FORMAT 0 +#define TEX3_VERTEX_FORMAT 0 +#define PROJ_TEX3_VERTEX_FORMAT 0 + +#define DO_XYZW (IND & I830_XYZW_BIT) +#define DO_RGBA (IND & I830_RGBA_BIT) +#define DO_SPEC (IND & I830_SPEC_BIT) +#define DO_FOG (IND & I830_FOG_BIT) +#define DO_TEX0 (IND & I830_TEX0_BIT) +#define DO_TEX1 (IND & I830_TEX1_BIT) +#define DO_TEX2 0 +#define DO_TEX3 0 +#define DO_PTEX (IND & I830_PTEX_BIT) + +#define VERTEX i830Vertex +#define GET_VIEWPORT_MAT() I830_CONTEXT(ctx)->ViewportMatrix.m +#define GET_TEXSOURCE(n) n +#define GET_VERTEX_FORMAT() I830_CONTEXT(ctx)->vertex_format +#define GET_VERTEX_STORE() I830_CONTEXT(ctx)->verts +#define GET_VERTEX_STRIDE_SHIFT() I830_CONTEXT(ctx)->vertex_stride_shift +#define GET_UBYTE_COLOR_STORE() &I830_CONTEXT(ctx)->UbyteColor +#define GET_UBYTE_SPEC_COLOR_STORE() &I830_CONTEXT(ctx)->UbyteSecondaryColor +#define INVALIDATE_STORED_VERTICES() + +#define HAVE_HW_VIEWPORT 0 +#define HAVE_HW_DIVIDE 0 +#define HAVE_RGBA_COLOR 0 +#define HAVE_TINY_VERTICES 1 +#define HAVE_NOTEX_VERTICES 1 +#define HAVE_TEX0_VERTICES 1 +#define HAVE_TEX1_VERTICES 1 +#define HAVE_TEX2_VERTICES 0 +#define HAVE_TEX3_VERTICES 0 +#define HAVE_PTEX_VERTICES 1 + +#define UNVIEWPORT_VARS GLfloat h = I830_CONTEXT(ctx)->driDrawable->h +#define UNVIEWPORT_X(x) x - SUBPIXEL_X +#define UNVIEWPORT_Y(y) - y + h + SUBPIXEL_Y +#define UNVIEWPORT_Z(z) z * (float)I830_CONTEXT(ctx)->ClearDepth + +#define PTEX_FALLBACK() FALLBACK(I830_CONTEXT(ctx), I830_FALLBACK_TEXTURE, 1) + +#define IMPORT_FLOAT_COLORS i830_import_float_colors +#define IMPORT_FLOAT_SPEC_COLORS i830_import_float_spec_colors + +#define INTERP_VERTEX setup_tab[I830_CONTEXT(ctx)->SetupIndex].interp +#define COPY_PV_VERTEX setup_tab[I830_CONTEXT(ctx)->SetupIndex].copy_pv + + +/*********************************************************************** + * Generate pv-copying and translation functions * + ***********************************************************************/ + +#define TAG(x) i830_##x +#include "tnl_dd/t_dd_vb.c" + +/*********************************************************************** + * Generate vertex emit and interp functions * + ***********************************************************************/ + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT) +#define TAG(x) x##_wg +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_SPEC_BIT) +#define TAG(x) x##_wgs +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_TEX0_BIT) +#define TAG(x) x##_wgt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_TEX0_BIT|I830_TEX1_BIT) +#define TAG(x) x##_wgt0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_TEX0_BIT|I830_PTEX_BIT) +#define TAG(x) x##_wgpt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT) +#define TAG(x) x##_wgst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT|\ + I830_TEX1_BIT) +#define TAG(x) x##_wgst0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT|\ + I830_PTEX_BIT) +#define TAG(x) x##_wgspt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT) +#define TAG(x) x##_wgf +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT) +#define TAG(x) x##_wgfs +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT) +#define TAG(x) x##_wgft0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT|\ + I830_TEX1_BIT) +#define TAG(x) x##_wgft0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT|\ + I830_PTEX_BIT) +#define TAG(x) x##_wgfpt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|\ + I830_TEX0_BIT) +#define TAG(x) x##_wgfst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|\ + I830_TEX0_BIT|I830_TEX1_BIT) +#define TAG(x) x##_wgfst0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|\ + I830_TEX0_BIT|I830_PTEX_BIT) +#define TAG(x) x##_wgfspt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_TEX0_BIT) +#define TAG(x) x##_t0 +#include "tnl_dd/t_dd_vbtmp.h" -typedef void (*setupFunc)(struct vertex_buffer *,GLuint,GLuint); +#define IND (I830_TEX0_BIT|I830_TEX1_BIT) +#define TAG(x) x##_t0t1 +#include "tnl_dd/t_dd_vbtmp.h" -static setupFunc setup_func[0x80]; +#define IND (I830_FOG_BIT) +#define TAG(x) x##_f +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_FOG_BIT|I830_TEX0_BIT) +#define TAG(x) x##_ft0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_FOG_BIT|I830_TEX0_BIT|I830_TEX1_BIT) +#define TAG(x) x##_ft0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_RGBA_BIT) +#define TAG(x) x##_g +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_RGBA_BIT|I830_SPEC_BIT) +#define TAG(x) x##_gs +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_RGBA_BIT|I830_TEX0_BIT) +#define TAG(x) x##_gt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_RGBA_BIT|I830_TEX0_BIT|I830_TEX1_BIT) +#define TAG(x) x##_gt0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT) +#define TAG(x) x##_gst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT|I830_TEX1_BIT) +#define TAG(x) x##_gst0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_RGBA_BIT|I830_FOG_BIT) +#define TAG(x) x##_gf +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT) +#define TAG(x) x##_gfs +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT) +#define TAG(x) x##_gft0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT|I830_TEX1_BIT) +#define TAG(x) x##_gft0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|I830_TEX0_BIT) +#define TAG(x) x##_gfst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|I830_TEX0_BIT|\ + I830_TEX1_BIT) +#define TAG(x) x##_gfst0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +/* Add functions for proj texturing for t0 and t1 */ +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_TEX0_BIT|I830_TEX1_BIT|\ + I830_PTEX_BIT) +#define TAG(x) x##_wgpt0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT|\ + I830_TEX1_BIT|I830_PTEX_BIT) +#define TAG(x) x##_wgspt0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT|\ + I830_TEX1_BIT|I830_PTEX_BIT) +#define TAG(x) x##_wgfpt0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|\ + I830_TEX1_BIT|I830_TEX0_BIT|I830_PTEX_BIT) +#define TAG(x) x##_wgfspt0t1 +#include "tnl_dd/t_dd_vbtmp.h" -void i830DDSetupInit( void ) + +static void init_setup_tab( void ) { - int i; - - for (i = 0 ; i < 0x80 ; i++) - setup_func[i] = rs_invalid; - - /* Functions to build vert's from scratch */ - setup_func[I830_WIN_BIT|I830_TEX0_BIT] = rs_wt0; - setup_func[I830_WIN_BIT|I830_TEX0_BIT|I830_TEX1_BIT] = rs_wt0t1; - setup_func[I830_WIN_BIT|I830_FOG_BIT|I830_TEX0_BIT] = rs_wft0; - setup_func[I830_WIN_BIT|I830_FOG_BIT|I830_TEX0_BIT|I830_TEX1_BIT] = rs_wft0t1; - setup_func[I830_WIN_BIT|I830_RGBA_BIT] = rs_wg; - setup_func[I830_WIN_BIT|I830_RGBA_BIT|I830_SPEC_BIT] = rs_wgs; - setup_func[I830_WIN_BIT|I830_RGBA_BIT|I830_TEX0_BIT] = rs_wgt0; - setup_func[I830_WIN_BIT|I830_RGBA_BIT|I830_TEX0_BIT|I830_TEX1_BIT] = rs_wgt0t1; - setup_func[I830_WIN_BIT|I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT] = rs_wgst0; - setup_func[I830_WIN_BIT|I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT|I830_TEX1_BIT] = rs_wgst0t1; - setup_func[I830_WIN_BIT|I830_RGBA_BIT|I830_FOG_BIT] = rs_wgf; - setup_func[I830_WIN_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT] = rs_wgfs; - setup_func[I830_WIN_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT] = rs_wgft0; - setup_func[I830_WIN_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT|I830_TEX1_BIT] = rs_wgft0t1; - setup_func[I830_WIN_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|I830_TEX0_BIT] = rs_wgfst0; - setup_func[I830_WIN_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|I830_TEX0_BIT|I830_TEX1_BIT] = rs_wgfst0t1; - - /* Repair functions */ - setup_func[I830_TEX0_BIT] = rs_t0; - setup_func[I830_TEX0_BIT|I830_TEX1_BIT] = rs_t0t1; - setup_func[I830_FOG_BIT] = rs_f; - setup_func[I830_FOG_BIT|I830_TEX0_BIT] = rs_ft0; - setup_func[I830_FOG_BIT|I830_TEX0_BIT|I830_TEX1_BIT] = rs_ft0t1; - setup_func[I830_RGBA_BIT] = rs_g; - setup_func[I830_RGBA_BIT|I830_SPEC_BIT] = rs_gs; - setup_func[I830_RGBA_BIT|I830_TEX0_BIT] = rs_gt0; - setup_func[I830_RGBA_BIT|I830_TEX0_BIT|I830_TEX1_BIT] = rs_gt0t1; - setup_func[I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT] = rs_gst0; - setup_func[I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT|I830_TEX1_BIT] = rs_gst0t1; - setup_func[I830_RGBA_BIT|I830_FOG_BIT] = rs_gf; - setup_func[I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT] = rs_gfs; - setup_func[I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT] = rs_gft0; - setup_func[I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT|I830_TEX1_BIT] = rs_gft0t1; - setup_func[I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|I830_TEX0_BIT] = rs_gfst0; - setup_func[I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|I830_TEX0_BIT|I830_TEX1_BIT] = rs_gfst0t1; - + init_wg(); + init_wgs(); + init_wgt0(); + init_wgt0t1(); + init_wgpt0(); + init_wgst0(); + init_wgst0t1(); + init_wgspt0(); + init_wgf(); + init_wgfs(); + init_wgft0(); + init_wgft0t1(); + init_wgfpt0(); + init_wgfst0(); + init_wgfst0t1(); + init_wgfspt0(); + init_t0(); + init_t0t1(); + init_f(); + init_ft0(); + init_ft0t1(); + init_g(); + init_gs(); + init_gt0(); + init_gt0t1(); + init_gst0(); + init_gst0t1(); + init_gf(); + init_gfs(); + init_gft0(); + init_gft0t1(); + init_gfst0(); + init_gfst0t1(); + /* Add proj texturing on t1 */ + init_wgpt0t1(); + init_wgspt0t1(); + init_wgfpt0t1(); + init_wgfspt0t1(); } + void i830PrintSetupFlags(char *msg, GLuint flags ) { - fprintf(stderr, "%s: %d %s%s%s%s%s%s%s\n", + fprintf(stderr, "%s(%x): %s%s%s%s%s%s%s\n", msg, (int)flags, - (flags & I830_WIN_BIT) ? " xyzw," : "", + (flags & I830_XYZW_BIT) ? " xyzw," : "", (flags & I830_RGBA_BIT) ? " rgba," : "", (flags & I830_SPEC_BIT) ? " spec," : "", (flags & I830_FOG_BIT) ? " fog," : "", (flags & I830_TEX0_BIT) ? " tex-0," : "", (flags & I830_TEX1_BIT) ? " tex-1," : "", - (flags & I830_ALPHA_BIT) ? " alpha," : ""); + (flags & I830_PTEX_BIT) ? " ptex," : ""); } - -void i830ChooseRasterSetupFunc(GLcontext *ctx) +void i830CheckTexSizes( GLcontext *ctx ) { - i830ContextPtr imesa = I830_CONTEXT( ctx ); - int funcindex = (I830_WIN_BIT | I830_RGBA_BIT); - - if(I830_DEBUG&DEBUG_VERBOSE_TRACE) - fprintf(stderr, "%s\n", __FUNCTION__); - - imesa->vertsize = 8; - imesa->Setup[I830_CTXREG_VF] = VRTX_FORMAT_NTEX(1); - - if (ctx->Texture.ReallyEnabled & 0xf) - funcindex |= I830_TEX0_BIT; - - if (ctx->Texture.ReallyEnabled & 0xf0) { - funcindex |= (I830_TEX0_BIT | I830_TEX1_BIT); - imesa->vertsize = 10; - imesa->Setup[I830_CTXREG_VF] = VRTX_FORMAT_NTEX(2); - } - - if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) - funcindex |= I830_SPEC_BIT; - - if (ctx->FogMode == FOG_FRAGMENT) - funcindex |= I830_FOG_BIT; - - if (MESA_VERBOSE) - i830PrintSetupFlags("xsmesa: full setup function", funcindex); - - imesa->setupindex = funcindex; - ctx->Driver.RasterSetup = setup_func[funcindex]; - if(0) fprintf(stderr, "funcindex : 0x%x\n", funcindex); -} - + TNLcontext *tnl = TNL_CONTEXT(ctx); + i830ContextPtr imesa = I830_CONTEXT( ctx ); + if (!setup_tab[imesa->SetupIndex].check_tex_sizes(ctx)) { + int ind = imesa->SetupIndex |= I830_PTEX_BIT; + + if(setup_tab[ind].vertex_format != imesa->vertex_format) { + int vfmt = setup_tab[ind].vertex_format; + + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_VF] = ~(1<<31) & vfmt; + + if (vfmt & (1<<31)) { + /* Proj texturing */ + imesa->Setup[I830_CTXREG_VF2] = (STATE3D_VERTEX_FORMAT_2_CMD | + VRTX_TEX_SET_0_FMT(TEXCOORDFMT_3D) | + VRTX_TEX_SET_1_FMT(TEXCOORDFMT_3D) | + VRTX_TEX_SET_2_FMT(TEXCOORDFMT_3D) | + VRTX_TEX_SET_3_FMT(TEXCOORDFMT_3D)); + i830UpdateTexUnitProj( ctx, 0, GL_TRUE ); + i830UpdateTexUnitProj( ctx, 1, GL_TRUE ); + + } else { + /* Normal texturing */ + imesa->Setup[I830_CTXREG_VF2] = (STATE3D_VERTEX_FORMAT_2_CMD | + VRTX_TEX_SET_0_FMT(TEXCOORDFMT_2D) | + VRTX_TEX_SET_1_FMT(TEXCOORDFMT_2D) | + VRTX_TEX_SET_2_FMT(TEXCOORDFMT_2D) | + VRTX_TEX_SET_3_FMT(TEXCOORDFMT_2D)); + i830UpdateTexUnitProj( ctx, 0, GL_FALSE ); + i830UpdateTexUnitProj( ctx, 1, GL_FALSE ); + } + imesa->vertex_format = vfmt; + imesa->vertex_size = setup_tab[ind].vertex_size; + imesa->vertex_stride_shift = setup_tab[ind].vertex_stride_shift; + } + if (!imesa->Fallback && + !(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) { + tnl->Driver.Render.Interp = setup_tab[imesa->SetupIndex].interp; + tnl->Driver.Render.CopyPV = setup_tab[imesa->SetupIndex].copy_pv; + } + } +} -void i830DDCheckPartialRasterSetup( GLcontext *ctx, - struct gl_pipeline_stage *d ) +void i830BuildVertices( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint newinputs ) { i830ContextPtr imesa = I830_CONTEXT( ctx ); - GLuint tmp = imesa->setupdone; + GLubyte *v = ((GLubyte *) + imesa->verts + (start<<imesa->vertex_stride_shift)); + GLuint stride = 1<<imesa->vertex_stride_shift; - d->type = 0; - imesa->setupdone = 0; /* cleared if we return */ + if (0) fprintf(stderr, "%s\n", __FUNCTION__); - if ((ctx->Array.Summary & VERT_OBJ_ANY) == 0) - return; + newinputs |= imesa->SetupNewInputs; + imesa->SetupNewInputs = 0; - if (ctx->IndirectTriangles) + if (!newinputs) return; - imesa->setupdone = tmp; + if (newinputs & VERT_CLIP) { + setup_tab[imesa->SetupIndex].emit( ctx, start, count, v, stride ); + } else { + GLuint ind = 0; - /* disabled until we have a merge&render op */ - /* d->inputs = available; */ - /* d->outputs = VERT_RAST_SETUP_PART; */ - /* d->type = PIPE_PRECALC; */ -} - - -/* Repair existing precalculated vertices with new data. - */ -void i830DDPartialRasterSetup( struct vertex_buffer *VB ) -{ - i830ContextPtr imesa = I830_CONTEXT( VB->ctx ); - GLuint new = VB->pipeline->new_outputs; - GLuint available = VB->pipeline->outputs; - GLuint ind = 0; - - if (new & VERT_WIN) { - new = available; - ind |= I830_WIN_BIT | I830_FOG_BIT; - } + if (newinputs & VERT_RGBA) + ind |= I830_RGBA_BIT; - if (new & VERT_RGBA) - ind |= I830_RGBA_BIT | I830_SPEC_BIT; + if (newinputs & VERT_SPEC_RGB) + ind |= I830_SPEC_BIT; - if (new & VERT_TEX0_ANY) - ind |= I830_TEX0_BIT; + if (newinputs & VERT_TEX0) + ind |= I830_TEX0_BIT; - if (new & VERT_TEX1_ANY) - ind |= I830_TEX1_BIT; + if (newinputs & VERT_TEX1) + ind |= I830_TEX1_BIT; - if (new & VERT_FOG_COORD) - ind |= I830_FOG_BIT; + if (newinputs & VERT_FOG_COORD) + ind |= I830_FOG_BIT; - imesa->setupdone &= ~ind; - ind &= imesa->setupindex; - imesa->setupdone |= ind; +#if 0 + if (imesa->SetupIndex & I830_PTEX_BIT) + ind = ~0; +#endif - if (0) i830PrintSetupFlags("xsmesa: partial setup function", ind); + ind &= imesa->SetupIndex; - if (ind) - setup_func[ind&~I830_ALPHA_BIT]( VB, VB->Start, VB->Count ); + if (ind) { + setup_tab[ind].emit( ctx, start, count, v, stride ); + } + } } - -void i830DDDoRasterSetup( struct vertex_buffer *VB ) +void i830ChooseVertexState( GLcontext *ctx ) { - GLcontext *ctx = VB->ctx; - - if (VB->Type == VB_CVA_PRECALC) - i830DDPartialRasterSetup( VB ); - else if (ctx->Driver.RasterSetup) - ctx->Driver.RasterSetup( VB, VB->CopyStart, VB->Count ); -} + TNLcontext *tnl = TNL_CONTEXT(ctx); + i830ContextPtr imesa = I830_CONTEXT( ctx ); + GLuint ind = I830_XYZW_BIT|I830_RGBA_BIT; + if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) + ind |= I830_SPEC_BIT; + if (ctx->Fog.Enabled) + ind |= I830_FOG_BIT; + if (ctx->Texture._ReallyEnabled & 0xf0) + ind |= I830_TEX1_BIT|I830_TEX0_BIT; + else if (ctx->Texture._ReallyEnabled & 0xf) + ind |= I830_TEX0_BIT; -void i830DDResizeVB( struct vertex_buffer *VB, GLuint size ) -{ - i830VertexBufferPtr mvb = I830_DRIVER_DATA(VB); + imesa->SetupIndex = ind; - while (mvb->size < size) - mvb->size *= 2; + if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) { + tnl->Driver.Render.Interp = i830_interp_extras; + tnl->Driver.Render.CopyPV = i830_copy_pv_extras; + } else { + tnl->Driver.Render.Interp = setup_tab[ind].interp; + tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv; + } - free( mvb->vert_store ); - mvb->vert_store = malloc( sizeof(i830Vertex) * mvb->size + 31); - if (!mvb->vert_store) { - fprintf(stderr, "i830glx: out of memory !\n"); - exit(1); + if (setup_tab[ind].vertex_format != imesa->vertex_format) { + int vfmt = setup_tab[ind].vertex_format; + + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_VF] = ~(1<<31) & vfmt; + + if (vfmt & (1<<31)) { + /* Proj texturing */ + imesa->Setup[I830_CTXREG_VF2] = (STATE3D_VERTEX_FORMAT_2_CMD | + VRTX_TEX_SET_0_FMT(TEXCOORDFMT_3D) | + VRTX_TEX_SET_1_FMT(TEXCOORDFMT_3D) | + VRTX_TEX_SET_2_FMT(TEXCOORDFMT_3D) | + VRTX_TEX_SET_3_FMT(TEXCOORDFMT_3D)); + i830UpdateTexUnitProj( ctx, 0, GL_TRUE ); + i830UpdateTexUnitProj( ctx, 1, GL_TRUE ); + } else { + /* Normal texturing */ + imesa->Setup[I830_CTXREG_VF2] = (STATE3D_VERTEX_FORMAT_2_CMD | + VRTX_TEX_SET_0_FMT(TEXCOORDFMT_2D) | + VRTX_TEX_SET_1_FMT(TEXCOORDFMT_2D) | + VRTX_TEX_SET_2_FMT(TEXCOORDFMT_2D) | + VRTX_TEX_SET_3_FMT(TEXCOORDFMT_2D)); + i830UpdateTexUnitProj( ctx, 0, GL_FALSE ); + i830UpdateTexUnitProj( ctx, 1, GL_FALSE ); + } + imesa->vertex_format = vfmt; + imesa->vertex_size = setup_tab[ind].vertex_size; + imesa->vertex_stride_shift = setup_tab[ind].vertex_stride_shift; } +} - mvb->verts = (i830VertexPtr)(((unsigned long)mvb->vert_store + 31) & ~31); - gl_vector1ui_free( &mvb->clipped_elements ); - gl_vector1ui_alloc( &mvb->clipped_elements, VEC_WRITABLE, mvb->size, 32 ); - if (!mvb->clipped_elements.start) { - fprintf(stderr, "i830glx: out of memory !\n"); - exit(1); - } - ALIGN_FREE( VB->ClipMask ); - VB->ClipMask = (GLubyte *) ALIGN_MALLOC(sizeof(GLubyte) * mvb->size, 4); - if (!VB->ClipMask) { - fprintf(stderr, "i830glx: out of memory !\n"); - exit(1); - } +void i830_emit_contiguous_verts( GLcontext *ctx, + GLuint start, + GLuint count ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + GLuint vertex_size = imesa->vertex_size * 4; + GLuint *dest = i830AllocDmaLow( imesa, (count-start) * vertex_size); + setup_tab[imesa->SetupIndex].emit( ctx, start, count, dest, vertex_size ); +} - if (VB->Type == VB_IMMEDIATE) { - free( mvb->primitive ); - free( mvb->next_primitive ); - mvb->primitive = (GLuint *)malloc( sizeof(GLuint) * mvb->size ); - mvb->next_primitive = (GLuint *)malloc( sizeof(GLuint) * mvb->size ); - if (!mvb->primitive || !mvb->next_primitive) { - fprintf(stderr, "i830glx: out of memory !\n"); - exit(1); + +void i830InitVB( GLcontext *ctx ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + GLuint size = TNL_CONTEXT(ctx)->vb.Size; + if (DEBUGGING) + fprintf (stderr,"\n%s\n",__FUNCTION__); + + imesa->verts = (char *)ALIGN_MALLOC(size * 4 * 16, 32); + + { + static int firsttime = 1; + if (firsttime) { + init_setup_tab(); + firsttime = 0; } } + if (DEBUGGING) + fprintf(stderr,"\nFinished InitVB\n"); } -void i830DDRegisterVB( struct vertex_buffer *VB ) +void i830FreeVB( GLcontext *ctx ) { - i830VertexBufferPtr mvb; - - mvb = (i830VertexBufferPtr)calloc( 1, sizeof(*mvb) ); - - mvb->size = VB->Size * 2; - mvb->vert_store = malloc( sizeof(i830Vertex) * mvb->size + 31); - if (!mvb->vert_store) { - fprintf(stderr, "i830glx: out of memory !\n"); - exit(1); + i830ContextPtr imesa = I830_CONTEXT(ctx); + if (imesa->verts) { + ALIGN_FREE(imesa->verts); + imesa->verts = 0; } - - mvb->verts = (i830VertexPtr)(((unsigned long)mvb->vert_store + 31) & ~31); - gl_vector1ui_alloc( &mvb->clipped_elements, VEC_WRITABLE, mvb->size, 32 ); - if (!mvb->clipped_elements.start) { - fprintf(stderr, "i830glx: out of memory !\n"); - exit(1); - } - - ALIGN_FREE( VB->ClipMask ); - VB->ClipMask = (GLubyte *) ALIGN_MALLOC(sizeof(GLubyte) * mvb->size, 4); - if (!VB->ClipMask) { - fprintf(stderr, "i830glx: out of memory !\n"); - exit(1); + if (imesa->UbyteSecondaryColor.Ptr) { + ALIGN_FREE(imesa->UbyteSecondaryColor.Ptr); + imesa->UbyteSecondaryColor.Ptr = 0; } - mvb->primitive = (GLuint *)malloc( sizeof(GLuint) * mvb->size ); - mvb->next_primitive = (GLuint *)malloc( sizeof(GLuint) * mvb->size ); - if (!mvb->primitive || !mvb->next_primitive) { - fprintf(stderr, "i830glx: out of memory !\n"); - exit(1); + if (imesa->UbyteColor.Ptr) { + ALIGN_FREE(imesa->UbyteColor.Ptr); + imesa->UbyteColor.Ptr = 0; } - - VB->driver_data = mvb; -} - - -void i830DDUnregisterVB( struct vertex_buffer *VB ) -{ - i830VertexBufferPtr mvb = I830_DRIVER_DATA(VB); - - if (mvb) { - if (mvb->vert_store) free(mvb->vert_store); - if (mvb->primitive) free(mvb->primitive); - if (mvb->next_primitive) free(mvb->next_primitive); - gl_vector1ui_free( &mvb->clipped_elements ); - free(mvb); - VB->driver_data = 0; - } } diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_vb.h b/xc/lib/GL/mesa/src/drv/i830/i830_vb.h new file mode 100644 index 000000000..143659146 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/i830/i830_vb.h @@ -0,0 +1,63 @@ +/* + * 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"), + * 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 + * 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. + * + * Adapted for use in the I830M: + * Jeff Hartmann <jhartmann@2d3d.com> + */ +/* $XFree86$ */ + +#ifndef I830VB_INC +#define I830VB_INC + +#include "mtypes.h" +#include "swrast/swrast.h" + +#define _I830_NEW_VERTEX (_NEW_TEXTURE | \ + _DD_NEW_SEPARATE_SPECULAR | \ + _DD_NEW_TRI_UNFILLED | \ + _DD_NEW_TRI_LIGHT_TWOSIDE | \ + _NEW_FOG) + + +extern void i830ChooseVertexState( GLcontext *ctx ); +extern void i830CheckTexSizes( GLcontext *ctx ); +extern void i830BuildVertices( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint newinputs ); + + +extern void i830_emit_contiguous_verts( GLcontext *ctx, + GLuint start, + GLuint count ); + +extern void i830_translate_vertex( GLcontext *ctx, + const i830Vertex *src, + SWvertex *dst ); + +extern void i830InitVB( GLcontext *ctx ); +extern void i830FreeVB( GLcontext *ctx ); + +extern void i830_print_vertex( GLcontext *ctx, const i830Vertex *v ); +extern void i830PrintSetupFlags(char *msg, GLuint flags ); + +#endif diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_vert_form_points.h b/xc/lib/GL/mesa/src/drv/i830/i830_vert_form_points.h index bffeb400a..6b0ebef76 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_vert_form_points.h +++ b/xc/lib/GL/mesa/src/drv/i830/i830_vert_form_points.h @@ -29,7 +29,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Author: - * Jeff Hartmann <jhartmann@valinux.com> + * Jeff Hartmann <jhartmann@2d3d.com> * * Heavily based on the I810 driver, which was written by: * Keith Whitwell <keithw@valinux.com> diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_vert_form_tris.h b/xc/lib/GL/mesa/src/drv/i830/i830_vert_form_tris.h index 328055ad7..915add2e2 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_vert_form_tris.h +++ b/xc/lib/GL/mesa/src/drv/i830/i830_vert_form_tris.h @@ -29,7 +29,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Author: - * Jeff Hartmann <jhartmann@valinux.com> + * Jeff Hartmann <jhartmann@2d3d.com> * * Heavily based on the I810 driver, which was written by: * Keith Whitwell <keithw@valinux.com> diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_xmesa.c b/xc/lib/GL/mesa/src/drv/i830/i830_xmesa.c deleted file mode 100644 index 436f789c3..000000000 --- a/xc/lib/GL/mesa/src/drv/i830/i830_xmesa.c +++ /dev/null @@ -1,722 +0,0 @@ -/************************************************************************** - -Copyright 2001 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 -on the rights to use, copy, modify, merge, publish, distribute, sub -license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL -ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS 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/i830/i830_xmesa.c,v 1.1 2001/10/04 18:28:21 alanh Exp $ */ - -/* - * Author: - * Jeff Hartmann <jhartmann@valinux.com> - * - * Heavily based on the I810 driver, which was written by: - * Keith Whitwell <keithw@valinux.com> - */ - -#ifdef GLX_DIRECT_RENDERING - -#include <X11/Xlibint.h> -#include <stdio.h> - -#include "context.h" -#include "vbxform.h" -#include "matrix.h" -#include "simple_list.h" - -#include "i830_drv.h" -#include "i830_tris.h" -#include "i830_ioctl.h" - -#include "i830_dri.h" - - - -#ifndef I830_DEBUG -int I830_DEBUG = (0 - | DEBUG_VERBOSE_TRACE -/* | DEBUG_VERBOSE_STATE */ -/* | DEBUG_ALWAYS_SYNC */ -/* | DEBUG_VERBOSE_RING */ -/* | DEBUG_VERBOSE_OUTREG */ -/* | DEBUG_VERBOSE_MSG */ -/* | DEBUG_NO_OUTRING */ -/* | DEBUG_NO_OUTREG */ -/* | DEBUG_VERBOSE_API */ -/* | DEBUG_VERBOSE_2D */ -/* | DEBUG_VERBOSE_DRI */ -/* | DEBUG_VALIDATE_RING */ -/* | DEBUG_VERBOSE_IOCTL */ - ); -#endif - - -static i830ContextPtr i830Ctx = 0; - - -/* These functions are accessed externally to the driver: - * - * XMesaInitDriver - * XMesaResetDriver - * XMesaCreateVisual - * XMesaDestroyVisual - * XMesaCreateContext - * XMesaDestroyContext - * XMesaCreateWindowBuffer - * XMesaCreatePixmapBuffer - * XMesaDestroyBuffer - * XMesaSwapBuffers - * XMesaMakeCurrent - * - */ - - -static int i830_malloc_proxy_buf(drmBufMapPtr buffers) -{ - char *buffer; - drmBufPtr buf; - int i; - - buffer = Xmalloc(I830_DMA_BUF_SZ); - if(buffer == NULL) return -1; - for(i = 0; i < I830_DMA_BUF_NR; i++) { - buf = &(buffers->list[i]); - buf->address = (drmAddress)buffer; - } - return 0; -} - -static drmBufMapPtr i830_create_empty_buffers(void) -{ - drmBufMapPtr retval; - - retval = (drmBufMapPtr)Xmalloc(sizeof(drmBufMap)); - if(retval == NULL) return NULL; - memset(retval, 0, sizeof(drmBufMap)); - retval->list = (drmBufPtr)Xmalloc(sizeof(drmBuf) * I830_DMA_BUF_NR); - if(retval->list == NULL) { - Xfree(retval); - return NULL; - } - memset(retval->list, 0, sizeof(drmBuf) * I830_DMA_BUF_NR); - /* - fprintf(stderr, "retval : %p, retval->list : %p\n", retval, retval->list); - */ - return retval; -} - -GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) -{ - i830ScreenPrivate *i830Screen; - I830DRIPtr gDRIPriv = (I830DRIPtr)sPriv->pDevPriv; - - /* Check the DRI version */ - { - int major, minor, patch; - if (XF86DRIQueryVersion(sPriv->display, &major, &minor, &patch)) { - if (major != 4 || minor < 0) { - char msg[1000]; - sprintf(msg, "i830 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) { - char msg[1000]; - sprintf(msg, "i830 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 < 2) { - char msg[1000]; - sprintf(msg, "i830 DRI driver expected DRM driver version 1.2.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch); - __driMesaMessage(msg); - return GL_FALSE; - } - - /* Allocate the private area */ - i830Screen = (i830ScreenPrivate *)Xmalloc(sizeof(i830ScreenPrivate)); - if (!i830Screen) - return GL_FALSE; - - i830Screen->driScrnPriv = sPriv; - sPriv->private = (void *)i830Screen; - - i830Screen->deviceID=gDRIPriv->deviceID; - i830Screen->width=gDRIPriv->width; - i830Screen->height=gDRIPriv->height; - i830Screen->mem=gDRIPriv->mem; - i830Screen->cpp=gDRIPriv->cpp; - i830Screen->fbStride=gDRIPriv->fbStride; - i830Screen->fbOffset=gDRIPriv->fbOffset; - - switch (gDRIPriv->bitsPerPixel) { - case 15: i830Screen->fbFormat = DV_PF_555; break; - case 16: i830Screen->fbFormat = DV_PF_565; break; - case 32: i830Screen->fbFormat = DV_PF_8888; break; - } - - i830Screen->backOffset=gDRIPriv->backOffset; - i830Screen->depthOffset=gDRIPriv->depthOffset; - i830Screen->backPitch = gDRIPriv->auxPitch; - i830Screen->backPitchBits = gDRIPriv->auxPitchBits; - i830Screen->textureOffset=gDRIPriv->textureOffset; - i830Screen->textureSize=gDRIPriv->textureSize; - i830Screen->logTextureGranularity = gDRIPriv->logTextureGranularity; - i830Screen->sarea_priv_offset = gDRIPriv->sarea_priv_offset; - - if (0) - fprintf(stderr, "Tex heap size %x, granularity %x bytes\n", - i830Screen->textureSize, 1<<(i830Screen->logTextureGranularity)); - - i830Screen->bufs = i830_create_empty_buffers(); - if(i830Screen->bufs == NULL) - { - Xfree(i830Screen); - return GL_FALSE; - } - - /* Check if you need to create a fake buffer */ - if(i830_check_copy(sPriv->fd) == 1) - { - i830_malloc_proxy_buf(i830Screen->bufs); - i830Screen->use_copy_buf = 1; - } - else - { - i830Screen->use_copy_buf = 0; - } - - i830Screen->back.handle = gDRIPriv->backbuffer; - i830Screen->back.size = gDRIPriv->backbufferSize; - - if (drmMap(sPriv->fd, - i830Screen->back.handle, - i830Screen->back.size, - (drmAddress *)&i830Screen->back.map) != 0) - { - Xfree(i830Screen); - sPriv->private = NULL; - return GL_FALSE; - } - - i830Screen->depth.handle = gDRIPriv->depthbuffer; - i830Screen->depth.size = gDRIPriv->depthbufferSize; - - if (drmMap(sPriv->fd, - i830Screen->depth.handle, - i830Screen->depth.size, - (drmAddress *)&i830Screen->depth.map) != 0) - { - Xfree(i830Screen); - drmUnmap(i830Screen->back.map, i830Screen->back.size); - sPriv->private = NULL; - return GL_FALSE; - } - - i830Screen->tex.handle = gDRIPriv->textures; - i830Screen->tex.size = gDRIPriv->textureSize; - - if (drmMap(sPriv->fd, - i830Screen->tex.handle, - i830Screen->tex.size, - (drmAddress *)&i830Screen->tex.map) != 0) - { - Xfree(i830Screen); - drmUnmap(i830Screen->back.map, i830Screen->back.size); - drmUnmap(i830Screen->depth.map, i830Screen->depth.size); - sPriv->private = NULL; - return GL_FALSE; - } - - - i830DDFastPathInit(); - i830DDTrifuncInit(); - i830DDSetupInit(); - - return GL_TRUE; -} - -/* Accessed by dlsym from dri_mesa_init.c - */ -void XMesaResetDriver(__DRIscreenPrivate *sPriv) -{ - i830ScreenPrivate *i830Screen = (i830ScreenPrivate *)sPriv->private; - - /* Need to unmap all the bufs and maps here: - */ - drmUnmap(i830Screen->back.map, i830Screen->back.size); - drmUnmap(i830Screen->depth.map, i830Screen->depth.size); - drmUnmap(i830Screen->tex.map, i830Screen->tex.size); - - Xfree(i830Screen); - sPriv->private = NULL; -} - - -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 ) -{ - GLcontext *ctx = driContextPriv->mesaContext; - i830ContextPtr imesa; - __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; - i830ScreenPrivate *i830Screen = (i830ScreenPrivate *)sPriv->private; - I830SAREAPtr saPriv=(I830SAREAPtr)(((char*)sPriv->pSAREA)+ - i830Screen->sarea_priv_offset); - - imesa = (i830ContextPtr)Xcalloc(sizeof(i830Context), 1); - if (!imesa) { - return GL_FALSE; - } - - - /* Set the maximum texture size small enough that we can guarentee - * that both texture units can bind a maximal texture and have them - * in memory at once. - */ - if (i830Screen->textureSize < 2*1024*1024) { - ctx->Const.MaxTextureLevels = 9; - ctx->Const.MaxTextureSize = 1<<8; - } else if (i830Screen->textureSize < 8*1024*1024) { - ctx->Const.MaxTextureLevels = 10; - ctx->Const.MaxTextureSize = 1<<9; - } else { - ctx->Const.MaxTextureLevels = 11; - ctx->Const.MaxTextureSize = 1<<10; - } - - ctx->Const.MinLineWidth = 1.0; - ctx->Const.MinLineWidthAA = 1.0; - ctx->Const.MaxLineWidth = 3.0; - ctx->Const.MaxLineWidthAA = 3.0; - ctx->Const.LineWidthGranularity = 1.0; - - - /* Dri stuff - */ - imesa->display = dpy; - imesa->hHWContext = driContextPriv->hHWContext; - imesa->driFd = sPriv->fd; - imesa->driHwLock = &sPriv->pSAREA->lock; - - imesa->i830Screen = i830Screen; - imesa->driScreen = sPriv; - imesa->sarea = saPriv; - imesa->glBuffer = NULL; - - imesa->texHeap = mmInit( 0, i830Screen->textureSize ); - - - /* Utah stuff - */ - imesa->renderindex = -1; /* impossible value */ - imesa->new_state = ~0; - imesa->dirty = ~0; - - make_empty_list(&imesa->TexObjList); - make_empty_list(&imesa->SwappedOut); - - imesa->TextureMode = ctx->Texture.Unit[0].EnvMode; - imesa->CurrentTexObj[0] = 0; - imesa->CurrentTexObj[1] = 0; - - ctx->DriverCtx = (void *) imesa; - imesa->glCtx = ctx; - - i830DDExtensionsInit( ctx ); - - imesa->hw_stencil = mesaVis->StencilBits && mesaVis->DepthBits == 24; - - switch(mesaVis->DepthBits) { - case 16: - imesa->depth_scale = 1.0/0x10000; - imesa->depth_clear_mask = ~0; - imesa->ClearDepth = 0xffff; - break; - case 24: - imesa->depth_scale = 1.0/0x1000000; - imesa->depth_clear_mask = 0x00ffffff; - imesa->stencil_clear_mask = 0xff000000; - imesa->ClearDepth = 0x00ffffff; - break; - case 32: /* Not supported I don't believe */ - default: -#define DUMMY() /* keep gcc happy */ - DUMMY(); - } - - /* Completely disable stenciling for now, there are some serious issues - * with stencil. - */ -#if 1 - imesa->hw_stencil = 0; -#endif - - i830DDInitStateFuncs( ctx ); - i830DDInitTextureFuncs( ctx ); - i830DDInitSpanFuncs( ctx ); - i830DDInitDriverFuncs( ctx ); - i830DDInitIoctlFuncs( ctx ); - - ctx->Driver.TriangleCaps = (DD_TRI_CULL| - DD_TRI_LIGHT_TWOSIDE| - DD_TRI_STIPPLE| - DD_TRI_OFFSET); - - /* Ask mesa to clip fog coordinates for us. - */ - ctx->TriangleCaps |= DD_CLIP_FOG_COORD; - - if (ctx->VB) - i830DDRegisterVB( ctx->VB ); - - if (ctx->NrPipelineStages) - ctx->NrPipelineStages = - i830DDRegisterPipelineStages(ctx->PipelineStage, - ctx->PipelineStage, - ctx->NrPipelineStages); - - i830DDInitState( imesa ); - - driContextPriv->driverPrivate = (void *) imesa; - - return GL_TRUE; -} - -void XMesaDestroyContext(__DRIcontextPrivate *driContextPriv) -{ - i830ContextPtr imesa = (i830ContextPtr) driContextPriv->driverPrivate; - - if (imesa) { - i830TextureObjectPtr next_t, t; - - foreach_s (t, next_t, &(imesa->TexObjList)) - i830DestroyTexObj(imesa, t); - - foreach_s (t, next_t, &(imesa->SwappedOut)) - i830DestroyTexObj(imesa, t); - - Xfree(imesa); - } -} - -GLframebuffer *XMesaCreateWindowBuffer( Display *dpy, - __DRIscreenPrivate *driScrnPriv, - __DRIdrawablePrivate *driDrawPriv, - GLvisual *mesaVis) -{ -#if 0 - GLboolean swStencil = mesaVis->StencilBits > 0 && mesaVis->DepthBits != 24; -#else - GLboolean swStencil = mesaVis->StencilBits > 0; -#endif - return gl_create_framebuffer(mesaVis, - GL_FALSE, - swStencil, - mesaVis->AccumRedBits > 0, - mesaVis->AlphaBits > 0 - ); -} - - -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) -{ - /* XXX should do swap according to the buffer, not the context! */ - i830ContextPtr imesa = i830Ctx; - - if( !driDrawPriv->mesaBuffer->Visual->DBflag ) return; - - FLUSH_VB( imesa->glCtx, "swap buffers" ); - i830SwapBuffers(imesa); -} - - - -void i830XMesaSetFrontClipRects( i830ContextPtr imesa ) -{ - __DRIdrawablePrivate *dPriv = imesa->driDrawable; - - imesa->numClipRects = dPriv->numClipRects; - imesa->pClipRects = dPriv->pClipRects; - imesa->dirty |= I830_UPLOAD_CLIPRECTS; - imesa->drawX = dPriv->x; - imesa->drawY = dPriv->y; - - i830EmitDrawingRectangle( imesa ); -} - - -void i830XMesaSetBackClipRects( i830ContextPtr imesa ) -{ - __DRIdrawablePrivate *dPriv = imesa->driDrawable; - int i; - - if (dPriv->numBackClipRects == 0) - { - if (I830_DEBUG & DEBUG_VERBOSE_DRI) - fprintf(stderr, "FRONT_CLIPRECTS, %d rects\n", - dPriv->numClipRects); - - imesa->numClipRects = dPriv->numClipRects; - imesa->pClipRects = dPriv->pClipRects; - imesa->drawX = dPriv->x; - imesa->drawY = dPriv->y; - } else { - if (I830_DEBUG & DEBUG_VERBOSE_DRI) - fprintf(stderr, "BACK_RECTS, %d rects\n", - dPriv->numBackClipRects); - - imesa->numClipRects = dPriv->numBackClipRects; - imesa->pClipRects = dPriv->pBackClipRects; - imesa->drawX = dPriv->backX; - imesa->drawY = dPriv->backY; - } - - i830EmitDrawingRectangle( imesa ); - imesa->dirty |= I830_UPLOAD_CLIPRECTS; - - if (I830_DEBUG & DEBUG_VERBOSE_DRI) - for (i = 0 ; i < imesa->numClipRects ; i++) - fprintf(stderr, "cliprect %d: %d,%d - %d,%d\n", - i, - imesa->pClipRects[i].x1, - imesa->pClipRects[i].y1, - imesa->pClipRects[i].x2, - imesa->pClipRects[i].y2); -} - - -static void i830XMesaWindowMoved( i830ContextPtr imesa ) -{ - if (0) - fprintf(stderr, "i830XMesaWindowMoved\n\n"); - - switch (imesa->glCtx->Color.DriverDrawBuffer) { - case GL_FRONT_LEFT: - i830XMesaSetFrontClipRects( imesa ); - break; - case GL_BACK_LEFT: - i830XMesaSetBackClipRects( imesa ); - break; - default: - /*fprintf(stderr, "fallback buffer\n");*/ - break; - } -} - -GLboolean -XMesaOpenFullScreen(__DRIcontextPrivate *driContextPriv) -{ - return GL_TRUE; -} - -GLboolean -XMesaCloseFullScreen(__DRIcontextPrivate *driContextPriv) -{ - return GL_TRUE; -} - -GLboolean XMesaUnbindContext(__DRIcontextPrivate *driContextPriv) -{ - i830ContextPtr i830 = (i830ContextPtr) driContextPriv->driverPrivate; - if (i830) - i830->dirty = ~0; - - return GL_TRUE; -} - - -GLboolean XMesaMakeCurrent(__DRIcontextPrivate *driContextPriv, - __DRIdrawablePrivate *driDrawPriv, - __DRIdrawablePrivate *driReadPriv) -{ - if (driContextPriv) { - i830Ctx = (i830ContextPtr) driContextPriv->driverPrivate; - - gl_make_current2(i830Ctx->glCtx, driDrawPriv->mesaBuffer, - driReadPriv->mesaBuffer); - - - i830Ctx->driDrawable = driDrawPriv; - i830Ctx->dirty = ~0; - - i830XMesaWindowMoved( i830Ctx ); - - if (!i830Ctx->glCtx->Viewport.Width) - gl_Viewport(i830Ctx->glCtx, 0, 0, driDrawPriv->w, driDrawPriv->h); - } - else - { - gl_make_current(0,0); - i830Ctx = NULL; - } - return GL_TRUE; -} - - -void i830GetLock( i830ContextPtr imesa, GLuint flags ) -{ - __DRIdrawablePrivate *dPriv = imesa->driDrawable; - __DRIscreenPrivate *sPriv = imesa->driScreen; - I830SAREAPtr sarea = imesa->sarea; - int me = imesa->hHWContext; - int stamp = dPriv->lastStamp; - - - if (0) fprintf(stderr, ".\n"); - - /* We know there has been contention. - */ - drmGetLock(imesa->driFd, imesa->hHWContext, flags); - - - /* Note contention for throttling hint - */ - imesa->any_contend = 1; - - /* If the window moved, may need to set a new cliprect now. - * - * NOTE: This releases and regains the hw lock, so all state - * checking must be done *after* this call: - */ - XMESA_VALIDATE_DRAWABLE_INFO(imesa->display, sPriv, dPriv); - - - if (0) - fprintf(stderr, "i830GetLock, last enque: %d last dispatch: %d\n", - sarea->last_enqueue, - sarea->last_dispatch); - - /* If we lost context, need to dump all registers to hardware. - * Note that we don't care about 2d contexts, even if they perform - * accelerated commands, so the DRI locking in the X server is even - * more broken than usual. - */ - if (sarea->ctxOwner != me) { - imesa->dirty |= (I830_UPLOAD_CTX | - I830_UPLOAD_CLIPRECTS | - I830_UPLOAD_BUFFERS | - I830_UPLOAD_TEX0 | - I830_UPLOAD_TEX1); - - if(imesa->TexBlendWordsUsed[0]) imesa->dirty |= I830_UPLOAD_TEXBLEND0; - if(imesa->TexBlendWordsUsed[1]) imesa->dirty |= I830_UPLOAD_TEXBLEND1; - - sarea->ctxOwner = me; - } - - /* Shared texture managment - if another client has played with - * texture space, figure out which if any of our textures have been - * ejected, and update our global LRU. - */ - if (sarea->texAge != imesa->texAge) { - int sz = 1 << (imesa->i830Screen->logTextureGranularity); - int idx, nr = 0; - - /* Have to go right round from the back to ensure stuff ends up - * LRU in our local list... - */ - for (idx = sarea->texList[I830_NR_TEX_REGIONS].prev ; - idx != I830_NR_TEX_REGIONS && nr < I830_NR_TEX_REGIONS ; - idx = sarea->texList[idx].prev, nr++) - { - if (sarea->texList[idx].age > imesa->texAge) - i830TexturesGone(imesa, idx * sz, sz, sarea->texList[idx].in_use); - } - - if (nr == I830_NR_TEX_REGIONS) { - i830TexturesGone(imesa, 0, imesa->i830Screen->textureSize, 0); - i830ResetGlobalLRU( imesa ); - } - - if (0) fprintf(stderr, "imesa %d sarea %d\n", imesa->texAge, sarea->texAge); - imesa->dirty |= I830_UPLOAD_TEX0_IMAGE; - imesa->dirty |= I830_UPLOAD_TEX1_IMAGE; - imesa->texAge = sarea->texAge; - } - - - if (dPriv->lastStamp != stamp) - i830XMesaWindowMoved( imesa ); - - - sarea->last_quiescent = -1; /* just kill it for now */ -} - - -#endif |