summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Deucher <alex@botch2.com>2008-04-10 13:59:58 -0400
committerAlex Deucher <alex@botch2.com>2008-04-10 13:59:58 -0400
commitd79040906cd25bd494feb5901f465bbd050aa923 (patch)
tree6b46da5442791a01915f0dffa099188e53be5b3d
parent0a96173cc38e506728d4c3f2dd383ba56e856578 (diff)
R3xx+: EXA/textured video fixes
- get pipe config based on GB_PIPE_SELECT where applicable (adapted from a similar patch from Dave) - only flush the dst cache after submitting vertices, freeing the cache lines stalls the pipe - no need to wait for 3D idle after submitting vertices - fix PURGE_CACHE() and PURGE_ZCACHE() for r3xx+ - fix depth 16 with EXA composite
-rw-r--r--src/radeon.h22
-rw-r--r--src/radeon_accel.c27
-rw-r--r--src/radeon_commonfuncs.c55
-rw-r--r--src/radeon_exa_render.c37
-rw-r--r--src/radeon_reg.h14
-rw-r--r--src/radeon_textured_videofuncs.c11
6 files changed, 100 insertions, 66 deletions
diff --git a/src/radeon.h b/src/radeon.h
index ef62883a..122a9dd3 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -760,6 +760,8 @@ typedef struct {
Bool r600_shadow_fb;
void *fb_shadow;
+
+ int num_gb_pipes;
} RADEONInfoRec, *RADEONInfoPtr;
#define RADEONWaitForFifo(pScrn, entries) \
@@ -1188,15 +1190,27 @@ do { \
#define RADEON_PURGE_CACHE() \
do { \
BEGIN_RING(2); \
- OUT_RING(CP_PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0)); \
- OUT_RING(RADEON_RB3D_DC_FLUSH_ALL); \
+ if (info->ChipFamily <= CHIP_FAMILY_RV280) { \
+ OUT_RING(CP_PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0)); \
+ OUT_RING(RADEON_RB3D_DC_FLUSH_ALL); \
+ } else { \
+ OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); \
+ OUT_RING(R300_RB3D_DC_FLUSH_ALL); \
+ } \
ADVANCE_RING(); \
} while (0)
#define RADEON_PURGE_ZCACHE() \
do { \
- OUT_RING(CP_PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0)); \
- OUT_RING(RADEON_RB3D_ZC_FLUSH_ALL); \
+ BEGIN_RING(2); \
+ if (info->ChipFamily <= CHIP_FAMILY_RV280) { \
+ OUT_RING(CP_PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0)); \
+ OUT_RING(RADEON_RB3D_ZC_FLUSH_ALL); \
+ } else { \
+ OUT_RING(CP_PACKET0(R300_RB3D_ZCACHE_CTLSTAT, 0)); \
+ OUT_RING(R300_ZC_FLUSH_ALL); \
+ } \
+ ADVANCE_RING(); \
} while (0)
#endif /* XF86DRI */
diff --git a/src/radeon_accel.c b/src/radeon_accel.c
index 015d1763..67dae7cb 100644
--- a/src/radeon_accel.c
+++ b/src/radeon_accel.c
@@ -400,6 +400,33 @@ void RADEONEngineInit(ScrnInfoPtr pScrn)
info->aux_sc_cntl = 0x00000000;
#endif
+ if ((info->ChipFamily == CHIP_FAMILY_RV410) ||
+ (info->ChipFamily == CHIP_FAMILY_R420) ||
+ (info->ChipFamily == CHIP_FAMILY_RS690) ||
+ (info->ChipFamily == CHIP_FAMILY_RS740) ||
+ (info->ChipFamily == CHIP_FAMILY_RS400) ||
+ IS_R500_3D) {
+ uint32_t gb_pipe_sel = INREG(R400_GB_PIPE_SELECT);
+ if (info->num_gb_pipes == 0) {
+ info->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "%s: num pipes is %d\n", __FUNCTION__, info->num_gb_pipes);
+ }
+ if (IS_R500_3D)
+ OUTPLL(pScrn, R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4));
+ } else {
+ if (info->num_gb_pipes == 0) {
+ if ((info->ChipFamily == CHIP_FAMILY_R300) ||
+ (info->ChipFamily == CHIP_FAMILY_R350)) {
+ /* R3xx chips */
+ info->num_gb_pipes = 2;
+ } else {
+ /* RV3xx chips */
+ info->num_gb_pipes = 1;
+ }
+ }
+ }
+
RADEONEngineRestore(pScrn);
}
diff --git a/src/radeon_commonfuncs.c b/src/radeon_commonfuncs.c
index 5c9eae1b..987dac65 100644
--- a/src/radeon_commonfuncs.c
+++ b/src/radeon_commonfuncs.c
@@ -55,7 +55,7 @@
static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
- CARD32 gb_tile_config;
+ CARD32 gb_tile_config, su_reg_dest;
ACCEL_PREAMBLE();
info->texW[0] = info->texH[0] = info->texW[1] = info->texH[1] = 1;
@@ -70,27 +70,12 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn)
gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16 | R300_SUBPIXEL_1_16);
- if ((info->Chipset == PCI_CHIP_RV410_5E4C) ||
- (info->Chipset == PCI_CHIP_RV410_5E4F)) {
- /* RV410 SE chips */
- gb_tile_config |= R300_PIPE_COUNT_RV350;
- } else if ((info->ChipFamily == CHIP_FAMILY_RV350) ||
- (info->ChipFamily == CHIP_FAMILY_RV380) ||
- (info->ChipFamily == CHIP_FAMILY_RS400)) {
- /* RV3xx, RS4xx chips */
- gb_tile_config |= R300_PIPE_COUNT_RV350;
- } else if ((info->ChipFamily == CHIP_FAMILY_R300) ||
- (info->ChipFamily == CHIP_FAMILY_R350)) {
- /* R3xx chips */
- gb_tile_config |= R300_PIPE_COUNT_R300;
- } else if ((info->ChipFamily == CHIP_FAMILY_RV410) ||
- (info->ChipFamily == CHIP_FAMILY_RS690) ||
- (info->ChipFamily == CHIP_FAMILY_RS740)) {
- /* RV4xx, RS6xx chips */
- gb_tile_config |= R300_PIPE_COUNT_R420_3P;
- } else {
- /* R4xx, R5xx chips */
- gb_tile_config |= R300_PIPE_COUNT_R420;
+ switch(info->num_gb_pipes) {
+ case 2: gb_tile_config |= R300_PIPE_COUNT_R300; break;
+ case 3: gb_tile_config |= R300_PIPE_COUNT_R420_3P; break;
+ case 4: gb_tile_config |= R300_PIPE_COUNT_R420; break;
+ default:
+ case 1: gb_tile_config |= R300_PIPE_COUNT_RV350; break;
}
BEGIN_ACCEL(3);
@@ -99,6 +84,14 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn)
OUT_ACCEL_REG(R300_GB_ENABLE, 0);
FINISH_ACCEL();
+ if (IS_R500_3D) {
+ su_reg_dest = ((1 << info->num_gb_pipes) - 1);
+ BEGIN_ACCEL(2);
+ OUT_ACCEL_REG(R500_SU_REG_DEST, su_reg_dest);
+ OUT_ACCEL_REG(R500_VAP_INDEX_OFFSET, 0);
+ FINISH_ACCEL();
+ }
+
BEGIN_ACCEL(3);
OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D | R300_DC_FREE_3D);
OUT_ACCEL_REG(R300_RB3D_ZCACHE_CTLSTAT, R300_ZC_FLUSH | R300_ZC_FREE);
@@ -150,14 +143,22 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn)
FINISH_ACCEL();
/* setup the VAP */
- BEGIN_ACCEL(5);
+ BEGIN_ACCEL(6);
/* disable TCL/PVS */
OUT_ACCEL_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0);
OUT_ACCEL_REG(R300_VAP_CNTL_STATUS, R300_PVS_BYPASS);
- OUT_ACCEL_REG(R300_VAP_CNTL, ((10 << R300_PVS_NUM_SLOTS_SHIFT) |
- (5 << R300_PVS_NUM_CNTLRS_SHIFT) |
- (4 << R300_PVS_NUM_FPUS_SHIFT) |
- (5 << R300_VF_MAX_VTX_NUM_SHIFT)));
+ if (IS_R300_3D)
+ OUT_ACCEL_REG(R300_VAP_CNTL, ((10 << R300_PVS_NUM_SLOTS_SHIFT) |
+ (6 << R300_PVS_NUM_CNTLRS_SHIFT) |
+ (6 << R300_PVS_NUM_FPUS_SHIFT) |
+ (12 << R300_VF_MAX_VTX_NUM_SHIFT)));
+ else
+ OUT_ACCEL_REG(R300_VAP_CNTL, ((10 << R300_PVS_NUM_SLOTS_SHIFT) |
+ (6 << R300_PVS_NUM_CNTLRS_SHIFT) |
+ (6 << R300_PVS_NUM_FPUS_SHIFT) |
+ (12 << R300_VF_MAX_VTX_NUM_SHIFT) |
+ R500_TCL_STATE_OPTIMIZATION));
+ OUT_ACCEL_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0);
OUT_ACCEL_REG(R300_VAP_VTE_CNTL, R300_VTX_XY_FMT | R300_VTX_Z_FMT);
OUT_ACCEL_REG(R300_VAP_PSC_SGN_NORM_CNTL, 0);
FINISH_ACCEL();
diff --git a/src/radeon_exa_render.c b/src/radeon_exa_render.c
index a97b752c..cd0fa488 100644
--- a/src/radeon_exa_render.c
+++ b/src/radeon_exa_render.c
@@ -1220,16 +1220,6 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture,
R300_OUT_FMT_C2_SEL_BLUE |
R300_OUT_FMT_C3_SEL_ALPHA);
break;
- case PICT_a1r5g5b5:
- case PICT_x1r5g5b5:
- /* fix me */
- case PICT_r5g6b5:
- output_fmt = (R300_OUT_FMT_C_5_6_5 |
- R300_OUT_FMT_C0_SEL_BLUE |
- R300_OUT_FMT_C1_SEL_GREEN |
- R300_OUT_FMT_C2_SEL_RED |
- R300_OUT_FMT_C3_SEL_ALPHA);
- break;
case PICT_a8:
output_fmt = (R300_OUT_FMT_C4_8 |
R300_OUT_FMT_C0_SEL_ALPHA);
@@ -1490,16 +1480,6 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture,
R300_OUT_FMT_C2_SEL_BLUE |
R300_OUT_FMT_C3_SEL_ALPHA);
break;
- case PICT_a1r5g5b5:
- case PICT_x1r5g5b5:
- /* fix me */
- case PICT_r5g6b5:
- output_fmt = (R300_OUT_FMT_C_5_6_5 |
- R300_OUT_FMT_C0_SEL_BLUE |
- R300_OUT_FMT_C1_SEL_GREEN |
- R300_OUT_FMT_C2_SEL_RED |
- R300_OUT_FMT_C3_SEL_ALPHA);
- break;
case PICT_a8:
output_fmt = (R300_OUT_FMT_C4_8 |
R300_OUT_FMT_C0_SEL_ALPHA);
@@ -1825,7 +1805,7 @@ static void FUNC_NAME(RadeonComposite)(PixmapPtr pDst,
vtx_count = VTX_COUNT;
- if (IS_R300_VARIANT || IS_AVIVO_VARIANT) {
+ if (IS_R300_3D || IS_R500_3D) {
BEGIN_ACCEL(1);
OUT_ACCEL_REG(R300_VAP_VTX_SIZE, vtx_count);
FINISH_ACCEL();
@@ -1845,8 +1825,8 @@ static void FUNC_NAME(RadeonComposite)(PixmapPtr pDst,
RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE |
(4 << RADEON_CP_VC_CNTL_NUM_SHIFT));
} else {
- if (IS_R300_VARIANT || IS_AVIVO_VARIANT)
- BEGIN_RING(4 * vtx_count + 6);
+ if (IS_R300_3D || IS_R500_3D)
+ BEGIN_RING(4 * vtx_count + 4);
else
BEGIN_RING(4 * vtx_count + 2);
@@ -1858,8 +1838,8 @@ static void FUNC_NAME(RadeonComposite)(PixmapPtr pDst,
}
#else /* ACCEL_CP */
- if (IS_R300_VARIANT || IS_AVIVO_VARIANT)
- BEGIN_ACCEL(3 + vtx_count * 4);
+ if (IS_R300_3D || IS_R500_3D)
+ BEGIN_ACCEL(2 + vtx_count * 4);
else
BEGIN_ACCEL(1 + vtx_count * 4);
@@ -1888,10 +1868,9 @@ static void FUNC_NAME(RadeonComposite)(PixmapPtr pDst,
xFixedToFloat(srcTopRight.x) / info->texW[0], xFixedToFloat(srcTopRight.y) / info->texH[0],
xFixedToFloat(maskTopRight.x) / info->texW[1], xFixedToFloat(maskTopRight.y) / info->texH[1]);
- if (IS_R300_VARIANT || IS_AVIVO_VARIANT) {
- OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D | R300_DC_FREE_3D);
- OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN);
- }
+ if (IS_R300_3D || IS_R500_3D)
+ /* flushing is pipelined, free/finish is not */
+ OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D);
#ifdef ACCEL_CP
ADVANCE_RING();
diff --git a/src/radeon_reg.h b/src/radeon_reg.h
index aebc7aca..6ace3429 100644
--- a/src/radeon_reg.h
+++ b/src/radeon_reg.h
@@ -3885,6 +3885,7 @@
#define R300_GB_SELECT 0x401c
#define R300_GB_ENABLE 0x4008
#define R300_GB_AA_CONFIG 0x4020
+#define R400_GB_PIPE_SELECT 0x402c
#define R300_GB_MSPOS0 0x4010
# define R300_MS_X0_SHIFT 0
# define R300_MS_Y0_SHIFT 4
@@ -3942,6 +3943,8 @@
# define R300_ALPHA3_SHADING_GOURAUD (2 << 14)
#define R300_GA_OFFSET 0x4290
+#define R500_SU_REG_DEST 0x42c8
+
#define R300_VAP_CNTL_STATUS 0x2140
# define R300_PVS_BYPASS (1 << 8)
#define R300_VAP_PVS_STATE_FLUSH_REG 0x2284
@@ -3952,6 +3955,7 @@
# define R300_VF_MAX_VTX_NUM_SHIFT 18
# define R300_GL_CLIP_SPACE_DEF (0 << 22)
# define R300_DX_CLIP_SPACE_DEF (1 << 22)
+# define R500_TCL_STATE_OPTIMIZATION (1 << 23)
#define R300_VAP_VTE_CNTL 0x20B0
# define R300_VPORT_X_SCALE_ENA (1 << 0)
# define R300_VPORT_X_OFFSET_ENA (1 << 1)
@@ -4191,6 +4195,8 @@
# define R300_BOUNDARY_EDGE_FLAG_ENA (1 << 18)
#define R300_VAP_PVS_STATE_FLUSH_REG 0x2284
+#define R500_VAP_INDEX_OFFSET 0x208c
+
#define R300_SU_TEX_WRAP 0x42a0
#define R300_SU_POLY_OFFSET_ENABLE 0x42b4
#define R300_SU_CULL_MODE 0x42b8
@@ -4604,12 +4610,19 @@
#define R300_FG_FOG_BLEND 0x4bc0
#define R300_FG_ALPHA_FUNC 0x4bd4
+#define R300_RB2D_DSTCACHE_CTLSTAT 0x342c
+# define R300_DC_FLUSH_2D (1 << 0)
+# define R300_DC_FREE_2D (1 << 2)
+# define R300_RB2D_DC_FLUSH_ALL (R300_DC_FLUSH_2D | R300_DC_FREE_2D)
#define R300_RB3D_DSTCACHE_CTLSTAT 0x4e4c
# define R300_DC_FLUSH_3D (2 << 0)
# define R300_DC_FREE_3D (2 << 2)
+# define R300_RB3D_DC_FLUSH_ALL (R300_DC_FLUSH_3D | R300_DC_FREE_3D)
+# define R300_DC_FINISH_3D (1 << 4)
#define R300_RB3D_ZCACHE_CTLSTAT 0x4f18
# define R300_ZC_FLUSH (1 << 0)
# define R300_ZC_FREE (1 << 1)
+# define R300_ZC_FLUSH_ALL 0x3
#define R300_WAIT_UNTIL 0x1720
# define R300_WAIT_2D_IDLECLEAN (1 << 16)
# define R300_WAIT_3D_IDLECLEAN (1 << 17)
@@ -5177,5 +5190,6 @@
# define R500_RS_IP_COL_FMT_RGBA (0 << 27)
# define R500_RS_IP_OFFSET_EN (1 << 31)
+#define R500_DYN_SCLK_PWMEM_PIPE 0x000d /* PLL */
#endif
diff --git a/src/radeon_textured_videofuncs.c b/src/radeon_textured_videofuncs.c
index 45dc0c93..e2db615d 100644
--- a/src/radeon_textured_videofuncs.c
+++ b/src/radeon_textured_videofuncs.c
@@ -589,7 +589,7 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
(4 << RADEON_CP_VC_CNTL_NUM_SHIFT));
} else {
if (IS_R300_3D || IS_R500_3D)
- BEGIN_RING(4 * VTX_DWORD_COUNT + 6);
+ BEGIN_RING(4 * VTX_DWORD_COUNT + 4);
else
BEGIN_RING(4 * VTX_DWORD_COUNT + 2);
OUT_RING(CP_PACKET3(R200_CP_PACKET3_3D_DRAW_IMMD_2,
@@ -600,7 +600,7 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
}
#else /* ACCEL_CP */
if (IS_R300_3D || IS_R500_3D)
- BEGIN_VIDEO(3 + VTX_DWORD_COUNT * 4);
+ BEGIN_VIDEO(2 + VTX_DWORD_COUNT * 4);
else
BEGIN_VIDEO(1 + VTX_DWORD_COUNT * 4);
@@ -625,10 +625,9 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
VTX_OUT((float)(dstX + dstw), (float)dstY,
xFixedToFloat(srcTopRight.x) / info->texW[0], xFixedToFloat(srcTopRight.y) / info->texH[0]);
- if (IS_R300_3D || IS_R500_3D) {
- OUT_VIDEO_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D | R300_DC_FREE_3D);
- OUT_VIDEO_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN);
- }
+ if (IS_R300_3D || IS_R500_3D)
+ /* flushing is pipelined, free/finish is not */
+ OUT_VIDEO_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D);
#ifdef ACCEL_CP
ADVANCE_RING();