Bläddra i källkod

mga driver, brought over by Jon Smirl

tags/vtx-0-2-21112003-freeze
Keith Whitwell 22 år sedan
förälder
incheckning
848ff108a0
35 ändrade filer med 12199 tillägg och 0 borttagningar
  1. 116
    0
      src/mesa/drivers/dri/mga/Makefile.X11
  2. 26
    0
      src/mesa/drivers/dri/mga/README
  3. 616
    0
      src/mesa/drivers/dri/mga/mga_xmesa.c
  4. 143
    0
      src/mesa/drivers/dri/mga/mga_xmesa.h
  5. 291
    0
      src/mesa/drivers/dri/mga/mgabuffers.c
  6. 37
    0
      src/mesa/drivers/dri/mga/mgabuffers.h
  7. 309
    0
      src/mesa/drivers/dri/mga/mgacontext.h
  8. 171
    0
      src/mesa/drivers/dri/mga/mgadd.c
  9. 37
    0
      src/mesa/drivers/dri/mga/mgadd.h
  10. 693
    0
      src/mesa/drivers/dri/mga/mgaioctl.c
  11. 113
    0
      src/mesa/drivers/dri/mga/mgaioctl.h
  12. 690
    0
      src/mesa/drivers/dri/mga/mgapixel.c
  13. 36
    0
      src/mesa/drivers/dri/mga/mgapixel.h
  14. 1381
    0
      src/mesa/drivers/dri/mga/mgaregs.h
  15. 208
    0
      src/mesa/drivers/dri/mga/mgarender.c
  16. 284
    0
      src/mesa/drivers/dri/mga/mgaspan.c
  17. 34
    0
      src/mesa/drivers/dri/mga/mgaspan.h
  18. 1131
    0
      src/mesa/drivers/dri/mga/mgastate.c
  19. 42
    0
      src/mesa/drivers/dri/mga/mgastate.h
  20. 985
    0
      src/mesa/drivers/dri/mga/mgatex.c
  21. 62
    0
      src/mesa/drivers/dri/mga/mgatex.h
  22. 256
    0
      src/mesa/drivers/dri/mga/mgatexcnv.c
  23. 564
    0
      src/mesa/drivers/dri/mga/mgatexmem.c
  24. 915
    0
      src/mesa/drivers/dri/mga/mgatris.c
  25. 43
    0
      src/mesa/drivers/dri/mga/mgatris.h
  26. 497
    0
      src/mesa/drivers/dri/mga/mgavb.c
  27. 65
    0
      src/mesa/drivers/dri/mga/mgavb.h
  28. 115
    0
      src/mesa/drivers/dri/mga/server/mga.h
  29. 143
    0
      src/mesa/drivers/dri/mga/server/mga_bios.h
  30. 152
    0
      src/mesa/drivers/dri/mga/server/mga_common.h
  31. 1136
    0
      src/mesa/drivers/dri/mga/server/mga_dri.c
  32. 84
    0
      src/mesa/drivers/dri/mga/server/mga_dri.h
  33. 118
    0
      src/mesa/drivers/dri/mga/server/mga_macros.h
  34. 484
    0
      src/mesa/drivers/dri/mga/server/mga_reg.h
  35. 222
    0
      src/mesa/drivers/dri/mga/server/mga_sarea.h

+ 116
- 0
src/mesa/drivers/dri/mga/Makefile.X11 Visa fil

@@ -0,0 +1,116 @@
# $Id: Makefile.X11,v 1.1 2003/08/06 18:01:13 keithw Exp $

# Mesa 3-D graphics library
# Version: 5.0
# Copyright (C) 1995-2002 Brian Paul

TOP = ../../../../..

SHARED_INCLUDES = $(INCLUDE_DIRS) -I. -I../common -Iserver
MINIGLX_INCLUDES = -I$(TOP)/src/miniglx

DEFINES += \
-D_HAVE_SWRAST=1 \
-D_HAVE_SWTNL=1 \
-D_HAVE_SANITY=1 \
-D_HAVE_CODEGEN=1 \
-D_HAVE_LIGHTING=1 \
-D_HAVE_TEXGEN=1 \
-D_HAVE_USERCLIP=1

MINIGLX_SOURCES = server/mga_dri.c

DRIVER_SOURCES = mgabuffers.c \
mgadd.c \
mgaioctl.c \
mgarender.c \
mgastate.c \
mgatris.c \
../common/mm.c

FULL_DRIVER_SOURCES = \
mgapixel.c \
mgaspan.c \
mgatex.c \
mgatexcnv.c \
mgatexmem.c \
mgavb.c \
mga_xmesa.c


INCLUDES = $(MINIGLX_INCLUDES) \
$(SHARED_INCLUDES)


C_SOURCES = $(MINIGLX_SOURCES) \
$(FULL_DRIVER_SOURCES) \
$(DRIVER_SOURCES)

MESA_MODULES = $(TOP)/src/mesa/mesa.a


ifeq ($(WINDOW_SYSTEM),dri)
WINOBJ=$(MESABUILDDIR)/dri/dri.a
WINLIB=
else
WINOBJ=
WINLIB=-L$(MESA)/src/miniglx
endif

ASM_SOURCES =
OBJECTS = $(C_SOURCES:.c=.o) \
$(ASM_SOURCES:.S=.o)



### Include directories

INCLUDE_DIRS = \
-I$(TOP)/include \
-I$(TOP)/src/mesa \
-I$(TOP)/src/mesa/main \
-I$(TOP)/src/mesa/glapi \
-I$(TOP)/src/mesa/math \
-I$(TOP)/src/mesa/transform \
-I$(TOP)/src/mesa/swrast \
-I$(TOP)/src/mesa/swrast_setup


##### RULES #####

