~ubuntu-branches/ubuntu/quantal/mesa-glw/quantal

« back to all changes in this revision

Viewing changes to src/mesa/drivers/dri/ffb/ffb_clear.c

  • Committer: Bazaar Package Importer
  • Author(s): Morten Kjeldgaard
  • Date: 2008-05-06 16:19:15 UTC
  • Revision ID: james.westby@ubuntu.com-20080506161915-uynz7nftmfixu6bq
Tags: upstream-7.0.3
ImportĀ upstreamĀ versionĀ 7.0.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_clear.c,v 1.2 2002/02/22 21:32:58 dawes Exp $
 
2
 *
 
3
 * GLX Hardware Device Driver for Sun Creator/Creator3D
 
4
 * Copyright (C) 2000 David S. Miller
 
5
 *
 
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:
 
12
 *
 
13
 * The above copyright notice and this permission notice shall be included
 
14
 * in all copies or substantial portions of the Software.
 
15
 *
 
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.
 
23
 *
 
24
 *
 
25
 *    David S. Miller <davem@redhat.com>
 
26
 */
 
27
 
 
28
#include "mtypes.h"
 
29
#include "extensions.h"
 
30
 
 
31
#include "mm.h"
 
32
#include "ffb_dd.h"
 
33
#include "ffb_span.h"
 
34
#include "ffb_depth.h"
 
35
#include "ffb_context.h"
 
36
#include "ffb_vb.h"
 
37
#include "ffb_tris.h"
 
38
#include "ffb_clear.h"
 
39
#include "ffb_lock.h"
 
40
 
 
41
#undef CLEAR_TRACE
 
42
 
 
43
#define BOX_AREA(__w, __h)      ((int)(__w) * (int)(__h))
 
44
 
 
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.
 
50
 */
 
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)); \
 
56
        ydiff = py - y; \
 
57
        px = ffp->Pf_AlignTab[x + (pf_bw - 1)]; \
 
58
        xdiff = px - x; \
 
59
        ph = ((h - ydiff) & ~(pf_bh - 1)); \
 
60
        if(ph <= 0) \
 
61
                ework = -1; \
 
62
        else { \
 
63
                pw = ffp->Pf_AlignTab[w - xdiff]; \
 
64
                if(pw <= 0) { \
 
65
                        ework = -1; \
 
66
                } else { \
 
67
                        ework = (((xdiff > 0)           || \
 
68
                                  (ydiff > 0)           || \
 
69
                                  ((w - pw) > 0)        || \
 
70
                                  ((h - ph) > 0))) ? 1 : 0; \
 
71
                } \
 
72
        } \
 
73
} while(0);
 
74
 
 
75
struct ff_fixups {
 
76
        int x, y, width, height;
 
77
};
 
78
 
 
79
/* Compute fixups of non-page aligned areas after a page fill.
 
80
 * Return the number of fixups needed.
 
81
 */
 
82
static __inline__ int
 
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)
 
87
{
 
88
        int nfixups = 0;
 
89
 
 
90
        /* FastFill Left */
 
91
        if(paligned_x != x) {
 
92
                fixups[nfixups].x = x;
 
93
                fixups[nfixups].y = paligned_y;
 
94
                fixups[nfixups].width = paligned_x - x;
 
95
                fixups[nfixups].height = paligned_h;
 
96
                nfixups++;
 
97
        }
 
98
        /* FastFill Top */
 
99
        if(paligned_y != y) {
 
100
                fixups[nfixups].x = x;
 
101
                fixups[nfixups].y = y;
 
102
                fixups[nfixups].width = w;
 
103
                fixups[nfixups].height = paligned_y - y;
 
104
                nfixups++;
 
105
        }
 
106
        /* FastFill Right */
 
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;
 
112
                nfixups++;
 
113
        }
 
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;
 
120
                nfixups++;
 
121
        }
 
122
        return nfixups;
 
123
}
 
124
 
 
125
static void
 
