From 13e6a4849c6800eac454fd1010cb2320874f2ed6 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Thu, 4 Dec 2003 13:38:06 +0000 Subject: add SPARC ffb DRI driver --- src/mesa/drivers/dri/ffb/ffb_clear.c | 354 +++++++++++++++++++++++++++++++++++ 1 file changed, 354 insertions(+) create mode 100644 src/mesa/drivers/dri/ffb/ffb_clear.c (limited to 'src/mesa/drivers/dri/ffb/ffb_clear.c') diff --git a/src/mesa/drivers/dri/ffb/ffb_clear.c b/src/mesa/drivers/dri/ffb/ffb_clear.c new file mode 100644 index 0000000000..5285774f6f --- /dev/null +++ b/src/mesa/drivers/dri/ffb/ffb_clear.c @@ -0,0 +1,354 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_clear.c,v 1.2 2002/02/22 21:32:58 dawes Exp $ + * + * GLX Hardware Device Driver for Sun Creator/Creator3D + * Copyright (C) 2000 David S. Miller + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * DAVID MILLER, OR ANY OTHER CONTRIBUTORS 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. + * + * + * David S. Miller + */ + +#include "mtypes.h" +#include "extensions.h" + +#include "mm.h" +#include "ffb_dd.h" +#include "ffb_span.h" +#include "ffb_depth.h" +#include "ffb_context.h" +#include "ffb_vb.h" +#include "ffb_tris.h" +#include "ffb_clear.h" +#include "ffb_lock.h" + +#undef CLEAR_TRACE + +#define BOX_AREA(__w, __h) ((int)(__w) * (int)(__h)) + +/* Compute the page aligned box for a page mode fast fill. + * In 'ework' this returns greater than zero if there are some odd + * edges to take care of which are outside of the page aligned area. + * It will place less than zero there if the box is too small, + * indicating that a different method must be used to fill it. + */ +#define CreatorPageFillParms(ffp, x, y, w, h, px, py, pw, ph, ework) \ +do { int xdiff, ydiff; \ + int pf_bh = ffp->pagefill_height; \ + int pf_bw = ffp->pagefill_width; \ + py = ((y + (pf_bh - 1)) & ~(pf_bh - 1)); \ + ydiff = py - y; \ + px = ffp->Pf_AlignTab[x + (pf_bw - 1)]; \ + xdiff = px - x; \ + ph = ((h - ydiff) & ~(pf_bh - 1)); \ + if(ph <= 0) \ + ework = -1; \ + else { \ + pw = ffp->Pf_AlignTab[w - xdiff]; \ + if(pw <= 0) { \ + ework = -1; \ + } else { \ + ework = (((xdiff > 0) || \ + (ydiff > 0) || \ + ((w - pw) > 0) || \ + ((h - ph) > 0))) ? 1 : 0; \ + } \ + } \ +} while(0); + +struct ff_fixups { + int x, y, width, height; +}; + +/* Compute fixups of non-page aligned areas after a page fill. + * Return the number of fixups needed. + */ +static __inline__ int +CreatorComputePageFillFixups(struct ff_fixups *fixups, + int x, int y, int w, int h, + int paligned_x, int paligned_y, + int paligned_w, int paligned_h) +{ + int nfixups = 0; + + /* FastFill Left */ + if(paligned_x != x) { + fixups[nfixups].x = x; + fixups[nfixups].y = paligned_y; + fixups[nfixups].width = paligned_x - x; + fixups[nfixups].height = paligned_h; + nfixups++; + } + /* FastFill Top */ + if(paligned_y != y) { + fixups[nfixups].x = x; + fixups[nfixups].y = y; + fixups[nfixups].width = w; + fixups[nfixups].height = paligned_y - y; + nfixups++; + } + /* FastFill Right */ + if((x+w) != (paligned_x+paligned_w)) { + fixups[nfixups].x = (paligned_x+paligned_w); + fixups[nfixups].y = paligned_y; + fixups[nfixups].width = (x+w) - fixups[nfixups].x; + fixups[nfixups].height = paligned_h; + nfixups++; + } + /* FastFill Bottom */ + if((y+h) != (paligned_y+paligned_h)) { + fixups[nfixups].x = x; + fixups[nfixups].y = (paligned_y+paligned_h); + fixups[nfixups].width = w; + fixups[nfixups].height = (y+h) - fixups[nfixups].y; + nfixups++; + } + return nfixups; +} + +static void +ffb_do_clear(ffbContextPtr fmesa, __DRIdrawablePrivate *dPriv, + GLboolean all, GLint cx, GLint cy, GLint cwidth, + GLint cheight) +{ + FFBDRIPtr gDRIPriv = (FFBDRIPtr) fmesa->driScreen->pDevPriv; + ffb_fbcPtr ffb = fmesa->regs; + XF86DRIClipRectPtr box = dPriv->pClipRects; + int nc = dPriv->numClipRects; + + cy = dPriv->h - cy - cheight; + cx += dPriv->x; + cy += dPriv->y; + + while (nc--) { + GLint x = box[nc].x1; + GLint y = box[nc].y1; + GLint width = box[nc].x2 - x; + GLint height = box[nc].y2 - y; + int paligned_y, paligned_x; + int paligned_h, paligned_w = 0; + int extra_work; + + if (!all) { + if (x < cx) { + width -= cx - x; + x = cx; + } + if (y < cy) { + height -= cy - y; + y = cy; + } + if (x + width > cx + cwidth) + width = cx + cwidth - x; + if (y + height > cy + cheight) + height = cy + cheight - y; + if (width <= 0) + continue; + if (height <= 0) + continue; + } + + if (BOX_AREA(width, height) < gDRIPriv->fastfill_small_area) { + FFBFifo(fmesa, 5); + ffb->drawop = FFB_DRAWOP_RECTANGLE; + ffb->by = y; + ffb->bx = x; + ffb->bh = height; + ffb->bw = width; + continue; + } + + FFBFifo(fmesa, 1); + ffb->drawop = FFB_DRAWOP_FASTFILL; + + if (gDRIPriv->disable_pagefill || + (width < (gDRIPriv->pagefill_width<<1)) || + (height < (gDRIPriv->pagefill_height<<1))) + goto do_fastfill; + + CreatorPageFillParms(gDRIPriv, + x, y, width, height, + paligned_x, paligned_y, + paligned_w, paligned_h, extra_work); + + if (extra_work < 0 || + BOX_AREA(paligned_w, paligned_h) < gDRIPriv->pagefill_small_area) { + do_fastfill: + FFBFifo(fmesa, 10); + ffb->by = FFB_FASTFILL_COLOR_BLK; + ffb->dy = 0; + ffb->dx = 0; + ffb->bh = gDRIPriv->fastfill_height; + ffb->bw = (gDRIPriv->fastfill_width * 4); + ffb->by = FFB_FASTFILL_BLOCK; + ffb->dy = y; + ffb->dx = x; + ffb->bh = (height + (y & (gDRIPriv->fastfill_height - 1))); + ffb->bx = (width + (x & (gDRIPriv->fastfill_width - 1))); + continue; + } + + /* Ok, page fill is possible and worth it. */ + FFBFifo(fmesa, 15); + ffb->by = FFB_FASTFILL_COLOR_BLK; + ffb->dy = 0; + ffb->dx = 0; + ffb->bh = gDRIPriv->fastfill_height; + ffb->bw = gDRIPriv->fastfill_width * 4; + ffb->by = FFB_FASTFILL_BLOCK_X; + ffb->dy = 0; + ffb->dx = 0; + ffb->bh = gDRIPriv->pagefill_height; + ffb->bw = gDRIPriv->pagefill_width * 4; + ffb->by = FFB_FASTFILL_PAGE; + ffb->dy = paligned_y; + ffb->dx = paligned_x; + ffb->bh = paligned_h; + ffb->bx = paligned_w; + + if (extra_work) { + struct ff_fixups local_fixups[4]; + int nfixups; + + nfixups = CreatorComputePageFillFixups(local_fixups, + x, y, width, height, + paligned_x, paligned_y, + paligned_w, paligned_h); + FFBFifo(fmesa, 5 + (nfixups * 5)); + ffb->by = FFB_FASTFILL_COLOR_BLK; + ffb->dy = 0; + ffb->dx = 0; + ffb->bh = gDRIPriv->fastfill_height; + ffb->bw = gDRIPriv->fastfill_width * 4; + + while (--nfixups >= 0) { + int xx, yy, ww, hh; + + xx = local_fixups[nfixups].x; + yy = local_fixups[nfixups].y; + ffb->dy = yy; + ffb->dx = xx; + ww = (local_fixups[nfixups].width + + (xx & (gDRIPriv->fastfill_width - 1))); + hh = (local_fixups[nfixups].height + + (yy & (gDRIPriv->fastfill_height - 1))); + if (nfixups != 0) { + ffb->by = FFB_FASTFILL_BLOCK; + ffb->bh = hh; + ffb->bw = ww; + } else { + ffb->bh = hh; + ffb->by = FFB_FASTFILL_BLOCK; + ffb->bx = ww; + } + } + } + } +} + +void ffbDDClear(GLcontext *ctx, GLbitfield mask, GLboolean all, + GLint cx, GLint cy, GLint cwidth, GLint cheight) +{ + ffbContextPtr fmesa = FFB_CONTEXT(ctx); + __DRIdrawablePrivate *dPriv = fmesa->driDrawable; + unsigned int stcmask = DD_STENCIL_BIT; + +#ifdef CLEAR_TRACE + fprintf(stderr, "ffbDDClear: mask(%08x) all(%d) " + "[x(%x)y(%x)w(%x)h(%x)]\n", + mask, (int) all, cx, cy, cwidth, cheight); +#endif + if (!(fmesa->ffb_sarea->flags & FFB_DRI_FFB2PLUS)) + stcmask = 0; + + if (mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT | DD_DEPTH_BIT | stcmask)) { + ffb_fbcPtr ffb = fmesa->regs; + unsigned int fbc, ppc; + + fbc = (FFB_FBC_XE_ON); + ppc = (FFB_PPC_ACE_DISABLE | FFB_PPC_DCE_DISABLE | + FFB_PPC_ABE_DISABLE | FFB_PPC_VCE_DISABLE | + FFB_PPC_APE_DISABLE | FFB_PPC_XS_WID | + FFB_PPC_ZS_CONST | FFB_PPC_CS_CONST); + + /* Y/X enables must be both on or both off. */ + if (mask & (DD_DEPTH_BIT | stcmask)) { + fbc |= (FFB_FBC_ZE_ON | FFB_FBC_YE_ON | FFB_FBC_WB_C); + } else + fbc |= FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF; + + /* All RGB enables must be both on or both off. */ + if (mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT)) { + if (mask & DD_FRONT_LEFT_BIT) { + if (fmesa->back_buffer == 0) + fbc |= FFB_FBC_WB_B; + else + fbc |= FFB_FBC_WB_A; + } + if (mask & DD_BACK_LEFT_BIT) { + if (fmesa->back_buffer == 0) + fbc |= FFB_FBC_WB_A; + else + fbc |= FFB_FBC_WB_B; + } + fbc |= FFB_FBC_RGBE_ON; + } else + fbc |= FFB_FBC_RGBE_OFF; + + LOCK_HARDWARE(fmesa); + + if (dPriv->numClipRects) { + FFBFifo(fmesa, 8); + ffb->fbc = fbc; + ffb->ppc = ppc; + ffb->xclip = FFB_XCLIP_TEST_ALWAYS; + ffb->cmp = 0x80808080; + ffb->rop = FFB_ROP_NEW; + + if (mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT)) + ffb->fg = fmesa->clear_pixel; + if (mask & DD_DEPTH_BIT) + ffb->constz = fmesa->clear_depth; + if (mask & stcmask) + ffb->consty = fmesa->clear_stencil; + + ffb_do_clear(fmesa, dPriv, all, cx, cy, cwidth, cheight); + + FFBFifo(fmesa, 6); + ffb->ppc = fmesa->ppc; + ffb->fbc = fmesa->fbc; + ffb->xclip = fmesa->xclip; + ffb->cmp = fmesa->cmp; + ffb->rop = fmesa->rop; + ffb->drawop = fmesa->drawop; + if (mask & stcmask) + ffb->consty = fmesa->consty; + fmesa->ffbScreen->rp_active = 1; + } + + UNLOCK_HARDWARE(fmesa); + + mask &= ~(DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT | + DD_DEPTH_BIT | stcmask); + } + + if (mask) + _swrast_Clear(ctx, mask, all, cx, cy, cwidth, cheight); +} + -- cgit v1.2.3