.c.o:
$(CC) -c $(SHARED_INCLUDES) $(MINIGLX_INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@

.S.o:
$(CC) -c $(SHARED_INCLUDES) $(MINIGLX_INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@


##### TARGETS #####

targets: mga_dri.so

mga_dri.so: $(OBJECTS) $(MESA_MODULES) $(WINOBJ) Makefile.X11
rm -f $@ && gcc -o $@ -shared $(OBJECTS) $(MESA_MODULES) $(WINOBJ) $(WINLIB) -lc -lm
rm -f $(TOP)/lib/mga_dri.so && \
install mga_dri.so $(TOP)/lib/mga_dri.so

# Run 'make -f Makefile.X11 dep' to update the dependencies if you change
# what's included by any source file.
dep: $(C_SOURCES) $(ASM_SOURCES)
makedepend -fdepend -Y $(SHARED_INCLUDES) \
$(C_SOURCES) $(ASM_SOURCES)


# Emacs tags
tags:
etags `find . -name \*.[ch]` `find ../include`


# Remove .o and backup files
clean:
-rm -f *.o *~ *.o *~ *.so


include $(TOP)/Make-config

include depend

+ 26
- 0
src/mesa/drivers/dri/mga/README Visa fil

@@ -0,0 +1,26 @@
MGA DRI driver ported from XF86DRI to FBDRI
by Denis Oliver Kropp <dok@directfb.org>


INFO

This driver has been ported from the head branch of XFree86 to
the embedded-1-branch of Mesa.


STATUS

Already working very well as far as I've tested it (16/32 bit).
glxgears runs at 935 fps (G550 32MB AGP 4x, Athlon 1.33) vs 744 fps with XFree.
Other demos (terrain, fire, etc.) have been successfully tested as well.


TODO

- mgaEngineShutdown
- mgaEngineRestore
- SGRAM detection
- remove some unused bits from server/*
- subset driver support
- mgaWaitForVBlank
- deinitialization (from MGADRICloseScreen) a la radeonDestroyScreen

+ 616
- 0
src/mesa/drivers/dri/mga/mga_xmesa.c Visa fil

@@ -0,0 +1,616 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c,v 1.19 2003/03/26 20:43:49 tsi Exp $ */
/*
* Copyright 2000-2001 VA Linux Systems, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
*/

#include <stdio.h>

#include "mga_common.h"
#include "mga_xmesa.h"
#include "context.h"
#include "matrix.h"
/*#include "mmath.h"*/
#include "simple_list.h"
/*#include "mem.h"*/

#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
#include "array_cache/acache.h"

#include "tnl/t_pipeline.h"

#include "mgadd.h"
#include "mgastate.h"
#include "mgatex.h"
#include "mgaspan.h"
#include "mgaioctl.h"
#include "mgatris.h"
#include "mgavb.h"
#include "mgabuffers.h"
#include "mgapixel.h"

#include "mga_xmesa.h"

#include "mga_dri.h"


#ifndef MGA_DEBUG
int MGA_DEBUG = (0
/* | DEBUG_ALWAYS_SYNC */
/* | DEBUG_VERBOSE_MSG */
/* | DEBUG_VERBOSE_LRU */
/* | DEBUG_VERBOSE_DRI */
/* | DEBUG_VERBOSE_IOCTL */
/* | DEBUG_VERBOSE_2D */
/* | DEBUG_VERBOSE_FALLBACK */
);
#endif


static GLboolean
mgaInitDriver(__DRIscreenPrivate *sPriv)
{
mgaScreenPrivate *mgaScreen;
MGADRIPtr serverInfo = (MGADRIPtr)sPriv->pDevPriv;

if (MGA_DEBUG&DEBUG_VERBOSE_DRI)
fprintf(stderr, "mgaInitDriver\n");

/* Check that the DRM driver version is compatible */
if (sPriv->drmMajor != 3 ||
sPriv->drmMinor < 0) {
__driUtilMessage("MGA DRI driver expected DRM driver version 3.0.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch);
return GL_FALSE;
}


/* Allocate the private area */
mgaScreen = (mgaScreenPrivate *)MALLOC(sizeof(mgaScreenPrivate));
if (!mgaScreen) {
__driUtilMessage("Couldn't malloc screen struct");
return GL_FALSE;
}

mgaScreen->sPriv = sPriv;
sPriv->private = (void *)mgaScreen;

if (sPriv->drmMinor >= 1) {
int ret;
drmMGAGetParam gp;

gp.param = MGA_PARAM_IRQ_NR;
gp.value = (int *) &mgaScreen->irq;

ret = drmCommandWriteRead( sPriv->fd, DRM_MGA_GETPARAM,
&gp, sizeof(gp));
if (ret) {
fprintf(stderr, "drmMgaGetParam (MGA_PARAM_IRQ_NR): %d\n", ret);
FREE(mgaScreen);
sPriv->private = NULL;
return GL_FALSE;
}
}
if (serverInfo->chipset != MGA_CARD_TYPE_G200 &&
serverInfo->chipset != MGA_CARD_TYPE_G400) {
FREE(mgaScreen);
sPriv->private = NULL;
__driUtilMessage("Unrecognized chipset");
return GL_FALSE;
}


mgaScreen->chipset = serverInfo->chipset;
mgaScreen->width = serverInfo->width;
mgaScreen->height = serverInfo->height;
mgaScreen->mem = serverInfo->mem;
mgaScreen->cpp = serverInfo->cpp;

mgaScreen->agpMode = serverInfo->agpMode;

mgaScreen->frontPitch = serverInfo->frontPitch;
mgaScreen->frontOffset = serverInfo->frontOffset;
mgaScreen->backOffset = serverInfo->backOffset;
mgaScreen->backPitch = serverInfo->backPitch;
mgaScreen->depthOffset = serverInfo->depthOffset;
mgaScreen->depthPitch = serverInfo->depthPitch;

mgaScreen->mmio.handle = serverInfo->registers.handle;
mgaScreen->mmio.size = serverInfo->registers.size;
if ( drmMap( sPriv->fd,
mgaScreen->mmio.handle, mgaScreen->mmio.size,
&mgaScreen->mmio.map ) < 0 ) {
FREE( mgaScreen );
sPriv->private = NULL;
__driUtilMessage( "Couldn't map MMIO registers" );
return GL_FALSE;
}

mgaScreen->primary.handle = serverInfo->primary.handle;
mgaScreen->primary.size = serverInfo->primary.size;
mgaScreen->buffers.handle = serverInfo->buffers.handle;
mgaScreen->buffers.size = serverInfo->buffers.size;

#if 0
mgaScreen->agp.handle = serverInfo->agp;
mgaScreen->agp.size = serverInfo->agpSize;

if (drmMap(sPriv->fd,
mgaScreen->agp.handle,
mgaScreen->agp.size,
(drmAddress *)&mgaScreen->agp.map) != 0)
{
Xfree(mgaScreen);
sPriv->private = NULL;
__driUtilMessage("Couldn't map agp region");
return GL_FALSE;
}
#endif

mgaScreen->textureOffset[MGA_CARD_HEAP] = serverInfo->textureOffset;
mgaScreen->textureOffset[MGA_AGP_HEAP] = (serverInfo->agpTextureOffset |
PDEA_pagpxfer_enable | 1);

mgaScreen->textureSize[MGA_CARD_HEAP] = serverInfo->textureSize;
mgaScreen->textureSize[MGA_AGP_HEAP] = serverInfo->agpTextureSize;

mgaScreen->logTextureGranularity[MGA_CARD_HEAP] =
serverInfo->logTextureGranularity;
mgaScreen->logTextureGranularity[MGA_AGP_HEAP] =
serverInfo->logAgpTextureGranularity;

mgaScreen->texVirtual[MGA_CARD_HEAP] = (char *)(mgaScreen->sPriv->pFB +
serverInfo->textureOffset);
if (drmMap(sPriv->fd,
serverInfo->agpTextureOffset,
serverInfo->agpTextureSize,
(drmAddress *)&mgaScreen->texVirtual[MGA_AGP_HEAP]) != 0)
{
free(mgaScreen);
sPriv->private = NULL;
__driUtilMessage("Couldn't map agptexture region");
return GL_FALSE;
}

#if 0
mgaScreen->texVirtual[MGA_AGP_HEAP] = (mgaScreen->agp.map +
serverInfo->agpTextureOffset);
#endif

mgaScreen->mAccess = serverInfo->mAccess;

/* For calculating setupdma addresses.
*/
mgaScreen->dmaOffset = serverInfo->buffers.handle;

mgaScreen->bufs = drmMapBufs(sPriv->fd);
if (!mgaScreen->bufs) {
/*drmUnmap(mgaScreen->agp_tex.map, mgaScreen->agp_tex.size);*/
FREE(mgaScreen);
sPriv->private = NULL;
__driUtilMessage("Couldn't map dma buffers");
return GL_FALSE;
}
mgaScreen->sarea_priv_offset = serverInfo->sarea_priv_offset;

return GL_TRUE;
}


static void
mgaDestroyScreen(__DRIscreenPrivate *sPriv)
{
mgaScreenPrivate *mgaScreen = (mgaScreenPrivate *) sPriv->private;

if (MGA_DEBUG&DEBUG_VERBOSE_DRI)
fprintf(stderr, "mgaDestroyScreen\n");

/*drmUnmap(mgaScreen->agp_tex.map, mgaScreen->agp_tex.size);*/
free(mgaScreen);
sPriv->private = NULL;
}


extern const struct gl_pipeline_stage _mga_render_stage;

static const struct gl_pipeline_stage *mga_pipeline[] = {
&_tnl_vertex_transform_stage,
&_tnl_normal_transform_stage,
&_tnl_lighting_stage,
&_tnl_fog_coordinate_stage,
&_tnl_texgen_stage,
&_tnl_texture_transform_stage,
/* REMOVE: point attenuation stage */
#if 0
&_mga_render_stage, /* ADD: unclipped rastersetup-to-dma */
/* Need new ioctl for wacceptseq */
#endif
&_tnl_render_stage,
0,
};


static GLboolean
mgaCreateContext( const __GLcontextModes *mesaVis,
__DRIcontextPrivate *driContextPriv,
void *sharedContextPrivate )
{
int i;
GLcontext *ctx, *shareCtx;
mgaContextPtr mmesa;
__DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
mgaScreenPrivate *mgaScreen = (mgaScreenPrivate *)sPriv->private;
MGASAREAPrivPtr saPriv=(MGASAREAPrivPtr)(((char*)sPriv->pSAREA)+
mgaScreen->sarea_priv_offset);

if (MGA_DEBUG&DEBUG_VERBOSE_DRI)
fprintf(stderr, "mgaCreateContext\n");

/* allocate mga context */
mmesa = (mgaContextPtr) CALLOC(sizeof(mgaContext));
if (!mmesa) {
return GL_FALSE;
}

/* Allocate the Mesa context */
if (sharedContextPrivate)
shareCtx = ((mgaContextPtr) sharedContextPrivate)->glCtx;
else
shareCtx = NULL;
mmesa->glCtx = _mesa_create_context(mesaVis, shareCtx, mmesa, GL_TRUE);
if (!mmesa->glCtx) {
FREE(mmesa);
return GL_FALSE;
}
driContextPriv->driverPrivate = mmesa;

/* Init mga state */
mmesa->hHWContext = driContextPriv->hHWContext;
mmesa->driFd = sPriv->fd;
mmesa->driHwLock = &sPriv->pSAREA->lock;

mmesa->mgaScreen = mgaScreen;
mmesa->driScreen = sPriv;
mmesa->sarea = (void *)saPriv;
mmesa->glBuffer = NULL;

make_empty_list(&mmesa->SwappedOut);

mmesa->lastTexHeap = mgaScreen->texVirtual[MGA_AGP_HEAP] ? 2 : 1;

for (i = 0 ; i < mmesa->lastTexHeap ; i++) {
mmesa->texHeap[i] = mmInit( 0, mgaScreen->textureSize[i]);
make_empty_list(&mmesa->TexObjList[i]);
}

/* Set the maximum texture size small enough that we can guarentee
* that both texture units can bind a maximal texture and have them
* on the card at once.
*/
ctx = mmesa->glCtx;
{
int nr = 2;

if (mgaScreen->chipset == MGA_CARD_TYPE_G200)
nr = 1;

if (mgaScreen->textureSize[0] < nr*1024*1024) {
ctx->Const.MaxTextureLevels = 9;
} else if (mgaScreen->textureSize[0] < nr*4*1024*1024) {
ctx->Const.MaxTextureLevels = 10;
} else {
ctx->Const.MaxTextureLevels = 11;
}

ctx->Const.MaxTextureUnits = nr;
}

ctx->Const.MinLineWidth = 1.0;
ctx->Const.MinLineWidthAA = 1.0;
ctx->Const.MaxLineWidth = 10.0;
ctx->Const.MaxLineWidthAA = 10.0;
ctx->Const.LineWidthGranularity = 1.0;

mmesa->hw_stencil = mesaVis->stencilBits && mesaVis->depthBits == 24;

switch (mesaVis->depthBits) {
case 16:
mmesa->depth_scale = 1.0/(GLdouble)0xffff;
mmesa->depth_clear_mask = ~0;
mmesa->ClearDepth = 0xffff;
break;
case 24:
mmesa->depth_scale = 1.0/(GLdouble)0xffffff;
if (mmesa->hw_stencil) {
mmesa->depth_clear_mask = 0xffffff00;
mmesa->stencil_clear_mask = 0x000000ff;
} else
mmesa->depth_clear_mask = ~0;
mmesa->ClearDepth = 0xffffff00;
break;
case 32:
mmesa->depth_scale = 1.0/(GLdouble)0xffffffff;
mmesa->depth_clear_mask = ~0;
mmesa->ClearDepth = 0xffffffff;
break;
};

mmesa->haveHwStipple = GL_FALSE;
mmesa->RenderIndex = -1; /* impossible value */
mmesa->new_state = ~0;
mmesa->dirty = ~0;
mmesa->vertex_format = 0;
mmesa->CurrentTexObj[0] = 0;
mmesa->CurrentTexObj[1] = 0;
mmesa->tmu_source[0] = 0;
mmesa->tmu_source[1] = 1;

mmesa->texAge[0] = 0;
mmesa->texAge[1] = 0;
/* Initialize the software rasterizer and helper modules.
*/
_swrast_CreateContext( ctx );
_ac_CreateContext( ctx );
_tnl_CreateContext( ctx );
_swsetup_CreateContext( ctx );

/* Install the customized pipeline:
*/
_tnl_destroy_pipeline( ctx );
_tnl_install_pipeline( ctx, mga_pipeline );

/* Configure swrast to match hardware characteristics:
*/
_swrast_allow_pixel_fog( ctx, GL_FALSE );
_swrast_allow_vertex_fog( ctx, GL_TRUE );

mmesa->primary_offset = mmesa->mgaScreen->primary.handle;

ctx->DriverCtx = (void *) mmesa;
mmesa->glCtx = ctx;

mgaDDExtensionsInit( ctx );

mgaDDInitStateFuncs( ctx );
mgaDDInitTextureFuncs( ctx );
mgaDDInitSpanFuncs( ctx );
mgaDDInitDriverFuncs( ctx );
mgaDDInitIoctlFuncs( ctx );
mgaDDInitPixelFuncs( ctx );
mgaDDInitTriFuncs( ctx );

mgaInitVB( ctx );
mgaInitState( mmesa );

driContextPriv->driverPrivate = (void *) mmesa;

return GL_TRUE;
}

static void
mgaDestroyContext(__DRIcontextPrivate *driContextPriv)
{
mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate;

if (MGA_DEBUG&DEBUG_VERBOSE_DRI)
fprintf(stderr, "mgaDestroyContext\n");

assert(mmesa); /* should never be null */
if (mmesa) {
_swsetup_DestroyContext( mmesa->glCtx );
_tnl_DestroyContext( mmesa->glCtx );
_ac_DestroyContext( mmesa->glCtx );
_swrast_DestroyContext( mmesa->glCtx );

mgaFreeVB( mmesa->glCtx );

/* free the Mesa context */
mmesa->glCtx->DriverCtx = NULL;
_mesa_destroy_context(mmesa->glCtx);
/* free the mga context */
FREE(mmesa);
}
}


static GLboolean
mgaCreateBuffer( __DRIscreenPrivate *driScrnPriv,
__DRIdrawablePrivate *driDrawPriv,
const __GLcontextModes *mesaVis,
GLboolean isPixmap )
{
if (isPixmap) {
return GL_FALSE; /* not implemented */
}
else {
GLboolean swStencil = (mesaVis->stencilBits > 0 &&
mesaVis->depthBits != 24);

driDrawPriv->driverPrivate = (void *)
_mesa_create_framebuffer(mesaVis,
GL_FALSE, /* software depth buffer? */
swStencil,
mesaVis->accumRedBits > 0,
mesaVis->alphaBits > 0 );

return (driDrawPriv->driverPrivate != NULL);
}
}


static void
mgaDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
{
_mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
}


static GLboolean
mgaUnbindContext(__DRIcontextPrivate *driContextPriv)
{
mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate;
if (mmesa)
mmesa->dirty = ~0;

return GL_TRUE;
}

static GLboolean
mgaOpenFullScreen(__DRIcontextPrivate *driContextPriv)
{
return GL_TRUE;
}

static GLboolean
mgaCloseFullScreen(__DRIcontextPrivate *driContextPriv)
{
return GL_TRUE;
}


/* This looks buggy to me - the 'b' variable isn't used anywhere...
* Hmm - It seems that the drawable is already hooked in to
* driDrawablePriv.
*
* But why are we doing context initialization here???
*/
static GLboolean
mgaMakeCurrent(__DRIcontextPrivate *driContextPriv,
__DRIdrawablePrivate *driDrawPriv,
__DRIdrawablePrivate *driReadPriv)
{
fprintf(stderr, "%s\n", __FUNCTION__);

if (driContextPriv) {
mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate;

if (mmesa->driDrawable != driDrawPriv) {
mmesa->driDrawable = driDrawPriv;
mmesa->dirty = ~0;
mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK);
}

_mesa_make_current2(mmesa->glCtx,
(GLframebuffer *) driDrawPriv->driverPrivate,
(GLframebuffer *) driReadPriv->driverPrivate);

if (!mmesa->glCtx->Viewport.Width)
_mesa_set_viewport(mmesa->glCtx, 0, 0,
driDrawPriv->w, driDrawPriv->h);

}
else {
_mesa_make_current(NULL, NULL);
}

return GL_TRUE;
}

void mgaGetLock( mgaContextPtr mmesa, GLuint flags )
{
__DRIdrawablePrivate *dPriv = mmesa->driDrawable;
MGASAREAPrivPtr sarea = mmesa->sarea;
int me = mmesa->hHWContext;
int i;

fprintf(stderr, "%s\n", __FUNCTION__);

drmGetLock(mmesa->driFd, mmesa->hHWContext, flags);
fprintf(stderr,
"mmesa->lastStamp %d dpriv->lastStamp %d *(dpriv->pStamp) %d\n",
mmesa->lastStamp,
dPriv->lastStamp,
*(dPriv->pStamp));
/* The window might have moved, so we might need to get new clip
* rects.
*
* NOTE: This releases and regrabs the hw lock to allow the X server
* to respond to the DRI protocol request for new drawable info.
* Since the hardware state depends on having the latest drawable
* clip rects, all state checking must be done _after_ this call.
*/
DRI_VALIDATE_DRAWABLE_INFO( sPriv, dPriv );

if ( mmesa->lastStamp == 0 ||
mmesa->lastStamp != dPriv->lastStamp ) {
mmesa->lastStamp = dPriv->lastStamp;
mmesa->SetupNewInputs |= VERT_BIT_CLIP;
mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK);
mgaUpdateRects( mmesa, (MGA_FRONT|MGA_BACK) );
}

mmesa->dirty |= MGA_UPLOAD_CONTEXT | MGA_UPLOAD_CLIPRECTS;

mmesa->sarea->dirty |= MGA_UPLOAD_CONTEXT;

if (sarea->ctxOwner != me) {
mmesa->dirty |= (MGA_UPLOAD_CONTEXT | MGA_UPLOAD_TEX0 |
MGA_UPLOAD_TEX1 | MGA_UPLOAD_PIPE);
sarea->ctxOwner=me;
}

for (i = 0 ; i < mmesa->lastTexHeap ; i++)
if (sarea->texAge[i] != mmesa->texAge[i])
mgaAgeTextures( mmesa, i );

sarea->last_quiescent = -1; /* just kill it for now */
}



static const struct __DriverAPIRec mgaAPI = {
mgaInitDriver,
mgaDestroyScreen,
mgaCreateContext,
mgaDestroyContext,
mgaCreateBuffer,
mgaDestroyBuffer,
mgaSwapBuffers,
mgaMakeCurrent,
mgaUnbindContext,
mgaOpenFullScreen,
mgaCloseFullScreen
};



/*
* This is the bootstrap function for the driver.
* The __driCreateScreen name is the symbol that libGL.so fetches.
* Return: pointer to a __DRIscreenPrivate.
*/
void *__driCreateScreen(struct DRIDriverRec *driver,
struct DRIDriverContextRec *driverContext)
{
__DRIscreenPrivate *psp;
psp = __driUtilCreateScreen(driver, driverContext, &mgaAPI);
return (void *) psp;
}

+ 143
- 0
src/mesa/drivers/dri/mga/mga_xmesa.h Visa fil

@@ -0,0 +1,143 @@
/*
* Copyright 2000-2001 VA Linux Systems, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
*/
/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h,v 1.12 2002/12/16 16:18:52 dawes Exp $ */

#ifndef _MGA_INIT_H_
#define _MGA_INIT_H_

#include <sys/time.h>
#include <linux/types.h>
#include "dri_util.h"
#include "mtypes.h"
#include "mgaregs.h"
#include "mga_common.h"

typedef struct mga_screen_private_s {

int chipset;
int width;
int height;
int mem;

int cpp; /* for front and back buffers */
GLint agpMode;
unsigned int irq; /* IRQ number (0 means none) */

unsigned int mAccess;

unsigned int frontOffset;
unsigned int frontPitch;
unsigned int backOffset;
unsigned int backPitch;

unsigned int depthOffset;
unsigned int depthPitch;
int depthCpp;

unsigned int dmaOffset;

unsigned int textureOffset[DRM_MGA_NR_TEX_HEAPS];
unsigned int textureSize[DRM_MGA_NR_TEX_HEAPS];
int logTextureGranularity[DRM_MGA_NR_TEX_HEAPS];
char *texVirtual[DRM_MGA_NR_TEX_HEAPS];


__DRIscreenPrivate *sPriv;
drmBufMapPtr bufs;

drmRegion mmio;
drmRegion status;
drmRegion primary;
drmRegion buffers;
unsigned int sarea_priv_offset;
} mgaScreenPrivate;


#include "mgacontext.h"

extern void mgaGetLock( mgaContextPtr mmesa, GLuint flags );
extern void mgaEmitHwStateLocked( mgaContextPtr mmesa );
extern void mgaEmitScissorValues( mgaContextPtr mmesa, int box_nr, int emit );

#define GET_DISPATCH_AGE( mmesa ) mmesa->sarea->last_dispatch
#define GET_ENQUEUE_AGE( mmesa ) mmesa->sarea->last_enqueue



/* Lock the hardware and validate our state.
*/
#define LOCK_HARDWARE( mmesa ) \
do { \
char __ret=0; \
DRM_CAS(mmesa->driHwLock, mmesa->hHWContext, \
(DRM_LOCK_HELD|mmesa->hHWContext), __ret); \
if (__ret) \
mgaGetLock( mmesa, 0 ); \
} while (0)


/*
*/
#define LOCK_HARDWARE_QUIESCENT( mmesa ) do { \
LOCK_HARDWARE( mmesa ); \
UPDATE_LOCK( mmesa, DRM_LOCK_QUIESCENT | DRM_LOCK_FLUSH ); \
} while (0)


