Update to xf86-video-ati 7.6.1. ok jsg@

This commit is contained in:
matthieu 2016-04-02 07:37:34 +00:00
parent b96f098cef
commit 3fd647ab8c
37 changed files with 5497 additions and 953 deletions

File diff suppressed because it is too large Load Diff

View File

@ -8,6 +8,15 @@
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the <dri3.h> header file. */
#undef HAVE_DRI3_H
/* Have fbGlyphs API */
#undef HAVE_FBGLYPHS
/* Have glamor_glyphs_init API */
#undef HAVE_GLAMOR_GLYPHS_INIT
/* Define to 1 if you have the <glamor.h> header file. */
#undef HAVE_GLAMOR_H
@ -17,12 +26,15 @@
/* libudev support */
#undef HAVE_LIBUDEV
/* Define to 1 if you have the <list.h> header file. */
#undef HAVE_LIST_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <misyncshm.h> header file. */
#undef HAVE_MISYNCSHM_H
/* Define to 1 if you have the <present.h> header file. */
#undef HAVE_PRESENT_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H

View File

@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for xf86-video-ati 7.5.0.
# Generated by GNU Autoconf 2.69 for xf86-video-ati 7.6.1.
#
# Report bugs to <https://bugs.freedesktop.org/enter_bug.cgi?product=xorg>.
#
@ -591,8 +591,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='xf86-video-ati'
PACKAGE_TARNAME='xf86-video-ati'
PACKAGE_VERSION='7.5.0'
PACKAGE_STRING='xf86-video-ati 7.5.0'
PACKAGE_VERSION='7.6.1'
PACKAGE_STRING='xf86-video-ati 7.6.1'
PACKAGE_BUGREPORT='https://bugs.freedesktop.org/enter_bug.cgi?product=xorg'
PACKAGE_URL=''
@ -1386,7 +1386,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures xf86-video-ati 7.5.0 to adapt to many kinds of systems.
\`configure' configures xf86-video-ati 7.6.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1456,7 +1456,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of xf86-video-ati 7.5.0:";;
short | recursive ) echo "Configuration of xf86-video-ati 7.6.1:";;
esac
cat <<\_ACEOF
@ -1609,7 +1609,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
xf86-video-ati configure 7.5.0
xf86-video-ati configure 7.6.1
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@ -2024,7 +2024,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by xf86-video-ati $as_me 7.5.0, which was
It was created by xf86-video-ati $as_me 7.6.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@ -2855,7 +2855,7 @@ fi
# Define the identity of the package.
PACKAGE='xf86-video-ati'
VERSION='7.5.0'
VERSION='7.6.1'
cat >>confdefs.h <<_ACEOF
@ -18438,12 +18438,12 @@ if test -n "$XORG_CFLAGS"; then
pkg_cv_XORG_CFLAGS="$XORG_CFLAGS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"xorg-server >= 1.7 xproto fontsproto xf86driproto \$REQUIRED_MODULES\""; } >&5
($PKG_CONFIG --exists --print-errors "xorg-server >= 1.7 xproto fontsproto xf86driproto $REQUIRED_MODULES") 2>&5
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"xorg-server >= 1.8 xproto fontsproto xf86driproto \$REQUIRED_MODULES\""; } >&5
($PKG_CONFIG --exists --print-errors "xorg-server >= 1.8 xproto fontsproto xf86driproto $REQUIRED_MODULES") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
pkg_cv_XORG_CFLAGS=`$PKG_CONFIG --cflags "xorg-server >= 1.7 xproto fontsproto xf86driproto $REQUIRED_MODULES" 2>/dev/null`
pkg_cv_XORG_CFLAGS=`$PKG_CONFIG --cflags "xorg-server >= 1.8 xproto fontsproto xf86driproto $REQUIRED_MODULES" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
@ -18455,12 +18455,12 @@ if test -n "$XORG_LIBS"; then
pkg_cv_XORG_LIBS="$XORG_LIBS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"xorg-server >= 1.7 xproto fontsproto xf86driproto \$REQUIRED_MODULES\""; } >&5
($PKG_CONFIG --exists --print-errors "xorg-server >= 1.7 xproto fontsproto xf86driproto $REQUIRED_MODULES") 2>&5
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"xorg-server >= 1.8 xproto fontsproto xf86driproto \$REQUIRED_MODULES\""; } >&5
($PKG_CONFIG --exists --print-errors "xorg-server >= 1.8 xproto fontsproto xf86driproto $REQUIRED_MODULES") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
pkg_cv_XORG_LIBS=`$PKG_CONFIG --libs "xorg-server >= 1.7 xproto fontsproto xf86driproto $REQUIRED_MODULES" 2>/dev/null`
pkg_cv_XORG_LIBS=`$PKG_CONFIG --libs "xorg-server >= 1.8 xproto fontsproto xf86driproto $REQUIRED_MODULES" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
@ -18481,14 +18481,14 @@ else
_pkg_short_errors_supported=no
fi
if test $_pkg_short_errors_supported = yes; then
XORG_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "xorg-server >= 1.7 xproto fontsproto xf86driproto $REQUIRED_MODULES" 2>&1`
XORG_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "xorg-server >= 1.8 xproto fontsproto xf86driproto $REQUIRED_MODULES" 2>&1`
else
XORG_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "xorg-server >= 1.7 xproto fontsproto xf86driproto $REQUIRED_MODULES" 2>&1`
XORG_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "xorg-server >= 1.8 xproto fontsproto xf86driproto $REQUIRED_MODULES" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$XORG_PKG_ERRORS" >&5
as_fn_error $? "Package requirements (xorg-server >= 1.7 xproto fontsproto xf86driproto $REQUIRED_MODULES) were not met:
as_fn_error $? "Package requirements (xorg-server >= 1.8 xproto fontsproto xf86driproto $REQUIRED_MODULES) were not met:
$XORG_PKG_ERRORS
@ -18736,6 +18736,16 @@ if test "x$ac_cv_have_decl_GLAMOR_NO_DRI3" = xyes; then :
GLAMOR_XSERVER="yes"
else
GLAMOR_XSERVER="no"
fi
ac_fn_c_check_decl "$LINENO" "glamor_glyphs_init" "ac_cv_have_decl_glamor_glyphs_init" "#include \"xorg-server.h\"
#include \"glamor.h\"
"
if test "x$ac_cv_have_decl_glamor_glyphs_init" = xyes; then :
$as_echo "#define HAVE_GLAMOR_GLYPHS_INIT 1" >>confdefs.h
fi
fi
@ -18940,27 +18950,24 @@ else
fi
for ac_header in list.h
do :
ac_fn_c_check_header_compile "$LINENO" "list.h" "ac_cv_header_list_h" "#include <X11/Xdefs.h>
#include \"xorg-server.h\"
ac_fn_c_check_decl "$LINENO" "fbGlyphs" "ac_cv_have_decl_fbGlyphs" "#include <X11/Xmd.h>
#include <X11/Xfuncproto.h>
#include <X11/extensions/renderproto.h>
#include <xorg-server.h>
#include <picture.h>
#include <glyphstr.h>
#include <fbpict.h>
"
if test "x$ac_cv_header_list_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_LIST_H 1
_ACEOF
have_list_h="yes"
else
have_list_h="no"
if test "x$ac_cv_have_decl_fbGlyphs" = xyes; then :
$as_echo "#define HAVE_FBGLYPHS 1" >>confdefs.h
fi
done
if test "x$have_list_h" = xyes; then
ac_fn_c_check_decl "$LINENO" "xorg_list_init" "ac_cv_have_decl_xorg_list_init" "#include <X11/Xdefs.h>
#include \"xorg-server.h\"
#include \"list.h\"
ac_fn_c_check_decl "$LINENO" "xorg_list_init" "ac_cv_have_decl_xorg_list_init" "#include <X11/Xdefs.h>
#include \"xorg-server.h\"
#include \"list.h\"
"
if test "x$ac_cv_have_decl_xorg_list_init" = xyes; then :
@ -18968,8 +18975,56 @@ $as_echo "#define HAVE_XORG_LIST 1" >>confdefs.h
fi
for ac_header in misyncshm.h
do :
ac_fn_c_check_header_compile "$LINENO" "misyncshm.h" "ac_cv_header_misyncshm_h" "#include <X11/Xdefs.h>
#include <X11/Xfuncproto.h>
#include <xorg-server.h>
#include <screenint.h>
"
if test "x$ac_cv_header_misyncshm_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_MISYNCSHM_H 1
_ACEOF
fi
done
for ac_header in present.h
do :
ac_fn_c_check_header_compile "$LINENO" "present.h" "ac_cv_header_present_h" "#include <X11/Xmd.h>
#include <X11/Xproto.h>
#include <X11/X.h>
#include \"xorg-server.h\"
"
if test "x$ac_cv_header_present_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_PRESENT_H 1
_ACEOF
fi
done
for ac_header in dri3.h
do :
ac_fn_c_check_header_compile "$LINENO" "dri3.h" "ac_cv_header_dri3_h" "#include <X11/Xmd.h>
#include <xorg-server.h>
"
if test "x$ac_cv_header_dri3_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_DRI3_H 1
_ACEOF
fi
done
CPPFLAGS="$SAVE_CPPFLAGS"
@ -19762,7 +19817,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by xf86-video-ati $as_me 7.5.0, which was
This file was extended by xf86-video-ati $as_me 7.6.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@ -19828,7 +19883,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
xf86-video-ati config.status 7.5.0
xf86-video-ati config.status 7.6.1
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"

View File

