From 490e764d7affc093feff80192ed3f3d4642fcb8f Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 29 Dec 2004 20:46:27 +0000 Subject: 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_ioctl.c | 865 +++++++++++------------------ 1 file changed, 324 insertions(+), 541 deletions(-) (limited to 'src/mesa/drivers/dri/unichrome/via_ioctl.c') diff --git a/src/mesa/drivers/dri/unichrome/via_ioctl.c b/src/mesa/drivers/dri/unichrome/via_ioctl.c index 431a26b2a9..55220f18f6 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; + } } -- cgit v1.2.3