diff options
author | Alex Deucher <alex@botch2.com> | 2008-04-10 13:59:58 -0400 |
---|---|---|
committer | Alex Deucher <alex@botch2.com> | 2008-04-10 13:59:58 -0400 |
commit | d79040906cd25bd494feb5901f465bbd050aa923 (patch) | |
tree | 6b46da5442791a01915f0dffa099188e53be5b3d /src | |
parent | 0a96173cc38e506728d4c3f2dd383ba56e856578 (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
Diffstat (limited to 'src')
-rw-r--r-- | src/radeon.h | 22 | ||||
-rw-r--r-- | src/radeon_accel.c | 27 | ||||
-rw-r--r-- | src/radeon_commonfuncs.c | 55 | ||||
-rw-r--r-- | src/radeon_exa_render.c | 37 | ||||
-rw-r--r-- | src/radeon_reg.h | 14 | ||||
-rw-r--r-- | src/radeon_textured_videofuncs.c | 11 |
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(); |