@ -23,7 +23,7 @@
# Initialize Autoconf
AC_PREREQ([2.60])
AC_INIT([xf86-video-ati],
[7.5.0],
[7.6.1],
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
[xf86-video-ati])
@ -75,7 +75,7 @@ PKG_CHECK_MODULES(LIBDRM, [libdrm >= 2.4.58])
PKG_CHECK_MODULES(LIBDRM_RADEON, [libdrm_radeon])
# Obtain compiler/linker options for the driver dependencies
PKG_CHECK_MODULES(XORG, [xorg-server >= 1.7 xproto fontsproto xf86driproto $REQUIRED_MODULES])
PKG_CHECK_MODULES(XORG, [xorg-server >= 1.8 xproto fontsproto xf86driproto $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")
@ -113,6 +113,12 @@ if test "x$GLAMOR" != "xno"; then
[GLAMOR_XSERVER="yes"], [GLAMOR_XSERVER="no"],
[#include "xorg-server.h"
#include "glamor.h"])
AC_CHECK_DECL(glamor_glyphs_init,
[AC_DEFINE(HAVE_GLAMOR_GLYPHS_INIT, 1,
[Have glamor_glyphs_init API])], [],
[#include "xorg-server.h"
#include "glamor.h"])
fi
if test "x$GLAMOR_XSERVER" != xyes; then
@ -125,18 +131,37 @@ else
fi
AM_CONDITIONAL(GLAMOR, test x$GLAMOR != xno)
AC_CHECK_HEADERS([list.h],
[have_list_h="yes"], [have_list_h="no"],
[#include <X11/Xdefs.h>
#include "xorg-server.h"])
AC_CHECK_DECL(fbGlyphs,
[AC_DEFINE(HAVE_FBGLYPHS, 1, [Have fbGlyphs API])], [],
[#include <X11/Xmd.h>
#include <X11/Xfuncproto.h>
#include <X11/extensions/renderproto.h>
#include <xorg-server.h>
#include <picture.h>
#include <glyphstr.h>
#include <fbpict.h>])
if test "x$have_list_h" = xyes; then
AC_CHECK_DECL(xorg_list_init,
[AC_DEFINE(HAVE_XORG_LIST, 1, [Have xorg_list API])], [],
[#include <X11/Xdefs.h>
#include "xorg-server.h"
#include "list.h"])
fi
AC_CHECK_DECL(xorg_list_init,
[AC_DEFINE(HAVE_XORG_LIST, 1, [Have xorg_list API])], [],
[#include <X11/Xdefs.h>
#include "xorg-server.h"
#include "list.h"])
AC_CHECK_HEADERS([misyncshm.h], [], [],
[#include <X11/Xdefs.h>
#include <X11/Xfuncproto.h>
#include <xorg-server.h>
#include <screenint.h>])
AC_CHECK_HEADERS([present.h], [], [],
[#include <X11/Xmd.h>
#include <X11/Xproto.h>
#include <X11/X.h>
#include "xorg-server.h"])
AC_CHECK_HEADERS([dri3.h], [], [],
[#include <X11/Xmd.h>
#include <xorg-server.h>])
CPPFLAGS="$SAVE_CPPFLAGS"

View File

@ -267,11 +267,23 @@ The default value is
for R/RV6XX, R/RV7XX, RS780, RS880, EVERGREEN, CAYMAN, ARUBA, Southern Islands, and
Sea Islands.
.TP
.BI "Option \*qDRI\*q \*q" integer \*q
Define the maximum level of DRI to enable. Valid values are 2 for DRI2 or 3 for DRI3.
The default is
.B 2 for DRI2.
.TP
.BI "Option \*qEnablePageFlip\*q \*q" boolean \*q
Enable DRI2 page flipping. The default is
.B on.
Pageflipping is supported on all radeon hardware.
.TP
.BI "Option \*qTearFree\*q \*q" boolean \*q
Enable tearing prevention using the hardware page flipping mechanism. This
option currently doesn't have any effect for rotated CRTCs. It requires
allocating two separate scanout buffers for each non-rotated CRTC. Enabling
this option currently disables Option \*qEnablePageFlip\*q. The default is
.B off.
.TP
.BI "Option \*qAccelMethod\*q \*q" "string" \*q
Chooses between available acceleration architectures. Valid values are
.B EXA
@ -282,6 +294,22 @@ Chooses between available acceleration architectures. Valid values are
as of TAHITI, otherwise
.B EXA.
.PP
The following driver
.B Options
are supported for
.B glamor
:
.TP
.BI "Option \*qShadowPrimary\*q \*q" boolean \*q
This option enables a so-called "shadow primary" buffer for fast CPU access to
pixel data, and separate scanout buffers for each display controller (CRTC).
This may improve performance for some 2D workloads, potentially at the expense
of other (e.g. 3D, video) workloads.
Note in particular that enabling this option currently disables page flipping.
The default is
.B off.
.PP
The following driver
.B Options

View File

@ -27,10 +27,11 @@
# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
ati_drv_la_LIBADD = $(PCIACCESS_LIBS)
radeon_drv_la_LIBADD = $(LIBDRM_RADEON_LIBS) $(PCIACCESS_LIBS)
radeon_drv_la_LIBADD = $(LIBDRM_RADEON_LIBS)
RADEON_KMS_SRCS=radeon_dri2.c radeon_kms.c drmmode_display.c radeon_vbo.c \
radeon_bo_helper.c
RADEON_KMS_SRCS=radeon_dri2.c radeon_dri3.c radeon_drm_queue.c radeon_kms.c \
radeon_present.c radeon_sync.c radeon_vbo.c radeon_bo_helper.c \
drmmode_display.c
RADEON_EXA_SOURCES = radeon_exa.c r600_exa.c r6xx_accel.c r600_textured_videofuncs.c r600_shader.c radeon_exa_shared.c \
evergreen_exa.c evergreen_accel.c evergreen_shader.c evergreen_textured_videofuncs.c cayman_accel.c cayman_shader.c
@ -64,6 +65,7 @@ if GLAMOR
AM_CFLAGS += @LIBGLAMOR_CFLAGS@
radeon_drv_la_LIBADD += @LIBGLAMOR_LIBS@
radeon_drv_la_SOURCES += \
radeon_glamor_wrappers.c \
radeon_glamor.c
endif
@ -88,11 +90,13 @@ EXTRA_DIST = \
bicubic_table.h \
bicubic_table.py \
radeon_bo_helper.h \
radeon_drm_queue.h \
radeon_exa_render.c \
radeon_exa_funcs.c \
radeon_exa_shared.h \
radeon_glamor.h \
radeon.h \
radeon_list.h \
radeon_probe.h \
radeon_reg.h \
radeon_version.h \

View File

@ -81,6 +81,7 @@ host_triplet = @host@
@GLAMOR_TRUE@am__append_2 = @LIBGLAMOR_CFLAGS@
@GLAMOR_TRUE@am__append_3 = @LIBGLAMOR_LIBS@
@GLAMOR_TRUE@am__append_4 = \
@GLAMOR_TRUE@ radeon_glamor_wrappers.c \
@GLAMOR_TRUE@ radeon_glamor.c
subdir = src
@ -137,24 +138,26 @@ ati_drv_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(ati_drv_la_LDFLAGS) $(LDFLAGS) -o $@
@LIBUDEV_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
radeon_drv_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \
$(am__DEPENDENCIES_1)
$(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
am__radeon_drv_la_SOURCES_DIST = radeon_accel.c radeon_video.c \
radeon_misc.c radeon_probe.c radeon_textured_video.c \
radeon_xvmc.c radeon_exa.c r600_exa.c r6xx_accel.c \
r600_textured_videofuncs.c r600_shader.c radeon_exa_shared.c \
evergreen_exa.c evergreen_accel.c evergreen_shader.c \
evergreen_textured_videofuncs.c cayman_accel.c cayman_shader.c \
radeon_dri2.c radeon_kms.c drmmode_display.c radeon_vbo.c \
radeon_bo_helper.c radeon_glamor.c
radeon_dri2.c radeon_dri3.c radeon_drm_queue.c radeon_kms.c \
radeon_present.c radeon_sync.c radeon_vbo.c radeon_bo_helper.c \
drmmode_display.c radeon_glamor_wrappers.c radeon_glamor.c
am__objects_1 = radeon_exa.lo r600_exa.lo r6xx_accel.lo \
r600_textured_videofuncs.lo r600_shader.lo \
radeon_exa_shared.lo evergreen_exa.lo evergreen_accel.lo \
evergreen_shader.lo evergreen_textured_videofuncs.lo \
cayman_accel.lo cayman_shader.lo
am__objects_2 = radeon_dri2.lo radeon_kms.lo drmmode_display.lo \
radeon_vbo.lo radeon_bo_helper.lo
@GLAMOR_TRUE@am__objects_3 = radeon_glamor.lo
am__objects_2 = radeon_dri2.lo radeon_dri3.lo radeon_drm_queue.lo \
radeon_kms.lo radeon_present.lo radeon_sync.lo radeon_vbo.lo \
radeon_bo_helper.lo drmmode_display.lo
@GLAMOR_TRUE@am__objects_3 = radeon_glamor_wrappers.lo \
@GLAMOR_TRUE@ radeon_glamor.lo
am_radeon_drv_la_OBJECTS = radeon_accel.lo radeon_video.lo \
radeon_misc.lo radeon_probe.lo radeon_textured_video.lo \
radeon_xvmc.lo $(am__objects_1) $(am__objects_2) \
@ -363,10 +366,11 @@ top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
ati_drv_la_LIBADD = $(PCIACCESS_LIBS)
radeon_drv_la_LIBADD = $(LIBDRM_RADEON_LIBS) $(PCIACCESS_LIBS) \
$(am__append_1) $(am__append_3)
RADEON_KMS_SRCS = radeon_dri2.c radeon_kms.c drmmode_display.c radeon_vbo.c \
radeon_bo_helper.c
radeon_drv_la_LIBADD = $(LIBDRM_RADEON_LIBS) $(am__append_1) \
$(am__append_3)
RADEON_KMS_SRCS = radeon_dri2.c radeon_dri3.c radeon_drm_queue.c radeon_kms.c \
radeon_present.c radeon_sync.c radeon_vbo.c radeon_bo_helper.c \
drmmode_display.c
RADEON_EXA_SOURCES = radeon_exa.c r600_exa.c r6xx_accel.c r600_textured_videofuncs.c r600_shader.c radeon_exa_shared.c \
evergreen_exa.c evergreen_accel.c evergreen_shader.c evergreen_textured_videofuncs.c cayman_accel.c cayman_shader.c
@ -406,11 +410,13 @@ EXTRA_DIST = \
bicubic_table.h \
bicubic_table.py \
radeon_bo_helper.h \
radeon_drm_queue.h \
radeon_exa_render.c \
radeon_exa_funcs.c \
radeon_exa_shared.h \
radeon_glamor.h \
radeon.h \
radeon_list.h \
radeon_probe.h \
radeon_reg.h \
radeon_version.h \
@ -558,12 +564,17 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radeon_accel.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radeon_bo_helper.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radeon_dri2.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radeon_dri3.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radeon_drm_queue.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radeon_exa.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radeon_exa_shared.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radeon_glamor.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radeon_glamor_wrappers.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radeon_kms.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radeon_misc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radeon_present.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radeon_probe.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radeon_sync.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radeon_textured_video.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radeon_vbo.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radeon_video.Plo@am__quote@

View File

@ -692,6 +692,7 @@
#define PCI_CHIP_OLAND_6610 0x6610
#define PCI_CHIP_OLAND_6611 0x6611
#define PCI_CHIP_OLAND_6613 0x6613
#define PCI_CHIP_OLAND_6617 0x6617
#define PCI_CHIP_OLAND_6620 0x6620
#define PCI_CHIP_OLAND_6621 0x6621
#define PCI_CHIP_OLAND_6623 0x6623
@ -712,6 +713,7 @@
#define PCI_CHIP_BONAIRE_6658 0x6658
#define PCI_CHIP_BONAIRE_665C 0x665C
#define PCI_CHIP_BONAIRE_665D 0x665D
#define PCI_CHIP_BONAIRE_665F 0x665F
#define PCI_CHIP_KABINI_9830 0x9830
#define PCI_CHIP_KABINI_9831 0x9831
#define PCI_CHIP_KABINI_9832 0x9832

File diff suppressed because it is too large Load Diff

View File

@ -32,6 +32,7 @@
#include "libudev.h"
#endif
#include "radeon_drm_queue.h"
#include "radeon_probe.h"
#ifndef DRM_CAP_TIMESTAMP_MONOTONIC
@ -41,7 +42,6 @@
typedef struct {
int fd;
unsigned fb_id;
drmModeResPtr mode_res;
drmModeFBPtr mode_fb;
int cpp;
struct radeon_bo_manager *bufmgr;
@ -51,6 +51,12 @@ typedef struct {
InputHandlerProc uevent_handler;
#endif
drmEventContext event_context;
int count_crtcs;
Bool delete_dp_12_displays;
Bool dri2_flipping;
Bool present_flipping;
} drmmode_rec, *drmmode_ptr;
typedef struct {
@ -59,8 +65,9 @@ typedef struct {
int flip_count;
void *event_data;
unsigned int fe_frame;
unsigned int fe_tv_sec;
unsigned int fe_tv_usec;
uint64_t fe_usec;
radeon_drm_handler_proc handler;
radeon_drm_abort_proc abort;
} drmmode_flipdata_rec, *drmmode_flipdata_ptr;
typedef struct {
@ -68,20 +75,33 @@ typedef struct {
Bool dispatch_me;
} drmmode_flipevtcarrier_rec, *drmmode_flipevtcarrier_ptr;
struct drmmode_scanout {
struct radeon_bo *bo;
PixmapPtr pixmap;
DamagePtr damage;
unsigned fb_id;
int width, height;
};
typedef struct {
drmmode_ptr drmmode;
drmModeCrtcPtr mode_crtc;
int hw_id;
struct radeon_bo *cursor_bo;
struct radeon_bo *rotate_bo;
unsigned rotate_fb_id;
struct drmmode_scanout rotate;
struct drmmode_scanout scanout[2];
unsigned scanout_id;
Bool scanout_update_pending;
int dpms_mode;
CARD64 dpms_last_ust;
uint32_t dpms_last_seq;
int dpms_last_fps;
uint32_t interpolated_vblanks;
uint16_t lut_r[256], lut_g[256], lut_b[256];
int scanout_pixmap_x;
int prime_pixmap_x;
/* Modeset needed for DPMS on */
Bool need_modeset;
} drmmode_crtc_private_rec, *drmmode_crtc_private_ptr;
typedef struct {
@ -112,18 +132,28 @@ extern void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
extern Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, struct radeon_bo_manager *bufmgr);
extern void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, struct radeon_bo *bo);
void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y);
extern Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
extern Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode,
Bool set_hw);
#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 10
extern void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
#endif
extern Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn);
extern void drmmode_scanout_free(ScrnInfoPtr scrn);
extern void drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode);
extern void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode);
extern int drmmode_get_crtc_id(xf86CrtcPtr crtc);
extern int drmmode_get_height_align(ScrnInfoPtr scrn, uint32_t tiling);
extern int drmmode_get_pitch_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling);
extern int drmmode_get_base_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling);
Bool radeon_do_pageflip(ScrnInfoPtr scrn, struct radeon_bo *new_front, void *data, int ref_crtc_hw_id);
Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
uint32_t new_front_handle, uint64_t id, void *data,
int ref_crtc_hw_id, radeon_drm_handler_proc handler,
radeon_drm_abort_proc abort);
int drmmode_crtc_get_ust_msc(xf86CrtcPtr crtc, CARD64 *ust, CARD64 *msc);
int drmmode_get_current_ust(int drm_fd, CARD64 *ust);
#endif

View File

@ -79,9 +79,9 @@ unsigned eg_tile_split(unsigned tile_split)
case 128: tile_split = 1; break;
case 256: tile_split = 2; break;
case 512: tile_split = 3; break;
default:
case 1024: tile_split = 4; break;
case 2048: tile_split = 5; break;
default:
case 4096: tile_split = 6; break;
}
return tile_split;

View File

@ -693,6 +693,7 @@
"0x6610","OLAND_6610","OLAND",,,,,,"OLAND"
"0x6611","OLAND_6611","OLAND",,,,,,"OLAND"
"0x6613","OLAND_6613","OLAND",,,,,,"OLAND"
"0x6617","OLAND_6617","OLAND",1,,,,,"OLAND"
"0x6620","OLAND_6620","OLAND",1,,,,,"OLAND"
"0x6621","OLAND_6621","OLAND",1,,,,,"OLAND"
"0x6623","OLAND_6623","OLAND",1,,,,,"OLAND"
@ -713,6 +714,7 @@
"0x6658","BONAIRE_6658","BONAIRE",,,,,,"BONAIRE"
"0x665C","BONAIRE_665C","BONAIRE",,,,,,"BONAIRE"
"0x665D","BONAIRE_665D","BONAIRE",,,,,,"BONAIRE"
"0x665F","BONAIRE_665F","BONAIRE",,,,,,"BONAIRE"
"0x9830","KABINI_9830","KABINI",1,1,,,1,"KABINI"
"0x9831","KABINI_9831","KABINI",,1,,,1,"KABINI"
"0x9832","KABINI_9832","KABINI",1,1,,,1,"KABINI"

1 #pciid define family mobility igp nocrtc2 Nointtvout singledac name
693 0x6610 OLAND_6610 OLAND OLAND
694 0x6611 OLAND_6611 OLAND OLAND
695 0x6613 OLAND_6613 OLAND OLAND
696 0x6617 OLAND_6617 OLAND 1 OLAND
697 0x6620 OLAND_6620 OLAND 1 OLAND
698 0x6621 OLAND_6621 OLAND 1 OLAND
699 0x6623 OLAND_6623 OLAND 1 OLAND
714 0x6658 BONAIRE_6658 BONAIRE BONAIRE
715 0x665C BONAIRE_665C BONAIRE BONAIRE
716 0x665D BONAIRE_665D BONAIRE BONAIRE
717 0x665F BONAIRE_665F BONAIRE BONAIRE
718 0x9830 KABINI_9830 KABINI 1 1 1 KABINI
719 0x9831 KABINI_9831 KABINI 1 1 KABINI
720 0x9832 KABINI_9832 KABINI 1 1 1 KABINI

View File

@ -51,8 +51,6 @@
#include "exa.h"
#include "radeon_glamor.h"
/* Exa and Cursor Support */
#include "xf86Cursor.h"
@ -92,6 +90,8 @@
#include "simple_list.h"
#include "atipcirename.h"
struct _SyncFence;
#ifndef MAX
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif
@ -148,7 +148,12 @@ typedef enum {
OPTION_ACCELMETHOD,
OPTION_EXA_VSYNC,
OPTION_ZAPHOD_HEADS,
OPTION_SWAPBUFFERS_WAIT
OPTION_SWAPBUFFERS_WAIT,
OPTION_DELETE_DP12,
OPTION_DRI3,
OPTION_DRI,
OPTION_SHADOW_PRIMARY,
OPTION_TEAR_FREE,
} RADEONOpts;
@ -241,6 +246,47 @@ typedef enum {
#define CURSOR_WIDTH_CIK 128
#define CURSOR_HEIGHT_CIK 128
#ifdef USE_GLAMOR
struct radeon_pixmap {
struct radeon_surface surface;
uint_fast32_t gpu_read;
uint_fast32_t gpu_write;
struct radeon_bo *bo;
uint32_t tiling_flags;
/* GEM handle for glamor-only pixmaps shared via DRI3 */
Bool handle_valid;
uint32_t handle;
};
#if HAS_DEVPRIVATEKEYREC
extern DevPrivateKeyRec glamor_pixmap_index;
#else
extern int glamor_pixmap_index;
#endif
static inline struct radeon_pixmap *radeon_get_pixmap_private(PixmapPtr pixmap)
{
#if HAS_DEVPRIVATEKEYREC
return dixGetPrivate(&pixmap->devPrivates, &glamor_pixmap_index);
#else
return dixLookupPrivate(&pixmap->devPrivates, &glamor_pixmap_index);
#endif
}
static inline void radeon_set_pixmap_private(PixmapPtr pixmap, struct radeon_pixmap *priv)
{
dixSetPrivate(&pixmap->devPrivates, &glamor_pixmap_index, priv);
}
#endif /* USE_GLAMOR */
struct radeon_exa_pixmap_priv {
struct radeon_bo *bo;
uint32_t tiling_flags;
@ -412,6 +458,9 @@ typedef struct {
void (*BlockHandler)(BLOCKHANDLER_ARGS_DECL);
void (*CreateFence) (ScreenPtr pScreen, struct _SyncFence *pFence,
Bool initially_triggered);
int pix24bpp; /* Depth of pixmap for 24bpp fb */
Bool dac6bits; /* Use 6 bit DAC? */
@ -419,15 +468,19 @@ typedef struct {
Bool directRenderingEnabled;
struct radeon_dri2 dri2;
Bool accelDFS;
/* accel */
Bool RenderAccel; /* Render */
Bool allowColorTiling;
Bool allowColorTiling2D;
uint_fast32_t gpu_flushed;
uint_fast32_t gpu_synced;
struct radeon_accel_state *accel_state;
PixmapPtr fbcon_pixmap;
Bool accelOn;
Bool use_glamor;
Bool shadow_primary;
Bool tear_free;
Bool exa_pixmaps;
Bool exa_force_create;
XF86ModReqInfo exaReq;
@ -442,9 +495,11 @@ typedef struct {
DisplayModePtr currentMode;
CreateScreenResourcesProcPtr CreateScreenResources;
#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 10
CreateWindowProcPtr CreateWindow;
#endif
Bool IsSecondary;
Bool IsPrimary;
Bool r600_shadow_fb;
void *fb_shadow;
@ -483,6 +538,31 @@ typedef struct {
/* cursor size */
int cursor_w;
int cursor_h;
#ifdef USE_GLAMOR
struct {
CreateGCProcPtr SavedCreateGC;
RegionPtr (*SavedCopyArea)(DrawablePtr, DrawablePtr, GCPtr, int, int,
int, int, int, int);
void (*SavedPolyFillRect)(DrawablePtr, GCPtr, int, xRectangle*);
CloseScreenProcPtr SavedCloseScreen;
GetImageProcPtr SavedGetImage;
GetSpansProcPtr SavedGetSpans;
CreatePixmapProcPtr SavedCreatePixmap;
DestroyPixmapProcPtr SavedDestroyPixmap;
CopyWindowProcPtr SavedCopyWindow;
ChangeWindowAttributesProcPtr SavedChangeWindowAttributes;
BitmapToRegionProcPtr SavedBitmapToRegion;
#ifdef RENDER
CompositeProcPtr SavedComposite;
TrianglesProcPtr SavedTriangles;
GlyphsProcPtr SavedGlyphs;
TrapezoidsProcPtr SavedTrapezoids;
AddTrapsProcPtr SavedAddTraps;
UnrealizeGlyphProcPtr SavedUnrealizeGlyph;
#endif
} glamor;
#endif /* USE_GLAMOR */
} RADEONInfoRec, *RADEONInfoPtr;
/* radeon_accel.c */
@ -512,6 +592,20 @@ extern Bool RADEONGetDatatypeBpp(int bpp, uint32_t *type);
extern Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix,
uint32_t *pitch_offset);
/* radeon_dri3.c */
Bool radeon_dri3_screen_init(ScreenPtr screen);
/* radeon_kms.c */
void radeon_scanout_update_handler(ScrnInfoPtr scrn, uint32_t frame,
uint64_t usec, void *event_data);
/* radeon_present.c */
Bool radeon_present_screen_init(ScreenPtr screen);
/* radeon_sync.c */
extern Bool radeon_sync_init(ScreenPtr screen);
extern void radeon_sync_close(ScreenPtr screen);
/* radeon_video.c */
extern void RADEONInitVideo(ScreenPtr pScreen);
extern void RADEONResetVideo(ScrnInfoPtr pScrn);
@ -630,7 +724,7 @@ static inline struct radeon_bo *radeon_get_pixmap_bo(PixmapPtr pPix)
{
struct radeon_exa_pixmap_priv *driver_priv;
driver_priv = exaGetPixmapDriverPrivate(pPix);
return driver_priv->bo;
return driver_priv ? driver_priv->bo : NULL;
}
return NULL;
@ -786,6 +880,7 @@ static __inline__ void RADEON_SYNC(RADEONInfoPtr info, ScrnInfoPtr pScrn)
}
enum {
RADEON_CREATE_PIXMAP_SCANOUT = 0x02000000,
RADEON_CREATE_PIXMAP_DRI2 = 0x04000000,
RADEON_CREATE_PIXMAP_TILING_MICRO_SQUARE = 0x08000000,
RADEON_CREATE_PIXMAP_TILING_MACRO = 0x10000000,

View File

@ -78,6 +78,7 @@
#include <assert.h>
/* Driver data structures */
#include "radeon.h"
#include "radeon_glamor.h"
#include "radeon_reg.h"
#include "r600_reg.h"
#include "radeon_probe.h"

View File

@ -25,6 +25,7 @@
#endif
#include "radeon.h"
#include "radeon_glamor.h"
#ifdef RADEON_PIXMAP_SHARING
#include "radeon_bo_gem.h"
@ -87,12 +88,15 @@ radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth,
if (usage_hint & RADEON_CREATE_PIXMAP_DEPTH)
tiling |= RADEON_TILING_MACRO | RADEON_TILING_MICRO;
if ((usage_hint == CREATE_PIXMAP_USAGE_BACKING_PIXMAP &&
info->shadow_primary)
#ifdef CREATE_PIXMAP_USAGE_SHARED
if ((usage_hint & 0xffff) == CREATE_PIXMAP_USAGE_SHARED) {
|| (usage_hint & 0xffff) == CREATE_PIXMAP_USAGE_SHARED
#endif
) {
tiling = 0;
domain = RADEON_GEM_DOMAIN_GTT;
}
#endif
}
/* Small pixmaps must not be macrotiled on R300, hw cannot sample them
@ -164,7 +168,8 @@ radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth,
tiling |= surface.bankw << RADEON_TILING_EG_BANKW_SHIFT;
tiling |= surface.bankh << RADEON_TILING_EG_BANKH_SHIFT;
tiling |= surface.mtilea << RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT;
tiling |= eg_tile_split(surface.tile_split) << RADEON_TILING_EG_TILE_SPLIT_SHIFT;
if (surface.tile_split)
tiling |= eg_tile_split(surface.tile_split) << RADEON_TILING_EG_TILE_SPLIT_SHIFT;
tiling |= eg_tile_split(surface.stencil_tile_split) << RADEON_TILING_EG_STENCIL_TILE_SPLIT_SHIFT;
break;
case RADEON_SURF_MODE_1D:
@ -187,6 +192,87 @@ radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth,
return bo;
}
/* Get GEM handle for the pixmap */
Bool radeon_get_pixmap_handle(PixmapPtr pixmap, uint32_t *handle)
{
struct radeon_bo *bo = radeon_get_pixmap_bo(pixmap);
#ifdef USE_GLAMOR
ScreenPtr screen = pixmap->drawable.pScreen;
RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(screen));
#endif
if (bo) {
*handle = bo->handle;
return TRUE;
}
#ifdef USE_GLAMOR
if (info->use_glamor) {
struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap);
CARD16 stride;
CARD32 size;
int fd, r;
if (!priv) {
priv = calloc(1, sizeof(*priv));
radeon_set_pixmap_private(pixmap, priv);
}
if (priv->handle_valid) {
*handle = priv->handle;
return TRUE;
}
fd = glamor_fd_from_pixmap(screen, pixmap, &stride, &size);
if (fd < 0)
return FALSE;
r = drmPrimeFDToHandle(info->dri2.drm_fd, fd, &priv->handle);
close(fd);
if (r == 0) {
struct drm_radeon_gem_set_tiling args = { .handle = priv->handle };
priv->handle_valid = TRUE;
*handle = priv->handle;
if (drmCommandWriteRead(info->dri2.drm_fd,
DRM_RADEON_GEM_GET_TILING, &args,
sizeof(args)) == 0)
priv->tiling_flags = args.tiling_flags;
return TRUE;
}
}
#endif
return FALSE;
}
uint32_t radeon_get_pixmap_tiling_flags(PixmapPtr pPix)
{
#ifdef USE_GLAMOR
RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen));
if (info->use_glamor) {
struct radeon_pixmap *priv = radeon_get_pixmap_private(pPix);
if (!priv || (!priv->bo && !priv->handle_valid)) {
uint32_t handle;
radeon_get_pixmap_handle(pPix, &handle);
priv = radeon_get_pixmap_private(pPix);
}
return priv ? priv->tiling_flags : 0;
} else
#endif
{
struct radeon_exa_pixmap_priv *driver_priv;
driver_priv = exaGetPixmapDriverPrivate(pPix);
return driver_priv ? driver_priv->tiling_flags : 0;
}
}
#ifdef RADEON_PIXMAP_SHARING
Bool radeon_share_pixmap_backing(struct radeon_bo *bo, void **handle_p)
@ -200,6 +286,21 @@ Bool radeon_share_pixmap_backing(struct radeon_bo *bo, void **handle_p)
return TRUE;
}
static unsigned eg_tile_split_opp(unsigned tile_split)
{
switch (tile_split) {
case 0: tile_split = 64; break;
case 1: tile_split = 128; break;
case 2: tile_split = 256; break;
case 3: tile_split = 512; break;
default:
case 4: tile_split = 1024; break;
case 5: tile_split = 2048; break;
case 6: tile_split = 4096; break;
}
return tile_split;
}
Bool radeon_set_shared_pixmap_backing(PixmapPtr ppix, void *fd_handle,
struct radeon_surface *surface)
{
@ -215,7 +316,22 @@ Bool radeon_set_shared_pixmap_backing(PixmapPtr ppix, void *fd_handle,
memset(surface, 0, sizeof(struct radeon_surface));
radeon_set_pixmap_bo(ppix, bo);
if (info->ChipFamily >= CHIP_FAMILY_R600 && info->surf_man) {
uint32_t tiling_flags;
#ifdef USE_GLAMOR
if (info->use_glamor) {
tiling_flags = radeon_get_pixmap_private(ppix)->tiling_flags;
} else
#endif
{
struct radeon_exa_pixmap_priv *driver_priv;
driver_priv = exaGetPixmapDriverPrivate(ppix);
tiling_flags = driver_priv->tiling_flags;
}
surface->npix_x = ppix->drawable.width;
surface->npix_y = ppix->drawable.height;
@ -229,7 +345,17 @@ Bool radeon_set_shared_pixmap_backing(PixmapPtr ppix, void *fd_handle,
/* we are requiring a recent enough libdrm version */
surface->flags |= RADEON_SURF_HAS_TILE_MODE_INDEX;
surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE);
surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR, MODE);
if (tiling_flags & RADEON_TILING_MACRO)
surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
else if (tiling_flags & RADEON_TILING_MICRO)
surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
else
surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE);
surface->bankw = (tiling_flags >> RADEON_TILING_EG_BANKW_SHIFT) & RADEON_TILING_EG_BANKW_MASK;
surface->bankh = (tiling_flags >> RADEON_TILING_EG_BANKH_SHIFT) & RADEON_TILING_EG_BANKH_MASK;
surface->tile_split = eg_tile_split_opp((tiling_flags >> RADEON_TILING_EG_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_TILE_SPLIT_MASK);
surface->stencil_tile_split = (tiling_flags >> RADEON_TILING_EG_STENCIL_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_STENCIL_TILE_SPLIT_MASK;
surface->mtilea = (tiling_flags >> RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT) & RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK;
if (radeon_surface_best(info->surf_man, surface)) {
return FALSE;
}
@ -241,7 +367,6 @@ Bool radeon_set_shared_pixmap_backing(PixmapPtr ppix, void *fd_handle,
surface->level[0].pitch_bytes = ppix->devKind;
surface->level[0].nblk_x = ppix->devKind / surface->bpe;
}
radeon_set_pixmap_bo(ppix, bo);
close(ihandle);
/* we have a reference from the alloc and one from set pixmap bo,

View File

@ -28,6 +28,12 @@ radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth,
int usage_hint, int bitsPerPixel, int *new_pitch,
struct radeon_surface *new_surface, uint32_t *new_tiling);
extern Bool
radeon_get_pixmap_handle(PixmapPtr pixmap, uint32_t *handle);
extern uint32_t
radeon_get_pixmap_tiling_flags(PixmapPtr pPix);
extern Bool
radeon_share_pixmap_backing(struct radeon_bo *bo, void **handle_p);

View File

@ -612,6 +612,7 @@ static RADEONCardInfo RADEONCards[] = {
{ 0x6610, CHIP_FAMILY_OLAND, 0, 0, 0, 0, 0 },
{ 0x6611, CHIP_FAMILY_OLAND, 0, 0, 0, 0, 0 },
{ 0x6613, CHIP_FAMILY_OLAND, 0, 0, 0, 0, 0 },
{ 0x6617, CHIP_FAMILY_OLAND, 1, 0, 0, 0, 0 },
{ 0x6620, CHIP_FAMILY_OLAND, 1, 0, 0, 0, 0 },
{ 0x6621, CHIP_FAMILY_OLAND, 1, 0, 0, 0, 0 },
{ 0x6623, CHIP_FAMILY_OLAND, 1, 0, 0, 0, 0 },
@ -632,6 +633,7 @@ static RADEONCardInfo RADEONCards[] = {
{ 0x6658, CHIP_FAMILY_BONAIRE, 0, 0, 0, 0, 0 },
{ 0x665C, CHIP_FAMILY_BONAIRE, 0, 0, 0, 0, 0 },
{ 0x665D, CHIP_FAMILY_BONAIRE, 0, 0, 0, 0, 0 },
{ 0x665F, CHIP_FAMILY_BONAIRE, 0, 0, 0, 0, 0 },
{ 0x9830, CHIP_FAMILY_KABINI, 1, 1, 0, 0, 1 },
{ 0x9831, CHIP_FAMILY_KABINI, 0, 1, 0, 0, 1 },
{ 0x9832, CHIP_FAMILY_KABINI, 1, 1, 0, 0, 1 },

View File

@ -612,6 +612,7 @@ SymTabRec RADEONChipsets[] = {
{ PCI_CHIP_OLAND_6610, "OLAND" },
{ PCI_CHIP_OLAND_6611, "OLAND" },
{ PCI_CHIP_OLAND_6613, "OLAND" },
{ PCI_CHIP_OLAND_6617, "OLAND" },
{ PCI_CHIP_OLAND_6620, "OLAND" },
{ PCI_CHIP_OLAND_6621, "OLAND" },
{ PCI_CHIP_OLAND_6623, "OLAND" },
@ -632,6 +633,7 @@ SymTabRec RADEONChipsets[] = {
{ PCI_CHIP_BONAIRE_6658, "BONAIRE" },
{ PCI_CHIP_BONAIRE_665C, "BONAIRE" },
{ PCI_CHIP_BONAIRE_665D, "BONAIRE" },
{ PCI_CHIP_BONAIRE_665F, "BONAIRE" },
{ PCI_CHIP_KABINI_9830, "KABINI" },
{ PCI_CHIP_KABINI_9831, "KABINI" },
{ PCI_CHIP_KABINI_9832, "KABINI" },

File diff suppressed because it is too large Load Diff

View File

@ -43,48 +43,11 @@ struct radeon_dri2 {
Bool radeon_dri2_screen_init(ScreenPtr pScreen);
void radeon_dri2_close_screen(ScreenPtr pScreen);
int drmmode_get_crtc_id(xf86CrtcPtr crtc);
void radeon_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec,
unsigned int tv_usec, void *event_data);
void radeon_dri2_flip_event_handler(unsigned int frame, unsigned int tv_sec,
unsigned int tv_usec, void *event_data);
#else
static inline Bool radeon_dri2_screen_init(ScreenPtr pScreen) { return FALSE; }
static inline void radeon_dri2_close_screen(ScreenPtr pScreen) {}
static inline void
radeon_dri2_dummy_event_handler(unsigned int frame, unsigned int tv_sec,
unsigned int tv_usec, void *event_data,
const char *name)
{
static Bool warned;
if (!warned) {
ErrorF("%s called but DRI2 disabled at build time\n", name);
warned = TRUE;
}
free(event_data);
}
static inline void
radeon_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec,
unsigned int tv_usec, void *event_data)
{
radeon_dri2_dummy_event_handler(frame, tv_sec, tv_usec, event_data,
__func__);
}
static inline void
radeon_dri2_flip_event_handler(unsigned int frame, unsigned int tv_sec,
unsigned int tv_usec, void *event_data)
{
radeon_dri2_dummy_event_handler(frame, tv_sec, tv_usec, event_data,
__func__);
}
#endif
#endif /* RADEON_DRI2_H */

View File

@ -0,0 +1,215 @@
/*
* Copyright © 2013-2014 Intel Corporation
* Copyright © 2015 Advanced Micro Devices, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "radeon.h"
#ifdef HAVE_DRI3_H
#include "radeon_bo_gem.h"
#include "radeon_glamor.h"
#include "dri3.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
static int
radeon_dri3_open(ScreenPtr screen, RRProviderPtr provider, int *out)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
RADEONInfoPtr info = RADEONPTR(scrn);
drm_magic_t magic;
int fd;
fd = open(info->dri2.device_name, O_RDWR | O_CLOEXEC);
if (fd < 0)
return BadAlloc;
/* Before FD passing in the X protocol with DRI3 (and increased
* security of rendering with per-process address spaces on the
* GPU), the kernel had to come up with a way to have the server
* decide which clients got to access the GPU, which was done by
* each client getting a unique (magic) number from the kernel,
* passing it to the server, and the server then telling the
* kernel which clients were authenticated for using the device.
*
* Now that we have FD passing, the server can just set up the
* authentication on its own and hand the prepared FD off to the
* client.
*/
if (drmGetMagic(fd, &magic) < 0) {
if (errno == EACCES) {
/* Assume that we're on a render node, and the fd is
* already as authenticated as it should be.
*/
*out = fd;
return Success;
} else {
close(fd);
return BadMatch;
}
}
if (drmAuthMagic(info->dri2.drm_fd, magic) < 0) {
close(fd);
return BadMatch;
}
*out = fd;
return Success;
}
static PixmapPtr radeon_dri3_pixmap_from_fd(ScreenPtr screen,
int fd,
CARD16 width,
CARD16 height,
CARD16 stride,
CARD8 depth,
CARD8 bpp)
{
PixmapPtr pixmap;
#ifdef USE_GLAMOR
/* Avoid generating a GEM flink name if possible */
if (RADEONPTR(xf86ScreenToScrn(screen))->use_glamor) {
pixmap = glamor_pixmap_from_fd(screen, fd, width, height,
stride, depth, bpp);
if (pixmap) {
struct radeon_pixmap *priv =
calloc(1, sizeof(struct radeon_pixmap));
if (priv) {
radeon_set_pixmap_private(pixmap, priv);
return pixmap;
}
screen->DestroyPixmap(pixmap);
}
}
#endif
if (depth < 8)
return NULL;
switch (bpp) {
case 8:
case 16:
case 32:
break;
default:
return NULL;
}
pixmap = screen->CreatePixmap(screen, 0, 0, depth, RADEON_CREATE_PIXMAP_DRI2);
if (!pixmap)
return NULL;
if (!screen->ModifyPixmapHeader(pixmap, width, height, 0, bpp, stride,
NULL))
goto free_pixmap;
if (screen->SetSharedPixmapBacking(pixmap, (void*)(intptr_t)fd))
return pixmap;
free_pixmap:
fbDestroyPixmap(pixmap);
return NULL;
}
static int radeon_dri3_fd_from_pixmap(ScreenPtr screen,
PixmapPtr pixmap,
CARD16 *stride,
CARD32 *size)
{
struct radeon_bo *bo;
int fd;
bo = radeon_get_pixmap_bo(pixmap);
if (!bo) {
#ifdef USE_GLAMOR
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
RADEONInfoPtr info = RADEONPTR(scrn);
if (info->use_glamor)
return glamor_fd_from_pixmap(screen, pixmap, stride, size);
#endif
exaMoveInPixmap(pixmap);
bo = radeon_get_pixmap_bo(pixmap);
if (!bo)
return -1;
}
if (pixmap->devKind > UINT16_MAX)
return -1;
if (radeon_gem_prime_share_bo(bo, &fd) < 0)
return -1;
*stride = pixmap->devKind;
*size = bo->size;
return fd;
}
static dri3_screen_info_rec radeon_dri3_screen_info = {
.version = 0,
.open = radeon_dri3_open,
.pixmap_from_fd = radeon_dri3_pixmap_from_fd,
.fd_from_pixmap = radeon_dri3_fd_from_pixmap
};
Bool
radeon_dri3_screen_init(ScreenPtr screen)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
if (!dri3_screen_init(screen, &radeon_dri3_screen_info)) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"dri3_screen_init failed\n");
return FALSE;
}
return TRUE;
}
#else /* !HAVE_DRI3_H */
Bool
radeon_dri3_screen_init(ScreenPtr screen)
{
xf86DrvMsg(xf86ScreenToScrn(screen)->scrnIndex, X_INFO,
"Can't initialize DRI3 because dri3.h not available at "
"build time\n");
return FALSE;
}
#endif

View File

@ -0,0 +1,181 @@
/*
* Copyright © 2007 Red Hat, Inc.
* Copyright © 2015 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.
*
* Authors:
* Dave Airlie <airlied@redhat.com>
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <xorg-server.h>
#include "radeon.h"
#include "radeon_drm_queue.h"
#include "radeon_list.h"
struct radeon_drm_queue_entry {
struct xorg_list list;
uint64_t id;
void *data;
ClientPtr client;
ScrnInfoPtr scrn;
radeon_drm_handler_proc handler;
radeon_drm_abort_proc abort;
};
static int radeon_drm_queue_refcnt;
static struct xorg_list radeon_drm_queue;
/*
* Handle a DRM event
*/
void
radeon_drm_queue_handler(int fd, unsigned int frame, unsigned int sec,
unsigned int usec, void *user_ptr)
{
struct radeon_drm_queue_entry *user_data = user_ptr;
struct radeon_drm_queue_entry *e, *tmp;
xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_queue, list) {
if (e == user_data) {
xorg_list_del(&e->list);
e->handler(e->scrn, frame,
(uint64_t)sec * 1000000 + usec, e->data);
free(e);
break;
}
}
}
/*
* Enqueue a potential drm response; when the associated response
* appears, we've got data to pass to the handler from here
*/
struct radeon_drm_queue_entry *
radeon_drm_queue_alloc(ScrnInfoPtr scrn, ClientPtr client,
uint64_t id, void *data,
radeon_drm_handler_proc handler,
radeon_drm_abort_proc abort)
{
struct radeon_drm_queue_entry *e;
e = calloc(1, sizeof(struct radeon_drm_queue_entry));
if (!e)
return NULL;
e->client = client;
e->scrn = scrn;
e->id = id;
e->data = data;
e->handler = handler;
e->abort = abort;
xorg_list_add(&e->list, &radeon_drm_queue);
return e;
}
/*
* Abort one queued DRM entry, removing it
* from the list, calling the abort function and
* freeing the memory
*/
static void
radeon_drm_abort_one(struct radeon_drm_queue_entry *e)
{
xorg_list_del(&e->list);
e->abort(e->scrn, e->data);
free(e);
}
/*
* Abort drm queue entries for a client
*/
void
radeon_drm_abort_client(ClientPtr client)
{
struct radeon_drm_queue_entry *e, *tmp;
xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_queue, list) {
if (e->client == client)
radeon_drm_abort_one(e);
}
}
/*
* Abort specific drm queue entry
*/
void
radeon_drm_abort_entry(struct radeon_drm_queue_entry *entry)
{
radeon_drm_abort_one(entry);
}
/*
* Abort specific drm queue entry by ID
*/
void
radeon_drm_abort_id(uint64_t id)
{
struct radeon_drm_queue_entry *e, *tmp;
xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_queue, list) {
if (e->id == id) {
radeon_drm_abort_one(e);
break;
}
}
}
/*
* Initialize the DRM event queue
*/
void
radeon_drm_queue_init()
{
if (radeon_drm_queue_refcnt++)
return;
xorg_list_init(&radeon_drm_queue);
}
/*
* Deinitialize the DRM event queue
*/
void
radeon_drm_queue_close(ScrnInfoPtr scrn)
{
struct radeon_drm_queue_entry *e, *tmp;
xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_queue, list) {
if (e->scrn == scrn)
radeon_drm_abort_one(e);
}
radeon_drm_queue_refcnt--;
}

View File

@ -0,0 +1,56 @@
/*
* Copyright © 2007 Red Hat, Inc.
* Copyright © 2015 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.
*
* Authors:
* Dave Airlie <airlied@redhat.com>
*
*/
#ifndef _RADEON_DRM_QUEUE_H_
#define _RADEON_DRM_QUEUE_H_
#define RADEON_DRM_QUEUE_CLIENT_DEFAULT serverClient
#define RADEON_DRM_QUEUE_ID_DEFAULT ~0ULL
struct radeon_drm_queue_entry;
typedef void (*radeon_drm_handler_proc)(ScrnInfoPtr scrn, uint32_t seq,
uint64_t usec, void *data);
typedef void (*radeon_drm_abort_proc)(ScrnInfoPtr scrn, void *data);
void radeon_drm_queue_handler(int fd, unsigned int frame,
unsigned int tv_sec, unsigned int tv_usec,
void *user_ptr);
struct radeon_drm_queue_entry *radeon_drm_queue_alloc(ScrnInfoPtr scrn,
ClientPtr client,
uint64_t id,
void *data,
radeon_drm_handler_proc handler,
radeon_drm_abort_proc abort);
void radeon_drm_abort_client(ClientPtr client);
void radeon_drm_abort_entry(struct radeon_drm_queue_entry *entry);
void radeon_drm_abort_id(uint64_t id);
void radeon_drm_queue_init();
void radeon_drm_queue_close(ScrnInfoPtr scrn);
#endif /* _RADEON_DRM_QUEUE_H_ */

View File

@ -330,7 +330,6 @@ Bool RADEONEXASetSharedPixmapBacking(PixmapPtr ppix, void *fd_handle)
return FALSE;
driver_priv->shared = TRUE;
driver_priv->tiling_flags = 0;
return TRUE;
}
#endif

View File

@ -29,11 +29,10 @@
#endif
#include <xf86.h>
#define GLAMOR_FOR_XORG 1
#include <glamor.h>
#include "radeon.h"
#include "radeon_bo_helper.h"
#include "radeon_glamor.h"
#if HAS_DEVPRIVATEKEYREC
DevPrivateKeyRec glamor_pixmap_index;
@ -61,8 +60,10 @@ radeon_glamor_create_screen_resources(ScreenPtr screen)
if (!info->use_glamor)
return TRUE;
#ifdef HAVE_GLAMOR_GLYPHS_INIT
if (!glamor_glyphs_init(screen))
return FALSE;
#endif
if (!glamor_egl_create_textured_screen_ext(screen,
info->front_bo->handle,
@ -152,51 +153,30 @@ radeon_glamor_pre_init(ScrnInfoPtr scrn)
}
Bool
radeon_glamor_create_textured_pixmap(PixmapPtr pixmap)
radeon_glamor_create_textured_pixmap(PixmapPtr pixmap, struct radeon_pixmap *priv)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen);
RADEONInfoPtr info = RADEONPTR(scrn);
struct radeon_pixmap *priv;
if ((info->use_glamor) == 0)
return TRUE;
priv = radeon_get_pixmap_private(pixmap);
if (!priv->stride)
priv->stride = pixmap->devKind;
if (glamor_egl_create_textured_pixmap(pixmap, priv->bo->handle,
priv->stride))
return TRUE;
else
return FALSE;
return glamor_egl_create_textured_pixmap(pixmap, priv->bo->handle,
pixmap->devKind);
}
Bool radeon_glamor_pixmap_is_offscreen(PixmapPtr pixmap)
{
struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap);
return priv && priv->bo;
}
#ifndef CREATE_PIXMAP_USAGE_SHARED
#define CREATE_PIXMAP_USAGE_SHARED RADEON_CREATE_PIXMAP_DRI2
#endif
#define RADEON_CREATE_PIXMAP_SHARED(usage) \
(((usage) & ~RADEON_CREATE_PIXMAP_TILING_FLAGS) == RADEON_CREATE_PIXMAP_DRI2 || \
(usage) == CREATE_PIXMAP_USAGE_SHARED)
static PixmapPtr
radeon_glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
unsigned usage)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
RADEONInfoPtr info = RADEONPTR(scrn);
struct radeon_pixmap *priv;
PixmapPtr pixmap, new_pixmap = NULL;
if (!RADEON_CREATE_PIXMAP_SHARED(usage)) {
pixmap = glamor_create_pixmap(screen, w, h, depth, usage);
if (pixmap)
return pixmap;
if (info->shadow_primary) {
if (usage != CREATE_PIXMAP_USAGE_BACKING_PIXMAP)
return fbCreatePixmap(screen, w, h, depth, usage);
} else {
pixmap = glamor_create_pixmap(screen, w, h, depth, usage);
if (pixmap)
return pixmap;
}
}
if (w > 32767 || h > 32767)
@ -213,13 +193,15 @@ radeon_glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
return pixmap;
if (w && h) {
int stride;
priv = calloc(1, sizeof (struct radeon_pixmap));
if (priv == NULL)
goto fallback_pixmap;
priv->bo = radeon_alloc_pixmap_bo(scrn, w, h, depth, usage,
pixmap->drawable.bitsPerPixel,
&priv->stride,
&stride,
&priv->surface,
&priv->tiling_flags);
if (!priv->bo)
@ -227,10 +209,12 @@ radeon_glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
radeon_set_pixmap_private(pixmap, priv);
screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, priv->stride, NULL);
screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, stride, NULL);
if (!radeon_glamor_create_textured_pixmap(pixmap))
if (!radeon_glamor_create_textured_pixmap(pixmap, priv))
goto fallback_glamor;
pixmap->devPrivate.ptr = NULL;
}
return pixmap;
@ -269,6 +253,13 @@ fallback_pixmap:
static Bool radeon_glamor_destroy_pixmap(PixmapPtr pixmap)
{
if (pixmap->refcnt == 1) {
if (pixmap->devPrivate.ptr) {
struct radeon_bo *bo = radeon_get_pixmap_bo(pixmap);
if (bo)
radeon_bo_unmap(bo);
}
glamor_egl_destroy_textured_pixmap(pixmap);
radeon_set_pixmap_bo(pixmap, NULL);
}
@ -302,11 +293,9 @@ radeon_glamor_set_shared_pixmap_backing(PixmapPtr pixmap, void *handle)
return FALSE;
priv = radeon_get_pixmap_private(pixmap);
priv->stride = pixmap->devKind;
priv->surface = surface;
priv->tiling_flags = 0;
if (!radeon_glamor_create_textured_pixmap(pixmap)) {
if (!radeon_glamor_create_textured_pixmap(pixmap, priv)) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
"Failed to get PRIME drawable for glamor pixmap.\n");
return FALSE;
@ -315,9 +304,7 @@ radeon_glamor_set_shared_pixmap_backing(PixmapPtr pixmap, void *handle)
screen->ModifyPixmapHeader(pixmap,
pixmap->drawable.width,
pixmap->drawable.height,
0, 0,
priv->stride,
NULL);
0, 0, 0, NULL);
return TRUE;
}
@ -328,12 +315,30 @@ Bool
radeon_glamor_init(ScreenPtr screen)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
if (!glamor_init(screen, GLAMOR_INVERTED_Y_AXIS | GLAMOR_USE_EGL_SCREEN |
#ifdef GLAMOR_NO_DRI3
GLAMOR_NO_DRI3 |
RADEONInfoPtr info = RADEONPTR(scrn);
#ifdef RENDER
#ifdef HAVE_FBGLYPHS
UnrealizeGlyphProcPtr SavedUnrealizeGlyph = NULL;
#endif
GLAMOR_USE_SCREEN | GLAMOR_USE_PICTURE_SCREEN)) {
PictureScreenPtr ps = NULL;
if (info->shadow_primary) {
ps = GetPictureScreenIfSet(screen);
if (ps) {
#ifdef HAVE_FBGLYPHS
SavedUnrealizeGlyph = ps->UnrealizeGlyph;
#endif
info->glamor.SavedGlyphs = ps->Glyphs;
info->glamor.SavedTriangles = ps->Triangles;
info->glamor.SavedTrapezoids = ps->Trapezoids;
}
}
#endif /* RENDER */
if (!glamor_init(screen, GLAMOR_USE_EGL_SCREEN | GLAMOR_USE_SCREEN |
GLAMOR_USE_PICTURE_SCREEN | GLAMOR_INVERTED_Y_AXIS |
GLAMOR_NO_DRI3)) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
"Failed to initialize glamor.\n");
return FALSE;
@ -352,6 +357,17 @@ radeon_glamor_init(ScreenPtr screen)
#endif
return FALSE;
if (info->shadow_primary)
radeon_glamor_screen_init(screen);
#if defined(RENDER) && defined(HAVE_FBGLYPHS)
/* For ShadowPrimary, we need fbUnrealizeGlyph instead of
* glamor_unrealize_glyph
*/
if (ps)
ps->UnrealizeGlyph = SavedUnrealizeGlyph;
#endif
screen->CreatePixmap = radeon_glamor_create_pixmap;
screen->DestroyPixmap = radeon_glamor_destroy_pixmap;
#ifdef RADEON_PIXMAP_SHARING
@ -364,15 +380,6 @@ radeon_glamor_init(ScreenPtr screen)
return TRUE;
}
void
radeon_glamor_flush(ScrnInfoPtr pScrn)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
if (info->use_glamor)
glamor_block_handler(pScrn->pScreen);
}
XF86VideoAdaptorPtr radeon_glamor_xv_init(ScreenPtr pScreen, int num_adapt)
{
return glamor_xv_init(pScreen, num_adapt);

View File

@ -28,52 +28,51 @@
#define RADEON_GLAMOR_H
#include "xf86xv.h"
struct radeon_pixmap;
#ifdef USE_GLAMOR
#define GLAMOR_FOR_XORG 1
#include <glamor.h>
#include "radeon_surface.h"
#ifndef CREATE_PIXMAP_USAGE_SHARED
#define CREATE_PIXMAP_USAGE_SHARED RADEON_CREATE_PIXMAP_DRI2
#endif
#define RADEON_CREATE_PIXMAP_SHARED(usage) \
(((usage) & ~RADEON_CREATE_PIXMAP_TILING_FLAGS) == RADEON_CREATE_PIXMAP_DRI2 || \
(usage) == CREATE_PIXMAP_USAGE_SHARED)
#ifndef GLAMOR_NO_DRI3
#define GLAMOR_NO_DRI3 0
#define glamor_fd_from_pixmap glamor_dri3_fd_from_pixmap
#define glamor_pixmap_from_fd glamor_egl_dri3_pixmap_from_fd
#endif
#ifndef GLAMOR_INVERTED_Y_AXIS
#define GLAMOR_INVERTED_Y_AXIS 0
#endif
#ifndef GLAMOR_USE_SCREEN
#define GLAMOR_USE_SCREEN 0
#endif
#ifndef GLAMOR_USE_PICTURE_SCREEN
#define GLAMOR_USE_PICTURE_SCREEN 0
#endif
Bool radeon_glamor_pre_init(ScrnInfoPtr scrn);
Bool radeon_glamor_init(ScreenPtr screen);
void radeon_glamor_screen_init(ScreenPtr screen);
Bool radeon_glamor_create_screen_resources(ScreenPtr screen);
void radeon_glamor_free_screen(int scrnIndex, int flags);
void radeon_glamor_flush(ScrnInfoPtr pScrn);
Bool radeon_glamor_create_textured_pixmap(PixmapPtr pixmap);
Bool radeon_glamor_create_textured_pixmap(PixmapPtr pixmap, struct radeon_pixmap *priv);
void radeon_glamor_exchange_buffers(PixmapPtr src, PixmapPtr dst);
Bool radeon_glamor_pixmap_is_offscreen(PixmapPtr pixmap);
XF86VideoAdaptorPtr radeon_glamor_xv_init(ScreenPtr pScreen, int num_adapt);
struct radeon_pixmap {
struct radeon_surface surface;
struct radeon_bo *bo;
uint32_t tiling_flags;
int stride;
};
#if HAS_DEVPRIVATEKEYREC
extern DevPrivateKeyRec glamor_pixmap_index;
#else
extern int glamor_pixmap_index;
#endif
static inline struct radeon_pixmap *radeon_get_pixmap_private(PixmapPtr pixmap)
{
#if HAS_DEVPRIVATEKEYREC
return dixGetPrivate(&pixmap->devPrivates, &glamor_pixmap_index);
#else
return dixLookupPrivate(&pixmap->devPrivates, &glamor_pixmap_index);
#endif
}
static inline void radeon_set_pixmap_private(PixmapPtr pixmap, struct radeon_pixmap *priv)
{
dixSetPrivate(&pixmap->devPrivates, &glamor_pixmap_index, priv);
}
#else
static inline Bool radeon_glamor_pre_init(ScrnInfoPtr scrn) { return FALSE; }
@ -81,14 +80,10 @@ static inline Bool radeon_glamor_init(ScreenPtr screen) { return FALSE; }
static inline Bool radeon_glamor_create_screen_resources(ScreenPtr screen) { return FALSE; }
static inline void radeon_glamor_free_screen(int scrnIndex, int flags) { }
static inline void radeon_glamor_flush(ScrnInfoPtr pScrn) { }
static inline Bool radeon_glamor_create_textured_pixmap(PixmapPtr pixmap) { return TRUE; }
static inline Bool radeon_glamor_create_textured_pixmap(PixmapPtr pixmap, struct radeon_pixmap *priv) { return TRUE; }
static inline void radeon_glamor_exchange_buffers(PixmapPtr src, PixmapPtr dst) {}
static inline Bool radeon_glamor_pixmap_is_offscreen(PixmapPtr pixmap) { return FALSE; }
static inline struct radeon_pixmap *radeon_get_pixmap_private(PixmapPtr pixmap) { return NULL; }
static inline XF86VideoAdaptorPtr radeon_glamor_xv_init(ScreenPtr pScreen, int num_adapt) { return NULL; }

View File

@ -0,0 +1,994 @@
/*
* Copyright © 2001 Keith Packard
* 2010 Intel Corporation
* 2012,2015 Advanced Micro Devices, Inc.
*
* Partly based on code Copyright © 2008 Red Hat, Inc.
* Partly based on code Copyright © 2000 SuSE, Inc.
*
* Partly based on code that is Copyright © The XFree86 Project Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of the opyright holders not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. The copyright holders make no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef USE_GLAMOR
#include "radeon.h"
#include "radeon_glamor.h"
/**
* get_drawable_pixmap() returns the backing pixmap for a given drawable.
*
* @param pDrawable the drawable being requested.
*
* This function returns the backing pixmap for a drawable, whether it is a
* redirected window, unredirected window, or already a pixmap.
*/
static PixmapPtr
get_drawable_pixmap(DrawablePtr pDrawable)
{
if (pDrawable->type == DRAWABLE_WINDOW)
return pDrawable->pScreen->
GetWindowPixmap((WindowPtr) pDrawable);
else
return (PixmapPtr) pDrawable;
}
/* Are there any outstanding GPU operations for this pixmap? */
static Bool
radeon_glamor_gpu_pending(uint_fast32_t gpu_synced, uint_fast32_t gpu_access)
{
return (int_fast32_t)(gpu_access - gpu_synced) > 0;
}
/*
* Pixmap CPU access wrappers
*/
static Bool
radeon_glamor_prepare_access_cpu(ScrnInfoPtr scrn, RADEONInfoPtr info,
PixmapPtr pixmap, struct radeon_pixmap *priv,
Bool need_sync)
{
struct radeon_bo *bo = priv->bo;
int ret;
/* When falling back to swrast, flush all pending operations */
if (need_sync) {
glamor_block_handler(scrn->pScreen);
info->gpu_flushed++;
}
if (!pixmap->devPrivate.ptr) {
ret = radeon_bo_map(bo, 1);
if (ret) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"%s: bo map (tiling_flags %d) failed: %s\n",
__FUNCTION__,
priv->tiling_flags,
strerror(-ret));
return FALSE;
}
pixmap->devPrivate.ptr = bo->ptr;
info->gpu_synced = info->gpu_flushed;
} else if (need_sync) {
radeon_bo_wait(bo);
info->gpu_synced = info->gpu_flushed;
}
return TRUE;
}
static Bool
radeon_glamor_prepare_access_cpu_ro(ScrnInfoPtr scrn, PixmapPtr pixmap,
struct radeon_pixmap *priv)
{
RADEONInfoPtr info;
Bool need_sync;
if (!priv)
return TRUE;
info = RADEONPTR(scrn);
need_sync = radeon_glamor_gpu_pending(info->gpu_synced, priv->gpu_write);
return radeon_glamor_prepare_access_cpu(scrn, RADEONPTR(scrn), pixmap,
priv, need_sync);
}
static Bool
radeon_glamor_prepare_access_cpu_rw(ScrnInfoPtr scrn, PixmapPtr pixmap,
struct radeon_pixmap *priv)
{
RADEONInfoPtr info;
uint_fast32_t gpu_synced;
Bool need_sync;
if (!priv)
return TRUE;
info = RADEONPTR(scrn);
gpu_synced = info->gpu_synced;
need_sync = radeon_glamor_gpu_pending(gpu_synced, priv->gpu_write) |
radeon_glamor_gpu_pending(gpu_synced, priv->gpu_read);
return radeon_glamor_prepare_access_cpu(scrn, info, pixmap, priv,
need_sync);
}
static void
radeon_glamor_finish_access_cpu(PixmapPtr pixmap)
{
/* Nothing to do */
}
/*
* Pixmap GPU access wrappers
*/
static Bool
radeon_glamor_prepare_access_gpu(struct radeon_pixmap *priv)
{
return priv != NULL;
}
static void
radeon_glamor_finish_access_gpu_ro(RADEONInfoPtr info,
struct radeon_pixmap *priv)
{
priv->gpu_read = info->gpu_flushed + 1;
}
static void
radeon_glamor_finish_access_gpu_rw(RADEONInfoPtr info,
struct radeon_pixmap *priv)
{
priv->gpu_write = priv->gpu_read = info->gpu_flushed + 1;
}
/*
* GC CPU access wrappers
*/
static Bool
radeon_glamor_prepare_access_gc(ScrnInfoPtr scrn, GCPtr pGC)
{
struct radeon_pixmap *priv;
if (pGC->stipple) {
priv = radeon_get_pixmap_private(pGC->stipple);
if (!radeon_glamor_prepare_access_cpu_ro(scrn, pGC->stipple, priv))
return FALSE;
}
if (pGC->fillStyle == FillTiled) {
priv = radeon_get_pixmap_private(pGC->tile.pixmap);
if (!radeon_glamor_prepare_access_cpu_ro(scrn, pGC->tile.pixmap,
priv)) {
if (pGC->stipple)
radeon_glamor_finish_access_cpu(pGC->stipple);
return FALSE;
}
}
return TRUE;
}
static void
radeon_glamor_finish_access_gc(GCPtr pGC)
{
if (pGC->fillStyle == FillTiled)
radeon_glamor_finish_access_cpu(pGC->tile.pixmap);
if (pGC->stipple)
radeon_glamor_finish_access_cpu(pGC->stipple);
}
/*
* Picture CPU access wrappers
*/
static void
radeon_glamor_picture_finish_access_cpu(PicturePtr picture)
{
/* Nothing to do */
}
static Bool
radeon_glamor_picture_prepare_access_cpu_ro(ScrnInfoPtr scrn,
PicturePtr picture)
{
PixmapPtr pixmap;
struct radeon_pixmap *priv;
if (picture->pDrawable == NULL)
return TRUE;
pixmap = get_drawable_pixmap(picture->pDrawable);
priv = radeon_get_pixmap_private(pixmap);
if (!radeon_glamor_prepare_access_cpu_ro(scrn, pixmap, priv))
return FALSE;
if (picture->alphaMap) {
pixmap = get_drawable_pixmap(picture->alphaMap->pDrawable);
priv = radeon_get_pixmap_private(pixmap);
if (!radeon_glamor_prepare_access_cpu_ro(scrn, pixmap, priv)) {
radeon_glamor_picture_finish_access_cpu(picture);
return FALSE;
}
}
return TRUE;
}
static Bool
radeon_glamor_picture_prepare_access_cpu_rw(ScrnInfoPtr scrn,
PicturePtr picture)
{
PixmapPtr pixmap;
struct radeon_pixmap *priv;
pixmap = get_drawable_pixmap(picture->pDrawable);
priv = radeon_get_pixmap_private(pixmap);
if (!radeon_glamor_prepare_access_cpu_rw(scrn, pixmap, priv))
return FALSE;
if (picture->alphaMap) {
pixmap = get_drawable_pixmap(picture->alphaMap->pDrawable);
priv = radeon_get_pixmap_private(pixmap);
if (!radeon_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) {
radeon_glamor_picture_finish_access_cpu(picture);
return FALSE;
}
}
return TRUE;
}
/*
* GC rendering wrappers
*/
static void
radeon_glamor_fill_spans(DrawablePtr pDrawable, GCPtr pGC, int nspans,
DDXPointPtr ppt, int *pwidth, int fSorted)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen);
PixmapPtr pixmap = get_drawable_pixmap(pDrawable);
struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap);
if (radeon_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) {
if (radeon_glamor_prepare_access_gc(scrn, pGC)) {
fbFillSpans(pDrawable, pGC, nspans, ppt, pwidth,
fSorted);
radeon_glamor_finish_access_gc(pGC);
}
radeon_glamor_finish_access_cpu(pixmap);
}
}
static void
radeon_glamor_set_spans(DrawablePtr pDrawable, GCPtr pGC, char *psrc,
DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen);
PixmapPtr pixmap = get_drawable_pixmap(pDrawable);
struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap);
if (radeon_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) {
fbSetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
radeon_glamor_finish_access_cpu(pixmap);
}
}
static void
radeon_glamor_put_image(DrawablePtr pDrawable, GCPtr pGC, int depth,
int x, int y, int w, int h, int leftPad, int format,
char *bits)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen);
PixmapPtr pixmap = get_drawable_pixmap(pDrawable);
struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap);
if (radeon_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) {
fbPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format,
bits);
radeon_glamor_finish_access_cpu(pixmap);
}
}
static RegionPtr
radeon_glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
int srcx, int srcy, int w, int h, int dstx, int dsty,
unsigned long bitPlane)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(pDst->pScreen);
PixmapPtr dst_pix = get_drawable_pixmap(pDst);
struct radeon_pixmap *dst_priv = radeon_get_pixmap_private(dst_pix);
RegionPtr ret = NULL;
if (radeon_glamor_prepare_access_cpu_rw(scrn, dst_pix, dst_priv)) {
PixmapPtr src_pix = get_drawable_pixmap(pSrc);
struct radeon_pixmap *src_priv = radeon_get_pixmap_private(src_pix);
if (radeon_glamor_prepare_access_cpu_ro(scrn, src_pix, src_priv)) {
ret =
fbCopyPlane(pSrc, pDst, pGC, srcx, srcy, w, h, dstx,
dsty, bitPlane);
radeon_glamor_finish_access_cpu(src_pix);
}
radeon_glamor_finish_access_cpu(dst_pix);
}
return ret;
}
static RegionPtr
radeon_glamor_copy_plane_nodstbo(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
int srcx, int srcy, int w, int h,
int dstx, int dsty, unsigned long bitPlane)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(pDst->pScreen);
PixmapPtr src_pix = get_drawable_pixmap(pSrc);
struct radeon_pixmap *src_priv = radeon_get_pixmap_private(src_pix);
RegionPtr ret = NULL;
if (radeon_glamor_prepare_access_cpu_ro(scrn, src_pix, src_priv)) {
ret = fbCopyPlane(pSrc, pDst, pGC, srcx, srcy, w, h,
dstx, dsty, bitPlane);
radeon_glamor_finish_access_cpu(src_pix);
}
return ret;
}
static void
radeon_glamor_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
DDXPointPtr pptInit)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen);
PixmapPtr pixmap = get_drawable_pixmap(pDrawable);
struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap);
if (radeon_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) {
fbPolyPoint(pDrawable, pGC, mode, npt, pptInit);
radeon_glamor_finish_access_cpu(pixmap);
}
}
static void
radeon_glamor_poly_lines(DrawablePtr pDrawable, GCPtr pGC,
int mode, int npt, DDXPointPtr ppt)
{
if (pGC->lineWidth == 0) {
ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen);
PixmapPtr pixmap = get_drawable_pixmap(pDrawable);
struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap);
if (radeon_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) {
if (radeon_glamor_prepare_access_gc(scrn, pGC)) {
fbPolyLine(pDrawable, pGC, mode, npt, ppt);
radeon_glamor_finish_access_gc(pGC);
}
radeon_glamor_finish_access_cpu(pixmap);
}
return;
}
/* fb calls mi functions in the lineWidth != 0 case. */
fbPolyLine(pDrawable, pGC, mode, npt, ppt);
}
static void
radeon_glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC,
int nsegInit, xSegment *pSegInit)
{
if (pGC->lineWidth == 0) {
ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen);
PixmapPtr pixmap = get_drawable_pixmap(pDrawable);
struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap);
if (radeon_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) {
if (radeon_glamor_prepare_access_gc(scrn, pGC)) {
fbPolySegment(pDrawable, pGC, nsegInit,
pSegInit);
radeon_glamor_finish_access_gc(pGC);
}
radeon_glamor_finish_access_cpu(pixmap);
}
return;
}
/* fb calls mi functions in the lineWidth != 0 case. */
fbPolySegment(pDrawable, pGC, nsegInit, pSegInit);
}
static void
radeon_glamor_poly_fill_rect(DrawablePtr pDrawable, GCPtr pGC,
int nrect, xRectangle *prect)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen);
RADEONInfoPtr info = RADEONPTR(scrn);
PixmapPtr pixmap = get_drawable_pixmap(pDrawable);
struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap);
if ((info->accel_state->force || (priv && !priv->bo)) &&
radeon_glamor_prepare_access_gpu(priv)) {
info->glamor.SavedPolyFillRect(pDrawable, pGC, nrect, prect);
radeon_glamor_finish_access_gpu_rw(info, priv);
return;
}
if (radeon_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) {
if (radeon_glamor_prepare_access_gc(scrn, pGC)) {
fbPolyFillRect(pDrawable, pGC, nrect, prect);
radeon_glamor_finish_access_gc(pGC);
}
radeon_glamor_finish_access_cpu(pixmap);
}
}
static void
radeon_glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, unsigned int nglyph,
CharInfoPtr *ppci, pointer pglyphBase)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen);
PixmapPtr pixmap = get_drawable_pixmap(pDrawable);
struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap);
if (radeon_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) {
if (radeon_glamor_prepare_access_gc(scrn, pGC)) {
fbImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci,
pglyphBase);
radeon_glamor_finish_access_gc(pGC);
}
radeon_glamor_finish_access_cpu(pixmap);
}
}
static void
radeon_glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, unsigned int nglyph,
CharInfoPtr *ppci, pointer pglyphBase)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen);
PixmapPtr pixmap = get_drawable_pixmap(pDrawable);
struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap);
if (radeon_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) {
if (radeon_glamor_prepare_access_gc(scrn, pGC)) {
fbPolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci,
pglyphBase);
radeon_glamor_finish_access_gc(pGC);
}
radeon_glamor_finish_access_cpu(pixmap);
}
}
static void
radeon_glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap,
DrawablePtr pDrawable, int w, int h, int x, int y)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen);
PixmapPtr pixmap = get_drawable_pixmap(pDrawable);
struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap);
if (radeon_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) {
priv = radeon_get_pixmap_private(pBitmap);
if (radeon_glamor_prepare_access_cpu_ro(scrn, pBitmap, priv)) {
if (radeon_glamor_prepare_access_gc(scrn, pGC)) {
fbPushPixels(pGC, pBitmap, pDrawable, w, h, x,
y);
radeon_glamor_finish_access_gc(pGC);
}
radeon_glamor_finish_access_cpu(pBitmap);
}
radeon_glamor_finish_access_cpu(pixmap);
}
}
static void
radeon_glamor_push_pixels_nodstbo(GCPtr pGC, PixmapPtr pBitmap,
DrawablePtr pDrawable, int w, int h,
int x, int y)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen);
struct radeon_pixmap *priv = radeon_get_pixmap_private(pBitmap);
if (radeon_glamor_prepare_access_cpu_ro(scrn, pBitmap, priv)) {
fbPushPixels(pGC, pBitmap, pDrawable, w, h, x, y);
radeon_glamor_finish_access_cpu(pBitmap);
}
}
static RegionPtr
radeon_glamor_copy_area(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
GCPtr pGC, int srcx, int srcy, int width, int height,
int dstx, int dsty)
{
ScreenPtr screen = pDstDrawable->pScreen;
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
RADEONInfoPtr info = RADEONPTR(scrn);
PixmapPtr src_pixmap = get_drawable_pixmap(pSrcDrawable);
PixmapPtr dst_pixmap = get_drawable_pixmap(pDstDrawable);
struct radeon_pixmap *src_priv = radeon_get_pixmap_private(src_pixmap);
struct radeon_pixmap *dst_priv = radeon_get_pixmap_private(dst_pixmap);
RegionPtr ret = NULL;
if (info->accel_state->force || (src_priv && !src_priv->bo) ||
(dst_priv && !dst_priv->bo)) {
if (!radeon_glamor_prepare_access_gpu(dst_priv))
goto fallback;
if (src_priv != dst_priv &&
!radeon_glamor_prepare_access_gpu(src_priv))
goto fallback;
ret = info->glamor.SavedCopyArea(pSrcDrawable, pDstDrawable,
pGC, srcx, srcy,
width, height, dstx, dsty);
radeon_glamor_finish_access_gpu_rw(info, dst_priv);
if (src_priv != dst_priv)
radeon_glamor_finish_access_gpu_ro(info, src_priv);
return ret;
}
fallback:
if (radeon_glamor_prepare_access_cpu_rw(scrn, dst_pixmap, dst_priv)) {
if (pSrcDrawable == pDstDrawable ||
radeon_glamor_prepare_access_cpu_ro(scrn, src_pixmap,
src_priv)) {
ret = fbCopyArea(pSrcDrawable, pDstDrawable, pGC,
srcx, srcy, width, height, dstx, dsty);
if (pSrcDrawable != pDstDrawable)
radeon_glamor_finish_access_cpu(src_pixmap);
}
radeon_glamor_finish_access_cpu(dst_pixmap);
}
return ret;
}
static RegionPtr
radeon_glamor_copy_area_nodstbo(DrawablePtr pSrcDrawable,
DrawablePtr pDstDrawable, GCPtr pGC,
int srcx, int srcy, int width, int height,
int dstx, int dsty)
{
ScreenPtr screen = pDstDrawable->pScreen;
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
PixmapPtr src_pixmap = get_drawable_pixmap(pSrcDrawable);
PixmapPtr dst_pixmap = get_drawable_pixmap(pDstDrawable);
struct radeon_pixmap *src_priv;
RegionPtr ret = NULL;
if (src_pixmap != dst_pixmap) {
src_priv = radeon_get_pixmap_private(src_pixmap);
if (!radeon_glamor_prepare_access_cpu_ro(scrn, src_pixmap,
src_priv))
return ret;
}
ret = fbCopyArea(pSrcDrawable, pDstDrawable, pGC, srcx, srcy,
width, height, dstx, dsty);
if (src_pixmap != dst_pixmap)
radeon_glamor_finish_access_cpu(src_pixmap);
return ret;
}
static const GCOps radeon_glamor_ops = {
radeon_glamor_fill_spans,
radeon_glamor_set_spans,
radeon_glamor_put_image,
radeon_glamor_copy_area,
radeon_glamor_copy_plane,
radeon_glamor_poly_point,
radeon_glamor_poly_lines,
radeon_glamor_poly_segment,
miPolyRectangle,
miPolyArc,
miFillPolygon,
radeon_glamor_poly_fill_rect,
miPolyFillArc,
miPolyText8,
miPolyText16,
miImageText8,
miImageText16,
radeon_glamor_image_glyph_blt,
radeon_glamor_poly_glyph_blt,
radeon_glamor_push_pixels,
};
static GCOps radeon_glamor_nodstbo_ops;
/**
* radeon_glamor_validate_gc() sets the ops to our implementations, which may be
* accelerated or may sync the card and fall back to fb.
*/
static void
radeon_glamor_validate_gc(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(pGC->pScreen);
RADEONInfoPtr info = RADEONPTR(scrn);
glamor_validate_gc(pGC, changes, pDrawable);
info->glamor.SavedCopyArea = pGC->ops->CopyArea;
info->glamor.SavedPolyFillRect = pGC->ops->PolyFillRect;
if (radeon_get_pixmap_private(get_drawable_pixmap(pDrawable)) ||
(pGC->stipple && radeon_get_pixmap_private(pGC->stipple)) ||
(pGC->fillStyle == FillTiled &&
radeon_get_pixmap_private(pGC->tile.pixmap)))
pGC->ops = (GCOps *)&radeon_glamor_ops;
else
pGC->ops = &radeon_glamor_nodstbo_ops;
}
static GCFuncs glamorGCFuncs = {
radeon_glamor_validate_gc,
miChangeGC,
miCopyGC,
miDestroyGC,
miChangeClip,
miDestroyClip,
miCopyClip
};
/**
* radeon_glamor_create_gc makes a new GC and hooks up its funcs handler, so that
* radeon_glamor_validate_gc() will get called.
*/
static int
radeon_glamor_create_gc(GCPtr pGC)
{
static Bool nodstbo_ops_initialized;
if (!fbCreateGC(pGC))
return FALSE;
if (!nodstbo_ops_initialized) {
radeon_glamor_nodstbo_ops = radeon_glamor_ops;
radeon_glamor_nodstbo_ops.FillSpans = pGC->ops->FillSpans;
radeon_glamor_nodstbo_ops.SetSpans = pGC->ops->SetSpans;
radeon_glamor_nodstbo_ops.PutImage = pGC->ops->PutImage;
radeon_glamor_nodstbo_ops.CopyArea = radeon_glamor_copy_area_nodstbo;
radeon_glamor_nodstbo_ops.CopyPlane = radeon_glamor_copy_plane_nodstbo;
radeon_glamor_nodstbo_ops.PolyPoint = pGC->ops->PolyPoint;
radeon_glamor_nodstbo_ops.Polylines = pGC->ops->Polylines;
radeon_glamor_nodstbo_ops.PolySegment = pGC->ops->PolySegment;
radeon_glamor_nodstbo_ops.PolyFillRect = pGC->ops->PolyFillRect;
radeon_glamor_nodstbo_ops.ImageGlyphBlt = pGC->ops->ImageGlyphBlt;
radeon_glamor_nodstbo_ops.PolyGlyphBlt = pGC->ops->PolyGlyphBlt;
radeon_glamor_nodstbo_ops.PushPixels = radeon_glamor_push_pixels_nodstbo;
nodstbo_ops_initialized = TRUE;
}
pGC->funcs = &glamorGCFuncs;
return TRUE;
}
/*
* Screen rendering wrappers
*/
static RegionPtr
radeon_glamor_bitmap_to_region(PixmapPtr pPix)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(pPix->drawable.pScreen);
struct radeon_pixmap *priv = radeon_get_pixmap_private(pPix);
RegionPtr ret;
if (!radeon_glamor_prepare_access_cpu_ro(scrn, pPix, priv))
return NULL;
ret = fbPixmapToRegion(pPix);
radeon_glamor_finish_access_cpu(pPix);
return ret;
}
static void
radeon_glamor_copy_window(WindowPtr pWin, DDXPointRec ptOldOrg,
RegionPtr prgnSrc)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(pWin->drawable.pScreen);
PixmapPtr pixmap = get_drawable_pixmap(&pWin->drawable);
struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap);
if (radeon_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) {
fbCopyWindow(pWin, ptOldOrg, prgnSrc);
radeon_glamor_finish_access_cpu(pixmap);
}
}
static void
radeon_glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h,
unsigned int format, unsigned long planeMask, char *d)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen);
PixmapPtr pixmap = get_drawable_pixmap(pDrawable);
struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap);
if (radeon_glamor_prepare_access_cpu_ro(scrn, pixmap, priv)) {
fbGetImage(pDrawable, x, y, w, h, format, planeMask, d);
radeon_glamor_finish_access_cpu(pixmap);
}
}
static void
radeon_glamor_get_spans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt,
int *pwidth, int nspans, char *pdstStart)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen);
PixmapPtr pixmap = get_drawable_pixmap(pDrawable);
struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap);
if (radeon_glamor_prepare_access_cpu_ro(scrn, pixmap, priv)) {
fbGetSpans(pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
radeon_glamor_finish_access_cpu(pixmap);
}
}
/*
* Picture screen rendering wrappers
*/
#ifdef RENDER
static void
radeon_glamor_composite(CARD8 op,
PicturePtr pSrc,
PicturePtr pMask,
PicturePtr pDst,
INT16 xSrc, INT16 ySrc,
INT16 xMask, INT16 yMask,
INT16 xDst, INT16 yDst,
CARD16 width, CARD16 height)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(pDst->pDrawable->pScreen);
RADEONInfoPtr info;
PixmapPtr pixmap;
struct radeon_pixmap *dst_priv, *src_priv = NULL, *mask_priv = NULL;
Bool gpu_done = FALSE;
if (pDst->alphaMap || pSrc->alphaMap || (pMask && pMask->alphaMap))
goto fallback;
pixmap = get_drawable_pixmap(pDst->pDrawable);
if (&pixmap->drawable != pDst->pDrawable ||
pixmap->usage_hint != RADEON_CREATE_PIXMAP_SCANOUT)
goto fallback;
dst_priv = radeon_get_pixmap_private(pixmap);
if (!radeon_glamor_prepare_access_gpu(dst_priv))
goto fallback;
info = RADEONPTR(scrn);
if (!pSrc->pDrawable ||
((pixmap = get_drawable_pixmap(pSrc->pDrawable)) &&
(src_priv = radeon_get_pixmap_private(pixmap)) &&
radeon_glamor_prepare_access_gpu(src_priv))) {
if (!pMask || !pMask->pDrawable ||
((pixmap = get_drawable_pixmap(pMask->pDrawable)) &&
(mask_priv = radeon_get_pixmap_private(pixmap)) &&
radeon_glamor_prepare_access_gpu(mask_priv))) {
info->glamor.SavedComposite(op, pSrc, pMask, pDst,
xSrc, ySrc, xMask, yMask,
xDst, yDst, width, height);
gpu_done = TRUE;
if (mask_priv)
radeon_glamor_finish_access_gpu_ro(info, mask_priv);
}
if (src_priv)
radeon_glamor_finish_access_gpu_ro(info, src_priv);
}
radeon_glamor_finish_access_gpu_rw(info, dst_priv);
if (gpu_done)
return;
fallback:
if (radeon_glamor_picture_prepare_access_cpu_rw(scrn, pDst)) {
if (radeon_glamor_picture_prepare_access_cpu_ro(scrn, pSrc)) {
if (!pMask ||
radeon_glamor_picture_prepare_access_cpu_ro(scrn, pMask)) {
fbComposite(op, pSrc, pMask, pDst,
xSrc, ySrc,
xMask, yMask,
xDst, yDst,
width, height);
if (pMask)
radeon_glamor_picture_finish_access_cpu(pMask);
}
radeon_glamor_picture_finish_access_cpu(pSrc);
}
radeon_glamor_picture_finish_access_cpu(pDst);
}
}
static void
radeon_glamor_add_traps(PicturePtr pPicture,
INT16 x_off, INT16 y_off, int ntrap, xTrap *traps)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(pPicture->pDrawable->pScreen);
if (radeon_glamor_picture_prepare_access_cpu_rw(scrn, pPicture)) {
fbAddTraps(pPicture, x_off, y_off, ntrap, traps);
radeon_glamor_picture_finish_access_cpu(pPicture);
}
}
static void
radeon_glamor_glyphs(CARD8 op,
PicturePtr src,
PicturePtr dst,
PictFormatPtr maskFormat,
INT16 xSrc,
INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr *glyphs)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(dst->pDrawable->pScreen);
if (radeon_glamor_picture_prepare_access_cpu_rw(scrn, dst)) {
if (radeon_glamor_picture_prepare_access_cpu_ro(scrn, src)) {
RADEONInfoPtr info = RADEONPTR(scrn);
info->glamor.SavedGlyphs(op, src, dst, maskFormat, xSrc,
ySrc, nlist, list, glyphs);
radeon_glamor_picture_finish_access_cpu(src);
}
radeon_glamor_picture_finish_access_cpu(dst);
}
}
static void
radeon_glamor_trapezoids(CARD8 op, PicturePtr src, PicturePtr dst,
PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
int ntrap, xTrapezoid *traps)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(dst->pDrawable->pScreen);
if (radeon_glamor_picture_prepare_access_cpu_rw(scrn, dst)) {
if (radeon_glamor_picture_prepare_access_cpu_ro(scrn, src)) {
RADEONInfoPtr info = RADEONPTR(scrn);
info->glamor.SavedTrapezoids(op, src, dst, maskFormat,
xSrc, ySrc, ntrap, traps);
radeon_glamor_picture_finish_access_cpu(src);
}
radeon_glamor_picture_finish_access_cpu(dst);
}
}
static void
radeon_glamor_triangles(CARD8 op, PicturePtr src, PicturePtr dst,
PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
int ntri, xTriangle *tri)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(dst->pDrawable->pScreen);
if (radeon_glamor_picture_prepare_access_cpu_rw(scrn, dst)) {
if (radeon_glamor_picture_prepare_access_cpu_ro(scrn, src)) {
RADEONInfoPtr info = RADEONPTR(scrn);
info->glamor.SavedTriangles(op, src, dst, maskFormat,
xSrc, ySrc, ntri, tri);
radeon_glamor_picture_finish_access_cpu(src);
}
radeon_glamor_picture_finish_access_cpu(dst);
}
}
#endif /* RENDER */
/**
* radeon_glamor_close_screen() unwraps its wrapped screen functions and tears
* down our screen private, before calling down to the next CloseScreen.
*/
static Bool
radeon_glamor_close_screen(CLOSE_SCREEN_ARGS_DECL)
{
RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pScreen));
#ifdef RENDER
PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
#endif
pScreen->CreateGC = info->glamor.SavedCreateGC;
pScreen->CloseScreen = info->glamor.SavedCloseScreen;
pScreen->GetImage = info->glamor.SavedGetImage;
pScreen->GetSpans = info->glamor.SavedGetSpans;
pScreen->CreatePixmap = info->glamor.SavedCreatePixmap;
pScreen->DestroyPixmap = info->glamor.SavedDestroyPixmap;
pScreen->CopyWindow = info->glamor.SavedCopyWindow;
pScreen->ChangeWindowAttributes =
info->glamor.SavedChangeWindowAttributes;
pScreen->BitmapToRegion = info->glamor.SavedBitmapToRegion;
#ifdef RENDER
if (ps) {
ps->Composite = info->glamor.SavedComposite;
ps->Glyphs = info->glamor.SavedGlyphs;
ps->UnrealizeGlyph = info->glamor.SavedUnrealizeGlyph;
ps->Trapezoids = info->glamor.SavedTrapezoids;
ps->AddTraps = info->glamor.SavedAddTraps;
ps->Triangles = info->glamor.SavedTriangles;
ps->UnrealizeGlyph = info->glamor.SavedUnrealizeGlyph;
}
#endif
return (*pScreen->CloseScreen) (CLOSE_SCREEN_ARGS);
}
/**
* @param screen screen being initialized
*/
void
radeon_glamor_screen_init(ScreenPtr screen)
{
RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(screen));
/*
* Replace various fb screen functions
*/
info->glamor.SavedCloseScreen = screen->CloseScreen;
screen->CloseScreen = radeon_glamor_close_screen;
info->glamor.SavedCreateGC = screen->CreateGC;
screen->CreateGC = radeon_glamor_create_gc;
info->glamor.SavedGetImage = screen->GetImage;
screen->GetImage = radeon_glamor_get_image;
info->glamor.SavedGetSpans = screen->GetSpans;
screen->GetSpans = radeon_glamor_get_spans;
info->glamor.SavedCreatePixmap = screen->CreatePixmap;
info->glamor.SavedDestroyPixmap = screen->DestroyPixmap;
info->glamor.SavedCopyWindow = screen->CopyWindow;
screen->CopyWindow = radeon_glamor_copy_window;
info->glamor.SavedBitmapToRegion = screen->BitmapToRegion;
screen->BitmapToRegion = radeon_glamor_bitmap_to_region;
#ifdef RENDER
{
PictureScreenPtr ps = GetPictureScreenIfSet(screen);
if (ps) {
info->glamor.SavedComposite = ps->Composite;
ps->Composite = radeon_glamor_composite;
info->glamor.SavedUnrealizeGlyph = ps->UnrealizeGlyph;
ps->Glyphs = radeon_glamor_glyphs;
ps->Triangles = radeon_glamor_triangles;
ps->Trapezoids = radeon_glamor_trapezoids;
info->glamor.SavedAddTraps = ps->AddTraps;
ps->AddTraps = radeon_glamor_add_traps;
}
}
#endif
}
#endif /* USE_GLAMOR */

