gx_accel.c revision 04007eba
1f29dbc25Smrg/* Copyright (c) 2003-2005 Advanced Micro Devices, Inc.
2f29dbc25Smrg *
3f29dbc25Smrg * Permission is hereby granted, free of charge, to any person obtaining a copy
4f29dbc25Smrg * of this software and associated documentation files (the "Software"), to
5f29dbc25Smrg * deal in the Software without restriction, including without limitation the
6f29dbc25Smrg * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7f29dbc25Smrg * sell copies of the Software, and to permit persons to whom the Software is
8f29dbc25Smrg * furnished to do so, subject to the following conditions:
9f29dbc25Smrg *
10f29dbc25Smrg * The above copyright notice and this permission notice shall be included in
11f29dbc25Smrg * all copies or substantial portions of the Software.
12f29dbc25Smrg *
13f29dbc25Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14f29dbc25Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15f29dbc25Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16f29dbc25Smrg * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17f29dbc25Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18f29dbc25Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19f29dbc25Smrg * IN THE SOFTWARE.
20f29dbc25Smrg *
21f29dbc25Smrg * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
22f29dbc25Smrg * contributors may be used to endorse or promote products derived from this
23f29dbc25Smrg * software without specific prior written permission.
24f29dbc25Smrg * */
25f29dbc25Smrg
26f29dbc25Smrg/*
27f29dbc25Smrg * File Contents:   This file is consists of main Xfree acceleration supported
28f29dbc25Smrg *                  routines like solid fill used here.
29f29dbc25Smrg *
30f29dbc25Smrg * Project:         Geode Xfree Frame buffer device driver.
31f29dbc25Smrg * */
32f29dbc25Smrg
33f29dbc25Smrg/* #undef OPT_ACCEL */
34f29dbc25Smrg
35f29dbc25Smrg/* Xfree86 header files */
36f29dbc25Smrg#ifdef HAVE_CONFIG_H
37f29dbc25Smrg#include "config.h"
38f29dbc25Smrg#endif
39f29dbc25Smrg
40f29dbc25Smrg#include "vgaHW.h"
41f29dbc25Smrg#include "xf86.h"
4204007ebaSmrg#ifdef HAVE_XAA_H
43f29dbc25Smrg#include "xaalocal.h"
4404007ebaSmrg#endif
45f29dbc25Smrg#include "xf86fbman.h"
46f29dbc25Smrg#include "miline.h"
47f29dbc25Smrg#include "xaarop.h"
48f29dbc25Smrg#include "servermd.h"
49f29dbc25Smrg#include "picture.h"
50f29dbc25Smrg#include "xf86.h"
51f29dbc25Smrg#include "xf86_OSproc.h"
52f29dbc25Smrg#include "xf86Pci.h"
53f29dbc25Smrg#include "xf86PciInfo.h"
54f29dbc25Smrg#include "geode.h"
55f29dbc25Smrg#include "gfx_defs.h"
56f29dbc25Smrg#include "gfx_regs.h"
57f29dbc25Smrg
58f29dbc25Smrg/* Common macros for blend operations are here */
59f29dbc25Smrg
60f29dbc25Smrg#include "geode_blend.h"
61f29dbc25Smrg
62f29dbc25Smrg#undef ulong
63f29dbc25Smrgtypedef unsigned long ulong;
64f29dbc25Smrg
65f29dbc25Smrg#undef uint
66f29dbc25Smrgtypedef unsigned int uint;
67f29dbc25Smrg
68f29dbc25Smrg#undef ushort
69f29dbc25Smrgtypedef unsigned short ushort;
70f29dbc25Smrg
71f29dbc25Smrg#undef uchar
72f29dbc25Smrgtypedef unsigned char uchar;
73f29dbc25Smrg
74f29dbc25Smrg#define CALC_FBOFFSET(x, y) \
75f29dbc25Smrg	        (((ulong)(y) * gu2_pitch + ((ulong)(x) << gu2_xshift)))
76f29dbc25Smrg
77f29dbc25Smrg#define FBADDR(x,y)				\
78f29dbc25Smrg		((unsigned char *)pGeode->FBBase + CALC_FBOFFSET(x, y))
79f29dbc25Smrg
80f29dbc25Smrg#define OS_UDELAY 0
81f29dbc25Smrg#if OS_UDELAY > 0
82f29dbc25Smrg#define OS_USLEEP(usec) usleep(usec);
83f29dbc25Smrg#else
84f29dbc25Smrg#define OS_USLEEP(usec)
85f29dbc25Smrg#endif
86f29dbc25Smrg
87f29dbc25Smrg#ifdef OPT_ACCEL
88f29dbc25Smrgstatic unsigned int BPP;
89f29dbc25Smrgstatic unsigned int BLT_MODE, VEC_MODE;
90f29dbc25Smrgstatic unsigned int ACCEL_STRIDE;
91f29dbc25Smrg
92f29dbc25Smrg#define GU2_WAIT_PENDING while(READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_PENDING)
93f29dbc25Smrg#define GU2_WAIT_BUSY    while(READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_BUSY)
94f29dbc25Smrg#endif
95f29dbc25Smrg
96f29dbc25Smrg#define HOOK(fn) localRecPtr->fn = GX##fn
97f29dbc25Smrg
98f29dbc25Smrg#define DLOG(l, fmt, args...) ErrorF(fmt, ##args)
99f29dbc25Smrg
100f29dbc25Smrg/* static storage declarations */
101f29dbc25Smrg
10204007ebaSmrgtypedef struct sGBltBox {
103f29dbc25Smrg    ulong x, y;
104f29dbc25Smrg    ulong w, h;
105f29dbc25Smrg    ulong color;
106f29dbc25Smrg    int bpp, transparent;
107f29dbc25Smrg} GBltBox;
108f29dbc25Smrg
109f29dbc25Smrg#if GX_SCANLINE_SUPPORT
110f29dbc25Smrgstatic GBltBox giwr;
111f29dbc25Smrg#endif
112f29dbc25Smrg#if GX_CPU2SCREXP_SUPPORT
113f29dbc25Smrgstatic GBltBox gc2s;
114f29dbc25Smrg#endif
115f29dbc25Smrg#if GX_CLREXP_8X8_PAT_SUPPORT
116f29dbc25Smrgstatic ulong *gc8x8p;
117f29dbc25Smrg#endif
118f29dbc25Smrg
119f29dbc25Smrg#if GX_DASH_LINE_SUPPORT
12004007ebaSmrgtypedef struct sGDashLine {
121f29dbc25Smrg    ulong pat[2];
122f29dbc25Smrg    int len;
123f29dbc25Smrg    int fg;
124f29dbc25Smrg    int bg;
125f29dbc25Smrg} GDashLine;
126f29dbc25Smrg
127f29dbc25Smrgstatic GDashLine gdln;
128f29dbc25Smrg#endif
129f29dbc25Smrg
130f29dbc25Smrgstatic unsigned int gu2_xshift, gu2_yshift;
131f29dbc25Smrgstatic unsigned int gu2_pitch;
132f29dbc25Smrg
13304007ebaSmrg#if XF86XAA
134f29dbc25Smrgstatic XAAInfoRecPtr localRecPtr;
13504007ebaSmrg#endif
136f29dbc25Smrg
137f29dbc25Smrg/* pat  0xF0 */
138f29dbc25Smrg/* src  0xCC */
139f29dbc25Smrg/* dst  0xAA */
140f29dbc25Smrg
141f29dbc25Smrg/* (src FUNC dst) */
142f29dbc25Smrg
143f29dbc25Smrgstatic const int SDfn[16] = {
144f29dbc25Smrg    0x00, 0x88, 0x44, 0xCC, 0x22, 0xAA, 0x66, 0xEE,
145f29dbc25Smrg    0x11, 0x99, 0x55, 0xDD, 0x33, 0xBB, 0x77, 0xFF
146f29dbc25Smrg};
147f29dbc25Smrg
148f29dbc25Smrg/* ((src FUNC dst) AND pat-mask) OR (dst AND (NOT pat-mask)) */
149f29dbc25Smrg
150f29dbc25Smrgstatic const int SDfn_PM[16] = {
151f29dbc25Smrg    0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
152f29dbc25Smrg    0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA
153f29dbc25Smrg};
154f29dbc25Smrg
155f29dbc25Smrg/* (pat FUNC dst) */
156f29dbc25Smrg
157f29dbc25Smrgstatic const int PDfn[16] = {
158f29dbc25Smrg    0x00, 0xA0, 0x50, 0xF0, 0x0A, 0xAA, 0x5A, 0xFA,
159f29dbc25Smrg    0x05, 0xA5, 0x55, 0xF5, 0x0F, 0xAF, 0x5F, 0xFF
160f29dbc25Smrg};
161f29dbc25Smrg
162f29dbc25Smrg/* ((pat FUNC dst) AND src-mask) OR (dst AND (NOT src-mask)) */
163f29dbc25Smrg
164f29dbc25Smrgstatic const int PDfn_SM[16] = {
165f29dbc25Smrg    0x22, 0xA2, 0x62, 0xE2, 0x2A, 0xAA, 0x6A, 0xEA,
166f29dbc25Smrg    0x26, 0xA6, 0x66, 0xE6, 0x2E, 0xAE, 0x6E, 0xEE
167f29dbc25Smrg};
168f29dbc25Smrg
169f29dbc25Smrg#ifdef OPT_ACCEL
170f29dbc25Smrgstatic inline CARD32
171f29dbc25Smrgamd_gx_BppToRasterMode(int bpp)
172f29dbc25Smrg{
173f29dbc25Smrg    switch (bpp) {
174f29dbc25Smrg    case 16:
17504007ebaSmrg        return MGP_RM_BPPFMT_565;
176f29dbc25Smrg    case 32:
17704007ebaSmrg        return MGP_RM_BPPFMT_8888;
178f29dbc25Smrg    case 8:
17904007ebaSmrg        return MGP_RM_BPPFMT_332;
180f29dbc25Smrg    default:
18104007ebaSmrg        return 0;
182f29dbc25Smrg    }
183f29dbc25Smrg}
18404007ebaSmrg#endif                          /* OPT_ACCEL */
185f29dbc25Smrg
186f29dbc25Smrg/*----------------------------------------------------------------------------
187f29dbc25Smrg * GXAccelSync.
188f29dbc25Smrg *
189f29dbc25Smrg * Description  :This function is called to synchronize with the graphics
190f29dbc25Smrg *               engine and it waits the graphic engine is idle.  This is
191f29dbc25Smrg *               required before allowing direct access to the framebuffer.
192f29dbc25Smrg *
193f29dbc25Smrg *    Arg        Type     Comment
194f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
195f29dbc25Smrg *
196f29dbc25Smrg * Returns              :none
197f29dbc25Smrg *---------------------------------------------------------------------------*/
198f29dbc25Smrgvoid
199f29dbc25SmrgGXAccelSync(ScrnInfoPtr pScrni)
200f29dbc25Smrg{
201f29dbc25Smrg    //ErrorF("GXAccelSync()\n");
202f29dbc25Smrg#ifndef OPT_ACCEL
203f29dbc25Smrg    gfx_wait_until_idle();
204f29dbc25Smrg#else
205f29dbc25Smrg    GU2_WAIT_BUSY;
206f29dbc25Smrg#endif
207f29dbc25Smrg}
208f29dbc25Smrg
209f29dbc25Smrg#if GX_FILL_RECT_SUPPORT
210f29dbc25Smrg/*----------------------------------------------------------------------------
211f29dbc25Smrg * GXSetupForSolidFill.
212f29dbc25Smrg *
213f29dbc25Smrg * Description  :The SetupFor and Subsequent SolidFill(Rect) provide
214f29dbc25Smrg *               filling rectangular areas of the screen with a
215f29dbc25Smrg *               foreground color.
216f29dbc25Smrg *
217f29dbc25Smrg * Parameters.
218f29dbc25Smrg *    Arg        Type     Comment
219f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
220f29dbc25Smrg *   color        int     foreground fill color
221f29dbc25Smrg *    rop         int     unmapped raster op
222f29dbc25Smrg * planemask     uint     -1 (fill) or pattern data
223f29dbc25Smrg *
224f29dbc25Smrg * Returns              :none
225f29dbc25Smrg *--------------------------------------------------------------------------*/
226f29dbc25Smrgstatic void
227f29dbc25SmrgGXSetupForSolidFill(ScrnInfoPtr pScrni,
22804007ebaSmrg                    int color, int rop, unsigned int planemask)
229f29dbc25Smrg{
230f29dbc25Smrg    //ErrorF("GXSetupForSolidFill(%#x,%#x,%#x)\n", color, rop, planemask);
231f29dbc25Smrg    rop &= 0x0F;
232f29dbc25Smrg#ifndef OPT_ACCEL
233f29dbc25Smrg    gfx_set_solid_pattern(planemask);
234f29dbc25Smrg    gfx_set_solid_source(color);
235f29dbc25Smrg    gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
236f29dbc25Smrg#else
237f29dbc25Smrg    {
23804007ebaSmrg        unsigned int ROP = BPP | (planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
23904007ebaSmrg
24004007ebaSmrg        BLT_MODE = ((ROP ^ (ROP >> 2)) & 0x33) == 0 ? MGP_BM_SRC_MONO : 0;
24104007ebaSmrg        if (((ROP ^ (ROP >> 1)) & 0x55) != 0)
24204007ebaSmrg            BLT_MODE |= MGP_BM_DST_REQ;
24304007ebaSmrg        GU2_WAIT_PENDING;
24404007ebaSmrg        WRITE_GP32(MGP_RASTER_MODE, ROP);
24504007ebaSmrg        WRITE_GP32(MGP_PAT_COLOR_0, planemask);
24604007ebaSmrg        WRITE_GP32(MGP_SRC_COLOR_FG, color);
24704007ebaSmrg        WRITE_GP32(MGP_STRIDE, ACCEL_STRIDE);
248f29dbc25Smrg    }
249f29dbc25Smrg#endif
250f29dbc25Smrg}
251f29dbc25Smrg
252f29dbc25Smrg/*----------------------------------------------------------------------------
253f29dbc25Smrg * GXSubsequentSolidFillRect.
254f29dbc25Smrg *
255f29dbc25Smrg * Description  :see GXSetupForSolidFill.
256f29dbc25Smrg *
257f29dbc25Smrg * Parameters.
258f29dbc25Smrg *    Arg        Type     Comment
259f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
260f29dbc25Smrg *     x          int     destination x offset
261f29dbc25Smrg *     y          int     destination y offset
262f29dbc25Smrg *     w          int     fill area width (pixels)
263f29dbc25Smrg *     h          int     fill area height (pixels)
264f29dbc25Smrg *
265f29dbc25Smrg * Returns      :none
266f29dbc25Smrg *
267f29dbc25Smrg * Sample application uses:
268f29dbc25Smrg *   - Window backgrounds.
269f29dbc25Smrg *   - pull down highlighting.
270f29dbc25Smrg *   - x11perf: rectangle tests (-rect500).
271f29dbc25Smrg *   - x11perf: fill trapezoid tests (-trap100).
272f29dbc25Smrg *   - x11perf: horizontal line segments (-hseg500).
273f29dbc25Smrg *----------------------------------------------------------------------------*/
274f29dbc25Smrgstatic void
275f29dbc25SmrgGXSubsequentSolidFillRect(ScrnInfoPtr pScrni, int x, int y, int w, int h)
276f29dbc25Smrg{
277f29dbc25Smrg    //ErrorF("GXSubsequentSolidFillRect() at %d,%d %dx%d\n", x, y, w, h);
278f29dbc25Smrg#ifndef OPT_ACCEL
279f29dbc25Smrg    gfx_pattern_fill(x, y, w, h);
280f29dbc25Smrg#else
281f29dbc25Smrg    {
28204007ebaSmrg        unsigned int offset = CALC_FBOFFSET(x, y);
28304007ebaSmrg        unsigned int size = (w << 16) | h;
284f29dbc25Smrg
28504007ebaSmrg        GU2_WAIT_PENDING;
28604007ebaSmrg        WRITE_GP32(MGP_DST_OFFSET, offset);
28704007ebaSmrg        WRITE_GP32(MGP_WID_HEIGHT, size);
28804007ebaSmrg        WRITE_GP32(MGP_BLT_MODE, BLT_MODE);
289f29dbc25Smrg    }
290f29dbc25Smrg#endif
291f29dbc25Smrg}
292f29dbc25Smrg
29304007ebaSmrg#endif                          /* if GX_FILL_RECT_SUPPORT */
294f29dbc25Smrg
295f29dbc25Smrg#if GX_CLREXP_8X8_PAT_SUPPORT
296f29dbc25Smrg/*----------------------------------------------------------------------------
297f29dbc25Smrg * GXSetupForColor8x8PatternFill
298f29dbc25Smrg *
299f29dbc25Smrg * Description  :8x8 color pattern data is 64 pixels of full color data
300f29dbc25Smrg *               stored linearly in offscreen video memory.  These patterns
301f29dbc25Smrg *               are useful as a substitute for 8x8 mono patterns when tiling,
302f29dbc25Smrg *               doing opaque stipples, or regular stipples.
303f29dbc25Smrg *
304f29dbc25Smrg *    Arg        Type     Comment
305f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
306f29dbc25Smrg *    patx        int     x offset to pattern data
307f29dbc25Smrg *    paty        int     y offset to pattern data
308f29dbc25Smrg *    rop         int     unmapped raster operation
309f29dbc25Smrg * planemask     uint     -1 (copy) or pattern data
310f29dbc25Smrg * trans_color    int     -1 (copy) or transparent color (not enabled)
311f29dbc25Smrg *                         trans color only supported on source channel
312f29dbc25Smrg *                         or in monochrome pattern channel
313f29dbc25Smrg *
314f29dbc25Smrg * Returns      :none.
315f29dbc25Smrg *
316f29dbc25Smrg *---------------------------------------------------------------------------*/
317f29dbc25Smrg
318f29dbc25Smrgstatic void
319f29dbc25SmrgGXSetupForColor8x8PatternFill(ScrnInfoPtr pScrni, int patx, int paty, int rop,
32004007ebaSmrg                              uint planemask, int trans_color)
321f29dbc25Smrg{
322f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR(pScrni);
323f29dbc25Smrg
324f29dbc25Smrg    //ErrorF("GXSetupForColor8x8PatternFill() pat %#x,%#x rop %#x %#x %#x\n",
325f29dbc25Smrg    //    patx, paty, rop, planemask, trans_color);
326f29dbc25Smrg    rop &= 0x0F;
32704007ebaSmrg    gc8x8p = (unsigned long *) FBADDR(patx, paty);
328f29dbc25Smrg    /* gfx_set_solid_pattern is needed to clear src/pat transparency */
329f29dbc25Smrg    gfx_set_solid_pattern(0);
330f29dbc25Smrg    gfx_set_raster_operation(planemask == ~0U ? PDfn[rop] :
33104007ebaSmrg                             (gfx_set_solid_source(planemask), PDfn_SM[rop]));
332f29dbc25Smrg    gfx2_set_source_stride(pGeode->Pitch);
333f29dbc25Smrg    gfx2_set_destination_stride(pGeode->Pitch);
334f29dbc25Smrg    if (trans_color == -1)
33504007ebaSmrg        gfx2_set_source_transparency(0, 0);
336f29dbc25Smrg    else
33704007ebaSmrg        gfx2_set_source_transparency(trans_color, ~0);
338f29dbc25Smrg}
339f29dbc25Smrg
340f29dbc25Smrg/*----------------------------------------------------------------------------
341f29dbc25Smrg * GXSubsequentColor8x8PatternFillRect
342f29dbc25Smrg *
343f29dbc25Smrg * Description  :see GXSetupForColor8x8PatternFill.
344f29dbc25Smrg *
345f29dbc25Smrg *    Arg        Type     Comment
346f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
347f29dbc25Smrg *   patx         int     pattern phase x offset
348f29dbc25Smrg *   paty         int     pattern phase y offset
349f29dbc25Smrg *      x         int     destination x offset
350f29dbc25Smrg *      y         int     destination y offset
351f29dbc25Smrg *      w         int     fill area width (pixels)
352f29dbc25Smrg *      h         int     fill area height (pixels)
353f29dbc25Smrg *
354f29dbc25Smrg * Returns      :none
355f29dbc25Smrg *
356f29dbc25Smrg * Sample application uses:
357f29dbc25Smrg *   - Patterned desktops
358f29dbc25Smrg *   - x11perf: stippled rectangle tests (-srect500).
359f29dbc25Smrg *   - x11perf: opaque stippled rectangle tests (-osrect500).
360f29dbc25Smrg *--------------------------------------------------------------------------*/
361f29dbc25Smrgstatic void
362f29dbc25SmrgGXSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrni, int patx, int paty,
36304007ebaSmrg                                    int x, int y, int w, int h)
364f29dbc25Smrg{
365f29dbc25Smrg    //ErrorF(
366f29dbc25Smrg    //    "GXSubsequentColor8x8PatternFillRect() patxy %d,%d at %d,%d %dsx%d\n",
367f29dbc25Smrg    //    patx, paty, x, y, w, h);
368f29dbc25Smrg    gfx2_set_pattern_origin(patx, paty);
369f29dbc25Smrg    gfx2_color_pattern_fill(CALC_FBOFFSET(x, y), w, h, gc8x8p);
370f29dbc25Smrg}
371f29dbc25Smrg
372f29dbc25Smrg/* GX_CLREXP_8X8_PAT_SUPPORT */
373f29dbc25Smrg#endif
374f29dbc25Smrg
375f29dbc25Smrg#if GX_MONO_8X8_PAT_SUPPORT
376f29dbc25Smrg/*----------------------------------------------------------------------------
377f29dbc25Smrg * GXSetupForMono8x8PatternFill
378f29dbc25Smrg *
379f29dbc25Smrg * Description  :8x8 mono pattern data is 64 bits of color expansion data
380f29dbc25Smrg *               with ones indicating the foreground color and zeros
381f29dbc25Smrg *               indicating the background color.  These patterns are
382f29dbc25Smrg *               useful when tiling, doing opaque stipples, or regular
383f29dbc25Smrg *               stipples.
384f29dbc25Smrg *
385f29dbc25Smrg *    Arg        Type     Comment
386f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
387f29dbc25Smrg *    patx        int     x offset to pattern data
388f29dbc25Smrg *    paty        int     y offset to pattern data
389f29dbc25Smrg *     fg         int     foreground color
390f29dbc25Smrg *     bg         int     -1 (transparent) or background color
391f29dbc25Smrg *    rop         int     unmapped raster operation
392f29dbc25Smrg * planemask     uint     -1 (copy) or pattern data
393f29dbc25Smrg *
394f29dbc25Smrg * Returns      :none.
395f29dbc25Smrg *
396f29dbc25Smrg * Comments     :none.
397f29dbc25Smrg *
398f29dbc25Smrg *--------------------------------------------------------------------------*/
399f29dbc25Smrgstatic void
400f29dbc25SmrgGXSetupForMono8x8PatternFill(ScrnInfoPtr pScrni, int patx, int paty,
40104007ebaSmrg                             int fg, int bg, int rop, uint planemask)
402f29dbc25Smrg{
403f29dbc25Smrg    //ErrorF(
404f29dbc25Smrg    //"GXSetupForMono8x8PatternFill() pat %#x,%#x fg %#x bg %#x %#x %#x\n",
405f29dbc25Smrg    //patx, paty, fg, bg, rop, planemask);
406f29dbc25Smrg    rop &= 0x0F;
407f29dbc25Smrg#ifndef OPT_ACCEL
408f29dbc25Smrg    gfx_set_mono_pattern(bg, fg, patx, paty, bg == -1 ? 1 : 0);
409f29dbc25Smrg    gfx_set_raster_operation(planemask == ~0U ? PDfn[rop] :
41004007ebaSmrg                             (gfx_set_solid_source(planemask), PDfn_SM[rop]));
411f29dbc25Smrg#else
412f29dbc25Smrg    {
41304007ebaSmrg        unsigned int ROP = BPP |
41404007ebaSmrg            (bg ==
41504007ebaSmrg             -1 ? MGP_RM_PAT_MONO | MGP_RM_PAT_TRANS : MGP_RM_PAT_MONO) |
41604007ebaSmrg            (planemask == ~0U ? PDfn[rop] : PDfn_SM[rop]);
41704007ebaSmrg        BLT_MODE = ((ROP ^ (ROP >> 2)) & 0x33) == 0 ? MGP_BM_SRC_MONO : 0;
41804007ebaSmrg        if (((ROP ^ (ROP >> 1)) & 0x55) != 0)
41904007ebaSmrg            BLT_MODE |= MGP_BM_DST_REQ;
42004007ebaSmrg        GU2_WAIT_PENDING;
42104007ebaSmrg        WRITE_GP32(MGP_RASTER_MODE, ROP);
42204007ebaSmrg        WRITE_GP32(MGP_SRC_COLOR_FG, planemask);
42304007ebaSmrg        WRITE_GP32(MGP_PAT_COLOR_0, bg);
42404007ebaSmrg        WRITE_GP32(MGP_PAT_COLOR_1, fg);
42504007ebaSmrg        WRITE_GP32(MGP_PAT_DATA_0, patx);
42604007ebaSmrg        WRITE_GP32(MGP_PAT_DATA_1, paty);
42704007ebaSmrg        WRITE_GP32(MGP_STRIDE, ACCEL_STRIDE);
428f29dbc25Smrg    }
429f29dbc25Smrg#endif
430f29dbc25Smrg}
431f29dbc25Smrg
432f29dbc25Smrg/*----------------------------------------------------------------------------
433f29dbc25Smrg * GXSubsequentMono8x8PatternFillRect
434f29dbc25Smrg *
435f29dbc25Smrg * Description  :see GXSetupForMono8x8PatternFill
436f29dbc25Smrg *
437f29dbc25Smrg *    Arg        Type     Comment
438f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
439f29dbc25Smrg *   patx         int     pattern phase x offset
440f29dbc25Smrg *   paty         int     pattern phase y offset
441f29dbc25Smrg *      x         int     destination x offset
442f29dbc25Smrg *      y         int     destination y offset
443f29dbc25Smrg *      w         int     fill area width (pixels)
444f29dbc25Smrg *      h         int     fill area height (pixels)
445f29dbc25Smrg
446f29dbc25Smrg * Returns      :none
447f29dbc25Smrg *
448f29dbc25Smrg * Sample application uses:
449f29dbc25Smrg *   - Patterned desktops
450f29dbc25Smrg *   - x11perf: stippled rectangle tests (-srect500).
451f29dbc25Smrg *   - x11perf: opaque stippled rectangle tests (-osrect500).
452f29dbc25Smrg *--------------------------------------------------------------------------*/
453f29dbc25Smrgstatic void
454f29dbc25SmrgGXSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrni, int patx, int paty,
45504007ebaSmrg                                   int x, int y, int w, int h)
456f29dbc25Smrg{
457f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() pat %#x,%#x at %d,%d %dx%d\n",
45804007ebaSmrg                 __func__, patx, paty, x, y, w, h));
459f29dbc25Smrg#ifndef OPT_ACCEL
460f29dbc25Smrg    gfx_pattern_fill(x, y, w, h);
461f29dbc25Smrg#else
462f29dbc25Smrg    {
46304007ebaSmrg        unsigned int offset =
46404007ebaSmrg            CALC_FBOFFSET(x, y) | ((x & 7) << 26) | ((y & 7) << 29);
46504007ebaSmrg        unsigned int size = (w << 16) | h;
46604007ebaSmrg
46704007ebaSmrg        GU2_WAIT_PENDING;
46804007ebaSmrg        WRITE_GP32(MGP_DST_OFFSET, offset);
46904007ebaSmrg        WRITE_GP32(MGP_WID_HEIGHT, size);
47004007ebaSmrg        WRITE_GP32(MGP_BLT_MODE, BLT_MODE);
471f29dbc25Smrg    }
472f29dbc25Smrg#endif
473f29dbc25Smrg}
474f29dbc25Smrg
47504007ebaSmrg#endif                          /* GX_MONO_8X8_PAT_SUPPORT */
476f29dbc25Smrg
477f29dbc25Smrg#if GX_SCR2SCRCPY_SUPPORT
478f29dbc25Smrg/*----------------------------------------------------------------------------
479f29dbc25Smrg * GXSetupForScreenToScreenCopy
480f29dbc25Smrg *
481f29dbc25Smrg * Description  :SetupFor and Subsequent ScreenToScreenCopy functions
482f29dbc25Smrg *               provide an interface for copying rectangular areas from
483f29dbc25Smrg *               video memory to video memory.
484f29dbc25Smrg *
485f29dbc25Smrg *    Arg        Type     Comment
486f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
487f29dbc25Smrg *   xdir         int     x copy direction (up/dn)
488f29dbc25Smrg *   ydir         int     y copy direction (up/dn)
489f29dbc25Smrg *    rop         int     unmapped raster operation
490f29dbc25Smrg * planemask     uint     -1 (copy) or pattern data
491f29dbc25Smrg * trans_color    int     -1 (copy) or transparent color
492f29dbc25Smrg *
493f29dbc25Smrg * Returns      :none
494f29dbc25Smrg *---------------------------------------------------------------------------*/
495f29dbc25Smrgstatic void
496f29dbc25SmrgGXSetupForScreenToScreenCopy(ScrnInfoPtr pScrni, int xdir, int ydir, int rop,
49704007ebaSmrg                             uint planemask, int trans_color)
498f29dbc25Smrg{
499f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() xd%d yd%d rop %#x %#x %#x\n",
50004007ebaSmrg                 __func__, xdir, ydir, rop, planemask, trans_color));
501f29dbc25Smrg    rop &= 0x0F;
502f29dbc25Smrg#ifndef OPT_ACCEL
503f29dbc25Smrg    {
50404007ebaSmrg        GeodeRec *pGeode = GEODEPTR(pScrni);
50504007ebaSmrg
50604007ebaSmrg        gfx_set_solid_pattern(planemask);
50704007ebaSmrg        /* transparency is a parameter to set_rop, but set...pattern clears
50804007ebaSmrg         * transparency */
50904007ebaSmrg        if (trans_color == -1)
51004007ebaSmrg            gfx2_set_source_transparency(0, 0);
51104007ebaSmrg        else
51204007ebaSmrg            gfx2_set_source_transparency(trans_color, ~0);
51304007ebaSmrg        gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
51404007ebaSmrg        gfx2_set_source_stride(pGeode->Pitch);
51504007ebaSmrg        gfx2_set_destination_stride(pGeode->Pitch);
516f29dbc25Smrg    }
517f29dbc25Smrg#else
518f29dbc25Smrg    {
51904007ebaSmrg        unsigned int ROP = BPP | (planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
52004007ebaSmrg
52104007ebaSmrg        if (trans_color != -1)
52204007ebaSmrg            ROP |= MGP_RM_SRC_TRANS;
52304007ebaSmrg        BLT_MODE = ((ROP ^ (ROP >> 1)) & 0x55) != 0 ?
52404007ebaSmrg            MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
52504007ebaSmrg        GU2_WAIT_PENDING;
52604007ebaSmrg        WRITE_GP32(MGP_RASTER_MODE, ROP);
52704007ebaSmrg        WRITE_GP32(MGP_PAT_COLOR_0, planemask);
52804007ebaSmrg        WRITE_GP32(MGP_SRC_COLOR_FG, trans_color);
52904007ebaSmrg        WRITE_GP32(MGP_SRC_COLOR_BG, ~0);
53004007ebaSmrg        WRITE_GP32(MGP_STRIDE, ACCEL_STRIDE);
531f29dbc25Smrg    }
532f29dbc25Smrg#endif
533f29dbc25Smrg}
534f29dbc25Smrg
535f29dbc25Smrg/*----------------------------------------------------------------------------
536f29dbc25Smrg * GXSubsquentScreenToScreenCopy
537f29dbc25Smrg *
538f29dbc25Smrg * Description  :see GXSetupForScreenToScreenCopy.
539f29dbc25Smrg *
540f29dbc25Smrg *    Arg        Type     Comment
541f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
542f29dbc25Smrg *     x1         int     source x offset
543f29dbc25Smrg *     y1         int     source y offset
544f29dbc25Smrg *     x2         int     destination x offset
545f29dbc25Smrg *     y2         int     destination y offset
546f29dbc25Smrg *      w         int     copy area width (pixels)
547f29dbc25Smrg *      h         int     copy area height (pixels)
548f29dbc25Smrg *
549f29dbc25Smrg * Returns      :none
550f29dbc25Smrg *
551f29dbc25Smrg * Sample application uses (non-transparent):
552f29dbc25Smrg *   - Moving windows.
553f29dbc25Smrg *   - x11perf: scroll tests (-scroll500).
554f29dbc25Smrg *   - x11perf: copy from window to window (-copywinwin500).
555f29dbc25Smrg *---------------------------------------------------------------------------*/
556f29dbc25Smrgstatic void
557f29dbc25SmrgGXSubsequentScreenToScreenCopy(ScrnInfoPtr pScrni,
55804007ebaSmrg                               int x1, int y1, int x2, int y2, int w, int h)
559f29dbc25Smrg{
560f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() from %d,%d to %d,%d %dx%d\n",
56104007ebaSmrg                 __func__, x1, y1, x2, y2, w, h));
562f29dbc25Smrg#ifndef OPT_ACCEL
563f29dbc25Smrg    {
56404007ebaSmrg        int flags = 0;
56504007ebaSmrg
56604007ebaSmrg        if (x2 > x1)
56704007ebaSmrg            flags |= 1;
56804007ebaSmrg        if (y2 > y1)
56904007ebaSmrg            flags |= 2;
57004007ebaSmrg        gfx2_screen_to_screen_blt(CALC_FBOFFSET(x1, y1), CALC_FBOFFSET(x2,
57104007ebaSmrg                                                                       y2), w,
57204007ebaSmrg                                  h, flags);
573f29dbc25Smrg    }
574f29dbc25Smrg#else
575f29dbc25Smrg    {
57604007ebaSmrg        GeodeRec *pGeode = GEODEPTR(pScrni);
57704007ebaSmrg        unsigned int src = CALC_FBOFFSET(x1, y1);
57804007ebaSmrg        unsigned int dst = CALC_FBOFFSET(x2, y2);
57904007ebaSmrg        unsigned int size = (w << 16) | h;
58004007ebaSmrg        unsigned int blt_mode = BLT_MODE;
58104007ebaSmrg
58204007ebaSmrg        if (x2 > x1) {
58304007ebaSmrg            int n = (w << gu2_xshift) - 1;
58404007ebaSmrg
58504007ebaSmrg            src += n;
58604007ebaSmrg            dst += n;
58704007ebaSmrg            blt_mode |= MGP_BM_NEG_XDIR;
58804007ebaSmrg        }
58904007ebaSmrg        if (y2 > y1) {
59004007ebaSmrg            int n = (h - 1) * pGeode->Pitch;
59104007ebaSmrg
59204007ebaSmrg            src += n;
59304007ebaSmrg            dst += n;
59404007ebaSmrg            blt_mode |= MGP_BM_NEG_YDIR;
59504007ebaSmrg        }
59604007ebaSmrg        GU2_WAIT_PENDING;
59704007ebaSmrg        WRITE_GP32(MGP_SRC_OFFSET, src);
59804007ebaSmrg        WRITE_GP32(MGP_DST_OFFSET, dst);
59904007ebaSmrg        WRITE_GP32(MGP_WID_HEIGHT, size);
60004007ebaSmrg        WRITE_GP16(MGP_BLT_MODE, blt_mode);
601f29dbc25Smrg    }
602f29dbc25Smrg#endif
603f29dbc25Smrg}
604f29dbc25Smrg
60504007ebaSmrg#endif                          /* if GX_SCR2SCRCPY_SUPPORT */
606f29dbc25Smrg
607f29dbc25Smrg#if GX_SCANLINE_SUPPORT
608f29dbc25Smrg/*----------------------------------------------------------------------------
609f29dbc25Smrg * GXSetupForScanlineImageWrite
610f29dbc25Smrg *
611f29dbc25Smrg * Description  :SetupFor/Subsequent ScanlineImageWrite and ImageWriteScanline
612f29dbc25Smrg *               transfer full color pixel data from system memory to video
613f29dbc25Smrg *               memory.  This is useful for dealing with alignment issues and
614f29dbc25Smrg *               performing raster ops on the data.
615f29dbc25Smrg *
616f29dbc25Smrg *    Arg        Type     Comment
617f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
618f29dbc25Smrg *    rop         int     unmapped raster operation
619f29dbc25Smrg * planemask     uint     -1 (copy) or pattern data
620f29dbc25Smrg *    bpp         int     bits per pixel (unused)
621f29dbc25Smrg *  depth         int     color depth (unused)
622f29dbc25Smrg *
623f29dbc25Smrg * Returns      :none
624f29dbc25Smrg *
625f29dbc25Smrg *  x11perf -putimage10
626f29dbc25Smrg *  x11perf -putimage100
627f29dbc25Smrg *  x11perf -putimage500
628f29dbc25Smrg *----------------------------------------------------------------------------
629f29dbc25Smrg */
630f29dbc25Smrgstatic void
631f29dbc25SmrgGXSetupForScanlineImageWrite(ScrnInfoPtr pScrni, int rop, uint planemask,
63204007ebaSmrg                             int trans_color, int bpp, int depth)
633f29dbc25Smrg{
634f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR(pScrni);
635f29dbc25Smrg
636f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() rop %#x %#x %#x %d %d\n",
63704007ebaSmrg                 __func__, rop, planemask, trans_color, bpp, depth));
638f29dbc25Smrg    rop &= 0x0F;
639f29dbc25Smrg    /* transparency is a parameter to set_rop, but set...pattern clears
640f29dbc25Smrg     * transparency */
641f29dbc25Smrg    gfx_set_solid_pattern(planemask);
642f29dbc25Smrg    if (trans_color == -1)
64304007ebaSmrg        gfx2_set_source_transparency(0, 0);
644f29dbc25Smrg    else
64504007ebaSmrg        gfx2_set_source_transparency(trans_color, ~0);
646f29dbc25Smrg    gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
647f29dbc25Smrg    gfx2_set_source_stride(pGeode->Pitch);
648f29dbc25Smrg    gfx2_set_destination_stride(pGeode->Pitch);
649f29dbc25Smrg}
650f29dbc25Smrg
651f29dbc25Smrg/*----------------------------------------------------------------------------
652f29dbc25Smrg * GXSubsequentScanlineImageWriteRect
653f29dbc25Smrg *
654f29dbc25Smrg * Description  : see GXSetupForScanlineImageWrite.
655f29dbc25Smrg *
656f29dbc25Smrg *    Arg        Type     Comment
657f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
658f29dbc25Smrg *      x         int     destination x offset
659f29dbc25Smrg *      y         int     destination y offset
660f29dbc25Smrg *      w         int     copy area width (pixels)
661f29dbc25Smrg *      h         int     copy area height (pixels)
662f29dbc25Smrg * skipleft       int     x margin (pixels) to skip (not enabled)
663f29dbc25Smrg *
664f29dbc25Smrg * Returns      :none
665f29dbc25Smrg *---------------------------------------------------------------------------*/
666f29dbc25Smrgstatic void
667f29dbc25SmrgGXSubsequentScanlineImageWriteRect(ScrnInfoPtr pScrni,
66804007ebaSmrg                                   int x, int y, int w, int h, int skipleft)
669f29dbc25Smrg{
670f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() rop %d,%d %dx%d %d\n",
67104007ebaSmrg                 __func__, x, y, w, h, skipleft));
672f29dbc25Smrg    giwr.x = x;
673f29dbc25Smrg    giwr.y = y;
674f29dbc25Smrg    giwr.w = w;
675f29dbc25Smrg    giwr.h = h;
676f29dbc25Smrg#if !GX_USE_OFFSCRN_MEM
677f29dbc25Smrg#if !GX_ONE_LINE_AT_A_TIME
678f29dbc25Smrg    GXAccelSync(pScrni);
679f29dbc25Smrg#endif
680f29dbc25Smrg#endif
681f29dbc25Smrg}
682f29dbc25Smrg
683f29dbc25Smrg/*----------------------------------------------------------------------------
684f29dbc25Smrg * GXSubsquentImageWriteScanline
685f29dbc25Smrg *
686f29dbc25Smrg * Description  : see GXSetupForScanlineImageWrite.
687f29dbc25Smrg *
688f29dbc25Smrg *    Arg        Type     Comment
689f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
690f29dbc25Smrg *  bufno         int     scanline number in write group
691f29dbc25Smrg *
692f29dbc25Smrg * Returns      :none
693f29dbc25Smrg *
694f29dbc25Smrg * Sample application uses (non-transparent):
695f29dbc25Smrg *   - Moving windows.
696f29dbc25Smrg *   - x11perf: scroll tests (-scroll500).
697f29dbc25Smrg *   - x11perf: copy from window to window (-copywinwin500).
698f29dbc25Smrg *
699f29dbc25Smrg *---------------------------------------------------------------------------*/
700f29dbc25Smrgstatic void
701f29dbc25SmrgGXSubsequentImageWriteScanline(ScrnInfoPtr pScrni, int bufno)
702f29dbc25Smrg{
703f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR(pScrni);
704f29dbc25Smrg
705f29dbc25Smrg#if !GX_USE_OFFSCRN_MEM
706f29dbc25Smrg    unsigned long offset;
707f29dbc25Smrg#endif
708f29dbc25Smrg
709f29dbc25Smrg#if GX_ONE_LINE_AT_A_TIME
710f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %d\n", __func__, bufno));
711f29dbc25Smrg#if !GX_USE_OFFSCRN_MEM
712f29dbc25Smrg    offset = pGeode->AccelImageWriteBuffers[bufno] - pGeode->FBBase;
713f29dbc25Smrg    gfx2_screen_to_screen_blt(offset, CALC_FBOFFSET(giwr.x, giwr.y), giwr.w,
71404007ebaSmrg                              1, 0);
71504007ebaSmrg#else                           /* if !GX_USE_OFFSCRN_MEM */
716f29dbc25Smrg    gfx2_color_bitmap_to_screen_blt(0, 0, CALC_FBOFFSET(giwr.x, giwr.y),
71704007ebaSmrg                                    giwr.w, 1,
71804007ebaSmrg                                    pGeode->AccelImageWriteBuffers[bufno],
71904007ebaSmrg                                    pGeode->Pitch);
72004007ebaSmrg#endif                          /* if !GX_USE_OFFSCRN_MEM */
721f29dbc25Smrg    ++giwr.y;
72204007ebaSmrg#else                           /* if GX_ONE_LINE_AT_A_TIME */
723f29dbc25Smrg    int blt_height;
724f29dbc25Smrg
725f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %d\n", __func__, bufno));
726f29dbc25Smrg
727f29dbc25Smrg    if ((blt_height = pGeode->NoOfImgBuffers) > giwr.h)
72804007ebaSmrg        blt_height = giwr.h;
729f29dbc25Smrg    if (++bufno < blt_height)
73004007ebaSmrg        return;
731f29dbc25Smrg#if !GX_USE_OFFSCRN_MEM
732f29dbc25Smrg    offset = pGeode->AccelImageWriteBuffers[0] - pGeode->FBBase;
733f29dbc25Smrg    gfx2_screen_to_screen_blt(offset, CALC_FBOFFSET(giwr.x, giwr.y), giwr.w,
73404007ebaSmrg                              blt_height, 0);
735f29dbc25Smrg    GXAccelSync(pScrni);
73604007ebaSmrg#else                           /* if !GX_USE_OFFSCRN_MEM */
737f29dbc25Smrg    gfx2_color_bitmap_to_screen_blt(0, 0, CALC_FBOFFSET(giwr.x, giwr.y),
73804007ebaSmrg                                    giwr.w, blt_height,
73904007ebaSmrg                                    pGeode->AccelImageWriteBuffers[0],
74004007ebaSmrg                                    pGeode->Pitch);
74104007ebaSmrg#endif                          /* if !GX_USE_OFFSCRN_MEM */
742f29dbc25Smrg    giwr.h -= blt_height;
743f29dbc25Smrg    giwr.y += blt_height;
74404007ebaSmrg#endif                          /* if GX_ONE_LINE_AT_A_TIME */
745f29dbc25Smrg}
74604007ebaSmrg#endif                          /* GX_SCANLINE_SUPPORT */
747f29dbc25Smrg
748f29dbc25Smrg#if GX_CPU2SCREXP_SUPPORT
749f29dbc25Smrg/*----------------------------------------------------------------------------
750f29dbc25Smrg * GXSetupForScanlineCPUToScreenColorExpandFill
751f29dbc25Smrg *
752f29dbc25Smrg * Description  :SetupFor/Subsequent CPUToScreenColorExpandFill and
753f29dbc25Smrg *               ColorExpandScanline routines provide an interface for
754f29dbc25Smrg *               doing expansion blits from source patterns stored in
755f29dbc25Smrg *               system memory.
756f29dbc25Smrg *
757f29dbc25Smrg *    Arg        Type     Comment
758f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
759f29dbc25Smrg *     fg         int     foreground color
760f29dbc25Smrg *     bg         int     -1 (transparent) or background color
761f29dbc25Smrg *    rop         int     unmapped raster operation
762f29dbc25Smrg * planemask     uint     -1 (copy) or pattern data
763f29dbc25Smrg *
764f29dbc25Smrg * Returns      :none.
765f29dbc25Smrg *---------------------------------------------------------------------------*/
766f29dbc25Smrg
767f29dbc25Smrgstatic void
768f29dbc25SmrgGXSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrni,
76904007ebaSmrg                                             int fg, int bg, int rop,
77004007ebaSmrg                                             uint planemask)
771f29dbc25Smrg{
772f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR(pScrni);
773f29dbc25Smrg    ulong srcpitch;
774f29dbc25Smrg
775f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() fg %#x bg %#x rop %#x %#x\n",
77604007ebaSmrg                 __func__, fg, bg, rop, planemask));
777f29dbc25Smrg    rop &= 0x0F;
778f29dbc25Smrg    srcpitch = ((pGeode->Pitch + 31) >> 5) << 2;
779f29dbc25Smrg#ifndef OPT_ACCEL
780f29dbc25Smrg    gfx_set_solid_pattern(planemask);
781f29dbc25Smrg    gfx_set_mono_source(bg, fg, bg == -1 ? 1 : 0);
782f29dbc25Smrg    gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
783f29dbc25Smrg    gfx2_set_source_stride(srcpitch);
784f29dbc25Smrg    gfx2_set_destination_stride(pGeode->Pitch);
785f29dbc25Smrg#else
786f29dbc25Smrg    {
78704007ebaSmrg        unsigned int stride = (srcpitch << 16) | pGeode->Pitch;
78804007ebaSmrg        unsigned int ROP = BPP | (planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
78904007ebaSmrg
79004007ebaSmrg        if (bg == -1)
79104007ebaSmrg            ROP |= MGP_RM_SRC_TRANS;
79204007ebaSmrg        BLT_MODE = ((ROP ^ (ROP >> 1)) & 0x55) != 0 ?
79304007ebaSmrg            MGP_BM_SRC_MONO | MGP_BM_SRC_FB | MGP_BM_DST_REQ :
79404007ebaSmrg            MGP_BM_SRC_MONO | MGP_BM_SRC_FB;
79504007ebaSmrg        GU2_WAIT_PENDING;
79604007ebaSmrg        WRITE_GP32(MGP_RASTER_MODE, ROP);
79704007ebaSmrg        WRITE_GP32(MGP_PAT_COLOR_0, planemask);
79804007ebaSmrg        WRITE_GP32(MGP_SRC_COLOR_BG, bg);
79904007ebaSmrg        WRITE_GP32(MGP_SRC_COLOR_FG, fg);
80004007ebaSmrg        WRITE_GP32(MGP_STRIDE, stride);
801f29dbc25Smrg    }
802f29dbc25Smrg#endif
803f29dbc25Smrg}
804f29dbc25Smrg
805f29dbc25Smrg/*----------------------------------------------------------------------------
806f29dbc25Smrg * GXSubsequentScanlineCPUToScreenColorExpandFill
807f29dbc25Smrg *
808f29dbc25Smrg  Description  :see GXSetupForScanlineCPUToScreenColorExpandFill
809f29dbc25Smrg *
810f29dbc25Smrg * Parameters:
811f29dbc25Smrg *    Arg        Type     Comment
812f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
813f29dbc25Smrg *     x          int     destination x offset
814f29dbc25Smrg *     y          int     destination y offset
815f29dbc25Smrg *     w          int     fill area width (pixels)
816f29dbc25Smrg *     h          int     fill area height (pixels)
817f29dbc25Smrg *
818f29dbc25Smrg * Returns      :none
819f29dbc25Smrg *
820f29dbc25Smrg *---------------------------------------------------------------------------*/
821f29dbc25Smrgstatic void
822f29dbc25SmrgGXSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrni,
82304007ebaSmrg                                               int x, int y, int w, int h,
82404007ebaSmrg                                               int skipleft)
825f29dbc25Smrg{
826f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %dx%d %d\n",
82704007ebaSmrg                 __func__, x, y, w, h, skipleft));
828f29dbc25Smrg    gc2s.x = x;
829f29dbc25Smrg    gc2s.y = y;
830f29dbc25Smrg    gc2s.w = w;
831f29dbc25Smrg    gc2s.h = h;
832f29dbc25Smrg#ifdef OPT_ACCEL
833f29dbc25Smrg    {
834f29dbc25Smrg#if GX_ONE_LINE_AT_A_TIME
83504007ebaSmrg        unsigned int size = (gc2s.w << 16) | 1;
836f29dbc25Smrg
83704007ebaSmrg        GU2_WAIT_PENDING;
83804007ebaSmrg        WRITE_GP32(MGP_WID_HEIGHT, size);
839f29dbc25Smrg#else
84004007ebaSmrg        GeodeRec *pGeode = GEODEPTR(pScrni);
84104007ebaSmrg        unsigned int src = pGeode->AccelColorExpandBuffers[0] - pGeode->FBBase;
84204007ebaSmrg
84304007ebaSmrg        GU2_WAIT_PENDING;
84404007ebaSmrg        WRITE_GP32(MGP_SRC_OFFSET, src);
845f29dbc25Smrg#endif
846f29dbc25Smrg    }
847f29dbc25Smrg#endif
848f29dbc25Smrg}
849f29dbc25Smrg
850f29dbc25Smrg/*----------------------------------------------------------------------------
851f29dbc25Smrg * GXSubsequentColorExpandScanline
852f29dbc25Smrg *
853f29dbc25Smrg * Description  :see GXSetupForScanlineCPUToScreenColorExpandFill
854f29dbc25Smrg *
855f29dbc25Smrg *    Arg        Type     Comment
856f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
857f29dbc25Smrg *  bufno         int     scanline number in write group
858f29dbc25Smrg *
859f29dbc25Smrg * Returns      :none
860f29dbc25Smrg *----------------------------------------------------------------------------
861f29dbc25Smrg */
862f29dbc25Smrgstatic void
863f29dbc25SmrgGXSubsequentColorExpandScanline(ScrnInfoPtr pScrni, int bufno)
864f29dbc25Smrg{
865f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR(pScrni);
866f29dbc25Smrg
867f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %d\n", __func__, bufno));
868f29dbc25Smrg#ifndef OPT_ACCEL
869f29dbc25Smrg    {
870f29dbc25Smrg#if GX_ONE_LINE_AT_A_TIME
87104007ebaSmrg        ulong offset = pGeode->AccelColorExpandBuffers[bufno] - pGeode->FBBase;
87204007ebaSmrg
87304007ebaSmrg        gfx2_mono_expand_blt(offset, 0, 0, CALC_FBOFFSET(gc2s.x, gc2s.y),
87404007ebaSmrg                             gc2s.w, 1, 0);
87504007ebaSmrg        ++gc2s.y;
87604007ebaSmrg#else                           /* if GX_ONE_LINE_AT_A_TIME */
87704007ebaSmrg        ulong srcpitch;
87804007ebaSmrg        int blt_height;
87904007ebaSmrg
88004007ebaSmrg        if ((blt_height = pGeode->NoOfImgBuffers) > gc2s.h)
88104007ebaSmrg            blt_height = gc2s.h;
88204007ebaSmrg        if (++bufno < blt_height)
88304007ebaSmrg            return;
88404007ebaSmrg
88504007ebaSmrg        /* convert from bits to dwords */
88604007ebaSmrg        srcpitch = ((pGeode->Pitch + 31) >> 5) << 2;
88704007ebaSmrg        gfx2_mono_bitmap_to_screen_blt(0, 0, CALC_FBOFFSET(gc2s.x, gc2s.y),
88804007ebaSmrg                                       gc2s.w, blt_height,
88904007ebaSmrg                                       pGeode->AccelColorExpandBuffers[0],
89004007ebaSmrg                                       srcpitch);
89104007ebaSmrg        gc2s.h -= blt_height;
89204007ebaSmrg        gc2s.y += blt_height;
89304007ebaSmrg#endif                          /* if GX_ONE_LINE_AT_A_TIME */
894f29dbc25Smrg    }
89504007ebaSmrg#else                           /* ifndef OPT_ACCEL */
896f29dbc25Smrg    {
897f29dbc25Smrg#if GX_ONE_LINE_AT_A_TIME
89804007ebaSmrg        unsigned int src =
89904007ebaSmrg            pGeode->AccelColorExpandBuffers[bufno] - pGeode->FBBase;
90004007ebaSmrg        unsigned int dst = CALC_FBOFFSET(gc2s.x, gc2s.y);
90104007ebaSmrg
90204007ebaSmrg        ++gc2s.y;
90304007ebaSmrg        GU2_WAIT_PENDING;
90404007ebaSmrg        WRITE_GP32(MGP_SRC_OFFSET, src);
90504007ebaSmrg        WRITE_GP32(MGP_DST_OFFSET, dst);
90604007ebaSmrg        WRITE_GP16(MGP_BLT_MODE, BLT_MODE);
90704007ebaSmrg#else                           /* if GX_ONE_LINE_AT_A_TIME */
90804007ebaSmrg        unsigned int dst, size;
90904007ebaSmrg        int blt_height;
91004007ebaSmrg
91104007ebaSmrg        GU2_WAIT_BUSY;
91204007ebaSmrg        if ((blt_height = pGeode->NoOfImgBuffers) > gc2s.h)
91304007ebaSmrg            blt_height = gc2s.h;
91404007ebaSmrg        if (++bufno < blt_height)
91504007ebaSmrg            return;
91604007ebaSmrg        dst = CALC_FBOFFSET(gc2s.x, gc2s.y);
91704007ebaSmrg        size = (gc2s.w << 16) | blt_height;
91804007ebaSmrg        gc2s.h -= blt_height;
91904007ebaSmrg        gc2s.y += blt_height;
92004007ebaSmrg        GU2_WAIT_PENDING;
92104007ebaSmrg        WRITE_GP32(MGP_DST_OFFSET, dst);
92204007ebaSmrg        WRITE_GP32(MGP_WID_HEIGHT, size);
92304007ebaSmrg        WRITE_GP16(MGP_BLT_MODE, BLT_MODE);
92404007ebaSmrg#endif                          /* if GX_ONE_LINE_AT_A_TIME */
925f29dbc25Smrg    }
92604007ebaSmrg#endif                          /* ifndef OPT_ACCEL */
927f29dbc25Smrg}
92804007ebaSmrg#endif                          /* GX_CPU2SCREXP_SUPPORT */
929f29dbc25Smrg
930f29dbc25Smrg#if GX_SCR2SCREXP_SUPPORT
931f29dbc25Smrg/*----------------------------------------------------------------------------
932f29dbc25Smrg * GXSetupForScreenToScreenColorExpandFill
933f29dbc25Smrg *
934f29dbc25Smrg * Description  :SetupFor/Subsequent ScreenToScreenColorExpandFill and
935f29dbc25Smrg *               ColorExpandScanline routines provide an interface for
936f29dbc25Smrg *               doing expansion blits from source patterns stored in
937f29dbc25Smrg *               video memory.
938f29dbc25Smrg *
939f29dbc25Smrg *    Arg        Type     Comment
940f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
941f29dbc25Smrg *     fg         int     foreground color
942f29dbc25Smrg *     bg         int     -1 (transparent) or background color
943f29dbc25Smrg *    rop         int     unmapped raster operation
944f29dbc25Smrg * planemask     uint     -1 (copy) or pattern data
945f29dbc25Smrg *
946f29dbc25Smrg * Returns      :none.
947f29dbc25Smrg *---------------------------------------------------------------------------*/
948f29dbc25Smrg
949f29dbc25Smrgstatic void
950f29dbc25SmrgGXSetupForScreenToScreenColorExpandFill(ScrnInfoPtr pScrni, int fg, int bg,
95104007ebaSmrg                                        int rop, uint planemask)
952f29dbc25Smrg{
953f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() fg %#x bg %#x rop %#x %#x\n",
95404007ebaSmrg                 __func__, fg, bg, rop, planemask));
955f29dbc25Smrg    rop &= 0x0F;
956f29dbc25Smrg#ifndef OPT_ACCEL
957f29dbc25Smrg    {
95804007ebaSmrg        GeodeRec *pGeode = GEODEPTR(pScrni);
959f29dbc25Smrg
96004007ebaSmrg        gfx_set_solid_pattern(planemask);
96104007ebaSmrg        gfx_set_mono_source(bg, fg, bg == -1 ? 1 : 0);
96204007ebaSmrg        gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
96304007ebaSmrg        gfx2_set_source_stride(pGeode->Pitch);
96404007ebaSmrg        gfx2_set_destination_stride(pGeode->Pitch);
965f29dbc25Smrg    }
966f29dbc25Smrg#else
967f29dbc25Smrg    {
96804007ebaSmrg        unsigned int ROP = BPP | (planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
96904007ebaSmrg
97004007ebaSmrg        if (bg == -1)
97104007ebaSmrg            ROP |= MGP_RM_SRC_TRANS;
97204007ebaSmrg        BLT_MODE = ((ROP ^ (ROP >> 1)) & 0x55) != 0 ?
97304007ebaSmrg            MGP_BM_SRC_MONO | MGP_BM_SRC_FB | MGP_BM_DST_REQ :
97404007ebaSmrg            MGP_BM_SRC_MONO | MGP_BM_SRC_FB;
97504007ebaSmrg        GU2_WAIT_PENDING;
97604007ebaSmrg        WRITE_GP32(MGP_RASTER_MODE, ROP);
97704007ebaSmrg        WRITE_GP32(MGP_PAT_COLOR_0, planemask);
97804007ebaSmrg        WRITE_GP32(MGP_SRC_COLOR_BG, bg);
97904007ebaSmrg        WRITE_GP32(MGP_SRC_COLOR_FG, fg);
98004007ebaSmrg        WRITE_GP32(MGP_STRIDE, ACCEL_STRIDE);
981f29dbc25Smrg    }
982f29dbc25Smrg#endif
983f29dbc25Smrg}
984f29dbc25Smrg
985f29dbc25Smrg/*----------------------------------------------------------------------------
986f29dbc25Smrg * GXSubsequentScreenToScreenColorExpandFill
987f29dbc25Smrg *
988f29dbc25Smrg * Description  :see GXSetupForScreenToScreenColorExpandFill
989f29dbc25Smrg *
990f29dbc25Smrg * Parameters:
991f29dbc25Smrg *    Arg        Type     Comment
992f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
993f29dbc25Smrg *     x          int     destination x offset
994f29dbc25Smrg *     y          int     destination y offset
995f29dbc25Smrg *     w          int     fill area width (pixels)
996f29dbc25Smrg *     h          int     fill area height (pixels)
997f29dbc25Smrg * offset         int     initial x offset
998f29dbc25Smrg *
999f29dbc25Smrg * Returns      :none
1000f29dbc25Smrg *
1001f29dbc25Smrg *---------------------------------------------------------------------------*/
1002f29dbc25Smrgstatic void
1003f29dbc25SmrgGXSubsequentScreenToScreenColorExpandFill(ScrnInfoPtr pScrni,
100404007ebaSmrg                                          int x, int y, int w, int h, int srcx,
100504007ebaSmrg                                          int srcy, int offset)
1006f29dbc25Smrg{
1007f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %dx%d %d,%d %d\n",
100804007ebaSmrg                 __func__, x, y, w, h, srcx, srcy, offset));
1009f29dbc25Smrg#ifndef OPT_ACCEL
1010f29dbc25Smrg    gfx2_mono_expand_blt(CALC_FBOFFSET(srcx, srcy), offset, 0,
101104007ebaSmrg                         CALC_FBOFFSET(x, y), w, h, 0);
1012f29dbc25Smrg#else
1013f29dbc25Smrg    {
101404007ebaSmrg        unsigned int src = (CALC_FBOFFSET(srcx,
101504007ebaSmrg                                          srcy) +
101604007ebaSmrg                            (offset >> 3)) | ((offset & 7) << 26);
101704007ebaSmrg        unsigned int dst = CALC_FBOFFSET(x, y);
101804007ebaSmrg        unsigned int size = (w << 16) | h;
101904007ebaSmrg
102004007ebaSmrg        GU2_WAIT_PENDING;
102104007ebaSmrg        WRITE_GP32(MGP_SRC_OFFSET, src);
102204007ebaSmrg        WRITE_GP32(MGP_DST_OFFSET, dst);
102304007ebaSmrg        WRITE_GP32(MGP_WID_HEIGHT, size);
102404007ebaSmrg        WRITE_GP16(MGP_BLT_MODE, BLT_MODE);
1025f29dbc25Smrg    }
1026f29dbc25Smrg#endif
1027f29dbc25Smrg}
102804007ebaSmrg#endif                          /* GX_SCR2SCREXP_SUPPORT */
1029f29dbc25Smrg
1030f29dbc25Smrg#define VM_MAJOR_DEC 0
1031f29dbc25Smrg#define VM_MINOR_DEC 0
1032f29dbc25Smrg
1033f29dbc25Smrgstatic unsigned short vmode[] = {
1034f29dbc25Smrg    VM_X_MAJOR | VM_MAJOR_INC | VM_MINOR_INC,
1035f29dbc25Smrg    /* !XDECREASING !YDECREASING !YMAJOR */
1036f29dbc25Smrg    VM_Y_MAJOR | VM_MAJOR_INC | VM_MINOR_INC,
1037f29dbc25Smrg    /* !XDECREASING !YDECREASING  YMAJOR */
1038f29dbc25Smrg    VM_X_MAJOR | VM_MAJOR_INC | VM_MINOR_DEC,
1039f29dbc25Smrg    /* !XDECREASING  YDECREASING !YMAJOR */
1040f29dbc25Smrg    VM_Y_MAJOR | VM_MAJOR_DEC | VM_MINOR_INC,
1041f29dbc25Smrg    /* !XDECREASING  YDECREASING  YMAJOR */
1042f29dbc25Smrg    VM_X_MAJOR | VM_MAJOR_DEC | VM_MINOR_INC,
1043f29dbc25Smrg    /*  XDECREASING !YDECREASING !YMAJOR */
1044f29dbc25Smrg    VM_Y_MAJOR | VM_MAJOR_INC | VM_MINOR_DEC,
1045f29dbc25Smrg    /*  XDECREASING !YDECREASING  YMAJOR */
1046f29dbc25Smrg    VM_X_MAJOR | VM_MAJOR_DEC | VM_MINOR_DEC,
1047f29dbc25Smrg    /*  XDECREASING  YDECREASING !YMAJOR */
1048f29dbc25Smrg    VM_Y_MAJOR | VM_MAJOR_DEC | VM_MINOR_DEC,
1049f29dbc25Smrg    /*  XDECREASING  YDECREASING  YMAJOR */
1050f29dbc25Smrg};
1051f29dbc25Smrg
1052f29dbc25Smrg#if GX_BRES_LINE_SUPPORT
1053f29dbc25Smrg/*----------------------------------------------------------------------------
1054f29dbc25Smrg * GXSetupForSolidLine
1055f29dbc25Smrg *
1056f29dbc25Smrg * Description  :SetupForSolidLine and Subsequent HorVertLine TwoPointLine
1057f29dbc25Smrg *               BresenhamLine provides an interface for drawing thin
1058f29dbc25Smrg *               solid lines.
1059f29dbc25Smrg *
1060f29dbc25Smrg *    Arg        Type     Comment
1061f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
1062f29dbc25Smrg *   color        int     foreground fill color
1063f29dbc25Smrg *    rop         int     unmapped raster op
1064f29dbc25Smrg * planemask     uint     -1 (fill) or pattern data (not enabled)
1065f29dbc25Smrg *
1066f29dbc25Smrg * Returns		:none
1067f29dbc25Smrg *---------------------------------------------------------------------------*/
1068f29dbc25Smrgstatic void
1069f29dbc25SmrgGXSetupForSolidLine(ScrnInfoPtr pScrni, int color, int rop, uint planemask)
1070f29dbc25Smrg{
1071f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %#x %#x %#x\n",
107204007ebaSmrg                 __func__, color, rop, planemask));
1073f29dbc25Smrg    rop &= 0x0F;
1074f29dbc25Smrg#ifndef OPT_ACCEL
1075f29dbc25Smrg    gfx_set_solid_pattern(color);
1076f29dbc25Smrg    gfx_set_raster_operation(planemask == ~0U ? PDfn[rop] :
107704007ebaSmrg                             (gfx_set_solid_source(planemask), PDfn_SM[rop]));
1078f29dbc25Smrg#else
1079f29dbc25Smrg    {
108004007ebaSmrg        unsigned int ROP = BPP | (planemask == ~0U ? PDfn[rop] : PDfn_SM[rop]);
108104007ebaSmrg
108204007ebaSmrg        BLT_MODE = ((ROP ^ (ROP >> 2)) & 0x33) == 0 ? MGP_BM_SRC_MONO : 0;
108304007ebaSmrg        VEC_MODE = ((ROP ^ (ROP >> 1)) & 0x55) != 0 ? ((BLT_MODE |=
108404007ebaSmrg                                                        MGP_BM_DST_REQ),
108504007ebaSmrg                                                       MGP_VM_DST_REQ) : 0;
108604007ebaSmrg        GU2_WAIT_PENDING;
108704007ebaSmrg        WRITE_GP32(MGP_RASTER_MODE, ROP);
108804007ebaSmrg        WRITE_GP32(MGP_PAT_COLOR_0, color);
108904007ebaSmrg        WRITE_GP32(MGP_SRC_COLOR_FG, planemask);
109004007ebaSmrg        WRITE_GP32(MGP_STRIDE, ACCEL_STRIDE);
1091f29dbc25Smrg    }
1092f29dbc25Smrg#endif
1093f29dbc25Smrg}
1094f29dbc25Smrg
1095f29dbc25Smrg/*---------------------------------------------------------------------------
1096f29dbc25Smrg * GXSubsequentSolidBresenhamLine
1097f29dbc25Smrg *
1098f29dbc25Smrg * Description  :see GXSetupForSolidLine
1099f29dbc25Smrg *
1100f29dbc25Smrg *    Arg        Type     Comment
1101f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
1102f29dbc25Smrg *     x1         int     destination x offset
1103f29dbc25Smrg *     y1         int     destination y offset
1104f29dbc25Smrg * absmaj         int     Bresenman absolute major
1105f29dbc25Smrg * absmin         int     Bresenman absolute minor
1106f29dbc25Smrg *    err         int     Bresenman initial error term
1107f29dbc25Smrg *    len         int     length of the vector (pixels)
1108f29dbc25Smrg * octant         int     specifies sign and magnitude relationships
1109f29dbc25Smrg *                         used to determine axis of magor rendering
1110f29dbc25Smrg *                         and direction of vector progress.
1111f29dbc25Smrg *
1112f29dbc25Smrg * Returns      :none
1113f29dbc25Smrg *
1114f29dbc25Smrg *   - Window outlines on window move.
1115f29dbc25Smrg *   - x11perf: line segments (-line500).
1116f29dbc25Smrg *   - x11perf: line segments (-seg500).
1117f29dbc25Smrg *---------------------------------------------------------------------------*/
1118f29dbc25Smrgstatic void
1119f29dbc25SmrgGXSubsequentSolidBresenhamLine(ScrnInfoPtr pScrni, int x1, int y1,
112004007ebaSmrg                               int absmaj, int absmin, int err, int len,
112104007ebaSmrg                               int octant)
1122f29dbc25Smrg{
1123f29dbc25Smrg    long axial, diagn;
1124f29dbc25Smrg
1125f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %d %d, %d %d, %d\n",
112604007ebaSmrg                 __func__, x1, y1, absmaj, absmin, err, len, octant));
1127f29dbc25Smrg    if (len <= 0)
112804007ebaSmrg        return;
1129f29dbc25Smrg    axial = absmin;
1130f29dbc25Smrg    err += axial;
1131f29dbc25Smrg    diagn = absmin - absmaj;
1132f29dbc25Smrg#ifndef OPT_ACCEL
1133f29dbc25Smrg    gfx_bresenham_line(x1, y1, len, err, axial, diagn, vmode[octant]);
1134f29dbc25Smrg#else
1135f29dbc25Smrg    {
113604007ebaSmrg        unsigned int offset = CALC_FBOFFSET(x1, y1);
113704007ebaSmrg        unsigned int vec_err = (axial << 16) | (unsigned short) diagn;
113804007ebaSmrg        unsigned int vec_len = (len << 16) | (unsigned short) err;
113904007ebaSmrg        unsigned int vec_mode = VEC_MODE | vmode[octant];
114004007ebaSmrg
114104007ebaSmrg        GU2_WAIT_PENDING;
114204007ebaSmrg        WRITE_GP32(MGP_DST_OFFSET, offset);
114304007ebaSmrg        WRITE_GP32(MGP_VEC_ERR, vec_err);
114404007ebaSmrg        WRITE_GP32(MGP_VEC_LEN, vec_len);
114504007ebaSmrg        WRITE_GP32(MGP_VECTOR_MODE, vec_mode);
1146f29dbc25Smrg    }
1147f29dbc25Smrg#endif
1148f29dbc25Smrg}
1149f29dbc25Smrg
1150f29dbc25Smrg/*---------------------------------------------------------------------------
1151f29dbc25Smrg * GXSubsequentSolidTwoPointLine
1152f29dbc25Smrg *
1153f29dbc25Smrg * Description  :see GXSetupForSolidLine
1154f29dbc25Smrg *
1155f29dbc25Smrg *    Arg        Type     Comment
1156f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
1157f29dbc25Smrg *     x0         int     destination x start offset
1158f29dbc25Smrg *     y0         int     destination y start offset
1159f29dbc25Smrg *     x1         int     destination x end offset
1160f29dbc25Smrg *     y1         int     destination y end offset
1161f29dbc25Smrg *  flags         int     OMIT_LAST, dont draw last pixel (not used)
1162f29dbc25Smrg *
1163f29dbc25Smrg * Returns      :none
1164f29dbc25Smrg *---------------------------------------------------------------------------*/
1165f29dbc25Smrgstatic void
1166f29dbc25SmrgGXSubsequentSolidTwoPointLine(ScrnInfoPtr pScrni, int x0, int y0,
116704007ebaSmrg                              int x1, int y1, int flags)
1168f29dbc25Smrg{
1169f29dbc25Smrg    long dx, dy, dmaj, dmin, octant, bias;
1170f29dbc25Smrg    long axial, diagn, err, len;
1171f29dbc25Smrg
1172f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %d,%d, %#x\n",
117304007ebaSmrg                 __func__, x0, y0, x1, y1, flags));
1174f29dbc25Smrg
1175f29dbc25Smrg    if ((dx = x1 - x0) < 0)
117604007ebaSmrg        dx = -dx;
1177f29dbc25Smrg    if ((dy = y1 - y0) < 0)
117804007ebaSmrg        dy = -dy;
1179f29dbc25Smrg    if (dy >= dx) {
118004007ebaSmrg        dmaj = dy;
118104007ebaSmrg        dmin = dx;
118204007ebaSmrg        octant = YMAJOR;
118304007ebaSmrg    }
118404007ebaSmrg    else {
118504007ebaSmrg        dmaj = dx;
118604007ebaSmrg        dmin = dy;
118704007ebaSmrg        octant = 0;
1188f29dbc25Smrg    }
1189f29dbc25Smrg    len = dmaj;
1190f29dbc25Smrg    if ((flags & OMIT_LAST) == 0)
119104007ebaSmrg        ++len;
1192f29dbc25Smrg    if (len <= 0)
119304007ebaSmrg        return;
1194f29dbc25Smrg    if (x1 < x0)
119504007ebaSmrg        octant |= XDECREASING;
1196f29dbc25Smrg    if (y1 < y0)
119704007ebaSmrg        octant |= YDECREASING;
1198f29dbc25Smrg
1199f29dbc25Smrg    axial = dmin << 1;
1200f29dbc25Smrg    bias = miGetZeroLineBias(pScrni->pScreen);
1201f29dbc25Smrg    err = axial - dmaj - ((bias >> octant) & 1);
1202f29dbc25Smrg    diagn = (dmin - dmaj) << 1;
1203f29dbc25Smrg
1204f29dbc25Smrg#ifndef OPT_ACCEL
1205f29dbc25Smrg    gfx_bresenham_line(x0, y0, len, err, axial, diagn, vmode[octant]);
1206f29dbc25Smrg#else
1207f29dbc25Smrg    {
120804007ebaSmrg        unsigned int offset = CALC_FBOFFSET(x0, y0);
120904007ebaSmrg        unsigned int vec_err = (axial << 16) | (unsigned short) diagn;
121004007ebaSmrg        unsigned int vec_len = (len << 16) | (unsigned short) err;
121104007ebaSmrg        unsigned int vec_mode = VEC_MODE | vmode[octant];
121204007ebaSmrg
121304007ebaSmrg        GU2_WAIT_PENDING;
121404007ebaSmrg        WRITE_GP32(MGP_DST_OFFSET, offset);
121504007ebaSmrg        WRITE_GP32(MGP_VEC_ERR, vec_err);
121604007ebaSmrg        WRITE_GP32(MGP_VEC_LEN, vec_len);
121704007ebaSmrg        WRITE_GP32(MGP_VECTOR_MODE, vec_mode);
1218f29dbc25Smrg    }
1219f29dbc25Smrg#endif
1220f29dbc25Smrg}
1221f29dbc25Smrg
1222f29dbc25Smrg/*---------------------------------------------------------------------------
1223f29dbc25Smrg * GXSubsequentSolidHorVertLine
1224f29dbc25Smrg *
1225f29dbc25Smrg * Description  :see GXSetupForSolidLine
1226f29dbc25Smrg *
1227f29dbc25Smrg *    Arg        Type     Comment
1228f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
1229f29dbc25Smrg *     x          int     destination x offset
1230f29dbc25Smrg *     y          int     destination y offset
1231f29dbc25Smrg *    len         int     length of the vector (pixels)
1232f29dbc25Smrg *    dir         int     DEGREES_270 or DEGREES_0 line direction
1233f29dbc25Smrg *
1234f29dbc25Smrg * Sample application uses:
1235f29dbc25Smrg *   - Window outlines on window move.
1236f29dbc25Smrg *   - x11perf: line segments (-hseg500).
1237f29dbc25Smrg *   - x11perf: line segments (-vseg500).
1238f29dbc25Smrg *---------------------------------------------------------------------------
1239f29dbc25Smrg */
1240f29dbc25Smrgstatic void
124104007ebaSmrgGXSubsequentSolidHorVertLine(ScrnInfoPtr pScrni, int x, int y, int len, int dir)
1242f29dbc25Smrg{
1243f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %d %d\n", __func__, x, y, len, dir));
1244f29dbc25Smrg#ifndef OPT_ACCEL
1245f29dbc25Smrg    if (dir == DEGREES_0)
124604007ebaSmrg        gfx_pattern_fill(x, y, len, 1);
1247f29dbc25Smrg    else
124804007ebaSmrg        gfx_pattern_fill(x, y, 1, len);
1249f29dbc25Smrg#else
1250f29dbc25Smrg    {
125104007ebaSmrg        unsigned int offset = CALC_FBOFFSET(x, y);
125204007ebaSmrg        unsigned int size =
125304007ebaSmrg            dir == DEGREES_0 ? (len << 16) | 1 : (1 << 16) | len;
125404007ebaSmrg        GU2_WAIT_PENDING;
125504007ebaSmrg        WRITE_GP32(MGP_DST_OFFSET, offset);
125604007ebaSmrg        WRITE_GP32(MGP_WID_HEIGHT, size);
125704007ebaSmrg        WRITE_GP32(MGP_BLT_MODE, BLT_MODE);
1258f29dbc25Smrg    }
1259f29dbc25Smrg#endif
1260f29dbc25Smrg}
126104007ebaSmrg#endif                          /* GX_BRES_LINE_SUPPORT */
1262f29dbc25Smrg
1263f29dbc25Smrg#if GX_DASH_LINE_SUPPORT
1264f29dbc25Smrg/*----------------------------------------------------------------------------
1265f29dbc25Smrg * GXSetupForDashedLine
1266f29dbc25Smrg *
1267f29dbc25Smrg * Description  :SetupForDashedLine and Subsequent TwoPointLine
1268f29dbc25Smrg *               BresenhamLine provides an interface for drawing thin
1269f29dbc25Smrg *               dashed lines.
1270f29dbc25Smrg *
1271f29dbc25Smrg *    Arg        Type     Comment
1272f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
1273f29dbc25Smrg *     fg         int     foreground fill color
1274f29dbc25Smrg *     bg         int     -1 (transp) or background fill color
1275f29dbc25Smrg *    rop         int     unmapped raster op
1276f29dbc25Smrg * planemask     uint     -1 (fill) or pattern data (not enabled)
1277f29dbc25Smrg *  length        int     pattern length (bits)
1278f29dbc25Smrg * pattern     uchar*     dash pattern mask
1279f29dbc25Smrg *
1280f29dbc25Smrg * Returns              :none
1281f29dbc25Smrg *---------------------------------------------------------------------------*/
1282f29dbc25Smrgstatic void
1283f29dbc25SmrgGXSetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop,
128404007ebaSmrg                     unsigned int planemask, int length, unsigned char *pattern)
1285f29dbc25Smrg{
1286f29dbc25Smrg    int i, l, n, m;
1287f29dbc25Smrg    CARD32 pat = *pattern;
1288f29dbc25Smrg    CARD32 pat8x8[2];
1289f29dbc25Smrg
1290f29dbc25Smrg    if (length <= 0)
129104007ebaSmrg        return;
1292f29dbc25Smrg    i = l = m = 0;
1293f29dbc25Smrg    while (i < 2) {
129404007ebaSmrg        m |= pat >> l;
129504007ebaSmrg        l += length;
129604007ebaSmrg        if ((n = l - 32) >= 0) {
129704007ebaSmrg            pat8x8[i++] = m;
129804007ebaSmrg            m = pat << (length - n);
129904007ebaSmrg            l = n;
130004007ebaSmrg        }
1301f29dbc25Smrg    }
1302f29dbc25Smrg    gdln.pat[0] = pat8x8[0];
1303f29dbc25Smrg    gdln.pat[1] = pat8x8[1];
1304f29dbc25Smrg    gdln.len = length;
1305f29dbc25Smrg    gdln.fg = fg;
1306f29dbc25Smrg    gdln.bg = bg;
1307f29dbc25Smrg    rop &= 0x0F;
1308f29dbc25Smrg    gfx_set_solid_pattern(0);
1309f29dbc25Smrg    gfx_set_raster_operation(planemask == ~0U ? PDfn[rop] :
131004007ebaSmrg                             (gfx_set_solid_source(planemask), PDfn_SM[rop]));
1311f29dbc25Smrg}
1312f29dbc25Smrg
1313f29dbc25Smrg/*---------------------------------------------------------------------------
1314f29dbc25Smrg * GXSubsequentDashedBresenhamLine
1315f29dbc25Smrg *
1316f29dbc25Smrg * Description:		This function is used to render a vector using the
1317f29dbc25Smrg *                 	specified bresenham parameters.
1318f29dbc25Smrg *
1319f29dbc25Smrg * Parameters:
1320f29dbc25Smrg *		pScrni:		Screen handler pointer having screen information.
1321f29dbc25Smrg *      x1:  		Specifies the starting x position
1322f29dbc25Smrg *      y1:      	Specifies starting y possition
1323f29dbc25Smrg *      absmaj:		Specfies the Bresenman absolute major.
1324f29dbc25Smrg *		absmin:		Specfies the Bresenman absolute minor.
1325f29dbc25Smrg *		err:     	Specifies the bresenham err term.
1326f29dbc25Smrg *		len:     	Specifies the length of the vector interms of pixels.
1327f29dbc25Smrg *		octant:  	not used in this function,may be added for standard
1328f29dbc25Smrg *               	interface.
1329f29dbc25Smrg *
1330f29dbc25Smrg * Returns:			none
1331f29dbc25Smrg *
1332f29dbc25Smrg * Comments:		none
1333f29dbc25Smrg *
1334f29dbc25Smrg * Sample application uses:
1335f29dbc25Smrg *   - Window outlines on window move.
1336f29dbc25Smrg *   - x11perf: line segments (-line500).
1337f29dbc25Smrg *   - x11perf: line segments (-seg500).
1338f29dbc25Smrg *----------------------------------------------------------------------------
1339f29dbc25Smrg */
1340f29dbc25Smrgstatic void
1341f29dbc25SmrgGXSubsequentDashedBresenhamLine(ScrnInfoPtr pScrni,
134204007ebaSmrg                                int x1, int y1, int absmaj, int absmin,
134304007ebaSmrg                                int err, int len, int octant, int phase)
1344f29dbc25Smrg{
1345f29dbc25Smrg    int i, n;
1346f29dbc25Smrg    int axial, diagn;
1347f29dbc25Smrg    int trans = (gdln.bg == -1);
1348f29dbc25Smrg    unsigned long pat8x8[2];
1349f29dbc25Smrg
1350f29dbc25Smrg    //ErrorF("BLine %d, %d, %d, %d, %d, %d, %d\n" x1, y1, absmaj, absmin,
1351f29dbc25Smrg    //err, len, octant);
1352f29dbc25Smrg
1353f29dbc25Smrg    i = phase >= 32 ? (phase -= 32, 1) : 0;
1354f29dbc25Smrg    n = 32 - phase;
1355f29dbc25Smrg    pat8x8[0] =
135604007ebaSmrg        ((gdln.pat[i] >> phase) & ((1UL << n) - 1)) | (gdln.pat[1 - i] << n);
1357f29dbc25Smrg    pat8x8[1] =
135804007ebaSmrg        ((gdln.pat[1 - i] >> phase) & ((1UL << n) - 1)) | (gdln.pat[i] << n);
1359f29dbc25Smrg    axial = absmin;
1360f29dbc25Smrg    err += axial;
1361f29dbc25Smrg    diagn = absmin - absmaj;
1362f29dbc25Smrg    gfx_set_mono_pattern(gdln.bg, gdln.fg, pat8x8[0], pat8x8[1], trans);
1363f29dbc25Smrg    gfx2_set_pattern_origin(x1, y1);
1364f29dbc25Smrg    gfx2_bresenham_line(CALC_FBOFFSET(x1, y1), len, err, axial, diagn,
136504007ebaSmrg                        vmode[octant]);
1366f29dbc25Smrg}
1367f29dbc25Smrg
1368f29dbc25Smrg/*---------------------------------------------------------------------------
1369f29dbc25Smrg * GXSubsequentDashedTwoPointLine
1370f29dbc25Smrg *
1371f29dbc25Smrg * Description  :see GXSetupForDashedLine
1372f29dbc25Smrg *
1373f29dbc25Smrg *    Arg        Type     Comment
1374f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
1375f29dbc25Smrg *     x0         int     destination x start offset
1376f29dbc25Smrg *     y0         int     destination y start offset
1377f29dbc25Smrg *     x1         int     destination x end offset
1378f29dbc25Smrg *     y1         int     destination y end offset
1379f29dbc25Smrg *  flags         int     OMIT_LAST, dont draw last pixel (not used)
1380f29dbc25Smrg *  phase         int     initial pattern offset at x1,y1
1381f29dbc25Smrg *
1382f29dbc25Smrg * Returns      :none
1383f29dbc25Smrg *---------------------------------------------------------------------------*/
1384f29dbc25Smrgstatic void
1385f29dbc25SmrgGXSubsequentDashedTwoPointLine(ScrnInfoPtr pScrni, int x0, int y0,
138604007ebaSmrg                               int x1, int y1, int flags, int phase)
1387f29dbc25Smrg{
1388f29dbc25Smrg    int i, n;
1389f29dbc25Smrg    long dx, dy, dmaj, dmin, octant, bias;
1390f29dbc25Smrg    long axial, diagn, err, len, pat8x8[2];
1391f29dbc25Smrg
1392f29dbc25Smrg    //ErrorF("GXSubsequentDashedTwoPointLine() %d,%d %d,%d, %#x %d\n",
1393f29dbc25Smrg    //   x0, y0, x1, y1, flags, phase);
1394f29dbc25Smrg
1395f29dbc25Smrg    i = phase >= 32 ? (phase -= 32, 1) : 0;
1396f29dbc25Smrg    n = 32 - phase;
1397f29dbc25Smrg    pat8x8[0] =
139804007ebaSmrg        ((gdln.pat[i] >> phase) & ((1UL << n) - 1)) | (gdln.pat[1 - i] << n);
1399f29dbc25Smrg    pat8x8[1] =
140004007ebaSmrg        ((gdln.pat[1 - i] >> phase) & ((1UL << n) - 1)) | (gdln.pat[i] << n);
1401f29dbc25Smrg
1402f29dbc25Smrg    if ((dx = x1 - x0) < 0)
140304007ebaSmrg        dx = -dx;
1404f29dbc25Smrg    if ((dy = y1 - y0) < 0)
140504007ebaSmrg        dy = -dy;
1406f29dbc25Smrg    if (dy >= dx) {
140704007ebaSmrg        dmaj = dy;
140804007ebaSmrg        dmin = dx;
140904007ebaSmrg        octant = YMAJOR;
141004007ebaSmrg    }
141104007ebaSmrg    else {
141204007ebaSmrg        dmaj = dx;
141304007ebaSmrg        dmin = dy;
141404007ebaSmrg        octant = 0;
1415f29dbc25Smrg    }
1416f29dbc25Smrg    len = dmaj;
1417f29dbc25Smrg    if ((flags & OMIT_LAST) == 0)
141804007ebaSmrg        ++len;
1419f29dbc25Smrg    if (len <= 0)
142004007ebaSmrg        return;
1421f29dbc25Smrg    if (x1 < x0)
142204007ebaSmrg        octant |= XDECREASING;
1423f29dbc25Smrg    if (y1 < y0)
142404007ebaSmrg        octant |= YDECREASING;
1425f29dbc25Smrg
1426f29dbc25Smrg    axial = dmin << 1;
1427f29dbc25Smrg    bias = miGetZeroLineBias(pScrni->pScreen);
1428f29dbc25Smrg    err = axial - dmaj - ((bias >> octant) & 1);
1429f29dbc25Smrg    diagn = (dmin - dmaj) << 1;
1430f29dbc25Smrg
1431f29dbc25Smrg    gfx2_set_pattern_origin(x0, y0);
1432f29dbc25Smrg    gfx2_bresenham_line(CALC_FBOFFSET(x0, y0), len, err, axial, diagn,
143304007ebaSmrg                        vmode[octant]);
1434f29dbc25Smrg
1435f29dbc25Smrg}
143604007ebaSmrg#endif                          /* GX_DASH_LINE_SUPPORT */
1437f29dbc25Smrg
1438f29dbc25Smrg#if GX_WRITE_PIXMAP_SUPPORT
1439f29dbc25Smrgstatic void
1440f29dbc25SmrgGXWritePixmap(ScrnInfoPtr pScrni, int x, int y, int w, int h,
144104007ebaSmrg              unsigned char *src, int srcwidth, int rop, unsigned int planemask,
144204007ebaSmrg              int trans, int bpp, int depth)
1443f29dbc25Smrg{
1444f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR(pScrni);
1445f29dbc25Smrg
1446f29dbc25Smrg    //ErrorF("GXWritePixmap() %d,%d %dx%d, s%#x sp%d %#x %#x %#x %d %d\n",
1447f29dbc25Smrg    //    x, y, w, h, src, srcwidth, rop, planemask, trans, bpp, depth);
1448f29dbc25Smrg
1449f29dbc25Smrg    if (bpp == pScrni->bitsPerPixel) {
145004007ebaSmrg        rop &= 0x0F;
145104007ebaSmrg        if (rop == GXcopy && trans == -1) {
145204007ebaSmrg            gfx_wait_until_idle();
145304007ebaSmrg            geode_memory_to_screen_blt((unsigned long) src,
145404007ebaSmrg                                       (unsigned long) FBADDR(x, y), srcwidth,
145504007ebaSmrg                                       pGeode->Pitch, w, h, bpp);
145604007ebaSmrg        }
145704007ebaSmrg        else {
145804007ebaSmrg            gfx_set_solid_pattern(planemask);
145904007ebaSmrg            gfx_set_raster_operation(planemask ==
146004007ebaSmrg                                     ~0U ? SDfn[rop] : SDfn_PM[rop]);
146104007ebaSmrg            if (trans != -1)
146204007ebaSmrg                gfx_color_bitmap_to_screen_xblt(0, 0, x, y, w, h, src,
146304007ebaSmrg                                                srcwidth, trans);
146404007ebaSmrg            else
146504007ebaSmrg                gfx_color_bitmap_to_screen_blt(0, 0, x, y, w, h, src, srcwidth);
146604007ebaSmrg            SET_SYNC_FLAG(pGeode->AccelInfoRec);
146704007ebaSmrg        }
146804007ebaSmrg    }
146904007ebaSmrg    else
147004007ebaSmrg        pGeode->WritePixmap(pScrni, x, y, w, h, src, srcwidth, rop, planemask,
147104007ebaSmrg                            trans, bpp, depth);
1472f29dbc25Smrg}
147304007ebaSmrg#endif                          /* if GX_WRITE_PIXMAP_SUPPORT */
1474f29dbc25Smrg
1475f29dbc25Smrg#if XF86EXA
1476f29dbc25Smrg
1477f29dbc25Smrgstatic void
1478f29dbc25Smrgamd_gx_exa_WaitMarker(ScreenPtr pScreen, int Marker)
1479f29dbc25Smrg{
1480f29dbc25Smrg    GU2_WAIT_BUSY;
1481f29dbc25Smrg}
1482f29dbc25Smrg
1483f29dbc25Smrgstatic void
1484f29dbc25Smrgamd_gx_exa_Done(PixmapPtr p)
1485f29dbc25Smrg{
1486f29dbc25Smrg}
1487f29dbc25Smrg
1488f29dbc25Smrgstatic Bool
1489f29dbc25Smrgamd_gx_exa_UploadToScreen(PixmapPtr pDst, int x, int y, int w, int h,
149004007ebaSmrg                          char *src, int src_pitch)
1491f29dbc25Smrg{
1492f29dbc25Smrg    char *dst = pDst->devPrivate.ptr;
1493f29dbc25Smrg    int dst_pitch = exaGetPixmapPitch(pDst);
1494f29dbc25Smrg    int bpp = pDst->drawable.bitsPerPixel;
1495f29dbc25Smrg
1496f29dbc25Smrg    dst += y * dst_pitch + x * (bpp >> 3);
1497f29dbc25Smrg    GU2_WAIT_BUSY;
149804007ebaSmrg    geode_memory_to_screen_blt((unsigned long) src, (unsigned long) dst,
149904007ebaSmrg                               src_pitch, dst_pitch, w, h, bpp);
1500f29dbc25Smrg    return TRUE;
1501f29dbc25Smrg}
1502f29dbc25Smrg
1503f29dbc25Smrgstatic Bool
1504f29dbc25Smrgamd_gx_exa_DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h,
150504007ebaSmrg                              char *dst, int dst_pitch)
1506f29dbc25Smrg{
1507f29dbc25Smrg    char *src = pSrc->devPrivate.ptr;
1508f29dbc25Smrg    int src_pitch = exaGetPixmapPitch(pSrc);
1509f29dbc25Smrg    int bpp = pSrc->drawable.bitsPerPixel;
1510f29dbc25Smrg
1511f29dbc25Smrg    src += (y * src_pitch) + (x * (bpp >> 3));
1512f29dbc25Smrg    GU2_WAIT_BUSY;
151304007ebaSmrg    geode_memory_to_screen_blt((unsigned long) src, (unsigned long) dst,
151404007ebaSmrg                               src_pitch, dst_pitch, w, h, bpp);
1515f29dbc25Smrg    return TRUE;
1516f29dbc25Smrg}
1517f29dbc25Smrg
1518f29dbc25Smrg/* Solid */
1519f29dbc25Smrg
1520f29dbc25Smrgstatic Bool
1521f29dbc25Smrgamd_gx_exa_PrepareSolid(PixmapPtr pxMap, int alu, Pixel planemask, Pixel fg)
1522f29dbc25Smrg{
1523f29dbc25Smrg    int dstPitch = exaGetPixmapPitch(pxMap);
1524f29dbc25Smrg    unsigned int ROP = amd_gx_BppToRasterMode(pxMap->drawable.bitsPerPixel)
152504007ebaSmrg        | (planemask == ~0U ? SDfn[alu] : SDfn_PM[alu]);
1526f29dbc25Smrg
1527f29dbc25Smrg    //  FIXME: this should go away -- workaround for the blockparty icon corruption
1528f29dbc25Smrg    //if (pxMap->drawable.bitsPerPixel == 32)
1529f29dbc25Smrg    //  return FALSE;
1530f29dbc25Smrg
1531f29dbc25Smrg    BLT_MODE = ((ROP ^ (ROP >> 2)) & 0x33) == 0 ? MGP_BM_SRC_MONO : 0;
1532f29dbc25Smrg    if (((ROP ^ (ROP >> 1)) & 0x55) != 0)
153304007ebaSmrg        BLT_MODE |= MGP_BM_DST_REQ;
1534f29dbc25Smrg    //ErrorF("amd_gx_exa_PrepareSolid(%#x,%#x,%#x - ROP=%x,BLT_MODE=%x)\n", alu, planemask, fg, ROP, BLT_MODE);
1535f29dbc25Smrg    GU2_WAIT_PENDING;
1536f29dbc25Smrg    WRITE_GP32(MGP_RASTER_MODE, ROP);
1537f29dbc25Smrg    WRITE_GP32(MGP_PAT_COLOR_0, planemask);
1538f29dbc25Smrg    WRITE_GP32(MGP_SRC_COLOR_FG, fg);
1539f29dbc25Smrg    WRITE_GP32(MGP_STRIDE, dstPitch);
1540f29dbc25Smrg    return TRUE;
1541f29dbc25Smrg}
1542f29dbc25Smrg
1543f29dbc25Smrgstatic void
1544f29dbc25Smrgamd_gx_exa_Solid(PixmapPtr pxMap, int x1, int y1, int x2, int y2)
1545f29dbc25Smrg{
1546f29dbc25Smrg    int bpp = (pxMap->drawable.bitsPerPixel + 7) / 8;
1547f29dbc25Smrg    int pitch = exaGetPixmapPitch(pxMap);
1548f29dbc25Smrg    unsigned int offset = exaGetPixmapOffset(pxMap) + pitch * y1 + bpp * x1;
1549f29dbc25Smrg    unsigned int size = ((x2 - x1) << 16) | (y2 - y1);
1550f29dbc25Smrg
1551f29dbc25Smrg    //ErrorF("amd_gx_exa_Solid() at %d,%d %d,%d - offset=%d, bpp=%d\n", x1, y1, x2, y2, offset, bpp);
1552f29dbc25Smrg
1553f29dbc25Smrg    GU2_WAIT_PENDING;
1554f29dbc25Smrg    WRITE_GP32(MGP_DST_OFFSET, offset);
1555f29dbc25Smrg    WRITE_GP32(MGP_WID_HEIGHT, size);
1556f29dbc25Smrg    WRITE_GP32(MGP_BLT_MODE, BLT_MODE);
1557f29dbc25Smrg}
1558f29dbc25Smrg
1559f29dbc25Smrg/* Copy */
1560f29dbc25Smrg
1561f29dbc25Smrgstatic Bool
1562f29dbc25Smrgamd_gx_exa_PrepareCopy(PixmapPtr pxSrc, PixmapPtr pxDst, int dx, int dy,
156304007ebaSmrg                       int alu, Pixel planemask)
1564f29dbc25Smrg{
1565f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst);
1566f29dbc25Smrg    int dstPitch = exaGetPixmapPitch(pxDst);
1567f29dbc25Smrg    unsigned int ROP;
1568f29dbc25Smrg
1569f29dbc25Smrg    /* Punt if the color formats aren't the same */
1570f29dbc25Smrg
1571f29dbc25Smrg    if (pxSrc->drawable.bitsPerPixel != pxDst->drawable.bitsPerPixel)
157204007ebaSmrg        return FALSE;
1573f29dbc25Smrg
1574f29dbc25Smrg    //ErrorF("amd_gx_exa_PrepareCopy() dx%d dy%d alu %#x %#x\n",
1575f29dbc25Smrg    //  dx, dy, alu, planemask);
1576f29dbc25Smrg
1577f29dbc25Smrg    pGeode->cpySrcOffset = exaGetPixmapOffset(pxSrc);
1578f29dbc25Smrg    pGeode->cpySrcPitch = exaGetPixmapPitch(pxSrc);
1579f29dbc25Smrg    pGeode->cpySrcBpp = (pxSrc->drawable.bitsPerPixel + 7) / 8;
1580f29dbc25Smrg    pGeode->cpyDx = dx;
1581f29dbc25Smrg    pGeode->cpyDy = dy;
1582f29dbc25Smrg    ROP = amd_gx_BppToRasterMode(pxSrc->drawable.bitsPerPixel) |
158304007ebaSmrg        (planemask == ~0U ? SDfn[alu] : SDfn_PM[alu]);
1584f29dbc25Smrg
1585f29dbc25Smrg    BLT_MODE = ((ROP ^ (ROP >> 1)) & 0x55) != 0 ?
158604007ebaSmrg        MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
1587f29dbc25Smrg    GU2_WAIT_PENDING;
1588f29dbc25Smrg    WRITE_GP32(MGP_RASTER_MODE, ROP);
1589f29dbc25Smrg    WRITE_GP32(MGP_PAT_COLOR_0, planemask);
1590f29dbc25Smrg    WRITE_GP32(MGP_SRC_COLOR_FG, ~0);
1591f29dbc25Smrg    WRITE_GP32(MGP_SRC_COLOR_BG, ~0);
1592f29dbc25Smrg    WRITE_GP32(MGP_STRIDE, (pGeode->cpySrcPitch << 16) | dstPitch);
1593f29dbc25Smrg    return TRUE;
1594f29dbc25Smrg}
1595f29dbc25Smrg
1596f29dbc25Smrgstatic void
1597f29dbc25Smrgamd_gx_exa_Copy(PixmapPtr pxDst, int srcX, int srcY, int dstX, int dstY,
159804007ebaSmrg                int w, int h)
1599f29dbc25Smrg{
1600f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst);
1601f29dbc25Smrg    int dstBpp = (pxDst->drawable.bitsPerPixel + 7) / 8;
1602f29dbc25Smrg    int dstPitch = exaGetPixmapPitch(pxDst);
1603f29dbc25Smrg    unsigned int srcOffset =
160404007ebaSmrg        pGeode->cpySrcOffset + (pGeode->cpySrcPitch * srcY) +
160504007ebaSmrg        (pGeode->cpySrcBpp * srcX);
1606f29dbc25Smrg    unsigned int dstOffset =
160704007ebaSmrg        exaGetPixmapOffset(pxDst) + (dstPitch * dstY) + (dstBpp * dstX);
1608f29dbc25Smrg    unsigned int size = (w << 16) | h;
1609f29dbc25Smrg    unsigned int blt_mode = BLT_MODE;
1610f29dbc25Smrg
1611f29dbc25Smrg    //ErrorF("amd_gx_exa_Copy() from %d,%d to %d,%d %dx%d\n", srcX, srcY,
1612f29dbc25Smrg    //   dstX, dstY, w, h);
1613f29dbc25Smrg
1614f29dbc25Smrg    if (pGeode->cpyDx < 0) {
161504007ebaSmrg        srcOffset += w * pGeode->cpySrcBpp - 1;
161604007ebaSmrg        dstOffset += w * dstBpp - 1;
161704007ebaSmrg        blt_mode |= MGP_BM_NEG_XDIR;
1618f29dbc25Smrg    }
1619f29dbc25Smrg    if (pGeode->cpyDy < 0) {
162004007ebaSmrg        srcOffset += (h - 1) * pGeode->cpySrcPitch;
162104007ebaSmrg        dstOffset += (h - 1) * dstPitch;
162204007ebaSmrg        blt_mode |= MGP_BM_NEG_YDIR;
1623f29dbc25Smrg    }
1624f29dbc25Smrg    GU2_WAIT_PENDING;
1625f29dbc25Smrg    WRITE_GP32(MGP_SRC_OFFSET, srcOffset);
1626f29dbc25Smrg    WRITE_GP32(MGP_DST_OFFSET, dstOffset);
1627f29dbc25Smrg    WRITE_GP32(MGP_WID_HEIGHT, size);
1628f29dbc25Smrg    WRITE_GP16(MGP_BLT_MODE, blt_mode);
1629f29dbc25Smrg}
1630f29dbc25Smrg
1631f29dbc25Smrg/* A=SRC, B=DST */
1632f29dbc25Smrg#define SRC_DST 0
1633f29dbc25Smrg/* B=SRC, A=DST */
1634f29dbc25Smrg#define DST_SRC MGP_RM_DEST_FROM_CHAN_A
1635f29dbc25Smrg/* A*alpha + B*0         */
1636f29dbc25Smrg#define Aa_B0   MGP_RM_ALPHA_TIMES_A
1637f29dbc25Smrg/* A*0     + B*(1-alpha) */
1638f29dbc25Smrg#define A0_B1a  MGP_RM_BETA_TIMES_B
1639f29dbc25Smrg/* A*1     + B*(1-alpha) */
1640f29dbc25Smrg#define A1_B1a  MGP_RM_A_PLUS_BETA_B
1641f29dbc25Smrg/* A*alpha + B*(1-alpha) */
1642f29dbc25Smrg#define Aa_B1a  MGP_RM_ALPHA_A_PLUS_BETA_B
1643f29dbc25Smrg/* alpha from A */
1644f29dbc25Smrg#define a_A MGP_RM_SELECT_ALPHA_A
1645f29dbc25Smrg/* alpha from B */
1646f29dbc25Smrg#define a_B MGP_RM_SELECT_ALPHA_B
1647f29dbc25Smrg/* alpha from const */
1648f29dbc25Smrg#define a_C MGP_RM_SELECT_ALPHA_R
1649f29dbc25Smrg/* alpha = 1 */
1650f29dbc25Smrg#define a_1 MGP_RM_SELECT_ALPHA_1
1651f29dbc25Smrg
1652f29dbc25Smrg#define MGP_RM_ALPHA_TO_ARGB (MGP_RM_ALPHA_TO_ALPHA | MGP_RM_ALPHA_TO_RGB)
165304007ebaSmrg#define gxPictOpMAX PictOpAdd   /* highest accelerated op */
1654f29dbc25Smrg
1655f29dbc25Smrgunsigned int amd_gx_exa_alpha_ops[] =
1656f29dbc25Smrg/*    A   B      OP     AS           const = 0 */
1657f29dbc25Smrg{
165804007ebaSmrg    (SRC_DST | Aa_B0 | a_C), 0, /* clear    (src*0) */
165904007ebaSmrg    (SRC_DST | Aa_B0 | a_1), 0, /* src      (src*1) */
166004007ebaSmrg    (DST_SRC | Aa_B0 | a_1), 0, /* dst      (dst*1) */
166104007ebaSmrg    (SRC_DST | A1_B1a | a_A), 0,        /* src-over (src*1 + dst(1-A)) */
166204007ebaSmrg    (DST_SRC | A1_B1a | a_A), 0,        /* dst-over (dst*1 + src(1-B)) */
166304007ebaSmrg    (SRC_DST | Aa_B0 | a_B), 0, /* src-in   (src*B) */
166404007ebaSmrg    (DST_SRC | Aa_B0 | a_B), 0, /* dst-in   (dst*A) */
166504007ebaSmrg    (DST_SRC | A0_B1a | a_A), 0,        /* src-out  (src*(1-B)) */
166604007ebaSmrg    (SRC_DST | A0_B1a | a_A), 0,        /* dst-out  (dst*(1-A)) */
1667f29dbc25Smrg/* pass1 (SRC=dst DST=scr=src), pass2 (SRC=src, DST=dst) */
166804007ebaSmrg    (DST_SRC | Aa_B0 | a_B),    /* srcatop  (src*B) */
166904007ebaSmrg    (SRC_DST | A0_B1a | a_A),   /*                  + (dst(1-A)) */
167004007ebaSmrg    (SRC_DST | Aa_B0 | a_B),    /* dstatop  (dst*A) */
167104007ebaSmrg    (DST_SRC | A0_B1a | a_A),   /*                  + (src(1-B) */
167204007ebaSmrg    (SRC_DST | A0_B1a | a_A),   /* xor      (src*(1-B) */
167304007ebaSmrg    (SRC_DST | A0_B1a | a_A),   /*                  + (dst(1-A) */
167404007ebaSmrg    (SRC_DST | A1_B1a | a_C), 0,        /* add      (src*1 + dst*1) */
1675f29dbc25Smrg};
1676f29dbc25Smrg
167704007ebaSmrgtypedef struct {
1678f29dbc25Smrg    int exa_fmt;
1679f29dbc25Smrg    int bpp;
1680f29dbc25Smrg    int gx_fmt;
1681f29dbc25Smrg    int alpha_bits;
1682f29dbc25Smrg} amd_gx_exa_fmt_t;
1683f29dbc25Smrg
1684f29dbc25Smrgamd_gx_exa_fmt_t amd_gx_exa_fmts[] = {
1685f29dbc25Smrg    {PICT_a8r8g8b8, 32, MGP_RM_BPPFMT_8888, 8},
1686f29dbc25Smrg    {PICT_x8r8g8b8, 32, MGP_RM_BPPFMT_8888, 0},
1687f29dbc25Smrg    {PICT_a4r4g4b4, 16, MGP_RM_BPPFMT_4444, 4},
1688f29dbc25Smrg    {PICT_a1r5g5b5, 16, MGP_RM_BPPFMT_1555, 1},
1689f29dbc25Smrg    {PICT_r5g6b5, 16, MGP_RM_BPPFMT_565, 0},
1690f29dbc25Smrg    {PICT_r3g3b2, 8, MGP_RM_BPPFMT_332, 0},
1691f29dbc25Smrg};
1692f29dbc25Smrg
1693f29dbc25Smrgstatic amd_gx_exa_fmt_t *
1694f29dbc25Smrgamd_gx_exa_check_format(PicturePtr p)
1695f29dbc25Smrg{
1696f29dbc25Smrg    int i;
1697f29dbc25Smrg    int bpp = p->pDrawable ? p->pDrawable->bitsPerPixel : 0;
1698f29dbc25Smrg    amd_gx_exa_fmt_t *fp = &amd_gx_exa_fmts[0];
1699f29dbc25Smrg
1700f29dbc25Smrg    for (i = sizeof(amd_gx_exa_fmts) / sizeof(amd_gx_exa_fmts[0]); --i >= 0;
170104007ebaSmrg         ++fp) {
170204007ebaSmrg        if (fp->bpp < bpp)
170304007ebaSmrg            return NULL;
170404007ebaSmrg        if (fp->bpp != bpp)
170504007ebaSmrg            continue;
170604007ebaSmrg        if (fp->exa_fmt == p->format)
170704007ebaSmrg            break;
1708f29dbc25Smrg    }
1709f29dbc25Smrg    return i < 0 ? NULL : fp;
1710f29dbc25Smrg}
1711f29dbc25Smrg
1712f29dbc25Smrg/* Composite */
1713f29dbc25Smrg
1714f29dbc25Smrgstatic Bool
1715f29dbc25Smrgamd_gx_exa_CheckComposite(int op, PicturePtr pSrc, PicturePtr pMsk,
171604007ebaSmrg                          PicturePtr pDst)
1717f29dbc25Smrg{
1718f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR_FROM_PICTURE(pDst);
1719f29dbc25Smrg
1720f29dbc25Smrg    if (op > gxPictOpMAX)
172104007ebaSmrg        return FALSE;
1722f29dbc25Smrg    if (pMsk)
172304007ebaSmrg        return FALSE;
1724f29dbc25Smrg    if (usesPasses(op) && pGeode->exaBfrSz == 0)
172504007ebaSmrg        return FALSE;
1726f29dbc25Smrg    if (pSrc->filter != PictFilterNearest &&
172704007ebaSmrg        pSrc->filter != PictFilterFast &&
172804007ebaSmrg        pSrc->filter != PictFilterGood && pSrc->filter != PictFilterBest)
172904007ebaSmrg        return FALSE;
1730f29dbc25Smrg    if (pSrc->repeat)
173104007ebaSmrg        return FALSE;
1732f29dbc25Smrg    if (pSrc->transform)
173304007ebaSmrg        return FALSE;
1734f29dbc25Smrg    return TRUE;
1735f29dbc25Smrg}
1736f29dbc25Smrg
1737f29dbc25Smrgstatic Bool
1738f29dbc25Smrgamd_gx_exa_PrepareComposite(int op, PicturePtr pSrc, PicturePtr pMsk,
173904007ebaSmrg                            PicturePtr pDst, PixmapPtr pxSrc, PixmapPtr pxMsk,
174004007ebaSmrg                            PixmapPtr pxDst)
1741f29dbc25Smrg{
1742f29dbc25Smrg    int srcPitch;
1743f29dbc25Smrg
1744f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst);
1745f29dbc25Smrg    amd_gx_exa_fmt_t *sfp, *dfp;
1746f29dbc25Smrg
1747f29dbc25Smrg    //ErrorF("amd_gx_exa_PrepareComposite()\n");
1748f29dbc25Smrg
1749f29dbc25Smrg    if ((sfp = amd_gx_exa_check_format(pSrc)) == NULL)
175004007ebaSmrg        return FALSE;
1751f29dbc25Smrg    if (sfp->alpha_bits == 0 && usesSrcAlpha(op))
175204007ebaSmrg        return FALSE;
1753f29dbc25Smrg    if ((dfp = amd_gx_exa_check_format(pDst)) == NULL)
175404007ebaSmrg        return FALSE;
1755f29dbc25Smrg    if (dfp->alpha_bits == 0 && usesDstAlpha(op))
175604007ebaSmrg        return FALSE;
1757f29dbc25Smrg    if (sfp->gx_fmt != dfp->gx_fmt)
175804007ebaSmrg        return FALSE;
1759f29dbc25Smrg    srcPitch = exaGetPixmapPitch(pxSrc);
1760f29dbc25Smrg    if (usesPasses(op) && srcPitch > pGeode->exaBfrSz)
176104007ebaSmrg        return FALSE;
1762f29dbc25Smrg    pGeode->cmpSrcPitch = srcPitch;
1763f29dbc25Smrg    pGeode->cmpOp = op;
1764f29dbc25Smrg    pGeode->cmpSrcOffset = exaGetPixmapOffset(pxSrc);
1765f29dbc25Smrg    pGeode->cmpSrcBpp = (pxSrc->drawable.bitsPerPixel + 7) / 8;
1766f29dbc25Smrg    pGeode->cmpSrcFmt = sfp->gx_fmt;
1767f29dbc25Smrg    pGeode->cmpDstFmt = dfp->gx_fmt | (dfp->alpha_bits == 0 ?
176804007ebaSmrg                                       MGP_RM_ALPHA_TO_RGB :
176904007ebaSmrg                                       MGP_RM_ALPHA_TO_ARGB);
1770f29dbc25Smrg    return TRUE;
1771f29dbc25Smrg}
1772f29dbc25Smrg
1773f29dbc25Smrgstatic void
1774f29dbc25Smrgamd_gx_exa_Composite(PixmapPtr pxDst, int srcX, int srcY, int maskX,
177504007ebaSmrg                     int maskY, int dstX, int dstY, int width, int height)
1776f29dbc25Smrg{
1777f29dbc25Smrg    int op, current_line, max_lines, lines, pass, scratchPitch;
1778f29dbc25Smrg    unsigned int srcOffset, srcOfs = 0, srcPitch, srcPch = 0, srcBpp;
1779f29dbc25Smrg    unsigned int dstOffset, dstOfs = 0, dstPitch, dstPch = 0, dstBpp;
1780f29dbc25Smrg    unsigned int sizes, strides, blt_mode = 0, rop = 0;
1781f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst);
1782f29dbc25Smrg
1783f29dbc25Smrg    //ErrorF("amd_gx_exa_Composite() from %d,%d to %d,%d %dx%d\n",
1784f29dbc25Smrg    //    srcX, srcY, dstX, dstY, width, height);
1785f29dbc25Smrg
1786f29dbc25Smrg    op = pGeode->cmpOp;
1787f29dbc25Smrg    if (usesPasses(op)) {
178804007ebaSmrg        int cacheLineSz = 32;
178904007ebaSmrg        int cachelines =
179004007ebaSmrg            (width * pGeode->cmpSrcBpp + cacheLineSz - 1) / cacheLineSz;
179104007ebaSmrg        scratchPitch = cachelines * cacheLineSz;
179204007ebaSmrg        if (scratchPitch > pGeode->cmpSrcPitch)
179304007ebaSmrg            scratchPitch = pGeode->cmpSrcPitch;
179404007ebaSmrg        max_lines = pGeode->exaBfrSz / scratchPitch;
179504007ebaSmrg    }
179604007ebaSmrg    else {
179704007ebaSmrg        scratchPitch = 0;
179804007ebaSmrg        max_lines = height;
1799f29dbc25Smrg    }
1800f29dbc25Smrg
1801f29dbc25Smrg    dstBpp = (pxDst->drawable.bitsPerPixel + 7) / 8;
1802f29dbc25Smrg    dstPitch = exaGetPixmapPitch(pxDst);
1803f29dbc25Smrg    dstOffset = exaGetPixmapOffset(pxDst) + dstPitch * dstY + dstBpp * dstX;
1804f29dbc25Smrg    srcBpp = pGeode->cmpSrcBpp;
1805f29dbc25Smrg    srcPitch = pGeode->cmpSrcPitch;
1806f29dbc25Smrg    srcOffset = pGeode->cmpSrcOffset + srcPitch * srcY + srcBpp * srcX;
1807f29dbc25Smrg
1808f29dbc25Smrg    current_line = pass = 0;
1809f29dbc25Smrg    while (current_line < height) {
181004007ebaSmrg        if (usesPasses(op)) {
181104007ebaSmrg            lines = height - current_line;
181204007ebaSmrg            if (lines > max_lines)
181304007ebaSmrg                lines = max_lines;
181404007ebaSmrg            switch (pass) {
181504007ebaSmrg            case 0:            /* copy src to scratch */
181604007ebaSmrg                srcPch = srcPitch;
181704007ebaSmrg                srcOfs = srcOffset + current_line * srcPch;
181804007ebaSmrg                dstPch = scratchPitch;
181904007ebaSmrg                dstOfs = pGeode->exaBfrOffset;
182004007ebaSmrg                rop = pGeode->cmpSrcFmt | MGP_RM_ALPHA_TO_ARGB;
182104007ebaSmrg                rop |= amd_gx_exa_alpha_ops[PictOpSrc * 2];
182204007ebaSmrg                blt_mode = usesChanB0(PictOpSrc) ?
182304007ebaSmrg                    MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
182404007ebaSmrg                ++pass;
182504007ebaSmrg                break;
182604007ebaSmrg            case 1:            /* pass1 */
182704007ebaSmrg                srcPch = dstPitch;
182804007ebaSmrg                srcOfs = dstOffset + current_line * srcPch;
182904007ebaSmrg                dstPch = scratchPitch;
183004007ebaSmrg                dstOfs = pGeode->exaBfrOffset;
183104007ebaSmrg                rop = pGeode->cmpSrcFmt | MGP_RM_ALPHA_TO_ARGB;
183204007ebaSmrg                rop |= amd_gx_exa_alpha_ops[op * 2];
183304007ebaSmrg                blt_mode = usesChanB1(op) ?
183404007ebaSmrg                    MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
183504007ebaSmrg                ++pass;
183604007ebaSmrg                break;
183704007ebaSmrg            case 2:            /* pass2 */
183804007ebaSmrg                srcPch = srcPitch;
183904007ebaSmrg                srcOfs = srcOffset + current_line * srcPch;
184004007ebaSmrg                dstPch = dstPitch;
184104007ebaSmrg                dstOfs = dstOffset + current_line * dstPch;
184204007ebaSmrg                rop = pGeode->cmpSrcFmt | MGP_RM_ALPHA_TO_ARGB;
184304007ebaSmrg                rop |= amd_gx_exa_alpha_ops[op * 2 + 1];
184404007ebaSmrg                blt_mode = usesChanB2(op) ?
184504007ebaSmrg                    MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
184604007ebaSmrg                ++pass;
184704007ebaSmrg                break;
184804007ebaSmrg            case 3:            /* add */
184904007ebaSmrg                srcPch = scratchPitch;
185004007ebaSmrg                srcOfs = pGeode->exaBfrOffset;
185104007ebaSmrg                dstPch = dstPitch;
185204007ebaSmrg                dstOfs = dstOffset + current_line * dstPch;
185304007ebaSmrg                rop = pGeode->cmpDstFmt;
185404007ebaSmrg                rop |= amd_gx_exa_alpha_ops[PictOpAdd * 2];
185504007ebaSmrg                blt_mode = usesChanB0(PictOpAdd) ?
185604007ebaSmrg                    MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
185704007ebaSmrg                current_line += lines;
185804007ebaSmrg                pass = 0;
185904007ebaSmrg                break;
186004007ebaSmrg            }
186104007ebaSmrg            strides = (srcPch << 16) | dstPch;
186204007ebaSmrg        }
186304007ebaSmrg        else {                  /* not multi pass */
186404007ebaSmrg            srcOfs = srcOffset;
186504007ebaSmrg            dstOfs = dstOffset;
186604007ebaSmrg            current_line = lines = height;
186704007ebaSmrg            strides = (srcPitch << 16) | dstPitch;
186804007ebaSmrg            rop = pGeode->cmpDstFmt | amd_gx_exa_alpha_ops[op * 2];
186904007ebaSmrg            blt_mode = usesChanB0(op) ?
187004007ebaSmrg                MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
187104007ebaSmrg        }
187204007ebaSmrg        sizes = (width << 16) | lines;
187304007ebaSmrg        if (srcOfs < dstOfs) {
187404007ebaSmrg            srcOfs += (lines - 1) * srcPitch + width * srcBpp - 1;
187504007ebaSmrg            dstOfs += (lines - 1) * dstPitch + width * dstBpp - 1;
187604007ebaSmrg            blt_mode |= MGP_BM_NEG_XDIR | MGP_BM_NEG_YDIR;
187704007ebaSmrg        }
187804007ebaSmrg        GU2_WAIT_PENDING;
187904007ebaSmrg        WRITE_GP32(MGP_RASTER_MODE, rop);
188004007ebaSmrg        WRITE_GP32(MGP_SRC_OFFSET, srcOfs);
188104007ebaSmrg        WRITE_GP32(MGP_DST_OFFSET, dstOfs);
188204007ebaSmrg        WRITE_GP32(MGP_WID_HEIGHT, sizes);
188304007ebaSmrg        WRITE_GP32(MGP_STRIDE, strides);
188404007ebaSmrg        WRITE_GP16(MGP_BLT_MODE, blt_mode);
1885f29dbc25Smrg    }
1886f29dbc25Smrg}
188704007ebaSmrg#endif                          /* #if XF86EXA */
1888f29dbc25Smrg
1889f29dbc25Smrg/*----------------------------------------------------------------------------
1890f29dbc25Smrg * GXAccelInit.
1891f29dbc25Smrg *
1892f29dbc25Smrg * Description:	This function sets up the supported acceleration routines and
1893f29dbc25Smrg *              appropriate flags.
1894f29dbc25Smrg *
1895f29dbc25Smrg * Parameters:
1896f29dbc25Smrg *      pScrn:	Screeen pointer structure.
1897f29dbc25Smrg *
1898f29dbc25Smrg * Returns:		TRUE on success and FALSE on Failure
1899f29dbc25Smrg *
1900f29dbc25Smrg * Comments:	This function is called in GXScreenInit in
1901f29dbc25Smrg *              geode_driver.c to set  * the acceleration.
1902f29dbc25Smrg *----------------------------------------------------------------------------
1903f29dbc25Smrg */
1904f29dbc25SmrgBool
1905f29dbc25SmrgGXAccelInit(ScreenPtr pScrn)
1906f29dbc25Smrg{
190704007ebaSmrg    ScrnInfoPtr pScrni = xf86ScreenToScrn(pScrn);
1908f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR(pScrni);
1909f29dbc25Smrg
1910f29dbc25Smrg#if XF86EXA
1911f29dbc25Smrg    ExaDriverPtr pExa = pGeode->pExa;
1912f29dbc25Smrg#endif
1913f29dbc25Smrg
1914f29dbc25Smrg    gu2_xshift = pScrni->bitsPerPixel >> 4;
1915f29dbc25Smrg
1916f29dbc25Smrg    /* XXX - fixme - this will change - we'll need to update it */
1917f29dbc25Smrg
1918f29dbc25Smrg    gu2_pitch = pGeode->Pitch;
1919f29dbc25Smrg
1920f29dbc25Smrg    switch (pGeode->Pitch) {
1921f29dbc25Smrg    case 1024:
192204007ebaSmrg        gu2_yshift = 10;
192304007ebaSmrg        break;
1924f29dbc25Smrg    case 2048:
192504007ebaSmrg        gu2_yshift = 11;
192604007ebaSmrg        break;
1927f29dbc25Smrg    case 4096:
192804007ebaSmrg        gu2_yshift = 12;
192904007ebaSmrg        break;
1930f29dbc25Smrg    default:
193104007ebaSmrg        gu2_yshift = 13;
193204007ebaSmrg        break;
1933f29dbc25Smrg    }
1934f29dbc25Smrg
1935f29dbc25Smrg#ifdef OPT_ACCEL
1936f29dbc25Smrg    ACCEL_STRIDE = (pGeode->Pitch << 16) | pGeode->Pitch;
1937f29dbc25Smrg    BPP = amd_gx_BppToRasterMode(pScrni->bitsPerPixel);
1938f29dbc25Smrg#endif
1939f29dbc25Smrg
1940f29dbc25Smrg#if XF86EXA
1941f29dbc25Smrg    if (pExa && pGeode->useEXA) {
194204007ebaSmrg        pExa->exa_major = EXA_VERSION_MAJOR;
194304007ebaSmrg        pExa->exa_minor = EXA_VERSION_MINOR;
194404007ebaSmrg
194504007ebaSmrg        /* Sync */
194604007ebaSmrg        pExa->WaitMarker = amd_gx_exa_WaitMarker;
194704007ebaSmrg        /* UploadToScreen */
194804007ebaSmrg        pExa->UploadToScreen = amd_gx_exa_UploadToScreen;
194904007ebaSmrg        pExa->DownloadFromScreen = amd_gx_exa_DownloadFromScreen;
195004007ebaSmrg
195104007ebaSmrg        /* Solid fill */
195204007ebaSmrg        pExa->PrepareSolid = amd_gx_exa_PrepareSolid;
195304007ebaSmrg        pExa->Solid = amd_gx_exa_Solid;
195404007ebaSmrg        pExa->DoneSolid = amd_gx_exa_Done;
195504007ebaSmrg
195604007ebaSmrg        /* Copy */
195704007ebaSmrg        pExa->PrepareCopy = amd_gx_exa_PrepareCopy;
195804007ebaSmrg        pExa->Copy = amd_gx_exa_Copy;
195904007ebaSmrg        pExa->DoneCopy = amd_gx_exa_Done;
196004007ebaSmrg
196104007ebaSmrg        /* Composite */
196204007ebaSmrg        pExa->CheckComposite = amd_gx_exa_CheckComposite;
196304007ebaSmrg        pExa->PrepareComposite = amd_gx_exa_PrepareComposite;
196404007ebaSmrg        pExa->Composite = amd_gx_exa_Composite;
196504007ebaSmrg        pExa->DoneComposite = amd_gx_exa_Done;
196604007ebaSmrg
196704007ebaSmrg        return exaDriverInit(pScrn, pGeode->pExa);
1968f29dbc25Smrg    }
1969f29dbc25Smrg#endif
1970f29dbc25Smrg
197104007ebaSmrg#if XF86XAA
197204007ebaSmrg
1973f29dbc25Smrg    /* Getting the pointer for acceleration Inforecord */
1974f29dbc25Smrg    pGeode->AccelInfoRec = localRecPtr = XAACreateInfoRec();
1975f29dbc25Smrg    if (!pGeode->AccelInfoRec)
197604007ebaSmrg        return FALSE;
1977f29dbc25Smrg
1978f29dbc25Smrg    /* SET ACCELERATION FLAGS */
197904007ebaSmrg    localRecPtr->Flags = PIXMAP_CACHE | OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER;
1980f29dbc25Smrg
1981f29dbc25Smrg    /* HOOK SYNCRONIZARION ROUTINE */
1982f29dbc25Smrg    localRecPtr->Sync = GXAccelSync;
1983f29dbc25Smrg
1984f29dbc25Smrg#if GX_FILL_RECT_SUPPORT
1985f29dbc25Smrg    /* HOOK FILLED RECTANGLES */
1986f29dbc25Smrg    HOOK(SetupForSolidFill);
1987f29dbc25Smrg    HOOK(SubsequentSolidFillRect);
1988f29dbc25Smrg    localRecPtr->SolidFillFlags = 0;
1989f29dbc25Smrg#endif
1990f29dbc25Smrg
1991f29dbc25Smrg#if GX_MONO_8X8_PAT_SUPPORT
1992f29dbc25Smrg    /* Color expansion */
1993f29dbc25Smrg    HOOK(SetupForMono8x8PatternFill);
1994f29dbc25Smrg    HOOK(SubsequentMono8x8PatternFillRect);
1995f29dbc25Smrg/*         BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD | NO_TRANSPARENCY | */
1996f29dbc25Smrg    localRecPtr->Mono8x8PatternFillFlags = BIT_ORDER_IN_BYTE_MSBFIRST |
199704007ebaSmrg        HARDWARE_PATTERN_PROGRAMMED_BITS | HARDWARE_PATTERN_SCREEN_ORIGIN;
1998f29dbc25Smrg#endif
1999f29dbc25Smrg
2000f29dbc25Smrg#if GX_CLREXP_8X8_PAT_SUPPORT
2001f29dbc25Smrg    /* Color expansion */
2002f29dbc25Smrg    HOOK(SetupForColor8x8PatternFill);
2003f29dbc25Smrg    HOOK(SubsequentColor8x8PatternFillRect);
2004f29dbc25Smrg/*         BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD | NO_TRANSPARENCY | */
2005f29dbc25Smrg    localRecPtr->Color8x8PatternFillFlags =
200604007ebaSmrg        BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD |
200704007ebaSmrg        HARDWARE_PATTERN_PROGRAMMED_BITS | HARDWARE_PATTERN_PROGRAMMED_ORIGIN;
2008f29dbc25Smrg#endif
2009f29dbc25Smrg
2010f29dbc25Smrg#if GX_SCR2SCRCPY_SUPPORT
2011f29dbc25Smrg    /* HOOK SCREEN TO SCREEN COPIES
2012f29dbc25Smrg     * Set flag to only allow copy if transparency is enabled.
2013f29dbc25Smrg     */
2014f29dbc25Smrg    HOOK(SetupForScreenToScreenCopy);
2015f29dbc25Smrg    HOOK(SubsequentScreenToScreenCopy);
2016f29dbc25Smrg    localRecPtr->ScreenToScreenCopyFlags =
201704007ebaSmrg        BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD;
2018f29dbc25Smrg#endif
2019f29dbc25Smrg
2020f29dbc25Smrg#if GX_BRES_LINE_SUPPORT
2021f29dbc25Smrg    /* HOOK BRESENHAM SOLID LINES */
2022f29dbc25Smrg    localRecPtr->SolidLineFlags = NO_PLANEMASK;
2023f29dbc25Smrg    HOOK(SetupForSolidLine);
2024f29dbc25Smrg    HOOK(SubsequentSolidBresenhamLine);
2025f29dbc25Smrg    HOOK(SubsequentSolidHorVertLine);
2026f29dbc25Smrg    HOOK(SubsequentSolidTwoPointLine);
2027f29dbc25Smrg    localRecPtr->SolidBresenhamLineErrorTermBits = 15;
2028f29dbc25Smrg#endif
2029f29dbc25Smrg
2030f29dbc25Smrg#if GX_DASH_LINE_SUPPORT
2031f29dbc25Smrg    /* HOOK BRESENHAM DASHED LINES */
2032f29dbc25Smrg    HOOK(SetupForDashedLine);
2033f29dbc25Smrg    HOOK(SubsequentDashedBresenhamLine);
2034f29dbc25Smrg    HOOK(SubsequentDashedTwoPointLine);
2035f29dbc25Smrg    localRecPtr->DashedBresenhamLineErrorTermBits = 15;
2036f29dbc25Smrg    localRecPtr->DashPatternMaxLength = 64;
203704007ebaSmrg    localRecPtr->DashedLineFlags = NO_PLANEMASK |       /* TRANSPARENCY_ONLY | */
203804007ebaSmrg        LINE_PATTERN_POWER_OF_2_ONLY | LINE_PATTERN_MSBFIRST_MSBJUSTIFIED;
2039f29dbc25Smrg#endif
2040f29dbc25Smrg
2041f29dbc25Smrg#if GX_SCR2SCREXP_SUPPORT
2042f29dbc25Smrg    /* Color expansion */
2043f29dbc25Smrg    HOOK(SetupForScreenToScreenColorExpandFill);
2044f29dbc25Smrg    HOOK(SubsequentScreenToScreenColorExpandFill);
2045f29dbc25Smrg    localRecPtr->ScreenToScreenColorExpandFillFlags =
204604007ebaSmrg        BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD | NO_TRANSPARENCY;
2047f29dbc25Smrg#endif
2048f29dbc25Smrg
2049f29dbc25Smrg    if (pGeode->AccelImageWriteBuffers) {
2050f29dbc25Smrg#if GX_SCANLINE_SUPPORT
205104007ebaSmrg        localRecPtr->ScanlineImageWriteBuffers = pGeode->AccelImageWriteBuffers;
205204007ebaSmrg        localRecPtr->NumScanlineImageWriteBuffers = pGeode->NoOfImgBuffers;
205304007ebaSmrg        HOOK(SetupForScanlineImageWrite);
205404007ebaSmrg        HOOK(SubsequentScanlineImageWriteRect);
205504007ebaSmrg        HOOK(SubsequentImageWriteScanline);
205604007ebaSmrg        localRecPtr->ScanlineImageWriteFlags = NO_PLANEMASK | NO_GXCOPY |
205704007ebaSmrg            BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD;
2058f29dbc25Smrg#endif
2059f29dbc25Smrg
206004007ebaSmrg    }
206104007ebaSmrg    else {
206204007ebaSmrg        localRecPtr->PixmapCacheFlags = DO_NOT_BLIT_STIPPLES;
2063f29dbc25Smrg    }
2064f29dbc25Smrg
2065f29dbc25Smrg    if (pGeode->AccelColorExpandBuffers) {
2066f29dbc25Smrg#if GX_CPU2SCREXP_SUPPORT
206704007ebaSmrg        /* Color expansion */
206804007ebaSmrg        localRecPtr->ScanlineColorExpandBuffers =
206904007ebaSmrg            pGeode->AccelColorExpandBuffers;
207004007ebaSmrg        localRecPtr->NumScanlineColorExpandBuffers =
207104007ebaSmrg            pGeode->NoOfColorExpandLines;
207204007ebaSmrg        HOOK(SetupForScanlineCPUToScreenColorExpandFill);
207304007ebaSmrg        HOOK(SubsequentScanlineCPUToScreenColorExpandFill);
207404007ebaSmrg        HOOK(SubsequentColorExpandScanline);
207504007ebaSmrg        localRecPtr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK |
207604007ebaSmrg            BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD;
2077f29dbc25Smrg#endif
2078f29dbc25Smrg    }
2079f29dbc25Smrg#if GX_WRITE_PIXMAP_SUPPORT
2080f29dbc25Smrg    pGeode->WritePixmap = localRecPtr->WritePixmap;
2081f29dbc25Smrg    HOOK(WritePixmap);
2082f29dbc25Smrg#endif
2083f29dbc25Smrg
2084f29dbc25Smrg    return (XAAInit(pScrn, localRecPtr));
208504007ebaSmrg#else                           /* XF86XAA */
208604007ebaSmrg    return FALSE;
208704007ebaSmrg#endif
2088f29dbc25Smrg}
2089f29dbc25Smrg
2090f29dbc25Smrg/* END OF FILE */
2091