~ubuntu-branches/ubuntu/intrepid/xserver-xgl/intrepid

« back to all changes in this revision

Viewing changes to hw/kdrive/ati/ati_draw.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Garrett
  • Date: 2006-02-13 14:21:43 UTC
  • Revision ID: james.westby@ubuntu.com-20060213142143-mad6z9xzem7hzxz9
Tags: upstream-7.0.0
ImportĀ upstreamĀ versionĀ 7.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * $Id: ati_draw.c,v 1.36 2005/12/27 08:29:44 ajax Exp $
 
3
 *
 
4
 * Copyright ļæ½ 2003 Eric Anholt
 
5
 *
 
6
 * Permission to use, copy, modify, distribute, and sell this software and its
 
7
 * documentation for any purpose is hereby granted without fee, provided that
 
8
 * the above copyright notice appear in all copies and that both that
 
9
 * copyright notice and this permission notice appear in supporting
 
10
 * documentation, and that the name of Eric Anholt not be used in
 
11
 * advertising or publicity pertaining to distribution of the software without
 
12
 * specific, written prior permission.  Eric Anholt makes no
 
13
 * representations about the suitability of this software for any purpose.  It
 
14
 * is provided "as is" without express or implied warranty.
 
15
 *
 
16
 * ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 
17
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 
18
 * EVENT SHALL ERIC ANHOLT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 
19
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 
20
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 
21
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 
22
 * PERFORMANCE OF THIS SOFTWARE.
 
23
 */
 
24
/* $Header: /cvs/xorg/xserver/xorg/hw/kdrive/ati/ati_draw.c,v 1.36 2005/12/27 08:29:44 ajax Exp $ */
 
25
 
 
26
#ifdef HAVE_CONFIG_H
 
27
#include <kdrive-config.h>
 
28
#endif
 
29
#include "ati.h"
 
30
#include "ati_reg.h"
 
31
#include "ati_dma.h"
 
32
#include "ati_draw.h"
 
33
#include "kaa.h"
 
34
 
 
35
CARD8 ATISolidRop[16] = {
 
36
    /* GXclear      */      0x00,         /* 0 */
 
37
    /* GXand        */      0xa0,         /* src AND dst */
 
38
    /* GXandReverse */      0x50,         /* src AND NOT dst */
 
39
    /* GXcopy       */      0xf0,         /* src */
 
40
    /* GXandInverted*/      0x0a,         /* NOT src AND dst */
 
41
    /* GXnoop       */      0xaa,         /* dst */
 
42
    /* GXxor        */      0x5a,         /* src XOR dst */
 
43
    /* GXor         */      0xfa,         /* src OR dst */
 
44
    /* GXnor        */      0x05,         /* NOT src AND NOT dst */
 
45
    /* GXequiv      */      0xa5,         /* NOT src XOR dst */
 
46
    /* GXinvert     */      0x55,         /* NOT dst */
 
47
    /* GXorReverse  */      0xf5,         /* src OR NOT dst */
 
48
    /* GXcopyInverted*/     0x0f,         /* NOT src */
 
49
    /* GXorInverted */      0xaf,         /* NOT src OR dst */
 
50
    /* GXnand       */      0x5f,         /* NOT src OR NOT dst */
 
51
    /* GXset        */      0xff,         /* 1 */
 
52
};
 
53
 
 
54
CARD8 ATIBltRop[16] = {
 
55
    /* GXclear      */      0x00,         /* 0 */
 
56
    /* GXand        */      0x88,         /* src AND dst */
 
57
    /* GXandReverse */      0x44,         /* src AND NOT dst */
 
58
    /* GXcopy       */      0xcc,         /* src */
 
59
    /* GXandInverted*/      0x22,         /* NOT src AND dst */
 
60
    /* GXnoop       */      0xaa,         /* dst */
 
61
    /* GXxor        */      0x66,         /* src XOR dst */
 
62
    /* GXor         */      0xee,         /* src OR dst */
 
63
    /* GXnor        */      0x11,         /* NOT src AND NOT dst */
 
64
    /* GXequiv      */      0x99,         /* NOT src XOR dst */
 
65
    /* GXinvert     */      0x55,         /* NOT dst */
 
66
    /* GXorReverse  */      0xdd,         /* src OR NOT dst */
 
67
    /* GXcopyInverted*/     0x33,         /* NOT src */
 
68
    /* GXorInverted */      0xbb,         /* NOT src OR dst */
 
69
    /* GXnand       */      0x77,         /* NOT src OR NOT dst */
 
70
    /* GXset        */      0xff,         /* 1 */
 
71
};
 
72
 
 
73
int copydx, copydy;
 
74
ATIScreenInfo *accel_atis;
 
75
/* If is_24bpp is set, then we are using the accelerator in 8-bit mode due
 
76
 * to it being broken for 24bpp, so coordinates have to be multiplied by 3.
 
77
 */
 
78
Bool is_24bpp;
 
79
CARD32 settings, color, src_pitch_offset, dst_pitch_offset;
 
80
 
 
81
int sample_count;
 
82
float sample_offsets_x[255];
 
83
float sample_offsets_y[255];
 
84
 
 
85
#define DRAW_USING_PACKET3 0
 
86
 
 
87
void
 
88
ATIDrawSetup(ScreenPtr pScreen)
 
