diff options
Diffstat (limited to 'src')
35 files changed, 12199 insertions, 0 deletions
| diff --git a/src/mesa/drivers/dri/mga/Makefile.X11 b/src/mesa/drivers/dri/mga/Makefile.X11 new file mode 100644 index 0000000000..c69d6e5989 --- /dev/null +++ b/src/mesa/drivers/dri/mga/Makefile.X11 @@ -0,0 +1,116 @@ +# $Id: Makefile.X11,v 1.1 2003/08/06 18:01:13 keithw Exp $ + +# Mesa 3-D graphics library +# Version:  5.0 +# Copyright (C) 1995-2002  Brian Paul + +TOP = ../../../../.. + +SHARED_INCLUDES = $(INCLUDE_DIRS) -I. -I../common -Iserver +MINIGLX_INCLUDES = -I$(TOP)/src/miniglx  + +DEFINES += \ +	-D_HAVE_SWRAST=1 \ +	-D_HAVE_SWTNL=1 \ +	-D_HAVE_SANITY=1 \ +	-D_HAVE_CODEGEN=1 \ +	-D_HAVE_LIGHTING=1 \ +	-D_HAVE_TEXGEN=1 \ +	-D_HAVE_USERCLIP=1 + +MINIGLX_SOURCES = server/mga_dri.c  + +DRIVER_SOURCES = mgabuffers.c \ +		 mgadd.c \ +		 mgaioctl.c \ +		 mgarender.c \ +		 mgastate.c \ +		 mgatris.c \ +		 ../common/mm.c  + +FULL_DRIVER_SOURCES = 	\ +		 mgapixel.c \ +		 mgaspan.c \ +		 mgatex.c \ +		 mgatexcnv.c \ +		 mgatexmem.c \ +		 mgavb.c \ +		 mga_xmesa.c + + +INCLUDES = $(MINIGLX_INCLUDES) \ +	   $(SHARED_INCLUDES) + + +C_SOURCES = $(MINIGLX_SOURCES) \ +	    $(FULL_DRIVER_SOURCES) \ +	    $(DRIVER_SOURCES)  + +MESA_MODULES = $(TOP)/src/mesa/mesa.a + + +ifeq ($(WINDOW_SYSTEM),dri) +WINOBJ=$(MESABUILDDIR)/dri/dri.a +WINLIB= +else +WINOBJ= +WINLIB=-L$(MESA)/src/miniglx +endif + +ASM_SOURCES =  +OBJECTS = $(C_SOURCES:.c=.o) \ +	  $(ASM_SOURCES:.S=.o)  + + + +### Include directories + +INCLUDE_DIRS = \ +	-I$(TOP)/include \ +	-I$(TOP)/src/mesa \ +	-I$(TOP)/src/mesa/main \ +	-I$(TOP)/src/mesa/glapi \ +	-I$(TOP)/src/mesa/math \ +	-I$(TOP)/src/mesa/transform \ +	-I$(TOP)/src/mesa/swrast \ +	-I$(TOP)/src/mesa/swrast_setup + + +##### RULES ##### + +.c.o: +	$(CC) -c $(SHARED_INCLUDES) $(MINIGLX_INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ + +.S.o: +	$(CC) -c $(SHARED_INCLUDES) $(MINIGLX_INCLUDES) $(CFLAGS) $(DEFINES)  $< -o $@ + + +##### TARGETS ##### + +targets: mga_dri.so + +mga_dri.so:  $(OBJECTS) $(MESA_MODULES) $(WINOBJ) Makefile.X11 +	rm -f $@ && gcc -o $@ -shared $(OBJECTS) $(MESA_MODULES) $(WINOBJ) $(WINLIB) -lc -lm +	rm -f $(TOP)/lib/mga_dri.so && \ +	install mga_dri.so $(TOP)/lib/mga_dri.so + +# Run 'make -f Makefile.X11 dep' to update the dependencies if you change +# what's included by any source file. +dep: $(C_SOURCES) $(ASM_SOURCES) +	makedepend -fdepend -Y $(SHARED_INCLUDES) \ +		$(C_SOURCES) $(ASM_SOURCES) + + +# Emacs tags +tags: +	etags `find . -name \*.[ch]` `find ../include` + + +# Remove .o and backup files +clean: +	-rm -f *.o *~ *.o *~ *.so + + +include $(TOP)/Make-config + +include depend diff --git a/src/mesa/drivers/dri/mga/README b/src/mesa/drivers/dri/mga/README new file mode 100644 index 0000000000..a7133fa66f --- /dev/null +++ b/src/mesa/drivers/dri/mga/README @@ -0,0 +1,26 @@ +MGA DRI driver ported from XF86DRI to FBDRI +by Denis Oliver Kropp <dok@directfb.org> + + +INFO + +This driver has been ported from the head branch of XFree86 to +the embedded-1-branch of Mesa. + + +STATUS + +Already working very well as far as I've tested it (16/32 bit). +glxgears runs at 935 fps (G550 32MB AGP 4x, Athlon 1.33) vs 744 fps with XFree. +Other demos (terrain, fire, etc.) have been successfully tested as well. + + +TODO + +- mgaEngineShutdown +- mgaEngineRestore +- SGRAM detection +- remove some unused bits from server/* +- subset driver support +- mgaWaitForVBlank +- deinitialization (from MGADRICloseScreen) a la radeonDestroyScreen diff --git a/src/mesa/drivers/dri/mga/mga_xmesa.c b/src/mesa/drivers/dri/mga/mga_xmesa.c new file mode 100644 index 0000000000..de1bcc2a0f --- /dev/null +++ b/src/mesa/drivers/dri/mga/mga_xmesa.c @@ -0,0 +1,616 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c,v 1.19 2003/03/26 20:43:49 tsi Exp $ */ +/* + * Copyright 2000-2001 VA Linux Systems, Inc. + * 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 + * VA LINUX SYSTEMS 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> + */ + +#include <stdio.h> + +#include "mga_common.h" +#include "mga_xmesa.h" +#include "context.h" +#include "matrix.h" +/*#include "mmath.h"*/ +#include "simple_list.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 "mgadd.h" +#include "mgastate.h" +#include "mgatex.h" +#include "mgaspan.h" +#include "mgaioctl.h" +#include "mgatris.h" +#include "mgavb.h" +#include "mgabuffers.h" +#include "mgapixel.h" + +#include "mga_xmesa.h" + +#include "mga_dri.h" + + +#ifndef MGA_DEBUG +int MGA_DEBUG = (0 +/*		 | DEBUG_ALWAYS_SYNC */ +/*		 | DEBUG_VERBOSE_MSG */ +/*		 | DEBUG_VERBOSE_LRU */ +/*		 | DEBUG_VERBOSE_DRI */ +/*		 | DEBUG_VERBOSE_IOCTL */ +/*		 | DEBUG_VERBOSE_2D */ +/*		 | DEBUG_VERBOSE_FALLBACK */ +   ); +#endif + + +static GLboolean +mgaInitDriver(__DRIscreenPrivate *sPriv) +{ +   mgaScreenPrivate *mgaScreen; +   MGADRIPtr         serverInfo = (MGADRIPtr)sPriv->pDevPriv; + +   if (MGA_DEBUG&DEBUG_VERBOSE_DRI) +      fprintf(stderr, "mgaInitDriver\n"); + +   /* Check that the DRM driver version is compatible */ +   if (sPriv->drmMajor != 3 || +       sPriv->drmMinor < 0) { +      __driUtilMessage("MGA DRI driver expected DRM driver version 3.0.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch); +      return GL_FALSE; +   } + + +   /* Allocate the private area */ +   mgaScreen = (mgaScreenPrivate *)MALLOC(sizeof(mgaScreenPrivate)); +   if (!mgaScreen) { +      __driUtilMessage("Couldn't malloc screen struct"); +      return GL_FALSE; +   } + +   mgaScreen->sPriv = sPriv; +   sPriv->private = (void *)mgaScreen; + +   if (sPriv->drmMinor >= 1) { +      int ret; +      drmMGAGetParam gp; + +      gp.param = MGA_PARAM_IRQ_NR; +      gp.value = (int *) &mgaScreen->irq; + +      ret = drmCommandWriteRead( sPriv->fd, DRM_MGA_GETPARAM, +				    &gp, sizeof(gp)); +      if (ret) { +	    fprintf(stderr, "drmMgaGetParam (MGA_PARAM_IRQ_NR): %d\n", ret); +	    FREE(mgaScreen); +	    sPriv->private = NULL; +	    return GL_FALSE; +      } +   } +    +   if (serverInfo->chipset != MGA_CARD_TYPE_G200 && +       serverInfo->chipset != MGA_CARD_TYPE_G400) { +      FREE(mgaScreen); +      sPriv->private = NULL; +      __driUtilMessage("Unrecognized chipset"); +      return GL_FALSE; +   } + + +   mgaScreen->chipset = serverInfo->chipset; +   mgaScreen->width = serverInfo->width; +   mgaScreen->height = serverInfo->height; +   mgaScreen->mem = serverInfo->mem; +   mgaScreen->cpp = serverInfo->cpp; + +   mgaScreen->agpMode = serverInfo->agpMode; + +   mgaScreen->frontPitch = serverInfo->frontPitch; +   mgaScreen->frontOffset = serverInfo->frontOffset; +   mgaScreen->backOffset = serverInfo->backOffset; +   mgaScreen->backPitch  =  serverInfo->backPitch; +   mgaScreen->depthOffset = serverInfo->depthOffset; +   mgaScreen->depthPitch  =  serverInfo->depthPitch; + +   mgaScreen->mmio.handle = serverInfo->registers.handle; +   mgaScreen->mmio.size = serverInfo->registers.size; +   if ( drmMap( sPriv->fd, +		mgaScreen->mmio.handle, mgaScreen->mmio.size, +		&mgaScreen->mmio.map ) < 0 ) { +      FREE( mgaScreen ); +      sPriv->private = NULL; +      __driUtilMessage( "Couldn't map MMIO registers" ); +      return GL_FALSE; +   } + +   mgaScreen->primary.handle = serverInfo->primary.handle; +   mgaScreen->primary.size = serverInfo->primary.size; +   mgaScreen->buffers.handle = serverInfo->buffers.handle; +   mgaScreen->buffers.size = serverInfo->buffers.size; + +#if 0 +   mgaScreen->agp.handle = serverInfo->agp; +   mgaScreen->agp.size = serverInfo->agpSize; + +   if (drmMap(sPriv->fd, +	      mgaScreen->agp.handle, +	      mgaScreen->agp.size, +	      (drmAddress *)&mgaScreen->agp.map) != 0) +   { +      Xfree(mgaScreen); +      sPriv->private = NULL; +      __driUtilMessage("Couldn't map agp region"); +      return GL_FALSE; +   } +#endif + +   mgaScreen->textureOffset[MGA_CARD_HEAP] = serverInfo->textureOffset; +   mgaScreen->textureOffset[MGA_AGP_HEAP] = (serverInfo->agpTextureOffset | +					     PDEA_pagpxfer_enable | 1); + +   mgaScreen->textureSize[MGA_CARD_HEAP] = serverInfo->textureSize; +   mgaScreen->textureSize[MGA_AGP_HEAP] = serverInfo->agpTextureSize; + +   mgaScreen->logTextureGranularity[MGA_CARD_HEAP] = +      serverInfo->logTextureGranularity; +   mgaScreen->logTextureGranularity[MGA_AGP_HEAP] = +      serverInfo->logAgpTextureGranularity; + +   mgaScreen->texVirtual[MGA_CARD_HEAP] = (char *)(mgaScreen->sPriv->pFB + +					   serverInfo->textureOffset); +   if (drmMap(sPriv->fd, +              serverInfo->agpTextureOffset, +              serverInfo->agpTextureSize, +              (drmAddress *)&mgaScreen->texVirtual[MGA_AGP_HEAP]) != 0) +   { +      free(mgaScreen); +      sPriv->private = NULL; +      __driUtilMessage("Couldn't map agptexture region"); +      return GL_FALSE; +   } + +#if 0 +   mgaScreen->texVirtual[MGA_AGP_HEAP] = (mgaScreen->agp.map + +					  serverInfo->agpTextureOffset); +#endif + +   mgaScreen->mAccess = serverInfo->mAccess; + +   /* For calculating setupdma addresses. +    */ +   mgaScreen->dmaOffset = serverInfo->buffers.handle; + +   mgaScreen->bufs = drmMapBufs(sPriv->fd); +   if (!mgaScreen->bufs) { +      /*drmUnmap(mgaScreen->agp_tex.map, mgaScreen->agp_tex.size);*/ +      FREE(mgaScreen); +      sPriv->private = NULL; +      __driUtilMessage("Couldn't map dma buffers"); +      return GL_FALSE; +   } +   mgaScreen->sarea_priv_offset = serverInfo->sarea_priv_offset; + +   return GL_TRUE; +} + + +static void +mgaDestroyScreen(__DRIscreenPrivate *sPriv) +{ +   mgaScreenPrivate *mgaScreen = (mgaScreenPrivate *) sPriv->private; + +   if (MGA_DEBUG&DEBUG_VERBOSE_DRI) +      fprintf(stderr, "mgaDestroyScreen\n"); + +   /*drmUnmap(mgaScreen->agp_tex.map, mgaScreen->agp_tex.size);*/ +   free(mgaScreen); +   sPriv->private = NULL; +} + + +extern const struct gl_pipeline_stage _mga_render_stage; + +static const struct gl_pipeline_stage *mga_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 0 +   &_mga_render_stage,		/* ADD: unclipped rastersetup-to-dma */ +                                /* Need new ioctl for wacceptseq */ +#endif +   &_tnl_render_stage,		 +   0, +}; + + +static GLboolean +mgaCreateContext( const __GLcontextModes *mesaVis, +                  __DRIcontextPrivate *driContextPriv, +                  void *sharedContextPrivate ) +{ +   int i; +   GLcontext *ctx, *shareCtx; +   mgaContextPtr mmesa; +   __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; +   mgaScreenPrivate *mgaScreen = (mgaScreenPrivate *)sPriv->private; +   MGASAREAPrivPtr saPriv=(MGASAREAPrivPtr)(((char*)sPriv->pSAREA)+ +					      mgaScreen->sarea_priv_offset); + +   if (MGA_DEBUG&DEBUG_VERBOSE_DRI) +      fprintf(stderr, "mgaCreateContext\n"); + +   /* allocate mga context */ +   mmesa = (mgaContextPtr) CALLOC(sizeof(mgaContext)); +   if (!mmesa) { +      return GL_FALSE; +   } + +   /* Allocate the Mesa context */ +   if (sharedContextPrivate) +      shareCtx = ((mgaContextPtr) sharedContextPrivate)->glCtx; +   else  +      shareCtx = NULL; +   mmesa->glCtx = _mesa_create_context(mesaVis, shareCtx, mmesa, GL_TRUE); +   if (!mmesa->glCtx) { +      FREE(mmesa); +      return GL_FALSE; +   } +   driContextPriv->driverPrivate = mmesa; + +   /* Init mga state */ +   mmesa->hHWContext = driContextPriv->hHWContext; +   mmesa->driFd = sPriv->fd; +   mmesa->driHwLock = &sPriv->pSAREA->lock; + +   mmesa->mgaScreen = mgaScreen; +   mmesa->driScreen = sPriv; +   mmesa->sarea = (void *)saPriv; +   mmesa->glBuffer = NULL; + +   make_empty_list(&mmesa->SwappedOut); + +   mmesa->lastTexHeap = mgaScreen->texVirtual[MGA_AGP_HEAP] ? 2 : 1; + +   for (i = 0 ; i < mmesa->lastTexHeap ; i++) { +      mmesa->texHeap[i] = mmInit( 0, mgaScreen->textureSize[i]); +      make_empty_list(&mmesa->TexObjList[i]); +   } + +   /* Set the maximum texture size small enough that we can guarentee +    * that both texture units can bind a maximal texture and have them +    * on the card at once. +    */ +   ctx = mmesa->glCtx; +   {  +      int nr = 2; + +      if (mgaScreen->chipset == MGA_CARD_TYPE_G200) +	 nr = 1; + +      if (mgaScreen->textureSize[0] < nr*1024*1024) { +	 ctx->Const.MaxTextureLevels = 9; +      } else if (mgaScreen->textureSize[0] < nr*4*1024*1024) { +	 ctx->Const.MaxTextureLevels = 10; +      } else { +	 ctx->Const.MaxTextureLevels = 11; +      } + +      ctx->Const.MaxTextureUnits = nr; +   } + +   ctx->Const.MinLineWidth = 1.0; +   ctx->Const.MinLineWidthAA = 1.0; +   ctx->Const.MaxLineWidth = 10.0; +   ctx->Const.MaxLineWidthAA = 10.0; +   ctx->Const.LineWidthGranularity = 1.0; + +   mmesa->hw_stencil = mesaVis->stencilBits && mesaVis->depthBits == 24; + +   switch (mesaVis->depthBits) { +   case 16:  +      mmesa->depth_scale = 1.0/(GLdouble)0xffff;  +      mmesa->depth_clear_mask = ~0; +      mmesa->ClearDepth = 0xffff; +      break; +   case 24: +      mmesa->depth_scale = 1.0/(GLdouble)0xffffff; +      if (mmesa->hw_stencil) { +	 mmesa->depth_clear_mask = 0xffffff00; +	 mmesa->stencil_clear_mask = 0x000000ff; +      } else +	 mmesa->depth_clear_mask = ~0; +      mmesa->ClearDepth = 0xffffff00; +      break; +   case 32: +      mmesa->depth_scale = 1.0/(GLdouble)0xffffffff; +      mmesa->depth_clear_mask = ~0; +      mmesa->ClearDepth = 0xffffffff; +      break; +   }; + +   mmesa->haveHwStipple = GL_FALSE; +   mmesa->RenderIndex = -1;		/* impossible value */ +   mmesa->new_state = ~0; +   mmesa->dirty = ~0; +   mmesa->vertex_format = 0;    +   mmesa->CurrentTexObj[0] = 0; +   mmesa->CurrentTexObj[1] = 0; +   mmesa->tmu_source[0] = 0; +   mmesa->tmu_source[1] = 1; + +   mmesa->texAge[0] = 0; +   mmesa->texAge[1] = 0; +    +   /* 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, mga_pipeline ); + +   /* Configure swrast to match hardware characteristics: +    */ +   _swrast_allow_pixel_fog( ctx, GL_FALSE ); +   _swrast_allow_vertex_fog( ctx, GL_TRUE ); + +   mmesa->primary_offset = mmesa->mgaScreen->primary.handle; + +   ctx->DriverCtx = (void *) mmesa; +   mmesa->glCtx = ctx; + +   mgaDDExtensionsInit( ctx ); + +   mgaDDInitStateFuncs( ctx ); +   mgaDDInitTextureFuncs( ctx ); +   mgaDDInitSpanFuncs( ctx ); +   mgaDDInitDriverFuncs( ctx ); +   mgaDDInitIoctlFuncs( ctx ); +   mgaDDInitPixelFuncs( ctx ); +   mgaDDInitTriFuncs( ctx ); + +   mgaInitVB( ctx ); +   mgaInitState( mmesa ); + +   driContextPriv->driverPrivate = (void *) mmesa; + +   return GL_TRUE; +} + +static void +mgaDestroyContext(__DRIcontextPrivate *driContextPriv) +{ +   mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate; + +   if (MGA_DEBUG&DEBUG_VERBOSE_DRI) +      fprintf(stderr, "mgaDestroyContext\n"); + +   assert(mmesa); /* should never be null */ +   if (mmesa) { +      _swsetup_DestroyContext( mmesa->glCtx ); +      _tnl_DestroyContext( mmesa->glCtx ); +      _ac_DestroyContext( mmesa->glCtx ); +      _swrast_DestroyContext( mmesa->glCtx ); + +      mgaFreeVB( mmesa->glCtx ); + +      /* free the Mesa context */ +      mmesa->glCtx->DriverCtx = NULL; +      _mesa_destroy_context(mmesa->glCtx); +      /* free the mga context */ +      FREE(mmesa); +   } +} + + +static GLboolean +mgaCreateBuffer( __DRIscreenPrivate *driScrnPriv, +                 __DRIdrawablePrivate *driDrawPriv, +                 const __GLcontextModes *mesaVis, +                 GLboolean isPixmap ) +{ +   if (isPixmap) { +      return GL_FALSE; /* not implemented */ +   } +   else { +      GLboolean swStencil = (mesaVis->stencilBits > 0 &&  +			     mesaVis->depthBits != 24); + +      driDrawPriv->driverPrivate = (void *)  +         _mesa_create_framebuffer(mesaVis, +                                  GL_FALSE,  /* software depth buffer? */ +                                  swStencil, +                                  mesaVis->accumRedBits > 0, +                                  mesaVis->alphaBits > 0 ); + +      return (driDrawPriv->driverPrivate != NULL); +   } +} + + +static void +mgaDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) +{ +   _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); +} + + +static GLboolean +mgaUnbindContext(__DRIcontextPrivate *driContextPriv) +{ +   mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate; +   if (mmesa) +      mmesa->dirty = ~0; + +   return GL_TRUE; +} + +static GLboolean +mgaOpenFullScreen(__DRIcontextPrivate *driContextPriv) +{ +    return GL_TRUE; +} + +static GLboolean +mgaCloseFullScreen(__DRIcontextPrivate *driContextPriv) +{ +    return GL_TRUE; +} + + +/* This looks buggy to me - the 'b' variable isn't used anywhere... + * Hmm - It seems that the drawable is already hooked in to + * driDrawablePriv. + * + * But why are we doing context initialization here??? + */ +static GLboolean +mgaMakeCurrent(__DRIcontextPrivate *driContextPriv, +               __DRIdrawablePrivate *driDrawPriv, +               __DRIdrawablePrivate *driReadPriv) +{ +   fprintf(stderr, "%s\n", __FUNCTION__); + +   if (driContextPriv) { +      mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate; + +      if (mmesa->driDrawable != driDrawPriv) { +	 mmesa->driDrawable = driDrawPriv; +	 mmesa->dirty = ~0;  +	 mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK);  +      } + +      _mesa_make_current2(mmesa->glCtx, +                          (GLframebuffer *) driDrawPriv->driverPrivate, +                          (GLframebuffer *) driReadPriv->driverPrivate); + +      if (!mmesa->glCtx->Viewport.Width) +	 _mesa_set_viewport(mmesa->glCtx, 0, 0, +                            driDrawPriv->w, driDrawPriv->h); + +   } +   else { +      _mesa_make_current(NULL, NULL); +   } + +   return GL_TRUE; +} + +void mgaGetLock( mgaContextPtr mmesa, GLuint flags ) +{ +   __DRIdrawablePrivate *dPriv = mmesa->driDrawable; +   MGASAREAPrivPtr sarea = mmesa->sarea; +   int me = mmesa->hHWContext; +   int i; + +   fprintf(stderr, "%s\n", __FUNCTION__); + +   drmGetLock(mmesa->driFd, mmesa->hHWContext, flags); +    +   fprintf(stderr,  +	   "mmesa->lastStamp %d dpriv->lastStamp %d *(dpriv->pStamp) %d\n", +	   mmesa->lastStamp,  +	   dPriv->lastStamp, +	   *(dPriv->pStamp)); +    +   /* The window might have moved, so we might need to get new clip +    * rects. +    * +    * NOTE: This releases and regrabs the hw lock to allow the X server +    * to respond to the DRI protocol request for new drawable info. +    * Since the hardware state depends on having the latest drawable +    * clip rects, all state checking must be done _after_ this call. +    */ +   DRI_VALIDATE_DRAWABLE_INFO( sPriv, dPriv ); + +   if ( mmesa->lastStamp == 0 || +	mmesa->lastStamp != dPriv->lastStamp ) { +      mmesa->lastStamp = dPriv->lastStamp; +      mmesa->SetupNewInputs |= VERT_BIT_CLIP; +      mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK); +      mgaUpdateRects( mmesa, (MGA_FRONT|MGA_BACK) ); +   } + +   mmesa->dirty |= MGA_UPLOAD_CONTEXT | MGA_UPLOAD_CLIPRECTS; + +   mmesa->sarea->dirty |= MGA_UPLOAD_CONTEXT; + +   if (sarea->ctxOwner != me) { +      mmesa->dirty |= (MGA_UPLOAD_CONTEXT | MGA_UPLOAD_TEX0 | +		       MGA_UPLOAD_TEX1 | MGA_UPLOAD_PIPE); +      sarea->ctxOwner=me; +   } + +   for (i = 0 ; i < mmesa->lastTexHeap ; i++) +      if (sarea->texAge[i] != mmesa->texAge[i]) +	 mgaAgeTextures( mmesa, i ); + +   sarea->last_quiescent = -1;	/* just kill it for now */ +} + + + +static const struct __DriverAPIRec mgaAPI = { +   mgaInitDriver, +   mgaDestroyScreen, +   mgaCreateContext, +   mgaDestroyContext, +   mgaCreateBuffer, +   mgaDestroyBuffer, +   mgaSwapBuffers, +   mgaMakeCurrent, +   mgaUnbindContext, +   mgaOpenFullScreen, +   mgaCloseFullScreen +}; + + + +/* + * 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(struct DRIDriverRec *driver, +                        struct DRIDriverContextRec *driverContext) +{ +   __DRIscreenPrivate *psp; +   psp = __driUtilCreateScreen(driver, driverContext, &mgaAPI); +   return (void *) psp; +} diff --git a/src/mesa/drivers/dri/mga/mga_xmesa.h b/src/mesa/drivers/dri/mga/mga_xmesa.h new file mode 100644 index 0000000000..eda996f5a4 --- /dev/null +++ b/src/mesa/drivers/dri/mga/mga_xmesa.h @@ -0,0 +1,143 @@ +/* + * Copyright 2000-2001 VA Linux Systems, Inc. + * 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 + * VA LINUX SYSTEMS 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> + */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h,v 1.12 2002/12/16 16:18:52 dawes Exp $ */ + +#ifndef _MGA_INIT_H_ +#define _MGA_INIT_H_ + +#include <sys/time.h> +#include <linux/types.h> +#include "dri_util.h" +#include "mtypes.h" +#include "mgaregs.h" +#include "mga_common.h" + +typedef struct mga_screen_private_s { + +   int chipset; +   int width; +   int height; +   int mem; + +   int cpp;			/* for front and back buffers */ +   GLint agpMode; +   unsigned int irq;		/* IRQ number (0 means none) */ + +   unsigned int mAccess; + +   unsigned int frontOffset; +   unsigned int frontPitch; +   unsigned int backOffset; +   unsigned int backPitch; + +   unsigned int depthOffset; +   unsigned int depthPitch; +   int depthCpp; + +   unsigned int dmaOffset; + +   unsigned int textureOffset[DRM_MGA_NR_TEX_HEAPS]; +   unsigned int textureSize[DRM_MGA_NR_TEX_HEAPS]; +   int logTextureGranularity[DRM_MGA_NR_TEX_HEAPS]; +   char *texVirtual[DRM_MGA_NR_TEX_HEAPS]; + + +   __DRIscreenPrivate *sPriv; +   drmBufMapPtr  bufs; + +   drmRegion mmio; +   drmRegion status; +   drmRegion primary; +   drmRegion buffers; +   unsigned int sarea_priv_offset; +} mgaScreenPrivate; + + +#include "mgacontext.h" + +extern void mgaGetLock( mgaContextPtr mmesa, GLuint flags ); +extern void mgaEmitHwStateLocked( mgaContextPtr mmesa ); +extern void mgaEmitScissorValues( mgaContextPtr mmesa, int box_nr, int emit ); + +#define GET_DISPATCH_AGE( mmesa ) mmesa->sarea->last_dispatch +#define GET_ENQUEUE_AGE( mmesa ) mmesa->sarea->last_enqueue + + + +/* Lock the hardware and validate our state. + */ +#define LOCK_HARDWARE( mmesa )					\ +  do {								\ +    char __ret=0;						\ +    DRM_CAS(mmesa->driHwLock, mmesa->hHWContext,		\ +	    (DRM_LOCK_HELD|mmesa->hHWContext), __ret);		\ +    if (__ret)							\ +        mgaGetLock( mmesa, 0 );					\ +  } while (0) + + +/* + */ +#define LOCK_HARDWARE_QUIESCENT( mmesa ) do {	                        \ +	LOCK_HARDWARE( mmesa );			                        \ +	UPDATE_LOCK( mmesa, DRM_LOCK_QUIESCENT | DRM_LOCK_FLUSH );	\ +} while (0) + + +/* Unlock the hardware using the global current context + */ +#define UNLOCK_HARDWARE(mmesa) 				\ +    DRM_UNLOCK(mmesa->driFd, mmesa->driHwLock, mmesa->hHWContext); + + +/* Freshen our snapshot of the drawables + */ +#define REFRESH_DRAWABLE_INFO( mmesa )		\ +do {						\ +   LOCK_HARDWARE( mmesa );			\ +   mmesa->lastX = mmesa->drawX; 		\ +   mmesa->lastY = mmesa->drawY; 		\ +   UNLOCK_HARDWARE( mmesa );			\ +} while (0) + + +#define GET_DRAWABLE_LOCK( mmesa ) while(0) +#define RELEASE_DRAWABLE_LOCK( mmesa ) while(0) + + +/* The 2D driver macros are busted -- we can't use them here as they + * rely on the 2D driver data structures rather than taking an explicit + * base address. + */ +#define MGA_BASE( reg )		((unsigned long)(mmesa->mgaScreen->mmio.map)) +#define MGA_ADDR( reg )		(MGA_BASE(reg) + reg) + +#define MGA_DEREF( reg )	*(volatile __u32 *)MGA_ADDR( reg ) +#define MGA_READ( reg )		MGA_DEREF( reg ) +#define MGA_WRITE( reg, val )	do { MGA_DEREF( reg ) = val; } while (0) + +#endif diff --git a/src/mesa/drivers/dri/mga/mgabuffers.c b/src/mesa/drivers/dri/mga/mgabuffers.c new file mode 100644 index 0000000000..19833566a0 --- /dev/null +++ b/src/mesa/drivers/dri/mga/mgabuffers.c @@ -0,0 +1,291 @@ +/* + * Copyright 2000-2001 VA Linux Systems, Inc. + * 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 + * VA LINUX SYSTEMS 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> + */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgabuffers.c,v 1.13 2002/11/05 17:46:08 tsi Exp $ */ + +#include <stdio.h> +#include "mgacontext.h" +#include "mgabuffers.h" +#include "mgastate.h" +#include "mgaioctl.h" +#include "mgatris.h" + +static void mgaXMesaSetFrontClipRects( mgaContextPtr mmesa ) +{ +   __DRIdrawablePrivate *driDrawable = mmesa->driDrawable; + +/*   fprintf( stderr, "%s\n", __FUNCTION__ );*/ + +   if (driDrawable->numClipRects == 0) { +       static XF86DRIClipRectRec zeroareacliprect = {0,0,0,0}; +       mmesa->numClipRects = 1; +       mmesa->pClipRects = &zeroareacliprect; +   } else { +       mmesa->numClipRects = driDrawable->numClipRects; +       mmesa->pClipRects = driDrawable->pClipRects; +   } +   mmesa->drawX = driDrawable->x; +   mmesa->drawY = driDrawable->y; + +   mmesa->setup.dstorg = mmesa->drawOffset; +   mmesa->dirty |= MGA_UPLOAD_CONTEXT | MGA_UPLOAD_CLIPRECTS; +} + + +static void mgaXMesaSetBackClipRects( mgaContextPtr mmesa ) +{ +   __DRIdrawablePrivate *driDrawable = mmesa->driDrawable; + +/*   fprintf( stderr, "%s\n", __FUNCTION__ );*/ + +   if (driDrawable->numBackClipRects == 0) +   { +      if (driDrawable->numClipRects == 0) { +	  static XF86DRIClipRectRec zeroareacliprect = {0,0,0,0}; +	  mmesa->numClipRects = 1; +	  mmesa->pClipRects = &zeroareacliprect; +      } else { +	  mmesa->numClipRects = driDrawable->numClipRects; +	  mmesa->pClipRects = driDrawable->pClipRects; +      } +      mmesa->drawX = driDrawable->x; +      mmesa->drawY = driDrawable->y; +   } else { +      mmesa->numClipRects = driDrawable->numBackClipRects; +      mmesa->pClipRects = driDrawable->pBackClipRects; +      mmesa->drawX = driDrawable->backX; +      mmesa->drawY = driDrawable->backY; +   } + +   mmesa->setup.dstorg = mmesa->drawOffset; +   mmesa->dirty |= MGA_UPLOAD_CONTEXT | MGA_UPLOAD_CLIPRECTS; +} + + + +#if 0 +static void mgaUpdateRectsFromSarea( mgaContextPtr mmesa ) +{ +   __DRIdrawablePrivate *driDrawable = mmesa->driDrawable; +   __DRIscreenPrivate *driScreen = mmesa->driScreen; +   MGASAREAPrivPtr sarea = mmesa->sarea; +   int i = 0, top = 0; + + +   if (sarea->exported_buffers & MGA_BACK) { + +      driDrawable->numBackClipRects = sarea->exported_nback; +      driDrawable->pBackClipRects = mmesa->tmp_boxes[0]; + +      top = sarea->exported_nback; +      for (i = 0 ; i < top ; i++) +	 driDrawable->pBackClipRects[i] = +	    *(XF86DRIClipRectPtr)&(sarea->exported_boxes[i]); +   } + + +   if (sarea->exported_buffers & MGA_FRONT) +   { +      int start = top; + +      driDrawable->numClipRects = sarea->exported_nfront; +      driDrawable->pClipRects = mmesa->tmp_boxes[1]; + +      top += sarea->exported_nfront; +      for ( ; i < top ; i++) +	 driDrawable->pClipRects[i-start] = +	    *(XF86DRIClipRectPtr)&(sarea->exported_boxes[i]); + +   } + + + +   driDrawable->index = sarea->exported_index; +   driDrawable->lastStamp = sarea->exported_stamp; +   driDrawable->x = sarea->exported_front_x; +   driDrawable->y = sarea->exported_front_y; +   driDrawable->backX = sarea->exported_back_x; +   driDrawable->backY = sarea->exported_back_y; +   driDrawable->w = sarea->exported_w; +   driDrawable->h = sarea->exported_h; +   driDrawable->pStamp = +      &(driScreen->pSAREA->drawableTable[driDrawable->index].stamp); + +   mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK) & ~(sarea->exported_buffers); +} +#endif + +#if 0 +static void printSareaRects( mgaContextPtr mmesa ) +{ +   __DRIscreenPrivate *driScreen = mmesa->driScreen; +   MGASAREAPrivPtr sarea = mmesa->sarea; +   int i; + +   fprintf(stderr, "sarea->exported: %d\n", sarea->exported_drawable); +   fprintf(stderr, "sarea->exported_index: %d\n", sarea->exported_index); +   fprintf(stderr, "sarea->exported_stamp: %d\n", sarea->exported_stamp); +   fprintf(stderr, "sarea->exported_front_x: %d\n", sarea->exported_front_x); +   fprintf(stderr, "sarea->exported_front_y: %d\n", sarea->exported_front_y); +   fprintf(stderr, "sarea->exported_back_x: %d\n", sarea->exported_back_x); +   fprintf(stderr, "sarea->exported_back_y: %d\n", sarea->exported_back_y); +   fprintf(stderr, "sarea->exported_w: %d\n", sarea->exported_w); +   fprintf(stderr, "sarea->exported_h: %d\n", sarea->exported_h); +   fprintf(stderr, "sarea->exported_buffers: %d\n", sarea->exported_buffers); +   fprintf(stderr, "sarea->exported_nfront: %d\n", sarea->exported_nfront); +   fprintf(stderr, "sarea->exported_nback: %d\n", sarea->exported_nback); + +   i = 0; +   if (sarea->exported_buffers & MGA_BACK) +      for ( ; i < sarea->exported_nback ; i++) +	 fprintf(stderr, "back %d: %d,%d-%d,%d\n", i, +		 sarea->exported_boxes[i].x1, sarea->exported_boxes[i].y1, +		 sarea->exported_boxes[i].x2, sarea->exported_boxes[i].y2); + +   if (sarea->exported_buffers & MGA_FRONT) { +      int start = i; +      int top = i + sarea->exported_nfront; +      for ( ; i < top ; i++) +	 fprintf(stderr, "front %d: %d,%d-%d,%d\n", +		 i - start, +		 sarea->exported_boxes[i].x1, sarea->exported_boxes[i].y1, +		 sarea->exported_boxes[i].x2, sarea->exported_boxes[i].y2); +   } + +   fprintf(stderr, "drawableTable[%d].stamp: %d\n", +	   sarea->exported_index, +	   driScreen->pSAREA->drawableTable[sarea->exported_index].stamp); +} + +static void printMmesaRects( mgaContextPtr mmesa ) +{ +   __DRIscreenPrivate *driScreen = mmesa->driScreen; +   __DRIdrawablePrivate *driDrawable = mmesa->driDrawable; +   int nr = mmesa->numClipRects; +   int i; + +   fprintf(stderr, "driDrawable->draw: %ld\n", driDrawable->draw); +   fprintf(stderr, "driDrawable->index: %d\n", driDrawable->index); +   fprintf(stderr, "driDrawable->lastStamp: %d\n", driDrawable->lastStamp); +   fprintf(stderr, "mmesa->drawX: %d\n", mmesa->drawX); +   fprintf(stderr, "mmesa->drawY: %d\n", mmesa->drawY); +   fprintf(stderr, "driDrawable->w: %d\n", driDrawable->w); +   fprintf(stderr, "driDrawable->h: %d\n", driDrawable->h); + +   for (i = 0 ; i < nr ; i++) +      fprintf(stderr, "box %d: %d,%d-%d,%d\n", i, +	      mmesa->pClipRects[i].x1, mmesa->pClipRects[i].y1, +	      mmesa->pClipRects[i].x2, mmesa->pClipRects[i].y2); + +   fprintf(stderr, "mmesa->draw_buffer: %d\n", mmesa->draw_buffer); +   fprintf(stderr, "drawableTable[%d].stamp: %d\n", +	   driDrawable->index, +	   driScreen->pSAREA->drawableTable[driDrawable->index].stamp); +} +#endif + + + +void mgaUpdateRects( mgaContextPtr mmesa, GLuint buffers ) +{ +   __DRIdrawablePrivate *driDrawable = mmesa->driDrawable; +   MGASAREAPrivPtr sarea = mmesa->sarea; + +/*   fprintf(stderr, "%s\n", __FUNCTION__);*/ + +   DRI_VALIDATE_DRAWABLE_INFO(driScreen, driDrawable);  +   mmesa->dirty_cliprects = 0;	 + +   if (mmesa->draw_buffer == MGA_FRONT) +      mgaXMesaSetFrontClipRects( mmesa ); +   else +      mgaXMesaSetBackClipRects( mmesa ); + +#if 0 +   printMmesaRects(mmesa);  +#endif + +   sarea->req_draw_buffer = mmesa->draw_buffer; + +   mgaUpdateClipping( mmesa->glCtx ); +   mgaCalcViewport( mmesa->glCtx ); + +   mmesa->dirty |= MGA_UPLOAD_CLIPRECTS; +} + + +void mgaDDSetReadBuffer(GLcontext *ctx, GLenum mode ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); + +   if (mode == GL_FRONT_LEFT)  +   { +      mmesa->readOffset = mmesa->mgaScreen->frontOffset; +      mmesa->read_buffer = MGA_FRONT; +   }  +   else  +   { +      mmesa->readOffset = mmesa->mgaScreen->backOffset; +      mmesa->read_buffer = MGA_BACK; +   } +} + +void mgaDDSetDrawBuffer(GLcontext *ctx, GLenum mode ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); + +   FLUSH_BATCH( MGA_CONTEXT(ctx) ); + +/*   fprintf( stderr, "%s %d\n", __FUNCTION__, mode);*/ + +   /* +    * _DrawDestMask is easier to cope with than <mode>. +    */ +   switch ( ctx->Color._DrawDestMask ) { +     case FRONT_LEFT_BIT: +       mmesa->drawOffset = mmesa->mgaScreen->frontOffset; +       mmesa->readOffset = mmesa->mgaScreen->frontOffset; +       mmesa->setup.dstorg = mmesa->mgaScreen->frontOffset; +       mmesa->dirty |= MGA_UPLOAD_CONTEXT; +       mmesa->draw_buffer = MGA_FRONT; +       mgaXMesaSetFrontClipRects( mmesa ); +       FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_FALSE ); +       break; +     case BACK_LEFT_BIT: +       mmesa->drawOffset = mmesa->mgaScreen->backOffset; +       mmesa->readOffset = mmesa->mgaScreen->backOffset; +       mmesa->setup.dstorg = mmesa->mgaScreen->backOffset; +       mmesa->draw_buffer = MGA_BACK; +       mmesa->dirty |= MGA_UPLOAD_CONTEXT; +       mgaXMesaSetBackClipRects( mmesa ); +       FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_FALSE ); +       break; +     default: +       FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_TRUE ); +       break; +   } +} + diff --git a/src/mesa/drivers/dri/mga/mgabuffers.h b/src/mesa/drivers/dri/mga/mgabuffers.h new file mode 100644 index 0000000000..2307f13c0a --- /dev/null +++ b/src/mesa/drivers/dri/mga/mgabuffers.h @@ -0,0 +1,37 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgabuffers.h,v 1.7 2002/10/30 12:51:35 alanh Exp $ */ +/* + * Copyright 2000-2001 VA Linux Systems, Inc. + * 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 + * VA LINUX SYSTEMS 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> + */ + +#ifndef MGA_BUFFERS_H +#define MGA_BUFFERS_H + +void mgaDDSetDrawBuffer(GLcontext *ctx, GLenum mode ); +void mgaDDSetReadBuffer(GLcontext *ctx, GLenum mode ); + +void mgaUpdateRects( mgaContextPtr mmesa, GLuint buffers ); + +#endif diff --git a/src/mesa/drivers/dri/mga/mgacontext.h b/src/mesa/drivers/dri/mga/mgacontext.h new file mode 100644 index 0000000000..3065ea9fd1 --- /dev/null +++ b/src/mesa/drivers/dri/mga/mgacontext.h @@ -0,0 +1,309 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgacontext.h,v 1.7 2002/12/16 16:18:52 dawes Exp $*/ +/* + * Copyright 2000-2001 VA Linux Systems, Inc. + * 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 + * VA LINUX SYSTEMS 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> + */ + +#ifndef MGALIB_INC +#define MGALIB_INC + +/*#include <X11/Xlibint.h>*/ +#include "dri_util.h" +#include "mtypes.h" +#include "xf86drm.h" +#include "mm.h" +/*#include "mem.h"*/ +#include "mga_sarea.h" + + +#define MGA_SET_FIELD(reg,mask,val)  reg = ((reg) & (mask)) | ((val) & ~(mask)) +#define MGA_FIELD(field,val) (((val) << (field ## _SHIFT)) & ~(field ## _MASK)) +#define MGA_GET_FIELD(field, val) ((val & ~(field ## _MASK)) >> (field ## _SHIFT)) + +#define MGA_IS_G200(mmesa) (mmesa->mgaScreen->chipset == MGA_CARD_TYPE_G200) +#define MGA_IS_G400(mmesa) (mmesa->mgaScreen->chipset == MGA_CARD_TYPE_G400) + + +/* SoftwareFallback + *    - texture env GL_BLEND -- can be fixed + *    - 1D and 3D textures + *    - incomplete textures + *    - GL_DEPTH_FUNC == GL_NEVER not in h/w + */ +#define MGA_FALLBACK_TEXTURE        0x1 +#define MGA_FALLBACK_DRAW_BUFFER    0x2 +#define MGA_FALLBACK_READ_BUFFER    0x4 +#define MGA_FALLBACK_LOGICOP        0x8 +#define MGA_FALLBACK_RENDERMODE     0x10 +#define MGA_FALLBACK_STENCIL        0x20 +#define MGA_FALLBACK_DEPTH          0x40 + + +/* For mgaCtx->new_state. + */ +#define MGA_NEW_DEPTH   0x1 +#define MGA_NEW_ALPHA   0x2 +#define MGA_NEW_CLIP    0x8 +#define MGA_NEW_TEXTURE 0x20 +#define MGA_NEW_CULL    0x40 +#define MGA_NEW_WARP    0x80 +#define MGA_NEW_STENCIL 0x100 +#define MGA_NEW_CONTEXT 0x200 + +/* Use the templated vertex formats: + */ +#define TAG(x) mga##x +#include "tnl_dd/t_dd_vertex.h" +#undef TAG + +typedef struct mga_context_t mgaContext; +typedef struct mga_context_t *mgaContextPtr; + +typedef void (*mga_tri_func)( mgaContextPtr, mgaVertex *, mgaVertex *, +			       mgaVertex * ); +typedef void (*mga_line_func)( mgaContextPtr, mgaVertex *, mgaVertex * ); +typedef void (*mga_point_func)( mgaContextPtr, mgaVertex * ); + + + +/* Reasons why the GL_BLEND fallback mightn't work: + */ +#define MGA_BLEND_ENV_COLOR 0x1 +#define MGA_BLEND_MULTITEX  0x2 + +struct mga_texture_object_s; +struct mga_screen_private_s; + +#define MGA_TEX_MAXLEVELS 5 + +typedef struct mga_texture_object_s +{ +   struct mga_texture_object_s *next; +   struct mga_texture_object_s *prev; +   struct gl_texture_object *tObj; +   struct mga_context_t *ctx; +   PMemBlock	MemBlock; +   GLuint		offsets[MGA_TEX_MAXLEVELS]; +   int             lastLevel; +   GLuint         dirty_images; +   GLuint		totalSize; +   int		texelBytes; +   GLuint 	age; +   int             bound; +   int             heap;	/* agp or card */ + +   mga_texture_regs_t setup; +} mgaTextureObject_t; + +struct mga_context_t { + +   GLcontext *glCtx; +   unsigned int lastStamp;	/* fullscreen breaks dpriv->laststamp, +				 * need to shadow it here. */ + +   /* Bookkeeping for texturing +    */ +   int lastTexHeap; +   struct mga_texture_object_s TexObjList[MGA_NR_TEX_HEAPS]; +   struct mga_texture_object_s SwappedOut; +   struct mga_texture_object_s *CurrentTexObj[2]; +   memHeap_t *texHeap[MGA_NR_TEX_HEAPS]; +   int c_texupload; +   int c_texusage; +   int tex_thrash; + + +   /* Map GL texture units onto hardware. +    */ +   GLuint tmu_source[2]; +    +   GLboolean default32BitTextures; + +   /* Manage fallbacks +    */ +   GLuint Fallback;   + + +   /* Temporaries for translating away float colors: +    */ +   struct gl_client_array UbyteColor; +   struct gl_client_array UbyteSecondaryColor; + +   /* Support for limited GL_BLEND fallback +    */ +   unsigned int blend_flags; +   unsigned int envcolor; + +   /* Rasterization state  +    */ +   GLuint SetupNewInputs; +   GLuint SetupIndex; +   GLuint RenderIndex; +    +   GLuint hw_primitive; +   GLenum raster_primitive; +   GLenum render_primitive; + +   char *verts; +   GLint vertex_stride_shift; +   GLuint vertex_format;		 +   GLuint vertex_size; + +   /* Fallback rasterization functions  +    */ +   mga_point_func draw_point; +   mga_line_func draw_line; +   mga_tri_func draw_tri; + + +   /* Manage driver and hardware state +    */ +   GLuint        new_gl_state;  +   GLuint        new_state;  +   GLuint        dirty; + +   mga_context_regs_t setup; + +   GLuint        ClearColor; +   GLuint        ClearDepth; +   GLuint        poly_stipple; +   GLfloat       depth_scale; + +   GLuint        depth_clear_mask; +   GLuint        stencil_clear_mask; +   GLuint        hw_stencil; +   GLuint        haveHwStipple; +   GLfloat       hw_viewport[16]; + +   /* Dma buffers +    */ +   drmBufPtr  vertex_dma_buffer; +   drmBufPtr  iload_buffer; + +   /* VBI +    */ +   GLuint vbl_seq; + +   /* Drawable, cliprect and scissor information +    */ +   int dirty_cliprects;		/* which sets of cliprects are uptodate? */ +   int draw_buffer;		/* which buffer are we rendering to */ +   unsigned int drawOffset;		/* draw buffer address in  space */ +   int read_buffer; +   int readOffset; +   int drawX, drawY;		/* origin of drawable in draw buffer */ +   int lastX, lastY;		/* detect DSTORG bug */ +   GLuint numClipRects;		/* cliprects for the draw buffer */ +   XF86DRIClipRectPtr pClipRects; +   XF86DRIClipRectRec draw_rect; +   XF86DRIClipRectRec scissor_rect; +   int scissor; + +   XF86DRIClipRectRec tmp_boxes[2][MGA_NR_SAREA_CLIPRECTS]; + + +   /* Texture aging and DMA based aging. +    */ +   unsigned int texAge[MGA_NR_TEX_HEAPS];/* texture LRU age  */ +   unsigned int dirtyAge;		/* buffer age for synchronization */ + +   GLuint primary_offset; + +   /* Mirrors of some DRI state. +    */ +   GLframebuffer *glBuffer; +   drmContext hHWContext; +   drmLock *driHwLock; +   int driFd; +   __DRIdrawablePrivate *driDrawable; +   __DRIscreenPrivate *driScreen; +   struct mga_screen_private_s *mgaScreen; +   MGASAREAPrivPtr sarea; +}; + +#define MGA_CONTEXT(ctx) ((mgaContextPtr)(ctx->DriverCtx)) + +#define MGAPACKCOLOR555(r,g,b,a) \ +  ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \ +    ((a) ? 0x8000 : 0)) + +#define MGAPACKCOLOR565(r,g,b) \ +  ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3)) + +#define MGAPACKCOLOR88(l, a) \ +  (((l) << 8) | (a)) + +#define MGAPACKCOLOR888(r,g,b) \ +  (((r) << 16) | ((g) << 8) | (b)) + +#define MGAPACKCOLOR8888(r,g,b,a) \ +  (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) + +#define MGAPACKCOLOR4444(r,g,b,a) \ +  ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4)) + + +#define MGA_DEBUG 0 +#ifndef MGA_DEBUG +extern int MGA_DEBUG; +#endif + +#define DEBUG_ALWAYS_SYNC	0x1 +#define DEBUG_VERBOSE_MSG	0x2 +#define DEBUG_VERBOSE_LRU	0x4 +#define DEBUG_VERBOSE_DRI	0x8 +#define DEBUG_VERBOSE_IOCTL	0x10 +#define DEBUG_VERBOSE_2D	0x20 +#define DEBUG_VERBOSE_FALLBACK	0x40 + +static __inline__ GLuint mgaPackColor(GLuint cpp, +				      GLubyte r, GLubyte g, +				      GLubyte b, GLubyte a) +{ +  switch (cpp) { +  case 2: +    return MGAPACKCOLOR565(r,g,b); +  case 4: +    return MGAPACKCOLOR8888(r,g,b,a); +  default: +    return 0; +  } +} + + +/* + * Subpixel offsets for window coordinates: + */ +#define SUBPIXEL_X (-0.5F) +#define SUBPIXEL_Y (-0.5F + 0.125) + + +#define MGA_WA_TRIANGLES     0x18000000 +#define MGA_WA_TRISTRIP_T0   0x02010200 +#define MGA_WA_TRIFAN_T0     0x01000408 +#define MGA_WA_TRISTRIP_T0T1 0x02010400 +#define MGA_WA_TRIFAN_T0T1   0x01000810 + +#endif diff --git a/src/mesa/drivers/dri/mga/mgadd.c b/src/mesa/drivers/dri/mga/mgadd.c new file mode 100644 index 0000000000..6ce50e6726 --- /dev/null +++ b/src/mesa/drivers/dri/mga/mgadd.c @@ -0,0 +1,171 @@ +/* + * Copyright 2000-2001 VA Linux Systems, Inc. + * 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 + * VA LINUX SYSTEMS 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> + */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgadd.c,v 1.14 2002/10/30 12:51:35 alanh Exp $ */ + + +#include "mtypes.h" + + +#include <stdio.h> +#include <stdlib.h> + +#include "mm.h" +#include "mgacontext.h" +#include "mgadd.h" +#include "mgastate.h" +#include "mgaspan.h" +#include "mgatex.h" +#include "mgatris.h" +#include "mgavb.h" +#include "mga_xmesa.h" +#include "extensions.h" +#if defined(USE_X86_ASM) +#include "X86/common_x86_asm.h" +#endif + +#define MGA_DATE	"20020221" + + +/*************************************** + * Mesa's Driver Functions + ***************************************/ + + +static const GLubyte *mgaDDGetString( GLcontext *ctx, GLenum name ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT( ctx ); +   static char buffer[128]; + +   switch ( name ) { +   case GL_VENDOR: +      return (GLubyte *) "VA Linux Systems Inc."; + +   case GL_RENDERER: +      sprintf( buffer, "Mesa DRI %s " MGA_DATE, +	       MGA_IS_G400(mmesa) ? "G400" : +	       MGA_IS_G200(mmesa) ? "G200" : "MGA" ); + +      /* Append any AGP-specific information. +       */ +      switch ( mmesa->mgaScreen->agpMode ) { +      case 1: +	 strncat( buffer, " AGP 1x", 7 ); +	 break; +      case 2: +	 strncat( buffer, " AGP 2x", 7 ); +	 break; +      case 4: +	 strncat( buffer, " AGP 4x", 7 ); +	 break; +      } + +      /* Append any CPU-specific information. +       */ +#ifdef USE_X86_ASM +      if ( _mesa_x86_cpu_features ) { +	 strncat( buffer, " x86", 4 ); +      } +#endif +#ifdef USE_MMX_ASM +      if ( cpu_has_mmx ) { +	 strncat( buffer, "/MMX", 4 ); +      } +#endif +#ifdef USE_3DNOW_ASM +      if ( cpu_has_3dnow ) { +	 strncat( buffer, "/3DNow!", 7 ); +      } +#endif +#ifdef USE_SSE_ASM +      if ( cpu_has_xmm ) { +	 strncat( buffer, "/SSE", 4 ); +      } +#endif +      return (GLubyte *)buffer; + +   default: +      return NULL; +   } +} + + + +static void mgaBufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height) +{ +   GET_CURRENT_CONTEXT(ctx); +   mgaContextPtr mmesa = MGA_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( mmesa ); +   *width = mmesa->driDrawable->w; +   *height = mmesa->driDrawable->h; +   UNLOCK_HARDWARE( mmesa ); +} + +void mgaDDExtensionsInit( GLcontext *ctx ) +{ +   /* paletted_textures currently doesn't work, but we could fix them later */ +   /* +   _mesa_enable_extension( ctx, "GL_EXT_shared_texture_palette" ); +   _mesa_enable_extension( ctx, "GL_EXT_paletted_texture" ); +   */ + +   _mesa_enable_extension( ctx, "GL_ARB_texture_compression" ); +   _mesa_enable_extension( ctx, "GL_ARB_multisample" ); + +   _mesa_enable_extension( ctx, "GL_SGIS_generate_mipmap" ); + +   /* Turn on multitexture and texenv_add for the G400. +    */ +   if (MGA_IS_G400(MGA_CONTEXT(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" ); + +#if defined (MESA_packed_depth_stencil) +      _mesa_enable_extension( ctx, "GL_MESA_packed_depth_stencil" ); +#endif + +#if defined (MESA_experimetal_agp_allocator) +      if (!getenv("MGA_DISABLE_AGP_ALLOCATOR"))   +	 _mesa_enable_extension( ctx, "GL_MESA_experimental_agp_allocator" ); +#endif +   } +} + + + +void mgaDDInitDriverFuncs( GLcontext *ctx ) +{ +   ctx->Driver.GetBufferSize = mgaBufferSize; +   ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; +   ctx->Driver.GetString = mgaDDGetString; +} diff --git a/src/mesa/drivers/dri/mga/mgadd.h b/src/mesa/drivers/dri/mga/mgadd.h new file mode 100644 index 0000000000..6072e6cfc9 --- /dev/null +++ b/src/mesa/drivers/dri/mga/mgadd.h @@ -0,0 +1,37 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgadd.h,v 1.3 2002/10/30 12:51:35 alanh Exp $ */ +/* + * Copyright 2000-2001 VA Linux Systems, Inc. + * 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 + * VA LINUX SYSTEMS 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> + */ + +#ifndef MGADD_INC +#define MGADD_INC + +#include "context.h" + +void mgaDDInitDriverFuncs( GLcontext *ctx ); +void mgaDDExtensionsInit( GLcontext *ctx ); + +#endif diff --git a/src/mesa/drivers/dri/mga/mgaioctl.c b/src/mesa/drivers/dri/mga/mgaioctl.c new file mode 100644 index 0000000000..f88c878060 --- /dev/null +++ b/src/mesa/drivers/dri/mga/mgaioctl.c @@ -0,0 +1,693 @@ +/* + * Copyright 2000-2001 VA Linux Systems, Inc. + * 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 + * VA LINUX SYSTEMS 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> + *    Gareth Hughes <gareth@valinux.com> + */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaioctl.c,v 1.16 2002/12/16 16:18:52 dawes Exp $ */ + +#include <stdio.h> +#include <errno.h> + +#include "mtypes.h" +#include "macros.h" +#include "dd.h" +#include "swrast/swrast.h" + +#include "mm.h" +#include "mgacontext.h" +#include "mgadd.h" +#include "mgastate.h" +#include "mgatex.h" +#include "mgavb.h" +#include "mgaioctl.h" +#include "mgatris.h" +#include "mgabuffers.h" + + +#include "xf86drm.h" +#include "mga_common.h" + +static void mga_iload_dma_ioctl(mgaContextPtr mmesa, +				unsigned long dest, +				int length) +{ +   drmBufPtr buf = mmesa->iload_buffer; +   drmMGAIload iload; +   int ret, i; + +   if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) +      fprintf(stderr, "DRM_IOCTL_MGA_ILOAD idx %d dst %x length %d\n", +	      buf->idx, (int) dest, length); + +   iload.idx = buf->idx; +   iload.dstorg = dest; +   iload.length = length; + +   i = 0; +   do { +      ret = drmCommandWrite( mmesa->driFd, DRM_MGA_ILOAD,  +                             &iload, sizeof(drmMGAIload) ); +   } while ( ret == -EBUSY && i++ < DRM_MGA_IDLE_RETRY ); + +   if ( ret < 0 ) { +      printf("send iload retcode = %d\n", ret); +      exit(1); +   } + +   mmesa->iload_buffer = 0; + +   if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) +      fprintf(stderr, "finished iload dma put\n"); + +} + +drmBufPtr mga_get_buffer_ioctl( mgaContextPtr mmesa ) +{ +   int idx = 0; +   int size = 0; +   drmDMAReq dma; +   int retcode; +   drmBufPtr buf; + +   if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) +      fprintf(stderr,  "Getting dma buffer\n"); + +   dma.context = mmesa->hHWContext; +   dma.send_count = 0; +   dma.send_list = NULL; +   dma.send_sizes = NULL; +   dma.flags = 0; +   dma.request_count = 1; +   dma.request_size = MGA_BUFFER_SIZE; +   dma.request_list = &idx; +   dma.request_sizes = &size; +   dma.granted_count = 0; + + +   if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) +      fprintf(stderr, "drmDMA (get) ctx %d count %d size 0x%x\n", +	   dma.context, dma.request_count, +	   dma.request_size); + +   while (1) { +      retcode = drmDMA(mmesa->driFd, &dma); + +      if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) +	 fprintf(stderr, "retcode %d sz %d idx %d count %d\n", +		 retcode, +		 dma.request_sizes[0], +		 dma.request_list[0], +		 dma.granted_count); + +      if (retcode == 0 && +	  dma.request_sizes[0] && +	  dma.granted_count) +	 break; + +      if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) +	 fprintf(stderr, "\n\nflush"); + +      UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT ); +   } + +   buf = &(mmesa->mgaScreen->bufs->list[idx]); +   buf->used = 0; + +   if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) +      fprintf(stderr, +	   "drmDMA (get) returns size[0] 0x%x idx[0] %d\n" +	   "dma_buffer now: buf idx: %d size: %d used: %d addr %p\n", +	   dma.request_sizes[0], dma.request_list[0], +	   buf->idx, buf->total, +	   buf->used, buf->address); + +   if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) +      fprintf(stderr, "finished getbuffer\n"); + +   return buf; +} + + + + +static void +mgaDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, +            GLint cx, GLint cy, GLint cw, GLint ch ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); +   __DRIdrawablePrivate *dPriv = mmesa->driDrawable; +   GLuint flags = 0; +   GLuint clear_color = mmesa->ClearColor; +   GLuint clear_depth = 0; +   GLuint color_mask = 0; +   GLuint depth_mask = 0; +   int ret; +   int i; +   static int nrclears; +   drmMGAClearRec clear; + +   FLUSH_BATCH( mmesa ); + +   if ( mask & DD_FRONT_LEFT_BIT ) { +      flags |= MGA_FRONT; +      color_mask = mmesa->setup.plnwt; +      mask &= ~DD_FRONT_LEFT_BIT; +   } + +   if ( mask & DD_BACK_LEFT_BIT ) { +      flags |= MGA_BACK; +      color_mask = mmesa->setup.plnwt; +      mask &= ~DD_BACK_LEFT_BIT; +   } + +   if ( (mask & DD_DEPTH_BIT) && ctx->Depth.Mask ) { +      flags |= MGA_DEPTH; +      clear_depth = (mmesa->ClearDepth & mmesa->depth_clear_mask); +      depth_mask |= mmesa->depth_clear_mask; +      mask &= ~DD_DEPTH_BIT; +   } + +   if ( (mask & DD_STENCIL_BIT) && mmesa->hw_stencil ) { +      flags |= MGA_DEPTH; +      clear_depth |= (ctx->Stencil.Clear & mmesa->stencil_clear_mask); +      depth_mask |= mmesa->stencil_clear_mask; +      mask &= ~DD_STENCIL_BIT; +   } + +   if ( flags ) { +      LOCK_HARDWARE( mmesa ); + +      if ( mmesa->dirty_cliprects ) +	 mgaUpdateRects( mmesa, (MGA_FRONT | MGA_BACK) ); + +      /* flip top to bottom */ +      cy = dPriv->h-cy-ch; +      cx += mmesa->drawX; +      cy += mmesa->drawY; + +      if ( MGA_DEBUG & DEBUG_VERBOSE_IOCTL ) +	 fprintf( stderr, "Clear, bufs %x nbox %d\n", +		  (int)flags, (int)mmesa->numClipRects ); + +      for (i = 0 ; i < mmesa->numClipRects ; ) +      { +	 int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, mmesa->numClipRects); +	 XF86DRIClipRectPtr box = mmesa->pClipRects; +	 XF86DRIClipRectPtr b = mmesa->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++ = *(XF86DRIClipRectPtr)&box[i]; +	       n++; +	    } +	 } + + +	 if ( MGA_DEBUG & DEBUG_VERBOSE_IOCTL ) +	    fprintf( stderr, +		     "DRM_IOCTL_MGA_CLEAR flag 0x%x color %x depth %x nbox %d\n", +		     flags, clear_color, clear_depth, mmesa->sarea->nbox ); + +	 mmesa->sarea->nbox = n; + +         clear.flags = flags; +         clear.clear_color = clear_color; +         clear.clear_depth = clear_depth; +         clear.color_mask = color_mask; +         clear.depth_mask = depth_mask; +         ret = drmCommandWrite( mmesa->driFd, DRM_MGA_CLEAR, +                                 &clear, sizeof(drmMGAClearRec)); +	 if ( ret ) { +	    fprintf( stderr, "send clear retcode = %d\n", ret ); +	    exit( 1 ); +	 } +	 if ( MGA_DEBUG & DEBUG_VERBOSE_IOCTL ) +	    fprintf( stderr, "finished clear %d\n", ++nrclears ); +      } + +      UNLOCK_HARDWARE( mmesa ); +      mmesa->dirty |= MGA_UPLOAD_CLIPRECTS|MGA_UPLOAD_CONTEXT; +   } + +   if (mask)  +      _swrast_Clear( ctx, mask, all, cx, cy, cw, ch ); +} + + +int nrswaps; + + +void mgaWaitForVBlank( mgaContextPtr mmesa ) +{ +#if 0 +    drmVBlank vbl; +    int ret; + +    if ( !mmesa->mgaScreen->irq ) +	return; + +    if ( getenv("LIBGL_SYNC_REFRESH") ) { +	/* Wait for until the next vertical blank */ +	vbl.request.type = DRM_VBLANK_RELATIVE; +	vbl.request.sequence = 1; +    } else if ( getenv("LIBGL_THROTTLE_REFRESH") ) { +	/* Wait for at least one vertical blank since the last call */ +	vbl.request.type = DRM_VBLANK_ABSOLUTE; +	vbl.request.sequence = mmesa->vbl_seq + 1; +    } else { +	return; +    } + +    if ((ret = drmWaitVBlank( mmesa->driFd, &vbl ))) { +	fprintf(stderr, "%s: drmWaitVBlank returned %d, IRQs don't seem to be" +		" working correctly.\nTry running with LIBGL_THROTTLE_REFRESH" +		" and LIBL_SYNC_REFRESH unset.\n", __FUNCTION__, ret); +	exit(1); +    } + +    mmesa->vbl_seq = vbl.reply.sequence; +#endif +} + + +/* + * Copy the back buffer to the front buffer. + */ +void mgaSwapBuffers(__DRIdrawablePrivate *dPriv) +{ +   mgaContextPtr mmesa; +   XF86DRIClipRectPtr pbox; +   GLint nbox; +   GLint ret, wait = 0; +   GLint i; +   GLuint last_frame, last_wrap; + +   assert(dPriv); +   assert(dPriv->driContextPriv); +   assert(dPriv->driContextPriv->driverPrivate); + +   mmesa = (mgaContextPtr) dPriv->driContextPriv->driverPrivate; + +   FLUSH_BATCH( mmesa ); + +   mgaWaitForVBlank( mmesa ); + +   LOCK_HARDWARE( mmesa ); + +   last_frame = mmesa->sarea->last_frame.head; +   last_wrap = mmesa->sarea->last_frame.wrap; + +   /* FIXME: Add a timeout to this loop... +    */ +   while ( 1 ) { +      if ( last_wrap < mmesa->sarea->last_wrap || +	   ( last_wrap == mmesa->sarea->last_wrap && +	     last_frame <= (MGA_READ( MGAREG_PRIMADDRESS ) - +			    mmesa->primary_offset) ) ) { +	 break; +      } +      if ( 0 ) { +	 wait++; +	 fprintf( stderr, "   last: head=0x%06x wrap=%d\n", +		  last_frame, last_wrap ); +	 fprintf( stderr, "   head: head=0x%06lx wrap=%d\n", +		  (long)(MGA_READ( MGAREG_PRIMADDRESS ) - mmesa->primary_offset), +		  mmesa->sarea->last_wrap ); +      } +      UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH ); + +      for ( i = 0 ; i < 1024 ; i++ ) { +	 /* Don't just hammer the register... */ +      } +   } +   if ( wait ) +      fprintf( stderr, "\n" ); + +   /* Use the frontbuffer cliprects +    */ +   if (mmesa->dirty_cliprects & MGA_FRONT) +      mgaUpdateRects( mmesa, MGA_FRONT ); + + +   pbox = dPriv->pClipRects; +   nbox = dPriv->numClipRects; + +   for (i = 0 ; i < nbox ; ) +   { +      int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, dPriv->numClipRects); +      XF86DRIClipRectPtr b = mmesa->sarea->boxes; + +      mmesa->sarea->nbox = nr - i; + +      for ( ; i < nr ; i++) +	 *b++ = pbox[i]; + +      if (0) +	 fprintf(stderr, "DRM_IOCTL_MGA_SWAP\n"); + +      ret = drmCommandNone( mmesa->driFd, DRM_MGA_SWAP ); +      if ( ret ) { +	 printf("send swap retcode = %d\n", ret); +	 exit(1); +      } +   } + +   UNLOCK_HARDWARE( mmesa ); + +   mmesa->dirty |= MGA_UPLOAD_CLIPRECTS; +} + + +/* This is overkill + */ +void mgaDDFinish( GLcontext *ctx  ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); + +   FLUSH_BATCH( mmesa ); + +   if (1/*mmesa->sarea->last_quiescent != mmesa->sarea->last_enqueue*/) { +      if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) +	 fprintf(stderr, "mgaRegetLockQuiescent\n"); + +      LOCK_HARDWARE( mmesa ); +      UPDATE_LOCK( mmesa, DRM_LOCK_QUIESCENT | DRM_LOCK_FLUSH ); +      UNLOCK_HARDWARE( mmesa ); + +      mmesa->sarea->last_quiescent = mmesa->sarea->last_enqueue; +   } +} + +void mgaWaitAgeLocked( mgaContextPtr mmesa, int age  ) +{ +   if (GET_DISPATCH_AGE(mmesa) < age) { +      UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH ); +   } +} + + +void mgaWaitAge( mgaContextPtr mmesa, int age  ) +{ +   if (GET_DISPATCH_AGE(mmesa) < age) { +      LOCK_HARDWARE(mmesa); +      if (GET_DISPATCH_AGE(mmesa) < age) { +	 UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH ); +      } +      UNLOCK_HARDWARE(mmesa); +   } +} + + +static int intersect_rect( XF86DRIClipRectPtr out, +			   XF86DRIClipRectPtr a, +			   XF86DRIClipRectPtr b ) +{ +   *out = *a; +   if (b->x1 > out->x1) out->x1 = b->x1; +   if (b->y1 > out->y1) out->y1 = b->y1; +   if (b->x2 < out->x2) out->x2 = b->x2; +   if (b->y2 < out->y2) out->y2 = b->y2; +   if (out->x1 > out->x2) return 0; +   if (out->y1 > out->y2) return 0; +   return 1; +} + + + + +static void age_mmesa( mgaContextPtr mmesa, int age ) +{ +   if (mmesa->CurrentTexObj[0]) mmesa->CurrentTexObj[0]->age = age; +   if (mmesa->CurrentTexObj[1]) mmesa->CurrentTexObj[1]->age = age; +} + +#ifdef __i386__ +static int __break_vertex = 0; +#endif + +void mgaFlushVerticesLocked( mgaContextPtr mmesa ) +{ +   XF86DRIClipRectPtr pbox = mmesa->pClipRects; +   int nbox = mmesa->numClipRects; +   drmBufPtr buffer = mmesa->vertex_dma_buffer; +   drmMGAVertex vertex; +   int i; + +   mmesa->vertex_dma_buffer = 0; + +   if (!buffer) +      return; + +   if (mmesa->dirty_cliprects & mmesa->draw_buffer) +      mgaUpdateRects( mmesa, mmesa->draw_buffer ); + +   if (mmesa->dirty & ~MGA_UPLOAD_CLIPRECTS) +      mgaEmitHwStateLocked( mmesa ); + +   /* FIXME: Workaround bug in kernel module. +    */ +   mmesa->sarea->dirty |= MGA_UPLOAD_CONTEXT; + +   if (!nbox) +      buffer->used = 0; + +   if (nbox >= MGA_NR_SAREA_CLIPRECTS) +      mmesa->dirty |= MGA_UPLOAD_CLIPRECTS; + +#if 0 +   if (!buffer->used || !(mmesa->dirty & MGA_UPLOAD_CLIPRECTS)) +   { +      if (nbox == 1) +	 mmesa->sarea->nbox = 0; +      else +	 mmesa->sarea->nbox = nbox; + +      if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) +	 fprintf(stderr, "Firing vertex -- case a nbox %d\n", nbox); + +      vertex.idx = buffer->idx; +      vertex.used = buffer->used; +      vertex.discard = 1; +      drmCommandWrite( mmesa->driFd, DRM_MGA_VERTEX,  +                       &vertex, sizeof(drmMGAVertex) ); + +      age_mmesa(mmesa, mmesa->sarea->last_enqueue); +   } +   else +#endif +   { +      for (i = 0 ; i < nbox ; ) +      { +	 int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, nbox); +	 XF86DRIClipRectPtr b = mmesa->sarea->boxes; +	 int discard = 0; + +	 if (mmesa->scissor) { +	    mmesa->sarea->nbox = 0; + +	    for ( ; i < nr ; i++) { +	       *b = pbox[i]; +	       if (intersect_rect(b, b, &mmesa->scissor_rect)) { +		  mmesa->sarea->nbox++; +		  b++; +	       } +	    } + +	    /* Culled? +	     */ +	    if (!mmesa->sarea->nbox) { +	       if (nr < nbox) continue; +	       buffer->used = 0; +	    } +	 } else { +	    mmesa->sarea->nbox = nr - i; +	    for ( ; i < nr ; i++) +	       *b++ = pbox[i]; +	 } + +	 /* Finished with the buffer? +	  */ +	 if (nr == nbox) +	    discard = 1; + +	 mmesa->sarea->dirty |= MGA_UPLOAD_CLIPRECTS; + +         vertex.idx = buffer->idx; +         vertex.used = buffer->used; +         vertex.discard = discard; +         drmCommandWrite( mmesa->driFd, DRM_MGA_VERTEX,  +                          &vertex, sizeof(drmMGAVertex) ); + +	 age_mmesa(mmesa, mmesa->sarea->last_enqueue); +      } +   } + +   /* Do we really need to do this ? */ +#ifdef __i386__ +   if ( __break_vertex ) { +      __asm__ __volatile__ ( "int $3" ); +   } +#endif + +   mmesa->dirty &= ~MGA_UPLOAD_CLIPRECTS; +} + +void mgaFlushVertices( mgaContextPtr mmesa ) +{ +   LOCK_HARDWARE( mmesa ); +   mgaFlushVerticesLocked( mmesa ); +   UNLOCK_HARDWARE( mmesa ); +} + + +void mgaFireILoadLocked( mgaContextPtr mmesa, +			 GLuint offset, GLuint length ) +{ +   if (!mmesa->iload_buffer) { +      fprintf(stderr, "mgaFireILoad: no buffer\n"); +      return; +   } + +   if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) +      fprintf(stderr, "mgaFireILoad idx %d ofs 0x%x length %d\n", +	      mmesa->iload_buffer->idx, (int)offset, (int)length ); + +   mga_iload_dma_ioctl( mmesa, offset, length ); +} + +void mgaGetILoadBufferLocked( mgaContextPtr mmesa ) +{ +   if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) +      fprintf(stderr, "mgaGetIloadBuffer (buffer now %p)\n", +	   mmesa->iload_buffer); + +   mmesa->iload_buffer = mga_get_buffer_ioctl( mmesa ); +} + +drmBufPtr mgaGetBufferLocked( mgaContextPtr mmesa ) +{ +   return mga_get_buffer_ioctl( mmesa ); +} + + + +void mgaDDFlush( GLcontext *ctx ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + + +   FLUSH_BATCH( mmesa ); + +   /* This may be called redundantly - dispatch_age may trail what +    * has actually been sent and processed by the hardware. +    */ +   if (1 || GET_DISPATCH_AGE( mmesa ) < mmesa->sarea->last_enqueue) { +      LOCK_HARDWARE( mmesa ); +      UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH ); +      UNLOCK_HARDWARE( mmesa ); +   } +} + + + + +void mgaReleaseBufLocked( mgaContextPtr mmesa, drmBufPtr buffer ) +{ +   drmMGAVertex vertex; + +   if (!buffer) return; + +   vertex.idx = buffer->idx; +   vertex.used = 0; +   vertex.discard = 1; +   drmCommandWrite( mmesa->driFd, DRM_MGA_VERTEX,  +                    &vertex, sizeof(drmMGAVertex) ); +} + +int mgaFlushDMA( int fd, drmLockFlags flags ) +{ +   drmMGALock lock; +   int ret, i = 0; + +   memset( &lock, 0, sizeof(drmMGALock) ); + +   if ( flags & DRM_LOCK_QUIESCENT )    lock.flags |= DRM_LOCK_QUIESCENT; +   if ( flags & DRM_LOCK_FLUSH )        lock.flags |= DRM_LOCK_FLUSH; +   if ( flags & DRM_LOCK_FLUSH_ALL )    lock.flags |= DRM_LOCK_FLUSH_ALL; + +   do { +      ret = drmCommandWrite( fd, DRM_MGA_FLUSH, &lock, sizeof(drmMGALock) ); +   } while ( ret && errno == EBUSY && i++ < DRM_MGA_IDLE_RETRY ); + +   if ( ret == 0 ) +      return 0; +   if ( errno != EBUSY ) +      return -errno; + +   if ( lock.flags & DRM_LOCK_QUIESCENT ) { +      /* Only keep trying if we need quiescence. +       */ +      lock.flags &= ~(DRM_LOCK_FLUSH | DRM_LOCK_FLUSH_ALL); + +      do { +         ret = drmCommandWrite( fd, DRM_MGA_FLUSH, &lock, sizeof(drmMGALock) ); +      } while ( ret && errno == EBUSY && i++ < DRM_MGA_IDLE_RETRY ); +   } + +   if ( ret == 0 ) { +      return 0; +   } else { +      return -errno; +   } +} + +void mgaDDInitIoctlFuncs( GLcontext *ctx ) +{ +   ctx->Driver.Clear = mgaDDClear; +   ctx->Driver.Flush = mgaDDFlush; +   ctx->Driver.Finish = mgaDDFinish; +} diff --git a/src/mesa/drivers/dri/mga/mgaioctl.h b/src/mesa/drivers/dri/mga/mgaioctl.h new file mode 100644 index 0000000000..b7cf44d6ff --- /dev/null +++ b/src/mesa/drivers/dri/mga/mgaioctl.h @@ -0,0 +1,113 @@ +/* + * Copyright 2000-2001 VA Linux Systems, Inc. + * 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 + * VA LINUX SYSTEMS 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> + *    Gareth Hughes <gareth@valinux.com> + */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaioctl.h,v 1.11 2002/10/30 12:51:36 alanh Exp $ */ + +#ifndef MGA_IOCTL_H +#define MGA_IOCTL_H + +#include "mgacontext.h" +#include "mga_xmesa.h" + +void mgaSwapBuffers( __DRIdrawablePrivate *dPriv ); + +GLuint *mgaAllocVertexDwords( mgaContextPtr mmesa, int dwords ); + + +void mgaGetILoadBufferLocked( mgaContextPtr mmesa ); +drmBufPtr mgaGetBufferLocked( mgaContextPtr mmesa ); + +void mgaWaitForVBlank( mgaContextPtr mmesa ); + +void mgaFireILoadLocked( mgaContextPtr mmesa, +			 GLuint offset, GLuint length ); + +void mgaWaitAgeLocked( mgaContextPtr mmesa, int age ); +void mgaWaitAge( mgaContextPtr mmesa, int age ); + +void mgaFlushVertices( mgaContextPtr mmesa ); +void mgaFlushVerticesLocked( mgaContextPtr mmesa ); +void mgaReleaseBufLocked( mgaContextPtr mmesa, drmBufPtr buffer ); +int mgaFlushDMA( int fd, drmLockFlags flags ); + +void mgaDDFlush( GLcontext *ctx ); +void mgaDDFinish( GLcontext *ctx ); + +void mgaDDInitIoctlFuncs( GLcontext *ctx ); + +#define FLUSH_BATCH(mmesa) do {						\ +        if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)  				\ +              fprintf(stderr, "FLUSH_BATCH in %s\n", __FUNCTION__);	\ +	if (mmesa->vertex_dma_buffer) mgaFlushVertices(mmesa);		\ +} while (0) + +#define MGA_STATECHANGE(mmesa, flag) do {	\ +   FLUSH_BATCH(mmesa);				\ +   mmesa->dirty |= flag;			\ +} while (0) + + +extern drmBufPtr mga_get_buffer_ioctl( mgaContextPtr mmesa ); + +static __inline +GLuint *mgaAllocDmaLow( mgaContextPtr mmesa, int bytes ) +{ +   GLuint *head; + +   if (!mmesa->vertex_dma_buffer) { +      LOCK_HARDWARE( mmesa ); +      mmesa->vertex_dma_buffer = mga_get_buffer_ioctl( mmesa ); +      UNLOCK_HARDWARE( mmesa ); +   } else if (mmesa->vertex_dma_buffer->used + bytes > +	      mmesa->vertex_dma_buffer->total) { +      LOCK_HARDWARE( mmesa ); +      mgaFlushVerticesLocked( mmesa ); +      mmesa->vertex_dma_buffer = mga_get_buffer_ioctl( mmesa ); +      UNLOCK_HARDWARE( mmesa ); +   } + +   head = (GLuint *)((char *)mmesa->vertex_dma_buffer->address + +		      mmesa->vertex_dma_buffer->used); + +   mmesa->vertex_dma_buffer->used += bytes; +   return head; +} + + +#define UPDATE_LOCK( mmesa, flags )					\ +do {									\ +   GLint ret = mgaFlushDMA( mmesa->driFd, flags );			\ +   if ( ret < 0 ) {							\ +      drmCommandNone( mmesa->driFd, DRM_MGA_RESET );			\ +      UNLOCK_HARDWARE( mmesa );						\ +      fprintf( stderr, "%s: flush ret=%d\n", __FUNCTION__, ret );	\ +      /*fprintf( stderr, "drmMGAFlushDMA: return = %d\n", ret );*/	\ +      exit( 1 );							\ +   }									\ +} while (0) + +#endif diff --git a/src/mesa/drivers/dri/mga/mgapixel.c b/src/mesa/drivers/dri/mga/mgapixel.c new file mode 100644 index 0000000000..0bc4b3fac5 --- /dev/null +++ b/src/mesa/drivers/dri/mga/mgapixel.c @@ -0,0 +1,690 @@ +/* + * Copyright 2000 Compaq Computer Inc. and VA Linux Systems, Inc. + * 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 + * VA LINUX SYSTEMS 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> + *    Gareth Hughes <gareth@valinux.com> + */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgapixel.c,v 1.9 2002/11/05 17:46:08 tsi Exp $ */ + +#include "enums.h" +#include "mtypes.h" +#include "macros.h" +#include "texutil.h" +#include "mgadd.h" +#include "mgacontext.h" +#include "mgaioctl.h" +#include "mgapixel.h" +#include "mgabuffers.h" + +#include "xf86drm.h" +#include "mga_common.h" + +#include "swrast/swrast.h" + +#define IS_AGP_MEM( mmesa, p )						  \ +   ((unsigned long)mmesa->mgaScreen->buffers.map <= ((unsigned long)p) && \ +    (unsigned long)mmesa->mgaScreen->buffers.map +			  \ +    (unsigned long)mmesa->mgaScreen->buffers.size > ((unsigned long)p)) +#define AGP_OFFSET( mmesa, p )						  \ +     (((unsigned long)p) - (unsigned long)mmesa->mgaScreen->buffers.map) + + +#if defined(MESA_packed_depth_stencil) +static GLboolean +check_depth_stencil_24_8( const GLcontext *ctx, GLenum type, +			  const struct gl_pixelstore_attrib *packing, +			  const void *pixels, GLint sz, +			  GLint pitch ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); + +   return ( type == GL_UNSIGNED_INT_24_8_MESA && +	    ctx->Visual->DepthBits == 24 && +	    ctx->Visual->StencilBits == 8 && +	    mmesa->mgaScreen->cpp == 4 && +	    mmesa->hw_stencil && +	    !ctx->Pixel.IndexShift && +	    !ctx->Pixel.IndexOffset && +	    !ctx->Pixel.MapStencilFlag && +	    ctx->Pixel.DepthBias == 0.0 && +	    ctx->Pixel.DepthScale == 1.0 && +	    !packing->SwapBytes && +	    pitch % 32 == 0 && +	    pitch < 4096 ); +} +#endif + + +static GLboolean +check_depth( const GLcontext *ctx, GLenum type, +	     const struct gl_pixelstore_attrib *packing, +	     const void *pixels, GLint sz, GLint pitch ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); + +   if ( IS_AGP_MEM( mmesa, pixels ) && +	!( ( type == GL_UNSIGNED_INT && mmesa->mgaScreen->cpp == 4 ) || +	   ( type == GL_UNSIGNED_SHORT && mmesa->mgaScreen->cpp == 2 ) ) ) +      return GL_FALSE; + +   return ( ctx->Pixel.DepthBias == 0.0 && +	    ctx->Pixel.DepthScale == 1.0 && +	    !packing->SwapBytes && +	    pitch % 32 == 0 && +	    pitch < 4096 ); +} + + +static GLboolean +check_color( const GLcontext *ctx, GLenum type, GLenum format, +	     const struct gl_pixelstore_attrib *packing, +	     const void *pixels, GLint sz, GLint pitch ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); +   GLuint cpp = mmesa->mgaScreen->cpp; + +   /* Can't do conversions on agp reads/draws. +    */ +   if ( IS_AGP_MEM( mmesa, pixels ) && +	!( pitch % 32 == 0 && pitch < 4096 && +	   ( ( type == GL_UNSIGNED_BYTE && +	       cpp == 4 && format == GL_BGRA ) || +	     ( type == GL_UNSIGNED_INT_8_8_8_8 && +	       cpp == 4 && format == GL_BGRA ) || +	     ( type == GL_UNSIGNED_SHORT_5_6_5_REV && +	       cpp == 2 && format == GL_RGB ) ) ) ) +      return GL_FALSE; + +   return (!ctx->_ImageTransferState && +	   !packing->SwapBytes && +	   !packing->LsbFirst); +} + +static GLboolean +check_color_per_fragment_ops( const GLcontext *ctx ) +{ +   return (!(       ctx->Color.AlphaEnabled || +		    ctx->Depth.Test || +		    ctx->Fog.Enabled || +		    ctx->Scissor.Enabled || +		    ctx->Stencil.Enabled || +		    !ctx->Color.ColorMask[0] || +		    !ctx->Color.ColorMask[1] || +		    !ctx->Color.ColorMask[2] || +		    !ctx->Color.ColorMask[3] || +		    ctx->Color.ColorLogicOpEnabled || +		    ctx->Texture.Unit[0]._ReallyEnabled || +		    ctx->Depth.OcclusionTest +           ) && +	   ctx->Current.RasterPosValid && +	   ctx->Pixel.ZoomX == 1.0F && +	   (ctx->Pixel.ZoomY == 1.0F || ctx->Pixel.ZoomY == -1.0F)); +} + +static GLboolean +check_depth_per_fragment_ops( const GLcontext *ctx ) +{ +   return ( ctx->Current.RasterPosValid && +	    ctx->Color.ColorMask[RCOMP] == 0 && +	    ctx->Color.ColorMask[BCOMP] == 0 && +	    ctx->Color.ColorMask[GCOMP] == 0 && +	    ctx->Color.ColorMask[ACOMP] == 0 && +	    ctx->Pixel.ZoomX == 1.0F && +	    ( ctx->Pixel.ZoomY == 1.0F || ctx->Pixel.ZoomY == -1.0F ) ); +} + +/* In addition to the requirements for depth: + */ +#if defined(MESA_packed_depth_stencil) +static GLboolean +check_stencil_per_fragment_ops( const GLcontext *ctx ) +{ +   return ( !ctx->Pixel.IndexShift && +	    !ctx->Pixel.IndexOffset ); +} +#endif + + +static GLboolean +clip_pixelrect( const GLcontext *ctx, +		const GLframebuffer *buffer, +		GLint *x, GLint *y, +		GLsizei *width, GLsizei *height, +		GLint *skipPixels, GLint *skipRows, +		GLint *size ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); + +   *width = MIN2(*width, MAX_WIDTH); /* redundant? */ + +   /* left clipping */ +   if (*x < buffer->_Xmin) { +      *skipPixels += (buffer->_Xmin - *x); +      *width -= (buffer->_Xmin - *x); +      *x = buffer->_Xmin; +   } + +   /* right clipping */ +   if (*x + *width > buffer->_Xmax) +      *width -= (*x + *width - buffer->_Xmax - 1); + +   if (*width <= 0) +      return GL_FALSE; + +   /* bottom clipping */ +   if (*y < buffer->_Ymin) { +      *skipRows += (buffer->_Ymin - *y); +      *height -= (buffer->_Ymin - *y); +      *y = buffer->_Ymin; +   } + +   /* top clipping */ +   if (*y + *height > buffer->_Ymax) +      *height -= (*y + *height - buffer->_Ymax - 1); + +   if (*height <= 0) +      return GL_FALSE; + +   *size = ((*y + *height - 1) * mmesa->mgaScreen->frontPitch + +	    (*x + *width - 1) * mmesa->mgaScreen->cpp); + +   return GL_TRUE; +} + +static GLboolean +mgaTryReadPixels( GLcontext *ctx, +		  GLint x, GLint y, GLsizei width, GLsizei height, +		  GLenum format, GLenum type, +		  const struct gl_pixelstore_attrib *pack, +		  GLvoid *pixels ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); +   GLint size, skipPixels, skipRows; +   GLint pitch = pack->RowLength ? pack->RowLength : width; +   GLboolean ok; + +   GLuint planemask; +   GLuint source; +#if 0 +   drmMGABlit blit; +   GLuint dest; +   GLint source_pitch, dest_pitch; +   GLint delta_sx, delta_sy; +   GLint delta_dx, delta_dy; +   GLint blit_height, ydir; +#endif + +   if (!clip_pixelrect(ctx, ctx->ReadBuffer, +		       &x, &y, &width, &height, +		       &skipPixels, &skipRows, &size)) { +      return GL_TRUE; +   } + +   /* Only accelerate reading to agp buffers. +    */ +   if ( !IS_AGP_MEM(mmesa, (char *)pixels) || +	!IS_AGP_MEM(mmesa, (char *)pixels + size) ) +      return GL_FALSE; + +   switch (format) { +#if defined(MESA_packed_depth_stencil) +   case GL_DEPTH_STENCIL_MESA: +      ok = check_depth_stencil_24_8(ctx, type, pack, pixels, size, pitch); +      planemask = ~0; +      source = mmesa->mgaScreen->depthOffset; +      break; +#endif + +   case GL_DEPTH_COMPONENT: +      ok = check_depth(ctx, type, pack, pixels, size, pitch); + +      /* Can't accelerate at this depth -- planemask does the wrong +       * thing; it doesn't clear the low order bits in the +       * destination, instead it leaves them untouched. +       * +       * Could get the acclerator to solid fill the destination with +       * zeros first...  Or get the cpu to do it... +       */ +      if (ctx->Visual.depthBits == 24) +	 return GL_FALSE; + +      planemask = ~0; +      source = mmesa->mgaScreen->depthOffset; +      break; + +   case GL_RGB: +   case GL_BGRA: +      ok = check_color(ctx, type, format, pack, pixels, size, pitch); +      planemask = ~0; +      source = (mmesa->draw_buffer == MGA_FRONT ? +		mmesa->mgaScreen->frontOffset : +		mmesa->mgaScreen->backOffset); +      break; + +   default: +      return GL_FALSE; +   } + +   if (!ok) { +      return GL_FALSE; +   } + + +   LOCK_HARDWARE( mmesa ); + +#if 0 +   { +      __DRIdrawablePrivate *dPriv = mmesa->driDrawable; +      int nbox, retcode, i; + +      UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT ); + +      if (mmesa->dirty_cliprects & MGA_FRONT) +	 mgaUpdateRects( mmesa, MGA_FRONT ); + +      nbox = dPriv->numClipRects; + +      y = dPriv->h - y - height; +      x += mmesa->drawX; +      y += mmesa->drawY; + +      dest = ((mmesa->mgaScreen->agp.handle + AGP_OFFSET(mmesa, pixels)) | +	      DO_dstmap_sys | DO_dstacc_agp); +      source_pitch = mmesa->mgaScreen->frontPitch / mmesa->mgaScreen->cpp; +      dest_pitch = pitch; +      delta_sx = 0; +      delta_sy = 0; +      delta_dx = -x; +      delta_dy = -y; +      blit_height = 2*y + height; +      ydir = -1; + +      if (0) fprintf(stderr, "XX doing readpixel blit src_pitch %d dst_pitch %d\n", +		     source_pitch, dest_pitch); + + + +      for (i = 0 ; i < nbox ; ) +      { +	 int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, dPriv->numClipRects); +	 XF86DRIClipRectRec *box = dPriv->pClipRects; +	 drm_clip_rect_t *b = mmesa->sarea->boxes; +	 int n = 0; + +	 for ( ; i < nr ; i++) { +	    GLint bx = box[i].x1; +	    GLint by = box[i].y1; +	    GLint bw = box[i].x2 - bx; +	    GLint bh = box[i].y2 - by; + +	    if (bx < x) bw -= x - bx, bx = x; +	    if (by < y) bh -= y - by, by = y; +	    if (bx + bw > x + width) bw = x + width - bx; +	    if (by + bh > y + height) bh = y + height - by; +	    if (bw <= 0) continue; +	    if (bh <= 0) continue; + +	    b->x1 = bx; +	    b->y1 = by; +	    b->x2 = bx + bw; +	    b->y2 = by + bh; +	    b++; +	    n++; +	 } + +	 mmesa->sarea->nbox = n; + +	 if (n && (retcode = drmCommandWrite( mmesa->driFd, DRM_MGA_BLIT, +                                              &blit, sizeof(drmMGABlit)))) { +	    fprintf(stderr, "blit ioctl failed, retcode = %d\n", retcode); +	    UNLOCK_HARDWARE( mmesa ); +	    exit(1); +	 } +      } + +      UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT ); +   } +#endif + +   UNLOCK_HARDWARE( mmesa ); + +   return GL_TRUE; +} + +static void +mgaDDReadPixels( GLcontext *ctx, +		 GLint x, GLint y, GLsizei width, GLsizei height, +		 GLenum format, GLenum type, +		 const struct gl_pixelstore_attrib *pack, +		 GLvoid *pixels ) +{ +   if (!mgaTryReadPixels( ctx, x, y, width, height, format, type, pack, pixels)) +      _swrast_ReadPixels( ctx, x, y, width, height, format, type, pack, pixels); +} + + + + +static void do_draw_pix( GLcontext *ctx, +			 GLint x, GLint y, GLsizei width, GLsizei height, +			 GLint pitch, +			 const void *pixels, +			 GLuint dest, GLuint planemask) +{ +#if 0 +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); +   drmMGABlit blit; +   __DRIdrawablePrivate *dPriv = mmesa->driDrawable; +   XF86DRIClipRectPtr pbox = dPriv->pClipRects; +   int nbox = dPriv->numClipRects; +   int retcode, i; + +   y = dPriv->h - y - height; +   x += mmesa->drawX; +   y += mmesa->drawY; + +   blit.dest = dest; +   blit.planemask = planemask; +   blit.source = ((mmesa->mgaScreen->agp.handle + AGP_OFFSET(mmesa, pixels)) +		  | SO_srcmap_sys | SO_srcacc_agp); +   blit.dest_pitch = mmesa->mgaScreen->frontPitch / mmesa->mgaScreen->cpp; +   blit.source_pitch = pitch; +   blit.delta_sx = -x; +   blit.delta_sy = -y; +   blit.delta_dx = 0; +   blit.delta_dy = 0; +   if (ctx->Pixel.ZoomY == -1) { +      blit.height = height; +      blit.ydir = 1; +   } else { +      blit.height = height; +      blit.ydir = -1; +   } + +   if (0) fprintf(stderr, +		  "doing drawpixel blit src_pitch %d dst_pitch %d\n", +		  blit.source_pitch, blit.dest_pitch); + +   for (i = 0 ; i < nbox ; ) +   { +      int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, dPriv->numClipRects); +      XF86DRIClipRectRec *box = mmesa->pClipRects; +      drm_clip_rect_t *b = mmesa->sarea->boxes; +      int n = 0; + +      for ( ; i < nr ; i++) { +	 GLint bx = box[i].x1; +	 GLint by = box[i].y1; +	 GLint bw = box[i].x2 - bx; +	 GLint bh = box[i].y2 - by; + +	 if (bx < x) bw -= x - bx, bx = x; +	 if (by < y) bh -= y - by, by = y; +	 if (bx + bw > x + width) bw = x + width - bx; +	 if (by + bh > y + height) bh = y + height - by; +	 if (bw <= 0) continue; +	 if (bh <= 0) continue; + +	 b->x1 = bx; +	 b->y1 = by; +	 b->x2 = bx + bw; +	 b->y2 = by + bh; +	 b++; +	 n++; +      } + +      mmesa->sarea->nbox = n; + +      if (n && (retcode = drmCommandWrite( mmesa->driFd, DRM_MGA_BLIT, +                                              &blit, sizeof(drmMGABlit)))) { +	 fprintf(stderr, "blit ioctl failed, retcode = %d\n", retcode); +	 UNLOCK_HARDWARE( mmesa ); +	 exit(1); +      } +   } +#endif +} + + + + +static GLboolean +mgaTryDrawPixels( GLcontext *ctx, +		  GLint x, GLint y, GLsizei width, GLsizei height, +		  GLenum format, GLenum type, +		  const struct gl_pixelstore_attrib *unpack, +		  const GLvoid *pixels ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); +   GLint size, skipPixels, skipRows; +   GLint pitch = unpack->RowLength ? unpack->RowLength : width; +   GLuint dest, planemask; +   GLuint cpp = mmesa->mgaScreen->cpp; + +   if (!clip_pixelrect(ctx, ctx->DrawBuffer, +		       &x, &y, &width, &height, +		       &skipPixels, &skipRows, &size)) { +      return GL_TRUE; +   } + + +   switch (format) { +#if defined(MESA_packed_depth_stencil) +   case GL_DEPTH_STENCIL_MESA: +      dest = mmesa->mgaScreen->depthOffset; +      planemask = ~0; +      if (!check_depth_stencil_24_8(ctx, type, unpack, pixels, size, pitch) || +	  !check_depth_per_fragment_ops(ctx) || +	  !check_stencil_per_fragment_ops(ctx)) +	 return GL_FALSE; +      break; +#endif + +   case GL_DEPTH_COMPONENT: +      dest = mmesa->mgaScreen->depthOffset; + +      if (ctx->Visual.depthBits == 24) +	 planemask = ~0xff; +      else +	 planemask = ~0; + +      if (!check_depth(ctx, type, unpack, pixels, size, pitch) || +	  !check_depth_per_fragment_ops(ctx)) +	 return GL_FALSE; +      break; + +   case GL_RGB: +   case GL_BGRA: +      dest = (mmesa->draw_buffer == MGA_FRONT ? +	      mmesa->mgaScreen->frontOffset : +	      mmesa->mgaScreen->backOffset); + +      planemask = mgaPackColor(cpp, +			       ctx->Color.ColorMask[RCOMP], +			       ctx->Color.ColorMask[GCOMP], +			       ctx->Color.ColorMask[BCOMP], +			       ctx->Color.ColorMask[ACOMP]); + +      if (cpp == 2) +	 planemask |= planemask << 16; + +      if (!check_color(ctx, type, format, unpack, pixels, size, pitch)) { +	 return GL_FALSE; +      } +      if (!check_color_per_fragment_ops(ctx)) { +	 return GL_FALSE; +      } +      break; + +   default: +      return GL_FALSE; +   } + +   LOCK_HARDWARE_QUIESCENT( mmesa ); + +   if (mmesa->dirty_cliprects & MGA_FRONT) +      mgaUpdateRects( mmesa, MGA_FRONT ); + +   if ( IS_AGP_MEM(mmesa, (char *)pixels) && +	IS_AGP_MEM(mmesa, (char *)pixels + size) ) +   { +      do_draw_pix( ctx, x, y, width, height, pitch, pixels, +		   dest, planemask ); +      UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT ); +   } +   else +   { +      /* Pixels is in regular memory -- get dma buffers and perform +       * upload through them. +       */ +/*        drmBufPtr buf = mgaGetBufferLocked(mmesa); */ +      GLuint bufferpitch = (width*cpp+31)&~31; + +      char *address = 0; /*  mmesa->mgaScreen->agp.map; */ + +      do { +/*  	 GLuint rows = MIN2( height, MGA_DMA_BUF_SZ / bufferpitch ); */ +	 GLuint rows = height; + + +	 if (0) fprintf(stderr, "trying to upload %d rows (pitch %d)\n", +			rows, bufferpitch); + +	 /* The texture conversion code is so slow that there is only +	  * negligble speedup when the buffers/images don't exactly +	  * match: +	  */ +#if 0 +	 if (cpp == 2) { +	    if (!_mesa_convert_texsubimage2d( MESA_FORMAT_RGB565, +					      0, 0, width, rows, +					      bufferpitch, format, type, +					      unpack, pixels, address )) { +/*  	       mgaReleaseBufLocked( mmesa, buf ); */ +	       UNLOCK_HARDWARE(mmesa); +	       return GL_FALSE; +	    } +	 } else { +	    if (!_mesa_convert_texsubimage2d( MESA_FORMAT_ARGB8888, +					      0, 0, width, rows, +					      bufferpitch, format, type, +					      unpack, pixels, address )) { +/*  	       mgaReleaseBufLocked( mmesa, buf ); */ +	       UNLOCK_HARDWARE(mmesa); +	       return GL_FALSE; +	    } +	 } +#else +	 memcpy( address, pixels, rows*bufferpitch ); +#endif + +	 do_draw_pix( ctx, x, y, width, rows, +		      bufferpitch/cpp, address, dest, planemask ); + +	 /* Fix me -- use multiple buffers to avoid flush. +	  */ +	 UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT ); + +	 pixels = (void *)((char *) pixels + rows * pitch); +	 height -= rows; +	 y += rows; +      } while (height); + +/*        mgaReleaseBufLocked( mmesa, buf ); */ +   } + +   UNLOCK_HARDWARE( mmesa ); +   mmesa->dirty |= MGA_UPLOAD_CLIPRECTS; + +   return GL_TRUE; +} + +static void +mgaDDDrawPixels( GLcontext *ctx, +		 GLint x, GLint y, GLsizei width, GLsizei height, +		 GLenum format, GLenum type, +		 const struct gl_pixelstore_attrib *unpack, +		 const GLvoid *pixels ) +{ +   if (!mgaTryDrawPixels( ctx, x, y, width, height, format, type, +			  unpack, pixels )) +      _swrast_DrawPixels( ctx, x, y, width, height, format, type, +			  unpack, pixels ); +} + + + +/* Stub functions - not a real allocator, always returns pointer to + * the same block of agp space which isn't used for anything else at + * present. + */ +#if defined(MESA_hacked_agp_allocator) +static void mgaDDFreeAgpMemory( GLcontext *ctx, void *ptr ) +{ +   (void) ptr; +} + +static void *mgaDDAllocateAgpMemory( GLcontext *ctx, GLsizei size ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); + +   if (size < mmesa->mgaScreen->textureSize[MGA_AGP_HEAP]) +      return mmesa->mgaScreen->texVirtual[MGA_AGP_HEAP]; +   else +      return 0; +} + +static GLint mgaDDGetAgpOffset( GLcontext *ctx, const void *ptr ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); + +   if (!IS_AGP_MEM(mmesa, ptr)) +      return -1; + +   return AGP_OFFSET(mmesa, ptr); +} +#endif + + +void mgaDDInitPixelFuncs( GLcontext *ctx ) +{ +#if defined (MESA_experimetal_agp_allocator) +   ctx->Driver.AllocateAgpMemory = mgaDDAllocateAgpMemory; +   ctx->Driver.GetAgpOffset = mgaDDGetAgpOffset; +   ctx->Driver.FreeAgpMemory = mgaDDFreeAgpMemory; +#endif + +   /* 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; + +   if (getenv("MGA_BLIT_PIXELS")) { +      ctx->Driver.ReadPixels = mgaDDReadPixels; /* requires agp dest */ +      ctx->Driver.DrawPixels = mgaDDDrawPixels; /* works with agp/normal mem */ +   } +} diff --git a/src/mesa/drivers/dri/mga/mgapixel.h b/src/mesa/drivers/dri/mga/mgapixel.h new file mode 100644 index 0000000000..c44fd769a8 --- /dev/null +++ b/src/mesa/drivers/dri/mga/mgapixel.h @@ -0,0 +1,36 @@ +/* + * Copyright 2000-2001 Compaq Computer Inc. VA Linux Systems, Inc. + * 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 + * VA LINUX SYSTEMS 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> + */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgapixel.h,v 1.5 2002/10/30 12:51:36 alanh Exp $ */ + +#ifndef MGA_PIXELS_H +#define MGA_PIXELS_H + +#include "mtypes.h" + +extern void mgaDDInitPixelFuncs( GLcontext *ctx ); + +#endif diff --git a/src/mesa/drivers/dri/mga/mgaregs.h b/src/mesa/drivers/dri/mga/mgaregs.h new file mode 100644 index 0000000000..f07dc2de0b --- /dev/null +++ b/src/mesa/drivers/dri/mga/mgaregs.h @@ -0,0 +1,1381 @@ +/* author: stephen crowley, crow@debian.org */ + +/* + * 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 + * STEPHEN CROWLEY, 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. + */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaregs.h,v 1.6 2003/01/12 03:55:46 tsi Exp $ */ + +#ifndef _MGAREGS_H_ +#define _MGAREGS_H_ + +/*************** (START) AUTOMATICLY GENERATED REGISTER FILE *****************/ +/* + * Generated on Wed Jan 26 13:44:46 MST 2000 + */ + + + +/* + * Power Graphic Mode Memory Space Registers + */ + +#define MGAREG_MGA_EXEC 			0x0100 +#define MGAREG_AGP_PLL 			0x1e4c + +#    define AGP_PLL_agp2xpllen_MASK 	0xfffffffe 	/* bit 0 */ +#    define AGP_PLL_agp2xpllen_disable 	0x0 		 +#    define AGP_PLL_agp2xpllen_enable 	0x1 		 + +#define MGAREG_CFG_OR 				0x1e4c + +#    define CFG_OR_comp_or_MASK 	0xfffffff7 	/* bit 3 */ +#    define CFG_OR_comp_or_disable 	0x0 		 +#    define CFG_OR_comp_or_enable 	0x8 		 +#    define CFG_OR_compfreq_MASK 	0xffffff0f 	/* bits 4-7 */ +#    define CFG_OR_compfreq_SHIFT 	4 		 +#    define CFG_OR_comporup_MASK 	0xfffff0ff 	/* bits 8-11 */ +#    define CFG_OR_comporup_SHIFT 	8 		 +#    define CFG_OR_compordn_MASK 	0xffff0fff 	/* bits 12-15 */ +#    define CFG_OR_compordn_SHIFT 	12 		 +#    define CFG_OR_e2pq_MASK 		0xfffeffff 	/* bit 16 */ +#    define CFG_OR_e2pq_disable 	0x0 		 +#    define CFG_OR_e2pq_enable 		0x10000 	 +#    define CFG_OR_e2pqbypcsn_MASK 	0xfffdffff 	/* bit 17 */ +#    define CFG_OR_e2pqbypcsn_disable 	0x0 		 +#    define CFG_OR_e2pqbypcsn_enable 	0x20000 	 +#    define CFG_OR_e2pqbypd_MASK 	0xfffbffff 	/* bit 18 */ +#    define CFG_OR_e2pqbypd_disable 	0x0 		 +#    define CFG_OR_e2pqbypd_enable 	0x40000 	 +#    define CFG_OR_e2pbypclk_MASK 	0xfff7ffff 	/* bit 19 */ +#    define CFG_OR_e2pbypclk_disable 	0x0 		 +#    define CFG_OR_e2pbypclk_enable 	0x80000 	 +#    define CFG_OR_e2pbyp_MASK 		0xffefffff 	/* bit 20 */ +#    define CFG_OR_e2pbyp_disable 	0x0 		 +#    define CFG_OR_e2pbyp_enable 	0x100000 	 +#    define CFG_OR_rate_cap_or_MASK 	0xff1fffff 	/* bits 21-23 */ +#    define CFG_OR_rate_cap_or_SHIFT 	21 		 +#    define CFG_OR_rq_or_MASK 		0xe0ffffff 	/* bits 24-28 */ +#    define CFG_OR_rq_or_SHIFT 		24 		 + +#define MGAREG_ALPHACTRL 			0x2c7c + +#    define AC_src_MASK 		0xfffffff0 	/* bits 0-3 */ +#    define AC_src_zero 		0x0 		/* val 0, shift 0 */ +#    define AC_src_one 			0x1 		/* val 1, shift 0 */ +#    define AC_src_dst_color 		0x2 		/* val 2, shift 0 */ +#    define AC_src_om_dst_color 	0x3 		/* val 3, shift 0 */ +#    define AC_src_src_alpha 		0x4 		/* val 4, shift 0 */ +#    define AC_src_om_src_alpha 	0x5 		/* val 5, shift 0 */ +#    define AC_src_dst_alpha 		0x6 		/* val 6, shift 0 */ +#    define AC_src_om_dst_alpha 	0x7 		/* val 7, shift 0 */ +#    define AC_src_src_alpha_sat 	0x8 		/* val 8, shift 0 */ +#    define AC_dst_MASK 		0xffffff0f 	/* bits 4-7 */ +#    define AC_dst_zero 		0x0 		/* val 0, shift 4 */ +#    define AC_dst_one 			0x10 		/* val 1, shift 4 */ +#    define AC_dst_src_color 		0x20 		/* val 2, shift 4 */ +#    define AC_dst_om_src_color 	0x30 		/* val 3, shift 4 */ +#    define AC_dst_src_alpha 		0x40 		/* val 4, shift 4 */ +#    define AC_dst_om_src_alpha 	0x50 		/* val 5, shift 4 */ +#    define AC_dst_dst_alpha 		0x60 		/* val 6, shift 4 */ +#    define AC_dst_om_dst_alpha 	0x70 		/* val 7, shift 4 */ +#    define AC_amode_MASK 		0xfffffcff 	/* bits 8-9 */ +#    define AC_amode_FCOL 		0x0 		/* val 0, shift 8 */ +#    define AC_amode_alpha_channel 	0x100 		/* val 1, shift 8 */ +#    define AC_amode_video_alpha 	0x200 		/* val 2, shift 8 */ +#    define AC_amode_RSVD 		0x300 		/* val 3, shift 8 */ +#    define AC_astipple_MASK 		0xfffff7ff 	/* bit 11 */ +#    define AC_astipple_disable 	0x0 		 +#    define AC_astipple_enable 		0x800 		 +#    define AC_aten_MASK 		0xffffefff 	/* bit 12 */ +#    define AC_aten_disable 		0x0 		 +#    define AC_aten_enable 		0x1000 		 +#    define AC_atmode_MASK 		0xffff1fff 	/* bits 13-15 */ +#    define AC_atmode_noacmp 		0x0 		/* val 0, shift 13 */ +#    define AC_atmode_ae 		0x4000 		/* val 2, shift 13 */ +#    define AC_atmode_ane 		0x6000 		/* val 3, shift 13 */ +#    define AC_atmode_alt 		0x8000 		/* val 4, shift 13 */ +#    define AC_atmode_alte 		0xa000 		/* val 5, shift 13 */ +#    define AC_atmode_agt 		0xc000 		/* val 6, shift 13 */ +#    define AC_atmode_agte 		0xe000 		/* val 7, shift 13 */ +#    define AC_atref_MASK 		0xff00ffff 	/* bits 16-23 */ +#    define AC_atref_SHIFT 		16 		 +#    define AC_alphasel_MASK 		0xfcffffff 	/* bits 24-25 */ +#    define AC_alphasel_fromtex 	0x0 		/* val 0, shift 24 */ +#    define AC_alphasel_diffused 	0x1000000 	/* val 1, shift 24 */ +#    define AC_alphasel_modulated 	0x2000000 	/* val 2, shift 24 */ +#    define AC_alphasel_trans 		0x3000000 	/* val 3, shift 24 */ + +#define MGAREG_ALPHASTART 			0x2c70 +#define MGAREG_ALPHAXINC 			0x2c74 +#define MGAREG_ALPHAYINC 			0x2c78 +#define MGAREG_AR0 				0x1c60 + +#    define AR0_ar0_MASK 		0xfffc0000 	/* bits 0-17 */ +#    define AR0_ar0_SHIFT 		0 		 + +#define MGAREG_AR1 				0x1c64 + +#    define AR1_ar1_MASK 		0xff000000 	/* bits 0-23 */ +#    define AR1_ar1_SHIFT 		0 		 + +#define MGAREG_AR2 				0x1c68 + +#    define AR2_ar2_MASK 		0xfffc0000 	/* bits 0-17 */ +#    define AR2_ar2_SHIFT 		0 		 + +#define MGAREG_AR3 				0x1c6c + +#    define AR3_ar3_MASK 		0xff000000 	/* bits 0-23 */ +#    define AR3_ar3_SHIFT 		0 		 +#    define AR3_spage_MASK 		0xf8ffffff 	/* bits 24-26 */ +#    define AR3_spage_SHIFT 		24 		 + +#define MGAREG_AR4 				0x1c70 + +#    define AR4_ar4_MASK 		0xfffc0000 	/* bits 0-17 */ +#    define AR4_ar4_SHIFT 		0 		 + +#define MGAREG_AR5 				0x1c74 + +#    define AR5_ar5_MASK 		0xfffc0000 	/* bits 0-17 */ +#    define AR5_ar5_SHIFT 		0 		 + +#define MGAREG_AR6 				0x1c78 + +#    define AR6_ar6_MASK 		0xfffc0000 	/* bits 0-17 */ +#    define AR6_ar6_SHIFT 		0 		 + +#define MGAREG_BCOL 				0x1c20 +#define MGAREG_BESA1CORG 			0x3d10 +#define MGAREG_BESA1ORG 			0x3d00 +#define MGAREG_BESA2CORG 			0x3d14 +#define MGAREG_BESA2ORG 			0x3d04 +#define MGAREG_BESB1CORG 			0x3d18 +#define MGAREG_BESB1ORG 			0x3d08 +#define MGAREG_BESB2CORG 			0x3d1c +#define MGAREG_BESB2ORG 			0x3d0c +#define MGAREG_BESCTL 				0x3d20 + +#    define BC_besen_MASK 		0xfffffffe 	/* bit 0 */ +#    define BC_besen_disable 		0x0 		 +#    define BC_besen_enable 		0x1 		 +#    define BC_besv1srcstp_MASK 	0xffffffbf 	/* bit 6 */ +#    define BC_besv1srcstp_even 	0x0 		 +#    define BC_besv1srcstp_odd 		0x40 		 +#    define BC_besv2srcstp_MASK 	0xfffffeff 	/* bit 8 */ +#    define BC_besv2srcstp_disable 	0x0 		 +#    define BC_besv2srcstp_enable 	0x100 		 +#    define BC_beshfen_MASK 		0xfffffbff 	/* bit 10 */ +#    define BC_beshfen_disable 		0x0 		 +#    define BC_beshfen_enable 		0x400 		 +#    define BC_besvfen_MASK 		0xfffff7ff 	/* bit 11 */ +#    define BC_besvfen_disable 		0x0 		 +#    define BC_besvfen_enable 		0x800 		 +#    define BC_beshfixc_MASK 		0xffffefff 	/* bit 12 */ +#    define BC_beshfixc_weight 		0x0 		 +#    define BC_beshfixc_coeff 		0x1000 		 +#    define BC_bescups_MASK 		0xfffeffff 	/* bit 16 */ +#    define BC_bescups_disable 		0x0 		 +#    define BC_bescups_enable 		0x10000 	 +#    define BC_bes420pl_MASK 		0xfffdffff 	/* bit 17 */ +#    define BC_bes420pl_422 		0x0 		 +#    define BC_bes420pl_420 		0x20000 	 +#    define BC_besdith_MASK 		0xfffbffff 	/* bit 18 */ +#    define BC_besdith_disable 		0x0 		 +#    define BC_besdith_enable 		0x40000 	 +#    define BC_beshmir_MASK 		0xfff7ffff 	/* bit 19 */ +#    define BC_beshmir_disable 		0x0 		 +#    define BC_beshmir_enable 		0x80000 	 +#    define BC_besbwen_MASK 		0xffefffff 	/* bit 20 */ +#    define BC_besbwen_color 		0x0 		 +#    define BC_besbwen_bw 		0x100000 	 +#    define BC_besblank_MASK 		0xffdfffff 	/* bit 21 */ +#    define BC_besblank_disable 	0x0 		 +#    define BC_besblank_enable 		0x200000 	 +#    define BC_besfselm_MASK 		0xfeffffff 	/* bit 24 */ +#    define BC_besfselm_soft 		0x0 		 +#    define BC_besfselm_hard 		0x1000000 	 +#    define BC_besfsel_MASK 		0xf9ffffff 	/* bits 25-26 */ +#    define BC_besfsel_a1 		0x0 		/* val 0, shift 25 */ +#    define BC_besfsel_a2 		0x2000000 	/* val 1, shift 25 */ +#    define BC_besfsel_b1 		0x4000000 	/* val 2, shift 25 */ +#    define BC_besfsel_b2 		0x6000000 	/* val 3, shift 25 */ + +#define MGAREG_BESGLOBCTL 			0x3dc0 + +#    define BGC_beshzoom_MASK 		0xfffffffe 	/* bit 0 */ +#    define BGC_beshzoom_disable 	0x0 		 +#    define BGC_beshzoom_enable 	0x1 		 +#    define BGC_beshzoomf_MASK 		0xfffffffd 	/* bit 1 */ +#    define BGC_beshzoomf_disable 	0x0 		 +#    define BGC_beshzoomf_enable 	0x2 		 +#    define BGC_bescorder_MASK 		0xfffffff7 	/* bit 3 */ +#    define BGC_bescorder_even 		0x0 		 +#    define BGC_bescorder_odd 		0x8 		 +#    define BGC_besreghup_MASK 		0xffffffef 	/* bit 4 */ +#    define BGC_besreghup_disable 	0x0 		 +#    define BGC_besreghup_enable 	0x10 		 +#    define BGC_besvcnt_MASK 		0xf000ffff 	/* bits 16-27 */ +#    define BGC_besvcnt_SHIFT 		16 		 + +#define MGAREG_BESHCOORD 			0x3d28 + +#    define BHC_besright_MASK 		0xfffff800 	/* bits 0-10 */ +#    define BHC_besright_SHIFT 		0 		 +#    define BHC_besleft_MASK 		0xf800ffff 	/* bits 16-26 */ +#    define BHC_besleft_SHIFT 		16 		 + +#define MGAREG_BESHISCAL 			0x3d30 + +#    define BHISF_beshiscal_MASK 	0xffe00003 	/* bits 2-20 */ +#    define BHISF_beshiscal_SHIFT 	2 		 + +#define MGAREG_BESHSRCEND 			0x3d3c + +#    define BHSE_beshsrcend_MASK 	0xfc000003 	/* bits 2-25 */ +#    define BHSE_beshsrcend_SHIFT 	2 		 + +#define MGAREG_BESHSRCLST 			0x3d50 + +#    define BHSL_beshsrclst_MASK 	0xfc00ffff 	/* bits 16-25 */ +#    define BHSL_beshsrclst_SHIFT 	16 		 + +#define MGAREG_BESHSRCST 			0x3d38 + +#    define BHSS_beshsrcst_MASK 	0xfc000003 	/* bits 2-25 */ +#    define BHSS_beshsrcst_SHIFT 	2 		 + +#define MGAREG_BESPITCH 			0x3d24 + +#    define BP_bespitch_MASK 		0xfffff000 	/* bits 0-11 */ +#    define BP_bespitch_SHIFT 		0 		 + +#define MGAREG_BESSTATUS 			0x3dc4 + +#    define BS_besstat_MASK 		0xfffffffc 	/* bits 0-1 */ +#    define BS_besstat_a1 		0x0 		/* val 0, shift 0 */ +#    define BS_besstat_a2 		0x1 		/* val 1, shift 0 */ +#    define BS_besstat_b1 		0x2 		/* val 2, shift 0 */ +#    define BS_besstat_b2 		0x3 		/* val 3, shift 0 */ + +#define MGAREG_BESV1SRCLST 			0x3d54 + +#    define BSF_besv1srclast_MASK 	0xfffffc00 	/* bits 0-9 */ +#    define BSF_besv1srclast_SHIFT 	0 		 + +#define MGAREG_BESV2SRCLST 			0x3d58 + +#    define BSF_besv2srclst_MASK 	0xfffffc00 	/* bits 0-9 */ +#    define BSF_besv2srclst_SHIFT 	0 		 + +#define MGAREG_BESV1WGHT 			0x3d48 + +#    define BSF_besv1wght_MASK 		0xffff0003 	/* bits 2-15 */ +#    define BSF_besv1wght_SHIFT 	2 		 +#    define BSF_besv1wghts_MASK 	0xfffeffff 	/* bit 16 */ +#    define BSF_besv1wghts_disable 	0x0 		 +#    define BSF_besv1wghts_enable 	0x10000 	 + +#define MGAREG_BESV2WGHT 			0x3d4c + +#    define BSF_besv2wght_MASK 		0xffff0003 	/* bits 2-15 */ +#    define BSF_besv2wght_SHIFT 	2 		 +#    define BSF_besv2wghts_MASK 	0xfffeffff 	/* bit 16 */ +#    define BSF_besv2wghts_disable 	0x0 		 +#    define BSF_besv2wghts_enable 	0x10000 	 + +#define MGAREG_BESVCOORD 			0x3d2c + +#    define BVC_besbot_MASK 		0xfffff800 	/* bits 0-10 */ +#    define BVC_besbot_SHIFT 		0 		 +#    define BVC_bestop_MASK 		0xf800ffff 	/* bits 16-26 */ +#    define BVC_bestop_SHIFT 		16 		 + +#define MGAREG_BESVISCAL 			0x3d34 + +#    define BVISF_besviscal_MASK 	0xffe00003 	/* bits 2-20 */ +#    define BVISF_besviscal_SHIFT 	2 		 + +#define MGAREG_CODECADDR 			0x3e44 +#define MGAREG_CODECCTL 			0x3e40 +#define MGAREG_CODECHARDPTR 			0x3e4c +#define MGAREG_CODECHOSTPTR 			0x3e48 +#define MGAREG_CODECLCODE 			0x3e50 +#define MGAREG_CXBNDRY 			0x1c80 + +#    define CXB_cxleft_MASK 		0xfffff000 	/* bits 0-11 */ +#    define CXB_cxleft_SHIFT 		0 		 +#    define CXB_cxright_MASK 		0xf000ffff 	/* bits 16-27 */ +#    define CXB_cxright_SHIFT 		16 		 + +#define MGAREG_CXLEFT 				0x1ca0 +#define MGAREG_CXRIGHT 			0x1ca4 +#define MGAREG_DMAMAP30 			0x1e30 +#define MGAREG_DMAMAP74 			0x1e34 +#define MGAREG_DMAMAPB8 			0x1e38 +#define MGAREG_DMAMAPFC 			0x1e3c +#define MGAREG_DMAPAD 				0x1c54 +#define MGAREG_DR0_Z32LSB 			0x2c50 +#define MGAREG_DR0_Z32MSB 			0x2c54 +#define MGAREG_DR2_Z32LSB 			0x2c60 +#define MGAREG_DR2_Z32MSB 			0x2c64 +#define MGAREG_DR3_Z32LSB 			0x2c68 +#define MGAREG_DR3_Z32MSB 			0x2c6c +#define MGAREG_DR0 				0x1cc0 +#define MGAREG_DR2 				0x1cc8 +#define MGAREG_DR3 				0x1ccc +#define MGAREG_DR4 				0x1cd0 +#define MGAREG_DR6 				0x1cd8 +#define MGAREG_DR7 				0x1cdc +#define MGAREG_DR8 				0x1ce0 +#define MGAREG_DR10 				0x1ce8 +#define MGAREG_DR11 				0x1cec +#define MGAREG_DR12 				0x1cf0 +#define MGAREG_DR14 				0x1cf8 +#define MGAREG_DR15 				0x1cfc +#define MGAREG_DSTORG 				0x2cb8 + +#    define DO_dstmap_MASK 		0xfffffffe 	/* bit 0 */ +#    define DO_dstmap_fb 		0x0 		 +#    define DO_dstmap_sys 		0x1 		 +#    define DO_dstacc_MASK 		0xfffffffd 	/* bit 1 */ +#    define DO_dstacc_pci 		0x0 		 +#    define DO_dstacc_agp 		0x2 		 +#    define DO_dstorg_MASK 		0x7 		/* bits 3-31 */ +#    define DO_dstorg_SHIFT 		3 		 + +#define MGAREG_DWG_INDIR_WT 			0x1e80 +#define MGAREG_DWGCTL 				0x1c00 + +#    define DC_opcod_MASK 		0xfffffff0 	/* bits 0-3 */ +#    define DC_opcod_line_open 		0x0 		/* val 0, shift 0 */ +#    define DC_opcod_autoline_open 	0x1 		/* val 1, shift 0 */ +#    define DC_opcod_line_close 	0x2 		/* val 2, shift 0 */ +#    define DC_opcod_autoline_close 	0x3 		/* val 3, shift 0 */ +#    define DC_opcod_trap 		0x4 		/* val 4, shift 0 */ +#    define DC_opcod_texture_trap 	0x6 		/* val 6, shift 0 */ +#    define DC_opcod_bitblt 		0x8 		/* val 8, shift 0 */ +#    define DC_opcod_iload 		0x9 		/* val 9, shift 0 */ +#    define DC_atype_MASK 		0xffffff8f 	/* bits 4-6 */ +#    define DC_atype_rpl 		0x0 		/* val 0, shift 4 */ +#    define DC_atype_rstr 		0x10 		/* val 1, shift 4 */ +#    define DC_atype_zi 		0x30 		/* val 3, shift 4 */ +#    define DC_atype_blk 		0x40 		/* val 4, shift 4 */ +#    define DC_atype_i 			0x70 		/* val 7, shift 4 */ +#    define DC_linear_MASK 		0xffffff7f 	/* bit 7 */ +#    define DC_linear_xy 		0x0 		 +#    define DC_linear_linear 		0x80 		 +#    define DC_zmode_MASK 		0xfffff8ff 	/* bits 8-10 */ +#    define DC_zmode_nozcmp 		0x0 		/* val 0, shift 8 */ +#    define DC_zmode_ze 		0x200 		/* val 2, shift 8 */ +#    define DC_zmode_zne 		0x300 		/* val 3, shift 8 */ +#    define DC_zmode_zlt 		0x400 		/* val 4, shift 8 */ +#    define DC_zmode_zlte 		0x500 		/* val 5, shift 8 */ +#    define DC_zmode_zgt 		0x600 		/* val 6, shift 8 */ +#    define DC_zmode_zgte 		0x700 		/* val 7, shift 8 */ +#    define DC_solid_MASK 		0xfffff7ff 	/* bit 11 */ +#    define DC_solid_disable 		0x0 		 +#    define DC_solid_enable 		0x800 		 +#    define DC_arzero_MASK 		0xffffefff 	/* bit 12 */ +#    define DC_arzero_disable 		0x0 		 +#    define DC_arzero_enable 		0x1000 		 +#    define DC_sgnzero_MASK 		0xffffdfff 	/* bit 13 */ +#    define DC_sgnzero_disable 		0x0 		 +#    define DC_sgnzero_enable 		0x2000 		 +#    define DC_shftzero_MASK 		0xffffbfff 	/* bit 14 */ +#    define DC_shftzero_disable 	0x0 		 +#    define DC_shftzero_enable 		0x4000 		 +#    define DC_bop_MASK 		0xfff0ffff 	/* bits 16-19 */ +#    define DC_bop_SHIFT 		16 		 +#    define DC_trans_MASK 		0xff0fffff 	/* bits 20-23 */ +#    define DC_trans_SHIFT 		20 		 +#    define DC_bltmod_MASK 		0xe1ffffff 	/* bits 25-28 */ +#    define DC_bltmod_bmonolef 		0x0 		/* val 0, shift 25 */ +#    define DC_bltmod_bmonowf 		0x8000000 	/* val 4, shift 25 */ +#    define DC_bltmod_bplan 		0x2000000 	/* val 1, shift 25 */ +#    define DC_bltmod_bfcol 		0x4000000 	/* val 2, shift 25 */ +#    define DC_bltmod_bu32bgr 		0x6000000 	/* val 3, shift 25 */ +#    define DC_bltmod_bu32rgb 		0xe000000 	/* val 7, shift 25 */ +#    define DC_bltmod_bu24bgr 		0x16000000 	/* val 11, shift 25 */ +#    define DC_bltmod_bu24rgb 		0x1e000000 	/* val 15, shift 25 */ +#    define DC_pattern_MASK 		0xdfffffff 	/* bit 29 */ +#    define DC_pattern_disable 		0x0 		 +#    define DC_pattern_enable 		0x20000000 	 +#    define DC_transc_MASK 		0xbfffffff 	/* bit 30 */ +#    define DC_transc_disable 		0x0 		 +#    define DC_transc_enable 		0x40000000 	 +#    define DC_clipdis_MASK 		0x7fffffff 	/* bit 31 */ +#    define DC_clipdis_disable 		0x0 		 +#    define DC_clipdis_enable 		0x80000000 	 + +#define MGAREG_DWGSYNC 			0x2c4c + +#    define DS_dwgsyncaddr_MASK 	0x3 		/* bits 2-31 */ +#    define DS_dwgsyncaddr_SHIFT 	2 		 + +#define MGAREG_FCOL 				0x1c24 +#define MGAREG_FIFOSTATUS 			0x1e10 + +#    define FS_fifocount_MASK 		0xffffff80 	/* bits 0-6 */ +#    define FS_fifocount_SHIFT 		0 		 +#    define FS_bfull_MASK 		0xfffffeff 	/* bit 8 */ +#    define FS_bfull_disable 		0x0 		 +#    define FS_bfull_enable 		0x100 		 +#    define FS_bempty_MASK 		0xfffffdff 	/* bit 9 */ +#    define FS_bempty_disable 		0x0 		 +#    define FS_bempty_enable 		0x200 		 + +#define MGAREG_FOGCOL 				0x1cf4 +#define MGAREG_FOGSTART 			0x1cc4 +#define MGAREG_FOGXINC 			0x1cd4 +#define MGAREG_FOGYINC 			0x1ce4 +#define MGAREG_FXBNDRY 			0x1c84 + +#    define XA_fxleft_MASK 		0xffff0000 	/* bits 0-15 */ +#    define XA_fxleft_SHIFT 		0 		 +#    define XA_fxright_MASK 		0xffff 		/* bits 16-31 */ +#    define XA_fxright_SHIFT 		16 		 + +#define MGAREG_FXLEFT 				0x1ca8 +#define MGAREG_FXRIGHT 			0x1cac +#define MGAREG_ICLEAR 				0x1e18 + +#    define IC_softrapiclr_MASK 	0xfffffffe 	/* bit 0 */ +#    define IC_softrapiclr_disable 	0x0 		 +#    define IC_softrapiclr_enable 	0x1 		 +#    define IC_pickiclr_MASK 		0xfffffffb 	/* bit 2 */ +#    define IC_pickiclr_disable 	0x0 		 +#    define IC_pickiclr_enable 		0x4 		 +#    define IC_vlineiclr_MASK 		0xffffffdf 	/* bit 5 */ +#    define IC_vlineiclr_disable 	0x0 		 +#    define IC_vlineiclr_enable 	0x20 		 +#    define IC_wiclr_MASK 		0xffffff7f 	/* bit 7 */ +#    define IC_wiclr_disable 		0x0 		 +#    define IC_wiclr_enable 		0x80 		 +#    define IC_wciclr_MASK 		0xfffffeff 	/* bit 8 */ +#    define IC_wciclr_disable 		0x0 		 +#    define IC_wciclr_enable 		0x100 		 + +#define MGAREG_IEN 				0x1e1c + +#    define IE_softrapien_MASK 		0xfffffffe 	/* bit 0 */ +#    define IE_softrapien_disable 	0x0 		 +#    define IE_softrapien_enable 	0x1 		 +#    define IE_pickien_MASK 		0xfffffffb 	/* bit 2 */ +#    define IE_pickien_disable 		0x0 		 +#    define IE_pickien_enable 		0x4 		 +#    define IE_vlineien_MASK 		0xffffffdf 	/* bit 5 */ +#    define IE_vlineien_disable 	0x0 		 +#    define IE_vlineien_enable 		0x20 		 +#    define IE_extien_MASK 		0xffffffbf 	/* bit 6 */ +#    define IE_extien_disable 		0x0 		 +#    define IE_extien_enable 		0x40 		 +#    define IE_wien_MASK 		0xffffff7f 	/* bit 7 */ +#    define IE_wien_disable 		0x0 		 +#    define IE_wien_enable 		0x80 		 +#    define IE_wcien_MASK 		0xfffffeff 	/* bit 8 */ +#    define IE_wcien_disable 		0x0 		 +#    define IE_wcien_enable 		0x100 		 + +#define MGAREG_LEN 				0x1c5c +#define MGAREG_MACCESS 			0x1c04 + +#    define MA_pwidth_MASK 		0xfffffffc 	/* bits 0-1 */ +#    define MA_pwidth_8 		0x0 		/* val 0, shift 0 */ +#    define MA_pwidth_16 		0x1 		/* val 1, shift 0 */ +#    define MA_pwidth_32 		0x2 		/* val 2, shift 0 */ +#    define MA_pwidth_24 		0x3 		/* val 3, shift 0 */ +#    define MA_zwidth_MASK 		0xffffffe7 	/* bits 3-4 */ +#    define MA_zwidth_16 		0x0 		/* val 0, shift 3 */ +#    define MA_zwidth_32 		0x8 		/* val 1, shift 3 */ +#    define MA_zwidth_15 		0x10 		/* val 2, shift 3 */ +#    define MA_zwidth_24 		0x18 		/* val 3, shift 3 */ +#    define MA_memreset_MASK 		0xffff7fff 	/* bit 15 */ +#    define MA_memreset_disable 	0x0 		 +#    define MA_memreset_enable 		0x8000 		 +#    define MA_fogen_MASK 		0xfbffffff 	/* bit 26 */ +#    define MA_fogen_disable 		0x0 		 +#    define MA_fogen_enable 		0x4000000 	 +#    define MA_tlutload_MASK 		0xdfffffff 	/* bit 29 */ +#    define MA_tlutload_disable 	0x0 		 +#    define MA_tlutload_enable 		0x20000000 	 +#    define MA_nodither_MASK 		0xbfffffff 	/* bit 30 */ +#    define MA_nodither_disable 	0x0 		 +#    define MA_nodither_enable 		0x40000000 	 +#    define MA_dit555_MASK 		0x7fffffff 	/* bit 31 */ +#    define MA_dit555_disable 		0x0 		 +#    define MA_dit555_enable 		0x80000000 	 + +#define MGAREG_MCTLWTST 			0x1c08 + +#    define MCWS_casltncy_MASK 		0xfffffff8 	/* bits 0-2 */ +#    define MCWS_casltncy_SHIFT 	0 		 +#    define MCWS_rrddelay_MASK 		0xffffffcf 	/* bits 4-5 */ +#    define MCWS_rcddelay_MASK 		0xfffffe7f 	/* bits 7-8 */ +#    define MCWS_rasmin_MASK 		0xffffe3ff 	/* bits 10-12 */ +#    define MCWS_rasmin_SHIFT 		10 		 +#    define MCWS_rpdelay_MASK 		0xffff3fff 	/* bits 14-15 */ +#    define MCWS_wrdelay_MASK 		0xfff3ffff 	/* bits 18-19 */ +#    define MCWS_rddelay_MASK 		0xffdfffff 	/* bit 21 */ +#    define MCWS_rddelay_disable 	0x0 		 +#    define MCWS_rddelay_enable 	0x200000 	 +#    define MCWS_smrdelay_MASK 		0xfe7fffff 	/* bits 23-24 */ +#    define MCWS_bwcdelay_MASK 		0xf3ffffff 	/* bits 26-27 */ +#    define MCWS_bpldelay_MASK 		0x1fffffff 	/* bits 29-31 */ +#    define MCWS_bpldelay_SHIFT 	29 		 + +#define MGAREG_MEMRDBK 			0x1e44 + +#    define MRB_mclkbrd0_MASK 		0xfffffff0 	/* bits 0-3 */ +#    define MRB_mclkbrd0_SHIFT 		0 		 +#    define MRB_mclkbrd1_MASK 		0xfffffe1f 	/* bits 5-8 */ +#    define MRB_mclkbrd1_SHIFT 		5 		 +#    define MRB_strmfctl_MASK 		0xff3fffff 	/* bits 22-23 */ +#    define MRB_mrsopcod_MASK 		0xe1ffffff 	/* bits 25-28 */ +#    define MRB_mrsopcod_SHIFT 		25 		 + +#define MGAREG_OPMODE 				0x1e54 + +#    define OM_dmamod_MASK 		0xfffffff3 	/* bits 2-3 */ +#    define OM_dmamod_general 		0x0 		/* val 0, shift 2 */ +#    define OM_dmamod_blit 		0x4 		/* val 1, shift 2 */ +#    define OM_dmamod_vector 		0x8 		/* val 2, shift 2 */ +#    define OM_dmamod_vertex 		0xc 		/* val 3, shift 2 */ +#    define OM_dmadatasiz_MASK 		0xfffffcff 	/* bits 8-9 */ +#    define OM_dmadatasiz_8 		0x0 		/* val 0, shift 8 */ +#    define OM_dmadatasiz_16 		0x100 		/* val 1, shift 8 */ +#    define OM_dmadatasiz_32 		0x200 		/* val 2, shift 8 */ +#    define OM_dirdatasiz_MASK 		0xfffcffff 	/* bits 16-17 */ +#    define OM_dirdatasiz_8 		0x0 		/* val 0, shift 16 */ +#    define OM_dirdatasiz_16 		0x10000 	/* val 1, shift 16 */ +#    define OM_dirdatasiz_32 		0x20000 	/* val 2, shift 16 */ + +#define MGAREG_PAT0 				0x1c10 +#define MGAREG_PAT1 				0x1c14 +#define MGAREG_PITCH 				0x1c8c + +#    define P_iy_MASK 			0xffffe000 	/* bits 0-12 */ +#    define P_iy_SHIFT 			0 		 +#    define P_ylin_MASK 		0xffff7fff 	/* bit 15 */ +#    define P_ylin_disable 		0x0 		 +#    define P_ylin_enable 		0x8000 		 + +#define MGAREG_PLNWT 				0x1c1c +#define MGAREG_PRIMADDRESS 			0x1e58 + +#    define PDCA_primod_MASK 		0xfffffffc 	/* bits 0-1 */ +#    define PDCA_primod_general 	0x0 		/* val 0, shift 0 */ +#    define PDCA_primod_blit 		0x1 		/* val 1, shift 0 */ +#    define PDCA_primod_vector 		0x2 		/* val 2, shift 0 */ +#    define PDCA_primod_vertex 		0x3 		/* val 3, shift 0 */ +#    define PDCA_primaddress_MASK 	0x3 		/* bits 2-31 */ +#    define PDCA_primaddress_SHIFT 	2 		 + +#define MGAREG_PRIMEND 			0x1e5c + +#    define PDEA_primnostart_MASK 	0xfffffffe 	/* bit 0 */ +#    define PDEA_primnostart_disable 	0x0 		 +#    define PDEA_primnostart_enable 	0x1 		 +#    define PDEA_pagpxfer_MASK 		0xfffffffd 	/* bit 1 */ +#    define PDEA_pagpxfer_disable 	0x0 		 +#    define PDEA_pagpxfer_enable 	0x2 		 +#    define PDEA_primend_MASK 		0x3 		/* bits 2-31 */ +#    define PDEA_primend_SHIFT 		2 		 + +#define MGAREG_PRIMPTR 			0x1e50 + +#    define PLS_primptren0_MASK 	0xfffffffe 	/* bit 0 */ +#    define PLS_primptren0_disable 	0x0 		 +#    define PLS_primptren0_enable 	0x1 		 +#    define PLS_primptren1_MASK 	0xfffffffd 	/* bit 1 */ +#    define PLS_primptren1_disable 	0x0 		 +#    define PLS_primptren1_enable 	0x2 		 +#    define PLS_primptr_MASK 		0x7 		/* bits 3-31 */ +#    define PLS_primptr_SHIFT 		3 		 + +#define MGAREG_RST 				0x1e40 + +#    define R_softreset_MASK 		0xfffffffe 	/* bit 0 */ +#    define R_softreset_disable 	0x0 		 +#    define R_softreset_enable 		0x1 		 +#    define R_softextrst_MASK 		0xfffffffd 	/* bit 1 */ +#    define R_softextrst_disable 	0x0 		 +#    define R_softextrst_enable 	0x2 		 + +#define MGAREG_SECADDRESS 			0x2c40 + +#    define SDCA_secmod_MASK 		0xfffffffc 	/* bits 0-1 */ +#    define SDCA_secmod_general 	0x0 		/* val 0, shift 0 */ +#    define SDCA_secmod_blit 		0x1 		/* val 1, shift 0 */ +#    define SDCA_secmod_vector 		0x2 		/* val 2, shift 0 */ +#    define SDCA_secmod_vertex 		0x3 		/* val 3, shift 0 */ +#    define SDCA_secaddress_MASK 	0x3 		/* bits 2-31 */ +#    define SDCA_secaddress_SHIFT 	2 		 + +#define MGAREG_SECEND 				0x2c44 + +#    define SDEA_sagpxfer_MASK 		0xfffffffd 	/* bit 1 */ +#    define SDEA_sagpxfer_disable 	0x0 		 +#    define SDEA_sagpxfer_enable 	0x2 		 +#    define SDEA_secend_MASK 		0x3 		/* bits 2-31 */ +#    define SDEA_secend_SHIFT 		2 		 + +#define MGAREG_SETUPADDRESS 			0x2cd0 + +#    define SETADD_mode_MASK 		0xfffffffc 	/* bits 0-1 */ +#    define SETADD_mode_vertlist 	0x0 		/* val 0, shift 0 */ +#    define SETADD_address_MASK 	0x3 		/* bits 2-31 */ +#    define SETADD_address_SHIFT 	2 		 + +#define MGAREG_SETUPEND 			0x2cd4 + +#    define SETEND_agpxfer_MASK 	0xfffffffd 	/* bit 1 */ +#    define SETEND_agpxfer_disable 	0x0 		 +#    define SETEND_agpxfer_enable 	0x2 		 +#    define SETEND_address_MASK 	0x3 		/* bits 2-31 */ +#    define SETEND_address_SHIFT 	2 		 + +#define MGAREG_SGN 				0x1c58 + +#    define S_sdydxl_MASK 		0xfffffffe 	/* bit 0 */ +#    define S_sdydxl_y 			0x0 		 +#    define S_sdydxl_x 			0x1 		 +#    define S_scanleft_MASK 		0xfffffffe 	/* bit 0 */ +#    define S_scanleft_disable 		0x0 		 +#    define S_scanleft_enable 		0x1 		 +#    define S_sdxl_MASK 		0xfffffffd 	/* bit 1 */ +#    define S_sdxl_pos 			0x0 		 +#    define S_sdxl_neg 			0x2 		 +#    define S_sdy_MASK 			0xfffffffb 	/* bit 2 */ +#    define S_sdy_pos 			0x0 		 +#    define S_sdy_neg 			0x4 		 +#    define S_sdxr_MASK 		0xffffffdf 	/* bit 5 */ +#    define S_sdxr_pos 			0x0 		 +#    define S_sdxr_neg 			0x20 		 +#    define S_brkleft_MASK 		0xfffffeff 	/* bit 8 */ +#    define S_brkleft_disable 		0x0 		 +#    define S_brkleft_enable 		0x100 		 +#    define S_errorinit_MASK 		0x7fffffff 	/* bit 31 */ +#    define S_errorinit_disable 	0x0 		 +#    define S_errorinit_enable 		0x80000000 	 + +#define MGAREG_SHIFT 				0x1c50 + +#    define FSC_x_off_MASK 		0xfffffff0 	/* bits 0-3 */ +#    define FSC_x_off_SHIFT 		0 		 +#    define FSC_funcnt_MASK 		0xffffff80 	/* bits 0-6 */ +#    define FSC_funcnt_SHIFT 		0 		 +#    define FSC_y_off_MASK 		0xffffff8f 	/* bits 4-6 */ +#    define FSC_y_off_SHIFT 		4 		 +#    define FSC_funoff_MASK 		0xffc0ffff 	/* bits 16-21 */ +#    define FSC_funoff_SHIFT 		16 		 +#    define FSC_stylelen_MASK 		0xffc0ffff 	/* bits 16-21 */ +#    define FSC_stylelen_SHIFT 		16 		 + +#define MGAREG_SOFTRAP 			0x2c48 + +#    define STH_softraphand_MASK 	0x3 		/* bits 2-31 */ +#    define STH_softraphand_SHIFT 	2 		 + +#define MGAREG_SPECBSTART 			0x2c98 +#define MGAREG_SPECBXINC 			0x2c9c +#define MGAREG_SPECBYINC 			0x2ca0 +#define MGAREG_SPECGSTART 			0x2c8c +#define MGAREG_SPECGXINC 			0x2c90 +#define MGAREG_SPECGYINC 			0x2c94 +#define MGAREG_SPECRSTART 			0x2c80 +#define MGAREG_SPECRXINC 			0x2c84 +#define MGAREG_SPECRYINC 			0x2c88 +#define MGAREG_SRC0 				0x1c30 +#define MGAREG_SRC1 				0x1c34 +#define MGAREG_SRC2 				0x1c38 +#define MGAREG_SRC3 				0x1c3c +#define MGAREG_SRCORG 				0x2cb4 + +#    define SO_srcmap_MASK 		0xfffffffe 	/* bit 0 */ +#    define SO_srcmap_fb 		0x0 		 +#    define SO_srcmap_sys 		0x1 		 +#    define SO_srcacc_MASK 		0xfffffffd 	/* bit 1 */ +#    define SO_srcacc_pci 		0x0 		 +#    define SO_srcacc_agp 		0x2 		 +#    define SO_srcorg_MASK 		0x7 		/* bits 3-31 */ +#    define SO_srcorg_SHIFT 		3 		 + +#define MGAREG_STATUS 				0x1e14 + +#    define STAT_softrapen_MASK 	0xfffffffe 	/* bit 0 */ +#    define STAT_softrapen_disable 	0x0 		 +#    define STAT_softrapen_enable 	0x1 		 +#    define STAT_pickpen_MASK 		0xfffffffb 	/* bit 2 */ +#    define STAT_pickpen_disable 	0x0 		 +#    define STAT_pickpen_enable 	0x4 		 +#    define STAT_vsyncsts_MASK 		0xfffffff7 	/* bit 3 */ +#    define STAT_vsyncsts_disable 	0x0 		 +#    define STAT_vsyncsts_enable 	0x8 		 +#    define STAT_vsyncpen_MASK 		0xffffffef 	/* bit 4 */ +#    define STAT_vsyncpen_disable 	0x0 		 +#    define STAT_vsyncpen_enable 	0x10 		 +#    define STAT_vlinepen_MASK 		0xffffffdf 	/* bit 5 */ +#    define STAT_vlinepen_disable 	0x0 		 +#    define STAT_vlinepen_enable 	0x20 		 +#    define STAT_extpen_MASK 		0xffffffbf 	/* bit 6 */ +#    define STAT_extpen_disable 	0x0 		 +#    define STAT_extpen_enable 		0x40 		 +#    define STAT_wpen_MASK 		0xffffff7f 	/* bit 7 */ +#    define STAT_wpen_disable 		0x0 		 +#    define STAT_wpen_enable 		0x80 		 +#    define STAT_wcpen_MASK 		0xfffffeff 	/* bit 8 */ +#    define STAT_wcpen_disable 		0x0 		 +#    define STAT_wcpen_enable 		0x100 		 +#    define STAT_dwgengsts_MASK 	0xfffeffff 	/* bit 16 */ +#    define STAT_dwgengsts_disable 	0x0 		 +#    define STAT_dwgengsts_enable 	0x10000 	 +#    define STAT_endprdmasts_MASK 	0xfffdffff 	/* bit 17 */ +#    define STAT_endprdmasts_disable 	0x0 		 +#    define STAT_endprdmasts_enable 	0x20000 	 +#    define STAT_wbusy_MASK 		0xfffbffff 	/* bit 18 */ +#    define STAT_wbusy_disable 		0x0 		 +#    define STAT_wbusy_enable 		0x40000 	 +#    define STAT_swflag_MASK 		0xfffffff 	/* bits 28-31 */ +#    define STAT_swflag_SHIFT 		28 		 + +#define MGAREG_STENCIL 			0x2cc8 + +#    define S_sref_MASK 		0xffffff00 	/* bits 0-7 */ +#    define S_sref_SHIFT 		0 		 +#    define S_smsk_MASK 		0xffff00ff 	/* bits 8-15 */ +#    define S_smsk_SHIFT 		8 		 +#    define S_swtmsk_MASK 		0xff00ffff 	/* bits 16-23 */ +#    define S_swtmsk_SHIFT 		16 		 + +#define MGAREG_STENCILCTL 			0x2ccc + +#    define SC_smode_MASK 		0xfffffff8 	/* bits 0-2 */ +#    define SC_smode_salways 		0x0 		/* val 0, shift 0 */ +#    define SC_smode_snever 		0x1 		/* val 1, shift 0 */ +#    define SC_smode_se 		0x2 		/* val 2, shift 0 */ +#    define SC_smode_sne 		0x3 		/* val 3, shift 0 */ +#    define SC_smode_slt 		0x4 		/* val 4, shift 0 */ +#    define SC_smode_slte 		0x5 		/* val 5, shift 0 */ +#    define SC_smode_sgt 		0x6 		/* val 6, shift 0 */ +#    define SC_smode_sgte 		0x7 		/* val 7, shift 0 */ +#    define SC_sfailop_MASK 		0xffffffc7 	/* bits 3-5 */ +#    define SC_sfailop_keep 		0x0 		/* val 0, shift 3 */ +#    define SC_sfailop_zero 		0x8 		/* val 1, shift 3 */ +#    define SC_sfailop_replace 		0x10 		/* val 2, shift 3 */ +#    define SC_sfailop_incrsat 		0x18 		/* val 3, shift 3 */ +#    define SC_sfailop_decrsat 		0x20 		/* val 4, shift 3 */ +#    define SC_sfailop_invert 		0x28 		/* val 5, shift 3 */ +#    define SC_sfailop_incr 		0x30 		/* val 6, shift 3 */ +#    define SC_sfailop_decr 		0x38 		/* val 7, shift 3 */ +#    define SC_szfailop_MASK 		0xfffffe3f 	/* bits 6-8 */ +#    define SC_szfailop_keep 		0x0 		/* val 0, shift 6 */ +#    define SC_szfailop_zero 		0x40 		/* val 1, shift 6 */ +#    define SC_szfailop_replace 	0x80 		/* val 2, shift 6 */ +#    define SC_szfailop_incrsat 	0xc0 		/* val 3, shift 6 */ +#    define SC_szfailop_decrsat 	0x100 		/* val 4, shift 6 */ +#    define SC_szfailop_invert 		0x140 		/* val 5, shift 6 */ +#    define SC_szfailop_incr 		0x180 		/* val 6, shift 6 */ +#    define SC_szfailop_decr 		0x1c0 		/* val 7, shift 6 */ +#    define SC_szpassop_MASK 		0xfffff1ff 	/* bits 9-11 */ +#    define SC_szpassop_keep 		0x0 		/* val 0, shift 9 */ +#    define SC_szpassop_zero 		0x200 		/* val 1, shift 9 */ +#    define SC_szpassop_replace 	0x400 		/* val 2, shift 9 */ +#    define SC_szpassop_incrsat 	0x600 		/* val 3, shift 9 */ +#    define SC_szpassop_decrsat 	0x800 		/* val 4, shift 9 */ +#    define SC_szpassop_invert 		0xa00 		/* val 5, shift 9 */ +#    define SC_szpassop_incr 		0xc00 		/* val 6, shift 9 */ +#    define SC_szpassop_decr 		0xe00 		/* val 7, shift 9 */ + +#define MGAREG_TDUALSTAGE0 			0x2cf8 + +#    define TD0_color_arg2_MASK 	0xfffffffc 	/* bits 0-1 */ +#    define TD0_color_arg2_diffuse 	0x0 		/* val 0, shift 0 */ +#    define TD0_color_arg2_specular 	0x1 		/* val 1, shift 0 */ +#    define TD0_color_arg2_fcol 	0x2 		/* val 2, shift 0 */ +#    define TD0_color_arg2_prevstage 	0x3 		/* val 3, shift 0 */ +#    define TD0_color_alpha_MASK 	0xffffffe3 	/* bits 2-4 */ +#    define TD0_color_alpha_diffuse 	0x0 		/* val 0, shift 2 */ +#    define TD0_color_alpha_fcol 	0x4 		/* val 1, shift 2 */ +#    define TD0_color_alpha_currtex 	0x8 		/* val 2, shift 2 */ +#    define TD0_color_alpha_prevtex 	0xc 		/* val 3, shift 2 */ +#    define TD0_color_alpha_prevstage 	0x10 		/* val 4, shift 2 */ +#    define TD0_color_arg1_replicatealpha_MASK 0xffffffdf 	/* bit 5 */ +#    define TD0_color_arg1_replicatealpha_disable 0x0 		 +#    define TD0_color_arg1_replicatealpha_enable 0x20 		 +#    define TD0_color_arg1_inv_MASK 	0xffffffbf 	/* bit 6 */ +#    define TD0_color_arg1_inv_disable 	0x0 		 +#    define TD0_color_arg1_inv_enable 	0x40 		 +#    define TD0_color_arg2_replicatealpha_MASK 0xffffff7f 	/* bit 7 */ +#    define TD0_color_arg2_replicatealpha_disable 0x0 		 +#    define TD0_color_arg2_replicatealpha_enable 0x80 		 +#    define TD0_color_arg2_inv_MASK 	0xfffffeff 	/* bit 8 */ +#    define TD0_color_arg2_inv_disable 	0x0 		 +#    define TD0_color_arg2_inv_enable 	0x100 		 +#    define TD0_color_alpha1inv_MASK 	0xfffffdff 	/* bit 9 */ +#    define TD0_color_alpha1inv_disable 0x0 		 +#    define TD0_color_alpha1inv_enable 	0x200 		 +#    define TD0_color_alpha2inv_MASK 	0xfffffbff 	/* bit 10 */ +#    define TD0_color_alpha2inv_disable 0x0 		 +#    define TD0_color_alpha2inv_enable 	0x400 		 +#    define TD0_color_arg1mul_MASK 	0xfffff7ff 	/* bit 11 */ +#    define TD0_color_arg1mul_disable 	0x0 		/* val 0, shift 11 */ +#    define TD0_color_arg1mul_alpha1 	0x800 		/* val 1, shift 11 */ +#    define TD0_color_arg2mul_MASK 	0xffffefff 	/* bit 12 */ +#    define TD0_color_arg2mul_disable 	0x0 		/* val 0, shift 12 */ +#    define TD0_color_arg2mul_alpha2 	0x1000 		/* val 1, shift 12 */ +#    define TD0_color_arg1add_MASK 	0xffffdfff 	/* bit 13 */ +#    define TD0_color_arg1add_disable 	0x0 		/* val 0, shift 13 */ +#    define TD0_color_arg1add_mulout 	0x2000 		/* val 1, shift 13 */ +#    define TD0_color_arg2add_MASK 	0xffffbfff 	/* bit 14 */ +#    define TD0_color_arg2add_disable 	0x0 		/* val 0, shift 14 */ +#    define TD0_color_arg2add_mulout 	0x4000 		/* val 1, shift 14 */ +#    define TD0_color_modbright_MASK 	0xfffe7fff 	/* bits 15-16 */ +#    define TD0_color_modbright_disable 0x0 		/* val 0, shift 15 */ +#    define TD0_color_modbright_2x 	0x8000 		/* val 1, shift 15 */ +#    define TD0_color_modbright_4x 	0x10000 	/* val 2, shift 15 */ +#    define TD0_color_add_MASK 		0xfffdffff 	/* bit 17 */ +#    define TD0_color_add_sub 		0x0 		/* val 0, shift 17 */ +#    define TD0_color_add_add 		0x20000 	/* val 1, shift 17 */ +#    define TD0_color_add2x_MASK 	0xfffbffff 	/* bit 18 */ +#    define TD0_color_add2x_disable 	0x0 		 +#    define TD0_color_add2x_enable 	0x40000 	 +#    define TD0_color_addbias_MASK 	0xfff7ffff 	/* bit 19 */ +#    define TD0_color_addbias_disable 	0x0 		 +#    define TD0_color_addbias_enable 	0x80000 	 +#    define TD0_color_blend_MASK 	0xffefffff 	/* bit 20 */ +#    define TD0_color_blend_disable 	0x0 		 +#    define TD0_color_blend_enable 	0x100000 	 +#    define TD0_color_sel_MASK 		0xff9fffff 	/* bits 21-22 */ +#    define TD0_color_sel_arg1 		0x0 		/* val 0, shift 21 */ +#    define TD0_color_sel_arg2 		0x200000 	/* val 1, shift 21 */ +#    define TD0_color_sel_add 		0x400000 	/* val 2, shift 21 */ +#    define TD0_color_sel_mul 		0x600000 	/* val 3, shift 21 */ +#    define TD0_alpha_arg1_inv_MASK 	0xff7fffff 	/* bit 23 */ +#    define TD0_alpha_arg1_inv_disable 	0x0 		 +#    define TD0_alpha_arg1_inv_enable 	0x800000 	 +#    define TD0_alpha_arg2_MASK 	0xfcffffff 	/* bits 24-25 */ +#    define TD0_alpha_arg2_diffuse 	0x0 		/* val 0, shift 24 */ +#    define TD0_alpha_arg2_fcol 	0x1000000 	/* val 1, shift 24 */ +#    define TD0_alpha_arg2_prevtex 	0x2000000 	/* val 2, shift 24 */ +#    define TD0_alpha_arg2_prevstage 	0x3000000 	/* val 3, shift 24 */ +#    define TD0_alpha_arg2_inv_MASK 	0xfbffffff 	/* bit 26 */ +#    define TD0_alpha_arg2_inv_disable 	0x0 		 +#    define TD0_alpha_arg2_inv_enable 	0x4000000 	 +#    define TD0_alpha_add_MASK 		0xf7ffffff 	/* bit 27 */ +#    define TD0_alpha_add_disable 	0x0 		 +#    define TD0_alpha_add_enable 	0x8000000 	 +#    define TD0_alpha_addbias_MASK 	0xefffffff 	/* bit 28 */ +#    define TD0_alpha_addbias_disable 	0x0 		 +#    define TD0_alpha_addbias_enable 	0x10000000 	 +#    define TD0_alpha_add2x_MASK 	0xdfffffff 	/* bit 29 */ +#    define TD0_alpha_add2x_disable 	0x0 		 +#    define TD0_alpha_add2x_enable 	0x20000000 	 +#    define TD0_alpha_modbright_MASK 	0xcfffffff 	/* bits 28-29 */ +#    define TD0_alpha_modbright_disable 0x0 		/* val 0, shift 28 */ +#    define TD0_alpha_modbright_2x 	0x10000000 	/* val 1, shift 28 */ +#    define TD0_alpha_modbright_4x 	0x20000000 	/* val 2, shift 28 */ +#    define TD0_alpha_sel_MASK 		0x3fffffff 	/* bits 30-31 */ +#    define TD0_alpha_sel_arg1 		0x0 		/* val 0, shift 30 */ +#    define TD0_alpha_sel_arg2 		0x40000000 	/* val 1, shift 30 */ +#    define TD0_alpha_sel_add 		0x80000000 	/* val 2, shift 30 */ +#    define TD0_alpha_sel_mul 		0xc0000000 	/* val 3, shift 30 */ + +#define MGAREG_TDUALSTAGE1 			0x2cfc + +#    define TD1_color_arg2_MASK 	0xfffffffc 	/* bits 0-1 */ +#    define TD1_color_arg2_diffuse 	0x0 		/* val 0, shift 0 */ +#    define TD1_color_arg2_specular 	0x1 		/* val 1, shift 0 */ +#    define TD1_color_arg2_fcol 	0x2 		/* val 2, shift 0 */ +#    define TD1_color_arg2_prevstage 	0x3 		/* val 3, shift 0 */ +#    define TD1_color_alpha_MASK 	0xffffffe3 	/* bits 2-4 */ +#    define TD1_color_alpha_diffuse 	0x0 		/* val 0, shift 2 */ +#    define TD1_color_alpha_fcol 	0x4 		/* val 1, shift 2 */ +#    define TD1_color_alpha_tex0 	0x8 		/* val 2, shift 2 */ +#    define TD1_color_alpha_prevtex 	0xc 		/* val 3, shift 2 */ +#    define TD1_color_alpha_prevstage 	0x10 		/* val 4, shift 2 */ +#    define TD1_color_arg1_replicatealpha_MASK 0xffffffdf 	/* bit 5 */ +#    define TD1_color_arg1_replicatealpha_disable 0x0 		 +#    define TD1_color_arg1_replicatealpha_enable 0x20 		 +#    define TD1_color_arg1_inv_MASK 	0xffffffbf 	/* bit 6 */ +#    define TD1_color_arg1_inv_disable 	0x0 		 +#    define TD1_color_arg1_inv_enable 	0x40 		 +#    define TD1_color_arg2_replicatealpha_MASK 0xffffff7f 	/* bit 7 */ +#    define TD1_color_arg2_replicatealpha_disable 0x0 		 +#    define TD1_color_arg2_replicatealpha_enable 0x80 		 +#    define TD1_color_arg2_inv_MASK 	0xfffffeff 	/* bit 8 */ +#    define TD1_color_arg2_inv_disable 	0x0 		 +#    define TD1_color_arg2_inv_enable 	0x100 		 +#    define TD1_color_alpha1inv_MASK 	0xfffffdff 	/* bit 9 */ +#    define TD1_color_alpha1inv_disable 0x0 		 +#    define TD1_color_alpha1inv_enable 	0x200 		 +#    define TD1_color_alpha2inv_MASK 	0xfffffbff 	/* bit 10 */ +#    define TD1_color_alpha2inv_disable 0x0 		 +#    define TD1_color_alpha2inv_enable 	0x400 		 +#    define TD1_color_arg1mul_MASK 	0xfffff7ff 	/* bit 11 */ +#    define TD1_color_arg1mul_disable 	0x0 		/* val 0, shift 11 */ +#    define TD1_color_arg1mul_alpha1 	0x800 		/* val 1, shift 11 */ +#    define TD1_color_arg2mul_MASK 	0xffffefff 	/* bit 12 */ +#    define TD1_color_arg2mul_disable 	0x0 		/* val 0, shift 12 */ +#    define TD1_color_arg2mul_alpha2 	0x1000 		/* val 1, shift 12 */ +#    define TD1_color_arg1add_MASK 	0xffffdfff 	/* bit 13 */ +#    define TD1_color_arg1add_disable 	0x0 		/* val 0, shift 13 */ +#    define TD1_color_arg1add_mulout 	0x2000 		/* val 1, shift 13 */ +#    define TD1_color_arg2add_MASK 	0xffffbfff 	/* bit 14 */ +#    define TD1_color_arg2add_disable 	0x0 		/* val 0, shift 14 */ +#    define TD1_color_arg2add_mulout 	0x4000 		/* val 1, shift 14 */ +#    define TD1_color_modbright_MASK 	0xfffe7fff 	/* bits 15-16 */ +#    define TD1_color_modbright_disable 0x0 		/* val 0, shift 15 */ +#    define TD1_color_modbright_2x 	0x8000 		/* val 1, shift 15 */ +#    define TD1_color_modbright_4x 	0x10000 	/* val 2, shift 15 */ +#    define TD1_color_add_MASK 		0xfffdffff 	/* bit 17 */ +#    define TD1_color_add_sub 		0x0 		/* val 0, shift 17 */ +#    define TD1_color_add_add 		0x20000 	/* val 1, shift 17 */ +#    define TD1_color_add2x_MASK 	0xfffbffff 	/* bit 18 */ +#    define TD1_color_add2x_disable 	0x0 		 +#    define TD1_color_add2x_enable 	0x40000 	 +#    define TD1_color_addbias_MASK 	0xfff7ffff 	/* bit 19 */ +#    define TD1_color_addbias_disable 	0x0 		 +#    define TD1_color_addbias_enable 	0x80000 	 +#    define TD1_color_blend_MASK 	0xffefffff 	/* bit 20 */ +#    define TD1_color_blend_disable 	0x0 		 +#    define TD1_color_blend_enable 	0x100000 	 +#    define TD1_color_sel_MASK 		0xff9fffff 	/* bits 21-22 */ +#    define TD1_color_sel_arg1 		0x0 		/* val 0, shift 21 */ +#    define TD1_color_sel_arg2 		0x200000 	/* val 1, shift 21 */ +#    define TD1_color_sel_add 		0x400000 	/* val 2, shift 21 */ +#    define TD1_color_sel_mul 		0x600000 	/* val 3, shift 21 */ +#    define TD1_alpha_arg1_inv_MASK 	0xff7fffff 	/* bit 23 */ +#    define TD1_alpha_arg1_inv_disable 	0x0 		 +#    define TD1_alpha_arg1_inv_enable 	0x800000 	 +#    define TD1_alpha_arg2_MASK 	0xfcffffff 	/* bits 24-25 */ +#    define TD1_alpha_arg2_diffuse 	0x0 		/* val 0, shift 24 */ +#    define TD1_alpha_arg2_fcol 	0x1000000 	/* val 1, shift 24 */ +#    define TD1_alpha_arg2_prevtex 	0x2000000 	/* val 2, shift 24 */ +#    define TD1_alpha_arg2_prevstage 	0x3000000 	/* val 3, shift 24 */ +#    define TD1_alpha_arg2_inv_MASK 	0xfbffffff 	/* bit 26 */ +#    define TD1_alpha_arg2_inv_disable 	0x0 		 +#    define TD1_alpha_arg2_inv_enable 	0x4000000 	 +#    define TD1_alpha_add_MASK 		0xf7ffffff 	/* bit 27 */ +#    define TD1_alpha_add_disable 	0x0 		 +#    define TD1_alpha_add_enable 	0x8000000 	 +#    define TD1_alpha_addbias_MASK 	0xefffffff 	/* bit 28 */ +#    define TD1_alpha_addbias_disable 	0x0 		 +#    define TD1_alpha_addbias_enable 	0x10000000 	 +#    define TD1_alpha_add2x_MASK 	0xdfffffff 	/* bit 29 */ +#    define TD1_alpha_add2x_disable 	0x0 		 +#    define TD1_alpha_add2x_enable 	0x20000000 	 +#    define TD1_alpha_modbright_MASK 	0xcfffffff 	/* bits 28-29 */ +#    define TD1_alpha_modbright_disable 0x0 		/* val 0, shift 28 */ +#    define TD1_alpha_modbright_2x 	0x10000000 	/* val 1, shift 28 */ +#    define TD1_alpha_modbright_4x 	0x20000000 	/* val 2, shift 28 */ +#    define TD1_alpha_sel_MASK 		0x3fffffff 	/* bits 30-31 */ +#    define TD1_alpha_sel_arg1 		0x0 		/* val 0, shift 30 */ +#    define TD1_alpha_sel_arg2 		0x40000000 	/* val 1, shift 30 */ +#    define TD1_alpha_sel_add 		0x80000000 	/* val 2, shift 30 */ +#    define TD1_alpha_sel_mul 		0xc0000000 	/* val 3, shift 30 */ + +#define MGAREG_TEST0 				0x1e48 + +#    define TST_ramtsten_MASK 		0xfffffffe 	/* bit 0 */ +#    define TST_ramtsten_disable 	0x0 		 +#    define TST_ramtsten_enable 	0x1 		 +#    define TST_ramtstdone_MASK 	0xfffffffd 	/* bit 1 */ +#    define TST_ramtstdone_disable 	0x0 		 +#    define TST_ramtstdone_enable 	0x2 		 +#    define TST_wramtstpass_MASK 	0xfffffffb 	/* bit 2 */ +#    define TST_wramtstpass_disable 	0x0 		 +#    define TST_wramtstpass_enable 	0x4 		 +#    define TST_tcachetstpass_MASK 	0xfffffff7 	/* bit 3 */ +#    define TST_tcachetstpass_disable 	0x0 		 +#    define TST_tcachetstpass_enable 	0x8 		 +#    define TST_tluttstpass_MASK 	0xffffffef 	/* bit 4 */ +#    define TST_tluttstpass_disable 	0x0 		 +#    define TST_tluttstpass_enable 	0x10 		 +#    define TST_luttstpass_MASK 	0xffffffdf 	/* bit 5 */ +#    define TST_luttstpass_disable 	0x0 		 +#    define TST_luttstpass_enable 	0x20 		 +#    define TST_besramtstpass_MASK 	0xffffffbf 	/* bit 6 */ +#    define TST_besramtstpass_disable 	0x0 		 +#    define TST_besramtstpass_enable 	0x40 		 +#    define TST_ringen_MASK 		0xfffffeff 	/* bit 8 */ +#    define TST_ringen_disable 		0x0 		 +#    define TST_ringen_enable 		0x100 		 +#    define TST_apllbyp_MASK 		0xfffffdff 	/* bit 9 */ +#    define TST_apllbyp_disable 	0x0 		 +#    define TST_apllbyp_enable 		0x200 		 +#    define TST_hiten_MASK 		0xfffffbff 	/* bit 10 */ +#    define TST_hiten_disable 		0x0 		 +#    define TST_hiten_enable 		0x400 		 +#    define TST_tmode_MASK 		0xffffc7ff 	/* bits 11-13 */ +#    define TST_tmode_SHIFT 		11 		 +#    define TST_tclksel_MASK 		0xfffe3fff 	/* bits 14-16 */ +#    define TST_tclksel_SHIFT 		14 		 +#    define TST_ringcnten_MASK 		0xfffdffff 	/* bit 17 */ +#    define TST_ringcnten_disable 	0x0 		 +#    define TST_ringcnten_enable 	0x20000 	 +#    define TST_ringcnt_MASK 		0xc003ffff 	/* bits 18-29 */ +#    define TST_ringcnt_SHIFT 		18 		 +#    define TST_ringcntclksl_MASK 	0xbfffffff 	/* bit 30 */ +#    define TST_ringcntclksl_disable 	0x0 		 +#    define TST_ringcntclksl_enable 	0x40000000 	 +#    define TST_biosboot_MASK 		0x7fffffff 	/* bit 31 */ +#    define TST_biosboot_disable 	0x0 		 +#    define TST_biosboot_enable 	0x80000000 	 + +#define MGAREG_TEXBORDERCOL 			0x2c5c +#define MGAREG_TEXCTL 				0x2c30 + +#    define TMC_tformat_MASK 		0xfffffff0 	/* bits 0-3 */ +#    define TMC_tformat_tw4 		0x0 		/* val 0, shift 0 */ +#    define TMC_tformat_tw8 		0x1 		/* val 1, shift 0 */ +#    define TMC_tformat_tw15 		0x2 		/* val 2, shift 0 */ +#    define TMC_tformat_tw16 		0x3 		/* val 3, shift 0 */ +#    define TMC_tformat_tw12 		0x4 		/* val 4, shift 0 */ +#    define TMC_tformat_tw32 		0x6 		/* val 6, shift 0 */ +#    define TMC_tformat_tw8a 		0x7 		/* val 7, shift 0 */ +#    define TMC_tformat_tw8al 		0x8 		/* val 8, shift 0 */ +#    define TMC_tformat_tw422 		0xa 		/* val 10, shift 0 */ +#    define TMC_tpitchlin_MASK 		0xfffffeff 	/* bit 8 */ +#    define TMC_tpitchlin_disable 	0x0 		 +#    define TMC_tpitchlin_enable 	0x100 		 +#    define TMC_tpitchext_MASK 		0xfff001ff 	/* bits 9-19 */ +#    define TMC_tpitchext_SHIFT 	9 		 +#    define TMC_tpitch_MASK 		0xfff8ffff 	/* bits 16-18 */ +#    define TMC_tpitch_SHIFT 		16 		 +#    define TMC_owalpha_MASK 		0xffbfffff 	/* bit 22 */ +#    define TMC_owalpha_disable 	0x0 		 +#    define TMC_owalpha_enable 		0x400000 	 +#    define TMC_azeroextend_MASK 	0xff7fffff 	/* bit 23 */ +#    define TMC_azeroextend_disable 	0x0 		 +#    define TMC_azeroextend_enable 	0x800000 	 +#    define TMC_decalckey_MASK 		0xfeffffff 	/* bit 24 */ +#    define TMC_decalckey_disable 	0x0 		 +#    define TMC_decalckey_enable 	0x1000000 	 +#    define TMC_takey_MASK 		0xfdffffff 	/* bit 25 */ +#    define TMC_takey_0 		0x0 		 +#    define TMC_takey_1 		0x2000000 	 +#    define TMC_tamask_MASK 		0xfbffffff 	/* bit 26 */ +#    define TMC_tamask_0 		0x0 		 +#    define TMC_tamask_1 		0x4000000 	 +#    define TMC_clampv_MASK 		0xf7ffffff 	/* bit 27 */ +#    define TMC_clampv_disable 		0x0 		 +#    define TMC_clampv_enable 		0x8000000 	 +#    define TMC_clampu_MASK 		0xefffffff 	/* bit 28 */ +#    define TMC_clampu_disable 		0x0 		 +#    define TMC_clampu_enable 		0x10000000 	 +#    define TMC_tmodulate_MASK 		0xdfffffff 	/* bit 29 */ +#    define TMC_tmodulate_disable 	0x0 		 +#    define TMC_tmodulate_enable 	0x20000000 	 +#    define TMC_strans_MASK 		0xbfffffff 	/* bit 30 */ +#    define TMC_strans_disable 		0x0 		 +#    define TMC_strans_enable 		0x40000000 	 +#    define TMC_itrans_MASK 		0x7fffffff 	/* bit 31 */ +#    define TMC_itrans_disable 		0x0 		 +#    define TMC_itrans_enable 		0x80000000 	 + +#define MGAREG_TEXCTL2 			0x2c3c + +#    define TMC_decalblend_MASK 	0xfffffffe 	/* bit 0 */ +#    define TMC_decalblend_disable 	0x0 		 +#    define TMC_decalblend_enable 	0x1 		 +#    define TMC_idecal_MASK 		0xfffffffd 	/* bit 1 */ +#    define TMC_idecal_disable 		0x0 		 +#    define TMC_idecal_enable 		0x2 		 +#    define TMC_decaldis_MASK 		0xfffffffb 	/* bit 2 */ +#    define TMC_decaldis_disable 	0x0 		 +#    define TMC_decaldis_enable 	0x4 		 +#    define TMC_ckstransdis_MASK 	0xffffffef 	/* bit 4 */ +#    define TMC_ckstransdis_disable 	0x0 		 +#    define TMC_ckstransdis_enable 	0x10 		 +#    define TMC_borderen_MASK 		0xffffffdf 	/* bit 5 */ +#    define TMC_borderen_disable 	0x0 		 +#    define TMC_borderen_enable 	0x20 		 +#    define TMC_specen_MASK 		0xffffffbf 	/* bit 6 */ +#    define TMC_specen_disable 		0x0 		 +#    define TMC_specen_enable 		0x40 		 +#    define TMC_dualtex_MASK 		0xffffff7f 	/* bit 7 */ +#    define TMC_dualtex_disable 	0x0 		 +#    define TMC_dualtex_enable 		0x80 		 +#    define TMC_tablefog_MASK 		0xfffffeff 	/* bit 8 */ +#    define TMC_tablefog_disable 	0x0 		 +#    define TMC_tablefog_enable 	0x100 		 +#    define TMC_bumpmap_MASK 		0xfffffdff 	/* bit 9 */ +#    define TMC_bumpmap_disable 	0x0 		 +#    define TMC_bumpmap_enable 		0x200 		 +#    define TMC_map1_MASK 		0x7fffffff 	/* bit 31 */ +#    define TMC_map1_disable 		0x0 		 +#    define TMC_map1_enable 		0x80000000 	 + +#define MGAREG_TEXFILTER 			0x2c58 + +#    define TF_minfilter_MASK 		0xfffffff0 	/* bits 0-3 */ +#    define TF_minfilter_nrst 		0x0 		/* val 0, shift 0 */ +#    define TF_minfilter_bilin 		0x2 		/* val 2, shift 0 */ +#    define TF_minfilter_cnst 		0x3 		/* val 3, shift 0 */ +#    define TF_minfilter_mm1s 		0x8 		/* val 8, shift 0 */ +#    define TF_minfilter_mm2s 		0x9 		/* val 9, shift 0 */ +#    define TF_minfilter_mm4s 		0xa 		/* val 10, shift 0 */ +#    define TF_minfilter_mm8s 		0xc 		/* val 12, shift 0 */ +#    define TF_magfilter_MASK 		0xffffff0f 	/* bits 4-7 */ +#    define TF_magfilter_nrst 		0x0 		/* val 0, shift 4 */ +#    define TF_magfilter_bilin 		0x20 		/* val 2, shift 4 */ +#    define TF_magfilter_cnst 		0x30 		/* val 3, shift 4 */ +#    define TF_avgstride_MASK 		0xfff7ffff 	/* bit 19 */ +#    define TF_avgstride_disable 	0x0 		 +#    define TF_avgstride_enable 	0x80000 	 +#    define TF_filteralpha_MASK 	0xffefffff 	/* bit 20 */ +#    define TF_filteralpha_disable 	0x0 		 +#    define TF_filteralpha_enable 	0x100000 	 +#    define TF_fthres_MASK 		0xe01fffff 	/* bits 21-28 */ +#    define TF_fthres_SHIFT 		21 		 +#    define TF_mapnb_MASK 		0x1fffffff 	/* bits 29-31 */ +#    define TF_mapnb_SHIFT 		29 		 + +#define MGAREG_TEXHEIGHT 			0x2c2c + +#    define TH_th_MASK 			0xffffffc0 	/* bits 0-5 */ +#    define TH_th_SHIFT 		0 		 +#    define TH_rfh_MASK 		0xffff81ff 	/* bits 9-14 */ +#    define TH_rfh_SHIFT 		9 		 +#    define TH_thmask_MASK 		0xe003ffff 	/* bits 18-28 */ +#    define TH_thmask_SHIFT 		18 		 + +#define MGAREG_TEXORG 				0x2c24 + +#    define TO_texorgmap_MASK 		0xfffffffe 	/* bit 0 */ +#    define TO_texorgmap_fb 		0x0 		 +#    define TO_texorgmap_sys 		0x1 		 +#    define TO_texorgacc_MASK 		0xfffffffd 	/* bit 1 */ +#    define TO_texorgacc_pci 		0x0 		 +#    define TO_texorgacc_agp 		0x2 		 +#    define TO_texorgoffsetsel 		0x4 		 +#    define TO_texorg_MASK 		0x1f 		/* bits 5-31 */ +#    define TO_texorg_SHIFT 		5 		 + +#define MGAREG_TEXORG1 			0x2ca4 +#define MGAREG_TEXORG2 			0x2ca8 +#define MGAREG_TEXORG3 			0x2cac +#define MGAREG_TEXORG4 			0x2cb0 +#define MGAREG_TEXTRANS 			0x2c34 + +#    define TT_tckey_MASK 		0xffff0000 	/* bits 0-15 */ +#    define TT_tckey_SHIFT 		0 		 +#    define TT_tkmask_MASK 		0xffff 		/* bits 16-31 */ +#    define TT_tkmask_SHIFT 		16 		 + +#define MGAREG_TEXTRANSHIGH 			0x2c38 + +#    define TT_tckeyh_MASK 		0xffff0000 	/* bits 0-15 */ +#    define TT_tckeyh_SHIFT 		0 		 +#    define TT_tkmaskh_MASK 		0xffff 		/* bits 16-31 */ +#    define TT_tkmaskh_SHIFT 		16 		 + +#define MGAREG_TEXWIDTH 			0x2c28 + +#    define TW_tw_MASK 			0xffffffc0 	/* bits 0-5 */ +#    define TW_tw_SHIFT 		0 		 +#    define TW_rfw_MASK 		0xffff81ff 	/* bits 9-14 */ +#    define TW_rfw_SHIFT 		9 		 +#    define TW_twmask_MASK 		0xe003ffff 	/* bits 18-28 */ +#    define TW_twmask_SHIFT 		18 		 + +#define MGAREG_TMR0 				0x2c00 +#define MGAREG_TMR1 				0x2c04 +#define MGAREG_TMR2 				0x2c08 +#define MGAREG_TMR3 				0x2c0c +#define MGAREG_TMR4 				0x2c10 +#define MGAREG_TMR5 				0x2c14 +#define MGAREG_TMR6 				0x2c18 +#define MGAREG_TMR7 				0x2c1c +#define MGAREG_TMR8 				0x2c20 +#define MGAREG_VBIADDR0 			0x3e08 +#define MGAREG_VBIADDR1 			0x3e0c +#define MGAREG_VCOUNT 				0x1e20 +#define MGAREG_WACCEPTSEQ 			0x1dd4 + +#    define WAS_seqdst0_MASK 		0xffffffc0 	/* bits 0-5 */ +#    define WAS_seqdst0_SHIFT 		0 		 +#    define WAS_seqdst1_MASK 		0xfffff03f 	/* bits 6-11 */ +#    define WAS_seqdst1_SHIFT 		6 		 +#    define WAS_seqdst2_MASK 		0xfffc0fff 	/* bits 12-17 */ +#    define WAS_seqdst2_SHIFT 		12 		 +#    define WAS_seqdst3_MASK 		0xff03ffff 	/* bits 18-23 */ +#    define WAS_seqdst3_SHIFT 		18 		 +#    define WAS_seqlen_MASK 		0xfcffffff 	/* bits 24-25 */ +#    define WAS_wfirsttag_MASK 		0xfbffffff 	/* bit 26 */ +#    define WAS_wfirsttag_disable 	0x0 		 +#    define WAS_wfirsttag_enable 	0x4000000 	 +#    define WAS_wsametag_MASK 		0xf7ffffff 	/* bit 27 */ +#    define WAS_wsametag_disable 	0x0 		 +#    define WAS_wsametag_enable 	0x8000000 	 +#    define WAS_seqoff_MASK 		0xefffffff 	/* bit 28 */ +#    define WAS_seqoff_disable 		0x0 		 +#    define WAS_seqoff_enable 		0x10000000 	 + +#define MGAREG_WCODEADDR 			0x1e6c + +#    define WMA_wcodeaddr_MASK 		0xff 		/* bits 8-31 */ +#    define WMA_wcodeaddr_SHIFT 	8 		 + +#define MGAREG_WFLAG 				0x1dc4 + +#    define WF_walustsflag_MASK 	0xffffff00 	/* bits 0-7 */ +#    define WF_walustsflag_SHIFT 	0 		 +#    define WF_walucfgflag_MASK 	0xffff00ff 	/* bits 8-15 */ +#    define WF_walucfgflag_SHIFT 	8 		 +#    define WF_wprgflag_MASK 		0xffff 		/* bits 16-31 */ +#    define WF_wprgflag_SHIFT 		16 		 + +#define MGAREG_WFLAG1 				0x1de0 + +#    define WF1_walustsflag1_MASK 	0xffffff00 	/* bits 0-7 */ +#    define WF1_walustsflag1_SHIFT 	0 		 +#    define WF1_walucfgflag1_MASK 	0xffff00ff 	/* bits 8-15 */ +#    define WF1_walucfgflag1_SHIFT 	8 		 +#    define WF1_wprgflag1_MASK 		0xffff 		/* bits 16-31 */ +#    define WF1_wprgflag1_SHIFT 	16 		 + +#define MGAREG_WFLAGNB 			0x1e64 +#define MGAREG_WFLAGNB1 			0x1e08 +#define MGAREG_WGETMSB 			0x1dc8 + +#    define WGV_wgetmsbmin_MASK 	0xffffffe0 	/* bits 0-4 */ +#    define WGV_wgetmsbmin_SHIFT 	0 		 +#    define WGV_wgetmsbmax_MASK 	0xffffe0ff 	/* bits 8-12 */ +#    define WGV_wgetmsbmax_SHIFT 	8 		 +#    define WGV_wbrklefttop_MASK 	0xfffeffff 	/* bit 16 */ +#    define WGV_wbrklefttop_disable 	0x0 		 +#    define WGV_wbrklefttop_enable 	0x10000 	 +#    define WGV_wfastcrop_MASK 		0xfffdffff 	/* bit 17 */ +#    define WGV_wfastcrop_disable 	0x0 		 +#    define WGV_wfastcrop_enable 	0x20000 	 +#    define WGV_wcentersnap_MASK 	0xfffbffff 	/* bit 18 */ +#    define WGV_wcentersnap_disable 	0x0 		 +#    define WGV_wcentersnap_enable 	0x40000 	 +#    define WGV_wbrkrighttop_MASK 	0xfff7ffff 	/* bit 19 */ +#    define WGV_wbrkrighttop_disable 	0x0 		 +#    define WGV_wbrkrighttop_enable 	0x80000 	 + +#define MGAREG_WIADDR 				0x1dc0 + +#    define WIA_wmode_MASK 		0xfffffffc 	/* bits 0-1 */ +#    define WIA_wmode_suspend 		0x0 		/* val 0, shift 0 */ +#    define WIA_wmode_resume 		0x1 		/* val 1, shift 0 */ +#    define WIA_wmode_jump 		0x2 		/* val 2, shift 0 */ +#    define WIA_wmode_start 		0x3 		/* val 3, shift 0 */ +#    define WIA_wagp_MASK 		0xfffffffb 	/* bit 2 */ +#    define WIA_wagp_pci 		0x0 		 +#    define WIA_wagp_agp 		0x4 		 +#    define WIA_wiaddr_MASK 		0x7 		/* bits 3-31 */ +#    define WIA_wiaddr_SHIFT 		3 		 + +#define MGAREG_WIADDR2 			0x1dd8 + +#    define WIA2_wmode_MASK 		0xfffffffc 	/* bits 0-1 */ +#    define WIA2_wmode_suspend 		0x0 		/* val 0, shift 0 */ +#    define WIA2_wmode_resume 		0x1 		/* val 1, shift 0 */ +#    define WIA2_wmode_jump 		0x2 		/* val 2, shift 0 */ +#    define WIA2_wmode_start 		0x3 		/* val 3, shift 0 */ +#    define WIA2_wagp_MASK 		0xfffffffb 	/* bit 2 */ +#    define WIA2_wagp_pci 		0x0 		 +#    define WIA2_wagp_agp 		0x4 		 +#    define WIA2_wiaddr_MASK 		0x7 		/* bits 3-31 */ +#    define WIA2_wiaddr_SHIFT 		3 		 + +#define MGAREG_WIADDRNB 			0x1e60 +#define MGAREG_WIADDRNB1 			0x1e04 +#define MGAREG_WIADDRNB2 			0x1e00 +#define MGAREG_WIMEMADDR 			0x1e68 + +#    define WIMA_wimemaddr_MASK 	0xffffff00 	/* bits 0-7 */ +#    define WIMA_wimemaddr_SHIFT 	0 		 + +#define MGAREG_WIMEMDATA 			0x2000 +#define MGAREG_WIMEMDATA1 			0x2100 +#define MGAREG_WMISC 				0x1e70 + +#    define WM_wucodecache_MASK 	0xfffffffe 	/* bit 0 */ +#    define WM_wucodecache_disable 	0x0 		 +#    define WM_wucodecache_enable 	0x1 		 +#    define WM_wmaster_MASK 		0xfffffffd 	/* bit 1 */ +#    define WM_wmaster_disable 		0x0 		 +#    define WM_wmaster_enable 		0x2 		 +#    define WM_wcacheflush_MASK 	0xfffffff7 	/* bit 3 */ +#    define WM_wcacheflush_disable 	0x0 		 +#    define WM_wcacheflush_enable 	0x8 		 + +#define MGAREG_WR 				0x2d00 +#define MGAREG_WVRTXSZ 			0x1dcc + +#    define WVS_wvrtxsz_MASK 		0xffffffc0 	/* bits 0-5 */ +#    define WVS_wvrtxsz_SHIFT 		0 		 +#    define WVS_primsz_MASK 		0xffffc0ff 	/* bits 8-13 */ +#    define WVS_primsz_SHIFT 		8 		 + +#define MGAREG_XDST 				0x1cb0 +#define MGAREG_XYEND 				0x1c44 + +#    define XYEA_x_end_MASK 		0xffff0000 	/* bits 0-15 */ +#    define XYEA_x_end_SHIFT 		0 		 +#    define XYEA_y_end_MASK 		0xffff 		/* bits 16-31 */ +#    define XYEA_y_end_SHIFT 		16 		 + +#define MGAREG_XYSTRT 				0x1c40 + +#    define XYSA_x_start_MASK 		0xffff0000 	/* bits 0-15 */ +#    define XYSA_x_start_SHIFT 		0 		 +#    define XYSA_y_start_MASK 		0xffff 		/* bits 16-31 */ +#    define XYSA_y_start_SHIFT 		16 		 + +#define MGAREG_YBOT 				0x1c9c +#define MGAREG_YDST 				0x1c90 + +#    define YA_ydst_MASK 		0xff800000 	/* bits 0-22 */ +#    define YA_ydst_SHIFT 		0 		 +#    define YA_sellin_MASK 		0x1fffffff 	/* bits 29-31 */ +#    define YA_sellin_SHIFT 		29 		 + +#define MGAREG_YDSTLEN 			0x1c88 + +#    define YDL_length_MASK 		0xffff0000 	/* bits 0-15 */ +#    define YDL_length_SHIFT 		0 		 +#    define YDL_yval_MASK 		0xffff 		/* bits 16-31 */ +#    define YDL_yval_SHIFT 		16 		 + +#define MGAREG_YDSTORG 			0x1c94 +#define MGAREG_YTOP 				0x1c98 +#define MGAREG_ZORG 				0x1c0c + +#    define ZO_zorgmap_MASK 		0xfffffffe 	/* bit 0 */ +#    define ZO_zorgmap_fb 		0x0 		 +#    define ZO_zorgmap_sys 		0x1 		 +#    define ZO_zorgacc_MASK 		0xfffffffd 	/* bit 1 */ +#    define ZO_zorgacc_pci 		0x0 		 +#    define ZO_zorgacc_agp 		0x2 		 +#    define ZO_zorg_MASK 		0x3 		/* bits 2-31 */ +#    define ZO_zorg_SHIFT 		2 		 + + + + +/**************** (END) AUTOMATICLY GENERATED REGISTER FILE ******************/ + +#endif 	/* _MGAREGS_H_ */ + diff --git a/src/mesa/drivers/dri/mga/mgarender.c b/src/mesa/drivers/dri/mga/mgarender.c new file mode 100644 index 0000000000..53614c223f --- /dev/null +++ b/src/mesa/drivers/dri/mga/mgarender.c @@ -0,0 +1,208 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgarender.c,v 1.4 2002/10/30 12:51:36 alanh Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and +                     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. + +**************************************************************************/ + +/* + * Authors: + *   Keith Whitwell <keith@tungstengraphics.com> + * + */ + + +/* + * Render unclipped vertex buffers by emitting vertices directly to + * dma buffers.  Use strip/fan hardware primitives where possible. + * Simulate missing primitives with indexed vertices. + */ +#include "glheader.h" +#include "context.h" +#include "macros.h" +/*//#include "mem.h"*/ +#include "mtypes.h" +/*#include "mmath.h" */ + +#include "tnl/t_context.h" + +#include "mgacontext.h" +#include "mgatris.h" +#include "mgastate.h" +#include "mgaioctl.h" +#include "mgavb.h" + +#define HAVE_POINTS      0 +#define HAVE_LINES       0 +#define HAVE_LINE_STRIPS 0 +#define HAVE_TRIANGLES   1 +#define HAVE_TRI_STRIPS  1 +#define HAVE_TRI_STRIP_1 0 +#define HAVE_TRI_FANS    1 +#define HAVE_POLYGONS    0 +#define HAVE_QUADS       0 +#define HAVE_QUAD_STRIPS 0 + +#define HAVE_ELTS        0	/* for now */ + +static void mgaDmaPrimitive( GLcontext *ctx, GLenum prim ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); +   GLuint hwprim; + +   switch (prim) { +   case GL_TRIANGLES: +      hwprim = MGA_WA_TRIANGLES; +      break; +   case GL_TRIANGLE_STRIP: +      if (mmesa->vertex_size == 8) +	 hwprim = MGA_WA_TRISTRIP_T0; +      else +	 hwprim = MGA_WA_TRISTRIP_T0T1; +      break; +   case GL_TRIANGLE_FAN: +      if (mmesa->vertex_size == 8) +	 hwprim = MGA_WA_TRIFAN_T0; +      else +	 hwprim = MGA_WA_TRIFAN_T0T1; +      break; +   default: +      return; +   } + +   mgaRasterPrimitive( ctx, GL_TRIANGLES, hwprim ); +} + +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 ); +   MGA_CONTEXT(ctx)->SetupNewInputs |= VERT_BIT_CLIP; +} + +#define LOCAL_VARS mgaContextPtr mmesa = MGA_CONTEXT(ctx)  +#define INIT( prim ) do {			\ +   if (0) fprintf(stderr, "%s\n", __FUNCTION__);	\ +   FLUSH_BATCH(mmesa);				\ +   mgaDmaPrimitive( ctx, prim );		\ +} while (0) +#define NEW_PRIMITIVE()  FLUSH_BATCH( mmesa ) +#define NEW_BUFFER()  FLUSH_BATCH( mmesa ) +#define GET_CURRENT_VB_MAX_VERTS() \ +   0 /* fix me */ +#define GET_SUBSEQUENT_VB_MAX_VERTS() \ +   MGA_BUFFER_SIZE / (mmesa->vertex_size * 4) +#define EMIT_VERTS( ctx, j, nr ) \ +   mga_emit_contiguous_verts(ctx, j, (j)+(nr)) + +  +#define TAG(x) mga_##x +#include "tnl_dd/t_dd_dmatmp.h" + + + +/**********************************************************************/ +/*                          Render pipeline stage                     */ +/**********************************************************************/ + + +static GLboolean mga_run_render( GLcontext *ctx, +				  struct gl_pipeline_stage *stage ) +{ +   mgaContextPtr mmesa = MGA_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 or vertex manipulations. +    */ +   if (VB->ClipOrMask || mmesa->RenderIndex != 0 || VB->Elts) { +      return GL_TRUE; +   } +    +   tnl->Driver.Render.Start( ctx ); +   mmesa->SetupNewInputs = ~0;       + +   for (i = VB->FirstPrimitive ; !(flags & PRIM_LAST) ; i += length) +   { +      flags = VB->Primitive[i]; +      length= VB->PrimitiveLength[i];	 +      if (length) +	 mga_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 mga_check_render( GLcontext *ctx, struct gl_pipeline_stage *stage ) +{ +   GLuint inputs = VERT_BIT_POS | VERT_BIT_CLIP | VERT_BIT_COLOR0; + +   if (ctx->RenderMode == GL_RENDER) { +      if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)  +	 inputs |= VERT_BIT_COLOR1; + +      if (ctx->Texture.Unit[0]._ReallyEnabled) +	 inputs |= VERT_BIT_TEX0; + +      if (ctx->Texture.Unit[1]._ReallyEnabled) +	 inputs |= VERT_BIT_TEX1; + +      if (ctx->Fog.Enabled)  +	 inputs |= VERT_BIT_FOG; +   } + +   stage->inputs = inputs; +} + + +static void dtr( struct gl_pipeline_stage *stage ) +{ +   (void)stage; +} + + +const struct gl_pipeline_stage _mga_render_stage =  +{  +   "mga 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 */ +   mga_check_render,		/* check - initially set to alloc data */ +   mga_run_render		/* run */ +}; diff --git a/src/mesa/drivers/dri/mga/mgaspan.c b/src/mesa/drivers/dri/mga/mgaspan.c new file mode 100644 index 0000000000..8dc971cfc5 --- /dev/null +++ b/src/mesa/drivers/dri/mga/mgaspan.c @@ -0,0 +1,284 @@ +/* + * Copyright 2000-2001 VA Linux Systems, Inc. + * 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 + * VA LINUX SYSTEMS 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> + */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaspan.c,v 1.11 2002/10/30 12:51:36 alanh Exp $ */ + +#include "mtypes.h" +#include "mgadd.h" +#include "mgacontext.h" +#include "mgaspan.h" +#include "mgaioctl.h" +#include "swrast/swrast.h" + +#define DBG 0 + + +#define LOCAL_VARS					\ +   __DRIdrawablePrivate *dPriv = mmesa->driDrawable;	\ +   mgaScreenPrivate *mgaScreen = mmesa->mgaScreen;	\ +   __DRIscreenPrivate *sPriv = mmesa->driScreen;	\ +   GLuint pitch = mgaScreen->frontPitch;		\ +   GLuint height = dPriv->h;				\ +   char *read_buf = (char *)(sPriv->pFB +		\ +			mmesa->readOffset +		\ +			dPriv->x * mgaScreen->cpp +	\ +			dPriv->y * pitch);		\ +   char *buf = (char *)(sPriv->pFB +			\ +			mmesa->drawOffset +		\ +			dPriv->x * mgaScreen->cpp +	\ +			dPriv->y * pitch);		\ +   GLuint p;						\ +   (void) read_buf; (void) buf; (void) p +    + + +#define LOCAL_DEPTH_VARS						\ +   __DRIdrawablePrivate *dPriv = mmesa->driDrawable;			\ +   mgaScreenPrivate *mgaScreen = mmesa->mgaScreen;			\ +   __DRIscreenPrivate *sPriv = mmesa->driScreen;			\ +   GLuint pitch = mgaScreen->frontPitch;				\ +   GLuint height = dPriv->h;						\ +   char *buf = (char *)(sPriv->pFB +					\ +			mgaScreen->depthOffset +			\ +			dPriv->x * mgaScreen->cpp +			\ +			dPriv->y * pitch) + +#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS  + +#define CLIPPIXEL(_x,_y) (_x >= minx && _x < maxx && \ +			  _y >= miny && _y < maxy) + +#define CLIPSPAN( _x, _y, _n, _x1, _n1, _i )				\ +   if ( _y < miny || _y >= maxy ) {					\ +      _n1 = 0, _x1 = x;							\ +   } else {								\ +      _n1 = _n;								\ +      _x1 = _x;								\ +      if ( _x1 < minx ) _i += (minx-_x1), n1 -= (minx-_x1), _x1 = minx; \ +      if ( _x1 + _n1 >= maxx ) n1 -= (_x1 + n1 - maxx);		        \ +   } + + +#define HW_LOCK()				\ +   mgaContextPtr mmesa = MGA_CONTEXT(ctx);	\ +   FLUSH_BATCH(mmesa);				\ +   LOCK_HARDWARE_QUIESCENT(mmesa); + + +#define HW_CLIPLOOP()						\ +  do {								\ +    int _nc = mmesa->numClipRects;				\ +    while (_nc--) {						\ +       int minx = mmesa->pClipRects[_nc].x1 - mmesa->drawX;	\ +       int miny = mmesa->pClipRects[_nc].y1 - mmesa->drawY;	\ +       int maxx = mmesa->pClipRects[_nc].x2 - mmesa->drawX;	\ +       int maxy = mmesa->pClipRects[_nc].y2 - mmesa->drawY; + +#define HW_ENDCLIPLOOP()			\ +    }						\ +  } while (0) + +#define HW_UNLOCK()				\ +    UNLOCK_HARDWARE(mmesa); + + + + + + + +/* 16 bit, 565 rgb color spanline and pixel functions + */ +#define Y_FLIP(_y) (height - _y - 1) + +#undef INIT_MONO_PIXEL +#define INIT_MONO_PIXEL(p, color) \ +  p = MGAPACKCOLOR565( color[0], color[1], color[2] ) + + +#define WRITE_RGBA( _x, _y, r, g, b, a )				\ +   *(GLushort *)(buf + _x*2 + _y*pitch)  = ( (((int)r & 0xf8) << 8) |	\ +		                             (((int)g & 0xfc) << 3) |	\ +		                             (((int)b & 0xf8) >> 3)) + +#define WRITE_PIXEL( _x, _y, p )  \ +   *(GLushort *)(buf + _x*2 + _y*pitch) = p + +#define READ_RGBA( rgba, _x, _y )				\ +do {								\ +   GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch);	\ +   rgba[0] = (((p >> 11) & 0x1f) * 255) / 31;			\ +   rgba[1] = (((p >>  5) & 0x3f) * 255) / 63;			\ +   rgba[2] = (((p >>  0) & 0x1f) * 255) / 31;			\ +   rgba[3] = 255;						\ +} while(0) + +#define TAG(x) mga##x##_565 +#include "spantmp.h" + + + + + +/* 32 bit, 8888 argb color spanline and pixel functions + */ + +#undef INIT_MONO_PIXEL +#define INIT_MONO_PIXEL(p, color) \ +  p = MGAPACKCOLOR8888( color[0], color[1], color[2], color[3] ) + + +#define WRITE_RGBA(_x, _y, r, g, b, a)			\ +    *(GLuint *)(buf + _x*4 + _y*pitch) = ((r << 16) |	\ +					  (g << 8)  |	\ +					  (b << 0)  |	\ +					  (a << 24) ) + +#define WRITE_PIXEL(_x, _y, p)			\ +    *(GLuint *)(buf + _x*4 + _y*pitch) = p + +#define READ_RGBA(rgba, _x, _y)					\ +    do {							\ +	GLuint p = *(GLuint *)(read_buf + _x*4 + _y*pitch);	\ +	rgba[0] = (p >> 16) & 0xff;				\ +	rgba[1] = (p >> 8)  & 0xff;				\ +	rgba[2] = (p >> 0)  & 0xff;				\ +	rgba[3] = 0xff;						\ +    } while (0) + +#define TAG(x) mga##x##_8888 +#include "spantmp.h" + + + + +/* 16 bit depthbuffer functions. + */ +#define WRITE_DEPTH( _x, _y, d )	\ +   *(GLushort *)(buf + _x*2 + _y*pitch) = d; + +#define READ_DEPTH( d, _x, _y )		\ +   d = *(GLushort *)(buf + _x*2 + _y*pitch); + +#define TAG(x) mga##x##_16 +#include "depthtmp.h" + + + + +/* 32 bit depthbuffer functions. + */ +#define WRITE_DEPTH( _x, _y, d )	\ +   *(GLuint *)(buf + _x*4 + _y*pitch) = d; + +#define READ_DEPTH( d, _x, _y )		\ +   d = *(GLuint *)(buf + _x*4 + _y*pitch); + +#define TAG(x) mga##x##_32 +#include "depthtmp.h" + + + +/* 24/8 bit interleaved depth/stencil functions + */ +#define WRITE_DEPTH( _x, _y, d ) {			\ +   GLuint tmp = *(GLuint *)(buf + _x*4 + _y*pitch);	\ +   tmp &= 0xff;						\ +   tmp |= (d) << 8;					\ +   *(GLuint *)(buf + _x*4 + _y*pitch) = tmp;		\ +} + +#define READ_DEPTH( d, _x, _y )	{				\ +   d = (*(GLuint *)(buf + _x*4 + _y*pitch) & ~0xff) >> 8;	\ +} + +#define TAG(x) mga##x##_24_8 +#include "depthtmp.h" + +#define WRITE_STENCIL( _x, _y, d ) {			\ +   GLuint tmp = *(GLuint *)(buf + _x*4 + _y*pitch);	\ +   tmp &= 0xffffff00;					\ +   tmp |= d & 0xff;					\ +   *(GLuint *)(buf + _x*4 + _y*pitch) = tmp;		\ +} + +#define READ_STENCIL( d, _x, _y )		\ +   d = *(GLuint *)(buf + _x*4 + _y*pitch) & 0xff; + +#define TAG(x) mga##x##_24_8 +#include "stenciltmp.h" + + + +void mgaDDInitSpanFuncs( GLcontext *ctx ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); +   struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx); + +   switch (mmesa->mgaScreen->cpp) { +   case 2: +      swdd->WriteRGBASpan = mgaWriteRGBASpan_565; +      swdd->WriteRGBSpan = mgaWriteRGBSpan_565; +      swdd->WriteMonoRGBASpan = mgaWriteMonoRGBASpan_565; +      swdd->WriteRGBAPixels = mgaWriteRGBAPixels_565; +      swdd->WriteMonoRGBAPixels = mgaWriteMonoRGBAPixels_565; +      swdd->ReadRGBASpan = mgaReadRGBASpan_565; +      swdd->ReadRGBAPixels = mgaReadRGBAPixels_565; + +      swdd->ReadDepthSpan = mgaReadDepthSpan_16; +      swdd->WriteDepthSpan = mgaWriteDepthSpan_16; +      swdd->ReadDepthPixels = mgaReadDepthPixels_16; +      swdd->WriteDepthPixels = mgaWriteDepthPixels_16; +      break; + +   case 4: +      swdd->WriteRGBASpan = mgaWriteRGBASpan_8888; +      swdd->WriteRGBSpan = mgaWriteRGBSpan_8888; +      swdd->WriteMonoRGBASpan = mgaWriteMonoRGBASpan_8888; +      swdd->WriteRGBAPixels = mgaWriteRGBAPixels_8888; +      swdd->WriteMonoRGBAPixels = mgaWriteMonoRGBAPixels_8888; +      swdd->ReadRGBASpan = mgaReadRGBASpan_8888; +      swdd->ReadRGBAPixels = mgaReadRGBAPixels_8888; +       +      if (!mmesa->hw_stencil) { +	 swdd->ReadDepthSpan = mgaReadDepthSpan_32; +	 swdd->WriteDepthSpan = mgaWriteDepthSpan_32; +	 swdd->ReadDepthPixels = mgaReadDepthPixels_32; +	 swdd->WriteDepthPixels = mgaWriteDepthPixels_32; +      } else { +	 swdd->ReadDepthSpan = mgaReadDepthSpan_24_8; +	 swdd->WriteDepthSpan = mgaWriteDepthSpan_24_8; +	 swdd->ReadDepthPixels = mgaReadDepthPixels_24_8; +	 swdd->WriteDepthPixels = mgaWriteDepthPixels_24_8; + +	 swdd->ReadStencilSpan = mgaReadStencilSpan_24_8; +	 swdd->WriteStencilSpan = mgaWriteStencilSpan_24_8; +	 swdd->ReadStencilPixels = mgaReadStencilPixels_24_8; +	 swdd->WriteStencilPixels = mgaWriteStencilPixels_24_8; +      } +      break; +   } +} diff --git a/src/mesa/drivers/dri/mga/mgaspan.h b/src/mesa/drivers/dri/mga/mgaspan.h new file mode 100644 index 0000000000..80583daca2 --- /dev/null +++ b/src/mesa/drivers/dri/mga/mgaspan.h @@ -0,0 +1,34 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaspan.h,v 1.3 2002/10/30 12:51:36 alanh Exp $ */ +/* + * Copyright 2000-2001 VA Linux Systems, Inc. + * 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 + * VA LINUX SYSTEMS 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> + */ + +#ifndef _MGA_SPAN_H +#define _MGA_SPAN_H + +extern void mgaDDInitSpanFuncs( GLcontext *ctx ); + +#endif diff --git a/src/mesa/drivers/dri/mga/mgastate.c b/src/mesa/drivers/dri/mga/mgastate.c new file mode 100644 index 0000000000..02b98fdb76 --- /dev/null +++ b/src/mesa/drivers/dri/mga/mgastate.c @@ -0,0 +1,1131 @@ +/* + * Copyright 2000-2001 VA Linux Systems, Inc. + * 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 + * VA LINUX SYSTEMS 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> + */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgastate.c,v 1.13 2002/10/30 12:51:36 alanh Exp $ */ + +#include <stdio.h> + +#include "mtypes.h" +#include "dd.h" + +#include "mm.h" +#include "mgacontext.h" +#include "mgadd.h" +#include "mgastate.h" +#include "mgatex.h" +#include "mgavb.h" +#include "mgatris.h" +#include "mgaioctl.h" +#include "mgaregs.h" +#include "mgabuffers.h" + +#include "swrast/swrast.h" +#include "array_cache/acache.h" +#include "tnl/tnl.h" +#include "swrast_setup/swrast_setup.h" + + + +/* Some outstanding problems with accelerating logic ops... + */ +#if defined(ACCEL_ROP) +static GLuint mgarop_NoBLK[16] = { +   DC_atype_rpl  | 0x00000000, DC_atype_rstr | 0x00080000, +   DC_atype_rstr | 0x00040000, DC_atype_rpl  | 0x000c0000, +   DC_atype_rstr | 0x00020000, DC_atype_rstr | 0x000a0000, +   DC_atype_rstr | 0x00060000, DC_atype_rstr | 0x000e0000, +   DC_atype_rstr | 0x00010000, DC_atype_rstr | 0x00090000, +   DC_atype_rstr | 0x00050000, DC_atype_rstr | 0x000d0000, +   DC_atype_rpl  | 0x00030000, DC_atype_rstr | 0x000b0000, +   DC_atype_rstr | 0x00070000, DC_atype_rpl  | 0x000f0000 +}; +#endif + + +static void mgaUpdateStencil(const GLcontext *ctx) +{ +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); +   GLuint stencil = 0, stencilctl = 0; + +   if (ctx->Stencil.Enabled) +   { +      stencil = ctx->Stencil.Ref[0] | +	 ( ctx->Stencil.ValueMask[0] << 8 ) | +	 ( ctx->Stencil.WriteMask[0] << 16 ); + +      switch (ctx->Stencil.Function[0]) +      { +      case GL_NEVER: +	 MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_snever); +	 break; +      case GL_LESS: +	 MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_slt); +	 break; +      case GL_LEQUAL: +	 MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_slte); +	 break; +      case GL_GREATER: +	 MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_sgt); +	 break; +      case GL_GEQUAL: +	 MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_sgte); +	 break; +      case GL_NOTEQUAL: +	 MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_sne); +	 break; +      case GL_EQUAL: +	 MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_se); +	 break; +      case GL_ALWAYS: +	 MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_salways); +      default: +	 break; +      } + +      switch (ctx->Stencil.FailFunc[0]) +      { +      case GL_KEEP: +	 MGA_SET_FIELD(stencilctl, SC_sfailop_MASK, SC_sfailop_keep); +	 break; +      case GL_ZERO: +	 MGA_SET_FIELD(stencilctl, SC_sfailop_MASK, SC_sfailop_zero); +	 break; +      case GL_REPLACE: +	 MGA_SET_FIELD(stencilctl, SC_sfailop_MASK, SC_sfailop_replace); +	 break; +      case GL_INCR: +	 MGA_SET_FIELD(stencilctl, SC_sfailop_MASK, SC_sfailop_incrsat); +	 break; +      case GL_DECR: +	 MGA_SET_FIELD(stencilctl, SC_sfailop_MASK, SC_sfailop_decrsat); +	 break; +      case GL_INVERT: +	 MGA_SET_FIELD(stencilctl, SC_sfailop_MASK, SC_sfailop_invert); +	 break; +      default: +	 break; +      } + +      switch (ctx->Stencil.ZFailFunc[0]) +      { +      case GL_KEEP: +	 MGA_SET_FIELD(stencilctl, SC_szfailop_MASK, SC_szfailop_keep); +	 break; +      case GL_ZERO: +	 MGA_SET_FIELD(stencilctl, SC_szfailop_MASK, SC_szfailop_zero); +	 break; +      case GL_REPLACE: +	 MGA_SET_FIELD(stencilctl, SC_szfailop_MASK, SC_szfailop_replace); +	 break; +      case GL_INCR: +	 MGA_SET_FIELD(stencilctl, SC_szfailop_MASK, SC_szfailop_incrsat); +	 break; +      case GL_DECR: +	 MGA_SET_FIELD(stencilctl, SC_szfailop_MASK, SC_szfailop_decrsat); +	 break; +      case GL_INVERT: +	 MGA_SET_FIELD(stencilctl, SC_szfailop_MASK, SC_szfailop_invert); +	 break; +      default: +	 break; +      } + +      switch (ctx->Stencil.ZPassFunc[0]) +      { +      case GL_KEEP: +	 MGA_SET_FIELD(stencilctl, SC_szpassop_MASK, SC_szpassop_keep); +	 break; +      case GL_ZERO: +	 MGA_SET_FIELD(stencilctl, SC_szpassop_MASK, SC_szpassop_zero); +	 break; +      case GL_REPLACE: +	 MGA_SET_FIELD(stencilctl, SC_szpassop_MASK, SC_szpassop_replace); +	 break; +      case GL_INCR: +	 MGA_SET_FIELD(stencilctl, SC_szpassop_MASK, SC_szpassop_incrsat); +	 break; +      case GL_DECR: +	 MGA_SET_FIELD(stencilctl, SC_szpassop_MASK, SC_szpassop_decrsat); +	 break; +      case GL_INVERT: +	 MGA_SET_FIELD(stencilctl, SC_szpassop_MASK, SC_szpassop_invert); +	 break; +      default: +	 break; +      } +   } + +   mmesa->setup.stencil = stencil; +   mmesa->setup.stencilctl = stencilctl; +   mmesa->dirty |= MGA_UPLOAD_CONTEXT; +} + +static void mgaDDStencilFunc(GLcontext *ctx, GLenum func, GLint ref, +			     GLuint mask) +{ +   FLUSH_BATCH( MGA_CONTEXT(ctx) ); +   MGA_CONTEXT(ctx)->new_state |= MGA_NEW_STENCIL; +} + +static void mgaDDStencilMask(GLcontext *ctx, GLuint mask) +{ +   FLUSH_BATCH( MGA_CONTEXT(ctx) ); +   MGA_CONTEXT(ctx)->new_state |= MGA_NEW_STENCIL; +} + +static void mgaDDStencilOp(GLcontext *ctx, GLenum fail, GLenum zfail, +			   GLenum zpass) +{ +   FLUSH_BATCH( MGA_CONTEXT(ctx) ); +   MGA_CONTEXT(ctx)->new_state |= MGA_NEW_STENCIL; +} + +static void mgaDDClearDepth(GLcontext *ctx, GLclampd d) +{ +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); + +   /* KW: should the ~ be there? */ +   switch (mmesa->setup.maccess & ~MA_zwidth_MASK) { +   case MA_zwidth_16: mmesa->ClearDepth = d * 0x0000ffff; break; +   case MA_zwidth_24: mmesa->ClearDepth = d * 0xffffff00; break; +   case MA_zwidth_32: mmesa->ClearDepth = d * 0xffffffff; break; +   default: return; +   } +} + +static void mgaUpdateZMode(const GLcontext *ctx) +{ +   mgaContextPtr mmesa = MGA_CONTEXT( ctx ); +   int zmode = 0; + +   if (ctx->Depth.Test) { +      switch(ctx->Depth.Func)  { +      case GL_NEVER: +         /* can't do this in h/w, we'll use a s/w fallback */ +	 zmode = DC_zmode_nozcmp; +         break; +      case GL_ALWAYS: +	 zmode = DC_zmode_nozcmp; break; +      case GL_LESS: +	 zmode = DC_zmode_zlt; break; +      case GL_LEQUAL: +	 zmode = DC_zmode_zlte; break; +      case GL_EQUAL: +	 zmode = DC_zmode_ze; break; +      case GL_GREATER: +	 zmode = DC_zmode_zgt; break; +      case GL_GEQUAL: +	 zmode = DC_zmode_zgte; break; +      case GL_NOTEQUAL: +	 zmode = DC_zmode_zne; break; +      default: +	 break; +      } + +      if (ctx->Depth.Mask) +         zmode |= DC_atype_zi; +      else +         zmode |= DC_atype_i; +   } +   else { +      zmode |= DC_zmode_nozcmp; +      zmode |= DC_atype_i;  /* don't write to zbuffer */ +   } + +#if defined(ACCEL_ROP) +   mmesa->setup.dwgctl &= DC_bop_MASK; +   if (ctx->Color.ColorLogicOpEnabled) +      zmode |= mgarop_NoBLK[(ctx->Color.LogicOp)&0xf]; +   else +      zmode |= mgarop_NoBLK[GL_COPY & 0xf]; +#endif + +   mmesa->setup.dwgctl &= DC_zmode_MASK & DC_atype_MASK; +   mmesa->setup.dwgctl |= zmode; +   mmesa->dirty |= MGA_UPLOAD_CONTEXT; +} + + +static void mgaDDAlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) +{ +   FLUSH_BATCH( MGA_CONTEXT(ctx) ); +   MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA; +} + + +static void mgaDDBlendEquation(GLcontext *ctx, GLenum mode) +{ +   FLUSH_BATCH( MGA_CONTEXT(ctx) ); +   MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA; + +   /* BlendEquation sets ColorLogicOpEnabled in an unexpected  +    * manner.   +    */ +   FALLBACK( ctx, MGA_FALLBACK_LOGICOP, +	     (ctx->Color.ColorLogicOpEnabled &&  +	      ctx->Color.LogicOp != GL_COPY)); +} + +static void mgaDDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor) +{ +   FLUSH_BATCH( MGA_CONTEXT(ctx) ); +   MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA; +} + +static void mgaDDBlendFuncSeparate( GLcontext *ctx, GLenum sfactorRGB, +				    GLenum dfactorRGB, GLenum sfactorA, +				    GLenum dfactorA ) +{ +   FLUSH_BATCH( MGA_CONTEXT(ctx) ); +   MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA; +} + + + +static void mgaDDLightModelfv(GLcontext *ctx, GLenum pname, +			      const GLfloat *param) +{ +   if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) { +      FLUSH_BATCH( MGA_CONTEXT(ctx) ); +      MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE; +   } +} + + +static void mgaDDShadeModel(GLcontext *ctx, GLenum mode) +{ +   FLUSH_BATCH( MGA_CONTEXT(ctx) ); +   MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE; +} + + +static void mgaDDDepthFunc(GLcontext *ctx, GLenum func) +{ +   FLUSH_BATCH( MGA_CONTEXT(ctx) ); +   MGA_CONTEXT(ctx)->new_state |= MGA_NEW_DEPTH; +} + +static void mgaDDDepthMask(GLcontext *ctx, GLboolean flag) +{ +   FLUSH_BATCH( MGA_CONTEXT(ctx) ); +   MGA_CONTEXT(ctx)->new_state |= MGA_NEW_DEPTH; +} + +#if defined(ACCEL_ROP) +static void mgaDDLogicOp( GLcontext *ctx, GLenum opcode ) +{ +   FLUSH_BATCH( MGA_CONTEXT(ctx) ); +   MGA_CONTEXT(ctx)->new_state |= MGA_NEW_DEPTH; +} +#else +static void mgaDDLogicOp( GLcontext *ctx, GLenum opcode ) +{ +   FLUSH_BATCH( MGA_CONTEXT(ctx) ); +   FALLBACK( ctx, MGA_FALLBACK_LOGICOP,  +	     (ctx->Color.ColorLogicOpEnabled && opcode != GL_COPY) ); +} +#endif + + + +static void mgaDDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param) +{ +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); + +   if (pname == GL_FOG_COLOR) { +      GLuint color = MGAPACKCOLOR888((GLubyte)(ctx->Fog.Color[0]*255.0F),  +				     (GLubyte)(ctx->Fog.Color[1]*255.0F),  +				     (GLubyte)(ctx->Fog.Color[2]*255.0F)); + +      MGA_STATECHANGE(mmesa, MGA_UPLOAD_CONTEXT);    +      mmesa->setup.fogcolor = color; +   } +} + + + + +/* ============================================================= + * Alpha blending + */ + + +static void mgaUpdateAlphaMode(GLcontext *ctx) +{ +   mgaContextPtr mmesa = MGA_CONTEXT( ctx ); +   mgaScreenPrivate *mgaScreen = mmesa->mgaScreen; +   int a = 0; + +   /* determine source of alpha for blending and testing */ +   if ( !ctx->Texture.Unit[0]._ReallyEnabled ) { +      a |= AC_alphasel_diffused; +   } +   else { +      /* G400: Regardless of texture env mode, we use the alpha from the +       * texture unit (AC_alphasel_fromtex) since it will have already +       * been modulated by the incoming fragment color, if needed. +       * We don't want (AC_alphasel_modulate) since that'll effectively +       * do the modulation twice. +       */ +      if (MGA_IS_G400(mmesa)) { +         a |= AC_alphasel_fromtex; +      } +      else { +         /* G200 */ +         switch (ctx->Texture.Unit[0].EnvMode) { +         case GL_DECAL: +            a |= AC_alphasel_diffused; +         case GL_REPLACE: +            a |= AC_alphasel_fromtex; +            break; +         case GL_BLEND: +         case GL_MODULATE: +            a |= AC_alphasel_modulated; +            break; +         default: +            break; +         } +      } +   } + + +   /* alpha test control. +    */ +   if (ctx->Color.AlphaEnabled) { +      GLubyte ref = ctx->Color.AlphaRef; +      switch (ctx->Color.AlphaFunc) { +      case GL_NEVER: +	 a |= AC_atmode_alt; +	 ref = 0; +	 break; +      case GL_LESS: +	 a |= AC_atmode_alt; +	 break; +      case GL_GEQUAL: +	 a |= AC_atmode_agte; +	 break; +      case GL_LEQUAL: +	 a |= AC_atmode_alte; +	 break; +      case GL_GREATER: +	 a |= AC_atmode_agt; +	 break; +      case GL_NOTEQUAL: +	 a |= AC_atmode_ane; +	 break; +      case GL_EQUAL: +	 a |= AC_atmode_ae; +	 break; +      case GL_ALWAYS: +	 a |= AC_atmode_noacmp; +	 break; +      default: +	 break; +      } +      a |= MGA_FIELD(AC_atref,ref); +   } + +   /* blending control */ +   if (ctx->Color.BlendEnabled) { +      switch (ctx->Color.BlendSrcRGB) { +      case GL_ZERO: +	 a |= AC_src_zero; break; +      case GL_SRC_ALPHA: +	 a |= AC_src_src_alpha; break; +      case GL_ONE: +	 a |= AC_src_one; break; +      case GL_DST_COLOR: +	 a |= AC_src_dst_color; break; +      case GL_ONE_MINUS_DST_COLOR: +	 a |= AC_src_om_dst_color; break; +      case GL_ONE_MINUS_SRC_ALPHA: +	 a |= AC_src_om_src_alpha; break; +      case GL_DST_ALPHA: +	 if (mgaScreen->cpp == 4) +	    a |= AC_src_dst_alpha; +	 else +	    a |= AC_src_one; +	 break; +      case GL_ONE_MINUS_DST_ALPHA: +	 if (mgaScreen->cpp == 4) +	    a |= AC_src_om_dst_alpha; +	 else +	    a |= AC_src_zero; +	 break; +      case GL_SRC_ALPHA_SATURATE: +         if (ctx->Visual.alphaBits > 0) +            a |= AC_src_src_alpha_sat; +         else +            a |= AC_src_zero; +	 break; +      default:		/* never happens */ +	 break; +      } + +      switch (ctx->Color.BlendDstRGB) { +      case GL_SRC_ALPHA: +	 a |= AC_dst_src_alpha; break; +      case GL_ONE_MINUS_SRC_ALPHA: +	 a |= AC_dst_om_src_alpha; break; +      case GL_ZERO: +	 a |= AC_dst_zero; break; +      case GL_ONE: +	 a |= AC_dst_one; break; +      case GL_SRC_COLOR: +	 a |= AC_dst_src_color; break; +      case GL_ONE_MINUS_SRC_COLOR: +	 a |= AC_dst_om_src_color; break; +      case GL_DST_ALPHA: +	 if (mgaScreen->cpp == 4) +	    a |= AC_dst_dst_alpha; +	 else +	    a |= AC_dst_one; +	 break; +      case GL_ONE_MINUS_DST_ALPHA: +	 if (mgaScreen->cpp == 4) +	    a |= AC_dst_om_dst_alpha; +	 else +	    a |= AC_dst_zero; +	 break; +      default:		/* never happens */ +	 break; +      } +   } else { +      a |= AC_src_one|AC_dst_zero; +   } + +   mmesa->setup.alphactrl = (AC_amode_alpha_channel | +			     AC_astipple_disable | +			     AC_aten_disable | +			     AC_atmode_noacmp | +			     a); + +   mmesa->dirty |= MGA_UPLOAD_CONTEXT; +} + + + +/* ============================================================= + * Hardware clipping + */ + +void mgaUpdateClipping(const GLcontext *ctx) +{ +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); + +   if (mmesa->driDrawable) +   { +      int x1 = mmesa->driDrawable->x + ctx->Scissor.X; +      int y1 = mmesa->driDrawable->y + mmesa->driDrawable->h +	 - (ctx->Scissor.Y + ctx->Scissor.Height); +      int x2 = x1 + ctx->Scissor.Width - 1; +      int y2 = y1 + ctx->Scissor.Height - 1; + +      if (x1 < 0) x1 = 0; +      if (y1 < 0) y1 = 0; +      if (x2 < 0) x2 = 0; +      if (y2 < 0) y2 = 0; + +      mmesa->scissor_rect.x1 = x1; +      mmesa->scissor_rect.y1 = y1; +      mmesa->scissor_rect.x2 = x2; +      mmesa->scissor_rect.y2 = y2; + +      if (MGA_DEBUG&DEBUG_VERBOSE_2D) +	 fprintf(stderr, "SET SCISSOR %d,%d-%d,%d\n", +		 mmesa->scissor_rect.x1, +		 mmesa->scissor_rect.y1, +		 mmesa->scissor_rect.x2, +		 mmesa->scissor_rect.y2); + +      mmesa->dirty |= MGA_UPLOAD_CLIPRECTS; +   } +} + + +static void mgaDDScissor( GLcontext *ctx, GLint x, GLint y, +			  GLsizei w, GLsizei h ) +{ +   FLUSH_BATCH( MGA_CONTEXT(ctx) ); +   MGA_CONTEXT(ctx)->new_state |= MGA_NEW_CLIP; +} + + +static void mgaDDClearColor(GLcontext *ctx,  +			    const GLfloat color[4] ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); + +   mmesa->ClearColor = mgaPackColor( mmesa->mgaScreen->cpp, +				     color[0], color[1],  +				     color[2], color[3]); +} + + +/* ============================================================= + * Culling + */ + +#define _CULL_DISABLE 0 +#define _CULL_NEGATIVE ((1<<11)|(1<<5)|(1<<16)) +#define _CULL_POSITIVE (1<<11) + + +void mgaUpdateCull( GLcontext *ctx ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); +   GLuint mode = _CULL_DISABLE; + +   if (ctx->Polygon.CullFlag &&  +       mmesa->raster_primitive == GL_TRIANGLES &&        +       ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK)  +   { +      mode = _CULL_NEGATIVE; +      if (ctx->Polygon.CullFaceMode == GL_FRONT) +	 mode ^= (_CULL_POSITIVE ^ _CULL_NEGATIVE); +      if (ctx->Polygon.FrontFace != GL_CCW) +	 mode ^= (_CULL_POSITIVE ^ _CULL_NEGATIVE); +      if ((ctx->Texture.Unit[0]._ReallyEnabled & TEXTURE_2D_BIT) && +          (ctx->Texture.Unit[1]._ReallyEnabled & TEXTURE_2D_BIT)) +	 mode ^= (_CULL_POSITIVE ^ _CULL_NEGATIVE); /* warp bug? */ +   } + +   mmesa->setup.wflag = mode; +   mmesa->dirty |= MGA_UPLOAD_CONTEXT; +} + + +static void mgaDDCullFaceFrontFace(GLcontext *ctx, GLenum mode) +{ +   FLUSH_BATCH( MGA_CONTEXT(ctx) ); +   MGA_CONTEXT(ctx)->new_state |= MGA_NEW_CULL; +} + + + + +/* ============================================================= + * Color masks + */ + +static void mgaDDColorMask(GLcontext *ctx,  +			   GLboolean r, GLboolean g,  +			   GLboolean b, GLboolean a ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT( ctx ); +   mgaScreenPrivate *mgaScreen = mmesa->mgaScreen; + + +   GLuint mask = mgaPackColor(mgaScreen->cpp, +			      ctx->Color.ColorMask[RCOMP], +			      ctx->Color.ColorMask[GCOMP], +			      ctx->Color.ColorMask[BCOMP], +			      ctx->Color.ColorMask[ACOMP]); + +   if (mgaScreen->cpp == 2) +      mask = mask | (mask << 16); + +   if (mmesa->setup.plnwt != mask) { +      MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT ); +      mmesa->setup.plnwt = mask;       +   } +} + +/* ============================================================= + * Polygon stipple + * + * The mga supports a subset of possible 4x4 stipples natively, GL + * wants 32x32.  Fortunately stipple is usually a repeating pattern. + * + * Note: the fully opaque pattern (0xffff) has been disabled in order + * to work around a conformance issue. + */ +static int mgaStipples[16] = { +   0xffff1,  /* See above note */ +   0xa5a5, +   0x5a5a, +   0xa0a0, +   0x5050, +   0x0a0a, +   0x0505, +   0x8020, +   0x0401, +   0x1040, +   0x0208, +   0x0802, +   0x4010, +   0x0104, +   0x2080, +   0x0000 +}; + +static void mgaDDPolygonStipple( GLcontext *ctx, const GLubyte *mask ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); +   const GLubyte *m = mask; +   GLubyte p[4]; +   int i,j,k; +   int active = (ctx->Polygon.StippleFlag &&  +		 mmesa->raster_primitive == GL_TRIANGLES); +   GLuint stipple; + +   FLUSH_BATCH(mmesa); +   mmesa->haveHwStipple = 0; + +   if (active) { +      mmesa->dirty |= MGA_UPLOAD_CONTEXT; +      mmesa->setup.dwgctl &= ~(0xf<<20); +   } + +   p[0] = mask[0] & 0xf; p[0] |= p[0] << 4; +   p[1] = mask[4] & 0xf; p[1] |= p[1] << 4; +   p[2] = mask[8] & 0xf; p[2] |= p[2] << 4; +   p[3] = mask[12] & 0xf; p[3] |= p[3] << 4; + +   for (k = 0 ; k < 8 ; k++) +      for (j = 0 ; j < 4; j++) +	 for (i = 0 ; i < 4 ; i++) +	    if (*m++ != p[j]) { +	       return; +	    } + +   stipple = ( ((p[0] & 0xf) << 0) | +	       ((p[1] & 0xf) << 4) | +	       ((p[2] & 0xf) << 8) | +	       ((p[3] & 0xf) << 12) ); + +   for (i = 0 ; i < 16 ; i++) +      if (mgaStipples[i] == stipple) { +	 mmesa->poly_stipple = i<<20; +	 mmesa->haveHwStipple = 1; +	 break; +      } +    +   if (active) { +      mmesa->setup.dwgctl &= ~(0xf<<20); +      mmesa->setup.dwgctl |= mmesa->poly_stipple; +   } +} + +/* ============================================================= + */ + +static void mgaDDPrintDirty( const char *msg, GLuint state ) +{ +   fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s%s\n", +	   msg, +	   (unsigned int) state, +	   (state & MGA_WAIT_AGE) ? "wait-age, " : "", +	   (state & MGA_UPLOAD_TEX0IMAGE)  ? "upload-tex0-img, " : "", +	   (state & MGA_UPLOAD_TEX1IMAGE)  ? "upload-tex1-img, " : "", +	   (state & MGA_UPLOAD_CONTEXT)        ? "upload-ctx, " : "", +	   (state & MGA_UPLOAD_TEX0)       ? "upload-tex0, " : "", +	   (state & MGA_UPLOAD_TEX1)       ? "upload-tex1, " : "", +	   (state & MGA_UPLOAD_PIPE)       ? "upload-pipe, " : "" +      ); +} + +/* Push the state into the sarea and/or texture memory. + */ +void mgaEmitHwStateLocked( mgaContextPtr mmesa ) +{ +   MGASAREAPrivPtr sarea = mmesa->sarea; + +   if (MGA_DEBUG & DEBUG_VERBOSE_MSG) +      mgaDDPrintDirty( "mgaEmitHwStateLocked", mmesa->dirty ); + +   if ((mmesa->dirty & MGA_UPLOAD_TEX0IMAGE) && mmesa->CurrentTexObj[0]) +      mgaUploadTexImages(mmesa, mmesa->CurrentTexObj[0]); + +   if ((mmesa->dirty & MGA_UPLOAD_TEX1IMAGE) && mmesa->CurrentTexObj[1]) +      mgaUploadTexImages(mmesa, mmesa->CurrentTexObj[1]); + +   if (mmesa->dirty & MGA_UPLOAD_CONTEXT) { +      memcpy( &sarea->ContextState, &mmesa->setup, sizeof(mmesa->setup)); +   } + +   if ((mmesa->dirty & MGA_UPLOAD_TEX0) && mmesa->CurrentTexObj[0]) { +      memcpy(&sarea->TexState[0], +	     &mmesa->CurrentTexObj[0]->setup, +	     sizeof(sarea->TexState[0])); +   } + +   if ((mmesa->dirty & MGA_UPLOAD_TEX1) && mmesa->CurrentTexObj[1]) { +      memcpy(&sarea->TexState[1], +	     &mmesa->CurrentTexObj[1]->setup, +	     sizeof(sarea->TexState[1])); +   } + +   if (sarea->TexState[0].texctl2 != +       sarea->TexState[1].texctl2) { +      memcpy(&sarea->TexState[1], +	     &sarea->TexState[0], +	     sizeof(sarea->TexState[0])); +      mmesa->dirty |= MGA_UPLOAD_TEX1|MGA_UPLOAD_TEX0; +   } + +   if (mmesa->dirty & MGA_UPLOAD_PIPE) { +/*        mmesa->sarea->wacceptseq = mmesa->hw_primitive; */ +      mmesa->sarea->WarpPipe = mmesa->vertex_format; +      mmesa->sarea->vertsize = mmesa->vertex_size; +   } + +   mmesa->sarea->dirty |= mmesa->dirty; + +   mmesa->dirty &= (MGA_UPLOAD_CLIPRECTS|MGA_WAIT_AGE); + +   /* This is a bit of a hack but seems to be the best place to ensure +    * that separate specular is disabled when not needed. +    */ +   if (mmesa->glCtx->Texture.Unit[0]._ReallyEnabled == 0 || +       !mmesa->glCtx->Light.Enabled || +       mmesa->glCtx->Light.Model.ColorControl == GL_SINGLE_COLOR) { +      sarea->TexState[0].texctl2 &= ~TMC_specen_enable; +      sarea->TexState[1].texctl2 &= ~TMC_specen_enable; +   } +} + +/* Fallback to swrast for select and feedback. + */ +static void mgaRenderMode( GLcontext *ctx, GLenum mode ) +{ +   FALLBACK( ctx, MGA_FALLBACK_RENDERMODE, (mode != GL_RENDER) ); +} + + +/* ============================================================= + */ + +void mgaCalcViewport( GLcontext *ctx ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); +   const GLfloat *v = ctx->Viewport._WindowMap.m; +   GLfloat *m = mmesa->hw_viewport; + +   /* See also mga_translate_vertex. +    */ +   m[MAT_SX] =   v[MAT_SX]; +   m[MAT_TX] =   v[MAT_TX] + mmesa->drawX + SUBPIXEL_X; +   m[MAT_SY] = - v[MAT_SY]; +   m[MAT_TY] = - v[MAT_TY] + mmesa->driDrawable->h + mmesa->drawY + SUBPIXEL_Y; +   m[MAT_SZ] =   v[MAT_SZ] * mmesa->depth_scale; +   m[MAT_TZ] =   v[MAT_TZ] * mmesa->depth_scale; + +   mmesa->SetupNewInputs = ~0; +} + +static void mgaViewport( GLcontext *ctx,  +			  GLint x, GLint y,  +			  GLsizei width, GLsizei height ) +{ +   mgaCalcViewport( ctx ); +} + +static void mgaDepthRange( GLcontext *ctx,  +			    GLclampd nearval, GLclampd farval ) +{ +   mgaCalcViewport( ctx ); +} + +/* ============================================================= + */ + +static void mgaDDEnable(GLcontext *ctx, GLenum cap, GLboolean state) +{ +   mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + +   switch(cap) { +   case GL_ALPHA_TEST: +      FLUSH_BATCH( mmesa ); +      mmesa->new_state |= MGA_NEW_ALPHA; +      break; +   case GL_BLEND: +      FLUSH_BATCH( mmesa ); +      mmesa->new_state |= MGA_NEW_ALPHA; + +      /* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled. +       */ +      FALLBACK( ctx, MGA_FALLBACK_LOGICOP, +		(ctx->Color.ColorLogicOpEnabled &&  +		 ctx->Color.LogicOp != GL_COPY)); +      break; +   case GL_DEPTH_TEST: +      FLUSH_BATCH( mmesa ); +      mmesa->new_state |= MGA_NEW_DEPTH; +      FALLBACK (ctx, MGA_FALLBACK_DEPTH, +		ctx->Depth.Func == GL_NEVER && ctx->Depth.Test); +      break; +   case GL_SCISSOR_TEST: +      FLUSH_BATCH( mmesa ); +      mmesa->scissor = state; +      mmesa->new_state |= MGA_NEW_CLIP; +      break; +   case GL_FOG: +      MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT ); +      if (ctx->Fog.Enabled)  +	 mmesa->setup.maccess |= MA_fogen_enable; +      else +	 mmesa->setup.maccess &= ~MA_fogen_enable; +      break; +   case GL_CULL_FACE: +      FLUSH_BATCH( mmesa ); +      mmesa->new_state |= MGA_NEW_CULL; +      break; +   case GL_TEXTURE_1D: +   case GL_TEXTURE_2D: +   case GL_TEXTURE_3D: +      FLUSH_BATCH( mmesa ); +      mmesa->new_state |= (MGA_NEW_TEXTURE|MGA_NEW_ALPHA); +      break; +   case GL_POLYGON_STIPPLE: +      if (mmesa->haveHwStipple && mmesa->raster_primitive == GL_TRIANGLES) { +	 FLUSH_BATCH(mmesa); +	 mmesa->dirty |= MGA_UPLOAD_CONTEXT; +	 mmesa->setup.dwgctl &= ~(0xf<<20); +	 if (state) +	    mmesa->setup.dwgctl |= mmesa->poly_stipple; +      } +      break; +   case GL_COLOR_LOGIC_OP: +      FLUSH_BATCH( mmesa ); +#if !defined(ACCEL_ROP) +      FALLBACK( ctx, MGA_FALLBACK_LOGICOP,  +		(state && ctx->Color.LogicOp != GL_COPY)); +#else +      mmesa->new_state |= MGA_NEW_DEPTH; +#endif +      break; +   case GL_STENCIL_TEST: +      FLUSH_BATCH( mmesa ); +      if (mmesa->hw_stencil) +	 mmesa->new_state |= MGA_NEW_STENCIL; +      else +	 FALLBACK( ctx, MGA_FALLBACK_STENCIL, state ); +   default: +      break; +   } +} + + +/* ============================================================= + */ + + + +/* ============================================================= + */ + +static void mgaDDPrintState( const char *msg, GLuint state ) +{ +   fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s\n", +	   msg, +	   state, +	   (state & MGA_NEW_DEPTH)   ? "depth, " : "", +	   (state & MGA_NEW_ALPHA)   ? "alpha, " : "", +	   (state & MGA_NEW_CLIP)    ? "clip, " : "", +	   (state & MGA_NEW_CULL)    ? "cull, " : "", +	   (state & MGA_NEW_TEXTURE) ? "texture, " : "", +	   (state & MGA_NEW_CONTEXT) ? "context, " : ""); +} + +void mgaDDUpdateHwState( GLcontext *ctx ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT( ctx ); +   int new_state = mmesa->new_state; + +   if (new_state) +   { +      FLUSH_BATCH( mmesa ); + +      mmesa->new_state = 0; + +      if (MESA_VERBOSE&VERBOSE_DRIVER) +	 mgaDDPrintState("UpdateHwState", new_state); + +      if (new_state & MGA_NEW_DEPTH) +	 mgaUpdateZMode(ctx); + +      if (new_state & MGA_NEW_ALPHA) +	 mgaUpdateAlphaMode(ctx); + +      if (new_state & MGA_NEW_CLIP) +	 mgaUpdateClipping(ctx); + +      if (new_state & MGA_NEW_STENCIL) +	 mgaUpdateStencil(ctx); + +      if (new_state & (MGA_NEW_WARP|MGA_NEW_CULL)) +	 mgaUpdateCull(ctx); + +      if (new_state & (MGA_NEW_WARP|MGA_NEW_TEXTURE)) +	 mgaUpdateTextureState(ctx); +   } +} + + +static void mgaDDInvalidateState( GLcontext *ctx, GLuint new_state ) +{ +   _swrast_InvalidateState( ctx, new_state ); +   _swsetup_InvalidateState( ctx, new_state ); +   _ac_InvalidateState( ctx, new_state ); +   _tnl_InvalidateState( ctx, new_state ); +   MGA_CONTEXT(ctx)->new_gl_state |= new_state; +} + + + +void mgaInitState( mgaContextPtr mmesa ) +{ +   mgaScreenPrivate *mgaScreen = mmesa->mgaScreen; +   GLcontext *ctx = mmesa->glCtx; + +   if (ctx->Color._DrawDestMask == BACK_LEFT_BIT) { +      mmesa->draw_buffer = MGA_BACK; +      mmesa->read_buffer = MGA_BACK; +      mmesa->drawOffset = mmesa->mgaScreen->backOffset; +      mmesa->readOffset = mmesa->mgaScreen->backOffset; +      mmesa->setup.dstorg = mgaScreen->backOffset; +   } else { +      mmesa->draw_buffer = MGA_FRONT; +      mmesa->read_buffer = MGA_FRONT; +      mmesa->drawOffset = mmesa->mgaScreen->frontOffset; +      mmesa->readOffset = mmesa->mgaScreen->frontOffset; +      mmesa->setup.dstorg = mgaScreen->frontOffset; +   } + +   mmesa->setup.maccess = (MA_memreset_disable | +			   MA_fogen_disable | +			   MA_tlutload_disable | +			   MA_nodither_disable | +			   MA_dit555_disable); + +   switch (mmesa->mgaScreen->cpp) { +   case 2: +      mmesa->setup.maccess |= MA_pwidth_16; +      break; +   case 4: +      mmesa->setup.maccess |= MA_pwidth_32; +      break; +   default: +      fprintf( stderr, "Error: unknown cpp %d, exiting...\n", +	       mmesa->mgaScreen->cpp ); +      exit( 1 ); +   } + +   switch (mmesa->glCtx->Visual.depthBits) { +   case 16: +      mmesa->setup.maccess |= MA_zwidth_16; +      break; +   case 24: +      mmesa->setup.maccess |= MA_zwidth_24; +      break; +   case 32: +      mmesa->setup.maccess |= MA_pwidth_32; +      break; +   } + +   mmesa->setup.dwgctl = (DC_opcod_trap | +			  DC_atype_i | +			  DC_linear_xy | +			  DC_zmode_nozcmp | +			  DC_solid_disable | +			  DC_arzero_disable | +			  DC_sgnzero_disable | +			  DC_shftzero_enable | +			  (0xC << DC_bop_SHIFT) | +			  (0x0 << DC_trans_SHIFT) | +			  DC_bltmod_bmonolef | +			  DC_pattern_disable | +			  DC_transc_disable | +			  DC_clipdis_disable); + + +   mmesa->setup.plnwt = ~0; +   mmesa->setup.alphactrl = ( AC_src_one | +			      AC_dst_zero | +			      AC_amode_FCOL | +			      AC_astipple_disable | +			      AC_aten_disable | +			      AC_atmode_noacmp | +			      AC_alphasel_fromtex ); + +   mmesa->setup.fogcolor = +      MGAPACKCOLOR888((GLubyte)(ctx->Fog.Color[0]*255.0F), +		      (GLubyte)(ctx->Fog.Color[1]*255.0F), +		      (GLubyte)(ctx->Fog.Color[2]*255.0F)); + +   mmesa->setup.wflag = 0; +   mmesa->setup.tdualstage0 = 0; +   mmesa->setup.tdualstage1 = 0; +   mmesa->setup.fcol = 0; +   mmesa->new_state = ~0; +} + + +void mgaDDInitStateFuncs( GLcontext *ctx ) +{ +   ctx->Driver.UpdateState = mgaDDInvalidateState; +   ctx->Driver.Enable = mgaDDEnable; +   ctx->Driver.LightModelfv = mgaDDLightModelfv; +   ctx->Driver.AlphaFunc = mgaDDAlphaFunc; +   ctx->Driver.BlendEquation = mgaDDBlendEquation; +   ctx->Driver.BlendFunc = mgaDDBlendFunc; +   ctx->Driver.BlendFuncSeparate = mgaDDBlendFuncSeparate; +   ctx->Driver.DepthFunc = mgaDDDepthFunc; +   ctx->Driver.DepthMask = mgaDDDepthMask; +   ctx->Driver.Fogfv = mgaDDFogfv; +   ctx->Driver.Scissor = mgaDDScissor; +   ctx->Driver.ShadeModel = mgaDDShadeModel; +   ctx->Driver.CullFace = mgaDDCullFaceFrontFace; +   ctx->Driver.FrontFace = mgaDDCullFaceFrontFace; +   ctx->Driver.ColorMask = mgaDDColorMask; + +   ctx->Driver.DrawBuffer = mgaDDSetDrawBuffer; +   ctx->Driver.ReadBuffer = mgaDDSetReadBuffer; +   ctx->Driver.ClearColor = mgaDDClearColor; +   ctx->Driver.ClearDepth = mgaDDClearDepth; +   ctx->Driver.LogicOpcode = mgaDDLogicOp; + +   ctx->Driver.PolygonStipple = mgaDDPolygonStipple; + +   ctx->Driver.StencilFunc = mgaDDStencilFunc; +   ctx->Driver.StencilMask = mgaDDStencilMask; +   ctx->Driver.StencilOp = mgaDDStencilOp; + +   ctx->Driver.DepthRange = mgaDepthRange; +   ctx->Driver.Viewport = mgaViewport; +   ctx->Driver.RenderMode = mgaRenderMode; + +   ctx->Driver.ClearIndex = 0; +   ctx->Driver.IndexMask = 0; + +   /* 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/src/mesa/drivers/dri/mga/mgastate.h b/src/mesa/drivers/dri/mga/mgastate.h new file mode 100644 index 0000000000..a9f1039d76 --- /dev/null +++ b/src/mesa/drivers/dri/mga/mgastate.h @@ -0,0 +1,42 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgastate.h,v 1.5 2002/10/30 12:51:36 alanh Exp $ */ +/* + * Copyright 2000-2001 VA Linux Systems, Inc. + * 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 + * VA LINUX SYSTEMS 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> + */ + +#ifndef _MGA_STATE_H +#define _MGA_STATE_H + + +extern void mgaInitState( mgaContextPtr mmesa ); +extern void mgaDDInitStateFuncs(GLcontext *ctx); +extern void mgaDDUpdateHwState( GLcontext *ctx ); +extern void mgaUpdateClipping(const GLcontext *ctx); +extern void mgaUpdateCull( GLcontext *ctx ); +extern void mgaCalcViewport( GLcontext *ctx ); + + + +#endif diff --git a/src/mesa/drivers/dri/mga/mgatex.c b/src/mesa/drivers/dri/mga/mgatex.c new file mode 100644 index 0000000000..b4ee787e0b --- /dev/null +++ b/src/mesa/drivers/dri/mga/mgatex.c @@ -0,0 +1,985 @@ +/* + * Copyright 2000-2001 VA Linux Systems, Inc. + * 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 + * VA LINUX SYSTEMS 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> + */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatex.c,v 1.14 2002/10/30 12:51:36 alanh Exp $ */ + +#include <stdlib.h> +#include <stdio.h> +#include <GL/gl.h> + +#include "mm.h" +#include "mgacontext.h" +#include "mgatex.h" +#include "mgaregs.h" +#include "mgatris.h" +#include "mgaioctl.h" + +#include "enums.h" +#include "simple_list.h" +/*#include "mem.h"*/ +#include "macros.h" +#include "texformat.h" +#include "texstore.h" +#include "teximage.h" + +#include "swrast/swrast.h" + +#define TEX_0 1 +#define TEX_1 2 + +/* + * mgaDestroyTexObj + * Free all memory associated with a texture and NULL any pointers + * to it. + */ +void +mgaDestroyTexObj( mgaContextPtr mmesa, mgaTextureObjectPtr t ) +{ +   if ( !t ) return; + +   /* free the texture memory */ +   if (t->MemBlock) { +      mmFreeMem( t->MemBlock ); +      t->MemBlock = 0; + +      if (mmesa && t->age > mmesa->dirtyAge) +	 mmesa->dirtyAge = t->age; +   } + +   /* free mesa's link */ +   if (t->tObj) +      t->tObj->DriverData = NULL; + +   /* see if it was the driver's current object */ +   if (mmesa) { +      if (t->bound & TEX_0) mmesa->CurrentTexObj[0] = 0; +      if (t->bound & TEX_1) mmesa->CurrentTexObj[1] = 0; +   } +	 +   remove_from_list(t); +   free( t ); +} + + +/* + * mgaSetTexWrappings + */ +static void mgaSetTexWrapping( mgaTextureObjectPtr t, +			       GLenum sWrap, +			       GLenum tWrap ) +{ +   GLuint val = 0; + +   if (sWrap != GL_REPEAT) +      val |= TMC_clampu_enable; + +   if (tWrap != GL_REPEAT) +      val |= TMC_clampv_enable; + +   t->setup.texctl &= ~(TMC_clampu_enable|TMC_clampv_enable); +   t->setup.texctl |= val; +} + + +/* + * mgaSetTexFilter + */ +static void mgaSetTexFilter(mgaTextureObjectPtr t, GLenum minf, GLenum magf) +{ +   GLuint val = 0; + +   switch (minf) { +   case GL_NEAREST: val = TF_minfilter_nrst; break; +   case GL_LINEAR: val = TF_minfilter_bilin; break; +   case GL_NEAREST_MIPMAP_NEAREST: val = TF_minfilter_mm1s; break; +   case GL_LINEAR_MIPMAP_NEAREST: val = TF_minfilter_mm4s; break; +   case GL_NEAREST_MIPMAP_LINEAR: val = TF_minfilter_mm2s; break; +   case GL_LINEAR_MIPMAP_LINEAR: val = TF_minfilter_mm8s; break; +   default: val = TF_minfilter_nrst; break; +   } + +   switch (magf) { +   case GL_NEAREST: val |= TF_magfilter_nrst; break; +   case GL_LINEAR: val |= TF_magfilter_bilin; break; +   default: val |= TF_magfilter_nrst; break; +   } + +   /* See OpenGL 1.2 specification */ +   if (magf == GL_LINEAR && (minf == GL_NEAREST_MIPMAP_NEAREST || +			     minf == GL_NEAREST_MIPMAP_LINEAR)) { +      val |= (0x20 << TF_fthres_SHIFT); /* c = 0.5 */ +   } else { +      val |= (0x10 << TF_fthres_SHIFT); /* c = 0 */ +   } + + +   t->setup.texfilter &= (TF_minfilter_MASK | +			  TF_magfilter_MASK | +			  TF_fthres_MASK); +   t->setup.texfilter |= val; +} + +/* + * mgaSetTexBorderColor + */ +static void mgaSetTexBorderColor(mgaTextureObjectPtr t, GLubyte color[4]) +{ +   t->setup.texbordercol = MGAPACKCOLOR8888(color[0],color[1], +					    color[2],color[3]); +} + + +static GLint mgaChooseTexFormat( mgaContextPtr mmesa, +				 struct gl_texture_image *texImage, +				 GLenum format, GLenum type ) +{ +   const GLboolean do32bpt = mmesa->default32BitTextures; +   const struct gl_texture_format *texFormat; +   GLint ret; + +   if ( 0 ) +      fprintf( stderr, "internal=%s format=%s type=%s\n", +	       texImage->IntFormat == 3 ? "GL_RGB (3)" : +	       texImage->IntFormat == 4 ? "GL_RGBA (4)" : +	       _mesa_lookup_enum_by_nr( texImage->IntFormat ), +	       _mesa_lookup_enum_by_nr( format ), +	       _mesa_lookup_enum_by_nr( type ) ); + +#define SET_FORMAT( r, gl )						\ +   do {									\ +      ret = (r);							\ +      texFormat = &(gl);						\ +   } while (0) + +#define SET_FORMAT_32BPT( r32, gl32, r16, gl16 )			\ +   do {									\ +      if ( do32bpt ) {							\ +	 ret = (r32);							\ +	 texFormat = &(gl32);						\ +      } else {								\ +	 ret = (r16);							\ +	 texFormat = &(gl16);						\ +      }									\ +   } while (0) + +   switch ( texImage->IntFormat ) { +      /* GH: Bias towards GL_RGB, GL_RGBA texture formats.  This has +       * got to be better than sticking them way down the end of this +       * huge list. +       */ +   case 4: +   case GL_RGBA: +   case GL_COMPRESSED_RGBA: +      if ( format == GL_BGRA ) { +	 if ( type == GL_UNSIGNED_INT_8_8_8_8_REV ) { +	    SET_FORMAT( TMC_tformat_tw32, _mesa_texformat_argb8888 ); +	    break; +	 } else if ( type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) { +	    SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 ); +	    break; +	 } else if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) { +	    SET_FORMAT( TMC_tformat_tw15, _mesa_texformat_argb1555 ); +	    break; +	 } +      } +      SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888, +			TMC_tformat_tw12, _mesa_texformat_argb4444 ); +      break; + +   case 3: +   case GL_RGB: +   case GL_COMPRESSED_RGB: +      if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) { +	 SET_FORMAT( TMC_tformat_tw16, _mesa_texformat_rgb565 ); +	 break; +      } +      SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888, +			TMC_tformat_tw16, _mesa_texformat_rgb565 ); +      break; + +      /* GH: Okay, keep checking as normal.  Still test for GL_RGB, +       * GL_RGBA formats first. +       */ +   case GL_RGBA8: +   case GL_RGB10_A2: +   case GL_RGBA12: +   case GL_RGBA16: +      SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888, +			TMC_tformat_tw12, _mesa_texformat_argb4444 ); +      break; + +   case GL_RGBA4: +   case GL_RGBA2: +      SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 ); +      break; + +   case GL_RGB5_A1: +      SET_FORMAT( TMC_tformat_tw15, _mesa_texformat_argb1555 ); +      break; + +   case GL_RGB8: +   case GL_RGB10: +   case GL_RGB12: +   case GL_RGB16: +      SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888, +			TMC_tformat_tw16, _mesa_texformat_rgb565 ); +      break; + +   case GL_RGB5: +   case GL_RGB4: +   case GL_R3_G3_B2: +      SET_FORMAT( TMC_tformat_tw16, _mesa_texformat_rgb565 ); +      break; + +   case GL_ALPHA: +   case GL_ALPHA4: +   case GL_ALPHA8: +   case GL_ALPHA12: +   case GL_ALPHA16: +   case GL_COMPRESSED_ALPHA: +      /* FIXME: This will report incorrect component sizes... */ +      SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 ); +      break; + +   case 1: +   case GL_LUMINANCE: +   case GL_LUMINANCE4: +   case GL_LUMINANCE8: +   case GL_LUMINANCE12: +   case GL_LUMINANCE16: +   case GL_COMPRESSED_LUMINANCE: +      /* FIXME: This will report incorrect component sizes... */ +      SET_FORMAT( TMC_tformat_tw16, _mesa_texformat_rgb565 ); +      break; + +   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: +   case GL_COMPRESSED_LUMINANCE_ALPHA: +      /* FIXME: This will report incorrect component sizes... */ +      SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 ); +      break; + +   case GL_INTENSITY: +   case GL_INTENSITY4: +   case GL_INTENSITY8: +   case GL_INTENSITY12: +   case GL_INTENSITY16: +   case GL_COMPRESSED_INTENSITY: +      /* FIXME: This will report incorrect component sizes... */ +      SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 ); +      break; + +   case GL_COLOR_INDEX: +   case GL_COLOR_INDEX1_EXT: +   case GL_COLOR_INDEX2_EXT: +   case GL_COLOR_INDEX4_EXT: +   case GL_COLOR_INDEX8_EXT: +   case GL_COLOR_INDEX12_EXT: +   case GL_COLOR_INDEX16_EXT: +      SET_FORMAT( TMC_tformat_tw8, _mesa_texformat_ci8 ); +      break; + +   default: +      fprintf( stderr, "bad texture format in mgaChooseTexFormat() %d", +	       texImage->IntFormat ); +      return -1; +   } + +   texImage->TexFormat = texFormat; + +   return ret; +} + + +/* + * mgaCreateTexObj + * Allocate space for and load the mesa images into the texture memory block. + * This will happen before drawing with a new texture, or drawing with a + * texture after it was swapped out or teximaged again. + */ +static void mgaCreateTexObj(mgaContextPtr mmesa, +			    struct gl_texture_object *tObj) +{ +   const GLint baseLevel = tObj->BaseLevel; +   struct gl_texture_image *image = tObj->Image[baseLevel]; +   mgaTextureObjectPtr t; +   int i, ofs; +   int LastLevel; +   int s, s2; +   int tformat; + +   if (!image) return; + +   tObj->DriverData = t = calloc( 1, sizeof( *t ) ); +   if (!t) { +      fprintf(stderr, "mgaCreateTexObj: Failed to malloc mgaTextureObject\n" ); +      return; +   } + +   /* FIXME: Use the real DD interface... +    */ +   tformat = mgaChooseTexFormat( mmesa, image, image->Format, +				 GL_UNSIGNED_BYTE ); +   t->texelBytes = image->TexFormat->TexelBytes; + +   /* We are going to upload all levels that are present, even if +    * later levels wouldn't be used by the current filtering mode.  This +    * allows the filtering mode to change without forcing another upload +    * of the images. +    */ +   LastLevel = MGA_TEX_MAXLEVELS-1; + +   ofs = 0; +   for ( i = 0 ; i <= LastLevel ; i++ ) { +      if ( !tObj->Image[i] ) { +	 LastLevel = i - 1; +	 break; +      } + +      t->offsets[i] = ofs; +      t->dirty_images |= (1<<i); + +      ofs += ((MAX2( tObj->Image[i]->Width, 8 ) * +	       MAX2( tObj->Image[i]->Height, 8 ) * +	       t->texelBytes) + 31) & ~31; +   } +   t->totalSize = ofs; +   t->lastLevel = LastLevel; +   t->tObj = tObj; +   t->ctx = mmesa; +   t->age = 0; +   t->bound = 0; +   t->MemBlock = 0; + +   insert_at_tail(&(mmesa->SwappedOut), t); + + +   /* setup hardware register values */ +   t->setup.texctl = TMC_takey_1 | TMC_tamask_0 | tformat; + +   if (image->WidthLog2 >= 3) +      t->setup.texctl |= ((image->WidthLog2 - 3) << TMC_tpitch_SHIFT); +   else +      t->setup.texctl |= (TMC_tpitchlin_enable | +			  (image->Width << TMC_tpitchext_SHIFT)); + + +   t->setup.texctl2 = TMC_ckstransdis_enable; + +   if ( mmesa->glCtx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ) +      t->setup.texctl2 |= TMC_specen_enable; + + +   t->setup.texfilter = (TF_minfilter_nrst | +			 TF_magfilter_nrst | +			 TF_filteralpha_enable | +			 (0x10 << TF_fthres_SHIFT) | +			 (LastLevel << TF_mapnb_SHIFT)); + +   /* warp texture registers */ +   ofs = MGA_IS_G200(mmesa) ? 28 : 11; +   s = image->Width; +   s2 = image->WidthLog2; +   t->setup.texwidth = (MGA_FIELD(TW_twmask, s - 1) | +			MGA_FIELD(TW_rfw, (10 - s2 - 8) & 63 ) | +			MGA_FIELD(TW_tw, (s2 + ofs ) | 0x40 )); + + +   s = image->Height; +   s2 = image->HeightLog2; +   t->setup.texheight = (MGA_FIELD(TH_thmask, s - 1) | +			 MGA_FIELD(TH_rfh, (10 - s2 - 8) & 63 ) | +			 MGA_FIELD(TH_th, (s2 + ofs ) | 0x40 )); + + +   /* set all the register values for filtering, border, etc */ +   mgaSetTexWrapping( t, tObj->WrapS, tObj->WrapT ); +   mgaSetTexFilter( t, tObj->MinFilter, tObj->MagFilter ); +   mgaSetTexBorderColor( t, tObj->_BorderChan ); +} + + + + +static void mgaUpdateTextureEnvG200( GLcontext *ctx ) +{ +   struct gl_texture_object *tObj = ctx->Texture.Unit[0]._Current; +   mgaTextureObjectPtr t; + +   if (!tObj || !tObj->DriverData) +      return; + +   t = (mgaTextureObjectPtr)tObj->DriverData; + +   t->setup.texctl2 &= ~TMC_decalblend_enable; + +   switch (ctx->Texture.Unit[0].EnvMode) { +   case GL_REPLACE: +      t->setup.texctl &= ~TMC_tmodulate_enable; +      break; +   case GL_MODULATE: +      t->setup.texctl |= TMC_tmodulate_enable; +      break; +   case GL_DECAL: +      t->setup.texctl &= ~TMC_tmodulate_enable; +      t->setup.texctl2 |= TMC_decalblend_enable; +      break; +   case GL_BLEND: +      FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE ); +      break; +   default: +      break; +   } +} + +static void mgaUpdateTextureEnvG400( GLcontext *ctx, int unit ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT( ctx ); +   GLuint *reg = ((GLuint *)&mmesa->setup.tdualstage0 + unit); +   GLuint source = mmesa->tmu_source[unit]; +   struct gl_texture_object *tObj = ctx->Texture.Unit[source]._Current; +   GLenum format; + +   if ( tObj != ctx->Texture.Unit[source].Current2D || !tObj )  +      return; + +   format = tObj->Image[tObj->BaseLevel]->Format; + +   switch (ctx->Texture.Unit[source].EnvMode) { +   case GL_REPLACE: +      if (format == GL_RGB || format == GL_LUMINANCE) { +	 *reg = (TD0_color_sel_arg1 | +                 TD0_alpha_arg2_diffuse | +		 TD0_alpha_sel_arg2 ); +      } +      else if (format == GL_ALPHA) { +         *reg = (TD0_color_sel_arg2 | +                 TD0_color_arg2_diffuse | +                 TD0_alpha_sel_arg1 ); +      } +      else { +         *reg = (TD0_color_sel_arg1 | +                 TD0_alpha_sel_arg1 ); +      } +      break; + +   case GL_MODULATE: +      if (unit == 0) { +	 *reg = ( TD0_color_arg2_diffuse | +		  TD0_color_sel_mul | +		  TD0_alpha_arg2_diffuse | +		  TD0_alpha_sel_mul); +      } +      else { +	 *reg = ( TD0_color_arg2_prevstage | +		  TD0_color_alpha_prevstage | +		  TD0_color_sel_mul | +		  TD0_alpha_arg2_prevstage | +		  TD0_alpha_sel_mul); +      } +      break; +   case GL_DECAL: +      if (format == GL_RGB) { +         if (unit == 0) { +            *reg = (TD0_color_sel_arg1 | +                    TD0_alpha_arg2_diffuse | +                    TD0_alpha_sel_arg2 ); +         } +         else { +            *reg = (TD0_color_sel_arg1 | +                    TD0_alpha_arg2_prevstage | +                    TD0_alpha_sel_arg2 ); +         } +      } +      else if ( format == GL_RGBA ) { +#if 0 +         if (unit == 0) { +            /* this doesn't work */ +            *reg = (TD0_color_arg2_diffuse | +                    TD0_color_alpha_currtex | +                    TD0_color_alpha2inv_enable | +                    TD0_color_arg2mul_alpha2 | +                    TD0_color_arg1mul_alpha1 | +                    TD0_color_blend_enable | +                    TD0_color_arg1add_mulout | +                    TD0_color_arg2add_mulout | +                    TD0_color_add_add | +                    TD0_color_sel_mul | +                    TD0_alpha_arg2_diffuse | +                    TD0_alpha_sel_arg2 ); +         } +         else { +            *reg = (TD0_color_arg2_prevstage | +                    TD0_color_alpha_currtex | +                    TD0_color_alpha2inv_enable | +                    TD0_color_arg2mul_alpha2 | +                    TD0_color_arg1mul_alpha1 | +                    TD0_color_add_add | +                    TD0_color_sel_add | +                    TD0_alpha_arg2_prevstage | +                    TD0_alpha_sel_arg2 ); +         } +#else +         /* s/w fallback, pretty sure we can't do in h/w */ +	 FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE ); +	 if ( MGA_DEBUG & DEBUG_VERBOSE_FALLBACK ) +	    fprintf( stderr, "FALLBACK: GL_DECAL RGBA texture, unit=%d\n", +		     unit ); +#endif +      } +      else { +	 if (unit == 0) { +	    *reg = ( TD0_color_arg2_diffuse | +		     TD0_color_sel_arg2 | +		     TD0_alpha_arg2_diffuse | +		     TD0_alpha_sel_arg2); +	 } +	 else { +	    *reg = ( TD0_color_arg2_prevstage | +		     TD0_color_sel_arg2 | +		     TD0_alpha_arg2_prevstage | +		     TD0_alpha_sel_arg2); +	 } +      } +      break; + +   case GL_ADD: +      if (unit == 0) { +         if (format == GL_INTENSITY) +            *reg = ( TD0_color_arg2_diffuse | +                     TD0_color_add_add | +                     TD0_color_sel_add | +                     TD0_alpha_arg2_diffuse | +                     TD0_alpha_add_enable | +                     TD0_alpha_sel_add); +         else if (format == GL_ALPHA) +            *reg = ( TD0_color_arg2_diffuse | +                     TD0_color_sel_mul | +                     TD0_alpha_arg2_diffuse | +                     TD0_alpha_sel_mul); +         else +            *reg = ( TD0_color_arg2_diffuse | +                     TD0_color_add_add | +                     TD0_color_sel_add | +                     TD0_alpha_arg2_diffuse | +                     TD0_alpha_sel_mul); +      } +      else { +         if (format == GL_INTENSITY) { +            *reg = ( TD0_color_arg2_prevstage | +                     TD0_color_add_add | +                     TD0_color_sel_add | +                     TD0_alpha_arg2_prevstage | +                     TD0_alpha_add_enable | +                     TD0_alpha_sel_add); +         } +         else if (format == GL_ALPHA) { +            *reg = ( TD0_color_arg2_prevstage | +                     TD0_color_sel_mul | +                     TD0_alpha_arg2_prevstage | +                     TD0_alpha_sel_mul); +         } +         else { +            *reg = ( TD0_color_arg2_prevstage | +                     TD0_color_alpha_prevstage | +                     TD0_color_add_add | +                     TD0_color_sel_add | +                     TD0_alpha_arg2_prevstage | +                     TD0_alpha_sel_mul); +         } +      } +      break; + +   case GL_BLEND: +      if (format == GL_ALPHA) { +	 *reg = ( TD0_color_arg2_diffuse | +		  TD0_color_sel_mul | +		  TD0_alpha_arg2_diffuse | +		  TD0_alpha_sel_mul); +      } +      else { +	 FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE ); +	 if ( MGA_DEBUG & DEBUG_VERBOSE_FALLBACK ) +	    fprintf( stderr, "FALLBACK: GL_BLEND envcolor=0x%08x\n", +		     mmesa->envcolor ); + +         /* Do singletexture GL_BLEND with 'all ones' env-color +          * by using both texture units.  Multitexture gl_blend +          * is a fallback. +          */ +         if (unit == 0) { +            /* Part 1: R1 = Rf ( 1 - Rt ) +             *         A1 = Af At +             */ +            *reg = ( TD0_color_arg2_diffuse | +                     TD0_color_arg1_inv_enable | +                     TD0_color_sel_mul | +                     TD0_alpha_arg2_diffuse | +                     TD0_alpha_sel_arg1); +         } else { +            /* Part 2: R2 = R1 + Rt +             *         A2 = A1 +             */ +            *reg = ( TD0_color_arg2_prevstage | +                     TD0_color_add_add | +                     TD0_color_sel_add | +                     TD0_alpha_arg2_prevstage | +                     TD0_alpha_sel_arg2); +         } +      } +      break; +   default: +      break; +   } +} + + + +static void mgaUpdateTextureObject( GLcontext *ctx, int hw_unit ) +{ +   mgaTextureObjectPtr t; +   struct gl_texture_object	*tObj; +   GLuint enabled; +   mgaContextPtr mmesa = MGA_CONTEXT( ctx ); +   GLuint gl_unit = mmesa->tmu_source[hw_unit]; + + +   enabled = ctx->Texture.Unit[gl_unit]._ReallyEnabled; +   tObj = ctx->Texture.Unit[gl_unit]._Current; + +   if (enabled != TEXTURE_2D_BIT) { +      if (enabled) +	 FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE ); +      return; +   } + +   if (tObj->Image[tObj->BaseLevel]->Border > 0) { +      FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE ); +      if ( MGA_DEBUG & DEBUG_VERBOSE_FALLBACK ) +	 fprintf( stderr, "FALLBACK: texture border\n" ); +      return; +   } + +   if ( !tObj->DriverData ) { +      mgaCreateTexObj( mmesa, tObj ); +      if ( !tObj->DriverData ) { +	 FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE ); +	 return;		 +      } +   } + +   t = (mgaTextureObjectPtr)tObj->DriverData; + +   if (t->dirty_images) +      mmesa->dirty |= (MGA_UPLOAD_TEX0IMAGE << hw_unit); + +   mmesa->CurrentTexObj[hw_unit] = t; +   t->bound |= hw_unit+1; + +/*     if (t->MemBlock) */ +/*        mgaUpdateTexLRU( mmesa, t ); */ + +   t->setup.texctl2 &= ~TMC_dualtex_enable; +   if ((ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT) && +       (ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT))  +      t->setup.texctl2 |= TMC_dualtex_enable; + +   t->setup.texctl2 &= ~TMC_specen_enable; +   if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) +      t->setup.texctl2 |= TMC_specen_enable; +} + + + + + + +/* The G400 is now programmed quite differently wrt texture environment. + */ +void mgaUpdateTextureState( GLcontext *ctx ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT( ctx ); +   FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_FALSE ); + +   if (mmesa->CurrentTexObj[0]) { +      mmesa->CurrentTexObj[0]->bound = 0; +      mmesa->CurrentTexObj[0] = 0; +   } + +   if (mmesa->CurrentTexObj[1]) { +      mmesa->CurrentTexObj[1]->bound = 0; +      mmesa->CurrentTexObj[1] = 0; +   } + +   if (ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT) { +      mmesa->tmu_source[0] = 1; +   } else { +      mmesa->tmu_source[0] = 0; +   } + +   if (MGA_IS_G400(mmesa)) { +      mgaUpdateTextureObject( ctx, 0 ); +      mgaUpdateTextureEnvG400( ctx, 0 ); + +      mmesa->setup.tdualstage1 = mmesa->setup.tdualstage0; +       +      if ((ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT) && +          (ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT)) { +	 mgaUpdateTextureObject( ctx, 1 );	 +	 mgaUpdateTextureEnvG400( ctx, 1 ); +	 mmesa->dirty |= MGA_UPLOAD_TEX1; +      } +   } else { +      mgaUpdateTextureObject( ctx, 0 ); +      mgaUpdateTextureEnvG200( ctx ); +   } + +   mmesa->dirty |= MGA_UPLOAD_CONTEXT | MGA_UPLOAD_TEX0; + +   mmesa->setup.dwgctl &= DC_opcod_MASK; +   mmesa->setup.dwgctl |= (ctx->Texture.Unit[0]._ReallyEnabled +			   ? DC_opcod_texture_trap +			   : DC_opcod_trap); +} + + + + +static void mgaDDTexEnv( GLcontext *ctx, GLenum target, +			 GLenum pname, const GLfloat *param ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); + + +   if (pname == GL_TEXTURE_ENV_MODE) { +      /* force the texture state to be updated */ +      FLUSH_BATCH( MGA_CONTEXT(ctx) ); +      MGA_CONTEXT(ctx)->new_state |= (MGA_NEW_TEXTURE | +				      MGA_NEW_ALPHA); +   } +   else if (pname == GL_TEXTURE_ENV_COLOR) +   { +      struct gl_texture_unit *texUnit = +	 &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; +      GLfloat *fc = texUnit->EnvColor; +      GLubyte c[4]; +      GLuint col; + +      COPY_4V(c, fc); +      col = mgaPackColor( mmesa->mgaScreen->cpp, c[0], c[1], c[2], c[3] ); +      mmesa->envcolor = (c[3]<<24) | (c[0]<<16) | (c[1]<<8) | (c[2]); + +      if (mmesa->setup.fcol != col) { +	 FLUSH_BATCH(mmesa); +	 mmesa->setup.fcol = col; +	 mmesa->dirty |= MGA_UPLOAD_CONTEXT; + +	 mmesa->blend_flags &= ~MGA_BLEND_ENV_COLOR; + +	 /* Actually just require all four components to be +	  * equal.  This permits a single-pass GL_BLEND. +	  * +	  * More complex multitexture/multipass fallbacks +	  * for blend can be done later. +	  */ +	 if (mmesa->envcolor != 0x0 && mmesa->envcolor != 0xffffffff) +	    mmesa->blend_flags |= MGA_BLEND_ENV_COLOR; +      } +   } +} + + +static void mgaTexImage2D( 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 ) +{ +   mgaTextureObjectPtr t = (mgaTextureObjectPtr) texObj->DriverData; +   if (t) { +      mgaDestroyTexObj( MGA_CONTEXT(ctx), t ); +      texObj->DriverData = 0; +   } +   _mesa_store_teximage2d( ctx, target, level, internalFormat, +			   width, height, border, format, type, +			   pixels, packing, texObj, texImage ); +} + +static void mgaTexSubImage2D( 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 ) +{ +   mgaTextureObjectPtr t = (mgaTextureObjectPtr) texObj->DriverData; +   if (t) { +      mgaDestroyTexObj( MGA_CONTEXT(ctx), t ); +      texObj->DriverData = 0; +   } +   _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width,  +			     height, format, type, pixels, packing, texObj, +			     texImage); + +} + + + + +/* + * mgaTexParameter + * This just changes variables and flags for a state update, which + * will happen at the next mgaUpdateTextureState + */ +static void +mgaDDTexParameter( GLcontext *ctx, GLenum target, +		   struct gl_texture_object *tObj, +		   GLenum pname, const GLfloat *params ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT( ctx ); +   mgaTextureObjectPtr t; + +   t = (mgaTextureObjectPtr) tObj->DriverData; + +   /* if we don't have a hardware texture, it will be automatically +      created with current state before it is used, so we don't have +      to do anything now */ +   if ( !t || !t->bound || target != GL_TEXTURE_2D ) { +      return; +   } + +   switch (pname) { +   case GL_TEXTURE_MIN_FILTER: +   case GL_TEXTURE_MAG_FILTER: +      FLUSH_BATCH(mmesa); +      mgaSetTexFilter( t, tObj->MinFilter, tObj->MagFilter ); +      break; + +   case GL_TEXTURE_WRAP_S: +   case GL_TEXTURE_WRAP_T: +      FLUSH_BATCH(mmesa); +      mgaSetTexWrapping(t,tObj->WrapS,tObj->WrapT); +      break; + +   case GL_TEXTURE_BORDER_COLOR: +      FLUSH_BATCH(mmesa); +      mgaSetTexBorderColor(t,tObj->_BorderChan); +      break; + +   default: +      return; +   } + +   mmesa->new_state |= MGA_NEW_TEXTURE; +} + + +static void +mgaDDBindTexture( GLcontext *ctx, GLenum target, +		  struct gl_texture_object *tObj ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT( ctx ); +   int unit = ctx->Texture.CurrentUnit; + +   FLUSH_BATCH(mmesa); + +   if (mmesa->CurrentTexObj[unit]) { +      mmesa->CurrentTexObj[unit]->bound &= ~(unit+1); +      mmesa->CurrentTexObj[unit] = 0; +   } + +   /* force the texture state to be updated +    */ +   MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE; +} + + +static void +mgaDDDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT( ctx ); +   mgaTextureObjectPtr t = (mgaTextureObjectPtr)tObj->DriverData; + +   if ( t ) { +      if (mmesa) { +         if (t->bound) { +            FLUSH_BATCH(mmesa); +            if (t->bound & TEX_0) mmesa->CurrentTexObj[0] = 0; +            if (t->bound & TEX_1) mmesa->CurrentTexObj[1] = 0; +         } +         mmesa->new_state |= MGA_NEW_TEXTURE; +      } + +      mgaDestroyTexObj( mmesa, t ); +   } +} + + +static GLboolean +mgaDDIsTextureResident( GLcontext *ctx, struct gl_texture_object *t ) +{ +   mgaTextureObjectPtr mt = (mgaTextureObjectPtr)t->DriverData; +   return mt && mt->MemBlock; +} + + +void +mgaDDInitTextureFuncs( GLcontext *ctx ) +{ +   ctx->Driver.TexEnv = mgaDDTexEnv; + +   ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format; +   ctx->Driver.TexImage1D = _mesa_store_teximage1d; +   ctx->Driver.TexImage2D = mgaTexImage2D; +   ctx->Driver.TexImage3D = _mesa_store_teximage3d; +   ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d; +   ctx->Driver.TexSubImage2D = mgaTexSubImage2D; +   ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d; +   ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d; +   ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d; +   ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d; +   ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d; +   ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d; +   ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage; + +   ctx->Driver.BindTexture = mgaDDBindTexture; +   ctx->Driver.DeleteTexture = mgaDDDeleteTexture; +   ctx->Driver.TexParameter = mgaDDTexParameter; +   ctx->Driver.UpdateTexturePalette = 0; +   ctx->Driver.IsTextureResident = mgaDDIsTextureResident; +} diff --git a/src/mesa/drivers/dri/mga/mgatex.h b/src/mesa/drivers/dri/mga/mgatex.h new file mode 100644 index 0000000000..c9f87d997e --- /dev/null +++ b/src/mesa/drivers/dri/mga/mgatex.h @@ -0,0 +1,62 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatex.h,v 1.7 2002/10/30 12:51:36 alanh Exp $ */ +/* + * Copyright 2000-2001 VA Linux Systems, Inc. + * 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 + * VA LINUX SYSTEMS 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> + */ + +#ifndef MGATEX_INC +#define MGATEX_INC + +#include "mgacontext.h" + +typedef struct mga_texture_object_s *mgaTextureObjectPtr; + + +/* Called before a primitive is rendered to make sure the texture + * state is properly setup.  Texture residence is checked later + * when we grab the lock. + */ +void mgaUpdateTextureState( GLcontext *ctx ); + +void mgaConvertTexture( GLuint *dest, int texelBytes, +			struct gl_texture_image *image, +			int x, int y, int width, int height ); + + +void mgaUploadSubImageLocked( mgaContextPtr mmesa, +			      mgaTextureObjectPtr t, +			      int level, +			      int x, int y, int width, int height ); + +int mgaUploadTexImages( mgaContextPtr mmesa, mgaTextureObjectPtr t ); + +void mgaDestroyTexObj( mgaContextPtr mmesa, mgaTextureObjectPtr t ); + +void mgaAgeTextures( mgaContextPtr mmesa, int heap ); + +void mgaDDInitTextureFuncs( GLcontext *ctx ); + + +#endif diff --git a/src/mesa/drivers/dri/mga/mgatexcnv.c b/src/mesa/drivers/dri/mga/mgatexcnv.c new file mode 100644 index 0000000000..3a05c7d3eb --- /dev/null +++ b/src/mesa/drivers/dri/mga/mgatexcnv.c @@ -0,0 +1,256 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatexcnv.c,v 1.3 2002/10/30 12:51:36 alanh Exp $ */ +/* + * Copyright 2000-2001 VA Linux Systems, Inc. + * 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 + * VA LINUX SYSTEMS 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> + */ + +#include <stdlib.h> +#include <stdio.h> + +#include <GL/gl.h> + +#include "mm.h" +#include "mgacontext.h" +#include "mgatex.h" + + +/* + * mgaConvertTexture + * Converts a mesa format texture to the appropriate hardware format + * Note that sometimes width may be larger than the texture, like 64x1 + * for an 8x8 texture.  This happens when we have to crutch the pitch + * limits of the mga by uploading a block of texels as a single line. + */ +void mgaConvertTexture( GLuint *destPtr, int texelBytes, +			struct gl_texture_image *image, +			int x, int y, int width, int height ) +{ +   register int		i, j; +   GLubyte		*src; +   int stride; + +   if (0) +      fprintf(stderr, "texture image %p\n", image->Data); + +   if (image->Data == 0) +      return; + +   /* FIXME: g400 luminance_alpha internal format */ +   switch (texelBytes) { +   case 1: +      switch (image->Format) { +      case GL_COLOR_INDEX: +      case GL_INTENSITY: +      case GL_LUMINANCE: +      case GL_ALPHA: +	 src = (GLubyte *)image->Data + ( y * image->Width + x ); +	 stride = (image->Width - width); +	 for ( i = height ; i ; i-- ) { +	    for ( j = width >> 2  ; j ; j-- ) { + +	       *destPtr++ = src[0] | ( src[1] << 8 ) | ( src[2] << 16 ) | ( src[3] << 24 ); +	       src += 4; +	    } +	    src += stride; +	 } +	 break; +      default: +	 goto format_error; +      } +      break; +   case 2: +      switch (image->Format) { +      case GL_RGB: +	 src = (GLubyte *)image->Data + ( y * image->Width + x ) * 3; +	 stride = (image->Width - width) * 3; +	 for ( i = height ; i ; i-- ) { +	    for ( j = width >> 1  ; j ; j-- ) { + +	       *destPtr++ = MGAPACKCOLOR565(src[0],src[1],src[2]) | +		  ( MGAPACKCOLOR565(src[3],src[4],src[5]) << 16 ); +	       src += 6; +	    } +	    src += stride; +	 } +	 break; +      case GL_RGBA: +	 src = (GLubyte *)image->Data + ( y * image->Width + x ) * 4; +	 stride = (image->Width - width) * 4; +	 for ( i = height ; i ; i-- ) { +	    for ( j = width >> 1  ; j ; j-- ) { + +	       *destPtr++ = MGAPACKCOLOR4444(src[0],src[1],src[2],src[3]) | +		  ( MGAPACKCOLOR4444(src[4],src[5],src[6],src[7]) << 16 ); +	       src += 8; +	    } +	    src += stride; +	 } +	 break; +      case GL_LUMINANCE: +	 src = (GLubyte *)image->Data + ( y * image->Width + x ); +	 stride = (image->Width - width); +	 for ( i = height ; i ; i-- ) { +	    for ( j = width >> 1  ; j ; j-- ) { +	       /* FIXME: should probably use 555 texture to get true grey */ +	       *destPtr++ = MGAPACKCOLOR565(src[0],src[0],src[0]) | +		  ( MGAPACKCOLOR565(src[1],src[1],src[1]) << 16 ); +	       src += 2; +	    } +	    src += stride; +	 } +	 break; +      case GL_INTENSITY: +	 src = (GLubyte *)image->Data + ( y * image->Width + x ); +	 stride = (image->Width - width); +	 for ( i = height ; i ; i-- ) { +	    for ( j = width >> 1  ; j ; j-- ) { + +	       *destPtr++ = MGAPACKCOLOR4444(src[0],src[0],src[0],src[0]) | +		  ( MGAPACKCOLOR4444(src[1],src[1],src[1],src[1]) << 16 ); +	       src += 2; +	    } +	    src += stride; +	 } +	 break; +      case GL_ALPHA: +	 src = (GLubyte *)image->Data + ( y * image->Width + x ); +	 stride = (image->Width - width); +	 for ( i = height ; i ; i-- ) { +	    for ( j = width >> 1  ; j ; j-- ) { + +	       *destPtr++ = MGAPACKCOLOR4444(255,255,255,src[0]) | +		  ( MGAPACKCOLOR4444(255,255,255,src[1]) << 16 ); +	       src += 2; +	    } +	    src += stride; +	 } +	 break; +      case GL_LUMINANCE_ALPHA: +	 src = (GLubyte *)image->Data + ( y * image->Width + x ) * 2; +	 stride = (image->Width - width) * 2; +	 for ( i = height ; i ; i-- ) { +	    for ( j = width >> 1  ; j ; j-- ) { + +	       *destPtr++ = MGAPACKCOLOR4444(src[0],src[0],src[0],src[1]) | +		  ( MGAPACKCOLOR4444(src[2],src[2],src[2],src[3]) << 16 ); +	       src += 4; +	    } +	    src += stride; +	 } +	 break; +      default: +	 goto format_error; +      } +      break; +   case 4: +      switch (image->Format) { +      case GL_RGB: +	 src = (GLubyte *)image->Data + (  y * image->Width + x ) * 3; +	 stride = (image->Width - width) * 3; +	 for ( i = height ; i ; i-- ) { +	    for ( j = width ; j ; j-- ) { + +	       *destPtr++ = MGAPACKCOLOR8888(src[0],src[1],src[2], 255); +	       src += 3; +	    } +	    src += stride; +	 } +	 break; +      case GL_RGBA: +	 src = (GLubyte *)image->Data + (  y * image->Width + x ) * 4; +	 stride = (image->Width - width) * 4; +	 for ( i = height ; i ; i-- ) { +	    for ( j = width  ; j ; j-- ) { + +	       *destPtr++ = MGAPACKCOLOR8888(src[0],src[1],src[2],src[3]); +	       src += 4; +	    } +	    src += stride; +	 } +	 break; +      case GL_LUMINANCE: +	 src = (GLubyte *)image->Data + ( y * image->Width + x ); +	 stride = (image->Width - width); +	 for ( i = height ; i ; i-- ) { +	    for ( j = width ; j ; j-- ) { + +	       *destPtr++ = MGAPACKCOLOR8888(src[0],src[0],src[0], 255); +	       src += 1; +	    } +	    src += stride; +	 } +	 break; +      case GL_INTENSITY: +	 src = (GLubyte *)image->Data + (  y * image->Width + x ); +	 stride = (image->Width - width); +	 for ( i = height ; i ; i-- ) { +	    for ( j = width ; j ; j-- ) { + +	       *destPtr++ = MGAPACKCOLOR8888(src[0],src[0],src[0],src[0]); +	       src += 1; +	    } +	    src += stride; +	 } +	 break; +      case GL_ALPHA: +	 src = (GLubyte *)image->Data + ( y * image->Width + x ); +	 stride = (image->Width - width); +	 for ( i = height ; i ; i-- ) { +	    for ( j = width ; j ; j-- ) { + +	       *destPtr++ = MGAPACKCOLOR8888(255,255,255,src[0]); +	       src += 1; +	    } +	    src += stride; +	 } +	 break; +      case GL_LUMINANCE_ALPHA: +	 src = (GLubyte *)image->Data + ( y * image->Width + x ) * 2; +	 stride = (image->Width - width) * 2; +	 for ( i = height ; i ; i-- ) { +	    for ( j = width ; j ; j-- ) { + +	       *destPtr++ = MGAPACKCOLOR8888(src[0],src[0], +					     src[0],src[1]); +	       src += 2; +	    } +	    src += stride; +	 } +	 break; +      default: +	 goto format_error; +      } +      break; +   default: +      goto format_error; +   } + +   return; + + format_error: + +   fprintf(stderr, "Unsupported texelBytes %i, image->Format %i\n", +	   (int)texelBytes, (int)image->Format ); +} diff --git a/src/mesa/drivers/dri/mga/mgatexmem.c b/src/mesa/drivers/dri/mga/mgatexmem.c new file mode 100644 index 0000000000..7dbdbc582f --- /dev/null +++ b/src/mesa/drivers/dri/mga/mgatexmem.c @@ -0,0 +1,564 @@ +/* + * Copyright 2000-2001 VA Linux Systems, Inc. + * 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 + * VA LINUX SYSTEMS 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> + */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatexmem.c,v 1.7 2002/10/30 12:51:36 alanh Exp $ */ + +#include <stdlib.h> +#include <stdio.h> +#include <GL/gl.h> + +#include "mm.h" +#include "mgacontext.h" +#include "mgatex.h" +#include "mgaregs.h" +#include "mgaioctl.h" + +/*#include "mem.h" */ +#include "simple_list.h" + +static void +mgaSwapOutTexObj(mgaContextPtr mmesa, mgaTextureObjectPtr t) +{ +   if (t->MemBlock) { +      mmFreeMem(t->MemBlock); +      t->MemBlock = 0; + +      if (t->age > mmesa->dirtyAge) +	 mmesa->dirtyAge = t->age; +   } + +   t->dirty_images = ~0; +   move_to_tail(&(mmesa->SwappedOut), t); +} + +static void +mgaPrintLocalLRU( mgaContextPtr mmesa, int heap ) +{ +   mgaTextureObjectPtr t; +   int sz = 1 << (mmesa->mgaScreen->logTextureGranularity[heap]); + +   fprintf(stderr, "\nLocal LRU, heap %d:\n", heap); + +   foreach( t, &(mmesa->TexObjList[heap]) ) { +      if (!t->tObj) +	 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); +   } + +   fprintf(stderr, "\n\n"); +} + +static void +mgaPrintGlobalLRU( mgaContextPtr mmesa, int heap ) +{ +   int i, j; +   drmTextureRegion *list = mmesa->sarea->texList[heap]; + +   fprintf(stderr, "\nGlobal LRU, heap %d list %p:\n", heap, list); + +   for (i = 0, j = MGA_NR_TEX_REGIONS ; i < MGA_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 == MGA_NR_TEX_REGIONS) break; +   } + +   if (j != MGA_NR_TEX_REGIONS) { +      fprintf(stderr, "Loop detected in global LRU\n\n\n"); +      for (i = 0 ; i < MGA_NR_TEX_REGIONS ; i++) { +	 fprintf(stderr, "list[%d] age %d next %d prev %d\n", +		 i, list[i].age, list[i].next, list[i].prev); +      } +   } + +   fprintf(stderr, "\n\n"); +} + + +static void mgaResetGlobalLRU( mgaContextPtr mmesa, GLuint heap ) +{ +   drmTextureRegion *list = mmesa->sarea->texList[heap]; +   int sz = 1 << mmesa->mgaScreen->logTextureGranularity[heap]; +   int i; + +   mmesa->texAge[heap] = ++mmesa->sarea->texAge[heap]; + +   if (0) fprintf(stderr, "mgaResetGlobalLRU %d\n", (int)heap); + +   /* (Re)initialize the global circular LRU list.  The last element +    * in the array (MGA_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 <= mmesa->mgaScreen->textureSize[heap] ; i++) { +      list[i].prev = i-1; +      list[i].next = i+1; +      list[i].age = mmesa->sarea->texAge[heap]; +   } + +   i--; +   list[0].prev = MGA_NR_TEX_REGIONS; +   list[i].prev = i-1; +   list[i].next = MGA_NR_TEX_REGIONS; +   list[MGA_NR_TEX_REGIONS].prev = i; +   list[MGA_NR_TEX_REGIONS].next = 0; + +} + + +static void mgaUpdateTexLRU( mgaContextPtr mmesa, mgaTextureObjectPtr t ) +{ +   int i; +   int heap = t->heap; +   int logsz = mmesa->mgaScreen->logTextureGranularity[heap]; +   int start = t->MemBlock->ofs >> logsz; +   int end = (t->MemBlock->ofs + t->MemBlock->size - 1) >> logsz; +   drmTextureRegion *list = mmesa->sarea->texList[heap]; + +   mmesa->texAge[heap] = ++mmesa->sarea->texAge[heap]; + +   if (!t->MemBlock) { +      fprintf(stderr, "no memblock\n\n"); +      return; +   } + +   /* Update our local LRU +    */ +   move_to_head( &(mmesa->TexObjList[heap]), t ); + + +   if (0) +      fprintf(stderr, "mgaUpdateTexLRU heap %d list %p\n", heap, list); + + +   /* Update the global LRU +    */ +   for (i = start ; i <= end ; i++) { + +      list[i].in_use = 1; +      list[i].age = mmesa->texAge[heap]; + +      /* 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 = MGA_NR_TEX_REGIONS; +      list[i].next = list[MGA_NR_TEX_REGIONS].next; +      list[(unsigned)list[MGA_NR_TEX_REGIONS].next].prev = i; +      list[MGA_NR_TEX_REGIONS].next = i; +   } + +   if (0) { +      mgaPrintGlobalLRU(mmesa, t->heap); +      mgaPrintLocalLRU(mmesa, t->heap); +   } +} + +/* 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. + */ +static void mgaTexturesGone( mgaContextPtr mmesa, +			     GLuint heap, +			     GLuint offset, +			     GLuint size, +			     GLuint in_use ) +{ +   mgaTextureObjectPtr t, tmp; + + + +   foreach_s ( t, tmp, &(mmesa->TexObjList[heap]) ) { + +      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) +	 mgaSwapOutTexObj( mmesa, t ); +      else +	 mgaDestroyTexObj( mmesa, t ); +   } + + +   if (in_use) { +      t = (mgaTextureObjectPtr) calloc(1, sizeof(*t)); +      if (!t) return; + +      t->heap = heap; +      t->MemBlock = mmAllocMem( mmesa->texHeap[heap], size, 0, offset); +      if (!t->MemBlock) { +	 fprintf(stderr, "Couldn't alloc placeholder sz %x ofs %x\n", +		 (int)size, (int)offset); +	 mmDumpMemInfo( mmesa->texHeap[heap]); +	 return; +      } +      insert_at_head( &(mmesa->TexObjList[heap]), t ); +   } +} + + +void mgaAgeTextures( mgaContextPtr mmesa, int heap ) +{ +   MGASAREAPrivPtr sarea = mmesa->sarea; +   int sz = 1 << (mmesa->mgaScreen->logTextureGranularity[heap]); +   int idx, nr = 0; + +   /* Have to go right round from the back to ensure stuff ends up +    * LRU in our local list...  Fix with a cursor pointer. +    */ +   for (idx = sarea->texList[heap][MGA_NR_TEX_REGIONS].prev ; +	idx != MGA_NR_TEX_REGIONS && nr < MGA_NR_TEX_REGIONS ; +	idx = sarea->texList[heap][idx].prev, nr++) +   { +      /* If switching texturing schemes, then the SAREA might not +       * have been properly cleared, so we need to reset the +       * global texture LRU. +       */ +      if ( idx * sz > mmesa->mgaScreen->textureSize[heap] ) { +         nr = MGA_NR_TEX_REGIONS; +         break; +      } + +      if (sarea->texList[heap][idx].age > mmesa->texAge[heap]) { +        mgaTexturesGone(mmesa, heap, idx * sz, sz, +                        sarea->texList[heap][idx].in_use); +      } +   } + +   if (nr == MGA_NR_TEX_REGIONS) { +      mgaTexturesGone(mmesa, heap, 0, +		      mmesa->mgaScreen->textureSize[heap], 0); +      mgaResetGlobalLRU( mmesa, heap ); +   } + + +   if (0) { +      mgaPrintGlobalLRU( mmesa, heap ); +      mgaPrintLocalLRU( mmesa, heap ); +   } + +   mmesa->texAge[heap] = sarea->texAge[heap]; +   mmesa->dirty |= MGA_UPLOAD_TEX0IMAGE | MGA_UPLOAD_TEX1IMAGE; +} + +/* + * mgaUploadSubImageLocked + * + * Perform an iload based update of a resident buffer.  This is used for + * both initial loading of the entire image, and texSubImage updates. + * + * Performed with the hardware lock held. + */ +void mgaUploadSubImageLocked( mgaContextPtr mmesa, +			      mgaTextureObjectPtr t, +			      int level, +			      int x, int y, int width, int height ) +{ +   int		x2; +   int		dwords; +   int		offset; +   struct gl_texture_image *image; +   int		texelBytes, texelsPerDword, texelMaccess, length; + +   if ( level < 0 || level >= MGA_TEX_MAXLEVELS ) +      return; + +   image = t->tObj->Image[level]; +   if ( !image ) return; + + +   if (image->Data == 0) { +      fprintf(stderr, "null texture image data tObj %p level %d\n", +	      t->tObj, level); +      return; +   } + + +   /* find the proper destination offset for this level */ +   offset = (t->MemBlock->ofs + +	     t->offsets[level]); + + +   texelBytes = t->texelBytes; +   switch( texelBytes ) { +   case 1: +      texelsPerDword = 4; +      texelMaccess = 0; +      break; +   case 2: +      texelsPerDword = 2; +      texelMaccess = 1; +      break; +   case 4: +      texelsPerDword = 1; +      texelMaccess = 2; +      break; +   default: +      return; +   } + + +   /* We can't do a subimage update if pitch is < 32 texels due +    * to hardware XY addressing limits, so we will need to +    * linearly upload all modified rows. +    */ +   if ( image->Width < 32 ) { +      x = 0; +      width = image->Width * height; +      height = 1; + +      /* Assume that 1x1 textures aren't going to cause a +       * bus error if we read up to four texels from that +       * location: +       */ +/*        if ( width < texelsPerDword ) { */ +/*  	 width = texelsPerDword; */ +/*        } */ +   } else { +      /* pad the size out to dwords.  The image is a pointer +	 to the entire image, so we can safely reference +	 outside the x,y,width,height bounds if we need to */ +      x2 = x + width; +      x2 = (x2 + (texelsPerDword-1)) & ~(texelsPerDword-1); +      x = (x + (texelsPerDword-1)) & ~(texelsPerDword-1); +      width = x2 - x; +   } + +   /* we may not be able to upload the entire texture in one +      batch due to register limits or dma buffer limits. +      Recursively split it up. */ +   while ( 1 ) { +      dwords = height * width / texelsPerDword; +      if ( dwords * 4 <= MGA_BUFFER_SIZE ) { +	 break; +      } + +      mgaUploadSubImageLocked( mmesa, t, level, x, y, +			       width, height >> 1 ); +      y += ( height >> 1 ); +      height -= ( height >> 1 ); +   } + +   length = dwords * 4; + +   /* Fill in the secondary buffer with properly converted texels +    * from the mesa buffer. */ +   /* FIXME: the sync for direct copy reduces speed.. */ +   if(t->heap == MGA_CARD_HEAP  ) { +      mgaGetILoadBufferLocked( mmesa ); +      mgaConvertTexture( (GLuint *)mmesa->iload_buffer->address, +			 texelBytes, image, x, y, width, height ); +      if(length < 64) length = 64; + +      if (0) +	 fprintf(stderr, "TexelBytes : %d, offset: %d, length : %d\n", +		 texelBytes, +		 mmesa->mgaScreen->textureOffset[t->heap] + +		 offset + +		 y * width * 4/texelsPerDword, +		 length); + +      mgaFireILoadLocked( mmesa, +			  mmesa->mgaScreen->textureOffset[t->heap] + +			  offset + +			  y * width * 4/texelsPerDword, +			  length); +   } else { +      /* This works, is slower for uploads to card space and needs +       * additional synchronization with the dma stream. +       */ +        +      UPDATE_LOCK(mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT); +      mgaConvertTexture( (GLuint *) +			 (mmesa->mgaScreen->texVirtual[t->heap] + +			  offset + +			  y * width * 4/texelsPerDword), +			 texelBytes, image, x, y, width, height ); +   } +} + + +static void mgaUploadTexLevel( mgaContextPtr mmesa, +			       mgaTextureObjectPtr t, +			       int l ) +{ +   mgaUploadSubImageLocked( mmesa, +			    t, +			    l, +			    0, 0, +			    t->tObj->Image[l]->Width, +			    t->tObj->Image[l]->Height); +} + + + + +#if 0 +static void mgaMigrateTexture( mgaContextPtr mmesa, mgaTextureObjectPtr t ) +{ +	/* NOT DONE */ +} +#endif + + +static int mgaChooseTexHeap( mgaContextPtr mmesa, mgaTextureObjectPtr t ) +{ +   int freeagp, freecard; +   int fitincard, fitinagp; +   int totalcard, totalagp; +   TMemBlock *b; + +   totalcard = totalagp = fitincard = fitinagp = freeagp = freecard = 0; + +   b = mmesa->texHeap[0]; +   while(b) +   { +     totalcard += b->size; +     if(b->free) if(t->totalSize <= b->size)fitincard = 1; +     b = b->next; +   } + +   b = mmesa->texHeap[1]; +   while(b) +   { +     totalagp += b->size; +     if(b->free)  if(t->totalSize <= b->size)fitinagp = 1; +     b = b->next; +   } + +   if(fitincard)return 0; +   if(fitinagp)return 1; + +   if(totalcard && totalagp) +   { +     int ages; +     int ratio = (totalcard > totalagp) ? totalcard / totalagp : totalagp / totalcard; +     ages = mmesa->sarea->texAge[0] + mmesa->sarea->texAge[1]; +     if( (ages % ratio) == 0)return totalcard > totalagp ? 1 : 0; +     else return totalcard > totalagp ? 0 : 1; +   } + +   if(totalagp) return 1; +   return 0; +} + + +int mgaUploadTexImages( mgaContextPtr mmesa, mgaTextureObjectPtr t ) +{ +   int heap; +   int i; +   int ofs; + +   heap = t->heap = mgaChooseTexHeap( mmesa, t ); + +   /* Do we need to eject LRU texture objects? +    */ +   if (!t->MemBlock) { +      while (1) +      { +	 mgaTextureObjectPtr tmp = mmesa->TexObjList[heap].prev; + +	 t->MemBlock = mmAllocMem( mmesa->texHeap[heap], +				   t->totalSize, +				   6, 0 ); +	 if (t->MemBlock) +	    break; + +	 if (mmesa->TexObjList[heap].prev->bound) { +	    fprintf(stderr, "Hit bound texture in upload\n"); +	    return -1; +	 } + +	 if (mmesa->TexObjList[heap].prev == +	     &(mmesa->TexObjList[heap])) +	 { +	    fprintf(stderr, "Failed to upload texture, sz %d\n", t->totalSize); +	    mmDumpMemInfo( mmesa->texHeap[heap] ); +	    return -1; +	 } + +	 mgaDestroyTexObj( mmesa, tmp ); +      } + +      ofs = t->MemBlock->ofs +	 + mmesa->mgaScreen->textureOffset[heap] +	 ; + +      t->setup.texorg  = ofs; +      t->setup.texorg1 = ofs + t->offsets[1]; +      t->setup.texorg2 = ofs + t->offsets[2]; +      t->setup.texorg3 = ofs + t->offsets[3]; +      t->setup.texorg4 = ofs + t->offsets[4]; + +      mmesa->dirty |= MGA_UPLOAD_CONTEXT; +   } + +   /* Let the world know we've used this memory recently. +    */ +   mgaUpdateTexLRU( mmesa, t ); + + +   if (MGA_DEBUG&DEBUG_VERBOSE_LRU) +      fprintf(stderr, "dispatch age: %d age freed memory: %d\n", +	      GET_DISPATCH_AGE(mmesa), mmesa->dirtyAge); + +   if (mmesa->dirtyAge >= GET_DISPATCH_AGE(mmesa)) +      mgaWaitAgeLocked( mmesa, mmesa->dirtyAge ); + +   if (t->dirty_images) { +      if (MGA_DEBUG&DEBUG_VERBOSE_LRU) +	 fprintf(stderr, "*"); + +      for (i = 0 ; i <= t->lastLevel ; i++) +	 if (t->dirty_images & (1<<i)) +	    mgaUploadTexLevel( mmesa, t, i ); +   } + + +   t->dirty_images = 0; +   return 0; +} diff --git a/src/mesa/drivers/dri/mga/mgatris.c b/src/mesa/drivers/dri/mga/mgatris.c new file mode 100644 index 0000000000..e47cfc171f --- /dev/null +++ b/src/mesa/drivers/dri/mga/mgatris.c @@ -0,0 +1,915 @@ +/* + * Copyright 2000-2001 VA Linux Systems, Inc. + * 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 + * VA LINUX SYSTEMS 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> + */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatris.c,v 1.10 2002/10/30 12:51:36 alanh Exp $ */ + +#include <stdio.h> +#include <math.h> + +#include "mtypes.h" +#include "macros.h" +#include "colormac.h" +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" + +#include "mm.h" +#include "mgacontext.h" +#include "mgaioctl.h" +#include "mgatris.h" +#include "mgavb.h" +#include "mgastate.h" + + +static void mgaRenderPrimitive( GLcontext *ctx, GLenum prim ); + +/*********************************************************************** + *                 Functions to draw basic primitives                  * + ***********************************************************************/ + + +#if defined (USE_X86_ASM) +#define EMIT_VERT( j, vb, vertex_size, v )		\ +do {	int __tmp;					\ +	__asm__ __volatile__( "rep ; movsl"		\ +			 : "=%c" (j), "=D" (vb), "=S" (__tmp)		\ +			 : "0" (vertex_size), 		\ +			   "D" ((long)vb), 		\ +			   "S" ((long)v));		\ +} while (0) +#else +#define EMIT_VERT( j, vb, vertex_size, v )	\ +do {						\ +   for ( j = 0 ; j < vertex_size ; j++ )	\ +      vb[j] = (v)->ui[j];			\ +   vb += vertex_size;				\ +} while (0) +#endif + +static void __inline__ mga_draw_triangle( mgaContextPtr mmesa, +					   mgaVertexPtr v0, +					   mgaVertexPtr v1, +					   mgaVertexPtr v2 ) +{ +   GLuint vertex_size = mmesa->vertex_size; +   GLuint *vb = mgaAllocDmaLow( mmesa, 3 * 4 * vertex_size ); +   int j; + +   EMIT_VERT( j, vb, vertex_size, v0 ); +   EMIT_VERT( j, vb, vertex_size, v1 ); +   EMIT_VERT( j, vb, vertex_size, v2 ); +} + + +static void __inline__ mga_draw_quad( mgaContextPtr mmesa, +				       mgaVertexPtr v0, +				       mgaVertexPtr v1, +				       mgaVertexPtr v2, +				       mgaVertexPtr v3 ) +{ +   GLuint vertex_size = mmesa->vertex_size; +   GLuint *vb = mgaAllocDmaLow( mmesa, 6 * 4 * vertex_size ); +   int j; + +   EMIT_VERT( j, vb, vertex_size, v0 ); +   EMIT_VERT( j, vb, vertex_size, v1 ); +   EMIT_VERT( j, vb, vertex_size, v3 ); +   EMIT_VERT( j, vb, vertex_size, v1 ); +   EMIT_VERT( j, vb, vertex_size, v2 ); +   EMIT_VERT( j, vb, vertex_size, v3 ); +} + + +static __inline__ void mga_draw_point( mgaContextPtr mmesa, +					mgaVertexPtr tmp ) +{ +   GLfloat sz = mmesa->glCtx->Point._Size * .5; +   int vertex_size = mmesa->vertex_size; +   GLuint *vb = mgaAllocDmaLow( mmesa, 6 * 4 * vertex_size ); +   int j; +    +#if 0 +   v0->v.x += PNT_X_OFFSET - TRI_X_OFFSET; +   v0->v.y += PNT_Y_OFFSET - TRI_Y_OFFSET; +#endif + +   /* Draw a point as two triangles. +    */ +   *(float *)&vb[0] = tmp->v.x - sz; +   *(float *)&vb[1] = tmp->v.y - sz; +   for (j = 2 ; j < vertex_size ; j++)  +      vb[j] = tmp->ui[j]; +   vb += vertex_size; + +   *(float *)&vb[0] = tmp->v.x + sz; +   *(float *)&vb[1] = tmp->v.y - sz; +   for (j = 2 ; j < vertex_size ; j++)  +      vb[j] = tmp->ui[j]; +   vb += vertex_size; + +   *(float *)&vb[0] = tmp->v.x + sz; +   *(float *)&vb[1] = tmp->v.y + sz; +   for (j = 2 ; j < vertex_size ; j++)  +      vb[j] = tmp->ui[j]; +   vb += vertex_size; + +   *(float *)&vb[0] = tmp->v.x + sz; +   *(float *)&vb[1] = tmp->v.y + sz; +   for (j = 2 ; j < vertex_size ; j++)  +      vb[j] = tmp->ui[j]; +   vb += vertex_size; + +   *(float *)&vb[0] = tmp->v.x - sz; +   *(float *)&vb[1] = tmp->v.y + sz; +   for (j = 2 ; j < vertex_size ; j++)  +      vb[j] = tmp->ui[j]; +   vb += vertex_size; + +   *(float *)&vb[0] = tmp->v.x - sz; +   *(float *)&vb[1] = tmp->v.y - sz; +   for (j = 2 ; j < vertex_size ; j++)  +      vb[j] = tmp->ui[j]; + +#if 0 +   v0->v.x -= PNT_X_OFFSET - TRI_X_OFFSET; +   v0->v.y -= PNT_Y_OFFSET - TRI_Y_OFFSET; +#endif +} + + +static __inline__ void mga_draw_line( mgaContextPtr mmesa, +				      mgaVertexPtr v0, +				      mgaVertexPtr v1 ) +{ +   GLuint vertex_size = mmesa->vertex_size; +   GLuint *vb = mgaAllocDmaLow( mmesa, 6 * 4 * vertex_size ); +   GLfloat dx, dy, ix, iy; +   GLfloat width = mmesa->glCtx->Line._Width; +   GLint j; + +#if 0 +   v0->v.x += LINE_X_OFFSET - TRI_X_OFFSET; +   v0->v.y += LINE_Y_OFFSET - TRI_Y_OFFSET; +   v1->v.x += LINE_X_OFFSET - TRI_X_OFFSET; +   v1->v.y += LINE_Y_OFFSET - TRI_Y_OFFSET; +#endif + +   dx = v0->v.x - v1->v.x; +   dy = v0->v.y - v1->v.y; +    +   ix = width * .5; iy = 0; +   if (dx * dx > dy * dy) { +      iy = ix; ix = 0; +   } + +   *(float *)&vb[0] = v0->v.x - ix; +   *(float *)&vb[1] = v0->v.y - iy; +   for (j = 2 ; j < vertex_size ; j++)  +      vb[j] = v0->ui[j]; +   vb += vertex_size; + +   *(float *)&vb[0] = v1->v.x + ix; +   *(float *)&vb[1] = v1->v.y + iy; +   for (j = 2 ; j < vertex_size ; j++)  +      vb[j] = v1->ui[j]; +   vb += vertex_size; + +   *(float *)&vb[0] = v0->v.x + ix; +   *(float *)&vb[1] = v0->v.y + iy; +   for (j = 2 ; j < vertex_size ; j++)  +      vb[j] = v0->ui[j]; +   vb += vertex_size; +	  +   *(float *)&vb[0] = v0->v.x - ix; +   *(float *)&vb[1] = v0->v.y - iy; +   for (j = 2 ; j < vertex_size ; j++)  +      vb[j] = v0->ui[j]; +   vb += vertex_size; + +   *(float *)&vb[0] = v1->v.x - ix; +   *(float *)&vb[1] = v1->v.y - iy; +   for (j = 2 ; j < vertex_size ; j++)  +      vb[j] = v1->ui[j]; +   vb += vertex_size; + +   *(float *)&vb[0] = v1->v.x + ix; +   *(float *)&vb[1] = v1->v.y + iy; +   for (j = 2 ; j < vertex_size ; j++)  +      vb[j] = v1->ui[j]; +   vb += vertex_size; + +#if 0 +   v0->v.x -= LINE_X_OFFSET - TRI_X_OFFSET; +   v0->v.y -= LINE_Y_OFFSET - TRI_Y_OFFSET; +   v1->v.x -= LINE_X_OFFSET - TRI_X_OFFSET; +   v1->v.y -= LINE_Y_OFFSET - TRI_Y_OFFSET; +#endif +} + +/*********************************************************************** + *          Macros for t_dd_tritmp.h to draw basic primitives          * + ***********************************************************************/ + +#define TRI( a, b, c )				\ +do {						\ +   if (DO_FALLBACK)				\ +      mmesa->draw_tri( mmesa, a, b, c );	\ +   else						\ +      mga_draw_triangle( mmesa, a, b, c );	\ +} while (0) + +#define QUAD( a, b, c, d )			\ +do {						\ +   if (DO_FALLBACK) {				\ +      mmesa->draw_tri( mmesa, a, b, d );	\ +      mmesa->draw_tri( mmesa, b, c, d );	\ +   } else {					\ +      mga_draw_quad( mmesa, a, b, c, d );	\ +   }						\ +} while (0) + +#define LINE( v0, v1 )				\ +do {						\ +   if (DO_FALLBACK)				\ +      mmesa->draw_line( mmesa, v0, v1 );	\ +   else {					\ +      mga_draw_line( mmesa, v0, v1 );		\ +   }						\ +} while (0) + +#define POINT( v0 )				\ +do {						\ +   if (DO_FALLBACK)				\ +      mmesa->draw_point( mmesa, v0 );		\ +   else {					\ +      mga_draw_point( mmesa, v0 );		\ +   }						\ +} while (0) + + +/*********************************************************************** + *              Fallback to swrast for basic primitives                * + ***********************************************************************/ + +/* This code is hit only when a mix of accelerated and unaccelerated + * primitives are being drawn, and only for the unaccelerated + * primitives.   + */ + +static void  +mga_fallback_tri( mgaContextPtr mmesa,  +		   mgaVertex *v0,  +		   mgaVertex *v1,  +		   mgaVertex *v2 ) +{ +   GLcontext *ctx = mmesa->glCtx; +   SWvertex v[3]; +   mga_translate_vertex( ctx, v0, &v[0] ); +   mga_translate_vertex( ctx, v1, &v[1] ); +   mga_translate_vertex( ctx, v2, &v[2] ); +   _swrast_Triangle( ctx, &v[0], &v[1], &v[2] ); +} + + +static void  +mga_fallback_line( mgaContextPtr mmesa, +		    mgaVertex *v0, +		    mgaVertex *v1 ) +{ +   GLcontext *ctx = mmesa->glCtx; +   SWvertex v[2]; +   mga_translate_vertex( ctx, v0, &v[0] ); +   mga_translate_vertex( ctx, v1, &v[1] ); +   _swrast_Line( ctx, &v[0], &v[1] ); +} + + +static void  +mga_fallback_point( mgaContextPtr mmesa,  +		     mgaVertex *v0 ) +{ +   GLcontext *ctx = mmesa->glCtx; +   SWvertex v[1]; +   mga_translate_vertex( ctx, v0, &v[0] ); +   _swrast_Point( ctx, &v[0] ); +} + +/*********************************************************************** + *              Build render functions from dd templates               * + ***********************************************************************/ + + +#define MGA_UNFILLED_BIT    0x1 +#define MGA_OFFSET_BIT	    0x2 +#define MGA_TWOSIDE_BIT     0x4 +#define MGA_FLAT_BIT        0x8	/* mga can't flatshade? */ +#define MGA_FALLBACK_BIT    0x10 +#define MGA_MAX_TRIFUNC     0x20 + +static struct { +   points_func	        points; +   line_func		line; +   triangle_func	triangle; +   quad_func		quad; +} rast_tab[MGA_MAX_TRIFUNC]; + +#define DO_FALLBACK (IND & MGA_FALLBACK_BIT) +#define DO_OFFSET   (IND & MGA_OFFSET_BIT) +#define DO_UNFILLED (IND & MGA_UNFILLED_BIT) +#define DO_TWOSIDE  (IND & MGA_TWOSIDE_BIT) +#define DO_FLAT     (IND & MGA_FLAT_BIT) +#define DO_TRI       1 +#define DO_QUAD      1 +#define DO_LINE      1 +#define DO_POINTS    1 +#define DO_FULL_QUAD 1 + +#define HAVE_RGBA         1 +#define HAVE_BACK_COLORS  0 +#define HAVE_SPEC         1 +#define HAVE_HW_FLATSHADE 0 +#define VERTEX mgaVertex +#define TAB rast_tab + +#define MGA_COLOR( dst, src )			\ +do {						\ +   dst[0] = src[2];				\ +   dst[1] = src[1];				\ +   dst[2] = src[0];				\ +   dst[3] = src[3];				\ +} while (0) + +#define MGA_SPEC( dst, src )			\ +do {						\ +   dst[0] = src[2];				\ +   dst[1] = src[1];				\ +   dst[2] = src[0];				\ +} while (0) + +#define DEPTH_SCALE mmesa->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) (mmesa->verts + (e<<mmesa->vertex_stride_shift)) + +#define VERT_SET_RGBA( v, c )  MGA_COLOR( v->ub4[4], c ) +#define VERT_COPY_RGBA( v0, v1 ) v0->ui[4] = v1->ui[4] +#define VERT_SAVE_RGBA( idx )  color[idx] = v[idx]->ui[4] +#define VERT_RESTORE_RGBA( idx ) v[idx]->ui[4] = color[idx]    + +#define VERT_SET_SPEC( v, c )  MGA_SPEC( v->ub4[5], c ) +#define VERT_COPY_SPEC( v0, v1 ) COPY_3V(v0->ub4[5], v1->ub4[5]) +#define VERT_SAVE_SPEC( idx )  spec[idx] = v[idx]->ui[5] +#define VERT_RESTORE_SPEC( idx ) v[idx]->ui[5] = spec[idx]    + +#define LOCAL_VARS(n)					\ +   mgaContextPtr mmesa = MGA_CONTEXT(ctx);		\ +   GLuint color[n], spec[n];				\ +   (void) color; (void) spec; + + + +/*********************************************************************** + *            Functions to draw basic unfilled primitives              * + ***********************************************************************/ + +#define RASTERIZE(x) if (mmesa->raster_primitive != x) \ +                        mgaRasterPrimitive( ctx, x, MGA_WA_TRIANGLES ) +#define RENDER_PRIMITIVE mmesa->render_primitive +#define IND MGA_FALLBACK_BIT +#define TAG(x) x +#include "tnl_dd/t_dd_unfilled.h" +#undef IND + +/*********************************************************************** + *                 Functions to draw GL primitives                     * + ***********************************************************************/ + +#define IND (0) +#define TAG(x) x +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (MGA_OFFSET_BIT) +#define TAG(x) x##_offset +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (MGA_TWOSIDE_BIT) +#define TAG(x) x##_twoside +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT) +#define TAG(x) x##_twoside_offset +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (MGA_UNFILLED_BIT) +#define TAG(x) x##_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (MGA_OFFSET_BIT|MGA_UNFILLED_BIT) +#define TAG(x) x##_offset_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (MGA_TWOSIDE_BIT|MGA_UNFILLED_BIT) +#define TAG(x) x##_twoside_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT|MGA_UNFILLED_BIT) +#define TAG(x) x##_twoside_offset_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (MGA_FALLBACK_BIT) +#define TAG(x) x##_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (MGA_OFFSET_BIT|MGA_FALLBACK_BIT) +#define TAG(x) x##_offset_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (MGA_TWOSIDE_BIT|MGA_FALLBACK_BIT) +#define TAG(x) x##_twoside_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT|MGA_FALLBACK_BIT) +#define TAG(x) x##_twoside_offset_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (MGA_UNFILLED_BIT|MGA_FALLBACK_BIT) +#define TAG(x) x##_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (MGA_OFFSET_BIT|MGA_UNFILLED_BIT|MGA_FALLBACK_BIT) +#define TAG(x) x##_offset_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (MGA_TWOSIDE_BIT|MGA_UNFILLED_BIT|MGA_FALLBACK_BIT) +#define TAG(x) x##_twoside_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT|MGA_UNFILLED_BIT| \ +	     MGA_FALLBACK_BIT) +#define TAG(x) x##_twoside_offset_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + + +/* Mga doesn't support provoking-vertex flat-shading? + */ +#define IND (MGA_FLAT_BIT) +#define TAG(x) x##_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (MGA_OFFSET_BIT|MGA_FLAT_BIT) +#define TAG(x) x##_offset_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (MGA_TWOSIDE_BIT|MGA_FLAT_BIT) +#define TAG(x) x##_twoside_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT|MGA_FLAT_BIT) +#define TAG(x) x##_twoside_offset_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (MGA_UNFILLED_BIT|MGA_FLAT_BIT) +#define TAG(x) x##_unfilled_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (MGA_OFFSET_BIT|MGA_UNFILLED_BIT|MGA_FLAT_BIT) +#define TAG(x) x##_offset_unfilled_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (MGA_TWOSIDE_BIT|MGA_UNFILLED_BIT|MGA_FLAT_BIT) +#define TAG(x) x##_twoside_unfilled_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT|MGA_UNFILLED_BIT|MGA_FLAT_BIT) +#define TAG(x) x##_twoside_offset_unfilled_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (MGA_FALLBACK_BIT|MGA_FLAT_BIT) +#define TAG(x) x##_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (MGA_OFFSET_BIT|MGA_FALLBACK_BIT|MGA_FLAT_BIT) +#define TAG(x) x##_offset_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (MGA_TWOSIDE_BIT|MGA_FALLBACK_BIT|MGA_FLAT_BIT) +#define TAG(x) x##_twoside_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT|MGA_FALLBACK_BIT|MGA_FLAT_BIT) +#define TAG(x) x##_twoside_offset_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (MGA_UNFILLED_BIT|MGA_FALLBACK_BIT|MGA_FLAT_BIT) +#define TAG(x) x##_unfilled_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (MGA_OFFSET_BIT|MGA_UNFILLED_BIT|MGA_FALLBACK_BIT|MGA_FLAT_BIT) +#define TAG(x) x##_offset_unfilled_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (MGA_TWOSIDE_BIT|MGA_UNFILLED_BIT|MGA_FALLBACK_BIT|MGA_FLAT_BIT) +#define TAG(x) x##_twoside_unfilled_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT|MGA_UNFILLED_BIT| \ +	     MGA_FALLBACK_BIT|MGA_FLAT_BIT) +#define TAG(x) x##_twoside_offset_unfilled_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" + + +static void init_rast_tab( void ) +{ +   init(); +   init_offset(); +   init_twoside(); +   init_twoside_offset(); +   init_unfilled(); +   init_offset_unfilled(); +   init_twoside_unfilled(); +   init_twoside_offset_unfilled(); +   init_fallback(); +   init_offset_fallback(); +   init_twoside_fallback(); +   init_twoside_offset_fallback(); +   init_unfilled_fallback(); +   init_offset_unfilled_fallback(); +   init_twoside_unfilled_fallback(); +   init_twoside_offset_unfilled_fallback(); + +   init_flat(); +   init_offset_flat(); +   init_twoside_flat(); +   init_twoside_offset_flat(); +   init_unfilled_flat(); +   init_offset_unfilled_flat(); +   init_twoside_unfilled_flat(); +   init_twoside_offset_unfilled_flat(); +   init_fallback_flat(); +   init_offset_fallback_flat(); +   init_twoside_fallback_flat(); +   init_twoside_offset_fallback_flat(); +   init_unfilled_fallback_flat(); +   init_offset_unfilled_fallback_flat(); +   init_twoside_unfilled_fallback_flat(); +   init_twoside_offset_unfilled_fallback_flat(); +} + +/**********************************************************************/ +/*                 Render whole begin/end objects                     */ +/**********************************************************************/ + + +#define VERT(x) (mgaVertex *)(vertptr + ((x)<<vertshift)) +#define RENDER_POINTS( start, count )		\ +   for ( ; start < count ; start++)		\ +      mga_draw_point( mmesa, VERT(ELT(start)) ); +#define RENDER_LINE( v0, v1 ) \ +   mga_draw_line( mmesa, VERT(v0), VERT(v1) ) +#define RENDER_TRI( v0, v1, v2 )  \ +   mga_draw_triangle( mmesa, VERT(v0), VERT(v1), VERT(v2) ) +#define RENDER_QUAD( v0, v1, v2, v3 ) \ +   mga_draw_quad( mmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) ) +#define INIT(x) mgaRenderPrimitive( ctx, x ) +#undef LOCAL_VARS +#define LOCAL_VARS						\ +    mgaContextPtr mmesa = MGA_CONTEXT(ctx);			\ +    GLubyte *vertptr = (GLubyte *)mmesa->verts;			\ +    const GLuint vertshift = mmesa->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) mga_##x##_verts +#include "tnl/t_vb_rendertmp.h" +#undef ELT +#undef TAG +#define TAG(x) mga_##x##_elts +#define ELT(x) elt[x] +#include "tnl/t_vb_rendertmp.h" + + +/**********************************************************************/ +/*                   Render clipped primitives                        */ +/**********************************************************************/ + + + +static void mgaRenderClippedPoly( GLcontext *ctx, const GLuint *elts, GLuint n ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); +   TNLcontext *tnl = TNL_CONTEXT(ctx); +   struct vertex_buffer *VB = &tnl->vb; +   GLuint prim = mmesa->render_primitive; + +   /* Render the new vertices as an unclipped polygon.  +    */ +   { +      GLuint *tmp = VB->Elts; +      VB->Elts = (GLuint *)elts; +      tnl->Driver.Render.PrimTabElts[GL_POLYGON]( ctx, 0, n, PRIM_BEGIN|PRIM_END ); +      VB->Elts = tmp; +   } + +   /* Restore the render primitive +    */ +   if (prim != GL_POLYGON) +      tnl->Driver.Render.PrimitiveNotify( ctx, prim ); +} + +static void mgaRenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj ) +{ +   TNLcontext *tnl = TNL_CONTEXT(ctx); +   tnl->Driver.Render.Line( ctx, ii, jj ); +} + +static void mgaFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts,  +				       GLuint n ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT( ctx ); +   GLuint vertex_size = mmesa->vertex_size; +   GLuint *vb = mgaAllocDmaLow( mmesa, (n-2) * 3 * 4 * vertex_size ); +   GLubyte *vertptr = (GLubyte *)mmesa->verts;			 +   const GLuint vertshift = mmesa->vertex_stride_shift;       	 +   const GLuint *start = (const GLuint *)VERT(elts[0]); +   int i,j; + +   for (i = 2 ; i < n ; i++) { +      EMIT_VERT( j, vb, vertex_size, (mgaVertexPtr) VERT(elts[i-1]) ); +      EMIT_VERT( j, vb, vertex_size, (mgaVertexPtr) VERT(elts[i]) ); +      EMIT_VERT( j, vb, vertex_size, (mgaVertexPtr) start ); +   } +} + +/**********************************************************************/ +/*                    Choose render functions                         */ +/**********************************************************************/ + + + +#define _MGA_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 (DD_POINT_SMOOTH) +#define LINE_FALLBACK (DD_LINE_SMOOTH | DD_LINE_STIPPLE) +#define TRI_FALLBACK (DD_TRI_SMOOTH | DD_TRI_UNFILLED) +#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK| \ +                            DD_TRI_STIPPLE) +#define ANY_RASTER_FLAGS (DD_FLATSHADE|DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET| \ +                          DD_TRI_UNFILLED) + +static void mgaChooseRenderState(GLcontext *ctx) +{ +   TNLcontext *tnl = TNL_CONTEXT(ctx); +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); +   GLuint flags = ctx->_TriangleCaps; +   GLuint index = 0; + +   if (flags & (ANY_FALLBACK_FLAGS|ANY_RASTER_FLAGS)) { +      if (flags & ANY_RASTER_FLAGS) { +	 if (flags & DD_TRI_LIGHT_TWOSIDE)    index |= MGA_TWOSIDE_BIT; +	 if (flags & DD_TRI_OFFSET)	      index |= MGA_OFFSET_BIT; +	 if (flags & DD_TRI_UNFILLED)	      index |= MGA_UNFILLED_BIT; +	 if (flags & DD_FLATSHADE)	      index |= MGA_FLAT_BIT; +      } + +      mmesa->draw_point = mga_draw_point; +      mmesa->draw_line = mga_draw_line; +      mmesa->draw_tri = mga_draw_triangle; + +      /* Hook in fallbacks for specific primitives. +       */ +      if (flags & ANY_FALLBACK_FLAGS) +      { +	 if (flags & POINT_FALLBACK)  +	    mmesa->draw_point = mga_fallback_point; +	  +	 if (flags & LINE_FALLBACK)  +	    mmesa->draw_line = mga_fallback_line; +	  +	 if (flags & TRI_FALLBACK)  +	    mmesa->draw_tri = mga_fallback_tri; +	  +	 if ((flags & DD_TRI_STIPPLE) && !mmesa->haveHwStipple) +	    mmesa->draw_tri = mga_fallback_tri; +       +	 index |= MGA_FALLBACK_BIT; +      } +   } + +   if (mmesa->RenderIndex != index) { +      mmesa->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 = mga_render_tab_verts; +	 tnl->Driver.Render.PrimTabElts = mga_render_tab_elts; +	 tnl->Driver.Render.ClippedLine = line; /* from tritmp.h */ +	 tnl->Driver.Render.ClippedPolygon = mgaFastRenderClippedPoly; +      } else { +	 tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; +	 tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; +	 tnl->Driver.Render.ClippedLine = mgaRenderClippedLine; +	 tnl->Driver.Render.ClippedPolygon = mgaRenderClippedPoly; +      } +   } +} + +/**********************************************************************/ +/*                Runtime render state and callbacks                  */ +/**********************************************************************/ + + +static void mgaRunPipeline( GLcontext *ctx ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); + +   if (mmesa->new_state) { +      mgaDDUpdateHwState( ctx ); +   } + +   if (!mmesa->Fallback && mmesa->new_gl_state) { +      if (mmesa->new_gl_state & _MGA_NEW_RASTERSETUP) +	 mgaChooseVertexState( ctx ); +       +      if (mmesa->new_gl_state & _MGA_NEW_RENDERSTATE) +	 mgaChooseRenderState( ctx ); +       +      mmesa->new_gl_state = 0; + +      /* Circularity: mgaDDUpdateHwState can affect mmesa->Fallback, +       * but mgaChooseVertexState can affect mmesa->new_state.  Hence +       * the second check.  (Fix this...) +       */ +      if (mmesa->new_state) { +	 mgaDDUpdateHwState( ctx ); +      } +   } + +   _tnl_run_pipeline( ctx ); +} + + +static GLenum reduced_prim[GL_POLYGON+1] = { +   GL_POINTS, +   GL_LINES, +   GL_LINES, +   GL_LINES, +   GL_TRIANGLES, +   GL_TRIANGLES, +   GL_TRIANGLES, +   GL_TRIANGLES, +   GL_TRIANGLES, +   GL_TRIANGLES +}; + + + +/* Always called between RenderStart and RenderFinish --> We already + * hold the lock. + */ +void mgaRasterPrimitive( GLcontext *ctx, GLenum prim, GLuint hwprim ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + +   FLUSH_BATCH( mmesa ); +   mmesa->raster_primitive = prim; +/*     mmesa->hw_primitive = hwprim; */ +   mmesa->hw_primitive = MGA_WA_TRIANGLES; /* disable mgarender.c for now */ +   mgaUpdateCull(ctx);    + +   if (ctx->Polygon.StippleFlag && mmesa->haveHwStipple) +   { +      mmesa->dirty |= MGA_UPLOAD_CONTEXT; +      if (mmesa->raster_primitive == GL_TRIANGLES) +	 mmesa->setup.dwgctl |= mmesa->poly_stipple; +      else +	 mmesa->setup.dwgctl &= ~(0xf<<20); +   } +} + + + +/* 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 mgarender.c. + */ +static void mgaRenderPrimitive( GLcontext *ctx, GLenum prim ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); +   GLuint rprim = reduced_prim[prim]; + +   mmesa->render_primitive = prim; + +   if (rprim == GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED)) +      return; +        +   if (mmesa->raster_primitive != rprim) { +      mgaRasterPrimitive( ctx, rprim, MGA_WA_TRIANGLES ); +   } +} + +static void mgaRenderFinish( GLcontext *ctx ) +{ +   if (MGA_CONTEXT(ctx)->RenderIndex & MGA_FALLBACK_BIT) +      _swrast_flush( ctx ); +} + + + +/**********************************************************************/ +/*               Manage total rasterization fallbacks                 */ +/**********************************************************************/ + +void mgaFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) +{ +   TNLcontext *tnl = TNL_CONTEXT(ctx); +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); +   GLuint oldfallback = mmesa->Fallback; + +   if (mode) { +      mmesa->Fallback |= bit; +      if (oldfallback == 0) { +	 FLUSH_BATCH(mmesa); +	 _swsetup_Wakeup( ctx ); +	 mmesa->RenderIndex = ~0; +      } +   } +   else { +      mmesa->Fallback &= ~bit; +      if (oldfallback == bit) { +	 _swrast_flush( ctx ); +	 tnl->Driver.Render.Start = mgaCheckTexSizes; +	 tnl->Driver.Render.PrimitiveNotify = mgaRenderPrimitive; +	 tnl->Driver.Render.Finish = mgaRenderFinish; +	 tnl->Driver.Render.BuildVertices = mgaBuildVertices; +	 mmesa->new_gl_state |= (_MGA_NEW_RENDERSTATE | +				 _MGA_NEW_RASTERSETUP); +      } +   } +} + + +void mgaDDInitTriFuncs( GLcontext *ctx ) +{ +   TNLcontext *tnl = TNL_CONTEXT(ctx); +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); +   static int firsttime = 1; +   if (firsttime) { +      init_rast_tab(); +      firsttime = 0; +   } + +   mmesa->RenderIndex = ~0; +	 +   tnl->Driver.RunPipeline               = mgaRunPipeline; +   tnl->Driver.Render.Start              = mgaCheckTexSizes; +   tnl->Driver.Render.Finish             = mgaRenderFinish;  +   tnl->Driver.Render.PrimitiveNotify    = mgaRenderPrimitive; +   tnl->Driver.Render.ResetLineStipple   = _swrast_ResetLineStipple; +   tnl->Driver.Render.BuildVertices      = mgaBuildVertices; +   tnl->Driver.Render.Multipass		 = NULL; +} diff --git a/src/mesa/drivers/dri/mga/mgatris.h b/src/mesa/drivers/dri/mga/mgatris.h new file mode 100644 index 0000000000..88eda91e13 --- /dev/null +++ b/src/mesa/drivers/dri/mga/mgatris.h @@ -0,0 +1,43 @@ +/* + * Copyright 2000-2001 VA Linux Systems, Inc. + * 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 + * VA LINUX SYSTEMS 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> + */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatris.h,v 1.10 2002/10/30 12:51:36 alanh Exp $ */ + +#ifndef MGATRIS_INC +#define MGATRIS_INC + +#include "mtypes.h" + +extern void mgaDDInitTriFuncs( GLcontext *ctx ); + +extern void mgaRasterPrimitive( GLcontext *ctx, GLenum prim, GLuint hwprim ); + +extern void mgaFallback( GLcontext *ctx, GLuint bit, GLboolean mode ); +#define FALLBACK( ctx, bit, mode ) mgaFallback( ctx, bit, mode ) + + + +#endif diff --git a/src/mesa/drivers/dri/mga/mgavb.c b/src/mesa/drivers/dri/mga/mgavb.c new file mode 100644 index 0000000000..d354fa43d2 --- /dev/null +++ b/src/mesa/drivers/dri/mga/mgavb.c @@ -0,0 +1,497 @@ +/* + * Copyright 2000-2001 VA Linux Systems, Inc. + * 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 + * VA LINUX SYSTEMS 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> + */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgavb.c,v 1.15 2003/03/26 20:43:49 tsi Exp $ */ + +#include "mgacontext.h" +#include "mgavb.h" +#include "mgatris.h" +#include "mgaioctl.h" +#include "mga_xmesa.h" + +#include "glheader.h" +#include "mtypes.h" +/*#include "mem.h" */ +#include "macros.h" +#include "colormac.h" +/*#include "mmath.h"*/ + +#include "tnl/t_context.h" +#include "swrast_setup/swrast_setup.h" +#include "swrast/swrast.h" + +#include <stdio.h> +#include <stdlib.h> + + +#define MGA_TEX1_BIT       0x1 +#define MGA_TEX0_BIT       0x2	 +#define MGA_RGBA_BIT       0x4 +#define MGA_SPEC_BIT       0x8 +#define MGA_FOG_BIT	   0x10 +#define MGA_XYZW_BIT       0x20 +#define MGA_PTEX_BIT       0x40 +#define MGA_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[MGA_MAX_SETUP]; + + +#define TINY_VERTEX_FORMAT      0 +#define NOTEX_VERTEX_FORMAT     0 +#define TEX0_VERTEX_FORMAT      (MGA_A|MGA_S|MGA_F) +#define TEX1_VERTEX_FORMAT      (MGA_A|MGA_S|MGA_F|MGA_T2) +#define PROJ_TEX1_VERTEX_FORMAT 0 +#define TEX2_VERTEX_FORMAT      0 +#define TEX3_VERTEX_FORMAT      0 +#define PROJ_TEX3_VERTEX_FORMAT 0 + +#define DO_XYZW (IND & MGA_XYZW_BIT) +#define DO_RGBA (IND & MGA_RGBA_BIT) +#define DO_SPEC (IND & MGA_SPEC_BIT) +#define DO_FOG  (IND & MGA_FOG_BIT) +#define DO_TEX0 (IND & MGA_TEX0_BIT) +#define DO_TEX1 (IND & MGA_TEX1_BIT) +#define DO_TEX2 0 +#define DO_TEX3 0 +#define DO_PTEX (IND & MGA_PTEX_BIT) + +			        +#define VERTEX mgaVertex +#define VERTEX_COLOR mga_color_t +#define LOCALVARS mgaContextPtr mmesa = MGA_CONTEXT(ctx); +#define GET_VIEWPORT_MAT() mmesa->hw_viewport +#define GET_TEXSOURCE(n)  mmesa->tmu_source[n] +#define GET_VERTEX_FORMAT() mmesa->vertex_format +#define GET_VERTEX_STORE() ((GLubyte *)mmesa->verts) +#define GET_VERTEX_STRIDE_SHIFT() mmesa->vertex_stride_shift +#define GET_UBYTE_COLOR_STORE() &mmesa->UbyteColor +#define GET_UBYTE_SPEC_COLOR_STORE() &mmesa->UbyteSecondaryColor + +#define HAVE_HW_VIEWPORT    0 +#define HAVE_HW_DIVIDE      0 +#define HAVE_RGBA_COLOR     0 +#define HAVE_TINY_VERTICES  0 +#define HAVE_NOTEX_VERTICES 0 +#define HAVE_TEX0_VERTICES  1 +#define HAVE_TEX1_VERTICES  1 +#define HAVE_TEX2_VERTICES  0 +#define HAVE_TEX3_VERTICES  0 +#define HAVE_PTEX_VERTICES  0 + +#define UNVIEWPORT_VARS					\ +   const GLfloat dx = - mmesa->drawX - SUBPIXEL_X;	\ +   const GLfloat dy = (mmesa->driDrawable->h + 		\ +		       mmesa->drawY + SUBPIXEL_Y);	\ +   const GLfloat sz = 1.0 / mmesa->depth_scale + +#define UNVIEWPORT_X(x)    x      + dx; +#define UNVIEWPORT_Y(y)  - y      + dy; +#define UNVIEWPORT_Z(z)    z * sz; + +#define PTEX_FALLBACK() FALLBACK(ctx, MGA_FALLBACK_TEXTURE, 1) + + +#define IMPORT_FLOAT_COLORS mga_import_float_colors +#define IMPORT_FLOAT_SPEC_COLORS mga_import_float_spec_colors + +#define INTERP_VERTEX setup_tab[MGA_CONTEXT(ctx)->SetupIndex].interp +#define COPY_PV_VERTEX setup_tab[MGA_CONTEXT(ctx)->SetupIndex].copy_pv + + +/*********************************************************************** + *         Generate  pv-copying and translation functions              * + ***********************************************************************/ + +#define TAG(x) mga_##x +#include "tnl_dd/t_dd_vb.c" + +/*********************************************************************** + *             Generate vertex emit and interp functions               * + ***********************************************************************/ + + +#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT) +#define TAG(x) x##_wg +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_SPEC_BIT) +#define TAG(x) x##_wgs +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_TEX0_BIT) +#define TAG(x) x##_wgt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT) +#define TAG(x) x##_wgt0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_TEX0_BIT|MGA_PTEX_BIT) +#define TAG(x) x##_wgpt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT) +#define TAG(x) x##_wgst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT) +#define TAG(x) x##_wgst0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT|MGA_PTEX_BIT) +#define TAG(x) x##_wgspt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_FOG_BIT) +#define TAG(x) x##_wgf +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_FOG_BIT|MGA_SPEC_BIT) +#define TAG(x) x##_wgfs +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_FOG_BIT|MGA_TEX0_BIT) +#define TAG(x) x##_wgft0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_FOG_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT) +#define TAG(x) x##_wgft0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_FOG_BIT|MGA_TEX0_BIT|MGA_PTEX_BIT) +#define TAG(x) x##_wgfpt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_FOG_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT) +#define TAG(x) x##_wgfst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_FOG_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT) +#define TAG(x) x##_wgfst0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_FOG_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT|MGA_PTEX_BIT) +#define TAG(x) x##_wgfspt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (MGA_TEX0_BIT) +#define TAG(x) x##_t0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (MGA_TEX0_BIT|MGA_TEX1_BIT) +#define TAG(x) x##_t0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (MGA_FOG_BIT) +#define TAG(x) x##_f +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (MGA_FOG_BIT|MGA_TEX0_BIT) +#define TAG(x) x##_ft0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (MGA_FOG_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT) +#define TAG(x) x##_ft0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (MGA_RGBA_BIT) +#define TAG(x) x##_g +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (MGA_RGBA_BIT|MGA_SPEC_BIT) +#define TAG(x) x##_gs +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (MGA_RGBA_BIT|MGA_TEX0_BIT) +#define TAG(x) x##_gt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (MGA_RGBA_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT) +#define TAG(x) x##_gt0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (MGA_RGBA_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT) +#define TAG(x) x##_gst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (MGA_RGBA_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT) +#define TAG(x) x##_gst0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (MGA_RGBA_BIT|MGA_FOG_BIT) +#define TAG(x) x##_gf +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (MGA_RGBA_BIT|MGA_FOG_BIT|MGA_SPEC_BIT) +#define TAG(x) x##_gfs +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (MGA_RGBA_BIT|MGA_FOG_BIT|MGA_TEX0_BIT) +#define TAG(x) x##_gft0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (MGA_RGBA_BIT|MGA_FOG_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT) +#define TAG(x) x##_gft0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (MGA_RGBA_BIT|MGA_FOG_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT) +#define TAG(x) x##_gfst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (MGA_RGBA_BIT|MGA_FOG_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT) +#define TAG(x) x##_gfst0t1 +#include "tnl_dd/t_dd_vbtmp.h" + + +static void init_setup_tab( void ) +{ +   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(); +} + + + + +void mgaPrintSetupFlags(char *msg, GLuint flags ) +{ +   fprintf(stderr, "%s: %d %s%s%s%s%s%s\n", +	   msg, +	   (int)flags, +	   (flags & MGA_XYZW_BIT)      ? " xyzw," : "",  +	   (flags & MGA_RGBA_BIT)     ? " rgba," : "", +	   (flags & MGA_SPEC_BIT)     ? " spec," : "", +	   (flags & MGA_FOG_BIT)      ? " fog," : "", +	   (flags & MGA_TEX0_BIT)     ? " tex-0," : "", +	   (flags & MGA_TEX1_BIT)     ? " tex-1," : ""); +} + + +void mgaCheckTexSizes( GLcontext *ctx ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT( ctx ); +   TNLcontext *tnl = TNL_CONTEXT(ctx); + +   /*fprintf(stderr, "%s\n", __FUNCTION__);*/ + +   if (!setup_tab[mmesa->SetupIndex].check_tex_sizes(ctx)) { +      mmesa->SetupIndex |= MGA_PTEX_BIT; +      mmesa->SetupNewInputs = ~0; + +      if (!mmesa->Fallback && +	  !(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) { +	 tnl->Driver.Render.Interp = setup_tab[mmesa->SetupIndex].interp; +	 tnl->Driver.Render.CopyPV = setup_tab[mmesa->SetupIndex].copy_pv; +      } +   } +} + + +void mgaBuildVertices( GLcontext *ctx,  +		       GLuint start,  +		       GLuint count, +		       GLuint newinputs ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT( ctx ); +   GLubyte *v = ((GLubyte *)mmesa->verts + (start<<mmesa->vertex_stride_shift)); +   GLuint stride = 1<<mmesa->vertex_stride_shift; + +   newinputs |= mmesa->SetupNewInputs; +   mmesa->SetupNewInputs = 0; + +   if (!newinputs) +      return; + +   if (newinputs & VERT_BIT_CLIP) { +      setup_tab[mmesa->SetupIndex].emit( ctx, start, count, v, stride );    +   } else { +      GLuint ind = 0; + +      if (newinputs & VERT_BIT_COLOR0) +	 ind |= MGA_RGBA_BIT; +       +      if (newinputs & VERT_BIT_COLOR1) +	 ind |= MGA_SPEC_BIT; + +      if (newinputs & VERT_BIT_TEX0)  +	 ind |= MGA_TEX0_BIT; + +      if (newinputs & VERT_BIT_TEX1) +	 ind |= MGA_TEX0_BIT|MGA_TEX1_BIT; + +      if (newinputs & VERT_BIT_FOG) +	 ind |= MGA_FOG_BIT; + +      if (mmesa->SetupIndex & MGA_PTEX_BIT) +	 ind = ~0; + +      ind &= mmesa->SetupIndex; + +      if (ind) { +	 setup_tab[ind].emit( ctx, start, count, v, stride );    +      } +   } +} + + +void mgaChooseVertexState( GLcontext *ctx ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT( ctx ); +   TNLcontext *tnl = TNL_CONTEXT(ctx); +   GLuint ind = MGA_XYZW_BIT|MGA_RGBA_BIT; + +   if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)  +      ind |= MGA_SPEC_BIT; + +   if (ctx->Fog.Enabled)  +      ind |= MGA_FOG_BIT; +    +   if (ctx->Texture.Unit[1]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) { +      if (ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) { +	 ind |= MGA_TEX1_BIT|MGA_TEX0_BIT; +      } +      else { +	 ind |= MGA_TEX0_BIT; +      } +   } +   else if (ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) { +      ind |= MGA_TEX0_BIT; +   } +    +   mmesa->SetupIndex = ind; + +   if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) { +      tnl->Driver.Render.Interp = mga_interp_extras; +      tnl->Driver.Render.CopyPV = mga_copy_pv_extras; +   } else { +      tnl->Driver.Render.Interp = setup_tab[ind].interp; +      tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv; +   } + +   if (setup_tab[ind].vertex_format != mmesa->vertex_format) { +      FLUSH_BATCH(mmesa);       +      mmesa->new_state |= MGA_NEW_WARP; +      mmesa->dirty |= MGA_UPLOAD_PIPE; +      mmesa->vertex_format = setup_tab[ind].vertex_format; +      mmesa->vertex_size = setup_tab[ind].vertex_size; +      mmesa->vertex_stride_shift = setup_tab[ind].vertex_stride_shift; +   } +} + + + +void mga_emit_contiguous_verts( GLcontext *ctx, +				 GLuint start, +				 GLuint count ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); +   GLuint vertex_size = mmesa->vertex_size * 4; +   GLuint *dest = mgaAllocDmaLow( mmesa, (count-start) * vertex_size); +   setup_tab[mmesa->SetupIndex].emit( ctx, start, count, dest, vertex_size ); +} +				    + + +void mgaInitVB( GLcontext *ctx ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); +   GLuint size = TNL_CONTEXT(ctx)->vb.Size; + +   mmesa->verts = (char *)ALIGN_MALLOC(size * sizeof(mgaVertex), 32); + +   { +      static int firsttime = 1; +      if (firsttime) { +	 init_setup_tab(); +	 firsttime = 0; +      } +   } + +   mmesa->new_state |= MGA_NEW_WARP; +   mmesa->dirty |= MGA_UPLOAD_PIPE; +   mmesa->vertex_format = setup_tab[0].vertex_format; +   mmesa->vertex_size = setup_tab[0].vertex_size; +   mmesa->vertex_stride_shift = setup_tab[0].vertex_stride_shift; +} + + +void mgaFreeVB( GLcontext *ctx ) +{ +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); +   if (mmesa->verts) { +      ALIGN_FREE(mmesa->verts); +      mmesa->verts = 0; +   } + +   if (mmesa->UbyteSecondaryColor.Ptr) { +      ALIGN_FREE(mmesa->UbyteSecondaryColor.Ptr); +      mmesa->UbyteSecondaryColor.Ptr = 0; +   } + +   if (mmesa->UbyteColor.Ptr) { +      ALIGN_FREE(mmesa->UbyteColor.Ptr); +      mmesa->UbyteColor.Ptr = 0; +   } +} + diff --git a/src/mesa/drivers/dri/mga/mgavb.h b/src/mesa/drivers/dri/mga/mgavb.h new file mode 100644 index 0000000000..88cc3108df --- /dev/null +++ b/src/mesa/drivers/dri/mga/mgavb.h @@ -0,0 +1,65 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgavb.h,v 1.8 2002/10/30 12:51:36 alanh Exp $ */ +/* + * Copyright 2000-2001 VA Linux Systems, Inc. + * 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 + * VA LINUX SYSTEMS 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> + */ + +#ifndef MGAVB_INC +#define MGAVB_INC + +#include "mtypes.h" +#include "mgacontext.h" +#include "swrast/swrast.h" + +#define _MGA_NEW_RASTERSETUP (_NEW_TEXTURE |			\ +			      _DD_NEW_SEPARATE_SPECULAR |	\ +			      _DD_NEW_TRI_UNFILLED |		\ +			      _DD_NEW_TRI_LIGHT_TWOSIDE |	\ +			      _NEW_FOG) + + +extern void mgaChooseVertexState( GLcontext *ctx ); +extern void mgaCheckTexSizes( GLcontext *ctx ); +extern void mgaBuildVertices( GLcontext *ctx,  +			      GLuint start,  +			      GLuint count, +			      GLuint newinputs ); + +extern void mgaPrintSetupFlags(char *msg, GLuint flags ); + +extern void mgaInitVB( GLcontext *ctx ); +extern void mgaFreeVB( GLcontext *ctx ); + +extern void mga_emit_contiguous_verts( GLcontext *ctx, +					GLuint start, +					GLuint count ); + +extern void mga_translate_vertex(GLcontext *ctx,  +				 const mgaVertex *src,  +				 SWvertex *dst); + +extern void mga_print_vertex( GLcontext *ctx, const mgaVertex *v ); + +#endif diff --git a/src/mesa/drivers/dri/mga/server/mga.h b/src/mesa/drivers/dri/mga/server/mga.h new file mode 100644 index 0000000000..830d48d859 --- /dev/null +++ b/src/mesa/drivers/dri/mga/server/mga.h @@ -0,0 +1,115 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h,v 1.85 2002/12/16 16:19:17 dawes Exp $ */ +/* + * MGA Millennium (MGA2064W) functions + * + * Copyright 1996 The XFree86 Project, Inc. + * + * Authors + *		Dirk Hohndel + *			hohndel@XFree86.Org + *		David Dawes + *			dawes@XFree86.Org + */ + +#ifndef MGA_H +#define MGA_H + + +#include "xf86drm.h" +#include "linux/types.h" + + +#define PCI_CHIP_MGA2085		0x0518 +#define PCI_CHIP_MGA2064		0x0519 +#define PCI_CHIP_MGA1064		0x051A +#define PCI_CHIP_MGA2164		0x051B +#define PCI_CHIP_MGA2164_AGP		0x051F +#define PCI_CHIP_MGAG200_PCI		0x0520 +#define PCI_CHIP_MGAG200		0x0521 +#define PCI_CHIP_MGAG400		0x0525 +#define PCI_CHIP_MGAG550		0x2527 +#define PCI_CHIP_MGAG100_PCI		0x1000 +#define PCI_CHIP_MGAG100		0x1001 + + +#  define MMIO_IN8(base, offset) \ +	*(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) +#  define MMIO_IN16(base, offset) \ +	*(volatile unsigned short *)(void *)(((unsigned char*)(base)) + (offset)) +#  define MMIO_IN32(base, offset) \ +	*(volatile unsigned int *)(void *)(((unsigned char*)(base)) + (offset)) +#  define MMIO_OUT8(base, offset, val) \ +	*(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) = (val) +#  define MMIO_OUT16(base, offset, val) \ +	*(volatile unsigned short *)(void *)(((unsigned char*)(base)) + (offset)) = (val) +#  define MMIO_OUT32(base, offset, val) \ +	*(volatile unsigned int *)(void *)(((unsigned char*)(base)) + (offset)) = (val) + +#define INREG8(addr) MMIO_IN8(pMga->IOBase, addr) +#define INREG16(addr) MMIO_IN16(pMga->IOBase, addr) +#define INREG(addr) MMIO_IN32(pMga->IOBase, addr) +#define OUTREG8(addr, val) MMIO_OUT8(pMga->IOBase, addr, val) +#define OUTREG16(addr, val) MMIO_OUT16(pMga->IOBase, addr, val) +#define OUTREG(addr, val) MMIO_OUT32(pMga->IOBase, addr, val) + +#define MGAIOMAPSIZE		0x00004000 + + +typedef struct { +  int               Chipset;          /**< \brief Chipset number */ + +  int               irq;              /**< \brief IRQ number */ + + +  int               frontOffset;      /**< \brief Front color buffer offset */ +  int               frontPitch;       /**< \brief Front color buffer pitch */ +  int               backOffset;       /**< \brief Back color buffer offset */ +  int               backPitch;        /**< \brief Back color buffer pitch */ +  int               depthOffset;      /**< \brief Depth buffer offset */ +  int               depthPitch;       /**< \brief Depth buffer pitch */ +  int               textureOffset;    /**< \brief Texture area offset */ +  int               textureSize;      /**< \brief Texture area size */ +  int               logTextureGranularity; + +  /** +   * \name AGP +   */ +  /*@{*/ +  drmSize           agpSize;          /**< \brief AGP map size */ +  int               agpMode;          /**< \brief AGP mode */ +  /*@}*/ + +  drmRegion         agp; + +  /* PCI mappings */ +  drmRegion         registers; +  drmRegion         status; + +  /* AGP mappings */ +  drmRegion         warp; +  drmRegion         primary; +  drmRegion         buffers; +  drmRegion         agpTextures; + +  drmBufMapPtr      drmBuffers; + +  unsigned long     IOAddress; +  unsigned char    *IOBase; +  int		    HasSDRAM; + +  __u32             reg_ien; +} MGARec, *MGAPtr; + + + +#define MGA_FRONT	0x1 +#define MGA_BACK	0x2 +#define MGA_DEPTH	0x4 + +#define MGA_AGP_1X_MODE		0x01 +#define MGA_AGP_2X_MODE		0x02 +#define MGA_AGP_4X_MODE		0x04 +#define MGA_AGP_MODE_MASK	0x07 + + +#endif diff --git a/src/mesa/drivers/dri/mga/server/mga_bios.h b/src/mesa/drivers/dri/mga/server/mga_bios.h new file mode 100644 index 0000000000..8fbf619e34 --- /dev/null +++ b/src/mesa/drivers/dri/mga/server/mga_bios.h @@ -0,0 +1,143 @@ +/* $XConsortium: mga_bios.h /main/2 1996/10/28 04:48:23 kaleb $ */ +#ifndef MGA_BIOS_H +#define MGA_BIOS_H + +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_bios.h,v 1.3 1998/07/25 16:55:51 dawes Exp $ */ + +/* + * MGABiosInfo - This struct describes the video BIOS info block. + * + * DESCRIPTION + *   Do not mess with this, unless you know what you are doing. + *   The data lengths and types are critical. + * + * HISTORY + *   October 7, 1996 - [aem] Andrew E. Mileski + *   This struct was shamelessly stolen from the MGA DDK. + *   It has been reformatted, and the data types changed. + */ +typedef struct { +	/* Length of this structure in bytes */ +	__u16 StructLen; + +	/* +	 * Unique number identifying the product type +	 * 0 : MGA-S1P20 (2MB base with 175MHz Ramdac) +	 * 1 : MGA-S1P21 (2MB base with 220MHz Ramdac) +	 * 2 : Reserved +	 * 3 : Reserved +	 * 4 : MGA-S1P40 (4MB base with 175MHz Ramdac) +	 * 5 : MGA-S1P41 (4MB base with 220MHz Ramdac) +	 */ +	__u16 ProductID; + +	/* Serial number of the board */ +	__u8 SerNo[ 10 ]; + +	/* +	 * Manufacturing date of the board (at product test) +	 * Format: yyyy yyym mmmd dddd +	 */ +	__u16 ManufDate; + +	/* Identification of manufacturing site */ +	__u16 ManufId; + +	/* +	 * Number and revision level of the PCB +	 * Format: nnnn nnnn nnnr rrrr +	 *         n = PCB number ex:576 (from 0->2047) +	 *         r = PCB revision      (from 0->31) +	 */ +	__u16 PCBInfo; + +	/* Identification of any PMBs */ +	__u16 PMBInfo; + +	/* +	 * Bit  0-7  : Ramdac speed (0=175MHz, 1=220MHz) +	 * Bit  8-15 : Ramdac type  (0=TVP3026, 1=TVP3027) +	 */ +	__u16 RamdacType; + +	/* Maximum PCLK of the ramdac */ +	__u16 PclkMax; + +	/* Maximum LDCLK supported by the WRAM memory */ +	__u16 LclkMax; + +	/* Maximum MCLK of base board */ +	__u16 ClkBase; + +	/* Maximum MCLK of 4Mb board */ +	__u16 Clk4MB; + +	/* Maximum MCLK of 8Mb board */ +	__u16 Clk8MB; + +	/* Maximum MCLK of board with multimedia module */ +	__u16 ClkMod; + +	/* Diagnostic test pass frequency */ +	__u16 TestClk; + +	/* Default VGA mode1 pixel frequency */ +	__u16 VGAFreq1; + +	/* Default VGA mode2 pixel frequency */ +	__u16 VGAFreq2; + +	/* Date of last BIOS programming/update */ +	__u16 ProgramDate; + +	/* Number of times BIOS has been programmed */ +	__u16 ProgramCnt; + +	/* Support for up to 32 hardware/software options */ +	__u32 Options; + +	/* Support for up to 32 hardware/software features */ +	__u32 FeatFlag; + +	/* Definition of VGA mode MCLK */ +	__u16 VGAClk; + +	/* Indicate the revision level of this header struct */ +	__u16 StructRev; + +	__u16 Reserved[ 3 ]; +} MGABiosInfo; + +/* from the PINS structure, refer pins info from MGA */ +typedef struct tagParamMGA { +	__u16 	PinID;		/* 0 */ +	__u8	StructLen;	/* 2 */ +	__u8	Rsvd1;		/* 3 */ +	__u16	StructRev;	/* 4 */ +	__u16	ProgramDate;	/* 6 */ +	__u16	ProgramCnt;	/* 8 */ +	__u16	ProductID;	/* 10 */ +	__u8	SerNo[16];	/* 12 */ +	__u8	PLInfo[6];	/* 28 */ +	__u16	PCBInfo;	/* 34 */ +	__u32	FeatFlag;	/* 36 */ +	__u8	RamdacType;	/* 40 */ +	__u8	RamdacSpeed;	/* 41 */ +	__u8	PclkMax;	/* 42 */ +	__u8	ClkGE;		/* 43 */ +	__u8   ClkMem;		/* 44 */ +	__u8	Clk4MB;		/* 45 */ +	__u8	Clk8MB;		/* 46 */ +	__u8	ClkMod;		/* 47 */ +	__u8	TestClk;	/* 48 */ +	__u8	VGAFreq1;	/* 49 */ +	__u8	VGAFreq2;	/* 50 */ +	__u8	MCTLWTST;	/* 51 */ +	__u8	VidCtrl;	/* 52 */ +	__u8	Clk12MB;	/* 53 */ +	__u8	Clk16MB;	/* 54 */ +	__u8	Reserved[8];	/* 55-62 */ +	__u8	PinCheck;	/* 63 */ +}	MGABios2Info; + +#endif diff --git a/src/mesa/drivers/dri/mga/server/mga_common.h b/src/mesa/drivers/dri/mga/server/mga_common.h new file mode 100644 index 0000000000..90f6b37f4e --- /dev/null +++ b/src/mesa/drivers/dri/mga/server/mga_common.h @@ -0,0 +1,152 @@ +/* mga_common.h -- common header definitions for MGA 2D/3D/DRM suite + * + * Copyright 2002 Tungsten Graphics, 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, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL + * 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. + * + * Converted to common header format: + *   Jens Owen <jens@tungstengraphics.com> + * + * $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_common.h,v 1.2 2002/12/16 16:19:18 dawes Exp $ + * + */ + +#ifndef _MGA_COMMON_H_ +#define _MGA_COMMON_H_ + +/* + * WARNING: If you change any of these defines, make sure to change + * the kernel include file as well (mga_drm.h) + */ + +#define  DRM_MGA_IDLE_RETRY          2048 +#define  DRM_MGA_NR_TEX_HEAPS        2 + +typedef struct { +   int installed; +   unsigned long phys_addr; +   int size; +} drmMGAWarpIndex; + +/* Driver specific DRM command indices + * NOTE: these are not OS specific, but they are driver specific + */ +#define DRM_MGA_INIT              0x00 +#define DRM_MGA_FLUSH             0x01 +#define DRM_MGA_RESET             0x02 +#define DRM_MGA_SWAP              0x03 +#define DRM_MGA_CLEAR             0x04 +#define DRM_MGA_VERTEX            0x05 +#define DRM_MGA_INDICES           0x06 +#define DRM_MGA_ILOAD             0x07 +#define DRM_MGA_BLIT              0x08 +#define DRM_MGA_GETPARAM          0x09 + +typedef struct { +   enum { +      MGA_INIT_DMA    = 0x01, +      MGA_CLEANUP_DMA = 0x02 +   } func; + +   unsigned long sarea_priv_offset; + +   int chipset; +   int sgram; + +   unsigned int maccess; + +   unsigned int fb_cpp; +   unsigned int front_offset, front_pitch; +   unsigned int back_offset, back_pitch; + +   unsigned int depth_cpp; +   unsigned int depth_offset, depth_pitch; + +   unsigned int texture_offset[DRM_MGA_NR_TEX_HEAPS]; +   unsigned int texture_size[DRM_MGA_NR_TEX_HEAPS]; + +   unsigned long fb_offset; +   unsigned long mmio_offset; +   unsigned long status_offset; +   unsigned long warp_offset; +   unsigned long primary_offset; +   unsigned long buffers_offset; +} drmMGAInit; + +typedef enum { +   DRM_MGA_LOCK_READY      = 0x01, /* Wait until hardware is ready for DMA */ +   DRM_MGA_LOCK_QUIESCENT  = 0x02, /* Wait until hardware quiescent        */ +   DRM_MGA_LOCK_FLUSH      = 0x04, /* Flush this context's DMA queue first */ +   DRM_MGA_LOCK_FLUSH_ALL  = 0x08, /* Flush all DMA queues first           */ +                                   /* These *HALT* flags aren't supported yet +                                      -- they will be used to support the +                                         full-screen DGA-like mode.        */ +   DRM_MGA_HALT_ALL_QUEUES = 0x10, /* Halt all current and future queues   */ +   DRM_MGA_HALT_CUR_QUEUES = 0x20  /* Halt all current queues              */ +} drmMGALockFlags; + +typedef struct { +   int             context; +   drmMGALockFlags flags; +} drmMGALock; + +typedef struct { +   int idx; +   unsigned int dstorg; +   unsigned int length; +} drmMGAIload; + +typedef struct { +   unsigned int flags; +   unsigned int clear_color; +   unsigned int clear_depth; +   unsigned int color_mask; +   unsigned int depth_mask; +} drmMGAClearRec; + +typedef struct { +   int idx;                        /* buffer to queue */ +   int used;                       /* bytes in use */ +   int discard;                    /* client finished with buffer?  */ +} drmMGAVertex; + +typedef struct { +        unsigned int planemask; +        unsigned int srcorg; +        unsigned int dstorg; +        int src_pitch, dst_pitch; +        int delta_sx, delta_sy; +        int delta_dx, delta_dy; +        int height, ydir;               /* flip image vertically */ +        int source_pitch, dest_pitch; +} drmMGABlit; + +/* 3.1: An ioctl to get parameters that aren't available to the 3d + * client any other way.   + */ +#define MGA_PARAM_IRQ_NR            1 + +typedef struct { +	int param; +	int *value; +} drmMGAGetParam; + +#endif diff --git a/src/mesa/drivers/dri/mga/server/mga_dri.c b/src/mesa/drivers/dri/mga/server/mga_dri.c new file mode 100644 index 0000000000..19ddb38510 --- /dev/null +++ b/src/mesa/drivers/dri/mga/server/mga_dri.c @@ -0,0 +1,1136 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c,v 1.28 2003/02/08 21:26:58 dawes Exp $ */ + +/* + * Copyright 2000 VA Linux Systems Inc., Fremont, California. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL + * VA LINUX SYSTEMS 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> + *    Gareth Hughes <gareth@valinux.com> + */ + +#include <errno.h> +#include <unistd.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +#include "driver.h" +#include "drm.h" + +#include "mga_reg.h" +#include "mga.h" +#include "mga_macros.h" +#include "mga_dri.h" +#include "mga_sarea.h" + +#include "sarea.h" + + + +/* Quiescence, locking + */ +#define MGA_TIMEOUT		2048 + +static void MGAWaitForIdleDMA( struct DRIDriverContextRec *ctx, MGAPtr pMga ) +{ +   drmMGALock lock; +   int ret; +   int i = 0; + +   memset( &lock, 0, sizeof(drmMGALock) ); + +   for (;;) { +      do { +         /* first ask for quiescent and flush */ +         lock.flags = DRM_MGA_LOCK_QUIESCENT | DRM_MGA_LOCK_FLUSH; +         do { +	    ret = drmCommandWrite( ctx->drmFD, DRM_MGA_FLUSH, +                                   &lock, sizeof( drmMGALock ) ); +         } while ( ret == -EBUSY && i++ < DRM_MGA_IDLE_RETRY ); + +         /* if it's still busy just try quiescent */ +         if ( ret == -EBUSY ) {  +            lock.flags = DRM_MGA_LOCK_QUIESCENT; +            do { +	       ret = drmCommandWrite( ctx->drmFD, DRM_MGA_FLUSH, +                                      &lock, sizeof( drmMGALock ) ); +            } while ( ret == -EBUSY && i++ < DRM_MGA_IDLE_RETRY ); +         } +      } while ( ( ret == -EBUSY ) && ( i++ < MGA_TIMEOUT ) ); + +      if ( ret == 0 ) +	 return; + +      fprintf( stderr, +               "[dri] Idle timed out, resetting engine...\n" ); + +      drmCommandNone( ctx->drmFD, DRM_MGA_RESET ); +   } +} + +static unsigned int mylog2( unsigned int n ) +{ +   unsigned int log2 = 1; +   while ( n > 1 ) n >>= 1, log2++; +   return log2; +} + +static int MGADRIAgpInit(struct DRIDriverContextRec *ctx, MGAPtr pMga) +{ +   unsigned long mode; +   unsigned int vendor, device; +   int ret, count, i; + +   if(pMga->agpSize < 12)pMga->agpSize = 12; +   if(pMga->agpSize > 64)pMga->agpSize = 64; /* cap */ + +   /* FIXME: Make these configurable... +    */ +   pMga->agp.size = pMga->agpSize * 1024 * 1024; + +   pMga->warp.offset = 0; +   pMga->warp.size = MGA_WARP_UCODE_SIZE; + +   pMga->primary.offset = (pMga->warp.offset + +				    pMga->warp.size); +   pMga->primary.size = 1024 * 1024; + +   pMga->buffers.offset = (pMga->primary.offset + +				    pMga->primary.size); +   pMga->buffers.size = MGA_NUM_BUFFERS * MGA_BUFFER_SIZE; + + +   pMga->agpTextures.offset = (pMga->buffers.offset + +                                    pMga->buffers.size); + +   pMga->agpTextures.size = pMga->agp.size - +                                     pMga->agpTextures.offset; + +   if ( drmAgpAcquire( ctx->drmFD ) < 0 ) { +     fprintf( stderr, "[agp] AGP not available\n" ); +      return 0; +   } + +   mode   = drmAgpGetMode( ctx->drmFD );        /* Default mode */ +   vendor = drmAgpVendorId( ctx->drmFD ); +   device = drmAgpDeviceId( ctx->drmFD ); + +   mode &= ~MGA_AGP_MODE_MASK; +   switch ( pMga->agpMode ) { +   case 4: +      mode |= MGA_AGP_4X_MODE; +   case 2: +      mode |= MGA_AGP_2X_MODE; +   case 1: +   default: +      mode |= MGA_AGP_1X_MODE; +   } + +#if 0 +   fprintf( stderr, +            "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n", +            mode, vendor, device, +            ctx->pciVendor, +            ctx->pciChipType ); +#endif + +   if ( drmAgpEnable( ctx->drmFD, mode ) < 0 ) { +     fprintf( stderr, "[agp] AGP not enabled\n" ); +      drmAgpRelease( ctx->drmFD ); +      return 0; +   } + +   if ( pMga->Chipset == PCI_CHIP_MGAG200 ) { +      switch ( pMga->agpMode ) { +      case 2: +	 fprintf( stderr, +		     "[drm] Enabling AGP 2x PLL encoding\n" ); +	 OUTREG( MGAREG_AGP_PLL, MGA_AGP2XPLL_ENABLE ); +	 break; + +      case 1: +      default: +	 fprintf( stderr, +		     "[drm] Disabling AGP 2x PLL encoding\n" ); +	 OUTREG( MGAREG_AGP_PLL, MGA_AGP2XPLL_DISABLE ); +	 pMga->agpMode = 1; +	 break; +      } +   } + +   ret = drmAgpAlloc( ctx->drmFD, pMga->agp.size, +		      0, NULL, &pMga->agp.handle ); +   if ( ret < 0 ) { +      fprintf( stderr, "[agp] Out of memory (%d)\n", ret ); +      drmAgpRelease( ctx->drmFD ); +      return 0; +   } +   fprintf( stderr, +	       "[agp] %d kB allocated with handle 0x%08x\n", +	       pMga->agp.size/1024, (unsigned int)pMga->agp.handle ); + +   if ( drmAgpBind( ctx->drmFD, pMga->agp.handle, 0 ) < 0 ) { +      fprintf( stderr, "[agp] Could not bind memory\n" ); +      drmAgpFree( ctx->drmFD, pMga->agp.handle ); +      drmAgpRelease( ctx->drmFD ); +      return 0; +   } + +   /* WARP microcode space +    */ +   if ( drmAddMap( ctx->drmFD, +		   pMga->warp.offset, +		   pMga->warp.size, +		   DRM_AGP, DRM_READ_ONLY, +		   &pMga->warp.handle ) < 0 ) { +      fprintf( stderr, +		  "[agp] Could not add WARP microcode mapping\n" ); +      return 0; +   } +   fprintf( stderr, +	       "[agp] WARP microcode handle = 0x%08lx\n", +	       pMga->warp.handle ); + +   if ( drmMap( ctx->drmFD, +		pMga->warp.handle, +		pMga->warp.size, +		&pMga->warp.map ) < 0 ) { +      fprintf( stderr, +		  "[agp] Could not map WARP microcode\n" ); +      return 0; +   } +   fprintf( stderr, +	       "[agp] WARP microcode mapped at 0x%08lx\n", +	       (unsigned long)pMga->warp.map ); + +   /* Primary DMA space +    */ +   if ( drmAddMap( ctx->drmFD, +		   pMga->primary.offset, +		   pMga->primary.size, +		   DRM_AGP, DRM_READ_ONLY, +		   &pMga->primary.handle ) < 0 ) { +      fprintf( stderr, +		  "[agp] Could not add primary DMA mapping\n" ); +      return 0; +   } +   fprintf( stderr, +	       "[agp] Primary DMA handle = 0x%08lx\n", +	       pMga->primary.handle ); + +   if ( drmMap( ctx->drmFD, +		pMga->primary.handle, +		pMga->primary.size, +		&pMga->primary.map ) < 0 ) { +      fprintf( stderr, +		  "[agp] Could not map primary DMA\n" ); +      return 0; +   } +   fprintf( stderr, +	       "[agp] Primary DMA mapped at 0x%08lx\n", +	       (unsigned long)pMga->primary.map ); + +   /* DMA buffers +    */ +   if ( drmAddMap( ctx->drmFD, +		   pMga->buffers.offset, +		   pMga->buffers.size, +		   DRM_AGP, 0, +		   &pMga->buffers.handle ) < 0 ) { +      fprintf( stderr, +		  "[agp] Could not add DMA buffers mapping\n" ); +      return 0; +   } +   fprintf( stderr, +	       "[agp] DMA buffers handle = 0x%08lx\n", +	       pMga->buffers.handle ); + +   if ( drmMap( ctx->drmFD, +		pMga->buffers.handle, +		pMga->buffers.size, +		&pMga->buffers.map ) < 0 ) { +      fprintf( stderr, +		  "[agp] Could not map DMA buffers\n" ); +      return 0; +   } +   fprintf( stderr, +	       "[agp] DMA buffers mapped at 0x%08lx\n", +	       (unsigned long)pMga->buffers.map ); + +   count = drmAddBufs( ctx->drmFD, +		       MGA_NUM_BUFFERS, MGA_BUFFER_SIZE, +		       DRM_AGP_BUFFER, pMga->buffers.offset ); +   if ( count <= 0 ) { +      fprintf( stderr, +		  "[drm] failure adding %d %d byte DMA buffers\n", +		  MGA_NUM_BUFFERS, MGA_BUFFER_SIZE ); +      return 0; +   } +   fprintf( stderr, +	       "[drm] Added %d %d byte DMA buffers\n", +	       count, MGA_BUFFER_SIZE ); + +   i = mylog2(pMga->agpTextures.size / MGA_NR_TEX_REGIONS); +   if(i < MGA_LOG_MIN_TEX_REGION_SIZE) +      i = MGA_LOG_MIN_TEX_REGION_SIZE; +   pMga->agpTextures.size = (pMga->agpTextures.size >> i) << i; + +   if ( drmAddMap( ctx->drmFD, +                   pMga->agpTextures.offset, +                   pMga->agpTextures.size, +                   DRM_AGP, 0, +                   &pMga->agpTextures.handle ) < 0 ) { +      fprintf( stderr, +                  "[agp] Could not add agpTexture mapping\n" ); +      return 0; +   } +/* should i map it ? */ +   fprintf( stderr, +               "[agp] agpTexture handle = 0x%08lx\n", +               pMga->agpTextures.handle ); +   fprintf( stderr, +               "[agp] agpTexture size: %d kb\n", pMga->agpTextures.size/1024 ); + +   return 1; +} + +static int MGADRIMapInit( struct DRIDriverContextRec *ctx, MGAPtr pMga ) +{ +   pMga->registers.size = MGAIOMAPSIZE; + +   if ( drmAddMap( ctx->drmFD, +		   (drmHandle)pMga->IOAddress, +		   pMga->registers.size, +		   DRM_REGISTERS, DRM_READ_ONLY, +		   &pMga->registers.handle ) < 0 ) { +      fprintf( stderr, +		  "[drm] Could not add MMIO registers mapping\n" ); +      return 0; +   } +   fprintf( stderr, +	       "[drm] Registers handle = 0x%08lx\n", +	       pMga->registers.handle ); + +   pMga->status.size = SAREA_MAX; + +   if ( drmAddMap( ctx->drmFD, 0, pMga->status.size, +		   DRM_SHM, DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL, +		   &pMga->status.handle ) < 0 ) { +      fprintf( stderr, +		  "[drm] Could not add status page mapping\n" ); +      return 0; +   } +   fprintf( stderr, +	       "[drm] Status handle = 0x%08lx\n", +	       pMga->status.handle ); + +   if ( drmMap( ctx->drmFD, +		pMga->status.handle, +		pMga->status.size, +		&pMga->status.map ) < 0 ) { +      fprintf( stderr, +		  "[agp] Could not map status page\n" ); +      return 0; +   } +   fprintf( stderr, +	       "[agp] Status page mapped at 0x%08lx\n", +	       (unsigned long)pMga->status.map ); + +   return 1; +} + +static int MGADRIKernelInit( struct DRIDriverContextRec *ctx, MGAPtr pMga ) +{ +   drmMGAInit init; +   int ret; + +   memset( &init, 0, sizeof(drmMGAInit) ); + +   init.func = MGA_INIT_DMA; +   init.sarea_priv_offset = sizeof(XF86DRISAREARec); + +   switch ( pMga->Chipset ) { +   case PCI_CHIP_MGAG550: +   case PCI_CHIP_MGAG400: +      init.chipset = MGA_CARD_TYPE_G400; +      break; +   case PCI_CHIP_MGAG200: +   case PCI_CHIP_MGAG200_PCI: +      init.chipset = MGA_CARD_TYPE_G200; +      break; +   default: +      return 0; +   } + +   init.sgram = 0; /* FIXME !pMga->HasSDRAM; */ + + +   switch (ctx->bpp) +     { +     case 16: +       init.maccess = MGA_MACCESS_PW16; +       break; +     case 32: +       init.maccess = MGA_MACCESS_PW32; +       break; +     default: +       fprintf( stderr, "[mga] invalid bpp (%d)\n", ctx->bpp ); +       return 0; +     } + + +   init.fb_cpp		= ctx->bpp / 8; +   init.front_offset	= pMga->frontOffset; +   init.front_pitch	= pMga->frontPitch / init.fb_cpp; +   init.back_offset	= pMga->backOffset; +   init.back_pitch	= pMga->backPitch / init.fb_cpp; + +   init.depth_cpp	= ctx->bpp / 8; +   init.depth_offset	= pMga->depthOffset; +   init.depth_pitch	= pMga->depthPitch / init.depth_cpp; + +   init.texture_offset[0] = pMga->textureOffset; +   init.texture_size[0] = pMga->textureSize; + +   init.fb_offset = ctx->shared.hFrameBuffer; +   init.mmio_offset = pMga->registers.handle; +   init.status_offset = pMga->status.handle; + +   init.warp_offset = pMga->warp.handle; +   init.primary_offset = pMga->primary.handle; +   init.buffers_offset = pMga->buffers.handle; + +   init.texture_offset[1] = pMga->agpTextures.handle; +   init.texture_size[1] = pMga->agpTextures.size; + +   ret = drmCommandWrite( ctx->drmFD, DRM_MGA_INIT, &init, sizeof(drmMGAInit)); +   if ( ret < 0 ) { +      fprintf( stderr, +		  "[drm] Failed to initialize DMA! (%d)\n", ret ); +      return 0; +   } + +   return 1; +} + +static void MGADRIIrqInit(struct DRIDriverContextRec *ctx, MGAPtr pMga) +{ +  if (!pMga->irq) +    { +      pMga->irq = drmGetInterruptFromBusID(ctx->drmFD, +                                           ctx->pciBus, +                                           ctx->pciDevice, +                                           ctx->pciFunc); + +      fprintf(stderr, "[drm] got IRQ %d\n", pMga->irq); + +    if((drmCtlInstHandler(ctx->drmFD, pMga->irq)) != 0) +      { +        fprintf(stderr, +                "[drm] failure adding irq handler, " +                "there is a device already using that irq\n" +                "[drm] falling back to irq-free operation\n"); +        pMga->irq = 0; +      } +    else +      { +        pMga->reg_ien = INREG( MGAREG_IEN ); +      } +    } + +  if (pMga->irq) +    fprintf(stderr, +            "[drm] dma control initialized, using IRQ %d\n", +            pMga->irq); +} + +static int MGADRIBuffersInit( struct DRIDriverContextRec *ctx, MGAPtr pMga ) +{ +   pMga->drmBuffers = drmMapBufs( ctx->drmFD ); +   if ( !pMga->drmBuffers ) +     { +       fprintf( stderr, +                "[drm] Failed to map DMA buffers list\n" ); +       return 0; +     } +    +   fprintf( stderr, +            "[drm] Mapped %d DMA buffers\n", +            pMga->drmBuffers->count ); + +   return 1; +} + +static int MGAMemoryInit( struct DRIDriverContextRec *ctx, MGAPtr pMga ) +{ +   int        width_bytes = ctx->shared.virtualWidth * ctx->cpp; +   int        bufferSize  = ((ctx->shared.virtualHeight * width_bytes +			      + MGA_BUFFER_ALIGN) +			     & ~MGA_BUFFER_ALIGN); +   int        depthSize   = ((((ctx->shared.virtualHeight+15) & ~15) * width_bytes +			      + MGA_BUFFER_ALIGN) +			     & ~MGA_BUFFER_ALIGN); +   int        l; + +   pMga->frontOffset = 0; +   pMga->frontPitch = ctx->shared.virtualWidth * ctx->cpp; + +   fprintf(stderr,  +	   "Using %d MB AGP aperture\n", pMga->agpSize); +   fprintf(stderr,  +	   "Using %d MB for vertex/indirect buffers\n", pMga->buffers.size>>20); +   fprintf(stderr,  +	   "Using %d MB for AGP textures\n", pMga->agpTextures.size>>20); + +   /* Front, back and depth buffers - everything else texture?? +    */ +   pMga->textureSize = ctx->shared.fbSize - 2 * bufferSize - depthSize; + +   if (pMga->textureSize < 0)  +      return 0; + +   l = mylog2( pMga->textureSize / MGA_NR_TEX_REGIONS ); +   if ( l < MGA_LOG_MIN_TEX_REGION_SIZE ) +      l = MGA_LOG_MIN_TEX_REGION_SIZE; + +   /* Round the texture size up to the nearest whole number of +    * texture regions.  Again, be greedy about this, don't +    * round down. +    */ +   pMga->logTextureGranularity = l; +   pMga->textureSize = (pMga->textureSize >> l) << l; + +   /* Set a minimum usable local texture heap size.  This will fit +    * two 256x256x32bpp textures. +    */ +   if (pMga->textureSize < 512 * 1024) { +      pMga->textureOffset = 0; +      pMga->textureSize = 0; +   } + +   /* Reserve space for textures */ +   pMga->textureOffset = ((ctx->shared.fbSize - pMga->textureSize + +			   MGA_BUFFER_ALIGN) & +			  ~MGA_BUFFER_ALIGN); + +   /* Reserve space for the shared depth +    * buffer. +    */ +   pMga->depthOffset = ((pMga->textureOffset - depthSize + +			 MGA_BUFFER_ALIGN) & +			~MGA_BUFFER_ALIGN); +   pMga->depthPitch = ctx->shared.virtualWidth * ctx->cpp; + +   pMga->backOffset = ((pMga->depthOffset - bufferSize + +			MGA_BUFFER_ALIGN) & +                        ~MGA_BUFFER_ALIGN); +   pMga->backPitch = ctx->shared.virtualWidth * ctx->cpp; + + +   fprintf(stderr,  +	   "Will use back buffer at offset 0x%x\n", +	   pMga->backOffset); +   fprintf(stderr,  +	   "Will use depth buffer at offset 0x%x\n", +	   pMga->depthOffset); +   fprintf(stderr,  +	   "Will use %d kb for textures at offset 0x%x\n", +	   pMga->textureSize/1024, pMga->textureOffset); + +   return 1; +}  + +static int MGACheckDRMVersion( struct DRIDriverContextRec *ctx, MGAPtr pMga ) +{ +  drmVersionPtr version; + +  /* Check the MGA DRM version */ +  version = drmGetVersion(ctx->drmFD); +  if ( version ) { +    if ( version->version_major != 3 || +         version->version_minor < 0 ) { +            /* incompatible drm version */ +      fprintf( stderr, +               "[dri] MGADRIScreenInit failed because of a version mismatch.\n" +               "[dri] mga.o kernel module version is %d.%d.%d but version 3.0.x is needed.\n" +               "[dri] Disabling DRI.\n", +               version->version_major, +               version->version_minor, +               version->version_patchlevel ); +      drmFreeVersion( version ); +      return 0; +    } +    drmFreeVersion( version ); +  } + +  return 1; +} + +static void print_client_msg( MGADRIPtr pMGADRI ) +{ +  fprintf( stderr, "chipset:                  %d\n", pMGADRI->chipset ); + +  fprintf( stderr, "width:                    %d\n", pMGADRI->width ); +  fprintf( stderr, "height:                   %d\n", pMGADRI->height ); +  fprintf( stderr, "mem:                      %d\n", pMGADRI->mem ); +  fprintf( stderr, "cpp:                      %d\n", pMGADRI->cpp ); + +  fprintf( stderr, "agpMode:                  %d\n", pMGADRI->agpMode ); + +  fprintf( stderr, "frontOffset:              %d\n", pMGADRI->frontOffset ); +  fprintf( stderr, "frontPitch:               %d\n", pMGADRI->frontPitch ); + +  fprintf( stderr, "backOffset:               %d\n", pMGADRI->backOffset ); +  fprintf( stderr, "backPitch:                %d\n", pMGADRI->backPitch ); + +  fprintf( stderr, "depthOffset:              %d\n", pMGADRI->depthOffset ); +  fprintf( stderr, "depthPitch:               %d\n", pMGADRI->depthPitch ); + +  fprintf( stderr, "textureOffset:            %d\n", pMGADRI->textureOffset ); +  fprintf( stderr, "textureSize:              %d\n", pMGADRI->textureSize ); + +  fprintf( stderr, "logTextureGranularity:    %d\n", pMGADRI->logTextureGranularity ); +  fprintf( stderr, "logAgpTextureGranularity: %d\n", pMGADRI->logAgpTextureGranularity ); + +  fprintf( stderr, "agpTextureHandle:         %u\n", (unsigned int)pMGADRI->agpTextureOffset ); +  fprintf( stderr, "agpTextureSize:           %u\n", (unsigned int)pMGADRI->agpTextureSize ); + +#if 0 +   pMGADRI->registers.handle	= pMga->registers.handle; +   pMGADRI->registers.size	= pMga->registers.size; +   pMGADRI->status.handle	= pMga->status.handle; +   pMGADRI->status.size		= pMga->status.size; +   pMGADRI->primary.handle	= pMga->primary.handle; +   pMGADRI->primary.size	= pMga->primary.size; +   pMGADRI->buffers.handle	= pMga->buffers.handle; +   pMGADRI->buffers.size	= pMga->buffers.size; +   pMGADRI->sarea_priv_offset = sizeof(XF86DRISAREARec); +#endif +} + +static int MGAScreenInit( struct DRIDriverContextRec *ctx, MGAPtr pMga ) +{ +  int       i; +  int       err; +  MGADRIPtr pMGADRI; + +  usleep(100); +  /*assert(!ctx->IsClient);*/ + +   { +      int  width_bytes = (ctx->shared.virtualWidth * ctx->cpp); +      int  maxy        = ctx->shared.fbSize / width_bytes; + + +      if (maxy <= ctx->shared.virtualHeight * 3) { +	 fprintf(stderr,  +		 "Static buffer allocation failed -- " +		 "need at least %d kB video memory (have %d kB)\n", +		 (ctx->shared.virtualWidth * ctx->shared.virtualHeight * +		  ctx->cpp * 3 + 1023) / 1024, +		 ctx->shared.fbSize / 1024); +	 return 0; +      }  +   } + +   switch(pMga->Chipset) { +   case PCI_CHIP_MGAG550: +   case PCI_CHIP_MGAG400: +   case PCI_CHIP_MGAG200: +#if 0 +   case PCI_CHIP_MGAG200_PCI: +#endif +      break; +   default: +      fprintf(stderr, "[drm] Direct rendering only supported with G200/G400/G550 AGP\n"); +      return 0; +   } + +   fprintf( stderr, +	       "[drm] bpp: %d depth: %d\n", +            ctx->bpp, ctx->bpp /* FIXME: depth */ ); + +   if ( (ctx->bpp / 8) != 2 && +	(ctx->bpp / 8) != 4 ) { +      fprintf( stderr, +		  "[dri] Direct rendering only supported in 16 and 32 bpp modes\n" ); +      return 0; +   } + +   ctx->shared.SAREASize = SAREA_MAX; + + +   /* Note that drmOpen will try to load the kernel module, if needed. */ +   ctx->drmFD = drmOpen("mga", NULL ); +   if (ctx->drmFD < 0) { +      fprintf(stderr, "[drm] drmOpen failed\n"); +      return 0; +   } + +   if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) { +      fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n", +	      ctx->drmFD, ctx->pciBusID, strerror(-err)); +      return 0; +   } + +      +   if (drmAddMap( ctx->drmFD, +		  0, +		  ctx->shared.SAREASize, +		  DRM_SHM, +		  DRM_CONTAINS_LOCK, +		  &ctx->shared.hSAREA) < 0) +   { +      fprintf(stderr, "[drm] drmAddMap failed\n"); +      return 0; +   } +   fprintf(stderr, "[drm] added %d byte SAREA at 0x%08lx\n", +	   ctx->shared.SAREASize, ctx->shared.hSAREA); + +   if (drmMap( ctx->drmFD, +	       ctx->shared.hSAREA, +	       ctx->shared.SAREASize, +	       (drmAddressPtr)(&ctx->pSAREA)) < 0) +   { +      fprintf(stderr, "[drm] drmMap failed\n"); +      return 0; +   } +   memset(ctx->pSAREA, 0, ctx->shared.SAREASize); +   fprintf(stderr, "[drm] mapped SAREA 0x%08lx to %p, size %d\n", +	   ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize); +    +   /* Need to AddMap the framebuffer and mmio regions here: +    */ +   if (drmAddMap( ctx->drmFD, +		  (drmHandle)ctx->FBStart, +		  ctx->FBSize, +		  DRM_FRAME_BUFFER, +		  0, +		  &ctx->shared.hFrameBuffer) < 0) +   { +      fprintf(stderr, "[drm] drmAddMap framebuffer failed\n"); +      return 0; +   } +   fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n", +	   ctx->shared.hFrameBuffer); + + +#if 0 /* will be done in MGADRIMapInit */ +   if (drmAddMap(ctx->drmFD,  +		 ctx->FixedInfo.mmio_start, +		 ctx->FixedInfo.mmio_len, +		 DRM_REGISTERS,  +		 DRM_READ_ONLY,  +		 &pMga->registers.handle) < 0) { +      fprintf(stderr, "[drm] drmAddMap mmio failed\n");	 +      return 0; +   } +   fprintf(stderr, +	   "[drm] register handle = 0x%08lx\n", pMga->registers.handle); +#endif + + +   /* Check the mga DRM version */ +   if (!MGACheckDRMVersion(ctx, pMga)) { +      return 0; +   } + +   if ( !MGADRIAgpInit( ctx, pMga ) ) { +      return 0; +   } + +   if ( !MGADRIMapInit( ctx, pMga ) ) { +      return 0; +   } + +   /* Memory manager setup */ +   if (!MGAMemoryInit(ctx, pMga)) { +      return 0; +   } + + +   /* Create a 'server' context so we can grab the lock for +    * initialization ioctls. +    */ +   if ((err = drmCreateContext(ctx->drmFD, &ctx->serverContext)) != 0) { +      fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err); +      return 0; +   } + +   DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0);  + +   /* Initialize the kernel data structures */ +   if (!MGADRIKernelInit(ctx, pMga)) { +      fprintf(stderr, "MGADRIKernelInit failed\n"); +      DRM_UNLOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext); +      return 0; +   } + +   /* Initialize the vertex buffers list */ +   if (!MGADRIBuffersInit(ctx, pMga)) { +      fprintf(stderr, "MGADRIBuffersInit failed\n"); +      DRM_UNLOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext); +      return 0; +   } + +   /* Initialize IRQ */ +   MGADRIIrqInit(ctx, pMga); + + +   /* Initialize the SAREA private data structure */ +   { +      MGASAREAPrivPtr pSAREAPriv; +      pSAREAPriv = (MGASAREAPrivPtr)(((char*)ctx->pSAREA) +  +					sizeof(XF86DRISAREARec)); +      memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); +   } + +   /* Quick hack to clear the front & back buffers.  Could also use +    * the clear ioctl to do this, but would need to setup hw state +    * first. +    */ +   memset((char *)ctx->FBAddress + pMga->frontOffset, +	  0, +	  pMga->frontPitch * ctx->shared.virtualHeight ); + +   memset((char *)ctx->FBAddress + pMga->backOffset, +	  0, +	  pMga->backPitch * ctx->shared.virtualHeight ); + +   /* Can release the lock now */ +/*   DRM_UNLOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext);*/ + +   /* This is the struct passed to radeon_dri.so for its initialization */ +   ctx->driverClientMsg = malloc(sizeof(MGADRIRec)); +   ctx->driverClientMsgSize = sizeof(MGADRIRec); + +   pMGADRI                    = (MGADRIPtr)ctx->driverClientMsg; + + +   switch(pMga->Chipset) { +   case PCI_CHIP_MGAG550: +   case PCI_CHIP_MGAG400: +      pMGADRI->chipset = MGA_CARD_TYPE_G400; +      break; +   case PCI_CHIP_MGAG200: +   case PCI_CHIP_MGAG200_PCI: +      pMGADRI->chipset = MGA_CARD_TYPE_G200; +      break; +   default: +      return 0; +   } +   pMGADRI->width		= ctx->shared.virtualWidth; +   pMGADRI->height		= ctx->shared.virtualHeight; +   pMGADRI->mem			= ctx->shared.fbSize; +   pMGADRI->cpp			= ctx->bpp / 8; + +   pMGADRI->agpMode		= pMga->agpMode; + +   pMGADRI->frontOffset		= pMga->frontOffset; +   pMGADRI->frontPitch		= pMga->frontPitch; +   pMGADRI->backOffset		= pMga->backOffset; +   pMGADRI->backPitch		= pMga->backPitch; +   pMGADRI->depthOffset		= pMga->depthOffset; +   pMGADRI->depthPitch		= pMga->depthPitch; +   pMGADRI->textureOffset	= pMga->textureOffset; +   pMGADRI->textureSize		= pMga->textureSize; +   pMGADRI->logTextureGranularity = pMga->logTextureGranularity; + +   i = mylog2( pMga->agpTextures.size / MGA_NR_TEX_REGIONS ); +   if ( i < MGA_LOG_MIN_TEX_REGION_SIZE ) +      i = MGA_LOG_MIN_TEX_REGION_SIZE; + +   pMGADRI->logAgpTextureGranularity = i; +   pMGADRI->agpTextureOffset = (unsigned int)pMga->agpTextures.handle; +   pMGADRI->agpTextureSize = (unsigned int)pMga->agpTextures.size; + +   pMGADRI->registers.handle	= pMga->registers.handle; +   pMGADRI->registers.size	= pMga->registers.size; +   pMGADRI->status.handle	= pMga->status.handle; +   pMGADRI->status.size		= pMga->status.size; +   pMGADRI->primary.handle	= pMga->primary.handle; +   pMGADRI->primary.size	= pMga->primary.size; +   pMGADRI->buffers.handle	= pMga->buffers.handle; +   pMGADRI->buffers.size	= pMga->buffers.size; +   pMGADRI->sarea_priv_offset = sizeof(XF86DRISAREARec); + +   print_client_msg( pMGADRI ); + +   return 1; +} + + +/** + * \brief Establish the set of modes available for the display. + * + * \param ctx display handle. + * \param numModes will receive the number of supported modes. + * \param modes will point to the list of supported modes. + * + * \return one on success, or zero on failure. + *  + * Allocates a single visual and fills it with information according to the + * display bit depth. Supports only 16 and 32 bpp bit depths, aborting + * otherwise. + */ +const __GLcontextModes __glModes[] = { +     +    /* 32 bit, RGBA Depth=24 Stencil=8 */ +    {.rgbMode = GL_TRUE, .colorIndexMode = GL_FALSE, .doubleBufferMode = GL_TRUE, .stereoMode = GL_FALSE, +     .haveAccumBuffer = GL_FALSE, .haveDepthBuffer = GL_TRUE, .haveStencilBuffer = GL_TRUE, +     .redBits = 8, .greenBits = 8, .blueBits = 8, .alphaBits = 8, +     .redMask = 0xff0000, .greenMask = 0xff00, .blueMask = 0xff, .alphaMask = 0xff000000, +     .rgbBits = 32, .indexBits = 0, +     .accumRedBits = 0, .accumGreenBits = 0, .accumBlueBits = 0, .accumAlphaBits = 0, +     .depthBits = 24, .stencilBits = 8, +     .numAuxBuffers= 0, .level = 0, .pixmapMode = GL_FALSE, }, + +    /* 16 bit, RGB Depth=16 */ +    {.rgbMode = GL_TRUE, .colorIndexMode = GL_FALSE, .doubleBufferMode = GL_TRUE, .stereoMode = GL_FALSE, +     .haveAccumBuffer = GL_FALSE, .haveDepthBuffer = GL_TRUE, .haveStencilBuffer = GL_FALSE, +     .redBits = 5, .greenBits = 6, .blueBits = 5, .alphaBits = 0, +     .redMask = 0xf800, .greenMask = 0x07e0, .blueMask = 0x001f, .alphaMask = 0x0, +     .rgbBits = 16, .indexBits = 0, +     .accumRedBits = 0, .accumGreenBits = 0, .accumBlueBits = 0, .accumAlphaBits = 0, +     .depthBits = 16, .stencilBits = 0, +     .numAuxBuffers= 0, .level = 0, .pixmapMode = GL_FALSE, }, +}; +static int mgaInitContextModes( const DRIDriverContext *ctx, +				   int *numModes, const __GLcontextModes **modes) +{ +   *numModes = sizeof(__glModes)/sizeof(__GLcontextModes *); +   *modes = &__glModes[0]; +   return 1; +} + + +/** + * \brief Validate the fbdev mode. + *  + * \param ctx display handle. + * + * \return one on success, or zero on failure. + * + * Saves some registers and returns 1. + * + * \sa mgaValidateMode(). + */ +static int mgaValidateMode( const DRIDriverContext *ctx ) +{ +   return 1; +} + + +/** + * \brief Examine mode returned by fbdev. + *  + * \param ctx display handle. + * + * \return one on success, or zero on failure. + * + * Restores registers that fbdev has clobbered and returns 1. + * + * \sa mgaValidateMode(). + */ +static int mgaPostValidateMode( const DRIDriverContext *ctx ) +{ +   return 1; +} + + +/** + * \brief Initialize the framebuffer device mode + * + * \param ctx display handle. + * + * \return one on success, or zero on failure. + * + * Fills in \p info with some default values and some information from \p ctx + * and then calls MGAScreenInit() for the screen initialization. + *  + * Before exiting clears the framebuffer memomry accessing it directly. + */ +static int mgaInitFBDev( struct DRIDriverContextRec *ctx ) +{ +   MGAPtr pMga = calloc(1, sizeof(*pMga)); + +   { +      int  dummy = ctx->shared.virtualWidth; + +      switch (ctx->bpp / 8) { +      case 1: dummy = (ctx->shared.virtualWidth + 127) & ~127; break; +      case 2: dummy = (ctx->shared.virtualWidth +  31) &  ~31; break; +      case 3: +      case 4: dummy = (ctx->shared.virtualWidth +  15) &  ~15; break; +      } + +      ctx->shared.virtualWidth = dummy; +   } + +   ctx->driverPrivate = (void *)pMga; +    +   pMga->agpMode       = MGA_DEFAULT_AGP_MODE; +   pMga->agpSize       = MGA_DEFAULT_AGP_SIZE; +   +   pMga->Chipset = ctx->chipset; + +   pMga->IOAddress = ctx->MMIOStart; +   pMga->IOBase    = ctx->MMIOAddress; + +   pMga->frontPitch = ctx->shared.virtualWidth * ctx->cpp; + +   if (!MGAScreenInit( ctx, pMga )) +      return 0; + +   return 1; +} + + +/** + * \brief The screen is being closed, so clean up any state and free any + * resources used by the DRI. + * + * \param ctx display handle. + * + * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver + * private data. + */ +static void mgaHaltFBDev( struct DRIDriverContextRec *ctx ) +{ +    drmUnmap( ctx->pSAREA, ctx->shared.SAREASize ); +    drmClose(ctx->drmFD); + +    if (ctx->driverPrivate) { +       free(ctx->driverPrivate); +       ctx->driverPrivate = NULL; +    } +} + + +static int mgaEngineShutdown( const DRIDriverContext *ctx ) +{ +   fprintf(stderr, "%s() is not yet implemented!\n", __FUNCTION__); + +   return 1; +} + +static int mgaEngineRestore( const DRIDriverContext *ctx ) +{ +   fprintf(stderr, "%s() is not yet implemented!\n", __FUNCTION__); + +   return 1; +} + +/** + * \brief Exported driver interface for Mini GLX. + * + * \sa DRIDriverRec. + */ +struct DRIDriverRec __driDriver = { +   mgaInitContextModes, +   mgaValidateMode, +   mgaPostValidateMode, +   mgaInitFBDev, +   mgaHaltFBDev, +   mgaEngineShutdown, +   mgaEngineRestore, +   0 +}; + + + + +#if 0 +void MGADRICloseScreen( ScreenPtr pScreen ) +{ +   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; +   MGAPtr pMga = MGAPTR(pScrn); +   MGADRIServerPrivatePtr pMga = pMga->DRIServerInfo; +   drmMGAInit init; + +   if ( pMga->drmBuffers ) { +      drmUnmapBufs( pMga->drmBuffers ); +      pMga->drmBuffers = NULL; +   } + +   if (pMga->irq) { +      drmCtlUninstHandler(ctx->drmFD); +      pMga->irq = 0; +   } + +   /* Cleanup DMA */ +   memset( &init, 0, sizeof(drmMGAInit) ); +   init.func = MGA_CLEANUP_DMA; +   drmCommandWrite( ctx->drmFD, DRM_MGA_INIT, &init, sizeof(drmMGAInit) ); + +   if ( pMga->status.map ) { +      drmUnmap( pMga->status.map, pMga->status.size ); +      pMga->status.map = NULL; +   } +   if ( pMga->buffers.map ) { +      drmUnmap( pMga->buffers.map, pMga->buffers.size ); +      pMga->buffers.map = NULL; +   } +   if ( pMga->primary.map ) { +      drmUnmap( pMga->primary.map, pMga->primary.size ); +      pMga->primary.map = NULL; +   } +   if ( pMga->warp.map ) { +      drmUnmap( pMga->warp.map, pMga->warp.size ); +      pMga->warp.map = NULL; +   } + +   if ( pMga->agpTextures.map ) { +      drmUnmap( pMga->agpTextures.map, pMga->agpTextures.size ); +      pMga->agpTextures.map = NULL; +   } + +   if ( pMga->agp.handle ) { +      drmAgpUnbind( ctx->drmFD, pMga->agp.handle ); +      drmAgpFree( ctx->drmFD, pMga->agp.handle ); +      pMga->agp.handle = 0; +      drmAgpRelease( ctx->drmFD ); +   } + +   DRICloseScreen( pScreen ); + +   if ( pMga->pDRIInfo ) { +      if ( pMga->pDRIpMga->devPrivate ) { +	 xfree( pMga->pDRIpMga->devPrivate ); +	 pMga->pDRIpMga->devPrivate = 0; +      } +      DRIDestroyInfoRec( pMga->pDRIInfo ); +      pMga->pDRIInfo = 0; +   } +   if ( pMga->DRIServerInfo ) { +      xfree( pMga->DRIServerInfo ); +      pMga->DRIServerInfo = 0; +   } +   if ( pMga->pVisualConfigs ) { +      xfree( pMga->pVisualConfigs ); +   } +   if ( pMga->pVisualConfigsPriv ) { +      xfree( pMga->pVisualConfigsPriv ); +   } +} +#endif diff --git a/src/mesa/drivers/dri/mga/server/mga_dri.h b/src/mesa/drivers/dri/mga/server/mga_dri.h new file mode 100644 index 0000000000..c6a3e23f41 --- /dev/null +++ b/src/mesa/drivers/dri/mga/server/mga_dri.h @@ -0,0 +1,84 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h,v 1.8 2002/11/29 11:06:42 eich Exp $ */ + +/* + * Copyright 2000 VA Linux Systems Inc., Fremont, California. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL + * VA LINUX SYSTEMS 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> + *   Gareth Hughes <gareth@valinux.com> + */ + +#ifndef __MGA_DRI_H__ +#define __MGA_DRI_H__ + +#include "xf86drm.h" +#include "mga_common.h" + +#define MGA_DEFAULT_AGP_SIZE     64 +#define MGA_DEFAULT_AGP_MODE     4 +#define MGA_MAX_AGP_MODE         4 + +/* Buffer are aligned on 4096 byte boundaries. + */ +#define MGA_BUFFER_ALIGN	0x00000fff + +typedef struct { +   int chipset; +   int width; +   int height; +   int mem; +   int cpp; + +   int agpMode; + +   int frontOffset; +   int frontPitch; + +   int backOffset; +   int backPitch; + +   int depthOffset; +   int depthPitch; + +   int textureOffset; +   int textureSize; +   int logTextureGranularity; + +   /* Allow calculation of setup dma addresses. +    */ +   unsigned int agpBufferOffset; + +   unsigned int agpTextureOffset; +   unsigned int agpTextureSize; +   int logAgpTextureGranularity; + +   unsigned int mAccess; + +   drmRegion registers; +   drmRegion status; +   drmRegion primary; +   drmRegion buffers; +   unsigned int sarea_priv_offset; +} MGADRIRec, *MGADRIPtr; + +#endif diff --git a/src/mesa/drivers/dri/mga/server/mga_macros.h b/src/mesa/drivers/dri/mga/server/mga_macros.h new file mode 100644 index 0000000000..d985081ab6 --- /dev/null +++ b/src/mesa/drivers/dri/mga/server/mga_macros.h @@ -0,0 +1,118 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_macros.h,v 1.22 2002/02/20 17:17:50 dawes Exp $ */ + +#ifndef _MGA_MACROS_H_ +#define _MGA_MACROS_H_ + +#ifndef PSZ +#define PSZ 8 +#endif + +#if PSZ == 8 +#define REPLICATE(r) r &= 0xFF; r |= r << 8; r |= r << 16 +#elif PSZ == 16 +#define REPLICATE(r) r &= 0xFFFF; r |= r << 16 +#elif PSZ == 24 +#define REPLICATE(r) r &= 0xFFFFFF; r |= r << 24 +#else +#define REPLICATE(r) /* */ +#endif + +#define RGBEQUAL(c) (!((((c) >> 8) ^ (c)) & 0xffff)) + +#ifdef XF86DRI +#define MGA_SYNC_XTAG                 0x275f4200 + +#define MGABUSYWAIT() do { \ +OUTREG(MGAREG_DWGSYNC, MGA_SYNC_XTAG); \ +while(INREG(MGAREG_DWGSYNC) != MGA_SYNC_XTAG) ; \ +}while(0); + +#endif + +#define MGAISBUSY() (INREG8(MGAREG_Status + 2) & 0x01) + +#define WAITFIFO(cnt) \ +   if(!pMga->UsePCIRetry) {\ +	register int n = cnt; \ +	if(n > pMga->FifoSize) n = pMga->FifoSize; \ +	while(pMga->fifoCount < (n))\ +	    pMga->fifoCount = INREG8(MGAREG_FIFOSTATUS);\ +	pMga->fifoCount -= n;\ +   } + +#define XYADDRESS(x,y) \ +    ((y) * pMga->CurrentLayout.displayWidth + (x) + pMga->YDstOrg) + +#define MAKEDMAINDEX(index)  ((((index) >> 2) & 0x7f) | (((index) >> 6) & 0x80)) + +#define DMAINDICES(one,two,three,four)	\ +	( MAKEDMAINDEX(one) | \ +	 (MAKEDMAINDEX(two) << 8) | \ +	 (MAKEDMAINDEX(three) << 16) | \ + 	 (MAKEDMAINDEX(four) << 24) ) + +#if PSZ == 24 +#define SET_PLANEMASK(p) /**/ +#else +#define SET_PLANEMASK(p) \ +	if(!(pMga->AccelFlags & MGA_NO_PLANEMASK) && ((p) != pMga->PlaneMask)) { \ +	   pMga->PlaneMask = (p); \ +	   REPLICATE((p)); \ +	   OUTREG(MGAREG_PLNWT,(p)); \ +	} +#endif + +#define SET_FOREGROUND(c) \ +	if((c) != pMga->FgColor) { \ +	   pMga->FgColor = (c); \ +	   REPLICATE((c)); \ +	   OUTREG(MGAREG_FCOL,(c)); \ +	} + +#define SET_BACKGROUND(c) \ +	if((c) != pMga->BgColor) { \ +	   pMga->BgColor = (c); \ +	   REPLICATE((c)); \ +	   OUTREG(MGAREG_BCOL,(c)); \ +	} + +#define DISABLE_CLIP() { \ +	pMga->AccelFlags &= ~CLIPPER_ON; \ +	WAITFIFO(1); \ +	OUTREG(MGAREG_CXBNDRY, 0xFFFF0000); } + +#ifdef XF86DRI +#define CHECK_DMA_QUIESCENT(pMGA, pScrn) {	\ +   if (!pMGA->haveQuiescense) {			\ +      pMGA->GetQuiescence( pScrn );		\ +   }						\ +} +#else +#define CHECK_DMA_QUIESCENT(pMGA, pScrn) +#endif + +#ifdef USEMGAHAL +#define HAL_CHIPSETS ((pMga->Chipset == PCI_CHIP_MGAG200_PCI) || \ +		  (pMga->Chipset == PCI_CHIP_MGAG200) || \ +		  (pMga->Chipset == PCI_CHIP_MGAG400) || \ +		  (pMga->Chipset == PCI_CHIP_MGAG550)) +     +#define MGA_HAL(x) { \ +	MGAPtr pMga = MGAPTR(pScrn); \ +	if (pMga->HALLoaded && HAL_CHIPSETS) { x; } \ +} +#define MGA_NOT_HAL(x) { \ +	MGAPtr pMga = MGAPTR(pScrn); \ +	if (!pMga->HALLoaded || !HAL_CHIPSETS) { x; } \ +} +#else +#define MGA_NOT_HAL(x) { x; } +#endif + +#define MGAISGx50(x) ( (((x)->Chipset == PCI_CHIP_MGAG400) && ((x)->ChipRev >= 0x80)) || \ +		       ((x)->Chipset == PCI_CHIP_MGAG550) ) + +#define MGA_DH_NEEDS_HAL(x) (((x)->Chipset == PCI_CHIP_MGAG400) && \ +			     ((x)->ChipRev < 0x80)) + +#endif /* _MGA_MACROS_H_ */ diff --git a/src/mesa/drivers/dri/mga/server/mga_reg.h b/src/mesa/drivers/dri/mga/server/mga_reg.h new file mode 100644 index 0000000000..b8e3499235 --- /dev/null +++ b/src/mesa/drivers/dri/mga/server/mga_reg.h @@ -0,0 +1,484 @@ +/* $XConsortium: mgareg.h /main/2 1996/10/25 10:33:21 kaleb $ */ + + + +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_reg.h,v 1.18 2001/09/26 12:59:18 alanh Exp $ */ + + + +/* + * MGA Millennium (MGA2064W) functions + * MGA Mystique (MGA1064SG) functions + * + * Copyright 1996 The XFree86 Project, Inc. + * + * Authors + *		Dirk Hohndel + *			hohndel@XFree86.Org + *		David Dawes + *			dawes@XFree86.Org + * Contributors: + *		Guy DESBIEF, Aix-en-provence, France + *			g.desbief@aix.pacwan.net + *		MGA1064SG Mystique register file + */ + + +#ifndef _MGA_REG_H_ +#define _MGA_REG_H_ + +#define	MGAREG_DWGCTL		0x1c00 +#define	MGAREG_MACCESS		0x1c04 +#define	MGA_MACCESS_PW16        0x00000001 +#define	MGA_MACCESS_PW32        0x00000002 +/* the following is a mystique only register */ +#define MGAREG_MCTLWTST		0x1c08 +#define	MGAREG_ZORG		0x1c0c + +#define	MGAREG_PAT0		0x1c10 +#define	MGAREG_PAT1		0x1c14 +#define	MGAREG_PLNWT		0x1c1c + +#define	MGAREG_BCOL		0x1c20 +#define	MGAREG_FCOL		0x1c24 + +#define	MGAREG_SRC0		0x1c30 +#define	MGAREG_SRC1		0x1c34 +#define	MGAREG_SRC2		0x1c38 +#define	MGAREG_SRC3		0x1c3c + +#define	MGAREG_XYSTRT		0x1c40 +#define	MGAREG_XYEND		0x1c44 + +#define	MGAREG_SHIFT		0x1c50 +/* the following is a mystique only register */ +#define MGAREG_DMAPAD		0x1c54 +#define	MGAREG_SGN		0x1c58 +#define	MGAREG_LEN		0x1c5c + +#define	MGAREG_AR0		0x1c60 +#define	MGAREG_AR1		0x1c64 +#define	MGAREG_AR2		0x1c68 +#define	MGAREG_AR3		0x1c6c +#define	MGAREG_AR4		0x1c70 +#define	MGAREG_AR5		0x1c74 +#define	MGAREG_AR6		0x1c78 + +#define	MGAREG_CXBNDRY		0x1c80 +#define	MGAREG_FXBNDRY		0x1c84 +#define	MGAREG_YDSTLEN		0x1c88 +#define	MGAREG_PITCH		0x1c8c + +#define	MGAREG_YDST		0x1c90 +#define	MGAREG_YDSTORG		0x1c94 +#define	MGAREG_YTOP		0x1c98 +#define	MGAREG_YBOT		0x1c9c + +#define	MGAREG_CXLEFT		0x1ca0 +#define	MGAREG_CXRIGHT		0x1ca4 +#define	MGAREG_FXLEFT		0x1ca8 +#define	MGAREG_FXRIGHT		0x1cac + +#define	MGAREG_XDST		0x1cb0 + +#define	MGAREG_DR0		0x1cc0 +#define	MGAREG_DR1		0x1cc4 +#define	MGAREG_DR2		0x1cc8 +#define	MGAREG_DR3		0x1ccc + +#define	MGAREG_DR4		0x1cd0 +#define	MGAREG_DR5		0x1cd4 +#define	MGAREG_DR6		0x1cd8 +#define	MGAREG_DR7		0x1cdc + +#define	MGAREG_DR8		0x1ce0 +#define	MGAREG_DR9		0x1ce4 +#define	MGAREG_DR10		0x1ce8 +#define	MGAREG_DR11		0x1cec + +#define	MGAREG_DR12		0x1cf0 +#define	MGAREG_DR13		0x1cf4 +#define	MGAREG_DR14		0x1cf8 +#define	MGAREG_DR15		0x1cfc + +#define MGAREG_SRCORG		0x2cb4 +#define MGAREG_DSTORG		0x2cb8 + +/* add or or this to one of the previous "power registers" to start +   the drawing engine */ + +#define MGAREG_EXEC		0x0100 + +#define	MGAREG_FIFOSTATUS	0x1e10 +#define	MGAREG_Status		0x1e14 +#define	MGAREG_ICLEAR		0x1e18 +#define	MGAREG_IEN		0x1e1c + +#define	MGAREG_VCOUNT		0x1e20 + +#define	MGAREG_Reset		0x1e40 + +#define	MGAREG_OPMODE		0x1e54 + +/* Warp Registers */ +#define MGAREG_WIADDR           0x1dc0 +#define MGAREG_WIADDR2          0x1dd8 +#define MGAREG_WGETMSB          0x1dc8 +#define MGAREG_WVRTXSZ          0x1dcc +#define MGAREG_WACCEPTSEQ       0x1dd4 +#define MGAREG_WMISC            0x1e70 + +/* OPMODE register additives */ + +#define MGAOPM_DMA_GENERAL	(0x00 << 2) +#define MGAOPM_DMA_BLIT		(0x01 << 2) +#define MGAOPM_DMA_VECTOR	(0x10 << 2) + +/* DWGCTL register additives */ + +/* Lines */ + +#define MGADWG_LINE_OPEN	0x00 +#define MGADWG_AUTOLINE_OPEN	0x01 +#define MGADWG_LINE_CLOSE	0x02 +#define MGADWG_AUTOLINE_CLOSE	0x03 + +/* Trapezoids */ +#define MGADWG_TRAP		0x04 +#define MGADWG_TEXTURE_TRAP	0x05 + +/* BitBlts */ + +#define MGADWG_BITBLT		0x08 +#define MGADWG_FBITBLT		0x0c +#define MGADWG_ILOAD		0x09 +#define MGADWG_ILOAD_SCALE	0x0d +#define MGADWG_ILOAD_FILTER	0x0f +#define MGADWG_ILOAD_HIQH	0x07 +#define MGADWG_ILOAD_HIQHV	0x0e +#define MGADWG_IDUMP		0x0a + +/* atype access to WRAM */ + +#define MGADWG_RPL		( 0x00 << 4 ) +#define MGADWG_RSTR		( 0x01 << 4 ) +#define MGADWG_ZI		( 0x03 << 4 ) +#define MGADWG_BLK 		( 0x04 << 4 ) +#define MGADWG_I		( 0x07 << 4 ) + +/* specifies whether bit blits are linear or xy */ +#define MGADWG_LINEAR		( 0x01 << 7 ) + +/* z drawing mode. use MGADWG_NOZCMP for always */ + +#define MGADWG_NOZCMP		( 0x00 << 8 ) +#define MGADWG_ZE		( 0x02 << 8 ) +#define MGADWG_ZNE		( 0x03 << 8 ) +#define MGADWG_ZLT		( 0x04 << 8 ) +#define MGADWG_ZLTE		( 0x05 << 8 ) +#define MGADWG_GT		( 0x06 << 8 ) +#define MGADWG_GTE		( 0x07 << 8 ) + +/* use this to force colour expansion circuitry to do its stuff */ + +#define MGADWG_SOLID		( 0x01 << 11 ) + +/* ar register at zero */ + +#define MGADWG_ARZERO		( 0x01 << 12 ) + +#define MGADWG_SGNZERO		( 0x01 << 13 ) + +#define MGADWG_SHIFTZERO	( 0x01 << 14 ) + +/* See table on 4-43 for bop ALU operations */ + +/* See table on 4-44 for translucidity masks */ + +#define MGADWG_BMONOLEF		( 0x00 << 25 ) +#define MGADWG_BMONOWF		( 0x04 << 25 ) +#define MGADWG_BPLAN		( 0x01 << 25 ) + +/* note that if bfcol is specified and you're doing a bitblt, it causes +   a fbitblt to be performed, so check that you obey the fbitblt rules */ + +#define MGADWG_BFCOL   		( 0x02 << 25 ) +#define MGADWG_BUYUV		( 0x0e << 25 ) +#define MGADWG_BU32BGR		( 0x03 << 25 ) +#define MGADWG_BU32RGB		( 0x07 << 25 ) +#define MGADWG_BU24BGR		( 0x0b << 25 ) +#define MGADWG_BU24RGB		( 0x0f << 25 ) + +#define MGADWG_PATTERN		( 0x01 << 29 ) +#define MGADWG_TRANSC		( 0x01 << 30 ) +#define MGAREG_MISC_WRITE	0x3c2 +#define MGAREG_MISC_READ	0x3cc +#define MGAREG_MISC_IOADSEL	(0x1 << 0) +#define MGAREG_MISC_RAMMAPEN	(0x1 << 1) +#define MGAREG_MISC_CLK_SEL_VGA25	(0x0 << 2) +#define MGAREG_MISC_CLK_SEL_VGA28	(0x1 << 2) +#define MGAREG_MISC_CLK_SEL_MGA_PIX	(0x2 << 2) +#define MGAREG_MISC_CLK_SEL_MGA_MSK	(0x3 << 2) +#define MGAREG_MISC_VIDEO_DIS	(0x1 << 4) +#define MGAREG_MISC_HIGH_PG_SEL	(0x1 << 5) + +/* MMIO VGA registers */ +#define MGAREG_SEQ_INDEX	0x1fc4 +#define MGAREG_SEQ_DATA		0x1fc5 +#define MGAREG_CRTC_INDEX	0x1fd4 +#define MGAREG_CRTC_DATA	0x1fd5 +#define MGAREG_CRTCEXT_INDEX	0x1fde +#define MGAREG_CRTCEXT_DATA	0x1fdf + + + +/* MGA bits for registers PCI_OPTION_REG */ +#define MGA1064_OPT_SYS_CLK_PCI   		( 0x00 << 0 ) +#define MGA1064_OPT_SYS_CLK_PLL   		( 0x01 << 0 ) +#define MGA1064_OPT_SYS_CLK_EXT   		( 0x02 << 0 ) +#define MGA1064_OPT_SYS_CLK_MSK   		( 0x03 << 0 ) + +#define MGA1064_OPT_SYS_CLK_DIS   		( 0x01 << 2 ) +#define MGA1064_OPT_G_CLK_DIV_1   		( 0x01 << 3 ) +#define MGA1064_OPT_M_CLK_DIV_1   		( 0x01 << 4 ) + +#define MGA1064_OPT_SYS_PLL_PDN   		( 0x01 << 5 ) +#define MGA1064_OPT_VGA_ION   		( 0x01 << 8 ) + +/* MGA registers in PCI config space */ +#define PCI_MGA_INDEX		0x44 +#define PCI_MGA_DATA		0x48 +#define PCI_MGA_OPTION2		0x50 +#define PCI_MGA_OPTION3		0x54 + +#define RAMDAC_OFFSET		0x3c00 + +/* TVP3026 direct registers */ + +#define TVP3026_INDEX		0x00 +#define TVP3026_WADR_PAL	0x00 +#define TVP3026_COL_PAL		0x01 +#define TVP3026_PIX_RD_MSK	0x02 +#define TVP3026_RADR_PAL	0x03 +#define TVP3026_CUR_COL_ADDR	0x04 +#define TVP3026_CUR_COL_DATA	0x05 +#define TVP3026_DATA		0x0a +#define TVP3026_CUR_RAM		0x0b +#define TVP3026_CUR_XLOW	0x0c +#define TVP3026_CUR_XHI		0x0d +#define TVP3026_CUR_YLOW	0x0e +#define TVP3026_CUR_YHI		0x0f + +/* TVP3026 indirect registers */ + +#define TVP3026_SILICON_REV	0x01 +#define TVP3026_CURSOR_CTL	0x06 +#define TVP3026_LATCH_CTL	0x0f +#define TVP3026_TRUE_COLOR_CTL	0x18 +#define TVP3026_MUX_CTL		0x19 +#define TVP3026_CLK_SEL		0x1a +#define TVP3026_PAL_PAGE	0x1c +#define TVP3026_GEN_CTL		0x1d +#define TVP3026_MISC_CTL	0x1e +#define TVP3026_GEN_IO_CTL	0x2a +#define TVP3026_GEN_IO_DATA	0x2b +#define TVP3026_PLL_ADDR	0x2c +#define TVP3026_PIX_CLK_DATA	0x2d +#define TVP3026_MEM_CLK_DATA	0x2e +#define TVP3026_LOAD_CLK_DATA	0x2f +#define TVP3026_KEY_RED_LOW	0x32 +#define TVP3026_KEY_RED_HI	0x33 +#define TVP3026_KEY_GREEN_LOW	0x34 +#define TVP3026_KEY_GREEN_HI	0x35 +#define TVP3026_KEY_BLUE_LOW	0x36 +#define TVP3026_KEY_BLUE_HI	0x37 +#define TVP3026_KEY_CTL		0x38 +#define TVP3026_MCLK_CTL	0x39 +#define TVP3026_SENSE_TEST	0x3a +#define TVP3026_TEST_DATA	0x3b +#define TVP3026_CRC_LSB		0x3c +#define TVP3026_CRC_MSB		0x3d +#define TVP3026_CRC_CTL		0x3e +#define TVP3026_ID		0x3f +#define TVP3026_RESET		0xff + + +/* MGA1064 DAC Register file */ +/* MGA1064 direct registers */ + +#define MGA1064_INDEX		0x00 +#define MGA1064_WADR_PAL	0x00 +#define MGA1064_COL_PAL		0x01 +#define MGA1064_PIX_RD_MSK	0x02 +#define MGA1064_RADR_PAL	0x03 +#define MGA1064_DATA		0x0a + +#define MGA1064_CUR_XLOW	0x0c +#define MGA1064_CUR_XHI		0x0d +#define MGA1064_CUR_YLOW	0x0e +#define MGA1064_CUR_YHI		0x0f + +/* MGA1064 indirect registers */ +#define MGA1064_DVI_PIPE_CTL    0x03 +#define MGA1064_CURSOR_BASE_ADR_LOW	0x04 +#define MGA1064_CURSOR_BASE_ADR_HI	0x05 +#define MGA1064_CURSOR_CTL	0x06 +#define MGA1064_CURSOR_COL0_RED	0x08 +#define MGA1064_CURSOR_COL0_GREEN	0x09 +#define MGA1064_CURSOR_COL0_BLUE	0x0a + +#define MGA1064_CURSOR_COL1_RED	0x0c +#define MGA1064_CURSOR_COL1_GREEN	0x0d +#define MGA1064_CURSOR_COL1_BLUE	0x0e + +#define MGA1064_CURSOR_COL2_RED	0x010 +#define MGA1064_CURSOR_COL2_GREEN	0x011 +#define MGA1064_CURSOR_COL2_BLUE	0x012 + +#define MGA1064_VREF_CTL	0x018 + +#define MGA1064_MUL_CTL		0x19 +#define MGA1064_MUL_CTL_8bits		0x0 +#define MGA1064_MUL_CTL_15bits		0x01 +#define MGA1064_MUL_CTL_16bits		0x02 +#define MGA1064_MUL_CTL_24bits		0x03 +#define MGA1064_MUL_CTL_32bits		0x04 +#define MGA1064_MUL_CTL_2G8V16bits		0x05 +#define MGA1064_MUL_CTL_G16V16bits		0x06 +#define MGA1064_MUL_CTL_32_24bits		0x07 + +#define MGAGDAC_XVREFCTRL		0x18 +#define MGA1064_PIX_CLK_CTL		0x1a +#define MGA1064_PIX_CLK_CTL_CLK_DIS   		( 0x01 << 2 ) +#define MGA1064_PIX_CLK_CTL_CLK_POW_DOWN   	( 0x01 << 3 ) +#define MGA1064_PIX_CLK_CTL_SEL_PCI   		( 0x00 << 0 ) +#define MGA1064_PIX_CLK_CTL_SEL_PLL   		( 0x01 << 0 ) +#define MGA1064_PIX_CLK_CTL_SEL_EXT   		( 0x02 << 0 ) +#define MGA1064_PIX_CLK_CTL_SEL_MSK   		( 0x03 << 0 ) + +#define MGA1064_GEN_CTL		0x1d +#define MGA1064_MISC_CTL	0x1e +#define MGA1064_MISC_CTL_DAC_POW_DN   		( 0x01 << 0 ) +#define MGA1064_MISC_CTL_VGA   		( 0x01 << 1 ) +#define MGA1064_MISC_CTL_DIS_CON   		( 0x03 << 1 ) +#define MGA1064_MISC_CTL_MAFC   		( 0x02 << 1 ) +#define MGA1064_MISC_CTL_VGA8   		( 0x01 << 3 ) +#define MGA1064_MISC_CTL_DAC_RAM_CS   		( 0x01 << 4 ) + +#define MGA1064_GEN_IO_CTL	0x2a +#define MGA1064_GEN_IO_DATA	0x2b +#define MGA1064_SYS_PLL_M	0x2c +#define MGA1064_SYS_PLL_N	0x2d +#define MGA1064_SYS_PLL_P	0x2e +#define MGA1064_SYS_PLL_STAT	0x2f +#define MGA1064_ZOOM_CTL	0x38 +#define MGA1064_SENSE_TST	0x3a + +#define MGA1064_CRC_LSB		0x3c +#define MGA1064_CRC_MSB		0x3d +#define MGA1064_CRC_CTL		0x3e +#define MGA1064_COL_KEY_MSK_LSB		0x40 +#define MGA1064_COL_KEY_MSK_MSB		0x41 +#define MGA1064_COL_KEY_LSB		0x42 +#define MGA1064_COL_KEY_MSB		0x43 +#define MGA1064_PIX_PLLA_M	0x44 +#define MGA1064_PIX_PLLA_N	0x45 +#define MGA1064_PIX_PLLA_P	0x46 +#define MGA1064_PIX_PLLB_M	0x48 +#define MGA1064_PIX_PLLB_N	0x49 +#define MGA1064_PIX_PLLB_P	0x4a +#define MGA1064_PIX_PLLC_M	0x4c +#define MGA1064_PIX_PLLC_N	0x4d +#define MGA1064_PIX_PLLC_P	0x4e + +#define MGA1064_PIX_PLL_STAT	0x4f + +/*Added for G450 dual head*/ +/* Supported PLL*/ +#define __PIXEL_PLL                 1 +#define __SYSTEM_PLL                2 +#define __VIDEO_PLL                 3 + +#define MGA1064_VID_PLL_P       0x8D +#define MGA1064_VID_PLL_M       0x8E +#define MGA1064_VID_PLL_N       0x8F + +#define MGA1064_DISP_CTL        0x8a +#define MGA1064_SYNC_CTL        0x8b +#define MGA1064_PWR_CTL         0xa0 +#define MGA1064_PAN_CTL         0xa2 + +/* Using crtc2 */ +#define MGAREG2_C2CTL            0x10 +#define MGAREG2_C2HPARAM         0x14 +#define MGAREG2_C2HSYNC          0x18 +#define MGAREG2_C2VPARAM         0x1c +#define MGAREG2_C2VSYNC          0x20 +#define MGAREG2_C2STARTADD0      0x28 + +#define MGAREG2_C2OFFSET         0x40 +#define MGAREG2_C2DATACTL        0x4c + +#define MGAREG_C2CTL            0x3c10 +#define MGAREG_C2HPARAM         0x3c14 +#define MGAREG_C2HSYNC          0x3c18 +#define MGAREG_C2VPARAM         0x3c1c +#define MGAREG_C2VSYNC          0x3c20 +#define MGAREG_C2STARTADD0      0x3c28 + +#define MGAREG_C2OFFSET         0x3c40 +#define MGAREG_C2DATACTL        0x3c4c + +#define MGA1064_DISP_CTL        0x8a +#define MGA1064_SYNC_CTL        0x8b +#define MGA1064_PWR_CTL         0xa0 + +/* video register */ + +#define MGAREG_BESA1C3ORG	0x3d60 +#define MGAREG_BESA1CORG	0x3d10 +#define MGAREG_BESA1ORG		0x3d00 +#define MGAREG_BESCTL		0x3d20 +#define MGAREG_BESGLOBCTL	0x3dc0 +#define MGAREG_BESHCOORD	0x3d28 +#define MGAREG_BESHISCAL	0x3d30 +#define MGAREG_BESHSRCEND	0x3d3c +#define MGAREG_BESHSRCLST	0x3d50 +#define MGAREG_BESHSRCST	0x3d38 +#define MGAREG_BESLUMACTL	0x3d40 +#define MGAREG_BESPITCH		0x3d24 +#define MGAREG_BESV1SRCLST	0x3d54 +#define MGAREG_BESV1WGHT	0x3d48 +#define MGAREG_BESVCOORD	0x3d2c +#define MGAREG_BESVISCAL	0x3d34 + +/* texture engine registers */ + +#define MGAREG_TMR0		0x2c00 +#define MGAREG_TMR1		0x2c04 +#define MGAREG_TMR2		0x2c08 +#define MGAREG_TMR3		0x2c0c +#define MGAREG_TMR4		0x2c10 +#define MGAREG_TMR5		0x2c14 +#define MGAREG_TMR6		0x2c18 +#define MGAREG_TMR7		0x2c1c +#define MGAREG_TMR8		0x2c20 +#define MGAREG_TEXORG		0x2c24 +#define MGAREG_TEXWIDTH		0x2c28 +#define MGAREG_TEXHEIGHT	0x2c2c +#define MGAREG_TEXCTL		0x2c30 +#define MGAREG_TEXCTL2		0x2c3c +#define MGAREG_TEXTRANS		0x2c34 +#define MGAREG_TEXTRANSHIGH	0x2c38 +#define MGAREG_TEXFILTER	0x2c58 +#define MGAREG_ALPHASTART	0x2c70 +#define MGAREG_ALPHAXINC	0x2c74 +#define MGAREG_ALPHAYINC	0x2c78 +#define MGAREG_ALPHACTRL	0x2c7c +#define MGAREG_DWGSYNC		0x2c4c + +#define MGAREG_AGP_PLL		0x1e4c +#define MGA_AGP2XPLL_ENABLE		0x1 +#define MGA_AGP2XPLL_DISABLE		0x0 + +#endif diff --git a/src/mesa/drivers/dri/mga/server/mga_sarea.h b/src/mesa/drivers/dri/mga/server/mga_sarea.h new file mode 100644 index 0000000000..8bfa3f51d5 --- /dev/null +++ b/src/mesa/drivers/dri/mga/server/mga_sarea.h @@ -0,0 +1,222 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_sarea.h,v 1.1 2001/03/21 17:11:47 dawes Exp $ */ + +/* + * Copyright 2000 Gareth Hughes + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL + * GARETH HUGHES BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + *   Gareth Hughes <gareth@valinux.com> + */ + +#ifndef __MGA_SAREA_H__ +#define __MGA_SAREA_H__ + +/* WARNING: If you change any of these defines, make sure to change + * the kernel include file as well (mga_drm.h) + */ +#ifndef __MGA_SAREA_DEFINES__ +#define __MGA_SAREA_DEFINES__ + +/* WARP pipe flags + */ +#define MGA_F			0x1		/* fog */ +#define MGA_A			0x2		/* alpha */ +#define MGA_S			0x4		/* specular */ +#define MGA_T2			0x8		/* multitexture */ + +#define MGA_WARP_TGZ		0 +#define MGA_WARP_TGZF		(MGA_F) +#define MGA_WARP_TGZA		(MGA_A) +#define MGA_WARP_TGZAF		(MGA_F|MGA_A) +#define MGA_WARP_TGZS		(MGA_S) +#define MGA_WARP_TGZSF		(MGA_S|MGA_F) +#define MGA_WARP_TGZSA		(MGA_S|MGA_A) +#define MGA_WARP_TGZSAF		(MGA_S|MGA_F|MGA_A) +#define MGA_WARP_T2GZ		(MGA_T2) +#define MGA_WARP_T2GZF		(MGA_T2|MGA_F) +#define MGA_WARP_T2GZA		(MGA_T2|MGA_A) +#define MGA_WARP_T2GZAF		(MGA_T2|MGA_A|MGA_F) +#define MGA_WARP_T2GZS		(MGA_T2|MGA_S) +#define MGA_WARP_T2GZSF		(MGA_T2|MGA_S|MGA_F) +#define MGA_WARP_T2GZSA		(MGA_T2|MGA_S|MGA_A) +#define MGA_WARP_T2GZSAF	(MGA_T2|MGA_S|MGA_F|MGA_A) + +#define MGA_MAX_G200_PIPES	8		/* no multitex */ +#define MGA_MAX_G400_PIPES	16 +#define MGA_MAX_WARP_PIPES	MGA_MAX_G400_PIPES +#define MGA_WARP_UCODE_SIZE	32768		/* in bytes */ + +#define MGA_CARD_TYPE_G200	1 +#define MGA_CARD_TYPE_G400	2 + + +#define MGA_FRONT		0x1 +#define MGA_BACK		0x2 +#define MGA_DEPTH		0x4 + +/* What needs to be changed for the current vertex dma buffer? + */ +#define MGA_UPLOAD_CONTEXT	0x1 +#define MGA_UPLOAD_TEX0		0x2 +#define MGA_UPLOAD_TEX1		0x4 +#define MGA_UPLOAD_PIPE		0x8 +#define MGA_UPLOAD_TEX0IMAGE	0x10 +#define MGA_UPLOAD_TEX1IMAGE	0x20 +#define MGA_UPLOAD_2D		0x40 +#define MGA_WAIT_AGE		0x80 /* handled client-side */ +#define MGA_UPLOAD_CLIPRECTS	0x100 /* handled client-side */ +#if 0 +#define MGA_DMA_FLUSH		0x200 /* set when someone gets the lock +					 quiescent */ +#endif + +/* 32 buffers of 64k each, total 1 meg. + */ +#define MGA_BUFFER_SIZE		(1 << 16) +#define MGA_NUM_BUFFERS		128 + +/* Keep these small for testing. + */ +#define MGA_NR_SAREA_CLIPRECTS	8 + +/* 2 heaps (1 for card, 1 for agp), each divided into upto 128 + * regions, subject to a minimum region size of (1<<16) == 64k. + * + * Clients may subdivide regions internally, but when sharing between + * clients, the region size is the minimum granularity. + */ + +#define MGA_CARD_HEAP			0 +#define MGA_AGP_HEAP			1 +#define MGA_NR_TEX_HEAPS		2 +#define MGA_NR_TEX_REGIONS		16 +#define MGA_LOG_MIN_TEX_REGION_SIZE	16 + +#endif /* __MGA_SAREA_DEFINES__ */ + + +/* Setup registers for 3D context + */ +typedef struct { +   unsigned int dstorg; +   unsigned int maccess; +   unsigned int plnwt; +   unsigned int dwgctl; +   unsigned int alphactrl; +   unsigned int fogcolor; +   unsigned int wflag; +   unsigned int tdualstage0; +   unsigned int tdualstage1; +   unsigned int fcol; +   unsigned int stencil; +   unsigned int stencilctl; +} mga_context_regs_t; + +/* Setup registers for 2D, X server + */ +typedef struct { +   unsigned int pitch; +} mga_server_regs_t; + +/* Setup registers for each texture unit + */ +typedef struct { +   unsigned int texctl; +   unsigned int texctl2; +   unsigned int texfilter; +   unsigned int texbordercol; +   unsigned int texorg; +   unsigned int texwidth; +   unsigned int texheight; +   unsigned int texorg1; +   unsigned int texorg2; +   unsigned int texorg3; +   unsigned int texorg4; +} mga_texture_regs_t; + +/* General ageing mechanism + */ +typedef struct { +	unsigned int head;		/* Position of head pointer          */ +	unsigned int wrap;		/* Primary DMA wrap count            */ +} mga_age_t; + + +/* WARNING: Do not change the SAREA structure without changing the kernel + * as well. + */ +typedef struct { +   /* The channel for communication of state information to the kernel +    * on firing a vertex dma buffer. +    */ +   mga_context_regs_t ContextState; +   mga_server_regs_t ServerState; +   mga_texture_regs_t TexState[2]; +   unsigned int WarpPipe; +   unsigned int dirty; +   unsigned int vertsize; + +   /* The current cliprects, or a subset thereof. +    */ +   XF86DRIClipRectRec boxes[MGA_NR_SAREA_CLIPRECTS]; +   unsigned int nbox; + +   /* Information about the most recently used 3d drawable.  The +    * client fills in the req_* fields, the server fills in the +    * exported_ fields and puts the cliprects into boxes, above. +    * +    * The client clears the exported_drawable field before +    * clobbering the boxes data. +    */ + +   unsigned int req_draw_buffer;    /* MGA_FRONT or MGA_BACK */ + +   unsigned int exported_drawable; +   unsigned int exported_index; +   unsigned int exported_stamp; +   unsigned int exported_buffers; +   unsigned int exported_nfront;	/* FIXME: verify signedness... */ +   unsigned int exported_nback; +   int exported_back_x, exported_front_x, exported_w; +   int exported_back_y, exported_front_y, exported_h; +   XF86DRIClipRectRec exported_boxes[MGA_NR_SAREA_CLIPRECTS]; + +   /* Counters for aging textures and for client-side throttling. +    */ +   unsigned int status[4]; +   unsigned int last_wrap; + +   mga_age_t last_frame; +   unsigned int last_enqueue;       /* last time a buffer was enqueued */ +   unsigned int last_dispatch;      /* age of the most recently dispatched buffer */ +   unsigned int last_quiescent;     /*  */ + +   /* LRU lists for texture memory in agp space and on the card. +    */ +   drmTextureRegion texList[MGA_NR_TEX_HEAPS][MGA_NR_TEX_REGIONS+1]; +   unsigned int texAge[MGA_NR_TEX_HEAPS]; + +   /* Last context that uploaded statel +    */ +   int ctxOwner; +} MGASAREAPrivRec, *MGASAREAPrivPtr; + +#endif | 