/* Unlock the hardware using the global current context
*/
#define UNLOCK_HARDWARE(mmesa) \
DRM_UNLOCK(mmesa->driFd, mmesa->driHwLock, mmesa->hHWContext);


/* Freshen our snapshot of the drawables
*/
#define REFRESH_DRAWABLE_INFO( mmesa ) \
do { \
LOCK_HARDWARE( mmesa ); \
mmesa->lastX = mmesa->drawX; \
mmesa->lastY = mmesa->drawY; \
UNLOCK_HARDWARE( mmesa ); \
} while (0)


#define GET_DRAWABLE_LOCK( mmesa ) while(0)
#define RELEASE_DRAWABLE_LOCK( mmesa ) while(0)


/* The 2D driver macros are busted -- we can't use them here as they
* rely on the 2D driver data structures rather than taking an explicit
* base address.
*/
#define MGA_BASE( reg ) ((unsigned long)(mmesa->mgaScreen->mmio.map))
#define MGA_ADDR( reg ) (MGA_BASE(reg) + reg)

#define MGA_DEREF( reg ) *(volatile __u32 *)MGA_ADDR( reg )
#define MGA_READ( reg ) MGA_DEREF( reg )
#define MGA_WRITE( reg, val ) do { MGA_DEREF( reg ) = val; } while (0)

#endif

+ 291
- 0
src/mesa/drivers/dri/mga/mgabuffers.c Visa fil

@@ -0,0 +1,291 @@
/*
* Copyright 2000-2001 VA Linux Systems, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
*/
/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgabuffers.c,v 1.13 2002/11/05 17:46:08 tsi Exp $ */

#include <stdio.h>
#include "mgacontext.h"
#include "mgabuffers.h"
#include "mgastate.h"
#include "mgaioctl.h"
#include "mgatris.h"

static void mgaXMesaSetFrontClipRects( mgaContextPtr mmesa )
{
__DRIdrawablePrivate *driDrawable = mmesa->driDrawable;

/* fprintf( stderr, "%s\n", __FUNCTION__ );*/

if (driDrawable->numClipRects == 0) {
static XF86DRIClipRectRec zeroareacliprect = {0,0,0,0};
mmesa->numClipRects = 1;
mmesa->pClipRects = &zeroareacliprect;
} else {
mmesa->numClipRects = driDrawable->numClipRects;
mmesa->pClipRects = driDrawable->pClipRects;
}
mmesa->drawX = driDrawable->x;
mmesa->drawY = driDrawable->y;

mmesa->setup.dstorg = mmesa->drawOffset;
mmesa->dirty |= MGA_UPLOAD_CONTEXT | MGA_UPLOAD_CLIPRECTS;
}


static void mgaXMesaSetBackClipRects( mgaContextPtr mmesa )
{
__DRIdrawablePrivate *driDrawable = mmesa->driDrawable;

/* fprintf( stderr, "%s\n", __FUNCTION__ );*/

if (driDrawable->numBackClipRects == 0)
{
if (driDrawable->numClipRects == 0) {
static XF86DRIClipRectRec zeroareacliprect = {0,0,0,0};
mmesa->numClipRects = 1;
mmesa->pClipRects = &zeroareacliprect;
} else {
mmesa->numClipRects = driDrawable->numClipRects;
mmesa->pClipRects = driDrawable->pClipRects;
}
mmesa->drawX = driDrawable->x;
mmesa->drawY = driDrawable->y;
} else {
mmesa->numClipRects = driDrawable->numBackClipRects;
mmesa->pClipRects = driDrawable->pBackClipRects;
mmesa->drawX = driDrawable->backX;
mmesa->drawY = driDrawable->backY;
}

mmesa->setup.dstorg = mmesa->drawOffset;
mmesa->dirty |= MGA_UPLOAD_CONTEXT | MGA_UPLOAD_CLIPRECTS;
}



