summaryrefslogtreecommitdiff
path: root/Source/DirectFB/gfxdrivers/radeon/r300_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'Source/DirectFB/gfxdrivers/radeon/r300_state.c')
-rwxr-xr-xSource/DirectFB/gfxdrivers/radeon/r300_state.c1103
1 files changed, 1103 insertions, 0 deletions
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 <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"
+
+#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 );
+}
+