diff options
-rw-r--r-- | src/atombios_crtc.c | 5 | ||||
-rw-r--r-- | src/legacy_crtc.c | 6 | ||||
-rw-r--r-- | src/radeon_commonfuncs.c | 23 | ||||
-rw-r--r-- | src/radeon_exa_render.c | 8 | ||||
-rw-r--r-- | src/radeon_reg.h | 15 | ||||
-rw-r--r-- | src/radeon_textured_videofuncs.c | 121 |
6 files changed, 124 insertions, 54 deletions
diff --git a/src/atombios_crtc.c b/src/atombios_crtc.c index 620bc8dc..bbd0c0a9 100644 --- a/src/atombios_crtc.c +++ b/src/atombios_crtc.c @@ -513,8 +513,9 @@ atombios_crtc_mode_set(xf86CrtcPtr crtc, 0); OUTREG(AVIVO_D1MODE_VLINE_START_END + radeon_crtc->crtc_offset, - ((0 << AVIVO_D1MODE_VLINE_START_SHIFT) | - (mode->VDisplay << AVIVO_D1MODE_VLINE_END_SHIFT))); + (((0) << AVIVO_D1MODE_VLINE_START_SHIFT) | + ((mode->VDisplay) << AVIVO_D1MODE_VLINE_END_SHIFT) | + AVIVO_D1MODE_VLINE_INV)); } atombios_crtc_set_pll(crtc, adjusted_mode, pll_flags); diff --git a/src/legacy_crtc.c b/src/legacy_crtc.c index 2e7063c1..751b5efc 100644 --- a/src/legacy_crtc.c +++ b/src/legacy_crtc.c @@ -956,7 +956,8 @@ RADEONInitCrtcRegisters(xf86CrtcPtr crtc, RADEONSavePtr save, save->crtc_pitch |= save->crtc_pitch << 16; save->crtc_gui_trig_vline = ((0 << RADEON_CRTC_GUI_TRIG_VLINE_START_SHIFT) | - (mode->CrtcVDisplay << RADEON_CRTC_GUI_TRIG_VLINE_END_SHIFT)); + (mode->CrtcVDisplay << RADEON_CRTC_GUI_TRIG_VLINE_END_SHIFT) | + RADEON_CRTC_GUI_TRIG_VLINE_INV); if (info->IsDellServer) { save->dac2_cntl = info->SavedReg->dac2_cntl; @@ -1150,7 +1151,8 @@ RADEONInitCrtc2Registers(xf86CrtcPtr crtc, RADEONSavePtr save, save->crtc2_pitch |= save->crtc2_pitch << 16; save->crtc2_gui_trig_vline = ((0 << RADEON_CRTC_GUI_TRIG_VLINE_START_SHIFT) | - (mode->CrtcVDisplay << RADEON_CRTC_GUI_TRIG_VLINE_END_SHIFT)); + (mode->CrtcVDisplay << RADEON_CRTC_GUI_TRIG_VLINE_END_SHIFT) | + RADEON_CRTC_GUI_TRIG_VLINE_INV); /* check to see if TV DAC is enabled for another crtc and keep it enabled */ if (save->crtc2_gen_cntl & RADEON_CRTC2_CRT2_ON) diff --git a/src/radeon_commonfuncs.c b/src/radeon_commonfuncs.c index 556dba3f..7f32acde 100644 --- a/src/radeon_commonfuncs.c +++ b/src/radeon_commonfuncs.c @@ -548,13 +548,8 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn) OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D | R300_DC_FREE_3D); FINISH_ACCEL(); - BEGIN_ACCEL(7); + BEGIN_ACCEL(5); OUT_ACCEL_REG(R300_SC_EDGERULE, 0xA5294A5); - OUT_ACCEL_REG(R300_SC_SCISSOR0, ((0 << R300_SCISSOR_X_SHIFT) | - (0 << R300_SCISSOR_Y_SHIFT))); - OUT_ACCEL_REG(R300_SC_SCISSOR1, ((8191 << R300_SCISSOR_X_SHIFT) | - (8191 << R300_SCISSOR_Y_SHIFT))); - if (IS_R300_3D) { /* clip has offset 1440 */ OUT_ACCEL_REG(R300_SC_CLIP_0_A, ((1088 << R300_CLIP_X_SHIFT) | @@ -575,7 +570,7 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn) (info->ChipFamily == CHIP_FAMILY_RS300) || (info->ChipFamily == CHIP_FAMILY_R200)) { - BEGIN_ACCEL(7); + BEGIN_ACCEL(6); if (info->ChipFamily == CHIP_FAMILY_RS300) { OUT_ACCEL_REG(R200_SE_VAP_CNTL_STATUS, RADEON_TCL_BYPASS); } else { @@ -584,7 +579,6 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn) OUT_ACCEL_REG(R200_PP_CNTL_X, 0); OUT_ACCEL_REG(R200_PP_TXMULTI_CTL_0, 0); OUT_ACCEL_REG(R200_SE_VTX_STATE_CNTL, 0); - OUT_ACCEL_REG(R200_RE_CNTL, 0x0); OUT_ACCEL_REG(R200_SE_VTE_CNTL, 0); OUT_ACCEL_REG(R200_SE_VAP_CNTL, R200_VAP_FORCE_W_TO_ONE | R200_VAP_VF_MAX_VTX_NUM); @@ -602,6 +596,15 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn) RADEON_ROUND_MODE_ROUND | RADEON_ROUND_PREC_4TH_PIX)); FINISH_ACCEL(); + + BEGIN_ACCEL(4); + OUT_ACCEL_REG(R200_RE_SCISSOR_TL_0, ((0 << R200_SCISSOR_X_SHIFT) | + (0 << R200_SCISSOR_Y_SHIFT))); + OUT_ACCEL_REG(R200_RE_SCISSOR_BR_0, ((2047 << R200_SCISSOR_X_SHIFT) | + (2047 << R200_SCISSOR_Y_SHIFT))); + OUT_ACCEL_REG(R200_RE_AUX_SCISSOR_CNTL, R200_SCISSOR_ENABLE_0); + OUT_ACCEL_REG(R200_RE_CNTL, R200_SCISSOR_ENABLE); + FINISH_ACCEL(); } else { BEGIN_ACCEL(2); if ((info->ChipFamily == CHIP_FAMILY_RADEON) || @@ -657,10 +660,10 @@ void FUNC_NAME(RADEONWaitForVLine)(ScrnInfoPtr pScrn, PixmapPtr pPix, int crtc) if (offset == 0) { BEGIN_ACCEL(1); if (crtc == 0) - OUT_ACCEL_REG(RADEON_WAIT_UNTIL, (RADEON_WAIT_FE_CRTC_VLINE | + OUT_ACCEL_REG(RADEON_WAIT_UNTIL, (RADEON_WAIT_CRTC_VLINE | RADEON_ENG_DISPLAY_SELECT_CRTC0)); else - OUT_ACCEL_REG(RADEON_WAIT_UNTIL, (RADEON_WAIT_FE_CRTC_VLINE | + OUT_ACCEL_REG(RADEON_WAIT_UNTIL, (RADEON_WAIT_CRTC_VLINE | RADEON_ENG_DISPLAY_SELECT_CRTC1)); FINISH_ACCEL(); } diff --git a/src/radeon_exa_render.c b/src/radeon_exa_render.c index 895958cc..5d3f737e 100644 --- a/src/radeon_exa_render.c +++ b/src/radeon_exa_render.c @@ -1864,6 +1864,14 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture, FINISH_ACCEL(); } + /* Clear out scissoring */ + BEGIN_ACCEL(2); + OUT_ACCEL_REG(R300_SC_SCISSOR0, ((0 << R300_SCISSOR_X_SHIFT) | + (0 << R300_SCISSOR_Y_SHIFT))); + OUT_ACCEL_REG(R300_SC_SCISSOR1, ((8191 << R300_SCISSOR_X_SHIFT) | + (8191 << R300_SCISSOR_Y_SHIFT))); + FINISH_ACCEL(); + BEGIN_ACCEL(3); OUT_ACCEL_REG(R300_RB3D_COLOROFFSET0, dst_offset); diff --git a/src/radeon_reg.h b/src/radeon_reg.h index bcb83ea4..92bbccca 100644 --- a/src/radeon_reg.h +++ b/src/radeon_reg.h @@ -2290,6 +2290,14 @@ # define R200_VTX_STQ3_D3D 0x00400000 # define R200_VTX_STQ4_D3D 0x01000000 # define R200_VTX_STQ5_D3D 0x04000000 +#define R200_RE_SCISSOR_TL_0 0x1cd8 +#define R200_RE_SCISSOR_BR_0 0x1cdc +#define R200_RE_SCISSOR_TL_1 0x1ce0 +#define R200_RE_SCISSOR_BR_1 0x1ce4 +#define R200_RE_SCISSOR_TL_2 0x1ce8 +#define R200_RE_SCISSOR_BR_2 0x1cec +# define R200_SCISSOR_X_SHIFT 0 +# define R200_SCISSOR_Y_SHIFT 16 #define RADEON_SE_CNTL_STATUS 0x2140 # define RADEON_VC_NO_SWAP (0 << 0) # define RADEON_VC_16BIT_SWAP (1 << 0) @@ -2589,6 +2597,13 @@ # define R200_VC_NO_SWAP (0 << 0) # define R200_VC_16BIT_SWAP (1 << 0) # define R200_VC_32BIT_SWAP (2 << 0) +#define R200_RE_AUX_SCISSOR_CNTL 0x26f0 +# define R200_EXCLUSIVE_SCISSOR_0 0x01000000 +# define R200_EXCLUSIVE_SCISSOR_1 0x02000000 +# define R200_EXCLUSIVE_SCISSOR_2 0x04000000 +# define R200_SCISSOR_ENABLE_0 0x10000000 +# define R200_SCISSOR_ENABLE_1 0x20000000 +# define R200_SCISSOR_ENABLE_2 0x40000000 #define R200_PP_TXFILTER_0 0x2c00 #define R200_PP_TXFILTER_1 0x2c20 #define R200_PP_TXFILTER_2 0x2c40 diff --git a/src/radeon_textured_videofuncs.c b/src/radeon_textured_videofuncs.c index edd322b3..ddf2df63 100644 --- a/src/radeon_textured_videofuncs.c +++ b/src/radeon_textured_videofuncs.c @@ -1475,6 +1475,44 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv } } + /* + * Rendering of the actual polygon is done in two different + * ways depending on chip generation: + * + * < R300: + * + * These chips can render a rectangle in one pass, so + * handling is pretty straight-forward. + * + * >= R300: + * + * These chips can accept a quad, but will render it as + * two triangles which results in a diagonal tear. Instead + * We render a single, large triangle and use the scissor + * functionality to restrict it to the desired rectangle. + */ + + if (IS_R300_3D || IS_R500_3D) { + /* + * Set up the scissor area to that of the output size. + */ + + BEGIN_ACCEL(2); + if (IS_R300_3D) { + /* R300 has an offset */ + OUT_ACCEL_REG(R300_SC_SCISSOR0, (((pPriv->drw_x + 1088) << R300_SCISSOR_X_SHIFT) | + ((pPriv->drw_y + 1088) << R300_SCISSOR_Y_SHIFT))); + OUT_ACCEL_REG(R300_SC_SCISSOR1, (((pPriv->drw_x + pPriv->dst_w + 1088 - 1) << R300_SCISSOR_X_SHIFT) | + ((pPriv->drw_y + pPriv->dst_h + 1088 - 1) << R300_SCISSOR_Y_SHIFT))); + } else { + OUT_ACCEL_REG(R300_SC_SCISSOR0, (((pPriv->drw_x) << R300_SCISSOR_X_SHIFT) | + ((pPriv->drw_y) << R300_SCISSOR_Y_SHIFT))); + OUT_ACCEL_REG(R300_SC_SCISSOR1, (((pPriv->drw_x + pPriv->dst_w - 1) << R300_SCISSOR_X_SHIFT) | + ((pPriv->drw_y + pPriv->dst_h - 1) << R300_SCISSOR_Y_SHIFT))); + } + FINISH_ACCEL(); + } + FUNC_NAME(RADEONWaitForVLine)(pScrn, pPixmap, radeon_covering_crtc_num(pScrn, pPriv->drw_x, @@ -1486,7 +1524,6 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv while (nBox--) { int srcX, srcY, srcw, srch; int dstX, dstY, dstw, dsth; - xPointFixed srcTopLeft, srcTopRight, srcBottomLeft, srcBottomRight; dstX = pBox->x1 + dstxoff; dstY = pBox->y1 + dstyoff; dstw = pBox->x2 - pBox->x1; @@ -1500,16 +1537,6 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv srcw = (pPriv->src_w * dstw) / pPriv->dst_w; srch = (pPriv->src_h * dsth) / pPriv->dst_h; - srcTopLeft.x = IntToxFixed(srcX); - srcTopLeft.y = IntToxFixed(srcY); - srcTopRight.x = IntToxFixed(srcX + srcw); - srcTopRight.y = IntToxFixed(srcY); - srcBottomLeft.x = IntToxFixed(srcX); - srcBottomLeft.y = IntToxFixed(srcY + srch); - srcBottomRight.x = IntToxFixed(srcX + srcw); - srcBottomRight.y = IntToxFixed(srcY + srch); - - #if 0 ErrorF("dst: %d, %d, %d, %d\n", dstX, dstY, dstw, dsth); ErrorF("src: %d, %d, %d, %d\n", srcX, srcY, srcw, srch); @@ -1528,12 +1555,12 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE | (3 << RADEON_CP_VC_CNTL_NUM_SHIFT)); } else if (IS_R300_3D || IS_R500_3D) { - BEGIN_RING(4 * vtx_count + 4); - OUT_RING(CP_PACKET3(R200_CP_PACKET3_3D_DRAW_IMMD_2, - 4 * vtx_count)); - OUT_RING(RADEON_CP_VC_CNTL_PRIM_TYPE_QUAD_LIST | - RADEON_CP_VC_CNTL_PRIM_WALK_RING | - (4 << RADEON_CP_VC_CNTL_NUM_SHIFT)); + BEGIN_RING(3 * vtx_count + 4); + OUT_RING(CP_PACKET3(R200_CP_PACKET3_3D_DRAW_IMMD_2, + 3 * vtx_count)); + OUT_RING(RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST | + RADEON_CP_VC_CNTL_PRIM_WALK_RING | + (3 << RADEON_CP_VC_CNTL_NUM_SHIFT)); } else { BEGIN_RING(3 * vtx_count + 2); OUT_RING(CP_PACKET3(R200_CP_PACKET3_3D_DRAW_IMMD_2, @@ -1544,7 +1571,7 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv } #else /* ACCEL_CP */ if (IS_R300_3D || IS_R500_3D) - BEGIN_ACCEL(2 + vtx_count * 4); + BEGIN_ACCEL(2 + vtx_count * 3); else BEGIN_ACCEL(1 + vtx_count * 3); @@ -1554,9 +1581,9 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv RADEON_VF_RADEON_MODE | (3 << RADEON_VF_NUM_VERTICES_SHIFT))); else if (IS_R300_3D || IS_R500_3D) - OUT_ACCEL_REG(RADEON_SE_VF_CNTL, (RADEON_VF_PRIM_TYPE_QUAD_LIST | + OUT_ACCEL_REG(RADEON_SE_VF_CNTL, (RADEON_VF_PRIM_TYPE_TRIANGLE_LIST | RADEON_VF_PRIM_WALK_DATA | - (4 << RADEON_VF_NUM_VERTICES_SHIFT))); + (3 << RADEON_VF_NUM_VERTICES_SHIFT))); else OUT_ACCEL_REG(RADEON_SE_VF_CNTL, (RADEON_VF_PRIM_TYPE_RECTANGLE_LIST | RADEON_VF_PRIM_WALK_DATA | @@ -1564,29 +1591,43 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv #endif if (pPriv->bicubic_enabled) { - VTX_OUT_FILTER((float)dstX, (float)dstY, - xFixedToFloat(srcTopLeft.x) / info->accel_state->texW[0], xFixedToFloat(srcTopLeft.y) / info->accel_state->texH[0], - xFixedToFloat(srcTopLeft.x) + 0.5, xFixedToFloat(srcTopLeft.y) + 0.5); - VTX_OUT_FILTER((float)dstX, (float)(dstY + dsth), - xFixedToFloat(srcBottomLeft.x) / info->accel_state->texW[0], xFixedToFloat(srcBottomLeft.y) / info->accel_state->texH[0], - xFixedToFloat(srcBottomLeft.x) + 0.5, xFixedToFloat(srcBottomLeft.y) + 0.5); - VTX_OUT_FILTER((float)(dstX + dstw), (float)(dstY + dsth), - xFixedToFloat(srcBottomRight.x) / info->accel_state->texW[0], xFixedToFloat(srcBottomRight.y) / info->accel_state->texH[0], - xFixedToFloat(srcBottomRight.x) + 0.5, xFixedToFloat(srcBottomRight.y) + 0.5); - VTX_OUT_FILTER((float)(dstX + dstw), (float)dstY, - xFixedToFloat(srcTopRight.x) / info->accel_state->texW[0], xFixedToFloat(srcTopRight.y) / info->accel_state->texH[0], - xFixedToFloat(srcTopRight.x) + 0.5, xFixedToFloat(srcTopRight.y) + 0.5); + /* + * This code is only executed on >= R200, so we don't + * have to deal with the legacy handling. + */ + VTX_OUT_FILTER((float)dstX, (float)dstY, + (float)srcX / info->accel_state->texW[0], (float)srcY / info->accel_state->texH[0], + (float)srcX + 0.5, (float)srcY + 0.5); + VTX_OUT_FILTER((float)dstX, (float)(dstY + dsth * 2), + (float)srcX / info->accel_state->texW[0], (float)(srcY + srch * 2) / info->accel_state->texH[0], + (float)srcX + 0.5, (float)(srcY + srch * 2) + 0.5); + VTX_OUT_FILTER((float)(dstX + dstw * 2), (float)dstY, + (float)(srcX + srcw * 2) / info->accel_state->texW[0], (float)srcY / info->accel_state->texH[0], + (float)(srcX + srcw * 2) + 0.5, (float)srcY + 0.5); } else { if (IS_R300_3D || IS_R500_3D) { - VTX_OUT((float)dstX, (float)dstY, - xFixedToFloat(srcTopLeft.x) / info->accel_state->texW[0], xFixedToFloat(srcTopLeft.y) / info->accel_state->texH[0]); + /* + * Render a big, scissored triangle. This means + * doubling the triangle size and adjusting + * texture coordinates. + */ + VTX_OUT((float)dstX, (float)dstY, + (float)srcX / info->accel_state->texW[0], (float)srcY / info->accel_state->texH[0]); + VTX_OUT((float)dstX, (float)(dstY + dsth * 2), + (float)srcX / info->accel_state->texW[0], (float)(srcY + srch * 2) / info->accel_state->texH[0]); + VTX_OUT((float)(dstX + dstw * 2), (float)dstY, + (float)(srcX + srcw * 2) / info->accel_state->texW[0], (float)srcY / info->accel_state->texH[0]); + } else { + /* + * Just render a quad (using three coords). + */ + VTX_OUT((float)dstX, (float)(dstY + dsth), + (float)srcX / info->accel_state->texW[0], (float)(srcY + srch) / info->accel_state->texH[0]); + VTX_OUT((float)(dstX + dstw), (float)(dstY + dsth), + (float)(srcX + srcw) / info->accel_state->texW[0], (float)(srcY + srch) / info->accel_state->texH[0]); + VTX_OUT((float)(dstX + dstw), (float)dstY, + (float)(srcX + srcw) / info->accel_state->texW[0], (float)srcY / info->accel_state->texH[0]); } - VTX_OUT((float)dstX, (float)(dstY + dsth), - xFixedToFloat(srcBottomLeft.x) / info->accel_state->texW[0], xFixedToFloat(srcBottomLeft.y) / info->accel_state->texH[0]); - VTX_OUT((float)(dstX + dstw), (float)(dstY + dsth), - xFixedToFloat(srcBottomRight.x) / info->accel_state->texW[0], xFixedToFloat(srcBottomRight.y) / info->accel_state->texH[0]); - VTX_OUT((float)(dstX + dstw), (float)dstY, - xFixedToFloat(srcTopRight.x) / info->accel_state->texW[0], xFixedToFloat(srcTopRight.y) / info->accel_state->texH[0]); } if (IS_R300_3D || IS_R500_3D) |