#if 0
static void mgaUpdateRectsFromSarea( mgaContextPtr mmesa )
{
__DRIdrawablePrivate *driDrawable = mmesa->driDrawable;
__DRIscreenPrivate *driScreen = mmesa->driScreen;
MGASAREAPrivPtr sarea = mmesa->sarea;
int i = 0, top = 0;


if (sarea->exported_buffers & MGA_BACK) {

driDrawable->numBackClipRects = sarea->exported_nback;
driDrawable->pBackClipRects = mmesa->tmp_boxes[0];

top = sarea->exported_nback;
for (i = 0 ; i < top ; i++)
driDrawable->pBackClipRects[i] =
*(XF86DRIClipRectPtr)&(sarea->exported_boxes[i]);
}


if (sarea->exported_buffers & MGA_FRONT)
{
int start = top;

driDrawable->numClipRects = sarea->exported_nfront;
driDrawable->pClipRects = mmesa->tmp_boxes[1];

top += sarea->exported_nfront;
for ( ; i < top ; i++)
driDrawable->pClipRects[i-start] =
*(XF86DRIClipRectPtr)&(sarea->exported_boxes[i]);

}



driDrawable->index = sarea->exported_index;
driDrawable->lastStamp = sarea->exported_stamp;
driDrawable->x = sarea->exported_front_x;
driDrawable->y = sarea->exported_front_y;
driDrawable->backX = sarea->exported_back_x;
driDrawable->backY = sarea->exported_back_y;
driDrawable->w = sarea->exported_w;
driDrawable->h = sarea->exported_h;
driDrawable->pStamp =
&(driScreen->pSAREA->drawableTable[driDrawable->index].stamp);

mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK) & ~(sarea->exported_buffers);
}
#endif

#if 0
static void printSareaRects( mgaContextPtr mmesa )
{
__DRIscreenPrivate *driScreen = mmesa->driScreen;
MGASAREAPrivPtr sarea = mmesa->sarea;
int i;

fprintf(stderr, "sarea->exported: %d\n", sarea->exported_drawable);
fprintf(stderr, "sarea->exported_index: %d\n", sarea->exported_index);
fprintf(stderr, "sarea->exported_stamp: %d\n", sarea->exported_stamp);
fprintf(stderr, "sarea->exported_front_x: %d\n", sarea->exported_front_x);
fprintf(stderr, "sarea->exported_front_y: %d\n", sarea->exported_front_y);
fprintf(stderr, "sarea->exported_back_x: %d\n", sarea->exported_back_x);
fprintf(stderr, "sarea->exported_back_y: %d\n", sarea->exported_back_y);
fprintf(stderr, "sarea->exported_w: %d\n", sarea->exported_w);
fprintf(stderr, "sarea->exported_h: %d\n", sarea->exported_h);
fprintf(stderr, "sarea->exported_buffers: %d\n", sarea->exported_buffers);
fprintf(stderr, "sarea->exported_nfront: %d\n", sarea->exported_nfront);
fprintf(stderr, "sarea->exported_nback: %d\n", sarea->exported_nback);

i = 0;
if (sarea->exported_buffers & MGA_BACK)
for ( ; i < sarea->exported_nback ; i++)
fprintf(stderr, "back %d: %d,%d-%d,%d\n", i,
sarea->exported_boxes[i].x1, sarea->exported_boxes[i].y1,
sarea->exported_boxes[i].x2, sarea->exported_boxes[i].y2);

if (sarea->exported_buffers & MGA_FRONT) {
int start = i;
int top = i + sarea->exported_nfront;
for ( ; i < top ; i++)
fprintf(stderr, "front %d: %d,%d-%d,%d\n",
i - start,
sarea->exported_boxes[i].x1, sarea->exported_boxes[i].y1,
sarea->exported_boxes[i].x2, sarea->exported_boxes[i].y2);
}

fprintf(stderr, "drawableTable[%d].stamp: %d\n",
sarea->exported_index,
driScreen->pSAREA->drawableTable[sarea->exported_index].stamp);
}

static void printMmesaRects( mgaContextPtr mmesa )
{
__DRIscreenPrivate *driScreen = mmesa->driScreen;
__DRIdrawablePrivate *driDrawable = mmesa->driDrawable;
int nr = mmesa->numClipRects;
int i;

fprintf(stderr, "driDrawable->draw: %ld\n", driDrawable->draw);
fprintf(stderr, "driDrawable->index: %d\n", driDrawable->index);
fprintf(stderr, "driDrawable->lastStamp: %d\n", driDrawable->lastStamp);
fprintf(stderr, "mmesa->drawX: %d\n", mmesa->drawX);
fprintf(stderr, "mmesa->drawY: %d\n", mmesa->drawY);
fprintf(stderr, "driDrawable->w: %d\n", driDrawable->w);
fprintf(stderr, "driDrawable->h: %d\n", driDrawable->h);

for (i = 0 ; i < nr ; i++)
fprintf(stderr, "box %d: %d,%d-%d,%d\n", i,
mmesa->pClipRects[i].x1, mmesa->pClipRects[i].y1,
mmesa->pClipRects[i].x2, mmesa->pClipRects[i].y2);

fprintf(stderr, "mmesa->draw_buffer: %d\n", mmesa->draw_buffer);
fprintf(stderr, "drawableTable[%d].stamp: %d\n",
driDrawable->index,
driScreen->pSAREA->drawableTable[driDrawable->index].stamp);
}
#endif



void mgaUpdateRects( mgaContextPtr mmesa, GLuint buffers )
{
__DRIdrawablePrivate *driDrawable = mmesa->driDrawable;
MGASAREAPrivPtr sarea = mmesa->sarea;

/* fprintf(stderr, "%s\n", __FUNCTION__);*/

DRI_VALIDATE_DRAWABLE_INFO(driScreen, driDrawable);
mmesa->dirty_cliprects = 0;

if (mmesa->draw_buffer == MGA_FRONT)
mgaXMesaSetFrontClipRects( mmesa );
else
mgaXMesaSetBackClipRects( mmesa );

#if 0
printMmesaRects(mmesa);
#endif

sarea->req_draw_buffer = mmesa->draw_buffer;

mgaUpdateClipping( mmesa->glCtx );
mgaCalcViewport( mmesa->glCtx );

mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
}


void mgaDDSetReadBuffer(GLcontext *ctx, GLenum mode )
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);

if (mode == GL_FRONT_LEFT)
{
mmesa->readOffset = mmesa->mgaScreen->frontOffset;
mmesa->read_buffer = MGA_FRONT;
}
else
{
mmesa->readOffset = mmesa->mgaScreen->backOffset;
mmesa->read_buffer = MGA_BACK;
}
}

void mgaDDSetDrawBuffer(GLcontext *ctx, GLenum mode )
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);

FLUSH_BATCH( MGA_CONTEXT(ctx) );

/* fprintf( stderr, "%s %d\n", __FUNCTION__, mode);*/

/*
* _DrawDestMask is easier to cope with than <mode>.
*/
switch ( ctx->Color._DrawDestMask ) {
case FRONT_LEFT_BIT:
mmesa->drawOffset = mmesa->mgaScreen->frontOffset;
mmesa->readOffset = mmesa->mgaScreen->frontOffset;
mmesa->setup.dstorg = mmesa->mgaScreen->frontOffset;
mmesa->dirty |= MGA_UPLOAD_CONTEXT;
mmesa->draw_buffer = MGA_FRONT;
mgaXMesaSetFrontClipRects( mmesa );
FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_FALSE );
break;
case BACK_LEFT_BIT:
mmesa->drawOffset = mmesa->mgaScreen->backOffset;
mmesa->readOffset = mmesa->mgaScreen->backOffset;
mmesa->setup.dstorg = mmesa->mgaScreen->backOffset;
mmesa->draw_buffer = MGA_BACK;
mmesa->dirty |= MGA_UPLOAD_CONTEXT;
mgaXMesaSetBackClipRects( mmesa );
FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_FALSE );
break;
default:
FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_TRUE );
break;
}
}


+ 37
- 0
src/mesa/drivers/dri/mga/mgabuffers.h Visa fil

@@ -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

+ 309
- 0
src/mesa/drivers/dri/mga/mgacontext.h Visa fil

@@ -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

+ 171
- 0
src/mesa/drivers/dri/mga/mgadd.c Visa fil

@@ -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;
}

+ 37
- 0
src/mesa/drivers/dri/mga/mgadd.h Visa fil

@@ -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

+ 693
- 0
src/mesa/drivers/dri/mga/mgaioctl.c Visa fil

@@ -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;
}

+ 113
- 0
src/mesa/drivers/dri/mga/mgaioctl.h Visa fil

@@ -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

+ 690
- 0
src/mesa/drivers/dri/mga/mgapixel.c Visa fil

@@ -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 */
}
}

+ 36
- 0
src/mesa/drivers/dri/mga/mgapixel.h Visa fil

@@ -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

+ 1381
- 0
src/mesa/drivers/dri/mga/mgaregs.h
Filskillnaden har hållits tillbaka eftersom den är för stor
Visa fil


+ 208
- 0
src/mesa/drivers/dri/mga/mgarender.c Visa fil

@@ -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 */
};

+ 284
- 0
src/mesa/drivers/dri/mga/mgaspan.c Visa fil

@@ -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;
}
}

+ 34
- 0
src/mesa/drivers/dri/mga/mgaspan.h Visa fil

@@ -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

+ 1131
- 0
src/mesa/drivers/dri/mga/mgastate.c
Filskillnaden har hållits tillbaka eftersom den är för stor
Visa fil


+ 42
- 0
src/mesa/drivers/dri/mga/mgastate.h Visa fil

@@ -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

+ 985
- 0
src/mesa/drivers/dri/mga/mgatex.c Visa fil

@@ -0,0 +1,985 @@
/*
* Copyright 2000-2001 VA Linux Systems, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
*/
/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatex.c,v 1.14 2002/10/30 12:51:36 alanh Exp $ */

#include <stdlib.h>
#include <stdio.h>
#include <GL/gl.h>

#include "mm.h"
#include "mgacontext.h"
#include "mgatex.h"
#include "mgaregs.h"
#include "mgatris.h"
#include "mgaioctl.h"

#include "enums.h"
#include "simple_list.h"
/*#include "mem.h"*/
#include "macros.h"
#include "texformat.h"
#include "texstore.h"
#include "teximage.h"

#include "swrast/swrast.h"

#define TEX_0 1
#define TEX_1 2

/*
* mgaDestroyTexObj
* Free all memory associated with a texture and NULL any pointers
* to it.
*/
void
mgaDestroyTexObj( mgaContextPtr mmesa, mgaTextureObjectPtr t )
{
if ( !t ) return;

/* free the texture memory */
if (t->MemBlock) {
mmFreeMem( t->MemBlock );
t->MemBlock = 0;

if (mmesa && t->age > mmesa->dirtyAge)
mmesa->dirtyAge = t->age;
}

/* free mesa's link */
if (t->tObj)
t->tObj->DriverData = NULL;

/* see if it was the driver's current object */
if (mmesa) {
if (t->bound & TEX_0) mmesa->CurrentTexObj[0] = 0;
if (t->bound & TEX_1) mmesa->CurrentTexObj[1] = 0;
}
remove_from_list(t);
free( t );
}


/*
* mgaSetTexWrappings
*/
static void mgaSetTexWrapping( mgaTextureObjectPtr t,
GLenum sWrap,
GLenum tWrap )
{
GLuint val = 0;

if (sWrap != GL_REPEAT)
val |= TMC_clampu_enable;

if (tWrap != GL_REPEAT)
val |= TMC_clampv_enable;

t->setup.texctl &= ~(TMC_clampu_enable|TMC_clampv_enable);
t->setup.texctl |= val;
}


