diff options
author | Keith Whitwell <keith@tungstengraphics.com> | 2003-04-24 22:33:53 +0000 |
---|---|---|
committer | Keith Whitwell <keith@tungstengraphics.com> | 2003-04-24 22:33:53 +0000 |
commit | 545df254e8baf9b509e2ca981b54e850b47fd436 (patch) | |
tree | 11168766347dbe7e7015da72855002f17ed334ad | |
parent | 0bb460f417441bb47978af572e05291d009ca24d (diff) |
mga driver ported over by Denis Oliver Kropp
35 files changed, 12259 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/mga/Makefile b/src/mesa/drivers/dri/mga/Makefile new file mode 100644 index 0000000000..369b8dac20 --- /dev/null +++ b/src/mesa/drivers/dri/mga/Makefile @@ -0,0 +1,125 @@ +# $Id: Makefile,v 1.1.2.1 2003/04/24 22:33:53 keithw Exp $ + +# Mesa 3-D graphics library +# Version: 5.0 +# Copyright (C) 1995-2002 Brian Paul + + + +MESA = ../../.. +default: mga_dri.so +include $(MESA)/Makefile.include + + +SHARED_INCLUDES= -I$(MESABUILDDIR) -I$(MESA)/include -I. -I../common -Iserver +MINIGLX_INCLUDES = -I$(MESABUILDDIR)/miniglx +DRI_INCLUDES = -I$(MESABUILDDIR)/dri + +ifeq ($(FULL_DRIVER),true) +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 \ + -D_HAVE_FULL_GL=1 +else +DEFINES = \ + -D_HAVE_SWRAST=0 \ + -D_HAVE_SWTNL=0 \ + -D_HAVE_SANITY=0 \ + -D_HAVE_CODEGEN=0 \ + -D_HAVE_LIGHTING=0 \ + -D_HAVE_TEXGEN=0 \ + -D_HAVE_USERCLIP=0 \ + -D_HAVE_FULL_GL=0 +endif + +# The .a files for each mesa module required by this driver: +# +FULL_MESA = $(MESABUILDDIR)/swrast_setup/swrast_setup.a \ + $(MESABUILDDIR)/tnl/tnl.a \ + $(MESABUILDDIR)/math/math.a \ + $(MESABUILDDIR)/array_cache/array_cache.a \ + $(MESABUILDDIR)/swrast/swrast.a \ + $(MESABUILDDIR)/mesa.a \ + $(MESABUILDDIR)/math/math.a #kludge + +SUBSET_MESA = $(MESABUILDDIR)/mesa.a \ + $(MESABUILDDIR)/math/math.a + + + +MINIGLX_SOURCES = server/mga_dri.c + +DRIVER_SOURCES = mgabuffers.c \ + mgadd.c \ + mgaioctl.c \ + mgarender.c \ + mgastate.c \ + mgatris.c \ + ../common/mm.c + +SUBSET_DRIVER_SOURCES = \ + radeon_subset_bitmap.c \ + radeon_subset_readpix.c \ + radeon_subset_select.c \ + radeon_subset_tex.c \ + radeon_subset_vtx.c + +FULL_DRIVER_SOURCES = \ + mgapixel.c \ + mgaspan.c \ + mgatex.c \ + mgatexcnv.c \ + mgatexmem.c \ + mgavb.c \ + mga_xmesa.c + + +INCLUDES = $(MINIGLX_INCLUDES) \ + $(SHARED_INCLUDES) + + +ifeq ($(FULL_DRIVER),true) +C_SOURCES = $(DRIVER_SOURCES) \ + $(FULL_DRIVER_SOURCES) \ + $(MINIGLX_SOURCES) +MESA_MODULES = $(FULL_MESA) +else +C_SOURCES = $(DRIVER_SOURCES) \ + $(SUBSET_DRIVER_SOURCES) \ + $(MINIGLX_SOURCES) +MESA_MODULES = $(SUBSET_MESA) +endif + + +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) + + + +##### TARGETS ##### + + +# Build the subset or full driver? +# +mga_dri.so: $(OBJECTS) $(MESA_MODULES) $(WINOBJ) Makefile + rm -f $@ && gcc -o $@ -shared $(OBJECTS) $(MESA_MODULES) $(WINOBJ) $(WINLIB) -lGL -lc -lm + rm -f $(MESA)/lib/mga_dri.so && \ + install mga_dri.so $(MESA)/lib/mga_dri.so + +##### DEPENDENCIES ##### + +-include $(C_SOURCES:.c=.d) diff --git a/src/mesa/drivers/dri/mga/README b/src/mesa/drivers/dri/mga/README new file mode 100644 index 0000000000..57cedb3cdb --- /dev/null +++ b/src/mesa/drivers/dri/mga/README @@ -0,0 +1,39 @@ +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. + + +INSTRUCTIONS + +1. Checkout Mesa embedded-1-branch via: + + cvs -d :pserver:anonymous@cvs.mesa3d.sourceforge.net:/cvsroot/mesa3d co -r embedded-1-branch Mesa + +2. Patch some Makefiles (within the Mesa/ directory) via: + + patch -p0 < Mesa-embedded-1-branch-mga.diff + +3. Unpack the driver source (within the Mesa/ directory) via: + + tar xvjf Mesa-embedded-1-branch-src-drv-mga.tar.bz2 + + +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 + +- 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..b9bf5b19ae --- /dev/null +++ b/src/mesa/drivers/dri/mga/mga_xmesa.c @@ -0,0 +1,596 @@ +/* $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); + XFree(mgaScreen); + sPriv->private = NULL; + return GL_FALSE; + } + } + + if (serverInfo->chipset != MGA_CARD_TYPE_G200 && + serverInfo->chipset != MGA_CARD_TYPE_G400) { + XFree(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);*/ + XFree(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) +{ + 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; + + drmGetLock(mmesa->driFd, mmesa->hHWContext, flags); + + if (*(dPriv->pStamp) != mmesa->lastStamp) { + mmesa->lastStamp = *(dPriv->pStamp); + 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(Display *dpy, int scrn, __DRIscreen *psc, + int numConfigs, __GLXvisualConfig *config) +{ + __DRIscreenPrivate *psp; + psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &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..ae9d4f4764 --- /dev/null +++ b/src/mesa/drivers/dri/mga/mga_xmesa.h @@ -0,0 +1,142 @@ +/* + * 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 "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..820f04f496 --- /dev/null +++ b/src/mesa/drivers/dri/mga/mgabuffers.c @@ -0,0 +1,285 @@ +/* + * 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; + + 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; + + if (driDrawable->numBackClipRects == 0) + { + if (driDrawable->numClipRects == 0) { + static XF86DRIClipRectRec zeroareacliprect = {0,0,800,600}; + 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_drawable = driDrawable->draw; + 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) ); + + + if (mode == GL_FRONT_LEFT) + { + 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 ); + } + else if (mode == GL_BACK_LEFT) + { + 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 ); + } + else + { + FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_TRUE ); + } +} + 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..52f2dfaf41 --- /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..fdda2eee35 --- /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..6571587eca --- /dev/null +++ b/src/mesa/drivers/dri/mga/mgatex.c @@ -0,0 +1,984 @@ +/* + * 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 "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..d561df37c5 --- /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 apropriate 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..34a3fbeaee --- /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..976610f8a7 --- /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..3fca53dc2f --- /dev/null +++ b/src/mesa/drivers/dri/mga/server/mga.h @@ -0,0 +1,114 @@ +/* $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" + + +#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..e60888dd73 --- /dev/null +++ b/src/mesa/drivers/dri/mga/server/mga_dri.c @@ -0,0 +1,1203 @@ +/* $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 "miniglxP.h" +#include "dri_util.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 MiniGLXDisplayRec *dpy, 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( dpy->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( dpy->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( dpy->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 MiniGLXDisplayRec *dpy, 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( dpy->drmFD ) < 0 ) { + fprintf( stderr, "[agp] AGP not available\n" ); + return 0; + } + + mode = drmAgpGetMode( dpy->drmFD ); /* Default mode */ + vendor = drmAgpVendorId( dpy->drmFD ); + device = drmAgpDeviceId( dpy->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, + dpy->pciVendor, + dpy->pciChipType ); +#endif + + if ( drmAgpEnable( dpy->drmFD, mode ) < 0 ) { + fprintf( stderr, "[agp] AGP not enabled\n" ); + drmAgpRelease( dpy->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( dpy->drmFD, pMga->agp.size, + 0, NULL, &pMga->agp.handle ); + if ( ret < 0 ) { + fprintf( stderr, "[agp] Out of memory (%d)\n", ret ); + drmAgpRelease( dpy->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( dpy->drmFD, pMga->agp.handle, 0 ) < 0 ) { + fprintf( stderr, "[agp] Could not bind memory\n" ); + drmAgpFree( dpy->drmFD, pMga->agp.handle ); + drmAgpRelease( dpy->drmFD ); + return 0; + } + + /* WARP microcode space + */ + if ( drmAddMap( dpy->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( dpy->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( dpy->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( dpy->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( dpy->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( dpy->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( dpy->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( dpy->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 MiniGLXDisplayRec *dpy, MGAPtr pMga ) +{ + pMga->registers.size = MGAIOMAPSIZE; + + if ( drmAddMap( dpy->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( dpy->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( dpy->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 MiniGLXDisplayRec *dpy, 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 (dpy->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", dpy->bpp ); + return 0; + } + + + init.fb_cpp = dpy->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 = dpy->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 = dpy->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( dpy->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 MiniGLXDisplayRec *dpy, MGAPtr pMga) +{ + if (!pMga->irq) + { + pMga->irq = drmGetInterruptFromBusID(dpy->drmFD, + dpy->pciBus, + dpy->pciDevice, + dpy->pciFunc); + + fprintf(stderr, "[drm] got IRQ %d\n", pMga->irq); + + if((drmCtlInstHandler(dpy->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 MiniGLXDisplayRec *dpy, MGAPtr pMga ) +{ + pMga->drmBuffers = drmMapBufs( dpy->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 MiniGLXDisplayRec *dpy, MGAPtr pMga ) +{ + int width_bytes = dpy->shared.virtualWidth * dpy->cpp; + int bufferSize = ((dpy->shared.virtualHeight * width_bytes + + MGA_BUFFER_ALIGN) + & ~MGA_BUFFER_ALIGN); + int depthSize = ((((dpy->shared.virtualHeight+15) & ~15) * width_bytes + + MGA_BUFFER_ALIGN) + & ~MGA_BUFFER_ALIGN); + int l; + + pMga->frontOffset = 0; + pMga->frontPitch = dpy->shared.virtualWidth * dpy->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 = dpy->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 = ((dpy->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 = dpy->shared.virtualWidth * dpy->cpp; + + pMga->backOffset = ((pMga->depthOffset - bufferSize + + MGA_BUFFER_ALIGN) & + ~MGA_BUFFER_ALIGN); + pMga->backPitch = dpy->shared.virtualWidth * dpy->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 MiniGLXDisplayRec *dpy, MGAPtr pMga ) +{ + drmVersionPtr version; + + /* Check the MGA DRM version */ + version = drmGetVersion(dpy->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 MiniGLXDisplayRec *dpy, MGAPtr pMga ) +{ + int i; + int err; + MGADRIPtr pMGADRI; + unsigned int serverContext; + + usleep(100); + assert(!dpy->IsClient); + + { + int width_bytes = (dpy->shared.virtualWidth * dpy->cpp); + int maxy = dpy->shared.fbSize / width_bytes; + + + if (maxy <= dpy->shared.virtualHeight * 3) { + fprintf(stderr, + "Static buffer allocation failed -- " + "need at least %d kB video memory (have %d kB)\n", + (dpy->shared.virtualWidth * dpy->shared.virtualHeight * + dpy->cpp * 3 + 1023) / 1024, + dpy->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", + dpy->bpp, dpy->bpp /* FIXME: depth */ ); + + if ( (dpy->bpp / 8) != 2 && + (dpy->bpp / 8) != 4 ) { + fprintf( stderr, + "[dri] Direct rendering only supported in 16 and 32 bpp modes\n" ); + return 0; + } + + dpy->shared.SAREASize = SAREA_MAX; + + + /* Note that drmOpen will try to load the kernel module, if needed. */ + dpy->drmFD = drmOpen("mga", NULL ); + if (dpy->drmFD < 0) { + fprintf(stderr, "[drm] drmOpen failed\n"); + return 0; + } + + if ((err = drmSetBusid(dpy->drmFD, dpy->pciBusID)) < 0) { + fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n", + dpy->drmFD, dpy->pciBusID, strerror(-err)); + return 0; + } + + + if (drmAddMap( dpy->drmFD, + 0, + dpy->shared.SAREASize, + DRM_SHM, + DRM_CONTAINS_LOCK, + &dpy->shared.hSAREA) < 0) + { + fprintf(stderr, "[drm] drmAddMap failed\n"); + return 0; + } + fprintf(stderr, "[drm] added %d byte SAREA at 0x%08lx\n", + dpy->shared.SAREASize, dpy->shared.hSAREA); + + if (drmMap( dpy->drmFD, + dpy->shared.hSAREA, + dpy->shared.SAREASize, + (drmAddressPtr)(&dpy->pSAREA)) < 0) + { + fprintf(stderr, "[drm] drmMap failed\n"); + return 0; + } + memset(dpy->pSAREA, 0, dpy->shared.SAREASize); + fprintf(stderr, "[drm] mapped SAREA 0x%08lx to %p, size %d\n", + dpy->shared.hSAREA, dpy->pSAREA, dpy->shared.SAREASize); + + /* Need to AddMap the framebuffer and mmio regions here: + */ + if (drmAddMap( dpy->drmFD, + (drmHandle)dpy->FixedInfo.smem_start, + dpy->FixedInfo.smem_len, + DRM_FRAME_BUFFER, + 0, + &dpy->shared.hFrameBuffer) < 0) + { + fprintf(stderr, "[drm] drmAddMap framebuffer failed\n"); + return 0; + } + fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n", + dpy->shared.hFrameBuffer); + + +#if 0 /* will be done in MGADRIMapInit */ + if (drmAddMap(dpy->drmFD, + dpy->FixedInfo.mmio_start, + dpy->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(dpy, pMga)) { + return 0; + } + + if ( !MGADRIAgpInit( dpy, pMga ) ) { + return 0; + } + + if ( !MGADRIMapInit( dpy, pMga ) ) { + return 0; + } + + /* Memory manager setup */ + if (!MGAMemoryInit(dpy, pMga)) { + return 0; + } + + + /* Create a 'server' context so we can grab the lock for + * initialization ioctls. + */ + if ((err = drmCreateContext(dpy->drmFD, &serverContext)) != 0) { + fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err); + return 0; + } + + DRM_LOCK(dpy->drmFD, dpy->pSAREA, serverContext, 0); + + /* Initialize the kernel data structures */ + if (!MGADRIKernelInit(dpy, pMga)) { + fprintf(stderr, "MGADRIKernelInit failed\n"); + DRM_UNLOCK(dpy->drmFD, dpy->pSAREA, serverContext); + return 0; + } + + /* Initialize the vertex buffers list */ + if (!MGADRIBuffersInit(dpy, pMga)) { + fprintf(stderr, "MGADRIBuffersInit failed\n"); + DRM_UNLOCK(dpy->drmFD, dpy->pSAREA, serverContext); + return 0; + } + + /* Initialize IRQ */ + MGADRIIrqInit(dpy, pMga); + + + /* Initialize the SAREA private data structure */ + { + MGASAREAPrivPtr pSAREAPriv; + pSAREAPriv = (MGASAREAPrivPtr)(((char*)dpy->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(dpy->FrameBuffer + pMga->frontOffset, + 0, + pMga->frontPitch * dpy->shared.virtualHeight ); + + memset(dpy->FrameBuffer + pMga->backOffset, + 0, + pMga->backPitch * dpy->shared.virtualHeight ); + + + /* Can release the lock now */ + DRM_UNLOCK(dpy->drmFD, dpy->pSAREA, serverContext); + + /* This is the struct passed to radeon_dri.so for its initialization */ + dpy->driverClientMsg = malloc(sizeof(MGADRIRec)); + dpy->driverClientMsgSize = sizeof(MGADRIRec); + + pMGADRI = (MGADRIPtr)dpy->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 = dpy->shared.virtualWidth; + pMGADRI->height = dpy->shared.virtualHeight; + pMGADRI->mem = dpy->shared.fbSize; + pMGADRI->cpp = dpy->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 visuals available for the display. + * + * \param dpy display handle. + * \param numConfigs will receive the number of supported visuals. + * \param configs will point to the list of supported visuals. + * + * \return one on sucess, or zero on failure. + * + * \note Requires the ::__GLXvisualConfig data type. + * + * 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. + */ +static int mgaInitScreenConfigs( struct MiniGLXDisplayRec *dpy, + int *numConfigs, __GLXvisualConfig **configs) +{ + int i; + + *numConfigs = 1; + *configs = (__GLXvisualConfig *) calloc(*numConfigs, + sizeof(__GLXvisualConfig)); + + switch (dpy->bpp) { + case 32: + for (i = 0; i < *numConfigs; i++) { + (*configs)[i].vid = 100 + i; + (*configs)[i].class = TrueColor; + (*configs)[i].rgba = True; + (*configs)[i].redSize = 8; + (*configs)[i].greenSize = 8; + (*configs)[i].blueSize = 8; + (*configs)[i].alphaSize = 8; + (*configs)[i].redMask = 0xff0000; + (*configs)[i].greenMask = 0xff00; + (*configs)[i].blueMask = 0xff; + (*configs)[i].alphaMask = 0xff000000; + (*configs)[i].doubleBuffer = True; + (*configs)[i].stereo = False; + (*configs)[i].bufferSize = 32; + (*configs)[i].depthSize = 24; + (*configs)[i].stencilSize = 8; + (*configs)[i].auxBuffers = 0; + (*configs)[i].level = 0; + /* leave remaining fields zero */ + } + break; + + case 16: + for (i = 0; i < *numConfigs; i++) { + (*configs)[i].vid = 100 + i; + (*configs)[i].class = TrueColor; + (*configs)[i].rgba = True; + (*configs)[i].redSize = 5; + (*configs)[i].greenSize = 6; + (*configs)[i].blueSize = 5; + (*configs)[i].alphaSize = 0; + (*configs)[i].redMask = 0xf800; + (*configs)[i].greenMask = 0x07e0; + (*configs)[i].blueMask = 0x001f; + (*configs)[i].alphaMask = 0x0000; + (*configs)[i].doubleBuffer = True; + (*configs)[i].stereo = False; + (*configs)[i].bufferSize = 16; + (*configs)[i].depthSize = 16; + (*configs)[i].stencilSize = 0; + (*configs)[i].auxBuffers = 0; + (*configs)[i].level = 0; + /* leave remaining fields zero */ + } + break; + + default: + fprintf(stderr, "Unknown bpp in %s: %d\n", __FUNCTION__, + dpy->bpp); + exit(1); + break; + + } + return 1; +} + + +/** + * \brief Validate the fbdev mode. + * + * \param dpy display handle. + * + * \return one on success, or zero on failure. + * + * Saves some registers and returns 1. + * + * \sa mgaValidateMode(). + */ +static int mgaValidateMode( struct MiniGLXDisplayRec *dpy ) +{ + return 1; +} + + +/** + * \brief Examine mode returned by fbdev. + * + * \param dpy display handle. + * + * \return one on success, or zero on failure. + * + * Restores registers that fbdev has clobbered and returns 1. + * + * \sa mgaValidateMode(). + */ +static int mgaPostValidateMode( struct MiniGLXDisplayRec *dpy ) +{ + return 1; +} + + +/** + * \brief Initialize the framebuffer device mode + * + * \param dpy display handle. + * + * \return one on success, or zero on failure. + * + * Fills in \p info with some default values and some information from \p dpy + * and then calls MGAScreenInit() for the screen initialization. + * + * Before exiting clears the framebuffer memomry accessing it directly. + */ +static int mgaInitFBDev( struct MiniGLXDisplayRec *dpy ) +{ + MGAPtr pMga = calloc(1, sizeof(*pMga)); + + { + int dummy = dpy->shared.virtualWidth; + + switch (dpy->bpp / 8) { + case 1: dummy = (dpy->shared.virtualWidth + 127) & ~127; break; + case 2: dummy = (dpy->shared.virtualWidth + 31) & ~31; break; + case 3: + case 4: dummy = (dpy->shared.virtualWidth + 15) & ~15; break; + } + + dpy->shared.virtualWidth = dummy; + } + + dpy->driverInfo = (void *)pMga; + + pMga->agpMode = MGA_DEFAULT_AGP_MODE; + pMga->agpSize = MGA_DEFAULT_AGP_SIZE; + + pMga->Chipset = dpy->chipset; + + pMga->IOAddress = dpy->FixedInfo.mmio_start; + pMga->IOBase = dpy->MMIOAddress; + + pMga->frontPitch = dpy->shared.virtualWidth * dpy->cpp; + + if (!MGAScreenInit( dpy, 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 dpy display handle. + * + * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver + * private data. + */ +static void mgaHaltFBDev( struct MiniGLXDisplayRec *dpy ) +{ + drmUnmap( dpy->pSAREA, dpy->shared.SAREASize ); + drmClose(dpy->drmFD); + + if (dpy->driverInfo) { + free(dpy->driverInfo); + dpy->driverInfo = 0; + } +} + + +/** + * \brief A VT release or aquire signal has been received, and + * requires some action. We deal with loosing the VT by setting the + * cliprects to zero and emitting an event to the application. + */ +static int mgaVTSwitchHandler( struct MiniGLXDisplayRec *dpy, int have_vt ) +{ + int *lock = (int *)dpy->pSAREA; + int old, new; + DRM_CAS_RESULT(ret); + GLXDrawable draw; + __DRIdrawable *pdraw; + __DRIdrawablePrivate *pdp; + + /* Indicate cliprects have changed + */ + draw = dpy->TheWindow; + if (!draw) return 1; + pdraw = &draw->driDrawable; + if (!pdraw) return 1; + pdp = (__DRIdrawablePrivate *) pdraw->private; + if (!pdp) return 1; + pdp->lastStamp++; + pdp->numClipRects = have_vt ? 1 : 0; + + /* Mark the lock contended. + */ + if (!dpy->pSAREA) return 0; + do { + old = *(int *)dpy->pSAREA; + new = old | _DRM_LOCK_CONT; + DRM_CAS( lock, old, new, ret ); + fprintf(stderr, "old %x new %x\n", old, new ); + } while (ret); + + if (have_vt) + return !(old & _DRM_LOCK_HELD); + else + return 1; +} + +/** + * \brief Exported driver interface for Mini GLX. + * + * \sa MiniGLXDriverRec. + */ +struct MiniGLXDriverRec __driMiniGLXDriver = { + mgaInitScreenConfigs, + mgaValidateMode, + mgaPostValidateMode, + mgaInitFBDev, + mgaHaltFBDev, + mgaVTSwitchHandler +}; + + + + +#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(dpy->drmFD); + pMga->irq = 0; + } + + /* Cleanup DMA */ + memset( &init, 0, sizeof(drmMGAInit) ); + init.func = MGA_CLEANUP_DMA; + drmCommandWrite( dpy->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( dpy->drmFD, pMga->agp.handle ); + drmAgpFree( dpy->drmFD, pMga->agp.handle ); + pMga->agp.handle = 0; + drmAgpRelease( dpy->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..40058ebde8 --- /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. + */ + GLXDrawable req_drawable; /* the X drawable id */ + 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 |