89
{
 
90
        KdScreenPriv(pScreen);
 
91
        ATIScreenInfo(pScreenPriv);
 
92
        ATICardInfo(pScreenPriv);
 
93
        RING_LOCALS;
 
94
 
 
95
        /* XXX: this shouldn't be necessary, but fixes some R128 composite
 
96
         * issues.
 
97
         */
 
98
        /*if (!atic->is_radeon) {
 
99
                char *mmio = atic->reg_base;
 
100
                ATIWaitIdle(atis);
 
101
                MMIO_OUT32(mmio, R128_REG_PC_GUI_MODE,
 
102
                    R128_PC_BYPASS_EN);
 
103
        }*/
 
104
 
 
105
        BEGIN_DMA(2);
 
106
        OUT_REG(ATI_REG_DEFAULT_SC_BOTTOM_RIGHT,
 
107
            ATI_DEFAULT_SC_RIGHT_MAX | ATI_DEFAULT_SC_BOTTOM_MAX);
 
108
        END_DMA();
 
109
 
 
110
        if (!atic->is_radeon) {
 
111
                /* Setup for R128 Composite */
 
112
                BEGIN_DMA(12);
 
113
                OUT_REG(R128_REG_SCALE_3D_CNTL,
 
114
                    R128_SCALE_3D_TEXMAP_SHADE |
 
115
                    R128_SCALE_PIX_REPLICATE |
 
116
                    R128_TEX_CACHE_SPLIT |
 
117
                    R128_TEX_MAP_ALPHA_IN_TEXTURE |
 
118
                    R128_TEX_CACHE_LINE_SIZE_4QW);
 
119
                OUT_REG(R128_REG_SETUP_CNTL,
 
120
                    R128_COLOR_SOLID_COLOR |
 
121
                    R128_PRIM_TYPE_TRI |
 
122
                    R128_TEXTURE_ST_MULT_W |
 
123
                    R128_STARTING_VERTEX_1 |
 
124
                    R128_ENDING_VERTEX_3 |
 
125
                    R128_SUB_PIX_4BITS);
 
126
                OUT_REG(R128_REG_PM4_VC_FPU_SETUP,
 
127
                    R128_FRONT_DIR_CCW |
 
128
                    R128_BACKFACE_CULL |
 
129
                    R128_FRONTFACE_SOLID |
 
130
                    R128_FPU_COLOR_SOLID |
 
131
                    R128_FPU_SUB_PIX_4BITS |
 
132
                    R128_FPU_MODE_3D |
 
133
                    R128_TRAP_BITS_DISABLE |
 
134
                    R128_XFACTOR_2 |
 
135
                    R128_YFACTOR_2 |
 
136
                    R128_FLAT_SHADE_VERTEX_OGL |
 
137
                    R128_FPU_ROUND_TRUNCATE |
 
138
                    R128_WM_SEL_8DW);
 
139
                OUT_REG(R128_REG_PLANE_3D_MASK_C, 0xffffffff);
 
140
                OUT_REG(R128_REG_CONSTANT_COLOR_C, 0xff000000);
 
141
                OUT_REG(R128_REG_WINDOW_XY_OFFSET, 0x00000000);
 
142
                END_DMA();
 
143
        } else if (!atic->is_r300) {
 
144
                /* Setup for R100/R200 Composite */
 
145
                BEGIN_DMA(8);
 
146
                OUT_REG(RADEON_REG_RE_TOP_LEFT, 0);
 
147
                OUT_REG(RADEON_REG_RE_WIDTH_HEIGHT, 0xffffffff);
 
148
                OUT_REG(RADEON_REG_RB3D_PLANEMASK, 0xffffffff);
 
149
                OUT_REG(RADEON_REG_SE_CNTL,
 
150
                    RADEON_FFACE_CULL_CCW |
 
151
                    RADEON_FFACE_SOLID |
 
152
                    RADEON_VTX_PIX_CENTER_OGL);
 
153
                END_DMA();
 
154
 
 
155
                if (atic->is_r100) {
 
156
                        BEGIN_DMA(6);
 
157
                        OUT_REG(RADEON_REG_SE_CNTL_STATUS, RADEON_TCL_BYPASS);
 
158
                        OUT_REG(RADEON_REG_SE_COORD_FMT,
 
159
                            RADEON_VTX_XY_PRE_MULT_1_OVER_W0 |
 
160
                            RADEON_VTX_ST0_NONPARAMETRIC |
 
161
                            RADEON_VTX_ST1_NONPARAMETRIC |
 
162
                            RADEON_TEX1_W_ROUTING_USE_W0);
 
163
                        OUT_REG(RADEON_REG_RB3D_DSTCACHE_MODE, 
 
164
                                RADEON_RB3D_DC_2D_CACHE_AUTOFLUSH |
 
165
                                RADEON_RB3D_DC_3D_CACHE_AUTOFLUSH);
 
166
                        END_DMA();
 
167
                } else {
 
168
                        BEGIN_DMA(18);
 
169
                        /* XXX: The 0 below should be RADEON_TCL_BYPASS on
 
170
                         * RS300s.
 
171
                         */
 
172
                        OUT_REG(R200_REG_SE_VAP_CNTL_STATUS, 0);
 
173
                        OUT_REG(R200_REG_PP_CNTL_X, 0);
 
174
                        OUT_REG(R200_REG_PP_TXMULTI_CTL_0, 0);
 
175
                        OUT_REG(R200_REG_SE_VTX_STATE_CNTL, 0);
 
176
                        OUT_REG(R200_REG_RE_CNTL, 0);
 
177
                        /* XXX: VTX_ST_DENORMALIZED is illegal for the case of
 
178
                         * repeating textures.
 
179
                         */
 
180
                        OUT_REG(R200_REG_SE_VTE_CNTL, R200_VTX_ST_DENORMALIZED);
 
181
                        OUT_REG(R200_REG_SE_VAP_CNTL,
 
182
                            R200_VAP_FORCE_W_TO_ONE |
 
183
                            R200_VAP_VF_MAX_VTX_NUM);
 
184
                        OUT_REG(R200_REG_RE_AUX_SCISSOR_CNTL, 0);
 
185
                        OUT_REG(RADEON_REG_RB3D_DSTCACHE_MODE, 
 
186
                                RADEON_RB3D_DC_2D_CACHE_AUTOFLUSH |
 
187
                                RADEON_RB3D_DC_3D_CACHE_AUTOFLUSH |
 
188
                                R200_RB3D_DC_2D_CACHE_AUTOFREE |
 
189
                                R200_RB3D_DC_3D_CACHE_AUTOFREE);
 
190
                        END_DMA();
 
191
                }
 
192
        }
 
193
}
 