/*
* mgaSetTexFilter
*/
static void mgaSetTexFilter(mgaTextureObjectPtr t, GLenum minf, GLenum magf)
{
GLuint val = 0;

switch (minf) {
case GL_NEAREST: val = TF_minfilter_nrst; break;
case GL_LINEAR: val = TF_minfilter_bilin; break;
case GL_NEAREST_MIPMAP_NEAREST: val = TF_minfilter_mm1s; break;
case GL_LINEAR_MIPMAP_NEAREST: val = TF_minfilter_mm4s; break;
case GL_NEAREST_MIPMAP_LINEAR: val = TF_minfilter_mm2s; break;
case GL_LINEAR_MIPMAP_LINEAR: val = TF_minfilter_mm8s; break;
default: val = TF_minfilter_nrst; break;
}

switch (magf) {
case GL_NEAREST: val |= TF_magfilter_nrst; break;
case GL_LINEAR: val |= TF_magfilter_bilin; break;
default: val |= TF_magfilter_nrst; break;
}

/* See OpenGL 1.2 specification */
if (magf == GL_LINEAR && (minf == GL_NEAREST_MIPMAP_NEAREST ||
minf == GL_NEAREST_MIPMAP_LINEAR)) {
val |= (0x20 << TF_fthres_SHIFT); /* c = 0.5 */
} else {
val |= (0x10 << TF_fthres_SHIFT); /* c = 0 */
}


t->setup.texfilter &= (TF_minfilter_MASK |
TF_magfilter_MASK |
TF_fthres_MASK);
t->setup.texfilter |= val;
}

/*
* mgaSetTexBorderColor
*/
static void mgaSetTexBorderColor(mgaTextureObjectPtr t, GLubyte color[4])
{
t->setup.texbordercol = MGAPACKCOLOR8888(color[0],color[1],
color[2],color[3]);
}


static GLint mgaChooseTexFormat( mgaContextPtr mmesa,
struct gl_texture_image *texImage,
GLenum format, GLenum type )
{
const GLboolean do32bpt = mmesa->default32BitTextures;
const struct gl_texture_format *texFormat;
GLint ret;

if ( 0 )
fprintf( stderr, "internal=%s format=%s type=%s\n",
texImage->IntFormat == 3 ? "GL_RGB (3)" :
texImage->IntFormat == 4 ? "GL_RGBA (4)" :
_mesa_lookup_enum_by_nr( texImage->IntFormat ),
_mesa_lookup_enum_by_nr( format ),
_mesa_lookup_enum_by_nr( type ) );

#define SET_FORMAT( r, gl ) \
do { \
ret = (r); \
texFormat = &(gl); \
} while (0)

#define SET_FORMAT_32BPT( r32, gl32, r16, gl16 ) \
do { \
if ( do32bpt ) { \
ret = (r32); \
texFormat = &(gl32); \
} else { \
ret = (r16); \
texFormat = &(gl16); \
} \
} while (0)

switch ( texImage->IntFormat ) {
/* GH: Bias towards GL_RGB, GL_RGBA texture formats. This has
* got to be better than sticking them way down the end of this
* huge list.
*/
case 4:
case GL_RGBA:
case GL_COMPRESSED_RGBA:
if ( format == GL_BGRA ) {
if ( type == GL_UNSIGNED_INT_8_8_8_8_REV ) {
SET_FORMAT( TMC_tformat_tw32, _mesa_texformat_argb8888 );
break;
} else if ( type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) {
SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 );
break;
} else if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) {
SET_FORMAT( TMC_tformat_tw15, _mesa_texformat_argb1555 );
break;
}
}
SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888,
TMC_tformat_tw12, _mesa_texformat_argb4444 );
break;

case 3:
case GL_RGB:
case GL_COMPRESSED_RGB:
if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) {
SET_FORMAT( TMC_tformat_tw16, _mesa_texformat_rgb565 );
break;
}
SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888,
TMC_tformat_tw16, _mesa_texformat_rgb565 );
break;

/* GH: Okay, keep checking as normal. Still test for GL_RGB,
* GL_RGBA formats first.
*/
case GL_RGBA8:
case GL_RGB10_A2:
case GL_RGBA12:
case GL_RGBA16:
SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888,
TMC_tformat_tw12, _mesa_texformat_argb4444 );
break;

case GL_RGBA4:
case GL_RGBA2:
SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 );
break;

case GL_RGB5_A1:
SET_FORMAT( TMC_tformat_tw15, _mesa_texformat_argb1555 );
break;

case GL_RGB8:
case GL_RGB10:
case GL_RGB12:
case GL_RGB16:
SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888,
TMC_tformat_tw16, _mesa_texformat_rgb565 );
break;

case GL_RGB5:
case GL_RGB4:
case GL_R3_G3_B2:
SET_FORMAT( TMC_tformat_tw16, _mesa_texformat_rgb565 );
break;

case GL_ALPHA:
case GL_ALPHA4:
case GL_ALPHA8:
case GL_ALPHA12:
case GL_ALPHA16:
case GL_COMPRESSED_ALPHA:
/* FIXME: This will report incorrect component sizes... */
SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 );
break;

case 1:
case GL_LUMINANCE:
case GL_LUMINANCE4:
case GL_LUMINANCE8:
case GL_LUMINANCE12:
case GL_LUMINANCE16:
case GL_COMPRESSED_LUMINANCE:
/* FIXME: This will report incorrect component sizes... */
SET_FORMAT( TMC_tformat_tw16, _mesa_texformat_rgb565 );
break;

case 2:
case GL_LUMINANCE_ALPHA:
case GL_LUMINANCE4_ALPHA4:
case GL_LUMINANCE6_ALPHA2:
case GL_LUMINANCE8_ALPHA8:
case GL_LUMINANCE12_ALPHA4:
case GL_LUMINANCE12_ALPHA12:
case GL_LUMINANCE16_ALPHA16:
case GL_COMPRESSED_LUMINANCE_ALPHA:
/* FIXME: This will report incorrect component sizes... */
SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 );
break;

case GL_INTENSITY:
case GL_INTENSITY4:
case GL_INTENSITY8:
case GL_INTENSITY12:
case GL_INTENSITY16:
case GL_COMPRESSED_INTENSITY:
/* FIXME: This will report incorrect component sizes... */
SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 );
break;

case GL_COLOR_INDEX:
case GL_COLOR_INDEX1_EXT:
case GL_COLOR_INDEX2_EXT:
case GL_COLOR_INDEX4_EXT:
case GL_COLOR_INDEX8_EXT:
case GL_COLOR_INDEX12_EXT:
case GL_COLOR_INDEX16_EXT:
SET_FORMAT( TMC_tformat_tw8, _mesa_texformat_ci8 );
break;

default:
fprintf( stderr, "bad texture format in mgaChooseTexFormat() %d",
texImage->IntFormat );
return -1;
}

texImage->TexFormat = texFormat;

return ret;
}


/*
* mgaCreateTexObj
* Allocate space for and load the mesa images into the texture memory block.
* This will happen before drawing with a new texture, or drawing with a
* texture after it was swapped out or teximaged again.
*/
static void mgaCreateTexObj(mgaContextPtr mmesa,
struct gl_texture_object *tObj)
{
const GLint baseLevel = tObj->BaseLevel;
struct gl_texture_image *image = tObj->Image[baseLevel];
mgaTextureObjectPtr t;
int i, ofs;
int LastLevel;
int s, s2;
int tformat;

if (!image) return;

tObj->DriverData = t = calloc( 1, sizeof( *t ) );
if (!t) {
fprintf(stderr, "mgaCreateTexObj: Failed to malloc mgaTextureObject\n" );
return;
}

/* FIXME: Use the real DD interface...
*/
tformat = mgaChooseTexFormat( mmesa, image, image->Format,
GL_UNSIGNED_BYTE );
t->texelBytes = image->TexFormat->TexelBytes;

/* We are going to upload all levels that are present, even if
* later levels wouldn't be used by the current filtering mode. This
* allows the filtering mode to change without forcing another upload
* of the images.
*/
LastLevel = MGA_TEX_MAXLEVELS-1;

ofs = 0;
for ( i = 0 ; i <= LastLevel ; i++ ) {
if ( !tObj->Image[i] ) {
LastLevel = i - 1;
break;
}

t->offsets[i] = ofs;
t->dirty_images |= (1<<i);

ofs += ((MAX2( tObj->Image[i]->Width, 8 ) *
MAX2( tObj->Image[i]->Height, 8 ) *
t->texelBytes) + 31) & ~31;
}
t->totalSize = ofs;
t->lastLevel = LastLevel;
t->tObj = tObj;
t->ctx = mmesa;
t->age = 0;
t->bound = 0;
t->MemBlock = 0;

insert_at_tail(&(mmesa->SwappedOut), t);


/* setup hardware register values */
t->setup.texctl = TMC_takey_1 | TMC_tamask_0 | tformat;

if (image->WidthLog2 >= 3)
t->setup.texctl |= ((image->WidthLog2 - 3) << TMC_tpitch_SHIFT);
else
t->setup.texctl |= (TMC_tpitchlin_enable |
(image->Width << TMC_tpitchext_SHIFT));


t->setup.texctl2 = TMC_ckstransdis_enable;

if ( mmesa->glCtx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR )
t->setup.texctl2 |= TMC_specen_enable;


t->setup.texfilter = (TF_minfilter_nrst |
TF_magfilter_nrst |
TF_filteralpha_enable |
(0x10 << TF_fthres_SHIFT) |
(LastLevel << TF_mapnb_SHIFT));

/* warp texture registers */
ofs = MGA_IS_G200(mmesa) ? 28 : 11;
s = image->Width;
s2 = image->WidthLog2;
t->setup.texwidth = (MGA_FIELD(TW_twmask, s - 1) |
MGA_FIELD(TW_rfw, (10 - s2 - 8) & 63 ) |
MGA_FIELD(TW_tw, (s2 + ofs ) | 0x40 ));


s = image->Height;
s2 = image->HeightLog2;
t->setup.texheight = (MGA_FIELD(TH_thmask, s - 1) |
MGA_FIELD(TH_rfh, (10 - s2 - 8) & 63 ) |
MGA_FIELD(TH_th, (s2 + ofs ) | 0x40 ));


/* set all the register values for filtering, border, etc */
mgaSetTexWrapping( t, tObj->WrapS, tObj->WrapT );
mgaSetTexFilter( t, tObj->MinFilter, tObj->MagFilter );
mgaSetTexBorderColor( t, tObj->_BorderChan );
}




static void mgaUpdateTextureEnvG200( GLcontext *ctx )
{
struct gl_texture_object *tObj = ctx->Texture.Unit[0]._Current;
mgaTextureObjectPtr t;

if (!tObj || !tObj->DriverData)
return;

t = (mgaTextureObjectPtr)tObj->DriverData;

t->setup.texctl2 &= ~TMC_decalblend_enable;

switch (ctx->Texture.Unit[0].EnvMode) {
case GL_REPLACE:
t->setup.texctl &= ~TMC_tmodulate_enable;
break;
case GL_MODULATE:
t->setup.texctl |= TMC_tmodulate_enable;
break;
case GL_DECAL:
t->setup.texctl &= ~TMC_tmodulate_enable;
t->setup.texctl2 |= TMC_decalblend_enable;
break;
case GL_BLEND:
FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE );
break;
default:
break;
}
}

