From 490e764d7affc093feff80192ed3f3d4642fcb8f Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 29 Dec 2004 20:46:27 +0000 Subject: [PATCH] Simplfy clear() and swapbuffers() code. Fix various mishandling of cliprects. Allow multiple primitives to be emitted to a single dma buffer, which was largely impossible previously. Re-enable the fast unclipped render stage. --- src/mesa/drivers/dri/unichrome/via_context.c | 326 ++--- src/mesa/drivers/dri/unichrome/via_context.h | 24 +- src/mesa/drivers/dri/unichrome/via_fb.c | 131 +- src/mesa/drivers/dri/unichrome/via_fb.h | 16 +- src/mesa/drivers/dri/unichrome/via_ioctl.c | 1311 ++++++++---------- src/mesa/drivers/dri/unichrome/via_ioctl.h | 22 +- src/mesa/drivers/dri/unichrome/via_span.c | 103 +- src/mesa/drivers/dri/unichrome/via_state.c | 20 +- src/mesa/drivers/dri/unichrome/via_tris.c | 99 +- src/mesa/drivers/dri/unichrome/via_vb.c | 8 +- 10 files changed, 835 insertions(+), 1225 deletions(-) diff --git a/src/mesa/drivers/dri/unichrome/via_context.c b/src/mesa/drivers/dri/unichrome/via_context.c index 9879a88e57a..b6c2c37aedd 100644 --- a/src/mesa/drivers/dri/unichrome/via_context.c +++ b/src/mesa/drivers/dri/unichrome/via_context.c @@ -68,39 +68,7 @@ #ifdef DEBUG GLuint VIA_DEBUG = 0; #endif -#define DMA_SIZE 2 -/*=* John Sheng [2003.5.31] agp tex *=*/ - -static GLboolean -AllocateBuffer(viaContextPtr vmesa) -{ - vmesa->front_base = vmesa->driScreen->pFB; - if (vmesa->drawType == GLX_PBUFFER_BIT) { - if (vmesa->front.map) - via_free_front_buffer(vmesa); - if (!via_alloc_front_buffer(vmesa)) - return GL_FALSE; - } - - if (vmesa->hasBack) { - if (vmesa->back.map) - via_free_back_buffer(vmesa); - if (!via_alloc_back_buffer(vmesa)) - return GL_FALSE; - } - - if (vmesa->hasDepth || vmesa->hasStencil) { - if (vmesa->depth.map) - via_free_depth_buffer(vmesa); - if (!via_alloc_depth_buffer(vmesa)) { - via_free_depth_buffer(vmesa); - return GL_FALSE; - } - } - - return GL_TRUE; -} /** * Return various strings for \c glGetString. @@ -169,79 +137,92 @@ buffer_align( unsigned width ) static GLboolean calculate_buffer_parameters( viaContextPtr vmesa ) { - const unsigned shift = vmesa->viaScreen->bitsPerPixel / 16; - const unsigned extra = (vmesa->drawType == GLX_PBUFFER_BIT) ? 0 : 32; - unsigned w; - unsigned h; + const unsigned shift = vmesa->viaScreen->bitsPerPixel / 16; + const unsigned extra = 32; + unsigned w; + unsigned h; - if (vmesa->drawType == GLX_PBUFFER_BIT) { - w = vmesa->driDrawable->w; - h = vmesa->driDrawable->h; - } - else { - w = vmesa->viaScreen->width; - h = vmesa->viaScreen->height; + /* Allocate front-buffer */ + if (vmesa->drawType == GLX_PBUFFER_BIT) { + w = vmesa->driDrawable->w; + h = vmesa->driDrawable->h; - vmesa->front.offset = 0; - vmesa->front.map = (char *) vmesa->driScreen->pFB; - } + vmesa->front.bpp = vmesa->viaScreen->bitsPerPixel; + vmesa->front.pitch = buffer_align( w ) << shift; + vmesa->front.size = vmesa->front.pitch * h; - vmesa->front.pitch = buffer_align( w ) << shift; - vmesa->front.size = vmesa->front.pitch * h; + if (vmesa->front.map) + via_free_draw_buffer(vmesa, &vmesa->front); + if (!via_alloc_draw_buffer(vmesa, &vmesa->front)) + return GL_FALSE; + + } + else { + w = vmesa->viaScreen->width; + h = vmesa->viaScreen->height; + + vmesa->front.bpp = vmesa->viaScreen->bitsPerPixel; + vmesa->front.pitch = buffer_align( w ) << shift; + vmesa->front.size = vmesa->front.pitch * h; + vmesa->front.offset = 0; + vmesa->front.map = (char *) vmesa->driScreen->pFB; + } - /* Allocate back-buffer */ + /* Allocate back-buffer */ + if (vmesa->hasBack) { + vmesa->back.bpp = vmesa->viaScreen->bitsPerPixel; + vmesa->back.pitch = (buffer_align( vmesa->driDrawable->w ) << shift) + extra; + vmesa->back.size = vmesa->back.pitch * vmesa->driDrawable->h; + if (vmesa->back.map) + via_free_draw_buffer(vmesa, &vmesa->back); + if (!via_alloc_draw_buffer(vmesa, &vmesa->back)) + return GL_FALSE; + } + else { + /* KW: mem leak if vmesa->hasBack ever changes: + */ + (void) memset( &vmesa->back, 0, sizeof( vmesa->back ) ); + } - vmesa->back.pitch = (buffer_align( vmesa->driDrawable->w ) << shift) - + extra; - vmesa->back.size = vmesa->back.pitch * vmesa->driDrawable->h; - if (VIA_DEBUG) fprintf(stderr, "%s backbuffer: w = %d h = %d bpp = %d sizs = %d\n", - __FUNCTION__, - vmesa->back.pitch, - vmesa->driDrawable->h, - 8 << shift, - vmesa->back.size); + /* Allocate depth-buffer */ + if ( vmesa->hasStencil || vmesa->hasDepth ) { + vmesa->depth.bpp = vmesa->depthBits; + if (vmesa->depth.bpp == 24) + vmesa->depth.bpp = 32; - /* Allocate depth-buffer */ - if ( vmesa->hasStencil || vmesa->hasDepth ) { - vmesa->depth.bpp = vmesa->depthBits; - if (vmesa->depth.bpp == 24) - vmesa->depth.bpp = 32; + vmesa->depth.pitch = (buffer_align( vmesa->driDrawable->w ) * (vmesa->depth.bpp/8)) + extra; + vmesa->depth.size = vmesa->depth.pitch * vmesa->driDrawable->h; - vmesa->depth.pitch = (buffer_align( vmesa->driDrawable->w ) * (vmesa->depth.bpp/8)) + extra; - vmesa->depth.size = vmesa->depth.pitch * vmesa->driDrawable->h; - } - else { - (void) memset( & vmesa->depth, 0, sizeof( vmesa->depth ) ); - } + if (vmesa->depth.map) + via_free_draw_buffer(vmesa, &vmesa->depth); + if (!via_alloc_draw_buffer(vmesa, &vmesa->depth)) { + return GL_FALSE; + } + } + else { + /* KW: mem leak if vmesa->hasStencil/hasDepth ever changes: + */ + (void) memset( & vmesa->depth, 0, sizeof( vmesa->depth ) ); + } - if (VIA_DEBUG) fprintf(stderr, "%s depthbuffer: w = %d h = %d bpp = %d sizs = %d\n", - __FUNCTION__, - vmesa->depth.pitch, - vmesa->driDrawable->h, - vmesa->depth.bpp, - vmesa->depth.size); - - /*=* John Sheng [2003.5.31] flip *=*/ - if( vmesa->viaScreen->width == vmesa->driDrawable->w && - vmesa->viaScreen->height == vmesa->driDrawable->h ) { + /*=* John Sheng [2003.5.31] flip *=*/ + if( vmesa->viaScreen->width == vmesa->driDrawable->w && + vmesa->viaScreen->height == vmesa->driDrawable->h ) { #define ALLOW_EXPERIMENTAL_PAGEFLIP 0 #if ALLOW_EXPERIMENTAL_PAGEFLIP - vmesa->doPageFlip = GL_TRUE; + vmesa->doPageFlip = GL_TRUE; #else - vmesa->doPageFlip = GL_FALSE; + vmesa->doPageFlip = GL_FALSE; #endif - vmesa->currentPage = 0; - vmesa->back.pitch = vmesa->front.pitch; - } + /* vmesa->currentPage = 0; */ + assert(vmesa->back.pitch == vmesa->front.pitch); + } + else + vmesa->doPageFlip = GL_FALSE; - if (!AllocateBuffer(vmesa)) { - FREE(vmesa); - return GL_FALSE; - } - - return GL_TRUE; + return GL_TRUE; } @@ -250,20 +231,8 @@ void viaReAllocateBuffers(GLframebuffer *drawbuffer) GET_CURRENT_CONTEXT(ctx); viaContextPtr vmesa = VIA_CONTEXT(ctx); - ctx->DrawBuffer->Width = drawbuffer->Width; - ctx->DrawBuffer->Height = drawbuffer->Height; - - if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); - ctx->DrawBuffer->Accum = 0; - - vmesa->driDrawable->w = ctx->DrawBuffer->Width; - vmesa->driDrawable->h = ctx->DrawBuffer->Height; - - LOCK_HARDWARE(vmesa); + _swrast_alloc_buffers( drawbuffer ); calculate_buffer_parameters( vmesa ); - UNLOCK_HARDWARE(vmesa); - - if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); } static void viaBufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height) @@ -303,9 +272,7 @@ static const struct tnl_pipeline_stage *via_pipeline[] = { &_tnl_texgen_stage, &_tnl_texture_transform_stage, /* REMOVE: point attenuation stage */ -#if 0 &_via_fastrender_stage, /* ADD: unclipped rastersetup-to-dma */ -#endif &_tnl_render_stage, 0, }; @@ -314,39 +281,14 @@ static const struct tnl_pipeline_stage *via_pipeline[] = { static GLboolean AllocateDmaBuffer(const GLvisual *visual, viaContextPtr vmesa) { - GLuint *addr; - - if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); if (vmesa->dma) via_free_dma_buffer(vmesa); - if (!via_alloc_dma_buffer(vmesa)) { - if (vmesa->front.map) - via_free_front_buffer(vmesa); - if (vmesa->back.map) - via_free_back_buffer(vmesa); - if (vmesa->depth.map) - via_free_depth_buffer(vmesa); - + if (!via_alloc_dma_buffer(vmesa)) return GL_FALSE; - } - /* Insert placeholder for a cliprect: - */ - addr = (GLuint *)vmesa->dma; - addr[0] = HC_HEADER2; - addr[1] = (HC_ParaType_NotTex << 16); - addr[2] = HC_DUMMY; - addr[3] = HC_DUMMY; - addr[4] = HC_DUMMY; - addr[5] = HC_DUMMY; - addr[6] = HC_DUMMY; - addr[7] = HC_DUMMY; - - vmesa->dmaLow = DMA_OFFSET; - vmesa->dmaAddr = (unsigned char *)vmesa->dma; - - if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); + vmesa->dmaLow = 0; + vmesa->dmaCliprectAddr = 0; return GL_TRUE; } @@ -354,13 +296,13 @@ static void FreeBuffer(viaContextPtr vmesa) { if (vmesa->front.map) - via_free_front_buffer(vmesa); + via_free_draw_buffer(vmesa, &vmesa->front); if (vmesa->back.map) - via_free_back_buffer(vmesa); + via_free_draw_buffer(vmesa, &vmesa->back); if (vmesa->depth.map) - via_free_depth_buffer(vmesa); + via_free_draw_buffer(vmesa, &vmesa->depth); if (vmesa->dma) via_free_dma_buffer(vmesa); @@ -536,6 +478,7 @@ viaCreateContext(const __GLcontextModes *mesaVis, */ if (!AllocateDmaBuffer(mesaVis, vmesa)) { fprintf(stderr ,"AllocateDmaBuffer fail\n"); + FreeBuffer(vmesa); FREE(vmesa); return GL_FALSE; } @@ -576,7 +519,7 @@ viaCreateContext(const __GLcontextModes *mesaVis, if ( vmesa->get_ust == NULL ) { vmesa->get_ust = get_ust_nop; } - (*vmesa->get_ust)( & vmesa->swap_ust ); + vmesa->get_ust( &vmesa->swap_ust ); vmesa->regMMIOBase = (GLuint *)((GLuint)viaScreen->reg); @@ -620,64 +563,59 @@ viaDestroyContext(__DRIcontextPrivate *driContextPriv) if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); } -void viaXMesaSetFrontClipRects(viaContextPtr vmesa) -{ - __DRIdrawablePrivate *dPriv = vmesa->driDrawable; - if (!dPriv) - return; - - vmesa->numClipRects = dPriv->numClipRects; - vmesa->pClipRects = dPriv->pClipRects; - vmesa->drawX = dPriv->x; - vmesa->drawY = dPriv->y; - vmesa->drawW = dPriv->w; - vmesa->drawH = dPriv->h; - - { - GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3; - vmesa->drawXoff = (GLuint)(((vmesa->drawX * bytePerPixel) & 0x1f) / bytePerPixel); - } - - viaCalcViewport(vmesa->glCtx); -} - -void viaXMesaSetBackClipRects(viaContextPtr vmesa) +void viaXMesaWindowMoved(viaContextPtr vmesa) { __DRIdrawablePrivate *dPriv = vmesa->driDrawable; + GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3; if (!dPriv) return; - /*=* John Sheng [2003.6.9] fix glxgears dirty screen */ - vmesa->numClipRects = dPriv->numClipRects; - vmesa->pClipRects = dPriv->pClipRects; - vmesa->drawX = dPriv->x; + switch (vmesa->glCtx->Color._DrawDestMask[0]) { + case DD_FRONT_LEFT_BIT: + if (dPriv->numBackClipRects == 0) { + vmesa->numClipRects = dPriv->numClipRects; + vmesa->pClipRects = dPriv->pClipRects; + } + else { + vmesa->numClipRects = dPriv->numBackClipRects; + vmesa->pClipRects = dPriv->pBackClipRects; + } + break; + case DD_BACK_LEFT_BIT: + vmesa->numClipRects = dPriv->numClipRects; + vmesa->pClipRects = dPriv->pClipRects; + break; + default: + vmesa->numClipRects = 0; + break; + } + + if (vmesa->drawW != dPriv->w || + vmesa->drawH != dPriv->h) + calculate_buffer_parameters( vmesa ); + + vmesa->drawXoff = (GLuint)(((dPriv->x * bytePerPixel) & 0x1f) / bytePerPixel); + vmesa->drawX = dPriv->x - vmesa->drawXoff; vmesa->drawY = dPriv->y; vmesa->drawW = dPriv->w; vmesa->drawH = dPriv->h; + vmesa->front.orig = (vmesa->front.offset + + vmesa->drawY * vmesa->front.pitch + + vmesa->drawX * bytePerPixel); - vmesa->drawXoff = 0; + vmesa->front.origMap = (vmesa->front.map + + vmesa->drawY * vmesa->front.pitch + + vmesa->drawX * bytePerPixel); - viaCalcViewport(vmesa->glCtx); -} - -void viaXMesaWindowMoved(viaContextPtr vmesa) -{ - - switch (vmesa->glCtx->Color._DrawDestMask[0]) { - case DD_FRONT_LEFT_BIT: - viaXMesaSetFrontClipRects(vmesa); - break; - case DD_BACK_LEFT_BIT: - viaXMesaSetBackClipRects(vmesa); - break; - default: - viaXMesaSetFrontClipRects(vmesa); - break; - } + vmesa->back.orig = vmesa->back.offset; + vmesa->depth.orig = vmesa->depth.offset; + vmesa->back.origMap = vmesa->back.map; + vmesa->depth.origMap = vmesa->depth.map; + viaCalcViewport(vmesa->glCtx); } GLboolean @@ -736,30 +674,20 @@ void viaGetLock(viaContextPtr vmesa, GLuint flags) { __DRIdrawablePrivate *dPriv = vmesa->driDrawable; __DRIscreenPrivate *sPriv = vmesa->driScreen; - drm_via_sarea_t *sarea = vmesa->sarea; - int me = vmesa->hHWContext; - __DRIdrawablePrivate *pdp; - __DRIscreenPrivate *psp; - pdp = dPriv; - psp = sPriv; - if (VIA_DEBUG) { - fprintf(stderr, "%s - in\n", __FUNCTION__); - fprintf(stderr, "is: %x non-contend: %x want: %x\n", - *(GLuint *)vmesa->driHwLock, vmesa->hHWContext, - (DRM_LOCK_HELD|vmesa->hHWContext)); - } drmGetLock(vmesa->driFd, vmesa->hHWContext, flags); DRI_VALIDATE_DRAWABLE_INFO( sPriv, dPriv ); - if (sarea->ctxOwner != me) { - sarea->ctxOwner = me; - vmesa->newState = ~0; + if (vmesa->sarea->ctxOwner != vmesa->hHWContext) { + vmesa->sarea->ctxOwner = vmesa->hHWContext; + vmesa->newState = ~0; } - viaXMesaWindowMoved(vmesa); - if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); + if (vmesa->lastStamp != dPriv->lastStamp) { + viaXMesaWindowMoved(vmesa); + vmesa->lastStamp = dPriv->lastStamp; + } } @@ -768,7 +696,7 @@ viaSwapBuffers(__DRIdrawablePrivate *drawablePrivate) { __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *)drawablePrivate; if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); - if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { + if (dPriv && dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { viaContextPtr vmesa; GLcontext *ctx; diff --git a/src/mesa/drivers/dri/unichrome/via_context.h b/src/mesa/drivers/dri/unichrome/via_context.h index 10d47777622..995e20698ec 100644 --- a/src/mesa/drivers/dri/unichrome/via_context.h +++ b/src/mesa/drivers/dri/unichrome/via_context.h @@ -52,9 +52,12 @@ typedef struct via_texture_object_t *viaTextureObjectPtr; #define VIA_FALLBACK_BLEND_FUNC 0x400 #define VIA_FALLBACK_USER_DISABLE 0x800 -#define VIA_DMA_BUFSIZ 500000 +#define VIA_DMA_BUFSIZ 5000 #define VIA_DMA_HIGHWATER (VIA_DMA_BUFSIZ - 256) +#define VIA_NO_CLIPRECTS 0x1 + + /* Use the templated vertex formats: */ #define TAG(x) via##x @@ -74,6 +77,10 @@ typedef struct { GLuint pitch; GLuint bpp; char *map; + GLuint orig; /* The drawing origin, + * at (drawX,drawY) in screen space. + */ + char *origMap; } viaBuffer, *viaBufferPtr; @@ -81,7 +88,6 @@ struct via_context_t { GLint refcount; GLcontext *glCtx; GLcontext *shareCtx; - unsigned char* front_base; viaBuffer front; viaBuffer back; viaBuffer depth; @@ -98,7 +104,7 @@ struct via_context_t { GLuint stencil_clear_mask; GLfloat depth_max; - GLuint *dma; + GLubyte *dma; viaRegion tex; GLuint isAGP; @@ -127,8 +133,8 @@ struct via_context_t { /* drmBufPtr dma_buffer; */ - unsigned char* dmaAddr; GLuint dmaLow; + GLuint dmaCliprectAddr; GLuint dmaLastPrim; GLboolean useAgp; @@ -202,7 +208,6 @@ struct via_context_t { int vertexSize; int vertexFormat; GLint lastStamp; - GLboolean stippleInHw; GLenum TexEnvImageFmt[2]; GLuint ClearColor; @@ -213,16 +218,15 @@ struct via_context_t { GLboolean doPageFlip; /*=* John Sheng [2003.5.31] flip *=*/ GLuint currentPage; - char *drawMap; /* draw buffer address in virtual mem */ - char *readMap; + + viaBuffer *drawBuffer; + viaBuffer *readBuffer; int drawX; /* origin of drawable in draw buffer */ int drawY; int drawW; int drawH; - int drawPitch; - int readPitch; int drawXoff; GLuint numClipRects; /* cliprects for that buffer */ drm_clip_rect_t *pClipRects; @@ -325,6 +329,8 @@ extern void viaXMesaWindowMoved(viaContextPtr vmesa); extern void viaTexCombineState(viaContextPtr vmesa, const struct gl_tex_env_combine_state * combine, unsigned unit ); +/* Via hw already adjusted for GL pixel centers: + */ #define SUBPIXEL_X 0 #define SUBPIXEL_Y 0 diff --git a/src/mesa/drivers/dri/unichrome/via_fb.c b/src/mesa/drivers/dri/unichrome/via_fb.c index cf4eadc58db..39d43e72784 100644 --- a/src/mesa/drivers/dri/unichrome/via_fb.c +++ b/src/mesa/drivers/dri/unichrome/via_fb.c @@ -31,126 +31,37 @@ #include GLboolean -via_alloc_back_buffer(viaContextPtr vmesa) +via_alloc_draw_buffer(viaContextPtr vmesa, viaBuffer *buf) { - drm_via_mem_t fb; - unsigned char *pFB; - if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); - fb.context = vmesa->hHWContext; - fb.size = vmesa->back.size; - fb.type = VIDEO; - if (VIA_DEBUG) fprintf(stderr, "context = %d, size =%d, type = %d\n", fb.context, fb.size, fb.type); - if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &fb)) - return GL_FALSE; - - pFB = vmesa->driScreen->pFB; - - vmesa->back.offset = fb.offset; - vmesa->back.map = (char *)(fb.offset + (GLuint)pFB); - vmesa->back.index = fb.index; - if (VIA_DEBUG) { - fprintf(stderr, "back offset = %08x\n", vmesa->back.offset); - fprintf(stderr, "back index = %d\n", vmesa->back.index); - } + drm_via_mem_t mem; + mem.context = vmesa->hHWContext; + mem.size = buf->size; + mem.type = VIDEO; - if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); - return GL_TRUE; -} - -GLboolean -via_alloc_front_buffer(viaContextPtr vmesa) -{ - drm_via_mem_t fb; - unsigned char *pFB; - if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); - fb.context = vmesa->hHWContext; - fb.size = vmesa->back.size; - fb.type = VIDEO; - if (VIA_DEBUG) fprintf(stderr, "context = %d, size =%d, type = %d\n", fb.context, fb.size, fb.type); - if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &fb)) - return GL_FALSE; + if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &mem)) + return GL_FALSE; - pFB = vmesa->driScreen->pFB; - vmesa->front.offset = fb.offset; - vmesa->front.map = (char *)(fb.offset + (GLuint)pFB); - vmesa->front.index = fb.index; - if (VIA_DEBUG) { - fprintf(stderr, "front offset = %08x\n", vmesa->front.offset); - fprintf(stderr, "front index = %d\n", vmesa->front.index); - } - - - if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); - return GL_TRUE; + buf->offset = mem.offset; + buf->map = (char *)vmesa->driScreen->pFB + mem.offset; + buf->index = mem.index; + return GL_TRUE; } void -via_free_back_buffer(viaContextPtr vmesa) +via_free_draw_buffer(viaContextPtr vmesa, viaBuffer *buf) { - drm_via_mem_t fb; + drm_via_mem_t mem; - if (!vmesa) return; - fb.context = vmesa->hHWContext; - fb.index = vmesa->back.index; - fb.type = VIDEO; - ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &fb); - vmesa->back.map = NULL; + if (!vmesa) return; + + mem.context = vmesa->hHWContext; + mem.index = buf->index; + mem.type = VIDEO; + ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &mem); + buf->map = NULL; } -void -via_free_front_buffer(viaContextPtr vmesa) -{ - drm_via_mem_t fb; - - if (!vmesa) return; - fb.context = vmesa->hHWContext; - fb.index = vmesa->front.index; - fb.type = VIDEO; - ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &fb); - vmesa->front.map = NULL; -} - -GLboolean -via_alloc_depth_buffer(viaContextPtr vmesa) -{ - drm_via_mem_t fb; - unsigned char *pFB; - if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); - fb.context = vmesa->hHWContext; - fb.size = vmesa->depth.size; - fb.type = VIDEO; - - if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &fb)) { - return GL_FALSE; - } - - pFB = vmesa->driScreen->pFB; - - vmesa->depth.offset = fb.offset; - vmesa->depth.map = (char *)(fb.offset + (GLuint)pFB); - vmesa->depth.index = fb.index; - if (VIA_DEBUG) { - fprintf(stderr, "depth offset = %08x\n", vmesa->depth.offset); - fprintf(stderr, "depth index = %d\n", vmesa->depth.index); - } - - if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); - return GL_TRUE; -} - -void -via_free_depth_buffer(viaContextPtr vmesa) -{ - drm_via_mem_t fb; - - if (!vmesa) return; - fb.context = vmesa->hHWContext; - fb.index = vmesa->depth.index; - fb.type = VIDEO; - ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &fb); - vmesa->depth.map = NULL; -} GLboolean via_alloc_dma_buffer(viaContextPtr vmesa) @@ -158,7 +69,7 @@ via_alloc_dma_buffer(viaContextPtr vmesa) drmVIADMAInit init; if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); - vmesa->dma = (GLuint *) malloc(VIA_DMA_BUFSIZ); + vmesa->dma = (GLubyte *) malloc(VIA_DMA_BUFSIZ); /* * Check whether AGP DMA has been initialized. diff --git a/src/mesa/drivers/dri/unichrome/via_fb.h b/src/mesa/drivers/dri/unichrome/via_fb.h index c4378c2469a..23fc861459f 100644 --- a/src/mesa/drivers/dri/unichrome/via_fb.h +++ b/src/mesa/drivers/dri/unichrome/via_fb.h @@ -25,18 +25,14 @@ #ifndef _VIAFB_INC #define _VIAFB_INC -#include "mtypes.h" -#include "swrast/swrast.h" -extern GLboolean via_alloc_front_buffer(viaContextPtr vmesa); -extern GLboolean via_alloc_back_buffer(viaContextPtr vmesa); -extern void via_free_back_buffer(viaContextPtr vmesa); -extern void via_free_front_buffer(viaContextPtr vmesa); -extern GLboolean via_alloc_depth_buffer(viaContextPtr vmesa); -extern void via_free_depth_buffer(viaContextPtr vmesa); +#include "via_context.h" + +extern GLboolean via_alloc_draw_buffer(viaContextPtr vmesa, viaBuffer *buf); extern GLboolean via_alloc_dma_buffer(viaContextPtr vmesa); -extern void via_free_dma_buffer(viaContextPtr vmesa); extern GLboolean via_alloc_texture(viaContextPtr vmesa, viaTextureObjectPtr t); -/*=* John Sheng [2003.5.31] agp tex *=*/ extern GLboolean via_alloc_texture_agp(viaContextPtr vmesa, viaTextureObjectPtr t); + +extern void via_free_draw_buffer(viaContextPtr vmesa, viaBuffer *buf); +extern void via_free_dma_buffer(viaContextPtr vmesa); extern void via_free_texture(viaContextPtr vmesa, viaTextureObjectPtr t); #endif diff --git a/src/mesa/drivers/dri/unichrome/via_ioctl.c b/src/mesa/drivers/dri/unichrome/via_ioctl.c index 431a26b2a94..55220f18f6f 100644 --- a/src/mesa/drivers/dri/unichrome/via_ioctl.c +++ b/src/mesa/drivers/dri/unichrome/via_ioctl.c @@ -73,593 +73,16 @@ v * copy of this software and associated documentation files (the "Software"), #define VIA_BLIT_SET 0xFF -#define DEPTH_SCALE ((1 << 16) - 1) - void viaCheckDma(viaContextPtr vmesa, GLuint bytes) { VIA_FINISH_PRIM( vmesa ); if (vmesa->dmaLow + bytes > VIA_DMA_HIGHWATER) { - viaFlushPrims(vmesa); + viaFlushDma(vmesa); } } -static void viaClear(GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint cx, GLint cy, GLint cw, GLint ch) -{ - viaContextPtr vmesa = VIA_CONTEXT(ctx); - __DRIdrawablePrivate *dPriv = vmesa->driDrawable; - const GLuint colorMask = *((GLuint *)&ctx->Color.ColorMask); - int flag = 0; - GLuint i = 0; - GLuint clear_depth_mask = 0xf << 28; - GLuint clear_depth = 0; - - VIA_FLUSH_DMA(vmesa); - - if ((mask & DD_FRONT_LEFT_BIT) && colorMask == ~0) { - flag |= VIA_FRONT; - mask &= ~DD_FRONT_LEFT_BIT; - } - - if ((mask & DD_BACK_LEFT_BIT) && colorMask == ~0) { - flag |= VIA_BACK; - mask &= ~DD_BACK_LEFT_BIT; - } - - if (mask & DD_DEPTH_BIT) { - flag |= VIA_DEPTH; - clear_depth = (GLuint)(ctx->Depth.Clear * vmesa->ClearDepth); - clear_depth_mask &= ~vmesa->depth_clear_mask; - mask &= ~DD_DEPTH_BIT; - } - - if (mask & DD_STENCIL_BIT) { - if (vmesa->have_hw_stencil) { - if (ctx->Stencil.WriteMask[0] == 0xff) { - flag |= VIA_DEPTH; - clear_depth &= ~0xff; - clear_depth |= (ctx->Stencil.Clear & 0xff); - clear_depth_mask &= ~vmesa->stencil_clear_mask; - mask &= ~DD_STENCIL_BIT; - } - else { - fprintf(stderr, "XXX: Clear stencil writemask %x -- need triangles (or a ROP?)\n", - ctx->Stencil.WriteMask[0]); - /* Fixme - clear with triangles */ - } - } - } - - if (flag) { - LOCK_HARDWARE(vmesa); - /* flip top to bottom */ - cy = dPriv->h - cy - ch; - cx += vmesa->drawX; - cy += vmesa->drawY; - - if (vmesa->numClipRects) { - int nr = MIN2(i + VIA_NR_SAREA_CLIPRECTS, vmesa->numClipRects); - drm_clip_rect_t *box = vmesa->pClipRects; - drm_clip_rect_t *b = vmesa->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++; - } - } - vmesa->sarea->nbox = n; - - } - - if (flag & VIA_FRONT) { - if (vmesa->drawType == GLX_PBUFFER_BIT) - viaFillFrontPBuffer(vmesa); - else - viaFillFrontBuffer(vmesa); - } - - if (flag & VIA_BACK) { - viaFillBackBuffer(vmesa); - } - - if (flag & VIA_DEPTH) { - viaFillDepthBuffer(vmesa, clear_depth, clear_depth_mask); - } - - UNLOCK_HARDWARE(vmesa); - } - - if (mask) - _swrast_Clear(ctx, mask, all, cx, cy, cw, ch); - if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__); -} - -/* - * Copy the back buffer to the front buffer. - */ -void viaCopyBuffer(const __DRIdrawablePrivate *dPriv) -{ - viaContextPtr vmesa = (viaContextPtr)dPriv->driContextPriv->driverPrivate; - GLboolean missed_target; - int64_t ust; - - VIA_FLUSH_DMA(vmesa); - - driWaitForVBlank( dPriv, & vmesa->vbl_seq, vmesa->vblank_flags, & missed_target ); - - LOCK_HARDWARE(vmesa); - if (vmesa->drawType == GLX_PBUFFER_BIT) { - viaDoSwapPBuffers(vmesa); - } - else { - viaDoSwapBuffers(vmesa); - } - UNLOCK_HARDWARE(vmesa); - - vmesa->swap_count++; - (*vmesa->get_ust)( & ust ); - if ( missed_target ) { - vmesa->swap_missed_count++; - vmesa->swap_missed_ust = ust - vmesa->swap_ust; - } - - vmesa->swap_ust = ust; -} - -/* - * XXX implement when full-screen extension is done. - */ -void viaPageFlip(const __DRIdrawablePrivate *dPriv) -{ - /*=* John Sheng [2003.5.31] flip *=*/ - viaContextPtr vmesa = (viaContextPtr)dPriv->driContextPriv->driverPrivate; - GLcontext *ctx = vmesa->glCtx; - GLuint nBackBase; - viaBuffer buffer_tmp; - GLboolean missed_target; - int retcode; - - if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); - assert(dPriv); - assert(dPriv->driContextPriv); - assert(dPriv->driContextPriv->driverPrivate); - - - VIA_FLUSH_DMA(vmesa); - - /* Now wait for the vblank: - */ - retcode = driWaitForVBlank( dPriv, &vmesa->vbl_seq, - vmesa->vblank_flags, &missed_target ); - if ( missed_target ) { - vmesa->swap_missed_count++; - (void) (*vmesa->get_ust)( &vmesa->swap_missed_ust ); - } - - LOCK_HARDWARE(vmesa); - - { - RING_VARS; - - if (!vmesa->nDoneFirstFlip) { - vmesa->nDoneFirstFlip = GL_FALSE; /* XXX: FIXME LATER!!! */ - BEGIN_RING(4); - OUT_RING(HALCYON_HEADER2); - OUT_RING(0x00fe0000); - OUT_RING(0x0000000e); - OUT_RING(0x0000000e); - ADVANCE_RING(); - } - nBackBase = (vmesa->back.offset ); - - BEGIN_RING(4); - OUT_RING( HALCYON_HEADER2 ); - OUT_RING( 0x00fe0000 ); - OUT_RING((HC_SubA_HFBBasL << 24) | (nBackBase & 0xFFFFF8) | 0x2); - OUT_RING((HC_SubA_HFBDrawFirst << 24) | - ((nBackBase & 0xFF000000) >> 24) | 0x0100); - ADVANCE_RING(); - - viaFlushPrimsLocked(vmesa); - } - - UNLOCK_HARDWARE(vmesa); - - vmesa->swap_count++; - (void) (*vmesa->get_ust)( &vmesa->swap_ust ); - - memcpy(&buffer_tmp, &vmesa->back, sizeof(viaBuffer)); - memcpy(&vmesa->back, &vmesa->front, sizeof(viaBuffer)); - memcpy(&vmesa->front, &buffer_tmp, sizeof(viaBuffer)); - - /* KW: BOGUS BOGUS BOGUS: The first time an app calls glDrawBuffer - * while pageflipping, this will blow up: FIXME - */ - if(vmesa->currentPage) { - vmesa->currentPage = 0; - if (vmesa->glCtx->Color._DrawDestMask[0] == DD_BACK_LEFT_BIT) { - ctx->Driver.DrawBuffer(ctx, GL_BACK); - } - else { - ctx->Driver.DrawBuffer(ctx, GL_FRONT); - } - } - else { - vmesa->currentPage = 1; - if (vmesa->glCtx->Color._DrawDestMask[0] == DD_BACK_LEFT_BIT) { - ctx->Driver.DrawBuffer(ctx, GL_BACK); - } - else { - ctx->Driver.DrawBuffer(ctx, GL_FRONT); - } - } - if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); -} - - - - -#define VIA_CMDBUF_MAX_LAG 50000 - -static int fire_buffer(viaContextPtr vmesa, drm_via_flush_sys_t *buf) -{ - drmVIACommandBuffer bufI; - int ret; - - bufI.buf = (char *) (buf->index + buf->offset); - bufI.size = buf->size; - - if (vmesa->useAgp) { - drmVIACmdBufSize bSiz; - - /* Do the CMDBUF_SIZE ioctl: - */ - bSiz.func = VIA_CMDBUF_LAG; - bSiz.wait = 1; - bSiz.size = VIA_CMDBUF_MAX_LAG; - do { - ret = drmCommandWriteRead(vmesa->driFd, DRM_VIA_CMDBUF_SIZE, - &bSiz, sizeof(bSiz)); - } while (ret == -EAGAIN); - if (ret) { - fprintf(stderr, "%s: DRM_VIA_CMDBUF_SIZE returned %d\n", __FUNCTION__, ret); - abort(); - return ret; - } - - /* Acutally fire the buffer: - */ - do { - ret = drmCommandWrite(vmesa->driFd, DRM_VIA_CMDBUFFER, - &bufI, sizeof(bufI)); - } while (ret == -EAGAIN); - if (ret) { - fprintf(stderr, "%s: DRM_VIA_CMDBUFFER returned %d\n", __FUNCTION__, ret); - abort(); - /* If this fails, the original code fell back to the PCI path. - */ - } - else - return 0; - - /* Fall through to PCI handling?!? - */ - WAIT_IDLE(vmesa); - } - - ret = drmCommandWrite(vmesa->driFd, DRM_VIA_PCICMD, &bufI, sizeof(bufI)); - if (ret) { - fprintf(stderr, "%s: DRM_VIA_PCICMD returned %d\n", __FUNCTION__, ret); - abort(); - } - - return ret; -} - - -/* Inserts the surface addresss and active cliprects one at a time - * into the head of the DMA buffer being flushed. Fires the buffer - * for each cliprect. - */ -static int via_flush_sys(viaContextPtr vmesa, drm_via_flush_sys_t* buf) -{ - GLuint *vb = (GLuint *)vmesa->dmaAddr; - GLuint format = (vmesa->viaScreen->bitsPerPixel == 0x20 - ? HC_HDBFM_ARGB8888 - : HC_HDBFM_RGB565); - - if (vmesa->glCtx->Color._DrawDestMask[0] == DD_BACK_LEFT_BIT) { - GLuint offset = vmesa->back.offset; - GLuint pitch = vmesa->back.pitch; - - vb[0] = HC_HEADER2; - vb[1] = HC_ParaType_NotTex << 16; - - if (vmesa->driDrawable->w == 0 || vmesa->driDrawable->h == 0) { - vb[2] = (HC_SubA_HClipTB << 24) | 0x0; - vb[3] = (HC_SubA_HClipLR << 24) | 0x0; - } - else { - vb[2] = (HC_SubA_HClipTB << 24) | vmesa->driDrawable->h; - vb[3] = (HC_SubA_HClipLR << 24) | vmesa->driDrawable->w; - } - - vb[4] = ((HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF)); - vb[5] = ((HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000)) >> 24); - vb[6] = ((HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch); - vb[7] = 0xcccccccc; - - return fire_buffer( vmesa, buf ); - } - else { - GLuint i, ret; - drm_clip_rect_t *b = vmesa->sarea->boxes; - - for (i = 0; i < vmesa->sarea->nbox; i++, b++) { - GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3; - GLuint pitch = vmesa->front.pitch; - GLuint offset = (vmesa->viaScreen->fbOffset + (vmesa->drawY * pitch + vmesa->drawX * bytePerPixel)) & ~0x1f; - - GLuint clipL = b->x1 + vmesa->drawXoff; - GLuint clipR = b->x2 + vmesa->drawXoff; - GLuint clipT = b->y1; - GLuint clipB = b->y2; - - vb[0] = HC_HEADER2; - vb[1] = (HC_ParaType_NotTex << 16); - - if (vmesa->driDrawable->w == 0 || vmesa->driDrawable->h == 0) { - vb[2] = (HC_SubA_HClipTB << 24) | 0x0; - vb[3] = (HC_SubA_HClipLR << 24) | 0x0; - } - else { - vb[2] = (HC_SubA_HClipTB << 24) | (clipT << 12) | clipB; - vb[3] = (HC_SubA_HClipLR << 24) | (clipL << 12) | clipR; - } - - vb[4] = ((HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF)); - vb[5] = ((HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000)) >> 24); - vb[6] = ((HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch); - vb[7] = 0xcccccccc; - - ret = fire_buffer( vmesa, buf ); - if (ret) - return ret; - } - } - - return 0; -} - - - -static int intersect_rect(drm_clip_rect_t *out, - drm_clip_rect_t *a, - drm_clip_rect_t *b) -{ - *out = *a; - - if (b->x1 > out->x1) out->x1 = b->x1; - if (b->x2 < out->x2) out->x2 = b->x2; - if (out->x1 >= out->x2) return 0; - - if (b->y1 > out->y1) out->y1 = b->y1; - if (b->y2 < out->y2) out->y2 = b->y2; - if (out->y1 >= out->y2) return 0; - - return 1; -} - -void viaFlushPrimsLocked(viaContextPtr vmesa) -{ - drm_clip_rect_t *pbox = (drm_clip_rect_t *)vmesa->pClipRects; - int nbox = vmesa->numClipRects; - drm_via_sarea_t *sarea = vmesa->sarea; - drm_via_flush_sys_t sysCmd; - int i; - RING_VARS; - - if (*(GLuint *)vmesa->driHwLock != (DRM_LOCK_HELD|vmesa->hHWContext) && - *(GLuint *)vmesa->driHwLock != (DRM_LOCK_HELD|DRM_LOCK_CONT|vmesa->hHWContext)) { - fprintf(stderr, "%s called without lock held\n", __FUNCTION__); - abort(); - } - - if (vmesa->dmaLow == DMA_OFFSET) { - return; - } - - assert(vmesa->dmaLastPrim == 0); - - /* viaFinishPrimitive can add up to 8 bytes beyond VIA_DMA_HIGHWATER: - */ - if (vmesa->dmaLow > VIA_DMA_HIGHWATER + 8) { - fprintf(stderr, "buffer overflow in Flush Prims = %d\n",vmesa->dmaLow); - abort(); - } - - switch (vmesa->dmaLow & 0x1F) { - case 8: - BEGIN_RING_NOCHECK( 6 ); - OUT_RING( HC_HEADER2 ); - OUT_RING( (HC_ParaType_NotTex << 16) ); - OUT_RING( HC_DUMMY ); - OUT_RING( HC_DUMMY ); - OUT_RING( HC_DUMMY ); - OUT_RING( HC_DUMMY ); - ADVANCE_RING(); - break; - case 16: - BEGIN_RING_NOCHECK( 4 ); - OUT_RING( HC_HEADER2 ); - OUT_RING( (HC_ParaType_NotTex << 16) ); - OUT_RING( HC_DUMMY ); - OUT_RING( HC_DUMMY ); - ADVANCE_RING(); - break; - case 24: - BEGIN_RING_NOCHECK( 10 ); - OUT_RING( HC_HEADER2 ); - OUT_RING( (HC_ParaType_NotTex << 16) ); - OUT_RING( HC_DUMMY ); - OUT_RING( HC_DUMMY ); - OUT_RING( HC_DUMMY ); - OUT_RING( HC_DUMMY ); - OUT_RING( HC_DUMMY ); - OUT_RING( HC_DUMMY ); - OUT_RING( HC_DUMMY ); - OUT_RING( HC_DUMMY ); - ADVANCE_RING(); - break; - case 0: - break; - default: - if (VIA_DEBUG) - fprintf(stderr, "%s: unaligned value for vmesa->dmaLow: %x\n", - __FUNCTION__, vmesa->dmaLow); -/* abort(); */ -/* goto done; */ - } - -/* assert((vmesa->dmaLow & 0x1f) == 0); */ - - sysCmd.offset = 0x0; - sysCmd.size = vmesa->dmaLow; - sysCmd.index = (GLuint)vmesa->dma; - sysCmd.discard = 0; - - if (!nbox) { - sysCmd.size = 0; /* KW: FIXME bogus if we ever start emitting partial state */ - sarea->nbox = 0; - sysCmd.discard = 1; - via_flush_sys(vmesa, &sysCmd); - } - else { - for (i = 0; i < nbox; ) { - int nr = MIN2(i + VIA_NR_SAREA_CLIPRECTS, nbox); - drm_clip_rect_t *b = sarea->boxes; - - if (vmesa->glCtx->Scissor.Enabled) { - sarea->nbox = 0; - - for (; i < nr; i++) { - b->x1 = pbox[i].x1 - vmesa->drawX; - b->y1 = pbox[i].y1 - vmesa->drawY; - b->x2 = pbox[i].x2 - vmesa->drawX; - b->y2 = pbox[i].y2 - vmesa->drawY; - if (intersect_rect(b, b, &vmesa->scissorRect)) { - sarea->nbox++; - b++; - } - } - if (!sarea->nbox) { - if (nr < nbox) continue; - sysCmd.size = 0; - } - } - else { - sarea->nbox = nr - i; - for (; i < nr; i++, b++) { - b->x1 = pbox[i].x1 - vmesa->drawX; - b->y1 = pbox[i].y1 - vmesa->drawY; - b->x2 = pbox[i].x2 - vmesa->drawX; - b->y2 = pbox[i].y2 - vmesa->drawY; - } - } - - if (nr == nbox) { - sysCmd.discard = 1; - } - - via_flush_sys(vmesa, &sysCmd); - } - } - - if (VIA_DEBUG) { - GLuint i; - GLuint *data = (GLuint *)vmesa->dmaAddr; - for (i = 0; i < vmesa->dmaLow; i += 16) { - fprintf(stderr, "%04x: ", i); - fprintf(stderr, "%08x ", *data++); - fprintf(stderr, "%08x ", *data++); - fprintf(stderr, "%08x ", *data++); - fprintf(stderr, "%08x\n", *data++); - } - fprintf(stderr, "******************************************\n"); - } - - done: - /* Reset vmesa vars: - */ - vmesa->dmaLow = DMA_OFFSET; - vmesa->dmaAddr = (unsigned char *)vmesa->dma; -} - -void viaFlushPrims(viaContextPtr vmesa) -{ - if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__); - - if (vmesa->dmaLow != DMA_OFFSET) { - LOCK_HARDWARE(vmesa); - viaFlushPrimsLocked(vmesa); - UNLOCK_HARDWARE(vmesa); - } - if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__); -} - -static void viaFlush(GLcontext *ctx) -{ - viaContextPtr vmesa = VIA_CONTEXT(ctx); - VIA_FLUSH_DMA(vmesa); -} - -static void viaFinish(GLcontext *ctx) -{ - viaContextPtr vmesa = VIA_CONTEXT(ctx); - VIA_FLUSH_DMA(vmesa); - WAIT_IDLE(vmesa); -} - -static void viaClearStencil(GLcontext *ctx, int s) -{ - return; -} - -void viaInitIoctlFuncs(GLcontext *ctx) -{ - ctx->Driver.Flush = viaFlush; - ctx->Driver.Clear = viaClear; - ctx->Driver.Finish = viaFinish; - ctx->Driver.ClearStencil = viaClearStencil; -} - - #define SetReg2DAGP(nReg, nData) do { \ OUT_RING( ((nReg) >> 2) | 0xF0000000 ); \ OUT_RING( nData ); \ @@ -743,212 +166,572 @@ static void viaBlit(viaContextPtr vmesa, GLuint bpp,GLuint srcBase, ADVANCE_RING(); } -void viaFillFrontBuffer(viaContextPtr vmesa) +static void viaFillBuffer(viaContextPtr vmesa, + viaBuffer *buffer, + drm_clip_rect_t *pbox, + int nboxes, + GLuint pixel, + GLuint mask) { - GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight,i; - drm_clip_rect_t *b = vmesa->sarea->boxes; - GLuint pixel = (GLuint)vmesa->ClearColor; - GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3; - nDestPitch = vmesa->front.pitch; + GLuint bytePerPixel = buffer->bpp >> 3; + GLuint i; - for (i = 0; i < vmesa->sarea->nbox ; i++) { - nDestWidth = b->x2 - b->x1; - nDestHeight = b->y2 - b->y1; - nDestBase = vmesa->viaScreen->fbOffset + - (b->y1* nDestPitch + b->x1 * bytePerPixel); - viaBlit(vmesa,vmesa->viaScreen->bitsPerPixel, nDestBase, nDestPitch, - nDestBase , nDestPitch, nDestWidth, nDestHeight, - 0,0,VIA_BLIT_FILL, pixel, 0x0); - b++; - } + for (i = 0; i < nboxes ; i++) { + int x = pbox[i].x1 - vmesa->drawX; + int y = pbox[i].y1 - vmesa->drawY; + int w = pbox[i].x2 - pbox[i].x1; + int h = pbox[i].y2 - pbox[i].y1; - viaFlushPrimsLocked(vmesa); + int offset = (buffer->orig + + y * buffer->pitch + + x * bytePerPixel); + + viaBlit(vmesa, + buffer->bpp, + offset, buffer->pitch, + offset, buffer->pitch, + w, h, + 0, 0, + VIA_BLIT_FILL, pixel, mask); + } } -void viaFillFrontPBuffer(viaContextPtr vmesa) + + +static void viaClear(GLcontext *ctx, GLbitfield mask, GLboolean all, + GLint cx, GLint cy, GLint cw, GLint ch) { - GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight, offset; - GLuint pixel = (GLuint)vmesa->ClearColor; + viaContextPtr vmesa = VIA_CONTEXT(ctx); + __DRIdrawablePrivate *dPriv = vmesa->driDrawable; + const GLuint colorMask = *((GLuint *)&ctx->Color.ColorMask); + int flag = 0; + GLuint i = 0; + GLuint clear_depth_mask = 0xf << 28; + GLuint clear_depth = 0; - offset = vmesa->front.offset; - if (VIA_DEBUG) fprintf(stderr, "Fill PFront offset = %08x\n", offset); - nDestBase = offset; - nDestPitch = vmesa->front.pitch; + VIA_FLUSH_DMA(vmesa); - nDestWidth = vmesa->driDrawable->w; - nDestHeight = vmesa->driDrawable->h; + if ((mask & DD_FRONT_LEFT_BIT) && colorMask == ~0) { + flag |= VIA_FRONT; + mask &= ~DD_FRONT_LEFT_BIT; + } - viaBlit(vmesa,vmesa->viaScreen->bitsPerPixel, nDestBase, nDestPitch, - nDestBase , nDestPitch, nDestWidth, nDestHeight, - 0,0,VIA_BLIT_FILL, pixel, 0x0); - - viaFlushPrimsLocked(vmesa); -} + if ((mask & DD_BACK_LEFT_BIT) && colorMask == ~0) { + flag |= VIA_BACK; + mask &= ~DD_BACK_LEFT_BIT; + } -void viaFillBackBuffer(viaContextPtr vmesa) -{ - GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight, offset; - GLcontext *ctx = vmesa->glCtx; - GLuint pixel = (GLuint)vmesa->ClearColor; - GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3; - - offset = vmesa->back.offset; - if (VIA_DEBUG) fprintf(stderr, "Fill Back offset = %08x\n", offset); - nDestBase = offset; - nDestPitch = vmesa->back.pitch; + if (mask & DD_DEPTH_BIT) { + flag |= VIA_DEPTH; + clear_depth = (GLuint)(ctx->Depth.Clear * vmesa->ClearDepth); + clear_depth_mask &= ~vmesa->depth_clear_mask; + mask &= ~DD_DEPTH_BIT; + } - if (!ctx->Scissor.Enabled) { - nDestWidth = (vmesa->back.pitch / bytePerPixel); - nDestHeight = vmesa->driDrawable->h; - viaBlit(vmesa,vmesa->viaScreen->bitsPerPixel, nDestBase, nDestPitch, - nDestBase , nDestPitch, nDestWidth, nDestHeight, - 0,0,VIA_BLIT_FILL, pixel, 0x0); + if (mask & DD_STENCIL_BIT) { + if (vmesa->have_hw_stencil) { + if (ctx->Stencil.WriteMask[0] == 0xff) { + flag |= VIA_DEPTH; + clear_depth &= ~0xff; + clear_depth |= (ctx->Stencil.Clear & 0xff); + clear_depth_mask &= ~vmesa->stencil_clear_mask; + mask &= ~DD_STENCIL_BIT; + } + else { + fprintf(stderr, "XXX: Clear stencil writemask %x -- need triangles (or a ROP?)\n", + ctx->Stencil.WriteMask[0]); + /* Fixme - clear with triangles */ + } + } + } + + if (flag) { + drm_clip_rect_t *boxes, *tmp_boxes = 0; + int nr = 0; + + LOCK_HARDWARE(vmesa); + + /* flip top to bottom */ + cy = dPriv->h - cy - ch; + cx += vmesa->drawX + vmesa->drawXoff; + cy += vmesa->drawY; + + if (!all) { + drm_clip_rect_t *b = vmesa->pClipRects; + + boxes = tmp_boxes = (drm_clip_rect_t *)malloc(vmesa->numClipRects * + sizeof(drm_clip_rect_t)); + if (!boxes) { + UNLOCK_HARDWARE(vmesa); + return; + } + + for (; i < vmesa->numClipRects; i++) { + GLint x = b[i].x1; + GLint y = b[i].y1; + GLint w = b[i].x2 - x; + GLint h = b[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; + + boxes[nr].x1 = x; + boxes[nr].y1 = y; + boxes[nr].x2 = x + w; + boxes[nr].y2 = y + h; + nr++; + } + } + else { + boxes = vmesa->pClipRects; + nr = vmesa->numClipRects; + } + + if (flag & VIA_FRONT) { + viaFillBuffer(vmesa, &vmesa->front, boxes, nr, vmesa->ClearColor, 0); + } + + if (flag & VIA_BACK) { + viaFillBuffer(vmesa, &vmesa->back, boxes, nr, vmesa->ClearColor, 0); /* FIXME: masks */ + } + + if (flag & VIA_DEPTH) { + viaFillBuffer(vmesa, &vmesa->depth, boxes, nr, clear_depth, clear_depth_mask); + } + + viaFlushDmaLocked(vmesa, VIA_NO_CLIPRECTS); + UNLOCK_HARDWARE(vmesa); + + if (tmp_boxes) + free(tmp_boxes); + } + + if (mask) + _swrast_Clear(ctx, mask, all, cx, cy, cw, ch); +} + + + + +static void viaDoSwapBuffers(viaContextPtr vmesa, + drm_clip_rect_t *b, + GLuint nbox) +{ + GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3; + viaBuffer *front = &vmesa->front; + viaBuffer *back = &vmesa->back; + GLuint i; + + for (i = 0; i < nbox; i++, b++) { + GLint x = b->x1 - vmesa->drawX; + GLint y = b->y1 - vmesa->drawY; + GLint w = b->x2 - b->x1; + GLint h = b->y2 - b->y1; + GLuint src = back->orig + y * back->pitch + x * bytePerPixel; + GLuint dest = front->orig + y * front->pitch + x * bytePerPixel; + + viaBlit(vmesa, + bytePerPixel << 3, + src, back->pitch, + dest, front->pitch, + w, h, + 0,0,VIA_BLIT_COPY, 0, 0); + } +} + + + + +/* + * Copy the back buffer to the front buffer. + */ +void viaCopyBuffer(const __DRIdrawablePrivate *dPriv) +{ + viaContextPtr vmesa = (viaContextPtr)dPriv->driContextPriv->driverPrivate; + GLboolean missed_target; + + VIA_FLUSH_DMA(vmesa); + driWaitForVBlank( dPriv, & vmesa->vbl_seq, vmesa->vblank_flags, & missed_target ); + if ( missed_target ) { + vmesa->swap_missed_count++; + vmesa->get_ust( &vmesa->swap_missed_ust ); + } + LOCK_HARDWARE(vmesa); + + viaDoSwapBuffers(vmesa, dPriv->pClipRects, dPriv->numClipRects); + viaFlushDmaLocked(vmesa, VIA_NO_CLIPRECTS); + + UNLOCK_HARDWARE(vmesa); + vmesa->swap_count++; + vmesa->get_ust( &vmesa->swap_ust ); +} + +/* + * XXX implement when full-screen extension is done. + */ +void viaPageFlip(const __DRIdrawablePrivate *dPriv) +{ + viaContextPtr vmesa = (viaContextPtr)dPriv->driContextPriv->driverPrivate; + viaBuffer buffer_tmp; + GLboolean missed_target; + + + VIA_FLUSH_DMA(vmesa); + driWaitForVBlank( dPriv, &vmesa->vbl_seq, vmesa->vblank_flags, &missed_target ); + if ( missed_target ) { + vmesa->swap_missed_count++; + vmesa->get_ust( &vmesa->swap_missed_ust ); } - /*=* John Sheng [2003.7.18] texenv *=*/ - else { - int i; - drm_clip_rect_t *b = vmesa->sarea->boxes; - for (i = 0; i < vmesa->sarea->nbox ; i++) { - nDestWidth = b->x2 - b->x1; - nDestHeight = b->y2 - b->y1; - nDestBase = offset + ((b->y1 - vmesa->drawY) * nDestPitch) + - (b->x1 - vmesa->drawX + vmesa->drawXoff) * bytePerPixel; - viaBlit(vmesa,vmesa->viaScreen->bitsPerPixel, nDestBase, nDestPitch, - nDestBase , nDestPitch, nDestWidth, nDestHeight, - 0,0,VIA_BLIT_FILL, pixel, 0x0); - b++; + LOCK_HARDWARE(vmesa); + + { + RING_VARS; + + if (!vmesa->nDoneFirstFlip) { + vmesa->nDoneFirstFlip = GL_FALSE; /* XXX: FIXME LATER!!! */ + BEGIN_RING(4); + OUT_RING(HALCYON_HEADER2); + OUT_RING(0x00fe0000); + OUT_RING(0x0000000e); + OUT_RING(0x0000000e); + ADVANCE_RING(); } + + BEGIN_RING(4); + OUT_RING( HALCYON_HEADER2 ); + OUT_RING( 0x00fe0000 ); + OUT_RING((HC_SubA_HFBBasL << 24) | (vmesa->back.offset & 0xFFFFF8) | 0x2); + OUT_RING((HC_SubA_HFBDrawFirst << 24) | + ((vmesa->back.offset & 0xFF000000) >> 24) | 0x0100); + ADVANCE_RING(); + } - if (VIA_DEBUG) { - fprintf(stderr," width = %08x\n", nDestWidth); - fprintf(stderr," height = %08x\n", nDestHeight); - } + + viaFlushDmaLocked(vmesa, VIA_NO_CLIPRECTS); + UNLOCK_HARDWARE(vmesa); + vmesa->swap_count++; + vmesa->get_ust( &vmesa->swap_ust ); + + /* KW: FIXME: When buffers are freed, could free frontbuffer by + * accident: + */ + memcpy(&buffer_tmp, &vmesa->back, sizeof(viaBuffer)); + memcpy(&vmesa->back, &vmesa->front, sizeof(viaBuffer)); + memcpy(&vmesa->front, &buffer_tmp, sizeof(viaBuffer)); + + if(vmesa->currentPage) { + vmesa->currentPage = 0; + } + else { + vmesa->currentPage = 1; + } + + if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); } -void viaFillDepthBuffer(viaContextPtr vmesa, GLuint pixel, GLuint mask) + + +#define VIA_CMDBUF_MAX_LAG 50000 + +static int fire_buffer(viaContextPtr vmesa) { - GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight, offsetX, offset; + drmVIACommandBuffer bufI; + int ret; - offset = vmesa->depth.offset; - if (VIA_DEBUG) - fprintf(stderr, "Fill Depth offset = %08x, pixel %x, mask %x\n", offset, pixel, mask); - nDestBase = offset; - nDestPitch = vmesa->depth.pitch; - - offsetX = vmesa->drawXoff; - nDestWidth = (vmesa->depth.pitch / vmesa->depth.bpp * 8) - offsetX; - nDestHeight = vmesa->driDrawable->h; + bufI.buf = (char *)vmesa->dma; + bufI.size = vmesa->dmaLow; - viaBlit(vmesa, vmesa->depth.bpp , nDestBase, nDestPitch, - nDestBase , nDestPitch, nDestWidth, nDestHeight, - 0,0,VIA_BLIT_FILL, pixel, mask); + if (vmesa->useAgp) { + drmVIACmdBufSize bSiz; - - if (vmesa->glCtx->Color._DrawDestMask[0] == DD_BACK_LEFT_BIT) { - viaFlushPrimsLocked(vmesa); - } -} + /* Do the CMDBUF_SIZE ioctl: + */ + bSiz.func = VIA_CMDBUF_LAG; + bSiz.wait = 1; + bSiz.size = VIA_CMDBUF_MAX_LAG; + do { + ret = drmCommandWriteRead(vmesa->driFd, DRM_VIA_CMDBUF_SIZE, + &bSiz, sizeof(bSiz)); + } while (ret == -EAGAIN); + if (ret) { + fprintf(stderr, "%s: DRM_VIA_CMDBUF_SIZE returned %d\n", __FUNCTION__, ret); + abort(); + return ret; + } -void viaDoSwapBuffers(viaContextPtr vmesa) -{ - GLuint nFrontPitch; - GLuint nBackPitch; - GLuint nFrontWidth, nFrontHeight; - GLuint nFrontBase, nBackBase; - drm_clip_rect_t *b = vmesa->pClipRects; - GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3; - GLuint i; - - nFrontPitch = vmesa->front.pitch; - nBackPitch = vmesa->back.pitch; - - for (i = 0; i < vmesa->numClipRects; i++) { + /* Acutally fire the buffer: + */ + do { + ret = drmCommandWrite(vmesa->driFd, DRM_VIA_CMDBUFFER, + &bufI, sizeof(bufI)); + } while (ret == -EAGAIN); + if (ret) { + fprintf(stderr, "%s: DRM_VIA_CMDBUFFER returned %d\n", __FUNCTION__, ret); + abort(); + /* If this fails, the original code fell back to the PCI path. + */ + } + else + return 0; - /* Width, Height */ - nFrontWidth = b->x2 - b->x1; - nFrontHeight = b->y2 - b->y1; - - nFrontBase = vmesa->viaScreen->fbOffset + (b->y1* nFrontPitch + - b->x1 * bytePerPixel); - nBackBase = vmesa->back.offset + ((b->y1 - vmesa->drawY) * nBackPitch) + - (b->x1 - vmesa->drawX + vmesa->drawXoff) * bytePerPixel; - - viaBlit(vmesa, bytePerPixel << 3 , nBackBase, nBackPitch, - nFrontBase , nFrontPitch, nFrontWidth, nFrontHeight, - 0,0,VIA_BLIT_COPY, 0, 0); - b++; - } + /* Fall through to PCI handling?!? + */ + WAIT_IDLE(vmesa); + } + + ret = drmCommandWrite(vmesa->driFd, DRM_VIA_PCICMD, &bufI, sizeof(bufI)); + if (ret) { + fprintf(stderr, "%s: DRM_VIA_PCICMD returned %d\n", __FUNCTION__, ret); + abort(); + } - viaFlushPrimsLocked(vmesa); - if (VIA_DEBUG) fprintf(stderr, "Do Swap Buffer\n"); + return ret; } -void viaDoSwapPBuffers(viaContextPtr vmesa) -{ - GLuint nFrontPitch; - GLuint nBackPitch; - GLuint nFrontWidth, nFrontHeight; - GLuint nFrontBase, nBackBase; - GLuint nFrontOffsetX, nFrontOffsetY, nBackOffsetX, nBackOffsetY; - GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3; - GLuint EngStatus = *(vmesa->pnGEMode); - GLuint blitMode; - RING_VARS; +/* Inserts the surface addresss and active cliprects one at a time + * into the head of the DMA buffer being flushed. Fires the buffer + * for each cliprect. + */ +static void via_emit_cliprect(viaContextPtr vmesa, + drm_clip_rect_t *b) +{ + viaBuffer *buffer = vmesa->drawBuffer; + GLuint *vb = (GLuint *)(vmesa->dma + vmesa->dmaCliprectAddr); - switch(bytePerPixel) { - case 4: - blitMode = 0x300; - break; - case 2: - blitMode = 0x100; - break; - default: - blitMode = 0x000; - break; - } + GLuint format = (vmesa->viaScreen->bitsPerPixel == 0x20 + ? HC_HDBFM_ARGB8888 + : HC_HDBFM_RGB565); - nFrontPitch = vmesa->front.pitch; - nBackPitch = vmesa->back.pitch; - - /* Caculate Base */ - nFrontBase = vmesa->front.offset; - nBackBase = vmesa->back.offset; - - /* Width, Height */ - nFrontWidth = nFrontPitch / bytePerPixel; - nFrontHeight = nBackPitch / bytePerPixel; - - /* Offset */ - nFrontOffsetX = 0; - nFrontOffsetY = 0; - nBackOffsetX = nFrontOffsetX; - nBackOffsetY = nFrontOffsetY; + GLuint pitch = buffer->pitch; + GLuint offset = buffer->orig; - BEGIN_RING(8 * 2); - /* Restore mode */ - SetReg2DAGP(0x04, (EngStatus & 0xFFFFFCFF) | blitMode); - /* GEWD */ - SetReg2DAGP(0x10, nFrontWidth | (nFrontHeight << 16)); - /* GEDST */ - SetReg2DAGP(0x0C, nFrontOffsetX | (nFrontOffsetY << 16)); - /* GESRC */ - SetReg2DAGP(0x08, nBackOffsetX | (nBackOffsetY << 16)); - /* GEDSTBASE */ - SetReg2DAGP(0x34, (nFrontBase >> 3)); - /* GESCRBASE */ - SetReg2DAGP(0x30, (nBackBase >> 3)); - /* GEPITCH */ - SetReg2DAGP(0x38, (((nFrontPitch >> 3) << 16) & 0x7FF0000) | 0x80000000 | - ((nBackPitch >> 3) & 0x7FF)); - /* BITBLT */ - SetReg2DAGP(0x0, 0x1 | 0xCC000000); - ADVANCE_RING(); + GLuint clipL = b->x1 - vmesa->drawX; + GLuint clipR = b->x2 - vmesa->drawX; + GLuint clipT = b->y1 - vmesa->drawY; + GLuint clipB = b->y2 - vmesa->drawY; + + vb[0] = HC_HEADER2; + vb[1] = (HC_ParaType_NotTex << 16); - viaFlushPrimsLocked(vmesa); - if (VIA_DEBUG) fprintf(stderr, "Do Swap PBuffer\n"); + if (vmesa->driDrawable->w == 0 || vmesa->driDrawable->h == 0) { + vb[2] = (HC_SubA_HClipTB << 24) | 0x0; + vb[3] = (HC_SubA_HClipLR << 24) | 0x0; + } + else { + vb[2] = (HC_SubA_HClipTB << 24) | (clipT << 12) | clipB; + vb[3] = (HC_SubA_HClipLR << 24) | (clipL << 12) | clipR; + } + + vb[4] = ((HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF)); + vb[5] = ((HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000)) >> 24); + vb[6] = ((HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch); + vb[7] = 0xcccccccc; +} + + + +static int intersect_rect(drm_clip_rect_t *out, + drm_clip_rect_t *a, + drm_clip_rect_t *b) +{ + *out = *a; + + if (b->x1 > out->x1) out->x1 = b->x1; + if (b->x2 < out->x2) out->x2 = b->x2; + if (out->x1 >= out->x2) return 0; + + if (b->y1 > out->y1) out->y1 = b->y1; + if (b->y2 < out->y2) out->y2 = b->y2; + if (out->y1 >= out->y2) return 0; + + return 1; +} + +static void dump_dma( viaContextPtr vmesa ) +{ + GLuint i; + GLuint *data = (GLuint *)vmesa->dma; + for (i = 0; i < vmesa->dmaLow; i += 16) { + fprintf(stderr, "%04x: ", i); + fprintf(stderr, "%08x ", *data++); + fprintf(stderr, "%08x ", *data++); + fprintf(stderr, "%08x ", *data++); + fprintf(stderr, "%08x\n", *data++); + } + fprintf(stderr, "******************************************\n"); +} + + +void viaFlushDmaLocked(viaContextPtr vmesa, GLuint flags) +{ + int i; + RING_VARS; + + if (*(GLuint *)vmesa->driHwLock != (DRM_LOCK_HELD|vmesa->hHWContext) && + *(GLuint *)vmesa->driHwLock != (DRM_LOCK_HELD|DRM_LOCK_CONT|vmesa->hHWContext)) { + fprintf(stderr, "%s called without lock held\n", __FUNCTION__); + abort(); + } + + if (vmesa->dmaLow == 0) { + return; + } + + assert(vmesa->dmaLastPrim == 0); + + /* viaFinishPrimitive can add up to 8 bytes beyond VIA_DMA_HIGHWATER: + */ + if (vmesa->dmaLow > VIA_DMA_HIGHWATER + 8) { + fprintf(stderr, "buffer overflow in Flush Prims = %d\n",vmesa->dmaLow); + abort(); + } + + switch (vmesa->dmaLow & 0x1F) { + case 8: + BEGIN_RING_NOCHECK( 6 ); + OUT_RING( HC_HEADER2 ); + OUT_RING( (HC_ParaType_NotTex << 16) ); + OUT_RING( HC_DUMMY ); + OUT_RING( HC_DUMMY ); + OUT_RING( HC_DUMMY ); + OUT_RING( HC_DUMMY ); + ADVANCE_RING(); + break; + case 16: + BEGIN_RING_NOCHECK( 4 ); + OUT_RING( HC_HEADER2 ); + OUT_RING( (HC_ParaType_NotTex << 16) ); + OUT_RING( HC_DUMMY ); + OUT_RING( HC_DUMMY ); + ADVANCE_RING(); + break; + case 24: + BEGIN_RING_NOCHECK( 10 ); + OUT_RING( HC_HEADER2 ); + OUT_RING( (HC_ParaType_NotTex << 16) ); + OUT_RING( HC_DUMMY ); + OUT_RING( HC_DUMMY ); + OUT_RING( HC_DUMMY ); + OUT_RING( HC_DUMMY ); + OUT_RING( HC_DUMMY ); + OUT_RING( HC_DUMMY ); + OUT_RING( HC_DUMMY ); + OUT_RING( HC_DUMMY ); + ADVANCE_RING(); + break; + case 0: + break; + default: + if (VIA_DEBUG) + fprintf(stderr, "%s: unaligned value for vmesa->dmaLow: %x\n", + __FUNCTION__, vmesa->dmaLow); + } + + + if (VIA_DEBUG) + dump_dma( vmesa ); + + if (flags & VIA_NO_CLIPRECTS) { + assert(vmesa->dmaCliprectAddr == 0); + fire_buffer( vmesa ); + } + else if (!vmesa->dmaCliprectAddr) { + /* Contains only state. Could just dump the packet? + */ + if (0) fprintf(stderr, "no dmaCliprectAddr\n"); + if (0) fire_buffer( vmesa ); + } + else if (vmesa->numClipRects) { + int ret; + drm_clip_rect_t *pbox = vmesa->pClipRects; + + for (i = 0; i < vmesa->numClipRects; i++) { + if (vmesa->glCtx->Scissor.Enabled) { + drm_clip_rect_t b; + if (!intersect_rect(&b, &pbox[i], &vmesa->scissorRect)) + continue; + via_emit_cliprect(vmesa, &b); + } + else { + via_emit_cliprect(vmesa, &pbox[i]); + } + + ret = fire_buffer(vmesa); + if (ret) + goto done; + } + } else { + UNLOCK_HARDWARE(vmesa); + sched_yield(); + LOCK_HARDWARE(vmesa); + } + + done: + /* Reset vmesa vars: + */ + vmesa->dmaLow = 0; + vmesa->dmaCliprectAddr = 0; + viaValidateState(vmesa->glCtx); +} + +void viaWrapPrimitive( viaContextPtr vmesa ) +{ + if (VIA_DEBUG) fprintf(stderr, "%s\n", __FUNCTION__); + viaFinishPrimitive( vmesa ); + + LOCK_HARDWARE(vmesa); + viaFlushDmaLocked(vmesa, 0); + UNLOCK_HARDWARE(vmesa); + + viaRasterPrimitive( vmesa->glCtx, + vmesa->renderPrimitive, + vmesa->hwPrimitive ); +} + +void viaFlushDma(viaContextPtr vmesa) +{ + if (vmesa->dmaLow) { + if (vmesa->dmaLastPrim) + viaWrapPrimitive(vmesa); + else { + LOCK_HARDWARE(vmesa); + viaFlushDmaLocked(vmesa, 0); + UNLOCK_HARDWARE(vmesa); + } + } +} + +static void viaFlush(GLcontext *ctx) +{ + viaContextPtr vmesa = VIA_CONTEXT(ctx); + VIA_FLUSH_DMA(vmesa); +} + +static void viaFinish(GLcontext *ctx) +{ + viaContextPtr vmesa = VIA_CONTEXT(ctx); + VIA_FLUSH_DMA(vmesa); + WAIT_IDLE(vmesa); +} + +static void viaClearStencil(GLcontext *ctx, int s) +{ + return; +} + +void viaInitIoctlFuncs(GLcontext *ctx) +{ + ctx->Driver.Flush = viaFlush; + ctx->Driver.Clear = viaClear; + ctx->Driver.Finish = viaFinish; + ctx->Driver.ClearStencil = viaClearStencil; } @@ -956,19 +739,19 @@ void viaDoSwapPBuffers(viaContextPtr vmesa) GLuint *viaAllocDmaFunc(viaContextPtr vmesa, int bytes, const char *func, int line) { - if (vmesa->dmaLow + bytes > VIA_DMA_HIGHWATER) { - if (VIA_DEBUG) fprintf(stderr, "buffer overflow in check dma = %d + %d = %d\n", - vmesa->dmaLow, bytes, vmesa->dmaLow + bytes); - viaFlushPrims(vmesa); - } + if (vmesa->dmaLow + bytes > VIA_DMA_HIGHWATER) { + if (VIA_DEBUG) fprintf(stderr, "buffer overflow in check dma = %d + %d = %d\n", + vmesa->dmaLow, bytes, vmesa->dmaLow + bytes); + viaFlushDma(vmesa); + } - { - GLuint *start = (GLuint *)(vmesa->dmaAddr + vmesa->dmaLow); - vmesa->dmaLow += bytes; - if (VIA_DEBUG && (vmesa->dmaLow & 0x4)) - fprintf(stderr, "%s/%d: alloc 0x%x --> dmaLow 0x%x\n", func, line, bytes, vmesa->dmaLow); - return start; - } + { + GLuint *start = (GLuint *)(vmesa->dma + vmesa->dmaLow); + vmesa->dmaLow += bytes; + if (VIA_DEBUG && (vmesa->dmaLow & 0x4)) + fprintf(stderr, "%s/%d: alloc 0x%x --> dmaLow 0x%x\n", func, line, bytes, vmesa->dmaLow); + return start; + } } diff --git a/src/mesa/drivers/dri/unichrome/via_ioctl.h b/src/mesa/drivers/dri/unichrome/via_ioctl.h index 193aab8a990..ddb75ba6b81 100644 --- a/src/mesa/drivers/dri/unichrome/via_ioctl.h +++ b/src/mesa/drivers/dri/unichrome/via_ioctl.h @@ -29,18 +29,12 @@ void viaFinishPrimitive(viaContextPtr vmesa); -void viaFlushPrims(viaContextPtr vmesa); -void viaFlushPrimsLocked(viaContextPtr vmesa); +void viaFlushDma(viaContextPtr vmesa); +void viaFlushDmaLocked(viaContextPtr vmesa, GLuint flags); void viaInitIoctlFuncs(GLcontext *ctx); void viaCopyBuffer(const __DRIdrawablePrivate *dpriv); void viaPageFlip(const __DRIdrawablePrivate *dpriv); -void viaFillFrontBuffer(viaContextPtr vmesa); -void viaFillFrontPBuffer(viaContextPtr vmesa); -void viaFillBackBuffer(viaContextPtr vmesa); -void viaFillDepthBuffer(viaContextPtr vmesa, GLuint pixel, GLuint mask); -void viaDoSwapBuffers(viaContextPtr vmesa); -void viaDoSwapPBuffers(viaContextPtr vmesa); void viaCheckDma(viaContextPtr vmesa, GLuint bytes); #define VIA_FINISH_PRIM(vmesa) do { \ @@ -50,8 +44,8 @@ void viaCheckDma(viaContextPtr vmesa, GLuint bytes); #define VIA_FLUSH_DMA(vmesa) do { \ VIA_FINISH_PRIM(vmesa); \ - if (vmesa->dmaLow != DMA_OFFSET) \ - viaFlushPrims(vmesa); \ + if (vmesa->dmaLow) \ + viaFlushDma(vmesa); \ } while (0) @@ -59,12 +53,6 @@ GLuint *viaAllocDmaFunc(viaContextPtr vmesa, int bytes, const char *func, int li #define viaAllocDma( v, b ) viaAllocDmaFunc(v, b, __FUNCTION__, __LINE__) - -/* Room for the cliprect and other preamble at the head of each dma - * buffer: (What about buffers which only contain blits?) - */ -#define DMA_OFFSET 32 - #define RING_VARS GLuint *_vb = 0, _nr, _x; #define BEGIN_RING(n) do { \ @@ -76,7 +64,7 @@ GLuint *viaAllocDmaFunc(viaContextPtr vmesa, int bytes, const char *func, int li #define BEGIN_RING_NOCHECK(n) do { \ if (_vb != 0) abort(); \ - _vb = (GLuint *)(vmesa->dmaAddr + vmesa->dmaLow); \ + _vb = (GLuint *)(vmesa->dma + vmesa->dmaLow); \ vmesa->dmaLow += (n) * sizeof(GLuint); \ _nr = (n); \ _x = 0; \ diff --git a/src/mesa/drivers/dri/unichrome/via_span.c b/src/mesa/drivers/dri/unichrome/via_span.c index 9578af3b657..4fdfec3eaa6 100644 --- a/src/mesa/drivers/dri/unichrome/via_span.c +++ b/src/mesa/drivers/dri/unichrome/via_span.c @@ -36,9 +36,9 @@ #define LOCAL_DEPTH_VARS \ __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \ viaScreenPrivate *viaScreen = vmesa->viaScreen; \ - GLuint pitch = viaScreen->backPitch; \ + GLuint depth_pitch = vmesa->depth.pitch; \ GLuint height = dPriv->h; \ - char *buf = (char *)(vmesa->depth.map) + char *buf = (char *)(vmesa->depth.map + (vmesa->drawXoff * vmesa->depth.bpp/8)) #define CLIPPIXEL(_x,_y) (_x >= minx && _x < maxx && \ _y >= miny && _y < maxy) @@ -63,10 +63,10 @@ __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \ int _nc = dPriv->numClipRects; \ while (_nc--) { \ - int minx = dPriv->pClipRects[_nc].x1 - dPriv->x; \ - int miny = dPriv->pClipRects[_nc].y1 - dPriv->y; \ - int maxx = dPriv->pClipRects[_nc].x2 - dPriv->x; \ - int maxy = dPriv->pClipRects[_nc].y2 - dPriv->y; + int minx = dPriv->pClipRects[_nc].x1 - vmesa->drawX; \ + int miny = dPriv->pClipRects[_nc].y1 - vmesa->drawY; \ + int maxx = dPriv->pClipRects[_nc].x2 - vmesa->drawX; \ + int maxy = dPriv->pClipRects[_nc].y2 - vmesa->drawY; #define HW_ENDCLIPLOOP() \ @@ -81,38 +81,28 @@ #define LOCAL_VARS \ viaContextPtr vmesa = VIA_CONTEXT(ctx); \ __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \ - GLuint pitch = vmesa->drawPitch; \ + GLuint draw_pitch = vmesa->drawBuffer->pitch; \ + GLuint read_pitch = vmesa->readBuffer->pitch; \ GLuint height = dPriv->h; \ - GLushort p; \ - char *buf, *read_buf; \ - p = 0; \ - if (vmesa->glCtx->Color._DrawDestMask[0] == DD_BACK_LEFT_BIT) { \ - buf = (char *)(vmesa->drawMap); \ - read_buf = (char *)(vmesa->readMap); \ - } \ - else { \ - buf = (char *)(vmesa->drawMap + \ - dPriv->x * 2 + \ - dPriv->y * pitch); \ - read_buf = (char *)(vmesa->readMap + \ - dPriv->x * 2 + \ - dPriv->y * pitch); \ - } + GLushort p = 0; \ + char *buf = (char *)(vmesa->drawBuffer->origMap + vmesa->drawXoff * 2); \ + char *read_buf = (char *)(vmesa->readBuffer->origMap + vmesa->drawXoff * 2); \ + (void) (read_pitch && draw_pitch && buf && read_buf && p); #define INIT_MONO_PIXEL(p, color) \ p = PACK_COLOR_565(color[0], color[1], color[2]) #define WRITE_RGBA(_x, _y, r, g, b, a) \ - *(GLushort *)(buf + _x * 2 + _y * pitch) = ((((int)r & 0xf8) << 8) | \ + *(GLushort *)(buf + _x * 2 + _y * draw_pitch) = ((((int)r & 0xf8) << 8) | \ (((int)g & 0xfc) << 3) | \ (((int)b & 0xf8) >> 3)) #define WRITE_PIXEL(_x, _y, p) \ - *(GLushort *)(buf + _x * 2 + _y * pitch) = p + *(GLushort *)(buf + _x * 2 + _y * draw_pitch) = p #define READ_RGBA(rgba, _x, _y) \ do { \ - GLushort p = *(GLushort *)(read_buf + _x * 2 + _y * pitch); \ + GLushort p = *(GLushort *)(read_buf + _x * 2 + _y * read_pitch); \ rgba[0] = ((p >> 8) & 0xf8) * 255 / 0xf8; \ rgba[1] = ((p >> 3) & 0xfc) * 255 / 0xfc; \ rgba[2] = ((p << 3) & 0xf8) * 255 / 0xf8; \ @@ -133,26 +123,16 @@ #define LOCAL_VARS \ viaContextPtr vmesa = VIA_CONTEXT(ctx); \ __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \ - GLuint pitch = vmesa->drawPitch; \ + GLuint draw_pitch = vmesa->drawBuffer->pitch; \ + GLuint read_pitch = vmesa->readBuffer->pitch; \ GLuint height = dPriv->h; \ - GLuint p; \ - char *buf, *read_buf; \ - p = 0; \ - if (vmesa->glCtx->Color._DrawDestMask[0] == DD_BACK_LEFT_BIT) { \ - buf = (char *)(vmesa->drawMap); \ - read_buf = (char *)(vmesa->readMap); \ - } \ - else { \ - buf = (char *)(vmesa->drawMap + \ - dPriv->x * 4 + \ - dPriv->y * pitch); \ - read_buf = (char *)(vmesa->readMap + \ - dPriv->x * 4 + \ - dPriv->y * pitch); \ - } + GLuint p = 0; \ + char *buf = (char *)(vmesa->drawBuffer->origMap + vmesa->drawXoff * 4); \ + char *read_buf = (char *)(vmesa->readBuffer->origMap + vmesa->drawXoff * 4); \ + (void) (read_pitch && draw_pitch && buf && read_buf && p); -#define GET_SRC_PTR(_x, _y) (read_buf + _x * 4 + _y * pitch) -#define GET_DST_PTR(_x, _y) ( buf + _x * 4 + _y * pitch) +#define GET_SRC_PTR(_x, _y) (read_buf + _x * 4 + _y * read_pitch) +#define GET_DST_PTR(_x, _y) ( buf + _x * 4 + _y * draw_pitch) #define SPANTMP_PIXEL_FMT GL_BGRA #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV @@ -166,7 +146,7 @@ #define LOCAL_DEPTH_VARS \ viaContextPtr vmesa = VIA_CONTEXT(ctx); \ __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \ - GLuint pitch = vmesa->depth.pitch; \ + GLuint depth_pitch = vmesa->depth.pitch; \ GLuint height = dPriv->h; \ char *buf = (char *)(vmesa->depth.map) @@ -174,10 +154,10 @@ #define WRITE_DEPTH(_x, _y, d) \ - *(GLushort *)(buf + _x * 2 + _y * pitch) = d; + *(GLushort *)(buf + _x * 2 + _y * depth_pitch) = d; #define READ_DEPTH(d, _x, _y) \ - d = *(GLushort *)(buf + _x * 2 + _y * pitch); + d = *(GLushort *)(buf + _x * 2 + _y * depth_pitch); #define TAG(x) via##x##_16 #include "depthtmp.h" @@ -185,10 +165,10 @@ /* 32 bit depthbuffer functions. */ #define WRITE_DEPTH(_x, _y, d) \ - *(GLuint *)(buf + _x * 4 + _y * pitch) = d; + *(GLuint *)(buf + _x * 4 + _y * depth_pitch) = d; #define READ_DEPTH(d, _x, _y) \ - d = *(GLuint *)(buf + _x * 4 + _y * pitch); + d = *(GLuint *)(buf + _x * 4 + _y * depth_pitch); #define TAG(x) via##x##_32 #include "depthtmp.h" @@ -198,28 +178,28 @@ /* 24/8 bit interleaved depth/stencil functions */ #define WRITE_DEPTH( _x, _y, d ) { \ - GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*pitch); \ + GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch); \ tmp &= 0x000000ff; \ tmp |= ((d)<<8); \ - *(GLuint *)(buf + (_x)*4 + (_y)*pitch) = tmp; \ + *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch) = tmp; \ } #define READ_DEPTH( d, _x, _y ) \ - d = (*(GLuint *)(buf + (_x)*4 + (_y)*pitch)) >> 8; + d = (*(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch)) >> 8; #define TAG(x) via##x##_24_8 #include "depthtmp.h" #define WRITE_STENCIL( _x, _y, d ) { \ - GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*pitch); \ + GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch); \ tmp &= 0xffffff00; \ tmp |= (d); \ - *(GLuint *)(buf + (_x)*4 + (_y)*pitch) = tmp; \ + *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch) = tmp; \ } #define READ_STENCIL( d, _x, _y ) \ - d = *(GLuint *)(buf + (_x)*4 + (_y)*pitch) & 0xff; + d = *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch) & 0xff; #define TAG(x) via##x##_24_8 #include "stenciltmp.h" @@ -230,23 +210,16 @@ static void viaSetBuffer(GLcontext *ctx, GLframebuffer *colorBuffer, GLuint bufferBit) { viaContextPtr vmesa = VIA_CONTEXT(ctx); - if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__); + if (bufferBit == DD_FRONT_LEFT_BIT) { - vmesa->drawMap = (char *)vmesa->driScreen->pFB; - vmesa->readMap = (char *)vmesa->driScreen->pFB; - vmesa->drawPitch = vmesa->front.pitch; - vmesa->readPitch = vmesa->front.pitch; + vmesa->drawBuffer = vmesa->readBuffer = &vmesa->front; } else if (bufferBit == DD_BACK_LEFT_BIT) { - vmesa->drawMap = vmesa->back.map; - vmesa->readMap = vmesa->back.map; - vmesa->drawPitch = vmesa->back.pitch; - vmesa->readPitch = vmesa->back.pitch; + vmesa->drawBuffer = vmesa->readBuffer = &vmesa->back; } else { ASSERT(0); } - if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__); } /* Move locking out to get reasonable span performance. @@ -256,7 +229,7 @@ void viaSpanRenderStart( GLcontext *ctx ) viaContextPtr vmesa = VIA_CONTEXT(ctx); VIA_FINISH_PRIM(vmesa); LOCK_HARDWARE(vmesa); - viaFlushPrimsLocked(vmesa); + viaFlushDmaLocked(vmesa, 0); WAIT_IDLE(vmesa); } diff --git a/src/mesa/drivers/dri/unichrome/via_state.c b/src/mesa/drivers/dri/unichrome/via_state.c index e9f0d6682f9..ef3846106d0 100644 --- a/src/mesa/drivers/dri/unichrome/via_state.c +++ b/src/mesa/drivers/dri/unichrome/via_state.c @@ -642,21 +642,13 @@ static void viaDrawBuffer(GLcontext *ctx, GLenum mode) if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__); if (mode == GL_FRONT) { VIA_FLUSH_DMA(vmesa); - vmesa->drawMap = (char *)vmesa->driScreen->pFB; - vmesa->readMap = (char *)vmesa->driScreen->pFB; - vmesa->drawPitch = vmesa->front.pitch; - vmesa->readPitch = vmesa->front.pitch; - viaXMesaSetFrontClipRects(vmesa); + vmesa->drawBuffer = vmesa->readBuffer = &vmesa->front; FALLBACK(vmesa, VIA_FALLBACK_DRAW_BUFFER, GL_FALSE); return; } else if (mode == GL_BACK) { VIA_FLUSH_DMA(vmesa); - vmesa->drawMap = vmesa->back.map; - vmesa->readMap = vmesa->back.map; - vmesa->drawPitch = vmesa->back.pitch; - vmesa->readPitch = vmesa->back.pitch; - viaXMesaSetBackClipRects(vmesa); + vmesa->drawBuffer = vmesa->readBuffer = &vmesa->back; FALLBACK(vmesa, VIA_FALLBACK_DRAW_BUFFER, GL_FALSE); return; } @@ -665,6 +657,8 @@ static void viaDrawBuffer(GLcontext *ctx, GLenum mode) return; } + viaXMesaWindowMoved(vmesa); + /* We want to update the s/w rast state too so that r200SetBuffer() * gets called. */ @@ -693,6 +687,10 @@ static void viaClearColor(GLcontext *ctx, const GLfloat color[4]) */ +/* Using drawXoff like this is incorrect outside of locked regions. + * This hardware just isn't capable of private back buffers without + * glitches and/or a hefty locking scheme. + */ void viaCalcViewport(GLcontext *ctx) { viaContextPtr vmesa = VIA_CONTEXT(ctx); @@ -1550,6 +1548,8 @@ void viaValidateState( GLcontext *ctx ) viaChooseStencilState(ctx); if (!vmesa->Fallback) { + viaChooseVertexState(ctx); + viaChooseRenderState(ctx); via_emit_state(vmesa); vmesa->newState = 0; } diff --git a/src/mesa/drivers/dri/unichrome/via_tris.c b/src/mesa/drivers/dri/unichrome/via_tris.c index b936760dc32..4d2092f3611 100644 --- a/src/mesa/drivers/dri/unichrome/via_tris.c +++ b/src/mesa/drivers/dri/unichrome/via_tris.c @@ -555,7 +555,7 @@ static void viaFastRenderClippedPoly(GLcontext *ctx, const GLuint *elts, #define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK) #define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED) -static void viaChooseRenderState(GLcontext *ctx) +void viaChooseRenderState(GLcontext *ctx) { TNLcontext *tnl = TNL_CONTEXT(ctx); viaContextPtr vmesa = VIA_CONTEXT(ctx); @@ -633,11 +633,6 @@ static void viaRunPipeline(GLcontext *ctx) if (vmesa->newState) { viaValidateState( ctx ); - - if (!vmesa->Fallback) { - viaChooseVertexState(ctx); - viaChooseRenderState(ctx); - } } _tnl_run_pipeline(ctx); @@ -677,9 +672,8 @@ void viaRasterPrimitive(GLcontext *ctx, _mesa_lookup_enum_by_nr(hwprim)); VIA_FINISH_PRIM(vmesa); + viaCheckDma( vmesa, 1024 ); /* Ensure no wrapping inside this function */ - vmesa->renderPrimitive = glprim; - regCmdB = vmesa->regCmdB; switch (hwprim) { @@ -738,7 +732,24 @@ void viaRasterPrimitive(GLcontext *ctx, return; } - assert((vmesa->dmaLow & 0x4) == 0); +/* assert((vmesa->dmaLow & 0x4) == 0); */ + + if (vmesa->dmaCliprectAddr == 0) { + if (VIA_DEBUG) fprintf(stderr, "reserve cliprect space at %x\n", vmesa->dmaLow); + assert(vmesa->dmaLow); + vmesa->dmaCliprectAddr = vmesa->dmaLow; + BEGIN_RING(8); + OUT_RING( HC_HEADER2 ); + OUT_RING( (HC_ParaType_NotTex << 16) ); + OUT_RING( 0xCCCCCCCC ); + OUT_RING( 0xCCCCCCCC ); + OUT_RING( 0xCCCCCCCC ); + OUT_RING( 0xCCCCCCCC ); + OUT_RING( 0xCCCCCCCC ); + OUT_RING( 0xCCCCCCCC ); + ADVANCE_RING(); + } + BEGIN_RING(8); OUT_RING( HC_HEADER2 ); @@ -752,8 +763,10 @@ void viaRasterPrimitive(GLcontext *ctx, OUT_RING( vmesa->regCmdA_End ); ADVANCE_RING(); + + vmesa->renderPrimitive = glprim; + vmesa->hwPrimitive = hwprim; vmesa->dmaLastPrim = vmesa->dmaLow; - vmesa->hwPrimitive = hwprim; } /* Callback for mesa: @@ -766,36 +779,46 @@ static void viaRenderPrimitive( GLcontext *ctx, GLuint prim ) void viaFinishPrimitive(viaContextPtr vmesa) { - if (!vmesa->dmaLastPrim) { - return; - } - else if (vmesa->dmaLow != vmesa->dmaLastPrim) { - GLuint cmdA = vmesa->regCmdA_End | HC_HPLEND_MASK | HC_HPMValidN_MASK | HC_HE3Fire_MASK; - RING_VARS; + if (VIA_DEBUG) fprintf(stderr, "%s\n", __FUNCTION__); - /* KW: modified 0x1 to 0x4 below: - */ - if ((vmesa->dmaLow & 0x1) || !vmesa->useAgp) { - BEGIN_RING_NOCHECK( 1 ); - OUT_RING( cmdA ); - ADVANCE_RING(); - } - else { - BEGIN_RING_NOCHECK( 2 ); - OUT_RING( cmdA ); - OUT_RING( cmdA ); - ADVANCE_RING(); - } - vmesa->dmaLastPrim = 0; + if (!vmesa->dmaLastPrim) { + return; + } + else if (vmesa->dmaLow != vmesa->dmaLastPrim) { + GLuint cmdA = vmesa->regCmdA_End | HC_HPLEND_MASK | HC_HPMValidN_MASK | HC_HE3Fire_MASK; + RING_VARS; - if (1 || vmesa->dmaLow > VIA_DMA_HIGHWATER) - viaFlushPrims( vmesa ); - } - else { - assert(vmesa->dmaLow >= (32 + DMA_OFFSET)); - vmesa->dmaLow -= 32; - vmesa->dmaLastPrim = 0; - } + /* KW: modified 0x1 to 0x4 below: + */ + if ((vmesa->dmaLow & 0x1) || !vmesa->useAgp) { + BEGIN_RING_NOCHECK( 1 ); + OUT_RING( cmdA ); + ADVANCE_RING(); + } + else { + BEGIN_RING_NOCHECK( 2 ); + OUT_RING( cmdA ); + OUT_RING( cmdA ); + ADVANCE_RING(); + } + vmesa->dmaLastPrim = 0; + + if (vmesa->dmaLow > VIA_DMA_HIGHWATER) + viaFlushDma( vmesa ); + } + else { + /* Remove the primitive header: + */ + vmesa->dmaLastPrim = 0; + vmesa->dmaLow -= 8 * sizeof(GLuint); + + /* Maybe remove the cliprect as well: + */ + if (vmesa->dmaCliprectAddr == vmesa->dmaLow - 8 * sizeof(GLuint)) { + vmesa->dmaLow -= 8 * sizeof(GLuint); + vmesa->dmaCliprectAddr = 0; + } + } } diff --git a/src/mesa/drivers/dri/unichrome/via_vb.c b/src/mesa/drivers/dri/unichrome/via_vb.c index 222a0f07ca1..0b6830a6bfb 100644 --- a/src/mesa/drivers/dri/unichrome/via_vb.c +++ b/src/mesa/drivers/dri/unichrome/via_vb.c @@ -86,9 +86,11 @@ static struct { #define HAVE_TEX3_VERTICES 0 #define HAVE_PTEX_VERTICES 0 -#define UNVIEWPORT_VARS GLfloat h = VIA_CONTEXT(ctx)->driDrawable->h, \ - depth_max = VIA_CONTEXT(ctx)->depth_max; -#define UNVIEWPORT_X(x) x - SUBPIXEL_X +#define UNVIEWPORT_VARS \ + viaContextPtr vmesa = VIA_CONTEXT(ctx); \ + GLfloat h = vmesa->driDrawable->h, depth_max = vmesa->depth_max, xoff = vmesa->drawXoff; + +#define UNVIEWPORT_X(x) x - (SUBPIXEL_X + xoff) #define UNVIEWPORT_Y(y) - y + h + SUBPIXEL_Y #define UNVIEWPORT_Z(z) z * (float)depth_max