194
 
 
195
static void
 
196
ATIWaitMarker(ScreenPtr pScreen, int marker)
 
197
{
 
198
        KdScreenPriv(pScreen);
 
199
        ATIScreenInfo(pScreenPriv);
 
200
 
 
201
        ENTER_DRAW(0);
 
202
        ATIWaitIdle(atis);
 
203
        LEAVE_DRAW(0);
 
204
}
 
205
 
 
206
void
 
207
RadeonSwitchTo2D(ATIScreenInfo *atis)
 
208
{
 
209
        RING_LOCALS;
 
210
 
 
211
        ENTER_DRAW(0);
 
212
        BEGIN_DMA(4);
 
213
        OUT_REG(RADEON_REG_RB3D_DSTCACHE_CTLSTAT, RADEON_RB3D_DC_FLUSH);
 
214
        OUT_REG(ATI_REG_WAIT_UNTIL,
 
215
            RADEON_WAIT_HOST_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
 
216
        END_DMA();
 
217
        LEAVE_DRAW(0);
 
218
}
 
219
 
 
220
void
 
221
RadeonSwitchTo3D(ATIScreenInfo *atis)
 
222
{
 
223
        RING_LOCALS;
 
224
 
 
225
        ENTER_DRAW(0);
 
226
        BEGIN_DMA(4);
 
227
        OUT_REG(RADEON_REG_RB3D_DSTCACHE_CTLSTAT, RADEON_RB3D_DC_FLUSH);
 
228
        /* We must wait for 3d to idle, in case source was just written as a dest. */
 
229
        OUT_REG(ATI_REG_WAIT_UNTIL,
 
230
            RADEON_WAIT_HOST_IDLECLEAN | RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
 
231
        END_DMA();
 
232
        LEAVE_DRAW(0);
 
233
}
 
234
 
 
235
#if ATI_TRACE_DRAW
 
236
void
 
237
ATIEnterDraw (PixmapPtr pPix, char *function)
 
238
{
 
239
    if (pPix != NULL) {
 
240
        KdScreenPriv(pPix->drawable.pScreen);
 
241
        CARD32 offset;
 
242
    
 
243
        offset = ((CARD8 *)pPix->devPrivate.ptr -
 
244
                  pScreenPriv->screen->memory_base);
 
245
    
 
246
        ErrorF ("Enter %s 0x%x (%dx%dx%d/%d)\n", function, offset,
 
247
            pPix->drawable.width, pPix->drawable.height, pPix->drawable.depth,
 
248
            pPix->drawable.bitsPerPixel);
 
249
    } else
 
250
        ErrorF ("Enter %s\n", function);
 
251
}
 
252
 
 
253
void
 
254
ATILeaveDraw (PixmapPtr pPix, char *function)
 
255
{
 
256
    if (pPix != NULL) {
 
257
        KdScreenPriv(pPix->drawable.pScreen);
 
258
        CARD32 offset;
 
259
    
 
260
        offset = ((CARD8 *)pPix->devPrivate.ptr -
 
261
                  pScreenPriv->screen->memory_base);
 
262
    
 
263
        ErrorF ("Leave %s 0x%x\n", function, offset);
 
264
    } else
 
265
        ErrorF ("Leave %s\n", function);
 
266
}
 
267
#endif
 
268
 
 
269
/* Assumes that depth 15 and 16 can be used as depth 16, which is okay since we
 
270
 * require src and dest datatypes to be equal.
 
271
 */
 
272
static Bool
 
273
ATIGetDatatypeBpp(int bpp, CARD32 *type)
 
274
{
 
275
        switch (bpp) {
 
276
        case 8:
 
277
                *type = R128_DATATYPE_CI8;
 
278
                return TRUE;
 
279
        case 16:
 
280
                *type = R128_DATATYPE_RGB565;
 
281
                return TRUE;
 
282
        case 24:
 
283
                *type = R128_DATATYPE_CI8;
 
284
                return TRUE;
 
285
        case 32:
 
286
                *type = R128_DATATYPE_ARGB8888;
 
287
                return TRUE;
 
288
        default:
 
289
                ATI_FALLBACK(("Unsupported bpp: %d\n", bpp));
 
290
                return FALSE;
 
291
        }
 
292
}
 
293
 
 
294
Bool
 
295
ATIGetOffsetPitch(ATIScreenInfo *atis, int bpp, CARD32 *pitch_offset,
 
296
    int offset, int pitch)
 
297
{
 
298
        ATICardInfo *atic = atis->atic;
 
299
 
 
300
        /* On the R128, depending on the bpp the screen can be set up so that it
 
301
         * doesn't meet the pitchAlign requirement but can still be
 
302
         * accelerated, so we check the specific pitch requirement of alignment
 
303
         * to 8 pixels.
 
304
         */
 
305
        if (atic->is_radeon) {
 
306
                if (pitch % atis->kaa.pitchAlign != 0)
 
307
                        ATI_FALLBACK(("Bad pitch 0x%08x\n", pitch));
 
308
                *pitch_offset = ((pitch >> 6) << 22) | (offset >> 10);
 
309
 
 
310
        } else {
 
311
                if (pitch % bpp != 0)
 
312
                        ATI_FALLBACK(("Bad pitch 0x%08x\n", pitch));
 
313
                *pitch_offset = ((pitch / bpp) << 21) | (offset >> 5);
 
314
        }
 
315
 
 
316
        if (offset % atis->kaa.offsetAlign != 0)
 
317
                ATI_FALLBACK(("Bad offset 0x%08x\n", offset));
 
318
 
 
319
        return TRUE;
 
320
}
 
321
 
 
322
Bool
 
323
ATIGetPixmapOffsetPitch(PixmapPtr pPix, CARD32 *pitch_offset)
 
324
{
 
325
        KdScreenPriv(pPix->drawable.pScreen);
 
326
        ATIScreenInfo(pScreenPriv);
 
327
        CARD32 pitch, offset;
 
328
        int bpp;
 
329
 
 
330
        bpp = pPix->drawable.bitsPerPixel;
 
331
        if (bpp == 24)
 
332
                bpp = 8;
 
333
 
 
334
        offset = ((CARD8 *)pPix->devPrivate.ptr -
 
335
            pScreenPriv->screen->memory_base);
 
336
        pitch = pPix->devKind;
 
337
 
 
338
        return ATIGetOffsetPitch(atis, bpp, pitch_offset, offset, pitch);
 
339
}
 
340
 
 
341
static Bool
 
342
ATIPrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg)
 
343
{
 
344
        KdScreenPriv(pPix->drawable.pScreen);
 
345
        ATIScreenInfo(pScreenPriv);
 
346
        ATICardInfo(pScreenPriv);
 
347
        CARD32 datatype;
 
348
        RING_LOCALS;
 
349
 
 
350
        is_24bpp = (pPix->drawable.bitsPerPixel == 24);
 
351
        accel_atis = atis;
 
352
 
 
353
        if (is_24bpp) {
 
354
                /* Solid fills in fake-24bpp mode only work if the pixel color
 
355
                 * and planemask are all the same byte.
 
356
                 */
 
357
                if ((fg & 0xffffff) != (((fg & 0xff) << 16) | ((fg >> 8) &
 
358
                    0xffff)))
 
359
                        ATI_FALLBACK(("Can't do solid color 0x%08x in 24bpp\n",
 
360
                            fg));
 
361
                if ((pm & 0xffffff) != (((pm & 0xff) << 16) | ((pm >> 8) &
 
362
                    0xffff)))
 
363
                        ATI_FALLBACK(("Can't do planemask 0x%08x in 24bpp\n",
 
364
                            pm));
 
365
        }
 
366
 
 
367
        if (!ATIGetDatatypeBpp(pPix->drawable.bitsPerPixel, &datatype))
 
368
                return FALSE;
 
369
        if (!ATIGetPixmapOffsetPitch(pPix, &dst_pitch_offset))
 
370
                return FALSE;
 
371
 
 
372
        ENTER_DRAW(pPix);
 
373
 
 
374
        if (atic->is_radeon)
 
375
                RadeonSwitchTo2D(atis);
 
376
 
 
377
        settings =
 
378
            ATI_GMC_DST_PITCH_OFFSET_CNTL |
 
379
            ATI_GMC_BRUSH_SOLID_COLOR |
 
380
            (datatype << 8) |
 
381
            ATI_GMC_SRC_DATATYPE_COLOR |
 
382
            (ATISolidRop[alu] << 16) |
 
383
            ATI_GMC_CLR_CMP_CNTL_DIS |
 
384
            R128_GMC_AUX_CLIP_DIS;
 
385
        color = fg;
 
386
 
 
387
#if DRAW_USING_PACKET3
 
388
        BEGIN_DMA(6);
 
389
        OUT_REG(ATI_REG_DEFAULT_SC_BOTTOM_RIGHT,
 
390
            ATI_DEFAULT_SC_RIGHT_MAX | ATI_DEFAULT_SC_BOTTOM_MAX);
 
391
        OUT_REG(ATI_REG_DP_WRITE_MASK, pm);
 
392
        OUT_REG(ATI_REG_DP_CNTL, ATI_DST_X_LEFT_TO_RIGHT |
 
393
            ATI_DST_Y_TOP_TO_BOTTOM);
 
394
        END_DMA();
 
395
#else
 
396
        BEGIN_DMA(12);
 
397
        OUT_REG(ATI_REG_DEFAULT_SC_BOTTOM_RIGHT,
 
398
            ATI_DEFAULT_SC_RIGHT_MAX | ATI_DEFAULT_SC_BOTTOM_MAX);
 
399
        OUT_REG(ATI_REG_DST_PITCH_OFFSET, dst_pitch_offset);
 
400
        OUT_REG(ATI_REG_DP_GUI_MASTER_CNTL, settings);
 
401
        OUT_REG(ATI_REG_DP_BRUSH_FRGD_CLR, fg);
 
402
        OUT_REG(ATI_REG_DP_WRITE_MASK, pm);
 
403
        OUT_REG(ATI_REG_DP_CNTL, ATI_DST_X_LEFT_TO_RIGHT |
 
404
            ATI_DST_Y_TOP_TO_BOTTOM);
 
405
        END_DMA();
 
406
#endif
 
407
 
 
408
        LEAVE_DRAW(pPix);
 
409
        return TRUE;
 
410
}
 
411
 
 
412
static void
 
413
ATISolid(int x1, int y1, int x2, int y2)
 
414
{
 
415
        ENTER_DRAW(0);
 
416
        ATIScreenInfo *atis = accel_atis;
 
417
        RING_LOCALS;
 
418
        
 
419
        if (is_24bpp) {
 
420
                x1 *= 3;
 
421
                x2 *= 3;
 
422
        }
 
423
#if DRAW_USING_PACKET3
 
424
        BEGIN_DMA(6);
 
425
        OUT_RING(DMA_PACKET3(ATI_CCE_PACKET3_PAINT_MULTI, 5));
 
426
        OUT_RING(settings);
 
427
        OUT_RING(dst_pitch_offset);
 
428
        OUT_RING(color);
 
429
        OUT_RING((x1 << 16) | y1);
 
430
        OUT_RING(((x2 - x1) << 16) | (y2 - y1));
 
431
        END_DMA();
 
432
#else
 
433
        BEGIN_DMA(3);
 
434
        OUT_RING(DMA_PACKET0(ATI_REG_DST_Y_X, 2));
 
435
        OUT_RING_REG(ATI_REG_DST_Y_X, (y1 << 16) | x1);
 
436
        OUT_RING_REG(ATI_REG_DST_HEIGHT_WIDTH, ((y2 - y1) << 16) | (x2 - x1));
 
437
        END_DMA();
 
438
#endif
 
439
        LEAVE_DRAW(0);
 
440
}
 
441
 
 
442
static void
 
443
ATIDoneSolid(void)
 
444
{
 
445
        ENTER_DRAW(0);
 
446
        LEAVE_DRAW(0);
 
447
}
 
448
 
 
449
static Bool
 
450
ATIPrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, int dx, int dy, int alu, Pixel pm)
 