static void mgaUpdateTextureEnvG400( GLcontext *ctx, int unit )
{
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
GLuint *reg = ((GLuint *)&mmesa->setup.tdualstage0 + unit);
GLuint source = mmesa->tmu_source[unit];
struct gl_texture_object *tObj = ctx->Texture.Unit[source]._Current;
GLenum format;

if ( tObj != ctx->Texture.Unit[source].Current2D || !tObj )
return;

format = tObj->Image[tObj->BaseLevel]->Format;

switch (ctx->Texture.Unit[source].EnvMode) {
case GL_REPLACE:
if (format == GL_RGB || format == GL_LUMINANCE) {
*reg = (TD0_color_sel_arg1 |
TD0_alpha_arg2_diffuse |
TD0_alpha_sel_arg2 );
}
else if (format == GL_ALPHA) {
*reg = (TD0_color_sel_arg2 |
TD0_color_arg2_diffuse |
TD0_alpha_sel_arg1 );
}
else {
*reg = (TD0_color_sel_arg1 |
TD0_alpha_sel_arg1 );
}
break;

case GL_MODULATE:
if (unit == 0) {
*reg = ( TD0_color_arg2_diffuse |
TD0_color_sel_mul |
TD0_alpha_arg2_diffuse |
TD0_alpha_sel_mul);
}
else {
*reg = ( TD0_color_arg2_prevstage |
TD0_color_alpha_prevstage |
TD0_color_sel_mul |
TD0_alpha_arg2_prevstage |
TD0_alpha_sel_mul);
}
break;
case GL_DECAL:
if (format == GL_RGB) {
if (unit == 0) {
*reg = (TD0_color_sel_arg1 |
TD0_alpha_arg2_diffuse |
TD0_alpha_sel_arg2 );
}
else {
*reg = (TD0_color_sel_arg1 |
TD0_alpha_arg2_prevstage |
TD0_alpha_sel_arg2 );
}
}
else if ( format == GL_RGBA ) {
#if 0
if (unit == 0) {
/* this doesn't work */
*reg = (TD0_color_arg2_diffuse |
TD0_color_alpha_currtex |
TD0_color_alpha2inv_enable |
TD0_color_arg2mul_alpha2 |
TD0_color_arg1mul_alpha1 |
TD0_color_blend_enable |
TD0_color_arg1add_mulout |
TD0_color_arg2add_mulout |
TD0_color_add_add |
TD0_color_sel_mul |
TD0_alpha_arg2_diffuse |
TD0_alpha_sel_arg2 );
}
else {
*reg = (TD0_color_arg2_prevstage |
TD0_color_alpha_currtex |
TD0_color_alpha2inv_enable |
TD0_color_arg2mul_alpha2 |
TD0_color_arg1mul_alpha1 |
TD0_color_add_add |
TD0_color_sel_add |
TD0_alpha_arg2_prevstage |
TD0_alpha_sel_arg2 );
}
#else
/* s/w fallback, pretty sure we can't do in h/w */
FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE );
if ( MGA_DEBUG & DEBUG_VERBOSE_FALLBACK )
fprintf( stderr, "FALLBACK: GL_DECAL RGBA texture, unit=%d\n",
unit );
#endif
}
else {
if (unit == 0) {
*reg = ( TD0_color_arg2_diffuse |
TD0_color_sel_arg2 |
TD0_alpha_arg2_diffuse |
TD0_alpha_sel_arg2);
}
else {
*reg = ( TD0_color_arg2_prevstage |
TD0_color_sel_arg2 |
TD0_alpha_arg2_prevstage |
TD0_alpha_sel_arg2);
}
}
break;

case GL_ADD:
if (unit == 0) {
if (format == GL_INTENSITY)
*reg = ( TD0_color_arg2_diffuse |
TD0_color_add_add |
TD0_color_sel_add |
TD0_alpha_arg2_diffuse |
TD0_alpha_add_enable |
TD0_alpha_sel_add);
else if (format == GL_ALPHA)
*reg = ( TD0_color_arg2_diffuse |
TD0_color_sel_mul |
TD0_alpha_arg2_diffuse |
TD0_alpha_sel_mul);
else
*reg = ( TD0_color_arg2_diffuse |
TD0_color_add_add |
TD0_color_sel_add |
TD0_alpha_arg2_diffuse |
TD0_alpha_sel_mul);
}
else {
if (format == GL_INTENSITY) {
*reg = ( TD0_color_arg2_prevstage |
TD0_color_add_add |
TD0_color_sel_add |
TD0_alpha_arg2_prevstage |
TD0_alpha_add_enable |
TD0_alpha_sel_add);
}
else if (format == GL_ALPHA) {
*reg = ( TD0_color_arg2_prevstage |
TD0_color_sel_mul |
TD0_alpha_arg2_prevstage |
TD0_alpha_sel_mul);
}
else {
*reg = ( TD0_color_arg2_prevstage |
TD0_color_alpha_prevstage |
TD0_color_add_add |
TD0_color_sel_add |
TD0_alpha_arg2_prevstage |
TD0_alpha_sel_mul);
}
}
break;

case GL_BLEND:
if (format == GL_ALPHA) {
*reg = ( TD0_color_arg2_diffuse |
TD0_color_sel_mul |
TD0_alpha_arg2_diffuse |
TD0_alpha_sel_mul);
}
else {
FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE );
if ( MGA_DEBUG & DEBUG_VERBOSE_FALLBACK )
fprintf( stderr, "FALLBACK: GL_BLEND envcolor=0x%08x\n",
mmesa->envcolor );

/* Do singletexture GL_BLEND with 'all ones' env-color
* by using both texture units. Multitexture gl_blend
* is a fallback.
*/
if (unit == 0) {
/* Part 1: R1 = Rf ( 1 - Rt )
* A1 = Af At
*/
*reg = ( TD0_color_arg2_diffuse |
TD0_color_arg1_inv_enable |
TD0_color_sel_mul |
TD0_alpha_arg2_diffuse |
TD0_alpha_sel_arg1);
} else {
/* Part 2: R2 = R1 + Rt
* A2 = A1
*/
*reg = ( TD0_color_arg2_prevstage |
TD0_color_add_add |
TD0_color_sel_add |
TD0_alpha_arg2_prevstage |
TD0_alpha_sel_arg2);
}
}
break;
default:
break;
}
}



static void mgaUpdateTextureObject( GLcontext *ctx, int hw_unit )
{
mgaTextureObjectPtr t;
struct gl_texture_object *tObj;
GLuint enabled;
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
GLuint gl_unit = mmesa->tmu_source[hw_unit];


enabled = ctx->Texture.Unit[gl_unit]._ReallyEnabled;
tObj = ctx->Texture.Unit[gl_unit]._Current;

if (enabled != TEXTURE_2D_BIT) {
if (enabled)
FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE );
return;
}

if (tObj->Image[tObj->BaseLevel]->Border > 0) {
FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE );
if ( MGA_DEBUG & DEBUG_VERBOSE_FALLBACK )
fprintf( stderr, "FALLBACK: texture border\n" );
return;
}

if ( !tObj->DriverData ) {
mgaCreateTexObj( mmesa, tObj );
if ( !tObj->DriverData ) {
FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE );
return;
}
}

t = (mgaTextureObjectPtr)tObj->DriverData;

if (t->dirty_images)
mmesa->dirty |= (MGA_UPLOAD_TEX0IMAGE << hw_unit);

mmesa->CurrentTexObj[hw_unit] = t;
t->bound |= hw_unit+1;

/* if (t->MemBlock) */
/* mgaUpdateTexLRU( mmesa, t ); */

t->setup.texctl2 &= ~TMC_dualtex_enable;
if ((ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT) &&
(ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT))
t->setup.texctl2 |= TMC_dualtex_enable;

t->setup.texctl2 &= ~TMC_specen_enable;
if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
t->setup.texctl2 |= TMC_specen_enable;
}






/* The G400 is now programmed quite differently wrt texture environment.
*/
void mgaUpdateTextureState( GLcontext *ctx )
{
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_FALSE );

if (mmesa->CurrentTexObj[0]) {
mmesa->CurrentTexObj[0]->bound = 0;
mmesa->CurrentTexObj[0] = 0;
}

if (mmesa->CurrentTexObj[1]) {
mmesa->CurrentTexObj[1]->bound = 0;
mmesa->CurrentTexObj[1] = 0;
}

if (ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT) {
mmesa->tmu_source[0] = 1;
} else {
mmesa->tmu_source[0] = 0;
}

if (MGA_IS_G400(mmesa)) {
mgaUpdateTextureObject( ctx, 0 );
mgaUpdateTextureEnvG400( ctx, 0 );

mmesa->setup.tdualstage1 = mmesa->setup.tdualstage0;
if ((ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT) &&
(ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT)) {
mgaUpdateTextureObject( ctx, 1 );
mgaUpdateTextureEnvG400( ctx, 1 );
mmesa->dirty |= MGA_UPLOAD_TEX1;
}
} else {
mgaUpdateTextureObject( ctx, 0 );
mgaUpdateTextureEnvG200( ctx );
}

mmesa->dirty |= MGA_UPLOAD_CONTEXT | MGA_UPLOAD_TEX0;

mmesa->setup.dwgctl &= DC_opcod_MASK;
mmesa->setup.dwgctl |= (ctx->Texture.Unit[0]._ReallyEnabled
? DC_opcod_texture_trap
: DC_opcod_trap);
}




static void mgaDDTexEnv( GLcontext *ctx, GLenum target,
GLenum pname, const GLfloat *param )
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);


if (pname == GL_TEXTURE_ENV_MODE) {
/* force the texture state to be updated */
FLUSH_BATCH( MGA_CONTEXT(ctx) );
MGA_CONTEXT(ctx)->new_state |= (MGA_NEW_TEXTURE |
MGA_NEW_ALPHA);
}
else if (pname == GL_TEXTURE_ENV_COLOR)
{
struct gl_texture_unit *texUnit =
&ctx->Texture.Unit[ctx->Texture.CurrentUnit];
GLfloat *fc = texUnit->EnvColor;
GLubyte c[4];
GLuint col;

COPY_4V(c, fc);
col = mgaPackColor( mmesa->mgaScreen->cpp, c[0], c[1], c[2], c[3] );
mmesa->envcolor = (c[3]<<24) | (c[0]<<16) | (c[1]<<8) | (c[2]);

if (mmesa->setup.fcol != col) {
FLUSH_BATCH(mmesa);
mmesa->setup.fcol = col;
mmesa->dirty |= MGA_UPLOAD_CONTEXT;

mmesa->blend_flags &= ~MGA_BLEND_ENV_COLOR;

/* Actually just require all four components to be
* equal. This permits a single-pass GL_BLEND.
*
* More complex multitexture/multipass fallbacks
* for blend can be done later.
*/
if (mmesa->envcolor != 0x0 && mmesa->envcolor != 0xffffffff)
mmesa->blend_flags |= MGA_BLEND_ENV_COLOR;
}
}
}


static void mgaTexImage2D( GLcontext *ctx, GLenum target, GLint level,
GLint internalFormat,
GLint width, GLint height, GLint border,
GLenum format, GLenum type, const GLvoid *pixels,
const struct gl_pixelstore_attrib *packing,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage )
{
mgaTextureObjectPtr t = (mgaTextureObjectPtr) texObj->DriverData;
if (t) {
mgaDestroyTexObj( MGA_CONTEXT(ctx), t );
texObj->DriverData = 0;
}
_mesa_store_teximage2d( ctx, target, level, internalFormat,
width, height, border, format, type,
pixels, packing, texObj, texImage );
}

static void mgaTexSubImage2D( GLcontext *ctx,
GLenum target,
GLint level,
GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height,
GLenum format, GLenum type,
const GLvoid *pixels,
const struct gl_pixelstore_attrib *packing,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage )
{
mgaTextureObjectPtr t = (mgaTextureObjectPtr) texObj->DriverData;
if (t) {
mgaDestroyTexObj( MGA_CONTEXT(ctx), t );
texObj->DriverData = 0;
}
_mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
height, format, type, pixels, packing, texObj,
texImage);

}




