diff options
author | Brian Paul <[email protected]> | 2004-01-30 23:26:19 +0000 |
---|---|---|
committer | Brian Paul <[email protected]> | 2004-01-30 23:26:19 +0000 |
commit | f18598cbd2802e61c2cbb1d610630da9b5951169 (patch) | |
tree | 2d59e9eff59e0fe08abfe4d7a1c4977fa35d202e /src/mesa/drivers/dri/unichrome/via_ioctl.c | |
parent | 2726d77b2e0610c45019d0070ba21ee8ff47668d (diff) |
Via Unichrome/cle266 driver (Erdi Chen)
Diffstat (limited to 'src/mesa/drivers/dri/unichrome/via_ioctl.c')
-rw-r--r-- | src/mesa/drivers/dri/unichrome/via_ioctl.c | 2217 |
1 files changed, 2217 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/unichrome/via_ioctl.c b/src/mesa/drivers/dri/unichrome/via_ioctl.c new file mode 100644 index 00000000000..04dc130d3f1 --- /dev/null +++ b/src/mesa/drivers/dri/unichrome/via_ioctl.c @@ -0,0 +1,2217 @@ +#/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#include <stdio.h> +#include <unistd.h> + +#include "glheader.h" +#include "mtypes.h" +#include "macros.h" +#include "dd.h" +#include "swrast/swrast.h" + +#include "mm.h" +#include "via_context.h" +#include "via_ioctl.h" +#include "via_state.h" + +#include "drm.h" +#include <sys/ioctl.h> + +GLuint FrameCount = 0; +GLuint dmaLow = 0; +/*=* John Sheng [2003.5.31] flip *=*/ +GLuint nFirstSwap = GL_TRUE; +GLuint nFirstFlip = GL_TRUE; +#define SetReg2DAGP(nReg, nData) { \ + *((GLuint *)(vb)) = ((nReg) >> 2) | 0xF0000000; \ + *((GLuint *)(vb) + 1) = (nData); \ + vb += 2; \ + vmesa->dmaLow +=8; \ +} + +#define DEPTH_SCALE ((1 << 16) - 1) + +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 scrn = 0, i = 0, side = 0; + scrn = vmesa->saam & S_MASK; + side = vmesa->saam & P_MASK; +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__); +#endif + VIA_FIREVERTICES(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) { + if (ctx->Depth.Mask) + flag |= VIA_DEPTH; + mask &= ~DD_DEPTH_BIT; + } + + if (mask & DD_STENCIL_BIT) { + if (ctx->Stencil.Enabled) + flag |= VIA_STENCIL; + mask &= ~DD_STENCIL_BIT; + } + + /*=* [DBG] make draw to front buffer *=*/ + if(DRAW_FRONT) { + flag |= VIA_FRONT; + flag &= ~VIA_BACK; + } + + 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); + XF86DRIClipRectRec *box = vmesa->pClipRects; + drm_clip_rect_t *b = vmesa->sarea->boxes; + int n = 0; + + if (!vmesa->saam) { + if (!all) { +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr,"!all"); +#endif + 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; + } + else { + GLuint scrn = 0; + scrn = vmesa->saam & S_MASK; + + if (scrn == S0 || scrn == S1) { + 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; + } + /* between */ + else { + 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[n]; + n++; + } + } + *b++ = *(drm_clip_rect_t *)vmesa->pSaamRects; + vmesa->sarea->nbox = n; + } + } + + { + if (flag & VIA_FRONT) { + + if (vmesa->drawType == GLX_PBUFFER_BIT) + viaFillFrontPBuffer(vmesa); + else + viaFillFrontBuffer(vmesa); + + if (vmesa->saam && (scrn == (S0 | S1))) { + nr = MIN2(i + VIA_NR_SAREA_CLIPRECTS, vmesa->numSaamRects); + box = vmesa->pSaamRects; + b = vmesa->sarea->boxes; + n = 0; + + for (i = 0; i < nr; i++) { + *b++ = *(drm_clip_rect_t *)&box[n]; + n++; + } + + vmesa->sarea->nbox = n; + viaFillFrontBufferSaam(vmesa); + } + } + + if (flag & VIA_BACK) { + viaFillBackBuffer(vmesa); + } + + if (flag & VIA_DEPTH) { + double depth_clamp, range = 0xffffffff; + if (vmesa->hasStencil == 0) { + if (vmesa->depthBits == 32) { + depth_clamp = ((double)ctx->Depth.Clear)*range; + viaFillDepthBuffer(vmesa, (GLuint)depth_clamp); + } + else { + depth_clamp = ((double)ctx->Depth.Clear)*range; + viaFillDepthBuffer(vmesa, (GLuint)depth_clamp); + } + } + else { + depth_clamp = ((double)ctx->Depth.Clear)*range; + viaFillStencilDepthBuffer(vmesa, (GLuint)depth_clamp); + } + } + /*=* [DBG] Fix tuxracer depth error *=*/ + else if (flag & VIA_STENCIL) { + viaFillStencilBuffer(vmesa, (GLuint)ctx->Stencil.Clear); + } + } + } + UNLOCK_HARDWARE(vmesa); + vmesa->uploadCliprects = GL_TRUE; + } + + if (mask) + _swrast_Clear(ctx, mask, all, cx, cy, cw, ch); +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__); +#endif +} + +/* + * Copy the back buffer to the front buffer. + */ +void viaCopyBuffer(const __DRIdrawablePrivate *dPriv) +{ + viaContextPtr vmesa; + XF86DRIClipRectPtr pbox; + int nbox, i; + GLuint scrn = 0, side = 0; +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__); +#endif + assert(dPriv); + assert(dPriv->driContextPriv); + assert(dPriv->driContextPriv->driverPrivate); + + vmesa = (viaContextPtr)dPriv->driContextPriv->driverPrivate; + + VIA_FIREVERTICES(vmesa); + LOCK_HARDWARE(vmesa); + + scrn = vmesa->saam & S_MASK; + side = vmesa->saam & P_MASK; + + pbox = vmesa->pClipRects; + nbox = vmesa->numClipRects; + +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s %d cliprects (%d), SAAM (%d)\n", + __FUNCTION__, nbox, vmesa->drawType, vmesa->saam); +#endif + + + if (vmesa->drawType == GLX_PBUFFER_BIT) { + viaDoSwapPBuffers(vmesa); +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s SwapPBuffers\n", __FUNCTION__); +#endif /*=* [DBG] for pbuffer *=*/ + /*viaDoSwapBufferSoftFront(vmesa);*/ + } + else { + GLuint scrn = 0; + scrn = vmesa->saam & S_MASK; + if (!vmesa->saam) { + for (i = 0; i < nbox; ) { + int nr = MIN2(i + VIA_NR_SAREA_CLIPRECTS, dPriv->numClipRects); + XF86DRIClipRectRec *b = (XF86DRIClipRectRec *)vmesa->sarea->boxes; + + vmesa->sarea->nbox = nr - i; + + for (; i < nr; i++) + *b++ = pbox[i]; + viaDoSwapBuffers(vmesa); +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s SwapBuffers\n", __FUNCTION__); +#endif + } + } + else if (scrn == S0 || scrn == S1) { + for (i = 0; i < nbox; ) { + int nr = MIN2(i + VIA_NR_SAREA_CLIPRECTS, vmesa->numClipRects); + XF86DRIClipRectRec *b = (XF86DRIClipRectRec *)vmesa->sarea->boxes; + + vmesa->sarea->nbox = nr - i; + + for (; i < nr; i++) { + *b++ = pbox[i]; + } + viaDoSwapBuffers(vmesa); + } + } + /* between */ + else { + for (i = 0; i < nbox; ) { + int nr = MIN2(i + VIA_NR_SAREA_CLIPRECTS, dPriv->numClipRects); + XF86DRIClipRectRec *b = (XF86DRIClipRectRec *)vmesa->sarea->boxes; + + vmesa->sarea->nbox = nr - i; + + for (; i < nr; i++) + *b++ = pbox[i]; + viaDoSwapBuffers(vmesa); + } + + pbox = vmesa->pSaamRects; + nbox = vmesa->numSaamRects; + + for (i = 0; i < nbox; ) { + int nr = MIN2(i + VIA_NR_SAREA_CLIPRECTS, vmesa->numSaamRects); + XF86DRIClipRectRec *b = (XF86DRIClipRectRec *)vmesa->sarea->boxes; + + vmesa->sarea->nbox = nr - i; + + for (; i < nr; i++) + *b++ = pbox[i]; + + viaDoSwapBuffersSaam(vmesa); + } + } + } + UNLOCK_HARDWARE(vmesa); + vmesa->uploadCliprects = GL_TRUE; +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__); +#endif +} + +/* + * 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; + GLuint *vb = viaCheckDma(vmesa, vmesa->sarea->nbox*56); + GLuint nBackBase; + viaBuffer buffer_tmp; + GLcontext *ctx; + +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); +#endif + assert(dPriv); + assert(dPriv->driContextPriv); + assert(dPriv->driContextPriv->driverPrivate); + + ctx = vmesa->glCtx; + + /*=* [DBG] make draw to front buffer *=*/ + if(DRAW_FRONT) + return; + + /* Page Flip*/ + if(GL_FALSE) { + viaFlushPrimsLocked(vmesa); + while ((*(volatile GLuint *)((GLuint)vmesa->regMMIOBase + 0x200) & 0x2) != 0x2); + while (*(volatile GLuint *)((GLuint)vmesa->regMMIOBase + 0x200) & 0x2); + nBackBase = vmesa->back.offset >> 1; + + /*if (nFirstFlip) { + *vb++ = HALCYON_HEADER2; + *vb++ = 0x00fe0000; + *vb++ = 0x00001004; + *vb++ = 0x00001004; + vmesa->dmaLow += 16; + + nFirstFlip = GL_FALSE; + } + SetReg2DAGP(0x214, nBackBase); + viaFlushPrimsLocked(vmesa);*/ + if (nFirstFlip) { + *((volatile GLuint *)((GLuint)vmesa->regMMIOBase + 0x43c)) = 0x00fe0000; + *((volatile GLuint *)((GLuint)vmesa->regMMIOBase + 0x440)) = 0x00001004; + nFirstFlip = GL_FALSE; + } + *((GLuint *)((GLuint)vmesa->regMMIOBase + 0x214)) = nBackBase; + } + /* Auto Swap */ + else { + viaFlushPrimsLocked(vmesa); + vb = viaCheckDma(vmesa, vmesa->sarea->nbox*56); + if (nFirstSwap) { + *vb++ = HALCYON_HEADER2; + *vb++ = 0x00fe0000; + *vb++ = 0x0000000e; + *vb++ = 0x0000000e; + vmesa->dmaLow += 16; + + nFirstSwap = GL_FALSE; + } + nBackBase = (vmesa->back.offset << 1); + + *vb++ = HALCYON_HEADER2; + *vb++ = 0x00fe0000; + *vb++ = (HC_SubA_HFBBasL << 24) | (nBackBase & 0xFFFFF8) | 0x2; + *vb++ = (HC_SubA_HFBDrawFirst << 24) | + ((nBackBase & 0xFF000000) >> 24) | 0x0100; + vmesa->dmaLow += 16; + viaFlushPrimsLocked(vmesa); + } + + + 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; + if (vmesa->glCtx->Color._DrawDestMask & BACK_LEFT_BIT) { + ctx->Driver.DrawBuffer(ctx, GL_BACK_LEFT); + } + else { + ctx->Driver.DrawBuffer(ctx, GL_FRONT_LEFT); + } + } + else { + vmesa->currentPage = 1; + if (vmesa->glCtx->Color._DrawDestMask & BACK_LEFT_BIT) { + ctx->Driver.DrawBuffer(ctx, GL_BACK_LEFT); + } + else { + ctx->Driver.DrawBuffer(ctx, GL_FRONT_LEFT); + } + } +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); +#endif + +} + +/* This waits for *everybody* to finish rendering -- overkill. + */ +void viaDmaFinish(viaContextPtr vmesa) +{ +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__); +#endif + VIA_FIREVERTICES(vmesa); + LOCK_HARDWARE(vmesa); + UNLOCK_HARDWARE(vmesa); +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__); +#endif +} + +void viaRegetLockQuiescent(viaContextPtr vmesa) +{ + drmUnlock(vmesa->driFd, vmesa->hHWContext); +} + +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_agp_t agpCmd; + drm_via_flush_sys_t sysCmd; + GLuint *vb = viaCheckDma(vmesa, 0); + int i; + + if (vmesa->dmaLow == DMA_OFFSET) { + return; + } + if (vmesa->dmaLow > 2097152) + fprintf(stderr, "buffer overflow in Flush Prims = %d\n",vmesa->dmaLow); + + switch (vmesa->dmaLow & 0x1F) { + case 8: + *vb++ = HC_HEADER2; + *vb++ = (HC_ParaType_NotTex << 16); + *vb++ = HC_DUMMY; + *vb++ = HC_DUMMY; + *vb++ = HC_DUMMY; + *vb++ = HC_DUMMY; + vmesa->dmaLow += 24; + break; + case 16: + *vb++ = HC_HEADER2; + *vb++ = (HC_ParaType_NotTex << 16); + *vb++ = HC_DUMMY; + *vb++ = HC_DUMMY; + vmesa->dmaLow += 16; + break; + case 24: + *vb++ = HC_HEADER2; + *vb++ = (HC_ParaType_NotTex << 16); + *vb++ = HC_DUMMY; + *vb++ = HC_DUMMY; + *vb++ = HC_DUMMY; + *vb++ = HC_DUMMY; + *vb++ = HC_DUMMY; + *vb++ = HC_DUMMY; + *vb++ = HC_DUMMY; + *vb++ = HC_DUMMY; + vmesa->dmaLow += 40; + break; + case 0: + break; + default: + break; + } + + if (vmesa->useAgp) { + agpCmd.offset = 0x0; + agpCmd.size = vmesa->dmaLow; + agpCmd.index = vmesa->dma[vmesa->dmaIndex].index; + agpCmd.discard = 0; + } + else { + sysCmd.offset = 0x0; + sysCmd.size = vmesa->dmaLow; + sysCmd.index = (GLuint)vmesa->dma[vmesa->dmaIndex].map; + sysCmd.discard = 0; + } + + sarea->vertexPrim = vmesa->hwPrimitive; + + if (!nbox) { + if (vmesa->useAgp) + agpCmd.size = 0; + else + sysCmd.size = 0; + } + else if (nbox > VIA_NR_SAREA_CLIPRECTS) { + vmesa->uploadCliprects = GL_TRUE; + } +/*=* John Sheng [2003.5.31] flip *=*/ +/*#ifdef DEBUG + if (VIA_DEBUG) { + GLuint i; + GLuint *data = (GLuint *)vmesa->dmaAddr; + for (i = 0; i < vmesa->dmaLow; i += 16) { + fprintf(stderr, "%08x ", *data++); + fprintf(stderr, "%08x ", *data++); + fprintf(stderr, "%08x ", *data++); + fprintf(stderr, "%08x\n", *data++); + } + fprintf(stderr, "******************************************\n"); + } +#endif*/ + if (!nbox || !vmesa->uploadCliprects) { + if (nbox == 1) + sarea->nbox = 0; + else + sarea->nbox = nbox; + + if (vmesa->useAgp) { + agpCmd.discard = 1; + flush_agp(vmesa, &agpCmd); + } + else { + sysCmd.discard = 1; + flush_sys(vmesa, &sysCmd); + } + } + else { + GLuint scrn; + GLuint side; + scrn = vmesa->saam & S_MASK; + side = vmesa->saam & P_MASK; + + for (i = 0; i < nbox; ) { + int nr = MIN2(i + VIA_NR_SAREA_CLIPRECTS, nbox); + drm_clip_rect_t *b = sarea->boxes; + + if (!vmesa->saam) { + 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; + agpCmd.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; + } + } + } + else if (scrn == S0 || scrn == S1){ + if (vmesa->scissor) { + 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; + agpCmd.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; + } + } + + } + /* between */ + else { + if (vmesa->scissor) { + 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; + agpCmd.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) { + if (vmesa->useAgp) { + agpCmd.discard = 1; + flush_agp(vmesa, &agpCmd); + } + else { + sysCmd.discard = 1; + flush_sys(vmesa, &sysCmd); + } + } + + if (scrn == (S0 | S1)) { + pbox = (drm_clip_rect_t *)vmesa->pSaamRects; + nbox = vmesa->numSaamRects; + for (i = 0; i < nbox; ) { + int nr = MIN2(i + VIA_NR_SAREA_CLIPRECTS, nbox); + drm_clip_rect_t *b = sarea->boxes; + if (vmesa->scissor) { + sarea->nbox = 0; + for (; i < nr; i++) { + b->x1 = pbox[i].x1 - vmesa->drawXSaam; + b->y1 = pbox[i].y1 - vmesa->drawYSaam; + b->x2 = pbox[i].x2 - vmesa->drawXSaam; + b->y2 = pbox[i].y2 - vmesa->drawYSaam; + + if (intersect_rect(b, b, &vmesa->scissorRect)) { + sarea->nbox++; + b++; + } + } + if (!sarea->nbox) { + if (nr < nbox) continue; + agpCmd.size = 0; + } + } + else { + sarea->nbox = nr - i; + for (; i < nr; i++, b++) { + b->x1 = pbox[i].x1 - vmesa->drawXSaam; + b->y1 = pbox[i].y1 - vmesa->drawYSaam; + b->x2 = pbox[i].x2 - vmesa->drawXSaam; + b->y2 = pbox[i].y2 - vmesa->drawYSaam; + } + } + } + flush_agp_saam(vmesa, &agpCmd); + } + } + } +#ifdef DEBUG + if (VIA_DEBUG) { + GLuint i; + GLuint *data = (GLuint *)vmesa->dmaAddr; + for (i = 0; i < vmesa->dmaLow; i += 16) { + fprintf(stderr, "%08x ", *data++); + fprintf(stderr, "%08x ", *data++); + fprintf(stderr, "%08x ", *data++); + fprintf(stderr, "%08x\n", *data++); + } + fprintf(stderr, "******************************************\n"); + } +#endif + /* Reset vmesa vars: + */ + vmesa->dmaLow = DMA_OFFSET; + if (vmesa->dmaIndex) { + vmesa->dmaAddr = vmesa->dma[0].map; + vmesa->dmaHigh = vmesa->dma[0].size; + vmesa->dmaLastPrim = DMA_OFFSET; + vmesa->dmaIndex = 0; + } + else { + vmesa->dmaAddr = vmesa->dma[1].map; + vmesa->dmaHigh = vmesa->dma[1].size; + vmesa->dmaLastPrim = DMA_OFFSET; + vmesa->dmaIndex = 1; + } +} + +void viaFlushPrims(viaContextPtr vmesa) +{ +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__); +#endif + if (vmesa->dmaLow) { + LOCK_HARDWARE(vmesa); + viaFlushPrimsLocked(vmesa); + UNLOCK_HARDWARE(vmesa); + } +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__); +#endif +} + +static void viaFlush(GLcontext *ctx) +{ + viaContextPtr vmesa = VIA_CONTEXT(ctx); +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__); +#endif + VIA_FIREVERTICES(vmesa); +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__); +#endif +} + +static void viaFinish(GLcontext *ctx) +{ +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__); + if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__); +#endif + return; +} + +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; +} + +void viaFillFrontBuffer(viaContextPtr vmesa) +{ + GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight, offsetX, offset,i; + drm_clip_rect_t *b = vmesa->sarea->boxes; + GLuint *vb = viaCheckDma(vmesa, vmesa->sarea->nbox*48); + GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3; + GLuint pixel = (GLuint)vmesa->ClearColor; + + offset = vmesa->viaScreen->fbOffset + (vmesa->drawY * vmesa->front.pitch + vmesa->drawX * bytePerPixel); +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "Fill Front offset = %08x\n", offset); +#endif + nDestBase = offset & 0xffffffe0; + nDestPitch = vmesa->front.pitch; + + for (i = 0; i < vmesa->sarea->nbox ; i++) { + nDestWidth = b->x2 - b->x1 - 1; + nDestHeight = b->y2 - b->y1 - 1; + + if (bytePerPixel == 4) + offsetX = (b->x1 - vmesa->drawX) + (vmesa->drawX & 7); + else + offsetX = (b->x1 - vmesa->drawX) + (vmesa->drawX & 15); + + + if (GL_TRUE) { + /* GEFGCOLOR*/ + SetReg2DAGP(0x18, pixel | 0x00000000); + /* GEWD*/ + SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16)); + /* GEDST*/ + SetReg2DAGP(0x0C, (offsetX | ((b->y1 - vmesa->drawY) << 16))); + /* GEDSTBASE*/ + SetReg2DAGP(0x34, (nDestBase >> 3)); + /* GEPITCH*/ + SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000); + /* BITBLT*/ + SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000); + } + b++; + } + + viaFlushPrimsLocked(vmesa); +} + +void viaFillFrontBufferSaam(viaContextPtr vmesa) +{ + GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight, offsetX, offset,i; + drm_clip_rect_t *b = vmesa->sarea->boxes; + GLuint *vb = viaCheckDma(vmesa, vmesa->sarea->nbox*48); + GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3; + GLuint pixel = (GLuint)vmesa->ClearColor; + + offset = vmesa->viaScreen->fbSize + + (vmesa->drawYSaam * vmesa->front.pitch + vmesa->drawXSaam * bytePerPixel); + nDestBase = offset & 0xffffffe0; + nDestPitch = vmesa->front.pitch; + + for (i = 0; i < vmesa->sarea->nbox ; i++) { + nDestWidth = b->x2 - b->x1 - 1; + nDestHeight = b->y2 - b->y1 - 1; + + if (bytePerPixel == 4) + offsetX = (b->x1 - vmesa->drawXSaam) + (vmesa->drawXSaam & 7); + else + offsetX = (b->x1 - vmesa->drawXSaam) + (vmesa->drawXSaam & 15); + + if (GL_TRUE) { + /* GEFGCOLOR*/ + SetReg2DAGP(0x18, pixel | 0x00000000); + /* GEWD*/ + SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16)); + /* GEDST*/ + SetReg2DAGP(0x0C, (offsetX | ((b->y1 - vmesa->drawYSaam) << 16))); + /* GEDSTBASE*/ + SetReg2DAGP(0x34, (nDestBase >> 3)); + /* GEPITCH*/ + SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000); + /* BITBLT*/ + SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000); + } + b++; + } + + viaFlushPrimsLocked(vmesa); +} + +void viaFillFrontPBuffer(viaContextPtr vmesa) +{ + GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight, offsetX, offset; + GLuint *vb = viaCheckDma(vmesa, vmesa->sarea->nbox*48); + GLuint pixel = (GLuint)vmesa->ClearColor; + + offset = vmesa->front.offset; +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "Fill PFront offset = %08x\n", offset); +#endif + nDestBase = offset; + nDestPitch = vmesa->front.pitch; + + nDestWidth = vmesa->driDrawable->w - 1; + nDestHeight = vmesa->driDrawable->h - 1; + + offsetX = 0; + + /* GEFGCOLOR*/ + SetReg2DAGP(0x18, pixel | 0x00000000); + /* GEWD*/ + SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16)); + /* GEDST*/ + SetReg2DAGP(0x0C, (offsetX | (0 << 16))); + /* GEDSTBASE*/ + SetReg2DAGP(0x34, (nDestBase >> 3)); + /* GEPITCH*/ + SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000); + /* BITBLT*/ + SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000); + + viaFlushPrimsLocked(vmesa); +} + +void viaFillBackBuffer(viaContextPtr vmesa) +{ + GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight, offsetX, offset; + GLcontext *ctx = vmesa->glCtx; + GLuint *vb = viaCheckDma(vmesa, 48); + GLuint pixel = (GLuint)vmesa->ClearColor; + GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3; + + offset = vmesa->back.offset; +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "Fill Back offset = %08x\n", offset); +#endif + nDestBase = offset; + nDestPitch = vmesa->back.pitch; + offsetX = vmesa->drawXoff; + + { + if (!ctx->Scissor.Enabled) { + + nDestWidth = (vmesa->back.pitch / vmesa->viaScreen->bitsPerPixel * 8) - 1; + nDestHeight = vmesa->driDrawable->h -1; + + /* GEFGCOLOR */ + SetReg2DAGP(0x18, pixel | 0x00000000); + /* GEWD */ + SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16)); + /* GEDST */ + SetReg2DAGP(0x0C, (offsetX | (0 << 16))); + /* GEDSTBASE */ + SetReg2DAGP(0x34, (nDestBase >> 3)); + /* GEPITCH */ + SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000); + /* BITBLT */ + SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000); + } + /*=* 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 - 1; + nDestHeight = b->y2 - b->y1 - 1; + + if (bytePerPixel == 4) + offsetX = (b->x1 - vmesa->drawX) + (vmesa->drawX & 7); + else + offsetX = (b->x1 - vmesa->drawX) + (vmesa->drawX & 15); + + /* GEFGCOLOR */ + SetReg2DAGP(0x18, pixel | 0x00000000); + /* GEWD */ + SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16)); + /* GEDST */ + SetReg2DAGP(0x0C, ((offsetX + (b->x1 - vmesa->drawX)) | ((b->y1 - vmesa->drawY) << 16))); + /* GEDSTBASE */ + SetReg2DAGP(0x34, (nDestBase >> 3)); + /* GEPITCH */ + SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000); + /* BITBLT */ + SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000); + b++; + } + } +#ifdef DEBUG + if (VIA_DEBUG) { + fprintf(stderr," width = %08x\n", nDestWidth); + fprintf(stderr," height = %08x\n", nDestHeight); + } +#endif + } +} + +void viaFillStencilDepthBuffer(viaContextPtr vmesa, GLuint pixel) +{ + GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight, offsetX, offset; + GLuint *vb = viaCheckDma(vmesa, 80); + GLuint nMask; + + offset = vmesa->depth.offset; +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "Fill Stencil Depth offset = %08x\n", offset); +#endif + nDestBase = offset; + nDestPitch = vmesa->depth.pitch; + offsetX = vmesa->drawXoff; + pixel = pixel & 0xffffff00; + nMask = 0x10000000; + + { + nDestWidth = (vmesa->depth.pitch / vmesa->depthBits * 8) - 1 - offsetX; + nDestHeight = vmesa->driDrawable->h -1; + + if (vmesa->viaScreen->bitsPerPixel == vmesa->depth.bpp) { + /* GEFGCOLOR */ + SetReg2DAGP(0x18, pixel); + /* GEMASK */ + SetReg2DAGP(0x2C, nMask); + /* GEWD */ + SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16)); + /* GEDST */ + SetReg2DAGP(0x0C, (offsetX | (0 << 16))); + /* GEDSTBASE */ + SetReg2DAGP(0x34, (nDestBase >> 3)); + /* GEPITCH */ + SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000); + /* BITBLT */ + SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000); + /* GEMASK */ + SetReg2DAGP(0x2C, 0x00000000); + } + else { + GLuint EngStatus = *(vmesa->pnGEMode); + /* GEMODE */ + SetReg2DAGP(0x04, (EngStatus & 0xFFFFFCFF) | 0x300); + /* GEFGCOLOR */ + SetReg2DAGP(0x18, pixel); + /* GEMASK */ + SetReg2DAGP(0x2C, nMask); + /* GEWD */ + SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16)); + /* GEDST */ + SetReg2DAGP(0x0C, (offsetX | (0 << 16))); + /* GEDSTBASE */ + SetReg2DAGP(0x34, (nDestBase >> 3)); + /* GEPITCH */ + SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000); + /* BITBLT */ + SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000); + /* GEMODE */ + SetReg2DAGP(0x04, EngStatus); + /* GEMASK */ + SetReg2DAGP(0x2C, 0x00000000); + + WAIT_IDLE + } + } + + if (vmesa->glCtx->Color._DrawDestMask & BACK_LEFT_BIT) { + viaFlushPrimsLocked(vmesa); + } +} + +void viaFillStencilBuffer(viaContextPtr vmesa, GLuint pixel) +{ + GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight, offsetX, offset; + GLuint *vb = viaCheckDma(vmesa, 80); + GLuint nMask; + + offset = vmesa->depth.offset; +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "Fill Stencil offset = %08x\n", offset); +#endif + nDestBase = offset; + nDestPitch = vmesa->depth.pitch; + offsetX = vmesa->drawXoff; + pixel = pixel & 0x000000ff; + nMask = 0xe0000000; + + { + nDestWidth = (vmesa->depth.pitch / vmesa->depthBits * 8) - 1 - offsetX; + nDestHeight = vmesa->driDrawable->h -1; + + if (vmesa->viaScreen->bitsPerPixel == vmesa->depth.bpp) { + /* GEFGCOLOR */ + SetReg2DAGP(0x18, pixel); + /* GEMASK */ + SetReg2DAGP(0x2C, nMask); + /* GEWD */ + SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16)); + /* GEDST */ + SetReg2DAGP(0x0C, (offsetX | (0 << 16))); + /* GEDSTBASE */ + SetReg2DAGP(0x34, (nDestBase >> 3)); + /* GEPITCH */ + SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000); + /* BITBLT */ + SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000); + /* GEMASK */ + SetReg2DAGP(0x2C, 0x00000000); + } + else { + GLuint EngStatus = *(vmesa->pnGEMode); + /* GEMODE */ + SetReg2DAGP(0x04, (EngStatus & 0xFFFFFCFF) | 0x300); + /* GEFGCOLOR */ + SetReg2DAGP(0x18, pixel); + /* GEMASK */ + SetReg2DAGP(0x2C, nMask); + /* GEWD */ + SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16)); + /* GEDST */ + SetReg2DAGP(0x0C, (offsetX | (0 << 16))); + /* GEDSTBASE */ + SetReg2DAGP(0x34, (nDestBase >> 3)); + /* GEPITCH */ + SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000); + /* BITBLT */ + SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000); + /* GEMODE */ + SetReg2DAGP(0x04, EngStatus); + /* GEMASK */ + SetReg2DAGP(0x2C, 0x00000000); + } + } + + if (vmesa->glCtx->Color._DrawDestMask & BACK_LEFT_BIT) { + viaFlushPrimsLocked(vmesa); + } +} + +void viaFillDepthBuffer(viaContextPtr vmesa, GLuint pixel) +{ + GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight, offsetX, offset; + GLuint *vb = viaCheckDma(vmesa, 72); + offset = vmesa->depth.offset; +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "Fill Depth offset = %08x\n", offset); +#endif + nDestBase = offset; + nDestPitch = vmesa->depth.pitch; + offsetX = vmesa->drawXoff; + + { + nDestWidth = (vmesa->depth.pitch / vmesa->depthBits * 8) - 1 - offsetX; + nDestHeight = vmesa->driDrawable->h -1; + + if (vmesa->viaScreen->bitsPerPixel == vmesa->depth.bpp) { + /* GEFGCOLOR */ + SetReg2DAGP(0x18, pixel); + /* GEMASK */ + SetReg2DAGP(0x2C, 0x0); + /* GEWD */ + SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16)); + /* GEDST */ + SetReg2DAGP(0x0C, (offsetX | (0 << 16))); + /* GEDSTBASE */ + SetReg2DAGP(0x34, (nDestBase >> 3)); + /* GEPITCH */ + SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000); + /* BITBLT */ + SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000); + } + /* depth = 16, color = 32 */ + else if (vmesa->depth.bpp == 16) { + GLuint EngStatus = *(vmesa->pnGEMode); + + /* GEMODE */ + SetReg2DAGP(0x04, (EngStatus & 0xFFFFFCFF) | 0x100); + /* GEMASK */ + SetReg2DAGP(0x2C, 0x0); + /* GEFGCOLOR */ + SetReg2DAGP(0x18, pixel); + /* GEWD */ + SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16)); + /* GEDST */ + SetReg2DAGP(0x0C, (offsetX | (0 << 16))); + /* GEDSTBASE */ + SetReg2DAGP(0x34, (nDestBase >> 3)); + /* GEPITCH */ + SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000); + /* BITBLT */ + SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000); + /* GEMODE */ + SetReg2DAGP(0x04, EngStatus); + } + /* depth = 32, color = 16 */ + else { + GLuint EngStatus = *(vmesa->pnGEMode); + + /* GEMODE */ + SetReg2DAGP(0x04, (EngStatus & 0xFFFFFCFF) | 0x300); + /* GEMASK */ + SetReg2DAGP(0x2C, 0x0); + /* GEFGCOLOR */ + SetReg2DAGP(0x18, pixel); + /* GEWD */ + SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16)); + /* GEDST */ + SetReg2DAGP(0x0C, (offsetX | (0 << 16))); + /* GEDSTBASE */ + SetReg2DAGP(0x34, (nDestBase >> 3)); + /* GEPITCH */ + SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000); + /* BITBLT */ + SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000); + /* GEMODE */ + SetReg2DAGP(0x04, EngStatus); + } + } + + if (vmesa->glCtx->Color._DrawDestMask & BACK_LEFT_BIT) { + viaFlushPrimsLocked(vmesa); + } +} + +void viaDoSwapBuffers(viaContextPtr vmesa) +{ + GLuint *vb = viaCheckDma(vmesa, vmesa->sarea->nbox*56); + GLuint nFrontPitch; + GLuint nBackPitch; + GLuint nFrontWidth, nFrontHeight, nBackWidth, nBackHeight; + GLuint nFrontBase, nBackBase; + GLuint nFrontOffsetX, nFrontOffsetY, nBackOffsetX, nBackOffsetY; + drm_clip_rect_t *b = vmesa->sarea->boxes; + GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3; + GLuint i; + + nFrontPitch = vmesa->front.pitch; + nBackPitch = vmesa->back.pitch; + + /* Caculate Base */ + nFrontBase = vmesa->viaScreen->fbOffset + (vmesa->drawY * nFrontPitch + vmesa->drawX * bytePerPixel); + nBackBase = vmesa->back.offset; + /* 128 bit alignment*/ + nFrontBase = nFrontBase & 0xffffffe0; + + /*=* [DBG] make draw to front buffer *=*/ + if(DRAW_FRONT) + return; + + for (i = 0; i < vmesa->sarea->nbox; i++) { + /* Width, Height */ + nFrontWidth = nBackWidth = b->x2 - b->x1 - 1; + nFrontHeight = nBackHeight = b->y2 - b->y1 - 1; + /* Offset */ + nFrontOffsetX = (b->x1 - vmesa->drawX) + vmesa->drawXoff; + nFrontOffsetY = b->y1 - vmesa->drawY; + + nBackOffsetX = nFrontOffsetX; + nBackOffsetY = nFrontOffsetY; + /* 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); + b++; + } + + viaFlushPrimsLocked(vmesa); +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "Do Swap Buffer\n"); +#endif +} + +void viaDoSwapBuffersSaam(viaContextPtr vmesa) +{ + GLuint *vb = viaCheckDma(vmesa, vmesa->sarea->nbox*56); + GLuint nFrontPitch; + GLuint nBackPitch; + GLuint nFrontWidth, nFrontHeight, nBackWidth, nBackHeight; + GLuint nFrontBase, nBackBase; + GLuint nFrontOffsetX, nFrontOffsetY, nBackOffsetX, nBackOffsetY; + drm_clip_rect_t *b = vmesa->sarea->boxes; + GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3; + GLuint i; + + nFrontPitch = vmesa->front.pitch; + nBackPitch = vmesa->back.pitch; + + /* Caculate Base */ + nFrontBase = vmesa->viaScreen->fbSize + (vmesa->drawYSaam * nFrontPitch + vmesa->drawXSaam * bytePerPixel); + nBackBase = vmesa->back.offset; + /* 128 bit alignment*/ + nFrontBase = nFrontBase & 0xffffffe0; + + /*=* [DBG] make draw to front buffer *=*/ + if(DRAW_FRONT) + return; + + for (i = 0; i < vmesa->sarea->nbox; i++) { + /* Width, Height */ + nFrontWidth = nBackWidth = b->x2 - b->x1 - 1; + nFrontHeight = nBackHeight = b->y2 - b->y1 - 1; + /* Offset */ + nFrontOffsetX = (b->x1 - vmesa->drawXSaam) + vmesa->drawXoff; + nFrontOffsetY = b->y1 - vmesa->drawYSaam; + + nBackOffsetX = nFrontOffsetX; + nBackOffsetY = nFrontOffsetY; + /* 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); + b++; + } + + viaFlushPrimsLocked(vmesa); +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "Do Swap Buffer\n"); +#endif +} + +void viaDoSwapPBuffers(viaContextPtr vmesa) +{ + GLuint *vb = viaCheckDma(vmesa, vmesa->sarea->nbox*56); + GLuint nFrontPitch; + GLuint nBackPitch; + GLuint nFrontWidth, nFrontHeight; + GLuint nFrontBase, nBackBase; + GLuint nFrontOffsetX, nFrontOffsetY, nBackOffsetX, nBackOffsetY; + GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3; + + 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; + /* 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); + + viaFlushPrimsLocked(vmesa); +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "Do Swap PBuffer\n"); +#endif +} + +void viaDoSwapBufferSoft(viaContextPtr vmesa) +{ + GLuint nFrontPitch; + GLuint nBackPitch; + GLuint nFrontBase, nBackBase; + GLuint i, j; + GLubyte *by, *fy; + GLuint w; + + w = vmesa->viaScreen->width; + w = BUFFER_ALIGN_WIDTH(w, BUFFER_ALIGNMENT); + + if (vmesa->viaScreen->bitsPerPixel == 0x20) + nFrontPitch = w << 2; + else + nFrontPitch = w << 1; + + nBackPitch = vmesa->back.pitch; + + /* Caculate Base */ + nFrontBase = (GLuint) vmesa->driScreen->pFB; + nBackBase = ((GLuint) vmesa->back.offset) + ((GLuint) vmesa->driScreen->pFB); + by = (GLubyte *) nBackBase; + fy = (GLubyte *) nFrontBase; + + viaFlushPrimsLocked(vmesa); + + for (i = 0; i < vmesa->driDrawable->h; i++) { + fy = (GLubyte *)(nFrontBase + i * nFrontPitch); + for (j = 0; j < nBackPitch; j++) { + *((GLubyte*)fy) = *((GLubyte*)by); + fy = fy + 1; + by = by + 1; + } + + } + +} + +void viaDoSwapBufferSoftFront(viaContextPtr vmesa) +{ + GLuint nFrontPitch; + GLuint nBackPitch; + GLuint nFrontBase, nBackBase; + GLuint i, j; + GLubyte *by, *fy; + GLuint w; + + w = vmesa->viaScreen->width; + w = BUFFER_ALIGN_WIDTH(w, BUFFER_ALIGNMENT); + + if (vmesa->viaScreen->bitsPerPixel == 0x20) + nFrontPitch = w << 2; + else + nFrontPitch = w << 1; + + nBackPitch = vmesa->front.pitch; + + /* Caculate Base */ + nFrontBase = (GLuint) vmesa->driScreen->pFB; + nBackBase = ((GLuint) vmesa->front.offset) + ((GLuint) vmesa->driScreen->pFB); + by = (GLubyte *) nBackBase; + fy = (GLubyte *) nFrontBase; + + viaFlushPrimsLocked(vmesa); + + for (i = 0; i < vmesa->driDrawable->h; i++) { + fy = (GLubyte *)(nFrontBase + i * nFrontPitch); + for (j = 0; j < nBackPitch; j++) { + *((GLubyte*)fy) = *((GLubyte*)by); + fy = fy + 1; + by = by + 1; + } + + } + +} +int flush_agp(viaContextPtr vmesa, drm_via_flush_agp_t* agpCmd) +{ + GLuint *pnAGPCurrentPhysStart; + GLuint *pnAGPCurrentPhysEnd; + GLuint *pnAGPCurrentStart; + GLuint *pnAGPCurrentEnd; + volatile GLuint *pnMMIOBase; + volatile GLuint *pnEngBaseTranSet; + volatile GLuint *pnEngBaseTranSpace; + GLuint *agpBase; + GLuint ofs = vmesa->dma[vmesa->dmaIndex].offset; + GLuint *vb = (GLuint *)vmesa->dmaAddr; + GLuint i = 0; + + pnMMIOBase = vmesa->regMMIOBase; + pnEngBaseTranSet = vmesa->regTranSet; + pnEngBaseTranSpace = vmesa->regTranSpace; + *pnEngBaseTranSet = (0x0010 << 16); + agpBase = vmesa->agpBase; + + if (!agpCmd->size) { + return -1; + } + + { + volatile GLuint *pnEngBase = vmesa->regEngineStatus; + int nStatus; + + while (1) { + nStatus = *pnEngBase; + if ((nStatus & 0xFFFEFFFF) == 0x00020000) + break; + i++; + } + } + + pnAGPCurrentStart = (GLuint *)(ofs + agpCmd->offset); + pnAGPCurrentEnd = (GLuint *)((GLuint)pnAGPCurrentStart + vmesa->dmaHigh); + pnAGPCurrentPhysStart = (GLuint *)( (GLuint)pnAGPCurrentStart + (GLuint)agpBase ); + pnAGPCurrentPhysEnd = (GLuint *)( (GLuint)pnAGPCurrentEnd + (GLuint)agpBase ); + + /*=* [DBG] make draw to front buffer *=*/ + if(DRAW_FRONT) + vmesa->glCtx->Color._DrawDestMask = FRONT_LEFT_BIT; + + if (vmesa->glCtx->Color._DrawDestMask & BACK_LEFT_BIT) { + + *vb++ = HC_HEADER2; + *vb++ = (HC_ParaType_NotTex << 16); + if (vmesa->driDrawable->w == 0 || vmesa->driDrawable->h == 0) { + *vb++ = (HC_SubA_HClipTB << 24) | 0x0; + *vb++ = (HC_SubA_HClipLR << 24) | 0x0; + } + else { + *vb++ = ((HC_SubA_HClipTB << 24) | (0x0 << 12) | vmesa->driDrawable->h); + *vb++ = ((HC_SubA_HClipLR << 24) | (vmesa->drawXoff << 12) | (vmesa->driDrawable->w + vmesa->drawXoff)); + } + + { + GLuint pitch, format, offset; + + if (vmesa->viaScreen->bitsPerPixel == 0x20) { + format = HC_HDBFM_ARGB8888; + } + else if (vmesa->viaScreen->bitsPerPixel == 0x10) { + format = HC_HDBFM_RGB565; + } + else + { + return -1; + } + + offset = vmesa->back.offset; + pitch = vmesa->back.pitch; + + *vb++ = ((HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF)); + *vb++ = ((HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000)) >> 24); + *vb++ = ((HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch); + *vb++ = 0xcccccccc; + } + + *pnEngBaseTranSpace = (HC_SubA_HAGPBstL << 24) | + ((GLuint)(pnAGPCurrentPhysStart) & 0xFFFFFF); + *pnEngBaseTranSpace = (HC_SubA_HAGPBendL << 24) | + ((GLuint)(pnAGPCurrentPhysEnd) & 0xFFFFFF); + *pnEngBaseTranSpace = (HC_SubA_HAGPCMNT << 24) | + ((GLuint)(pnAGPCurrentPhysEnd) & 0xFF000000) >> 16 | + ((GLuint)(pnAGPCurrentPhysStart) & 0xFF000000) >> 24; + *pnEngBaseTranSpace = (HC_SubA_HAGPBpH << 24) | + ((GLuint)((GLbyte *)pnAGPCurrentPhysStart + agpCmd->size - 4) & 0xFF000000) >> 24; + *pnEngBaseTranSpace = (HC_SubA_HAGPBpL << 24) | + ((GLuint)((GLbyte *)pnAGPCurrentPhysStart + agpCmd->size - 4) & 0xFFFFFF) | + HC_HAGPBpID_STOP; + *pnEngBaseTranSpace = (HC_SubA_HAGPCMNT << 24) | + ((GLuint)(pnAGPCurrentPhysEnd) & 0xFF000000) >> 16 | + ((GLuint)(pnAGPCurrentPhysStart) & 0xFF000000) >> 24 | + HC_HAGPCMNT_MASK; + } + else { + GLuint *head; + GLuint clipL, clipR, clipT, clipB; + drm_clip_rect_t *b = vmesa->sarea->boxes; + *vb++ = HC_HEADER2; + *vb++ = (HC_ParaType_NotTex << 16); + head = vb; + + *pnEngBaseTranSpace = (HC_SubA_HAGPBstL << 24) | + ((GLuint)(pnAGPCurrentPhysStart) & 0xFFFFFF); + *pnEngBaseTranSpace = (HC_SubA_HAGPBendL << 24) | + ((GLuint)(pnAGPCurrentPhysEnd) & 0xFFFFFF); + *pnEngBaseTranSpace = (HC_SubA_HAGPCMNT << 24) | + ((GLuint)(pnAGPCurrentPhysEnd) & 0xFF000000) >> 16 | + ((GLuint)(pnAGPCurrentPhysStart) & 0xFF000000) >> 24; + *pnEngBaseTranSpace = (HC_SubA_HAGPBpH << 24) | + ((GLuint)((GLbyte *)pnAGPCurrentPhysStart + agpCmd->size - 4) & 0xFF000000) >> 24; + *pnEngBaseTranSpace = (HC_SubA_HAGPBpL << 24) | + ((GLuint)((GLbyte *)pnAGPCurrentPhysStart + agpCmd->size - 4) & 0xFFFFFF) | + HC_HAGPBpID_STOP; + + for (i = 0; i < vmesa->sarea->nbox; i++) { + if (1) { + volatile GLuint *pnEngBase = vmesa->regEngineStatus; + int nStatus; + + while (1) { + nStatus = *pnEngBase; + if ((nStatus & 0xFFFEFFFF) == 0x00020000) + break; + } + } + + clipL = b->x1 + vmesa->drawXoff; + clipR = b->x2; + clipT = b->y1; + clipB = b->y2; +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "clip = %d\n", i); +#endif + if (vmesa->driDrawable->w == 0 || vmesa->driDrawable->h == 0) { + + *vb = (HC_SubA_HClipTB << 24) | 0x0; + vb++; + + *vb = (HC_SubA_HClipLR << 24) | 0x0; + vb++; + } + else { + *vb = (HC_SubA_HClipTB << 24) | (clipT << 12) | clipB; + vb++; + + *vb = (HC_SubA_HClipLR << 24) | (clipL << 12) | clipR; + vb++; + } + + { + GLuint pitch, format, offset; + GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3; + + if (vmesa->viaScreen->bitsPerPixel == 0x20) { + format = HC_HDBFM_ARGB8888; + } + else if (vmesa->viaScreen->bitsPerPixel == 0x10) { + format = HC_HDBFM_RGB565; + } + else + return -1; + + pitch = vmesa->front.pitch; + offset = vmesa->viaScreen->fbOffset + (vmesa->drawY * pitch + vmesa->drawX * bytePerPixel); + offset = offset & 0xffffffe0; + + *vb++ = ((HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF)); + *vb++ = ((HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000)) >> 24); + *vb++ = ((HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch); + *vb++ = 0xcccccccc; + } + *pnEngBaseTranSpace = (HC_SubA_HAGPCMNT << 24) | + ((GLuint)(pnAGPCurrentPhysEnd) & 0xFF000000) >> 16 | + ((GLuint)(pnAGPCurrentPhysStart) & 0xFF000000) >> 24 | + HC_HAGPCMNT_MASK; +#ifdef DEBUG + if (VIA_DEBUG) { + GLuint i; + GLuint *data = (GLuint *)vmesa->dmaAddr; + for (i = 0; i < vmesa->dmaLow; i += 16) { + fprintf(stderr, "%08x ", *data++); + fprintf(stderr, "%08x ", *data++); + fprintf(stderr, "%08x ", *data++); + fprintf(stderr, "%08x\n", *data++); + } + fprintf(stderr, "******************************************\n"); + } +#endif + b++; + vb = head; + } + } + +#ifdef DEBUG + if (VIA_DEBUG && 0/*FIXME*/) { + volatile GLuint *pnEngBase = (volatile GLuint *)((GLuint)pnMMIOBase + 0x400); + int nStatus; + int i = 0; + + while (1) { + nStatus = *pnEngBase; + if ((nStatus & 0xFFFEFFFF) == 0x00020000) { + break; + } + else { + GLuint j; + GLuint *data; + /* dump current command buffer */ + data = (GLuint *)vmesa->dmaAddr; + + if (i == 500000) { + fprintf(stderr, "current command buffer"); + fprintf(stderr, "i = %d\n", i); + for (j = 0; j < vmesa->dmaLow; j += 16) { + fprintf(stderr, "%08x ", *data++); + fprintf(stderr, "%08x ", *data++); + fprintf(stderr, "%08x ", *data++); + fprintf(stderr, "%08x\n", *data++); + } + } + /* dump previous command buffer */ + if (vmesa->dmaIndex) { + data = (GLuint *)vmesa->dma[0].map; + } + else { + data = (GLuint *)vmesa->dma[1].map; + } + if (i == 500000) { + fprintf(stderr, "previous command buffer"); + fprintf(stderr, "i = %d\n", i); + for (j = 0; j < dmaLow; j += 16) { + fprintf(stderr, "%08x ", *data++); + fprintf(stderr, "%08x ", *data++); + fprintf(stderr, "%08x ", *data++); + fprintf(stderr, "%08x\n", *data++); + } + } + } + i++; + } + } +#endif + dmaLow = vmesa->dmaLow; + return 0; +} + +int flush_agp_saam(viaContextPtr vmesa, drm_via_flush_agp_t* agpCmd) +{ + GLuint *pnAGPCurrentPhysStart; + GLuint *pnAGPCurrentPhysEnd; + GLuint *pnAGPCurrentStart; + GLuint *pnAGPCurrentEnd; + volatile GLuint *pnMMIOBase; + volatile GLuint *pnEngBaseTranSet; + volatile GLuint *pnEngBaseTranSpace; + GLuint *agpBase; + GLuint ofs = vmesa->dma[vmesa->dmaIndex].offset; + GLuint *vb = (GLuint *)vmesa->dmaAddr; + GLuint i = 0; + + pnMMIOBase = vmesa->regMMIOBase; + pnEngBaseTranSet = vmesa->regTranSet; + pnEngBaseTranSpace = vmesa->regTranSpace; + *pnEngBaseTranSet = (0x0010 << 16); + agpBase = vmesa->agpBase; + + if (!agpCmd->size) { + return -1; + } + + { + volatile GLuint *pnEngBase = vmesa->regEngineStatus; + int nStatus; + + while (1) { + nStatus = *pnEngBase; + if ((nStatus & 0xFFFEFFFF) == 0x00020000) + break; + i++; + } + } + + pnAGPCurrentStart = (GLuint *)(ofs + agpCmd->offset); + pnAGPCurrentEnd = (GLuint *)((GLuint)pnAGPCurrentStart + vmesa->dmaHigh); + pnAGPCurrentPhysStart = (GLuint *)( (GLuint)pnAGPCurrentStart + (GLuint)agpBase ); + pnAGPCurrentPhysEnd = (GLuint *)( (GLuint)pnAGPCurrentEnd + (GLuint)agpBase ); + + /*=* [DBG] make draw to front buffer *=*/ + if(DRAW_FRONT) + vmesa->glCtx->Color._DrawDestMask = FRONT_LEFT_BIT; + + if (vmesa->glCtx->Color._DrawDestMask & BACK_LEFT_BIT) { + + *vb++ = HC_HEADER2; + *vb++ = (HC_ParaType_NotTex << 16); + if (vmesa->driDrawable->w == 0 || vmesa->driDrawable->h == 0) { + *vb++ = (HC_SubA_HClipTB << 24) | 0x0; + *vb++ = (HC_SubA_HClipLR << 24) | 0x0; + } + else { + *vb++ = ((HC_SubA_HClipTB << 24) | (0x0 << 12) | vmesa->driDrawable->h); + *vb++ = ((HC_SubA_HClipLR << 24) | (vmesa->drawXoff << 12) | (vmesa->driDrawable->w + vmesa->drawXoff)); + } + + { + GLuint pitch, format, offset; + + if (vmesa->viaScreen->bitsPerPixel == 0x20) { + format = HC_HDBFM_ARGB8888; + } + else if (vmesa->viaScreen->bitsPerPixel == 0x10) { + format = HC_HDBFM_RGB565; + } + else + return -1; + + offset = vmesa->back.offset; + pitch = vmesa->back.pitch; + + *vb++ = ((HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF)); + *vb++ = ((HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000)) >> 24); + *vb++ = ((HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch); + *vb++ = 0xcccccccc; + } + + *pnEngBaseTranSpace = (HC_SubA_HAGPBstL << 24) | + ((GLuint)(pnAGPCurrentPhysStart) & 0xFFFFFF); + *pnEngBaseTranSpace = (HC_SubA_HAGPBendL << 24) | + ((GLuint)(pnAGPCurrentPhysEnd) & 0xFFFFFF); + *pnEngBaseTranSpace = (HC_SubA_HAGPCMNT << 24) | + ((GLuint)(pnAGPCurrentPhysEnd) & 0xFF000000) >> 16 | + ((GLuint)(pnAGPCurrentPhysStart) & 0xFF000000) >> 24; + *pnEngBaseTranSpace = (HC_SubA_HAGPBpH << 24) | + ((GLuint)((GLbyte *)pnAGPCurrentPhysStart + agpCmd->size - 4) & 0xFF000000) >> 24; + *pnEngBaseTranSpace = (HC_SubA_HAGPBpL << 24) | + ((GLuint)((GLbyte *)pnAGPCurrentPhysStart + agpCmd->size - 4) & 0xFFFFFF) | + HC_HAGPBpID_STOP; + *pnEngBaseTranSpace = (HC_SubA_HAGPCMNT << 24) | + ((GLuint)(pnAGPCurrentPhysEnd) & 0xFF000000) >> 16 | + ((GLuint)(pnAGPCurrentPhysStart) & 0xFF000000) >> 24 | + HC_HAGPCMNT_MASK; + } + else { + GLuint *head; + GLuint clipL, clipR, clipT, clipB; + drm_clip_rect_t *b = vmesa->sarea->boxes; + *vb++ = HC_HEADER2; + *vb++ = (HC_ParaType_NotTex << 16); + head = vb; + + *pnEngBaseTranSpace = (HC_SubA_HAGPBstL << 24) | + ((GLuint)(pnAGPCurrentPhysStart) & 0xFFFFFF); + *pnEngBaseTranSpace = (HC_SubA_HAGPBendL << 24) | + ((GLuint)(pnAGPCurrentPhysEnd) & 0xFFFFFF); + *pnEngBaseTranSpace = (HC_SubA_HAGPCMNT << 24) | + ((GLuint)(pnAGPCurrentPhysEnd) & 0xFF000000) >> 16 | + ((GLuint)(pnAGPCurrentPhysStart) & 0xFF000000) >> 24; + *pnEngBaseTranSpace = (HC_SubA_HAGPBpH << 24) | + ((GLuint)((GLbyte *)pnAGPCurrentPhysStart + agpCmd->size - 4) & 0xFF000000) >> 24; + *pnEngBaseTranSpace = (HC_SubA_HAGPBpL << 24) | + ((GLuint)((GLbyte *)pnAGPCurrentPhysStart + agpCmd->size - 4) & 0xFFFFFF) | + HC_HAGPBpID_STOP; + + for (i = 0; i < vmesa->sarea->nbox; i++) { + if (1) { + volatile GLuint *pnEngBase = vmesa->regEngineStatus; + int nStatus; + + while (1) { + nStatus = *pnEngBase; + if ((nStatus & 0xFFFEFFFF) == 0x00020000) + break; + } + } + + clipL = b->x1 + vmesa->drawXoff; + clipR = b->x2; + clipT = b->y1; + clipB = b->y2; +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "clip = %d\n", i); +#endif + if (vmesa->driDrawable->w == 0 || vmesa->driDrawable->h == 0) { + + *vb = (HC_SubA_HClipTB << 24) | 0x0; + vb++; + + *vb = (HC_SubA_HClipLR << 24) | 0x0; + vb++; + } + else { + *vb = (HC_SubA_HClipTB << 24) | (clipT << 12) | clipB; + vb++; + + *vb = (HC_SubA_HClipLR << 24) | (clipL << 12) | clipR; + vb++; + } + + { + GLuint pitch, format, offset; + GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3; + + if (vmesa->viaScreen->bitsPerPixel == 0x20) { + format = HC_HDBFM_ARGB8888; + } + else if (vmesa->viaScreen->bitsPerPixel == 0x10) { + format = HC_HDBFM_RGB565; + } + else + return -1; + + pitch = vmesa->front.pitch; + offset = vmesa->viaScreen->fbOffset + (vmesa->drawY * pitch + vmesa->drawX * bytePerPixel); + offset = offset & 0xffffffe0; + + *vb++ = ((HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF)); + *vb++ = ((HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000)) >> 24); + *vb++ = ((HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch); + *vb++ = 0xcccccccc; + } + *pnEngBaseTranSpace = (HC_SubA_HAGPCMNT << 24) | + ((GLuint)(pnAGPCurrentPhysEnd) & 0xFF000000) >> 16 | + ((GLuint)(pnAGPCurrentPhysStart) & 0xFF000000) >> 24 | + HC_HAGPCMNT_MASK; +#ifdef DEBUG + if (VIA_DEBUG) { + GLuint i; + GLuint *data = (GLuint *)vmesa->dmaAddr; + for (i = 0; i < vmesa->dmaLow; i += 16) { + fprintf(stderr, "%08x ", *data++); + fprintf(stderr, "%08x ", *data++); + fprintf(stderr, "%08x ", *data++); + fprintf(stderr, "%08x\n", *data++); + } + fprintf(stderr, "******************************************\n"); + } +#endif + b++; + vb = head; + } + } + +#ifdef DEBUG + if (VIA_DEBUG) { + volatile GLuint *pnEngBase = (GLuint *)((GLuint)pnMMIOBase + 0x400); + int nStatus; + int i = 0; + + while (1) { + nStatus = *pnEngBase; + if ((nStatus & 0xFFFEFFFF) == 0x00020000) { + break; + } + else { + GLuint j; + GLuint *data; + /* dump current command buffer */ + data = (GLuint *)vmesa->dmaAddr; + + if (i == 500000) { + fprintf(stderr, "current command buffer"); + fprintf(stderr, "i = %d\n", i); + for (j = 0; j < vmesa->dmaLow; j += 16) { + fprintf(stderr, "%08x ", *data++); + fprintf(stderr, "%08x ", *data++); + fprintf(stderr, "%08x ", *data++); + fprintf(stderr, "%08x\n", *data++); + } + } + /* dump previous command buffer */ + if (vmesa->dmaIndex) { + data = (GLuint *)vmesa->dma[0].map; + } + else { + data = (GLuint *)vmesa->dma[1].map; + } + if (i == 500000) { + fprintf(stderr, "previous command buffer"); + fprintf(stderr, "i = %d\n", i); + for (j = 0; j < dmaLow; j += 16) { + fprintf(stderr, "%08x ", *data++); + fprintf(stderr, "%08x ", *data++); + fprintf(stderr, "%08x ", *data++); + fprintf(stderr, "%08x\n", *data++); + } + } + } + i++; + } + } +#endif + dmaLow = vmesa->dmaLow; + return 0; +} + +int flush_sys(viaContextPtr vmesa, drm_via_flush_sys_t* buf) + +{ + GLuint *pnBuf; + GLuint *pnEnd; + volatile GLuint *pnMMIOBase; + volatile GLuint *pnEngBaseTranSet; + volatile GLuint *pnEngBaseTranSpace; + GLuint uCheck2DCmd = GL_TRUE; + GLuint addr; + GLuint *vb = (GLuint *)vmesa->dmaAddr; + GLuint i = 0; + + pnMMIOBase = vmesa->regMMIOBase; + pnEngBaseTranSet = vmesa->regTranSet; + pnEngBaseTranSpace = vmesa->regTranSpace; + + pnBuf = (GLuint *)(buf->index + buf->offset); + pnEnd = (GLuint *)((GLuint)pnBuf + buf->size); + + /*=* [DBG] make draw to front buffer *=*/ + if(DRAW_FRONT) + vmesa->glCtx->Color._DrawDestMask = FRONT_LEFT_BIT; + + /*=* John Sheng [2003.6.20] fix pci *=*/ + { + volatile GLuint *pnEngBase = vmesa->regEngineStatus; + int nStatus; + + while (1) { + nStatus = *pnEngBase; + if ((nStatus & 0xFFFEFFFF) == 0x00020000) + break; + i++; + } + } + + if (vmesa->glCtx->Color._DrawDestMask & BACK_LEFT_BIT) { + *vb++ = HC_HEADER2; + *vb++ = (HC_ParaType_NotTex << 16); + + if (vmesa->driDrawable->w == 0 || vmesa->driDrawable->h == 0) { + *vb++ = (HC_SubA_HClipTB << 24) | 0x0; + *vb++ = (HC_SubA_HClipLR << 24) | 0x0; + } + else { + *vb++ = ((HC_SubA_HClipTB << 24) | (0x0 << 12) | vmesa->driDrawable->h); + *vb++ = ((HC_SubA_HClipLR << 24) | (vmesa->drawXoff << 12) | (vmesa->driDrawable->w + vmesa->drawXoff)); + } + + /*=* John Sheng [2003.6.16] fix pci path *=*/ + { + GLuint pitch, format, offset; + + if (vmesa->viaScreen->bitsPerPixel == 0x20) { + format = HC_HDBFM_ARGB8888; + } + else if (vmesa->viaScreen->bitsPerPixel == 0x10) { + format = HC_HDBFM_RGB565; + } + else + return -1; + + offset = vmesa->back.offset; + pitch = vmesa->back.pitch; + + *vb++ = ((HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF)); + *vb++ = ((HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000)) >> 24); + *vb++ = ((HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch); + *vb++ = 0xcccccccc; + } + + while (pnBuf != pnEnd) { + if (*pnBuf == HALCYON_HEADER2) { + pnBuf++; + if (*pnBuf == HALCYON_SUB_ADDR0) { + *pnEngBaseTranSet = *pnBuf; + pnBuf++; + uCheck2DCmd = GL_FALSE; + } + else { + *pnEngBaseTranSet = *pnBuf; + pnBuf++; + uCheck2DCmd = GL_TRUE; + } + } + else if (uCheck2DCmd && ((*pnBuf&HALCYON_HEADER1MASK)==HALCYON_HEADER1)) { + addr = ((*pnBuf)&0x0000001f) << 2; + pnBuf++; + *((GLuint*)((GLuint)pnMMIOBase+addr)) = *pnBuf; + pnBuf++; + } + else if ((*pnBuf&HALCYON_FIREMASK) == HALCYON_FIRECMD) { + *pnEngBaseTranSpace = *pnBuf; + pnBuf++; + if ((pnBuf!=pnEnd)&&((*pnBuf&HALCYON_FIREMASK)==HALCYON_FIRECMD)) + pnBuf++; + if ((*pnBuf&HALCYON_CMDBMASK) != HC_ACMD_HCmdB) + uCheck2DCmd = GL_TRUE; + } + else { + *pnEngBaseTranSpace = *pnBuf; + pnBuf++; + } + } + } + else { + GLuint *head; + GLuint clipL, clipR, clipT, clipB; + drm_clip_rect_t *b = vmesa->sarea->boxes; + GLuint *pnTmp; + + *vb++ = HC_HEADER2; + *vb++ = (HC_ParaType_NotTex << 16); + + head = vb; + pnTmp = pnBuf; + + for (i = 0; i < vmesa->sarea->nbox; i++) { + clipL = b->x1 + vmesa->drawXoff; + clipR = b->x2 + vmesa->drawXoff; + clipT = b->y1; + clipB = b->y2; + + if (vmesa->driDrawable->w == 0 || vmesa->driDrawable->h == 0) { + *vb = (HC_SubA_HClipTB << 24) | 0x0; + vb++; + *vb = (HC_SubA_HClipLR << 24) | 0x0; + vb++; + } + else { + *vb = (HC_SubA_HClipTB << 24) | (clipT << 12) | clipB; + vb++; + *vb = (HC_SubA_HClipLR << 24) | (clipL << 12) | clipR; + vb++; + } + + /*=* John Sheng [2003.6.16] fix pci path *=*/ + { + GLuint pitch, format, offset; + GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3; + + if (vmesa->viaScreen->bitsPerPixel == 0x20) { + format = HC_HDBFM_ARGB8888; + } + else if (vmesa->viaScreen->bitsPerPixel == 0x10) { + format = HC_HDBFM_RGB565; + } + else + return -1; + + pitch = vmesa->front.pitch; + offset = vmesa->viaScreen->fbOffset + (vmesa->drawY * pitch + vmesa->drawX * bytePerPixel); + offset = offset & 0xffffffe0; + + *vb++ = ((HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF)); + *vb++ = ((HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000)) >> 24); + *vb++ = ((HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch); + *vb++ = 0xcccccccc; + } + + pnBuf = pnTmp; + + while (pnBuf != pnEnd) { + if (*pnBuf == HALCYON_HEADER2) { + pnBuf++; + if (*pnBuf == HALCYON_SUB_ADDR0) { + *pnEngBaseTranSet = *pnBuf; + pnBuf++; + uCheck2DCmd = GL_FALSE; + } + else { + *pnEngBaseTranSet = *pnBuf; + pnBuf++; + uCheck2DCmd = GL_TRUE; + } + } + else if (uCheck2DCmd && ((*pnBuf&HALCYON_HEADER1MASK)==HALCYON_HEADER1)) { + addr = ((*pnBuf)&0x0000001f) << 2; + pnBuf++; + *((GLuint*)((GLuint)pnMMIOBase+addr)) = *pnBuf; + pnBuf++; + } + else if ((*pnBuf&HALCYON_FIREMASK) == HALCYON_FIRECMD) { + *pnEngBaseTranSpace = *pnBuf; + pnBuf++; + if ((pnBuf!=pnEnd)&&((*pnBuf&HALCYON_FIREMASK)==HALCYON_FIRECMD)) + pnBuf++; + if ((*pnBuf&HALCYON_CMDBMASK) != HC_ACMD_HCmdB) + uCheck2DCmd = GL_TRUE; + } + else { + *pnEngBaseTranSpace = *pnBuf; + pnBuf++; + } + } + b++; + vb = head; + } + } + return 0; +} |