1
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_clear.c,v 1.2 2002/02/22 21:32:58 dawes Exp $
3
* GLX Hardware Device Driver for Sun Creator/Creator3D
4
* Copyright (C) 2000 David S. Miller
6
* Permission is hereby granted, free of charge, to any person obtaining a
7
* copy of this software and associated documentation files (the "Software"),
8
* to deal in the Software without restriction, including without limitation
9
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
* and/or sell copies of the Software, and to permit persons to whom the
11
* Software is furnished to do so, subject to the following conditions:
13
* The above copyright notice and this permission notice shall be included
14
* in all copies or substantial portions of the Software.
16
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
* DAVID MILLER, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
20
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
22
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
* David S. Miller <davem@redhat.com>
29
#include "extensions.h"
34
#include "ffb_depth.h"
35
#include "ffb_context.h"
38
#include "ffb_clear.h"
43
#define BOX_AREA(__w, __h) ((int)(__w) * (int)(__h))
45
/* Compute the page aligned box for a page mode fast fill.
46
* In 'ework' this returns greater than zero if there are some odd
47
* edges to take care of which are outside of the page aligned area.
48
* It will place less than zero there if the box is too small,
49
* indicating that a different method must be used to fill it.
51
#define CreatorPageFillParms(ffp, x, y, w, h, px, py, pw, ph, ework) \
52
do { int xdiff, ydiff; \
53
int pf_bh = ffp->pagefill_height; \
54
int pf_bw = ffp->pagefill_width; \
55
py = ((y + (pf_bh - 1)) & ~(pf_bh - 1)); \
57
px = ffp->Pf_AlignTab[x + (pf_bw - 1)]; \
59
ph = ((h - ydiff) & ~(pf_bh - 1)); \
63
pw = ffp->Pf_AlignTab[w - xdiff]; \
67
ework = (((xdiff > 0) || \
70
((h - ph) > 0))) ? 1 : 0; \
76
int x, y, width, height;
79
/* Compute fixups of non-page aligned areas after a page fill.
80
* Return the number of fixups needed.
83
CreatorComputePageFillFixups(struct ff_fixups *fixups,
84
int x, int y, int w, int h,
85
int paligned_x, int paligned_y,
86
int paligned_w, int paligned_h)
92
fixups[nfixups].x = x;
93
fixups[nfixups].y = paligned_y;
94
fixups[nfixups].width = paligned_x - x;
95
fixups[nfixups].height = paligned_h;
100
fixups[nfixups].x = x;
101
fixups[nfixups].y = y;
102
fixups[nfixups].width = w;
103
fixups[nfixups].height = paligned_y - y;
107
if((x+w) != (paligned_x+paligned_w)) {
108
fixups[nfixups].x = (paligned_x+paligned_w);
109
fixups[nfixups].y = paligned_y;
110
fixups[nfixups].width = (x+w) - fixups[nfixups].x;
111
fixups[nfixups].height = paligned_h;
114
/* FastFill Bottom */
115
if((y+h) != (paligned_y+paligned_h)) {
116
fixups[nfixups].x = x;
117
fixups[nfixups].y = (paligned_y+paligned_h);
118
fixups[nfixups].width = w;
119
fixups[nfixups].height = (y+h) - fixups[nfixups].y;
126
ffb_do_clear(GLcontext *ctx, __DRIdrawablePrivate *dPriv)
128
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
129
FFBDRIPtr gDRIPriv = (FFBDRIPtr) fmesa->driScreen->pDevPriv;
130
ffb_fbcPtr ffb = fmesa->regs;
131
drm_clip_rect_t *box = dPriv->pClipRects;
132
int nc = dPriv->numClipRects;
133
GLint cx, cy, cw, ch;
135
/* compute region after locking: */
136
cx = ctx->DrawBuffer->_Xmin;
137
cy = ctx->DrawBuffer->_Ymin;
138
cw = ctx->DrawBuffer->_Xmax - cx;
139
ch = ctx->DrawBuffer->_Ymax - cy;
141
cy = dPriv->h - cy - ch;
146
GLint x = box[nc].x1;
147
GLint y = box[nc].y1;
148
GLint width = box[nc].x2 - x;
149
GLint height = box[nc].y2 - y;
150
int paligned_y, paligned_x;
151
int paligned_h, paligned_w = 0;
154
if (BOX_AREA(width, height) < gDRIPriv->fastfill_small_area) {
156
ffb->drawop = FFB_DRAWOP_RECTANGLE;
165
ffb->drawop = FFB_DRAWOP_FASTFILL;
167
if (gDRIPriv->disable_pagefill ||
168
(width < (gDRIPriv->pagefill_width<<1)) ||
169
(height < (gDRIPriv->pagefill_height<<1)))
172
CreatorPageFillParms(gDRIPriv,
174
paligned_x, paligned_y,
175
paligned_w, paligned_h, extra_work);
177
if (extra_work < 0 ||
178
BOX_AREA(paligned_w, paligned_h) < gDRIPriv->pagefill_small_area) {
181
ffb->by = FFB_FASTFILL_COLOR_BLK;
184
ffb->bh = gDRIPriv->fastfill_height;
185
ffb->bw = (gDRIPriv->fastfill_width * 4);
186
ffb->by = FFB_FASTFILL_BLOCK;
189
ffb->bh = (height + (y & (gDRIPriv->fastfill_height - 1)));
190
ffb->bx = (width + (x & (gDRIPriv->fastfill_width - 1)));
194
/* Ok, page fill is possible and worth it. */
196
ffb->by = FFB_FASTFILL_COLOR_BLK;
199
ffb->bh = gDRIPriv->fastfill_height;
200
ffb->bw = gDRIPriv->fastfill_width * 4;
201
ffb->by = FFB_FASTFILL_BLOCK_X;
204
ffb->bh = gDRIPriv->pagefill_height;
205
ffb->bw = gDRIPriv->pagefill_width * 4;
206
ffb->by = FFB_FASTFILL_PAGE;
207
ffb->dy = paligned_y;
208
ffb->dx = paligned_x;
209
ffb->bh = paligned_h;
210
ffb->bx = paligned_w;
213
struct ff_fixups local_fixups[4];
216
nfixups = CreatorComputePageFillFixups(local_fixups,
218
paligned_x, paligned_y,
219
paligned_w, paligned_h);
220
FFBFifo(fmesa, 5 + (nfixups * 5));
221
ffb->by = FFB_FASTFILL_COLOR_BLK;
224
ffb->bh = gDRIPriv->fastfill_height;
225
ffb->bw = gDRIPriv->fastfill_width * 4;
227
while (--nfixups >= 0) {
230
xx = local_fixups[nfixups].x;
231
yy = local_fixups[nfixups].y;
234
ww = (local_fixups[nfixups].width +
235
(xx & (gDRIPriv->fastfill_width - 1)));
236
hh = (local_fixups[nfixups].height +
237
(yy & (gDRIPriv->fastfill_height - 1)));
239
ffb->by = FFB_FASTFILL_BLOCK;
244
ffb->by = FFB_FASTFILL_BLOCK;
252
void ffbDDClear(GLcontext *ctx, GLbitfield mask)
254
ffbContextPtr fmesa = FFB_CONTEXT(ctx);
255
__DRIdrawablePrivate *dPriv = fmesa->driDrawable;
256
unsigned int stcmask = BUFFER_BIT_STENCIL;
259
fprintf(stderr, "ffbDDClear: mask(%08x) \n", mask);
261
if (!(fmesa->ffb_sarea->flags & FFB_DRI_FFB2PLUS))
264
if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT | BUFFER_BIT_DEPTH | stcmask)) {
265
ffb_fbcPtr ffb = fmesa->regs;
266
unsigned int fbc, ppc;
268
fbc = (FFB_FBC_XE_ON);
269
ppc = (FFB_PPC_ACE_DISABLE | FFB_PPC_DCE_DISABLE |
270
FFB_PPC_ABE_DISABLE | FFB_PPC_VCE_DISABLE |
271
FFB_PPC_APE_DISABLE | FFB_PPC_XS_WID |
272
FFB_PPC_ZS_CONST | FFB_PPC_CS_CONST);
274
/* Y/X enables must be both on or both off. */
275
if (mask & (BUFFER_BIT_DEPTH | stcmask)) {
276
fbc |= (FFB_FBC_ZE_ON | FFB_FBC_YE_ON | FFB_FBC_WB_C);
278
fbc |= FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF;
280
/* All RGB enables must be both on or both off. */
281
if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT)) {
282
if (mask & BUFFER_BIT_FRONT_LEFT) {
283
if (fmesa->back_buffer == 0)
288
if (mask & BUFFER_BIT_BACK_LEFT) {
289
if (fmesa->back_buffer == 0)
294
fbc |= FFB_FBC_RGBE_ON;
296
fbc |= FFB_FBC_RGBE_OFF;
298
LOCK_HARDWARE(fmesa);
300
if (dPriv->numClipRects) {
304
ffb->xclip = FFB_XCLIP_TEST_ALWAYS;
305
ffb->cmp = 0x80808080;
306
ffb->rop = FFB_ROP_NEW;
308
if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT))
309
ffb->fg = fmesa->clear_pixel;
310
if (mask & BUFFER_BIT_DEPTH)
311
ffb->constz = fmesa->clear_depth;
313
ffb->consty = fmesa->clear_stencil;
315
ffb_do_clear(ctx, dPriv);
318
ffb->ppc = fmesa->ppc;
319
ffb->fbc = fmesa->fbc;
320
ffb->xclip = fmesa->xclip;
321
ffb->cmp = fmesa->cmp;
322
ffb->rop = fmesa->rop;
323
ffb->drawop = fmesa->drawop;
325
ffb->consty = fmesa->consty;
326
fmesa->ffbScreen->rp_active = 1;
329
UNLOCK_HARDWARE(fmesa);
331
mask &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT |
332
BUFFER_BIT_DEPTH | stcmask);
336
_swrast_Clear(ctx, mask);