/*
* mgaTexParameter
* This just changes variables and flags for a state update, which
* will happen at the next mgaUpdateTextureState
*/
static void
mgaDDTexParameter( GLcontext *ctx, GLenum target,
struct gl_texture_object *tObj,
GLenum pname, const GLfloat *params )
{
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
mgaTextureObjectPtr t;

t = (mgaTextureObjectPtr) tObj->DriverData;

/* if we don't have a hardware texture, it will be automatically
created with current state before it is used, so we don't have
to do anything now */
if ( !t || !t->bound || target != GL_TEXTURE_2D ) {
return;
}

switch (pname) {
case GL_TEXTURE_MIN_FILTER:
case GL_TEXTURE_MAG_FILTER:
FLUSH_BATCH(mmesa);
mgaSetTexFilter( t, tObj->MinFilter, tObj->MagFilter );
break;

case GL_TEXTURE_WRAP_S:
case GL_TEXTURE_WRAP_T:
FLUSH_BATCH(mmesa);
mgaSetTexWrapping(t,tObj->WrapS,tObj->WrapT);
break;

case GL_TEXTURE_BORDER_COLOR:
FLUSH_BATCH(mmesa);
mgaSetTexBorderColor(t,tObj->_BorderChan);
break;

default:
return;
}

mmesa->new_state |= MGA_NEW_TEXTURE;
}


static void
mgaDDBindTexture( GLcontext *ctx, GLenum target,
struct gl_texture_object *tObj )
{
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
int unit = ctx->Texture.CurrentUnit;

FLUSH_BATCH(mmesa);

if (mmesa->CurrentTexObj[unit]) {
mmesa->CurrentTexObj[unit]->bound &= ~(unit+1);
mmesa->CurrentTexObj[unit] = 0;
}

/* force the texture state to be updated
*/
MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE;
}


static void
mgaDDDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj )
{
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
mgaTextureObjectPtr t = (mgaTextureObjectPtr)tObj->DriverData;

if ( t ) {
if (mmesa) {
if (t->bound) {
FLUSH_BATCH(mmesa);
if (t->bound & TEX_0) mmesa->CurrentTexObj[0] = 0;
if (t->bound & TEX_1) mmesa->CurrentTexObj[1] = 0;
}
mmesa->new_state |= MGA_NEW_TEXTURE;
}

mgaDestroyTexObj( mmesa, t );
}
}


static GLboolean
mgaDDIsTextureResident( GLcontext *ctx, struct gl_texture_object *t )
{
mgaTextureObjectPtr mt = (mgaTextureObjectPtr)t->DriverData;
return mt && mt->MemBlock;
}


void
mgaDDInitTextureFuncs( GLcontext *ctx )
{
ctx->Driver.TexEnv = mgaDDTexEnv;

ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
ctx->Driver.TexImage1D = _mesa_store_teximage1d;
ctx->Driver.TexImage2D = mgaTexImage2D;
ctx->Driver.TexImage3D = _mesa_store_teximage3d;
ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
ctx->Driver.TexSubImage2D = mgaTexSubImage2D;
ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;

ctx->Driver.BindTexture = mgaDDBindTexture;
ctx->Driver.DeleteTexture = mgaDDDeleteTexture;
ctx->Driver.TexParameter = mgaDDTexParameter;
ctx->Driver.UpdateTexturePalette = 0;
ctx->Driver.IsTextureResident = mgaDDIsTextureResident;
}

+ 62
- 0
src/mesa/drivers/dri/mga/mgatex.h Visa fil

@@ -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

+ 256
- 0
src/mesa/drivers/dri/mga/mgatexcnv.c Visa fil

@@ -0,0 +1,256 @@
/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatexcnv.c,v 1.3 2002/10/30 12:51:36 alanh Exp $ */
/*
* Copyright 2000-2001 VA Linux Systems, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
*/

#include <stdlib.h>
#include <stdio.h>

#include <GL/gl.h>

#include "mm.h"
#include "mgacontext.h"
#include "mgatex.h"


/*
* mgaConvertTexture
* Converts a mesa format texture to the appropriate hardware format
* Note that sometimes width may be larger than the texture, like 64x1
* for an 8x8 texture. This happens when we have to crutch the pitch
* limits of the mga by uploading a block of texels as a single line.
*/
void mgaConvertTexture( GLuint *destPtr, int texelBytes,
struct gl_texture_image *image,
int x, int y, int width, int height )
{
register int i, j;
GLubyte *src;
int stride;

if (0)
fprintf(stderr, "texture image %p\n", image->Data);

if (image->Data == 0)
return;

/* FIXME: g400 luminance_alpha internal format */
switch (texelBytes) {
case 1:
switch (image->Format) {
case GL_COLOR_INDEX:
case GL_INTENSITY:
case GL_LUMINANCE:
case GL_ALPHA:
src = (GLubyte *)image->Data + ( y * image->Width + x );
stride = (image->Width - width);
for ( i = height ; i ; i-- ) {
for ( j = width >> 2 ; j ; j-- ) {

*destPtr++ = src[0] | ( src[1] << 8 ) | ( src[2] << 16 ) | ( src[3] << 24 );
src += 4;
}
src += stride;
}
break;
default:
goto format_error;
}
break;
case 2:
switch (image->Format) {
case GL_RGB:
src = (GLubyte *)image->Data + ( y * image->Width + x ) * 3;
stride = (image->Width - width) * 3;
for ( i = height ; i ; i-- ) {
for ( j = width >> 1 ; j ; j-- ) {

*destPtr++ = MGAPACKCOLOR565(src[0],src[1],src[2]) |
( MGAPACKCOLOR565(src[3],src[4],src[5]) << 16 );
src += 6;
}
src += stride;
}
break;
case GL_RGBA:
src = (GLubyte *)image->Data + ( y * image->Width + x ) * 4;
stride = (image->Width - width) * 4;
for ( i = height ; i ; i-- ) {
for ( j = width >> 1 ; j ; j-- ) {

*destPtr++ = MGAPACKCOLOR4444(src[0],src[1],src[2],src[3]) |
( MGAPACKCOLOR4444(src[4],src[5],src[6],src[7]) << 16 );
src += 8;
}
src += stride;
}
break;
case GL_LUMINANCE:
src = (GLubyte *)image->Data + ( y * image->Width + x );
stride = (image->Width - width);
for ( i = height ; i ; i-- ) {
for ( j = width >> 1 ; j ; j-- ) {
/* FIXME: should probably use 555 texture to get true grey */
*destPtr++ = MGAPACKCOLOR565(src[0],src[0],src[0]) |
( MGAPACKCOLOR565(src[1],src[1],src[1]) << 16 );
src += 2;
}
src += stride;
}
break;
case GL_INTENSITY:
src = (GLubyte *)image->Data + ( y * image->Width + x );
stride = (image->Width - width);
for ( i = height ; i ; i-- ) {
for ( j = width >> 1 ; j ; j-- ) {

*destPtr++ = MGAPACKCOLOR4444(src[0],src[0],src[0],src[0]) |
( MGAPACKCOLOR4444(src[1],src[1],src[1],src[1]) << 16 );
src += 2;
}
src += stride;
}
break;
case GL_ALPHA:
src = (GLubyte *)image->Data + ( y * image->Width + x );
stride = (image->Width - width);
for ( i = height ; i ; i-- ) {
for ( j = width >> 1 ; j ; j-- ) {

*destPtr++ = MGAPACKCOLOR4444(255,255,255,src[0]) |
( MGAPACKCOLOR4444(255,255,255,src[1]) << 16 );
src += 2;
}
src += stride;
}
break;
case GL_LUMINANCE_ALPHA:
src = (GLubyte *)image->Data + ( y * image->Width + x ) * 2;
stride = (image->Width - width) * 2;
for ( i = height ; i ; i-- ) {
for ( j = width >> 1 ; j ; j-- ) {

*destPtr++ = MGAPACKCOLOR4444(src[0],src[0],src[0],src[1]) |
( MGAPACKCOLOR4444(src[2],src[2],src[2],src[3]) << 16 );
src += 4;
}
src += stride;
}
break;
default:
goto format_error;
}
break;
case 4:
switch (image->Format) {
case GL_RGB:
src = (GLubyte *)image->Data + ( y * image->Width + x ) * 3;
stride = (image->Width - width) * 3;
for ( i = height ; i ; i-- ) {
for ( j = width ; j ; j-- ) {

*destPtr++ = MGAPACKCOLOR8888(src[0],src[1],src[2], 255);
src += 3;
}
src += stride;
}
break;
case GL_RGBA:
src = (GLubyte *)image->Data + ( y * image->Width + x ) * 4;
stride = (image->Width - width) * 4;
for ( i = height ; i ; i-- ) {
for ( j = width ; j ; j-- ) {

*destPtr++ = MGAPACKCOLOR8888(src[0],src[1],src[2],src[3]);
src += 4;
}
src += stride;
}
break;
case GL_LUMINANCE:
src = (GLubyte *)image->Data + ( y * image->Width + x );
stride = (image->Width - width);
for ( i = height ; i ; i-- ) {
for ( j = width ; j ; j-- ) {

*destPtr++ = MGAPACKCOLOR8888(src[0],src[0],src[0], 255);
src += 1;
}
src += stride;
}
break;
case GL_INTENSITY:
src = (GLubyte *)image->Data + ( y * image->Width + x );
stride = (image->Width - width);
for ( i = height ; i ; i-- ) {
for ( j = width ; j ; j-- ) {

*destPtr++ = MGAPACKCOLOR8888(src[0],src[0],src[0],src[0]);
src += 1;
}
src += stride;
}
break;
case GL_ALPHA:
src = (GLubyte *)image->Data + ( y * image->Width + x );
stride = (image->Width - width);
for ( i = height ; i ; i-- ) {
for ( j = width ; j ; j-- ) {

*destPtr++ = MGAPACKCOLOR8888(255,255,255,src[0]);
src += 1;
}
src += stride;
}
break;
case GL_LUMINANCE_ALPHA:
src = (GLubyte *)image->Data + ( y * image->Width + x ) * 2;
stride = (image->Width - width) * 2;
for ( i = height ; i ; i-- ) {
for ( j = width ; j ; j-- ) {

*destPtr++ = MGAPACKCOLOR8888(src[0],src[0],
src[0],src[1]);
src += 2;
}
src += stride;
}
break;
default:
goto format_error;
}
break;
default:
goto format_error;
}

return;

format_error:

fprintf(stderr, "Unsupported texelBytes %i, image->Format %i\n",
(int)texelBytes, (int)image->Format );
}

+ 564
- 0
src/mesa/drivers/dri/mga/mgatexmem.c Visa fil

@@ -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;
}

+ 915
- 0
src/mesa/drivers/dri/mga/mgatris.c Visa fil

@@ -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;
}

+ 43
- 0
src/mesa/drivers/dri/mga/mgatris.h Visa fil

@@ -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

+ 497
- 0
src/mesa/drivers/dri/mga/mgavb.c Visa fil

@@ -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;
}
}


+ 65
- 0
src/mesa/drivers/dri/mga/mgavb.h Visa fil

@@ -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

+ 115
- 0
src/mesa/drivers/dri/mga/server/mga.h Visa fil

@@ -0,0 +1,115 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h,v 1.85 2002/12/16 16:19:17 dawes Exp $ */
/*
* MGA Millennium (MGA2064W) functions
*
* Copyright 1996 The XFree86 Project, Inc.
*
* Authors
* Dirk Hohndel
* hohndel@XFree86.Org
* David Dawes
* dawes@XFree86.Org
*/

