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 | 129 +-- src/mesa/drivers/dri/unichrome/via_fb.h | 16 +- src/mesa/drivers/dri/unichrome/via_ioctl.c | 865 +++++++------------ 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 | 103 ++- src/mesa/drivers/dri/unichrome/via_vb.c | 8 +- 10 files changed, 613 insertions(+), 1003 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; - - if (vmesa->drawType == GLX_PBUFFER_BIT) { - w = vmesa->driDrawable->w; - h = vmesa->driDrawable->h; - } - else { - w = vmesa->viaScreen->width; - h = vmesa->viaScreen->height; + const unsigned shift = vmesa->viaScreen->bitsPerPixel / 16; + const unsigned extra = 32; + unsigned w; + unsigned h; - vmesa->front.offset = 0; - vmesa->front.map = (char *) vmesa->driScreen->pFB; - } + /* Allocate front-buffer */ + if (vmesa->drawType == GLX_PBUFFER_BIT) { + w = vmesa->driDrawable->w; + h = vmesa->driDrawable->h; - vmesa->front.pitch = buffer_align( w ) << shift; - vmesa->front.size = vmesa->front.pitch * h; + vmesa->front.bpp = vmesa->viaScreen->bitsPerPixel; + 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; - /* Allocate back-buffer */ + } + 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; + } - 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 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 ) ); + } - /* 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; - } - else { - (void) memset( & vmesa->depth, 0, sizeof( vmesa->depth ) ); - } + /* 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; - 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); + 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 ) ); + } - /*=* 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); - } - - if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); - return GL_TRUE; -} + drm_via_mem_t mem; + mem.context = vmesa->hHWContext; + mem.size = buf->size; + mem.type = VIDEO; -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; -} - -void -via_free_back_buffer(viaContextPtr vmesa) -{ - drm_via_mem_t fb; - - 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; + buf->offset = mem.offset; + buf->map = (char *)vmesa->driScreen->pFB + mem.offset; + buf->index = mem.index; + return GL_TRUE; } void -via_free_front_buffer(viaContextPtr vmesa) +via_free_draw_buffer(viaContextPtr vmesa, viaBuffer *buf) { - 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; + drm_via_mem_t mem; - 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 (!vmesa) return; - if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); - return GL_TRUE; + 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_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,14 +73,127 @@ 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); + } +} + + + +#define SetReg2DAGP(nReg, nData) do { \ + OUT_RING( ((nReg) >> 2) | 0xF0000000 ); \ + OUT_RING( nData ); \ +} while (0) + + +static void viaBlit(viaContextPtr vmesa, GLuint bpp,GLuint srcBase, + GLuint srcPitch,GLuint dstBase,GLuint dstPitch, + GLuint w,GLuint h,int xdir,int ydir, GLuint blitMode, + GLuint color, GLuint nMask ) +{ + + GLuint dwGEMode = 0, srcY=0, srcX, dstY=0, dstX; + GLuint cmd; + RING_VARS; + + if (VIA_DEBUG) + fprintf(stderr, "%s bpp %d src %x/%x dst %x/%x w %d h %d dir %d,%d mode: %x color: 0x%08x mask 0x%08x\n", + __FUNCTION__, bpp, srcBase, srcPitch, dstBase, dstPitch, w,h, xdir, ydir, blitMode, color, nMask); + + + if (!w || !h) + return; + + srcX = srcBase & 31; + dstX = dstBase & 31; + switch (bpp) { + case 16: + dwGEMode |= VIA_GEM_16bpp; + srcX >>= 1; + dstX >>= 1; + break; + case 32: + dwGEMode |= VIA_GEM_32bpp; + srcX >>= 2; + dstX >>= 2; + break; + default: + dwGEMode |= VIA_GEM_8bpp; + break; } + + + cmd = 0; + + if (xdir < 0) { + cmd |= VIA_GEC_DECX; + srcX += (w - 1); + dstX += (w - 1); + } + if (ydir < 0) { + cmd |= VIA_GEC_DECY; + srcY += (h - 1); + dstY += (h - 1); + } + + switch(blitMode) { + case VIA_BLIT_FILL: + BEGIN_RING((2 + 9) * 2); + SetReg2DAGP(VIA_REG_GEMODE, dwGEMode); + SetReg2DAGP( VIA_REG_FGCOLOR, color); + cmd |= VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | (VIA_BLIT_FILL << 24); + break; + case VIA_BLIT_COPY: + BEGIN_RING((2 + 9) * 2); + SetReg2DAGP(VIA_REG_GEMODE, dwGEMode); + SetReg2DAGP( VIA_REG_KEYCONTROL, 0x0); + cmd |= VIA_GEC_BLT | (VIA_BLIT_COPY << 24); + } + + SetReg2DAGP( 0x2C, nMask); + SetReg2DAGP( VIA_REG_SRCBASE, (srcBase & ~31) >> 3); + SetReg2DAGP( VIA_REG_DSTBASE, (dstBase & ~31) >> 3); + SetReg2DAGP( VIA_REG_PITCH, VIA_PITCH_ENABLE | + (srcPitch >> 3) | (((dstPitch) >> 3) << 16)); + SetReg2DAGP( VIA_REG_SRCPOS, ((srcY << 16) | srcX)); + SetReg2DAGP( VIA_REG_DSTPOS, ((dstY << 16) | dstX)); + SetReg2DAGP( VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1))); + SetReg2DAGP( VIA_REG_GECMD, cmd); + SetReg2DAGP( 0x2C, 0x00000000); + ADVANCE_RING(); +} + +static void viaFillBuffer(viaContextPtr vmesa, + viaBuffer *buffer, + drm_clip_rect_t *pbox, + int nboxes, + GLuint pixel, + GLuint mask) +{ + GLuint bytePerPixel = buffer->bpp >> 3; + GLuint i; + + 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; + + 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); + } } @@ -133,73 +246,107 @@ static void viaClear(GLcontext *ctx, GLbitfield mask, GLboolean all, } 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; + cx += vmesa->drawX + vmesa->drawXoff; 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++; - } + 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; } - vmesa->sarea->nbox = n; + 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) { - if (vmesa->drawType == GLX_PBUFFER_BIT) - viaFillFrontPBuffer(vmesa); - else - viaFillFrontBuffer(vmesa); + viaFillBuffer(vmesa, &vmesa->front, boxes, nr, vmesa->ClearColor, 0); } if (flag & VIA_BACK) { - viaFillBackBuffer(vmesa); + viaFillBuffer(vmesa, &vmesa->back, boxes, nr, vmesa->ClearColor, 0); /* FIXME: masks */ } if (flag & VIA_DEPTH) { - viaFillDepthBuffer(vmesa, clear_depth, clear_depth_mask); + 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); - if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__); } + + + +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. */ @@ -207,29 +354,21 @@ 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->get_ust( &vmesa->swap_missed_ust ); } - - vmesa->swap_ust = 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 ); } /* @@ -237,31 +376,17 @@ void viaCopyBuffer(const __DRIdrawablePrivate *dPriv) */ 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 ); + 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 ); + vmesa->get_ust( &vmesa->swap_missed_ust ); } - LOCK_HARDWARE(vmesa); { @@ -276,49 +401,36 @@ void viaPageFlip(const __DRIdrawablePrivate *dPriv) 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_HFBBasL << 24) | (vmesa->back.offset & 0xFFFFF8) | 0x2); OUT_RING((HC_SubA_HFBDrawFirst << 24) | - ((nBackBase & 0xFF000000) >> 24) | 0x0100); + ((vmesa->back.offset & 0xFF000000) >> 24) | 0x0100); ADVANCE_RING(); - viaFlushPrimsLocked(vmesa); } - - UNLOCK_HARDWARE(vmesa); + viaFlushDmaLocked(vmesa, VIA_NO_CLIPRECTS); + UNLOCK_HARDWARE(vmesa); vmesa->swap_count++; - (void) (*vmesa->get_ust)( &vmesa->swap_ust ); - + 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)); - /* 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__); } @@ -327,13 +439,13 @@ void viaPageFlip(const __DRIdrawablePrivate *dPriv) #define VIA_CMDBUF_MAX_LAG 50000 -static int fire_buffer(viaContextPtr vmesa, drm_via_flush_sys_t *buf) +static int fire_buffer(viaContextPtr vmesa) { drmVIACommandBuffer bufI; int ret; - bufI.buf = (char *) (buf->index + buf->offset); - bufI.size = buf->size; + bufI.buf = (char *)vmesa->dma; + bufI.size = vmesa->dmaLow; if (vmesa->useAgp) { drmVIACmdBufSize bSiz; @@ -387,74 +499,40 @@ static int fire_buffer(viaContextPtr vmesa, drm_via_flush_sys_t *buf) * 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) +static void via_emit_cliprect(viaContextPtr vmesa, + drm_clip_rect_t *b) { - GLuint *vb = (GLuint *)vmesa->dmaAddr; + viaBuffer *buffer = vmesa->drawBuffer; + GLuint *vb = (GLuint *)(vmesa->dma + vmesa->dmaCliprectAddr); + 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; + GLuint pitch = buffer->pitch; + GLuint offset = buffer->orig; - 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; + 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); - return fire_buffer( vmesa, buf ); + if (vmesa->driDrawable->w == 0 || vmesa->driDrawable->h == 0) { + vb[2] = (HC_SubA_HClipTB << 24) | 0x0; + vb[3] = (HC_SubA_HClipLR << 24) | 0x0; } 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; - } + vb[2] = (HC_SubA_HClipTB << 24) | (clipT << 12) | clipB; + vb[3] = (HC_SubA_HClipLR << 24) | (clipL << 12) | clipR; } - - return 0; + + 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; } @@ -476,12 +554,23 @@ static int intersect_rect(drm_clip_rect_t *out, return 1; } -void viaFlushPrimsLocked(viaContextPtr vmesa) +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) { - 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; @@ -491,7 +580,7 @@ void viaFlushPrimsLocked(viaContextPtr vmesa) abort(); } - if (vmesa->dmaLow == DMA_OFFSET) { + if (vmesa->dmaLow == 0) { return; } @@ -543,94 +632,80 @@ void viaFlushPrimsLocked(viaContextPtr vmesa) 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 (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) { - 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; - } + drm_clip_rect_t b; + if (!intersect_rect(&b, &pbox[i], &vmesa->scissorRect)) + continue; + via_emit_cliprect(vmesa, &b); } 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; - } + via_emit_cliprect(vmesa, &pbox[i]); } - - if (nr == nbox) { - sysCmd.discard = 1; - } - - via_flush_sys(vmesa, &sysCmd); + + ret = fire_buffer(vmesa); + if (ret) + goto done; } + } else { + UNLOCK_HARDWARE(vmesa); + sched_yield(); + LOCK_HARDWARE(vmesa); } - 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; + vmesa->dmaLow = 0; + vmesa->dmaCliprectAddr = 0; + viaValidateState(vmesa->glCtx); } -void viaFlushPrims(viaContextPtr vmesa) +void viaWrapPrimitive( viaContextPtr vmesa ) { - if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__); + if (VIA_DEBUG) fprintf(stderr, "%s\n", __FUNCTION__); + viaFinishPrimitive( vmesa ); + + LOCK_HARDWARE(vmesa); + viaFlushDmaLocked(vmesa, 0); + UNLOCK_HARDWARE(vmesa); - if (vmesa->dmaLow != DMA_OFFSET) { - LOCK_HARDWARE(vmesa); - viaFlushPrimsLocked(vmesa); - 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); + } } - if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__); } static void viaFlush(GLcontext *ctx) @@ -660,315 +735,23 @@ void viaInitIoctlFuncs(GLcontext *ctx) } -#define SetReg2DAGP(nReg, nData) do { \ - OUT_RING( ((nReg) >> 2) | 0xF0000000 ); \ - OUT_RING( nData ); \ -} while (0) - - -static void viaBlit(viaContextPtr vmesa, GLuint bpp,GLuint srcBase, - GLuint srcPitch,GLuint dstBase,GLuint dstPitch, - GLuint w,GLuint h,int xdir,int ydir, GLuint blitMode, - GLuint color, GLuint nMask ) -{ - - GLuint dwGEMode = 0, srcY=0, srcX, dstY=0, dstX; - GLuint cmd; - RING_VARS; - - if (VIA_DEBUG) - fprintf(stderr, "%s bpp %d src %x/%x dst %x/%x w %d h %d dir %d,%d mode: %x color: 0x%08x mask 0x%08x\n", - __FUNCTION__, bpp, srcBase, srcPitch, dstBase, dstPitch, w,h, xdir, ydir, blitMode, color, nMask); - - - if (!w || !h) - return; - - srcX = srcBase & 31; - dstX = dstBase & 31; - switch (bpp) { - case 16: - dwGEMode |= VIA_GEM_16bpp; - srcX >>= 1; - dstX >>= 1; - break; - case 32: - dwGEMode |= VIA_GEM_32bpp; - srcX >>= 2; - dstX >>= 2; - break; - default: - dwGEMode |= VIA_GEM_8bpp; - break; - } - - - cmd = 0; - - if (xdir < 0) { - cmd |= VIA_GEC_DECX; - srcX += (w - 1); - dstX += (w - 1); - } - if (ydir < 0) { - cmd |= VIA_GEC_DECY; - srcY += (h - 1); - dstY += (h - 1); - } - - switch(blitMode) { - case VIA_BLIT_FILL: - BEGIN_RING((2 + 9) * 2); - SetReg2DAGP(VIA_REG_GEMODE, dwGEMode); - SetReg2DAGP( VIA_REG_FGCOLOR, color); - cmd |= VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | (VIA_BLIT_FILL << 24); - break; - case VIA_BLIT_COPY: - BEGIN_RING((2 + 9) * 2); - SetReg2DAGP(VIA_REG_GEMODE, dwGEMode); - SetReg2DAGP( VIA_REG_KEYCONTROL, 0x0); - cmd |= VIA_GEC_BLT | (VIA_BLIT_COPY << 24); - } - - SetReg2DAGP( 0x2C, nMask); - SetReg2DAGP( VIA_REG_SRCBASE, (srcBase & ~31) >> 3); - SetReg2DAGP( VIA_REG_DSTBASE, (dstBase & ~31) >> 3); - SetReg2DAGP( VIA_REG_PITCH, VIA_PITCH_ENABLE | - (srcPitch >> 3) | (((dstPitch) >> 3) << 16)); - SetReg2DAGP( VIA_REG_SRCPOS, ((srcY << 16) | srcX)); - SetReg2DAGP( VIA_REG_DSTPOS, ((dstY << 16) | dstX)); - SetReg2DAGP( VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1))); - SetReg2DAGP( VIA_REG_GECMD, cmd); - SetReg2DAGP( 0x2C, 0x00000000); - ADVANCE_RING(); -} - -void viaFillFrontBuffer(viaContextPtr vmesa) -{ - 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; - - 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++; - } - - viaFlushPrimsLocked(vmesa); -} - -void viaFillFrontPBuffer(viaContextPtr vmesa) -{ - GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight, offset; - GLuint pixel = (GLuint)vmesa->ClearColor; - - offset = vmesa->front.offset; - if (VIA_DEBUG) fprintf(stderr, "Fill PFront offset = %08x\n", offset); - nDestBase = offset; - nDestPitch = vmesa->front.pitch; - - nDestWidth = vmesa->driDrawable->w; - nDestHeight = vmesa->driDrawable->h; - - viaBlit(vmesa,vmesa->viaScreen->bitsPerPixel, nDestBase, nDestPitch, - nDestBase , nDestPitch, nDestWidth, nDestHeight, - 0,0,VIA_BLIT_FILL, pixel, 0x0); - - viaFlushPrimsLocked(vmesa); -} - -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 (!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); - - } - /*=* 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++; - } - } - if (VIA_DEBUG) { - fprintf(stderr," width = %08x\n", nDestWidth); - fprintf(stderr," height = %08x\n", nDestHeight); - } -} - - -void viaFillDepthBuffer(viaContextPtr vmesa, GLuint pixel, GLuint mask) -{ - GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight, offsetX, offset; - - 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; - - viaBlit(vmesa, vmesa->depth.bpp , nDestBase, nDestPitch, - nDestBase , nDestPitch, nDestWidth, nDestHeight, - 0,0,VIA_BLIT_FILL, pixel, mask); - - - if (vmesa->glCtx->Color._DrawDestMask[0] == DD_BACK_LEFT_BIT) { - viaFlushPrimsLocked(vmesa); - } -} - -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++) { - - /* 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++; - } - - viaFlushPrimsLocked(vmesa); - if (VIA_DEBUG) fprintf(stderr, "Do Swap Buffer\n"); -} - - -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; - - switch(bytePerPixel) { - case 4: - blitMode = 0x300; - break; - case 2: - blitMode = 0x100; - break; - default: - blitMode = 0x000; - break; - } - - 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; - - 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(); - - viaFlushPrimsLocked(vmesa); - if (VIA_DEBUG) fprintf(stderr, "Do Swap PBuffer\n"); -} - - 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; - - /* 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 (1 || vmesa->dmaLow > VIA_DMA_HIGHWATER) - viaFlushPrims( vmesa ); - } - else { - assert(vmesa->dmaLow >= (32 + DMA_OFFSET)); - vmesa->dmaLow -= 32; - vmesa->dmaLastPrim = 0; - } + if (VIA_DEBUG) fprintf(stderr, "%s\n", __FUNCTION__); + + 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; + + /* 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 -- 2.30.2