summaryrefslogtreecommitdiff
path: root/Source/DirectFB/gfxdrivers/radeon/r100_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'Source/DirectFB/gfxdrivers/radeon/r100_state.c')
-rwxr-xr-xSource/DirectFB/gfxdrivers/radeon/r100_state.c954
1 files changed, 954 insertions, 0 deletions
diff --git a/Source/DirectFB/gfxdrivers/radeon/r100_state.c b/Source/DirectFB/gfxdrivers/radeon/r100_state.c
new file mode 100755
index 0000000..8985733
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/radeon/r100_state.c
@@ -0,0 +1,954 @@
+/*
+ * Copyright (C) 2006 Claudio Ciccani <klan@users.sf.net>
+ *
+ * Graphics driver for ATI Radeon cards written by
+ * Claudio Ciccani <klan@users.sf.net>.
+ *
+ * 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 <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <directfb.h>
+
+#include <direct/messages.h>
+
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <core/state.h>
+#include <core/gfxcard.h>
+#include <core/surface.h>
+
+#include <gfx/convert.h>
+
+#include "radeon.h"
+#include "radeon_regs.h"
+#include "radeon_mmio.h"
+#include "radeon_state.h"
+
+
+static const u32 r100SrcBlend[] = {
+ SRC_BLEND_GL_ZERO, // DSBF_ZERO
+ SRC_BLEND_GL_ONE, // DSBF_ONE
+ SRC_BLEND_GL_SRC_COLOR, // DSBF_SRCCOLOR
+ SRC_BLEND_GL_ONE_MINUS_SRC_COLOR, // DSBF_INVSRCCOLOR
+ SRC_BLEND_GL_SRC_ALPHA, // DSBF_SRCALPHA
+ SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA, // DSBF_INVSRCALPHA
+ SRC_BLEND_GL_DST_ALPHA, // DSBF_DSTALPHA
+ SRC_BLEND_GL_ONE_MINUS_DST_ALPHA, // DSBF_INVDSTALPHA
+ SRC_BLEND_GL_DST_COLOR, // DSBF_DSTCOLOR
+ SRC_BLEND_GL_ONE_MINUS_DST_COLOR, // DSBF_INVDSTCOLOR
+ SRC_BLEND_GL_SRC_ALPHA_SATURATE // DSBF_SRCALPHASAT
+};
+
+static const u32 r100DstBlend[] = {
+ DST_BLEND_GL_ZERO, // DSBF_ZERO
+ DST_BLEND_GL_ONE, // DSBF_ONE
+ DST_BLEND_GL_SRC_COLOR, // DSBF_SRCCOLOR
+ DST_BLEND_GL_ONE_MINUS_SRC_COLOR, // DSBF_INVSRCCOLOR
+ DST_BLEND_GL_SRC_ALPHA, // DSBF_SRCALPHA
+ DST_BLEND_GL_ONE_MINUS_SRC_ALPHA, // DSBF_INVSRCALPHA
+ DST_BLEND_GL_DST_ALPHA, // DSBF_DSTALPHA
+ DST_BLEND_GL_ONE_MINUS_DST_ALPHA, // DSBF_INVDSTALPHA
+ DST_BLEND_GL_DST_COLOR, // DSBF_DSTCOLOR
+ DST_BLEND_GL_ONE_MINUS_DST_COLOR, // DSBF_INVDSTCOLOR
+ DST_BLEND_GL_ZERO // DSBF_SRCALPHASAT
+};
+
+
+void r100_restore( RadeonDriverData *rdrv, RadeonDeviceData *rdev )
+{
+ volatile u8 *mmio = rdrv->mmio_base;
+
+ radeon_waitfifo( rdrv, rdev, 8 );
+ /* enable caches */
+ radeon_out32( mmio, RB2D_DSTCACHE_MODE, RB2D_DC_2D_CACHE_AUTOFLUSH |
+ RB2D_DC_3D_CACHE_AUTOFLUSH );
+ radeon_out32( mmio, RB3D_DSTCACHE_MODE, RB3D_DC_2D_CACHE_AUTOFLUSH |
+ RB3D_DC_3D_CACHE_AUTOFLUSH );
+ /* restore 3d engine state */
+ radeon_out32( mmio, SE_COORD_FMT, VTX_XY_PRE_MULT_1_OVER_W0 |
+ TEX1_W_ROUTING_USE_W0 );
+ radeon_out32( mmio, SE_LINE_WIDTH, 0x10 );
+#ifdef WORDS_BIGENDIAN
+ radeon_out32( mmio, SE_CNTL_STATUS, TCL_BYPASS | VC_32BIT_SWAP );
+#else
+ radeon_out32( mmio, SE_CNTL_STATUS, TCL_BYPASS );
+#endif
+ radeon_out32( mmio, PP_MISC, ALPHA_TEST_PASS );
+ radeon_out32( mmio, RB3D_ZSTENCILCNTL, Z_TEST_ALWAYS );
+ radeon_out32( mmio, RB3D_ROPCNTL, ROP_XOR );
+}
+
+void r100_set_destination( RadeonDriverData *rdrv,
+ RadeonDeviceData *rdev,
+ CardState *state )
+{
+ CoreSurface *surface = state->destination;
+ CoreSurfaceBuffer *buffer = state->dst.buffer;
+ volatile u8 *mmio = rdrv->mmio_base;
+ u32 offset;
+ u32 pitch;
+
+ if (RADEON_IS_SET( DESTINATION ))
+ return;
+
+ D_ASSERT( (state->dst.offset % 32) == 0 );
+ D_ASSERT( (state->dst.pitch % 32) == 0 );
+
+ offset = radeon_buffer_offset( rdev, &state->dst );
+ pitch = state->dst.pitch;
+
+ if (rdev->dst_offset != offset ||
+ rdev->dst_pitch != pitch ||
+ rdev->dst_format != buffer->format)
+ {
+ bool dst_422 = false;
+
+ switch (buffer->format) {
+ case DSPF_LUT8:
+ case DSPF_ALUT44:
+ case DSPF_A8:
+ rdev->gui_master_cntl = GMC_DST_8BPP;
+ rdev->rb3d_cntl = COLOR_FORMAT_RGB8;
+ break;
+ case DSPF_RGB332:
+ rdev->gui_master_cntl = GMC_DST_8BPP;
+ rdev->rb3d_cntl = COLOR_FORMAT_RGB332 | DITHER_ENABLE;
+ break;
+ case DSPF_ARGB2554:
+ rdev->gui_master_cntl = GMC_DST_16BPP;
+ rdev->rb3d_cntl = COLOR_FORMAT_RGB565;
+ break;
+ case DSPF_RGB444:
+ case DSPF_ARGB4444:
+ rdev->gui_master_cntl = GMC_DST_16BPP;
+ rdev->rb3d_cntl = COLOR_FORMAT_ARGB4444 | DITHER_ENABLE;
+ break;
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ rdev->gui_master_cntl = GMC_DST_15BPP;
+ rdev->rb3d_cntl = COLOR_FORMAT_ARGB1555 | DITHER_ENABLE;
+ break;
+ case DSPF_RGB16:
+ rdev->gui_master_cntl = GMC_DST_16BPP;
+ rdev->rb3d_cntl = COLOR_FORMAT_RGB565 | DITHER_ENABLE;
+ break;
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ case DSPF_AiRGB:
+ case DSPF_AYUV:
+ rdev->gui_master_cntl = GMC_DST_32BPP;
+ rdev->rb3d_cntl = COLOR_FORMAT_ARGB8888;
+ break;
+ case DSPF_UYVY:
+ rdev->gui_master_cntl = GMC_DST_YVYU;
+ rdev->rb3d_cntl = COLOR_FORMAT_YUV422_YVYU;
+ dst_422 = true;
+ break;
+ case DSPF_YUY2:
+ rdev->gui_master_cntl = GMC_DST_VYUY;
+ rdev->rb3d_cntl = COLOR_FORMAT_YUV422_VYUY;
+ dst_422 = true;
+ break;
+ case DSPF_I420:
+ rdev->gui_master_cntl = GMC_DST_8BPP;
+ rdev->rb3d_cntl = COLOR_FORMAT_RGB8;
+ rdev->dst_offset_cb = offset + pitch * surface->config.size.h;
+ rdev->dst_offset_cr = rdev->dst_offset_cb +
+ pitch/2 * surface->config.size.h/2;
+ break;
+ case DSPF_YV12:
+ rdev->gui_master_cntl = GMC_DST_8BPP;
+ rdev->rb3d_cntl = COLOR_FORMAT_RGB8;
+ rdev->dst_offset_cr = offset + pitch * surface->config.size.h;
+ rdev->dst_offset_cb = rdev->dst_offset_cr +
+ pitch/2 * surface->config.size.h/2;
+ break;
+ default:
+ D_BUG( "unexpected pixelformat" );
+ return;
+ }
+
+ rdev->gui_master_cntl |= GMC_DP_SRC_SOURCE_MEMORY |
+ GMC_WR_MSK_DIS |
+ GMC_SRC_PITCH_OFFSET_CNTL |
+ GMC_DST_PITCH_OFFSET_CNTL |
+ GMC_DST_CLIPPING;
+
+ radeon_waitfifo( rdrv, rdev, 4 );
+ radeon_out32( mmio, DST_OFFSET, offset );
+ radeon_out32( mmio, DST_PITCH, pitch );
+ radeon_out32( mmio, RB3D_COLOROFFSET, offset );
+ radeon_out32( mmio, RB3D_COLORPITCH,
+ pitch / DFB_BYTES_PER_PIXEL(buffer->format) );
+
+ if (rdev->dst_format != buffer->format) {
+ if (dst_422 && !rdev->dst_422) {
+ RADEON_UNSET( SOURCE );
+ RADEON_UNSET( CLIP );
+ }
+
+ RADEON_UNSET( COLOR );
+ RADEON_UNSET( DST_BLEND );
+ }
+
+ rdev->dst_format = buffer->format;
+ rdev->dst_offset = offset;
+ rdev->dst_pitch = pitch;
+ rdev->dst_422 = dst_422;
+ }
+
+ RADEON_SET( DESTINATION );
+}
+
+void r100_set_source( RadeonDriverData *rdrv,
+ RadeonDeviceData *rdev,
+ CardState *state )
+{
+ CoreSurface *surface = state->source;
+ CoreSurfaceBuffer *buffer = state->src.buffer;
+ volatile u8 *mmio = rdrv->mmio_base;
+ u32 txformat = TXFORMAT_NON_POWER2;
+ u32 txfilter = MAG_FILTER_LINEAR |
+ MIN_FILTER_LINEAR |
+ CLAMP_S_CLAMP_LAST |
+ CLAMP_T_CLAMP_LAST;
+
+ if (RADEON_IS_SET( SOURCE )) {
+ if ((state->blittingflags & DSBLIT_DEINTERLACE) ==
+ (rdev->blittingflags & DSBLIT_DEINTERLACE))
+ return;
+ }
+
+ D_ASSERT( (state->src.offset % 32) == 0 );
+ D_ASSERT( (state->src.pitch % 32) == 0 );
+
+ rdev->src_offset = radeon_buffer_offset( rdev, &state->src );
+ rdev->src_pitch = state->src.pitch;
+ rdev->src_width = surface->config.size.w;
+ rdev->src_height = surface->config.size.h;
+
+ switch (buffer->format) {
+ case DSPF_LUT8:
+ txformat |= TXFORMAT_I8;
+ txfilter &= ~(MAG_FILTER_LINEAR |
+ MIN_FILTER_LINEAR);
+ rdev->src_mask = 0x000000ff;
+ break;
+ case DSPF_ALUT44:
+ txformat |= TXFORMAT_I8;
+ txfilter &= ~(MAG_FILTER_LINEAR |
+ MIN_FILTER_LINEAR);
+ rdev->src_mask = 0x0000000f;
+ break;
+ case DSPF_A8:
+ txformat |= TXFORMAT_I8 |
+ TXFORMAT_ALPHA_IN_MAP;
+ rdev->src_mask = 0;
+ break;
+ case DSPF_RGB332:
+ txformat |= TXFORMAT_RGB332;
+ rdev->src_mask = 0x000000ff;
+ break;
+ case DSPF_ARGB2554:
+ txformat |= TXFORMAT_RGB565;
+ txfilter &= ~(MAG_FILTER_LINEAR |
+ MIN_FILTER_LINEAR);
+ rdev->src_mask = 0x00003fff;
+ break;
+ case DSPF_RGB444:
+ txformat |= TXFORMAT_ARGB4444;
+ rdev->src_mask = 0x00000fff;
+ break;
+ case DSPF_ARGB4444:
+ txformat |= TXFORMAT_ARGB4444 |
+ TXFORMAT_ALPHA_IN_MAP;
+ rdev->src_mask = 0x00000fff;
+ break;
+ case DSPF_RGB555:
+ txformat |= TXFORMAT_ARGB1555;
+ rdev->src_mask = 0x00007fff;
+ break;
+ case DSPF_ARGB1555:
+ txformat |= TXFORMAT_ARGB1555 |
+ TXFORMAT_ALPHA_IN_MAP;
+ rdev->src_mask = 0x00007fff;
+ break;
+ case DSPF_RGB16:
+ txformat |= TXFORMAT_RGB565;
+ rdev->src_mask = 0x0000ffff;
+ break;
+ case DSPF_RGB32:
+ txformat |= TXFORMAT_ARGB8888;
+ rdev->src_mask = 0x00ffffff;
+ break;
+ case DSPF_ARGB:
+ case DSPF_AiRGB:
+ case DSPF_AYUV:
+ txformat |= TXFORMAT_ARGB8888 |
+ TXFORMAT_ALPHA_IN_MAP;
+ rdev->src_mask = 0x00ffffff;
+ break;
+ case DSPF_UYVY:
+ txformat |= TXFORMAT_YVYU422;
+ if (!rdev->dst_422)
+ txfilter |= YUV_TO_RGB;
+ rdev->src_mask = 0xffffffff;
+ break;
+ case DSPF_YUY2:
+ txformat |= TXFORMAT_VYUY422;
+ if (!rdev->dst_422)
+ txfilter |= YUV_TO_RGB;
+ rdev->src_mask = 0xffffffff;
+ break;
+ case DSPF_I420:
+ txformat |= TXFORMAT_I8;
+ rdev->src_offset_cb = rdev->src_offset +
+ rdev->src_pitch * rdev->src_height;
+ rdev->src_offset_cr = rdev->src_offset_cb +
+ rdev->src_pitch/2 * rdev->src_height/2;
+ rdev->src_mask = 0x000000ff;
+ break;
+ case DSPF_YV12:
+ txformat |= TXFORMAT_I8;
+ rdev->src_offset_cr = rdev->src_offset +
+ rdev->src_pitch * rdev->src_height;
+ rdev->src_offset_cb = rdev->src_offset_cr +
+ rdev->src_pitch/2 * rdev->src_height/2;
+ rdev->src_mask = 0x000000ff;
+ break;
+ default:
+ D_BUG( "unexpected pixelformat" );
+ return;
+ }
+
+ if (state->blittingflags & DSBLIT_DEINTERLACE) {
+ rdev->src_height /= 2;
+ if (surface->config.caps & DSCAPS_SEPARATED) {
+ if (surface->field) {
+ rdev->src_offset += rdev->src_height * rdev->src_pitch;
+ rdev->src_offset_cr += rdev->src_height * rdev->src_pitch/4;
+ rdev->src_offset_cb += rdev->src_height * rdev->src_pitch/4;
+ }
+ } else {
+ if (surface->field) {
+ rdev->src_offset += rdev->src_pitch;
+ rdev->src_offset_cr += rdev->src_pitch/2;
+ rdev->src_offset_cb += rdev->src_pitch/2;
+ }
+ rdev->src_pitch *= 2;
+ }
+ }
+
+ radeon_waitfifo( rdrv, rdev, 7 );
+ radeon_out32( mmio, SRC_OFFSET, rdev->src_offset );
+ radeon_out32( mmio, SRC_PITCH, rdev->src_pitch );
+ radeon_out32( mmio, PP_TXFILTER_0, txfilter );
+ radeon_out32( mmio, PP_TXFORMAT_0, txformat );
+ radeon_out32( mmio, PP_TEX_SIZE_0, ((rdev->src_height-1) << 16) |
+ ((rdev->src_width-1) & 0xffff) );
+ radeon_out32( mmio, PP_TEX_PITCH_0, rdev->src_pitch - 32 );
+ radeon_out32( mmio, PP_TXOFFSET_0, rdev->src_offset );
+
+ if (rdev->src_format != buffer->format)
+ RADEON_UNSET( BLITTING_FLAGS );
+ rdev->src_format = buffer->format;
+
+ RADEON_SET( SOURCE );
+}
+
+void r100_set_source_mask( RadeonDriverData *rdrv,
+ RadeonDeviceData *rdev,
+ CardState *state )
+{
+ CoreSurface *surface = state->source_mask;
+ CoreSurfaceBuffer *buffer = state->src_mask.buffer;
+ volatile u8 *mmio = rdrv->mmio_base;
+ u32 txformat = TXFORMAT_NON_POWER2;
+ u32 txfilter = MAG_FILTER_LINEAR |
+ MIN_FILTER_LINEAR |
+ CLAMP_S_CLAMP_LAST |
+ CLAMP_T_CLAMP_LAST;
+
+ if (RADEON_IS_SET( SOURCE_MASK )) {
+ if ((state->blittingflags & DSBLIT_DEINTERLACE) ==
+ (rdev->blittingflags & DSBLIT_DEINTERLACE))
+ return;
+ }
+
+ D_ASSERT( (state->src_mask.offset % 32) == 0 );
+ D_ASSERT( (state->src_mask.pitch % 32) == 0 );
+
+ rdev->msk_format = buffer->format;
+ rdev->msk_offset = radeon_buffer_offset( rdev, &state->src_mask );
+ rdev->msk_pitch = state->src_mask.pitch;
+ rdev->msk_width = surface->config.size.w;
+ rdev->msk_height = surface->config.size.h;
+
+ switch (buffer->format) {
+ case DSPF_A8:
+ txformat |= TXFORMAT_I8 |
+ TXFORMAT_ALPHA_IN_MAP;
+ break;
+ case DSPF_RGB332:
+ txformat |= TXFORMAT_RGB332;
+ break;
+ case DSPF_RGB444:
+ txformat |= TXFORMAT_ARGB4444;
+ break;
+ case DSPF_ARGB4444:
+ txformat |= TXFORMAT_ARGB4444 |
+ TXFORMAT_ALPHA_IN_MAP;
+ break;
+ case DSPF_RGB555:
+ txformat |= TXFORMAT_ARGB1555;
+ break;
+ case DSPF_ARGB1555:
+ txformat |= TXFORMAT_ARGB1555 |
+ TXFORMAT_ALPHA_IN_MAP;
+ break;
+ case DSPF_RGB16:
+ txformat |= TXFORMAT_RGB565;
+ break;
+ case DSPF_RGB32:
+ txformat |= TXFORMAT_ARGB8888;
+ break;
+ case DSPF_ARGB:
+ case DSPF_AiRGB:
+ txformat |= TXFORMAT_ARGB8888 |
+ TXFORMAT_ALPHA_IN_MAP;
+ break;
+ default:
+ D_BUG( "unexpected pixelformat" );
+ return;
+ }
+
+ if (state->blittingflags & DSBLIT_DEINTERLACE) {
+ rdev->msk_height /= 2;
+ if (surface->config.caps & DSCAPS_SEPARATED) {
+ if (surface->field)
+ rdev->msk_offset += rdev->msk_height * rdev->msk_pitch;
+ } else {
+ if (surface->field)
+ rdev->msk_offset += rdev->msk_pitch;
+ rdev->msk_pitch *= 2;
+ }
+ }
+
+ radeon_waitfifo( rdrv, rdev, 5 );
+ radeon_out32( mmio, PP_TXFILTER_1, txfilter );
+ radeon_out32( mmio, PP_TXFORMAT_1, txformat );
+ radeon_out32( mmio, PP_TEX_SIZE_1, ((rdev->msk_height-1) << 16) |
+ ((rdev->msk_width-1) & 0xffff) );
+ radeon_out32( mmio, PP_TEX_PITCH_1, rdev->msk_pitch - 32 );
+ radeon_out32( mmio, PP_TXOFFSET_1, rdev->msk_offset );
+
+ RADEON_SET( SOURCE_MASK );
+}
+
+void r100_set_clip( RadeonDriverData *rdrv,
+ RadeonDeviceData *rdev,
+ CardState *state )
+{
+ DFBRegion *clip = &state->clip;
+ volatile u8 *mmio = rdrv->mmio_base;
+
+ if (RADEON_IS_SET( CLIP ))
+ return;
+
+ /* 2d clip */
+ radeon_waitfifo( rdrv, rdev, 2 );
+ if (rdev->dst_422) {
+ radeon_out32( mmio, SC_TOP_LEFT,
+ (clip->y1 << 16) | (clip->x1/2 & 0xffff) );
+ radeon_out32( mmio, SC_BOTTOM_RIGHT,
+ ((clip->y2+1) << 16) | ((clip->x2+1)/2 & 0xffff) );
+ } else {
+ 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) );
+ }
+
+ /* 3d clip */
+ radeon_waitfifo( rdrv, rdev, 2 );
+ radeon_out32( mmio, RE_TOP_LEFT,
+ (clip->y1 << 16) | (clip->x1 & 0xffff) );
+ radeon_out32( mmio, RE_BOTTOM_RIGHT,
+ (clip->y2 << 16) | (clip->x2 & 0xffff) );
+
+ rdev->clip = state->clip;
+
+ RADEON_SET( CLIP );
+}
+
+#define R100_SET_YUV422_COLOR( rdrv, rdev, y, u, v ) { \
+ radeon_out32( (rdrv)->fb_base, (rdev)->yuv422_buffer, \
+ PIXEL_YUY2( y, u, v ) ); \
+ radeon_in8( (rdrv)->fb_base, (rdev)->yuv422_buffer ); \
+ radeon_waitfifo( rdrv, rdev, 3 ); \
+ radeon_out32( (rdrv)->mmio_base, PP_TXFILTER_1, 0 ); \
+ radeon_out32( (rdrv)->mmio_base, PP_TXFORMAT_1, TXFORMAT_VYUY422 ); \
+ radeon_out32( (rdrv)->mmio_base, PP_TXOFFSET_1, \
+ (rdev)->fb_offset + (rdev)->yuv422_buffer ); \
+}
+
+void r100_set_drawing_color( RadeonDriverData *rdrv,
+ RadeonDeviceData *rdev,
+ CardState *state )
+{
+ DFBColor color = state->color;
+ int index = state->color_index;
+ u32 color2d;
+ u32 color3d;
+ int y, u, v;
+
+ if (RADEON_IS_SET( COLOR ) && RADEON_IS_SET( DRAWING_FLAGS ))
+ return;
+
+ if (state->drawingflags & DSDRAW_SRC_PREMULTIPLY) {
+ color.r = color.r * color.a / 255;
+ color.g = color.g * color.a / 255;
+ color.b = color.b * color.a / 255;
+ }
+
+ color3d = PIXEL_ARGB( color.a, color.r,
+ color.g, color.b );
+
+ switch (rdev->dst_format) {
+ case DSPF_ALUT44:
+ index |= (color.a & 0xf0);
+ case DSPF_LUT8:
+ color2d = index;
+ color3d = PIXEL_RGB32( index, index, index );
+ break;
+ case DSPF_A8:
+ color2d = color.a;
+ color3d = (color.a << 24) | 0x00ffffff;
+ break;
+ case DSPF_RGB332:
+ color2d = PIXEL_RGB332( color.r, color.g, color.b );
+ break;
+ case DSPF_ARGB2554:
+ color2d = PIXEL_ARGB2554( color.a, color.r,
+ color.g, color.b );
+ break;
+ case DSPF_RGB444:
+ case DSPF_ARGB4444:
+ color2d = PIXEL_ARGB4444( color.a, color.r,
+ color.g, color.b );
+ break;
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ color2d = PIXEL_ARGB1555( color.a, color.r,
+ color.g, color.b );
+ break;
+ case DSPF_RGB16:
+ color2d = PIXEL_RGB16( color.r, color.g, color.b );
+ break;
+ case DSPF_RGB32:
+ color2d = PIXEL_RGB32( color.r, color.g, color.b );
+ break;
+ case DSPF_ARGB:
+ color2d = PIXEL_ARGB( color.a, color.r,
+ color.g, color.b );
+ break;
+ case DSPF_AiRGB:
+ color2d = PIXEL_AiRGB( color.a, color.r,
+ color.g, color.b );
+ break;
+ case DSPF_AYUV:
+ RGB_TO_YCBCR( color.r, color.g, color.b, y, u, v );
+ color3d = color2d = PIXEL_AYUV( color.a, y, u, v );
+ break;
+ case DSPF_UYVY:
+ RGB_TO_YCBCR( color.r, color.g, color.b, y, u, v );
+ color2d = PIXEL_UYVY( y, u, v );
+ R100_SET_YUV422_COLOR( rdrv, rdev, y, u, v );
+ break;
+ case DSPF_YUY2:
+ RGB_TO_YCBCR( color.r, color.g, color.b, y, u, v );
+ color2d = PIXEL_YUY2( y, u, v );
+ R100_SET_YUV422_COLOR( rdrv, rdev, y, u, v );
+ break;
+ case DSPF_I420:
+ case DSPF_YV12:
+ RGB_TO_YCBCR( color.r, color.g, color.b, y, u, v );
+ rdev->y_cop = PIXEL_ARGB( color.a, y, y, y );
+ rdev->cb_cop = PIXEL_ARGB( color.a, u, u, u );
+ rdev->cr_cop = PIXEL_ARGB( color.a, v, v, v );
+ color3d = color2d = rdev->y_cop;
+ break;
+ default:
+ D_BUG( "unexpected pixelformat" );
+ color2d = 0;
+ break;
+ }
+
+ radeon_waitfifo( rdrv, rdev, 2 );
+ radeon_out32( rdrv->mmio_base, DP_BRUSH_FRGD_CLR, color2d );
+ radeon_out32( rdrv->mmio_base, PP_TFACTOR_1, color3d );
+
+ RADEON_SET( COLOR );
+}
+
+void r100_set_blitting_color( RadeonDriverData *rdrv,
+ RadeonDeviceData *rdev,
+ CardState *state )
+{
+ DFBColor color = state->color;
+ u32 color3d;
+ int y, u, v;
+
+ if (RADEON_IS_SET( COLOR ) && RADEON_IS_SET( BLITTING_FLAGS ))
+ return;
+
+ if (state->blittingflags & DSBLIT_COLORIZE &&
+ state->blittingflags & DSBLIT_SRC_PREMULTCOLOR) {
+ color.r = ((long) color.r * color.a / 255L);
+ color.g = ((long) color.g * color.a / 255L);
+ color.b = ((long) color.b * color.a / 255L);
+ }
+
+ switch (rdev->dst_format) {
+ case DSPF_A8:
+ color3d = (color.a << 24) | 0x00ffffff;
+ break;
+ case DSPF_I420:
+ case DSPF_YV12:
+ RGB_TO_YCBCR( color.r, color.g, color.b, y, u, v );
+ rdev->y_cop = PIXEL_ARGB( color.a, y, y, y );
+ rdev->cb_cop = PIXEL_ARGB( color.a, u, u, u );
+ rdev->cr_cop = PIXEL_ARGB( color.a, v, v, v );
+ color3d = rdev->y_cop;
+ break;
+ case DSPF_AYUV:
+ RGB_TO_YCBCR( color.r, color.g, color.b, y, u, v );
+ color3d = PIXEL_AYUV( color.a, y, u, v );
+ break;
+ case DSPF_UYVY:
+ case DSPF_YUY2:
+ RGB_TO_YCBCR( color.r, color.g, color.b, y, u, v );
+ R100_SET_YUV422_COLOR( rdrv, rdev, y, u, v );
+ default:
+ color3d = PIXEL_ARGB( color.a, color.r,
+ color.g, color.b );
+ break;
+ }
+
+ radeon_waitfifo( rdrv, rdev, 1 );
+ radeon_out32( rdrv->mmio_base, PP_TFACTOR_0, color3d );
+
+ RADEON_SET( COLOR );
+}
+
+void r100_set_src_colorkey( RadeonDriverData *rdrv,
+ RadeonDeviceData *rdev,
+ CardState *state )
+{
+ volatile u8 *mmio = rdrv->mmio_base;
+
+ if (RADEON_IS_SET( SRC_COLORKEY ))
+ return;
+
+ radeon_waitfifo( rdrv, rdev, 2 );
+ radeon_out32( mmio, CLR_CMP_CLR_SRC, state->src_colorkey );
+ radeon_out32( mmio, CLR_CMP_MASK, rdev->src_mask );
+
+ RADEON_SET( SRC_COLORKEY );
+}
+
+void r100_set_blend_function( RadeonDriverData *rdrv,
+ RadeonDeviceData *rdev,
+ CardState *state )
+{
+ volatile u8 *mmio = rdrv->mmio_base;
+ u32 sblend;
+ u32 dblend;
+
+ if (RADEON_IS_SET( SRC_BLEND ) && RADEON_IS_SET( DST_BLEND ))
+ return;
+
+ sblend = r100SrcBlend[state->src_blend-1];
+ dblend = r100DstBlend[state->dst_blend-1];
+
+ if (!DFB_PIXELFORMAT_HAS_ALPHA(rdev->dst_format)) {
+ if (sblend == SRC_BLEND_GL_DST_ALPHA)
+ sblend = SRC_BLEND_GL_ONE;
+ else if (sblend == SRC_BLEND_GL_ONE_MINUS_DST_ALPHA)
+ sblend = SRC_BLEND_GL_ZERO;
+
+ if (dblend == DST_BLEND_GL_DST_ALPHA)
+ dblend = DST_BLEND_GL_ONE;
+ else if (dblend == DST_BLEND_GL_ONE_MINUS_DST_ALPHA)
+ dblend = DST_BLEND_GL_ZERO;
+ }
+ else if (rdev->dst_format == DSPF_A8) {
+ if (sblend == SRC_BLEND_GL_DST_ALPHA)
+ sblend = SRC_BLEND_GL_DST_COLOR;
+ else if (sblend == SRC_BLEND_GL_ONE_MINUS_DST_ALPHA)
+ sblend = SRC_BLEND_GL_ONE_MINUS_DST_COLOR;
+
+ if (dblend == DST_BLEND_GL_DST_ALPHA)
+ dblend = DST_BLEND_GL_DST_COLOR;
+ else if (dblend == DST_BLEND_GL_ONE_MINUS_DST_ALPHA)
+ dblend = DST_BLEND_GL_ONE_MINUS_DST_COLOR;
+ }
+
+ radeon_waitfifo( rdrv, rdev, 1 );
+ radeon_out32( mmio, RB3D_BLENDCNTL, sblend | dblend );
+
+ RADEON_SET( SRC_BLEND );
+ RADEON_SET( DST_BLEND );
+}
+
+void r100_set_render_options( RadeonDriverData *rdrv,
+ RadeonDeviceData *rdev,
+ CardState *state )
+{
+ if (RADEON_IS_SET( RENDER_OPTIONS ))
+ return;
+
+ if (state->render_options & DSRO_MATRIX &&
+ (!state->affine_matrix ||
+ state->matrix[0] != (1<<16) || state->matrix[1] != 0 || state->matrix[2] != 0 ||
+ state->matrix[3] != 0 || state->matrix[4] != (1<<16) || state->matrix[5] != 0)) {
+ rdev->matrix = state->matrix;
+ rdev->affine_matrix = state->affine_matrix;
+ }
+ else {
+ rdev->matrix = NULL;
+ }
+
+ if ((rdev->render_options & DSRO_ANTIALIAS) != (state->render_options & DSRO_ANTIALIAS)) {
+ RADEON_UNSET( DRAWING_FLAGS );
+ RADEON_UNSET( BLITTING_FLAGS );
+ }
+ rdev->render_options = state->render_options;
+
+ RADEON_SET( RENDER_OPTIONS );
+}
+
+/* NOTES:
+ * - We use texture unit 0 for blitting functions,
+ * texture unit 1 for drawing functions
+ * - Default blend equation is ADD_CLAMP (A * B + C)
+ */
+
+void r100_set_drawingflags( RadeonDriverData *rdrv,
+ RadeonDeviceData *rdev,
+ CardState *state )
+{
+ volatile u8 *mmio = rdrv->mmio_base;
+ u32 master_cntl = rdev->gui_master_cntl |
+ GMC_SRC_DATATYPE_MONO_FG_LA |
+ GMC_BRUSH_SOLID_COLOR |
+ GMC_CLR_CMP_CNTL_DIS;
+ u32 rb3d_cntl = rdev->rb3d_cntl & ~DITHER_ENABLE;
+ u32 pp_cntl = SCISSOR_ENABLE | TEX_BLEND_1_ENABLE;
+ u32 cblend = COLOR_ARG_C_TFACTOR_COLOR;
+
+ if (RADEON_IS_SET( DRAWING_FLAGS ))
+ return;
+
+ if (rdev->dst_422) {
+ pp_cntl |= TEX_1_ENABLE;
+ cblend = COLOR_ARG_C_T1_COLOR;
+ }
+ else if (rdev->dst_format == DSPF_A8) {
+ cblend = COLOR_ARG_C_TFACTOR_ALPHA;
+ }
+
+ if (state->drawingflags & DSDRAW_BLEND)
+ rb3d_cntl |= ALPHA_BLEND_ENABLE;
+
+ if (state->drawingflags & DSDRAW_XOR) {
+ rb3d_cntl |= ROP_ENABLE;
+ master_cntl |= GMC_ROP3_PATXOR;
+ }
+ else {
+ master_cntl |= GMC_ROP3_PATCOPY;
+ }
+
+ if (state->render_options & DSRO_ANTIALIAS)
+ pp_cntl |= ANTI_ALIAS_LINE_POLY;
+
+ radeon_waitfifo( rdrv, rdev, 8 );
+ radeon_out32( mmio, DP_GUI_MASTER_CNTL, master_cntl );
+ radeon_out32( mmio, DP_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM );
+ radeon_out32( mmio, RB3D_CNTL, rb3d_cntl );
+ radeon_out32( mmio, SE_CNTL, DIFFUSE_SHADE_FLAT |
+ ALPHA_SHADE_FLAT |
+ BFACE_SOLID |
+ FFACE_SOLID |
+ VTX_PIX_CENTER_OGL |
+ ROUND_MODE_ROUND |
+ ROUND_PREC_4TH_PIX );
+ radeon_out32( mmio, PP_CNTL, pp_cntl );
+ radeon_out32( mmio, PP_TXCBLEND_1, cblend );
+ radeon_out32( mmio, PP_TXABLEND_1, ALPHA_ARG_C_TFACTOR_ALPHA );
+ radeon_out32( mmio, SE_VTX_FMT, SE_VTX_FMT_XY );
+
+ rdev->drawingflags = state->drawingflags;
+
+ RADEON_SET ( DRAWING_FLAGS );
+ RADEON_UNSET( BLITTING_FLAGS );
+}
+
+void r100_set_blittingflags( RadeonDriverData *rdrv,
+ RadeonDeviceData *rdev,
+ CardState *state )
+{
+ volatile u8 *mmio = rdrv->mmio_base;
+ u32 master_cntl = rdev->gui_master_cntl |
+ GMC_BRUSH_NONE |
+ GMC_SRC_DATATYPE_COLOR;
+ u32 cmp_cntl = 0;
+ u32 rb3d_cntl = rdev->rb3d_cntl;
+ u32 se_cntl = BFACE_SOLID |
+ FFACE_SOLID |
+ VTX_PIX_CENTER_OGL |
+ ROUND_MODE_ROUND;
+ u32 pp_cntl = SCISSOR_ENABLE |
+ TEX_0_ENABLE |
+ TEX_BLEND_0_ENABLE;
+ u32 cblend = COLOR_ARG_C_T0_COLOR;
+ u32 ablend = ALPHA_ARG_C_T0_ALPHA;
+ u32 vtx_fmt = SE_VTX_FMT_XY | SE_VTX_FMT_ST0;
+ u32 coord_fmt = VTX_XY_PRE_MULT_1_OVER_W0 |
+ TEX1_W_ROUTING_USE_W0;
+
+ if (RADEON_IS_SET( BLITTING_FLAGS ))
+ return;
+
+ if (rdev->accel == DFXL_TEXTRIANGLES) {
+ se_cntl |= DIFFUSE_SHADE_GOURAUD |
+ ALPHA_SHADE_GOURAUD |
+ SPECULAR_SHADE_GOURAUD |
+ FLAT_SHADE_VTX_LAST |
+ ROUND_PREC_8TH_PIX;
+ vtx_fmt |= SE_VTX_FMT_W0 | SE_VTX_FMT_Z;
+ }
+ else {
+ se_cntl |= DIFFUSE_SHADE_FLAT |
+ ALPHA_SHADE_FLAT |
+ ROUND_PREC_4TH_PIX;
+ coord_fmt |= VTX_ST0_NONPARAMETRIC |
+ VTX_ST1_NONPARAMETRIC;
+ }
+
+ if (state->blittingflags & (DSBLIT_BLEND_COLORALPHA |
+ DSBLIT_BLEND_ALPHACHANNEL)) {
+ if (state->blittingflags & DSBLIT_BLEND_COLORALPHA) {
+ if (state->blittingflags & DSBLIT_BLEND_ALPHACHANNEL)
+ ablend = ALPHA_ARG_A_T0_ALPHA | ALPHA_ARG_B_TFACTOR_ALPHA;
+ else
+ ablend = ALPHA_ARG_C_TFACTOR_ALPHA;
+ }
+
+ rb3d_cntl |= ALPHA_BLEND_ENABLE;
+ }
+
+ if (rdev->dst_format != DSPF_A8) {
+ if (state->blittingflags & (DSBLIT_SRC_MASK_ALPHA | DSBLIT_SRC_MASK_COLOR)) {
+ if (state->blittingflags & DSBLIT_SRC_MASK_ALPHA)
+ ablend = ALPHA_ARG_A_T0_ALPHA | ALPHA_ARG_B_T1_ALPHA;
+
+ if (state->blittingflags & DSBLIT_SRC_MASK_COLOR)
+ cblend = COLOR_ARG_A_T0_COLOR | COLOR_ARG_B_T1_COLOR;
+
+ pp_cntl |= TEX_1_ENABLE;
+ }
+ else if (state->blittingflags & DSBLIT_COLORIZE) {
+ if (rdev->dst_422) {
+ cblend = (rdev->src_format == DSPF_A8)
+ ? (COLOR_ARG_C_T1_COLOR)
+ : (COLOR_ARG_A_T0_COLOR | COLOR_ARG_B_T1_COLOR);
+
+ pp_cntl |= TEX_1_ENABLE;
+ }
+ else {
+ cblend = (rdev->src_format == DSPF_A8)
+ ? (COLOR_ARG_C_TFACTOR_COLOR)
+ : (COLOR_ARG_A_T0_COLOR | COLOR_ARG_B_TFACTOR_COLOR);
+ }
+ }
+ else if (state->blittingflags & DSBLIT_SRC_PREMULTCOLOR) {
+ cblend = (rdev->src_format == DSPF_A8)
+ ? (COLOR_ARG_C_T0_ALPHA)
+ : (COLOR_ARG_A_T0_COLOR | COLOR_ARG_B_TFACTOR_ALPHA);
+ }
+ else if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY) {
+ cblend = (rdev->src_format == DSPF_A8)
+ ? (COLOR_ARG_C_T0_ALPHA)
+ : (COLOR_ARG_A_T0_COLOR | COLOR_ARG_B_T0_ALPHA);
+ }
+ } /* DSPF_A8 */
+ else {
+ if (state->blittingflags & DSBLIT_SRC_MASK_ALPHA) {
+ ablend = ALPHA_ARG_A_T0_ALPHA | ALPHA_ARG_B_T1_ALPHA;
+ cblend = COLOR_ARG_A_T0_ALPHA | COLOR_ARG_B_T1_ALPHA;
+ pp_cntl |= TEX_1_ENABLE;
+ }
+ else if (state->blittingflags & DSBLIT_BLEND_COLORALPHA) {
+ if (state->blittingflags & DSBLIT_BLEND_ALPHACHANNEL)
+ cblend = COLOR_ARG_A_T0_ALPHA | COLOR_ARG_B_TFACTOR_ALPHA;
+ else
+ cblend = COLOR_ARG_C_TFACTOR_ALPHA;
+ }
+ else {
+ cblend = COLOR_ARG_C_T0_ALPHA;
+ }
+ }
+
+ if (state->blittingflags & DSBLIT_SRC_COLORKEY)
+ cmp_cntl = SRC_CMP_EQ_COLOR | CLR_CMP_SRC_SOURCE;
+ else
+ master_cntl |= GMC_CLR_CMP_CNTL_DIS;
+
+ if (state->blittingflags & DSBLIT_XOR) {
+ master_cntl |= GMC_ROP3_XOR;
+ rb3d_cntl |= ROP_ENABLE;
+ }
+ else {
+ master_cntl |= GMC_ROP3_SRCCOPY;
+ }
+
+ if (state->render_options & DSRO_ANTIALIAS)
+ pp_cntl |= ANTI_ALIAS_POLY;
+
+ radeon_waitfifo( rdrv, rdev, 9 );
+ radeon_out32( mmio, CLR_CMP_CNTL, cmp_cntl );
+ radeon_out32( mmio, DP_GUI_MASTER_CNTL, master_cntl );
+ radeon_out32( mmio, RB3D_CNTL, rb3d_cntl );
+ radeon_out32( mmio, SE_CNTL, se_cntl );
+ radeon_out32( mmio, PP_CNTL, pp_cntl );
+ radeon_out32( mmio, PP_TXCBLEND_0, cblend );
+ radeon_out32( mmio, PP_TXABLEND_0, ablend );
+ radeon_out32( mmio, SE_VTX_FMT, vtx_fmt );
+ radeon_out32( mmio, SE_COORD_FMT, coord_fmt );
+
+ rdev->blittingflags = state->blittingflags;
+
+ RADEON_SET ( BLITTING_FLAGS );
+ RADEON_UNSET( DRAWING_FLAGS );
+}
+