savagetex.c \
savagetris.c \
savageioctl.c \
- savagespan.c \
- savagedma.c
+ savagespan.c
C_SOURCES = \
$(COMMON_SOURCES) \
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
{
#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
} savageRegion, *savageRegionPtr;
typedef struct {
- savageRegion front;
- savageRegion back;
- savageRegion depth;
- savageRegion aperture;
-
int chipset;
int width;
int height;
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;
#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 );
#include "savage_dri.h"
-#include "savagedma.h"
-
#include "xmlpool.h"
/* Configuration
{ "fall", DEBUG_FALLBACKS },
{ "api", DEBUG_VERBOSE_API },
{ "lru", DEBUG_VERBOSE_LRU },
+ { "verb", DEBUG_VERBOSE_MSG },
+ { "dma", DEBUG_DMA },
{ NULL, 0 }
};
#ifndef SAVAGE_DEBUG
savageScreenPrivate *savageScreen;
SAVAGEDRIPtr gDRIPriv = (SAVAGEDRIPtr)sPriv->pDevPriv;
-
/* Allocate the private area */
savageScreen = (savageScreenPrivate *)Xmalloc(sizeof(savageScreenPrivate));
if (!savageScreen)
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] =
gDRIPriv->logTextureGranularity;
savageScreen->textureOffset[SAVAGE_AGP_HEAP] =
- gDRIPriv->agpTextures.handle;
+ gDRIPriv->agpTextureHandle;
savageScreen->textureSize[SAVAGE_AGP_HEAP] =
- gDRIPriv->agpTextures.size;
+ gDRIPriv->agpTextureSize;
savageScreen->logTextureGranularity[SAVAGE_AGP_HEAP] =
gDRIPriv->logAgpTextureGranularity;
-
- savageScreen->back.handle = gDRIPriv->backbuffer;
- savageScreen->back.size = gDRIPriv->backbufferSize;
- savageScreen->back.map =
- (drmAddress)(((unsigned int)sPriv->pFB)+gDRIPriv->backOffset);
-
- savageScreen->depth.handle = gDRIPriv->depthbuffer;
- savageScreen->depth.size = gDRIPriv->depthbufferSize;
-
- savageScreen->depth.map =
- (drmAddress)(((unsigned int)sPriv->pFB)+gDRIPriv->depthOffset);
-
- savageScreen->sarea_priv_offset = gDRIPriv->sarea_priv_offset;
- savageScreen->texVirtual[SAVAGE_CARD_HEAP] =
- (drmAddress)(((unsigned int)sPriv->pFB)+gDRIPriv->textureOffset);
-
- if (drmMap(sPriv->fd,
- gDRIPriv->registers.handle,
- gDRIPriv->registers.size,
- (drmAddress *)&(gDRIPriv->registers.map)) != 0)
- {
- Xfree(savageScreen);
- sPriv->private = NULL;
- return GL_FALSE;
- }
-
+ savageScreen->agpTextures.handle = gDRIPriv->agpTextureHandle;
+ savageScreen->agpTextures.size = gDRIPriv->agpTextureSize;
if (drmMap(sPriv->fd,
- gDRIPriv->agpTextures.handle,
- gDRIPriv->agpTextures.size,
- (drmAddress *)&(gDRIPriv->agpTextures.map)) != 0)
+ savageScreen->agpTextures.handle,
+ savageScreen->agpTextures.size,
+ (drmAddress *)&(savageScreen->agpTextures.map)) != 0)
{
Xfree(savageScreen);
sPriv->private = NULL;
return GL_FALSE;
}
-/* agp texture*/
+ savageScreen->texVirtual[SAVAGE_CARD_HEAP] =
+ (drmAddress)(((unsigned int)sPriv->pFB)+gDRIPriv->textureOffset);
savageScreen->texVirtual[SAVAGE_AGP_HEAP] =
- (drmAddress)(gDRIPriv->agpTextures.map);
-
- gDRIPriv->BCIcmdBuf.map = (drmAddress *)
- ((unsigned int)gDRIPriv->registers.map+0x00010000);
+ (drmAddress)(savageScreen->agpTextures.map);
- savageScreen->aperture.handle = gDRIPriv->aperture.handle;
- savageScreen->aperture.size = gDRIPriv->aperture.size;
+ savageScreen->aperture.handle = gDRIPriv->apertureHandle;
+ savageScreen->aperture.size = gDRIPriv->apertureSize;
+ savageScreen->aperturePitch = gDRIPriv->aperturePitch;
if (drmMap(sPriv->fd,
savageScreen->aperture.handle,
savageScreen->aperture.size,
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);
{
savageScreenPrivate *savageScreen = (savageScreenPrivate *)sPriv->private;
+ drmUnmapBufs(savageScreen->bufs);
+
/* free all option information */
driDestroyOptionInfo (&savageScreen->optionCache);
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);
}
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");
/* 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() */
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.
/* Utah stuff
*/
imesa->new_state = ~0;
+ imesa->new_gl_state = ~0;
imesa->RenderIndex = ~0;
imesa->dirty = ~0;
imesa->lostContext = GL_TRUE;
ctx->DriverCtx = (void *) imesa;
imesa->glCtx = ctx;
- if (savageDMAInit(imesa) == GL_FALSE)
- return GL_FALSE;
#ifndef SAVAGE_DEBUG
SAVAGE_DEBUG = driParseDebugString( getenv( "SAVAGE_DEBUG" ),
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;
}
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 );
* 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;
}
savageResetGlobalLRU( imesa , heap );
}
- imesa->dirty |= SAVAGE_UPLOAD_TEX0IMAGE;
- imesa->dirty |= SAVAGE_UPLOAD_TEX1IMAGE;
imesa->texAge[heap] = sarea->texAge[heap];
}
} /* end of for loop */
{
__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,
#include "tnl/t_vertex.h"
#include "savagetex.h"
-#include "savagedma.h"
#include "xmlconfig.h"
#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
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 {
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];
GLenum raster_primitive;
GLenum render_primitive;
- GLuint DrawPrimitiveCmd;
+ GLuint skip;
+ GLubyte HwPrim;
GLuint HwVertexSize;
/* Fallback rasterization functions
GLuint ClearColor;
GLfloat depth_scale;
GLfloat hw_viewport[16];
- /* DRI stuff */
- drmBufPtr vertex_dma_buffer;
+ /* DRI stuff */
+ GLuint bufferSize;
+ GLuint vertsPending;
GLframebuffer *glBuffer;
GLuint backup_streamFIFO;
GLuint NotFirstFrame;
+ GLboolean inSwap;
GLuint lastSwap;
- GLuint secondLastSwap;
GLuint ctxAge;
GLuint dirtyAge;
GLuint any_contend; /* throttle me harder */
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];
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))
#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
#include "savagecontext.h"
#include "extensions.h"
+#include "utils.h"
+
+
+#define DRIVER_DATE "20050101"
/***************************************
* Mesa's Driver Functions
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;
}
#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 */
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;
-}
int savageDMAInit (savageContextPtr imesa);
int savageDMAClose (savageContextPtr);
-/* faked implementation of vertex buffers */
-void savageFakeVertices (savageContextPtr imesa, drmBufPtr buffer);
-drmBufPtr savageFakeGetBuffer (savageContextPtr imesa);
-
#endif
#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);
imesa->regs.s4.zBufCtrl.ni.frameID =
~imesa->regs.s4.zBufCtrl.ni.frameID;
- imesa->dirty |= SAVAGE_UPLOAD_CTX;
+ imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
}
else
{
savageDMAFlush (imesa);
}
-struct timeb a,b;
-
static void savage_BCI_swap(savageContextPtr imesa)
{
int nbox = imesa->sarea->nbox;
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);
}
}
+#endif
+
+
+static GLboolean intersect_rect( drm_clip_rect_t *out,
+ const drm_clip_rect_t *a,
+ const drm_clip_rect_t *b )
+{
+ *out = *a;
+ if (b->x1 > out->x1) out->x1 = b->x1;
+ if (b->y1 > out->y1) out->y1 = b->y1;
+ if (b->x2 < out->x2) out->x2 = b->x2;
+ if (b->y2 < out->y2) out->y2 = b->y2;
+
+ return ((out->x1 < out->x2) && (out->y1 < out->y2));
+}
+
+
+static GLuint savageIntersectClipRects(drm_clip_rect_t *dest,
+ const drm_clip_rect_t *src,
+ GLuint nsrc,
+ const drm_clip_rect_t *clip)
+{
+ GLuint i, ndest;
+
+ for (i = 0, ndest = 0; i < nsrc; ++i, ++src) {
+ if (intersect_rect(dest, src, clip)) {
+ dest++;
+ ndest++;
+ }
+ }
+
+ return ndest;
+}
static void savageDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
GLint cx, GLint cy, GLint cw, GLint ch )
{
savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
- __DRIdrawablePrivate *dPriv = imesa->driDrawable;
- const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
- drm_savage_clear_t clear;
- int i;
+ GLuint colorMask, depthMask, clearColor, clearDepth, flags;
- clear.flags = 0;
- clear.clear_color = imesa->ClearColor;
+ if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG)
+ fprintf (stderr, "%s\n", __FUNCTION__);
+ clearColor = imesa->ClearColor;
if(imesa->savageScreen->zpp == 2)
- clear.clear_depth = (GLuint) (ctx->Depth.Clear * DEPTH_SCALE_16);
+ clearDepth = (GLuint) (ctx->Depth.Clear * DEPTH_SCALE_16);
else
- clear.clear_depth = (GLuint) (ctx->Depth.Clear * DEPTH_SCALE_24);
+ clearDepth = (GLuint) (ctx->Depth.Clear * DEPTH_SCALE_24);
- FLUSH_BATCH( imesa );
+ colorMask = *((GLuint *) &ctx->Color.ColorMask);
+ depthMask = 0;
- if ((mask & DD_FRONT_LEFT_BIT) && ((colorMask&0xffffffUL)==0xffffffUL) ){
- clear.flags |= SAVAGE_FRONT;
+ flags = 0;
+
+ if (mask & DD_FRONT_LEFT_BIT) {
+ flags |= SAVAGE_FRONT;
mask &= ~DD_FRONT_LEFT_BIT;
}
- if ((mask & DD_BACK_LEFT_BIT) && ((colorMask&0xffffffUL)==0xffffffUL) ) {
- clear.flags |= SAVAGE_BACK;
+ if (mask & DD_BACK_LEFT_BIT) {
+ flags |= SAVAGE_BACK;
mask &= ~DD_BACK_LEFT_BIT;
}
if ((mask & DD_DEPTH_BIT) && ctx->Depth.Mask) {
- clear.flags |= SAVAGE_DEPTH;
+ flags |= SAVAGE_DEPTH;
+ depthMask |=
+ (imesa->savageScreen->zpp == 2) ? 0xffffffff : 0x00ffffff;
mask &= ~DD_DEPTH_BIT;
}
if((mask & DD_STENCIL_BIT) && imesa->hw_stencil)
{
- clear.flags |= SAVAGE_STENCIL;
- mask &= ~DD_STENCIL_BIT;
+ flags |= SAVAGE_DEPTH;
+ depthMask |= 0xff000000;
+ mask &= ~DD_STENCIL_BIT;
}
- if (clear.flags) {
- LOCK_HARDWARE( imesa );
-
- /* flip top to bottom */
- cy = dPriv->h-cy-ch;
- cx += imesa->drawX;
- cy += imesa->drawY;
-
- for (i = 0 ; i < imesa->numClipRects ; ) {
- int nr = MIN2(i + SAVAGE_NR_SAREA_CLIPRECTS, imesa->numClipRects);
- drm_clip_rect_t *box = imesa->pClipRects;
- drm_clip_rect_t *b = imesa->sarea->boxes;
- int n = 0;
-
- if (!all) {
- for ( ; i < nr ; i++) {
- GLint x = box[i].x1;
- GLint y = box[i].y1;
- GLint w = box[i].x2 - x;
- GLint h = box[i].y2 - y;
-
- if (x < cx) w -= cx - x, x = cx;
- if (y < cy) h -= cy - y, y = cy;
- if (x + w > cx + cw) w = cx + cw - x;
- if (y + h > cy + ch) h = cy + ch - y;
- if (w <= 0) continue;
- if (h <= 0) continue;
-
- b->x1 = x;
- b->y1 = y;
- b->x2 = x + w;
- b->y2 = y + h;
- b++;
- n++;
- }
- } else {
- for ( ; i < nr ; i++) {
- *b++ = *(drm_clip_rect_t *)&box[i];
- n++;
- }
- }
-
- imesa->sarea->nbox = n;
-
- savage_BCI_clear(ctx,&clear);
+ savageFlushVertices(imesa);
+
+ if (flags) {
+ GLboolean depthCleared = GL_FALSE;
+ if (flags & (SAVAGE_FRONT|SAVAGE_BACK)) {
+ drm_savage_cmd_header_t *cmd;
+ cmd = savageAllocCmdBuf(imesa, sizeof(drm_savage_cmd_header_t));
+ cmd[0].clear0.cmd = SAVAGE_CMD_CLEAR;
+ if ((flags & SAVAGE_DEPTH) &&
+ clearDepth == clearColor && depthMask == colorMask) {
+ cmd[0].clear0.flags = flags;
+ depthCleared = GL_TRUE;
+ } else
+ cmd[0].clear0.flags = flags & (SAVAGE_FRONT|SAVAGE_BACK);
+ cmd[1].clear1.mask = colorMask;
+ cmd[1].clear1.value = clearColor;
+ }
+
+ if ((flags & SAVAGE_DEPTH) && !depthCleared) {
+ drm_savage_cmd_header_t *cmd;
+ cmd = savageAllocCmdBuf(imesa, sizeof(drm_savage_cmd_header_t));
+ cmd[0].clear0.cmd = SAVAGE_CMD_CLEAR;
+ cmd[0].clear0.flags = SAVAGE_DEPTH;
+ cmd[1].clear1.mask = depthMask;
+ cmd[1].clear1.value = clearDepth;
}
- UNLOCK_HARDWARE( imesa );
- imesa->dirty |= SAVAGE_UPLOAD_CLIPRECTS|SAVAGE_UPLOAD_CTX;
+ imesa->dirty |= SAVAGE_UPLOAD_CLIPRECTS;
}
if (mask)
}
-
+/* 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.
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);
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 ) );
}
}
+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
#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 );
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
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);
}
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)
/*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)
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,
{
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)
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)
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;
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;
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;
}
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>.
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;
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;
* 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 )
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 */
{
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,
{
imesa->regs.s3d.zBufCtrl.ni.drawUpdateEn = GL_FALSE;
}
- imesa->dirty |= SAVAGE_UPLOAD_CTX;
+ imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
/* TODO: need a software fallback */
}
*/
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) {
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) {
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,
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)
{
{
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)
{
{
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;
}
{
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)
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];
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])
{
break;
}
- imesa->dirty |= SAVAGE_UPLOAD_CTX;
+ if (stencilCtrl != imesa->regs.s4.stencilCtrl.ui)
+ imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
}
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.
*/
savageBlendFunc_s4(ctx);
break;
case GL_DEPTH_TEST:
- imesa->dirty |= SAVAGE_UPLOAD_CTX;
savageDDDepthFunc_s4(ctx,ctx->Depth.Func);
break;
case GL_SCISSOR_TEST:
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 {
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:
#endif
break;
case GL_DITHER:
- imesa->dirty |= SAVAGE_UPLOAD_CTX;
if (state)
{
if ( ctx->Color.DitherFlag )
{
imesa->regs.s4.drawCtrl1.ni.ditherEn=GL_FALSE;
}
+ imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
break;
case GL_LIGHTING:
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.
*/
savageBlendFunc_s3d(ctx);
break;
case GL_DEPTH_TEST:
- imesa->dirty |= SAVAGE_UPLOAD_CTX;
savageDDDepthFunc_s3d(ctx,ctx->Depth.Func);
break;
case GL_SCISSOR_TEST:
FALLBACK (ctx, SAVAGE_FALLBACK_STENCIL, state);
break;
case GL_FOG:
- imesa->dirty |= SAVAGE_UPLOAD_CTX;
savageDDFogfv(ctx,0,0);
break;
case GL_CULL_FACE:
#endif
break;
case GL_DITHER:
- imesa->dirty |= SAVAGE_UPLOAD_CTX;
if (state)
{
if ( ctx->Color.DitherFlag )
{
imesa->regs.s3d.drawCtrl.ni.ditherEn=GL_FALSE;
}
+ imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
break;
case GL_LIGHTING:
savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
if (imesa->new_state) {
- FLUSH_BATCH(imesa);
-
+ savageFlushVertices(imesa);
if (imesa->new_state & SAVAGE_NEW_TEXTURE) {
savageUpdateTextureState( ctx );
}
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, " : ""
);
}
}
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) {
}
static void savageUpdateRegister_s4(savageContextPtr imesa)
{
- u_int32_t *pBCIBase;
-
/*
* Scissors updates drawctrl0 and drawctrl 1
*/
/* 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)
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
}
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);
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;
}
#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
{
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++) {
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;
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];
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, "*");
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 )
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)
{
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);
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);
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;
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;
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;
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;
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;
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;
/***********************************************************************
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;
+ }
}
/**********************************************************************/
{
savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
+ if (imesa->no_rast)
+ FALLBACK(ctx, SAVAGE_FALLBACK_NORAST, GL_TRUE);
+
if (imesa->new_state)
savageDDUpdateHwState( ctx );
}
_tnl_run_pipeline( ctx );
+
+ if (imesa->no_rast)
+ FALLBACK(ctx, SAVAGE_FALLBACK_NORAST, GL_FALSE);
}
/**********************************************************************/
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 ) \
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
VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
imesa->vertex_attr_count = 0;
- /* EMIT_ATTR's must be in order as they tell t_vertex.c how to
- * build up a hardware vertex.
- */
- if ((index & _TNL_BITS_TEX_ANY) || !(ctx->_TriangleCaps & DD_FLATSHADE)) {
- EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, SAVAGE_EMIT_W, SAVAGE_HW_NO_W );
- }
- else {
- EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, 0, 0 );
- }
+ if (imesa->savageScreen->chipset < S3_SAVAGE4) {
+ skip = SAVAGE_SKIP_ALL_S3D;
+ skip &= ~SAVAGE_SKIP_Z; /* all mesa vertices have a z coordinate */
- /* t_context.c always includes a diffuse color */
- EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, SAVAGE_EMIT_C0, SAVAGE_HW_NO_CD );
+ /* EMIT_ATTR's must be in order as they tell t_vertex.c how to
+ * build up a hardware vertex.
+ */
+ if ((index & _TNL_BITS_TEX_ANY) || !(ctx->_TriangleCaps & DD_FLATSHADE)) {
+ EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, SAVAGE_EMIT_W, SAVAGE_SKIP_W );
+ }
+ else {
+ EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, 0, 0 );
+ EMIT_PAD( 4 );
+ skip &= ~SAVAGE_SKIP_W;
+ }
+
+ /* t_context.c always includes a diffuse color */
+ EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, SAVAGE_EMIT_C0, SAVAGE_SKIP_C0 );
- if (index & (_TNL_BIT_COLOR1|_TNL_BIT_FOG)) {
if ((index & _TNL_BIT_COLOR1))
- EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, SAVAGE_EMIT_C1, SAVAGE_HW_NO_CS );
+ EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, SAVAGE_EMIT_C1, SAVAGE_SKIP_C1 );
else
EMIT_PAD( 3 );
if ((index & _TNL_BIT_FOG))
- EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, SAVAGE_EMIT_FOG, SAVAGE_HW_NO_CS );
+ EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, SAVAGE_EMIT_FOG, SAVAGE_SKIP_C1 );
else
EMIT_PAD( 1 );
- }
-
- if (index & _TNL_BIT_TEX(0)) {
- if (ptexHack)
- EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_3F_XYW, SAVAGE_EMIT_STQ0, SAVAGE_HW_NO_UV0);
- else if (VB->TexCoordPtr[0]->size == 4)
- assert (0); /* should be caught by savageCheckPTexHack */
- else if (VB->TexCoordPtr[0]->size >= 2)
- /* The chromium menu emits some 3D tex coords even though no
- * 3D texture is enabled. Ignore the 3rd coordinate. */
- EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_2F, SAVAGE_EMIT_ST0, SAVAGE_HW_NO_UV0 );
- else
- EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_1F, SAVAGE_EMIT_S0, SAVAGE_HW_NO_U0 );
- }
- if (index & _TNL_BIT_TEX(1)) {
- if (VB->TexCoordPtr[1]->size == 4)
- /* Projective textures are not supported by the hardware */
- assert (0); /* should be caught by savageCheckPTexHack */
- else if (VB->TexCoordPtr[1]->size >= 2)
- EMIT_ATTR( _TNL_ATTRIB_TEX1, EMIT_2F, SAVAGE_EMIT_ST1, SAVAGE_HW_NO_UV1 );
+ skip &= ~SAVAGE_SKIP_C1;
+
+ if (index & _TNL_BIT_TEX(0)) {
+ if (ptexHack)
+ EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_3F_XYW, SAVAGE_EMIT_STQ0, SAVAGE_SKIP_ST0);
+ else if (VB->TexCoordPtr[0]->size == 4)
+ assert (0); /* should be caught by savageCheckPTexHack */
+ else if (VB->TexCoordPtr[0]->size >= 2)
+ /* The chromium menu emits some 3D tex coords even though no
+ * 3D texture is enabled. Ignore the 3rd coordinate. */
+ EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_2F, SAVAGE_EMIT_ST0, SAVAGE_SKIP_ST0 );
+ else if (VB->TexCoordPtr[0]->size == 1) {
+ EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_1F, SAVAGE_EMIT_S0, SAVAGE_SKIP_S0 );
+ EMIT_PAD( 4 );
+ } else
+ EMIT_PAD( 8 );
+ } else
+ EMIT_PAD( 8 );
+ skip &= ~SAVAGE_SKIP_ST0;
+ } else {
+ skip = SAVAGE_SKIP_ALL_S4;
+ skip &= ~SAVAGE_SKIP_Z; /* all mesa vertices have a z coordinate */
+
+ /* EMIT_ATTR's must be in order as they tell t_vertex.c how to
+ * build up a hardware vertex.
+ */
+ if ((index & _TNL_BITS_TEX_ANY) || !(ctx->_TriangleCaps & DD_FLATSHADE))
+ EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, SAVAGE_EMIT_W, SAVAGE_SKIP_W );
else
- EMIT_ATTR( _TNL_ATTRIB_TEX1, EMIT_1F, SAVAGE_EMIT_S1, SAVAGE_HW_NO_U1 );
+ EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, 0, 0 );
+
+ /* t_context.c always includes a diffuse color */
+ EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, SAVAGE_EMIT_C0, SAVAGE_SKIP_C0 );
+
+ if (index & (_TNL_BIT_COLOR1|_TNL_BIT_FOG)) {
+ if ((index & _TNL_BIT_COLOR1))
+ EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, SAVAGE_EMIT_C1, SAVAGE_SKIP_C1 );
+ else
+ EMIT_PAD( 3 );
+ if ((index & _TNL_BIT_FOG))
+ EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, SAVAGE_EMIT_FOG, SAVAGE_SKIP_C1 );
+ else
+ EMIT_PAD( 1 );
+ }
+
+ if (index & _TNL_BIT_TEX(0)) {
+ if (ptexHack)
+ EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_3F_XYW, SAVAGE_EMIT_STQ0, SAVAGE_SKIP_ST0);
+ else if (VB->TexCoordPtr[0]->size == 4)
+ assert (0); /* should be caught by savageCheckPTexHack */
+ else if (VB->TexCoordPtr[0]->size >= 2)
+ /* The chromium menu emits some 3D tex coords even though no
+ * 3D texture is enabled. Ignore the 3rd coordinate. */
+ EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_2F, SAVAGE_EMIT_ST0, SAVAGE_SKIP_ST0 );
+ else
+ EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_1F, SAVAGE_EMIT_S0, SAVAGE_SKIP_S0 );
+ }
+ if (index & _TNL_BIT_TEX(1)) {
+ if (VB->TexCoordPtr[1]->size == 4)
+ /* projective textures are not supported by the hardware */
+ assert (0); /* should be caught by savageCheckPTexHack */
+ else if (VB->TexCoordPtr[1]->size >= 2)
+ EMIT_ATTR( _TNL_ATTRIB_TEX1, EMIT_2F, SAVAGE_EMIT_ST1, SAVAGE_SKIP_ST1 );
+ else
+ EMIT_ATTR( _TNL_ATTRIB_TEX1, EMIT_1F, SAVAGE_EMIT_S1, SAVAGE_SKIP_S1 );
+ }
}
/* Need to change the vertex emit code if the SetupIndex changed or
* is set for the first time (indicated by vertex_size == 0). */
if (setupIndex != imesa->SetupIndex || imesa->vertex_size == 0) {
- imesa->vertex_size =
+ GLuint hwVertexSize;
+ imesa->vertex_size =
_tnl_install_attrs( ctx,
imesa->vertex_attrs,
imesa->vertex_attr_count,
imesa->hw_viewport, 0 );
imesa->vertex_size >>= 2;
imesa->SetupIndex = setupIndex;
+ imesa->skip = skip;
- imesa->DrawPrimitiveCmd = drawCmd;
- imesa->HwVertexSize = imesa->vertex_size;
-
+ hwVertexSize = imesa->vertex_size;
if (setupIndex & SAVAGE_EMIT_Q0) {
/* The vertex setup code emits homogenous texture
* coordinates. They are converted to normal 2D coords by
* 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 */
#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
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;
drmRegion status;
/* AGP mappings */
-#if 0
- drmRegion warp;
- drmRegion primary;
drmRegion buffers;
-#endif
-
drmRegion agpTextures;
int logAgpTextureGranularity;
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
-
-
-
-
-
-
-
-