451
{
 
452
        KdScreenPriv(pDst->drawable.pScreen);
 
453
        ATIScreenInfo(pScreenPriv);
 
454
        ATICardInfo(pScreenPriv);
 
455
        CARD32 datatype;
 
456
        RING_LOCALS;
 
457
 
 
458
        copydx = dx;
 
459
        copydy = dy;
 
460
        is_24bpp = pDst->drawable.bitsPerPixel == 24;
 
461
        accel_atis = atis;
 
462
 
 
463
        if (is_24bpp && ((pm & 0xffffff) != (((pm & 0xff) << 16) | ((pm >> 8) &
 
464
            0xffff))))
 
465
                ATI_FALLBACK(("Can't do planemask 0x%08x in 24bpp\n", pm));
 
466
 
 
467
        if (!ATIGetDatatypeBpp(pDst->drawable.bitsPerPixel, &datatype))
 
468
                return FALSE;
 
469
        if (!ATIGetPixmapOffsetPitch(pSrc, &src_pitch_offset))
 
470
                return FALSE;
 
471
        if (!ATIGetPixmapOffsetPitch(pDst, &dst_pitch_offset))
 
472
                return FALSE;
 
473
 
 
474
        ENTER_DRAW (pDst);
 
475
        if (atic->is_radeon)
 
476
                RadeonSwitchTo2D(atis);
 
477
 
 
478
        settings =
 
479
            ATI_GMC_SRC_PITCH_OFFSET_CNTL |
 
480
            ATI_GMC_DST_PITCH_OFFSET_CNTL |
 
481
            ATI_GMC_BRUSH_NONE |
 
482
            (datatype << 8) |
 
483
            ATI_GMC_SRC_DATATYPE_COLOR |
 
484
            (ATIBltRop[alu] << 16) |
 
485
            ATI_DP_SRC_SOURCE_MEMORY |
 
486
            ATI_GMC_CLR_CMP_CNTL_DIS |
 
487
            R128_GMC_AUX_CLIP_DIS;
 
488
 
 
489
#if DRAW_USING_PACKET3
 
490
        BEGIN_DMA(6);
 
491
        OUT_REG(ATI_REG_DEFAULT_SC_BOTTOM_RIGHT,
 
492
            ATI_DEFAULT_SC_RIGHT_MAX | ATI_DEFAULT_SC_BOTTOM_MAX);
 
493
        OUT_REG(ATI_REG_DP_WRITE_MASK, pm);
 
494
        OUT_REG(ATI_REG_DP_CNTL,
 
495
            (dx >= 0 ? ATI_DST_X_LEFT_TO_RIGHT : 0) |
 
496
            (dy >= 0 ? ATI_DST_Y_TOP_TO_BOTTOM : 0));
 
497
        END_DMA();
 
498
 
 
499
#else
 
500
        BEGIN_DMA(12);
 
501
        OUT_REG(ATI_REG_DEFAULT_SC_BOTTOM_RIGHT,
 
502
            ATI_DEFAULT_SC_RIGHT_MAX | ATI_DEFAULT_SC_BOTTOM_MAX);
 
503
        OUT_REG(ATI_REG_SRC_PITCH_OFFSET, src_pitch_offset);
 
504
        OUT_REG(ATI_REG_DST_PITCH_OFFSET, dst_pitch_offset);
 
505
        OUT_REG(ATI_REG_DP_GUI_MASTER_CNTL, settings);
 
506
        OUT_REG(ATI_REG_DP_WRITE_MASK, pm);
 
507
        OUT_REG(ATI_REG_DP_CNTL,
 
508
            (dx >= 0 ? ATI_DST_X_LEFT_TO_RIGHT : 0) |
 
509
            (dy >= 0 ? ATI_DST_Y_TOP_TO_BOTTOM : 0));
 
510
        END_DMA();
 
511
#endif
 
512
        LEAVE_DRAW(pDst);
 
513
 
 
514
        return TRUE;
 
515
}
 
