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/r300_state.c | 1103 ++++++++++++++++++++++++ 1 file changed, 1103 insertions(+) create mode 100755 Source/DirectFB/gfxdrivers/radeon/r300_state.c (limited to 'Source/DirectFB/gfxdrivers/radeon/r300_state.c') diff --git a/Source/DirectFB/gfxdrivers/radeon/r300_state.c b/Source/DirectFB/gfxdrivers/radeon/r300_state.c new file mode 100755 index 0000000..97bfd6a --- /dev/null +++ b/Source/DirectFB/gfxdrivers/radeon/r300_state.c @@ -0,0 +1,1103 @@ +/* + * 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 "radeon.h" +#include "radeon_regs.h" +#include "radeon_mmio.h" +#include "radeon_state.h" + +#include "r300_program.h" + + +#define R300_HAS_3DREGS() (rdrv->mmio_size > 0x4000) + + +static const u32 r300SrcBlend[] = { + 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 r300DstBlend[] = { + 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 r300_restore( RadeonDriverData *rdrv, RadeonDeviceData *rdev ) +{ + const u32 rs_magic[8] = { 0x00, 0x44, 0x84, 0xc4, + 0x04, 0x04, 0x04, 0x04 }; + volatile u8 *mmio = rdrv->mmio_base; + int i; + + /* enable caches */ + radeon_waitfifo( rdrv, rdev, 1 ); + radeon_out32( mmio, RB2D_DSTCACHE_MODE, RB2D_DC_2D_CACHE_AUTOFLUSH | + R300_RB2D_DC_ENABLE ); + + if (!R300_HAS_3DREGS()) + return; + + /* restore 3d engine state */ + radeon_waitfifo( rdrv, rdev, 50 ); + radeon_out32( mmio, 0x2080, 0x0030045a ); + radeon_out32( mmio, R300_SE_VTE_CNTL, R300_VTX_W0_FMT ); + radeon_out32( mmio, R300_SE_VTE_CNTL+4, 0x00000008 ); + radeon_out32( mmio, 0x2134, 0x00FFFFFF ); + radeon_out32( mmio, 0x2138, 0x00000000 ); +#ifdef WORDS_BIGENDIAN + radeon_out32( mmio, 0x2140, 0x00000002 ); +#else + radeon_out32( mmio, 0x2140, 0x00000000 ); +#endif + radeon_out32( mmio, 0x21dc, 0xaaaaaaaa ); + radeon_out32( mmio, 0x2220, f2d(1.0) ); + radeon_out32( mmio, 0x2224, f2d(1.0) ); + radeon_out32( mmio, 0x2228, f2d(1.0) ); + radeon_out32( mmio, 0x222c, f2d(1.0) ); + if (rdev->chipset >= CHIP_RV350) + radeon_out32( mmio, R300_VAP_UNKNOWN_2288, R300_2288_RV350 ); + else + radeon_out32( mmio, R300_VAP_UNKNOWN_2288, R300_2288_R300 ); + radeon_out32( mmio, R300_GB_ENABLE, R300_GB_POINT_STUFF_ENABLE | + R300_GB_LINE_STUFF_ENABLE | + R300_GB_TRIANGLE_STUFF_ENABLE ); + radeon_out32( mmio, R300_GB_MSPOS0, 0x66666666 ); + radeon_out32( mmio, R300_GB_MSPOS1, 0x06666666 ); + if (rdev->chipset == CHIP_R300 || rdev->chipset == CHIP_R350 || rdev->chipset == CHIP_RV410) { + radeon_out32( mmio, R300_GB_TILE_CONFIG, R300_GB_TILE_ENABLE | + R300_GB_TILE_PIPE_COUNT_R300 | + R300_GB_TILE_SIZE_16 ); + } + else if (rdev->chipset == CHIP_R420) { + radeon_out32( mmio, R300_GB_TILE_CONFIG, R300_GB_TILE_ENABLE | + R300_GB_TILE_PIPE_COUNT_R420 | + R300_GB_TILE_SIZE_16 ); + } + else { + radeon_out32( mmio, R300_GB_TILE_CONFIG, R300_GB_TILE_ENABLE | + R300_GB_TILE_PIPE_COUNT_RV300 | + R300_GB_TILE_SIZE_16 ); + } + radeon_out32( mmio, R300_GB_SELECT, 0 ); + radeon_out32( mmio, R300_GB_AA_CONFIG, 0 ); + radeon_out32( mmio, 0x4200, f2d(0.0) ); + radeon_out32( mmio, 0x4204, f2d(0.0) ); + radeon_out32( mmio, 0x4208, f2d(1.0) ); + radeon_out32( mmio, 0x420c, f2d(1.0) ); + radeon_out32( mmio, 0x4214, 0x00050005 ); + radeon_out32( mmio, R300_RE_POINTSIZE, (6 << R300_POINTSIZE_X_SHIFT) | + (6 << R300_POINTSIZE_Y_SHIFT) ); + radeon_out32( mmio, 0x4230, 0x18000006 ); + radeon_out32( mmio, R300_RE_LINE_CNT, (6 << R300_LINESIZE_SHIFT) | + R300_LINE_CNT_VE ); + radeon_out32( mmio, R300_RE_UNK4238, f2d(1.0/192.0) ); + radeon_out32( mmio, 0x4260, 0x00000000 ); + radeon_out32( mmio, 0x4264, f2d(0.0) ); + radeon_out32( mmio, 0x4268, f2d(1.0) ); + radeon_out32( mmio, 0x4274, 0x00000002 ); + radeon_out32( mmio, 0x427c, 0x00000000 ); + radeon_out32( mmio, 0x4280, 0x00000000 ); + radeon_out32( mmio, R300_RE_POLYGON_MODE, 0 ); + radeon_out32( mmio, 0x428c, 0x00000001 ); + radeon_out32( mmio, 0x4290, 0x00000000 ); + radeon_out32( mmio, 0x4294, 0x00000000 ); + radeon_out32( mmio, 0x4298, 0x00000000 ); + radeon_out32( mmio, 0x42a0, 0x00000000 ); + radeon_out32( mmio, R300_RE_ZBIAS_T_FACTOR, 0 ); + radeon_out32( mmio, R300_RE_ZBIAS_T_CONSTANT, 0 ); + radeon_out32( mmio, R300_RE_ZBIAS_W_FACTOR, 0 ); + radeon_out32( mmio, R300_RE_ZBIAS_W_CONSTANT, 0 ); + radeon_out32( mmio, R300_RE_OCCLUSION_CNTL, 0 ); + radeon_out32( mmio, R300_RE_CULL_CNTL, 0 ); + radeon_out32( mmio, 0x42c0, 0x4b7fffff ); + radeon_out32( mmio, 0x42c4, 0x00000000 ); + + radeon_waitfifo( rdrv, rdev, 16 ); + for (i = 0; i < 8; i++) { + radeon_out32( mmio, R300_RS_INTERP_0+i*4, R300_RS_INTERP_USED | rs_magic[i] ); + //radeon_out32( mmio, R300_RS_ROUTE_0+i*4, 0 ); + } + + radeon_waitfifo( rdrv, rdev, 43 ); + radeon_out32( mmio, 0x43a4, 0x0000001c ); + radeon_out32( mmio, 0x43a8, 0x2da49525 ); + radeon_out32( mmio, 0x43e8, 0x00ffffff ); + radeon_out32( mmio, 0x46a4, 0x00001b01 ); + radeon_out32( mmio, 0x46a8, 0x00001b0f ); + radeon_out32( mmio, 0x46ac, 0x00001b0f ); + radeon_out32( mmio, 0x46b0, 0x00001b0f ); + radeon_out32( mmio, 0x46b4, 0x00000001 ); + radeon_out32( mmio, 0x4bc0, 0x00000000 ); + radeon_out32( mmio, 0x4bc8, 0x00000000 ); + radeon_out32( mmio, 0x4bcc, 0x00000000 ); + radeon_out32( mmio, 0x4bd0, 0x00000000 ); + radeon_out32( mmio, R300_PP_ALPHA_TEST, R300_ALPHA_TEST_PASS ); + radeon_out32( mmio, 0x4bd8, 0x00000000 ); + radeon_out32( mmio, 0x4e00, 0x00000000 ); + radeon_out32( mmio, R300_RB3D_COLORMASK, R300_COLORMASK0_B | + R300_COLORMASK0_G | + R300_COLORMASK0_R | + R300_COLORMASK0_A ); + radeon_out32( mmio, R300_RB3D_BLENDCOLOR, 0xffffffff ); + radeon_out32( mmio, 0x4e14, 0x00000000 ); + radeon_out32( mmio, 0x4e18, 0x00000000 ); + radeon_out32( mmio, 0x4e50, 0x00000000 ); + radeon_out32( mmio, 0x4e54, 0x00000000 ); + radeon_out32( mmio, 0x4e58, 0x00000000 ); + radeon_out32( mmio, 0x4e5c, 0x00000000 ); + radeon_out32( mmio, 0x4e60, 0x00000000 ); + radeon_out32( mmio, 0x4e64, 0x00000000 ); + radeon_out32( mmio, 0x4e68, 0x00000000 ); + radeon_out32( mmio, 0x4e6c, 0x00000000 ); + radeon_out32( mmio, 0x4e70, 0x00000000 ); + radeon_out32( mmio, 0x4e88, 0x00000000 ); + radeon_out32( mmio, 0x4ea0, 0x00000000 ); + radeon_out32( mmio, 0x4ea4, 0xffffffff ); + radeon_out32( mmio, R300_RB3D_ZSTENCIL_CNTL_0, R300_RB3D_Z_DISABLED_1 ); + radeon_out32( mmio, R300_RB3D_ZSTENCIL_CNTL_1, R300_ZS_ALWAYS ); + radeon_out32( mmio, R300_RB3D_ZSTENCIL_CNTL_2, 0xffffff00 ); + radeon_out32( mmio, R300_RB3D_ZSTENCIL_FORMAT, R300_DEPTH_FORMAT_16BIT_INT_Z ); + radeon_out32( mmio, 0x4f14, 0x00000000 ); + radeon_out32( mmio, 0x4f18, 0x00000003 ); + radeon_out32( mmio, 0x4f1c, 0x00000000 ); + radeon_out32( mmio, 0x4f28, 0x00000000 ); + radeon_out32( mmio, 0x4f30, 0x00000000 ); + radeon_out32( mmio, 0x4f34, 0x00000000 ); + radeon_out32( mmio, 0x4f44, 0x00000000 ); + radeon_out32( mmio, 0x4f54, 0x00000000 ); + + /* upload vertex program */ + radeon_waitfifo( rdrv, rdev, 50 ); + radeon_out32( mmio, R300_VAP_PVS_CNTL_1, + (0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT) | + (4 << R300_PVS_CNTL_1_POS_END_SHIFT) | + (4 << R300_PVS_CNTL_1_PROGRAM_END_SHIFT) ); + radeon_out32( mmio, R300_VAP_PVS_CNTL_2, + (0 << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT) | + (4 << R300_PVS_CNTL_2_PARAM_COUNT_SHIFT) ); + radeon_out32( mmio, R300_VAP_PVS_CNTL_3, + (4 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT) | + (4 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN2_SHIFT) ); + radeon_out32( mmio, R300_VAP_PVS_WAITIDLE, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_ADDRESS, R300_PVS_UPLOAD_POINTSIZE ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, f2d(1.0) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, 0 ); + radeon_out32( mmio, R300_VAP_PVS_WAITIDLE, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_ADDRESS, R300_PVS_UPLOAD_PROGRAM ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, EASY_VSF_OP(MAD, 0, ALL, TMP) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, VSF_ATTR_X(0) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, VSF_PARAM(0) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, EASY_VSF_SOURCE(0, ZERO, ZERO, ZERO, ZERO, PARAM, NONE) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, EASY_VSF_OP(MAD, 0, ALL, TMP) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, VSF_ATTR_Y(0) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, VSF_PARAM(1) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, VSF_TMP(0) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, EASY_VSF_OP(MAD, 0, ALL, TMP) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, VSF_ATTR_Z(0) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, VSF_PARAM(2) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, VSF_TMP(0) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, EASY_VSF_OP(MAD, 0, ALL, RESULT) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, VSF_ATTR_W(0) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, VSF_PARAM(3) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, VSF_TMP(0) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, EASY_VSF_OP(ADD, 1, ALL, RESULT) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, VSF_REG(1) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, EASY_VSF_SOURCE(1, ZERO, ZERO, ZERO, ZERO, ATTR, NONE) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, EASY_VSF_SOURCE(1, ZERO, ZERO, ZERO, ZERO, ATTR, NONE) ); + radeon_out32( mmio, R300_VAP_PVS_WAITIDLE, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_ADDRESS, R300_PVS_UPLOAD_PARAMETERS ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, f2d(1.0) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, f2d(1.0) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, f2d(1.0) ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, 0 ); + radeon_out32( mmio, R300_VAP_PVS_UPLOAD_DATA, f2d(1.0) ); + +#if 0 + /* set YUV422 color buffer */ + radeon_waitfifo( rdrv, rdev, 4 ); + radeon_out32( mmio, R300_TX_FILTER_1, R300_TX_MAG_FILTER_NEAREST | + R300_TX_MIN_FILTER_NEAREST ); + radeon_out32( mmio, R300_TX_FILTER1_0, 0 ); + radeon_out32( mmio, R300_TX_SIZE_1, (1 << R300_TX_WIDTHMASK_SHIFT) | + (1 << R300_TX_HEIGHTMASK_SHIFT) ); + radeon_out32( mmio, R300_TX_FORMAT_1, R300_TXFORMAT_VYUY422 ); +#endif +} + +void r300_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; + u32 format = 0; + bool dst_422 = false; + + if (RADEON_IS_SET( DESTINATION )) + return; + + D_ASSERT( (state->dst.offset % 32) == 0 ); + D_ASSERT( (state->dst.pitch % 64) == 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) + { + switch (buffer->format) { + case DSPF_LUT8: + case DSPF_ALUT44: + case DSPF_A8: + case DSPF_RGB332: + format = R300_COLOR_FORMAT_RGB8; + rdev->gui_master_cntl = GMC_DST_8BPP; + break; + case DSPF_ARGB2554: + rdev->gui_master_cntl = GMC_DST_16BPP; + break; + case DSPF_RGB444: + case DSPF_ARGB4444: + rdev->gui_master_cntl = GMC_DST_16BPP; + break; + case DSPF_RGB555: + case DSPF_ARGB1555: + rdev->gui_master_cntl = GMC_DST_15BPP; + break; + case DSPF_RGB16: + format = R300_COLOR_FORMAT_RGB565; + rdev->gui_master_cntl = GMC_DST_16BPP; + break; + case DSPF_RGB32: + case DSPF_ARGB: + case DSPF_AiRGB: + case DSPF_AYUV: + format = R300_COLOR_FORMAT_ARGB8888; + rdev->gui_master_cntl = GMC_DST_32BPP; + break; + case DSPF_UYVY: + rdev->gui_master_cntl = GMC_DST_YVYU; + dst_422 = true; + break; + case DSPF_YUY2: + rdev->gui_master_cntl = GMC_DST_VYUY; + dst_422 = true; + break; + case DSPF_I420: + format = R300_COLOR_FORMAT_RGB8; + rdev->gui_master_cntl = GMC_DST_8BPP; + 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: + format = R300_COLOR_FORMAT_RGB8; + rdev->gui_master_cntl = GMC_DST_8BPP; + 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" ); + break; + } + + 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, 2 ); + radeon_out32( mmio, DST_OFFSET, offset ); + radeon_out32( mmio, DST_PITCH, pitch ); + + if (R300_HAS_3DREGS() && format) { + radeon_waitfifo( rdrv, rdev, 2 ); + radeon_out32( mmio, R300_RB3D_COLOROFFSET0, offset ); + radeon_out32( mmio, R300_RB3D_COLORPITCH0, + ((pitch / DFB_BYTES_PER_PIXEL(buffer->format)) + & R300_COLORPITCH_MASK) | format ); + } + + if (rdev->dst_format != buffer->format) { + if (dst_422 && !rdev->dst_422) { + RADEON_UNSET( CLIP ); + RADEON_UNSET( SOURCE ); + rdev->src_format = DSPF_UNKNOWN; + } + + 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 r300_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 = 0; + u32 txfilter = (R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_S_SHIFT) | + (R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_T_SHIFT) | + (R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_Q_SHIFT) | + R300_TX_MAG_FILTER_LINEAR | + R300_TX_MIN_FILTER_LINEAR; + + 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 % 64) == 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 = R300_TXFORMAT_I8; + txfilter &= ~(R300_TX_MAG_FILTER_LINEAR | + R300_TX_MIN_FILTER_LINEAR); + txfilter |= R300_TX_MAG_FILTER_NEAREST | + R300_TX_MIN_FILTER_NEAREST; + rdev->src_mask = 0x000000ff; + break; + case DSPF_ALUT44: + txformat = R300_TXFORMAT_I8; + txfilter &= ~(R300_TX_MAG_FILTER_LINEAR | + R300_TX_MIN_FILTER_LINEAR); + txfilter |= R300_TX_MAG_FILTER_NEAREST | + R300_TX_MIN_FILTER_NEAREST; + rdev->src_mask = 0x0000000f; + break; + case DSPF_A8: + txformat = R300_TXFORMAT_A8; + rdev->src_mask = 0; + break; + case DSPF_RGB332: + txformat = R300_TXFORMAT_RGB332; + rdev->src_mask = 0x000000ff; + break; + case DSPF_ARGB2554: + txformat = R300_TXFORMAT_RGB565; + txfilter &= ~(R300_TX_MAG_FILTER_LINEAR | + R300_TX_MIN_FILTER_LINEAR); + txfilter |= R300_TX_MAG_FILTER_NEAREST | + R300_TX_MIN_FILTER_NEAREST; + rdev->src_mask = 0x00003fff; + break; + case DSPF_RGB444: + txformat = R300_TXFORMAT_RGB444; + rdev->src_mask = 0x00000fff; + break; + case DSPF_ARGB4444: + txformat = R300_TXFORMAT_ARGB4444; + rdev->src_mask = 0x00000fff; + break; + case DSPF_RGB555: + txformat = R300_TXFORMAT_RGB555; + rdev->src_mask = 0x00007fff; + break; + case DSPF_ARGB1555: + txformat = R300_TXFORMAT_ARGB1555; + rdev->src_mask = 0x00007fff; + break; + case DSPF_RGB16: + txformat = R300_TXFORMAT_RGB565; + rdev->src_mask = 0x0000ffff; + break; + case DSPF_RGB32: + txformat = R300_TXFORMAT_XRGB8888; + rdev->src_mask = 0x00ffffff; + break; + case DSPF_ARGB: + case DSPF_AiRGB: + case DSPF_AYUV: + txformat = R300_TXFORMAT_ARGB8888; + rdev->src_mask = 0x00ffffff; + break; + case DSPF_UYVY: + txformat = R300_TXFORMAT_YVYU422; + rdev->src_mask = 0xffffffff; + break; + case DSPF_YUY2: + txformat = R300_TXFORMAT_VYUY422; + rdev->src_mask = 0xffffffff; + break; + case DSPF_I420: + txformat = R300_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 = R300_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" ); + break; + } + + 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, 2 ); + radeon_out32( mmio, SRC_OFFSET, rdev->src_offset ); + radeon_out32( mmio, SRC_PITCH, rdev->src_pitch ); + + if (R300_HAS_3DREGS()) { + radeon_waitfifo( rdrv, rdev, 6 ); + radeon_out32( mmio, R300_TX_CNTL, 0 ); + radeon_out32( mmio, R300_TX_FILTER_0, txfilter ); + radeon_out32( mmio, R300_TX_FORMAT_0, txformat ); + radeon_out32( mmio, R300_TX_SIZE_0, ((rdev->src_width -1) << R300_TX_WIDTH_SHIFT) | + ((rdev->src_height-1) << R300_TX_HEIGHT_SHIFT) | + R300_TX_SIZE_TXPITCH_EN ); + radeon_out32( mmio, R300_TX_PITCH_0, rdev->src_pitch / + DFB_BYTES_PER_PIXEL(buffer->format) - 8 ); + radeon_out32( mmio, R300_TX_OFFSET_0, rdev->src_offset ); + } + + if (rdev->src_format != buffer->format) + RADEON_UNSET( BLITTING_FLAGS ); + rdev->src_format = buffer->format; + + RADEON_SET( SOURCE ); +} + +void r300_set_clip3d( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + const DFBRegion *clip ) +{ + volatile u8 *mmio = rdrv->mmio_base; + int x1, y1, x2, y2; + + x1 = clip->x1 + R300_CLIPRECT_OFFSET; + y1 = clip->y1 + R300_CLIPRECT_OFFSET; + x2 = clip->x2 + R300_CLIPRECT_OFFSET; + y2 = clip->y2 + R300_CLIPRECT_OFFSET; + + radeon_waitfifo( rdrv, rdev, 5 ); + radeon_out32( mmio, R300_RE_CLIPRECT_TL_0, + ((y1 << R300_CLIPRECT_Y_SHIFT) & R300_CLIPRECT_Y_MASK) | + ((x1 << R300_CLIPRECT_X_SHIFT) & R300_CLIPRECT_X_MASK) ); + radeon_out32( mmio, R300_RE_CLIPRECT_BR_0, + ((y2 << R300_CLIPRECT_Y_SHIFT) & R300_CLIPRECT_Y_MASK) | + ((x2 << R300_CLIPRECT_X_SHIFT) & R300_CLIPRECT_X_MASK) ); + radeon_out32( mmio, R300_RE_CLIPRECT_CNTL, 0x0000aaaa ); + radeon_out32( mmio, R300_RE_SCISSORS_TL, + ((y1 << R300_SCISSORS_Y_SHIFT) & R300_SCISSORS_Y_MASK) | + ((x1 << R300_SCISSORS_X_SHIFT) & R300_SCISSORS_X_MASK) ); + radeon_out32( mmio, R300_RE_SCISSORS_BR, + ((y2 << R300_SCISSORS_Y_SHIFT) & R300_SCISSORS_Y_MASK) | + ((x2 << R300_SCISSORS_X_SHIFT) & R300_SCISSORS_X_MASK) ); +} + +void r300_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 */ + if (R300_HAS_3DREGS()) + r300_set_clip3d( rdrv, rdev, clip ); + + rdev->clip = state->clip; + + RADEON_SET( CLIP ); +} + +#define R300_SET_YUV422_COLOR( rdrv, rdev, y, u, v ) \ + if (R300_HAS_3DREGS()) { \ + 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, 1 ); \ + radeon_out32( (rdrv)->mmio_base, R300_TX_OFFSET_1, \ + ((rdev)->fb_offset + (rdev)->yuv422_buffer) ); \ + } + +void r300_set_drawing_color( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + DFBColor color = state->color; + int index = state->color_index; + u32 color2d; + int y, u, v; + + if (RADEON_IS_SET( COLOR ) && RADEON_IS_SET( DRAWING_FLAGS )) + return; + + if (state->drawingflags & DSDRAW_SRC_PREMULTIPLY) { + 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_ALUT44: + index |= (color.a & 0xf0); + case DSPF_LUT8: + color2d = index; + break; + case DSPF_A8: + color2d = color.a; + 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 ); + 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 ); + //R300_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 ); + //R300_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 ); + color2d = rdev->y_cop; + break; + default: + D_BUG( "unexpected pixelformat" ); + color2d = 0; + break; + } + + rdev->color[0] = (float)color.r/255.0; + rdev->color[1] = (float)color.g/255.0; + rdev->color[2] = (float)color.b/255.0; + rdev->color[3] = (float)color.a/255.0; + + radeon_waitfifo( rdrv, rdev, 1 ); + radeon_out32( rdrv->mmio_base, DP_BRUSH_FRGD_CLR, color2d ); + + RADEON_SET( COLOR ); +} + +void r300_set_blitting_color( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + DFBColor color = state->color; + int y, u, v; + + if (RADEON_IS_SET( COLOR ) && RADEON_IS_SET( BLITTING_FLAGS )) + return; + + switch (rdev->dst_format) { + case DSPF_A8: + color.r = color.g = color.b = 0xff; + 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 ); + break; + case DSPF_AYUV: + RGB_TO_YCBCR( color.r, color.g, color.b, y, u, v ); + color.r = y; + color.g = u; + color.b = v; + break; + case DSPF_UYVY: + case DSPF_YUY2: + RGB_TO_YCBCR( color.r, color.g, color.b, y, u, v ); + //R300_SET_YUV422_COLOR( rdrv, rdev, y, u, v ); + default: + break; + } + + /*rdev->color[0] = (float)color.r/255.0; + rdev->color[1] = (float)color.g/255.0; + rdev->color[2] = (float)color.b/255.0; + rdev->color[3] = (float)color.a/255.0;*/ + + if (R300_HAS_3DREGS()) { + u32 argb; + + argb = (state->blittingflags & DSBLIT_BLEND_COLORALPHA) ? (color.a << 24) : 0xff000000; + if (state->blittingflags & DSBLIT_COLORIZE && + state->blittingflags & (DSBLIT_SRC_PREMULTCOLOR | DSBLIT_BLEND_COLORALPHA)) { + argb |= PIXEL_RGB32( (long)color.r * color.a / 255L, + (long)color.g * color.a / 255L, + (long)color.b * color.a / 255L ); + } + else { + argb |= (state->blittingflags & DSBLIT_COLORIZE) + ? PIXEL_RGB32( color.r, color.g, color.b ) + : PIXEL_RGB32( color.a, color.a, color.a ); + } + + radeon_waitfifo( rdrv, rdev, 1 ); + radeon_out32( rdrv->mmio_base, R300_RB3D_BLENDCOLOR, argb ); + } + + RADEON_SET( COLOR ); +} + +void r300_set_src_colorkey( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + volatile u8 *mmio = rdrv->mmio_base; + u32 key = state->src_colorkey; + + if (RADEON_IS_SET( SRC_COLORKEY )) + return; + + switch (rdev->src_format) { + case DSPF_ARGB4444: + key |= 0xf000; + break; + case DSPF_ARGB2554: + key |= 0xc000; + break; + case DSPF_ARGB1555: + key |= 0x8000; + break; + case DSPF_ARGB: + case DSPF_AYUV: + key |= 0xff000000; + break; + default: + break; + } + + radeon_waitfifo( rdrv, rdev, 3 ); + radeon_out32( mmio, CLR_CMP_CLR_SRC, key ); + /* XXX: R300 seems to ignore CLR_CMP_MASK. */ + radeon_out32( mmio, CLR_CMP_MASK, rdev->src_mask ); + if (R300_HAS_3DREGS()) + radeon_out32( mmio, R300_TX_CHROMA_KEY_0, state->src_colorkey ); + + RADEON_SET( SRC_COLORKEY ); +} + +void +r300_set_blend_function( RadeonDriverData *rdrv, + RadeonDeviceData *rdev, + CardState *state ) +{ + u32 sblend, dblend; + + if (RADEON_IS_SET( SRC_BLEND ) && RADEON_IS_SET( DST_BLEND )) + return; + + sblend = r300SrcBlend[state->src_blend-1]; + dblend = r300DstBlend[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; + } + + rdev->rb3d_blend = sblend | dblend; + + RADEON_UNSET( DRAWING_FLAGS ); + RADEON_UNSET( BLITTING_FLAGS ); + RADEON_SET( SRC_BLEND ); + RADEON_SET( DST_BLEND ); +} + +void r300_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; + } + + /* TODO: antialiasing */ +#if 0 + radeon_waitfifo( rdrv, rdev, 1 ); + radeon_out32( rdrv->mmio_base, R300_GB_AA_CONFIG, + (state->render_options & DSRO_ANTIALIAS) ? R300_AA_ENABLE : 0 ); +#endif + rdev->render_options = state->render_options & ~DSRO_ANTIALIAS; + + RADEON_SET( RENDER_OPTIONS ); +} + +void r300_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_blend; + + if (RADEON_IS_SET( DRAWING_FLAGS )) + return; + + if (state->drawingflags & DSDRAW_BLEND) { + rb3d_blend = R300_BLEND_ENABLE | R300_BLEND_UNKNOWN | + R300_BLEND_NO_SEPARATE | rdev->rb3d_blend; + } + else { + rb3d_blend = R300_SRC_BLEND_GL_ONE | R300_DST_BLEND_GL_ZERO; + } + + if (state->drawingflags & DSDRAW_XOR) + master_cntl |= GMC_ROP3_PATXOR; + else + master_cntl |= GMC_ROP3_PATCOPY; + + radeon_waitfifo( rdrv, rdev, 2 ); + radeon_out32( mmio, DP_GUI_MASTER_CNTL, master_cntl ); + radeon_out32( mmio, DP_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM ); + + if (R300_HAS_3DREGS()) { + radeon_waitfifo( rdrv, rdev, 27 ); + radeon_out32( mmio, R300_TX_ENABLE, 0 ); + radeon_out32( mmio, R300_RE_SHADE_MODEL, R300_RE_SHADE_MODEL_FLAT ); + /* fragment program */ + radeon_out32( mmio, R300_PFS_CNTL_0, 0 ); + radeon_out32( mmio, R300_PFS_CNTL_1, 0 ); + radeon_out32( mmio, R300_PFS_CNTL_2, 0 ); + radeon_out32( mmio, R300_PFS_NODE_0, 0 ); + radeon_out32( mmio, R300_PFS_NODE_1, 0 ); + radeon_out32( mmio, R300_PFS_NODE_2, 0 ); + radeon_out32( mmio, R300_PFS_NODE_3, R300_PFS_NODE_OUTPUT_COLOR ); + radeon_out32( mmio, R300_PFS_INSTR0_0, + FP_INSTRC(MAD, FP_ARGC(SRC0C_XYZ), FP_ARGC(ONE), FP_ARGC(ZERO)) ); + radeon_out32( mmio, R300_PFS_INSTR1_0, + FP_SELC(0,NO,XYZ,FP_TMP(0),FP_TMP(2),FP_TMP(2)) ); + radeon_out32( mmio, R300_PFS_INSTR2_0, + FP_INSTRA(MAD, FP_ARGA(SRC0A), FP_ARGA(ONE), FP_ARGA(ZERO)) ); + radeon_out32( mmio, R300_PFS_INSTR3_0, + FP_SELA(0,NO,W,FP_TMP(0),FP_TMP(2),FP_TMP(2)) ); + /* blend functions */ + radeon_out32( mmio, R300_RB3D_CBLEND, rb3d_blend ); + radeon_out32( mmio, R300_RB3D_ABLEND, rb3d_blend & 0xfffffff0 ); + /* routing */ + radeon_out32( mmio, R300_RS_CNTL_0, (0 << R300_RS_CNTL_TC_CNT_SHIFT) | + (1 << R300_RS_CNTL_CI_CNT_SHIFT) | + R300_RS_CNTL_0_UNKNOWN_18 ); + radeon_out32( mmio, R300_RS_CNTL_1, 0x000000c0 ); + radeon_out32( mmio, R300_RS_ROUTE_0, R300_RS_ROUTE_0_COLOR ); + /* input */ + radeon_out32( mmio, R300_VAP_INPUT_ROUTE_0_0, 0x21030003 ); + radeon_out32( mmio, R300_VAP_INPUT_ROUTE_1_0, 0xf688f688 ); + radeon_out32( mmio, R300_VAP_INPUT_CNTL_0, R300_INPUT_CNTL_0_COLOR ); + radeon_out32( mmio, R300_VAP_INPUT_CNTL_1, R300_INPUT_CNTL_POS | + R300_INPUT_CNTL_COLOR ); + /* output */ + radeon_out32( mmio, R300_VAP_OUTPUT_VTX_FMT_0, + R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT | + R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT ); + radeon_out32( mmio, R300_VAP_OUTPUT_VTX_FMT_1, 0 ); + radeon_out32( mmio, R300_GB_VAP_RASTER_VTX_FMT_0, + R300_GB_VAP_RASTER_VTX_FMT_0__POS_PRESENT | + R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_0_PRESENT ); + radeon_out32( mmio, R300_GB_VAP_RASTER_VTX_FMT_1, 0 ); + radeon_out32( mmio, R300_VAP_UNKNOWN_221C, R300_221C_CLEAR ); + } + + rdev->drawingflags = state->drawingflags; + + RADEON_SET ( DRAWING_FLAGS ); + RADEON_UNSET( BLITTING_FLAGS ); +} + +void r300_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 txfilter1 = R300_TX_TRI_PERF_0_8; + u32 cmp_cntl = 0; + u32 rb3d_blend; + + if (RADEON_IS_SET( BLITTING_FLAGS )) + return; + + if (state->blittingflags & (DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA | + DSBLIT_COLORIZE | DSBLIT_SRC_PREMULTCOLOR)) { + rb3d_blend = R300_BLEND_ENABLE | R300_BLEND_UNKNOWN | R300_BLEND_NO_SEPARATE; + + if (state->blittingflags & DSBLIT_BLEND_ALPHACHANNEL) + rb3d_blend |= rdev->rb3d_blend; + else + rb3d_blend |= R300_SRC_BLEND_GL_ONE | R300_DST_BLEND_GL_ZERO; + + if (state->blittingflags & DSBLIT_BLEND_COLORALPHA) { + rb3d_blend &= ~(R300_SRC_BLEND_MASK | R300_DST_BLEND_MASK); + rb3d_blend |= R300_SRC_BLEND_GL_CONST_ALPHA | + R300_DST_BLEND_GL_ONE_MINUS_CONST_ALPHA; + } + if (state->blittingflags & (DSBLIT_COLORIZE | DSBLIT_SRC_PREMULTCOLOR)) { + rb3d_blend &= ~R300_SRC_BLEND_MASK; + rb3d_blend |= R300_SRC_BLEND_GL_CONST_COLOR; + } + } + else { + rb3d_blend = R300_SRC_BLEND_GL_ONE | R300_DST_BLEND_GL_ZERO; + } + + if (state->blittingflags & DSBLIT_SRC_COLORKEY) { + txfilter1 |= R300_CHROMA_KEY_FORCE; + 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; + else + master_cntl |= GMC_ROP3_SRCCOPY; + + radeon_waitfifo( rdrv, rdev, 2 ); + radeon_out32( mmio, CLR_CMP_CNTL, cmp_cntl ); + radeon_out32( mmio, DP_GUI_MASTER_CNTL, master_cntl ); + + if (R300_HAS_3DREGS()) { + radeon_waitfifo( rdrv, rdev, 29 ); + radeon_out32( mmio, R300_TX_FILTER1_0, txfilter1 ); + radeon_out32( mmio, R300_TX_ENABLE, R300_TX_ENABLE_0 ); + if (rdev->accel == DFXL_TEXTRIANGLES) + radeon_out32( mmio, R300_RE_SHADE_MODEL, R300_RE_SHADE_MODEL_SMOOTH ); + else + radeon_out32( mmio, R300_RE_SHADE_MODEL, R300_RE_SHADE_MODEL_FLAT ); + /* fragment program */ + radeon_out32( mmio, R300_PFS_CNTL_0, R300_PFS_CNTL_FIRST_NODE_HAS_TEX ); + radeon_out32( mmio, R300_PFS_CNTL_1, 0 ); + radeon_out32( mmio, R300_PFS_CNTL_2, 0 ); + radeon_out32( mmio, R300_PFS_NODE_0, 0 ); + radeon_out32( mmio, R300_PFS_NODE_1, 0 ); + radeon_out32( mmio, R300_PFS_NODE_2, 0 ); + radeon_out32( mmio, R300_PFS_NODE_3, R300_PFS_NODE_OUTPUT_COLOR ); + radeon_out32( mmio, R300_PFS_TEXI_0, R300_FPITX_OP_TXP ); + radeon_out32( mmio, R300_PFS_INSTR0_0, + FP_INSTRC(MAD, FP_ARGC(SRC0C_XYZ), FP_ARGC(ONE), FP_ARGC(ZERO)) ); + radeon_out32( mmio, R300_PFS_INSTR1_0, + FP_SELC(0,NO,XYZ,FP_TMP(0),FP_TMP(2),FP_TMP(2)) ); + radeon_out32( mmio, R300_PFS_INSTR2_0, + FP_INSTRA(MAD, FP_ARGA(SRC0A), FP_ARGA(ONE), FP_ARGA(ZERO)) ); + radeon_out32( mmio, R300_PFS_INSTR3_0, + FP_SELA(0,NO,W,FP_TMP(0),FP_TMP(2),FP_TMP(2)) ); + /* blend functions */ + radeon_out32( mmio, R300_RB3D_CBLEND, rb3d_blend ); + radeon_out32( mmio, R300_RB3D_ABLEND, rb3d_blend & 0xfffffff0 ); + /* routing */ + radeon_out32( mmio, R300_RS_CNTL_0, (1 << R300_RS_CNTL_TC_CNT_SHIFT) | + (0 << R300_RS_CNTL_CI_CNT_SHIFT) | + R300_RS_CNTL_0_UNKNOWN_18 ); + radeon_out32( mmio, R300_RS_CNTL_1, 0x000000c0 ); + radeon_out32( mmio, R300_RS_ROUTE_0, R300_RS_ROUTE_ENABLE ); + /* input routing */ + radeon_out32( mmio, R300_VAP_INPUT_ROUTE_0_0, 0x21030003 ); + radeon_out32( mmio, R300_VAP_INPUT_ROUTE_1_0, 0xf688f688 ); + radeon_out32( mmio, R300_VAP_INPUT_CNTL_0, 0x5555 ); + radeon_out32( mmio, R300_VAP_INPUT_CNTL_1, R300_INPUT_CNTL_POS | + R300_INPUT_CNTL_TC0 ); + /* output routing */ + radeon_out32( mmio, R300_VAP_OUTPUT_VTX_FMT_0, + R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT ); + radeon_out32( mmio, R300_VAP_OUTPUT_VTX_FMT_1, 4 ); + radeon_out32( mmio, R300_GB_VAP_RASTER_VTX_FMT_0, + R300_GB_VAP_RASTER_VTX_FMT_0__POS_PRESENT ); + radeon_out32( mmio, R300_GB_VAP_RASTER_VTX_FMT_1, 4 ); + radeon_out32( mmio, R300_VAP_UNKNOWN_221C, R300_221C_CLEAR ); + } + + rdev->blittingflags = state->blittingflags; + + RADEON_SET ( BLITTING_FLAGS ); + RADEON_UNSET( DRAWING_FLAGS ); +} + -- cgit