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
4000be8644Schristos#include "xorg-server.h"
4100be8644Schristos
42f29dbc25Smrg#include "vgaHW.h"
43f29dbc25Smrg#include "xf86.h"
4404007ebaSmrg#ifdef HAVE_XAA_H
45f29dbc25Smrg#include "xaalocal.h"
4604007ebaSmrg#endif
47f29dbc25Smrg#include "xf86fbman.h"
48f29dbc25Smrg#include "miline.h"
49f29dbc25Smrg#include "xaarop.h"
50f29dbc25Smrg#include "servermd.h"
51f29dbc25Smrg#include "picture.h"
52f29dbc25Smrg#include "xf86.h"
53f29dbc25Smrg#include "xf86_OSproc.h"
54f29dbc25Smrg#include "xf86Pci.h"
55f29dbc25Smrg#include "xf86PciInfo.h"
56f29dbc25Smrg#include "geode.h"
57f29dbc25Smrg#include "gfx_defs.h"
58f29dbc25Smrg#include "gfx_regs.h"
59f29dbc25Smrg
60f29dbc25Smrg/* Common macros for blend operations are here */
61f29dbc25Smrg
62f29dbc25Smrg#include "geode_blend.h"
63f29dbc25Smrg
64f29dbc25Smrg#undef ulong
65f29dbc25Smrgtypedef unsigned long ulong;
66f29dbc25Smrg
67f29dbc25Smrg#undef uint
68f29dbc25Smrgtypedef unsigned int uint;
69f29dbc25Smrg
70f29dbc25Smrg#undef ushort
71f29dbc25Smrgtypedef unsigned short ushort;
72f29dbc25Smrg
73f29dbc25Smrg#undef uchar
74f29dbc25Smrgtypedef unsigned char uchar;
75f29dbc25Smrg
76f29dbc25Smrg#define CALC_FBOFFSET(x, y) \
77f29dbc25Smrg	        (((ulong)(y) * gu2_pitch + ((ulong)(x) << gu2_xshift)))
78f29dbc25Smrg
79f29dbc25Smrg#define FBADDR(x,y)				\
80f29dbc25Smrg		((unsigned char *)pGeode->FBBase + CALC_FBOFFSET(x, y))
81f29dbc25Smrg
82f29dbc25Smrg#define OS_UDELAY 0
83f29dbc25Smrg#if OS_UDELAY > 0
84f29dbc25Smrg#define OS_USLEEP(usec) usleep(usec);
85f29dbc25Smrg#else
86f29dbc25Smrg#define OS_USLEEP(usec)
87f29dbc25Smrg#endif
88f29dbc25Smrg
89f29dbc25Smrg#ifdef OPT_ACCEL
90f29dbc25Smrgstatic unsigned int BPP;
91f29dbc25Smrgstatic unsigned int BLT_MODE, VEC_MODE;
92f29dbc25Smrgstatic unsigned int ACCEL_STRIDE;
93f29dbc25Smrg
94f29dbc25Smrg#define GU2_WAIT_PENDING while(READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_PENDING)
95f29dbc25Smrg#define GU2_WAIT_BUSY    while(READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_BUSY)
96f29dbc25Smrg#endif
97f29dbc25Smrg
98f29dbc25Smrg#define HOOK(fn) localRecPtr->fn = GX##fn
99f29dbc25Smrg
100f29dbc25Smrg#define DLOG(l, fmt, args...) ErrorF(fmt, ##args)
101f29dbc25Smrg
102f29dbc25Smrg/* static storage declarations */
103f29dbc25Smrg
10404007ebaSmrgtypedef struct sGBltBox {
105f29dbc25Smrg    ulong x, y;
106f29dbc25Smrg    ulong w, h;
107f29dbc25Smrg    ulong color;
108f29dbc25Smrg    int bpp, transparent;
109f29dbc25Smrg} GBltBox;
110f29dbc25Smrg
111f29dbc25Smrg#if GX_SCANLINE_SUPPORT
112f29dbc25Smrgstatic GBltBox giwr;
113f29dbc25Smrg#endif
114f29dbc25Smrg#if GX_CPU2SCREXP_SUPPORT
115f29dbc25Smrgstatic GBltBox gc2s;
116f29dbc25Smrg#endif
117f29dbc25Smrg#if GX_CLREXP_8X8_PAT_SUPPORT
118f29dbc25Smrgstatic ulong *gc8x8p;
119f29dbc25Smrg#endif
120f29dbc25Smrg
121f29dbc25Smrg#if GX_DASH_LINE_SUPPORT
12204007ebaSmrgtypedef struct sGDashLine {
123f29dbc25Smrg    ulong pat[2];
124f29dbc25Smrg    int len;
125f29dbc25Smrg    int fg;
126f29dbc25Smrg    int bg;
127f29dbc25Smrg} GDashLine;
128f29dbc25Smrg
129f29dbc25Smrgstatic GDashLine gdln;
130f29dbc25Smrg#endif
131f29dbc25Smrg
132f29dbc25Smrgstatic unsigned int gu2_xshift, gu2_yshift;
133f29dbc25Smrgstatic unsigned int gu2_pitch;
134f29dbc25Smrg
13504007ebaSmrg#if XF86XAA
136f29dbc25Smrgstatic XAAInfoRecPtr localRecPtr;
13704007ebaSmrg#endif
138f29dbc25Smrg
139f29dbc25Smrg/* pat  0xF0 */
140f29dbc25Smrg/* src  0xCC */
141f29dbc25Smrg/* dst  0xAA */
142f29dbc25Smrg
143f29dbc25Smrg/* (src FUNC dst) */
144f29dbc25Smrg
145f29dbc25Smrgstatic const int SDfn[16] = {
146f29dbc25Smrg    0x00, 0x88, 0x44, 0xCC, 0x22, 0xAA, 0x66, 0xEE,
147f29dbc25Smrg    0x11, 0x99, 0x55, 0xDD, 0x33, 0xBB, 0x77, 0xFF
148f29dbc25Smrg};
149f29dbc25Smrg
150f29dbc25Smrg/* ((src FUNC dst) AND pat-mask) OR (dst AND (NOT pat-mask)) */
151f29dbc25Smrg
152f29dbc25Smrgstatic const int SDfn_PM[16] = {
153f29dbc25Smrg    0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
154f29dbc25Smrg    0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA
155f29dbc25Smrg};
156f29dbc25Smrg
157f29dbc25Smrg/* (pat FUNC dst) */
158f29dbc25Smrg
159f29dbc25Smrgstatic const int PDfn[16] = {
160f29dbc25Smrg    0x00, 0xA0, 0x50, 0xF0, 0x0A, 0xAA, 0x5A, 0xFA,
161f29dbc25Smrg    0x05, 0xA5, 0x55, 0xF5, 0x0F, 0xAF, 0x5F, 0xFF
162f29dbc25Smrg};
163f29dbc25Smrg
164f29dbc25Smrg/* ((pat FUNC dst) AND src-mask) OR (dst AND (NOT src-mask)) */
165f29dbc25Smrg
166f29dbc25Smrgstatic const int PDfn_SM[16] = {
167f29dbc25Smrg    0x22, 0xA2, 0x62, 0xE2, 0x2A, 0xAA, 0x6A, 0xEA,
168f29dbc25Smrg    0x26, 0xA6, 0x66, 0xE6, 0x2E, 0xAE, 0x6E, 0xEE
169f29dbc25Smrg};
170f29dbc25Smrg
171f29dbc25Smrg#ifdef OPT_ACCEL
172f29dbc25Smrgstatic inline CARD32
173f29dbc25Smrgamd_gx_BppToRasterMode(int bpp)
174f29dbc25Smrg{
175f29dbc25Smrg    switch (bpp) {
176f29dbc25Smrg    case 16:
17704007ebaSmrg        return MGP_RM_BPPFMT_565;
178f29dbc25Smrg    case 32:
17904007ebaSmrg        return MGP_RM_BPPFMT_8888;
180f29dbc25Smrg    case 8:
18104007ebaSmrg        return MGP_RM_BPPFMT_332;
182f29dbc25Smrg    default:
18304007ebaSmrg        return 0;
184f29dbc25Smrg    }
185f29dbc25Smrg}
18604007ebaSmrg#endif                          /* OPT_ACCEL */
187f29dbc25Smrg
188f29dbc25Smrg/*----------------------------------------------------------------------------
189f29dbc25Smrg * GXAccelSync.
190f29dbc25Smrg *
191f29dbc25Smrg * Description  :This function is called to synchronize with the graphics
192f29dbc25Smrg *               engine and it waits the graphic engine is idle.  This is
193f29dbc25Smrg *               required before allowing direct access to the framebuffer.
194f29dbc25Smrg *
195f29dbc25Smrg *    Arg        Type     Comment
196f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
197f29dbc25Smrg *
198f29dbc25Smrg * Returns              :none
199f29dbc25Smrg *---------------------------------------------------------------------------*/
200f29dbc25Smrgvoid
201f29dbc25SmrgGXAccelSync(ScrnInfoPtr pScrni)
202f29dbc25Smrg{
203f29dbc25Smrg    //ErrorF("GXAccelSync()\n");
204f29dbc25Smrg#ifndef OPT_ACCEL
205f29dbc25Smrg    gfx_wait_until_idle();
206f29dbc25Smrg#else
207f29dbc25Smrg    GU2_WAIT_BUSY;
208f29dbc25Smrg#endif
209f29dbc25Smrg}
210f29dbc25Smrg
211f29dbc25Smrg#if GX_FILL_RECT_SUPPORT
212f29dbc25Smrg/*----------------------------------------------------------------------------
213f29dbc25Smrg * GXSetupForSolidFill.
214f29dbc25Smrg *
215f29dbc25Smrg * Description  :The SetupFor and Subsequent SolidFill(Rect) provide
216f29dbc25Smrg *               filling rectangular areas of the screen with a
217f29dbc25Smrg *               foreground color.
218f29dbc25Smrg *
219f29dbc25Smrg * Parameters.
220f29dbc25Smrg *    Arg        Type     Comment
221f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
222f29dbc25Smrg *   color        int     foreground fill color
223f29dbc25Smrg *    rop         int     unmapped raster op
224f29dbc25Smrg * planemask     uint     -1 (fill) or pattern data
225f29dbc25Smrg *
226f29dbc25Smrg * Returns              :none
227f29dbc25Smrg *--------------------------------------------------------------------------*/
228f29dbc25Smrgstatic void
229f29dbc25SmrgGXSetupForSolidFill(ScrnInfoPtr pScrni,
23004007ebaSmrg                    int color, int rop, unsigned int planemask)
231f29dbc25Smrg{
232f29dbc25Smrg    //ErrorF("GXSetupForSolidFill(%#x,%#x,%#x)\n", color, rop, planemask);
233f29dbc25Smrg    rop &= 0x0F;
234f29dbc25Smrg#ifndef OPT_ACCEL
235f29dbc25Smrg    gfx_set_solid_pattern(planemask);
236f29dbc25Smrg    gfx_set_solid_source(color);
237f29dbc25Smrg    gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
238f29dbc25Smrg#else
239f29dbc25Smrg    {
24004007ebaSmrg        unsigned int ROP = BPP | (planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
24104007ebaSmrg
24204007ebaSmrg        BLT_MODE = ((ROP ^ (ROP >> 2)) & 0x33) == 0 ? MGP_BM_SRC_MONO : 0;
24304007ebaSmrg        if (((ROP ^ (ROP >> 1)) & 0x55) != 0)
24404007ebaSmrg            BLT_MODE |= MGP_BM_DST_REQ;
24504007ebaSmrg        GU2_WAIT_PENDING;
24604007ebaSmrg        WRITE_GP32(MGP_RASTER_MODE, ROP);
24704007ebaSmrg        WRITE_GP32(MGP_PAT_COLOR_0, planemask);
24804007ebaSmrg        WRITE_GP32(MGP_SRC_COLOR_FG, color);
24904007ebaSmrg        WRITE_GP32(MGP_STRIDE, ACCEL_STRIDE);
250f29dbc25Smrg    }
251f29dbc25Smrg#endif
252f29dbc25Smrg}
253f29dbc25Smrg
254f29dbc25Smrg/*----------------------------------------------------------------------------
255f29dbc25Smrg * GXSubsequentSolidFillRect.
256f29dbc25Smrg *
257f29dbc25Smrg * Description  :see GXSetupForSolidFill.
258f29dbc25Smrg *
259f29dbc25Smrg * Parameters.
260f29dbc25Smrg *    Arg        Type     Comment
261f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
262f29dbc25Smrg *     x          int     destination x offset
263f29dbc25Smrg *     y          int     destination y offset
264f29dbc25Smrg *     w          int     fill area width (pixels)
265f29dbc25Smrg *     h          int     fill area height (pixels)
266f29dbc25Smrg *
267f29dbc25Smrg * Returns      :none
268f29dbc25Smrg *
269f29dbc25Smrg * Sample application uses:
270f29dbc25Smrg *   - Window backgrounds.
271f29dbc25Smrg *   - pull down highlighting.
272f29dbc25Smrg *   - x11perf: rectangle tests (-rect500).
273f29dbc25Smrg *   - x11perf: fill trapezoid tests (-trap100).
274f29dbc25Smrg *   - x11perf: horizontal line segments (-hseg500).
275f29dbc25Smrg *----------------------------------------------------------------------------*/
276f29dbc25Smrgstatic void
277f29dbc25SmrgGXSubsequentSolidFillRect(ScrnInfoPtr pScrni, int x, int y, int w, int h)
278f29dbc25Smrg{
279f29dbc25Smrg    //ErrorF("GXSubsequentSolidFillRect() at %d,%d %dx%d\n", x, y, w, h);
280f29dbc25Smrg#ifndef OPT_ACCEL
281f29dbc25Smrg    gfx_pattern_fill(x, y, w, h);
282f29dbc25Smrg#else
283f29dbc25Smrg    {
28404007ebaSmrg        unsigned int offset = CALC_FBOFFSET(x, y);
28504007ebaSmrg        unsigned int size = (w << 16) | h;
286f29dbc25Smrg
28704007ebaSmrg        GU2_WAIT_PENDING;
28804007ebaSmrg        WRITE_GP32(MGP_DST_OFFSET, offset);
28904007ebaSmrg        WRITE_GP32(MGP_WID_HEIGHT, size);
29004007ebaSmrg        WRITE_GP32(MGP_BLT_MODE, BLT_MODE);
291f29dbc25Smrg    }
292f29dbc25Smrg#endif
293f29dbc25Smrg}
294f29dbc25Smrg
29504007ebaSmrg#endif                          /* if GX_FILL_RECT_SUPPORT */
296f29dbc25Smrg
297f29dbc25Smrg#if GX_CLREXP_8X8_PAT_SUPPORT
298f29dbc25Smrg/*----------------------------------------------------------------------------
299f29dbc25Smrg * GXSetupForColor8x8PatternFill
300f29dbc25Smrg *
301f29dbc25Smrg * Description  :8x8 color pattern data is 64 pixels of full color data
302f29dbc25Smrg *               stored linearly in offscreen video memory.  These patterns
303f29dbc25Smrg *               are useful as a substitute for 8x8 mono patterns when tiling,
304f29dbc25Smrg *               doing opaque stipples, or regular stipples.
305f29dbc25Smrg *
306f29dbc25Smrg *    Arg        Type     Comment
307f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
308f29dbc25Smrg *    patx        int     x offset to pattern data
309f29dbc25Smrg *    paty        int     y offset to pattern data
310f29dbc25Smrg *    rop         int     unmapped raster operation
311f29dbc25Smrg * planemask     uint     -1 (copy) or pattern data
312f29dbc25Smrg * trans_color    int     -1 (copy) or transparent color (not enabled)
313f29dbc25Smrg *                         trans color only supported on source channel
314f29dbc25Smrg *                         or in monochrome pattern channel
315f29dbc25Smrg *
316f29dbc25Smrg * Returns      :none.
317f29dbc25Smrg *
318f29dbc25Smrg *---------------------------------------------------------------------------*/
319f29dbc25Smrg
320f29dbc25Smrgstatic void
321f29dbc25SmrgGXSetupForColor8x8PatternFill(ScrnInfoPtr pScrni, int patx, int paty, int rop,
32204007ebaSmrg                              uint planemask, int trans_color)
323f29dbc25Smrg{
324f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR(pScrni);
325f29dbc25Smrg
326f29dbc25Smrg    //ErrorF("GXSetupForColor8x8PatternFill() pat %#x,%#x rop %#x %#x %#x\n",
327f29dbc25Smrg    //    patx, paty, rop, planemask, trans_color);
328f29dbc25Smrg    rop &= 0x0F;
32904007ebaSmrg    gc8x8p = (unsigned long *) FBADDR(patx, paty);
330f29dbc25Smrg    /* gfx_set_solid_pattern is needed to clear src/pat transparency */
331f29dbc25Smrg    gfx_set_solid_pattern(0);
332f29dbc25Smrg    gfx_set_raster_operation(planemask == ~0U ? PDfn[rop] :
33304007ebaSmrg                             (gfx_set_solid_source(planemask), PDfn_SM[rop]));
334f29dbc25Smrg    gfx2_set_source_stride(pGeode->Pitch);
335f29dbc25Smrg    gfx2_set_destination_stride(pGeode->Pitch);
336f29dbc25Smrg    if (trans_color == -1)
33704007ebaSmrg        gfx2_set_source_transparency(0, 0);
338f29dbc25Smrg    else
33904007ebaSmrg        gfx2_set_source_transparency(trans_color, ~0);
340f29dbc25Smrg}
341f29dbc25Smrg
342f29dbc25Smrg/*----------------------------------------------------------------------------
343f29dbc25Smrg * GXSubsequentColor8x8PatternFillRect
344f29dbc25Smrg *
345f29dbc25Smrg * Description  :see GXSetupForColor8x8PatternFill.
346f29dbc25Smrg *
347f29dbc25Smrg *    Arg        Type     Comment
348f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
349f29dbc25Smrg *   patx         int     pattern phase x offset
350f29dbc25Smrg *   paty         int     pattern phase y offset
351f29dbc25Smrg *      x         int     destination x offset
352f29dbc25Smrg *      y         int     destination y offset
353f29dbc25Smrg *      w         int     fill area width (pixels)
354f29dbc25Smrg *      h         int     fill area height (pixels)
355f29dbc25Smrg *
356f29dbc25Smrg * Returns      :none
357f29dbc25Smrg *
358f29dbc25Smrg * Sample application uses:
359f29dbc25Smrg *   - Patterned desktops
360f29dbc25Smrg *   - x11perf: stippled rectangle tests (-srect500).
361f29dbc25Smrg *   - x11perf: opaque stippled rectangle tests (-osrect500).
362f29dbc25Smrg *--------------------------------------------------------------------------*/
363f29dbc25Smrgstatic void
364f29dbc25SmrgGXSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrni, int patx, int paty,
36504007ebaSmrg                                    int x, int y, int w, int h)
366f29dbc25Smrg{
367f29dbc25Smrg    //ErrorF(
368f29dbc25Smrg    //    "GXSubsequentColor8x8PatternFillRect() patxy %d,%d at %d,%d %dsx%d\n",
369f29dbc25Smrg    //    patx, paty, x, y, w, h);
370f29dbc25Smrg    gfx2_set_pattern_origin(patx, paty);
371f29dbc25Smrg    gfx2_color_pattern_fill(CALC_FBOFFSET(x, y), w, h, gc8x8p);
372f29dbc25Smrg}
373f29dbc25Smrg
374f29dbc25Smrg/* GX_CLREXP_8X8_PAT_SUPPORT */
375f29dbc25Smrg#endif
376f29dbc25Smrg
377f29dbc25Smrg#if GX_MONO_8X8_PAT_SUPPORT
378f29dbc25Smrg/*----------------------------------------------------------------------------
379f29dbc25Smrg * GXSetupForMono8x8PatternFill
380f29dbc25Smrg *
381f29dbc25Smrg * Description  :8x8 mono pattern data is 64 bits of color expansion data
382f29dbc25Smrg *               with ones indicating the foreground color and zeros
383f29dbc25Smrg *               indicating the background color.  These patterns are
384f29dbc25Smrg *               useful when tiling, doing opaque stipples, or regular
385f29dbc25Smrg *               stipples.
386f29dbc25Smrg *
387f29dbc25Smrg *    Arg        Type     Comment
388f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
389f29dbc25Smrg *    patx        int     x offset to pattern data
390f29dbc25Smrg *    paty        int     y offset to pattern data
391f29dbc25Smrg *     fg         int     foreground color
392f29dbc25Smrg *     bg         int     -1 (transparent) or background color
393f29dbc25Smrg *    rop         int     unmapped raster operation
394f29dbc25Smrg * planemask     uint     -1 (copy) or pattern data
395f29dbc25Smrg *
396f29dbc25Smrg * Returns      :none.
397f29dbc25Smrg *
398f29dbc25Smrg * Comments     :none.
399f29dbc25Smrg *
400f29dbc25Smrg *--------------------------------------------------------------------------*/
401f29dbc25Smrgstatic void
402f29dbc25SmrgGXSetupForMono8x8PatternFill(ScrnInfoPtr pScrni, int patx, int paty,
40304007ebaSmrg                             int fg, int bg, int rop, uint planemask)
404f29dbc25Smrg{
405f29dbc25Smrg    //ErrorF(
406f29dbc25Smrg    //"GXSetupForMono8x8PatternFill() pat %#x,%#x fg %#x bg %#x %#x %#x\n",
407f29dbc25Smrg    //patx, paty, fg, bg, rop, planemask);
408f29dbc25Smrg    rop &= 0x0F;
409f29dbc25Smrg#ifndef OPT_ACCEL
410f29dbc25Smrg    gfx_set_mono_pattern(bg, fg, patx, paty, bg == -1 ? 1 : 0);
411f29dbc25Smrg    gfx_set_raster_operation(planemask == ~0U ? PDfn[rop] :
41204007ebaSmrg                             (gfx_set_solid_source(planemask), PDfn_SM[rop]));
413f29dbc25Smrg#else
414f29dbc25Smrg    {
41504007ebaSmrg        unsigned int ROP = BPP |
41604007ebaSmrg            (bg ==
41704007ebaSmrg             -1 ? MGP_RM_PAT_MONO | MGP_RM_PAT_TRANS : MGP_RM_PAT_MONO) |
41804007ebaSmrg            (planemask == ~0U ? PDfn[rop] : PDfn_SM[rop]);
41904007ebaSmrg        BLT_MODE = ((ROP ^ (ROP >> 2)) & 0x33) == 0 ? MGP_BM_SRC_MONO : 0;
42004007ebaSmrg        if (((ROP ^ (ROP >> 1)) & 0x55) != 0)
42104007ebaSmrg            BLT_MODE |= MGP_BM_DST_REQ;
42204007ebaSmrg        GU2_WAIT_PENDING;
42304007ebaSmrg        WRITE_GP32(MGP_RASTER_MODE, ROP);
42404007ebaSmrg        WRITE_GP32(MGP_SRC_COLOR_FG, planemask);
42504007ebaSmrg        WRITE_GP32(MGP_PAT_COLOR_0, bg);
42604007ebaSmrg        WRITE_GP32(MGP_PAT_COLOR_1, fg);
42704007ebaSmrg        WRITE_GP32(MGP_PAT_DATA_0, patx);
42804007ebaSmrg        WRITE_GP32(MGP_PAT_DATA_1, paty);
42904007ebaSmrg        WRITE_GP32(MGP_STRIDE, ACCEL_STRIDE);
430f29dbc25Smrg    }
431f29dbc25Smrg#endif
432f29dbc25Smrg}
433f29dbc25Smrg
434f29dbc25Smrg/*----------------------------------------------------------------------------
435f29dbc25Smrg * GXSubsequentMono8x8PatternFillRect
436f29dbc25Smrg *
437f29dbc25Smrg * Description  :see GXSetupForMono8x8PatternFill
438f29dbc25Smrg *
439f29dbc25Smrg *    Arg        Type     Comment
440f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
441f29dbc25Smrg *   patx         int     pattern phase x offset
442f29dbc25Smrg *   paty         int     pattern phase y offset
443f29dbc25Smrg *      x         int     destination x offset
444f29dbc25Smrg *      y         int     destination y offset
445f29dbc25Smrg *      w         int     fill area width (pixels)
446f29dbc25Smrg *      h         int     fill area height (pixels)
447f29dbc25Smrg
448f29dbc25Smrg * Returns      :none
449f29dbc25Smrg *
450f29dbc25Smrg * Sample application uses:
451f29dbc25Smrg *   - Patterned desktops
452f29dbc25Smrg *   - x11perf: stippled rectangle tests (-srect500).
453f29dbc25Smrg *   - x11perf: opaque stippled rectangle tests (-osrect500).
454f29dbc25Smrg *--------------------------------------------------------------------------*/
455f29dbc25Smrgstatic void
456f29dbc25SmrgGXSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrni, int patx, int paty,
45704007ebaSmrg                                   int x, int y, int w, int h)
458f29dbc25Smrg{
459f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() pat %#x,%#x at %d,%d %dx%d\n",
46004007ebaSmrg                 __func__, patx, paty, x, y, w, h));
461f29dbc25Smrg#ifndef OPT_ACCEL
462f29dbc25Smrg    gfx_pattern_fill(x, y, w, h);
463f29dbc25Smrg#else
464f29dbc25Smrg    {
46504007ebaSmrg        unsigned int offset =
46604007ebaSmrg            CALC_FBOFFSET(x, y) | ((x & 7) << 26) | ((y & 7) << 29);
46704007ebaSmrg        unsigned int size = (w << 16) | h;
46804007ebaSmrg
46904007ebaSmrg        GU2_WAIT_PENDING;
47004007ebaSmrg        WRITE_GP32(MGP_DST_OFFSET, offset);
47104007ebaSmrg        WRITE_GP32(MGP_WID_HEIGHT, size);
47204007ebaSmrg        WRITE_GP32(MGP_BLT_MODE, BLT_MODE);
473f29dbc25Smrg    }
474f29dbc25Smrg#endif
475f29dbc25Smrg}
476f29dbc25Smrg
47704007ebaSmrg#endif                          /* GX_MONO_8X8_PAT_SUPPORT */
478f29dbc25Smrg
479f29dbc25Smrg#if GX_SCR2SCRCPY_SUPPORT
480f29dbc25Smrg/*----------------------------------------------------------------------------
481f29dbc25Smrg * GXSetupForScreenToScreenCopy
482f29dbc25Smrg *
483f29dbc25Smrg * Description  :SetupFor and Subsequent ScreenToScreenCopy functions
484f29dbc25Smrg *               provide an interface for copying rectangular areas from
485f29dbc25Smrg *               video memory to video memory.
486f29dbc25Smrg *
487f29dbc25Smrg *    Arg        Type     Comment
488f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
489f29dbc25Smrg *   xdir         int     x copy direction (up/dn)
490f29dbc25Smrg *   ydir         int     y copy direction (up/dn)
491f29dbc25Smrg *    rop         int     unmapped raster operation
492f29dbc25Smrg * planemask     uint     -1 (copy) or pattern data
493f29dbc25Smrg * trans_color    int     -1 (copy) or transparent color
494f29dbc25Smrg *
495f29dbc25Smrg * Returns      :none
496f29dbc25Smrg *---------------------------------------------------------------------------*/
497f29dbc25Smrgstatic void
498f29dbc25SmrgGXSetupForScreenToScreenCopy(ScrnInfoPtr pScrni, int xdir, int ydir, int rop,
49904007ebaSmrg                             uint planemask, int trans_color)
500f29dbc25Smrg{
501f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() xd%d yd%d rop %#x %#x %#x\n",
50204007ebaSmrg                 __func__, xdir, ydir, rop, planemask, trans_color));
503f29dbc25Smrg    rop &= 0x0F;
504f29dbc25Smrg#ifndef OPT_ACCEL
505f29dbc25Smrg    {
50604007ebaSmrg        GeodeRec *pGeode = GEODEPTR(pScrni);
50704007ebaSmrg
50804007ebaSmrg        gfx_set_solid_pattern(planemask);
50904007ebaSmrg        /* transparency is a parameter to set_rop, but set...pattern clears
51004007ebaSmrg         * transparency */
51104007ebaSmrg        if (trans_color == -1)
51204007ebaSmrg            gfx2_set_source_transparency(0, 0);
51304007ebaSmrg        else
51404007ebaSmrg            gfx2_set_source_transparency(trans_color, ~0);
51504007ebaSmrg        gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
51604007ebaSmrg        gfx2_set_source_stride(pGeode->Pitch);
51704007ebaSmrg        gfx2_set_destination_stride(pGeode->Pitch);
518f29dbc25Smrg    }
519f29dbc25Smrg#else
520f29dbc25Smrg    {
52104007ebaSmrg        unsigned int ROP = BPP | (planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
52204007ebaSmrg
52304007ebaSmrg        if (trans_color != -1)
52404007ebaSmrg            ROP |= MGP_RM_SRC_TRANS;
52504007ebaSmrg        BLT_MODE = ((ROP ^ (ROP >> 1)) & 0x55) != 0 ?
52604007ebaSmrg            MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
52704007ebaSmrg        GU2_WAIT_PENDING;
52804007ebaSmrg        WRITE_GP32(MGP_RASTER_MODE, ROP);
52904007ebaSmrg        WRITE_GP32(MGP_PAT_COLOR_0, planemask);
53004007ebaSmrg        WRITE_GP32(MGP_SRC_COLOR_FG, trans_color);
53104007ebaSmrg        WRITE_GP32(MGP_SRC_COLOR_BG, ~0);
53204007ebaSmrg        WRITE_GP32(MGP_STRIDE, ACCEL_STRIDE);
533f29dbc25Smrg    }
534f29dbc25Smrg#endif
535f29dbc25Smrg}
536f29dbc25Smrg
537f29dbc25Smrg/*----------------------------------------------------------------------------
538f29dbc25Smrg * GXSubsquentScreenToScreenCopy
539f29dbc25Smrg *
540f29dbc25Smrg * Description  :see GXSetupForScreenToScreenCopy.
541f29dbc25Smrg *
542f29dbc25Smrg *    Arg        Type     Comment
543f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
544f29dbc25Smrg *     x1         int     source x offset
545f29dbc25Smrg *     y1         int     source y offset
546f29dbc25Smrg *     x2         int     destination x offset
547f29dbc25Smrg *     y2         int     destination y offset
548f29dbc25Smrg *      w         int     copy area width (pixels)
549f29dbc25Smrg *      h         int     copy area height (pixels)
550f29dbc25Smrg *
551f29dbc25Smrg * Returns      :none
552f29dbc25Smrg *
553f29dbc25Smrg * Sample application uses (non-transparent):
554f29dbc25Smrg *   - Moving windows.
555f29dbc25Smrg *   - x11perf: scroll tests (-scroll500).
556f29dbc25Smrg *   - x11perf: copy from window to window (-copywinwin500).
557f29dbc25Smrg *---------------------------------------------------------------------------*/
558f29dbc25Smrgstatic void
559f29dbc25SmrgGXSubsequentScreenToScreenCopy(ScrnInfoPtr pScrni,
56004007ebaSmrg                               int x1, int y1, int x2, int y2, int w, int h)
561f29dbc25Smrg{
562f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() from %d,%d to %d,%d %dx%d\n",
56304007ebaSmrg                 __func__, x1, y1, x2, y2, w, h));
564f29dbc25Smrg#ifndef OPT_ACCEL
565f29dbc25Smrg    {
56604007ebaSmrg        int flags = 0;
56704007ebaSmrg
56804007ebaSmrg        if (x2 > x1)
56904007ebaSmrg            flags |= 1;
57004007ebaSmrg        if (y2 > y1)
57104007ebaSmrg            flags |= 2;
57204007ebaSmrg        gfx2_screen_to_screen_blt(CALC_FBOFFSET(x1, y1), CALC_FBOFFSET(x2,
57304007ebaSmrg                                                                       y2), w,
57404007ebaSmrg                                  h, flags);
575f29dbc25Smrg    }
576f29dbc25Smrg#else
577f29dbc25Smrg    {
57804007ebaSmrg        GeodeRec *pGeode = GEODEPTR(pScrni);
57904007ebaSmrg        unsigned int src = CALC_FBOFFSET(x1, y1);
58004007ebaSmrg        unsigned int dst = CALC_FBOFFSET(x2, y2);
58104007ebaSmrg        unsigned int size = (w << 16) | h;
58204007ebaSmrg        unsigned int blt_mode = BLT_MODE;
58304007ebaSmrg
58404007ebaSmrg        if (x2 > x1) {
58504007ebaSmrg            int n = (w << gu2_xshift) - 1;
58604007ebaSmrg
58704007ebaSmrg            src += n;
58804007ebaSmrg            dst += n;
58904007ebaSmrg            blt_mode |= MGP_BM_NEG_XDIR;
59004007ebaSmrg        }
59104007ebaSmrg        if (y2 > y1) {
59204007ebaSmrg            int n = (h - 1) * pGeode->Pitch;
59304007ebaSmrg
59404007ebaSmrg            src += n;
59504007ebaSmrg            dst += n;
59604007ebaSmrg            blt_mode |= MGP_BM_NEG_YDIR;
59704007ebaSmrg        }
59804007ebaSmrg        GU2_WAIT_PENDING;
59904007ebaSmrg        WRITE_GP32(MGP_SRC_OFFSET, src);
60004007ebaSmrg        WRITE_GP32(MGP_DST_OFFSET, dst);
60104007ebaSmrg        WRITE_GP32(MGP_WID_HEIGHT, size);
60204007ebaSmrg        WRITE_GP16(MGP_BLT_MODE, blt_mode);
603f29dbc25Smrg    }
604f29dbc25Smrg#endif
605f29dbc25Smrg}
606f29dbc25Smrg
60704007ebaSmrg#endif                          /* if GX_SCR2SCRCPY_SUPPORT */
608f29dbc25Smrg
609f29dbc25Smrg#if GX_SCANLINE_SUPPORT
610f29dbc25Smrg/*----------------------------------------------------------------------------
611f29dbc25Smrg * GXSetupForScanlineImageWrite
612f29dbc25Smrg *
613f29dbc25Smrg * Description  :SetupFor/Subsequent ScanlineImageWrite and ImageWriteScanline
614f29dbc25Smrg *               transfer full color pixel data from system memory to video
615f29dbc25Smrg *               memory.  This is useful for dealing with alignment issues and
616f29dbc25Smrg *               performing raster ops on the data.
617f29dbc25Smrg *
618f29dbc25Smrg *    Arg        Type     Comment
619f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
620f29dbc25Smrg *    rop         int     unmapped raster operation
621f29dbc25Smrg * planemask     uint     -1 (copy) or pattern data
622f29dbc25Smrg *    bpp         int     bits per pixel (unused)
623f29dbc25Smrg *  depth         int     color depth (unused)
624f29dbc25Smrg *
625f29dbc25Smrg * Returns      :none
626f29dbc25Smrg *
627f29dbc25Smrg *  x11perf -putimage10
628f29dbc25Smrg *  x11perf -putimage100
629f29dbc25Smrg *  x11perf -putimage500
630f29dbc25Smrg *----------------------------------------------------------------------------
631f29dbc25Smrg */
632f29dbc25Smrgstatic void
633f29dbc25SmrgGXSetupForScanlineImageWrite(ScrnInfoPtr pScrni, int rop, uint planemask,
63404007ebaSmrg                             int trans_color, int bpp, int depth)
635f29dbc25Smrg{
636f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR(pScrni);
637f29dbc25Smrg
638f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() rop %#x %#x %#x %d %d\n",
63904007ebaSmrg                 __func__, rop, planemask, trans_color, bpp, depth));
640f29dbc25Smrg    rop &= 0x0F;
641f29dbc25Smrg    /* transparency is a parameter to set_rop, but set...pattern clears
642f29dbc25Smrg     * transparency */
643f29dbc25Smrg    gfx_set_solid_pattern(planemask);
644f29dbc25Smrg    if (trans_color == -1)
64504007ebaSmrg        gfx2_set_source_transparency(0, 0);
646f29dbc25Smrg    else
64704007ebaSmrg        gfx2_set_source_transparency(trans_color, ~0);
648f29dbc25Smrg    gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
649f29dbc25Smrg    gfx2_set_source_stride(pGeode->Pitch);
650f29dbc25Smrg    gfx2_set_destination_stride(pGeode->Pitch);
651f29dbc25Smrg}
652f29dbc25Smrg
653f29dbc25Smrg/*----------------------------------------------------------------------------
654f29dbc25Smrg * GXSubsequentScanlineImageWriteRect
655f29dbc25Smrg *
656f29dbc25Smrg * Description  : see GXSetupForScanlineImageWrite.
657f29dbc25Smrg *
658f29dbc25Smrg *    Arg        Type     Comment
659f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
660f29dbc25Smrg *      x         int     destination x offset
661f29dbc25Smrg *      y         int     destination y offset
662f29dbc25Smrg *      w         int     copy area width (pixels)
663f29dbc25Smrg *      h         int     copy area height (pixels)
664f29dbc25Smrg * skipleft       int     x margin (pixels) to skip (not enabled)
665f29dbc25Smrg *
666f29dbc25Smrg * Returns      :none
667f29dbc25Smrg *---------------------------------------------------------------------------*/
668f29dbc25Smrgstatic void
669f29dbc25SmrgGXSubsequentScanlineImageWriteRect(ScrnInfoPtr pScrni,
67004007ebaSmrg                                   int x, int y, int w, int h, int skipleft)
671f29dbc25Smrg{
672f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() rop %d,%d %dx%d %d\n",
67304007ebaSmrg                 __func__, x, y, w, h, skipleft));
674f29dbc25Smrg    giwr.x = x;
675f29dbc25Smrg    giwr.y = y;
676f29dbc25Smrg    giwr.w = w;
677f29dbc25Smrg    giwr.h = h;
678f29dbc25Smrg#if !GX_USE_OFFSCRN_MEM
679f29dbc25Smrg#if !GX_ONE_LINE_AT_A_TIME
680f29dbc25Smrg    GXAccelSync(pScrni);
681f29dbc25Smrg#endif
682f29dbc25Smrg#endif
683f29dbc25Smrg}
684f29dbc25Smrg
685f29dbc25Smrg/*----------------------------------------------------------------------------
686f29dbc25Smrg * GXSubsquentImageWriteScanline
687f29dbc25Smrg *
688f29dbc25Smrg * Description  : see GXSetupForScanlineImageWrite.
689f29dbc25Smrg *
690f29dbc25Smrg *    Arg        Type     Comment
691f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
692f29dbc25Smrg *  bufno         int     scanline number in write group
693f29dbc25Smrg *
694f29dbc25Smrg * Returns      :none
695f29dbc25Smrg *
696f29dbc25Smrg * Sample application uses (non-transparent):
697f29dbc25Smrg *   - Moving windows.
698f29dbc25Smrg *   - x11perf: scroll tests (-scroll500).
699f29dbc25Smrg *   - x11perf: copy from window to window (-copywinwin500).
700f29dbc25Smrg *
701f29dbc25Smrg *---------------------------------------------------------------------------*/
702f29dbc25Smrgstatic void
703f29dbc25SmrgGXSubsequentImageWriteScanline(ScrnInfoPtr pScrni, int bufno)
704f29dbc25Smrg{
705f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR(pScrni);
706f29dbc25Smrg
707f29dbc25Smrg#if !GX_USE_OFFSCRN_MEM
708f29dbc25Smrg    unsigned long offset;
709f29dbc25Smrg#endif
710f29dbc25Smrg
711f29dbc25Smrg#if GX_ONE_LINE_AT_A_TIME
712f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %d\n", __func__, bufno));
713f29dbc25Smrg#if !GX_USE_OFFSCRN_MEM
714f29dbc25Smrg    offset = pGeode->AccelImageWriteBuffers[bufno] - pGeode->FBBase;
715f29dbc25Smrg    gfx2_screen_to_screen_blt(offset, CALC_FBOFFSET(giwr.x, giwr.y), giwr.w,
71604007ebaSmrg                              1, 0);
71704007ebaSmrg#else                           /* if !GX_USE_OFFSCRN_MEM */
718f29dbc25Smrg    gfx2_color_bitmap_to_screen_blt(0, 0, CALC_FBOFFSET(giwr.x, giwr.y),
71904007ebaSmrg                                    giwr.w, 1,
72004007ebaSmrg                                    pGeode->AccelImageWriteBuffers[bufno],
72104007ebaSmrg                                    pGeode->Pitch);
72204007ebaSmrg#endif                          /* if !GX_USE_OFFSCRN_MEM */
723f29dbc25Smrg    ++giwr.y;
72404007ebaSmrg#else                           /* if GX_ONE_LINE_AT_A_TIME */
725f29dbc25Smrg    int blt_height;
726f29dbc25Smrg
727f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %d\n", __func__, bufno));
728f29dbc25Smrg
729f29dbc25Smrg    if ((blt_height = pGeode->NoOfImgBuffers) > giwr.h)
73004007ebaSmrg        blt_height = giwr.h;
731f29dbc25Smrg    if (++bufno < blt_height)
73204007ebaSmrg        return;
733f29dbc25Smrg#if !GX_USE_OFFSCRN_MEM
734f29dbc25Smrg    offset = pGeode->AccelImageWriteBuffers[0] - pGeode->FBBase;
735f29dbc25Smrg    gfx2_screen_to_screen_blt(offset, CALC_FBOFFSET(giwr.x, giwr.y), giwr.w,
73604007ebaSmrg                              blt_height, 0);
737f29dbc25Smrg    GXAccelSync(pScrni);
73804007ebaSmrg#else                           /* if !GX_USE_OFFSCRN_MEM */
739f29dbc25Smrg    gfx2_color_bitmap_to_screen_blt(0, 0, CALC_FBOFFSET(giwr.x, giwr.y),
74004007ebaSmrg                                    giwr.w, blt_height,
74104007ebaSmrg                                    pGeode->AccelImageWriteBuffers[0],
74204007ebaSmrg                                    pGeode->Pitch);
74304007ebaSmrg#endif                          /* if !GX_USE_OFFSCRN_MEM */
744f29dbc25Smrg    giwr.h -= blt_height;
745f29dbc25Smrg    giwr.y += blt_height;
74604007ebaSmrg#endif                          /* if GX_ONE_LINE_AT_A_TIME */
747f29dbc25Smrg}
74804007ebaSmrg#endif                          /* GX_SCANLINE_SUPPORT */
749f29dbc25Smrg
750f29dbc25Smrg#if GX_CPU2SCREXP_SUPPORT
751f29dbc25Smrg/*----------------------------------------------------------------------------
752f29dbc25Smrg * GXSetupForScanlineCPUToScreenColorExpandFill
753f29dbc25Smrg *
754f29dbc25Smrg * Description  :SetupFor/Subsequent CPUToScreenColorExpandFill and
755f29dbc25Smrg *               ColorExpandScanline routines provide an interface for
756f29dbc25Smrg *               doing expansion blits from source patterns stored in
757f29dbc25Smrg *               system memory.
758f29dbc25Smrg *
759f29dbc25Smrg *    Arg        Type     Comment
760f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
761f29dbc25Smrg *     fg         int     foreground color
762f29dbc25Smrg *     bg         int     -1 (transparent) or background color
763f29dbc25Smrg *    rop         int     unmapped raster operation
764f29dbc25Smrg * planemask     uint     -1 (copy) or pattern data
765f29dbc25Smrg *
766f29dbc25Smrg * Returns      :none.
767f29dbc25Smrg *---------------------------------------------------------------------------*/
768f29dbc25Smrg
769f29dbc25Smrgstatic void
770f29dbc25SmrgGXSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrni,
77104007ebaSmrg                                             int fg, int bg, int rop,
77204007ebaSmrg                                             uint planemask)
773f29dbc25Smrg{
774f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR(pScrni);
775f29dbc25Smrg    ulong srcpitch;
776f29dbc25Smrg
777f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() fg %#x bg %#x rop %#x %#x\n",
77804007ebaSmrg                 __func__, fg, bg, rop, planemask));
779f29dbc25Smrg    rop &= 0x0F;
780f29dbc25Smrg    srcpitch = ((pGeode->Pitch + 31) >> 5) << 2;
781f29dbc25Smrg#ifndef OPT_ACCEL
782f29dbc25Smrg    gfx_set_solid_pattern(planemask);
783f29dbc25Smrg    gfx_set_mono_source(bg, fg, bg == -1 ? 1 : 0);
784f29dbc25Smrg    gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
785f29dbc25Smrg    gfx2_set_source_stride(srcpitch);
786f29dbc25Smrg    gfx2_set_destination_stride(pGeode->Pitch);
787f29dbc25Smrg#else
788f29dbc25Smrg    {
78904007ebaSmrg        unsigned int stride = (srcpitch << 16) | pGeode->Pitch;
79004007ebaSmrg        unsigned int ROP = BPP | (planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
79104007ebaSmrg
79204007ebaSmrg        if (bg == -1)
79304007ebaSmrg            ROP |= MGP_RM_SRC_TRANS;
79404007ebaSmrg        BLT_MODE = ((ROP ^ (ROP >> 1)) & 0x55) != 0 ?
79504007ebaSmrg            MGP_BM_SRC_MONO | MGP_BM_SRC_FB | MGP_BM_DST_REQ :
79604007ebaSmrg            MGP_BM_SRC_MONO | MGP_BM_SRC_FB;
79704007ebaSmrg        GU2_WAIT_PENDING;
79804007ebaSmrg        WRITE_GP32(MGP_RASTER_MODE, ROP);
79904007ebaSmrg        WRITE_GP32(MGP_PAT_COLOR_0, planemask);
80004007ebaSmrg        WRITE_GP32(MGP_SRC_COLOR_BG, bg);
80104007ebaSmrg        WRITE_GP32(MGP_SRC_COLOR_FG, fg);
80204007ebaSmrg        WRITE_GP32(MGP_STRIDE, stride);
803f29dbc25Smrg    }
804f29dbc25Smrg#endif
805f29dbc25Smrg}
806f29dbc25Smrg
807f29dbc25Smrg/*----------------------------------------------------------------------------
808f29dbc25Smrg * GXSubsequentScanlineCPUToScreenColorExpandFill
809f29dbc25Smrg *
810f29dbc25Smrg  Description  :see GXSetupForScanlineCPUToScreenColorExpandFill
811f29dbc25Smrg *
812f29dbc25Smrg * Parameters:
813f29dbc25Smrg *    Arg        Type     Comment
814f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
815f29dbc25Smrg *     x          int     destination x offset
816f29dbc25Smrg *     y          int     destination y offset
817f29dbc25Smrg *     w          int     fill area width (pixels)
818f29dbc25Smrg *     h          int     fill area height (pixels)
819f29dbc25Smrg *
820f29dbc25Smrg * Returns      :none
821f29dbc25Smrg *
822f29dbc25Smrg *---------------------------------------------------------------------------*/
823f29dbc25Smrgstatic void
824f29dbc25SmrgGXSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrni,
82504007ebaSmrg                                               int x, int y, int w, int h,
82604007ebaSmrg                                               int skipleft)
827f29dbc25Smrg{
828f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %dx%d %d\n",
82904007ebaSmrg                 __func__, x, y, w, h, skipleft));
830f29dbc25Smrg    gc2s.x = x;
831f29dbc25Smrg    gc2s.y = y;
832f29dbc25Smrg    gc2s.w = w;
833f29dbc25Smrg    gc2s.h = h;
834f29dbc25Smrg#ifdef OPT_ACCEL
835f29dbc25Smrg    {
836f29dbc25Smrg#if GX_ONE_LINE_AT_A_TIME
83704007ebaSmrg        unsigned int size = (gc2s.w << 16) | 1;
838f29dbc25Smrg
83904007ebaSmrg        GU2_WAIT_PENDING;
84004007ebaSmrg        WRITE_GP32(MGP_WID_HEIGHT, size);
841f29dbc25Smrg#else
84204007ebaSmrg        GeodeRec *pGeode = GEODEPTR(pScrni);
84304007ebaSmrg        unsigned int src = pGeode->AccelColorExpandBuffers[0] - pGeode->FBBase;
84404007ebaSmrg
84504007ebaSmrg        GU2_WAIT_PENDING;
84604007ebaSmrg        WRITE_GP32(MGP_SRC_OFFSET, src);
847f29dbc25Smrg#endif
848f29dbc25Smrg    }
849f29dbc25Smrg#endif
850f29dbc25Smrg}
851f29dbc25Smrg
852f29dbc25Smrg/*----------------------------------------------------------------------------
853f29dbc25Smrg * GXSubsequentColorExpandScanline
854f29dbc25Smrg *
855f29dbc25Smrg * Description  :see GXSetupForScanlineCPUToScreenColorExpandFill
856f29dbc25Smrg *
857f29dbc25Smrg *    Arg        Type     Comment
858f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
859f29dbc25Smrg *  bufno         int     scanline number in write group
860f29dbc25Smrg *
861f29dbc25Smrg * Returns      :none
862f29dbc25Smrg *----------------------------------------------------------------------------
863f29dbc25Smrg */
864f29dbc25Smrgstatic void
865f29dbc25SmrgGXSubsequentColorExpandScanline(ScrnInfoPtr pScrni, int bufno)
866f29dbc25Smrg{
867f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR(pScrni);
868f29dbc25Smrg
869f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %d\n", __func__, bufno));
870f29dbc25Smrg#ifndef OPT_ACCEL
871f29dbc25Smrg    {
872f29dbc25Smrg#if GX_ONE_LINE_AT_A_TIME
87304007ebaSmrg        ulong offset = pGeode->AccelColorExpandBuffers[bufno] - pGeode->FBBase;
87404007ebaSmrg
87504007ebaSmrg        gfx2_mono_expand_blt(offset, 0, 0, CALC_FBOFFSET(gc2s.x, gc2s.y),
87604007ebaSmrg                             gc2s.w, 1, 0);
87704007ebaSmrg        ++gc2s.y;
87804007ebaSmrg#else                           /* if GX_ONE_LINE_AT_A_TIME */
87904007ebaSmrg        ulong srcpitch;
88004007ebaSmrg        int blt_height;
88104007ebaSmrg
88204007ebaSmrg        if ((blt_height = pGeode->NoOfImgBuffers) > gc2s.h)
88304007ebaSmrg            blt_height = gc2s.h;
88404007ebaSmrg        if (++bufno < blt_height)
88504007ebaSmrg            return;
88604007ebaSmrg
88704007ebaSmrg        /* convert from bits to dwords */
88804007ebaSmrg        srcpitch = ((pGeode->Pitch + 31) >> 5) << 2;
88904007ebaSmrg        gfx2_mono_bitmap_to_screen_blt(0, 0, CALC_FBOFFSET(gc2s.x, gc2s.y),
89004007ebaSmrg                                       gc2s.w, blt_height,
89104007ebaSmrg                                       pGeode->AccelColorExpandBuffers[0],
89204007ebaSmrg                                       srcpitch);
89304007ebaSmrg        gc2s.h -= blt_height;
89404007ebaSmrg        gc2s.y += blt_height;
89504007ebaSmrg#endif                          /* if GX_ONE_LINE_AT_A_TIME */
896f29dbc25Smrg    }
89704007ebaSmrg#else                           /* ifndef OPT_ACCEL */
898f29dbc25Smrg    {
899f29dbc25Smrg#if GX_ONE_LINE_AT_A_TIME
90004007ebaSmrg        unsigned int src =
90104007ebaSmrg            pGeode->AccelColorExpandBuffers[bufno] - pGeode->FBBase;
90204007ebaSmrg        unsigned int dst = CALC_FBOFFSET(gc2s.x, gc2s.y);
90304007ebaSmrg
90404007ebaSmrg        ++gc2s.y;
90504007ebaSmrg        GU2_WAIT_PENDING;
90604007ebaSmrg        WRITE_GP32(MGP_SRC_OFFSET, src);
90704007ebaSmrg        WRITE_GP32(MGP_DST_OFFSET, dst);
90804007ebaSmrg        WRITE_GP16(MGP_BLT_MODE, BLT_MODE);
90904007ebaSmrg#else                           /* if GX_ONE_LINE_AT_A_TIME */
91004007ebaSmrg        unsigned int dst, size;
91104007ebaSmrg        int blt_height;
91204007ebaSmrg
91304007ebaSmrg        GU2_WAIT_BUSY;
91404007ebaSmrg        if ((blt_height = pGeode->NoOfImgBuffers) > gc2s.h)
91504007ebaSmrg            blt_height = gc2s.h;
91604007ebaSmrg        if (++bufno < blt_height)
91704007ebaSmrg            return;
91804007ebaSmrg        dst = CALC_FBOFFSET(gc2s.x, gc2s.y);
91904007ebaSmrg        size = (gc2s.w << 16) | blt_height;
92004007ebaSmrg        gc2s.h -= blt_height;
92104007ebaSmrg        gc2s.y += blt_height;
92204007ebaSmrg        GU2_WAIT_PENDING;
92304007ebaSmrg        WRITE_GP32(MGP_DST_OFFSET, dst);
92404007ebaSmrg        WRITE_GP32(MGP_WID_HEIGHT, size);
92504007ebaSmrg        WRITE_GP16(MGP_BLT_MODE, BLT_MODE);
92604007ebaSmrg#endif                          /* if GX_ONE_LINE_AT_A_TIME */
927f29dbc25Smrg    }
92804007ebaSmrg#endif                          /* ifndef OPT_ACCEL */
929f29dbc25Smrg}
93004007ebaSmrg#endif                          /* GX_CPU2SCREXP_SUPPORT */
931f29dbc25Smrg
932f29dbc25Smrg#if GX_SCR2SCREXP_SUPPORT
933f29dbc25Smrg/*----------------------------------------------------------------------------
934f29dbc25Smrg * GXSetupForScreenToScreenColorExpandFill
935f29dbc25Smrg *
936f29dbc25Smrg * Description  :SetupFor/Subsequent ScreenToScreenColorExpandFill and
937f29dbc25Smrg *               ColorExpandScanline routines provide an interface for
938f29dbc25Smrg *               doing expansion blits from source patterns stored in
939f29dbc25Smrg *               video memory.
940f29dbc25Smrg *
941f29dbc25Smrg *    Arg        Type     Comment
942f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
943f29dbc25Smrg *     fg         int     foreground color
944f29dbc25Smrg *     bg         int     -1 (transparent) or background color
945f29dbc25Smrg *    rop         int     unmapped raster operation
946f29dbc25Smrg * planemask     uint     -1 (copy) or pattern data
947f29dbc25Smrg *
948f29dbc25Smrg * Returns      :none.
949f29dbc25Smrg *---------------------------------------------------------------------------*/
950f29dbc25Smrg
951f29dbc25Smrgstatic void
952f29dbc25SmrgGXSetupForScreenToScreenColorExpandFill(ScrnInfoPtr pScrni, int fg, int bg,
95304007ebaSmrg                                        int rop, uint planemask)
954f29dbc25Smrg{
955f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() fg %#x bg %#x rop %#x %#x\n",
95604007ebaSmrg                 __func__, fg, bg, rop, planemask));
957f29dbc25Smrg    rop &= 0x0F;
958f29dbc25Smrg#ifndef OPT_ACCEL
959f29dbc25Smrg    {
96004007ebaSmrg        GeodeRec *pGeode = GEODEPTR(pScrni);
961f29dbc25Smrg
96204007ebaSmrg        gfx_set_solid_pattern(planemask);
96304007ebaSmrg        gfx_set_mono_source(bg, fg, bg == -1 ? 1 : 0);
96404007ebaSmrg        gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
96504007ebaSmrg        gfx2_set_source_stride(pGeode->Pitch);
96604007ebaSmrg        gfx2_set_destination_stride(pGeode->Pitch);
967f29dbc25Smrg    }
968f29dbc25Smrg#else
969f29dbc25Smrg    {
97004007ebaSmrg        unsigned int ROP = BPP | (planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]);
97104007ebaSmrg
97204007ebaSmrg        if (bg == -1)
97304007ebaSmrg            ROP |= MGP_RM_SRC_TRANS;
97404007ebaSmrg        BLT_MODE = ((ROP ^ (ROP >> 1)) & 0x55) != 0 ?
97504007ebaSmrg            MGP_BM_SRC_MONO | MGP_BM_SRC_FB | MGP_BM_DST_REQ :
97604007ebaSmrg            MGP_BM_SRC_MONO | MGP_BM_SRC_FB;
97704007ebaSmrg        GU2_WAIT_PENDING;
97804007ebaSmrg        WRITE_GP32(MGP_RASTER_MODE, ROP);
97904007ebaSmrg        WRITE_GP32(MGP_PAT_COLOR_0, planemask);
98004007ebaSmrg        WRITE_GP32(MGP_SRC_COLOR_BG, bg);
98104007ebaSmrg        WRITE_GP32(MGP_SRC_COLOR_FG, fg);
98204007ebaSmrg        WRITE_GP32(MGP_STRIDE, ACCEL_STRIDE);
983f29dbc25Smrg    }
984f29dbc25Smrg#endif
985f29dbc25Smrg}
986f29dbc25Smrg
987f29dbc25Smrg/*----------------------------------------------------------------------------
988f29dbc25Smrg * GXSubsequentScreenToScreenColorExpandFill
989f29dbc25Smrg *
990f29dbc25Smrg * Description  :see GXSetupForScreenToScreenColorExpandFill
991f29dbc25Smrg *
992f29dbc25Smrg * Parameters:
993f29dbc25Smrg *    Arg        Type     Comment
994f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
995f29dbc25Smrg *     x          int     destination x offset
996f29dbc25Smrg *     y          int     destination y offset
997f29dbc25Smrg *     w          int     fill area width (pixels)
998f29dbc25Smrg *     h          int     fill area height (pixels)
999f29dbc25Smrg * offset         int     initial x offset
1000f29dbc25Smrg *
1001f29dbc25Smrg * Returns      :none
1002f29dbc25Smrg *
1003f29dbc25Smrg *---------------------------------------------------------------------------*/
1004f29dbc25Smrgstatic void
1005f29dbc25SmrgGXSubsequentScreenToScreenColorExpandFill(ScrnInfoPtr pScrni,
100604007ebaSmrg                                          int x, int y, int w, int h, int srcx,
100704007ebaSmrg                                          int srcy, int offset)
1008f29dbc25Smrg{
1009f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %dx%d %d,%d %d\n",
101004007ebaSmrg                 __func__, x, y, w, h, srcx, srcy, offset));
1011f29dbc25Smrg#ifndef OPT_ACCEL
1012f29dbc25Smrg    gfx2_mono_expand_blt(CALC_FBOFFSET(srcx, srcy), offset, 0,
101304007ebaSmrg                         CALC_FBOFFSET(x, y), w, h, 0);
1014f29dbc25Smrg#else
1015f29dbc25Smrg    {
101604007ebaSmrg        unsigned int src = (CALC_FBOFFSET(srcx,
101704007ebaSmrg                                          srcy) +
101804007ebaSmrg                            (offset >> 3)) | ((offset & 7) << 26);
101904007ebaSmrg        unsigned int dst = CALC_FBOFFSET(x, y);
102004007ebaSmrg        unsigned int size = (w << 16) | h;
102104007ebaSmrg
102204007ebaSmrg        GU2_WAIT_PENDING;
102304007ebaSmrg        WRITE_GP32(MGP_SRC_OFFSET, src);
102404007ebaSmrg        WRITE_GP32(MGP_DST_OFFSET, dst);
102504007ebaSmrg        WRITE_GP32(MGP_WID_HEIGHT, size);
102604007ebaSmrg        WRITE_GP16(MGP_BLT_MODE, BLT_MODE);
1027f29dbc25Smrg    }
1028f29dbc25Smrg#endif
1029f29dbc25Smrg}
103004007ebaSmrg#endif                          /* GX_SCR2SCREXP_SUPPORT */
1031f29dbc25Smrg
1032f29dbc25Smrg#define VM_MAJOR_DEC 0
1033f29dbc25Smrg#define VM_MINOR_DEC 0
1034f29dbc25Smrg
1035f29dbc25Smrgstatic unsigned short vmode[] = {
1036f29dbc25Smrg    VM_X_MAJOR | VM_MAJOR_INC | VM_MINOR_INC,
1037f29dbc25Smrg    /* !XDECREASING !YDECREASING !YMAJOR */
1038f29dbc25Smrg    VM_Y_MAJOR | VM_MAJOR_INC | VM_MINOR_INC,
1039f29dbc25Smrg    /* !XDECREASING !YDECREASING  YMAJOR */
1040f29dbc25Smrg    VM_X_MAJOR | VM_MAJOR_INC | VM_MINOR_DEC,
1041f29dbc25Smrg    /* !XDECREASING  YDECREASING !YMAJOR */
1042f29dbc25Smrg    VM_Y_MAJOR | VM_MAJOR_DEC | VM_MINOR_INC,
1043f29dbc25Smrg    /* !XDECREASING  YDECREASING  YMAJOR */
1044f29dbc25Smrg    VM_X_MAJOR | VM_MAJOR_DEC | VM_MINOR_INC,
1045f29dbc25Smrg    /*  XDECREASING !YDECREASING !YMAJOR */
1046f29dbc25Smrg    VM_Y_MAJOR | VM_MAJOR_INC | VM_MINOR_DEC,
1047f29dbc25Smrg    /*  XDECREASING !YDECREASING  YMAJOR */
1048f29dbc25Smrg    VM_X_MAJOR | VM_MAJOR_DEC | VM_MINOR_DEC,
1049f29dbc25Smrg    /*  XDECREASING  YDECREASING !YMAJOR */
1050f29dbc25Smrg    VM_Y_MAJOR | VM_MAJOR_DEC | VM_MINOR_DEC,
1051f29dbc25Smrg    /*  XDECREASING  YDECREASING  YMAJOR */
1052f29dbc25Smrg};
1053f29dbc25Smrg
1054f29dbc25Smrg#if GX_BRES_LINE_SUPPORT
1055f29dbc25Smrg/*----------------------------------------------------------------------------
1056f29dbc25Smrg * GXSetupForSolidLine
1057f29dbc25Smrg *
1058f29dbc25Smrg * Description  :SetupForSolidLine and Subsequent HorVertLine TwoPointLine
1059f29dbc25Smrg *               BresenhamLine provides an interface for drawing thin
1060f29dbc25Smrg *               solid lines.
1061f29dbc25Smrg *
1062f29dbc25Smrg *    Arg        Type     Comment
1063f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
1064f29dbc25Smrg *   color        int     foreground fill color
1065f29dbc25Smrg *    rop         int     unmapped raster op
1066f29dbc25Smrg * planemask     uint     -1 (fill) or pattern data (not enabled)
1067f29dbc25Smrg *
1068f29dbc25Smrg * Returns		:none
1069f29dbc25Smrg *---------------------------------------------------------------------------*/
1070f29dbc25Smrgstatic void
1071f29dbc25SmrgGXSetupForSolidLine(ScrnInfoPtr pScrni, int color, int rop, uint planemask)
1072f29dbc25Smrg{
1073f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %#x %#x %#x\n",
107404007ebaSmrg                 __func__, color, rop, planemask));
1075f29dbc25Smrg    rop &= 0x0F;
1076f29dbc25Smrg#ifndef OPT_ACCEL
1077f29dbc25Smrg    gfx_set_solid_pattern(color);
1078f29dbc25Smrg    gfx_set_raster_operation(planemask == ~0U ? PDfn[rop] :
107904007ebaSmrg                             (gfx_set_solid_source(planemask), PDfn_SM[rop]));
1080f29dbc25Smrg#else
1081f29dbc25Smrg    {
108204007ebaSmrg        unsigned int ROP = BPP | (planemask == ~0U ? PDfn[rop] : PDfn_SM[rop]);
108304007ebaSmrg
108404007ebaSmrg        BLT_MODE = ((ROP ^ (ROP >> 2)) & 0x33) == 0 ? MGP_BM_SRC_MONO : 0;
108504007ebaSmrg        VEC_MODE = ((ROP ^ (ROP >> 1)) & 0x55) != 0 ? ((BLT_MODE |=
108604007ebaSmrg                                                        MGP_BM_DST_REQ),
108704007ebaSmrg                                                       MGP_VM_DST_REQ) : 0;
108804007ebaSmrg        GU2_WAIT_PENDING;
108904007ebaSmrg        WRITE_GP32(MGP_RASTER_MODE, ROP);
109004007ebaSmrg        WRITE_GP32(MGP_PAT_COLOR_0, color);
109104007ebaSmrg        WRITE_GP32(MGP_SRC_COLOR_FG, planemask);
109204007ebaSmrg        WRITE_GP32(MGP_STRIDE, ACCEL_STRIDE);
1093f29dbc25Smrg    }
1094f29dbc25Smrg#endif
1095f29dbc25Smrg}
1096f29dbc25Smrg
1097f29dbc25Smrg/*---------------------------------------------------------------------------
1098f29dbc25Smrg * GXSubsequentSolidBresenhamLine
1099f29dbc25Smrg *
1100f29dbc25Smrg * Description  :see GXSetupForSolidLine
1101f29dbc25Smrg *
1102f29dbc25Smrg *    Arg        Type     Comment
1103f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
1104f29dbc25Smrg *     x1         int     destination x offset
1105f29dbc25Smrg *     y1         int     destination y offset
1106f29dbc25Smrg * absmaj         int     Bresenman absolute major
1107f29dbc25Smrg * absmin         int     Bresenman absolute minor
1108f29dbc25Smrg *    err         int     Bresenman initial error term
1109f29dbc25Smrg *    len         int     length of the vector (pixels)
1110f29dbc25Smrg * octant         int     specifies sign and magnitude relationships
1111f29dbc25Smrg *                         used to determine axis of magor rendering
1112f29dbc25Smrg *                         and direction of vector progress.
1113f29dbc25Smrg *
1114f29dbc25Smrg * Returns      :none
1115f29dbc25Smrg *
1116f29dbc25Smrg *   - Window outlines on window move.
1117f29dbc25Smrg *   - x11perf: line segments (-line500).
1118f29dbc25Smrg *   - x11perf: line segments (-seg500).
1119f29dbc25Smrg *---------------------------------------------------------------------------*/
1120f29dbc25Smrgstatic void
1121f29dbc25SmrgGXSubsequentSolidBresenhamLine(ScrnInfoPtr pScrni, int x1, int y1,
112204007ebaSmrg                               int absmaj, int absmin, int err, int len,
112304007ebaSmrg                               int octant)
1124f29dbc25Smrg{
1125f29dbc25Smrg    long axial, diagn;
1126f29dbc25Smrg
1127f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %d %d, %d %d, %d\n",
112804007ebaSmrg                 __func__, x1, y1, absmaj, absmin, err, len, octant));
1129f29dbc25Smrg    if (len <= 0)
113004007ebaSmrg        return;
1131f29dbc25Smrg    axial = absmin;
1132f29dbc25Smrg    err += axial;
1133f29dbc25Smrg    diagn = absmin - absmaj;
1134f29dbc25Smrg#ifndef OPT_ACCEL
1135f29dbc25Smrg    gfx_bresenham_line(x1, y1, len, err, axial, diagn, vmode[octant]);
1136f29dbc25Smrg#else
1137f29dbc25Smrg    {
113804007ebaSmrg        unsigned int offset = CALC_FBOFFSET(x1, y1);
113904007ebaSmrg        unsigned int vec_err = (axial << 16) | (unsigned short) diagn;
114004007ebaSmrg        unsigned int vec_len = (len << 16) | (unsigned short) err;
114104007ebaSmrg        unsigned int vec_mode = VEC_MODE | vmode[octant];
114204007ebaSmrg
114304007ebaSmrg        GU2_WAIT_PENDING;
114404007ebaSmrg        WRITE_GP32(MGP_DST_OFFSET, offset);
114504007ebaSmrg        WRITE_GP32(MGP_VEC_ERR, vec_err);
114604007ebaSmrg        WRITE_GP32(MGP_VEC_LEN, vec_len);
114704007ebaSmrg        WRITE_GP32(MGP_VECTOR_MODE, vec_mode);
1148f29dbc25Smrg    }
1149f29dbc25Smrg#endif
1150f29dbc25Smrg}
1151f29dbc25Smrg
1152f29dbc25Smrg/*---------------------------------------------------------------------------
1153f29dbc25Smrg * GXSubsequentSolidTwoPointLine
1154f29dbc25Smrg *
1155f29dbc25Smrg * Description  :see GXSetupForSolidLine
1156f29dbc25Smrg *
1157f29dbc25Smrg *    Arg        Type     Comment
1158f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
1159f29dbc25Smrg *     x0         int     destination x start offset
1160f29dbc25Smrg *     y0         int     destination y start offset
1161f29dbc25Smrg *     x1         int     destination x end offset
1162f29dbc25Smrg *     y1         int     destination y end offset
1163c744f008Smrg *  flags         int     OMIT_LAST, don't draw last pixel (not used)
1164f29dbc25Smrg *
1165f29dbc25Smrg * Returns      :none
1166f29dbc25Smrg *---------------------------------------------------------------------------*/
1167f29dbc25Smrgstatic void
1168f29dbc25SmrgGXSubsequentSolidTwoPointLine(ScrnInfoPtr pScrni, int x0, int y0,
116904007ebaSmrg                              int x1, int y1, int flags)
1170f29dbc25Smrg{
1171f29dbc25Smrg    long dx, dy, dmaj, dmin, octant, bias;
1172f29dbc25Smrg    long axial, diagn, err, len;
1173f29dbc25Smrg
1174f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %d,%d, %#x\n",
117504007ebaSmrg                 __func__, x0, y0, x1, y1, flags));
1176f29dbc25Smrg
1177f29dbc25Smrg    if ((dx = x1 - x0) < 0)
117804007ebaSmrg        dx = -dx;
1179f29dbc25Smrg    if ((dy = y1 - y0) < 0)
118004007ebaSmrg        dy = -dy;
1181f29dbc25Smrg    if (dy >= dx) {
118204007ebaSmrg        dmaj = dy;
118304007ebaSmrg        dmin = dx;
118404007ebaSmrg        octant = YMAJOR;
118504007ebaSmrg    }
118604007ebaSmrg    else {
118704007ebaSmrg        dmaj = dx;
118804007ebaSmrg        dmin = dy;
118904007ebaSmrg        octant = 0;
1190f29dbc25Smrg    }
1191f29dbc25Smrg    len = dmaj;
1192f29dbc25Smrg    if ((flags & OMIT_LAST) == 0)
119304007ebaSmrg        ++len;
1194f29dbc25Smrg    if (len <= 0)
119504007ebaSmrg        return;
1196f29dbc25Smrg    if (x1 < x0)
119704007ebaSmrg        octant |= XDECREASING;
1198f29dbc25Smrg    if (y1 < y0)
119904007ebaSmrg        octant |= YDECREASING;
1200f29dbc25Smrg
1201f29dbc25Smrg    axial = dmin << 1;
1202f29dbc25Smrg    bias = miGetZeroLineBias(pScrni->pScreen);
1203f29dbc25Smrg    err = axial - dmaj - ((bias >> octant) & 1);
1204f29dbc25Smrg    diagn = (dmin - dmaj) << 1;
1205f29dbc25Smrg
1206f29dbc25Smrg#ifndef OPT_ACCEL
1207f29dbc25Smrg    gfx_bresenham_line(x0, y0, len, err, axial, diagn, vmode[octant]);
1208f29dbc25Smrg#else
1209f29dbc25Smrg    {
121004007ebaSmrg        unsigned int offset = CALC_FBOFFSET(x0, y0);
121104007ebaSmrg        unsigned int vec_err = (axial << 16) | (unsigned short) diagn;
121204007ebaSmrg        unsigned int vec_len = (len << 16) | (unsigned short) err;
121304007ebaSmrg        unsigned int vec_mode = VEC_MODE | vmode[octant];
121404007ebaSmrg
121504007ebaSmrg        GU2_WAIT_PENDING;
121604007ebaSmrg        WRITE_GP32(MGP_DST_OFFSET, offset);
121704007ebaSmrg        WRITE_GP32(MGP_VEC_ERR, vec_err);
121804007ebaSmrg        WRITE_GP32(MGP_VEC_LEN, vec_len);
121904007ebaSmrg        WRITE_GP32(MGP_VECTOR_MODE, vec_mode);
1220f29dbc25Smrg    }
1221f29dbc25Smrg#endif
1222f29dbc25Smrg}
1223f29dbc25Smrg
1224f29dbc25Smrg/*---------------------------------------------------------------------------
1225f29dbc25Smrg * GXSubsequentSolidHorVertLine
1226f29dbc25Smrg *
1227f29dbc25Smrg * Description  :see GXSetupForSolidLine
1228f29dbc25Smrg *
1229f29dbc25Smrg *    Arg        Type     Comment
1230f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
1231f29dbc25Smrg *     x          int     destination x offset
1232f29dbc25Smrg *     y          int     destination y offset
1233f29dbc25Smrg *    len         int     length of the vector (pixels)
1234f29dbc25Smrg *    dir         int     DEGREES_270 or DEGREES_0 line direction
1235f29dbc25Smrg *
1236f29dbc25Smrg * Sample application uses:
1237f29dbc25Smrg *   - Window outlines on window move.
1238f29dbc25Smrg *   - x11perf: line segments (-hseg500).
1239f29dbc25Smrg *   - x11perf: line segments (-vseg500).
1240f29dbc25Smrg *---------------------------------------------------------------------------
1241f29dbc25Smrg */
1242f29dbc25Smrgstatic void
124304007ebaSmrgGXSubsequentSolidHorVertLine(ScrnInfoPtr pScrni, int x, int y, int len, int dir)
1244f29dbc25Smrg{
1245f29dbc25Smrg    DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %d %d\n", __func__, x, y, len, dir));
1246f29dbc25Smrg#ifndef OPT_ACCEL
1247f29dbc25Smrg    if (dir == DEGREES_0)
124804007ebaSmrg        gfx_pattern_fill(x, y, len, 1);
1249f29dbc25Smrg    else
125004007ebaSmrg        gfx_pattern_fill(x, y, 1, len);
1251f29dbc25Smrg#else
1252f29dbc25Smrg    {
125304007ebaSmrg        unsigned int offset = CALC_FBOFFSET(x, y);
125404007ebaSmrg        unsigned int size =
125504007ebaSmrg            dir == DEGREES_0 ? (len << 16) | 1 : (1 << 16) | len;
125604007ebaSmrg        GU2_WAIT_PENDING;
125704007ebaSmrg        WRITE_GP32(MGP_DST_OFFSET, offset);
125804007ebaSmrg        WRITE_GP32(MGP_WID_HEIGHT, size);
125904007ebaSmrg        WRITE_GP32(MGP_BLT_MODE, BLT_MODE);
1260f29dbc25Smrg    }
1261f29dbc25Smrg#endif
1262f29dbc25Smrg}
126304007ebaSmrg#endif                          /* GX_BRES_LINE_SUPPORT */
1264f29dbc25Smrg
1265f29dbc25Smrg#if GX_DASH_LINE_SUPPORT
1266f29dbc25Smrg/*----------------------------------------------------------------------------
1267f29dbc25Smrg * GXSetupForDashedLine
1268f29dbc25Smrg *
1269f29dbc25Smrg * Description  :SetupForDashedLine and Subsequent TwoPointLine
1270f29dbc25Smrg *               BresenhamLine provides an interface for drawing thin
1271f29dbc25Smrg *               dashed lines.
1272f29dbc25Smrg *
1273f29dbc25Smrg *    Arg        Type     Comment
1274f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
1275f29dbc25Smrg *     fg         int     foreground fill color
1276f29dbc25Smrg *     bg         int     -1 (transp) or background fill color
1277f29dbc25Smrg *    rop         int     unmapped raster op
1278f29dbc25Smrg * planemask     uint     -1 (fill) or pattern data (not enabled)
1279f29dbc25Smrg *  length        int     pattern length (bits)
1280f29dbc25Smrg * pattern     uchar*     dash pattern mask
1281f29dbc25Smrg *
1282f29dbc25Smrg * Returns              :none
1283f29dbc25Smrg *---------------------------------------------------------------------------*/
1284f29dbc25Smrgstatic void
1285f29dbc25SmrgGXSetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop,
128604007ebaSmrg                     unsigned int planemask, int length, unsigned char *pattern)
1287f29dbc25Smrg{
1288f29dbc25Smrg    int i, l, n, m;
1289f29dbc25Smrg    CARD32 pat = *pattern;
1290f29dbc25Smrg    CARD32 pat8x8[2];
1291f29dbc25Smrg
1292f29dbc25Smrg    if (length <= 0)
129304007ebaSmrg        return;
1294f29dbc25Smrg    i = l = m = 0;
1295f29dbc25Smrg    while (i < 2) {
129604007ebaSmrg        m |= pat >> l;
129704007ebaSmrg        l += length;
129804007ebaSmrg        if ((n = l - 32) >= 0) {
129904007ebaSmrg            pat8x8[i++] = m;
130004007ebaSmrg            m = pat << (length - n);
130104007ebaSmrg            l = n;
130204007ebaSmrg        }
1303f29dbc25Smrg    }
1304f29dbc25Smrg    gdln.pat[0] = pat8x8[0];
1305f29dbc25Smrg    gdln.pat[1] = pat8x8[1];
1306f29dbc25Smrg    gdln.len = length;
1307f29dbc25Smrg    gdln.fg = fg;
1308f29dbc25Smrg    gdln.bg = bg;
1309f29dbc25Smrg    rop &= 0x0F;
1310f29dbc25Smrg    gfx_set_solid_pattern(0);
1311f29dbc25Smrg    gfx_set_raster_operation(planemask == ~0U ? PDfn[rop] :
131204007ebaSmrg                             (gfx_set_solid_source(planemask), PDfn_SM[rop]));
1313f29dbc25Smrg}
1314f29dbc25Smrg
1315f29dbc25Smrg/*---------------------------------------------------------------------------
1316f29dbc25Smrg * GXSubsequentDashedBresenhamLine
1317f29dbc25Smrg *
1318f29dbc25Smrg * Description:		This function is used to render a vector using the
1319f29dbc25Smrg *                 	specified bresenham parameters.
1320f29dbc25Smrg *
1321f29dbc25Smrg * Parameters:
1322f29dbc25Smrg *		pScrni:		Screen handler pointer having screen information.
1323f29dbc25Smrg *      x1:  		Specifies the starting x position
1324c744f008Smrg *      y1:      	Specifies starting y position
1325c744f008Smrg *      absmaj:		Specifies the Bresenman absolute major.
1326c744f008Smrg *		absmin:		Specifies the Bresenman absolute minor.
1327f29dbc25Smrg *		err:     	Specifies the bresenham err term.
1328f29dbc25Smrg *		len:     	Specifies the length of the vector interms of pixels.
1329f29dbc25Smrg *		octant:  	not used in this function,may be added for standard
1330f29dbc25Smrg *               	interface.
1331f29dbc25Smrg *
1332f29dbc25Smrg * Returns:			none
1333f29dbc25Smrg *
1334f29dbc25Smrg * Comments:		none
1335f29dbc25Smrg *
1336f29dbc25Smrg * Sample application uses:
1337f29dbc25Smrg *   - Window outlines on window move.
1338f29dbc25Smrg *   - x11perf: line segments (-line500).
1339f29dbc25Smrg *   - x11perf: line segments (-seg500).
1340f29dbc25Smrg *----------------------------------------------------------------------------
1341f29dbc25Smrg */
1342f29dbc25Smrgstatic void
1343f29dbc25SmrgGXSubsequentDashedBresenhamLine(ScrnInfoPtr pScrni,
134404007ebaSmrg                                int x1, int y1, int absmaj, int absmin,
134504007ebaSmrg                                int err, int len, int octant, int phase)
1346f29dbc25Smrg{
1347f29dbc25Smrg    int i, n;
1348f29dbc25Smrg    int axial, diagn;
1349f29dbc25Smrg    int trans = (gdln.bg == -1);
1350f29dbc25Smrg    unsigned long pat8x8[2];
1351f29dbc25Smrg
1352f29dbc25Smrg    //ErrorF("BLine %d, %d, %d, %d, %d, %d, %d\n" x1, y1, absmaj, absmin,
1353f29dbc25Smrg    //err, len, octant);
1354f29dbc25Smrg
1355f29dbc25Smrg    i = phase >= 32 ? (phase -= 32, 1) : 0;
1356f29dbc25Smrg    n = 32 - phase;
1357f29dbc25Smrg    pat8x8[0] =
135804007ebaSmrg        ((gdln.pat[i] >> phase) & ((1UL << n) - 1)) | (gdln.pat[1 - i] << n);
1359f29dbc25Smrg    pat8x8[1] =
136004007ebaSmrg        ((gdln.pat[1 - i] >> phase) & ((1UL << n) - 1)) | (gdln.pat[i] << n);
1361f29dbc25Smrg    axial = absmin;
1362f29dbc25Smrg    err += axial;
1363f29dbc25Smrg    diagn = absmin - absmaj;
1364f29dbc25Smrg    gfx_set_mono_pattern(gdln.bg, gdln.fg, pat8x8[0], pat8x8[1], trans);
1365f29dbc25Smrg    gfx2_set_pattern_origin(x1, y1);
1366f29dbc25Smrg    gfx2_bresenham_line(CALC_FBOFFSET(x1, y1), len, err, axial, diagn,
136704007ebaSmrg                        vmode[octant]);
1368f29dbc25Smrg}
1369f29dbc25Smrg
1370f29dbc25Smrg/*---------------------------------------------------------------------------
1371f29dbc25Smrg * GXSubsequentDashedTwoPointLine
1372f29dbc25Smrg *
1373f29dbc25Smrg * Description  :see GXSetupForDashedLine
1374f29dbc25Smrg *
1375f29dbc25Smrg *    Arg        Type     Comment
1376f29dbc25Smrg *  pScrni   ScrnInfoPtr  pointer to Screeen info
1377f29dbc25Smrg *     x0         int     destination x start offset
1378f29dbc25Smrg *     y0         int     destination y start offset
1379f29dbc25Smrg *     x1         int     destination x end offset
1380f29dbc25Smrg *     y1         int     destination y end offset
1381c744f008Smrg *  flags         int     OMIT_LAST, don't draw last pixel (not used)
1382f29dbc25Smrg *  phase         int     initial pattern offset at x1,y1
1383f29dbc25Smrg *
1384f29dbc25Smrg * Returns      :none
1385f29dbc25Smrg *---------------------------------------------------------------------------*/
1386f29dbc25Smrgstatic void
1387f29dbc25SmrgGXSubsequentDashedTwoPointLine(ScrnInfoPtr pScrni, int x0, int y0,
138804007ebaSmrg                               int x1, int y1, int flags, int phase)
1389f29dbc25Smrg{
1390f29dbc25Smrg    int i, n;
1391f29dbc25Smrg    long dx, dy, dmaj, dmin, octant, bias;
1392f29dbc25Smrg    long axial, diagn, err, len, pat8x8[2];
1393f29dbc25Smrg
1394f29dbc25Smrg    //ErrorF("GXSubsequentDashedTwoPointLine() %d,%d %d,%d, %#x %d\n",
1395f29dbc25Smrg    //   x0, y0, x1, y1, flags, phase);
1396f29dbc25Smrg
1397f29dbc25Smrg    i = phase >= 32 ? (phase -= 32, 1) : 0;
1398f29dbc25Smrg    n = 32 - phase;
1399f29dbc25Smrg    pat8x8[0] =
140004007ebaSmrg        ((gdln.pat[i] >> phase) & ((1UL << n) - 1)) | (gdln.pat[1 - i] << n);
1401f29dbc25Smrg    pat8x8[1] =
140204007ebaSmrg        ((gdln.pat[1 - i] >> phase) & ((1UL << n) - 1)) | (gdln.pat[i] << n);
1403f29dbc25Smrg
1404f29dbc25Smrg    if ((dx = x1 - x0) < 0)
140504007ebaSmrg        dx = -dx;
1406f29dbc25Smrg    if ((dy = y1 - y0) < 0)
140704007ebaSmrg        dy = -dy;
1408f29dbc25Smrg    if (dy >= dx) {
140904007ebaSmrg        dmaj = dy;
141004007ebaSmrg        dmin = dx;
141104007ebaSmrg        octant = YMAJOR;
141204007ebaSmrg    }
141304007ebaSmrg    else {
141404007ebaSmrg        dmaj = dx;
141504007ebaSmrg        dmin = dy;
141604007ebaSmrg        octant = 0;
1417f29dbc25Smrg    }
1418f29dbc25Smrg    len = dmaj;
1419f29dbc25Smrg    if ((flags & OMIT_LAST) == 0)
142004007ebaSmrg        ++len;
1421f29dbc25Smrg    if (len <= 0)
142204007ebaSmrg        return;
1423f29dbc25Smrg    if (x1 < x0)
142404007ebaSmrg        octant |= XDECREASING;
1425f29dbc25Smrg    if (y1 < y0)
142604007ebaSmrg        octant |= YDECREASING;
1427f29dbc25Smrg
1428f29dbc25Smrg    axial = dmin << 1;
1429f29dbc25Smrg    bias = miGetZeroLineBias(pScrni->pScreen);
1430f29dbc25Smrg    err = axial - dmaj - ((bias >> octant) & 1);
1431f29dbc25Smrg    diagn = (dmin - dmaj) << 1;
1432f29dbc25Smrg
1433f29dbc25Smrg    gfx2_set_pattern_origin(x0, y0);
1434f29dbc25Smrg    gfx2_bresenham_line(CALC_FBOFFSET(x0, y0), len, err, axial, diagn,
143504007ebaSmrg                        vmode[octant]);
1436f29dbc25Smrg
1437f29dbc25Smrg}
143804007ebaSmrg#endif                          /* GX_DASH_LINE_SUPPORT */
1439f29dbc25Smrg
1440f29dbc25Smrg#if GX_WRITE_PIXMAP_SUPPORT
1441f29dbc25Smrgstatic void
1442f29dbc25SmrgGXWritePixmap(ScrnInfoPtr pScrni, int x, int y, int w, int h,
144304007ebaSmrg              unsigned char *src, int srcwidth, int rop, unsigned int planemask,
144404007ebaSmrg              int trans, int bpp, int depth)
1445f29dbc25Smrg{
1446f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR(pScrni);
1447f29dbc25Smrg
1448f29dbc25Smrg    //ErrorF("GXWritePixmap() %d,%d %dx%d, s%#x sp%d %#x %#x %#x %d %d\n",
1449f29dbc25Smrg    //    x, y, w, h, src, srcwidth, rop, planemask, trans, bpp, depth);
1450f29dbc25Smrg
1451f29dbc25Smrg    if (bpp == pScrni->bitsPerPixel) {
145204007ebaSmrg        rop &= 0x0F;
145304007ebaSmrg        if (rop == GXcopy && trans == -1) {
145404007ebaSmrg            gfx_wait_until_idle();
145504007ebaSmrg            geode_memory_to_screen_blt((unsigned long) src,
145604007ebaSmrg                                       (unsigned long) FBADDR(x, y), srcwidth,
145704007ebaSmrg                                       pGeode->Pitch, w, h, bpp);
145804007ebaSmrg        }
145904007ebaSmrg        else {
146004007ebaSmrg            gfx_set_solid_pattern(planemask);
146104007ebaSmrg            gfx_set_raster_operation(planemask ==
146204007ebaSmrg                                     ~0U ? SDfn[rop] : SDfn_PM[rop]);
146304007ebaSmrg            if (trans != -1)
146404007ebaSmrg                gfx_color_bitmap_to_screen_xblt(0, 0, x, y, w, h, src,
146504007ebaSmrg                                                srcwidth, trans);
146604007ebaSmrg            else
146704007ebaSmrg                gfx_color_bitmap_to_screen_blt(0, 0, x, y, w, h, src, srcwidth);
146804007ebaSmrg            SET_SYNC_FLAG(pGeode->AccelInfoRec);
146904007ebaSmrg        }
147004007ebaSmrg    }
147104007ebaSmrg    else
147204007ebaSmrg        pGeode->WritePixmap(pScrni, x, y, w, h, src, srcwidth, rop, planemask,
147304007ebaSmrg                            trans, bpp, depth);
1474f29dbc25Smrg}
147504007ebaSmrg#endif                          /* if GX_WRITE_PIXMAP_SUPPORT */
1476f29dbc25Smrg
1477f29dbc25Smrg#if XF86EXA
1478f29dbc25Smrg
1479f29dbc25Smrgstatic void
1480f29dbc25Smrgamd_gx_exa_WaitMarker(ScreenPtr pScreen, int Marker)
1481f29dbc25Smrg{
1482f29dbc25Smrg    GU2_WAIT_BUSY;
1483f29dbc25Smrg}
1484f29dbc25Smrg
1485f29dbc25Smrgstatic void
1486f29dbc25Smrgamd_gx_exa_Done(PixmapPtr p)
1487f29dbc25Smrg{
1488f29dbc25Smrg}
1489f29dbc25Smrg
1490f29dbc25Smrgstatic Bool
1491f29dbc25Smrgamd_gx_exa_UploadToScreen(PixmapPtr pDst, int x, int y, int w, int h,
149204007ebaSmrg                          char *src, int src_pitch)
1493f29dbc25Smrg{
149444802259Smrg    GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pDst);
149544802259Smrg    char *dst = pGeode->pExa->memoryBase + exaGetPixmapOffset(pDst);
1496f29dbc25Smrg    int dst_pitch = exaGetPixmapPitch(pDst);
1497f29dbc25Smrg    int bpp = pDst->drawable.bitsPerPixel;
1498f29dbc25Smrg
1499f29dbc25Smrg    dst += y * dst_pitch + x * (bpp >> 3);
1500f29dbc25Smrg    GU2_WAIT_BUSY;
150104007ebaSmrg    geode_memory_to_screen_blt((unsigned long) src, (unsigned long) dst,
150204007ebaSmrg                               src_pitch, dst_pitch, w, h, bpp);
1503f29dbc25Smrg    return TRUE;
1504f29dbc25Smrg}
1505f29dbc25Smrg
1506f29dbc25Smrgstatic Bool
1507f29dbc25Smrgamd_gx_exa_DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h,
150804007ebaSmrg                              char *dst, int dst_pitch)
1509f29dbc25Smrg{
151044802259Smrg    GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pSrc);
151144802259Smrg    char *src = pGeode->pExa->memoryBase + exaGetPixmapOffset(pSrc);
1512f29dbc25Smrg    int src_pitch = exaGetPixmapPitch(pSrc);
1513f29dbc25Smrg    int bpp = pSrc->drawable.bitsPerPixel;
1514f29dbc25Smrg
1515f29dbc25Smrg    src += (y * src_pitch) + (x * (bpp >> 3));
1516f29dbc25Smrg    GU2_WAIT_BUSY;
151704007ebaSmrg    geode_memory_to_screen_blt((unsigned long) src, (unsigned long) dst,
151804007ebaSmrg                               src_pitch, dst_pitch, w, h, bpp);
1519f29dbc25Smrg    return TRUE;
1520f29dbc25Smrg}
1521f29dbc25Smrg
1522f29dbc25Smrg/* Solid */
1523f29dbc25Smrg
1524f29dbc25Smrgstatic Bool
1525f29dbc25Smrgamd_gx_exa_PrepareSolid(PixmapPtr pxMap, int alu, Pixel planemask, Pixel fg)
1526f29dbc25Smrg{
1527f29dbc25Smrg    int dstPitch = exaGetPixmapPitch(pxMap);
1528f29dbc25Smrg    unsigned int ROP = amd_gx_BppToRasterMode(pxMap->drawable.bitsPerPixel)
152904007ebaSmrg        | (planemask == ~0U ? SDfn[alu] : SDfn_PM[alu]);
1530f29dbc25Smrg
1531f29dbc25Smrg    //  FIXME: this should go away -- workaround for the blockparty icon corruption
1532f29dbc25Smrg    //if (pxMap->drawable.bitsPerPixel == 32)
1533f29dbc25Smrg    //  return FALSE;
1534f29dbc25Smrg
1535f29dbc25Smrg    BLT_MODE = ((ROP ^ (ROP >> 2)) & 0x33) == 0 ? MGP_BM_SRC_MONO : 0;
1536f29dbc25Smrg    if (((ROP ^ (ROP >> 1)) & 0x55) != 0)
153704007ebaSmrg        BLT_MODE |= MGP_BM_DST_REQ;
1538f29dbc25Smrg    //ErrorF("amd_gx_exa_PrepareSolid(%#x,%#x,%#x - ROP=%x,BLT_MODE=%x)\n", alu, planemask, fg, ROP, BLT_MODE);
1539f29dbc25Smrg    GU2_WAIT_PENDING;
1540f29dbc25Smrg    WRITE_GP32(MGP_RASTER_MODE, ROP);
1541f29dbc25Smrg    WRITE_GP32(MGP_PAT_COLOR_0, planemask);
1542f29dbc25Smrg    WRITE_GP32(MGP_SRC_COLOR_FG, fg);
1543f29dbc25Smrg    WRITE_GP32(MGP_STRIDE, dstPitch);
1544f29dbc25Smrg    return TRUE;
1545f29dbc25Smrg}
1546f29dbc25Smrg
1547f29dbc25Smrgstatic void
1548f29dbc25Smrgamd_gx_exa_Solid(PixmapPtr pxMap, int x1, int y1, int x2, int y2)
1549f29dbc25Smrg{
1550f29dbc25Smrg    int bpp = (pxMap->drawable.bitsPerPixel + 7) / 8;
1551f29dbc25Smrg    int pitch = exaGetPixmapPitch(pxMap);
1552f29dbc25Smrg    unsigned int offset = exaGetPixmapOffset(pxMap) + pitch * y1 + bpp * x1;
1553f29dbc25Smrg    unsigned int size = ((x2 - x1) << 16) | (y2 - y1);
1554f29dbc25Smrg
1555f29dbc25Smrg    //ErrorF("amd_gx_exa_Solid() at %d,%d %d,%d - offset=%d, bpp=%d\n", x1, y1, x2, y2, offset, bpp);
1556f29dbc25Smrg
1557f29dbc25Smrg    GU2_WAIT_PENDING;
1558f29dbc25Smrg    WRITE_GP32(MGP_DST_OFFSET, offset);
1559f29dbc25Smrg    WRITE_GP32(MGP_WID_HEIGHT, size);
1560f29dbc25Smrg    WRITE_GP32(MGP_BLT_MODE, BLT_MODE);
1561f29dbc25Smrg}
1562f29dbc25Smrg
1563f29dbc25Smrg/* Copy */
1564f29dbc25Smrg
1565f29dbc25Smrgstatic Bool
1566f29dbc25Smrgamd_gx_exa_PrepareCopy(PixmapPtr pxSrc, PixmapPtr pxDst, int dx, int dy,
156704007ebaSmrg                       int alu, Pixel planemask)
1568f29dbc25Smrg{
1569f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst);
1570f29dbc25Smrg    int dstPitch = exaGetPixmapPitch(pxDst);
1571f29dbc25Smrg    unsigned int ROP;
1572f29dbc25Smrg
1573f29dbc25Smrg    /* Punt if the color formats aren't the same */
1574f29dbc25Smrg
1575f29dbc25Smrg    if (pxSrc->drawable.bitsPerPixel != pxDst->drawable.bitsPerPixel)
157604007ebaSmrg        return FALSE;
1577f29dbc25Smrg
1578f29dbc25Smrg    //ErrorF("amd_gx_exa_PrepareCopy() dx%d dy%d alu %#x %#x\n",
1579f29dbc25Smrg    //  dx, dy, alu, planemask);
1580f29dbc25Smrg
1581f29dbc25Smrg    pGeode->cpySrcOffset = exaGetPixmapOffset(pxSrc);
1582f29dbc25Smrg    pGeode->cpySrcPitch = exaGetPixmapPitch(pxSrc);
1583f29dbc25Smrg    pGeode->cpySrcBpp = (pxSrc->drawable.bitsPerPixel + 7) / 8;
1584f29dbc25Smrg    pGeode->cpyDx = dx;
1585f29dbc25Smrg    pGeode->cpyDy = dy;
1586f29dbc25Smrg    ROP = amd_gx_BppToRasterMode(pxSrc->drawable.bitsPerPixel) |
158704007ebaSmrg        (planemask == ~0U ? SDfn[alu] : SDfn_PM[alu]);
1588f29dbc25Smrg
1589f29dbc25Smrg    BLT_MODE = ((ROP ^ (ROP >> 1)) & 0x55) != 0 ?
159004007ebaSmrg        MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
1591f29dbc25Smrg    GU2_WAIT_PENDING;
1592f29dbc25Smrg    WRITE_GP32(MGP_RASTER_MODE, ROP);
1593f29dbc25Smrg    WRITE_GP32(MGP_PAT_COLOR_0, planemask);
1594f29dbc25Smrg    WRITE_GP32(MGP_SRC_COLOR_FG, ~0);
1595f29dbc25Smrg    WRITE_GP32(MGP_SRC_COLOR_BG, ~0);
1596f29dbc25Smrg    WRITE_GP32(MGP_STRIDE, (pGeode->cpySrcPitch << 16) | dstPitch);
1597f29dbc25Smrg    return TRUE;
1598f29dbc25Smrg}
1599f29dbc25Smrg
1600f29dbc25Smrgstatic void
1601f29dbc25Smrgamd_gx_exa_Copy(PixmapPtr pxDst, int srcX, int srcY, int dstX, int dstY,
160204007ebaSmrg                int w, int h)
1603f29dbc25Smrg{
1604f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst);
1605f29dbc25Smrg    int dstBpp = (pxDst->drawable.bitsPerPixel + 7) / 8;
1606f29dbc25Smrg    int dstPitch = exaGetPixmapPitch(pxDst);
1607f29dbc25Smrg    unsigned int srcOffset =
160804007ebaSmrg        pGeode->cpySrcOffset + (pGeode->cpySrcPitch * srcY) +
160904007ebaSmrg        (pGeode->cpySrcBpp * srcX);
1610f29dbc25Smrg    unsigned int dstOffset =
161104007ebaSmrg        exaGetPixmapOffset(pxDst) + (dstPitch * dstY) + (dstBpp * dstX);
1612f29dbc25Smrg    unsigned int size = (w << 16) | h;
1613f29dbc25Smrg    unsigned int blt_mode = BLT_MODE;
1614f29dbc25Smrg
1615f29dbc25Smrg    //ErrorF("amd_gx_exa_Copy() from %d,%d to %d,%d %dx%d\n", srcX, srcY,
1616f29dbc25Smrg    //   dstX, dstY, w, h);
1617f29dbc25Smrg
1618f29dbc25Smrg    if (pGeode->cpyDx < 0) {
161904007ebaSmrg        srcOffset += w * pGeode->cpySrcBpp - 1;
162004007ebaSmrg        dstOffset += w * dstBpp - 1;
162104007ebaSmrg        blt_mode |= MGP_BM_NEG_XDIR;
1622f29dbc25Smrg    }
1623f29dbc25Smrg    if (pGeode->cpyDy < 0) {
162404007ebaSmrg        srcOffset += (h - 1) * pGeode->cpySrcPitch;
162504007ebaSmrg        dstOffset += (h - 1) * dstPitch;
162604007ebaSmrg        blt_mode |= MGP_BM_NEG_YDIR;
1627f29dbc25Smrg    }
1628f29dbc25Smrg    GU2_WAIT_PENDING;
1629f29dbc25Smrg    WRITE_GP32(MGP_SRC_OFFSET, srcOffset);
1630f29dbc25Smrg    WRITE_GP32(MGP_DST_OFFSET, dstOffset);
1631f29dbc25Smrg    WRITE_GP32(MGP_WID_HEIGHT, size);
1632f29dbc25Smrg    WRITE_GP16(MGP_BLT_MODE, blt_mode);
1633f29dbc25Smrg}
1634f29dbc25Smrg
1635f29dbc25Smrg/* A=SRC, B=DST */
1636f29dbc25Smrg#define SRC_DST 0
1637f29dbc25Smrg/* B=SRC, A=DST */
1638f29dbc25Smrg#define DST_SRC MGP_RM_DEST_FROM_CHAN_A
1639f29dbc25Smrg/* A*alpha + B*0         */
1640f29dbc25Smrg#define Aa_B0   MGP_RM_ALPHA_TIMES_A
1641f29dbc25Smrg/* A*0     + B*(1-alpha) */
1642f29dbc25Smrg#define A0_B1a  MGP_RM_BETA_TIMES_B
1643f29dbc25Smrg/* A*1     + B*(1-alpha) */
1644f29dbc25Smrg#define A1_B1a  MGP_RM_A_PLUS_BETA_B
1645f29dbc25Smrg/* A*alpha + B*(1-alpha) */
1646f29dbc25Smrg#define Aa_B1a  MGP_RM_ALPHA_A_PLUS_BETA_B
1647f29dbc25Smrg/* alpha from A */
1648f29dbc25Smrg#define a_A MGP_RM_SELECT_ALPHA_A
1649f29dbc25Smrg/* alpha from B */
1650f29dbc25Smrg#define a_B MGP_RM_SELECT_ALPHA_B
1651f29dbc25Smrg/* alpha from const */
1652f29dbc25Smrg#define a_C MGP_RM_SELECT_ALPHA_R
1653f29dbc25Smrg/* alpha = 1 */
1654f29dbc25Smrg#define a_1 MGP_RM_SELECT_ALPHA_1
1655f29dbc25Smrg
1656f29dbc25Smrg#define MGP_RM_ALPHA_TO_ARGB (MGP_RM_ALPHA_TO_ALPHA | MGP_RM_ALPHA_TO_RGB)
165704007ebaSmrg#define gxPictOpMAX PictOpAdd   /* highest accelerated op */
1658f29dbc25Smrg
1659f29dbc25Smrgunsigned int amd_gx_exa_alpha_ops[] =
1660f29dbc25Smrg/*    A   B      OP     AS           const = 0 */
1661f29dbc25Smrg{
166204007ebaSmrg    (SRC_DST | Aa_B0 | a_C), 0, /* clear    (src*0) */
166304007ebaSmrg    (SRC_DST | Aa_B0 | a_1), 0, /* src      (src*1) */
166404007ebaSmrg    (DST_SRC | Aa_B0 | a_1), 0, /* dst      (dst*1) */
166504007ebaSmrg    (SRC_DST | A1_B1a | a_A), 0,        /* src-over (src*1 + dst(1-A)) */
166604007ebaSmrg    (DST_SRC | A1_B1a | a_A), 0,        /* dst-over (dst*1 + src(1-B)) */
166704007ebaSmrg    (SRC_DST | Aa_B0 | a_B), 0, /* src-in   (src*B) */
166804007ebaSmrg    (DST_SRC | Aa_B0 | a_B), 0, /* dst-in   (dst*A) */
166904007ebaSmrg    (DST_SRC | A0_B1a | a_A), 0,        /* src-out  (src*(1-B)) */
167004007ebaSmrg    (SRC_DST | A0_B1a | a_A), 0,        /* dst-out  (dst*(1-A)) */
1671f29dbc25Smrg/* pass1 (SRC=dst DST=scr=src), pass2 (SRC=src, DST=dst) */
167204007ebaSmrg    (DST_SRC | Aa_B0 | a_B),    /* srcatop  (src*B) */
167304007ebaSmrg    (SRC_DST | A0_B1a | a_A),   /*                  + (dst(1-A)) */
167404007ebaSmrg    (SRC_DST | Aa_B0 | a_B),    /* dstatop  (dst*A) */
167504007ebaSmrg    (DST_SRC | A0_B1a | a_A),   /*                  + (src(1-B) */
167604007ebaSmrg    (SRC_DST | A0_B1a | a_A),   /* xor      (src*(1-B) */
167704007ebaSmrg    (SRC_DST | A0_B1a | a_A),   /*                  + (dst(1-A) */
167804007ebaSmrg    (SRC_DST | A1_B1a | a_C), 0,        /* add      (src*1 + dst*1) */
1679f29dbc25Smrg};
1680f29dbc25Smrg
168104007ebaSmrgtypedef struct {
1682f29dbc25Smrg    int exa_fmt;
1683f29dbc25Smrg    int bpp;
1684f29dbc25Smrg    int gx_fmt;
1685f29dbc25Smrg    int alpha_bits;
1686f29dbc25Smrg} amd_gx_exa_fmt_t;
1687f29dbc25Smrg
1688f29dbc25Smrgamd_gx_exa_fmt_t amd_gx_exa_fmts[] = {
1689f29dbc25Smrg    {PICT_a8r8g8b8, 32, MGP_RM_BPPFMT_8888, 8},
1690f29dbc25Smrg    {PICT_x8r8g8b8, 32, MGP_RM_BPPFMT_8888, 0},
1691f29dbc25Smrg    {PICT_a4r4g4b4, 16, MGP_RM_BPPFMT_4444, 4},
1692f29dbc25Smrg    {PICT_a1r5g5b5, 16, MGP_RM_BPPFMT_1555, 1},
1693f29dbc25Smrg    {PICT_r5g6b5, 16, MGP_RM_BPPFMT_565, 0},
1694f29dbc25Smrg    {PICT_r3g3b2, 8, MGP_RM_BPPFMT_332, 0},
1695f29dbc25Smrg};
1696f29dbc25Smrg
1697f29dbc25Smrgstatic amd_gx_exa_fmt_t *
1698f29dbc25Smrgamd_gx_exa_check_format(PicturePtr p)
1699f29dbc25Smrg{
1700f29dbc25Smrg    int i;
1701f29dbc25Smrg    int bpp = p->pDrawable ? p->pDrawable->bitsPerPixel : 0;
1702f29dbc25Smrg    amd_gx_exa_fmt_t *fp = &amd_gx_exa_fmts[0];
1703f29dbc25Smrg
1704f29dbc25Smrg    for (i = sizeof(amd_gx_exa_fmts) / sizeof(amd_gx_exa_fmts[0]); --i >= 0;
170504007ebaSmrg         ++fp) {
170604007ebaSmrg        if (fp->bpp < bpp)
170704007ebaSmrg            return NULL;
170804007ebaSmrg        if (fp->bpp != bpp)
170904007ebaSmrg            continue;
171004007ebaSmrg        if (fp->exa_fmt == p->format)
171104007ebaSmrg            break;
1712f29dbc25Smrg    }
1713f29dbc25Smrg    return i < 0 ? NULL : fp;
1714f29dbc25Smrg}
1715f29dbc25Smrg
1716f29dbc25Smrg/* Composite */
1717f29dbc25Smrg
1718f29dbc25Smrgstatic Bool
1719f29dbc25Smrgamd_gx_exa_CheckComposite(int op, PicturePtr pSrc, PicturePtr pMsk,
172004007ebaSmrg                          PicturePtr pDst)
1721f29dbc25Smrg{
1722f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR_FROM_PICTURE(pDst);
1723f29dbc25Smrg
1724f29dbc25Smrg    if (op > gxPictOpMAX)
172504007ebaSmrg        return FALSE;
1726f29dbc25Smrg    if (pMsk)
172704007ebaSmrg        return FALSE;
1728f29dbc25Smrg    if (usesPasses(op) && pGeode->exaBfrSz == 0)
172904007ebaSmrg        return FALSE;
1730f29dbc25Smrg    if (pSrc->filter != PictFilterNearest &&
173104007ebaSmrg        pSrc->filter != PictFilterFast &&
173204007ebaSmrg        pSrc->filter != PictFilterGood && pSrc->filter != PictFilterBest)
173304007ebaSmrg        return FALSE;
1734f29dbc25Smrg    if (pSrc->repeat)
173504007ebaSmrg        return FALSE;
1736f29dbc25Smrg    if (pSrc->transform)
173704007ebaSmrg        return FALSE;
1738f29dbc25Smrg    return TRUE;
1739f29dbc25Smrg}
1740f29dbc25Smrg
1741f29dbc25Smrgstatic Bool
1742f29dbc25Smrgamd_gx_exa_PrepareComposite(int op, PicturePtr pSrc, PicturePtr pMsk,
174304007ebaSmrg                            PicturePtr pDst, PixmapPtr pxSrc, PixmapPtr pxMsk,
174404007ebaSmrg                            PixmapPtr pxDst)
1745f29dbc25Smrg{
1746f29dbc25Smrg    int srcPitch;
174744802259Smrg    if (!pxSrc || !pSrc->pDrawable) return FALSE;
1748f29dbc25Smrg
1749f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst);
1750f29dbc25Smrg    amd_gx_exa_fmt_t *sfp, *dfp;
1751f29dbc25Smrg
1752f29dbc25Smrg    //ErrorF("amd_gx_exa_PrepareComposite()\n");
1753f29dbc25Smrg
1754f29dbc25Smrg    if ((sfp = amd_gx_exa_check_format(pSrc)) == NULL)
175504007ebaSmrg        return FALSE;
1756f29dbc25Smrg    if (sfp->alpha_bits == 0 && usesSrcAlpha(op))
175704007ebaSmrg        return FALSE;
1758f29dbc25Smrg    if ((dfp = amd_gx_exa_check_format(pDst)) == NULL)
175904007ebaSmrg        return FALSE;
1760f29dbc25Smrg    if (dfp->alpha_bits == 0 && usesDstAlpha(op))
176104007ebaSmrg        return FALSE;
1762f29dbc25Smrg    if (sfp->gx_fmt != dfp->gx_fmt)
176304007ebaSmrg        return FALSE;
1764f29dbc25Smrg    srcPitch = exaGetPixmapPitch(pxSrc);
1765f29dbc25Smrg    if (usesPasses(op) && srcPitch > pGeode->exaBfrSz)
176604007ebaSmrg        return FALSE;
1767f29dbc25Smrg    pGeode->cmpSrcPitch = srcPitch;
1768f29dbc25Smrg    pGeode->cmpOp = op;
1769f29dbc25Smrg    pGeode->cmpSrcOffset = exaGetPixmapOffset(pxSrc);
1770f29dbc25Smrg    pGeode->cmpSrcBpp = (pxSrc->drawable.bitsPerPixel + 7) / 8;
1771f29dbc25Smrg    pGeode->cmpSrcFmt = sfp->gx_fmt;
1772f29dbc25Smrg    pGeode->cmpDstFmt = dfp->gx_fmt | (dfp->alpha_bits == 0 ?
177304007ebaSmrg                                       MGP_RM_ALPHA_TO_RGB :
177404007ebaSmrg                                       MGP_RM_ALPHA_TO_ARGB);
1775f29dbc25Smrg    return TRUE;
1776f29dbc25Smrg}
1777f29dbc25Smrg
1778f29dbc25Smrgstatic void
1779f29dbc25Smrgamd_gx_exa_Composite(PixmapPtr pxDst, int srcX, int srcY, int maskX,
178004007ebaSmrg                     int maskY, int dstX, int dstY, int width, int height)
1781f29dbc25Smrg{
1782f29dbc25Smrg    int op, current_line, max_lines, lines, pass, scratchPitch;
1783f29dbc25Smrg    unsigned int srcOffset, srcOfs = 0, srcPitch, srcPch = 0, srcBpp;
1784f29dbc25Smrg    unsigned int dstOffset, dstOfs = 0, dstPitch, dstPch = 0, dstBpp;
1785f29dbc25Smrg    unsigned int sizes, strides, blt_mode = 0, rop = 0;
1786f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst);
1787f29dbc25Smrg
1788f29dbc25Smrg    //ErrorF("amd_gx_exa_Composite() from %d,%d to %d,%d %dx%d\n",
1789f29dbc25Smrg    //    srcX, srcY, dstX, dstY, width, height);
1790f29dbc25Smrg
1791f29dbc25Smrg    op = pGeode->cmpOp;
1792f29dbc25Smrg    if (usesPasses(op)) {
179304007ebaSmrg        int cacheLineSz = 32;
179404007ebaSmrg        int cachelines =
179504007ebaSmrg            (width * pGeode->cmpSrcBpp + cacheLineSz - 1) / cacheLineSz;
179604007ebaSmrg        scratchPitch = cachelines * cacheLineSz;
179704007ebaSmrg        if (scratchPitch > pGeode->cmpSrcPitch)
179804007ebaSmrg            scratchPitch = pGeode->cmpSrcPitch;
179904007ebaSmrg        max_lines = pGeode->exaBfrSz / scratchPitch;
180004007ebaSmrg    }
180104007ebaSmrg    else {
180204007ebaSmrg        scratchPitch = 0;
180304007ebaSmrg        max_lines = height;
1804f29dbc25Smrg    }
1805f29dbc25Smrg
1806f29dbc25Smrg    dstBpp = (pxDst->drawable.bitsPerPixel + 7) / 8;
1807f29dbc25Smrg    dstPitch = exaGetPixmapPitch(pxDst);
1808f29dbc25Smrg    dstOffset = exaGetPixmapOffset(pxDst) + dstPitch * dstY + dstBpp * dstX;
1809f29dbc25Smrg    srcBpp = pGeode->cmpSrcBpp;
1810f29dbc25Smrg    srcPitch = pGeode->cmpSrcPitch;
1811f29dbc25Smrg    srcOffset = pGeode->cmpSrcOffset + srcPitch * srcY + srcBpp * srcX;
1812f29dbc25Smrg
1813f29dbc25Smrg    current_line = pass = 0;
1814f29dbc25Smrg    while (current_line < height) {
181504007ebaSmrg        if (usesPasses(op)) {
181604007ebaSmrg            lines = height - current_line;
181704007ebaSmrg            if (lines > max_lines)
181804007ebaSmrg                lines = max_lines;
181904007ebaSmrg            switch (pass) {
182004007ebaSmrg            case 0:            /* copy src to scratch */
182104007ebaSmrg                srcPch = srcPitch;
182204007ebaSmrg                srcOfs = srcOffset + current_line * srcPch;
182304007ebaSmrg                dstPch = scratchPitch;
182404007ebaSmrg                dstOfs = pGeode->exaBfrOffset;
182504007ebaSmrg                rop = pGeode->cmpSrcFmt | MGP_RM_ALPHA_TO_ARGB;
182604007ebaSmrg                rop |= amd_gx_exa_alpha_ops[PictOpSrc * 2];
182704007ebaSmrg                blt_mode = usesChanB0(PictOpSrc) ?
182804007ebaSmrg                    MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
182904007ebaSmrg                ++pass;
183004007ebaSmrg                break;
183104007ebaSmrg            case 1:            /* pass1 */
183204007ebaSmrg                srcPch = dstPitch;
183304007ebaSmrg                srcOfs = dstOffset + current_line * srcPch;
183404007ebaSmrg                dstPch = scratchPitch;
183504007ebaSmrg                dstOfs = pGeode->exaBfrOffset;
183604007ebaSmrg                rop = pGeode->cmpSrcFmt | MGP_RM_ALPHA_TO_ARGB;
183704007ebaSmrg                rop |= amd_gx_exa_alpha_ops[op * 2];
183804007ebaSmrg                blt_mode = usesChanB1(op) ?
183904007ebaSmrg                    MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
184004007ebaSmrg                ++pass;
184104007ebaSmrg                break;
184204007ebaSmrg            case 2:            /* pass2 */
184304007ebaSmrg                srcPch = srcPitch;
184404007ebaSmrg                srcOfs = srcOffset + current_line * srcPch;
184504007ebaSmrg                dstPch = dstPitch;
184604007ebaSmrg                dstOfs = dstOffset + current_line * dstPch;
184704007ebaSmrg                rop = pGeode->cmpSrcFmt | MGP_RM_ALPHA_TO_ARGB;
184804007ebaSmrg                rop |= amd_gx_exa_alpha_ops[op * 2 + 1];
184904007ebaSmrg                blt_mode = usesChanB2(op) ?
185004007ebaSmrg                    MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
185104007ebaSmrg                ++pass;
185204007ebaSmrg                break;
185304007ebaSmrg            case 3:            /* add */
185404007ebaSmrg                srcPch = scratchPitch;
185504007ebaSmrg                srcOfs = pGeode->exaBfrOffset;
185604007ebaSmrg                dstPch = dstPitch;
185704007ebaSmrg                dstOfs = dstOffset + current_line * dstPch;
185804007ebaSmrg                rop = pGeode->cmpDstFmt;
185904007ebaSmrg                rop |= amd_gx_exa_alpha_ops[PictOpAdd * 2];
186004007ebaSmrg                blt_mode = usesChanB0(PictOpAdd) ?
186104007ebaSmrg                    MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
186204007ebaSmrg                current_line += lines;
186304007ebaSmrg                pass = 0;
186404007ebaSmrg                break;
186504007ebaSmrg            }
186604007ebaSmrg            strides = (srcPch << 16) | dstPch;
186704007ebaSmrg        }
186804007ebaSmrg        else {                  /* not multi pass */
186904007ebaSmrg            srcOfs = srcOffset;
187004007ebaSmrg            dstOfs = dstOffset;
187104007ebaSmrg            current_line = lines = height;
187204007ebaSmrg            strides = (srcPitch << 16) | dstPitch;
187304007ebaSmrg            rop = pGeode->cmpDstFmt | amd_gx_exa_alpha_ops[op * 2];
187404007ebaSmrg            blt_mode = usesChanB0(op) ?
187504007ebaSmrg                MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB;
187604007ebaSmrg        }
187704007ebaSmrg        sizes = (width << 16) | lines;
187804007ebaSmrg        if (srcOfs < dstOfs) {
187904007ebaSmrg            srcOfs += (lines - 1) * srcPitch + width * srcBpp - 1;
188004007ebaSmrg            dstOfs += (lines - 1) * dstPitch + width * dstBpp - 1;
188104007ebaSmrg            blt_mode |= MGP_BM_NEG_XDIR | MGP_BM_NEG_YDIR;
188204007ebaSmrg        }
188304007ebaSmrg        GU2_WAIT_PENDING;
188404007ebaSmrg        WRITE_GP32(MGP_RASTER_MODE, rop);
188504007ebaSmrg        WRITE_GP32(MGP_SRC_OFFSET, srcOfs);
188604007ebaSmrg        WRITE_GP32(MGP_DST_OFFSET, dstOfs);
188704007ebaSmrg        WRITE_GP32(MGP_WID_HEIGHT, sizes);
188804007ebaSmrg        WRITE_GP32(MGP_STRIDE, strides);
188904007ebaSmrg        WRITE_GP16(MGP_BLT_MODE, blt_mode);
1890f29dbc25Smrg    }
1891f29dbc25Smrg}
189204007ebaSmrg#endif                          /* #if XF86EXA */
1893f29dbc25Smrg
1894f29dbc25Smrg/*----------------------------------------------------------------------------
1895f29dbc25Smrg * GXAccelInit.
1896f29dbc25Smrg *
1897f29dbc25Smrg * Description:	This function sets up the supported acceleration routines and
1898f29dbc25Smrg *              appropriate flags.
1899f29dbc25Smrg *
1900f29dbc25Smrg * Parameters:
1901f29dbc25Smrg *      pScrn:	Screeen pointer structure.
1902f29dbc25Smrg *
1903f29dbc25Smrg * Returns:		TRUE on success and FALSE on Failure
1904f29dbc25Smrg *
1905f29dbc25Smrg * Comments:	This function is called in GXScreenInit in
1906f29dbc25Smrg *              geode_driver.c to set  * the acceleration.
1907f29dbc25Smrg *----------------------------------------------------------------------------
1908f29dbc25Smrg */
1909f29dbc25SmrgBool
1910f29dbc25SmrgGXAccelInit(ScreenPtr pScrn)
1911f29dbc25Smrg{
191204007ebaSmrg    ScrnInfoPtr pScrni = xf86ScreenToScrn(pScrn);
1913f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR(pScrni);
1914f29dbc25Smrg
1915f29dbc25Smrg#if XF86EXA
1916f29dbc25Smrg    ExaDriverPtr pExa = pGeode->pExa;
1917f29dbc25Smrg#endif
1918f29dbc25Smrg
1919f29dbc25Smrg    gu2_xshift = pScrni->bitsPerPixel >> 4;
1920f29dbc25Smrg
1921f29dbc25Smrg    /* XXX - fixme - this will change - we'll need to update it */
1922f29dbc25Smrg
1923f29dbc25Smrg    gu2_pitch = pGeode->Pitch;
1924f29dbc25Smrg
1925f29dbc25Smrg    switch (pGeode->Pitch) {
1926f29dbc25Smrg    case 1024:
192704007ebaSmrg        gu2_yshift = 10;
192804007ebaSmrg        break;
1929f29dbc25Smrg    case 2048:
193004007ebaSmrg        gu2_yshift = 11;
193104007ebaSmrg        break;
1932f29dbc25Smrg    case 4096:
193304007ebaSmrg        gu2_yshift = 12;
193404007ebaSmrg        break;
1935f29dbc25Smrg    default:
193604007ebaSmrg        gu2_yshift = 13;
193704007ebaSmrg        break;
1938f29dbc25Smrg    }
1939f29dbc25Smrg
1940f29dbc25Smrg#ifdef OPT_ACCEL
1941f29dbc25Smrg    ACCEL_STRIDE = (pGeode->Pitch << 16) | pGeode->Pitch;
1942f29dbc25Smrg    BPP = amd_gx_BppToRasterMode(pScrni->bitsPerPixel);
1943f29dbc25Smrg#endif
1944f29dbc25Smrg
1945f29dbc25Smrg#if XF86EXA
1946f29dbc25Smrg    if (pExa && pGeode->useEXA) {
194704007ebaSmrg        pExa->exa_major = EXA_VERSION_MAJOR;
194804007ebaSmrg        pExa->exa_minor = EXA_VERSION_MINOR;
194904007ebaSmrg
195004007ebaSmrg        /* Sync */
195104007ebaSmrg        pExa->WaitMarker = amd_gx_exa_WaitMarker;
195204007ebaSmrg        /* UploadToScreen */
195304007ebaSmrg        pExa->UploadToScreen = amd_gx_exa_UploadToScreen;
195404007ebaSmrg        pExa->DownloadFromScreen = amd_gx_exa_DownloadFromScreen;
195504007ebaSmrg
195604007ebaSmrg        /* Solid fill */
195704007ebaSmrg        pExa->PrepareSolid = amd_gx_exa_PrepareSolid;
195804007ebaSmrg        pExa->Solid = amd_gx_exa_Solid;
195904007ebaSmrg        pExa->DoneSolid = amd_gx_exa_Done;
196004007ebaSmrg
196104007ebaSmrg        /* Copy */
196204007ebaSmrg        pExa->PrepareCopy = amd_gx_exa_PrepareCopy;
196304007ebaSmrg        pExa->Copy = amd_gx_exa_Copy;
196404007ebaSmrg        pExa->DoneCopy = amd_gx_exa_Done;
196504007ebaSmrg
196604007ebaSmrg        /* Composite */
196704007ebaSmrg        pExa->CheckComposite = amd_gx_exa_CheckComposite;
196804007ebaSmrg        pExa->PrepareComposite = amd_gx_exa_PrepareComposite;
196904007ebaSmrg        pExa->Composite = amd_gx_exa_Composite;
197004007ebaSmrg        pExa->DoneComposite = amd_gx_exa_Done;
197104007ebaSmrg
197204007ebaSmrg        return exaDriverInit(pScrn, pGeode->pExa);
1973f29dbc25Smrg    }
1974f29dbc25Smrg#endif
1975f29dbc25Smrg
197604007ebaSmrg#if XF86XAA
197704007ebaSmrg
1978f29dbc25Smrg    /* Getting the pointer for acceleration Inforecord */
1979f29dbc25Smrg    pGeode->AccelInfoRec = localRecPtr = XAACreateInfoRec();
1980f29dbc25Smrg    if (!pGeode->AccelInfoRec)
198104007ebaSmrg        return FALSE;
1982f29dbc25Smrg
1983f29dbc25Smrg    /* SET ACCELERATION FLAGS */
198404007ebaSmrg    localRecPtr->Flags = PIXMAP_CACHE | OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER;
1985f29dbc25Smrg
1986f29dbc25Smrg    /* HOOK SYNCRONIZARION ROUTINE */
1987f29dbc25Smrg    localRecPtr->Sync = GXAccelSync;
1988f29dbc25Smrg
1989f29dbc25Smrg#if GX_FILL_RECT_SUPPORT
1990f29dbc25Smrg    /* HOOK FILLED RECTANGLES */
1991f29dbc25Smrg    HOOK(SetupForSolidFill);
1992f29dbc25Smrg    HOOK(SubsequentSolidFillRect);
1993f29dbc25Smrg    localRecPtr->SolidFillFlags = 0;
1994f29dbc25Smrg#endif
1995f29dbc25Smrg
1996f29dbc25Smrg#if GX_MONO_8X8_PAT_SUPPORT
1997f29dbc25Smrg    /* Color expansion */
1998f29dbc25Smrg    HOOK(SetupForMono8x8PatternFill);
1999f29dbc25Smrg    HOOK(SubsequentMono8x8PatternFillRect);
2000f29dbc25Smrg/*         BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD | NO_TRANSPARENCY | */
2001f29dbc25Smrg    localRecPtr->Mono8x8PatternFillFlags = BIT_ORDER_IN_BYTE_MSBFIRST |
200204007ebaSmrg        HARDWARE_PATTERN_PROGRAMMED_BITS | HARDWARE_PATTERN_SCREEN_ORIGIN;
2003f29dbc25Smrg#endif
2004f29dbc25Smrg
2005f29dbc25Smrg#if GX_CLREXP_8X8_PAT_SUPPORT
2006f29dbc25Smrg    /* Color expansion */
2007f29dbc25Smrg    HOOK(SetupForColor8x8PatternFill);
2008f29dbc25Smrg    HOOK(SubsequentColor8x8PatternFillRect);
2009f29dbc25Smrg/*         BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD | NO_TRANSPARENCY | */
2010f29dbc25Smrg    localRecPtr->Color8x8PatternFillFlags =
201104007ebaSmrg        BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD |
201204007ebaSmrg        HARDWARE_PATTERN_PROGRAMMED_BITS | HARDWARE_PATTERN_PROGRAMMED_ORIGIN;
2013f29dbc25Smrg#endif
2014f29dbc25Smrg
2015f29dbc25Smrg#if GX_SCR2SCRCPY_SUPPORT
2016f29dbc25Smrg    /* HOOK SCREEN TO SCREEN COPIES
2017f29dbc25Smrg     * Set flag to only allow copy if transparency is enabled.
2018f29dbc25Smrg     */
2019f29dbc25Smrg    HOOK(SetupForScreenToScreenCopy);
2020f29dbc25Smrg    HOOK(SubsequentScreenToScreenCopy);
2021f29dbc25Smrg    localRecPtr->ScreenToScreenCopyFlags =
202204007ebaSmrg        BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD;
2023f29dbc25Smrg#endif
2024f29dbc25Smrg
2025f29dbc25Smrg#if GX_BRES_LINE_SUPPORT
2026f29dbc25Smrg    /* HOOK BRESENHAM SOLID LINES */
2027f29dbc25Smrg    localRecPtr->SolidLineFlags = NO_PLANEMASK;
2028f29dbc25Smrg    HOOK(SetupForSolidLine);
2029f29dbc25Smrg    HOOK(SubsequentSolidBresenhamLine);
2030f29dbc25Smrg    HOOK(SubsequentSolidHorVertLine);
2031f29dbc25Smrg    HOOK(SubsequentSolidTwoPointLine);
2032f29dbc25Smrg    localRecPtr->SolidBresenhamLineErrorTermBits = 15;
2033f29dbc25Smrg#endif
2034f29dbc25Smrg
2035f29dbc25Smrg#if GX_DASH_LINE_SUPPORT
2036f29dbc25Smrg    /* HOOK BRESENHAM DASHED LINES */
2037f29dbc25Smrg    HOOK(SetupForDashedLine);
2038f29dbc25Smrg    HOOK(SubsequentDashedBresenhamLine);
2039f29dbc25Smrg    HOOK(SubsequentDashedTwoPointLine);
2040f29dbc25Smrg    localRecPtr->DashedBresenhamLineErrorTermBits = 15;
2041f29dbc25Smrg    localRecPtr->DashPatternMaxLength = 64;
204204007ebaSmrg    localRecPtr->DashedLineFlags = NO_PLANEMASK |       /* TRANSPARENCY_ONLY | */
204304007ebaSmrg        LINE_PATTERN_POWER_OF_2_ONLY | LINE_PATTERN_MSBFIRST_MSBJUSTIFIED;
2044f29dbc25Smrg#endif
2045f29dbc25Smrg
2046f29dbc25Smrg#if GX_SCR2SCREXP_SUPPORT
2047f29dbc25Smrg    /* Color expansion */
2048f29dbc25Smrg    HOOK(SetupForScreenToScreenColorExpandFill);
2049f29dbc25Smrg    HOOK(SubsequentScreenToScreenColorExpandFill);
2050f29dbc25Smrg    localRecPtr->ScreenToScreenColorExpandFillFlags =
205104007ebaSmrg        BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD | NO_TRANSPARENCY;
2052f29dbc25Smrg#endif
2053f29dbc25Smrg
2054f29dbc25Smrg    if (pGeode->AccelImageWriteBuffers) {
2055f29dbc25Smrg#if GX_SCANLINE_SUPPORT
205604007ebaSmrg        localRecPtr->ScanlineImageWriteBuffers = pGeode->AccelImageWriteBuffers;
205704007ebaSmrg        localRecPtr->NumScanlineImageWriteBuffers = pGeode->NoOfImgBuffers;
205804007ebaSmrg        HOOK(SetupForScanlineImageWrite);
205904007ebaSmrg        HOOK(SubsequentScanlineImageWriteRect);
206004007ebaSmrg        HOOK(SubsequentImageWriteScanline);
206104007ebaSmrg        localRecPtr->ScanlineImageWriteFlags = NO_PLANEMASK | NO_GXCOPY |
206204007ebaSmrg            BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD;
2063f29dbc25Smrg#endif
2064f29dbc25Smrg
206504007ebaSmrg    }
206604007ebaSmrg    else {
206704007ebaSmrg        localRecPtr->PixmapCacheFlags = DO_NOT_BLIT_STIPPLES;
2068f29dbc25Smrg    }
2069f29dbc25Smrg
2070f29dbc25Smrg    if (pGeode->AccelColorExpandBuffers) {
2071f29dbc25Smrg#if GX_CPU2SCREXP_SUPPORT
207204007ebaSmrg        /* Color expansion */
207304007ebaSmrg        localRecPtr->ScanlineColorExpandBuffers =
207404007ebaSmrg            pGeode->AccelColorExpandBuffers;
207504007ebaSmrg        localRecPtr->NumScanlineColorExpandBuffers =
207604007ebaSmrg            pGeode->NoOfColorExpandLines;
207704007ebaSmrg        HOOK(SetupForScanlineCPUToScreenColorExpandFill);
207804007ebaSmrg        HOOK(SubsequentScanlineCPUToScreenColorExpandFill);
207904007ebaSmrg        HOOK(SubsequentColorExpandScanline);
208004007ebaSmrg        localRecPtr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK |
208104007ebaSmrg            BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD;
2082f29dbc25Smrg#endif
2083f29dbc25Smrg    }
2084f29dbc25Smrg#if GX_WRITE_PIXMAP_SUPPORT
2085f29dbc25Smrg    pGeode->WritePixmap = localRecPtr->WritePixmap;
2086f29dbc25Smrg    HOOK(WritePixmap);
2087f29dbc25Smrg#endif
2088f29dbc25Smrg
2089f29dbc25Smrg    return (XAAInit(pScrn, localRecPtr));
209004007ebaSmrg#else                           /* XF86XAA */
209104007ebaSmrg    return FALSE;
209204007ebaSmrg#endif
2093f29dbc25Smrg}
2094f29dbc25Smrg
2095f29dbc25Smrg/* END OF FILE */
2096