View File

@ -32,6 +32,8 @@
#include <sys/ioctl.h>
/* Driver data structures */
#include "radeon.h"
#include "radeon_drm_queue.h"
#include "radeon_glamor.h"
#include "radeon_reg.h"
#include "radeon_probe.h"
#include "micmap.h"
@ -68,12 +70,16 @@ const OptionInfoRec RADEONOptions_KMS[] = {
{ OPTION_SUBPIXEL_ORDER, "SubPixelOrder", OPTV_ANYSTR, {0}, FALSE },
#ifdef USE_GLAMOR
{ OPTION_ACCELMETHOD, "AccelMethod", OPTV_STRING, {0}, FALSE },
{ OPTION_SHADOW_PRIMARY, "ShadowPrimary", OPTV_BOOLEAN, {0}, FALSE },
#endif
{ OPTION_EXA_VSYNC, "EXAVSync", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_EXA_PIXMAPS, "EXAPixmaps", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_ZAPHOD_HEADS, "ZaphodHeads", OPTV_STRING, {0}, FALSE },
{ OPTION_PAGE_FLIP, "EnablePageFlip", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_SWAPBUFFERS_WAIT,"SwapbuffersWait", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_DELETE_DP12, "DeleteUnusedDP12Displays", OPTV_BOOLEAN, {0}, FALSE},
{ OPTION_DRI3, "DRI3", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_DRI, "DRI", OPTV_INTEGER, {0}, FALSE },
{ OPTION_TEAR_FREE, "TearFree", OPTV_BOOLEAN, {0}, FALSE },
{ -1, NULL, OPTV_NONE, {0}, FALSE }
};
@ -82,12 +88,22 @@ const OptionInfoRec *RADEONOptionsWeak(void) { return RADEONOptions_KMS; }
void radeon_cs_flush_indirect(ScrnInfoPtr pScrn)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
struct radeon_accel_state *accel_state = info->accel_state;
struct radeon_accel_state *accel_state;
int ret;
#ifdef USE_GLAMOR
if (info->use_glamor) {
glamor_block_handler(pScrn->pScreen);
info->gpu_flushed++;
return;
}
#endif
if (!info->cs->cdw)
return;
accel_state = info->accel_state;
/* release the current VBO so we don't block on mapping it later */
if (info->accel_state->vbo.vb_offset && info->accel_state->vbo.vb_bo) {
radeon_vbo_put(pScrn, &info->accel_state->vbo);
@ -171,6 +187,9 @@ static void RADEONFreeRec(ScrnInfoPtr pScrn)
info = RADEONPTR(pScrn);
if (info->fbcon_pixmap)
pScrn->pScreen->DestroyPixmap(info->fbcon_pixmap);
if (info->dri2.drm_fd > 0) {
DevUnion *pPriv;
RADEONEntPtr pRADEONEnt;
@ -230,7 +249,7 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen)
return FALSE;
pScreen->CreateScreenResources = RADEONCreateScreenResources_KMS;
if (!drmmode_set_desired_modes(pScrn, &info->drmmode))
if (!drmmode_set_desired_modes(pScrn, &info->drmmode, FALSE))
return FALSE;
drmmode_uevent_init(pScrn, &info->drmmode);
@ -269,7 +288,11 @@ redisplay_dirty(ScreenPtr screen, PixmapDirtyUpdatePtr dirty)
PixmapRegionInit(&pixregion, dirty->slave_dst);
DamageRegionAppend(&dirty->slave_dst->drawable, &pixregion);
#ifdef HAS_DIRTYTRACKING_ROTATION
PixmapSyncDirtyHelper(dirty);
#else
PixmapSyncDirtyHelper(dirty, &pixregion);
#endif
radeon_cs_flush_indirect(pScrn);
DamageRegionProcessPending(&dirty->slave_dst->drawable);
@ -295,6 +318,204 @@ radeon_dirty_update(ScreenPtr screen)
}
#endif
static Bool
radeon_scanout_extents_intersect(BoxPtr extents, int x, int y, int w, int h)
{
extents->x1 = max(extents->x1 - x, 0);
extents->y1 = max(extents->y1 - y, 0);
extents->x2 = min(extents->x2 - x, w);
extents->y2 = min(extents->y2 - y, h);
return (extents->x1 < extents->x2 && extents->y1 < extents->y2);
}
static Bool
radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id)
{
drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private;
ScrnInfoPtr scrn;
DamagePtr pDamage;
RegionPtr pRegion;
DrawablePtr pDraw;
ScreenPtr pScreen;
GCPtr gc;
BoxRec extents;
RADEONInfoPtr info;
Bool force;
if (!xf86_crtc->enabled ||
drmmode_crtc->dpms_mode != DPMSModeOn ||
!drmmode_crtc->scanout[scanout_id].pixmap)
return FALSE;
pDamage = drmmode_crtc->scanout[scanout_id].damage;
if (!pDamage)
return FALSE;
pRegion = DamageRegion(pDamage);
if (!RegionNotEmpty(pRegion))
return FALSE;
pDraw = &drmmode_crtc->scanout[scanout_id].pixmap->drawable;
extents = *RegionExtents(pRegion);
RegionEmpty(pRegion);
if (!radeon_scanout_extents_intersect(&extents, xf86_crtc->x, xf86_crtc->y,
pDraw->width, pDraw->height))
return FALSE;
pScreen = pDraw->pScreen;
gc = GetScratchGC(pDraw->depth, pScreen);
scrn = xf86_crtc->scrn;
info = RADEONPTR(scrn);
force = info->accel_state->force;
info->accel_state->force = TRUE;
ValidateGC(pDraw, gc);
(*gc->ops->CopyArea)(&pScreen->GetScreenPixmap(pScreen)->drawable,
pDraw, gc,
xf86_crtc->x + extents.x1, xf86_crtc->y + extents.y1,
extents.x2 - extents.x1, extents.y2 - extents.y1,
extents.x1, extents.y1);
FreeScratchGC(gc);
info->accel_state->force = force;
radeon_cs_flush_indirect(scrn);
return TRUE;
}
static void
radeon_scanout_update_abort(ScrnInfoPtr scrn, void *event_data)
{
xf86CrtcPtr xf86_crtc = event_data;
drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private;
drmmode_crtc->scanout_update_pending = FALSE;
}
void
radeon_scanout_update_handler(ScrnInfoPtr scrn, uint32_t frame, uint64_t usec,
void *event_data)
{
radeon_scanout_do_update(event_data, 0);
radeon_scanout_update_abort(scrn, event_data);
}
static void
radeon_scanout_update(xf86CrtcPtr xf86_crtc)
{
drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private;
struct radeon_drm_queue_entry *drm_queue_entry;
ScrnInfoPtr scrn;
drmVBlank vbl;
DamagePtr pDamage;
RegionPtr pRegion;
DrawablePtr pDraw;
BoxRec extents;
if (!xf86_crtc->enabled ||
drmmode_crtc->scanout_update_pending ||
!drmmode_crtc->scanout[0].pixmap ||
drmmode_crtc->dpms_mode != DPMSModeOn)
return;
pDamage = drmmode_crtc->scanout[0].damage;
if (!pDamage)
return;
pRegion = DamageRegion(pDamage);
if (!RegionNotEmpty(pRegion))
return;
pDraw = &drmmode_crtc->scanout[0].pixmap->drawable;
extents = *RegionExtents(pRegion);
if (!radeon_scanout_extents_intersect(&extents, xf86_crtc->x, xf86_crtc->y,
pDraw->width, pDraw->height))
return;
scrn = xf86_crtc->scrn;
drm_queue_entry = radeon_drm_queue_alloc(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT,
RADEON_DRM_QUEUE_ID_DEFAULT,
xf86_crtc,
radeon_scanout_update_handler,
radeon_scanout_update_abort);
if (!drm_queue_entry) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"radeon_drm_queue_alloc failed for scanout update\n");
return;
}
vbl.request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT;
vbl.request.type |= radeon_populate_vbl_request_type(xf86_crtc);
vbl.request.sequence = 1;
vbl.request.signal = (unsigned long)drm_queue_entry;
if (drmWaitVBlank(RADEONPTR(scrn)->dri2.drm_fd, &vbl)) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"drmWaitVBlank failed for scanout update: %s\n",
strerror(errno));
radeon_drm_abort_entry(drm_queue_entry);
return;
}
drmmode_crtc->scanout_update_pending = TRUE;
}
static void
radeon_scanout_flip_abort(ScrnInfoPtr scrn, void *event_data)
{
drmmode_crtc_private_ptr drmmode_crtc = event_data;
drmmode_crtc->scanout_update_pending = FALSE;
}
static void
radeon_scanout_flip_handler(ScrnInfoPtr scrn, uint32_t frame, uint64_t usec, void *event_data)
{
radeon_scanout_flip_abort(scrn, event_data);
}
static void
radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info,
xf86CrtcPtr xf86_crtc)
{
drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private;
ScrnInfoPtr scrn;
struct radeon_drm_queue_entry *drm_queue_entry;
unsigned scanout_id;
if (drmmode_crtc->scanout_update_pending)
return;
scanout_id = drmmode_crtc->scanout_id ^ 1;
if (!radeon_scanout_do_update(xf86_crtc, scanout_id))
return;
scrn = xf86_crtc->scrn;
drm_queue_entry = radeon_drm_queue_alloc(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT,
RADEON_DRM_QUEUE_ID_DEFAULT,
drmmode_crtc,
radeon_scanout_flip_handler,
radeon_scanout_flip_abort);
if (!drm_queue_entry) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"Allocating DRM event queue entry failed.\n");
return;
}
if (drmModePageFlip(drmmode_crtc->drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
drmmode_crtc->scanout[scanout_id].fb_id,
DRM_MODE_PAGE_FLIP_EVENT, drm_queue_entry)) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING, "flip queue failed in %s: %s\n",
__func__, strerror(errno));
return;
}
drmmode_crtc->scanout_id = scanout_id;
drmmode_crtc->scanout_update_pending = TRUE;
}
static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL)
{
SCREEN_PTR(arg);
@ -305,25 +526,44 @@ static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL)
(*pScreen->BlockHandler) (BLOCKHANDLER_ARGS);
pScreen->BlockHandler = RADEONBlockHandler_KMS;
if (info->use_glamor)
radeon_glamor_flush(pScrn);
if (info->tear_free || info->shadow_primary) {
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
int c;
for (c = 0; c < xf86_config->num_crtc; c++) {
if (info->tear_free)
radeon_scanout_flip(pScreen, info, xf86_config->crtc[c]);
else
radeon_scanout_update(xf86_config->crtc[c]);
}
}
radeon_cs_flush_indirect(pScrn);
#ifdef RADEON_PIXMAP_SHARING
radeon_dirty_update(pScreen);
#endif
}
static void RADEONBlockHandler_oneshot(BLOCKHANDLER_ARGS_DECL)
{
SCREEN_PTR(arg);
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
RADEONInfoPtr info = RADEONPTR(pScrn);
drmmode_set_desired_modes(pScrn, &info->drmmode, TRUE);
RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS);
}
static void
radeon_flush_callback(CallbackListPtr *list,
pointer user_data, pointer call_data)
{
ScrnInfoPtr pScrn = user_data;
if (pScrn->vtSema) {
if (pScrn->vtSema)
radeon_cs_flush_indirect(pScrn);
radeon_glamor_flush(pScrn);
}
}
static Bool RADEONIsFastFBWorking(ScrnInfoPtr pScrn)
@ -779,14 +1019,48 @@ static void RADEONSetupCapabilities(ScrnInfoPtr pScrn)
pScrn->capabilities = 0;
ret = drmGetCap(info->dri2.drm_fd, DRM_CAP_PRIME, &value);
if (ret == 0) {
if (value & DRM_PRIME_CAP_EXPORT)
pScrn->capabilities |= RR_Capability_SourceOutput | RR_Capability_SinkOffload;
if (value & DRM_PRIME_CAP_IMPORT)
pScrn->capabilities |= RR_Capability_SourceOffload | RR_Capability_SinkOutput;
if (value & DRM_PRIME_CAP_EXPORT) {
pScrn->capabilities |= RR_Capability_SourceOutput;
if (!info->r600_shadow_fb && info->dri2.available)
pScrn->capabilities |= RR_Capability_SinkOffload;
}
if (value & DRM_PRIME_CAP_IMPORT) {
pScrn->capabilities |= RR_Capability_SinkOutput;
if (!info->r600_shadow_fb && info->dri2.available)
pScrn->capabilities |= RR_Capability_SourceOffload;
}
}
#endif
}
#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 10
/* When the root window is created, initialize the screen contents from
* console if -background none was specified on the command line
*/
static Bool RADEONCreateWindow_oneshot(WindowPtr pWin)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
ScrnInfoPtr pScrn;
RADEONInfoPtr info;
Bool ret;
if (pWin != pScreen->root)
ErrorF("%s called for non-root window %p\n", __func__, pWin);
pScrn = xf86ScreenToScrn(pScreen);
info = RADEONPTR(pScrn);
pScreen->CreateWindow = info->CreateWindow;
ret = pScreen->CreateWindow(pWin);
if (ret)
drmmode_copy_fb(pScrn, &info->drmmode);
return ret;
}
#endif
Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
{
RADEONInfoPtr info;
@ -806,7 +1080,6 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
info = RADEONPTR(pScrn);
info->IsSecondary = FALSE;
info->IsPrimary = FALSE;
info->pEnt = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]);
if (info->pEnt->location.type != BUS_PCI
#ifdef XSERVER_PLATFORM_BUS
@ -824,14 +1097,10 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
if(xf86IsPrimInitDone(pScrn->entityList[0]))
{
info->IsSecondary = TRUE;
pRADEONEnt->pSecondaryScrn = pScrn;
}
else
{
info->IsPrimary = TRUE;
xf86SetPrimInitDone(pScrn->entityList[0]);
pRADEONEnt->pPrimaryScrn = pScrn;
pRADEONEnt->HasSecondary = FALSE;
}
}
@ -870,6 +1139,8 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
if (!RADEONPreInitAccel_KMS(pScrn)) goto fail;
radeon_drm_queue_init();
info->allowColorTiling2D = FALSE;
RADEONSetupCapabilities(pScrn);
@ -920,11 +1191,37 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"KMS Color Tiling 2D: %sabled\n", info->allowColorTiling2D ? "en" : "dis");
#if USE_GLAMOR
if (info->use_glamor) {
info->shadow_primary = xf86ReturnOptValBool(info->Options,
OPTION_SHADOW_PRIMARY, FALSE);
if (info->shadow_primary)
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShadowPrimary enabled\n");
}
#endif
info->tear_free = xf86ReturnOptValBool(info->Options, OPTION_TEAR_FREE,
FALSE);
if (info->tear_free)
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TearFree enabled\n");
if (info->dri2.pKernelDRMVersion->version_minor >= 8) {
info->allowPageFlip = xf86ReturnOptValBool(info->Options,
OPTION_PAGE_FLIP, TRUE);
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"KMS Pageflipping: %sabled\n", info->allowPageFlip ? "en" : "dis");
if (info->tear_free || info->shadow_primary) {
xf86DrvMsg(pScrn->scrnIndex,
info->allowPageFlip ? X_WARNING : X_DEFAULT,
"KMS Pageflipping: disabled%s\n",
info->allowPageFlip ?
" because of ShadowPrimary/TearFree" : "");
info->allowPageFlip = FALSE;
} else {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"KMS Pageflipping: %sabled\n", info->allowPageFlip ? "en" : "dis");
}
}
info->swapBuffersWait = xf86ReturnOptValBool(info->Options,
@ -932,12 +1229,16 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"SwapBuffers wait for vsync: %sabled\n", info->swapBuffersWait ? "en" : "dis");
if (xf86ReturnOptValBool(info->Options, OPTION_DELETE_DP12, FALSE)) {
info->drmmode.delete_dp_12_displays = TRUE;
}
if (drmmode_pre_init(pScrn, &info->drmmode, pScrn->bitsPerPixel / 8) == FALSE) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Kernel modesetting setup failed\n");
goto fail;
}
if (info->drmmode.mode_res->count_crtcs == 1)
if (info->drmmode.count_crtcs == 1)
pRADEONEnt->HasCRTC2 = FALSE;
else
pRADEONEnt->HasCRTC2 = TRUE;
@ -1158,11 +1459,16 @@ static Bool RADEONCloseScreen_KMS(CLOSE_SCREEN_ARGS_DECL)
{
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
RADEONInfoPtr info = RADEONPTR(pScrn);
RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
"RADEONCloseScreen\n");
/* Clear mask of assigned crtc's in this generation */
pRADEONEnt->assigned_crtcs = 0;
drmmode_uevent_fini(pScrn, &info->drmmode);
radeon_drm_queue_close(pScrn);
radeon_cs_flush_indirect(pScrn);
DeleteCallback(&FlushCallback, radeon_flush_callback, pScrn);
@ -1173,6 +1479,8 @@ static Bool RADEONCloseScreen_KMS(CLOSE_SCREEN_ARGS_DECL)
info->accel_state->exa = NULL;
}
radeon_sync_close(pScreen);
if (info->accel_state->use_vbos)
radeon_vbo_free_lists(pScrn);
@ -1209,6 +1517,9 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
RADEONInfoPtr info = RADEONPTR(pScrn);
int subPixelOrder = SubPixelUnknown;
MessageType from;
Bool value;
int driLevel;
const char *s;
void *front_ptr;
@ -1319,6 +1630,28 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
}
#endif
value = FALSE;
from = X_DEFAULT;
if (xf86GetOptValBool(info->Options, OPTION_DRI3, &value))
from = X_CONFIG;
if (xf86GetOptValInteger(info->Options, OPTION_DRI, &driLevel) &&
(driLevel == 2 || driLevel == 3)) {
from = X_CONFIG;
value = driLevel == 3;
}
if (value) {
value = radeon_sync_init(pScreen) &&
radeon_present_screen_init(pScreen) &&
radeon_dri3_screen_init(pScreen);
if (!value)
from = X_WARNING;
}
xf86DrvMsg(pScrn->scrnIndex, from, "DRI3 %sabled\n", value ? "en" : "dis");
pScrn->vtSema = TRUE;
xf86SetBackingStore(pScreen);
@ -1388,13 +1721,20 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
}
pScrn->pScreen = pScreen;
#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 10
if (serverGeneration == 1 && bgNoneRoot && info->accelOn) {
info->CreateWindow = pScreen->CreateWindow;
pScreen->CreateWindow = RADEONCreateWindow_oneshot;
}
#endif
/* Provide SaveScreen & wrap BlockHandler and CloseScreen */
/* Wrap CloseScreen */
info->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = RADEONCloseScreen_KMS;
pScreen->SaveScreen = RADEONSaveScreen_KMS;
info->BlockHandler = pScreen->BlockHandler;
pScreen->BlockHandler = RADEONBlockHandler_KMS;
pScreen->BlockHandler = RADEONBlockHandler_oneshot;
if (!AddCallback(&FlushCallback, radeon_flush_callback, pScrn))
return FALSE;
@ -1447,7 +1787,7 @@ Bool RADEONEnterVT_KMS(VT_FUNC_ARGS_DECL)
pScrn->vtSema = TRUE;
if (!drmmode_set_desired_modes(pScrn, &info->drmmode))
if (!drmmode_set_desired_modes(pScrn, &info->drmmode, TRUE))
return FALSE;
return TRUE;
@ -1465,6 +1805,7 @@ void RADEONLeaveVT_KMS(VT_FUNC_ARGS_DECL)
radeon_drop_drm_master(pScrn);
xf86RotateFreeShadow(pScrn);
drmmode_scanout_free(pScrn);
xf86_hide_cursors (pScrn);
info->accel_state->XInited3D = FALSE;
@ -1515,7 +1856,7 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen)
}
}
if (info->allowColorTiling) {
if (info->allowColorTiling && !info->shadow_primary) {
if (info->ChipFamily >= CHIP_FAMILY_R600) {
if (info->allowColorTiling2D) {
tiling_flags |= RADEON_TILING_MACRO;
@ -1578,7 +1919,9 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen)
tiling_flags |= surface.bankw << RADEON_TILING_EG_BANKW_SHIFT;
tiling_flags |= surface.bankh << RADEON_TILING_EG_BANKH_SHIFT;
tiling_flags |= surface.mtilea << RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT;
tiling_flags |= eg_tile_split(surface.tile_split) << RADEON_TILING_EG_TILE_SPLIT_SHIFT;
if (surface.tile_split)
tiling_flags |= eg_tile_split(surface.tile_split)
<< RADEON_TILING_EG_TILE_SPLIT_SHIFT;
break;
case RADEON_SURF_MODE_1D:
tiling_flags |= RADEON_TILING_MICRO;
@ -1618,7 +1961,10 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen)
if (info->front_bo == NULL) {
info->front_bo = radeon_bo_open(info->bufmgr, 0, screen_size,
base_align, RADEON_GEM_DOMAIN_VRAM, 0);
base_align,
info->shadow_primary ?
RADEON_GEM_DOMAIN_GTT :
RADEON_GEM_DOMAIN_VRAM, 0);
if (info->r600_shadow_fb == TRUE) {
if (radeon_bo_map(info->front_bo, 1)) {
ErrorF("Failed to map cursor buffer memory\n");

View File

@ -0,0 +1,39 @@
/*
* Copyright © 2015 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.
*/
#ifndef _RADEON_LIST_H_
#define _RADEON_LIST_H_
#include <xorg-server.h>
#include <list.h>
#if !HAVE_XORG_LIST
#define xorg_list list
#define xorg_list_init list_init
#define xorg_list_add list_add
#define xorg_list_del list_del
#define xorg_list_for_each_entry list_for_each_entry
#define xorg_list_for_each_entry_safe list_for_each_entry_safe
#endif
#endif /* _RADEON_LIST_H_ */

View File

@ -612,6 +612,7 @@ static PciChipsets RADEONPciChipsets[] = {
{ PCI_CHIP_OLAND_6610, PCI_CHIP_OLAND_6610, RES_SHARED_VGA },
{ PCI_CHIP_OLAND_6611, PCI_CHIP_OLAND_6611, RES_SHARED_VGA },
{ PCI_CHIP_OLAND_6613, PCI_CHIP_OLAND_6613, RES_SHARED_VGA },
{ PCI_CHIP_OLAND_6617, PCI_CHIP_OLAND_6617, RES_SHARED_VGA },
{ PCI_CHIP_OLAND_6620, PCI_CHIP_OLAND_6620, RES_SHARED_VGA },
{ PCI_CHIP_OLAND_6621, PCI_CHIP_OLAND_6621, RES_SHARED_VGA },
{ PCI_CHIP_OLAND_6623, PCI_CHIP_OLAND_6623, RES_SHARED_VGA },
@ -632,6 +633,7 @@ static PciChipsets RADEONPciChipsets[] = {
{ PCI_CHIP_BONAIRE_6658, PCI_CHIP_BONAIRE_6658, RES_SHARED_VGA },
{ PCI_CHIP_BONAIRE_665C, PCI_CHIP_BONAIRE_665C, RES_SHARED_VGA },
{ PCI_CHIP_BONAIRE_665D, PCI_CHIP_BONAIRE_665D, RES_SHARED_VGA },
{ PCI_CHIP_BONAIRE_665F, PCI_CHIP_BONAIRE_665F, RES_SHARED_VGA },
{ PCI_CHIP_KABINI_9830, PCI_CHIP_KABINI_9830, RES_SHARED_VGA },
{ PCI_CHIP_KABINI_9831, PCI_CHIP_KABINI_9831, RES_SHARED_VGA },
{ PCI_CHIP_KABINI_9832, PCI_CHIP_KABINI_9832, RES_SHARED_VGA },

View File

@ -612,6 +612,7 @@ static const struct pci_id_match radeon_device_match[] = {
ATI_DEVICE_MATCH( PCI_CHIP_OLAND_6610, 0 ),
ATI_DEVICE_MATCH( PCI_CHIP_OLAND_6611, 0 ),
ATI_DEVICE_MATCH( PCI_CHIP_OLAND_6613, 0 ),
ATI_DEVICE_MATCH( PCI_CHIP_OLAND_6617, 0 ),
ATI_DEVICE_MATCH( PCI_CHIP_OLAND_6620, 0 ),
ATI_DEVICE_MATCH( PCI_CHIP_OLAND_6621, 0 ),
ATI_DEVICE_MATCH( PCI_CHIP_OLAND_6623, 0 ),
@ -632,6 +633,7 @@ static const struct pci_id_match radeon_device_match[] = {
ATI_DEVICE_MATCH( PCI_CHIP_BONAIRE_6658, 0 ),
ATI_DEVICE_MATCH( PCI_CHIP_BONAIRE_665C, 0 ),
ATI_DEVICE_MATCH( PCI_CHIP_BONAIRE_665D, 0 ),
ATI_DEVICE_MATCH( PCI_CHIP_BONAIRE_665F, 0 ),
ATI_DEVICE_MATCH( PCI_CHIP_KABINI_9830, 0 ),
ATI_DEVICE_MATCH( PCI_CHIP_KABINI_9831, 0 ),
ATI_DEVICE_MATCH( PCI_CHIP_KABINI_9832, 0 ),

View File

@ -0,0 +1,465 @@
/*
* Copyright © 2014 Intel Corporation
* Copyright © 2015 Advanced Micro Devices, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "radeon.h"
#ifdef HAVE_PRESENT_H
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <poll.h>
#include <sys/time.h>
#include <time.h>
#include <errno.h>
#include "radeon_bo_helper.h"
#include "radeon_glamor.h"
#include "radeon_video.h"
#include "present.h"
struct radeon_present_vblank_event {
uint64_t event_id;
xf86CrtcPtr crtc;
};
static uint32_t crtc_select(int crtc_id)
{
if (crtc_id > 1)
return crtc_id << DRM_VBLANK_HIGH_CRTC_SHIFT;
else if (crtc_id > 0)
return DRM_VBLANK_SECONDARY;
else
return 0;
}
static RRCrtcPtr
radeon_present_get_crtc(WindowPtr window)
{
ScreenPtr screen = window->drawable.pScreen;
ScrnInfoPtr pScrn = xf86ScreenToScrn(screen);
xf86CrtcPtr crtc;
RRCrtcPtr randr_crtc = NULL;
crtc = radeon_pick_best_crtc(pScrn, FALSE,
window->drawable.x,
window->drawable.x + window->drawable.width,
window->drawable.y,
window->drawable.y + window->drawable.height);
/* Make sure the CRTC is valid and this is the real front buffer */
if (crtc != NULL && !crtc->rotatedData)
randr_crtc = crtc->randr_crtc;
return randr_crtc;
}
static int
radeon_present_get_ust_msc(RRCrtcPtr crtc, CARD64 *ust, CARD64 *msc)
{
xf86CrtcPtr xf86_crtc = crtc->devPrivate;
drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private;
if (drmmode_crtc->dpms_mode != DPMSModeOn)
return BadAlloc;
return drmmode_crtc_get_ust_msc(xf86_crtc, ust, msc);
}
/*
* Flush the DRM event queue when full; this
* makes space for new requests
*/
static Bool
radeon_present_flush_drm_events(ScreenPtr screen)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[0]->driver_private;
drmmode_ptr drmmode = drmmode_crtc->drmmode;
struct pollfd p = { .fd = drmmode->fd, .events = POLLIN };
int r;
do {
r = poll(&p, 1, 0);
} while (r == -1 && (errno == EINTR || errno == EAGAIN));
if (r <= 0)
return 0;
return drmHandleEvent(drmmode->fd, &drmmode->event_context) >= 0;
}
/*
* Called when the queued vblank event has occurred
*/
static void
radeon_present_vblank_handler(ScrnInfoPtr scrn, unsigned int msc,
uint64_t usec, void *data)
{
struct radeon_present_vblank_event *event = data;
present_event_notify(event->event_id, usec, msc);
free(event);
}
/*
* Called when the queued vblank is aborted
*/
static void
radeon_present_vblank_abort(ScrnInfoPtr scrn, void *data)
{
struct radeon_present_vblank_event *event = data;
free(event);
}
/*
* Queue an event to report back to the Present extension when the specified
* MSC has past
*/
static int
radeon_present_queue_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc)
{
xf86CrtcPtr xf86_crtc = crtc->devPrivate;
ScreenPtr screen = crtc->pScreen;
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
RADEONInfoPtr info = RADEONPTR(scrn);
int crtc_id = drmmode_get_crtc_id(xf86_crtc);
struct radeon_present_vblank_event *event;
struct radeon_drm_queue_entry *queue;
drmVBlank vbl;
int ret;
event = calloc(sizeof(struct radeon_present_vblank_event), 1);
if (!event)
return BadAlloc;
event->event_id = event_id;
queue = radeon_drm_queue_alloc(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT,
event_id, event,
radeon_present_vblank_handler,
radeon_present_vblank_abort);
if (!queue) {
free(event);
return BadAlloc;
}
vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT | crtc_select(crtc_id);
vbl.request.sequence = msc;
vbl.request.signal = (unsigned long)queue;
for (;;) {
ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
if (!ret)
break;
if (errno != EBUSY || !radeon_present_flush_drm_events(screen)) {
radeon_drm_abort_entry(queue);
return BadAlloc;
}
}
return Success;
}
/*
* Remove a pending vblank event from the DRM queue so that it is not reported
* to the extension
*/
static void
radeon_present_abort_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc)
{
radeon_drm_abort_id(event_id);
}
/*
* Flush our batch buffer when requested by the Present extension.
*/
static void
radeon_present_flush(WindowPtr window)
{
radeon_cs_flush_indirect(xf86ScreenToScrn(window->drawable.pScreen));
}
static uint32_t
radeon_present_get_pixmap_tiling_flags(RADEONInfoPtr info, PixmapPtr pixmap)
{
uint32_t tiling_flags = radeon_get_pixmap_tiling_flags(pixmap);
/* Micro tiling is always enabled with macro tiling on >= R600, so we
* can ignore the micro tiling bit in that case
*/
if ((tiling_flags & RADEON_TILING_MACRO) &&
info->ChipFamily >= CHIP_FAMILY_R600)
tiling_flags &= ~RADEON_TILING_MICRO;
return tiling_flags;
}
/*
* Test to see if page flipping is possible on the target crtc
*/
static Bool
radeon_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap,
Bool sync_flip)
{
ScreenPtr screen = window->drawable.pScreen;
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
RADEONInfoPtr info = RADEONPTR(scrn);
PixmapPtr screen_pixmap;
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
int num_crtcs_on;
int i;
if (!scrn->vtSema)
return FALSE;
if (!info->allowPageFlip)
return FALSE;
if (!sync_flip)
return FALSE;
if (info->drmmode.dri2_flipping)
return FALSE;
/* The kernel driver doesn't handle flipping between BOs with different
* tiling parameters correctly yet
*/
screen_pixmap = screen->GetScreenPixmap(screen);
if (radeon_present_get_pixmap_tiling_flags(info, pixmap) !=
radeon_present_get_pixmap_tiling_flags(info, screen_pixmap))
return FALSE;
for (i = 0, num_crtcs_on = 0; i < config->num_crtc; i++) {
drmmode_crtc_private_ptr drmmode_crtc = config->crtc[i]->driver_private;
if (!config->crtc[i]->enabled)
continue;
if (!drmmode_crtc || drmmode_crtc->rotate.bo != NULL)
return FALSE;
if (drmmode_crtc->dpms_mode == DPMSModeOn)
num_crtcs_on++;
}
return num_crtcs_on > 0;
}
/*
* Once the flip has been completed on all CRTCs, notify the
* extension code telling it when that happened
*/
static void
radeon_present_flip_event(ScrnInfoPtr scrn, uint32_t msc, uint64_t ust, void *pageflip_data)
{
RADEONInfoPtr info = RADEONPTR(scrn);
struct radeon_present_vblank_event *event = pageflip_data;
if (!event->crtc)
info->drmmode.present_flipping = FALSE;
present_event_notify(event->event_id, ust, msc);
free(event);
}
/*
* The flip has been aborted, free the structure
*/
static void
radeon_present_flip_abort(ScrnInfoPtr scrn, void *pageflip_data)
{
struct radeon_present_vblank_event *event = pageflip_data;
free(event);
}
/*
* Queue a flip on 'crtc' to 'pixmap' at 'target_msc'. If 'sync_flip' is true,
* then wait for vblank. Otherwise, flip immediately
*/
static Bool
radeon_present_flip(RRCrtcPtr crtc, uint64_t event_id, uint64_t target_msc,
PixmapPtr pixmap, Bool sync_flip)
{
ScreenPtr screen = crtc->pScreen;
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
RADEONInfoPtr info = RADEONPTR(scrn);
struct radeon_present_vblank_event *event;
xf86CrtcPtr xf86_crtc = crtc->devPrivate;
int crtc_id = xf86_crtc ? drmmode_get_crtc_id(xf86_crtc) : -1;
uint32_t handle;
Bool ret;
if (!radeon_present_check_flip(crtc, screen->root, pixmap, sync_flip))
return FALSE;
if (!radeon_get_pixmap_handle(pixmap, &handle))
return FALSE;
event = calloc(1, sizeof(struct radeon_present_vblank_event));
if (!event)
return FALSE;
event->event_id = event_id;
event->crtc = xf86_crtc;
ret = radeon_do_pageflip(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT, handle,
event_id, event, crtc_id,
radeon_present_flip_event,
radeon_present_flip_abort);
if (!ret)
xf86DrvMsg(scrn->scrnIndex, X_ERROR, "present flip failed\n");
else
info->drmmode.present_flipping = TRUE;
return ret;
}
/*
* Queue a flip back to the normal frame buffer
*/
static void
radeon_present_unflip(ScreenPtr screen, uint64_t event_id)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
RADEONInfoPtr info = RADEONPTR(scrn);
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
struct radeon_present_vblank_event *event;
PixmapPtr pixmap = screen->GetScreenPixmap(screen);
uint32_t handle;
int i;
if (!radeon_present_check_flip(NULL, screen->root, pixmap, TRUE))
goto modeset;
if (!radeon_get_pixmap_handle(pixmap, &handle)) {
ErrorF("%s: radeon_get_pixmap_handle failed, display might freeze\n",
__func__);
goto modeset;
}
event = calloc(1, sizeof(struct radeon_present_vblank_event));
if (!event) {
ErrorF("%s: calloc failed, display might freeze\n", __func__);
goto modeset;
}
event->event_id = event_id;
if (radeon_do_pageflip(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT, handle,
event_id, event, -1, radeon_present_flip_event,
radeon_present_flip_abort))
return;
modeset:
for (i = 0; i < config->num_crtc; i++) {
xf86CrtcPtr crtc = config->crtc[i];
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
if (!crtc->enabled)
continue;
if (drmmode_crtc->dpms_mode == DPMSModeOn)
crtc->funcs->set_mode_major(crtc, &crtc->mode, crtc->rotation,
crtc->x, crtc->y);
else
drmmode_crtc->need_modeset = TRUE;
}
present_event_notify(event_id, 0, 0);
info->drmmode.present_flipping = FALSE;
}
static present_screen_info_rec radeon_present_screen_info = {
.version = 0,
.get_crtc = radeon_present_get_crtc,
.get_ust_msc = radeon_present_get_ust_msc,
.queue_vblank = radeon_present_queue_vblank,
.abort_vblank = radeon_present_abort_vblank,
.flush = radeon_present_flush,
.capabilities = PresentCapabilityNone,
.check_flip = radeon_present_check_flip,
.flip = radeon_present_flip,
.unflip = radeon_present_unflip,
};
static Bool
radeon_present_has_async_flip(ScreenPtr screen)
{
#ifdef DRM_CAP_ASYNC_PAGE_FLIP
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
RADEONInfoPtr info = RADEONPTR(scrn);
int ret;
uint64_t value;
ret = drmGetCap(info->dri2.drm_fd, DRM_CAP_ASYNC_PAGE_FLIP, &value);
if (ret == 0)
return value == 1;
#endif
return FALSE;
}
Bool
radeon_present_screen_init(ScreenPtr screen)
{
if (radeon_present_has_async_flip(screen))
radeon_present_screen_info.capabilities |= PresentCapabilityAsync;
if (!present_screen_init(screen, &radeon_present_screen_info)) {
xf86DrvMsg(xf86ScreenToScrn(screen)->scrnIndex, X_WARNING,
"Present extension disabled because present_screen_init failed\n");
return FALSE;
}
xf86DrvMsg(xf86ScreenToScrn(screen)->scrnIndex, X_INFO,
"Present extension enabled\n");
return TRUE;
}
#else /* !HAVE_PRESENT_H */
Bool
radeon_present_screen_init(ScreenPtr screen)
{
xf86DrvMsg(xf86ScreenToScrn(screen)->scrnIndex, X_INFO,
"Present extension disabled because present.h not available at "
"build time\n");
return FALSE;
}
#endif

View File

@ -154,7 +154,6 @@ radeon_get_scrninfo(int entity_num, void *pci_dev)
*/
{
DevUnion *pPriv;
RADEONEntPtr pRADEONEnt;
xf86SetEntitySharable(entity_num);
@ -166,14 +165,8 @@ radeon_get_scrninfo(int entity_num, void *pci_dev)
xf86SetEntityInstanceForScreen(pScrn, pEnt->index, xf86GetNumEntityInstances(pEnt->index) - 1);
if (!pPriv->ptr) {
if (!pPriv->ptr)
pPriv->ptr = xnfcalloc(sizeof(RADEONEntRec), 1);
pRADEONEnt = pPriv->ptr;
pRADEONEnt->HasSecondary = FALSE;
} else {
pRADEONEnt = pPriv->ptr;
pRADEONEnt->HasSecondary = TRUE;
}
}
free(pEnt);
@ -271,10 +264,8 @@ radeon_platform_probe(DriverPtr pDriver,
if (!pPriv->ptr) {
pPriv->ptr = xnfcalloc(sizeof(RADEONEntRec), 1);
pRADEONEnt = pPriv->ptr;
pRADEONEnt->HasSecondary = FALSE;
} else {
pRADEONEnt = pPriv->ptr;
pRADEONEnt->HasSecondary = TRUE;
}
pRADEONEnt->platform_dev = dev;
}

View File

@ -132,16 +132,13 @@ typedef struct {
typedef struct
{
Bool HasSecondary;
Bool HasCRTC2; /* All cards except original Radeon */
ScrnInfoPtr pSecondaryScrn;
ScrnInfoPtr pPrimaryScrn;
int fd; /* for sharing across zaphod heads */
int fd_ref;
unsigned long fd_wakeup_registered; /* server generation for which fd has been registered for wakeup handling */
int fd_wakeup_ref;
unsigned int assigned_crtcs;
#ifdef XSERVER_PLATFORM_BUS
struct xf86_platform_device *platform_dev;
#endif

View File

@ -0,0 +1,145 @@
/*
* Copyright © 2013-2014 Intel Corporation
* Copyright © 2015 Advanced Micro Devices, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include "radeon.h"
#ifdef HAVE_MISYNCSHM_H
#include "misync.h"
#include "misyncshm.h"
#include "misyncstr.h"
/*
* This whole file exists to wrap a sync fence trigger operation
* so that we can flush the batch buffer to provide serialization
* between the server and the shm fence client
*/
static DevPrivateKeyRec radeon_sync_fence_private_key;
typedef struct _radeon_sync_fence_private {
SyncFenceSetTriggeredFunc set_triggered;
} radeon_sync_fence_private;
#define SYNC_FENCE_PRIV(pFence) \
(radeon_sync_fence_private *) dixLookupPrivate(&pFence->devPrivates, &radeon_sync_fence_private_key)
static void
radeon_sync_fence_set_triggered (SyncFence *fence)
{
ScreenPtr screen = fence->pScreen;
radeon_sync_fence_private *private = SYNC_FENCE_PRIV(fence);
/* Flush pending rendering operations */
radeon_cs_flush_indirect(xf86ScreenToScrn(screen));
fence->funcs.SetTriggered = private->set_triggered;
fence->funcs.SetTriggered(fence);
private->set_triggered = fence->funcs.SetTriggered;
fence->funcs.SetTriggered = radeon_sync_fence_set_triggered;
}
static void
radeon_sync_create_fence(ScreenPtr screen,
SyncFence *fence,
Bool initially_triggered)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
RADEONInfoPtr info = RADEONPTR(scrn);
SyncScreenFuncsPtr screen_funcs = miSyncGetScreenFuncs(screen);
radeon_sync_fence_private *private = SYNC_FENCE_PRIV(fence);
screen_funcs->CreateFence = info->CreateFence;
screen_funcs->CreateFence(screen, fence, initially_triggered);
info->CreateFence = screen_funcs->CreateFence;
screen_funcs->CreateFence = radeon_sync_create_fence;
private->set_triggered = fence->funcs.SetTriggered;
fence->funcs.SetTriggered = radeon_sync_fence_set_triggered;
}
Bool
radeon_sync_init(ScreenPtr screen)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
RADEONInfoPtr info = RADEONPTR(scrn);
SyncScreenFuncsPtr screen_funcs;
if (!miSyncShmScreenInit(screen)) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"SYNC extension fences disabled because "
"miSyncShmScreenInit failed\n");
return FALSE;
}
if (!dixPrivateKeyRegistered(&radeon_sync_fence_private_key)) {
if (!dixRegisterPrivateKey(&radeon_sync_fence_private_key,
PRIVATE_SYNC_FENCE,
sizeof (radeon_sync_fence_private))) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"SYNC extension fences disabled because "
"dixRegisterPrivateKey failed\n");
return FALSE;
}
}
xf86DrvMsg(xf86ScreenToScrn(screen)->scrnIndex, X_INFO,
"SYNC extension fences enabled\n");
screen_funcs = miSyncGetScreenFuncs(screen);
info->CreateFence = screen_funcs->CreateFence;
screen_funcs->CreateFence = radeon_sync_create_fence;
return TRUE;
}
void
radeon_sync_close(ScreenPtr screen)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
RADEONInfoPtr info = RADEONPTR(scrn);
SyncScreenFuncsPtr screen_funcs = miSyncGetScreenFuncs(screen);
if (screen_funcs && info->CreateFence)
screen_funcs->CreateFence = info->CreateFence;
info->CreateFence = NULL;
}
#else /* !HAVE_MISYNCSHM_H */
Bool
radeon_sync_init(ScreenPtr screen)
{
xf86DrvMsg(xf86ScreenToScrn(screen)->scrnIndex, X_INFO,
"SYNC extension fences disabled because misyncshm.h not "
"available at build time\n");
return FALSE;
}
void
radeon_sync_close(ScreenPtr screen)
{
}
#endif

View File

@ -9,6 +9,7 @@
#include <math.h>
#include "radeon.h"
#include "radeon_glamor.h"
#include "radeon_reg.h"
#include "radeon_probe.h"
#include "radeon_video.h"
@ -73,18 +74,12 @@ Bool radeon_crtc_is_enabled(xf86CrtcPtr crtc)
return drmmode_crtc->dpms_mode == DPMSModeOn;
}
uint32_t radeon_get_interpolated_vblanks(xf86CrtcPtr crtc)
{
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
return drmmode_crtc->interpolated_vblanks;
}
xf86CrtcPtr
radeon_pick_best_crtc(ScrnInfoPtr pScrn, Bool consider_disabled,
int x1, int x2, int y1, int y2)
{
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
int coverage, best_coverage, c;
int coverage, best_coverage, c, cd;
BoxRec box, crtc_box, cover_box;
RROutputPtr primary_output = NULL;
xf86CrtcPtr best_crtc = NULL, primary_crtc = NULL;
@ -108,38 +103,30 @@ radeon_pick_best_crtc(ScrnInfoPtr pScrn, Bool consider_disabled,
if (primary_output && primary_output->crtc)
primary_crtc = primary_output->crtc->devPrivate;
/* first consider only enabled CRTCs */
for (c = 0; c < xf86_config->num_crtc; c++) {
xf86CrtcPtr crtc = xf86_config->crtc[c];
/* first consider only enabled CRTCs
* then on second pass consider disabled ones
*/
for (cd = 0; cd < (consider_disabled ? 2 : 1); cd++) {
for (c = 0; c < xf86_config->num_crtc; c++) {
xf86CrtcPtr crtc = xf86_config->crtc[c];
if (!radeon_crtc_is_enabled(crtc))
continue;
if (!cd && !radeon_crtc_is_enabled(crtc))
continue;
radeon_crtc_box(crtc, &crtc_box);
radeon_box_intersect(&cover_box, &crtc_box, &box);
coverage = radeon_box_area(&cover_box);
if (coverage > best_coverage ||
(coverage == best_coverage && crtc == primary_crtc)) {
best_crtc = crtc;
best_coverage = coverage;
radeon_crtc_box(crtc, &crtc_box);
radeon_box_intersect(&cover_box, &crtc_box, &box);
coverage = radeon_box_area(&cover_box);
if (coverage > best_coverage ||
(coverage == best_coverage &&
crtc == primary_crtc)) {
best_crtc = crtc;
best_coverage = coverage;
}
}
if (best_crtc)
break;
}
if (best_crtc || !consider_disabled)
return best_crtc;
/* if we found nothing, repeat the search including disabled CRTCs */
for (c = 0; c < xf86_config->num_crtc; c++) {
xf86CrtcPtr crtc = xf86_config->crtc[c];
radeon_crtc_box(crtc, &crtc_box);
radeon_box_intersect(&cover_box, &crtc_box, &box);
coverage = radeon_box_area(&cover_box);
if (coverage > best_coverage ||
(coverage == best_coverage && crtc == primary_crtc)) {
best_crtc = crtc;
best_coverage = coverage;
}
}
return best_crtc;
}
@ -158,7 +145,7 @@ void RADEONInitVideo(ScreenPtr pScreen)
return;
num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
newAdaptors = malloc((num_adaptors + 2) * sizeof(XF86VideoAdaptorPtr *));
newAdaptors = malloc((num_adaptors + 2) * sizeof(*newAdaptors));
if (newAdaptors == NULL)
return;

View File

@ -101,6 +101,5 @@ RADEONCopyMungedData(ScrnInfoPtr pScrn,
unsigned int dstPitch, unsigned int h, unsigned int w);
Bool radeon_crtc_is_enabled(xf86CrtcPtr crtc);
uint32_t radeon_get_interpolated_vblanks(xf86CrtcPtr crtc);
#endif