diff options
| -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 | 523 | ||||
| -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 | 186 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/savage/server/savage_dri.h | 77 | 
15 files changed, 839 insertions, 871 deletions
diff --git a/src/mesa/drivers/dri/savage/Makefile b/src/mesa/drivers/dri/savage/Makefile index d662cb06d8..181556318f 100644 --- a/src/mesa/drivers/dri/savage/Makefile +++ b/src/mesa/drivers/dri/savage/Makefile @@ -25,8 +25,7 @@ DRIVER_SOURCES = \  	savagetex.c \  	savagetris.c \  	savageioctl.c \ -	savagespan.c \ -	savagedma.c +	savagespan.c  C_SOURCES = \  	$(COMMON_SOURCES) \ diff --git a/src/mesa/drivers/dri/savage/savage_bci.h b/src/mesa/drivers/dri/savage/savage_bci.h index 3c91e01f21..0928b3ca74 100644 --- a/src/mesa/drivers/dri/savage/savage_bci.h +++ b/src/mesa/drivers/dri/savage/savage_bci.h @@ -341,8 +341,8 @@ typedef enum      TPS_256  } TexPaletteSize; -    #define MAX_MIPMAP_LOD_BIAS             255 -    #define MIN_MIPMAP_LOD_BIAS             -255 +#define MAX_MIPMAP_LOD_BIAS 255 +#define MIN_MIPMAP_LOD_BIAS -255  typedef enum  { @@ -627,107 +627,6 @@ typedef union {  #define SAVAGE_HW_NO_UV1        ((1<<6) | (1<<7))  #define SAVAGE_HW_SKIPFLAGS     0x000000ff -#define SAVAGE_HW_TRIANGLE_TYPE     (3UL<<25) -#define SAVAGE_HW_TRIANGLE_CONT     (1UL<<24) -#define SAVAGE_HW_TRIANGLE_LIST     (0<<25)  -#define SAVAGE_HW_TRIANGLE_STRIP    (1<<25)  -#define SAVAGE_HW_TRIANGLE_FAN      (2<<25)  -#define SAVAGE_HW_QUAD              (3<<25)  - -#define __HW_TEXTURE_CHANGED       0x00002FE -#define __HW_HAS_SCISSORS_CHANGED  0x00001800 -#define __HW_ALL_CHANGED           0x1FFFFFF            -/*Frank 2001/11/14 Wait commands*/ -#define WAIT_3D_IDLE    0xC0010000 -#define WAIT_3D_2D_IDLE 0xC0030000 - -#define SET_REGISTER(index, count) \ -    ((CMD_SetRegister << 27) | (0x6000000) | ((count) << 16) | (index)) - -/*frank 2001/11/20 */ -#define MAXLOOP 0xFFFFFF -/*#define MAXFIFO 0x7F00*/ -#define MAXFIFO 0x1FF00 - -/* get eventtag from shadow status */ -/* here we use eventTag1 because eventTag0 is used by HWXvMC*/ -#define GET_EVENTTAG \ -    (((*(volatile GLuint *)(imesa->MMIO_BASE+0x48c04)) & 0xffff0000L)>>16) - -#define SHADOW_WAIT(imesa ) do \ -{ \ -    int loop=0; \ -    imesa->shadowCounter = (imesa->shadowCounter + 1) & 0xffff;\ -    if(imesa->shadowCounter == 0)\ -      imesa->shadowCounter = MAX_SHADOWCOUNTER;\ -    *(volatile GLuint *)imesa->BCIBase = imesa->shadowCounter | 0x98400000L;\ -    while(\ -	  (GET_EVENTTAG) != imesa->shadowCounter  &&\ -	  (loop++ < MAXLOOP));\ -}while(0); - -#define SHADOW_WAIT_IDLE(imesa ) do \ -{ \ -    int loop=0; \ -    imesa->shadowCounter = (imesa->shadowCounter + 1) & 0xffff;\ -    if(imesa->shadowCounter == 0)\ -      imesa->shadowCounter = MAX_SHADOWCOUNTER;\ -/*    *(volatile GLuint *)imesa->BCIBase = WAIT_3D_IDLE;\*/\ -    *(volatile GLuint *)imesa->BCIBase = imesa->shadowCounter | 0x98400000L;\ -    while ( \ -    (GET_EVENTTAG) != imesa->shadowCounter && \ -    (loop++ < MAXLOOP)); \ -}while(0); - -#if 0 -#define ALT_STATUS_WORD0 (* (volatile GLuint *)(imesa->MMIO_BASE+0x48c60)) - -#define PAGE_PENDING(result) do{\ -result=((ALT_STATUS_WORD0 & 0x08000000)?GL_TRUE:GL_FALSE);\ -}while(0) - -#define WAIT_FOR_FIFO(count) do{\ -int loop = 0; \ -int slots = MAXFIFO-count; \ -while(((ALT_STATUS_WORD0 &0x001fffff)>slots)&&(loop++<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 1454b6b36c..27539bea16 100644 --- a/src/mesa/drivers/dri/savage/savage_init.h +++ b/src/mesa/drivers/dri/savage/savage_init.h @@ -41,11 +41,6 @@ typedef struct {  } savageRegion, *savageRegionPtr;  typedef struct { -   savageRegion front; -   savageRegion back; -   savageRegion depth; -   savageRegion aperture; -     int chipset;     int width;     int height; @@ -53,31 +48,34 @@ typedef struct {     int cpp;			/* for front and back buffers */     int zpp; + +   int agpMode; + +   unsigned int bufferSize; +  #if 0      int bitsPerPixel;  #endif     unsigned int frontFormat;     unsigned int frontOffset; -   unsigned int frontPitch; -   unsigned int frontBitmapDesc; -     unsigned int backOffset; -   unsigned int backBitmapDesc;     unsigned int depthOffset; -   unsigned int depthBitmapDesc; -   unsigned int backPitch; -   unsigned int backPitchBits; +   unsigned int aperturePitch;     unsigned int textureOffset[SAVAGE_NR_TEX_HEAPS];     unsigned int textureSize[SAVAGE_NR_TEX_HEAPS];     unsigned int logTextureGranularity[SAVAGE_NR_TEX_HEAPS];     drmAddress texVirtual[SAVAGE_NR_TEX_HEAPS]; -  __DRIscreenPrivate *driScrnPriv; -  drmBufMapPtr  bufs; -  int use_copy_buf; -  unsigned int sarea_priv_offset; +   __DRIscreenPrivate *driScrnPriv; + +   savageRegion aperture; +   savageRegion agpTextures; + +   drmBufMapPtr bufs; + +   unsigned int sarea_priv_offset;     /* Configuration cache with default values for all contexts */     driOptionCache optionCache; @@ -87,7 +85,6 @@ typedef struct {  #include "savagecontext.h"  extern void savageGetLock( savageContextPtr imesa, GLuint flags ); -extern void savageEmitHwStateLocked( savageContextPtr imesa );  extern void savageEmitScissorValues( savageContextPtr imesa, int box_nr, int emit );  extern void savageEmitDrawingRectangle( savageContextPtr imesa );  extern void savageXMesaSetBackClipRects( savageContextPtr imesa ); diff --git a/src/mesa/drivers/dri/savage/savage_xmesa.c b/src/mesa/drivers/dri/savage/savage_xmesa.c index bcbc9d69ed..f1798de134 100644 --- a/src/mesa/drivers/dri/savage/savage_xmesa.c +++ b/src/mesa/drivers/dri/savage/savage_xmesa.c @@ -55,8 +55,6 @@  #include "savage_dri.h" -#include "savagedma.h" -  #include "xmlpool.h"  /* Configuration @@ -85,6 +83,8 @@ static const struct dri_debug_control debug_control[] =      { "fall",  DEBUG_FALLBACKS },      { "api",   DEBUG_VERBOSE_API },      { "lru",   DEBUG_VERBOSE_LRU }, +    { "verb",  DEBUG_VERBOSE_MSG }, +    { "dma",   DEBUG_DMA },      { NULL,    0 }  };  #ifndef SAVAGE_DEBUG @@ -131,7 +131,6 @@ savageInitDriver(__DRIscreenPrivate *sPriv)    savageScreenPrivate *savageScreen;    SAVAGEDRIPtr         gDRIPriv = (SAVAGEDRIPtr)sPriv->pDevPriv; -     /* Allocate the private area */     savageScreen = (savageScreenPrivate *)Xmalloc(sizeof(savageScreenPrivate));     if (!savageScreen) @@ -146,23 +145,19 @@ savageInitDriver(__DRIscreenPrivate *sPriv)     savageScreen->mem=gDRIPriv->mem;     savageScreen->cpp=gDRIPriv->cpp;     savageScreen->zpp=gDRIPriv->zpp; -   savageScreen->frontPitch=gDRIPriv->frontPitch; -   savageScreen->frontOffset=gDRIPriv->frontOffset; -   savageScreen->frontBitmapDesc = gDRIPriv->frontBitmapDesc; -    + +   savageScreen->agpMode=gDRIPriv->agpMode; + +   savageScreen->bufferSize=gDRIPriv->bufferSize; +     if (gDRIPriv->cpp == 4)          savageScreen->frontFormat = DV_PF_8888;     else         savageScreen->frontFormat = DV_PF_565; - +   savageScreen->frontOffset=gDRIPriv->frontOffset;     savageScreen->backOffset = gDRIPriv->backOffset;  -   savageScreen->backBitmapDesc = gDRIPriv->backBitmapDesc;      savageScreen->depthOffset=gDRIPriv->depthOffset; -   savageScreen->depthBitmapDesc = gDRIPriv->depthBitmapDesc;  -#if 0    -   savageScreen->backPitch = gDRIPriv->auxPitch; -   savageScreen->backPitchBits = gDRIPriv->auxPitchBits; -#endif    +     savageScreen->textureOffset[SAVAGE_CARD_HEAP] =                                      gDRIPriv->textureOffset;     savageScreen->textureSize[SAVAGE_CARD_HEAP] =  @@ -171,57 +166,32 @@ savageInitDriver(__DRIscreenPrivate *sPriv)                                     gDRIPriv->logTextureGranularity;     savageScreen->textureOffset[SAVAGE_AGP_HEAP] =  -                                   gDRIPriv->agpTextures.handle; +                                   gDRIPriv->agpTextureHandle;     savageScreen->textureSize[SAVAGE_AGP_HEAP] =  -                                   gDRIPriv->agpTextures.size; +                                   gDRIPriv->agpTextureSize;     savageScreen->logTextureGranularity[SAVAGE_AGP_HEAP] =                                     gDRIPriv->logAgpTextureGranularity; -    -   savageScreen->back.handle = gDRIPriv->backbuffer; -   savageScreen->back.size = gDRIPriv->backbufferSize; -   savageScreen->back.map =  -       (drmAddress)(((unsigned int)sPriv->pFB)+gDRIPriv->backOffset); -    -   savageScreen->depth.handle = gDRIPriv->depthbuffer; -   savageScreen->depth.size = gDRIPriv->depthbufferSize; - -   savageScreen->depth.map =  -              (drmAddress)(((unsigned int)sPriv->pFB)+gDRIPriv->depthOffset); -    -   savageScreen->sarea_priv_offset = gDRIPriv->sarea_priv_offset; - -   savageScreen->texVirtual[SAVAGE_CARD_HEAP] =  -             (drmAddress)(((unsigned int)sPriv->pFB)+gDRIPriv->textureOffset); +   savageScreen->agpTextures.handle = gDRIPriv->agpTextureHandle; +   savageScreen->agpTextures.size   = gDRIPriv->agpTextureSize;     if (drmMap(sPriv->fd,  -	      gDRIPriv->registers.handle,  -	      gDRIPriv->registers.size,  -	      (drmAddress *)&(gDRIPriv->registers.map)) != 0)  -   { -      Xfree(savageScreen); -      sPriv->private = NULL; -      return GL_FALSE; -   } -    -   if (drmMap(sPriv->fd,  -	      gDRIPriv->agpTextures.handle,  -	      gDRIPriv->agpTextures.size,  -	      (drmAddress *)&(gDRIPriv->agpTextures.map)) != 0)  +	      savageScreen->agpTextures.handle, +	      savageScreen->agpTextures.size, +	      (drmAddress *)&(savageScreen->agpTextures.map)) != 0)      {        Xfree(savageScreen);        sPriv->private = NULL;        return GL_FALSE;     } -/* agp texture*/ +   savageScreen->texVirtual[SAVAGE_CARD_HEAP] =  +             (drmAddress)(((unsigned int)sPriv->pFB)+gDRIPriv->textureOffset);     savageScreen->texVirtual[SAVAGE_AGP_HEAP] =  -                        (drmAddress)(gDRIPriv->agpTextures.map); - -   gDRIPriv->BCIcmdBuf.map = (drmAddress *) -                           ((unsigned int)gDRIPriv->registers.map+0x00010000); +                        (drmAddress)(savageScreen->agpTextures.map); -   savageScreen->aperture.handle = gDRIPriv->aperture.handle; -   savageScreen->aperture.size   = gDRIPriv->aperture.size; +   savageScreen->aperture.handle = gDRIPriv->apertureHandle; +   savageScreen->aperture.size   = gDRIPriv->apertureSize; +   savageScreen->aperturePitch   = gDRIPriv->aperturePitch;     if (drmMap(sPriv->fd,   	      savageScreen->aperture.handle,   	      savageScreen->aperture.size,  @@ -230,8 +200,12 @@ savageInitDriver(__DRIscreenPrivate *sPriv)        Xfree(savageScreen);        sPriv->private = NULL;        return GL_FALSE; -   }  -       +   } + +   savageScreen->bufs = drmMapBufs(sPriv->fd); + +   savageScreen->sarea_priv_offset = gDRIPriv->sarea_priv_offset; +     /* parse information in __driConfigOptions */     driParseOptionInfo (&savageScreen->optionCache,  		       __driConfigOptions, __driNConfigOptions); @@ -251,6 +225,8 @@ savageDestroyScreen(__DRIscreenPrivate *sPriv)  {     savageScreenPrivate *savageScreen = (savageScreenPrivate *)sPriv->private; +   drmUnmapBufs(savageScreen->bufs); +     /* free all option information */     driDestroyOptionInfo (&savageScreen->optionCache); @@ -295,7 +271,6 @@ savageCreateContext( const __GLcontextModes *mesaVis,     savageContextPtr imesa;     __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;     struct dd_function_table functions; -   SAVAGEDRIPtr         gDRIPriv = (SAVAGEDRIPtr)sPriv->pDevPriv;     savageScreenPrivate *savageScreen = (savageScreenPrivate *)sPriv->private;     drm_savage_sarea_t *saPriv=(drm_savage_sarea_t *)(((char*)sPriv->pSAREA)+  						 savageScreen->sarea_priv_offset); @@ -323,6 +298,12 @@ savageCreateContext( const __GLcontextModes *mesaVis,     }     driContextPriv->driverPrivate = imesa; +   imesa->cmdBuf.size = SAVAGE_CMDBUF_SIZE; +   imesa->cmdBuf.base = imesa->cmdBuf.write = +       malloc(SAVAGE_CMDBUF_SIZE * sizeof(drm_savage_cmd_header_t)); +   if (!imesa->cmdBuf.base) +       return GL_FALSE; +     /* Parse configuration files */     driParseConfigFiles (&imesa->optionCache, &savageScreen->optionCache,                          sPriv->myNum, "savage"); @@ -398,26 +379,14 @@ savageCreateContext( const __GLcontextModes *mesaVis,     /* DMA buffer */ -   /*The shadow pointer*/ -   imesa->shadowPointer =  -     (volatile GLuint *)((((GLuint)(&saPriv->shadow_status)) + 31) & 0xffffffe0L) ; -   /* here we use eventTag1 because eventTag0 is used by HWXvMC*/ -   imesa->eventTag1 = (volatile GLuint *)(imesa->shadowPointer + 6); -   /*   imesa->eventTag1=(volatile GLuint *)(imesa->MMIO_BASE+0x48c04);*/ -   imesa->shadowCounter = MAX_SHADOWCOUNTER; -   imesa->shadowStatus = GL_TRUE;/*Will judge by 2d message */ - -   imesa->MMIO_BASE = (GLuint)gDRIPriv->registers.map; -   imesa->BCIBase= (GLuint)gDRIPriv->BCIcmdBuf.map;     for(i=0;i<5;i++)     {         imesa->apertureBase[i] = ((GLuint)savageScreen->aperture.map +                                    0x01000000 * i );     } -   imesa->aperturePitch = gDRIPriv->aperturePitch; -    -    +   imesa->aperturePitch = savageScreen->aperturePitch; +     /* change texHeap initialize to support two kind of texture heap*/     /* here is some parts of initialization, others in InitDriver() */ @@ -440,7 +409,17 @@ savageCreateContext( const __GLcontextModes *mesaVis,     imesa->depth_scale = (imesa->savageScreen->zpp == 2) ?         (1.0F/0x10000):(1.0F/0x1000000); -   imesa->vertex_dma_buffer = NULL; +   imesa->bufferSize = savageScreen->bufferSize; +   imesa->dmaVtxBuf.total = 0; +   imesa->dmaVtxBuf.used = 0; +   imesa->dmaVtxBuf.flushed = 0; + +   imesa->clientVtxBuf.total = 16384; +   imesa->clientVtxBuf.used = 0; +   imesa->clientVtxBuf.flushed = 0; +   imesa->clientVtxBuf.buf = (u_int32_t *)malloc(16384*4); + +   imesa->vtxBuf = &imesa->clientVtxBuf;     /* Uninitialized vertex format. Force setting the vertex state in      * savageRenderStart. @@ -450,6 +429,7 @@ savageCreateContext( const __GLcontextModes *mesaVis,     /* Utah stuff      */     imesa->new_state = ~0; +   imesa->new_gl_state = ~0;     imesa->RenderIndex = ~0;     imesa->dirty = ~0;     imesa->lostContext = GL_TRUE; @@ -483,8 +463,6 @@ savageCreateContext( const __GLcontextModes *mesaVis,     ctx->DriverCtx = (void *) imesa;     imesa->glCtx = ctx; -   if (savageDMAInit(imesa) == GL_FALSE) -       return GL_FALSE;    #ifndef SAVAGE_DEBUG     SAVAGE_DEBUG = driParseDebugString( getenv( "SAVAGE_DEBUG" ), @@ -501,8 +479,7 @@ savageCreateContext( const __GLcontextModes *mesaVis,     savageDDInitState( imesa ); -   if (driQueryOptionb(&imesa->optionCache, "no_rast")) -       FALLBACK(ctx, SAVAGE_FALLBACK_NORAST, GL_TRUE); +   imesa->no_rast = driQueryOptionb(&imesa->optionCache, "no_rast");     driContextPriv->driverPrivate = (void *) imesa; @@ -529,8 +506,10 @@ savageDestroyContext(__DRIcontextPrivate *driContextPriv)        }        foreach_s (t, next_t, &(imesa->SwappedOut))  	 savageDestroyTexObj(imesa, t); -      /*free the dma buffer*/ -      savageDMAClose(imesa); + +      free(imesa->cmdBuf.base); +      free(imesa->clientVtxBuf.buf); +        _swsetup_DestroyContext(imesa->glCtx );        _tnl_DestroyContext( imesa->glCtx );        _ac_DestroyContext( imesa->glCtx ); @@ -753,10 +732,13 @@ void savageGetLock( savageContextPtr imesa, GLuint flags )      * more broken than usual.      */     if (sarea->ctxOwner != me) { -      imesa->dirty |= (SAVAGE_UPLOAD_CTX | -		       SAVAGE_UPLOAD_CLIPRECTS | +      imesa->dirty |= (SAVAGE_UPLOAD_LOCAL | +		       SAVAGE_UPLOAD_GLOBAL | +		       SAVAGE_UPLOAD_FOGTBL |  		       SAVAGE_UPLOAD_TEX0 | -		       SAVAGE_UPLOAD_TEX1); +		       SAVAGE_UPLOAD_TEX1 | +		       SAVAGE_UPLOAD_TEXGLOBAL | +		       SAVAGE_UPLOAD_CLIPRECTS);        imesa->lostContext = GL_TRUE;        sarea->ctxOwner = me;     } @@ -794,8 +776,6 @@ void savageGetLock( savageContextPtr imesa, GLuint flags )  	      savageResetGlobalLRU( imesa , heap );             } -           imesa->dirty |= SAVAGE_UPLOAD_TEX0IMAGE; -           imesa->dirty |= SAVAGE_UPLOAD_TEX1IMAGE;             imesa->texAge[heap] = sarea->texAge[heap];         }     } /* end of for loop */  @@ -948,10 +928,9 @@ void * __driCreateNewScreen( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc  {     __DRIscreenPrivate *psp; -   static const __DRIversion ddx_expected = { 1, 0, 0 }; +   static const __DRIversion ddx_expected = { 2, 0, 0 };     static const __DRIversion dri_expected = { 4, 0, 0 }; -   static const __DRIversion drm_expected = { 1, 0, 0 }; - +   static const __DRIversion drm_expected = { 2, 0, 0 };     if ( ! driCheckDriDdxDrmVersions2( "Savage",  				      dri_version, & dri_expected, diff --git a/src/mesa/drivers/dri/savage/savagecontext.h b/src/mesa/drivers/dri/savage/savagecontext.h index f41b73e0de..8978f9247c 100644 --- a/src/mesa/drivers/dri/savage/savagecontext.h +++ b/src/mesa/drivers/dri/savage/savagecontext.h @@ -42,7 +42,6 @@ typedef struct savage_texture_object_t *savageTextureObjectPtr;  #include "tnl/t_vertex.h"  #include "savagetex.h" -#include "savagedma.h"  #include "xmlconfig.h" @@ -69,10 +68,26 @@ typedef struct savage_texture_object_t *savageTextureObjectPtr;  #define SAVAGE_NEW_TEXTURE 0x1  #define SAVAGE_NEW_CULL    0x2 +/* What needs to be changed for the current vertex dma buffer? + * This will go away! + */ +#define SAVAGE_UPLOAD_LOCAL	0x1  /* DrawLocalCtrl (S4) or  +					DrawCtrl and ZBufCtrl (S3D) */ +#define SAVAGE_UPLOAD_TEX0	0x2  /* texture unit 0 */ +#define SAVAGE_UPLOAD_TEX1	0x4  /* texture unit 1 (S4 only) */ +#define SAVAGE_UPLOAD_FOGTBL	0x8  /* fog table */ +#define SAVAGE_UPLOAD_GLOBAL	0x10 /* most global regs */ +#define SAVAGE_UPLOAD_TEXGLOBAL 0x20 /* TexBlendColor (S4 only) */ +#define SAVAGE_UPLOAD_CLIPRECTS 0x1000 /* FIXME: get rid of this */  /*define the max numer of vertex in vertex buf*/  #define SAVAGE_MAX_VERTEXS 0x10000 +/* Don't make it too big. We don't want to buffer up a whole frame + * that would force the application to wait later. */ +#define SAVAGE_CMDBUF_SIZE 1024 +#define SAVAGE_MAX_VERTS_PENDING 1024 +  /* Use the templated vertex formats:   */  #define TAG(x) savage##x @@ -113,6 +128,18 @@ typedef void (*savage_point_func)( savageContextPtr, savageVertex * );  			imesa->savageScreen->deviceID == CHIP_S3TRISTAR64CDDR ) +struct savage_vtxbuf_t { +    GLuint total, used, flushed; /* in 32 bit units */ +    GLuint idx;		/* for DMA buffers */ +    u_int32_t *buf; +}; + +struct savage_cmdbuf_t { +    GLuint size; /* size in qwords */ +    drm_savage_cmd_header_t *base;  /* initial state starts here */ +    drm_savage_cmd_header_t *start; /* drawing/state commands start here */ +    drm_savage_cmd_header_t *write; /* append stuff here */ +};  struct savage_context_t { @@ -143,11 +170,12 @@ struct savage_context_t {      GLuint new_gl_state;      GLboolean ptexHack; -    GLuint BCIBase;   -    GLuint MMIO_BASE; +    /* Command buffer */ +    struct savage_cmdbuf_t cmdBuf; -    /* DMA command buffer */ -    DMABuffer_t DMABuf; +    /* Vertex buffers */ +    struct savage_vtxbuf_t dmaVtxBuf, clientVtxBuf; +    struct savage_vtxbuf_t *vtxBuf;      /* aperture base */      GLuint apertureBase[5]; @@ -179,7 +207,8 @@ struct savage_context_t {     GLenum raster_primitive;     GLenum render_primitive; -   GLuint DrawPrimitiveCmd; +   GLuint skip; +   GLubyte HwPrim;     GLuint HwVertexSize;     /* Fallback rasterization functions  @@ -194,8 +223,9 @@ struct savage_context_t {      GLuint ClearColor;      GLfloat depth_scale;      GLfloat hw_viewport[16]; -    /* DRI stuff */   -    drmBufPtr  vertex_dma_buffer; +    /* DRI stuff */ +    GLuint bufferSize; +    GLuint vertsPending;      GLframebuffer *glBuffer; @@ -225,8 +255,8 @@ struct savage_context_t {      GLuint backup_streamFIFO;      GLuint NotFirstFrame; +    GLboolean inSwap;      GLuint lastSwap; -    GLuint secondLastSwap;      GLuint ctxAge;      GLuint dirtyAge;      GLuint any_contend;		/* throttle me harder */ @@ -235,7 +265,7 @@ struct savage_context_t {      GLboolean scissorChanged;      drm_clip_rect_t draw_rect;      drm_clip_rect_t scissor_rect; -    drm_clip_rect_t tmp_boxes[2][SAVAGE_NR_SAREA_CLIPRECTS]; +      /*Texture aging and DMA based aging*/      unsigned int texAge[SAVAGE_NR_TEX_HEAPS];  @@ -259,16 +289,11 @@ struct savage_context_t {      GLboolean hw_stencil; -    /*shadow pointer*/ -    volatile GLuint  *shadowPointer; -    volatile GLuint *eventTag1; -    GLuint shadowCounter; -    GLboolean shadowStatus; -      /* Configuration cache       */      driOptionCache optionCache; -    int texture_depth; +    GLint texture_depth; +    GLboolean no_rast;  };  #define SAVAGE_CONTEXT(ctx) ((savageContextPtr)(ctx->DriverCtx)) @@ -283,6 +308,8 @@ extern int SAVAGE_DEBUG;  #define DEBUG_FALLBACKS      0x001  #define DEBUG_VERBOSE_API    0x002  #define DEBUG_VERBOSE_LRU    0x004 +#define DEBUG_VERBOSE_MSG    0x008 +#define DEBUG_DMA            0x010  #define TARGET_FRONT    0x0  #define TARGET_BACK     0x1 diff --git a/src/mesa/drivers/dri/savage/savagedd.c b/src/mesa/drivers/dri/savage/savagedd.c index dddc6d9a65..312f6f62f4 100644 --- a/src/mesa/drivers/dri/savage/savagedd.c +++ b/src/mesa/drivers/dri/savage/savagedd.c @@ -38,6 +38,10 @@  #include "savagecontext.h"  #include "extensions.h" +#include "utils.h" + + +#define DRIVER_DATE "20050101"  /***************************************   * Mesa's Driver Functions @@ -46,11 +50,33 @@  static const GLubyte *savageDDGetString( GLcontext *ctx, GLenum name )  { +   static char *cardNames[S3_LAST] = { +       "Unknown", +       "Savage3D", +       "Savage/MX/IX", +       "Savage4", +       "ProSavage", +       "Twister", +       "ProSavageDDR", +       "SuperSavage", +       "Savage2000" +   }; +   static char buffer[128]; +   savageContextPtr imesa = SAVAGE_CONTEXT(ctx); +   savageScreenPrivate *screen = imesa->savageScreen; +   enum S3CHIPTAGS chipset = screen->chipset; +   unsigned offset; + +   if (chipset < S3_SAVAGE3D || chipset >= S3_LAST) +      chipset = S3_UNKNOWN; /* should not happen */ +     switch (name) {     case GL_VENDOR:        return (GLubyte *)"S3 Graphics Inc.";     case GL_RENDERER: -      return (GLubyte *)"Mesa DRI SAVAGE Linux_1.1.18"; +      offset = driGetRendererString( buffer, cardNames[chipset], DRIVER_DATE, +				     screen->agpMode ); +      return (GLubyte *)buffer;     default:        return 0;     } diff --git a/src/mesa/drivers/dri/savage/savagedma.c b/src/mesa/drivers/dri/savage/savagedma.c index 86ee763a31..51a1e6d2bd 100644 --- a/src/mesa/drivers/dri/savage/savagedma.c +++ b/src/mesa/drivers/dri/savage/savagedma.c @@ -30,20 +30,7 @@  #include <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 0896ca148d..09f0c46e95 100644 --- a/src/mesa/drivers/dri/savage/savagedma.h +++ b/src/mesa/drivers/dri/savage/savagedma.h @@ -49,8 +49,4 @@ void savageDMAFlush (savageContextPtr imesa);  int savageDMAInit (savageContextPtr imesa);  int savageDMAClose (savageContextPtr); -/* faked implementation of vertex buffers */ -void savageFakeVertices (savageContextPtr imesa, drmBufPtr buffer); -drmBufPtr savageFakeGetBuffer (savageContextPtr imesa); -  #endif diff --git a/src/mesa/drivers/dri/savage/savageioctl.c b/src/mesa/drivers/dri/savage/savageioctl.c index ac9e055e93..dd7a84e2e7 100644 --- a/src/mesa/drivers/dri/savage/savageioctl.c +++ b/src/mesa/drivers/dri/savage/savageioctl.c @@ -37,16 +37,86 @@  #include "savagecontext.h"  #include "savageioctl.h"  #include "savage_bci.h" -#include "savagedma.h" +#include "savagestate.h"  #include "drm.h"  #include <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; +   savageFlushVertices(imesa); -	   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; +   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; +       } -	   savage_BCI_clear(ctx,&clear); +       if ((flags & SAVAGE_DEPTH) && !depthCleared) { +	   drm_savage_cmd_header_t *cmd; +	   cmd = savageAllocCmdBuf(imesa, sizeof(drm_savage_cmd_header_t)); +	   cmd[0].clear0.cmd = SAVAGE_CMD_CLEAR; +	   cmd[0].clear0.flags = SAVAGE_DEPTH; +	   cmd[1].clear1.mask = depthMask; +	   cmd[1].clear1.value = clearDepth;         } -       UNLOCK_HARDWARE( imesa ); -       imesa->dirty |= SAVAGE_UPLOAD_CLIPRECTS|SAVAGE_UPLOAD_CTX; +       imesa->dirty |= SAVAGE_UPLOAD_CLIPRECTS;     }     if (mask)  @@ -318,7 +402,11 @@ static void savageDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all,  } - +/* This is necessary as to prevent annyoing stuttering effects with + * some games, though it does reduce the frame rate (glxgears) + * slightly. I believe this is due to texture uploads which do not go + * through the Savage command pipeline yet. */ +#define SYNC_FRAMES 1  /*   * Copy the back buffer to the front buffer.  @@ -326,11 +414,9 @@ static void savageDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all,  void savageSwapBuffers( __DRIdrawablePrivate *dPriv )  {     savageContextPtr imesa; -   drm_clip_rect_t *pbox; -   int nbox; -   int i; -   GLboolean pending; +   if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG) +       fprintf (stderr, "%s\n================================\n", __FUNCTION__);     assert(dPriv);     assert(dPriv->driContextPriv); @@ -342,38 +428,30 @@ void savageSwapBuffers( __DRIdrawablePrivate *dPriv )     FLUSH_BATCH(imesa); -   LOCK_HARDWARE( imesa ); -   WAIT_IDLE_EMPTY; -   PAGE_PENDING(pending); - -   if(!pending) -   { -   pbox = dPriv->pClipRects; -   nbox = dPriv->numClipRects; +#if SYNC_FRAMES +   imesa->lastSwap = savageEmitEvent( imesa, 0 ); +#endif +   if (imesa->lastSwap != 0) +       savageWaitEvent( imesa, imesa->lastSwap ); -   for (i = 0 ; i < nbox ; )     { -      int nr = MIN2(i + SAVAGE_NR_SAREA_CLIPRECTS, dPriv->numClipRects); -      drm_clip_rect_t *b = (drm_clip_rect_t *)imesa->sarea->boxes; - -      imesa->sarea->nbox = nr - i; - -      for ( ; i < nr ; i++)  -	 *b++ = pbox[i]; -     savage_BCI_swap(imesa) ; -   } +       drm_savage_cmd_header_t *cmd = savageAllocCmdBuf(imesa, 0); +       cmd->cmd.cmd = SAVAGE_CMD_SWAP; +       imesa->inSwap = GL_TRUE; /* ignore scissors in savageFlushCmdBuf */ +       savageFlushCmdBuf(imesa, GL_FALSE); +       imesa->inSwap = GL_FALSE;     } -   UNLOCK_HARDWARE( imesa ); -    +#if !SYNC_FRAMES +   imesa->lastSwap = savageEmitEvent( imesa, 0 ); +#endif  }  /* This waits for *everybody* to finish rendering -- overkill.   */  void savageDmaFinish( savageContextPtr imesa  )   { -    savageDMAFlush(imesa); -    WAIT_IDLE_EMPTY; +    savageWaitEvent( imesa, savageEmitEventLocked( imesa, SAVAGE_WAIT_3D ) );  } @@ -393,152 +471,189 @@ void savageWaitAge( savageContextPtr imesa, int age  )  } +unsigned int savageEmitEventLocked( savageContextPtr imesa, unsigned int flags ) +{ +    drm_savage_event_emit_t event; +    int ret; +    event.count = 0; +    event.flags = flags; +    ret = drmCommandWriteRead( imesa->driFd, DRM_SAVAGE_BCI_EVENT_EMIT, +			       &event, sizeof(event) ); +    if (ret) { +	fprintf (stderr, "emit event returned %d\n", ret); +	exit (1); +    } +    return event.count; +} +unsigned int savageEmitEvent( savageContextPtr imesa, unsigned int flags ) +{ +    unsigned int ret; +    LOCK_HARDWARE( imesa ); +    ret = savageEmitEventLocked( imesa, flags ); +    UNLOCK_HARDWARE( imesa ); +    return ret; +} + -void savageFlushVerticesLocked( savageContextPtr imesa ) +void savageWaitEvent( savageContextPtr imesa, unsigned int count )  { -    drmBufPtr buffer = imesa->vertex_dma_buffer; +    drm_savage_event_wait_t event; +    int ret; +    event.count = count; +    event.flags = 0; +    ret = drmCommandWriteRead( imesa->driFd, DRM_SAVAGE_BCI_EVENT_WAIT, +			       &event, sizeof(event) ); +    if (ret) { +	fprintf (stderr, "wait event returned %d\n", ret); +	exit (1); +    } +} -    if (!buffer) -	return; -    imesa->vertex_dma_buffer = NULL; +void savageFlushVertices( savageContextPtr imesa ) +{ +    struct savage_vtxbuf_t *buffer = imesa->vtxBuf; + +    if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG) +	fprintf (stderr, "%s\n", __FUNCTION__); -    /* Lot's of stuff to do here. For now there is a fake DMA implementation -     * in savagedma.c that emits drawing commands. Cliprects are not handled -     * yet. */ -    if (buffer->used) { +    if (!buffer->total) +	return; + +    if (buffer->used > buffer->flushed) { +	drm_savage_cmd_header_t *cmd;  	/* State must be updated "per primitive" because hardware  	 * culling must be disabled for unfilled primitives, points  	 * and lines. */ -	savageEmitHwStateLocked (imesa); -	savageFakeVertices (imesa, buffer); +	savageEmitChangedState (imesa); +	cmd = savageAllocCmdBuf(imesa, 0); +	cmd->prim.cmd = buffer == &imesa->dmaVtxBuf ? +	    SAVAGE_CMD_DMA_PRIM : SAVAGE_CMD_VB_PRIM; +	cmd->prim.prim = imesa->HwPrim; +	cmd->prim.skip = imesa->skip; +	cmd->prim.start = buffer->flushed / imesa->HwVertexSize; +	cmd->prim.count = buffer->used / imesa->HwVertexSize - cmd->prim.start; +	buffer->flushed = buffer->used; +	/* Make sure we don't buffer too many vertices without +	 * telling the hardware. */ +	imesa->vertsPending += cmd->prim.count; +	if (imesa->vertsPending > SAVAGE_MAX_VERTS_PENDING) { +	    savageFlushCmdBuf(imesa, GL_FALSE); +	    imesa->vertsPending = 0; +	}      }  } - -void savageFlushVertices( savageContextPtr imesa )  +void savageFlushCmdBufLocked( savageContextPtr imesa, GLboolean discard )  { -    LOCK_HARDWARE(imesa); -    savageFlushVerticesLocked (imesa); -    UNLOCK_HARDWARE(imesa); +    __DRIdrawablePrivate *dPriv = imesa->driDrawable; +    drm_savage_cmdbuf_t cmdbuf; +    drm_savage_cmd_header_t *start; +    int ret; + +    /* If we lost the context we must restore the initial state (at +     * the start of the command buffer). */ +    if (imesa->lostContext) { +	start = imesa->cmdBuf.base; +	imesa->lostContext = GL_FALSE; +    } else +	start = imesa->cmdBuf.start; + +    if (!imesa->dmaVtxBuf.total) +	discard = GL_FALSE; + +    if ((SAVAGE_DEBUG & DEBUG_DMA) && discard) +	fprintf (stderr, "Discarding DMA buffer, used=%u\n", +		 imesa->dmaVtxBuf.used); + +    cmdbuf.dma_idx = imesa->dmaVtxBuf.idx; +    cmdbuf.discard = discard; +    cmdbuf.vb_addr = imesa->clientVtxBuf.buf; +    cmdbuf.vb_size = imesa->clientVtxBuf.total*4; +    cmdbuf.vb_stride = imesa->HwVertexSize; +    cmdbuf.cmd_addr = start; +    cmdbuf.size = (imesa->cmdBuf.write - start); +    if (!imesa->inSwap && imesa->glCtx->Scissor.Enabled) { +	drm_clip_rect_t *box = dPriv->pClipRects, *ibox; +	GLuint nbox = dPriv->numClipRects, nibox; +	ibox = malloc(dPriv->numClipRects*sizeof(drm_clip_rect_t)); +	if (!ibox) { +	    fprintf(stderr, "Out of memory.\n"); +	    exit(1); +	} +	nibox = savageIntersectClipRects(ibox, box, nbox, &imesa->scissor_rect); +	cmdbuf.nbox = nibox; +	cmdbuf.box_addr = ibox; +    } else { +	cmdbuf.nbox = dPriv->numClipRects; +	cmdbuf.box_addr = dPriv->pClipRects; +    } + +    ret = drmCommandWrite( imesa->driFd, DRM_SAVAGE_BCI_CMDBUF, +			   &cmdbuf, sizeof(cmdbuf) ); +    if (ret) { +	fprintf (stderr, "cmdbuf ioctl returned %d\n", ret); +	exit(1); +    } + +    if (cmdbuf.box_addr != dPriv->pClipRects) { +	free(cmdbuf.box_addr); +    } + +    if (discard) { +	imesa->dmaVtxBuf.total = 0; +	imesa->dmaVtxBuf.used = 0; +	imesa->dmaVtxBuf.flushed = 0; +    } +    imesa->clientVtxBuf.used = 0; +    imesa->clientVtxBuf.flushed = 0; + +    imesa->cmdBuf.write = imesa->cmdBuf.base; + +    /* Save the current state at the start of the command buffer. That +     * state will only be emitted, if the context was lost since the +     * last command buffer. */ +    savageEmitOldState(imesa); +    imesa->cmdBuf.start = imesa->cmdBuf.write;  } -int savage_check_copy(int fd) +void savageFlushCmdBuf( savageContextPtr imesa, GLboolean discard )   { -    return 0; +    if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG) +	fprintf (stderr, "%s\n", __FUNCTION__); +    LOCK_HARDWARE(imesa); +    savageFlushCmdBufLocked (imesa, discard); +    UNLOCK_HARDWARE(imesa);  } +  static void savageDDFlush( GLcontext *ctx )  { +    if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG) +	fprintf (stderr, "%s\n", __FUNCTION__);      savageContextPtr imesa = SAVAGE_CONTEXT(ctx); +    savageFlushVertices (imesa);      LOCK_HARDWARE(imesa); -    savageFlushVerticesLocked (imesa); -    savageDMAFlush (imesa); +    savageFlushCmdBufLocked(imesa, GL_FALSE);      UNLOCK_HARDWARE(imesa);  }  static void savageDDFinish( GLcontext *ctx  )   { +    if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG) +	fprintf (stderr, "%s\n", __FUNCTION__);      savageContextPtr imesa = SAVAGE_CONTEXT(ctx); +    savageFlushVertices (imesa);      LOCK_HARDWARE(imesa); -    savageFlushVerticesLocked (imesa); +    savageFlushCmdBufLocked(imesa, GL_FALSE);      savageDmaFinish (imesa);      UNLOCK_HARDWARE(imesa);  } -#define ALT_STATUS_WORD0 (* (volatile GLuint *)(imesa->MMIO_BASE+0x48c60)) -#define STATUS_WORD0 (* (volatile GLuint *)(imesa->MMIO_BASE+0x48c00)) -#define MAXFIFO_S4  0x7F00 -#define MAXFIFO_S3D 0x7F00 - -static GLboolean savagePagePending_s4( savageContextPtr imesa ) { -    return (ALT_STATUS_WORD0 & 0x08000000) ? GL_TRUE : GL_FALSE; -} -static GLboolean savagePagePending_s3d( savageContextPtr imesa ) { -    return GL_FALSE; -} -static void savageWaitForFIFO_s4( savageContextPtr imesa, unsigned count ) { -    int loop = 0; -    int slots = MAXFIFO_S4-count; -    while((ALT_STATUS_WORD0 & 0x001fffff) > slots && loop++ < MAXLOOP); -} -static void savageWaitForFIFO_s3d( savageContextPtr imesa, unsigned count ) { -    int loop = 0; -    int slots = MAXFIFO_S3D-count; -    while((STATUS_WORD0 & 0x0001ffff) > slots && loop++ < MAXLOOP); -} -static void savageWaitIdleEmpty_s4( savageContextPtr imesa ) { -    int loop = 0; -    while((ALT_STATUS_WORD0 & 0x00ffffff) != 0x00E00000L && loop++ < MAXLOOP); -} -static void savageWaitIdleEmpty_s3d( savageContextPtr imesa ) { -    int loop = 0; -    while((STATUS_WORD0 & 0x000fffff) != 0x000E0000L && loop++ < MAXLOOP); -} - -GLboolean (*savagePagePending)( savageContextPtr imesa ) = NULL; -void (*savageWaitForFIFO)( savageContextPtr imesa, unsigned count ) = NULL; -void (*savageWaitIdleEmpty)( savageContextPtr imesa ) = NULL; - -  void savageDDInitIoctlFuncs( GLcontext *ctx )  {     ctx->Driver.Clear = savageDDClear;     ctx->Driver.Flush = savageDDFlush;     ctx->Driver.Finish = savageDDFinish; -   if (SAVAGE_CONTEXT( ctx )->savageScreen->chipset >= S3_SAVAGE4) { -       savagePagePending = savagePagePending_s4; -       savageWaitForFIFO = savageWaitForFIFO_s4; -       savageWaitIdleEmpty = savageWaitIdleEmpty_s4; -   } else { -       savagePagePending = savagePagePending_s3d; -       savageWaitForFIFO = savageWaitForFIFO_s3d; -       savageWaitIdleEmpty = savageWaitIdleEmpty_s3d; -   }  } - -#if SAVAGE_CMD_DMA -/* Alloc a continuous memory */ -/* return: 0 error when kernel alloc pages(can try a half memory size)  -           >0 sucess -	   <0 Other error*/ -int  savageAllocDMABuffer(savageContextPtr imesa,  drm_savage_alloc_cont_mem_t *req) -{ -  int ret; -  if (req ==NULL) -    return 0; - -  if ((ret=ioctl(imesa->driFd, DRM_IOCTL_SAVAGE_ALLOC_CONTINUOUS_MEM, req)) <=0)     -    return ret; -   -  return 1; -   -} - -/* get the physics address*/ -GLuint savageGetPhyAddress(savageContextPtr imesa,void * pointer) -{ - -  drm_savage_get_physcis_address_t req; -  int ret; - -  req.v_address = (GLuint )pointer; -  ret = ioctl(imesa->driFd, DRM_IOCTL_SAVAGE_GET_PHYSICS_ADDRESS,&req); - -  return req.p_address; -} - -/* free the buffer got by savageAllocDMABuffe*/ -int  savageFreeDMABuffer(savageContextPtr imesa,  drm_savage_alloc_cont_mem_t *req) -{ -  GLuint ret; -  if (req ==NULL) -    return 0; -   -  if ((ret=ioctl(imesa->driFd, DRM_IOCTL_SAVAGE_FREE_CONTINUOUS_MEM, req)) <=0)     -    return ret; -  return 1; -   -} -#endif diff --git a/src/mesa/drivers/dri/savage/savageioctl.h b/src/mesa/drivers/dri/savage/savageioctl.h index acf398b9a6..941e74e56b 100644 --- a/src/mesa/drivers/dri/savage/savageioctl.h +++ b/src/mesa/drivers/dri/savage/savageioctl.h @@ -27,17 +27,22 @@  #define SAVAGE_IOCTL_H  #include "savagecontext.h" -#include "savagedma.h"  void savageGetGeneralDmaBufferLocked( savageContextPtr mmesa );   void savageFlushVertices( savageContextPtr mmesa );  -void savageFlushVerticesLocked( savageContextPtr mmesa );  void savageFlushGeneralLocked( savageContextPtr imesa );  void savageWaitAgeLocked( savageContextPtr imesa, int age );  void savageWaitAge( savageContextPtr imesa, int age ); +unsigned int savageEmitEventLocked( savageContextPtr imesa, unsigned int flags ); +unsigned int savageEmitEvent( savageContextPtr imesa, unsigned int flags ); +void savageWaitEvent( savageContextPtr imesa, unsigned int event); + +void savageFlushCmdBufLocked( savageContextPtr imesa, GLboolean discard ); +void savageFlushCmdBuf( savageContextPtr imesa, GLboolean discard ); +  void savageDmaFinish( savageContextPtr imesa );  void savageRegetLockQuiescent( savageContextPtr imesa ); @@ -46,54 +51,69 @@ void savageDDInitIoctlFuncs( GLcontext *ctx );  void savageSwapBuffers( __DRIdrawablePrivate *dPriv ); -int savage_check_copy(int fd); - -extern GLboolean (*savagePagePending)( savageContextPtr imesa ); -extern void (*savageWaitForFIFO)( savageContextPtr imesa, unsigned count ); -extern void (*savageWaitIdleEmpty)( savageContextPtr imesa ); - -#define PAGE_PENDING(result) do { \ -    result = savagePagePending(imesa); \ -} while (0) -#define WAIT_FOR_FIFO(count) do { \ -    savageWaitForFIFO(imesa, count); \ -} while (0)  #define WAIT_IDLE_EMPTY do { \ -    savageWaitIdleEmpty(imesa); \ +    savageWaitEvent(imesa, \ +		    savageEmitEvent(imesa, SAVAGE_WAIT_3D|SAVAGE_WAIT_2D)); \  } while (0) -#if SAVAGE_CMD_DMA -int  savageAllocDMABuffer(savageContextPtr imesa,  drm_savage_alloc_cont_mem_t *req); -GLuint savageGetPhyAddress(savageContextPtr imesa,void * pointer); -int  savageFreeDMABuffer(savageContextPtr, drm_savage_alloc_cont_mem_t*); -#endif -  #define FLUSH_BATCH(imesa) do { \ -    if (imesa->vertex_dma_buffer) savageFlushVertices(imesa); \ +    if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG) \ +        fprintf (stderr, "FLUSH_BATCH in %s\n", __FUNCTION__); \ +    savageFlushVertices(imesa); \ +    savageFlushCmdBuf(imesa, GL_FALSE); \  } while (0) +extern void savageGetDMABuffer( savageContextPtr imesa ); +  static __inline -u_int32_t *savageAllocDmaLow( savageContextPtr imesa, GLuint bytes ) +u_int32_t *savageAllocVtxBuf( savageContextPtr imesa, GLuint words )  { +   struct savage_vtxbuf_t *buffer = imesa->vtxBuf;     u_int32_t *head; -   if (!imesa->vertex_dma_buffer) { -      LOCK_HARDWARE(imesa); -      imesa->vertex_dma_buffer = savageFakeGetBuffer (imesa); -      UNLOCK_HARDWARE(imesa); -   } else if (imesa->vertex_dma_buffer->used + bytes > -	      imesa->vertex_dma_buffer->total) { -      LOCK_HARDWARE(imesa); -      savageFlushVerticesLocked( imesa ); -      imesa->vertex_dma_buffer = savageFakeGetBuffer (imesa); -      UNLOCK_HARDWARE(imesa); +   if (buffer == &imesa->dmaVtxBuf) { +       if (!buffer->total) { +	   LOCK_HARDWARE(imesa); +	   savageGetDMABuffer(imesa); +	   UNLOCK_HARDWARE(imesa); +       } else if (buffer->used + words > buffer->total) { +	   if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG) +	       fprintf (stderr, "... flushing DMA buffer in %s\n", +			__FUNCTION__); +	   savageFlushVertices( imesa ); +	   LOCK_HARDWARE(imesa); +	   savageFlushCmdBufLocked(imesa, GL_TRUE); /* discard DMA buffer */ +	   savageGetDMABuffer(imesa); +	   UNLOCK_HARDWARE(imesa); +       } +   } else if (buffer->used + words > buffer->total) { +       if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG) +	   fprintf (stderr, "... flushing client vertex buffer in %s\n", +		    __FUNCTION__); +       savageFlushVertices( imesa ); +       LOCK_HARDWARE(imesa); +       savageFlushCmdBufLocked(imesa, GL_FALSE); /* free clientVtxBuf */ +       UNLOCK_HARDWARE(imesa);     } -   head = (u_int32_t *)((u_int8_t *)imesa->vertex_dma_buffer->address + -		       imesa->vertex_dma_buffer->used); +   head = &buffer->buf[buffer->used]; -   imesa->vertex_dma_buffer->used += bytes; +   buffer->used += words;     return head;  } +static __inline +drm_savage_cmd_header_t *savageAllocCmdBuf( savageContextPtr imesa, GLuint bytes ) +{ +    drm_savage_cmd_header_t *ret; +    GLuint qwords = ((bytes + 7) >> 3) + 1; /* round up */ +    assert (qwords < imesa->cmdBuf.size); +    if (imesa->cmdBuf.write - imesa->cmdBuf.base + qwords > imesa->cmdBuf.size) { +	savageFlushCmdBuf(imesa, GL_FALSE); +    } +    ret = (drm_savage_cmd_header_t *)imesa->cmdBuf.write; +    imesa->cmdBuf.write += qwords; +    return ret; +} +  #endif diff --git a/src/mesa/drivers/dri/savage/savagestate.c b/src/mesa/drivers/dri/savage/savagestate.c index f4f22602d8..d6048291be 100644 --- a/src/mesa/drivers/dri/savage/savagestate.c +++ b/src/mesa/drivers/dri/savage/savagestate.c @@ -69,16 +69,10 @@ static __inline__ GLuint savagePackColor(GLuint format,  static void savageDDAlphaFunc_s4(GLcontext *ctx, GLenum func, GLfloat ref)  { -    /* This can be done in BlendFunc*/ -    savageContextPtr imesa = SAVAGE_CONTEXT(ctx); -    imesa->dirty |= SAVAGE_UPLOAD_CTX;      savageBlendFunc_s4(ctx);  }  static void savageDDAlphaFunc_s3d(GLcontext *ctx, GLenum func, GLfloat ref)  { -    /* This can be done in BlendFunc*/ -    savageContextPtr imesa = SAVAGE_CONTEXT(ctx); -    imesa->dirty |= SAVAGE_UPLOAD_CTX;      savageBlendFunc_s3d(ctx);  } @@ -103,6 +97,9 @@ static void savageDDBlendEquationSeparate(GLcontext *ctx,  static void savageBlendFunc_s4(GLcontext *ctx)  {      savageContextPtr imesa = SAVAGE_CONTEXT(ctx); +    u_int32_t drawLocalCtrl = imesa->regs.s4.drawLocalCtrl.ui; +    u_int32_t drawCtrl0 = imesa->regs.s4.drawCtrl0.ui; +    u_int32_t drawCtrl1 = imesa->regs.s4.drawCtrl1.ui;      /* set up draw control register (including blending, alpha       * test, and shading model) @@ -266,11 +263,17 @@ static void savageBlendFunc_s4(GLcontext *ctx)      /*imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn =          ~drawLocalCtrl.ni.wrZafterAlphaTst;*/ -    imesa->dirty |= SAVAGE_UPLOAD_CTX; +    if (drawLocalCtrl != imesa->regs.s4.drawLocalCtrl.ui) +	imesa->dirty |= SAVAGE_UPLOAD_LOCAL; +    if (drawCtrl0 != imesa->regs.s4.drawCtrl0.ui || +	drawCtrl1 != imesa->regs.s4.drawCtrl1.ui) +	imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;  }  static void savageBlendFunc_s3d(GLcontext *ctx)  {      savageContextPtr imesa = SAVAGE_CONTEXT(ctx); +    u_int32_t drawCtrl = imesa->regs.s3d.drawCtrl.ui; +    u_int32_t zBufCtrl = imesa->regs.s3d.zBufCtrl.ui;      /* set up draw control register (including blending, alpha       * test, dithering, and shading model) @@ -432,7 +435,9 @@ static void savageBlendFunc_s3d(GLcontext *ctx)      imesa->regs.s3d.zBufCtrl.ni.wrZafterAlphaTst =  	imesa->regs.s3d.drawCtrl.ni.alphaTestEn; -    imesa->dirty |= SAVAGE_UPLOAD_CTX; +    if (drawCtrl != imesa->regs.s3d.drawCtrl.ui || +	zBufCtrl != imesa->regs.s3d.zBufCtrl.ui) +	imesa->dirty |= SAVAGE_UPLOAD_LOCAL;  }  static void savageDDBlendFuncSeparate_s4( GLcontext *ctx, GLenum sfactorRGB,  @@ -456,7 +461,9 @@ static void savageDDDepthFunc_s4(GLcontext *ctx, GLenum func)  {      savageContextPtr imesa = SAVAGE_CONTEXT(ctx);      ZCmpFunc zmode; -#define depthIndex 0 +    u_int32_t drawLocalCtrl = imesa->regs.s4.drawLocalCtrl.ui; +    u_int32_t zBufCtrl = imesa->regs.s4.zBufCtrl.ui; +    u_int32_t zWatermarks = imesa->regs.s4.zWatermarks.ui; /* FIXME: in DRM */      /* set up z-buffer control register (global)       * set up z-buffer offset register (global) @@ -513,14 +520,20 @@ static void savageDDDepthFunc_s4(GLcontext *ctx, GLenum func)  	imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites = GL_FALSE;  	imesa->regs.s4.zWatermarks.ni.wLow        = 8;      } -   -    imesa->dirty |= SAVAGE_UPLOAD_CTX; + +    if (drawLocalCtrl != imesa->regs.s4.drawLocalCtrl.ui) +	imesa->dirty |= SAVAGE_UPLOAD_LOCAL; +    if (zBufCtrl != imesa->regs.s4.zBufCtrl.ui || +	zWatermarks != imesa->regs.s4.zWatermarks.ui) +	imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;  }  static void savageDDDepthFunc_s3d(GLcontext *ctx, GLenum func)  {      savageContextPtr imesa = SAVAGE_CONTEXT(ctx);      ZCmpFunc zmode; -#define depthIndex 0 +    u_int32_t drawCtrl = imesa->regs.s3d.drawCtrl.ui; +    u_int32_t zBufCtrl = imesa->regs.s3d.zBufCtrl.ui; +    u_int32_t zWatermarks = imesa->regs.s3d.zWatermarks.ui; /* FIXME: in DRM */      /* set up z-buffer control register (global)       * set up z-buffer offset register (global) @@ -565,14 +578,18 @@ static void savageDDDepthFunc_s3d(GLcontext *ctx, GLenum func)  	imesa->regs.s3d.zWatermarks.ni.wLow = 8;      } -    imesa->dirty |= SAVAGE_UPLOAD_CTX; +    if (drawCtrl != imesa->regs.s3d.drawCtrl.ui || +	zBufCtrl != imesa->regs.s3d.zBufCtrl.ui) +	imesa->dirty |= SAVAGE_UPLOAD_LOCAL; +    if (zWatermarks != imesa->regs.s3d.zWatermarks.ui) +	imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;  }  static void savageDDDepthMask_s4(GLcontext *ctx, GLboolean flag)  {      savageContextPtr imesa = SAVAGE_CONTEXT(ctx); +    u_int32_t drawLocalCtrl = imesa->regs.s4.drawLocalCtrl.ui; -    imesa->dirty |= SAVAGE_UPLOAD_CTX;      if (flag)      {  	imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites = GL_TRUE; @@ -582,12 +599,15 @@ static void savageDDDepthMask_s4(GLcontext *ctx, GLboolean flag)  	imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites = GL_FALSE;      }      savageDDDepthFunc_s4(ctx,ctx->Depth.Func); + +    if (drawLocalCtrl != imesa->regs.s4.drawLocalCtrl.ui) +	imesa->dirty |= SAVAGE_UPLOAD_LOCAL;  }  static void savageDDDepthMask_s3d(GLcontext *ctx, GLboolean flag)  {      savageContextPtr imesa = SAVAGE_CONTEXT(ctx); +    u_int32_t drawCtrl = imesa->regs.s3d.drawCtrl.ui; -    imesa->dirty |= SAVAGE_UPLOAD_CTX;      if (flag)      {  	imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_TRUE; @@ -597,6 +617,9 @@ static void savageDDDepthMask_s3d(GLcontext *ctx, GLboolean flag)  	imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_FALSE;      }      savageDDDepthFunc_s3d(ctx,ctx->Depth.Func); + +    if (drawCtrl != imesa->regs.s3d.drawCtrl.ui) +	imesa->dirty |= SAVAGE_UPLOAD_LOCAL;  } @@ -629,6 +652,7 @@ static void savageDDScissor( GLcontext *ctx, GLint x, GLint y,  static void savageDDDrawBuffer(GLcontext *ctx, GLenum mode )  {      savageContextPtr imesa = SAVAGE_CONTEXT(ctx); +    u_int32_t destCtrl = imesa->regs.s4.destCtrl.ui;      /*       * _DrawDestMask is easier to cope with than <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 2cbdb81de5..b1b402a184 100644 --- a/src/mesa/drivers/dri/savage/savagestate.h +++ b/src/mesa/drivers/dri/savage/savagestate.h @@ -28,43 +28,13 @@  #include "savagecontext.h" +void savageEmitOldState( savageContextPtr imesa ); +void savageEmitChangedState( savageContextPtr imesa ); +  extern void savageDDUpdateHwState( GLcontext *ctx );  extern void savageDDInitState( savageContextPtr imesa );  extern void savageDDInitStateFuncs( GLcontext *ctx );  extern void savageDDRenderStart(GLcontext *ctx);  extern void savageDDRenderEnd(GLcontext *ctx); -/*frank 2001/11/13 add macro for sarea state copy*/ -#if 0 -#define SAVAGE_STATE_COPY(ctx) { \ -ctx->sarea->setup[0]=ctx->Registers.DrawLocalCtrl.ui; \ -ctx->sarea->setup[1]=ctx->Registers.TexPalAddr.ui; \ -ctx->sarea->setup[2]=ctx->Registers.TexCtrl[0].ui; \ -ctx->sarea->setup[3]=ctx->Registers.TexCtrl[1].ui; \ -ctx->sarea->setup[4]=ctx->Registers.TexAddr[0].ui; \ -ctx->sarea->setup[5]=ctx->Registers.TexAddr[1].ui; \ -ctx->sarea->setup[6]=ctx->Registers.TexBlendCtrl[0].ui; \ -ctx->sarea->setup[7]=ctx->Registers.TexBlendCtrl[1].ui; \ -ctx->sarea->setup[8]=ctx->Registers.TexXprClr.ui; \ -ctx->sarea->setup[9]=ctx->Registers.TexDescr.ui; \ -ctx->sarea->setup[10]=ctx->Registers.FogTable.ni.ulEntry[0]; \ -ctx->sarea->setup[11]=ctx->Registers.FogTable.ni.ulEntry[1]; \ -ctx->sarea->setup[12]=ctx->Registers.FogTable.ni.ulEntry[2]; \ -ctx->sarea->setup[13]=ctx->Registers.FogTable.ni.ulEntry[3]; \ -ctx->sarea->setup[14]=ctx->Registers.FogTable.ni.ulEntry[4]; \ -ctx->sarea->setup[15]=ctx->Registers.FogTable.ni.ulEntry[5]; \ -ctx->sarea->setup[16]=ctx->Registers.FogTable.ni.ulEntry[6]; \ -ctx->sarea->setup[17]=ctx->Registers.FogTable.ni.ulEntry[7]; \ -ctx->sarea->setup[18]=ctx->Registers.FogCtrl.ui; \ -ctx->sarea->setup[19]=ctx->Registers.StencilCtrl.ui; \ -ctx->sarea->setup[20]=ctx->Registers.ZBufCtrl.ui; \ -ctx->sarea->setup[21]=ctx->Registers.ZBufOffset.ui; \ -ctx->sarea->setup[22]=ctx->Registers.DestCtrl.ui; \ -ctx->sarea->setup[23]=ctx->Registers.DrawCtrl0.ui; \ -ctx->sarea->setup[24]=ctx->Registers.DrawCtrl1.ui; \ -ctx->sarea->setup[25]=ctx->Registers.ZWatermarks.ui; \ -ctx->sarea->setup[26]=ctx->Registers.DestTexWatermarks.ui; \ -ctx->sarea->setup[27]=ctx->Registers.TexBlendColor.ui; \ -} -#endif  #endif diff --git a/src/mesa/drivers/dri/savage/savagetex.c b/src/mesa/drivers/dri/savage/savagetex.c index c6143baabd..924f06187b 100644 --- a/src/mesa/drivers/dri/savage/savagetex.c +++ b/src/mesa/drivers/dri/savage/savagetex.c @@ -606,7 +606,7 @@ void savagePrintGlobalLRU( savageContextPtr imesa , GLuint heap)  {     int i, j; -   drm_savage_tex_region_t *list = imesa->sarea->texList[heap]; +   drm_tex_region_t *list = imesa->sarea->texList[heap];     for (i = 0, j = SAVAGE_NR_TEX_REGIONS ; i < SAVAGE_NR_TEX_REGIONS ; i++) { @@ -628,7 +628,7 @@ void savagePrintGlobalLRU( savageContextPtr imesa , GLuint heap)  void savageResetGlobalLRU( savageContextPtr imesa, GLuint heap )  { -    drm_savage_tex_region_t *list = imesa->sarea->texList[heap]; +    drm_tex_region_t *list = imesa->sarea->texList[heap];     int sz = 1 << imesa->savageScreen->logTextureGranularity[heap];     int i; @@ -661,7 +661,7 @@ static void savageUpdateTexLRU( savageContextPtr imesa, savageTextureObjectPtr t     int logsz = imesa->savageScreen->logTextureGranularity[heap];     int start = t->MemBlock->ofs >> logsz;     int end = (t->MemBlock->ofs + t->MemBlock->size - 1) >> logsz; -   drm_savage_tex_region_t *list = imesa->sarea->texList[heap]; +   drm_tex_region_t *list = imesa->sarea->texList[heap];     imesa->texAge[heap] = ++imesa->sarea->texAge[heap]; @@ -787,16 +787,19 @@ int savageUploadTexImages( savageContextPtr imesa, savageTextureObjectPtr t )        ofs = t->MemBlock->ofs;        t->texParams.hwPhysAddress = imesa->savageScreen->textureOffset[heap] + ofs;        t->BufAddr = (char *)((GLuint) imesa->savageScreen->texVirtual[heap] + ofs); -      imesa->dirty |= SAVAGE_UPLOAD_CTX; +      imesa->dirty |= SAVAGE_UPLOAD_GLOBAL; /* FIXME: really needed? */     }     /* Let the world know we've used this memory recently.      */ +   LOCK_HARDWARE(imesa);     savageUpdateTexLRU( imesa, t ); +   UNLOCK_HARDWARE(imesa);     if (t->dirty_images) { +      savageFlushVertices (imesa);        LOCK_HARDWARE(imesa); -      savageFlushVerticesLocked (imesa); +      savageFlushCmdBufLocked (imesa, GL_FALSE);        savageDmaFinish (imesa);        if (SAVAGE_DEBUG & DEBUG_VERBOSE_LRU)  	 fprintf(stderr, "*"); @@ -1436,8 +1439,7 @@ static void savageUpdateTextureState_s4( GLcontext *ctx )     imesa->CurrentTexObj[1] = 0;        savageUpdateTex0State_s4( ctx );     savageUpdateTex1State_s4( ctx ); -   imesa->dirty |= (SAVAGE_UPLOAD_CTX | -		    SAVAGE_UPLOAD_TEX0 |  +   imesa->dirty |= (SAVAGE_UPLOAD_TEX0 |   		    SAVAGE_UPLOAD_TEX1);  }  static void savageUpdateTextureState_s3d( GLcontext *ctx ) @@ -1446,8 +1448,7 @@ static void savageUpdateTextureState_s3d( GLcontext *ctx )      if (imesa->CurrentTexObj[0]) imesa->CurrentTexObj[0]->bound &= ~1;      imesa->CurrentTexObj[0] = 0;      savageUpdateTexState_s3d( ctx ); -    imesa->dirty |= (SAVAGE_UPLOAD_CTX | -		     SAVAGE_UPLOAD_TEX0); +    imesa->dirty |= (SAVAGE_UPLOAD_TEX0);  }  void savageUpdateTextureState( GLcontext *ctx)  { diff --git a/src/mesa/drivers/dri/savage/savagetris.c b/src/mesa/drivers/dri/savage/savagetris.c index 69633ecae7..1732dc5074 100644 --- a/src/mesa/drivers/dri/savage/savagetris.c +++ b/src/mesa/drivers/dri/savage/savagetris.c @@ -100,7 +100,7 @@ static void __inline__ savage_draw_triangle (savageContextPtr imesa,  					     savageVertexPtr v1,  					     savageVertexPtr v2) {     GLuint vertsize = imesa->HwVertexSize; -   u_int32_t *vb = savageAllocDmaLow (imesa, 3*4*vertsize); +   u_int32_t *vb = savageAllocVtxBuf (imesa, 3*vertsize);     GLuint j;     EMIT_VERT (j, vb, vertsize, 0, v0); @@ -114,7 +114,7 @@ static void __inline__ savage_draw_quad (savageContextPtr imesa,  					 savageVertexPtr v2,  					 savageVertexPtr v3) {     GLuint vertsize = imesa->HwVertexSize; -   u_int32_t *vb = savageAllocDmaLow (imesa, 6*4*vertsize); +   u_int32_t *vb = savageAllocVtxBuf (imesa, 6*vertsize);     GLuint j;     EMIT_VERT (j, vb, vertsize, 0, v0); @@ -128,7 +128,7 @@ static void __inline__ savage_draw_quad (savageContextPtr imesa,  static __inline__ void savage_draw_point (savageContextPtr imesa,  					  savageVertexPtr tmp) {     GLuint vertsize = imesa->HwVertexSize; -   u_int32_t *vb = savageAllocDmaLow (imesa, 6*4*vertsize); +   u_int32_t *vb = savageAllocVtxBuf (imesa, 6*vertsize);     const GLfloat x = tmp->v.x;     const GLfloat y = tmp->v.y;     const GLfloat sz = imesa->glCtx->Point._Size * .5; @@ -163,7 +163,7 @@ static __inline__ void savage_draw_line (savageContextPtr imesa,  					 savageVertexPtr v0,  					 savageVertexPtr v1 ) {     GLuint vertsize = imesa->HwVertexSize; -   u_int32_t *vb = savageAllocDmaLow (imesa, 6*4*vertsize); +   u_int32_t *vb = savageAllocVtxBuf (imesa, 6*vertsize);     GLfloat width = imesa->glCtx->Line._Width;     GLfloat dx, dy, ix, iy;     GLuint j; @@ -220,7 +220,7 @@ static void __inline__ savage_ptex_tri (savageContextPtr imesa,  					savageVertexPtr v1,  					savageVertexPtr v2) {     GLuint vertsize = imesa->HwVertexSize; -   u_int32_t *vb = savageAllocDmaLow (imesa, 3*4*vertsize); +   u_int32_t *vb = savageAllocVtxBuf (imesa, 3*vertsize);     savageVertex tmp;     GLuint j; @@ -233,7 +233,7 @@ static __inline__ void savage_ptex_line (savageContextPtr imesa,  					 savageVertexPtr v0,  					 savageVertexPtr v1 ) {     GLuint vertsize = imesa->HwVertexSize; -   u_int32_t *vb = savageAllocDmaLow (imesa, 6*4*vertsize); +   u_int32_t *vb = savageAllocVtxBuf (imesa, 6*vertsize);     GLfloat width = imesa->glCtx->Line._Width;     GLfloat dx, dy, ix, iy;     savageVertex tmp0, tmp1; @@ -278,7 +278,7 @@ static __inline__ void savage_ptex_line (savageContextPtr imesa,  static __inline__ void savage_ptex_point (savageContextPtr imesa,  					  savageVertexPtr v0) {     GLuint vertsize = imesa->HwVertexSize; -   u_int32_t *vb = savageAllocDmaLow (imesa, 6*4*vertsize); +   u_int32_t *vb = savageAllocVtxBuf (imesa, 6*vertsize);     const GLfloat x = v0->v.x;     const GLfloat y = v0->v.y;     const GLfloat sz = imesa->glCtx->Point._Size * .5; @@ -428,9 +428,9 @@ do {								\     savageContextPtr imesa = SAVAGE_CONTEXT(ctx);		\     GLuint color[n], spec[n];					\     GLuint coloroffset =						\ -      ((imesa->DrawPrimitiveCmd & SAVAGE_HW_NO_W) ? 3 : 4);	\ +      ((imesa->skip & SAVAGE_SKIP_W) ? 3 : 4);			\     GLboolean specoffset =					\ -      ((imesa->DrawPrimitiveCmd & SAVAGE_HW_NO_CS) ? 0 : coloroffset+1);\ +      ((imesa->skip & SAVAGE_SKIP_C1) ? 0 : coloroffset+1);	\     (void) color; (void) spec; (void) coloroffset; (void) specoffset;  /*********************************************************************** @@ -756,6 +756,16 @@ static void savageChooseRenderState(GLcontext *ctx)        imesa->RenderIndex = index;     } + +   if (imesa->savageScreen->chipset < S3_SAVAGE4 && (flags & DD_FLATSHADE)) { +      if (imesa->HwPrim != SAVAGE_PRIM_TRILIST_201) +	 savageFlushVertices(imesa); +      imesa->HwPrim = SAVAGE_PRIM_TRILIST_201; +   } else { +      if (imesa->HwPrim != SAVAGE_PRIM_TRILIST) +	 savageFlushVertices(imesa); +      imesa->HwPrim = SAVAGE_PRIM_TRILIST; +   }  }  /**********************************************************************/ @@ -766,6 +776,9 @@ static void savageRunPipeline( GLcontext *ctx )  {     savageContextPtr imesa = SAVAGE_CONTEXT(ctx); +   if (imesa->no_rast) +      FALLBACK(ctx, SAVAGE_FALLBACK_NORAST, GL_TRUE); +     if (imesa->new_state)        savageDDUpdateHwState( ctx ); @@ -777,6 +790,9 @@ static void savageRunPipeline( GLcontext *ctx )     }     _tnl_run_pipeline( ctx ); + +   if (imesa->no_rast) +      FALLBACK(ctx, SAVAGE_FALLBACK_NORAST, GL_FALSE);  }  /**********************************************************************/ @@ -858,7 +874,7 @@ do {									\     imesa->vertex_attrs[imesa->vertex_attr_count].format = (STYLE);	\     imesa->vertex_attr_count++;						\     setupIndex |= (INDEX);						\ -   drawCmd &= ~(SKIP);							\ +   skip &= ~(SKIP);							\  } while (0)  #define EMIT_PAD( N )							\ @@ -891,11 +907,8 @@ static void savageRenderStart( GLcontext *ctx )     struct vertex_buffer *VB = &tnl->vb;     GLuint index = tnl->render_inputs;     GLuint setupIndex = SAVAGE_EMIT_XYZ; -   GLuint drawCmd = SAVAGE_HW_SKIPFLAGS; +   GLubyte skip;     GLboolean ptexHack; -   if (imesa->savageScreen->chipset < S3_SAVAGE4) -      drawCmd &= ~SAVAGE_HW_NO_UV1; -   drawCmd &= ~SAVAGE_HW_NO_Z; /* all mesa vertices have a z coordinate */     /* Check if we need to apply the ptex hack. Choose a new render      * state if necessary. (Note: this can't be done in @@ -917,66 +930,115 @@ static void savageRenderStart( GLcontext *ctx )     VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;     imesa->vertex_attr_count = 0; -   /* EMIT_ATTR's must be in order as they tell t_vertex.c how to -    * build up a hardware vertex. -    */ -   if ((index & _TNL_BITS_TEX_ANY) || !(ctx->_TriangleCaps & DD_FLATSHADE)) { -      EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, SAVAGE_EMIT_W, SAVAGE_HW_NO_W ); -   } -   else { -      EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, 0, 0 ); -   } +   if (imesa->savageScreen->chipset < S3_SAVAGE4) { +      skip = SAVAGE_SKIP_ALL_S3D; +      skip &= ~SAVAGE_SKIP_Z; /* all mesa vertices have a z coordinate */ -   /* t_context.c always includes a diffuse color */ -   EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, SAVAGE_EMIT_C0, SAVAGE_HW_NO_CD ); +      /* EMIT_ATTR's must be in order as they tell t_vertex.c how to +       * build up a hardware vertex. +       */ +      if ((index & _TNL_BITS_TEX_ANY) || !(ctx->_TriangleCaps & DD_FLATSHADE)) { +	 EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, SAVAGE_EMIT_W, SAVAGE_SKIP_W ); +      } +      else { +	 EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, 0, 0 ); +	 EMIT_PAD( 4 ); +	 skip &= ~SAVAGE_SKIP_W; +      } + +      /* t_context.c always includes a diffuse color */ +      EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, SAVAGE_EMIT_C0, SAVAGE_SKIP_C0 ); -   if (index & (_TNL_BIT_COLOR1|_TNL_BIT_FOG)) {        if ((index & _TNL_BIT_COLOR1)) -	 EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, SAVAGE_EMIT_C1, SAVAGE_HW_NO_CS ); +	 EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, SAVAGE_EMIT_C1, SAVAGE_SKIP_C1 );        else  	 EMIT_PAD( 3 );        if ((index & _TNL_BIT_FOG)) -	 EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, SAVAGE_EMIT_FOG, SAVAGE_HW_NO_CS ); +	 EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, SAVAGE_EMIT_FOG, SAVAGE_SKIP_C1 );        else  	 EMIT_PAD( 1 ); -   } +      skip &= ~SAVAGE_SKIP_C1; -   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 ); +      if (index & _TNL_BIT_TEX(0)) { +	 if (ptexHack) +	    EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_3F_XYW, SAVAGE_EMIT_STQ0, SAVAGE_SKIP_ST0); +	 else if (VB->TexCoordPtr[0]->size == 4) +	    assert (0); /* should be caught by savageCheckPTexHack */ +	 else if (VB->TexCoordPtr[0]->size >= 2) +	    /* The chromium menu emits some 3D tex coords even though no +	     * 3D texture is enabled. Ignore the 3rd coordinate. */ +	    EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_2F, SAVAGE_EMIT_ST0, SAVAGE_SKIP_ST0 ); +	 else if (VB->TexCoordPtr[0]->size == 1) { +	    EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_1F, SAVAGE_EMIT_S0, SAVAGE_SKIP_S0 ); +	    EMIT_PAD( 4 ); +	 } else +	    EMIT_PAD( 8 ); +      } else +	 EMIT_PAD( 8 ); +      skip &= ~SAVAGE_SKIP_ST0; +   } else { +      skip = SAVAGE_SKIP_ALL_S4; +      skip &= ~SAVAGE_SKIP_Z; /* all mesa vertices have a z coordinate */ + +      /* EMIT_ATTR's must be in order as they tell t_vertex.c how to +       * build up a hardware vertex. +       */ +      if ((index & _TNL_BITS_TEX_ANY) || !(ctx->_TriangleCaps & DD_FLATSHADE)) +	 EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, SAVAGE_EMIT_W, SAVAGE_SKIP_W );        else -	 EMIT_ATTR( _TNL_ATTRIB_TEX1, EMIT_1F, SAVAGE_EMIT_S1, SAVAGE_HW_NO_U1 ); +	 EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, 0, 0 ); + +      /* t_context.c always includes a diffuse color */ +      EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, SAVAGE_EMIT_C0, SAVAGE_SKIP_C0 ); +       +      if (index & (_TNL_BIT_COLOR1|_TNL_BIT_FOG)) { +	 if ((index & _TNL_BIT_COLOR1)) +	    EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, SAVAGE_EMIT_C1, SAVAGE_SKIP_C1 ); +	 else +	    EMIT_PAD( 3 ); +	 if ((index & _TNL_BIT_FOG)) +	    EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, SAVAGE_EMIT_FOG, SAVAGE_SKIP_C1 ); +	 else +	    EMIT_PAD( 1 ); +      } + +      if (index & _TNL_BIT_TEX(0)) { +	 if (ptexHack) +	    EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_3F_XYW, SAVAGE_EMIT_STQ0, SAVAGE_SKIP_ST0); +	 else if (VB->TexCoordPtr[0]->size == 4) +	    assert (0); /* should be caught by savageCheckPTexHack */ +	 else if (VB->TexCoordPtr[0]->size >= 2) +	    /* The chromium menu emits some 3D tex coords even though no +	     * 3D texture is enabled. Ignore the 3rd coordinate. */ +	    EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_2F, SAVAGE_EMIT_ST0, SAVAGE_SKIP_ST0 ); +	 else +	    EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_1F, SAVAGE_EMIT_S0, SAVAGE_SKIP_S0 ); +      } +      if (index & _TNL_BIT_TEX(1)) { +	 if (VB->TexCoordPtr[1]->size == 4) +	    /* projective textures are not supported by the hardware */ +	    assert (0); /* should be caught by savageCheckPTexHack */ +	 else if (VB->TexCoordPtr[1]->size >= 2) +	    EMIT_ATTR( _TNL_ATTRIB_TEX1, EMIT_2F, SAVAGE_EMIT_ST1, SAVAGE_SKIP_ST1 ); +	 else +	    EMIT_ATTR( _TNL_ATTRIB_TEX1, EMIT_1F, SAVAGE_EMIT_S1, SAVAGE_SKIP_S1 ); +      }     }     /* Need to change the vertex emit code if the SetupIndex changed or      * is set for the first time (indicated by vertex_size == 0). */     if (setupIndex != imesa->SetupIndex || imesa->vertex_size == 0) { -      imesa->vertex_size =  +      GLuint hwVertexSize; +      imesa->vertex_size =  	 _tnl_install_attrs( ctx,   			     imesa->vertex_attrs,   			     imesa->vertex_attr_count,  			     imesa->hw_viewport, 0 );        imesa->vertex_size >>= 2;        imesa->SetupIndex = setupIndex; +      imesa->skip = skip; -      imesa->DrawPrimitiveCmd = drawCmd; -      imesa->HwVertexSize = imesa->vertex_size; - +      hwVertexSize = imesa->vertex_size;        if (setupIndex & SAVAGE_EMIT_Q0) {  	 /* The vertex setup code emits homogenous texture  	  * coordinates. They are converted to normal 2D coords by @@ -984,10 +1046,28 @@ static void savageRenderStart( GLcontext *ctx )  	  * vertex sizes. Functions that emit vertices to the hardware  	  * need to use HwVertexSize, anything that manipulates the  	  * vertices generated by t_vertex uses vertex_size. */ -	 imesa->HwVertexSize--; +	 hwVertexSize--;  	 assert (imesa->ptexHack);        } else  	 assert (!imesa->ptexHack); + +      if (hwVertexSize != imesa->HwVertexSize) { +	 /* Changing the vertex size: flush vertex and command buffer and +	  * discard the DMA buffer, if we were using one. */ +	 savageFlushVertices(imesa); +	 savageFlushCmdBuf(imesa, GL_TRUE); +	 if (hwVertexSize == 8) { +	    if (SAVAGE_DEBUG & DEBUG_DMA) +	       fprintf (stderr, "Using DMA, skip=0x%02x\n", skip); +	    /* we can use vertex dma */ +	    imesa->vtxBuf = &imesa->dmaVtxBuf; +	 } else { +	    if (SAVAGE_DEBUG & DEBUG_DMA) +	       fprintf (stderr, "Not using DMA, skip=0x%02x\n", skip); +	    imesa->vtxBuf = &imesa->clientVtxBuf; +	 } +	 imesa->HwVertexSize = hwVertexSize; +      }     }     /* Update hardware state and get the lock */ diff --git a/src/mesa/drivers/dri/savage/server/savage_dri.h b/src/mesa/drivers/dri/savage/server/savage_dri.h index af62e761c4..39b6564fc3 100644 --- a/src/mesa/drivers/dri/savage/server/savage_dri.h +++ b/src/mesa/drivers/dri/savage/server/savage_dri.h @@ -29,6 +29,11 @@  #include "xf86drm.h"  #include "drm.h" +/* Totals 2 Mbytes which equals 2^16 32-byte vertices divided among up + * to 32 clients. */ +#define SAVAGE_NUM_BUFFERS 32 +#define SAVAGE_BUFFER_SIZE (1 << 16) /* 64k */ +  #define SAVAGE_DEFAULT_AGP_MODE     1  #define SAVAGE_MAX_AGP_MODE         4 @@ -68,14 +73,17 @@ typedef struct _server{     unsigned int frontOffset;     unsigned int frontPitch;     unsigned int frontbufferSize; +   unsigned int frontBitmapDesc;     unsigned int backOffset;     unsigned int backPitch;     unsigned int backbufferSize; +   unsigned int backBitmapDesc;     unsigned int depthOffset;     unsigned int depthPitch;     unsigned int depthbufferSize; +   unsigned int depthBitmapDesc;     unsigned int textureOffset;     int textureSize; @@ -89,12 +97,7 @@ typedef struct _server{     drmRegion status;     /* AGP mappings */ -#if 0 -   drmRegion warp; -   drmRegion primary;     drmRegion buffers; -#endif -     drmRegion agpTextures;     int logAgpTextureGranularity; @@ -114,71 +117,41 @@ typedef struct {     int cpp;     int zpp; -   int agpMode; +   int agpMode; /* 0 for PCI cards */ + +   unsigned int sarea_priv_offset; + +   unsigned int bufferSize; /* size of DMA buffers */ -   drm_handle_t frontbuffer;     unsigned int frontbufferSize;     unsigned int frontOffset; -   unsigned int frontPitch; -   unsigned int frontBitmapDesc;   /*Bitmap Descriptior*/  -   unsigned int IsfrontTiled; -   drm_handle_t backbuffer;     unsigned int backbufferSize;     unsigned int backOffset; -   unsigned int backPitch; -   unsigned int backBitmapDesc;   /*Bitmap Descriptior*/ -   drm_handle_t depthbuffer;     unsigned int depthbufferSize;     unsigned int depthOffset; -   unsigned int depthPitch; -   unsigned int depthBitmapDesc;   /*Bitmap Descriptior*/ - - -   drm_handle_t textures; -   drm_handle_t xvmcSurfHandle;     unsigned int textureOffset;     unsigned int textureSize;     int logTextureGranularity; -   /* Allow calculation of setup dma addresses. -    */ -   unsigned int agpBufferOffset; - -   unsigned int agpTextureOffset; -   unsigned int agpTextureSize; -   drmRegion agpTextures; -   int logAgpTextureGranularity; - -/*   unsigned int mAccess;*/ - -   drmRegion aperture; +   /* Linear aperture */ +   drm_handle_t apertureHandle; +   unsigned int apertureSize;     unsigned int aperturePitch;    /* in byte */ +   /* Status page (probably not needed, but no harm, read-only) */ +   drm_handle_t statusHandle; +   unsigned int statusSize; -   drmRegion registers; -   drmRegion BCIcmdBuf; -   drmRegion status; - -#if 0 -   drmRegion primary; -   drmRegion buffers; -#endif -  /*For shadow status*/ -  unsigned long sareaPhysAddr; +   /* AGP textures */ +   drm_handle_t agpTextureHandle; +   unsigned int agpTextureSize; +   int logAgpTextureGranularity; -   unsigned int sarea_priv_offset; -  int shadowStatus; +   /* Not sure about this one */ +   drm_handle_t xvmcSurfHandle; /* ? */  } SAVAGEDRIRec, *SAVAGEDRIPtr;  #endif - - - - - - - -  | 
