summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCooper Yuan <cooperyuan@gmail.com>2009-09-06 13:16:14 +0800
committerCooper Yuan <cooperyuan@gmail.com>2009-09-06 13:16:14 +0800
commit66d6ddcf4d14c0ed46cdf0b699a37657ec210e17 (patch)
tree3396947c878447d40e77f2ed39999f0cfc02c12f
parent11889ca4e24471fecff858158f752d4336b5fec3 (diff)
update ddx driver
-rw-r--r--Makefile.am2
-rw-r--r--README13
-rw-r--r--configure.ac89
-rw-r--r--src/Makefile.am16
-rw-r--r--src/ati_pciids_gen.h12
-rw-r--r--src/atombios_crtc.c62
-rw-r--r--src/atombios_output.c484
-rw-r--r--src/legacy_output.c19
-rw-r--r--src/pcidb/ati_pciids.csv22
-rwxr-xr-xsrc/pcidb/parse_pci_ids.pl2
-rw-r--r--src/r500_hwmc.c118
-rw-r--r--src/r500_hwmc.h4
-rw-r--r--src/r600_exa.c300
-rw-r--r--src/r600_shader.c16
-rw-r--r--src/r600_state.h5
-rw-r--r--src/r600_textured_videofuncs.c33
-rw-r--r--src/r6xx_accel.c150
-rw-r--r--src/radeon.h185
-rw-r--r--src/radeon_accel.c168
-rw-r--r--src/radeon_atombios.c28
-rw-r--r--src/radeon_chipinfo_gen.h14
-rw-r--r--src/radeon_chipset_gen.h22
-rw-r--r--src/radeon_commonfuncs.c159
-rw-r--r--src/radeon_crtc.c6
-rw-r--r--src/radeon_dri.c25
-rw-r--r--src/radeon_driver.c84
-rw-r--r--src/radeon_drm.h152
-rw-r--r--src/radeon_exa.c193
-rw-r--r--src/radeon_exa_funcs.c464
-rw-r--r--src/radeon_exa_render.c570
-rw-r--r--src/radeon_hwmc.c221
-rw-r--r--src/radeon_hwmc.h67
-rw-r--r--src/radeon_legacy_memory.c22
-rw-r--r--src/radeon_macros.h46
-rw-r--r--src/radeon_output.c36
-rw-r--r--src/radeon_pci_chipset_gen.h12
-rw-r--r--src/radeon_pci_device_match_gen.h12
-rw-r--r--src/radeon_pm.c11
-rw-r--r--src/radeon_probe.c82
-rw-r--r--src/radeon_probe.h11
-rw-r--r--src/radeon_reg.h32
-rw-r--r--src/radeon_textured_video.c94
-rw-r--r--src/radeon_textured_videofuncs.c236
-rw-r--r--src/radeon_tv.c2
-rw-r--r--src/radeon_video.c6
-rw-r--r--src/radeon_video.h4
-rw-r--r--src/xvmc/r500_xvmc.c66
-rw-r--r--src/xvmc/r500_xvmc.h19
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
diff --git a/README b/README
index 99de20d..4b92a18 100644
--- a/README
+++ b/README
@@ -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