126
ffb_do_clear(GLcontext *ctx, __DRIdrawablePrivate *dPriv)
 
127
{
 
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;
 
134
 
 
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;
 
140
 
 
141
        cy  = dPriv->h - cy - ch;
 
142
        cx += dPriv->x;
 
143
        cy += dPriv->y;
 
144
 
 
145
        while (nc--) {
 
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;
 
152
                int extra_work;
 
153
 
 
154
                if (BOX_AREA(width, height) < gDRIPriv->fastfill_small_area) {
 
155
                        FFBFifo(fmesa, 5);
 
156
                        ffb->drawop = FFB_DRAWOP_RECTANGLE;
 
157
                        ffb->by = y;
 
158
                        ffb->bx = x;
 
159
                        ffb->bh = height;
 
160
                        ffb->bw = width;
 
161
                        continue;
 
162
                }
 
163
 
 
164
                FFBFifo(fmesa, 1);
 
165
                ffb->drawop = FFB_DRAWOP_FASTFILL;
 
166
 
 
167
                if (gDRIPriv->disable_pagefill ||
 
168
                    (width < (gDRIPriv->pagefill_width<<1)) ||
 
169
                    (height < (gDRIPriv->pagefill_height<<1)))
 
170
                        goto do_fastfill;
 
171
 
 
172
                CreatorPageFillParms(gDRIPriv,
 
173
                                     x, y, width, height,
 
174
                                     paligned_x, paligned_y,
 
175
                                     paligned_w, paligned_h, extra_work);
 
176
 
 
177
                if (extra_work < 0 ||
 
178
                    BOX_AREA(paligned_w, paligned_h) < gDRIPriv->pagefill_small_area) {
 
179
                do_fastfill:
 
180
                        FFBFifo(fmesa, 10);
 
181
                        ffb->by = FFB_FASTFILL_COLOR_BLK;
 
182
                        ffb->dy = 0;
 
183
                        ffb->dx = 0;
 
184
                        ffb->bh = gDRIPriv->fastfill_height;
 
185
                        ffb->bw = (gDRIPriv->fastfill_width * 4);
 
186
                        ffb->by = FFB_FASTFILL_BLOCK;
 
187
                        ffb->dy = y;
 
188
                        ffb->dx = x;
 
189
                        ffb->bh = (height + (y & (gDRIPriv->fastfill_height - 1)));
 
190
                        ffb->bx = (width + (x & (gDRIPriv->fastfill_width - 1)));
 
191
                        continue;
 
192
                }
 
193
 
 
194
                /* Ok, page fill is possible and worth it. */
 
195
                FFBFifo(fmesa, 15);
 
196
                ffb->by = FFB_FASTFILL_COLOR_BLK;
 
197
                ffb->dy = 0;
 
198
                ffb->dx = 0;
 
199
                ffb->bh = gDRIPriv->fastfill_height;
 
200
                ffb->bw = gDRIPriv->fastfill_width * 4;
 
201
                ffb->by = FFB_FASTFILL_BLOCK_X;
 
202
                ffb->dy = 0;
 
203
                ffb->dx = 0;
 
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;
 
211
 
 
212
                if (extra_work) {
 
213
                        struct ff_fixups local_fixups[4];
 
214
                        int nfixups;
 
215
 
 
216
                        nfixups = CreatorComputePageFillFixups(local_fixups,
 
217
                                                               x, y, width, height,
 
218
                                                               paligned_x, paligned_y,
 
219
                                                               paligned_w, paligned_h);
 
220
                        FFBFifo(fmesa, 5 + (nfixups * 5));
 
221
                        ffb->by = FFB_FASTFILL_COLOR_BLK;
 
222
                        ffb->dy = 0;
 
223
                        ffb->dx = 0;
 
224
                        ffb->bh = gDRIPriv->fastfill_height;
 
225
                        ffb->bw = gDRIPriv->fastfill_width * 4;
 
226
 
 
227
                        while (--nfixups >= 0) {
 
228
                                int xx, yy, ww, hh;
 
229
 
 
230
                                xx = local_fixups[nfixups].x;
 
231
                                yy = local_fixups[nfixups].y;
 
232
                                ffb->dy = yy;
 
233
                                ffb->dx = xx;
 
234
                                ww = (local_fixups[nfixups].width +
 
235
                                      (xx & (gDRIPriv->fastfill_width - 1)));
 
236
                                hh = (local_fixups[nfixups].height +
 
237
                                      (yy & (gDRIPriv->fastfill_height - 1)));
 
238
                                if (nfixups != 0) {
 
239
                                        ffb->by = FFB_FASTFILL_BLOCK;
 
240
                                        ffb->bh = hh;
 
241
                                        ffb->bw = ww;
 
242
                                } else {
 
243
                                        ffb->bh = hh;
 
244
                                        ffb->by = FFB_FASTFILL_BLOCK;
 
245
                                        ffb->bx = ww;
 
246
                                }
 
247
                        }
 
248
                }
 
249
        }
 
250
}
 
