From 7fe60435bce6595a9c58a9bfd8244d74b5320e96 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Jan 2013 08:46:13 +0100 Subject: Import DirectFB141_2k11R3_beta5 --- Source/DirectFB/gfxdrivers/radeon/radeon_2d.c | 397 ++++++++++++++++++++++++++ 1 file changed, 397 insertions(+) create mode 100755 Source/DirectFB/gfxdrivers/radeon/radeon_2d.c (limited to 'Source/DirectFB/gfxdrivers/radeon/radeon_2d.c') diff --git a/Source/DirectFB/gfxdrivers/radeon/radeon_2d.c b/Source/DirectFB/gfxdrivers/radeon/radeon_2d.c new file mode 100755 index 0000000..acee7aa --- /dev/null +++ b/Source/DirectFB/gfxdrivers/radeon/radeon_2d.c @@ -0,0 +1,397 @@ +/* + * Copyright (C) 2006 Claudio Ciccani + * + * Graphics driver for ATI Radeon cards written by + * Claudio Ciccani . + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "radeon.h" +#include "radeon_regs.h" +#include "radeon_mmio.h" +#include "radeon_2d.h" + + +static void +radeonDoFillRectangle2D( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + DFBRectangle *rect ) +{ + volatile u8 *mmio = rdrv->mmio_base; + + radeon_waitfifo( rdrv, rdev, 2 ); + + radeon_out32( mmio, DST_Y_X, (rect->y << 16) | + (rect->x & 0x3fff) ); + radeon_out32( mmio, DST_HEIGHT_WIDTH, (rect->h << 16) | + (rect->w & 0x3fff) ); +} + +bool radeonFillRectangle2D( void *drv, void *dev, DFBRectangle *rect ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + + if (rdev->dst_422) { + rect->x /= 2; + rect->w = (rect->w+1) >> 1; + } + + radeonDoFillRectangle2D( rdrv, rdev, rect ); + + return true; +} + +bool radeonFillRectangle2D_420( void *drv, void *dev, DFBRectangle *rect ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + DFBRegion *clip = &rdev->clip; + volatile u8 *mmio = rdrv->mmio_base; + + /* Fill Luma plane */ + radeonDoFillRectangle2D( rdrv, rdev, rect ); + + /* Scale coordinates */ + rect->x /= 2; + rect->y /= 2; + rect->w = (rect->w+1) >> 1; + rect->h = (rect->h+1) >> 1; + + /* Prepare Cb plane */ + radeon_waitfifo( rdrv, rdev, 5 ); + radeon_out32( mmio, DST_OFFSET, rdev->dst_offset_cb ); + radeon_out32( mmio, DST_PITCH, rdev->dst_pitch/2 ); + radeon_out32( mmio, SC_TOP_LEFT, (clip->y1/2 << 16) | + (clip->x1/2 & 0xffff) ); + radeon_out32( mmio, SC_BOTTOM_RIGHT, ((clip->y2+1)/2 << 16) | + ((clip->x2+1)/2 & 0xffff) ); + radeon_out32( mmio, DP_BRUSH_FRGD_CLR, rdev->cb_cop ); + + /* Fill Cb plane */ + radeonDoFillRectangle2D( rdrv, rdev, rect ); + + /* Prepare Cr plane */ + radeon_waitfifo( rdrv, rdev, 2 ); + radeon_out32( mmio, DST_OFFSET, rdev->dst_offset_cr ); + radeon_out32( mmio, DP_BRUSH_FRGD_CLR, rdev->cr_cop ); + + /* Fill Cr plane */ + radeonDoFillRectangle2D( rdrv, rdev, rect ); + + /* Reset */ + radeon_waitfifo( rdrv, rdev, 5 ); + radeon_out32( mmio, DST_OFFSET, rdev->dst_offset ); + radeon_out32( mmio, DST_PITCH, rdev->dst_pitch ); + radeon_out32( mmio, SC_TOP_LEFT, (clip->y1 << 16) | + (clip->x1 & 0xffff) ); + radeon_out32( mmio, SC_BOTTOM_RIGHT, ((clip->y2+1) << 16) | + ((clip->x2+1) & 0xffff) ); + radeon_out32( mmio, DP_BRUSH_FRGD_CLR, rdev->y_cop ); + + return true; +} + +static void +radeonDoDrawRectangle2D( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + DFBRectangle *rect ) +{ + volatile u8 *mmio = rdrv->mmio_base; + + radeon_waitfifo( rdrv, rdev, 7 ); + + /* left line */ + radeon_out32( mmio, DST_Y_X, (rect->y << 16) | (rect->x & 0x3fff) ); + radeon_out32( mmio, DST_HEIGHT_WIDTH, (rect->h << 16) | 1 ); + /* top line */ + radeon_out32( mmio, DST_HEIGHT_WIDTH, (1 << 16) | (rect->w & 0xffff) ); + /* bottom line */ + radeon_out32( mmio, DST_Y_X, ((rect->y+rect->h-1) << 16) | (rect->x & 0x3fff) ); + radeon_out32( mmio, DST_HEIGHT_WIDTH, (1 << 16) | (rect->w & 0xffff) ); + /* right line */ + radeon_out32( mmio, DST_Y_X, (rect->y << 16) | ((rect->x+rect->w-1) & 0x3fff) ); + radeon_out32( mmio, DST_HEIGHT_WIDTH, (rect->h << 16) | 1 ); +} + +bool radeonDrawRectangle2D( void *drv, void *dev, DFBRectangle *rect ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + + if (rdev->dst_422) { + rect->x /= 2; + rect->w = (rect->w+1) >> 1; + } + + radeonDoDrawRectangle2D( rdrv, rdev, rect ); + + return true; +} + +bool radeonDrawRectangle2D_420( void *drv, void *dev, DFBRectangle *rect ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + DFBRegion *clip = &rdev->clip; + volatile u8 *mmio = rdrv->mmio_base; + + /* Fill Luma plane */ + radeonDoDrawRectangle2D( rdrv, rdev, rect ); + + /* Scale coordinates */ + rect->x /= 2; + rect->y /= 2; + rect->w >>= 1; + rect->h >>= 1; + + /* Prepare Cb plane */ + radeon_waitfifo( rdrv, rdev, 5 ); + radeon_out32( mmio, DST_OFFSET, rdev->dst_offset_cb ); + radeon_out32( mmio, DST_PITCH, rdev->dst_pitch/2 ); + radeon_out32( mmio, SC_TOP_LEFT, (clip->y1/2 << 16) | + (clip->x1/2 & 0xffff) ); + radeon_out32( mmio, SC_BOTTOM_RIGHT, ((clip->y2+1)/2 << 16) | + ((clip->x2+1)/2 & 0xffff) ); + radeon_out32( mmio, DP_BRUSH_FRGD_CLR, rdev->cb_cop ); + + /* Fill Cb plane */ + radeonDoDrawRectangle2D( rdrv, rdev, rect ); + + /* Prepare Cr plane */ + radeon_waitfifo( rdrv, rdev, 2 ); + radeon_out32( mmio, DST_OFFSET, rdev->dst_offset_cr ); + radeon_out32( mmio, DP_BRUSH_FRGD_CLR, rdev->cr_cop ); + + /* Fill Cr plane */ + radeonDoDrawRectangle2D( rdrv, rdev, rect ); + + /* Reset */ + radeon_waitfifo( rdrv, rdev, 5 ); + radeon_out32( mmio, DST_OFFSET, rdev->dst_offset ); + radeon_out32( mmio, DST_PITCH, rdev->dst_pitch ); + radeon_out32( mmio, SC_TOP_LEFT, (clip->y1 << 16) | + (clip->x1 & 0xffff) ); + radeon_out32( mmio, SC_BOTTOM_RIGHT, ((clip->y2+1) << 16) | + ((clip->x2+1) & 0xffff) ); + radeon_out32( mmio, DP_BRUSH_FRGD_CLR, rdev->y_cop ); + + return true; +} + +static void +radeonDoDrawLine2D( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + DFBRegion *line ) +{ + volatile u8 *mmio = rdrv->mmio_base; + + radeon_waitfifo( rdrv, rdev, 2 ); + + radeon_out32( mmio, DST_LINE_START, (line->y1 << 16) | + (line->x1 & 0xffff) ); + radeon_out32( mmio, DST_LINE_END, (line->y2 << 16) | + (line->x2 & 0xffff) ); +} + +bool radeonDrawLine2D( void *drv, void *dev, DFBRegion *line ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + + if (rdev->dst_422) { + line->x1 /= 2; + line->x2 = (line->x2+1) / 2; + } + + radeonDoDrawLine2D( rdrv, rdev, line ); + + return true; +} + +bool radeonDrawLine2D_420( void *drv, void *dev, DFBRegion *line ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + DFBRegion *clip = &rdev->clip; + volatile u8 *mmio = rdrv->mmio_base; + + line->x1 &= ~1; + line->y1 &= ~1; + line->x2 &= ~1; + line->y2 &= ~1; + + /* Fill Luma plane */ + radeonDoDrawLine2D( rdrv, rdev, line ); + + /* Scale coordinates */ + line->x1 /= 2; + line->y1 /= 2; + line->x2 /= 2; + line->y2 /= 2; + + /* Prepare Cb plane */ + radeon_waitfifo( rdrv, rdev, 5 ); + radeon_out32( mmio, DST_OFFSET, rdev->dst_offset_cb ); + radeon_out32( mmio, DST_PITCH, rdev->dst_pitch/2 ); + radeon_out32( mmio, SC_TOP_LEFT, (clip->y1/2 << 16) | + (clip->x1/2 & 0xffff) ); + radeon_out32( mmio, SC_BOTTOM_RIGHT, ((clip->y2+1)/2 << 16) | + ((clip->x2+1)/2 & 0xffff) ); + radeon_out32( mmio, DP_BRUSH_FRGD_CLR, rdev->cb_cop ); + + /* Fill Cb plane */ + radeonDoDrawLine2D( rdrv, rdev, line ); + + /* Prepare Cr plane */ + radeon_waitfifo( rdrv, rdev, 2 ); + radeon_out32( mmio, DST_OFFSET, rdev->dst_offset_cr ); + radeon_out32( mmio, DP_BRUSH_FRGD_CLR, rdev->cr_cop ); + + /* Fill Cr plane */ + radeonDoDrawLine2D( rdrv, rdev, line ); + + /* Reset */ + radeon_waitfifo( rdrv, rdev, 5 ); + radeon_out32( mmio, DST_OFFSET, rdev->dst_offset ); + radeon_out32( mmio, DST_PITCH, rdev->dst_pitch ); + radeon_out32( mmio, SC_TOP_LEFT, (clip->y1 << 16) | + (clip->x1 & 0xffff) ); + radeon_out32( mmio, SC_BOTTOM_RIGHT, ((clip->y2+1) << 16) | + ((clip->x2+1) & 0xffff) ); + radeon_out32( mmio, DP_BRUSH_FRGD_CLR, rdev->y_cop ); + + return true; +} + +static void +radeonDoBlit2D( RadeonDriverData *rdrv, RadeonDeviceData *rdev, + int sx, int sy, int dx, int dy, int w, int h ) +{ + volatile u8 *mmio = rdrv->mmio_base; + u32 dir = 0; + + /* check which blitting direction should be used */ + if (sx <= dx) { + sx += w-1; + dx += w-1; + } else + dir |= DST_X_LEFT_TO_RIGHT; + + if (sy <= dy) { + sy += h-1; + dy += h-1; + } else + dir |= DST_Y_TOP_TO_BOTTOM; + + radeon_waitfifo( rdrv, rdev, 4 ); + + radeon_out32( mmio, DP_CNTL, dir ); + radeon_out32( mmio, SRC_Y_X, (sy << 16) | (sx & 0x3fff) ); + radeon_out32( mmio, DST_Y_X, (dy << 16) | (dx & 0x3fff) ); + radeon_out32( mmio, DST_HEIGHT_WIDTH, (h << 16) | (w & 0x3fff) ); +} + +bool radeonBlit2D( void *drv, void *dev, DFBRectangle *sr, int dx, int dy ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + + if (rdev->dst_422) { + sr->x /= 2; + sr->w = (sr->w+1) >> 1; + dx /= 2; + } + + radeonDoBlit2D( rdrv, rdev, sr->x, sr->y, dx, dy, sr->w, sr->h ); + + return true; +} + +bool radeonBlit2D_420( void *drv, void *dev, DFBRectangle *sr, int dx, int dy ) +{ + RadeonDriverData *rdrv = (RadeonDriverData*) drv; + RadeonDeviceData *rdev = (RadeonDeviceData*) dev; + DFBRegion *clip = &rdev->clip; + volatile u8 *mmio = rdrv->mmio_base; + + /* Blit Luma plane */ + radeonDoBlit2D( rdrv, rdev, sr->x, sr->y, dx, dy, sr->w, sr->h ); + + /* Scale coordinates */ + sr->x /= 2; + sr->y /= 2; + sr->w = (sr->w+1) >> 1; + sr->h = (sr->h+1) >> 1; + dx /= 2; + dy /= 2; + + /* Prepare Cb plane */ + radeon_waitfifo( rdrv, rdev, 6 ); + radeon_out32( mmio, DST_OFFSET, rdev->dst_offset_cb ); + radeon_out32( mmio, DST_PITCH, rdev->dst_pitch/2 ); + radeon_out32( mmio, SRC_OFFSET, rdev->src_offset_cb ); + radeon_out32( mmio, SRC_PITCH, rdev->src_pitch/2 ); + radeon_out32( mmio, SC_TOP_LEFT, (clip->y1/2 << 16) | + (clip->x1/2 & 0xffff) ); + radeon_out32( mmio, SC_BOTTOM_RIGHT, ((clip->y2+1/2) << 16) | + ((clip->x2+1/2) & 0xffff) ); + + /* Blit Cb plane */ + radeonDoBlit2D( rdrv, rdev, sr->x, sr->y, dx, dy, sr->w, sr->h ); + + /* Prepare Cr plane */ + radeon_waitfifo( rdrv, rdev, 2 ); + radeon_out32( mmio, DST_OFFSET, rdev->dst_offset_cr ); + radeon_out32( mmio, SRC_OFFSET, rdev->src_offset_cr ); + + /* Blit Cr plane */ + radeonDoBlit2D( rdrv, rdev, sr->x, sr->y, dx, dy, sr->w, sr->h ); + + /* Reset */ + radeon_waitfifo( rdrv, rdev, 6 ); + radeon_out32( mmio, DST_OFFSET, rdev->dst_offset ); + radeon_out32( mmio, DST_PITCH, rdev->dst_pitch ); + radeon_out32( mmio, SRC_OFFSET, rdev->src_offset ); + radeon_out32( mmio, SRC_PITCH, rdev->src_pitch ); + radeon_out32( mmio, SC_TOP_LEFT, (clip->y1 << 16) | + (clip->x1 & 0xffff) ); + radeon_out32( mmio, SC_BOTTOM_RIGHT, ((clip->y2+1) << 16) | + ((clip->x2+1) & 0xffff) ); + + return true; +} + -- cgit