/* * 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 ); }