gx_accel.c revision 44802259
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
403406bd8eSmrg#include "xorg-server.h"
41f29dbc25Smrg#include "vgaHW.h"
42f29dbc25Smrg#include "xf86.h"
4304007ebaSmrg#ifdef HAVE_XAA_H
44f29dbc25Smrg#include "xaalocal.h"
4504007ebaSmrg#endif
46f29dbc25Smrg#include "xf86fbman.h"
47f29dbc25Smrg#include "miline.h"
48f29dbc25Smrg#include "xaarop.h"
49f29dbc25Smrg#include "servermd.h"
50f29dbc25Smrg#include "picture.h"
51f29dbc25Smrg#include "xf86.h"
52f29dbc25Smrg#include "xf86_OSproc.h"
53f29dbc25Smrg#include "xf86Pci.h"
54f29dbc25Smrg#include "xf86PciInfo.h"
55f29dbc25Smrg#include "geode.h"
56f29dbc25Smrg#include "gfx_defs.h"
57f29dbc25Smrg#include "gfx_regs.h"
58f29dbc25Smrg
59f29dbc25Smrg/* Common macros for blend operations are here */
60f29dbc25Smrg
61f29dbc25Smrg#include "geode_blend.h"
62f29dbc25Smrg
63f29dbc25Smrg#undef ulong
64f29dbc25Smrgtypedef unsigned long ulong;
65f29dbc25Smrg
66f29dbc25Smrg#undef uint
67f29dbc25Smrgtypedef unsigned int uint;
68f29dbc25Smrg
69f29dbc25Smrg#undef ushort
70f29dbc25Smrgtypedef unsigned short ushort;
71f29dbc25Smrg
72f29dbc25Smrg#undef uchar
73f29dbc25Smrgtypedef unsigned char uchar;
74f29dbc25Smrg
75f29dbc25Smrg#define CALC_FBOFFSET(x, y) \
76f29dbc25Smrg	        (((ulong)(y) * gu2_pitch + ((ulong)(x) << gu2_xshift)))
77f29dbc25Smrg
78f29dbc25Smrg#define FBADDR(x,y)				\
79f29dbc25Smrg		((unsigned char *)pGeode->FBBase + CALC_FBOFFSET(x, y))
80f29dbc25Smrg
81f29dbc25Smrg#define OS_UDELAY 0
82f29dbc25Smrg#if OS_UDELAY > 0
83f29dbc25Smrg#define OS_USLEEP(usec) usleep(usec);
84f29dbc25Smrg#else
85f29dbc25Smrg#define OS_USLEEP(usec)
86f29dbc25Smrg#endif
87f29dbc25Smrg
88f29dbc25Smrg#ifdef OPT_ACCEL
89f29dbc25Smrgstatic unsigned int BPP;
90f29dbc25Smrgstatic unsigned int BLT_MODE, VEC_MODE;
91f29dbc25Smrgstatic unsigned int ACCEL_STRIDE;
92f29dbc25Smrg
93f29dbc25Smrg#define GU2_WAIT_PENDING while(READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_PENDING)
94f29dbc25Smrg#define GU2_WAIT_BUSY    while(READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_BUSY)
95f29dbc25Smrg#endif
96f29dbc25Smrg
97f29dbc25Smrg#define HOOK(fn) localRecPtr->fn = GX##fn
98f29dbc25Smrg
99f29dbc25Smrg#define DLOG(l, fmt, args...) ErrorF(fmt, ##args)
100f29dbc25Smrg
101f29dbc25Smrg/* static storage declarations */
102f29dbc25Smrg
10304007ebaSmrgtypedef struct sGBltBox {
104f29dbc25Smrg    ulong x, y;
105f29dbc25Smrg    ulong w, h;
106f29dbc25Smrg    ulong color;
107f29dbc25Smrg    int bpp, transparent;
108f29dbc25Smrg} GBltBox;
109f29dbc25Smrg
110f29dbc25Smrg#if GX_SCANLINE_SUPPORT
111f29dbc25Smrgstatic GBltBox giwr;
112f29dbc25Smrg#endif
113f29dbc25Smrg#if GX_CPU2SCREXP_SUPPORT
114f29dbc25Smrgstatic GBltBox gc2s;
115f29dbc25Smrg#endif
116f29dbc25Smrg#if GX_CLREXP_8X8_PAT_SUPPORT
117f29dbc25Smrgstatic ulong *gc8x8p;
118f29dbc25Smrg#endif
119f29dbc25Smrg
120f29dbc25Smrg#if GX_DASH_LINE_SUPPORT
12104007ebaSmrgtypedef struct sGDashLine {
122f29dbc25Smrg    ulong pat[2];
123f29dbc25Smrg    int len;
124f29dbc25Smrg    int fg;
125f29dbc25Smrg    int bg;
126f29dbc25Smrg} GDashLine;
127f29dbc25Smrg
128f29dbc25Smrgstatic GDashLine gdln;
129f29dbc25Smrg#endif
130f29dbc25Smrg
131f29dbc25Smrgstatic unsigned int gu2_xshift, gu2_yshift;
132f29dbc25Smrgstatic unsigned int gu2_pitch;
133f29dbc25Smrg
13404007ebaSmrg#if XF86XAA
135f29dbc25Smrgstatic XAAInfoRecPtr localRecPtr;
13604007ebaSmrg#endif
137f29dbc25Smrg
138f29dbc25Smrg/* pat  0xF0 */
139f29dbc25Smrg/* src  0xCC */
140f29dbc25Smrg/* dst  0xAA */
141f29dbc25Smrg
142f29dbc25Smrg/* (src FUNC dst) */
143f29dbc25Smrg
144f29dbc25Smrgstatic const int SDfn[16] = {
145f29dbc25Smrg    0x00, 0x88, 0x44, 0xCC, 0x22, 0xAA, 0x66, 0xEE,
146f29dbc25Smrg    0x11, 0x99, 0x55, 0xDD, 0x33, 0xBB, 0x77, 0xFF
147f29dbc25Smrg};
148f29dbc25Smrg
149f29dbc25Smrg/* ((src FUNC dst) AND pat-mask) OR (dst AND (NOT pat-mask)) */
150f29dbc25Smrg
151f29dbc25Smrgstatic const int SDfn_PM[16] = {
152f29dbc25Smrg    0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
153f29dbc25Smrg    0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA
154f29dbc25Smrg};
155f29dbc25Smrg
156f29dbc25Smrg/* (pat FUNC dst) */
157f29dbc25Smrg
158f29dbc25Smrgstatic const int PDfn[16] = {
159f29dbc25Smrg    0x00, 0xA0, 0x50, 0xF0, 0x0A, 0xAA, 0x5A, 0xFA,
160f29dbc25Smrg    0x05, 0xA5, 0x55, 0xF5, 0x0F, 0xAF, 0x5F, 0xFF
161f29dbc25Smrg};
162f29dbc25Smrg
163f29dbc25Smrg/* ((pat FUNC dst) AND src-mask) OR (dst AND (NOT src-mask)) */
164f29dbc25Smrg
165f29dbc25Smrgstatic const int PDfn_SM[16] = {
166f29dbc25Smrg    0x22, 0xA2, 0x62, 0xE2, 0x2A, 0xAA, 0x6A, 0xEA,
167f29dbc25Smrg    0x26, 0xA6, 0x66, 0xE6, 0x2E, 0xAE, 0x6E, 0xEE
168f29dbc25Smrg};
169f29dbc25Smrg
170f29dbc25Smrg#ifdef OPT_ACCEL
171f29dbc25Smrgstatic inline CARD32
172f29dbc25Smrgamd_gx_BppToRasterMode(int bpp)
173f29dbc25Smrg{
174f29dbc25Smrg    switch (bpp) {
175f29dbc25Smrg    case 16:
17604007ebaSmrg        return MGP_RM_BPPFMT_565;
177f29dbc25Smrg    case 32:
17804007ebaSmrg        return MGP_RM_BPPFMT_8888;
179f29dbc25Smrg    case 8:
18004007ebaSmrg        return MGP_RM_BPPFMT_332;
181f29dbc25Smrg    default:
18204007ebaSmrg        return 0;
183f29dbc25Smrg    }
184f29dbc25Smrg}
18504007ebaSmrg#endif                          /* OPT_ACCEL */
186f29dbc25Smrg
187f29dbc25Smrg/*----------------------------------------------------------------------------
188f29dbc25Smrg * GXAccelSync.
189f29dbc25Smrg *
190f29dbc25Smrg * Description  :This function is called to synchronize with the graphics
191f29dbc25Smrg *               engine and it waits the graphic engine is idle.  This is
192f29dbc25Smrg *               required before allowing direct access to the framebuffer.
193f29dbc25Smrg *
194f29dbc25Smrg *    Arg        Type     Comment
195f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
196f29dbc25Smrg *
197f29dbc25Smrg * Returns              :none
198f29dbc25Smrg *---------------------------------------------------------------------------*/
199f29dbc25Smrgvoid
200f29dbc25SmrgGXAccelSync(ScrnInfoPtr pScrni)
201f29dbc25Smrg{
202f29dbc25Smrg    //ErrorF("GXAccelSync()\n");
203f29dbc25Smrg#ifndef OPT_ACCEL
204f29dbc25Smrg    gfx_wait_until_idle();
205f29dbc25Smrg#else
206f29dbc25Smrg    GU2_WAIT_BUSY;
207f29dbc25Smrg#endif
208f29dbc25Smrg}
209f29dbc25Smrg
210f29dbc25Smrg#if GX_FILL_RECT_SUPPORT
211f29dbc25Smrg/*----------------------------------------------------------------------------
212f29dbc25Smrg * GXSetupForSolidFill.
213f29dbc25Smrg *
214f29dbc25Smrg * Description  :The SetupFor and Subsequent SolidFill(Rect) provide
215f29dbc25Smrg *               filling rectangular areas of the screen with a
216f29dbc25Smrg *               foreground color.
217f29dbc25Smrg *
218f29dbc25Smrg * Parameters.
219f29dbc25Smrg *    Arg        Type     Comment
220f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
221f29dbc25Smrg *   color        int     foreground fill color
222f29dbc25Smrg *    rop         int     unmapped raster op
223f29dbc25Smrg * planemask     uint     -1 (fill) or pattern data
224f29dbc25Smrg *
225f29dbc25Smrg * Returns              :none
226f29dbc25Smrg *--------------------------------------------------------------------------*/
227f29dbc25Smrgstatic void
228f29dbc25SmrgGXSetupForSolidFill(ScrnInfoPtr pScrni,
22904007ebaSmrg                    int color, int rop, unsigned int planemask)
230f29dbc25Smrg{
231f29dbc25Smrg    //ErrorF("GXSetupForSolidFill(%#x,%#x,%#x)\n", color, rop, planemask);
232f29dbc25Smrg    rop &= 0x0F;
233f29dbc25Smrg#ifndef OPT_ACCEL
234f29dbc25Smrg    gfx_set_solid_pattern(planemask);
235f29dbc25Smrg    gfx_set_solid_source(color);
236f29dbc25Smrg    gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
237f29dbc25Smrg#else
238f29dbc25Smrg    {
23904007ebaSmrg        unsigned int ROP = BPP | (planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
24004007ebaSmrg
24104007ebaSmrg        BLT_MODE = ((ROP ^ (ROP >> 2)) & 0x33) == 0 ? MGP_BM_SRC_MONO : 0;
24204007ebaSmrg        if (((ROP ^ (ROP >> 1)) & 0x55) != 0)
24304007ebaSmrg            BLT_MODE |= MGP_BM_DST_REQ;
24404007ebaSmrg        GU2_WAIT_PENDING;
24504007ebaSmrg        WRITE_GP32(MGP_RASTER_MODE, ROP);
24604007ebaSmrg        WRITE_GP32(MGP_PAT_COLOR_0, planemask);
24704007ebaSmrg        WRITE_GP32(MGP_SRC_COLOR_FG, color);
24804007ebaSmrg        WRITE_GP32(MGP_STRIDE, ACCEL_STRIDE);
249f29dbc25Smrg    }
250f29dbc25Smrg#endif
251f29dbc25Smrg}
252f29dbc25Smrg
253f29dbc25Smrg/*----------------------------------------------------------------------------
254f29dbc25Smrg * GXSubsequentSolidFillRect.
255f29dbc25Smrg *
256f29dbc25Smrg * Description  :see GXSetupForSolidFill.
257f29dbc25Smrg *
258f29dbc25Smrg * Parameters.
259f29dbc25Smrg *    Arg        Type     Comment
260f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
261f29dbc25Smrg *     x          int     destination x offset
262f29dbc25Smrg *     y          int     destination y offset
263f29dbc25Smrg *     w          int     fill area width (pixels)
264f29dbc25Smrg *     h          int     fill area height (pixels)
265f29dbc25Smrg *
266f29dbc25Smrg * Returns      :none
267f29dbc25Smrg *
268f29dbc25Smrg * Sample application uses:
269f29dbc25Smrg *   - Window backgrounds.
270f29dbc25Smrg *   - pull down highlighting.
271f29dbc25Smrg *   - x11perf: rectangle tests (-rect500).
272f29dbc25Smrg *   - x11perf: fill trapezoid tests (-trap100).
273f29dbc25Smrg *   - x11perf: horizontal line segments (-hseg500).
274f29dbc25Smrg *----------------------------------------------------------------------------*/
275f29dbc25Smrgstatic void
276f29dbc25SmrgGXSubsequentSolidFillRect(ScrnInfoPtr pScrni, int x, int y, int w, int h)
277f29dbc25Smrg{
278f29dbc25Smrg    //ErrorF("GXSubsequentSolidFillRect() at %d,%d %dx%d\n", x, y, w, h);
279f29dbc25Smrg#ifndef OPT_ACCEL
280f29dbc25Smrg    gfx_pattern_fill(x, y, w, h);
281f29dbc25Smrg#else
282f29dbc25Smrg    {
28304007ebaSmrg        unsigned int offset = CALC_FBOFFSET(x, y);
28404007ebaSmrg        unsigned int size = (w << 16) | h;
285f29dbc25Smrg
28604007ebaSmrg        GU2_WAIT_PENDING;
28704007ebaSmrg        WRITE_GP32(MGP_DST_OFFSET, offset);
28804007ebaSmrg        WRITE_GP32(MGP_WID_HEIGHT, size);
28904007ebaSmrg        WRITE_GP32(MGP_BLT_MODE, BLT_MODE);
290f29dbc25Smrg    }
291f29dbc25Smrg#endif
292f29dbc25Smrg}
293f29dbc25Smrg
29404007ebaSmrg#endif                          /* if GX_FILL_RECT_SUPPORT */
295f29dbc25Smrg
296f29dbc25Smrg#if GX_CLREXP_8X8_PAT_SUPPORT
297f29dbc25Smrg/*----------------------------------------------------------------------------
298f29dbc25Smrg * GXSetupForColor8x8PatternFill
299f29dbc25Smrg *
300f29dbc25Smrg * Description  :8x8 color pattern data is 64 pixels of full color data
301f29dbc25Smrg *               stored linearly in offscreen video memory.  These patterns
302f29dbc25Smrg *               are useful as a substitute for 8x8 mono patterns when tiling,
303f29dbc25Smrg *               doing opaque stipples, or regular stipples.
304f29dbc25Smrg *
305f29dbc25Smrg *    Arg        Type     Comment
306f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
307f29dbc25Smrg *    patx        int     x offset to pattern data
308f29dbc25Smrg *    paty        int     y offset to pattern data
309f29dbc25Smrg *    rop         int     unmapped raster operation
310f29dbc25Smrg * planemask     uint     -1 (copy) or pattern data
311f29dbc25Smrg * trans_color    int     -1 (copy) or transparent color (not enabled)
312f29dbc25Smrg *                         trans color only supported on source channel
313f29dbc25Smrg *                         or in monochrome pattern channel
314f29dbc25Smrg *
315f29dbc25Smrg * Returns      :none.
316f29dbc25Smrg *
317f29dbc25Smrg *---------------------------------------------------------------------------*/
318f29dbc25Smrg
319f29dbc25Smrgstatic void
320f29dbc25SmrgGXSetupForColor8x8PatternFill(ScrnInfoPtr pScrni, int patx, int paty, int rop,
32104007ebaSmrg                              uint planemask, int trans_color)
322f29dbc25Smrg{
323f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR(pScrni);
324f29dbc25Smrg
325f29dbc25Smrg    //ErrorF("GXSetupForColor8x8PatternFill() pat %#x,%#x rop %#x %#x %#x\n",
326f29dbc25Smrg    //    patx, paty, rop, planemask, trans_color);
327f29dbc25Smrg    rop &= 0x0F;
32804007ebaSmrg    gc8x8p = (unsigned long *) FBADDR(patx, paty);
329f29dbc25Smrg    /* gfx_set_solid_pattern is needed to clear src/pat transparency */
330f29dbc25Smrg    gfx_set_solid_pattern(0);
331f29dbc25Smrg    gfx_set_raster_operation(planemask == ~0U ? PDfn[rop] :
33204007ebaSmrg                             (gfx_set_solid_source(planemask), PDfn_SM[rop]));
333f29dbc25Smrg    gfx2_set_source_stride(pGeode->Pitch);
334f29dbc25Smrg    gfx2_set_destination_stride(pGeode->Pitch);
335f29dbc25Smrg    if (trans_color == -1)
33604007ebaSmrg        gfx2_set_source_transparency(0, 0);
337f29dbc25Smrg    else
33804007ebaSmrg        gfx2_set_source_transparency(trans_color, ~0);
339f29dbc25Smrg}
340f29dbc25Smrg
341f29dbc25Smrg/*----------------------------------------------------------------------------
342f29dbc25Smrg * GXSubsequentColor8x8PatternFillRect
343f29dbc25Smrg *
344f29dbc25Smrg * Description  :see GXSetupForColor8x8PatternFill.
345f29dbc25Smrg *
346f29dbc25Smrg *    Arg        Type     Comment
347f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
348f29dbc25Smrg *   patx         int     pattern phase x offset
349f29dbc25Smrg *   paty         int     pattern phase y offset
350f29dbc25Smrg *      x         int     destination x offset
351f29dbc25Smrg *      y         int     destination y offset
352f29dbc25Smrg *      w         int     fill area width (pixels)
353f29dbc25Smrg *      h         int     fill area height (pixels)
354f29dbc25Smrg *
355f29dbc25Smrg * Returns      :none
356f29dbc25Smrg *
357f29dbc25Smrg * Sample application uses:
358f29dbc25Smrg *   - Patterned desktops
359f29dbc25Smrg *   - x11perf: stippled rectangle tests (-srect500).
360f29dbc25Smrg *   - x11perf: opaque stippled rectangle tests (-osrect500).
361f29dbc25Smrg *--------------------------------------------------------------------------*/
362f29dbc25Smrgstatic void
363f29dbc25SmrgGXSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrni, int patx, int paty,
36404007ebaSmrg                                    int x, int y, int w, int h)
365f29dbc25Smrg{
366f29dbc25Smrg    //ErrorF(
367f29dbc25Smrg    //    "GXSubsequentColor8x8PatternFillRect() patxy %d,%d at %d,%d %dsx%d\n",
368f29dbc25Smrg    //    patx, paty, x, y, w, h);
369f29dbc25Smrg    gfx2_set_pattern_origin(patx, paty);
370f29dbc25Smrg    gfx2_color_pattern_fill(CALC_FBOFFSET(x, y), w, h, gc8x8p);
371f29dbc25Smrg}
372f29dbc25Smrg
373f29dbc25Smrg/* GX_CLREXP_8X8_PAT_SUPPORT */
374f29dbc25Smrg#endif
375f29dbc25Smrg
376f29dbc25Smrg#if GX_MONO_8X8_PAT_SUPPORT
377f29dbc25Smrg/*----------------------------------------------------------------------------
378f29dbc25Smrg * GXSetupForMono8x8PatternFill
379f29dbc25Smrg *
380f29dbc25Smrg * Description  :8x8 mono pattern data is 64 bits of color expansion data
381f29dbc25Smrg *               with ones indicating the foreground color and zeros
382f29dbc25Smrg *               indicating the background color.  These patterns are
383f29dbc25Smrg *               useful when tiling, doing opaque stipples, or regular
384f29dbc25Smrg *               stipples.
385f29dbc25Smrg *
386f29dbc25Smrg *    Arg        Type     Comment
387f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
388f29dbc25Smrg *    patx        int     x offset to pattern data
389f29dbc25Smrg *    paty        int     y offset to pattern data
390f29dbc25Smrg *     fg         int     foreground color
391f29dbc25Smrg *     bg         int     -1 (transparent) or background color
392f29dbc25Smrg *    rop         int     unmapped raster operation
393f29dbc25Smrg * planemask     uint     -1 (copy) or pattern data
394f29dbc25Smrg *
395f29dbc25Smrg * Returns      :none.
396f29dbc25Smrg *
397f29dbc25Smrg * Comments     :none.
398f29dbc25Smrg *
399f29dbc25Smrg *--------------------------------------------------------------------------*/
400f29dbc25Smrgstatic void
401f29dbc25SmrgGXSetupForMono8x8PatternFill(ScrnInfoPtr pScrni, int patx, int paty,
40204007ebaSmrg                             int fg, int bg, int rop, uint planemask)
403f29dbc25Smrg{
404f29dbc25Smrg    //ErrorF(
405f29dbc25Smrg    //"GXSetupForMono8x8PatternFill() pat %#x,%#x fg %#x bg %#x %#x %#x\n",
406f29dbc25Smrg    //patx, paty, fg, bg, rop, planemask);
407f29dbc25Smrg    rop &= 0x0F;
408f29dbc25Smrg#ifndef OPT_ACCEL
409f29dbc25Smrg    gfx_set_mono_pattern(bg, fg, patx, paty, bg == -1 ? 1 : 0);
410f29dbc25Smrg    gfx_set_raster_operation(planemask == ~0U ? PDfn[rop] :
41104007ebaSmrg                             (gfx_set_solid_source(planemask), PDfn_SM[rop]));
412f29dbc25Smrg#else
413f29dbc25Smrg    {
41404007ebaSmrg        unsigned int ROP = BPP |
41504007ebaSmrg            (bg ==
41604007ebaSmrg             -1 ? MGP_RM_PAT_MONO | MGP_RM_PAT_TRANS : MGP_RM_PAT_MONO) |
41704007ebaSmrg            (planemask == ~0U ? PDfn[rop] : PDfn_SM[rop]);
41804007ebaSmrg        BLT_MODE = ((ROP ^ (ROP >> 2)) & 0x33) == 0 ? MGP_BM_SRC_MONO : 0;
41904007ebaSmrg        if (((ROP ^ (ROP >> 1)) & 0x55) != 0)
42004007ebaSmrg            BLT_MODE |= MGP_BM_DST_REQ;
42104007ebaSmrg        GU2_WAIT_PENDING;
42204007ebaSmrg        WRITE_GP32(MGP_RASTER_MODE, ROP);
42304007ebaSmrg        WRITE_GP32(MGP_SRC_COLOR_FG, planemask);
42404007ebaSmrg        WRITE_GP32(MGP_PAT_COLOR_0, bg);
42504007ebaSmrg        WRITE_GP32(MGP_PAT_COLOR_1, fg);
42604007ebaSmrg        WRITE_GP32(MGP_PAT_DATA_0, patx);
42704007ebaSmrg        WRITE_GP32(MGP_PAT_DATA_1, paty);
42804007ebaSmrg        WRITE_GP32(MGP_STRIDE, ACCEL_STRIDE);
429f29dbc25Smrg    }
430f29dbc25Smrg#endif
431f29dbc25Smrg}
432f29dbc25Smrg
433f29dbc25Smrg/*----------------------------------------------------------------------------
434f29dbc25Smrg * GXSubsequentMono8x8PatternFillRect
435f29dbc25Smrg *
436f29dbc25Smrg * Description  :see GXSetupForMono8x8PatternFill
437f29dbc25Smrg *
438f29dbc25Smrg *    Arg        Type     Comment
439f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
440f29dbc25Smrg *   patx         int     pattern phase x offset
441f29dbc25Smrg *   paty         int     pattern phase y offset
442f29dbc25Smrg *      x         int     destination x offset
443f29dbc25Smrg *      y         int     destination y offset
444f29dbc25Smrg *      w         int     fill area width (pixels)
445f29dbc25Smrg *      h         int     fill area height (pixels)
446f29dbc25Smrg
447f29dbc25Smrg * Returns      :none
448f29dbc25Smrg *
449f29dbc25Smrg * Sample application uses:
450f29dbc25Smrg *   - Patterned desktops
451f29dbc25Smrg *   - x11perf: stippled rectangle tests (-srect500).
452f29dbc25Smrg *   - x11perf: opaque stippled rectangle tests (-osrect500).
453f29dbc25Smrg *--------------------------------------------------------------------------*/
454f29dbc25Smrgstatic void
455f29dbc25SmrgGXSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrni, int patx, int paty,
45604007ebaSmrg                                   int x, int y, int w, int h)
457f29dbc25Smrg{
458f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() pat %#x,%#x at %d,%d %dx%d\n",
45904007ebaSmrg                 __func__, patx, paty, x, y, w, h));
460f29dbc25Smrg#ifndef OPT_ACCEL
461f29dbc25Smrg    gfx_pattern_fill(x, y, w, h);
462f29dbc25Smrg#else
463f29dbc25Smrg    {
46404007ebaSmrg        unsigned int offset =
46504007ebaSmrg            CALC_FBOFFSET(x, y) | ((x & 7) << 26) | ((y & 7) << 29);
46604007ebaSmrg        unsigned int size = (w << 16) | h;
46704007ebaSmrg
46804007ebaSmrg        GU2_WAIT_PENDING;
46904007ebaSmrg        WRITE_GP32(MGP_DST_OFFSET, offset);
47004007ebaSmrg        WRITE_GP32(MGP_WID_HEIGHT, size);
47104007ebaSmrg        WRITE_GP32(MGP_BLT_MODE, BLT_MODE);
472f29dbc25Smrg    }
473f29dbc25Smrg#endif
474f29dbc25Smrg}
475f29dbc25Smrg
47604007ebaSmrg#endif                          /* GX_MONO_8X8_PAT_SUPPORT */
477f29dbc25Smrg
478f29dbc25Smrg#if GX_SCR2SCRCPY_SUPPORT
479f29dbc25Smrg/*----------------------------------------------------------------------------
480f29dbc25Smrg * GXSetupForScreenToScreenCopy
481f29dbc25Smrg *
482f29dbc25Smrg * Description  :SetupFor and Subsequent ScreenToScreenCopy functions
483f29dbc25Smrg *               provide an interface for copying rectangular areas from
484f29dbc25Smrg *               video memory to video memory.
485f29dbc25Smrg *
486f29dbc25Smrg *    Arg        Type     Comment
487f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
488f29dbc25Smrg *   xdir         int     x copy direction (up/dn)
489f29dbc25Smrg *   ydir         int     y copy direction (up/dn)
490f29dbc25Smrg *    rop         int     unmapped raster operation
491f29dbc25Smrg * planemask     uint     -1 (copy) or pattern data
492f29dbc25Smrg * trans_color    int     -1 (copy) or transparent color
493f29dbc25Smrg *
494f29dbc25Smrg * Returns      :none
495f29dbc25Smrg *---------------------------------------------------------------------------*/
496f29dbc25Smrgstatic void
497f29dbc25SmrgGXSetupForScreenToScreenCopy(ScrnInfoPtr pScrni, int xdir, int ydir, int rop,
49804007ebaSmrg                             uint planemask, int trans_color)
499f29dbc25Smrg{
500f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() xd%d yd%d rop %#x %#x %#x\n",
50104007ebaSmrg                 __func__, xdir, ydir, rop, planemask, trans_color));
502f29dbc25Smrg    rop &= 0x0F;
503f29dbc25Smrg#ifndef OPT_ACCEL
504f29dbc25Smrg    {
50504007ebaSmrg        GeodeRec *pGeode = GEODEPTR(pScrni);
50604007ebaSmrg
50704007ebaSmrg        gfx_set_solid_pattern(planemask);
50804007ebaSmrg        /* transparency is a parameter to set_rop, but set...pattern clears
50904007ebaSmrg         * transparency */
51004007ebaSmrg        if (trans_color == -1)
51104007ebaSmrg            gfx2_set_source_transparency(0, 0);
51204007ebaSmrg        else
51304007ebaSmrg            gfx2_set_source_transparency(trans_color, ~0);
51404007ebaSmrg        gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
51504007ebaSmrg        gfx2_set_source_stride(pGeode->Pitch);
51604007ebaSmrg        gfx2_set_destination_stride(pGeode->Pitch);
517f29dbc25Smrg    }
518f29dbc25Smrg#else
519f29dbc25Smrg    {
52004007ebaSmrg        unsigned int ROP = BPP | (planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
52104007ebaSmrg
52204007ebaSmrg        if (trans_color != -1)
52304007ebaSmrg            ROP |= MGP_RM_SRC_TRANS;
52404007ebaSmrg        BLT_MODE = ((ROP ^ (ROP >> 1)) & 0x55) != 0 ?
52504007ebaSmrg            MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
52604007ebaSmrg        GU2_WAIT_PENDING;
52704007ebaSmrg        WRITE_GP32(MGP_RASTER_MODE, ROP);
52804007ebaSmrg        WRITE_GP32(MGP_PAT_COLOR_0, planemask);
52904007ebaSmrg        WRITE_GP32(MGP_SRC_COLOR_FG, trans_color);
53004007ebaSmrg        WRITE_GP32(MGP_SRC_COLOR_BG, ~0);
53104007ebaSmrg        WRITE_GP32(MGP_STRIDE, ACCEL_STRIDE);
532f29dbc25Smrg    }
533f29dbc25Smrg#endif
534f29dbc25Smrg}
535f29dbc25Smrg
536f29dbc25Smrg/*----------------------------------------------------------------------------
537f29dbc25Smrg * GXSubsquentScreenToScreenCopy
538f29dbc25Smrg *
539f29dbc25Smrg * Description  :see GXSetupForScreenToScreenCopy.
540f29dbc25Smrg *
541f29dbc25Smrg *    Arg        Type     Comment
542f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
543f29dbc25Smrg *     x1         int     source x offset
544f29dbc25Smrg *     y1         int     source y offset
545f29dbc25Smrg *     x2         int     destination x offset
546f29dbc25Smrg *     y2         int     destination y offset
547f29dbc25Smrg *      w         int     copy area width (pixels)
548f29dbc25Smrg *      h         int     copy area height (pixels)
549f29dbc25Smrg *
550f29dbc25Smrg * Returns      :none
551f29dbc25Smrg *
552f29dbc25Smrg * Sample application uses (non-transparent):
553f29dbc25Smrg *   - Moving windows.
554f29dbc25Smrg *   - x11perf: scroll tests (-scroll500).
555f29dbc25Smrg *   - x11perf: copy from window to window (-copywinwin500).
556f29dbc25Smrg *---------------------------------------------------------------------------*/
557f29dbc25Smrgstatic void
558f29dbc25SmrgGXSubsequentScreenToScreenCopy(ScrnInfoPtr pScrni,
55904007ebaSmrg                               int x1, int y1, int x2, int y2, int w, int h)
560f29dbc25Smrg{
561f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() from %d,%d to %d,%d %dx%d\n",
56204007ebaSmrg                 __func__, x1, y1, x2, y2, w, h));
563f29dbc25Smrg#ifndef OPT_ACCEL
564f29dbc25Smrg    {
56504007ebaSmrg        int flags = 0;
56604007ebaSmrg
56704007ebaSmrg        if (x2 > x1)
56804007ebaSmrg            flags |= 1;
56904007ebaSmrg        if (y2 > y1)
57004007ebaSmrg            flags |= 2;
57104007ebaSmrg        gfx2_screen_to_screen_blt(CALC_FBOFFSET(x1, y1), CALC_FBOFFSET(x2,
57204007ebaSmrg                                                                       y2), w,
57304007ebaSmrg                                  h, flags);
574f29dbc25Smrg    }
575f29dbc25Smrg#else
576f29dbc25Smrg    {
57704007ebaSmrg        GeodeRec *pGeode = GEODEPTR(pScrni);
57804007ebaSmrg        unsigned int src = CALC_FBOFFSET(x1, y1);
57904007ebaSmrg        unsigned int dst = CALC_FBOFFSET(x2, y2);
58004007ebaSmrg        unsigned int size = (w << 16) | h;
58104007ebaSmrg        unsigned int blt_mode = BLT_MODE;
58204007ebaSmrg
58304007ebaSmrg        if (x2 > x1) {
58404007ebaSmrg            int n = (w << gu2_xshift) - 1;
58504007ebaSmrg
58604007ebaSmrg            src += n;
58704007ebaSmrg            dst += n;
58804007ebaSmrg            blt_mode |= MGP_BM_NEG_XDIR;
58904007ebaSmrg        }
59004007ebaSmrg        if (y2 > y1) {
59104007ebaSmrg            int n = (h - 1) * pGeode->Pitch;
59204007ebaSmrg
59304007ebaSmrg            src += n;
59404007ebaSmrg            dst += n;
59504007ebaSmrg            blt_mode |= MGP_BM_NEG_YDIR;
59604007ebaSmrg        }
59704007ebaSmrg        GU2_WAIT_PENDING;
59804007ebaSmrg        WRITE_GP32(MGP_SRC_OFFSET, src);
59904007ebaSmrg        WRITE_GP32(MGP_DST_OFFSET, dst);
60004007ebaSmrg        WRITE_GP32(MGP_WID_HEIGHT, size);
60104007ebaSmrg        WRITE_GP16(MGP_BLT_MODE, blt_mode);
602f29dbc25Smrg    }
603f29dbc25Smrg#endif
604f29dbc25Smrg}
605f29dbc25Smrg
60604007ebaSmrg#endif                          /* if GX_SCR2SCRCPY_SUPPORT */
607f29dbc25Smrg
608f29dbc25Smrg#if GX_SCANLINE_SUPPORT
609f29dbc25Smrg/*----------------------------------------------------------------------------
610f29dbc25Smrg * GXSetupForScanlineImageWrite
611f29dbc25Smrg *
612f29dbc25Smrg * Description  :SetupFor/Subsequent ScanlineImageWrite and ImageWriteScanline
613f29dbc25Smrg *               transfer full color pixel data from system memory to video
614f29dbc25Smrg *               memory.  This is useful for dealing with alignment issues and
615f29dbc25Smrg *               performing raster ops on the data.
616f29dbc25Smrg *
617f29dbc25Smrg *    Arg        Type     Comment
618f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
619f29dbc25Smrg *    rop         int     unmapped raster operation
620f29dbc25Smrg * planemask     uint     -1 (copy) or pattern data
621f29dbc25Smrg *    bpp         int     bits per pixel (unused)
622f29dbc25Smrg *  depth         int     color depth (unused)
623f29dbc25Smrg *
624f29dbc25Smrg * Returns      :none
625f29dbc25Smrg *
626f29dbc25Smrg *  x11perf -putimage10
627f29dbc25Smrg *  x11perf -putimage100
628f29dbc25Smrg *  x11perf -putimage500
629f29dbc25Smrg *----------------------------------------------------------------------------
630f29dbc25Smrg */
631f29dbc25Smrgstatic void
632f29dbc25SmrgGXSetupForScanlineImageWrite(ScrnInfoPtr pScrni, int rop, uint planemask,
63304007ebaSmrg                             int trans_color, int bpp, int depth)
634f29dbc25Smrg{
635f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR(pScrni);
636f29dbc25Smrg
637f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() rop %#x %#x %#x %d %d\n",
63804007ebaSmrg                 __func__, rop, planemask, trans_color, bpp, depth));
639f29dbc25Smrg    rop &= 0x0F;
640f29dbc25Smrg    /* transparency is a parameter to set_rop, but set...pattern clears
641f29dbc25Smrg     * transparency */
642f29dbc25Smrg    gfx_set_solid_pattern(planemask);
643f29dbc25Smrg    if (trans_color == -1)
64404007ebaSmrg        gfx2_set_source_transparency(0, 0);
645f29dbc25Smrg    else
64604007ebaSmrg        gfx2_set_source_transparency(trans_color, ~0);
647f29dbc25Smrg    gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
648f29dbc25Smrg    gfx2_set_source_stride(pGeode->Pitch);
649f29dbc25Smrg    gfx2_set_destination_stride(pGeode->Pitch);
650f29dbc25Smrg}
651f29dbc25Smrg
652f29dbc25Smrg/*----------------------------------------------------------------------------
653f29dbc25Smrg * GXSubsequentScanlineImageWriteRect
654f29dbc25Smrg *
655f29dbc25Smrg * Description  : see GXSetupForScanlineImageWrite.
656f29dbc25Smrg *
657f29dbc25Smrg *    Arg        Type     Comment
658f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
659f29dbc25Smrg *      x         int     destination x offset
660f29dbc25Smrg *      y         int     destination y offset
661f29dbc25Smrg *      w         int     copy area width (pixels)
662f29dbc25Smrg *      h         int     copy area height (pixels)
663f29dbc25Smrg * skipleft       int     x margin (pixels) to skip (not enabled)
664f29dbc25Smrg *
665f29dbc25Smrg * Returns      :none
666f29dbc25Smrg *---------------------------------------------------------------------------*/
667f29dbc25Smrgstatic void
668f29dbc25SmrgGXSubsequentScanlineImageWriteRect(ScrnInfoPtr pScrni,
66904007ebaSmrg                                   int x, int y, int w, int h, int skipleft)
670f29dbc25Smrg{
671f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() rop %d,%d %dx%d %d\n",
67204007ebaSmrg                 __func__, x, y, w, h, skipleft));
673f29dbc25Smrg    giwr.x = x;
674f29dbc25Smrg    giwr.y = y;
675f29dbc25Smrg    giwr.w = w;
676f29dbc25Smrg    giwr.h = h;
677f29dbc25Smrg#if !GX_USE_OFFSCRN_MEM
678f29dbc25Smrg#if !GX_ONE_LINE_AT_A_TIME
679f29dbc25Smrg    GXAccelSync(pScrni);
680f29dbc25Smrg#endif
681f29dbc25Smrg#endif
682f29dbc25Smrg}
683f29dbc25Smrg
684f29dbc25Smrg/*----------------------------------------------------------------------------
685f29dbc25Smrg * GXSubsquentImageWriteScanline
686f29dbc25Smrg *
687f29dbc25Smrg * Description  : see GXSetupForScanlineImageWrite.
688f29dbc25Smrg *
689f29dbc25Smrg *    Arg        Type     Comment
690f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
691f29dbc25Smrg *  bufno         int     scanline number in write group
692f29dbc25Smrg *
693f29dbc25Smrg * Returns      :none
694f29dbc25Smrg *
695f29dbc25Smrg * Sample application uses (non-transparent):
696f29dbc25Smrg *   - Moving windows.
697f29dbc25Smrg *   - x11perf: scroll tests (-scroll500).
698f29dbc25Smrg *   - x11perf: copy from window to window (-copywinwin500).
699f29dbc25Smrg *
700f29dbc25Smrg *---------------------------------------------------------------------------*/
701f29dbc25Smrgstatic void
702f29dbc25SmrgGXSubsequentImageWriteScanline(ScrnInfoPtr pScrni, int bufno)
703f29dbc25Smrg{
704f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR(pScrni);
705f29dbc25Smrg
706f29dbc25Smrg#if !GX_USE_OFFSCRN_MEM
707f29dbc25Smrg    unsigned long offset;
708f29dbc25Smrg#endif
709f29dbc25Smrg
710f29dbc25Smrg#if GX_ONE_LINE_AT_A_TIME
711f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %d\n", __func__, bufno));
712f29dbc25Smrg#if !GX_USE_OFFSCRN_MEM
713f29dbc25Smrg    offset = pGeode->AccelImageWriteBuffers[bufno] - pGeode->FBBase;
714f29dbc25Smrg    gfx2_screen_to_screen_blt(offset, CALC_FBOFFSET(giwr.x, giwr.y), giwr.w,
71504007ebaSmrg                              1, 0);
71604007ebaSmrg#else                           /* if !GX_USE_OFFSCRN_MEM */
717f29dbc25Smrg    gfx2_color_bitmap_to_screen_blt(0, 0, CALC_FBOFFSET(giwr.x, giwr.y),
71804007ebaSmrg                                    giwr.w, 1,
71904007ebaSmrg                                    pGeode->AccelImageWriteBuffers[bufno],
72004007ebaSmrg                                    pGeode->Pitch);
72104007ebaSmrg#endif                          /* if !GX_USE_OFFSCRN_MEM */
722f29dbc25Smrg    ++giwr.y;
72304007ebaSmrg#else                           /* if GX_ONE_LINE_AT_A_TIME */
724f29dbc25Smrg    int blt_height;
725f29dbc25Smrg
726f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %d\n", __func__, bufno));
727f29dbc25Smrg
728f29dbc25Smrg    if ((blt_height = pGeode->NoOfImgBuffers) > giwr.h)
72904007ebaSmrg        blt_height = giwr.h;
730f29dbc25Smrg    if (++bufno < blt_height)
73104007ebaSmrg        return;
732f29dbc25Smrg#if !GX_USE_OFFSCRN_MEM
733f29dbc25Smrg    offset = pGeode->AccelImageWriteBuffers[0] - pGeode->FBBase;
734f29dbc25Smrg    gfx2_screen_to_screen_blt(offset, CALC_FBOFFSET(giwr.x, giwr.y), giwr.w,
73504007ebaSmrg                              blt_height, 0);
736f29dbc25Smrg    GXAccelSync(pScrni);
73704007ebaSmrg#else                           /* if !GX_USE_OFFSCRN_MEM */
738f29dbc25Smrg    gfx2_color_bitmap_to_screen_blt(0, 0, CALC_FBOFFSET(giwr.x, giwr.y),
73904007ebaSmrg                                    giwr.w, blt_height,
74004007ebaSmrg                                    pGeode->AccelImageWriteBuffers[0],
74104007ebaSmrg                                    pGeode->Pitch);
74204007ebaSmrg#endif                          /* if !GX_USE_OFFSCRN_MEM */
743f29dbc25Smrg    giwr.h -= blt_height;
744f29dbc25Smrg    giwr.y += blt_height;
74504007ebaSmrg#endif                          /* if GX_ONE_LINE_AT_A_TIME */
746f29dbc25Smrg}
74704007ebaSmrg#endif                          /* GX_SCANLINE_SUPPORT */
748f29dbc25Smrg
749f29dbc25Smrg#if GX_CPU2SCREXP_SUPPORT
750f29dbc25Smrg/*----------------------------------------------------------------------------
751f29dbc25Smrg * GXSetupForScanlineCPUToScreenColorExpandFill
752f29dbc25Smrg *
753f29dbc25Smrg * Description  :SetupFor/Subsequent CPUToScreenColorExpandFill and
754f29dbc25Smrg *               ColorExpandScanline routines provide an interface for
755f29dbc25Smrg *               doing expansion blits from source patterns stored in
756f29dbc25Smrg *               system memory.
757f29dbc25Smrg *
758f29dbc25Smrg *    Arg        Type     Comment
759f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
760f29dbc25Smrg *     fg         int     foreground color
761f29dbc25Smrg *     bg         int     -1 (transparent) or background color
762f29dbc25Smrg *    rop         int     unmapped raster operation
763f29dbc25Smrg * planemask     uint     -1 (copy) or pattern data
764f29dbc25Smrg *
765f29dbc25Smrg * Returns      :none.
766f29dbc25Smrg *---------------------------------------------------------------------------*/
767f29dbc25Smrg
768f29dbc25Smrgstatic void
769f29dbc25SmrgGXSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrni,
77004007ebaSmrg                                             int fg, int bg, int rop,
77104007ebaSmrg                                             uint planemask)
772f29dbc25Smrg{
773f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR(pScrni);
774f29dbc25Smrg    ulong srcpitch;
775f29dbc25Smrg
776f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() fg %#x bg %#x rop %#x %#x\n",
77704007ebaSmrg                 __func__, fg, bg, rop, planemask));
778f29dbc25Smrg    rop &= 0x0F;
779f29dbc25Smrg    srcpitch = ((pGeode->Pitch + 31) >> 5) << 2;
780f29dbc25Smrg#ifndef OPT_ACCEL
781f29dbc25Smrg    gfx_set_solid_pattern(planemask);
782f29dbc25Smrg    gfx_set_mono_source(bg, fg, bg == -1 ? 1 : 0);
783f29dbc25Smrg    gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
784f29dbc25Smrg    gfx2_set_source_stride(srcpitch);
785f29dbc25Smrg    gfx2_set_destination_stride(pGeode->Pitch);
786f29dbc25Smrg#else
787f29dbc25Smrg    {
78804007ebaSmrg        unsigned int stride = (srcpitch << 16) | pGeode->Pitch;
78904007ebaSmrg        unsigned int ROP = BPP | (planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
79004007ebaSmrg
79104007ebaSmrg        if (bg == -1)
79204007ebaSmrg            ROP |= MGP_RM_SRC_TRANS;
79304007ebaSmrg        BLT_MODE = ((ROP ^ (ROP >> 1)) & 0x55) != 0 ?
79404007ebaSmrg            MGP_BM_SRC_MONO | MGP_BM_SRC_FB | MGP_BM_DST_REQ :
79504007ebaSmrg            MGP_BM_SRC_MONO | MGP_BM_SRC_FB;
79604007ebaSmrg        GU2_WAIT_PENDING;
79704007ebaSmrg        WRITE_GP32(MGP_RASTER_MODE, ROP);
79804007ebaSmrg        WRITE_GP32(MGP_PAT_COLOR_0, planemask);
79904007ebaSmrg        WRITE_GP32(MGP_SRC_COLOR_BG, bg);
80004007ebaSmrg        WRITE_GP32(MGP_SRC_COLOR_FG, fg);
80104007ebaSmrg        WRITE_GP32(MGP_STRIDE, stride);
802f29dbc25Smrg    }
803f29dbc25Smrg#endif
804f29dbc25Smrg}
805f29dbc25Smrg
806f29dbc25Smrg/*----------------------------------------------------------------------------
807f29dbc25Smrg * GXSubsequentScanlineCPUToScreenColorExpandFill
808f29dbc25Smrg *
809f29dbc25Smrg  Description  :see GXSetupForScanlineCPUToScreenColorExpandFill
810f29dbc25Smrg *
811f29dbc25Smrg * Parameters:
812f29dbc25Smrg *    Arg        Type     Comment
813f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
814f29dbc25Smrg *     x          int     destination x offset
815f29dbc25Smrg *     y          int     destination y offset
816f29dbc25Smrg *     w          int     fill area width (pixels)
817f29dbc25Smrg *     h          int     fill area height (pixels)
818f29dbc25Smrg *
819f29dbc25Smrg * Returns      :none
820f29dbc25Smrg *
821f29dbc25Smrg *---------------------------------------------------------------------------*/
822f29dbc25Smrgstatic void
823f29dbc25SmrgGXSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrni,
82404007ebaSmrg                                               int x, int y, int w, int h,
82504007ebaSmrg                                               int skipleft)
826f29dbc25Smrg{
827f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %dx%d %d\n",
82804007ebaSmrg                 __func__, x, y, w, h, skipleft));
829f29dbc25Smrg    gc2s.x = x;
830f29dbc25Smrg    gc2s.y = y;
831f29dbc25Smrg    gc2s.w = w;
832f29dbc25Smrg    gc2s.h = h;
833f29dbc25Smrg#ifdef OPT_ACCEL
834f29dbc25Smrg    {
835f29dbc25Smrg#if GX_ONE_LINE_AT_A_TIME
83604007ebaSmrg        unsigned int size = (gc2s.w << 16) | 1;
837f29dbc25Smrg
83804007ebaSmrg        GU2_WAIT_PENDING;
83904007ebaSmrg        WRITE_GP32(MGP_WID_HEIGHT, size);
840f29dbc25Smrg#else
84104007ebaSmrg        GeodeRec *pGeode = GEODEPTR(pScrni);
84204007ebaSmrg        unsigned int src = pGeode->AccelColorExpandBuffers[0] - pGeode->FBBase;
84304007ebaSmrg
84404007ebaSmrg        GU2_WAIT_PENDING;
84504007ebaSmrg        WRITE_GP32(MGP_SRC_OFFSET, src);
846f29dbc25Smrg#endif
847f29dbc25Smrg    }
848f29dbc25Smrg#endif
849f29dbc25Smrg}
850f29dbc25Smrg
851f29dbc25Smrg/*----------------------------------------------------------------------------
852f29dbc25Smrg * GXSubsequentColorExpandScanline
853f29dbc25Smrg *
854f29dbc25Smrg * Description  :see GXSetupForScanlineCPUToScreenColorExpandFill
855f29dbc25Smrg *
856f29dbc25Smrg *    Arg        Type     Comment
857f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
858f29dbc25Smrg *  bufno         int     scanline number in write group
859f29dbc25Smrg *
860f29dbc25Smrg * Returns      :none
861f29dbc25Smrg *----------------------------------------------------------------------------
862f29dbc25Smrg */
863f29dbc25Smrgstatic void
864f29dbc25SmrgGXSubsequentColorExpandScanline(ScrnInfoPtr pScrni, int bufno)
865f29dbc25Smrg{
866f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR(pScrni);
867f29dbc25Smrg
868f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %d\n", __func__, bufno));
869f29dbc25Smrg#ifndef OPT_ACCEL
870f29dbc25Smrg    {
871f29dbc25Smrg#if GX_ONE_LINE_AT_A_TIME
87204007ebaSmrg        ulong offset = pGeode->AccelColorExpandBuffers[bufno] - pGeode->FBBase;
87304007ebaSmrg
87404007ebaSmrg        gfx2_mono_expand_blt(offset, 0, 0, CALC_FBOFFSET(gc2s.x, gc2s.y),
87504007ebaSmrg                             gc2s.w, 1, 0);
87604007ebaSmrg        ++gc2s.y;
87704007ebaSmrg#else                           /* if GX_ONE_LINE_AT_A_TIME */
87804007ebaSmrg        ulong srcpitch;
87904007ebaSmrg        int blt_height;
88004007ebaSmrg
88104007ebaSmrg        if ((blt_height = pGeode->NoOfImgBuffers) > gc2s.h)
88204007ebaSmrg            blt_height = gc2s.h;
88304007ebaSmrg        if (++bufno < blt_height)
88404007ebaSmrg            return;
88504007ebaSmrg
88604007ebaSmrg        /* convert from bits to dwords */
88704007ebaSmrg        srcpitch = ((pGeode->Pitch + 31) >> 5) << 2;
88804007ebaSmrg        gfx2_mono_bitmap_to_screen_blt(0, 0, CALC_FBOFFSET(gc2s.x, gc2s.y),
88904007ebaSmrg                                       gc2s.w, blt_height,
89004007ebaSmrg                                       pGeode->AccelColorExpandBuffers[0],
89104007ebaSmrg                                       srcpitch);
89204007ebaSmrg        gc2s.h -= blt_height;
89304007ebaSmrg        gc2s.y += blt_height;
89404007ebaSmrg#endif                          /* if GX_ONE_LINE_AT_A_TIME */
895f29dbc25Smrg    }
89604007ebaSmrg#else                           /* ifndef OPT_ACCEL */
897f29dbc25Smrg    {
898f29dbc25Smrg#if GX_ONE_LINE_AT_A_TIME
89904007ebaSmrg        unsigned int src =
90004007ebaSmrg            pGeode->AccelColorExpandBuffers[bufno] - pGeode->FBBase;
90104007ebaSmrg        unsigned int dst = CALC_FBOFFSET(gc2s.x, gc2s.y);
90204007ebaSmrg
90304007ebaSmrg        ++gc2s.y;
90404007ebaSmrg        GU2_WAIT_PENDING;
90504007ebaSmrg        WRITE_GP32(MGP_SRC_OFFSET, src);
90604007ebaSmrg        WRITE_GP32(MGP_DST_OFFSET, dst);
90704007ebaSmrg        WRITE_GP16(MGP_BLT_MODE, BLT_MODE);
90804007ebaSmrg#else                           /* if GX_ONE_LINE_AT_A_TIME */
90904007ebaSmrg        unsigned int dst, size;
91004007ebaSmrg        int blt_height;
91104007ebaSmrg
91204007ebaSmrg        GU2_WAIT_BUSY;
91304007ebaSmrg        if ((blt_height = pGeode->NoOfImgBuffers) > gc2s.h)
91404007ebaSmrg            blt_height = gc2s.h;
91504007ebaSmrg        if (++bufno < blt_height)
91604007ebaSmrg            return;
91704007ebaSmrg        dst = CALC_FBOFFSET(gc2s.x, gc2s.y);
91804007ebaSmrg        size = (gc2s.w << 16) | blt_height;
91904007ebaSmrg        gc2s.h -= blt_height;
92004007ebaSmrg        gc2s.y += blt_height;
92104007ebaSmrg        GU2_WAIT_PENDING;
92204007ebaSmrg        WRITE_GP32(MGP_DST_OFFSET, dst);
92304007ebaSmrg        WRITE_GP32(MGP_WID_HEIGHT, size);
92404007ebaSmrg        WRITE_GP16(MGP_BLT_MODE, BLT_MODE);
92504007ebaSmrg#endif                          /* if GX_ONE_LINE_AT_A_TIME */
926f29dbc25Smrg    }
92704007ebaSmrg#endif                          /* ifndef OPT_ACCEL */
928f29dbc25Smrg}
92904007ebaSmrg#endif                          /* GX_CPU2SCREXP_SUPPORT */
930f29dbc25Smrg
931f29dbc25Smrg#if GX_SCR2SCREXP_SUPPORT
932f29dbc25Smrg/*----------------------------------------------------------------------------
933f29dbc25Smrg * GXSetupForScreenToScreenColorExpandFill
934f29dbc25Smrg *
935f29dbc25Smrg * Description  :SetupFor/Subsequent ScreenToScreenColorExpandFill and
936f29dbc25Smrg *               ColorExpandScanline routines provide an interface for
937f29dbc25Smrg *               doing expansion blits from source patterns stored in
938f29dbc25Smrg *               video memory.
939f29dbc25Smrg *
940f29dbc25Smrg *    Arg        Type     Comment
941f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
942f29dbc25Smrg *     fg         int     foreground color
943f29dbc25Smrg *     bg         int     -1 (transparent) or background color
944f29dbc25Smrg *    rop         int     unmapped raster operation
945f29dbc25Smrg * planemask     uint     -1 (copy) or pattern data
946f29dbc25Smrg *
947f29dbc25Smrg * Returns      :none.
948f29dbc25Smrg *---------------------------------------------------------------------------*/
949f29dbc25Smrg
950f29dbc25Smrgstatic void
951f29dbc25SmrgGXSetupForScreenToScreenColorExpandFill(ScrnInfoPtr pScrni, int fg, int bg,
95204007ebaSmrg                                        int rop, uint planemask)
953f29dbc25Smrg{
954f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() fg %#x bg %#x rop %#x %#x\n",
95504007ebaSmrg                 __func__, fg, bg, rop, planemask));
956f29dbc25Smrg    rop &= 0x0F;
957f29dbc25Smrg#ifndef OPT_ACCEL
958f29dbc25Smrg    {
95904007ebaSmrg        GeodeRec *pGeode = GEODEPTR(pScrni);
960f29dbc25Smrg
96104007ebaSmrg        gfx_set_solid_pattern(planemask);
96204007ebaSmrg        gfx_set_mono_source(bg, fg, bg == -1 ? 1 : 0);
96304007ebaSmrg        gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
96404007ebaSmrg        gfx2_set_source_stride(pGeode->Pitch);
96504007ebaSmrg        gfx2_set_destination_stride(pGeode->Pitch);
966f29dbc25Smrg    }
967f29dbc25Smrg#else
968f29dbc25Smrg    {
96904007ebaSmrg        unsigned int ROP = BPP | (planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
97004007ebaSmrg
97104007ebaSmrg        if (bg == -1)
97204007ebaSmrg            ROP |= MGP_RM_SRC_TRANS;
97304007ebaSmrg        BLT_MODE = ((ROP ^ (ROP >> 1)) & 0x55) != 0 ?
97404007ebaSmrg            MGP_BM_SRC_MONO | MGP_BM_SRC_FB | MGP_BM_DST_REQ :
97504007ebaSmrg            MGP_BM_SRC_MONO | MGP_BM_SRC_FB;
97604007ebaSmrg        GU2_WAIT_PENDING;
97704007ebaSmrg        WRITE_GP32(MGP_RASTER_MODE, ROP);
97804007ebaSmrg        WRITE_GP32(MGP_PAT_COLOR_0, planemask);
97904007ebaSmrg        WRITE_GP32(MGP_SRC_COLOR_BG, bg);
98004007ebaSmrg        WRITE_GP32(MGP_SRC_COLOR_FG, fg);
98104007ebaSmrg        WRITE_GP32(MGP_STRIDE, ACCEL_STRIDE);
982f29dbc25Smrg    }
983f29dbc25Smrg#endif
984f29dbc25Smrg}
985f29dbc25Smrg
986f29dbc25Smrg/*----------------------------------------------------------------------------
987f29dbc25Smrg * GXSubsequentScreenToScreenColorExpandFill
988f29dbc25Smrg *
989f29dbc25Smrg * Description  :see GXSetupForScreenToScreenColorExpandFill
990f29dbc25Smrg *
991f29dbc25Smrg * Parameters:
992f29dbc25Smrg *    Arg        Type     Comment
993f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
994f29dbc25Smrg *     x          int     destination x offset
995f29dbc25Smrg *     y          int     destination y offset
996f29dbc25Smrg *     w          int     fill area width (pixels)
997f29dbc25Smrg *     h          int     fill area height (pixels)
998f29dbc25Smrg * offset         int     initial x offset
999f29dbc25Smrg *
1000f29dbc25Smrg * Returns      :none
1001f29dbc25Smrg *
1002f29dbc25Smrg *---------------------------------------------------------------------------*/
1003f29dbc25Smrgstatic void
1004f29dbc25SmrgGXSubsequentScreenToScreenColorExpandFill(ScrnInfoPtr pScrni,
100504007ebaSmrg                                          int x, int y, int w, int h, int srcx,
100604007ebaSmrg                                          int srcy, int offset)
1007f29dbc25Smrg{
1008f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %dx%d %d,%d %d\n",
100904007ebaSmrg                 __func__, x, y, w, h, srcx, srcy, offset));
1010f29dbc25Smrg#ifndef OPT_ACCEL
1011f29dbc25Smrg    gfx2_mono_expand_blt(CALC_FBOFFSET(srcx, srcy), offset, 0,
101204007ebaSmrg                         CALC_FBOFFSET(x, y), w, h, 0);
1013f29dbc25Smrg#else
1014f29dbc25Smrg    {
101504007ebaSmrg        unsigned int src = (CALC_FBOFFSET(srcx,
101604007ebaSmrg                                          srcy) +
101704007ebaSmrg                            (offset >> 3)) | ((offset & 7) << 26);
101804007ebaSmrg        unsigned int dst = CALC_FBOFFSET(x, y);
101904007ebaSmrg        unsigned int size = (w << 16) | h;
102004007ebaSmrg
102104007ebaSmrg        GU2_WAIT_PENDING;
102204007ebaSmrg        WRITE_GP32(MGP_SRC_OFFSET, src);
102304007ebaSmrg        WRITE_GP32(MGP_DST_OFFSET, dst);
102404007ebaSmrg        WRITE_GP32(MGP_WID_HEIGHT, size);
102504007ebaSmrg        WRITE_GP16(MGP_BLT_MODE, BLT_MODE);
1026f29dbc25Smrg    }
1027f29dbc25Smrg#endif
1028f29dbc25Smrg}
102904007ebaSmrg#endif                          /* GX_SCR2SCREXP_SUPPORT */
1030f29dbc25Smrg
1031f29dbc25Smrg#define VM_MAJOR_DEC 0
1032f29dbc25Smrg#define VM_MINOR_DEC 0
1033f29dbc25Smrg
1034f29dbc25Smrgstatic unsigned short vmode[] = {
1035f29dbc25Smrg    VM_X_MAJOR | VM_MAJOR_INC | VM_MINOR_INC,
1036f29dbc25Smrg    /* !XDECREASING !YDECREASING !YMAJOR */
1037f29dbc25Smrg    VM_Y_MAJOR | VM_MAJOR_INC | VM_MINOR_INC,
1038f29dbc25Smrg    /* !XDECREASING !YDECREASING  YMAJOR */
1039f29dbc25Smrg    VM_X_MAJOR | VM_MAJOR_INC | VM_MINOR_DEC,
1040f29dbc25Smrg    /* !XDECREASING  YDECREASING !YMAJOR */
1041f29dbc25Smrg    VM_Y_MAJOR | VM_MAJOR_DEC | VM_MINOR_INC,
1042f29dbc25Smrg    /* !XDECREASING  YDECREASING  YMAJOR */
1043f29dbc25Smrg    VM_X_MAJOR | VM_MAJOR_DEC | VM_MINOR_INC,
1044f29dbc25Smrg    /*  XDECREASING !YDECREASING !YMAJOR */
1045f29dbc25Smrg    VM_Y_MAJOR | VM_MAJOR_INC | VM_MINOR_DEC,
1046f29dbc25Smrg    /*  XDECREASING !YDECREASING  YMAJOR */
1047f29dbc25Smrg    VM_X_MAJOR | VM_MAJOR_DEC | VM_MINOR_DEC,
1048f29dbc25Smrg    /*  XDECREASING  YDECREASING !YMAJOR */
1049f29dbc25Smrg    VM_Y_MAJOR | VM_MAJOR_DEC | VM_MINOR_DEC,
1050f29dbc25Smrg    /*  XDECREASING  YDECREASING  YMAJOR */
1051f29dbc25Smrg};
1052f29dbc25Smrg
1053f29dbc25Smrg#if GX_BRES_LINE_SUPPORT
1054f29dbc25Smrg/*----------------------------------------------------------------------------
1055f29dbc25Smrg * GXSetupForSolidLine
1056f29dbc25Smrg *
1057f29dbc25Smrg * Description  :SetupForSolidLine and Subsequent HorVertLine TwoPointLine
1058f29dbc25Smrg *               BresenhamLine provides an interface for drawing thin
1059f29dbc25Smrg *               solid lines.
1060f29dbc25Smrg *
1061f29dbc25Smrg *    Arg        Type     Comment
1062f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
1063f29dbc25Smrg *   color        int     foreground fill color
1064f29dbc25Smrg *    rop         int     unmapped raster op
1065f29dbc25Smrg * planemask     uint     -1 (fill) or pattern data (not enabled)
1066f29dbc25Smrg *
1067f29dbc25Smrg * Returns		:none
1068f29dbc25Smrg *---------------------------------------------------------------------------*/
1069f29dbc25Smrgstatic void
1070f29dbc25SmrgGXSetupForSolidLine(ScrnInfoPtr pScrni, int color, int rop, uint planemask)
1071f29dbc25Smrg{
1072f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %#x %#x %#x\n",
107304007ebaSmrg                 __func__, color, rop, planemask));
1074f29dbc25Smrg    rop &= 0x0F;
1075f29dbc25Smrg#ifndef OPT_ACCEL
1076f29dbc25Smrg    gfx_set_solid_pattern(color);
1077f29dbc25Smrg    gfx_set_raster_operation(planemask == ~0U ? PDfn[rop] :
107804007ebaSmrg                             (gfx_set_solid_source(planemask), PDfn_SM[rop]));
1079f29dbc25Smrg#else
1080f29dbc25Smrg    {
108104007ebaSmrg        unsigned int ROP = BPP | (planemask == ~0U ? PDfn[rop] : PDfn_SM[rop]);
108204007ebaSmrg
108304007ebaSmrg        BLT_MODE = ((ROP ^ (ROP >> 2)) & 0x33) == 0 ? MGP_BM_SRC_MONO : 0;
108404007ebaSmrg        VEC_MODE = ((ROP ^ (ROP >> 1)) & 0x55) != 0 ? ((BLT_MODE |=
108504007ebaSmrg                                                        MGP_BM_DST_REQ),
108604007ebaSmrg                                                       MGP_VM_DST_REQ) : 0;
108704007ebaSmrg        GU2_WAIT_PENDING;
108804007ebaSmrg        WRITE_GP32(MGP_RASTER_MODE, ROP);
108904007ebaSmrg        WRITE_GP32(MGP_PAT_COLOR_0, color);
109004007ebaSmrg        WRITE_GP32(MGP_SRC_COLOR_FG, planemask);
109104007ebaSmrg        WRITE_GP32(MGP_STRIDE, ACCEL_STRIDE);
1092f29dbc25Smrg    }
1093f29dbc25Smrg#endif
1094f29dbc25Smrg}
1095f29dbc25Smrg
1096f29dbc25Smrg/*---------------------------------------------------------------------------
1097f29dbc25Smrg * GXSubsequentSolidBresenhamLine
1098f29dbc25Smrg *
1099f29dbc25Smrg * Description  :see GXSetupForSolidLine
1100f29dbc25Smrg *
1101f29dbc25Smrg *    Arg        Type     Comment
1102f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
1103f29dbc25Smrg *     x1         int     destination x offset
1104f29dbc25Smrg *     y1         int     destination y offset
1105f29dbc25Smrg * absmaj         int     Bresenman absolute major
1106f29dbc25Smrg * absmin         int     Bresenman absolute minor
1107f29dbc25Smrg *    err         int     Bresenman initial error term
1108f29dbc25Smrg *    len         int     length of the vector (pixels)
1109f29dbc25Smrg * octant         int     specifies sign and magnitude relationships
1110f29dbc25Smrg *                         used to determine axis of magor rendering
1111f29dbc25Smrg *                         and direction of vector progress.
1112f29dbc25Smrg *
1113f29dbc25Smrg * Returns      :none
1114f29dbc25Smrg *
1115f29dbc25Smrg *   - Window outlines on window move.
1116f29dbc25Smrg *   - x11perf: line segments (-line500).
1117f29dbc25Smrg *   - x11perf: line segments (-seg500).
1118f29dbc25Smrg *---------------------------------------------------------------------------*/
1119f29dbc25Smrgstatic void
1120f29dbc25SmrgGXSubsequentSolidBresenhamLine(ScrnInfoPtr pScrni, int x1, int y1,
112104007ebaSmrg                               int absmaj, int absmin, int err, int len,
112204007ebaSmrg                               int octant)
1123f29dbc25Smrg{
1124f29dbc25Smrg    long axial, diagn;
1125f29dbc25Smrg
1126f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %d %d, %d %d, %d\n",
112704007ebaSmrg                 __func__, x1, y1, absmaj, absmin, err, len, octant));
1128f29dbc25Smrg    if (len <= 0)
112904007ebaSmrg        return;
1130f29dbc25Smrg    axial = absmin;
1131f29dbc25Smrg    err += axial;
1132f29dbc25Smrg    diagn = absmin - absmaj;
1133f29dbc25Smrg#ifndef OPT_ACCEL
1134f29dbc25Smrg    gfx_bresenham_line(x1, y1, len, err, axial, diagn, vmode[octant]);
1135f29dbc25Smrg#else
1136f29dbc25Smrg    {
113704007ebaSmrg        unsigned int offset = CALC_FBOFFSET(x1, y1);
113804007ebaSmrg        unsigned int vec_err = (axial << 16) | (unsigned short) diagn;
113904007ebaSmrg        unsigned int vec_len = (len << 16) | (unsigned short) err;
114004007ebaSmrg        unsigned int vec_mode = VEC_MODE | vmode[octant];
114104007ebaSmrg
114204007ebaSmrg        GU2_WAIT_PENDING;
114304007ebaSmrg        WRITE_GP32(MGP_DST_OFFSET, offset);
114404007ebaSmrg        WRITE_GP32(MGP_VEC_ERR, vec_err);
114504007ebaSmrg        WRITE_GP32(MGP_VEC_LEN, vec_len);
114604007ebaSmrg        WRITE_GP32(MGP_VECTOR_MODE, vec_mode);
1147f29dbc25Smrg    }
1148f29dbc25Smrg#endif
1149f29dbc25Smrg}
1150f29dbc25Smrg
1151f29dbc25Smrg/*---------------------------------------------------------------------------
1152f29dbc25Smrg * GXSubsequentSolidTwoPointLine
1153f29dbc25Smrg *
1154f29dbc25Smrg * Description  :see GXSetupForSolidLine
1155f29dbc25Smrg *
1156f29dbc25Smrg *    Arg        Type     Comment
1157f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
1158f29dbc25Smrg *     x0         int     destination x start offset
1159f29dbc25Smrg *     y0         int     destination y start offset
1160f29dbc25Smrg *     x1         int     destination x end offset
1161f29dbc25Smrg *     y1         int     destination y end offset
1162f29dbc25Smrg *  flags         int     OMIT_LAST, dont draw last pixel (not used)
1163f29dbc25Smrg *
1164f29dbc25Smrg * Returns      :none
1165f29dbc25Smrg *---------------------------------------------------------------------------*/
1166f29dbc25Smrgstatic void
1167f29dbc25SmrgGXSubsequentSolidTwoPointLine(ScrnInfoPtr pScrni, int x0, int y0,
116804007ebaSmrg                              int x1, int y1, int flags)
1169f29dbc25Smrg{
1170f29dbc25Smrg    long dx, dy, dmaj, dmin, octant, bias;
1171f29dbc25Smrg    long axial, diagn, err, len;
1172f29dbc25Smrg
1173f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %d,%d, %#x\n",
117404007ebaSmrg                 __func__, x0, y0, x1, y1, flags));
1175f29dbc25Smrg
1176f29dbc25Smrg    if ((dx = x1 - x0) < 0)
117704007ebaSmrg        dx = -dx;
1178f29dbc25Smrg    if ((dy = y1 - y0) < 0)
117904007ebaSmrg        dy = -dy;
1180f29dbc25Smrg    if (dy >= dx) {
118104007ebaSmrg        dmaj = dy;
118204007ebaSmrg        dmin = dx;
118304007ebaSmrg        octant = YMAJOR;
118404007ebaSmrg    }
118504007ebaSmrg    else {
118604007ebaSmrg        dmaj = dx;
118704007ebaSmrg        dmin = dy;
118804007ebaSmrg        octant = 0;
1189f29dbc25Smrg    }
1190f29dbc25Smrg    len = dmaj;
1191f29dbc25Smrg    if ((flags & OMIT_LAST) == 0)
119204007ebaSmrg        ++len;
1193f29dbc25Smrg    if (len <= 0)
119404007ebaSmrg        return;
1195f29dbc25Smrg    if (x1 < x0)
119604007ebaSmrg        octant |= XDECREASING;
1197f29dbc25Smrg    if (y1 < y0)
119804007ebaSmrg        octant |= YDECREASING;
1199f29dbc25Smrg
1200f29dbc25Smrg    axial = dmin << 1;
1201f29dbc25Smrg    bias = miGetZeroLineBias(pScrni->pScreen);
1202f29dbc25Smrg    err = axial - dmaj - ((bias >> octant) & 1);
1203f29dbc25Smrg    diagn = (dmin - dmaj) << 1;
1204f29dbc25Smrg
1205f29dbc25Smrg#ifndef OPT_ACCEL
1206f29dbc25Smrg    gfx_bresenham_line(x0, y0, len, err, axial, diagn, vmode[octant]);
1207f29dbc25Smrg#else
1208f29dbc25Smrg    {
120904007ebaSmrg        unsigned int offset = CALC_FBOFFSET(x0, y0);
121004007ebaSmrg        unsigned int vec_err = (axial << 16) | (unsigned short) diagn;
121104007ebaSmrg        unsigned int vec_len = (len << 16) | (unsigned short) err;
121204007ebaSmrg        unsigned int vec_mode = VEC_MODE | vmode[octant];
121304007ebaSmrg
121404007ebaSmrg        GU2_WAIT_PENDING;
121504007ebaSmrg        WRITE_GP32(MGP_DST_OFFSET, offset);
121604007ebaSmrg        WRITE_GP32(MGP_VEC_ERR, vec_err);
121704007ebaSmrg        WRITE_GP32(MGP_VEC_LEN, vec_len);
121804007ebaSmrg        WRITE_GP32(MGP_VECTOR_MODE, vec_mode);
1219f29dbc25Smrg    }
1220f29dbc25Smrg#endif
1221f29dbc25Smrg}
1222f29dbc25Smrg
1223f29dbc25Smrg/*---------------------------------------------------------------------------
1224f29dbc25Smrg * GXSubsequentSolidHorVertLine
1225f29dbc25Smrg *
1226f29dbc25Smrg * Description  :see GXSetupForSolidLine
1227f29dbc25Smrg *
1228f29dbc25Smrg *    Arg        Type     Comment
1229f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
1230f29dbc25Smrg *     x          int     destination x offset
1231f29dbc25Smrg *     y          int     destination y offset
1232f29dbc25Smrg *    len         int     length of the vector (pixels)
1233f29dbc25Smrg *    dir         int     DEGREES_270 or DEGREES_0 line direction
1234f29dbc25Smrg *
1235f29dbc25Smrg * Sample application uses:
1236f29dbc25Smrg *   - Window outlines on window move.
1237f29dbc25Smrg *   - x11perf: line segments (-hseg500).
1238f29dbc25Smrg *   - x11perf: line segments (-vseg500).
1239f29dbc25Smrg *---------------------------------------------------------------------------
1240f29dbc25Smrg */
1241f29dbc25Smrgstatic void
124204007ebaSmrgGXSubsequentSolidHorVertLine(ScrnInfoPtr pScrni, int x, int y, int len, int dir)
1243f29dbc25Smrg{
1244f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %d %d\n", __func__, x, y, len, dir));
1245f29dbc25Smrg#ifndef OPT_ACCEL
1246f29dbc25Smrg    if (dir == DEGREES_0)
124704007ebaSmrg        gfx_pattern_fill(x, y, len, 1);
1248f29dbc25Smrg    else
124904007ebaSmrg        gfx_pattern_fill(x, y, 1, len);
1250f29dbc25Smrg#else
1251f29dbc25Smrg    {
125204007ebaSmrg        unsigned int offset = CALC_FBOFFSET(x, y);
125304007ebaSmrg        unsigned int size =
125404007ebaSmrg            dir == DEGREES_0 ? (len << 16) | 1 : (1 << 16) | len;
125504007ebaSmrg        GU2_WAIT_PENDING;
125604007ebaSmrg        WRITE_GP32(MGP_DST_OFFSET, offset);
125704007ebaSmrg        WRITE_GP32(MGP_WID_HEIGHT, size);
125804007ebaSmrg        WRITE_GP32(MGP_BLT_MODE, BLT_MODE);
1259f29dbc25Smrg    }
1260f29dbc25Smrg#endif
1261f29dbc25Smrg}
126204007ebaSmrg#endif                          /* GX_BRES_LINE_SUPPORT */
1263f29dbc25Smrg
1264f29dbc25Smrg#if GX_DASH_LINE_SUPPORT
1265f29dbc25Smrg/*----------------------------------------------------------------------------
1266f29dbc25Smrg * GXSetupForDashedLine
1267f29dbc25Smrg *
1268f29dbc25Smrg * Description  :SetupForDashedLine and Subsequent TwoPointLine
1269f29dbc25Smrg *               BresenhamLine provides an interface for drawing thin
1270f29dbc25Smrg *               dashed lines.
1271f29dbc25Smrg *
1272f29dbc25Smrg *    Arg        Type     Comment
1273f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
1274f29dbc25Smrg *     fg         int     foreground fill color
1275f29dbc25Smrg *     bg         int     -1 (transp) or background fill color
1276f29dbc25Smrg *    rop         int     unmapped raster op
1277f29dbc25Smrg * planemask     uint     -1 (fill) or pattern data (not enabled)
1278f29dbc25Smrg *  length        int     pattern length (bits)
1279f29dbc25Smrg * pattern     uchar*     dash pattern mask
1280f29dbc25Smrg *
1281f29dbc25Smrg * Returns              :none
1282f29dbc25Smrg *---------------------------------------------------------------------------*/
1283f29dbc25Smrgstatic void
1284f29dbc25SmrgGXSetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop,
128504007ebaSmrg                     unsigned int planemask, int length, unsigned char *pattern)
1286f29dbc25Smrg{
1287f29dbc25Smrg    int i, l, n, m;
1288f29dbc25Smrg    CARD32 pat = *pattern;
1289f29dbc25Smrg    CARD32 pat8x8[2];
1290f29dbc25Smrg
1291f29dbc25Smrg    if (length <= 0)
129204007ebaSmrg        return;
1293f29dbc25Smrg    i = l = m = 0;
1294f29dbc25Smrg    while (i < 2) {
129504007ebaSmrg        m |= pat >> l;
129604007ebaSmrg        l += length;
129704007ebaSmrg        if ((n = l - 32) >= 0) {
129804007ebaSmrg            pat8x8[i++] = m;
129904007ebaSmrg            m = pat << (length - n);
130004007ebaSmrg            l = n;
130104007ebaSmrg        }
1302f29dbc25Smrg    }
1303f29dbc25Smrg    gdln.pat[0] = pat8x8[0];
1304f29dbc25Smrg    gdln.pat[1] = pat8x8[1];
1305f29dbc25Smrg    gdln.len = length;
1306f29dbc25Smrg    gdln.fg = fg;
1307f29dbc25Smrg    gdln.bg = bg;
1308f29dbc25Smrg    rop &= 0x0F;
1309f29dbc25Smrg    gfx_set_solid_pattern(0);
1310f29dbc25Smrg    gfx_set_raster_operation(planemask == ~0U ? PDfn[rop] :
131104007ebaSmrg                             (gfx_set_solid_source(planemask), PDfn_SM[rop]));
1312f29dbc25Smrg}
1313f29dbc25Smrg
1314f29dbc25Smrg/*---------------------------------------------------------------------------
1315f29dbc25Smrg * GXSubsequentDashedBresenhamLine
1316f29dbc25Smrg *
1317f29dbc25Smrg * Description:		This function is used to render a vector using the
1318f29dbc25Smrg *                 	specified bresenham parameters.
1319f29dbc25Smrg *
1320f29dbc25Smrg * Parameters:
1321f29dbc25Smrg *		pScrni:		Screen handler pointer having screen information.
1322f29dbc25Smrg *      x1:  		Specifies the starting x position
1323f29dbc25Smrg *      y1:      	Specifies starting y possition
1324f29dbc25Smrg *      absmaj:		Specfies the Bresenman absolute major.
1325f29dbc25Smrg *		absmin:		Specfies the Bresenman absolute minor.
1326f29dbc25Smrg *		err:     	Specifies the bresenham err term.
1327f29dbc25Smrg *		len:     	Specifies the length of the vector interms of pixels.
1328f29dbc25Smrg *		octant:  	not used in this function,may be added for standard
1329f29dbc25Smrg *               	interface.
1330f29dbc25Smrg *
1331f29dbc25Smrg * Returns:			none
1332f29dbc25Smrg *
1333f29dbc25Smrg * Comments:		none
1334f29dbc25Smrg *
1335f29dbc25Smrg * Sample application uses:
1336f29dbc25Smrg *   - Window outlines on window move.
1337f29dbc25Smrg *   - x11perf: line segments (-line500).
1338f29dbc25Smrg *   - x11perf: line segments (-seg500).
1339f29dbc25Smrg *----------------------------------------------------------------------------
1340f29dbc25Smrg */
1341f29dbc25Smrgstatic void
1342f29dbc25SmrgGXSubsequentDashedBresenhamLine(ScrnInfoPtr pScrni,
134304007ebaSmrg                                int x1, int y1, int absmaj, int absmin,
134404007ebaSmrg                                int err, int len, int octant, int phase)
1345f29dbc25Smrg{
1346f29dbc25Smrg    int i, n;
1347f29dbc25Smrg    int axial, diagn;
1348f29dbc25Smrg    int trans = (gdln.bg == -1);
1349f29dbc25Smrg    unsigned long pat8x8[2];
1350f29dbc25Smrg
1351f29dbc25Smrg    //ErrorF("BLine %d, %d, %d, %d, %d, %d, %d\n" x1, y1, absmaj, absmin,
1352f29dbc25Smrg    //err, len, octant);
1353f29dbc25Smrg
1354f29dbc25Smrg    i = phase >= 32 ? (phase -= 32, 1) : 0;
1355f29dbc25Smrg    n = 32 - phase;
1356f29dbc25Smrg    pat8x8[0] =
135704007ebaSmrg        ((gdln.pat[i] >> phase) & ((1UL << n) - 1)) | (gdln.pat[1 - i] << n);
1358f29dbc25Smrg    pat8x8[1] =
135904007ebaSmrg        ((gdln.pat[1 - i] >> phase) & ((1UL << n) - 1)) | (gdln.pat[i] << n);
1360f29dbc25Smrg    axial = absmin;
1361f29dbc25Smrg    err += axial;
1362f29dbc25Smrg    diagn = absmin - absmaj;
1363f29dbc25Smrg    gfx_set_mono_pattern(gdln.bg, gdln.fg, pat8x8[0], pat8x8[1], trans);
1364f29dbc25Smrg    gfx2_set_pattern_origin(x1, y1);
1365f29dbc25Smrg    gfx2_bresenham_line(CALC_FBOFFSET(x1, y1), len, err, axial, diagn,
136604007ebaSmrg                        vmode[octant]);
1367f29dbc25Smrg}
1368f29dbc25Smrg
1369f29dbc25Smrg/*---------------------------------------------------------------------------
1370f29dbc25Smrg * GXSubsequentDashedTwoPointLine
1371f29dbc25Smrg *
1372f29dbc25Smrg * Description  :see GXSetupForDashedLine
1373f29dbc25Smrg *
1374f29dbc25Smrg *    Arg        Type     Comment
1375f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
1376f29dbc25Smrg *     x0         int     destination x start offset
1377f29dbc25Smrg *     y0         int     destination y start offset
1378f29dbc25Smrg *     x1         int     destination x end offset
1379f29dbc25Smrg *     y1         int     destination y end offset
1380f29dbc25Smrg *  flags         int     OMIT_LAST, dont draw last pixel (not used)
1381f29dbc25Smrg *  phase         int     initial pattern offset at x1,y1
1382f29dbc25Smrg *
1383f29dbc25Smrg * Returns      :none
1384f29dbc25Smrg *---------------------------------------------------------------------------*/
1385f29dbc25Smrgstatic void
1386f29dbc25SmrgGXSubsequentDashedTwoPointLine(ScrnInfoPtr pScrni, int x0, int y0,
138704007ebaSmrg                               int x1, int y1, int flags, int phase)
1388f29dbc25Smrg{
1389f29dbc25Smrg    int i, n;
1390f29dbc25Smrg    long dx, dy, dmaj, dmin, octant, bias;
1391f29dbc25Smrg    long axial, diagn, err, len, pat8x8[2];
1392f29dbc25Smrg
1393f29dbc25Smrg    //ErrorF("GXSubsequentDashedTwoPointLine() %d,%d %d,%d, %#x %d\n",
1394f29dbc25Smrg    //   x0, y0, x1, y1, flags, phase);
1395f29dbc25Smrg
1396f29dbc25Smrg    i = phase >= 32 ? (phase -= 32, 1) : 0;
1397f29dbc25Smrg    n = 32 - phase;
1398f29dbc25Smrg    pat8x8[0] =
139904007ebaSmrg        ((gdln.pat[i] >> phase) & ((1UL << n) - 1)) | (gdln.pat[1 - i] << n);
1400f29dbc25Smrg    pat8x8[1] =
140104007ebaSmrg        ((gdln.pat[1 - i] >> phase) & ((1UL << n) - 1)) | (gdln.pat[i] << n);
1402f29dbc25Smrg
1403f29dbc25Smrg    if ((dx = x1 - x0) < 0)
140404007ebaSmrg        dx = -dx;
1405f29dbc25Smrg    if ((dy = y1 - y0) < 0)
140604007ebaSmrg        dy = -dy;
1407f29dbc25Smrg    if (dy >= dx) {
140804007ebaSmrg        dmaj = dy;
140904007ebaSmrg        dmin = dx;
141004007ebaSmrg        octant = YMAJOR;
141104007ebaSmrg    }
141204007ebaSmrg    else {
141304007ebaSmrg        dmaj = dx;
141404007ebaSmrg        dmin = dy;
141504007ebaSmrg        octant = 0;
1416f29dbc25Smrg    }
1417f29dbc25Smrg    len = dmaj;
1418f29dbc25Smrg    if ((flags & OMIT_LAST) == 0)
141904007ebaSmrg        ++len;
1420f29dbc25Smrg    if (len <= 0)
142104007ebaSmrg        return;
1422f29dbc25Smrg    if (x1 < x0)
142304007ebaSmrg        octant |= XDECREASING;
1424f29dbc25Smrg    if (y1 < y0)
142504007ebaSmrg        octant |= YDECREASING;
1426f29dbc25Smrg
1427f29dbc25Smrg    axial = dmin << 1;
1428f29dbc25Smrg    bias = miGetZeroLineBias(pScrni->pScreen);
1429f29dbc25Smrg    err = axial - dmaj - ((bias >> octant) & 1);
1430f29dbc25Smrg    diagn = (dmin - dmaj) << 1;
1431f29dbc25Smrg
1432f29dbc25Smrg    gfx2_set_pattern_origin(x0, y0);
1433f29dbc25Smrg    gfx2_bresenham_line(CALC_FBOFFSET(x0, y0), len, err, axial, diagn,
143404007ebaSmrg                        vmode[octant]);
1435f29dbc25Smrg
1436f29dbc25Smrg}
143704007ebaSmrg#endif                          /* GX_DASH_LINE_SUPPORT */
1438f29dbc25Smrg
1439f29dbc25Smrg#if GX_WRITE_PIXMAP_SUPPORT
1440f29dbc25Smrgstatic void
1441f29dbc25SmrgGXWritePixmap(ScrnInfoPtr pScrni, int x, int y, int w, int h,
144204007ebaSmrg              unsigned char *src, int srcwidth, int rop, unsigned int planemask,
144304007ebaSmrg              int trans, int bpp, int depth)
1444f29dbc25Smrg{
1445f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR(pScrni);
1446f29dbc25Smrg
1447f29dbc25Smrg    //ErrorF("GXWritePixmap() %d,%d %dx%d, s%#x sp%d %#x %#x %#x %d %d\n",
1448f29dbc25Smrg    //    x, y, w, h, src, srcwidth, rop, planemask, trans, bpp, depth);
1449f29dbc25Smrg
1450f29dbc25Smrg    if (bpp == pScrni->bitsPerPixel) {
145104007ebaSmrg        rop &= 0x0F;
145204007ebaSmrg        if (rop == GXcopy && trans == -1) {
145304007ebaSmrg            gfx_wait_until_idle();
145404007ebaSmrg            geode_memory_to_screen_blt((unsigned long) src,
145504007ebaSmrg                                       (unsigned long) FBADDR(x, y), srcwidth,
145604007ebaSmrg                                       pGeode->Pitch, w, h, bpp);
145704007ebaSmrg        }
145804007ebaSmrg        else {
145904007ebaSmrg            gfx_set_solid_pattern(planemask);
146004007ebaSmrg            gfx_set_raster_operation(planemask ==
146104007ebaSmrg                                     ~0U ? SDfn[rop] : SDfn_PM[rop]);
146204007ebaSmrg            if (trans != -1)
146304007ebaSmrg                gfx_color_bitmap_to_screen_xblt(0, 0, x, y, w, h, src,
146404007ebaSmrg                                                srcwidth, trans);
146504007ebaSmrg            else
146604007ebaSmrg                gfx_color_bitmap_to_screen_blt(0, 0, x, y, w, h, src, srcwidth);
146704007ebaSmrg            SET_SYNC_FLAG(pGeode->AccelInfoRec);
146804007ebaSmrg        }
146904007ebaSmrg    }
147004007ebaSmrg    else
147104007ebaSmrg        pGeode->WritePixmap(pScrni, x, y, w, h, src, srcwidth, rop, planemask,
147204007ebaSmrg                            trans, bpp, depth);
1473f29dbc25Smrg}
147404007ebaSmrg#endif                          /* if GX_WRITE_PIXMAP_SUPPORT */
1475f29dbc25Smrg
1476f29dbc25Smrg#if XF86EXA
1477f29dbc25Smrg
1478f29dbc25Smrgstatic void
1479f29dbc25Smrgamd_gx_exa_WaitMarker(ScreenPtr pScreen, int Marker)
1480f29dbc25Smrg{
1481f29dbc25Smrg    GU2_WAIT_BUSY;
1482f29dbc25Smrg}
1483f29dbc25Smrg
1484f29dbc25Smrgstatic void
1485f29dbc25Smrgamd_gx_exa_Done(PixmapPtr p)
1486f29dbc25Smrg{
1487f29dbc25Smrg}
1488f29dbc25Smrg
1489f29dbc25Smrgstatic Bool
1490f29dbc25Smrgamd_gx_exa_UploadToScreen(PixmapPtr pDst, int x, int y, int w, int h,
149104007ebaSmrg                          char *src, int src_pitch)
1492f29dbc25Smrg{
149344802259Smrg    GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pDst);
149444802259Smrg    char *dst = pGeode->pExa->memoryBase + exaGetPixmapOffset(pDst);
1495f29dbc25Smrg    int dst_pitch = exaGetPixmapPitch(pDst);
1496f29dbc25Smrg    int bpp = pDst->drawable.bitsPerPixel;
1497f29dbc25Smrg
1498f29dbc25Smrg    dst += y * dst_pitch + x * (bpp >> 3);
1499f29dbc25Smrg    GU2_WAIT_BUSY;
150004007ebaSmrg    geode_memory_to_screen_blt((unsigned long) src, (unsigned long) dst,
150104007ebaSmrg                               src_pitch, dst_pitch, w, h, bpp);
1502f29dbc25Smrg    return TRUE;
1503f29dbc25Smrg}
1504f29dbc25Smrg
1505f29dbc25Smrgstatic Bool
1506f29dbc25Smrgamd_gx_exa_DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h,
150704007ebaSmrg                              char *dst, int dst_pitch)
1508f29dbc25Smrg{
150944802259Smrg    GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pSrc);
151044802259Smrg    char *src = pGeode->pExa->memoryBase + exaGetPixmapOffset(pSrc);
1511f29dbc25Smrg    int src_pitch = exaGetPixmapPitch(pSrc);
1512f29dbc25Smrg    int bpp = pSrc->drawable.bitsPerPixel;
1513f29dbc25Smrg
1514f29dbc25Smrg    src += (y * src_pitch) + (x * (bpp >> 3));
1515f29dbc25Smrg    GU2_WAIT_BUSY;
151604007ebaSmrg    geode_memory_to_screen_blt((unsigned long) src, (unsigned long) dst,
151704007ebaSmrg                               src_pitch, dst_pitch, w, h, bpp);
1518f29dbc25Smrg    return TRUE;
1519f29dbc25Smrg}
1520f29dbc25Smrg
1521f29dbc25Smrg/* Solid */
1522f29dbc25Smrg
1523f29dbc25Smrgstatic Bool
1524f29dbc25Smrgamd_gx_exa_PrepareSolid(PixmapPtr pxMap, int alu, Pixel planemask, Pixel fg)
1525f29dbc25Smrg{
1526f29dbc25Smrg    int dstPitch = exaGetPixmapPitch(pxMap);
1527f29dbc25Smrg    unsigned int ROP = amd_gx_BppToRasterMode(pxMap->drawable.bitsPerPixel)
152804007ebaSmrg        | (planemask == ~0U ? SDfn[alu] : SDfn_PM[alu]);
1529f29dbc25Smrg
1530f29dbc25Smrg    //  FIXME: this should go away -- workaround for the blockparty icon corruption
1531f29dbc25Smrg    //if (pxMap->drawable.bitsPerPixel == 32)
1532f29dbc25Smrg    //  return FALSE;
1533f29dbc25Smrg
1534f29dbc25Smrg    BLT_MODE = ((ROP ^ (ROP >> 2)) & 0x33) == 0 ? MGP_BM_SRC_MONO : 0;
1535f29dbc25Smrg    if (((ROP ^ (ROP >> 1)) & 0x55) != 0)
153604007ebaSmrg        BLT_MODE |= MGP_BM_DST_REQ;
1537f29dbc25Smrg    //ErrorF("amd_gx_exa_PrepareSolid(%#x,%#x,%#x - ROP=%x,BLT_MODE=%x)\n", alu, planemask, fg, ROP, BLT_MODE);
1538f29dbc25Smrg    GU2_WAIT_PENDING;
1539f29dbc25Smrg    WRITE_GP32(MGP_RASTER_MODE, ROP);
1540f29dbc25Smrg    WRITE_GP32(MGP_PAT_COLOR_0, planemask);
1541f29dbc25Smrg    WRITE_GP32(MGP_SRC_COLOR_FG, fg);
1542f29dbc25Smrg    WRITE_GP32(MGP_STRIDE, dstPitch);
1543f29dbc25Smrg    return TRUE;
1544f29dbc25Smrg}
1545f29dbc25Smrg
1546f29dbc25Smrgstatic void
1547f29dbc25Smrgamd_gx_exa_Solid(PixmapPtr pxMap, int x1, int y1, int x2, int y2)
1548f29dbc25Smrg{
1549f29dbc25Smrg    int bpp = (pxMap->drawable.bitsPerPixel + 7) / 8;
1550f29dbc25Smrg    int pitch = exaGetPixmapPitch(pxMap);
1551f29dbc25Smrg    unsigned int offset = exaGetPixmapOffset(pxMap) + pitch * y1 + bpp * x1;
1552f29dbc25Smrg    unsigned int size = ((x2 - x1) << 16) | (y2 - y1);
1553f29dbc25Smrg
1554f29dbc25Smrg    //ErrorF("amd_gx_exa_Solid() at %d,%d %d,%d - offset=%d, bpp=%d\n", x1, y1, x2, y2, offset, bpp);
1555f29dbc25Smrg
1556f29dbc25Smrg    GU2_WAIT_PENDING;
1557f29dbc25Smrg    WRITE_GP32(MGP_DST_OFFSET, offset);
1558f29dbc25Smrg    WRITE_GP32(MGP_WID_HEIGHT, size);
1559f29dbc25Smrg    WRITE_GP32(MGP_BLT_MODE, BLT_MODE);
1560f29dbc25Smrg}
1561f29dbc25Smrg
1562f29dbc25Smrg/* Copy */
1563f29dbc25Smrg
1564f29dbc25Smrgstatic Bool
1565f29dbc25Smrgamd_gx_exa_PrepareCopy(PixmapPtr pxSrc, PixmapPtr pxDst, int dx, int dy,
156604007ebaSmrg                       int alu, Pixel planemask)
1567f29dbc25Smrg{
1568f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst);
1569f29dbc25Smrg    int dstPitch = exaGetPixmapPitch(pxDst);
1570f29dbc25Smrg    unsigned int ROP;
1571f29dbc25Smrg
1572f29dbc25Smrg    /* Punt if the color formats aren't the same */
1573f29dbc25Smrg
1574f29dbc25Smrg    if (pxSrc->drawable.bitsPerPixel != pxDst->drawable.bitsPerPixel)
157504007ebaSmrg        return FALSE;
1576f29dbc25Smrg
1577f29dbc25Smrg    //ErrorF("amd_gx_exa_PrepareCopy() dx%d dy%d alu %#x %#x\n",
1578f29dbc25Smrg    //  dx, dy, alu, planemask);
1579f29dbc25Smrg
1580f29dbc25Smrg    pGeode->cpySrcOffset = exaGetPixmapOffset(pxSrc);
1581f29dbc25Smrg    pGeode->cpySrcPitch = exaGetPixmapPitch(pxSrc);
1582f29dbc25Smrg    pGeode->cpySrcBpp = (pxSrc->drawable.bitsPerPixel + 7) / 8;
1583f29dbc25Smrg    pGeode->cpyDx = dx;
1584f29dbc25Smrg    pGeode->cpyDy = dy;
1585f29dbc25Smrg    ROP = amd_gx_BppToRasterMode(pxSrc->drawable.bitsPerPixel) |
158604007ebaSmrg        (planemask == ~0U ? SDfn[alu] : SDfn_PM[alu]);
1587f29dbc25Smrg
1588f29dbc25Smrg    BLT_MODE = ((ROP ^ (ROP >> 1)) & 0x55) != 0 ?
158904007ebaSmrg        MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
1590f29dbc25Smrg    GU2_WAIT_PENDING;
1591f29dbc25Smrg    WRITE_GP32(MGP_RASTER_MODE, ROP);
1592f29dbc25Smrg    WRITE_GP32(MGP_PAT_COLOR_0, planemask);
1593f29dbc25Smrg    WRITE_GP32(MGP_SRC_COLOR_FG, ~0);
1594f29dbc25Smrg    WRITE_GP32(MGP_SRC_COLOR_BG, ~0);
1595f29dbc25Smrg    WRITE_GP32(MGP_STRIDE, (pGeode->cpySrcPitch << 16) | dstPitch);
1596f29dbc25Smrg    return TRUE;
1597f29dbc25Smrg}
1598f29dbc25Smrg
1599f29dbc25Smrgstatic void
1600f29dbc25Smrgamd_gx_exa_Copy(PixmapPtr pxDst, int srcX, int srcY, int dstX, int dstY,
160104007ebaSmrg                int w, int h)
1602f29dbc25Smrg{
1603f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst);
1604f29dbc25Smrg    int dstBpp = (pxDst->drawable.bitsPerPixel + 7) / 8;
1605f29dbc25Smrg    int dstPitch = exaGetPixmapPitch(pxDst);
1606f29dbc25Smrg    unsigned int srcOffset =
160704007ebaSmrg        pGeode->cpySrcOffset + (pGeode->cpySrcPitch * srcY) +
160804007ebaSmrg        (pGeode->cpySrcBpp * srcX);
1609f29dbc25Smrg    unsigned int dstOffset =
161004007ebaSmrg        exaGetPixmapOffset(pxDst) + (dstPitch * dstY) + (dstBpp * dstX);
1611f29dbc25Smrg    unsigned int size = (w << 16) | h;
1612f29dbc25Smrg    unsigned int blt_mode = BLT_MODE;
1613f29dbc25Smrg
1614f29dbc25Smrg    //ErrorF("amd_gx_exa_Copy() from %d,%d to %d,%d %dx%d\n", srcX, srcY,
1615f29dbc25Smrg    //   dstX, dstY, w, h);
1616f29dbc25Smrg
1617f29dbc25Smrg    if (pGeode->cpyDx < 0) {
161804007ebaSmrg        srcOffset += w * pGeode->cpySrcBpp - 1;
161904007ebaSmrg        dstOffset += w * dstBpp - 1;
162004007ebaSmrg        blt_mode |= MGP_BM_NEG_XDIR;
1621f29dbc25Smrg    }
1622f29dbc25Smrg    if (pGeode->cpyDy < 0) {
162304007ebaSmrg        srcOffset += (h - 1) * pGeode->cpySrcPitch;
162404007ebaSmrg        dstOffset += (h - 1) * dstPitch;
162504007ebaSmrg        blt_mode |= MGP_BM_NEG_YDIR;
1626f29dbc25Smrg    }
1627f29dbc25Smrg    GU2_WAIT_PENDING;
1628f29dbc25Smrg    WRITE_GP32(MGP_SRC_OFFSET, srcOffset);
1629f29dbc25Smrg    WRITE_GP32(MGP_DST_OFFSET, dstOffset);
1630f29dbc25Smrg    WRITE_GP32(MGP_WID_HEIGHT, size);
1631f29dbc25Smrg    WRITE_GP16(MGP_BLT_MODE, blt_mode);
1632f29dbc25Smrg}
1633f29dbc25Smrg
1634f29dbc25Smrg/* A=SRC, B=DST */
1635f29dbc25Smrg#define SRC_DST 0
1636f29dbc25Smrg/* B=SRC, A=DST */
1637f29dbc25Smrg#define DST_SRC MGP_RM_DEST_FROM_CHAN_A
1638f29dbc25Smrg/* A*alpha + B*0         */
1639f29dbc25Smrg#define Aa_B0   MGP_RM_ALPHA_TIMES_A
1640f29dbc25Smrg/* A*0     + B*(1-alpha) */
1641f29dbc25Smrg#define A0_B1a  MGP_RM_BETA_TIMES_B
1642f29dbc25Smrg/* A*1     + B*(1-alpha) */
1643f29dbc25Smrg#define A1_B1a  MGP_RM_A_PLUS_BETA_B
1644f29dbc25Smrg/* A*alpha + B*(1-alpha) */
1645f29dbc25Smrg#define Aa_B1a  MGP_RM_ALPHA_A_PLUS_BETA_B
1646f29dbc25Smrg/* alpha from A */
1647f29dbc25Smrg#define a_A MGP_RM_SELECT_ALPHA_A
1648f29dbc25Smrg/* alpha from B */
1649f29dbc25Smrg#define a_B MGP_RM_SELECT_ALPHA_B
1650f29dbc25Smrg/* alpha from const */
1651f29dbc25Smrg#define a_C MGP_RM_SELECT_ALPHA_R
1652f29dbc25Smrg/* alpha = 1 */
1653f29dbc25Smrg#define a_1 MGP_RM_SELECT_ALPHA_1
1654f29dbc25Smrg
1655f29dbc25Smrg#define MGP_RM_ALPHA_TO_ARGB (MGP_RM_ALPHA_TO_ALPHA | MGP_RM_ALPHA_TO_RGB)
165604007ebaSmrg#define gxPictOpMAX PictOpAdd   /* highest accelerated op */
1657f29dbc25Smrg
1658f29dbc25Smrgunsigned int amd_gx_exa_alpha_ops[] =
1659f29dbc25Smrg/*    A   B      OP     AS           const = 0 */
1660f29dbc25Smrg{
166104007ebaSmrg    (SRC_DST | Aa_B0 | a_C), 0, /* clear    (src*0) */
166204007ebaSmrg    (SRC_DST | Aa_B0 | a_1), 0, /* src      (src*1) */
166304007ebaSmrg    (DST_SRC | Aa_B0 | a_1), 0, /* dst      (dst*1) */
166404007ebaSmrg    (SRC_DST | A1_B1a | a_A), 0,        /* src-over (src*1 + dst(1-A)) */
166504007ebaSmrg    (DST_SRC | A1_B1a | a_A), 0,        /* dst-over (dst*1 + src(1-B)) */
166604007ebaSmrg    (SRC_DST | Aa_B0 | a_B), 0, /* src-in   (src*B) */
166704007ebaSmrg    (DST_SRC | Aa_B0 | a_B), 0, /* dst-in   (dst*A) */
166804007ebaSmrg    (DST_SRC | A0_B1a | a_A), 0,        /* src-out  (src*(1-B)) */
166904007ebaSmrg    (SRC_DST | A0_B1a | a_A), 0,        /* dst-out  (dst*(1-A)) */
1670f29dbc25Smrg/* pass1 (SRC=dst DST=scr=src), pass2 (SRC=src, DST=dst) */
167104007ebaSmrg    (DST_SRC | Aa_B0 | a_B),    /* srcatop  (src*B) */
167204007ebaSmrg    (SRC_DST | A0_B1a | a_A),   /*                  + (dst(1-A)) */
167304007ebaSmrg    (SRC_DST | Aa_B0 | a_B),    /* dstatop  (dst*A) */
167404007ebaSmrg    (DST_SRC | A0_B1a | a_A),   /*                  + (src(1-B) */
167504007ebaSmrg    (SRC_DST | A0_B1a | a_A),   /* xor      (src*(1-B) */
167604007ebaSmrg    (SRC_DST | A0_B1a | a_A),   /*                  + (dst(1-A) */
167704007ebaSmrg    (SRC_DST | A1_B1a | a_C), 0,        /* add      (src*1 + dst*1) */
1678f29dbc25Smrg};
1679f29dbc25Smrg
168004007ebaSmrgtypedef struct {
1681f29dbc25Smrg    int exa_fmt;
1682f29dbc25Smrg    int bpp;
1683f29dbc25Smrg    int gx_fmt;
1684f29dbc25Smrg    int alpha_bits;
1685f29dbc25Smrg} amd_gx_exa_fmt_t;
1686f29dbc25Smrg
1687f29dbc25Smrgamd_gx_exa_fmt_t amd_gx_exa_fmts[] = {
1688f29dbc25Smrg    {PICT_a8r8g8b8, 32, MGP_RM_BPPFMT_8888, 8},
1689f29dbc25Smrg    {PICT_x8r8g8b8, 32, MGP_RM_BPPFMT_8888, 0},
1690f29dbc25Smrg    {PICT_a4r4g4b4, 16, MGP_RM_BPPFMT_4444, 4},
1691f29dbc25Smrg    {PICT_a1r5g5b5, 16, MGP_RM_BPPFMT_1555, 1},
1692f29dbc25Smrg    {PICT_r5g6b5, 16, MGP_RM_BPPFMT_565, 0},
1693f29dbc25Smrg    {PICT_r3g3b2, 8, MGP_RM_BPPFMT_332, 0},
1694f29dbc25Smrg};
1695f29dbc25Smrg
1696f29dbc25Smrgstatic amd_gx_exa_fmt_t *
1697f29dbc25Smrgamd_gx_exa_check_format(PicturePtr p)
1698f29dbc25Smrg{
1699f29dbc25Smrg    int i;
1700f29dbc25Smrg    int bpp = p->pDrawable ? p->pDrawable->bitsPerPixel : 0;
1701f29dbc25Smrg    amd_gx_exa_fmt_t *fp = &amd_gx_exa_fmts[0];
1702f29dbc25Smrg
1703f29dbc25Smrg    for (i = sizeof(amd_gx_exa_fmts) / sizeof(amd_gx_exa_fmts[0]); --i >= 0;
170404007ebaSmrg         ++fp) {
170504007ebaSmrg        if (fp->bpp < bpp)
170604007ebaSmrg            return NULL;
170704007ebaSmrg        if (fp->bpp != bpp)
170804007ebaSmrg            continue;
170904007ebaSmrg        if (fp->exa_fmt == p->format)
171004007ebaSmrg            break;
1711f29dbc25Smrg    }
1712f29dbc25Smrg    return i < 0 ? NULL : fp;
1713f29dbc25Smrg}
1714f29dbc25Smrg
1715f29dbc25Smrg/* Composite */
1716f29dbc25Smrg
1717f29dbc25Smrgstatic Bool
1718f29dbc25Smrgamd_gx_exa_CheckComposite(int op, PicturePtr pSrc, PicturePtr pMsk,
171904007ebaSmrg                          PicturePtr pDst)
1720f29dbc25Smrg{
1721f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR_FROM_PICTURE(pDst);
1722f29dbc25Smrg
1723f29dbc25Smrg    if (op > gxPictOpMAX)
172404007ebaSmrg        return FALSE;
1725f29dbc25Smrg    if (pMsk)
172604007ebaSmrg        return FALSE;
1727f29dbc25Smrg    if (usesPasses(op) && pGeode->exaBfrSz == 0)
172804007ebaSmrg        return FALSE;
1729f29dbc25Smrg    if (pSrc->filter != PictFilterNearest &&
173004007ebaSmrg        pSrc->filter != PictFilterFast &&
173104007ebaSmrg        pSrc->filter != PictFilterGood && pSrc->filter != PictFilterBest)
173204007ebaSmrg        return FALSE;
1733f29dbc25Smrg    if (pSrc->repeat)
173404007ebaSmrg        return FALSE;
1735f29dbc25Smrg    if (pSrc->transform)
173604007ebaSmrg        return FALSE;
1737f29dbc25Smrg    return TRUE;
1738f29dbc25Smrg}
1739f29dbc25Smrg
1740f29dbc25Smrgstatic Bool
1741f29dbc25Smrgamd_gx_exa_PrepareComposite(int op, PicturePtr pSrc, PicturePtr pMsk,
174204007ebaSmrg                            PicturePtr pDst, PixmapPtr pxSrc, PixmapPtr pxMsk,
174304007ebaSmrg                            PixmapPtr pxDst)
1744f29dbc25Smrg{
1745f29dbc25Smrg    int srcPitch;
174644802259Smrg    if (!pxSrc || !pSrc->pDrawable) return FALSE;
1747f29dbc25Smrg
1748f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst);
1749f29dbc25Smrg    amd_gx_exa_fmt_t *sfp, *dfp;
1750f29dbc25Smrg
1751f29dbc25Smrg    //ErrorF("amd_gx_exa_PrepareComposite()\n");
1752f29dbc25Smrg
1753f29dbc25Smrg    if ((sfp = amd_gx_exa_check_format(pSrc)) == NULL)
175404007ebaSmrg        return FALSE;
1755f29dbc25Smrg    if (sfp->alpha_bits == 0 && usesSrcAlpha(op))
175604007ebaSmrg        return FALSE;
1757f29dbc25Smrg    if ((dfp = amd_gx_exa_check_format(pDst)) == NULL)
175804007ebaSmrg        return FALSE;
1759f29dbc25Smrg    if (dfp->alpha_bits == 0 && usesDstAlpha(op))
176004007ebaSmrg        return FALSE;
1761f29dbc25Smrg    if (sfp->gx_fmt != dfp->gx_fmt)
176204007ebaSmrg        return FALSE;
1763f29dbc25Smrg    srcPitch = exaGetPixmapPitch(pxSrc);
1764f29dbc25Smrg    if (usesPasses(op) && srcPitch > pGeode->exaBfrSz)
176504007ebaSmrg        return FALSE;
1766f29dbc25Smrg    pGeode->cmpSrcPitch = srcPitch;
1767f29dbc25Smrg    pGeode->cmpOp = op;
1768f29dbc25Smrg    pGeode->cmpSrcOffset = exaGetPixmapOffset(pxSrc);
1769f29dbc25Smrg    pGeode->cmpSrcBpp = (pxSrc->drawable.bitsPerPixel + 7) / 8;
1770f29dbc25Smrg    pGeode->cmpSrcFmt = sfp->gx_fmt;
1771f29dbc25Smrg    pGeode->cmpDstFmt = dfp->gx_fmt | (dfp->alpha_bits == 0 ?
177204007ebaSmrg                                       MGP_RM_ALPHA_TO_RGB :
177304007ebaSmrg                                       MGP_RM_ALPHA_TO_ARGB);
1774f29dbc25Smrg    return TRUE;
1775f29dbc25Smrg}
1776f29dbc25Smrg
1777f29dbc25Smrgstatic void
1778f29dbc25Smrgamd_gx_exa_Composite(PixmapPtr pxDst, int srcX, int srcY, int maskX,
177904007ebaSmrg                     int maskY, int dstX, int dstY, int width, int height)
1780f29dbc25Smrg{
1781f29dbc25Smrg    int op, current_line, max_lines, lines, pass, scratchPitch;
1782f29dbc25Smrg    unsigned int srcOffset, srcOfs = 0, srcPitch, srcPch = 0, srcBpp;
1783f29dbc25Smrg    unsigned int dstOffset, dstOfs = 0, dstPitch, dstPch = 0, dstBpp;
1784f29dbc25Smrg    unsigned int sizes, strides, blt_mode = 0, rop = 0;
1785f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst);
1786f29dbc25Smrg
1787f29dbc25Smrg    //ErrorF("amd_gx_exa_Composite() from %d,%d to %d,%d %dx%d\n",
1788f29dbc25Smrg    //    srcX, srcY, dstX, dstY, width, height);
1789f29dbc25Smrg
1790f29dbc25Smrg    op = pGeode->cmpOp;
1791f29dbc25Smrg    if (usesPasses(op)) {
179204007ebaSmrg        int cacheLineSz = 32;
179304007ebaSmrg        int cachelines =
179404007ebaSmrg            (width * pGeode->cmpSrcBpp + cacheLineSz - 1) / cacheLineSz;
179504007ebaSmrg        scratchPitch = cachelines * cacheLineSz;
179604007ebaSmrg        if (scratchPitch > pGeode->cmpSrcPitch)
179704007ebaSmrg            scratchPitch = pGeode->cmpSrcPitch;
179804007ebaSmrg        max_lines = pGeode->exaBfrSz / scratchPitch;
179904007ebaSmrg    }
180004007ebaSmrg    else {
180104007ebaSmrg        scratchPitch = 0;
180204007ebaSmrg        max_lines = height;
1803f29dbc25Smrg    }
1804f29dbc25Smrg
1805f29dbc25Smrg    dstBpp = (pxDst->drawable.bitsPerPixel + 7) / 8;
1806f29dbc25Smrg    dstPitch = exaGetPixmapPitch(pxDst);
1807f29dbc25Smrg    dstOffset = exaGetPixmapOffset(pxDst) + dstPitch * dstY + dstBpp * dstX;
1808f29dbc25Smrg    srcBpp = pGeode->cmpSrcBpp;
1809f29dbc25Smrg    srcPitch = pGeode->cmpSrcPitch;
1810f29dbc25Smrg    srcOffset = pGeode->cmpSrcOffset + srcPitch * srcY + srcBpp * srcX;
1811f29dbc25Smrg
1812f29dbc25Smrg    current_line = pass = 0;
1813f29dbc25Smrg    while (current_line < height) {
181404007ebaSmrg        if (usesPasses(op)) {
181504007ebaSmrg            lines = height - current_line;
181604007ebaSmrg            if (lines > max_lines)
181704007ebaSmrg                lines = max_lines;
181804007ebaSmrg            switch (pass) {
181904007ebaSmrg            case 0:            /* copy src to scratch */
182004007ebaSmrg                srcPch = srcPitch;
182104007ebaSmrg                srcOfs = srcOffset + current_line * srcPch;
182204007ebaSmrg                dstPch = scratchPitch;
182304007ebaSmrg                dstOfs = pGeode->exaBfrOffset;
182404007ebaSmrg                rop = pGeode->cmpSrcFmt | MGP_RM_ALPHA_TO_ARGB;
182504007ebaSmrg                rop |= amd_gx_exa_alpha_ops[PictOpSrc * 2];
182604007ebaSmrg                blt_mode = usesChanB0(PictOpSrc) ?
182704007ebaSmrg                    MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
182804007ebaSmrg                ++pass;
182904007ebaSmrg                break;
183004007ebaSmrg            case 1:            /* pass1 */
183104007ebaSmrg                srcPch = dstPitch;
183204007ebaSmrg                srcOfs = dstOffset + current_line * srcPch;
183304007ebaSmrg                dstPch = scratchPitch;
183404007ebaSmrg                dstOfs = pGeode->exaBfrOffset;
183504007ebaSmrg                rop = pGeode->cmpSrcFmt | MGP_RM_ALPHA_TO_ARGB;
183604007ebaSmrg                rop |= amd_gx_exa_alpha_ops[op * 2];
183704007ebaSmrg                blt_mode = usesChanB1(op) ?
183804007ebaSmrg                    MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
183904007ebaSmrg                ++pass;
184004007ebaSmrg                break;
184104007ebaSmrg            case 2:            /* pass2 */
184204007ebaSmrg                srcPch = srcPitch;
184304007ebaSmrg                srcOfs = srcOffset + current_line * srcPch;
184404007ebaSmrg                dstPch = dstPitch;
184504007ebaSmrg                dstOfs = dstOffset + current_line * dstPch;
184604007ebaSmrg                rop = pGeode->cmpSrcFmt | MGP_RM_ALPHA_TO_ARGB;
184704007ebaSmrg                rop |= amd_gx_exa_alpha_ops[op * 2 + 1];
184804007ebaSmrg                blt_mode = usesChanB2(op) ?
184904007ebaSmrg                    MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
185004007ebaSmrg                ++pass;
185104007ebaSmrg                break;
185204007ebaSmrg            case 3:            /* add */
185304007ebaSmrg                srcPch = scratchPitch;
185404007ebaSmrg                srcOfs = pGeode->exaBfrOffset;
185504007ebaSmrg                dstPch = dstPitch;
185604007ebaSmrg                dstOfs = dstOffset + current_line * dstPch;
185704007ebaSmrg                rop = pGeode->cmpDstFmt;
185804007ebaSmrg                rop |= amd_gx_exa_alpha_ops[PictOpAdd * 2];
185904007ebaSmrg                blt_mode = usesChanB0(PictOpAdd) ?
186004007ebaSmrg                    MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
186104007ebaSmrg                current_line += lines;
186204007ebaSmrg                pass = 0;
186304007ebaSmrg                break;
186404007ebaSmrg            }
186504007ebaSmrg            strides = (srcPch << 16) | dstPch;
186604007ebaSmrg        }
186704007ebaSmrg        else {                  /* not multi pass */
186804007ebaSmrg            srcOfs = srcOffset;
186904007ebaSmrg            dstOfs = dstOffset;
187004007ebaSmrg            current_line = lines = height;
187104007ebaSmrg            strides = (srcPitch << 16) | dstPitch;
187204007ebaSmrg            rop = pGeode->cmpDstFmt | amd_gx_exa_alpha_ops[op * 2];
187304007ebaSmrg            blt_mode = usesChanB0(op) ?
187404007ebaSmrg                MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
187504007ebaSmrg        }
187604007ebaSmrg        sizes = (width << 16) | lines;
187704007ebaSmrg        if (srcOfs < dstOfs) {
187804007ebaSmrg            srcOfs += (lines - 1) * srcPitch + width * srcBpp - 1;
187904007ebaSmrg            dstOfs += (lines - 1) * dstPitch + width * dstBpp - 1;
188004007ebaSmrg            blt_mode |= MGP_BM_NEG_XDIR | MGP_BM_NEG_YDIR;
188104007ebaSmrg        }
188204007ebaSmrg        GU2_WAIT_PENDING;
188304007ebaSmrg        WRITE_GP32(MGP_RASTER_MODE, rop);
188404007ebaSmrg        WRITE_GP32(MGP_SRC_OFFSET, srcOfs);
188504007ebaSmrg        WRITE_GP32(MGP_DST_OFFSET, dstOfs);
188604007ebaSmrg        WRITE_GP32(MGP_WID_HEIGHT, sizes);
188704007ebaSmrg        WRITE_GP32(MGP_STRIDE, strides);
188804007ebaSmrg        WRITE_GP16(MGP_BLT_MODE, blt_mode);
1889f29dbc25Smrg    }
1890f29dbc25Smrg}
189104007ebaSmrg#endif                          /* #if XF86EXA */
1892f29dbc25Smrg
1893f29dbc25Smrg/*----------------------------------------------------------------------------
1894f29dbc25Smrg * GXAccelInit.
1895f29dbc25Smrg *
1896f29dbc25Smrg * Description:	This function sets up the supported acceleration routines and
1897f29dbc25Smrg *              appropriate flags.
1898f29dbc25Smrg *
1899f29dbc25Smrg * Parameters:
1900f29dbc25Smrg *      pScrn:	Screeen pointer structure.
1901f29dbc25Smrg *
1902f29dbc25Smrg * Returns:		TRUE on success and FALSE on Failure
1903f29dbc25Smrg *
1904f29dbc25Smrg * Comments:	This function is called in GXScreenInit in
1905f29dbc25Smrg *              geode_driver.c to set  * the acceleration.
1906f29dbc25Smrg *----------------------------------------------------------------------------
1907f29dbc25Smrg */
1908f29dbc25SmrgBool
1909f29dbc25SmrgGXAccelInit(ScreenPtr pScrn)
1910f29dbc25Smrg{
191104007ebaSmrg    ScrnInfoPtr pScrni = xf86ScreenToScrn(pScrn);
1912f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR(pScrni);
1913f29dbc25Smrg
1914f29dbc25Smrg#if XF86EXA
1915f29dbc25Smrg    ExaDriverPtr pExa = pGeode->pExa;
1916f29dbc25Smrg#endif
1917f29dbc25Smrg
1918f29dbc25Smrg    gu2_xshift = pScrni->bitsPerPixel >> 4;
1919f29dbc25Smrg
1920f29dbc25Smrg    /* XXX - fixme - this will change - we'll need to update it */
1921f29dbc25Smrg
1922f29dbc25Smrg    gu2_pitch = pGeode->Pitch;
1923f29dbc25Smrg
1924f29dbc25Smrg    switch (pGeode->Pitch) {
1925f29dbc25Smrg    case 1024:
192604007ebaSmrg        gu2_yshift = 10;
192704007ebaSmrg        break;
1928f29dbc25Smrg    case 2048:
192904007ebaSmrg        gu2_yshift = 11;
193004007ebaSmrg        break;
1931f29dbc25Smrg    case 4096:
193204007ebaSmrg        gu2_yshift = 12;
193304007ebaSmrg        break;
1934f29dbc25Smrg    default:
193504007ebaSmrg        gu2_yshift = 13;
193604007ebaSmrg        break;
1937f29dbc25Smrg    }
1938f29dbc25Smrg
1939f29dbc25Smrg#ifdef OPT_ACCEL
1940f29dbc25Smrg    ACCEL_STRIDE = (pGeode->Pitch << 16) | pGeode->Pitch;
1941f29dbc25Smrg    BPP = amd_gx_BppToRasterMode(pScrni->bitsPerPixel);
1942f29dbc25Smrg#endif
1943f29dbc25Smrg
1944f29dbc25Smrg#if XF86EXA
1945f29dbc25Smrg    if (pExa && pGeode->useEXA) {
194604007ebaSmrg        pExa->exa_major = EXA_VERSION_MAJOR;
194704007ebaSmrg        pExa->exa_minor = EXA_VERSION_MINOR;
194804007ebaSmrg
194904007ebaSmrg        /* Sync */
195004007ebaSmrg        pExa->WaitMarker = amd_gx_exa_WaitMarker;
195104007ebaSmrg        /* UploadToScreen */
195204007ebaSmrg        pExa->UploadToScreen = amd_gx_exa_UploadToScreen;
195304007ebaSmrg        pExa->DownloadFromScreen = amd_gx_exa_DownloadFromScreen;
195404007ebaSmrg
195504007ebaSmrg        /* Solid fill */
195604007ebaSmrg        pExa->PrepareSolid = amd_gx_exa_PrepareSolid;
195704007ebaSmrg        pExa->Solid = amd_gx_exa_Solid;
195804007ebaSmrg        pExa->DoneSolid = amd_gx_exa_Done;
195904007ebaSmrg
196004007ebaSmrg        /* Copy */
196104007ebaSmrg        pExa->PrepareCopy = amd_gx_exa_PrepareCopy;
196204007ebaSmrg        pExa->Copy = amd_gx_exa_Copy;
196304007ebaSmrg        pExa->DoneCopy = amd_gx_exa_Done;
196404007ebaSmrg
196504007ebaSmrg        /* Composite */
196604007ebaSmrg        pExa->CheckComposite = amd_gx_exa_CheckComposite;
196704007ebaSmrg        pExa->PrepareComposite = amd_gx_exa_PrepareComposite;
196804007ebaSmrg        pExa->Composite = amd_gx_exa_Composite;
196904007ebaSmrg        pExa->DoneComposite = amd_gx_exa_Done;
197004007ebaSmrg
197104007ebaSmrg        return exaDriverInit(pScrn, pGeode->pExa);
1972f29dbc25Smrg    }
1973f29dbc25Smrg#endif
1974f29dbc25Smrg
197504007ebaSmrg#if XF86XAA
197604007ebaSmrg
1977f29dbc25Smrg    /* Getting the pointer for acceleration Inforecord */
1978f29dbc25Smrg    pGeode->AccelInfoRec = localRecPtr = XAACreateInfoRec();
1979f29dbc25Smrg    if (!pGeode->AccelInfoRec)
198004007ebaSmrg        return FALSE;
1981f29dbc25Smrg
1982f29dbc25Smrg    /* SET ACCELERATION FLAGS */
198304007ebaSmrg    localRecPtr->Flags = PIXMAP_CACHE | OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER;
1984f29dbc25Smrg
1985f29dbc25Smrg    /* HOOK SYNCRONIZARION ROUTINE */
1986f29dbc25Smrg    localRecPtr->Sync = GXAccelSync;
1987f29dbc25Smrg
1988f29dbc25Smrg#if GX_FILL_RECT_SUPPORT
1989f29dbc25Smrg    /* HOOK FILLED RECTANGLES */
1990f29dbc25Smrg    HOOK(SetupForSolidFill);
1991f29dbc25Smrg    HOOK(SubsequentSolidFillRect);
1992f29dbc25Smrg    localRecPtr->SolidFillFlags = 0;
1993f29dbc25Smrg#endif
1994f29dbc25Smrg
1995f29dbc25Smrg#if GX_MONO_8X8_PAT_SUPPORT
1996f29dbc25Smrg    /* Color expansion */
1997f29dbc25Smrg    HOOK(SetupForMono8x8PatternFill);
1998f29dbc25Smrg    HOOK(SubsequentMono8x8PatternFillRect);
1999f29dbc25Smrg/*         BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD | NO_TRANSPARENCY | */
2000f29dbc25Smrg    localRecPtr->Mono8x8PatternFillFlags = BIT_ORDER_IN_BYTE_MSBFIRST |
200104007ebaSmrg        HARDWARE_PATTERN_PROGRAMMED_BITS | HARDWARE_PATTERN_SCREEN_ORIGIN;
2002f29dbc25Smrg#endif
2003f29dbc25Smrg
2004f29dbc25Smrg#if GX_CLREXP_8X8_PAT_SUPPORT
2005f29dbc25Smrg    /* Color expansion */
2006f29dbc25Smrg    HOOK(SetupForColor8x8PatternFill);
2007f29dbc25Smrg    HOOK(SubsequentColor8x8PatternFillRect);
2008f29dbc25Smrg/*         BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD | NO_TRANSPARENCY | */
2009f29dbc25Smrg    localRecPtr->Color8x8PatternFillFlags =
201004007ebaSmrg        BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD |
201104007ebaSmrg        HARDWARE_PATTERN_PROGRAMMED_BITS | HARDWARE_PATTERN_PROGRAMMED_ORIGIN;
2012f29dbc25Smrg#endif
2013f29dbc25Smrg
2014f29dbc25Smrg#if GX_SCR2SCRCPY_SUPPORT
2015f29dbc25Smrg    /* HOOK SCREEN TO SCREEN COPIES
2016f29dbc25Smrg     * Set flag to only allow copy if transparency is enabled.
2017f29dbc25Smrg     */
2018f29dbc25Smrg    HOOK(SetupForScreenToScreenCopy);
2019f29dbc25Smrg    HOOK(SubsequentScreenToScreenCopy);
2020f29dbc25Smrg    localRecPtr->ScreenToScreenCopyFlags =
202104007ebaSmrg        BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD;
2022f29dbc25Smrg#endif
2023f29dbc25Smrg
2024f29dbc25Smrg#if GX_BRES_LINE_SUPPORT
2025f29dbc25Smrg    /* HOOK BRESENHAM SOLID LINES */
2026f29dbc25Smrg    localRecPtr->SolidLineFlags = NO_PLANEMASK;
2027f29dbc25Smrg    HOOK(SetupForSolidLine);
2028f29dbc25Smrg    HOOK(SubsequentSolidBresenhamLine);
2029f29dbc25Smrg    HOOK(SubsequentSolidHorVertLine);
2030f29dbc25Smrg    HOOK(SubsequentSolidTwoPointLine);
2031f29dbc25Smrg    localRecPtr->SolidBresenhamLineErrorTermBits = 15;
2032f29dbc25Smrg#endif
2033f29dbc25Smrg
2034f29dbc25Smrg#if GX_DASH_LINE_SUPPORT
2035f29dbc25Smrg    /* HOOK BRESENHAM DASHED LINES */
2036f29dbc25Smrg    HOOK(SetupForDashedLine);
2037f29dbc25Smrg    HOOK(SubsequentDashedBresenhamLine);
2038f29dbc25Smrg    HOOK(SubsequentDashedTwoPointLine);
2039f29dbc25Smrg    localRecPtr->DashedBresenhamLineErrorTermBits = 15;
2040f29dbc25Smrg    localRecPtr->DashPatternMaxLength = 64;
204104007ebaSmrg    localRecPtr->DashedLineFlags = NO_PLANEMASK |       /* TRANSPARENCY_ONLY | */
204204007ebaSmrg        LINE_PATTERN_POWER_OF_2_ONLY | LINE_PATTERN_MSBFIRST_MSBJUSTIFIED;
2043f29dbc25Smrg#endif
2044f29dbc25Smrg
2045f29dbc25Smrg#if GX_SCR2SCREXP_SUPPORT
2046f29dbc25Smrg    /* Color expansion */
2047f29dbc25Smrg    HOOK(SetupForScreenToScreenColorExpandFill);
2048f29dbc25Smrg    HOOK(SubsequentScreenToScreenColorExpandFill);
2049f29dbc25Smrg    localRecPtr->ScreenToScreenColorExpandFillFlags =
205004007ebaSmrg        BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD | NO_TRANSPARENCY;
2051f29dbc25Smrg#endif
2052f29dbc25Smrg
2053f29dbc25Smrg    if (pGeode->AccelImageWriteBuffers) {
2054f29dbc25Smrg#if GX_SCANLINE_SUPPORT
205504007ebaSmrg        localRecPtr->ScanlineImageWriteBuffers = pGeode->AccelImageWriteBuffers;
205604007ebaSmrg        localRecPtr->NumScanlineImageWriteBuffers = pGeode->NoOfImgBuffers;
205704007ebaSmrg        HOOK(SetupForScanlineImageWrite);
205804007ebaSmrg        HOOK(SubsequentScanlineImageWriteRect);
205904007ebaSmrg        HOOK(SubsequentImageWriteScanline);
206004007ebaSmrg        localRecPtr->ScanlineImageWriteFlags = NO_PLANEMASK | NO_GXCOPY |
206104007ebaSmrg            BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD;
2062f29dbc25Smrg#endif
2063f29dbc25Smrg
206404007ebaSmrg    }
206504007ebaSmrg    else {
206604007ebaSmrg        localRecPtr->PixmapCacheFlags = DO_NOT_BLIT_STIPPLES;
2067f29dbc25Smrg    }
2068f29dbc25Smrg
2069f29dbc25Smrg    if (pGeode->AccelColorExpandBuffers) {
2070f29dbc25Smrg#if GX_CPU2SCREXP_SUPPORT
207104007ebaSmrg        /* Color expansion */
207204007ebaSmrg        localRecPtr->ScanlineColorExpandBuffers =
207304007ebaSmrg            pGeode->AccelColorExpandBuffers;
207404007ebaSmrg        localRecPtr->NumScanlineColorExpandBuffers =
207504007ebaSmrg            pGeode->NoOfColorExpandLines;
207604007ebaSmrg        HOOK(SetupForScanlineCPUToScreenColorExpandFill);
207704007ebaSmrg        HOOK(SubsequentScanlineCPUToScreenColorExpandFill);
207804007ebaSmrg        HOOK(SubsequentColorExpandScanline);
207904007ebaSmrg        localRecPtr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK |
208004007ebaSmrg            BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD;
2081f29dbc25Smrg#endif
2082f29dbc25Smrg    }
2083f29dbc25Smrg#if GX_WRITE_PIXMAP_SUPPORT
2084f29dbc25Smrg    pGeode->WritePixmap = localRecPtr->WritePixmap;
2085f29dbc25Smrg    HOOK(WritePixmap);
2086f29dbc25Smrg#endif
2087f29dbc25Smrg
2088f29dbc25Smrg    return (XAAInit(pScrn, localRecPtr));
208904007ebaSmrg#else                           /* XF86XAA */
209004007ebaSmrg    return FALSE;
209104007ebaSmrg#endif
2092f29dbc25Smrg}
2093f29dbc25Smrg
2094f29dbc25Smrg/* END OF FILE */
2095