#ifndef MGA_H
#define MGA_H


#include "xf86drm.h"
#include "linux/types.h"


#define PCI_CHIP_MGA2085 0x0518
#define PCI_CHIP_MGA2064 0x0519
#define PCI_CHIP_MGA1064 0x051A
#define PCI_CHIP_MGA2164 0x051B
#define PCI_CHIP_MGA2164_AGP 0x051F
#define PCI_CHIP_MGAG200_PCI 0x0520
#define PCI_CHIP_MGAG200 0x0521
#define PCI_CHIP_MGAG400 0x0525
#define PCI_CHIP_MGAG550 0x2527
#define PCI_CHIP_MGAG100_PCI 0x1000
#define PCI_CHIP_MGAG100 0x1001


# define MMIO_IN8(base, offset) \
*(volatile unsigned char *)(((unsigned char*)(base)) + (offset))
# define MMIO_IN16(base, offset) \
*(volatile unsigned short *)(void *)(((unsigned char*)(base)) + (offset))
# define MMIO_IN32(base, offset) \
*(volatile unsigned int *)(void *)(((unsigned char*)(base)) + (offset))
# define MMIO_OUT8(base, offset, val) \
*(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) = (val)
# define MMIO_OUT16(base, offset, val) \
*(volatile unsigned short *)(void *)(((unsigned char*)(base)) + (offset)) = (val)
# define MMIO_OUT32(base, offset, val) \
*(volatile unsigned int *)(void *)(((unsigned char*)(base)) + (offset)) = (val)

#define INREG8(addr) MMIO_IN8(pMga->IOBase, addr)
#define INREG16(addr) MMIO_IN16(pMga->IOBase, addr)
#define INREG(addr) MMIO_IN32(pMga->IOBase, addr)
#define OUTREG8(addr, val) MMIO_OUT8(pMga->IOBase, addr, val)
#define OUTREG16(addr, val) MMIO_OUT16(pMga->IOBase, addr, val)
#define OUTREG(addr, val) MMIO_OUT32(pMga->IOBase, addr, val)

#define MGAIOMAPSIZE 0x00004000


typedef struct {
int Chipset; /**< \brief Chipset number */

int irq; /**< \brief IRQ number */


int frontOffset; /**< \brief Front color buffer offset */
int frontPitch; /**< \brief Front color buffer pitch */
int backOffset; /**< \brief Back color buffer offset */
int backPitch; /**< \brief Back color buffer pitch */
int depthOffset; /**< \brief Depth buffer offset */
int depthPitch; /**< \brief Depth buffer pitch */
int textureOffset; /**< \brief Texture area offset */
int textureSize; /**< \brief Texture area size */
int logTextureGranularity;

/**
* \name AGP
*/
/*@{*/
drmSize agpSize; /**< \brief AGP map size */
int agpMode; /**< \brief AGP mode */
/*@}*/

drmRegion agp;

/* PCI mappings */
drmRegion registers;
drmRegion status;

/* AGP mappings */
drmRegion warp;
drmRegion primary;
drmRegion buffers;
drmRegion agpTextures;

drmBufMapPtr drmBuffers;

unsigned long IOAddress;
unsigned char *IOBase;
int HasSDRAM;

__u32 reg_ien;
} MGARec, *MGAPtr;



#define MGA_FRONT 0x1
#define MGA_BACK 0x2
#define MGA_DEPTH 0x4

#define MGA_AGP_1X_MODE 0x01
#define MGA_AGP_2X_MODE 0x02
#define MGA_AGP_4X_MODE 0x04
#define MGA_AGP_MODE_MASK 0x07


#endif

+ 143
- 0
src/mesa/drivers/dri/mga/server/mga_bios.h Visa fil

@@ -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

+ 152
- 0
src/mesa/drivers/dri/mga/server/mga_common.h Visa fil

@@ -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

+ 1136
- 0
src/mesa/drivers/dri/mga/server/mga_dri.c
Filskillnaden har hållits tillbaka eftersom den är för stor
Visa fil


+ 84
- 0
src/mesa/drivers/dri/mga/server/mga_dri.h Visa fil

@@ -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

+ 118
- 0
src/mesa/drivers/dri/mga/server/mga_macros.h Visa fil

@@ -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_ */

+ 484
- 0
src/mesa/drivers/dri/mga/server/mga_reg.h Visa fil

@@ -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

+ 222
- 0
src/mesa/drivers/dri/mga/server/mga_sarea.h Visa fil

@@ -0,0 +1,222 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_sarea.h,v 1.1 2001/03/21 17:11:47 dawes Exp $ */

/*
* Copyright 2000 Gareth Hughes
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* GARETH HUGHES BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Gareth Hughes <gareth@valinux.com>
*/

#ifndef __MGA_SAREA_H__
#define __MGA_SAREA_H__

/* WARNING: If you change any of these defines, make sure to change
* the kernel include file as well (mga_drm.h)
*/
#ifndef __MGA_SAREA_DEFINES__
#define __MGA_SAREA_DEFINES__

/* WARP pipe flags
*/
#define MGA_F 0x1 /* fog */
#define MGA_A 0x2 /* alpha */
#define MGA_S 0x4 /* specular */
#define MGA_T2 0x8 /* multitexture */

#define MGA_WARP_TGZ 0
#define MGA_WARP_TGZF (MGA_F)
#define MGA_WARP_TGZA (MGA_A)
#define MGA_WARP_TGZAF (MGA_F|MGA_A)
#define MGA_WARP_TGZS (MGA_S)
#define MGA_WARP_TGZSF (MGA_S|MGA_F)
#define MGA_WARP_TGZSA (MGA_S|MGA_A)
#define MGA_WARP_TGZSAF (MGA_S|MGA_F|MGA_A)
#define MGA_WARP_T2GZ (MGA_T2)
#define MGA_WARP_T2GZF (MGA_T2|MGA_F)
#define MGA_WARP_T2GZA (MGA_T2|MGA_A)
#define MGA_WARP_T2GZAF (MGA_T2|MGA_A|MGA_F)
#define MGA_WARP_T2GZS (MGA_T2|MGA_S)
#define MGA_WARP_T2GZSF (MGA_T2|MGA_S|MGA_F)
#define MGA_WARP_T2GZSA (MGA_T2|MGA_S|MGA_A)
#define MGA_WARP_T2GZSAF (MGA_T2|MGA_S|MGA_F|MGA_A)

#define MGA_MAX_G200_PIPES 8 /* no multitex */
#define MGA_MAX_G400_PIPES 16
#define MGA_MAX_WARP_PIPES MGA_MAX_G400_PIPES
#define MGA_WARP_UCODE_SIZE 32768 /* in bytes */

#define MGA_CARD_TYPE_G200 1
#define MGA_CARD_TYPE_G400 2


#define MGA_FRONT 0x1
#define MGA_BACK 0x2
#define MGA_DEPTH 0x4

/* What needs to be changed for the current vertex dma buffer?
*/
#define MGA_UPLOAD_CONTEXT 0x1
#define MGA_UPLOAD_TEX0 0x2
#define MGA_UPLOAD_TEX1 0x4
#define MGA_UPLOAD_PIPE 0x8
#define MGA_UPLOAD_TEX0IMAGE 0x10
#define MGA_UPLOAD_TEX1IMAGE 0x20
#define MGA_UPLOAD_2D 0x40
#define MGA_WAIT_AGE 0x80 /* handled client-side */
#define MGA_UPLOAD_CLIPRECTS 0x100 /* handled client-side */
#if 0
#define MGA_DMA_FLUSH 0x200 /* set when someone gets the lock
quiescent */
#endif

/* 32 buffers of 64k each, total 1 meg.
*/
#define MGA_BUFFER_SIZE (1 << 16)
#define MGA_NUM_BUFFERS 128

/* Keep these small for testing.
*/
#define MGA_NR_SAREA_CLIPRECTS 8

/* 2 heaps (1 for card, 1 for agp), each divided into upto 128
* regions, subject to a minimum region size of (1<<16) == 64k.
*
* Clients may subdivide regions internally, but when sharing between
* clients, the region size is the minimum granularity.
*/

#define MGA_CARD_HEAP 0
#define MGA_AGP_HEAP 1
#define MGA_NR_TEX_HEAPS 2
#define MGA_NR_TEX_REGIONS 16
#define MGA_LOG_MIN_TEX_REGION_SIZE 16

#endif /* __MGA_SAREA_DEFINES__ */


/* Setup registers for 3D context
*/
typedef struct {
unsigned int dstorg;
unsigned int maccess;
unsigned int plnwt;
unsigned int dwgctl;
unsigned int alphactrl;
unsigned int fogcolor;
unsigned int wflag;
unsigned int tdualstage0;
unsigned int tdualstage1;
unsigned int fcol;
unsigned int stencil;
unsigned int stencilctl;
} mga_context_regs_t;

/* Setup registers for 2D, X server
*/
typedef struct {
unsigned int pitch;
} mga_server_regs_t;

/* Setup registers for each texture unit
*/
typedef struct {
unsigned int texctl;
unsigned int texctl2;
unsigned int texfilter;
unsigned int texbordercol;
unsigned int texorg;
unsigned int texwidth;
unsigned int texheight;
unsigned int texorg1;
unsigned int texorg2;
unsigned int texorg3;
unsigned int texorg4;
} mga_texture_regs_t;

/* General ageing mechanism
*/
typedef struct {
unsigned int head; /* Position of head pointer */
unsigned int wrap; /* Primary DMA wrap count */
} mga_age_t;


/* WARNING: Do not change the SAREA structure without changing the kernel
* as well.
*/
typedef struct {
/* The channel for communication of state information to the kernel
* on firing a vertex dma buffer.
*/
mga_context_regs_t ContextState;
mga_server_regs_t ServerState;
mga_texture_regs_t TexState[2];
unsigned int WarpPipe;
unsigned int dirty;
unsigned int vertsize;

/* The current cliprects, or a subset thereof.
*/
XF86DRIClipRectRec boxes[MGA_NR_SAREA_CLIPRECTS];
unsigned int nbox;

/* Information about the most recently used 3d drawable. The
* client fills in the req_* fields, the server fills in the
* exported_ fields and puts the cliprects into boxes, above.
*
* The client clears the exported_drawable field before
* clobbering the boxes data.
*/

unsigned int req_draw_buffer; /* MGA_FRONT or MGA_BACK */

unsigned int exported_drawable;
unsigned int exported_index;
unsigned int exported_stamp;
unsigned int exported_buffers;
unsigned int exported_nfront; /* FIXME: verify signedness... */
unsigned int exported_nback;
int exported_back_x, exported_front_x, exported_w;
int exported_back_y, exported_front_y, exported_h;
XF86DRIClipRectRec exported_boxes[MGA_NR_SAREA_CLIPRECTS];

/* Counters for aging textures and for client-side throttling.
*/
unsigned int status[4];
unsigned int last_wrap;

mga_age_t last_frame;
unsigned int last_enqueue; /* last time a buffer was enqueued */
unsigned int last_dispatch; /* age of the most recently dispatched buffer */
unsigned int last_quiescent; /* */

/* LRU lists for texture memory in agp space and on the card.
*/
drmTextureRegion texList[MGA_NR_TEX_HEAPS][MGA_NR_TEX_REGIONS+1];
unsigned int texAge[MGA_NR_TEX_HEAPS];

/* Last context that uploaded statel
*/
int ctxOwner;
} MGASAREAPrivRec, *MGASAREAPrivPtr;

#endif

Laddar…
Avbryt
Spara