diff options
author | Felix Kuehling <[email protected]> | 2005-01-01 20:40:14 +0000 |
---|---|---|
committer | Felix Kuehling <[email protected]> | 2005-01-01 20:40:14 +0000 |
commit | 1067ce0cea1392b4ea1cc1c2c940cec33efb9c96 (patch) | |
tree | 8a489032a80fea40a528c64e745cc5bd53aacfdf /src/mesa/drivers/dri | |
parent | 467d64a177d611293c6db14daf97997b389f3cb0 (diff) |
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.
Diffstat (limited to 'src/mesa/drivers/dri')
-rw-r--r-- | src/mesa/drivers/dri/savage/Makefile | 3 | ||||
-rw-r--r-- | src/mesa/drivers/dri/savage/savage_bci.h | 105 | ||||
-rw-r--r-- | src/mesa/drivers/dri/savage/savage_init.h | 31 | ||||
-rw-r--r-- | src/mesa/drivers/dri/savage/savage_xmesa.c | 147 | ||||
-rw-r--r-- | src/mesa/drivers/dri/savage/savagecontext.h | 61 | ||||
-rw-r--r-- | src/mesa/drivers/dri/savage/savagedd.c | 28 | ||||
-rw-r--r-- | src/mesa/drivers/dri/savage/savagedma.c | 150 | ||||
-rw-r--r-- | src/mesa/drivers/dri/savage/savagedma.h | 4 | ||||
-rw-r--r-- | src/mesa/drivers/dri/savage/savageioctl.c | 527 | ||||
-rw-r--r-- | src/mesa/drivers/dri/savage/savageioctl.h | 92 | ||||
-rw-r--r-- | src/mesa/drivers/dri/savage/savagestate.c | 248 | ||||
-rw-r--r-- | src/mesa/drivers/dri/savage/savagestate.h | 36 | ||||
-rw-r--r-- | src/mesa/drivers/dri/savage/savagetex.c | 19 | ||||
-rw-r--r-- | src/mesa/drivers/dri/savage/savagetris.c | 188 | ||||
-rw-r--r-- | 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 d662cb06d8d..181556318fb 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 3c91e01f210..0928b3ca74e 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++<MAXLOOP)); \ -}while(0) - - -#define WAIT_IDLE_EMPTY do{\ -int loop = 0; \ - if (/*imesa->shadowStatus*/0)\ - {\ - SHADOW_WAIT_IDLE(imesa);\ - }\ - else\ - { \ - while(((ALT_STATUS_WORD0 &0x00ffffff)!=0x00E00000L)&&(loop++<MAXLOOP));\ - }\ -}while(0) - -#define WAIT_IDLE do{\ -int loop = 0; \ -if (imesa->shadowStatus)\ - while((((*imesa->shadowPointer) & 0x0E000000L)!=0x0E000000L)&&(loop++<MAXLOOP));\ -else\ -while(((ALT_STATUS_WORD0 &0x00E00000)!=0x00E00000L)&&(loop++<MAXLOOP)); \ -}while(0) -#endif /* 0 */ - -#define SAVAGE_DRAW_PRIMITIVE(count, typeandvertexSkip, isCont) \ - ( ((count)<<16) | (typeandvertexSkip) | (isCont | (1<<31))); - -static __inline volatile GLuint * SAVAGE_GET_BCI_POINTER(savageContextPtr imesa, GLuint count) -{ - WAIT_FOR_FIFO(count); - return (volatile GLuint *)(imesa->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 1454b6b36c8..27539bea163 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 bcbc9d69ed4..f1798de134d 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 f41b73e0de5..8978f9247cf 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 dddc6d9a650..312f6f62f48 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 86ee763a31f..51a1e6d2bd1 100644 --- a/src/mesa/drivers/dri/savage/savagedma.c +++ b/src/mesa/drivers/dri/savage/savagedma.c @@ -30,20 +30,7 @@ #include <time.h> #include <unistd.h> -/* 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 0896ca148d5..09f0c46e95f 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 ac9e055e931..dd7a84e2e72 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 <sys/ioctl.h> #include <sys/timeb.h> -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 acf398b9a6b..941e74e56b5 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 f4f22602d8d..d6048291bee 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 <mode>. @@ -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 2cbdb81de58..b1b402a1843 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 c6143baabdd..924f06187b4 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 69633ecae75..1732dc50740 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 af62e761c43..39b6564fc38 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 - - - - - - - - |