516
 
 
517
static void
 
518
ATICopy(int srcX, int srcY, int dstX, int dstY, int w, int h)
 
519
{
 
520
        ATIScreenInfo *atis = accel_atis;
 
521
        RING_LOCALS;
 
522
 
 
523
        if (is_24bpp) {
 
524
                srcX *= 3;
 
525
                dstX *= 3;
 
526
                w *= 3;
 
527
        }
 
528
 
 
529
#if !DRAW_USING_PACKET3
 
530
        if (copydx < 0) {
 
531
                srcX += w - 1;
 
532
                dstX += w - 1;
 
533
        }
 
534
 
 
535
        if (copydy < 0)  {
 
536
                srcY += h - 1;
 
537
                dstY += h - 1;
 
538
        }
 
539
#endif
 
540
 
 
541
#if DRAW_USING_PACKET3
 
542
        BEGIN_DMA(7);
 
543
        OUT_RING(DMA_PACKET3(ATI_CCE_PACKET3_BITBLT_MULTI, 6));
 
544
        OUT_RING(settings);
 
545
        OUT_RING(src_pitch_offset);
 
546
        OUT_RING(dst_pitch_offset);
 
547
        OUT_RING((srcX << 16) | srcY);
 
548
        OUT_RING((dstX << 16) | dstY);
 
549
        OUT_RING((w << 16) | h);
 
550
        END_DMA();
 
551
#else
 
552
        BEGIN_DMA(4);
 
553
        OUT_RING(DMA_PACKET0(ATI_REG_SRC_Y_X, 3));
 
554
        OUT_RING_REG(ATI_REG_SRC_Y_X, (srcY << 16) | srcX);
 
555
        OUT_RING_REG(ATI_REG_DST_Y_X, (dstY << 16) | dstX);
 
556
        OUT_RING_REG(ATI_REG_DST_HEIGHT_WIDTH, (h << 16) | w);
 
557
        END_DMA();
 
558
#endif
 
559
}
 