251
 
 
252
void ffbDDClear(GLcontext *ctx, GLbitfield mask)
 
253
{
 
254
        ffbContextPtr fmesa = FFB_CONTEXT(ctx);
 
255
        __DRIdrawablePrivate *dPriv = fmesa->driDrawable;
 
256
        unsigned int stcmask = BUFFER_BIT_STENCIL;
 
257
 
 
258
#ifdef CLEAR_TRACE
 
259
        fprintf(stderr, "ffbDDClear: mask(%08x) \n", mask);
 
260
#endif
 
261
        if (!(fmesa->ffb_sarea->flags & FFB_DRI_FFB2PLUS))
 
262
                stcmask = 0;
 
263
 
 
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;
 
267
 
 
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);
 
273
 
 
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);
 
277
                } else
 
278
                        fbc |= FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF;
 
279
 
 
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)
 
284
                                        fbc |= FFB_FBC_WB_B;
 
285
                                else
 
286
                                        fbc |= FFB_FBC_WB_A;
 
287
                        }
 
288
                        if (mask & BUFFER_BIT_BACK_LEFT) {
 
289
                                if (fmesa->back_buffer == 0)
 
290
                                        fbc |= FFB_FBC_WB_A;
 
291
                                else
 
292
                                        fbc |= FFB_FBC_WB_B;
 
293
                        }
 
294
                        fbc |= FFB_FBC_RGBE_ON;
 
295
                } else
 
296
                        fbc |= FFB_FBC_RGBE_OFF;
 
297
 
 
298
                LOCK_HARDWARE(fmesa);
 
299
 
 
300
                if (dPriv->numClipRects) {
 
301
                        FFBFifo(fmesa, 8);
 
302
                        ffb->fbc = fbc;
 
303
                        ffb->ppc = ppc;
 
304
                        ffb->xclip = FFB_XCLIP_TEST_ALWAYS;
 
305
                        ffb->cmp = 0x80808080;
 
306
                        ffb->rop = FFB_ROP_NEW;
 
307
 
 
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;
 
312
                        if (mask & stcmask)
 
313
                                ffb->consty = fmesa->clear_stencil;
 
314
 
 
315
                        ffb_do_clear(ctx, dPriv);
 
316
 
 
317
                        FFBFifo(fmesa, 6);
 
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;
 
324
                        if (mask & stcmask)
 
325
                                ffb->consty = fmesa->consty;
 
326
                        fmesa->ffbScreen->rp_active = 1;
 
327
                }
 
328
 
 
329
                UNLOCK_HARDWARE(fmesa);
 
330
 
 
331
                mask &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT |
 
332
                          BUFFER_BIT_DEPTH | stcmask);
 
333
        }
 
334
 
 
335
        if (mask) 
 
336
                _swrast_Clear(ctx, mask);
 
337
}
 
338