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