summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/atombios_crtc.c5
-rw-r--r--src/legacy_crtc.c6
-rw-r--r--src/radeon_commonfuncs.c23
-rw-r--r--src/radeon_exa_render.c8
-rw-r--r--src/radeon_reg.h15
-rw-r--r--src/radeon_textured_videofuncs.c121
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)