diff --git a/src/atombios_crtc.c b/src/atombios_crtc.c index 4e2395f..bbd0c0a 100644 --- a/src/atombios_crtc.c +++ b/src/atombios_crtc.c @@ -511,6 +511,11 @@ atombios_crtc_mode_set(xf86CrtcPtr crtc, else OUTREG(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0); + + OUTREG(AVIVO_D1MODE_VLINE_START_END + radeon_crtc->crtc_offset, + (((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 75ab6c8..2e7063c 100644 --- a/src/legacy_crtc.c +++ b/src/legacy_crtc.c @@ -133,8 +133,10 @@ RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn, OUTREG(RADEON_CRTC_V_TOTAL_DISP, restore->crtc_v_total_disp); OUTREG(RADEON_CRTC_V_SYNC_STRT_WID, restore->crtc_v_sync_strt_wid); + OUTREG(RADEON_CRTC_GUI_TRIG_VLINE, restore->crtc_gui_trig_vline); + if (IS_R300_VARIANT) - OUTREG(R300_CRTC_TILE_X0_Y0, restore->crtc_tile_x0_y0); + OUTREG(R300_CRTC_TILE_X0_Y0, restore->crtc_tile_x0_y0); OUTREG(RADEON_CRTC_OFFSET_CNTL, restore->crtc_offset_cntl); OUTREG(RADEON_CRTC_OFFSET, restore->crtc_offset); @@ -177,11 +179,13 @@ RADEONRestoreCrtc2Registers(ScrnInfoPtr pScrn, OUTREG(RADEON_CRTC2_V_TOTAL_DISP, restore->crtc2_v_total_disp); OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, restore->crtc2_v_sync_strt_wid); + OUTREG(RADEON_CRTC2_GUI_TRIG_VLINE, restore->crtc2_gui_trig_vline); + OUTREG(RADEON_FP_H2_SYNC_STRT_WID, restore->fp_h2_sync_strt_wid); OUTREG(RADEON_FP_V2_SYNC_STRT_WID, restore->fp_v2_sync_strt_wid); if (IS_R300_VARIANT) - OUTREG(R300_CRTC2_TILE_X0_Y0, restore->crtc2_tile_x0_y0); + OUTREG(R300_CRTC2_TILE_X0_Y0, restore->crtc2_tile_x0_y0); OUTREG(RADEON_CRTC2_OFFSET_CNTL, restore->crtc2_offset_cntl); OUTREG(RADEON_CRTC2_OFFSET, restore->crtc2_offset); @@ -518,6 +522,8 @@ RADEONSaveCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) save->crtc_v_total_disp = INREG(RADEON_CRTC_V_TOTAL_DISP); save->crtc_v_sync_strt_wid = INREG(RADEON_CRTC_V_SYNC_STRT_WID); + save->crtc_gui_trig_vline = INREG(RADEON_CRTC_GUI_TRIG_VLINE); + save->crtc_offset = INREG(RADEON_CRTC_OFFSET); save->crtc_offset_cntl = INREG(RADEON_CRTC_OFFSET_CNTL); save->crtc_pitch = INREG(RADEON_CRTC_PITCH); @@ -553,6 +559,9 @@ RADEONSaveCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save) save->crtc2_h_sync_strt_wid = INREG(RADEON_CRTC2_H_SYNC_STRT_WID); save->crtc2_v_total_disp = INREG(RADEON_CRTC2_V_TOTAL_DISP); save->crtc2_v_sync_strt_wid = INREG(RADEON_CRTC2_V_SYNC_STRT_WID); + + save->crtc2_gui_trig_vline = INREG(RADEON_CRTC2_GUI_TRIG_VLINE); + save->crtc2_offset = INREG(RADEON_CRTC2_OFFSET); save->crtc2_offset_cntl = INREG(RADEON_CRTC2_OFFSET_CNTL); save->crtc2_pitch = INREG(RADEON_CRTC2_PITCH); @@ -946,6 +955,9 @@ RADEONInitCrtcRegisters(xf86CrtcPtr crtc, RADEONSavePtr save, (pScrn->bitsPerPixel * 8)); 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)); + if (info->IsDellServer) { save->dac2_cntl = info->SavedReg->dac2_cntl; save->tv_dac_cntl = info->SavedReg->tv_dac_cntl; @@ -1137,6 +1149,9 @@ RADEONInitCrtc2Registers(xf86CrtcPtr crtc, RADEONSavePtr save, ((pScrn->bitsPerPixel * 8) -1)) / (pScrn->bitsPerPixel * 8); 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)); + /* check to see if TV DAC is enabled for another crtc and keep it enabled */ if (save->crtc2_gen_cntl & RADEON_CRTC2_CRT2_ON) save->crtc2_gen_cntl = RADEON_CRTC2_CRT2_ON; diff --git a/src/radeon.h b/src/radeon.h index f7ae1a8..16ec6d4 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -938,8 +938,10 @@ extern Bool radeon_card_posted(ScrnInfoPtr pScrn); /* radeon_commonfuncs.c */ #ifdef XF86DRI extern void RADEONWaitForIdleCP(ScrnInfoPtr pScrn); +extern void RADEONWaitForVLineCP(ScrnInfoPtr pScrn, PixmapPtr pPix, int crtc); #endif extern void RADEONWaitForIdleMMIO(ScrnInfoPtr pScrn); +extern void RADEONWaitForVLineMMIO(ScrnInfoPtr pScrn, PixmapPtr pPix, int crtc); /* radeon_crtc.c */ extern void radeon_crtc_dpms(xf86CrtcPtr crtc, int mode); diff --git a/src/radeon_commonfuncs.c b/src/radeon_commonfuncs.c index dba197e..0fc77c5 100644 --- a/src/radeon_commonfuncs.c +++ b/src/radeon_commonfuncs.c @@ -667,6 +667,39 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn) } +/* inserts a wait for vline in the command stream */ +void FUNC_NAME(RADEONWaitForVLine)(ScrnInfoPtr pScrn, PixmapPtr pPix, int crtc) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + uint32_t offset; + ACCEL_PREAMBLE(); + + if ((crtc < 0) || (crtc > 1)) + return; + + if (!xf86_config->crtc[crtc]->enabled) + return; + +#ifdef USE_EXA + if (info->useEXA) + offset = exaGetPixmapOffset(pPix); + else +#endif + offset = pPix->devPrivate.ptr - info->FB; + + /* if drawing to front buffer */ + if (offset == 0) { + BEGIN_ACCEL(1); + if (crtc == 0) + OUT_ACCEL_REG(RADEON_WAIT_UNTIL, (RADEON_WAIT_CRTC_VLINE | + RADEON_ENG_DISPLAY_SELECT_CRTC0)); + else + OUT_ACCEL_REG(RADEON_WAIT_UNTIL, (RADEON_WAIT_CRTC_VLINE | + RADEON_ENG_DISPLAY_SELECT_CRTC1)); + FINISH_ACCEL(); + } +} /* MMIO: * diff --git a/src/radeon_exa.c b/src/radeon_exa.c index 0f86fdd..d712334 100644 --- a/src/radeon_exa.c +++ b/src/radeon_exa.c @@ -192,6 +192,38 @@ Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix, uint32_t *pitch_offset) return RADEONGetOffsetPitch(pPix, bpp, pitch_offset, offset, pitch); } +/* + * Used for vblank render stalling. + * Ideally we'd have one pixmap per crtc. + * syncing per-blit is unrealistic so, + * we sync to whichever crtc has a larger area. + */ +int RADEONBiggerCrtcArea(PixmapPtr pPix) +{ + /* Just disable wait in EXA -- CRTC 3 is non-existent. + * TODO: proper EXA disable, this is ugly hack. + */ + return 3; + + ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum]; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int c, crtc_num = -1, area = 0; + + for (c = 0; c < xf86_config->num_crtc; c++) { + xf86CrtcPtr crtc = xf86_config->crtc[c]; + + if (!crtc->enabled) + continue; + + if ((crtc->mode.HDisplay * crtc->mode.VDisplay) > area) { + area = crtc->mode.HDisplay * crtc->mode.VDisplay; + crtc_num = c; + } + } + + return crtc_num; +} + #if X_BYTE_ORDER == X_BIG_ENDIAN static unsigned long swapper_surfaces[3]; diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c index 62224d0..76d6c41 100644 --- a/src/radeon_exa_funcs.c +++ b/src/radeon_exa_funcs.c @@ -117,6 +117,8 @@ FUNC_NAME(RADEONPrepareSolid)(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, dst_pitch_offset); FINISH_ACCEL(); + FUNC_NAME(RADEONWaitForVLine)(pScrn, pPix, RADEONBiggerCrtcArea(pPix)); + return TRUE; } @@ -205,6 +207,8 @@ FUNC_NAME(RADEONPrepareCopy)(PixmapPtr pSrc, PixmapPtr pDst, FUNC_NAME(RADEONDoPrepareCopy)(pScrn, src_pitch_offset, dst_pitch_offset, datatype, rop, planemask); + FUNC_NAME(RADEONWaitForVLine)(pScrn, pDst, RADEONBiggerCrtcArea(pDst)); + return TRUE; } @@ -264,7 +268,7 @@ FUNC_NAME(RADEONUploadToScreen)(PixmapPtr pDst, int x, int y, int w, int h, unsigned int hpass; uint32_t buf_pitch, dst_pitch_off; #endif -#if X_BYTE_ORDER == X_BIG_ENDIAN +#if X_BYTE_ORDER == X_BIG_ENDIAN unsigned char *RADEONMMIO = info->MMIO; unsigned int swapper = info->ModeReg->surface_cntl & ~(RADEON_NONSURF_AP0_SWP_32BPP | RADEON_NONSURF_AP1_SWP_32BPP | @@ -284,6 +288,9 @@ FUNC_NAME(RADEONUploadToScreen)(PixmapPtr pDst, int x, int y, int w, int h, ACCEL_PREAMBLE(); RADEON_SWITCH_TO_2D(); + + FUNC_NAME(RADEONWaitForVLine)(pScrn, pDst, RADEONBiggerCrtcArea(pDst)); + while ((buf = RADEONHostDataBlit(pScrn, cpp, w, dst_pitch_off, &buf_pitch, x, &y, (unsigned int*)&h, &hpass)) != 0) { diff --git a/src/radeon_exa_render.c b/src/radeon_exa_render.c index 97199ae..8b76424 100644 --- a/src/radeon_exa_render.c +++ b/src/radeon_exa_render.c @@ -624,6 +624,8 @@ static Bool FUNC_NAME(R100PrepareComposite)(int op, OUT_ACCEL_REG(RADEON_RB3D_BLENDCNTL, blendcntl); FINISH_ACCEL(); + FUNC_NAME(RADEONWaitForVLine)(pScrn, pDst, RADEONBiggerCrtcArea(pDst)); + return TRUE; } @@ -930,6 +932,8 @@ static Bool FUNC_NAME(R200PrepareComposite)(int op, PicturePtr pSrcPicture, OUT_ACCEL_REG(RADEON_RB3D_BLENDCNTL, blendcntl); FINISH_ACCEL(); + FUNC_NAME(RADEONWaitForVLine)(pScrn, pDst, RADEONBiggerCrtcArea(pDst)); + return TRUE; } @@ -1839,6 +1843,8 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture, FINISH_ACCEL(); + FUNC_NAME(RADEONWaitForVLine)(pScrn, pDst, RADEONBiggerCrtcArea(pDst)); + return TRUE; } diff --git a/src/radeon_probe.h b/src/radeon_probe.h index c14241e..7ecfdb3 100644 --- a/src/radeon_probe.h +++ b/src/radeon_probe.h @@ -438,6 +438,7 @@ typedef struct { uint32_t crtc_h_sync_strt_wid; uint32_t crtc_v_total_disp; uint32_t crtc_v_sync_strt_wid; + uint32_t crtc_gui_trig_vline; uint32_t crtc_offset; uint32_t crtc_offset_cntl; uint32_t crtc_pitch; @@ -459,6 +460,7 @@ typedef struct { uint32_t crtc2_h_sync_strt_wid; uint32_t crtc2_v_total_disp; uint32_t crtc2_v_sync_strt_wid; + uint32_t crtc2_gui_trig_vline; uint32_t crtc2_offset; uint32_t crtc2_offset_cntl; uint32_t crtc2_pitch; diff --git a/src/radeon_reg.h b/src/radeon_reg.h index 19f9869..876b721 100644 --- a/src/radeon_reg.h +++ b/src/radeon_reg.h @@ -401,6 +401,9 @@ # define RADEON_CRTC_H_CUTOFF_ACTIVE_EN (1<<4) # define RADEON_CRTC_V_CUTOFF_ACTIVE_EN (1<<5) #define RADEON_CRTC_GUI_TRIG_VLINE 0x0218 +# define RADEON_CRTC_GUI_TRIG_VLINE_START_SHIFT 0 +# define RADEON_CRTC_GUI_TRIG_VLINE_END_SHIFT 16 +# define RADEON_CRTC_GUI_TRIG_VLINE_INV (1 << 15) #define RADEON_CRTC_H_SYNC_STRT_WID 0x0204 # define RADEON_CRTC_H_SYNC_STRT_PIX (0x07 << 0) # define RADEON_CRTC_H_SYNC_STRT_CHAR (0x3ff << 3) @@ -3619,6 +3622,10 @@ #define AVIVO_D1MODE_DATA_FORMAT 0x6528 # define AVIVO_D1MODE_INTERLEAVE_EN (1 << 0) #define AVIVO_D1MODE_DESKTOP_HEIGHT 0x652c +#define AVIVO_D1MODE_VLINE_START_END 0x6538 +# define AVIVO_D1MODE_VLINE_START_SHIFT 0 +# define AVIVO_D1MODE_VLINE_END_SHIFT 16 +# define AVIVO_D1MODE_VLINE_INV (1 << 31) #define AVIVO_D1MODE_VIEWPORT_START 0x6580 #define AVIVO_D1MODE_VIEWPORT_SIZE 0x6584 #define AVIVO_D1MODE_EXT_OVERSCAN_LEFT_RIGHT 0x6588 diff --git a/src/radeon_textured_videofuncs.c b/src/radeon_textured_videofuncs.c index c5ad0e1..1660138 100644 --- a/src/radeon_textured_videofuncs.c +++ b/src/radeon_textured_videofuncs.c @@ -1123,6 +1123,45 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv } } + /* + * Rendering of the actual polygon is done in two different + * ways depending on chip generation: + * + * < R200: + * + * These chips can render a rectangle in one pass, so + * handling is pretty straight-forward. + * + * >= R200: + * + * 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 (info->ChipFamily >= CHIP_FAMILY_R200) { + /* + * Set up the scissor area to that of the output size. + */ + + /* FIXME: What's with the offsets? */ + BEGIN_ACCEL(2); + OUT_ACCEL_REG(R300_SC_SCISSOR0, (((pPriv->drw_x + 1024 + 64) << R300_SCISSOR_X_SHIFT) | + ((pPriv->drw_y + 1024 + 64) << R300_SCISSOR_Y_SHIFT))); + OUT_ACCEL_REG(R300_SC_SCISSOR1, (((pPriv->drw_x + pPriv->dst_w + 1024 + 64 - 1) << R300_SCISSOR_X_SHIFT) | + ((pPriv->drw_y + pPriv->dst_h + 1024 + 64 - 1) << R300_SCISSOR_Y_SHIFT))); + FINISH_ACCEL(); + } + + FUNC_NAME(RADEONWaitForVLine)(pScrn, pPixmap, + radeon_covering_crtc_num(pScrn, + pPriv->drw_x, + pPriv->drw_x + pPriv->dst_w, + pPriv->drw_y, + pPriv->drw_y + pPriv->dst_h, + pPriv->desired_crtc)); + while (nBox--) { int srcX, srcY, srcw, srch; int dstX, dstY, dstw, dsth; @@ -1169,22 +1208,22 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv (3 << RADEON_CP_VC_CNTL_NUM_SHIFT)); } else { if (IS_R300_3D || IS_R500_3D) - BEGIN_RING(4 * vtx_count + 4); + BEGIN_RING(3 * vtx_count + 4); else - BEGIN_RING(4 * vtx_count + 2); + BEGIN_RING(3 * vtx_count + 2); OUT_RING(CP_PACKET3(R200_CP_PACKET3_3D_DRAW_IMMD_2, - 4 * vtx_count)); - OUT_RING(RADEON_CP_VC_CNTL_PRIM_TYPE_QUAD_LIST | + 3 * vtx_count)); + OUT_RING(RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST | RADEON_CP_VC_CNTL_PRIM_WALK_RING | - (4 << RADEON_CP_VC_CNTL_NUM_SHIFT)); + (3 << RADEON_CP_VC_CNTL_NUM_SHIFT)); } #else /* ACCEL_CP */ if (IS_R300_3D || IS_R500_3D) - BEGIN_ACCEL(2 + vtx_count * 4); + BEGIN_ACCEL(2 + vtx_count * 3); else if (info->ChipFamily < CHIP_FAMILY_R200) BEGIN_ACCEL(1 + vtx_count * 3); else - BEGIN_ACCEL(1 + vtx_count * 4); + BEGIN_ACCEL(1 + vtx_count * 3); if (info->ChipFamily < CHIP_FAMILY_R200) OUT_ACCEL_REG(RADEON_SE_VF_CNTL, (RADEON_VF_PRIM_TYPE_RECTANGLE_LIST | @@ -1192,35 +1231,50 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv RADEON_VF_RADEON_MODE | (3 << RADEON_VF_NUM_VERTICES_SHIFT))); else - 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))); #endif if (pPriv->bicubic_enabled) { + /* + * This code is only executed on >= R200, so we don't + * have to deal with the legacy handling. + */ + fprintf(stderr, "Filtered!\n"); 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) / 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], + VTX_OUT_FILTER((float)dstX, (float)(dstY + dsth * 2), + xFixedToFloat(srcBottomLeft.x) / info->accel_state->texW[0], xFixedToFloat(srcBottomLeft.y) / info->accel_state->texH[0] + 1.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], + VTX_OUT_FILTER((float)(dstX + dstw * 2), (float)dstY, + xFixedToFloat(srcTopRight.x) / info->accel_state->texW[0] + 1.0, xFixedToFloat(srcTopRight.y) / info->accel_state->texH[0], xFixedToFloat(srcTopRight.x) + 0.5, xFixedToFloat(srcTopRight.y) + 0.5); } else { if (info->ChipFamily >= CHIP_FAMILY_R200) { + /* + * Render a big, scissored triangle. This means + * doubling the triangle size and adjusting + * texture coordinates. + */ VTX_OUT((float)dstX, (float)dstY, - xFixedToFloat(srcTopLeft.x) / info->accel_state->texW[0], xFixedToFloat(srcTopLeft.y) / info->accel_state->texH[0]); + xFixedToFloat(srcTopLeft.x) / info->accel_state->texW[0], xFixedToFloat(srcTopLeft.y) / info->accel_state->texH[0]); + VTX_OUT((float)dstX, (float)(dstY + dsth * 2), + xFixedToFloat(srcBottomLeft.x) / info->accel_state->texW[0], xFixedToFloat(srcBottomLeft.y) / info->accel_state->texH[0] + 1.0); + VTX_OUT((float)(dstX + dstw * 2), (float)dstY, + xFixedToFloat(srcTopRight.x) / info->accel_state->texW[0] + 1.0, xFixedToFloat(srcTopRight.y) / info->accel_state->texH[0]); + } else { + /* + * Just render a quad (using three coords). + */ + 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]); } - 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) diff --git a/src/radeon_video.c b/src/radeon_video.c index 6249cea..423ea28 100644 --- a/src/radeon_video.c +++ b/src/radeon_video.c @@ -105,7 +105,6 @@ static Atom xvOvAlpha, xvGrAlpha, xvAlphaMode; #define GET_PORT_PRIVATE(pScrn) \ (RADEONPortPrivPtr)((RADEONPTR(pScrn))->adaptor->pPortPrivates[0].ptr) -#ifndef HAVE_XF86CRTCCLIPVIDEOHELPER static void radeon_box_intersect(BoxPtr dest, BoxPtr a, BoxPtr b) { @@ -136,6 +135,37 @@ radeon_box_area(BoxPtr box) return (int) (box->x2 - box->x1) * (int) (box->y2 - box->y1); } +int +radeon_covering_crtc_num(ScrnInfoPtr pScrn, + int x1, int x2, int y1, int y2, + xf86CrtcPtr desired) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int coverage, best_coverage; + int c, best_crtc = 0; + BoxRec box, crtc_box, cover_box; + + box.x1 = x1; + box.x2 = x2; + box.y1 = y1; + box.y2 = y2; + best_coverage = 0; + for (c = 0; c < xf86_config->num_crtc; c++) { + xf86CrtcPtr crtc = xf86_config->crtc[c]; + radeon_crtc_box(crtc, &crtc_box); + radeon_box_intersect(&cover_box, &crtc_box, &box); + coverage = radeon_box_area(&cover_box); + if (coverage && crtc == desired) { + return c; + } else if (coverage > best_coverage) { + best_crtc = c; + best_coverage = coverage; + } + } + return best_crtc; +} + +#ifndef HAVE_XF86CRTCCLIPVIDEOHELPER static xf86CrtcPtr radeon_covering_crtc(ScrnInfoPtr pScrn, BoxPtr box, diff --git a/src/radeon_video.h b/src/radeon_video.h index 11b8029..a08e4e3 100644 --- a/src/radeon_video.h +++ b/src/radeon_video.h @@ -113,6 +113,11 @@ typedef struct { int drw_x, drw_y; } RADEONPortPrivRec, *RADEONPortPrivPtr; +int +radeon_covering_crtc_num(ScrnInfoPtr pScrn, + int x1, int x2, int y1, int y2, + xf86CrtcPtr desired); + void RADEONInitI2C(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv); void RADEONResetI2C(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv);