From 1067ce0cea1392b4ea1cc1c2c940cec33efb9c96 Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Sat, 1 Jan 2005 20:40:14 +0000 Subject: Removed all direct hardware access (MMIO, BCI) from the Savage DRI driver. It uses the new DRM version 2.0.x now, which has just been committed to DRM CVS. --- src/mesa/drivers/dri/savage/Makefile | 3 +- src/mesa/drivers/dri/savage/savage_bci.h | 105 +---- src/mesa/drivers/dri/savage/savage_init.h | 31 +- src/mesa/drivers/dri/savage/savage_xmesa.c | 147 +++---- src/mesa/drivers/dri/savage/savagecontext.h | 61 ++- src/mesa/drivers/dri/savage/savagedd.c | 28 +- src/mesa/drivers/dri/savage/savagedma.c | 150 +------ src/mesa/drivers/dri/savage/savagedma.h | 4 - src/mesa/drivers/dri/savage/savageioctl.c | 527 +++++++++++++++--------- src/mesa/drivers/dri/savage/savageioctl.h | 92 +++-- src/mesa/drivers/dri/savage/savagestate.c | 248 ++++++----- src/mesa/drivers/dri/savage/savagestate.h | 36 +- src/mesa/drivers/dri/savage/savagetex.c | 19 +- src/mesa/drivers/dri/savage/savagetris.c | 188 ++++++--- src/mesa/drivers/dri/savage/server/savage_dri.h | 77 ++-- 15 files changed, 842 insertions(+), 874 deletions(-) diff --git a/src/mesa/drivers/dri/savage/Makefile b/src/mesa/drivers/dri/savage/Makefile index d662cb06d8..181556318f 100644 --- a/src/mesa/drivers/dri/savage/Makefile +++ b/src/mesa/drivers/dri/savage/Makefile @@ -25,8 +25,7 @@ DRIVER_SOURCES = \ savagetex.c \ savagetris.c \ savageioctl.c \ - savagespan.c \ - savagedma.c + savagespan.c C_SOURCES = \ $(COMMON_SOURCES) \ diff --git a/src/mesa/drivers/dri/savage/savage_bci.h b/src/mesa/drivers/dri/savage/savage_bci.h index 3c91e01f21..0928b3ca74 100644 --- a/src/mesa/drivers/dri/savage/savage_bci.h +++ b/src/mesa/drivers/dri/savage/savage_bci.h @@ -341,8 +341,8 @@ typedef enum TPS_256 } TexPaletteSize; - #define MAX_MIPMAP_LOD_BIAS 255 - #define MIN_MIPMAP_LOD_BIAS -255 +#define MAX_MIPMAP_LOD_BIAS 255 +#define MIN_MIPMAP_LOD_BIAS -255 typedef enum { @@ -627,107 +627,6 @@ typedef union { #define SAVAGE_HW_NO_UV1 ((1<<6) | (1<<7)) #define SAVAGE_HW_SKIPFLAGS 0x000000ff -#define SAVAGE_HW_TRIANGLE_TYPE (3UL<<25) -#define SAVAGE_HW_TRIANGLE_CONT (1UL<<24) -#define SAVAGE_HW_TRIANGLE_LIST (0<<25) -#define SAVAGE_HW_TRIANGLE_STRIP (1<<25) -#define SAVAGE_HW_TRIANGLE_FAN (2<<25) -#define SAVAGE_HW_QUAD (3<<25) - -#define __HW_TEXTURE_CHANGED 0x00002FE -#define __HW_HAS_SCISSORS_CHANGED 0x00001800 -#define __HW_ALL_CHANGED 0x1FFFFFF -/*Frank 2001/11/14 Wait commands*/ -#define WAIT_3D_IDLE 0xC0010000 -#define WAIT_3D_2D_IDLE 0xC0030000 - -#define SET_REGISTER(index, count) \ - ((CMD_SetRegister << 27) | (0x6000000) | ((count) << 16) | (index)) - -/*frank 2001/11/20 */ -#define MAXLOOP 0xFFFFFF -/*#define MAXFIFO 0x7F00*/ -#define MAXFIFO 0x1FF00 - -/* get eventtag from shadow status */ -/* here we use eventTag1 because eventTag0 is used by HWXvMC*/ -#define GET_EVENTTAG \ - (((*(volatile GLuint *)(imesa->MMIO_BASE+0x48c04)) & 0xffff0000L)>>16) - -#define SHADOW_WAIT(imesa ) do \ -{ \ - int loop=0; \ - imesa->shadowCounter = (imesa->shadowCounter + 1) & 0xffff;\ - if(imesa->shadowCounter == 0)\ - imesa->shadowCounter = MAX_SHADOWCOUNTER;\ - *(volatile GLuint *)imesa->BCIBase = imesa->shadowCounter | 0x98400000L;\ - while(\ - (GET_EVENTTAG) != imesa->shadowCounter &&\ - (loop++ < MAXLOOP));\ -}while(0); - -#define SHADOW_WAIT_IDLE(imesa ) do \ -{ \ - int loop=0; \ - imesa->shadowCounter = (imesa->shadowCounter + 1) & 0xffff;\ - if(imesa->shadowCounter == 0)\ - imesa->shadowCounter = MAX_SHADOWCOUNTER;\ -/* *(volatile GLuint *)imesa->BCIBase = WAIT_3D_IDLE;\*/\ - *(volatile GLuint *)imesa->BCIBase = imesa->shadowCounter | 0x98400000L;\ - while ( \ - (GET_EVENTTAG) != imesa->shadowCounter && \ - (loop++ < MAXLOOP)); \ -}while(0); - -#if 0 -#define ALT_STATUS_WORD0 (* (volatile GLuint *)(imesa->MMIO_BASE+0x48c60)) - -#define PAGE_PENDING(result) do{\ -result=((ALT_STATUS_WORD0 & 0x08000000)?GL_TRUE:GL_FALSE);\ -}while(0) - -#define WAIT_FOR_FIFO(count) do{\ -int loop = 0; \ -int slots = MAXFIFO-count; \ -while(((ALT_STATUS_WORD0 &0x001fffff)>slots)&&(loop++shadowStatus*/0)\ - {\ - SHADOW_WAIT_IDLE(imesa);\ - }\ - else\ - { \ - while(((ALT_STATUS_WORD0 &0x00ffffff)!=0x00E00000L)&&(loop++shadowStatus)\ - while((((*imesa->shadowPointer) & 0x0E000000L)!=0x0E000000L)&&(loop++BCIBase); -} - -/*use this set bci cmd now!*/ -#define WRITE_CMD(buf,cmd,type) do {\ - *((type*)buf)=cmd;\ - buf++;\ - }while(0) #endif diff --git a/src/mesa/drivers/dri/savage/savage_init.h b/src/mesa/drivers/dri/savage/savage_init.h index 1454b6b36c..27539bea16 100644 --- a/src/mesa/drivers/dri/savage/savage_init.h +++ b/src/mesa/drivers/dri/savage/savage_init.h @@ -41,11 +41,6 @@ typedef struct { } savageRegion, *savageRegionPtr; typedef struct { - savageRegion front; - savageRegion back; - savageRegion depth; - savageRegion aperture; - int chipset; int width; int height; @@ -53,31 +48,34 @@ typedef struct { int cpp; /* for front and back buffers */ int zpp; + + int agpMode; + + unsigned int bufferSize; + #if 0 int bitsPerPixel; #endif unsigned int frontFormat; unsigned int frontOffset; - unsigned int frontPitch; - unsigned int frontBitmapDesc; - unsigned int backOffset; - unsigned int backBitmapDesc; unsigned int depthOffset; - unsigned int depthBitmapDesc; - unsigned int backPitch; - unsigned int backPitchBits; + unsigned int aperturePitch; unsigned int textureOffset[SAVAGE_NR_TEX_HEAPS]; unsigned int textureSize[SAVAGE_NR_TEX_HEAPS]; unsigned int logTextureGranularity[SAVAGE_NR_TEX_HEAPS]; drmAddress texVirtual[SAVAGE_NR_TEX_HEAPS]; - __DRIscreenPrivate *driScrnPriv; - drmBufMapPtr bufs; - int use_copy_buf; - unsigned int sarea_priv_offset; + __DRIscreenPrivate *driScrnPriv; + + savageRegion aperture; + savageRegion agpTextures; + + drmBufMapPtr bufs; + + unsigned int sarea_priv_offset; /* Configuration cache with default values for all contexts */ driOptionCache optionCache; @@ -87,7 +85,6 @@ typedef struct { #include "savagecontext.h" extern void savageGetLock( savageContextPtr imesa, GLuint flags ); -extern void savageEmitHwStateLocked( savageContextPtr imesa ); extern void savageEmitScissorValues( savageContextPtr imesa, int box_nr, int emit ); extern void savageEmitDrawingRectangle( savageContextPtr imesa ); extern void savageXMesaSetBackClipRects( savageContextPtr imesa ); diff --git a/src/mesa/drivers/dri/savage/savage_xmesa.c b/src/mesa/drivers/dri/savage/savage_xmesa.c index bcbc9d69ed..f1798de134 100644 --- a/src/mesa/drivers/dri/savage/savage_xmesa.c +++ b/src/mesa/drivers/dri/savage/savage_xmesa.c @@ -55,8 +55,6 @@ #include "savage_dri.h" -#include "savagedma.h" - #include "xmlpool.h" /* Configuration @@ -85,6 +83,8 @@ static const struct dri_debug_control debug_control[] = { "fall", DEBUG_FALLBACKS }, { "api", DEBUG_VERBOSE_API }, { "lru", DEBUG_VERBOSE_LRU }, + { "verb", DEBUG_VERBOSE_MSG }, + { "dma", DEBUG_DMA }, { NULL, 0 } }; #ifndef SAVAGE_DEBUG @@ -131,7 +131,6 @@ savageInitDriver(__DRIscreenPrivate *sPriv) savageScreenPrivate *savageScreen; SAVAGEDRIPtr gDRIPriv = (SAVAGEDRIPtr)sPriv->pDevPriv; - /* Allocate the private area */ savageScreen = (savageScreenPrivate *)Xmalloc(sizeof(savageScreenPrivate)); if (!savageScreen) @@ -146,23 +145,19 @@ savageInitDriver(__DRIscreenPrivate *sPriv) savageScreen->mem=gDRIPriv->mem; savageScreen->cpp=gDRIPriv->cpp; savageScreen->zpp=gDRIPriv->zpp; - savageScreen->frontPitch=gDRIPriv->frontPitch; - savageScreen->frontOffset=gDRIPriv->frontOffset; - savageScreen->frontBitmapDesc = gDRIPriv->frontBitmapDesc; - + + savageScreen->agpMode=gDRIPriv->agpMode; + + savageScreen->bufferSize=gDRIPriv->bufferSize; + if (gDRIPriv->cpp == 4) savageScreen->frontFormat = DV_PF_8888; else savageScreen->frontFormat = DV_PF_565; - + savageScreen->frontOffset=gDRIPriv->frontOffset; savageScreen->backOffset = gDRIPriv->backOffset; - savageScreen->backBitmapDesc = gDRIPriv->backBitmapDesc; savageScreen->depthOffset=gDRIPriv->depthOffset; - savageScreen->depthBitmapDesc = gDRIPriv->depthBitmapDesc; -#if 0 - savageScreen->backPitch = gDRIPriv->auxPitch; - savageScreen->backPitchBits = gDRIPriv->auxPitchBits; -#endif + savageScreen->textureOffset[SAVAGE_CARD_HEAP] = gDRIPriv->textureOffset; savageScreen->textureSize[SAVAGE_CARD_HEAP] = @@ -171,57 +166,32 @@ savageInitDriver(__DRIscreenPrivate *sPriv) gDRIPriv->logTextureGranularity; savageScreen->textureOffset[SAVAGE_AGP_HEAP] = - gDRIPriv->agpTextures.handle; + gDRIPriv->agpTextureHandle; savageScreen->textureSize[SAVAGE_AGP_HEAP] = - gDRIPriv->agpTextures.size; + gDRIPriv->agpTextureSize; savageScreen->logTextureGranularity[SAVAGE_AGP_HEAP] = gDRIPriv->logAgpTextureGranularity; - - savageScreen->back.handle = gDRIPriv->backbuffer; - savageScreen->back.size = gDRIPriv->backbufferSize; - savageScreen->back.map = - (drmAddress)(((unsigned int)sPriv->pFB)+gDRIPriv->backOffset); - - savageScreen->depth.handle = gDRIPriv->depthbuffer; - savageScreen->depth.size = gDRIPriv->depthbufferSize; - - savageScreen->depth.map = - (drmAddress)(((unsigned int)sPriv->pFB)+gDRIPriv->depthOffset); - - savageScreen->sarea_priv_offset = gDRIPriv->sarea_priv_offset; - savageScreen->texVirtual[SAVAGE_CARD_HEAP] = - (drmAddress)(((unsigned int)sPriv->pFB)+gDRIPriv->textureOffset); - - if (drmMap(sPriv->fd, - gDRIPriv->registers.handle, - gDRIPriv->registers.size, - (drmAddress *)&(gDRIPriv->registers.map)) != 0) - { - Xfree(savageScreen); - sPriv->private = NULL; - return GL_FALSE; - } - + savageScreen->agpTextures.handle = gDRIPriv->agpTextureHandle; + savageScreen->agpTextures.size = gDRIPriv->agpTextureSize; if (drmMap(sPriv->fd, - gDRIPriv->agpTextures.handle, - gDRIPriv->agpTextures.size, - (drmAddress *)&(gDRIPriv->agpTextures.map)) != 0) + savageScreen->agpTextures.handle, + savageScreen->agpTextures.size, + (drmAddress *)&(savageScreen->agpTextures.map)) != 0) { Xfree(savageScreen); sPriv->private = NULL; return GL_FALSE; } -/* agp texture*/ + savageScreen->texVirtual[SAVAGE_CARD_HEAP] = + (drmAddress)(((unsigned int)sPriv->pFB)+gDRIPriv->textureOffset); savageScreen->texVirtual[SAVAGE_AGP_HEAP] = - (drmAddress)(gDRIPriv->agpTextures.map); - - gDRIPriv->BCIcmdBuf.map = (drmAddress *) - ((unsigned int)gDRIPriv->registers.map+0x00010000); + (drmAddress)(savageScreen->agpTextures.map); - savageScreen->aperture.handle = gDRIPriv->aperture.handle; - savageScreen->aperture.size = gDRIPriv->aperture.size; + savageScreen->aperture.handle = gDRIPriv->apertureHandle; + savageScreen->aperture.size = gDRIPriv->apertureSize; + savageScreen->aperturePitch = gDRIPriv->aperturePitch; if (drmMap(sPriv->fd, savageScreen->aperture.handle, savageScreen->aperture.size, @@ -230,8 +200,12 @@ savageInitDriver(__DRIscreenPrivate *sPriv) Xfree(savageScreen); sPriv->private = NULL; return GL_FALSE; - } - + } + + savageScreen->bufs = drmMapBufs(sPriv->fd); + + savageScreen->sarea_priv_offset = gDRIPriv->sarea_priv_offset; + /* parse information in __driConfigOptions */ driParseOptionInfo (&savageScreen->optionCache, __driConfigOptions, __driNConfigOptions); @@ -251,6 +225,8 @@ savageDestroyScreen(__DRIscreenPrivate *sPriv) { savageScreenPrivate *savageScreen = (savageScreenPrivate *)sPriv->private; + drmUnmapBufs(savageScreen->bufs); + /* free all option information */ driDestroyOptionInfo (&savageScreen->optionCache); @@ -295,7 +271,6 @@ savageCreateContext( const __GLcontextModes *mesaVis, savageContextPtr imesa; __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; struct dd_function_table functions; - SAVAGEDRIPtr gDRIPriv = (SAVAGEDRIPtr)sPriv->pDevPriv; savageScreenPrivate *savageScreen = (savageScreenPrivate *)sPriv->private; drm_savage_sarea_t *saPriv=(drm_savage_sarea_t *)(((char*)sPriv->pSAREA)+ savageScreen->sarea_priv_offset); @@ -323,6 +298,12 @@ savageCreateContext( const __GLcontextModes *mesaVis, } driContextPriv->driverPrivate = imesa; + imesa->cmdBuf.size = SAVAGE_CMDBUF_SIZE; + imesa->cmdBuf.base = imesa->cmdBuf.write = + malloc(SAVAGE_CMDBUF_SIZE * sizeof(drm_savage_cmd_header_t)); + if (!imesa->cmdBuf.base) + return GL_FALSE; + /* Parse configuration files */ driParseConfigFiles (&imesa->optionCache, &savageScreen->optionCache, sPriv->myNum, "savage"); @@ -398,26 +379,14 @@ savageCreateContext( const __GLcontextModes *mesaVis, /* DMA buffer */ - /*The shadow pointer*/ - imesa->shadowPointer = - (volatile GLuint *)((((GLuint)(&saPriv->shadow_status)) + 31) & 0xffffffe0L) ; - /* here we use eventTag1 because eventTag0 is used by HWXvMC*/ - imesa->eventTag1 = (volatile GLuint *)(imesa->shadowPointer + 6); - /* imesa->eventTag1=(volatile GLuint *)(imesa->MMIO_BASE+0x48c04);*/ - imesa->shadowCounter = MAX_SHADOWCOUNTER; - imesa->shadowStatus = GL_TRUE;/*Will judge by 2d message */ - - imesa->MMIO_BASE = (GLuint)gDRIPriv->registers.map; - imesa->BCIBase= (GLuint)gDRIPriv->BCIcmdBuf.map; for(i=0;i<5;i++) { imesa->apertureBase[i] = ((GLuint)savageScreen->aperture.map + 0x01000000 * i ); } - imesa->aperturePitch = gDRIPriv->aperturePitch; - - + imesa->aperturePitch = savageScreen->aperturePitch; + /* change texHeap initialize to support two kind of texture heap*/ /* here is some parts of initialization, others in InitDriver() */ @@ -440,7 +409,17 @@ savageCreateContext( const __GLcontextModes *mesaVis, imesa->depth_scale = (imesa->savageScreen->zpp == 2) ? (1.0F/0x10000):(1.0F/0x1000000); - imesa->vertex_dma_buffer = NULL; + imesa->bufferSize = savageScreen->bufferSize; + imesa->dmaVtxBuf.total = 0; + imesa->dmaVtxBuf.used = 0; + imesa->dmaVtxBuf.flushed = 0; + + imesa->clientVtxBuf.total = 16384; + imesa->clientVtxBuf.used = 0; + imesa->clientVtxBuf.flushed = 0; + imesa->clientVtxBuf.buf = (u_int32_t *)malloc(16384*4); + + imesa->vtxBuf = &imesa->clientVtxBuf; /* Uninitialized vertex format. Force setting the vertex state in * savageRenderStart. @@ -450,6 +429,7 @@ savageCreateContext( const __GLcontextModes *mesaVis, /* Utah stuff */ imesa->new_state = ~0; + imesa->new_gl_state = ~0; imesa->RenderIndex = ~0; imesa->dirty = ~0; imesa->lostContext = GL_TRUE; @@ -483,8 +463,6 @@ savageCreateContext( const __GLcontextModes *mesaVis, ctx->DriverCtx = (void *) imesa; imesa->glCtx = ctx; - if (savageDMAInit(imesa) == GL_FALSE) - return GL_FALSE; #ifndef SAVAGE_DEBUG SAVAGE_DEBUG = driParseDebugString( getenv( "SAVAGE_DEBUG" ), @@ -501,8 +479,7 @@ savageCreateContext( const __GLcontextModes *mesaVis, savageDDInitState( imesa ); - if (driQueryOptionb(&imesa->optionCache, "no_rast")) - FALLBACK(ctx, SAVAGE_FALLBACK_NORAST, GL_TRUE); + imesa->no_rast = driQueryOptionb(&imesa->optionCache, "no_rast"); driContextPriv->driverPrivate = (void *) imesa; @@ -529,8 +506,10 @@ savageDestroyContext(__DRIcontextPrivate *driContextPriv) } foreach_s (t, next_t, &(imesa->SwappedOut)) savageDestroyTexObj(imesa, t); - /*free the dma buffer*/ - savageDMAClose(imesa); + + free(imesa->cmdBuf.base); + free(imesa->clientVtxBuf.buf); + _swsetup_DestroyContext(imesa->glCtx ); _tnl_DestroyContext( imesa->glCtx ); _ac_DestroyContext( imesa->glCtx ); @@ -753,10 +732,13 @@ void savageGetLock( savageContextPtr imesa, GLuint flags ) * more broken than usual. */ if (sarea->ctxOwner != me) { - imesa->dirty |= (SAVAGE_UPLOAD_CTX | - SAVAGE_UPLOAD_CLIPRECTS | + imesa->dirty |= (SAVAGE_UPLOAD_LOCAL | + SAVAGE_UPLOAD_GLOBAL | + SAVAGE_UPLOAD_FOGTBL | SAVAGE_UPLOAD_TEX0 | - SAVAGE_UPLOAD_TEX1); + SAVAGE_UPLOAD_TEX1 | + SAVAGE_UPLOAD_TEXGLOBAL | + SAVAGE_UPLOAD_CLIPRECTS); imesa->lostContext = GL_TRUE; sarea->ctxOwner = me; } @@ -794,8 +776,6 @@ void savageGetLock( savageContextPtr imesa, GLuint flags ) savageResetGlobalLRU( imesa , heap ); } - imesa->dirty |= SAVAGE_UPLOAD_TEX0IMAGE; - imesa->dirty |= SAVAGE_UPLOAD_TEX1IMAGE; imesa->texAge[heap] = sarea->texAge[heap]; } } /* end of for loop */ @@ -948,10 +928,9 @@ void * __driCreateNewScreen( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc { __DRIscreenPrivate *psp; - static const __DRIversion ddx_expected = { 1, 0, 0 }; + static const __DRIversion ddx_expected = { 2, 0, 0 }; static const __DRIversion dri_expected = { 4, 0, 0 }; - static const __DRIversion drm_expected = { 1, 0, 0 }; - + static const __DRIversion drm_expected = { 2, 0, 0 }; if ( ! driCheckDriDdxDrmVersions2( "Savage", dri_version, & dri_expected, diff --git a/src/mesa/drivers/dri/savage/savagecontext.h b/src/mesa/drivers/dri/savage/savagecontext.h index f41b73e0de..8978f9247c 100644 --- a/src/mesa/drivers/dri/savage/savagecontext.h +++ b/src/mesa/drivers/dri/savage/savagecontext.h @@ -42,7 +42,6 @@ typedef struct savage_texture_object_t *savageTextureObjectPtr; #include "tnl/t_vertex.h" #include "savagetex.h" -#include "savagedma.h" #include "xmlconfig.h" @@ -69,10 +68,26 @@ typedef struct savage_texture_object_t *savageTextureObjectPtr; #define SAVAGE_NEW_TEXTURE 0x1 #define SAVAGE_NEW_CULL 0x2 +/* What needs to be changed for the current vertex dma buffer? + * This will go away! + */ +#define SAVAGE_UPLOAD_LOCAL 0x1 /* DrawLocalCtrl (S4) or + DrawCtrl and ZBufCtrl (S3D) */ +#define SAVAGE_UPLOAD_TEX0 0x2 /* texture unit 0 */ +#define SAVAGE_UPLOAD_TEX1 0x4 /* texture unit 1 (S4 only) */ +#define SAVAGE_UPLOAD_FOGTBL 0x8 /* fog table */ +#define SAVAGE_UPLOAD_GLOBAL 0x10 /* most global regs */ +#define SAVAGE_UPLOAD_TEXGLOBAL 0x20 /* TexBlendColor (S4 only) */ +#define SAVAGE_UPLOAD_CLIPRECTS 0x1000 /* FIXME: get rid of this */ /*define the max numer of vertex in vertex buf*/ #define SAVAGE_MAX_VERTEXS 0x10000 +/* Don't make it too big. We don't want to buffer up a whole frame + * that would force the application to wait later. */ +#define SAVAGE_CMDBUF_SIZE 1024 +#define SAVAGE_MAX_VERTS_PENDING 1024 + /* Use the templated vertex formats: */ #define TAG(x) savage##x @@ -113,6 +128,18 @@ typedef void (*savage_point_func)( savageContextPtr, savageVertex * ); imesa->savageScreen->deviceID == CHIP_S3TRISTAR64CDDR ) +struct savage_vtxbuf_t { + GLuint total, used, flushed; /* in 32 bit units */ + GLuint idx; /* for DMA buffers */ + u_int32_t *buf; +}; + +struct savage_cmdbuf_t { + GLuint size; /* size in qwords */ + drm_savage_cmd_header_t *base; /* initial state starts here */ + drm_savage_cmd_header_t *start; /* drawing/state commands start here */ + drm_savage_cmd_header_t *write; /* append stuff here */ +}; struct savage_context_t { @@ -143,11 +170,12 @@ struct savage_context_t { GLuint new_gl_state; GLboolean ptexHack; - GLuint BCIBase; - GLuint MMIO_BASE; + /* Command buffer */ + struct savage_cmdbuf_t cmdBuf; - /* DMA command buffer */ - DMABuffer_t DMABuf; + /* Vertex buffers */ + struct savage_vtxbuf_t dmaVtxBuf, clientVtxBuf; + struct savage_vtxbuf_t *vtxBuf; /* aperture base */ GLuint apertureBase[5]; @@ -179,7 +207,8 @@ struct savage_context_t { GLenum raster_primitive; GLenum render_primitive; - GLuint DrawPrimitiveCmd; + GLuint skip; + GLubyte HwPrim; GLuint HwVertexSize; /* Fallback rasterization functions @@ -194,8 +223,9 @@ struct savage_context_t { GLuint ClearColor; GLfloat depth_scale; GLfloat hw_viewport[16]; - /* DRI stuff */ - drmBufPtr vertex_dma_buffer; + /* DRI stuff */ + GLuint bufferSize; + GLuint vertsPending; GLframebuffer *glBuffer; @@ -225,8 +255,8 @@ struct savage_context_t { GLuint backup_streamFIFO; GLuint NotFirstFrame; + GLboolean inSwap; GLuint lastSwap; - GLuint secondLastSwap; GLuint ctxAge; GLuint dirtyAge; GLuint any_contend; /* throttle me harder */ @@ -235,7 +265,7 @@ struct savage_context_t { GLboolean scissorChanged; drm_clip_rect_t draw_rect; drm_clip_rect_t scissor_rect; - drm_clip_rect_t tmp_boxes[2][SAVAGE_NR_SAREA_CLIPRECTS]; + /*Texture aging and DMA based aging*/ unsigned int texAge[SAVAGE_NR_TEX_HEAPS]; @@ -259,16 +289,11 @@ struct savage_context_t { GLboolean hw_stencil; - /*shadow pointer*/ - volatile GLuint *shadowPointer; - volatile GLuint *eventTag1; - GLuint shadowCounter; - GLboolean shadowStatus; - /* Configuration cache */ driOptionCache optionCache; - int texture_depth; + GLint texture_depth; + GLboolean no_rast; }; #define SAVAGE_CONTEXT(ctx) ((savageContextPtr)(ctx->DriverCtx)) @@ -283,6 +308,8 @@ extern int SAVAGE_DEBUG; #define DEBUG_FALLBACKS 0x001 #define DEBUG_VERBOSE_API 0x002 #define DEBUG_VERBOSE_LRU 0x004 +#define DEBUG_VERBOSE_MSG 0x008 +#define DEBUG_DMA 0x010 #define TARGET_FRONT 0x0 #define TARGET_BACK 0x1 diff --git a/src/mesa/drivers/dri/savage/savagedd.c b/src/mesa/drivers/dri/savage/savagedd.c index dddc6d9a65..312f6f62f4 100644 --- a/src/mesa/drivers/dri/savage/savagedd.c +++ b/src/mesa/drivers/dri/savage/savagedd.c @@ -38,6 +38,10 @@ #include "savagecontext.h" #include "extensions.h" +#include "utils.h" + + +#define DRIVER_DATE "20050101" /*************************************** * Mesa's Driver Functions @@ -46,11 +50,33 @@ static const GLubyte *savageDDGetString( GLcontext *ctx, GLenum name ) { + static char *cardNames[S3_LAST] = { + "Unknown", + "Savage3D", + "Savage/MX/IX", + "Savage4", + "ProSavage", + "Twister", + "ProSavageDDR", + "SuperSavage", + "Savage2000" + }; + static char buffer[128]; + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + savageScreenPrivate *screen = imesa->savageScreen; + enum S3CHIPTAGS chipset = screen->chipset; + unsigned offset; + + if (chipset < S3_SAVAGE3D || chipset >= S3_LAST) + chipset = S3_UNKNOWN; /* should not happen */ + switch (name) { case GL_VENDOR: return (GLubyte *)"S3 Graphics Inc."; case GL_RENDERER: - return (GLubyte *)"Mesa DRI SAVAGE Linux_1.1.18"; + offset = driGetRendererString( buffer, cardNames[chipset], DRIVER_DATE, + screen->agpMode ); + return (GLubyte *)buffer; default: return 0; } diff --git a/src/mesa/drivers/dri/savage/savagedma.c b/src/mesa/drivers/dri/savage/savagedma.c index 86ee763a31..51a1e6d2bd 100644 --- a/src/mesa/drivers/dri/savage/savagedma.c +++ b/src/mesa/drivers/dri/savage/savagedma.c @@ -30,20 +30,7 @@ #include #include -/* Commit does not depend on whether we use real DMA or fake it via the BCI */ -void savageDMACommit (savageContextPtr imesa, void *endPtr) { - DMABufferPtr dmaBuff = &imesa->DMABuf; - GLuint end = (GLuint)endPtr; - - /* make sure that enough space was allocated */ - assert (end <= dmaBuff->allocEnd); - - dmaBuff->allocEnd = dmaBuff->end = end; - - /* TODO: check commands, either here or in flush */ -} - -#if SAVAGE_CMD_DMA +#if 0 /* flag = 0 return -1 if no available page 1 wait until a page be available */ @@ -219,139 +206,4 @@ int savageDMAClose (savageContextPtr imesa) return GL_TRUE; } -#else -/* Allocate space in faked DMA buffer */ -void *savageDMAAlloc (savageContextPtr imesa, GLuint size) { - DMABufferPtr dmaBuff = &imesa->DMABuf; - - /* make sure that everything has been filled in and committed */ - assert (dmaBuff->end == dmaBuff->allocEnd); - - size *= sizeof (u_int32_t); /* size in bytes */ - if (dmaBuff->end + size >= dmaBuff->buf->linear + DMA_PAGE_SIZE) { - /* need kick off */ - savageDMAFlush (imesa); - } - dmaBuff->allocEnd = dmaBuff->end + size; - return (void *)dmaBuff->end; -} - -/* Flush DMA buffer via BCI (faked DMA) */ -void savageDMAFlush(savageContextPtr imesa) { - volatile u_int32_t* BCIbase; - DMABufferPtr dmaBuff = &imesa->DMABuf; - u_int32_t *entry; - - /* make sure that everything has been filled in and committed */ - assert (dmaBuff->allocEnd == dmaBuff->end); - - if (dmaBuff->start == dmaBuff->end) /* no command? */ - return; - - /* get bci base */ - BCIbase = (volatile u_int32_t *)SAVAGE_GET_BCI_POINTER( - imesa, (dmaBuff->end - dmaBuff->start) / sizeof (u_int32_t)); - - for (entry = (u_int32_t *)dmaBuff->start; - entry < (u_int32_t *)dmaBuff->end; ++entry) - *BCIbase = *entry; - - dmaBuff->end = dmaBuff->allocEnd = dmaBuff->start; -} - -/* Init faked DMA */ -int savageDMAInit (savageContextPtr imesa) { - DMABufferPtr dmaBuff = &imesa->DMABuf; - drm_savage_alloc_cont_mem_t * req; - - req = (drm_savage_alloc_cont_mem_t *) - malloc (sizeof(drm_savage_alloc_cont_mem_t)); - if (!req) - return GL_FALSE; - - req->linear = (GLuint)malloc (DMA_PAGE_SIZE); - if (!req->linear) { - free (req); - return GL_FALSE; - } - - dmaBuff->buf = req; - - dmaBuff->start = dmaBuff->end = dmaBuff->allocEnd = req->linear; - dmaBuff->usingPage = 0; - dmaBuff->kickFlag = GL_FALSE; - - return GL_TRUE; -} - -/* Close faked DMA */ -int savageDMAClose (savageContextPtr imesa) { - DMABufferPtr dmaBuff = &imesa->DMABuf; - drm_savage_alloc_cont_mem_t * req = dmaBuff->buf; - - free ((void *)req->linear); - free (req); - - return GL_TRUE; -} - #endif - -/* Faked vertex buffers - * - * This is a dirty hack, knowing that it will go away soon when real - * vertex DMA is implemented and eventually moved to the DRM. - */ - -static u_int32_t vertex_data[16384]; /* 64KB */ -static drmBuf vertex_buffer = { - 0, /* idx */ - 65536, /* total = 64KB */ - 0, /* used */ - (drmAddress)vertex_data /* address */ -}; - -void savageFakeVertices (savageContextPtr imesa, drmBufPtr buffer) { - GLuint vertexStride = imesa->HwVertexSize; /* stride in dwords */ - GLuint vertexSize = imesa->HwVertexSize; /* the real vertex size in dwords */ - GLuint nVertices = buffer->used / (vertexStride*4); - u_int32_t *data = (u_int32_t*)buffer->address; - u_int32_t vertexFormat = imesa->DrawPrimitiveCmd & SAVAGE_HW_SKIPFLAGS; - GLuint i, j, left; - - /* we have the monopoly on vertex buffers ;-) */ - assert (buffer == &vertex_buffer); - assert (buffer->used % (vertexStride*4) == 0); /* whole vertices */ - assert (nVertices % 3 == 0); /* triangle lists */ - - /* Flush (pseodo) DMA before accessing the BCI directly. */ - savageDMAFlush(imesa); - - left = nVertices; - while (left != 0) { - /* Can emit up to 255 vertices (85 triangles) with one command. */ - GLuint count = left > 255 ? 255 : left; - /* Don't go through another buffering mechanism, copy to BCI - * directly. */ - volatile u_int32_t *vb = SAVAGE_GET_BCI_POINTER(imesa, - count*vertexSize + 1); - - WRITE_CMD (vb, SAVAGE_DRAW_PRIMITIVE( - count, SAVAGE_HW_TRIANGLE_LIST | vertexFormat, 0), - u_int32_t); - for (i = 0; i < count; ++i) { - for (j = 0; j < vertexSize; ++j) - WRITE_CMD (vb, data[j], u_int32_t); - data += vertexStride; - } - left -= count; - } - - /* clear the vertex buffer for the next set of vertices */ - vertex_buffer.used = 0; -} - -drmBufPtr savageFakeGetBuffer (savageContextPtr imesa) { - assert (vertex_buffer.used == 0); /* has been flushed */ - return &vertex_buffer; -} diff --git a/src/mesa/drivers/dri/savage/savagedma.h b/src/mesa/drivers/dri/savage/savagedma.h index 0896ca148d..09f0c46e95 100644 --- a/src/mesa/drivers/dri/savage/savagedma.h +++ b/src/mesa/drivers/dri/savage/savagedma.h @@ -49,8 +49,4 @@ void savageDMAFlush (savageContextPtr imesa); int savageDMAInit (savageContextPtr imesa); int savageDMAClose (savageContextPtr); -/* faked implementation of vertex buffers */ -void savageFakeVertices (savageContextPtr imesa, drmBufPtr buffer); -drmBufPtr savageFakeGetBuffer (savageContextPtr imesa); - #endif diff --git a/src/mesa/drivers/dri/savage/savageioctl.c b/src/mesa/drivers/dri/savage/savageioctl.c index ac9e055e93..dd7a84e2e7 100644 --- a/src/mesa/drivers/dri/savage/savageioctl.c +++ b/src/mesa/drivers/dri/savage/savageioctl.c @@ -37,16 +37,86 @@ #include "savagecontext.h" #include "savageioctl.h" #include "savage_bci.h" -#include "savagedma.h" +#include "savagestate.h" #include "drm.h" #include #include -extern GLuint bcicount; #define DEPTH_SCALE_16 ((1<<16)-1) #define DEPTH_SCALE_24 ((1<<24)-1) + +void savageGetDMABuffer( savageContextPtr imesa ) +{ + int idx = 0; + int size = 0; + drmDMAReq dma; + int retcode; + drmBufPtr buf; + + if (SAVAGE_DEBUG & DEBUG_DMA) + fprintf(stderr, "Getting dma buffer\n"); + + dma.context = imesa->hHWContext; + dma.send_count = 0; + dma.send_list = NULL; + dma.send_sizes = NULL; + dma.flags = 0; + dma.request_count = 1; + dma.request_size = imesa->bufferSize; + dma.request_list = &idx; + dma.request_sizes = &size; + dma.granted_count = 0; + + + if (SAVAGE_DEBUG & DEBUG_DMA) + fprintf(stderr, "drmDMA (get) ctx %d count %d size 0x%x\n", + dma.context, dma.request_count, + dma.request_size); + + while (1) { + retcode = drmDMA(imesa->driFd, &dma); + + if (SAVAGE_DEBUG & DEBUG_DMA) + 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 (SAVAGE_DEBUG & DEBUG_DMA) + fprintf(stderr, "\n\nflush"); + } + + buf = &(imesa->savageScreen->bufs->list[idx]); + + if (SAVAGE_DEBUG & DEBUG_DMA) + 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); + + imesa->dmaVtxBuf.total = buf->total / 4; + imesa->dmaVtxBuf.used = 0; + imesa->dmaVtxBuf.flushed = 0; + imesa->dmaVtxBuf.idx = buf->idx; + imesa->dmaVtxBuf.buf = (u_int32_t *)buf->address; + + if (SAVAGE_DEBUG & DEBUG_DMA) + fprintf(stderr, "finished getbuffer\n"); +} + +#if 0 +/* Still keeping this around because it demonstrates page flipping and + * automatic z-clear. */ static void savage_BCI_clear(GLcontext *ctx, drm_savage_clear_t *pclear) { savageContextPtr imesa = SAVAGE_CONTEXT(ctx); @@ -113,7 +183,7 @@ static void savage_BCI_clear(GLcontext *ctx, drm_savage_clear_t *pclear) imesa->regs.s4.zBufCtrl.ni.frameID = ~imesa->regs.s4.zBufCtrl.ni.frameID; - imesa->dirty |= SAVAGE_UPLOAD_CTX; + imesa->dirty |= SAVAGE_UPLOAD_GLOBAL; } else { @@ -157,8 +227,6 @@ static void savage_BCI_clear(GLcontext *ctx, drm_savage_clear_t *pclear) savageDMAFlush (imesa); } -struct timeb a,b; - static void savage_BCI_swap(savageContextPtr imesa) { int nbox = imesa->sarea->nbox; @@ -186,7 +254,7 @@ static void savage_BCI_swap(savageContextPtr imesa) imesa->readMap = (char *)imesa->apertureBase[imesa->toggle]; imesa->regs.s4.destCtrl.ni.offset = imesa->savageScreen->backOffset>>11; - imesa->dirty |= SAVAGE_UPLOAD_CTX; + imesa->dirty |= SAVAGE_UPLOAD_GLOBAL; bciptr = SAVAGE_GET_BCI_POINTER(imesa,3); *(bciptr) = 0x960100B0; *(bciptr) = (imesa->savageScreen->frontOffset); @@ -220,97 +288,113 @@ static void savage_BCI_swap(savageContextPtr imesa) } } +#endif + + +static GLboolean intersect_rect( drm_clip_rect_t *out, + const drm_clip_rect_t *a, + const drm_clip_rect_t *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; + + return ((out->x1 < out->x2) && (out->y1 < out->y2)); +} + + +static GLuint savageIntersectClipRects(drm_clip_rect_t *dest, + const drm_clip_rect_t *src, + GLuint nsrc, + const drm_clip_rect_t *clip) +{ + GLuint i, ndest; + + for (i = 0, ndest = 0; i < nsrc; ++i, ++src) { + if (intersect_rect(dest, src, clip)) { + dest++; + ndest++; + } + } + + return ndest; +} static void savageDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, GLint cx, GLint cy, GLint cw, GLint ch ) { savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); - __DRIdrawablePrivate *dPriv = imesa->driDrawable; - const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); - drm_savage_clear_t clear; - int i; + GLuint colorMask, depthMask, clearColor, clearDepth, flags; - clear.flags = 0; - clear.clear_color = imesa->ClearColor; + if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG) + fprintf (stderr, "%s\n", __FUNCTION__); + clearColor = imesa->ClearColor; if(imesa->savageScreen->zpp == 2) - clear.clear_depth = (GLuint) (ctx->Depth.Clear * DEPTH_SCALE_16); + clearDepth = (GLuint) (ctx->Depth.Clear * DEPTH_SCALE_16); else - clear.clear_depth = (GLuint) (ctx->Depth.Clear * DEPTH_SCALE_24); + clearDepth = (GLuint) (ctx->Depth.Clear * DEPTH_SCALE_24); - FLUSH_BATCH( imesa ); + colorMask = *((GLuint *) &ctx->Color.ColorMask); + depthMask = 0; - if ((mask & DD_FRONT_LEFT_BIT) && ((colorMask&0xffffffUL)==0xffffffUL) ){ - clear.flags |= SAVAGE_FRONT; + flags = 0; + + if (mask & DD_FRONT_LEFT_BIT) { + flags |= SAVAGE_FRONT; mask &= ~DD_FRONT_LEFT_BIT; } - if ((mask & DD_BACK_LEFT_BIT) && ((colorMask&0xffffffUL)==0xffffffUL) ) { - clear.flags |= SAVAGE_BACK; + if (mask & DD_BACK_LEFT_BIT) { + flags |= SAVAGE_BACK; mask &= ~DD_BACK_LEFT_BIT; } if ((mask & DD_DEPTH_BIT) && ctx->Depth.Mask) { - clear.flags |= SAVAGE_DEPTH; + flags |= SAVAGE_DEPTH; + depthMask |= + (imesa->savageScreen->zpp == 2) ? 0xffffffff : 0x00ffffff; mask &= ~DD_DEPTH_BIT; } if((mask & DD_STENCIL_BIT) && imesa->hw_stencil) { - clear.flags |= SAVAGE_STENCIL; - mask &= ~DD_STENCIL_BIT; + flags |= SAVAGE_DEPTH; + depthMask |= 0xff000000; + mask &= ~DD_STENCIL_BIT; } - if (clear.flags) { - LOCK_HARDWARE( imesa ); - - /* flip top to bottom */ - cy = dPriv->h-cy-ch; - cx += imesa->drawX; - cy += imesa->drawY; - - for (i = 0 ; i < imesa->numClipRects ; ) { - int nr = MIN2(i + SAVAGE_NR_SAREA_CLIPRECTS, imesa->numClipRects); - drm_clip_rect_t *box = imesa->pClipRects; - drm_clip_rect_t *b = imesa->sarea->boxes; - int n = 0; - - if (!all) { - for ( ; i < nr ; i++) { - GLint x = box[i].x1; - GLint y = box[i].y1; - GLint w = box[i].x2 - x; - GLint h = box[i].y2 - y; - - if (x < cx) w -= cx - x, x = cx; - if (y < cy) h -= cy - y, y = cy; - if (x + w > cx + cw) w = cx + cw - x; - if (y + h > cy + ch) h = cy + ch - y; - if (w <= 0) continue; - if (h <= 0) continue; - - b->x1 = x; - b->y1 = y; - b->x2 = x + w; - b->y2 = y + h; - b++; - n++; - } - } else { - for ( ; i < nr ; i++) { - *b++ = *(drm_clip_rect_t *)&box[i]; - n++; - } - } - - imesa->sarea->nbox = n; - - savage_BCI_clear(ctx,&clear); + savageFlushVertices(imesa); + + if (flags) { + GLboolean depthCleared = GL_FALSE; + if (flags & (SAVAGE_FRONT|SAVAGE_BACK)) { + drm_savage_cmd_header_t *cmd; + cmd = savageAllocCmdBuf(imesa, sizeof(drm_savage_cmd_header_t)); + cmd[0].clear0.cmd = SAVAGE_CMD_CLEAR; + if ((flags & SAVAGE_DEPTH) && + clearDepth == clearColor && depthMask == colorMask) { + cmd[0].clear0.flags = flags; + depthCleared = GL_TRUE; + } else + cmd[0].clear0.flags = flags & (SAVAGE_FRONT|SAVAGE_BACK); + cmd[1].clear1.mask = colorMask; + cmd[1].clear1.value = clearColor; + } + + if ((flags & SAVAGE_DEPTH) && !depthCleared) { + drm_savage_cmd_header_t *cmd; + cmd = savageAllocCmdBuf(imesa, sizeof(drm_savage_cmd_header_t)); + cmd[0].clear0.cmd = SAVAGE_CMD_CLEAR; + cmd[0].clear0.flags = SAVAGE_DEPTH; + cmd[1].clear1.mask = depthMask; + cmd[1].clear1.value = clearDepth; } - UNLOCK_HARDWARE( imesa ); - imesa->dirty |= SAVAGE_UPLOAD_CLIPRECTS|SAVAGE_UPLOAD_CTX; + imesa->dirty |= SAVAGE_UPLOAD_CLIPRECTS; } if (mask) @@ -318,7 +402,11 @@ static void savageDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, } - +/* This is necessary as to prevent annyoing stuttering effects with + * some games, though it does reduce the frame rate (glxgears) + * slightly. I believe this is due to texture uploads which do not go + * through the Savage command pipeline yet. */ +#define SYNC_FRAMES 1 /* * Copy the back buffer to the front buffer. @@ -326,11 +414,9 @@ static void savageDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, void savageSwapBuffers( __DRIdrawablePrivate *dPriv ) { savageContextPtr imesa; - drm_clip_rect_t *pbox; - int nbox; - int i; - GLboolean pending; + if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG) + fprintf (stderr, "%s\n================================\n", __FUNCTION__); assert(dPriv); assert(dPriv->driContextPriv); @@ -342,38 +428,30 @@ void savageSwapBuffers( __DRIdrawablePrivate *dPriv ) FLUSH_BATCH(imesa); - LOCK_HARDWARE( imesa ); - WAIT_IDLE_EMPTY; - PAGE_PENDING(pending); - - if(!pending) - { - pbox = dPriv->pClipRects; - nbox = dPriv->numClipRects; +#if SYNC_FRAMES + imesa->lastSwap = savageEmitEvent( imesa, 0 ); +#endif + if (imesa->lastSwap != 0) + savageWaitEvent( imesa, imesa->lastSwap ); - for (i = 0 ; i < nbox ; ) { - int nr = MIN2(i + SAVAGE_NR_SAREA_CLIPRECTS, dPriv->numClipRects); - drm_clip_rect_t *b = (drm_clip_rect_t *)imesa->sarea->boxes; - - imesa->sarea->nbox = nr - i; - - for ( ; i < nr ; i++) - *b++ = pbox[i]; - savage_BCI_swap(imesa) ; + drm_savage_cmd_header_t *cmd = savageAllocCmdBuf(imesa, 0); + cmd->cmd.cmd = SAVAGE_CMD_SWAP; + imesa->inSwap = GL_TRUE; /* ignore scissors in savageFlushCmdBuf */ + savageFlushCmdBuf(imesa, GL_FALSE); + imesa->inSwap = GL_FALSE; } - } - UNLOCK_HARDWARE( imesa ); - +#if !SYNC_FRAMES + imesa->lastSwap = savageEmitEvent( imesa, 0 ); +#endif } /* This waits for *everybody* to finish rendering -- overkill. */ void savageDmaFinish( savageContextPtr imesa ) { - savageDMAFlush(imesa); - WAIT_IDLE_EMPTY; + savageWaitEvent( imesa, savageEmitEventLocked( imesa, SAVAGE_WAIT_3D ) ); } @@ -393,152 +471,189 @@ void savageWaitAge( savageContextPtr imesa, int age ) } +unsigned int savageEmitEventLocked( savageContextPtr imesa, unsigned int flags ) +{ + drm_savage_event_emit_t event; + int ret; + event.count = 0; + event.flags = flags; + ret = drmCommandWriteRead( imesa->driFd, DRM_SAVAGE_BCI_EVENT_EMIT, + &event, sizeof(event) ); + if (ret) { + fprintf (stderr, "emit event returned %d\n", ret); + exit (1); + } + return event.count; +} +unsigned int savageEmitEvent( savageContextPtr imesa, unsigned int flags ) +{ + unsigned int ret; + LOCK_HARDWARE( imesa ); + ret = savageEmitEventLocked( imesa, flags ); + UNLOCK_HARDWARE( imesa ); + return ret; +} -void savageFlushVerticesLocked( savageContextPtr imesa ) + +void savageWaitEvent( savageContextPtr imesa, unsigned int count ) { - drmBufPtr buffer = imesa->vertex_dma_buffer; + drm_savage_event_wait_t event; + int ret; + event.count = count; + event.flags = 0; + ret = drmCommandWriteRead( imesa->driFd, DRM_SAVAGE_BCI_EVENT_WAIT, + &event, sizeof(event) ); + if (ret) { + fprintf (stderr, "wait event returned %d\n", ret); + exit (1); + } +} - if (!buffer) - return; - imesa->vertex_dma_buffer = NULL; +void savageFlushVertices( savageContextPtr imesa ) +{ + struct savage_vtxbuf_t *buffer = imesa->vtxBuf; + + if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG) + fprintf (stderr, "%s\n", __FUNCTION__); - /* Lot's of stuff to do here. For now there is a fake DMA implementation - * in savagedma.c that emits drawing commands. Cliprects are not handled - * yet. */ - if (buffer->used) { + if (!buffer->total) + return; + + if (buffer->used > buffer->flushed) { + drm_savage_cmd_header_t *cmd; /* State must be updated "per primitive" because hardware * culling must be disabled for unfilled primitives, points * and lines. */ - savageEmitHwStateLocked (imesa); - savageFakeVertices (imesa, buffer); + savageEmitChangedState (imesa); + cmd = savageAllocCmdBuf(imesa, 0); + cmd->prim.cmd = buffer == &imesa->dmaVtxBuf ? + SAVAGE_CMD_DMA_PRIM : SAVAGE_CMD_VB_PRIM; + cmd->prim.prim = imesa->HwPrim; + cmd->prim.skip = imesa->skip; + cmd->prim.start = buffer->flushed / imesa->HwVertexSize; + cmd->prim.count = buffer->used / imesa->HwVertexSize - cmd->prim.start; + buffer->flushed = buffer->used; + /* Make sure we don't buffer too many vertices without + * telling the hardware. */ + imesa->vertsPending += cmd->prim.count; + if (imesa->vertsPending > SAVAGE_MAX_VERTS_PENDING) { + savageFlushCmdBuf(imesa, GL_FALSE); + imesa->vertsPending = 0; + } } } - -void savageFlushVertices( savageContextPtr imesa ) +void savageFlushCmdBufLocked( savageContextPtr imesa, GLboolean discard ) { - LOCK_HARDWARE(imesa); - savageFlushVerticesLocked (imesa); - UNLOCK_HARDWARE(imesa); + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + drm_savage_cmdbuf_t cmdbuf; + drm_savage_cmd_header_t *start; + int ret; + + /* If we lost the context we must restore the initial state (at + * the start of the command buffer). */ + if (imesa->lostContext) { + start = imesa->cmdBuf.base; + imesa->lostContext = GL_FALSE; + } else + start = imesa->cmdBuf.start; + + if (!imesa->dmaVtxBuf.total) + discard = GL_FALSE; + + if ((SAVAGE_DEBUG & DEBUG_DMA) && discard) + fprintf (stderr, "Discarding DMA buffer, used=%u\n", + imesa->dmaVtxBuf.used); + + cmdbuf.dma_idx = imesa->dmaVtxBuf.idx; + cmdbuf.discard = discard; + cmdbuf.vb_addr = imesa->clientVtxBuf.buf; + cmdbuf.vb_size = imesa->clientVtxBuf.total*4; + cmdbuf.vb_stride = imesa->HwVertexSize; + cmdbuf.cmd_addr = start; + cmdbuf.size = (imesa->cmdBuf.write - start); + if (!imesa->inSwap && imesa->glCtx->Scissor.Enabled) { + drm_clip_rect_t *box = dPriv->pClipRects, *ibox; + GLuint nbox = dPriv->numClipRects, nibox; + ibox = malloc(dPriv->numClipRects*sizeof(drm_clip_rect_t)); + if (!ibox) { + fprintf(stderr, "Out of memory.\n"); + exit(1); + } + nibox = savageIntersectClipRects(ibox, box, nbox, &imesa->scissor_rect); + cmdbuf.nbox = nibox; + cmdbuf.box_addr = ibox; + } else { + cmdbuf.nbox = dPriv->numClipRects; + cmdbuf.box_addr = dPriv->pClipRects; + } + + ret = drmCommandWrite( imesa->driFd, DRM_SAVAGE_BCI_CMDBUF, + &cmdbuf, sizeof(cmdbuf) ); + if (ret) { + fprintf (stderr, "cmdbuf ioctl returned %d\n", ret); + exit(1); + } + + if (cmdbuf.box_addr != dPriv->pClipRects) { + free(cmdbuf.box_addr); + } + + if (discard) { + imesa->dmaVtxBuf.total = 0; + imesa->dmaVtxBuf.used = 0; + imesa->dmaVtxBuf.flushed = 0; + } + imesa->clientVtxBuf.used = 0; + imesa->clientVtxBuf.flushed = 0; + + imesa->cmdBuf.write = imesa->cmdBuf.base; + + /* Save the current state at the start of the command buffer. That + * state will only be emitted, if the context was lost since the + * last command buffer. */ + savageEmitOldState(imesa); + imesa->cmdBuf.start = imesa->cmdBuf.write; } -int savage_check_copy(int fd) +void savageFlushCmdBuf( savageContextPtr imesa, GLboolean discard ) { - return 0; + if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG) + fprintf (stderr, "%s\n", __FUNCTION__); + LOCK_HARDWARE(imesa); + savageFlushCmdBufLocked (imesa, discard); + UNLOCK_HARDWARE(imesa); } + static void savageDDFlush( GLcontext *ctx ) { + if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG) + fprintf (stderr, "%s\n", __FUNCTION__); savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + savageFlushVertices (imesa); LOCK_HARDWARE(imesa); - savageFlushVerticesLocked (imesa); - savageDMAFlush (imesa); + savageFlushCmdBufLocked(imesa, GL_FALSE); UNLOCK_HARDWARE(imesa); } static void savageDDFinish( GLcontext *ctx ) { + if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG) + fprintf (stderr, "%s\n", __FUNCTION__); savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + savageFlushVertices (imesa); LOCK_HARDWARE(imesa); - savageFlushVerticesLocked (imesa); + savageFlushCmdBufLocked(imesa, GL_FALSE); savageDmaFinish (imesa); UNLOCK_HARDWARE(imesa); } -#define ALT_STATUS_WORD0 (* (volatile GLuint *)(imesa->MMIO_BASE+0x48c60)) -#define STATUS_WORD0 (* (volatile GLuint *)(imesa->MMIO_BASE+0x48c00)) -#define MAXFIFO_S4 0x7F00 -#define MAXFIFO_S3D 0x7F00 - -static GLboolean savagePagePending_s4( savageContextPtr imesa ) { - return (ALT_STATUS_WORD0 & 0x08000000) ? GL_TRUE : GL_FALSE; -} -static GLboolean savagePagePending_s3d( savageContextPtr imesa ) { - return GL_FALSE; -} -static void savageWaitForFIFO_s4( savageContextPtr imesa, unsigned count ) { - int loop = 0; - int slots = MAXFIFO_S4-count; - while((ALT_STATUS_WORD0 & 0x001fffff) > slots && loop++ < MAXLOOP); -} -static void savageWaitForFIFO_s3d( savageContextPtr imesa, unsigned count ) { - int loop = 0; - int slots = MAXFIFO_S3D-count; - while((STATUS_WORD0 & 0x0001ffff) > slots && loop++ < MAXLOOP); -} -static void savageWaitIdleEmpty_s4( savageContextPtr imesa ) { - int loop = 0; - while((ALT_STATUS_WORD0 & 0x00ffffff) != 0x00E00000L && loop++ < MAXLOOP); -} -static void savageWaitIdleEmpty_s3d( savageContextPtr imesa ) { - int loop = 0; - while((STATUS_WORD0 & 0x000fffff) != 0x000E0000L && loop++ < MAXLOOP); -} - -GLboolean (*savagePagePending)( savageContextPtr imesa ) = NULL; -void (*savageWaitForFIFO)( savageContextPtr imesa, unsigned count ) = NULL; -void (*savageWaitIdleEmpty)( savageContextPtr imesa ) = NULL; - - void savageDDInitIoctlFuncs( GLcontext *ctx ) { ctx->Driver.Clear = savageDDClear; ctx->Driver.Flush = savageDDFlush; ctx->Driver.Finish = savageDDFinish; - if (SAVAGE_CONTEXT( ctx )->savageScreen->chipset >= S3_SAVAGE4) { - savagePagePending = savagePagePending_s4; - savageWaitForFIFO = savageWaitForFIFO_s4; - savageWaitIdleEmpty = savageWaitIdleEmpty_s4; - } else { - savagePagePending = savagePagePending_s3d; - savageWaitForFIFO = savageWaitForFIFO_s3d; - savageWaitIdleEmpty = savageWaitIdleEmpty_s3d; - } -} - -#if SAVAGE_CMD_DMA -/* Alloc a continuous memory */ -/* return: 0 error when kernel alloc pages(can try a half memory size) - >0 sucess - <0 Other error*/ -int savageAllocDMABuffer(savageContextPtr imesa, drm_savage_alloc_cont_mem_t *req) -{ - int ret; - if (req ==NULL) - return 0; - - if ((ret=ioctl(imesa->driFd, DRM_IOCTL_SAVAGE_ALLOC_CONTINUOUS_MEM, req)) <=0) - return ret; - - return 1; - } - -/* get the physics address*/ -GLuint savageGetPhyAddress(savageContextPtr imesa,void * pointer) -{ - - drm_savage_get_physcis_address_t req; - int ret; - - req.v_address = (GLuint )pointer; - ret = ioctl(imesa->driFd, DRM_IOCTL_SAVAGE_GET_PHYSICS_ADDRESS,&req); - - return req.p_address; -} - -/* free the buffer got by savageAllocDMABuffe*/ -int savageFreeDMABuffer(savageContextPtr imesa, drm_savage_alloc_cont_mem_t *req) -{ - GLuint ret; - if (req ==NULL) - return 0; - - if ((ret=ioctl(imesa->driFd, DRM_IOCTL_SAVAGE_FREE_CONTINUOUS_MEM, req)) <=0) - return ret; - return 1; - -} -#endif diff --git a/src/mesa/drivers/dri/savage/savageioctl.h b/src/mesa/drivers/dri/savage/savageioctl.h index acf398b9a6..941e74e56b 100644 --- a/src/mesa/drivers/dri/savage/savageioctl.h +++ b/src/mesa/drivers/dri/savage/savageioctl.h @@ -27,17 +27,22 @@ #define SAVAGE_IOCTL_H #include "savagecontext.h" -#include "savagedma.h" void savageGetGeneralDmaBufferLocked( savageContextPtr mmesa ); void savageFlushVertices( savageContextPtr mmesa ); -void savageFlushVerticesLocked( savageContextPtr mmesa ); void savageFlushGeneralLocked( savageContextPtr imesa ); void savageWaitAgeLocked( savageContextPtr imesa, int age ); void savageWaitAge( savageContextPtr imesa, int age ); +unsigned int savageEmitEventLocked( savageContextPtr imesa, unsigned int flags ); +unsigned int savageEmitEvent( savageContextPtr imesa, unsigned int flags ); +void savageWaitEvent( savageContextPtr imesa, unsigned int event); + +void savageFlushCmdBufLocked( savageContextPtr imesa, GLboolean discard ); +void savageFlushCmdBuf( savageContextPtr imesa, GLboolean discard ); + void savageDmaFinish( savageContextPtr imesa ); void savageRegetLockQuiescent( savageContextPtr imesa ); @@ -46,54 +51,69 @@ void savageDDInitIoctlFuncs( GLcontext *ctx ); void savageSwapBuffers( __DRIdrawablePrivate *dPriv ); -int savage_check_copy(int fd); - -extern GLboolean (*savagePagePending)( savageContextPtr imesa ); -extern void (*savageWaitForFIFO)( savageContextPtr imesa, unsigned count ); -extern void (*savageWaitIdleEmpty)( savageContextPtr imesa ); - -#define PAGE_PENDING(result) do { \ - result = savagePagePending(imesa); \ -} while (0) -#define WAIT_FOR_FIFO(count) do { \ - savageWaitForFIFO(imesa, count); \ -} while (0) #define WAIT_IDLE_EMPTY do { \ - savageWaitIdleEmpty(imesa); \ + savageWaitEvent(imesa, \ + savageEmitEvent(imesa, SAVAGE_WAIT_3D|SAVAGE_WAIT_2D)); \ } while (0) -#if SAVAGE_CMD_DMA -int savageAllocDMABuffer(savageContextPtr imesa, drm_savage_alloc_cont_mem_t *req); -GLuint savageGetPhyAddress(savageContextPtr imesa,void * pointer); -int savageFreeDMABuffer(savageContextPtr, drm_savage_alloc_cont_mem_t*); -#endif - #define FLUSH_BATCH(imesa) do { \ - if (imesa->vertex_dma_buffer) savageFlushVertices(imesa); \ + if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG) \ + fprintf (stderr, "FLUSH_BATCH in %s\n", __FUNCTION__); \ + savageFlushVertices(imesa); \ + savageFlushCmdBuf(imesa, GL_FALSE); \ } while (0) +extern void savageGetDMABuffer( savageContextPtr imesa ); + static __inline -u_int32_t *savageAllocDmaLow( savageContextPtr imesa, GLuint bytes ) +u_int32_t *savageAllocVtxBuf( savageContextPtr imesa, GLuint words ) { + struct savage_vtxbuf_t *buffer = imesa->vtxBuf; u_int32_t *head; - if (!imesa->vertex_dma_buffer) { - LOCK_HARDWARE(imesa); - imesa->vertex_dma_buffer = savageFakeGetBuffer (imesa); - UNLOCK_HARDWARE(imesa); - } else if (imesa->vertex_dma_buffer->used + bytes > - imesa->vertex_dma_buffer->total) { - LOCK_HARDWARE(imesa); - savageFlushVerticesLocked( imesa ); - imesa->vertex_dma_buffer = savageFakeGetBuffer (imesa); - UNLOCK_HARDWARE(imesa); + if (buffer == &imesa->dmaVtxBuf) { + if (!buffer->total) { + LOCK_HARDWARE(imesa); + savageGetDMABuffer(imesa); + UNLOCK_HARDWARE(imesa); + } else if (buffer->used + words > buffer->total) { + if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG) + fprintf (stderr, "... flushing DMA buffer in %s\n", + __FUNCTION__); + savageFlushVertices( imesa ); + LOCK_HARDWARE(imesa); + savageFlushCmdBufLocked(imesa, GL_TRUE); /* discard DMA buffer */ + savageGetDMABuffer(imesa); + UNLOCK_HARDWARE(imesa); + } + } else if (buffer->used + words > buffer->total) { + if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG) + fprintf (stderr, "... flushing client vertex buffer in %s\n", + __FUNCTION__); + savageFlushVertices( imesa ); + LOCK_HARDWARE(imesa); + savageFlushCmdBufLocked(imesa, GL_FALSE); /* free clientVtxBuf */ + UNLOCK_HARDWARE(imesa); } - head = (u_int32_t *)((u_int8_t *)imesa->vertex_dma_buffer->address + - imesa->vertex_dma_buffer->used); + head = &buffer->buf[buffer->used]; - imesa->vertex_dma_buffer->used += bytes; + buffer->used += words; return head; } +static __inline +drm_savage_cmd_header_t *savageAllocCmdBuf( savageContextPtr imesa, GLuint bytes ) +{ + drm_savage_cmd_header_t *ret; + GLuint qwords = ((bytes + 7) >> 3) + 1; /* round up */ + assert (qwords < imesa->cmdBuf.size); + if (imesa->cmdBuf.write - imesa->cmdBuf.base + qwords > imesa->cmdBuf.size) { + savageFlushCmdBuf(imesa, GL_FALSE); + } + ret = (drm_savage_cmd_header_t *)imesa->cmdBuf.write; + imesa->cmdBuf.write += qwords; + return ret; +} + #endif diff --git a/src/mesa/drivers/dri/savage/savagestate.c b/src/mesa/drivers/dri/savage/savagestate.c index f4f22602d8..d6048291be 100644 --- a/src/mesa/drivers/dri/savage/savagestate.c +++ b/src/mesa/drivers/dri/savage/savagestate.c @@ -69,16 +69,10 @@ static __inline__ GLuint savagePackColor(GLuint format, static void savageDDAlphaFunc_s4(GLcontext *ctx, GLenum func, GLfloat ref) { - /* This can be done in BlendFunc*/ - savageContextPtr imesa = SAVAGE_CONTEXT(ctx); - imesa->dirty |= SAVAGE_UPLOAD_CTX; savageBlendFunc_s4(ctx); } static void savageDDAlphaFunc_s3d(GLcontext *ctx, GLenum func, GLfloat ref) { - /* This can be done in BlendFunc*/ - savageContextPtr imesa = SAVAGE_CONTEXT(ctx); - imesa->dirty |= SAVAGE_UPLOAD_CTX; savageBlendFunc_s3d(ctx); } @@ -103,6 +97,9 @@ static void savageDDBlendEquationSeparate(GLcontext *ctx, static void savageBlendFunc_s4(GLcontext *ctx) { savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + u_int32_t drawLocalCtrl = imesa->regs.s4.drawLocalCtrl.ui; + u_int32_t drawCtrl0 = imesa->regs.s4.drawCtrl0.ui; + u_int32_t drawCtrl1 = imesa->regs.s4.drawCtrl1.ui; /* set up draw control register (including blending, alpha * test, and shading model) @@ -266,11 +263,17 @@ static void savageBlendFunc_s4(GLcontext *ctx) /*imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn = ~drawLocalCtrl.ni.wrZafterAlphaTst;*/ - imesa->dirty |= SAVAGE_UPLOAD_CTX; + if (drawLocalCtrl != imesa->regs.s4.drawLocalCtrl.ui) + imesa->dirty |= SAVAGE_UPLOAD_LOCAL; + if (drawCtrl0 != imesa->regs.s4.drawCtrl0.ui || + drawCtrl1 != imesa->regs.s4.drawCtrl1.ui) + imesa->dirty |= SAVAGE_UPLOAD_GLOBAL; } static void savageBlendFunc_s3d(GLcontext *ctx) { savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + u_int32_t drawCtrl = imesa->regs.s3d.drawCtrl.ui; + u_int32_t zBufCtrl = imesa->regs.s3d.zBufCtrl.ui; /* set up draw control register (including blending, alpha * test, dithering, and shading model) @@ -432,7 +435,9 @@ static void savageBlendFunc_s3d(GLcontext *ctx) imesa->regs.s3d.zBufCtrl.ni.wrZafterAlphaTst = imesa->regs.s3d.drawCtrl.ni.alphaTestEn; - imesa->dirty |= SAVAGE_UPLOAD_CTX; + if (drawCtrl != imesa->regs.s3d.drawCtrl.ui || + zBufCtrl != imesa->regs.s3d.zBufCtrl.ui) + imesa->dirty |= SAVAGE_UPLOAD_LOCAL; } static void savageDDBlendFuncSeparate_s4( GLcontext *ctx, GLenum sfactorRGB, @@ -456,7 +461,9 @@ static void savageDDDepthFunc_s4(GLcontext *ctx, GLenum func) { savageContextPtr imesa = SAVAGE_CONTEXT(ctx); ZCmpFunc zmode; -#define depthIndex 0 + u_int32_t drawLocalCtrl = imesa->regs.s4.drawLocalCtrl.ui; + u_int32_t zBufCtrl = imesa->regs.s4.zBufCtrl.ui; + u_int32_t zWatermarks = imesa->regs.s4.zWatermarks.ui; /* FIXME: in DRM */ /* set up z-buffer control register (global) * set up z-buffer offset register (global) @@ -513,14 +520,20 @@ static void savageDDDepthFunc_s4(GLcontext *ctx, GLenum func) imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites = GL_FALSE; imesa->regs.s4.zWatermarks.ni.wLow = 8; } - - imesa->dirty |= SAVAGE_UPLOAD_CTX; + + if (drawLocalCtrl != imesa->regs.s4.drawLocalCtrl.ui) + imesa->dirty |= SAVAGE_UPLOAD_LOCAL; + if (zBufCtrl != imesa->regs.s4.zBufCtrl.ui || + zWatermarks != imesa->regs.s4.zWatermarks.ui) + imesa->dirty |= SAVAGE_UPLOAD_GLOBAL; } static void savageDDDepthFunc_s3d(GLcontext *ctx, GLenum func) { savageContextPtr imesa = SAVAGE_CONTEXT(ctx); ZCmpFunc zmode; -#define depthIndex 0 + u_int32_t drawCtrl = imesa->regs.s3d.drawCtrl.ui; + u_int32_t zBufCtrl = imesa->regs.s3d.zBufCtrl.ui; + u_int32_t zWatermarks = imesa->regs.s3d.zWatermarks.ui; /* FIXME: in DRM */ /* set up z-buffer control register (global) * set up z-buffer offset register (global) @@ -565,14 +578,18 @@ static void savageDDDepthFunc_s3d(GLcontext *ctx, GLenum func) imesa->regs.s3d.zWatermarks.ni.wLow = 8; } - imesa->dirty |= SAVAGE_UPLOAD_CTX; + if (drawCtrl != imesa->regs.s3d.drawCtrl.ui || + zBufCtrl != imesa->regs.s3d.zBufCtrl.ui) + imesa->dirty |= SAVAGE_UPLOAD_LOCAL; + if (zWatermarks != imesa->regs.s3d.zWatermarks.ui) + imesa->dirty |= SAVAGE_UPLOAD_GLOBAL; } static void savageDDDepthMask_s4(GLcontext *ctx, GLboolean flag) { savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + u_int32_t drawLocalCtrl = imesa->regs.s4.drawLocalCtrl.ui; - imesa->dirty |= SAVAGE_UPLOAD_CTX; if (flag) { imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites = GL_TRUE; @@ -582,12 +599,15 @@ static void savageDDDepthMask_s4(GLcontext *ctx, GLboolean flag) imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites = GL_FALSE; } savageDDDepthFunc_s4(ctx,ctx->Depth.Func); + + if (drawLocalCtrl != imesa->regs.s4.drawLocalCtrl.ui) + imesa->dirty |= SAVAGE_UPLOAD_LOCAL; } static void savageDDDepthMask_s3d(GLcontext *ctx, GLboolean flag) { savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + u_int32_t drawCtrl = imesa->regs.s3d.drawCtrl.ui; - imesa->dirty |= SAVAGE_UPLOAD_CTX; if (flag) { imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_TRUE; @@ -597,6 +617,9 @@ static void savageDDDepthMask_s3d(GLcontext *ctx, GLboolean flag) imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_FALSE; } savageDDDepthFunc_s3d(ctx,ctx->Depth.Func); + + if (drawCtrl != imesa->regs.s3d.drawCtrl.ui) + imesa->dirty |= SAVAGE_UPLOAD_LOCAL; } @@ -629,6 +652,7 @@ static void savageDDScissor( GLcontext *ctx, GLint x, GLint y, static void savageDDDrawBuffer(GLcontext *ctx, GLenum mode ) { savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + u_int32_t destCtrl = imesa->regs.s4.destCtrl.ui; /* * _DrawDestMask is easier to cope with than . @@ -641,7 +665,6 @@ static void savageDDDrawBuffer(GLcontext *ctx, GLenum mode ) imesa->readMap = (char *)imesa->apertureBase[TARGET_FRONT]; imesa->regs.s4.destCtrl.ni.offset = imesa->savageScreen->frontOffset>>11; imesa->NotFirstFrame = GL_FALSE; - imesa->dirty |= SAVAGE_UPLOAD_BUFFERS | SAVAGE_UPLOAD_CTX; savageXMesaSetFrontClipRects( imesa ); FALLBACK( ctx, SAVAGE_FALLBACK_DRAW_BUFFER, GL_FALSE ); break; @@ -651,7 +674,6 @@ static void savageDDDrawBuffer(GLcontext *ctx, GLenum mode ) imesa->readMap = (char *)imesa->apertureBase[TARGET_BACK]; imesa->regs.s4.destCtrl.ni.offset = imesa->savageScreen->backOffset>>11; imesa->NotFirstFrame = GL_FALSE; - imesa->dirty |= SAVAGE_UPLOAD_BUFFERS | SAVAGE_UPLOAD_CTX; savageXMesaSetBackClipRects( imesa ); FALLBACK( ctx, SAVAGE_FALLBACK_DRAW_BUFFER, GL_FALSE ); break; @@ -664,6 +686,9 @@ static void savageDDDrawBuffer(GLcontext *ctx, GLenum mode ) * gets called. */ _swrast_DrawBuffer(ctx, mode); + + if (destCtrl != imesa->regs.s4.destCtrl.ui) + imesa->dirty |= SAVAGE_UPLOAD_GLOBAL; } static void savageDDReadBuffer(GLcontext *ctx, GLenum mode ) @@ -800,12 +825,12 @@ static void savageUpdateCull( GLcontext *ctx ) if (imesa->savageScreen->chipset >= S3_SAVAGE4) { if (imesa->regs.s4.drawCtrl1.ni.cullMode != cullMode) { imesa->regs.s4.drawCtrl1.ni.cullMode = cullMode; - imesa->dirty |= SAVAGE_UPLOAD_CTX; + imesa->dirty |= SAVAGE_UPLOAD_GLOBAL; } } else { if (imesa->regs.s3d.drawCtrl.ni.cullMode != cullMode) { imesa->regs.s3d.drawCtrl.ni.cullMode = cullMode; - imesa->dirty |= SAVAGE_UPLOAD_CTX; + imesa->dirty |= SAVAGE_UPLOAD_LOCAL; } } #endif /* end #if HW_CULL */ @@ -846,7 +871,7 @@ static void savageDDColorMask_s4(GLcontext *ctx, { imesa->regs.s4.drawLocalCtrl.ni.drawUpdateEn = GL_FALSE; } - imesa->dirty |= SAVAGE_UPLOAD_CTX; + imesa->dirty |= SAVAGE_UPLOAD_LOCAL; /* TODO: need a software fallback */ } static void savageDDColorMask_s3d(GLcontext *ctx, @@ -873,7 +898,7 @@ static void savageDDColorMask_s3d(GLcontext *ctx, { imesa->regs.s3d.zBufCtrl.ni.drawUpdateEn = GL_FALSE; } - imesa->dirty |= SAVAGE_UPLOAD_CTX; + imesa->dirty |= SAVAGE_UPLOAD_LOCAL; /* TODO: need a software fallback */ } @@ -886,6 +911,7 @@ static void savageDDColorMask_s3d(GLcontext *ctx, */ static void savageUpdateSpecular_s4(GLcontext *ctx) { savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); + u_int32_t drawLocalCtrl = imesa->regs.s4.drawLocalCtrl.ui; if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR && ctx->Light.Enabled) { @@ -895,10 +921,13 @@ static void savageUpdateSpecular_s4(GLcontext *ctx) { imesa->regs.s4.drawLocalCtrl.ni.specShadeEn = GL_FALSE; /*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_FALSE);*/ } - imesa->dirty |= SAVAGE_UPLOAD_CTX; + + if (drawLocalCtrl != imesa->regs.s4.drawLocalCtrl.ui) + imesa->dirty |= SAVAGE_UPLOAD_LOCAL; } static void savageUpdateSpecular_s3d(GLcontext *ctx) { savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); + u_int32_t drawCtrl = imesa->regs.s3d.drawCtrl.ui; if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR && ctx->Light.Enabled) { @@ -908,7 +937,9 @@ static void savageUpdateSpecular_s3d(GLcontext *ctx) { imesa->regs.s3d.drawCtrl.ni.specShadeEn = GL_FALSE; /*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_FALSE);*/ } - imesa->dirty |= SAVAGE_UPLOAD_CTX; + + if (drawCtrl != imesa->regs.s3d.drawCtrl.ui) + imesa->dirty |= SAVAGE_UPLOAD_LOCAL; } static void savageDDLightModelfv_s4(GLcontext *ctx, GLenum pname, @@ -925,6 +956,7 @@ static void savageDDLightModelfv_s3d(GLcontext *ctx, GLenum pname, static void savageDDShadeModel_s4(GLcontext *ctx, GLuint mod) { savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); + u_int32_t drawLocalCtrl = imesa->regs.s4.drawLocalCtrl.ui; if (mod == GL_SMOOTH) { @@ -934,11 +966,14 @@ static void savageDDShadeModel_s4(GLcontext *ctx, GLuint mod) { imesa->regs.s4.drawLocalCtrl.ni.flatShadeEn = GL_TRUE; } - imesa->dirty |= SAVAGE_UPLOAD_CTX; + + if (drawLocalCtrl != imesa->regs.s4.drawLocalCtrl.ui) + imesa->dirty |= SAVAGE_UPLOAD_LOCAL; } static void savageDDShadeModel_s3d(GLcontext *ctx, GLuint mod) { savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); + u_int32_t drawCtrl = imesa->regs.s3d.drawCtrl.ui; if (mod == GL_SMOOTH) { @@ -948,7 +983,9 @@ static void savageDDShadeModel_s3d(GLcontext *ctx, GLuint mod) { imesa->regs.s3d.drawCtrl.ni.flatShadeEn = GL_TRUE; } - imesa->dirty |= SAVAGE_UPLOAD_CTX; + + if (drawCtrl != imesa->regs.s3d.drawCtrl.ui) + imesa->dirty |= SAVAGE_UPLOAD_LOCAL; } @@ -962,6 +999,7 @@ static void savageDDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param) { savageContextPtr imesa = SAVAGE_CONTEXT(ctx); GLuint fogClr; + u_int32_t fogCtrl = imesa->regs.s4.fogCtrl.ui; /*if ((ctx->Fog.Enabled) &&(pname == GL_FOG_COLOR))*/ if (ctx->Fog.Enabled) @@ -981,17 +1019,19 @@ static void savageDDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param) imesa->regs.s4.fogCtrl.ni.fogEn = 0; imesa->regs.s4.fogCtrl.ni.fogMode = 0; } - imesa->dirty |= SAVAGE_UPLOAD_CTX; -} + if (fogCtrl != imesa->regs.s4.fogCtrl.ui) + imesa->dirty |= SAVAGE_UPLOAD_GLOBAL; +} -static void savageStencilFunc(GLcontext *); static void savageDDStencilFunc(GLcontext *ctx, GLenum func, GLint ref, GLuint mask) { savageContextPtr imesa = SAVAGE_CONTEXT(ctx); SCmpFunc a=0; + u_int32_t zBufCtrl = imesa->regs.s4.zBufCtrl.ui; + u_int32_t stencilCtrl = imesa->regs.s4.stencilCtrl.ui; imesa->regs.s4.zBufCtrl.ni.stencilRefVal = ctx->Stencil.Ref[0]; imesa->regs.s4.stencilCtrl.ni.readMask = ctx->Stencil.ValueMask[0]; @@ -1012,22 +1052,26 @@ static void savageDDStencilFunc(GLcontext *ctx, GLenum func, GLint ref, imesa->regs.s4.stencilCtrl.ni.cmpFunc = a; - imesa->dirty |= SAVAGE_UPLOAD_CTX; + if (zBufCtrl != imesa->regs.s4.zBufCtrl.ui || + stencilCtrl != imesa->regs.s4.stencilCtrl.ui) + imesa->dirty |= SAVAGE_UPLOAD_GLOBAL; } static void savageDDStencilMask(GLcontext *ctx, GLuint mask) { savageContextPtr imesa = SAVAGE_CONTEXT(ctx); - imesa->regs.s4.stencilCtrl.ni.writeMask = ctx->Stencil.WriteMask[0]; - - imesa->dirty |= SAVAGE_UPLOAD_CTX; + if (imesa->regs.s4.stencilCtrl.ni.writeMask != ctx->Stencil.WriteMask[0]) { + imesa->regs.s4.stencilCtrl.ni.writeMask = ctx->Stencil.WriteMask[0]; + imesa->dirty |= SAVAGE_UPLOAD_GLOBAL; + } } static void savageDDStencilOp(GLcontext *ctx, GLenum fail, GLenum zfail, GLenum zpass) { savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + u_int32_t stencilCtrl = imesa->regs.s4.stencilCtrl.ui; switch (ctx->Stencil.FailFunc[0]) { @@ -1114,7 +1158,8 @@ static void savageDDStencilOp(GLcontext *ctx, GLenum fail, GLenum zfail, break; } - imesa->dirty |= SAVAGE_UPLOAD_CTX; + if (stencilCtrl != imesa->regs.s4.stencilCtrl.ui) + imesa->dirty |= SAVAGE_UPLOAD_GLOBAL; } @@ -1128,11 +1173,9 @@ static void savageDDEnable_s4(GLcontext *ctx, GLenum cap, GLboolean state) switch(cap) { case GL_ALPHA_TEST: /* we should consider the disable case*/ - imesa->dirty |= SAVAGE_UPLOAD_CTX; savageBlendFunc_s4(ctx); break; case GL_BLEND: - imesa->dirty |= SAVAGE_UPLOAD_CTX; /*Can't find Enable bit in the 3D registers.*/ /* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled. */ @@ -1146,7 +1189,6 @@ static void savageDDEnable_s4(GLcontext *ctx, GLenum cap, GLboolean state) savageBlendFunc_s4(ctx); break; case GL_DEPTH_TEST: - imesa->dirty |= SAVAGE_UPLOAD_CTX; savageDDDepthFunc_s4(ctx,ctx->Depth.Func); break; case GL_SCISSOR_TEST: @@ -1154,7 +1196,6 @@ static void savageDDEnable_s4(GLcontext *ctx, GLenum cap, GLboolean state) imesa->dirty |= SAVAGE_UPLOAD_CLIPRECTS; break; case GL_STENCIL_TEST: - imesa->dirty |= SAVAGE_UPLOAD_CTX; if (!imesa->hw_stencil) FALLBACK (ctx, SAVAGE_FALLBACK_STENCIL, state); else { @@ -1167,11 +1208,10 @@ static void savageDDEnable_s4(GLcontext *ctx, GLenum cap, GLboolean state) imesa->regs.s4.zBufCtrl.ni.zBufEn = GL_TRUE; imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn = GL_FALSE; } - imesa->dirty |= SAVAGE_UPLOAD_CTX; + imesa->dirty |= SAVAGE_UPLOAD_GLOBAL | SAVAGE_UPLOAD_LOCAL; } break; case GL_FOG: - imesa->dirty |= SAVAGE_UPLOAD_CTX; savageDDFogfv(ctx,0,0); break; case GL_CULL_FACE: @@ -1188,7 +1228,6 @@ static void savageDDEnable_s4(GLcontext *ctx, GLenum cap, GLboolean state) #endif break; case GL_DITHER: - imesa->dirty |= SAVAGE_UPLOAD_CTX; if (state) { if ( ctx->Color.DitherFlag ) @@ -1200,6 +1239,7 @@ static void savageDDEnable_s4(GLcontext *ctx, GLenum cap, GLboolean state) { imesa->regs.s4.drawCtrl1.ni.ditherEn=GL_FALSE; } + imesa->dirty |= SAVAGE_UPLOAD_GLOBAL; break; case GL_LIGHTING: @@ -1223,11 +1263,9 @@ static void savageDDEnable_s3d(GLcontext *ctx, GLenum cap, GLboolean state) switch(cap) { case GL_ALPHA_TEST: /* we should consider the disable case*/ - imesa->dirty |= SAVAGE_UPLOAD_CTX; savageBlendFunc_s3d(ctx); break; case GL_BLEND: - imesa->dirty |= SAVAGE_UPLOAD_CTX; /*Can't find Enable bit in the 3D registers.*/ /* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled. */ @@ -1241,7 +1279,6 @@ static void savageDDEnable_s3d(GLcontext *ctx, GLenum cap, GLboolean state) savageBlendFunc_s3d(ctx); break; case GL_DEPTH_TEST: - imesa->dirty |= SAVAGE_UPLOAD_CTX; savageDDDepthFunc_s3d(ctx,ctx->Depth.Func); break; case GL_SCISSOR_TEST: @@ -1252,7 +1289,6 @@ static void savageDDEnable_s3d(GLcontext *ctx, GLenum cap, GLboolean state) FALLBACK (ctx, SAVAGE_FALLBACK_STENCIL, state); break; case GL_FOG: - imesa->dirty |= SAVAGE_UPLOAD_CTX; savageDDFogfv(ctx,0,0); break; case GL_CULL_FACE: @@ -1269,7 +1305,6 @@ static void savageDDEnable_s3d(GLcontext *ctx, GLenum cap, GLboolean state) #endif break; case GL_DITHER: - imesa->dirty |= SAVAGE_UPLOAD_CTX; if (state) { if ( ctx->Color.DitherFlag ) @@ -1281,6 +1316,7 @@ static void savageDDEnable_s3d(GLcontext *ctx, GLenum cap, GLboolean state) { imesa->regs.s3d.drawCtrl.ni.ditherEn=GL_FALSE; } + imesa->dirty |= SAVAGE_UPLOAD_LOCAL; break; case GL_LIGHTING: @@ -1303,8 +1339,7 @@ void savageDDUpdateHwState( GLcontext *ctx ) savageContextPtr imesa = SAVAGE_CONTEXT(ctx); if (imesa->new_state) { - FLUSH_BATCH(imesa); - + savageFlushVertices(imesa); if (imesa->new_state & SAVAGE_NEW_TEXTURE) { savageUpdateTextureState( ctx ); } @@ -1368,20 +1403,20 @@ void savageEmitDrawingRectangle( savageContextPtr imesa ) imesa->regs.ni.changed.ni.fDrawCtrl1Changed=GL_TRUE;*/ savageCalcViewport (imesa->glCtx); - - imesa->dirty |= SAVAGE_UPLOAD_BUFFERS; } static void savageDDPrintDirty( const char *msg, GLuint state ) { - fprintf(stderr, "%s (0x%x): %s%s%s%s%s\n", + fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s%s\n", msg, (unsigned int) state, - (state & SAVAGE_UPLOAD_TEX0IMAGE) ? "upload-tex0, " : "", - (state & SAVAGE_UPLOAD_TEX1IMAGE) ? "upload-tex1, " : "", - (state & SAVAGE_UPLOAD_CTX) ? "upload-ctx, " : "", - (state & SAVAGE_UPLOAD_BUFFERS) ? "upload-bufs, " : "", + (state & SAVAGE_UPLOAD_LOCAL) ? "upload-local, " : "", + (state & SAVAGE_UPLOAD_TEX0) ? "upload-tex0, " : "", + (state & SAVAGE_UPLOAD_TEX1) ? "upload-tex1, " : "", + (state & SAVAGE_UPLOAD_FOGTBL) ? "upload-fogtbl, " : "", + (state & SAVAGE_UPLOAD_GLOBAL) ? "upload-global, " : "", + (state & SAVAGE_UPLOAD_TEXGLOBAL) ? "upload-texglobal, " : "", (state & SAVAGE_UPLOAD_CLIPRECTS) ? "upload-cliprects, " : "" ); } @@ -1400,18 +1435,32 @@ static GLboolean savageGlobalRegChanged (savageContextPtr imesa, } return GL_FALSE; } +static void savageEmitOldRegs (savageContextPtr imesa, + GLuint first, GLuint last, GLboolean global) { + GLuint n = last-first+1; + drm_savage_cmd_header_t *cmd = savageAllocCmdBuf(imesa, n*4); + cmd->state.cmd = SAVAGE_CMD_STATE; + cmd->state.global = global; + cmd->state.count = n; + cmd->state.start = first; + memcpy(cmd+1, &imesa->oldRegs.ui[first-SAVAGE_FIRST_REG], n*4); +} static void savageEmitContiguousRegs (savageContextPtr imesa, GLuint first, GLuint last) { GLuint i; - u_int32_t *pBCIBase; - pBCIBase = savageDMAAlloc (imesa, last - first + 2); - WRITE_CMD (pBCIBase, SET_REGISTER(first, last - first + 1), u_int32_t); - - for (i = first - SAVAGE_FIRST_REG; i <= last - SAVAGE_FIRST_REG; ++i) { - WRITE_CMD (pBCIBase, imesa->regs.ui[i], u_int32_t); + GLuint n = last-first+1; + drm_savage_cmd_header_t *cmd = savageAllocCmdBuf(imesa, n*4); + cmd->state.cmd = SAVAGE_CMD_STATE; + cmd->state.global = savageGlobalRegChanged(imesa, first, last); + cmd->state.count = n; + cmd->state.start = first; + memcpy(cmd+1, &imesa->regs.ui[first-SAVAGE_FIRST_REG], n*4); + /* savageAllocCmdBuf may need to flush the cmd buffer and backup + * the current hardware state. It should see the "old" (current) + * state that has actually been emitted to the hardware. Therefore + * this update is done *after* savageAllocCmdBuf. */ + for (i = first - SAVAGE_FIRST_REG; i <= last - SAVAGE_FIRST_REG; ++i) imesa->oldRegs.ui[i] = imesa->regs.ui[i]; - } - savageDMACommit (imesa, pBCIBase); } static void savageEmitChangedRegs (savageContextPtr imesa, GLuint first, GLuint last) { @@ -1445,8 +1494,6 @@ static void savageEmitChangedRegChunk (savageContextPtr imesa, } static void savageUpdateRegister_s4(savageContextPtr imesa) { - u_int32_t *pBCIBase; - /* * Scissors updates drawctrl0 and drawctrl 1 */ @@ -1470,23 +1517,12 @@ static void savageUpdateRegister_s4(savageContextPtr imesa) /* the savage4 uses the contiguous range of BCI registers 0x1e-0x39 * 0x1e-0x27 are local, no need to check them for global changes */ - if (imesa->lostContext || savageGlobalRegChanged (imesa, 0x28, 0x39)) { - pBCIBase = savageDMAAlloc (imesa, 1); - WRITE_CMD (pBCIBase, WAIT_3D_IDLE, u_int32_t); - savageDMACommit (imesa, pBCIBase); - } - if (imesa->lostContext) - savageEmitContiguousRegs (imesa, 0x1e, 0x39); - else - savageEmitChangedRegs (imesa, 0x1e, 0x39); + savageEmitContiguousRegs (imesa, 0x1e, 0x39); imesa->dirty=0; - imesa->lostContext = GL_FALSE; } static void savageUpdateRegister_s3d(savageContextPtr imesa) { - u_int32_t *pBCIBase; - if (imesa->scissorChanged) { if(imesa->scissor) @@ -1519,63 +1555,55 @@ static void savageUpdateRegister_s3d(savageContextPtr imesa) imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_TRUE; /* the savage3d uses two contiguous ranges of BCI registers: - * 0x18-0x1c and 0x20-0x38. The first range is local. */ - if (imesa->lostContext || savageGlobalRegChanged (imesa, 0x20, 0x38)) { - pBCIBase = savageDMAAlloc (imesa, 1); - WRITE_CMD (pBCIBase, WAIT_3D_IDLE, u_int32_t); - savageDMACommit (imesa, pBCIBase); - } + * 0x18-0x1c and 0x20-0x38. Some texture registers need to be + * emitted in one chunk or we get some funky rendering errors. */ /* FIXME: watermark registers aren't programmed correctly ATM */ - if (imesa->lostContext) { - savageEmitContiguousRegs (imesa, 0x18, 0x1c); - savageEmitContiguousRegs (imesa, 0x20, 0x36); - } else { - /* On the Savage IX texture registers (at least some of them) - * have to be emitted as one chunk. */ - savageEmitChangedRegs (imesa, 0x18, 0x19); - savageEmitChangedRegChunk (imesa, 0x1a, 0x1c); - savageEmitChangedRegs (imesa, 0x20, 0x36); - } + savageEmitChangedRegs (imesa, 0x18, 0x19); + savageEmitChangedRegChunk (imesa, 0x1a, 0x1c); + savageEmitChangedRegs (imesa, 0x20, 0x36); imesa->dirty=0; - imesa->lostContext = GL_FALSE; } +void savageEmitOldState( savageContextPtr imesa ) +{ + assert(imesa->cmdBuf.write == imesa->cmdBuf.base); + if (imesa->savageScreen->chipset >= S3_SAVAGE4) { + savageEmitOldRegs (imesa, 0x1e, 0x39, GL_TRUE); + } else { + savageEmitOldRegs (imesa, 0x18, 0x1c, GL_TRUE); + savageEmitOldRegs (imesa, 0x20, 0x36, GL_FALSE); + } +} + /* Push the state into the sarea and/or texture memory. */ -void savageEmitHwStateLocked( savageContextPtr imesa ) +void savageEmitChangedState( savageContextPtr imesa ) { if (SAVAGE_DEBUG & DEBUG_VERBOSE_API) savageDDPrintDirty( "\n\n\nsavageEmitHwStateLocked", imesa->dirty ); if (imesa->dirty & ~SAVAGE_UPLOAD_CLIPRECTS) { - if (imesa->dirty & (SAVAGE_UPLOAD_CTX | SAVAGE_UPLOAD_TEX0 | \ - SAVAGE_UPLOAD_TEX1 | SAVAGE_UPLOAD_BUFFERS)) + if (imesa->dirty & (SAVAGE_UPLOAD_GLOBAL | SAVAGE_UPLOAD_LOCAL | + SAVAGE_UPLOAD_TEX0 | SAVAGE_UPLOAD_TEX1 | + SAVAGE_UPLOAD_FOGTBL | SAVAGE_UPLOAD_TEXGLOBAL)) { - - /*SAVAGE_STATE_COPY(imesa);*/ - /* update state to hw*/ - if (imesa->driDrawable &&imesa->driDrawable->numClipRects ==0 ) - { - return ; - } + if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG) + fprintf (stderr, "... emitting state\n"); if (imesa->savageScreen->chipset >= S3_SAVAGE4) savageUpdateRegister_s4(imesa); else savageUpdateRegister_s3d(imesa); } - imesa->sarea->dirty |= (imesa->dirty & - ~(SAVAGE_UPLOAD_TEX1|SAVAGE_UPLOAD_TEX0)); imesa->dirty &= SAVAGE_UPLOAD_CLIPRECTS; } } - static void savageDDInitState_s4( savageContextPtr imesa ) { #if 1 @@ -1719,7 +1747,6 @@ static void savageDDInitState_s3d( savageContextPtr imesa ) } void savageDDInitState( savageContextPtr imesa ) { memset (imesa->regs.ui, 0, SAVAGE_NR_REGS*sizeof(u_int32_t)); - memset (imesa->oldRegs.ui, 0, SAVAGE_NR_REGS*sizeof(u_int32_t)); memset (imesa->globalRegMask.ui, 0xff, SAVAGE_NR_REGS*sizeof(u_int32_t)); if (imesa->savageScreen->chipset >= S3_SAVAGE4) savageDDInitState_s4 (imesa); @@ -1789,6 +1816,13 @@ void savageDDInitState( savageContextPtr imesa ) { imesa->readMap = (char *)imesa->apertureBase[TARGET_BACK]; } } + + memcpy (imesa->oldRegs.ui, imesa->regs.ui, SAVAGE_NR_REGS*sizeof(u_int32_t)); + + /* Emit the initial state to the (empty) command buffer. */ + assert (imesa->cmdBuf.write == imesa->cmdBuf.base); + savageEmitOldState(imesa); + imesa->cmdBuf.start = imesa->cmdBuf.write; } diff --git a/src/mesa/drivers/dri/savage/savagestate.h b/src/mesa/drivers/dri/savage/savagestate.h index 2cbdb81de5..b1b402a184 100644 --- a/src/mesa/drivers/dri/savage/savagestate.h +++ b/src/mesa/drivers/dri/savage/savagestate.h @@ -28,43 +28,13 @@ #include "savagecontext.h" +void savageEmitOldState( savageContextPtr imesa ); +void savageEmitChangedState( savageContextPtr imesa ); + extern void savageDDUpdateHwState( GLcontext *ctx ); extern void savageDDInitState( savageContextPtr imesa ); extern void savageDDInitStateFuncs( GLcontext *ctx ); extern void savageDDRenderStart(GLcontext *ctx); extern void savageDDRenderEnd(GLcontext *ctx); -/*frank 2001/11/13 add macro for sarea state copy*/ -#if 0 -#define SAVAGE_STATE_COPY(ctx) { \ -ctx->sarea->setup[0]=ctx->Registers.DrawLocalCtrl.ui; \ -ctx->sarea->setup[1]=ctx->Registers.TexPalAddr.ui; \ -ctx->sarea->setup[2]=ctx->Registers.TexCtrl[0].ui; \ -ctx->sarea->setup[3]=ctx->Registers.TexCtrl[1].ui; \ -ctx->sarea->setup[4]=ctx->Registers.TexAddr[0].ui; \ -ctx->sarea->setup[5]=ctx->Registers.TexAddr[1].ui; \ -ctx->sarea->setup[6]=ctx->Registers.TexBlendCtrl[0].ui; \ -ctx->sarea->setup[7]=ctx->Registers.TexBlendCtrl[1].ui; \ -ctx->sarea->setup[8]=ctx->Registers.TexXprClr.ui; \ -ctx->sarea->setup[9]=ctx->Registers.TexDescr.ui; \ -ctx->sarea->setup[10]=ctx->Registers.FogTable.ni.ulEntry[0]; \ -ctx->sarea->setup[11]=ctx->Registers.FogTable.ni.ulEntry[1]; \ -ctx->sarea->setup[12]=ctx->Registers.FogTable.ni.ulEntry[2]; \ -ctx->sarea->setup[13]=ctx->Registers.FogTable.ni.ulEntry[3]; \ -ctx->sarea->setup[14]=ctx->Registers.FogTable.ni.ulEntry[4]; \ -ctx->sarea->setup[15]=ctx->Registers.FogTable.ni.ulEntry[5]; \ -ctx->sarea->setup[16]=ctx->Registers.FogTable.ni.ulEntry[6]; \ -ctx->sarea->setup[17]=ctx->Registers.FogTable.ni.ulEntry[7]; \ -ctx->sarea->setup[18]=ctx->Registers.FogCtrl.ui; \ -ctx->sarea->setup[19]=ctx->Registers.StencilCtrl.ui; \ -ctx->sarea->setup[20]=ctx->Registers.ZBufCtrl.ui; \ -ctx->sarea->setup[21]=ctx->Registers.ZBufOffset.ui; \ -ctx->sarea->setup[22]=ctx->Registers.DestCtrl.ui; \ -ctx->sarea->setup[23]=ctx->Registers.DrawCtrl0.ui; \ -ctx->sarea->setup[24]=ctx->Registers.DrawCtrl1.ui; \ -ctx->sarea->setup[25]=ctx->Registers.ZWatermarks.ui; \ -ctx->sarea->setup[26]=ctx->Registers.DestTexWatermarks.ui; \ -ctx->sarea->setup[27]=ctx->Registers.TexBlendColor.ui; \ -} -#endif #endif diff --git a/src/mesa/drivers/dri/savage/savagetex.c b/src/mesa/drivers/dri/savage/savagetex.c index c6143baabd..924f06187b 100644 --- a/src/mesa/drivers/dri/savage/savagetex.c +++ b/src/mesa/drivers/dri/savage/savagetex.c @@ -606,7 +606,7 @@ void savagePrintGlobalLRU( savageContextPtr imesa , GLuint heap) { int i, j; - drm_savage_tex_region_t *list = imesa->sarea->texList[heap]; + drm_tex_region_t *list = imesa->sarea->texList[heap]; for (i = 0, j = SAVAGE_NR_TEX_REGIONS ; i < SAVAGE_NR_TEX_REGIONS ; i++) { @@ -628,7 +628,7 @@ void savagePrintGlobalLRU( savageContextPtr imesa , GLuint heap) void savageResetGlobalLRU( savageContextPtr imesa, GLuint heap ) { - drm_savage_tex_region_t *list = imesa->sarea->texList[heap]; + drm_tex_region_t *list = imesa->sarea->texList[heap]; int sz = 1 << imesa->savageScreen->logTextureGranularity[heap]; int i; @@ -661,7 +661,7 @@ static void savageUpdateTexLRU( savageContextPtr imesa, savageTextureObjectPtr t int logsz = imesa->savageScreen->logTextureGranularity[heap]; int start = t->MemBlock->ofs >> logsz; int end = (t->MemBlock->ofs + t->MemBlock->size - 1) >> logsz; - drm_savage_tex_region_t *list = imesa->sarea->texList[heap]; + drm_tex_region_t *list = imesa->sarea->texList[heap]; imesa->texAge[heap] = ++imesa->sarea->texAge[heap]; @@ -787,16 +787,19 @@ int savageUploadTexImages( savageContextPtr imesa, savageTextureObjectPtr t ) ofs = t->MemBlock->ofs; t->texParams.hwPhysAddress = imesa->savageScreen->textureOffset[heap] + ofs; t->BufAddr = (char *)((GLuint) imesa->savageScreen->texVirtual[heap] + ofs); - imesa->dirty |= SAVAGE_UPLOAD_CTX; + imesa->dirty |= SAVAGE_UPLOAD_GLOBAL; /* FIXME: really needed? */ } /* Let the world know we've used this memory recently. */ + LOCK_HARDWARE(imesa); savageUpdateTexLRU( imesa, t ); + UNLOCK_HARDWARE(imesa); if (t->dirty_images) { + savageFlushVertices (imesa); LOCK_HARDWARE(imesa); - savageFlushVerticesLocked (imesa); + savageFlushCmdBufLocked (imesa, GL_FALSE); savageDmaFinish (imesa); if (SAVAGE_DEBUG & DEBUG_VERBOSE_LRU) fprintf(stderr, "*"); @@ -1436,8 +1439,7 @@ static void savageUpdateTextureState_s4( GLcontext *ctx ) imesa->CurrentTexObj[1] = 0; savageUpdateTex0State_s4( ctx ); savageUpdateTex1State_s4( ctx ); - imesa->dirty |= (SAVAGE_UPLOAD_CTX | - SAVAGE_UPLOAD_TEX0 | + imesa->dirty |= (SAVAGE_UPLOAD_TEX0 | SAVAGE_UPLOAD_TEX1); } static void savageUpdateTextureState_s3d( GLcontext *ctx ) @@ -1446,8 +1448,7 @@ static void savageUpdateTextureState_s3d( GLcontext *ctx ) if (imesa->CurrentTexObj[0]) imesa->CurrentTexObj[0]->bound &= ~1; imesa->CurrentTexObj[0] = 0; savageUpdateTexState_s3d( ctx ); - imesa->dirty |= (SAVAGE_UPLOAD_CTX | - SAVAGE_UPLOAD_TEX0); + imesa->dirty |= (SAVAGE_UPLOAD_TEX0); } void savageUpdateTextureState( GLcontext *ctx) { diff --git a/src/mesa/drivers/dri/savage/savagetris.c b/src/mesa/drivers/dri/savage/savagetris.c index 69633ecae7..1732dc5074 100644 --- a/src/mesa/drivers/dri/savage/savagetris.c +++ b/src/mesa/drivers/dri/savage/savagetris.c @@ -100,7 +100,7 @@ static void __inline__ savage_draw_triangle (savageContextPtr imesa, savageVertexPtr v1, savageVertexPtr v2) { GLuint vertsize = imesa->HwVertexSize; - u_int32_t *vb = savageAllocDmaLow (imesa, 3*4*vertsize); + u_int32_t *vb = savageAllocVtxBuf (imesa, 3*vertsize); GLuint j; EMIT_VERT (j, vb, vertsize, 0, v0); @@ -114,7 +114,7 @@ static void __inline__ savage_draw_quad (savageContextPtr imesa, savageVertexPtr v2, savageVertexPtr v3) { GLuint vertsize = imesa->HwVertexSize; - u_int32_t *vb = savageAllocDmaLow (imesa, 6*4*vertsize); + u_int32_t *vb = savageAllocVtxBuf (imesa, 6*vertsize); GLuint j; EMIT_VERT (j, vb, vertsize, 0, v0); @@ -128,7 +128,7 @@ static void __inline__ savage_draw_quad (savageContextPtr imesa, static __inline__ void savage_draw_point (savageContextPtr imesa, savageVertexPtr tmp) { GLuint vertsize = imesa->HwVertexSize; - u_int32_t *vb = savageAllocDmaLow (imesa, 6*4*vertsize); + u_int32_t *vb = savageAllocVtxBuf (imesa, 6*vertsize); const GLfloat x = tmp->v.x; const GLfloat y = tmp->v.y; const GLfloat sz = imesa->glCtx->Point._Size * .5; @@ -163,7 +163,7 @@ static __inline__ void savage_draw_line (savageContextPtr imesa, savageVertexPtr v0, savageVertexPtr v1 ) { GLuint vertsize = imesa->HwVertexSize; - u_int32_t *vb = savageAllocDmaLow (imesa, 6*4*vertsize); + u_int32_t *vb = savageAllocVtxBuf (imesa, 6*vertsize); GLfloat width = imesa->glCtx->Line._Width; GLfloat dx, dy, ix, iy; GLuint j; @@ -220,7 +220,7 @@ static void __inline__ savage_ptex_tri (savageContextPtr imesa, savageVertexPtr v1, savageVertexPtr v2) { GLuint vertsize = imesa->HwVertexSize; - u_int32_t *vb = savageAllocDmaLow (imesa, 3*4*vertsize); + u_int32_t *vb = savageAllocVtxBuf (imesa, 3*vertsize); savageVertex tmp; GLuint j; @@ -233,7 +233,7 @@ static __inline__ void savage_ptex_line (savageContextPtr imesa, savageVertexPtr v0, savageVertexPtr v1 ) { GLuint vertsize = imesa->HwVertexSize; - u_int32_t *vb = savageAllocDmaLow (imesa, 6*4*vertsize); + u_int32_t *vb = savageAllocVtxBuf (imesa, 6*vertsize); GLfloat width = imesa->glCtx->Line._Width; GLfloat dx, dy, ix, iy; savageVertex tmp0, tmp1; @@ -278,7 +278,7 @@ static __inline__ void savage_ptex_line (savageContextPtr imesa, static __inline__ void savage_ptex_point (savageContextPtr imesa, savageVertexPtr v0) { GLuint vertsize = imesa->HwVertexSize; - u_int32_t *vb = savageAllocDmaLow (imesa, 6*4*vertsize); + u_int32_t *vb = savageAllocVtxBuf (imesa, 6*vertsize); const GLfloat x = v0->v.x; const GLfloat y = v0->v.y; const GLfloat sz = imesa->glCtx->Point._Size * .5; @@ -428,9 +428,9 @@ do { \ savageContextPtr imesa = SAVAGE_CONTEXT(ctx); \ GLuint color[n], spec[n]; \ GLuint coloroffset = \ - ((imesa->DrawPrimitiveCmd & SAVAGE_HW_NO_W) ? 3 : 4); \ + ((imesa->skip & SAVAGE_SKIP_W) ? 3 : 4); \ GLboolean specoffset = \ - ((imesa->DrawPrimitiveCmd & SAVAGE_HW_NO_CS) ? 0 : coloroffset+1);\ + ((imesa->skip & SAVAGE_SKIP_C1) ? 0 : coloroffset+1); \ (void) color; (void) spec; (void) coloroffset; (void) specoffset; /*********************************************************************** @@ -756,6 +756,16 @@ static void savageChooseRenderState(GLcontext *ctx) imesa->RenderIndex = index; } + + if (imesa->savageScreen->chipset < S3_SAVAGE4 && (flags & DD_FLATSHADE)) { + if (imesa->HwPrim != SAVAGE_PRIM_TRILIST_201) + savageFlushVertices(imesa); + imesa->HwPrim = SAVAGE_PRIM_TRILIST_201; + } else { + if (imesa->HwPrim != SAVAGE_PRIM_TRILIST) + savageFlushVertices(imesa); + imesa->HwPrim = SAVAGE_PRIM_TRILIST; + } } /**********************************************************************/ @@ -766,6 +776,9 @@ static void savageRunPipeline( GLcontext *ctx ) { savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + if (imesa->no_rast) + FALLBACK(ctx, SAVAGE_FALLBACK_NORAST, GL_TRUE); + if (imesa->new_state) savageDDUpdateHwState( ctx ); @@ -777,6 +790,9 @@ static void savageRunPipeline( GLcontext *ctx ) } _tnl_run_pipeline( ctx ); + + if (imesa->no_rast) + FALLBACK(ctx, SAVAGE_FALLBACK_NORAST, GL_FALSE); } /**********************************************************************/ @@ -858,7 +874,7 @@ do { \ imesa->vertex_attrs[imesa->vertex_attr_count].format = (STYLE); \ imesa->vertex_attr_count++; \ setupIndex |= (INDEX); \ - drawCmd &= ~(SKIP); \ + skip &= ~(SKIP); \ } while (0) #define EMIT_PAD( N ) \ @@ -891,11 +907,8 @@ static void savageRenderStart( GLcontext *ctx ) struct vertex_buffer *VB = &tnl->vb; GLuint index = tnl->render_inputs; GLuint setupIndex = SAVAGE_EMIT_XYZ; - GLuint drawCmd = SAVAGE_HW_SKIPFLAGS; + GLubyte skip; GLboolean ptexHack; - if (imesa->savageScreen->chipset < S3_SAVAGE4) - drawCmd &= ~SAVAGE_HW_NO_UV1; - drawCmd &= ~SAVAGE_HW_NO_Z; /* all mesa vertices have a z coordinate */ /* Check if we need to apply the ptex hack. Choose a new render * state if necessary. (Note: this can't be done in @@ -917,66 +930,115 @@ static void savageRenderStart( GLcontext *ctx ) VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr; imesa->vertex_attr_count = 0; - /* EMIT_ATTR's must be in order as they tell t_vertex.c how to - * build up a hardware vertex. - */ - if ((index & _TNL_BITS_TEX_ANY) || !(ctx->_TriangleCaps & DD_FLATSHADE)) { - EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, SAVAGE_EMIT_W, SAVAGE_HW_NO_W ); - } - else { - EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, 0, 0 ); - } + if (imesa->savageScreen->chipset < S3_SAVAGE4) { + skip = SAVAGE_SKIP_ALL_S3D; + skip &= ~SAVAGE_SKIP_Z; /* all mesa vertices have a z coordinate */ - /* t_context.c always includes a diffuse color */ - EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, SAVAGE_EMIT_C0, SAVAGE_HW_NO_CD ); + /* EMIT_ATTR's must be in order as they tell t_vertex.c how to + * build up a hardware vertex. + */ + if ((index & _TNL_BITS_TEX_ANY) || !(ctx->_TriangleCaps & DD_FLATSHADE)) { + EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, SAVAGE_EMIT_W, SAVAGE_SKIP_W ); + } + else { + EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, 0, 0 ); + EMIT_PAD( 4 ); + skip &= ~SAVAGE_SKIP_W; + } + + /* t_context.c always includes a diffuse color */ + EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, SAVAGE_EMIT_C0, SAVAGE_SKIP_C0 ); - if (index & (_TNL_BIT_COLOR1|_TNL_BIT_FOG)) { if ((index & _TNL_BIT_COLOR1)) - EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, SAVAGE_EMIT_C1, SAVAGE_HW_NO_CS ); + EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, SAVAGE_EMIT_C1, SAVAGE_SKIP_C1 ); else EMIT_PAD( 3 ); if ((index & _TNL_BIT_FOG)) - EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, SAVAGE_EMIT_FOG, SAVAGE_HW_NO_CS ); + EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, SAVAGE_EMIT_FOG, SAVAGE_SKIP_C1 ); else EMIT_PAD( 1 ); - } - - if (index & _TNL_BIT_TEX(0)) { - if (ptexHack) - EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_3F_XYW, SAVAGE_EMIT_STQ0, SAVAGE_HW_NO_UV0); - else if (VB->TexCoordPtr[0]->size == 4) - assert (0); /* should be caught by savageCheckPTexHack */ - else if (VB->TexCoordPtr[0]->size >= 2) - /* The chromium menu emits some 3D tex coords even though no - * 3D texture is enabled. Ignore the 3rd coordinate. */ - EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_2F, SAVAGE_EMIT_ST0, SAVAGE_HW_NO_UV0 ); - else - EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_1F, SAVAGE_EMIT_S0, SAVAGE_HW_NO_U0 ); - } - if (index & _TNL_BIT_TEX(1)) { - if (VB->TexCoordPtr[1]->size == 4) - /* Projective textures are not supported by the hardware */ - assert (0); /* should be caught by savageCheckPTexHack */ - else if (VB->TexCoordPtr[1]->size >= 2) - EMIT_ATTR( _TNL_ATTRIB_TEX1, EMIT_2F, SAVAGE_EMIT_ST1, SAVAGE_HW_NO_UV1 ); + skip &= ~SAVAGE_SKIP_C1; + + if (index & _TNL_BIT_TEX(0)) { + if (ptexHack) + EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_3F_XYW, SAVAGE_EMIT_STQ0, SAVAGE_SKIP_ST0); + else if (VB->TexCoordPtr[0]->size == 4) + assert (0); /* should be caught by savageCheckPTexHack */ + else if (VB->TexCoordPtr[0]->size >= 2) + /* The chromium menu emits some 3D tex coords even though no + * 3D texture is enabled. Ignore the 3rd coordinate. */ + EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_2F, SAVAGE_EMIT_ST0, SAVAGE_SKIP_ST0 ); + else if (VB->TexCoordPtr[0]->size == 1) { + EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_1F, SAVAGE_EMIT_S0, SAVAGE_SKIP_S0 ); + EMIT_PAD( 4 ); + } else + EMIT_PAD( 8 ); + } else + EMIT_PAD( 8 ); + skip &= ~SAVAGE_SKIP_ST0; + } else { + skip = SAVAGE_SKIP_ALL_S4; + skip &= ~SAVAGE_SKIP_Z; /* all mesa vertices have a z coordinate */ + + /* EMIT_ATTR's must be in order as they tell t_vertex.c how to + * build up a hardware vertex. + */ + if ((index & _TNL_BITS_TEX_ANY) || !(ctx->_TriangleCaps & DD_FLATSHADE)) + EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, SAVAGE_EMIT_W, SAVAGE_SKIP_W ); else - EMIT_ATTR( _TNL_ATTRIB_TEX1, EMIT_1F, SAVAGE_EMIT_S1, SAVAGE_HW_NO_U1 ); + EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, 0, 0 ); + + /* t_context.c always includes a diffuse color */ + EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, SAVAGE_EMIT_C0, SAVAGE_SKIP_C0 ); + + if (index & (_TNL_BIT_COLOR1|_TNL_BIT_FOG)) { + if ((index & _TNL_BIT_COLOR1)) + EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, SAVAGE_EMIT_C1, SAVAGE_SKIP_C1 ); + else + EMIT_PAD( 3 ); + if ((index & _TNL_BIT_FOG)) + EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, SAVAGE_EMIT_FOG, SAVAGE_SKIP_C1 ); + else + EMIT_PAD( 1 ); + } + + if (index & _TNL_BIT_TEX(0)) { + if (ptexHack) + EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_3F_XYW, SAVAGE_EMIT_STQ0, SAVAGE_SKIP_ST0); + else if (VB->TexCoordPtr[0]->size == 4) + assert (0); /* should be caught by savageCheckPTexHack */ + else if (VB->TexCoordPtr[0]->size >= 2) + /* The chromium menu emits some 3D tex coords even though no + * 3D texture is enabled. Ignore the 3rd coordinate. */ + EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_2F, SAVAGE_EMIT_ST0, SAVAGE_SKIP_ST0 ); + else + EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_1F, SAVAGE_EMIT_S0, SAVAGE_SKIP_S0 ); + } + if (index & _TNL_BIT_TEX(1)) { + if (VB->TexCoordPtr[1]->size == 4) + /* projective textures are not supported by the hardware */ + assert (0); /* should be caught by savageCheckPTexHack */ + else if (VB->TexCoordPtr[1]->size >= 2) + EMIT_ATTR( _TNL_ATTRIB_TEX1, EMIT_2F, SAVAGE_EMIT_ST1, SAVAGE_SKIP_ST1 ); + else + EMIT_ATTR( _TNL_ATTRIB_TEX1, EMIT_1F, SAVAGE_EMIT_S1, SAVAGE_SKIP_S1 ); + } } /* Need to change the vertex emit code if the SetupIndex changed or * is set for the first time (indicated by vertex_size == 0). */ if (setupIndex != imesa->SetupIndex || imesa->vertex_size == 0) { - imesa->vertex_size = + GLuint hwVertexSize; + imesa->vertex_size = _tnl_install_attrs( ctx, imesa->vertex_attrs, imesa->vertex_attr_count, imesa->hw_viewport, 0 ); imesa->vertex_size >>= 2; imesa->SetupIndex = setupIndex; + imesa->skip = skip; - imesa->DrawPrimitiveCmd = drawCmd; - imesa->HwVertexSize = imesa->vertex_size; - + hwVertexSize = imesa->vertex_size; if (setupIndex & SAVAGE_EMIT_Q0) { /* The vertex setup code emits homogenous texture * coordinates. They are converted to normal 2D coords by @@ -984,10 +1046,28 @@ static void savageRenderStart( GLcontext *ctx ) * vertex sizes. Functions that emit vertices to the hardware * need to use HwVertexSize, anything that manipulates the * vertices generated by t_vertex uses vertex_size. */ - imesa->HwVertexSize--; + hwVertexSize--; assert (imesa->ptexHack); } else assert (!imesa->ptexHack); + + if (hwVertexSize != imesa->HwVertexSize) { + /* Changing the vertex size: flush vertex and command buffer and + * discard the DMA buffer, if we were using one. */ + savageFlushVertices(imesa); + savageFlushCmdBuf(imesa, GL_TRUE); + if (hwVertexSize == 8) { + if (SAVAGE_DEBUG & DEBUG_DMA) + fprintf (stderr, "Using DMA, skip=0x%02x\n", skip); + /* we can use vertex dma */ + imesa->vtxBuf = &imesa->dmaVtxBuf; + } else { + if (SAVAGE_DEBUG & DEBUG_DMA) + fprintf (stderr, "Not using DMA, skip=0x%02x\n", skip); + imesa->vtxBuf = &imesa->clientVtxBuf; + } + imesa->HwVertexSize = hwVertexSize; + } } /* Update hardware state and get the lock */ diff --git a/src/mesa/drivers/dri/savage/server/savage_dri.h b/src/mesa/drivers/dri/savage/server/savage_dri.h index af62e761c4..39b6564fc3 100644 --- a/src/mesa/drivers/dri/savage/server/savage_dri.h +++ b/src/mesa/drivers/dri/savage/server/savage_dri.h @@ -29,6 +29,11 @@ #include "xf86drm.h" #include "drm.h" +/* Totals 2 Mbytes which equals 2^16 32-byte vertices divided among up + * to 32 clients. */ +#define SAVAGE_NUM_BUFFERS 32 +#define SAVAGE_BUFFER_SIZE (1 << 16) /* 64k */ + #define SAVAGE_DEFAULT_AGP_MODE 1 #define SAVAGE_MAX_AGP_MODE 4 @@ -68,14 +73,17 @@ typedef struct _server{ unsigned int frontOffset; unsigned int frontPitch; unsigned int frontbufferSize; + unsigned int frontBitmapDesc; unsigned int backOffset; unsigned int backPitch; unsigned int backbufferSize; + unsigned int backBitmapDesc; unsigned int depthOffset; unsigned int depthPitch; unsigned int depthbufferSize; + unsigned int depthBitmapDesc; unsigned int textureOffset; int textureSize; @@ -89,12 +97,7 @@ typedef struct _server{ drmRegion status; /* AGP mappings */ -#if 0 - drmRegion warp; - drmRegion primary; drmRegion buffers; -#endif - drmRegion agpTextures; int logAgpTextureGranularity; @@ -114,71 +117,41 @@ typedef struct { int cpp; int zpp; - int agpMode; + int agpMode; /* 0 for PCI cards */ + + unsigned int sarea_priv_offset; + + unsigned int bufferSize; /* size of DMA buffers */ - drm_handle_t frontbuffer; unsigned int frontbufferSize; unsigned int frontOffset; - unsigned int frontPitch; - unsigned int frontBitmapDesc; /*Bitmap Descriptior*/ - unsigned int IsfrontTiled; - drm_handle_t backbuffer; unsigned int backbufferSize; unsigned int backOffset; - unsigned int backPitch; - unsigned int backBitmapDesc; /*Bitmap Descriptior*/ - drm_handle_t depthbuffer; unsigned int depthbufferSize; unsigned int depthOffset; - unsigned int depthPitch; - unsigned int depthBitmapDesc; /*Bitmap Descriptior*/ - - - drm_handle_t textures; - drm_handle_t xvmcSurfHandle; unsigned int textureOffset; unsigned int textureSize; int logTextureGranularity; - /* Allow calculation of setup dma addresses. - */ - unsigned int agpBufferOffset; - - unsigned int agpTextureOffset; - unsigned int agpTextureSize; - drmRegion agpTextures; - int logAgpTextureGranularity; - -/* unsigned int mAccess;*/ - - drmRegion aperture; + /* Linear aperture */ + drm_handle_t apertureHandle; + unsigned int apertureSize; unsigned int aperturePitch; /* in byte */ + /* Status page (probably not needed, but no harm, read-only) */ + drm_handle_t statusHandle; + unsigned int statusSize; - drmRegion registers; - drmRegion BCIcmdBuf; - drmRegion status; - -#if 0 - drmRegion primary; - drmRegion buffers; -#endif - /*For shadow status*/ - unsigned long sareaPhysAddr; + /* AGP textures */ + drm_handle_t agpTextureHandle; + unsigned int agpTextureSize; + int logAgpTextureGranularity; - unsigned int sarea_priv_offset; - int shadowStatus; + /* Not sure about this one */ + drm_handle_t xvmcSurfHandle; /* ? */ } SAVAGEDRIRec, *SAVAGEDRIPtr; #endif - - - - - - - - -- cgit v1.2.3