560
 
 
561
static void
 
562
ATIDoneCopy(void)
 
563
{
 
564
}
 
565
 
 
566
static Bool
 
567
ATIUploadToScreen(PixmapPtr pDst, char *src, int src_pitch)
 
568
{
 
569
        ScreenPtr pScreen = pDst->drawable.pScreen;
 
570
        KdScreenPriv(pScreen);
 
571
        ATIScreenInfo(pScreenPriv);
 
572
        ATICardInfo(pScreenPriv);
 
573
        int width, height, bpp, i, dwords;
 
574
        int dst_pitch, dst_offset;
 
575
        CARD32 dst_pitch_offset, datatype;
 
576
        Bool success;
 
577
        RING_LOCALS;
 
578
 
 
579
        ENTER_DRAW (pDst);
 
580
 
 
581
        LEAVE_DRAW (pDst);
 
582
        /* XXX: Hostdata uploads aren't working yet. */
 
583
        return FALSE;
 
584
        
 
585
        dst_offset = ((CARD8 *)pDst->devPrivate.ptr -
 
586
            pScreenPriv->screen->memory_base);
 
587
        dst_pitch = pDst->devKind;
 
588
        width = pDst->drawable.width;
 
589
        height = pDst->drawable.height;
 
590
        bpp =  pDst->drawable.bitsPerPixel;
 
591
 
 
592
        success = ATIGetDatatypeBpp(bpp, &datatype);
 
593
 
 
594
        if (bpp == 24) {
 
595
                is_24bpp = TRUE;
 
596
                bpp = 8;
 
597
        } else
 
598
                is_24bpp = FALSE;
 
599
 
 
600
        if (!ATIGetOffsetPitch(atis, bpp, &dst_pitch_offset, dst_offset,
 
601
            dst_pitch))
 
602
                return FALSE;
 
603
 
 
604
        if (src_pitch != (width * bpp / 8))
 
605
                return FALSE;
 
606
 
 
607
        /* No PACKET3 packets when in PIO mode. */
 
608
        if (atis->using_pio)
 
609
                return FALSE;
 
610
 
 
611
        dwords = (width * height * (bpp / 8) + 3) / 4;
 
612
 
 
613
        /* Flush pixel cache so nothing being written to the destination
 
614
         * previously gets mixed up with the hostdata blit.
 
615
         */
 
616
        if (atic->is_radeon) {
 
617
                BEGIN_DMA(4);
 
618
                OUT_REG(RADEON_REG_RB3D_DSTCACHE_CTLSTAT, RADEON_RB3D_DC_FLUSH);
 
619
                OUT_REG(ATI_REG_WAIT_UNTIL,
 
620
                    RADEON_WAIT_2D_IDLECLEAN |
 
621
                    RADEON_WAIT_3D_IDLECLEAN |
 
622
                    RADEON_WAIT_HOST_IDLECLEAN);
 
623
                END_DMA();
 
624
        } else {
 
625
                BEGIN_DMA(2);
 
626
                OUT_REG(R128_REG_PC_GUI_CTLSTAT,
 
627
                    R128_PC_FLUSH_GUI | R128_PC_RI_GUI);
 
628
                END_DMA();
 
629
        }
 
630
 
 
631
        BEGIN_DMA(8);
 
632
        OUT_RING(DMA_PACKET3(ATI_CCE_PACKET3_HOSTDATA_BLT, 7 + dwords));
 
633
        OUT_RING(ATI_GMC_DST_PITCH_OFFSET_CNTL |
 
634
            ATI_GMC_BRUSH_NONE |
 
635
            (datatype << 8) |
 
636
            ATI_GMC_SRC_DATATYPE_COLOR |
 
637
            (ATISolidRop[GXcopy] << 16) |
 
638
            ATI_DP_SRC_SOURCE_HOST_DATA |
 
639
            ATI_GMC_CLR_CMP_CNTL_DIS |
 
640
            R128_GMC_AUX_CLIP_DIS |
 
641
            ATI_GMC_WR_MSK_DIS);
 
642
        OUT_RING(dst_pitch_offset);
 
643
        OUT_RING(0xffffffff);
 
644
        OUT_RING(0xffffffff);
 
645
        OUT_RING((0 << 16) | 0);
 
646
        OUT_RING((height << 16) | width);
 
647
        OUT_RING(dwords);
 
648
        END_DMA();
 
649
 
 
650
        for (i = 0; i < dwords; i++) {
 
651
                BEGIN_DMA(1);
 
652
                OUT_RING(((CARD32 *)src)[i]);
 
653
                END_DMA();
 
654
        }
 
655
 
 
656
        if (atic->is_radeon) {
 
657
                BEGIN_DMA(4);
 
658
                OUT_REG(RADEON_REG_RB3D_DSTCACHE_CTLSTAT,
 
659
                    RADEON_RB3D_DC_FLUSH_ALL);
 
660
                OUT_REG(ATI_REG_WAIT_UNTIL,
 
661
                    RADEON_WAIT_2D_IDLECLEAN |
 
662
                    RADEON_WAIT_HOST_IDLECLEAN);
 
663
                END_DMA();
 
664
        } else {
 
665
                BEGIN_DMA(2);
 
666
                OUT_REG(R128_REG_PC_GUI_CTLSTAT, R128_PC_FLUSH_GUI);
 
667
                END_DMA();
 
668
        }
 
669
 
 
670
        kaaMarkSync(pScreen);
 
671
 
 
672
        ErrorF("hostdata upload %d,%d %dbpp\n", width, height, bpp);
 
673
 
 
674
        return TRUE;
 
675
}
 
676
 
 
677
 
 
678
static Bool
 
679
ATIUploadToScratch(PixmapPtr pSrc, PixmapPtr pDst)
 
