r128_exa.c revision 42a55b46
142a55b46Smrg/*
242a55b46Smrg * Copyright 2006 Joseph Garvin
342a55b46Smrg * Copyright 2012 Connor Behan
442a55b46Smrg * All Rights Reserved.
542a55b46Smrg *
642a55b46Smrg * Permission is hereby granted, free of charge, to any person obtaining a
742a55b46Smrg * copy of this software and associated documentation files (the "Software"),
842a55b46Smrg * to deal in the Software without restriction, including without limitation
942a55b46Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1042a55b46Smrg * and/or sell copies of the Software, and to permit persons to whom the
1142a55b46Smrg * Software is furnished to do so, subject to the following conditions:
1242a55b46Smrg *
1342a55b46Smrg * The above copyright notice and this permission notice (including the next
1442a55b46Smrg * paragraph) shall be included in all copies or substantial portions of the
1542a55b46Smrg * Software.
1642a55b46Smrg *
1742a55b46Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1842a55b46Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1942a55b46Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
2042a55b46Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2142a55b46Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2242a55b46Smrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2342a55b46Smrg * SOFTWARE.
2442a55b46Smrg *
2542a55b46Smrg * Authors:
2642a55b46Smrg *    Joseph Garvin <joseph.h.garvin@gmail.com>
2742a55b46Smrg *    Connor Behan <connor.behan@gmail.com>
2842a55b46Smrg *
2942a55b46Smrg */
3042a55b46Smrg
3142a55b46Smrg#ifdef HAVE_CONFIG_H
3242a55b46Smrg#include "config.h"
3342a55b46Smrg#endif
3442a55b46Smrg
3542a55b46Smrg#include "r128.h"
3642a55b46Smrg#include "exa.h"
3742a55b46Smrg
3842a55b46Smrg#include "r128_reg.h"
3942a55b46Smrg
4042a55b46Smrg#include "xf86.h"
4142a55b46Smrg
4242a55b46Smrgstatic struct {
4342a55b46Smrg    int rop;
4442a55b46Smrg    int pattern;
4542a55b46Smrg} R128_ROP[] = {
4642a55b46Smrg    { R128_ROP3_ZERO, R128_ROP3_ZERO }, /* GXclear        */
4742a55b46Smrg    { R128_ROP3_DSa,  R128_ROP3_DPa  }, /* Gxand          */
4842a55b46Smrg    { R128_ROP3_SDna, R128_ROP3_PDna }, /* GXandReverse   */
4942a55b46Smrg    { R128_ROP3_S,    R128_ROP3_P    }, /* GXcopy         */
5042a55b46Smrg    { R128_ROP3_DSna, R128_ROP3_DPna }, /* GXandInverted  */
5142a55b46Smrg    { R128_ROP3_D,    R128_ROP3_D    }, /* GXnoop         */
5242a55b46Smrg    { R128_ROP3_DSx,  R128_ROP3_DPx  }, /* GXxor          */
5342a55b46Smrg    { R128_ROP3_DSo,  R128_ROP3_DPo  }, /* GXor           */
5442a55b46Smrg    { R128_ROP3_DSon, R128_ROP3_DPon }, /* GXnor          */
5542a55b46Smrg    { R128_ROP3_DSxn, R128_ROP3_PDxn }, /* GXequiv        */
5642a55b46Smrg    { R128_ROP3_Dn,   R128_ROP3_Dn   }, /* GXinvert       */
5742a55b46Smrg    { R128_ROP3_SDno, R128_ROP3_PDno }, /* GXorReverse    */
5842a55b46Smrg    { R128_ROP3_Sn,   R128_ROP3_Pn   }, /* GXcopyInverted */
5942a55b46Smrg    { R128_ROP3_DSno, R128_ROP3_DPno }, /* GXorInverted   */
6042a55b46Smrg    { R128_ROP3_DSan, R128_ROP3_DPan }, /* GXnand         */
6142a55b46Smrg    { R128_ROP3_ONE,  R128_ROP3_ONE  }  /* GXset          */
6242a55b46Smrg};
6342a55b46Smrg
6442a55b46Smrg/* Assumes that depth 15 and 16 can be used as depth 16, which is okay since we
6542a55b46Smrg * require src and dest datatypes to be equal.
6642a55b46Smrg */
6742a55b46SmrgBool R128GetDatatypeBpp(int bpp, uint32_t *type)
6842a55b46Smrg{
6942a55b46Smrg    switch (bpp) {
7042a55b46Smrg    case 8:
7142a55b46Smrg        *type = R128_DATATYPE_CI8;
7242a55b46Smrg        return TRUE;
7342a55b46Smrg    case 16:
7442a55b46Smrg        *type = R128_DATATYPE_RGB565;
7542a55b46Smrg        return TRUE;
7642a55b46Smrg    case 24:
7742a55b46Smrg        *type = R128_DATATYPE_RGB888;
7842a55b46Smrg        return TRUE;
7942a55b46Smrg    case 32:
8042a55b46Smrg        *type = R128_DATATYPE_ARGB8888;
8142a55b46Smrg        return TRUE;
8242a55b46Smrg    default:
8342a55b46Smrg        return FALSE;
8442a55b46Smrg    }
8542a55b46Smrg}
8642a55b46Smrg
8742a55b46Smrgstatic Bool R128GetOffsetPitch(PixmapPtr pPix, int bpp, uint32_t *pitch_offset,
8842a55b46Smrg				 unsigned int offset, unsigned int pitch)
8942a55b46Smrg{
9042a55b46Smrg    ScreenPtr     pScreen   = pPix->drawable.pScreen;
9142a55b46Smrg    ScrnInfoPtr   pScrn     = xf86ScreenToScrn(pScreen);
9242a55b46Smrg    R128InfoPtr   info      = R128PTR(pScrn);
9342a55b46Smrg
9442a55b46Smrg    if (pitch > 16320 || pitch % info->ExaDriver->pixmapPitchAlign != 0) {
9542a55b46Smrg        R128TRACE(("Bad pitch 0x%08x\n", pitch));
9642a55b46Smrg	return FALSE;
9742a55b46Smrg    }
9842a55b46Smrg
9942a55b46Smrg    if (offset % info->ExaDriver->pixmapOffsetAlign != 0) {
10042a55b46Smrg        R128TRACE(("Bad offset 0x%08x\n", offset));
10142a55b46Smrg	return FALSE;
10242a55b46Smrg    }
10342a55b46Smrg
10442a55b46Smrg    *pitch_offset = ((pitch / bpp) << 21) | (offset >> 5);
10542a55b46Smrg
10642a55b46Smrg    return TRUE;
10742a55b46Smrg}
10842a55b46Smrg
10942a55b46SmrgBool R128GetPixmapOffsetPitch(PixmapPtr pPix, uint32_t *pitch_offset)
11042a55b46Smrg{
11142a55b46Smrg    uint32_t pitch, offset;
11242a55b46Smrg    int bpp;
11342a55b46Smrg
11442a55b46Smrg    bpp = pPix->drawable.bitsPerPixel;
11542a55b46Smrg    if (bpp == 24)
11642a55b46Smrg        bpp = 8;
11742a55b46Smrg
11842a55b46Smrg    offset = exaGetPixmapOffset(pPix);
11942a55b46Smrg    pitch = exaGetPixmapPitch(pPix);
12042a55b46Smrg
12142a55b46Smrg    return R128GetOffsetPitch(pPix, bpp, pitch_offset, offset, pitch);
12242a55b46Smrg}
12342a55b46Smrg
12442a55b46Smrgstatic void Emit2DState(ScrnInfoPtr pScrn)
12542a55b46Smrg{
12642a55b46Smrg    R128InfoPtr   info      = R128PTR(pScrn);
12742a55b46Smrg    int has_src		    = info->state_2d.src_pitch_offset;
12842a55b46Smrg    unsigned char *R128MMIO = info->MMIO;
12942a55b46Smrg
13042a55b46Smrg    R128WaitForFifo(pScrn, (has_src ? 10 : 9));
13142a55b46Smrg
13242a55b46Smrg    OUTREG(R128_DEFAULT_SC_BOTTOM_RIGHT, info->state_2d.default_sc_bottom_right);
13342a55b46Smrg    OUTREG(R128_DP_GUI_MASTER_CNTL, info->state_2d.dp_gui_master_cntl);
13442a55b46Smrg    OUTREG(R128_DP_BRUSH_FRGD_CLR, info->state_2d.dp_brush_frgd_clr);
13542a55b46Smrg    OUTREG(R128_DP_BRUSH_BKGD_CLR, info->state_2d.dp_brush_bkgd_clr);
13642a55b46Smrg    OUTREG(R128_DP_SRC_FRGD_CLR,   info->state_2d.dp_src_frgd_clr);
13742a55b46Smrg    OUTREG(R128_DP_SRC_BKGD_CLR,   info->state_2d.dp_src_bkgd_clr);
13842a55b46Smrg    OUTREG(R128_DP_WRITE_MASK, info->state_2d.dp_write_mask);
13942a55b46Smrg    OUTREG(R128_DP_CNTL, info->state_2d.dp_cntl);
14042a55b46Smrg
14142a55b46Smrg    OUTREG(R128_DST_PITCH_OFFSET, info->state_2d.dst_pitch_offset);
14242a55b46Smrg    if (has_src) OUTREG(R128_SRC_PITCH_OFFSET, info->state_2d.src_pitch_offset);
14342a55b46Smrg}
14442a55b46Smrg
14542a55b46Smrg#ifdef R128DRI
14642a55b46Smrgstatic void EmitCCE2DState(ScrnInfoPtr pScrn)
14742a55b46Smrg{
14842a55b46Smrg    R128InfoPtr   info      = R128PTR(pScrn);
14942a55b46Smrg    int has_src		    = info->state_2d.src_pitch_offset;
15042a55b46Smrg    RING_LOCALS;
15142a55b46Smrg
15242a55b46Smrg    R128CCE_REFRESH( pScrn, info );
15342a55b46Smrg
15442a55b46Smrg    BEGIN_RING( (has_src ? 20 : 18) );
15542a55b46Smrg
15642a55b46Smrg    OUT_RING_REG( R128_DEFAULT_SC_BOTTOM_RIGHT, info->state_2d.default_sc_bottom_right );
15742a55b46Smrg    OUT_RING_REG( R128_DP_GUI_MASTER_CNTL, info->state_2d.dp_gui_master_cntl );
15842a55b46Smrg    OUT_RING_REG( R128_DP_BRUSH_FRGD_CLR, info->state_2d.dp_brush_frgd_clr );
15942a55b46Smrg    OUT_RING_REG( R128_DP_BRUSH_BKGD_CLR, info->state_2d.dp_brush_bkgd_clr );
16042a55b46Smrg    OUT_RING_REG( R128_DP_SRC_FRGD_CLR,   info->state_2d.dp_src_frgd_clr );
16142a55b46Smrg    OUT_RING_REG( R128_DP_SRC_BKGD_CLR,   info->state_2d.dp_src_bkgd_clr );
16242a55b46Smrg    OUT_RING_REG( R128_DP_WRITE_MASK, info->state_2d.dp_write_mask );
16342a55b46Smrg    OUT_RING_REG( R128_DP_CNTL, info->state_2d.dp_cntl );
16442a55b46Smrg
16542a55b46Smrg    OUT_RING_REG( R128_DST_PITCH_OFFSET, info->state_2d.dst_pitch_offset );
16642a55b46Smrg    if (has_src) OUT_RING_REG( R128_SRC_PITCH_OFFSET, info->state_2d.src_pitch_offset );
16742a55b46Smrg
16842a55b46Smrg    ADVANCE_RING();
16942a55b46Smrg}
17042a55b46Smrg#endif
17142a55b46Smrg
17242a55b46Smrg/* EXA Callbacks */
17342a55b46Smrg
17442a55b46Smrgstatic Bool
17542a55b46SmrgR128PrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg)
17642a55b46Smrg{
17742a55b46Smrg    ScreenPtr     pScreen   = pPixmap->drawable.pScreen;
17842a55b46Smrg    ScrnInfoPtr   pScrn     = xf86ScreenToScrn(pScreen);
17942a55b46Smrg    R128InfoPtr   info      = R128PTR(pScrn);
18042a55b46Smrg
18142a55b46Smrg    int bpp = pPixmap->drawable.bitsPerPixel;
18242a55b46Smrg    uint32_t datatype, dst_pitch_offset;
18342a55b46Smrg
18442a55b46Smrg    if (!R128GetDatatypeBpp(bpp, &datatype)) {
18542a55b46Smrg        R128TRACE(("R128GetDatatypeBpp failed\n"));
18642a55b46Smrg	return FALSE;
18742a55b46Smrg    }
18842a55b46Smrg    if (!R128GetPixmapOffsetPitch(pPixmap, &dst_pitch_offset)) {
18942a55b46Smrg        R128TRACE(("R128GetPixmapOffsetPitch failed\n"));
19042a55b46Smrg	return FALSE;
19142a55b46Smrg    }
19242a55b46Smrg    if (info->state_2d.in_use) return FALSE;
19342a55b46Smrg
19442a55b46Smrg    info->state_2d.in_use = TRUE;
19542a55b46Smrg    info->state_2d.default_sc_bottom_right = (R128_DEFAULT_SC_RIGHT_MAX | R128_DEFAULT_SC_BOTTOM_MAX);
19642a55b46Smrg    info->state_2d.dp_brush_bkgd_clr = 0x00000000;
19742a55b46Smrg    info->state_2d.dp_src_frgd_clr = 0xffffffff;
19842a55b46Smrg    info->state_2d.dp_src_bkgd_clr = 0x00000000;
19942a55b46Smrg    info->state_2d.dp_gui_master_cntl = (R128_GMC_DST_PITCH_OFFSET_CNTL |
20042a55b46Smrg					  R128_GMC_BRUSH_SOLID_COLOR |
20142a55b46Smrg					  (datatype >> 8) |
20242a55b46Smrg					  R128_GMC_SRC_DATATYPE_COLOR |
20342a55b46Smrg					  R128_ROP[alu].pattern |
20442a55b46Smrg					  R128_GMC_CLR_CMP_CNTL_DIS);
20542a55b46Smrg    info->state_2d.dp_brush_frgd_clr = fg;
20642a55b46Smrg    info->state_2d.dp_cntl = (R128_DST_X_LEFT_TO_RIGHT | R128_DST_Y_TOP_TO_BOTTOM);
20742a55b46Smrg    info->state_2d.dp_write_mask = planemask;
20842a55b46Smrg    info->state_2d.dst_pitch_offset = dst_pitch_offset;
20942a55b46Smrg    info->state_2d.src_pitch_offset = 0;
21042a55b46Smrg
21142a55b46Smrg#ifdef R128DRI
21242a55b46Smrg    if (info->directRenderingEnabled) {
21342a55b46Smrg        EmitCCE2DState(pScrn);
21442a55b46Smrg    } else
21542a55b46Smrg#endif
21642a55b46Smrg    {
21742a55b46Smrg        Emit2DState(pScrn);
21842a55b46Smrg    }
21942a55b46Smrg    return TRUE;
22042a55b46Smrg}
22142a55b46Smrg
22242a55b46Smrgstatic void
22342a55b46SmrgR128Solid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
22442a55b46Smrg{
22542a55b46Smrg    ScreenPtr     pScreen   = pPixmap->drawable.pScreen;
22642a55b46Smrg    ScrnInfoPtr   pScrn     = xf86ScreenToScrn(pScreen);
22742a55b46Smrg    R128InfoPtr   info      = R128PTR(pScrn);
22842a55b46Smrg    unsigned char *R128MMIO = info->MMIO;
22942a55b46Smrg
23042a55b46Smrg    R128WaitForFifo(pScrn, 2);
23142a55b46Smrg    OUTREG(R128_DST_Y_X,          (y1 << 16) | x1);
23242a55b46Smrg    OUTREG(R128_DST_WIDTH_HEIGHT, ((x2-x1) << 16) | (y2-y1));
23342a55b46Smrg}
23442a55b46Smrg
23542a55b46Smrg#define R128DoneSolid R128Done
23642a55b46Smrg
23742a55b46Smrgvoid
23842a55b46SmrgR128DoPrepareCopy(ScrnInfoPtr pScrn, uint32_t src_pitch_offset,
23942a55b46Smrg			uint32_t dst_pitch_offset, uint32_t datatype, int alu, Pixel planemask)
24042a55b46Smrg{
24142a55b46Smrg    R128InfoPtr   info      = R128PTR(pScrn);
24242a55b46Smrg
24342a55b46Smrg    info->state_2d.in_use = TRUE;
24442a55b46Smrg    info->state_2d.dp_gui_master_cntl = (R128_GMC_DST_PITCH_OFFSET_CNTL |
24542a55b46Smrg					  R128_GMC_SRC_PITCH_OFFSET_CNTL |
24642a55b46Smrg					  R128_GMC_BRUSH_NONE |
24742a55b46Smrg					  (datatype >> 8) |
24842a55b46Smrg					  R128_GMC_SRC_DATATYPE_COLOR |
24942a55b46Smrg					  R128_ROP[alu].rop |
25042a55b46Smrg					  R128_DP_SRC_SOURCE_MEMORY |
25142a55b46Smrg					  R128_GMC_CLR_CMP_CNTL_DIS);
25242a55b46Smrg    info->state_2d.dp_cntl = ((info->xdir >= 0 ? R128_DST_X_LEFT_TO_RIGHT : 0) |
25342a55b46Smrg			       (info->ydir >= 0 ? R128_DST_Y_TOP_TO_BOTTOM : 0));
25442a55b46Smrg    info->state_2d.dp_brush_frgd_clr = 0xffffffff;
25542a55b46Smrg    info->state_2d.dp_brush_bkgd_clr = 0x00000000;
25642a55b46Smrg    info->state_2d.dp_src_frgd_clr = 0xffffffff;
25742a55b46Smrg    info->state_2d.dp_src_bkgd_clr = 0x00000000;
25842a55b46Smrg    info->state_2d.dp_write_mask = planemask;
25942a55b46Smrg    info->state_2d.dst_pitch_offset = dst_pitch_offset;
26042a55b46Smrg    info->state_2d.src_pitch_offset = src_pitch_offset;
26142a55b46Smrg    info->state_2d.default_sc_bottom_right = (R128_DEFAULT_SC_RIGHT_MAX | R128_DEFAULT_SC_BOTTOM_MAX);
26242a55b46Smrg
26342a55b46Smrg#ifdef R128DRI
26442a55b46Smrg    if (info->directRenderingEnabled) {
26542a55b46Smrg        EmitCCE2DState(pScrn);
26642a55b46Smrg    } else
26742a55b46Smrg#endif
26842a55b46Smrg    {
26942a55b46Smrg        Emit2DState(pScrn);
27042a55b46Smrg    }
27142a55b46Smrg}
27242a55b46Smrg
27342a55b46Smrgstatic Bool
27442a55b46SmrgR128PrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, int ydir, int alu, Pixel planemask)
27542a55b46Smrg{
27642a55b46Smrg    ScreenPtr     pScreen   = pSrcPixmap->drawable.pScreen;
27742a55b46Smrg    ScrnInfoPtr   pScrn     = xf86ScreenToScrn(pScreen);
27842a55b46Smrg    R128InfoPtr   info      = R128PTR(pScrn);
27942a55b46Smrg
28042a55b46Smrg    int bpp = pDstPixmap->drawable.bitsPerPixel;
28142a55b46Smrg    uint32_t datatype, src_pitch_offset, dst_pitch_offset;
28242a55b46Smrg
28342a55b46Smrg    if (!R128GetDatatypeBpp(bpp, &datatype)) {
28442a55b46Smrg        R128TRACE(("R128GetDatatypeBpp failed\n"));
28542a55b46Smrg	return FALSE;
28642a55b46Smrg    }
28742a55b46Smrg    if (!R128GetPixmapOffsetPitch(pSrcPixmap, &src_pitch_offset)) {
28842a55b46Smrg        R128TRACE(("R128GetPixmapOffsetPitch source failed\n"));
28942a55b46Smrg	return FALSE;
29042a55b46Smrg    }
29142a55b46Smrg    if (!R128GetPixmapOffsetPitch(pDstPixmap, &dst_pitch_offset)) {
29242a55b46Smrg        R128TRACE(("R128GetPixmapOffsetPitch dest failed\n"));
29342a55b46Smrg	return FALSE;
29442a55b46Smrg    }
29542a55b46Smrg    if (info->state_2d.in_use) return FALSE;
29642a55b46Smrg
29742a55b46Smrg    info->xdir = xdir;
29842a55b46Smrg    info->ydir = ydir;
29942a55b46Smrg
30042a55b46Smrg    R128DoPrepareCopy(pScrn, src_pitch_offset, dst_pitch_offset, datatype, alu, planemask);
30142a55b46Smrg
30242a55b46Smrg    return TRUE;
30342a55b46Smrg}
30442a55b46Smrg
30542a55b46Smrgstatic void
30642a55b46SmrgR128Copy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, int width, int height)
30742a55b46Smrg{
30842a55b46Smrg    ScreenPtr     pScreen   = pDstPixmap->drawable.pScreen;
30942a55b46Smrg    ScrnInfoPtr   pScrn     = xf86ScreenToScrn(pScreen);
31042a55b46Smrg    R128InfoPtr   info      = R128PTR(pScrn);
31142a55b46Smrg    unsigned char *R128MMIO = info->MMIO;
31242a55b46Smrg
31342a55b46Smrg    if (info->xdir < 0) srcX += width - 1, dstX += width - 1;
31442a55b46Smrg    if (info->ydir < 0) srcY += height - 1, dstY += height - 1;
31542a55b46Smrg
31642a55b46Smrg    R128WaitForFifo(pScrn, 3);
31742a55b46Smrg    OUTREG(R128_SRC_Y_X,          (srcY << 16) | srcX);
31842a55b46Smrg    OUTREG(R128_DST_Y_X,          (dstY << 16) | dstX);
31942a55b46Smrg    OUTREG(R128_DST_HEIGHT_WIDTH, (height << 16) | width);
32042a55b46Smrg}
32142a55b46Smrg
32242a55b46Smrg#define R128DoneCopy R128Done
32342a55b46Smrg
32442a55b46Smrgstatic void
32542a55b46SmrgR128Sync(ScreenPtr pScreen, int marker)
32642a55b46Smrg{
32742a55b46Smrg    R128WaitForIdle(xf86ScreenToScrn(pScreen));
32842a55b46Smrg}
32942a55b46Smrg
33042a55b46Smrgstatic void
33142a55b46SmrgR128Done(PixmapPtr pPixmap)
33242a55b46Smrg{
33342a55b46Smrg    ScreenPtr     pScreen   = pPixmap->drawable.pScreen;
33442a55b46Smrg    ScrnInfoPtr   pScrn     = xf86ScreenToScrn(pScreen);
33542a55b46Smrg    R128InfoPtr   info      = R128PTR(pScrn);
33642a55b46Smrg
33742a55b46Smrg    info->state_2d.in_use = FALSE;
33842a55b46Smrg#if defined(R128DRI) && defined(RENDER)
33942a55b46Smrg    if (info->state_2d.src_pix) {
34042a55b46Smrg        pScreen->DestroyPixmap(info->state_2d.src_pix);
34142a55b46Smrg	info->state_2d.src_pix = NULL;
34242a55b46Smrg    }
34342a55b46Smrg    if (info->state_2d.msk_pix) {
34442a55b46Smrg        pScreen->DestroyPixmap(info->state_2d.msk_pix);
34542a55b46Smrg	info->state_2d.msk_pix = NULL;
34642a55b46Smrg    }
34742a55b46Smrg#endif
34842a55b46Smrg}
34942a55b46Smrg
35042a55b46Smrg#ifdef R128DRI
35142a55b46Smrg
35242a55b46Smrg#define R128CCEPrepareSolid R128PrepareSolid
35342a55b46Smrg
35442a55b46Smrgstatic void
35542a55b46SmrgR128CCESolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
35642a55b46Smrg{
35742a55b46Smrg    ScreenPtr     pScreen   = pPixmap->drawable.pScreen;
35842a55b46Smrg    ScrnInfoPtr   pScrn     = xf86ScreenToScrn(pScreen);
35942a55b46Smrg    R128InfoPtr   info      = R128PTR(pScrn);
36042a55b46Smrg    RING_LOCALS;
36142a55b46Smrg
36242a55b46Smrg    R128CCE_REFRESH( pScrn, info );
36342a55b46Smrg
36442a55b46Smrg    BEGIN_RING( 4 );
36542a55b46Smrg
36642a55b46Smrg    OUT_RING_REG( R128_DST_Y_X,          (y1 << 16) | x1 );
36742a55b46Smrg    OUT_RING_REG( R128_DST_WIDTH_HEIGHT, ((x2-x1) << 16) | (y2-y1) );
36842a55b46Smrg
36942a55b46Smrg    ADVANCE_RING();
37042a55b46Smrg}
37142a55b46Smrg
37242a55b46Smrg#define R128CCEDoneSolid R128Done
37342a55b46Smrg
37442a55b46Smrg#define R128CCEPrepareCopy R128PrepareCopy
37542a55b46Smrg
37642a55b46Smrgstatic void
37742a55b46SmrgR128CCECopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY,
37842a55b46Smrg	 int width, int height)
37942a55b46Smrg{
38042a55b46Smrg    ScreenPtr     pScreen   = pDstPixmap->drawable.pScreen;
38142a55b46Smrg    ScrnInfoPtr   pScrn     = xf86ScreenToScrn(pScreen);
38242a55b46Smrg    R128InfoPtr   info      = R128PTR(pScrn);
38342a55b46Smrg    RING_LOCALS;
38442a55b46Smrg
38542a55b46Smrg    R128CCE_REFRESH( pScrn, info );
38642a55b46Smrg
38742a55b46Smrg    if (info->xdir < 0) srcX += width - 1, dstX += width - 1;
38842a55b46Smrg    if (info->ydir < 0) srcY += height - 1, dstY += height - 1;
38942a55b46Smrg
39042a55b46Smrg    BEGIN_RING( 6 );
39142a55b46Smrg
39242a55b46Smrg    OUT_RING_REG( R128_SRC_Y_X,          (srcY << 16) | srcX );
39342a55b46Smrg    OUT_RING_REG( R128_DST_Y_X,          (dstY << 16) | dstX );
39442a55b46Smrg    OUT_RING_REG( R128_DST_HEIGHT_WIDTH, (height << 16) | width );
39542a55b46Smrg
39642a55b46Smrg    ADVANCE_RING();
39742a55b46Smrg}
39842a55b46Smrg
39942a55b46Smrg#define R128CCEDoneCopy R128Done
40042a55b46Smrg
40142a55b46Smrgstatic void
40242a55b46SmrgR128CCESync(ScreenPtr pScreen, int marker)
40342a55b46Smrg{
40442a55b46Smrg    R128CCEWaitForIdle(xf86ScreenToScrn(pScreen));
40542a55b46Smrg}
40642a55b46Smrg
40742a55b46Smrg#ifdef RENDER
40842a55b46Smrg#include "r128_exa_render.c"
40942a55b46Smrg#endif
41042a55b46Smrg
41142a55b46Smrg#endif
41242a55b46Smrg
41342a55b46SmrgBool
41442a55b46SmrgR128EXAInit(ScreenPtr pScreen)
41542a55b46Smrg{
41642a55b46Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
41742a55b46Smrg    R128InfoPtr info  = R128PTR(pScrn);
41842a55b46Smrg
41942a55b46Smrg    info->ExaDriver->exa_major = EXA_VERSION_MAJOR;
42042a55b46Smrg    info->ExaDriver->exa_minor = EXA_VERSION_MINOR;
42142a55b46Smrg
42242a55b46Smrg    info->ExaDriver->memoryBase = info->FB + pScrn->fbOffset;
42342a55b46Smrg    info->ExaDriver->flags = EXA_OFFSCREEN_PIXMAPS | EXA_OFFSCREEN_ALIGN_POT;
42442a55b46Smrg
42542a55b46Smrg#if EXA_VERSION_MAJOR > 2 || (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 3)
42642a55b46Smrg    info->ExaDriver->maxPitchBytes = 16320;
42742a55b46Smrg#endif
42842a55b46Smrg    /* Pitch alignment is in sets of 8 pixels, and we need to cover 32bpp, so it's 32 bytes */
42942a55b46Smrg    info->ExaDriver->pixmapPitchAlign = 32;
43042a55b46Smrg    info->ExaDriver->pixmapOffsetAlign = 32;
43142a55b46Smrg    info->ExaDriver->maxX = 2048;
43242a55b46Smrg    info->ExaDriver->maxY = 2048;
43342a55b46Smrg
43442a55b46Smrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
43542a55b46Smrg	       "Setting up EXA callbacks\n");
43642a55b46Smrg
43742a55b46Smrg#ifdef R128DRI
43842a55b46Smrg    if (info->directRenderingEnabled) {
43942a55b46Smrg	info->ExaDriver->PrepareSolid = R128CCEPrepareSolid;
44042a55b46Smrg	info->ExaDriver->Solid = R128CCESolid;
44142a55b46Smrg	info->ExaDriver->DoneSolid = R128CCEDoneSolid;
44242a55b46Smrg
44342a55b46Smrg	info->ExaDriver->PrepareCopy = R128CCEPrepareCopy;
44442a55b46Smrg	info->ExaDriver->Copy = R128CCECopy;
44542a55b46Smrg	info->ExaDriver->DoneCopy = R128CCEDoneCopy;
44642a55b46Smrg
44742a55b46Smrg#ifdef RENDER
44842a55b46Smrg	if (info->RenderAccel) {
44942a55b46Smrg	    info->ExaDriver->CheckComposite = R128CCECheckComposite;
45042a55b46Smrg	    info->ExaDriver->PrepareComposite = R128CCEPrepareComposite;
45142a55b46Smrg	    info->ExaDriver->Composite = R128CCEComposite;
45242a55b46Smrg	    info->ExaDriver->DoneComposite = R128CCEDoneComposite;
45342a55b46Smrg	}
45442a55b46Smrg#endif
45542a55b46Smrg
45642a55b46Smrg	info->ExaDriver->WaitMarker = R128CCESync;
45742a55b46Smrg    } else
45842a55b46Smrg#endif
45942a55b46Smrg    {
46042a55b46Smrg	info->ExaDriver->PrepareSolid = R128PrepareSolid;
46142a55b46Smrg	info->ExaDriver->Solid = R128Solid;
46242a55b46Smrg	info->ExaDriver->DoneSolid = R128DoneSolid;
46342a55b46Smrg
46442a55b46Smrg	info->ExaDriver->PrepareCopy = R128PrepareCopy;
46542a55b46Smrg	info->ExaDriver->Copy = R128Copy;
46642a55b46Smrg	info->ExaDriver->DoneCopy = R128DoneCopy;
46742a55b46Smrg
46842a55b46Smrg	/* The registers used for r128 compositing are CCE specific, just like the
46942a55b46Smrg	 * registers used for radeon compositing are CP specific. The radeon driver
47042a55b46Smrg	 * falls back to different registers when there is no DRI. The equivalent
47142a55b46Smrg	 * registers on the r128 (if they even exist) are not listed in the register
47242a55b46Smrg	 * file so I can't implement compositing without DRI.
47342a55b46Smrg	 */
47442a55b46Smrg
47542a55b46Smrg	info->ExaDriver->WaitMarker = R128Sync;
47642a55b46Smrg    }
47742a55b46Smrg
47842a55b46Smrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
47942a55b46Smrg	       "Initalizing 2D acceleration engine...\n");
48042a55b46Smrg
48142a55b46Smrg    R128EngineInit(pScrn);
48242a55b46Smrg
48342a55b46Smrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
48442a55b46Smrg	       "Initializing EXA driver...\n");
48542a55b46Smrg
48642a55b46Smrg    if (!exaDriverInit(pScreen, info->ExaDriver)) {
48742a55b46Smrg        free(info->ExaDriver);
48842a55b46Smrg	return FALSE;
48942a55b46Smrg    }
49042a55b46Smrg
49142a55b46Smrg    info->state_2d.composite_setup = FALSE;
49242a55b46Smrg    return TRUE;
49342a55b46Smrg}
494