diff options
author | Cooper Yuan <cooperyuan@gmail.com> | 2009-09-06 13:16:14 +0800 |
---|---|---|
committer | Cooper Yuan <cooperyuan@gmail.com> | 2009-09-06 13:16:14 +0800 |
commit | 66d6ddcf4d14c0ed46cdf0b699a37657ec210e17 (patch) | |
tree | 3396947c878447d40e77f2ed39999f0cfc02c12f | |
parent | 11889ca4e24471fecff858158f752d4336b5fec3 (diff) |
update ddx driver
48 files changed, 3127 insertions, 1269 deletions
diff --git a/Makefile.am b/Makefile.am index 87e90ba..e76bf11 100644 --- a/Makefile.am +++ b/Makefile.am @@ -27,6 +27,6 @@ CLEANFILES = ChangeLog .PHONY: ChangeLog ChangeLog: - (GIT_DIR=$(top_srcdir)/.git git-log > .changelog.tmp && mv .changelog.tmp ChangeLog; rm -f .changelog.tmp) || (touch ChangeLog; echo 'git directory not found: installing possibly empty changelog.' >&2) + $(CHANGELOG_CMD) dist-hook: ChangeLog @@ -1,20 +1,25 @@ xf86-video-ati - ATI Radeon video driver for the Xorg X server -Please submit bugs & patches to the Xorg bugzilla: - - https://bugs.freedesktop.org/enter_bug.cgi?product=xorg - All questions regarding this software should be directed at the Xorg mailing list: http://lists.freedesktop.org/mailman/listinfo/xorg +Please submit bug reports to the Xorg bugzilla: + + https://bugs.freedesktop.org/enter_bug.cgi?product=xorg + The master development code repository can be found at: git://anongit.freedesktop.org/git/xorg/driver/xf86-video-ati http://cgit.freedesktop.org/xorg/driver/xf86-video-ati +For patch submission instructions, see: + + http://www.x.org/wiki/Development/Documentation/SubmittingPatches + For more information on the git code manager, see: http://wiki.x.org/wiki/GitPage + diff --git a/configure.ac b/configure.ac index fec70e3..66f76aa 100644 --- a/configure.ac +++ b/configure.ac @@ -28,12 +28,20 @@ AC_INIT([xf86-video-ati], AC_CONFIG_SRCDIR([Makefile.am]) AM_CONFIG_HEADER([config.h]) + +# Require xorg-macros: XORG_RELEASE_VERSION XORG_CHANGELOG +m4_ifndef([XORG_MACROS_VERSION], [AC_FATAL([must install xorg-macros 1.2 or later before running autoconf/autogen])]) +XORG_MACROS_VERSION(1.2) + AC_CONFIG_AUX_DIR(.) AM_INIT_AUTOMAKE([dist-bzip2]) +AC_SYS_LARGEFILE AM_MAINTAINER_MODE +AC_CONFIG_FILES([shave shave-libtool]) + # Checks for programs. AC_DISABLE_STATIC AC_PROG_LIBTOOL @@ -62,17 +70,17 @@ AC_ARG_ENABLE(exa, [EXA="$enableval"], [EXA=yes]) +AC_ARG_ENABLE(kms, + AC_HELP_STRING([--disable-kms], + [Disable KMS support [[default=enabled]]]), + [DRM_MODE="$enableval"], + [DRM_MODE=yes]) + AC_ARG_WITH(xserver-source,AC_HELP_STRING([--with-xserver-source=XSERVER_SOURCE], [Path to X server source tree]), [ XSERVER_SOURCE="$withval" ], [ XSERVER_SOURCE="" ]) - -AC_ARG_ENABLE(xvmc, AC_HELP_STRING([--disable-xvmc], - [Disable XvMC support [[default=auto]]]), - [XVMC="$enableval"], - [XVMC=auto]) - # Checks for extensions XORG_DRIVER_CHECK_EXT(XINERAMA, xineramaproto) XORG_DRIVER_CHECK_EXT(RANDR, randrproto) @@ -82,6 +90,10 @@ XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto) # Checks for pkg-config packages PKG_CHECK_MODULES(XORG, [xorg-server >= 1.2 xproto fontsproto $REQUIRED_MODULES]) +PKG_CHECK_MODULES(XEXT, [xextproto >= 7.0.99.1], + HAVE_XEXTPROTO_71="yes"; AC_DEFINE(HAVE_XEXTPROTO_71, 1, [xextproto 7.1 available]), + HAVE_XEXTPROTO_71="no") +AM_CONDITIONAL(HAVE_XEXTPROTO_71, [ test "$HAVE_XEXTPROTO_71" = "yes" ]) sdkdir=$(pkg-config --variable=sdkdir xorg-server) # Checks for libraries. @@ -112,23 +124,6 @@ if test x$DRI = xauto; then fi AC_MSG_RESULT([$DRI]) -if test "$XVMC" = auto; then - XVMC="$DRI" -fi -if test "$XVMC" = yes && test "$DRI" = no; then - AC_MSG_ERROR([XvMC can't be enabled without DRI]) -fi -if test "$XVMC" = yes; then - PKG_CHECK_MODULES(XVMCLIB, [xvmc], [XVMC=yes], [XVMC=no]) -fi -AC_MSG_CHECKING([whether to include XvMC support]) -AC_MSG_RESULT([$XVMC]) -AM_CONDITIONAL(XVMC, test x$XVMC = xyes) -if test "$XVMC" = yes; then - AC_DEFINE(ENABLE_XVMC,1,[Enable XvMC support]) - AC_SUBST([XVMCLIB_CFLAGS]) -fi - AM_CONDITIONAL(DRI, test x$DRI = xyes) if test "$DRI" = yes; then PKG_CHECK_MODULES(DRI, [libdrm >= 2.2 xf86driproto]) @@ -137,6 +132,24 @@ if test "$DRI" = yes; then if test "$have_damage_h" = yes; then AC_DEFINE(DAMAGE,1,[Use Damage extension]) fi + + save_CFLAGS="$CFLAGS" + CFLAGS="$XORG_CFLAGS $DRI_CFLAGS $CFLAGS" + AM_CONDITIONAL(DRM_MODE, test x$DRM_MODE = xyes) + if test "$DRM_MODE" = yes; then + AC_CHECK_HEADER(xf86drmMode.h,[DRM_MODE=yes],[DRM_MODE=no],[#include <stdint.h> +#include <stdlib.h>]) + if test "x$DRM_MODE" = xyes; then + PKG_CHECK_MODULES(LIBDRM_RADEON, [xorg-server >= 1.6.2 libdrm_radeon], + [LIBDRM_RADEON=yes], [LIBDRM_RADEON=no]) + + if test "x$LIBDRM_RADEON" = xyes; then + AC_DEFINE(XF86DRM_MODE,1,[DRM kernel modesetting]) + AC_DEFINE(RADEON_DRI2, 1,[Enable DRI2 code]) + fi + fi + fi + CFLAGS="$save_CFLAGS" fi save_CFLAGS="$CFLAGS" @@ -260,6 +273,8 @@ CPPFLAGS="$SAVE_CPPFLAGS" AM_CONDITIONAL(USE_EXA, test "x$USE_EXA" = xyes) +AM_CONDITIONAL(XF86DRM_MODE, test "x$LIBDRM_RADEON" = xyes) + if test "x$XSERVER_LIBPCIACCESS" = xyes; then PKG_CHECK_MODULES([PCIACCESS], [pciaccess >= 0.8.0]) XORG_CFLAGS="$XORG_CFLAGS $PCIACCESS_CFLAGS" @@ -333,6 +348,8 @@ esac AC_SUBST([XORG_CFLAGS]) AC_SUBST([DRI_CFLAGS]) +AC_SUBST([LIBDRM_RADEON_CFLAGS]) +AC_SUBST([LIBDRM_RADEON_LIBS]) AC_SUBST([moduledir]) DRIVER_NAME=ati @@ -341,6 +358,7 @@ AC_SUBST([DRIVER_NAME]) XORG_MANPAGE_SECTIONS XORG_RELEASE_VERSION XORG_CHECK_LINUXDOC +XORG_CHANGELOG AC_MSG_NOTICE( [The atimisc sub-driver has been split out to xf86-video-mach64:] @@ -354,9 +372,32 @@ AC_MSG_NOTICE( [Please install that driver as well for rage128-based cards.] ) +SHAVE_INIT(.,enable) + AC_OUTPUT([ Makefile src/Makefile man/Makefile - src/xvmc/Makefile ]) + +dnl +dnl Output some configuration info for the user +dnl +echo "" +echo " prefix: $prefix" +echo " exec_prefix: $exec_prefix" +echo " libdir: $libdir" +echo " includedir: $includedir" + + +echo "" +echo " Kernel modesetting: $DRM_MODE" + +echo "" +echo " CFLAGS: $CFLAGS" +echo " CXXFLAGS: $CXXFLAGS" +echo " Macros: $DEFINES" + +echo "" +echo " Run '${MAKE-make}' to build xf86-video-ati" +echo "" diff --git a/src/Makefile.am b/src/Makefile.am index c83da18..57a365b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -26,9 +26,7 @@ # _ladir passes a dummy rpath to libtool so the thing will actually link # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. -radeon_drv_la_LIBADD = - -SUBDIRS = xvmc +radeon_drv_la_LIBADD = $(LIBDRM_RADEON_LIBS) if DRI RADEON_DRI_SRCS = radeon_dri.c @@ -67,6 +65,10 @@ XMODE_SRCS=\ modes/xf86Rotate.c \ modes/xf86DiDGA.c +if XF86DRM_MODE +RADEON_KMS_SRCS=radeon_dri2.c radeon_kms.c drmmode_display.c +endif + if USE_EXA RADEON_EXA_SOURCES = radeon_exa.c r600_exa.c r6xx_accel.c r600_textured_videofuncs.c r600_shader.c endif @@ -94,11 +96,11 @@ radeon_drv_la_SOURCES = \ radeon_driver.c radeon_video.c radeon_bios.c radeon_mm_i2c.c \ radeon_vip.c radeon_misc.c radeon_probe.c \ legacy_crtc.c legacy_output.c \ - r500_hwmc.c \ radeon_textured_video.c radeon_pm.c \ radeon_crtc.c radeon_output.c radeon_modes.c radeon_tv.c \ $(RADEON_ATOMBIOS_SOURCES) radeon_atombios.c radeon_atomwrapper.c \ - $(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES) atombios_output.c atombios_crtc.c + $(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES) atombios_output.c atombios_crtc.c \ + $(RADEON_KMS_SRCS) if XMODES radeon_drv_la_SOURCES += \ @@ -167,4 +169,6 @@ EXTRA_DIST = \ radeon_pci_device_match_gen.h \ pcidb/ati_pciids.csv \ pcidb/parse_pci_ids.pl \ - radeon_atombios.h + radeon_atombios.h \ + radeon_dri2.h \ + drmmode_display.h diff --git a/src/ati_pciids_gen.h b/src/ati_pciids_gen.h index 8b37d5b..3f9691e 100644 --- a/src/ati_pciids_gen.h +++ b/src/ati_pciids_gen.h @@ -354,15 +354,26 @@ #define PCI_CHIP_RV770_946B 0x946B #define PCI_CHIP_RV770_947A 0x947A #define PCI_CHIP_RV770_947B 0x947B +#define PCI_CHIP_RV730_9480 0x9480 #define PCI_CHIP_RV730_9487 0x9487 +#define PCI_CHIP_RV730_9488 0x9488 #define PCI_CHIP_RV730_9489 0x9489 #define PCI_CHIP_RV730_948F 0x948F #define PCI_CHIP_RV730_9490 0x9490 #define PCI_CHIP_RV730_9491 0x9491 +#define PCI_CHIP_RV730_9495 0x9495 #define PCI_CHIP_RV730_9498 0x9498 #define PCI_CHIP_RV730_949C 0x949C #define PCI_CHIP_RV730_949E 0x949E #define PCI_CHIP_RV730_949F 0x949F +#define PCI_CHIP_RV740_94A0 0x94A0 +#define PCI_CHIP_RV740_94A1 0x94A1 +#define PCI_CHIP_RV740_94A3 0x94A3 +#define PCI_CHIP_RV740_94B1 0x94B1 +#define PCI_CHIP_RV740_94B3 0x94B3 +#define PCI_CHIP_RV740_94B4 0x94B4 +#define PCI_CHIP_RV740_94B5 0x94B5 +#define PCI_CHIP_RV740_94B9 0x94B9 #define PCI_CHIP_RV610_94C0 0x94C0 #define PCI_CHIP_RV610_94C1 0x94C1 #define PCI_CHIP_RV610_94C3 0x94C3 @@ -395,6 +406,7 @@ #define PCI_CHIP_RV710_9552 0x9552 #define PCI_CHIP_RV710_9553 0x9553 #define PCI_CHIP_RV710_9555 0x9555 +#define PCI_CHIP_RV710_9557 0x9557 #define PCI_CHIP_RV630_9580 0x9580 #define PCI_CHIP_RV630_9581 0x9581 #define PCI_CHIP_RV630_9583 0x9583 diff --git a/src/atombios_crtc.c b/src/atombios_crtc.c index f331800..341deb4 100644 --- a/src/atombios_crtc.c +++ b/src/atombios_crtc.c @@ -33,8 +33,13 @@ #include "config.h" #endif /* DPMS */ +#ifdef HAVE_XEXTPROTO_71 +#include <X11/extensions/dpmsconst.h> +#else #define DPMS_SERVER #include <X11/extensions/dpms.h> +#endif + #include "radeon.h" #include "radeon_reg.h" @@ -276,6 +281,10 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode) memset(&spc_param, 0, sizeof(spc_param)); if (IS_AVIVO_VARIANT) { + if ((info->ChipFamily == CHIP_FAMILY_RS600) || + (info->ChipFamily == CHIP_FAMILY_RS690) || + (info->ChipFamily == CHIP_FAMILY_RS740)) + pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV | RADEON_PLL_PREFER_CLOSEST_LOWER; if (IS_DCE3_VARIANT && mode->Clock > 200000) /* range limits??? */ pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; else @@ -689,7 +698,8 @@ RADEONInitDispBandwidthAVIVO(ScrnInfoPtr pScrn, uint32_t mc_init_misc_lat_timer = 0; if (info->ChipFamily == CHIP_FAMILY_RV515) mc_init_misc_lat_timer = INMC(pScrn, RV515_MC_INIT_MISC_LAT_TIMER); - else if (info->ChipFamily == CHIP_FAMILY_RS690) + else if ((info->ChipFamily == CHIP_FAMILY_RS690) || + (info->ChipFamily == CHIP_FAMILY_RS740)) mc_init_misc_lat_timer = INMC(pScrn, RS690_MC_INIT_MISC_LAT_TIMER); mc_init_misc_lat_timer &= ~(R300_MC_DISP1R_INIT_LAT_MASK << R300_MC_DISP1R_INIT_LAT_SHIFT); @@ -702,7 +712,8 @@ RADEONInitDispBandwidthAVIVO(ScrnInfoPtr pScrn, if (info->ChipFamily == CHIP_FAMILY_RV515) OUTMC(pScrn, RV515_MC_INIT_MISC_LAT_TIMER, mc_init_misc_lat_timer); - else if (info->ChipFamily == CHIP_FAMILY_RS690) + else if ((info->ChipFamily == CHIP_FAMILY_RS690) || + (info->ChipFamily == CHIP_FAMILY_RS740)) OUTMC(pScrn, RS690_MC_INIT_MISC_LAT_TIMER, mc_init_misc_lat_timer); } @@ -756,9 +767,37 @@ RADEONInitDispBandwidthAVIVO(ScrnInfoPtr pScrn, OUTREG(AVIVO_DC_LB_MEMORY_SPLIT, dc_lb_memory_split); #endif - // fixme - if (info->ChipFamily == CHIP_FAMILY_RS600) + /* fixme + * Still need to implement the actual watermark calculation + * for rs600. This just allows us to force high display + * priority. + */ + if (info->ChipFamily == CHIP_FAMILY_RS600) { + if (info->DispPriority == 2) { + uint32_t priority_cnt; + + if (mode1) { + priority_cnt = INREG(AVIVO_D1MODE_PRIORITY_A_CNT); + priority_cnt |= AVIVO_DxMODE_PRIORITY_ALWAYS_ON; + OUTREG(AVIVO_D1MODE_PRIORITY_A_CNT, priority_cnt); + + priority_cnt = INREG(AVIVO_D1MODE_PRIORITY_B_CNT); + priority_cnt |= AVIVO_DxMODE_PRIORITY_ALWAYS_ON; + OUTREG(AVIVO_D1MODE_PRIORITY_B_CNT, priority_cnt); + } + + if (mode2) { + priority_cnt = INREG(AVIVO_D2MODE_PRIORITY_A_CNT); + priority_cnt |= AVIVO_DxMODE_PRIORITY_ALWAYS_ON; + OUTREG(AVIVO_D2MODE_PRIORITY_A_CNT, priority_cnt); + + priority_cnt = INREG(AVIVO_D2MODE_PRIORITY_B_CNT); + priority_cnt |= AVIVO_DxMODE_PRIORITY_ALWAYS_ON; + OUTREG(AVIVO_D2MODE_PRIORITY_B_CNT, priority_cnt); + } + } return; + } /* IGP bandwidth - get from integrated systems table * SYSTEM_MEMORY_BANDWIDTH (Mbyte/s) = SYSTEM_MEMORY_CLOCK (MHz) * (1+DDR) * 8 * EFF * Num of channels @@ -796,7 +835,7 @@ RADEONInitDispBandwidthAVIVO(ScrnInfoPtr pScrn, float consumption_time, consumption_rate; int num_line_pair, request_fifo_depth, lb_request_fifo_depth; int max_req; - uint32_t lb_max_req_outstanding; + uint32_t lb_max_req_outstanding, priority_cnt; float line_time, active_time, chunk_time; float worst_case_latency, tolerable_latency; float fill_rate; @@ -1120,16 +1159,21 @@ RADEONInitDispBandwidthAVIVO(ScrnInfoPtr pScrn, else if (priority_mark > priority_mark_max) priority_mark = priority_mark_max; + priority_cnt = priority_mark & AVIVO_DxMODE_PRIORITY_MARK_MASK; + + if (info->DispPriority == 2) + priority_cnt |= AVIVO_DxMODE_PRIORITY_ALWAYS_ON; + /*ErrorF("priority_mark %d: 0x%x\n", i, priority_mark);*/ /* Determine which display to program priority mark for */ /* FIXME: program DxMODE_PRIORITY_B_CNT for slower sclk */ if (i == 0) { - OUTREG(AVIVO_D1MODE_PRIORITY_A_CNT, (priority_mark & AVIVO_DxMODE_PRIORITY_MARK_MASK)); - OUTREG(AVIVO_D1MODE_PRIORITY_B_CNT, (priority_mark & AVIVO_DxMODE_PRIORITY_MARK_MASK)); + OUTREG(AVIVO_D1MODE_PRIORITY_A_CNT, priority_cnt); + OUTREG(AVIVO_D1MODE_PRIORITY_B_CNT, priority_cnt); } else { - OUTREG(AVIVO_D2MODE_PRIORITY_A_CNT, (priority_mark & AVIVO_DxMODE_PRIORITY_MARK_MASK)); - OUTREG(AVIVO_D2MODE_PRIORITY_B_CNT, (priority_mark & AVIVO_DxMODE_PRIORITY_MARK_MASK)); + OUTREG(AVIVO_D2MODE_PRIORITY_A_CNT, priority_cnt); + OUTREG(AVIVO_D2MODE_PRIORITY_B_CNT, priority_cnt); } } diff --git a/src/atombios_output.c b/src/atombios_output.c index 158e76f..57345b3 100644 --- a/src/atombios_output.c +++ b/src/atombios_output.c @@ -34,8 +34,13 @@ #include "config.h" #endif /* DPMS */ +#ifdef HAVE_XEXTPROTO_71 +#include <X11/extensions/dpmsconst.h> +#else #define DPMS_SERVER #include <X11/extensions/dpms.h> +#endif + #include <unistd.h> #include "radeon.h" @@ -60,6 +65,8 @@ const char *device_name[12] = { "DFP5", }; +static void atombios_set_output_crtc_source(xf86OutputPtr output); + static int atombios_output_dac_setup(xf86OutputPtr output, int action) { @@ -766,234 +773,238 @@ atombios_output_dig_transmitter_setup(xf86OutputPtr output, int action) } -static void atom_rv515_force_tv_scaler(ScrnInfoPtr pScrn) +static void atom_rv515_force_tv_scaler(ScrnInfoPtr pScrn, RADEONCrtcPrivatePtr radeon_crtc) { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; - - OUTREG(0x659C,0x0); - OUTREG(0x6594,0x705); - OUTREG(0x65A4,0x10001); - OUTREG(0x65D8,0x0); - OUTREG(0x65B0,0x0); - OUTREG(0x65C0,0x0); - OUTREG(0x65D4,0x0); - OUTREG(0x6578,0x0); - OUTREG(0x657C,0x841880A8); - OUTREG(0x6578,0x1); - OUTREG(0x657C,0x84208680); - OUTREG(0x6578,0x2); - OUTREG(0x657C,0xBFF880B0); - OUTREG(0x6578,0x100); - OUTREG(0x657C,0x83D88088); - OUTREG(0x6578,0x101); - OUTREG(0x657C,0x84608680); - OUTREG(0x6578,0x102); - OUTREG(0x657C,0xBFF080D0); - OUTREG(0x6578,0x200); - OUTREG(0x657C,0x83988068); - OUTREG(0x6578,0x201); - OUTREG(0x657C,0x84A08680); - OUTREG(0x6578,0x202); - OUTREG(0x657C,0xBFF080F8); - OUTREG(0x6578,0x300); - OUTREG(0x657C,0x83588058); - OUTREG(0x6578,0x301); - OUTREG(0x657C,0x84E08660); - OUTREG(0x6578,0x302); - OUTREG(0x657C,0xBFF88120); - OUTREG(0x6578,0x400); - OUTREG(0x657C,0x83188040); - OUTREG(0x6578,0x401); - OUTREG(0x657C,0x85008660); - OUTREG(0x6578,0x402); - OUTREG(0x657C,0xBFF88150); - OUTREG(0x6578,0x500); - OUTREG(0x657C,0x82D88030); - OUTREG(0x6578,0x501); - OUTREG(0x657C,0x85408640); - OUTREG(0x6578,0x502); - OUTREG(0x657C,0xBFF88180); - OUTREG(0x6578,0x600); - OUTREG(0x657C,0x82A08018); - OUTREG(0x6578,0x601); - OUTREG(0x657C,0x85808620); - OUTREG(0x6578,0x602); - OUTREG(0x657C,0xBFF081B8); - OUTREG(0x6578,0x700); - OUTREG(0x657C,0x82608010); - OUTREG(0x6578,0x701); - OUTREG(0x657C,0x85A08600); - OUTREG(0x6578,0x702); - OUTREG(0x657C,0x800081F0); - OUTREG(0x6578,0x800); - OUTREG(0x657C,0x8228BFF8); - OUTREG(0x6578,0x801); - OUTREG(0x657C,0x85E085E0); - OUTREG(0x6578,0x802); - OUTREG(0x657C,0xBFF88228); - OUTREG(0x6578,0x10000); - OUTREG(0x657C,0x82A8BF00); - OUTREG(0x6578,0x10001); - OUTREG(0x657C,0x82A08CC0); - OUTREG(0x6578,0x10002); - OUTREG(0x657C,0x8008BEF8); - OUTREG(0x6578,0x10100); - OUTREG(0x657C,0x81F0BF28); - OUTREG(0x6578,0x10101); - OUTREG(0x657C,0x83608CA0); - OUTREG(0x6578,0x10102); - OUTREG(0x657C,0x8018BED0); - OUTREG(0x6578,0x10200); - OUTREG(0x657C,0x8148BF38); - OUTREG(0x6578,0x10201); - OUTREG(0x657C,0x84408C80); - OUTREG(0x6578,0x10202); - OUTREG(0x657C,0x8008BEB8); - OUTREG(0x6578,0x10300); - OUTREG(0x657C,0x80B0BF78); - OUTREG(0x6578,0x10301); - OUTREG(0x657C,0x85008C20); - OUTREG(0x6578,0x10302); - OUTREG(0x657C,0x8020BEA0); - OUTREG(0x6578,0x10400); - OUTREG(0x657C,0x8028BF90); - OUTREG(0x6578,0x10401); - OUTREG(0x657C,0x85E08BC0); - OUTREG(0x6578,0x10402); - OUTREG(0x657C,0x8018BE90); - OUTREG(0x6578,0x10500); - OUTREG(0x657C,0xBFB8BFB0); - OUTREG(0x6578,0x10501); - OUTREG(0x657C,0x86C08B40); - OUTREG(0x6578,0x10502); - OUTREG(0x657C,0x8010BE90); - OUTREG(0x6578,0x10600); - OUTREG(0x657C,0xBF58BFC8); - OUTREG(0x6578,0x10601); - OUTREG(0x657C,0x87A08AA0); - OUTREG(0x6578,0x10602); - OUTREG(0x657C,0x8010BE98); - OUTREG(0x6578,0x10700); - OUTREG(0x657C,0xBF10BFF0); - OUTREG(0x6578,0x10701); - OUTREG(0x657C,0x886089E0); - OUTREG(0x6578,0x10702); - OUTREG(0x657C,0x8018BEB0); - OUTREG(0x6578,0x10800); - OUTREG(0x657C,0xBED8BFE8); - OUTREG(0x6578,0x10801); - OUTREG(0x657C,0x89408940); - OUTREG(0x6578,0x10802); - OUTREG(0x657C,0xBFE8BED8); - OUTREG(0x6578,0x20000); - OUTREG(0x657C,0x80008000); - OUTREG(0x6578,0x20001); - OUTREG(0x657C,0x90008000); - OUTREG(0x6578,0x20002); - OUTREG(0x657C,0x80008000); - OUTREG(0x6578,0x20003); - OUTREG(0x657C,0x80008000); - OUTREG(0x6578,0x20100); - OUTREG(0x657C,0x80108000); - OUTREG(0x6578,0x20101); - OUTREG(0x657C,0x8FE0BF70); - OUTREG(0x6578,0x20102); - OUTREG(0x657C,0xBFE880C0); - OUTREG(0x6578,0x20103); - OUTREG(0x657C,0x80008000); - OUTREG(0x6578,0x20200); - OUTREG(0x657C,0x8018BFF8); - OUTREG(0x6578,0x20201); - OUTREG(0x657C,0x8F80BF08); - OUTREG(0x6578,0x20202); - OUTREG(0x657C,0xBFD081A0); - OUTREG(0x6578,0x20203); - OUTREG(0x657C,0xBFF88000); - OUTREG(0x6578,0x20300); - OUTREG(0x657C,0x80188000); - OUTREG(0x6578,0x20301); - OUTREG(0x657C,0x8EE0BEC0); - OUTREG(0x6578,0x20302); - OUTREG(0x657C,0xBFB082A0); - OUTREG(0x6578,0x20303); - OUTREG(0x657C,0x80008000); - OUTREG(0x6578,0x20400); - OUTREG(0x657C,0x80188000); - OUTREG(0x6578,0x20401); - OUTREG(0x657C,0x8E00BEA0); - OUTREG(0x6578,0x20402); - OUTREG(0x657C,0xBF8883C0); - OUTREG(0x6578,0x20403); - OUTREG(0x657C,0x80008000); - OUTREG(0x6578,0x20500); - OUTREG(0x657C,0x80188000); - OUTREG(0x6578,0x20501); - OUTREG(0x657C,0x8D00BE90); - OUTREG(0x6578,0x20502); - OUTREG(0x657C,0xBF588500); - OUTREG(0x6578,0x20503); - OUTREG(0x657C,0x80008008); - OUTREG(0x6578,0x20600); - OUTREG(0x657C,0x80188000); - OUTREG(0x6578,0x20601); - OUTREG(0x657C,0x8BC0BE98); - OUTREG(0x6578,0x20602); - OUTREG(0x657C,0xBF308660); - OUTREG(0x6578,0x20603); - OUTREG(0x657C,0x80008008); - OUTREG(0x6578,0x20700); - OUTREG(0x657C,0x80108000); - OUTREG(0x6578,0x20701); - OUTREG(0x657C,0x8A80BEB0); - OUTREG(0x6578,0x20702); - OUTREG(0x657C,0xBF0087C0); - OUTREG(0x6578,0x20703); - OUTREG(0x657C,0x80008008); - OUTREG(0x6578,0x20800); - OUTREG(0x657C,0x80108000); - OUTREG(0x6578,0x20801); - OUTREG(0x657C,0x8920BED0); - OUTREG(0x6578,0x20802); - OUTREG(0x657C,0xBED08920); - OUTREG(0x6578,0x20803); - OUTREG(0x657C,0x80008010); - OUTREG(0x6578,0x30000); - OUTREG(0x657C,0x90008000); - OUTREG(0x6578,0x30001); - OUTREG(0x657C,0x80008000); - OUTREG(0x6578,0x30100); - OUTREG(0x657C,0x8FE0BF90); - OUTREG(0x6578,0x30101); - OUTREG(0x657C,0xBFF880A0); - OUTREG(0x6578,0x30200); - OUTREG(0x657C,0x8F60BF40); - OUTREG(0x6578,0x30201); - OUTREG(0x657C,0xBFE88180); - OUTREG(0x6578,0x30300); - OUTREG(0x657C,0x8EC0BF00); - OUTREG(0x6578,0x30301); - OUTREG(0x657C,0xBFC88280); - OUTREG(0x6578,0x30400); - OUTREG(0x657C,0x8DE0BEE0); - OUTREG(0x6578,0x30401); - OUTREG(0x657C,0xBFA083A0); - OUTREG(0x6578,0x30500); - OUTREG(0x657C,0x8CE0BED0); - OUTREG(0x6578,0x30501); - OUTREG(0x657C,0xBF7884E0); - OUTREG(0x6578,0x30600); - OUTREG(0x657C,0x8BA0BED8); - OUTREG(0x6578,0x30601); - OUTREG(0x657C,0xBF508640); - OUTREG(0x6578,0x30700); - OUTREG(0x657C,0x8A60BEE8); - OUTREG(0x6578,0x30701); - OUTREG(0x657C,0xBF2087A0); - OUTREG(0x6578,0x30800); - OUTREG(0x657C,0x8900BF00); - OUTREG(0x6578,0x30801); - OUTREG(0x657C,0xBF008900); + int index_reg = 0x6578, data_reg = 0x657c; + + index_reg += radeon_crtc->crtc_offset; + data_reg += radeon_crtc->crtc_offset; + + OUTREG(0x659C + radeon_crtc->crtc_offset, 0x0); + OUTREG(0x6594 + radeon_crtc->crtc_offset, 0x705); + OUTREG(0x65A4 + radeon_crtc->crtc_offset, 0x10001); + OUTREG(0x65D8 + radeon_crtc->crtc_offset, 0x0); + OUTREG(0x65B0 + radeon_crtc->crtc_offset, 0x0); + OUTREG(0x65C0 + radeon_crtc->crtc_offset, 0x0); + OUTREG(0x65D4 + radeon_crtc->crtc_offset, 0x0); + OUTREG(index_reg,0x0); + OUTREG(data_reg,0x841880A8); + OUTREG(index_reg,0x1); + OUTREG(data_reg,0x84208680); + OUTREG(index_reg,0x2); + OUTREG(data_reg,0xBFF880B0); + OUTREG(index_reg,0x100); + OUTREG(data_reg,0x83D88088); + OUTREG(index_reg,0x101); + OUTREG(data_reg,0x84608680); + OUTREG(index_reg,0x102); + OUTREG(data_reg,0xBFF080D0); + OUTREG(index_reg,0x200); + OUTREG(data_reg,0x83988068); + OUTREG(index_reg,0x201); + OUTREG(data_reg,0x84A08680); + OUTREG(index_reg,0x202); + OUTREG(data_reg,0xBFF080F8); + OUTREG(index_reg,0x300); + OUTREG(data_reg,0x83588058); + OUTREG(index_reg,0x301); + OUTREG(data_reg,0x84E08660); + OUTREG(index_reg,0x302); + OUTREG(data_reg,0xBFF88120); + OUTREG(index_reg,0x400); + OUTREG(data_reg,0x83188040); + OUTREG(index_reg,0x401); + OUTREG(data_reg,0x85008660); + OUTREG(index_reg,0x402); + OUTREG(data_reg,0xBFF88150); + OUTREG(index_reg,0x500); + OUTREG(data_reg,0x82D88030); + OUTREG(index_reg,0x501); + OUTREG(data_reg,0x85408640); + OUTREG(index_reg,0x502); + OUTREG(data_reg,0xBFF88180); + OUTREG(index_reg,0x600); + OUTREG(data_reg,0x82A08018); + OUTREG(index_reg,0x601); + OUTREG(data_reg,0x85808620); + OUTREG(index_reg,0x602); + OUTREG(data_reg,0xBFF081B8); + OUTREG(index_reg,0x700); + OUTREG(data_reg,0x82608010); + OUTREG(index_reg,0x701); + OUTREG(data_reg,0x85A08600); + OUTREG(index_reg,0x702); + OUTREG(data_reg,0x800081F0); + OUTREG(index_reg,0x800); + OUTREG(data_reg,0x8228BFF8); + OUTREG(index_reg,0x801); + OUTREG(data_reg,0x85E085E0); + OUTREG(index_reg,0x802); + OUTREG(data_reg,0xBFF88228); + OUTREG(index_reg,0x10000); + OUTREG(data_reg,0x82A8BF00); + OUTREG(index_reg,0x10001); + OUTREG(data_reg,0x82A08CC0); + OUTREG(index_reg,0x10002); + OUTREG(data_reg,0x8008BEF8); + OUTREG(index_reg,0x10100); + OUTREG(data_reg,0x81F0BF28); + OUTREG(index_reg,0x10101); + OUTREG(data_reg,0x83608CA0); + OUTREG(index_reg,0x10102); + OUTREG(data_reg,0x8018BED0); + OUTREG(index_reg,0x10200); + OUTREG(data_reg,0x8148BF38); + OUTREG(index_reg,0x10201); + OUTREG(data_reg,0x84408C80); + OUTREG(index_reg,0x10202); + OUTREG(data_reg,0x8008BEB8); + OUTREG(index_reg,0x10300); + OUTREG(data_reg,0x80B0BF78); + OUTREG(index_reg,0x10301); + OUTREG(data_reg,0x85008C20); + OUTREG(index_reg,0x10302); + OUTREG(data_reg,0x8020BEA0); + OUTREG(index_reg,0x10400); + OUTREG(data_reg,0x8028BF90); + OUTREG(index_reg,0x10401); + OUTREG(data_reg,0x85E08BC0); + OUTREG(index_reg,0x10402); + OUTREG(data_reg,0x8018BE90); + OUTREG(index_reg,0x10500); + OUTREG(data_reg,0xBFB8BFB0); + OUTREG(index_reg,0x10501); + OUTREG(data_reg,0x86C08B40); + OUTREG(index_reg,0x10502); + OUTREG(data_reg,0x8010BE90); + OUTREG(index_reg,0x10600); + OUTREG(data_reg,0xBF58BFC8); + OUTREG(index_reg,0x10601); + OUTREG(data_reg,0x87A08AA0); + OUTREG(index_reg,0x10602); + OUTREG(data_reg,0x8010BE98); + OUTREG(index_reg,0x10700); + OUTREG(data_reg,0xBF10BFF0); + OUTREG(index_reg,0x10701); + OUTREG(data_reg,0x886089E0); + OUTREG(index_reg,0x10702); + OUTREG(data_reg,0x8018BEB0); + OUTREG(index_reg,0x10800); + OUTREG(data_reg,0xBED8BFE8); + OUTREG(index_reg,0x10801); + OUTREG(data_reg,0x89408940); + OUTREG(index_reg,0x10802); + OUTREG(data_reg,0xBFE8BED8); + OUTREG(index_reg,0x20000); + OUTREG(data_reg,0x80008000); + OUTREG(index_reg,0x20001); + OUTREG(data_reg,0x90008000); + OUTREG(index_reg,0x20002); + OUTREG(data_reg,0x80008000); + OUTREG(index_reg,0x20003); + OUTREG(data_reg,0x80008000); + OUTREG(index_reg,0x20100); + OUTREG(data_reg,0x80108000); + OUTREG(index_reg,0x20101); + OUTREG(data_reg,0x8FE0BF70); + OUTREG(index_reg,0x20102); + OUTREG(data_reg,0xBFE880C0); + OUTREG(index_reg,0x20103); + OUTREG(data_reg,0x80008000); + OUTREG(index_reg,0x20200); + OUTREG(data_reg,0x8018BFF8); + OUTREG(index_reg,0x20201); + OUTREG(data_reg,0x8F80BF08); + OUTREG(index_reg,0x20202); + OUTREG(data_reg,0xBFD081A0); + OUTREG(index_reg,0x20203); + OUTREG(data_reg,0xBFF88000); + OUTREG(index_reg,0x20300); + OUTREG(data_reg,0x80188000); + OUTREG(index_reg,0x20301); + OUTREG(data_reg,0x8EE0BEC0); + OUTREG(index_reg,0x20302); + OUTREG(data_reg,0xBFB082A0); + OUTREG(index_reg,0x20303); + OUTREG(data_reg,0x80008000); + OUTREG(index_reg,0x20400); + OUTREG(data_reg,0x80188000); + OUTREG(index_reg,0x20401); + OUTREG(data_reg,0x8E00BEA0); + OUTREG(index_reg,0x20402); + OUTREG(data_reg,0xBF8883C0); + OUTREG(index_reg,0x20403); + OUTREG(data_reg,0x80008000); + OUTREG(index_reg,0x20500); + OUTREG(data_reg,0x80188000); + OUTREG(index_reg,0x20501); + OUTREG(data_reg,0x8D00BE90); + OUTREG(index_reg,0x20502); + OUTREG(data_reg,0xBF588500); + OUTREG(index_reg,0x20503); + OUTREG(data_reg,0x80008008); + OUTREG(index_reg,0x20600); + OUTREG(data_reg,0x80188000); + OUTREG(index_reg,0x20601); + OUTREG(data_reg,0x8BC0BE98); + OUTREG(index_reg,0x20602); + OUTREG(data_reg,0xBF308660); + OUTREG(index_reg,0x20603); + OUTREG(data_reg,0x80008008); + OUTREG(index_reg,0x20700); + OUTREG(data_reg,0x80108000); + OUTREG(index_reg,0x20701); + OUTREG(data_reg,0x8A80BEB0); + OUTREG(index_reg,0x20702); + OUTREG(data_reg,0xBF0087C0); + OUTREG(index_reg,0x20703); + OUTREG(data_reg,0x80008008); + OUTREG(index_reg,0x20800); + OUTREG(data_reg,0x80108000); + OUTREG(index_reg,0x20801); + OUTREG(data_reg,0x8920BED0); + OUTREG(index_reg,0x20802); + OUTREG(data_reg,0xBED08920); + OUTREG(index_reg,0x20803); + OUTREG(data_reg,0x80008010); + OUTREG(index_reg,0x30000); + OUTREG(data_reg,0x90008000); + OUTREG(index_reg,0x30001); + OUTREG(data_reg,0x80008000); + OUTREG(index_reg,0x30100); + OUTREG(data_reg,0x8FE0BF90); + OUTREG(index_reg,0x30101); + OUTREG(data_reg,0xBFF880A0); + OUTREG(index_reg,0x30200); + OUTREG(data_reg,0x8F60BF40); + OUTREG(index_reg,0x30201); + OUTREG(data_reg,0xBFE88180); + OUTREG(index_reg,0x30300); + OUTREG(data_reg,0x8EC0BF00); + OUTREG(index_reg,0x30301); + OUTREG(data_reg,0xBFC88280); + OUTREG(index_reg,0x30400); + OUTREG(data_reg,0x8DE0BEE0); + OUTREG(index_reg,0x30401); + OUTREG(data_reg,0xBFA083A0); + OUTREG(index_reg,0x30500); + OUTREG(data_reg,0x8CE0BED0); + OUTREG(index_reg,0x30501); + OUTREG(data_reg,0xBF7884E0); + OUTREG(index_reg,0x30600); + OUTREG(data_reg,0x8BA0BED8); + OUTREG(index_reg,0x30601); + OUTREG(data_reg,0xBF508640); + OUTREG(index_reg,0x30700); + OUTREG(data_reg,0x8A60BEE8); + OUTREG(index_reg,0x30701); + OUTREG(data_reg,0xBF2087A0); + OUTREG(index_reg,0x30800); + OUTREG(data_reg,0x8900BF00); + OUTREG(index_reg,0x30801); + OUTREG(data_reg,0xBF008900); } static int @@ -1182,7 +1193,7 @@ atombios_output_scaler_setup(xf86OutputPtr output) if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT) && info->ChipFamily >= CHIP_FAMILY_RV515 && info->ChipFamily <= CHIP_FAMILY_RV570) { ErrorF("forcing TV scaler\n"); - atom_rv515_force_tv_scaler(output->scrn); + atom_rv515_force_tv_scaler(output->scrn, radeon_crtc); } ErrorF("scaler %d setup success\n", radeon_crtc->crtc_id); return ATOM_SUCCESS; @@ -1271,6 +1282,9 @@ atombios_output_dpms(xf86OutputPtr output, int mode) ErrorF("Output %s enable failed\n", device_name[radeon_get_device_index(radeon_output->active_device)]); } + /* at least for TV atom fails to reassociate the correct crtc source at dpms on */ + if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) + atombios_set_output_crtc_source(output); break; case DPMSModeStandby: case DPMSModeSuspend: @@ -1600,7 +1614,7 @@ atombios_dac_detect(xf86OutputPtr output) RADEONOutputPrivatePtr radeon_output = output->driver_private; RADEONMonitorType MonType = MT_NONE; AtomBiosResult ret; - uint32_t bios_0_scratch; + RADEONSavePtr save = info->ModeReg; if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) { if (xf86ReturnOptValBool(info->Options, OPTION_FORCE_TVOUT, FALSE)) { @@ -1614,24 +1628,24 @@ atombios_dac_detect(xf86OutputPtr output) ret = atom_bios_dac_load_detect(info->atomBIOS, output); if (ret == ATOM_SUCCESS) { if (info->ChipFamily >= CHIP_FAMILY_R600) - bios_0_scratch = INREG(R600_BIOS_0_SCRATCH); + save->bios_0_scratch = INREG(R600_BIOS_0_SCRATCH); else - bios_0_scratch = INREG(RADEON_BIOS_0_SCRATCH); - /*ErrorF("DAC connect %08X\n", (unsigned int)bios_0_scratch);*/ + save->bios_0_scratch = INREG(RADEON_BIOS_0_SCRATCH); + /*ErrorF("DAC connect %08X\n", (unsigned int)save->bios_0_scratch);*/ if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT) { - if (bios_0_scratch & ATOM_S0_CRT1_MASK) + if (save->bios_0_scratch & ATOM_S0_CRT1_MASK) MonType = MT_CRT; } else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT) { - if (bios_0_scratch & ATOM_S0_CRT2_MASK) + if (save->bios_0_scratch & ATOM_S0_CRT2_MASK) MonType = MT_CRT; } else if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT) { - if (bios_0_scratch & (ATOM_S0_CV_MASK | ATOM_S0_CV_MASK_A)) + if (save->bios_0_scratch & (ATOM_S0_CV_MASK | ATOM_S0_CV_MASK_A)) MonType = MT_CV; } else if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) { - if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A)) + if (save->bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A)) MonType = MT_CTV; - else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A)) + else if (save->bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A)) MonType = MT_STV; } } diff --git a/src/legacy_output.c b/src/legacy_output.c index 7134ee1..73c86b9 100644 --- a/src/legacy_output.c +++ b/src/legacy_output.c @@ -1216,14 +1216,25 @@ RADEONInitFP2Registers(xf86OutputPtr output, RADEONSavePtr save, if ((info->Chipset == PCI_CHIP_RV350_NP) && (PCI_SUB_VENDOR_ID(info->PciInfo) == 0x1028) && (PCI_SUB_DEVICE_ID(info->PciInfo) == 0x2001)) - save->fp2_gen_cntl |= R300_FP2_DVO_CLOCK_MODE_SINGLE; /* Dell Inspiron 8600 */ + save->fp2_gen_cntl |= R200_FP2_DVO_CLOCK_MODE_SINGLE; /* Dell Inspiron 8600 */ else - save->fp2_gen_cntl |= RADEON_FP2_PAD_FLOP_EN | R300_FP2_DVO_CLOCK_MODE_SINGLE; + save->fp2_gen_cntl |= RADEON_FP2_PAD_FLOP_EN | R200_FP2_DVO_CLOCK_MODE_SINGLE; + } + #if 0 - if (mode->Clock > 165000) + /* DVO configurations: + * SDR single channel (data rate 165 Mhz, port width 12 bits) + * DDR single channel (data rate 330 Mhz, port width 12 bits) + * SDR dual channel (data rate 330 Mhz, port width 24 bits) + * - dual channel is only available on r3xx+ + */ + if (info->ChipFamily >= CHIP_FAMILY_R200) { + if (sdr) + save->fp2_gen_cntl |= R200_FP2_DVO_RATE_SEL_SDR; + if (IS_R300_VARIANT && dual channel) save->fp2_gen_cntl |= R300_FP2_DVO_DUAL_CHANNEL_EN; -#endif } +#endif if (IsPrimary) { if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) { diff --git a/src/pcidb/ati_pciids.csv b/src/pcidb/ati_pciids.csv index 51dafee..695d9a6 100644 --- a/src/pcidb/ati_pciids.csv +++ b/src/pcidb/ati_pciids.csv @@ -355,15 +355,26 @@ "0x946B","RV770_946B","RV770",1,,,,,"ATI M98" "0x947A","RV770_947A","RV770",1,,,,,"ATI M98" "0x947B","RV770_947B","RV770",1,,,,,"ATI M98" +"0x9480","RV730_9480","RV730",1,,,,,"ATI Mobility Radeon HD 4650" "0x9487","RV730_9487","RV730",,,,,,"ATI Radeon RV730 (AGP)" +"0x9488","RV730_9488","RV730",1,,,,,"ATI Mobility Radeon HD 4670" "0x9489","RV730_9489","RV730",1,,,,,"ATI FirePro M5750" "0x948F","RV730_948F","RV730",,,,,,"ATI Radeon RV730 (AGP)" "0x9490","RV730_9490","RV730",,,,,,"ATI RV730XT [Radeon HD 4670]" "0x9491","RV730_9491","RV730",,,,,,"ATI RADEON E4600" +"0x9495","RV730_9495","RV730",,,,,,"ATI Radeon HD 4600 Series" "0x9498","RV730_9498","RV730",,,,,,"ATI RV730 PRO [Radeon HD 4650]" "0x949C","RV730_949C","RV730",,,,,,"ATI FirePro V7750 (FireGL)" "0x949E","RV730_949E","RV730",,,,,,"ATI FirePro V5700 (FireGL)" "0x949F","RV730_949F","RV730",,,,,,"ATI FirePro V3750 (FireGL)" +"0x94A0","RV740_94A0","RV740",1,,,,,"ATI Mobility Radeon HD 4830" +"0x94A1","RV740_94A1","RV740",1,,,,,"ATI Mobility Radeon HD 4850" +"0x94A3","RV740_94A3","RV740",1,,,,,"ATI FirePro M7740" +"0x94B1","RV740_94B1","RV740",,,,,,"ATI RV740" +"0x94B3","RV740_94B3","RV740",,,,,,"ATI Radeon HD 4770" +"0x94B4","RV740_94B4","RV740",,,,,,"ATI Radeon HD 4700 Series" +"0x94B5","RV740_94B5","RV740",,,,,,"ATI Radeon HD 4770" +"0x94B9","RV740_94B9","RV740",1,,,,,"ATI FirePro M5750" "0x94C0","RV610_94C0","RV610",,,,,,"ATI RV610" "0x94C1","RV610_94C1","RV610",,,,,,"ATI Radeon HD 2400 XT" "0x94C3","RV610_94C3","RV610",,,,,,"ATI Radeon HD 2400 Pro" @@ -396,6 +407,7 @@ "0x9552","RV710_9552","RV710",1,,,,,"ATI Mobility Radeon 4300 Series" "0x9553","RV710_9553","RV710",1,,,,,"ATI Mobility Radeon 4500 Series" "0x9555","RV710_9555","RV710",1,,,,,"ATI Mobility Radeon 4500 Series" +"0x9557","RV710_9557","RV710",1,,,,,"ATI FirePro RG220" "0x9580","RV630_9580","RV630",,,,,,"ATI RV630" "0x9581","RV630_9581","RV630",1,,,,,"ATI Mobility Radeon HD 2600" "0x9583","RV630_9583","RV630",1,,,,,"ATI Mobility Radeon HD 2600 XT" @@ -437,8 +449,8 @@ "0x9614","RS780_9614","RS780",,1,,,1,"ATI Radeon HD 3300 Graphics" "0x9615","RS780_9615","RS780",,1,,,1,"ATI Radeon HD 3200 Graphics" "0x9616","RS780_9616","RS780",,1,,,1,"ATI Radeon 3000 Graphics" -"0x9710","RS880_9710","RS880",,1,,,1,"ATI Radeon HD Graphics" -"0x9711","RS880_9711","RS880",,1,,,1,"ATI Radeon Graphics" -"0x9712","RS880_9712","RS880",1,1,,,1,"ATI Mobility Radeon HD Graphics" -"0x9713","RS880_9713","RS880",1,1,,,1,"ATI Mobility Radeon Graphics" -"0x9714","RS880_9714","RS880",,1,,,1,"ATI Radeon Graphics" +"0x9710","RS880_9710","RS880",,1,,,1,"ATI Radeon HD 4200" +"0x9711","RS880_9711","RS880",,1,,,1,"ATI Radeon 4100" +"0x9712","RS880_9712","RS880",1,1,,,1,"ATI Mobility Radeon HD 4200" +"0x9713","RS880_9713","RS880",1,1,,,1,"ATI Mobility Radeon 4100" +"0x9714","RS880_9714","RS880",,1,,,1,"ATI RS880" diff --git a/src/pcidb/parse_pci_ids.pl b/src/pcidb/parse_pci_ids.pl index a3a8af8..d1900a4 100755 --- a/src/pcidb/parse_pci_ids.pl +++ b/src/pcidb/parse_pci_ids.pl @@ -33,7 +33,7 @@ print PCICHIPSET "PciChipsets RADEONPciChipsets[] = {\n"; print PCIDEVICEMATCH "/* This file is autogenerated please do not edit */\n"; print PCIDEVICEMATCH "static const struct pci_id_match radeon_device_match[] = {\n"; print RADEONCHIPINFO "/* This file is autogenerated please do not edit */\n"; -print RADEONCHIPINFO "RADEONCardInfo RADEONCards[] = {\n"; +print RADEONCHIPINFO "static RADEONCardInfo RADEONCards[] = {\n"; while (<CSV>) { if ($csv->parse($_)) { my @columns = $csv->fields(); diff --git a/src/r500_hwmc.c b/src/r500_hwmc.c index 64babf8..982296b 100644 --- a/src/r500_hwmc.c +++ b/src/r500_hwmc.c @@ -97,6 +97,124 @@ static XF86MCSurfaceInfoPtr ppSI[2] = static int r500_hwmc_create_context (ScrnInfoPtr pScrn, XvMCContextPtr pContext, int *num_priv, long **priv ) { + I830Ptr pI830 = I830PTR(pScrn); + DRIInfoPtr pDRIInfo = pI830->pDRIInfo; + I830DRIPtr pI830DRI = pDRIInfo->devPrivate; + I915XvMCCreateContextRec *contextRec = NULL; + I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate; + I915XvMCContextPriv *ctxpriv = NULL; + int i; + + *priv = NULL; + *num_priv = 0; + + if (!pI830->XvMCEnabled) + { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[XvMC] r500: XvMC disabled!\n"); + return BadAlloc; + } + + for (i = 0; i < I915_XVMC_MAX_CONTEXTS; i++) + { + if (!pXvMC->contexts[i]) + break; + } + + if (i == I915_XVMC_MAX_CONTEXTS || pXvMC->ncontexts >= I915_XVMC_MAX_CONTEXTS) + { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[XvMC] i915: Out of contexts.\n"); + return BadAlloc; + } + + i915_check_context_size(pContext); + + *priv = xcalloc(1, sizeof(I915XvMCCreateContextRec)); + contextRec = (I915XvMCCreateContextRec *)*priv; + + if (!*priv) + { + *num_priv = 0; + return BadAlloc; + } + + *num_priv = sizeof(I915XvMCCreateContextRec) >> 2; + + ctxpriv = (I915XvMCContextPriv *)xcalloc(1, sizeof(I915XvMCContextPriv)); + + if (!ctxpriv) + { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[XvMC] i915: Unable to allocate memory!\n"); + xfree(*priv); + *priv = NULL; + *num_priv = 0; + return BadAlloc; + } + + if (!i915_allocate_xvmc_buffers(pScrn, ctxpriv)) + { + i915_free_xvmc_buffers(pScrn, ctxpriv); + xfree(ctxpriv); + ctxpriv = NULL; + xfree(*priv); + *priv = NULL; + *num_priv = 0; + return BadAlloc; + } + + if (!i915_map_xvmc_buffers(pScrn, ctxpriv)) + { + i915_unmap_xvmc_buffers(pScrn, ctxpriv); + i915_free_xvmc_buffers(pScrn, ctxpriv); + xfree(ctxpriv); + ctxpriv = NULL; + xfree(*priv); + *priv = NULL; + *num_priv = 0; + return BadAlloc; + } + + /* common context items */ + contextRec->comm.type = xvmc_driver->flag; + contextRec->comm.sarea_size = pDRIInfo->SAREASize; + contextRec->comm.batchbuffer.offset = xvmc_driver->batch->offset; + contextRec->comm.batchbuffer.size = xvmc_driver->batch->size; + contextRec->comm.batchbuffer.handle = xvmc_driver->batch_handle; + + /* i915 private context */ + contextRec->ctxno = i; + contextRec->sis.handle = ctxpriv->sis_handle; + contextRec->sis.offset = ctxpriv->mcStaticIndirectState->offset; + contextRec->sis.size = ctxpriv->mcStaticIndirectState->size; + contextRec->ssb.handle = ctxpriv->ssb_handle; + contextRec->ssb.offset = ctxpriv->mcSamplerState->offset; + contextRec->ssb.size = ctxpriv->mcSamplerState->size; + contextRec->msb.handle = ctxpriv->msb_handle; + contextRec->msb.offset = ctxpriv->mcMapState->offset; + contextRec->msb.size = ctxpriv->mcMapState->size; + contextRec->psp.handle = ctxpriv->psp_handle; + contextRec->psp.offset = ctxpriv->mcPixelShaderProgram->offset; + contextRec->psp.size = ctxpriv->mcPixelShaderProgram->size; + contextRec->psc.handle = ctxpriv->psc_handle; + contextRec->psc.offset = ctxpriv->mcPixelShaderConstants->offset; + contextRec->psc.size = ctxpriv->mcPixelShaderConstants->size; + contextRec->corrdata.handle = ctxpriv->corrdata_handle; + contextRec->corrdata.offset = ctxpriv->mcCorrdata->offset; + contextRec->corrdata.size = ctxpriv->mcCorrdata->size; + contextRec->sarea_priv_offset = sizeof(XF86DRISAREARec); + contextRec->deviceID = pI830DRI->deviceID; + + contextRec->sis.bus_addr = ctxpriv->mcStaticIndirectState->bus_addr; + contextRec->ssb.bus_addr = ctxpriv->mcSamplerState->bus_addr; + contextRec->msb.bus_addr = ctxpriv->mcMapState->bus_addr; + contextRec->psp.bus_addr = ctxpriv->mcPixelShaderProgram->bus_addr; + contextRec->psc.bus_addr = ctxpriv->mcPixelShaderConstants->bus_addr; + + pXvMC->ncontexts++; + pXvMC->contexts[i] = pContext->context_id; + pXvMC->ctxprivs[i] = ctxpriv; + + return Success; } static void r500_hwmc_destroy_context (ScrnInfoPtr pScrn, XvMCContextPtr pContext) diff --git a/src/r500_hwmc.h b/src/r500_hwmc.h index db4fdaf..acfcbde 100644 --- a/src/r500_hwmc.h +++ b/src/r500_hwmc.h @@ -24,8 +24,8 @@ * */ -#ifndef RADEON_HWMC_H -#define RADEON_HWMC_H +#ifndef R500_HWMC_H +#define R500_HWMC_H #define FOURCC_XVMC (('C' << 24) + ('M' << 16) + ('V' << 8) + 'X') #define XVMC_R500_MPEG2_MC 0x1 diff --git a/src/r600_exa.c b/src/r600_exa.c index 18831f7..d2df1db 100644 --- a/src/r600_exa.c +++ b/src/r600_exa.c @@ -39,6 +39,21 @@ #include "r600_reg.h" #include "r600_state.h" + +#define RADEON_TRACE_FALL 0 +#define RADEON_TRACE_DRAW 0 + +#if RADEON_TRACE_FALL +#define RADEON_FALLBACK(x) \ +do { \ + ErrorF("%s: ", __FUNCTION__); \ + ErrorF x; \ + return FALSE; \ +} while (0) +#else +#define RADEON_FALLBACK(x) return FALSE +#endif + extern PixmapPtr RADEONGetDrawablePixmap(DrawablePtr pDrawable); @@ -80,6 +95,20 @@ uint32_t RADEON_ROP[16] = { RADEON_ROP3_ONE, /* GXset */ }; +static Bool R600CheckBPP(int bpp) +{ + switch (bpp) { + case 8: + case 16: + case 32: + return TRUE; + default: + break; + } + return FALSE; +} + + static void R600DoneSolid(PixmapPtr pPix); @@ -99,20 +128,22 @@ R600PrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) uint32_t a, r, g, b; float ps_alu_consts[4]; + if (pPix->drawable.bitsPerPixel == 24) + RADEON_FALLBACK(("24bpp unsupported\n")); + if (!R600CheckBPP(pPix->drawable.bitsPerPixel)) + RADEON_FALLBACK(("R600CheckDatatype failed\n")); + accel_state->dst_mc_addr = exaGetPixmapOffset(pPix) + info->fbLocation + pScrn->fbOffset; accel_state->dst_size = exaGetPixmapPitch(pPix) * pPix->drawable.height; accel_state->dst_pitch = exaGetPixmapPitch(pPix) / (pPix->drawable.bitsPerPixel / 8); /* bad pitch */ if (accel_state->dst_pitch & 7) - return FALSE; + RADEON_FALLBACK(("Bad pitch 0x%08x\n", accel_state->dst_pitch)); /* bad offset */ if (accel_state->dst_mc_addr & 0xff) - return FALSE; - - if (pPix->drawable.bitsPerPixel == 24) - return FALSE; + RADEON_FALLBACK(("Bad offset 0x%08x\n", accel_state->dst_mc_addr)); CLEAR (cb_conf); CLEAR (vs_conf); @@ -126,6 +157,7 @@ R600PrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) #endif accel_state->ib = RADEONCPGetBuffer(pScrn); + r600_vb_get(pScrn); /* Init */ start_3d(pScrn, accel_state->ib); @@ -136,6 +168,10 @@ R600PrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) EREG(accel_state->ib, PA_CL_VTE_CNTL, VTX_XY_FMT_bit); EREG(accel_state->ib, PA_CL_CLIP_CNTL, CLIP_DISABLE_bit); + set_generic_scissor(pScrn, accel_state->ib, 0, 0, pPix->drawable.width, pPix->drawable.height); + set_screen_scissor(pScrn, accel_state->ib, 0, 0, pPix->drawable.width, pPix->drawable.height); + set_window_scissor(pScrn, accel_state->ib, 0, 0, pPix->drawable.width, pPix->drawable.height); + accel_state->vs_mc_addr = info->fbLocation + pScrn->fbOffset + accel_state->shaders->offset + accel_state->solid_vs_offset; accel_state->ps_mc_addr = info->fbLocation + pScrn->fbOffset + accel_state->shaders->offset + @@ -219,7 +255,7 @@ R600PrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) (0x03 << DEFAULT_VAL_shift) | FLAT_SHADE_bit | SEL_CENTROID_bit)); - EREG(accel_state->ib, SPI_INTERP_CONTROL_0, FLAT_SHADE_ENA_bit | 0); + EREG(accel_state->ib, SPI_INTERP_CONTROL_0, FLAT_SHADE_ENA_bit); /* PS alu constants */ if (pPix->drawable.bitsPerPixel == 16) { @@ -249,8 +285,6 @@ R600PrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) set_alu_consts(pScrn, accel_state->ib, SQ_ALU_CONSTANT_ps, sizeof(ps_alu_consts) / SQ_ALU_CONSTANT_offset, ps_alu_consts); - accel_state->vb_index = 0; - #ifdef SHOW_VERTEXES ErrorF("PM: 0x%08x\n", pm); #endif @@ -267,15 +301,13 @@ R600Solid(PixmapPtr pPix, int x1, int y1, int x2, int y2) struct radeon_accel_state *accel_state = info->accel_state; float *vb; - if (((accel_state->vb_index + 3) * 8) > (accel_state->ib->total / 2)) { - R600DoneSolid(pPix); - accel_state->vb_index = 0; - accel_state->ib = RADEONCPGetBuffer(pScrn); + if (((accel_state->vb_index + 3) * 8) > accel_state->vb_total) { + R600DoneSolid(pPix); + accel_state->ib = RADEONCPGetBuffer(pScrn); + r600_vb_get(pScrn); } - vb = (pointer)((char*)accel_state->ib->address + - (accel_state->ib->total / 2) + - accel_state->vb_index * 8); + vb = (pointer)((char*)accel_state->vb_ptr+accel_state->vb_index*8); vb[0] = (float)x1; vb[1] = (float)y1; @@ -303,18 +335,18 @@ R600DoneSolid(PixmapPtr pPix) CLEAR (vtx_res); if (accel_state->vb_index == 0) { - R600IBDiscard(pScrn, accel_state->ib); - return; + R600IBDiscard(pScrn, accel_state->ib); + r600_vb_discard(pScrn); + return; } - accel_state->vb_mc_addr = info->gartLocation + info->dri->bufStart + - (accel_state->ib->idx * accel_state->ib->total) + (accel_state->ib->total / 2); accel_state->vb_size = accel_state->vb_index * 8; /* flush vertex cache */ if ((info->ChipFamily == CHIP_FAMILY_RV610) || (info->ChipFamily == CHIP_FAMILY_RV620) || (info->ChipFamily == CHIP_FAMILY_RS780) || + (info->ChipFamily == CHIP_FAMILY_RS880) || (info->ChipFamily == CHIP_FAMILY_RV710)) cp_set_surface_sync(pScrn, accel_state->ib, TC_ACTION_ENA_bit, accel_state->vb_size, accel_state->vb_mc_addr); @@ -351,7 +383,7 @@ R600DoneSolid(PixmapPtr pPix) static void R600DoPrepareCopy(ScrnInfoPtr pScrn, int src_pitch, int src_width, int src_height, uint32_t src_offset, int src_bpp, - int dst_pitch, int dst_height, uint32_t dst_offset, int dst_bpp, + int dst_pitch, int dst_width, int dst_height, uint32_t dst_offset, int dst_bpp, int rop, Pixel planemask) { RADEONInfoPtr info = RADEONPTR(pScrn); @@ -369,6 +401,7 @@ R600DoPrepareCopy(ScrnInfoPtr pScrn, CLEAR (ps_conf); accel_state->ib = RADEONCPGetBuffer(pScrn); + r600_vb_get(pScrn); /* Init */ start_3d(pScrn, accel_state->ib); @@ -379,6 +412,10 @@ R600DoPrepareCopy(ScrnInfoPtr pScrn, EREG(accel_state->ib, PA_CL_VTE_CNTL, VTX_XY_FMT_bit); EREG(accel_state->ib, PA_CL_CLIP_CNTL, CLIP_DISABLE_bit); + set_generic_scissor(pScrn, accel_state->ib, 0, 0, dst_width, dst_height); + set_screen_scissor(pScrn, accel_state->ib, 0, 0, dst_width, dst_height); + set_window_scissor(pScrn, accel_state->ib, 0, 0, dst_width, dst_height); + accel_state->vs_mc_addr = info->fbLocation + pScrn->fbOffset + accel_state->shaders->offset + accel_state->copy_vs_offset; accel_state->ps_mc_addr = info->fbLocation + pScrn->fbOffset + accel_state->shaders->offset + @@ -524,9 +561,6 @@ R600DoPrepareCopy(ScrnInfoPtr pScrn, (0x01 << DEFAULT_VAL_shift) | SEL_CENTROID_bit)); EREG(accel_state->ib, SPI_INTERP_CONTROL_0, 0); - - accel_state->vb_index = 0; - } static void @@ -541,18 +575,18 @@ R600DoCopy(ScrnInfoPtr pScrn) CLEAR (vtx_res); if (accel_state->vb_index == 0) { - R600IBDiscard(pScrn, accel_state->ib); - return; + R600IBDiscard(pScrn, accel_state->ib); + r600_vb_discard(pScrn); + return; } - accel_state->vb_mc_addr = info->gartLocation + info->dri->bufStart + - (accel_state->ib->idx * accel_state->ib->total) + (accel_state->ib->total / 2); accel_state->vb_size = accel_state->vb_index * 16; /* flush vertex cache */ if ((info->ChipFamily == CHIP_FAMILY_RV610) || (info->ChipFamily == CHIP_FAMILY_RV620) || (info->ChipFamily == CHIP_FAMILY_RS780) || + (info->ChipFamily == CHIP_FAMILY_RS880) || (info->ChipFamily == CHIP_FAMILY_RV710)) cp_set_surface_sync(pScrn, accel_state->ib, TC_ACTION_ENA_bit, accel_state->vb_size, accel_state->vb_mc_addr); @@ -595,15 +629,13 @@ R600AppendCopyVertex(ScrnInfoPtr pScrn, struct radeon_accel_state *accel_state = info->accel_state; float *vb; - if (((accel_state->vb_index + 3) * 16) > (accel_state->ib->total / 2)) { - R600DoCopy(pScrn); - accel_state->vb_index = 0; - accel_state->ib = RADEONCPGetBuffer(pScrn); + if (((accel_state->vb_index + 3) * 16) > accel_state->vb_total) { + R600DoCopy(pScrn); + accel_state->ib = RADEONCPGetBuffer(pScrn); + r600_vb_get(pScrn); } - vb = (pointer)((char*)accel_state->ib->address + - (accel_state->ib->total / 2) + - accel_state->vb_index * 16); + vb = (pointer)((char*)accel_state->vb_ptr+accel_state->vb_index*16); vb[0] = (float)dstX; vb[1] = (float)dstY; @@ -633,6 +665,15 @@ R600PrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, RADEONInfoPtr info = RADEONPTR(pScrn); struct radeon_accel_state *accel_state = info->accel_state; + if (pSrc->drawable.bitsPerPixel == 24) + RADEON_FALLBACK(("24bpp unsupported\n")); + if (pDst->drawable.bitsPerPixel == 24) + RADEON_FALLBACK(("24bpp unsupported\n")); + if (!R600CheckBPP(pSrc->drawable.bitsPerPixel)) + RADEON_FALLBACK(("R600CheckDatatype src failed\n")); + if (!R600CheckBPP(pDst->drawable.bitsPerPixel)) + RADEON_FALLBACK(("R600CheckDatatype dst failed\n")); + accel_state->dst_pitch = exaGetPixmapPitch(pDst) / (pDst->drawable.bitsPerPixel / 8); accel_state->src_pitch[0] = exaGetPixmapPitch(pSrc) / (pSrc->drawable.bitsPerPixel / 8); @@ -647,20 +688,16 @@ R600PrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, /* bad pitch */ if (accel_state->src_pitch[0] & 7) - return FALSE; + RADEON_FALLBACK(("Bad src pitch 0x%08x\n", accel_state->src_pitch[0])); if (accel_state->dst_pitch & 7) - return FALSE; + RADEON_FALLBACK(("Bad dst pitch 0x%08x\n", accel_state->dst_pitch)); /* bad offset */ if (accel_state->src_mc_addr[0] & 0xff) - return FALSE; - if (accel_state->dst_mc_addr & 0xff) - return FALSE; + RADEON_FALLBACK(("Bad src offset 0x%08x\n", accel_state->src_mc_addr[0])); - if (pSrc->drawable.bitsPerPixel == 24) - return FALSE; - if (pDst->drawable.bitsPerPixel == 24) - return FALSE; + if (accel_state->dst_mc_addr & 0xff) + RADEON_FALLBACK(("Bad dst offset 0x%08x\n", accel_state->dst_mc_addr)); /* return FALSE; */ @@ -689,7 +726,7 @@ R600PrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, R600DoPrepareCopy(pScrn, accel_state->src_pitch[0], pSrc->drawable.width, pSrc->drawable.height, accel_state->src_mc_addr[0], pSrc->drawable.bitsPerPixel, - accel_state->dst_pitch, pDst->drawable.height, + accel_state->dst_pitch, pDst->drawable.width, pDst->drawable.height, accel_state->dst_mc_addr, pDst->drawable.bitsPerPixel, rop, planemask); @@ -738,7 +775,7 @@ R600OverlapCopy(PixmapPtr pDst, if (srcY > dstY ) { /* diagonal up */ R600DoPrepareCopy(pScrn, dst_pitch, pDst->drawable.width, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel, - dst_pitch, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel, + dst_pitch, pDst->drawable.width, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel, accel_state->rop, accel_state->planemask); R600AppendCopyVertex(pScrn, srcX, srcY, dstX, dstY, w, vchunk); R600DoCopy(pScrn); @@ -748,7 +785,7 @@ R600OverlapCopy(PixmapPtr pDst, } else { /* diagonal down */ R600DoPrepareCopy(pScrn, dst_pitch, pDst->drawable.width, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel, - dst_pitch, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel, + dst_pitch, pDst->drawable.width, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel, accel_state->rop, accel_state->planemask); R600AppendCopyVertex(pScrn, srcX, srcY + h - vchunk, dstX, dstY + h - vchunk, w, vchunk); R600DoCopy(pScrn); @@ -759,7 +796,7 @@ R600OverlapCopy(PixmapPtr pDst, if (srcX > dstX ) { /* diagonal left */ R600DoPrepareCopy(pScrn, dst_pitch, pDst->drawable.width, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel, - dst_pitch, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel, + dst_pitch, pDst->drawable.width, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel, accel_state->rop, accel_state->planemask); R600AppendCopyVertex(pScrn, srcX, srcY, dstX, dstY, hchunk, h); R600DoCopy(pScrn); @@ -769,7 +806,7 @@ R600OverlapCopy(PixmapPtr pDst, } else { /* diagonal right */ R600DoPrepareCopy(pScrn, dst_pitch, pDst->drawable.width, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel, - dst_pitch, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel, + dst_pitch, pDst->drawable.width, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel, accel_state->rop, accel_state->planemask); R600AppendCopyVertex(pScrn, srcX + w - hchunk, srcY, dstX + w - hchunk, dstY, hchunk, h); R600DoCopy(pScrn); @@ -785,7 +822,7 @@ R600OverlapCopy(PixmapPtr pDst, for (i = w; i > 0; i -= hchunk) { R600DoPrepareCopy(pScrn, dst_pitch, pDst->drawable.width, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel, - dst_pitch, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel, + dst_pitch, pDst->drawable.width, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel, accel_state->rop, accel_state->planemask); R600AppendCopyVertex(pScrn, srcX + i - hchunk, srcY, dstX + i - hchunk, dstY, hchunk, h); R600DoCopy(pScrn); @@ -795,7 +832,7 @@ R600OverlapCopy(PixmapPtr pDst, for (i = 0; i < w; i += hchunk) { R600DoPrepareCopy(pScrn, dst_pitch, pDst->drawable.width, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel, - dst_pitch, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel, + dst_pitch, pDst->drawable.width, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel, accel_state->rop, accel_state->planemask); R600AppendCopyVertex(pScrn, srcX + i, srcY, dstX + i, dstY, hchunk, h); @@ -808,7 +845,7 @@ R600OverlapCopy(PixmapPtr pDst, for (i = 0; i < h; i += vchunk) { R600DoPrepareCopy(pScrn, dst_pitch, pDst->drawable.width, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel, - dst_pitch, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel, + dst_pitch, pDst->drawable.width, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel, accel_state->rop, accel_state->planemask); if (vchunk > h - i) vchunk = h - i; @@ -820,7 +857,7 @@ R600OverlapCopy(PixmapPtr pDst, for (i = h; i > 0; i -= vchunk) { R600DoPrepareCopy(pScrn, dst_pitch, pDst->drawable.width, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel, - dst_pitch, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel, + dst_pitch, pDst->drawable.width, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel, accel_state->rop, accel_state->planemask); if (vchunk > i) vchunk = i; @@ -832,7 +869,7 @@ R600OverlapCopy(PixmapPtr pDst, } else { R600DoPrepareCopy(pScrn, dst_pitch, pDst->drawable.width, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel, - dst_pitch, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel, + dst_pitch, pDst->drawable.width, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel, accel_state->rop, accel_state->planemask); R600AppendCopyVertex(pScrn, srcX, srcY, dstX, dstY, w, h); @@ -863,13 +900,13 @@ R600Copy(PixmapPtr pDst, R600DoPrepareCopy(pScrn, pitch, pDst->drawable.width, pDst->drawable.height, orig_offset, pDst->drawable.bitsPerPixel, - pitch, pDst->drawable.height, tmp_offset, pDst->drawable.bitsPerPixel, + pitch, pDst->drawable.width, pDst->drawable.height, tmp_offset, pDst->drawable.bitsPerPixel, accel_state->rop, accel_state->planemask); R600AppendCopyVertex(pScrn, srcX, srcY, dstX, dstY, w, h); R600DoCopy(pScrn); R600DoPrepareCopy(pScrn, pitch, pDst->drawable.width, pDst->drawable.height, tmp_offset, pDst->drawable.bitsPerPixel, - pitch, pDst->drawable.height, orig_offset, pDst->drawable.bitsPerPixel, + pitch, pDst->drawable.width, pDst->drawable.height, orig_offset, pDst->drawable.bitsPerPixel, accel_state->rop, accel_state->planemask); R600AppendCopyVertex(pScrn, dstX, dstY, dstX, dstY, w, h); R600DoCopy(pScrn); @@ -881,7 +918,7 @@ R600Copy(PixmapPtr pDst, R600DoPrepareCopy(pScrn, pitch, pDst->drawable.width, pDst->drawable.height, offset, pDst->drawable.bitsPerPixel, - pitch, pDst->drawable.height, offset, pDst->drawable.bitsPerPixel, + pitch, pDst->drawable.width, pDst->drawable.height, offset, pDst->drawable.bitsPerPixel, accel_state->rop, accel_state->planemask); R600AppendCopyVertex(pScrn, srcX, srcY, dstX, dstY, w, h); R600DoCopy(pScrn); @@ -908,19 +945,6 @@ R600DoneCopy(PixmapPtr pDst) } -#define RADEON_TRACE_FALL 0 -#define RADEON_TRACE_DRAW 0 - -#if RADEON_TRACE_FALL -#define RADEON_FALLBACK(x) \ -do { \ - ErrorF("%s: ", __FUNCTION__); \ - ErrorF x; \ - return FALSE; \ -} while (0) -#else -#define RADEON_FALLBACK(x) return FALSE -#endif #define xFixedToFloat(f) (((float) (f)) / 65536) @@ -1038,6 +1062,7 @@ static Bool R600CheckCompositeTexture(PicturePtr pPict, { int w = pPict->pDrawable->width; int h = pPict->pDrawable->height; + unsigned int repeatType = pPict->repeat ? pPict->repeatType : RepeatNone; unsigned int i; int max_tex_w, max_tex_h; @@ -1068,7 +1093,7 @@ static Bool R600CheckCompositeTexture(PicturePtr pPict, * clipping. */ /* FIXME R6xx */ - if (pPict->transform != 0 && !pPict->repeat && PICT_FORMAT_A(pPict->format) == 0) { + if (pPict->transform != 0 && repeatType == RepeatNone && PICT_FORMAT_A(pPict->format) == 0) { if (!(((op == PictOpSrc) || (op == PictOpClear)) && (PICT_FORMAT_A(pDstPict->format) == 0))) RADEON_FALLBACK(("REPEAT_NONE unsupported for transformed xRGB source\n")); } @@ -1084,6 +1109,7 @@ static Bool R600TextureSetup(PicturePtr pPict, PixmapPtr pPix, struct radeon_accel_state *accel_state = info->accel_state; int w = pPict->pDrawable->width; int h = pPict->pDrawable->height; + unsigned int repeatType = pPict->repeat ? pPict->repeatType : RepeatNone; unsigned int i; tex_resource_t tex_res; tex_sampler_t tex_samp; @@ -1097,10 +1123,10 @@ static Bool R600TextureSetup(PicturePtr pPict, PixmapPtr pPix, accel_state->src_pitch[unit] = exaGetPixmapPitch(pPix) / (pPix->drawable.bitsPerPixel / 8); accel_state->src_size[unit] = exaGetPixmapPitch(pPix) * pPix->drawable.height; - if (accel_state->src_pitch[1] & 7) + if (accel_state->src_pitch[unit] & 7) RADEON_FALLBACK(("Bad pitch %d 0x%x\n", (int)accel_state->src_pitch[unit], unit)); - if (accel_state->src_mc_addr[1] & 0xff) + if (accel_state->src_mc_addr[unit] & 0xff) RADEON_FALLBACK(("Bad offset %d 0x%x\n", (int)accel_state->src_mc_addr[unit], unit)); for (i = 0; i < sizeof(R600TexFormats) / sizeof(R600TexFormats[0]); i++) { @@ -1166,7 +1192,7 @@ static Bool R600TextureSetup(PicturePtr pPict, PixmapPtr pPix, } if (unit == 0) { - if (!accel_state->has_mask) { + if (!accel_state->msk_pic) { if (PICT_FORMAT_RGB(pPict->format) == 0) { pix_r = SQ_SEL_0; pix_g = SQ_SEL_0; @@ -1234,30 +1260,25 @@ static Bool R600TextureSetup(PicturePtr pPict, PixmapPtr pPix, tex_samp.id = unit; tex_samp.border_color = SQ_TEX_BORDER_COLOR_TRANS_BLACK; - if (pPict->repeat) { - switch (pPict->repeatType) { - case RepeatNormal: - tex_samp.clamp_x = SQ_TEX_WRAP; - tex_samp.clamp_y = SQ_TEX_WRAP; - break; - case RepeatPad: - tex_samp.clamp_x = SQ_TEX_CLAMP_LAST_TEXEL; - tex_samp.clamp_y = SQ_TEX_CLAMP_LAST_TEXEL; - break; - case RepeatReflect: - tex_samp.clamp_x = SQ_TEX_MIRROR; - tex_samp.clamp_y = SQ_TEX_MIRROR; - break; - case RepeatNone: - tex_samp.clamp_x = SQ_TEX_CLAMP_BORDER; - tex_samp.clamp_y = SQ_TEX_CLAMP_BORDER; - break; - default: - RADEON_FALLBACK(("Bad repeat 0x%x\n", pPict->repeatType)); - } - } else { + switch (repeatType) { + case RepeatNormal: + tex_samp.clamp_x = SQ_TEX_WRAP; + tex_samp.clamp_y = SQ_TEX_WRAP; + break; + case RepeatPad: + tex_samp.clamp_x = SQ_TEX_CLAMP_LAST_TEXEL; + tex_samp.clamp_y = SQ_TEX_CLAMP_LAST_TEXEL; + break; + case RepeatReflect: + tex_samp.clamp_x = SQ_TEX_MIRROR; + tex_samp.clamp_y = SQ_TEX_MIRROR; + break; + case RepeatNone: tex_samp.clamp_x = SQ_TEX_CLAMP_BORDER; tex_samp.clamp_y = SQ_TEX_CLAMP_BORDER; + break; + default: + RADEON_FALLBACK(("Bad repeat 0x%x\n", repeatType)); } switch (pPict->filter) { @@ -1323,6 +1344,9 @@ static Bool R600CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskP if (op >= (int) (sizeof(R600BlendOp) / sizeof(R600BlendOp[0]))) RADEON_FALLBACK(("Unsupported Composite op 0x%x\n", op)); + if (!pSrcPicture->pDrawable) + RADEON_FALLBACK(("Solid or gradient pictures not supported yet\n")); + pSrcPixmap = RADEONGetDrawablePixmap(pSrcPicture->pDrawable); max_tex_w = 8192; @@ -1397,7 +1421,7 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture, /* return FALSE; */ if (pMask) { - accel_state->has_mask = TRUE; + accel_state->msk_pic = pMaskPicture; if (pMaskPicture->componentAlpha) { accel_state->component_alpha = TRUE; if (R600BlendOp[op].src_alpha) @@ -1409,7 +1433,7 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture, accel_state->src_alpha = FALSE; } } else { - accel_state->has_mask = FALSE; + accel_state->msk_pic = NULL; accel_state->component_alpha = FALSE; accel_state->src_alpha = FALSE; } @@ -1432,6 +1456,7 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture, CLEAR (ps_conf); accel_state->ib = RADEONCPGetBuffer(pScrn); + r600_vb_get(pScrn); /* Init */ start_3d(pScrn, accel_state->ib); @@ -1442,18 +1467,24 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture, EREG(accel_state->ib, PA_CL_VTE_CNTL, VTX_XY_FMT_bit); EREG(accel_state->ib, PA_CL_CLIP_CNTL, CLIP_DISABLE_bit); + set_generic_scissor(pScrn, accel_state->ib, 0, 0, pDst->drawable.width, pDst->drawable.height); + set_screen_scissor(pScrn, accel_state->ib, 0, 0, pDst->drawable.width, pDst->drawable.height); + set_window_scissor(pScrn, accel_state->ib, 0, 0, pDst->drawable.width, pDst->drawable.height); + if (!R600TextureSetup(pSrcPicture, pSrc, 0)) { - R600IBDiscard(pScrn, accel_state->ib); - return FALSE; + R600IBDiscard(pScrn, accel_state->ib); + r600_vb_discard(pScrn); + return FALSE; } if (pMask) { - if (!R600TextureSetup(pMaskPicture, pMask, 1)) { - R600IBDiscard(pScrn, accel_state->ib); - return FALSE; - } + if (!R600TextureSetup(pMaskPicture, pMask, 1)) { + R600IBDiscard(pScrn, accel_state->ib); + r600_vb_discard(pScrn); + return FALSE; + } } else - accel_state->is_transform[1] = FALSE; + accel_state->is_transform[1] = FALSE; if (pMask) { set_bool_consts(pScrn, accel_state->ib, SQ_BOOL_CONST_vs, (1 << 0)); @@ -1569,8 +1600,6 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture, SEL_CENTROID_bit)); EREG(accel_state->ib, SPI_INTERP_CONTROL_0, 0); - accel_state->vb_index = 0; - return TRUE; } @@ -1598,18 +1627,16 @@ static void R600Composite(PixmapPtr pDst, srcBottomRight.x = IntToxFixed(srcX + w); srcBottomRight.y = IntToxFixed(srcY + h); - if (accel_state->has_mask) { + if (accel_state->msk_pic) { xPointFixed maskTopLeft, maskTopRight, maskBottomLeft, maskBottomRight; - if (((accel_state->vb_index + 3) * 24) > (accel_state->ib->total / 2)) { - R600DoneComposite(pDst); - accel_state->vb_index = 0; - accel_state->ib = RADEONCPGetBuffer(pScrn); - } + if (((accel_state->vb_index + 3) * 24) > accel_state->vb_total) { + R600DoneComposite(pDst); + accel_state->ib = RADEONCPGetBuffer(pScrn); + r600_vb_get(pScrn); + } - vb = (pointer)((char*)accel_state->ib->address + - (accel_state->ib->total / 2) + - accel_state->vb_index * 24); + vb = (pointer)((char*)accel_state->vb_ptr+accel_state->vb_index*24); maskTopLeft.x = IntToxFixed(maskX); maskTopLeft.y = IntToxFixed(maskY); @@ -1642,15 +1669,13 @@ static void R600Composite(PixmapPtr pDst, vb[17] = xFixedToFloat(maskBottomRight.y); } else { - if (((accel_state->vb_index + 3) * 16) > (accel_state->ib->total / 2)) { - R600DoneComposite(pDst); - accel_state->vb_index = 0; - accel_state->ib = RADEONCPGetBuffer(pScrn); - } + if (((accel_state->vb_index + 3) * 16) > accel_state->vb_total) { + R600DoneComposite(pDst); + accel_state->ib = RADEONCPGetBuffer(pScrn); + r600_vb_get(pScrn); + } - vb = (pointer)((char*)accel_state->ib->address + - (accel_state->ib->total / 2) + - accel_state->vb_index * 16); + vb = (pointer)((char*)accel_state->vb_ptr+accel_state->vb_index*16); vb[0] = (float)dstX; vb[1] = (float)dstY; @@ -1684,16 +1709,13 @@ static void R600DoneComposite(PixmapPtr pDst) CLEAR (vtx_res); if (accel_state->vb_index == 0) { - R600IBDiscard(pScrn, accel_state->ib); - return; + R600IBDiscard(pScrn, accel_state->ib); + r600_vb_discard(pScrn); + return; } - accel_state->vb_mc_addr = info->gartLocation + info->dri->bufStart + - (accel_state->ib->idx * accel_state->ib->total) + (accel_state->ib->total / 2); - - /* Vertex buffer setup */ - if (accel_state->has_mask) { + if (accel_state->msk_pic) { accel_state->vb_size = accel_state->vb_index * 24; vtx_res.id = SQ_VTX_RESOURCE_vs; vtx_res.vtx_size_dw = 24 / 4; @@ -1712,6 +1734,7 @@ static void R600DoneComposite(PixmapPtr pDst) if ((info->ChipFamily == CHIP_FAMILY_RV610) || (info->ChipFamily == CHIP_FAMILY_RV620) || (info->ChipFamily == CHIP_FAMILY_RS780) || + (info->ChipFamily == CHIP_FAMILY_RS880) || (info->ChipFamily == CHIP_FAMILY_RV710)) cp_set_surface_sync(pScrn, accel_state->ib, TC_ACTION_ENA_bit, accel_state->vb_size, accel_state->vb_mc_addr); @@ -1740,7 +1763,7 @@ static void R600DoneComposite(PixmapPtr pDst) Bool R600CopyToVRAM(ScrnInfoPtr pScrn, char *src, int src_pitch, - uint32_t dst_pitch, uint32_t dst_mc_addr, uint32_t dst_height, int bpp, + uint32_t dst_pitch, uint32_t dst_mc_addr, uint32_t dst_width, uint32_t dst_height, int bpp, int x, int y, int w, int h) { RADEONInfoPtr info = RADEONPTR(pScrn); @@ -1794,7 +1817,7 @@ R600CopyToVRAM(ScrnInfoPtr pScrn, /* blit from scratch to vram */ R600DoPrepareCopy(pScrn, scratch_pitch, w, oldhpass, offset, bpp, - dst_pitch, dst_height, dst_mc_addr, bpp, + dst_pitch, dst_width, dst_height, dst_mc_addr, bpp, 3, 0xffffffff); R600AppendCopyVertex(pScrn, 0, 0, x, y, w, oldhpass); R600DoCopy(pScrn); @@ -1802,6 +1825,7 @@ R600CopyToVRAM(ScrnInfoPtr pScrn, } R600IBDiscard(pScrn, scratch); + r600_vb_discard(pScrn); return TRUE; } @@ -1814,12 +1838,11 @@ R600UploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, RADEONInfoPtr info = RADEONPTR(pScrn); uint32_t dst_pitch = exaGetPixmapPitch(pDst) / (pDst->drawable.bitsPerPixel / 8); uint32_t dst_mc_addr = exaGetPixmapOffset(pDst) + info->fbLocation + pScrn->fbOffset; - uint32_t dst_height = pDst->drawable.height; int bpp = pDst->drawable.bitsPerPixel; return R600CopyToVRAM(pScrn, src, src_pitch, - dst_pitch, dst_mc_addr, dst_height, bpp, + dst_pitch, dst_mc_addr, pDst->drawable.width, pDst->drawable.height, bpp, x, y, w, h); } @@ -1841,6 +1864,10 @@ R600DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, int wpass = w * (bpp/8); drmBufPtr scratch; + /* RV740 seems to be particularly problematic with small xfers */ + if ((info->ChipFamily == CHIP_FAMILY_RV740) && (w < 32 || h < 32)) + return FALSE; + if (src_pitch & 7) return FALSE; @@ -1854,7 +1881,7 @@ R600DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, /* blit from vram to scratch */ R600DoPrepareCopy(pScrn, src_pitch, src_width, src_height, src_mc_addr, bpp, - scratch_pitch, hpass, scratch_mc_addr, bpp, + scratch_pitch, src_width, hpass, scratch_mc_addr, bpp, 3, 0xffffffff); R600AppendCopyVertex(pScrn, x, y, 0, 0, w, hpass); R600DoCopy(pScrn); @@ -1871,7 +1898,7 @@ R600DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, /* blit from vram to scratch */ R600DoPrepareCopy(pScrn, src_pitch, src_width, src_height, src_mc_addr, bpp, - scratch_pitch, hpass, scratch_mc_addr + scratch_offset, bpp, + scratch_pitch, src_width, hpass, scratch_mc_addr + scratch_offset, bpp, 3, 0xffffffff); R600AppendCopyVertex(pScrn, x, y, 0, 0, w, hpass); R600DoCopy(pScrn); @@ -1888,6 +1915,7 @@ R600DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, } R600IBDiscard(pScrn, scratch); + r600_vb_discard(pScrn); return TRUE; diff --git a/src/r600_shader.c b/src/r600_shader.c index ceabad8..584deb4 100644 --- a/src/r600_shader.c +++ b/src/r600_shader.c @@ -546,7 +546,7 @@ int R600_xv_vs(RADEONChipFamily ChipSet, uint32_t* shader) DST_GPR(0), DST_REL(ABSOLUTE), DST_ELEM(ELEM_X), - CLAMP(1)); + CLAMP(0)); /* 5 texY / h */ shader[i++] = ALU_DWORD0(SRC0_SEL(0), @@ -573,7 +573,7 @@ int R600_xv_vs(RADEONChipFamily ChipSet, uint32_t* shader) DST_GPR(0), DST_REL(ABSOLUTE), DST_ELEM(ELEM_Y), - CLAMP(1)); + CLAMP(0)); /* 6/7 */ shader[i++] = VTX_DWORD0(VTX_INST(SQ_VTX_INST_FETCH), @@ -1715,7 +1715,7 @@ int R600_comp_vs(RADEONChipFamily ChipSet, uint32_t* shader) DST_GPR(1), DST_REL(ABSOLUTE), DST_ELEM(ELEM_X), - CLAMP(1)); + CLAMP(0)); /* 18 srcY / h */ shader[i++] = ALU_DWORD0(SRC0_SEL(1), @@ -1742,7 +1742,7 @@ int R600_comp_vs(RADEONChipFamily ChipSet, uint32_t* shader) DST_GPR(1), DST_REL(ABSOLUTE), DST_ELEM(ELEM_Y), - CLAMP(1)); + CLAMP(0)); /* 19 maskX / w */ shader[i++] = ALU_DWORD0(SRC0_SEL(0), @@ -1769,7 +1769,7 @@ int R600_comp_vs(RADEONChipFamily ChipSet, uint32_t* shader) DST_GPR(0), DST_REL(ABSOLUTE), DST_ELEM(ELEM_X), - CLAMP(1)); + CLAMP(0)); /* 20 maskY / h */ shader[i++] = ALU_DWORD0(SRC0_SEL(0), @@ -1796,7 +1796,7 @@ int R600_comp_vs(RADEONChipFamily ChipSet, uint32_t* shader) DST_GPR(0), DST_REL(ABSOLUTE), DST_ELEM(ELEM_Y), - CLAMP(1)); + CLAMP(0)); /* 21 */ shader[i++] = 0x00000000; shader[i++] = 0x00000000; @@ -2068,7 +2068,7 @@ int R600_comp_vs(RADEONChipFamily ChipSet, uint32_t* shader) DST_GPR(0), DST_REL(ABSOLUTE), DST_ELEM(ELEM_X), - CLAMP(1)); + CLAMP(0)); /* 38 srcY / h */ shader[i++] = ALU_DWORD0(SRC0_SEL(0), @@ -2095,7 +2095,7 @@ int R600_comp_vs(RADEONChipFamily ChipSet, uint32_t* shader) DST_GPR(0), DST_REL(ABSOLUTE), DST_ELEM(ELEM_Y), - CLAMP(1)); + CLAMP(0)); /* 39 */ shader[i++] = 0x00000000; diff --git a/src/r600_state.h b/src/r600_state.h index 44e7600..8f20e42 100644 --- a/src/r600_state.h +++ b/src/r600_state.h @@ -279,4 +279,9 @@ draw_immd(ScrnInfoPtr pScrn, drmBufPtr ib, draw_config_t *draw_conf, uint32_t *i void draw_auto(ScrnInfoPtr pScrn, drmBufPtr ib, draw_config_t *draw_conf); +void +r600_vb_get(ScrnInfoPtr pScrn); +void +r600_vb_discard(ScrnInfoPtr pScrn); + #endif diff --git a/src/r600_textured_videofuncs.c b/src/r600_textured_videofuncs.c index 6af0949..5dc79c9 100644 --- a/src/r600_textured_videofuncs.c +++ b/src/r600_textured_videofuncs.c @@ -66,18 +66,18 @@ R600DoneTexturedVideo(ScrnInfoPtr pScrn) CLEAR (vtx_res); if (accel_state->vb_index == 0) { - R600IBDiscard(pScrn, accel_state->ib); - return; + R600IBDiscard(pScrn, accel_state->ib); + r600_vb_discard(pScrn); + return; } - accel_state->vb_mc_addr = info->gartLocation + info->dri->bufStart + - (accel_state->ib->idx * accel_state->ib->total) + (accel_state->ib->total / 2); accel_state->vb_size = accel_state->vb_index * 16; /* flush vertex cache */ if ((info->ChipFamily == CHIP_FAMILY_RV610) || (info->ChipFamily == CHIP_FAMILY_RV620) || (info->ChipFamily == CHIP_FAMILY_RS780) || + (info->ChipFamily == CHIP_FAMILY_RS880) || (info->ChipFamily == CHIP_FAMILY_RV710)) cp_set_surface_sync(pScrn, accel_state->ib, TC_ACTION_ENA_bit, accel_state->vb_size, accel_state->vb_mc_addr); @@ -234,6 +234,7 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) #endif accel_state->ib = RADEONCPGetBuffer(pScrn); + r600_vb_get(pScrn); /* Init */ start_3d(pScrn, accel_state->ib); @@ -244,6 +245,10 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) EREG(accel_state->ib, PA_CL_VTE_CNTL, VTX_XY_FMT_bit); EREG(accel_state->ib, PA_CL_CLIP_CNTL, CLIP_DISABLE_bit); + set_generic_scissor(pScrn, accel_state->ib, 0, 0, pPixmap->drawable.width, pPixmap->drawable.height); + set_screen_scissor(pScrn, accel_state->ib, 0, 0, pPixmap->drawable.width, pPixmap->drawable.height); + set_window_scissor(pScrn, accel_state->ib, 0, 0, pPixmap->drawable.width, pPixmap->drawable.height); + accel_state->vs_mc_addr = info->fbLocation + pScrn->fbOffset + accel_state->shaders->offset + accel_state->xv_vs_offset; @@ -297,7 +302,7 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) switch(pPriv->id) { case FOURCC_YV12: case FOURCC_I420: - accel_state->src_mc_addr[0] = pPriv->src_offset; + accel_state->src_mc_addr[0] = pPriv->src_offset + info->fbLocation + pScrn->fbOffset; accel_state->src_size[0] = accel_state->src_pitch[0] * pPriv->h; /* flush texture cache */ @@ -392,7 +397,7 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) case FOURCC_UYVY: case FOURCC_YUY2: default: - accel_state->src_mc_addr[0] = pPriv->src_offset; + accel_state->src_mc_addr[0] = pPriv->src_offset + info->fbLocation + pScrn->fbOffset; accel_state->src_size[0] = accel_state->src_pitch[0] * pPriv->h; /* flush texture cache */ @@ -547,22 +552,18 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) } } - accel_state->vb_index = 0; - while (nBox--) { int srcX, srcY, srcw, srch; int dstX, dstY, dstw, dsth; float *vb; - if (((accel_state->vb_index + 3) * 16) > (accel_state->ib->total / 2)) { - R600DoneTexturedVideo(pScrn); - accel_state->vb_index = 0; - accel_state->ib = RADEONCPGetBuffer(pScrn); - } + if (((accel_state->vb_index + 3) * 16) > accel_state->vb_total) { + R600DoneTexturedVideo(pScrn); + accel_state->ib = RADEONCPGetBuffer(pScrn); + r600_vb_get(pScrn); + } - vb = (pointer)((char*)accel_state->ib->address + - (accel_state->ib->total / 2) + - accel_state->vb_index * 16); + vb = (pointer)((char*)accel_state->vb_ptr+accel_state->vb_index*16); dstX = pBox->x1 + dstxoff; dstY = pBox->y1 + dstyoff; diff --git a/src/r6xx_accel.c b/src/r6xx_accel.c index bce597b..0457f7d 100644 --- a/src/r6xx_accel.c +++ b/src/r6xx_accel.c @@ -96,75 +96,6 @@ wait_3d_idle(ScrnInfoPtr pScrn, drmBufPtr ib) } -static void -reset_cb(ScrnInfoPtr pScrn, drmBufPtr ib) -{ - int i; - - PACK0(ib, CB_COLOR0_INFO, 8); - for (i = 0; i < 8; i++) - E32(ib, 0); -} - -static void -reset_td_samplers(ScrnInfoPtr pScrn, drmBufPtr ib) -{ - int i; - - wait_3d_idle(pScrn, ib); - - PACK0(ib, TD_PS_SAMPLER0_BORDER_RED, 4*TD_PS_SAMPLER0_BORDER_RED_num); - for (i = 0; i < 4*TD_PS_SAMPLER0_BORDER_RED_num; i++) - E32(ib, 0); - PACK0(ib, TD_VS_SAMPLER0_BORDER_RED, 4*TD_VS_SAMPLER0_BORDER_RED_num); - for (i = 0; i < 4*TD_VS_SAMPLER0_BORDER_RED_num; i++) - E32(ib, 0); - - wait_3d_idle(pScrn, ib); -} - -static void -reset_sampler_const (ScrnInfoPtr pScrn, drmBufPtr ib) -{ - int i; - - for (i = 0; i < SQ_TEX_SAMPLER_WORD_all_num; i++) { - PACK0(ib, SQ_TEX_SAMPLER_WORD + i * SQ_TEX_SAMPLER_WORD_offset, 3); - E32(ib, SQ_TEX_DEPTH_COMPARE_LESSEQUAL << DEPTH_COMPARE_FUNCTION_shift); - E32(ib, MAX_LOD_mask); - E32(ib, 0); - } -} - -static void -reset_dx9_alu_consts(ScrnInfoPtr pScrn, drmBufPtr ib) -{ - int i; - - const int count = SQ_ALU_CONSTANT_all_num * (SQ_ALU_CONSTANT_offset >> 2); - - PACK0(ib, SQ_ALU_CONSTANT, count); - for (i = 0; i < count; i++) - EFLOAT(ib, 0.0); -} - -static void -reset_bool_loop_const(ScrnInfoPtr pScrn, drmBufPtr ib) -{ - int i; - - - PACK0(ib, SQ_BOOL_CONST, SQ_BOOL_CONST_all_num); - for (i = 0; i < SQ_BOOL_CONST_all_num; i++) - E32(ib, 0); - - PACK0(ib, SQ_LOOP_CONST, SQ_LOOP_CONST_all_num); - - for (i = 0; i < SQ_LOOP_CONST_all_num; i++) - E32(ib, 0); - -} - void start_3d(ScrnInfoPtr pScrn, drmBufPtr ib) { @@ -197,6 +128,7 @@ sq_setup(ScrnInfoPtr pScrn, drmBufPtr ib, sq_config_t *sq_conf) if ((info->ChipFamily == CHIP_FAMILY_RV610) || (info->ChipFamily == CHIP_FAMILY_RV620) || (info->ChipFamily == CHIP_FAMILY_RS780) || + (info->ChipFamily == CHIP_FAMILY_RS880) || (info->ChipFamily == CHIP_FAMILY_RV710)) sq_config = 0; // no VC else @@ -654,10 +586,8 @@ set_default_state(ScrnInfoPtr pScrn, drmBufPtr ib) memset(&tex_res, 0, sizeof(tex_resource_t)); memset(&fs_conf, 0, sizeof(shader_config_t)); -#if 1 if (accel_state->XInited3D) return; -#endif accel_state->XInited3D = TRUE; @@ -690,11 +620,6 @@ set_default_state(ScrnInfoPtr pScrn, drmBufPtr ib) 0)); } - reset_td_samplers(pScrn, ib); - reset_dx9_alu_consts(pScrn, ib); - reset_bool_loop_const (pScrn, ib); - reset_sampler_const (pScrn, ib); - // SQ sq_conf.ps_prio = 0; sq_conf.vs_prio = 1; @@ -738,6 +663,7 @@ set_default_state(ScrnInfoPtr pScrn, drmBufPtr ib) case CHIP_FAMILY_RV610: case CHIP_FAMILY_RV620: case CHIP_FAMILY_RS780: + case CHIP_FAMILY_RS880: default: sq_conf.num_ps_gprs = 84; sq_conf.num_vs_gprs = 36; @@ -784,6 +710,7 @@ set_default_state(ScrnInfoPtr pScrn, drmBufPtr ib) sq_conf.num_es_stack_entries = 0; break; case CHIP_FAMILY_RV730: + case CHIP_FAMILY_RV740: sq_conf.num_ps_gprs = 84; sq_conf.num_vs_gprs = 36; sq_conf.num_temp_gprs = 4; @@ -853,24 +780,12 @@ set_default_state(ScrnInfoPtr pScrn, drmBufPtr ib) EREG(ib, SX_ALPHA_REF, 0); // CB - reset_cb(pScrn, ib); - PACK0(ib, CB_BLEND_RED, 4); E32(ib, 0x00000000); E32(ib, 0x00000000); E32(ib, 0x00000000); E32(ib, 0x00000000); - /* CB_COLOR_CONTROL.PER_MRT_BLEND is off */ - // RV6xx+ have per-MRT blend - if (info->ChipFamily > CHIP_FAMILY_R600) { - PACK0(ib, CB_BLEND0_CONTROL, CB_BLEND0_CONTROL_num); - for (i = 0; i < CB_BLEND0_CONTROL_num; i++) - E32(ib, 0); - } - - EREG(ib, CB_BLEND_CONTROL, 0); - if (info->ChipFamily < CHIP_FAMILY_RV770) { PACK0(ib, CB_FOG_RED, 3); E32(ib, 0x00000000); @@ -878,7 +793,6 @@ set_default_state(ScrnInfoPtr pScrn, drmBufPtr ib) E32(ib, 0x00000000); } - EREG(ib, CB_COLOR_CONTROL, 0); PACK0(ib, CB_CLRCMP_CONTROL, 4); E32(ib, 1 << CLRCMP_FCN_SEL_shift); // CB_CLRCMP_CONTROL: use CLRCMP_FCN_SRC E32(ib, 0); // CB_CLRCMP_SRC @@ -896,11 +810,8 @@ set_default_state(ScrnInfoPtr pScrn, drmBufPtr ib) EREG(ib, CB_TARGET_MASK, (0x0f << TARGET0_ENABLE_shift)); // SC - set_generic_scissor(pScrn, ib, 0, 0, 8192, 8192); - set_screen_scissor(pScrn, ib, 0, 0, 8192, 8192); EREG(ib, PA_SC_WINDOW_OFFSET, ((0 << WINDOW_X_OFFSET_shift) | (0 << WINDOW_Y_OFFSET_shift))); - set_window_scissor(pScrn, ib, 0, 0, 8192, 8192); EREG(ib, PA_SC_CLIPRECT_RULE, CLIP_RULE_mask); @@ -947,7 +858,6 @@ set_default_state(ScrnInfoPtr pScrn, drmBufPtr ib) EFLOAT(ib, 0.0f); // PA_CL_VPORT_YOFFSET EFLOAT(ib, 0.0f); // PA_CL_VPORT_ZSCALE EFLOAT(ib, 0.0f); // PA_CL_VPORT_ZOFFSET - EREG(ib, PA_CL_CLIP_CNTL, (CLIP_DISABLE_bit | DX_CLIP_SPACE_DEF_bit)); EREG(ib, PA_CL_VTE_CNTL, 0); EREG(ib, PA_CL_VS_OUT_CNTL, 0); EREG(ib, PA_CL_NANINF_CNTL, 0); @@ -957,11 +867,6 @@ set_default_state(ScrnInfoPtr pScrn, drmBufPtr ib) EFLOAT(ib, 1.0); // PA_CL_GB_HORZ_CLIP_ADJ EFLOAT(ib, 1.0); // PA_CL_GB_HORZ_DISC_ADJ - /* user clipping planes are disabled by default */ - PACK0(ib, PA_CL_UCP_0_X, 24); - for (i = 0; i < 24; i++) - EFLOAT(ib, 0.0); - // SU EREG(ib, PA_SU_SC_MODE_CNTL, FACE_bit); EREG(ib, PA_SU_POINT_SIZE, 0); @@ -973,7 +878,7 @@ set_default_state(ScrnInfoPtr pScrn, drmBufPtr ib) EREG(ib, PA_SU_POLY_OFFSET_FRONT_OFFSET, 0); EREG(ib, PA_SU_LINE_CNTL, (8 << PA_SU_LINE_CNTL__WIDTH_shift)); /* Line width 1 pixel */ - EREG(ib, PA_SU_VTX_CNTL, ((2 << PA_SU_VTX_CNTL__ROUND_MODE_shift) | + EREG(ib, PA_SU_VTX_CNTL, ((2 << PA_SU_VTX_CNTL__ROUND_MODE_shift) | PIX_CENTER_bit | (5 << QUANT_MODE_shift))); /* Round to Even, fixed point 1/256 */ EREG(ib, PA_SU_POLY_OFFSET_CLAMP, 0); @@ -983,20 +888,11 @@ set_default_state(ScrnInfoPtr pScrn, drmBufPtr ib) else EREG(ib, R7xx_SPI_THREAD_GROUPING, (1 << PS_GROUPING_shift)); - EREG(ib, SPI_INTERP_CONTROL_0, ((2 << PNT_SPRITE_OVRD_X_shift) | - (3 << PNT_SPRITE_OVRD_Y_shift) | - (0 << PNT_SPRITE_OVRD_Z_shift) | - (1 << PNT_SPRITE_OVRD_W_shift))); /* s,t,0,1 */ EREG(ib, SPI_INPUT_Z, 0); EREG(ib, SPI_FOG_CNTL, 0); EREG(ib, SPI_FOG_FUNC_SCALE, 0); EREG(ib, SPI_FOG_FUNC_BIAS, 0); - PACK0(ib, SPI_VS_OUT_ID_0, SPI_VS_OUT_ID_0_num); - for (i = 0; i < SPI_VS_OUT_ID_0_num; i++) /* identity mapping */ - E32(ib, 0x03020100 + i*0x04040404); - EREG(ib, SPI_VS_OUT_CONFIG, 0); - // clear FS fs_setup(pScrn, ib, &fs_conf); @@ -1028,24 +924,6 @@ set_default_state(ScrnInfoPtr pScrn, drmBufPtr ib) EREG(ib, VGT_VTX_CNT_EN, 0); EREG(ib, VGT_STRMOUT_BUFFER_EN, 0); - // clear tex resources - PS - for (i = 0; i < 16; i++) { - tex_res.id = i; - set_tex_resource(pScrn, ib, &tex_res); - } - - // clear tex resources - VS - for (i = 160; i < 164; i++) { - tex_res.id = i; - set_tex_resource(pScrn, ib, &tex_res); - } - - // clear tex resources - FS - for (i = 320; i < 335; i++) { - tex_res.id = i; - set_tex_resource(pScrn, ib, &tex_res); - } - } @@ -1101,3 +979,23 @@ draw_auto(ScrnInfoPtr pScrn, drmBufPtr ib, draw_config_t *draw_conf) E32(ib, draw_conf->num_indices); E32(ib, draw_conf->vgt_draw_initiator); } + +void +r600_vb_get(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + struct radeon_accel_state *accel_state = info->accel_state; + + accel_state->vb_mc_addr = info->gartLocation + info->dri->bufStart + + (accel_state->ib->idx * accel_state->ib->total) + + (accel_state->ib->total / 2); + accel_state->vb_total = (accel_state->ib->total / 2); + accel_state->vb_ptr = (pointer)((char*)accel_state->ib->address + + (accel_state->ib->total / 2)); + accel_state->vb_index = 0; +} + +void +r600_vb_discard(ScrnInfoPtr pScrn) +{ +} diff --git a/src/radeon.h b/src/radeon.h index 9ce251a..3a3631e 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -75,6 +75,7 @@ #include "dri.h" #include "GL/glxint.h" #include "xf86drm.h" +#include "radeon_drm.h" #ifdef DAMAGE #include "damage.h" @@ -85,6 +86,15 @@ #include "xf86Crtc.h" #include "X11/Xatom.h" +#ifdef XF86DRM_MODE +#include "radeon_bo.h" +#include "radeon_cs.h" +#include "radeon_dri2.h" +#include "drmmode_display.h" +#else +#include "radeon_dummy_bufmgr.h" +#endif + /* Render support */ #ifdef RENDER #include "picturestr.h" @@ -262,6 +272,7 @@ typedef struct { #define RADEON_PLL_PREFER_LOW_POST_DIV (1 << 8) #define RADEON_PLL_PREFER_HIGH_POST_DIV (1 << 9) #define RADEON_PLL_USE_FRAC_FB_DIV (1 << 10) +#define RADEON_PLL_PREFER_CLOSEST_LOWER (1 << 11) typedef struct { uint16_t reference_freq; @@ -333,6 +344,7 @@ typedef enum { CHIP_FAMILY_RV770, CHIP_FAMILY_RV730, CHIP_FAMILY_RV710, + CHIP_FAMILY_RV740, CHIP_FAMILY_LAST } RADEONChipFamily; @@ -448,6 +460,11 @@ typedef struct { typedef struct _atomBiosHandle *atomBiosHandlePtr; +struct radeon_exa_pixmap_priv { + struct radeon_bo *bo; + int flags; +}; + typedef struct { uint32_t pci_device_id; RADEONChipFamily chip_family; @@ -458,6 +475,25 @@ typedef struct { int singledac; } RADEONCardInfo; +#define RADEON_2D_EXA_COPY 1 +#define RADEON_2D_EXA_SOLID 2 + +struct radeon_2d_state { + int op; // + uint32_t dst_pitch_offset; + uint32_t src_pitch_offset; + uint32_t dp_gui_master_cntl; + uint32_t dp_cntl; + uint32_t dp_write_mask; + uint32_t dp_brush_frgd_clr; + uint32_t dp_brush_bkgd_clr; + uint32_t dp_src_frgd_clr; + uint32_t dp_src_bkgd_clr; + uint32_t default_sc_bottom_right; + struct radeon_bo *dst_bo; + struct radeon_bo *src_bo; +}; + #ifdef XF86DRI struct radeon_cp { Bool CPRuns; /* CP is running */ @@ -636,9 +672,15 @@ struct radeon_accel_state { #define EXA_ENGINEMODE_2D 1 #define EXA_ENGINEMODE_3D 2 + int composite_op; + PicturePtr dst_pic; + PicturePtr msk_pic; + PicturePtr src_pic; + PixmapPtr dst_pix; + PixmapPtr msk_pix; + PixmapPtr src_pix; Bool is_transform[2]; PictTransform *transform[2]; - Bool has_mask; /* Whether we are tiling horizontally and vertically */ Bool need_src_tile_x; Bool need_src_tile_y; @@ -650,6 +692,10 @@ struct radeon_accel_state { drmBufPtr ib; int vb_index; + uint64_t vb_mc_addr; + int vb_total; + void *vb_ptr; + uint32_t vb_size; // shader storage ExaOffscreenArea *shaders; @@ -679,8 +725,6 @@ struct radeon_accel_state { uint64_t vs_mc_addr; uint32_t ps_size; uint64_t ps_mc_addr; - uint32_t vb_size; - uint64_t vb_mc_addr; // UTS/DFS drmBufPtr scratch; @@ -823,6 +867,9 @@ typedef struct { RADEONCardType cardType; /* Current card is a PCI card */ struct radeon_cp *cp; struct radeon_dri *dri; +#ifdef XF86DRM_MODE + struct radeon_dri2 dri2; +#endif #ifdef USE_EXA Bool accelDFS; #endif @@ -935,6 +982,29 @@ typedef struct { float igp_ht_link_clk; float igp_ht_link_width; + int can_resize; + void (*reemit_current2d)(ScrnInfoPtr pScrn, int op); // emit the current 2D state into the IB + struct radeon_2d_state state_2d; + Bool kms_enabled; + struct radeon_bo *front_bo; +#ifdef XF86DRM_MODE + struct radeon_bo_manager *bufmgr; + struct radeon_cs_manager *csm; + struct radeon_cs *cs; + + struct radeon_bo *cursor_bo[2]; + uint64_t vram_size; + uint64_t gart_size; + drmmode_rec drmmode; +#else + /* fake bool */ + Bool cs; +#endif + + /* Xv bicubic filtering */ + struct radeon_bo *bicubic_bo; + void *bicubic_memory; + int bicubic_offset; } RADEONInfoRec, *RADEONInfoPtr; #define RADEONWaitForFifo(pScrn, entries) \ @@ -1016,6 +1086,7 @@ extern int RADEONCPStop(ScrnInfoPtr pScrn, RADEONInfoPtr info); # ifdef USE_XAA extern Bool RADEONSetupMemXAA_DRI(int scrnIndex, ScreenPtr pScreen); # endif +uint32_t radeonGetPixmapOffset(PixmapPtr pPix); #endif #ifdef USE_XAA @@ -1115,6 +1186,12 @@ extern void RADEONInitMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, extern void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore); +Bool RADEONGetRec(ScrnInfoPtr pScrn); +void RADEONFreeRec(ScrnInfoPtr pScrn); +Bool RADEONPreInitVisual(ScrnInfoPtr pScrn); +Bool RADEONPreInitWeight(ScrnInfoPtr pScrn); + + /* radeon_pm.c */ extern void RADEONPMInit(ScrnInfoPtr pScrn); extern void RADEONPMBlockHandler(ScrnInfoPtr pScrn); @@ -1189,6 +1266,7 @@ extern void RADEONUpdateHVPosition(xf86OutputPtr output, DisplayModePtr mode); /* radeon_video.c */ extern void RADEONInitVideo(ScreenPtr pScreen); extern void RADEONResetVideo(ScrnInfoPtr pScrn); +extern Bool radeon_load_bicubic_texture(ScrnInfoPtr pScrn); /* radeon_legacy_memory.c */ extern uint32_t @@ -1200,6 +1278,15 @@ extern void radeon_legacy_free_memory(ScrnInfoPtr pScrn, void *mem_struct); +#ifdef XF86DRM_MODE +extern void radeon_cs_flush_indirect(ScrnInfoPtr pScrn); +extern void radeon_ddx_cs_start(ScrnInfoPtr pScrn, + int num, const char *file, + const char *func, int line); +#endif +struct radeon_bo *radeon_get_pixmap_bo(PixmapPtr pPix); +void radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo); + #ifdef XF86DRI # ifdef USE_XAA /* radeon_accelfuncs.c */ @@ -1218,7 +1305,9 @@ do { \ #define RADEONCP_RELEASE(pScrn, info) \ do { \ - if (info->cp->CPInUse) { \ + if (info->cs) { \ + radeon_cs_flush_indirect(pScrn); \ + } else if (info->cp->CPInUse) { \ RADEON_PURGE_CACHE(); \ RADEON_WAIT_UNTIL_IDLE(); \ RADEONCPReleaseIndirect(pScrn); \ @@ -1253,7 +1342,7 @@ do { \ #define RADEONCP_REFRESH(pScrn, info) \ do { \ - if (!info->cp->CPInUse) { \ + if (!info->cp->CPInUse && !info->cs) { \ if (info->cp->needCacheFlush) { \ RADEON_PURGE_CACHE(); \ RADEON_PURGE_ZCACHE(); \ @@ -1284,54 +1373,59 @@ do { \ xf86DrvMsg(pScrn->scrnIndex, X_INFO, \ "BEGIN_RING(%d) in %s\n", (unsigned int)n, __FUNCTION__);\ } \ - if (++info->cp->dma_begin_count != 1) { \ + if (info->cs) { radeon_ddx_cs_start(pScrn, n, __FILE__, __func__, __LINE__); } else { \ + if (++info->cp->dma_begin_count != 1) { \ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ "BEGIN_RING without end at %s:%d\n", \ - info->cp->dma_debug_func, info->cp->dma_debug_lineno); \ + info->cp->dma_debug_func, info->cp->dma_debug_lineno); \ info->cp->dma_begin_count = 1; \ - } \ - info->cp->dma_debug_func = __FILE__; \ - info->cp->dma_debug_lineno = __LINE__; \ - if (!info->cp->indirectBuffer) { \ + } \ + info->cp->dma_debug_func = __FILE__; \ + info->cp->dma_debug_lineno = __LINE__; \ + if (!info->cp->indirectBuffer) { \ info->cp->indirectBuffer = RADEONCPGetBuffer(pScrn); \ info->cp->indirectStart = 0; \ - } else if (info->cp->indirectBuffer->used + (n) * (int)sizeof(uint32_t) > \ - info->cp->indirectBuffer->total) { \ + } else if (info->cp->indirectBuffer->used + (n) * (int)sizeof(uint32_t) > \ + info->cp->indirectBuffer->total) { \ RADEONCPFlushIndirect(pScrn, 1); \ + } \ + __expected = n; \ + __head = (pointer)((char *)info->cp->indirectBuffer->address + \ + info->cp->indirectBuffer->used); \ + __count = 0; \ } \ - __expected = n; \ - __head = (pointer)((char *)info->cp->indirectBuffer->address + \ - info->cp->indirectBuffer->used); \ - __count = 0; \ } while (0) #define ADVANCE_RING() do { \ - if (info->cp->dma_begin_count-- != 1) { \ + if (info->cs) radeon_cs_end(info->cs, __FILE__, __func__, __LINE__); else { \ + if (info->cp->dma_begin_count-- != 1) { \ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ "ADVANCE_RING without begin at %s:%d\n", \ __FILE__, __LINE__); \ info->cp->dma_begin_count = 0; \ - } \ - if (__count != __expected) { \ + } \ + if (__count != __expected) { \ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ "ADVANCE_RING count != expected (%d vs %d) at %s:%d\n", \ __count, __expected, __FILE__, __LINE__); \ - } \ - if (RADEON_VERBOSE) { \ + } \ + if (RADEON_VERBOSE) { \ xf86DrvMsg(pScrn->scrnIndex, X_INFO, \ "ADVANCE_RING() start: %d used: %d count: %d\n", \ info->cp->indirectStart, \ info->cp->indirectBuffer->used, \ __count * (int)sizeof(uint32_t)); \ + } \ + info->cp->indirectBuffer->used += __count * (int)sizeof(uint32_t); \ } \ - info->cp->indirectBuffer->used += __count * (int)sizeof(uint32_t); \ -} while (0) + } while (0) #define OUT_RING(x) do { \ if (RADEON_VERBOSE) { \ xf86DrvMsg(pScrn->scrnIndex, X_INFO, \ " OUT_RING(0x%08x)\n", (unsigned int)(x)); \ } \ + if (info->cs) radeon_cs_write_dword(info->cs, (x)); else \ __head[__count++] = (x); \ } while (0) @@ -1341,12 +1435,22 @@ do { \ OUT_RING(val); \ } while (0) +#define OUT_RING_RELOC(x, read_domains, write_domain) \ + do { \ + int _ret; \ + _ret = radeon_cs_write_reloc(info->cs, x, read_domains, write_domain, 0); \ + if (_ret) ErrorF("reloc emit failure %d\n", _ret); \ + } while(0) + + #define FLUSH_RING() \ do { \ if (RADEON_VERBOSE) \ xf86DrvMsg(pScrn->scrnIndex, X_INFO, \ "FLUSH_RING in %s\n", __FUNCTION__); \ - if (info->cp->indirectBuffer) \ + if (info->cs) \ + radeon_cs_flush_indirect(pScrn); \ + else if (info->cp->indirectBuffer) \ RADEONCPFlushIndirect(pScrn, 0); \ } while (0) @@ -1422,6 +1526,13 @@ do { \ #endif /* XF86DRI */ #if defined(XF86DRI) && defined(USE_EXA) + +#ifdef XF86DRM_MODE +#define CS_FULL(cs) ((cs)->cdw > 15 * 1024) +#else +#define CS_FULL(cs) FALSE +#endif + #define RADEON_SWITCH_TO_2D() \ do { \ uint32_t flush = 0; \ @@ -1432,8 +1543,12 @@ do { \ case EXA_ENGINEMODE_2D: \ break; \ } \ - if (flush && info->directRenderingEnabled) \ - RADEONCPFlushIndirect(pScrn, 1); \ + if (flush) { \ + if (info->cs) \ + radeon_cs_flush_indirect(pScrn); \ + else if (info->directRenderingEnabled) \ + RADEONCPFlushIndirect(pScrn, 1); \ + } \ info->accel_state->engineMode = EXA_ENGINEMODE_2D; \ } while (0); @@ -1442,16 +1557,21 @@ do { \ uint32_t flush = 0; \ switch (info->accel_state->engineMode) { \ case EXA_ENGINEMODE_UNKNOWN: \ - case EXA_ENGINEMODE_2D: \ flush = 1; \ + break; \ + case EXA_ENGINEMODE_2D: \ + flush = !info->cs || CS_FULL(info->cs); \ case EXA_ENGINEMODE_3D: \ break; \ } \ if (flush) { \ - if (info->directRenderingEnabled) \ + if (info->cs) \ + radeon_cs_flush_indirect(pScrn); \ + else if (info->directRenderingEnabled) \ RADEONCPFlushIndirect(pScrn, 1); \ - RADEONInit3DEngine(pScrn); \ } \ + if (!info->accel_state->XInited3D) \ + RADEONInit3DEngine(pScrn); \ info->accel_state->engineMode = EXA_ENGINEMODE_3D; \ } while (0); #else @@ -1500,4 +1620,9 @@ static __inline__ int radeon_timedout(const struct timeval *endtime) now.tv_usec > endtime->tv_usec : now.tv_sec > endtime->tv_sec; } +enum { + RADEON_CREATE_PIXMAP_TILING_MACRO = 0x10000000, + RADEON_CREATE_PIXMAP_TILING_MICRO = 0x20000000, +}; + #endif /* _RADEON_H_ */ diff --git a/src/radeon_accel.c b/src/radeon_accel.c index f90b386..02905dd 100644 --- a/src/radeon_accel.c +++ b/src/radeon_accel.c @@ -375,6 +375,9 @@ void RADEONEngineRestore(ScrnInfoPtr pScrn) RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; + if (info->cs) + return; + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, "EngineRestore (%d/%d)\n", info->CurrentLayout.pixel_code, @@ -421,6 +424,24 @@ void RADEONEngineRestore(ScrnInfoPtr pScrn) info->accel_state->XInited3D = FALSE; } +static int RADEONDRMGetNumPipes(ScrnInfoPtr pScrn, int *num_pipes) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + if (info->dri->pKernelDRMVersion->version_major < 2) { + drm_radeon_getparam_t np; + + memset(&np, 0, sizeof(np)); + np.param = RADEON_PARAM_NUM_GB_PIPES; + np.value = num_pipes; + return drmCommandWriteRead(info->dri->drmFD, DRM_RADEON_GETPARAM, &np, sizeof(np)); + } else { + struct drm_radeon_info np2; + np2.value = (unsigned long)num_pipes; + np2.request = RADEON_INFO_NUM_GB_PIPES; + return drmCommandWriteRead(info->dri->drmFD, DRM_RADEON_INFO, &np2, sizeof(np2)); + } +} + /* Initialize the acceleration hardware */ void RADEONEngineInit(ScrnInfoPtr pScrn) { @@ -436,15 +457,9 @@ void RADEONEngineInit(ScrnInfoPtr pScrn) #ifdef XF86DRI if (info->directRenderingEnabled && (IS_R300_3D || IS_R500_3D)) { - drm_radeon_getparam_t np; int num_pipes; - memset(&np, 0, sizeof(np)); - np.param = RADEON_PARAM_NUM_GB_PIPES; - np.value = &num_pipes; - - if (drmCommandWriteRead(info->dri->drmFD, DRM_RADEON_GETPARAM, &np, - sizeof(np)) < 0) { + if(RADEONDRMGetNumPipes(pScrn, &num_pipes) < 0) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to determine num pipes from DRM, falling back to " "manual look-up!\n"); @@ -455,64 +470,67 @@ void RADEONEngineInit(ScrnInfoPtr pScrn) } #endif - if ((info->ChipFamily == CHIP_FAMILY_RV410) || - (info->ChipFamily == CHIP_FAMILY_R420) || - (info->ChipFamily == CHIP_FAMILY_RS600) || - (info->ChipFamily == CHIP_FAMILY_RS690) || - (info->ChipFamily == CHIP_FAMILY_RS740) || - (info->ChipFamily == CHIP_FAMILY_RS400) || - (info->ChipFamily == CHIP_FAMILY_RS480) || - IS_R500_3D) { - if (info->accel_state->num_gb_pipes == 0) { - uint32_t gb_pipe_sel = INREG(R400_GB_PIPE_SELECT); - - info->accel_state->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1; - if (IS_R500_3D) - OUTPLL(pScrn, R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4)); - } - } else { - if (info->accel_state->num_gb_pipes == 0) { - if ((info->ChipFamily == CHIP_FAMILY_R300) || - (info->ChipFamily == CHIP_FAMILY_R350)) { - /* R3xx chips */ - info->accel_state->num_gb_pipes = 2; - } else { - /* RV3xx chips */ - info->accel_state->num_gb_pipes = 1; + if (!info->cs) { + if ((info->ChipFamily == CHIP_FAMILY_RV410) || + (info->ChipFamily == CHIP_FAMILY_R420) || + (info->ChipFamily == CHIP_FAMILY_RS600) || + (info->ChipFamily == CHIP_FAMILY_RS690) || + (info->ChipFamily == CHIP_FAMILY_RS740) || + (info->ChipFamily == CHIP_FAMILY_RS400) || + (info->ChipFamily == CHIP_FAMILY_RS480) || + IS_R500_3D) { + if (info->accel_state->num_gb_pipes == 0) { + uint32_t gb_pipe_sel = INREG(R400_GB_PIPE_SELECT); + + info->accel_state->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1; + if (IS_R500_3D) + OUTPLL(pScrn, R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4)); + } + } else { + if (info->accel_state->num_gb_pipes == 0) { + if ((info->ChipFamily == CHIP_FAMILY_R300) || + (info->ChipFamily == CHIP_FAMILY_R350)) { + /* R3xx chips */ + info->accel_state->num_gb_pipes = 2; + } else { + /* RV3xx chips */ + info->accel_state->num_gb_pipes = 1; + } } - } - } - - /* RV410 SE cards only have 1 quadpipe */ - if ((info->Chipset == PCI_CHIP_RV410_5E4C) || - (info->Chipset == PCI_CHIP_RV410_5E4F)) - info->accel_state->num_gb_pipes = 1; - - if (IS_R300_3D || IS_R500_3D) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "num quad-pipes is %d\n", info->accel_state->num_gb_pipes); - - if (IS_R300_3D || IS_R500_3D) { - uint32_t gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16); - - switch(info->accel_state->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; } - OUTREG(R300_GB_TILE_CONFIG, gb_tile_config); - OUTREG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN); - OUTREG(R300_DST_PIPE_CONFIG, INREG(R300_DST_PIPE_CONFIG) | R300_PIPE_AUTO_CONFIG); - OUTREG(R300_RB2D_DSTCACHE_MODE, (INREG(R300_RB2D_DSTCACHE_MODE) | - R300_DC_AUTOFLUSH_ENABLE | - R300_DC_DC_DISABLE_IGNORE_PE)); - } else - OUTREG(RADEON_RB3D_CNTL, 0); + /* RV410 SE cards only have 1 quadpipe */ + if ((info->Chipset == PCI_CHIP_RV410_5E4C) || + (info->Chipset == PCI_CHIP_RV410_5E4F)) + info->accel_state->num_gb_pipes = 1; + + if (IS_R300_3D || IS_R500_3D) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "num quad-pipes is %d\n", info->accel_state->num_gb_pipes); + + if (IS_R300_3D || IS_R500_3D) { + uint32_t gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16); + + switch(info->accel_state->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; + } - RADEONEngineReset(pScrn); + OUTREG(R300_GB_TILE_CONFIG, gb_tile_config); + OUTREG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN); + if (info->ChipFamily >= CHIP_FAMILY_R420) + OUTREG(R300_DST_PIPE_CONFIG, INREG(R300_DST_PIPE_CONFIG) | R300_PIPE_AUTO_CONFIG); + OUTREG(R300_RB2D_DSTCACHE_MODE, (INREG(R300_RB2D_DSTCACHE_MODE) | + R300_DC_AUTOFLUSH_ENABLE | + R300_DC_DC_DISABLE_IGNORE_PE)); + } else + OUTREG(RADEON_RB3D_CNTL, 0); + + RADEONEngineReset(pScrn); + } switch (info->CurrentLayout.pixel_code) { case 8: datatype = 2; break; @@ -536,6 +554,24 @@ void RADEONEngineInit(ScrnInfoPtr pScrn) RADEONEngineRestore(pScrn); } +uint32_t radeonGetPixmapOffset(PixmapPtr pPix) +{ + ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + uint32_t offset = 0; + if (info->cs) + return 0; +#ifdef USE_EXA + if (info->useEXA) { + offset = exaGetPixmapOffset(pPix); + } else +#endif + { + offset = pPix->devPrivate.ptr - info->FB; + } + offset += info->fbLocation + pScrn->fbOffset; + return offset; +} #define ACCEL_MMIO #define ACCEL_PREAMBLE() unsigned char *RADEONMMIO = info->MMIO @@ -620,6 +656,8 @@ int RADEONCPStop(ScrnInfoPtr pScrn, RADEONInfoPtr info) } } +#define RADEON_IB_RESERVE (16 * sizeof(uint32_t)) + /* Get an indirect buffer for the CP 2D acceleration commands */ drmBufPtr RADEONCPGetBuffer(ScrnInfoPtr pScrn) { @@ -696,6 +734,7 @@ void RADEONCPFlushIndirect(ScrnInfoPtr pScrn, int discard) int start = info->cp->indirectStart; drm_radeon_indirect_t indirect; + assert(!info->cs); if (!buffer) return; if (start == buffer->used && !discard) return; @@ -745,6 +784,7 @@ void RADEONCPReleaseIndirect(ScrnInfoPtr pScrn) int start = info->cp->indirectStart; drm_radeon_indirect_t indirect; + assert(!info->cs); if (info->ChipFamily >= CHIP_FAMILY_R600) { if (buffer && (buffer->used & 0x3c)) { RING_LOCALS; @@ -1079,8 +1119,10 @@ void RADEONInit3DEngine(ScrnInfoPtr pScrn) if (info->directRenderingEnabled) { drm_radeon_sarea_t *pSAREAPriv; - pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen); - pSAREAPriv->ctx_owner = DRIGetContext(pScrn->pScreen); + if (!info->kms_enabled) { + pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen); + pSAREAPriv->ctx_owner = DRIGetContext(pScrn->pScreen); + } RADEONInit3DEngineCP(pScrn); } else #endif diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c index 7e4a355..b1cb559 100644 --- a/src/radeon_atombios.c +++ b/src/radeon_atombios.c @@ -1436,11 +1436,11 @@ const int object_connector_convert[] = CONNECTOR_CTV, CONNECTOR_STV, CONNECTOR_NONE, + CONNECTOR_NONE, CONNECTOR_DIN, CONNECTOR_SCART, CONNECTOR_HDMI_TYPE_A, CONNECTOR_HDMI_TYPE_B, - CONNECTOR_HDMI_TYPE_B, CONNECTOR_LVDS, CONNECTOR_DIN, CONNECTOR_NONE, @@ -1625,20 +1625,32 @@ static void RADEONApplyATOMQuirks(ScrnInfoPtr pScrn, int index) } } - /* some BIOSes seem to report DAC on HDMI - they hurt me with their lies */ - if ((info->BiosConnector[index].ConnectorType == CONNECTOR_HDMI_TYPE_A) || - (info->BiosConnector[index].ConnectorType == CONNECTOR_HDMI_TYPE_B)) { - info->BiosConnector[index].devices &= ~(ATOM_DEVICE_CRT_SUPPORT); - } - /* ASUS HD 3600 XT board lists the DVI port as HDMI */ if ((info->Chipset == PCI_CHIP_RV635_9598) && (PCI_SUB_VENDOR_ID(info->PciInfo) == 0x1043) && (PCI_SUB_DEVICE_ID(info->PciInfo) == 0x01da)) { - if (info->BiosConnector[index].ConnectorType == CONNECTOR_HDMI_TYPE_B) + if (info->BiosConnector[index].ConnectorType == CONNECTOR_HDMI_TYPE_A) + info->BiosConnector[index].ConnectorType = CONNECTOR_DVI_D; + } + + /* ASUS HD 3450 board lists the DVI port as HDMI */ + if ((info->Chipset == PCI_CHIP_RV620_95C5) && + (PCI_SUB_VENDOR_ID(info->PciInfo) == 0x1043) && + (PCI_SUB_DEVICE_ID(info->PciInfo) == 0x01e2)) { + if (info->BiosConnector[index].ConnectorType == CONNECTOR_HDMI_TYPE_A) info->BiosConnector[index].ConnectorType = CONNECTOR_DVI_D; } + /* some BIOSes seem to report DAC on HDMI - usually this is a board with + * HDMI + VGA reporting as HDMI + */ + if (info->BiosConnector[index].ConnectorType == CONNECTOR_HDMI_TYPE_A) { + if (info->BiosConnector[index].devices & (ATOM_DEVICE_CRT_SUPPORT)) { + info->BiosConnector[index].devices &= ~(ATOM_DEVICE_DFP_SUPPORT); + info->BiosConnector[index].ConnectorType = CONNECTOR_VGA; + info->BiosConnector[index].connector_object = 0; + } + } } diff --git a/src/radeon_chipinfo_gen.h b/src/radeon_chipinfo_gen.h index 7b2512a..41144c7 100644 --- a/src/radeon_chipinfo_gen.h +++ b/src/radeon_chipinfo_gen.h @@ -1,5 +1,5 @@ /* This file is autogenerated please do not edit */ -RADEONCardInfo RADEONCards[] = { +static RADEONCardInfo RADEONCards[] = { { 0x3150, CHIP_FAMILY_RV380, 1, 0, 0, 0, 0 }, { 0x3151, CHIP_FAMILY_RV380, 0, 0, 0, 0, 0 }, { 0x3152, CHIP_FAMILY_RV380, 1, 0, 0, 0, 0 }, @@ -274,15 +274,26 @@ RADEONCardInfo RADEONCards[] = { { 0x946B, CHIP_FAMILY_RV770, 1, 0, 0, 0, 0 }, { 0x947A, CHIP_FAMILY_RV770, 1, 0, 0, 0, 0 }, { 0x947B, CHIP_FAMILY_RV770, 1, 0, 0, 0, 0 }, + { 0x9480, CHIP_FAMILY_RV730, 1, 0, 0, 0, 0 }, { 0x9487, CHIP_FAMILY_RV730, 0, 0, 0, 0, 0 }, + { 0x9488, CHIP_FAMILY_RV730, 1, 0, 0, 0, 0 }, { 0x9489, CHIP_FAMILY_RV730, 1, 0, 0, 0, 0 }, { 0x948F, CHIP_FAMILY_RV730, 0, 0, 0, 0, 0 }, { 0x9490, CHIP_FAMILY_RV730, 0, 0, 0, 0, 0 }, { 0x9491, CHIP_FAMILY_RV730, 0, 0, 0, 0, 0 }, + { 0x9495, CHIP_FAMILY_RV730, 0, 0, 0, 0, 0 }, { 0x9498, CHIP_FAMILY_RV730, 0, 0, 0, 0, 0 }, { 0x949C, CHIP_FAMILY_RV730, 0, 0, 0, 0, 0 }, { 0x949E, CHIP_FAMILY_RV730, 0, 0, 0, 0, 0 }, { 0x949F, CHIP_FAMILY_RV730, 0, 0, 0, 0, 0 }, + { 0x94A0, CHIP_FAMILY_RV740, 1, 0, 0, 0, 0 }, + { 0x94A1, CHIP_FAMILY_RV740, 1, 0, 0, 0, 0 }, + { 0x94A3, CHIP_FAMILY_RV740, 1, 0, 0, 0, 0 }, + { 0x94B1, CHIP_FAMILY_RV740, 0, 0, 0, 0, 0 }, + { 0x94B3, CHIP_FAMILY_RV740, 0, 0, 0, 0, 0 }, + { 0x94B4, CHIP_FAMILY_RV740, 0, 0, 0, 0, 0 }, + { 0x94B5, CHIP_FAMILY_RV740, 0, 0, 0, 0, 0 }, + { 0x94B9, CHIP_FAMILY_RV740, 1, 0, 0, 0, 0 }, { 0x94C0, CHIP_FAMILY_RV610, 0, 0, 0, 0, 0 }, { 0x94C1, CHIP_FAMILY_RV610, 0, 0, 0, 0, 0 }, { 0x94C3, CHIP_FAMILY_RV610, 0, 0, 0, 0, 0 }, @@ -315,6 +326,7 @@ RADEONCardInfo RADEONCards[] = { { 0x9552, CHIP_FAMILY_RV710, 1, 0, 0, 0, 0 }, { 0x9553, CHIP_FAMILY_RV710, 1, 0, 0, 0, 0 }, { 0x9555, CHIP_FAMILY_RV710, 1, 0, 0, 0, 0 }, + { 0x9557, CHIP_FAMILY_RV710, 1, 0, 0, 0, 0 }, { 0x9580, CHIP_FAMILY_RV630, 0, 0, 0, 0, 0 }, { 0x9581, CHIP_FAMILY_RV630, 1, 0, 0, 0, 0 }, { 0x9583, CHIP_FAMILY_RV630, 1, 0, 0, 0, 0 }, diff --git a/src/radeon_chipset_gen.h b/src/radeon_chipset_gen.h index 70b9ff6..fc41c3d 100644 --- a/src/radeon_chipset_gen.h +++ b/src/radeon_chipset_gen.h @@ -274,15 +274,26 @@ static SymTabRec RADEONChipsets[] = { { PCI_CHIP_RV770_946B, "ATI M98" }, { PCI_CHIP_RV770_947A, "ATI M98" }, { PCI_CHIP_RV770_947B, "ATI M98" }, + { PCI_CHIP_RV730_9480, "ATI Mobility Radeon HD 4650" }, { PCI_CHIP_RV730_9487, "ATI Radeon RV730 (AGP)" }, + { PCI_CHIP_RV730_9488, "ATI Mobility Radeon HD 4670" }, { PCI_CHIP_RV730_9489, "ATI FirePro M5750" }, { PCI_CHIP_RV730_948F, "ATI Radeon RV730 (AGP)" }, { PCI_CHIP_RV730_9490, "ATI RV730XT [Radeon HD 4670]" }, { PCI_CHIP_RV730_9491, "ATI RADEON E4600" }, + { PCI_CHIP_RV730_9495, "ATI Radeon HD 4600 Series" }, { PCI_CHIP_RV730_9498, "ATI RV730 PRO [Radeon HD 4650]" }, { PCI_CHIP_RV730_949C, "ATI FirePro V7750 (FireGL)" }, { PCI_CHIP_RV730_949E, "ATI FirePro V5700 (FireGL)" }, { PCI_CHIP_RV730_949F, "ATI FirePro V3750 (FireGL)" }, + { PCI_CHIP_RV740_94A0, "ATI Mobility Radeon HD 4830" }, + { PCI_CHIP_RV740_94A1, "ATI Mobility Radeon HD 4850" }, + { PCI_CHIP_RV740_94A3, "ATI FirePro M7740" }, + { PCI_CHIP_RV740_94B1, "ATI RV740" }, + { PCI_CHIP_RV740_94B3, "ATI Radeon HD 4770" }, + { PCI_CHIP_RV740_94B4, "ATI Radeon HD 4700 Series" }, + { PCI_CHIP_RV740_94B5, "ATI Radeon HD 4770" }, + { PCI_CHIP_RV740_94B9, "ATI FirePro M5750" }, { PCI_CHIP_RV610_94C0, "ATI RV610" }, { PCI_CHIP_RV610_94C1, "ATI Radeon HD 2400 XT" }, { PCI_CHIP_RV610_94C3, "ATI Radeon HD 2400 Pro" }, @@ -315,6 +326,7 @@ static SymTabRec RADEONChipsets[] = { { PCI_CHIP_RV710_9552, "ATI Mobility Radeon 4300 Series" }, { PCI_CHIP_RV710_9553, "ATI Mobility Radeon 4500 Series" }, { PCI_CHIP_RV710_9555, "ATI Mobility Radeon 4500 Series" }, + { PCI_CHIP_RV710_9557, "ATI FirePro RG220" }, { PCI_CHIP_RV630_9580, "ATI RV630" }, { PCI_CHIP_RV630_9581, "ATI Mobility Radeon HD 2600" }, { PCI_CHIP_RV630_9583, "ATI Mobility Radeon HD 2600 XT" }, @@ -356,10 +368,10 @@ static SymTabRec RADEONChipsets[] = { { PCI_CHIP_RS780_9614, "ATI Radeon HD 3300 Graphics" }, { PCI_CHIP_RS780_9615, "ATI Radeon HD 3200 Graphics" }, { PCI_CHIP_RS780_9616, "ATI Radeon 3000 Graphics" }, - { PCI_CHIP_RS880_9710, "ATI Radeon HD Graphics" }, - { PCI_CHIP_RS880_9711, "ATI Radeon Graphics" }, - { PCI_CHIP_RS880_9712, "ATI Mobility Radeon HD Graphics" }, - { PCI_CHIP_RS880_9713, "ATI Mobility Radeon Graphics" }, - { PCI_CHIP_RS880_9714, "ATI Radeon Graphics" }, + { PCI_CHIP_RS880_9710, "ATI Radeon HD 4200" }, + { PCI_CHIP_RS880_9711, "ATI Radeon 4100" }, + { PCI_CHIP_RS880_9712, "ATI Mobility Radeon HD 4200" }, + { PCI_CHIP_RS880_9713, "ATI Mobility Radeon 4100" }, + { PCI_CHIP_RS880_9714, "ATI RS880" }, { -1, NULL } }; diff --git a/src/radeon_commonfuncs.c b/src/radeon_commonfuncs.c index deea2d2..6387e4f 100644 --- a/src/radeon_commonfuncs.c +++ b/src/radeon_commonfuncs.c @@ -56,6 +56,7 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); uint32_t gb_tile_config, su_reg_dest, vap_cntl; + int size; ACCEL_PREAMBLE(); info->accel_state->texW[0] = info->accel_state->texH[0] = @@ -63,11 +64,13 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn) if (IS_R300_3D || IS_R500_3D) { - 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); - OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN); - FINISH_ACCEL(); + if (!info->cs) { + 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); + OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN); + FINISH_ACCEL(); + } gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16); @@ -79,20 +82,26 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn) case 1: gb_tile_config |= R300_PIPE_COUNT_RV350; break; } - BEGIN_ACCEL(5); - OUT_ACCEL_REG(R300_GB_TILE_CONFIG, gb_tile_config); - OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN); - OUT_ACCEL_REG(R300_DST_PIPE_CONFIG, R300_PIPE_AUTO_CONFIG); - OUT_ACCEL_REG(R300_GB_SELECT, 0); - OUT_ACCEL_REG(R300_GB_ENABLE, 0); - FINISH_ACCEL(); + if (info->dri->pKernelDRMVersion->version_major < 2) { + size = (info->ChipFamily >= CHIP_FAMILY_R420) ? 5 : 4; + BEGIN_ACCEL(size); + OUT_ACCEL_REG(R300_GB_TILE_CONFIG, gb_tile_config); + OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN); + if (info->ChipFamily >= CHIP_FAMILY_R420) + OUT_ACCEL_REG(R300_DST_PIPE_CONFIG, R300_PIPE_AUTO_CONFIG); + OUT_ACCEL_REG(R300_GB_SELECT, 0); + OUT_ACCEL_REG(R300_GB_ENABLE, 0); + FINISH_ACCEL(); + } if (IS_R500_3D) { su_reg_dest = ((1 << info->accel_state->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(); + if (info->dri->pKernelDRMVersion->version_major < 2) { + 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); @@ -101,29 +110,34 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn) OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN); FINISH_ACCEL(); - BEGIN_ACCEL(5); + BEGIN_ACCEL(3); OUT_ACCEL_REG(R300_GB_AA_CONFIG, 0); 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); - OUT_ACCEL_REG(R300_GB_MSPOS0, ((6 << R300_MS_X0_SHIFT) | - (6 << R300_MS_Y0_SHIFT) | - (6 << R300_MS_X1_SHIFT) | - (6 << R300_MS_Y1_SHIFT) | - (6 << R300_MS_X2_SHIFT) | - (6 << R300_MS_Y2_SHIFT) | - (6 << R300_MSBD0_Y_SHIFT) | - (6 << R300_MSBD0_X_SHIFT))); - OUT_ACCEL_REG(R300_GB_MSPOS1, ((6 << R300_MS_X3_SHIFT) | - (6 << R300_MS_Y3_SHIFT) | - (6 << R300_MS_X4_SHIFT) | - (6 << R300_MS_Y4_SHIFT) | - (6 << R300_MS_X5_SHIFT) | - (6 << R300_MS_Y5_SHIFT) | - (6 << R300_MSBD1_SHIFT))); FINISH_ACCEL(); - BEGIN_ACCEL(5); - OUT_ACCEL_REG(R300_GA_ENHANCE, R300_GA_DEADLOCK_CNTL | R300_GA_FASTSYNC_CNTL); + if (info->dri->pKernelDRMVersion->version_major < 2) { + BEGIN_ACCEL(3); + OUT_ACCEL_REG(R300_GB_MSPOS0, ((6 << R300_MS_X0_SHIFT) | + (6 << R300_MS_Y0_SHIFT) | + (6 << R300_MS_X1_SHIFT) | + (6 << R300_MS_Y1_SHIFT) | + (6 << R300_MS_X2_SHIFT) | + (6 << R300_MS_Y2_SHIFT) | + (6 << R300_MSBD0_Y_SHIFT) | + (6 << R300_MSBD0_X_SHIFT))); + OUT_ACCEL_REG(R300_GB_MSPOS1, ((6 << R300_MS_X3_SHIFT) | + (6 << R300_MS_Y3_SHIFT) | + (6 << R300_MS_X4_SHIFT) | + (6 << R300_MS_Y4_SHIFT) | + (6 << R300_MS_X5_SHIFT) | + (6 << R300_MS_Y5_SHIFT) | + (6 << R300_MSBD1_SHIFT))); + OUT_ACCEL_REG(R300_GA_ENHANCE, R300_GA_DEADLOCK_CNTL | R300_GA_FASTSYNC_CNTL); + FINISH_ACCEL(); + } + + BEGIN_ACCEL(4); OUT_ACCEL_REG(R300_GA_POLY_MODE, R300_FRONT_PTYPE_TRIANGE | R300_BACK_PTYPE_TRIANGE); OUT_ACCEL_REG(R300_GA_ROUND_MODE, (R300_GEOMETRY_ROUND_NEAREST | R300_COLOR_ROUND_NEAREST)); @@ -775,10 +789,9 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn) R200_VAP_VF_MAX_VTX_NUM); FINISH_ACCEL(); - BEGIN_ACCEL(5); - OUT_ACCEL_REG(RADEON_RE_TOP_LEFT, 0); - OUT_ACCEL_REG(RADEON_RE_WIDTH_HEIGHT, 0x07ff07ff); - OUT_ACCEL_REG(RADEON_AUX_SC_CNTL, 0); + BEGIN_ACCEL(4); + OUT_ACCEL_REG(R200_RE_AUX_SCISSOR_CNTL, 0); + OUT_ACCEL_REG(R200_RE_CNTL, 0); OUT_ACCEL_REG(RADEON_RB3D_PLANEMASK, 0xffffffff); OUT_ACCEL_REG(RADEON_SE_CNTL, (RADEON_DIFFUSE_SHADE_GOURAUD | RADEON_BFACE_SOLID | @@ -799,10 +812,7 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn) RADEON_TEX1_W_ROUTING_USE_W0); FINISH_ACCEL(); - BEGIN_ACCEL(5); - OUT_ACCEL_REG(RADEON_RE_TOP_LEFT, 0); - OUT_ACCEL_REG(RADEON_RE_WIDTH_HEIGHT, 0x07ff07ff); - OUT_ACCEL_REG(RADEON_AUX_SC_CNTL, 0); + BEGIN_ACCEL(2); OUT_ACCEL_REG(RADEON_RB3D_PLANEMASK, 0xffffffff); OUT_ACCEL_REG(RADEON_SE_CNTL, (RADEON_DIFFUSE_SHADE_GOURAUD | RADEON_BFACE_SOLID | @@ -815,6 +825,39 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn) } +#if defined(ACCEL_CP) && defined(XF86DRM_MODE) +void drmmode_wait_for_vline(ScrnInfoPtr pScrn, PixmapPtr pPix, + int crtc, int start, int stop) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[crtc]->driver_private; + ACCEL_PREAMBLE(); + + BEGIN_ACCEL(3); + + if (IS_AVIVO_VARIANT) { + uint32_t reg = AVIVO_D1MODE_VLINE_START_END; /* this is just a marker */ + OUT_ACCEL_REG(reg, + ((start << AVIVO_D1MODE_VLINE_START_SHIFT) | + (stop << AVIVO_D1MODE_VLINE_END_SHIFT) | + AVIVO_D1MODE_VLINE_INV)); + } else { + OUT_ACCEL_REG(RADEON_CRTC_GUI_TRIG_VLINE, /* another placeholder */ + ((start << RADEON_CRTC_GUI_TRIG_VLINE_START_SHIFT) | + (stop << RADEON_CRTC_GUI_TRIG_VLINE_END_SHIFT) | + RADEON_CRTC_GUI_TRIG_VLINE_INV | + RADEON_CRTC_GUI_TRIG_VLINE_STALL)); + } + OUT_ACCEL_REG(RADEON_WAIT_UNTIL, (RADEON_WAIT_CRTC_VLINE | + RADEON_ENG_DISPLAY_SELECT_CRTC0)); + + OUT_RING(CP_PACKET3(RADEON_CP_PACKET3_NOP, 0)); + OUT_RING(drmmode_crtc->mode_crtc->crtc_id); + FINISH_ACCEL(); +} +#endif + /* inserts a wait for vline in the command stream */ void FUNC_NAME(RADEONWaitForVLine)(ScrnInfoPtr pScrn, PixmapPtr pPix, int crtc, int start, int stop) @@ -833,16 +876,21 @@ void FUNC_NAME(RADEONWaitForVLine)(ScrnInfoPtr pScrn, PixmapPtr pPix, if (!xf86_config->crtc[crtc]->enabled) return; + if (info->cs) { + if (pPix != pScrn->pScreen->GetScreenPixmap(pScrn->pScreen)) + return; + } else { #ifdef USE_EXA - if (info->useEXA) - offset = exaGetPixmapOffset(pPix); - else + if (info->useEXA) + offset = exaGetPixmapOffset(pPix); + else #endif - offset = pPix->devPrivate.ptr - info->FB; + offset = pPix->devPrivate.ptr - info->FB; - /* if drawing to front buffer */ - if (offset != 0) - return; + /* if drawing to front buffer */ + if (offset != 0) + return; + } start = max(start, 0); stop = min(stop, xf86_config->crtc[crtc]->mode.VDisplay); @@ -850,6 +898,13 @@ void FUNC_NAME(RADEONWaitForVLine)(ScrnInfoPtr pScrn, PixmapPtr pPix, if (start > xf86_config->crtc[crtc]->mode.VDisplay) return; +#if defined(ACCEL_CP) && defined(XF86DRM_MODE) + if (info->kms_enabled) { + drmmode_wait_for_vline(pScrn, pPix, crtc, start, stop); + return; + } +#endif + BEGIN_ACCEL(2); if (IS_AVIVO_VARIANT) { @@ -864,12 +919,14 @@ void FUNC_NAME(RADEONWaitForVLine)(ScrnInfoPtr pScrn, PixmapPtr pPix, OUT_ACCEL_REG(RADEON_CRTC_GUI_TRIG_VLINE, ((start << RADEON_CRTC_GUI_TRIG_VLINE_START_SHIFT) | (stop << RADEON_CRTC_GUI_TRIG_VLINE_END_SHIFT) | - RADEON_CRTC_GUI_TRIG_VLINE_INV)); + RADEON_CRTC_GUI_TRIG_VLINE_INV | + RADEON_CRTC_GUI_TRIG_VLINE_STALL)); else OUT_ACCEL_REG(RADEON_CRTC2_GUI_TRIG_VLINE, ((start << RADEON_CRTC_GUI_TRIG_VLINE_START_SHIFT) | (stop << RADEON_CRTC_GUI_TRIG_VLINE_END_SHIFT) | - RADEON_CRTC_GUI_TRIG_VLINE_INV)); + RADEON_CRTC_GUI_TRIG_VLINE_INV | + RADEON_CRTC_GUI_TRIG_VLINE_STALL)); } if (crtc == 0) diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c index c78ac43..3899064 100644 --- a/src/radeon_crtc.c +++ b/src/radeon_crtc.c @@ -230,7 +230,11 @@ RADEONComputePLL(RADEONPLLPtr pll, tmp += (CARD64)pll->reference_freq * 1000 * frac_feedback_div; current_freq = RADEONDiv(tmp, ref_div * post_div); - error = abs(current_freq - freq); + if (flags & RADEON_PLL_PREFER_CLOSEST_LOWER) { + error = freq - current_freq; + error = error < 0 ? 0xffffffff : error; + } else + error = abs(current_freq - freq); vco_diff = abs(vco - best_vco); if ((best_vco == 0 && error < best_error) || diff --git a/src/radeon_dri.c b/src/radeon_dri.c index 19f7abe..8a7ed83 100644 --- a/src/radeon_dri.c +++ b/src/radeon_dri.c @@ -745,6 +745,8 @@ static radeon_agpmode_quirk radeon_agpmode_quirk_list[] = { { PCI_VENDOR_INTEL,0x2570, PCI_VENDOR_ATI,0x4a4e, PCI_VENDOR_DELL,0x5106, 4 }, /* Intel 82865G/PE/P DRAM Controller/Host-Hub / RV280 [Radeon 9200 SE] Needs AGPMode 4 (lp #300304) */ { PCI_VENDOR_INTEL,0x2570, PCI_VENDOR_ATI,0x5964, 0x148c,0x2073, 4 }, + /* Intel 82855PM host bridge / Mobility M7 LW Needs AGPMode 4 (lp: #353996) */ + { PCI_VENDOR_INTEL,0x3340, PCI_VENDOR_ATI,0x4c57, PCI_VENDOR_IBM,0x0530, 4 }, /* Intel 82855PM Processor to I/O Controller / Mobility M6 LY Needs AGPMode 1 (deb #467235) */ { PCI_VENDOR_INTEL,0x3340, PCI_VENDOR_ATI,0x4c59, PCI_VENDOR_IBM,0x052f, 1 }, /* Intel 82855PM host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (lp #195051) */ @@ -767,6 +769,16 @@ static radeon_agpmode_quirk radeon_agpmode_quirk_list[] = { { PCI_VENDOR_INTEL,0x3580, PCI_VENDOR_ATI,0x4e50, PCI_VENDOR_ASUS,0x1942, 1 }, /* Intel 82852/82855 host bridge / Mobility 9600/9700 Needs AGPMode 1 (deb #510208) */ { PCI_VENDOR_INTEL,0x3580, PCI_VENDOR_ATI,0x4e50, 0x10cf,0x127f, 1 }, + /* Intel 82443BX/ZX/DX Host bridge / RV280 [Radeon 9200] Needs AGPMode 1 (lp #370205) */ + { PCI_VENDOR_INTEL,0x7190, PCI_VENDOR_ATI,0x5961, 0x174b,0x7c13, 1 }, + + /* Ali Corp M1671 Super P4 Northbridge / Mobility M6 LY Needs AGPMode 1 (lp #146303)*/ + { 0x10b9,0x1671, PCI_VENDOR_ATI,0x4c59, 0x103c,0x0027, 1 }, + + /* SiS Host Bridge 655 / R420 [Radeon X800] Needs AGPMode 4 (lp #371296) */ + { 0x1039,0x0655, PCI_VENDOR_ATI,0x4a4b, PCI_VENDOR_ATI,0x4422, 4 }, + /* SiS Host Bridge / RV280 Needs AGPMode 4 */ + { 0x1039,0x0741, PCI_VENDOR_ATI,0x5964, 0x148c,0x2073, 4 }, /* ASRock K7VT4A+ AGP 8x / ATI Radeon 9250 AGP Needs AGPMode 4 (lp #133192) */ { 0x1849,0x3189, PCI_VENDOR_ATI,0x5960, 0x1787,0x5960, 4 }, @@ -787,6 +799,8 @@ static radeon_agpmode_quirk radeon_agpmode_quirk_list[] = { { PCI_VENDOR_VIA,0x3189, PCI_VENDOR_ATI,0x5960, 0x1462,0x0380, 4 }, /* VIA VT8377 Host Bridge / RV280 Needs AGPMode 4 (ati ML) */ { PCI_VENDOR_VIA,0x3189, PCI_VENDOR_ATI,0x5964, 0x148c,0x2073, 4 }, + /* VIA VT8377 Host Bridge / RV280 Needs AGPMode 4 (fdo #12544) */ + { PCI_VENDOR_VIA,0x3189, PCI_VENDOR_ATI,0x5964, 0x1043,0xc008, 4 }, /* ATI Host Bridge / RV280 [M9+] Needs AGPMode 1 (phoronix forum) */ { PCI_VENDOR_ATI,0xcbb2, PCI_VENDOR_ATI,0x5c61, PCI_VENDOR_SONY,0x8175, 1 }, @@ -794,6 +808,9 @@ static radeon_agpmode_quirk radeon_agpmode_quirk_list[] = { /* HP Host Bridge / R300 [FireGL X1] Needs AGPMode 2 (fdo #7770) */ { PCI_VENDOR_HP,0x122e, PCI_VENDOR_ATI,0x4e47, PCI_VENDOR_ATI,0x0152, 2 }, + /* nVidia Host Bridge / R420 [X800 Pro] Needs AGPMode 4 (fdo #22726) */ + { 0x10de,0x00e1, PCI_VENDOR_ATI,0x4a49, PCI_VENDOR_ATI,0x0002, 4 }, + { 0, 0, 0, 0, 0, 0, 0 }, }; @@ -1374,7 +1391,7 @@ Bool RADEONDRIGetVersion(ScrnInfoPtr pScrn) if (!xf86LoaderCheckSymbol("drmAvailable")) return FALSE; if (!xf86LoaderCheckSymbol("DRIQueryVersion")) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "[dri] RADEONDRIGetVersion failed (libdri.a too old)\n" + "[dri] RADEONDRIGetVersion failed (libdri too old)\n" "[dri] Disabling DRI.\n"); return FALSE; } @@ -1398,7 +1415,7 @@ Bool RADEONDRIGetVersion(ScrnInfoPtr pScrn) info->dri->pLibDRMVersion = drmGetLibVersion(info->dri->drmFD); if (info->dri->pLibDRMVersion == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "[dri] RADEONDRIGetVersion failed because libDRM is really " + "[dri] RADEONDRIGetVersion failed because libdrm is really " "way to old to even get a version number out of it.\n" "[dri] Disabling DRI.\n"); return FALSE; @@ -1409,7 +1426,7 @@ Bool RADEONDRIGetVersion(ScrnInfoPtr pScrn) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[dri] RADEONDRIGetVersion failed because of a " "version mismatch.\n" - "[dri] libdrm.a module version is %d.%d.%d but " + "[dri] libdrm module version is %d.%d.%d but " "version 1.2.x is needed.\n" "[dri] Disabling DRI.\n", info->dri->pLibDRMVersion->version_major, @@ -1473,7 +1490,7 @@ Bool RADEONDRIGetVersion(ScrnInfoPtr pScrn) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[dri] RADEONDRIGetVersion failed because of a version " "mismatch.\n" - "[dri] radeon.o kernel module version is %d.%d.%d " + "[dri] radeon kernel module version is %d.%d.%d " "but version 1.%d.%d or newer is needed.\n" "[dri] Disabling DRI.\n", info->dri->pKernelDRMVersion->version_major, diff --git a/src/radeon_driver.c b/src/radeon_driver.c index 8a2a978..e766093 100644 --- a/src/radeon_driver.c +++ b/src/radeon_driver.c @@ -92,9 +92,11 @@ /* X and server generic header files */ #include "xf86.h" #include "xf86_OSproc.h" -#include "xf86RAC.h" #include "xf86RandR12.h" +#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6 +#include "xf86RAC.h" #include "xf86Resources.h" +#endif #include "xf86cmap.h" #include "vbe.h" @@ -104,8 +106,13 @@ #include "vgaHW.h" #endif +#ifdef HAVE_XEXTPROTO_71 +#include <X11/extensions/dpmsconst.h> +#else #define DPMS_SERVER #include <X11/extensions/dpms.h> +#endif + #include "atipciids.h" #include "radeon_chipset_gen.h" @@ -340,7 +347,7 @@ RADEONPostInt10Check(ScrnInfoPtr pScrn, void *ptr) } /* Allocate our private RADEONInfoRec */ -static Bool RADEONGetRec(ScrnInfoPtr pScrn) +Bool RADEONGetRec(ScrnInfoPtr pScrn) { if (pScrn->driverPrivate) return TRUE; @@ -349,7 +356,7 @@ static Bool RADEONGetRec(ScrnInfoPtr pScrn) } /* Free our private RADEONInfoRec */ -static void RADEONFreeRec(ScrnInfoPtr pScrn) +void RADEONFreeRec(ScrnInfoPtr pScrn) { RADEONInfoPtr info; int i; @@ -616,6 +623,12 @@ unsigned RADEONINMC(ScrnInfoPtr pScrn, int addr) } else if (info->ChipFamily == CHIP_FAMILY_RS600) { OUTREG(RS600_MC_INDEX, ((addr & RS600_MC_ADDR_MASK) | RS600_MC_IND_CITF_ARB0)); data = INREG(RS600_MC_DATA); + } else if ((info->ChipFamily == CHIP_FAMILY_RS780) || + (info->ChipFamily == CHIP_FAMILY_RS880)) { + OUTREG(RS780_MC_INDEX, (addr & RS780_MC_INDEX_MASK)); + data = INREG(RS780_MC_DATA); + } else if (info->ChipFamily >= CHIP_FAMILY_R600) { + data = 0; } else if (IS_AVIVO_VARIANT) { OUTREG(AVIVO_MC_INDEX, (addr & 0xff) | 0x7f0000); (void)INREG(AVIVO_MC_INDEX); @@ -652,6 +665,13 @@ void RADEONOUTMC(ScrnInfoPtr pScrn, int addr, uint32_t data) RS600_MC_IND_CITF_ARB0 | RS600_MC_IND_WR_EN)); OUTREG(RS600_MC_DATA, data); + } else if ((info->ChipFamily == CHIP_FAMILY_RS780) || + (info->ChipFamily == CHIP_FAMILY_RS880)) { + OUTREG(RS780_MC_INDEX, ((addr & RS780_MC_INDEX_MASK) | + RS780_MC_INDEX_WR_EN)); + OUTREG(RS780_MC_DATA, data); + } else if (info->ChipFamily >= CHIP_FAMILY_R600) { + // do nothing } else if (IS_AVIVO_VARIANT) { OUTREG(AVIVO_MC_INDEX, (addr & 0xff) | 0xff0000); (void)INREG(AVIVO_MC_INDEX); @@ -1251,7 +1271,7 @@ static void RADEONGetClockInfo(ScrnInfoPtr pScrn) /* This is called by RADEONPreInit to set up the default visual */ -static Bool RADEONPreInitVisual(ScrnInfoPtr pScrn) +Bool RADEONPreInitVisual(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); @@ -1308,7 +1328,7 @@ static Bool RADEONPreInitVisual(ScrnInfoPtr pScrn) } /* This is called by RADEONPreInit to handle all color weight issues */ -static Bool RADEONPreInitWeight(ScrnInfoPtr pScrn) +Bool RADEONPreInitWeight(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); @@ -1959,7 +1979,6 @@ static Bool RADEONPreInitChipType(ScrnInfoPtr pScrn) } } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s card detected\n", (info->cardType==CARD_PCI) ? "PCI" : (info->cardType==CARD_PCIE) ? "PCIE" : "AGP"); @@ -1979,12 +1998,15 @@ static Bool RADEONPreInitChipType(ScrnInfoPtr pScrn) if (strcmp(s, "AGP") == 0) { info->cardType = CARD_AGP; xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forced into AGP mode\n"); - } else if (strcmp(s, "PCI") == 0) { - info->cardType = CARD_PCI; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forced into PCI mode\n"); - } else if (strcmp(s, "PCIE") == 0) { - info->cardType = CARD_PCIE; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forced into PCI Express mode\n"); + } else if ((strcmp(s, "PCI") == 0) || + (strcmp(s, "PCIE") == 0)) { + if (info->ChipFamily >= CHIP_FAMILY_RV380) { + info->cardType = CARD_PCIE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forced into PCI Express mode\n"); + } else { + info->cardType = CARD_PCI; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forced into PCI mode\n"); + } } else { xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Invalid BusType option, using detected type\n"); @@ -2061,6 +2083,7 @@ static Bool RADEONPreInitAccel(ScrnInfoPtr pScrn) #if defined(USE_EXA) && defined(USE_XAA) char *optstr; #endif + int maxy = info->FbMapSize / (pScrn->displayWidth * info->CurrentLayout.pixel_bytes); if (!(info->accel_state = xcalloc(1, sizeof(struct radeon_accel_state)))) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to allocate accel_state rec!\n"); @@ -2081,7 +2104,22 @@ static Bool RADEONPreInitAccel(ScrnInfoPtr pScrn) info->accel_state->has_tcl = TRUE; } - info->useEXA = TRUE; + /* if we have shadow fb bail */ + if (info->r600_shadow_fb) { + info->useEXA = FALSE; + return TRUE; + } + +#ifdef XF86DRI + if ((!info->directRenderingEnabled) || + (maxy <= pScrn->virtualY * 3) || + (pScrn->videoRam <= 32768)) + info->useEXA = FALSE; + else + info->useEXA = TRUE; +#else + info->useEXA = FALSE; +#endif if (!xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) { int errmaj = 0, errmin = 0; @@ -2091,9 +2129,10 @@ static Bool RADEONPreInitAccel(ScrnInfoPtr pScrn) #if defined(USE_XAA) optstr = (char *)xf86GetOptValString(info->Options, OPTION_ACCELMETHOD); if (optstr != NULL) { - if (xf86NameCmp(optstr, "EXA") == 0) + if (xf86NameCmp(optstr, "EXA") == 0) { from = X_CONFIG; - else if (xf86NameCmp(optstr, "XAA") == 0) { + info->useEXA = TRUE; + } else if (xf86NameCmp(optstr, "XAA") == 0) { from = X_CONFIG; if (info->ChipFamily < CHIP_FAMILY_R600) info->useEXA = FALSE; @@ -2145,6 +2184,9 @@ static Bool RADEONPreInitAccel(ScrnInfoPtr pScrn) } } #endif /* USE_XAA */ + } else { + /* NoAccel */ + info->useEXA = FALSE; } return TRUE; @@ -2253,9 +2295,6 @@ static Bool RADEONPreInitDRI(ScrnInfoPtr pScrn) } } - if (info->ChipFamily == CHIP_FAMILY_RS880) - return FALSE; - if (!xf86ReturnOptValBool(info->Options, OPTION_DRI, TRUE)) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering forced off\n"); @@ -2810,6 +2849,7 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) info->IsSecondary = FALSE; info->IsPrimary = FALSE; + info->kms_enabled = FALSE; info->pEnt = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]); if (info->pEnt->location.type != BUS_PCI) goto fail; @@ -2899,12 +2939,14 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) PCI_DEV_DEV(info->PciInfo), PCI_DEV_FUNC(info->PciInfo)); +#ifndef XSERVER_LIBPCIACCESS if (xf86RegisterResources(info->pEnt->index, 0, ResExclusive)) goto fail; xf86SetOperatingState(resVga, info->pEnt->index, ResUnusedOpr); pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_VIEWPORT | RAC_CURSOR; +#endif pScrn->monitor = pScrn->confScreen->monitor; /* Allocate an xf86CrtcConfig */ @@ -5624,7 +5666,7 @@ Bool RADEONEnterVT(int scrnIndex, int flags) RADEONRestoreSurfaces(pScrn, info->ModeReg); #ifdef XF86DRI if (info->directRenderingEnabled) { - if (info->cardType == CARD_PCIE && + if (info->cardType == CARD_PCIE && info->dri->pKernelDRMVersion->version_minor >= 19 && info->FbSecureSize) { #if X_BYTE_ORDER == X_BIG_ENDIAN @@ -5638,7 +5680,7 @@ Bool RADEONEnterVT(int scrnIndex, int flags) #if X_BYTE_ORDER == X_BIG_ENDIAN OUTREG(RADEON_SURFACE_CNTL, sctrl); #endif - } + } /* get the DRI back into shape after resume */ RADEONDRISetVBlankInterrupt (pScrn, TRUE); @@ -5666,6 +5708,8 @@ Bool RADEONEnterVT(int scrnIndex, int flags) DRIUnlock(pScrn->pScreen); } #endif + if (IS_R500_3D || IS_R300_3D) + radeon_load_bicubic_texture(pScrn); return TRUE; } diff --git a/src/radeon_drm.h b/src/radeon_drm.h index 54bc234..f974e19 100644 --- a/src/radeon_drm.h +++ b/src/radeon_drm.h @@ -493,6 +493,18 @@ typedef struct { #define DRM_RADEON_SETPARAM 0x19 #define DRM_RADEON_SURF_ALLOC 0x1a #define DRM_RADEON_SURF_FREE 0x1b +/* KMS ioctl */ +#define DRM_RADEON_GEM_INFO 0x1c +#define DRM_RADEON_GEM_CREATE 0x1d +#define DRM_RADEON_GEM_MMAP 0x1e +#define DRM_RADEON_GEM_PREAD 0x21 +#define DRM_RADEON_GEM_PWRITE 0x22 +#define DRM_RADEON_GEM_SET_DOMAIN 0x23 +#define DRM_RADEON_GEM_WAIT_IDLE 0x24 +#define DRM_RADEON_CS 0x26 +#define DRM_RADEON_INFO 0x27 +#define DRM_RADEON_GEM_SET_TILING 0x28 +#define DRM_RADEON_GEM_GET_TILING 0x29 #define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t) #define DRM_IOCTL_RADEON_CP_START DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_START) @@ -521,6 +533,18 @@ typedef struct { #define DRM_IOCTL_RADEON_SETPARAM DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SETPARAM, drm_radeon_setparam_t) #define DRM_IOCTL_RADEON_SURF_ALLOC DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_ALLOC, drm_radeon_surface_alloc_t) #define DRM_IOCTL_RADEON_SURF_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_FREE, drm_radeon_surface_free_t) +/* KMS */ +#define DRM_IOCTL_RADEON_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_INFO, struct drm_radeon_gem_info) +#define DRM_IOCTL_RADEON_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_CREATE, struct drm_radeon_gem_create) +#define DRM_IOCTL_RADEON_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_MMAP, struct drm_radeon_gem_mmap) +#define DRM_IOCTL_RADEON_GEM_PREAD DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PREAD, struct drm_radeon_gem_pread) +#define DRM_IOCTL_RADEON_GEM_PWRITE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PWRITE, struct drm_radeon_gem_pwrite) +#define DRM_IOCTL_RADEON_GEM_SET_DOMAIN DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_SET_DOMAIN, struct drm_radeon_gem_set_domain) +#define DRM_IOCTL_RADEON_GEM_WAIT_IDLE DRM_IOW(DRM_COMMAND_BASE + DRM_RADEON_GEM_WAIT_IDLE, struct drm_radeon_gem_wait_idle) +#define DRM_IOCTL_RADEON_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS, struct drm_radeon_cs) +#define DRM_IOCTL_RADEON_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_INFO, struct drm_radeon_info) +#define DRM_IOCTL_RADEON_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_SET_TILING, struct drm_radeon_gem_set_tiling) +#define DRM_IOCTL_RADEON_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_GET_TILING, struct drm_radeon_gem_get_tiling) typedef struct drm_radeon_init { enum { @@ -528,7 +552,7 @@ typedef struct drm_radeon_init { RADEON_CLEANUP_CP = 0x02, RADEON_INIT_R200_CP = 0x03, RADEON_INIT_R300_CP = 0x04, - RADEON_INIT_R600_CP = 0x05, + RADEON_INIT_R600_CP = 0x05 } func; unsigned long sarea_priv_offset; int is_pci; /* for overriding only */ @@ -753,4 +777,130 @@ typedef struct drm_radeon_surface_free { #define DRM_RADEON_VBLANK_CRTC1 1 #define DRM_RADEON_VBLANK_CRTC2 2 +/* + * Kernel modesetting world below. + */ +#define RADEON_GEM_DOMAIN_CPU 0x1 +#define RADEON_GEM_DOMAIN_GTT 0x2 +#define RADEON_GEM_DOMAIN_VRAM 0x4 + +struct drm_radeon_gem_info { + uint64_t gart_size; + uint64_t vram_size; + uint64_t vram_visible; +}; + +#define RADEON_GEM_NO_BACKING_STORE 1 + +struct drm_radeon_gem_create { + uint64_t size; + uint64_t alignment; + uint32_t handle; + uint32_t initial_domain; + uint32_t flags; +}; + +#define RADEON_TILING_MACRO 0x1 +#define RADEON_TILING_MICRO 0x2 +#define RADEON_TILING_SWAP 0x4 +#define RADEON_TILING_SURFACE 0x8 /* this object requires a surface + * when mapped - i.e. front buffer */ + +struct drm_radeon_gem_set_tiling { + uint32_t handle; + uint32_t tiling_flags; + uint32_t pitch; +}; + +struct drm_radeon_gem_get_tiling { + uint32_t handle; + uint32_t tiling_flags; + uint32_t pitch; +}; + +struct drm_radeon_gem_mmap { + uint32_t handle; + uint32_t pad; + uint64_t offset; + uint64_t size; + uint64_t addr_ptr; +}; + +struct drm_radeon_gem_set_domain { + uint32_t handle; + uint32_t read_domains; + uint32_t write_domain; +}; + +struct drm_radeon_gem_wait_idle { + uint32_t handle; + uint32_t pad; +}; + +struct drm_radeon_gem_busy { + uint32_t handle; + uint32_t busy; +}; + +struct drm_radeon_gem_pread { + /** Handle for the object being read. */ + uint32_t handle; + uint32_t pad; + /** Offset into the object to read from */ + uint64_t offset; + /** Length of data to read */ + uint64_t size; + /** Pointer to write the data into. */ + /* void *, but pointers are not 32/64 compatible */ + uint64_t data_ptr; +}; + +struct drm_radeon_gem_pwrite { + /** Handle for the object being written to. */ + uint32_t handle; + uint32_t pad; + /** Offset into the object to write to */ + uint64_t offset; + /** Length of data to write */ + uint64_t size; + /** Pointer to read the data from. */ + /* void *, but pointers are not 32/64 compatible */ + uint64_t data_ptr; +}; + +#define RADEON_CHUNK_ID_RELOCS 0x01 +#define RADEON_CHUNK_ID_IB 0x02 + +struct drm_radeon_cs_chunk { + uint32_t chunk_id; + uint32_t length_dw; + uint64_t chunk_data; +}; + +struct drm_radeon_cs_reloc { + uint32_t handle; + uint32_t read_domains; + uint32_t write_domain; + uint32_t flags; +}; + +struct drm_radeon_cs { + uint32_t num_chunks; + uint32_t cs_id; + /* this points to uint64_t * which point to cs chunks */ + uint64_t chunks; + /* updates to the limits after this CS ioctl */ + uint64_t gart_limit; + uint64_t vram_limit; +}; + +#define RADEON_INFO_DEVICE_ID 0x00 +#define RADEON_INFO_NUM_GB_PIPES 0x01 + +struct drm_radeon_info { + uint32_t request; + uint32_t pad; + uint64_t value; +}; + #endif diff --git a/src/radeon_exa.c b/src/radeon_exa.c index ae68146..ca4c523 100644 --- a/src/radeon_exa.c +++ b/src/radeon_exa.c @@ -120,6 +120,19 @@ static __inline__ uint32_t F_TO_DW(float val) return tmp.l; } + +#ifdef XF86DRM_MODE + +static inline void radeon_add_pixmap(struct radeon_cs *cs, PixmapPtr pPix, int read_domains, int write_domain) +{ + struct radeon_exa_pixmap_priv *driver_priv = exaGetPixmapDriverPrivate(pPix); + + radeon_cs_space_add_persistent_bo(cs, driver_priv->bo, read_domains, write_domain); +} + +#endif /* XF86DRM_MODE */ + + /* Assumes that depth 15 and 16 can be used as depth 16, which is okay since we * require src and dest datatypes to be equal. */ @@ -179,7 +192,6 @@ static Bool RADEONGetOffsetPitch(PixmapPtr pPix, int bpp, uint32_t *pitch_offset Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix, uint32_t *pitch_offset) { - RINFO_FROM_SCREEN(pPix->drawable.pScreen); uint32_t pitch, offset; int bpp; @@ -187,7 +199,7 @@ Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix, uint32_t *pitch_offset) if (bpp == 24) bpp = 8; - offset = exaGetPixmapOffset(pPix) + info->fbLocation + pScrn->fbOffset; + offset = radeonGetPixmapOffset(pPix); pitch = exaGetPixmapPitch(pPix); return RADEONGetOffsetPitch(pPix, bpp, pitch_offset, offset, pitch); @@ -224,7 +236,7 @@ int RADEONBiggerCrtcArea(PixmapPtr pPix) static unsigned long swapper_surfaces[6]; -static Bool RADEONPrepareAccess(PixmapPtr pPix, int index) +static Bool RADEONPrepareAccess_BE(PixmapPtr pPix, int index) { RINFO_FROM_SCREEN(pPix->drawable.pScreen); unsigned char *RADEONMMIO = info->MMIO; @@ -290,7 +302,7 @@ static Bool RADEONPrepareAccess(PixmapPtr pPix, int index) return TRUE; } -static void RADEONFinishAccess(PixmapPtr pPix, int index) +static void RADEONFinishAccess_BE(PixmapPtr pPix, int index) { RINFO_FROM_SCREEN(pPix->drawable.pScreen); unsigned char *RADEONMMIO = info->MMIO; @@ -323,6 +335,172 @@ static void RADEONFinishAccess(PixmapPtr pPix, int index) #endif /* X_BYTE_ORDER == X_BIG_ENDIAN */ +#ifdef XF86DRM_MODE +static Bool RADEONPrepareAccess_CS(PixmapPtr pPix, int index) +{ + ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum]; + struct radeon_exa_pixmap_priv *driver_priv; + int ret; + + driver_priv = exaGetPixmapDriverPrivate(pPix); + if (!driver_priv) + return FALSE; + + /* if we have more refs than just the BO then flush */ + if (driver_priv->bo->cref > 1) + radeon_cs_flush_indirect(pScrn); + + /* flush IB */ + ret = radeon_bo_map(driver_priv->bo, 1); + if (ret) { + FatalError("failed to map pixmap %d\n", ret); + return FALSE; + } + + pPix->devPrivate.ptr = driver_priv->bo->ptr; + + return TRUE; +} + +static void RADEONFinishAccess_CS(PixmapPtr pPix, int index) +{ + struct radeon_exa_pixmap_priv *driver_priv; + + driver_priv = exaGetPixmapDriverPrivate(pPix); + if (!driver_priv) + return; + + radeon_bo_unmap(driver_priv->bo); + pPix->devPrivate.ptr = NULL; +} + + +void *RADEONEXACreatePixmap(ScreenPtr pScreen, int size, int align) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + struct radeon_exa_pixmap_priv *new_priv; + + new_priv = xcalloc(1, sizeof(struct radeon_exa_pixmap_priv)); + if (!new_priv) + return NULL; + + if (size == 0) + return new_priv; + + new_priv->bo = radeon_bo_open(info->bufmgr, 0, size, align, + RADEON_GEM_DOMAIN_VRAM, 0); + if (!new_priv->bo) { + xfree(new_priv); + ErrorF("Failed to alloc memory\n"); + return NULL; + } + + return new_priv; + +} + +void *RADEONEXACreatePixmap2(ScreenPtr pScreen, int width, int height, + int depth, int usage_hint, int bitsPerPixel, + int *new_pitch) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + struct radeon_exa_pixmap_priv *new_priv; + int padded_width; + uint32_t size; + uint32_t tiling = 0; + int pixmap_align = 0; + + if (usage_hint) { + if (info->allowColorTiling) { + if (usage_hint & RADEON_CREATE_PIXMAP_TILING_MACRO) + tiling |= RADEON_TILING_MACRO; + if (usage_hint & RADEON_CREATE_PIXMAP_TILING_MICRO) + tiling |= RADEON_TILING_MICRO; + } + } + + if (tiling) { + height = (height + 15) & ~15; + pixmap_align = 255; + } else + pixmap_align = 63; + + padded_width = ((width * bitsPerPixel + FB_MASK) >> FB_SHIFT) * sizeof(FbBits); + padded_width = (padded_width + pixmap_align) & ~pixmap_align; + size = height * padded_width; + + new_priv = xcalloc(1, sizeof(struct radeon_exa_pixmap_priv)); + if (!new_priv) + return NULL; + + if (size == 0) + return new_priv; + + *new_pitch = padded_width; + + new_priv->bo = radeon_bo_open(info->bufmgr, 0, size, 0, + RADEON_GEM_DOMAIN_VRAM, 0); + if (!new_priv->bo) { + xfree(new_priv); + ErrorF("Failed to alloc memory\n"); + return NULL; + } + + if (tiling) + radeon_bo_set_tiling(new_priv->bo, tiling, *new_pitch); + + return new_priv; +} + +static void RADEONEXADestroyPixmap(ScreenPtr pScreen, void *driverPriv) +{ + struct radeon_exa_pixmap_priv *driver_priv = driverPriv; + + if (!driverPriv) + return; + + if (driver_priv->bo) + radeon_bo_unref(driver_priv->bo); + xfree(driverPriv); +} + +struct radeon_bo *radeon_get_pixmap_bo(PixmapPtr pPix) +{ + struct radeon_exa_pixmap_priv *driver_priv; + driver_priv = exaGetPixmapDriverPrivate(pPix); + return driver_priv->bo; +} + +void radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo) +{ + struct radeon_exa_pixmap_priv *driver_priv; + + driver_priv = exaGetPixmapDriverPrivate(pPix); + if (driver_priv) { + if (driver_priv->bo) + radeon_bo_unref(driver_priv->bo); + + radeon_bo_ref(bo); + driver_priv->bo = bo; + } +} + +static Bool RADEONEXAPixmapIsOffscreen(PixmapPtr pPix) +{ + struct radeon_exa_pixmap_priv *driver_priv; + + driver_priv = exaGetPixmapDriverPrivate(pPix); + + if (!driver_priv) + return FALSE; + if (driver_priv->bo) + return TRUE; + return FALSE; +} +#endif + #define ENTER_DRAW(x) TRACE #define LEAVE_DRAW(x) TRACE /***********************************************************************/ @@ -332,6 +510,7 @@ static void RADEONFinishAccess(PixmapPtr pPix, int index) #define BEGIN_ACCEL(n) RADEONWaitForFifo(pScrn, (n)) #define OUT_ACCEL_REG(reg, val) OUTREG(reg, val) #define OUT_ACCEL_REG_F(reg, val) OUTREG(reg, F_TO_DW(val)) +#define OUT_RELOC(x, read, write) do {} while(0) #define FINISH_ACCEL() #ifdef RENDER @@ -345,6 +524,7 @@ static void RADEONFinishAccess(PixmapPtr pPix, int index) #undef OUT_ACCEL_REG #undef OUT_ACCEL_REG_F #undef FINISH_ACCEL +#undef OUT_RELOC #ifdef XF86DRI @@ -355,6 +535,7 @@ static void RADEONFinishAccess(PixmapPtr pPix, int index) #define BEGIN_ACCEL(n) BEGIN_RING(2*(n)) #define OUT_ACCEL_REG(reg, val) OUT_RING_REG(reg, val) #define FINISH_ACCEL() ADVANCE_RING() +#define OUT_RELOC(x, read, write) OUT_RING_RELOC(x, read, write) #define OUT_RING_F(x) OUT_RING(F_TO_DW(x)) @@ -523,6 +704,10 @@ RADEONTexOffsetStart(PixmapPtr pPix) { RINFO_FROM_SCREEN(pPix->drawable.pScreen); unsigned long long offset; + + if (exaGetPixmapDriverPrivate(pPix)) + return -1; + exaMoveInPixmap(pPix); ExaOffscreenMarkUsed(pPix); diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c index 7a27565..c74b9d9 100644 --- a/src/radeon_exa_funcs.c +++ b/src/radeon_exa_funcs.c @@ -74,6 +74,9 @@ FUNC_NAME(RADEONSync)(ScreenPtr pScreen, int marker) ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; RADEONInfoPtr info = RADEONPTR(pScrn); + if (info->cs) + return; + TRACE; if (info->accel_state->exaMarkerSynced != marker) { @@ -84,12 +87,71 @@ FUNC_NAME(RADEONSync)(ScreenPtr pScreen, int marker) RADEONPTR(pScrn)->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN; } +static void FUNC_NAME(Emit2DState)(ScrnInfoPtr pScrn, int op) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + int has_src; + ACCEL_PREAMBLE(); + + /* don't emit if no operation in progress */ + if (info->state_2d.op == 0 && op == 0) + return; + + has_src = info->state_2d.src_pitch_offset || (info->cs && info->state_2d.src_bo); + + if (has_src) { + BEGIN_ACCEL_RELOC(10, 2); + } else { + BEGIN_ACCEL_RELOC(9, 1); + } + OUT_ACCEL_REG(RADEON_DEFAULT_SC_BOTTOM_RIGHT, info->state_2d.default_sc_bottom_right); + OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL, info->state_2d.dp_gui_master_cntl); + OUT_ACCEL_REG(RADEON_DP_BRUSH_FRGD_CLR, info->state_2d.dp_brush_frgd_clr); + OUT_ACCEL_REG(RADEON_DP_BRUSH_BKGD_CLR, info->state_2d.dp_brush_bkgd_clr); + OUT_ACCEL_REG(RADEON_DP_SRC_FRGD_CLR, info->state_2d.dp_src_frgd_clr); + OUT_ACCEL_REG(RADEON_DP_SRC_BKGD_CLR, info->state_2d.dp_src_bkgd_clr); + OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, info->state_2d.dp_write_mask); + OUT_ACCEL_REG(RADEON_DP_CNTL, info->state_2d.dp_cntl); + + OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, info->state_2d.dst_pitch_offset); + if (info->cs) + OUT_RELOC(info->state_2d.dst_bo, 0, RADEON_GEM_DOMAIN_VRAM); + + if (has_src) { + OUT_ACCEL_REG(RADEON_SRC_PITCH_OFFSET, info->state_2d.src_pitch_offset); + if (info->cs) + OUT_RELOC(info->state_2d.src_bo, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0); + + } + FINISH_ACCEL(); + + if (op) + info->state_2d.op = op; + if (info->cs) + info->reemit_current2d = FUNC_NAME(Emit2DState); +} + +static void +FUNC_NAME(RADEONDone2D)(PixmapPtr pPix) +{ + RINFO_FROM_SCREEN(pPix->drawable.pScreen); + ACCEL_PREAMBLE(); + + TRACE; + + info->state_2d.op = 0; + BEGIN_ACCEL(2); + OUT_ACCEL_REG(RADEON_DSTCACHE_CTLSTAT, RADEON_RB2D_DC_FLUSH_ALL); + OUT_ACCEL_REG(RADEON_WAIT_UNTIL, + RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_DMA_GUI_IDLE); + FINISH_ACCEL(); +} + static Bool FUNC_NAME(RADEONPrepareSolid)(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) { RINFO_FROM_SCREEN(pPix->drawable.pScreen); uint32_t datatype, dst_pitch_offset; - ACCEL_PREAMBLE(); TRACE; @@ -102,20 +164,47 @@ FUNC_NAME(RADEONPrepareSolid)(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) RADEON_SWITCH_TO_2D(); - BEGIN_ACCEL(5); - OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL, - RADEON_GMC_DST_PITCH_OFFSET_CNTL | - RADEON_GMC_BRUSH_SOLID_COLOR | - (datatype << 8) | - RADEON_GMC_SRC_DATATYPE_COLOR | - RADEON_ROP[alu].pattern | - RADEON_GMC_CLR_CMP_CNTL_DIS); - OUT_ACCEL_REG(RADEON_DP_BRUSH_FRGD_CLR, fg); - OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, pm); - OUT_ACCEL_REG(RADEON_DP_CNTL, - (RADEON_DST_X_LEFT_TO_RIGHT | RADEON_DST_Y_TOP_TO_BOTTOM)); - OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, dst_pitch_offset); - FINISH_ACCEL(); +#ifdef XF86DRM_MODE + if (info->cs) { + struct radeon_exa_pixmap_priv *driver_priv; + int ret; + + radeon_cs_space_reset_bos(info->cs); + + driver_priv = exaGetPixmapDriverPrivate(pPix); + radeon_cs_space_add_persistent_bo(info->cs, driver_priv->bo, 0, RADEON_GEM_DOMAIN_VRAM); + + ret = radeon_cs_space_check(info->cs); + if (ret) + RADEON_FALLBACK(("Not enough RAM to hw accel solid operation\n")); + + driver_priv = exaGetPixmapDriverPrivate(pPix); + if (driver_priv) + info->state_2d.dst_bo = driver_priv->bo; + } +#endif + + info->state_2d.default_sc_bottom_right = (RADEON_DEFAULT_SC_RIGHT_MAX | + RADEON_DEFAULT_SC_BOTTOM_MAX); + info->state_2d.dp_brush_bkgd_clr = 0x00000000; + info->state_2d.dp_src_frgd_clr = 0xffffffff; + info->state_2d.dp_src_bkgd_clr = 0x00000000; + info->state_2d.dp_gui_master_cntl = (RADEON_GMC_DST_PITCH_OFFSET_CNTL | + RADEON_GMC_BRUSH_SOLID_COLOR | + (datatype << 8) | + RADEON_GMC_SRC_DATATYPE_COLOR | + RADEON_ROP[alu].pattern | + RADEON_GMC_CLR_CMP_CNTL_DIS); + info->state_2d.dp_brush_frgd_clr = fg; + info->state_2d.dp_cntl = (RADEON_DST_X_LEFT_TO_RIGHT | RADEON_DST_Y_TOP_TO_BOTTOM); + info->state_2d.dp_write_mask = pm; + info->state_2d.dst_pitch_offset = dst_pitch_offset; + info->state_2d.src_pitch_offset = 0; + info->state_2d.src_bo = NULL; + + info->accel_state->dst_pix = pPix; + + FUNC_NAME(Emit2DState)(pScrn, RADEON_2D_EXA_SOLID); return TRUE; } @@ -129,6 +218,13 @@ FUNC_NAME(RADEONSolid)(PixmapPtr pPix, int x1, int y1, int x2, int y2) TRACE; +#if defined(ACCEL_CP) && defined(XF86DRM_MODE) + if (info->cs && CS_FULL(info->cs)) { + FUNC_NAME(RADEONDone2D)(info->accel_state->dst_pix); + radeon_cs_flush_indirect(pScrn); + } +#endif + if (info->accel_state->vsync) FUNC_NAME(RADEONWaitForVLine)(pScrn, pPix, RADEONBiggerCrtcArea(pPix), y1, y2); @@ -138,48 +234,35 @@ FUNC_NAME(RADEONSolid)(PixmapPtr pPix, int x1, int y1, int x2, int y2) FINISH_ACCEL(); } -static void -FUNC_NAME(RADEONDoneSolid)(PixmapPtr pPix) -{ - RINFO_FROM_SCREEN(pPix->drawable.pScreen); - ACCEL_PREAMBLE(); - - TRACE; - - BEGIN_ACCEL(2); - OUT_ACCEL_REG(RADEON_DSTCACHE_CTLSTAT, RADEON_RB2D_DC_FLUSH_ALL); - OUT_ACCEL_REG(RADEON_WAIT_UNTIL, - RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_DMA_GUI_IDLE); - FINISH_ACCEL(); -} - void FUNC_NAME(RADEONDoPrepareCopy)(ScrnInfoPtr pScrn, uint32_t src_pitch_offset, uint32_t dst_pitch_offset, uint32_t datatype, int rop, Pixel planemask) { RADEONInfoPtr info = RADEONPTR(pScrn); - ACCEL_PREAMBLE(); - - RADEON_SWITCH_TO_2D(); - BEGIN_ACCEL(5); - OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL, - RADEON_GMC_DST_PITCH_OFFSET_CNTL | - RADEON_GMC_SRC_PITCH_OFFSET_CNTL | - RADEON_GMC_BRUSH_NONE | - (datatype << 8) | - RADEON_GMC_SRC_DATATYPE_COLOR | - RADEON_ROP[rop].rop | - RADEON_DP_SRC_SOURCE_MEMORY | - RADEON_GMC_CLR_CMP_CNTL_DIS); - OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, planemask); - OUT_ACCEL_REG(RADEON_DP_CNTL, - ((info->accel_state->xdir >= 0 ? RADEON_DST_X_LEFT_TO_RIGHT : 0) | - (info->accel_state->ydir >= 0 ? RADEON_DST_Y_TOP_TO_BOTTOM : 0))); - OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, dst_pitch_offset); - OUT_ACCEL_REG(RADEON_SRC_PITCH_OFFSET, src_pitch_offset); - FINISH_ACCEL(); + /* setup 2D state */ + info->state_2d.dp_gui_master_cntl = (RADEON_GMC_DST_PITCH_OFFSET_CNTL | + RADEON_GMC_SRC_PITCH_OFFSET_CNTL | + RADEON_GMC_BRUSH_NONE | + (datatype << 8) | + RADEON_GMC_SRC_DATATYPE_COLOR | + RADEON_ROP[rop].rop | + RADEON_DP_SRC_SOURCE_MEMORY | + RADEON_GMC_CLR_CMP_CNTL_DIS); + info->state_2d.dp_cntl = ((info->accel_state->xdir >= 0 ? RADEON_DST_X_LEFT_TO_RIGHT : 0) | + (info->accel_state->ydir >= 0 ? RADEON_DST_Y_TOP_TO_BOTTOM : 0)); + info->state_2d.dp_brush_frgd_clr = 0xffffffff; + info->state_2d.dp_brush_bkgd_clr = 0x00000000; + info->state_2d.dp_src_frgd_clr = 0xffffffff; + info->state_2d.dp_src_bkgd_clr = 0x00000000; + info->state_2d.dp_write_mask = planemask; + info->state_2d.dst_pitch_offset = dst_pitch_offset; + info->state_2d.src_pitch_offset = src_pitch_offset; + info->state_2d.default_sc_bottom_right = (RADEON_DEFAULT_SC_RIGHT_MAX + | RADEON_DEFAULT_SC_BOTTOM_MAX); + + FUNC_NAME(Emit2DState)(pScrn, RADEON_2D_EXA_COPY); } static Bool @@ -190,11 +273,34 @@ FUNC_NAME(RADEONPrepareCopy)(PixmapPtr pSrc, PixmapPtr pDst, { RINFO_FROM_SCREEN(pDst->drawable.pScreen); uint32_t datatype, src_pitch_offset, dst_pitch_offset; - TRACE; + RADEON_SWITCH_TO_2D(); + +#ifdef XF86DRM_MODE + if (info->cs) { + struct radeon_exa_pixmap_priv *driver_priv; + int ret; + + radeon_cs_space_reset_bos(info->cs); + + driver_priv = exaGetPixmapDriverPrivate(pSrc); + radeon_cs_space_add_persistent_bo(info->cs, driver_priv->bo, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); + info->state_2d.src_bo = driver_priv->bo; + + driver_priv = exaGetPixmapDriverPrivate(pDst); + radeon_cs_space_add_persistent_bo(info->cs, driver_priv->bo, 0, RADEON_GEM_DOMAIN_VRAM); + info->state_2d.dst_bo = driver_priv->bo; + + ret = radeon_cs_space_check(info->cs); + if (ret) + RADEON_FALLBACK(("Not enough RAM to hw accel copy operation\n")); + } +#endif + info->accel_state->xdir = xdir; info->accel_state->ydir = ydir; + info->accel_state->dst_pix = pDst; if (pDst->drawable.bitsPerPixel == 24) RADEON_FALLBACK(("24bpp unsupported")); @@ -222,6 +328,13 @@ FUNC_NAME(RADEONCopy)(PixmapPtr pDst, TRACE; +#if defined(ACCEL_CP) && defined(XF86DRM_MODE) + if (info->cs && CS_FULL(info->cs)) { + FUNC_NAME(RADEONDone2D)(info->accel_state->dst_pix); + radeon_cs_flush_indirect(pScrn); + } +#endif + if (info->accel_state->xdir < 0) { srcX += w - 1; dstX += w - 1; @@ -231,7 +344,7 @@ FUNC_NAME(RADEONCopy)(PixmapPtr pDst, dstY += h - 1; } - if (info->accel_state->vsync) + if (info->accel_state->vsync) FUNC_NAME(RADEONWaitForVLine)(pScrn, pDst, RADEONBiggerCrtcArea(pDst), dstY, dstY + h); BEGIN_ACCEL(3); @@ -243,22 +356,6 @@ FUNC_NAME(RADEONCopy)(PixmapPtr pDst, FINISH_ACCEL(); } -static void -FUNC_NAME(RADEONDoneCopy)(PixmapPtr pDst) -{ - RINFO_FROM_SCREEN(pDst->drawable.pScreen); - ACCEL_PREAMBLE(); - - TRACE; - - BEGIN_ACCEL(2); - OUT_ACCEL_REG(RADEON_DSTCACHE_CTLSTAT, RADEON_RB2D_DC_FLUSH_ALL); - OUT_ACCEL_REG(RADEON_WAIT_UNTIL, - RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_DMA_GUI_IDLE); - FINISH_ACCEL(); -} - - #ifdef ACCEL_CP static Bool @@ -303,14 +400,22 @@ RADEONUploadToScreenCP(PixmapPtr pDst, int x, int y, int w, int h, /* Emit blit with arbitrary source and destination offsets and pitches */ static void -RADEONBlitChunk(ScrnInfoPtr pScrn, uint32_t datatype, uint32_t src_pitch_offset, - uint32_t dst_pitch_offset, int srcX, int srcY, int dstX, int dstY, - int w, int h) +RADEONBlitChunk(ScrnInfoPtr pScrn, struct radeon_bo *src_bo, + struct radeon_bo *dst_bo, uint32_t datatype, + uint32_t src_pitch_offset, uint32_t dst_pitch_offset, + int srcX, int srcY, int dstX, int dstY, int w, int h, + uint32_t src_domain, uint32_t dst_domain) { RADEONInfoPtr info = RADEONPTR(pScrn); ACCEL_PREAMBLE(); - BEGIN_ACCEL(6); + if (src_bo && dst_bo) { + BEGIN_ACCEL_RELOC(6, 2); + } else if (src_bo && dst_bo == NULL) { + BEGIN_ACCEL_RELOC(6, 1); + } else { + BEGIN_ACCEL(6); + } OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL, RADEON_GMC_DST_PITCH_OFFSET_CNTL | RADEON_GMC_SRC_PITCH_OFFSET_CNTL | @@ -322,7 +427,13 @@ RADEONBlitChunk(ScrnInfoPtr pScrn, uint32_t datatype, uint32_t src_pitch_offset, RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS); OUT_ACCEL_REG(RADEON_SRC_PITCH_OFFSET, src_pitch_offset); + if (src_bo) { + OUT_RELOC(src_bo, src_domain, 0); + } OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, dst_pitch_offset); + if (dst_bo) { + OUT_RELOC(dst_bo, 0, dst_domain); + } OUT_ACCEL_REG(RADEON_SRC_Y_X, (srcY << 16) | srcX); OUT_ACCEL_REG(RADEON_DST_Y_X, (dstY << 16) | dstX); OUT_ACCEL_REG(RADEON_DST_HEIGHT_WIDTH, (h << 16) | w); @@ -334,6 +445,152 @@ RADEONBlitChunk(ScrnInfoPtr pScrn, uint32_t datatype, uint32_t src_pitch_offset, FINISH_ACCEL(); } +#if defined(XF86DRM_MODE) +static Bool +RADEONUploadToScreenCS(PixmapPtr pDst, int x, int y, int w, int h, + char *src, int src_pitch) +{ + RINFO_FROM_SCREEN(pDst->drawable.pScreen); + struct radeon_exa_pixmap_priv *driver_priv; + struct radeon_bo *scratch; + unsigned size; + uint32_t datatype = 0; + uint32_t dst_domain; + uint32_t dst_pitch_offset; + unsigned bpp = pDst->drawable.bitsPerPixel; + uint32_t scratch_pitch = (w * bpp / 8 + 63) & ~63; + Bool r; + int i; + + if (bpp < 8) + return FALSE; + + driver_priv = exaGetPixmapDriverPrivate(pDst); + + /* If we know the BO won't be busy, don't bother */ + if (driver_priv->bo->cref == 1 && + !radeon_bo_is_busy(driver_priv->bo, &dst_domain)) + return FALSE; + + size = scratch_pitch * h; + scratch = radeon_bo_open(info->bufmgr, 0, size, 0, RADEON_GEM_DOMAIN_GTT, 0); + if (scratch == NULL) { + return FALSE; + } + radeon_cs_space_reset_bos(info->cs); + radeon_add_pixmap(info->cs, pDst, 0, RADEON_GEM_DOMAIN_VRAM); + radeon_cs_space_add_persistent_bo(info->cs, scratch, RADEON_GEM_DOMAIN_GTT, 0); + r = radeon_cs_space_check(info->cs); + if (r) { + r = FALSE; + goto out; + } + + r = radeon_bo_map(scratch, 0); + if (r) { + r = FALSE; + goto out; + } + r = TRUE; + size = w * bpp / 8; + for (i = 0; i < h; i++) { + memcpy(scratch->ptr + i * scratch_pitch, src, size); + src += src_pitch; + } + radeon_bo_unmap(scratch); + + RADEONGetDatatypeBpp(pDst->drawable.bitsPerPixel, &datatype); + RADEONGetPixmapOffsetPitch(pDst, &dst_pitch_offset); + ACCEL_PREAMBLE(); + RADEON_SWITCH_TO_2D(); + RADEONBlitChunk(pScrn, scratch, driver_priv->bo, datatype, scratch_pitch << 16, + dst_pitch_offset, 0, 0, x, y, w, h, + RADEON_GEM_DOMAIN_GTT, RADEON_GEM_DOMAIN_VRAM); + +out: + radeon_bo_unref(scratch); + return r; +} + +static Bool +RADEONDownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w, + int h, char *dst, int dst_pitch) +{ + RINFO_FROM_SCREEN(pSrc->drawable.pScreen); + struct radeon_exa_pixmap_priv *driver_priv; + struct radeon_bo *scratch; + unsigned size; + uint32_t datatype = 0; + uint32_t src_domain = 0; + uint32_t src_pitch_offset; + unsigned bpp = pSrc->drawable.bitsPerPixel; + uint32_t scratch_pitch = (w * bpp / 8 + 63) & ~63; + Bool r; + + if (bpp < 8) + return FALSE; + + driver_priv = exaGetPixmapDriverPrivate(pSrc); + + /* If we know the BO won't end up in VRAM anyway, don't bother */ + if (driver_priv->bo->cref > 1) { + src_domain = driver_priv->bo->space_accounted & 0xffff; + if (!src_domain) + src_domain = driver_priv->bo->space_accounted >> 16; + + if ((src_domain & (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) == + (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) + src_domain = 0; + } + + if (!src_domain) + radeon_bo_is_busy(driver_priv->bo, &src_domain); + + if (src_domain != RADEON_GEM_DOMAIN_VRAM) + return FALSE; + + size = scratch_pitch * h; + scratch = radeon_bo_open(info->bufmgr, 0, size, 0, RADEON_GEM_DOMAIN_GTT, 0); + if (scratch == NULL) { + return FALSE; + } + radeon_cs_space_reset_bos(info->cs); + radeon_add_pixmap(info->cs, pSrc, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); + radeon_cs_space_add_persistent_bo(info->cs, scratch, 0, RADEON_GEM_DOMAIN_GTT); + r = radeon_cs_space_check(info->cs); + if (r) { + r = FALSE; + goto out; + } + RADEONGetDatatypeBpp(pSrc->drawable.bitsPerPixel, &datatype); + RADEONGetPixmapOffsetPitch(pSrc, &src_pitch_offset); + ACCEL_PREAMBLE(); + RADEON_SWITCH_TO_2D(); + RADEONBlitChunk(pScrn, driver_priv->bo, scratch, datatype, src_pitch_offset, + scratch_pitch << 16, x, y, 0, 0, w, h, + RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, + RADEON_GEM_DOMAIN_GTT); + FLUSH_RING(); + + r = radeon_bo_map(scratch, 0); + if (r) { + r = FALSE; + goto out; + } + r = TRUE; + w *= bpp / 8; + size = 0; + while (h--) { + memcpy(dst, scratch->ptr + size, w); + size += scratch_pitch; + dst += dst_pitch; + } + radeon_bo_unmap(scratch); +out: + radeon_bo_unref(scratch); + return r; +} +#endif static Bool RADEONDownloadFromScreenCP(PixmapPtr pSrc, int x, int y, int w, int h, @@ -367,8 +624,8 @@ RADEONDownloadFromScreenCP(PixmapPtr pSrc, int x, int y, int w, int h, RADEON_SWITCH_TO_2D(); /* Kick the first blit as early as possible */ - RADEONBlitChunk(pScrn, datatype, src_pitch_offset, scratch_pitch_offset, - x, y, 0, 0, w, hpass); + RADEONBlitChunk(pScrn, NULL, NULL, datatype, src_pitch_offset, + scratch_pitch_offset, x, y, 0, 0, w, hpass, 0, 0); FLUSH_RING(); #if X_BYTE_ORDER == X_BIG_ENDIAN @@ -394,8 +651,9 @@ RADEONDownloadFromScreenCP(PixmapPtr pSrc, int x, int y, int w, int h, /* Prepare next blit if anything's left */ if (hpass) { scratch_off = scratch->total/2 - scratch_off; - RADEONBlitChunk(pScrn, datatype, src_pitch_offset, scratch_pitch_offset + (scratch_off >> 10), - x, y, 0, 0, w, hpass); + RADEONBlitChunk(pScrn, NULL, NULL, datatype, src_pitch_offset, + scratch_pitch_offset + (scratch_off >> 10), + x, y, 0, 0, w, hpass, 0, 0); } /* @@ -459,24 +717,32 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen) info->accel_state->exa->PrepareSolid = FUNC_NAME(RADEONPrepareSolid); info->accel_state->exa->Solid = FUNC_NAME(RADEONSolid); - info->accel_state->exa->DoneSolid = FUNC_NAME(RADEONDoneSolid); + info->accel_state->exa->DoneSolid = FUNC_NAME(RADEONDone2D); info->accel_state->exa->PrepareCopy = FUNC_NAME(RADEONPrepareCopy); info->accel_state->exa->Copy = FUNC_NAME(RADEONCopy); - info->accel_state->exa->DoneCopy = FUNC_NAME(RADEONDoneCopy); + info->accel_state->exa->DoneCopy = FUNC_NAME(RADEONDone2D); info->accel_state->exa->MarkSync = FUNC_NAME(RADEONMarkSync); info->accel_state->exa->WaitMarker = FUNC_NAME(RADEONSync); #ifdef ACCEL_CP - info->accel_state->exa->UploadToScreen = RADEONUploadToScreenCP; - if (info->accelDFS) - info->accel_state->exa->DownloadFromScreen = RADEONDownloadFromScreenCP; + if (!info->kms_enabled) { + info->accel_state->exa->UploadToScreen = RADEONUploadToScreenCP; + if (info->accelDFS) + info->accel_state->exa->DownloadFromScreen = RADEONDownloadFromScreenCP; + } +# if defined(XF86DRM_MODE) + else { + info->accel_state->exa->UploadToScreen = &RADEONUploadToScreenCS; + info->accel_state->exa->DownloadFromScreen = &RADEONDownloadFromScreenCS; + } +# endif #endif #if X_BYTE_ORDER == X_BIG_ENDIAN - info->accel_state->exa->PrepareAccess = RADEONPrepareAccess; - info->accel_state->exa->FinishAccess = RADEONFinishAccess; -#endif /* X_BYTE_ORDER == X_BIG_ENDIAN */ + info->accel_state->exa->PrepareAccess = RADEONPrepareAccess_BE; + info->accel_state->exa->FinishAccess = RADEONFinishAccess_BE; +#endif info->accel_state->exa->flags = EXA_OFFSCREEN_PIXMAPS; #ifdef EXA_SUPPORTS_PREPARE_AUX @@ -489,12 +755,18 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen) info->accel_state->exa->pixmapOffsetAlign = RADEON_BUFFER_ALIGN + 1; info->accel_state->exa->pixmapPitchAlign = 64; +#ifdef EXA_HANDLES_PIXMAPS + if (info->cs) { + info->accel_state->exa->flags |= EXA_HANDLES_PIXMAPS; +#ifdef EXA_MIXED_PIXMAPS + info->accel_state->exa->flags |= EXA_MIXED_PIXMAPS; +#endif + } +#endif + #ifdef RENDER if (info->RenderAccel) { - if (info->ChipFamily >= CHIP_FAMILY_R600) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Render acceleration " - "unsupported on R600 and newer cards.\n"); - else if (IS_R300_3D || IS_R500_3D) { + if (IS_R300_3D || IS_R500_3D) { if ((info->ChipFamily < CHIP_FAMILY_RS400) #ifdef XF86DRI || (info->directRenderingEnabled) @@ -529,6 +801,22 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen) } #endif +#ifdef XF86DRM_MODE +#if (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 4) + if (info->cs) { + info->accel_state->exa->CreatePixmap = RADEONEXACreatePixmap; + info->accel_state->exa->DestroyPixmap = RADEONEXADestroyPixmap; + info->accel_state->exa->PixmapIsOffscreen = RADEONEXAPixmapIsOffscreen; + info->accel_state->exa->PrepareAccess = RADEONPrepareAccess_CS; + info->accel_state->exa->FinishAccess = RADEONFinishAccess_CS; +#if (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 5) + info->accel_state->exa->CreatePixmap2 = RADEONEXACreatePixmap2; +#endif + } +#endif +#endif + + #if EXA_VERSION_MAJOR > 2 || (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 3) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting EXA maxPitchBytes\n"); diff --git a/src/radeon_exa_render.c b/src/radeon_exa_render.c index 68f9514..6053eef 100644 --- a/src/radeon_exa_render.c +++ b/src/radeon_exa_render.c @@ -233,10 +233,11 @@ static Bool RADEONCheckTexturePOT(PicturePtr pPict, Bool canTile) { int w = pPict->pDrawable->width; int h = pPict->pDrawable->height; + unsigned int repeatType = pPict->repeat ? pPict->repeatType : RepeatNone; - if (pPict->repeat && pPict->repeatType != RepeatPad && + if ((repeatType == RepeatNormal || repeatType == RepeatReflect) && ((w & (w - 1)) != 0 || (h & (h - 1)) != 0) && - !(pPict->repeatType == RepeatNormal && !pPict->transform && canTile)) + !(repeatType == RepeatNormal && !pPict->transform && canTile)) RADEON_FALLBACK(("NPOT repeating %s unsupported (%dx%d), transform=%d\n", canTile ? "source" : "mask", w, h, pPict->transform != 0)); @@ -280,11 +281,12 @@ static Bool RADEONSetupSourceTile(PicturePtr pPict, Bool needMatchingPitch) { RINFO_FROM_SCREEN(pPix->drawable.pScreen); + unsigned int repeatType = pPict->repeat ? pPict->repeatType : RepeatNone; info->accel_state->need_src_tile_x = info->accel_state->need_src_tile_y = FALSE; info->accel_state->src_tile_width = info->accel_state->src_tile_height = 65536; /* "infinite" */ - if (pPict->repeat && pPict->repeatType != RepeatPad) { + if (repeatType == RepeatNormal || repeatType == RepeatReflect) { Bool badPitch = needMatchingPitch && !RADEONPitchMatches(pPix); int w = pPict->pDrawable->width; @@ -300,7 +302,7 @@ static Bool RADEONSetupSourceTile(PicturePtr pPict, if ((info->accel_state->need_src_tile_x || info->accel_state->need_src_tile_y) && - pPict->repeatType != RepeatNormal) + repeatType != RepeatNormal) RADEON_FALLBACK(("Can only tile RepeatNormal at this time\n")); if (!canTile1d) @@ -362,16 +364,18 @@ static Bool FUNC_NAME(R100TextureSetup)(PicturePtr pPict, PixmapPtr pPix, uint32_t txfilter, txformat, txoffset, txpitch; int w = pPict->pDrawable->width; int h = pPict->pDrawable->height; - Bool repeat = pPict->repeat && pPict->repeatType != RepeatPad && + unsigned int repeatType = pPict->repeat ? pPict->repeatType : RepeatNone; + Bool repeat = (repeatType == RepeatNormal || repeatType == RepeatReflect) && !(unit == 0 && (info->accel_state->need_src_tile_x || info->accel_state->need_src_tile_y)); int i; + struct radeon_exa_pixmap_priv *driver_priv; ACCEL_PREAMBLE(); txpitch = exaGetPixmapPitch(pPix); - txoffset = exaGetPixmapOffset(pPix) + info->fbLocation + pScrn->fbOffset; + txoffset = 0; + + CHECK_OFFSET(pPix, 0x1f, "texture"); - if ((txoffset & 0x1f) != 0) - RADEON_FALLBACK(("Bad texture offset 0x%x\n", (int)txoffset)); if ((txpitch & 0x1f) != 0) RADEON_FALLBACK(("Bad texture pitch 0x%x\n", (int)txpitch)); @@ -409,10 +413,12 @@ static Bool FUNC_NAME(R100TextureSetup)(PicturePtr pPict, PixmapPtr pPix, RADEON_FALLBACK(("Bad filter 0x%x\n", pPict->filter)); } - if (repeat) { - switch (pPict->repeatType) { + switch (repeatType) { case RepeatNormal: - txfilter |= RADEON_CLAMP_S_WRAP | RADEON_CLAMP_T_WRAP; + if (txformat & RADEON_TXFORMAT_NON_POWER2) + txfilter |= RADEON_CLAMP_S_CLAMP_LAST | RADEON_CLAMP_T_CLAMP_LAST; + else + txfilter |= RADEON_CLAMP_S_WRAP | RADEON_CLAMP_T_WRAP; break; case RepeatPad: txfilter |= RADEON_CLAMP_S_CLAMP_LAST | RADEON_CLAMP_T_CLAMP_LAST; @@ -421,28 +427,33 @@ static Bool FUNC_NAME(R100TextureSetup)(PicturePtr pPict, PixmapPtr pPix, txfilter |= RADEON_CLAMP_S_MIRROR | RADEON_CLAMP_T_MIRROR; break; case RepeatNone: - /* Nothing to do */ + /* don't set an illegal clamp mode for rects */ + if (txformat & RADEON_TXFORMAT_NON_POWER2) + txfilter |= RADEON_CLAMP_S_CLAMP_LAST | RADEON_CLAMP_T_CLAMP_LAST; break; - } } - BEGIN_ACCEL(5); + BEGIN_ACCEL_RELOC(5, 1); if (unit == 0) { OUT_ACCEL_REG(RADEON_PP_TXFILTER_0, txfilter); OUT_ACCEL_REG(RADEON_PP_TXFORMAT_0, txformat); - OUT_ACCEL_REG(RADEON_PP_TXOFFSET_0, txoffset); OUT_ACCEL_REG(RADEON_PP_TEX_SIZE_0, (pPix->drawable.width - 1) | ((pPix->drawable.height - 1) << RADEON_TEX_VSIZE_SHIFT)); OUT_ACCEL_REG(RADEON_PP_TEX_PITCH_0, txpitch - 32); + + EMIT_READ_OFFSET(RADEON_PP_TXOFFSET_0, txoffset, pPix); + /* emit a texture relocation */ } else { OUT_ACCEL_REG(RADEON_PP_TXFILTER_1, txfilter); OUT_ACCEL_REG(RADEON_PP_TXFORMAT_1, txformat); - OUT_ACCEL_REG(RADEON_PP_TXOFFSET_1, txoffset); + OUT_ACCEL_REG(RADEON_PP_TEX_SIZE_1, (pPix->drawable.width - 1) | ((pPix->drawable.height - 1) << RADEON_TEX_VSIZE_SHIFT)); OUT_ACCEL_REG(RADEON_PP_TEX_PITCH_1, txpitch - 32); + EMIT_READ_OFFSET(RADEON_PP_TXOFFSET_1, txoffset, pPix); + /* emit a texture relocation */ } FINISH_ACCEL(); @@ -478,7 +489,7 @@ static Bool R100CheckComposite(int op, PicturePtr pSrcPicture, RADEON_FALLBACK(("Unsupported Composite op 0x%x\n", op)); if (!pSrcPicture->pDrawable) - return FALSE; + RADEON_FALLBACK(("Solid or gradient pictures not supported yet\n")); /* r100 limit should be 2048, there are issues with 2048 * see 197a62704742a4a19736c2637ac92d1dc5ab34ed @@ -537,6 +548,45 @@ static Bool R100CheckComposite(int op, PicturePtr pSrcPicture, return TRUE; } + +static Bool +RADEONPrepareCompositeCS(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, + PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr pMask, + PixmapPtr pDst) +{ + RINFO_FROM_SCREEN(pDst->drawable.pScreen); + + info->accel_state->composite_op = op; + info->accel_state->dst_pic = pDstPicture; + info->accel_state->msk_pic = pMaskPicture; + info->accel_state->src_pic = pSrcPicture; + info->accel_state->dst_pix = pDst; + info->accel_state->msk_pix = pMask; + info->accel_state->src_pix = pSrc; + +#ifdef XF86DRM_MODE + if (info->cs) { + int ret; + + radeon_cs_space_reset_bos(info->cs); + + radeon_add_pixmap(info->cs, pSrc, + RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); + + if (pMask) + radeon_add_pixmap(info->cs, pMask, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); + + radeon_add_pixmap(info->cs, pDst, 0, RADEON_GEM_DOMAIN_VRAM); + + ret = radeon_cs_space_check(info->cs); + if (ret) + RADEON_FALLBACK(("Not enough RAM to hw accel composite operation\n")); + } +#endif + + return TRUE; +} + #endif /* ONLY_ONCE */ static Bool FUNC_NAME(R100PrepareComposite)(int op, @@ -548,9 +598,10 @@ static Bool FUNC_NAME(R100PrepareComposite)(int op, PixmapPtr pDst) { RINFO_FROM_SCREEN(pDst->drawable.pScreen); - uint32_t dst_format, dst_offset, dst_pitch, colorpitch; + uint32_t dst_format, dst_pitch, colorpitch; uint32_t pp_cntl, blendcntl, cblend, ablend; int pixel_shift; + struct radeon_exa_pixmap_priv *driver_priv; ACCEL_PREAMBLE(); TRACE; @@ -561,29 +612,25 @@ static Bool FUNC_NAME(R100PrepareComposite)(int op, if (pDstPicture->format == PICT_a8 && RadeonBlendOp[op].dst_alpha) RADEON_FALLBACK(("Can't dst alpha blend A8\n")); - if (pMask) - info->accel_state->has_mask = TRUE; - else - info->accel_state->has_mask = FALSE; - pixel_shift = pDst->drawable.bitsPerPixel >> 4; - dst_offset = exaGetPixmapOffset(pDst) + info->fbLocation + pScrn->fbOffset; dst_pitch = exaGetPixmapPitch(pDst); colorpitch = dst_pitch >> pixel_shift; if (RADEONPixmapIsColortiled(pDst)) colorpitch |= RADEON_COLOR_TILE_ENABLE; - dst_offset = exaGetPixmapOffset(pDst) + info->fbLocation + pScrn->fbOffset; - dst_pitch = exaGetPixmapPitch(pDst); - if ((dst_offset & 0x0f) != 0) - RADEON_FALLBACK(("Bad destination offset 0x%x\n", (int)dst_offset)); + CHECK_OFFSET(pDst, 0x0f, "destination"); + if (((dst_pitch >> pixel_shift) & 0x7) != 0) RADEON_FALLBACK(("Bad destination pitch 0x%x\n", (int)dst_pitch)); if (!RADEONSetupSourceTile(pSrcPicture, pSrc, FALSE, TRUE)) return FALSE; + RADEONPrepareCompositeCS(op, pSrcPicture, pMaskPicture, pDstPicture, + pSrc, pMask, pDst); + + /* switch to 3D after doing buffer space checks as the latter may flush */ RADEON_SWITCH_TO_3D(); if (!FUNC_NAME(R100TextureSetup)(pSrcPicture, pSrc, 0)) @@ -598,11 +645,11 @@ static Bool FUNC_NAME(R100PrepareComposite)(int op, info->accel_state->is_transform[1] = FALSE; } - BEGIN_ACCEL(8); + BEGIN_ACCEL_RELOC(10, 2); OUT_ACCEL_REG(RADEON_PP_CNTL, pp_cntl); OUT_ACCEL_REG(RADEON_RB3D_CNTL, dst_format | RADEON_ALPHA_BLEND_ENABLE); - OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, dst_offset); - OUT_ACCEL_REG(RADEON_RB3D_COLORPITCH, colorpitch); + EMIT_WRITE_OFFSET(RADEON_RB3D_COLOROFFSET, 0, pDst); + EMIT_COLORPITCH(RADEON_RB3D_COLORPITCH, colorpitch, pDst); /* IN operator: Multiply src by mask components or mask alpha. * BLEND_CTL_ADD is A * B + C. @@ -650,6 +697,10 @@ static Bool FUNC_NAME(R100PrepareComposite)(int op, blendcntl = RADEONGetBlendCntl(op, pMaskPicture, pDstPicture->format); OUT_ACCEL_REG(RADEON_RB3D_BLENDCNTL, blendcntl); + + OUT_ACCEL_REG(RADEON_RE_TOP_LEFT, 0); + OUT_ACCEL_REG(RADEON_RE_WIDTH_HEIGHT, (((pDst->drawable.width) << RADEON_RE_WIDTH_SHIFT) | + ((pDst->drawable.height) << RADEON_RE_HEIGHT_SHIFT))); FINISH_ACCEL(); return TRUE; @@ -698,16 +749,18 @@ static Bool FUNC_NAME(R200TextureSetup)(PicturePtr pPict, PixmapPtr pPix, uint32_t txfilter, txformat, txoffset, txpitch; int w = pPict->pDrawable->width; int h = pPict->pDrawable->height; - Bool repeat = pPict->repeat && pPict->repeatType != RepeatPad && + unsigned int repeatType = pPict->repeat ? pPict->repeatType : RepeatNone; + Bool repeat = (repeatType == RepeatNormal || repeatType == RepeatReflect) && !(unit == 0 && (info->accel_state->need_src_tile_x || info->accel_state->need_src_tile_y)); int i; + struct radeon_exa_pixmap_priv *driver_priv; ACCEL_PREAMBLE(); txpitch = exaGetPixmapPitch(pPix); - txoffset = exaGetPixmapOffset(pPix) + info->fbLocation + pScrn->fbOffset; - if ((txoffset & 0x1f) != 0) - RADEON_FALLBACK(("Bad texture offset 0x%x\n", (int)txoffset)); + txoffset = 0; + CHECK_OFFSET(pPix, 0x1f, "texture"); + if ((txpitch & 0x1f) != 0) RADEON_FALLBACK(("Bad texture pitch 0x%x\n", (int)txpitch)); @@ -747,10 +800,12 @@ static Bool FUNC_NAME(R200TextureSetup)(PicturePtr pPict, PixmapPtr pPix, RADEON_FALLBACK(("Bad filter 0x%x\n", pPict->filter)); } - if (repeat) { - switch (pPict->repeatType) { + switch (repeatType) { case RepeatNormal: - txfilter |= R200_CLAMP_S_WRAP | R200_CLAMP_T_WRAP; + if (txformat & R200_TXFORMAT_NON_POWER2) + txfilter |= R200_CLAMP_S_CLAMP_LAST | R200_CLAMP_T_CLAMP_LAST; + else + txfilter |= R200_CLAMP_S_WRAP | R200_CLAMP_T_WRAP; break; case RepeatPad: txfilter |= R200_CLAMP_S_CLAMP_LAST | R200_CLAMP_T_CLAMP_LAST; @@ -759,12 +814,13 @@ static Bool FUNC_NAME(R200TextureSetup)(PicturePtr pPict, PixmapPtr pPix, txfilter |= R200_CLAMP_S_MIRROR | R200_CLAMP_T_MIRROR; break; case RepeatNone: - /* Nothing to do */ + /* don't set an illegal clamp mode for rect textures */ + if (txformat & R200_TXFORMAT_NON_POWER2) + txfilter |= R200_CLAMP_S_CLAMP_LAST | R200_CLAMP_T_CLAMP_LAST; break; - } } - BEGIN_ACCEL(6); + BEGIN_ACCEL_RELOC(6, 1); if (unit == 0) { OUT_ACCEL_REG(R200_PP_TXFILTER_0, txfilter); OUT_ACCEL_REG(R200_PP_TXFORMAT_0, txformat); @@ -772,7 +828,7 @@ static Bool FUNC_NAME(R200TextureSetup)(PicturePtr pPict, PixmapPtr pPix, OUT_ACCEL_REG(R200_PP_TXSIZE_0, (pPix->drawable.width - 1) | ((pPix->drawable.height - 1) << RADEON_TEX_VSIZE_SHIFT)); OUT_ACCEL_REG(R200_PP_TXPITCH_0, txpitch - 32); - OUT_ACCEL_REG(R200_PP_TXOFFSET_0, txoffset); + EMIT_READ_OFFSET(R200_PP_TXOFFSET_0, txoffset, pPix); } else { OUT_ACCEL_REG(R200_PP_TXFILTER_1, txfilter); OUT_ACCEL_REG(R200_PP_TXFORMAT_1, txformat); @@ -780,7 +836,8 @@ static Bool FUNC_NAME(R200TextureSetup)(PicturePtr pPict, PixmapPtr pPix, OUT_ACCEL_REG(R200_PP_TXSIZE_1, (pPix->drawable.width - 1) | ((pPix->drawable.height - 1) << RADEON_TEX_VSIZE_SHIFT)); OUT_ACCEL_REG(R200_PP_TXPITCH_1, txpitch - 32); - OUT_ACCEL_REG(R200_PP_TXOFFSET_1, txoffset); + EMIT_READ_OFFSET(R200_PP_TXOFFSET_1, txoffset, pPix); + /* emit a texture relocation */ } FINISH_ACCEL(); @@ -803,8 +860,12 @@ static Bool R200CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskP TRACE; + /* Check for unsupported compositing operations. */ + if (op >= sizeof(RadeonBlendOp) / sizeof(RadeonBlendOp[0])) + RADEON_FALLBACK(("Unsupported Composite op 0x%x\n", op)); + if (!pSrcPicture->pDrawable) - return FALSE; + RADEON_FALLBACK(("Solid or gradient pictures not supported yet\n")); /* r200 limit should be 2048, there are issues with 2048 * see bug 19269 @@ -870,9 +931,10 @@ static Bool FUNC_NAME(R200PrepareComposite)(int op, PicturePtr pSrcPicture, PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst) { RINFO_FROM_SCREEN(pDst->drawable.pScreen); - uint32_t dst_format, dst_offset, dst_pitch; + uint32_t dst_format, dst_pitch; uint32_t pp_cntl, blendcntl, cblend, ablend, colorpitch; int pixel_shift; + struct radeon_exa_pixmap_priv *driver_priv; ACCEL_PREAMBLE(); TRACE; @@ -883,27 +945,25 @@ static Bool FUNC_NAME(R200PrepareComposite)(int op, PicturePtr pSrcPicture, if (pDstPicture->format == PICT_a8 && RadeonBlendOp[op].dst_alpha) RADEON_FALLBACK(("Can't dst alpha blend A8\n")); - if (pMask) - info->accel_state->has_mask = TRUE; - else - info->accel_state->has_mask = FALSE; - pixel_shift = pDst->drawable.bitsPerPixel >> 4; - dst_offset = exaGetPixmapOffset(pDst) + info->fbLocation + pScrn->fbOffset; dst_pitch = exaGetPixmapPitch(pDst); colorpitch = dst_pitch >> pixel_shift; if (RADEONPixmapIsColortiled(pDst)) colorpitch |= RADEON_COLOR_TILE_ENABLE; - if ((dst_offset & 0x0f) != 0) - RADEON_FALLBACK(("Bad destination offset 0x%x\n", (int)dst_offset)); + CHECK_OFFSET(pDst, 0xf, "destination"); + if (((dst_pitch >> pixel_shift) & 0x7) != 0) RADEON_FALLBACK(("Bad destination pitch 0x%x\n", (int)dst_pitch)); if (!RADEONSetupSourceTile(pSrcPicture, pSrc, FALSE, TRUE)) return FALSE; + RADEONPrepareCompositeCS(op, pSrcPicture, pMaskPicture, pDstPicture, + pSrc, pMask, pDst); + + /* switch to 3D after doing buffer space checks as it may flush */ RADEON_SWITCH_TO_3D(); if (!FUNC_NAME(R200TextureSetup)(pSrcPicture, pSrc, 0)) @@ -918,11 +978,13 @@ static Bool FUNC_NAME(R200PrepareComposite)(int op, PicturePtr pSrcPicture, info->accel_state->is_transform[1] = FALSE; } - BEGIN_ACCEL(11); + BEGIN_ACCEL_RELOC(12, 2); OUT_ACCEL_REG(RADEON_PP_CNTL, pp_cntl); OUT_ACCEL_REG(RADEON_RB3D_CNTL, dst_format | RADEON_ALPHA_BLEND_ENABLE); - OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, dst_offset); + + EMIT_WRITE_OFFSET(RADEON_RB3D_COLOROFFSET, 0, pDst); + EMIT_COLORPITCH(RADEON_RB3D_COLORPITCH, colorpitch, pDst); OUT_ACCEL_REG(R200_SE_VTX_FMT_0, R200_VTX_XY); if (pMask) @@ -933,7 +995,7 @@ static Bool FUNC_NAME(R200PrepareComposite)(int op, PicturePtr pSrcPicture, OUT_ACCEL_REG(R200_SE_VTX_FMT_1, (2 << R200_VTX_TEX0_COMP_CNT_SHIFT)); - OUT_ACCEL_REG(RADEON_RB3D_COLORPITCH, colorpitch); + /* IN operator: Multiply src by mask components or mask alpha. * BLEND_CTL_ADD is A * B + C. @@ -978,6 +1040,10 @@ static Bool FUNC_NAME(R200PrepareComposite)(int op, PicturePtr pSrcPicture, /* Op operator. */ blendcntl = RADEONGetBlendCntl(op, pMaskPicture, pDstPicture->format); OUT_ACCEL_REG(RADEON_RB3D_BLENDCNTL, blendcntl); + + OUT_ACCEL_REG(RADEON_RE_WIDTH_HEIGHT, (((pDst->drawable.width) << RADEON_RE_WIDTH_SHIFT) | + ((pDst->drawable.height) << RADEON_RE_HEIGHT_SHIFT))); + FINISH_ACCEL(); return TRUE; @@ -991,6 +1057,11 @@ static Bool R300CheckCompositeTexture(PicturePtr pPict, int unit, Bool is_r500) { + ScreenPtr pScreen = pDstPict->pDrawable->pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + + unsigned int repeatType = pPict->repeat ? pPict->repeatType : RepeatNone; int w = pPict->pDrawable->width; int h = pPict->pDrawable->height; int i; @@ -1016,8 +1087,17 @@ static Bool R300CheckCompositeTexture(PicturePtr pPict, RADEON_FALLBACK(("Unsupported picture format 0x%x\n", (int)pPict->format)); - if (!RADEONCheckTexturePOT(pPict, unit == 0)) + if (!RADEONCheckTexturePOT(pPict, unit == 0)) { + if (info->cs) { + struct radeon_exa_pixmap_priv *driver_priv; + PixmapPtr pPix; + + pPix = RADEONGetDrawablePixmap(pPict->pDrawable); + driver_priv = exaGetPixmapDriverPrivate(pPix); + //TODOradeon_bufmgr_gem_force_gtt(driver_priv->bo); + } return FALSE; + } if (pPict->filter != PictFilterNearest && pPict->filter != PictFilterBilinear) @@ -1031,7 +1111,7 @@ static Bool R300CheckCompositeTexture(PicturePtr pPict, * matter. I have not, however, verified that the X server always does such * clipping. */ - if (pPict->transform != 0 && !pPict->repeat && PICT_FORMAT_A(pPict->format) == 0) { + if (pPict->transform != 0 && repeatType == RepeatNone && PICT_FORMAT_A(pPict->format) == 0) { if (!(((op == PictOpSrc) || (op == PictOpClear)) && (PICT_FORMAT_A(pDstPict->format) == 0))) RADEON_FALLBACK(("REPEAT_NONE unsupported for transformed xRGB source\n")); } @@ -1049,15 +1129,17 @@ static Bool FUNC_NAME(R300TextureSetup)(PicturePtr pPict, PixmapPtr pPix, int w = pPict->pDrawable->width; int h = pPict->pDrawable->height; int i, pixel_shift; + unsigned int repeatType = pPict->repeat ? pPict->repeatType : RepeatNone; + struct radeon_exa_pixmap_priv *driver_priv; ACCEL_PREAMBLE(); TRACE; txpitch = exaGetPixmapPitch(pPix); - txoffset = exaGetPixmapOffset(pPix) + info->fbLocation + pScrn->fbOffset; + txoffset = 0; + + CHECK_OFFSET(pPix, 0x1f, "texture"); - if ((txoffset & 0x1f) != 0) - RADEON_FALLBACK(("Bad texture offset 0x%x\n", (int)txoffset)); if ((txpitch & 0x1f) != 0) RADEON_FALLBACK(("Bad texture pitch 0x%x\n", (int)txpitch)); @@ -1078,7 +1160,7 @@ static Bool FUNC_NAME(R300TextureSetup)(PicturePtr pPict, PixmapPtr pPix, txformat1 = R300TexFormats[i].card_fmt; if (IS_R300_3D) { - if ((unit == 0) && info->accel_state->has_mask) + if ((unit == 0) && info->accel_state->msk_pic) txformat1 |= R300_TX_FORMAT_CACHE_HALF_REGION_0; else if (unit == 1) txformat1 |= R300_TX_FORMAT_CACHE_HALF_REGION_1; @@ -1101,36 +1183,32 @@ static Bool FUNC_NAME(R300TextureSetup)(PicturePtr pPict, PixmapPtr pPix, txfilter = (unit << R300_TX_ID_SHIFT); - if (pPict->repeat) { - switch (pPict->repeatType) { - case RepeatNormal: - if (unit != 0 || !info->accel_state->need_src_tile_x) - txfilter |= R300_TX_CLAMP_S(R300_TX_CLAMP_WRAP); - else - txfilter |= R300_TX_CLAMP_S(R300_TX_CLAMP_CLAMP_GL); - - if (unit != 0 || !info->accel_state->need_src_tile_y) - txfilter |= R300_TX_CLAMP_T(R300_TX_CLAMP_WRAP); - else - txfilter |= R300_TX_CLAMP_T(R300_TX_CLAMP_CLAMP_GL); + switch (repeatType) { + case RepeatNormal: + if (unit != 0 || !info->accel_state->need_src_tile_x) + txfilter |= R300_TX_CLAMP_S(R300_TX_CLAMP_WRAP); + else + txfilter |= R300_TX_CLAMP_S(R300_TX_CLAMP_CLAMP_GL); + + if (unit != 0 || !info->accel_state->need_src_tile_y) + txfilter |= R300_TX_CLAMP_T(R300_TX_CLAMP_WRAP); + else + txfilter |= R300_TX_CLAMP_T(R300_TX_CLAMP_CLAMP_GL); - break; - case RepeatPad: - txfilter |= R300_TX_CLAMP_S(R300_TX_CLAMP_CLAMP_LAST) | - R300_TX_CLAMP_T(R300_TX_CLAMP_CLAMP_LAST); - break; - case RepeatReflect: - txfilter |= R300_TX_CLAMP_S(R300_TX_CLAMP_MIRROR) | - R300_TX_CLAMP_T(R300_TX_CLAMP_MIRROR); - break; - case RepeatNone: - txfilter |= R300_TX_CLAMP_S(R300_TX_CLAMP_CLAMP_GL) | - R300_TX_CLAMP_T(R300_TX_CLAMP_CLAMP_GL); - break; - } - } else + break; + case RepeatPad: + txfilter |= R300_TX_CLAMP_S(R300_TX_CLAMP_CLAMP_LAST) | + R300_TX_CLAMP_T(R300_TX_CLAMP_CLAMP_LAST); + break; + case RepeatReflect: + txfilter |= R300_TX_CLAMP_S(R300_TX_CLAMP_MIRROR) | + R300_TX_CLAMP_T(R300_TX_CLAMP_MIRROR); + break; + case RepeatNone: txfilter |= R300_TX_CLAMP_S(R300_TX_CLAMP_CLAMP_GL) | - R300_TX_CLAMP_T(R300_TX_CLAMP_CLAMP_GL); + R300_TX_CLAMP_T(R300_TX_CLAMP_CLAMP_GL); + break; + } switch (pPict->filter) { case PictFilterNearest: @@ -1143,14 +1221,16 @@ static Bool FUNC_NAME(R300TextureSetup)(PicturePtr pPict, PixmapPtr pPix, RADEON_FALLBACK(("Bad filter 0x%x\n", pPict->filter)); } - BEGIN_ACCEL(pPict->repeat ? 6 : 7); + BEGIN_ACCEL_RELOC(repeatType == RepeatNone ? 7 : 6, 1); OUT_ACCEL_REG(R300_TX_FILTER0_0 + (unit * 4), txfilter); OUT_ACCEL_REG(R300_TX_FILTER1_0 + (unit * 4), 0); OUT_ACCEL_REG(R300_TX_FORMAT0_0 + (unit * 4), txformat0); OUT_ACCEL_REG(R300_TX_FORMAT1_0 + (unit * 4), txformat1); OUT_ACCEL_REG(R300_TX_FORMAT2_0 + (unit * 4), txpitch); - OUT_ACCEL_REG(R300_TX_OFFSET_0 + (unit * 4), txoffset); - if (!pPict->repeat) + + EMIT_READ_OFFSET((R300_TX_OFFSET_0 + (unit * 4)), txoffset, pPix); + + if (repeatType == RepeatNone) OUT_ACCEL_REG(R300_TX_BORDER_COLOR_0 + (unit * 4), 0); FINISH_ACCEL(); @@ -1235,6 +1315,9 @@ static Bool R300CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskP if (op >= sizeof(RadeonBlendOp) / sizeof(RadeonBlendOp[0])) RADEON_FALLBACK(("Unsupported Composite op 0x%x\n", op)); + if (!pSrcPicture->pDrawable) + RADEON_FALLBACK(("Solid or gradient pictures not supported yet\n")); + pSrcPixmap = RADEONGetDrawablePixmap(pSrcPicture->pDrawable); if (IS_R500_3D) { @@ -1245,8 +1328,8 @@ static Bool R300CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskP } else { max_tex_w = 2048; max_tex_h = 2048; - max_dst_w = 2560; - max_dst_h = 2560; + max_dst_w = 4021; + max_dst_h = 4021; } if (pSrcPixmap->drawable.width > max_tex_w || @@ -1308,25 +1391,21 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture, PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst) { RINFO_FROM_SCREEN(pDst->drawable.pScreen); - uint32_t dst_format, dst_offset, dst_pitch; + uint32_t dst_format, dst_pitch; uint32_t txenable, colorpitch; - uint32_t blendcntl; + uint32_t blendcntl, output_fmt; + uint32_t src_color, src_alpha; + uint32_t mask_color, mask_alpha; int pixel_shift; + struct radeon_exa_pixmap_priv *driver_priv; ACCEL_PREAMBLE(); - TRACE; if (!R300GetDestFormat(pDstPicture, &dst_format)) return FALSE; - if (pMask) - info->accel_state->has_mask = TRUE; - else - info->accel_state->has_mask = FALSE; - pixel_shift = pDst->drawable.bitsPerPixel >> 4; - dst_offset = exaGetPixmapOffset(pDst) + info->fbLocation + pScrn->fbOffset; dst_pitch = exaGetPixmapPitch(pDst); colorpitch = dst_pitch >> pixel_shift; @@ -1335,14 +1414,18 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture, colorpitch |= dst_format; - if ((dst_offset & 0x0f) != 0) - RADEON_FALLBACK(("Bad destination offset 0x%x\n", (int)dst_offset)); + CHECK_OFFSET(pDst, 0x0f, "destination"); + if (((dst_pitch >> pixel_shift) & 0x7) != 0) RADEON_FALLBACK(("Bad destination pitch 0x%x\n", (int)dst_pitch)); if (!RADEONSetupSourceTile(pSrcPicture, pSrc, TRUE, FALSE)) return FALSE; + RADEONPrepareCompositeCS(op, pSrcPicture, pMaskPicture, pDstPicture, + pSrc, pMask, pDst); + + /* have to execute switch after doing buffer sizing check as the latter flushes */ RADEON_SWITCH_TO_3D(); if (!FUNC_NAME(R300TextureSetup)(pSrcPicture, pSrc, 0)) @@ -1457,12 +1540,33 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture, OUT_ACCEL_REG(R300_TX_ENABLE, txenable); FINISH_ACCEL(); + /* shader output swizzling */ + switch (pDstPicture->format) { + case PICT_a8r8g8b8: + case PICT_x8r8g8b8: + default: + output_fmt = (R300_OUT_FMT_C4_8 | + 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_a8b8g8r8: + case PICT_x8b8g8r8: + output_fmt = (R300_OUT_FMT_C4_8 | + R300_OUT_FMT_C0_SEL_RED | + R300_OUT_FMT_C1_SEL_GREEN | + R300_OUT_FMT_C2_SEL_BLUE | + R300_OUT_FMT_C3_SEL_ALPHA); + break; + case PICT_a8: + output_fmt = (R300_OUT_FMT_C4_8 | + R300_OUT_FMT_C0_SEL_ALPHA); + break; + } + /* setup pixel shader */ if (IS_R300_3D) { - uint32_t output_fmt; - int src_color, src_alpha; - int mask_color, mask_alpha; - if (PICT_FORMAT_RGB(pSrcPicture->format) == 0) src_color = R300_ALU_RGB_0_0; else @@ -1473,45 +1577,22 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture, else src_alpha = R300_ALU_ALPHA_SRC0_A; - if (pMask && pMaskPicture->componentAlpha) { - if (RadeonBlendOp[op].src_alpha) { - if (PICT_FORMAT_A(pSrcPicture->format) == 0) { - src_color = R300_ALU_RGB_1_0; - src_alpha = R300_ALU_ALPHA_1_0; - } else { - src_color = R300_ALU_RGB_SRC0_AAA; - src_alpha = R300_ALU_ALPHA_SRC0_A; - } - + if (pMask) { + if (pMaskPicture->componentAlpha) { + if (RadeonBlendOp[op].src_alpha) { + if (PICT_FORMAT_A(pSrcPicture->format) == 0) + src_color = R300_ALU_RGB_1_0; + else + src_color = R300_ALU_RGB_SRC0_AAA; + } else + src_color = R300_ALU_RGB_SRC0_RGB; mask_color = R300_ALU_RGB_SRC1_RGB; - - if (PICT_FORMAT_A(pMaskPicture->format) == 0) - mask_alpha = R300_ALU_ALPHA_1_0; - else - mask_alpha = R300_ALU_ALPHA_SRC1_A; - } else { - src_color = R300_ALU_RGB_SRC0_RGB; - - if (PICT_FORMAT_A(pSrcPicture->format) == 0) - src_alpha = R300_ALU_ALPHA_1_0; - else - src_alpha = R300_ALU_ALPHA_SRC0_A; - - mask_color = R300_ALU_RGB_SRC1_RGB; - if (PICT_FORMAT_A(pMaskPicture->format) == 0) - mask_alpha = R300_ALU_ALPHA_1_0; + mask_color = R300_ALU_RGB_1_0; else - mask_alpha = R300_ALU_ALPHA_SRC1_A; - + mask_color = R300_ALU_RGB_SRC1_AAA; } - } else if (pMask) { - if (PICT_FORMAT_A(pMaskPicture->format) == 0) - mask_color = R300_ALU_RGB_1_0; - else - mask_color = R300_ALU_RGB_SRC1_AAA; - if (PICT_FORMAT_A(pMaskPicture->format) == 0) mask_alpha = R300_ALU_ALPHA_1_0; else @@ -1521,32 +1602,6 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture, mask_alpha = R300_ALU_ALPHA_1_0; } - /* shader output swizzling */ - switch (pDstPicture->format) { - case PICT_a8r8g8b8: - case PICT_x8r8g8b8: - default: - output_fmt = (R300_OUT_FMT_C4_8 | - 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_a8b8g8r8: - case PICT_x8b8g8r8: - output_fmt = (R300_OUT_FMT_C4_8 | - R300_OUT_FMT_C0_SEL_RED | - R300_OUT_FMT_C1_SEL_GREEN | - R300_OUT_FMT_C2_SEL_BLUE | - R300_OUT_FMT_C3_SEL_ALPHA); - break; - case PICT_a8: - output_fmt = (R300_OUT_FMT_C4_8 | - R300_OUT_FMT_C0_SEL_ALPHA); - break; - } - - /* setup the rasterizer, load FS */ if (pMask) { BEGIN_ACCEL(16); @@ -1690,10 +1745,6 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture, R300_ALU_ALPHA_CLAMP)); FINISH_ACCEL(); } else { - uint32_t output_fmt; - uint32_t src_color, src_alpha; - uint32_t mask_color, mask_alpha; - if (PICT_FORMAT_RGB(pSrcPicture->format) == 0) src_color = (R500_ALU_RGB_R_SWIZ_A_0 | R500_ALU_RGB_G_SWIZ_A_0 | @@ -1708,59 +1759,35 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture, else src_alpha = R500_ALPHA_SWIZ_A_A; - if (pMask && pMaskPicture->componentAlpha) { - if (RadeonBlendOp[op].src_alpha) { - if (PICT_FORMAT_A(pSrcPicture->format) == 0) { - src_color = (R500_ALU_RGB_R_SWIZ_A_1 | - R500_ALU_RGB_G_SWIZ_A_1 | - R500_ALU_RGB_B_SWIZ_A_1); - src_alpha = R500_ALPHA_SWIZ_A_1; - } else { - src_color = (R500_ALU_RGB_R_SWIZ_A_A | - R500_ALU_RGB_G_SWIZ_A_A | - R500_ALU_RGB_B_SWIZ_A_A); - src_alpha = R500_ALPHA_SWIZ_A_A; - } + if (pMask) { + if (pMaskPicture->componentAlpha) { + if (RadeonBlendOp[op].src_alpha) { + if (PICT_FORMAT_A(pSrcPicture->format) == 0) + src_color = (R500_ALU_RGB_R_SWIZ_A_1 | + R500_ALU_RGB_G_SWIZ_A_1 | + R500_ALU_RGB_B_SWIZ_A_1); + else + src_color = (R500_ALU_RGB_R_SWIZ_A_A | + R500_ALU_RGB_G_SWIZ_A_A | + R500_ALU_RGB_B_SWIZ_A_A); + } else + src_color = (R500_ALU_RGB_R_SWIZ_A_R | + R500_ALU_RGB_G_SWIZ_A_G | + R500_ALU_RGB_B_SWIZ_A_B); mask_color = (R500_ALU_RGB_R_SWIZ_B_R | R500_ALU_RGB_G_SWIZ_B_G | R500_ALU_RGB_B_SWIZ_B_B); - - if (PICT_FORMAT_A(pMaskPicture->format) == 0) - mask_alpha = R500_ALPHA_SWIZ_B_1; - else - mask_alpha = R500_ALPHA_SWIZ_B_A; - } else { - src_color = (R500_ALU_RGB_R_SWIZ_A_R | - R500_ALU_RGB_G_SWIZ_A_G | - R500_ALU_RGB_B_SWIZ_A_B); - - if (PICT_FORMAT_A(pSrcPicture->format) == 0) - src_alpha = R500_ALPHA_SWIZ_A_1; - else - src_alpha = R500_ALPHA_SWIZ_A_A; - - mask_color = (R500_ALU_RGB_R_SWIZ_B_R | - R500_ALU_RGB_G_SWIZ_B_G | - R500_ALU_RGB_B_SWIZ_B_B); - if (PICT_FORMAT_A(pMaskPicture->format) == 0) - mask_alpha = R500_ALPHA_SWIZ_B_1; + mask_color = (R500_ALU_RGB_R_SWIZ_B_1 | + R500_ALU_RGB_G_SWIZ_B_1 | + R500_ALU_RGB_B_SWIZ_B_1); else - mask_alpha = R500_ALPHA_SWIZ_B_A; - + mask_color = (R500_ALU_RGB_R_SWIZ_B_A | + R500_ALU_RGB_G_SWIZ_B_A | + R500_ALU_RGB_B_SWIZ_B_A); } - } else if (pMask) { - if (PICT_FORMAT_A(pMaskPicture->format) == 0) - mask_color = (R500_ALU_RGB_R_SWIZ_B_1 | - R500_ALU_RGB_G_SWIZ_B_1 | - R500_ALU_RGB_B_SWIZ_B_1); - else - mask_color = (R500_ALU_RGB_R_SWIZ_B_A | - R500_ALU_RGB_G_SWIZ_B_A | - R500_ALU_RGB_B_SWIZ_B_A); - if (PICT_FORMAT_A(pMaskPicture->format) == 0) mask_alpha = R500_ALPHA_SWIZ_B_1; else @@ -1772,31 +1799,6 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture, mask_alpha = R500_ALPHA_SWIZ_B_1; } - /* shader output swizzling */ - switch (pDstPicture->format) { - case PICT_a8r8g8b8: - case PICT_x8r8g8b8: - default: - output_fmt = (R300_OUT_FMT_C4_8 | - 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_a8b8g8r8: - case PICT_x8b8g8r8: - output_fmt = (R300_OUT_FMT_C4_8 | - R300_OUT_FMT_C0_SEL_RED | - R300_OUT_FMT_C1_SEL_GREEN | - R300_OUT_FMT_C2_SEL_BLUE | - R300_OUT_FMT_C3_SEL_ALPHA); - break; - case PICT_a8: - output_fmt = (R300_OUT_FMT_C4_8 | - R300_OUT_FMT_C0_SEL_ALPHA); - break; - } - BEGIN_ACCEL(7); if (pMask) { /* 4 components: 2 for tex0, 2 for tex1 */ @@ -1997,20 +1999,24 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture, /* Clear out scissoring */ BEGIN_ACCEL(2); - if (IS_R300_3D) + if (IS_R300_3D) { OUT_ACCEL_REG(R300_SC_SCISSOR0, ((1440 << R300_SCISSOR_X_SHIFT) | (1440 << R300_SCISSOR_Y_SHIFT))); - else + OUT_ACCEL_REG(R300_SC_SCISSOR1, (((pDst->drawable.width + 1440 - 1) << R300_SCISSOR_X_SHIFT) | + ((pDst->drawable.height + 1440 - 1) << R300_SCISSOR_Y_SHIFT))); + + } else { 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))); + OUT_ACCEL_REG(R300_SC_SCISSOR1, (((pDst->drawable.width - 1) << R300_SCISSOR_X_SHIFT) | + ((pDst->drawable.height - 1) << R300_SCISSOR_Y_SHIFT))); + } FINISH_ACCEL(); - BEGIN_ACCEL(3); - - OUT_ACCEL_REG(R300_RB3D_COLOROFFSET0, dst_offset); - OUT_ACCEL_REG(R300_RB3D_COLORPITCH0, colorpitch); + + BEGIN_ACCEL_RELOC(3, 2); + EMIT_WRITE_OFFSET(R300_RB3D_COLOROFFSET0, 0, pDst); + EMIT_COLORPITCH(R300_RB3D_COLORPITCH0, colorpitch, pDst); blendcntl = RADEONGetBlendCntl(op, pMaskPicture, pDstPicture->format); OUT_ACCEL_REG(R300_RB3D_BLENDCNTL, blendcntl | R300_ALPHA_BLEND_ENABLE | R300_READ_ENABLE); @@ -2018,7 +2024,7 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture, FINISH_ACCEL(); BEGIN_ACCEL(1); - if (info->accel_state->has_mask) + if (pMask) OUT_ACCEL_REG(R300_VAP_VTX_SIZE, 6); else OUT_ACCEL_REG(R300_VAP_VTX_SIZE, 4); @@ -2027,6 +2033,25 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture, return TRUE; } +static void FUNC_NAME(RadeonDoneComposite)(PixmapPtr pDst) +{ + RINFO_FROM_SCREEN(pDst->drawable.pScreen); + ACCEL_PREAMBLE(); + + ENTER_DRAW(0); + + if (IS_R300_3D || IS_R500_3D) { + BEGIN_ACCEL(3); + OUT_ACCEL_REG(R300_SC_CLIP_RULE, 0xAAAA); + OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_RB3D_DC_FLUSH_ALL); + } else + BEGIN_ACCEL(1); + OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN); + FINISH_ACCEL(); + + LEAVE_DRAW(0); +} + #ifdef ACCEL_CP @@ -2101,6 +2126,20 @@ static void FUNC_NAME(RadeonCompositeTile)(ScrnInfoPtr pScrn, /* ErrorF("RadeonComposite (%d,%d) (%d,%d) (%d,%d) (%d,%d)\n", srcX, srcY, maskX, maskY,dstX, dstY, w, h); */ +#if defined(ACCEL_CP) && defined(XF86DRM_MODE) + if (info->cs && CS_FULL(info->cs)) { + FUNC_NAME(RadeonDoneComposite)(info->accel_state->dst_pix); + radeon_cs_flush_indirect(pScrn); + info->accel_state->exa->PrepareComposite(info->accel_state->composite_op, + info->accel_state->src_pic, + info->accel_state->msk_pic, + info->accel_state->dst_pic, + info->accel_state->src_pix, + info->accel_state->msk_pix, + info->accel_state->dst_pix); + } +#endif + srcTopLeft.x = IntToxFixed(srcX); srcTopLeft.y = IntToxFixed(srcY); srcTopRight.x = IntToxFixed(srcX + w); @@ -2119,7 +2158,7 @@ static void FUNC_NAME(RadeonCompositeTile)(ScrnInfoPtr pScrn, } } - if (info->accel_state->has_mask) { + if (info->accel_state->msk_pic) { maskTopLeft.x = IntToxFixed(maskX); maskTopLeft.y = IntToxFixed(maskY); maskTopRight.x = IntToxFixed(maskX + w); @@ -2150,7 +2189,7 @@ static void FUNC_NAME(RadeonCompositeTile)(ScrnInfoPtr pScrn, BEGIN_RING(3 * vtx_count + 3); OUT_RING(CP_PACKET3(RADEON_CP_PACKET3_3D_DRAW_IMMD, 3 * vtx_count + 1)); - if (info->accel_state->has_mask) + if (info->accel_state->msk_pic) OUT_RING(RADEON_CP_VC_FRMT_XY | RADEON_CP_VC_FRMT_ST0 | RADEON_CP_VC_FRMT_ST1); @@ -2200,7 +2239,7 @@ static void FUNC_NAME(RadeonCompositeTile)(ScrnInfoPtr pScrn, #endif - if (info->accel_state->has_mask) { + if (info->accel_state->msk_pic) { if (IS_R300_3D || IS_R500_3D) { VTX_OUT_MASK((float)dstX, (float)dstY, xFixedToFloat(srcTopLeft.x) / info->accel_state->texW[0], xFixedToFloat(srcTopLeft.y) / info->accel_state->texH[0], @@ -2308,24 +2347,5 @@ static void FUNC_NAME(RadeonComposite)(PixmapPtr pDst, } } -static void FUNC_NAME(RadeonDoneComposite)(PixmapPtr pDst) -{ - RINFO_FROM_SCREEN(pDst->drawable.pScreen); - ACCEL_PREAMBLE(); - - ENTER_DRAW(0); - - if (IS_R300_3D || IS_R500_3D) { - BEGIN_ACCEL(3); - OUT_ACCEL_REG(R300_SC_CLIP_RULE, 0xAAAA); - OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_RB3D_DC_FLUSH_ALL); - } else - BEGIN_ACCEL(1); - OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN); - FINISH_ACCEL(); - - LEAVE_DRAW(0); -} - #undef ONLY_ONCE #undef FUNC_NAME diff --git a/src/radeon_hwmc.c b/src/radeon_hwmc.c new file mode 100644 index 0000000..28d349e --- /dev/null +++ b/src/radeon_hwmc.c @@ -0,0 +1,221 @@ +/* + * Copyright 2008 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Author: Cooper Yuan <cooper.yuan@amd.com> + * + */ +#include <string.h> + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "compiler.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "xf86fbman.h" +#include "regionstr.h" +#include "xf86drm.h" +#include "xf86xv.h" +#include <X11/extensions/Xv.h> +#include <X11/extensions/XvMC.h> +#include "xaa.h" +#include "xaalocal.h" +#include "dixstruct.h" +#include "fourcc.h" + +#define _RADEON_XVMC_SERVER_ +#include "r500_hwmc.h" + +struct radeon_hwmc_driver *hwmc_driver_ptr; + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) + +enum +{ + SURFACE_TYPE_MPEG2_MPML = FOURCC_XVMC, + SURFACE_TYPE_MPEG1_MPML, + SURFACE_TYPE_MAX +}; + +static XF86MCSurfaceInfoRec radeon_YV12_mpg2_surface = +{ + SURFACE_TYPE_MPEG2_MPML, + XVMC_CHROMA_FORMAT_420, + 0, + 720, + 576, + 720, + 576, + XVMC_MPEG_2, + /* XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING,*/ + 0, + /* &yv12_subpicture_list*/ + NULL, +}; + +static XF86MCSurfaceInfoRec radeon_YV12_mpg1_surface = +{ + SURFACE_TYPE_MPEG1_MPML, + XVMC_CHROMA_FORMAT_420, + 0, + 720, + 576, + 720, + 576, + XVMC_MPEG_1, + /* XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING,*/ + 0, + /* &yv12_subpicture_list*/ + NULL, +}; + +static XF86MCSurfaceInfoPtr ppSI[2] = +{ + (XF86MCSurfaceInfoPtr)&radeon_YV12_mpg2_surface, + (XF86MCSurfaceInfoPtr)&radeon_YV12_mpg1_surface +}; + +/* set global current driver for xvmc */ +static Bool intel_xvmc_set_driver(struct intel_xvmc_driver *d) +{ + if (xvmc_driver_ptr) + { + ErrorF("XvMC driver already set!\n"); + return FALSE; + } else + xvmc_driver = d; + return TRUE; +} + +/* check chip type and load xvmc driver */ +/* This must be first called! */ +Bool intel_xvmc_probe(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + Bool ret = FALSE; + + /* Disable XvMC on DRI2 for now */ + if (pI830->directRenderingType == DRI_DRI2) { + pI830->XvMCEnabled = FALSE; + return FALSE; + } + + if (!pI830->XvMCEnabled) + return FALSE; + + if (IS_I9XX(pI830)) { + if (IS_I915(pI830)) + ret = intel_xvmc_set_driver(&i915_xvmc_driver); + else + ret = intel_xvmc_set_driver(&i965_xvmc_driver); + } else { + ErrorF("Your chipset doesn't support XvMC.\n"); + return FALSE; + } + return TRUE; +} + +void intel_xvmc_finish(ScrnInfoPtr pScrn) +{ + if (!xvmc_driver) + return; + (*xvmc_driver->fini)(pScrn); +} + +Bool intel_xvmc_driver_init(ScreenPtr pScreen, XF86VideoAdaptorPtr xv_adaptor) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + + if (!xvmc_driver) { + ErrorF("Failed to probe XvMC driver.\n"); + return FALSE; + } + + if (!(*xvmc_driver->init)(pScrn, xv_adaptor)) { + ErrorF("XvMC driver initialize failed.\n"); + return FALSE; + } + return TRUE; +} + +Bool intel_xvmc_screen_init(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + DRIInfoPtr pDRIInfo = pI830->pDRIInfo; + + if (!xvmc_driver) + return FALSE; + + if (xf86XvMCScreenInit(pScreen, 1, &xvmc_driver->adaptor)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[XvMC] %s driver initialized.\n", + xvmc_driver->name); + } else { + intel_xvmc_finish(pScrn); + pI830->XvMCEnabled = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[XvMC] Failed to initialize XvMC.\n"); + return FALSE; + } + + xf86XvMCRegisterDRInfo(pScreen, INTEL_XVMC_LIBNAME, + pDRIInfo->busIdString, + INTEL_XVMC_MAJOR, INTEL_XVMC_MINOR, INTEL_XVMC_PATCHLEVEL); + return TRUE; +} + +Bool intel_xvmc_init_batch(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + int size = KB(64); + + if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC] batch buffer", + &(xvmc_driver->batch), size, + ALIGN_BOTH_ENDS)) + return FALSE; + + if (drmAddMap(pI830->drmSubFD, + (drm_handle_t)(xvmc_driver->batch->offset+pI830->LinearAddr), + xvmc_driver->batch->size, DRM_AGP, 0, + &xvmc_driver->batch_handle) < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[drm] drmAddMap(batchbuffer_handle) failed!\n"); + return FALSE; + } + return TRUE; +} + +void intel_xvmc_fini_batch(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + + if (xvmc_driver->batch_handle) { + drmRmMap(pI830->drmSubFD, xvmc_driver->batch_handle); + xvmc_driver->batch_handle = 0; + } + if (xvmc_driver->batch) { + i830_free_memory(pScrn, xvmc_driver->batch); + xvmc_driver->batch = NULL; + } +} + diff --git a/src/radeon_hwmc.h b/src/radeon_hwmc.h new file mode 100644 index 0000000..db4fdaf --- /dev/null +++ b/src/radeon_hwmc.h @@ -0,0 +1,67 @@ +/* + * Copyright 2008 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Author: Cooper Yuan <cooper.yuan@amd.com> + * + */ + +#ifndef RADEON_HWMC_H +#define RADEON_HWMC_H + +#define FOURCC_XVMC (('C' << 24) + ('M' << 16) + ('V' << 8) + 'X') +#define XVMC_R500_MPEG2_MC 0x1 + +struct hwmc_buffer +{ + drm_handle_t handle; + unsigned long offset; + unsigned long size; + unsigned long bus_addr; +}; + +struct radeon_xvmc_common { + unsigned int type; + unsigned int sarea_size; + struct hwmc_buffer batchbuffer; +}; + +#ifdef _RADEON_XVMC_SERVER_ +#include <xf86xvmc.h> +struct radeon_hwmc_driver +{ + char *name; + XF86MCAdaptorPtr adaptor; + unsigned int flag; +// r500_memory *batch; + drm_handle_t batch_handle; + + /* more items for xvmv surface manage? */ + Bool (*init)(ScrnInfoPtr, XF86VideoAdaptorPtr); + void (*fini)(ScrnInfoPtr); + void* devPrivate; +}; + +extern struct radeon_hwmc_driver *hwmc_driver_ptr; +extern struct radeon_hwmc_driver *r500_hwmc_driver_ptr; +#endif + +#endif
\ No newline at end of file diff --git a/src/radeon_legacy_memory.c b/src/radeon_legacy_memory.c index 861fd97..02b95ed 100644 --- a/src/radeon_legacy_memory.c +++ b/src/radeon_legacy_memory.c @@ -21,6 +21,20 @@ radeon_legacy_allocate_memory(ScrnInfoPtr pScrn, RADEONInfoPtr info = RADEONPTR(pScrn); uint32_t offset = 0; +#ifdef XF86DRM_MODE + if (info->cs) { + struct radeon_bo *video_bo; + + video_bo = radeon_bo_open(info->bufmgr, 0, size, 4096, 0, 0); + + *mem_struct = video_bo; + + if (!video_bo) + return 0; + + return (uint32_t)-1; + } +#endif #ifdef USE_EXA if (info->useEXA) { ExaOffscreenArea *area = *mem_struct; @@ -94,6 +108,14 @@ radeon_legacy_free_memory(ScrnInfoPtr pScrn, void *mem_struct) { RADEONInfoPtr info = RADEONPTR(pScrn); + +#ifdef XF86DRM_MODE + if (info->cs) { + struct radeon_bo *bo = mem_struct; + radeon_bo_unref(bo); + return; + } +#endif #ifdef USE_EXA ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; diff --git a/src/radeon_macros.h b/src/radeon_macros.h index 8575884..26d9825 100644 --- a/src/radeon_macros.h +++ b/src/radeon_macros.h @@ -160,4 +160,50 @@ do { \ #define INPCIE_P(pScrn, addr) R600INPCIE_PORT(pScrn, addr) #define OUTPCIE_P(pScrn, addr, val) R600OUTPCIE_PORT(pScrn, addr, val) +#define BEGIN_ACCEL_RELOC(n, r) do { \ + int _nqw = (n) + (info->cs ? (r) : 0); \ + BEGIN_ACCEL(_nqw); \ + } while (0) + +#define CHECK_OFFSET(pPix, mask, type) do { \ + if (!info->cs) { \ + uint32_t _pix_offset = radeonGetPixmapOffset(pPix); \ + if ((_pix_offset & mask) != 0) \ + RADEON_FALLBACK(("Bad %s offset 0x%x\n", type, (int)_pix_offset)); \ + } \ + } while(0) + +#define EMIT_OFFSET(reg, value, pPix, rd, wd) do { \ + if (info->cs) { \ + driver_priv = exaGetPixmapDriverPrivate(pPix); \ + OUT_ACCEL_REG((reg), (value)); \ + OUT_RELOC(driver_priv->bo, (rd), (wd)); \ + } else { \ + uint32_t _pix_offset; \ + _pix_offset = radeonGetPixmapOffset(pPix); \ + OUT_ACCEL_REG((reg), _pix_offset | value); \ + } \ + } while(0) + +#define EMIT_READ_OFFSET(reg, value, pPix) EMIT_OFFSET(reg, value, pPix, (RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT), 0) +#define EMIT_WRITE_OFFSET(reg, value, pPix) EMIT_OFFSET(reg, value, pPix, 0, RADEON_GEM_DOMAIN_VRAM) + +#define OUT_TEXTURE_REG(reg, offset, bo) do { \ + if (info->cs) { \ + OUT_ACCEL_REG((reg), (offset)); \ + OUT_RELOC((bo), RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0); \ + } else { \ + OUT_ACCEL_REG((reg), (offset) + info->fbLocation + pScrn->fbOffset);} \ + } while(0) + +#define EMIT_COLORPITCH(reg, value, pPix) do { \ + if (info->cs) { \ + driver_priv = exaGetPixmapDriverPrivate(pPix); \ + OUT_ACCEL_REG((reg), value); \ + OUT_RELOC(driver_priv->bo, 0, RADEON_GEM_DOMAIN_VRAM); \ + } else { \ + OUT_ACCEL_REG((reg), value); \ + } \ +}while(0) + #endif diff --git a/src/radeon_output.c b/src/radeon_output.c index e453cc2..30f6f3b 100644 --- a/src/radeon_output.c +++ b/src/radeon_output.c @@ -209,6 +209,12 @@ radeon_set_active_device(xf86OutputPtr output) } } +static Bool +monitor_is_digital(xf86MonPtr MonInfo) +{ + return (MonInfo->rawData[0x14] & 0x80) != 0; +} + static RADEONMonitorType radeon_ddc_connected(xf86OutputPtr output) { @@ -234,9 +240,8 @@ radeon_ddc_connected(xf86OutputPtr output) break; case CONNECTOR_DVI_D: case CONNECTOR_HDMI_TYPE_A: - case CONNECTOR_HDMI_TYPE_B: if (radeon_output->shared_ddc) { - if (MonInfo->rawData[0x14] & 0x80) /* if it's digital and DVI/HDMI/etc. */ + if (monitor_is_digital(MonInfo)) MonType = MT_DFP; else MonType = MT_NONE; @@ -249,8 +254,10 @@ radeon_ddc_connected(xf86OutputPtr output) * or AUXCH. */ MonType = MT_DFP; + break; + case CONNECTOR_HDMI_TYPE_B: case CONNECTOR_DVI_I: - if (MonInfo->rawData[0x14] & 0x80) /* if it's digital and DVI */ + if (monitor_is_digital(MonInfo)) MonType = MT_DFP; else MonType = MT_CRT; @@ -259,7 +266,7 @@ radeon_ddc_connected(xf86OutputPtr output) case CONNECTOR_DVI_A: default: if (radeon_output->shared_ddc) { - if (MonInfo->rawData[0x14] & 0x80) /* if it's digital and VGA */ + if (monitor_is_digital(MonInfo)) MonType = MT_NONE; else MonType = MT_CRT; @@ -274,9 +281,6 @@ radeon_ddc_connected(xf86OutputPtr output) } else MonType = MT_NONE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Output: %s, Detected Monitor Type: %d\n", output->name, MonType); - return MonType; } @@ -1006,6 +1010,8 @@ radeon_detect(xf86OutputPtr output) } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Output: %s, Detected Monitor Type: %d\n", output->name, radeon_output->MonType); if (output->MonInfo) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID data from the display on output: %s ----------------------\n", output->name); @@ -2720,12 +2726,12 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn) RADEONConnectorType conntype = info->BiosConnector[i].ConnectorType; if ((conntype == CONNECTOR_DVI_D) || (conntype == CONNECTOR_DVI_I) || - (conntype == CONNECTOR_DVI_A)) { + (conntype == CONNECTOR_DVI_A) || + (conntype == CONNECTOR_HDMI_TYPE_B)) { num_dvi++; } else if (conntype == CONNECTOR_VGA) { num_vga++; - } else if ((conntype == CONNECTOR_HDMI_TYPE_A) || - (conntype == CONNECTOR_HDMI_TYPE_B)) { + } else if (conntype == CONNECTOR_HDMI_TYPE_A) { num_hdmi++; } else if (conntype == CONNECTOR_DISPLAY_PORT) { num_dp++; @@ -2755,14 +2761,18 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn) radeon_output->linkb = info->BiosConnector[i].linkb; radeon_output->connector_id = info->BiosConnector[i].connector_object; + /* Technically HDMI-B is a glorfied DL DVI so the bios is correct, + * but this can be confusing to users when it comes to output names, + * so call it DVI + */ if ((conntype == CONNECTOR_DVI_D) || (conntype == CONNECTOR_DVI_I) || - (conntype == CONNECTOR_DVI_A)) { + (conntype == CONNECTOR_DVI_A) || + (conntype == CONNECTOR_HDMI_TYPE_B)) { output = RADEONOutputCreate(pScrn, "DVI-%d", --num_dvi); } else if (conntype == CONNECTOR_VGA) { output = RADEONOutputCreate(pScrn, "VGA-%d", --num_vga); - } else if ((conntype == CONNECTOR_HDMI_TYPE_A) || - (conntype == CONNECTOR_HDMI_TYPE_B)) { + } else if (conntype == CONNECTOR_HDMI_TYPE_A) { output = RADEONOutputCreate(pScrn, "HDMI-%d", --num_hdmi); } else if (conntype == CONNECTOR_DISPLAY_PORT) { output = RADEONOutputCreate(pScrn, "DisplayPort-%d", --num_dp); diff --git a/src/radeon_pci_chipset_gen.h b/src/radeon_pci_chipset_gen.h index 7765ee6..1b85dcc 100644 --- a/src/radeon_pci_chipset_gen.h +++ b/src/radeon_pci_chipset_gen.h @@ -274,15 +274,26 @@ PciChipsets RADEONPciChipsets[] = { { PCI_CHIP_RV770_946B, PCI_CHIP_RV770_946B, RES_SHARED_VGA }, { PCI_CHIP_RV770_947A, PCI_CHIP_RV770_947A, RES_SHARED_VGA }, { PCI_CHIP_RV770_947B, PCI_CHIP_RV770_947B, RES_SHARED_VGA }, + { PCI_CHIP_RV730_9480, PCI_CHIP_RV730_9480, RES_SHARED_VGA }, { PCI_CHIP_RV730_9487, PCI_CHIP_RV730_9487, RES_SHARED_VGA }, + { PCI_CHIP_RV730_9488, PCI_CHIP_RV730_9488, RES_SHARED_VGA }, { PCI_CHIP_RV730_9489, PCI_CHIP_RV730_9489, RES_SHARED_VGA }, { PCI_CHIP_RV730_948F, PCI_CHIP_RV730_948F, RES_SHARED_VGA }, { PCI_CHIP_RV730_9490, PCI_CHIP_RV730_9490, RES_SHARED_VGA }, { PCI_CHIP_RV730_9491, PCI_CHIP_RV730_9491, RES_SHARED_VGA }, + { PCI_CHIP_RV730_9495, PCI_CHIP_RV730_9495, RES_SHARED_VGA }, { PCI_CHIP_RV730_9498, PCI_CHIP_RV730_9498, RES_SHARED_VGA }, { PCI_CHIP_RV730_949C, PCI_CHIP_RV730_949C, RES_SHARED_VGA }, { PCI_CHIP_RV730_949E, PCI_CHIP_RV730_949E, RES_SHARED_VGA }, { PCI_CHIP_RV730_949F, PCI_CHIP_RV730_949F, RES_SHARED_VGA }, + { PCI_CHIP_RV740_94A0, PCI_CHIP_RV740_94A0, RES_SHARED_VGA }, + { PCI_CHIP_RV740_94A1, PCI_CHIP_RV740_94A1, RES_SHARED_VGA }, + { PCI_CHIP_RV740_94A3, PCI_CHIP_RV740_94A3, RES_SHARED_VGA }, + { PCI_CHIP_RV740_94B1, PCI_CHIP_RV740_94B1, RES_SHARED_VGA }, + { PCI_CHIP_RV740_94B3, PCI_CHIP_RV740_94B3, RES_SHARED_VGA }, + { PCI_CHIP_RV740_94B4, PCI_CHIP_RV740_94B4, RES_SHARED_VGA }, + { PCI_CHIP_RV740_94B5, PCI_CHIP_RV740_94B5, RES_SHARED_VGA }, + { PCI_CHIP_RV740_94B9, PCI_CHIP_RV740_94B9, RES_SHARED_VGA }, { PCI_CHIP_RV610_94C0, PCI_CHIP_RV610_94C0, RES_SHARED_VGA }, { PCI_CHIP_RV610_94C1, PCI_CHIP_RV610_94C1, RES_SHARED_VGA }, { PCI_CHIP_RV610_94C3, PCI_CHIP_RV610_94C3, RES_SHARED_VGA }, @@ -315,6 +326,7 @@ PciChipsets RADEONPciChipsets[] = { { PCI_CHIP_RV710_9552, PCI_CHIP_RV710_9552, RES_SHARED_VGA }, { PCI_CHIP_RV710_9553, PCI_CHIP_RV710_9553, RES_SHARED_VGA }, { PCI_CHIP_RV710_9555, PCI_CHIP_RV710_9555, RES_SHARED_VGA }, + { PCI_CHIP_RV710_9557, PCI_CHIP_RV710_9557, RES_SHARED_VGA }, { PCI_CHIP_RV630_9580, PCI_CHIP_RV630_9580, RES_SHARED_VGA }, { PCI_CHIP_RV630_9581, PCI_CHIP_RV630_9581, RES_SHARED_VGA }, { PCI_CHIP_RV630_9583, PCI_CHIP_RV630_9583, RES_SHARED_VGA }, diff --git a/src/radeon_pci_device_match_gen.h b/src/radeon_pci_device_match_gen.h index 397cf63..64127bd 100644 --- a/src/radeon_pci_device_match_gen.h +++ b/src/radeon_pci_device_match_gen.h @@ -274,15 +274,26 @@ static const struct pci_id_match radeon_device_match[] = { ATI_DEVICE_MATCH( PCI_CHIP_RV770_946B, 0 ), ATI_DEVICE_MATCH( PCI_CHIP_RV770_947A, 0 ), ATI_DEVICE_MATCH( PCI_CHIP_RV770_947B, 0 ), + ATI_DEVICE_MATCH( PCI_CHIP_RV730_9480, 0 ), ATI_DEVICE_MATCH( PCI_CHIP_RV730_9487, 0 ), + ATI_DEVICE_MATCH( PCI_CHIP_RV730_9488, 0 ), ATI_DEVICE_MATCH( PCI_CHIP_RV730_9489, 0 ), ATI_DEVICE_MATCH( PCI_CHIP_RV730_948F, 0 ), ATI_DEVICE_MATCH( PCI_CHIP_RV730_9490, 0 ), ATI_DEVICE_MATCH( PCI_CHIP_RV730_9491, 0 ), + ATI_DEVICE_MATCH( PCI_CHIP_RV730_9495, 0 ), ATI_DEVICE_MATCH( PCI_CHIP_RV730_9498, 0 ), ATI_DEVICE_MATCH( PCI_CHIP_RV730_949C, 0 ), ATI_DEVICE_MATCH( PCI_CHIP_RV730_949E, 0 ), ATI_DEVICE_MATCH( PCI_CHIP_RV730_949F, 0 ), + ATI_DEVICE_MATCH( PCI_CHIP_RV740_94A0, 0 ), + ATI_DEVICE_MATCH( PCI_CHIP_RV740_94A1, 0 ), + ATI_DEVICE_MATCH( PCI_CHIP_RV740_94A3, 0 ), + ATI_DEVICE_MATCH( PCI_CHIP_RV740_94B1, 0 ), + ATI_DEVICE_MATCH( PCI_CHIP_RV740_94B3, 0 ), + ATI_DEVICE_MATCH( PCI_CHIP_RV740_94B4, 0 ), + ATI_DEVICE_MATCH( PCI_CHIP_RV740_94B5, 0 ), + ATI_DEVICE_MATCH( PCI_CHIP_RV740_94B9, 0 ), ATI_DEVICE_MATCH( PCI_CHIP_RV610_94C0, 0 ), ATI_DEVICE_MATCH( PCI_CHIP_RV610_94C1, 0 ), ATI_DEVICE_MATCH( PCI_CHIP_RV610_94C3, 0 ), @@ -315,6 +326,7 @@ static const struct pci_id_match radeon_device_match[] = { ATI_DEVICE_MATCH( PCI_CHIP_RV710_9552, 0 ), ATI_DEVICE_MATCH( PCI_CHIP_RV710_9553, 0 ), ATI_DEVICE_MATCH( PCI_CHIP_RV710_9555, 0 ), + ATI_DEVICE_MATCH( PCI_CHIP_RV710_9557, 0 ), ATI_DEVICE_MATCH( PCI_CHIP_RV630_9580, 0 ), ATI_DEVICE_MATCH( PCI_CHIP_RV630_9581, 0 ), ATI_DEVICE_MATCH( PCI_CHIP_RV630_9583, 0 ), diff --git a/src/radeon_pm.c b/src/radeon_pm.c index 131a9fd..fe8f214 100644 --- a/src/radeon_pm.c +++ b/src/radeon_pm.c @@ -38,6 +38,8 @@ #include "radeon_macros.h" #include "radeon_atombios.h" +#include "ati_pciids_gen.h" + /* 10 khz */ static uint32_t calc_eng_mem_clock(ScrnInfoPtr pScrn, uint32_t req_clock, @@ -629,6 +631,15 @@ RADEONSetPCIELanes(ScrnInfoPtr pScrn, int lanes) if (info->IsIGP) return; + /* don't change lanes on multi-gpu cards for now */ + if ((info->Chipset == PCI_CHIP_RV770_9441) || + (info->Chipset == PCI_CHIP_RV770_9443) || + (info->Chipset == PCI_CHIP_RV770_944B) || + (info->Chipset == PCI_CHIP_RV670_9506) || + (info->Chipset == PCI_CHIP_RV670_9509) || + (info->Chipset == PCI_CHIP_RV670_950F)) + return; + RADEONWaitForIdleMMIO(pScrn); switch (lanes) { diff --git a/src/radeon_probe.c b/src/radeon_probe.c index 041bab6..42e7259 100644 --- a/src/radeon_probe.c +++ b/src/radeon_probe.c @@ -36,6 +36,7 @@ * Authors: * Kevin E. Martin <martin@xfree86.org> * Rickard E. Faith <faith@valinux.com> + * KMS support - Dave Airlie <airlied@redhat.com> */ #include "radeon_probe.h" @@ -44,12 +45,20 @@ #include "atipcirename.h" #include "xf86.h" +#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6 #include "xf86Resources.h" +#endif + +#ifdef XF86DRM_MODE +#include "xf86drmMode.h" +#include "dri.h" +#endif #include "radeon_chipset_gen.h" #include "radeon_pci_chipset_gen.h" + #ifdef XSERVER_LIBPCIACCESS #include "radeon_pci_device_match_gen.h" #endif @@ -76,11 +85,42 @@ RADEONIdentify(int flags) RADEONChipsets); } + +#ifdef XF86DRM_MODE +static Bool radeon_kernel_mode_enabled(ScrnInfoPtr pScrn, struct pci_device *pci_dev) +{ + char *busIdString; + int ret; + + if (!xf86LoaderCheckSymbol("DRICreatePCIBusID")) { + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0, + "[KMS] No DRICreatePCIBusID symbol, no kernel modesetting.\n"); + return FALSE; + } + + busIdString = DRICreatePCIBusID(pci_dev); + ret = drmCheckModesettingSupported(busIdString); + xfree(busIdString); + if (ret) { + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0, + "[KMS] drm report modesetting isn't supported.\n"); + return FALSE; + } + + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0, + "[KMS] Kernel modesetting enabled.\n"); + return TRUE; +} +#else +#define radeon_kernel_mode_enabled(x, y) FALSE +#endif + static Bool -radeon_get_scrninfo(int entity_num) +radeon_get_scrninfo(int entity_num, void *pci_dev) { ScrnInfoPtr pScrn = NULL; EntityInfoPtr pEnt; + int kms = 0; pScrn = xf86ConfigPciEntity(pScrn, 0, entity_num, RADEONPciChipsets, NULL, @@ -89,6 +129,11 @@ radeon_get_scrninfo(int entity_num) if (!pScrn) return FALSE; + if (pci_dev) { + if (radeon_kernel_mode_enabled(pScrn, pci_dev)) + kms = 1; + } + pScrn->driverVersion = RADEON_VERSION_CURRENT; pScrn->driverName = RADEON_DRIVER_NAME; pScrn->name = RADEON_NAME; @@ -97,14 +142,29 @@ radeon_get_scrninfo(int entity_num) #else pScrn->Probe = RADEONProbe; #endif - pScrn->PreInit = RADEONPreInit; - pScrn->ScreenInit = RADEONScreenInit; - pScrn->SwitchMode = RADEONSwitchMode; - pScrn->AdjustFrame = RADEONAdjustFrame; - pScrn->EnterVT = RADEONEnterVT; - pScrn->LeaveVT = RADEONLeaveVT; - pScrn->FreeScreen = RADEONFreeScreen; - pScrn->ValidMode = RADEONValidMode; + +#ifdef XF86DRM_MODE + if (kms == 1) { + pScrn->PreInit = RADEONPreInit_KMS; + pScrn->ScreenInit = RADEONScreenInit_KMS; + pScrn->SwitchMode = RADEONSwitchMode_KMS; + pScrn->AdjustFrame = RADEONAdjustFrame_KMS; + pScrn->EnterVT = RADEONEnterVT_KMS; + pScrn->LeaveVT = RADEONLeaveVT_KMS; + pScrn->FreeScreen = RADEONFreeScreen_KMS; + pScrn->ValidMode = RADEONValidMode; + } else +#endif + { + pScrn->PreInit = RADEONPreInit; + pScrn->ScreenInit = RADEONScreenInit; + pScrn->SwitchMode = RADEONSwitchMode; + pScrn->AdjustFrame = RADEONAdjustFrame; + pScrn->EnterVT = RADEONEnterVT; + pScrn->LeaveVT = RADEONLeaveVT; + pScrn->FreeScreen = RADEONFreeScreen; + pScrn->ValidMode = RADEONValidMode; + } pEnt = xf86GetEntityInfo(entity_num); @@ -178,7 +238,7 @@ RADEONProbe(DriverPtr drv, int flags) foundScreen = TRUE; } else { for (i = 0; i < numUsed; i++) { - if (radeon_get_scrninfo(usedChips[i])) + if (radeon_get_scrninfo(usedChips[i], NULL)) foundScreen = TRUE; } } @@ -199,7 +259,7 @@ radeon_pci_probe( intptr_t match_data ) { - return radeon_get_scrninfo(entity_num); + return radeon_get_scrninfo(entity_num, (void *)device); } #endif /* XSERVER_LIBPCIACCESS */ diff --git a/src/radeon_probe.h b/src/radeon_probe.h index 31709e8..9cac15c 100644 --- a/src/radeon_probe.h +++ b/src/radeon_probe.h @@ -615,6 +615,7 @@ typedef struct RADEONSaveRec SavedReg; /* Original (text) mode */ void *MMIO; /* Map of MMIO region */ + int fd; /* for sharing across zaphod heads */ } RADEONEntRec, *RADEONEntPtr; /* radeon_probe.c */ @@ -636,4 +637,14 @@ extern ModeStatus RADEONValidMode(int, DisplayModePtr, Bool, int); extern const OptionInfoRec *RADEONOptionsWeak(void); +#ifdef XF86DRM_MODE +extern Bool RADEONPreInit_KMS(ScrnInfoPtr, int); +extern Bool RADEONScreenInit_KMS(int, ScreenPtr, int, char **); +extern Bool RADEONSwitchMode_KMS(int, DisplayModePtr, int); +extern void RADEONAdjustFrame_KMS(int, int, int, int); +extern Bool RADEONEnterVT_KMS(int, int); +extern void RADEONLeaveVT_KMS(int, int); +extern void RADEONFreeScreen_KMS(int scrnIndex, int flags); +#endif + #endif /* _RADEON_PROBE_H_ */ diff --git a/src/radeon_reg.h b/src/radeon_reg.h index 8da513b..5467286 100644 --- a/src/radeon_reg.h +++ b/src/radeon_reg.h @@ -103,28 +103,6 @@ #define RADEON_ATTRDR 0x03c1 /* VGA */ #define RADEON_ATTRDW 0x03c0 /* VGA */ #define RADEON_ATTRX 0x03c0 /* VGA */ -#define RADEON_AUX_SC_CNTL 0x1660 -# define RADEON_AUX1_SC_EN (1 << 0) -# define RADEON_AUX1_SC_MODE_OR (0 << 1) -# define RADEON_AUX1_SC_MODE_NAND (1 << 1) -# define RADEON_AUX2_SC_EN (1 << 2) -# define RADEON_AUX2_SC_MODE_OR (0 << 3) -# define RADEON_AUX2_SC_MODE_NAND (1 << 3) -# define RADEON_AUX3_SC_EN (1 << 4) -# define RADEON_AUX3_SC_MODE_OR (0 << 5) -# define RADEON_AUX3_SC_MODE_NAND (1 << 5) -#define RADEON_AUX1_SC_BOTTOM 0x1670 -#define RADEON_AUX1_SC_LEFT 0x1664 -#define RADEON_AUX1_SC_RIGHT 0x1668 -#define RADEON_AUX1_SC_TOP 0x166c -#define RADEON_AUX2_SC_BOTTOM 0x1680 -#define RADEON_AUX2_SC_LEFT 0x1674 -#define RADEON_AUX2_SC_RIGHT 0x1678 -#define RADEON_AUX2_SC_TOP 0x167c -#define RADEON_AUX3_SC_BOTTOM 0x1690 -#define RADEON_AUX3_SC_LEFT 0x1684 -#define RADEON_AUX3_SC_RIGHT 0x1688 -#define RADEON_AUX3_SC_TOP 0x168c #define RADEON_AUX_WINDOW_HORZ_CNTL 0x02d8 #define RADEON_AUX_WINDOW_VERT_CNTL 0x02dc @@ -445,8 +423,9 @@ # 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_GUI_TRIG_VLINE_END_SHIFT 16 +# define RADEON_CRTC_GUI_TRIG_VLINE_STALL (1 << 30) #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) @@ -903,7 +882,7 @@ # define RADEON_FP2_DVO_EN (1 << 25) # define RADEON_FP2_DVO_RATE_SEL_SDR (1 << 26) # define R200_FP2_DVO_RATE_SEL_SDR (1 << 27) -# define R300_FP2_DVO_CLOCK_MODE_SINGLE (1 << 28) +# define R200_FP2_DVO_CLOCK_MODE_SINGLE (1 << 28) # define R300_FP2_DVO_DUAL_CHANNEL_EN (1 << 29) #define RADEON_FP_H_SYNC_STRT_WID 0x02c4 #define RADEON_FP_H2_SYNC_STRT_WID 0x03c4 @@ -3548,6 +3527,11 @@ # define R520_MEM_NUM_CHANNELS_SHIFT 24 # define R520_MC_CHANNEL_SIZE (1 << 23) +#define RS780_MC_INDEX 0x28f8 +# define RS780_MC_INDEX_MASK 0x1ff +# define RS780_MC_INDEX_WR_EN (1 << 9) +#define RS780_MC_DATA 0x28fc + #define R600_RAMCFG 0x2408 # define R600_CHANSIZE (1 << 7) # define R600_CHANSIZE_OVERRIDE (1 << 10) diff --git a/src/radeon_textured_video.c b/src/radeon_textured_video.c index ab743be..932759b 100644 --- a/src/radeon_textured_video.c +++ b/src/radeon_textured_video.c @@ -50,7 +50,7 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv); extern Bool R600CopyToVRAM(ScrnInfoPtr pScrn, char *src, int src_pitch, - uint32_t dst_pitch, uint32_t dst_mc_addr, uint32_t dst_height, int bpp, + uint32_t dst_pitch, uint32_t dst_mc_addr, uint32_t dst_width, uint32_t dst_height, int bpp, int x, int y, int w, int h); #define IMAGE_MAX_WIDTH 2048 @@ -142,6 +142,7 @@ static REF_TRANSFORM trans[2] = #define BEGIN_ACCEL(n) RADEONWaitForFifo(pScrn, (n)) #define OUT_ACCEL_REG(reg, val) OUTREG(reg, val) #define OUT_ACCEL_REG_F(reg, val) OUTREG(reg, F_TO_DW(val)) +#define OUT_RELOC(x, read, write) do {} while(0) #define FINISH_ACCEL() #include "radeon_textured_videofuncs.c" @@ -151,6 +152,7 @@ static REF_TRANSFORM trans[2] = #undef BEGIN_ACCEL #undef OUT_ACCEL_REG #undef OUT_ACCEL_REG_F +#undef OUT_RELOC #undef FINISH_ACCEL #ifdef XF86DRI @@ -164,6 +166,7 @@ static REF_TRANSFORM trans[2] = #define OUT_ACCEL_REG_F(reg, val) OUT_ACCEL_REG(reg, F_TO_DW(val)) #define FINISH_ACCEL() ADVANCE_RING() #define OUT_RING_F(x) OUT_RING(F_TO_DW(x)) +#define OUT_RELOC(x, read, write) OUT_RING_RELOC(x, read, write) #include "radeon_textured_videofuncs.c" @@ -200,7 +203,7 @@ R600CopyData( R600CopyToVRAM(pScrn, (char *)src, srcPitch, - dstPitch, dst_mc_addr, h, cpp * 8, + dstPitch, dst_mc_addr, w, h, cpp * 8, 0, 0, w, h); } else { if (srcPitch == dstPitch) @@ -323,16 +326,16 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn, size * 2, 64); if (pPriv->video_offset == 0) return BadAlloc; + + if (info->cs) + pPriv->src_bo = pPriv->video_memory; } /* Bicubic filter loading */ - if (pPriv->bicubic_memory == NULL && pPriv->bicubic_enabled) { - pPriv->bicubic_offset = radeon_legacy_allocate_memory(pScrn, - &pPriv->bicubic_memory, - sizeof(bicubic_tex_512), 64); - pPriv->bicubic_src_offset = pPriv->bicubic_offset + info->fbLocation + pScrn->fbOffset; - if (pPriv->bicubic_offset == 0) - pPriv->bicubic_enabled = FALSE; + if (pPriv->bicubic_enabled) { + if (info->bicubic_offset == 0) + pPriv->bicubic_enabled = FALSE; + pPriv->bicubic_src_offset = info->bicubic_offset; } if (pDraw->type == DRAWABLE_WINDOW) @@ -361,8 +364,17 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn, top = (y1 >> 16) & ~1; nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top; - pPriv->src_offset = pPriv->video_offset + info->fbLocation + pScrn->fbOffset; - pPriv->src_addr = (uint8_t *)(info->FB + pPriv->video_offset); + pPriv->src_offset = pPriv->video_offset; + if (info->cs) { + int ret; + ret = radeon_bo_map(pPriv->src_bo, 1); + if (ret) + return BadAlloc; + + pPriv->src_addr = pPriv->src_bo->ptr; + } else { + pPriv->src_addr = (uint8_t *)(info->FB + pPriv->video_offset); + } pPriv->src_pitch = dstPitch; pPriv->planeu_offset = dstPitch * dst_height; @@ -429,13 +441,6 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn, break; } - /* Upload bicubic filter tex */ - if (pPriv->bicubic_enabled) { - if (info->ChipFamily < CHIP_FAMILY_R600) - RADEONCopyData(pScrn, (uint8_t *)bicubic_tex_512, - (uint8_t *)(info->FB + pPriv->bicubic_offset), 1024, 1024, 1, 512, 2); - } - /* update cliplist */ if (!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) { REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes); @@ -453,6 +458,8 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn, pPriv->w = width; pPriv->h = height; + if (info->cs) + radeon_bo_unmap(pPriv->src_bo); #ifdef XF86DRI if (info->directRenderingEnabled) { if (IS_R600_3D) @@ -663,6 +670,54 @@ RADEONSetTexPortAttribute(ScrnInfoPtr pScrn, return Success; } +Bool radeon_load_bicubic_texture(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + /* Bicubic filter loading */ + info->bicubic_offset = radeon_legacy_allocate_memory(pScrn, + &info->bicubic_memory, + sizeof(bicubic_tex_512), 64); + if (info->bicubic_offset == 0) + return FALSE; + + if (info->cs) + info->bicubic_bo = info->bicubic_memory; + + /* Upload bicubic filter tex */ + if (info->ChipFamily < CHIP_FAMILY_R600) { + uint8_t *bicubic_addr; + int ret; + if (info->cs) { + ret = radeon_bo_map(info->bicubic_bo, 1); + if (ret) + return FALSE; + + bicubic_addr = info->bicubic_bo->ptr; + } else + bicubic_addr = (uint8_t *)(info->FB + info->bicubic_offset); + + RADEONCopyData(pScrn, (uint8_t *)bicubic_tex_512, bicubic_addr, 1024, 1024, 1, 512, 2); + if (info->cs) + radeon_bo_unmap(info->bicubic_bo); + } + return TRUE; +} + +#if 0 +/* XXX */ +static void radeon_unload_bicubic_texture(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + if (info->bicubic_memory != NULL) { + radeon_legacy_free_memory(pScrn, info->bicubic_memory); + info->bicubic_memory = NULL; + } + +} +#endif + XF86VideoAdaptorPtr RADEONSetupImageTexturedVideo(ScreenPtr pScreen) { @@ -760,6 +815,9 @@ RADEONSetupImageTexturedVideo(ScreenPtr pScreen) adapt->pPortPrivates[i].ptr = (pointer) (pPriv); } + if (IS_R500_3D || IS_R300_3D) + radeon_load_bicubic_texture(pScrn); + return adapt; } diff --git a/src/radeon_textured_videofuncs.c b/src/radeon_textured_videofuncs.c index 227e19a..f069d8f 100644 --- a/src/radeon_textured_videofuncs.c +++ b/src/radeon_textured_videofuncs.c @@ -92,8 +92,9 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv { RADEONInfoPtr info = RADEONPTR(pScrn); PixmapPtr pPixmap = pPriv->pPixmap; - uint32_t txformat, txsize, txpitch; - uint32_t dst_offset, dst_pitch, dst_format; + struct radeon_exa_pixmap_priv *driver_priv; + uint32_t txformat, txsize, txpitch, txoffset; + uint32_t dst_pitch, dst_format; uint32_t colorpitch; Bool isplanar = FALSE; int dstxoff, dstyoff, pixel_shift, vtx_count; @@ -101,18 +102,37 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv int nBox = REGION_NUM_RECTS(&pPriv->clip); ACCEL_PREAMBLE(); +#ifdef XF86DRM_MODE + if (info->cs) { + int ret; + + radeon_cs_space_reset_bos(info->cs); + radeon_cs_space_add_persistent_bo(info->cs, pPriv->src_bo, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); + + if (pPriv->bicubic_enabled) + radeon_cs_space_add_persistent_bo(info->cs, info->bicubic_bo, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); + + driver_priv = exaGetPixmapDriverPrivate(pPixmap); + radeon_cs_space_add_persistent_bo(info->cs, driver_priv->bo, 0, RADEON_GEM_DOMAIN_VRAM); + + ret = radeon_cs_space_check(info->cs); + if (ret) { + ErrorF("Not enough RAM to hw accel xv operation\n"); + return; + } + } +#endif + pixel_shift = pPixmap->drawable.bitsPerPixel >> 4; + #ifdef USE_EXA if (info->useEXA) { - dst_offset = exaGetPixmapOffset(pPixmap) + info->fbLocation + pScrn->fbOffset; dst_pitch = exaGetPixmapPitch(pPixmap); } else #endif { - dst_offset = (pPixmap->devPrivate.ptr - info->FB) + - info->fbLocation + pScrn->fbOffset; - dst_pitch = pPixmap->devKind; + dst_pitch = pPixmap->devKind; } #ifdef COMPOSITE @@ -175,11 +195,13 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv if (RADEONTilingEnabled(pScrn, pPixmap)) colorpitch |= RADEON_COLOR_TILE_ENABLE; - BEGIN_ACCEL(4); + txoffset = info->cs ? 0 : pPriv->src_offset; + + BEGIN_ACCEL_RELOC(4,2); OUT_ACCEL_REG(RADEON_RB3D_CNTL, dst_format); - OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, dst_offset); - OUT_ACCEL_REG(RADEON_RB3D_COLORPITCH, colorpitch); + EMIT_WRITE_OFFSET(RADEON_RB3D_COLOROFFSET, 0, pPixmap); + EMIT_COLORPITCH(RADEON_RB3D_COLORPITCH, colorpitch, pPixmap); OUT_ACCEL_REG(RADEON_RB3D_BLENDCNTL, RADEON_SRC_BLEND_GL_ONE | RADEON_DST_BLEND_GL_ZERO); @@ -196,7 +218,7 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv txpitch = ((pPriv->src_pitch >> 1) + 63) & ~63; txpitch -= 32; - BEGIN_ACCEL(23); + BEGIN_ACCEL_RELOC(23, 3); OUT_ACCEL_REG(RADEON_SE_VTX_FMT, (RADEON_SE_VTX_FMT_XY | RADEON_SE_VTX_FMT_ST0 | @@ -215,7 +237,7 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv RADEON_CLAMP_T_CLAMP_LAST | RADEON_YUV_TO_RGB); OUT_ACCEL_REG(RADEON_PP_TXFORMAT_0, txformat | RADEON_TXFORMAT_ST_ROUTE_STQ0); - OUT_ACCEL_REG(RADEON_PP_TXOFFSET_0, pPriv->src_offset); + OUT_TEXTURE_REG(RADEON_PP_TXOFFSET_0, txoffset, pPriv->src_bo); OUT_ACCEL_REG(RADEON_PP_TXCBLEND_0, RADEON_COLOR_ARG_A_ZERO | RADEON_COLOR_ARG_B_ZERO | @@ -242,7 +264,7 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv RADEON_CLAMP_S_CLAMP_LAST | RADEON_CLAMP_T_CLAMP_LAST); OUT_ACCEL_REG(RADEON_PP_TXFORMAT_1, txformat | RADEON_TXFORMAT_ST_ROUTE_STQ1); - OUT_ACCEL_REG(RADEON_PP_TXOFFSET_1, pPriv->src_offset + pPriv->planeu_offset); + OUT_TEXTURE_REG(RADEON_PP_TXOFFSET_1, txoffset + pPriv->planeu_offset, pPriv->src_bo); OUT_ACCEL_REG(RADEON_PP_TXCBLEND_1, RADEON_COLOR_ARG_A_ZERO | RADEON_COLOR_ARG_B_ZERO | @@ -266,7 +288,7 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv RADEON_CLAMP_S_CLAMP_LAST | RADEON_CLAMP_T_CLAMP_LAST); OUT_ACCEL_REG(RADEON_PP_TXFORMAT_2, txformat | RADEON_TXFORMAT_ST_ROUTE_STQ1); - OUT_ACCEL_REG(RADEON_PP_TXOFFSET_2, pPriv->src_offset + pPriv->planev_offset); + OUT_TEXTURE_REG(RADEON_PP_TXOFFSET_2, txoffset + pPriv->planev_offset, pPriv->src_bo); OUT_ACCEL_REG(RADEON_PP_TXCBLEND_2, RADEON_COLOR_ARG_A_ZERO | RADEON_COLOR_ARG_B_ZERO | @@ -285,7 +307,7 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv FINISH_ACCEL(); } else { vtx_count = 4; - BEGIN_ACCEL(9); + BEGIN_ACCEL_RELOC(9, 1); OUT_ACCEL_REG(RADEON_SE_VTX_FMT, (RADEON_SE_VTX_FMT_XY | RADEON_SE_VTX_FMT_ST0)); @@ -299,7 +321,7 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv RADEON_CLAMP_T_CLAMP_LAST | RADEON_YUV_TO_RGB); OUT_ACCEL_REG(RADEON_PP_TXFORMAT_0, txformat | RADEON_TXFORMAT_ST_ROUTE_STQ0); - OUT_ACCEL_REG(RADEON_PP_TXOFFSET_0, pPriv->src_offset); + OUT_TEXTURE_REG(RADEON_PP_TXOFFSET_0, txoffset, pPriv->src_bo); OUT_ACCEL_REG(RADEON_PP_TXCBLEND_0, RADEON_COLOR_ARG_A_ZERO | RADEON_COLOR_ARG_B_ZERO | @@ -321,6 +343,12 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv FINISH_ACCEL(); } + BEGIN_ACCEL(2); + OUT_ACCEL_REG(RADEON_RE_TOP_LEFT, 0); + OUT_ACCEL_REG(RADEON_RE_WIDTH_HEIGHT, (((pPixmap->drawable.width) << RADEON_RE_WIDTH_SHIFT) | + ((pPixmap->drawable.height) << RADEON_RE_HEIGHT_SHIFT))); + FINISH_ACCEL(); + if (pPriv->vsync) { xf86CrtcPtr crtc = radeon_xv_pick_best_crtc(pScrn, pPriv->drw_x, @@ -442,9 +470,10 @@ FUNC_NAME(R200DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) { RADEONInfoPtr info = RADEONPTR(pScrn); PixmapPtr pPixmap = pPriv->pPixmap; + struct radeon_exa_pixmap_priv *driver_priv; uint32_t txformat; - uint32_t txfilter, txsize, txpitch; - uint32_t dst_offset, dst_pitch, dst_format; + uint32_t txfilter, txsize, txpitch, txoffset; + uint32_t dst_pitch, dst_format; uint32_t colorpitch; Bool isplanar = FALSE; int dstxoff, dstyoff, pixel_shift, vtx_count; @@ -460,22 +489,39 @@ FUNC_NAME(R200DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) int ref = pPriv->transform_index; float ucscale = 0.25, vcscale = 0.25; Bool needux8 = FALSE, needvx8 = FALSE; - ACCEL_PREAMBLE(); +#ifdef XF86DRM_MODE + if (info->cs) { + int ret; + + radeon_cs_space_reset_bos(info->cs); + radeon_cs_space_add_persistent_bo(info->cs, pPriv->src_bo, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); + + if (pPriv->bicubic_enabled) + radeon_cs_space_add_persistent_bo(info->cs, info->bicubic_bo, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); + + driver_priv = exaGetPixmapDriverPrivate(pPixmap); + radeon_cs_space_add_persistent_bo(info->cs, driver_priv->bo, 0, RADEON_GEM_DOMAIN_VRAM); + + ret = radeon_cs_space_check(info->cs); + if (ret) { + ErrorF("Not enough RAM to hw accel xv operation\n"); + return; + } + } +#endif + pixel_shift = pPixmap->drawable.bitsPerPixel >> 4; #ifdef USE_EXA if (info->useEXA) { - dst_offset = exaGetPixmapOffset(pPixmap) + info->fbLocation + pScrn->fbOffset; dst_pitch = exaGetPixmapPitch(pPixmap); } else #endif - { - dst_offset = (pPixmap->devPrivate.ptr - info->FB) + - info->fbLocation + pScrn->fbOffset; - dst_pitch = pPixmap->devKind; - } + { + dst_pitch = pPixmap->devKind; + } #ifdef COMPOSITE dstxoff = -pPixmap->screen_x + pPixmap->drawable.x; @@ -537,11 +583,11 @@ FUNC_NAME(R200DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) if (RADEONTilingEnabled(pScrn, pPixmap)) colorpitch |= RADEON_COLOR_TILE_ENABLE; - BEGIN_ACCEL(4); + BEGIN_ACCEL_RELOC(4,2); OUT_ACCEL_REG(RADEON_RB3D_CNTL, dst_format); - OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, dst_offset); - OUT_ACCEL_REG(RADEON_RB3D_COLORPITCH, colorpitch); + EMIT_WRITE_OFFSET(RADEON_RB3D_COLOROFFSET, 0, pPixmap); + EMIT_COLORPITCH(RADEON_RB3D_COLORPITCH, colorpitch, pPixmap); OUT_ACCEL_REG(RADEON_RB3D_BLENDCNTL, RADEON_SRC_BLEND_GL_ONE | RADEON_DST_BLEND_GL_ZERO); @@ -584,6 +630,8 @@ FUNC_NAME(R200DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) vcscale = 0.125; } + txoffset = info->cs ? 0 : pPriv->src_offset; + if (isplanar) { /* need 2 texcoord sets (even though they are identical) due to denormalization! hw apparently can't premultiply @@ -595,7 +643,7 @@ FUNC_NAME(R200DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) txpitch = ((pPriv->src_pitch >> 1) + 63) & ~63; txpitch -= 32; - BEGIN_ACCEL(36); + BEGIN_ACCEL_RELOC(36, 3); OUT_ACCEL_REG(RADEON_PP_CNTL, RADEON_TEX_0_ENABLE | RADEON_TEX_1_ENABLE | RADEON_TEX_2_ENABLE | @@ -615,21 +663,21 @@ FUNC_NAME(R200DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) (pPriv->w - 1) | ((pPriv->h - 1) << RADEON_TEX_VSIZE_SHIFT)); OUT_ACCEL_REG(R200_PP_TXPITCH_0, pPriv->src_pitch - 32); - OUT_ACCEL_REG(R200_PP_TXOFFSET_0, pPriv->src_offset); + OUT_TEXTURE_REG(R200_PP_TXOFFSET_0, txoffset, pPriv->src_bo); OUT_ACCEL_REG(R200_PP_TXFILTER_1, txfilter); OUT_ACCEL_REG(R200_PP_TXFORMAT_1, txformat | R200_TXFORMAT_ST_ROUTE_STQ1); OUT_ACCEL_REG(R200_PP_TXFORMAT_X_1, 0); OUT_ACCEL_REG(R200_PP_TXSIZE_1, txsize); OUT_ACCEL_REG(R200_PP_TXPITCH_1, txpitch); - OUT_ACCEL_REG(R200_PP_TXOFFSET_1, pPriv->src_offset + pPriv->planeu_offset); + OUT_TEXTURE_REG(R200_PP_TXOFFSET_1, txoffset + pPriv->planeu_offset, pPriv->src_bo); OUT_ACCEL_REG(R200_PP_TXFILTER_2, txfilter); OUT_ACCEL_REG(R200_PP_TXFORMAT_2, txformat | R200_TXFORMAT_ST_ROUTE_STQ1); OUT_ACCEL_REG(R200_PP_TXFORMAT_X_2, 0); OUT_ACCEL_REG(R200_PP_TXSIZE_2, txsize); OUT_ACCEL_REG(R200_PP_TXPITCH_2, txpitch); - OUT_ACCEL_REG(R200_PP_TXOFFSET_2, pPriv->src_offset + pPriv->planev_offset); + OUT_TEXTURE_REG(R200_PP_TXOFFSET_2, txoffset + pPriv->planev_offset, pPriv->src_bo); /* similar to r300 code. Note the big problem is that hardware constants * are 8 bits only, representing 0.0-1.0. We can get that up (using bias @@ -753,7 +801,7 @@ FUNC_NAME(R200DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) } else { vtx_count = 4; - BEGIN_ACCEL(24); + BEGIN_ACCEL_RELOC(24, 1); OUT_ACCEL_REG(RADEON_PP_CNTL, RADEON_TEX_0_ENABLE | @@ -771,7 +819,7 @@ FUNC_NAME(R200DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) (pPriv->w - 1) | ((pPriv->h - 1) << RADEON_TEX_VSIZE_SHIFT)); OUT_ACCEL_REG(R200_PP_TXPITCH_0, pPriv->src_pitch - 32); - OUT_ACCEL_REG(R200_PP_TXOFFSET_0, pPriv->src_offset); + OUT_TEXTURE_REG(R200_PP_TXOFFSET_0, txoffset, pPriv->src_bo); /* MAD temp1 / 2, const0.a * 2, temp0.ggg, -const0.rgb */ OUT_ACCEL_REG(R200_PP_TXCBLEND_0, @@ -856,6 +904,12 @@ FUNC_NAME(R200DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) FINISH_ACCEL(); } + BEGIN_ACCEL(2); + OUT_ACCEL_REG(RADEON_RE_TOP_LEFT, 0); + OUT_ACCEL_REG(RADEON_RE_WIDTH_HEIGHT, (((pPixmap->drawable.width) << RADEON_RE_WIDTH_SHIFT) | + ((pPixmap->drawable.height) << RADEON_RE_HEIGHT_SHIFT))); + FINISH_ACCEL(); + if (pPriv->vsync) { xf86CrtcPtr crtc = radeon_xv_pick_best_crtc(pScrn, pPriv->drw_x, @@ -968,9 +1022,10 @@ FUNC_NAME(R300DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) { RADEONInfoPtr info = RADEONPTR(pScrn); PixmapPtr pPixmap = pPriv->pPixmap; + struct radeon_exa_pixmap_priv *driver_priv; uint32_t txfilter, txformat0, txformat1, txoffset, txpitch; - uint32_t dst_offset, dst_pitch, dst_format; - uint32_t txenable, colorpitch; + uint32_t dst_pitch, dst_format; + uint32_t txenable, colorpitch, bicubic_offset; uint32_t output_fmt; Bool isplanar = FALSE; int dstxoff, dstyoff, pixel_shift, vtx_count; @@ -978,19 +1033,37 @@ FUNC_NAME(R300DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) int nBox = REGION_NUM_RECTS(&pPriv->clip); ACCEL_PREAMBLE(); +#ifdef XF86DRM_MODE + if (info->cs) { + int ret; + + radeon_cs_space_reset_bos(info->cs); + radeon_cs_space_add_persistent_bo(info->cs, pPriv->src_bo, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); + + if (pPriv->bicubic_enabled) + radeon_cs_space_add_persistent_bo(info->cs, info->bicubic_bo, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); + + driver_priv = exaGetPixmapDriverPrivate(pPixmap); + radeon_cs_space_add_persistent_bo(info->cs, driver_priv->bo, 0, RADEON_GEM_DOMAIN_VRAM); + + ret = radeon_cs_space_check(info->cs); + if (ret) { + ErrorF("Not enough RAM to hw accel xv operation\n"); + return; + } + } +#endif + pixel_shift = pPixmap->drawable.bitsPerPixel >> 4; #ifdef USE_EXA if (info->useEXA) { - dst_offset = exaGetPixmapOffset(pPixmap) + info->fbLocation + pScrn->fbOffset; dst_pitch = exaGetPixmapPitch(pPixmap); } else #endif - { - dst_offset = (pPixmap->devPrivate.ptr - info->FB) + - info->fbLocation + pScrn->fbOffset; - dst_pitch = pPixmap->devKind; - } + { + dst_pitch = pPixmap->devKind; + } #ifdef COMPOSITE dstxoff = -pPixmap->screen_x + pPixmap->drawable.x; @@ -1083,9 +1156,9 @@ FUNC_NAME(R300DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) R300_TX_MIN_FILTER_LINEAR | (0 << R300_TX_ID_SHIFT)); - txoffset = pPriv->src_offset; + txoffset = info->cs ? 0 : pPriv->src_offset; - BEGIN_ACCEL(6); + BEGIN_ACCEL_RELOC(6, 1); OUT_ACCEL_REG(R300_TX_FILTER0_0, txfilter); OUT_ACCEL_REG(R300_TX_FILTER1_0, 0); OUT_ACCEL_REG(R300_TX_FORMAT0_0, txformat0); @@ -1094,7 +1167,7 @@ FUNC_NAME(R300DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) else OUT_ACCEL_REG(R300_TX_FORMAT1_0, txformat1); OUT_ACCEL_REG(R300_TX_FORMAT2_0, txpitch); - OUT_ACCEL_REG(R300_TX_OFFSET_0, txoffset); + OUT_TEXTURE_REG(R300_TX_OFFSET_0, txoffset, pPriv->src_bo); FINISH_ACCEL(); txenable = R300_TEX_0_ENABLE; @@ -1110,19 +1183,19 @@ FUNC_NAME(R300DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) R300_TX_MIN_FILTER_LINEAR | R300_TX_MAG_FILTER_LINEAR); - BEGIN_ACCEL(12); + BEGIN_ACCEL_RELOC(12, 2); OUT_ACCEL_REG(R300_TX_FILTER0_1, txfilter | (1 << R300_TX_ID_SHIFT)); OUT_ACCEL_REG(R300_TX_FILTER1_1, 0); OUT_ACCEL_REG(R300_TX_FORMAT0_1, txformat0); OUT_ACCEL_REG(R300_TX_FORMAT1_1, R300_TX_FORMAT_X8 | R300_TX_FORMAT_CACHE_FOURTH_REGION_2); OUT_ACCEL_REG(R300_TX_FORMAT2_1, txpitch); - OUT_ACCEL_REG(R300_TX_OFFSET_1, txoffset + pPriv->planeu_offset); + OUT_TEXTURE_REG(R300_TX_OFFSET_1, txoffset + pPriv->planeu_offset, pPriv->src_bo); OUT_ACCEL_REG(R300_TX_FILTER0_2, txfilter | (2 << R300_TX_ID_SHIFT)); OUT_ACCEL_REG(R300_TX_FILTER1_2, 0); OUT_ACCEL_REG(R300_TX_FORMAT0_2, txformat0); OUT_ACCEL_REG(R300_TX_FORMAT1_2, R300_TX_FORMAT_X8 | R300_TX_FORMAT_CACHE_FOURTH_REGION_3); OUT_ACCEL_REG(R300_TX_FORMAT2_2, txpitch); - OUT_ACCEL_REG(R300_TX_OFFSET_2, txoffset + pPriv->planev_offset); + OUT_TEXTURE_REG(R300_TX_OFFSET_2, txoffset + pPriv->planev_offset, pPriv->src_bo); FINISH_ACCEL(); txenable |= R300_TEX_1_ENABLE | R300_TEX_2_ENABLE; } @@ -1143,13 +1216,18 @@ FUNC_NAME(R300DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) R300_TX_MAG_FILTER_NEAREST | (1 << R300_TX_ID_SHIFT)); - BEGIN_ACCEL(6); + if (info->cs) + bicubic_offset = 0; + else + bicubic_offset = pPriv->bicubic_src_offset; + + BEGIN_ACCEL_RELOC(6, 1); OUT_ACCEL_REG(R300_TX_FILTER0_1, txfilter); OUT_ACCEL_REG(R300_TX_FILTER1_1, 0); OUT_ACCEL_REG(R300_TX_FORMAT0_1, txformat0); OUT_ACCEL_REG(R300_TX_FORMAT1_1, txformat1); OUT_ACCEL_REG(R300_TX_FORMAT2_1, txpitch); - OUT_ACCEL_REG(R300_TX_OFFSET_1, pPriv->bicubic_src_offset); + OUT_TEXTURE_REG(R300_TX_OFFSET_1, bicubic_offset, info->bicubic_bo); FINISH_ACCEL(); /* Enable tex 1 */ @@ -2193,12 +2271,12 @@ FUNC_NAME(R300DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) FINISH_ACCEL(); } - BEGIN_ACCEL(6); + BEGIN_ACCEL_RELOC(6, 2); OUT_ACCEL_REG(R300_TX_INVALTAGS, 0); OUT_ACCEL_REG(R300_TX_ENABLE, txenable); - OUT_ACCEL_REG(R300_RB3D_COLOROFFSET0, dst_offset); - OUT_ACCEL_REG(R300_RB3D_COLORPITCH0, colorpitch); + EMIT_WRITE_OFFSET(R300_RB3D_COLOROFFSET0, 0, pPixmap); + EMIT_COLORPITCH(R300_RB3D_COLORPITCH0, colorpitch, pPixmap); /* no need to enable blending */ OUT_ACCEL_REG(R300_RB3D_BLENDCNTL, RADEON_SRC_BLEND_GL_ONE | RADEON_DST_BLEND_GL_ZERO); @@ -2395,9 +2473,10 @@ FUNC_NAME(R500DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) { RADEONInfoPtr info = RADEONPTR(pScrn); PixmapPtr pPixmap = pPriv->pPixmap; + struct radeon_exa_pixmap_priv *driver_priv; uint32_t txfilter, txformat0, txformat1, txoffset, txpitch; - uint32_t dst_offset, dst_pitch, dst_format; - uint32_t txenable, colorpitch; + uint32_t dst_pitch, dst_format; + uint32_t txenable, colorpitch, bicubic_offset; uint32_t output_fmt; Bool isplanar = FALSE; int dstxoff, dstyoff, pixel_shift, vtx_count; @@ -2405,19 +2484,37 @@ FUNC_NAME(R500DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) int nBox = REGION_NUM_RECTS(&pPriv->clip); ACCEL_PREAMBLE(); +#ifdef XF86DRM_MODE + if (info->cs) { + int ret; + + radeon_cs_space_reset_bos(info->cs); + radeon_cs_space_add_persistent_bo(info->cs, pPriv->src_bo, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); + + if (pPriv->bicubic_enabled) + radeon_cs_space_add_persistent_bo(info->cs, info->bicubic_bo, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); + + driver_priv = exaGetPixmapDriverPrivate(pPixmap); + radeon_cs_space_add_persistent_bo(info->cs, driver_priv->bo, 0, RADEON_GEM_DOMAIN_VRAM); + + ret = radeon_cs_space_check(info->cs); + if (ret) { + ErrorF("Not enough RAM to hw accel xv operation\n"); + return; + } + } +#endif + pixel_shift = pPixmap->drawable.bitsPerPixel >> 4; #ifdef USE_EXA if (info->useEXA) { - dst_offset = exaGetPixmapOffset(pPixmap) + info->fbLocation + pScrn->fbOffset; dst_pitch = exaGetPixmapPitch(pPixmap); } else #endif - { - dst_offset = (pPixmap->devPrivate.ptr - info->FB) + - info->fbLocation + pScrn->fbOffset; - dst_pitch = pPixmap->devKind; - } + { + dst_pitch = pPixmap->devKind; + } #ifdef COMPOSITE dstxoff = -pPixmap->screen_x + pPixmap->drawable.x; @@ -2516,15 +2613,15 @@ FUNC_NAME(R500DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) if ((pPriv->h - 1) & 0x800) txpitch |= R500_TXHEIGHT_11; - txoffset = pPriv->src_offset; + txoffset = info->cs ? 0 : pPriv->src_offset; - BEGIN_ACCEL(6); + BEGIN_ACCEL_RELOC(6, 1); OUT_ACCEL_REG(R300_TX_FILTER0_0, txfilter); OUT_ACCEL_REG(R300_TX_FILTER1_0, 0); OUT_ACCEL_REG(R300_TX_FORMAT0_0, txformat0); OUT_ACCEL_REG(R300_TX_FORMAT1_0, txformat1); OUT_ACCEL_REG(R300_TX_FORMAT2_0, txpitch); - OUT_ACCEL_REG(R300_TX_OFFSET_0, txoffset); + OUT_TEXTURE_REG(R300_TX_OFFSET_0, txoffset, pPriv->src_bo); FINISH_ACCEL(); txenable = R300_TEX_0_ENABLE; @@ -2573,13 +2670,18 @@ FUNC_NAME(R500DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) R300_TX_MAG_FILTER_NEAREST | (1 << R300_TX_ID_SHIFT)); + if (info->cs) + bicubic_offset = 0; + else + bicubic_offset = pPriv->bicubic_src_offset; + BEGIN_ACCEL(6); OUT_ACCEL_REG(R300_TX_FILTER0_1, txfilter); OUT_ACCEL_REG(R300_TX_FILTER1_1, 0); OUT_ACCEL_REG(R300_TX_FORMAT0_1, txformat0); OUT_ACCEL_REG(R300_TX_FORMAT1_1, txformat1); OUT_ACCEL_REG(R300_TX_FORMAT2_1, txpitch); - OUT_ACCEL_REG(R300_TX_OFFSET_1, pPriv->bicubic_src_offset); + OUT_TEXTURE_REG(R300_TX_OFFSET_1, bicubic_offset, info->bicubic_bo); FINISH_ACCEL(); /* Enable tex 1 */ @@ -3746,12 +3848,12 @@ FUNC_NAME(R500DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) FINISH_ACCEL(); } - BEGIN_ACCEL(6); + BEGIN_ACCEL_RELOC(6, 2); OUT_ACCEL_REG(R300_TX_INVALTAGS, 0); OUT_ACCEL_REG(R300_TX_ENABLE, txenable); - OUT_ACCEL_REG(R300_RB3D_COLOROFFSET0, dst_offset); - OUT_ACCEL_REG(R300_RB3D_COLORPITCH0, colorpitch); + EMIT_WRITE_OFFSET(R300_RB3D_COLOROFFSET0, 0, pPixmap); + EMIT_COLORPITCH(R300_RB3D_COLORPITCH0, colorpitch, pPixmap); /* no need to enable blending */ OUT_ACCEL_REG(R300_RB3D_BLENDCNTL, RADEON_SRC_BLEND_GL_ONE | RADEON_DST_BLEND_GL_ZERO); diff --git a/src/radeon_tv.c b/src/radeon_tv.c index eef45d9..6c083ce 100644 --- a/src/radeon_tv.c +++ b/src/radeon_tv.c @@ -1198,7 +1198,7 @@ void RADEONAdjustCrtc2RegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save, save->crtc2_v_total_disp = ((constPtr->verResolution - 1) << RADEON_CRTC_V_DISP_SHIFT) | ((constPtr->verTotal - 1) << RADEON_CRTC_V_TOTAL_SHIFT); - save->crtc_v_sync_strt_wid = (save->crtc_v_sync_strt_wid & ~RADEON_CRTC_V_SYNC_STRT) | + save->crtc2_v_sync_strt_wid = (save->crtc2_v_sync_strt_wid & ~RADEON_CRTC_V_SYNC_STRT) | ((constPtr->verSyncStart - 1) << RADEON_CRTC_V_SYNC_STRT_SHIFT); } diff --git a/src/radeon_video.c b/src/radeon_video.c index a14f44c..f1fe72b 100644 --- a/src/radeon_video.c +++ b/src/radeon_video.c @@ -284,7 +284,7 @@ void RADEONInitVideo(ScreenPtr pScreen) memcpy(newAdaptors, adaptors, num_adaptors * sizeof(XF86VideoAdaptorPtr)); adaptors = newAdaptors; - if (!IS_AVIVO_VARIANT) { + if (!IS_AVIVO_VARIANT && !info->kms_enabled) { overlayAdaptor = RADEONSetupImageVideo(pScreen); if (overlayAdaptor != NULL) { adaptors[num_adaptors++] = overlayAdaptor; @@ -1648,10 +1648,6 @@ RADEONStopVideo(ScrnInfoPtr pScrn, pointer data, Bool cleanup) if (pPriv->textured) { if (cleanup) { - if (pPriv->bicubic_memory != NULL) { - radeon_legacy_free_memory(pScrn, pPriv->bicubic_memory); - pPriv->bicubic_memory = NULL; - } if (pPriv->video_memory != NULL) { radeon_legacy_free_memory(pScrn, pPriv->video_memory); pPriv->video_memory = NULL; diff --git a/src/radeon_video.h b/src/radeon_video.h index 0cf8168..989942c 100644 --- a/src/radeon_video.h +++ b/src/radeon_video.h @@ -94,8 +94,6 @@ typedef struct { int planev_offset; /* bicubic filtering */ - void *bicubic_memory; - int bicubic_offset; Bool bicubic_enabled; uint32_t bicubic_src_offset; int bicubic_state; @@ -120,6 +118,8 @@ typedef struct { int drw_x, drw_y; int src_x, src_y; int vsync; + + struct radeon_bo *src_bo; } RADEONPortPrivRec, *RADEONPortPrivPtr; /* Reference color space transform data */ diff --git a/src/xvmc/r500_xvmc.c b/src/xvmc/r500_xvmc.c index dc3fa5c..5051032 100644 --- a/src/xvmc/r500_xvmc.c +++ b/src/xvmc/r500_xvmc.c @@ -24,10 +24,76 @@ * */ #include "radeon_xvmc.h" +#include "r500_xvmc.h" static Status r500_xvmc_create_context(Display *display, XvMCContext *context, int priv_count, CARD32 *priv_data) { + r500XvMCContext *pR500XvMC = NULL; + I915XvMCCreateContextRec *tmpComm = NULL; + drm_sarea_t *pSAREA; + + XVMC_DBG("%s\n", __FUNCTION__); + + if (priv_count != (sizeof(I915XvMCCreateContextRec) >> 2)) { + XVMC_ERR("_xvmc_create_context() returned incorrect data size!"); + XVMC_INFO("\tExpected %d, got %d", + (int)(sizeof(I915XvMCCreateContextRec) >> 2),priv_count); + _xvmc_destroy_context(display, context); + XFree(priv_data); + context->privData = NULL; + return BadValue; + } + + context->privData = (void *)calloc(1, sizeof(r500XvMCContext)); + if (!context->privData) + { + ErrorF("[XvMC]: Unable to allocate resources for XvMC context."); + return BadAlloc; + } + pR500XvMC = (r500XvMCContext *)context->privData; + + tmpComm = (I915XvMCCreateContextRec *)priv_data; + pR500XvMC->ctxno = tmpComm->ctxno; + pR500XvMC->deviceID = tmpComm->deviceID; + pR500XvMC->corrdata.handle = tmpComm->corrdata.handle; + pR500XvMC->corrdata.offset = tmpComm->corrdata.offset; + pR500XvMC->corrdata.size = tmpComm->corrdata.size; + pR500XvMC->sarea_priv_offset= tmpComm->sarea_priv_offset; + + /* Must free the private data we were passed from X */ + XFree(priv_data); + priv_data = NULL; + + pSAREA = (drm_sarea_t *)xvmc_driver->sarea_address; + pR500XvMC->sarea = (drmI830Sarea*)((char*)pSAREA + pR500XvMC->sarea_priv_offset); + + if (i915_xvmc_map_buffers(pR500XvMC)) { + i915_xvmc_unmap_buffers(pR500XvMC); + free(pR500XvMC); + context->privData = NULL; + return BadAlloc; + } + + /* Initialize private context values */ + pR500XvMC->yStride = STRIDE(context->width); + pR500XvMC->uvStride = STRIDE(context->width >> 1); + pR500XvMC->haveXv = 0; + pR500XvMC->dual_prime = 0; + pR500XvMC->last_flip = 0; + pR500XvMC->port = context->port; + pR500XvMC->ref = 1; + + /* pre-init state buffers */ + i915_mc_one_time_context_init(context); + i915_mc_one_time_state_init(context); + + i915_mc_static_indirect_state_init(context); + + i915_mc_map_state_init(context); + + i915_mc_load_indirect_render_init(context); + return Success; } static int r500_xvmc_destroy_context(Display *display, XvMCContext *context) diff --git a/src/xvmc/r500_xvmc.h b/src/xvmc/r500_xvmc.h index 4d57b15..e998e23 100644 --- a/src/xvmc/r500_xvmc.h +++ b/src/xvmc/r500_xvmc.h @@ -28,4 +28,23 @@ extern struct radeon_xvmc_driver r500_xvmc_driver; +typedef struct _r500XvMCContext +{ + unsigned int ctx_id; + unsigned int last_flip; + unsigned int dual_prime; /* whether dual prime is in use. */ + unsigned int yStride; + unsigned int uvStride; + unsigned short ref; + unsigned int sarea_priv_offset; /* Offset in sarea to private part */ + unsigned int depth; + XvPortID port; /* Xv Port ID when displaying */ + int haveXv; /* Have I initialized the Xv? */ + XvImage *xvImage; /* Fake Xv Image used for command */ + GC gc; /* X GC needed for displaying */ + Drawable draw; /* Drawable to undisplay from */ + void *drawHash; + int deviceID; +} r500XvMCContext; + #endif
\ No newline at end of file |