680
{
 
681
        KdScreenPriv(pSrc->drawable.pScreen);
 
682
        ATICardInfo(pScreenPriv);
 
683
        ATIScreenInfo(pScreenPriv);
 
684
        int dst_pitch, src_pitch, w, i, size, bytes;
 
685
        unsigned char *dst, *src;
 
686
        RING_LOCALS;
 
687
 
 
688
        ENTER_DRAW(pSrc);
 
689
        /* Align width to log 2, useful for R128 composite.  This should be a
 
690
         * KAA flag we check for (and supported in kaa.c in general) since many
 
691
         * older bits of hardware are going to want POT pitches.
 
692
         */
 
693
        w = pSrc->drawable.width;
 
694
        if (atis->kaa.flags & KAA_OFFSCREEN_ALIGN_POT)
 
695
                w = 1 << (ATILog2(w - 1) + 1);
 
696
        dst_pitch = (w * pSrc->drawable.bitsPerPixel / 8 +
 
697
            atis->kaa.pitchAlign - 1) & ~(atis->kaa.pitchAlign - 1);
 
698
 
 
699
        size = dst_pitch * pSrc->drawable.height;
 
700
        if (size > atis->scratch_area->size)
 
701
                ATI_FALLBACK(("Pixmap too large for scratch (%d,%d)\n",
 
702
                    pSrc->drawable.width, pSrc->drawable.height));
 
703
 
 
704
        atis->scratch_next = (atis->scratch_next + atis->kaa.offsetAlign - 1) &
 
705
            ~(atis->kaa.offsetAlign - 1);
 
706
        if (atis->scratch_next + size > atis->scratch_area->offset +
 
707
            atis->scratch_area->size) {
 
708
                /* Only sync when we've used all of the scratch area. */
 
709
                kaaWaitSync(pSrc->drawable.pScreen);
 
710
                atis->scratch_next = atis->scratch_area->offset;
 
711
        }
 
712
        memcpy(pDst, pSrc, sizeof(*pDst));
 
713
        pDst->devKind = dst_pitch;
 
714
        pDst->devPrivate.ptr = pScreenPriv->screen->memory_base +
 
715
            atis->scratch_next;
 
716
        atis->scratch_next += size;
 
717
 
 
718
        src = pSrc->devPrivate.ptr;
 
719
        src_pitch = pSrc->devKind;
 
720
        dst = pDst->devPrivate.ptr;
 
721
        bytes = src_pitch < dst_pitch ? src_pitch : dst_pitch;
 
722
 
 
723
        i = pSrc->drawable.height;
 
724
        while (i--) {
 
725
                memcpy(dst, src, bytes);
 
726
                dst += dst_pitch;
 
727
                src += src_pitch;
 
728
        }
 
729
 
 
730
        /* Flush the pixel cache */
 
731
        if (atic->is_radeon) {
 
732
                BEGIN_DMA(4);
 
733
                OUT_REG(RADEON_REG_RB3D_DSTCACHE_CTLSTAT,
 
734
                    RADEON_RB3D_DC_FLUSH_ALL);
 
735
                OUT_REG(ATI_REG_WAIT_UNTIL, RADEON_WAIT_HOST_IDLECLEAN);
 
736
                END_DMA();
 
737
        } else {
 
738
                BEGIN_DMA(2);
 
739
                OUT_REG(R128_REG_PC_GUI_CTLSTAT, R128_PC_FLUSH_ALL);
 
740
                END_DMA();
 
741
        }
 
742
 
 
743
        LEAVE_DRAW(pSrc);
 
744
        return TRUE;
 
745
}
 
746
 
 
747
static void
 
748
ATIBlockHandler(pointer blockData, OSTimePtr timeout, pointer readmask)
 
749
{
 
750
        ScreenPtr pScreen = (ScreenPtr) blockData;
 
751
        KdScreenPriv(pScreen);
 
752
        ATIScreenInfo(pScreenPriv);
 
753
 
 
754
        /* When the server is going to sleep, make sure that all DMA data has
 
755
         * been flushed.
 
756
         */
 
757
        if (atis->indirectBuffer)
 
758
                ATIFlushIndirect(atis, 1);
 
759
}
 
760
 
 
761
static void
 
762
ATIWakeupHandler(pointer blockData, int result, pointer readmask)
 
763
{
 
764
}
 
765
 
 
766
Bool
 
767
ATIDrawInit(ScreenPtr pScreen)
 
768
{
 
769
        KdScreenPriv(pScreen);
 
770
        ATIScreenInfo(pScreenPriv);
 
771
        ATICardInfo(pScreenPriv);
 
772
 
 
773
        ErrorF("Screen: %d/%d depth/bpp\n", pScreenPriv->screen->fb[0].depth,
 
774
            pScreenPriv->screen->fb[0].bitsPerPixel);
 
775
 
 
776
        RegisterBlockAndWakeupHandlers(ATIBlockHandler, ATIWakeupHandler,
 
777
            pScreen);
 
778
 
 
779
#ifdef USE_DRI
 
780
        atis->using_dri = ATIDRIScreenInit(pScreen);
 
781
#endif /* USE_DRI */
 
782
 
 
783
        memset(&atis->kaa, 0, sizeof(KaaScreenInfoRec));
 
784
        atis->kaa.waitMarker = ATIWaitMarker;
 
785
        atis->kaa.PrepareSolid = ATIPrepareSolid;
 
786
        atis->kaa.Solid = ATISolid;
 
787
        atis->kaa.DoneSolid = ATIDoneSolid;
 
788
        atis->kaa.PrepareCopy = ATIPrepareCopy;
 
789
        atis->kaa.Copy = ATICopy;
 
790
        atis->kaa.DoneCopy = ATIDoneCopy;
 
791
        /* Other acceleration will be hooked in in DrawEnable depending on
 
792
         * what type of DMA gets initialized.
 
793
         */
 
794
 
 
795
        atis->kaa.flags = KAA_OFFSCREEN_PIXMAPS;
 
796
        if (atic->is_radeon) {
 
797
                atis->kaa.offsetAlign = 1024;
 
798
                atis->kaa.pitchAlign = 64;
 
799
        } else {
 
800
                /* Rage 128 compositing wants power-of-two pitches. */
 
801
                atis->kaa.flags |= KAA_OFFSCREEN_ALIGN_POT;
 
802
                atis->kaa.offsetAlign = 32;
 
803
                /* Pitch alignment is in sets of 8 pixels, and we need to cover
 
804
                 * 32bpp, so 32 bytes.
 
805
                 */
 
806
                atis->kaa.pitchAlign = 32;
 
807
        }
 
808
 
 
809
        kaaInitTrapOffsets(8, sample_offsets_x, sample_offsets_y, 0.0, 0.0);
 
810
        sample_count = (1 << 8) - 1;
 
811
 
 
812
        if (!kaaDrawInit(pScreen, &atis->kaa))
 
813
                return FALSE;
 
814
 
 
815
        return TRUE;
 
816
}
 
817
 
 
818
static void
 
819
ATIScratchSave(ScreenPtr pScreen, KdOffscreenArea *area)
 
820
{
 
821
        KdScreenPriv(pScreen);
 
822
        ATIScreenInfo(pScreenPriv);
 
823
 
 
824
        atis->scratch_area = NULL;
 
825
}
 
826
 
 
827
void
 
828
ATIDrawEnable(ScreenPtr pScreen)
 
829
{
 
830
        KdScreenPriv(pScreen);
 
831
        ATIScreenInfo(pScreenPriv);
 
832
        ATICardInfo(pScreenPriv);
 
833
 
 
834
        ATIDMASetup(pScreen);
 
835
        ATIDrawSetup(pScreen);
 
836
 
 
837
        atis->scratch_area = NULL;
 
838
        atis->kaa.PrepareBlend = NULL;
 
839
        atis->kaa.Blend = NULL;
 
840
        atis->kaa.DoneBlend = NULL;
 
841
        atis->kaa.CheckComposite = NULL;
 
842
        atis->kaa.PrepareComposite = NULL;
 
843
        atis->kaa.Composite = NULL;
 
844
        atis->kaa.DoneComposite = NULL;
 
845
        atis->kaa.UploadToScreen = NULL;
 
846
        atis->kaa.UploadToScratch = NULL;
 
847
 
 
848
        /* We can't dispatch 3d commands in PIO mode. */
 
849
        if (!atis->using_pio) {
 
850
                if (!atic->is_radeon) {
 
851
                        atis->kaa.CheckComposite = R128CheckComposite;
 
852
                        atis->kaa.PrepareComposite = R128PrepareComposite;
 
853
                        atis->kaa.Composite = R128Composite;
 
854
                        atis->kaa.DoneComposite = R128DoneComposite;
 
855
                } else if (atic->is_r100) {
 
856
                        atis->kaa.CheckComposite = R100CheckComposite;
 
857
                        atis->kaa.PrepareComposite = R100PrepareComposite;
 
858
                        atis->kaa.Composite = RadeonComposite;
 
859
                        atis->kaa.DoneComposite = RadeonDoneComposite;
 
860
                } else if (atic->is_r200) {
 
861
                        atis->kaa.CheckComposite = R200CheckComposite;
 
862
                        atis->kaa.PrepareComposite = R200PrepareComposite;
 
863
                        atis->kaa.Composite = RadeonComposite;
 
864
                        atis->kaa.DoneComposite = RadeonDoneComposite;
 
865
                }
 
866
        }
 
867
#ifdef USE_DRI
 
868
        if (atis->using_dri) {
 
869
                if (!atic->is_radeon) {
 
870
                        /*atis->kaa.PrepareTrapezoids = R128PrepareTrapezoids;
 
871
                        atis->kaa.Trapezoids = R128Trapezoids;
 
872
                        atis->kaa.DoneTrapezoids = R128DoneTrapezoids;*/
 
873
                } else if (atic->is_r100 || atic->is_r200) {
 
874
                        atis->kaa.PrepareTrapezoids = RadeonPrepareTrapezoids;
 
875
                        atis->kaa.Trapezoids = RadeonTrapezoids;
 
876
                        atis->kaa.DoneTrapezoids = RadeonDoneTrapezoids;
 
877
                }
 
878
        }
 
879
#endif /* USE_DRI */
 
880
 
 
881
        atis->kaa.UploadToScreen = ATIUploadToScreen;
 
882
 
 
883
        /* Reserve a scratch area.  It'll be used for storing glyph data during
 
884
         * Composite operations, because glyphs aren't in real pixmaps and thus
 
885
         * can't be migrated.
 
886
         */
 
887
        atis->scratch_area = KdOffscreenAlloc(pScreen, 131072,
 
888
            atis->kaa.offsetAlign, TRUE, ATIScratchSave, atis);
 
889
        if (atis->scratch_area != NULL) {
 
890
                atis->scratch_next = atis->scratch_area->offset;
 
891
                atis->kaa.UploadToScratch = ATIUploadToScratch;
 
892
        }
 
893
 
 
894
        kaaMarkSync(pScreen);
 
895
}
 
896
 
 
897
void
 
898
ATIDrawDisable(ScreenPtr pScreen)
 
899
{
 
900
 
 
901
        ATIDMATeardown(pScreen);
 
902
}
 
903
 
 
904
void
 
905
ATIDrawFini(ScreenPtr pScreen)
 
906
{
 
907
#ifdef USE_DRI
 
908
        KdScreenPriv(pScreen);
 
909
        ATIScreenInfo(pScreenPriv);
 
910
        if (atis->using_dri) {
 
911
                ATIDRICloseScreen(pScreen);
 
912
                atis->using_dri = FALSE;
 
913
        }
 
914
#endif /* USE_DRI */
 
915
 
 
916
        RemoveBlockAndWakeupHandlers(ATIBlockHandler, ATIWakeupHandler,
 
917
            pScreen);
 
918
 
 
919
        kaaDrawFini(pScreen);
 
920
}
 
921