gx_accel.c revision f29dbc25
1f29dbc25Smrg/* Copyright (c) 2003-2005 Advanced Micro Devices, Inc.
2f29dbc25Smrg *
3f29dbc25Smrg * Permission is hereby granted, free of charge, to any person obtaining a copy
4f29dbc25Smrg * of this software and associated documentation files (the "Software"), to
5f29dbc25Smrg * deal in the Software without restriction, including without limitation the
6f29dbc25Smrg * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7f29dbc25Smrg * sell copies of the Software, and to permit persons to whom the Software is
8f29dbc25Smrg * furnished to do so, subject to the following conditions:
9f29dbc25Smrg *
10f29dbc25Smrg * The above copyright notice and this permission notice shall be included in
11f29dbc25Smrg * all copies or substantial portions of the Software.
12f29dbc25Smrg *
13f29dbc25Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14f29dbc25Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15f29dbc25Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16f29dbc25Smrg * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17f29dbc25Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18f29dbc25Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19f29dbc25Smrg * IN THE SOFTWARE.
20f29dbc25Smrg *
21f29dbc25Smrg * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
22f29dbc25Smrg * contributors may be used to endorse or promote products derived from this
23f29dbc25Smrg * software without specific prior written permission.
24f29dbc25Smrg * */
25f29dbc25Smrg
26f29dbc25Smrg/*
27f29dbc25Smrg * File Contents:   This file is consists of main Xfree acceleration supported
28f29dbc25Smrg *                  routines like solid fill used here.
29f29dbc25Smrg *
30f29dbc25Smrg * Project:         Geode Xfree Frame buffer device driver.
31f29dbc25Smrg * */
32f29dbc25Smrg
33f29dbc25Smrg/* #undef OPT_ACCEL */
34f29dbc25Smrg
35f29dbc25Smrg/* Xfree86 header files */
36f29dbc25Smrg#ifdef HAVE_CONFIG_H
37f29dbc25Smrg#include "config.h"
38f29dbc25Smrg#endif
39f29dbc25Smrg
40f29dbc25Smrg#include "vgaHW.h"
41f29dbc25Smrg#include "xf86.h"
42f29dbc25Smrg#include "xaalocal.h"
43f29dbc25Smrg#include "xf86fbman.h"
44f29dbc25Smrg#include "miline.h"
45f29dbc25Smrg#include "xaarop.h"
46f29dbc25Smrg#include "servermd.h"
47f29dbc25Smrg#include "picture.h"
48f29dbc25Smrg#include "xf86.h"
49f29dbc25Smrg#include "xf86_OSproc.h"
50f29dbc25Smrg#include "xf86Pci.h"
51f29dbc25Smrg#include "xf86PciInfo.h"
52f29dbc25Smrg#include "geode.h"
53f29dbc25Smrg#include "gfx_defs.h"
54f29dbc25Smrg#include "gfx_regs.h"
55f29dbc25Smrg
56f29dbc25Smrg/* Common macros for blend operations are here */
57f29dbc25Smrg
58f29dbc25Smrg#include "geode_blend.h"
59f29dbc25Smrg
60f29dbc25Smrg#undef ulong
61f29dbc25Smrgtypedef unsigned long ulong;
62f29dbc25Smrg
63f29dbc25Smrg#undef uint
64f29dbc25Smrgtypedef unsigned int uint;
65f29dbc25Smrg
66f29dbc25Smrg#undef ushort
67f29dbc25Smrgtypedef unsigned short ushort;
68f29dbc25Smrg
69f29dbc25Smrg#undef uchar
70f29dbc25Smrgtypedef unsigned char uchar;
71f29dbc25Smrg
72f29dbc25Smrg#define CALC_FBOFFSET(x, y) \
73f29dbc25Smrg	        (((ulong)(y) * gu2_pitch + ((ulong)(x) << gu2_xshift)))
74f29dbc25Smrg
75f29dbc25Smrg#define FBADDR(x,y)				\
76f29dbc25Smrg		((unsigned char *)pGeode->FBBase + CALC_FBOFFSET(x, y))
77f29dbc25Smrg
78f29dbc25Smrg#define OS_UDELAY 0
79f29dbc25Smrg#if OS_UDELAY > 0
80f29dbc25Smrg#define OS_USLEEP(usec) usleep(usec);
81f29dbc25Smrg#else
82f29dbc25Smrg#define OS_USLEEP(usec)
83f29dbc25Smrg#endif
84f29dbc25Smrg
85f29dbc25Smrg#ifdef OPT_ACCEL
86f29dbc25Smrgstatic unsigned int BPP;
87f29dbc25Smrgstatic unsigned int BLT_MODE, VEC_MODE;
88f29dbc25Smrgstatic unsigned int ACCEL_STRIDE;
89f29dbc25Smrg
90f29dbc25Smrg#define GU2_WAIT_PENDING while(READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_PENDING)
91f29dbc25Smrg#define GU2_WAIT_BUSY    while(READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_BUSY)
92f29dbc25Smrg#endif
93f29dbc25Smrg
94f29dbc25Smrg#define HOOK(fn) localRecPtr->fn = GX##fn
95f29dbc25Smrg
96f29dbc25Smrg#define DLOG(l, fmt, args...) ErrorF(fmt, ##args)
97f29dbc25Smrg
98f29dbc25Smrg/* static storage declarations */
99f29dbc25Smrg
100f29dbc25Smrgtypedef struct sGBltBox
101f29dbc25Smrg{
102f29dbc25Smrg    ulong x, y;
103f29dbc25Smrg    ulong w, h;
104f29dbc25Smrg    ulong color;
105f29dbc25Smrg    int bpp, transparent;
106f29dbc25Smrg} GBltBox;
107f29dbc25Smrg
108f29dbc25Smrg#if GX_SCANLINE_SUPPORT
109f29dbc25Smrgstatic GBltBox giwr;
110f29dbc25Smrg#endif
111f29dbc25Smrg#if GX_CPU2SCREXP_SUPPORT
112f29dbc25Smrgstatic GBltBox gc2s;
113f29dbc25Smrg#endif
114f29dbc25Smrg#if GX_CLREXP_8X8_PAT_SUPPORT
115f29dbc25Smrgstatic ulong *gc8x8p;
116f29dbc25Smrg#endif
117f29dbc25Smrg
118f29dbc25Smrg#if GX_DASH_LINE_SUPPORT
119f29dbc25Smrgtypedef struct sGDashLine
120f29dbc25Smrg{
121f29dbc25Smrg    ulong pat[2];
122f29dbc25Smrg    int len;
123f29dbc25Smrg    int fg;
124f29dbc25Smrg    int bg;
125f29dbc25Smrg} GDashLine;
126f29dbc25Smrg
127f29dbc25Smrgstatic GDashLine gdln;
128f29dbc25Smrg#endif
129f29dbc25Smrg
130f29dbc25Smrgstatic unsigned int gu2_xshift, gu2_yshift;
131f29dbc25Smrgstatic unsigned int gu2_pitch;
132f29dbc25Smrg
133f29dbc25Smrgstatic XAAInfoRecPtr localRecPtr;
134f29dbc25Smrg
135f29dbc25Smrg/* pat  0xF0 */
136f29dbc25Smrg/* src  0xCC */
137f29dbc25Smrg/* dst  0xAA */
138f29dbc25Smrg
139f29dbc25Smrg/* (src FUNC dst) */
140f29dbc25Smrg
141f29dbc25Smrgstatic const int SDfn[16] = {
142f29dbc25Smrg    0x00, 0x88, 0x44, 0xCC, 0x22, 0xAA, 0x66, 0xEE,
143f29dbc25Smrg    0x11, 0x99, 0x55, 0xDD, 0x33, 0xBB, 0x77, 0xFF
144f29dbc25Smrg};
145f29dbc25Smrg
146f29dbc25Smrg/* ((src FUNC dst) AND pat-mask) OR (dst AND (NOT pat-mask)) */
147f29dbc25Smrg
148f29dbc25Smrgstatic const int SDfn_PM[16] = {
149f29dbc25Smrg    0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
150f29dbc25Smrg    0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA
151f29dbc25Smrg};
152f29dbc25Smrg
153f29dbc25Smrg/* (pat FUNC dst) */
154f29dbc25Smrg
155f29dbc25Smrgstatic const int PDfn[16] = {
156f29dbc25Smrg    0x00, 0xA0, 0x50, 0xF0, 0x0A, 0xAA, 0x5A, 0xFA,
157f29dbc25Smrg    0x05, 0xA5, 0x55, 0xF5, 0x0F, 0xAF, 0x5F, 0xFF
158f29dbc25Smrg};
159f29dbc25Smrg
160f29dbc25Smrg/* ((pat FUNC dst) AND src-mask) OR (dst AND (NOT src-mask)) */
161f29dbc25Smrg
162f29dbc25Smrgstatic const int PDfn_SM[16] = {
163f29dbc25Smrg    0x22, 0xA2, 0x62, 0xE2, 0x2A, 0xAA, 0x6A, 0xEA,
164f29dbc25Smrg    0x26, 0xA6, 0x66, 0xE6, 0x2E, 0xAE, 0x6E, 0xEE
165f29dbc25Smrg};
166f29dbc25Smrg
167f29dbc25Smrg#ifdef OPT_ACCEL
168f29dbc25Smrgstatic inline CARD32
169f29dbc25Smrgamd_gx_BppToRasterMode(int bpp)
170f29dbc25Smrg{
171f29dbc25Smrg    switch (bpp) {
172f29dbc25Smrg    case 16:
173f29dbc25Smrg	return MGP_RM_BPPFMT_565;
174f29dbc25Smrg    case 32:
175f29dbc25Smrg	return MGP_RM_BPPFMT_8888;
176f29dbc25Smrg    case 8:
177f29dbc25Smrg	return MGP_RM_BPPFMT_332;
178f29dbc25Smrg    default:
179f29dbc25Smrg	return 0;
180f29dbc25Smrg    }
181f29dbc25Smrg}
182f29dbc25Smrg#endif /* OPT_ACCEL */
183f29dbc25Smrg
184f29dbc25Smrg/*----------------------------------------------------------------------------
185f29dbc25Smrg * GXAccelSync.
186f29dbc25Smrg *
187f29dbc25Smrg * Description  :This function is called to synchronize with the graphics
188f29dbc25Smrg *               engine and it waits the graphic engine is idle.  This is
189f29dbc25Smrg *               required before allowing direct access to the framebuffer.
190f29dbc25Smrg *
191f29dbc25Smrg *    Arg        Type     Comment
192f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
193f29dbc25Smrg *
194f29dbc25Smrg * Returns              :none
195f29dbc25Smrg *---------------------------------------------------------------------------*/
196f29dbc25Smrgvoid
197f29dbc25SmrgGXAccelSync(ScrnInfoPtr pScrni)
198f29dbc25Smrg{
199f29dbc25Smrg    //ErrorF("GXAccelSync()\n");
200f29dbc25Smrg#ifndef OPT_ACCEL
201f29dbc25Smrg    gfx_wait_until_idle();
202f29dbc25Smrg#else
203f29dbc25Smrg    GU2_WAIT_BUSY;
204f29dbc25Smrg#endif
205f29dbc25Smrg}
206f29dbc25Smrg
207f29dbc25Smrg#if GX_FILL_RECT_SUPPORT
208f29dbc25Smrg/*----------------------------------------------------------------------------
209f29dbc25Smrg * GXSetupForSolidFill.
210f29dbc25Smrg *
211f29dbc25Smrg * Description  :The SetupFor and Subsequent SolidFill(Rect) provide
212f29dbc25Smrg *               filling rectangular areas of the screen with a
213f29dbc25Smrg *               foreground color.
214f29dbc25Smrg *
215f29dbc25Smrg * Parameters.
216f29dbc25Smrg *    Arg        Type     Comment
217f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
218f29dbc25Smrg *   color        int     foreground fill color
219f29dbc25Smrg *    rop         int     unmapped raster op
220f29dbc25Smrg * planemask     uint     -1 (fill) or pattern data
221f29dbc25Smrg *
222f29dbc25Smrg * Returns              :none
223f29dbc25Smrg *--------------------------------------------------------------------------*/
224f29dbc25Smrgstatic void
225f29dbc25SmrgGXSetupForSolidFill(ScrnInfoPtr pScrni,
226f29dbc25Smrg    int color, int rop, unsigned int planemask)
227f29dbc25Smrg{
228f29dbc25Smrg    //ErrorF("GXSetupForSolidFill(%#x,%#x,%#x)\n", color, rop, planemask);
229f29dbc25Smrg    rop &= 0x0F;
230f29dbc25Smrg#ifndef OPT_ACCEL
231f29dbc25Smrg    gfx_set_solid_pattern(planemask);
232f29dbc25Smrg    gfx_set_solid_source(color);
233f29dbc25Smrg    gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
234f29dbc25Smrg#else
235f29dbc25Smrg    {
236f29dbc25Smrg	unsigned int ROP =
237f29dbc25Smrg	    BPP | (planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
238f29dbc25Smrg	BLT_MODE = ((ROP ^ (ROP >> 2)) & 0x33) == 0 ? MGP_BM_SRC_MONO : 0;
239f29dbc25Smrg	if (((ROP ^ (ROP >> 1)) & 0x55) != 0)
240f29dbc25Smrg	    BLT_MODE |= MGP_BM_DST_REQ;
241f29dbc25Smrg	GU2_WAIT_PENDING;
242f29dbc25Smrg	WRITE_GP32(MGP_RASTER_MODE, ROP);
243f29dbc25Smrg	WRITE_GP32(MGP_PAT_COLOR_0, planemask);
244f29dbc25Smrg	WRITE_GP32(MGP_SRC_COLOR_FG, color);
245f29dbc25Smrg	WRITE_GP32(MGP_STRIDE, ACCEL_STRIDE);
246f29dbc25Smrg    }
247f29dbc25Smrg#endif
248f29dbc25Smrg}
249f29dbc25Smrg
250f29dbc25Smrg/*----------------------------------------------------------------------------
251f29dbc25Smrg * GXSubsequentSolidFillRect.
252f29dbc25Smrg *
253f29dbc25Smrg * Description  :see GXSetupForSolidFill.
254f29dbc25Smrg *
255f29dbc25Smrg * Parameters.
256f29dbc25Smrg *    Arg        Type     Comment
257f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
258f29dbc25Smrg *     x          int     destination x offset
259f29dbc25Smrg *     y          int     destination y offset
260f29dbc25Smrg *     w          int     fill area width (pixels)
261f29dbc25Smrg *     h          int     fill area height (pixels)
262f29dbc25Smrg *
263f29dbc25Smrg * Returns      :none
264f29dbc25Smrg *
265f29dbc25Smrg * Sample application uses:
266f29dbc25Smrg *   - Window backgrounds.
267f29dbc25Smrg *   - pull down highlighting.
268f29dbc25Smrg *   - x11perf: rectangle tests (-rect500).
269f29dbc25Smrg *   - x11perf: fill trapezoid tests (-trap100).
270f29dbc25Smrg *   - x11perf: horizontal line segments (-hseg500).
271f29dbc25Smrg *----------------------------------------------------------------------------*/
272f29dbc25Smrgstatic void
273f29dbc25SmrgGXSubsequentSolidFillRect(ScrnInfoPtr pScrni, int x, int y, int w, int h)
274f29dbc25Smrg{
275f29dbc25Smrg    //ErrorF("GXSubsequentSolidFillRect() at %d,%d %dx%d\n", x, y, w, h);
276f29dbc25Smrg#ifndef OPT_ACCEL
277f29dbc25Smrg    gfx_pattern_fill(x, y, w, h);
278f29dbc25Smrg#else
279f29dbc25Smrg    {
280f29dbc25Smrg	unsigned int offset = CALC_FBOFFSET(x, y);
281f29dbc25Smrg	unsigned int size = (w << 16) | h;
282f29dbc25Smrg
283f29dbc25Smrg	GU2_WAIT_PENDING;
284f29dbc25Smrg	WRITE_GP32(MGP_DST_OFFSET, offset);
285f29dbc25Smrg	WRITE_GP32(MGP_WID_HEIGHT, size);
286f29dbc25Smrg	WRITE_GP32(MGP_BLT_MODE, BLT_MODE);
287f29dbc25Smrg    }
288f29dbc25Smrg#endif
289f29dbc25Smrg}
290f29dbc25Smrg
291f29dbc25Smrg#endif /* if GX_FILL_RECT_SUPPORT */
292f29dbc25Smrg
293f29dbc25Smrg#if GX_CLREXP_8X8_PAT_SUPPORT
294f29dbc25Smrg/*----------------------------------------------------------------------------
295f29dbc25Smrg * GXSetupForColor8x8PatternFill
296f29dbc25Smrg *
297f29dbc25Smrg * Description  :8x8 color pattern data is 64 pixels of full color data
298f29dbc25Smrg *               stored linearly in offscreen video memory.  These patterns
299f29dbc25Smrg *               are useful as a substitute for 8x8 mono patterns when tiling,
300f29dbc25Smrg *               doing opaque stipples, or regular stipples.
301f29dbc25Smrg *
302f29dbc25Smrg *    Arg        Type     Comment
303f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
304f29dbc25Smrg *    patx        int     x offset to pattern data
305f29dbc25Smrg *    paty        int     y offset to pattern data
306f29dbc25Smrg *    rop         int     unmapped raster operation
307f29dbc25Smrg * planemask     uint     -1 (copy) or pattern data
308f29dbc25Smrg * trans_color    int     -1 (copy) or transparent color (not enabled)
309f29dbc25Smrg *                         trans color only supported on source channel
310f29dbc25Smrg *                         or in monochrome pattern channel
311f29dbc25Smrg *
312f29dbc25Smrg * Returns      :none.
313f29dbc25Smrg *
314f29dbc25Smrg *---------------------------------------------------------------------------*/
315f29dbc25Smrg
316f29dbc25Smrgstatic void
317f29dbc25SmrgGXSetupForColor8x8PatternFill(ScrnInfoPtr pScrni, int patx, int paty, int rop,
318f29dbc25Smrg    uint planemask, int trans_color)
319f29dbc25Smrg{
320f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR(pScrni);
321f29dbc25Smrg
322f29dbc25Smrg    //ErrorF("GXSetupForColor8x8PatternFill() pat %#x,%#x rop %#x %#x %#x\n",
323f29dbc25Smrg    //    patx, paty, rop, planemask, trans_color);
324f29dbc25Smrg    rop &= 0x0F;
325f29dbc25Smrg    gc8x8p = (unsigned long *)FBADDR(patx, paty);
326f29dbc25Smrg    /* gfx_set_solid_pattern is needed to clear src/pat transparency */
327f29dbc25Smrg    gfx_set_solid_pattern(0);
328f29dbc25Smrg    gfx_set_raster_operation(planemask == ~0U ? PDfn[rop] :
329f29dbc25Smrg	(gfx_set_solid_source(planemask), PDfn_SM[rop]));
330f29dbc25Smrg    gfx2_set_source_stride(pGeode->Pitch);
331f29dbc25Smrg    gfx2_set_destination_stride(pGeode->Pitch);
332f29dbc25Smrg    if (trans_color == -1)
333f29dbc25Smrg	gfx2_set_source_transparency(0, 0);
334f29dbc25Smrg    else
335f29dbc25Smrg	gfx2_set_source_transparency(trans_color, ~0);
336f29dbc25Smrg}
337f29dbc25Smrg
338f29dbc25Smrg/*----------------------------------------------------------------------------
339f29dbc25Smrg * GXSubsequentColor8x8PatternFillRect
340f29dbc25Smrg *
341f29dbc25Smrg * Description  :see GXSetupForColor8x8PatternFill.
342f29dbc25Smrg *
343f29dbc25Smrg *    Arg        Type     Comment
344f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
345f29dbc25Smrg *   patx         int     pattern phase x offset
346f29dbc25Smrg *   paty         int     pattern phase y offset
347f29dbc25Smrg *      x         int     destination x offset
348f29dbc25Smrg *      y         int     destination y offset
349f29dbc25Smrg *      w         int     fill area width (pixels)
350f29dbc25Smrg *      h         int     fill area height (pixels)
351f29dbc25Smrg *
352f29dbc25Smrg * Returns      :none
353f29dbc25Smrg *
354f29dbc25Smrg * Sample application uses:
355f29dbc25Smrg *   - Patterned desktops
356f29dbc25Smrg *   - x11perf: stippled rectangle tests (-srect500).
357f29dbc25Smrg *   - x11perf: opaque stippled rectangle tests (-osrect500).
358f29dbc25Smrg *--------------------------------------------------------------------------*/
359f29dbc25Smrgstatic void
360f29dbc25SmrgGXSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrni, int patx, int paty,
361f29dbc25Smrg    int x, int y, int w, int h)
362f29dbc25Smrg{
363f29dbc25Smrg    //ErrorF(
364f29dbc25Smrg    //    "GXSubsequentColor8x8PatternFillRect() patxy %d,%d at %d,%d %dsx%d\n",
365f29dbc25Smrg    //    patx, paty, x, y, w, h);
366f29dbc25Smrg    gfx2_set_pattern_origin(patx, paty);
367f29dbc25Smrg    gfx2_color_pattern_fill(CALC_FBOFFSET(x, y), w, h, gc8x8p);
368f29dbc25Smrg}
369f29dbc25Smrg
370f29dbc25Smrg/* GX_CLREXP_8X8_PAT_SUPPORT */
371f29dbc25Smrg#endif
372f29dbc25Smrg
373f29dbc25Smrg#if GX_MONO_8X8_PAT_SUPPORT
374f29dbc25Smrg/*----------------------------------------------------------------------------
375f29dbc25Smrg * GXSetupForMono8x8PatternFill
376f29dbc25Smrg *
377f29dbc25Smrg * Description  :8x8 mono pattern data is 64 bits of color expansion data
378f29dbc25Smrg *               with ones indicating the foreground color and zeros
379f29dbc25Smrg *               indicating the background color.  These patterns are
380f29dbc25Smrg *               useful when tiling, doing opaque stipples, or regular
381f29dbc25Smrg *               stipples.
382f29dbc25Smrg *
383f29dbc25Smrg *    Arg        Type     Comment
384f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
385f29dbc25Smrg *    patx        int     x offset to pattern data
386f29dbc25Smrg *    paty        int     y offset to pattern data
387f29dbc25Smrg *     fg         int     foreground color
388f29dbc25Smrg *     bg         int     -1 (transparent) or background color
389f29dbc25Smrg *    rop         int     unmapped raster operation
390f29dbc25Smrg * planemask     uint     -1 (copy) or pattern data
391f29dbc25Smrg *
392f29dbc25Smrg * Returns      :none.
393f29dbc25Smrg *
394f29dbc25Smrg * Comments     :none.
395f29dbc25Smrg *
396f29dbc25Smrg *--------------------------------------------------------------------------*/
397f29dbc25Smrgstatic void
398f29dbc25SmrgGXSetupForMono8x8PatternFill(ScrnInfoPtr pScrni, int patx, int paty,
399f29dbc25Smrg    int fg, int bg, int rop, uint planemask)
400f29dbc25Smrg{
401f29dbc25Smrg    //ErrorF(
402f29dbc25Smrg    //"GXSetupForMono8x8PatternFill() pat %#x,%#x fg %#x bg %#x %#x %#x\n",
403f29dbc25Smrg    //patx, paty, fg, bg, rop, planemask);
404f29dbc25Smrg    rop &= 0x0F;
405f29dbc25Smrg#ifndef OPT_ACCEL
406f29dbc25Smrg    gfx_set_mono_pattern(bg, fg, patx, paty, bg == -1 ? 1 : 0);
407f29dbc25Smrg    gfx_set_raster_operation(planemask == ~0U ? PDfn[rop] :
408f29dbc25Smrg	(gfx_set_solid_source(planemask), PDfn_SM[rop]));
409f29dbc25Smrg#else
410f29dbc25Smrg    {
411f29dbc25Smrg	unsigned int ROP = BPP |
412f29dbc25Smrg	    (bg ==
413f29dbc25Smrg	    -1 ? MGP_RM_PAT_MONO | MGP_RM_PAT_TRANS : MGP_RM_PAT_MONO) |
414f29dbc25Smrg	    (planemask == ~0U ? PDfn[rop] : PDfn_SM[rop]);
415f29dbc25Smrg	BLT_MODE = ((ROP ^ (ROP >> 2)) & 0x33) == 0 ? MGP_BM_SRC_MONO : 0;
416f29dbc25Smrg	if (((ROP ^ (ROP >> 1)) & 0x55) != 0)
417f29dbc25Smrg	    BLT_MODE |= MGP_BM_DST_REQ;
418f29dbc25Smrg	GU2_WAIT_PENDING;
419f29dbc25Smrg	WRITE_GP32(MGP_RASTER_MODE, ROP);
420f29dbc25Smrg	WRITE_GP32(MGP_SRC_COLOR_FG, planemask);
421f29dbc25Smrg	WRITE_GP32(MGP_PAT_COLOR_0, bg);
422f29dbc25Smrg	WRITE_GP32(MGP_PAT_COLOR_1, fg);
423f29dbc25Smrg	WRITE_GP32(MGP_PAT_DATA_0, patx);
424f29dbc25Smrg	WRITE_GP32(MGP_PAT_DATA_1, paty);
425f29dbc25Smrg	WRITE_GP32(MGP_STRIDE, ACCEL_STRIDE);
426f29dbc25Smrg    }
427f29dbc25Smrg#endif
428f29dbc25Smrg}
429f29dbc25Smrg
430f29dbc25Smrg/*----------------------------------------------------------------------------
431f29dbc25Smrg * GXSubsequentMono8x8PatternFillRect
432f29dbc25Smrg *
433f29dbc25Smrg * Description  :see GXSetupForMono8x8PatternFill
434f29dbc25Smrg *
435f29dbc25Smrg *    Arg        Type     Comment
436f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
437f29dbc25Smrg *   patx         int     pattern phase x offset
438f29dbc25Smrg *   paty         int     pattern phase y offset
439f29dbc25Smrg *      x         int     destination x offset
440f29dbc25Smrg *      y         int     destination y offset
441f29dbc25Smrg *      w         int     fill area width (pixels)
442f29dbc25Smrg *      h         int     fill area height (pixels)
443f29dbc25Smrg
444f29dbc25Smrg * Returns      :none
445f29dbc25Smrg *
446f29dbc25Smrg * Sample application uses:
447f29dbc25Smrg *   - Patterned desktops
448f29dbc25Smrg *   - x11perf: stippled rectangle tests (-srect500).
449f29dbc25Smrg *   - x11perf: opaque stippled rectangle tests (-osrect500).
450f29dbc25Smrg *--------------------------------------------------------------------------*/
451f29dbc25Smrgstatic void
452f29dbc25SmrgGXSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrni, int patx, int paty,
453f29dbc25Smrg    int x, int y, int w, int h)
454f29dbc25Smrg{
455f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() pat %#x,%#x at %d,%d %dx%d\n",
456f29dbc25Smrg	    __func__, patx, paty, x, y, w, h));
457f29dbc25Smrg#ifndef OPT_ACCEL
458f29dbc25Smrg    gfx_pattern_fill(x, y, w, h);
459f29dbc25Smrg#else
460f29dbc25Smrg    {
461f29dbc25Smrg	unsigned int offset =
462f29dbc25Smrg	    CALC_FBOFFSET(x, y) | ((x & 7) << 26) | ((y & 7) << 29);
463f29dbc25Smrg	unsigned int size = (w << 16) | h;
464f29dbc25Smrg
465f29dbc25Smrg	GU2_WAIT_PENDING;
466f29dbc25Smrg	WRITE_GP32(MGP_DST_OFFSET, offset);
467f29dbc25Smrg	WRITE_GP32(MGP_WID_HEIGHT, size);
468f29dbc25Smrg	WRITE_GP32(MGP_BLT_MODE, BLT_MODE);
469f29dbc25Smrg    }
470f29dbc25Smrg#endif
471f29dbc25Smrg}
472f29dbc25Smrg
473f29dbc25Smrg#endif /* GX_MONO_8X8_PAT_SUPPORT */
474f29dbc25Smrg
475f29dbc25Smrg#if GX_SCR2SCRCPY_SUPPORT
476f29dbc25Smrg/*----------------------------------------------------------------------------
477f29dbc25Smrg * GXSetupForScreenToScreenCopy
478f29dbc25Smrg *
479f29dbc25Smrg * Description  :SetupFor and Subsequent ScreenToScreenCopy functions
480f29dbc25Smrg *               provide an interface for copying rectangular areas from
481f29dbc25Smrg *               video memory to video memory.
482f29dbc25Smrg *
483f29dbc25Smrg *    Arg        Type     Comment
484f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
485f29dbc25Smrg *   xdir         int     x copy direction (up/dn)
486f29dbc25Smrg *   ydir         int     y copy direction (up/dn)
487f29dbc25Smrg *    rop         int     unmapped raster operation
488f29dbc25Smrg * planemask     uint     -1 (copy) or pattern data
489f29dbc25Smrg * trans_color    int     -1 (copy) or transparent color
490f29dbc25Smrg *
491f29dbc25Smrg * Returns      :none
492f29dbc25Smrg *---------------------------------------------------------------------------*/
493f29dbc25Smrgstatic void
494f29dbc25SmrgGXSetupForScreenToScreenCopy(ScrnInfoPtr pScrni, int xdir, int ydir, int rop,
495f29dbc25Smrg    uint planemask, int trans_color)
496f29dbc25Smrg{
497f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() xd%d yd%d rop %#x %#x %#x\n",
498f29dbc25Smrg	    __func__, xdir, ydir, rop, planemask, trans_color));
499f29dbc25Smrg    rop &= 0x0F;
500f29dbc25Smrg#ifndef OPT_ACCEL
501f29dbc25Smrg    {
502f29dbc25Smrg	GeodeRec *pGeode = GEODEPTR(pScrni);
503f29dbc25Smrg
504f29dbc25Smrg	gfx_set_solid_pattern(planemask);
505f29dbc25Smrg	/* transparency is a parameter to set_rop, but set...pattern clears
506f29dbc25Smrg	 * transparency */
507f29dbc25Smrg	if (trans_color == -1)
508f29dbc25Smrg	    gfx2_set_source_transparency(0, 0);
509f29dbc25Smrg	else
510f29dbc25Smrg	    gfx2_set_source_transparency(trans_color, ~0);
511f29dbc25Smrg	gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
512f29dbc25Smrg	gfx2_set_source_stride(pGeode->Pitch);
513f29dbc25Smrg	gfx2_set_destination_stride(pGeode->Pitch);
514f29dbc25Smrg    }
515f29dbc25Smrg#else
516f29dbc25Smrg    {
517f29dbc25Smrg	unsigned int ROP =
518f29dbc25Smrg	    BPP | (planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
519f29dbc25Smrg	if (trans_color != -1)
520f29dbc25Smrg	    ROP |= MGP_RM_SRC_TRANS;
521f29dbc25Smrg	BLT_MODE = ((ROP ^ (ROP >> 1)) & 0x55) != 0 ?
522f29dbc25Smrg	    MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
523f29dbc25Smrg	GU2_WAIT_PENDING;
524f29dbc25Smrg	WRITE_GP32(MGP_RASTER_MODE, ROP);
525f29dbc25Smrg	WRITE_GP32(MGP_PAT_COLOR_0, planemask);
526f29dbc25Smrg	WRITE_GP32(MGP_SRC_COLOR_FG, trans_color);
527f29dbc25Smrg	WRITE_GP32(MGP_SRC_COLOR_BG, ~0);
528f29dbc25Smrg	WRITE_GP32(MGP_STRIDE, ACCEL_STRIDE);
529f29dbc25Smrg    }
530f29dbc25Smrg#endif
531f29dbc25Smrg}
532f29dbc25Smrg
533f29dbc25Smrg/*----------------------------------------------------------------------------
534f29dbc25Smrg * GXSubsquentScreenToScreenCopy
535f29dbc25Smrg *
536f29dbc25Smrg * Description  :see GXSetupForScreenToScreenCopy.
537f29dbc25Smrg *
538f29dbc25Smrg *    Arg        Type     Comment
539f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
540f29dbc25Smrg *     x1         int     source x offset
541f29dbc25Smrg *     y1         int     source y offset
542f29dbc25Smrg *     x2         int     destination x offset
543f29dbc25Smrg *     y2         int     destination y offset
544f29dbc25Smrg *      w         int     copy area width (pixels)
545f29dbc25Smrg *      h         int     copy area height (pixels)
546f29dbc25Smrg *
547f29dbc25Smrg * Returns      :none
548f29dbc25Smrg *
549f29dbc25Smrg * Sample application uses (non-transparent):
550f29dbc25Smrg *   - Moving windows.
551f29dbc25Smrg *   - x11perf: scroll tests (-scroll500).
552f29dbc25Smrg *   - x11perf: copy from window to window (-copywinwin500).
553f29dbc25Smrg *---------------------------------------------------------------------------*/
554f29dbc25Smrgstatic void
555f29dbc25SmrgGXSubsequentScreenToScreenCopy(ScrnInfoPtr pScrni,
556f29dbc25Smrg    int x1, int y1, int x2, int y2, int w, int h)
557f29dbc25Smrg{
558f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() from %d,%d to %d,%d %dx%d\n",
559f29dbc25Smrg	    __func__, x1, y1, x2, y2, w, h));
560f29dbc25Smrg#ifndef OPT_ACCEL
561f29dbc25Smrg    {
562f29dbc25Smrg	int flags = 0;
563f29dbc25Smrg
564f29dbc25Smrg	if (x2 > x1)
565f29dbc25Smrg	    flags |= 1;
566f29dbc25Smrg	if (y2 > y1)
567f29dbc25Smrg	    flags |= 2;
568f29dbc25Smrg	gfx2_screen_to_screen_blt(CALC_FBOFFSET(x1, y1), CALC_FBOFFSET(x2,
569f29dbc25Smrg		y2), w, h, flags);
570f29dbc25Smrg    }
571f29dbc25Smrg#else
572f29dbc25Smrg    {
573f29dbc25Smrg	GeodeRec *pGeode = GEODEPTR(pScrni);
574f29dbc25Smrg	unsigned int src = CALC_FBOFFSET(x1, y1);
575f29dbc25Smrg	unsigned int dst = CALC_FBOFFSET(x2, y2);
576f29dbc25Smrg	unsigned int size = (w << 16) | h;
577f29dbc25Smrg	unsigned int blt_mode = BLT_MODE;
578f29dbc25Smrg
579f29dbc25Smrg	if (x2 > x1) {
580f29dbc25Smrg	    int n = (w << gu2_xshift) - 1;
581f29dbc25Smrg
582f29dbc25Smrg	    src += n;
583f29dbc25Smrg	    dst += n;
584f29dbc25Smrg	    blt_mode |= MGP_BM_NEG_XDIR;
585f29dbc25Smrg	}
586f29dbc25Smrg	if (y2 > y1) {
587f29dbc25Smrg	    int n = (h - 1) * pGeode->Pitch;
588f29dbc25Smrg
589f29dbc25Smrg	    src += n;
590f29dbc25Smrg	    dst += n;
591f29dbc25Smrg	    blt_mode |= MGP_BM_NEG_YDIR;
592f29dbc25Smrg	}
593f29dbc25Smrg	GU2_WAIT_PENDING;
594f29dbc25Smrg	WRITE_GP32(MGP_SRC_OFFSET, src);
595f29dbc25Smrg	WRITE_GP32(MGP_DST_OFFSET, dst);
596f29dbc25Smrg	WRITE_GP32(MGP_WID_HEIGHT, size);
597f29dbc25Smrg	WRITE_GP16(MGP_BLT_MODE, blt_mode);
598f29dbc25Smrg    }
599f29dbc25Smrg#endif
600f29dbc25Smrg}
601f29dbc25Smrg
602f29dbc25Smrg#endif /* if GX_SCR2SCRCPY_SUPPORT */
603f29dbc25Smrg
604f29dbc25Smrg#if GX_SCANLINE_SUPPORT
605f29dbc25Smrg/*----------------------------------------------------------------------------
606f29dbc25Smrg * GXSetupForScanlineImageWrite
607f29dbc25Smrg *
608f29dbc25Smrg * Description  :SetupFor/Subsequent ScanlineImageWrite and ImageWriteScanline
609f29dbc25Smrg *               transfer full color pixel data from system memory to video
610f29dbc25Smrg *               memory.  This is useful for dealing with alignment issues and
611f29dbc25Smrg *               performing raster ops on the data.
612f29dbc25Smrg *
613f29dbc25Smrg *    Arg        Type     Comment
614f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
615f29dbc25Smrg *    rop         int     unmapped raster operation
616f29dbc25Smrg * planemask     uint     -1 (copy) or pattern data
617f29dbc25Smrg *    bpp         int     bits per pixel (unused)
618f29dbc25Smrg *  depth         int     color depth (unused)
619f29dbc25Smrg *
620f29dbc25Smrg * Returns      :none
621f29dbc25Smrg *
622f29dbc25Smrg *  x11perf -putimage10
623f29dbc25Smrg *  x11perf -putimage100
624f29dbc25Smrg *  x11perf -putimage500
625f29dbc25Smrg *----------------------------------------------------------------------------
626f29dbc25Smrg */
627f29dbc25Smrgstatic void
628f29dbc25SmrgGXSetupForScanlineImageWrite(ScrnInfoPtr pScrni, int rop, uint planemask,
629f29dbc25Smrg    int trans_color, int bpp, int depth)
630f29dbc25Smrg{
631f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR(pScrni);
632f29dbc25Smrg
633f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() rop %#x %#x %#x %d %d\n",
634f29dbc25Smrg	    __func__, rop, planemask, trans_color, bpp, depth));
635f29dbc25Smrg    rop &= 0x0F;
636f29dbc25Smrg    /* transparency is a parameter to set_rop, but set...pattern clears
637f29dbc25Smrg     * transparency */
638f29dbc25Smrg    gfx_set_solid_pattern(planemask);
639f29dbc25Smrg    if (trans_color == -1)
640f29dbc25Smrg	gfx2_set_source_transparency(0, 0);
641f29dbc25Smrg    else
642f29dbc25Smrg	gfx2_set_source_transparency(trans_color, ~0);
643f29dbc25Smrg    gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
644f29dbc25Smrg    gfx2_set_source_stride(pGeode->Pitch);
645f29dbc25Smrg    gfx2_set_destination_stride(pGeode->Pitch);
646f29dbc25Smrg}
647f29dbc25Smrg
648f29dbc25Smrg/*----------------------------------------------------------------------------
649f29dbc25Smrg * GXSubsequentScanlineImageWriteRect
650f29dbc25Smrg *
651f29dbc25Smrg * Description  : see GXSetupForScanlineImageWrite.
652f29dbc25Smrg *
653f29dbc25Smrg *    Arg        Type     Comment
654f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
655f29dbc25Smrg *      x         int     destination x offset
656f29dbc25Smrg *      y         int     destination y offset
657f29dbc25Smrg *      w         int     copy area width (pixels)
658f29dbc25Smrg *      h         int     copy area height (pixels)
659f29dbc25Smrg * skipleft       int     x margin (pixels) to skip (not enabled)
660f29dbc25Smrg *
661f29dbc25Smrg * Returns      :none
662f29dbc25Smrg *---------------------------------------------------------------------------*/
663f29dbc25Smrgstatic void
664f29dbc25SmrgGXSubsequentScanlineImageWriteRect(ScrnInfoPtr pScrni,
665f29dbc25Smrg    int x, int y, int w, int h, int skipleft)
666f29dbc25Smrg{
667f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() rop %d,%d %dx%d %d\n",
668f29dbc25Smrg	    __func__, x, y, w, h, skipleft));
669f29dbc25Smrg    giwr.x = x;
670f29dbc25Smrg    giwr.y = y;
671f29dbc25Smrg    giwr.w = w;
672f29dbc25Smrg    giwr.h = h;
673f29dbc25Smrg#if !GX_USE_OFFSCRN_MEM
674f29dbc25Smrg#if !GX_ONE_LINE_AT_A_TIME
675f29dbc25Smrg    GXAccelSync(pScrni);
676f29dbc25Smrg#endif
677f29dbc25Smrg#endif
678f29dbc25Smrg}
679f29dbc25Smrg
680f29dbc25Smrg/*----------------------------------------------------------------------------
681f29dbc25Smrg * GXSubsquentImageWriteScanline
682f29dbc25Smrg *
683f29dbc25Smrg * Description  : see GXSetupForScanlineImageWrite.
684f29dbc25Smrg *
685f29dbc25Smrg *    Arg        Type     Comment
686f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
687f29dbc25Smrg *  bufno         int     scanline number in write group
688f29dbc25Smrg *
689f29dbc25Smrg * Returns      :none
690f29dbc25Smrg *
691f29dbc25Smrg * Sample application uses (non-transparent):
692f29dbc25Smrg *   - Moving windows.
693f29dbc25Smrg *   - x11perf: scroll tests (-scroll500).
694f29dbc25Smrg *   - x11perf: copy from window to window (-copywinwin500).
695f29dbc25Smrg *
696f29dbc25Smrg *---------------------------------------------------------------------------*/
697f29dbc25Smrgstatic void
698f29dbc25SmrgGXSubsequentImageWriteScanline(ScrnInfoPtr pScrni, int bufno)
699f29dbc25Smrg{
700f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR(pScrni);
701f29dbc25Smrg
702f29dbc25Smrg#if !GX_USE_OFFSCRN_MEM
703f29dbc25Smrg    unsigned long offset;
704f29dbc25Smrg#endif
705f29dbc25Smrg
706f29dbc25Smrg#if GX_ONE_LINE_AT_A_TIME
707f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %d\n", __func__, bufno));
708f29dbc25Smrg#if !GX_USE_OFFSCRN_MEM
709f29dbc25Smrg    offset = pGeode->AccelImageWriteBuffers[bufno] - pGeode->FBBase;
710f29dbc25Smrg    gfx2_screen_to_screen_blt(offset, CALC_FBOFFSET(giwr.x, giwr.y), giwr.w,
711f29dbc25Smrg	1, 0);
712f29dbc25Smrg#else /* if !GX_USE_OFFSCRN_MEM */
713f29dbc25Smrg    gfx2_color_bitmap_to_screen_blt(0, 0, CALC_FBOFFSET(giwr.x, giwr.y),
714f29dbc25Smrg	giwr.w, 1, pGeode->AccelImageWriteBuffers[bufno], pGeode->Pitch);
715f29dbc25Smrg#endif /* if !GX_USE_OFFSCRN_MEM */
716f29dbc25Smrg    ++giwr.y;
717f29dbc25Smrg#else /* if GX_ONE_LINE_AT_A_TIME */
718f29dbc25Smrg    int blt_height;
719f29dbc25Smrg
720f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %d\n", __func__, bufno));
721f29dbc25Smrg
722f29dbc25Smrg    if ((blt_height = pGeode->NoOfImgBuffers) > giwr.h)
723f29dbc25Smrg	blt_height = giwr.h;
724f29dbc25Smrg    if (++bufno < blt_height)
725f29dbc25Smrg	return;
726f29dbc25Smrg#if !GX_USE_OFFSCRN_MEM
727f29dbc25Smrg    offset = pGeode->AccelImageWriteBuffers[0] - pGeode->FBBase;
728f29dbc25Smrg    gfx2_screen_to_screen_blt(offset, CALC_FBOFFSET(giwr.x, giwr.y), giwr.w,
729f29dbc25Smrg	blt_height, 0);
730f29dbc25Smrg    GXAccelSync(pScrni);
731f29dbc25Smrg#else /* if !GX_USE_OFFSCRN_MEM */
732f29dbc25Smrg    gfx2_color_bitmap_to_screen_blt(0, 0, CALC_FBOFFSET(giwr.x, giwr.y),
733f29dbc25Smrg	giwr.w, blt_height, pGeode->AccelImageWriteBuffers[0], pGeode->Pitch);
734f29dbc25Smrg#endif /* if !GX_USE_OFFSCRN_MEM */
735f29dbc25Smrg    giwr.h -= blt_height;
736f29dbc25Smrg    giwr.y += blt_height;
737f29dbc25Smrg#endif /* if GX_ONE_LINE_AT_A_TIME */
738f29dbc25Smrg}
739f29dbc25Smrg#endif /* GX_SCANLINE_SUPPORT */
740f29dbc25Smrg
741f29dbc25Smrg#if GX_CPU2SCREXP_SUPPORT
742f29dbc25Smrg/*----------------------------------------------------------------------------
743f29dbc25Smrg * GXSetupForScanlineCPUToScreenColorExpandFill
744f29dbc25Smrg *
745f29dbc25Smrg * Description  :SetupFor/Subsequent CPUToScreenColorExpandFill and
746f29dbc25Smrg *               ColorExpandScanline routines provide an interface for
747f29dbc25Smrg *               doing expansion blits from source patterns stored in
748f29dbc25Smrg *               system memory.
749f29dbc25Smrg *
750f29dbc25Smrg *    Arg        Type     Comment
751f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
752f29dbc25Smrg *     fg         int     foreground color
753f29dbc25Smrg *     bg         int     -1 (transparent) or background color
754f29dbc25Smrg *    rop         int     unmapped raster operation
755f29dbc25Smrg * planemask     uint     -1 (copy) or pattern data
756f29dbc25Smrg *
757f29dbc25Smrg * Returns      :none.
758f29dbc25Smrg *---------------------------------------------------------------------------*/
759f29dbc25Smrg
760f29dbc25Smrgstatic void
761f29dbc25SmrgGXSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrni,
762f29dbc25Smrg    int fg, int bg, int rop, uint planemask)
763f29dbc25Smrg{
764f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR(pScrni);
765f29dbc25Smrg    ulong srcpitch;
766f29dbc25Smrg
767f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() fg %#x bg %#x rop %#x %#x\n",
768f29dbc25Smrg	    __func__, fg, bg, rop, planemask));
769f29dbc25Smrg    rop &= 0x0F;
770f29dbc25Smrg    srcpitch = ((pGeode->Pitch + 31) >> 5) << 2;
771f29dbc25Smrg#ifndef OPT_ACCEL
772f29dbc25Smrg    gfx_set_solid_pattern(planemask);
773f29dbc25Smrg    gfx_set_mono_source(bg, fg, bg == -1 ? 1 : 0);
774f29dbc25Smrg    gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
775f29dbc25Smrg    gfx2_set_source_stride(srcpitch);
776f29dbc25Smrg    gfx2_set_destination_stride(pGeode->Pitch);
777f29dbc25Smrg#else
778f29dbc25Smrg    {
779f29dbc25Smrg	unsigned int stride = (srcpitch << 16) | pGeode->Pitch;
780f29dbc25Smrg	unsigned int ROP =
781f29dbc25Smrg	    BPP | (planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
782f29dbc25Smrg	if (bg == -1)
783f29dbc25Smrg	    ROP |= MGP_RM_SRC_TRANS;
784f29dbc25Smrg	BLT_MODE = ((ROP ^ (ROP >> 1)) & 0x55) != 0 ?
785f29dbc25Smrg	    MGP_BM_SRC_MONO | MGP_BM_SRC_FB | MGP_BM_DST_REQ :
786f29dbc25Smrg	    MGP_BM_SRC_MONO | MGP_BM_SRC_FB;
787f29dbc25Smrg	GU2_WAIT_PENDING;
788f29dbc25Smrg	WRITE_GP32(MGP_RASTER_MODE, ROP);
789f29dbc25Smrg	WRITE_GP32(MGP_PAT_COLOR_0, planemask);
790f29dbc25Smrg	WRITE_GP32(MGP_SRC_COLOR_BG, bg);
791f29dbc25Smrg	WRITE_GP32(MGP_SRC_COLOR_FG, fg);
792f29dbc25Smrg	WRITE_GP32(MGP_STRIDE, stride);
793f29dbc25Smrg    }
794f29dbc25Smrg#endif
795f29dbc25Smrg}
796f29dbc25Smrg
797f29dbc25Smrg/*----------------------------------------------------------------------------
798f29dbc25Smrg * GXSubsequentScanlineCPUToScreenColorExpandFill
799f29dbc25Smrg *
800f29dbc25Smrg  Description  :see GXSetupForScanlineCPUToScreenColorExpandFill
801f29dbc25Smrg *
802f29dbc25Smrg * Parameters:
803f29dbc25Smrg *    Arg        Type     Comment
804f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
805f29dbc25Smrg *     x          int     destination x offset
806f29dbc25Smrg *     y          int     destination y offset
807f29dbc25Smrg *     w          int     fill area width (pixels)
808f29dbc25Smrg *     h          int     fill area height (pixels)
809f29dbc25Smrg *
810f29dbc25Smrg * Returns      :none
811f29dbc25Smrg *
812f29dbc25Smrg *---------------------------------------------------------------------------*/
813f29dbc25Smrgstatic void
814f29dbc25SmrgGXSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrni,
815f29dbc25Smrg    int x, int y, int w, int h, int skipleft)
816f29dbc25Smrg{
817f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %dx%d %d\n",
818f29dbc25Smrg	    __func__, x, y, w, h, skipleft));
819f29dbc25Smrg    gc2s.x = x;
820f29dbc25Smrg    gc2s.y = y;
821f29dbc25Smrg    gc2s.w = w;
822f29dbc25Smrg    gc2s.h = h;
823f29dbc25Smrg#ifdef OPT_ACCEL
824f29dbc25Smrg    {
825f29dbc25Smrg#if GX_ONE_LINE_AT_A_TIME
826f29dbc25Smrg	unsigned int size = (gc2s.w << 16) | 1;
827f29dbc25Smrg
828f29dbc25Smrg	GU2_WAIT_PENDING;
829f29dbc25Smrg	WRITE_GP32(MGP_WID_HEIGHT, size);
830f29dbc25Smrg#else
831f29dbc25Smrg	GeodeRec *pGeode = GEODEPTR(pScrni);
832f29dbc25Smrg	unsigned int src =
833f29dbc25Smrg	    pGeode->AccelColorExpandBuffers[0] - pGeode->FBBase;
834f29dbc25Smrg	GU2_WAIT_PENDING;
835f29dbc25Smrg	WRITE_GP32(MGP_SRC_OFFSET, src);
836f29dbc25Smrg#endif
837f29dbc25Smrg    }
838f29dbc25Smrg#endif
839f29dbc25Smrg}
840f29dbc25Smrg
841f29dbc25Smrg/*----------------------------------------------------------------------------
842f29dbc25Smrg * GXSubsequentColorExpandScanline
843f29dbc25Smrg *
844f29dbc25Smrg * Description  :see GXSetupForScanlineCPUToScreenColorExpandFill
845f29dbc25Smrg *
846f29dbc25Smrg *    Arg        Type     Comment
847f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
848f29dbc25Smrg *  bufno         int     scanline number in write group
849f29dbc25Smrg *
850f29dbc25Smrg * Returns      :none
851f29dbc25Smrg *----------------------------------------------------------------------------
852f29dbc25Smrg */
853f29dbc25Smrgstatic void
854f29dbc25SmrgGXSubsequentColorExpandScanline(ScrnInfoPtr pScrni, int bufno)
855f29dbc25Smrg{
856f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR(pScrni);
857f29dbc25Smrg
858f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %d\n", __func__, bufno));
859f29dbc25Smrg#ifndef OPT_ACCEL
860f29dbc25Smrg    {
861f29dbc25Smrg#if GX_ONE_LINE_AT_A_TIME
862f29dbc25Smrg	ulong offset =
863f29dbc25Smrg	    pGeode->AccelColorExpandBuffers[bufno] - pGeode->FBBase;
864f29dbc25Smrg	gfx2_mono_expand_blt(offset, 0, 0, CALC_FBOFFSET(gc2s.x, gc2s.y),
865f29dbc25Smrg	    gc2s.w, 1, 0);
866f29dbc25Smrg	++gc2s.y;
867f29dbc25Smrg#else /* if GX_ONE_LINE_AT_A_TIME */
868f29dbc25Smrg	ulong srcpitch;
869f29dbc25Smrg	int blt_height;
870f29dbc25Smrg
871f29dbc25Smrg	if ((blt_height = pGeode->NoOfImgBuffers) > gc2s.h)
872f29dbc25Smrg	    blt_height = gc2s.h;
873f29dbc25Smrg	if (++bufno < blt_height)
874f29dbc25Smrg	    return;
875f29dbc25Smrg
876f29dbc25Smrg	/* convert from bits to dwords */
877f29dbc25Smrg	srcpitch = ((pGeode->Pitch + 31) >> 5) << 2;
878f29dbc25Smrg	gfx2_mono_bitmap_to_screen_blt(0, 0, CALC_FBOFFSET(gc2s.x, gc2s.y),
879f29dbc25Smrg	    gc2s.w, blt_height, pGeode->AccelColorExpandBuffers[0], srcpitch);
880f29dbc25Smrg	gc2s.h -= blt_height;
881f29dbc25Smrg	gc2s.y += blt_height;
882f29dbc25Smrg#endif /* if GX_ONE_LINE_AT_A_TIME */
883f29dbc25Smrg    }
884f29dbc25Smrg#else /* ifndef OPT_ACCEL */
885f29dbc25Smrg    {
886f29dbc25Smrg#if GX_ONE_LINE_AT_A_TIME
887f29dbc25Smrg	unsigned int src =
888f29dbc25Smrg	    pGeode->AccelColorExpandBuffers[bufno] - pGeode->FBBase;
889f29dbc25Smrg	unsigned int dst = CALC_FBOFFSET(gc2s.x, gc2s.y);
890f29dbc25Smrg
891f29dbc25Smrg	++gc2s.y;
892f29dbc25Smrg	GU2_WAIT_PENDING;
893f29dbc25Smrg	WRITE_GP32(MGP_SRC_OFFSET, src);
894f29dbc25Smrg	WRITE_GP32(MGP_DST_OFFSET, dst);
895f29dbc25Smrg	WRITE_GP16(MGP_BLT_MODE, BLT_MODE);
896f29dbc25Smrg#else /* if GX_ONE_LINE_AT_A_TIME */
897f29dbc25Smrg	unsigned int dst, size;
898f29dbc25Smrg	int blt_height;
899f29dbc25Smrg
900f29dbc25Smrg	GU2_WAIT_BUSY;
901f29dbc25Smrg	if ((blt_height = pGeode->NoOfImgBuffers) > gc2s.h)
902f29dbc25Smrg	    blt_height = gc2s.h;
903f29dbc25Smrg	if (++bufno < blt_height)
904f29dbc25Smrg	    return;
905f29dbc25Smrg	dst = CALC_FBOFFSET(gc2s.x, gc2s.y);
906f29dbc25Smrg	size = (gc2s.w << 16) | blt_height;
907f29dbc25Smrg	gc2s.h -= blt_height;
908f29dbc25Smrg	gc2s.y += blt_height;
909f29dbc25Smrg	GU2_WAIT_PENDING;
910f29dbc25Smrg	WRITE_GP32(MGP_DST_OFFSET, dst);
911f29dbc25Smrg	WRITE_GP32(MGP_WID_HEIGHT, size);
912f29dbc25Smrg	WRITE_GP16(MGP_BLT_MODE, BLT_MODE);
913f29dbc25Smrg#endif /* if GX_ONE_LINE_AT_A_TIME */
914f29dbc25Smrg    }
915f29dbc25Smrg#endif /* ifndef OPT_ACCEL */
916f29dbc25Smrg}
917f29dbc25Smrg#endif /* GX_CPU2SCREXP_SUPPORT */
918f29dbc25Smrg
919f29dbc25Smrg#if GX_SCR2SCREXP_SUPPORT
920f29dbc25Smrg/*----------------------------------------------------------------------------
921f29dbc25Smrg * GXSetupForScreenToScreenColorExpandFill
922f29dbc25Smrg *
923f29dbc25Smrg * Description  :SetupFor/Subsequent ScreenToScreenColorExpandFill and
924f29dbc25Smrg *               ColorExpandScanline routines provide an interface for
925f29dbc25Smrg *               doing expansion blits from source patterns stored in
926f29dbc25Smrg *               video memory.
927f29dbc25Smrg *
928f29dbc25Smrg *    Arg        Type     Comment
929f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
930f29dbc25Smrg *     fg         int     foreground color
931f29dbc25Smrg *     bg         int     -1 (transparent) or background color
932f29dbc25Smrg *    rop         int     unmapped raster operation
933f29dbc25Smrg * planemask     uint     -1 (copy) or pattern data
934f29dbc25Smrg *
935f29dbc25Smrg * Returns      :none.
936f29dbc25Smrg *---------------------------------------------------------------------------*/
937f29dbc25Smrg
938f29dbc25Smrgstatic void
939f29dbc25SmrgGXSetupForScreenToScreenColorExpandFill(ScrnInfoPtr pScrni, int fg, int bg,
940f29dbc25Smrg    int rop, uint planemask)
941f29dbc25Smrg{
942f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() fg %#x bg %#x rop %#x %#x\n",
943f29dbc25Smrg	    __func__, fg, bg, rop, planemask));
944f29dbc25Smrg    rop &= 0x0F;
945f29dbc25Smrg#ifndef OPT_ACCEL
946f29dbc25Smrg    {
947f29dbc25Smrg	GeodeRec *pGeode = GEODEPTR(pScrni);
948f29dbc25Smrg
949f29dbc25Smrg	gfx_set_solid_pattern(planemask);
950f29dbc25Smrg	gfx_set_mono_source(bg, fg, bg == -1 ? 1 : 0);
951f29dbc25Smrg	gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
952f29dbc25Smrg	gfx2_set_source_stride(pGeode->Pitch);
953f29dbc25Smrg	gfx2_set_destination_stride(pGeode->Pitch);
954f29dbc25Smrg    }
955f29dbc25Smrg#else
956f29dbc25Smrg    {
957f29dbc25Smrg	unsigned int ROP =
958f29dbc25Smrg	    BPP | (planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
959f29dbc25Smrg	if (bg == -1)
960f29dbc25Smrg	    ROP |= MGP_RM_SRC_TRANS;
961f29dbc25Smrg	BLT_MODE = ((ROP ^ (ROP >> 1)) & 0x55) != 0 ?
962f29dbc25Smrg	    MGP_BM_SRC_MONO | MGP_BM_SRC_FB | MGP_BM_DST_REQ :
963f29dbc25Smrg	    MGP_BM_SRC_MONO | MGP_BM_SRC_FB;
964f29dbc25Smrg	GU2_WAIT_PENDING;
965f29dbc25Smrg	WRITE_GP32(MGP_RASTER_MODE, ROP);
966f29dbc25Smrg	WRITE_GP32(MGP_PAT_COLOR_0, planemask);
967f29dbc25Smrg	WRITE_GP32(MGP_SRC_COLOR_BG, bg);
968f29dbc25Smrg	WRITE_GP32(MGP_SRC_COLOR_FG, fg);
969f29dbc25Smrg	WRITE_GP32(MGP_STRIDE, ACCEL_STRIDE);
970f29dbc25Smrg    }
971f29dbc25Smrg#endif
972f29dbc25Smrg}
973f29dbc25Smrg
974f29dbc25Smrg/*----------------------------------------------------------------------------
975f29dbc25Smrg * GXSubsequentScreenToScreenColorExpandFill
976f29dbc25Smrg *
977f29dbc25Smrg * Description  :see GXSetupForScreenToScreenColorExpandFill
978f29dbc25Smrg *
979f29dbc25Smrg * Parameters:
980f29dbc25Smrg *    Arg        Type     Comment
981f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
982f29dbc25Smrg *     x          int     destination x offset
983f29dbc25Smrg *     y          int     destination y offset
984f29dbc25Smrg *     w          int     fill area width (pixels)
985f29dbc25Smrg *     h          int     fill area height (pixels)
986f29dbc25Smrg * offset         int     initial x offset
987f29dbc25Smrg *
988f29dbc25Smrg * Returns      :none
989f29dbc25Smrg *
990f29dbc25Smrg *---------------------------------------------------------------------------*/
991f29dbc25Smrgstatic void
992f29dbc25SmrgGXSubsequentScreenToScreenColorExpandFill(ScrnInfoPtr pScrni,
993f29dbc25Smrg    int x, int y, int w, int h, int srcx, int srcy, int offset)
994f29dbc25Smrg{
995f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %dx%d %d,%d %d\n",
996f29dbc25Smrg	    __func__, x, y, w, h, srcx, srcy, offset));
997f29dbc25Smrg#ifndef OPT_ACCEL
998f29dbc25Smrg    gfx2_mono_expand_blt(CALC_FBOFFSET(srcx, srcy), offset, 0,
999f29dbc25Smrg	CALC_FBOFFSET(x, y), w, h, 0);
1000f29dbc25Smrg#else
1001f29dbc25Smrg    {
1002f29dbc25Smrg	unsigned int src = (CALC_FBOFFSET(srcx,
1003f29dbc25Smrg		srcy) + (offset >> 3)) | ((offset & 7) << 26);
1004f29dbc25Smrg	unsigned int dst = CALC_FBOFFSET(x, y);
1005f29dbc25Smrg	unsigned int size = (w << 16) | h;
1006f29dbc25Smrg
1007f29dbc25Smrg	GU2_WAIT_PENDING;
1008f29dbc25Smrg	WRITE_GP32(MGP_SRC_OFFSET, src);
1009f29dbc25Smrg	WRITE_GP32(MGP_DST_OFFSET, dst);
1010f29dbc25Smrg	WRITE_GP32(MGP_WID_HEIGHT, size);
1011f29dbc25Smrg	WRITE_GP16(MGP_BLT_MODE, BLT_MODE);
1012f29dbc25Smrg    }
1013f29dbc25Smrg#endif
1014f29dbc25Smrg}
1015f29dbc25Smrg#endif /* GX_SCR2SCREXP_SUPPORT */
1016f29dbc25Smrg
1017f29dbc25Smrg#define VM_MAJOR_DEC 0
1018f29dbc25Smrg#define VM_MINOR_DEC 0
1019f29dbc25Smrg
1020f29dbc25Smrgstatic unsigned short vmode[] = {
1021f29dbc25Smrg    VM_X_MAJOR | VM_MAJOR_INC | VM_MINOR_INC,
1022f29dbc25Smrg    /* !XDECREASING !YDECREASING !YMAJOR */
1023f29dbc25Smrg    VM_Y_MAJOR | VM_MAJOR_INC | VM_MINOR_INC,
1024f29dbc25Smrg    /* !XDECREASING !YDECREASING  YMAJOR */
1025f29dbc25Smrg    VM_X_MAJOR | VM_MAJOR_INC | VM_MINOR_DEC,
1026f29dbc25Smrg    /* !XDECREASING  YDECREASING !YMAJOR */
1027f29dbc25Smrg    VM_Y_MAJOR | VM_MAJOR_DEC | VM_MINOR_INC,
1028f29dbc25Smrg    /* !XDECREASING  YDECREASING  YMAJOR */
1029f29dbc25Smrg    VM_X_MAJOR | VM_MAJOR_DEC | VM_MINOR_INC,
1030f29dbc25Smrg    /*  XDECREASING !YDECREASING !YMAJOR */
1031f29dbc25Smrg    VM_Y_MAJOR | VM_MAJOR_INC | VM_MINOR_DEC,
1032f29dbc25Smrg    /*  XDECREASING !YDECREASING  YMAJOR */
1033f29dbc25Smrg    VM_X_MAJOR | VM_MAJOR_DEC | VM_MINOR_DEC,
1034f29dbc25Smrg    /*  XDECREASING  YDECREASING !YMAJOR */
1035f29dbc25Smrg    VM_Y_MAJOR | VM_MAJOR_DEC | VM_MINOR_DEC,
1036f29dbc25Smrg    /*  XDECREASING  YDECREASING  YMAJOR */
1037f29dbc25Smrg};
1038f29dbc25Smrg
1039f29dbc25Smrg#if GX_BRES_LINE_SUPPORT
1040f29dbc25Smrg/*----------------------------------------------------------------------------
1041f29dbc25Smrg * GXSetupForSolidLine
1042f29dbc25Smrg *
1043f29dbc25Smrg * Description  :SetupForSolidLine and Subsequent HorVertLine TwoPointLine
1044f29dbc25Smrg *               BresenhamLine provides an interface for drawing thin
1045f29dbc25Smrg *               solid lines.
1046f29dbc25Smrg *
1047f29dbc25Smrg *    Arg        Type     Comment
1048f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
1049f29dbc25Smrg *   color        int     foreground fill color
1050f29dbc25Smrg *    rop         int     unmapped raster op
1051f29dbc25Smrg * planemask     uint     -1 (fill) or pattern data (not enabled)
1052f29dbc25Smrg *
1053f29dbc25Smrg * Returns		:none
1054f29dbc25Smrg *---------------------------------------------------------------------------*/
1055f29dbc25Smrgstatic void
1056f29dbc25SmrgGXSetupForSolidLine(ScrnInfoPtr pScrni, int color, int rop, uint planemask)
1057f29dbc25Smrg{
1058f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %#x %#x %#x\n",
1059f29dbc25Smrg	    __func__, color, rop, planemask));
1060f29dbc25Smrg    rop &= 0x0F;
1061f29dbc25Smrg#ifndef OPT_ACCEL
1062f29dbc25Smrg    gfx_set_solid_pattern(color);
1063f29dbc25Smrg    gfx_set_raster_operation(planemask == ~0U ? PDfn[rop] :
1064f29dbc25Smrg	(gfx_set_solid_source(planemask), PDfn_SM[rop]));
1065f29dbc25Smrg#else
1066f29dbc25Smrg    {
1067f29dbc25Smrg	unsigned int ROP =
1068f29dbc25Smrg	    BPP | (planemask == ~0U ? PDfn[rop] : PDfn_SM[rop]);
1069f29dbc25Smrg	BLT_MODE = ((ROP ^ (ROP >> 2)) & 0x33) == 0 ? MGP_BM_SRC_MONO : 0;
1070f29dbc25Smrg	VEC_MODE = ((ROP ^ (ROP >> 1)) & 0x55) != 0 ? ((BLT_MODE |=
1071f29dbc25Smrg		MGP_BM_DST_REQ), MGP_VM_DST_REQ) : 0;
1072f29dbc25Smrg	GU2_WAIT_PENDING;
1073f29dbc25Smrg	WRITE_GP32(MGP_RASTER_MODE, ROP);
1074f29dbc25Smrg	WRITE_GP32(MGP_PAT_COLOR_0, color);
1075f29dbc25Smrg	WRITE_GP32(MGP_SRC_COLOR_FG, planemask);
1076f29dbc25Smrg	WRITE_GP32(MGP_STRIDE, ACCEL_STRIDE);
1077f29dbc25Smrg    }
1078f29dbc25Smrg#endif
1079f29dbc25Smrg}
1080f29dbc25Smrg
1081f29dbc25Smrg/*---------------------------------------------------------------------------
1082f29dbc25Smrg * GXSubsequentSolidBresenhamLine
1083f29dbc25Smrg *
1084f29dbc25Smrg * Description  :see GXSetupForSolidLine
1085f29dbc25Smrg *
1086f29dbc25Smrg *    Arg        Type     Comment
1087f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
1088f29dbc25Smrg *     x1         int     destination x offset
1089f29dbc25Smrg *     y1         int     destination y offset
1090f29dbc25Smrg * absmaj         int     Bresenman absolute major
1091f29dbc25Smrg * absmin         int     Bresenman absolute minor
1092f29dbc25Smrg *    err         int     Bresenman initial error term
1093f29dbc25Smrg *    len         int     length of the vector (pixels)
1094f29dbc25Smrg * octant         int     specifies sign and magnitude relationships
1095f29dbc25Smrg *                         used to determine axis of magor rendering
1096f29dbc25Smrg *                         and direction of vector progress.
1097f29dbc25Smrg *
1098f29dbc25Smrg * Returns      :none
1099f29dbc25Smrg *
1100f29dbc25Smrg *   - Window outlines on window move.
1101f29dbc25Smrg *   - x11perf: line segments (-line500).
1102f29dbc25Smrg *   - x11perf: line segments (-seg500).
1103f29dbc25Smrg *---------------------------------------------------------------------------*/
1104f29dbc25Smrgstatic void
1105f29dbc25SmrgGXSubsequentSolidBresenhamLine(ScrnInfoPtr pScrni, int x1, int y1,
1106f29dbc25Smrg    int absmaj, int absmin, int err, int len, int octant)
1107f29dbc25Smrg{
1108f29dbc25Smrg    long axial, diagn;
1109f29dbc25Smrg
1110f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %d %d, %d %d, %d\n",
1111f29dbc25Smrg	    __func__, x1, y1, absmaj, absmin, err, len, octant));
1112f29dbc25Smrg    if (len <= 0)
1113f29dbc25Smrg	return;
1114f29dbc25Smrg    axial = absmin;
1115f29dbc25Smrg    err += axial;
1116f29dbc25Smrg    diagn = absmin - absmaj;
1117f29dbc25Smrg#ifndef OPT_ACCEL
1118f29dbc25Smrg    gfx_bresenham_line(x1, y1, len, err, axial, diagn, vmode[octant]);
1119f29dbc25Smrg#else
1120f29dbc25Smrg    {
1121f29dbc25Smrg	unsigned int offset = CALC_FBOFFSET(x1, y1);
1122f29dbc25Smrg	unsigned int vec_err = (axial << 16) | (unsigned short)diagn;
1123f29dbc25Smrg	unsigned int vec_len = (len << 16) | (unsigned short)err;
1124f29dbc25Smrg	unsigned int vec_mode = VEC_MODE | vmode[octant];
1125f29dbc25Smrg
1126f29dbc25Smrg	GU2_WAIT_PENDING;
1127f29dbc25Smrg	WRITE_GP32(MGP_DST_OFFSET, offset);
1128f29dbc25Smrg	WRITE_GP32(MGP_VEC_ERR, vec_err);
1129f29dbc25Smrg	WRITE_GP32(MGP_VEC_LEN, vec_len);
1130f29dbc25Smrg	WRITE_GP32(MGP_VECTOR_MODE, vec_mode);
1131f29dbc25Smrg    }
1132f29dbc25Smrg#endif
1133f29dbc25Smrg}
1134f29dbc25Smrg
1135f29dbc25Smrg/*---------------------------------------------------------------------------
1136f29dbc25Smrg * GXSubsequentSolidTwoPointLine
1137f29dbc25Smrg *
1138f29dbc25Smrg * Description  :see GXSetupForSolidLine
1139f29dbc25Smrg *
1140f29dbc25Smrg *    Arg        Type     Comment
1141f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
1142f29dbc25Smrg *     x0         int     destination x start offset
1143f29dbc25Smrg *     y0         int     destination y start offset
1144f29dbc25Smrg *     x1         int     destination x end offset
1145f29dbc25Smrg *     y1         int     destination y end offset
1146f29dbc25Smrg *  flags         int     OMIT_LAST, dont draw last pixel (not used)
1147f29dbc25Smrg *
1148f29dbc25Smrg * Returns      :none
1149f29dbc25Smrg *---------------------------------------------------------------------------*/
1150f29dbc25Smrgstatic void
1151f29dbc25SmrgGXSubsequentSolidTwoPointLine(ScrnInfoPtr pScrni, int x0, int y0,
1152f29dbc25Smrg    int x1, int y1, int flags)
1153f29dbc25Smrg{
1154f29dbc25Smrg    long dx, dy, dmaj, dmin, octant, bias;
1155f29dbc25Smrg    long axial, diagn, err, len;
1156f29dbc25Smrg
1157f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %d,%d, %#x\n",
1158f29dbc25Smrg	    __func__, x0, y0, x1, y1, flags));
1159f29dbc25Smrg
1160f29dbc25Smrg    if ((dx = x1 - x0) < 0)
1161f29dbc25Smrg	dx = -dx;
1162f29dbc25Smrg    if ((dy = y1 - y0) < 0)
1163f29dbc25Smrg	dy = -dy;
1164f29dbc25Smrg    if (dy >= dx) {
1165f29dbc25Smrg	dmaj = dy;
1166f29dbc25Smrg	dmin = dx;
1167f29dbc25Smrg	octant = YMAJOR;
1168f29dbc25Smrg    } else {
1169f29dbc25Smrg	dmaj = dx;
1170f29dbc25Smrg	dmin = dy;
1171f29dbc25Smrg	octant = 0;
1172f29dbc25Smrg    }
1173f29dbc25Smrg    len = dmaj;
1174f29dbc25Smrg    if ((flags & OMIT_LAST) == 0)
1175f29dbc25Smrg	++len;
1176f29dbc25Smrg    if (len <= 0)
1177f29dbc25Smrg	return;
1178f29dbc25Smrg    if (x1 < x0)
1179f29dbc25Smrg	octant |= XDECREASING;
1180f29dbc25Smrg    if (y1 < y0)
1181f29dbc25Smrg	octant |= YDECREASING;
1182f29dbc25Smrg
1183f29dbc25Smrg    axial = dmin << 1;
1184f29dbc25Smrg    bias = miGetZeroLineBias(pScrni->pScreen);
1185f29dbc25Smrg    err = axial - dmaj - ((bias >> octant) & 1);
1186f29dbc25Smrg    diagn = (dmin - dmaj) << 1;
1187f29dbc25Smrg
1188f29dbc25Smrg#ifndef OPT_ACCEL
1189f29dbc25Smrg    gfx_bresenham_line(x0, y0, len, err, axial, diagn, vmode[octant]);
1190f29dbc25Smrg#else
1191f29dbc25Smrg    {
1192f29dbc25Smrg	unsigned int offset = CALC_FBOFFSET(x0, y0);
1193f29dbc25Smrg	unsigned int vec_err = (axial << 16) | (unsigned short)diagn;
1194f29dbc25Smrg	unsigned int vec_len = (len << 16) | (unsigned short)err;
1195f29dbc25Smrg	unsigned int vec_mode = VEC_MODE | vmode[octant];
1196f29dbc25Smrg
1197f29dbc25Smrg	GU2_WAIT_PENDING;
1198f29dbc25Smrg	WRITE_GP32(MGP_DST_OFFSET, offset);
1199f29dbc25Smrg	WRITE_GP32(MGP_VEC_ERR, vec_err);
1200f29dbc25Smrg	WRITE_GP32(MGP_VEC_LEN, vec_len);
1201f29dbc25Smrg	WRITE_GP32(MGP_VECTOR_MODE, vec_mode);
1202f29dbc25Smrg    }
1203f29dbc25Smrg#endif
1204f29dbc25Smrg}
1205f29dbc25Smrg
1206f29dbc25Smrg/*---------------------------------------------------------------------------
1207f29dbc25Smrg * GXSubsequentSolidHorVertLine
1208f29dbc25Smrg *
1209f29dbc25Smrg * Description  :see GXSetupForSolidLine
1210f29dbc25Smrg *
1211f29dbc25Smrg *    Arg        Type     Comment
1212f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
1213f29dbc25Smrg *     x          int     destination x offset
1214f29dbc25Smrg *     y          int     destination y offset
1215f29dbc25Smrg *    len         int     length of the vector (pixels)
1216f29dbc25Smrg *    dir         int     DEGREES_270 or DEGREES_0 line direction
1217f29dbc25Smrg *
1218f29dbc25Smrg * Sample application uses:
1219f29dbc25Smrg *   - Window outlines on window move.
1220f29dbc25Smrg *   - x11perf: line segments (-hseg500).
1221f29dbc25Smrg *   - x11perf: line segments (-vseg500).
1222f29dbc25Smrg *---------------------------------------------------------------------------
1223f29dbc25Smrg */
1224f29dbc25Smrgstatic void
1225f29dbc25SmrgGXSubsequentSolidHorVertLine(ScrnInfoPtr pScrni,
1226f29dbc25Smrg    int x, int y, int len, int dir)
1227f29dbc25Smrg{
1228f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %d %d\n", __func__, x, y, len, dir));
1229f29dbc25Smrg#ifndef OPT_ACCEL
1230f29dbc25Smrg    if (dir == DEGREES_0)
1231f29dbc25Smrg	gfx_pattern_fill(x, y, len, 1);
1232f29dbc25Smrg    else
1233f29dbc25Smrg	gfx_pattern_fill(x, y, 1, len);
1234f29dbc25Smrg#else
1235f29dbc25Smrg    {
1236f29dbc25Smrg	unsigned int offset = CALC_FBOFFSET(x, y);
1237f29dbc25Smrg	unsigned int size =
1238f29dbc25Smrg	    dir == DEGREES_0 ? (len << 16) | 1 : (1 << 16) | len;
1239f29dbc25Smrg	GU2_WAIT_PENDING;
1240f29dbc25Smrg	WRITE_GP32(MGP_DST_OFFSET, offset);
1241f29dbc25Smrg	WRITE_GP32(MGP_WID_HEIGHT, size);
1242f29dbc25Smrg	WRITE_GP32(MGP_BLT_MODE, BLT_MODE);
1243f29dbc25Smrg    }
1244f29dbc25Smrg#endif
1245f29dbc25Smrg}
1246f29dbc25Smrg#endif /* GX_BRES_LINE_SUPPORT */
1247f29dbc25Smrg
1248f29dbc25Smrg#if GX_DASH_LINE_SUPPORT
1249f29dbc25Smrg/*----------------------------------------------------------------------------
1250f29dbc25Smrg * GXSetupForDashedLine
1251f29dbc25Smrg *
1252f29dbc25Smrg * Description  :SetupForDashedLine and Subsequent TwoPointLine
1253f29dbc25Smrg *               BresenhamLine provides an interface for drawing thin
1254f29dbc25Smrg *               dashed lines.
1255f29dbc25Smrg *
1256f29dbc25Smrg *    Arg        Type     Comment
1257f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
1258f29dbc25Smrg *     fg         int     foreground fill color
1259f29dbc25Smrg *     bg         int     -1 (transp) or background fill color
1260f29dbc25Smrg *    rop         int     unmapped raster op
1261f29dbc25Smrg * planemask     uint     -1 (fill) or pattern data (not enabled)
1262f29dbc25Smrg *  length        int     pattern length (bits)
1263f29dbc25Smrg * pattern     uchar*     dash pattern mask
1264f29dbc25Smrg *
1265f29dbc25Smrg * Returns              :none
1266f29dbc25Smrg *---------------------------------------------------------------------------*/
1267f29dbc25Smrgstatic void
1268f29dbc25SmrgGXSetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop,
1269f29dbc25Smrg    unsigned int planemask, int length, unsigned char *pattern)
1270f29dbc25Smrg{
1271f29dbc25Smrg    int i, l, n, m;
1272f29dbc25Smrg    CARD32 pat = *pattern;
1273f29dbc25Smrg    CARD32 pat8x8[2];
1274f29dbc25Smrg
1275f29dbc25Smrg    if (length <= 0)
1276f29dbc25Smrg	return;
1277f29dbc25Smrg    i = l = m = 0;
1278f29dbc25Smrg    while (i < 2) {
1279f29dbc25Smrg	m |= pat >> l;
1280f29dbc25Smrg	l += length;
1281f29dbc25Smrg	if ((n = l - 32) >= 0) {
1282f29dbc25Smrg	    pat8x8[i++] = m;
1283f29dbc25Smrg	    m = pat << (length - n);
1284f29dbc25Smrg	    l = n;
1285f29dbc25Smrg	}
1286f29dbc25Smrg    }
1287f29dbc25Smrg    gdln.pat[0] = pat8x8[0];
1288f29dbc25Smrg    gdln.pat[1] = pat8x8[1];
1289f29dbc25Smrg    gdln.len = length;
1290f29dbc25Smrg    gdln.fg = fg;
1291f29dbc25Smrg    gdln.bg = bg;
1292f29dbc25Smrg    rop &= 0x0F;
1293f29dbc25Smrg    gfx_set_solid_pattern(0);
1294f29dbc25Smrg    gfx_set_raster_operation(planemask == ~0U ? PDfn[rop] :
1295f29dbc25Smrg	(gfx_set_solid_source(planemask), PDfn_SM[rop]));
1296f29dbc25Smrg}
1297f29dbc25Smrg
1298f29dbc25Smrg/*---------------------------------------------------------------------------
1299f29dbc25Smrg * GXSubsequentDashedBresenhamLine
1300f29dbc25Smrg *
1301f29dbc25Smrg * Description:		This function is used to render a vector using the
1302f29dbc25Smrg *                 	specified bresenham parameters.
1303f29dbc25Smrg *
1304f29dbc25Smrg * Parameters:
1305f29dbc25Smrg *		pScrni:		Screen handler pointer having screen information.
1306f29dbc25Smrg *      x1:  		Specifies the starting x position
1307f29dbc25Smrg *      y1:      	Specifies starting y possition
1308f29dbc25Smrg *      absmaj:		Specfies the Bresenman absolute major.
1309f29dbc25Smrg *		absmin:		Specfies the Bresenman absolute minor.
1310f29dbc25Smrg *		err:     	Specifies the bresenham err term.
1311f29dbc25Smrg *		len:     	Specifies the length of the vector interms of pixels.
1312f29dbc25Smrg *		octant:  	not used in this function,may be added for standard
1313f29dbc25Smrg *               	interface.
1314f29dbc25Smrg *
1315f29dbc25Smrg * Returns:			none
1316f29dbc25Smrg *
1317f29dbc25Smrg * Comments:		none
1318f29dbc25Smrg *
1319f29dbc25Smrg * Sample application uses:
1320f29dbc25Smrg *   - Window outlines on window move.
1321f29dbc25Smrg *   - x11perf: line segments (-line500).
1322f29dbc25Smrg *   - x11perf: line segments (-seg500).
1323f29dbc25Smrg *----------------------------------------------------------------------------
1324f29dbc25Smrg */
1325f29dbc25Smrgstatic void
1326f29dbc25SmrgGXSubsequentDashedBresenhamLine(ScrnInfoPtr pScrni,
1327f29dbc25Smrg    int x1, int y1, int absmaj, int absmin,
1328f29dbc25Smrg    int err, int len, int octant, int phase)
1329f29dbc25Smrg{
1330f29dbc25Smrg    int i, n;
1331f29dbc25Smrg    int axial, diagn;
1332f29dbc25Smrg    int trans = (gdln.bg == -1);
1333f29dbc25Smrg    unsigned long pat8x8[2];
1334f29dbc25Smrg
1335f29dbc25Smrg    //ErrorF("BLine %d, %d, %d, %d, %d, %d, %d\n" x1, y1, absmaj, absmin,
1336f29dbc25Smrg    //err, len, octant);
1337f29dbc25Smrg
1338f29dbc25Smrg    i = phase >= 32 ? (phase -= 32, 1) : 0;
1339f29dbc25Smrg    n = 32 - phase;
1340f29dbc25Smrg    pat8x8[0] =
1341f29dbc25Smrg	((gdln.pat[i] >> phase) & ((1UL << n) - 1)) | (gdln.pat[1 - i] << n);
1342f29dbc25Smrg    pat8x8[1] =
1343f29dbc25Smrg	((gdln.pat[1 - i] >> phase) & ((1UL << n) - 1)) | (gdln.pat[i] << n);
1344f29dbc25Smrg    axial = absmin;
1345f29dbc25Smrg    err += axial;
1346f29dbc25Smrg    diagn = absmin - absmaj;
1347f29dbc25Smrg    gfx_set_mono_pattern(gdln.bg, gdln.fg, pat8x8[0], pat8x8[1], trans);
1348f29dbc25Smrg    gfx2_set_pattern_origin(x1, y1);
1349f29dbc25Smrg    gfx2_bresenham_line(CALC_FBOFFSET(x1, y1), len, err, axial, diagn,
1350f29dbc25Smrg	vmode[octant]);
1351f29dbc25Smrg}
1352f29dbc25Smrg
1353f29dbc25Smrg/*---------------------------------------------------------------------------
1354f29dbc25Smrg * GXSubsequentDashedTwoPointLine
1355f29dbc25Smrg *
1356f29dbc25Smrg * Description  :see GXSetupForDashedLine
1357f29dbc25Smrg *
1358f29dbc25Smrg *    Arg        Type     Comment
1359f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
1360f29dbc25Smrg *     x0         int     destination x start offset
1361f29dbc25Smrg *     y0         int     destination y start offset
1362f29dbc25Smrg *     x1         int     destination x end offset
1363f29dbc25Smrg *     y1         int     destination y end offset
1364f29dbc25Smrg *  flags         int     OMIT_LAST, dont draw last pixel (not used)
1365f29dbc25Smrg *  phase         int     initial pattern offset at x1,y1
1366f29dbc25Smrg *
1367f29dbc25Smrg * Returns      :none
1368f29dbc25Smrg *---------------------------------------------------------------------------*/
1369f29dbc25Smrgstatic void
1370f29dbc25SmrgGXSubsequentDashedTwoPointLine(ScrnInfoPtr pScrni, int x0, int y0,
1371f29dbc25Smrg    int x1, int y1, int flags, int phase)
1372f29dbc25Smrg{
1373f29dbc25Smrg    int i, n;
1374f29dbc25Smrg    long dx, dy, dmaj, dmin, octant, bias;
1375f29dbc25Smrg    long axial, diagn, err, len, pat8x8[2];
1376f29dbc25Smrg
1377f29dbc25Smrg    //ErrorF("GXSubsequentDashedTwoPointLine() %d,%d %d,%d, %#x %d\n",
1378f29dbc25Smrg    //   x0, y0, x1, y1, flags, phase);
1379f29dbc25Smrg
1380f29dbc25Smrg    i = phase >= 32 ? (phase -= 32, 1) : 0;
1381f29dbc25Smrg    n = 32 - phase;
1382f29dbc25Smrg    pat8x8[0] =
1383f29dbc25Smrg	((gdln.pat[i] >> phase) & ((1UL << n) - 1)) | (gdln.pat[1 - i] << n);
1384f29dbc25Smrg    pat8x8[1] =
1385f29dbc25Smrg	((gdln.pat[1 - i] >> phase) & ((1UL << n) - 1)) | (gdln.pat[i] << n);
1386f29dbc25Smrg
1387f29dbc25Smrg    if ((dx = x1 - x0) < 0)
1388f29dbc25Smrg	dx = -dx;
1389f29dbc25Smrg    if ((dy = y1 - y0) < 0)
1390f29dbc25Smrg	dy = -dy;
1391f29dbc25Smrg    if (dy >= dx) {
1392f29dbc25Smrg	dmaj = dy;
1393f29dbc25Smrg	dmin = dx;
1394f29dbc25Smrg	octant = YMAJOR;
1395f29dbc25Smrg    } else {
1396f29dbc25Smrg	dmaj = dx;
1397f29dbc25Smrg	dmin = dy;
1398f29dbc25Smrg	octant = 0;
1399f29dbc25Smrg    }
1400f29dbc25Smrg    len = dmaj;
1401f29dbc25Smrg    if ((flags & OMIT_LAST) == 0)
1402f29dbc25Smrg	++len;
1403f29dbc25Smrg    if (len <= 0)
1404f29dbc25Smrg	return;
1405f29dbc25Smrg    if (x1 < x0)
1406f29dbc25Smrg	octant |= XDECREASING;
1407f29dbc25Smrg    if (y1 < y0)
1408f29dbc25Smrg	octant |= YDECREASING;
1409f29dbc25Smrg
1410f29dbc25Smrg    axial = dmin << 1;
1411f29dbc25Smrg    bias = miGetZeroLineBias(pScrni->pScreen);
1412f29dbc25Smrg    err = axial - dmaj - ((bias >> octant) & 1);
1413f29dbc25Smrg    diagn = (dmin - dmaj) << 1;
1414f29dbc25Smrg
1415f29dbc25Smrg    gfx2_set_pattern_origin(x0, y0);
1416f29dbc25Smrg    gfx2_bresenham_line(CALC_FBOFFSET(x0, y0), len, err, axial, diagn,
1417f29dbc25Smrg	vmode[octant]);
1418f29dbc25Smrg
1419f29dbc25Smrg}
1420f29dbc25Smrg#endif /* GX_DASH_LINE_SUPPORT */
1421f29dbc25Smrg
1422f29dbc25Smrg#if GX_WRITE_PIXMAP_SUPPORT
1423f29dbc25Smrgstatic void
1424f29dbc25SmrgGXWritePixmap(ScrnInfoPtr pScrni, int x, int y, int w, int h,
1425f29dbc25Smrg    unsigned char *src, int srcwidth, int rop, unsigned int planemask,
1426f29dbc25Smrg    int trans, int bpp, int depth)
1427f29dbc25Smrg{
1428f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR(pScrni);
1429f29dbc25Smrg
1430f29dbc25Smrg    //ErrorF("GXWritePixmap() %d,%d %dx%d, s%#x sp%d %#x %#x %#x %d %d\n",
1431f29dbc25Smrg    //    x, y, w, h, src, srcwidth, rop, planemask, trans, bpp, depth);
1432f29dbc25Smrg
1433f29dbc25Smrg    if (bpp == pScrni->bitsPerPixel) {
1434f29dbc25Smrg	rop &= 0x0F;
1435f29dbc25Smrg	if (rop == GXcopy && trans == -1) {
1436f29dbc25Smrg	    gfx_wait_until_idle();
1437f29dbc25Smrg	    geode_memory_to_screen_blt((unsigned long)src,
1438f29dbc25Smrg		(unsigned long)FBADDR(x, y), srcwidth, pGeode->Pitch, w,
1439f29dbc25Smrg		h, bpp);
1440f29dbc25Smrg	} else {
1441f29dbc25Smrg	    gfx_set_solid_pattern(planemask);
1442f29dbc25Smrg	    gfx_set_raster_operation(planemask ==
1443f29dbc25Smrg		~0U ? SDfn[rop] : SDfn_PM[rop]);
1444f29dbc25Smrg	    if (trans != -1)
1445f29dbc25Smrg		gfx_color_bitmap_to_screen_xblt(0, 0, x, y, w, h, src,
1446f29dbc25Smrg		    srcwidth, trans);
1447f29dbc25Smrg	    else
1448f29dbc25Smrg		gfx_color_bitmap_to_screen_blt(0, 0, x, y, w, h, src,
1449f29dbc25Smrg		    srcwidth);
1450f29dbc25Smrg	    SET_SYNC_FLAG(pGeode->AccelInfoRec);
1451f29dbc25Smrg	}
1452f29dbc25Smrg    } else
1453f29dbc25Smrg	pGeode->WritePixmap(pScrni, x, y, w, h, src, srcwidth, rop, planemask,
1454f29dbc25Smrg	    trans, bpp, depth);
1455f29dbc25Smrg}
1456f29dbc25Smrg#endif /* if GX_WRITE_PIXMAP_SUPPORT */
1457f29dbc25Smrg
1458f29dbc25Smrg#if XF86EXA
1459f29dbc25Smrg
1460f29dbc25Smrgstatic void
1461f29dbc25Smrgamd_gx_exa_WaitMarker(ScreenPtr pScreen, int Marker)
1462f29dbc25Smrg{
1463f29dbc25Smrg    GU2_WAIT_BUSY;
1464f29dbc25Smrg}
1465f29dbc25Smrg
1466f29dbc25Smrgstatic void
1467f29dbc25Smrgamd_gx_exa_Done(PixmapPtr p)
1468f29dbc25Smrg{
1469f29dbc25Smrg}
1470f29dbc25Smrg
1471f29dbc25Smrgstatic Bool
1472f29dbc25Smrgamd_gx_exa_UploadToScreen(PixmapPtr pDst, int x, int y, int w, int h,
1473f29dbc25Smrg    char *src, int src_pitch)
1474f29dbc25Smrg{
1475f29dbc25Smrg    char *dst = pDst->devPrivate.ptr;
1476f29dbc25Smrg    int dst_pitch = exaGetPixmapPitch(pDst);
1477f29dbc25Smrg    int bpp = pDst->drawable.bitsPerPixel;
1478f29dbc25Smrg
1479f29dbc25Smrg    dst += y * dst_pitch + x * (bpp >> 3);
1480f29dbc25Smrg    GU2_WAIT_BUSY;
1481f29dbc25Smrg    geode_memory_to_screen_blt((unsigned long)src, (unsigned long)dst,
1482f29dbc25Smrg	src_pitch, dst_pitch, w, h, bpp);
1483f29dbc25Smrg    return TRUE;
1484f29dbc25Smrg}
1485f29dbc25Smrg
1486f29dbc25Smrgstatic Bool
1487f29dbc25Smrgamd_gx_exa_DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h,
1488f29dbc25Smrg    char *dst, int dst_pitch)
1489f29dbc25Smrg{
1490f29dbc25Smrg    char *src = pSrc->devPrivate.ptr;
1491f29dbc25Smrg    int src_pitch = exaGetPixmapPitch(pSrc);
1492f29dbc25Smrg    int bpp = pSrc->drawable.bitsPerPixel;
1493f29dbc25Smrg
1494f29dbc25Smrg    src += (y * src_pitch) + (x * (bpp >> 3));
1495f29dbc25Smrg    GU2_WAIT_BUSY;
1496f29dbc25Smrg    geode_memory_to_screen_blt((unsigned long)src, (unsigned long)dst,
1497f29dbc25Smrg	src_pitch, dst_pitch, w, h, bpp);
1498f29dbc25Smrg    return TRUE;
1499f29dbc25Smrg}
1500f29dbc25Smrg
1501f29dbc25Smrg/* Solid */
1502f29dbc25Smrg
1503f29dbc25Smrgstatic Bool
1504f29dbc25Smrgamd_gx_exa_PrepareSolid(PixmapPtr pxMap, int alu, Pixel planemask, Pixel fg)
1505f29dbc25Smrg{
1506f29dbc25Smrg    int dstPitch = exaGetPixmapPitch(pxMap);
1507f29dbc25Smrg    unsigned int ROP = amd_gx_BppToRasterMode(pxMap->drawable.bitsPerPixel)
1508f29dbc25Smrg	| (planemask == ~0U ? SDfn[alu] : SDfn_PM[alu]);
1509f29dbc25Smrg
1510f29dbc25Smrg    //  FIXME: this should go away -- workaround for the blockparty icon corruption
1511f29dbc25Smrg    //if (pxMap->drawable.bitsPerPixel == 32)
1512f29dbc25Smrg    //  return FALSE;
1513f29dbc25Smrg
1514f29dbc25Smrg    BLT_MODE = ((ROP ^ (ROP >> 2)) & 0x33) == 0 ? MGP_BM_SRC_MONO : 0;
1515f29dbc25Smrg    if (((ROP ^ (ROP >> 1)) & 0x55) != 0)
1516f29dbc25Smrg	BLT_MODE |= MGP_BM_DST_REQ;
1517f29dbc25Smrg    //ErrorF("amd_gx_exa_PrepareSolid(%#x,%#x,%#x - ROP=%x,BLT_MODE=%x)\n", alu, planemask, fg, ROP, BLT_MODE);
1518f29dbc25Smrg    GU2_WAIT_PENDING;
1519f29dbc25Smrg    WRITE_GP32(MGP_RASTER_MODE, ROP);
1520f29dbc25Smrg    WRITE_GP32(MGP_PAT_COLOR_0, planemask);
1521f29dbc25Smrg    WRITE_GP32(MGP_SRC_COLOR_FG, fg);
1522f29dbc25Smrg    WRITE_GP32(MGP_STRIDE, dstPitch);
1523f29dbc25Smrg    return TRUE;
1524f29dbc25Smrg}
1525f29dbc25Smrg
1526f29dbc25Smrgstatic void
1527f29dbc25Smrgamd_gx_exa_Solid(PixmapPtr pxMap, int x1, int y1, int x2, int y2)
1528f29dbc25Smrg{
1529f29dbc25Smrg    int bpp = (pxMap->drawable.bitsPerPixel + 7) / 8;
1530f29dbc25Smrg    int pitch = exaGetPixmapPitch(pxMap);
1531f29dbc25Smrg    unsigned int offset = exaGetPixmapOffset(pxMap) + pitch * y1 + bpp * x1;
1532f29dbc25Smrg    unsigned int size = ((x2 - x1) << 16) | (y2 - y1);
1533f29dbc25Smrg
1534f29dbc25Smrg    //ErrorF("amd_gx_exa_Solid() at %d,%d %d,%d - offset=%d, bpp=%d\n", x1, y1, x2, y2, offset, bpp);
1535f29dbc25Smrg
1536f29dbc25Smrg    GU2_WAIT_PENDING;
1537f29dbc25Smrg    WRITE_GP32(MGP_DST_OFFSET, offset);
1538f29dbc25Smrg    WRITE_GP32(MGP_WID_HEIGHT, size);
1539f29dbc25Smrg    WRITE_GP32(MGP_BLT_MODE, BLT_MODE);
1540f29dbc25Smrg}
1541f29dbc25Smrg
1542f29dbc25Smrg/* Copy */
1543f29dbc25Smrg
1544f29dbc25Smrgstatic Bool
1545f29dbc25Smrgamd_gx_exa_PrepareCopy(PixmapPtr pxSrc, PixmapPtr pxDst, int dx, int dy,
1546f29dbc25Smrg    int alu, Pixel planemask)
1547f29dbc25Smrg{
1548f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst);
1549f29dbc25Smrg    int dstPitch = exaGetPixmapPitch(pxDst);
1550f29dbc25Smrg    unsigned int ROP;
1551f29dbc25Smrg
1552f29dbc25Smrg    /* Punt if the color formats aren't the same */
1553f29dbc25Smrg
1554f29dbc25Smrg    if (pxSrc->drawable.bitsPerPixel != pxDst->drawable.bitsPerPixel)
1555f29dbc25Smrg	return FALSE;
1556f29dbc25Smrg
1557f29dbc25Smrg    //ErrorF("amd_gx_exa_PrepareCopy() dx%d dy%d alu %#x %#x\n",
1558f29dbc25Smrg    //  dx, dy, alu, planemask);
1559f29dbc25Smrg
1560f29dbc25Smrg    pGeode->cpySrcOffset = exaGetPixmapOffset(pxSrc);
1561f29dbc25Smrg    pGeode->cpySrcPitch = exaGetPixmapPitch(pxSrc);
1562f29dbc25Smrg    pGeode->cpySrcBpp = (pxSrc->drawable.bitsPerPixel + 7) / 8;
1563f29dbc25Smrg    pGeode->cpyDx = dx;
1564f29dbc25Smrg    pGeode->cpyDy = dy;
1565f29dbc25Smrg    ROP = amd_gx_BppToRasterMode(pxSrc->drawable.bitsPerPixel) |
1566f29dbc25Smrg	(planemask == ~0U ? SDfn[alu] : SDfn_PM[alu]);
1567f29dbc25Smrg
1568f29dbc25Smrg    BLT_MODE = ((ROP ^ (ROP >> 1)) & 0x55) != 0 ?
1569f29dbc25Smrg	MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
1570f29dbc25Smrg    GU2_WAIT_PENDING;
1571f29dbc25Smrg    WRITE_GP32(MGP_RASTER_MODE, ROP);
1572f29dbc25Smrg    WRITE_GP32(MGP_PAT_COLOR_0, planemask);
1573f29dbc25Smrg    WRITE_GP32(MGP_SRC_COLOR_FG, ~0);
1574f29dbc25Smrg    WRITE_GP32(MGP_SRC_COLOR_BG, ~0);
1575f29dbc25Smrg    WRITE_GP32(MGP_STRIDE, (pGeode->cpySrcPitch << 16) | dstPitch);
1576f29dbc25Smrg    return TRUE;
1577f29dbc25Smrg}
1578f29dbc25Smrg
1579f29dbc25Smrgstatic void
1580f29dbc25Smrgamd_gx_exa_Copy(PixmapPtr pxDst, int srcX, int srcY, int dstX, int dstY,
1581f29dbc25Smrg    int w, int h)
1582f29dbc25Smrg{
1583f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst);
1584f29dbc25Smrg    int dstBpp = (pxDst->drawable.bitsPerPixel + 7) / 8;
1585f29dbc25Smrg    int dstPitch = exaGetPixmapPitch(pxDst);
1586f29dbc25Smrg    unsigned int srcOffset =
1587f29dbc25Smrg	pGeode->cpySrcOffset + (pGeode->cpySrcPitch * srcY) +
1588f29dbc25Smrg	(pGeode->cpySrcBpp * srcX);
1589f29dbc25Smrg    unsigned int dstOffset =
1590f29dbc25Smrg	exaGetPixmapOffset(pxDst) + (dstPitch * dstY) + (dstBpp * dstX);
1591f29dbc25Smrg    unsigned int size = (w << 16) | h;
1592f29dbc25Smrg    unsigned int blt_mode = BLT_MODE;
1593f29dbc25Smrg
1594f29dbc25Smrg    //ErrorF("amd_gx_exa_Copy() from %d,%d to %d,%d %dx%d\n", srcX, srcY,
1595f29dbc25Smrg    //   dstX, dstY, w, h);
1596f29dbc25Smrg
1597f29dbc25Smrg    if (pGeode->cpyDx < 0) {
1598f29dbc25Smrg	srcOffset += w * pGeode->cpySrcBpp - 1;
1599f29dbc25Smrg	dstOffset += w * dstBpp - 1;
1600f29dbc25Smrg	blt_mode |= MGP_BM_NEG_XDIR;
1601f29dbc25Smrg    }
1602f29dbc25Smrg    if (pGeode->cpyDy < 0) {
1603f29dbc25Smrg	srcOffset += (h - 1) * pGeode->cpySrcPitch;
1604f29dbc25Smrg	dstOffset += (h - 1) * dstPitch;
1605f29dbc25Smrg	blt_mode |= MGP_BM_NEG_YDIR;
1606f29dbc25Smrg    }
1607f29dbc25Smrg    GU2_WAIT_PENDING;
1608f29dbc25Smrg    WRITE_GP32(MGP_SRC_OFFSET, srcOffset);
1609f29dbc25Smrg    WRITE_GP32(MGP_DST_OFFSET, dstOffset);
1610f29dbc25Smrg    WRITE_GP32(MGP_WID_HEIGHT, size);
1611f29dbc25Smrg    WRITE_GP16(MGP_BLT_MODE, blt_mode);
1612f29dbc25Smrg}
1613f29dbc25Smrg
1614f29dbc25Smrg/* A=SRC, B=DST */
1615f29dbc25Smrg#define SRC_DST 0
1616f29dbc25Smrg/* B=SRC, A=DST */
1617f29dbc25Smrg#define DST_SRC MGP_RM_DEST_FROM_CHAN_A
1618f29dbc25Smrg/* A*alpha + B*0         */
1619f29dbc25Smrg#define Aa_B0   MGP_RM_ALPHA_TIMES_A
1620f29dbc25Smrg/* A*0     + B*(1-alpha) */
1621f29dbc25Smrg#define A0_B1a  MGP_RM_BETA_TIMES_B
1622f29dbc25Smrg/* A*1     + B*(1-alpha) */
1623f29dbc25Smrg#define A1_B1a  MGP_RM_A_PLUS_BETA_B
1624f29dbc25Smrg/* A*alpha + B*(1-alpha) */
1625f29dbc25Smrg#define Aa_B1a  MGP_RM_ALPHA_A_PLUS_BETA_B
1626f29dbc25Smrg/* alpha from A */
1627f29dbc25Smrg#define a_A MGP_RM_SELECT_ALPHA_A
1628f29dbc25Smrg/* alpha from B */
1629f29dbc25Smrg#define a_B MGP_RM_SELECT_ALPHA_B
1630f29dbc25Smrg/* alpha from const */
1631f29dbc25Smrg#define a_C MGP_RM_SELECT_ALPHA_R
1632f29dbc25Smrg/* alpha = 1 */
1633f29dbc25Smrg#define a_1 MGP_RM_SELECT_ALPHA_1
1634f29dbc25Smrg
1635f29dbc25Smrg#define MGP_RM_ALPHA_TO_ARGB (MGP_RM_ALPHA_TO_ALPHA | MGP_RM_ALPHA_TO_RGB)
1636f29dbc25Smrg#define gxPictOpMAX PictOpAdd	       /* highest accelerated op */
1637f29dbc25Smrg
1638f29dbc25Smrgunsigned int amd_gx_exa_alpha_ops[] =
1639f29dbc25Smrg/*    A   B      OP     AS           const = 0 */
1640f29dbc25Smrg{
1641f29dbc25Smrg    (SRC_DST | Aa_B0 | a_C), 0,	       /* clear    (src*0) */
1642f29dbc25Smrg    (SRC_DST | Aa_B0 | a_1), 0,	       /* src      (src*1) */
1643f29dbc25Smrg    (DST_SRC | Aa_B0 | a_1), 0,	       /* dst      (dst*1) */
1644f29dbc25Smrg    (SRC_DST | A1_B1a | a_A), 0,       /* src-over (src*1 + dst(1-A)) */
1645f29dbc25Smrg    (DST_SRC | A1_B1a | a_A), 0,       /* dst-over (dst*1 + src(1-B)) */
1646f29dbc25Smrg    (SRC_DST | Aa_B0 | a_B), 0,	       /* src-in   (src*B) */
1647f29dbc25Smrg    (DST_SRC | Aa_B0 | a_B), 0,	       /* dst-in   (dst*A) */
1648f29dbc25Smrg    (DST_SRC | A0_B1a | a_A), 0,       /* src-out  (src*(1-B)) */
1649f29dbc25Smrg    (SRC_DST | A0_B1a | a_A), 0,       /* dst-out  (dst*(1-A)) */
1650f29dbc25Smrg/* pass1 (SRC=dst DST=scr=src), pass2 (SRC=src, DST=dst) */
1651f29dbc25Smrg    (DST_SRC | Aa_B0 | a_B),	       /* srcatop  (src*B) */
1652f29dbc25Smrg    (SRC_DST | A0_B1a | a_A),	       /*                  + (dst(1-A)) */
1653f29dbc25Smrg    (SRC_DST | Aa_B0 | a_B),	       /* dstatop  (dst*A) */
1654f29dbc25Smrg    (DST_SRC | A0_B1a | a_A),	       /*                  + (src(1-B) */
1655f29dbc25Smrg    (SRC_DST | A0_B1a | a_A),	       /* xor      (src*(1-B) */
1656f29dbc25Smrg    (SRC_DST | A0_B1a | a_A),	       /*                  + (dst(1-A) */
1657f29dbc25Smrg    (SRC_DST | A1_B1a | a_C), 0,       /* add      (src*1 + dst*1) */
1658f29dbc25Smrg};
1659f29dbc25Smrg
1660f29dbc25Smrgtypedef struct
1661f29dbc25Smrg{
1662f29dbc25Smrg    int exa_fmt;
1663f29dbc25Smrg    int bpp;
1664f29dbc25Smrg    int gx_fmt;
1665f29dbc25Smrg    int alpha_bits;
1666f29dbc25Smrg} amd_gx_exa_fmt_t;
1667f29dbc25Smrg
1668f29dbc25Smrgamd_gx_exa_fmt_t amd_gx_exa_fmts[] = {
1669f29dbc25Smrg    {PICT_a8r8g8b8, 32, MGP_RM_BPPFMT_8888, 8},
1670f29dbc25Smrg    {PICT_x8r8g8b8, 32, MGP_RM_BPPFMT_8888, 0},
1671f29dbc25Smrg    {PICT_a4r4g4b4, 16, MGP_RM_BPPFMT_4444, 4},
1672f29dbc25Smrg    {PICT_a1r5g5b5, 16, MGP_RM_BPPFMT_1555, 1},
1673f29dbc25Smrg    {PICT_r5g6b5, 16, MGP_RM_BPPFMT_565, 0},
1674f29dbc25Smrg    {PICT_r3g3b2, 8, MGP_RM_BPPFMT_332, 0},
1675f29dbc25Smrg};
1676f29dbc25Smrg
1677f29dbc25Smrgstatic amd_gx_exa_fmt_t *
1678f29dbc25Smrgamd_gx_exa_check_format(PicturePtr p)
1679f29dbc25Smrg{
1680f29dbc25Smrg    int i;
1681f29dbc25Smrg    int bpp = p->pDrawable ? p->pDrawable->bitsPerPixel : 0;
1682f29dbc25Smrg    amd_gx_exa_fmt_t *fp = &amd_gx_exa_fmts[0];
1683f29dbc25Smrg
1684f29dbc25Smrg    for (i = sizeof(amd_gx_exa_fmts) / sizeof(amd_gx_exa_fmts[0]); --i >= 0;
1685f29dbc25Smrg	++fp) {
1686f29dbc25Smrg	if (fp->bpp < bpp)
1687f29dbc25Smrg	    return NULL;
1688f29dbc25Smrg	if (fp->bpp != bpp)
1689f29dbc25Smrg	    continue;
1690f29dbc25Smrg	if (fp->exa_fmt == p->format)
1691f29dbc25Smrg	    break;
1692f29dbc25Smrg    }
1693f29dbc25Smrg    return i < 0 ? NULL : fp;
1694f29dbc25Smrg}
1695f29dbc25Smrg
1696f29dbc25Smrg/* Composite */
1697f29dbc25Smrg
1698f29dbc25Smrgstatic Bool
1699f29dbc25Smrgamd_gx_exa_CheckComposite(int op, PicturePtr pSrc, PicturePtr pMsk,
1700f29dbc25Smrg    PicturePtr pDst)
1701f29dbc25Smrg{
1702f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR_FROM_PICTURE(pDst);
1703f29dbc25Smrg
1704f29dbc25Smrg    if (op > gxPictOpMAX)
1705f29dbc25Smrg	return FALSE;
1706f29dbc25Smrg    if (pMsk)
1707f29dbc25Smrg	return FALSE;
1708f29dbc25Smrg    if (usesPasses(op) && pGeode->exaBfrSz == 0)
1709f29dbc25Smrg	return FALSE;
1710f29dbc25Smrg    if (pSrc->filter != PictFilterNearest &&
1711f29dbc25Smrg	pSrc->filter != PictFilterFast &&
1712f29dbc25Smrg	pSrc->filter != PictFilterGood && pSrc->filter != PictFilterBest)
1713f29dbc25Smrg	return FALSE;
1714f29dbc25Smrg    if (pSrc->repeat)
1715f29dbc25Smrg	return FALSE;
1716f29dbc25Smrg    if (pSrc->transform)
1717f29dbc25Smrg	return FALSE;
1718f29dbc25Smrg    return TRUE;
1719f29dbc25Smrg}
1720f29dbc25Smrg
1721f29dbc25Smrgstatic Bool
1722f29dbc25Smrgamd_gx_exa_PrepareComposite(int op, PicturePtr pSrc, PicturePtr pMsk,
1723f29dbc25Smrg    PicturePtr pDst, PixmapPtr pxSrc, PixmapPtr pxMsk, PixmapPtr pxDst)
1724f29dbc25Smrg{
1725f29dbc25Smrg    int srcPitch;
1726f29dbc25Smrg
1727f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst);
1728f29dbc25Smrg    amd_gx_exa_fmt_t *sfp, *dfp;
1729f29dbc25Smrg
1730f29dbc25Smrg    //ErrorF("amd_gx_exa_PrepareComposite()\n");
1731f29dbc25Smrg
1732f29dbc25Smrg    if ((sfp = amd_gx_exa_check_format(pSrc)) == NULL)
1733f29dbc25Smrg	return FALSE;
1734f29dbc25Smrg    if (sfp->alpha_bits == 0 && usesSrcAlpha(op))
1735f29dbc25Smrg	return FALSE;
1736f29dbc25Smrg    if ((dfp = amd_gx_exa_check_format(pDst)) == NULL)
1737f29dbc25Smrg	return FALSE;
1738f29dbc25Smrg    if (dfp->alpha_bits == 0 && usesDstAlpha(op))
1739f29dbc25Smrg	return FALSE;
1740f29dbc25Smrg    if (sfp->gx_fmt != dfp->gx_fmt)
1741f29dbc25Smrg	return FALSE;
1742f29dbc25Smrg    srcPitch = exaGetPixmapPitch(pxSrc);
1743f29dbc25Smrg    if (usesPasses(op) && srcPitch > pGeode->exaBfrSz)
1744f29dbc25Smrg	return FALSE;
1745f29dbc25Smrg    pGeode->cmpSrcPitch = srcPitch;
1746f29dbc25Smrg    pGeode->cmpOp = op;
1747f29dbc25Smrg    pGeode->cmpSrcOffset = exaGetPixmapOffset(pxSrc);
1748f29dbc25Smrg    pGeode->cmpSrcBpp = (pxSrc->drawable.bitsPerPixel + 7) / 8;
1749f29dbc25Smrg    pGeode->cmpSrcFmt = sfp->gx_fmt;
1750f29dbc25Smrg    pGeode->cmpDstFmt = dfp->gx_fmt | (dfp->alpha_bits == 0 ?
1751f29dbc25Smrg	MGP_RM_ALPHA_TO_RGB : MGP_RM_ALPHA_TO_ARGB);
1752f29dbc25Smrg    return TRUE;
1753f29dbc25Smrg}
1754f29dbc25Smrg
1755f29dbc25Smrgstatic void
1756f29dbc25Smrgamd_gx_exa_Composite(PixmapPtr pxDst, int srcX, int srcY, int maskX,
1757f29dbc25Smrg    int maskY, int dstX, int dstY, int width, int height)
1758f29dbc25Smrg{
1759f29dbc25Smrg    int op, current_line, max_lines, lines, pass, scratchPitch;
1760f29dbc25Smrg    unsigned int srcOffset, srcOfs = 0, srcPitch, srcPch = 0, srcBpp;
1761f29dbc25Smrg    unsigned int dstOffset, dstOfs = 0, dstPitch, dstPch = 0, dstBpp;
1762f29dbc25Smrg    unsigned int sizes, strides, blt_mode = 0, rop = 0;
1763f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst);
1764f29dbc25Smrg
1765f29dbc25Smrg    //ErrorF("amd_gx_exa_Composite() from %d,%d to %d,%d %dx%d\n",
1766f29dbc25Smrg    //    srcX, srcY, dstX, dstY, width, height);
1767f29dbc25Smrg
1768f29dbc25Smrg    op = pGeode->cmpOp;
1769f29dbc25Smrg    if (usesPasses(op)) {
1770f29dbc25Smrg	int cacheLineSz = 32;
1771f29dbc25Smrg	int cachelines =
1772f29dbc25Smrg	    (width * pGeode->cmpSrcBpp + cacheLineSz - 1) / cacheLineSz;
1773f29dbc25Smrg	scratchPitch = cachelines * cacheLineSz;
1774f29dbc25Smrg	if (scratchPitch > pGeode->cmpSrcPitch)
1775f29dbc25Smrg	    scratchPitch = pGeode->cmpSrcPitch;
1776f29dbc25Smrg	max_lines = pGeode->exaBfrSz / scratchPitch;
1777f29dbc25Smrg    } else {
1778f29dbc25Smrg	scratchPitch = 0;
1779f29dbc25Smrg	max_lines = height;
1780f29dbc25Smrg    }
1781f29dbc25Smrg
1782f29dbc25Smrg    dstBpp = (pxDst->drawable.bitsPerPixel + 7) / 8;
1783f29dbc25Smrg    dstPitch = exaGetPixmapPitch(pxDst);
1784f29dbc25Smrg    dstOffset = exaGetPixmapOffset(pxDst) + dstPitch * dstY + dstBpp * dstX;
1785f29dbc25Smrg    srcBpp = pGeode->cmpSrcBpp;
1786f29dbc25Smrg    srcPitch = pGeode->cmpSrcPitch;
1787f29dbc25Smrg    srcOffset = pGeode->cmpSrcOffset + srcPitch * srcY + srcBpp * srcX;
1788f29dbc25Smrg
1789f29dbc25Smrg    current_line = pass = 0;
1790f29dbc25Smrg    while (current_line < height) {
1791f29dbc25Smrg	if (usesPasses(op)) {
1792f29dbc25Smrg	    lines = height - current_line;
1793f29dbc25Smrg	    if (lines > max_lines)
1794f29dbc25Smrg		lines = max_lines;
1795f29dbc25Smrg	    switch (pass) {
1796f29dbc25Smrg	    case 0:		       /* copy src to scratch */
1797f29dbc25Smrg		srcPch = srcPitch;
1798f29dbc25Smrg		srcOfs = srcOffset + current_line * srcPch;
1799f29dbc25Smrg		dstPch = scratchPitch;
1800f29dbc25Smrg		dstOfs = pGeode->exaBfrOffset;
1801f29dbc25Smrg		rop = pGeode->cmpSrcFmt | MGP_RM_ALPHA_TO_ARGB;
1802f29dbc25Smrg		rop |= amd_gx_exa_alpha_ops[PictOpSrc * 2];
1803f29dbc25Smrg		blt_mode = usesChanB0(PictOpSrc) ?
1804f29dbc25Smrg		    MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
1805f29dbc25Smrg		++pass;
1806f29dbc25Smrg		break;
1807f29dbc25Smrg	    case 1:		       /* pass1 */
1808f29dbc25Smrg		srcPch = dstPitch;
1809f29dbc25Smrg		srcOfs = dstOffset + current_line * srcPch;
1810f29dbc25Smrg		dstPch = scratchPitch;
1811f29dbc25Smrg		dstOfs = pGeode->exaBfrOffset;
1812f29dbc25Smrg		rop = pGeode->cmpSrcFmt | MGP_RM_ALPHA_TO_ARGB;
1813f29dbc25Smrg		rop |= amd_gx_exa_alpha_ops[op * 2];
1814f29dbc25Smrg		blt_mode = usesChanB1(op) ?
1815f29dbc25Smrg		    MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
1816f29dbc25Smrg		++pass;
1817f29dbc25Smrg		break;
1818f29dbc25Smrg	    case 2:		       /* pass2 */
1819f29dbc25Smrg		srcPch = srcPitch;
1820f29dbc25Smrg		srcOfs = srcOffset + current_line * srcPch;
1821f29dbc25Smrg		dstPch = dstPitch;
1822f29dbc25Smrg		dstOfs = dstOffset + current_line * dstPch;
1823f29dbc25Smrg		rop = pGeode->cmpSrcFmt | MGP_RM_ALPHA_TO_ARGB;
1824f29dbc25Smrg		rop |= amd_gx_exa_alpha_ops[op * 2 + 1];
1825f29dbc25Smrg		blt_mode = usesChanB2(op) ?
1826f29dbc25Smrg		    MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
1827f29dbc25Smrg		++pass;
1828f29dbc25Smrg		break;
1829f29dbc25Smrg	    case 3:		       /* add */
1830f29dbc25Smrg		srcPch = scratchPitch;
1831f29dbc25Smrg		srcOfs = pGeode->exaBfrOffset;
1832f29dbc25Smrg		dstPch = dstPitch;
1833f29dbc25Smrg		dstOfs = dstOffset + current_line * dstPch;
1834f29dbc25Smrg		rop = pGeode->cmpDstFmt;
1835f29dbc25Smrg		rop |= amd_gx_exa_alpha_ops[PictOpAdd * 2];
1836f29dbc25Smrg		blt_mode = usesChanB0(PictOpAdd) ?
1837f29dbc25Smrg		    MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
1838f29dbc25Smrg		current_line += lines;
1839f29dbc25Smrg		pass = 0;
1840f29dbc25Smrg		break;
1841f29dbc25Smrg	    }
1842f29dbc25Smrg	    strides = (srcPch << 16) | dstPch;
1843f29dbc25Smrg	} else {		       /* not multi pass */
1844f29dbc25Smrg	    srcOfs = srcOffset;
1845f29dbc25Smrg	    dstOfs = dstOffset;
1846f29dbc25Smrg	    current_line = lines = height;
1847f29dbc25Smrg	    strides = (srcPitch << 16) | dstPitch;
1848f29dbc25Smrg	    rop = pGeode->cmpDstFmt | amd_gx_exa_alpha_ops[op * 2];
1849f29dbc25Smrg	    blt_mode = usesChanB0(op) ?
1850f29dbc25Smrg		MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
1851f29dbc25Smrg	}
1852f29dbc25Smrg	sizes = (width << 16) | lines;
1853f29dbc25Smrg	if (srcOfs < dstOfs) {
1854f29dbc25Smrg	    srcOfs += (lines - 1) * srcPitch + width * srcBpp - 1;
1855f29dbc25Smrg	    dstOfs += (lines - 1) * dstPitch + width * dstBpp - 1;
1856f29dbc25Smrg	    blt_mode |= MGP_BM_NEG_XDIR | MGP_BM_NEG_YDIR;
1857f29dbc25Smrg	}
1858f29dbc25Smrg	GU2_WAIT_PENDING;
1859f29dbc25Smrg	WRITE_GP32(MGP_RASTER_MODE, rop);
1860f29dbc25Smrg	WRITE_GP32(MGP_SRC_OFFSET, srcOfs);
1861f29dbc25Smrg	WRITE_GP32(MGP_DST_OFFSET, dstOfs);
1862f29dbc25Smrg	WRITE_GP32(MGP_WID_HEIGHT, sizes);
1863f29dbc25Smrg	WRITE_GP32(MGP_STRIDE, strides);
1864f29dbc25Smrg	WRITE_GP16(MGP_BLT_MODE, blt_mode);
1865f29dbc25Smrg    }
1866f29dbc25Smrg}
1867f29dbc25Smrg#endif /* #if XF86EXA */
1868f29dbc25Smrg
1869f29dbc25Smrg/*----------------------------------------------------------------------------
1870f29dbc25Smrg * GXAccelInit.
1871f29dbc25Smrg *
1872f29dbc25Smrg * Description:	This function sets up the supported acceleration routines and
1873f29dbc25Smrg *              appropriate flags.
1874f29dbc25Smrg *
1875f29dbc25Smrg * Parameters:
1876f29dbc25Smrg *      pScrn:	Screeen pointer structure.
1877f29dbc25Smrg *
1878f29dbc25Smrg * Returns:		TRUE on success and FALSE on Failure
1879f29dbc25Smrg *
1880f29dbc25Smrg * Comments:	This function is called in GXScreenInit in
1881f29dbc25Smrg *              geode_driver.c to set  * the acceleration.
1882f29dbc25Smrg *----------------------------------------------------------------------------
1883f29dbc25Smrg */
1884f29dbc25SmrgBool
1885f29dbc25SmrgGXAccelInit(ScreenPtr pScrn)
1886f29dbc25Smrg{
1887f29dbc25Smrg    ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum];
1888f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR(pScrni);
1889f29dbc25Smrg
1890f29dbc25Smrg#if XF86EXA
1891f29dbc25Smrg    ExaDriverPtr pExa = pGeode->pExa;
1892f29dbc25Smrg#endif
1893f29dbc25Smrg
1894f29dbc25Smrg    gu2_xshift = pScrni->bitsPerPixel >> 4;
1895f29dbc25Smrg
1896f29dbc25Smrg    /* XXX - fixme - this will change - we'll need to update it */
1897f29dbc25Smrg
1898f29dbc25Smrg    gu2_pitch = pGeode->Pitch;
1899f29dbc25Smrg
1900f29dbc25Smrg    switch (pGeode->Pitch) {
1901f29dbc25Smrg    case 1024:
1902f29dbc25Smrg	gu2_yshift = 10;
1903f29dbc25Smrg	break;
1904f29dbc25Smrg    case 2048:
1905f29dbc25Smrg	gu2_yshift = 11;
1906f29dbc25Smrg	break;
1907f29dbc25Smrg    case 4096:
1908f29dbc25Smrg	gu2_yshift = 12;
1909f29dbc25Smrg	break;
1910f29dbc25Smrg    default:
1911f29dbc25Smrg	gu2_yshift = 13;
1912f29dbc25Smrg	break;
1913f29dbc25Smrg    }
1914f29dbc25Smrg
1915f29dbc25Smrg#ifdef OPT_ACCEL
1916f29dbc25Smrg    ACCEL_STRIDE = (pGeode->Pitch << 16) | pGeode->Pitch;
1917f29dbc25Smrg    BPP = amd_gx_BppToRasterMode(pScrni->bitsPerPixel);
1918f29dbc25Smrg#endif
1919f29dbc25Smrg
1920f29dbc25Smrg#if XF86EXA
1921f29dbc25Smrg    if (pExa && pGeode->useEXA) {
1922f29dbc25Smrg	pExa->exa_major = EXA_VERSION_MAJOR;
1923f29dbc25Smrg	pExa->exa_minor = EXA_VERSION_MINOR;
1924f29dbc25Smrg
1925f29dbc25Smrg	/* Sync */
1926f29dbc25Smrg	pExa->WaitMarker = amd_gx_exa_WaitMarker;
1927f29dbc25Smrg	/* UploadToScreen */
1928f29dbc25Smrg	pExa->UploadToScreen = amd_gx_exa_UploadToScreen;
1929f29dbc25Smrg	pExa->DownloadFromScreen = amd_gx_exa_DownloadFromScreen;
1930f29dbc25Smrg
1931f29dbc25Smrg	/* Solid fill */
1932f29dbc25Smrg	pExa->PrepareSolid = amd_gx_exa_PrepareSolid;
1933f29dbc25Smrg	pExa->Solid = amd_gx_exa_Solid;
1934f29dbc25Smrg	pExa->DoneSolid = amd_gx_exa_Done;
1935f29dbc25Smrg
1936f29dbc25Smrg	/* Copy */
1937f29dbc25Smrg	pExa->PrepareCopy = amd_gx_exa_PrepareCopy;
1938f29dbc25Smrg	pExa->Copy = amd_gx_exa_Copy;
1939f29dbc25Smrg	pExa->DoneCopy = amd_gx_exa_Done;
1940f29dbc25Smrg
1941f29dbc25Smrg	/* Composite */
1942f29dbc25Smrg	pExa->CheckComposite = amd_gx_exa_CheckComposite;
1943f29dbc25Smrg	pExa->PrepareComposite = amd_gx_exa_PrepareComposite;
1944f29dbc25Smrg	pExa->Composite = amd_gx_exa_Composite;
1945f29dbc25Smrg	pExa->DoneComposite = amd_gx_exa_Done;
1946f29dbc25Smrg
1947f29dbc25Smrg	return exaDriverInit(pScrn, pGeode->pExa);
1948f29dbc25Smrg    }
1949f29dbc25Smrg#endif
1950f29dbc25Smrg
1951f29dbc25Smrg    /* Getting the pointer for acceleration Inforecord */
1952f29dbc25Smrg    pGeode->AccelInfoRec = localRecPtr = XAACreateInfoRec();
1953f29dbc25Smrg    if (!pGeode->AccelInfoRec)
1954f29dbc25Smrg	return FALSE;
1955f29dbc25Smrg
1956f29dbc25Smrg    /* SET ACCELERATION FLAGS */
1957f29dbc25Smrg    localRecPtr->Flags =
1958f29dbc25Smrg	PIXMAP_CACHE | OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER;
1959f29dbc25Smrg
1960f29dbc25Smrg    /* HOOK SYNCRONIZARION ROUTINE */
1961f29dbc25Smrg    localRecPtr->Sync = GXAccelSync;
1962f29dbc25Smrg
1963f29dbc25Smrg#if GX_FILL_RECT_SUPPORT
1964f29dbc25Smrg    /* HOOK FILLED RECTANGLES */
1965f29dbc25Smrg    HOOK(SetupForSolidFill);
1966f29dbc25Smrg    HOOK(SubsequentSolidFillRect);
1967f29dbc25Smrg    localRecPtr->SolidFillFlags = 0;
1968f29dbc25Smrg#endif
1969f29dbc25Smrg
1970f29dbc25Smrg#if GX_MONO_8X8_PAT_SUPPORT
1971f29dbc25Smrg    /* Color expansion */
1972f29dbc25Smrg    HOOK(SetupForMono8x8PatternFill);
1973f29dbc25Smrg    HOOK(SubsequentMono8x8PatternFillRect);
1974f29dbc25Smrg/*         BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD | NO_TRANSPARENCY | */
1975f29dbc25Smrg    localRecPtr->Mono8x8PatternFillFlags = BIT_ORDER_IN_BYTE_MSBFIRST |
1976f29dbc25Smrg	HARDWARE_PATTERN_PROGRAMMED_BITS | HARDWARE_PATTERN_SCREEN_ORIGIN;
1977f29dbc25Smrg#endif
1978f29dbc25Smrg
1979f29dbc25Smrg#if GX_CLREXP_8X8_PAT_SUPPORT
1980f29dbc25Smrg    /* Color expansion */
1981f29dbc25Smrg    HOOK(SetupForColor8x8PatternFill);
1982f29dbc25Smrg    HOOK(SubsequentColor8x8PatternFillRect);
1983f29dbc25Smrg/*         BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD | NO_TRANSPARENCY | */
1984f29dbc25Smrg    localRecPtr->Color8x8PatternFillFlags =
1985f29dbc25Smrg	BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD |
1986f29dbc25Smrg	HARDWARE_PATTERN_PROGRAMMED_BITS | HARDWARE_PATTERN_PROGRAMMED_ORIGIN;
1987f29dbc25Smrg#endif
1988f29dbc25Smrg
1989f29dbc25Smrg#if GX_SCR2SCRCPY_SUPPORT
1990f29dbc25Smrg    /* HOOK SCREEN TO SCREEN COPIES
1991f29dbc25Smrg     * Set flag to only allow copy if transparency is enabled.
1992f29dbc25Smrg     */
1993f29dbc25Smrg    HOOK(SetupForScreenToScreenCopy);
1994f29dbc25Smrg    HOOK(SubsequentScreenToScreenCopy);
1995f29dbc25Smrg    localRecPtr->ScreenToScreenCopyFlags =
1996f29dbc25Smrg	BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD;
1997f29dbc25Smrg#endif
1998f29dbc25Smrg
1999f29dbc25Smrg#if GX_BRES_LINE_SUPPORT
2000f29dbc25Smrg    /* HOOK BRESENHAM SOLID LINES */
2001f29dbc25Smrg    localRecPtr->SolidLineFlags = NO_PLANEMASK;
2002f29dbc25Smrg    HOOK(SetupForSolidLine);
2003f29dbc25Smrg    HOOK(SubsequentSolidBresenhamLine);
2004f29dbc25Smrg    HOOK(SubsequentSolidHorVertLine);
2005f29dbc25Smrg    HOOK(SubsequentSolidTwoPointLine);
2006f29dbc25Smrg    localRecPtr->SolidBresenhamLineErrorTermBits = 15;
2007f29dbc25Smrg#endif
2008f29dbc25Smrg
2009f29dbc25Smrg#if GX_DASH_LINE_SUPPORT
2010f29dbc25Smrg    /* HOOK BRESENHAM DASHED LINES */
2011f29dbc25Smrg    HOOK(SetupForDashedLine);
2012f29dbc25Smrg    HOOK(SubsequentDashedBresenhamLine);
2013f29dbc25Smrg    HOOK(SubsequentDashedTwoPointLine);
2014f29dbc25Smrg    localRecPtr->DashedBresenhamLineErrorTermBits = 15;
2015f29dbc25Smrg    localRecPtr->DashPatternMaxLength = 64;
2016f29dbc25Smrg    localRecPtr->DashedLineFlags = NO_PLANEMASK |	/* TRANSPARENCY_ONLY | */
2017f29dbc25Smrg	LINE_PATTERN_POWER_OF_2_ONLY | LINE_PATTERN_MSBFIRST_MSBJUSTIFIED;
2018f29dbc25Smrg#endif
2019f29dbc25Smrg
2020f29dbc25Smrg#if GX_SCR2SCREXP_SUPPORT
2021f29dbc25Smrg    /* Color expansion */
2022f29dbc25Smrg    HOOK(SetupForScreenToScreenColorExpandFill);
2023f29dbc25Smrg    HOOK(SubsequentScreenToScreenColorExpandFill);
2024f29dbc25Smrg    localRecPtr->ScreenToScreenColorExpandFillFlags =
2025f29dbc25Smrg	BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD | NO_TRANSPARENCY;
2026f29dbc25Smrg#endif
2027f29dbc25Smrg
2028f29dbc25Smrg    if (pGeode->AccelImageWriteBuffers) {
2029f29dbc25Smrg#if GX_SCANLINE_SUPPORT
2030f29dbc25Smrg	localRecPtr->ScanlineImageWriteBuffers =
2031f29dbc25Smrg	    pGeode->AccelImageWriteBuffers;
2032f29dbc25Smrg	localRecPtr->NumScanlineImageWriteBuffers = pGeode->NoOfImgBuffers;
2033f29dbc25Smrg	HOOK(SetupForScanlineImageWrite);
2034f29dbc25Smrg	HOOK(SubsequentScanlineImageWriteRect);
2035f29dbc25Smrg	HOOK(SubsequentImageWriteScanline);
2036f29dbc25Smrg	localRecPtr->ScanlineImageWriteFlags = NO_PLANEMASK | NO_GXCOPY |
2037f29dbc25Smrg	    BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD;
2038f29dbc25Smrg#endif
2039f29dbc25Smrg
2040f29dbc25Smrg    } else {
2041f29dbc25Smrg	localRecPtr->PixmapCacheFlags = DO_NOT_BLIT_STIPPLES;
2042f29dbc25Smrg    }
2043f29dbc25Smrg
2044f29dbc25Smrg    if (pGeode->AccelColorExpandBuffers) {
2045f29dbc25Smrg#if GX_CPU2SCREXP_SUPPORT
2046f29dbc25Smrg	/* Color expansion */
2047f29dbc25Smrg	localRecPtr->ScanlineColorExpandBuffers =
2048f29dbc25Smrg	    pGeode->AccelColorExpandBuffers;
2049f29dbc25Smrg	localRecPtr->NumScanlineColorExpandBuffers =
2050f29dbc25Smrg	    pGeode->NoOfColorExpandLines;
2051f29dbc25Smrg	HOOK(SetupForScanlineCPUToScreenColorExpandFill);
2052f29dbc25Smrg	HOOK(SubsequentScanlineCPUToScreenColorExpandFill);
2053f29dbc25Smrg	HOOK(SubsequentColorExpandScanline);
2054f29dbc25Smrg	localRecPtr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK |
2055f29dbc25Smrg	    BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD;
2056f29dbc25Smrg#endif
2057f29dbc25Smrg    }
2058f29dbc25Smrg#if GX_WRITE_PIXMAP_SUPPORT
2059f29dbc25Smrg    pGeode->WritePixmap = localRecPtr->WritePixmap;
2060f29dbc25Smrg    HOOK(WritePixmap);
2061f29dbc25Smrg#endif
2062f29dbc25Smrg
2063f29dbc25Smrg    return (XAAInit(pScrn, localRecPtr));
2064f29dbc25Smrg}
2065f29dbc25Smrg
2066f29dbc25Smrg/* END OF FILE */
2067